ImagesTable: Add expiring/expired status to OCI images

Pre-authenticated requests for the OCI images expire 7 days after creation. This adds "Expires in <x> days" and "Expired" as possible statuses for the OCI images.
This commit is contained in:
regexowl 2023-11-01 14:05:49 +01:00 committed by Klara Simickova
parent 7ec87dfa58
commit 1fd8deec1a
4 changed files with 129 additions and 85 deletions

View file

@ -40,11 +40,12 @@ import {
} from './ImageDetails';
import { AwsS3Instance, CloudInstance, OciInstance } from './Instance';
import Release from './Release';
import { AwsS3Status, CloudStatus } from './Status';
import { ExpiringStatus, CloudStatus } from './Status';
import { AwsTarget, Target } from './Target';
import {
AWS_S3_EXPIRATION_TIME_IN_HOURS,
OCI_STORAGE_EXPIRATION_TIME_IN_DAYS,
STATUS_POLLING_INTERVAL,
} from '../../constants';
import {
@ -337,9 +338,20 @@ type OciRowPropTypes = {
};
const OciRow = ({ compose, rowIndex }: OciRowPropTypes) => {
const daysToExpiration = Math.floor(
computeHoursToExpiration(compose.created_at) / 24
);
const isExpired = daysToExpiration >= OCI_STORAGE_EXPIRATION_TIME_IN_DAYS;
const details = <OciDetails compose={compose} />;
const instance = <OciInstance compose={compose} />;
const status = <CloudStatus compose={compose} />;
const instance = <OciInstance compose={compose} isExpired={isExpired} />;
const status = (
<ExpiringStatus
compose={compose}
isExpired={isExpired}
timeToExpiration={daysToExpiration}
/>
);
return (
<Row
@ -364,10 +376,10 @@ const AwsS3Row = ({ compose, rowIndex }: AwsS3RowPropTypes) => {
const details = <AwsS3Details compose={compose} />;
const instance = <AwsS3Instance compose={compose} isExpired={isExpired} />;
const status = (
<AwsS3Status
<ExpiringStatus
compose={compose}
isExpired={isExpired}
hoursToExpiration={hoursToExpiration}
timeToExpiration={hoursToExpiration}
/>
);

View file

@ -180,9 +180,11 @@ const getImageProvider = (compose: ComposesResponseItem) => {
type OciInstancePropTypes = {
compose: ComposesResponseItem;
isExpired: boolean;
};
export const OciInstance = ({ compose }: OciInstancePropTypes) => {
export const OciInstance = ({ compose, isExpired }: OciInstancePropTypes) => {
const navigate = useNavigate();
const { data, isSuccess, isFetching, isError } = useGetComposeStatusQuery({
composeId: compose.id,
});
@ -199,79 +201,93 @@ export const OciInstance = ({ compose }: OciInstancePropTypes) => {
);
}
return (
<Popover
position="bottom"
headerContent={<div>Launch an OCI image</div>}
minWidth="30rem"
bodyContent={
<>
<p>
To run the image copy the link below and follow the steps below:
</p>
<List component={ListComponent.ol} type={OrderType.number}>
<ListItem>
Go to &quot;Compute&quot; in Oracle Cloud and choose &quot;Custom
Images&quot;.
</ListItem>
<ListItem>
Click on &quot;Import image&quot;, choose &quot;Import from an
object storage URL&quot;.
</ListItem>
<ListItem>
Choose &quot;Import from an object storage URL&quot; and paste the
URL in the &quot;Object Storage URL&quot; field. The image type
has to be set to QCOW2 and the launch mode should be
paravirtualized.
</ListItem>
</List>
<br />
{isSuccess && (
<ClipboardCopy
hoverTip="Copy"
clickTip="Copied"
variant="inline-compact"
ouiaId="oci-link"
isBlock
>
{options?.url}
</ClipboardCopy>
)}
{isFetching && <Skeleton />}
{isError && (
<Alert
title="The link to launch the image could not be loaded. Please refresh
the page and try again."
variant="danger"
isPlain
isInline
/>
)}
<br />
<Button
component="a"
target="_blank"
variant="link"
icon={<ExternalLinkAltIcon />}
iconPosition="right"
// TO DO update the link after documentation is up
href="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/creating_customized_images_by_using_insights_image_builder/customizing-file-systems-during-the-image-creation"
className="pf-u-pl-0"
>
Read more about launching OCI images
</Button>
</>
}
>
if (isExpired) {
return (
<Button
component="a"
target="_blank"
variant="link"
className="pf-u-p-0 pf-u-font-size-sm"
isDisabled={data?.image_status.status === 'success' ? false : true}
onClick={() => navigate(resolveRelPath(`imagewizard/${compose.id}`))}
isInline
>
Image link
Recreate image
</Button>
</Popover>
);
);
} else {
return (
<Popover
position="bottom"
headerContent={<div>Launch an OCI image</div>}
minWidth="30rem"
bodyContent={
<>
<p>
To run the image copy the link below and follow the steps below:
</p>
<List component={ListComponent.ol} type={OrderType.number}>
<ListItem>
Go to &quot;Compute&quot; in Oracle Cloud and choose &quot;
Custom Images&quot;.
</ListItem>
<ListItem>
Click on &quot;Import image&quot;, choose &quot;Import from an
object storage URL&quot;.
</ListItem>
<ListItem>
Choose &quot;Import from an object storage URL&quot; and paste
the URL in the &quot;Object Storage URL&quot; field. The image
type has to be set to QCOW2 and the launch mode should be
paravirtualized.
</ListItem>
</List>
<br />
{isSuccess && (
<ClipboardCopy
hoverTip="Copy"
clickTip="Copied"
variant="inline-compact"
ouiaId="oci-link"
isBlock
>
{options?.url}
</ClipboardCopy>
)}
{isFetching && <Skeleton />}
{isError && (
<Alert
title="The link to launch the image could not be loaded. Please refresh
the page and try again."
variant="danger"
isPlain
isInline
/>
)}
<br />
<Button
component="a"
target="_blank"
variant="link"
icon={<ExternalLinkAltIcon />}
iconPosition="right"
// TO DO update the link after documentation is up
href="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/creating_customized_images_by_using_insights_image_builder/customizing-file-systems-during-the-image-creation"
className="pf-u-pl-0"
>
Read more about launching OCI images
</Button>
</>
}
>
<Button
variant="link"
className="pf-u-p-0 pf-u-font-size-sm"
isDisabled={data?.image_status.status === 'success' ? false : true}
>
Image link
</Button>
</Popover>
);
}
};
type AwsS3InstancePropTypes = {

View file

@ -20,7 +20,10 @@ import {
PendingIcon,
} from '@patternfly/react-icons';
import { AWS_S3_EXPIRATION_TIME_IN_HOURS } from '../../constants';
import {
AWS_S3_EXPIRATION_TIME_IN_HOURS,
OCI_STORAGE_EXPIRATION_TIME_IN_DAYS,
} from '../../constants';
import {
ClonesResponseItem,
ComposeStatus,
@ -147,17 +150,17 @@ export const AzureStatus = ({ status }: AzureStatusPropTypes) => {
}
};
type AwsS3StatusPropTypes = {
type ExpiringStatusPropTypes = {
compose: ComposesResponseItem;
isExpired: boolean;
hoursToExpiration: number;
timeToExpiration: number;
};
export const AwsS3Status = ({
export const ExpiringStatus = ({
compose,
isExpired,
hoursToExpiration,
}: AwsS3StatusPropTypes) => {
timeToExpiration,
}: ExpiringStatusPropTypes) => {
const { data: composeStatus, isSuccess } = useGetComposeStatusQuery({
composeId: compose.id,
});
@ -167,18 +170,30 @@ export const AwsS3Status = ({
}
const status = composeStatus.image_status.status;
const remainingTime = AWS_S3_EXPIRATION_TIME_IN_HOURS - hoursToExpiration;
const remainingHours = AWS_S3_EXPIRATION_TIME_IN_HOURS - timeToExpiration;
const remainingDays = OCI_STORAGE_EXPIRATION_TIME_IN_DAYS - timeToExpiration;
const imageType = compose.request.image_requests[0].upload_request.type;
if (isExpired) {
return (
<Status icon={statuses['expired'].icon} text={statuses['expired'].text} />
);
} else if (status === 'success') {
} else if (imageType === 'aws.s3' && status === 'success') {
return (
<Status
icon={statuses['expiring'].icon}
text={`Expires in ${remainingTime} ${
remainingTime > 1 ? 'hours' : 'hour'
text={`Expires in ${remainingHours} ${
remainingHours > 1 ? 'hours' : 'hour'
}`}
/>
);
} else if (imageType === 'oci.objectstorage' && status === 'success') {
return (
<Status
icon={statuses['expiring'].icon}
text={`Expires in ${remainingDays} ${
remainingDays > 1 ? 'days' : 'day'
}`}
/>
);

View file

@ -122,6 +122,7 @@ export const AWS_REGIONS = [
];
export const AWS_S3_EXPIRATION_TIME_IN_HOURS = 6;
export const OCI_STORAGE_EXPIRATION_TIME_IN_DAYS = 7;
// Anchor element for all modals that we display so that they play nice with top-most components like Quickstarts
export const MODAL_ANCHOR = '.pf-c-page.chr-c-page';