From f24c52abb954e82bec5f42b405bf03ac10f8d70d Mon Sep 17 00:00:00 2001 From: Dipanshu Gupta Date: Fri, 10 Nov 2023 18:46:37 +0530 Subject: [PATCH] [WIP] enabling accelerators API --- .../acceleratorProfilesUtils.ts | 59 +++++++++++++++++++ .../routes/api/accelerator-profiles/index.ts | 18 ++++++ .../list/AcceleratorProfileEnableToggle.tsx | 48 +++++++++++++++ .../list/DisableAcceleratorProfileModal.tsx | 31 ++++++++++ .../src/services/acceleratorProfileService.ts | 12 ++++ 5 files changed, 168 insertions(+) create mode 100644 backend/src/routes/api/accelerator-profiles/acceleratorProfilesUtils.ts create mode 100644 backend/src/routes/api/accelerator-profiles/index.ts create mode 100644 frontend/src/pages/acceleratorProfiles/screens/list/AcceleratorProfileEnableToggle.tsx create mode 100644 frontend/src/pages/acceleratorProfiles/screens/list/DisableAcceleratorProfileModal.tsx create mode 100644 frontend/src/services/acceleratorProfileService.ts diff --git a/backend/src/routes/api/accelerator-profiles/acceleratorProfilesUtils.ts b/backend/src/routes/api/accelerator-profiles/acceleratorProfilesUtils.ts new file mode 100644 index 0000000000..d9c35db4cd --- /dev/null +++ b/backend/src/routes/api/accelerator-profiles/acceleratorProfilesUtils.ts @@ -0,0 +1,59 @@ +import { KubeFastifyInstance, AcceleratorKind } from '../../../types'; +import { FastifyRequest } from 'fastify'; +import createError from 'http-errors'; + +export const updateAcceleratorProfile = async ( + fastify: KubeFastifyInstance, + request: FastifyRequest, +): Promise<{ success: boolean; error: string }> => { + const customObjectsApi = fastify.kube.customObjectsApi; + const namespace = fastify.kube.namespace; + const params = request.params as { acceleratorProfileName: string }; + const body = request.body as Partial; + + try { + const currentProfile = await customObjectsApi + .getNamespacedCustomObject( + 'dashboard.opendatahub.io', + 'v1', + namespace, + 'acceleratorprofiles', + params.acceleratorProfileName, + ) + .then((r) => r.body as AcceleratorKind) + .catch((e) => { + throw createError(e.statusCode, e?.body?.message); + }); + console.log('gupta', body); + if (body !== undefined) { + console.log('dip', body); + currentProfile.spec.enabled = body.enabled; + } + + // Update the modified date annotation + currentProfile.metadata.annotations['opendatahub.io/modified-date'] = new Date().toISOString(); + + await customObjectsApi + .patchNamespacedCustomObject( + 'dashboard.opendatahub.io', + 'v1', + namespace, + 'acceleratorprofiles', + params.acceleratorProfileName, + currentProfile, + undefined, + undefined, + undefined, + { + headers: { 'Content-Type': 'application/merge-patch+json' }, + }, + ) + .catch((e) => { + throw createError(e.statusCode, e?.body?.message); + }); + return { success: true, error: null }; + } catch (e) { + fastify.log.error(e, 'Unable to update accelerator profile.'); + return { success: false, error: 'Unable to update accelerator profile: ' + e.message }; + } +}; diff --git a/backend/src/routes/api/accelerator-profiles/index.ts b/backend/src/routes/api/accelerator-profiles/index.ts new file mode 100644 index 0000000000..cdf25009f6 --- /dev/null +++ b/backend/src/routes/api/accelerator-profiles/index.ts @@ -0,0 +1,18 @@ +import { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify'; +import { secureAdminRoute } from '../../../utils/route-security'; +import { updateAcceleratorProfile } from './acceleratorProfilesUtils'; + +export default async (fastify: FastifyInstance): Promise => { + fastify.put( + '/:acceleratorProfileName', + secureAdminRoute(fastify)(async (request: FastifyRequest, reply: FastifyReply) => { + return updateAcceleratorProfile(fastify, request) + .then((res) => { + return res; + }) + .catch((res) => { + reply.send(res); + }); + }), + ); +}; diff --git a/frontend/src/pages/acceleratorProfiles/screens/list/AcceleratorProfileEnableToggle.tsx b/frontend/src/pages/acceleratorProfiles/screens/list/AcceleratorProfileEnableToggle.tsx new file mode 100644 index 0000000000..cf11e765e0 --- /dev/null +++ b/frontend/src/pages/acceleratorProfiles/screens/list/AcceleratorProfileEnableToggle.tsx @@ -0,0 +1,48 @@ +import * as React from 'react'; +import { Switch } from '@patternfly/react-core'; +import DisableAcceleratorProfileModal from '~/pages/acceleratorProfiles/screens/list/DisableAcceleratorProfileModal'; +import { updateAcceleratorProfile } from '~/services/acceleratorProfileService'; + +type AcceleratorProfileEnableToggleProps = { + enabled: boolean; + name: string; +}; + +const AcceleratorProfileEnableToggle: React.FC = ({ + enabled, + name, +}) => { + const label = enabled ? 'enabled' : 'stopped'; + const [isModalOpen, setIsModalOpen] = React.useState(false); + const [inProgress, setInProgress] = React.useState(false); + + return ( + <> + { + if (enabled) { + setIsModalOpen(true); + } else { + setInProgress(true); + updateAcceleratorProfile(name, true).then(() => setInProgress(false)); + } + }} + /> + { + if (confirmStatus) { + updateAcceleratorProfile(name, false); + } + setIsModalOpen(false); + }} + /> + + ); +}; + +export default AcceleratorProfileEnableToggle; diff --git a/frontend/src/pages/acceleratorProfiles/screens/list/DisableAcceleratorProfileModal.tsx b/frontend/src/pages/acceleratorProfiles/screens/list/DisableAcceleratorProfileModal.tsx new file mode 100644 index 0000000000..d59e9dc809 --- /dev/null +++ b/frontend/src/pages/acceleratorProfiles/screens/list/DisableAcceleratorProfileModal.tsx @@ -0,0 +1,31 @@ +import * as React from 'react'; +import { Button, Modal } from '@patternfly/react-core'; + +type DisableAcceleratorProfileModal = { + isOpen: boolean; + onClose: (confirmStatus: boolean) => void; +}; + +const DisableAcceleratorProfileModal: React.FC = ({ + isOpen, + onClose, +}) => ( + onClose(false)} + actions={[ + , + , + ]} + > + Disable this will disable accelerators for existing images and runtimes that want to use it. + +); + +export default DisableAcceleratorProfileModal; diff --git a/frontend/src/services/acceleratorProfileService.ts b/frontend/src/services/acceleratorProfileService.ts new file mode 100644 index 0000000000..34a4fa1f82 --- /dev/null +++ b/frontend/src/services/acceleratorProfileService.ts @@ -0,0 +1,12 @@ +import axios from 'axios'; +import { ResponseStatus } from '~/types'; + +export const updateAcceleratorProfile = (name: string, e: boolean): Promise => { + const url = `/api/accelerator-profiles/${name}`; + return axios + .put(url, { enabled: e }) + .then((response) => response.data) + .catch((e) => { + throw new Error(e.response.data.message); + }); +};