@rancher/shell 3.0.12-rc.2 → 3.0.12-rc.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apis/impl/apis.ts +6 -0
- package/apis/index.ts +26 -0
- package/apis/intf/resources-api/cluster-api.ts +18 -0
- package/apis/intf/resources-api/mgmt-api.ts +15 -0
- package/apis/intf/resources-api/resource-base.ts +107 -0
- package/apis/intf/resources-api/resource-constants.ts +147 -0
- package/apis/intf/resources-api/resources-api.ts +143 -0
- package/apis/intf/resources.ts +49 -0
- package/apis/intf/{modal.ts → shell-api/modal.ts} +21 -26
- package/apis/intf/shell-api/proxy.ts +216 -0
- package/apis/intf/{slide-in.ts → shell-api/slide-in.ts} +4 -3
- package/apis/intf/{system.ts → shell-api/system.ts} +4 -1
- package/apis/intf/shell.ts +12 -6
- package/apis/resources/__tests__/resources-api-class.test.ts +550 -0
- package/apis/resources/index.ts +22 -0
- package/apis/resources/resources-api-class.ts +187 -0
- package/apis/shell/__tests__/proxy.test.ts +369 -0
- package/apis/shell/index.ts +8 -1
- package/apis/shell/modal.ts +4 -1
- package/apis/shell/notifications.ts +9 -6
- package/apis/shell/proxy.ts +256 -0
- package/apis/shell/slide-in.ts +4 -1
- package/apis/vue-shim.d.ts +2 -1
- package/assets/data/aws-regions.json +4 -0
- package/assets/fonts/lato/LatoLatin-Black.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Black.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-BlackItalic.woff +0 -0
- package/assets/fonts/lato/LatoLatin-BlackItalic.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-Bold.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Bold.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-BoldItalic.woff +0 -0
- package/assets/fonts/lato/LatoLatin-BoldItalic.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-Heavy.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Heavy.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-HeavyItalic.woff +0 -0
- package/assets/fonts/lato/LatoLatin-HeavyItalic.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-Italic.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Italic.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-Light.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Light.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-LightItalic.woff +0 -0
- package/assets/fonts/lato/LatoLatin-LightItalic.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-Medium.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Medium.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-MediumItalic.woff +0 -0
- package/assets/fonts/lato/LatoLatin-MediumItalic.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-Regular.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Regular.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-Semibold.woff +0 -0
- package/assets/fonts/lato/LatoLatin-Semibold.woff2 +0 -0
- package/assets/fonts/lato/LatoLatin-SemiboldItalic.woff +0 -0
- package/assets/fonts/lato/LatoLatin-SemiboldItalic.woff2 +0 -0
- package/assets/styles/base/_variables.scss +2 -0
- package/assets/styles/fonts/_fontstack.scss +132 -8
- package/assets/styles/global/_layout.scss +4 -0
- package/assets/translations/en-us.yaml +165 -45
- package/assets/translations/zh-hans.yaml +1 -7
- package/chart/monitoring/ClusterSelector.vue +0 -21
- package/chart/monitoring/index.vue +10 -1
- package/chart/monitoring/prometheus/index.vue +6 -3
- package/components/ActionDropdownShell.vue +2 -1
- package/components/CruResource.vue +161 -14
- package/components/CruResourceFooter.vue +9 -5
- package/components/ExplorerMembers.vue +8 -4
- package/components/ExplorerProjectsNamespaces.vue +11 -7
- package/components/GrowlManager.vue +4 -0
- package/components/InstallHelmCharts.vue +2 -2
- package/components/LandingPagePreference.vue +14 -5
- package/components/MgmtNodeList.vue +184 -0
- package/components/Resource/Detail/Card/StateCard/__tests__/composables.test.ts +90 -1
- package/components/Resource/Detail/Card/StateCard/composables.ts +57 -87
- package/components/Resource/Detail/Card/StatusCard/__tests__/StatusCard.test.ts +61 -0
- package/components/Resource/Detail/Card/StatusCard/index.vue +61 -15
- package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +17 -1
- package/components/Resource/Detail/Metadata/KeyValue.vue +5 -2
- package/components/Resource/Detail/Metadata/KeyValueRow.vue +2 -6
- package/components/Resource/Detail/Metadata/index.vue +6 -0
- package/components/Resource/Detail/ResourcePopover/index.vue +12 -1
- package/components/Resource/Detail/SpacedRow.vue +3 -1
- package/components/Resource/Detail/TitleBar/index.vue +10 -11
- package/components/ResourceDetail/index.vue +1 -1
- package/components/ResourceList/Masthead.vue +19 -9
- package/components/ResourceList/index.vue +82 -1
- package/components/RichTranslation.vue +5 -2
- package/components/SelectIconGrid.vue +0 -10
- package/components/Setting.vue +1 -0
- package/components/SingleClusterInfo.vue +1 -0
- package/components/SortableTable/__tests__/sorting.test.ts +126 -0
- package/components/SortableTable/index.vue +6 -9
- package/components/SortableTable/selection.js +23 -5
- package/components/SortableTable/sorting.js +6 -3
- package/components/SubtleLink.vue +31 -6
- package/components/Tabbed/Tab.vue +29 -3
- package/components/Tabbed/index.vue +25 -3
- package/components/TableOfContents/TableOfContents.vue +109 -0
- package/components/TableOfContents/composables.ts +258 -0
- package/components/Window/ContainerShell.vue +21 -11
- package/components/Window/__tests__/ContainerShell.test.ts +107 -37
- package/components/Wizard.vue +23 -17
- package/components/fleet/AppCoChartGrid.vue +401 -0
- package/components/fleet/AppCoEmptyState.vue +127 -0
- package/components/fleet/AppCoPageHeader.vue +119 -0
- package/components/fleet/AppCoVersionSelect.vue +70 -0
- package/components/fleet/FleetBundles.vue +100 -12
- package/components/fleet/FleetClusterTargets/ClusterSelectionFields.vue +217 -0
- package/components/fleet/FleetClusterTargets/TargetsList.vue +123 -35
- package/components/fleet/FleetClusterTargets/index.vue +226 -161
- package/components/fleet/FleetIntro.vue +7 -3
- package/components/fleet/FleetNoWorkspaces.vue +7 -3
- package/components/fleet/FleetSecretSelector.vue +5 -3
- package/components/fleet/FleetValuesFrom.vue +8 -2
- package/components/fleet/GitRepoTargetTab.vue +0 -2
- package/components/fleet/HelmOpAdvancedTab.vue +19 -53
- package/components/fleet/HelmOpAppCoConfigTab.vue +593 -0
- package/components/fleet/HelmOpAppCoResourcesSection.vue +162 -0
- package/components/fleet/HelmOpResourcesSection.vue +82 -0
- package/components/fleet/HelmOpTargetOptionsSection.vue +89 -0
- package/components/fleet/HelmOpTargetTab.vue +64 -60
- package/components/fleet/HelmOpValuesTab.vue +129 -105
- package/components/fleet/__tests__/AppCoEmptyState.test.ts +71 -0
- package/components/fleet/__tests__/AppCoVersionSelect.test.ts +36 -0
- package/components/fleet/__tests__/ClusterSelectionFields.test.ts +62 -0
- package/components/fleet/__tests__/FleetClusterTargets.test.ts +402 -115
- package/components/fleet/__tests__/FleetClusters.test.ts +12 -12
- package/components/fleet/__tests__/FleetSecretSelector.test.ts +16 -0
- package/components/fleet/__tests__/FleetValuesFrom.test.ts +44 -0
- package/components/fleet/__tests__/HelmOpAppCoConfigTab.test.ts +59 -0
- package/components/fleet/__tests__/HelmOpAppCoResourcesSection.test.ts +62 -0
- package/components/fleet/__tests__/HelmOpResourcesSection.test.ts +43 -0
- package/components/fleet/__tests__/HelmOpTargetOptionsSection.test.ts +34 -0
- package/components/fleet/__tests__/HelmOpValuesTab.test.ts +39 -0
- package/components/fleet/__tests__/__snapshots__/AppCoEmptyState.test.ts.snap +97 -0
- package/components/fleet/__tests__/__snapshots__/AppCoVersionSelect.test.ts.snap +30 -0
- package/components/fleet/__tests__/__snapshots__/ClusterSelectionFields.test.ts.snap +209 -0
- package/components/fleet/__tests__/__snapshots__/HelmOpTargetOptionsSection.test.ts.snap +140 -0
- package/components/fleet/dashboard/Empty.vue +8 -4
- package/components/fleet/dashboard/ResourceCard.vue +28 -0
- package/components/fleet/dashboard/ResourceDetails.vue +28 -0
- package/components/fleet/dashboard/__tests__/ResourceCard.test.ts +87 -0
- package/components/form/ArrayList.vue +61 -4
- package/components/form/KeyValue.vue +23 -2
- package/components/form/LabeledSelect.vue +59 -4
- package/components/form/Labels.vue +22 -3
- package/components/form/NameNsDescription.vue +24 -5
- package/components/form/ResourceTabs/index.vue +1 -0
- package/components/form/Security.vue +6 -2
- package/components/form/WorkloadPorts.vue +2 -7
- package/components/form/__tests__/NameNsDescription.test.ts +75 -0
- package/components/form/__tests__/Security.test.ts +76 -0
- package/components/formatter/Autoscaler.vue +4 -4
- package/components/formatter/ClusterKubeVersion.vue +27 -0
- package/components/formatter/ClusterLink.vue +1 -7
- package/components/formatter/ClusterProvider.vue +6 -10
- package/components/formatter/FleetSummaryGraph.vue +0 -3
- package/components/formatter/InternalExternalIP.vue +10 -4
- package/components/formatter/MachineSummaryGraph.vue +1 -1
- package/components/formatter/PodsUsage.vue +2 -2
- package/components/formatter/ServiceTargets.vue +26 -7
- package/components/formatter/__tests__/Autoscaler.test.ts +19 -22
- package/components/formatter/__tests__/FleetSummaryGraph.test.ts +216 -0
- package/components/formatter/__tests__/InternalExternalIP.test.ts +132 -0
- package/components/formatter/__tests__/PodsUsage.test.ts +6 -10
- package/components/formatter/__tests__/ServiceTargets.test.ts +412 -0
- package/components/nav/Header.vue +4 -0
- package/components/nav/NamespaceFilter.vue +2 -2
- package/components/nav/TopLevelMenu.helper.ts +15 -3
- package/components/nav/TopLevelMenu.vue +22 -6
- package/components/nav/__tests__/Header.test.ts +15 -0
- package/components/nav/__tests__/TopLevelMenu.test.ts +263 -21
- package/components/templates/default.vue +9 -4
- package/components/templates/home.vue +23 -0
- package/components/templates/plain.vue +23 -0
- package/components/templates/standalone.vue +17 -0
- package/composables/useFormValidation.ts +93 -0
- package/composables/useHelmOpResources.test.ts +56 -0
- package/composables/useHelmOpResources.ts +32 -0
- package/composables/useStateColor.test.ts +325 -0
- package/composables/useStateColor.ts +128 -0
- package/composables/useVeeValidateField.test.ts +159 -0
- package/composables/useVeeValidateField.ts +67 -0
- package/config/home-links.js +1 -1
- package/config/labels-annotations.js +1 -0
- package/config/pagination-table-headers.js +18 -1
- package/config/product/explorer.js +17 -4
- package/config/product/manager.js +84 -21
- package/config/router/index.js +16 -0
- package/config/router/navigation-guards/__tests__/authentication.test.ts +130 -0
- package/config/router/navigation-guards/authentication.js +10 -4
- package/config/router/routes.js +26 -6
- package/config/settings.ts +0 -2
- package/config/table-headers.js +23 -5
- package/config/types.js +11 -1
- package/core/__tests__/plugin-products.test.ts +904 -20
- package/core/plugin-products-base.ts +110 -10
- package/core/plugin-products.ts +4 -0
- package/core/plugin-types.ts +194 -31
- package/core/plugin.ts +18 -7
- package/core/productDebugger.js +9 -4
- package/core/types-provisioning.ts +77 -31
- package/core/types.ts +72 -22
- package/detail/__tests__/pod.test.ts +41 -0
- package/detail/__tests__/provisioning.cattle.io.cluster.test.ts +114 -0
- package/detail/__tests__/workload.test.ts +3 -152
- package/detail/catalog.cattle.io.clusterrepo.vue +1 -1
- package/detail/harvesterhci.io.management.cluster.vue +6 -2
- package/detail/pod.vue +1 -1
- package/detail/provisioning.cattle.io.cluster.vue +34 -14
- package/detail/workload/index.vue +12 -55
- package/edit/__tests__/catalog.cattle.io.clusterrepo.test.ts +248 -0
- package/edit/__tests__/fleet.cattle.io.helmop.test.ts +105 -0
- package/edit/auditlog.cattle.io.auditpolicy/__tests__/__snapshots__/General.test.ts.snap +6 -0
- package/edit/auditlog.cattle.io.auditpolicy/__tests__/__snapshots__/index.test.ts.snap +1 -0
- package/edit/auth/__tests__/azuread.test.ts +247 -39
- package/edit/auth/__tests__/github.test.ts +234 -0
- package/edit/auth/__tests__/oidc.test.ts +26 -6
- package/edit/auth/__tests__/saml.test.ts +196 -0
- package/edit/auth/azuread.vue +197 -56
- package/edit/auth/github.vue +72 -13
- package/edit/auth/ldap/__tests__/index.test.ts +206 -0
- package/edit/auth/ldap/config.vue +8 -0
- package/edit/auth/ldap/index.vue +75 -1
- package/edit/auth/oidc.vue +119 -73
- package/edit/auth/saml.vue +76 -12
- package/edit/catalog.cattle.io.clusterrepo.vue +140 -32
- package/edit/fleet.cattle.io.helmop.vue +491 -136
- package/edit/management.cattle.io.user.vue +5 -2
- package/edit/networking.k8s.io.ingress/DefaultBackend.vue +13 -4
- package/edit/networking.k8s.io.ingress/RulePath.vue +8 -4
- package/edit/networking.k8s.io.ingress/index.vue +75 -20
- package/edit/provisioning.cattle.io.cluster/__tests__/MachinePool.test.ts +104 -0
- package/edit/provisioning.cattle.io.cluster/index.vue +11 -7
- package/edit/provisioning.cattle.io.cluster/rke2.vue +92 -14
- package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +22 -0
- package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +37 -4
- package/edit/provisioning.cattle.io.cluster/tabs/registries/__tests__/RegistryConfigs.test.ts +132 -7
- package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +2 -1
- package/edit/secret/__tests__/ssh.test.ts +5 -6
- package/edit/secret/basic.vue +31 -0
- package/edit/secret/index.vue +68 -17
- package/edit/secret/registry.vue +38 -0
- package/edit/secret/ssh.vue +29 -0
- package/edit/secret/tls.vue +30 -0
- package/edit/service.vue +4 -4
- package/edit/workload/Upgrading.vue +3 -3
- package/edit/workload/__tests__/Upgrading.test.ts +6 -9
- package/edit/workload/mixins/workload.js +2 -1
- package/list/fleet.cattle.io.bundle.vue +7 -104
- package/list/fleet.cattle.io.clusterregistrationtoken.vue +20 -0
- package/list/group.principal.vue +5 -4
- package/list/harvesterhci.io.management.cluster.vue +8 -9
- package/list/management.cattle.io.user.vue +12 -9
- package/list/provisioning.cattle.io.cluster.vue +268 -180
- package/list/utils/management.cattle.io.cluster.utils.ts +128 -0
- package/mixins/__tests__/auth-config.test.ts +90 -0
- package/mixins/__tests__/chart.test.ts +206 -0
- package/mixins/__tests__/resource-fetch-api-pagination.test.ts +48 -0
- package/mixins/auth-config.js +7 -0
- package/mixins/brand.js +2 -1
- package/mixins/chart.js +22 -9
- package/mixins/child-hook.js +12 -6
- package/mixins/create-edit-view/impl.js +5 -3
- package/mixins/resource-fetch-api-pagination.js +62 -6
- package/models/__tests__/catalog.cattle.io.clusterrepo.test.ts +57 -0
- package/models/__tests__/compliance.cattle.io.clusterscan.test.ts +144 -0
- package/models/__tests__/ext.cattle.io.kubeconfig.test.ts +67 -67
- package/models/__tests__/fleet-application.test.ts +175 -0
- package/models/__tests__/fleet.cattle.io.bundle.test.ts +169 -0
- package/models/__tests__/fleet.cattle.io.helmop.test.ts +84 -0
- package/models/__tests__/management.cattle.io.cluster.test.ts +1 -1
- package/models/__tests__/management.cattle.io.node.ts +28 -5
- package/models/__tests__/management.cattle.io.nodepool.ts +5 -4
- package/models/__tests__/namespace.test.ts +36 -0
- package/models/__tests__/provisioning.cattle.io.cluster.test.ts +81 -11
- package/models/__tests__/workload.test.ts +401 -26
- package/models/base-cluster.x-k8s.io.js +26 -0
- package/models/catalog.cattle.io.clusterrepo.js +28 -4
- package/models/cluster.js +1 -1
- package/models/cluster.x-k8s.io.machine.js +4 -22
- package/models/cluster.x-k8s.io.machinedeployment.js +2 -20
- package/models/cluster.x-k8s.io.machineset.js +2 -20
- package/models/compliance.cattle.io.clusterscan.js +165 -2
- package/models/ext.cattle.io.kubeconfig.ts +4 -7
- package/models/fleet-application.js +7 -1
- package/models/fleet.cattle.io.helmop.js +20 -1
- package/models/management.cattle.io.cluster.js +434 -41
- package/models/management.cattle.io.node.js +50 -7
- package/models/management.cattle.io.nodepool.js +1 -1
- package/models/namespace.js +1 -1
- package/models/networking.k8s.io.ingress.js +12 -4
- package/models/pod.js +33 -1
- package/models/provisioning.cattle.io.cluster.js +51 -334
- package/models/rke.cattle.io.etcdsnapshot.js +1 -2
- package/models/workload.js +108 -13
- package/models/workload.service.js +5 -0
- package/package.json +22 -39
- package/pages/__tests__/readme.test.ts +49 -0
- package/pages/about.vue +5 -6
- package/pages/auth/login.vue +0 -35
- package/pages/auth/setup.vue +13 -3
- package/pages/c/_cluster/apps/charts/AppChartCardFooter.vue +2 -2
- package/pages/c/_cluster/apps/charts/AppChartCardSubHeader.vue +10 -1
- package/pages/c/_cluster/apps/charts/__tests__/chart.test.ts +76 -0
- package/pages/c/_cluster/apps/charts/__tests__/index.test.ts +93 -0
- package/pages/c/_cluster/apps/charts/chart.vue +62 -9
- package/pages/c/_cluster/apps/charts/index.vue +48 -10
- package/pages/c/_cluster/apps/charts/install.vue +122 -113
- package/pages/c/_cluster/auth/roles/index.vue +5 -4
- package/pages/c/_cluster/explorer/__tests__/index.test.ts +23 -25
- package/pages/c/_cluster/explorer/index.vue +5 -49
- package/pages/c/_cluster/explorer/workload-dashboard/ByNamespaceSection.vue +31 -0
- package/pages/c/_cluster/explorer/workload-dashboard/ByStateSection.vue +138 -0
- package/pages/c/_cluster/explorer/workload-dashboard/ByTypeSection.vue +30 -0
- package/pages/c/_cluster/explorer/workload-dashboard/WorkloadCard.vue +155 -0
- package/pages/c/_cluster/explorer/workload-dashboard/WorkloadNamespaceCard.vue +142 -0
- package/pages/c/_cluster/explorer/workload-dashboard/WorkloadTypeCard.vue +159 -0
- package/pages/c/_cluster/explorer/workload-dashboard/__tests__/composable.test.ts +561 -0
- package/pages/c/_cluster/explorer/workload-dashboard/composable.ts +440 -0
- package/pages/c/_cluster/explorer/workload-dashboard/index.vue +187 -0
- package/pages/c/_cluster/explorer/workload-dashboard/types.ts +80 -0
- package/pages/c/_cluster/fleet/application/create.vue +187 -136
- package/pages/c/_cluster/fleet/application/index.vue +5 -3
- package/pages/c/_cluster/fleet/application/suse-app-collection/ChartDetailBody.vue +338 -0
- package/pages/c/_cluster/fleet/application/suse-app-collection/ChartDetailHeader.vue +121 -0
- package/pages/c/_cluster/fleet/application/suse-app-collection/chart.vue +369 -0
- package/pages/c/_cluster/fleet/application/suse-app-collection/charts.vue +248 -0
- package/pages/c/_cluster/fleet/application/suse-app-collection/credentials.vue +310 -0
- package/pages/c/_cluster/fleet/index.vue +2 -2
- package/pages/c/_cluster/istio/__tests__/istio.index.test.ts +194 -0
- package/pages/c/_cluster/istio/index.vue +21 -6
- package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +1 -0
- package/pages/c/_cluster/uiplugins/__tests__/index.test.ts +815 -2
- package/pages/c/_cluster/uiplugins/index.vue +218 -197
- package/pages/diagnostic.vue +13 -17
- package/pages/fail-whale.vue +30 -7
- package/pages/home.vue +93 -306
- package/pages/readme.vue +88 -0
- package/plugins/clean-html.d.ts +9 -0
- package/plugins/dashboard-store/__tests__/resource-class.test.ts +181 -0
- package/plugins/dashboard-store/actions.js +40 -18
- package/plugins/dashboard-store/resource-class.js +67 -9
- package/plugins/steve/__tests__/actions.test.ts +212 -0
- package/plugins/steve/__tests__/subscribe.spec.ts +6 -3
- package/plugins/steve/actions.js +96 -0
- package/plugins/steve/steve-pagination-utils.ts +12 -4
- package/plugins/steve/subscribe.js +35 -5
- package/rancher-components/Accordion/Accordion.vue +53 -9
- package/rancher-components/Form/Checkbox/Checkbox.vue +14 -0
- package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +10 -4
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +7 -52
- package/rancher-components/Form/Radio/RadioButton.vue +17 -1
- package/rancher-components/Form/Radio/RadioGroup.vue +10 -0
- package/rancher-components/Pill/RcTag/RcTag.vue +3 -2
- package/rancher-components/RcButton/RcButton.test.ts +140 -1
- package/rancher-components/RcButton/RcButton.vue +126 -17
- package/rancher-components/RcButton/types.ts +3 -0
- package/rancher-components/RcDropdown/RcDropdownTrigger.vue +10 -8
- package/rancher-components/RcItemCard/RcItemCard.test.ts +18 -0
- package/rancher-components/RcItemCard/RcItemCard.vue +2 -2
- package/rancher-components/RcSection/RcSection.vue +28 -3
- package/scripts/extension/helm/package/Dockerfile +1 -1
- package/scripts/test-plugins-build.sh +2 -1
- package/store/__tests__/catalog.test.ts +115 -1
- package/store/__tests__/notifications.test.ts +434 -0
- package/store/__tests__/type-map.test.ts +556 -1
- package/store/action-menu.js +8 -3
- package/store/auth.js +1 -1
- package/store/aws.js +27 -16
- package/store/catalog.js +84 -3
- package/store/digitalocean.js +20 -38
- package/store/index.js +2 -0
- package/store/linode.js +25 -40
- package/store/plugins.js +7 -4
- package/store/pnap.js +1 -0
- package/store/type-map.js +111 -29
- package/tsconfig.paths.json +8 -8
- package/types/components/buttonGroup.ts +5 -0
- package/types/kube/kube-api.ts +14 -1
- package/types/rancher/steve.api.ts +12 -12
- package/types/resources/settings.d.ts +2 -1
- package/types/shell/index.d.ts +206 -72
- package/types/store/dashboard-store.types.ts +108 -11
- package/types/store/pagination.types.ts +6 -3
- package/utils/__tests__/alertmanagerconfig.test.ts +117 -0
- package/utils/__tests__/async.test.ts +87 -0
- package/utils/__tests__/auth.test.ts +273 -0
- package/utils/__tests__/aws.test.ts +140 -0
- package/utils/__tests__/banners.test.ts +176 -0
- package/utils/__tests__/chart.test.ts +64 -1
- package/utils/__tests__/color.test.ts +226 -0
- package/utils/__tests__/computed.test.ts +193 -0
- package/utils/__tests__/cspAdaptor.test.ts +163 -0
- package/utils/__tests__/dom.test.ts +81 -0
- package/utils/__tests__/duration.test.ts +176 -0
- package/utils/__tests__/dynamic-importer.test.ts +102 -0
- package/utils/__tests__/fleet-appco.test.ts +312 -0
- package/utils/__tests__/fleet.test.ts +340 -0
- package/utils/__tests__/ingress.test.ts +553 -0
- package/utils/__tests__/kube.test.ts +68 -0
- package/utils/__tests__/monitoring.test.ts +130 -0
- package/utils/__tests__/namespace-filter.test.ts +109 -0
- package/utils/__tests__/object.test.ts +22 -0
- package/utils/__tests__/pagination-utils.test.ts +361 -0
- package/utils/__tests__/parse-externalid.test.ts +137 -0
- package/utils/__tests__/perf-setting.utils.test.ts +98 -0
- package/utils/__tests__/platform.test.ts +91 -0
- package/utils/__tests__/poller-sequential.test.ts +177 -0
- package/utils/__tests__/poller.test.ts +170 -0
- package/utils/__tests__/position.test.ts +237 -0
- package/utils/__tests__/promise.test.ts +346 -0
- package/utils/__tests__/provider.test.ts +51 -1
- package/utils/__tests__/queue.test.ts +232 -0
- package/utils/__tests__/release-notes.test.ts +221 -0
- package/utils/__tests__/router.test.js +254 -1
- package/utils/__tests__/select.test.ts +208 -0
- package/utils/__tests__/settings.test.ts +140 -0
- package/utils/__tests__/sort-utils.test.ts +301 -0
- package/utils/__tests__/string-utils.test.ts +798 -0
- package/utils/__tests__/string.test.ts +23 -1
- package/utils/__tests__/style.test.ts +154 -0
- package/utils/__tests__/svg-filter.test.ts +184 -0
- package/utils/__tests__/time.test.ts +265 -1
- package/utils/__tests__/title.test.ts +47 -0
- package/utils/__tests__/units.test.ts +417 -0
- package/utils/__tests__/versions.test.ts +128 -0
- package/utils/__tests__/width.test.ts +53 -0
- package/utils/__tests__/window.test.ts +158 -0
- package/utils/__tests__/xccdf.test.ts +511 -0
- package/utils/chart.js +36 -0
- package/utils/crypto/__tests__/browserHashUtils.test.ts +98 -0
- package/utils/crypto/__tests__/index.test.ts +144 -0
- package/utils/duration.ts +104 -0
- package/utils/dynamic-content/__tests__/notification-handler.test.ts +196 -0
- package/utils/dynamic-content/info.ts +2 -1
- package/utils/error.js +13 -0
- package/utils/fleet-appco.ts +323 -0
- package/utils/fleet.ts +13 -3
- package/utils/gatekeeper/__tests__/util.test.ts +174 -0
- package/utils/gc/__tests__/gc-interval.test.ts +119 -0
- package/utils/gc/__tests__/gc-root-store.test.ts +225 -0
- package/utils/gc/__tests__/gc-route-changed.test.ts +96 -0
- package/utils/gc/__tests__/gc.test.ts +487 -0
- package/utils/ingress.ts +9 -1
- package/utils/object.js +22 -2
- package/utils/pagination-utils.ts +2 -1
- package/utils/provider.ts +12 -0
- package/utils/string.js +25 -2
- package/utils/uiplugins.ts +5 -5
- package/utils/validators/__tests__/cluster-name.test.ts +110 -0
- package/utils/validators/__tests__/container-images.test.ts +104 -0
- package/utils/validators/__tests__/cron-schedule.test.ts +79 -0
- package/utils/validators/__tests__/flow-output.test.ts +91 -0
- package/utils/validators/__tests__/index.test.ts +481 -0
- package/utils/validators/__tests__/kubernetes-name.test.ts +163 -0
- package/utils/validators/__tests__/logging-outputs.test.ts +58 -0
- package/utils/validators/__tests__/misc-validators.test.ts +246 -0
- package/utils/validators/__tests__/monitoring-route.test.ts +119 -0
- package/utils/validators/__tests__/pod-affinity.test.ts +382 -0
- package/utils/validators/__tests__/prometheusrule.test.ts +211 -0
- package/utils/validators/__tests__/role-template.test.ts +149 -0
- package/utils/validators/__tests__/service.test.ts +283 -0
- package/utils/validators/__tests__/setting.test.js +32 -0
- package/utils/validators/formRules/__tests__/index.test.ts +50 -0
- package/utils/validators/formRules/index.ts +5 -5
- package/utils/validators/machine-pool.ts +1 -1
- package/utils/validators/setting.js +18 -3
- package/utils/xccdf.ts +415 -0
- package/vue.config.js +1 -1
- package/assets/fonts/lato/lato-v17-latin-700.woff +0 -0
- package/assets/fonts/lato/lato-v17-latin-700.woff2 +0 -0
- package/assets/fonts/lato/lato-v17-latin-regular.woff +0 -0
- package/assets/fonts/lato/lato-v17-latin-regular.woff2 +0 -0
- package/pages/support/index.vue +0 -264
- package/utils/duration.js +0 -43
|
@@ -69,4 +69,94 @@ describe('mixin: authConfigMixin', () => {
|
|
|
69
69
|
expect(instance.model.scope).toStrictEqual(scope);
|
|
70
70
|
});
|
|
71
71
|
});
|
|
72
|
+
|
|
73
|
+
describe('accessMode on enable', () => {
|
|
74
|
+
const FakeComponent = {
|
|
75
|
+
render() {},
|
|
76
|
+
mixins: [authConfigMixin, childHook],
|
|
77
|
+
methods: { applyHooks: jest.fn() },
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const createMock = (model: any, overrides: Record<string, any> = {}) => ({
|
|
81
|
+
data: () => ({
|
|
82
|
+
value: { configType: 'oidc' },
|
|
83
|
+
model,
|
|
84
|
+
...overrides,
|
|
85
|
+
}),
|
|
86
|
+
computed: { principal: () => ({ me: {} }) },
|
|
87
|
+
global: {
|
|
88
|
+
mocks: {
|
|
89
|
+
$store: { dispatch: () => model },
|
|
90
|
+
$route: {
|
|
91
|
+
params: { id: model.id || '123' },
|
|
92
|
+
query: { mode: 'edit' },
|
|
93
|
+
},
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it.each([
|
|
99
|
+
'github',
|
|
100
|
+
'githubapp',
|
|
101
|
+
])('should default accessMode to restricted for %s on enable', async(id) => {
|
|
102
|
+
const model = {
|
|
103
|
+
id,
|
|
104
|
+
enabled: false,
|
|
105
|
+
authConfigName: 'whatever',
|
|
106
|
+
doAction: jest.fn(),
|
|
107
|
+
save: jest.fn(),
|
|
108
|
+
};
|
|
109
|
+
const instance = mount(FakeComponent, createMock(model)).vm as any;
|
|
110
|
+
|
|
111
|
+
await instance.save(jest.fn());
|
|
112
|
+
|
|
113
|
+
expect(model.save).toHaveBeenCalled();
|
|
114
|
+
expect(instance.model.accessMode).toStrictEqual('required');
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('should default accessMode to unrestricted for non-github oauth on enable', async() => {
|
|
118
|
+
const model = {
|
|
119
|
+
id: 'googleoauth',
|
|
120
|
+
enabled: false,
|
|
121
|
+
authConfigName: 'whatever',
|
|
122
|
+
doAction: jest.fn(),
|
|
123
|
+
save: jest.fn(),
|
|
124
|
+
};
|
|
125
|
+
const instance = mount(FakeComponent, createMock(model)).vm as any;
|
|
126
|
+
|
|
127
|
+
await instance.save(jest.fn());
|
|
128
|
+
|
|
129
|
+
expect(instance.model.accessMode).toStrictEqual('required');
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('should set accessMode to required after enabling a provider', async() => {
|
|
133
|
+
const model = {
|
|
134
|
+
enabled: false,
|
|
135
|
+
accessMode: 'unrestricted',
|
|
136
|
+
authConfigName: 'whatever',
|
|
137
|
+
doAction: jest.fn(),
|
|
138
|
+
save: async() => {}
|
|
139
|
+
};
|
|
140
|
+
const instance = mount(FakeComponent, createMock(model)).vm as any;
|
|
141
|
+
|
|
142
|
+
await instance.save(jest.fn());
|
|
143
|
+
|
|
144
|
+
expect(instance.model.accessMode).toStrictEqual('required');
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('should not change accessMode when editing an already enabled provider', async() => {
|
|
148
|
+
const model = {
|
|
149
|
+
enabled: true,
|
|
150
|
+
accessMode: 'unrestricted',
|
|
151
|
+
authConfigName: 'whatever',
|
|
152
|
+
doAction: jest.fn(),
|
|
153
|
+
save: async() => {}
|
|
154
|
+
};
|
|
155
|
+
const instance = mount(FakeComponent, createMock(model, { editConfig: true })).vm as any;
|
|
156
|
+
|
|
157
|
+
await instance.save(jest.fn());
|
|
158
|
+
|
|
159
|
+
expect(instance.model.accessMode).toStrictEqual('unrestricted');
|
|
160
|
+
});
|
|
161
|
+
});
|
|
72
162
|
});
|
|
@@ -214,6 +214,72 @@ describe('chartMixin', () => {
|
|
|
214
214
|
id: 'custom-ns/custom-name'
|
|
215
215
|
});
|
|
216
216
|
});
|
|
217
|
+
|
|
218
|
+
it('should fall back to matchingInstalledApps when version namespace lookup fails', async() => {
|
|
219
|
+
const installedApp = {
|
|
220
|
+
id: 'other-ns/custom-name',
|
|
221
|
+
spec: { chart: { metadata: { version: '0.9.0' } } }
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
const mockStore = {
|
|
225
|
+
dispatch: jest.fn((action, payload) => {
|
|
226
|
+
if (action === 'cluster/find') {
|
|
227
|
+
return Promise.reject(new Error('not found'));
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return Promise.resolve();
|
|
231
|
+
}),
|
|
232
|
+
getters: {
|
|
233
|
+
currentCluster: () => {},
|
|
234
|
+
isRancher: () => true,
|
|
235
|
+
'catalog/repo': () => {
|
|
236
|
+
return () => 'repo';
|
|
237
|
+
},
|
|
238
|
+
'catalog/chart': () => {
|
|
239
|
+
return {
|
|
240
|
+
id: 'chart-id',
|
|
241
|
+
versions: [{ version: '1.0.0' }],
|
|
242
|
+
matchingInstalledApps: [installedApp]
|
|
243
|
+
};
|
|
244
|
+
},
|
|
245
|
+
'catalog/version': () => ({
|
|
246
|
+
version: '1.0.0',
|
|
247
|
+
annotations: {
|
|
248
|
+
[CATALOG_ANNOTATIONS.NAMESPACE]: 'custom-ns',
|
|
249
|
+
[CATALOG_ANNOTATIONS.RELEASE_NAME]: 'custom-name',
|
|
250
|
+
}
|
|
251
|
+
}),
|
|
252
|
+
'prefs/get': () => {},
|
|
253
|
+
'i18n/t': () => jest.fn()
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
const DummyComponent = {
|
|
258
|
+
mixins: [ChartMixin],
|
|
259
|
+
template: '<div></div>',
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
const wrapper = mount(
|
|
263
|
+
DummyComponent,
|
|
264
|
+
{
|
|
265
|
+
global: {
|
|
266
|
+
mocks: {
|
|
267
|
+
$store: mockStore,
|
|
268
|
+
$route: {
|
|
269
|
+
query: {
|
|
270
|
+
chart: 'chart_name',
|
|
271
|
+
versionName: '1.0.0'
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
await wrapper.vm.fetchChart();
|
|
279
|
+
|
|
280
|
+
expect(wrapper.vm.existing).toStrictEqual(installedApp);
|
|
281
|
+
expect(wrapper.vm.mode).toStrictEqual('edit');
|
|
282
|
+
});
|
|
217
283
|
});
|
|
218
284
|
|
|
219
285
|
describe('action', () => {
|
|
@@ -366,6 +432,52 @@ describe('chartMixin', () => {
|
|
|
366
432
|
});
|
|
367
433
|
});
|
|
368
434
|
|
|
435
|
+
describe('isChartTargeted', () => {
|
|
436
|
+
const DummyComponent = {
|
|
437
|
+
mixins: [ChartMixin],
|
|
438
|
+
template: '<div></div>',
|
|
439
|
+
};
|
|
440
|
+
|
|
441
|
+
const mockStore = {
|
|
442
|
+
dispatch: jest.fn(() => Promise.resolve()),
|
|
443
|
+
getters: { 'i18n/t': (key: string) => key }
|
|
444
|
+
};
|
|
445
|
+
|
|
446
|
+
it('should return truthy when version annotations have both namespace and release-name', () => {
|
|
447
|
+
const wrapper = mount(DummyComponent, {
|
|
448
|
+
data: () => ({
|
|
449
|
+
version: {
|
|
450
|
+
annotations: {
|
|
451
|
+
[CATALOG_ANNOTATIONS.NAMESPACE]: 'custom-ns',
|
|
452
|
+
[CATALOG_ANNOTATIONS.RELEASE_NAME]: 'custom-name',
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}),
|
|
456
|
+
global: { mocks: { $store: mockStore } }
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
expect(wrapper.vm.isChartTargeted).toBeTruthy();
|
|
460
|
+
});
|
|
461
|
+
|
|
462
|
+
it('should return falsy when version annotations are missing', () => {
|
|
463
|
+
const wrapper = mount(DummyComponent, {
|
|
464
|
+
data: () => ({ version: { annotations: {} } }),
|
|
465
|
+
global: { mocks: { $store: mockStore } }
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
expect(wrapper.vm.isChartTargeted).toBeFalsy();
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
it('should return falsy when version is null', () => {
|
|
472
|
+
const wrapper = mount(DummyComponent, {
|
|
473
|
+
data: () => ({ version: null }),
|
|
474
|
+
global: { mocks: { $store: mockStore } }
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
expect(wrapper.vm.isChartTargeted).toBeFalsy();
|
|
478
|
+
});
|
|
479
|
+
});
|
|
480
|
+
|
|
369
481
|
describe('mappedVersions', () => {
|
|
370
482
|
it('should return versions sorted by semver (descending)', () => {
|
|
371
483
|
const versions = [
|
|
@@ -469,5 +581,99 @@ describe('chartMixin', () => {
|
|
|
469
581
|
'0.0.1'
|
|
470
582
|
]);
|
|
471
583
|
});
|
|
584
|
+
|
|
585
|
+
it('should correctly format current version when it is Linux-only', () => {
|
|
586
|
+
const versions = [
|
|
587
|
+
{
|
|
588
|
+
version: '1.0.0',
|
|
589
|
+
created: '2026-01-01',
|
|
590
|
+
annotations: { 'catalog.cattle.io/permits-os': 'linux' }
|
|
591
|
+
}
|
|
592
|
+
];
|
|
593
|
+
|
|
594
|
+
const mockStore = {
|
|
595
|
+
dispatch: jest.fn(() => Promise.resolve()),
|
|
596
|
+
getters: {
|
|
597
|
+
currentCluster: () => ({ workerOSs: ['linux'] }),
|
|
598
|
+
isRancher: () => true,
|
|
599
|
+
'catalog/repo': () => () => 'repo',
|
|
600
|
+
'catalog/chart': () => ({ versions }),
|
|
601
|
+
'prefs/get': () => () => true,
|
|
602
|
+
'i18n/t': () => jest.fn()
|
|
603
|
+
}
|
|
604
|
+
};
|
|
605
|
+
|
|
606
|
+
const DummyComponent = {
|
|
607
|
+
mixins: [ChartMixin],
|
|
608
|
+
template: '<div></div>',
|
|
609
|
+
};
|
|
610
|
+
|
|
611
|
+
const wrapper = mount(
|
|
612
|
+
DummyComponent,
|
|
613
|
+
{
|
|
614
|
+
data: () => ({
|
|
615
|
+
chart: { versions },
|
|
616
|
+
existing: { spec: { chart: { metadata: { version: '1.0.0' } } } }
|
|
617
|
+
}),
|
|
618
|
+
global: {
|
|
619
|
+
mocks: {
|
|
620
|
+
$store: mockStore,
|
|
621
|
+
$route: { query: { version: '1.0.0' } },
|
|
622
|
+
t: (key: string, args: any) => `${ args?.ver } (Current, Linux-only)`
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
});
|
|
626
|
+
|
|
627
|
+
const result = (wrapper.vm as any).mappedVersions;
|
|
628
|
+
|
|
629
|
+
expect(result[0].label).toBe('1.0.0 (Current, Linux-only)');
|
|
630
|
+
});
|
|
631
|
+
|
|
632
|
+
it('should correctly format current version when it is not OS-restricted', () => {
|
|
633
|
+
const versions = [
|
|
634
|
+
{
|
|
635
|
+
version: '1.0.0',
|
|
636
|
+
created: '2026-01-01',
|
|
637
|
+
annotations: {}
|
|
638
|
+
}
|
|
639
|
+
];
|
|
640
|
+
|
|
641
|
+
const mockStore = {
|
|
642
|
+
dispatch: jest.fn(() => Promise.resolve()),
|
|
643
|
+
getters: {
|
|
644
|
+
currentCluster: () => ({ workerOSs: ['linux'] }),
|
|
645
|
+
isRancher: () => true,
|
|
646
|
+
'catalog/repo': () => () => 'repo',
|
|
647
|
+
'catalog/chart': () => ({ versions }),
|
|
648
|
+
'prefs/get': () => () => true,
|
|
649
|
+
'i18n/t': () => jest.fn()
|
|
650
|
+
}
|
|
651
|
+
};
|
|
652
|
+
|
|
653
|
+
const DummyComponent = {
|
|
654
|
+
mixins: [ChartMixin],
|
|
655
|
+
template: '<div></div>',
|
|
656
|
+
};
|
|
657
|
+
|
|
658
|
+
const wrapper = mount(
|
|
659
|
+
DummyComponent,
|
|
660
|
+
{
|
|
661
|
+
data: () => ({
|
|
662
|
+
chart: { versions },
|
|
663
|
+
existing: { spec: { chart: { metadata: { version: '1.0.0' } } } }
|
|
664
|
+
}),
|
|
665
|
+
global: {
|
|
666
|
+
mocks: {
|
|
667
|
+
$store: mockStore,
|
|
668
|
+
$route: { query: { version: '1.0.0' } },
|
|
669
|
+
t: (key: string, args: any) => `${ args?.ver } (Current)`
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
});
|
|
673
|
+
|
|
674
|
+
const result = (wrapper.vm as any).mappedVersions;
|
|
675
|
+
|
|
676
|
+
expect(result[0].label).toBe('1.0.0 (Current)');
|
|
677
|
+
});
|
|
472
678
|
});
|
|
473
679
|
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { parseStateFilter } from '@shell/mixins/resource-fetch-api-pagination';
|
|
2
|
+
import { PaginationFilterEquality } from '@shell/types/store/pagination.types';
|
|
3
|
+
|
|
4
|
+
describe('parseStateFilter', () => {
|
|
5
|
+
it('should return null for null input', () => {
|
|
6
|
+
expect(parseStateFilter(null)).toBeNull();
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('should return null for undefined input', () => {
|
|
10
|
+
expect(parseStateFilter(undefined)).toBeNull();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('should return null for empty string', () => {
|
|
14
|
+
expect(parseStateFilter('')).toBeNull();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('should parse a single state', () => {
|
|
18
|
+
const result = parseStateFilter('running');
|
|
19
|
+
|
|
20
|
+
expect(result).toHaveLength(1);
|
|
21
|
+
expect(result?.[0].field).toStrictEqual('metadata.state.name');
|
|
22
|
+
expect(result?.[0].value).toStrictEqual('running');
|
|
23
|
+
expect(result?.[0].equality).toStrictEqual(PaginationFilterEquality.IN);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('should parse multiple comma-separated states', () => {
|
|
27
|
+
const result = parseStateFilter('running,active');
|
|
28
|
+
|
|
29
|
+
expect(result).toHaveLength(1);
|
|
30
|
+
expect(result?.[0].field).toStrictEqual('metadata.state.name');
|
|
31
|
+
expect(result?.[0].value).toStrictEqual('running,active');
|
|
32
|
+
expect(result?.[0].equality).toStrictEqual(PaginationFilterEquality.IN);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('should parse three comma-separated states', () => {
|
|
36
|
+
const result = parseStateFilter('running,active,waiting');
|
|
37
|
+
|
|
38
|
+
expect(result).toHaveLength(1);
|
|
39
|
+
expect(result?.[0].value).toStrictEqual('running,active,waiting');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('should ignore empty segments from trailing commas', () => {
|
|
43
|
+
const result = parseStateFilter('running,,active,');
|
|
44
|
+
|
|
45
|
+
expect(result).toHaveLength(1);
|
|
46
|
+
expect(result?.[0].value).toStrictEqual('running,active');
|
|
47
|
+
});
|
|
48
|
+
});
|
package/mixins/auth-config.js
CHANGED
|
@@ -201,6 +201,9 @@ export default {
|
|
|
201
201
|
if (!this.model.accessMode) {
|
|
202
202
|
this.model.accessMode = 'unrestricted';
|
|
203
203
|
}
|
|
204
|
+
if (this.model.id === 'github' || this.model.id === 'githubapp') {
|
|
205
|
+
this.model.accessMode = 'restricted';
|
|
206
|
+
}
|
|
204
207
|
await this.model.doAction('testAndApply', obj, { redirectUnauthorized: false });
|
|
205
208
|
}
|
|
206
209
|
|
|
@@ -241,6 +244,10 @@ export default {
|
|
|
241
244
|
} else {
|
|
242
245
|
console.warn(`Unable to find principal marked as 'me'`); // eslint-disable-line no-console
|
|
243
246
|
}
|
|
247
|
+
|
|
248
|
+
if (!wasEnabled) {
|
|
249
|
+
this.model.accessMode = 'required';
|
|
250
|
+
}
|
|
244
251
|
}
|
|
245
252
|
if (wasEnabled && configType === 'oauth') {
|
|
246
253
|
await this.model.save({ ignoreFields: ['oauthCredential', 'serviceAccountCredential'] } );
|
package/mixins/brand.js
CHANGED
|
@@ -183,7 +183,8 @@ export default {
|
|
|
183
183
|
},
|
|
184
184
|
setBodyClass() {
|
|
185
185
|
const body = document.getElementsByTagName('body')[0];
|
|
186
|
-
const
|
|
186
|
+
const isStandalone = this.$route?.meta?.standalone;
|
|
187
|
+
const cssClass = isStandalone ? 'dashboard-body' : 'overflow-hidden dashboard-body';
|
|
187
188
|
let bodyClass = `theme-${ this.theme } ${ cssClass }`;
|
|
188
189
|
|
|
189
190
|
if ( this.brand ) {
|
package/mixins/chart.js
CHANGED
|
@@ -13,7 +13,7 @@ import { CAPI, CATALOG } from '@shell/config/types';
|
|
|
13
13
|
import { isPrerelease } from '@shell/utils/version';
|
|
14
14
|
import { compareChartVersions } from '@shell/utils/chart';
|
|
15
15
|
import difference from 'lodash/difference';
|
|
16
|
-
import {
|
|
16
|
+
import { APP_UPGRADE_STATUS, isRancherRepo, getPermittedOSs } from '@shell/store/catalog';
|
|
17
17
|
import { clone } from '@shell/utils/object';
|
|
18
18
|
import { merge } from 'lodash';
|
|
19
19
|
|
|
@@ -71,6 +71,8 @@ export default {
|
|
|
71
71
|
|
|
72
72
|
const selectedVersion = this.targetVersion;
|
|
73
73
|
const OSs = this.currentCluster?.workerOSs;
|
|
74
|
+
const isRancher = isRancherRepo(this.repo, this.chart);
|
|
75
|
+
const permittedSystemsByVersion = new Map();
|
|
74
76
|
const out = [];
|
|
75
77
|
|
|
76
78
|
versions.forEach((version) => {
|
|
@@ -84,7 +86,9 @@ export default {
|
|
|
84
86
|
keywords: version.keywords
|
|
85
87
|
};
|
|
86
88
|
|
|
87
|
-
const permittedSystems = (version?.annotations
|
|
89
|
+
const permittedSystems = getPermittedOSs(version?.annotations, isRancher);
|
|
90
|
+
|
|
91
|
+
permittedSystemsByVersion.set(version.version, permittedSystems);
|
|
88
92
|
|
|
89
93
|
if (permittedSystems.length > 0 && difference(OSs, permittedSystems).length > 0) {
|
|
90
94
|
nue.disabled = true;
|
|
@@ -117,7 +121,13 @@ export default {
|
|
|
117
121
|
const currentVersion = out.find((v) => v.originalVersion === this.currentVersion);
|
|
118
122
|
|
|
119
123
|
if (currentVersion) {
|
|
120
|
-
|
|
124
|
+
const permittedSystems = permittedSystemsByVersion.get(currentVersion.originalVersion) || [];
|
|
125
|
+
|
|
126
|
+
if (permittedSystems.length === 1) {
|
|
127
|
+
currentVersion.label = this.t(`catalog.install.versions.current_${ permittedSystems[0] }`, { ver: this.currentVersion });
|
|
128
|
+
} else {
|
|
129
|
+
currentVersion.label = this.t('catalog.install.versions.current', { ver: this.currentVersion });
|
|
130
|
+
}
|
|
121
131
|
}
|
|
122
132
|
|
|
123
133
|
return out;
|
|
@@ -271,7 +281,7 @@ export default {
|
|
|
271
281
|
},
|
|
272
282
|
|
|
273
283
|
isChartTargeted() {
|
|
274
|
-
return this.
|
|
284
|
+
return this.version?.annotations?.[CATALOG_ANNOTATIONS.NAMESPACE] && this.version?.annotations?.[CATALOG_ANNOTATIONS.RELEASE_NAME];
|
|
275
285
|
},
|
|
276
286
|
|
|
277
287
|
hasQuestions() {
|
|
@@ -386,8 +396,8 @@ export default {
|
|
|
386
396
|
// Use those values to check for a catalog app resource.
|
|
387
397
|
// If found, set the form to edit mode. If not, set the
|
|
388
398
|
// form to create mode.
|
|
389
|
-
// This is a hard blocker - installing a new instance is NOT allowed.
|
|
390
399
|
|
|
400
|
+
// This is a hard blocker - installing a new instance is NOT allowed.
|
|
391
401
|
this.canInstallNew = false;
|
|
392
402
|
|
|
393
403
|
try {
|
|
@@ -410,11 +420,10 @@ export default {
|
|
|
410
420
|
if ( targetNamespace && targetName ) {
|
|
411
421
|
// If the app name and namespace values are not provided in the
|
|
412
422
|
// query, fall back on target values defined in the Helm chart itself.
|
|
413
|
-
|
|
414
423
|
// Ask to install a special chart with fixed namespace/name
|
|
415
424
|
// or edit it if there's an existing install.
|
|
416
|
-
// This is a hard blocker - installing a new instance is NOT allowed.
|
|
417
425
|
|
|
426
|
+
// This is a hard blocker - installing a new instance is NOT allowed.
|
|
418
427
|
this.canInstallNew = false;
|
|
419
428
|
|
|
420
429
|
try {
|
|
@@ -424,8 +433,12 @@ export default {
|
|
|
424
433
|
});
|
|
425
434
|
this.mode = _EDIT;
|
|
426
435
|
} catch (e) {
|
|
427
|
-
|
|
428
|
-
|
|
436
|
+
// Version targets a different namespace than where the app is installed.
|
|
437
|
+
// Fall back to matching installed apps (e.g. chart detail page).
|
|
438
|
+
const matching = this.chart?.matchingInstalledApps || [];
|
|
439
|
+
|
|
440
|
+
this.existing = matching[0] || null;
|
|
441
|
+
this.mode = this.existing ? _EDIT : _CREATE;
|
|
429
442
|
}
|
|
430
443
|
} else {
|
|
431
444
|
// Regular chart (not targeted) - check if there are installed instances.
|
package/mixins/child-hook.js
CHANGED
|
@@ -8,20 +8,26 @@ export const AFTER_SAVE_HOOKS = '_afterSaveHooks';
|
|
|
8
8
|
|
|
9
9
|
export default {
|
|
10
10
|
methods: {
|
|
11
|
+
registerHook(key, boundFn, name, priority = 99, boundFnContext) {
|
|
12
|
+
this._registerHook(key, boundFn, name, priority, boundFnContext);
|
|
13
|
+
},
|
|
14
|
+
|
|
11
15
|
registerBeforeHook(boundFn, name, priority = 99, boundFnContext) {
|
|
12
|
-
this.
|
|
16
|
+
this.registerHook(BEFORE_SAVE_HOOKS, boundFn, name, priority, boundFnContext);
|
|
13
17
|
},
|
|
14
18
|
|
|
15
|
-
|
|
16
|
-
this[
|
|
17
|
-
// BEFORE_SAVE_HOOKS is an array of objects with keys
|
|
18
|
-
// fn, name and priority.
|
|
19
|
+
unregisterHook(key, name) {
|
|
20
|
+
this[key] = (this[key] || []).filter((hook) => {
|
|
19
21
|
return hook.name !== name;
|
|
20
22
|
});
|
|
21
23
|
},
|
|
22
24
|
|
|
25
|
+
unregisterBeforeSaveHook(name) {
|
|
26
|
+
this.unregisterHook(BEFORE_SAVE_HOOKS, name);
|
|
27
|
+
},
|
|
28
|
+
|
|
23
29
|
registerAfterHook(boundFn, name, priority = 99, boundFnContext) {
|
|
24
|
-
this.
|
|
30
|
+
this.registerHook(AFTER_SAVE_HOOKS, boundFn, name, priority, boundFnContext);
|
|
25
31
|
},
|
|
26
32
|
|
|
27
33
|
async applyHooks(key, ...args) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { _CREATE, _EDIT, _VIEW } from '@shell/config/query-params';
|
|
2
2
|
import { LAST_NAMESPACE } from '@shell/store/prefs';
|
|
3
|
-
import { exceptionToErrorsArray } from '@shell/utils/error';
|
|
3
|
+
import { exceptionToErrorsArray, isDoNotLogError } from '@shell/utils/error';
|
|
4
4
|
import ChildHook, { BEFORE_SAVE_HOOKS, AFTER_SAVE_HOOKS } from '@shell/mixins/child-hook';
|
|
5
5
|
import { clear } from '@shell/utils/array';
|
|
6
6
|
import { DEFAULT_WORKSPACE } from '@shell/config/types';
|
|
@@ -184,8 +184,10 @@ export default {
|
|
|
184
184
|
} else {
|
|
185
185
|
this.errors = exceptionToErrorsArray(err);
|
|
186
186
|
}
|
|
187
|
-
|
|
188
|
-
|
|
187
|
+
if (!isDoNotLogError(err)) {
|
|
188
|
+
// Provide a stack trace for easier debugging of save errors
|
|
189
|
+
console.error('CreateEditView mixin failed to save: ', err); // eslint-disable-line no-console
|
|
190
|
+
}
|
|
189
191
|
buttonDone && buttonDone(false);
|
|
190
192
|
}
|
|
191
193
|
},
|
|
@@ -1,14 +1,32 @@
|
|
|
1
1
|
import { NAMESPACE_FILTER_NAMESPACED_YES, NAMESPACE_FILTER_NAMESPACED_NO, NAMESPACE_FILTER_ALL } from '@shell/utils/namespace-filter';
|
|
2
|
-
import { NAMESPACE } from '@shell/config/types';
|
|
2
|
+
import { MANAGEMENT, NAMESPACE } from '@shell/config/types';
|
|
3
3
|
import { ALL_NAMESPACES } from '@shell/store/prefs';
|
|
4
4
|
import { mapGetters } from 'vuex';
|
|
5
5
|
import { ResourceListComponentName } from '../components/ResourceList/resource-list.config';
|
|
6
6
|
import paginationUtils from '@shell/utils/pagination-utils';
|
|
7
7
|
import debounce from 'lodash/debounce';
|
|
8
|
-
import { PaginationParamFilter, PaginationFilterField, PaginationArgs } from '@shell/types/store/pagination.types';
|
|
8
|
+
import { PaginationParamFilter, PaginationFilterField, PaginationFilterEquality, PaginationArgs } from '@shell/types/store/pagination.types';
|
|
9
9
|
import stevePaginationUtils from '@shell/plugins/steve/steve-pagination-utils';
|
|
10
10
|
import { STEVE_WATCH_MODE } from '@shell/types/store/subscribe.types';
|
|
11
11
|
|
|
12
|
+
export function parseStateFilter(stateFilter) {
|
|
13
|
+
if (!stateFilter) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const states = stateFilter.split(',').filter(Boolean);
|
|
18
|
+
|
|
19
|
+
if (!states.length) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return [new PaginationFilterField({
|
|
24
|
+
field: 'metadata.state.name',
|
|
25
|
+
value: states.join(','),
|
|
26
|
+
equality: PaginationFilterEquality.IN,
|
|
27
|
+
})];
|
|
28
|
+
}
|
|
29
|
+
|
|
12
30
|
/**
|
|
13
31
|
* Companion mixin used with `resource-fetch` for `ResourceList` to determine if the user needs to filter the list by a single namespace
|
|
14
32
|
*/
|
|
@@ -75,6 +93,7 @@ export default {
|
|
|
75
93
|
const {
|
|
76
94
|
page, perPage, filter, sort, descending
|
|
77
95
|
} = event;
|
|
96
|
+
const stateFilters = parseStateFilter(this.$route?.query?.stateFilter) || [];
|
|
78
97
|
const searchFilters = filter.searchQuery ? filter.searchFields.map((field) => new PaginationFilterField({
|
|
79
98
|
field,
|
|
80
99
|
value: filter.searchQuery,
|
|
@@ -91,6 +110,7 @@ export default {
|
|
|
91
110
|
projectsOrNamespaces: this.requestFilters.projectsOrNamespaces,
|
|
92
111
|
filters: [
|
|
93
112
|
new PaginationParamFilter({ fields: searchFilters }),
|
|
113
|
+
new PaginationParamFilter({ fields: stateFilters }),
|
|
94
114
|
...this.requestFilters.filters, // Apply the additional filters. these aren't from the user but from ns filtering
|
|
95
115
|
]
|
|
96
116
|
});
|
|
@@ -248,7 +268,7 @@ export default {
|
|
|
248
268
|
namespaceFilters: {
|
|
249
269
|
immediate: true,
|
|
250
270
|
async handler(neu, old) {
|
|
251
|
-
if (!this.canPaginate || !this.isNamespaced) {
|
|
271
|
+
if (!this.canPaginate || !this.isNamespaced || !this.currentProduct?.showNamespaceFilter) {
|
|
252
272
|
return;
|
|
253
273
|
}
|
|
254
274
|
|
|
@@ -283,7 +303,7 @@ export default {
|
|
|
283
303
|
allNamespaces: this.$store.getters[`${ this.currentProduct?.inStore }/all`](NAMESPACE),
|
|
284
304
|
selection: neu,
|
|
285
305
|
isAllNamespaces: this.isAllNamespaces,
|
|
286
|
-
isLocalCluster: this.$store.getters['currentCluster']
|
|
306
|
+
isLocalCluster: this.$store.getters['currentCluster']?.isLocal,
|
|
287
307
|
showReservedRancherNamespaces: this.showDynamicRancherNamespaces,
|
|
288
308
|
productHidesSystemNamespaces: this.productHidesSystemNamespaces,
|
|
289
309
|
});
|
|
@@ -354,15 +374,51 @@ export default {
|
|
|
354
374
|
|
|
355
375
|
async beforeUnmount() {
|
|
356
376
|
if (this.havePaginated) {
|
|
377
|
+
const store = this.overrideInStore || this.inStore;
|
|
357
378
|
// of type @STEVE_WATCH_PARAMS
|
|
358
379
|
const watchArgs = {
|
|
359
380
|
type: this.resource,
|
|
360
381
|
mode: STEVE_WATCH_MODE.RESOURCE_CHANGES,
|
|
361
382
|
};
|
|
362
383
|
|
|
363
|
-
|
|
364
|
-
|
|
384
|
+
// Ensure that a resource remains in the store... and it's the same reference as before
|
|
385
|
+
// We'll do this for the mgmt cluster if there's a currentCluster set, otherwise we become unstuck
|
|
386
|
+
// (on nav we ensure currentCluster exists, but beforeUnmount fires afterwards, removing the cluster from pages that are using it)
|
|
387
|
+
const retainResource = this.resource === MANAGEMENT.CLUSTER && this.currentCluster ? this.currentCluster : null;
|
|
388
|
+
|
|
389
|
+
// Forget (unwatch, clear from store) the list's resource
|
|
390
|
+
await this.$store.dispatch(`${ store }/forgetType`, {
|
|
391
|
+
type: this.resource,
|
|
392
|
+
compareWatches: (watchParams) => {
|
|
393
|
+
return watchParams.type === watchArgs.type && watchParams.mode === watchArgs.mode;
|
|
394
|
+
},
|
|
395
|
+
unwatch: true,
|
|
396
|
+
forget: !retainResource
|
|
365
397
|
});
|
|
398
|
+
|
|
399
|
+
if (!!retainResource) {
|
|
400
|
+
// The end state should be just like we've dispatched `${store}/find`
|
|
401
|
+
|
|
402
|
+
try {
|
|
403
|
+
// Clone to ensure we can load each property of A into B without worrying about them being the same reference
|
|
404
|
+
const clone = await this.$store.dispatch(`${ store }/clone`, { resource: retainResource });
|
|
405
|
+
|
|
406
|
+
// Load the resource. It's already in the store but this makes sure any legacy state (like havePage) is reset
|
|
407
|
+
await this.$store.dispatch(`${ store }/load`, {
|
|
408
|
+
data: clone,
|
|
409
|
+
existing: retainResource,
|
|
410
|
+
invalidatePageCache: true,
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
// Watch the resource.
|
|
414
|
+
await this.$store.dispatch(`${ store }/watch`, {
|
|
415
|
+
type: this.resource,
|
|
416
|
+
id: retainResource.id,
|
|
417
|
+
});
|
|
418
|
+
} catch (error) {
|
|
419
|
+
console.error('Error occurred whilst trying to retain the management cluster in cache and correctly watched', error); // eslint-disable-line no-console
|
|
420
|
+
}
|
|
421
|
+
}
|
|
366
422
|
}
|
|
367
423
|
}
|
|
368
424
|
};
|