From 6ae42af9ff5de3ddb688d7ab2e9bf58ec34646c1 Mon Sep 17 00:00:00 2001 From: Jari Kolehmainen Date: Wed, 14 Jul 2021 13:39:48 +0300 Subject: [PATCH] wip: catalog helm repos Signed-off-by: Jari Kolehmainen --- .../catalog-entities/helm-repository.ts | 83 +++++++++++++++++++ src/common/catalog-entities/icons/helm.svg | 1 + src/common/catalog-entities/index.ts | 1 + .../catalog-entities/kubernetes-cluster.ts | 2 + src/main/catalog-sources/helm-repositories.ts | 62 ++++++++++++++ src/main/catalog-sources/index.ts | 1 + src/main/helm/helm-repo-manager.ts | 21 ++++- src/main/index.ts | 8 +- src/renderer/initializers/catalog.tsx | 1 + .../initializers/entity-details-registry.ts | 33 ++++++++ src/renderer/initializers/index.ts | 1 + 11 files changed, 209 insertions(+), 5 deletions(-) create mode 100644 src/common/catalog-entities/helm-repository.ts create mode 100644 src/common/catalog-entities/icons/helm.svg create mode 100644 src/main/catalog-sources/helm-repositories.ts create mode 100644 src/renderer/initializers/entity-details-registry.ts diff --git a/src/common/catalog-entities/helm-repository.ts b/src/common/catalog-entities/helm-repository.ts new file mode 100644 index 0000000000..c927b5fe31 --- /dev/null +++ b/src/common/catalog-entities/helm-repository.ts @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import { CatalogCategory, CatalogEntity, CatalogEntityContextMenuContext, CatalogEntityMetadata, CatalogEntityStatus } from "../catalog"; +import { catalogCategoryRegistry } from "../catalog/catalog-category-registry"; + +export interface HelmRepositoryStatus extends CatalogEntityStatus { + phase: "available" | "unavailable"; +} + +export type HelmRepositorySpec = { + url: string; + id?: string; + digest?: string; + cacheFilePath?: string + caFile?: string, + certFile?: string, + insecureSkipTlsVerify?: boolean, + keyFile?: string, + username?: string, + password?: string, + icon?: { + src: string + } +}; + +export class HelmRepository extends CatalogEntity { + public readonly apiVersion = "entity.k8slens.dev/v1alpha1"; + public readonly kind = "HelmRepository"; + + async onRun() { + window.open(this.spec.url, "_blank"); + } + + public onSettingsOpen(): void { + return; + } + + async onContextMenuOpen(context: CatalogEntityContextMenuContext) { + // todo + } +} + +export class HelmRepositoryCategory extends CatalogCategory { + public readonly apiVersion = "catalog.k8slens.dev/v1alpha1"; + public readonly kind = "CatalogCategory"; + public metadata = { + name: "Helm Repositories", + icon: "apps" + }; + public spec = { + group: "entity.k8slens.dev", + versions: [ + { + name: "v1alpha1", + entityClass: HelmRepository + } + ], + names: { + kind: "HelmRepository" + } + }; +} + +catalogCategoryRegistry.add(new HelmRepositoryCategory()); diff --git a/src/common/catalog-entities/icons/helm.svg b/src/common/catalog-entities/icons/helm.svg new file mode 100644 index 0000000000..99c66f850f --- /dev/null +++ b/src/common/catalog-entities/icons/helm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/common/catalog-entities/index.ts b/src/common/catalog-entities/index.ts index ee8a41b552..f53853ad9d 100644 --- a/src/common/catalog-entities/index.ts +++ b/src/common/catalog-entities/index.ts @@ -22,3 +22,4 @@ export * from "./general"; export * from "./kubernetes-cluster"; export * from "./web-link"; +export * from "./helm-repository"; diff --git a/src/common/catalog-entities/kubernetes-cluster.ts b/src/common/catalog-entities/kubernetes-cluster.ts index db948df25a..a39a385611 100644 --- a/src/common/catalog-entities/kubernetes-cluster.ts +++ b/src/common/catalog-entities/kubernetes-cluster.ts @@ -59,6 +59,8 @@ export type KubernetesClusterStatusPhase = "connected" | "connecting" | "disconn export interface KubernetesClusterStatus extends CatalogEntityStatus { phase: KubernetesClusterStatusPhase; + clusterVersion?: string; + clientVersion?: string; } export class KubernetesCluster extends CatalogEntity { diff --git a/src/main/catalog-sources/helm-repositories.ts b/src/main/catalog-sources/helm-repositories.ts new file mode 100644 index 0000000000..03c4e9dd64 --- /dev/null +++ b/src/main/catalog-sources/helm-repositories.ts @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import { observable } from "mobx"; +import { HelmRepository } from "../../common/catalog-entities"; +import { catalogEntityRegistry } from "../catalog"; +import { HelmRepoManager } from "../helm/helm-repo-manager"; + +export function syncHelmRepositories() { + const repos = observable.array([]); + + setTimeout(() => { + HelmRepoManager.loadAvailableRepos().then((helmRepos) => { + repos.replace(helmRepos.map((helmRepo) => { + const labels: Record = {}; + + if (helmRepo.verifiedPublisher) { + labels["verified-publisher"] = "true"; + } + + if (helmRepo.official) { + labels["official"] = "true"; + } + + return new HelmRepository({ + metadata: { + uid: helmRepo.id || helmRepo.url, + name: helmRepo.name, + source: "ArtifactHub.io", + labels + }, + spec: { + ...helmRepo + }, + status: { + phase: "available" + } + }); + })); + }); + }, 5000); + + catalogEntityRegistry.addObservableSource("helm-repositories", repos); +} diff --git a/src/main/catalog-sources/index.ts b/src/main/catalog-sources/index.ts index 70c2d073fb..2e96cd9a28 100644 --- a/src/main/catalog-sources/index.ts +++ b/src/main/catalog-sources/index.ts @@ -22,3 +22,4 @@ export { syncWeblinks } from "./weblinks"; export { KubeconfigSyncManager } from "./kubeconfig-sync"; export { syncGeneralEntities } from "./general"; +export { syncHelmRepositories } from "./helm-repositories"; diff --git a/src/main/helm/helm-repo-manager.ts b/src/main/helm/helm-repo-manager.ts index dc30d92edd..4a2bad0d30 100644 --- a/src/main/helm/helm-repo-manager.ts +++ b/src/main/helm/helm-repo-manager.ts @@ -40,6 +40,8 @@ export interface HelmRepoConfig { export interface HelmRepo { name: string; url: string; + id?: string; + digest?: string; cacheFilePath?: string caFile?: string, certFile?: string, @@ -47,6 +49,9 @@ export interface HelmRepo { keyFile?: string, username?: string, password?: string, + verifiedPublisher?: boolean, + official?: boolean, + lastScanned?: number } export class HelmRepoManager extends Singleton { @@ -64,7 +69,21 @@ export class HelmRepoManager extends Singleton { timeout: 10000, }); - return orderBy(res.body, repo => repo.name); + const repos = res.body.map((repo: any) => { + const helmRepo: HelmRepo = { + id: repo.repository_id, + name: repo.name, + url: repo.url, + digest: repo.digest, + verifiedPublisher: repo.verified_publisher, + official: repo.official, + lastScanned: repo.last_scanned_ts + }; + + return helmRepo; + }); + + return orderBy(repos, repo => repo.name); } private async init() { diff --git a/src/main/index.ts b/src/main/index.ts index 20e1c8d19c..1fe3e46f99 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -48,7 +48,7 @@ import { IpcRendererNavigationEvents } from "../renderer/navigation/events"; import { pushCatalogToRenderer } from "./catalog-pusher"; import { catalogEntityRegistry } from "./catalog"; import { HelmRepoManager } from "./helm/helm-repo-manager"; -import { syncGeneralEntities, syncWeblinks, KubeconfigSyncManager } from "./catalog-sources"; +import { syncGeneralEntities, syncWeblinks, KubeconfigSyncManager, syncHelmRepositories } from "./catalog-sources"; import { handleWsUpgrade } from "./proxy/ws-upgrade"; import configurePackages from "../common/configure-packages"; import { PrometheusProviderRegistry } from "./prometheus"; @@ -152,9 +152,6 @@ app.on("ready", async () => { ExtensionsStore.createInstance(); FilesystemProvisionerStore.createInstance(); WeblinkStore.createInstance(); - - syncWeblinks(); - HelmRepoManager.createInstance(); // create the instance const lensProxy = LensProxy.createInstance( @@ -195,6 +192,9 @@ app.on("ready", async () => { ExtensionLoader.createInstance().init(); extensionDiscovery.init(); + syncHelmRepositories(); + syncWeblinks(); + // Start the app without showing the main window when auto starting on login // (On Windows and Linux, we get a flag. On MacOS, we get special API.) const startHidden = process.argv.includes("--hidden") || (isMac && app.getLoginItemSettings().wasOpenedAsHidden); diff --git a/src/renderer/initializers/catalog.tsx b/src/renderer/initializers/catalog.tsx index b9c56bc0c6..14879f6e9f 100644 --- a/src/renderer/initializers/catalog.tsx +++ b/src/renderer/initializers/catalog.tsx @@ -20,6 +20,7 @@ */ import React from "react"; +import "../../common/catalog-entities/helm-repository"; import { WebLinkCategory } from "../../common/catalog-entities"; import { WeblinkAddCommand } from "../components/catalog-entities/weblink-add-command"; import { CommandOverlay } from "../components/command-palette"; diff --git a/src/renderer/initializers/entity-details-registry.ts b/src/renderer/initializers/entity-details-registry.ts new file mode 100644 index 0000000000..908f6a21bb --- /dev/null +++ b/src/renderer/initializers/entity-details-registry.ts @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import { CatalogEntityDetailRegistry } from "../../extensions/registries"; +import { ConnectionDetails } from "../components/cluster-details/connection-details"; + +export function initEntityDetailsRegistry() { + CatalogEntityDetailRegistry.getInstance().add({ + kind: "KubernetesCluster", + apiVersions: ["entity.k8slens.dev/v1alpha1"], + components: { + Details: ConnectionDetails + } + }); +} diff --git a/src/renderer/initializers/index.ts b/src/renderer/initializers/index.ts index 03f32f1a9d..7aba23d722 100644 --- a/src/renderer/initializers/index.ts +++ b/src/renderer/initializers/index.ts @@ -21,6 +21,7 @@ export * from "./command-registry"; export * from "./entity-settings-registry"; +export * from "./entity-details-registry"; export * from "./kube-object-detail-registry"; export * from "./kube-object-menu-registry"; export * from "./registries";