mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
chore: Change refactoring of implementation to maintain behaviour
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
1 parent
8395c262ad
commit
dcc5495312
8 files changed
+103
-94
No files matched your search
@@ -9,33 +9,35 @@ import apiKubeInjectable from "../../../renderer/k8s/api-kube.injectable";
|
||||
import type { StatefulSetApi } from "../endpoints";
|
||||
import statefulSetApiInjectable from "../endpoints/stateful-set.api.injectable";
|
||||
import type { KubeJsonApi } from "../kube-json-api";
|
||||
import type { AsyncFnMock } from "@async-fn/jest";
|
||||
import asyncFn from "@async-fn/jest";
|
||||
import { flushPromises } from "@k8slens/test-utils";
|
||||
|
||||
describe("StatefulSetApi", () => {
|
||||
let statefulSetApi: StatefulSetApi;
|
||||
let kubeJsonApi: jest.Mocked<KubeJsonApi>;
|
||||
let kubeJsonApiPatchMock: AsyncFnMock<KubeJsonApi["patch"]>;
|
||||
let kubeJsonApiGetMock: AsyncFnMock<KubeJsonApi["get"]>;
|
||||
|
||||
beforeEach(() => {
|
||||
const di = getDiForUnitTesting();
|
||||
|
||||
di.override(storesAndApisCanBeCreatedInjectable, () => true);
|
||||
kubeJsonApi = {
|
||||
getResponse: jest.fn(),
|
||||
get: jest.fn(),
|
||||
post: jest.fn(),
|
||||
put: jest.fn(),
|
||||
patch: jest.fn(),
|
||||
del: jest.fn(),
|
||||
} as never;
|
||||
di.override(apiKubeInjectable, () => kubeJsonApi);
|
||||
kubeJsonApiPatchMock = asyncFn();
|
||||
kubeJsonApiGetMock = asyncFn();
|
||||
di.override(apiKubeInjectable, () => ({
|
||||
get: kubeJsonApiGetMock,
|
||||
patch: kubeJsonApiPatchMock,
|
||||
} as Partial<KubeJsonApi> as KubeJsonApi));
|
||||
|
||||
statefulSetApi = di.inject(statefulSetApiInjectable);
|
||||
});
|
||||
|
||||
describe("scale", () => {
|
||||
it("requests Kubernetes API with PATCH verb and correct amount of replicas", () => {
|
||||
statefulSetApi.scale({ namespace: "default", name: "statefulset-1" }, 5);
|
||||
it("requests Kubernetes API with PATCH verb and correct amount of replicas", async () => {
|
||||
const req = statefulSetApi.scale({ namespace: "default", name: "statefulset-1" }, 5);
|
||||
|
||||
expect(kubeJsonApi.patch).toHaveBeenCalledWith("/apis/apps/v1/namespaces/default/statefulsets/statefulset-1/scale", {
|
||||
await flushPromises();
|
||||
expect(kubeJsonApiPatchMock).toHaveBeenCalledWith("/apis/apps/v1/namespaces/default/statefulsets/statefulset-1/scale", {
|
||||
data: {
|
||||
spec: {
|
||||
replicas: 5,
|
||||
@@ -47,6 +49,19 @@ describe("StatefulSetApi", () => {
|
||||
"content-type": "application/merge-patch+json",
|
||||
},
|
||||
});
|
||||
|
||||
await kubeJsonApiPatchMock.resolve({});
|
||||
await req;
|
||||
});
|
||||
|
||||
it("requests Kubernetes API with GET verb and correct sub-resource", async () => {
|
||||
const req = statefulSetApi.getReplicas({ namespace: "default", name: "statefulset-1" });
|
||||
|
||||
await flushPromises();
|
||||
expect(kubeJsonApiGetMock).toHaveBeenCalledWith("/apis/apps/v1/namespaces/default/statefulsets/statefulset-1/scale");
|
||||
await kubeJsonApiGetMock.resolve({ status: { replicas: 10 }});
|
||||
|
||||
expect(await req).toBe(10);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -8,7 +8,6 @@ import moment from "moment";
|
||||
import type { DerivedKubeApiOptions, KubeApiDependencies, NamespacedResourceDescriptor } from "../kube-api";
|
||||
import { KubeApi } from "../kube-api";
|
||||
import { Deployment } from "@k8slens/kube-object";
|
||||
import { hasTypedProperty, isNumber, isObject } from "@k8slens/utilities";
|
||||
|
||||
export class DeploymentApi extends KubeApi<Deployment> {
|
||||
constructor(deps: KubeApiDependencies, opts?: DerivedKubeApiOptions) {
|
||||
@@ -18,33 +17,14 @@ export class DeploymentApi extends KubeApi<Deployment> {
|
||||
});
|
||||
}
|
||||
|
||||
protected getScaleApiUrl(params: NamespacedResourceDescriptor) {
|
||||
return `${this.formatUrlForNotListing(params)}/scale`;
|
||||
}
|
||||
|
||||
async getReplicas(params: NamespacedResourceDescriptor): Promise<number> {
|
||||
const { status } = await this.request.get(this.getScaleApiUrl(params));
|
||||
const { status } = await this.getResourceScale(params);
|
||||
|
||||
if (isObject(status) && hasTypedProperty(status, "replicas", isNumber)) {
|
||||
return status.replicas;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return status.replicas;
|
||||
}
|
||||
|
||||
scale(params: NamespacedResourceDescriptor, replicas: number) {
|
||||
return this.request.patch(this.getScaleApiUrl(params), {
|
||||
data: {
|
||||
spec: {
|
||||
replicas,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
"content-type": "application/merge-patch+json",
|
||||
},
|
||||
});
|
||||
return this.scaleResource(params, { spec: { replicas }});
|
||||
}
|
||||
|
||||
restart(params: NamespacedResourceDescriptor) {
|
||||
|
||||
@@ -15,24 +15,13 @@ export class ReplicaSetApi extends KubeApi<ReplicaSet> {
|
||||
});
|
||||
}
|
||||
|
||||
protected getScaleApiUrl(params: NamespacedResourceDescriptor) {
|
||||
return `${this.formatUrlForNotListing(params)}/scale`;
|
||||
}
|
||||
|
||||
async getReplicas(params: NamespacedResourceDescriptor): Promise<number> {
|
||||
const { status } = await this.request.get(this.getScaleApiUrl(params));
|
||||
const { status } = await this.getResourceScale(params);
|
||||
|
||||
return (status as { replicas: number })?.replicas;
|
||||
return status.replicas;
|
||||
}
|
||||
|
||||
scale(params: NamespacedResourceDescriptor, replicas: number) {
|
||||
return this.request.put(this.getScaleApiUrl(params), {
|
||||
data: {
|
||||
metadata: params,
|
||||
spec: {
|
||||
replicas,
|
||||
},
|
||||
},
|
||||
});
|
||||
return this.scaleResource(params, { spec: { replicas }});
|
||||
}
|
||||
}
|
||||
@@ -25,17 +25,6 @@ export class ReplicationControllerApi extends KubeApi<ReplicationController> {
|
||||
}
|
||||
|
||||
scale(params: NamespacedResourceDescriptor, replicas: number): Promise<Scale> {
|
||||
return this.request.patch(this.getScaleApiUrl(params), {
|
||||
data: {
|
||||
metadata: params,
|
||||
spec: {
|
||||
replicas,
|
||||
},
|
||||
},
|
||||
}, {
|
||||
headers: {
|
||||
"content-type": "application/strategic-merge-patch+json",
|
||||
},
|
||||
});
|
||||
return this.scaleResource(params, { spec: { replicas }});
|
||||
}
|
||||
}
|
||||
@@ -17,23 +17,14 @@ export class StatefulSetApi extends KubeApi<StatefulSet> {
|
||||
});
|
||||
}
|
||||
|
||||
protected getScaleApiUrl(params: NamespacedResourceDescriptor) {
|
||||
return `${this.formatUrlForNotListing(params)}/scale`;
|
||||
}
|
||||
|
||||
async getReplicas(params: NamespacedResourceDescriptor): Promise<number> {
|
||||
const apiUrl = this.getScaleApiUrl(params);
|
||||
const { status = 0 } = await this.request.get(apiUrl) as { status?: number };
|
||||
const { status } = await this.getResourceScale(params);
|
||||
|
||||
return status;
|
||||
return status.replicas;
|
||||
}
|
||||
|
||||
scale(params: NamespacedResourceDescriptor, replicas: number) {
|
||||
return this.patch(params, {
|
||||
spec: {
|
||||
replicas,
|
||||
},
|
||||
}, "merge");
|
||||
return this.scaleResource(params, { spec: { replicas }});
|
||||
}
|
||||
|
||||
restart(params: NamespacedResourceDescriptor) {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import { merge } from "lodash";
|
||||
import { stringify } from "querystring";
|
||||
import { createKubeApiURL, parseKubeApi } from "./kube-api-parse";
|
||||
import type { KubeObjectConstructor, KubeJsonApiDataFor, KubeObjectMetadata, KubeJsonApiData, KubeObject, KubeObjectScope } from "@k8slens/kube-object";
|
||||
import type { KubeObjectConstructor, KubeJsonApiDataFor, KubeObjectMetadata, KubeJsonApiData, KubeObject, KubeObjectScope, Scale } from "@k8slens/kube-object";
|
||||
import { isJsonApiData, isJsonApiDataList, isPartialJsonApiData, KubeStatus, isKubeStatusData } from "@k8slens/kube-object";
|
||||
import byline from "byline";
|
||||
import type { IKubeWatchEvent } from "./kube-watch-event";
|
||||
@@ -22,6 +22,7 @@ import type { PartialDeep } from "type-fest";
|
||||
import type { Logger } from "../logger";
|
||||
import { matches } from "lodash/fp";
|
||||
import { makeObservable, observable } from "mobx";
|
||||
import type { ScaleCreateOptions } from "@k8slens/kube-object/src/types/scale";
|
||||
|
||||
/**
|
||||
* The options used for creating a `KubeApi`
|
||||
@@ -213,6 +214,10 @@ export interface ResourceDescriptor {
|
||||
namespace?: string;
|
||||
}
|
||||
|
||||
export interface SubResourceDescriptor {
|
||||
subResource: string;
|
||||
}
|
||||
|
||||
export type SpecificResourceDescriptor<Scope extends KubeObjectScope> = {
|
||||
/**
|
||||
* The name of the kubernetes resource
|
||||
@@ -592,6 +597,37 @@ export class KubeApi<
|
||||
return parsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* An internal method for requesting the `/scale` sub-resource if it exists
|
||||
*/
|
||||
protected async getResourceScale(desc: ResourceDescriptor): Promise<Scale> {
|
||||
await this.checkPreferredVersion();
|
||||
const apiUrl = this.formatUrlForNotListing(desc);
|
||||
|
||||
const res = await this.request.get(`${apiUrl}/scale`);
|
||||
|
||||
return res as Scale;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* An internal method for requesting the `/scale` sub-resource if it exists
|
||||
*/
|
||||
protected async scaleResource(desc: ResourceDescriptor, data: ScaleCreateOptions): Promise<Scale> {
|
||||
await this.checkPreferredVersion();
|
||||
const apiUrl = this.formatUrlForNotListing(desc);
|
||||
|
||||
const res = await this.request.patch(`${apiUrl}/scale`, {
|
||||
data: { ...data },
|
||||
}, {
|
||||
headers: {
|
||||
"content-type": patchTypeHeaders.merge,
|
||||
},
|
||||
});
|
||||
|
||||
return res as Scale;
|
||||
}
|
||||
|
||||
async patch(desc: ResourceDescriptor, data: PartialDeep<Object>): Promise<Object | null>;
|
||||
async patch(desc: ResourceDescriptor, data: PartialDeep<Object>, strategy: "strategic" | "merge"): Promise<Object | null>;
|
||||
async patch(desc: ResourceDescriptor, data: Patch, strategy: "json"): Promise<Object | null>;
|
||||
|
||||
Reference in new issue
Block a user