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

special case */namespace/* in parseApi, add test (#509)

This commit is contained in:
Sebastian Malton 2020-06-23 08:48:20 -04:00 committed by GitHub
parent f620b3198f
commit 6770f05dc8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 25 deletions

View File

@ -2,7 +2,7 @@ import { KubeApi, IKubeApiLinkBase } from "../kube-api";
interface ParseAPITest { interface ParseAPITest {
url: string; url: string;
expected: IKubeApiLinkBase; expected: Required<IKubeApiLinkBase>;
} }
const tests: ParseAPITest[] = [ const tests: ParseAPITest[] = [
@ -97,6 +97,19 @@ const tests: ParseAPITest[] = [
namespace: undefined, namespace: undefined,
}, },
}, },
{
url: "/api/v1/namespaces/kube-public",
expected: {
apiBase: "/api/v1/namespaces",
apiPrefix: "/api",
apiGroup: "",
apiVersion: "v1",
apiVersionWithGroup: "v1",
resource: "namespaces",
name: "kube-public",
namespace: undefined,
},
},
]; ];
jest.mock('../kube-watch-api.ts', () => 'KubeWatchApi'); jest.mock('../kube-watch-api.ts', () => 'KubeWatchApi');

View File

@ -8,7 +8,6 @@ import { apiKube } from "./index";
import { kubeWatchApi } from "./kube-watch-api"; import { kubeWatchApi } from "./kube-watch-api";
import { apiManager } from "./api-manager"; import { apiManager } from "./api-manager";
import { split } from "../utils/arrays"; import { split } from "../utils/arrays";
import isEqual from "lodash/isEqual";
export interface IKubeApiOptions<T extends KubeObject> { export interface IKubeApiOptions<T extends KubeObject> {
kind: string; // resource type within api-group, e.g. "Namespace" kind: string; // resource type within api-group, e.g. "Namespace"
@ -43,7 +42,6 @@ export interface IKubeApiLinkBase extends IKubeApiLinkRef {
export class KubeApi<T extends KubeObject = any> { export class KubeApi<T extends KubeObject = any> {
static parseApi(apiPath = ""): IKubeApiLinkBase { static parseApi(apiPath = ""): IKubeApiLinkBase {
apiPath = new URL(apiPath, location.origin).pathname; apiPath = new URL(apiPath, location.origin).pathname;
const [, prefix, ...parts] = apiPath.split("/"); const [, prefix, ...parts] = apiPath.split("/");
const apiPrefix = `/${prefix}`; const apiPrefix = `/${prefix}`;
@ -52,12 +50,12 @@ export class KubeApi<T extends KubeObject = any> {
if (namespaced) { if (namespaced) {
switch (right.length) { switch (right.length) {
case 1:
name = right[0];
// fallthrough
case 0: case 0:
resource = "namespaces"; // special case this due to `split` removing namespaces resource = "namespaces"; // special case this due to `split` removing namespaces
break; break;
case 1:
resource = right[0];
break;
default: default:
[namespace, resource, name] = right; [namespace, resource, name] = right;
break; break;
@ -69,27 +67,28 @@ export class KubeApi<T extends KubeObject = any> {
switch (left.length) { switch (left.length) {
case 2: case 2:
resource = left.pop(); resource = left.pop();
// fallthrough
case 1: case 1:
apiVersion = left.pop(); apiVersion = left.pop();
apiGroup = ""; apiGroup = "";
break; break;
default: default:
/** /**
* Given that * Given that
* - `apiVersion` is `GROUP/VERSION` and * - `apiVersion` is `GROUP/VERSION` and
* - `VERSION` is `DNS_LABEL` which is /^[a-z0-9]((-[a-z0-9])|[a-z0-9])*$/i * - `VERSION` is `DNS_LABEL` which is /^[a-z0-9]((-[a-z0-9])|[a-z0-9])*$/i
* where length <= 63 * where length <= 63
* - `GROUP` is /^D(\.D)*$/ where D is `DNS_LABEL` and length <= 253 * - `GROUP` is /^D(\.D)*$/ where D is `DNS_LABEL` and length <= 253
* *
* There is no well defined selection from an array of items that were * There is no well defined selection from an array of items that were
* seperated by '/' * seperated by '/'
* *
* Solution is to create a huristic. Namely: * Solution is to create a huristic. Namely:
* 1. if '.' in left[0] then apiGroup <- left[0] * 1. if '.' in left[0] then apiGroup <- left[0]
* 2. if left[1] matches /^v[0-9]/ then apiGroup, apiVersion <- left[0], left[1] * 2. if left[1] matches /^v[0-9]/ then apiGroup, apiVersion <- left[0], left[1]
* 3. otherwise assume apiVersion <- left[0] * 3. otherwise assume apiVersion <- left[0]
* 4. always resource, name <- left[(0 or 1)+1..] * 4. always resource, name <- left[(0 or 1)+1..]
*/ */
if (left[0].includes('.') || left[1].match(/^v[0-9]/)) { if (left[0].includes('.') || left[1].match(/^v[0-9]/)) {
[apiGroup, apiVersion] = left; [apiGroup, apiVersion] = left;
resource = left.slice(2).join("/") resource = left.slice(2).join("/")
@ -199,7 +198,7 @@ export class KubeApi<T extends KubeObject = any> {
if (KubeObject.isJsonApiData(data)) { if (KubeObject.isJsonApiData(data)) {
return new KubeObjectConstructor(data); return new KubeObjectConstructor(data);
} }
// process items list response // process items list response
if (KubeObject.isJsonApiDataList(data)) { if (KubeObject.isJsonApiDataList(data)) {
const { apiVersion, items, metadata } = data; const { apiVersion, items, metadata } = data;
@ -211,12 +210,12 @@ export class KubeApi<T extends KubeObject = any> {
...item, ...item,
})) }))
} }
// custom apis might return array for list response, e.g. users, groups, etc. // custom apis might return array for list response, e.g. users, groups, etc.
if (Array.isArray(data)) { if (Array.isArray(data)) {
return data.map(data => new KubeObjectConstructor(data)); return data.map(data => new KubeObjectConstructor(data));
} }
return data; return data;
} }
@ -234,7 +233,7 @@ export class KubeApi<T extends KubeObject = any> {
async create({ name = "", namespace = "default" } = {}, data?: Partial<T>): Promise<T> { async create({ name = "", namespace = "default" } = {}, data?: Partial<T>): Promise<T> {
const apiUrl = this.getUrl({ namespace }); const apiUrl = this.getUrl({ namespace });
return this.request return this.request
.post(apiUrl, { .post(apiUrl, {
data: merge({ data: merge({