mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
cluster-store refactoring -- part 1
Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
parent
d4bbaf4f34
commit
afb54694f4
@ -25,7 +25,7 @@ export class BaseStore<T = any> extends Singleton {
|
|||||||
protected constructor(protected params: BaseStoreParams) {
|
protected constructor(protected params: BaseStoreParams) {
|
||||||
super();
|
super();
|
||||||
this.params = {
|
this.params = {
|
||||||
autoLoad: true,
|
autoLoad: !app, // disabled in main process due delayed configuration
|
||||||
syncEnabled: true,
|
syncEnabled: true,
|
||||||
...params,
|
...params,
|
||||||
}
|
}
|
||||||
@ -54,7 +54,7 @@ export class BaseStore<T = any> extends Singleton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async load() {
|
async load() {
|
||||||
const { configName, syncEnabled, confOptions = {} } = this.params;
|
const { configName, syncEnabled, confOptions = {} } = this.params;
|
||||||
|
|
||||||
// use "await" to make pseudo-async "load" for more future-proof usages
|
// use "await" to make pseudo-async "load" for more future-proof usages
|
||||||
@ -63,7 +63,10 @@ export class BaseStore<T = any> extends Singleton {
|
|||||||
projectVersion: getAppVersion(),
|
projectVersion: getAppVersion(),
|
||||||
configName: configName,
|
configName: configName,
|
||||||
watch: syncEnabled, // watch for changes in multi-process app (e.g. main/renderer)
|
watch: syncEnabled, // watch for changes in multi-process app (e.g. main/renderer)
|
||||||
cwd: (app || remote.app).getPath("userData"), // todo: remove remote.app in favor ipc.invoke
|
get cwd() {
|
||||||
|
// todo: remove remote.app in favor ipc.invoke
|
||||||
|
return (app || remote.app).getPath("userData");
|
||||||
|
},
|
||||||
...confOptions,
|
...confOptions,
|
||||||
});
|
});
|
||||||
const data = this.storeConfig.store;
|
const data = this.storeConfig.store;
|
||||||
|
|||||||
@ -1,86 +1,84 @@
|
|||||||
import Config from "conf"
|
import { action, computed, toJS } from "mobx";
|
||||||
import Singleton from "./utils/singleton";
|
|
||||||
import migrations from "../migrations/cluster-store"
|
import migrations from "../migrations/cluster-store"
|
||||||
import { Cluster, ClusterBaseInfo } from "../main/cluster";
|
import { BaseStore } from "./base-store";
|
||||||
|
import { Cluster } from "../main/cluster";
|
||||||
|
|
||||||
export class ClusterStore extends Singleton {
|
export interface ClusterStoreModel {
|
||||||
private storeConfig = new Config({
|
clusters: ClusterModel[]
|
||||||
configName: "lens-cluster-store",
|
}
|
||||||
accessPropertiesByDotNotation: false, // To make dots safe in cluster context names
|
|
||||||
migrations: migrations,
|
|
||||||
})
|
|
||||||
|
|
||||||
public getAllClusterObjects(): Cluster[] {
|
export type ClusterId = string;
|
||||||
return this.storeConfig.get("clusters", []).map((clusterInfo: ClusterBaseInfo) => {
|
|
||||||
return new Cluster(clusterInfo)
|
export interface ClusterModel {
|
||||||
})
|
id: ClusterId;
|
||||||
|
contextName: string;
|
||||||
|
kubeConfigPath: string;
|
||||||
|
kubeConfig?: string;
|
||||||
|
port?: number;
|
||||||
|
workspace?: string;
|
||||||
|
preferences?: ClusterPreferences;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ClusterPreferences {
|
||||||
|
terminalCWD?: string;
|
||||||
|
clusterName?: string;
|
||||||
|
prometheus?: {
|
||||||
|
namespace: string;
|
||||||
|
service: string;
|
||||||
|
port: number;
|
||||||
|
prefix: string;
|
||||||
|
};
|
||||||
|
prometheusProvider?: {
|
||||||
|
type: string;
|
||||||
|
};
|
||||||
|
icon?: string;
|
||||||
|
httpsProxy?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ClusterStore extends BaseStore<ClusterStoreModel> {
|
||||||
|
private constructor() {
|
||||||
|
super({
|
||||||
|
configName: "lens-cluster-store",
|
||||||
|
confOptions: {
|
||||||
|
migrations: migrations,
|
||||||
|
accessPropertiesByDotNotation: false, // To make dots safe in cluster context names
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public getAllClusters(): ClusterBaseInfo[] {
|
// setup initial value
|
||||||
return this.storeConfig.get("clusters", [])
|
protected data: ClusterStoreModel = {
|
||||||
|
clusters: [],
|
||||||
}
|
}
|
||||||
|
|
||||||
public removeCluster(id: string): void {
|
@computed get clusters(): Cluster[] {
|
||||||
this.storeConfig.delete(id);
|
return toJS(this.data.clusters).map(model => new Cluster(model));
|
||||||
const clusterBaseInfos = this.getAllClusters()
|
}
|
||||||
const index = clusterBaseInfos.findIndex((cbi) => cbi.id === id)
|
|
||||||
if (index !== -1) {
|
getById(clusterId: ClusterId): Cluster {
|
||||||
clusterBaseInfos.splice(index, 1)
|
return this.clusters.find(cluster => cluster.id === clusterId)
|
||||||
this.storeConfig.set("clusters", clusterBaseInfos)
|
}
|
||||||
|
|
||||||
|
getIndexById(clusterId: ClusterId): number {
|
||||||
|
return this.clusters.findIndex(cluster => cluster.id === clusterId)
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
removeById(clusterId: ClusterId): void {
|
||||||
|
const index = this.getIndexById(clusterId);
|
||||||
|
if (index > -1) {
|
||||||
|
this.data.clusters.splice(index, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public removeClustersByWorkspace(workspace: string) {
|
@action
|
||||||
this.getAllClusters().forEach((cluster) => {
|
removeAllByWorkspaceId(workspaceId: string) {
|
||||||
if (cluster.workspace === workspace) {
|
this.clusters.forEach(cluster => {
|
||||||
this.removeCluster(cluster.id)
|
if (cluster.workspace === workspaceId) {
|
||||||
|
this.removeById(cluster.id)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
public getCluster(id: string): Cluster {
|
|
||||||
const cluster = this.getAllClusterObjects().find((cluster) => cluster.id === id)
|
|
||||||
if (cluster) {
|
|
||||||
return cluster
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
public saveCluster(cluster: ClusterBaseInfo) {
|
|
||||||
const clusters = this.getAllClusters();
|
|
||||||
const index = clusters.findIndex((cl) => cl.id === cluster.id)
|
|
||||||
const storable = {
|
|
||||||
id: cluster.id,
|
|
||||||
kubeConfigPath: cluster.kubeConfigPath,
|
|
||||||
contextName: cluster.contextName,
|
|
||||||
preferences: cluster.preferences,
|
|
||||||
workspace: cluster.workspace
|
|
||||||
}
|
|
||||||
if (index === -1) {
|
|
||||||
clusters.push(storable)
|
|
||||||
} else {
|
|
||||||
clusters[index] = storable
|
|
||||||
}
|
|
||||||
this.storeConfig.set("clusters", clusters)
|
|
||||||
}
|
|
||||||
|
|
||||||
public storeClusters(clusters: ClusterBaseInfo[]) {
|
|
||||||
clusters.forEach((cluster: ClusterBaseInfo) => {
|
|
||||||
this.removeCluster(cluster.id)
|
|
||||||
this.saveCluster(cluster)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
public reloadCluster(cluster: ClusterBaseInfo): void {
|
|
||||||
const storedCluster = this.getCluster(cluster.id);
|
|
||||||
if (storedCluster) {
|
|
||||||
cluster.kubeConfigPath = storedCluster.kubeConfigPath
|
|
||||||
cluster.contextName = storedCluster.contextName
|
|
||||||
cluster.preferences = storedCluster.preferences
|
|
||||||
cluster.workspace = storedCluster.workspace
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const clusterStore: ClusterStore = ClusterStore.getInstance();
|
export const clusterStore: ClusterStore = ClusterStore.getInstance();
|
||||||
|
|||||||
@ -1,297 +0,0 @@
|
|||||||
import mockFs from "mock-fs"
|
|
||||||
import yaml from "js-yaml"
|
|
||||||
import { ClusterStore } from "./cluster-store";
|
|
||||||
import { Cluster } from "../main/cluster";
|
|
||||||
|
|
||||||
let clusterStore: ClusterStore;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
ClusterStore.resetInstance()
|
|
||||||
clusterStore = ClusterStore.getInstance();
|
|
||||||
})
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
mockFs.restore()
|
|
||||||
})
|
|
||||||
|
|
||||||
describe("for an empty config", () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
const mockOpts = {
|
|
||||||
'tmp': {
|
|
||||||
'lens-cluster-store.json': JSON.stringify({})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mockFs(mockOpts)
|
|
||||||
})
|
|
||||||
|
|
||||||
it("allows to store and retrieve a cluster", async () => {
|
|
||||||
const cluster = new Cluster({
|
|
||||||
id: 'foo',
|
|
||||||
kubeConfigPath: 'kubeconfig',
|
|
||||||
contextName: "foo",
|
|
||||||
preferences: {
|
|
||||||
terminalCWD: '/tmp',
|
|
||||||
icon: 'path to icon'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
clusterStore.saveCluster(cluster);
|
|
||||||
const storedCluster = clusterStore.getCluster(cluster.id);
|
|
||||||
expect(storedCluster.kubeConfigPath).toBe(cluster.kubeConfigPath)
|
|
||||||
expect(storedCluster.contextName).toBe(cluster.contextName)
|
|
||||||
expect(storedCluster.preferences.icon).toBe(cluster.preferences.icon)
|
|
||||||
expect(storedCluster.preferences.terminalCWD).toBe(cluster.preferences.terminalCWD)
|
|
||||||
expect(storedCluster.id).toBe(cluster.id)
|
|
||||||
})
|
|
||||||
|
|
||||||
it("allows to delete a cluster", async () => {
|
|
||||||
const cluster = new Cluster({
|
|
||||||
id: 'foofoo',
|
|
||||||
kubeConfigPath: 'kubeconfig',
|
|
||||||
contextName: "foo",
|
|
||||||
preferences: {
|
|
||||||
terminalCWD: '/tmp'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
clusterStore.saveCluster(cluster);
|
|
||||||
const storedCluster = clusterStore.getCluster(cluster.id);
|
|
||||||
expect(storedCluster.id).toBe(cluster.id)
|
|
||||||
|
|
||||||
clusterStore.removeCluster(cluster.id);
|
|
||||||
|
|
||||||
expect(clusterStore.getCluster(cluster.id)).toBe(null)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe("for a config with existing clusters", () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
const mockOpts = {
|
|
||||||
'tmp': {
|
|
||||||
'lens-cluster-store.json': JSON.stringify({
|
|
||||||
__internal__: {
|
|
||||||
migrations: {
|
|
||||||
version: "99.99.99"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
clusters: [
|
|
||||||
{
|
|
||||||
id: 'cluster1',
|
|
||||||
kubeConfigPath: 'foo',
|
|
||||||
preferences: { terminalCWD: '/foo' }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'cluster2',
|
|
||||||
kubeConfigPath: 'foo2',
|
|
||||||
preferences: { terminalCWD: '/foo2' }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mockFs(mockOpts)
|
|
||||||
})
|
|
||||||
|
|
||||||
it("allows to retrieve a cluster", async () => {
|
|
||||||
const storedCluster = clusterStore.getCluster('cluster1')
|
|
||||||
expect(storedCluster.kubeConfigPath).toBe('foo')
|
|
||||||
expect(storedCluster.preferences.terminalCWD).toBe('/foo')
|
|
||||||
expect(storedCluster.id).toBe('cluster1')
|
|
||||||
|
|
||||||
const storedCluster2 = clusterStore.getCluster('cluster2')
|
|
||||||
expect(storedCluster2.kubeConfigPath).toBe('foo2')
|
|
||||||
expect(storedCluster2.preferences.terminalCWD).toBe('/foo2')
|
|
||||||
expect(storedCluster2.id).toBe('cluster2')
|
|
||||||
})
|
|
||||||
|
|
||||||
it("allows to delete a cluster", async () => {
|
|
||||||
clusterStore.removeCluster('cluster2')
|
|
||||||
|
|
||||||
// Verify the other cluster still exists:
|
|
||||||
const storedCluster = clusterStore.getCluster('cluster1')
|
|
||||||
expect(storedCluster.id).toBe('cluster1')
|
|
||||||
|
|
||||||
const storedCluster2 = clusterStore.getCluster('cluster2')
|
|
||||||
expect(storedCluster2).toBe(null)
|
|
||||||
})
|
|
||||||
|
|
||||||
it("allows to reload a cluster in-place", async () => {
|
|
||||||
const cluster = new Cluster({
|
|
||||||
id: 'cluster1',
|
|
||||||
kubeConfigPath: 'kubeconfig string',
|
|
||||||
contextName: "foo",
|
|
||||||
preferences: {
|
|
||||||
terminalCWD: '/tmp'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
clusterStore.reloadCluster(cluster)
|
|
||||||
|
|
||||||
expect(cluster.kubeConfigPath).toBe('foo')
|
|
||||||
expect(cluster.preferences.terminalCWD).toBe('/foo')
|
|
||||||
expect(cluster.id).toBe('cluster1')
|
|
||||||
})
|
|
||||||
|
|
||||||
it("allows getting all the clusters", async () => {
|
|
||||||
const storedClusters = clusterStore.getAllClusters()
|
|
||||||
|
|
||||||
expect(storedClusters[0].id).toBe('cluster1')
|
|
||||||
expect(storedClusters[0].preferences.terminalCWD).toBe('/foo')
|
|
||||||
expect(storedClusters[0].kubeConfigPath).toBe('foo')
|
|
||||||
|
|
||||||
expect(storedClusters[1].id).toBe('cluster2')
|
|
||||||
expect(storedClusters[1].preferences.terminalCWD).toBe('/foo2')
|
|
||||||
expect(storedClusters[1].kubeConfigPath).toBe('foo2')
|
|
||||||
})
|
|
||||||
|
|
||||||
it("allows storing the clusters in a different order", async () => {
|
|
||||||
const storedClusters = clusterStore.getAllClusters()
|
|
||||||
|
|
||||||
const reorderedClusters = [storedClusters[1], storedClusters[0]]
|
|
||||||
clusterStore.storeClusters(reorderedClusters)
|
|
||||||
const storedClusters2 = clusterStore.getAllClusters()
|
|
||||||
|
|
||||||
expect(storedClusters2[0].id).toBe('cluster2')
|
|
||||||
expect(storedClusters2[1].id).toBe('cluster1')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// describe("for a pre 2.0 config with an existing cluster", () => {
|
|
||||||
// beforeEach(() => {
|
|
||||||
// const mockOpts = {
|
|
||||||
// 'tmp': {
|
|
||||||
// 'lens-cluster-store.json': JSON.stringify({
|
|
||||||
// __internal__: {
|
|
||||||
// migrations: {
|
|
||||||
// version: "1.0.0"
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// cluster1: 'kubeconfig content'
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// mockFs(mockOpts)
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// it("migrates to modern format with kubeconfig under a key", async () => {
|
|
||||||
// const storedCluster = clusterStore.store.get('clusters')[0]
|
|
||||||
// expect(storedCluster.kubeConfigPath).toBe(`tmp/kubeconfigs/${storedCluster.id}`)
|
|
||||||
// })
|
|
||||||
// })
|
|
||||||
|
|
||||||
// describe("for a pre 2.4.1 config with an existing cluster", () => {
|
|
||||||
// beforeEach(() => {
|
|
||||||
// const mockOpts = {
|
|
||||||
// 'tmp': {
|
|
||||||
// 'lens-cluster-store.json': JSON.stringify({
|
|
||||||
// __internal__: {
|
|
||||||
// migrations: {
|
|
||||||
// version: "2.0.0-beta.2"
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// cluster1: {
|
|
||||||
// kubeConfig: 'foo',
|
|
||||||
// online: true,
|
|
||||||
// accessible: false,
|
|
||||||
// failureReason: 'user error'
|
|
||||||
// },
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// mockFs(mockOpts)
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// it("migrates to modern format throwing out the state related data", async () => {
|
|
||||||
// const storedClusterData = clusterStore.store.get('clusters')[0]
|
|
||||||
// expect(storedClusterData.hasOwnProperty('online')).toBe(false)
|
|
||||||
// expect(storedClusterData.hasOwnProperty('accessible')).toBe(false)
|
|
||||||
// expect(storedClusterData.hasOwnProperty('failureReason')).toBe(false)
|
|
||||||
// })
|
|
||||||
// })
|
|
||||||
|
|
||||||
// describe("for a pre 2.6.0 config with a cluster that has arrays in auth config", () => {
|
|
||||||
// beforeEach(() => {
|
|
||||||
// const mockOpts = {
|
|
||||||
// 'tmp': {
|
|
||||||
// 'lens-cluster-store.json': JSON.stringify({
|
|
||||||
// __internal__: {
|
|
||||||
// migrations: {
|
|
||||||
// version: "2.4.1"
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// cluster1: {
|
|
||||||
// kubeConfig: "apiVersion: v1\nclusters:\n- cluster:\n server: https://10.211.55.6:8443\n name: minikube\ncontexts:\n- context:\n cluster: minikube\n user: minikube\n name: minikube\ncurrent-context: minikube\nkind: Config\npreferences: {}\nusers:\n- name: minikube\n user:\n client-certificate: /Users/kimmo/.minikube/client.crt\n client-key: /Users/kimmo/.minikube/client.key\n auth-provider:\n config:\n access-token:\n - should be string\n expiry:\n - should be string\n"
|
|
||||||
// },
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// mockFs(mockOpts)
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// it("replaces array format access token and expiry into string", async () => {
|
|
||||||
// const storedClusterData = clusterStore.store.get('clusters')[0]
|
|
||||||
// const kc = yaml.safeLoad(fs.readFileSync(storedClusterData.kubeConfigPath).toString())
|
|
||||||
// expect(kc.users[0].user['auth-provider'].config['access-token']).toBe("should be string")
|
|
||||||
// expect(kc.users[0].user['auth-provider'].config['expiry']).toBe("should be string")
|
|
||||||
// expect(storedClusterData.contextName).toBe("minikube")
|
|
||||||
// })
|
|
||||||
// })
|
|
||||||
|
|
||||||
// describe("for a pre 2.6.0 config with a cluster icon", () => {
|
|
||||||
// beforeEach(() => {
|
|
||||||
// const mockOpts = {
|
|
||||||
// 'tmp': {
|
|
||||||
// 'lens-cluster-store.json': JSON.stringify({
|
|
||||||
// __internal__: {
|
|
||||||
// migrations: {
|
|
||||||
// version: "2.4.1"
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// cluster1: {
|
|
||||||
// kubeConfig: "foo",
|
|
||||||
// icon: "icon path",
|
|
||||||
// preferences: {
|
|
||||||
// terminalCWD: "/tmp"
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// mockFs(mockOpts)
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// it("moves the icon into preferences", async () => {
|
|
||||||
// const storedClusterData = clusterStore.store.get('clusters')[0]
|
|
||||||
// expect(storedClusterData.hasOwnProperty('icon')).toBe(false)
|
|
||||||
// expect(storedClusterData.preferences.hasOwnProperty('icon')).toBe(true)
|
|
||||||
// expect(storedClusterData.preferences.icon).toBe("icon path")
|
|
||||||
// })
|
|
||||||
// })
|
|
||||||
|
|
||||||
// describe("for a pre 2.7.0-beta.0 config without a workspace", () => {
|
|
||||||
// beforeEach(() => {
|
|
||||||
// const mockOpts = {
|
|
||||||
// 'tmp': {
|
|
||||||
// 'lens-cluster-store.json': JSON.stringify({
|
|
||||||
// __internal__: {
|
|
||||||
// migrations: {
|
|
||||||
// version: "2.6.6"
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// cluster1: {
|
|
||||||
// kubeConfig: "foo",
|
|
||||||
// icon: "icon path",
|
|
||||||
// preferences: {
|
|
||||||
// terminalCWD: "/tmp"
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// mockFs(mockOpts)
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// it("adds cluster to default workspace", async () => {
|
|
||||||
// const storedClusterData = clusterStore.store.get("clusters")[0]
|
|
||||||
// expect(storedClusterData.workspace).toBe('default')
|
|
||||||
// })
|
|
||||||
// })
|
|
||||||
@ -1,5 +1,5 @@
|
|||||||
import semver from "semver"
|
import semver from "semver"
|
||||||
import { observable, reaction, toJS } from "mobx";
|
import { action, observable, reaction, toJS } from "mobx";
|
||||||
import { BaseStore } from "./base-store";
|
import { BaseStore } from "./base-store";
|
||||||
import migrations from "../migrations/user-store"
|
import migrations from "../migrations/user-store"
|
||||||
import { getAppVersion } from "./utils/app-version";
|
import { getAppVersion } from "./utils/app-version";
|
||||||
@ -47,17 +47,19 @@ export class UserStore extends BaseStore<UserStoreModel> {
|
|||||||
return semver.gt(getAppVersion(), this.lastSeenAppVersion);
|
return semver.gt(getAppVersion(), this.lastSeenAppVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
saveLastSeenAppVersion() {
|
saveLastSeenAppVersion() {
|
||||||
this.lastSeenAppVersion = getAppVersion();
|
this.lastSeenAppVersion = getAppVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
protected fromStore(data: Partial<UserStoreModel> = {}) {
|
protected fromStore(data: Partial<UserStoreModel> = {}) {
|
||||||
const { lastSeenAppVersion, seenContexts, preferences } = data
|
const { lastSeenAppVersion, seenContexts, preferences } = data
|
||||||
if (lastSeenAppVersion) {
|
if (lastSeenAppVersion) {
|
||||||
this.lastSeenAppVersion = lastSeenAppVersion;
|
this.lastSeenAppVersion = lastSeenAppVersion;
|
||||||
}
|
}
|
||||||
if (seenContexts) {
|
if (seenContexts) {
|
||||||
this.seenContexts = observable.set(seenContexts)
|
this.seenContexts = observable.set(seenContexts);
|
||||||
}
|
}
|
||||||
if (preferences) {
|
if (preferences) {
|
||||||
Object.assign(this.preferences, preferences);
|
Object.assign(this.preferences, preferences);
|
||||||
@ -75,5 +77,4 @@ export class UserStore extends BaseStore<UserStoreModel> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const userStore: UserStore = UserStore.getInstance();
|
export const userStore: UserStore = UserStore.getInstance();
|
||||||
export { userStore }
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { computed, toJS } from "mobx";
|
import { action, computed, toJS } from "mobx";
|
||||||
import { BaseStore } from "./base-store";
|
import { BaseStore } from "./base-store";
|
||||||
import { clusterStore } from "./cluster-store"
|
import { clusterStore } from "./cluster-store"
|
||||||
|
|
||||||
@ -42,6 +42,7 @@ export class WorkspaceStore extends BaseStore<WorkspaceStoreModel> {
|
|||||||
return this.workspaces.findIndex(workspace => workspace.id === id);
|
return this.workspaces.findIndex(workspace => workspace.id === id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
public saveWorkspace(newWorkspace: Workspace) {
|
public saveWorkspace(newWorkspace: Workspace) {
|
||||||
const workspace = this.getById(newWorkspace.id);
|
const workspace = this.getById(newWorkspace.id);
|
||||||
if (workspace) {
|
if (workspace) {
|
||||||
@ -51,6 +52,7 @@ export class WorkspaceStore extends BaseStore<WorkspaceStoreModel> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
public removeWorkspace(workspaceOrId: Workspace | WorkspaceId) {
|
public removeWorkspace(workspaceOrId: Workspace | WorkspaceId) {
|
||||||
const workspace = this.getById(typeof workspaceOrId == "string" ? workspaceOrId : workspaceOrId.id);
|
const workspace = this.getById(typeof workspaceOrId == "string" ? workspaceOrId : workspaceOrId.id);
|
||||||
if (!workspace) return;
|
if (!workspace) return;
|
||||||
@ -60,7 +62,7 @@ export class WorkspaceStore extends BaseStore<WorkspaceStoreModel> {
|
|||||||
const index = this.getIndexById(workspace.id);
|
const index = this.getIndexById(workspace.id);
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
this.data.workspaces.splice(index, 1)
|
this.data.workspaces.splice(index, 1)
|
||||||
clusterStore.removeClustersByWorkspace(workspace.id)
|
clusterStore.removeAllByWorkspaceId(workspace.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import { KubeConfig } from "@kubernetes/client-node"
|
import { KubeConfig } from "@kubernetes/client-node"
|
||||||
import { PromiseIpc } from "electron-promise-ipc"
|
import { PromiseIpc } from "electron-promise-ipc"
|
||||||
import http from "http"
|
import http from "http"
|
||||||
import { Cluster, ClusterBaseInfo } from "./cluster"
|
import { Cluster } from "./cluster"
|
||||||
import { clusterStore } from "../common/cluster-store"
|
import { ClusterModel, clusterStore } from "../common/cluster-store"
|
||||||
import * as k8s from "./k8s"
|
import * as k8s from "./k8s"
|
||||||
import logger from "./logger"
|
import logger from "./logger"
|
||||||
import { LensProxy } from "./proxy"
|
import { LensProxy } from "./proxy"
|
||||||
@ -14,6 +14,8 @@ import filenamify from "filenamify"
|
|||||||
import { v4 as uuid } from "uuid"
|
import { v4 as uuid } from "uuid"
|
||||||
import { apiPrefix } from "../common/vars";
|
import { apiPrefix } from "../common/vars";
|
||||||
|
|
||||||
|
// todo: refactor + reuse parts of cluster-store more heavily
|
||||||
|
|
||||||
export type FeatureInstallRequest = {
|
export type FeatureInstallRequest = {
|
||||||
name: string;
|
name: string;
|
||||||
clusterId: string;
|
clusterId: string;
|
||||||
@ -32,7 +34,10 @@ export type ClusterIconUpload = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class ClusterManager {
|
export class ClusterManager {
|
||||||
public static readonly clusterIconDir = path.join(app.getPath("userData"), "icons")
|
static get clusterIconDir(){
|
||||||
|
return path.join(app.getPath("userData"), "icons")
|
||||||
|
}
|
||||||
|
|
||||||
protected promiseIpc: any
|
protected promiseIpc: any
|
||||||
protected proxyServer: LensProxy
|
protected proxyServer: LensProxy
|
||||||
protected port: number
|
protected port: number
|
||||||
@ -83,7 +88,7 @@ export class ClusterManager {
|
|||||||
return kc;
|
return kc;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async addNewCluster(clusterData: ClusterBaseInfo): Promise<Cluster> {
|
protected async addNewCluster(clusterData: ClusterModel): Promise<Cluster> {
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
const kc = this.loadKubeConfig(clusterData.kubeConfigPath)
|
const kc = this.loadKubeConfig(clusterData.kubeConfigPath)
|
||||||
@ -110,7 +115,7 @@ export class ClusterManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected listenEvents() {
|
protected listenEvents() {
|
||||||
this.promiseIpc.on("addCluster", async (clusterData: ClusterBaseInfo) => {
|
this.promiseIpc.on("addCluster", async (clusterData: ClusterModel) => {
|
||||||
logger.debug(`IPC: addCluster`)
|
logger.debug(`IPC: addCluster`)
|
||||||
const cluster = await this.addNewCluster(clusterData)
|
const cluster = await this.addNewCluster(clusterData)
|
||||||
return {
|
return {
|
||||||
@ -174,10 +179,10 @@ export class ClusterManager {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const clusterIcon = await this.uploadClusterIcon(cluster, fileUpload.name, fileUpload.path)
|
const clusterIcon = await this.uploadClusterIcon(cluster, fileUpload.name, fileUpload.path)
|
||||||
clusterStore.reloadCluster(cluster);
|
// clusterStore.reloadCluster(cluster);
|
||||||
if(!cluster.preferences) cluster.preferences = {};
|
if(!cluster.preferences) cluster.preferences = {};
|
||||||
cluster.preferences.icon = clusterIcon
|
cluster.preferences.icon = clusterIcon
|
||||||
clusterStore.saveCluster(cluster);
|
// clusterStore.saveCluster(cluster);
|
||||||
return {success: true, cluster: cluster.toClusterInfo(), message: ""}
|
return {success: true, cluster: cluster.toClusterInfo(), message: ""}
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
return {success: false, message: error}
|
return {success: false, message: error}
|
||||||
@ -189,7 +194,7 @@ export class ClusterManager {
|
|||||||
const cluster = this.getCluster(id)
|
const cluster = this.getCluster(id)
|
||||||
if (cluster && cluster.preferences) {
|
if (cluster && cluster.preferences) {
|
||||||
cluster.preferences.icon = null;
|
cluster.preferences.icon = null;
|
||||||
clusterStore.saveCluster(cluster)
|
// clusterStore.saveCluster(cluster)
|
||||||
return {success: true, cluster: cluster.toClusterInfo(), message: ""}
|
return {success: true, cluster: cluster.toClusterInfo(), message: ""}
|
||||||
} else {
|
} else {
|
||||||
return {success: false, message: "Cluster not found"}
|
return {success: false, message: "Cluster not found"}
|
||||||
@ -221,7 +226,7 @@ export class ClusterManager {
|
|||||||
logger.debug(`IPC: clusterStored: ${clusterId}`)
|
logger.debug(`IPC: clusterStored: ${clusterId}`)
|
||||||
const cluster = this.clusters.get(clusterId)
|
const cluster = this.clusters.get(clusterId)
|
||||||
if (cluster) {
|
if (cluster) {
|
||||||
clusterStore.reloadCluster(cluster);
|
// clusterStore.reloadCluster(cluster);
|
||||||
cluster.stopServer()
|
cluster.stopServer()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -244,7 +249,7 @@ export class ClusterManager {
|
|||||||
const cluster = this.clusters.get(id)
|
const cluster = this.clusters.get(id)
|
||||||
if (cluster) {
|
if (cluster) {
|
||||||
cluster.stopServer()
|
cluster.stopServer()
|
||||||
clusterStore.removeCluster(cluster.id);
|
clusterStore.removeById(cluster.id);
|
||||||
this.clusters.delete(cluster.id)
|
this.clusters.delete(cluster.id)
|
||||||
}
|
}
|
||||||
return Array.from(this.clusters.values())
|
return Array.from(this.clusters.values())
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { ContextHandler } from "./context-handler"
|
import { ContextHandler } from "./context-handler"
|
||||||
import { FeatureStatusMap } from "./feature"
|
import { FeatureStatusMap } from "./feature"
|
||||||
import * as k8s from "./k8s"
|
import * as k8s from "./k8s"
|
||||||
import { clusterStore } from "../common/cluster-store"
|
import { ClusterId, ClusterModel, ClusterPreferences } from "../common/cluster-store"
|
||||||
import logger from "./logger"
|
import logger from "./logger"
|
||||||
import { AuthorizationV1Api, CoreV1Api, KubeConfig, V1ResourceAttributes } from "@kubernetes/client-node"
|
import { AuthorizationV1Api, CoreV1Api, KubeConfig, V1ResourceAttributes } from "@kubernetes/client-node"
|
||||||
import * as fm from "./feature-manager";
|
import * as fm from "./feature-manager";
|
||||||
@ -10,6 +10,7 @@ import { KubeconfigManager } from "./kubeconfig-manager"
|
|||||||
import { PromiseIpc } from "electron-promise-ipc"
|
import { PromiseIpc } from "electron-promise-ipc"
|
||||||
import request from "request-promise-native"
|
import request from "request-promise-native"
|
||||||
import { apiPrefix } from "../common/vars";
|
import { apiPrefix } from "../common/vars";
|
||||||
|
import type { ClusterInfo } from "../renderer/_vue/store/modules/clusters";
|
||||||
|
|
||||||
enum ClusterStatus {
|
enum ClusterStatus {
|
||||||
AccessGranted = 2,
|
AccessGranted = 2,
|
||||||
@ -17,49 +18,8 @@ enum ClusterStatus {
|
|||||||
Offline = 0
|
Offline = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ClusterBaseInfo {
|
export class Cluster implements ClusterModel {
|
||||||
id: string;
|
public id: ClusterId;
|
||||||
kubeConfig?: string;
|
|
||||||
kubeConfigPath: string;
|
|
||||||
contextName: string;
|
|
||||||
preferences?: ClusterPreferences;
|
|
||||||
port?: number;
|
|
||||||
workspace?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ClusterInfo extends ClusterBaseInfo {
|
|
||||||
url: string;
|
|
||||||
apiUrl: string;
|
|
||||||
online?: boolean;
|
|
||||||
accessible?: boolean;
|
|
||||||
failureReason?: string;
|
|
||||||
nodes?: number;
|
|
||||||
version?: string;
|
|
||||||
distribution?: string;
|
|
||||||
isAdmin?: boolean;
|
|
||||||
features?: FeatureStatusMap;
|
|
||||||
kubeCtl?: Kubectl;
|
|
||||||
contextName: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ClusterPreferences = {
|
|
||||||
terminalCWD?: string;
|
|
||||||
clusterName?: string;
|
|
||||||
prometheus?: {
|
|
||||||
namespace: string;
|
|
||||||
service: string;
|
|
||||||
port: number;
|
|
||||||
prefix: string;
|
|
||||||
};
|
|
||||||
prometheusProvider?: {
|
|
||||||
type: string;
|
|
||||||
};
|
|
||||||
icon?: string;
|
|
||||||
httpsProxy?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Cluster implements ClusterInfo {
|
|
||||||
public id: string;
|
|
||||||
public workspace: string;
|
public workspace: string;
|
||||||
public contextHandler: ContextHandler;
|
public contextHandler: ContextHandler;
|
||||||
public contextName: string;
|
public contextName: string;
|
||||||
@ -84,8 +44,8 @@ export class Cluster implements ClusterInfo {
|
|||||||
|
|
||||||
protected kubeconfigManager: KubeconfigManager;
|
protected kubeconfigManager: KubeconfigManager;
|
||||||
|
|
||||||
constructor(clusterInfo: ClusterBaseInfo) {
|
constructor(jsonModel: ClusterModel) {
|
||||||
if (clusterInfo) Object.assign(this, clusterInfo)
|
if (jsonModel) Object.assign(this, jsonModel)
|
||||||
if (!this.preferences) this.preferences = {}
|
if (!this.preferences) this.preferences = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,7 +89,7 @@ export class Cluster implements ClusterInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async refreshCluster() {
|
public async refreshCluster() {
|
||||||
clusterStore.reloadCluster(this)
|
// clusterStore.reloadCluster(this)
|
||||||
this.contextHandler.setClusterPreferences(this.preferences)
|
this.contextHandler.setClusterPreferences(this.preferences)
|
||||||
|
|
||||||
const connectionStatus = await this.getConnectionStatus()
|
const connectionStatus = await this.getConnectionStatus()
|
||||||
@ -155,7 +115,7 @@ export class Cluster implements ClusterInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public save() {
|
public save() {
|
||||||
clusterStore.saveCluster(this)
|
// clusterStore.saveCluster(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
public toClusterInfo(): ClusterInfo {
|
public toClusterInfo(): ClusterInfo {
|
||||||
|
|||||||
@ -5,9 +5,10 @@ import * as url from "url"
|
|||||||
import logger from "./logger"
|
import logger from "./logger"
|
||||||
import { getFreePort } from "./port"
|
import { getFreePort } from "./port"
|
||||||
import { KubeAuthProxy } from "./kube-auth-proxy"
|
import { KubeAuthProxy } from "./kube-auth-proxy"
|
||||||
import { Cluster, ClusterPreferences } from "./cluster"
|
import { Cluster } from "./cluster"
|
||||||
import { prometheusProviders } from "../common/prometheus-providers"
|
import { prometheusProviders } from "../common/prometheus-providers"
|
||||||
import { PrometheusService, PrometheusProvider } from "./prometheus/provider-registry"
|
import type { PrometheusService, PrometheusProvider } from "./prometheus/provider-registry"
|
||||||
|
import type { ClusterPreferences } from "../common/cluster-store";
|
||||||
|
|
||||||
export class ContextHandler {
|
export class ContextHandler {
|
||||||
public contextName: string
|
public contextName: string
|
||||||
|
|||||||
@ -1,15 +1,9 @@
|
|||||||
// Main process
|
// Main process
|
||||||
|
|
||||||
import "../common/system-ca"
|
import "../common/system-ca"
|
||||||
import { app, dialog, protocol } from "electron"
|
|
||||||
import { isMac, vueAppName, isDevelopment } from "../common/vars";
|
|
||||||
if (isDevelopment) {
|
|
||||||
const appName = 'LensDev';
|
|
||||||
const appData = app.getPath('appData');
|
|
||||||
app.setName(appName);
|
|
||||||
app.setPath('userData', path.join(appData, appName));
|
|
||||||
}
|
|
||||||
import "../common/prometheus-providers"
|
import "../common/prometheus-providers"
|
||||||
|
import { app, dialog, protocol } from "electron"
|
||||||
|
import { isDevelopment, isMac, vueAppName } from "../common/vars";
|
||||||
import { PromiseIpc } from "electron-promise-ipc"
|
import { PromiseIpc } from "electron-promise-ipc"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { format as formatUrl } from "url"
|
import { format as formatUrl } from "url"
|
||||||
@ -17,7 +11,6 @@ import logger from "./logger"
|
|||||||
import initMenu from "./menu"
|
import initMenu from "./menu"
|
||||||
import * as proxy from "./proxy"
|
import * as proxy from "./proxy"
|
||||||
import { WindowManager } from "./window-manager";
|
import { WindowManager } from "./window-manager";
|
||||||
import { clusterStore } from "../common/cluster-store"
|
|
||||||
import { ClusterManager } from "./cluster-manager";
|
import { ClusterManager } from "./cluster-manager";
|
||||||
import AppUpdater from "./app-updater"
|
import AppUpdater from "./app-updater"
|
||||||
import { shellSync } from "./shell-sync"
|
import { shellSync } from "./shell-sync"
|
||||||
@ -25,8 +18,17 @@ import { getFreePort } from "./port"
|
|||||||
import { mangleProxyEnv } from "./proxy-env"
|
import { mangleProxyEnv } from "./proxy-env"
|
||||||
import { findMainWebContents } from "./webcontents"
|
import { findMainWebContents } from "./webcontents"
|
||||||
import { registerStaticProtocol } from "../common/register-static";
|
import { registerStaticProtocol } from "../common/register-static";
|
||||||
|
import { clusterStore } from "../common/cluster-store"
|
||||||
|
import { userStore } from "../common/user-store";
|
||||||
import { tracker } from "../common/tracker";
|
import { tracker } from "../common/tracker";
|
||||||
|
|
||||||
|
if (isDevelopment) {
|
||||||
|
const appName = "LensDev";
|
||||||
|
const appData = app.getPath("appData");
|
||||||
|
app.setName(appName);
|
||||||
|
app.setPath("userData", path.join(appData, appName));
|
||||||
|
}
|
||||||
|
|
||||||
mangleProxyEnv()
|
mangleProxyEnv()
|
||||||
if (app.commandLine.getSwitchValue("proxy-server") !== "") {
|
if (app.commandLine.getSwitchValue("proxy-server") !== "") {
|
||||||
process.env.HTTPS_PROXY = app.commandLine.getSwitchValue("proxy-server")
|
process.env.HTTPS_PROXY = app.commandLine.getSwitchValue("proxy-server")
|
||||||
@ -69,8 +71,14 @@ async function main() {
|
|||||||
app.quit();
|
app.quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// preload required stores
|
||||||
|
await Promise.all([
|
||||||
|
userStore.load(),
|
||||||
|
clusterStore.load(),
|
||||||
|
]);
|
||||||
|
|
||||||
// create cluster manager
|
// create cluster manager
|
||||||
clusterManager = new ClusterManager(clusterStore.getAllClusterObjects(), port)
|
clusterManager = new ClusterManager(clusterStore.clusters, port)
|
||||||
// run proxy
|
// run proxy
|
||||||
try {
|
try {
|
||||||
proxyServer = proxy.listen(port, clusterManager)
|
proxyServer = proxy.listen(port, clusterManager)
|
||||||
|
|||||||
@ -46,14 +46,16 @@ if(isDevelopment) {
|
|||||||
if(process.platform === "win32") bundledPath = `${bundledPath}.exe`
|
if(process.platform === "win32") bundledPath = `${bundledPath}.exe`
|
||||||
|
|
||||||
export class Kubectl {
|
export class Kubectl {
|
||||||
|
|
||||||
public kubectlVersion: string
|
public kubectlVersion: string
|
||||||
protected directory: string
|
protected directory: string
|
||||||
protected url: string
|
protected url: string
|
||||||
protected path: string
|
protected path: string
|
||||||
protected dirname: string
|
protected dirname: string
|
||||||
|
|
||||||
public static readonly kubectlDir = path.join((app || remote.app).getPath("userData"), "binaries", "kubectl")
|
static get kubectlDir(){
|
||||||
|
return path.join((app || remote.app).getPath("userData"), "binaries", "kubectl")
|
||||||
|
}
|
||||||
|
|
||||||
public static readonly bundledKubectlPath = bundledPath
|
public static readonly bundledKubectlPath = bundledPath
|
||||||
public static readonly bundledKubectlVersion: string = bundledVersion
|
public static readonly bundledKubectlVersion: string = bundledVersion
|
||||||
private static bundledInstance: Kubectl;
|
private static bundledInstance: Kubectl;
|
||||||
|
|||||||
@ -1,21 +1,21 @@
|
|||||||
// Move embedded kubeconfig into separate file and add reference to it to cluster settings
|
// Move embedded kubeconfig into separate file and add reference to it to cluster settings
|
||||||
|
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { app } from "electron"
|
import { app, remote } from "electron"
|
||||||
import { migration } from "../migration-wrapper";
|
import { migration } from "../migration-wrapper";
|
||||||
import { ensureDirSync } from "fs-extra"
|
import { ensureDirSync } from "fs-extra"
|
||||||
import { KubeConfig } from "@kubernetes/client-node";
|
import { KubeConfig } from "@kubernetes/client-node";
|
||||||
import { writeEmbeddedKubeConfig } from "../../common/utils/kubeconfig"
|
import { writeEmbeddedKubeConfig } from "../../common/utils/kubeconfig"
|
||||||
import { ClusterBaseInfo } from "../../main/cluster";
|
import { ClusterModel } from "../../common/cluster-store";
|
||||||
|
|
||||||
export default migration({
|
export default migration({
|
||||||
version: "3.6.0-beta.1",
|
version: "3.6.0-beta.1",
|
||||||
run(store, log: (...args: any[]) => void) {
|
run(store, log: (...args: any[]) => void) {
|
||||||
const migratingClusters: ClusterBaseInfo[] = []
|
const migratingClusters: ClusterModel[] = []
|
||||||
|
|
||||||
const kubeConfigBase = path.join(app.getPath("userData"), "kubeconfigs")
|
const kubeConfigBase = path.join((app || remote.app).getPath("userData"), "kubeconfigs")
|
||||||
ensureDirSync(kubeConfigBase)
|
ensureDirSync(kubeConfigBase)
|
||||||
const storedClusters: ClusterBaseInfo[] = store.get("clusters")
|
const storedClusters: ClusterModel[] = store.get("clusters")
|
||||||
if (!storedClusters) return
|
if (!storedClusters) return
|
||||||
|
|
||||||
log("Number of clusters to migrate: ", storedClusters.length)
|
log("Number of clusters to migrate: ", storedClusters.length)
|
||||||
|
|||||||
@ -22,7 +22,6 @@
|
|||||||
import ClusterMenuItem from "@/_vue/components/MainMenu/ClusterMenuItem";
|
import ClusterMenuItem from "@/_vue/components/MainMenu/ClusterMenuItem";
|
||||||
import AddClusterMenuItem from "@/_vue/components/MainMenu/AddClusterMenuItem";
|
import AddClusterMenuItem from "@/_vue/components/MainMenu/AddClusterMenuItem";
|
||||||
import draggable from 'vuedraggable'
|
import draggable from 'vuedraggable'
|
||||||
import { clusterStore } from "../../../../common/cluster-store"
|
|
||||||
import { isMac } from "../../../../common/vars"
|
import { isMac } from "../../../../common/vars"
|
||||||
|
|
||||||
const {remote} = require('electron')
|
const {remote} = require('electron')
|
||||||
@ -47,7 +46,7 @@ export default {
|
|||||||
},
|
},
|
||||||
set: function (clusters) {
|
set: function (clusters) {
|
||||||
this.$store.commit("updateClusters", clusters);
|
this.$store.commit("updateClusters", clusters);
|
||||||
clusterStore.storeClusters(clusters);
|
// clusterStore.storeClusters(clusters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -10,6 +10,8 @@ import App from './App'
|
|||||||
import router from './router'
|
import router from './router'
|
||||||
import store from './store'
|
import store from './store'
|
||||||
import { userStore } from "../../common/user-store"
|
import { userStore } from "../../common/user-store"
|
||||||
|
import { workspaceStore } from "../../common/workspace-store"
|
||||||
|
import { clusterStore } from "../../common/cluster-store"
|
||||||
|
|
||||||
const promiseIpc = new PromiseIpc({maxTimeoutMs: 6000});
|
const promiseIpc = new PromiseIpc({maxTimeoutMs: 6000});
|
||||||
|
|
||||||
@ -29,9 +31,13 @@ Vue.mixin({
|
|||||||
|
|
||||||
// any initialization we want to do for app state
|
// any initialization we want to do for app state
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
await userStore.whenLoaded;
|
await Promise.all([
|
||||||
await store.dispatch('init')
|
userStore.whenLoaded,
|
||||||
|
workspaceStore.whenLoaded,
|
||||||
|
clusterStore.whenLoaded,
|
||||||
|
]);
|
||||||
|
|
||||||
|
await store.dispatch('init')
|
||||||
new Vue({
|
new Vue({
|
||||||
components: {App},
|
components: {App},
|
||||||
store,
|
store,
|
||||||
|
|||||||
@ -1,12 +1,29 @@
|
|||||||
import Vue from "vue"
|
import Vue from "vue"
|
||||||
import { ClusterInfo } from "../../../../main/cluster"
|
|
||||||
import { ActionTree, GetterTree, MutationTree } from "vuex"
|
import { ActionTree, GetterTree, MutationTree } from "vuex"
|
||||||
import { PromiseIpc } from 'electron-promise-ipc'
|
import { PromiseIpc } from 'electron-promise-ipc'
|
||||||
import { clusterStore } from "../../../../common/cluster-store"
|
import { ClusterModel } from "../../../../common/cluster-store"
|
||||||
import { Workspace } from "../../../../common/workspace-store"
|
import { Workspace } from "../../../../common/workspace-store"
|
||||||
import { tracker } from "../../../../common/tracker";
|
import { tracker } from "../../../../common/tracker";
|
||||||
|
import { FeatureStatusMap } from "../../../../main/feature";
|
||||||
|
import { Kubectl } from "../../../../main/kubectl";
|
||||||
|
|
||||||
const promiseIpc = new PromiseIpc({ maxTimeoutMs: 120000 });
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
export interface ClusterInfo extends ClusterModel {
|
||||||
|
url: string;
|
||||||
|
apiUrl: string;
|
||||||
|
online?: boolean;
|
||||||
|
accessible?: boolean;
|
||||||
|
failureReason?: string;
|
||||||
|
nodes?: number;
|
||||||
|
version?: string;
|
||||||
|
distribution?: string;
|
||||||
|
isAdmin?: boolean;
|
||||||
|
features?: FeatureStatusMap;
|
||||||
|
kubeCtl?: Kubectl;
|
||||||
|
contextName: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface LensWebview {
|
export interface LensWebview {
|
||||||
id: string;
|
id: string;
|
||||||
@ -19,6 +36,8 @@ export interface ClusterState {
|
|||||||
clusters: ClusterInfo[];
|
clusters: ClusterInfo[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const promiseIpc = new PromiseIpc({ maxTimeoutMs: 120000 });
|
||||||
|
|
||||||
const state: ClusterState = {
|
const state: ClusterState = {
|
||||||
lenses: [],
|
lenses: [],
|
||||||
clusters: []
|
clusters: []
|
||||||
@ -218,7 +237,7 @@ const actions: ActionTree<ClusterState, any> = {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
storeCluster({ commit }, cluster: ClusterInfo) {
|
storeCluster({ commit }, cluster: ClusterInfo) {
|
||||||
clusterStore.saveCluster(cluster);
|
// clusterStore.saveCluster(cluster);
|
||||||
commit("updateCluster", cluster)
|
commit("updateCluster", cluster)
|
||||||
promiseIpc.send("clusterStored", cluster.id)
|
promiseIpc.send("clusterStored", cluster.id)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user