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

Fix KubeApi.create not populating kind and apiVersion (#4478)

This commit is contained in:
Sebastian Malton 2021-12-01 15:57:08 -05:00
parent c387797b88
commit baab93d69d
2 changed files with 154 additions and 12 deletions

View File

@ -33,7 +33,7 @@ class TestKubeObject extends KubeObject {
static apiBase = "/api/v1/pods";
}
class TestKubeApi extends KubeApi<TestKubeObject> {}
class TestKubeApi extends KubeApi<TestKubeObject> { }
describe("forRemoteCluster", () => {
it("builds api client for KubeObject", async () => {
@ -474,4 +474,142 @@ describe("KubeApi", () => {
});
});
});
describe("create", () => {
let api: TestKubeApi;
beforeEach(() => {
api = new TestKubeApi({
request,
objectConstructor: TestKubeObject,
});
});
it("should add kind and apiVersion", async () => {
expect.hasAssertions();
(fetch as any).mockResponse(async (request: Request) => {
expect(request.method).toEqual("POST");
expect(JSON.parse(request.body.toString())).toEqual({
kind: "Pod",
apiVersion: "v1",
metadata: {
name: "foobar",
namespace: "default",
},
spec: {
containers: [
{
name: "web",
image: "nginx",
ports: [
{
name: "web",
containerPort: 80,
protocol: "TCP",
},
],
},
],
},
});
return {};
});
await api.create({
name: "foobar",
namespace: "default",
}, {
spec: {
containers: [
{
name: "web",
image: "nginx",
ports: [
{
name: "web",
containerPort: 80,
protocol: "TCP",
},
],
},
],
},
});
});
it("doesn't override metadata.labels", async () => {
expect.hasAssertions();
(fetch as any).mockResponse(async (request: Request) => {
expect(request.method).toEqual("POST");
expect(JSON.parse(request.body.toString())).toEqual({
kind: "Pod",
apiVersion: "v1",
metadata: {
name: "foobar",
namespace: "default",
labels: {
foo: "bar",
},
},
});
return {};
});
await api.create({
name: "foobar",
namespace: "default",
}, {
metadata: {
labels: {
foo: "bar",
},
},
});
});
});
describe("update", () => {
let api: TestKubeApi;
beforeEach(() => {
api = new TestKubeApi({
request,
objectConstructor: TestKubeObject,
});
});
it("doesn't override metadata.labels", async () => {
expect.hasAssertions();
(fetch as any).mockResponse(async (request: Request) => {
expect(request.method).toEqual("PUT");
expect(JSON.parse(request.body.toString())).toEqual({
metadata: {
name: "foobar",
namespace: "default",
labels: {
foo: "bar",
},
},
});
return {};
});
await api.update({
name: "foobar",
namespace: "default",
}, {
metadata: {
labels: {
foo: "bar",
},
},
});
});
});
});

View File

@ -21,7 +21,7 @@
// Base class for building all kubernetes apis
import { isFunction } from "lodash";
import { isFunction, merge } from "lodash";
import { stringify } from "querystring";
import { apiKubePrefix, isDevelopment } from "../../common/vars";
import logger from "../../main/logger";
@ -102,7 +102,11 @@ export type PropagationPolicy = undefined | "Orphan" | "Foreground" | "Backgroun
/**
* @deprecated
*/
export interface IKubeApiCluster extends ILocalKubeApiConfig {}
export interface IKubeApiCluster extends ILocalKubeApiConfig { }
export type PartialKubeObject<T extends KubeObject> = Partial<Omit<T, "metadata">> & {
metadata?: Partial<T["metadata"]>,
};
export interface IRemoteKubeApiConfig {
cluster: {
@ -478,18 +482,19 @@ export class KubeApi<T extends KubeObject> {
return parsed;
}
async create({ name, namespace }: Partial<ResourceDescriptor>, data?: Partial<T>): Promise<T | null> {
async create({ name, namespace }: Partial<ResourceDescriptor>, data?: PartialKubeObject<T>): Promise<T | null> {
await this.checkPreferredVersion();
const apiUrl = this.getUrl({ namespace });
const res = await this.request.post(apiUrl, {
data: {
...data,
data: merge(data, {
kind: this.kind,
apiVersion: this.apiVersionWithGroup,
metadata: {
name,
namespace,
},
},
}),
});
const parsed = this.parseResponse(res);
@ -500,18 +505,17 @@ export class KubeApi<T extends KubeObject> {
return parsed;
}
async update({ name, namespace }: ResourceDescriptor, data: Partial<T>): Promise<T | null> {
async update({ name, namespace }: ResourceDescriptor, data: PartialKubeObject<T>): Promise<T | null> {
await this.checkPreferredVersion();
const apiUrl = this.getUrl({ namespace, name });
const res = await this.request.put(apiUrl, {
data: {
...data,
data: merge(data, {
metadata: {
name,
namespace,
},
},
}),
});
const parsed = this.parseResponse(res);
@ -580,7 +584,7 @@ export class KubeApi<T extends KubeObject> {
clearTimeout(timedRetry);
});
const requestParams = timeout ? { query: { timeoutSeconds: timeout }}: {};
const requestParams = timeout ? { query: { timeoutSeconds: timeout }} : {};
const watchUrl = this.getWatchUrl(namespace);
const responsePromise = this.request.getResponse(watchUrl, requestParams, {
signal: abortController.signal,