From 6b742901f03e510108f69218b691ce639a6ca655 Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Thu, 8 Jul 2021 09:51:05 -0400 Subject: [PATCH] Ignore extensions' clusters when adding to kubeConfigSync - To accomplish this we now ignore all configs that are logiaclly in a child directory of $userData/extension_data. This is done at the path level so as to minimize the number of FS interactions. Signed-off-by: Sebastian Malton --- src/common/__tests__/user-store.test.ts | 39 +++++++++++++++++------ src/migrations/user-store/5.0.3-beta.1.ts | 15 ++++++--- 2 files changed, 41 insertions(+), 13 deletions(-) diff --git a/src/common/__tests__/user-store.test.ts b/src/common/__tests__/user-store.test.ts index 6e5a6433ef..c5a15aec28 100644 --- a/src/common/__tests__/user-store.test.ts +++ b/src/common/__tests__/user-store.test.ts @@ -19,10 +19,6 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { Console } from "console"; - -console = new Console(process.stdout, process.stderr); - import mockFs from "mock-fs"; jest.mock("electron", () => { @@ -37,27 +33,27 @@ jest.mock("electron", () => { }); import { UserStore } from "../user-store"; +import { Console } from "console"; import { SemVer } from "semver"; import electron from "electron"; import { stdout, stderr } from "process"; import { beforeEachWrapped } from "../../../integration/helpers/utils"; import { ThemeStore } from "../../renderer/theme.store"; +import type { ClusterStoreModel } from "../cluster-store"; console = new Console(stdout, stderr); describe("user store tests", () => { describe("for an empty config", () => { beforeEachWrapped(() => { - UserStore.resetInstance(); mockFs({ tmp: { "config.json": "{}", "kube_config": "{}" } }); (UserStore.createInstance() as any).refreshNewContexts = jest.fn(() => Promise.resolve()); - - UserStore.getInstance(); }); afterEach(() => { mockFs.restore(); + UserStore.resetInstance(); }); it("allows setting and retrieving lastSeenAppVersion", () => { @@ -99,14 +95,31 @@ describe("user store tests", () => { describe("migrations", () => { beforeEachWrapped(() => { - UserStore.resetInstance(); mockFs({ "tmp": { "config.json": JSON.stringify({ user: { username: "foobar" }, preferences: { colorTheme: "light" }, lastSeenAppVersion: "1.2.3" - }) + }), + "lens-cluster-store.json": JSON.stringify({ + clusters: [ + { + id: "foobar", + kubeConfigPath: "tmp/extension_data/foo/bar", + }, + { + id: "barfoo", + kubeConfigPath: "some/other/path", + }, + ] + } as ClusterStoreModel), + "extension_data": {}, + }, + "some": { + "other": { + "path": "is file", + } } }); @@ -114,6 +127,7 @@ describe("user store tests", () => { }); afterEach(() => { + UserStore.resetInstance(); mockFs.restore(); }); @@ -122,5 +136,12 @@ describe("user store tests", () => { expect(us.lastSeenAppVersion).toBe("0.0.0"); }); + + it.only("skips clusters for adding to kube-sync with files under extension_data/", () => { + const us = UserStore.getInstance(); + + expect(us.syncKubeconfigEntries.has("tmp/extension_data/foo/bar")).toBe(false); + expect(us.syncKubeconfigEntries.has("some/other/path")).toBe(true); + }); }); }); diff --git a/src/migrations/user-store/5.0.3-beta.1.ts b/src/migrations/user-store/5.0.3-beta.1.ts index 57271e30a4..72f3899627 100644 --- a/src/migrations/user-store/5.0.3-beta.1.ts +++ b/src/migrations/user-store/5.0.3-beta.1.ts @@ -20,7 +20,7 @@ */ import { app } from "electron"; -import { existsSync, readJsonSync } from "fs-extra"; +import { existsSync, readFileSync } from "fs"; import path from "path"; import os from "os"; import { ClusterStore, ClusterStoreModel } from "../../common/cluster-store"; @@ -32,9 +32,11 @@ export default { run(store) { try { const { syncKubeconfigEntries = [], ...preferences }: UserPreferencesModel = store.get("preferences") ?? {}; - const { clusters = [] }: ClusterStoreModel = readJsonSync(path.resolve(app.getPath("userData"), "lens-cluster-store.json")) ?? {}; + const { clusters = [] }: ClusterStoreModel = JSON.parse(readFileSync(path.resolve(app.getPath("userData"), "lens-cluster-store.json"), "utf-8")) ?? {}; + const extensionDataDir = path.resolve(app.getPath("userData"), "extension_data"); const syncPaths = new Set(syncKubeconfigEntries.map(s => s.filePath)); + console.log(extensionDataDir); syncPaths.add(path.join(os.homedir(), ".kube")); for (const cluster of clusters) { @@ -50,6 +52,13 @@ export default { continue; } + const relativeToExtensionData = path.relative(cluster.kubeConfigPath, extensionDataDir); + + if (relativeToExtensionData === "" || relativeToExtensionData.match(/^(\.\.)([\\\/]\.\.)*$/)) { + migrationLog(`Skipping ${cluster.id} because kubeConfigPath is placed under an extension_data folder`); + continue; + } + if (!existsSync(cluster.kubeConfigPath)) { migrationLog(`Skipping ${cluster.id} because kubeConfigPath no longer exists`); continue; @@ -64,8 +73,6 @@ export default { migrationLog("Final list of synced paths", updatedSyncEntries); store.set("preferences", { ...preferences, syncKubeconfigEntries: updatedSyncEntries }); } catch (error) { - console.log(error); - if (error.code !== "ENOENT") { // ignore files being missing throw error;