@rancher/shell 3.0.7 → 3.0.8-rc.10
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/assets/brand/suse/banner.svg +1 -0
- package/assets/brand/suse/dark/banner.svg +1 -0
- package/assets/brand/suse/dark/login-landscape.svg +1 -0
- package/assets/brand/suse/dark/rancher-logo.svg +1 -1
- package/assets/brand/suse/favicon.png +0 -0
- package/assets/brand/suse/login-landscape.svg +1 -0
- package/assets/brand/suse/metadata.json +11 -1
- package/assets/brand/suse/rancher-logo.svg +1 -1
- package/assets/fonts/suse/suse-v2-latin-300.woff +0 -0
- package/assets/fonts/suse/suse-v2-latin-300.woff2 +0 -0
- package/assets/fonts/suse/suse-v2-latin-600.woff +0 -0
- package/assets/fonts/suse/suse-v2-latin-600.woff2 +0 -0
- package/assets/fonts/suse/suse-v2-latin-700.woff +0 -0
- package/assets/fonts/suse/suse-v2-latin-700.woff2 +0 -0
- package/assets/fonts/suse/suse-v2-latin-800.woff +0 -0
- package/assets/fonts/suse/suse-v2-latin-800.woff2 +0 -0
- package/assets/fonts/suse/suse-v2-latin-regular.woff +0 -0
- package/assets/fonts/suse/suse-v2-latin-regular.woff2 +0 -0
- package/assets/images/content/README.md +5 -0
- package/assets/images/content/cloud-native.svg +84 -0
- package/assets/images/content/dark/cloud-native.svg +21 -0
- package/assets/images/content/dark/shield.svg +59 -0
- package/assets/images/content/dark/suse.svg +10 -0
- package/assets/images/content/shield.svg +59 -0
- package/assets/images/content/suse.svg +10 -0
- package/assets/images/vendor/githubapp.svg +13 -0
- package/assets/styles/base/_typography.scss +2 -1
- package/assets/styles/fonts/_fontstack.scss +53 -1
- package/assets/styles/global/_cards.scss +0 -3
- package/assets/styles/global/_layout.scss +21 -35
- package/assets/styles/themes/_dark.scss +1 -1
- package/assets/styles/themes/_light.scss +1 -1
- package/assets/styles/themes/_modern.scss +16 -8
- package/assets/styles/themes/_suse.scss +116 -24
- package/assets/translations/en-us.yaml +185 -21
- package/assets/translations/zh-hans.yaml +0 -4
- package/components/AutoscalerCard.vue +113 -0
- package/components/AutoscalerTab.vue +94 -0
- package/components/BackLink.vue +8 -0
- package/components/BannerGraphic.vue +36 -21
- package/components/BrandImage.vue +17 -6
- package/components/ClusterIconMenu.vue +1 -1
- package/components/ClusterProviderIcon.vue +1 -1
- package/components/Cron/CronExpressionEditor.vue +1 -1
- package/components/Cron/CronExpressionEditorModal.vue +1 -1
- package/components/Drawer/Chrome.vue +2 -6
- package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +4 -9
- package/components/Drawer/ResourceDetailDrawer/YamlTab.vue +3 -8
- package/components/Drawer/ResourceDetailDrawer/composables.ts +3 -4
- package/components/Drawer/ResourceDetailDrawer/index.vue +4 -9
- package/components/Drawer/ResourceDetailDrawer/types.ts +17 -0
- package/components/Drawer/types.ts +3 -0
- package/components/DynamicContent/DynamicContentBanner.vue +102 -0
- package/components/DynamicContent/DynamicContentCloseButton.vue +42 -0
- package/components/DynamicContent/DynamicContentIcon.vue +132 -0
- package/components/DynamicContent/DynamicContentPanel.vue +112 -0
- package/components/DynamicContent/content.ts +78 -0
- package/components/EmberPage.vue +1 -1
- package/components/IconOrSvg.vue +2 -2
- package/components/Inactivity.vue +222 -106
- package/components/InstallHelmCharts.vue +2 -2
- package/components/PaginatedResourceTable.vue +2 -6
- package/components/PopoverCard.vue +192 -0
- package/components/Questions/__tests__/index.test.ts +159 -0
- package/components/Resource/Detail/CopyToClipboard.vue +4 -1
- package/components/Resource/Detail/FetchLoader/composables.ts +18 -4
- package/components/Resource/Detail/Metadata/Annotations/index.vue +2 -2
- package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/identifying-fields.test.ts +1 -1
- package/components/Resource/Detail/Metadata/IdentifyingInformation/identifying-fields.ts +4 -0
- package/components/Resource/Detail/Metadata/KeyValueRow.vue +1 -1
- package/components/Resource/Detail/Metadata/Labels/index.vue +2 -2
- package/components/Resource/Detail/Metadata/composables.ts +9 -9
- package/components/Resource/Detail/Metadata/index.vue +3 -3
- package/components/Resource/Detail/ResourcePopover/ResourcePopoverCard.vue +2 -19
- package/components/Resource/Detail/ResourcePopover/__tests__/ResourcePopoverCard.test.ts +0 -29
- package/components/Resource/Detail/ResourcePopover/__tests__/index.test.ts +132 -150
- package/components/Resource/Detail/ResourcePopover/index.vue +54 -159
- package/components/Resource/Detail/TitleBar/__tests__/index.test.ts +0 -2
- package/components/Resource/Detail/TitleBar/composables.ts +2 -1
- package/components/Resource/Detail/TitleBar/index.vue +10 -6
- package/components/Resource/Detail/composables.ts +12 -0
- package/components/ResourceDetail/Masthead/latest.vue +29 -0
- package/components/ResourceDetail/index.vue +5 -2
- package/components/ResourceList/Masthead.vue +1 -1
- package/components/SortableTable/index.vue +18 -2
- package/components/Tabbed/__tests__/index.test.ts +86 -0
- package/components/{nav/WindowManager → Window}/ContainerLogs.vue +1 -1
- package/components/{nav/WindowManager → Window}/ContainerLogsActions.vue +1 -0
- package/components/{nav/WindowManager → Window}/__tests__/ContainerLogs.test.ts +1 -1
- package/components/{nav/WindowManager → Window}/__tests__/ContainerShell.test.ts +2 -2
- package/components/__tests__/AutoscalerCard.test.ts +154 -0
- package/components/__tests__/AutoscalerTab.test.ts +125 -0
- package/components/__tests__/PopoverCard.test.ts +204 -0
- package/components/auth/SelectPrincipal.vue +24 -6
- package/components/auth/__tests__/SelectPrincipal.test.ts +119 -0
- package/components/fleet/FleetConfigMapSelector.vue +117 -0
- package/components/fleet/FleetSecretSelector.vue +127 -0
- package/components/fleet/__tests__/FleetConfigMapSelector.test.ts +125 -0
- package/components/fleet/__tests__/FleetSecretSelector.test.ts +82 -0
- package/components/form/FileImageSelector.vue +13 -4
- package/components/form/FileSelector.vue +11 -2
- package/components/form/ResourceLabeledSelect.vue +1 -0
- package/components/form/__tests__/ResourceLabeledSelect.test.ts +90 -0
- package/components/formatter/Autoscaler.vue +97 -0
- package/components/formatter/InternalExternalIP.vue +198 -24
- package/components/formatter/__tests__/Autoscaler.test.ts +156 -0
- package/components/formatter/__tests__/InternalExternalIP.test.ts +133 -0
- package/components/google/util/__tests__/formatter.test.ts +47 -0
- package/components/google/util/formatter.ts +5 -2
- package/components/nav/Group.vue +12 -3
- package/components/nav/Header.vue +37 -16
- package/components/nav/NamespaceFilter.vue +13 -1
- package/components/nav/NotificationCenter/index.vue +2 -1
- package/components/nav/TopLevelMenu.helper.ts +16 -6
- package/components/nav/TopLevelMenu.vue +4 -2
- package/components/{DraggableZone.vue → nav/WindowManager/PinArea.vue} +47 -80
- package/components/nav/WindowManager/composables/useComponentsMount.ts +70 -0
- package/components/nav/WindowManager/composables/useDimensionsHandler.ts +105 -0
- package/components/nav/WindowManager/composables/useDragHandler.ts +99 -0
- package/components/nav/WindowManager/composables/usePanelHandler.ts +72 -0
- package/components/nav/WindowManager/composables/usePanelsHandler.ts +14 -0
- package/components/nav/WindowManager/composables/useResizeHandler.ts +167 -0
- package/components/nav/WindowManager/composables/useTabsHandler.ts +51 -0
- package/components/nav/WindowManager/constants.ts +23 -0
- package/components/nav/WindowManager/index.vue +61 -575
- package/components/nav/WindowManager/panels/HorizontalPanel.vue +265 -0
- package/components/nav/WindowManager/panels/TabBodyContainer.vue +39 -0
- package/components/nav/WindowManager/panels/VerticalPanel.vue +308 -0
- package/components/templates/default.vue +4 -40
- package/components/templates/home.vue +31 -5
- package/components/templates/plain.vue +30 -4
- package/components/templates/standalone.vue +1 -1
- package/composables/useI18n.ts +10 -1
- package/composables/useInterval.ts +15 -0
- package/config/__test__/uiplugins.test.ts +309 -0
- package/config/labels-annotations.js +9 -1
- package/config/product/auth.js +1 -0
- package/config/product/explorer.js +3 -1
- package/config/product/manager.js +20 -9
- package/config/query-params.js +1 -0
- package/config/router/routes.js +10 -2
- package/config/settings.ts +10 -2
- package/config/store.js +4 -2
- package/config/table-headers.js +8 -0
- package/config/types.js +11 -0
- package/config/uiplugins.js +46 -2
- package/config/version.js +1 -1
- package/core/__test__/extension-manager-impl.test.js +236 -0
- package/core/extension-manager-impl.js +23 -6
- package/core/plugin-helpers.ts +2 -0
- package/core/types-provisioning.ts +4 -1
- package/detail/pod.vue +1 -0
- package/detail/provisioning.cattle.io.cluster.vue +13 -1
- package/dialog/AddonConfigConfirmationDialog.vue +45 -1
- package/dialog/DeveloperLoadExtensionDialog.vue +12 -3
- package/dialog/RollbackWorkloadDialog.vue +2 -5
- package/directives/ui-context.ts +103 -0
- package/edit/__tests__/fleet.cattle.io.helmop.test.ts +52 -11
- package/edit/auth/AuthProviderWarningBanners.vue +14 -1
- package/edit/auth/__tests__/oidc.test.ts +26 -0
- package/edit/auth/github-app-steps.vue +97 -0
- package/edit/auth/github-steps.vue +75 -0
- package/edit/auth/github.vue +99 -65
- package/edit/auth/oidc.vue +5 -1
- package/edit/autoscaling.horizontalpodautoscaler/index.vue +1 -0
- package/edit/cloudcredential.vue +1 -1
- package/edit/configmap.vue +1 -0
- package/edit/constraints.gatekeeper.sh.constraint/index.vue +1 -0
- package/edit/fleet.cattle.io.gitrepo.vue +0 -10
- package/edit/fleet.cattle.io.helmop.vue +51 -2
- package/edit/helm.cattle.io.projecthelmchart.vue +1 -0
- package/edit/k8s.cni.cncf.io.networkattachmentdefinition.vue +1 -0
- package/edit/logging-flow/index.vue +1 -0
- package/edit/logging.banzaicloud.io.output/index.vue +1 -0
- package/edit/management.cattle.io.fleetworkspace.vue +1 -1
- package/edit/management.cattle.io.project.vue +1 -0
- package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +4 -1
- package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +2 -1
- package/edit/monitoring.coreos.com.prometheusrule/index.vue +1 -0
- package/edit/monitoring.coreos.com.receiver/index.vue +2 -1
- package/edit/monitoring.coreos.com.route.vue +1 -1
- package/edit/namespace.vue +1 -0
- package/edit/networking.istio.io.destinationrule/index.vue +1 -0
- package/edit/networking.k8s.io.ingress/index.vue +1 -0
- package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +15 -5
- package/edit/networking.k8s.io.networkpolicy/PolicyRules.vue +1 -0
- package/edit/networking.k8s.io.networkpolicy/index.vue +1 -0
- package/edit/node.vue +1 -0
- package/edit/persistentvolume/index.vue +27 -22
- package/edit/persistentvolume/plugins/awsElasticBlockStore.vue +13 -14
- package/edit/persistentvolume/plugins/azureDisk.vue +49 -48
- package/edit/persistentvolume/plugins/azureFile.vue +15 -14
- package/edit/persistentvolume/plugins/cephfs.vue +15 -14
- package/edit/persistentvolume/plugins/cinder.vue +15 -14
- package/edit/persistentvolume/plugins/csi.vue +18 -16
- package/edit/persistentvolume/plugins/fc.vue +13 -14
- package/edit/persistentvolume/plugins/flexVolume.vue +15 -14
- package/edit/persistentvolume/plugins/flocker.vue +1 -3
- package/edit/persistentvolume/plugins/gcePersistentDisk.vue +13 -14
- package/edit/persistentvolume/plugins/glusterfs.vue +15 -14
- package/edit/persistentvolume/plugins/hostPath.vue +40 -39
- package/edit/persistentvolume/plugins/iscsi.vue +13 -14
- package/edit/persistentvolume/plugins/local.vue +1 -3
- package/edit/persistentvolume/plugins/longhorn.vue +23 -22
- package/edit/persistentvolume/plugins/nfs.vue +15 -14
- package/edit/persistentvolume/plugins/photonPersistentDisk.vue +1 -14
- package/edit/persistentvolume/plugins/portworxVolume.vue +15 -14
- package/edit/persistentvolume/plugins/quobyte.vue +15 -14
- package/edit/persistentvolume/plugins/rbd.vue +15 -14
- package/edit/persistentvolume/plugins/scaleIO.vue +15 -14
- package/edit/persistentvolume/plugins/storageos.vue +15 -14
- package/edit/persistentvolume/plugins/vsphereVolume.vue +1 -3
- package/edit/provisioning.cattle.io.cluster/CustomCommand.vue +32 -5
- package/edit/provisioning.cattle.io.cluster/__tests__/CustomCommand.test.ts +35 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/Networking.test.ts +155 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +11 -9
- package/edit/provisioning.cattle.io.cluster/index.vue +25 -15
- package/edit/provisioning.cattle.io.cluster/rke2.vue +98 -17
- package/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig.vue +28 -2
- package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +107 -5
- package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +92 -4
- package/edit/secret/index.vue +1 -1
- package/edit/service.vue +9 -4
- package/edit/serviceaccount.vue +1 -0
- package/edit/storage.k8s.io.storageclass/index.vue +1 -0
- package/edit/workload/index.vue +2 -1
- package/edit/workload/mixins/workload.js +1 -1
- package/initialize/App.vue +4 -4
- package/initialize/install-directives.js +2 -0
- package/initialize/install-plugins.js +19 -2
- package/list/projectsecret.vue +1 -1
- package/list/provisioning.cattle.io.cluster.vue +15 -2
- package/machine-config/amazonec2.vue +42 -135
- package/machine-config/azure.vue +1 -1
- package/machine-config/components/EC2Networking.vue +490 -0
- package/machine-config/components/__tests__/EC2Networking.test.ts +148 -0
- package/machine-config/components/__tests__/utils/vpcSubnetMockData.js +294 -0
- package/machine-config/digitalocean.vue +11 -0
- package/machine-config/google.vue +1 -1
- package/mixins/__tests__/brand.spec.ts +2 -2
- package/mixins/__tests__/chart.test.ts +21 -0
- package/mixins/brand.js +1 -7
- package/mixins/chart.js +8 -2
- package/mixins/create-edit-view/index.js +5 -0
- package/models/__tests__/chart.test.ts +49 -12
- package/models/__tests__/compliance.cattle.io.clusterscanprofile.spec.js +30 -0
- package/models/__tests__/provisioning.cattle.io.cluster.test.ts +112 -5
- package/models/catalog.cattle.io.app.js +1 -1
- package/models/chart.js +28 -14
- package/models/cluster/node.js +13 -6
- package/models/cluster.x-k8s.io.machine.js +10 -20
- package/models/cluster.x-k8s.io.machinedeployment.js +5 -1
- package/models/compliance.cattle.io.clusterscanprofile.js +1 -1
- package/models/management.cattle.io.authconfig.js +1 -0
- package/models/management.cattle.io.cluster.js +21 -3
- package/models/management.cattle.io.kontainerdriver.js +1 -0
- package/models/provisioning.cattle.io.cluster.js +249 -33
- package/package.json +6 -5
- package/pages/auth/login.vue +43 -4
- package/pages/auth/verify.vue +1 -1
- package/pages/c/_cluster/apps/charts/AppChartCardSubHeader.vue +3 -2
- package/pages/c/_cluster/apps/charts/__tests__/chart.test.ts +135 -0
- package/pages/c/_cluster/apps/charts/chart.vue +35 -17
- package/pages/c/_cluster/apps/charts/index.vue +11 -13
- package/pages/c/_cluster/apps/charts/install.vue +1 -1
- package/pages/c/_cluster/explorer/EventsTable.vue +89 -3
- package/pages/c/_cluster/explorer/index.vue +8 -6
- package/pages/c/_cluster/explorer/tools/index.vue +3 -3
- package/pages/c/_cluster/manager/hostedprovider/index.vue +220 -0
- package/pages/c/_cluster/settings/brand.vue +1 -1
- package/pages/c/_cluster/settings/performance.vue +12 -25
- package/pages/c/_cluster/uiplugins/__tests__/index.test.ts +7 -0
- package/pages/c/_cluster/uiplugins/catalogs.vue +147 -0
- package/pages/c/_cluster/uiplugins/index.vue +126 -184
- package/pages/home.vue +327 -16
- package/pkg/dynamic-importer.lib.js +4 -0
- package/plugins/axios.js +2 -1
- package/plugins/dashboard-client-init.js +3 -0
- package/plugins/dashboard-store/actions.js +1 -1
- package/plugins/dashboard-store/getters.js +18 -1
- package/plugins/dashboard-store/resource-class.js +21 -6
- package/plugins/dynamic-content.js +13 -0
- package/plugins/i18n.js +8 -0
- package/plugins/steve/__tests__/steve-pagination-utils.test.ts +333 -0
- package/plugins/steve/steve-pagination-utils.ts +41 -22
- package/plugins/steve/subscribe.js +17 -9
- package/plugins/subscribe-events.ts +4 -2
- package/rancher-components/Form/Checkbox/Checkbox.vue +1 -1
- package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.vue +6 -34
- package/rancher-components/Pill/RcStatusBadge/index.ts +0 -1
- package/rancher-components/Pill/RcStatusBadge/types.ts +1 -1
- package/rancher-components/Pill/RcStatusIndicator/RcStatusIndicator.vue +5 -28
- package/rancher-components/Pill/RcStatusIndicator/types.ts +2 -1
- package/rancher-components/Pill/types.ts +0 -1
- package/rancher-components/RcDropdown/RcDropdownItem.vue +1 -0
- package/rancher-components/RcDropdown/RcDropdownItemSelect.vue +5 -1
- package/rancher-components/RcIcon/RcIcon.test.ts +51 -0
- package/rancher-components/RcIcon/RcIcon.vue +46 -0
- package/rancher-components/RcIcon/index.ts +1 -0
- package/rancher-components/RcIcon/types.ts +160 -0
- package/rancher-components/utils/status.test.ts +67 -0
- package/rancher-components/utils/status.ts +77 -0
- package/scripts/extension/publish +1 -1
- package/scripts/typegen.sh +1 -0
- package/store/action-menu.js +8 -0
- package/store/auth.js +11 -6
- package/store/aws.js +8 -6
- package/store/catalog.js +6 -0
- package/store/features.js +2 -0
- package/store/index.js +45 -20
- package/store/notifications.ts +51 -4
- package/store/plugins.js +7 -3
- package/store/prefs.js +12 -6
- package/store/type-map.js +3 -3
- package/store/ui-context.ts +86 -0
- package/store/wm.ts +244 -0
- package/types/kube/kube-api.ts +2 -1
- package/types/notifications/index.ts +27 -3
- package/types/rancher/index.d.ts +1 -0
- package/types/resources/settings.d.ts +29 -7
- package/types/shell/index.d.ts +138 -4
- package/types/store/__tests__/pagination.types.spec.ts +137 -0
- package/types/store/pagination.types.ts +157 -9
- package/types/store/subscribe-events.types.ts +8 -1
- package/types/store/subscribe.types.ts +1 -0
- package/types/window-manager.ts +24 -0
- package/utils/__tests__/cluster.test.ts +379 -1
- package/utils/__tests__/object.test.ts +19 -0
- package/utils/__tests__/provider.test.ts +98 -0
- package/utils/__tests__/selector-typed.test.ts +263 -0
- package/utils/__tests__/version.test.ts +19 -1
- package/utils/autoscaler-utils.ts +7 -0
- package/utils/back-off.ts +3 -3
- package/utils/brand.ts +29 -0
- package/utils/chart.js +18 -0
- package/utils/cluster.js +157 -3
- package/utils/color.js +1 -1
- package/utils/dynamic-content/__tests__/announcement.test.ts +498 -0
- package/utils/dynamic-content/__tests__/config.test.ts +187 -0
- package/utils/dynamic-content/__tests__/index.test.ts +390 -0
- package/utils/dynamic-content/__tests__/info.test.ts +275 -0
- package/utils/dynamic-content/__tests__/new-release.test.ts +216 -0
- package/utils/dynamic-content/__tests__/support-notice.test.ts +262 -0
- package/utils/dynamic-content/__tests__/util.test.ts +235 -0
- package/utils/dynamic-content/announcement.ts +142 -0
- package/utils/dynamic-content/config.ts +55 -0
- package/utils/dynamic-content/example.json +40 -0
- package/utils/dynamic-content/index.ts +277 -0
- package/utils/dynamic-content/info.ts +261 -0
- package/utils/dynamic-content/new-release.ts +126 -0
- package/utils/dynamic-content/notification-handler.ts +48 -0
- package/utils/dynamic-content/support-notice.ts +169 -0
- package/utils/dynamic-content/types.d.ts +153 -0
- package/utils/dynamic-content/util.ts +122 -0
- package/utils/dynamic-importer.js +2 -2
- package/utils/favicon.js +4 -4
- package/utils/inactivity.ts +104 -0
- package/utils/object.js +20 -2
- package/utils/pagination-utils.ts +19 -4
- package/utils/pagination-wrapper.ts +12 -8
- package/utils/provider.ts +14 -0
- package/utils/release-notes.ts +1 -1
- package/utils/scroll.js +7 -0
- package/utils/selector-typed.ts +6 -2
- package/utils/settings.ts +15 -0
- package/utils/validators/machine-pool.ts +13 -3
- package/utils/version.js +15 -0
- package/assets/images/icons/document.svg +0 -3
- package/plugins/nuxt-client-init.js +0 -3
- package/store/wm.js +0 -95
- /package/components/{nav/WindowManager → Window}/ChartReadme.vue +0 -0
- /package/components/{nav/WindowManager → Window}/ContainerShell.vue +0 -0
- /package/components/{nav/WindowManager → Window}/KubectlShell.vue +0 -0
- /package/components/{nav/WindowManager → Window}/MachineSsh.vue +0 -0
- /package/components/{nav/WindowManager → Window}/Window.vue +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { abbreviateClusterName } from '@shell/utils/cluster';
|
|
1
|
+
import { abbreviateClusterName, _addonConfigPreserveFilter, addonConfigPreserve } from '@shell/utils/cluster';
|
|
2
|
+
import { diff } from '@shell/utils/object';
|
|
2
3
|
|
|
3
4
|
describe('fx: abbreviateClusterName', () => {
|
|
4
5
|
it.each([
|
|
@@ -55,3 +56,380 @@ describe('fx: abbreviateClusterName', () => {
|
|
|
55
56
|
expect(result).toStrictEqual(expected);
|
|
56
57
|
});
|
|
57
58
|
});
|
|
59
|
+
|
|
60
|
+
describe('fx: _addonConfigPreserveFilter', () => {
|
|
61
|
+
it('should return an empty object if there are no differences between default values', () => {
|
|
62
|
+
const oldDefaults = { replicaCount: 1 };
|
|
63
|
+
const newDefaults = { replicaCount: 1 };
|
|
64
|
+
const userVals = { replicaCount: 3 };
|
|
65
|
+
const diffs = diff(oldDefaults, newDefaults);
|
|
66
|
+
const expected = {};
|
|
67
|
+
|
|
68
|
+
expect(_addonConfigPreserveFilter(diffs, userVals)).toStrictEqual(expected);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('should return an empty object if no user values are provided', () => {
|
|
72
|
+
const oldDefaults = { replicaCount: 1 };
|
|
73
|
+
const newDefaults = { replicaCount: 2 };
|
|
74
|
+
const userVals = {};
|
|
75
|
+
const diffs = diff(oldDefaults, newDefaults);
|
|
76
|
+
const expected = {};
|
|
77
|
+
|
|
78
|
+
expect(_addonConfigPreserveFilter(diffs, userVals)).toStrictEqual(expected);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('should filter out diffs for fields not customized by the user', () => {
|
|
82
|
+
const oldDefaults = {
|
|
83
|
+
replicaCount: 1,
|
|
84
|
+
persistence: false
|
|
85
|
+
};
|
|
86
|
+
const newDefaults = {
|
|
87
|
+
replicaCount: 2,
|
|
88
|
+
persistence: true
|
|
89
|
+
};
|
|
90
|
+
const userVals = { replicaCount: 3 };
|
|
91
|
+
const diffs = diff(oldDefaults, newDefaults);
|
|
92
|
+
const expected = { replicaCount: 2 };
|
|
93
|
+
|
|
94
|
+
expect(_addonConfigPreserveFilter(diffs, userVals)).toStrictEqual(expected);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('should include diffs for fields customized by the user', () => {
|
|
98
|
+
const oldDefaults = { replicaCount: 1 };
|
|
99
|
+
const newDefaults = { replicaCount: 2 };
|
|
100
|
+
const userVals = { replicaCount: 3 };
|
|
101
|
+
const diffs = diff(oldDefaults, newDefaults);
|
|
102
|
+
const expected = { replicaCount: 2 };
|
|
103
|
+
|
|
104
|
+
expect(_addonConfigPreserveFilter(diffs, userVals)).toStrictEqual(expected);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('should handle nested objects: include diff if user customized nested property', () => {
|
|
108
|
+
const oldDefaults = { service: { port: 80 } };
|
|
109
|
+
const newDefaults = { service: { port: 8080 } };
|
|
110
|
+
const userVals = { service: { port: 9000 } };
|
|
111
|
+
const diffs = diff(oldDefaults, newDefaults);
|
|
112
|
+
const expected = { service: { port: 8080 } };
|
|
113
|
+
|
|
114
|
+
expect(_addonConfigPreserveFilter(diffs, userVals)).toStrictEqual(expected);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('should handle nested objects: exclude diff if user did not customize nested property', () => {
|
|
118
|
+
const oldDefaults = { service: { port: 80, type: 'ClusterIP' } };
|
|
119
|
+
const newDefaults = { service: { port: 8080, type: 'ClusterIP' } };
|
|
120
|
+
const userVals = { service: { type: 'NodePort' } };
|
|
121
|
+
const diffs = diff(oldDefaults, newDefaults);
|
|
122
|
+
const expected = {};
|
|
123
|
+
|
|
124
|
+
expect(_addonConfigPreserveFilter(diffs, userVals)).toStrictEqual(expected);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it('should handle nested objects: include diff if user customized a removed nested object', () => {
|
|
128
|
+
const oldDefaults = { service: { port: 80 } };
|
|
129
|
+
const newDefaults = {};
|
|
130
|
+
const userVals = { service: { port: 9000 } };
|
|
131
|
+
const diffs = diff(oldDefaults, newDefaults);
|
|
132
|
+
const expected = { service: { port: null } };
|
|
133
|
+
|
|
134
|
+
expect(_addonConfigPreserveFilter(diffs, userVals)).toStrictEqual(expected);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it('should handle nested objects: exclude diff if a new property is added to default nested object and user did not customize it', () => {
|
|
138
|
+
const oldDefaults = { service: { port: 80 } };
|
|
139
|
+
const newDefaults = { service: { port: 80, type: 'ClusterIP' } };
|
|
140
|
+
const userVals = { service: { port: 80 } };
|
|
141
|
+
const diffs = diff(oldDefaults, newDefaults);
|
|
142
|
+
const expected = {};
|
|
143
|
+
|
|
144
|
+
expect(_addonConfigPreserveFilter(diffs, userVals)).toStrictEqual(expected);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('should handle arrays of primitives: include diff if user customized array and default array changed', () => {
|
|
148
|
+
const oldDefaults = { ingress: { hosts: ['host1.com', 'host2.com'] } };
|
|
149
|
+
const newDefaults = { ingress: { hosts: ['host1.com', 'host3.com'] } };
|
|
150
|
+
const userVals = { ingress: { hosts: ['user.host.com'] } };
|
|
151
|
+
const diffs = diff(oldDefaults, newDefaults);
|
|
152
|
+
const expected = { ingress: { hosts: ['host1.com', 'host3.com'] } };
|
|
153
|
+
|
|
154
|
+
expect(_addonConfigPreserveFilter(diffs, userVals)).toStrictEqual(expected);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it('should handle arrays of primitives: exclude diff if user did not customize array', () => {
|
|
158
|
+
const oldDefaults = { ingress: { hosts: ['host1.com', 'host2.com'] } };
|
|
159
|
+
const newDefaults = { ingress: { hosts: ['host1.com', 'host3.com'] } };
|
|
160
|
+
const userVals = { ingress: { enabled: true } };
|
|
161
|
+
const diffs = diff(oldDefaults, newDefaults);
|
|
162
|
+
const expected = {};
|
|
163
|
+
|
|
164
|
+
expect(_addonConfigPreserveFilter(diffs, userVals)).toStrictEqual(expected);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('should handle arrays of objects: include diff if user customized array and default array changed', () => {
|
|
168
|
+
const oldDefaults = { service: { ports: [{ name: 'http', port: 80 }] } };
|
|
169
|
+
const newDefaults = { service: { ports: [{ name: 'http', port: 80 }, { name: 'https', port: 443 }] } };
|
|
170
|
+
const userVals = { service: { ports: [{ name: 'http', port: 8080 }] } };
|
|
171
|
+
const diffs = diff(oldDefaults, newDefaults);
|
|
172
|
+
const expected = { service: { ports: [{ name: 'http', port: 80 }, { name: 'https', port: 443 }] } };
|
|
173
|
+
|
|
174
|
+
expect(_addonConfigPreserveFilter(diffs, userVals)).toStrictEqual(expected);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it('should handle arrays of objects: exclude diff if user did not customize array', () => {
|
|
178
|
+
const oldDefaults = { service: { ports: [{ name: 'http', port: 80 }] } };
|
|
179
|
+
const newDefaults = { service: { ports: [{ name: 'http', port: 80 }, { name: 'https', port: 443 }] } };
|
|
180
|
+
const userVals = { service: { type: 'ClusterIP' } };
|
|
181
|
+
const diffs = diff(oldDefaults, newDefaults);
|
|
182
|
+
const expected = {};
|
|
183
|
+
|
|
184
|
+
expect(_addonConfigPreserveFilter(diffs, userVals)).toStrictEqual(expected);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it('should handle properties added/removed: include diff if user customized a removed property', () => {
|
|
188
|
+
const oldDefaults = { oldProperty: 'defaultValue' };
|
|
189
|
+
const newDefaults = {};
|
|
190
|
+
const userVals = { oldProperty: 'customValue' };
|
|
191
|
+
const diffs = diff(oldDefaults, newDefaults);
|
|
192
|
+
const expected = { oldProperty: null };
|
|
193
|
+
|
|
194
|
+
expect(_addonConfigPreserveFilter(diffs, userVals)).toStrictEqual(expected);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it('should handle properties added/removed: exclude diff if user did not customize an added property', () => {
|
|
198
|
+
const oldDefaults = {};
|
|
199
|
+
const newDefaults = { newProperty: 'defaultValue' };
|
|
200
|
+
const userVals = { otherProp: 'value' };
|
|
201
|
+
const diffs = diff(oldDefaults, newDefaults);
|
|
202
|
+
const expected = {};
|
|
203
|
+
|
|
204
|
+
expect(_addonConfigPreserveFilter(diffs, userVals)).toStrictEqual(expected);
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
it('should handle complex nested structures with multiple changes', () => {
|
|
208
|
+
const oldDefaults = {
|
|
209
|
+
replicaCount: 1,
|
|
210
|
+
image: {
|
|
211
|
+
repository: 'nginx',
|
|
212
|
+
tag: 'stable'
|
|
213
|
+
},
|
|
214
|
+
service: {
|
|
215
|
+
type: 'ClusterIP',
|
|
216
|
+
port: 80
|
|
217
|
+
},
|
|
218
|
+
ingress: {
|
|
219
|
+
enabled: false,
|
|
220
|
+
hosts: ['chart-example.local']
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
const newDefaults = {
|
|
224
|
+
replicaCount: 2,
|
|
225
|
+
image: {
|
|
226
|
+
repository: 'nginx',
|
|
227
|
+
tag: 'mainline'
|
|
228
|
+
},
|
|
229
|
+
service: {
|
|
230
|
+
type: 'ClusterIP',
|
|
231
|
+
port: 80
|
|
232
|
+
},
|
|
233
|
+
ingress: {
|
|
234
|
+
enabled: true,
|
|
235
|
+
hosts: ['chart-example.local', 'new.chart-example.local'],
|
|
236
|
+
tls: true
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
const userVals = {
|
|
240
|
+
replicaCount: 3,
|
|
241
|
+
ingress: { hosts: ['my.custom.host'] }
|
|
242
|
+
};
|
|
243
|
+
const diffs = diff(oldDefaults, newDefaults);
|
|
244
|
+
const expected = {
|
|
245
|
+
replicaCount: 2,
|
|
246
|
+
ingress: { hosts: ['chart-example.local', 'new.chart-example.local'] }
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
expect(_addonConfigPreserveFilter(diffs, userVals)).toStrictEqual(expected);
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
describe('fx: addonConfigPreserve', () => {
|
|
254
|
+
const ADDON_NAME = 'rke2-my-addon';
|
|
255
|
+
const mockOldVersionCharts = {
|
|
256
|
+
[ADDON_NAME]: {
|
|
257
|
+
repo: 'repo',
|
|
258
|
+
version: '1.0.0'
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
const mockNewVersionCharts = {
|
|
263
|
+
[ADDON_NAME]: {
|
|
264
|
+
repo: 'repo',
|
|
265
|
+
version: '1.1.0'
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
const mockOldVersionInfo = {
|
|
270
|
+
values: {
|
|
271
|
+
replicas: 1,
|
|
272
|
+
service: { type: 'ClusterIP' }
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
const mockNewVersionInfo = {
|
|
277
|
+
values: {
|
|
278
|
+
replicas: 2, // changed
|
|
279
|
+
service: { type: 'ClusterIP' },
|
|
280
|
+
persistence: true // new
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
let mockStore: any;
|
|
285
|
+
let addonConfigDiffs: any;
|
|
286
|
+
let userChartValues: any;
|
|
287
|
+
let context: any;
|
|
288
|
+
|
|
289
|
+
beforeEach(() => {
|
|
290
|
+
mockStore = {
|
|
291
|
+
dispatch: jest.fn((action, payload) => {
|
|
292
|
+
if (action === 'catalog/getVersionInfo') {
|
|
293
|
+
if (payload.versionName === '1.0.0') {
|
|
294
|
+
return Promise.resolve(mockOldVersionInfo);
|
|
295
|
+
}
|
|
296
|
+
if (payload.versionName === '1.1.0') {
|
|
297
|
+
return Promise.resolve(mockNewVersionInfo);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return Promise.resolve({});
|
|
302
|
+
})
|
|
303
|
+
};
|
|
304
|
+
addonConfigDiffs = {};
|
|
305
|
+
userChartValues = {};
|
|
306
|
+
context = {
|
|
307
|
+
addonConfigDiffs,
|
|
308
|
+
addonNames: [ADDON_NAME],
|
|
309
|
+
$store: mockStore,
|
|
310
|
+
userChartValues,
|
|
311
|
+
};
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
it('should identify no relevant changes if user has no custom values', async() => {
|
|
315
|
+
// No user overrides means no relevant differences.
|
|
316
|
+
context.userChartValues = {};
|
|
317
|
+
await addonConfigPreserve(context, mockOldVersionCharts, mockNewVersionCharts);
|
|
318
|
+
|
|
319
|
+
expect(context.addonConfigDiffs[ADDON_NAME]).toStrictEqual({});
|
|
320
|
+
expect(context.userChartValues[`${ ADDON_NAME }-1.1.0`]).toBeUndefined();
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
it('should identify no relevant changes if user custom values are for different fields', async() => {
|
|
324
|
+
// User overrides for non-differing fields should not be considered relevant.
|
|
325
|
+
context.userChartValues = { [`${ ADDON_NAME }-1.0.0`]: { service: { type: 'NodePort' } } };
|
|
326
|
+
await addonConfigPreserve(context, mockOldVersionCharts, mockNewVersionCharts);
|
|
327
|
+
|
|
328
|
+
expect(context.addonConfigDiffs[ADDON_NAME]).toStrictEqual({});
|
|
329
|
+
// Since diffs are empty, user values should be preserved
|
|
330
|
+
expect(context.userChartValues[`${ ADDON_NAME }-1.1.0`]).toStrictEqual({ service: { type: 'NodePort' } });
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
it('should identify relevant changes if user has customized a changed field', async() => {
|
|
334
|
+
// A user override on a changed default should be flagged as a relevant difference.
|
|
335
|
+
context.userChartValues = { [`${ ADDON_NAME }-1.0.0`]: { replicas: 3 } };
|
|
336
|
+
await addonConfigPreserve(context, mockOldVersionCharts, mockNewVersionCharts);
|
|
337
|
+
|
|
338
|
+
expect(context.addonConfigDiffs[ADDON_NAME]).toStrictEqual({ replicas: 2 });
|
|
339
|
+
// Since diffs are NOT empty, user values should NOT be preserved
|
|
340
|
+
expect(context.userChartValues[`${ ADDON_NAME }-1.1.0`]).toBeUndefined();
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
it('should not identify relevant changes for new fields not customized by user', async() => {
|
|
344
|
+
// New fields in the addon default values are not relevant if not customized by the user.
|
|
345
|
+
context.userChartValues = { [`${ ADDON_NAME }-1.0.0`]: {} };
|
|
346
|
+
await addonConfigPreserve(context, mockOldVersionCharts, mockNewVersionCharts);
|
|
347
|
+
|
|
348
|
+
// The only diff is `replicas`, which user didn't touch. `persistence` is new but also not touched.
|
|
349
|
+
// So final diffs should be empty.
|
|
350
|
+
expect(context.addonConfigDiffs[ADDON_NAME]).toStrictEqual({});
|
|
351
|
+
expect(context.userChartValues[`${ ADDON_NAME }-1.1.0`]).toStrictEqual({});
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
it('should preserve user values if there are no relevant differences', async() => {
|
|
355
|
+
// User values should be carried over to the new version if no relevant diffs are found.
|
|
356
|
+
context.userChartValues = { [`${ ADDON_NAME }-1.0.0`]: { service: { type: 'NodePort' } } };
|
|
357
|
+
await addonConfigPreserve(context, mockOldVersionCharts, mockNewVersionCharts);
|
|
358
|
+
|
|
359
|
+
expect(context.addonConfigDiffs[ADDON_NAME]).toStrictEqual({});
|
|
360
|
+
expect(context.userChartValues[`${ ADDON_NAME }-1.1.0`]).toStrictEqual({ service: { type: 'NodePort' } });
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
it('should not preserve user values if there are relevant differences', async() => {
|
|
364
|
+
// User values should not be carried over if relevant diffs are found.
|
|
365
|
+
context.userChartValues = { [`${ ADDON_NAME }-1.0.0`]: { replicas: 3 } };
|
|
366
|
+
await addonConfigPreserve(context, mockOldVersionCharts, mockNewVersionCharts);
|
|
367
|
+
|
|
368
|
+
expect(context.addonConfigDiffs[ADDON_NAME]).toStrictEqual({ replicas: 2 });
|
|
369
|
+
expect(context.userChartValues[`${ ADDON_NAME }-1.1.0`]).toBeUndefined();
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
it('should handle catalog API errors gracefully', async() => {
|
|
373
|
+
// Errors from fetching chart info should be caught and handled.
|
|
374
|
+
const error = new Error('catalog fetch failed');
|
|
375
|
+
|
|
376
|
+
jest.spyOn(context.$store, 'dispatch').mockImplementation().mockRejectedValue(error);
|
|
377
|
+
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => { });
|
|
378
|
+
|
|
379
|
+
await addonConfigPreserve(context, mockOldVersionCharts, mockNewVersionCharts);
|
|
380
|
+
|
|
381
|
+
expect(context.addonConfigDiffs[ADDON_NAME]).toBeUndefined();
|
|
382
|
+
expect(errorSpy).toHaveBeenCalledWith(`Failed to get chart version info for diff for chart ${ ADDON_NAME }`, error);
|
|
383
|
+
errorSpy.mockRestore();
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
it('should do nothing if oldCharts is not provided', async() => {
|
|
387
|
+
await addonConfigPreserve(context, {}, mockNewVersionCharts);
|
|
388
|
+
expect(context.addonConfigDiffs).toStrictEqual({});
|
|
389
|
+
expect(mockStore.dispatch).not.toHaveBeenCalled();
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
it('should do nothing if newCharts is not provided', async() => {
|
|
393
|
+
await addonConfigPreserve(context, mockOldVersionCharts, {});
|
|
394
|
+
expect(context.addonConfigDiffs).toStrictEqual({});
|
|
395
|
+
expect(mockStore.dispatch).not.toHaveBeenCalled();
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
it('should do nothing if addon version is the same', async() => {
|
|
399
|
+
const mockNewVersionSame = {
|
|
400
|
+
[ADDON_NAME]: {
|
|
401
|
+
repo: 'repo',
|
|
402
|
+
version: '1.0.0'
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
await addonConfigPreserve(context, mockOldVersionCharts, mockNewVersionSame);
|
|
407
|
+
expect(context.addonConfigDiffs[ADDON_NAME]).toBeUndefined();
|
|
408
|
+
expect(mockStore.dispatch).not.toHaveBeenCalled();
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
it('should handle multiple addons', async() => {
|
|
412
|
+
const ADDON2_NAME = 'rke2-my-addon2';
|
|
413
|
+
const ADDON3_NAME = 'rke2-my-addon3'; // same version
|
|
414
|
+
|
|
415
|
+
const oldCharts = {
|
|
416
|
+
...mockOldVersionCharts,
|
|
417
|
+
[ADDON2_NAME]: { repo: 'repo', version: '1.0.0' },
|
|
418
|
+
[ADDON3_NAME]: { repo: 'repo', version: '1.0.0' },
|
|
419
|
+
};
|
|
420
|
+
const newCharts = {
|
|
421
|
+
...mockNewVersionCharts,
|
|
422
|
+
[ADDON2_NAME]: { repo: 'repo', version: '1.1.0' }, // changed version, but no user values
|
|
423
|
+
[ADDON3_NAME]: { repo: 'repo', version: '1.0.0' }, // same version
|
|
424
|
+
};
|
|
425
|
+
|
|
426
|
+
context.addonNames = [ADDON_NAME, ADDON2_NAME, ADDON3_NAME];
|
|
427
|
+
context.userChartValues = { [`${ ADDON_NAME }-1.0.0`]: { replicas: 3 } };
|
|
428
|
+
|
|
429
|
+
await addonConfigPreserve(context, oldCharts, newCharts);
|
|
430
|
+
|
|
431
|
+
expect(context.addonConfigDiffs[ADDON_NAME]).toStrictEqual({ replicas: 2 });
|
|
432
|
+
expect(context.addonConfigDiffs[ADDON2_NAME]).toStrictEqual({});
|
|
433
|
+
expect(context.addonConfigDiffs[ADDON3_NAME]).toBeUndefined();
|
|
434
|
+
});
|
|
435
|
+
});
|
|
@@ -182,6 +182,25 @@ describe('fx: diff', () => {
|
|
|
182
182
|
|
|
183
183
|
expect(result).toStrictEqual(expected);
|
|
184
184
|
});
|
|
185
|
+
it('should return an object with property "baz" different than "null" if using the flag "preventNull" as true', () => {
|
|
186
|
+
const from = {
|
|
187
|
+
foo: 'bar',
|
|
188
|
+
baz: 'bang',
|
|
189
|
+
};
|
|
190
|
+
const to = {
|
|
191
|
+
foo: 'bar',
|
|
192
|
+
bang: 'baz'
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
const result = diff(from, to, true);
|
|
196
|
+
const expected = {
|
|
197
|
+
// the property "baz" having value !== null covers test case for https://github.com/rancher/dashboard/issues/15710
|
|
198
|
+
baz: 'bang',
|
|
199
|
+
bang: 'baz'
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
expect(result).toStrictEqual(expected);
|
|
203
|
+
});
|
|
185
204
|
it('should return an object and dot characters in object should still be respected', () => {
|
|
186
205
|
const from = {};
|
|
187
206
|
const to = { foo: { 'bar.baz': 'bang' } };
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { getHostedProviders, isHostedProvider } from '../provider';
|
|
2
|
+
import { ClusterProvisionerContext, IClusterProvisioner } from '@shell/core/types';
|
|
3
|
+
|
|
4
|
+
const DEFAULT_CONTEXT = {
|
|
5
|
+
dispatch: {},
|
|
6
|
+
getters: {},
|
|
7
|
+
axios: {},
|
|
8
|
+
t: (args: any) => args.join(' '),
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const MOCK_PROVIDERS: IClusterProvisioner[] = [
|
|
12
|
+
{ id: 'AKS', group: 'hosted' } as IClusterProvisioner,
|
|
13
|
+
{ id: 'EKS', group: 'hosted' } as IClusterProvisioner,
|
|
14
|
+
{ id: 'GKE', group: 'hosted' } as IClusterProvisioner,
|
|
15
|
+
{ id: 'alibaba', group: 'hosted' } as IClusterProvisioner,
|
|
16
|
+
{ id: 'other', group: 'other' } as IClusterProvisioner,
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
describe('utils/provider', () => {
|
|
20
|
+
describe('getHostedProviders', () => {
|
|
21
|
+
it('should return an empty array when context.$extension is undefined', () => {
|
|
22
|
+
const context = { ...DEFAULT_CONTEXT } as ClusterProvisionerContext;
|
|
23
|
+
const result = getHostedProviders(context);
|
|
24
|
+
|
|
25
|
+
expect(result).toStrictEqual([]);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('should return hosted providers when context.$extension is defined', () => {
|
|
29
|
+
const context = {
|
|
30
|
+
...DEFAULT_CONTEXT,
|
|
31
|
+
$extension: { getProviders: jest.fn().mockReturnValue(MOCK_PROVIDERS) }
|
|
32
|
+
} as unknown as ClusterProvisionerContext;
|
|
33
|
+
|
|
34
|
+
const result = getHostedProviders(context);
|
|
35
|
+
|
|
36
|
+
expect(result).toStrictEqual([
|
|
37
|
+
{ id: 'AKS', group: 'hosted' },
|
|
38
|
+
{ id: 'EKS', group: 'hosted' },
|
|
39
|
+
{ id: 'GKE', group: 'hosted' },
|
|
40
|
+
{ id: 'alibaba', group: 'hosted' },
|
|
41
|
+
]);
|
|
42
|
+
expect(context.$extension.getProviders).toHaveBeenCalledWith(context);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('should return an empty array if getProviders returns null', () => {
|
|
46
|
+
const context = {
|
|
47
|
+
...DEFAULT_CONTEXT,
|
|
48
|
+
$extension: { getProviders: jest.fn().mockReturnValue(null) }
|
|
49
|
+
} as unknown as ClusterProvisionerContext;
|
|
50
|
+
|
|
51
|
+
const result = getHostedProviders(context);
|
|
52
|
+
|
|
53
|
+
expect(result).toStrictEqual([]);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should return an empty array if getProviders returns undefined', () => {
|
|
57
|
+
const context = {
|
|
58
|
+
...DEFAULT_CONTEXT,
|
|
59
|
+
$extension: { getProviders: jest.fn().mockReturnValue(undefined) }
|
|
60
|
+
} as unknown as ClusterProvisionerContext;
|
|
61
|
+
|
|
62
|
+
const result = getHostedProviders(context);
|
|
63
|
+
|
|
64
|
+
expect(result).toStrictEqual([]);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
describe('isHostedProvider', () => {
|
|
69
|
+
it('should return false if provisioner is not provided', () => {
|
|
70
|
+
const context = {
|
|
71
|
+
...DEFAULT_CONTEXT,
|
|
72
|
+
$extension: { getProviders: jest.fn().mockReturnValue(MOCK_PROVIDERS) }
|
|
73
|
+
} as ClusterProvisionerContext;
|
|
74
|
+
|
|
75
|
+
expect(isHostedProvider(context, '')).toBe(false);
|
|
76
|
+
expect(isHostedProvider(context, undefined as any)).toBe(false);
|
|
77
|
+
expect(isHostedProvider(context, null as any)).toBe(false);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('should return true only if provisioner is in the list of hosted providers', () => {
|
|
81
|
+
const context = {
|
|
82
|
+
...DEFAULT_CONTEXT,
|
|
83
|
+
$extension: { getProviders: jest.fn().mockReturnValue(MOCK_PROVIDERS) }
|
|
84
|
+
} as ClusterProvisionerContext;
|
|
85
|
+
|
|
86
|
+
expect(isHostedProvider(context, 'AKS')).toBe(true);
|
|
87
|
+
expect(isHostedProvider(context, 'eks')).toBe(true);
|
|
88
|
+
expect(isHostedProvider(context, 'different')).toBe(false); // case-insensitive check
|
|
89
|
+
expect(isHostedProvider(context, 'other')).toBe(false); // case-insensitive check
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('should return false if there are no hosted providers', () => {
|
|
93
|
+
const context = { ...DEFAULT_CONTEXT, $extension: { getProviders: jest.fn().mockReturnValue([]) } } as ClusterProvisionerContext;
|
|
94
|
+
|
|
95
|
+
expect(isHostedProvider(context, 'prov1')).toBe(false);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
});
|