Kubeconfigs as file references (#466)

Signed-off-by: Jussi Nummelin <jussi.nummelin@gmail.com>
Co-authored-by: Lauri Nevala <lauri.nevala@gmail.com>
Co-authored-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
authored and GitHub committed 2020-07-03 16:53:23 +03:00
1 parent c15aa7972c
commit 55687b7d35
23 files changed
+272 -162

No files matched your search

+8 -4
View File
@@ -6,6 +6,7 @@ import * as version260Beta2 from "../migrations/cluster-store/2.6.0-beta.2"
import * as version260Beta3 from "../migrations/cluster-store/2.6.0-beta.3"
import * as version270Beta0 from "../migrations/cluster-store/2.7.0-beta.0"
import * as version270Beta1 from "../migrations/cluster-store/2.7.0-beta.1"
import * as version360Beta1 from "../migrations/cluster-store/3.6.0-beta.1"
import { getAppVersion } from "./utils/app-version";
export class ClusterStore {
@@ -25,7 +26,8 @@ export class ClusterStore {
"2.6.0-beta.2": version260Beta2.migration,
"2.6.0-beta.3": version260Beta3.migration,
"2.7.0-beta.0": version270Beta0.migration,
"2.7.0-beta.1": version270Beta1.migration
"2.7.0-beta.1": version270Beta1.migration,
"3.6.0-beta.1": version360Beta1.migration
}
})
}
@@ -72,7 +74,8 @@ export class ClusterStore {
const index = clusters.findIndex((cl) => cl.id === cluster.id)
const storable = {
id: cluster.id,
kubeConfig: cluster.kubeConfig,
kubeConfigPath: cluster.kubeConfigPath,
contextName: cluster.contextName,
preferences: cluster.preferences,
workspace: cluster.workspace
}
@@ -95,7 +98,8 @@ export class ClusterStore {
public reloadCluster(cluster: ClusterBaseInfo): void {
const storedCluster = this.getCluster(cluster.id);
if (storedCluster) {
cluster.kubeConfig = storedCluster.kubeConfig
cluster.kubeConfigPath = storedCluster.kubeConfigPath
cluster.contextName = storedCluster.contextName
cluster.preferences = storedCluster.preferences
cluster.workspace = storedCluster.workspace
}
@@ -113,4 +117,4 @@ export class ClusterStore {
}
}
export const clusterStore = ClusterStore.getInstance();
export const clusterStore: ClusterStore = ClusterStore.getInstance();
+29 -13
View File
@@ -1,8 +1,19 @@
import mockFs from "mock-fs"
import yaml from "js-yaml"
import * as fs from "fs"
import { ClusterStore } from "./cluster-store";
import { Cluster } from "../main/cluster";
jest.mock("electron", () => {
return {
app: {
getVersion: () => '99.99.99',
getPath: () => 'tmp',
getLocale: () => 'en'
}
}
})
// Console.log needs to be called before fs-mocks, see https://github.com/tschaub/mock-fs/issues/234
console.log("");
@@ -24,7 +35,8 @@ describe("for an empty config", () => {
it("allows to store and retrieve a cluster", async () => {
const cluster = new Cluster({
id: 'foo',
kubeConfig: 'kubeconfig string',
kubeConfigPath: 'kubeconfig',
contextName: "foo",
preferences: {
terminalCWD: '/tmp',
icon: 'path to icon'
@@ -33,7 +45,8 @@ describe("for an empty config", () => {
const clusterStore = ClusterStore.getInstance()
clusterStore.storeCluster(cluster);
const storedCluster = clusterStore.getCluster(cluster.id);
expect(storedCluster.kubeConfig).toBe(cluster.kubeConfig)
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)
@@ -42,7 +55,8 @@ describe("for an empty config", () => {
it("allows to delete a cluster", async () => {
const cluster = new Cluster({
id: 'foofoo',
kubeConfig: 'kubeconfig string',
kubeConfigPath: 'kubeconfig',
contextName: "foo",
preferences: {
terminalCWD: '/tmp'
}
@@ -74,12 +88,12 @@ describe("for a config with existing clusters", () => {
clusters: [
{
id: 'cluster1',
kubeConfig: 'foo',
kubeConfigPath: 'foo',
preferences: { terminalCWD: '/foo' }
},
{
id: 'cluster2',
kubeConfig: 'foo2',
kubeConfigPath: 'foo2',
preferences: { terminalCWD: '/foo2' }
}
]
@@ -96,12 +110,12 @@ describe("for a config with existing clusters", () => {
it("allows to retrieve a cluster", async () => {
const clusterStore = ClusterStore.getInstance()
const storedCluster = clusterStore.getCluster('cluster1')
expect(storedCluster.kubeConfig).toBe('foo')
expect(storedCluster.kubeConfigPath).toBe('foo')
expect(storedCluster.preferences.terminalCWD).toBe('/foo')
expect(storedCluster.id).toBe('cluster1')
const storedCluster2 = clusterStore.getCluster('cluster2')
expect(storedCluster2.kubeConfig).toBe('foo2')
expect(storedCluster2.kubeConfigPath).toBe('foo2')
expect(storedCluster2.preferences.terminalCWD).toBe('/foo2')
expect(storedCluster2.id).toBe('cluster2')
})
@@ -122,7 +136,8 @@ describe("for a config with existing clusters", () => {
it("allows to reload a cluster in-place", async () => {
const cluster = new Cluster({
id: 'cluster1',
kubeConfig: 'kubeconfig string',
kubeConfigPath: 'kubeconfig string',
contextName: "foo",
preferences: {
terminalCWD: '/tmp'
}
@@ -131,7 +146,7 @@ describe("for a config with existing clusters", () => {
const clusterStore = ClusterStore.getInstance()
clusterStore.reloadCluster(cluster)
expect(cluster.kubeConfig).toBe('foo')
expect(cluster.kubeConfigPath).toBe('foo')
expect(cluster.preferences.terminalCWD).toBe('/foo')
expect(cluster.id).toBe('cluster1')
})
@@ -142,11 +157,11 @@ describe("for a config with existing clusters", () => {
expect(storedClusters[0].id).toBe('cluster1')
expect(storedClusters[0].preferences.terminalCWD).toBe('/foo')
expect(storedClusters[0].kubeConfig).toBe('foo')
expect(storedClusters[0].kubeConfigPath).toBe('foo')
expect(storedClusters[1].id).toBe('cluster2')
expect(storedClusters[1].preferences.terminalCWD).toBe('/foo2')
expect(storedClusters[1].kubeConfig).toBe('foo2')
expect(storedClusters[1].kubeConfigPath).toBe('foo2')
})
it("allows storing the clusters in a different order", async () => {
@@ -187,7 +202,7 @@ describe("for a pre 2.0 config with an existing cluster", () => {
it("migrates to modern format with kubeconfig under a key", async () => {
const clusterStore = ClusterStore.getInstance()
const storedCluster = clusterStore.store.get('clusters')[0]
expect(storedCluster.kubeConfig).toBe('kubeconfig content')
expect(storedCluster.kubeConfigPath).toBe(`tmp/kubeconfigs/${storedCluster.id}`)
})
})
@@ -254,9 +269,10 @@ describe("for a pre 2.6.0 config with a cluster that has arrays in auth config",
it("replaces array format access token and expiry into string", async () => {
const clusterStore = ClusterStore.getInstance()
const storedClusterData = clusterStore.store.get('clusters')[0]
const kc = yaml.safeLoad(storedClusterData.kubeConfig)
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")
})
})
+16
View File
@@ -0,0 +1,16 @@
import { app, remote } from "electron"
import { ensureDirSync, writeFileSync } from "fs-extra"
import * as path from "path"
// Writes kubeconfigs to "embedded" store, i.e. .../Lens/kubeconfigs/
export function writeEmbeddedKubeConfig(clusterId: string, kubeConfig: string): string {
// This can be called from main & renderer
const a = (app || remote.app)
const kubeConfigBase = path.join(a.getPath("userData"), "kubeconfigs")
ensureDirSync(kubeConfigBase)
const kubeConfigFile = path.join(kubeConfigBase, clusterId)
writeFileSync(kubeConfigFile, kubeConfig)
return kubeConfigFile
}