Add the provisioning Button
This commit is contained in:
parent
03421acc74
commit
357401ecfa
5 changed files with 210 additions and 118 deletions
53
package-lock.json
generated
53
package-lock.json
generated
|
|
@ -17,6 +17,7 @@
|
||||||
"@redhat-cloud-services/frontend-components-notifications": "3.2.11",
|
"@redhat-cloud-services/frontend-components-notifications": "3.2.11",
|
||||||
"@redhat-cloud-services/frontend-components-utilities": "3.2.16",
|
"@redhat-cloud-services/frontend-components-utilities": "3.2.16",
|
||||||
"@reduxjs/toolkit": "^1.8.5",
|
"@reduxjs/toolkit": "^1.8.5",
|
||||||
|
"@scalprum/react-core": "^0.2.8",
|
||||||
"classnames": "2.3.1",
|
"classnames": "2.3.1",
|
||||||
"react": "17.0.2",
|
"react": "17.0.2",
|
||||||
"react-dom": "17.0.2",
|
"react-dom": "17.0.2",
|
||||||
|
|
@ -3288,6 +3289,19 @@
|
||||||
"react-router-dom": ">=4.2.2"
|
"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": {
|
"node_modules/@redhat-cloud-services/rbac-client": {
|
||||||
"version": "1.0.106",
|
"version": "1.0.106",
|
||||||
"resolved": "https://registry.npmjs.org/@redhat-cloud-services/rbac-client/-/rbac-client-1.0.106.tgz",
|
"resolved": "https://registry.npmjs.org/@redhat-cloud-services/rbac-client/-/rbac-client-1.0.106.tgz",
|
||||||
|
|
@ -3340,11 +3354,11 @@
|
||||||
"integrity": "sha512-dupFyb1niBpyy1Mb6+bSbhZhNGYGQ4T32iNNdLB6Pvey64bApSnXl7AFl2D8468xO1YTb4Bah1libovLWvZovQ=="
|
"integrity": "sha512-dupFyb1niBpyy1Mb6+bSbhZhNGYGQ4T32iNNdLB6Pvey64bApSnXl7AFl2D8468xO1YTb4Bah1libovLWvZovQ=="
|
||||||
},
|
},
|
||||||
"node_modules/@scalprum/react-core": {
|
"node_modules/@scalprum/react-core": {
|
||||||
"version": "0.1.9",
|
"version": "0.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/@scalprum/react-core/-/react-core-0.1.9.tgz",
|
"resolved": "https://registry.npmjs.org/@scalprum/react-core/-/react-core-0.2.8.tgz",
|
||||||
"integrity": "sha512-lb6sQQp7eylEF8z6UIeGygzURWXJ+1dbQi2NXctp7EU8zJ/3vfDD3dDGp2YOjs1DEVrG6Byxjf5394jlBFB2Vw==",
|
"integrity": "sha512-+qGfiA6FkXAx4x53fHmv7Q3oZcEQK0NChgaVeKGaZfG+LSNa1ozgkd4oSWueAMG3XV3St0QbAxzAtRQNFRyqNQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@scalprum/core": "^0.1.2",
|
"@scalprum/core": "^0.2.3",
|
||||||
"lodash": "^4.17.0"
|
"lodash": "^4.17.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
|
@ -3352,6 +3366,11 @@
|
||||||
"react-dom": ">=16.8.0 || >=17.0.0"
|
"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": {
|
"node_modules/@sentry/browser": {
|
||||||
"version": "5.30.0",
|
"version": "5.30.0",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-5.30.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-5.30.0.tgz",
|
||||||
|
|
@ -19400,6 +19419,17 @@
|
||||||
"@scalprum/core": "^0.1.1",
|
"@scalprum/core": "^0.1.1",
|
||||||
"@scalprum/react-core": "^0.1.7",
|
"@scalprum/react-core": "^0.1.7",
|
||||||
"sanitize-html": "^2.3.2"
|
"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": {
|
"@redhat-cloud-services/frontend-components-config": {
|
||||||
|
|
@ -19661,12 +19691,19 @@
|
||||||
"integrity": "sha512-dupFyb1niBpyy1Mb6+bSbhZhNGYGQ4T32iNNdLB6Pvey64bApSnXl7AFl2D8468xO1YTb4Bah1libovLWvZovQ=="
|
"integrity": "sha512-dupFyb1niBpyy1Mb6+bSbhZhNGYGQ4T32iNNdLB6Pvey64bApSnXl7AFl2D8468xO1YTb4Bah1libovLWvZovQ=="
|
||||||
},
|
},
|
||||||
"@scalprum/react-core": {
|
"@scalprum/react-core": {
|
||||||
"version": "0.1.9",
|
"version": "0.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/@scalprum/react-core/-/react-core-0.1.9.tgz",
|
"resolved": "https://registry.npmjs.org/@scalprum/react-core/-/react-core-0.2.8.tgz",
|
||||||
"integrity": "sha512-lb6sQQp7eylEF8z6UIeGygzURWXJ+1dbQi2NXctp7EU8zJ/3vfDD3dDGp2YOjs1DEVrG6Byxjf5394jlBFB2Vw==",
|
"integrity": "sha512-+qGfiA6FkXAx4x53fHmv7Q3oZcEQK0NChgaVeKGaZfG+LSNa1ozgkd4oSWueAMG3XV3St0QbAxzAtRQNFRyqNQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@scalprum/core": "^0.1.2",
|
"@scalprum/core": "^0.2.3",
|
||||||
"lodash": "^4.17.0"
|
"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": {
|
"@sentry/browser": {
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
"@redhat-cloud-services/frontend-components-notifications": "3.2.11",
|
"@redhat-cloud-services/frontend-components-notifications": "3.2.11",
|
||||||
"@redhat-cloud-services/frontend-components-utilities": "3.2.16",
|
"@redhat-cloud-services/frontend-components-utilities": "3.2.16",
|
||||||
"@reduxjs/toolkit": "^1.8.5",
|
"@reduxjs/toolkit": "^1.8.5",
|
||||||
|
"@scalprum/react-core": "^0.2.8",
|
||||||
"classnames": "2.3.1",
|
"classnames": "2.3.1",
|
||||||
"react": "17.0.2",
|
"react": "17.0.2",
|
||||||
"react-dom": "17.0.2",
|
"react-dom": "17.0.2",
|
||||||
|
|
|
||||||
|
|
@ -1,126 +1,49 @@
|
||||||
import React from 'react';
|
import React, { Suspense } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import { Button } from '@patternfly/react-core';
|
||||||
import {
|
import { useLoadModule, useScalprum } from '@scalprum/react-core';
|
||||||
Button,
|
import ImageLinkDirect from './ImageLinkDirect';
|
||||||
Popover,
|
|
||||||
Text,
|
|
||||||
TextContent,
|
|
||||||
TextVariants,
|
|
||||||
} from '@patternfly/react-core';
|
|
||||||
import { DownloadIcon, ExternalLinkAltIcon } from '@patternfly/react-icons';
|
|
||||||
|
|
||||||
const ImageLink = (props) => {
|
const ImageLink = (props) => {
|
||||||
const fileExtensions = {
|
const scalprum = useScalprum();
|
||||||
vsphere: '.vmdk',
|
const hasProvisionig = scalprum.initialized && scalprum.config?.provisioning;
|
||||||
'guest-image': '.qcow2',
|
if (hasProvisionig && props.imageType === 'ami') {
|
||||||
'image-installer': '.iso',
|
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
|
if (!error) {
|
||||||
? 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 (
|
return (
|
||||||
<Button
|
<Suspense fallback="loading">
|
||||||
component="a"
|
<Button variant="link" isInline onClick={() => openWizard(true)}>
|
||||||
target="_blank"
|
Launch
|
||||||
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>
|
</Button>
|
||||||
</Popover>
|
{wizardOpen && (
|
||||||
);
|
<ProvisioningWizard
|
||||||
} else if (uploadStatus.type === 'aws.s3') {
|
isOpen
|
||||||
return (
|
onClose={() => openWizard(false)}
|
||||||
<Button
|
image={{ name: props.imageName, id: props.imageId }}
|
||||||
component="a"
|
/>
|
||||||
target="_blank"
|
)}
|
||||||
variant="link"
|
</Suspense>
|
||||||
icon={<DownloadIcon />}
|
|
||||||
iconPosition="right"
|
|
||||||
isInline
|
|
||||||
href={uploadStatus.options.url}
|
|
||||||
>
|
|
||||||
Download {fileExtensions[props.imageType]}
|
|
||||||
</Button>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return <ImageLinkDirect {...props} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
ImageLink.propTypes = {
|
ImageLink.propTypes = {
|
||||||
|
imageId: PropTypes.string.isRequired,
|
||||||
|
imageName: PropTypes.string.isRequired,
|
||||||
imageStatus: PropTypes.object,
|
imageStatus: PropTypes.object,
|
||||||
imageType: PropTypes.string,
|
imageType: PropTypes.string,
|
||||||
uploadOptions: PropTypes.object,
|
uploadOptions: PropTypes.object,
|
||||||
|
|
|
||||||
129
src/Components/ImagesTable/ImageLinkDirect.js
Normal file
129
src/Components/ImagesTable/ImageLinkDirect.js
Normal 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;
|
||||||
|
|
@ -265,6 +265,8 @@ const ImagesTable = () => {
|
||||||
</Td>
|
</Td>
|
||||||
<Td dataLabel="Instance">
|
<Td dataLabel="Instance">
|
||||||
<ImageLink
|
<ImageLink
|
||||||
|
imageId={id}
|
||||||
|
imageName={compose.request.image_name || id}
|
||||||
imageStatus={compose.image_status}
|
imageStatus={compose.image_status}
|
||||||
imageType={
|
imageType={
|
||||||
compose.request.image_requests[0].image_type
|
compose.request.image_requests[0].image_type
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue