mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
fixed all src/** tests, moved from spec/src to source code locations
This commit is contained in:
parent
a772ef6b94
commit
43b3453e24
@ -3,7 +3,8 @@ module.exports = {
|
|||||||
match: jest.fn(),
|
match: jest.fn(),
|
||||||
app: {
|
app: {
|
||||||
getVersion: jest.fn().mockReturnValue("3.0.0"),
|
getVersion: jest.fn().mockReturnValue("3.0.0"),
|
||||||
getPath: jest.fn().mockReturnValue("/foo/bar")
|
getPath: jest.fn().mockReturnValue("tmp"),
|
||||||
|
getLocale: jest.fn().mockRejectedValue("en"),
|
||||||
},
|
},
|
||||||
remote: {
|
remote: {
|
||||||
app: {
|
app: {
|
||||||
|
|||||||
@ -25,8 +25,8 @@
|
|||||||
"build:linux": "yarn compile && electron-builder --linux --dir -c.productName=LensDev",
|
"build:linux": "yarn compile && electron-builder --linux --dir -c.productName=LensDev",
|
||||||
"build:mac": "yarn compile && electron-builder --mac --dir -c.productName=LensDev",
|
"build:mac": "yarn compile && electron-builder --mac --dir -c.productName=LensDev",
|
||||||
"build:win": "yarn compile && electron-builder --win --dir -c.productName=LensDev",
|
"build:win": "yarn compile && electron-builder --win --dir -c.productName=LensDev",
|
||||||
"test": "jest spec/src $@",
|
"test": "jest --env=jsdom src $@",
|
||||||
"integration": "jest spec/integration $@",
|
"integration": "jest --coverage integration $@",
|
||||||
"dist": "yarn compile && electron-builder -p onTag",
|
"dist": "yarn compile && electron-builder -p onTag",
|
||||||
"dist:win": "yarn compile && electron-builder -p onTag --x64 --ia32",
|
"dist:win": "yarn compile && electron-builder -p onTag --x64 --ia32",
|
||||||
"dist:dir": "yarn dist --dir -c.compression=store -c.mac.identity=null",
|
"dist:dir": "yarn dist --dir -c.compression=store -c.mac.identity=null",
|
||||||
@ -63,7 +63,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
"testRegex": ".*_(spec)\\.[jt]sx?$",
|
"testRegex": ".*_(spec|test)\\.[jt]sx?$",
|
||||||
"collectCoverage": false,
|
"collectCoverage": false,
|
||||||
"verbose": true,
|
"verbose": true,
|
||||||
"testEnvironment": "node",
|
"testEnvironment": "node",
|
||||||
|
|||||||
@ -1,17 +1,7 @@
|
|||||||
import mockFs from "mock-fs"
|
import mockFs from "mock-fs"
|
||||||
import yaml from "js-yaml"
|
import yaml from "js-yaml"
|
||||||
import { ClusterStore } from "../../../src/common/cluster-store";
|
import { ClusterStore } from "./cluster-store";
|
||||||
import { Cluster } from "../../../src/main/cluster";
|
import { Cluster } from "../main/cluster";
|
||||||
|
|
||||||
jest.mock("electron", () => {
|
|
||||||
return {
|
|
||||||
app: {
|
|
||||||
getVersion: () => '99.99.99',
|
|
||||||
getPath: () => 'tmp',
|
|
||||||
getLocale: () => 'en'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Console.log needs to be called before fs-mocks, see https://github.com/tschaub/mock-fs/issues/234
|
// Console.log needs to be called before fs-mocks, see https://github.com/tschaub/mock-fs/issues/234
|
||||||
console.log("");
|
console.log("");
|
||||||
@ -1,15 +1,7 @@
|
|||||||
import mockFs from "mock-fs"
|
import mockFs from "mock-fs"
|
||||||
import { userStore, UserStore } from "../../../src/common/user-store"
|
import { userStore, UserStore } from "./user-store"
|
||||||
|
|
||||||
jest.mock("electron", () => {
|
jest.mock("electron")
|
||||||
return {
|
|
||||||
app: {
|
|
||||||
getVersion: () => '99.99.99',
|
|
||||||
getPath: () => 'tmp',
|
|
||||||
getLocale: () => 'en'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Console.log needs to be called before fs-mocks, see https://github.com/tschaub/mock-fs/issues/234
|
// Console.log needs to be called before fs-mocks, see https://github.com/tschaub/mock-fs/issues/234
|
||||||
console.log("");
|
console.log("");
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import { splitArray } from "../splitArray";
|
import { splitArray } from "./splitArray";
|
||||||
|
|
||||||
describe("split array on element tests", () => {
|
describe("split array on element tests", () => {
|
||||||
test("empty array", () => {
|
test("empty array", () => {
|
||||||
@ -12,6 +12,7 @@ export const isDebugging = process.env.DEBUG === "true";
|
|||||||
export const isProduction = process.env.NODE_ENV === "production"
|
export const isProduction = process.env.NODE_ENV === "production"
|
||||||
export const isDevelopment = isDebugging || !isProduction;
|
export const isDevelopment = isDebugging || !isProduction;
|
||||||
export const buildVersion = process.env.BUILD_VERSION;
|
export const buildVersion = process.env.BUILD_VERSION;
|
||||||
|
export const isTestEnv = !!process.env.JEST_WORKER_ID;
|
||||||
|
|
||||||
// Paths
|
// Paths
|
||||||
export const contextDir = process.cwd();
|
export const contextDir = process.cwd();
|
||||||
|
|||||||
@ -1,14 +1,10 @@
|
|||||||
import packageInfo from "../../../package.json"
|
import packageInfo from "../../package.json"
|
||||||
|
import { bundledKubectl, Kubectl } from "../../src/main/kubectl";
|
||||||
// fixme: ENOENT: no such file or directory, mkdir '/foo/bar'
|
|
||||||
// import { bundledKubectl, Kubectl } from "../../../src/main/kubectl";
|
|
||||||
var bundledKubectl: any;
|
|
||||||
var Kubectl: any;
|
|
||||||
|
|
||||||
jest.mock("electron")
|
jest.mock("electron")
|
||||||
jest.mock("../../../src/common/user-store")
|
jest.mock("../common/user-store")
|
||||||
|
|
||||||
xdescribe("kubectlVersion", () => {
|
describe("kubectlVersion", () => {
|
||||||
it("returns bundled version if exactly same version used", async () => {
|
it("returns bundled version if exactly same version used", async () => {
|
||||||
const kubectl = new Kubectl(bundledKubectl.kubectlVersion)
|
const kubectl = new Kubectl(bundledKubectl.kubectlVersion)
|
||||||
expect(kubectl.kubectlVersion).toBe(bundledKubectl.kubectlVersion)
|
expect(kubectl.kubectlVersion).toBe(bundledKubectl.kubectlVersion)
|
||||||
@ -1,24 +1,25 @@
|
|||||||
import { EventEmitter } from 'events'
|
import { EventEmitter } from 'events'
|
||||||
|
import { getFreePort } from "./port"
|
||||||
|
import net from "net"
|
||||||
|
|
||||||
|
jest.mock("net");
|
||||||
|
|
||||||
class MockServer extends EventEmitter {
|
class MockServer extends EventEmitter {
|
||||||
listen = jest.fn((obj) => {
|
listen = jest.fn((obj) => {
|
||||||
this.emit('listening', {})
|
this.emit('listening', {})
|
||||||
return this
|
return this
|
||||||
})
|
})
|
||||||
address = () => { return { port: 12345 }}
|
address = () => {
|
||||||
|
return { port: 12345 }
|
||||||
|
}
|
||||||
unref = jest.fn()
|
unref = jest.fn()
|
||||||
close = jest.fn((cb) => {
|
close = jest.fn(cb => cb())
|
||||||
cb()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
||||||
const net = require("net")
|
|
||||||
jest.mock("net")
|
|
||||||
|
|
||||||
import * as port from "../../../src/main/port"
|
describe.only("getFreePort", () => {
|
||||||
|
|
||||||
describe("getFreePort", () => {
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
// @ts-ignore
|
||||||
|
// fixme: find a better way to support types for mocked module
|
||||||
net.createServer.mockReturnValue(new MockServer)
|
net.createServer.mockReturnValue(new MockServer)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -27,6 +28,6 @@ describe("getFreePort", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("finds the next free port", async () => {
|
it("finds the next free port", async () => {
|
||||||
return expect(port.getFreePort()).resolves.toEqual(expect.any(Number))
|
return expect(getFreePort()).resolves.toEqual(expect.any(Number))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -1,8 +1,12 @@
|
|||||||
/* Early store format had the kubeconfig directly under context name, this moves
|
/* Early store format had the kubeconfig directly under context name, this moves
|
||||||
it under the kubeConfig key */
|
it under the kubeConfig key */
|
||||||
|
|
||||||
|
import { isTestEnv } from "../../common/vars";
|
||||||
|
|
||||||
export function migration(store: any) {
|
export function migration(store: any) {
|
||||||
console.log("CLUSTER STORE, MIGRATION: 2.0.0-beta.2");
|
if(!isTestEnv) {
|
||||||
|
console.log("CLUSTER STORE, MIGRATION: 2.0.0-beta.2");
|
||||||
|
}
|
||||||
for (const value of store) {
|
for (const value of store) {
|
||||||
const contextName = value[0];
|
const contextName = value[0];
|
||||||
// Looping all the keys gives out the store internal stuff too...
|
// Looping all the keys gives out the store internal stuff too...
|
||||||
|
|||||||
@ -1,9 +1,13 @@
|
|||||||
// Cleans up a store that had the state related data stored
|
// Cleans up a store that had the state related data stored
|
||||||
|
import { isTestEnv } from "../../common/vars";
|
||||||
|
|
||||||
export function migration(store: any) {
|
export function migration(store: any) {
|
||||||
console.log("CLUSTER STORE, MIGRATION: 2.4.1");
|
if (!isTestEnv) {
|
||||||
|
console.log("CLUSTER STORE, MIGRATION: 2.4.1");
|
||||||
|
}
|
||||||
for (const value of store) {
|
for (const value of store) {
|
||||||
const contextName = value[0];
|
const contextName = value[0];
|
||||||
if(contextName === "__internal__") continue;
|
if (contextName === "__internal__") continue;
|
||||||
const cluster = value[1];
|
const cluster = value[1];
|
||||||
|
|
||||||
store.set(contextName, { kubeConfig: cluster.kubeConfig, icon: cluster.icon || null, preferences: cluster.preferences || {} });
|
store.set(contextName, { kubeConfig: cluster.kubeConfig, icon: cluster.icon || null, preferences: cluster.preferences || {} });
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
// Move cluster icon from root to preferences
|
// Move cluster icon from root to preferences
|
||||||
|
import { isTestEnv } from "../../common/vars";
|
||||||
|
|
||||||
export function migration(store: any) {
|
export function migration(store: any) {
|
||||||
console.log("CLUSTER STORE, MIGRATION: 2.6.0-beta.2");
|
if(!isTestEnv) {
|
||||||
|
console.log("CLUSTER STORE, MIGRATION: 2.6.0-beta.2");
|
||||||
|
}
|
||||||
for (const value of store) {
|
for (const value of store) {
|
||||||
const clusterKey = value[0];
|
const clusterKey = value[0];
|
||||||
if(clusterKey === "__internal__") continue
|
if(clusterKey === "__internal__") continue
|
||||||
|
|||||||
@ -1,8 +1,11 @@
|
|||||||
import * as yaml from "js-yaml"
|
import * as yaml from "js-yaml"
|
||||||
|
import { isTestEnv } from "../../common/vars";
|
||||||
|
|
||||||
// Convert access token and expiry from arrays into strings
|
// Convert access token and expiry from arrays into strings
|
||||||
export function migration(store: any) {
|
export function migration(store: any) {
|
||||||
console.log("CLUSTER STORE, MIGRATION: 2.6.0-beta.3");
|
if(!isTestEnv) {
|
||||||
|
console.log("CLUSTER STORE, MIGRATION: 2.6.0-beta.3");
|
||||||
|
}
|
||||||
for (const value of store) {
|
for (const value of store) {
|
||||||
const clusterKey = value[0];
|
const clusterKey = value[0];
|
||||||
if(clusterKey === "__internal__") continue
|
if(clusterKey === "__internal__") continue
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
// Add existing clusters to "default" workspace
|
// Add existing clusters to "default" workspace
|
||||||
|
import { isTestEnv } from "../../common/vars";
|
||||||
|
|
||||||
export function migration(store: any) {
|
export function migration(store: any) {
|
||||||
console.log("CLUSTER STORE, MIGRATION: 2.7.0-beta.0");
|
if(!isTestEnv) {
|
||||||
|
console.log("CLUSTER STORE, MIGRATION: 2.7.0-beta.0");
|
||||||
|
}
|
||||||
for (const value of store) {
|
for (const value of store) {
|
||||||
const clusterKey = value[0];
|
const clusterKey = value[0];
|
||||||
if(clusterKey === "__internal__") continue
|
if(clusterKey === "__internal__") continue
|
||||||
|
|||||||
@ -1,8 +1,11 @@
|
|||||||
// add id for clusters and store them to array
|
// add id for clusters and store them to array
|
||||||
import { v4 as uuid } from "uuid"
|
import { v4 as uuid } from "uuid"
|
||||||
|
import { isTestEnv } from "../../common/vars";
|
||||||
|
|
||||||
export function migration(store: any) {
|
export function migration(store: any) {
|
||||||
console.log("CLUSTER STORE, MIGRATION: 2.7.0-beta.1");
|
if(!isTestEnv) {
|
||||||
|
console.log("CLUSTER STORE, MIGRATION: 2.7.0-beta.1");
|
||||||
|
}
|
||||||
const clusters: any[] = []
|
const clusters: any[] = []
|
||||||
for (const value of store) {
|
for (const value of store) {
|
||||||
const clusterKey = value[0];
|
const clusterKey = value[0];
|
||||||
|
|||||||
103
src/renderer/api/kube-api-parse.ts
Normal file
103
src/renderer/api/kube-api-parse.ts
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
// Parse kube-api path and get api-version, group, etc.
|
||||||
|
import { splitArray } from "../../common/utils";
|
||||||
|
|
||||||
|
export interface IKubeApiLinkRef {
|
||||||
|
apiPrefix?: string;
|
||||||
|
apiVersion: string;
|
||||||
|
resource: string;
|
||||||
|
name: string;
|
||||||
|
namespace?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IKubeApiLinkBase extends IKubeApiLinkRef {
|
||||||
|
apiBase: string;
|
||||||
|
apiGroup: string;
|
||||||
|
apiVersionWithGroup: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseApi(path: string): IKubeApiLinkBase {
|
||||||
|
path = new URL(path, location.origin).pathname;
|
||||||
|
const [, prefix, ...parts] = path.split("/");
|
||||||
|
const apiPrefix = `/${prefix}`;
|
||||||
|
|
||||||
|
const [left, right, namespaced] = splitArray(parts, "namespaces");
|
||||||
|
let apiGroup, apiVersion, namespace, resource, name;
|
||||||
|
|
||||||
|
if (namespaced) {
|
||||||
|
switch (right.length) {
|
||||||
|
case 1:
|
||||||
|
name = right[0];
|
||||||
|
// fallthrough
|
||||||
|
case 0:
|
||||||
|
resource = "namespaces"; // special case this due to `split` removing namespaces
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
[namespace, resource, name] = right;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
apiVersion = left.pop();
|
||||||
|
apiGroup = left.join("/");
|
||||||
|
} else {
|
||||||
|
switch (left.length) {
|
||||||
|
case 2:
|
||||||
|
resource = left.pop();
|
||||||
|
// fallthrough
|
||||||
|
case 1:
|
||||||
|
apiVersion = left.pop();
|
||||||
|
apiGroup = "";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/**
|
||||||
|
* Given that
|
||||||
|
* - `apiVersion` is `GROUP/VERSION` and
|
||||||
|
* - `VERSION` is `DNS_LABEL` which is /^[a-z0-9]((-[a-z0-9])|[a-z0-9])*$/i
|
||||||
|
* where length <= 63
|
||||||
|
* - `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
|
||||||
|
* seperated by '/'
|
||||||
|
*
|
||||||
|
* Solution is to create a huristic. Namely:
|
||||||
|
* 1. if '.' in left[0] then apiGroup <- left[0]
|
||||||
|
* 2. if left[1] matches /^v[0-9]/ then apiGroup, apiVersion <- left[0], left[1]
|
||||||
|
* 3. otherwise assume apiVersion <- left[0]
|
||||||
|
* 4. always resource, name <- left[(0 or 1)+1..]
|
||||||
|
*/
|
||||||
|
if (left[0].includes('.') || left[1].match(/^v[0-9]/)) {
|
||||||
|
[apiGroup, apiVersion] = left;
|
||||||
|
resource = left.slice(2).join("/")
|
||||||
|
} else {
|
||||||
|
apiGroup = "";
|
||||||
|
apiVersion = left[0];
|
||||||
|
[resource, name] = left.slice(1)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const apiVersionWithGroup = [apiGroup, apiVersion].filter(v => v).join("/");
|
||||||
|
const apiBase = [apiPrefix, apiGroup, apiVersion, resource].filter(v => v).join("/");
|
||||||
|
|
||||||
|
if (!apiBase) {
|
||||||
|
throw new Error(`invalid apiPath: ${path}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
apiBase,
|
||||||
|
apiPrefix, apiGroup,
|
||||||
|
apiVersion, apiVersionWithGroup,
|
||||||
|
namespace, resource, name,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createApiLink(ref: IKubeApiLinkRef): string {
|
||||||
|
const { apiPrefix = "/apis", resource, apiVersion, name } = ref;
|
||||||
|
let { namespace } = ref;
|
||||||
|
if (namespace) {
|
||||||
|
namespace = `namespaces/${namespace}`
|
||||||
|
}
|
||||||
|
return [apiPrefix, apiVersion, namespace, resource, name]
|
||||||
|
.filter(v => v)
|
||||||
|
.join("/")
|
||||||
|
}
|
||||||
@ -1,11 +1,11 @@
|
|||||||
import { IKubeApiLinkBase, KubeApi } from "../kube-api";
|
import { IKubeApiLinkBase, parseApi } from "./kube-api-parse";
|
||||||
|
|
||||||
interface ParseAPITest {
|
interface KubeApi_Parse_Test {
|
||||||
url: string;
|
url: string;
|
||||||
expected: Required<IKubeApiLinkBase>;
|
expected: Required<IKubeApiLinkBase>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tests: ParseAPITest[] = [
|
const tests: KubeApi_Parse_Test[] = [
|
||||||
{
|
{
|
||||||
url: "/api/v1/namespaces/kube-system/pods/coredns-6955765f44-v8p27",
|
url: "/api/v1/namespaces/kube-system/pods/coredns-6955765f44-v8p27",
|
||||||
expected: {
|
expected: {
|
||||||
@ -112,12 +112,11 @@ const tests: ParseAPITest[] = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
jest.mock('../kube-watch-api.ts', () => 'KubeWatchApi');
|
describe.only("parseApi unit tests", () => {
|
||||||
describe("parseApi unit tests", () => {
|
|
||||||
for (const i in tests) {
|
for (const i in tests) {
|
||||||
const { url: tUrl, expected:tExpect} = tests[i];
|
const { url: tUrl, expected:tExpect} = tests[i];
|
||||||
test(`test #${parseInt(i)+1}`, () => {
|
test(`test #${parseInt(i)+1}`, () => {
|
||||||
expect(KubeApi.parseApi(tUrl)).toStrictEqual(tExpect);
|
expect(parseApi(tUrl)).toStrictEqual(tExpect);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -7,7 +7,7 @@ import { IKubeObjectRef, KubeJsonApi, KubeJsonApiData, KubeJsonApiDataList } fro
|
|||||||
import { apiKube } from "./index";
|
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 { splitArray } from "../../common/utils";
|
import { createApiLink, parseApi } from "./kube-api-parse";
|
||||||
|
|
||||||
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"
|
||||||
@ -25,107 +25,9 @@ export interface IKubeApiQueryParams {
|
|||||||
continue?: string; // might be used with ?limit from second request
|
continue?: string; // might be used with ?limit from second request
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IKubeApiLinkRef {
|
|
||||||
apiPrefix?: string;
|
|
||||||
apiVersion: string;
|
|
||||||
resource: string;
|
|
||||||
name: string;
|
|
||||||
namespace?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IKubeApiLinkBase extends IKubeApiLinkRef {
|
|
||||||
apiBase: string;
|
|
||||||
apiGroup: string;
|
|
||||||
apiVersionWithGroup: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class KubeApi<T extends KubeObject = any> {
|
export class KubeApi<T extends KubeObject = any> {
|
||||||
static parseApi(apiPath = ""): IKubeApiLinkBase {
|
static parseApi = parseApi;
|
||||||
apiPath = new URL(apiPath, location.origin).pathname;
|
static createLink = createApiLink;
|
||||||
const [, prefix, ...parts] = apiPath.split("/");
|
|
||||||
const apiPrefix = `/${prefix}`;
|
|
||||||
|
|
||||||
const [left, right, namespaced] = splitArray(parts, "namespaces");
|
|
||||||
let apiGroup, apiVersion, namespace, resource, name;
|
|
||||||
|
|
||||||
if (namespaced) {
|
|
||||||
switch (right.length) {
|
|
||||||
case 1:
|
|
||||||
name = right[0];
|
|
||||||
// fallthrough
|
|
||||||
case 0:
|
|
||||||
resource = "namespaces"; // special case this due to `split` removing namespaces
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
[namespace, resource, name] = right;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
apiVersion = left.pop();
|
|
||||||
apiGroup = left.join("/");
|
|
||||||
} else {
|
|
||||||
switch (left.length) {
|
|
||||||
case 2:
|
|
||||||
resource = left.pop();
|
|
||||||
// fallthrough
|
|
||||||
case 1:
|
|
||||||
apiVersion = left.pop();
|
|
||||||
apiGroup = "";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/**
|
|
||||||
* Given that
|
|
||||||
* - `apiVersion` is `GROUP/VERSION` and
|
|
||||||
* - `VERSION` is `DNS_LABEL` which is /^[a-z0-9]((-[a-z0-9])|[a-z0-9])*$/i
|
|
||||||
* where length <= 63
|
|
||||||
* - `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
|
|
||||||
* seperated by '/'
|
|
||||||
*
|
|
||||||
* Solution is to create a huristic. Namely:
|
|
||||||
* 1. if '.' in left[0] then apiGroup <- left[0]
|
|
||||||
* 2. if left[1] matches /^v[0-9]/ then apiGroup, apiVersion <- left[0], left[1]
|
|
||||||
* 3. otherwise assume apiVersion <- left[0]
|
|
||||||
* 4. always resource, name <- left[(0 or 1)+1..]
|
|
||||||
*/
|
|
||||||
if (left[0].includes('.') || left[1].match(/^v[0-9]/)) {
|
|
||||||
[apiGroup, apiVersion] = left;
|
|
||||||
resource = left.slice(2).join("/")
|
|
||||||
} else {
|
|
||||||
apiGroup = "";
|
|
||||||
apiVersion = left[0];
|
|
||||||
[resource, name] = left.slice(1)
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const apiVersionWithGroup = [apiGroup, apiVersion].filter(v => v).join("/");
|
|
||||||
const apiBase = [apiPrefix, apiGroup, apiVersion, resource].filter(v => v).join("/");
|
|
||||||
|
|
||||||
if (!apiBase) {
|
|
||||||
throw new Error(`invalid apiPath: ${apiPath}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
apiBase,
|
|
||||||
apiPrefix, apiGroup,
|
|
||||||
apiVersion, apiVersionWithGroup,
|
|
||||||
namespace, resource, name,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static createLink(ref: IKubeApiLinkRef): string {
|
|
||||||
const { apiPrefix = "/apis", resource, apiVersion, name } = ref;
|
|
||||||
let { namespace } = ref;
|
|
||||||
if (namespace) {
|
|
||||||
namespace = `namespaces/${namespace}`
|
|
||||||
}
|
|
||||||
return [apiPrefix, apiVersion, namespace, resource, name]
|
|
||||||
.filter(v => v)
|
|
||||||
.join("/")
|
|
||||||
}
|
|
||||||
|
|
||||||
static watchAll(...apis: KubeApi[]) {
|
static watchAll(...apis: KubeApi[]) {
|
||||||
const disposers = apis.map(api => api.watch());
|
const disposers = apis.map(api => api.watch());
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user