Unverified Commit 58a446bd authored by Jari Kolehmainen's avatar Jari Kolehmainen Committed by GitHub
Browse files

Refactor k8s api to common (#3553)


* refactor kube api to common
Signed-off-by: default avatarJari Kolehmainen <jari.kolehmainen@gmail.com>

* refactor more utils to common
Signed-off-by: default avatarJari Kolehmainen <jari.kolehmainen@gmail.com>

* refactor more utils to common
Signed-off-by: default avatarJari Kolehmainen <jari.kolehmainen@gmail.com>

* fix tests
Signed-off-by: default avatarJari Kolehmainen <jari.kolehmainen@gmail.com>

* switch to use node-fetch on both sides
Signed-off-by: default avatarJari Kolehmainen <jari.kolehmainen@gmail.com>

* cleanup
Signed-off-by: default avatarJari Kolehmainen <jari.kolehmainen@gmail.com>

* improve logger
Signed-off-by: default avatarJari Kolehmainen <jari.kolehmainen@gmail.com>

* fix lint errors
Signed-off-by: default avatarJari Kolehmainen <jari.kolehmainen@gmail.com>

* fix/improve tests
Signed-off-by: default avatarJari Kolehmainen <jari.kolehmainen@gmail.com>

* fix tests
Signed-off-by: default avatarJari Kolehmainen <jari.kolehmainen@gmail.com>

* fix node-fetch require error on prod build

Signed-off-by: Jari Kolehmainen <jari.koleh...
parent 476aa741
Showing with 161 additions and 32 deletions
+161 -32
File moved
......@@ -19,7 +19,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
import { ingressStore } from "../../components/+network-ingresses/ingress.store";
import { ingressStore } from "../../../renderer/components/+network-ingresses/ingress.store";
import { apiManager } from "../api-manager";
import { KubeApi } from "../kube-api";
import { KubeObject } from "../kube-object";
......
......@@ -20,12 +20,22 @@
*/
import { KubeApi } from "../kube-api";
import { KubeJsonApi } from "../kube-json-api";
import { KubeObject } from "../kube-object";
describe("KubeApi", () => {
let request: KubeJsonApi;
beforeEach(() => {
request = new KubeJsonApi({
serverAddress: `http://127.0.0.1:9999`,
apiBase: "/api-kube"
});
});
it("uses url from apiBase if apiBase contains the resource", async () => {
(fetch as any).mockResponse(async (request: any) => {
if (request.url === "/api-kube/apis/networking.k8s.io/v1") {
if (request.url === "http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1") {
return {
body: JSON.stringify({
resources: [{
......@@ -33,7 +43,7 @@ describe("KubeApi", () => {
}] as any[]
})
};
} else if (request.url === "/api-kube/apis/extensions/v1beta1") {
} else if (request.url === "http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1") {
// Even if the old API contains ingresses, KubeApi should prefer the apiBase url
return {
body: JSON.stringify({
......@@ -54,6 +64,7 @@ describe("KubeApi", () => {
const apiBase = "/apis/networking.k8s.io/v1/ingresses";
const fallbackApiBase = "/apis/extensions/v1beta1/ingresses";
const kubeApi = new KubeApi({
request,
objectConstructor: KubeObject,
apiBase,
fallbackApiBases: [fallbackApiBase],
......@@ -67,13 +78,13 @@ describe("KubeApi", () => {
it("uses url from fallbackApiBases if apiBase lacks the resource", async () => {
(fetch as any).mockResponse(async (request: any) => {
if (request.url === "/api-kube/apis/networking.k8s.io/v1") {
if (request.url === "http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1") {
return {
body: JSON.stringify({
resources: [] as any[]
})
};
} else if (request.url === "/api-kube/apis/extensions/v1beta1") {
} else if (request.url === "http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1") {
return {
body: JSON.stringify({
resources: [{
......@@ -93,6 +104,7 @@ describe("KubeApi", () => {
const apiBase = "apis/networking.k8s.io/v1/ingresses";
const fallbackApiBase = "/apis/extensions/v1beta1/ingresses";
const kubeApi = new KubeApi({
request,
objectConstructor: KubeObject,
apiBase,
fallbackApiBases: [fallbackApiBase],
......
......@@ -19,7 +19,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
import type { KubeObjectStore } from "../kube-object.store";
import type { KubeObjectStore } from "./kube-object.store";
import { action, observable, makeObservable } from "mobx";
import { autoBind, iter } from "../utils";
......@@ -49,6 +49,8 @@ export class ApiManager {
}
registerApi(apiBase: string, api: KubeApi<KubeObject>) {
if (!api.apiBase) return;
if (!this.apis.has(apiBase)) {
this.stores.forEach((store) => {
if (store.api === api) {
......@@ -84,8 +86,8 @@ export class ApiManager {
@action
registerStore(store: KubeObjectStore<KubeObject>, apis: KubeApi<KubeObject>[] = [store.api]) {
apis.forEach(api => {
this.stores.set(api.apiBase, store);
apis.filter(Boolean).forEach(api => {
if (api.apiBase) this.stores.set(api.apiBase, store);
});
}
......
/**
* Copyright (c) 2021 OpenLens Authors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
import type { Cluster } from "../../main/cluster";
export interface ClusterContext {
cluster?: Cluster;
allNamespaces: string[]; // available / allowed namespaces from cluster.ts
contextNamespaces: string[]; // selected by user (see: namespace-select.tsx)
}
......@@ -18,6 +18,7 @@
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
import { isClusterPageContext } from "../../utils/cluster-id-url-parsing";
import { KubeApi } from "../kube-api";
import { KubeObject } from "../kube-object";
......@@ -53,6 +54,17 @@ export class ClusterRoleBinding extends KubeObject {
}
}
export const clusterRoleBindingApi = new KubeApi({
objectConstructor: ClusterRoleBinding,
});
/**
* Only available within kubernetes cluster pages
*/
let clusterRoleBindingApi: KubeApi<ClusterRoleBinding>;
if (isClusterPageContext()) {
clusterRoleBindingApi = new KubeApi({
objectConstructor: ClusterRoleBinding,
});
}
export {
clusterRoleBindingApi
};
......@@ -19,6 +19,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
import { isClusterPageContext } from "../../utils/cluster-id-url-parsing";
import { KubeApi } from "../kube-api";
import { KubeObject } from "../kube-object";
......@@ -41,6 +42,17 @@ export class ClusterRole extends KubeObject {
}
}
export const clusterRoleApi = new KubeApi({
objectConstructor: ClusterRole,
});
/**
* Only available within kubernetes cluster pages
*/
let clusterRoleApi: KubeApi<ClusterRole>;
if (isClusterPageContext()) { // initialize automatically only when within a cluster iframe/context
clusterRoleApi = new KubeApi({
objectConstructor: ClusterRole,
});
}
export {
clusterRoleApi
};
......@@ -22,6 +22,7 @@
import { IMetrics, IMetricsReqParams, metricsApi } from "./metrics.api";
import { KubeObject } from "../kube-object";
import { KubeApi } from "../kube-api";
import { isClusterPageContext } from "../../utils/cluster-id-url-parsing";
export class ClusterApi extends KubeApi<Cluster> {
static kind = "Cluster";
......@@ -122,6 +123,17 @@ export class Cluster extends KubeObject {
}
}
export const clusterApi = new ClusterApi({
objectConstructor: Cluster,
});
/**
* Only available within kubernetes cluster pages
*/
let clusterApi: ClusterApi;
if (isClusterPageContext()) { // initialize automatically only when within a cluster iframe/context
clusterApi = new ClusterApi({
objectConstructor: Cluster,
});
}
export {
clusterApi
};
......@@ -22,7 +22,8 @@
import { KubeObject } from "../kube-object";
import type { KubeJsonApiData } from "../kube-json-api";
import { KubeApi } from "../kube-api";
import { autoBind } from "../../../common/utils";
import { autoBind } from "../../utils";
import { isClusterPageContext } from "../../utils/cluster-id-url-parsing";
export interface ConfigMap {
data: {
......@@ -47,6 +48,17 @@ export class ConfigMap extends KubeObject {
}
}
export const configMapApi = new KubeApi({
objectConstructor: ConfigMap,
});
/**
* Only available within kubernetes cluster pages
*/
let configMapApi: KubeApi<ConfigMap>;
if (isClusterPageContext()) {
configMapApi = new KubeApi({
objectConstructor: ConfigMap,
});
}
export {
configMapApi
};
......@@ -21,7 +21,8 @@
import { KubeObject } from "../kube-object";
import { KubeApi } from "../kube-api";
import { crdResourcesURL } from "../../../common/routes";
import { crdResourcesURL } from "../../routes";
import { isClusterPageContext } from "../../utils/cluster-id-url-parsing";
type AdditionalPrinterColumnsCommon = {
name: string;
......@@ -174,7 +175,18 @@ export class CustomResourceDefinition extends KubeObject {
}
}
export const crdApi = new KubeApi<CustomResourceDefinition>({
objectConstructor: CustomResourceDefinition,
checkPreferredVersion: true,
});
/**
* Only available within kubernetes cluster pages
*/
let crdApi: KubeApi<CustomResourceDefinition>;
if (isClusterPageContext()) {
crdApi = new KubeApi<CustomResourceDefinition>({
objectConstructor: CustomResourceDefinition,
checkPreferredVersion: true,
});
}
export {
crdApi
};
......@@ -26,6 +26,7 @@ import { formatDuration } from "../../utils/formatDuration";
import { autoBind } from "../../utils";
import { KubeApi } from "../kube-api";
import type { KubeJsonApiData } from "../kube-json-api";
import { isClusterPageContext } from "../../utils/cluster-id-url-parsing";
export class CronJobApi extends KubeApi<CronJob> {
suspend(params: { namespace: string; name: string }) {
......@@ -140,6 +141,17 @@ export class CronJob extends KubeObject {
}
}
export const cronJobApi = new CronJobApi({
objectConstructor: CronJob,
});
/**
* Only available within kubernetes cluster pages
*/
let cronJobApi: CronJobApi;
if (isClusterPageContext()) {
cronJobApi = new CronJobApi({
objectConstructor: CronJob,
});
}
export {
cronJobApi
};
......@@ -26,6 +26,7 @@ import { KubeApi } from "../kube-api";
import { metricsApi } from "./metrics.api";
import type { KubeJsonApiData } from "../kube-json-api";
import type { IPodContainer, IPodMetrics } from "./pods.api";
import { isClusterPageContext } from "../../utils/cluster-id-url-parsing";
export class DaemonSet extends WorkloadKubeObject {
static kind = "DaemonSet";
......@@ -116,6 +117,17 @@ export function getMetricsForDaemonSets(daemonsets: DaemonSet[], namespace: stri
});
}
export const daemonSetApi = new DaemonSetApi({
objectConstructor: DaemonSet,
});
/**
* Only available within kubernetes cluster pages
*/
let daemonSetApi: DaemonSetApi;
if (isClusterPageContext()) {
daemonSetApi = new DaemonSetApi({
objectConstructor: DaemonSet,
});
}
export {
daemonSetApi
};
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment