mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Move cluster related types and function into seperate files (#3530)
This commit is contained in:
1 parent
2893ad956d
commit
a6e91fc34a
49 files changed
+435
-258
No files matched your search
@@ -25,9 +25,11 @@ import yaml from "js-yaml";
|
||||
import path from "path";
|
||||
import fse from "fs-extra";
|
||||
import { Cluster } from "../../main/cluster";
|
||||
import { ClusterId, ClusterStore, getClusterIdFromHost } from "../cluster-store";
|
||||
import { ClusterStore } from "../cluster-store";
|
||||
import { Console } from "console";
|
||||
import { stdout, stderr } from "process";
|
||||
import type { ClusterId } from "../cluster-types";
|
||||
import { getCustomKubeConfigPath } from "../utils";
|
||||
|
||||
console = new Console(stdout, stderr);
|
||||
|
||||
@@ -57,7 +59,7 @@ users:
|
||||
`;
|
||||
|
||||
function embed(clusterId: ClusterId, contents: any): string {
|
||||
const absPath = ClusterStore.getCustomKubeConfigPath(clusterId);
|
||||
const absPath = getCustomKubeConfigPath(clusterId);
|
||||
|
||||
fse.ensureDirSync(path.dirname(absPath));
|
||||
fse.writeFileSync(absPath, contents, { encoding: "utf-8", mode: 0o600 });
|
||||
@@ -550,27 +552,3 @@ describe("pre 3.6.0-beta.1 config with an existing cluster", () => {
|
||||
expect(icon.startsWith("data:;base64,")).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getClusterIdFromHost", () => {
|
||||
const clusterFakeId = "fe540901-0bd6-4f6c-b472-bce1559d7c4a";
|
||||
|
||||
it("should return undefined for non cluster frame hosts", () => {
|
||||
expect(getClusterIdFromHost("localhost:45345")).toBeUndefined();
|
||||
});
|
||||
|
||||
it("should return ClusterId for cluster frame hosts", () => {
|
||||
expect(getClusterIdFromHost(`${clusterFakeId}.localhost:59110`)).toBe(clusterFakeId);
|
||||
});
|
||||
|
||||
it("should return ClusterId for cluster frame hosts with additional subdomains", () => {
|
||||
expect(getClusterIdFromHost(`abc.${clusterFakeId}.localhost:59110`)).toBe(clusterFakeId);
|
||||
expect(getClusterIdFromHost(`abc.def.${clusterFakeId}.localhost:59110`)).toBe(clusterFakeId);
|
||||
expect(getClusterIdFromHost(`abc.def.ghi.${clusterFakeId}.localhost:59110`)).toBe(clusterFakeId);
|
||||
expect(getClusterIdFromHost(`abc.def.ghi.jkl.${clusterFakeId}.localhost:59110`)).toBe(clusterFakeId);
|
||||
expect(getClusterIdFromHost(`abc.def.ghi.jkl.mno.${clusterFakeId}.localhost:59110`)).toBe(clusterFakeId);
|
||||
expect(getClusterIdFromHost(`abc.def.ghi.jkl.mno.pqr.${clusterFakeId}.localhost:59110`)).toBe(clusterFakeId);
|
||||
expect(getClusterIdFromHost(`abc.def.ghi.jkl.mno.pqr.stu.${clusterFakeId}.localhost:59110`)).toBe(clusterFakeId);
|
||||
expect(getClusterIdFromHost(`abc.def.ghi.jkl.mno.pqr.stu.vwx.${clusterFakeId}.localhost:59110`)).toBe(clusterFakeId);
|
||||
expect(getClusterIdFromHost(`abc.def.ghi.jkl.mno.pqr.stu.vwx.yz.${clusterFakeId}.localhost:59110`)).toBe(clusterFakeId);
|
||||
});
|
||||
});
|
||||
+3
-115
@@ -19,119 +19,26 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import path from "path";
|
||||
import { app, ipcMain, ipcRenderer, remote, webFrame } from "electron";
|
||||
import { ipcMain, ipcRenderer, webFrame } from "electron";
|
||||
import { action, comparer, computed, makeObservable, observable, reaction } from "mobx";
|
||||
import { BaseStore } from "./base-store";
|
||||
import { Cluster, ClusterState } from "../main/cluster";
|
||||
import { Cluster } from "../main/cluster";
|
||||
import migrations from "../migrations/cluster-store";
|
||||
import * as uuid from "uuid";
|
||||
import logger from "../main/logger";
|
||||
import { appEventBus } from "./event-bus";
|
||||
import { ipcMainHandle, ipcMainOn, ipcRendererOn, requestMain } from "./ipc";
|
||||
import { disposer, toJS } from "./utils";
|
||||
|
||||
export interface ClusterIconUpload {
|
||||
clusterId: string;
|
||||
name: string;
|
||||
path: string;
|
||||
}
|
||||
|
||||
export interface ClusterMetadata {
|
||||
[key: string]: string | number | boolean | object;
|
||||
}
|
||||
|
||||
export type ClusterPrometheusMetadata = {
|
||||
success?: boolean;
|
||||
provider?: string;
|
||||
autoDetected?: boolean;
|
||||
};
|
||||
import type { ClusterModel, ClusterId, ClusterState } from "./cluster-types";
|
||||
|
||||
export interface ClusterStoreModel {
|
||||
clusters?: ClusterModel[];
|
||||
}
|
||||
|
||||
export type ClusterId = string;
|
||||
|
||||
export interface UpdateClusterModel extends Omit<ClusterModel, "id"> {
|
||||
id?: ClusterId;
|
||||
}
|
||||
|
||||
export interface ClusterModel {
|
||||
/** Unique id for a cluster */
|
||||
id: ClusterId;
|
||||
|
||||
/** Path to cluster kubeconfig */
|
||||
kubeConfigPath: string;
|
||||
|
||||
/**
|
||||
* Workspace id
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
workspace?: string;
|
||||
|
||||
/**
|
||||
* @deprecated this is used only for hotbar migrations from 4.2.X
|
||||
*/
|
||||
workspaces?: string[];
|
||||
|
||||
/** User context in kubeconfig */
|
||||
contextName: string;
|
||||
|
||||
/** Preferences */
|
||||
preferences?: ClusterPreferences;
|
||||
|
||||
/** Metadata */
|
||||
metadata?: ClusterMetadata;
|
||||
|
||||
/**
|
||||
* Labels for the catalog entity
|
||||
*/
|
||||
labels?: Record<string, string>;
|
||||
|
||||
/** List of accessible namespaces */
|
||||
accessibleNamespaces?: string[];
|
||||
}
|
||||
|
||||
export interface ClusterPreferences extends ClusterPrometheusPreferences {
|
||||
terminalCWD?: string;
|
||||
clusterName?: string;
|
||||
iconOrder?: number;
|
||||
icon?: string;
|
||||
httpsProxy?: string;
|
||||
hiddenMetrics?: string[];
|
||||
nodeShellImage?: string;
|
||||
imagePullSecret?: string;
|
||||
}
|
||||
|
||||
export interface ClusterPrometheusPreferences {
|
||||
prometheus?: {
|
||||
namespace: string;
|
||||
service: string;
|
||||
port: number;
|
||||
prefix: string;
|
||||
};
|
||||
prometheusProvider?: {
|
||||
type: string;
|
||||
};
|
||||
}
|
||||
|
||||
const initialStates = "cluster:states";
|
||||
|
||||
export const initialNodeShellImage = "docker.io/alpine:3.13";
|
||||
|
||||
export class ClusterStore extends BaseStore<ClusterStoreModel> {
|
||||
private static StateChannel = "cluster:state";
|
||||
|
||||
static get storedKubeConfigFolder(): string {
|
||||
return path.resolve((app ?? remote.app).getPath("userData"), "kubeconfigs");
|
||||
}
|
||||
|
||||
static getCustomKubeConfigPath(clusterId: ClusterId = uuid.v4()): string {
|
||||
return path.resolve(ClusterStore.storedKubeConfigFolder, clusterId);
|
||||
}
|
||||
|
||||
clusters = observable.map<ClusterId, Cluster>();
|
||||
removedClusters = observable.map<ClusterId, Cluster>();
|
||||
|
||||
@@ -272,22 +179,3 @@ export class ClusterStore extends BaseStore<ClusterStoreModel> {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function getClusterIdFromHost(host: string): ClusterId | undefined {
|
||||
// e.g host == "%clusterId.localhost:45345"
|
||||
const subDomains = host.split(":")[0].split(".");
|
||||
|
||||
return subDomains.slice(-2, -1)[0]; // ClusterId or undefined
|
||||
}
|
||||
|
||||
export function getClusterFrameUrl(clusterId: ClusterId) {
|
||||
return `//${clusterId}.${location.host}`;
|
||||
}
|
||||
|
||||
export function getHostedClusterId() {
|
||||
return getClusterIdFromHost(location.host);
|
||||
}
|
||||
|
||||
export function getHostedCluster(): Cluster {
|
||||
return ClusterStore.getInstance().getById(getHostedClusterId());
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* JSON serializable metadata type
|
||||
*/
|
||||
export type ClusterMetadata = Record<string, string | number | boolean | object>;
|
||||
|
||||
/**
|
||||
* Metadata for cluster's prometheus settings
|
||||
*/
|
||||
export interface ClusterPrometheusMetadata {
|
||||
success?: boolean;
|
||||
provider?: string;
|
||||
autoDetected?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* A ClusterId is an opaque string
|
||||
*/
|
||||
export type ClusterId = string;
|
||||
|
||||
/**
|
||||
* The fields that are used for updating a cluster instance
|
||||
*/
|
||||
export type UpdateClusterModel = Omit<ClusterModel, "id">;
|
||||
|
||||
/**
|
||||
* The model for passing cluster data around, including to disk
|
||||
*/
|
||||
export interface ClusterModel {
|
||||
/** Unique id for a cluster */
|
||||
id: ClusterId;
|
||||
|
||||
/** Path to cluster kubeconfig */
|
||||
kubeConfigPath: string;
|
||||
|
||||
/**
|
||||
* Workspace id
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
workspace?: string;
|
||||
|
||||
/**
|
||||
* @deprecated this is used only for hotbar migrations from 4.2.X
|
||||
*/
|
||||
workspaces?: string[];
|
||||
|
||||
/** User context in kubeconfig */
|
||||
contextName: string;
|
||||
|
||||
/** Preferences */
|
||||
preferences?: ClusterPreferences;
|
||||
|
||||
/** Metadata */
|
||||
metadata?: ClusterMetadata;
|
||||
|
||||
/** List of accessible namespaces */
|
||||
accessibleNamespaces?: string[];
|
||||
|
||||
/**
|
||||
* Labels for the catalog entity
|
||||
*/
|
||||
labels?: Record<string, string>;
|
||||
}
|
||||
|
||||
/**
|
||||
* The complete set of cluster settings or preferences
|
||||
*/
|
||||
export interface ClusterPreferences extends ClusterPrometheusPreferences {
|
||||
terminalCWD?: string;
|
||||
clusterName?: string;
|
||||
iconOrder?: number;
|
||||
icon?: string;
|
||||
httpsProxy?: string;
|
||||
hiddenMetrics?: string[];
|
||||
nodeShellImage?: string;
|
||||
imagePullSecret?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A cluster's prometheus settings (a subset of cluster settings)
|
||||
*/
|
||||
export interface ClusterPrometheusPreferences {
|
||||
prometheus?: {
|
||||
namespace: string;
|
||||
service: string;
|
||||
port: number;
|
||||
prefix: string;
|
||||
};
|
||||
prometheusProvider?: {
|
||||
type: string;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The options for the status of connection attempts to a cluster
|
||||
*/
|
||||
export enum ClusterStatus {
|
||||
AccessGranted = 2,
|
||||
AccessDenied = 1,
|
||||
Offline = 0
|
||||
}
|
||||
|
||||
/**
|
||||
* The OpenLens known static metadata keys
|
||||
*/
|
||||
export enum ClusterMetadataKey {
|
||||
VERSION = "version",
|
||||
CLUSTER_ID = "id",
|
||||
DISTRIBUTION = "distribution",
|
||||
NODES_COUNT = "nodes",
|
||||
LAST_SEEN = "lastSeen",
|
||||
PROMETHEUS = "prometheus"
|
||||
}
|
||||
|
||||
/**
|
||||
* A shorthand enum for resource types that have metrics attached to them via OpenLens metrics stack
|
||||
*/
|
||||
export enum ClusterMetricsResourceType {
|
||||
Cluster = "Cluster",
|
||||
Node = "Node",
|
||||
Pod = "Pod",
|
||||
Deployment = "Deployment",
|
||||
StatefulSet = "StatefulSet",
|
||||
Container = "Container",
|
||||
Ingress = "Ingress",
|
||||
VolumeClaim = "VolumeClaim",
|
||||
ReplicaSet = "ReplicaSet",
|
||||
DaemonSet = "DaemonSet",
|
||||
Job = "Job",
|
||||
Namespace = "Namespace",
|
||||
}
|
||||
|
||||
/**
|
||||
* The default node shell image
|
||||
*/
|
||||
export const initialNodeShellImage = "docker.io/alpine:3.13";
|
||||
|
||||
/**
|
||||
* The arguments for requesting to refresh a cluster's metadata
|
||||
*/
|
||||
export interface ClusterRefreshOptions {
|
||||
refreshMetadata?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* The data representing a cluster's state, for passing between main and renderer
|
||||
*/
|
||||
export interface ClusterState {
|
||||
apiUrl: string;
|
||||
online: boolean;
|
||||
disconnected: boolean;
|
||||
accessible: boolean;
|
||||
ready: boolean;
|
||||
failureReason: string;
|
||||
isAdmin: boolean;
|
||||
allowedNamespaces: string[]
|
||||
allowedResources: string[]
|
||||
isGlobalWatchEnabled: boolean;
|
||||
}
|
||||
+3
-2
@@ -19,7 +19,8 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { getHostedCluster } from "./cluster-store";
|
||||
import { ClusterStore } from "./cluster-store";
|
||||
import { getHostedClusterId } from "./utils";
|
||||
|
||||
export type KubeResource =
|
||||
"namespaces" | "nodes" | "events" | "resourcequotas" | "services" | "limitranges" |
|
||||
@@ -78,7 +79,7 @@ export function isAllowedResource(resources: KubeResource | KubeResource[]) {
|
||||
if (!Array.isArray(resources)) {
|
||||
resources = [resources];
|
||||
}
|
||||
const { allowedResources = [] } = getHostedCluster() || {};
|
||||
const { allowedResources = [] } = ClusterStore.getInstance().getById(getHostedClusterId()) || {};
|
||||
|
||||
for (const resource of resources) {
|
||||
if (!allowedResources.includes(resource)) {
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* 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 { getClusterIdFromHost } from "../cluster-id-url-parsing";
|
||||
|
||||
describe("getClusterIdFromHost", () => {
|
||||
const clusterFakeId = "fe540901-0bd6-4f6c-b472-bce1559d7c4a";
|
||||
|
||||
it("should return undefined for non cluster frame hosts", () => {
|
||||
expect(getClusterIdFromHost("localhost:45345")).toBeUndefined();
|
||||
});
|
||||
|
||||
it("should return ClusterId for cluster frame hosts", () => {
|
||||
expect(getClusterIdFromHost(`${clusterFakeId}.localhost:59110`)).toBe(clusterFakeId);
|
||||
});
|
||||
|
||||
it("should return ClusterId for cluster frame hosts with additional subdomains", () => {
|
||||
expect(getClusterIdFromHost(`abc.${clusterFakeId}.localhost:59110`)).toBe(clusterFakeId);
|
||||
expect(getClusterIdFromHost(`abc.def.${clusterFakeId}.localhost:59110`)).toBe(clusterFakeId);
|
||||
expect(getClusterIdFromHost(`abc.def.ghi.${clusterFakeId}.localhost:59110`)).toBe(clusterFakeId);
|
||||
expect(getClusterIdFromHost(`abc.def.ghi.jkl.${clusterFakeId}.localhost:59110`)).toBe(clusterFakeId);
|
||||
expect(getClusterIdFromHost(`abc.def.ghi.jkl.mno.${clusterFakeId}.localhost:59110`)).toBe(clusterFakeId);
|
||||
expect(getClusterIdFromHost(`abc.def.ghi.jkl.mno.pqr.${clusterFakeId}.localhost:59110`)).toBe(clusterFakeId);
|
||||
expect(getClusterIdFromHost(`abc.def.ghi.jkl.mno.pqr.stu.${clusterFakeId}.localhost:59110`)).toBe(clusterFakeId);
|
||||
expect(getClusterIdFromHost(`abc.def.ghi.jkl.mno.pqr.stu.vwx.${clusterFakeId}.localhost:59110`)).toBe(clusterFakeId);
|
||||
expect(getClusterIdFromHost(`abc.def.ghi.jkl.mno.pqr.stu.vwx.yz.${clusterFakeId}.localhost:59110`)).toBe(clusterFakeId);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* 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 { ClusterId } from "../cluster-types";
|
||||
|
||||
/**
|
||||
* Grab the `ClusterId` out of a host that was generated by `getClusterFrameUrl`, or nothing
|
||||
* @param host The host section of a URL
|
||||
* @returns The `ClusterId` part of the host, or `undefined`
|
||||
*/
|
||||
export function getClusterIdFromHost(host: string): ClusterId | undefined {
|
||||
// e.g host == "%clusterId.localhost:45345"
|
||||
const subDomains = host.split(":")[0].split(".");
|
||||
|
||||
return subDomains.slice(-2, -1)[0]; // ClusterId or undefined
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the OpenLens backend routing host for a given `ClusterId`
|
||||
* @param clusterId The ID to put in front of the current host
|
||||
* @returns a new URL host section
|
||||
*/
|
||||
export function getClusterFrameUrl(clusterId: ClusterId) {
|
||||
return `//${clusterId}.${location.host}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the result of `getClusterIdFromHost` from the current `location.host`
|
||||
*/
|
||||
export function getHostedClusterId(): ClusterId | undefined {
|
||||
return getClusterIdFromHost(location.host);
|
||||
}
|
||||
@@ -31,6 +31,7 @@ export * from "./autobind";
|
||||
export * from "./base64";
|
||||
export * from "./camelCase";
|
||||
export * from "./cloneJson";
|
||||
export * from "./cluster-id-url-parsing";
|
||||
export * from "./debouncePromise";
|
||||
export * from "./defineGlobal";
|
||||
export * from "./delay";
|
||||
@@ -40,6 +41,7 @@ export * from "./escapeRegExp";
|
||||
export * from "./extended-map";
|
||||
export * from "./getRandId";
|
||||
export * from "./hash-set";
|
||||
export * from "./local-kubeconfig";
|
||||
export * from "./n-fircate";
|
||||
export * from "./openExternal";
|
||||
export * from "./paths";
|
||||
@@ -51,6 +53,7 @@ export * from "./tar";
|
||||
export * from "./toggle-set";
|
||||
export * from "./toJS";
|
||||
export * from "./type-narrowing";
|
||||
export * from "./types";
|
||||
|
||||
import * as iter from "./iter";
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* 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 { app, remote } from "electron";
|
||||
import path from "path";
|
||||
import * as uuid from "uuid";
|
||||
import type { ClusterId } from "../cluster-types";
|
||||
|
||||
export function storedKubeConfigFolder(): string {
|
||||
return path.resolve((app || remote.app).getPath("userData"), "kubeconfigs");
|
||||
}
|
||||
|
||||
export function getCustomKubeConfigPath(clusterId: ClusterId = uuid.v4()): string {
|
||||
return path.resolve(storedKubeConfigFolder(), clusterId);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* An N length tuple of T
|
||||
*/
|
||||
export type Tuple<T, N extends number> = N extends N ? number extends N ? T[] : _TupleOf<T, N, []> : never;
|
||||
type _TupleOf<T, N extends number, R extends unknown[]> = R["length"] extends N ? R : _TupleOf<T, N, [T, ...R]>;
|
||||
Reference in new issue
Block a user