Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add backend route for storage class metadata #3127

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions backend/src/routes/api/storage-class/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { FastifyReply, FastifyRequest } from 'fastify';
import { StorageClassConfig, KubeFastifyInstance } from '../../../types';
import { secureAdminRoute } from '../../../utils/route-security';
import { updateStorageClassConfig } from './utils';

export default async (fastify: KubeFastifyInstance): Promise<void> => {
jpuzz0 marked this conversation as resolved.
Show resolved Hide resolved
fastify.put(
'/:storageClassName/config',
secureAdminRoute(fastify)(
async (
request: FastifyRequest<{
Body: StorageClassConfig;
Params: { storageClassName: string };
}>,
reply: FastifyReply,
) => {
return updateStorageClassConfig(fastify, request)
.then((res) => {
return res;
})
.catch((res) => {
reply.send(res);
});
},
),
);
};
63 changes: 63 additions & 0 deletions backend/src/routes/api/storage-class/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { FastifyRequest } from 'fastify';
import {
K8sResourceCommon,
KubeFastifyInstance,
ResponseStatus,
StorageClassConfig,
} from '../../../types';
import { isHttpError } from '../../../utils';
import { errorHandler } from '../../../utils';

export async function updateStorageClassConfig(
fastify: KubeFastifyInstance,
request: FastifyRequest<{ Body: StorageClassConfig; Params: { storageClassName: string } }>,
): Promise<ResponseStatus> {
const params = request.params;
const body = request.body;

try {
// Fetch the existing custom object for the StorageClass
const storageClass = await fastify.kube.customObjectsApi.getClusterCustomObject(
'storage.k8s.io',
'v1',
'storageclasses',
params.storageClassName,
);

// Extract and update the annotations
const annotations = (storageClass.body as K8sResourceCommon).metadata.annotations || {};
annotations['opendatahub.io/sc-config'] = JSON.stringify(body);

// Patch the StorageClass with the new annotations
await fastify.kube.customObjectsApi.patchClusterCustomObject(
'storage.k8s.io',
'v1',
'storageclasses',
params.storageClassName,
{
metadata: {
annotations,
},
},
undefined,
undefined,
undefined,
{
headers: {
'Content-Type': 'application/merge-patch+json',
},
},
);

return { success: true, error: '' };
} catch (e) {
if (!isHttpError(e) || e.statusCode !== 404) {
fastify.log.error(e, 'Unable to update storage class metadata.');
return {
success: false,
error: `Unable to update storage class metadata: ${errorHandler(e)}`,
};
}
throw e;
}
}
13 changes: 13 additions & 0 deletions backend/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,14 @@ export type ImageTagInfo = {

export type ImageType = 'byon' | 'jupyter' | 'other';

export type StorageClassConfig = {
jpuzz0 marked this conversation as resolved.
Show resolved Hide resolved
displayName: string;
isEnabled: boolean;
isDefault: boolean;
lastModified: string;
description?: string;
};

export type PersistentVolumeClaimKind = {
apiVersion?: string;
kind?: string;
Expand Down Expand Up @@ -1191,3 +1199,8 @@ export type ModelRegistryKind = K8sResourceCommon & {
conditions?: K8sCondition[];
};
};

export type ResponseStatus = {
success: boolean;
error: string;
};
16 changes: 16 additions & 0 deletions frontend/src/services/StorageClassService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import axios from '~/utilities/axios';
import { StorageClassConfig } from '~/k8sTypes';
import { ResponseStatus } from '~/types';

export const updateStorageClassConfig = (

Check warning on line 5 in frontend/src/services/StorageClassService.ts

View check run for this annotation

Codecov / codecov/patch

frontend/src/services/StorageClassService.ts#L5

Added line #L5 was not covered by tests
name: string,
spec: StorageClassConfig,
): Promise<ResponseStatus> => {
const url = `/api/storage-class/${name}/config`;
return axios

Check warning on line 10 in frontend/src/services/StorageClassService.ts

View check run for this annotation

Codecov / codecov/patch

frontend/src/services/StorageClassService.ts#L8-L10

Added lines #L8 - L10 were not covered by tests
.put(url, spec)
.then((response) => response.data)
.catch((e) => {
throw new Error(e.response.data.message);

Check warning on line 14 in frontend/src/services/StorageClassService.ts

View check run for this annotation

Codecov / codecov/patch

frontend/src/services/StorageClassService.ts#L12-L14

Added lines #L12 - L14 were not covered by tests
});
};
9 changes: 9 additions & 0 deletions manifests/core-bases/base/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@ apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: odh-dashboard
rules:
- verbs:
- get
- list
- update
- patch
apiGroups:
- storage.k8s.io
resources:
- storageclasses
- verbs:
- create
- get
Expand Down
Loading