Skip to content

Commit

Permalink
API submit logic and enabling feature flag by default
Browse files Browse the repository at this point in the history
  • Loading branch information
ppadti committed Jan 8, 2025
1 parent 14b1c4d commit 3926db9
Show file tree
Hide file tree
Showing 15 changed files with 285 additions and 71 deletions.
27 changes: 17 additions & 10 deletions backend/src/routes/api/modelRegistries/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@ import { secureAdminRoute } from '../../../utils/route-security';
import { KubeFastifyInstance, ModelRegistryKind, RecursivePartial } from '../../../types';
import createError from 'http-errors';
import {
createModelRegistryAndSecret,
createModelRegistryAndCredentials,
deleteModelRegistryAndSecret,
getDatabasePassword,
getModelRegistry,
getModelRegistryNamespace,
listModelRegistries,
patchModelRegistryAndUpdatePassword,
patchModelRegistryAndUpdateCredentials,
} from './modelRegistryUtils';

type ModelRegistryAndDBPassword = {
type ModelRegistryAndCredentials = {
modelRegistry: ModelRegistryKind;
databasePassword?: string;
newDatabaseCACertificate?: string;
};

// Lists ModelRegistries directly (does not look up passwords from associated Secrets, you must make a direct request to '/:modelRegistryName' for that)
Expand Down Expand Up @@ -48,19 +49,20 @@ export default async (fastify: KubeFastifyInstance): Promise<void> => {
async (
request: FastifyRequest<{
Querystring: { dryRun?: string };
Body: ModelRegistryAndDBPassword;
Body: ModelRegistryAndCredentials;
}>,
reply: FastifyReply,
) => {
const { dryRun } = request.query;
const { modelRegistry, databasePassword } = request.body;
const { modelRegistry, databasePassword, newDatabaseCACertificate } = request.body;
try {
const modelRegistryNamespace = getModelRegistryNamespace(fastify);
return createModelRegistryAndSecret(
return createModelRegistryAndCredentials(
fastify,
modelRegistry,
modelRegistryNamespace,
databasePassword,
newDatabaseCACertificate,
!!dryRun,
).catch((e) => {
throw createError(e.statusCode, e?.body?.message);
Expand Down Expand Up @@ -98,7 +100,7 @@ export default async (fastify: KubeFastifyInstance): Promise<void> => {
modelRegistry,
modelRegistryNamespace,
);
return { modelRegistry, databasePassword } satisfies ModelRegistryAndDBPassword;
return { modelRegistry, databasePassword } satisfies ModelRegistryAndCredentials;
} catch (e) {
fastify.log.error(
`ModelRegistry ${modelRegistryName} could not be read, ${
Expand All @@ -120,21 +122,26 @@ export default async (fastify: KubeFastifyInstance): Promise<void> => {
request: FastifyRequest<{
Querystring: { dryRun?: string };
Params: { modelRegistryName: string };
Body: RecursivePartial<ModelRegistryAndDBPassword>;
Body: RecursivePartial<ModelRegistryAndCredentials>;
}>,
reply: FastifyReply,
) => {
const { dryRun } = request.query;
const { modelRegistryName } = request.params;
const { modelRegistry: patchBody, databasePassword } = request.body;
const {
modelRegistry: patchBody,
databasePassword,
newDatabaseCACertificate,
} = request.body;
try {
const modelRegistryNamespace = getModelRegistryNamespace(fastify);
const modelRegistry = await patchModelRegistryAndUpdatePassword(
const modelRegistry = await patchModelRegistryAndUpdateCredentials(
fastify,
modelRegistryName,
modelRegistryNamespace,
patchBody,
databasePassword,
newDatabaseCACertificate,
!!dryRun,
);
return { modelRegistry, databasePassword };
Expand Down
64 changes: 61 additions & 3 deletions backend/src/routes/api/modelRegistries/modelRegistryUtils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { KubeFastifyInstance, ModelRegistryKind, RecursivePartial } from '../../../types';
import { PatchUtils, V1Secret, V1Status } from '@kubernetes/client-node';
import { PatchUtils, V1ConfigMap, V1Secret, V1Status } from '@kubernetes/client-node';
import { getClusterStatus } from '../../../utils/resourceUtils';

const MODEL_REGISTRY_API_GROUP = 'modelregistry.opendatahub.io';
Expand Down Expand Up @@ -130,13 +130,51 @@ const createModelRegistry = async (
return response.body;
};

export const createModelRegistryAndSecret = async (
const createConfigMapForCACertficate = async (
fastify: KubeFastifyInstance,
namespace: string,
name: string,
newDatabaseCACertificate: string,
): Promise<V1ConfigMap> => {
const body: V1ConfigMap = {
metadata: {
name,
namespace,
},
data: { 'ca.crt': newDatabaseCACertificate },
};
return await fastify.kube.coreV1Api
.createNamespacedConfigMap(namespace, body)
.then((response) => response.body);
};

export const createModelRegistryAndCredentials = async (
fastify: KubeFastifyInstance,
modelRegistry: ModelRegistryKind,
modelRegistryNamespace: string,
databasePassword?: string,
newDatabaseCACertificate?: string,
dryRunOnly = false,
): Promise<ModelRegistryKind> => {
let newCACertificateConfigMap: { name: string; key: string };
if (newDatabaseCACertificate) {
const newConfigMap = await createConfigMapForCACertficate(
fastify,
modelRegistryNamespace,
modelRegistry.spec.mysql.sslRootCertificateConfigMap.name,
newDatabaseCACertificate,
);

newCACertificateConfigMap = {
name: newConfigMap.metadata.name,
key: Object.keys(newConfigMap.data || {})[0],
};

if (modelRegistry.spec.mysql) {
modelRegistry.spec.mysql.sslRootCertificateConfigMap = newCACertificateConfigMap;
}
}

const createBoth = async (dryRun = false) => {
const dbSpec = getDatabaseSpec(modelRegistry);
const newSecret =
Expand Down Expand Up @@ -288,14 +326,34 @@ const updateDatabasePassword = async (
}
};

export const patchModelRegistryAndUpdatePassword = async (
export const patchModelRegistryAndUpdateCredentials = async (
fastify: KubeFastifyInstance,
modelRegistryName: string,
modelRegistryNamespace: string,
patchBody: RecursivePartial<ModelRegistryKind>,
databasePassword?: string,
newDatabaseCACertificate?: string,
dryRunOnly = false,
): Promise<ModelRegistryKind> => {
let newCACertificateConfigMap: { name: string; key: string };
if (newDatabaseCACertificate) {
const newConfigMap = await createConfigMapForCACertficate(
fastify,
modelRegistryNamespace,
patchBody.spec.mysql.sslRootCertificateConfigMap.name,
newDatabaseCACertificate,
);

newCACertificateConfigMap = {
name: newConfigMap.metadata.name,
key: Object.keys(newConfigMap.data || {})[0],
};

if (patchBody.spec.mysql) {
patchBody.spec.mysql.sslRootCertificateConfigMap = newCACertificateConfigMap;
}
}

const patchBoth = async (dryRun = false) => {
const modelRegistry = await patchModelRegistry(
fastify,
Expand Down
15 changes: 14 additions & 1 deletion backend/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1201,7 +1201,20 @@ export type ModelRegistryKind = K8sResourceCommon & {
port?: number;
skipDBCreation?: boolean;
username?: string;
};
} & EitherNotBoth<
{
sslRootCertificateConfigMap?: {
name: string;
key: string;
};
},
{
sslRootCertificateSecret?: {
name: string;
key: string;
};
}
>;
},
{
postgres?: {
Expand Down
2 changes: 1 addition & 1 deletion backend/src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export const blankDashboardCR: DashboardConfig = {
disableHardwareProfiles: true,
disableDistributedWorkloads: false,
disableModelRegistry: false,
disableModelRegistrySecureDB: true,
disableModelRegistrySecureDB: false,
disableServingRuntimeParams: false,
disableConnectionTypes: false,
disableStorageClasses: false,
Expand Down
2 changes: 1 addition & 1 deletion docs/dashboard-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ The following are a list of features that are supported, along with there defaul
| disablePerformanceMetrics | false | Disables Endpoint Performance tab from Model Serving metrics. |
| disableDistributedWorkloads | false | Disables Distributed Workload Metrics from the dashboard. |
| disableModelRegistry | false | Disables Model Registry from the dashboard. |
| disableModelRegistrySecureDB | true | Disables Model Registry Secure DB from the dashboard. |
| disableModelRegistrySecureDB | false | Disables Model Registry Secure DB from the dashboard. |
| disableServingRuntimeParams | false | Disables Serving Runtime params from the dashboard. |
| disableStorageClasses | false | Disables storage classes settings nav item from the dashboard. |
| disableNIMModelServing | true | Disables components of NIM Model UI from the dashboard. |
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/__mocks__/mockDashboardConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export const mockDashboardConfig = ({
disableTrustyBiasMetrics = false,
disableDistributedWorkloads = false,
disableModelRegistry = false,
disableModelRegistrySecureDB = true,
disableModelRegistrySecureDB = false,
disableServingRuntimeParams = false,
disableConnectionTypes = true,
disableStorageClasses = false,
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/concepts/areas/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const allFeatureFlags: string[] = Object.keys({
disableHardwareProfiles: false,
disableDistributedWorkloads: false,
disableModelRegistry: false,
disableModelRegistrySecureDB: true,
disableModelRegistrySecureDB: false,
disableServingRuntimeParams: false,
disableConnectionTypes: false,
disableStorageClasses: false,
Expand Down
15 changes: 14 additions & 1 deletion frontend/src/k8sTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1322,7 +1322,20 @@ export type ModelRegistryKind = K8sResourceCommon & {
port?: number;
skipDBCreation?: boolean;
username?: string;
};
} & EitherNotBoth<
{
sslRootCertificateConfigMap?: {
name: string;
key: string;
} | null;
},
{
sslRootCertificateSecret?: {
name: string;
key: string;
} | null;
}
>;
},
{
postgres?: {
Expand Down
Loading

0 comments on commit 3926db9

Please sign in to comment.