-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* 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
Showing
11 changed files
with
421 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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[]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 42 additions & 0 deletions
42
packages/core/src/main/cluster/update-entity-metadata.injectable.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
160
packages/core/src/main/cluster/update-entity-metadata.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
41
packages/core/src/main/cluster/update-entity-spec.injectable.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
Oops, something went wrong.