Skip to content

Commit

Permalink
Release 6.4.6 (#7327)
Browse files Browse the repository at this point in the history
* Copy detected metadata from cluster to catalog cluster (#7316)

* Copy detected metadata from cluster to catalog cluster

Signed-off-by: Juho Heikka <[email protected]>

* Remove duplicate copyright comment

Signed-off-by: Juho Heikka <[email protected]>

* Lint fixes

Signed-off-by: Juho Heikka <[email protected]>

* Typescript fix

Signed-off-by: Juho Heikka <[email protected]>

---------

Signed-off-by: Juho Heikka <[email protected]>

* Release 6.4.6

Signed-off-by: Juho Heikka <[email protected]>

* Fix tests for older getDiForUnitTesting implementation

Signed-off-by: Juho Heikka <[email protected]>

---------

Signed-off-by: Juho Heikka <[email protected]>
  • Loading branch information
jweak authored Mar 9, 2023
1 parent 4df5079 commit 30e72e8
Show file tree
Hide file tree
Showing 11 changed files with 421 additions and 43 deletions.
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"packages": [
"packages/*"
],
"version": "6.4.5",
"version": "6.4.6",
"npmClient": "yarn",
"npmClientArgs": [
"--network-timeout=100000"
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"productName": "",
"description": "Lens Desktop Core",
"homepage": "https://github.com/lensapp/lens",
"version": "6.4.5",
"version": "6.4.6",
"repository": {
"type": "git",
"url": "git+https://github.com/lensapp/lens.git"
Expand Down
8 changes: 8 additions & 0 deletions packages/core/src/common/utils/enum.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/

export function enumKeys<O extends object, K extends keyof O = keyof O>(obj: O): K[] {
return Object.keys(obj).filter(k => Number.isNaN(+k)) as K[];
}
4 changes: 4 additions & 0 deletions packages/core/src/main/cluster/manager.injectable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import loggerInjectable from "../../common/logger.injectable";
import catalogEntityRegistryInjectable from "../catalog/entity-registry.injectable";
import clustersThatAreBeingDeletedInjectable from "./are-being-deleted.injectable";
import { ClusterManager } from "./manager";
import updateEntityMetadataInjectable from "./update-entity-metadata.injectable";
import updateEntitySpecInjectable from "./update-entity-spec.injectable";
import visibleClusterInjectable from "./visible-cluster.injectable";

const clusterManagerInjectable = getInjectable({
Expand All @@ -19,6 +21,8 @@ const clusterManagerInjectable = getInjectable({
clustersThatAreBeingDeleted: di.inject(clustersThatAreBeingDeletedInjectable),
visibleCluster: di.inject(visibleClusterInjectable),
logger: di.inject(loggerInjectable),
updateEntityMetadata: di.inject(updateEntityMetadataInjectable),
updateEntitySpec: di.inject(updateEntitySpecInjectable),
}),
});

Expand Down
43 changes: 6 additions & 37 deletions packages/core/src/main/cluster/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ import type { IObservableValue, ObservableSet } from "mobx";
import { action, makeObservable, observe, reaction, toJS } from "mobx";
import type { Cluster } from "../../common/cluster/cluster";
import { isErrnoException } from "../../common/utils";
import type { KubernetesClusterPrometheusMetrics } from "../../common/catalog-entities/kubernetes-cluster";
import { isKubernetesCluster, KubernetesCluster, LensKubernetesClusterStatus } from "../../common/catalog-entities/kubernetes-cluster";
import { ipcMainOn } from "../../common/ipc";
import { once } from "lodash";
import type { ClusterStore } from "../../common/cluster-store/cluster-store";
import type { ClusterId } from "../../common/cluster-types";
import type { CatalogEntityRegistry } from "../catalog";
import type { Logger } from "../../common/logger";
import type { UpdateEntityMetadata } from "./update-entity-metadata.injectable";
import type { UpdateEntitySpec } from "./update-entity-spec.injectable";

const logPrefix = "[CLUSTER-MANAGER]:";

Expand All @@ -27,6 +28,8 @@ interface Dependencies {
readonly clustersThatAreBeingDeleted: ObservableSet<ClusterId>;
readonly visibleCluster: IObservableValue<ClusterId | null>;
readonly logger: Logger;
readonly updateEntityMetadata: UpdateEntityMetadata;
readonly updateEntitySpec: UpdateEntitySpec;
}

export class ClusterManager {
Expand Down Expand Up @@ -97,42 +100,8 @@ export class ClusterManager {

this.updateEntityStatus(entity, cluster);

entity.metadata.labels = {
...entity.metadata.labels,
...cluster.labels,
};
entity.metadata.distro = cluster.distribution;
entity.metadata.kubeVersion = cluster.version;

if (cluster.preferences?.clusterName) {
/**
* Only set the name if the it is overriden in preferences. If it isn't
* set then the name of the entity has been explicitly set by its source
*/
entity.metadata.name = cluster.preferences.clusterName;
}

entity.spec.metrics ||= { source: "local" };

if (entity.spec.metrics.source === "local") {
const prometheus: KubernetesClusterPrometheusMetrics = entity.spec?.metrics?.prometheus || {};

prometheus.type = cluster.preferences.prometheusProvider?.type;
prometheus.address = cluster.preferences.prometheus;
entity.spec.metrics.prometheus = prometheus;
}

if (cluster.preferences.icon) {
entity.spec.icon ??= {};
entity.spec.icon.src = cluster.preferences.icon;
} else if (cluster.preferences.icon === null) {
/**
* NOTE: only clear the icon if set to `null` by ClusterIconSettings.
* We can then also clear that value too
*/
entity.spec.icon = undefined;
cluster.preferences.icon = undefined;
}
this.dependencies.updateEntityMetadata(entity, cluster);
this.dependencies.updateEntitySpec(entity, cluster);

this.dependencies.catalogEntityRegistry.items.splice(index, 1, entity);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import type { KubernetesCluster } from "../../common/catalog-entities";
import { ClusterMetadataKey } from "../../common/cluster-types";
import type { Cluster } from "../../common/cluster/cluster";
import { enumKeys } from "../../common/utils/enum";

export type UpdateEntityMetadata = (entity: KubernetesCluster, cluster: Cluster) => void;

const updateEntityMetadataInjectable = getInjectable({
id: "update-entity-metadata",

instantiate: (): UpdateEntityMetadata => {
return (entity, cluster) => {
entity.metadata.labels = {
...entity.metadata.labels,
...cluster.labels,
};
entity.metadata.distro = cluster.distribution;
entity.metadata.kubeVersion = cluster.version;

enumKeys(ClusterMetadataKey).forEach((key) => {
const metadataKey = ClusterMetadataKey[key];

entity.metadata[metadataKey] = cluster.metadata[metadataKey];
});

if (cluster.preferences?.clusterName) {
/**
* Only set the name if the it is overriden in preferences. If it isn't
* set then the name of the entity has been explicitly set by its source
*/
entity.metadata.name = cluster.preferences.clusterName;
}
};
},
});

export default updateEntityMetadataInjectable;
160 changes: 160 additions & 0 deletions packages/core/src/main/cluster/update-entity-metadata.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { AppPaths } from "../../common/app-paths/app-path-injection-token";
import appPathsStateInjectable from "../../common/app-paths/app-paths-state.injectable";
import directoryForUserDataInjectable from "../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
import { KubernetesCluster } from "../../common/catalog-entities";
import { ClusterMetadataKey } from "../../common/cluster-types";
import type { Cluster } from "../../common/cluster/cluster";
import { createClusterInjectionToken } from "../../common/cluster/create-cluster-injection-token";
import { getDiForUnitTesting } from "../getDiForUnitTesting";
import type { UpdateEntityMetadata } from "./update-entity-metadata.injectable";
import updateEntityMetadataInjectable from "./update-entity-metadata.injectable";

describe("update-entity-metadata", () => {
let cluster: Cluster;
let entity: KubernetesCluster;
let updateEntityMetadata: UpdateEntityMetadata;
let detectedMetadata: Record<ClusterMetadataKey, any>;

beforeEach(() => {
const di = getDiForUnitTesting({ doGeneralOverrides: true });

di.override(directoryForUserDataInjectable, () => "/some-user-store-path");
di.override(appPathsStateInjectable, () => ({
get: () => ({} as AppPaths),
set: () => {},
}));
const createCluster = di.inject(createClusterInjectionToken);

updateEntityMetadata = di.inject(updateEntityMetadataInjectable);

cluster = createCluster({
id: "some-id",
contextName: "some-context",
kubeConfigPath: "minikube-config.yml",
}, {
clusterServerUrl: "foo",
});

detectedMetadata = {
[ClusterMetadataKey.CLUSTER_ID]: "some-cluster-id",
[ClusterMetadataKey.DISTRIBUTION]: "some-distribution",
[ClusterMetadataKey.VERSION]: "some-version",
[ClusterMetadataKey.LAST_SEEN]: "some-date",
[ClusterMetadataKey.NODES_COUNT]: 42,
[ClusterMetadataKey.PROMETHEUS]: {
"some-parameter": "some-value",
},
};

cluster.metadata = {
...cluster.metadata,
};

entity = new KubernetesCluster({
metadata: {
uid: "some-uid",
name: "some-name",
labels: {},
},
spec: {
kubeconfigContext: "some-context",
kubeconfigPath: "/some/path/to/kubeconfig",
},
status: {
phase: "connecting",
},
});
});

it("given cluster metadata has no some last seen timestamp, does not update entity metadata with last seen timestamp", () => {
updateEntityMetadata(entity, cluster);
expect(entity.metadata.lastSeen).toEqual(undefined);
});

it("given cluster metadata has some last seen timestamp, updates entity metadata with last seen timestamp", () => {
cluster.metadata[ClusterMetadataKey.LAST_SEEN] = detectedMetadata[ClusterMetadataKey.LAST_SEEN];
updateEntityMetadata(entity, cluster);
expect(entity.metadata.lastSeen).toEqual("some-date");
});

it("given cluster metadata has some version, updates entity metadata with version", () => {
cluster.metadata[ClusterMetadataKey.VERSION] = detectedMetadata[ClusterMetadataKey.VERSION];
updateEntityMetadata(entity, cluster);
expect(entity.metadata.version).toEqual("some-version");
});

it("given cluster metadata has nodes count, updates entity metadata with node count", () => {
cluster.metadata[ClusterMetadataKey.NODES_COUNT] = detectedMetadata[ClusterMetadataKey.NODES_COUNT];
updateEntityMetadata(entity, cluster);
expect(entity.metadata.nodes).toEqual(42);
});

it("given cluster metadata has prometheus data, updates entity metadata with prometheus data", () => {
cluster.metadata[ClusterMetadataKey.PROMETHEUS] = detectedMetadata[ClusterMetadataKey.PROMETHEUS];
updateEntityMetadata(entity, cluster);
expect(entity.metadata.prometheus).toEqual({
"some-parameter": "some-value",
});
});

it("given cluster metadata has distribution, updates entity metadata with distribution", () => {
cluster.metadata[ClusterMetadataKey.DISTRIBUTION] = detectedMetadata[ClusterMetadataKey.DISTRIBUTION];
updateEntityMetadata(entity, cluster);
expect(entity.metadata.distribution).toEqual("some-distribution");
});

it("given cluster metadata has cluster id, updates entity metadata with cluster id", () => {
cluster.metadata[ClusterMetadataKey.CLUSTER_ID] = detectedMetadata[ClusterMetadataKey.CLUSTER_ID];
updateEntityMetadata(entity, cluster);
expect(entity.metadata.id).toEqual("some-cluster-id");
});

it("given cluster metadata has no kubernetes version, updates entity metadata with 'unknown' kubernetes version", () => {
updateEntityMetadata(entity, cluster);
expect(entity.metadata.kubeVersion).toEqual("unknown");
});

it("given cluster metadata has kubernetes version, updates entity metadata with kubernetes version", () => {
cluster.metadata.version = "some-kubernetes-version";
updateEntityMetadata(entity, cluster);
expect(entity.metadata.kubeVersion).toEqual("some-kubernetes-version");
});

it("given cluster has labels, updates entity metadata with labels", () => {
cluster.labels = {
"some-label": "some-value",
};
entity.metadata.labels = {
"some-other-label": "some-other-value",
};
updateEntityMetadata(entity, cluster);
expect(entity.metadata.labels).toEqual({
"some-label": "some-value",
"some-other-label": "some-other-value",
});
});

it("given cluster has labels, overwrites entity metadata with cluster labels", () => {
cluster.labels = {
"some-label": "some-cluster-value",
};
entity.metadata.labels = {
"some-label": "some-entity-value",
};
updateEntityMetadata(entity, cluster);
expect(entity.metadata.labels).toEqual({
"some-label": "some-cluster-value",
});
});

it("give cluster preferences has name, updates entity metadata with name", () => {
cluster.preferences.clusterName = "some-cluster-name";

updateEntityMetadata(entity, cluster);
expect(entity.metadata.name).toEqual("some-cluster-name");
});
});
41 changes: 41 additions & 0 deletions packages/core/src/main/cluster/update-entity-spec.injectable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import type { KubernetesCluster, KubernetesClusterPrometheusMetrics } from "../../common/catalog-entities";
import type { Cluster } from "../../common/cluster/cluster";

export type UpdateEntitySpec = (entity: KubernetesCluster, cluster: Cluster) => void;

const updateEntitySpecInjectable = getInjectable({
id: "update-entity-spec",

instantiate: (): UpdateEntitySpec => {
return (entity, cluster) => {
entity.spec.metrics ||= { source: "local" };

if (entity.spec.metrics.source === "local") {
const prometheus: KubernetesClusterPrometheusMetrics = entity.spec?.metrics?.prometheus || {};

prometheus.type = cluster.preferences.prometheusProvider?.type;
prometheus.address = cluster.preferences.prometheus;
entity.spec.metrics.prometheus = prometheus;
}

if (cluster.preferences.icon) {
entity.spec.icon ??= {};
entity.spec.icon.src = cluster.preferences.icon;
} else if (cluster.preferences.icon === null) {
/**
* NOTE: only clear the icon if set to `null` by ClusterIconSettings.
* We can then also clear that value too
*/
entity.spec.icon = undefined;
cluster.preferences.icon = undefined;
}
};
},
});

export default updateEntitySpecInjectable;
Loading

0 comments on commit 30e72e8

Please sign in to comment.