Skip to content

Commit

Permalink
Support for Trusty DB fields
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewballantyne committed Oct 4, 2024
1 parent 215d63d commit 445a472
Show file tree
Hide file tree
Showing 32 changed files with 911 additions and 438 deletions.
26 changes: 10 additions & 16 deletions frontend/src/api/trustyai/k8s.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,6 @@ import { TRUSTYAI_DEFINITION_NAME } from '~/concepts/trustyai/const';
import { applyK8sAPIOptions } from '~/api/apiMergeUtils';
import { TrustyAIApplicationsModel } from '~/api/models/trustyai';

const trustyAIDefaultCRSpec: TrustyAIKind['spec'] = {
storage: {
format: 'PVC',
folder: '/inputs',
size: '1Gi',
},
data: {
filename: 'data.csv',
format: 'CSV',
},
metrics: {
schedule: '5s',
},
};

export const getTrustyAICR = async (
namespace: string,
opts?: K8sAPIOptions,
Expand All @@ -43,6 +28,7 @@ export const getTrustyAICR = async (

export const createTrustyAICR = async (
namespace: string,
secretName: string,
opts?: K8sAPIOptions,
): Promise<TrustyAIKind> => {
const resource: TrustyAIKind = {
Expand All @@ -52,7 +38,15 @@ export const createTrustyAICR = async (
name: TRUSTYAI_DEFINITION_NAME,
namespace,
},
spec: trustyAIDefaultCRSpec,
spec: {
storage: {
format: 'DATABASE',
databaseConfigurations: secretName,
},
metrics: {
schedule: '5s',
},
},
};

return k8sCreateResource<TrustyAIKind>(
Expand Down
16 changes: 16 additions & 0 deletions frontend/src/components/FieldGroupHelpLabelIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import * as React from 'react';
import { Popover } from '@patternfly/react-core';
import { OutlinedQuestionCircleIcon } from '@patternfly/react-icons';
import DashboardPopupIconButton from '~/concepts/dashboard/DashboardPopupIconButton';

type FieldGroupHelpLabelIconProps = {
content: React.ComponentProps<typeof Popover>['bodyContent'];
};

const FieldGroupHelpLabelIcon: React.FC<FieldGroupHelpLabelIconProps> = ({ content }) => (
<Popover bodyContent={content}>
<DashboardPopupIconButton icon={<OutlinedQuestionCircleIcon />} aria-label="More info" />
</Popover>
);

export default FieldGroupHelpLabelIcon;
13 changes: 5 additions & 8 deletions frontend/src/concepts/k8s/ResourceNameDefinitionTooltip.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
import * as React from 'react';
import { Popover, Stack, StackItem } from '@patternfly/react-core';
import { OutlinedQuestionCircleIcon } from '@patternfly/react-icons';
import DashboardPopupIconButton from '~/concepts/dashboard/DashboardPopupIconButton';
import { Stack, StackItem } from '@patternfly/react-core';
import FieldGroupHelpLabelIcon from '~/components/FieldGroupHelpLabelIcon';

const ResourceNameDefinitionTooltip: React.FC = () => (
<Popover
bodyContent={
<FieldGroupHelpLabelIcon
content={
<Stack hasGutter>
<StackItem>Resource names are what your resources are labeled in OpenShift.</StackItem>
<StackItem>Resource names are not editable after creation.</StackItem>
</Stack>
}
>
<DashboardPopupIconButton icon={<OutlinedQuestionCircleIcon />} aria-label="More info" />
</Popover>
/>
);

export default ResourceNameDefinitionTooltip;
15 changes: 14 additions & 1 deletion frontend/src/concepts/k8s/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { K8sResourceCommon } from '@openshift/dynamic-plugin-sdk-utils';
import { K8sDSGResource } from '~/k8sTypes';
import { K8sCondition, K8sDSGResource } from '~/k8sTypes';
import { genRandomChars } from '~/utilities/string';

export const PreInstalledName = 'Pre-installed';
Expand Down Expand Up @@ -108,3 +108,16 @@ export const translateDisplayNameForK8s = (

export const isValidK8sName = (name?: string): boolean =>
name === undefined || (name.length > 0 && /^[a-z0-9]([-a-z0-9]*[a-z0-9])?$/.test(name));

type ResourceWithConditions = K8sResourceCommon & { status?: { conditions?: K8sCondition[] } };

export const getConditionForType = (
resource: ResourceWithConditions,
type: string,
): K8sCondition | undefined => resource.status?.conditions?.find((c) => c.type === type);

export const isConditionInStatus = (
resource: ResourceWithConditions,
type: string,
status: string,
): boolean => getConditionForType(resource, type)?.status === status;
6 changes: 4 additions & 2 deletions frontend/src/concepts/trustyai/const.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export const TRUSTYAI_ROUTE_NAME = 'trustyai-service';

export const TRUSTYAI_DEFINITION_NAME = 'trustyai-service';

export const TRUSTYAI_SECRET_NAME = 'trustyai-db-secret';

export const TRUSTYAI_INSTALL_MODAL_TEST_ID = 'trusty-db-config';
62 changes: 0 additions & 62 deletions frontend/src/concepts/trustyai/content/InstallTrustyAICheckbox.tsx

This file was deleted.

110 changes: 110 additions & 0 deletions frontend/src/concepts/trustyai/content/InstallTrustyModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import * as React from 'react';
import { Form, Modal, Radio } from '@patternfly/react-core';
import DashboardModalFooter from '~/concepts/dashboard/DashboardModalFooter';
import TrustyDBSecretFields from '~/concepts/trustyai/content/TrustyDBSecretFields';
import useTrustyInstallModalData, {
TrustyInstallModalFormType,
} from '~/concepts/trustyai/content/useTrustyInstallModalData';
import { UseManageTrustyAICRReturnType } from '~/concepts/trustyai/useManageTrustyAICR';
import FieldGroupHelpLabelIcon from '~/components/FieldGroupHelpLabelIcon';
import TrustyDBExistingSecretField from '~/concepts/trustyai/content/TrustyDBExistingSecretField';

type InstallTrustyModalProps = {
onClose: () => void;
namespace: string;
onInstallExistingDB: UseManageTrustyAICRReturnType['installCRForExistingDB'];
onInstallNewDB: UseManageTrustyAICRReturnType['installCRForNewDB'];
};

const InstallTrustyModal: React.FC<InstallTrustyModalProps> = ({
onClose,
namespace,
onInstallNewDB,
onInstallExistingDB,
}) => {
const [submitting, setSubmitting] = React.useState(false);
const [installError, setInstallError] = React.useState<Error | undefined>();
const formData = useTrustyInstallModalData(namespace);

return (
<Modal
title="Configure TrustyAI service"
isOpen
variant="medium"
onClose={onClose}
footer={
<DashboardModalFooter
onCancel={onClose}
onSubmit={() => {
let promise: Promise<void>;
if (formData.type === TrustyInstallModalFormType.EXISTING) {
promise = onInstallExistingDB(formData.data);
} else {
promise = onInstallNewDB(formData.data);
}
setSubmitting(true);
setInstallError(undefined);
promise
.then(() => {
onClose();
})
.catch((e) => {
setInstallError(e);
})
.finally(() => {
setSubmitting(false);
});
}}
submitLabel="Configure"
isSubmitLoading={submitting}
isSubmitDisabled={!formData.canSubmit || submitting}
error={installError}
alertTitle="Install error"
/>
}
>
<Form
onSubmit={(e) => {
e.preventDefault();
}}
>
<Radio
id="existing"
label={
<>
Specify an existing secret{' '}
<FieldGroupHelpLabelIcon content="Provide the name of an existing Kubernetes secret within your project." />
</>
}
name="secret-value"
isChecked={formData.type === TrustyInstallModalFormType.EXISTING}
onChange={() => formData.onModeChange(TrustyInstallModalFormType.EXISTING)}
body={
formData.type === TrustyInstallModalFormType.EXISTING && (
<TrustyDBExistingSecretField formData={formData} />
)
}
/>
<Radio
id="new"
label={
<>
Create a new secret{' '}
<FieldGroupHelpLabelIcon content="Consult the product documentation for more information on these fields." />
</>
}
name="secret-value"
isChecked={formData.type === TrustyInstallModalFormType.NEW}
onChange={() => formData.onModeChange(TrustyInstallModalFormType.NEW)}
body={
formData.type === TrustyInstallModalFormType.NEW && (
<TrustyDBSecretFields data={formData.data} onDataChange={formData.onDataChange} />
)
}
/>
</Form>
</Modal>
);
};

export default InstallTrustyModal;

This file was deleted.

Loading

0 comments on commit 445a472

Please sign in to comment.