@rancher/shell 3.0.12-rc.1 → 3.0.12-rc.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apis/impl/apis.ts +6 -0
- package/apis/index.ts +26 -0
- package/apis/intf/resources-api/cluster-api.ts +18 -0
- package/apis/intf/resources-api/mgmt-api.ts +15 -0
- package/apis/intf/resources-api/resource-base.ts +107 -0
- package/apis/intf/resources-api/resource-constants.ts +147 -0
- package/apis/intf/resources-api/resources-api.ts +143 -0
- package/apis/intf/resources.ts +49 -0
- package/apis/intf/{modal.ts → shell-api/modal.ts} +21 -26
- package/apis/intf/shell-api/proxy.ts +216 -0
- package/apis/intf/{slide-in.ts → shell-api/slide-in.ts} +4 -3
- package/apis/intf/{system.ts → shell-api/system.ts} +4 -1
- package/apis/intf/shell.ts +12 -6
- package/apis/resources/__tests__/resources-api-class.test.ts +550 -0
- package/apis/resources/index.ts +22 -0
- package/apis/resources/resources-api-class.ts +187 -0
- package/apis/shell/__tests__/proxy.test.ts +369 -0
- package/apis/shell/index.ts +8 -1
- package/apis/shell/modal.ts +4 -1
- package/apis/shell/notifications.ts +9 -6
- package/apis/shell/proxy.ts +256 -0
- package/apis/shell/slide-in.ts +4 -1
- package/apis/vue-shim.d.ts +2 -1
- package/assets/data/aws-regions.json +4 -0
- package/assets/fonts/lato/LatoLatin-Black.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Black.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-BlackItalic.woff +0 -0
- package/assets/fonts/lato/LatoLatin-BlackItalic.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-Bold.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Bold.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-BoldItalic.woff +0 -0
- package/assets/fonts/lato/LatoLatin-BoldItalic.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-Heavy.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Heavy.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-HeavyItalic.woff +0 -0
- package/assets/fonts/lato/LatoLatin-HeavyItalic.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-Italic.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Italic.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-Light.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Light.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-LightItalic.woff +0 -0
- package/assets/fonts/lato/LatoLatin-LightItalic.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-Medium.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Medium.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-MediumItalic.woff +0 -0
- package/assets/fonts/lato/LatoLatin-MediumItalic.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-Regular.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Regular.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-Semibold.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Semibold.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-SemiboldItalic.woff +0 -0
- package/assets/fonts/lato/LatoLatin-SemiboldItalic.woff2 +0 -0
- package/assets/images/providers/entraid-black.svg +4 -0
- package/assets/images/providers/entraid.svg +9 -0
- package/assets/images/vendor/entraid.svg +9 -0
- package/assets/styles/app.scss +0 -1
- package/assets/styles/base/_variables.scss +2 -0
- package/assets/styles/fonts/_fontstack.scss +132 -8
- package/assets/translations/en-us.yaml +41 -22
- package/assets/translations/zh-hans.yaml +4 -8
- package/chart/__tests__/S3.test.ts +10 -3
- package/chart/monitoring/index.vue +10 -1
- package/components/ActionDropdownShell.vue +2 -1
- package/components/CountBox.vue +20 -0
- package/components/CreateDriver.vue +0 -12
- package/components/CruResourceFooter.vue +9 -5
- package/components/DetailText.vue +12 -3
- package/components/ExplorerProjectsNamespaces.vue +1 -1
- package/components/InstallHelmCharts.vue +2 -2
- package/components/LandingPagePreference.vue +14 -5
- package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +15 -1
- package/components/Resource/Detail/Metadata/index.vue +6 -0
- package/components/Resource/Detail/ResourcePopover/index.vue +12 -1
- package/components/Resource/Detail/SpacedRow.vue +3 -1
- package/components/Resource/Detail/TitleBar/index.vue +10 -11
- package/components/ResourceList/Masthead.vue +12 -8
- package/components/SelectIconGrid.vue +5 -10
- package/components/SingleClusterInfo.vue +1 -0
- package/components/SortableTable/__tests__/sorting.test.ts +126 -0
- package/components/SortableTable/index.vue +6 -9
- package/components/SortableTable/selection.js +23 -5
- package/components/SortableTable/sorting.js +6 -3
- package/components/Wizard.vue +14 -13
- package/components/__tests__/CountBox.test.ts +72 -0
- package/components/__tests__/DetailText.test.ts +113 -0
- package/components/fleet/FleetBundles.vue +100 -12
- package/components/fleet/FleetClusterTargets/index.vue +54 -15
- package/components/fleet/__tests__/FleetClusterTargets.test.ts +149 -115
- package/components/fleet/__tests__/FleetClusters.test.ts +12 -12
- package/components/form/InputWithSelect.vue +18 -10
- package/components/form/KeyValue.vue +17 -1
- package/components/form/LabeledSelect.vue +101 -26
- package/components/form/NameNsDescription.vue +11 -0
- package/components/form/Security.vue +6 -2
- package/components/form/Select.vue +73 -56
- package/components/form/ServiceNameSelect.vue +13 -11
- package/components/form/WorkloadPorts.vue +2 -7
- package/components/form/__tests__/KeyValue.test.ts +66 -0
- package/components/form/__tests__/NodeScheduling.test.ts +9 -0
- package/components/form/__tests__/Security.test.ts +76 -0
- package/components/form/labeled-select-utils/useLabeledSelectPagination.ts +138 -0
- package/components/formatter/Autoscaler.vue +4 -4
- package/components/formatter/ClusterKubeVersion.vue +27 -0
- package/components/formatter/ClusterLink.vue +1 -7
- package/components/formatter/ClusterProvider.vue +6 -10
- package/components/formatter/FleetSummaryGraph.vue +0 -3
- package/components/formatter/MachineSummaryGraph.vue +1 -1
- package/components/formatter/PodsUsage.vue +2 -2
- package/components/formatter/__tests__/Autoscaler.test.ts +19 -22
- package/components/formatter/__tests__/FleetSummaryGraph.test.ts +216 -0
- package/components/formatter/__tests__/PodsUsage.test.ts +6 -10
- package/components/nav/Group.vue +7 -6
- package/components/nav/Header.vue +24 -3
- package/components/nav/NamespaceFilter.vue +2 -2
- package/components/nav/NotificationCenter/Notification.vue +4 -1
- package/components/nav/NotificationCenter/NotificationHeader.vue +20 -8
- package/components/nav/NotificationCenter/__tests__/NotificationHeader.test.ts +80 -0
- package/components/nav/TopLevelMenu.helper.ts +15 -3
- package/components/nav/TopLevelMenu.vue +16 -5
- package/components/nav/Type.vue +8 -7
- package/components/nav/WindowManager/index.vue +2 -1
- package/components/nav/WorkspaceSwitcher.vue +13 -0
- package/components/nav/__tests__/Group.test.ts +67 -0
- package/components/nav/__tests__/Header.test.ts +235 -0
- package/components/nav/__tests__/TopLevelMenu.test.ts +145 -21
- package/components/nav/__tests__/Type.test.ts +20 -3
- package/components/templates/default.vue +34 -4
- package/components/templates/home.vue +30 -25
- package/components/templates/plain.vue +31 -26
- package/components/templates/standalone.vue +17 -0
- package/composables/useFormValidation.ts +93 -0
- package/composables/useLabeledFormElement.ts +10 -2
- package/composables/useLabeledSelect.ts +60 -0
- package/composables/useUserRetentionValidation.ts +1 -49
- package/composables/useVeeValidateField.test.ts +159 -0
- package/composables/useVeeValidateField.ts +67 -0
- package/config/cookies.js +0 -1
- package/config/labels-annotations.js +1 -0
- package/config/pagination-table-headers.js +18 -1
- package/config/product/manager.js +82 -21
- package/config/query-params.js +1 -0
- package/config/router/routes.js +6 -8
- package/config/table-headers.js +20 -1
- package/config/types.js +2 -1
- package/core/__tests__/plugin-products.test.ts +1505 -30
- package/core/plugin-products-base.ts +137 -20
- package/core/plugin-products-helpers.ts +5 -4
- package/core/plugin-products.ts +4 -0
- package/core/plugin-types.ts +129 -4
- package/core/plugin.ts +15 -7
- package/core/productDebugger.js +9 -4
- package/core/types-provisioning.ts +43 -30
- package/core/types.ts +58 -19
- package/detail/__tests__/management.cattle.io.fleetworkspace.test.ts +128 -0
- package/detail/__tests__/pod.test.ts +41 -0
- package/detail/harvesterhci.io.management.cluster.vue +6 -2
- package/detail/management.cattle.io.fleetworkspace.vue +49 -0
- package/detail/pod.vue +1 -1
- package/detail/provisioning.cattle.io.cluster.vue +4 -10
- package/edit/__tests__/fleet.cattle.io.helmop.test.ts +9 -0
- package/edit/__tests__/kontainerDriver.test.ts +0 -13
- package/edit/__tests__/nodeDriver.test.ts +5 -11
- package/edit/__tests__/resources.cattle.io.restore.test.ts +9 -0
- package/edit/auditlog.cattle.io.auditpolicy/__tests__/__snapshots__/General.test.ts.snap +6 -0
- package/edit/auth/__tests__/azuread.test.ts +217 -34
- package/edit/auth/__tests__/oidc.test.ts +54 -0
- package/edit/auth/azuread.vue +123 -15
- package/edit/auth/oidc.vue +10 -2
- package/edit/kontainerDriver.vue +1 -2
- package/edit/networking.k8s.io.ingress/DefaultBackend.vue +13 -4
- package/edit/networking.k8s.io.ingress/RulePath.vue +8 -4
- package/edit/networking.k8s.io.ingress/index.vue +75 -20
- package/edit/nodeDriver.vue +0 -2
- package/edit/provisioning.cattle.io.cluster/AgentEnv.vue +1 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/AgentEnv.test.ts +25 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/MachinePool.test.ts +104 -0
- package/edit/provisioning.cattle.io.cluster/index.vue +81 -106
- package/edit/provisioning.cattle.io.cluster/rke2.vue +8 -4
- package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +11 -0
- package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +37 -4
- package/edit/provisioning.cattle.io.cluster/tabs/registries/__tests__/RegistryConfigs.test.ts +132 -7
- package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +2 -1
- package/edit/secret/__tests__/ssh.test.ts +5 -6
- package/edit/secret/basic.vue +31 -0
- package/edit/secret/index.vue +68 -17
- package/edit/secret/registry.vue +38 -0
- package/edit/secret/ssh.vue +29 -0
- package/edit/secret/tls.vue +30 -0
- package/edit/service.vue +4 -4
- package/edit/workload/Upgrading.vue +3 -3
- package/edit/workload/__tests__/Upgrading.test.ts +6 -9
- package/edit/workload/mixins/workload.js +2 -1
- package/initialize/App.vue +29 -2
- package/initialize/install-plugins.js +0 -2
- package/list/__tests__/management.cattle.io.feature.test.ts +105 -0
- package/list/catalog.cattle.io.app.vue +25 -5
- package/list/fleet.cattle.io.bundle.vue +7 -104
- package/list/fleet.cattle.io.clusterregistrationtoken.vue +20 -0
- package/list/management.cattle.io.feature.vue +1 -1
- package/list/management.cattle.io.fleetworkspace.vue +8 -0
- package/list/provisioning.cattle.io.cluster.vue +262 -180
- package/list/utils/management.cattle.io.cluster.utils.ts +128 -0
- package/machine-config/amazonec2.vue +1 -0
- package/mixins/__tests__/chart.test.ts +112 -0
- package/mixins/brand.js +2 -1
- package/mixins/chart.js +50 -15
- package/mixins/resource-fetch-api-pagination.js +41 -5
- package/models/__tests__/catalog.cattle.io.app.test.ts +15 -1
- package/models/__tests__/catalog.cattle.io.clusterrepo.test.ts +84 -0
- package/models/__tests__/chart.test.ts +99 -6
- package/models/__tests__/ext.cattle.io.kubeconfig.test.ts +67 -67
- package/models/__tests__/management.cattle.io.cluster.test.ts +1 -1
- package/models/__tests__/management.cattle.io.feature.test.ts +131 -0
- package/models/__tests__/management.cattle.io.node.ts +6 -5
- package/models/__tests__/management.cattle.io.nodepool.ts +5 -4
- package/models/__tests__/monitoring.coreos.com.alertmanagerconfig.test.ts +98 -0
- package/models/__tests__/provisioning.cattle.io.cluster.test.ts +32 -11
- package/models/base-cluster.x-k8s.io.js +26 -0
- package/models/catalog.cattle.io.app.js +21 -17
- package/models/catalog.cattle.io.clusterrepo.js +39 -11
- package/models/chart.js +33 -19
- package/models/cluster.js +1 -1
- package/models/cluster.x-k8s.io.machine.js +4 -22
- package/models/cluster.x-k8s.io.machinedeployment.js +2 -20
- package/models/cluster.x-k8s.io.machineset.js +2 -20
- package/models/compliance.cattle.io.clusterscan.js +130 -2
- package/models/ext.cattle.io.kubeconfig.ts +4 -7
- package/models/fleet-application.js +4 -2
- package/models/fleet.cattle.io.bundle.js +1 -1
- package/models/kontainerdriver.js +11 -0
- package/models/management.cattle.io.authconfig.js +5 -1
- package/models/management.cattle.io.cluster.js +402 -78
- package/models/management.cattle.io.feature.js +3 -3
- package/models/management.cattle.io.kontainerdriver.js +1 -26
- package/models/management.cattle.io.node.js +6 -4
- package/models/management.cattle.io.nodepool.js +1 -1
- package/models/monitoring.coreos.com.alertmanagerconfig.js +31 -17
- package/models/networking.k8s.io.ingress.js +12 -4
- package/models/nodedriver.js +7 -0
- package/models/provisioning.cattle.io.cluster.js +47 -330
- package/models/rke.cattle.io.etcdsnapshot.js +1 -2
- package/package.json +20 -37
- package/pages/__tests__/readme.test.ts +49 -0
- package/pages/auth/setup.vue +2 -3
- package/pages/c/_cluster/apps/charts/__tests__/chart.test.ts +265 -0
- package/pages/c/_cluster/apps/charts/__tests__/index.test.ts +55 -0
- package/pages/c/_cluster/apps/charts/__tests__/install.test.ts +53 -0
- package/pages/c/_cluster/apps/charts/chart.vue +275 -39
- package/pages/c/_cluster/apps/charts/index.vue +2 -2
- package/pages/c/_cluster/apps/charts/install.vue +18 -10
- package/pages/c/_cluster/auth/user.retention/index.vue +55 -22
- package/pages/c/_cluster/explorer/__tests__/index.test.ts +23 -25
- package/pages/c/_cluster/explorer/index.vue +5 -49
- package/pages/c/_cluster/istio/__tests__/istio.index.test.ts +194 -0
- package/pages/c/_cluster/istio/index.vue +21 -6
- package/pages/c/_cluster/manager/drivers/kontainerDriver/index.vue +5 -7
- package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +40 -2
- package/pages/c/_cluster/uiplugins/__tests__/PluginInfoPanel.test.ts +61 -0
- package/pages/c/_cluster/uiplugins/__tests__/index.test.ts +735 -13
- package/pages/c/_cluster/uiplugins/index.vue +226 -222
- package/pages/diagnostic.vue +13 -17
- package/pages/fail-whale.vue +18 -0
- package/pages/home.vue +77 -260
- package/pages/readme.vue +88 -0
- package/plugins/dashboard-store/__tests__/resource-class.test.ts +88 -0
- package/plugins/dashboard-store/actions.js +40 -18
- package/plugins/dashboard-store/resource-class.js +5 -2
- package/plugins/steve/__tests__/subscribe.spec.ts +6 -3
- package/plugins/steve/steve-pagination-utils.ts +11 -3
- package/plugins/steve/subscribe.js +35 -5
- package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +211 -1
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +37 -4
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +1 -1
- package/rancher-components/RcButton/RcButton.test.ts +37 -1
- package/rancher-components/RcButton/RcButton.vue +38 -8
- package/rancher-components/RcDropdown/RcDropdownTrigger.vue +10 -8
- package/scripts/test-plugins-build.sh +5 -2
- package/server/server-middleware.js +2 -2
- package/static/humans.txt +1 -0
- package/static/robots.txt +34 -0
- package/static/welcome-cow.svg +18 -0
- package/store/__tests__/catalog.test.ts +276 -12
- package/store/__tests__/type-map.test.ts +556 -1
- package/store/action-menu.js +8 -3
- package/store/auth.js +1 -4
- package/store/aws.js +27 -16
- package/store/catalog.js +87 -11
- package/store/digitalocean.js +20 -38
- package/store/index.js +2 -0
- package/store/linode.js +25 -40
- package/store/pnap.js +1 -0
- package/store/type-map.js +111 -29
- package/tsconfig.paths.json +8 -8
- package/types/kube/kube-api.ts +14 -1
- package/types/rancher/steve.api.ts +12 -12
- package/types/resources/settings.d.ts +2 -1
- package/types/shell/index.d.ts +128 -24
- package/types/store/dashboard-store.types.ts +108 -11
- package/types/store/pagination.types.ts +6 -3
- package/utils/__tests__/alertmanagerconfig.test.ts +117 -0
- package/utils/__tests__/async.test.ts +87 -0
- package/utils/__tests__/aws.test.ts +140 -0
- package/utils/__tests__/banners.test.ts +176 -0
- package/utils/__tests__/chart.test.ts +64 -1
- package/utils/__tests__/color.test.ts +226 -0
- package/utils/__tests__/duration.test.ts +140 -0
- package/utils/__tests__/fleet.test.ts +340 -0
- package/utils/__tests__/git.test.ts +270 -0
- package/utils/__tests__/inactivity.test.ts +316 -0
- package/utils/__tests__/ingress.test.ts +553 -0
- package/utils/__tests__/kube.test.ts +68 -0
- package/utils/__tests__/namespace-filter.test.ts +109 -0
- package/utils/__tests__/object.test.ts +77 -0
- package/utils/__tests__/pagination-utils.test.ts +361 -0
- package/utils/__tests__/parse-externalid.test.ts +137 -0
- package/utils/__tests__/perf-setting.utils.test.ts +98 -0
- package/utils/__tests__/poller-sequential.test.ts +177 -0
- package/utils/__tests__/poller.test.ts +170 -0
- package/utils/__tests__/promise.test.ts +346 -0
- package/utils/__tests__/settings.test.ts +140 -0
- package/utils/__tests__/sort-utils.test.ts +301 -0
- package/utils/__tests__/string-utils.test.ts +798 -0
- package/utils/__tests__/string.test.ts +23 -1
- package/utils/__tests__/style.test.ts +154 -0
- package/utils/__tests__/svg-filter.test.ts +184 -0
- package/utils/__tests__/time.test.ts +14 -1
- package/utils/__tests__/units.test.ts +417 -0
- package/utils/__tests__/url.test.ts +246 -0
- package/utils/__tests__/versions.test.ts +128 -0
- package/utils/__tests__/xccdf.test.ts +391 -0
- package/utils/chart.js +36 -0
- package/utils/fleet.ts +13 -3
- package/utils/gatekeeper/__tests__/util.test.ts +174 -0
- package/utils/gc/__tests__/gc-interval.test.ts +119 -0
- package/utils/gc/__tests__/gc-root-store.test.ts +225 -0
- package/utils/gc/__tests__/gc-route-changed.test.ts +96 -0
- package/utils/gc/__tests__/gc.test.ts +487 -0
- package/utils/ingress.ts +9 -1
- package/utils/object.js +33 -2
- package/utils/pagination-utils.ts +2 -1
- package/utils/string.js +25 -2
- package/utils/time.ts +5 -0
- package/utils/uiplugins.ts +5 -5
- package/utils/validators/__tests__/cluster-name.test.ts +110 -0
- package/utils/validators/__tests__/cron-schedule.test.ts +79 -0
- package/utils/validators/__tests__/index.test.ts +481 -0
- package/utils/validators/__tests__/kubernetes-name.test.ts +163 -0
- package/utils/validators/__tests__/misc-validators.test.ts +246 -0
- package/utils/validators/__tests__/pod-affinity.test.ts +382 -0
- package/utils/validators/__tests__/prometheusrule.test.ts +211 -0
- package/utils/validators/__tests__/role-template.test.ts +149 -0
- package/utils/validators/__tests__/service.test.ts +283 -0
- package/utils/validators/__tests__/setting.test.js +32 -0
- package/utils/validators/formRules/__tests__/index.test.ts +50 -0
- package/utils/validators/formRules/index.ts +5 -5
- package/utils/validators/machine-pool.ts +1 -1
- package/utils/validators/setting.js +18 -3
- package/utils/xccdf.ts +418 -0
- package/vue.config.js +0 -9
- package/assets/fonts/lato/lato-v17-latin-700.woff +0 -0
- package/assets/fonts/lato/lato-v17-latin-700.woff2 +0 -0
- package/assets/fonts/lato/lato-v17-latin-regular.woff +0 -0
- package/assets/fonts/lato/lato-v17-latin-regular.woff2 +0 -0
- package/assets/images/providers/azuread-black.svg +0 -22
- package/assets/images/providers/azuread.svg +0 -25
- package/assets/images/vendor/azuread.svg +0 -18
- package/assets/styles/fonts/_dots.scss +0 -18
- package/components/EmberPage.vue +0 -622
- package/components/EmberPageView.vue +0 -39
- package/components/form/labeled-select-utils/labeled-select-pagination.ts +0 -116
- package/mixins/labeled-form-element.ts +0 -225
- package/pages/c/_cluster/explorer/tools/pages/_page.vue +0 -28
- package/pages/c/_cluster/manager/pages/_page.vue +0 -22
- package/pages/c/_cluster/mcapps/pages/_page.vue +0 -22
- package/plugins/ember-cookie.js +0 -17
- package/utils/ember-page.js +0 -30
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Kubeconfig from '@shell/models/ext.cattle.io.kubeconfig';
|
|
2
|
-
import {
|
|
2
|
+
import { MANAGEMENT } from '@shell/config/types';
|
|
3
3
|
|
|
4
4
|
// SteveModel is JS, so we need to type the constructor
|
|
5
5
|
const KubeconfigModel = Kubeconfig as unknown as new (data: object) => Kubeconfig;
|
|
@@ -19,8 +19,9 @@ describe('class Kubeconfig', () => {
|
|
|
19
19
|
// Mock $rootGetters before any getters are accessed
|
|
20
20
|
// Cast to any since $rootGetters is inherited from JS SteveModel
|
|
21
21
|
jest.spyOn(kubeconfig as any, '$rootGetters', 'get').mockReturnValue({
|
|
22
|
-
'i18n/t':
|
|
23
|
-
'management/all':
|
|
22
|
+
'i18n/t': mockT,
|
|
23
|
+
'management/all': () => [],
|
|
24
|
+
'management/byId': () => null,
|
|
24
25
|
...rootGetters
|
|
25
26
|
});
|
|
26
27
|
|
|
@@ -70,11 +71,12 @@ describe('class Kubeconfig', () => {
|
|
|
70
71
|
});
|
|
71
72
|
|
|
72
73
|
describe('referencedClusters', () => {
|
|
73
|
-
const mockProvCluster = {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
const mockProvCluster = { detailLocation: { name: 'c-cluster-product-resource-id', params: { cluster: 'my-cluster' } } };
|
|
75
|
+
|
|
76
|
+
const mockMgmtClusterWithProv = {
|
|
77
|
+
id: 'c-m-abc123',
|
|
78
|
+
nameDisplay: 'my-cluster',
|
|
79
|
+
provCluster: mockProvCluster
|
|
78
80
|
};
|
|
79
81
|
|
|
80
82
|
const mockMgmtCluster = {
|
|
@@ -99,12 +101,12 @@ describe('class Kubeconfig', () => {
|
|
|
99
101
|
spec: { clusters: ['c-m-abc123'] }
|
|
100
102
|
},
|
|
101
103
|
{
|
|
102
|
-
'management/
|
|
103
|
-
if (type ===
|
|
104
|
-
return
|
|
104
|
+
'management/byId': (type: string, id: string) => {
|
|
105
|
+
if (type === MANAGEMENT.CLUSTER && id === 'c-m-abc123') {
|
|
106
|
+
return mockMgmtClusterWithProv;
|
|
105
107
|
}
|
|
106
108
|
|
|
107
|
-
return
|
|
109
|
+
return null;
|
|
108
110
|
}
|
|
109
111
|
}
|
|
110
112
|
);
|
|
@@ -124,12 +126,12 @@ describe('class Kubeconfig', () => {
|
|
|
124
126
|
spec: { clusters: ['c-m-def456'] }
|
|
125
127
|
},
|
|
126
128
|
{
|
|
127
|
-
'management/
|
|
128
|
-
if (type === MANAGEMENT.CLUSTER) {
|
|
129
|
-
return
|
|
129
|
+
'management/byId': (type: string, id: string) => {
|
|
130
|
+
if (type === MANAGEMENT.CLUSTER && id === 'c-m-def456') {
|
|
131
|
+
return mockMgmtCluster;
|
|
130
132
|
}
|
|
131
133
|
|
|
132
|
-
return
|
|
134
|
+
return null;
|
|
133
135
|
}
|
|
134
136
|
}
|
|
135
137
|
);
|
|
@@ -157,11 +159,12 @@ describe('class Kubeconfig', () => {
|
|
|
157
159
|
expect(mockT).toHaveBeenCalledWith('"ext.cattle.io.kubeconfig".deleted', { name: 'c-m-deleted' });
|
|
158
160
|
});
|
|
159
161
|
|
|
160
|
-
it('should prefer provisioning cluster over management cluster', () => {
|
|
161
|
-
const
|
|
162
|
+
it('should prefer provisioning cluster over management cluster for location', () => {
|
|
163
|
+
const mgmtClusterBothLocs = {
|
|
162
164
|
id: 'c-m-abc123',
|
|
163
|
-
nameDisplay: '
|
|
164
|
-
detailLocation: { name: 'mgmt-location' }
|
|
165
|
+
nameDisplay: 'my-cluster',
|
|
166
|
+
detailLocation: { name: 'mgmt-location' },
|
|
167
|
+
provCluster: { detailLocation: { name: 'prov-location' } }
|
|
165
168
|
};
|
|
166
169
|
|
|
167
170
|
const kubeconfig = createKubeconfig(
|
|
@@ -170,15 +173,12 @@ describe('class Kubeconfig', () => {
|
|
|
170
173
|
spec: { clusters: ['c-m-abc123'] }
|
|
171
174
|
},
|
|
172
175
|
{
|
|
173
|
-
'management/
|
|
174
|
-
if (type ===
|
|
175
|
-
return
|
|
176
|
-
}
|
|
177
|
-
if (type === MANAGEMENT.CLUSTER) {
|
|
178
|
-
return [mgmtClusterSameId];
|
|
176
|
+
'management/byId': (type: string, id: string) => {
|
|
177
|
+
if (type === MANAGEMENT.CLUSTER && id === 'c-m-abc123') {
|
|
178
|
+
return mgmtClusterBothLocs;
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
-
return
|
|
181
|
+
return null;
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
184
|
);
|
|
@@ -186,7 +186,7 @@ describe('class Kubeconfig', () => {
|
|
|
186
186
|
expect(kubeconfig.referencedClusters).toStrictEqual([
|
|
187
187
|
{
|
|
188
188
|
label: 'my-cluster',
|
|
189
|
-
location:
|
|
189
|
+
location: { name: 'prov-location' }
|
|
190
190
|
}
|
|
191
191
|
]);
|
|
192
192
|
});
|
|
@@ -195,7 +195,7 @@ describe('class Kubeconfig', () => {
|
|
|
195
195
|
describe('sortedReferencedClusters', () => {
|
|
196
196
|
it('should sort existing clusters before deleted clusters', () => {
|
|
197
197
|
const existingCluster = {
|
|
198
|
-
|
|
198
|
+
id: 'c-m-exists',
|
|
199
199
|
nameDisplay: 'existing-cluster',
|
|
200
200
|
detailLocation: { name: 'location' }
|
|
201
201
|
};
|
|
@@ -206,12 +206,12 @@ describe('class Kubeconfig', () => {
|
|
|
206
206
|
spec: { clusters: ['deleted-1', 'c-m-exists', 'deleted-2'] }
|
|
207
207
|
},
|
|
208
208
|
{
|
|
209
|
-
'management/
|
|
210
|
-
if (type ===
|
|
211
|
-
return
|
|
209
|
+
'management/byId': (type: string, id: string) => {
|
|
210
|
+
if (type === MANAGEMENT.CLUSTER && id === 'c-m-exists') {
|
|
211
|
+
return existingCluster;
|
|
212
212
|
}
|
|
213
213
|
|
|
214
|
-
return
|
|
214
|
+
return null;
|
|
215
215
|
}
|
|
216
216
|
}
|
|
217
217
|
);
|
|
@@ -225,17 +225,17 @@ describe('class Kubeconfig', () => {
|
|
|
225
225
|
});
|
|
226
226
|
|
|
227
227
|
it('should sort existing clusters alphabetically', () => {
|
|
228
|
-
const clusters =
|
|
229
|
-
{
|
|
230
|
-
|
|
228
|
+
const clusters: Record<string, any> = {
|
|
229
|
+
'c-m-zebra': {
|
|
230
|
+
id: 'c-m-zebra', nameDisplay: 'zebra', detailLocation: { name: 'z' }
|
|
231
231
|
},
|
|
232
|
-
{
|
|
233
|
-
|
|
232
|
+
'c-m-alpha': {
|
|
233
|
+
id: 'c-m-alpha', nameDisplay: 'alpha', detailLocation: { name: 'a' }
|
|
234
234
|
},
|
|
235
|
-
{
|
|
236
|
-
|
|
235
|
+
'c-m-beta': {
|
|
236
|
+
id: 'c-m-beta', nameDisplay: 'beta', detailLocation: { name: 'b' }
|
|
237
237
|
}
|
|
238
|
-
|
|
238
|
+
};
|
|
239
239
|
|
|
240
240
|
const kubeconfig = createKubeconfig(
|
|
241
241
|
{
|
|
@@ -243,12 +243,12 @@ describe('class Kubeconfig', () => {
|
|
|
243
243
|
spec: { clusters: ['c-m-zebra', 'c-m-alpha', 'c-m-beta'] }
|
|
244
244
|
},
|
|
245
245
|
{
|
|
246
|
-
'management/
|
|
247
|
-
if (type ===
|
|
248
|
-
return clusters;
|
|
246
|
+
'management/byId': (type: string, id: string) => {
|
|
247
|
+
if (type === MANAGEMENT.CLUSTER) {
|
|
248
|
+
return clusters[id] || null;
|
|
249
249
|
}
|
|
250
250
|
|
|
251
|
-
return
|
|
251
|
+
return null;
|
|
252
252
|
}
|
|
253
253
|
}
|
|
254
254
|
);
|
|
@@ -259,17 +259,17 @@ describe('class Kubeconfig', () => {
|
|
|
259
259
|
});
|
|
260
260
|
|
|
261
261
|
it('should sort numerically when names contain numbers', () => {
|
|
262
|
-
const clusters =
|
|
263
|
-
{
|
|
264
|
-
|
|
262
|
+
const clusters: Record<string, any> = {
|
|
263
|
+
'c-m-2': {
|
|
264
|
+
id: 'c-m-2', nameDisplay: 'cluster2', detailLocation: { name: 'c2' }
|
|
265
265
|
},
|
|
266
|
-
{
|
|
267
|
-
|
|
266
|
+
'c-m-10': {
|
|
267
|
+
id: 'c-m-10', nameDisplay: 'cluster10', detailLocation: { name: 'c10' }
|
|
268
268
|
},
|
|
269
|
-
{
|
|
270
|
-
|
|
269
|
+
'c-m-1': {
|
|
270
|
+
id: 'c-m-1', nameDisplay: 'cluster1', detailLocation: { name: 'c1' }
|
|
271
271
|
}
|
|
272
|
-
|
|
272
|
+
};
|
|
273
273
|
|
|
274
274
|
const kubeconfig = createKubeconfig(
|
|
275
275
|
{
|
|
@@ -277,12 +277,12 @@ describe('class Kubeconfig', () => {
|
|
|
277
277
|
spec: { clusters: ['c-m-2', 'c-m-10', 'c-m-1'] }
|
|
278
278
|
},
|
|
279
279
|
{
|
|
280
|
-
'management/
|
|
281
|
-
if (type ===
|
|
282
|
-
return clusters;
|
|
280
|
+
'management/byId': (type: string, id: string) => {
|
|
281
|
+
if (type === MANAGEMENT.CLUSTER) {
|
|
282
|
+
return clusters[id] || null;
|
|
283
283
|
}
|
|
284
284
|
|
|
285
|
-
return
|
|
285
|
+
return null;
|
|
286
286
|
}
|
|
287
287
|
}
|
|
288
288
|
);
|
|
@@ -295,14 +295,14 @@ describe('class Kubeconfig', () => {
|
|
|
295
295
|
|
|
296
296
|
describe('referencedClustersSortable', () => {
|
|
297
297
|
it('should return comma-separated lowercase labels', () => {
|
|
298
|
-
const clusters =
|
|
299
|
-
{
|
|
300
|
-
|
|
298
|
+
const clusters: Record<string, any> = {
|
|
299
|
+
'c-m-1': {
|
|
300
|
+
id: 'c-m-1', nameDisplay: 'Alpha', detailLocation: { name: 'a' }
|
|
301
301
|
},
|
|
302
|
-
{
|
|
303
|
-
|
|
302
|
+
'c-m-2': {
|
|
303
|
+
id: 'c-m-2', nameDisplay: 'Beta', detailLocation: { name: 'b' }
|
|
304
304
|
}
|
|
305
|
-
|
|
305
|
+
};
|
|
306
306
|
|
|
307
307
|
const kubeconfig = createKubeconfig(
|
|
308
308
|
{
|
|
@@ -310,12 +310,12 @@ describe('class Kubeconfig', () => {
|
|
|
310
310
|
spec: { clusters: ['c-m-1', 'c-m-2'] }
|
|
311
311
|
},
|
|
312
312
|
{
|
|
313
|
-
'management/
|
|
314
|
-
if (type ===
|
|
315
|
-
return clusters;
|
|
313
|
+
'management/byId': (type: string, id: string) => {
|
|
314
|
+
if (type === MANAGEMENT.CLUSTER) {
|
|
315
|
+
return clusters[id] || null;
|
|
316
316
|
}
|
|
317
317
|
|
|
318
|
-
return
|
|
318
|
+
return null;
|
|
319
319
|
}
|
|
320
320
|
}
|
|
321
321
|
);
|
|
@@ -7,7 +7,7 @@ jest.mock('@shell/utils/clipboard', () => {
|
|
|
7
7
|
describe('class MgmtCluster', () => {
|
|
8
8
|
describe('provisioner', () => {
|
|
9
9
|
const testCases = [
|
|
10
|
-
[{ provider: '
|
|
10
|
+
[{ provider: 'rke2', driver: 'imported' }, 'rke2'],
|
|
11
11
|
[{ provider: 'k3s', driver: 'K3S' }, 'K3S'],
|
|
12
12
|
[{ provider: 'aks', driver: 'AKS' }, 'AKS'],
|
|
13
13
|
[{}, 'imported'],
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import Feature from '@shell/models/management.cattle.io.feature.js';
|
|
2
|
+
import Resource from '@shell/plugins/dashboard-store/resource-class';
|
|
3
|
+
|
|
4
|
+
describe('class Feature', () => {
|
|
5
|
+
const ctx = {
|
|
6
|
+
dispatch: jest.fn(),
|
|
7
|
+
rootGetters: { 'i18n/t': (key: string) => key },
|
|
8
|
+
getters: { schemaFor: () => ({ linkFor: jest.fn() }) },
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
// The parent Resource._availableActions getter depends on runtime config we don't have
|
|
12
|
+
// in tests — stub it out so we can assert on Feature's own additions.
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
jest.spyOn(Resource.prototype, '_availableActions', 'get').mockReturnValue([]);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
afterEach(() => {
|
|
18
|
+
jest.restoreAllMocks();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
describe('enabled getter', () => {
|
|
22
|
+
it.each([
|
|
23
|
+
[true, true],
|
|
24
|
+
[false, false],
|
|
25
|
+
])('should return lockedValue (%s) when status.lockedValue is not null', (lockedValue, expected) => {
|
|
26
|
+
const feature = new Feature({
|
|
27
|
+
spec: { value: false },
|
|
28
|
+
status: { lockedValue, default: false }
|
|
29
|
+
}, ctx);
|
|
30
|
+
|
|
31
|
+
expect(feature.enabled).toBe(expected);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('should return spec.value when lockedValue is null and spec.value is set', () => {
|
|
35
|
+
const feature = new Feature({
|
|
36
|
+
spec: { value: true },
|
|
37
|
+
status: { lockedValue: null, default: false }
|
|
38
|
+
}, ctx);
|
|
39
|
+
|
|
40
|
+
expect(feature.enabled).toBe(true);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('should fall back to status.default when lockedValue is null and spec.value is null', () => {
|
|
44
|
+
const feature = new Feature({
|
|
45
|
+
spec: { value: null },
|
|
46
|
+
status: { lockedValue: null, default: true }
|
|
47
|
+
}, ctx);
|
|
48
|
+
|
|
49
|
+
expect(feature.enabled).toBe(true);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('should not throw when status is missing (malformed feature flag)', () => {
|
|
53
|
+
const feature = new Feature({ spec: { value: true } }, ctx);
|
|
54
|
+
|
|
55
|
+
expect(() => feature.enabled).not.toThrow();
|
|
56
|
+
expect(feature.enabled).toBe(true);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
describe('restartRequired getter', () => {
|
|
61
|
+
it('should return false when status.dynamic is true', () => {
|
|
62
|
+
const feature = new Feature({ spec: {}, status: { dynamic: true, lockedValue: null } }, ctx);
|
|
63
|
+
|
|
64
|
+
expect(feature.restartRequired).toBe(false);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('should return true when status.dynamic is false', () => {
|
|
68
|
+
const feature = new Feature({ spec: {}, status: { dynamic: false, lockedValue: null } }, ctx);
|
|
69
|
+
|
|
70
|
+
expect(feature.restartRequired).toBe(true);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('should return true when status is missing (malformed feature flag)', () => {
|
|
74
|
+
const feature = new Feature({ spec: {} }, ctx);
|
|
75
|
+
|
|
76
|
+
expect(() => feature.restartRequired).not.toThrow();
|
|
77
|
+
expect(feature.restartRequired).toBe(true);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
describe('_availableActions getter', () => {
|
|
82
|
+
it('should disable the toggle action when lockedValue is not null', () => {
|
|
83
|
+
const feature = new Feature({
|
|
84
|
+
spec: { value: false },
|
|
85
|
+
status: {
|
|
86
|
+
lockedValue: true, default: false, dynamic: true
|
|
87
|
+
},
|
|
88
|
+
}, ctx);
|
|
89
|
+
|
|
90
|
+
jest.spyOn(feature, 'canUpdate', 'get').mockReturnValue(true);
|
|
91
|
+
|
|
92
|
+
const actions = feature._availableActions;
|
|
93
|
+
|
|
94
|
+
expect(actions[0].action).toBe('toggleFeatureFlag');
|
|
95
|
+
expect(actions[0].enabled).toBe(false);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('should enable the toggle action when lockedValue is null and user canUpdate', () => {
|
|
99
|
+
const feature = new Feature({
|
|
100
|
+
spec: { value: false },
|
|
101
|
+
status: {
|
|
102
|
+
lockedValue: null, default: false, dynamic: true
|
|
103
|
+
},
|
|
104
|
+
id: 'some-feature',
|
|
105
|
+
}, ctx);
|
|
106
|
+
|
|
107
|
+
jest.spyOn(feature, 'canUpdate', 'get').mockReturnValue(true);
|
|
108
|
+
|
|
109
|
+
const actions = feature._availableActions;
|
|
110
|
+
|
|
111
|
+
expect(actions[0].action).toBe('toggleFeatureFlag');
|
|
112
|
+
expect(actions[0].enabled).toBe(true);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('should not throw and should disable the toggle action when status is missing (malformed feature flag)', () => {
|
|
116
|
+
const feature = new Feature({
|
|
117
|
+
spec: { value: false },
|
|
118
|
+
id: 'some-feature',
|
|
119
|
+
}, ctx);
|
|
120
|
+
|
|
121
|
+
jest.spyOn(feature, 'canUpdate', 'get').mockReturnValue(true);
|
|
122
|
+
|
|
123
|
+
expect(() => feature._availableActions).not.toThrow();
|
|
124
|
+
|
|
125
|
+
const actions = feature._availableActions;
|
|
126
|
+
|
|
127
|
+
expect(actions[0].action).toBe('toggleFeatureFlag');
|
|
128
|
+
expect(actions[0].enabled).toBeFalsy();
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
});
|
|
@@ -167,11 +167,12 @@ describe('class MgmtNode', () => {
|
|
|
167
167
|
id: nodeId
|
|
168
168
|
}, {
|
|
169
169
|
...baseCtx,
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
170
|
+
rootGetters: {
|
|
171
|
+
...baseCtx.rootGetters,
|
|
172
|
+
'management/byId': () => ({
|
|
173
|
+
id: mgmtClusterId,
|
|
174
|
+
provCluster: { nodes }
|
|
175
|
+
})
|
|
175
176
|
}
|
|
176
177
|
});
|
|
177
178
|
|
|
@@ -66,14 +66,15 @@ describe('class MgmtNodePool', () => {
|
|
|
66
66
|
const { spec, nodes } = data;
|
|
67
67
|
const mgmtNode = new MgmtNodePool({
|
|
68
68
|
spec,
|
|
69
|
-
|
|
69
|
+
metadata: {},
|
|
70
|
+
id: nodeId
|
|
70
71
|
}, {
|
|
71
72
|
...baseCtx,
|
|
72
73
|
getters: {
|
|
73
|
-
|
|
74
|
-
mgmtClusterId,
|
|
74
|
+
byId: () => ({
|
|
75
|
+
id: mgmtClusterId,
|
|
75
76
|
nodes
|
|
76
|
-
}
|
|
77
|
+
})
|
|
77
78
|
}
|
|
78
79
|
});
|
|
79
80
|
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import AlertmanagerConfig from '@shell/models/monitoring.coreos.com.alertmanagerconfig';
|
|
2
|
+
|
|
3
|
+
const base = {
|
|
4
|
+
apiVersion: 'monitoring.coreos.com/v1alpha1',
|
|
5
|
+
kind: 'AlertmanagerConfig',
|
|
6
|
+
metadata: { name: 'test', namespace: 'default' },
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const build = (data: Record<string, any>) => new AlertmanagerConfig(data) as any;
|
|
10
|
+
|
|
11
|
+
describe('class AlertmanagerConfig', () => {
|
|
12
|
+
describe('applyDefaults', () => {
|
|
13
|
+
it('on a fresh resource, seeds the route with defaults and no match/matchRe', () => {
|
|
14
|
+
const amc = build({ ...base });
|
|
15
|
+
|
|
16
|
+
amc.applyDefaults();
|
|
17
|
+
|
|
18
|
+
expect(amc.spec.receivers).toStrictEqual([]);
|
|
19
|
+
expect(amc.spec.route).toStrictEqual({
|
|
20
|
+
groupBy: [],
|
|
21
|
+
groupWait: '30s',
|
|
22
|
+
groupInterval: '5m',
|
|
23
|
+
repeatInterval: '4h',
|
|
24
|
+
matchers: [],
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('backfills route defaults on a resource loaded without a route', () => {
|
|
29
|
+
const amc = build({
|
|
30
|
+
...base,
|
|
31
|
+
spec: { receivers: [{ name: 'existing' }] },
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
amc.applyDefaults();
|
|
35
|
+
|
|
36
|
+
expect(amc.spec.route).toBeDefined();
|
|
37
|
+
expect(amc.spec.route.receiver).toBeUndefined();
|
|
38
|
+
expect(amc.spec.route.matchers).toStrictEqual([]);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('preserves existing matchers on load', () => {
|
|
42
|
+
const matchers = [{
|
|
43
|
+
name: 'severity', value: 'warning', matchType: '='
|
|
44
|
+
}];
|
|
45
|
+
const amc = build({
|
|
46
|
+
...base,
|
|
47
|
+
spec: {
|
|
48
|
+
receivers: [{ name: 'existing' }],
|
|
49
|
+
route: { receiver: 'existing', matchers },
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
amc.applyDefaults();
|
|
54
|
+
|
|
55
|
+
expect(amc.spec.route.matchers).toStrictEqual(matchers);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
describe('cleanForSave', () => {
|
|
60
|
+
it('drops spec.route when no receiver is set — this is what fixes #17347 on 109+ charts', () => {
|
|
61
|
+
const amc = build({ ...base });
|
|
62
|
+
|
|
63
|
+
const out = amc.cleanForSave({
|
|
64
|
+
...base,
|
|
65
|
+
spec: {
|
|
66
|
+
receivers: [],
|
|
67
|
+
route: {
|
|
68
|
+
groupBy: [],
|
|
69
|
+
groupWait: '30s',
|
|
70
|
+
groupInterval: '5m',
|
|
71
|
+
repeatInterval: '4h',
|
|
72
|
+
matchers: [],
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
}, true);
|
|
76
|
+
|
|
77
|
+
expect(out.spec.route).toBeUndefined();
|
|
78
|
+
expect(out.spec.receivers).toStrictEqual([]);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('keeps spec.route when a receiver is set', () => {
|
|
82
|
+
const amc = build({ ...base });
|
|
83
|
+
|
|
84
|
+
const out = amc.cleanForSave({
|
|
85
|
+
...base,
|
|
86
|
+
spec: {
|
|
87
|
+
receivers: [{ name: 'existing' }],
|
|
88
|
+
route: {
|
|
89
|
+
receiver: 'existing', groupBy: [], matchers: []
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
}, false);
|
|
93
|
+
|
|
94
|
+
expect(out.spec.route).toBeDefined();
|
|
95
|
+
expect(out.spec.route.receiver).toBe('existing');
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
});
|
|
@@ -1,29 +1,36 @@
|
|
|
1
1
|
import ProvCluster from '@shell/models/provisioning.cattle.io.cluster';
|
|
2
|
+
import MgmtCluster from '@shell/models/management.cattle.io.cluster';
|
|
3
|
+
|
|
2
4
|
jest.mock('@shell/utils/provider', () => ({
|
|
3
5
|
isHostedProvider: jest.fn().mockImplementation((context, provider) => {
|
|
4
6
|
return ['GKE', 'EKS', 'AKS'].includes(provider);
|
|
5
7
|
})
|
|
6
8
|
}));
|
|
9
|
+
|
|
10
|
+
jest.mock('@shell/utils/clipboard', () => {
|
|
11
|
+
return { copyTextToClipboard: jest.fn(() => Promise.resolve({})) };
|
|
12
|
+
});
|
|
13
|
+
|
|
7
14
|
describe('class ProvCluster', () => {
|
|
8
15
|
const gkeClusterWithPrivateEndpoint = {
|
|
9
16
|
clusterName: 'test',
|
|
10
17
|
provisioner: 'GKE',
|
|
11
18
|
spec: { },
|
|
12
|
-
mgmt: { spec: { gkeConfig: { privateClusterConfig: { enablePrivateEndpoint: true } } } }
|
|
19
|
+
mgmt: new MgmtCluster({ spec: { gkeConfig: { privateClusterConfig: { enablePrivateEndpoint: true } } } }),
|
|
13
20
|
};
|
|
14
21
|
|
|
15
22
|
const eksClusterWithPrivateEndpoint = {
|
|
16
23
|
clusterName: 'test',
|
|
17
24
|
provisioner: 'EKS',
|
|
18
25
|
spec: { },
|
|
19
|
-
mgmt: { spec: { eksConfig: { privateAccess: true } } }
|
|
26
|
+
mgmt: new MgmtCluster({ spec: { eksConfig: { privateAccess: true } } }),
|
|
20
27
|
};
|
|
21
28
|
|
|
22
29
|
const aksClusterWithPrivateEndpoint = {
|
|
23
30
|
clusterName: 'test',
|
|
24
31
|
provisioner: 'AKS',
|
|
25
32
|
spec: { },
|
|
26
|
-
mgmt: { spec: { aksConfig: { privateCluster: true } } }
|
|
33
|
+
mgmt: new MgmtCluster({ spec: { aksConfig: { privateCluster: true } } }),
|
|
27
34
|
};
|
|
28
35
|
|
|
29
36
|
// Related to https://github.com/rancher/dashboard/issues/9402
|
|
@@ -41,10 +48,14 @@ describe('class ProvCluster', () => {
|
|
|
41
48
|
it.each(testCases)('should return the isHostedKubernetesProvider and isPrivateHostedProvider values properly based on the props data', (clusterData: Object, expected: Boolean) => {
|
|
42
49
|
const cluster = new ProvCluster({ spec: clusterData.spec });
|
|
43
50
|
|
|
51
|
+
jest.spyOn(clusterData.mgmt, 'provCluster', 'get').mockReturnValue(
|
|
52
|
+
clusterData
|
|
53
|
+
);
|
|
54
|
+
|
|
44
55
|
jest.spyOn(cluster, 'mgmt', 'get').mockReturnValue(
|
|
45
56
|
clusterData.mgmt
|
|
46
57
|
);
|
|
47
|
-
jest.spyOn(
|
|
58
|
+
jest.spyOn(clusterData.mgmt, 'provisioner', 'get').mockReturnValue(
|
|
48
59
|
clusterData.provisioner
|
|
49
60
|
);
|
|
50
61
|
|
|
@@ -54,6 +65,7 @@ describe('class ProvCluster', () => {
|
|
|
54
65
|
resetMocks();
|
|
55
66
|
});
|
|
56
67
|
});
|
|
68
|
+
|
|
57
69
|
describe('isImported', () => {
|
|
58
70
|
const testCases = [
|
|
59
71
|
{
|
|
@@ -114,7 +126,8 @@ describe('class ProvCluster', () => {
|
|
|
114
126
|
clusterData: {
|
|
115
127
|
isLocal: false,
|
|
116
128
|
isHostedKubernetesProvider: true,
|
|
117
|
-
providerConfig: { imported: true }
|
|
129
|
+
providerConfig: { imported: true },
|
|
130
|
+
mgmt: { status: { provider: '', driver: 'EKS' } }
|
|
118
131
|
},
|
|
119
132
|
expected: true
|
|
120
133
|
},
|
|
@@ -123,7 +136,8 @@ describe('class ProvCluster', () => {
|
|
|
123
136
|
clusterData: {
|
|
124
137
|
isLocal: false,
|
|
125
138
|
isHostedKubernetesProvider: true,
|
|
126
|
-
providerConfig: { imported: false }
|
|
139
|
+
providerConfig: { imported: false },
|
|
140
|
+
mgmt: { status: { provider: '', driver: 'EKS' } }
|
|
127
141
|
},
|
|
128
142
|
expected: false
|
|
129
143
|
},
|
|
@@ -150,23 +164,27 @@ describe('class ProvCluster', () => {
|
|
|
150
164
|
};
|
|
151
165
|
|
|
152
166
|
it.each(testCases)('$description', ({ clusterData, expected }) => {
|
|
167
|
+
const mgmtCluster = new MgmtCluster(clusterData.mgmt || {});
|
|
153
168
|
const cluster = new ProvCluster({});
|
|
154
169
|
|
|
155
170
|
// Mock getters
|
|
156
171
|
jest.spyOn(cluster, 'mgmt', 'get').mockReturnValue(
|
|
157
|
-
|
|
172
|
+
mgmtCluster
|
|
173
|
+
);
|
|
174
|
+
jest.spyOn(mgmtCluster, 'provCluster', 'get').mockReturnValue(
|
|
175
|
+
cluster
|
|
158
176
|
);
|
|
159
177
|
if (clusterData.isLocal !== undefined) {
|
|
160
|
-
jest.spyOn(
|
|
178
|
+
jest.spyOn(mgmtCluster, 'isLocal', 'get').mockReturnValue(clusterData.isLocal);
|
|
161
179
|
}
|
|
162
180
|
if (clusterData.isHostedKubernetesProvider !== undefined) {
|
|
163
|
-
jest.spyOn(
|
|
181
|
+
jest.spyOn(mgmtCluster, 'isHostedKubernetesProvider', 'get').mockReturnValue(clusterData.isHostedKubernetesProvider);
|
|
164
182
|
}
|
|
165
183
|
if (clusterData.providerConfig !== undefined) {
|
|
166
184
|
jest.spyOn(cluster, 'providerConfig', 'get').mockReturnValue(clusterData.providerConfig);
|
|
167
185
|
}
|
|
168
186
|
if (clusterData.provisioner !== undefined) {
|
|
169
|
-
jest.spyOn(
|
|
187
|
+
jest.spyOn(mgmtCluster, 'provisioner', 'get').mockReturnValue(clusterData.provisioner);
|
|
170
188
|
}
|
|
171
189
|
|
|
172
190
|
expect(cluster.isImported).toBe(expected);
|
|
@@ -268,7 +286,10 @@ describe('class ProvCluster', () => {
|
|
|
268
286
|
|
|
269
287
|
it.each(testCases)('should return the hasError value properly based on the "status.conditions" props data for testcase %p', (testName: string, conditions: Array, expected: Boolean) => {
|
|
270
288
|
const ctx = { rootGetters: { 'management/byId': jest.fn() } };
|
|
271
|
-
const
|
|
289
|
+
const mgmtCluster = new MgmtCluster({ status: { conditions } }, ctx);
|
|
290
|
+
const cluster = new ProvCluster({}, ctx);
|
|
291
|
+
|
|
292
|
+
jest.spyOn(cluster, 'mgmt', 'get').mockReturnValue(mgmtCluster);
|
|
272
293
|
|
|
273
294
|
expect(cluster.hasError).toBe(expected);
|
|
274
295
|
resetMocks();
|