@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
|
@@ -1,20 +1,25 @@
|
|
|
1
|
-
import { CATALOG, CLUSTER_BADGE } from '@shell/config/labels-annotations';
|
|
1
|
+
import { CATALOG, CLUSTER_BADGE, NODE_ARCHITECTURE } from '@shell/config/labels-annotations';
|
|
2
2
|
import {
|
|
3
|
-
NODE, FLEET, MANAGEMENT, CAPI, EXT
|
|
3
|
+
NODE, FLEET, MANAGEMENT, CAPI, EXT,
|
|
4
|
+
NORMAN,
|
|
5
|
+
HCI
|
|
4
6
|
} from '@shell/config/types';
|
|
5
7
|
import { insertAt, addObject, removeObject } from '@shell/utils/array';
|
|
6
8
|
import { downloadFile } from '@shell/utils/download';
|
|
7
9
|
import { parseSi } from '@shell/utils/units';
|
|
8
10
|
import { parseColor, textColor } from '@shell/utils/color';
|
|
9
|
-
import { isEmpty } from '@shell/utils/object';
|
|
11
|
+
import { isEmpty, isEqual } from '@shell/utils/object';
|
|
10
12
|
import { HARVESTER_NAME as HARVESTER } from '@shell/config/features';
|
|
11
13
|
import { isHarvesterCluster } from '@shell/utils/cluster';
|
|
12
14
|
import SteveModel from '@shell/plugins/steve/steve-class';
|
|
13
15
|
import { LINUX, WINDOWS } from '@shell/store/catalog';
|
|
16
|
+
import { KEV1 } from './management.cattle.io.kontainerdriver';
|
|
14
17
|
import { requireAsset } from '@shell/utils/require-asset';
|
|
15
18
|
import { PINNED_CLUSTERS } from '@shell/store/prefs';
|
|
16
19
|
import { copyTextToClipboard } from '@shell/utils/clipboard';
|
|
17
|
-
import { isHostedProvider } from '@shell/utils/provider';
|
|
20
|
+
import { isHostedProvider, isCAPIProvider } from '@shell/utils/provider';
|
|
21
|
+
import { ucFirst } from '@shell/utils/string';
|
|
22
|
+
import { sortBy } from '@shell/utils/sort';
|
|
18
23
|
|
|
19
24
|
const DEFAULT_BADGE_COLOR = '#707070';
|
|
20
25
|
|
|
@@ -55,6 +60,30 @@ export default class MgmtCluster extends SteveModel {
|
|
|
55
60
|
return (schema?.collectionMethods || []).includes('POST');
|
|
56
61
|
}
|
|
57
62
|
|
|
63
|
+
get availableActions() {
|
|
64
|
+
// If on the Cluster Management Cluster List use the provisioning cluster actions instead of the management cluster
|
|
65
|
+
// This resolution feels a bit hacky, however the alternative would be to create a table prop and lots of weird plumbing
|
|
66
|
+
// It's a small use case, so just doing a limited solution
|
|
67
|
+
const listLocation = this.provCluster?.listLocation || {};
|
|
68
|
+
const currentRoute = this.currentRoute();
|
|
69
|
+
|
|
70
|
+
// Compare params, but exclude cluster (could be a bad link which provides a specific cluster)
|
|
71
|
+
const { cluster: _1, ...lLProduct } = listLocation.params || {};
|
|
72
|
+
const { cluster: _2, ...cRParams } = currentRoute.params;
|
|
73
|
+
const paramsEqual = isEqual(lLProduct, cRParams);
|
|
74
|
+
|
|
75
|
+
const isClusterManagementListPage = listLocation?.name === currentRoute?.name && paramsEqual;
|
|
76
|
+
|
|
77
|
+
if (isClusterManagementListPage) {
|
|
78
|
+
return this.provCluster?.availableActions.map((action) => ({
|
|
79
|
+
...action,
|
|
80
|
+
altResource: this.provCluster, // actions work by using the row's resource with the function name. this overrides that
|
|
81
|
+
}));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return super.availableActions;
|
|
85
|
+
}
|
|
86
|
+
|
|
58
87
|
get _availableActions() {
|
|
59
88
|
const out = super._availableActions;
|
|
60
89
|
|
|
@@ -96,24 +125,187 @@ export default class MgmtCluster extends SteveModel {
|
|
|
96
125
|
}
|
|
97
126
|
|
|
98
127
|
get provisioner() {
|
|
128
|
+
// Sometimes the driver will be empty (like unconnected custom rke2 clusters), so fall back on the new and improved status.provider
|
|
129
|
+
if (this.status?.provider) {
|
|
130
|
+
if (['gke', 'eks', 'aks', 'k3s'].includes(this.status.provider)) {
|
|
131
|
+
// Defensive coding. we're now using status.provider which uses lowercase for some distro's
|
|
132
|
+
// To support the old use case of upper case status.driver values make status.provider upper case...
|
|
133
|
+
return this.status.provider.toUpperCase();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return this.status.provider;
|
|
137
|
+
}
|
|
138
|
+
|
|
99
139
|
// For imported K3s clusters, this.status.driver is 'k3s.'
|
|
100
|
-
|
|
140
|
+
if (this.status?.driver) {
|
|
141
|
+
return this.status.driver;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return 'imported';
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
get provisionerDisplay() {
|
|
148
|
+
// Allow a model extension to override the display of the provisioner
|
|
149
|
+
if (this.customProvisionerHelper?.provisionerDisplay) {
|
|
150
|
+
return this.customProvisionerHelper?.provisionerDisplay(this);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
let provisioner = this.provisioner?.toLowerCase();
|
|
154
|
+
|
|
155
|
+
if (provisioner === 'rke.windows') {
|
|
156
|
+
provisioner = 'rkeWindows';
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (!this.$rootGetters['i18n/exists'](`cluster.provider.${ provisioner }`)) {
|
|
160
|
+
provisioner = 'other';
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return this.$rootGetters['i18n/withFallback'](`cluster.provider."${ provisioner }"`, null, ucFirst(this.provisioner));
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Get the custom provisioner helper for this model
|
|
168
|
+
*/
|
|
169
|
+
get customProvisionerHelper() {
|
|
170
|
+
if (!this.provCluster) {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Find the first model extension that says it can be used for this model
|
|
175
|
+
return this.modelExtensions.find((modelExt) => modelExt.useFor ? modelExt.useFor(this.provCluster) : false);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
get provider() {
|
|
179
|
+
return this.status?.provider;
|
|
101
180
|
}
|
|
102
181
|
|
|
103
182
|
get machineProvider() {
|
|
104
|
-
|
|
183
|
+
return this.status?.info?.machineProvider;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
get machineProviderDisplay() {
|
|
187
|
+
if (this.customProvisionerHelper?.machineProviderDisplay) {
|
|
188
|
+
return this.customProvisionerHelper?.machineProviderDisplay(this);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const provider = (this.machineProvider || '').toLowerCase();
|
|
192
|
+
|
|
193
|
+
if ( provider ) {
|
|
194
|
+
return this.$rootGetters['i18n/withFallback'](`cluster.provider."${ provider }"`, null, provider);
|
|
195
|
+
} else {
|
|
196
|
+
return this.$rootGetters['i18n/t']('generic.unknown');
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Is the cluster a legacy (unsupported) KEV1 cluster?
|
|
201
|
+
get isKev1() {
|
|
202
|
+
return KEV1.includes(this.spec?.genericEngineConfig?.driverName);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
get isImported() {
|
|
206
|
+
const provider = this.status?.provider;
|
|
207
|
+
const driver = this.status?.driver;
|
|
208
|
+
|
|
209
|
+
// The main case
|
|
210
|
+
if (provider === 'k3s' || provider === 'rke2') {
|
|
211
|
+
return driver === provider;
|
|
212
|
+
}
|
|
213
|
+
// The 'waiting' case
|
|
214
|
+
if (!provider && (driver === 'k3s' || driver === 'rke2')) {
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// imported KEv2
|
|
219
|
+
// we can't rely on this.provisioner to determine imported-ness for these clusters, as it will return 'aks' 'eks' 'gke' for both provisioned and imported clusters
|
|
220
|
+
if (this.isHostedKubernetesProvider && !!this.provCluster?.providerConfig?.imported) {
|
|
221
|
+
return true;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return this.provisioner === 'imported';
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
get isCustom() {
|
|
228
|
+
if ( this.isRke2 ) {
|
|
229
|
+
return !(this.provCluster?.spec?.rkeConfig?.machinePools?.length);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
get isImportedK3s() {
|
|
236
|
+
return this.isImported && this.isK3s;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
get isImportedRke2() {
|
|
240
|
+
return this.isImported && this.provider?.startsWith('rke2');
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
get isK3s() {
|
|
244
|
+
return this.status ? this.status.provider === 'k3s' : (this.kubernetesVersion || '').includes('k3s') ;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
get isRke2() {
|
|
248
|
+
return !!this.provCluster?.isRke2;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// identify v2 provisioning clusters created using upstream capi infrastructure providers instead of rancher/machine
|
|
252
|
+
get isCapiHybrid() {
|
|
253
|
+
if (!this.isRke2) {
|
|
254
|
+
return false;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const machineReferences = (this.provCluster.spec?.rkeConfig?.machinePools || []).map((pool) => pool.machineConfigRef);
|
|
258
|
+
|
|
259
|
+
const capiMachines = machineReferences.find((r) => r?.apiVersion?.includes('cluster.x-k8s.io'));
|
|
260
|
+
|
|
261
|
+
return !!capiMachines;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
get isCAPIProvider() {
|
|
265
|
+
if (!this.isCapiHybrid || !this.machineProvider) {
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
const context = {
|
|
270
|
+
dispatch: this.$dispatch,
|
|
271
|
+
getters: this.$getters,
|
|
272
|
+
axios: this.$axios,
|
|
273
|
+
$extension: this.$extension,
|
|
274
|
+
t: (...args) => this.t.apply(this, args),
|
|
275
|
+
};
|
|
105
276
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
277
|
+
return isCAPIProvider(context, this.machineProvider.toLowerCase());
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
get isHostedKubernetesProvider() {
|
|
281
|
+
const context = {
|
|
282
|
+
dispatch: this.$dispatch,
|
|
283
|
+
getters: this.$getters,
|
|
284
|
+
axios: this.$axios,
|
|
285
|
+
$extension: this.$extension,
|
|
286
|
+
t: (...args) => this.t.apply(this, args),
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
return isHostedProvider(context, this.provisioner);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
get isPrivateHostedProvider() {
|
|
293
|
+
if (this.isHostedKubernetesProvider && this.provisioner) {
|
|
294
|
+
switch (this.provisioner.toLowerCase()) {
|
|
295
|
+
case 'gke':
|
|
296
|
+
return this.spec?.gkeConfig?.privateClusterConfig?.enablePrivateEndpoint;
|
|
297
|
+
case 'eks':
|
|
298
|
+
return this.spec?.eksConfig?.privateAccess;
|
|
299
|
+
case 'aks':
|
|
300
|
+
return this.spec?.aksConfig?.privateCluster;
|
|
301
|
+
}
|
|
110
302
|
}
|
|
111
303
|
|
|
112
|
-
return
|
|
304
|
+
return false;
|
|
113
305
|
}
|
|
114
306
|
|
|
115
307
|
get groupByLabel() {
|
|
116
|
-
return this
|
|
308
|
+
return `Workspace: ${ this.spec.fleetWorkspaceName }`;
|
|
117
309
|
}
|
|
118
310
|
|
|
119
311
|
get isReady() {
|
|
@@ -138,10 +330,7 @@ export default class MgmtCluster extends SteveModel {
|
|
|
138
330
|
}
|
|
139
331
|
|
|
140
332
|
get kubernetesVersionRaw() {
|
|
141
|
-
|
|
142
|
-
const fromSpec = this.config?.kubernetesVersion;
|
|
143
|
-
|
|
144
|
-
return fromStatus || fromSpec;
|
|
333
|
+
return this.statusInfo.kubernetesVersion;
|
|
145
334
|
}
|
|
146
335
|
|
|
147
336
|
get kubernetesVersion() {
|
|
@@ -161,7 +350,7 @@ export default class MgmtCluster extends SteveModel {
|
|
|
161
350
|
}
|
|
162
351
|
|
|
163
352
|
get providerOs() {
|
|
164
|
-
if ( this.
|
|
353
|
+
if ( this.provider?.endsWith('.windows')) {
|
|
165
354
|
return 'windows';
|
|
166
355
|
}
|
|
167
356
|
|
|
@@ -204,20 +393,8 @@ export default class MgmtCluster extends SteveModel {
|
|
|
204
393
|
return isHarvesterCluster(this);
|
|
205
394
|
}
|
|
206
395
|
|
|
207
|
-
get isHostedKubernetesProvider() {
|
|
208
|
-
const context = {
|
|
209
|
-
dispatch: this.$dispatch,
|
|
210
|
-
getters: this.$getters,
|
|
211
|
-
axios: this.$axios,
|
|
212
|
-
$extension: this.$extension,
|
|
213
|
-
t: (...args) => this.t.apply(this, args),
|
|
214
|
-
};
|
|
215
|
-
|
|
216
|
-
return isHostedProvider(context, this.provisioner);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
396
|
get providerLogo() {
|
|
220
|
-
let provider = this.
|
|
397
|
+
let provider = this.provider || 'kubernetes';
|
|
221
398
|
|
|
222
399
|
if (this.isHarvester) {
|
|
223
400
|
provider = HARVESTER;
|
|
@@ -248,6 +425,136 @@ export default class MgmtCluster extends SteveModel {
|
|
|
248
425
|
return this.providerLogo;
|
|
249
426
|
}
|
|
250
427
|
|
|
428
|
+
get pools() {
|
|
429
|
+
const deployments = this.$rootGetters['management/all'](CAPI.MACHINE_DEPLOYMENT).filter((pool) => pool.spec?.clusterName === this.provClusterName);
|
|
430
|
+
|
|
431
|
+
if (!!deployments.length) {
|
|
432
|
+
return deployments;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
return this.machinePools;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
get desired() {
|
|
439
|
+
return this.pools.reduce((acc, pool) => acc + (pool.desired || 0), 0);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
get pending() {
|
|
443
|
+
return this.pools.reduce((acc, pool) => acc + (pool.pending || 0), 0);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
get outdated() {
|
|
447
|
+
return this.pools.reduce((acc, pool) => acc + (pool.outdated || 0), 0);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
get ready() {
|
|
451
|
+
return this.pools.reduce((acc, pool) => acc + (pool.ready || 0), 0);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
get stateParts() {
|
|
455
|
+
const out = [
|
|
456
|
+
{
|
|
457
|
+
label: 'Pending',
|
|
458
|
+
color: 'bg-info',
|
|
459
|
+
textColor: 'text-info',
|
|
460
|
+
value: this.pending,
|
|
461
|
+
sort: 1,
|
|
462
|
+
},
|
|
463
|
+
{
|
|
464
|
+
label: 'Outdated',
|
|
465
|
+
color: 'bg-warning',
|
|
466
|
+
textColor: 'text-warning',
|
|
467
|
+
value: this.outdated,
|
|
468
|
+
sort: 2,
|
|
469
|
+
},
|
|
470
|
+
{
|
|
471
|
+
label: 'Unavailable',
|
|
472
|
+
color: 'bg-error',
|
|
473
|
+
textColor: 'text-error',
|
|
474
|
+
value: this.unavailable,
|
|
475
|
+
sort: 3,
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
label: 'Ready',
|
|
479
|
+
color: 'bg-success',
|
|
480
|
+
textColor: 'text-success',
|
|
481
|
+
value: this.ready,
|
|
482
|
+
sort: 4,
|
|
483
|
+
},
|
|
484
|
+
].filter((x) => x.value > 0);
|
|
485
|
+
|
|
486
|
+
return sortBy(out, 'sort:desc');
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
get nodes() {
|
|
490
|
+
return this.$getters['all'](MANAGEMENT.NODE).filter((node) => node.id.startsWith(this.id));
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
get nodesArchitecture() {
|
|
494
|
+
const obj = {};
|
|
495
|
+
|
|
496
|
+
this.nodes?.forEach((node) => {
|
|
497
|
+
if (!node.metadata?.state?.transitioning) {
|
|
498
|
+
const architecture = node.status?.nodeLabels?.[NODE_ARCHITECTURE];
|
|
499
|
+
|
|
500
|
+
const key = architecture || this.t('cluster.architecture.label.unknown');
|
|
501
|
+
|
|
502
|
+
obj[key] = (obj[key] || 0) + 1;
|
|
503
|
+
}
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
return obj;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
get architecture() {
|
|
510
|
+
if (!this.statusInfo.arch) {
|
|
511
|
+
return { label: this.t('generic.provisioning') };
|
|
512
|
+
}
|
|
513
|
+
if (this.statusInfo.arch === 'mixed') {
|
|
514
|
+
return { label: this.t('cluster.architecture.label.mixed') };
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
return { label: this.statusInfo.arch };
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
get machines() {
|
|
521
|
+
return this.$rootGetters['management/all'](CAPI.MACHINE).filter((machine) => {
|
|
522
|
+
if ( machine.metadata?.namespace !== this.provClusterNamespace ) {
|
|
523
|
+
return false;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
return machine.spec?.clusterName === this.provClusterName;
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
get unavailable() {
|
|
531
|
+
return this.pools.reduce((acc, pool) => acc + (pool.unavailable || 0), 0);
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
get unavailableMachines() {
|
|
535
|
+
if (this.isReady) {
|
|
536
|
+
const names = this.machines.filter((machine) => {
|
|
537
|
+
return machine.status?.conditions?.find((c) => c.error && c.type === 'NodeHealthy');
|
|
538
|
+
}).map((machine) => {
|
|
539
|
+
if (machine.status?.nodeRef?.name) {
|
|
540
|
+
return this.t('cluster.availabilityWarnings.node', { name: machine.status.nodeRef.name });
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
return this.t('cluster.availabilityWarnings.machine', { name: machine.metadata.name });
|
|
544
|
+
});
|
|
545
|
+
|
|
546
|
+
return names.join('<br>');
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
return '';
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// nodeGroups can be undefined for an EKS cluster that has just been created and has not
|
|
553
|
+
// had any node groups added to it
|
|
554
|
+
get eksNodeGroups() {
|
|
555
|
+
return this.spec?.eksConfig?.nodeGroups || [];
|
|
556
|
+
}
|
|
557
|
+
|
|
251
558
|
// Color to use as the underline for the icon in the app bar
|
|
252
559
|
get iconColor() {
|
|
253
560
|
return this.metadata?.annotations?.[CLUSTER_BADGE.COLOR];
|
|
@@ -301,8 +608,8 @@ export default class MgmtCluster extends SteveModel {
|
|
|
301
608
|
}
|
|
302
609
|
|
|
303
610
|
get availableCpu() {
|
|
304
|
-
const reserved = parseSi(this.status
|
|
305
|
-
const allocatable = parseSi(this.status
|
|
611
|
+
const reserved = parseSi(this.status?.requested?.cpu);
|
|
612
|
+
const allocatable = parseSi(this.status?.allocatable?.cpu);
|
|
306
613
|
|
|
307
614
|
if ( allocatable > 0 && reserved >= 0 ) {
|
|
308
615
|
return Math.max(0, allocatable - reserved);
|
|
@@ -312,8 +619,8 @@ export default class MgmtCluster extends SteveModel {
|
|
|
312
619
|
}
|
|
313
620
|
|
|
314
621
|
get availableMemory() {
|
|
315
|
-
const reserved = parseSi(this.status
|
|
316
|
-
const allocatable = parseSi(this.status
|
|
622
|
+
const reserved = parseSi(this.status?.requested?.memory);
|
|
623
|
+
const allocatable = parseSi(this.status?.allocatable?.memory);
|
|
317
624
|
|
|
318
625
|
if ( allocatable > 0 && reserved >= 0 ) {
|
|
319
626
|
return Math.max(0, allocatable - reserved);
|
|
@@ -397,17 +704,23 @@ export default class MgmtCluster extends SteveModel {
|
|
|
397
704
|
}, initialAggregation);
|
|
398
705
|
}
|
|
399
706
|
|
|
400
|
-
get
|
|
401
|
-
return this.$
|
|
707
|
+
get normanCluster() {
|
|
708
|
+
return this.$rootGetters['rancher/byId'](NORMAN.CLUSTER, this.id);
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
async findNormanCluster() {
|
|
712
|
+
return await this.$dispatch('rancher/find', { type: NORMAN.CLUSTER, id: this.id }, { root: true });
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
get provCluster() {
|
|
716
|
+
return this.$rootGetters['management/byId'](CAPI.RANCHER_CLUSTER, this.provClusterId);
|
|
402
717
|
}
|
|
403
718
|
|
|
404
719
|
get provClusterId() {
|
|
405
|
-
|
|
406
|
-
//
|
|
407
|
-
// RKE2 cluster IDs include the name - fleet-default/cluster-name - whereas an RKE1
|
|
408
|
-
// cluster has the less human readable management cluster ID in it: fleet-default/c-khk48
|
|
720
|
+
// Note - there's also status.info.provisioningClusterReg, which is a link to the lifecycle owning type
|
|
721
|
+
// for v2prov this would be a provisioning.cattle.io.cluster, but for others it wouldn't be.
|
|
409
722
|
|
|
410
|
-
const verb = this.isLocal ||
|
|
723
|
+
const verb = this.isLocal || this.isHostedKubernetesProvider ? 'to' : 'from';
|
|
411
724
|
const res = findRelationship(verb, CAPI.RANCHER_CLUSTER, this.metadata?.relationships);
|
|
412
725
|
|
|
413
726
|
if (res) {
|
|
@@ -417,6 +730,20 @@ export default class MgmtCluster extends SteveModel {
|
|
|
417
730
|
return findRelationship(verb === 'to' ? 'from' : 'to', CAPI.RANCHER_CLUSTER, this.metadata?.relationships);
|
|
418
731
|
}
|
|
419
732
|
|
|
733
|
+
get provClusterNamespace() {
|
|
734
|
+
// Could consider using `metadata.annotations."objectset.rio.cattle.io/owner-namespace"` instead of provClusterId from resource rels
|
|
735
|
+
const [namespace] = this.provClusterId?.split('/') || [];
|
|
736
|
+
|
|
737
|
+
return namespace;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
get provClusterName() {
|
|
741
|
+
// Could consider using `metadata.annotations."objectset.rio.cattle.io/owner-name"` instead of provClusterId from resource rels
|
|
742
|
+
const [, name] = this.provClusterId?.split('/') || [];
|
|
743
|
+
|
|
744
|
+
return name;
|
|
745
|
+
}
|
|
746
|
+
|
|
420
747
|
get pinned() {
|
|
421
748
|
return this.$rootGetters['prefs/get'](PINNED_CLUSTERS).includes(this.id);
|
|
422
749
|
}
|
|
@@ -436,4 +763,70 @@ export default class MgmtCluster extends SteveModel {
|
|
|
436
763
|
|
|
437
764
|
this.$dispatch('prefs/set', { key: PINNED_CLUSTERS, value: types }, { root: true });
|
|
438
765
|
}
|
|
766
|
+
|
|
767
|
+
get canExplore() {
|
|
768
|
+
return this.isReady && !this.hasError;
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
get hasError() {
|
|
772
|
+
// TODO: kinara - this was copied over from prov cluster. prov conditions vs mgmt conditions
|
|
773
|
+
// Before we were just checking for this.status?.conditions?.some((condition) => condition.error === true)
|
|
774
|
+
// but this is wrong as an error might exist but it might not be meaningful in the context of readiness of a cluster
|
|
775
|
+
// which is what this 'hasError' is used for.
|
|
776
|
+
// We now check if there's a ready condition after an error, which helps dictate the readiness of a cluster
|
|
777
|
+
// Based on the findings in https://github.com/rancher/dashboard/issues/10043
|
|
778
|
+
if (this.status?.conditions && this.status?.conditions.length) {
|
|
779
|
+
// if there are errors, we compare with how recent the "Ready" condition is compared to that error, otherwise we just move on
|
|
780
|
+
if (this.status?.conditions.some((c) => c.error === true)) {
|
|
781
|
+
// there's no ready condition and has an error, mark it
|
|
782
|
+
if (!this.status?.conditions.some((c) => c.type === 'Ready')) {
|
|
783
|
+
return true;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
const filteredConditions = this.status?.conditions.filter((c) => c.error === true || c.type === 'Ready');
|
|
787
|
+
const mostRecentCondition = filteredConditions.reduce((a, b) => ((a.lastUpdateTime > b.lastUpdateTime) ? a : b));
|
|
788
|
+
|
|
789
|
+
return mostRecentCondition.error;
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
return false;
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
get isAutoscalerEnabled() {
|
|
797
|
+
if (!this.provCluster) {
|
|
798
|
+
return false;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
return !!this.provCluster.spec?.rkeConfig?.machinePools?.some((pool) => {
|
|
802
|
+
return typeof pool.autoscalingMinSize !== 'undefined' || typeof pool.autoscalingMaxSize !== 'undefined';
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
_statusInfoWarned = false;
|
|
807
|
+
get statusInfo() {
|
|
808
|
+
if (!this.status.info) {
|
|
809
|
+
if (!this._statusInfoWarned) {
|
|
810
|
+
this._statusInfoWarned = true;
|
|
811
|
+
// eslint-disable-next-line no-console
|
|
812
|
+
console.warn(`management.cattle.io.cluster '${ this.id }' is missing 'status.info'. This could mean the resource is troubled, or an extension has brought in this new model which is used in an older rancher`);
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
return { };
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
return this.status.info;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
async goToHarvesterCluster() {
|
|
822
|
+
const harvesterCluster = await this.$dispatch('create', {
|
|
823
|
+
...this.provCluster,
|
|
824
|
+
type: HCI.CLUSTER
|
|
825
|
+
});
|
|
826
|
+
|
|
827
|
+
try {
|
|
828
|
+
await harvesterCluster.goToCluster();
|
|
829
|
+
} catch {
|
|
830
|
+
}
|
|
831
|
+
}
|
|
439
832
|
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { MANAGEMENT_NODE } from '@shell/config/labels-annotations';
|
|
2
|
-
import {
|
|
3
|
-
ADDRESSES, CAPI, MANAGEMENT, NODE, NORMAN
|
|
4
|
-
} from '@shell/config/types';
|
|
2
|
+
import { ADDRESSES, MANAGEMENT, NODE, NORMAN } from '@shell/config/types';
|
|
5
3
|
import { NAME as EXPLORER } from '@shell/config/product/explorer';
|
|
6
4
|
import { listNodeRoles } from '@shell/models/cluster/node';
|
|
7
5
|
import { downloadUrl } from '@shell/utils/download';
|
|
@@ -12,7 +10,8 @@ import { notOnlyOfRole } from '@shell/models/cluster.x-k8s.io.machine';
|
|
|
12
10
|
const RKE1_ALLOWED_ACTIONS = [
|
|
13
11
|
'goToViewYaml',
|
|
14
12
|
'download',
|
|
15
|
-
'viewInApi'
|
|
13
|
+
'viewInApi',
|
|
14
|
+
'showConfiguration'
|
|
16
15
|
];
|
|
17
16
|
|
|
18
17
|
export default class MgmtNode extends HybridModel {
|
|
@@ -26,6 +25,10 @@ export default class MgmtNode extends HybridModel {
|
|
|
26
25
|
return this.metadata.labels[MANAGEMENT_NODE.NODE_NAME];
|
|
27
26
|
}
|
|
28
27
|
|
|
28
|
+
get mgmtCluster() {
|
|
29
|
+
return this.$rootGetters['management/byId'](MANAGEMENT.CLUSTER, this.mgmtClusterId);
|
|
30
|
+
}
|
|
31
|
+
|
|
29
32
|
get mgmtClusterId() {
|
|
30
33
|
return this.id.substring(0, this.id.indexOf('/'));
|
|
31
34
|
}
|
|
@@ -61,6 +64,10 @@ export default class MgmtNode extends HybridModel {
|
|
|
61
64
|
}
|
|
62
65
|
|
|
63
66
|
get pool() {
|
|
67
|
+
if (!this.spec?.nodePoolName) {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
|
|
64
71
|
const nodePoolID = this.spec.nodePoolName.replace(':', '/');
|
|
65
72
|
|
|
66
73
|
return this.$rootGetters['management/byId'](MANAGEMENT.NODE_POOL, nodePoolID);
|
|
@@ -101,7 +108,7 @@ export default class MgmtNode extends HybridModel {
|
|
|
101
108
|
}
|
|
102
109
|
|
|
103
110
|
get provisioningCluster() {
|
|
104
|
-
return this
|
|
111
|
+
return this.mgmtCluster?.provCluster;
|
|
105
112
|
}
|
|
106
113
|
|
|
107
114
|
get doneOverride() {
|
|
@@ -116,6 +123,42 @@ export default class MgmtNode extends HybridModel {
|
|
|
116
123
|
return this.status?.addresses || this.status?.internalNodeStatus?.addresses || [];
|
|
117
124
|
}
|
|
118
125
|
|
|
126
|
+
get internalIps() {
|
|
127
|
+
const internal = this.addresses.filter(({ type }) => {
|
|
128
|
+
return type === ADDRESSES.INTERNAL_IP;
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
if (!internal.length) {
|
|
132
|
+
// For RKE1 clusters in EC2, node addresses are
|
|
133
|
+
// under status.rkeNode.address and status.rkeNode.internalAddress
|
|
134
|
+
if (this.status?.rkeNode) {
|
|
135
|
+
return this.status.rkeNode.internalAddress ? [this.status.rkeNode.internalAddress] : [];
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return [];
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return internal.map(({ address }) => address);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
get externalIps() {
|
|
145
|
+
const external = this.addresses.filter(({ type }) => {
|
|
146
|
+
return type === ADDRESSES.EXTERNAL_IP;
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
if (!external.length) {
|
|
150
|
+
// For RKE1 clusters in EC2, node addresses are
|
|
151
|
+
// under status.rkeNode.address and status.rkeNode.internalAddress
|
|
152
|
+
if (this.status?.rkeNode) {
|
|
153
|
+
return this.status.rkeNode.address ? [this.status.rkeNode.address] : [];
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return [];
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return external.map(({ address }) => address);
|
|
160
|
+
}
|
|
161
|
+
|
|
119
162
|
get internalIp() {
|
|
120
163
|
// This shows in the IP address column for RKE1 nodes in the
|
|
121
164
|
// list of nodes in the cluster detail page of Cluster Management.
|
|
@@ -129,7 +172,7 @@ export default class MgmtNode extends HybridModel {
|
|
|
129
172
|
|
|
130
173
|
// For RKE1 clusters in EC2, node addresses are
|
|
131
174
|
// under status.rkeNode.address and status.rkeNode.internalAddress
|
|
132
|
-
if (!internal && this.status
|
|
175
|
+
if (!internal && this.status?.rkeNode) {
|
|
133
176
|
return this.status.rkeNode.internalAddress;
|
|
134
177
|
}
|
|
135
178
|
|
|
@@ -145,7 +188,7 @@ export default class MgmtNode extends HybridModel {
|
|
|
145
188
|
|
|
146
189
|
// For RKE1 clusters in EC2, node addresses are
|
|
147
190
|
// under status.rkeNode.address and status.rkeNode.internalAddress
|
|
148
|
-
if (!statusAddress && this.status
|
|
191
|
+
if (!statusAddress && this.status?.rkeNode) {
|
|
149
192
|
return this.status.rkeNode.address;
|
|
150
193
|
}
|
|
151
194
|
|
|
@@ -45,7 +45,7 @@ export default class MgmtNodePool extends HybridModel {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
get provisioningCluster() {
|
|
48
|
-
return this.$getters['
|
|
48
|
+
return this.$getters['byId'](CAPI.RANCHER_CLUSTER, `${ this.metadata.namespace }/${ this.spec.clusterName }`);
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
get doneOverride() {
|