@rancher/shell 3.0.12-rc.3 → 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/assets/styles/global/_layout.scss +4 -0
- package/assets/translations/en-us.yaml +144 -41
- package/assets/translations/zh-hans.yaml +1 -7
- package/chart/monitoring/ClusterSelector.vue +0 -21
- package/chart/monitoring/prometheus/index.vue +6 -3
- package/components/CruResource.vue +161 -14
- package/components/ExplorerMembers.vue +8 -4
- package/components/ExplorerProjectsNamespaces.vue +10 -6
- package/components/GrowlManager.vue +4 -0
- 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 +2 -0
- package/components/Resource/Detail/Metadata/KeyValue.vue +5 -2
- package/components/Resource/Detail/Metadata/KeyValueRow.vue +2 -6
- package/components/ResourceDetail/index.vue +1 -1
- package/components/ResourceList/Masthead.vue +7 -1
- package/components/ResourceList/index.vue +82 -1
- package/components/RichTranslation.vue +5 -2
- package/components/Setting.vue +1 -0
- 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 +9 -4
- 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/FleetClusterTargets/ClusterSelectionFields.vue +217 -0
- package/components/fleet/FleetClusterTargets/TargetsList.vue +123 -35
- package/components/fleet/FleetClusterTargets/index.vue +189 -146
- 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 +253 -0
- 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 +39 -1
- package/components/form/Labels.vue +22 -3
- package/components/form/NameNsDescription.vue +13 -5
- package/components/form/ResourceTabs/index.vue +1 -0
- package/components/form/__tests__/NameNsDescription.test.ts +75 -0
- package/components/formatter/InternalExternalIP.vue +10 -4
- package/components/formatter/ServiceTargets.vue +26 -7
- package/components/formatter/__tests__/InternalExternalIP.test.ts +132 -0
- package/components/formatter/__tests__/ServiceTargets.test.ts +412 -0
- package/components/nav/Header.vue +4 -0
- package/components/nav/TopLevelMenu.vue +7 -2
- package/components/nav/__tests__/Header.test.ts +15 -0
- package/components/nav/__tests__/TopLevelMenu.test.ts +120 -2
- package/components/templates/default.vue +9 -4
- package/components/templates/home.vue +9 -4
- package/components/templates/plain.vue +9 -4
- 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/config/home-links.js +1 -1
- package/config/labels-annotations.js +1 -0
- package/config/product/explorer.js +17 -4
- package/config/product/manager.js +2 -0
- 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 +20 -6
- package/config/settings.ts +0 -2
- package/config/table-headers.js +3 -4
- package/config/types.js +9 -0
- package/core/plugin-products-base.ts +3 -3
- package/core/plugin-types.ts +83 -30
- package/core/plugin.ts +3 -0
- package/core/types-provisioning.ts +34 -1
- package/core/types.ts +15 -2
- 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/provisioning.cattle.io.cluster.vue +30 -4
- 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 +34 -9
- 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 +128 -95
- 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/provisioning.cattle.io.cluster/rke2.vue +84 -10
- package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +11 -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 +16 -10
- package/mixins/__tests__/auth-config.test.ts +90 -0
- package/mixins/__tests__/chart.test.ts +94 -0
- package/mixins/__tests__/resource-fetch-api-pagination.test.ts +48 -0
- package/mixins/auth-config.js +7 -0
- package/mixins/chart.js +11 -2
- package/mixins/child-hook.js +12 -6
- package/mixins/create-edit-view/impl.js +5 -3
- package/mixins/resource-fetch-api-pagination.js +21 -1
- 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__/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.node.ts +22 -0
- package/models/__tests__/namespace.test.ts +36 -0
- package/models/__tests__/provisioning.cattle.io.cluster.test.ts +49 -0
- package/models/__tests__/workload.test.ts +401 -26
- package/models/catalog.cattle.io.clusterrepo.js +28 -4
- package/models/compliance.cattle.io.clusterscan.js +39 -4
- package/models/fleet-application.js +4 -0
- package/models/fleet.cattle.io.helmop.js +20 -1
- package/models/management.cattle.io.cluster.js +18 -2
- package/models/management.cattle.io.node.js +44 -3
- package/models/namespace.js +1 -1
- package/models/pod.js +33 -1
- package/models/provisioning.cattle.io.cluster.js +5 -5
- package/models/workload.js +108 -13
- package/models/workload.service.js +5 -0
- package/package.json +14 -13
- package/pages/about.vue +5 -6
- package/pages/auth/login.vue +0 -35
- package/pages/auth/setup.vue +11 -0
- 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__/index.test.ts +93 -0
- package/pages/c/_cluster/apps/charts/chart.vue +2 -1
- package/pages/c/_cluster/apps/charts/index.vue +48 -10
- package/pages/c/_cluster/apps/charts/install.vue +122 -116
- package/pages/c/_cluster/auth/roles/index.vue +5 -4
- 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/uiplugins/__tests__/index.test.ts +96 -0
- package/pages/c/_cluster/uiplugins/index.vue +15 -0
- package/pages/fail-whale.vue +16 -11
- package/pages/home.vue +16 -46
- package/plugins/clean-html.d.ts +9 -0
- package/plugins/dashboard-store/__tests__/resource-class.test.ts +93 -0
- package/plugins/dashboard-store/resource-class.js +62 -7
- package/plugins/steve/__tests__/actions.test.ts +212 -0
- package/plugins/steve/actions.js +96 -0
- package/plugins/steve/steve-pagination-utils.ts +1 -1
- package/rancher-components/Accordion/Accordion.vue +53 -9
- package/rancher-components/Form/Checkbox/Checkbox.vue +14 -0
- 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 +103 -0
- package/rancher-components/RcButton/RcButton.vue +94 -15
- package/rancher-components/RcButton/types.ts +3 -0
- 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__/notifications.test.ts +434 -0
- package/store/catalog.js +57 -0
- package/store/plugins.js +7 -4
- package/types/components/buttonGroup.ts +5 -0
- package/types/shell/index.d.ts +104 -70
- package/utils/__tests__/auth.test.ts +273 -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 +37 -1
- package/utils/__tests__/dynamic-importer.test.ts +102 -0
- package/utils/__tests__/fleet-appco.test.ts +312 -0
- package/utils/__tests__/monitoring.test.ts +130 -0
- package/utils/__tests__/object.test.ts +22 -0
- package/utils/__tests__/platform.test.ts +91 -0
- package/utils/__tests__/position.test.ts +237 -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__/time.test.ts +265 -1
- package/utils/__tests__/title.test.ts +47 -0
- package/utils/__tests__/width.test.ts +53 -0
- package/utils/__tests__/window.test.ts +158 -0
- package/utils/__tests__/xccdf.test.ts +126 -6
- 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/object.js +22 -2
- package/utils/provider.ts +12 -0
- package/utils/validators/__tests__/container-images.test.ts +104 -0
- package/utils/validators/__tests__/flow-output.test.ts +91 -0
- package/utils/validators/__tests__/logging-outputs.test.ts +58 -0
- package/utils/validators/__tests__/monitoring-route.test.ts +119 -0
- package/utils/xccdf.ts +39 -42
- package/vue.config.js +1 -1
- package/pages/support/index.vue +0 -264
- package/utils/duration.js +0 -43
package/core/plugin-types.ts
CHANGED
|
@@ -35,6 +35,12 @@ export type ProductRegistrationRouteGenerationOptions = {
|
|
|
35
35
|
* Generated route should omit the path property
|
|
36
36
|
*/
|
|
37
37
|
omitPath?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* @internal
|
|
40
|
+
* Whether the route should start with the product name or not (e.g. "my-product/c/:cluster/:resource" vs "c/:cluster/my-product/:resource")
|
|
41
|
+
* only to be used in very special usecases (internal use only - check FLEET product config for an example)
|
|
42
|
+
* */
|
|
43
|
+
startRouteWithProduct?: boolean;
|
|
38
44
|
}
|
|
39
45
|
|
|
40
46
|
/**
|
|
@@ -72,7 +78,7 @@ export type ProductChildMetadata = {
|
|
|
72
78
|
/**
|
|
73
79
|
* Represents the allowed configuration for a custom page (virtualType)
|
|
74
80
|
*/
|
|
75
|
-
export type
|
|
81
|
+
export type CustomPageConfiguration = {
|
|
76
82
|
/** Display only if condition is met (relates to IF_HAVE in shell/store/type-map) */
|
|
77
83
|
ifHave?: boolean;
|
|
78
84
|
/** Display only if feature is present (relates to shell/store/features) */
|
|
@@ -81,23 +87,44 @@ export type VirtualTypeConfiguration = {
|
|
|
81
87
|
ifHaveType?: string;
|
|
82
88
|
/** Used in conjunction with "ifHaveType", display only if resource type allows this verb (GET, POST, PUT, DELETE) */
|
|
83
89
|
ifHaveVerb?: string;
|
|
84
|
-
/**
|
|
90
|
+
/**
|
|
91
|
+
* @internal
|
|
92
|
+
* Display label for the custom page
|
|
93
|
+
*/
|
|
85
94
|
label?: string;
|
|
86
|
-
/**
|
|
95
|
+
/**
|
|
96
|
+
* @internal
|
|
97
|
+
* Translation key for the label
|
|
98
|
+
* */
|
|
87
99
|
labelKey?: string;
|
|
88
|
-
/**
|
|
100
|
+
/**
|
|
101
|
+
* @internal
|
|
102
|
+
* Name of the page (unique identifier)
|
|
103
|
+
*/
|
|
89
104
|
name?: string;
|
|
90
|
-
/**
|
|
105
|
+
/**
|
|
106
|
+
* @internal
|
|
107
|
+
* Entry route definition for this custom page
|
|
108
|
+
*/
|
|
91
109
|
route?: RouteRecordRawWithParams | PluginRouteRecordRaw | Object;
|
|
92
|
-
/**
|
|
110
|
+
/**
|
|
111
|
+
* @internal
|
|
112
|
+
* Icon for the custom page (relates to icons in https://github.com/rancher/icons)
|
|
113
|
+
*/
|
|
93
114
|
icon?: 'compass';
|
|
94
115
|
/** Whether this custom page is namespaced or not */
|
|
95
116
|
namespaced?: boolean;
|
|
96
|
-
/**
|
|
117
|
+
/**
|
|
118
|
+
* @internal
|
|
119
|
+
* Ordering weight for the custom page
|
|
120
|
+
*/
|
|
97
121
|
weight?: number;
|
|
98
122
|
/** Whether this custom page is exact match */
|
|
99
123
|
exact?: boolean;
|
|
100
|
-
/**
|
|
124
|
+
/**
|
|
125
|
+
* @internal
|
|
126
|
+
* Whether this custom page will act as an overview page
|
|
127
|
+
* */
|
|
101
128
|
overview?: boolean;
|
|
102
129
|
/** Whether this custom page has an exact path match */
|
|
103
130
|
'exact-path'?: boolean;
|
|
@@ -106,7 +133,11 @@ export type VirtualTypeConfiguration = {
|
|
|
106
133
|
/**
|
|
107
134
|
* Represents the allowed configuration for a resource page (configureType)
|
|
108
135
|
*/
|
|
109
|
-
export type
|
|
136
|
+
export type ResourcePageConfiguration = {
|
|
137
|
+
/**
|
|
138
|
+
* @internal
|
|
139
|
+
* Entry route definition for this custom page
|
|
140
|
+
*/
|
|
110
141
|
/** Override for the name displayed */
|
|
111
142
|
displayName?: string;
|
|
112
143
|
/** Override for the create button string on a list view */
|
|
@@ -129,25 +160,47 @@ export type ConfigureTypeConfiguration = {
|
|
|
129
160
|
canYaml?: boolean;
|
|
130
161
|
/** Show the Masthead in the edit resource component */
|
|
131
162
|
resourceEditMasthead?: boolean;
|
|
132
|
-
/**
|
|
163
|
+
/**
|
|
164
|
+
* @internal
|
|
165
|
+
* Entry route definition for this resource page
|
|
166
|
+
*/
|
|
133
167
|
customRoute?: RouteRecordRawWithParams;
|
|
134
168
|
/** Hide this type from the nav/search bar on downstream clusters (will only show in "local" cluster) */
|
|
135
169
|
localOnly?: boolean;
|
|
170
|
+
/** Whether this custom page is namespaced or not */
|
|
171
|
+
namespaced?: boolean;
|
|
172
|
+
/**
|
|
173
|
+
* @internal
|
|
174
|
+
* Whether this custom page has list groups (definition for grouping items in the list view)
|
|
175
|
+
*/
|
|
176
|
+
listGroups?: {
|
|
177
|
+
/** Icon for the group (relates to icons in rancher-icons */
|
|
178
|
+
icon?: string;
|
|
179
|
+
/** Value for the group (used for grouping items in the list view) */
|
|
180
|
+
value?: string;
|
|
181
|
+
/** Field for the group (used for grouping items in the list view) */
|
|
182
|
+
field?: string;
|
|
183
|
+
/** Column to hide when this group is active */
|
|
184
|
+
hideColumn?: string;
|
|
185
|
+
/** Tooltip key for the group */
|
|
186
|
+
tooltipKey?: string;
|
|
187
|
+
}[];
|
|
188
|
+
/**
|
|
189
|
+
* @internal
|
|
190
|
+
* Whether the provided list groups will override the default grouping options (e.g. group by namespace, group by cluster, etc.) or be added to them
|
|
191
|
+
*/
|
|
192
|
+
listGroupsWillOverride?: boolean;
|
|
193
|
+
/**
|
|
194
|
+
* @internal
|
|
195
|
+
* Use this to configure subtypes that should be shown in the list view for this type (e.g. show "pods" and "deployments" in the list view for "workloads")
|
|
196
|
+
*/
|
|
197
|
+
subTypes?: string[];
|
|
136
198
|
// resource: undefined; // Use this resource in ResourceDetails instead
|
|
137
199
|
// resourceDetail: undefined; // Use this resource specifically for ResourceDetail's detail component
|
|
138
200
|
// resourceEdit: undefined; // Use this resource specifically for ResourceDetail's edit component
|
|
139
201
|
// depaginate: undefined; // Use this to depaginate requests for this type
|
|
140
202
|
// notFilterNamespace: undefined; // Define namespaces that do not need to be filtered
|
|
141
203
|
// used in configureType options, to be typed later if needed
|
|
142
|
-
// listGroups: [
|
|
143
|
-
// {
|
|
144
|
-
// icon: 'icon-role-binding',
|
|
145
|
-
// value: 'node',
|
|
146
|
-
// field: 'roleDisplay',
|
|
147
|
-
// hideColumn: ROLE.name,
|
|
148
|
-
// tooltipKey: 'resourceTable.groupBy.role'
|
|
149
|
-
// }
|
|
150
|
-
// ]
|
|
151
204
|
}
|
|
152
205
|
|
|
153
206
|
/**
|
|
@@ -165,16 +218,6 @@ export type OverviewPageRoutingMetadata = {
|
|
|
165
218
|
component: VueRouteComponent;
|
|
166
219
|
}
|
|
167
220
|
|
|
168
|
-
/**
|
|
169
|
-
* Represents a custom page with a component
|
|
170
|
-
*/
|
|
171
|
-
export type ProductChildCustomPage = ProductChildMetadata & {
|
|
172
|
-
/** Component to render for this custom page */
|
|
173
|
-
component: VueRouteComponent;
|
|
174
|
-
/** Optional configuration for the page */
|
|
175
|
-
config?: VirtualTypeConfiguration;
|
|
176
|
-
};
|
|
177
|
-
|
|
178
221
|
/**
|
|
179
222
|
* Represents a resource page with a type (K8s resource)
|
|
180
223
|
*/
|
|
@@ -182,7 +225,7 @@ export type ProductChildResourcePage = {
|
|
|
182
225
|
/** K8s resource type name for a resource page */
|
|
183
226
|
type: string;
|
|
184
227
|
/** Optional configuration for the resource page */
|
|
185
|
-
config?:
|
|
228
|
+
config?: ResourcePageConfiguration;
|
|
186
229
|
/** Ordering weight for this page among its siblings */
|
|
187
230
|
weight?: number;
|
|
188
231
|
/** Use this to override the resource name used in the list view for this type */
|
|
@@ -197,6 +240,16 @@ export type ProductChildResourcePage = {
|
|
|
197
240
|
sspHeaders?: PaginationHeaderOptions[];
|
|
198
241
|
};
|
|
199
242
|
|
|
243
|
+
/**
|
|
244
|
+
* Represents a custom page with a component
|
|
245
|
+
*/
|
|
246
|
+
export type ProductChildCustomPage = ProductChildMetadata & {
|
|
247
|
+
/** Component to render for this custom page */
|
|
248
|
+
component: VueRouteComponent;
|
|
249
|
+
/** Optional configuration for the page */
|
|
250
|
+
config?: CustomPageConfiguration;
|
|
251
|
+
};
|
|
252
|
+
|
|
200
253
|
/**
|
|
201
254
|
* Represents a page item (custom page or resource page) in a product's config
|
|
202
255
|
* - For custom pages: use `component` with `name` and `label`/`labelKey`
|
package/core/plugin.ts
CHANGED
|
@@ -124,6 +124,9 @@ export class Plugin implements IPlugin {
|
|
|
124
124
|
this.topLevelProduct = true;
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
+
_setStartRouteWithProduct(_value: boolean): void {
|
|
128
|
+
}
|
|
129
|
+
|
|
127
130
|
// Track which products the plugin creates
|
|
128
131
|
// Legacy DSL method
|
|
129
132
|
DSL(store: any, productName: string) {
|
|
@@ -41,7 +41,11 @@ export type ClusterDetailTabs = {
|
|
|
41
41
|
/**
|
|
42
42
|
* Kube conditions of the provisioning.cattle.io.cluster instance
|
|
43
43
|
*/
|
|
44
|
-
conditions: boolean
|
|
44
|
+
conditions: boolean,
|
|
45
|
+
/**
|
|
46
|
+
* RKE2 autoscaler
|
|
47
|
+
*/
|
|
48
|
+
autoscaler: boolean
|
|
45
49
|
};
|
|
46
50
|
|
|
47
51
|
/**
|
|
@@ -238,6 +242,16 @@ export interface IClusterProvisioner {
|
|
|
238
242
|
*/
|
|
239
243
|
machineConfigSchema?: { [key: string]: any };
|
|
240
244
|
|
|
245
|
+
/**
|
|
246
|
+
* Schema for infrastructure cluster object. For example infrastructure.cluster.x-k8s.io.awscluster
|
|
247
|
+
*
|
|
248
|
+
* The `id` should be in the format of `infrastructure.cluster.x-k8s.io.${ provider id }cluster`
|
|
249
|
+
*
|
|
250
|
+
* The `attributes: { kind: <value> }` should match the last part of the id
|
|
251
|
+
* The `attributes: { group: <value> }` should match the remaining parts of the id
|
|
252
|
+
*/
|
|
253
|
+
infrastructureClusterSchema?: { [key: string]: any };
|
|
254
|
+
|
|
241
255
|
/**
|
|
242
256
|
* Override the default method to create a machine config object that will be inserted into a new machine pool
|
|
243
257
|
*
|
|
@@ -270,6 +284,16 @@ export interface IClusterProvisioner {
|
|
|
270
284
|
*/
|
|
271
285
|
saveMachinePoolConfigs?(pools: any[], cluster: any): Promise<any>
|
|
272
286
|
|
|
287
|
+
/**
|
|
288
|
+
* Optional custom UI section for infrastructure-cluster-specific configuration.
|
|
289
|
+
*/
|
|
290
|
+
extensionInfrastructureSection?: any
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Indicates the provisioner manages upstream CAPI infrastructure resources directly.
|
|
294
|
+
*/
|
|
295
|
+
isUpstreamCAPIProvider?: boolean
|
|
296
|
+
|
|
273
297
|
/* --------------------------------------------------------------------------------------
|
|
274
298
|
* Optionally override parts of the cluster save process with
|
|
275
299
|
* - hooks that run before or after the cluster resource is saved
|
|
@@ -289,6 +313,15 @@ export interface IClusterProvisioner {
|
|
|
289
313
|
*/
|
|
290
314
|
registerSaveHooks?(registerBeforeHook: RegisterClusterSaveHook, registerAfterHook: RegisterClusterSaveHook, cluster: any): void;
|
|
291
315
|
|
|
316
|
+
/**
|
|
317
|
+
* Register hooks that run during `initSpecs` while initializing the cluster form.
|
|
318
|
+
*
|
|
319
|
+
* @param registerInitHook
|
|
320
|
+
* Call `registerInitHook` with a function. The function will be executed during form initialization.
|
|
321
|
+
* @param cluster The cluster (`provisioning.cattle.io.cluster`)
|
|
322
|
+
*/
|
|
323
|
+
registerInitHooks?(registerInitHook: RegisterClusterSaveHook, cluster: any): void;
|
|
324
|
+
|
|
292
325
|
/**
|
|
293
326
|
* Optionally override the save of the cluster resource itself
|
|
294
327
|
*
|
package/core/types.ts
CHANGED
|
@@ -291,6 +291,11 @@ export interface ProductOptions {
|
|
|
291
291
|
*/
|
|
292
292
|
to?: PluginRouteRecordRaw;
|
|
293
293
|
|
|
294
|
+
/**
|
|
295
|
+
* Whether the product can be removed by users (default: false — products are built-in/not removable unless explicitly set to true)
|
|
296
|
+
*/
|
|
297
|
+
removable?: boolean;
|
|
298
|
+
|
|
294
299
|
/**
|
|
295
300
|
* Alternative to the icon property. Uses require
|
|
296
301
|
*/
|
|
@@ -301,6 +306,11 @@ export interface ProductOptions {
|
|
|
301
306
|
*/
|
|
302
307
|
name?: string;
|
|
303
308
|
|
|
309
|
+
/**
|
|
310
|
+
* controls whether a workspace switcher dropdown appears in the header (instead of the namespace filter) if set to true
|
|
311
|
+
*/
|
|
312
|
+
showWorkspaceSwitcher?: boolean;
|
|
313
|
+
|
|
304
314
|
/**
|
|
305
315
|
*
|
|
306
316
|
*/
|
|
@@ -317,8 +327,6 @@ export interface ProductOptions {
|
|
|
317
327
|
* Leaving these here for completeness but I don't think these should be advertised as useable to plugin creators.
|
|
318
328
|
*/
|
|
319
329
|
// ifHaveVerb: string | RegExp;
|
|
320
|
-
// removable: string;
|
|
321
|
-
// showWorkspaceSwitcher: boolean;
|
|
322
330
|
// supportRoute: string;
|
|
323
331
|
// typeStoreMap: string;
|
|
324
332
|
}
|
|
@@ -694,6 +702,11 @@ export interface IExtension {
|
|
|
694
702
|
* @internal - DO NOT USE - Internal API only
|
|
695
703
|
*/
|
|
696
704
|
_registerTopLevelProduct(): void;
|
|
705
|
+
/**
|
|
706
|
+
*
|
|
707
|
+
* @internal - DO NOT USE - Internal API only
|
|
708
|
+
*/
|
|
709
|
+
_setStartRouteWithProduct(value: boolean): void;
|
|
697
710
|
|
|
698
711
|
/**
|
|
699
712
|
* Add a product to the sidebar, with children and a side menu for navigation for internal pages
|
|
@@ -127,4 +127,118 @@ describe('view: provisioning.cattle.io.cluster', () => {
|
|
|
127
127
|
expect(wrapper.vm.showRegistration).toStrictEqual(false);
|
|
128
128
|
});
|
|
129
129
|
});
|
|
130
|
+
|
|
131
|
+
describe('fakeMachines', () => {
|
|
132
|
+
const clusterName = 'my-cluster';
|
|
133
|
+
const poolName = 'pool1';
|
|
134
|
+
const namespace = 'fleet-default';
|
|
135
|
+
const poolFullName = `${ clusterName }-${ poolName }`;
|
|
136
|
+
|
|
137
|
+
const wrongTemplate = { metadata: { name: `${ poolFullName }-aaaa1111`, namespace } };
|
|
138
|
+
const correctTemplate = { metadata: { name: `${ poolFullName }-bbbb2222`, namespace } };
|
|
139
|
+
|
|
140
|
+
const baseValue = {
|
|
141
|
+
name: clusterName,
|
|
142
|
+
nameDisplay: clusterName,
|
|
143
|
+
namespace,
|
|
144
|
+
machines: [],
|
|
145
|
+
spec: {
|
|
146
|
+
rkeConfig: {
|
|
147
|
+
machinePools: [
|
|
148
|
+
{
|
|
149
|
+
name: poolName,
|
|
150
|
+
machineConfigRef: { name: `nc-${ poolFullName }-xyz`, kind: 'Amazonec2Config' },
|
|
151
|
+
},
|
|
152
|
+
],
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
it('uses MachineDeployment infrastructureRef to select the correct template for an empty pool', async() => {
|
|
158
|
+
const machineDeployment = {
|
|
159
|
+
metadata: { name: poolFullName, namespace },
|
|
160
|
+
spec: { template: { spec: { infrastructureRef: { name: correctTemplate.metadata.name } } } },
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
const wrapper = shallowMount(ProvisioningCattleIoCluster, {
|
|
164
|
+
props: { value: baseValue },
|
|
165
|
+
global: { mocks },
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
await wrapper.setData({
|
|
169
|
+
allMachineDeployments: [machineDeployment],
|
|
170
|
+
machineTemplates: [wrongTemplate, correctTemplate],
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
const [fakeMachine] = wrapper.vm.fakeMachines;
|
|
174
|
+
|
|
175
|
+
expect(fakeMachine.pool._template).toStrictEqual(correctTemplate);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it('returns the first prefix-matching template when no MachineDeployment exists for the pool', async() => {
|
|
179
|
+
const wrapper = shallowMount(ProvisioningCattleIoCluster, {
|
|
180
|
+
props: { value: baseValue },
|
|
181
|
+
global: { mocks },
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
await wrapper.setData({
|
|
185
|
+
allMachineDeployments: [],
|
|
186
|
+
machineTemplates: [wrongTemplate, correctTemplate],
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
const [fakeMachine] = wrapper.vm.fakeMachines;
|
|
190
|
+
|
|
191
|
+
expect(fakeMachine.pool._template).toStrictEqual(wrongTemplate);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
it('returns undefined template when MachineDeployment infrastructureRef does not match any template', async() => {
|
|
195
|
+
const machineDeployment = {
|
|
196
|
+
metadata: { name: poolFullName, namespace },
|
|
197
|
+
spec: { template: { spec: { infrastructureRef: { name: `${ poolFullName }-nonexistent` } } } },
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
const wrapper = shallowMount(ProvisioningCattleIoCluster, {
|
|
201
|
+
props: { value: baseValue },
|
|
202
|
+
global: { mocks },
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
await wrapper.setData({
|
|
206
|
+
allMachineDeployments: [machineDeployment],
|
|
207
|
+
machineTemplates: [wrongTemplate, correctTemplate],
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
const [fakeMachine] = wrapper.vm.fakeMachines;
|
|
211
|
+
|
|
212
|
+
expect(fakeMachine.pool._template).toBeUndefined();
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
it('does not include a pool in fakeMachines when it has active machines', async() => {
|
|
216
|
+
const valueWithMachines = {
|
|
217
|
+
...baseValue,
|
|
218
|
+
machines: [
|
|
219
|
+
{
|
|
220
|
+
metadata: {
|
|
221
|
+
labels: {
|
|
222
|
+
'cluster.x-k8s.io/cluster-name': clusterName,
|
|
223
|
+
'rke.cattle.io/rke-machine-pool-name': poolName,
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
spec: { infrastructureRef: { apiGroup: 'rke-machine.cattle.io', name: `${ poolFullName }-bbbb2222` } },
|
|
227
|
+
},
|
|
228
|
+
],
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
const wrapper = shallowMount(ProvisioningCattleIoCluster, {
|
|
232
|
+
props: { value: valueWithMachines },
|
|
233
|
+
global: { mocks },
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
await wrapper.setData({
|
|
237
|
+
allMachineDeployments: [],
|
|
238
|
+
machineTemplates: [wrongTemplate, correctTemplate],
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
expect(wrapper.vm.fakeMachines).toHaveLength(0);
|
|
242
|
+
});
|
|
243
|
+
});
|
|
130
244
|
});
|
|
@@ -1,156 +1,7 @@
|
|
|
1
1
|
import Workload from '@shell/detail/workload/index.vue';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
it('should do nothing if ingress schema is not present', () => {
|
|
7
|
-
const mockThis = {
|
|
8
|
-
ingressSchema: undefined,
|
|
9
|
-
matchingIngresses: [],
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
findMatchingIngresses.call(mockThis);
|
|
13
|
-
expect(mockThis.matchingIngresses).toStrictEqual([]);
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
it('should not find any ingresses if there are none', () => {
|
|
17
|
-
const mockThis = {
|
|
18
|
-
ingressSchema: true,
|
|
19
|
-
allIngresses: [],
|
|
20
|
-
matchingIngresses: [],
|
|
21
|
-
value: { metadata: { namespace: 'test' }, relatedServices: [] }
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
findMatchingIngresses.call(mockThis);
|
|
25
|
-
expect(mockThis.matchingIngresses).toStrictEqual([]);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it('should find matching ingresses', () => {
|
|
29
|
-
const mockThis = {
|
|
30
|
-
ingressSchema: true,
|
|
31
|
-
allIngresses: [
|
|
32
|
-
{ // matching
|
|
33
|
-
metadata: { namespace: 'test' },
|
|
34
|
-
spec: { rules: [{ http: { paths: [{ backend: { service: { name: 'service1' } } }] } }] }
|
|
35
|
-
}
|
|
36
|
-
],
|
|
37
|
-
matchingIngresses: [],
|
|
38
|
-
value: { metadata: { namespace: 'test' }, relatedServices: [{ metadata: { name: 'service1' } }] }
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
findMatchingIngresses.call(mockThis);
|
|
42
|
-
expect(mockThis.matchingIngresses).toHaveLength(1);
|
|
43
|
-
expect(mockThis.matchingIngresses[0]).toStrictEqual(mockThis.allIngresses[0]);
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('should not match ingresses from other namespaces', () => {
|
|
47
|
-
const mockThis = {
|
|
48
|
-
ingressSchema: true,
|
|
49
|
-
allIngresses: [
|
|
50
|
-
{ // not matching
|
|
51
|
-
metadata: { namespace: 'other' },
|
|
52
|
-
spec: { rules: [{ http: { paths: [{ backend: { service: { name: 'service1' } } }] } }] }
|
|
53
|
-
}
|
|
54
|
-
],
|
|
55
|
-
matchingIngresses: [],
|
|
56
|
-
value: { metadata: { namespace: 'test' }, relatedServices: [{ metadata: { name: 'service1' } }] }
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
findMatchingIngresses.call(mockThis);
|
|
60
|
-
expect(mockThis.matchingIngresses).toHaveLength(0);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('should not match ingresses pointing to other services', () => {
|
|
64
|
-
const mockThis = {
|
|
65
|
-
ingressSchema: true,
|
|
66
|
-
allIngresses: [
|
|
67
|
-
{ // not matching
|
|
68
|
-
metadata: { namespace: 'test' },
|
|
69
|
-
spec: { rules: [{ http: { paths: [{ backend: { service: { name: 'service2' } } }] } }] }
|
|
70
|
-
}
|
|
71
|
-
],
|
|
72
|
-
matchingIngresses: [],
|
|
73
|
-
value: { metadata: { namespace: 'test' }, relatedServices: [{ metadata: { name: 'service1' } }] }
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
findMatchingIngresses.call(mockThis);
|
|
77
|
-
expect(mockThis.matchingIngresses).toHaveLength(0);
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it('should handle ingresses with no rules', () => {
|
|
81
|
-
const mockThis = {
|
|
82
|
-
ingressSchema: true,
|
|
83
|
-
allIngresses: [
|
|
84
|
-
{
|
|
85
|
-
metadata: { namespace: 'test' },
|
|
86
|
-
spec: { }
|
|
87
|
-
}
|
|
88
|
-
],
|
|
89
|
-
matchingIngresses: [],
|
|
90
|
-
value: { metadata: { namespace: 'test' }, relatedServices: [{ metadata: { name: 'service1' } }] }
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
findMatchingIngresses.call(mockThis);
|
|
94
|
-
expect(mockThis.matchingIngresses).toHaveLength(0);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it('should handle ingress rules with no paths', () => {
|
|
98
|
-
const mockThis = {
|
|
99
|
-
ingressSchema: true,
|
|
100
|
-
allIngresses: [
|
|
101
|
-
{
|
|
102
|
-
metadata: { namespace: 'test' },
|
|
103
|
-
spec: { rules: [{ http: {} }] }
|
|
104
|
-
}
|
|
105
|
-
],
|
|
106
|
-
matchingIngresses: [],
|
|
107
|
-
value: { metadata: { namespace: 'test' }, relatedServices: [{ metadata: { name: 'service1' } }] }
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
findMatchingIngresses.call(mockThis);
|
|
111
|
-
expect(mockThis.matchingIngresses).toHaveLength(0);
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it('should handle ingress paths with no backend service', () => {
|
|
115
|
-
const mockThis = {
|
|
116
|
-
ingressSchema: true,
|
|
117
|
-
allIngresses: [
|
|
118
|
-
{
|
|
119
|
-
metadata: { namespace: 'test' },
|
|
120
|
-
spec: { rules: [{ http: { paths: [{ backend: {} }] } }] }
|
|
121
|
-
}
|
|
122
|
-
],
|
|
123
|
-
matchingIngresses: [],
|
|
124
|
-
value: { metadata: { namespace: 'test' }, relatedServices: [{ metadata: { name: 'service1' } }] }
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
findMatchingIngresses.call(mockThis);
|
|
128
|
-
expect(mockThis.matchingIngresses).toHaveLength(0);
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
it('should find one of many ingresses', () => {
|
|
132
|
-
const mockThis = {
|
|
133
|
-
ingressSchema: true,
|
|
134
|
-
allIngresses: [
|
|
135
|
-
{ // not matching
|
|
136
|
-
metadata: { namespace: 'other' },
|
|
137
|
-
spec: { rules: [{ http: { paths: [{ backend: { service: { name: 'service1' } } }] } }] }
|
|
138
|
-
},
|
|
139
|
-
{ // matching
|
|
140
|
-
metadata: { namespace: 'test' },
|
|
141
|
-
spec: { rules: [{ http: { paths: [{ backend: { service: { name: 'service1' } } }] } }] }
|
|
142
|
-
},
|
|
143
|
-
{ // not matching
|
|
144
|
-
metadata: { namespace: 'test' },
|
|
145
|
-
spec: { rules: [{ http: { paths: [{ backend: { service: { name: 'service2' } } }] } }] }
|
|
146
|
-
}
|
|
147
|
-
],
|
|
148
|
-
matchingIngresses: [],
|
|
149
|
-
value: { metadata: { namespace: 'test' }, relatedServices: [{ metadata: { name: 'service1' } }] }
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
findMatchingIngresses.call(mockThis);
|
|
153
|
-
expect(mockThis.matchingIngresses).toHaveLength(1);
|
|
154
|
-
expect(mockThis.matchingIngresses[0]).toStrictEqual(mockThis.allIngresses[1]);
|
|
3
|
+
describe('workload detail page', () => {
|
|
4
|
+
it('should not have findMatchingIngresses method (logic moved to workload model)', () => {
|
|
5
|
+
expect(Workload.methods?.findMatchingIngresses).toBeUndefined();
|
|
155
6
|
});
|
|
156
7
|
});
|
|
@@ -96,7 +96,18 @@ export default {
|
|
|
96
96
|
await this.value.waitForProvisioner();
|
|
97
97
|
|
|
98
98
|
// Support for the 'provisioner' extension
|
|
99
|
-
|
|
99
|
+
let extClass = this.$extension.getDynamic('provisioner', this.value.machineProvider);
|
|
100
|
+
let provider = this.value.machineProvider;
|
|
101
|
+
|
|
102
|
+
if (!extClass) {
|
|
103
|
+
extClass = this.$extension.getDynamic('provisioner', this.value.provisioner.toLowerCase());
|
|
104
|
+
provider = this.value.provisioner.toLowerCase();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (!extClass && this.value.isImported) {
|
|
108
|
+
extClass = this.$extension.getDynamic('provisioner', 'imported');
|
|
109
|
+
provider = 'imported';
|
|
110
|
+
}
|
|
100
111
|
|
|
101
112
|
if (extClass) {
|
|
102
113
|
this.extProvider = new extClass({
|
|
@@ -111,7 +122,7 @@ export default {
|
|
|
111
122
|
...this.extDetailTabs,
|
|
112
123
|
...this.extProvider.detailTabs
|
|
113
124
|
};
|
|
114
|
-
this.extCustomParams = { provider
|
|
125
|
+
this.extCustomParams = { provider };
|
|
115
126
|
}
|
|
116
127
|
|
|
117
128
|
// Support for a model extension
|
|
@@ -120,7 +131,7 @@ export default {
|
|
|
120
131
|
...this.extDetailTabs,
|
|
121
132
|
...this.value.customProvisionerHelper.detailTabs
|
|
122
133
|
};
|
|
123
|
-
this.extCustomParams = { provider
|
|
134
|
+
this.extCustomParams = { provider };
|
|
124
135
|
}
|
|
125
136
|
|
|
126
137
|
const schema = this.$store.getters[`management/schemaFor`](CAPI.RANCHER_CLUSTER);
|
|
@@ -402,8 +413,23 @@ export default {
|
|
|
402
413
|
|
|
403
414
|
const templateNamePrefix = `${ pool.metadata.name }-`;
|
|
404
415
|
|
|
416
|
+
// The MachineDeployment still exists for empty pools. The
|
|
417
|
+
// infrastructureRef points to the template that matches the current
|
|
418
|
+
// config. Fallback to the prefix-match to return an arbitrary template
|
|
419
|
+
// when multiple exist
|
|
420
|
+
const machineDeployment = this.allMachineDeployments.find(
|
|
421
|
+
(d) => d.metadata.name === pool.metadata.name && d.metadata.namespace === pool.metadata.namespace
|
|
422
|
+
);
|
|
423
|
+
const activeTemplateName = machineDeployment?.spec?.template?.spec?.infrastructureRef?.name;
|
|
424
|
+
|
|
405
425
|
// All of these properties are needed to ensure the pool displays correctly and that we can scale up and down
|
|
406
|
-
pool._template = this.machineTemplates.find((t) =>
|
|
426
|
+
pool._template = this.machineTemplates.find((t) => {
|
|
427
|
+
if (activeTemplateName) {
|
|
428
|
+
return t.metadata.name === activeTemplateName;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
return t.metadata.name.startsWith(templateNamePrefix);
|
|
432
|
+
});
|
|
407
433
|
pool._cluster = this.value;
|
|
408
434
|
pool._clusterSpec = mp;
|
|
409
435
|
|