mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Migrating Vue components to React and stores refactoring (#585)
Signed-off-by: Roman <ixrock@gmail.com> Co-authored-by: Sebastian Malton <sebastian@malton.name> Co-authored-by: Sebastian Malton <smalton@mirantis.com> Co-authored-by: Lauri Nevala <lauri.nevala@gmail.com> Co-authored-by: Alex Andreev <alex.andreev.email@gmail.com>
This commit is contained in:
297 files changed
+8186
-9103
No files matched your search
@@ -1,9 +0,0 @@
|
||||
// App configuration api
|
||||
import type { IConfigRoutePayload } from "../../../main/routes/config";
|
||||
import { apiBase } from "../index";
|
||||
|
||||
export const configApi = {
|
||||
getConfig() {
|
||||
return apiBase.get<IConfigRoutePayload>("/config")
|
||||
},
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
import { compile } from "path-to-regexp";
|
||||
import { apiHelm } from "../index";
|
||||
import { apiBase } from "../index";
|
||||
import { stringify } from "querystring";
|
||||
import { autobind } from "../../utils";
|
||||
|
||||
@@ -21,7 +21,7 @@ const endpoint = compile(`/v2/charts/:repo?/:name?`) as (params?: {
|
||||
|
||||
export const helmChartsApi = {
|
||||
list() {
|
||||
return apiHelm
|
||||
return apiBase
|
||||
.get<IHelmChartList>(endpoint())
|
||||
.then(data => {
|
||||
return Object
|
||||
@@ -33,7 +33,7 @@ export const helmChartsApi = {
|
||||
|
||||
get(repo: string, name: string, readmeVersion?: string) {
|
||||
const path = endpoint({ repo, name });
|
||||
return apiHelm
|
||||
return apiBase
|
||||
.get<IHelmChartDetails>(path + "?" + stringify({ version: readmeVersion }))
|
||||
.then(data => {
|
||||
const versions = data.versions.map(HelmChart.create);
|
||||
@@ -46,7 +46,7 @@ export const helmChartsApi = {
|
||||
},
|
||||
|
||||
getValues(repo: string, name: string, version: string) {
|
||||
return apiHelm
|
||||
return apiBase
|
||||
.get<string>(`/v2/charts/${repo}/${name}/values?` + stringify({ version }));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@ import jsYaml from "js-yaml";
|
||||
import { compile } from "path-to-regexp";
|
||||
import { autobind, formatDuration } from "../../utils";
|
||||
import capitalize from "lodash/capitalize";
|
||||
import { apiHelm } from "../index";
|
||||
import { apiBase } from "../index";
|
||||
import { helmChartStore } from "../../components/+apps-helm-charts/helm-chart.store";
|
||||
import { ItemObject } from "../../item.store";
|
||||
import { KubeObject } from "../kube-object";
|
||||
@@ -69,14 +69,14 @@ const endpoint = compile(`/v2/releases/:namespace?/:name?`) as (
|
||||
|
||||
export const helmReleasesApi = {
|
||||
list(namespace?: string) {
|
||||
return apiHelm
|
||||
return apiBase
|
||||
.get<HelmRelease[]>(endpoint({ namespace }))
|
||||
.then(releases => releases.map(HelmRelease.create));
|
||||
},
|
||||
|
||||
get(name: string, namespace: string) {
|
||||
const path = endpoint({ name, namespace });
|
||||
return apiHelm.get<IReleaseRawDetails>(path).then(details => {
|
||||
return apiBase.get<IReleaseRawDetails>(path).then(details => {
|
||||
const items: KubeObject[] = JSON.parse(details.resources).items;
|
||||
const resources = items.map(item => KubeObject.create(item));
|
||||
return {
|
||||
@@ -90,34 +90,34 @@ export const helmReleasesApi = {
|
||||
const { repo, ...data } = payload;
|
||||
data.chart = `${repo}/${data.chart}`;
|
||||
data.values = jsYaml.safeLoad(data.values);
|
||||
return apiHelm.post(endpoint(), { data });
|
||||
return apiBase.post(endpoint(), { data });
|
||||
},
|
||||
|
||||
update(name: string, namespace: string, payload: IReleaseUpdatePayload): Promise<IReleaseUpdateDetails> {
|
||||
const { repo, ...data } = payload;
|
||||
data.chart = `${repo}/${data.chart}`;
|
||||
data.values = jsYaml.safeLoad(data.values);
|
||||
return apiHelm.put(endpoint({ name, namespace }), { data });
|
||||
return apiBase.put(endpoint({ name, namespace }), { data });
|
||||
},
|
||||
|
||||
async delete(name: string, namespace: string) {
|
||||
const path = endpoint({ name, namespace });
|
||||
return apiHelm.del(path);
|
||||
return apiBase.del(path);
|
||||
},
|
||||
|
||||
getValues(name: string, namespace: string) {
|
||||
const path = endpoint({ name, namespace }) + "/values";
|
||||
return apiHelm.get<string>(path);
|
||||
return apiBase.get<string>(path);
|
||||
},
|
||||
|
||||
getHistory(name: string, namespace: string): Promise<IReleaseRevision[]> {
|
||||
const path = endpoint({ name, namespace }) + "/history";
|
||||
return apiHelm.get(path);
|
||||
return apiBase.get(path);
|
||||
},
|
||||
|
||||
rollback(name: string, namespace: string, revision: number) {
|
||||
const path = endpoint({ name, namespace }) + "/rollback";
|
||||
return apiHelm.put(path, {
|
||||
return apiBase.put(path, {
|
||||
data: {
|
||||
revision: revision
|
||||
}
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
// Local express.js endpoints
|
||||
export * from "./config.api"
|
||||
export * from "./cluster.api"
|
||||
export * from "./kubeconfig.api"
|
||||
|
||||
// Kubernetes endpoints
|
||||
// Kubernetes apis
|
||||
// Docs: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.10/
|
||||
|
||||
export * from "./cluster.api"
|
||||
export * from "./namespaces.api"
|
||||
export * from "./cluster-role.api"
|
||||
export * from "./cluster-role-binding.api"
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
// Kubeconfig api
|
||||
import { apiBase } from "../index";
|
||||
|
||||
export const kubeConfigApi = {
|
||||
getUserConfig() {
|
||||
return apiBase.get("/kubeconfig/user");
|
||||
},
|
||||
|
||||
getServiceAccountConfig(account: string, namespace: string) {
|
||||
return apiBase.get(`/kubeconfig/service-account/${namespace}/${account}`);
|
||||
},
|
||||
};
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import moment from "moment";
|
||||
import { apiBase } from "../index";
|
||||
import type { IMetricsQuery } from "../../../main/routes/metrics";
|
||||
import type { IMetricsQuery } from "../../../main/routes/metrics-route";
|
||||
|
||||
export interface IMetrics {
|
||||
status: string;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import jsYaml from "js-yaml"
|
||||
import { KubeObject } from "../kube-object";
|
||||
import { KubeJsonApiData } from "../kube-json-api";
|
||||
import { apiResourceApplier } from "../index";
|
||||
import { apiBase } from "../index";
|
||||
import { apiManager } from "../api-manager";
|
||||
|
||||
export const resourceApplierApi = {
|
||||
@@ -13,7 +13,7 @@ export const resourceApplierApi = {
|
||||
if (typeof resource === "string") {
|
||||
resource = jsYaml.safeLoad(resource);
|
||||
}
|
||||
return apiResourceApplier
|
||||
return apiBase
|
||||
.post<KubeJsonApiData[]>("/stack", { data: resource })
|
||||
.then(data => {
|
||||
const items = data.map(obj => {
|
||||
|
||||
@@ -24,7 +24,7 @@ export class SelfSubjectRulesReview extends KubeObject {
|
||||
static kind = "SelfSubjectRulesReview"
|
||||
|
||||
spec: {
|
||||
// fixme: add more types from api docs
|
||||
// todo: add more types from api docs
|
||||
namespace?: string;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,29 +1,19 @@
|
||||
import { JsonApi, JsonApiErrorParsed } from "./json-api";
|
||||
import { KubeJsonApi } from "./kube-json-api";
|
||||
import { Notifications } from "../components/notifications";
|
||||
import { apiPrefix, isDevelopment } from "../../common/vars";
|
||||
|
||||
//-- JSON HTTP APIS
|
||||
import { apiKubePrefix, apiPrefix, isDevelopment } from "../../common/vars";
|
||||
|
||||
export const apiBase = new JsonApi({
|
||||
apiBase: apiPrefix,
|
||||
debug: isDevelopment,
|
||||
apiPrefix: apiPrefix.BASE,
|
||||
});
|
||||
export const apiKube = new KubeJsonApi({
|
||||
apiBase: apiKubePrefix,
|
||||
debug: isDevelopment,
|
||||
apiPrefix: apiPrefix.KUBE_BASE,
|
||||
});
|
||||
export const apiHelm = new KubeJsonApi({
|
||||
debug: isDevelopment,
|
||||
apiPrefix: apiPrefix.KUBE_HELM,
|
||||
});
|
||||
export const apiResourceApplier = new KubeJsonApi({
|
||||
debug: isDevelopment,
|
||||
apiPrefix: apiPrefix.KUBE_RESOURCE_APPLIER,
|
||||
});
|
||||
|
||||
// Common handler for HTTP api errors
|
||||
function onApiError(error: JsonApiErrorParsed, res: Response) {
|
||||
export function onApiError(error: JsonApiErrorParsed, res: Response) {
|
||||
switch (res.status) {
|
||||
case 403:
|
||||
error.isUsedForNotification = true;
|
||||
@@ -34,5 +24,3 @@ function onApiError(error: JsonApiErrorParsed, res: Response) {
|
||||
|
||||
apiBase.onError.addListener(onApiError);
|
||||
apiKube.onError.addListener(onApiError);
|
||||
apiHelm.onError.addListener(onApiError);
|
||||
apiResourceApplier.onError.addListener(onApiError);
|
||||
@@ -27,7 +27,7 @@ export interface JsonApiLog {
|
||||
}
|
||||
|
||||
export interface JsonApiConfig {
|
||||
apiPrefix: string;
|
||||
apiBase: string;
|
||||
debug?: boolean;
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ export class JsonApi<D = JsonApiData, P extends JsonApiParams = JsonApiParams> {
|
||||
}
|
||||
|
||||
protected request<D>(path: string, params?: P, init: RequestInit = {}) {
|
||||
let reqUrl = this.config.apiPrefix + path;
|
||||
let reqUrl = this.config.apiBase + path;
|
||||
const reqInit: RequestInit = { ...this.reqInit, ...init };
|
||||
const { data, query } = params || {} as P;
|
||||
if (data && !reqInit.body) {
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
// Parse kube-api path and get api-version, group, etc.
|
||||
|
||||
import type { KubeObject } from "./kube-object";
|
||||
import { splitArray } from "../../common/utils";
|
||||
import { apiManager } from "./api-manager";
|
||||
|
||||
export interface IKubeObjectRef {
|
||||
kind: string;
|
||||
apiVersion: string;
|
||||
name: string;
|
||||
namespace?: string;
|
||||
}
|
||||
|
||||
export interface IKubeApiLinkRef {
|
||||
apiPrefix?: string;
|
||||
@@ -9,13 +19,13 @@ export interface IKubeApiLinkRef {
|
||||
namespace?: string;
|
||||
}
|
||||
|
||||
export interface IKubeApiLinkBase extends IKubeApiLinkRef {
|
||||
export interface IKubeApiParsed extends IKubeApiLinkRef {
|
||||
apiBase: string;
|
||||
apiGroup: string;
|
||||
apiVersionWithGroup: string;
|
||||
}
|
||||
|
||||
export function parseApi(path: string): IKubeApiLinkBase {
|
||||
export function parseKubeApi(path: string): IKubeApiParsed {
|
||||
path = new URL(path, location.origin).pathname;
|
||||
const [, prefix, ...parts] = path.split("/");
|
||||
const apiPrefix = `/${prefix}`;
|
||||
@@ -94,7 +104,7 @@ export function parseApi(path: string): IKubeApiLinkBase {
|
||||
};
|
||||
}
|
||||
|
||||
export function createApiLink(ref: IKubeApiLinkRef): string {
|
||||
export function createKubeApiURL(ref: IKubeApiLinkRef): string {
|
||||
const { apiPrefix = "/apis", resource, apiVersion, name } = ref;
|
||||
let { namespace } = ref;
|
||||
if (namespace) {
|
||||
@@ -104,3 +114,36 @@ export function createApiLink(ref: IKubeApiLinkRef): string {
|
||||
.filter(v => v)
|
||||
.join("/")
|
||||
}
|
||||
|
||||
export function lookupApiLink(ref: IKubeObjectRef, parentObject: KubeObject): string {
|
||||
const {
|
||||
kind, apiVersion, name,
|
||||
namespace = parentObject.getNs()
|
||||
} = ref;
|
||||
|
||||
// search in registered apis by 'kind' & 'apiVersion'
|
||||
const api = apiManager.getApi(api => api.kind === kind && api.apiVersionWithGroup == apiVersion)
|
||||
if (api) {
|
||||
return api.getUrl({ namespace, name })
|
||||
}
|
||||
|
||||
// lookup api by generated resource link
|
||||
const apiPrefixes = ["/apis", "/api"];
|
||||
const resource = kind.toLowerCase() + kind.endsWith("s") ? "es" : "s";
|
||||
for (const apiPrefix of apiPrefixes) {
|
||||
const apiLink = createKubeApiURL({ apiPrefix, apiVersion, name, namespace, resource });
|
||||
if (apiManager.getApi(apiLink)) {
|
||||
return apiLink;
|
||||
}
|
||||
}
|
||||
|
||||
// resolve by kind only (hpa's might use refs to older versions of resources for example)
|
||||
const apiByKind = apiManager.getApi(api => api.kind === kind);
|
||||
if (apiByKind) {
|
||||
return apiByKind.getUrl({ name, namespace })
|
||||
}
|
||||
|
||||
// otherwise generate link with default prefix
|
||||
// resource still might exists in k8s, but api is not registered in the app
|
||||
return createKubeApiURL({ apiVersion, name, namespace, resource })
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
import { IKubeApiLinkBase, parseApi } from "./kube-api-parse";
|
||||
import { IKubeApiParsed, parseKubeApi } from "./kube-api-parse";
|
||||
|
||||
interface KubeApi_Parse_Test {
|
||||
url: string;
|
||||
expected: Required<IKubeApiLinkBase>;
|
||||
expected: Required<IKubeApiParsed>;
|
||||
}
|
||||
|
||||
const tests: KubeApi_Parse_Test[] = [
|
||||
@@ -129,7 +129,7 @@ describe.only("parseApi unit tests", () => {
|
||||
for (const i in tests) {
|
||||
const { url: tUrl, expected:tExpect} = tests[i];
|
||||
test(`test #${parseInt(i)+1}`, () => {
|
||||
expect(parseApi(tUrl)).toStrictEqual(tExpect);
|
||||
expect(parseKubeApi(tUrl)).toStrictEqual(tExpect);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -3,11 +3,11 @@
|
||||
import merge from "lodash/merge"
|
||||
import { stringify } from "querystring";
|
||||
import { IKubeObjectConstructor, KubeObject } from "./kube-object";
|
||||
import { IKubeObjectRef, KubeJsonApi, KubeJsonApiData, KubeJsonApiDataList } from "./kube-json-api";
|
||||
import { KubeJsonApi, KubeJsonApiData, KubeJsonApiDataList } from "./kube-json-api";
|
||||
import { apiKube } from "./index";
|
||||
import { kubeWatchApi } from "./kube-watch-api";
|
||||
import { apiManager } from "./api-manager";
|
||||
import { createApiLink, parseApi } from "./kube-api-parse";
|
||||
import { createKubeApiURL, parseKubeApi } from "./kube-api-parse";
|
||||
|
||||
export interface IKubeApiOptions<T extends KubeObject> {
|
||||
kind: string; // resource type within api-group, e.g. "Namespace"
|
||||
@@ -26,8 +26,7 @@ export interface IKubeApiQueryParams {
|
||||
}
|
||||
|
||||
export class KubeApi<T extends KubeObject = any> {
|
||||
static parseApi = parseApi;
|
||||
static createLink = createApiLink;
|
||||
static parseApi = parseKubeApi;
|
||||
|
||||
static watchAll(...apis: KubeApi[]) {
|
||||
const disposers = apis.map(api => api.watch());
|
||||
@@ -85,7 +84,7 @@ export class KubeApi<T extends KubeObject = any> {
|
||||
|
||||
getUrl({ name = "", namespace = "" } = {}, query?: Partial<IKubeApiQueryParams>) {
|
||||
const { apiPrefix, apiVersionWithGroup, apiResource } = this;
|
||||
const resourcePath = KubeApi.createLink({
|
||||
const resourcePath = createKubeApiURL({
|
||||
apiPrefix: apiPrefix,
|
||||
apiVersion: apiVersionWithGroup,
|
||||
resource: apiResource,
|
||||
@@ -175,35 +174,4 @@ export class KubeApi<T extends KubeObject = any> {
|
||||
}
|
||||
}
|
||||
|
||||
export function lookupApiLink(ref: IKubeObjectRef, parentObject: KubeObject): string {
|
||||
const {
|
||||
kind, apiVersion, name,
|
||||
namespace = parentObject.getNs()
|
||||
} = ref;
|
||||
|
||||
// search in registered apis by 'kind' & 'apiVersion'
|
||||
const api = apiManager.getApi(api => api.kind === kind && api.apiVersionWithGroup == apiVersion)
|
||||
if (api) {
|
||||
return api.getUrl({ namespace, name })
|
||||
}
|
||||
|
||||
// lookup api by generated resource link
|
||||
const apiPrefixes = ["/apis", "/api"];
|
||||
const resource = kind.toLowerCase() + kind.endsWith("s") ? "es" : "s";
|
||||
for (const apiPrefix of apiPrefixes) {
|
||||
const apiLink = KubeApi.createLink({ apiPrefix, apiVersion, name, namespace, resource });
|
||||
if (apiManager.getApi(apiLink)) {
|
||||
return apiLink;
|
||||
}
|
||||
}
|
||||
|
||||
// resolve by kind only (hpa's might use refs to older versions of resources for example)
|
||||
const apiByKind = apiManager.getApi(api => api.kind === kind);
|
||||
if (apiByKind) {
|
||||
return apiByKind.getUrl({ name, namespace })
|
||||
}
|
||||
|
||||
// otherwise generate link with default prefix
|
||||
// resource still might exists in k8s, but api is not registered in the app
|
||||
return KubeApi.createLink({ apiVersion, name, namespace, resource })
|
||||
}
|
||||
export * from "./kube-api-parse"
|
||||
@@ -31,13 +31,6 @@ export interface KubeJsonApiData extends JsonApiData {
|
||||
};
|
||||
}
|
||||
|
||||
export interface IKubeObjectRef {
|
||||
kind: string;
|
||||
apiVersion: string;
|
||||
name: string;
|
||||
namespace?: string;
|
||||
}
|
||||
|
||||
export interface KubeJsonApiError extends JsonApiError {
|
||||
code: number;
|
||||
status: string;
|
||||
@@ -49,14 +42,6 @@ export interface KubeJsonApiError extends JsonApiError {
|
||||
};
|
||||
}
|
||||
|
||||
export interface IKubeJsonApiQuery {
|
||||
watch?: any;
|
||||
resourceVersion?: string;
|
||||
timeoutSeconds?: number;
|
||||
limit?: number; // doesn't work with ?watch
|
||||
continue?: string; // might be used with ?limit from second request
|
||||
}
|
||||
|
||||
export class KubeJsonApi extends JsonApi<KubeJsonApiData> {
|
||||
protected parseError(error: KubeJsonApiError | any, res: Response): string[] {
|
||||
const { status, reason, message } = error;
|
||||
|
||||
@@ -6,9 +6,9 @@ import { autobind, EventEmitter } from "../utils";
|
||||
import { KubeJsonApiData } from "./kube-json-api";
|
||||
import type { KubeObjectStore } from "../kube-object.store";
|
||||
import { KubeApi } from "./kube-api";
|
||||
import { configStore } from "../config.store";
|
||||
import { apiManager } from "./api-manager";
|
||||
import { apiPrefix, isDevelopment } from "../../common/vars";
|
||||
import { getHostedCluster } from "../../common/cluster-store";
|
||||
|
||||
export interface IKubeWatchEvent<T = any> {
|
||||
type: "ADDED" | "MODIFIED" | "DELETED";
|
||||
@@ -29,7 +29,6 @@ export interface IKubeWatchRouteQuery {
|
||||
export class KubeWatchApi {
|
||||
protected evtSource: EventSource;
|
||||
protected onData = new EventEmitter<[IKubeWatchEvent]>();
|
||||
protected apiUrl = apiPrefix.BASE + "/watch";
|
||||
protected subscribers = observable.map<KubeApi, number>();
|
||||
protected reconnectTimeoutMs = 5000;
|
||||
protected maxReconnectsOnError = 10;
|
||||
@@ -62,10 +61,10 @@ export class KubeWatchApi {
|
||||
}
|
||||
|
||||
protected getQuery(): Partial<IKubeWatchRouteQuery> {
|
||||
const { isClusterAdmin, allowedNamespaces } = configStore;
|
||||
const { isAdmin, allowedNamespaces } = getHostedCluster()
|
||||
return {
|
||||
api: this.activeApis.map(api => {
|
||||
if (isClusterAdmin) return api.getWatchUrl();
|
||||
if (isAdmin) return api.getWatchUrl();
|
||||
return allowedNamespaces.map(namespace => api.getWatchUrl(namespace))
|
||||
}).flat()
|
||||
}
|
||||
@@ -79,7 +78,7 @@ export class KubeWatchApi {
|
||||
return;
|
||||
}
|
||||
const query = this.getQuery();
|
||||
const apiUrl = this.apiUrl + "?" + stringify(query);
|
||||
const apiUrl = `${apiPrefix}/watch?` + stringify(query);
|
||||
this.evtSource = new EventSource(apiUrl);
|
||||
this.evtSource.onmessage = this.onMessage;
|
||||
this.evtSource.onerror = this.onError;
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
import { configStore } from "../config.store";
|
||||
|
||||
export function isAllowedResource(resources: string | string[]) {
|
||||
if (!Array.isArray(resources)) {
|
||||
resources = [resources];
|
||||
}
|
||||
const { allowedResources } = configStore;
|
||||
for (const resource of resources) {
|
||||
if (!allowedResources.includes(resource)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
import { stringify } from "querystring";
|
||||
import { autobind, base64, EventEmitter, interval } from "../utils";
|
||||
import { autobind, base64, EventEmitter } from "../utils";
|
||||
import { WebSocketApi } from "./websocket-api";
|
||||
import { configStore } from "../config.store";
|
||||
import isEqual from "lodash/isEqual"
|
||||
import { apiPrefix, isDevelopment } from "../../common/vars";
|
||||
import { isDevelopment } from "../../common/vars";
|
||||
|
||||
export enum TerminalChannels {
|
||||
STDIN = 0,
|
||||
@@ -25,21 +24,19 @@ enum TerminalColor {
|
||||
NO_COLOR = "\u001b[0m",
|
||||
}
|
||||
|
||||
export interface ITerminalApiOptions {
|
||||
export type TerminalApiQuery = Record<string, string> & {
|
||||
id: string;
|
||||
node?: string;
|
||||
colorTheme?: "light" | "dark";
|
||||
type?: string | "node";
|
||||
}
|
||||
|
||||
export class TerminalApi extends WebSocketApi {
|
||||
protected size: { Width: number; Height: number };
|
||||
protected currentToken: string;
|
||||
protected tokenInterval = interval(60, this.sendNewToken); // refresh every minute
|
||||
|
||||
public onReady = new EventEmitter<[]>();
|
||||
public isReady = false;
|
||||
|
||||
constructor(protected options: ITerminalApiOptions) {
|
||||
constructor(protected options: TerminalApiQuery) {
|
||||
super({
|
||||
logging: isDevelopment,
|
||||
flushOnOpen: false,
|
||||
@@ -47,50 +44,33 @@ export class TerminalApi extends WebSocketApi {
|
||||
});
|
||||
}
|
||||
|
||||
async getUrl(token: string) {
|
||||
const { hostname, protocol } = location;
|
||||
async getUrl() {
|
||||
let { port } = location;
|
||||
const { hostname, protocol } = location;
|
||||
const { id, node } = this.options;
|
||||
const wss = `ws${protocol === "https:" ? "s" : ""}://`;
|
||||
const queryParams = { token, id };
|
||||
const query: TerminalApiQuery = { id };
|
||||
if (port) {
|
||||
port = `:${port}`
|
||||
}
|
||||
if (node) {
|
||||
Object.assign(queryParams, {
|
||||
node: node,
|
||||
type: "node"
|
||||
});
|
||||
query.node = node;
|
||||
query.type = "node";
|
||||
}
|
||||
return `${wss}${hostname}${port}/api?${stringify(queryParams)}`;
|
||||
return `${wss}${hostname}${port}/api?${stringify(query)}`;
|
||||
}
|
||||
|
||||
async connect() {
|
||||
const token = await configStore.getToken();
|
||||
const apiUrl = await this.getUrl(token);
|
||||
const { colorTheme } = this.options;
|
||||
this.emitStatus("Connecting ...", {
|
||||
color: colorTheme == "light" ? TerminalColor.GRAY : TerminalColor.LIGHT_GRAY
|
||||
});
|
||||
const apiUrl = await this.getUrl();
|
||||
this.emitStatus("Connecting ...");
|
||||
this.onData.addListener(this._onReady, { prepend: true });
|
||||
this.currentToken = token;
|
||||
this.tokenInterval.start();
|
||||
return super.connect(apiUrl);
|
||||
}
|
||||
|
||||
@autobind()
|
||||
async sendNewToken() {
|
||||
const token = await configStore.getToken();
|
||||
if (!this.isReady || token == this.currentToken) return;
|
||||
this.sendCommand(token, TerminalChannels.TOKEN);
|
||||
this.currentToken = token;
|
||||
}
|
||||
|
||||
destroy() {
|
||||
if (!this.socket) return;
|
||||
const exitCode = String.fromCharCode(4); // ctrl+d
|
||||
this.sendCommand(exitCode);
|
||||
this.tokenInterval.stop();
|
||||
setTimeout(() => super.destroy(), 2000);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import get from "lodash/get";
|
||||
import { IKubeObjectMetadata, KubeObject } from "./kube-object";
|
||||
import { KubeObject } from "./kube-object";
|
||||
|
||||
interface IToleration {
|
||||
key?: string;
|
||||
@@ -47,9 +47,7 @@ export interface IAffinity {
|
||||
}
|
||||
|
||||
export class WorkloadKubeObject extends KubeObject {
|
||||
|
||||
// fixme: add type
|
||||
spec: any;
|
||||
spec: any; // todo: add proper types
|
||||
|
||||
getSelectors(): string[] {
|
||||
const selector = this.spec.selector;
|
||||
|
||||
Reference in new issue
Block a user