From 24265f6e0e7223a7c7c6dce2d49e5d7d7850bea2 Mon Sep 17 00:00:00 2001 From: Anatolii Bazko Date: Mon, 1 Aug 2022 13:49:59 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20introduce=20--delete-all=20flag=20to=20?= =?UTF-8?q?delete=20both=20Eclipse=20Che=20and=20Dev=20=E2=80=A6=20(#2196)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: introduce --delete-all flag to delete both Eclipse Che and Dev Workspace related resources Signed-off-by: Anatolii Bazko --- README.md | 4 +- src/commands/server/delete.ts | 121 +++--- src/constants.ts | 2 +- .../devfile-workspace-operator-installer.ts | 364 ------------------ .../devworkspace/olm-installer.ts} | 45 ++- .../devworkspace/operator-installer.ts | 260 +++++++++++++ src/tasks/installers/olm.ts | 2 +- src/tasks/installers/operator.ts | 154 ++++---- yarn.lock | 2 +- 9 files changed, 442 insertions(+), 512 deletions(-) delete mode 100644 src/tasks/component-installers/devfile-workspace-operator-installer.ts rename src/tasks/{installers/olm-dev-workspace-operator.ts => component-installers/devworkspace/olm-installer.ts} (84%) create mode 100644 src/tasks/component-installers/devworkspace/operator-installer.ts diff --git a/README.md b/README.md index b4f1b0cc3..26ff90857 100644 --- a/README.md +++ b/README.md @@ -213,7 +213,7 @@ _See code: [src/commands/server/debug.ts](https://github.com/che-incubator/chect ## `chectl server:delete` -delete any Eclipse Che related resource: Kubernetes/OpenShift +delete any Eclipse Che related resource ``` USAGE @@ -228,6 +228,8 @@ OPTIONS --batch Batch mode. Running a command without end user interaction. + --delete-all Indicates to delete Eclipse Che and Dev Workspace related resources + --delete-namespace Indicates that a Eclipse Che namespace will be deleted as well --skip-kubernetes-health-check Skip Kubernetes health check diff --git a/src/commands/server/delete.ts b/src/commands/server/delete.ts index 7e061f00d..4e40fc216 100644 --- a/src/commands/server/delete.ts +++ b/src/commands/server/delete.ts @@ -14,18 +14,16 @@ import { Command, flags } from '@oclif/command' import { boolean } from '@oclif/command/lib/flags' import { cli } from 'cli-ux' import * as Listrq from 'listr' -import { OLMDevWorkspaceTasks } from '../../tasks/installers/olm-dev-workspace-operator' +import { OLMDevWorkspaceTasks } from '../../tasks/component-installers/devworkspace/olm-installer' import { ChectlContext } from '../../api/context' import { KubeHelper } from '../../api/kube' import { assumeYes, batch, cheNamespace, CHE_TELEMETRY, listrRenderer, skipKubeHealthzCheck } from '../../common-flags' import { DEFAULT_ANALYTIC_HOOK_NAME, - DEFAULT_CHE_NAMESPACE, - WORKSPACE_CONTROLLER_NAMESPACE, - OPENSHIFT_OPERATORS_NAMESPACE, + DEFAULT_CHE_NAMESPACE, OPENSHIFT_OPERATORS_NAMESPACE, WORKSPACE_CONTROLLER_NAMESPACE, } from '../../constants' import { CheTasks } from '../../tasks/che' -import { DevWorkspaceTasks } from '../../tasks/component-installers/devfile-workspace-operator-installer' +import { DevWorkspaceTasks } from '../../tasks/component-installers/devworkspace/operator-installer' import { OLMTasks } from '../../tasks/installers/olm' import { OperatorTasks } from '../../tasks/installers/operator' import { ApiTasks } from '../../tasks/platforms/api' @@ -33,7 +31,7 @@ import { findWorkingNamespace, getCommandSuccessMessage, notifyCommandCompletedS import Listr = require('listr') export default class Delete extends Command { - static description = 'delete any Eclipse Che related resource: Kubernetes/OpenShift' + static description = 'delete any Eclipse Che related resource' static flags: flags.Input = { help: flags.help({ char: 'h' }), @@ -43,6 +41,10 @@ export default class Delete extends Command { description: 'Indicates that a Eclipse Che namespace will be deleted as well', default: false, }), + 'delete-all': boolean({ + description: 'Indicates to delete Eclipse Che and Dev Workspace related resources', + default: false, + }), 'listr-renderer': listrRenderer, 'skip-deletion-check': boolean({ description: 'Skip user confirmation on deletion check', @@ -56,10 +58,9 @@ export default class Delete extends Command { async run() { const { flags } = this.parse(Delete) - const ctx = await ChectlContext.initAndGet(flags, this) - flags.chenamespace = flags.chenamespace || await findWorkingNamespace(flags) || DEFAULT_CHE_NAMESPACE + const ctx = await ChectlContext.initAndGet(flags, this) await this.config.runHook(DEFAULT_ANALYTIC_HOOK_NAME, { command: Delete.id, flags }) if (flags['skip-deletion-check']) { @@ -67,63 +68,75 @@ export default class Delete extends Command { flags.yes = flags['skip-deletion-check'] } - const apiTasks = new ApiTasks() - const kube = new KubeHelper(flags) - const operatorTasks = new OperatorTasks(flags) - const olmTasks = new OLMTasks(flags) - const cheTasks = new CheTasks(flags) - const olmDevWorkspaceTasks = new OLMDevWorkspaceTasks(flags) - const devWorkspaceTasks = new DevWorkspaceTasks(flags) - const tasks = new Listrq([], ctx.listrOptions) + + const apiTasks = new ApiTasks() tasks.add(apiTasks.testApiTasks(flags)) - tasks.add({ - title: 'Delete operator resources', - task: () => new Listr(operatorTasks.getDeleteTasks(flags)), - }) - tasks.add({ - title: 'Delete OLM resources', - task: () => new Listr(olmTasks.getDeleteTasks(flags)), - }) - tasks.add({ - title: 'Wait until all pods are deleted', - task: () => new Listr(cheTasks.getWaitPodsDeletedTasks()), - }) - // Remove devworkspace controller only if there are no more cheClusters after olm/operator tasks tasks.add({ title: 'Uninstall Dev Workspace Operator', - task: async (_ctx: any, task: any) => { - try { - const checlusters = await kube.getAllCheClusters() - if (checlusters.length === 0) { - const tasks = new Listr() - - if (await olmDevWorkspaceTasks.isCustomDevWorkspaceCatalogExists()) { - tasks.add(devWorkspaceTasks.deleteDevOperatorCRsAndCRDsTasks()) - tasks.add(olmDevWorkspaceTasks.deleteResourcesTasks()) - tasks.add(devWorkspaceTasks.deleteDevWorkspaceWebhooksTasks(OPENSHIFT_OPERATORS_NAMESPACE)) - } - - if (!await olmDevWorkspaceTasks.isDevWorkspaceOperatorInstalledViaOLM()) { - tasks.add(devWorkspaceTasks.deleteDevOperatorCRsAndCRDsTasks()) - tasks.add(devWorkspaceTasks.deleteResourcesTasks()) - tasks.add(devWorkspaceTasks.deleteDevWorkspaceWebhooksTasks(WORKSPACE_CONTROLLER_NAMESPACE)) - } - - return tasks + task: async (_ctx: any, _task: any) => { + if (flags['delete-all']) { + const olmDevWorkspaceTasks = new OLMDevWorkspaceTasks(flags) + const devWorkspaceTasks = new DevWorkspaceTasks(flags) + + const tasks = new Listrq([], ctx.listrOptions) + tasks.add({ + title: 'Delete Custom Resources', + task: () => new Listr(devWorkspaceTasks.getDeleteCRsTasks()), + }) + + let devWorkspaceNamespace = WORKSPACE_CONTROLLER_NAMESPACE + if (await olmDevWorkspaceTasks.isDevWorkspaceOperatorInstalledViaOLM()) { + devWorkspaceNamespace = OPENSHIFT_OPERATORS_NAMESPACE + + tasks.add({ + title: 'Delete OLM resources', + task: () => new Listr(olmDevWorkspaceTasks.getDeleteTasks()), + }) } - task.title = `${task.title}...[Skipped: another Eclipse Che instance found]` - } catch (e: any) { - task.title = `${task.title}...[Failed: ${e.message}]` + tasks.add({ + title: 'Delete operator resources', + task: () => new Listr(devWorkspaceTasks.getDeleteTasks(devWorkspaceNamespace)), + }) + + return tasks } }, }) - if (flags['delete-namespace']) { - tasks.add(cheTasks.getDeleteNamespaceTasks(flags)) - } + tasks.add({ + title: 'Uninstall Eclipse Che Operator', + task: async (_ctx: any, _task: any) => { + const operatorTasks = new OperatorTasks(flags) + const olmTasks = new OLMTasks(flags) + const cheTasks = new CheTasks(flags) + + const tasks = new Listrq([], ctx.listrOptions) + tasks.add({ + title: 'Delete Custom Resources', + task: () => new Listr(operatorTasks.getDeleteCRsTasks(flags)), + }) + tasks.add({ + title: 'Delete OLM resources', + task: () => new Listr(olmTasks.getDeleteTasks(flags)), + }) + tasks.add({ + title: 'Delete operator resources', + task: () => new Listr(operatorTasks.getDeleteTasks(flags)), + }) + tasks.add({ + title: 'Wait until all pods are deleted', + task: () => new Listr(cheTasks.getWaitPodsDeletedTasks()), + }) + if (flags['delete-namespace'] || flags['delete-all']) { + tasks.add(cheTasks.getDeleteNamespaceTasks(flags)) + } + + return tasks + }, + }) if (flags.batch || await this.isDeletionConfirmed(flags)) { try { diff --git a/src/constants.ts b/src/constants.ts index ef604c84e..d36dd4369 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -78,7 +78,7 @@ export const CHE_CLUSTER_API_VERSION_V2 = 'v2' export const CHE_CLUSTER_KIND_PLURAL = 'checlusters' export const DEVFILE_WORKSPACE_API_GROUP = 'workspace.devfile.io' -export const DEVFILE_WORKSPACE_API_VERSION = 'v1alpha2' +export const DEVFILE_WORKSPACE_API_VERSION = 'v1alpha1' export const DEVFILE_WORKSPACE_KIND_PLURAL = 'devworkspaces' export const DEVFILE_WORKSPACE_ROUTINGS_API_GROUP = 'controller.devfile.io' diff --git a/src/tasks/component-installers/devfile-workspace-operator-installer.ts b/src/tasks/component-installers/devfile-workspace-operator-installer.ts deleted file mode 100644 index cdf22d6e9..000000000 --- a/src/tasks/component-installers/devfile-workspace-operator-installer.ts +++ /dev/null @@ -1,364 +0,0 @@ -/** - * Copyright (c) 2019-2021 Red Hat, Inc. - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Red Hat, Inc. - initial API and implementation - */ - -import * as Listr from 'listr' -import { ChectlContext } from '../../api/context' -import { CheHelper } from '../../api/che' -import { KubeHelper } from '../../api/kube' -import { OpenShiftHelper } from '../../api/openshift' -import { WORKSPACE_CONTROLLER_NAMESPACE, DEVFILE_WORKSPACE_API_GROUP, DEVFILE_WORKSPACE_API_VERSION, DEVFILE_WORKSPACE_KIND_PLURAL, DEVFILE_WORKSPACE_ROUTINGS_API_GROUP, DEVFILE_WORKSPACE_ROUTINGS_KIND_PLURAL, DEVFILE_WORKSPACE_ROUTINGS_VERSION } from '../../constants' -import { CertManagerTasks } from '../component-installers/cert-manager' - -/** - * Handle setup of the dev workspace operator controller. - */ -export class DevWorkspaceTasks { - protected kubeHelper: KubeHelper - - protected cheHelper: CheHelper - - protected openShiftHelper: OpenShiftHelper - - protected certManagerTask: CertManagerTasks - - protected devWorkspaceServiceAccount = 'devworkspace-controller-serviceaccount' - protected devWorkspaceWebhookServiceAccount = 'devworkspace-webhook-server' - - // DevWorkspace Controller Roles - protected devWorkspaceLeaderElectionRole = 'devworkspace-controller-leader-election-role' - - // DevWorkspace Controller Role Bindings - protected devWorkspaceLeaderElectionRoleBinding = 'devworkspace-controller-leader-election-role' - - // DevWorkspace Controller Cluster Roles - protected devWorkspaceEditWorkspaceClusterRole = 'devworkspace-controller-edit-workspaces' - - protected devWorkspaceProxyClusterRole = 'devworkspace-controller-proxy-role' - - protected devworkspaceClusterRole = 'devworkspace-controller-role' - - protected devWorkspaceMetricsClusterRole = 'devworkspace-controller-metrics-reader' - - protected devWorkspaceViewWorkspaceClusterRole = 'devworkspace-controller-view-workspaces' - - protected devWorkspaceClusterRoleWebhook = 'devworkspace-webhook-server' - - // DevWorkspace Controller ClusterRole Bindings - protected devworkspaceProxyClusterRoleBinding = 'devworkspace-controller-proxy-rolebinding' - - protected devWorkspaceRoleBinding = 'devworkspace-controller-rolebinding' - - protected devWorkspaceWebhookServerClusterRole = 'devworkspace-webhook-server' - - // Deployment names - protected deploymentName = 'devworkspace-controller-manager' - protected deploymentWebhookName = 'devworkspace-webhook-server' - - // Services - protected serviceWebhookName = 'devworkspace-webhookserver' - - // ConfigMap names - protected devWorkspaceConfigMap = 'devworkspace-controller-configmap' - - protected devWorkspaceCertificate = 'devworkspace-controller-serving-cert' - - protected devWorkspaceCertIssuer = 'devworkspace-controller-selfsigned-issuer' - - // DevWorkspace CRD Names - protected devWorkspacesCrdName = 'devworkspaces.workspace.devfile.io' - - protected devWorkspaceTemplatesCrdName = 'devworkspacetemplates.workspace.devfile.io' - - protected workspaceRoutingsCrdName = 'devworkspaceroutings.controller.devfile.io' - - protected devWorkspaceConfigCrdName = 'devworkspaceoperatorconfigs.controller.devfile.io' - - protected webhooksName = 'controller.devfile.io' - - // Web Terminal Operator constants - protected WTOSubscriptionName = 'web-terminal' - - protected WTONamespace = 'openshift-operators' - - constructor(flags: any) { - this.kubeHelper = new KubeHelper(flags) - this.cheHelper = new CheHelper(flags) - this.openShiftHelper = new OpenShiftHelper() - this.certManagerTask = new CertManagerTasks({ flags }) - } - - /** - * Returns list of tasks which uninstall dev-workspace operator. - */ - deleteResourcesTasks(): ReadonlyArray { - return [ - { - title: 'Delete all Dev Workspace Controller deployments', - task: async (_ctx: any, task: any) => { - try { - await this.kubeHelper.deleteAllDeployments(WORKSPACE_CONTROLLER_NAMESPACE) - task.title = `${task.title}...[Ok]` - } catch (e: any) { - task.title = `${task.title}...[Failed: ${e.message}]` - } - }, - }, - { - title: 'Delete all Dev Workspace Controller services', - task: async (_ctx: any, task: any) => { - try { - await this.kubeHelper.deleteAllServices(WORKSPACE_CONTROLLER_NAMESPACE) - task.title = `${task.title}...[Ok]` - } catch (e: any) { - task.title = `${task.title}...[Failed: ${e.message}]` - } - }, - }, - { - title: 'Delete all Dev Workspace Controller routes', - enabled: (ctx: any) => !ctx[ChectlContext.IS_OPENSHIFT], - task: async (_ctx: any, task: any) => { - try { - await this.kubeHelper.deleteAllIngresses(WORKSPACE_CONTROLLER_NAMESPACE) - task.title = `${task.title}...[Ok]` - } catch (e: any) { - task.title = `${task.title}...[Failed: ${e.message}]` - } - }, - }, - { - title: 'Delete all Dev Workspace Controller routes', - enabled: (ctx: any) => ctx[ChectlContext.IS_OPENSHIFT], - task: async (_ctx: any, task: any) => { - try { - await this.openShiftHelper.deleteAllRoutes(WORKSPACE_CONTROLLER_NAMESPACE) - task.title = `${task.title}...[Ok]` - } catch (e: any) { - task.title = `${task.title}...[Failed: ${e.message}]` - } - }, - }, - { - title: 'Delete Dev Workspace Controller configmaps', - task: async (_ctx: any, task: any) => { - try { - await this.kubeHelper.deleteConfigMap(this.devWorkspaceConfigMap, WORKSPACE_CONTROLLER_NAMESPACE) - task.title = `${task.title}...[Ok]` - } catch (e: any) { - task.title = `${task.title}...[Failed: ${e.message}]` - } - }, - }, - { - title: 'Delete Dev Workspace Controller ClusterRoleBindings', - task: async (_ctx: any, task: any) => { - try { - await this.kubeHelper.deleteClusterRoleBinding(this.devWorkspaceRoleBinding) - await this.kubeHelper.deleteClusterRoleBinding(this.devworkspaceProxyClusterRoleBinding) - task.title = `${task.title}...[Ok]` - } catch (e: any) { - task.title = `${task.title}...[Failed: ${e.message}]` - } - }, - }, - { - title: 'Delete Dev Workspace Controller role', - task: async (_ctx: any, task: any) => { - try { - await this.kubeHelper.deleteRole(this.devWorkspaceLeaderElectionRole, WORKSPACE_CONTROLLER_NAMESPACE) - task.title = `${task.title}...[Ok]` - } catch (e: any) { - task.title = `${task.title}...[Failed: ${e.message}]` - } - }, - }, - { - title: 'Delete Dev Workspace Controller roleBinding', - task: async (_ctx: any, task: any) => { - try { - await this.kubeHelper.deleteRoleBinding(this.devWorkspaceLeaderElectionRoleBinding, WORKSPACE_CONTROLLER_NAMESPACE) - task.title = `${task.title}...[Ok]` - } catch (e: any) { - task.title = `${task.title}...[Failed: ${e.message}]` - } - }, - }, - { - title: 'Delete Dev Workspace Controller cluster roles', - task: async (_ctx: any, task: any) => { - try { - await this.kubeHelper.deleteClusterRole(this.devWorkspaceEditWorkspaceClusterRole) - await this.kubeHelper.deleteClusterRole(this.devWorkspaceViewWorkspaceClusterRole) - await this.kubeHelper.deleteClusterRole(this.devWorkspaceProxyClusterRole) - await this.kubeHelper.deleteClusterRole(this.devWorkspaceMetricsClusterRole) - await this.kubeHelper.deleteClusterRole(this.devworkspaceClusterRole) - task.title = `${task.title}...[Ok]` - } catch (e: any) { - task.title = `${task.title}...[Failed: ${e.message}]` - } - }, - }, - { - title: 'Delete Dev Workspace Controller service account', - task: async (_ctx: any, task: any) => { - try { - await this.kubeHelper.deleteServiceAccount(this.devWorkspaceServiceAccount, WORKSPACE_CONTROLLER_NAMESPACE) - task.title = `${task.title}...[Ok]` - } catch (e: any) { - task.title = `${task.title}...[Failed: ${e.message}]` - } - }, - }, - { - title: 'Delete Dev Workspace Controller self-signed certificates', - enabled: async (ctx: any) => !ctx[ChectlContext.IS_OPENSHIFT], - task: async (_ctx: any, task: any) => { - try { - await this.kubeHelper.deleteCertificate(this.devWorkspaceCertificate, WORKSPACE_CONTROLLER_NAMESPACE) - await this.kubeHelper.deleteIssuer(this.devWorkspaceCertIssuer, WORKSPACE_CONTROLLER_NAMESPACE) - task.title = `${task.title}...[Ok]` - } catch (e: any) { - task.title = `${task.title}...[Failed: ${e.message}]` - } - }, - }, - { - title: 'Delete Dev Workspace Operator Namespace', - task: async (_ctx: any, task: any) => { - try { - const namespaceExist = await this.kubeHelper.getNamespace(WORKSPACE_CONTROLLER_NAMESPACE) - if (namespaceExist) { - await this.kubeHelper.deleteNamespace(WORKSPACE_CONTROLLER_NAMESPACE) - } - task.title = `${task.title}...[Ok]` - } catch (e: any) { - task.title = `${task.title}...[Failed: ${e.message}]` - } - }, - }, - ] - } - - deleteDevOperatorCRsAndCRDsTasks(): ReadonlyArray { - return [ - { - title: `Delete ${DEVFILE_WORKSPACE_API_GROUP}/${DEVFILE_WORKSPACE_API_VERSION} resources`, - task: async (_ctx: any, task: any) => { - try { - await this.kubeHelper.deleteAllCustomResources(DEVFILE_WORKSPACE_API_GROUP, DEVFILE_WORKSPACE_API_VERSION, DEVFILE_WORKSPACE_KIND_PLURAL) - task.title = `${task.title}...[Ok]` - } catch (e: any) { - task.title = `${task.title}...[Failed: ${e.message}]` - } - }, - }, - { - title: `Delete ${DEVFILE_WORKSPACE_ROUTINGS_API_GROUP}/${DEVFILE_WORKSPACE_ROUTINGS_VERSION} resources`, - task: async (_ctx: any, task: any) => { - try { - await this.kubeHelper.deleteAllCustomResources(DEVFILE_WORKSPACE_ROUTINGS_API_GROUP, DEVFILE_WORKSPACE_ROUTINGS_VERSION, DEVFILE_WORKSPACE_ROUTINGS_KIND_PLURAL) - task.title = `${task.title}...[Ok]` - } catch (e: any) { - task.title = `${task.title}...[Failed: ${e.message}]` - } - }, - }, - { - title: 'Delete All Dev Workspace CRD', - task: async (_ctx: any, task: any) => { - try { - await this.kubeHelper.deleteCrd(this.devWorkspacesCrdName) - await this.kubeHelper.deleteCrd(this.devWorkspaceTemplatesCrdName) - await this.kubeHelper.deleteCrd(this.workspaceRoutingsCrdName) - await this.kubeHelper.deleteCrd(this.devWorkspaceConfigCrdName) - task.title = `${task.title}...[Ok]` - } catch (e: any) { - task.title = `${task.title}...[Failed: ${e.message}]` - } - }, - }, - ] - } - - deleteDevWorkspaceWebhooksTasks(namespace: string): ReadonlyArray { - return [ - { - title: 'Delete Dev Workspace webhook deployment', - task: async (_ctx: any, task: any) => { - try { - await this.kubeHelper.deleteDeployment(this.deploymentWebhookName, namespace) - task.title = `${task.title}...[Ok]` - } catch (e: any) { - task.title = `${task.title}...[Failed: ${e.message}]` - } - }, - }, - { - title: 'Delete Dev Workspace webhook service', - task: async (_ctx: any, task: any) => { - try { - await this.kubeHelper.deleteService(this.serviceWebhookName, namespace) - task.title = `${task.title}...[Ok]` - } catch (e: any) { - task.title = `${task.title}...[Failed: ${e.message}]` - } - }, - }, - { - title: 'Delete Dev Workspace webhook Cluster RoleBinding', - task: async (_ctx: any, task: any) => { - try { - await this.kubeHelper.deleteClusterRoleBinding(this.devWorkspaceWebhookServerClusterRole) - task.title = `${task.title}...[Ok]` - } catch (e: any) { - task.title = `${task.title}...[Failed: ${e.message}]` - } - }, - }, - { - title: 'Delete Dev Workspace webhook Cluster Role', - task: async (_ctx: any, task: any) => { - try { - await this.kubeHelper.deleteClusterRole(this.devWorkspaceWebhookServerClusterRole) - task.title = `${task.title}...[Ok]` - } catch (e: any) { - task.title = `${task.title}...[Failed: ${e.message}]` - } - }, - }, - { - title: 'Delete Dev Workspace webhooks service account', - task: async (_ctx: any, task: any) => { - try { - await this.kubeHelper.deleteServiceAccount(this.devWorkspaceWebhookServiceAccount, namespace) - task.title = `${task.title}...[Ok]` - } catch (e: any) { - task.title = `${task.title}...[Failed: ${e.message}]` - } - }, - }, - { - title: 'Delete Dev Workspace webhooks configurations', - enabled: ctx => !ctx.isOLMStableDevWorkspaceOperator && !ctx.devWorkspacesPresent, - task: async (_ctx: any, task: any) => { - try { - await this.kubeHelper.deleteMutatingWebhookConfiguration(this.webhooksName) - await this.kubeHelper.deleteValidatingWebhookConfiguration(this.webhooksName) - task.title = `${task.title} ...[Ok]` - } catch (e: any) { - task.title = `${task.title}...[Failed: ${e.message}]` - } - }, - }, - ] - } -} diff --git a/src/tasks/installers/olm-dev-workspace-operator.ts b/src/tasks/component-installers/devworkspace/olm-installer.ts similarity index 84% rename from src/tasks/installers/olm-dev-workspace-operator.ts rename to src/tasks/component-installers/devworkspace/olm-installer.ts index ee43e5aa7..572c010e4 100644 --- a/src/tasks/installers/olm-dev-workspace-operator.ts +++ b/src/tasks/component-installers/devworkspace/olm-installer.ts @@ -10,17 +10,17 @@ * Red Hat, Inc. - initial API and implementation */ -import {DevWorkspaceContextKeys, OLM, OLMInstallationUpdate} from '../../api/context' -import { KubeHelper } from '../../api/kube' -import { CatalogSource, Subscription } from '../../api/types/olm' +import {DevWorkspaceContextKeys, OLM, OLMInstallationUpdate} from '../../../api/context' +import { KubeHelper } from '../../../api/kube' +import { CatalogSource, Subscription } from '../../../api/types/olm' import { DEVWORKSPACE_CSV_PREFIX, DEV_WORKSPACE_NEXT_CATALOG_SOURCE_IMAGE, DEV_WORKSPACE_STABLE_CATALOG_SOURCE_IMAGE, NEXT_CATALOG_SOURCE_DEV_WORKSPACE_OPERATOR, STABLE_CATALOG_SOURCE_DEV_WORKSPACE_OPERATOR, - OPENSHIFT_OPERATORS_NAMESPACE, -} from '../../constants' + OPENSHIFT_OPERATORS_NAMESPACE, OPENSHIFT_MARKET_PLACE_NAMESPACE, OLM_STABLE_CHANNEL_NAME, +} from '../../../constants' import Listr = require('listr') export class OLMDevWorkspaceTasks { @@ -49,13 +49,18 @@ export class OLMDevWorkspaceTasks { title: 'Create Dev Workspace CatalogSource', enabled: ctx => !ctx[DevWorkspaceContextKeys.IS_DEV_WORKSPACE_INSTALLED_VIA_OPERATOR_HUB], task: async (ctx: any, task: any) => { - ctx[DevWorkspaceContextKeys.CATALOG_SOURCE_NAME] = ctx[OLM.CHANNEL] ? STABLE_CATALOG_SOURCE_DEV_WORKSPACE_OPERATOR : NEXT_CATALOG_SOURCE_DEV_WORKSPACE_OPERATOR - const catalogSourceImage = ctx[OLM.CHANNEL] ? DEV_WORKSPACE_STABLE_CATALOG_SOURCE_IMAGE : DEV_WORKSPACE_NEXT_CATALOG_SOURCE_IMAGE + ctx[DevWorkspaceContextKeys.CATALOG_SOURCE_NAME] = ctx[OLM.CHANNEL] === OLM_STABLE_CHANNEL_NAME ? + STABLE_CATALOG_SOURCE_DEV_WORKSPACE_OPERATOR : + NEXT_CATALOG_SOURCE_DEV_WORKSPACE_OPERATOR - if (!await this.kube.isCatalogSourceExists(ctx[DevWorkspaceContextKeys.CATALOG_SOURCE_NAME], OPENSHIFT_OPERATORS_NAMESPACE)) { + const catalogSourceImage = ctx[OLM.CHANNEL] === OLM_STABLE_CHANNEL_NAME ? + DEV_WORKSPACE_STABLE_CATALOG_SOURCE_IMAGE : + DEV_WORKSPACE_NEXT_CATALOG_SOURCE_IMAGE + + if (!await this.kube.isCatalogSourceExists(ctx[DevWorkspaceContextKeys.CATALOG_SOURCE_NAME], OPENSHIFT_MARKET_PLACE_NAMESPACE)) { const catalogSource = this.constructCatalogSource(ctx[DevWorkspaceContextKeys.CATALOG_SOURCE_NAME], catalogSourceImage) - await this.kube.createCatalogSource(catalogSource, OPENSHIFT_OPERATORS_NAMESPACE) - await this.kube.waitCatalogSource(ctx[DevWorkspaceContextKeys.CATALOG_SOURCE_NAME], OPENSHIFT_OPERATORS_NAMESPACE) + await this.kube.createCatalogSource(catalogSource, OPENSHIFT_MARKET_PLACE_NAMESPACE) + await this.kube.waitCatalogSource(ctx[DevWorkspaceContextKeys.CATALOG_SOURCE_NAME], OPENSHIFT_MARKET_PLACE_NAMESPACE) task.title = `${task.title}...[OK]` } else { task.title = `${task.title}...[Exists]` @@ -68,7 +73,7 @@ export class OLMDevWorkspaceTasks { task: async (ctx: any, task: any) => { const subscription = await this.kube.getOperatorSubscription(this.DEV_WORKSPACE_OPERATOR_SUBSCRIPTION, OPENSHIFT_OPERATORS_NAMESPACE) if (!subscription) { - const channel = ctx[OLM.CHANNEL] ? this.STABLE_CHANNEL : this.NEXT_CHANNEL + const channel = ctx[OLM.CHANNEL] === OLM_STABLE_CHANNEL_NAME ? this.STABLE_CHANNEL : this.NEXT_CHANNEL const subscription = this.constructSubscription(this.DEV_WORKSPACE_OPERATOR_SUBSCRIPTION, ctx[DevWorkspaceContextKeys.CATALOG_SOURCE_NAME], channel) await this.kube.createOperatorSubscription(subscription) task.title = `${task.title}...[OK]` @@ -113,10 +118,10 @@ export class OLMDevWorkspaceTasks { ] } - deleteResourcesTasks(): ReadonlyArray { + getDeleteTasks(): ReadonlyArray { return [ { - title: 'Delete Dev Workspace operator subscription', + title: `Delete Subscription ${this.DEV_WORKSPACE_OPERATOR_SUBSCRIPTION}`, task: async (_ctx: any, task: any) => { try { await this.kube.deleteOperatorSubscription(this.DEV_WORKSPACE_OPERATOR_SUBSCRIPTION, OPENSHIFT_OPERATORS_NAMESPACE) @@ -127,7 +132,7 @@ export class OLMDevWorkspaceTasks { }, }, { - title: 'Delete Dev Workspace operator CSV', + title: 'Delete CSV', task: async (_ctx: any, task: any) => { try { const csvs = await this.kube.getCSVWithPrefix(DEVWORKSPACE_CSV_PREFIX, OPENSHIFT_OPERATORS_NAMESPACE) @@ -141,10 +146,10 @@ export class OLMDevWorkspaceTasks { }, }, { - title: 'Delete Dev Workspace operator catalog source for \'next\' channel', + title: `Delete CatalogSource ${NEXT_CATALOG_SOURCE_DEV_WORKSPACE_OPERATOR}`, task: async (_ctx: any, task: any) => { try { - await this.kube.deleteCatalogSource(NEXT_CATALOG_SOURCE_DEV_WORKSPACE_OPERATOR, OPENSHIFT_OPERATORS_NAMESPACE) + await this.kube.deleteCatalogSource(NEXT_CATALOG_SOURCE_DEV_WORKSPACE_OPERATOR, OPENSHIFT_MARKET_PLACE_NAMESPACE) task.title = `${task.title}...[Ok]` } catch (e: any) { task.title = `${task.title}...[Failed: ${e.message}]` @@ -152,10 +157,10 @@ export class OLMDevWorkspaceTasks { }, }, { - title: 'Delete Dev Workspace operator catalog source for \'stable\' channel', + title: `Delete CatalogSource ${STABLE_CATALOG_SOURCE_DEV_WORKSPACE_OPERATOR}`, task: async (_ctx: any, task: any) => { try { - await this.kube.deleteCatalogSource(STABLE_CATALOG_SOURCE_DEV_WORKSPACE_OPERATOR, OPENSHIFT_OPERATORS_NAMESPACE) + await this.kube.deleteCatalogSource(STABLE_CATALOG_SOURCE_DEV_WORKSPACE_OPERATOR, OPENSHIFT_MARKET_PLACE_NAMESPACE) task.title = `${task.title}...[Ok]` } catch (e: any) { task.title = `${task.title}...[Failed: ${e.message}]` @@ -171,7 +176,7 @@ export class OLMDevWorkspaceTasks { kind: 'CatalogSource', metadata: { name, - namespace: OPENSHIFT_OPERATORS_NAMESPACE, + namespace: OPENSHIFT_MARKET_PLACE_NAMESPACE, }, spec: { image, @@ -198,7 +203,7 @@ export class OLMDevWorkspaceTasks { installPlanApproval: OLMInstallationUpdate.AUTO, name: this.OLM_PACKAGE_NAME, source, - sourceNamespace: OPENSHIFT_OPERATORS_NAMESPACE, + sourceNamespace: OPENSHIFT_MARKET_PLACE_NAMESPACE, }, } } diff --git a/src/tasks/component-installers/devworkspace/operator-installer.ts b/src/tasks/component-installers/devworkspace/operator-installer.ts new file mode 100644 index 000000000..5346f0805 --- /dev/null +++ b/src/tasks/component-installers/devworkspace/operator-installer.ts @@ -0,0 +1,260 @@ +/** + * Copyright (c) 2019-2021 Red Hat, Inc. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ + +import * as Listr from 'listr' +import { CheHelper } from '../../../api/che' +import { KubeHelper } from '../../../api/kube' +import { DEVFILE_WORKSPACE_API_GROUP, DEVFILE_WORKSPACE_API_VERSION, DEVFILE_WORKSPACE_KIND_PLURAL, DEVFILE_WORKSPACE_ROUTINGS_API_GROUP, DEVFILE_WORKSPACE_ROUTINGS_KIND_PLURAL, DEVFILE_WORKSPACE_ROUTINGS_VERSION } from '../../../constants' + +/** + * Handle setup of the dev workspace operator controller. + */ +export class DevWorkspaceTasks { + protected kubeHelper: KubeHelper + protected cheHelper: CheHelper + + // ServiceAccounts + protected devWorkspaceSAName = 'devworkspace-controller-serviceaccount' + protected webhookServerSAName = 'devworkspace-webhook-server' + + // Roles and RoleBindings + protected devWorkspaceLeaderElectionRoleName = 'devworkspace-controller-leader-election-role' + protected devWorkspaceLeaderElectionRoleBindingName = 'devworkspace-controller-leader-election-rolebinding' + protected devWorkspaceServiceCertRoleName = 'devworkspace-controller-manager-service-cert' + protected devWorkspaceServiceCertRoleBindingName = 'devworkspace-controller-manager-service-cert' + + // ClusterRoles and ClusterRoleBindings + protected devWorkspaceEditWorkspaceClusterRoleName = 'devworkspace-controller-edit-workspaces' + protected devWorkspaceProxyClusterRoleName = 'devworkspace-controller-proxy-role' + protected devWorkspaceClusterRoleName = 'devworkspace-controller-role' + protected devWorkspaceMetricsReaderClusterRoleName = 'devworkspace-controller-metrics-reader' + protected devWorkspaceViewWorkspaceClusterRoleName = 'devworkspace-controller-view-workspaces' + protected devWorkspaceProxyClusterRoleBindingName = 'devworkspace-controller-proxy-rolebinding' + protected devWorkspaceClusterRoleBindingName = 'devworkspace-controller-rolebinding' + protected webhookServerClusterRoleName = 'devworkspace-webhook-server' + protected webhookServerClusterRoleBindingName = 'devworkspace-webhook-server' + + // Issuer + protected devWorkspaceCertificateName = 'devworkspace-controller-serving-cert' + protected devWorkspaceIssuerName = 'devworkspace-controller-selfsigned-issuer' + + // Secrets + protected webhookCertSecretName = 'devworkspace-operator-webhook-cert' + protected devWorkspaceCertSecretName = 'devworkspace-controller-manager-service-cert' + protected webhookTlsSecretName = 'devworkspace-webhookserver-tls' + + // DevWorkspace CRD Names + protected devWorkspacesCrdName = 'devworkspaces.workspace.devfile.io' + protected devWorkspaceTemplatesCrdName = 'devworkspacetemplates.workspace.devfile.io' + protected devWorkspaceRoutingsCrdName = 'devworkspaceroutings.controller.devfile.io' + protected devWorkspaceConfigCrdName = 'devworkspaceoperatorconfigs.controller.devfile.io' + + // Deployments + protected webhookServerDeploymentName = 'devworkspace-webhook-server' + protected devWorkspaceControllerManagerDeploymentName = 'devworkspace-controller-manager' + + // Services + protected webhookServiceName = 'devworkspace-webhookserver' + protected devWorkspaceMetricsServiceName = 'devworkspace-controller-metrics' + protected devWorkspaceManagerServiceName = 'devworkspace-controller-manager-service' + + // DevWorkspace webhook + protected webhookConfigurationName = 'controller.devfile.io' + + constructor(flags: any) { + this.kubeHelper = new KubeHelper(flags) + this.cheHelper = new CheHelper(flags) + } + + getDeleteTasks(devWorkspaceNamespace: string): ReadonlyArray { + return [ + { + title: `Delete WebhookConfigurations ${this.webhookConfigurationName}`, + task: async (_ctx: any, task: any) => { + try { + await this.kubeHelper.deleteMutatingWebhookConfiguration(this.webhookConfigurationName) + await this.kubeHelper.deleteValidatingWebhookConfiguration(this.webhookConfigurationName) + task.title = `${task.title} ...[Ok]` + } catch (e: any) { + task.title = `${task.title}...[Failed: ${e.message}]` + } + }, + }, + { + title: 'Delete CRDs', + task: async (_ctx: any, task: any) => { + try { + await this.kubeHelper.deleteCrd(this.devWorkspacesCrdName) + await this.kubeHelper.deleteCrd(this.devWorkspaceTemplatesCrdName) + await this.kubeHelper.deleteCrd(this.devWorkspaceRoutingsCrdName) + await this.kubeHelper.deleteCrd(this.devWorkspaceConfigCrdName) + task.title = `${task.title}...[Ok]` + } catch (e: any) { + task.title = `${task.title}...[Failed: ${e.message}]` + } + }, + }, + { + title: 'Delete Deployments', + task: async (_ctx: any, task: any) => { + try { + await this.kubeHelper.deleteDeployment(this.devWorkspaceControllerManagerDeploymentName, devWorkspaceNamespace) + await this.kubeHelper.deleteDeployment(this.webhookServerDeploymentName, devWorkspaceNamespace) + task.title = `${task.title}...[Ok]` + } catch (e: any) { + task.title = `${task.title}...[Failed: ${e.message}]` + } + }, + }, + { + title: 'Delete Services', + task: async (_ctx: any, task: any) => { + try { + await this.kubeHelper.deleteService(this.webhookServiceName, devWorkspaceNamespace) + await this.kubeHelper.deleteService(this.devWorkspaceManagerServiceName, devWorkspaceNamespace) + await this.kubeHelper.deleteService(this.devWorkspaceMetricsServiceName, devWorkspaceNamespace) + task.title = `${task.title}...[Ok]` + } catch (e: any) { + task.title = `${task.title}...[Failed: ${e.message}]` + } + }, + }, + { + title: 'Delete Secrets', + task: async (_ctx: any, task: any) => { + try { + await this.kubeHelper.deleteSecret(this.webhookCertSecretName, devWorkspaceNamespace) + await this.kubeHelper.deleteSecret(this.devWorkspaceCertSecretName, devWorkspaceNamespace) + await this.kubeHelper.deleteSecret(this.webhookTlsSecretName, devWorkspaceNamespace) + task.title = `${task.title}...[Ok]` + } catch (e: any) { + task.title = `${task.title}...[Failed: ${e.message}]` + } + }, + }, + { + title: 'Delete RoleBindings', + task: async (_ctx: any, task: any) => { + try { + await this.kubeHelper.deleteRoleBinding(this.devWorkspaceLeaderElectionRoleBindingName, devWorkspaceNamespace) + await this.kubeHelper.deleteRoleBinding(this.devWorkspaceServiceCertRoleName, devWorkspaceNamespace) + task.title = `${task.title}...[Ok]` + } catch (e: any) { + task.title = `${task.title}...[Failed: ${e.message}]` + } + }, + }, + { + title: 'Delete Roles', + task: async (_ctx: any, task: any) => { + try { + await this.kubeHelper.deleteRole(this.devWorkspaceLeaderElectionRoleName, devWorkspaceNamespace) + await this.kubeHelper.deleteRoleBinding(this.devWorkspaceServiceCertRoleBindingName, devWorkspaceNamespace) + task.title = `${task.title}...[Ok]` + } catch (e: any) { + task.title = `${task.title}...[Failed: ${e.message}]` + } + }, + }, + { + title: 'Delete ClusterRoleBindings', + task: async (_ctx: any, task: any) => { + try { + await this.kubeHelper.deleteClusterRoleBinding(this.devWorkspaceClusterRoleBindingName) + await this.kubeHelper.deleteClusterRoleBinding(this.devWorkspaceProxyClusterRoleBindingName) + await this.kubeHelper.deleteClusterRoleBinding(this.webhookServerClusterRoleBindingName) + task.title = `${task.title}...[Ok]` + } catch (e: any) { + task.title = `${task.title}...[Failed: ${e.message}]` + } + }, + }, + { + title: 'Delete ClusterRoles', + task: async (_ctx: any, task: any) => { + try { + await this.kubeHelper.deleteClusterRole(this.devWorkspaceEditWorkspaceClusterRoleName) + await this.kubeHelper.deleteClusterRole(this.devWorkspaceViewWorkspaceClusterRoleName) + await this.kubeHelper.deleteClusterRole(this.devWorkspaceProxyClusterRoleName) + await this.kubeHelper.deleteClusterRole(this.devWorkspaceMetricsReaderClusterRoleName) + await this.kubeHelper.deleteClusterRole(this.devWorkspaceClusterRoleName) + await this.kubeHelper.deleteClusterRole(this.webhookServerClusterRoleName) + task.title = `${task.title}...[Ok]` + } catch (e: any) { + task.title = `${task.title}...[Failed: ${e.message}]` + } + }, + }, + { + title: 'Delete ServiceAccounts', + task: async (_ctx: any, task: any) => { + try { + await this.kubeHelper.deleteServiceAccount(this.devWorkspaceSAName, devWorkspaceNamespace) + await this.kubeHelper.deleteServiceAccount(this.webhookServerSAName, devWorkspaceNamespace) + task.title = `${task.title}...[Ok]` + } catch (e: any) { + task.title = `${task.title}...[Failed: ${e.message}]` + } + }, + }, + { + title: `Delete Issuer ${this.devWorkspaceIssuerName}`, + task: async (_ctx: any, task: any) => { + try { + await this.kubeHelper.deleteIssuer(this.devWorkspaceIssuerName, devWorkspaceNamespace) + task.title = `${task.title}...[Ok]` + } catch (e: any) { + task.title = `${task.title}...[Failed: ${e.message}]` + } + }, + }, + { + title: `Delete Certificate ${this.devWorkspaceCertificateName}`, + task: async (_ctx: any, task: any) => { + try { + await this.kubeHelper.deleteCertificate(this.devWorkspaceCertificateName, devWorkspaceNamespace) + task.title = `${task.title}...[Ok]` + } catch (e: any) { + task.title = `${task.title}...[Failed: ${e.message}]` + } + }, + }, + ] + } + + getDeleteCRsTasks(): ReadonlyArray { + return [ + { + title: `Delete ${DEVFILE_WORKSPACE_API_GROUP}/${DEVFILE_WORKSPACE_API_VERSION} resources`, + task: async (_ctx: any, task: any) => { + try { + await this.kubeHelper.deleteAllCustomResources(DEVFILE_WORKSPACE_API_GROUP, DEVFILE_WORKSPACE_API_VERSION, DEVFILE_WORKSPACE_KIND_PLURAL) + task.title = `${task.title}...[Ok]` + } catch (e: any) { + task.title = `${task.title}...[Failed: ${e.message}]` + } + }, + }, + { + title: `Delete ${DEVFILE_WORKSPACE_ROUTINGS_API_GROUP}/${DEVFILE_WORKSPACE_ROUTINGS_VERSION} resources`, + task: async (_ctx: any, task: any) => { + try { + await this.kubeHelper.deleteAllCustomResources(DEVFILE_WORKSPACE_ROUTINGS_API_GROUP, DEVFILE_WORKSPACE_ROUTINGS_VERSION, DEVFILE_WORKSPACE_ROUTINGS_KIND_PLURAL) + task.title = `${task.title}...[Ok]` + } catch (e: any) { + task.title = `${task.title}...[Failed: ${e.message}]` + } + }, + }, + ] + } +} diff --git a/src/tasks/installers/olm.ts b/src/tasks/installers/olm.ts index efc5c4b44..24208f67f 100644 --- a/src/tasks/installers/olm.ts +++ b/src/tasks/installers/olm.ts @@ -36,7 +36,7 @@ import { } from '../../constants' import {getEmbeddedTemplatesDirectory, getProjectName, isCheClusterAPIV2} from '../../util' import { createEclipseCheClusterTask, patchingEclipseCheCluster } from './common-tasks' -import { OLMDevWorkspaceTasks } from './olm-dev-workspace-operator' +import { OLMDevWorkspaceTasks } from '../component-installers/devworkspace/olm-installer' import Listr = require('listr') import { V1Role, V1RoleBinding } from '@kubernetes/client-node' import {merge} from 'lodash' diff --git a/src/tasks/installers/operator.ts b/src/tasks/installers/operator.ts index baf5bd4ea..a6e28bb45 100644 --- a/src/tasks/installers/operator.ts +++ b/src/tasks/installers/operator.ts @@ -27,7 +27,13 @@ import * as path from 'path' import * as yaml from 'js-yaml' import {ChectlContext} from '../../api/context' import {KubeHelper} from '../../api/kube' -import {CHE_CLUSTER_CRD, CHE_OPERATOR_SELECTOR, OPERATOR_DEPLOYMENT_NAME} from '../../constants' +import { + CHE_CLUSTER_API_GROUP, + CHE_CLUSTER_API_VERSION_V2, + CHE_CLUSTER_CRD, + CHE_OPERATOR_SELECTOR, + OPERATOR_DEPLOYMENT_NAME, +} from '../../constants' import {getImageNameAndTag, isCheClusterAPIV1, safeLoadFromYamlFile} from '../../util' import {KubeTasks} from '../kube' import {createEclipseCheClusterTask, patchingEclipseCheCluster} from './common-tasks' @@ -40,7 +46,6 @@ export class OperatorTasks { private static readonly CERTIFICATE = 'che-operator-serving-cert' private static readonly ISSUER = 'che-operator-selfsigned-issuer' private static readonly SERVICE_ACCOUNT = 'che-operator' - private static readonly DEVWORKSPACE_PREFIX = 'devworkspace-che' private static readonly CONSOLELINK = 'che' protected kh: KubeHelper @@ -513,73 +518,11 @@ export class OperatorTasks { /** * Returns list of tasks which remove Eclipse Che operator related resources */ - getDeleteTasks(flags: any): ReadonlyArray { + getDeleteCRsTasks(flags: any): ReadonlyArray { const kh = new KubeHelper(flags) return [ { - title: `Delete ValidatingWebhookConfiguration ${OperatorTasks.VALIDATING_WEBHOOK}`, - task: async (_ctx: any, task: any) => { - try { - await kh.deleteValidatingWebhookConfiguration(OperatorTasks.VALIDATING_WEBHOOK) - task.title = `${task.title}...[Ok]` - } catch (e: any) { - task.title = `${task.title}...[Failed: ${e.message}]` - } - }, - }, - { - title: `Delete Issuer ${OperatorTasks.ISSUER}`, - task: async (_ctx: any, task: any) => { - try { - await kh.deleteIssuer(OperatorTasks.ISSUER, this.flags.chenamespace) - task.title = `${task.title}...[Ok]` - } catch (e: any) { - task.title = `${task.title}...[Failed: ${e.message}]` - } - }, - }, - { - title: `Delete Certificate ${OperatorTasks.CERTIFICATE}`, - task: async (_ctx: any, task: any) => { - try { - await kh.deleteCertificate(OperatorTasks.CERTIFICATE, this.flags.chenamespace) - task.title = `${task.title}...[Ok]` - } catch (e: any) { - task.title = `${task.title}...[Failed: ${e.message}]` - } - }, - }, - { - title: 'Delete OAuthClient', - enabled: (ctx: any) => ctx[ChectlContext.IS_OPENSHIFT], - task: async (_ctx: any, task: any) => { - try { - const checluster = await kh.getCheClusterV1(flags.chenamespace) - if (checluster) { - if (isCheClusterAPIV1(checluster)) { - if (checluster?.spec?.auth?.oAuthClientName) { - await kh.deleteOAuthClient(checluster.spec.auth.oAuthClientName) - } - } else { - if (checluster?.spec?.networking?.auth?.oAuthClientName) { - await kh.deleteOAuthClient(checluster.spec.networking.auth.oAuthClientName) - } - } - } - - const oauthClients = await kh.listOAuthClientBySelector('app.kubernetes.io/part-of=che.eclipse.org') - for (const oauthClient of oauthClients) { - await kh.deleteOAuthClient(oauthClient.metadata.name) - } - - task.title = `${task.title}...[Ok]` - } catch (e: any) { - task.title = `${task.title}...[Failed: ${e.message}]` - } - }, - }, - { - title: `Delete the Custom Resource of type ${CHE_CLUSTER_CRD}`, + title: `Delete ${CHE_CLUSTER_API_GROUP}/${CHE_CLUSTER_API_VERSION_V2} resources`, task: async (_ctx: any, task: any) => { try { await kh.deleteAllCheClusters(flags.chenamespace) @@ -620,6 +563,26 @@ export class OperatorTasks { } }, }, + ] + } + + /** + * Returns list of tasks which remove Eclipse Che operator related resources + */ + getDeleteTasks(flags: any): ReadonlyArray { + const kh = new KubeHelper(flags) + return [ + { + title: `Delete ValidatingWebhookConfiguration ${OperatorTasks.VALIDATING_WEBHOOK}`, + task: async (_ctx: any, task: any) => { + try { + await kh.deleteValidatingWebhookConfiguration(OperatorTasks.VALIDATING_WEBHOOK) + task.title = `${task.title}...[Ok]` + } catch (e: any) { + task.title = `${task.title}...[Failed: ${e.message}]` + } + }, + }, { title: 'Delete CRDs', task: async (_ctx: any, task: any) => { @@ -729,16 +692,16 @@ export class OperatorTasks { const clusterRoleBindings = await kh.listClusterRoleBindings() for (const clusterRoleBinding of clusterRoleBindings.items) { - const name = clusterRoleBinding.metadata && clusterRoleBinding.metadata.name || '' - if (name.startsWith(flags.chenamespace) || name.startsWith(OperatorTasks.DEVWORKSPACE_PREFIX)) { + const name = clusterRoleBinding.metadata?.name + if (name && name.startsWith(flags.chenamespace)) { await kh.deleteClusterRoleBinding(name) } } const clusterRoles = await kh.listClusterRoles() for (const clusterRole of clusterRoles.items) { - const name = clusterRole.metadata && clusterRole.metadata.name || '' - if (name.startsWith(flags.chenamespace) || name.startsWith(OperatorTasks.DEVWORKSPACE_PREFIX)) { + const name = clusterRole.metadata?.name + if (name && name.startsWith(flags.chenamespace)) { await kh.deleteClusterRole(name) } } @@ -806,6 +769,57 @@ export class OperatorTasks { } }, }, + { + title: `Delete Issuer ${OperatorTasks.ISSUER}`, + task: async (_ctx: any, task: any) => { + try { + await kh.deleteIssuer(OperatorTasks.ISSUER, this.flags.chenamespace) + task.title = `${task.title}...[Ok]` + } catch (e: any) { + task.title = `${task.title}...[Failed: ${e.message}]` + } + }, + }, + { + title: `Delete Certificate ${OperatorTasks.CERTIFICATE}`, + task: async (_ctx: any, task: any) => { + try { + await kh.deleteCertificate(OperatorTasks.CERTIFICATE, this.flags.chenamespace) + task.title = `${task.title}...[Ok]` + } catch (e: any) { + task.title = `${task.title}...[Failed: ${e.message}]` + } + }, + }, + { + title: 'Delete OAuthClient', + enabled: (ctx: any) => ctx[ChectlContext.IS_OPENSHIFT], + task: async (_ctx: any, task: any) => { + try { + const checluster = await kh.getCheClusterV1(flags.chenamespace) + if (checluster) { + if (isCheClusterAPIV1(checluster)) { + if (checluster?.spec?.auth?.oAuthClientName) { + await kh.deleteOAuthClient(checluster.spec.auth.oAuthClientName) + } + } else { + if (checluster?.spec?.networking?.auth?.oAuthClientName) { + await kh.deleteOAuthClient(checluster.spec.networking.auth.oAuthClientName) + } + } + } + + const oauthClients = await kh.listOAuthClientBySelector('app.kubernetes.io/part-of=che.eclipse.org') + for (const oauthClient of oauthClients) { + await kh.deleteOAuthClient(oauthClient.metadata.name) + } + + task.title = `${task.title}...[Ok]` + } catch (e: any) { + task.title = `${task.title}...[Failed: ${e.message}]` + } + }, + }, { title: 'Delete PVCs', task: async (_ctx: any, task: any) => { diff --git a/yarn.lock b/yarn.lock index 7bc94b5ba..2078139c6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2517,7 +2517,7 @@ ecc-jsbn@~0.1.1: "eclipse-che-operator@https://github.com/eclipse-che/che-operator#main": version "0.0.0" - resolved "https://github.com/eclipse-che/che-operator#d6f5dbd7aecf36eef1ea200c8ae78694e757ca26" + resolved "https://github.com/eclipse-che/che-operator#8117846f13642512374660a2ba8d0c4e898fb1a4" editorconfig@^0.15.0: version "0.15.3"