Skip to content

Commit

Permalink
Show tls automation status (#999)
Browse files Browse the repository at this point in the history
* show tls automation status

* handle unknown statuses
  • Loading branch information
nilsgstrabo authored Apr 10, 2024
1 parent 2b62c71 commit 3146891
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 14 deletions.
64 changes: 55 additions & 9 deletions src/components/external-dns-list/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,33 @@ import {

import * as PropTypes from 'prop-types';
import { Icon, Table, Typography } from '@equinor/eds-core-react';
import { ExternalDns, Tls } from '../../store/radix-api';
import { ExternalDns, Tls, TlsAutomation } from '../../store/radix-api';
import { ExternalDNSStatusBadge } from '../status-badges';
import { check, chevron_down, chevron_up } from '@equinor/eds-icons';
import { chevron_down, chevron_up } from '@equinor/eds-icons';
import clsx from 'clsx';
import { TLSCertificateList } from '../tls-certificate-list';
import { dataSorter, sortCompareString } from '../../utils/sort-utils';
import { pluraliser } from '../../utils/string';
import { differenceInDays } from 'date-fns';
import { Alert, AlertProps } from '../alert';
import { TLSAutomationStatusBadge } from '../status-badges/tls-automation-status-badge';

const AlertTemplates = {
type TlsStatus = Tls['status'];

const StatusMessageAlertTemplate = {
Pending: { type: 'info' },
Consistent: { type: 'info' },
Invalid: { type: 'danger' },
} satisfies Record<Tls['status'], AlertProps>;
} satisfies Record<TlsStatus, AlertProps>;

type StatusMessagesProps = {
status: Tls['status'];
status: TlsStatus;
messages: Array<string>;
};

function StatusMessages({ status, messages }: StatusMessagesProps) {
return (
<Alert {...AlertTemplates[status]}>
<Alert {...StatusMessageAlertTemplate[status]}>
<div className="grid grid--gap-medium">
{messages.map((msg, i) => (
<Typography key={i}>{msg}</Typography>
Expand All @@ -41,6 +44,33 @@ function StatusMessages({ status, messages }: StatusMessagesProps) {
);
}

type AutomationStatus = TlsAutomation['status'] | 'Unknown';

const TlsAutomationMessageAlertTemplate = {
Pending: { type: 'warning' },
Success: { type: 'info' },
Failed: { type: 'danger' },
Unknown: { type: 'warning' },
} satisfies Record<AutomationStatus, AlertProps>;

type TlsAutomationMessageProps = {
status: AutomationStatus;
message: string;
};

function TlsAutomationStatusMessage({
status,
message,
}: TlsAutomationMessageProps) {
return (
<Alert {...TlsAutomationMessageAlertTemplate[status]}>
<div className="grid grid--gap-medium">
<Typography>{message}</Typography>
</div>
</Alert>
);
}

const dayPluraliser = pluraliser('day', 'days');

export const ExternalDNSList: FunctionComponent<{
Expand All @@ -67,7 +97,7 @@ export const ExternalDNSList: FunctionComponent<{
<Table.Cell width={40} />
<Table.Cell>Alias</Table.Cell>
<Table.Cell width={150}>Expires</Table.Cell>
<Table.Cell width={150}>Status</Table.Cell>
<Table.Cell width={150}>Certificate</Table.Cell>
<Table.Cell width={190} style={{ textAlign: 'center' }}>
Certificate Automation
</Table.Cell>
Expand All @@ -83,6 +113,7 @@ export const ExternalDNSList: FunctionComponent<{
? v.tls.certificates[0].notAfter
: null,
hasMessages: v.tls.statusMessages?.length > 0,
hasAutomationMessage: v.tls.automation?.message?.length > 0,
expanded: !!expandedRows[v.fqdn],
}))
.map(
Expand All @@ -91,6 +122,7 @@ export const ExternalDNSList: FunctionComponent<{
hasCertificates,
certificateExpiry,
hasMessages,
hasAutomationMessage,
expanded,
}) => (
<Fragment key={externalDns.fqdn}>
Expand All @@ -100,7 +132,9 @@ export const ExternalDNSList: FunctionComponent<{
})}
>
<Table.Cell className="fitwidth padding-right-0">
{(hasCertificates || hasMessages) && (
{(hasCertificates ||
hasMessages ||
hasAutomationMessage) && (
<Typography
link
as="span"
Expand Down Expand Up @@ -141,7 +175,11 @@ export const ExternalDNSList: FunctionComponent<{
<Table.Cell style={{ textAlign: 'center' }}>
{externalDns.tls.useAutomation && (
<Typography as="span" color="primary">
<Icon data={check} />
<TLSAutomationStatusBadge
status={
externalDns.tls.automation?.status || 'Unknown'
}
/>
</Typography>
)}
</Table.Cell>
Expand All @@ -154,6 +192,14 @@ export const ExternalDNSList: FunctionComponent<{
className="grid grid--gap-medium"
style={{ margin: '16px 0' }}
>
{hasAutomationMessage && (
<TlsAutomationStatusMessage
status={
externalDns.tls.automation?.status || 'Unknown'
}
message={externalDns.tls.automation?.message}
/>
)}
{hasMessages && (
<StatusMessages
status={externalDns.tls.status}
Expand Down
10 changes: 5 additions & 5 deletions src/components/status-badges/external-dns-status-badge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,22 @@ type Status = Tls['status'];

const BadgeTemplates: Record<
Status,
Readonly<Pick<StatusBadgeTemplateProps, 'icon' | 'type'>>
Readonly<Pick<StatusBadgeTemplateProps, 'icon' | 'type'> & { text?: string }>
> = {
Pending: { type: 'warning', icon: <Icon data={time} /> },
Consistent: { icon: <Icon data={check} /> },
Pending: { type: 'warning', icon: <Icon data={time} />, text: 'Missing' },
Consistent: { icon: <Icon data={check} />, text: 'Valid' },
Invalid: { type: 'danger', icon: <Icon data={error_outlined} /> },
};

type Props = {
status: Status;
};
export function ExternalDNSStatusBadge({ status }: Props) {
const { type, icon } = BadgeTemplates[status];
const { type, icon, text } = BadgeTemplates[status];

return (
<StatusBadgeTemplate type={type} icon={icon}>
{status}
{text || status}
</StatusBadgeTemplate>
);
}
Expand Down
51 changes: 51 additions & 0 deletions src/components/status-badges/tls-automation-status-badge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Icon } from '@equinor/eds-core-react';
import { check, error_outlined, time } from '@equinor/eds-icons';
import * as PropTypes from 'prop-types';

import {
StatusBadgeTemplate,
StatusBadgeTemplateProps,
} from './status-badge-template';

import { TlsAutomation } from '../../store/radix-api';

type Status = TlsAutomation['status'] | 'Unknown';

const BadgeTemplates: Record<
Status,
Readonly<Pick<StatusBadgeTemplateProps, 'icon' | 'type'> & { text?: string }>
> = {
Pending: {
type: 'warning',
icon: <Icon data={time} />,
text: 'Order In Progress',
},
Success: { icon: <Icon data={check} />, text: 'Order Successful' },
Failed: {
type: 'danger',
icon: <Icon data={error_outlined} />,
text: 'Order Failed',
},
Unknown: {
type: 'warning',
icon: <Icon data={time} />,
text: 'Order Status Unknown',
},
};

type Props = {
status: Status;
};
export function TLSAutomationStatusBadge({ status }: Props) {
const { type, icon, text } = BadgeTemplates[status];

return (
<StatusBadgeTemplate type={type} icon={icon}>
{text || status}
</StatusBadgeTemplate>
);
}

TLSAutomationStatusBadge.propTypes = {
status: PropTypes.string.isRequired as PropTypes.Validator<Status>,
};
10 changes: 10 additions & 0 deletions src/store/radix-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2134,6 +2134,15 @@ export type StopApplicationApiArg = {
/** Works only with custom setup of cluster. Allow impersonation of a comma-seperated list of test groups (Required if Impersonate-User is set) */
'Impersonate-Group'?: string;
};
export type TlsAutomation = {
/** Message is a human readable description of the reason for the status */
message?: string;
/** Status of certificate automation request
Pending TLSAutomationPending Certificate automation request pending
Success TLSAutomationSuccess Certificate automation request succeeded
Failed TLSAutomationFailed Certificate automation request failed */
status: 'Pending' | 'Success' | 'Failed';
};
export type X509Certificate = {
/** DNSNames defines list of Subject Alternate Names in the certificate */
dnsNames?: string[];
Expand All @@ -2147,6 +2156,7 @@ export type X509Certificate = {
subject: string;
};
export type Tls = {
automation?: TlsAutomation;
/** Certificates holds the X509 certificate chain
The first certificate in the list should be the host certificate and the rest should be intermediate certificates */
certificates?: X509Certificate[];
Expand Down

0 comments on commit 3146891

Please sign in to comment.