@rancher/shell 3.0.5-rc.3 → 3.0.5-rc.6
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/data/aws-regions.json +1 -0
- package/assets/images/icons/document.svg +3 -0
- package/assets/images/key.svg +17 -0
- package/assets/images/vendor/cognito.svg +1 -0
- package/assets/styles/app.scss +1 -0
- package/assets/styles/base/_basic.scss +10 -0
- package/assets/styles/base/_spacing.scss +29 -0
- package/assets/styles/global/_form.scss +1 -1
- package/assets/styles/global/_labeled-input.scss +1 -1
- package/assets/styles/global/_layout.scss +1 -1
- package/assets/styles/themes/_dark.scss +28 -0
- package/assets/styles/themes/_light.scss +68 -0
- package/assets/styles/vendor/vue-select.scss +1 -1
- package/assets/translations/en-us.yaml +721 -83
- package/assets/translations/zh-hans.yaml +11 -9
- package/cloud-credential/gcp.vue +9 -1
- package/components/AppModal.vue +2 -0
- package/components/Certificates.vue +5 -0
- package/components/CodeMirror.vue +1 -1
- package/components/ConfigMapSettings/Settings.vue +377 -0
- package/components/ConfigMapSettings/index.vue +354 -0
- package/components/CruResource.vue +1 -2
- package/components/DetailText.vue +61 -11
- package/components/Drawer/Chrome.vue +116 -0
- package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +61 -0
- package/components/Drawer/ResourceDetailDrawer/YamlTab.vue +48 -0
- package/components/Drawer/ResourceDetailDrawer/__tests__/ConfigTab.test.ts +54 -0
- package/components/Drawer/ResourceDetailDrawer/__tests__/YamlTab.test.ts +80 -0
- package/components/Drawer/ResourceDetailDrawer/__tests__/composables.test.ts +82 -0
- package/components/Drawer/ResourceDetailDrawer/__tests__/helpers.test.ts +42 -0
- package/components/Drawer/ResourceDetailDrawer/composables.ts +50 -0
- package/components/Drawer/ResourceDetailDrawer/helpers.ts +10 -0
- package/components/Drawer/ResourceDetailDrawer/index.vue +110 -0
- package/components/FilterPanel.vue +156 -0
- package/components/{fleet/ForceDirectedTreeChart/index.vue → ForceDirectedTreeChart.vue} +47 -41
- package/components/GrowlManager.vue +16 -15
- package/components/IconOrSvg.vue +19 -35
- package/components/KeyValueView.vue +1 -1
- package/components/LocaleSelector.vue +9 -1
- package/components/ProgressBarMulti.vue +1 -0
- package/components/PromptModal.vue +6 -1
- package/components/PromptRemove.vue +5 -1
- package/components/RelatedResources.vue +4 -12
- package/components/Resource/Detail/Additional.vue +46 -0
- package/components/Resource/Detail/Card/PodsCard/Bubble.vue +13 -0
- package/components/Resource/Detail/Card/PodsCard/composable.ts +30 -0
- package/components/Resource/Detail/Card/PodsCard/index.vue +118 -0
- package/components/Resource/Detail/Card/ResourceUsageCard/composable.ts +51 -0
- package/components/Resource/Detail/Card/ResourceUsageCard/index.vue +79 -0
- package/components/Resource/Detail/Card/Scaler.vue +89 -0
- package/components/Resource/Detail/Card/StateCard/composables.ts +112 -0
- package/components/Resource/Detail/Card/StateCard/index.vue +39 -0
- package/components/Resource/Detail/Card/VerticalGap.vue +11 -0
- package/components/Resource/Detail/Card/__tests__/Card.test.ts +36 -0
- package/components/Resource/Detail/Card/__tests__/PodsCard.test.ts +84 -0
- package/components/Resource/Detail/Card/__tests__/ResourceUsageCard.test.ts +72 -0
- package/components/Resource/Detail/Card/__tests__/Scaler.test.ts +87 -0
- package/components/Resource/Detail/Card/__tests__/StateCard.test.ts +53 -0
- package/components/Resource/Detail/Card/__tests__/VerticalGap.test.ts +14 -0
- package/components/Resource/Detail/Card/__tests__/index.test.ts +36 -0
- package/components/Resource/Detail/Card/index.vue +56 -0
- package/components/Resource/Detail/Metadata/Annotations/__tests__/index.test.ts +19 -0
- package/components/Resource/Detail/Metadata/Annotations/composable.ts +12 -0
- package/components/Resource/Detail/Metadata/Annotations/index.vue +31 -0
- package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/identifying-fields.test.ts +223 -0
- package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/index.test.ts +103 -0
- package/components/Resource/Detail/Metadata/IdentifyingInformation/composable.ts +64 -0
- package/components/Resource/Detail/Metadata/IdentifyingInformation/identifying-fields.ts +298 -0
- package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +133 -0
- package/components/Resource/Detail/Metadata/KeyValue.vue +138 -0
- package/components/Resource/Detail/Metadata/Labels/__tests__/index.test.ts +18 -0
- package/components/Resource/Detail/Metadata/Labels/composable.ts +12 -0
- package/components/Resource/Detail/Metadata/Labels/index.vue +31 -0
- package/components/Resource/Detail/Metadata/Rectangle.vue +32 -0
- package/components/Resource/Detail/Metadata/__tests__/KeyValue.test.ts +107 -0
- package/components/Resource/Detail/Metadata/__tests__/Rectangle.test.ts +24 -0
- package/components/Resource/Detail/Metadata/__tests__/composables.test.ts +75 -0
- package/components/Resource/Detail/Metadata/__tests__/index.test.ts +91 -0
- package/components/Resource/Detail/Metadata/composables.ts +78 -0
- package/components/Resource/Detail/Metadata/index.vue +73 -0
- package/components/Resource/Detail/Page.vue +37 -0
- package/components/Resource/Detail/PercentageBar.vue +40 -0
- package/components/Resource/Detail/ResourceRow.vue +138 -0
- package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/__tests__/composables.test.ts +29 -0
- package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/__tests__/index.test.ts +48 -0
- package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/composables.ts +31 -0
- package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/index.vue +50 -0
- package/components/Resource/Detail/ResourceTabs/KnownHostsTab/__tests__/composables.test.ts +66 -0
- package/components/Resource/Detail/ResourceTabs/KnownHostsTab/composables.ts +21 -0
- package/components/Resource/Detail/ResourceTabs/KnownHostsTab/index.vue +31 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/Basic.vue +45 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/BasicAuth.vue +31 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/Certificate.vue +31 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/Registry.vue +22 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/ServiceAccountToken.vue +31 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/Ssh.vue +32 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Basic.test.ts +40 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/BasicAuth.test.ts +33 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Certificate.test.ts +33 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Registry.test.ts +27 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/ServiceAccountToken.test.ts +33 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Ssh.test.ts +33 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/auth-types.test.ts +186 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/composables.test.ts +102 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/auth-types.ts +109 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/composeables.ts +52 -0
- package/components/Resource/Detail/ResourceTabs/SecretDataTab/index.vue +71 -0
- package/components/Resource/Detail/SpacedRow.vue +14 -0
- package/components/Resource/Detail/StatusBar.vue +59 -0
- package/components/Resource/Detail/StatusRow.vue +61 -0
- package/components/Resource/Detail/TitleBar/Title.vue +14 -0
- package/components/Resource/Detail/TitleBar/Top.vue +14 -0
- package/components/Resource/Detail/TitleBar/__tests__/Title.test.ts +17 -0
- package/components/Resource/Detail/TitleBar/__tests__/Top.test.ts +17 -0
- package/components/Resource/Detail/TitleBar/__tests__/composables.test.ts +63 -0
- package/components/Resource/Detail/TitleBar/__tests__/index.test.ts +142 -0
- package/components/Resource/Detail/TitleBar/composables.ts +44 -0
- package/components/Resource/Detail/TitleBar/index.vue +196 -0
- package/components/Resource/Detail/Top/index.vue +34 -0
- package/components/Resource/Detail/__tests__/Page.test.ts +32 -0
- package/components/Resource/Detail/composables.ts +45 -0
- package/components/ResourceDetail/Masthead/__tests__/index.test.ts +70 -0
- package/components/ResourceDetail/{__tests__/Masthead.test.ts → Masthead/__tests__/legacy.test.ts} +3 -3
- package/components/ResourceDetail/Masthead/index.vue +65 -0
- package/components/ResourceDetail/Masthead/latest.vue +44 -0
- package/components/ResourceDetail/__tests__/index.test.ts +135 -0
- package/components/ResourceDetail/index.vue +73 -557
- package/components/ResourceDetail/legacy.vue +562 -0
- package/components/ResourceList/Masthead.vue +6 -0
- package/components/ResourceTable.vue +41 -7
- package/components/ResourceYaml.vue +14 -1
- package/components/SlideInPanelManager.vue +117 -10
- package/components/SortableTable/index.vue +13 -2
- package/components/SortableTable/selection.js +21 -8
- package/components/StateDot/index.vue +28 -0
- package/components/StatusBadge.vue +6 -4
- package/components/SubtleLink.vue +25 -0
- package/components/Tabbed/index.vue +11 -15
- package/components/Wizard.vue +16 -3
- package/components/YamlEditor.vue +1 -1
- package/components/__tests__/ConfigMapSettings.test.ts +376 -0
- package/components/__tests__/FilterPanel.test.ts +81 -0
- package/components/__tests__/GrowlManager.test.ts +0 -25
- package/components/auth/AuthBanner.vue +2 -3
- package/components/auth/RoleDetailEdit.vue +45 -3
- package/components/auth/login/ldap.vue +1 -1
- package/components/auth/login/oidc.vue +6 -1
- package/components/fleet/FleetApplications.vue +174 -0
- package/components/fleet/FleetClusterTargets/TargetsList.vue +66 -0
- package/components/fleet/FleetClusterTargets/index.vue +455 -0
- package/components/fleet/FleetClusters.vue +25 -6
- package/components/fleet/FleetGitRepoPaths.vue +476 -0
- package/components/fleet/FleetHelmOps.vue +123 -0
- package/components/fleet/FleetIntro.vue +58 -28
- package/components/fleet/FleetNoWorkspaces.vue +5 -1
- package/components/fleet/FleetOCIStorageSecret.vue +171 -0
- package/components/fleet/FleetRepos.vue +37 -80
- package/components/fleet/FleetResources.vue +53 -26
- package/components/fleet/FleetSummary.vue +26 -51
- package/components/fleet/FleetValuesFrom.vue +295 -0
- package/components/fleet/__tests__/FleetClusterTargets.test.ts +1224 -0
- package/components/fleet/__tests__/FleetGitRepoPaths.test.ts +265 -0
- package/components/fleet/__tests__/FleetOCIStorageSecret.test.ts +213 -0
- package/components/fleet/__tests__/FleetSummary.test.ts +39 -39
- package/components/fleet/__tests__/FleetValuesFrom.test.ts +300 -0
- package/components/fleet/dashboard/Empty.vue +73 -0
- package/components/fleet/dashboard/ResourceCard.vue +184 -0
- package/components/fleet/dashboard/ResourceCardSummary.vue +195 -0
- package/components/fleet/dashboard/ResourceDetails.vue +194 -0
- package/components/fleet/dashboard/ResourcePanel.vue +383 -0
- package/components/form/ArrayList.vue +19 -2
- package/components/form/ChangePassword.vue +3 -1
- package/components/form/Footer.vue +10 -4
- package/components/form/KeyValue.vue +81 -43
- package/components/form/LabeledSelect.vue +56 -16
- package/components/form/Labels.vue +90 -17
- package/components/form/MatchExpressions.vue +46 -5
- package/components/form/NameNsDescription.vue +1 -1
- package/components/form/ResourceSelector.vue +1 -0
- package/components/form/ResourceTabs/index.vue +5 -0
- package/components/form/SecretSelector.vue +9 -2
- package/components/form/Select.vue +57 -19
- package/components/form/SimpleSecretSelector.vue +17 -4
- package/components/form/Taints.vue +21 -2
- package/components/form/UnitInput.vue +8 -0
- package/components/form/ValueFromResource.vue +31 -19
- package/components/form/__tests__/LabeledSelect.test.ts +8 -4
- package/components/form/__tests__/Labels.test.ts +360 -0
- package/components/form/__tests__/MatchExpressions.test.ts +16 -13
- package/components/form/__tests__/Select.test.ts +5 -2
- package/components/formatter/FleetApplicationClustersReady.vue +77 -0
- package/components/formatter/FleetApplicationSource.vue +71 -0
- package/components/formatter/FleetSummaryGraph.vue +7 -0
- package/components/formatter/WorkloadHealthScale.vue +1 -1
- package/components/google/AccountAccess.vue +211 -0
- package/components/google/types/gcp.d.ts +136 -0
- package/components/google/types/index.d.ts +101 -0
- package/components/google/util/__mocks__/gcp.ts +465 -0
- package/components/google/util/formatter.ts +82 -0
- package/components/google/util/gcp.ts +134 -0
- package/components/google/util/index.d.ts +11 -0
- package/components/nav/Favorite.vue +1 -1
- package/components/nav/Group.vue +70 -47
- package/components/nav/Header.vue +13 -8
- package/components/nav/NamespaceFilter.vue +13 -1
- package/components/nav/NotificationCenter/Notification.vue +510 -0
- package/components/nav/NotificationCenter/NotificationHeader.vue +112 -0
- package/components/nav/NotificationCenter/index.vue +148 -0
- package/components/nav/TopLevelMenu.helper.ts +55 -34
- package/components/nav/TopLevelMenu.vue +11 -0
- package/components/nav/Type.vue +4 -1
- package/composables/drawer.ts +26 -0
- package/composables/resources.test.ts +63 -0
- package/composables/resources.ts +38 -0
- package/composables/useI18n.ts +12 -11
- package/composables/useIsNewDetailPageEnabled.ts +17 -0
- package/config/labels-annotations.js +20 -11
- package/config/product/auth.js +17 -1
- package/config/product/{cis.js → compliance.js} +23 -26
- package/config/product/explorer.js +5 -1
- package/config/product/fleet.js +77 -17
- package/config/product/settings.js +22 -11
- package/config/query-params.js +6 -1
- package/config/roles.ts +2 -1
- package/config/router/navigation-guards/authentication.js +51 -2
- package/config/router/routes.js +45 -31
- package/config/secret.ts +15 -0
- package/config/settings.ts +24 -5
- package/config/store.js +2 -0
- package/config/system-namespaces.js +1 -1
- package/config/table-headers.js +53 -23
- package/config/types.js +17 -6
- package/core/plugin-helpers.ts +3 -2
- package/core/plugin.ts +32 -7
- package/core/types.ts +18 -1
- package/detail/{cis.cattle.io.clusterscan.vue → compliance.cattle.io.clusterscan.vue} +22 -18
- package/detail/fleet.cattle.io.cluster.vue +28 -15
- package/detail/fleet.cattle.io.gitrepo.vue +10 -1
- package/detail/fleet.cattle.io.helmop.vue +157 -0
- package/detail/management.cattle.io.fleetworkspace.vue +18 -27
- package/detail/management.cattle.io.oidcclient.vue +369 -0
- package/detail/node.vue +2 -2
- package/detail/pod.vue +2 -2
- package/detail/service.vue +10 -1
- package/detail/workload/index.vue +8 -2
- package/dialog/ExtensionCatalogUninstallDialog.vue +7 -4
- package/dialog/GenericPrompt.vue +1 -1
- package/dialog/HelmOpForceUpdateDialog.vue +132 -0
- package/dialog/ImportDialog.vue +8 -8
- package/dialog/OidcClientSecretDialog.vue +117 -0
- package/dialog/RedeployWorkloadDialog.vue +164 -0
- package/edit/__tests__/cis.cattle.io.clusterscan.test.ts +3 -3
- package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +60 -68
- package/edit/auth/oidc.vue +159 -93
- package/edit/autoscaling.horizontalpodautoscaler/index.vue +4 -1
- package/edit/{cis.cattle.io.clusterscan.vue → compliance.cattle.io.clusterscan.vue} +30 -31
- package/edit/{cis.cattle.io.clusterscanbenchmark.vue → compliance.cattle.io.clusterscanbenchmark.vue} +4 -4
- package/edit/{cis.cattle.io.clusterscanprofile.vue → compliance.cattle.io.clusterscanprofile.vue} +5 -5
- package/edit/configmap.vue +4 -1
- package/edit/constraints.gatekeeper.sh.constraint/index.vue +1 -0
- package/edit/fleet.cattle.io.gitrepo.vue +70 -255
- package/edit/fleet.cattle.io.helmop.vue +772 -0
- 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 +44 -10
- package/edit/management.cattle.io.oidcclient.vue +162 -0
- package/edit/management.cattle.io.project.vue +4 -1
- package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +1 -1
- package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +5 -0
- package/edit/monitoring.coreos.com.prometheusrule/index.vue +1 -0
- package/edit/monitoring.coreos.com.receiver/auth.vue +30 -30
- package/edit/monitoring.coreos.com.receiver/index.vue +1 -0
- package/edit/monitoring.coreos.com.receiver/types/email.vue +1 -1
- package/edit/monitoring.coreos.com.route.vue +1 -0
- package/edit/namespace.vue +1 -0
- package/edit/networking.istio.io.destinationrule/index.vue +4 -1
- package/edit/networking.k8s.io.ingress/index.vue +4 -1
- package/edit/networking.k8s.io.networkpolicy/PolicyRules.vue +7 -2
- package/edit/networking.k8s.io.networkpolicy/index.vue +6 -2
- package/edit/node.vue +1 -0
- package/edit/persistentvolume/index.vue +4 -1
- package/edit/provisioning.cattle.io.cluster/rke2.vue +418 -382
- package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +27 -27
- package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +5 -0
- package/edit/resources.cattle.io.restore.vue +1 -1
- package/edit/secret/index.vue +1 -0
- package/edit/service.vue +4 -1
- package/edit/serviceaccount.vue +4 -1
- package/edit/storage.k8s.io.storageclass/index.vue +4 -1
- package/edit/workload/index.vue +5 -0
- package/list/{cis.cattle.io.clusterscan.vue → compliance.cattle.io.clusterscan.vue} +2 -2
- package/list/fleet.cattle.io.gitrepo.vue +1 -1
- package/list/fleet.cattle.io.helmop.vue +108 -0
- package/list/management.cattle.io.oidcclient.vue +108 -0
- package/list/namespace.vue +5 -2
- package/list/node.vue +2 -0
- package/machine-config/amazonec2.vue +3 -24
- package/machine-config/components/GCEImage.vue +374 -0
- package/machine-config/google.vue +617 -0
- package/mixins/__tests__/brand.spec.ts +170 -0
- package/mixins/auth-config.js +8 -1
- package/mixins/brand.js +16 -17
- package/mixins/create-edit-view/index.js +5 -0
- package/mixins/preset.js +100 -0
- package/mixins/resource-fetch-api-pagination.js +18 -0
- package/mixins/resource-fetch.js +1 -1
- package/mixins/resource-table-watch.js +45 -0
- package/mixins/vue-select-overrides.js +1 -0
- package/models/__tests__/chart.test.ts +273 -0
- package/models/__tests__/fleet.cattle.io.gitrepo.test.ts +1 -1
- package/models/chart.js +144 -2
- package/models/{cis.cattle.io.clusterscan.js → compliance.cattle.io.clusterscan.js} +8 -8
- package/models/{cis.cattle.io.clusterscanbenchmark.js → compliance.cattle.io.clusterscanbenchmark.js} +1 -1
- package/models/{cis.cattle.io.clusterscanprofile.js → compliance.cattle.io.clusterscanprofile.js} +5 -5
- package/models/{cis.cattle.io.clusterscanreport.js → compliance.cattle.io.clusterscanreport.js} +1 -1
- package/models/fleet-application.js +314 -0
- package/models/fleet.cattle.io.bundle.js +9 -8
- package/models/fleet.cattle.io.cluster.js +11 -0
- package/models/fleet.cattle.io.gitrepo.js +41 -365
- package/models/fleet.cattle.io.helmop.js +198 -0
- package/models/management.cattle.io.authconfig.js +1 -0
- package/models/management.cattle.io.fleetworkspace.js +14 -1
- package/models/management.cattle.io.oidcclient.js +18 -0
- package/models/management.cattle.io.registration.js +3 -0
- package/models/provisioning.cattle.io.cluster.js +5 -5
- package/models/service.js +4 -0
- package/models/workload.js +19 -18
- package/package.json +2 -1
- package/pages/about.vue +4 -58
- package/pages/auth/login.vue +1 -1
- package/pages/auth/verify.vue +13 -1
- package/pages/c/_cluster/apps/charts/AddRepoLink.vue +36 -0
- package/pages/c/_cluster/apps/charts/AppChartCardFooter.vue +80 -0
- package/pages/c/_cluster/apps/charts/AppChartCardSubHeader.vue +54 -0
- package/pages/c/_cluster/apps/charts/StatusLabel.vue +33 -0
- package/pages/c/_cluster/apps/charts/index.vue +487 -465
- package/pages/c/_cluster/auth/user.retention/index.vue +87 -78
- package/pages/c/_cluster/explorer/EventsTable.vue +1 -1
- package/pages/c/_cluster/explorer/index.vue +3 -3
- package/pages/c/_cluster/explorer/tools/pages/_page.vue +0 -1
- package/pages/c/_cluster/fleet/__tests__/index.test.ts +426 -0
- package/pages/c/_cluster/fleet/application/_resource/_id.vue +14 -0
- package/pages/c/_cluster/fleet/application/_resource/create.vue +14 -0
- package/pages/c/_cluster/fleet/application/create.vue +341 -0
- package/pages/c/_cluster/fleet/application/index.vue +139 -0
- package/pages/c/_cluster/fleet/graph/config.js +277 -0
- package/pages/c/_cluster/fleet/index.vue +809 -329
- package/pages/c/_cluster/fleet/settings/index.vue +229 -0
- package/pages/c/_cluster/longhorn/index.vue +5 -2
- package/pages/c/_cluster/uiplugins/CatalogList/index.vue +16 -1
- package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +2 -2
- package/pages/explorer/resource/detail/configmap.vue +42 -0
- package/pages/explorer/resource/detail/secret.vue +50 -0
- package/pages/home.vue +9 -55
- package/pages/support/index.vue +4 -6
- package/plugins/dashboard-store/actions.js +50 -14
- package/plugins/dashboard-store/getters.js +38 -21
- package/plugins/dashboard-store/mutations.js +51 -7
- package/plugins/dashboard-store/resource-class.js +30 -4
- package/plugins/steve/__tests__/subscribe.spec.ts +66 -1
- package/plugins/steve/actions.js +3 -0
- package/plugins/steve/steve-pagination-utils.ts +17 -8
- package/plugins/steve/subscribe.js +235 -43
- package/rancher-components/BadgeState/BadgeState.vue +3 -1
- package/rancher-components/Banner/Banner.vue +13 -0
- package/rancher-components/Form/Checkbox/Checkbox.vue +11 -6
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +1 -1
- package/rancher-components/LabeledTooltip/LabeledTooltip.vue +1 -0
- package/rancher-components/RcItemCard/RcItemCard.test.ts +189 -0
- package/rancher-components/RcItemCard/RcItemCard.vue +430 -0
- package/rancher-components/RcItemCard/RcItemCardAction.vue +24 -0
- package/rancher-components/RcItemCard/index.ts +2 -0
- package/store/auth.js +3 -0
- package/store/catalog.js +85 -25
- package/store/growl.js +97 -8
- package/store/index.js +39 -14
- package/store/notifications.ts +426 -0
- package/store/prefs.js +0 -1
- package/store/slideInPanel.ts +6 -0
- package/store/type-map.js +19 -15
- package/store/uiplugins.ts +15 -1
- package/types/fleet.d.ts +59 -0
- package/types/notifications/index.ts +74 -0
- package/types/resources/settings.d.ts +19 -1
- package/types/shell/index.d.ts +388 -307
- package/types/store/dashboard-store.types.ts +33 -3
- package/types/store/pagination.types.ts +6 -1
- package/types/store/subscribe.types.ts +50 -0
- package/utils/__tests__/fleet.test.ts +148 -0
- package/utils/__tests__/object.test.ts +54 -1
- package/utils/__tests__/string.test.ts +273 -1
- package/utils/__tests__/time.test.ts +31 -0
- package/utils/auth.js +41 -5
- package/utils/crypto/encryption.ts +103 -0
- package/utils/cspAdaptor.ts +51 -0
- package/utils/fleet-types.ts +0 -0
- package/utils/fleet.ts +190 -2
- package/utils/object.js +36 -0
- package/utils/pagination-utils.ts +27 -2
- package/utils/pagination-wrapper.ts +132 -50
- package/utils/release-notes.ts +48 -0
- package/utils/selector-typed.ts +7 -2
- package/utils/settings.ts +4 -1
- package/utils/string.js +24 -0
- package/utils/style.ts +39 -0
- package/utils/{time.js → time.ts} +25 -6
- package/utils/uiplugins.ts +22 -0
- package/utils/validators/formRules/__tests__/index.test.ts +36 -3
- package/utils/validators/formRules/index.ts +13 -3
- package/utils/window.js +11 -7
- package/components/__tests__/ApplicationCard.test.ts +0 -27
- package/components/cards/ApplicationCard.vue +0 -145
- package/components/fleet/ForceDirectedTreeChart/chartIcons.js +0 -17
- package/config/product/legacy.js +0 -62
- package/config/secret.js +0 -14
- package/pages/c/_cluster/fleet/GitRepoGraphConfig.js +0 -249
- package/pages/c/_cluster/legacy/pages/_page.vue +0 -29
- package/pages/c/_cluster/legacy/project/_page.vue +0 -57
- package/pages/c/_cluster/legacy/project/index.vue +0 -32
- package/pages/c/_cluster/legacy/project/pipelines.vue +0 -96
- /package/components/ResourceDetail/{Masthead.vue → Masthead/legacy.vue} +0 -0
- /package/{components/form/SSHKnownHosts → dialog}/__tests__/KnownHostsEditDialog.test.ts +0 -0
|
@@ -0,0 +1,1224 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils';
|
|
2
|
+
import flushPromises from 'flush-promises';
|
|
3
|
+
import FleetClusterTargets from '@shell/components/fleet/FleetClusterTargets/index.vue';
|
|
4
|
+
import { _CREATE, _EDIT } from '@shell/config/query-params';
|
|
5
|
+
import { Selector } from '@shell/types/fleet';
|
|
6
|
+
|
|
7
|
+
describe('component: FleetClusterTargets', () => {
|
|
8
|
+
describe('mode: edit', () => {
|
|
9
|
+
const mode = _EDIT;
|
|
10
|
+
|
|
11
|
+
describe('decode spec.targets and set form data', () => {
|
|
12
|
+
it('should build form source data from target with clusterName and clusterSelector', () => {
|
|
13
|
+
const target1 = {
|
|
14
|
+
clusterName: 'fleet-5-france',
|
|
15
|
+
clusterSelector: { matchLabels: { foo: 'true' } }
|
|
16
|
+
};
|
|
17
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
18
|
+
props: {
|
|
19
|
+
targets: [target1],
|
|
20
|
+
namespace: 'fleet-default',
|
|
21
|
+
mode
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const targetMode = wrapper.vm.targetMode;
|
|
26
|
+
const selectedClusters = wrapper.vm.selectedClusters;
|
|
27
|
+
const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
|
|
28
|
+
|
|
29
|
+
expect(targetMode).toBe('clusters');
|
|
30
|
+
expect(selectedClusters).toStrictEqual([target1.clusterName]);
|
|
31
|
+
expect(clusterSelectors[0].matchLabels).toStrictEqual(target1.clusterSelector.matchLabels);
|
|
32
|
+
expect(clusterSelectors[0].matchExpressions).toBeUndefined();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('should set targetMode to "all" and correctly filter clusterSelector for harvester rule', () => {
|
|
36
|
+
const target1 = {
|
|
37
|
+
clusterSelector: {
|
|
38
|
+
matchExpressions: [{
|
|
39
|
+
key: 'provider.cattle.io',
|
|
40
|
+
operator: 'NotIn',
|
|
41
|
+
values: ['harvester']
|
|
42
|
+
}]
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
46
|
+
props: {
|
|
47
|
+
targets: [target1],
|
|
48
|
+
namespace: 'fleet-default',
|
|
49
|
+
mode,
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const targetMode = wrapper.vm.targetMode;
|
|
54
|
+
const selectedClusters = wrapper.vm.selectedClusters;
|
|
55
|
+
const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
|
|
56
|
+
|
|
57
|
+
expect(targetMode).toBe('all');
|
|
58
|
+
expect(clusterSelectors).toStrictEqual([]); // Harvester rule should be filtered out
|
|
59
|
+
expect(selectedClusters).toStrictEqual([]);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('should set targetMode to "clusters" and populate selectedClusters and clusterSelectors', () => {
|
|
63
|
+
const target1 = { clusterName: 'fleet-5-france' };
|
|
64
|
+
|
|
65
|
+
const target2 = { clusterSelector: { matchLabels: { foo: 'true' } } };
|
|
66
|
+
|
|
67
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
68
|
+
props: {
|
|
69
|
+
targets: [target1, target2],
|
|
70
|
+
namespace: 'fleet-default',
|
|
71
|
+
mode
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const targetMode = wrapper.vm.targetMode;
|
|
76
|
+
const selectedClusters = wrapper.vm.selectedClusters;
|
|
77
|
+
const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
|
|
78
|
+
|
|
79
|
+
expect(targetMode).toBe('clusters');
|
|
80
|
+
expect(selectedClusters).toStrictEqual(['fleet-5-france']);
|
|
81
|
+
expect(clusterSelectors).toStrictEqual([{
|
|
82
|
+
key: 0,
|
|
83
|
+
matchLabels: { foo: 'true' },
|
|
84
|
+
matchExpressions: undefined
|
|
85
|
+
}]);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('should set targetMode to "clusters" and populate clusterSelectors with multiple entries', () => {
|
|
89
|
+
const target1 = { clusterSelector: { matchLabels: { foo: 'true' } } };
|
|
90
|
+
const target2 = { clusterSelector: { matchLabels: { hci: 'true' } } };
|
|
91
|
+
|
|
92
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
93
|
+
props: {
|
|
94
|
+
targets: [target1, target2],
|
|
95
|
+
namespace: 'fleet-default',
|
|
96
|
+
mode
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
const targetMode = wrapper.vm.targetMode;
|
|
101
|
+
const selectedClusters = wrapper.vm.selectedClusters;
|
|
102
|
+
const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
|
|
103
|
+
|
|
104
|
+
expect(targetMode).toBe('clusters');
|
|
105
|
+
expect(selectedClusters).toStrictEqual([]);
|
|
106
|
+
expect(clusterSelectors).toStrictEqual([{
|
|
107
|
+
key: 0,
|
|
108
|
+
matchLabels: { foo: 'true' },
|
|
109
|
+
matchExpressions: undefined
|
|
110
|
+
}, {
|
|
111
|
+
key: 1,
|
|
112
|
+
matchLabels: { hci: 'true' },
|
|
113
|
+
matchExpressions: undefined
|
|
114
|
+
}]);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('should set targetMode to "advanced" and return early if clusterGroupSelector is present', () => {
|
|
118
|
+
const target1 = { clusterGroupSelector: {} };
|
|
119
|
+
|
|
120
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
121
|
+
props: {
|
|
122
|
+
targets: [target1],
|
|
123
|
+
namespace: 'fleet-default',
|
|
124
|
+
mode
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
const targetMode = wrapper.vm.targetMode;
|
|
129
|
+
const selectedClusters = wrapper.vm.selectedClusters;
|
|
130
|
+
const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
|
|
131
|
+
|
|
132
|
+
expect(targetMode).toBe('advanced');
|
|
133
|
+
// Expect no further processing for selectedClusters or clusterSelectors due to early return
|
|
134
|
+
expect(selectedClusters).toStrictEqual([]);
|
|
135
|
+
expect(clusterSelectors).toStrictEqual([]);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('should set targetMode to "advanced" and return early if clusterGroup is present', () => {
|
|
139
|
+
const target1 = {
|
|
140
|
+
clusterGroup: 'cg1',
|
|
141
|
+
clusterGroupSelector: {
|
|
142
|
+
matchExpressions: [{
|
|
143
|
+
key: 'string',
|
|
144
|
+
operator: 'string',
|
|
145
|
+
values: ['string']
|
|
146
|
+
}],
|
|
147
|
+
matchLabels: { foo: 'bar' }
|
|
148
|
+
},
|
|
149
|
+
clusterName: 'pippo',
|
|
150
|
+
clusterSelector: {
|
|
151
|
+
matchExpressions: [{
|
|
152
|
+
key: 'string',
|
|
153
|
+
operator: 'string',
|
|
154
|
+
values: ['vvv']
|
|
155
|
+
}],
|
|
156
|
+
matchLabels: { foo: 'bar' }
|
|
157
|
+
},
|
|
158
|
+
name: 'tt1',
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
162
|
+
props: {
|
|
163
|
+
targets: [target1],
|
|
164
|
+
namespace: 'fleet-default',
|
|
165
|
+
mode
|
|
166
|
+
},
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
const targetMode = wrapper.vm.targetMode;
|
|
170
|
+
const selectedClusters = wrapper.vm.selectedClusters;
|
|
171
|
+
const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
|
|
172
|
+
|
|
173
|
+
expect(targetMode).toBe('advanced');
|
|
174
|
+
// Expect no further processing for selectedClusters or clusterSelectors due to early return
|
|
175
|
+
expect(selectedClusters).toStrictEqual([]);
|
|
176
|
+
expect(clusterSelectors).toStrictEqual([]);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it('should return early and not modify state if targets is empty', () => {
|
|
180
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
181
|
+
props: {
|
|
182
|
+
targets: [],
|
|
183
|
+
namespace: 'fleet-default',
|
|
184
|
+
mode
|
|
185
|
+
},
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
const targetMode = wrapper.vm.targetMode;
|
|
189
|
+
const selectedClusters = wrapper.vm.selectedClusters;
|
|
190
|
+
const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
|
|
191
|
+
|
|
192
|
+
expect(targetMode).toBe('none');
|
|
193
|
+
expect(selectedClusters).toStrictEqual([]);
|
|
194
|
+
expect(clusterSelectors).toStrictEqual([]);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it('should return targetMode local if namespace is fleet-local', () => {
|
|
198
|
+
const target1 = { clusterSelector: { matchLabels: { foo: 'true' } } };
|
|
199
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
200
|
+
props: {
|
|
201
|
+
targets: [target1],
|
|
202
|
+
namespace: 'fleet-local',
|
|
203
|
+
mode
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
const targetMode = wrapper.vm.targetMode;
|
|
208
|
+
|
|
209
|
+
expect(targetMode).toBe('local');
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
it('should handle targets with multiple clusterName', () => {
|
|
213
|
+
const target1 = { clusterName: 'prod-cluster' };
|
|
214
|
+
const target2 = { clusterName: 'test-cluster' };
|
|
215
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
216
|
+
props: {
|
|
217
|
+
targets: [target1, target2],
|
|
218
|
+
namespace: 'fleet-default',
|
|
219
|
+
mode
|
|
220
|
+
},
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
const targetMode = wrapper.vm.targetMode;
|
|
224
|
+
const selectedClusters = wrapper.vm.selectedClusters;
|
|
225
|
+
const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
|
|
226
|
+
|
|
227
|
+
expect(targetMode).toBe('clusters');
|
|
228
|
+
expect(selectedClusters).toStrictEqual(['prod-cluster', 'test-cluster']);
|
|
229
|
+
expect(clusterSelectors).toStrictEqual([]);
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
it('should filter out harvester rule and leave others', () => {
|
|
233
|
+
const target1 = {
|
|
234
|
+
clusterSelector: {
|
|
235
|
+
matchExpressions: [{
|
|
236
|
+
key: 'provider.cattle.io',
|
|
237
|
+
operator: 'NotIn',
|
|
238
|
+
values: ['harvester']
|
|
239
|
+
}, {
|
|
240
|
+
key: 'foo',
|
|
241
|
+
operator: 'In',
|
|
242
|
+
values: ['bar']
|
|
243
|
+
}]
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
248
|
+
props: {
|
|
249
|
+
targets: [target1],
|
|
250
|
+
namespace: 'fleet-default',
|
|
251
|
+
mode
|
|
252
|
+
},
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
const targetMode = wrapper.vm.targetMode;
|
|
256
|
+
const selectedClusters = wrapper.vm.selectedClusters;
|
|
257
|
+
const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
|
|
258
|
+
|
|
259
|
+
expect(targetMode).toBe('clusters');
|
|
260
|
+
expect(selectedClusters).toStrictEqual([]);
|
|
261
|
+
expect(clusterSelectors).toStrictEqual([{
|
|
262
|
+
key: 0,
|
|
263
|
+
matchLabels: undefined,
|
|
264
|
+
matchExpressions: [{
|
|
265
|
+
key: 'foo',
|
|
266
|
+
operator: 'In',
|
|
267
|
+
values: ['bar']
|
|
268
|
+
}]
|
|
269
|
+
}]);
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
it('should correctly process targets when targetMode is "all" and no clusterName or clusterSelector is present', () => {
|
|
273
|
+
const target1 = { name: 'simple-target' };
|
|
274
|
+
|
|
275
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
276
|
+
props: {
|
|
277
|
+
targets: [target1],
|
|
278
|
+
namespace: 'fleet-default',
|
|
279
|
+
mode,
|
|
280
|
+
},
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
const targetMode = wrapper.vm.targetMode;
|
|
284
|
+
const selectedClusters = wrapper.vm.selectedClusters;
|
|
285
|
+
const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
|
|
286
|
+
|
|
287
|
+
expect(targetMode).toBe('all');
|
|
288
|
+
expect(selectedClusters).toStrictEqual([]);
|
|
289
|
+
expect(clusterSelectors).toStrictEqual([]);
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
it('should correctly process targets when targetMode is "all", name is defined and harvester rule is present', () => {
|
|
293
|
+
const target1 = {
|
|
294
|
+
clusterSelector: {
|
|
295
|
+
matchExpressions: [{
|
|
296
|
+
key: 'provider.cattle.io',
|
|
297
|
+
operator: 'NotIn',
|
|
298
|
+
values: ['harvester']
|
|
299
|
+
}]
|
|
300
|
+
},
|
|
301
|
+
name: 'simple-target'
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
305
|
+
props: {
|
|
306
|
+
targets: [target1],
|
|
307
|
+
namespace: 'fleet-default',
|
|
308
|
+
mode,
|
|
309
|
+
},
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
const targetMode = wrapper.vm.targetMode;
|
|
313
|
+
const selectedClusters = wrapper.vm.selectedClusters;
|
|
314
|
+
const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
|
|
315
|
+
|
|
316
|
+
expect(targetMode).toBe('all');
|
|
317
|
+
expect(selectedClusters).toStrictEqual([]);
|
|
318
|
+
expect(clusterSelectors).toStrictEqual([]); // Harvester rule should be filtered out
|
|
319
|
+
});
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
describe('decode form data and emit to spec.targets', () => {
|
|
323
|
+
it('should emit target with clusterName and clusterSelector', async() => {
|
|
324
|
+
const target1 = {
|
|
325
|
+
clusterName: 'fleet-5-france',
|
|
326
|
+
clusterSelector: { matchLabels: { foo: 'true' } }
|
|
327
|
+
};
|
|
328
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
329
|
+
props: {
|
|
330
|
+
targets: [target1],
|
|
331
|
+
namespace: 'fleet-default',
|
|
332
|
+
mode,
|
|
333
|
+
},
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
wrapper.vm.update();
|
|
337
|
+
|
|
338
|
+
await flushPromises();
|
|
339
|
+
|
|
340
|
+
expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{ clusterName: 'fleet-5-france' }, { clusterSelector: { matchLabels: { foo: 'true' } } }]);
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
it('should emit harvester exclude rule', async() => {
|
|
344
|
+
const target1 = {
|
|
345
|
+
clusterSelector: {
|
|
346
|
+
matchExpressions: [{
|
|
347
|
+
key: 'provider.cattle.io',
|
|
348
|
+
operator: 'NotIn',
|
|
349
|
+
values: ['harvester']
|
|
350
|
+
}]
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
354
|
+
props: {
|
|
355
|
+
targets: [target1],
|
|
356
|
+
namespace: 'fleet-default',
|
|
357
|
+
mode,
|
|
358
|
+
},
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
wrapper.vm.update();
|
|
362
|
+
await flushPromises();
|
|
363
|
+
|
|
364
|
+
expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{
|
|
365
|
+
clusterSelector: {
|
|
366
|
+
matchExpressions: [{
|
|
367
|
+
key: 'provider.cattle.io', operator: 'NotIn', values: ['harvester']
|
|
368
|
+
}]
|
|
369
|
+
}
|
|
370
|
+
}]);
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
it('should emit multiple targets with clusterName and clusterSelector', async() => {
|
|
374
|
+
const target1 = { clusterName: 'fleet-5-france' };
|
|
375
|
+
|
|
376
|
+
const target2 = { clusterSelector: { matchLabels: { foo: 'true' } } };
|
|
377
|
+
|
|
378
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
379
|
+
props: {
|
|
380
|
+
targets: [target1, target2],
|
|
381
|
+
namespace: 'fleet-default',
|
|
382
|
+
mode,
|
|
383
|
+
},
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
wrapper.vm.update();
|
|
387
|
+
await flushPromises();
|
|
388
|
+
|
|
389
|
+
expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{ clusterName: 'fleet-5-france' }, { clusterSelector: { matchLabels: { foo: 'true' } } }]);
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
it('should emit multiple targets containing both clusterSelector fields', async() => {
|
|
393
|
+
const target1 = { clusterSelector: { matchLabels: { foo: 'true' } } };
|
|
394
|
+
const target2 = { clusterSelector: { matchLabels: { hci: 'true' } } };
|
|
395
|
+
|
|
396
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
397
|
+
props: {
|
|
398
|
+
targets: [target1, target2],
|
|
399
|
+
namespace: 'fleet-default',
|
|
400
|
+
mode,
|
|
401
|
+
},
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
wrapper.vm.update();
|
|
405
|
+
await flushPromises();
|
|
406
|
+
|
|
407
|
+
expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{ clusterSelector: { matchLabels: { foo: 'true' } } }, { clusterSelector: { matchLabels: { hci: 'true' } } }]);
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
it('should emit advanced cases untouched', async() => {
|
|
411
|
+
const target1 = { clusterGroupSelector: {} };
|
|
412
|
+
|
|
413
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
414
|
+
props: {
|
|
415
|
+
targets: [target1],
|
|
416
|
+
namespace: 'fleet-default',
|
|
417
|
+
mode,
|
|
418
|
+
},
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
wrapper.vm.update();
|
|
422
|
+
await flushPromises();
|
|
423
|
+
|
|
424
|
+
expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{ clusterGroupSelector: {} }]);
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
it('should emit full target definition', async() => {
|
|
428
|
+
const target1 = {
|
|
429
|
+
clusterGroup: 'cg1',
|
|
430
|
+
clusterGroupSelector: {
|
|
431
|
+
matchExpressions: [{
|
|
432
|
+
key: 'string',
|
|
433
|
+
operator: 'string',
|
|
434
|
+
values: ['string']
|
|
435
|
+
}],
|
|
436
|
+
matchLabels: { foo: 'bar' }
|
|
437
|
+
},
|
|
438
|
+
clusterName: 'pippo',
|
|
439
|
+
clusterSelector: {
|
|
440
|
+
matchExpressions: [{
|
|
441
|
+
key: 'string',
|
|
442
|
+
operator: 'string',
|
|
443
|
+
values: ['vvv']
|
|
444
|
+
}],
|
|
445
|
+
matchLabels: { foo: 'bar' }
|
|
446
|
+
},
|
|
447
|
+
name: 'tt1',
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
451
|
+
props: {
|
|
452
|
+
targets: [target1],
|
|
453
|
+
namespace: 'fleet-default',
|
|
454
|
+
mode,
|
|
455
|
+
},
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
wrapper.vm.update();
|
|
459
|
+
await flushPromises();
|
|
460
|
+
|
|
461
|
+
expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{
|
|
462
|
+
clusterGroup: 'cg1',
|
|
463
|
+
clusterGroupSelector: {
|
|
464
|
+
matchExpressions: [{
|
|
465
|
+
key: 'string', operator: 'string', values: ['string']
|
|
466
|
+
}],
|
|
467
|
+
matchLabels: { foo: 'bar' }
|
|
468
|
+
},
|
|
469
|
+
clusterName: 'pippo',
|
|
470
|
+
clusterSelector: {
|
|
471
|
+
matchExpressions: [{
|
|
472
|
+
key: 'string', operator: 'string', values: ['vvv']
|
|
473
|
+
}],
|
|
474
|
+
matchLabels: { foo: 'bar' }
|
|
475
|
+
},
|
|
476
|
+
name: 'tt1'
|
|
477
|
+
}]);
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
it('should emit harvester rule from empty targets source', async() => {
|
|
481
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
482
|
+
props: {
|
|
483
|
+
targets: [], // targetMode === 'none'
|
|
484
|
+
namespace: 'fleet-default',
|
|
485
|
+
mode,
|
|
486
|
+
},
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
wrapper.vm.update();
|
|
490
|
+
await flushPromises();
|
|
491
|
+
|
|
492
|
+
expect(wrapper.emitted('update:value')?.[0][0]).toBeUndefined();
|
|
493
|
+
});
|
|
494
|
+
|
|
495
|
+
it('should emit untouched targets from source when operating in fleet-local workspace', async() => {
|
|
496
|
+
const target1 = { clusterSelector: { matchLabels: { foo: 'true' } } };
|
|
497
|
+
|
|
498
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
499
|
+
props: {
|
|
500
|
+
targets: [target1],
|
|
501
|
+
namespace: 'fleet-local',
|
|
502
|
+
mode,
|
|
503
|
+
},
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
wrapper.vm.update();
|
|
507
|
+
await flushPromises();
|
|
508
|
+
|
|
509
|
+
expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{ clusterSelector: { matchLabels: { foo: 'true' } } }]);
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
it('should emit custom targets filtering out harvester rule', async() => {
|
|
513
|
+
const target1 = {
|
|
514
|
+
clusterSelector: {
|
|
515
|
+
matchExpressions: [{
|
|
516
|
+
key: 'provider.cattle.io',
|
|
517
|
+
operator: 'NotIn',
|
|
518
|
+
values: ['harvester']
|
|
519
|
+
}, {
|
|
520
|
+
key: 'foo',
|
|
521
|
+
operator: 'In',
|
|
522
|
+
values: ['bar']
|
|
523
|
+
}]
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
|
|
527
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
528
|
+
props: {
|
|
529
|
+
targets: [target1],
|
|
530
|
+
namespace: 'fleet-default',
|
|
531
|
+
mode,
|
|
532
|
+
},
|
|
533
|
+
});
|
|
534
|
+
|
|
535
|
+
wrapper.vm.update();
|
|
536
|
+
await flushPromises();
|
|
537
|
+
|
|
538
|
+
expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{
|
|
539
|
+
clusterSelector: {
|
|
540
|
+
matchExpressions: [{
|
|
541
|
+
key: 'foo', operator: 'In', values: ['bar']
|
|
542
|
+
}]
|
|
543
|
+
}
|
|
544
|
+
}]);
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
it('should emit targets excluding target names and adding harvester rule', async() => {
|
|
548
|
+
const target1 = { name: 'simple-target' };
|
|
549
|
+
|
|
550
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
551
|
+
props: {
|
|
552
|
+
targets: [target1],
|
|
553
|
+
namespace: 'fleet-default',
|
|
554
|
+
mode,
|
|
555
|
+
},
|
|
556
|
+
});
|
|
557
|
+
|
|
558
|
+
wrapper.vm.update();
|
|
559
|
+
await flushPromises();
|
|
560
|
+
|
|
561
|
+
expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{
|
|
562
|
+
clusterSelector: {
|
|
563
|
+
matchExpressions: [{
|
|
564
|
+
key: 'provider.cattle.io', operator: 'NotIn', values: ['harvester']
|
|
565
|
+
}]
|
|
566
|
+
}
|
|
567
|
+
}]);
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
it('should emit targets excluding target names and harvester rule if present in source targets', async() => {
|
|
571
|
+
const target1 = {
|
|
572
|
+
clusterSelector: {
|
|
573
|
+
matchExpressions: [{
|
|
574
|
+
key: 'provider.cattle.io',
|
|
575
|
+
operator: 'NotIn',
|
|
576
|
+
values: ['harvester']
|
|
577
|
+
}]
|
|
578
|
+
},
|
|
579
|
+
name: 'simple-target'
|
|
580
|
+
};
|
|
581
|
+
|
|
582
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
583
|
+
props: {
|
|
584
|
+
targets: [target1],
|
|
585
|
+
namespace: 'fleet-default',
|
|
586
|
+
mode,
|
|
587
|
+
},
|
|
588
|
+
});
|
|
589
|
+
|
|
590
|
+
wrapper.vm.update();
|
|
591
|
+
await flushPromises();
|
|
592
|
+
|
|
593
|
+
expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{
|
|
594
|
+
clusterSelector: {
|
|
595
|
+
matchExpressions: [{
|
|
596
|
+
key: 'provider.cattle.io', operator: 'NotIn', values: ['harvester']
|
|
597
|
+
}]
|
|
598
|
+
}
|
|
599
|
+
}]);
|
|
600
|
+
});
|
|
601
|
+
});
|
|
602
|
+
});
|
|
603
|
+
|
|
604
|
+
describe('mode: create', () => {
|
|
605
|
+
const mode = _CREATE;
|
|
606
|
+
|
|
607
|
+
describe('decode spec.targets and set form data', () => {
|
|
608
|
+
it('should build form source data from target with clusterName and clusterSelector', () => {
|
|
609
|
+
const target1 = {
|
|
610
|
+
clusterName: 'fleet-5-france',
|
|
611
|
+
clusterSelector: { matchLabels: { foo: 'true' } }
|
|
612
|
+
};
|
|
613
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
614
|
+
props: {
|
|
615
|
+
targets: [target1],
|
|
616
|
+
namespace: 'fleet-default',
|
|
617
|
+
mode,
|
|
618
|
+
created: 'clusters'
|
|
619
|
+
},
|
|
620
|
+
});
|
|
621
|
+
|
|
622
|
+
const targetMode = wrapper.vm.targetMode;
|
|
623
|
+
const selectedClusters = wrapper.vm.selectedClusters;
|
|
624
|
+
const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
|
|
625
|
+
|
|
626
|
+
expect(targetMode).toBe('clusters');
|
|
627
|
+
expect(selectedClusters).toStrictEqual([target1.clusterName]);
|
|
628
|
+
expect(clusterSelectors[0].matchLabels).toStrictEqual(target1.clusterSelector.matchLabels);
|
|
629
|
+
expect(clusterSelectors[0].matchExpressions).toBeUndefined();
|
|
630
|
+
});
|
|
631
|
+
|
|
632
|
+
it('should set targetMode to "all" and correctly filter clusterSelector for harvester rule', () => {
|
|
633
|
+
const target1 = {
|
|
634
|
+
clusterSelector: {
|
|
635
|
+
matchExpressions: [{
|
|
636
|
+
key: 'provider.cattle.io',
|
|
637
|
+
operator: 'NotIn',
|
|
638
|
+
values: ['harvester']
|
|
639
|
+
}]
|
|
640
|
+
}
|
|
641
|
+
};
|
|
642
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
643
|
+
props: {
|
|
644
|
+
targets: [target1],
|
|
645
|
+
namespace: 'fleet-default',
|
|
646
|
+
mode,
|
|
647
|
+
},
|
|
648
|
+
});
|
|
649
|
+
|
|
650
|
+
const targetMode = wrapper.vm.targetMode;
|
|
651
|
+
const selectedClusters = wrapper.vm.selectedClusters;
|
|
652
|
+
const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
|
|
653
|
+
|
|
654
|
+
expect(targetMode).toBe('all');
|
|
655
|
+
expect(clusterSelectors).toStrictEqual([]); // Harvester rule should be filtered out
|
|
656
|
+
expect(selectedClusters).toStrictEqual([]);
|
|
657
|
+
});
|
|
658
|
+
|
|
659
|
+
it('should set targetMode to "clusters" and populate selectedClusters and clusterSelectors', () => {
|
|
660
|
+
const target1 = { clusterName: 'fleet-5-france' };
|
|
661
|
+
|
|
662
|
+
const target2 = { clusterSelector: { matchLabels: { foo: 'true' } } };
|
|
663
|
+
|
|
664
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
665
|
+
props: {
|
|
666
|
+
targets: [target1, target2],
|
|
667
|
+
namespace: 'fleet-default',
|
|
668
|
+
mode,
|
|
669
|
+
created: 'clusters'
|
|
670
|
+
},
|
|
671
|
+
});
|
|
672
|
+
|
|
673
|
+
const targetMode = wrapper.vm.targetMode;
|
|
674
|
+
const selectedClusters = wrapper.vm.selectedClusters;
|
|
675
|
+
const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
|
|
676
|
+
|
|
677
|
+
expect(targetMode).toBe('clusters');
|
|
678
|
+
expect(selectedClusters).toStrictEqual(['fleet-5-france']);
|
|
679
|
+
expect(clusterSelectors).toStrictEqual([{
|
|
680
|
+
key: 0,
|
|
681
|
+
matchLabels: { foo: 'true' },
|
|
682
|
+
matchExpressions: undefined
|
|
683
|
+
}]);
|
|
684
|
+
});
|
|
685
|
+
|
|
686
|
+
it('should set targetMode to "clusters" and populate clusterSelectors with multiple entries', () => {
|
|
687
|
+
const target1 = { clusterSelector: { matchLabels: { foo: 'true' } } };
|
|
688
|
+
const target2 = { clusterSelector: { matchLabels: { hci: 'true' } } };
|
|
689
|
+
|
|
690
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
691
|
+
props: {
|
|
692
|
+
targets: [target1, target2],
|
|
693
|
+
namespace: 'fleet-default',
|
|
694
|
+
mode,
|
|
695
|
+
created: 'clusters'
|
|
696
|
+
},
|
|
697
|
+
});
|
|
698
|
+
|
|
699
|
+
const targetMode = wrapper.vm.targetMode;
|
|
700
|
+
const selectedClusters = wrapper.vm.selectedClusters;
|
|
701
|
+
const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
|
|
702
|
+
|
|
703
|
+
expect(targetMode).toBe('clusters');
|
|
704
|
+
expect(selectedClusters).toStrictEqual([]);
|
|
705
|
+
expect(clusterSelectors).toStrictEqual([{
|
|
706
|
+
key: 0,
|
|
707
|
+
matchLabels: { foo: 'true' },
|
|
708
|
+
matchExpressions: undefined
|
|
709
|
+
}, {
|
|
710
|
+
key: 1,
|
|
711
|
+
matchLabels: { hci: 'true' },
|
|
712
|
+
matchExpressions: undefined
|
|
713
|
+
}]);
|
|
714
|
+
});
|
|
715
|
+
|
|
716
|
+
it('should set targetMode to "advanced" and return early if clusterGroupSelector is present', () => {
|
|
717
|
+
const target1 = { clusterGroupSelector: {} };
|
|
718
|
+
|
|
719
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
720
|
+
props: {
|
|
721
|
+
targets: [target1],
|
|
722
|
+
namespace: 'fleet-default',
|
|
723
|
+
mode,
|
|
724
|
+
created: 'advanced'
|
|
725
|
+
},
|
|
726
|
+
});
|
|
727
|
+
|
|
728
|
+
const targetMode = wrapper.vm.targetMode;
|
|
729
|
+
const selectedClusters = wrapper.vm.selectedClusters;
|
|
730
|
+
const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
|
|
731
|
+
|
|
732
|
+
expect(targetMode).toBe('advanced');
|
|
733
|
+
// Expect no further processing for selectedClusters or clusterSelectors due to early return
|
|
734
|
+
expect(selectedClusters).toStrictEqual([]);
|
|
735
|
+
expect(clusterSelectors).toStrictEqual([]);
|
|
736
|
+
});
|
|
737
|
+
|
|
738
|
+
it('should set targetMode to "advanced" and return early if clusterGroup is present', () => {
|
|
739
|
+
const target1 = {
|
|
740
|
+
clusterGroup: 'cg1',
|
|
741
|
+
clusterGroupSelector: {
|
|
742
|
+
matchExpressions: [{
|
|
743
|
+
key: 'string',
|
|
744
|
+
operator: 'string',
|
|
745
|
+
values: ['string']
|
|
746
|
+
}],
|
|
747
|
+
matchLabels: { foo: 'bar' }
|
|
748
|
+
},
|
|
749
|
+
clusterName: 'pippo',
|
|
750
|
+
clusterSelector: {
|
|
751
|
+
matchExpressions: [{
|
|
752
|
+
key: 'string',
|
|
753
|
+
operator: 'string',
|
|
754
|
+
values: ['vvv']
|
|
755
|
+
}],
|
|
756
|
+
matchLabels: { foo: 'bar' }
|
|
757
|
+
},
|
|
758
|
+
name: 'tt1',
|
|
759
|
+
};
|
|
760
|
+
|
|
761
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
762
|
+
props: {
|
|
763
|
+
targets: [target1],
|
|
764
|
+
namespace: 'fleet-default',
|
|
765
|
+
mode,
|
|
766
|
+
created: 'advanced'
|
|
767
|
+
},
|
|
768
|
+
});
|
|
769
|
+
|
|
770
|
+
const targetMode = wrapper.vm.targetMode;
|
|
771
|
+
const selectedClusters = wrapper.vm.selectedClusters;
|
|
772
|
+
const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
|
|
773
|
+
|
|
774
|
+
expect(targetMode).toBe('advanced');
|
|
775
|
+
// Expect no further processing for selectedClusters or clusterSelectors due to early return
|
|
776
|
+
expect(selectedClusters).toStrictEqual([]);
|
|
777
|
+
expect(clusterSelectors).toStrictEqual([]);
|
|
778
|
+
});
|
|
779
|
+
|
|
780
|
+
it('should return early and not modify state if targets is empty', () => {
|
|
781
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
782
|
+
props: {
|
|
783
|
+
targets: [],
|
|
784
|
+
namespace: 'fleet-default',
|
|
785
|
+
mode,
|
|
786
|
+
created: 'none'
|
|
787
|
+
},
|
|
788
|
+
});
|
|
789
|
+
|
|
790
|
+
const targetMode = wrapper.vm.targetMode;
|
|
791
|
+
const selectedClusters = wrapper.vm.selectedClusters;
|
|
792
|
+
const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
|
|
793
|
+
|
|
794
|
+
expect(targetMode).toBe('none');
|
|
795
|
+
expect(selectedClusters).toStrictEqual([]);
|
|
796
|
+
expect(clusterSelectors).toStrictEqual([]);
|
|
797
|
+
});
|
|
798
|
+
|
|
799
|
+
it('should return targetMode local if namespace is fleet-local', () => {
|
|
800
|
+
const target1 = { clusterSelector: { matchLabels: { foo: 'true' } } };
|
|
801
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
802
|
+
props: {
|
|
803
|
+
targets: [target1],
|
|
804
|
+
namespace: 'fleet-local',
|
|
805
|
+
mode,
|
|
806
|
+
created: 'local'
|
|
807
|
+
},
|
|
808
|
+
});
|
|
809
|
+
|
|
810
|
+
const targetMode = wrapper.vm.targetMode;
|
|
811
|
+
|
|
812
|
+
expect(targetMode).toBe('local');
|
|
813
|
+
});
|
|
814
|
+
|
|
815
|
+
it('should handle targets with multiple clusterName', () => {
|
|
816
|
+
const target1 = { clusterName: 'prod-cluster' };
|
|
817
|
+
const target2 = { clusterName: 'test-cluster' };
|
|
818
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
819
|
+
props: {
|
|
820
|
+
targets: [target1, target2],
|
|
821
|
+
namespace: 'fleet-default',
|
|
822
|
+
mode,
|
|
823
|
+
created: 'clusters'
|
|
824
|
+
},
|
|
825
|
+
});
|
|
826
|
+
|
|
827
|
+
const targetMode = wrapper.vm.targetMode;
|
|
828
|
+
const selectedClusters = wrapper.vm.selectedClusters;
|
|
829
|
+
const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
|
|
830
|
+
|
|
831
|
+
expect(targetMode).toBe('clusters');
|
|
832
|
+
expect(selectedClusters).toStrictEqual(['prod-cluster', 'test-cluster']);
|
|
833
|
+
expect(clusterSelectors).toStrictEqual([]);
|
|
834
|
+
});
|
|
835
|
+
|
|
836
|
+
it('should filter out harvester rule and leave others', () => {
|
|
837
|
+
const target1 = {
|
|
838
|
+
clusterSelector: {
|
|
839
|
+
matchExpressions: [{
|
|
840
|
+
key: 'provider.cattle.io',
|
|
841
|
+
operator: 'NotIn',
|
|
842
|
+
values: ['harvester']
|
|
843
|
+
}, {
|
|
844
|
+
key: 'foo',
|
|
845
|
+
operator: 'In',
|
|
846
|
+
values: ['bar']
|
|
847
|
+
}]
|
|
848
|
+
}
|
|
849
|
+
};
|
|
850
|
+
|
|
851
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
852
|
+
props: {
|
|
853
|
+
targets: [target1],
|
|
854
|
+
namespace: 'fleet-default',
|
|
855
|
+
mode,
|
|
856
|
+
created: 'clusters'
|
|
857
|
+
},
|
|
858
|
+
});
|
|
859
|
+
|
|
860
|
+
const targetMode = wrapper.vm.targetMode;
|
|
861
|
+
const selectedClusters = wrapper.vm.selectedClusters;
|
|
862
|
+
const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
|
|
863
|
+
|
|
864
|
+
expect(targetMode).toBe('clusters');
|
|
865
|
+
expect(selectedClusters).toStrictEqual([]);
|
|
866
|
+
expect(clusterSelectors).toStrictEqual([{
|
|
867
|
+
key: 0,
|
|
868
|
+
matchLabels: undefined,
|
|
869
|
+
matchExpressions: [{
|
|
870
|
+
key: 'foo',
|
|
871
|
+
operator: 'In',
|
|
872
|
+
values: ['bar']
|
|
873
|
+
}]
|
|
874
|
+
}]);
|
|
875
|
+
});
|
|
876
|
+
|
|
877
|
+
it('should correctly process targets when targetMode is "all" and no clusterName or clusterSelector is present', () => {
|
|
878
|
+
const target1 = { name: 'simple-target' };
|
|
879
|
+
|
|
880
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
881
|
+
props: {
|
|
882
|
+
targets: [target1],
|
|
883
|
+
namespace: 'fleet-default',
|
|
884
|
+
mode,
|
|
885
|
+
},
|
|
886
|
+
});
|
|
887
|
+
|
|
888
|
+
const targetMode = wrapper.vm.targetMode;
|
|
889
|
+
const selectedClusters = wrapper.vm.selectedClusters;
|
|
890
|
+
const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
|
|
891
|
+
|
|
892
|
+
expect(targetMode).toBe('all');
|
|
893
|
+
expect(selectedClusters).toStrictEqual([]);
|
|
894
|
+
expect(clusterSelectors).toStrictEqual([]);
|
|
895
|
+
});
|
|
896
|
+
|
|
897
|
+
it('should correctly process targets when targetMode is "all", name is defined and harvester rule is present', () => {
|
|
898
|
+
const target1 = {
|
|
899
|
+
clusterSelector: {
|
|
900
|
+
matchExpressions: [{
|
|
901
|
+
key: 'provider.cattle.io',
|
|
902
|
+
operator: 'NotIn',
|
|
903
|
+
values: ['harvester']
|
|
904
|
+
}]
|
|
905
|
+
},
|
|
906
|
+
name: 'simple-target'
|
|
907
|
+
};
|
|
908
|
+
|
|
909
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
910
|
+
props: {
|
|
911
|
+
targets: [target1],
|
|
912
|
+
namespace: 'fleet-default',
|
|
913
|
+
mode,
|
|
914
|
+
},
|
|
915
|
+
});
|
|
916
|
+
|
|
917
|
+
const targetMode = wrapper.vm.targetMode;
|
|
918
|
+
const selectedClusters = wrapper.vm.selectedClusters;
|
|
919
|
+
const clusterSelectors = wrapper.vm.clusterSelectors as Selector[];
|
|
920
|
+
|
|
921
|
+
expect(targetMode).toBe('all');
|
|
922
|
+
expect(selectedClusters).toStrictEqual([]);
|
|
923
|
+
expect(clusterSelectors).toStrictEqual([]); // Harvester rule should be filtered out
|
|
924
|
+
});
|
|
925
|
+
});
|
|
926
|
+
|
|
927
|
+
describe('decode form data and emit to spec.targets', () => {
|
|
928
|
+
it('should emit target with clusterName and clusterSelector', async() => {
|
|
929
|
+
const target1 = {
|
|
930
|
+
clusterName: 'fleet-5-france',
|
|
931
|
+
clusterSelector: { matchLabels: { foo: 'true' } }
|
|
932
|
+
};
|
|
933
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
934
|
+
props: {
|
|
935
|
+
targets: [target1],
|
|
936
|
+
namespace: 'fleet-default',
|
|
937
|
+
mode,
|
|
938
|
+
},
|
|
939
|
+
});
|
|
940
|
+
|
|
941
|
+
wrapper.setData({ targetMode: 'clusters' });
|
|
942
|
+
|
|
943
|
+
wrapper.vm.update();
|
|
944
|
+
|
|
945
|
+
await flushPromises();
|
|
946
|
+
|
|
947
|
+
expect(wrapper.emitted('update:value')?.[1][0]).toStrictEqual([{ clusterName: 'fleet-5-france' }, { clusterSelector: { matchLabels: { foo: 'true' } } }]);
|
|
948
|
+
});
|
|
949
|
+
|
|
950
|
+
it('should emit harvester exclude rule', async() => {
|
|
951
|
+
const target1 = {
|
|
952
|
+
clusterSelector: {
|
|
953
|
+
matchExpressions: [{
|
|
954
|
+
key: 'provider.cattle.io',
|
|
955
|
+
operator: 'NotIn',
|
|
956
|
+
values: ['harvester']
|
|
957
|
+
}]
|
|
958
|
+
}
|
|
959
|
+
};
|
|
960
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
961
|
+
props: {
|
|
962
|
+
targets: [target1],
|
|
963
|
+
namespace: 'fleet-default',
|
|
964
|
+
mode,
|
|
965
|
+
},
|
|
966
|
+
});
|
|
967
|
+
|
|
968
|
+
wrapper.vm.update();
|
|
969
|
+
await flushPromises();
|
|
970
|
+
|
|
971
|
+
expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{
|
|
972
|
+
clusterSelector: {
|
|
973
|
+
matchExpressions: [{
|
|
974
|
+
key: 'provider.cattle.io', operator: 'NotIn', values: ['harvester']
|
|
975
|
+
}]
|
|
976
|
+
}
|
|
977
|
+
}]);
|
|
978
|
+
});
|
|
979
|
+
|
|
980
|
+
it('should emit multiple targets with clusterName and clusterSelector', async() => {
|
|
981
|
+
const target1 = { clusterName: 'fleet-5-france' };
|
|
982
|
+
|
|
983
|
+
const target2 = { clusterSelector: { matchLabels: { foo: 'true' } } };
|
|
984
|
+
|
|
985
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
986
|
+
props: {
|
|
987
|
+
targets: [target1, target2],
|
|
988
|
+
namespace: 'fleet-default',
|
|
989
|
+
mode,
|
|
990
|
+
},
|
|
991
|
+
});
|
|
992
|
+
|
|
993
|
+
wrapper.setData({ targetMode: 'clusters' });
|
|
994
|
+
|
|
995
|
+
wrapper.vm.update();
|
|
996
|
+
await flushPromises();
|
|
997
|
+
|
|
998
|
+
expect(wrapper.emitted('update:value')?.[1][0]).toStrictEqual([{ clusterName: 'fleet-5-france' }, { clusterSelector: { matchLabels: { foo: 'true' } } }]);
|
|
999
|
+
});
|
|
1000
|
+
|
|
1001
|
+
it('should emit multiple targets containing both clusterSelector fields', async() => {
|
|
1002
|
+
const target1 = { clusterSelector: { matchLabels: { foo: 'true' } } };
|
|
1003
|
+
const target2 = { clusterSelector: { matchLabels: { hci: 'true' } } };
|
|
1004
|
+
|
|
1005
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
1006
|
+
props: {
|
|
1007
|
+
targets: [target1, target2],
|
|
1008
|
+
namespace: 'fleet-default',
|
|
1009
|
+
mode,
|
|
1010
|
+
},
|
|
1011
|
+
});
|
|
1012
|
+
|
|
1013
|
+
wrapper.setData({ targetMode: 'clusters' });
|
|
1014
|
+
|
|
1015
|
+
wrapper.vm.update();
|
|
1016
|
+
await flushPromises();
|
|
1017
|
+
|
|
1018
|
+
expect(wrapper.emitted('update:value')?.[1][0]).toStrictEqual([{ clusterSelector: { matchLabels: { foo: 'true' } } }, { clusterSelector: { matchLabels: { hci: 'true' } } }]);
|
|
1019
|
+
});
|
|
1020
|
+
|
|
1021
|
+
it('should emit advanced cases untouched', async() => {
|
|
1022
|
+
const target1 = { clusterGroupSelector: {} };
|
|
1023
|
+
|
|
1024
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
1025
|
+
props: {
|
|
1026
|
+
targets: [target1],
|
|
1027
|
+
namespace: 'fleet-default',
|
|
1028
|
+
mode,
|
|
1029
|
+
},
|
|
1030
|
+
});
|
|
1031
|
+
|
|
1032
|
+
wrapper.setData({ targetMode: 'advanced' });
|
|
1033
|
+
|
|
1034
|
+
wrapper.vm.update();
|
|
1035
|
+
await flushPromises();
|
|
1036
|
+
|
|
1037
|
+
expect(wrapper.emitted('update:value')?.[1][0]).toStrictEqual([{ clusterGroupSelector: {} }]);
|
|
1038
|
+
});
|
|
1039
|
+
|
|
1040
|
+
it('should emit full target definition', async() => {
|
|
1041
|
+
const target1 = {
|
|
1042
|
+
clusterGroup: 'cg1',
|
|
1043
|
+
clusterGroupSelector: {
|
|
1044
|
+
matchExpressions: [{
|
|
1045
|
+
key: 'string',
|
|
1046
|
+
operator: 'string',
|
|
1047
|
+
values: ['string']
|
|
1048
|
+
}],
|
|
1049
|
+
matchLabels: { foo: 'bar' }
|
|
1050
|
+
},
|
|
1051
|
+
clusterName: 'pippo',
|
|
1052
|
+
clusterSelector: {
|
|
1053
|
+
matchExpressions: [{
|
|
1054
|
+
key: 'string',
|
|
1055
|
+
operator: 'string',
|
|
1056
|
+
values: ['vvv']
|
|
1057
|
+
}],
|
|
1058
|
+
matchLabels: { foo: 'bar' }
|
|
1059
|
+
},
|
|
1060
|
+
name: 'tt1',
|
|
1061
|
+
};
|
|
1062
|
+
|
|
1063
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
1064
|
+
props: {
|
|
1065
|
+
targets: [target1],
|
|
1066
|
+
namespace: 'fleet-default',
|
|
1067
|
+
mode,
|
|
1068
|
+
},
|
|
1069
|
+
});
|
|
1070
|
+
|
|
1071
|
+
wrapper.setData({ targetMode: 'advanced' });
|
|
1072
|
+
|
|
1073
|
+
wrapper.vm.update();
|
|
1074
|
+
await flushPromises();
|
|
1075
|
+
|
|
1076
|
+
expect(wrapper.emitted('update:value')?.[1][0]).toStrictEqual([{
|
|
1077
|
+
clusterGroup: 'cg1',
|
|
1078
|
+
clusterGroupSelector: {
|
|
1079
|
+
matchExpressions: [{
|
|
1080
|
+
key: 'string', operator: 'string', values: ['string']
|
|
1081
|
+
}],
|
|
1082
|
+
matchLabels: { foo: 'bar' }
|
|
1083
|
+
},
|
|
1084
|
+
clusterName: 'pippo',
|
|
1085
|
+
clusterSelector: {
|
|
1086
|
+
matchExpressions: [{
|
|
1087
|
+
key: 'string', operator: 'string', values: ['vvv']
|
|
1088
|
+
}],
|
|
1089
|
+
matchLabels: { foo: 'bar' }
|
|
1090
|
+
},
|
|
1091
|
+
name: 'tt1'
|
|
1092
|
+
}]);
|
|
1093
|
+
});
|
|
1094
|
+
|
|
1095
|
+
it('should emit harvester rule from empty targets source', async() => {
|
|
1096
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
1097
|
+
props: {
|
|
1098
|
+
targets: [], // targetMode === 'none'
|
|
1099
|
+
namespace: 'fleet-default',
|
|
1100
|
+
mode,
|
|
1101
|
+
},
|
|
1102
|
+
});
|
|
1103
|
+
|
|
1104
|
+
wrapper.setData({ targetMode: 'none' });
|
|
1105
|
+
|
|
1106
|
+
wrapper.vm.update();
|
|
1107
|
+
await flushPromises();
|
|
1108
|
+
|
|
1109
|
+
expect(wrapper.emitted('update:value')?.[1][0]).toBeUndefined();
|
|
1110
|
+
});
|
|
1111
|
+
|
|
1112
|
+
it('should emit untouched targets from source when operating in fleet-local workspace', async() => {
|
|
1113
|
+
const target1 = { clusterSelector: { matchLabels: { foo: 'true' } } };
|
|
1114
|
+
|
|
1115
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
1116
|
+
props: {
|
|
1117
|
+
targets: [target1],
|
|
1118
|
+
namespace: 'fleet-local',
|
|
1119
|
+
mode,
|
|
1120
|
+
},
|
|
1121
|
+
});
|
|
1122
|
+
|
|
1123
|
+
wrapper.setData({ targetMode: 'clusters' });
|
|
1124
|
+
|
|
1125
|
+
wrapper.vm.update();
|
|
1126
|
+
await flushPromises();
|
|
1127
|
+
|
|
1128
|
+
expect(wrapper.emitted('update:value')?.[1][0]).toStrictEqual([{ clusterSelector: { matchLabels: { foo: 'true' } } }]);
|
|
1129
|
+
});
|
|
1130
|
+
|
|
1131
|
+
it('should emit custom targets filtering out harvester rule', async() => {
|
|
1132
|
+
const target1 = {
|
|
1133
|
+
clusterSelector: {
|
|
1134
|
+
matchExpressions: [{
|
|
1135
|
+
key: 'provider.cattle.io',
|
|
1136
|
+
operator: 'NotIn',
|
|
1137
|
+
values: ['harvester']
|
|
1138
|
+
}, {
|
|
1139
|
+
key: 'foo',
|
|
1140
|
+
operator: 'In',
|
|
1141
|
+
values: ['bar']
|
|
1142
|
+
}]
|
|
1143
|
+
}
|
|
1144
|
+
};
|
|
1145
|
+
|
|
1146
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
1147
|
+
props: {
|
|
1148
|
+
targets: [target1],
|
|
1149
|
+
namespace: 'fleet-default',
|
|
1150
|
+
mode,
|
|
1151
|
+
},
|
|
1152
|
+
});
|
|
1153
|
+
|
|
1154
|
+
wrapper.setData({ targetMode: 'clusters' });
|
|
1155
|
+
|
|
1156
|
+
wrapper.vm.update();
|
|
1157
|
+
await flushPromises();
|
|
1158
|
+
|
|
1159
|
+
expect(wrapper.emitted('update:value')?.[1][0]).toStrictEqual([{
|
|
1160
|
+
clusterSelector: {
|
|
1161
|
+
matchExpressions: [{
|
|
1162
|
+
key: 'foo', operator: 'In', values: ['bar']
|
|
1163
|
+
}]
|
|
1164
|
+
}
|
|
1165
|
+
}]);
|
|
1166
|
+
});
|
|
1167
|
+
|
|
1168
|
+
it('should emit targets excluding target names and adding harvester rule', async() => {
|
|
1169
|
+
const target1 = { name: 'simple-target' };
|
|
1170
|
+
|
|
1171
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
1172
|
+
props: {
|
|
1173
|
+
targets: [target1],
|
|
1174
|
+
namespace: 'fleet-default',
|
|
1175
|
+
mode,
|
|
1176
|
+
},
|
|
1177
|
+
});
|
|
1178
|
+
|
|
1179
|
+
wrapper.vm.update();
|
|
1180
|
+
await flushPromises();
|
|
1181
|
+
|
|
1182
|
+
expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{
|
|
1183
|
+
clusterSelector: {
|
|
1184
|
+
matchExpressions: [{
|
|
1185
|
+
key: 'provider.cattle.io', operator: 'NotIn', values: ['harvester']
|
|
1186
|
+
}]
|
|
1187
|
+
}
|
|
1188
|
+
}]);
|
|
1189
|
+
});
|
|
1190
|
+
|
|
1191
|
+
it('should emit targets excluding target names and harvester rule if present in source targets', async() => {
|
|
1192
|
+
const target1 = {
|
|
1193
|
+
clusterSelector: {
|
|
1194
|
+
matchExpressions: [{
|
|
1195
|
+
key: 'provider.cattle.io',
|
|
1196
|
+
operator: 'NotIn',
|
|
1197
|
+
values: ['harvester']
|
|
1198
|
+
}]
|
|
1199
|
+
},
|
|
1200
|
+
name: 'simple-target'
|
|
1201
|
+
};
|
|
1202
|
+
|
|
1203
|
+
const wrapper = mount(FleetClusterTargets, {
|
|
1204
|
+
props: {
|
|
1205
|
+
targets: [target1],
|
|
1206
|
+
namespace: 'fleet-default',
|
|
1207
|
+
mode,
|
|
1208
|
+
},
|
|
1209
|
+
});
|
|
1210
|
+
|
|
1211
|
+
wrapper.vm.update();
|
|
1212
|
+
await flushPromises();
|
|
1213
|
+
|
|
1214
|
+
expect(wrapper.emitted('update:value')?.[0][0]).toStrictEqual([{
|
|
1215
|
+
clusterSelector: {
|
|
1216
|
+
matchExpressions: [{
|
|
1217
|
+
key: 'provider.cattle.io', operator: 'NotIn', values: ['harvester']
|
|
1218
|
+
}]
|
|
1219
|
+
}
|
|
1220
|
+
}]);
|
|
1221
|
+
});
|
|
1222
|
+
});
|
|
1223
|
+
});
|
|
1224
|
+
});
|