Add the provisioning Button

This commit is contained in:
Ondrej Ezr 2022-10-14 15:36:25 +02:00 committed by Sanne Raymaekers
parent 03421acc74
commit 357401ecfa
5 changed files with 210 additions and 118 deletions

53
package-lock.json generated
View file

@ -17,6 +17,7 @@
"@redhat-cloud-services/frontend-components-notifications": "3.2.11",
"@redhat-cloud-services/frontend-components-utilities": "3.2.16",
"@reduxjs/toolkit": "^1.8.5",
"@scalprum/react-core": "^0.2.8",
"classnames": "2.3.1",
"react": "17.0.2",
"react-dom": "17.0.2",
@ -3288,6 +3289,19 @@
"react-router-dom": ">=4.2.2"
}
},
"node_modules/@redhat-cloud-services/frontend-components/node_modules/@scalprum/react-core": {
"version": "0.1.9",
"resolved": "https://registry.npmjs.org/@scalprum/react-core/-/react-core-0.1.9.tgz",
"integrity": "sha512-lb6sQQp7eylEF8z6UIeGygzURWXJ+1dbQi2NXctp7EU8zJ/3vfDD3dDGp2YOjs1DEVrG6Byxjf5394jlBFB2Vw==",
"dependencies": {
"@scalprum/core": "^0.1.2",
"lodash": "^4.17.0"
},
"peerDependencies": {
"react": ">=16.8.0 || >=17.0.0",
"react-dom": ">=16.8.0 || >=17.0.0"
}
},
"node_modules/@redhat-cloud-services/rbac-client": {
"version": "1.0.106",
"resolved": "https://registry.npmjs.org/@redhat-cloud-services/rbac-client/-/rbac-client-1.0.106.tgz",
@ -3340,11 +3354,11 @@
"integrity": "sha512-dupFyb1niBpyy1Mb6+bSbhZhNGYGQ4T32iNNdLB6Pvey64bApSnXl7AFl2D8468xO1YTb4Bah1libovLWvZovQ=="
},
"node_modules/@scalprum/react-core": {
"version": "0.1.9",
"resolved": "https://registry.npmjs.org/@scalprum/react-core/-/react-core-0.1.9.tgz",
"integrity": "sha512-lb6sQQp7eylEF8z6UIeGygzURWXJ+1dbQi2NXctp7EU8zJ/3vfDD3dDGp2YOjs1DEVrG6Byxjf5394jlBFB2Vw==",
"version": "0.2.8",
"resolved": "https://registry.npmjs.org/@scalprum/react-core/-/react-core-0.2.8.tgz",
"integrity": "sha512-+qGfiA6FkXAx4x53fHmv7Q3oZcEQK0NChgaVeKGaZfG+LSNa1ozgkd4oSWueAMG3XV3St0QbAxzAtRQNFRyqNQ==",
"dependencies": {
"@scalprum/core": "^0.1.2",
"@scalprum/core": "^0.2.3",
"lodash": "^4.17.0"
},
"peerDependencies": {
@ -3352,6 +3366,11 @@
"react-dom": ">=16.8.0 || >=17.0.0"
}
},
"node_modules/@scalprum/react-core/node_modules/@scalprum/core": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/@scalprum/core/-/core-0.2.3.tgz",
"integrity": "sha512-bL7YjXWSgtAw44ha+goEF/cCWUu1BELB0qo4Y8hlfmn0+FMnoIHcY0gD1OOotz7Oy74r5+DRxi5Wra40DTG8Qg=="
},
"node_modules/@sentry/browser": {
"version": "5.30.0",
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-5.30.0.tgz",
@ -19400,6 +19419,17 @@
"@scalprum/core": "^0.1.1",
"@scalprum/react-core": "^0.1.7",
"sanitize-html": "^2.3.2"
},
"dependencies": {
"@scalprum/react-core": {
"version": "0.1.9",
"resolved": "https://registry.npmjs.org/@scalprum/react-core/-/react-core-0.1.9.tgz",
"integrity": "sha512-lb6sQQp7eylEF8z6UIeGygzURWXJ+1dbQi2NXctp7EU8zJ/3vfDD3dDGp2YOjs1DEVrG6Byxjf5394jlBFB2Vw==",
"requires": {
"@scalprum/core": "^0.1.2",
"lodash": "^4.17.0"
}
}
}
},
"@redhat-cloud-services/frontend-components-config": {
@ -19661,12 +19691,19 @@
"integrity": "sha512-dupFyb1niBpyy1Mb6+bSbhZhNGYGQ4T32iNNdLB6Pvey64bApSnXl7AFl2D8468xO1YTb4Bah1libovLWvZovQ=="
},
"@scalprum/react-core": {
"version": "0.1.9",
"resolved": "https://registry.npmjs.org/@scalprum/react-core/-/react-core-0.1.9.tgz",
"integrity": "sha512-lb6sQQp7eylEF8z6UIeGygzURWXJ+1dbQi2NXctp7EU8zJ/3vfDD3dDGp2YOjs1DEVrG6Byxjf5394jlBFB2Vw==",
"version": "0.2.8",
"resolved": "https://registry.npmjs.org/@scalprum/react-core/-/react-core-0.2.8.tgz",
"integrity": "sha512-+qGfiA6FkXAx4x53fHmv7Q3oZcEQK0NChgaVeKGaZfG+LSNa1ozgkd4oSWueAMG3XV3St0QbAxzAtRQNFRyqNQ==",
"requires": {
"@scalprum/core": "^0.1.2",
"@scalprum/core": "^0.2.3",
"lodash": "^4.17.0"
},
"dependencies": {
"@scalprum/core": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/@scalprum/core/-/core-0.2.3.tgz",
"integrity": "sha512-bL7YjXWSgtAw44ha+goEF/cCWUu1BELB0qo4Y8hlfmn0+FMnoIHcY0gD1OOotz7Oy74r5+DRxi5Wra40DTG8Qg=="
}
}
},
"@sentry/browser": {

View file

@ -16,6 +16,7 @@
"@redhat-cloud-services/frontend-components-notifications": "3.2.11",
"@redhat-cloud-services/frontend-components-utilities": "3.2.16",
"@reduxjs/toolkit": "^1.8.5",
"@scalprum/react-core": "^0.2.8",
"classnames": "2.3.1",
"react": "17.0.2",
"react-dom": "17.0.2",

View file

@ -1,126 +1,49 @@
import React from 'react';
import React, { Suspense } from 'react';
import PropTypes from 'prop-types';
import {
Button,
Popover,
Text,
TextContent,
TextVariants,
} from '@patternfly/react-core';
import { DownloadIcon, ExternalLinkAltIcon } from '@patternfly/react-icons';
import { Button } from '@patternfly/react-core';
import { useLoadModule, useScalprum } from '@scalprum/react-core';
import ImageLinkDirect from './ImageLinkDirect';
const ImageLink = (props) => {
const fileExtensions = {
vsphere: '.vmdk',
'guest-image': '.qcow2',
'image-installer': '.iso',
};
const scalprum = useScalprum();
const hasProvisionig = scalprum.initialized && scalprum.config?.provisioning;
if (hasProvisionig && props.imageType === 'ami') {
const [wizardOpen, openWizard] = React.useState(false);
const [{ default: ProvisioningWizard }, error] = useLoadModule(
{
appName: 'provisioning', // optional
scope: 'provisioning',
module: './ProvisioningWizard',
// processor: (val) => val, // optional
},
{},
{}
);
const uploadStatus = props.imageStatus
? props.imageStatus.upload_status
: undefined;
if (uploadStatus) {
if (uploadStatus.type === 'aws') {
const url =
'https://console.aws.amazon.com/ec2/v2/home?region=' +
uploadStatus.options.region +
'#LaunchInstanceWizard:ami=' +
uploadStatus.options.ami;
if (!error) {
return (
<Button
component="a"
target="_blank"
variant="link"
icon={<ExternalLinkAltIcon />}
iconPosition="right"
isInline
href={url}
>
Launch instance
</Button>
);
} else if (uploadStatus.type === 'azure') {
const url =
'https://portal.azure.com/#@' +
props.uploadOptions.tenant_id +
'/resource/subscriptions/' +
props.uploadOptions.subscription_id +
'/resourceGroups/' +
props.uploadOptions.resource_group +
'/providers/Microsoft.Compute/images/' +
uploadStatus.options.image_name;
return (
<Button
component="a"
target="_blank"
variant="link"
icon={<ExternalLinkAltIcon />}
iconPosition="right"
isInline
href={url}
>
View uploaded image
</Button>
);
} else if (uploadStatus.type === 'gcp') {
return (
<Popover
aria-label="Popover with google cloud platform image details"
maxWidth="30rem"
headerContent={'GCP image details'}
bodyContent={
<TextContent>
<Text component={TextVariants.p}>
To use an Image Builder created Google Cloud Platform (GCP)
image in your project, specify the project ID and image name in
your templates and configurations.
</Text>
<Text>
<strong>Project ID</strong>
<br />
{uploadStatus.options.project_id}
</Text>
<Text>
<strong>Image Name</strong>
<br />
{uploadStatus.options.image_name}
</Text>
<Text>
<strong>Shared with</strong>
<br />
{/* the account the image is shared with is stored in the form type:account so this extracts the account */}
{props.uploadOptions.share_with_accounts[0].split(':')[1]}
</Text>
</TextContent>
}
>
<Button component="a" target="_blank" variant="link" isInline>
Image details
<Suspense fallback="loading">
<Button variant="link" isInline onClick={() => openWizard(true)}>
Launch
</Button>
</Popover>
);
} else if (uploadStatus.type === 'aws.s3') {
return (
<Button
component="a"
target="_blank"
variant="link"
icon={<DownloadIcon />}
iconPosition="right"
isInline
href={uploadStatus.options.url}
>
Download {fileExtensions[props.imageType]}
</Button>
{wizardOpen && (
<ProvisioningWizard
isOpen
onClose={() => openWizard(false)}
image={{ name: props.imageName, id: props.imageId }}
/>
)}
</Suspense>
);
}
}
return null;
return <ImageLinkDirect {...props} />;
};
ImageLink.propTypes = {
imageId: PropTypes.string.isRequired,
imageName: PropTypes.string.isRequired,
imageStatus: PropTypes.object,
imageType: PropTypes.string,
uploadOptions: PropTypes.object,

View file

@ -0,0 +1,129 @@
import React from 'react';
import PropTypes from 'prop-types';
import {
Button,
Popover,
Text,
TextContent,
TextVariants,
} from '@patternfly/react-core';
import { DownloadIcon, ExternalLinkAltIcon } from '@patternfly/react-icons';
const ImageLinkDirect = (props) => {
const fileExtensions = {
vsphere: '.vmdk',
'guest-image': '.qcow2',
'image-installer': '.iso',
};
const uploadStatus = props.imageStatus
? props.imageStatus.upload_status
: undefined;
if (uploadStatus) {
if (uploadStatus.type === 'aws') {
const url =
'https://console.aws.amazon.com/ec2/v2/home?region=' +
uploadStatus.options.region +
'#LaunchInstanceWizard:ami=' +
uploadStatus.options.ami;
return (
<Button
component="a"
target="_blank"
variant="link"
icon={<ExternalLinkAltIcon />}
iconPosition="right"
isInline
href={url}
>
Launch instance
</Button>
);
} else if (uploadStatus.type === 'azure') {
const url =
'https://portal.azure.com/#@' +
props.uploadOptions.tenant_id +
'/resource/subscriptions/' +
props.uploadOptions.subscription_id +
'/resourceGroups/' +
props.uploadOptions.resource_group +
'/providers/Microsoft.Compute/images/' +
uploadStatus.options.image_name;
return (
<Button
component="a"
target="_blank"
variant="link"
icon={<ExternalLinkAltIcon />}
iconPosition="right"
isInline
href={url}
>
View uploaded image
</Button>
);
} else if (uploadStatus.type === 'gcp') {
return (
<Popover
aria-label="Popover with google cloud platform image details"
maxWidth="30rem"
headerContent={'GCP image details'}
bodyContent={
<TextContent>
<Text component={TextVariants.p}>
To use an Image Builder created Google Cloud Platform (GCP)
image in your project, specify the project ID and image name in
your templates and configurations.
</Text>
<Text>
<strong>Project ID</strong>
<br />
{uploadStatus.options.project_id}
</Text>
<Text>
<strong>Image Name</strong>
<br />
{uploadStatus.options.image_name}
</Text>
<Text>
<strong>Shared with</strong>
<br />
{/* the account the image is shared with is stored in the form type:account so this extracts the account */}
{props.uploadOptions.share_with_accounts[0].split(':')[1]}
</Text>
</TextContent>
}
>
<Button component="a" target="_blank" variant="link" isInline>
Image details
</Button>
</Popover>
);
} else if (uploadStatus.type === 'aws.s3') {
return (
<Button
component="a"
target="_blank"
variant="link"
icon={<DownloadIcon />}
iconPosition="right"
isInline
href={uploadStatus.options.url}
>
Download {fileExtensions[props.imageType]}
</Button>
);
}
}
return null;
};
ImageLinkDirect.propTypes = {
imageStatus: PropTypes.object,
imageType: PropTypes.string,
uploadOptions: PropTypes.object,
};
export default ImageLinkDirect;

View file

@ -265,6 +265,8 @@ const ImagesTable = () => {
</Td>
<Td dataLabel="Instance">
<ImageLink
imageId={id}
imageName={compose.request.image_name || id}
imageStatus={compose.image_status}
imageType={
compose.request.image_requests[0].image_type