1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Refactoring: removed kube versioned api (#1328)

Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
Roman 2020-11-12 08:39:50 +02:00 committed by GitHub
parent 00be4aa184
commit 1f88c05e82
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 68 deletions

View File

@ -2,7 +2,6 @@ export { isAllowedResource } from "../../common/rbac"
export { apiManager } from "../../renderer/api/api-manager";
export { KubeObjectStore } from "../../renderer/kube-object.store"
export { KubeApi, forCluster, IKubeApiCluster } from "../../renderer/api/kube-api";
export { VersionedKubeApi } from "../../renderer/api/kube-api-versioned";
export { KubeObject } from "../../renderer/api/kube-object";
export { Pod, podsApi, PodsApi, IPodContainer, IPodContainerStatus } from "../../renderer/api/endpoints";
export { Node, nodesApi, NodesApi } from "../../renderer/api/endpoints";
@ -32,10 +31,10 @@ export { RoleBinding, roleBindingApi } from "../../renderer/api/endpoints";
export { ClusterRole, clusterRoleApi } from "../../renderer/api/endpoints";
export { ClusterRoleBinding, clusterRoleBindingApi } from "../../renderer/api/endpoints";
export { CustomResourceDefinition, crdApi } from "../../renderer/api/endpoints";
export { KubeObjectStatus, KubeObjectStatusLevel} from "./kube-object-status"
export { KubeObjectStatus, KubeObjectStatusLevel } from "./kube-object-status"
// stores
export type { EventStore } from "../../renderer/components/+events/event.store"
export type { EventStore } from "../../renderer/components/+events/event.store"
export type { PodsStore } from "../../renderer/components/+workloads-pods/pods.store"
export type { NodesStore } from "../../renderer/components/+nodes/nodes.store"
export type { DeploymentStore } from "../../renderer/components/+workloads-deployments/deployments.store"

View File

@ -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,
});

View File

@ -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(this.normalizeQuery(query)) : "");
}
}

View File

@ -16,6 +16,7 @@ export interface IKubeApiOptions<T extends KubeObject> {
request?: KubeJsonApi;
isNamespaced?: boolean;
kind?: string;
checkPreferredVersion?: boolean;
}
export interface IKubeApiQueryParams {
@ -28,6 +29,12 @@ export interface IKubeApiQueryParams {
fieldSelector?: string | string[]; // restrict list of objects by their fields, e.g. fieldSelector: "field=name"
}
export interface IKubePreferredVersion {
preferredVersion?: {
version: string;
}
}
export interface IKubeApiCluster {
id: string;
}
@ -60,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
@ -86,15 +93,35 @@ 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) {
const res = await this.request.get<IKubePreferredVersion>(`${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);
}
@ -108,11 +135,10 @@ 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,
});
@ -156,18 +182,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
@ -185,6 +214,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 })
@ -192,6 +222,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)
}