Skip to content

Commit

Permalink
[RHOAIENG-1106] Storage classes table
Browse files Browse the repository at this point in the history
  • Loading branch information
jpuzz0 committed Sep 6, 2024
1 parent d786249 commit eb6be9a
Show file tree
Hide file tree
Showing 13 changed files with 730 additions and 117 deletions.
24 changes: 20 additions & 4 deletions backend/src/routes/api/storage-class/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,23 @@ export async function updateStorageClassConfig(
'storageclasses',
params.storageClassName,
);
const existingAnnotations = (storageClass.body as K8sResourceCommon).metadata.annotations || {};
let existingStorageClassConfig = null;

// Extract and update the annotations
const annotations = (storageClass.body as K8sResourceCommon).metadata.annotations || {};
annotations['opendatahub.io/sc-config'] = JSON.stringify(body);
try {
existingStorageClassConfig = JSON.parse(existingAnnotations['opendatahub.io/sc-config']);
} catch (e) {
fastify.log.error(e, 'Unable to extend existing storage class config.');
}

const storageClassAnnotation = {
'opendatahub.io/sc-config': body
? JSON.stringify({
...existingStorageClassConfig,
...body,
})
: '',
};

// Patch the StorageClass with the new annotations
await fastify.kube.customObjectsApi.patchClusterCustomObject(
Expand All @@ -36,7 +49,10 @@ export async function updateStorageClassConfig(
params.storageClassName,
{
metadata: {
annotations,
annotations: {
...existingAnnotations,
...storageClassAnnotation,
},
},
},
undefined,
Expand Down
111 changes: 24 additions & 87 deletions frontend/src/__mocks__/mockStorageClasses.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { K8sResourceListResult, StorageClassKind } from '~/k8sTypes';

type MockStorageClass = Omit<StorageClassKind, 'apiVersion' | 'kind'>;
export type MockStorageClass = Omit<StorageClassKind, 'apiVersion' | 'kind'>;

export type MockStorageClassList = Omit<K8sResourceListResult<MockStorageClass>, 'metadata'> & {
metadata: {
Expand All @@ -19,34 +19,32 @@ export const mockStorageClassList = (
items: storageClasses,
});

const mockStorageClasses: MockStorageClass[] = [
export const mockStorageClasses: MockStorageClass[] = [
{
metadata: {
name: 'csi-manila-ceph',
uid: 'c3c05a4a-c1b7-4358-a246-da6b6dfd12cd',
resourceVersion: '50902775',
creationTimestamp: '2024-07-04T09:21:40Z',
name: 'openshift-default-sc',
uid: '5de188ae-aa8e-43d1-a714-4d60ecc5c6da',
resourceVersion: '50902774',
creationTimestamp: '2024-07-04T09:20:40Z',
annotations: {
'opendatahub.io/sc-config':
'{"displayName":"csi-manila-ceph","isDefault":false,"isEnabled":false,"lastModified":"2024-08-22T15:42:53.100Z"}',
'{"displayName":"openshift-default-sc","isDefault":true,"isEnabled":true,"lastModified":"2024-08-22T15:42:53.101Z"}',
'storageclass.kubernetes.io/is-default-class': 'true',
},
managedFields: [
{
manager: 'csi-driver-manila-operator',
manager: 'openstack-cinder-csi-driver-operator',
operation: 'Update',
apiVersion: 'storage.k8s.io/v1',
time: '2024-07-04T09:21:40Z',
time: '2024-07-04T09:20:40Z',
fieldsType: 'FieldsV1',
fieldsV1: {
'f:parameters': {
'.': {},
'f:csi.storage.k8s.io/node-publish-secret-name': {},
'f:csi.storage.k8s.io/node-publish-secret-namespace': {},
'f:csi.storage.k8s.io/node-stage-secret-name': {},
'f:csi.storage.k8s.io/node-stage-secret-namespace': {},
'f:csi.storage.k8s.io/provisioner-secret-name': {},
'f:csi.storage.k8s.io/provisioner-secret-namespace': {},
'f:type': {},
'f:allowVolumeExpansion': {},
'f:metadata': {
'f:annotations': {
'.': {},
'f:storageclass.kubernetes.io/is-default-class': {},
},
},
'f:provisioner': {},
'f:reclaimPolicy': {},
Expand All @@ -62,36 +60,27 @@ const mockStorageClasses: MockStorageClass[] = [
fieldsV1: {
'f:metadata': {
'f:annotations': {
'.': {},
'f:opendatahub.io/sc-config': {},
},
},
},
},
],
},
provisioner: 'manila.csi.openstack.org',
parameters: JSON.stringify({
'csi.storage.k8s.io/node-publish-secret-name': 'csi-manila-secrets',
'csi.storage.k8s.io/node-publish-secret-namespace': 'openshift-manila-csi-driver',
'csi.storage.k8s.io/node-stage-secret-name': 'csi-manila-secrets',
'csi.storage.k8s.io/node-stage-secret-namespace': 'openshift-manila-csi-driver',
'csi.storage.k8s.io/provisioner-secret-name': 'csi-manila-secrets',
'csi.storage.k8s.io/provisioner-secret-namespace': 'openshift-manila-csi-driver',
type: 'ceph',
}),
provisioner: 'cinder.csi.openstack.org',
reclaimPolicy: 'Delete',
volumeBindingMode: 'Immediate',
allowVolumeExpansion: true,
volumeBindingMode: 'WaitForFirstConsumer',
},
{
metadata: {
name: 'csi-manila-netapp',
uid: 'f818edb6-3936-4ca0-90af-87f469c177d8',
resourceVersion: '50902773',
name: 'test-storage-class-1',
uid: 'c3c05a4a-c1b7-4358-a246-da6b6dfd12cd',
resourceVersion: '50902775',
creationTimestamp: '2024-07-04T09:21:40Z',
annotations: {
'opendatahub.io/sc-config':
'{"displayName":"csi-manila-netapp","isDefault":false,"isEnabled":false,"lastModified":"2024-08-22T15:42:53.101Z"}',
'{"displayName":"Test SC 1","isDefault":false,"isEnabled":false,"lastModified":"2024-08-22T15:42:53.100Z"}',
},
managedFields: [
{
Expand Down Expand Up @@ -141,61 +130,9 @@ const mockStorageClasses: MockStorageClass[] = [
'csi.storage.k8s.io/node-stage-secret-namespace': 'openshift-manila-csi-driver',
'csi.storage.k8s.io/provisioner-secret-name': 'csi-manila-secrets',
'csi.storage.k8s.io/provisioner-secret-namespace': 'openshift-manila-csi-driver',
type: 'netapp',
type: 'ceph',
}),
reclaimPolicy: 'Delete',
volumeBindingMode: 'Immediate',
},
{
metadata: {
name: 'standard-csi',
uid: '5de188ae-aa8e-43d1-a714-4d60ecc5c6da',
resourceVersion: '50902774',
creationTimestamp: '2024-07-04T09:20:40Z',
annotations: {
'opendatahub.io/sc-config':
'{"displayName":"standard-csi","isDefault":true,"isEnabled":true,"lastModified":"2024-08-22T15:42:53.101Z"}',
'storageclass.kubernetes.io/is-default-class': 'true',
},
managedFields: [
{
manager: 'openstack-cinder-csi-driver-operator',
operation: 'Update',
apiVersion: 'storage.k8s.io/v1',
time: '2024-07-04T09:20:40Z',
fieldsType: 'FieldsV1',
fieldsV1: {
'f:allowVolumeExpansion': {},
'f:metadata': {
'f:annotations': {
'.': {},
'f:storageclass.kubernetes.io/is-default-class': {},
},
},
'f:provisioner': {},
'f:reclaimPolicy': {},
'f:volumeBindingMode': {},
},
},
{
manager: 'unknown',
operation: 'Update',
apiVersion: 'storage.k8s.io/v1',
time: '2024-08-22T15:42:53Z',
fieldsType: 'FieldsV1',
fieldsV1: {
'f:metadata': {
'f:annotations': {
'f:opendatahub.io/sc-config': {},
},
},
},
},
],
},
provisioner: 'cinder.csi.openstack.org',
reclaimPolicy: 'Delete',
allowVolumeExpansion: true,
volumeBindingMode: 'WaitForFirstConsumer',
},
];
54 changes: 54 additions & 0 deletions frontend/src/__tests__/cypress/cypress/pages/storageClasses.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import type { MockStorageClass } from '~/__mocks__';
import { mockStorageClassList } from '~/__mocks__';
import { appChrome } from '~/__tests__/cypress/cypress/pages/appChrome';
import { TableRow } from '~/__tests__/cypress/cypress/pages/components/table';

class StorageClassesPage {
visit() {
Expand All @@ -20,4 +23,55 @@ class StorageClassesPage {
}
}

class StorageClassesTableRow extends TableRow {
findOpenshiftDefaultLabel() {
return this.find().findByTestId('openshift-sc-default-label');
}

findEnableSwitch() {
return this.find().findByTestId('enable-switch');
}

findDefaultRadio() {
return this.find().findByTestId('set-default-radio');
}

findOpenshiftScName() {
return this.find().find(`[data-label="Openshift storage class"]`);
}
}

class StorageClassesTable {
find() {
return cy.findByTestId('storage-classes-table');
}

getRowByName(name: string) {
return new StorageClassesTableRow(() =>
this.find().find(`[data-label="Display name"]`).contains(name).parents('tr'),
);
}

findRowByName(name: string) {
return this.getRowByName(name).find();
}

mockUpdateStorageClass(storageClassName: string, times?: number) {
return cy.interceptOdh(
`PUT /api/storage-class/:name/config`,
{ path: { name: storageClassName }, times },
{ success: true, error: '' },
);
}

mockGetStorageClasses(storageClasses: MockStorageClass[], times?: number) {
return cy.interceptOdh(
'GET /api/k8s/apis/storage.k8s.io/v1/storageclasses',
{ times },
mockStorageClassList(storageClasses),
);
}
}

export const storageClassesPage = new StorageClassesPage();
export const storageClassesTable = new StorageClassesTable();
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import type {
OdhDocument,
PrometheusQueryRangeResponse,
PrometheusQueryResponse,
ResponseStatus,
SubscriptionStatusData,
} from '~/types';
import type {
Expand Down Expand Up @@ -195,8 +196,14 @@ declare global {
) => Cypress.Chainable<null>) &
((
type: 'GET /api/k8s/apis/storage.k8s.io/v1/storageclasses',
options: { times?: number },
response: OdhResponse<MockStorageClassList>,
) => Cypress.Chainable<null>) &
((
type: 'PUT /api/storage-class/:name/config',
options: { path: { name: string }; times?: number },
response: OdhResponse<ResponseStatus>,
) => Cypress.Chainable<null>) &
((
type: 'GET /api/images/byon',
response: OdhResponse<BYONImage[]>,
Expand Down
Loading

0 comments on commit eb6be9a

Please sign in to comment.