Skip to content

Commit

Permalink
Merge branch 'main' into cypress-RHOAIENG-17124
Browse files Browse the repository at this point in the history
  • Loading branch information
antowaddle authored Dec 18, 2024
2 parents a31c55e + 2ee880d commit 2742612
Show file tree
Hide file tree
Showing 17 changed files with 469 additions and 159 deletions.
24 changes: 24 additions & 0 deletions backend/src/routes/api/modelRegistryCertificates/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { secureAdminRoute } from '../../../utils/route-security';
import { KubeFastifyInstance } from '../../../types';
import { getModelRegistryNamespace } from '../modelRegistries/modelRegistryUtils';
import { listModelRegistryCertificateNames } from './modelRegistryCertificatesUtils';
import { FastifyReply, FastifyRequest } from 'fastify';

export default async (fastify: KubeFastifyInstance): Promise<void> => {
fastify.get(
'/',
secureAdminRoute(fastify)(async (request: FastifyRequest, reply: FastifyReply) => {
try {
const modelRegistryNamespace = getModelRegistryNamespace(fastify);
return listModelRegistryCertificateNames(fastify, modelRegistryNamespace);
} catch (e) {
fastify.log.error(
`Model registry certificate names could not be listed, ${
e.response?.body?.message || e.message
}`,
);
reply.send(e);
}
}),
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { V1ConfigMap, V1Secret } from '@kubernetes/client-node';
import { ConfigSecretItem, KubeFastifyInstance } from '../../../types';

export const listSecrets = async (
fastify: KubeFastifyInstance,
modelRegistryNamespace: string,
): Promise<{ items: V1Secret[] }> => {
const response = await (fastify.kube.coreV1Api.listNamespacedSecret(
modelRegistryNamespace,
) as Promise<{ body: { items: V1Secret[] } }>);
return response.body;
};

export const listConfigMaps = async (
fastify: KubeFastifyInstance,
modelRegistryNamespace: string,
): Promise<{ items: V1ConfigMap[] }> => {
const response = await (fastify.kube.coreV1Api.listNamespacedConfigMap(
modelRegistryNamespace,
) as Promise<{ body: { items: V1ConfigMap[] } }>);
return response.body;
};

export const listModelRegistryCertificateNames = async (
fastify: KubeFastifyInstance,
namespace: string,
): Promise<{
secrets: ConfigSecretItem[];
configMaps: ConfigSecretItem[];
}> => {
try {
const [secretsResponse, configMapsResponse] = await Promise.all([
listSecrets(fastify, namespace),
listConfigMaps(fastify, namespace),
]);

const secrets = secretsResponse.items
.filter((secret) => secret.type === 'Opaque')
.map((secret) => {
const keys = Object.keys(secret.data || {}).filter(
(key) => secret.data?.[key] !== undefined && secret.data[key] !== '',
);
return { name: secret.metadata?.name || 'unknown', keys };
})
.filter((secret) => secret.keys.length > 0);

const configMaps = configMapsResponse.items
.map((configMap) => {
const keys = Object.keys(configMap.data || {}).filter(
(key) => configMap.data?.[key] !== undefined && configMap.data[key] !== '',
);
return { name: configMap.metadata?.name || 'unknown', keys };
})
.filter((configMap) => configMap.keys.length > 0);

return { secrets, configMaps };
} catch (e: any) {
fastify.log.error(
`Error fetching config maps and secrets, ${e.response?.body?.message || e.message}`,
);
throw e;
}
};
10 changes: 10 additions & 0 deletions backend/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1261,3 +1261,13 @@ export type ResourceAccessReviewResponse = {
groups?: string[];
users?: string[];
};

export type ConfigSecretItem = {
name: string;
keys: string[];
};

export type ListConfigSecretsResponse = {
secrets: ConfigSecretItem[];
configMaps: ConfigSecretItem[];
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ class ModelVersionDeployModal extends Modal {
}

selectProjectByName(name: string) {
this.findProjectSelector().click();
this.find().findByRole('option', { name, timeout: 5000 }).click();
this.findProjectSelector().findSelectOption(name).click();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,14 +184,21 @@ const initIntercepts = ({
};

describe('Deploy model version', () => {
it('Deploy model version on unsupported platform', () => {
initIntercepts({ kServeInstalled: false, modelMeshInstalled: false });
it('Deploy model version on unsupported multi-model platform', () => {
initIntercepts({ modelMeshInstalled: false });
cy.visit(`/modelRegistry/modelregistry-sample/registeredModels/1/versions`);
const modelVersionRow = modelRegistry.getModelVersionRow('test model version');
modelVersionRow.findKebabAction('Deploy').click();
cy.wait('@getProjects');
modelVersionDeployModal.selectProjectByName('Model mesh project');
cy.findByText('Multi-model platform is not installed').should('exist');
});

it('Deploy model version on unsupported single-model platform', () => {
initIntercepts({ kServeInstalled: false });
cy.visit(`/modelRegistry/modelregistry-sample/registeredModels/1/versions`);
const modelVersionRow = modelRegistry.getModelVersionRow('test model version');
modelVersionRow.findKebabAction('Deploy').click();
cy.wait('@getProjects');
modelVersionDeployModal.selectProjectByName('KServe project');
cy.findByText('Single-model platform is not installed').should('exist');
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/concepts/design/HeaderIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import {
typedBackgroundColor,
ProjectObjectType,
SectionType,
sectionTypeIconColor,
typedIconColor,
} from '~/concepts/design/utils';
import TypedObjectIcon from '~/concepts/design/TypedObjectIcon';

Expand Down Expand Up @@ -32,6 +34,7 @@ const HeaderIcon: React.FC<HeaderIconProps> = ({
background: sectionType
? sectionTypeBackgroundColor(sectionType)
: typedBackgroundColor(type),
color: sectionType ? sectionTypeIconColor(sectionType) : typedIconColor(type),
}}
>
<TypedObjectIcon
Expand Down
30 changes: 4 additions & 26 deletions frontend/src/concepts/design/InfoGalleryItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,9 @@ import {
Stack,
StackItem,
} from '@patternfly/react-core';
import {
ProjectObjectType,
SectionType,
sectionTypeBackgroundColor,
} from '~/concepts/design/utils';
import { ProjectObjectType, SectionType } from '~/concepts/design/utils';
import DividedGalleryItem from '~/concepts/design/DividedGalleryItem';
import TypedObjectIcon from '~/concepts/design/TypedObjectIcon';

const HEADER_ICON_SIZE = 40;
const HEADER_ICON_PADDING = 2;
import HeaderIcon from '~/concepts/design/HeaderIcon';

type InfoGalleryItemProps = {
title: string;
Expand Down Expand Up @@ -47,23 +40,8 @@ const InfoGalleryItem: React.FC<InfoGalleryItemProps> = ({
direction={{ default: isOpen ? 'column' : 'row' }}
alignItems={{ default: isOpen ? 'alignItemsFlexStart' : 'alignItemsCenter' }}
>
<FlexItem
style={{
display: 'inline-block',
width: HEADER_ICON_SIZE,
height: HEADER_ICON_SIZE,
padding: HEADER_ICON_PADDING,
borderRadius: HEADER_ICON_SIZE / 2,
background: sectionTypeBackgroundColor(sectionType),
}}
>
<TypedObjectIcon
resourceType={resourceType}
style={{
width: HEADER_ICON_SIZE - HEADER_ICON_PADDING * 2,
height: HEADER_ICON_SIZE - HEADER_ICON_PADDING * 2,
}}
/>
<FlexItem>
<HeaderIcon type={resourceType} sectionType={sectionType} />
</FlexItem>
{onClick ? (
<Button
Expand Down
74 changes: 74 additions & 0 deletions frontend/src/concepts/design/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,63 @@ export enum ProjectObjectType {
resources = 'resources',
}

export const typedIconColor = (objectType: ProjectObjectType): string => {
switch (objectType) {
case ProjectObjectType.project:
return 'var(--ai-project--IconColor)';
case ProjectObjectType.projectContext:
return 'var(--ai-project-context--IconColor)';
case ProjectObjectType.notebook:
return 'var(--ai-notebook--IconColor)';
case ProjectObjectType.notebookImage:
return 'var(--ai-set-up--IconColor)';
case ProjectObjectType.pipeline:
case ProjectObjectType.pipelineRun:
case ProjectObjectType.pipelineExperiment:
case ProjectObjectType.pipelineExecution:
case ProjectObjectType.pipelineArtifact:
return 'var(--ai-pipeline--IconColor)';
case ProjectObjectType.pipelineSetup:
return 'var(--ai-set-up--IconColor)';
case ProjectObjectType.clusterStorage:
case ProjectObjectType.storageClasses:
return 'var(--ai-cluster-storage--IconColor)';
case ProjectObjectType.model:
case ProjectObjectType.singleModel:
case ProjectObjectType.multiModel:
case ProjectObjectType.modelServer:
case ProjectObjectType.registeredModels:
case ProjectObjectType.deployedModels:
case ProjectObjectType.deployingModels:
return 'var(--ai-model-server--IconColor)';
case ProjectObjectType.modelRegistrySettings:
return 'var(--ai-set-up--IconColor)';
case ProjectObjectType.dataConnection:
case ProjectObjectType.connections:
return 'var(--ai-data-connection--IconColor)';
case ProjectObjectType.user:
return 'var(--ai-user--IconColor)';
case ProjectObjectType.group:
return 'var(--ai-group--IconColor)';
case ProjectObjectType.permissions:
return 'var(--ai-set-up--IconColor)';
case ProjectObjectType.enabledApplications:
case ProjectObjectType.exploreApplications:
return 'var(--ai-config--IconColor)';
case ProjectObjectType.resources:
return 'var(--ai-general--IconColor)';
case ProjectObjectType.distributedWorkload:
return 'var(--ai-serving--IconColor)';
case ProjectObjectType.clusterSettings:
case ProjectObjectType.acceleratorProfile:
return 'var(--ai-set-up--IconColor)';
case ProjectObjectType.servingRuntime:
return 'var(--ai-set-up--IconColor)';
default:
return '';
}
};

export const typedBackgroundColor = (objectType: ProjectObjectType): string => {
switch (objectType) {
case ProjectObjectType.project:
Expand Down Expand Up @@ -233,6 +290,23 @@ export const typedEmptyImage = (objectType: ProjectObjectType, option?: string):
}
};

export const sectionTypeIconColor = (sectionType: SectionType): string => {
switch (sectionType) {
case SectionType.setup:
return 'var(--ai-set-up--IconColor)';
case SectionType.organize:
return 'var(--ai-organize--IconColor)';
case SectionType.training:
return 'var(--ai-training--IconColor)';
case SectionType.serving:
return 'var(--ai-serving--IconColor)';
case SectionType.general:
return 'var(--ai-general--IconColor)';
default:
return '';
}
};

export const sectionTypeBackgroundColor = (sectionType: SectionType): string => {
switch (sectionType) {
case SectionType.setup:
Expand Down
Loading

0 comments on commit 2742612

Please sign in to comment.