From 8dee67db82ee2e89da27eca82ada27fad3a93fa1 Mon Sep 17 00:00:00 2001 From: guilhane Date: Tue, 11 Jun 2024 16:48:45 +0200 Subject: [PATCH] frontend: Add non-editable fields to KubeObjects and exclude them in YAML editor This PR adds a new var to KubeObject classes to declare non-editable fields. It also sets a new getEditableObject method that uses these fields and removes them from an object clone and ensure YAML editor uses getEditableObject to exclude non-editable fields. Fixes: #2032 Signed-off-by: guilhane --- .../components/common/Resource/EditButton.tsx | 2 +- frontend/src/lib/k8s/cluster.ts | 27 +++++++++++++++++++ frontend/src/lib/k8s/crd.ts | 1 + 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/common/Resource/EditButton.tsx b/frontend/src/components/common/Resource/EditButton.tsx index 1f0b462095..bd68c54b66 100644 --- a/frontend/src/components/common/Resource/EditButton.tsx +++ b/frontend/src/components/common/Resource/EditButton.tsx @@ -108,7 +108,7 @@ export default function EditButton(props: EditButtonProps) { /> {openDialog && ( setOpenDialog(false)} onSave={handleSave} diff --git a/frontend/src/lib/k8s/cluster.ts b/frontend/src/lib/k8s/cluster.ts index 9c60b753ff..5c776a9200 100644 --- a/frontend/src/lib/k8s/cluster.ts +++ b/frontend/src/lib/k8s/cluster.ts @@ -1,4 +1,5 @@ import { OpPatch } from 'json-patch'; +import { JSONPath } from 'jsonpath-plus'; import { cloneDeep, unset } from 'lodash'; import React from 'react'; import helpers from '../../helpers'; @@ -329,6 +330,11 @@ export interface AuthRequestResourceAttrs { group?: string; verb?: string; } +type JsonPath = T extends object + ? { + [K in keyof T]: K extends string ? `${K}` | `${K}.${JsonPath}` : never; + }[keyof T] + : never; // @todo: uses of makeKubeObject somehow end up in an 'any' type. @@ -343,6 +349,7 @@ export function makeKubeObject( class KubeObject { static apiEndpoint: ReturnType; jsonData: T | null = null; + public static readOnlyFields: JsonPath[]; private readonly _clusterName: string; constructor(json: T) { @@ -430,6 +437,26 @@ export function makeKubeObject( return this.apiEndpoint.isNamespaced; } + getEditableObject() { + const fieldsToRemove = this._class().readOnlyFields; + const code = this.jsonData ? cloneDeep(this.jsonData) : {}; + + fieldsToRemove?.forEach((path: JsonPath) => { + JSONPath({ + path, + json: code, + callback: (result, type, fullPayload) => { + if (fullPayload.parent && fullPayload.parentProperty) { + delete fullPayload.parent[fullPayload.parentProperty]; + } + }, + resultType: 'all', + }); + }); + + return code; + } + // @todo: apiList has 'any' return type. /** * Returns the API endpoint for this object. diff --git a/frontend/src/lib/k8s/crd.ts b/frontend/src/lib/k8s/crd.ts index 9e1b7e29ef..91f7763e4e 100644 --- a/frontend/src/lib/k8s/crd.ts +++ b/frontend/src/lib/k8s/crd.ts @@ -52,6 +52,7 @@ class CustomResourceDefinition extends makeKubeObject('crd') { ['apiextensions.k8s.io', 'v1', 'customresourcedefinitions'], ['apiextensions.k8s.io', 'v1beta1', 'customresourcedefinitions'] ); + static readOnlyFields = ['metadata.managedFields']; static get className(): string { return 'CustomResourceDefinition';