diff --git a/cypress/e2e/po/edit/provisioning.cattle.io.cluster/create/cluster-create.po.ts b/cypress/e2e/po/edit/provisioning.cattle.io.cluster/create/cluster-create.po.ts index 53b782381cb..4be22a79773 100644 --- a/cypress/e2e/po/edit/provisioning.cattle.io.cluster/create/cluster-create.po.ts +++ b/cypress/e2e/po/edit/provisioning.cattle.io.cluster/create/cluster-create.po.ts @@ -42,6 +42,10 @@ export default class ClusterManagerCreatePagePo extends ClusterManagerCreateImpo return this.self().contains('.grid .name', name, { timeout: 10000 }).should(assertion); } + gridElementGroupTitles() { + return this.self().find('.subtypes-container > div > h4'); + } + selectKubeProvider(index: number) { return this.resourceDetail().cruResource().selectSubType(0, index).click(); } diff --git a/cypress/e2e/tests/pages/manager/cluster-manager.spec.ts b/cypress/e2e/tests/pages/manager/cluster-manager.spec.ts index c54c3c24cdb..10dd81531d9 100644 --- a/cypress/e2e/tests/pages/manager/cluster-manager.spec.ts +++ b/cypress/e2e/tests/pages/manager/cluster-manager.spec.ts @@ -25,6 +25,8 @@ import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po'; import TabbedPo from '@/cypress/e2e/po/components/tabbed.po'; import LoadingPo from '@/cypress/e2e/po/components/loading.po'; import { EXTRA_LONG_TIMEOUT_OPT, MEDIUM_TIMEOUT_OPT } from '@/cypress/support/utils/timeouts'; +import KontainerDriversPagePo from '@/cypress/e2e/po/pages/cluster-manager/kontainer-drivers.po'; +import DeactivateDriverDialogPo from '@/cypress/e2e/po/prompts/deactivateDriverDialog.po'; // At some point these will come from somewhere central, then we can make tools to remove resources from this or all runs const runTimestamp = +new Date(); @@ -88,6 +90,68 @@ describe('Cluster Manager', { testIsolation: 'off', tags: ['@manager', '@adminUs }); }); + it('deactivating a kontainer driver should hide its card from the cluster creation page', () => { + const driversPage = new KontainerDriversPagePo(); + const clusterCreatePage = new ClusterManagerCreatePagePo(); + + // deactivate the AKS driver + KontainerDriversPagePo.navTo(); + driversPage.waitForPage(); + driversPage.list().actionMenu('Azure AKS').getMenuItem('Deactivate').click(); + const deactivateDialog = new DeactivateDriverDialogPo(); + + deactivateDialog.deactivate(); + + // verify that the AKS card is not shown + clusterList.goTo(); + clusterList.checkIsCurrentPage(); + clusterList.createCluster(); + clusterCreatePage.gridElementExistanceByName('Azure AKS', 'not.exist'); + + // re-enable the AKS kontainer driver + KontainerDriversPagePo.navTo(); + driversPage.waitForPage(); + driversPage.list().actionMenu('Azure AKS').getMenuItem('Activate').click(); + + // verify that the AKS card is back + clusterList.goTo(); + clusterList.checkIsCurrentPage(); + clusterList.createCluster(); + clusterCreatePage.gridElementExistanceByName('Azure AKS', 'exist'); + }); + + it('deleting a kontainer driver should hide its card from the cluster creation page', () => { + // intercept get request for kontainer drivers + cy.intercept('GET', '/v1/management.cattle.io.kontainerdriver*', (req) => { + req.reply( { + type: 'collection', + resourceType: 'management.cattle.io.kontainerdriver', + count: 0, + data: [] + }); + } ).as('kontainerDrivers'); + + const clusterCreatePage = new ClusterManagerCreatePagePo(); + + // verify that the AKS card is not shown + clusterList.goTo(); + clusterList.checkIsCurrentPage(); + clusterList.createCluster(); + + clusterCreatePage.waitForPage(); + cy.wait('@kontainerDrivers'); + + clusterCreatePage.rkeToggleExistance('exist'); + clusterCreatePage.gridElementExistanceByName('Azure AKS', 'not.exist'); + + clusterCreatePage.gridElementGroupTitles().should('have.length', 2); + + clusterCreatePage.gridElementGroupTitles().eq(0).should('not.contain.text', 'Create a cluster'); + + clusterCreatePage.gridElementGroupTitles().eq(0).should('contain.text', 'Provision new nodes'); + clusterCreatePage.gridElementGroupTitles().eq(1).should('contain.text', 'Use existing nodes'); + }); + describe('All providers', () => { providersList.forEach((prov) => { prov.conditions.forEach((condition) => { diff --git a/pkg/aks/provisioner.ts b/pkg/aks/provisioner.ts index 14f05f473b8..b049894e769 100644 --- a/pkg/aks/provisioner.ts +++ b/pkg/aks/provisioner.ts @@ -2,6 +2,7 @@ import { IClusterProvisioner, ClusterProvisionerContext } from '@shell/core/type import CruAks from './components/CruAks.vue'; import { mapDriver } from '@shell/store/plugins'; import type { Component } from 'vue'; +import { MANAGEMENT } from '@shell/config/types'; export class AKSProvisioner implements IClusterProvisioner { static ID = 'azureaks' @@ -30,6 +31,12 @@ export class AKSProvisioner implements IClusterProvisioner { return CruAks; } + get hidden(): boolean { + const kontainerDriver = this.context.getters['management/byId'](MANAGEMENT.KONTAINER_DRIVER, 'azurekubernetesservice'); + + return !kontainerDriver?.spec?.active; + } + get detailTabs(): any { return { machines: false, diff --git a/pkg/eks/provisioner.ts b/pkg/eks/provisioner.ts index 7300e77f2d0..91b435d74b2 100644 --- a/pkg/eks/provisioner.ts +++ b/pkg/eks/provisioner.ts @@ -1,7 +1,8 @@ import { IClusterProvisioner, ClusterProvisionerContext } from '@shell/core/types'; import CruEKS from './components/CruEKS.vue'; import { mapDriver } from '@shell/store/plugins'; -import { Component } from 'vue/types/umd'; +import { Component } from 'vue'; +import { MANAGEMENT } from '@shell/config/types'; export class EKSProvisioner implements IClusterProvisioner { static ID = 'amazoneks' @@ -30,6 +31,12 @@ export class EKSProvisioner implements IClusterProvisioner { return CruEKS; } + get hidden(): boolean { + const kontainerDriver = this.context.getters['management/byId'](MANAGEMENT.KONTAINER_DRIVER, 'amazonelasticcontainerservice'); + + return !kontainerDriver?.spec?.active; + } + get detailTabs(): any { return { machines: false, diff --git a/pkg/gke/provisioner.ts b/pkg/gke/provisioner.ts index a0a7a131a3e..937de5ccb87 100644 --- a/pkg/gke/provisioner.ts +++ b/pkg/gke/provisioner.ts @@ -1,7 +1,8 @@ import { IClusterProvisioner, ClusterProvisionerContext } from '@shell/core/types'; import CruGKE from './components/CruGKE.vue'; import { mapDriver } from '@shell/store/plugins'; -import { Component } from 'vue/types/umd'; +import { Component } from 'vue'; +import { MANAGEMENT } from '@shell/config/types'; export class GKEProvisioner implements IClusterProvisioner { static ID = 'googlegke' @@ -30,6 +31,12 @@ export class GKEProvisioner implements IClusterProvisioner { return CruGKE; } + get hidden(): boolean { + const kontainerDriver = this.context.getters['management/byId'](MANAGEMENT.KONTAINER_DRIVER, 'googlekubernetesengine'); + + return !kontainerDriver?.spec?.active; + } + get detailTabs(): any { return { machines: false, diff --git a/shell/core/types-provisioning.ts b/shell/core/types-provisioning.ts index 6e31451b7ec..d9f190d1ff0 100644 --- a/shell/core/types-provisioning.ts +++ b/shell/core/types-provisioning.ts @@ -106,6 +106,11 @@ export interface IClusterProvisioner { */ disabled?: boolean; + /** + * Hide the cluster provider card + */ + hidden?: boolean; + /** * Custom Dashboard route to navigate to when the cluster provider card is clicked */ diff --git a/shell/edit/provisioning.cattle.io.cluster/index.vue b/shell/edit/provisioning.cattle.io.cluster/index.vue index f1f7906e64b..d113b51a428 100644 --- a/shell/edit/provisioning.cattle.io.cluster/index.vue +++ b/shell/edit/provisioning.cattle.io.cluster/index.vue @@ -404,7 +404,8 @@ export default { disabled: ext.disabled || false, link: ext.link, tag: ext.tag, - component: ext.component + component: ext.component, + hidden: ext.hidden, }; out.push(subtype); @@ -449,10 +450,14 @@ export default { } }, + filteredSubTypes() { + return this.subTypes.filter((subtype) => !subtype.hidden); + }, + groupedSubTypes() { const out = {}; - for ( const row of this.subTypes ) { + for ( const row of this.filteredSubTypes ) { const name = row.group; let entry = out[name]; @@ -623,7 +628,7 @@ export default {