mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
fix: allow to select kube-api objects with label & field selectors
Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
parent
469b723469
commit
41896a2288
@ -1,6 +1,6 @@
|
||||
import { KubeObject } from "../kube-object";
|
||||
import { VersionedKubeApi } from "../kube-api-versioned";
|
||||
import { crdResourcesURL } from "../../components/+custom-resources/crd.route";
|
||||
import { KubeApi } from "../kube-api";
|
||||
|
||||
type AdditionalPrinterColumnsCommon = {
|
||||
name: string;
|
||||
@ -146,6 +146,7 @@ export class CustomResourceDefinition extends KubeObject {
|
||||
}
|
||||
}
|
||||
|
||||
export const crdApi = new VersionedKubeApi<CustomResourceDefinition>({
|
||||
objectConstructor: CustomResourceDefinition
|
||||
export const crdApi = new KubeApi<CustomResourceDefinition>({
|
||||
objectConstructor: CustomResourceDefinition,
|
||||
checkPreferredVersion: true,
|
||||
});
|
||||
|
||||
@ -1,56 +0,0 @@
|
||||
import { stringify } from "querystring";
|
||||
import { KubeObject } from "./kube-object";
|
||||
import { createKubeApiURL } from "./kube-api-parse";
|
||||
import { KubeApi, IKubeApiQueryParams, IKubeApiOptions } from "./kube-api";
|
||||
import { apiManager } from "./api-manager";
|
||||
|
||||
export class VersionedKubeApi<T extends KubeObject = any> extends KubeApi<T> {
|
||||
private preferredVersion?: string;
|
||||
|
||||
constructor(opts: IKubeApiOptions<T>) {
|
||||
super(opts);
|
||||
|
||||
this.getPreferredVersion().then(() => {
|
||||
if (this.apiBase != opts.apiBase)
|
||||
apiManager.registerApi(this.apiBase, this);
|
||||
});
|
||||
}
|
||||
|
||||
// override this property to make read-write
|
||||
apiBase: string
|
||||
|
||||
async getPreferredVersion() {
|
||||
if (this.preferredVersion) return;
|
||||
|
||||
const apiGroupVersion = await this.request.get<{ preferredVersion?: { version: string; }; }>(`${this.apiPrefix}/${this.apiGroup}`);
|
||||
|
||||
if (!apiGroupVersion?.preferredVersion) return;
|
||||
|
||||
this.preferredVersion = apiGroupVersion.preferredVersion.version;
|
||||
|
||||
// update apiBase
|
||||
this.apiBase = this.getUrl();
|
||||
}
|
||||
|
||||
async list({ namespace = "" } = {}, query?: IKubeApiQueryParams): Promise<T[]> {
|
||||
await this.getPreferredVersion();
|
||||
return await super.list({namespace}, query);
|
||||
}
|
||||
async get({ name = "", namespace = "default" } = {}, query?: IKubeApiQueryParams): Promise<T> {
|
||||
await this.getPreferredVersion();
|
||||
return super.get({ name, namespace }, query);
|
||||
}
|
||||
|
||||
getUrl({ name = "", namespace = "" } = {}, query?: Partial<IKubeApiQueryParams>) {
|
||||
const { apiPrefix, apiGroup, apiVersion, apiResource, preferredVersion, isNamespaced } = this;
|
||||
|
||||
const resourcePath = createKubeApiURL({
|
||||
apiPrefix: apiPrefix,
|
||||
apiVersion: `${apiGroup}/${preferredVersion ?? apiVersion}`,
|
||||
resource: apiResource,
|
||||
namespace: isNamespaced ? namespace : undefined,
|
||||
name: name,
|
||||
});
|
||||
return resourcePath + (query ? `?` + stringify(query) : "");
|
||||
}
|
||||
}
|
||||
@ -16,6 +16,7 @@ export interface IKubeApiOptions<T extends KubeObject> {
|
||||
request?: KubeJsonApi;
|
||||
isNamespaced?: boolean;
|
||||
kind?: string;
|
||||
checkPreferredVersion?: boolean;
|
||||
}
|
||||
|
||||
export interface IKubeApiQueryParams {
|
||||
@ -24,6 +25,14 @@ export interface IKubeApiQueryParams {
|
||||
timeoutSeconds?: number;
|
||||
limit?: number; // doesn't work with ?watch
|
||||
continue?: string; // might be used with ?limit from second request
|
||||
labelSelector?: string | string[]; // restrict list of objects by their labels, e.g. labelSelector: ["label=value"]
|
||||
fieldSelector?: string | string[]; // restrict list of objects by their fields, e.g. fieldSelector: "field=name"
|
||||
}
|
||||
|
||||
export interface IKubeApiPreferredVersion {
|
||||
preferredVersion?: {
|
||||
version: string;
|
||||
}
|
||||
}
|
||||
|
||||
export interface IKubeApiCluster {
|
||||
@ -58,7 +67,7 @@ export class KubeApi<T extends KubeObject = any> {
|
||||
readonly apiPrefix: string
|
||||
readonly apiGroup: string
|
||||
readonly apiVersion: string
|
||||
readonly apiVersionWithGroup: string
|
||||
readonly apiVersionPreferred?: string;
|
||||
readonly apiResource: string
|
||||
readonly isNamespaced: boolean
|
||||
|
||||
@ -84,15 +93,36 @@ export class KubeApi<T extends KubeObject = any> {
|
||||
this.apiPrefix = apiPrefix;
|
||||
this.apiGroup = apiGroup;
|
||||
this.apiVersion = apiVersion;
|
||||
this.apiVersionWithGroup = apiVersionWithGroup;
|
||||
this.apiResource = resource;
|
||||
this.request = request;
|
||||
this.objectConstructor = objectConstructor;
|
||||
|
||||
this.checkPreferredVersion();
|
||||
this.parseResponse = this.parseResponse.bind(this);
|
||||
apiManager.registerApi(apiBase, this);
|
||||
}
|
||||
|
||||
get apiVersionWithGroup() {
|
||||
return [this.apiGroup, this.apiVersionPreferred ?? this.apiVersion]
|
||||
.filter(Boolean)
|
||||
.join("/")
|
||||
}
|
||||
|
||||
protected async checkPreferredVersion() {
|
||||
if (!this.options.checkPreferredVersion || this.apiVersionPreferred === undefined) {
|
||||
return;
|
||||
}
|
||||
const res = await this.request.get<IKubeApiPreferredVersion>(`${this.apiPrefix}/${this.apiGroup}`);
|
||||
Object.defineProperty(this, "apiVersionPreferred", {
|
||||
value: res?.preferredVersion?.version ?? null,
|
||||
});
|
||||
|
||||
if (this.apiVersionPreferred) {
|
||||
Object.defineProperty(this, "apiBase", { value: this.getUrl() })
|
||||
apiManager.registerApi(this.apiBase, this);
|
||||
}
|
||||
}
|
||||
|
||||
setResourceVersion(namespace = "", newVersion: string) {
|
||||
this.resourceVersions.set(namespace, newVersion);
|
||||
}
|
||||
@ -106,15 +136,24 @@ export class KubeApi<T extends KubeObject = any> {
|
||||
}
|
||||
|
||||
getUrl({ name = "", namespace = "" } = {}, query?: Partial<IKubeApiQueryParams>) {
|
||||
const { apiPrefix, apiVersionWithGroup, apiResource } = this;
|
||||
const resourcePath = createKubeApiURL({
|
||||
apiPrefix: apiPrefix,
|
||||
apiVersion: apiVersionWithGroup,
|
||||
resource: apiResource,
|
||||
apiPrefix: this.apiPrefix,
|
||||
apiVersion: this.apiVersionWithGroup,
|
||||
resource: this.apiResource,
|
||||
namespace: this.isNamespaced ? namespace : undefined,
|
||||
name: name,
|
||||
});
|
||||
return resourcePath + (query ? `?` + stringify(query) : "");
|
||||
return resourcePath + (query ? `?` + stringify(this.normalizeQuery(query)) : "");
|
||||
}
|
||||
|
||||
protected normalizeQuery(query: Partial<IKubeApiQueryParams> = {}) {
|
||||
if (query.labelSelector) {
|
||||
query.labelSelector = [query.labelSelector].flat().join(",")
|
||||
}
|
||||
if (query.fieldSelector) {
|
||||
query.fieldSelector = [query.fieldSelector].flat().join(",")
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
protected parseResponse(data: KubeJsonApiData | KubeJsonApiData[] | KubeJsonApiDataList, namespace?: string): any {
|
||||
@ -144,18 +183,21 @@ export class KubeApi<T extends KubeObject = any> {
|
||||
}
|
||||
|
||||
async list({ namespace = "" } = {}, query?: IKubeApiQueryParams): Promise<T[]> {
|
||||
await this.checkPreferredVersion();
|
||||
return this.request
|
||||
.get(this.getUrl({ namespace }), { query })
|
||||
.then(data => this.parseResponse(data, namespace));
|
||||
}
|
||||
|
||||
async get({ name = "", namespace = "default" } = {}, query?: IKubeApiQueryParams): Promise<T> {
|
||||
await this.checkPreferredVersion();
|
||||
return this.request
|
||||
.get(this.getUrl({ namespace, name }), { query })
|
||||
.then(this.parseResponse);
|
||||
}
|
||||
|
||||
async create({ name = "", namespace = "default" } = {}, data?: Partial<T>): Promise<T> {
|
||||
await this.checkPreferredVersion();
|
||||
const apiUrl = this.getUrl({ namespace });
|
||||
|
||||
return this.request
|
||||
@ -173,6 +215,7 @@ export class KubeApi<T extends KubeObject = any> {
|
||||
}
|
||||
|
||||
async update({ name = "", namespace = "default" } = {}, data?: Partial<T>): Promise<T> {
|
||||
await this.checkPreferredVersion();
|
||||
const apiUrl = this.getUrl({ namespace, name });
|
||||
return this.request
|
||||
.put(apiUrl, { data })
|
||||
@ -180,6 +223,7 @@ export class KubeApi<T extends KubeObject = any> {
|
||||
}
|
||||
|
||||
async delete({ name = "", namespace = "default" }) {
|
||||
await this.checkPreferredVersion();
|
||||
const apiUrl = this.getUrl({ namespace, name });
|
||||
return this.request.del(apiUrl)
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user