From 67407bcb2d455ac14494a97bca841995af59b594 Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Fri, 8 Oct 2021 12:03:59 -0400 Subject: [PATCH] Use the served and storage version of a CRD instead of the first Signed-off-by: Sebastian Malton --- src/common/k8s-api/endpoints/crd.api.ts | 34 ++++++++++++++++++++++--- src/common/k8s-api/json-api.ts | 3 +-- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/common/k8s-api/endpoints/crd.api.ts b/src/common/k8s-api/endpoints/crd.api.ts index b1ab179cc4..015f2ffb1b 100644 --- a/src/common/k8s-api/endpoints/crd.api.ts +++ b/src/common/k8s-api/endpoints/crd.api.ts @@ -19,10 +19,11 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { KubeObject } from "../kube-object"; +import { KubeCreationError, KubeObject } from "../kube-object"; import { KubeApi } from "../kube-api"; import { crdResourcesURL } from "../../routes"; import { isClusterPageContext } from "../../utils/cluster-id-url-parsing"; +import type { KubeJsonApiData } from "../kube-json-api"; type AdditionalPrinterColumnsCommon = { name: string; @@ -42,7 +43,10 @@ type AdditionalPrinterColumnsV1Beta = AdditionalPrinterColumnsCommon & { export interface CustomResourceDefinition { spec: { group: string; - version?: string; // deprecated in v1 api + /** + * This is deprecated for apiextensions.k8s.io/v1 but used previously + */ + version?: string; names: { plural: string; singular: string; @@ -88,6 +92,14 @@ export class CustomResourceDefinition extends KubeObject { static namespaced = false; static apiBase = "/apis/apiextensions.k8s.io/v1/customresourcedefinitions"; + constructor(data: KubeJsonApiData) { + super(data); + + if (!data.spec || typeof data.spec !== "object") { + throw new KubeCreationError("Cannot create a CustomResourceDefinition from an object without spec", data); + } + } + getResourceUrl() { return crdResourcesURL({ params: { @@ -126,8 +138,22 @@ export class CustomResourceDefinition extends KubeObject { } getVersion() { - // v1 has removed the spec.version property, if it is present it must match the first version - return this.spec.versions?.[0]?.name ?? this.spec.version; + // Prefer the modern `versions` over the legacy `version` + for (const version of this.spec.versions || []) { + /** + * If the version is not served then 404 errors will occur + * We should also prefer the storage version + */ + if (version.served && version.storage) { + return version.name; + } + } + + if (this.spec.version) { + return this.spec.version; + } + + throw new Error(`Failed to find a version for CustomResourceDefinition ${this.metadata.name}`); } isNamespaced() { diff --git a/src/common/k8s-api/json-api.ts b/src/common/k8s-api/json-api.ts index 8690521099..42b3a02975 100644 --- a/src/common/k8s-api/json-api.ts +++ b/src/common/k8s-api/json-api.ts @@ -27,8 +27,7 @@ import { stringify } from "querystring"; import { EventEmitter } from "../../common/event-emitter"; import logger from "../../common/logger"; -export interface JsonApiData { -} +export type JsonApiData = Record; export interface JsonApiError { code?: number;