@rancher/shell 3.0.5-rc.5 → 3.0.5-rc.7

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.
Files changed (361) hide show
  1. package/assets/data/aws-regions.json +1 -0
  2. package/assets/images/key.svg +17 -0
  3. package/assets/styles/base/_spacing.scss +2 -2
  4. package/assets/styles/base/_variables.scss +17 -11
  5. package/assets/styles/global/_form.scss +1 -1
  6. package/assets/styles/global/_labeled-input.scss +1 -1
  7. package/assets/styles/themes/_dark.scss +5 -0
  8. package/assets/styles/themes/_light.scss +11 -2
  9. package/assets/styles/vendor/vue-select.scss +1 -1
  10. package/assets/translations/en-us.yaml +426 -64
  11. package/assets/translations/zh-hans.yaml +3 -4
  12. package/cloud-credential/gcp.vue +9 -1
  13. package/components/AppModal.vue +2 -0
  14. package/components/CodeMirror.vue +2 -2
  15. package/components/ConfigMapSettings/Settings.vue +377 -0
  16. package/components/ConfigMapSettings/index.vue +354 -0
  17. package/components/CruResource.vue +1 -2
  18. package/components/DetailText.vue +61 -11
  19. package/components/Drawer/Chrome.vue +115 -0
  20. package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +61 -0
  21. package/components/Drawer/ResourceDetailDrawer/YamlTab.vue +48 -0
  22. package/components/Drawer/ResourceDetailDrawer/__tests__/ConfigTab.test.ts +54 -0
  23. package/components/Drawer/ResourceDetailDrawer/__tests__/YamlTab.test.ts +80 -0
  24. package/components/Drawer/ResourceDetailDrawer/__tests__/composables.test.ts +106 -0
  25. package/components/Drawer/ResourceDetailDrawer/__tests__/helpers.test.ts +42 -0
  26. package/components/Drawer/ResourceDetailDrawer/composables.ts +53 -0
  27. package/components/Drawer/ResourceDetailDrawer/helpers.ts +10 -0
  28. package/components/Drawer/ResourceDetailDrawer/index.vue +111 -0
  29. package/components/GrowlManager.vue +16 -15
  30. package/components/IconOrSvg.vue +5 -0
  31. package/components/KeyValueView.vue +1 -1
  32. package/components/Loading.vue +1 -1
  33. package/components/LocaleSelector.vue +9 -1
  34. package/components/PaginatedResourceTable.vue +46 -1
  35. package/components/ProgressBarMulti.vue +1 -0
  36. package/components/PromptModal.vue +6 -1
  37. package/components/PromptRestore.vue +22 -44
  38. package/components/RelatedResources.vue +4 -12
  39. package/components/Resource/Detail/Additional.vue +46 -0
  40. package/components/Resource/Detail/Metadata/Annotations/__tests__/index.test.ts +1 -1
  41. package/components/Resource/Detail/Metadata/Annotations/index.vue +5 -0
  42. package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/identifying-fields.test.ts +223 -0
  43. package/components/Resource/Detail/Metadata/IdentifyingInformation/composable.ts +47 -256
  44. package/components/Resource/Detail/Metadata/IdentifyingInformation/identifying-fields.ts +317 -0
  45. package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +34 -5
  46. package/components/Resource/Detail/Metadata/KeyValue.vue +32 -22
  47. package/components/Resource/Detail/Metadata/Labels/__tests__/index.test.ts +1 -1
  48. package/components/Resource/Detail/Metadata/Labels/index.vue +4 -0
  49. package/components/Resource/Detail/Metadata/Rectangle.vue +3 -1
  50. package/components/Resource/Detail/Metadata/__tests__/KeyValue.test.ts +1 -1
  51. package/components/Resource/Detail/Metadata/__tests__/Rectangle.test.ts +1 -1
  52. package/components/Resource/Detail/Metadata/__tests__/composables.test.ts +75 -0
  53. package/components/Resource/Detail/Metadata/composables.ts +60 -11
  54. package/components/Resource/Detail/Metadata/index.vue +12 -5
  55. package/components/Resource/Detail/Page.vue +15 -0
  56. package/components/Resource/Detail/ResourceRow.vue +37 -18
  57. package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/__tests__/composables.test.ts +29 -0
  58. package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/__tests__/index.test.ts +48 -0
  59. package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/composables.ts +31 -0
  60. package/components/Resource/Detail/ResourceTabs/ConfigMapDataTab/index.vue +50 -0
  61. package/components/Resource/Detail/ResourceTabs/KnownHostsTab/__tests__/composables.test.ts +66 -0
  62. package/components/Resource/Detail/ResourceTabs/KnownHostsTab/composables.ts +21 -0
  63. package/components/Resource/Detail/ResourceTabs/KnownHostsTab/index.vue +31 -0
  64. package/components/Resource/Detail/ResourceTabs/SecretDataTab/Basic.vue +45 -0
  65. package/components/Resource/Detail/ResourceTabs/SecretDataTab/BasicAuth.vue +31 -0
  66. package/components/Resource/Detail/ResourceTabs/SecretDataTab/Certificate.vue +31 -0
  67. package/components/Resource/Detail/ResourceTabs/SecretDataTab/Registry.vue +22 -0
  68. package/components/Resource/Detail/ResourceTabs/SecretDataTab/ServiceAccountToken.vue +31 -0
  69. package/components/Resource/Detail/ResourceTabs/SecretDataTab/Ssh.vue +32 -0
  70. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Basic.test.ts +40 -0
  71. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/BasicAuth.test.ts +33 -0
  72. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Certificate.test.ts +33 -0
  73. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Registry.test.ts +27 -0
  74. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/ServiceAccountToken.test.ts +33 -0
  75. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/Ssh.test.ts +33 -0
  76. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/auth-types.test.ts +186 -0
  77. package/components/Resource/Detail/ResourceTabs/SecretDataTab/__tests__/composables.test.ts +102 -0
  78. package/components/Resource/Detail/ResourceTabs/SecretDataTab/auth-types.ts +109 -0
  79. package/components/Resource/Detail/ResourceTabs/SecretDataTab/composeables.ts +52 -0
  80. package/components/Resource/Detail/ResourceTabs/SecretDataTab/index.vue +71 -0
  81. package/components/Resource/Detail/SpacedRow.vue +1 -1
  82. package/components/Resource/Detail/TitleBar/Title.vue +2 -1
  83. package/components/Resource/Detail/TitleBar/__tests__/Title.test.ts +1 -1
  84. package/components/Resource/Detail/TitleBar/__tests__/Top.test.ts +1 -1
  85. package/components/Resource/Detail/TitleBar/__tests__/composables.test.ts +63 -0
  86. package/components/Resource/Detail/TitleBar/__tests__/index.test.ts +1 -1
  87. package/components/Resource/Detail/TitleBar/composables.ts +45 -0
  88. package/components/Resource/Detail/TitleBar/index.vue +85 -13
  89. package/components/Resource/Detail/composables.ts +45 -0
  90. package/components/ResourceDetail/Masthead/__tests__/index.test.ts +70 -0
  91. package/components/ResourceDetail/{__tests__/Masthead.test.ts → Masthead/__tests__/legacy.test.ts} +3 -3
  92. package/components/ResourceDetail/Masthead/index.vue +65 -0
  93. package/components/ResourceDetail/Masthead/latest.vue +44 -0
  94. package/components/ResourceDetail/{Masthead.vue → Masthead/legacy.vue} +1 -1
  95. package/components/ResourceDetail/__tests__/index.test.ts +26 -5
  96. package/components/ResourceDetail/index.vue +33 -17
  97. package/components/ResourceDetail/legacy.vue +18 -1
  98. package/components/ResourceList/Masthead.vue +6 -0
  99. package/components/ResourceList/index.vue +1 -0
  100. package/components/ResourceTable.vue +6 -1
  101. package/components/ResourceYaml.vue +15 -2
  102. package/components/RichTranslation.vue +106 -0
  103. package/components/SlideInPanelManager.vue +46 -11
  104. package/components/SortableTable/index.vue +1 -1
  105. package/components/SortableTable/selection.js +0 -1
  106. package/components/StateDot/index.vue +28 -0
  107. package/components/Tabbed/index.vue +17 -16
  108. package/components/Wizard.vue +4 -2
  109. package/components/__tests__/ConfigMapSettings.test.ts +376 -0
  110. package/components/__tests__/GrowlManager.test.ts +0 -25
  111. package/components/__tests__/PromptRestore.test.ts +1 -65
  112. package/components/__tests__/RichTranslation.test.ts +115 -0
  113. package/components/auth/login/ldap.vue +1 -1
  114. package/components/fleet/FleetApplications.vue +0 -7
  115. package/components/fleet/FleetClusterTargets/TargetsList.vue +66 -0
  116. package/components/fleet/FleetClusterTargets/index.vue +455 -0
  117. package/components/fleet/FleetClusters.vue +25 -6
  118. package/components/fleet/FleetGitRepoPaths.vue +476 -0
  119. package/components/fleet/FleetHelmOps.vue +8 -0
  120. package/components/fleet/FleetRepos.vue +1 -6
  121. package/components/fleet/FleetResources.vue +4 -5
  122. package/components/fleet/FleetValuesFrom.vue +295 -0
  123. package/components/fleet/__tests__/FleetClusterTargets.test.ts +1224 -0
  124. package/components/fleet/__tests__/FleetGitRepoPaths.test.ts +265 -0
  125. package/components/fleet/__tests__/FleetOCIStorageSecret.test.ts +13 -13
  126. package/components/fleet/__tests__/FleetValuesFrom.test.ts +300 -0
  127. package/components/fleet/dashboard/ResourceCard.vue +1 -0
  128. package/components/fleet/dashboard/ResourceCardSummary.vue +1 -5
  129. package/components/fleet/dashboard/ResourceDetails.vue +8 -10
  130. package/components/fleet/dashboard/ResourcePanel.vue +17 -9
  131. package/components/form/ArrayList.vue +13 -2
  132. package/components/form/ChangePassword.vue +3 -1
  133. package/components/form/FileImageSelector.vue +1 -1
  134. package/components/form/Footer.vue +10 -4
  135. package/components/form/KeyValue.vue +81 -43
  136. package/components/form/LabeledSelect.vue +56 -16
  137. package/components/form/Labels.vue +90 -17
  138. package/components/form/MatchExpressions.vue +46 -5
  139. package/components/form/NameNsDescription.vue +2 -1
  140. package/components/form/Networking.vue +24 -19
  141. package/components/form/ResourceLabeledSelect.vue +4 -3
  142. package/components/form/ResourceSelector.vue +1 -0
  143. package/components/form/ResourceTabs/index.vue +5 -0
  144. package/components/form/SecretSelector.vue +9 -2
  145. package/components/form/Select.vue +57 -19
  146. package/components/form/SelectOrCreateAuthSecret.vue +6 -3
  147. package/components/form/SimpleSecretSelector.vue +9 -2
  148. package/components/form/Taints.vue +21 -2
  149. package/components/form/UnitInput.vue +8 -0
  150. package/components/form/ValueFromResource.vue +1 -1
  151. package/components/form/__tests__/LabeledSelect.test.ts +8 -4
  152. package/components/form/__tests__/Labels.test.ts +360 -0
  153. package/components/form/__tests__/MatchExpressions.test.ts +16 -13
  154. package/components/form/__tests__/Networking.test.ts +116 -0
  155. package/components/form/__tests__/Select.test.ts +5 -2
  156. package/components/formatter/FleetApplicationSource.vue +1 -1
  157. package/components/formatter/PodImages.vue +1 -1
  158. package/components/formatter/WorkloadHealthScale.vue +1 -1
  159. package/components/formatter/__tests__/LiveDate.test.ts +10 -2
  160. package/components/google/AccountAccess.vue +209 -0
  161. package/components/google/types/gcp.d.ts +136 -0
  162. package/components/google/types/index.d.ts +101 -0
  163. package/components/google/util/__mocks__/gcp.ts +465 -0
  164. package/components/google/util/formatter.ts +82 -0
  165. package/components/google/util/gcp.ts +134 -0
  166. package/components/google/util/index.d.ts +11 -0
  167. package/components/nav/Favorite.vue +1 -1
  168. package/components/nav/Group.vue +71 -45
  169. package/components/nav/Header.vue +5 -1
  170. package/components/nav/NamespaceFilter.vue +13 -1
  171. package/components/nav/NotificationCenter/Notification.vue +510 -0
  172. package/components/nav/NotificationCenter/NotificationHeader.vue +112 -0
  173. package/components/nav/NotificationCenter/index.vue +148 -0
  174. package/composables/drawer.ts +26 -0
  175. package/composables/resources.test.ts +63 -0
  176. package/composables/resources.ts +38 -0
  177. package/composables/useIsNewDetailPageEnabled.ts +17 -0
  178. package/config/labels-annotations.js +8 -0
  179. package/config/pagination-table-headers.js +8 -1
  180. package/config/product/auth.js +16 -1
  181. package/config/product/{cis.js → compliance.js} +23 -26
  182. package/config/product/explorer.js +32 -3
  183. package/config/product/fleet.js +7 -0
  184. package/config/product/manager.js +0 -1
  185. package/config/product/settings.js +22 -11
  186. package/config/query-params.js +13 -0
  187. package/config/roles.ts +1 -1
  188. package/config/router/navigation-guards/authentication.js +51 -2
  189. package/config/router/routes.js +47 -31
  190. package/config/settings.ts +21 -3
  191. package/config/store.js +2 -0
  192. package/config/system-namespaces.js +1 -1
  193. package/config/table-headers.js +32 -3
  194. package/config/types.js +16 -7
  195. package/config/version.js +1 -1
  196. package/core/plugin.ts +32 -7
  197. package/core/types.ts +18 -1
  198. package/detail/{cis.cattle.io.clusterscan.vue → compliance.cattle.io.clusterscan.vue} +22 -18
  199. package/detail/management.cattle.io.fleetworkspace.vue +18 -27
  200. package/detail/management.cattle.io.oidcclient.vue +369 -0
  201. package/detail/node.vue +2 -2
  202. package/detail/pod.vue +2 -2
  203. package/detail/provisioning.cattle.io.cluster.vue +3 -47
  204. package/detail/service.vue +10 -1
  205. package/detail/workload/index.vue +8 -2
  206. package/dialog/ExtensionCatalogUninstallDialog.vue +7 -4
  207. package/dialog/GenericPrompt.vue +1 -1
  208. package/dialog/ImportDialog.vue +8 -8
  209. package/dialog/OidcClientSecretDialog.vue +117 -0
  210. package/dialog/RotateEncryptionKeyDialog.vue +10 -30
  211. package/edit/__tests__/cis.cattle.io.clusterscan.test.ts +3 -3
  212. package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +5 -2
  213. package/edit/auth/ldap/__tests__/config.test.ts +14 -0
  214. package/edit/auth/ldap/config.vue +24 -0
  215. package/edit/autoscaling.horizontalpodautoscaler/index.vue +4 -1
  216. package/edit/{cis.cattle.io.clusterscan.vue → compliance.cattle.io.clusterscan.vue} +30 -31
  217. package/edit/{cis.cattle.io.clusterscanbenchmark.vue → compliance.cattle.io.clusterscanbenchmark.vue} +4 -4
  218. package/edit/{cis.cattle.io.clusterscanprofile.vue → compliance.cattle.io.clusterscanprofile.vue} +5 -5
  219. package/edit/configmap.vue +8 -2
  220. package/edit/constraints.gatekeeper.sh.constraint/index.vue +1 -0
  221. package/edit/fleet.cattle.io.gitrepo.vue +44 -222
  222. package/edit/fleet.cattle.io.helmop.vue +44 -269
  223. package/edit/helm.cattle.io.projecthelmchart.vue +1 -0
  224. package/edit/k8s.cni.cncf.io.networkattachmentdefinition.vue +1 -0
  225. package/edit/logging-flow/index.vue +1 -0
  226. package/edit/logging.banzaicloud.io.output/index.vue +1 -0
  227. package/edit/management.cattle.io.fleetworkspace.vue +1 -0
  228. package/edit/management.cattle.io.oidcclient.vue +162 -0
  229. package/edit/management.cattle.io.project.vue +4 -1
  230. package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +1 -1
  231. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +5 -0
  232. package/edit/monitoring.coreos.com.prometheusrule/index.vue +1 -0
  233. package/edit/monitoring.coreos.com.receiver/auth.vue +30 -30
  234. package/edit/monitoring.coreos.com.receiver/index.vue +1 -0
  235. package/edit/monitoring.coreos.com.receiver/types/email.vue +1 -1
  236. package/edit/monitoring.coreos.com.route.vue +1 -0
  237. package/edit/namespace.vue +1 -0
  238. package/edit/networking.istio.io.destinationrule/index.vue +4 -1
  239. package/edit/networking.k8s.io.ingress/Certificate.vue +12 -12
  240. package/edit/networking.k8s.io.ingress/__tests__/Certificate.test.ts +165 -0
  241. package/edit/networking.k8s.io.ingress/index.vue +4 -1
  242. package/edit/networking.k8s.io.networkpolicy/PolicyRules.vue +7 -2
  243. package/edit/networking.k8s.io.networkpolicy/index.vue +6 -2
  244. package/edit/node.vue +1 -0
  245. package/edit/persistentvolume/index.vue +4 -1
  246. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +3 -2
  247. package/edit/provisioning.cattle.io.cluster/rke2.vue +516 -426
  248. package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +48 -39
  249. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +5 -0
  250. package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +2 -2
  251. package/edit/resources.cattle.io.restore.vue +1 -1
  252. package/edit/secret/basic.vue +1 -0
  253. package/edit/secret/index.vue +127 -15
  254. package/edit/service.vue +4 -1
  255. package/edit/serviceaccount.vue +4 -1
  256. package/edit/storage.k8s.io.storageclass/index.vue +4 -1
  257. package/edit/workload/index.vue +5 -0
  258. package/list/{cis.cattle.io.clusterscan.vue → compliance.cattle.io.clusterscan.vue} +2 -2
  259. package/list/management.cattle.io.oidcclient.vue +108 -0
  260. package/list/node.vue +2 -0
  261. package/list/projectsecret.vue +345 -0
  262. package/list/secret.vue +109 -0
  263. package/machine-config/amazonec2.vue +3 -24
  264. package/machine-config/components/GCEImage.vue +374 -0
  265. package/machine-config/google.vue +617 -0
  266. package/mixins/__tests__/brand.spec.ts +170 -0
  267. package/mixins/brand.js +16 -17
  268. package/mixins/create-edit-view/impl.js +10 -1
  269. package/mixins/create-edit-view/index.js +5 -0
  270. package/mixins/resource-fetch-api-pagination.js +24 -8
  271. package/mixins/resource-fetch.js +3 -1
  272. package/mixins/vue-select-overrides.js +1 -0
  273. package/models/cluster.x-k8s.io.machinedeployment.js +11 -2
  274. package/models/{cis.cattle.io.clusterscan.js → compliance.cattle.io.clusterscan.js} +8 -8
  275. package/models/{cis.cattle.io.clusterscanbenchmark.js → compliance.cattle.io.clusterscanbenchmark.js} +1 -1
  276. package/models/{cis.cattle.io.clusterscanprofile.js → compliance.cattle.io.clusterscanprofile.js} +5 -5
  277. package/models/{cis.cattle.io.clusterscanreport.js → compliance.cattle.io.clusterscanreport.js} +1 -1
  278. package/models/fleet-application.js +8 -79
  279. package/models/fleet.cattle.io.cluster.js +13 -2
  280. package/models/fleet.cattle.io.gitrepo.js +2 -2
  281. package/models/fleet.cattle.io.helmop.js +9 -39
  282. package/models/management.cattle.io.fleetworkspace.js +2 -1
  283. package/models/management.cattle.io.oidcclient.js +18 -0
  284. package/models/management.cattle.io.registration.js +3 -0
  285. package/models/provisioning.cattle.io.cluster.js +29 -33
  286. package/models/secret.js +157 -2
  287. package/models/service.js +4 -0
  288. package/models/workload.js +5 -0
  289. package/package.json +2 -2
  290. package/pages/about.vue +4 -58
  291. package/pages/auth/login.vue +1 -1
  292. package/pages/c/_cluster/apps/charts/AddRepoLink.vue +0 -1
  293. package/pages/c/_cluster/apps/charts/index.vue +296 -81
  294. package/pages/c/_cluster/auth/user.retention/index.vue +87 -78
  295. package/pages/c/_cluster/explorer/index.vue +3 -3
  296. package/pages/c/_cluster/explorer/projectsecret.vue +34 -0
  297. package/pages/c/_cluster/explorer/tools/pages/_page.vue +0 -1
  298. package/pages/c/_cluster/fleet/application/create.vue +3 -2
  299. package/pages/c/_cluster/fleet/index.vue +94 -57
  300. package/pages/c/_cluster/fleet/settings/index.vue +229 -0
  301. package/pages/c/_cluster/longhorn/index.vue +5 -2
  302. package/pages/c/_cluster/uiplugins/CatalogList/index.vue +16 -1
  303. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +2 -2
  304. package/pages/explorer/resource/detail/configmap.vue +30 -7
  305. package/pages/explorer/resource/detail/projectsecret.vue +9 -0
  306. package/pages/explorer/resource/detail/secret.vue +63 -0
  307. package/pages/home.vue +9 -55
  308. package/pages/support/index.vue +4 -6
  309. package/plugins/dashboard-store/__tests__/normalize.test.ts +223 -0
  310. package/plugins/dashboard-store/__tests__/resource-class.test.ts +191 -0
  311. package/plugins/dashboard-store/__tests__/utils/normalize-usecases.ts +1526 -0
  312. package/plugins/dashboard-store/actions.js +19 -5
  313. package/plugins/dashboard-store/getters.js +4 -0
  314. package/plugins/dashboard-store/normalize.js +29 -17
  315. package/plugins/dashboard-store/resource-class.js +68 -19
  316. package/plugins/steve/steve-pagination-utils.ts +38 -19
  317. package/plugins/steve/subscribe.js +6 -1
  318. package/rancher-components/Banner/Banner.vue +13 -0
  319. package/rancher-components/Form/Checkbox/Checkbox.vue +9 -4
  320. package/rancher-components/Form/LabeledInput/LabeledInput.vue +1 -1
  321. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +1 -0
  322. package/rancher-components/RcItemCard/RcItemCard.vue +8 -3
  323. package/store/auth.js +2 -0
  324. package/store/catalog.js +23 -1
  325. package/store/growl.js +97 -8
  326. package/store/index.js +6 -0
  327. package/store/notifications.ts +426 -0
  328. package/store/prefs.js +0 -1
  329. package/store/type-map.js +19 -16
  330. package/store/uiplugins.ts +15 -1
  331. package/types/fleet.d.ts +24 -0
  332. package/types/kube/kube-api.ts +12 -0
  333. package/types/notifications/index.ts +74 -0
  334. package/types/shell/index.d.ts +661 -589
  335. package/types/store/dashboard-store.types.ts +16 -0
  336. package/types/store/pagination.types.ts +16 -6
  337. package/utils/__tests__/create-yaml.test.ts +235 -0
  338. package/utils/__tests__/fleet.test.ts +148 -0
  339. package/utils/__tests__/object.test.ts +54 -1
  340. package/utils/__tests__/string.test.ts +273 -1
  341. package/utils/__tests__/time.test.ts +31 -0
  342. package/utils/auth.js +9 -2
  343. package/utils/create-yaml.js +103 -9
  344. package/utils/crypto/encryption.ts +103 -0
  345. package/utils/cspAdaptor.ts +51 -0
  346. package/utils/fleet.ts +54 -65
  347. package/utils/object.js +36 -0
  348. package/utils/pagination-utils.ts +19 -1
  349. package/utils/release-notes.ts +48 -0
  350. package/utils/selector-typed.ts +7 -2
  351. package/utils/string.js +24 -0
  352. package/utils/{time.js → time.ts} +25 -6
  353. package/utils/uiplugins.ts +22 -0
  354. package/utils/validators/formRules/index.ts +3 -0
  355. package/components/Resource/Detail/TitleBar/composable.ts +0 -31
  356. package/config/product/legacy.js +0 -62
  357. package/models/etcdbackup.js +0 -45
  358. package/pages/c/_cluster/legacy/pages/_page.vue +0 -29
  359. package/pages/c/_cluster/legacy/project/_page.vue +0 -57
  360. package/pages/c/_cluster/legacy/project/index.vue +0 -32
  361. package/pages/c/_cluster/legacy/project/pipelines.vue +0 -96
@@ -6,6 +6,8 @@ import merge from 'lodash/merge';
6
6
  import CreateEditView from '@shell/mixins/create-edit-view';
7
7
  import FormValidation from '@shell/mixins/form-validation';
8
8
  import { normalizeName } from '@shell/utils/kube';
9
+ import AccountAccess from '@shell/components/google/AccountAccess.vue';
10
+ import { handleConflict } from '@shell/plugins/dashboard-store/normalize';
9
11
 
10
12
  import {
11
13
  CAPI,
@@ -66,6 +68,7 @@ import AddOnAdditionalManifest from '@shell/edit/provisioning.cattle.io.cluster/
66
68
  import VsphereUtils, { VMWARE_VSPHERE } from '@shell/utils/v-sphere';
67
69
  import { mapGetters } from 'vuex';
68
70
  const HARVESTER = 'harvester';
71
+ const GOOGLE = 'google';
69
72
  const HARVESTER_CLOUD_PROVIDER = 'harvester-cloud-provider';
70
73
  const NETBIOS_TRUNCATION_LENGTH = 15;
71
74
 
@@ -118,7 +121,8 @@ export default {
118
121
  AddOnConfig,
119
122
  Advanced,
120
123
  ClusterAppearance,
121
- AddOnAdditionalManifest
124
+ AddOnAdditionalManifest,
125
+ AccountAccess
122
126
  },
123
127
 
124
128
  mixins: [CreateEditView, FormValidation],
@@ -223,6 +227,7 @@ export default {
223
227
  allPSAs: [],
224
228
  credentialId: '',
225
229
  credential: null,
230
+ initialMachinePoolsValues: {},
226
231
  machinePools: null,
227
232
  rke2Versions: null,
228
233
  k3sVersions: null,
@@ -251,7 +256,7 @@ export default {
251
256
  path: 'metadata.name', rules: ['subDomain'], translationKey: 'nameNsDescription.name.label'
252
257
  }],
253
258
  harvesterVersionRange: {},
254
- cisOverride: false,
259
+ complianceOverride: false,
255
260
  truncateLimit,
256
261
  busy: false,
257
262
  machinePoolValidation: {}, // map of validation states for each machine pool
@@ -265,6 +270,8 @@ export default {
265
270
  clusterAgentDefaultPC: null,
266
271
  clusterAgentDefaultPDB: null,
267
272
  activeTab: null,
273
+ isAuthenticated: this.provider !== GOOGLE || this.mode === _EDIT,
274
+ projectId: null,
268
275
  REGISTRIES_TAB_NAME,
269
276
  labelForAddon
270
277
 
@@ -851,6 +858,9 @@ export default {
851
858
  set(newValue) {
852
859
  this.$emit('update:value', newValue);
853
860
  }
861
+ },
862
+ hideFooter() {
863
+ return this.needCredential && !this.credential;
854
864
  }
855
865
  },
856
866
 
@@ -941,6 +951,7 @@ export default {
941
951
  this.registerBeforeHook(this.setRegistryConfig, 'set-registry-config');
942
952
  this.registerBeforeHook(this.handleVsphereCpiSecret, 'sync-vsphere-cpi');
943
953
  this.registerBeforeHook(this.handleVsphereCsiSecret, 'sync-vsphere-csi');
954
+ this.registerBeforeHook(this.setHarvesterChartValues, 'set-harvester-chart-values');
944
955
  this.registerAfterHook(this.cleanupMachinePools, 'cleanup-machine-pools');
945
956
  this.registerAfterHook(this.saveRoleBindings, 'save-role-bindings');
946
957
 
@@ -1209,7 +1220,7 @@ export default {
1209
1220
  // @TODO what if the pool is missing?
1210
1221
  const id = `pool${ ++this.lastIdx }`;
1211
1222
 
1212
- out.push({
1223
+ const poolData = {
1213
1224
  id,
1214
1225
  remove: false,
1215
1226
  create: false,
@@ -1217,7 +1228,15 @@ export default {
1217
1228
  pool: clone(pool),
1218
1229
  config: config ? await this.$store.dispatch('management/clone', { resource: config }) : null,
1219
1230
  configMissing
1220
- });
1231
+ };
1232
+
1233
+ // add data to machine pools array
1234
+ out.push(poolData);
1235
+
1236
+ // but we also store the initial data so that we can handle conflicts
1237
+ if (poolData?.config?.id) {
1238
+ this.initialMachinePoolsValues[poolData.config.id] = structuredClone(poolData.config);
1239
+ }
1221
1240
  }
1222
1241
  }
1223
1242
 
@@ -1312,17 +1331,25 @@ export default {
1312
1331
  const _latestConfig = await this.$store.dispatch('management/request', { url: `/v1/${ machinePool.config.type }s/${ machinePool.config.id }` });
1313
1332
  const latestConfig = await this.$store.dispatch('management/create', _latestConfig);
1314
1333
 
1315
- const clonedCurrentConfig = await this.$store.dispatch('management/clone', { resource: machinePool.config });
1316
- const clonedLatestConfig = await this.$store.dispatch('management/clone', { resource: latestConfig });
1317
-
1318
- // We don't allow the user to edit any of the fields in metadata from the UI so it's safe to override it with the
1319
- // metadata defined by the latest backend value. This is primarily used to ensure the resourceVersion is up to date.
1320
- delete clonedCurrentConfig.metadata;
1334
+ const _initialMachinePoolValue = this.initialMachinePoolsValues[machinePool?.config?.id] || {};
1335
+ const initialMachinePoolValue = await this.$store.dispatch('management/create', _initialMachinePoolValue);
1336
+
1337
+ // if there's the initial machine pool config, we are in a good position to apply the handleConflict function
1338
+ // to deal with out-of-sync data between machinePools configs. This also mutates the data inside machinePool.config through object reference
1339
+ const conflict = await handleConflict(
1340
+ initialMachinePoolValue,
1341
+ machinePool.config,
1342
+ latestConfig,
1343
+ {
1344
+ dispatch: this.$store.dispatch,
1345
+ getters: this.$store.getters
1346
+ },
1347
+ 'management'
1348
+ );
1321
1349
 
1322
- if (this.provider === VMWARE_VSPHERE) {
1323
- machinePool.config = mergeWithReplace(clonedLatestConfig, clonedCurrentConfig, { mutateOriginal: true });
1324
- } else {
1325
- machinePool.config = merge(clonedLatestConfig, clonedCurrentConfig);
1350
+ // if there's conflicts, throw Error stops save process and surfaces error to user
1351
+ if (conflict) {
1352
+ throw Error(conflict);
1326
1353
  }
1327
1354
  }
1328
1355
  },
@@ -1370,12 +1397,31 @@ export default {
1370
1397
 
1371
1398
  // Capitals and such aren't allowed;
1372
1399
  entry.pool.name = normalizeName(entry.pool.name) || 'pool';
1400
+ const prefix = `${ this.value.metadata.name }-${ entry.pool.name }`;
1401
+
1402
+ const prefixFormatted = prefix.substr(0, 50).toLowerCase();
1373
1403
 
1374
- const prefix = `${ this.value.metadata.name }-${ entry.pool.name }`.substr(0, 50).toLowerCase();
1404
+ // For Google, we need to set internal and external firewall prefixes if enabled,
1405
+ // but it is better to track it here since cluster and pool names are guaranteed to be set by now.
1406
+ if (this.provider === GOOGLE) {
1407
+ if (!!entry.config.setInternalFirewallRulePrefix) {
1408
+ entry.config.internalFirewallRulePrefix = `${ this.value.metadata.name }`;
1409
+ } else if (!!entry.config.internalFirewallRulePrefix) {
1410
+ delete entry.config.internalFirewallRulePrefix;
1411
+ }
1412
+ if (!!entry.config.setExternalFirewallRulePrefix) {
1413
+ entry.config.externalFirewallRulePrefix = prefix;
1414
+ } else if (!!entry.config.externalFirewallRulePrefix) {
1415
+ delete entry.config.externalFirewallRulePrefix;
1416
+ }
1417
+ // These have to be removed regardless of their value because they are not part of the object we are sending
1418
+ delete entry.config.setInternalFirewallRulePrefix;
1419
+ delete entry.config.setExternalFirewallRulePrefix;
1420
+ }
1375
1421
 
1376
1422
  if (entry.create) {
1377
1423
  if (!entry.config.metadata?.name) {
1378
- entry.config.metadata.generateName = `nc-${ prefix }-`;
1424
+ entry.config.metadata.generateName = `nc-${ prefixFormatted }-`;
1379
1425
  }
1380
1426
 
1381
1427
  const neu = await entry.config.save();
@@ -1390,7 +1436,7 @@ export default {
1390
1436
 
1391
1437
  // Ensure Elemental clusters have a hostname prefix
1392
1438
  if (this.isElementalCluster && !entry.pool.hostnamePrefix) {
1393
- entry.pool.hostnamePrefix = `${ prefix }-`;
1439
+ entry.pool.hostnamePrefix = `${ prefixFormatted }-`;
1394
1440
  }
1395
1441
 
1396
1442
  finalPools.push(entry.pool);
@@ -1512,41 +1558,7 @@ export default {
1512
1558
  }
1513
1559
 
1514
1560
  try {
1515
- const clusterId = get(this.credential, 'decodedData.clusterId') || '';
1516
-
1517
1561
  this.applyChartValues(this.value.spec.rkeConfig);
1518
-
1519
- const isUpgrade = this.isEdit && this.liveValue?.spec?.kubernetesVersion !== this.value?.spec?.kubernetesVersion;
1520
-
1521
- if (this.agentConfig?.['cloud-provider-name'] === HARVESTER && clusterId && (this.isCreate || isUpgrade)) {
1522
- const namespace = this.machinePools?.[0]?.config?.vmNamespace;
1523
-
1524
- const res = await this.$store.dispatch('management/request', {
1525
- url: `/k8s/clusters/${ clusterId }/v1/harvester/kubeconfig`,
1526
- method: 'POST',
1527
- data: {
1528
- csiClusterRoleName: 'harvesterhci.io:csi-driver',
1529
- clusterRoleName: 'harvesterhci.io:cloudprovider',
1530
- namespace,
1531
- serviceAccountName: this.value.metadata.name,
1532
- },
1533
- });
1534
-
1535
- const kubeconfig = res.data;
1536
-
1537
- const harvesterKubeconfigSecret = await this.createKubeconfigSecret(kubeconfig);
1538
-
1539
- this.agentConfig['cloud-provider-config'] = `secret://fleet-default:${ harvesterKubeconfigSecret?.metadata?.name }`;
1540
-
1541
- if (this.isCreate) {
1542
- set(this.chartValues, `${ HARVESTER_CLOUD_PROVIDER }.global.cattle.clusterName`, this.value.metadata.name);
1543
- }
1544
-
1545
- const distroSubdir = this.value?.spec?.kubernetesVersion?.includes('k3s') ? DEFAULT_SUBDIRS.K8S_DISTRO_K3S : DEFAULT_SUBDIRS.K8S_DISTRO_RKE2;
1546
- const distroRoot = this.value?.spec?.rkeConfig?.dataDirectories?.k8sDistro?.length ? this.value?.spec?.rkeConfig?.dataDirectories?.k8sDistro : `${ DEFAULT_COMMON_BASE_PATH }/${ distroSubdir }`;
1547
-
1548
- set(this.chartValues, `${ HARVESTER_CLOUD_PROVIDER }.cloudConfigPath`, `${ distroRoot }/etc/config-files/cloud-provider-config`);
1549
- }
1550
1562
  } catch (err) {
1551
1563
  this.errors.push(err);
1552
1564
 
@@ -1593,6 +1605,62 @@ export default {
1593
1605
  }
1594
1606
  },
1595
1607
 
1608
+ async setHarvesterChartValues() {
1609
+ const isHarvester = this.agentConfig?.['cloud-provider-name'] === HARVESTER;
1610
+
1611
+ if (!isHarvester) {
1612
+ return;
1613
+ }
1614
+ try {
1615
+ const clusterId = get(this.credential, 'decodedData.clusterId') || '';
1616
+ const isUpgrade = this.isEdit && this.liveValue?.spec?.kubernetesVersion !== this.value?.spec?.kubernetesVersion;
1617
+
1618
+ if (!this.value?.metadata?.name) {
1619
+ const err = this.t('cluster.harvester.kubeconfigSecret.nameRequired');
1620
+
1621
+ throw new Error(err);
1622
+ }
1623
+
1624
+ if (clusterId && (this.isCreate || isUpgrade)) {
1625
+ const namespace = this.machinePools?.[0]?.config?.vmNamespace;
1626
+
1627
+ const res = await this.$store.dispatch('management/request', {
1628
+ url: `/k8s/clusters/${ clusterId }/v1/harvester/kubeconfig`,
1629
+ method: 'POST',
1630
+ data: {
1631
+ csiClusterRoleName: 'harvesterhci.io:csi-driver',
1632
+ clusterRoleName: 'harvesterhci.io:cloudprovider',
1633
+ namespace,
1634
+ serviceAccountName: this.value.metadata.name,
1635
+ },
1636
+ });
1637
+
1638
+ const kubeconfig = res.data;
1639
+
1640
+ const harvesterKubeconfigSecret = await this.createKubeconfigSecret(kubeconfig);
1641
+
1642
+ this.agentConfig['cloud-provider-config'] = `secret://fleet-default:${ harvesterKubeconfigSecret?.metadata?.name }`;
1643
+
1644
+ const harvesterCloudProviderKey = this.chartVersionKey(HARVESTER_CLOUD_PROVIDER);
1645
+
1646
+ if (this.isCreate) {
1647
+ set(this.userChartValues, `'${ harvesterCloudProviderKey }'.global.cattle.clusterName`, this.value.metadata.name);
1648
+ }
1649
+
1650
+ const distroSubdir = this.value?.spec?.kubernetesVersion?.includes('k3s') ? DEFAULT_SUBDIRS.K8S_DISTRO_K3S : DEFAULT_SUBDIRS.K8S_DISTRO_RKE2;
1651
+ const distroRoot = this.value?.spec?.rkeConfig?.dataDirectories?.k8sDistro?.length ? this.value?.spec?.rkeConfig?.dataDirectories?.k8sDistro : `${ DEFAULT_COMMON_BASE_PATH }/${ distroSubdir }`;
1652
+
1653
+ set(this.userChartValues, `'${ harvesterCloudProviderKey }'.cloudConfigPath`, `${ distroRoot }/etc/config-files/cloud-provider-config`);
1654
+ }
1655
+ } catch (e) {
1656
+ const cause = e.errors ? e.errors.join('; ') : e?.message;
1657
+ const msg = this.t('cluster.harvester.kubeconfigSecret.error', { err: cause });
1658
+
1659
+ this.errors.push(msg);
1660
+ throw new Error(msg);
1661
+ }
1662
+ },
1663
+
1596
1664
  // create a secret to reference the harvester cluster kubeconfig in rkeConfig
1597
1665
  async createKubeconfigSecret(kubeconfig = '') {
1598
1666
  const clusterName = this.value.metadata.name;
@@ -1869,6 +1937,7 @@ export default {
1869
1937
 
1870
1938
  charts.forEach((name) => {
1871
1939
  const key = this.chartVersionKey(name);
1940
+
1872
1941
  const userValues = this.userChartValues[key];
1873
1942
 
1874
1943
  if (userValues) {
@@ -1926,27 +1995,27 @@ export default {
1926
1995
  togglePsaDefault() {
1927
1996
  // This option is created from the server and is guaranteed to exist #8032
1928
1997
  const hardcodedTemplate = 'rancher-restricted';
1929
- const cisValue = this.agentConfig?.profile || this.serverConfig?.profile;
1998
+ const complianceValue = this.agentConfig?.profile || this.serverConfig?.profile;
1930
1999
 
1931
- if (!this.cisOverride) {
1932
- if (cisValue) {
2000
+ if (!this.complianceOverride) {
2001
+ if (complianceValue) {
1933
2002
  this.value.spec.defaultPodSecurityAdmissionConfigurationTemplateName = hardcodedTemplate;
1934
2003
  }
1935
2004
  }
1936
2005
  },
1937
2006
 
1938
- handleCisChange() {
2007
+ handleComplianceChange() {
1939
2008
  this.togglePsaDefault();
1940
- this.updateCisProfile();
2009
+ this.updateComplianceProfile();
1941
2010
  },
1942
2011
 
1943
- updateCisProfile() {
1944
- // If the user selects any Worker CIS Profile,
2012
+ updateComplianceProfile() {
2013
+ // If the user selects any Worker Compliance Profile,
1945
2014
  // protect-kernel-defaults should be set to false
1946
2015
  // in the RKE2 worker/agent config.
1947
- const selectedCisProfile = this.agentConfig?.profile;
2016
+ const selectedComplianceProfile = this.agentConfig?.profile;
1948
2017
 
1949
- if (selectedCisProfile) {
2018
+ if (selectedComplianceProfile) {
1950
2019
  this.agentConfig['protect-kernel-defaults'] = true;
1951
2020
  } else {
1952
2021
  this.agentConfig['protect-kernel-defaults'] = false;
@@ -2000,12 +2069,12 @@ export default {
2000
2069
  };
2001
2070
  },
2002
2071
 
2003
- handleCisChanged() {
2004
- this.handleCisChange();
2072
+ handleComplianceChanged() {
2073
+ this.handleComplianceChange();
2005
2074
  },
2006
2075
 
2007
2076
  handlePsaDefaultChanged() {
2008
- this.cisOverride = !this.cisOverride;
2077
+ this.complianceOverride = !this.complianceOverride;
2009
2078
  this.togglePsaDefault();
2010
2079
  },
2011
2080
 
@@ -2141,398 +2210,413 @@ export default {
2141
2210
  <span v-clean-html="t('cluster.banner.rke2-k3-reprovisioning', {}, true)" />
2142
2211
  </Banner>
2143
2212
  </div>
2144
- <SelectCredential
2145
- v-if="needCredential"
2146
- v-model:value="credentialId"
2213
+ <AccountAccess
2214
+ v-if="!isAuthenticated"
2215
+ v-model:credential="credential"
2216
+ v-model:project="projectId"
2217
+ v-model:is-authenticated="isAuthenticated"
2147
2218
  :mode="mode"
2148
- :provider="provider"
2149
- :cancel="cancelCredential"
2150
- :showing-form="showForm"
2151
- :default-on-cancel="true"
2152
- data-testid="select-credential"
2153
- class="mt-20"
2219
+ @error="e=>errors.push(e)"
2220
+ @cancel-credential="cancelCredential"
2154
2221
  />
2155
-
2156
2222
  <div
2157
- v-if="showForm"
2158
- data-testid="form"
2159
- class="mt-20"
2223
+ v-else
2224
+ class="authenticated"
2160
2225
  >
2161
- <NameNsDescription
2162
- v-if="!isView"
2163
- v-model:value="localValue"
2226
+ <SelectCredential
2227
+ v-if="needCredential"
2228
+ v-model:value="credentialId"
2164
2229
  :mode="mode"
2165
- :namespaced="needsNamespace"
2166
- :namespace-options="allNamespaces"
2167
- name-label="cluster.name.label"
2168
- name-placeholder="cluster.name.placeholder"
2169
- description-label="cluster.description.label"
2170
- description-placeholder="cluster.description.placeholder"
2171
- :rules="{ name: fvGetAndReportPathRules('metadata.name') }"
2172
- @update:value="$emit('input', $event)"
2230
+ :provider="provider"
2231
+ :cancel="cancelCredential"
2232
+ :showing-form="showForm"
2233
+ :default-on-cancel="true"
2234
+ data-testid="select-credential"
2235
+ class="mt-20"
2236
+ />
2237
+
2238
+ <div
2239
+ v-if="showForm"
2240
+ data-testid="form"
2241
+ class="mt-20"
2173
2242
  >
2174
- <template #customize>
2175
- <ClusterAppearance
2176
- :name="clusterName"
2177
- :currentCluster="currentCluster"
2178
- :mode="mode"
2179
- />
2180
- </template>
2181
- </NameNsDescription>
2182
-
2183
- <Banner
2184
- v-if="appsOSWarning"
2185
- color="error"
2186
- >
2187
- {{ appsOSWarning }}
2188
- </Banner>
2189
-
2190
- <!-- Pools Extras -->
2191
- <template v-if="hasMachinePools">
2192
- <div class="clearfix">
2193
- <h2
2194
- v-t="'cluster.tabs.machinePools'"
2195
- class="pull-left"
2196
- />
2197
- <div
2198
- v-if="!isView"
2199
- class="pull-right"
2200
- >
2201
- <BadgeState
2202
- v-clean-tooltip="nodeTotals.tooltip.etcd"
2203
- :color="nodeTotals.color.etcd"
2204
- :icon="nodeTotals.icon.etcd"
2205
- :label="nodeTotals.label.etcd"
2206
- class="mr-10"
2207
- />
2208
- <BadgeState
2209
- v-clean-tooltip="nodeTotals.tooltip.controlPlane"
2210
- :color="nodeTotals.color.controlPlane"
2211
- :icon="nodeTotals.icon.controlPlane"
2212
- :label="nodeTotals.label.controlPlane"
2213
- class="mr-10"
2243
+ <NameNsDescription
2244
+ v-if="!isView"
2245
+ v-model:value="localValue"
2246
+ :mode="mode"
2247
+ :namespaced="needsNamespace"
2248
+ :namespace-options="allNamespaces"
2249
+ name-label="cluster.name.label"
2250
+ name-placeholder="cluster.name.placeholder"
2251
+ description-label="cluster.description.label"
2252
+ description-placeholder="cluster.description.placeholder"
2253
+ :rules="{ name: fvGetAndReportPathRules('metadata.name') }"
2254
+ @update:value="$emit('input', $event)"
2255
+ >
2256
+ <template #customize>
2257
+ <ClusterAppearance
2258
+ :name="clusterName"
2259
+ :currentCluster="currentCluster"
2260
+ :mode="mode"
2214
2261
  />
2215
- <BadgeState
2216
- v-clean-tooltip="nodeTotals.tooltip.worker"
2217
- :color="nodeTotals.color.worker"
2218
- :icon="nodeTotals.icon.worker"
2219
- :label="nodeTotals.label.worker"
2262
+ </template>
2263
+ </NameNsDescription>
2264
+
2265
+ <Banner
2266
+ v-if="appsOSWarning"
2267
+ color="error"
2268
+ >
2269
+ {{ appsOSWarning }}
2270
+ </Banner>
2271
+
2272
+ <!-- Pools Extras -->
2273
+ <template v-if="hasMachinePools">
2274
+ <div class="clearfix">
2275
+ <h2
2276
+ v-t="'cluster.tabs.machinePools'"
2277
+ class="pull-left"
2220
2278
  />
2279
+ <div
2280
+ v-if="!isView"
2281
+ class="pull-right"
2282
+ >
2283
+ <BadgeState
2284
+ v-clean-tooltip="nodeTotals.tooltip.etcd"
2285
+ :color="nodeTotals.color.etcd"
2286
+ :icon="nodeTotals.icon.etcd"
2287
+ :label="nodeTotals.label.etcd"
2288
+ class="mr-10"
2289
+ />
2290
+ <BadgeState
2291
+ v-clean-tooltip="nodeTotals.tooltip.controlPlane"
2292
+ :color="nodeTotals.color.controlPlane"
2293
+ :icon="nodeTotals.icon.controlPlane"
2294
+ :label="nodeTotals.label.controlPlane"
2295
+ class="mr-10"
2296
+ />
2297
+ <BadgeState
2298
+ v-clean-tooltip="nodeTotals.tooltip.worker"
2299
+ :color="nodeTotals.color.worker"
2300
+ :icon="nodeTotals.icon.worker"
2301
+ :label="nodeTotals.label.worker"
2302
+ />
2303
+ </div>
2221
2304
  </div>
2222
- </div>
2223
2305
 
2224
- <!-- Extra Tabs for Machine Pool -->
2306
+ <!-- Extra Tabs for Machine Pool -->
2307
+ <Tabbed
2308
+ ref="pools"
2309
+ :side-tabs="true"
2310
+ :show-tabs-add-remove="!isView"
2311
+ @addTab="addMachinePool($event)"
2312
+ @removeTab="removeMachinePool($event)"
2313
+ >
2314
+ <template
2315
+ v-for="(obj, idx) in machinePools"
2316
+ :key="idx"
2317
+ >
2318
+ <Tab
2319
+ v-if="!obj.remove"
2320
+ :key="obj.id"
2321
+ :name="obj.id"
2322
+ :label="obj.pool.name || '(Not Named)'"
2323
+ :show-header="false"
2324
+ :error="!machinePoolValidation[obj.id]"
2325
+ >
2326
+ <MachinePool
2327
+ ref="pool"
2328
+ :value="obj"
2329
+ :cluster="value"
2330
+ :mode="mode"
2331
+ :provider="provider"
2332
+ :credential-id="credentialId"
2333
+ :project-id="projectId"
2334
+ :idx="idx"
2335
+ :machine-pools="machinePools"
2336
+ :busy="busy"
2337
+ :pool-id="obj.id"
2338
+ :pool-create-mode="obj.create"
2339
+ @error="handleMachinePoolError"
2340
+ @validationChanged="v => machinePoolValidationChanged(obj.id, v)"
2341
+ />
2342
+ </Tab>
2343
+ </template>
2344
+ <div v-if="!unremovedMachinePools.length">
2345
+ {{ t('cluster.machinePool.noPoolsDisclaimer') }}
2346
+ </div>
2347
+ </Tabbed>
2348
+ <div class="spacer" />
2349
+ </template>
2350
+
2351
+ <!-- Cluster Tabs -->
2352
+ <h2 v-t="'cluster.tabs.cluster'" />
2225
2353
  <Tabbed
2226
- ref="pools"
2227
2354
  :side-tabs="true"
2228
- :show-tabs-add-remove="!isView"
2229
- @addTab="addMachinePool($event)"
2230
- @removeTab="removeMachinePool($event)"
2355
+ class="min-height"
2356
+ :use-hash="useTabbedHash"
2357
+ @changed="handleTabChange"
2231
2358
  >
2232
- <template
2233
- v-for="(obj, idx) in machinePools"
2234
- :key="idx"
2359
+ <Tab
2360
+ name="basic"
2361
+ label-key="cluster.tabs.basic"
2362
+ :weight="11"
2363
+ @active="refreshComponentWithYamls('tab-Basics')"
2235
2364
  >
2236
- <Tab
2237
- v-if="!obj.remove"
2238
- :key="obj.id"
2239
- :name="obj.id"
2240
- :label="obj.pool.name || '(Not Named)'"
2241
- :show-header="false"
2242
- :error="!machinePoolValidation[obj.id]"
2243
- >
2244
- <MachinePool
2245
- ref="pool"
2246
- :value="obj"
2247
- :cluster="value"
2248
- :mode="mode"
2249
- :provider="provider"
2250
- :credential-id="credentialId"
2251
- :idx="idx"
2252
- :machine-pools="machinePools"
2253
- :busy="busy"
2254
- :pool-id="obj.id"
2255
- :pool-create-mode="obj.create"
2256
- @error="handleMachinePoolError"
2257
- @validationChanged="v => machinePoolValidationChanged(obj.id, v)"
2258
- />
2259
- </Tab>
2260
- </template>
2261
- <div v-if="!unremovedMachinePools.length">
2262
- {{ t('cluster.machinePool.noPoolsDisclaimer') }}
2263
- </div>
2264
- </Tabbed>
2265
- <div class="spacer" />
2266
- </template>
2267
-
2268
- <!-- Cluster Tabs -->
2269
- <h2 v-t="'cluster.tabs.cluster'" />
2270
- <Tabbed
2271
- :side-tabs="true"
2272
- class="min-height"
2273
- @changed="handleTabChange"
2274
- >
2275
- <Tab
2276
- name="basic"
2277
- label-key="cluster.tabs.basic"
2278
- :weight="11"
2279
- @active="refreshComponentWithYamls('tab-Basics')"
2280
- >
2281
- <!-- Basic -->
2282
- <Basics
2283
- ref="tab-Basics"
2284
- v-model:value="localValue"
2285
- :live-value="liveValue"
2286
- :mode="mode"
2287
- :provider="provider"
2288
- :user-chart-values="userChartValues"
2289
- :credential="credential"
2290
- :cis-override="cisOverride"
2291
- :all-psas="allPSAs"
2292
- :addon-versions="addonVersions"
2293
- :show-deprecated-patch-versions="showDeprecatedPatchVersions"
2294
- :selected-version="selectedVersion"
2295
- :is-harvester-driver="isHarvesterDriver"
2296
- :is-harvester-incompatible="isHarvesterIncompatible"
2297
- :version-options="versionOptions"
2298
- :is-elemental-cluster="isElementalCluster"
2299
- :have-arg-info="haveArgInfo"
2300
- :show-cni="showCni"
2301
- :show-cloud-provider="showCloudProvider"
2302
- :cloud-provider-options="cloudProviderOptions"
2303
- :is-azure-provider-unsupported="isAzureProviderUnsupported"
2304
- :can-azure-migrate-on-edit="canAzureMigrateOnEdit"
2305
- @update:value="$emit('input', $event)"
2306
- @cilium-values-changed="handleCiliumValuesChanged"
2307
- @enabled-system-services-changed="handleEnabledSystemServicesChanged"
2308
- @kubernetes-changed="handleKubernetesChange"
2309
- @cis-changed="handleCisChanged"
2310
- @psa-default-changed="handlePsaDefaultChanged"
2311
- @show-deprecated-patch-versions-changed="handleShowDeprecatedPatchVersionsChanged"
2312
- />
2313
- </Tab>
2314
-
2315
- <!-- Member Roles -->
2316
- <Tab
2317
- v-if="canManageMembers"
2318
- name="memberRoles"
2319
- label-key="cluster.tabs.memberRoles"
2320
- :weight="10"
2321
- >
2322
- <MemberRoles
2323
- v-model:value="localValue"
2324
- :mode="mode"
2325
- :on-membership-update="onMembershipUpdate"
2326
- @update:value="$emit('input', $event)"
2327
- />
2328
- </Tab>
2329
- <!-- etcd -->
2330
- <Tab
2331
- name="etcd"
2332
- label-key="cluster.tabs.etcd"
2333
- >
2334
- <Etcd
2335
- v-model:value="localValue"
2336
- :mode="mode"
2337
- :s3-backup="s3Backup"
2338
- :register-before-hook="registerBeforeHook"
2339
- :selected-version="selectedVersion"
2340
- @update:value="$emit('input', $event)"
2341
- @s3-backup-changed="handleS3BackupChanged"
2342
- @config-etcd-expose-metrics-changed="handleConfigEtcdExposeMetricsChanged"
2343
- />
2344
- </Tab>
2365
+ <!-- Basic -->
2366
+ <Basics
2367
+ ref="tab-Basics"
2368
+ v-model:value="localValue"
2369
+ :live-value="liveValue"
2370
+ :mode="mode"
2371
+ :provider="provider"
2372
+ :user-chart-values="userChartValues"
2373
+ :credential="credential"
2374
+ :compliance-override="complianceOverride"
2375
+ :all-psas="allPSAs"
2376
+ :addon-versions="addonVersions"
2377
+ :show-deprecated-patch-versions="showDeprecatedPatchVersions"
2378
+ :selected-version="selectedVersion"
2379
+ :is-harvester-driver="isHarvesterDriver"
2380
+ :is-harvester-incompatible="isHarvesterIncompatible"
2381
+ :version-options="versionOptions"
2382
+ :is-elemental-cluster="isElementalCluster"
2383
+ :have-arg-info="haveArgInfo"
2384
+ :show-cni="showCni"
2385
+ :show-cloud-provider="showCloudProvider"
2386
+ :cloud-provider-options="cloudProviderOptions"
2387
+ :is-azure-provider-unsupported="isAzureProviderUnsupported"
2388
+ :can-azure-migrate-on-edit="canAzureMigrateOnEdit"
2389
+ @update:value="$emit('input', $event)"
2390
+ @cilium-values-changed="handleCiliumValuesChanged"
2391
+ @enabled-system-services-changed="handleEnabledSystemServicesChanged"
2392
+ @kubernetes-changed="handleKubernetesChange"
2393
+ @compliance-changed="handleComplianceChanged"
2394
+ @psa-default-changed="handlePsaDefaultChanged"
2395
+ @show-deprecated-patch-versions-changed="handleShowDeprecatedPatchVersionsChanged"
2396
+ />
2397
+ </Tab>
2398
+
2399
+ <!-- Member Roles -->
2400
+ <Tab
2401
+ v-if="canManageMembers"
2402
+ name="memberRoles"
2403
+ label-key="cluster.tabs.memberRoles"
2404
+ :weight="10"
2405
+ >
2406
+ <MemberRoles
2407
+ v-model:value="localValue"
2408
+ :mode="mode"
2409
+ :on-membership-update="onMembershipUpdate"
2410
+ @update:value="$emit('input', $event)"
2411
+ />
2412
+ </Tab>
2413
+ <!-- etcd -->
2414
+ <Tab
2415
+ name="etcd"
2416
+ label-key="cluster.tabs.etcd"
2417
+ >
2418
+ <Etcd
2419
+ v-model:value="localValue"
2420
+ :mode="mode"
2421
+ :s3-backup="s3Backup"
2422
+ :register-before-hook="registerBeforeHook"
2423
+ :selected-version="selectedVersion"
2424
+ @update:value="$emit('input', $event)"
2425
+ @s3-backup-changed="handleS3BackupChanged"
2426
+ @config-etcd-expose-metrics-changed="handleConfigEtcdExposeMetricsChanged"
2427
+ />
2428
+ </Tab>
2345
2429
 
2346
- <!-- Networking -->
2347
- <Tab
2348
- v-if="haveArgInfo"
2349
- name="networking"
2350
- label-key="cluster.tabs.networking"
2351
- >
2352
- <Networking
2353
- v-model:value="localValue"
2354
- :mode="mode"
2355
- :selected-version="selectedVersion"
2356
- :truncate-limit="truncateLimit"
2357
- @truncate-hostname-changed="truncateHostname"
2358
- @cluster-cidr-changed="(val)=>localValue.spec.rkeConfig.machineGlobalConfig['cluster-cidr'] = val"
2359
- @service-cidr-changed="(val)=>localValue.spec.rkeConfig.machineGlobalConfig['service-cidr'] = val"
2360
- @cluster-domain-changed="(val)=>localValue.spec.rkeConfig.machineGlobalConfig['cluster-domain'] = val"
2361
- @cluster-dns-changed="(val)=>localValue.spec.rkeConfig.machineGlobalConfig['cluster-dns'] = val"
2362
- @service-node-port-range-changed="(val)=>localValue.spec.rkeConfig.machineGlobalConfig['service-node-port-range'] = val"
2363
- @tls-san-changed="(val)=>localValue.spec.rkeConfig.machineGlobalConfig['tls-san'] = val"
2364
- @local-cluster-auth-endpoint-changed="enableLocalClusterAuthEndpoint"
2365
- @ca-certs-changed="(val)=>localValue.spec.localClusterAuthEndpoint.caCerts = val"
2366
- @fqdn-changed="(val)=>localValue.spec.localClusterAuthEndpoint.fqdn = val"
2367
- />
2368
- </Tab>
2430
+ <!-- Networking -->
2431
+ <Tab
2432
+ v-if="haveArgInfo"
2433
+ name="networking"
2434
+ label-key="cluster.tabs.networking"
2435
+ >
2436
+ <Networking
2437
+ v-model:value="localValue"
2438
+ :mode="mode"
2439
+ :selected-version="selectedVersion"
2440
+ :truncate-limit="truncateLimit"
2441
+ @truncate-hostname-changed="truncateHostname"
2442
+ @cluster-cidr-changed="(val)=>localValue.spec.rkeConfig.machineGlobalConfig['cluster-cidr'] = val"
2443
+ @service-cidr-changed="(val)=>localValue.spec.rkeConfig.machineGlobalConfig['service-cidr'] = val"
2444
+ @cluster-domain-changed="(val)=>localValue.spec.rkeConfig.machineGlobalConfig['cluster-domain'] = val"
2445
+ @cluster-dns-changed="(val)=>localValue.spec.rkeConfig.machineGlobalConfig['cluster-dns'] = val"
2446
+ @service-node-port-range-changed="(val)=>localValue.spec.rkeConfig.machineGlobalConfig['service-node-port-range'] = val"
2447
+ @tls-san-changed="(val)=>localValue.spec.rkeConfig.machineGlobalConfig['tls-san'] = val"
2448
+ @local-cluster-auth-endpoint-changed="enableLocalClusterAuthEndpoint"
2449
+ @ca-certs-changed="(val)=>localValue.spec.localClusterAuthEndpoint.caCerts = val"
2450
+ @fqdn-changed="(val)=>localValue.spec.localClusterAuthEndpoint.fqdn = val"
2451
+ />
2452
+ </Tab>
2369
2453
 
2370
- <!-- Upgrade -->
2371
- <Tab
2372
- name="upgrade"
2373
- label-key="cluster.tabs.upgrade"
2374
- >
2375
- <Upgrade
2376
- v-model:value="localValue"
2377
- :mode="mode"
2378
- @update:value="$emit('input', $event)"
2379
- />
2380
- </Tab>
2454
+ <!-- Upgrade -->
2455
+ <Tab
2456
+ name="upgrade"
2457
+ label-key="cluster.tabs.upgrade"
2458
+ >
2459
+ <Upgrade
2460
+ v-model:value="localValue"
2461
+ :mode="mode"
2462
+ @update:value="$emit('input', $event)"
2463
+ />
2464
+ </Tab>
2381
2465
 
2382
- <!-- Registries -->
2383
- <Tab
2384
- :name="REGISTRIES_TAB_NAME"
2385
- label-key="cluster.tabs.registry"
2386
- >
2387
- <Registries
2388
- v-if="isActiveTabRegistries"
2466
+ <!-- Registries -->
2467
+ <Tab
2468
+ :name="REGISTRIES_TAB_NAME"
2469
+ label-key="cluster.tabs.registry"
2470
+ >
2471
+ <Registries
2472
+ v-if="isActiveTabRegistries"
2473
+ v-model:value="localValue"
2474
+ :mode="mode"
2475
+ :register-before-hook="registerBeforeHook"
2476
+ :show-custom-registry-input="showCustomRegistryInput"
2477
+ :registry-host="registryHost"
2478
+ :registry-secret="registrySecret"
2479
+ :show-custom-registry-advanced-input="showCustomRegistryAdvancedInput"
2480
+ @update:value="$emit('input', $event)"
2481
+ @update-configs-changed="updateConfigs"
2482
+ @custom-registry-changed="toggleCustomRegistry"
2483
+ @registry-host-changed="handleRegistryHostChanged"
2484
+ @registry-secret-changed="handleRegistrySecretChanged"
2485
+ />
2486
+ </Tab>
2487
+
2488
+ <!-- Add-on Configs -->
2489
+ <Tab
2490
+ v-for="v in addonVersions"
2491
+ :key="v.name"
2492
+ :name="v.name"
2493
+ :label="labelForAddon($store, v.name, false)"
2494
+ :weight="9"
2495
+ :showHeader="false"
2496
+ :error="addonConfigValidation[v.name]===false"
2497
+ @active="showAddons(v.name)"
2498
+ >
2499
+ <AddOnConfig
2500
+ :ref="v.name"
2501
+ v-model:value="localValue"
2502
+ :mode="mode"
2503
+ :version-info="versionInfo"
2504
+ :addon-version="v"
2505
+ :addons-rev="addonsRev"
2506
+ :user-chart-values-temp="userChartValuesTemp"
2507
+ :init-yaml-editor="initYamlEditor"
2508
+ @update:value="$emit('input', $event)"
2509
+ @update-questions="syncChartValues"
2510
+ @update-values="updateValues"
2511
+ @validationChanged="e => addonConfigValidationChanged(v.name, e)"
2512
+ />
2513
+ </Tab>
2514
+
2515
+ <!-- Add-on Additional Manifest -->
2516
+ <Tab
2517
+ name="additionalmanifest"
2518
+ label-key="cluster.tabs.addOnAdditionalManifest"
2519
+ :showHeader="false"
2520
+ @active="refreshComponentWithYamls('additionalmanifest')"
2521
+ >
2522
+ <AddOnAdditionalManifest
2523
+ ref="additionalmanifest"
2524
+ :value="value"
2525
+ :mode="mode"
2526
+ @additional-manifest-changed="updateAdditionalManifest"
2527
+ />
2528
+ </Tab>
2529
+
2530
+ <!-- Cluster Agent Configuration -->
2531
+ <Tab
2532
+ v-if="value.spec.clusterAgentDeploymentCustomization"
2533
+ name="clusteragentconfig"
2534
+ label-key="cluster.agentConfig.tabs.cluster"
2535
+ >
2536
+ <AgentConfiguration
2537
+ v-model:value="value.spec.clusterAgentDeploymentCustomization"
2538
+ data-testid="rke2-cluster-agent-config"
2539
+ type="cluster"
2540
+ :mode="mode"
2541
+ :scheduling-customization-feature-enabled="schedulingCustomizationFeatureEnabled"
2542
+ :default-p-c="clusterAgentDefaultPC"
2543
+ :default-p-d-b="clusterAgentDefaultPDB"
2544
+ :scheduling-customization-originally-enabled="schedulingCustomizationOriginallyEnabled"
2545
+ @scheduling-customization-changed="setSchedulingCustomization"
2546
+ />
2547
+ </Tab>
2548
+
2549
+ <!-- Fleet Agent Configuration -->
2550
+ <Tab
2551
+ name="fleetagentconfig"
2552
+ label-key="cluster.agentConfig.tabs.fleet"
2553
+ >
2554
+ <AgentConfiguration
2555
+ v-if="value.spec.fleetAgentDeploymentCustomization"
2556
+ v-model:value="value.spec.fleetAgentDeploymentCustomization"
2557
+ data-testid="rke2-fleet-agent-config"
2558
+ type="fleet"
2559
+ :mode="mode"
2560
+ />
2561
+ </Tab>
2562
+
2563
+ <!-- Advanced -->
2564
+ <Tab
2565
+ v-if="haveArgInfo || agentArgs['protect-kernel-defaults']"
2566
+ name="advanced"
2567
+ label-key="cluster.tabs.advanced"
2568
+ :weight="-1"
2569
+ >
2570
+ <Advanced
2571
+ v-model:value="localValue"
2572
+ :mode="mode"
2573
+ :have-arg-info="haveArgInfo"
2574
+ :selected-version="selectedVersion"
2575
+ @update:value="$emit('input', $event)"
2576
+ />
2577
+ </Tab>
2578
+
2579
+ <AgentEnv
2389
2580
  v-model:value="localValue"
2390
2581
  :mode="mode"
2391
- :register-before-hook="registerBeforeHook"
2392
- :show-custom-registry-input="showCustomRegistryInput"
2393
- :registry-host="registryHost"
2394
- :registry-secret="registrySecret"
2395
- :show-custom-registry-advanced-input="showCustomRegistryAdvancedInput"
2396
2582
  @update:value="$emit('input', $event)"
2397
- @update-configs-changed="updateConfigs"
2398
- @custom-registry-changed="toggleCustomRegistry"
2399
- @registry-host-changed="handleRegistryHostChanged"
2400
- @registry-secret-changed="handleRegistrySecretChanged"
2401
2583
  />
2402
- </Tab>
2403
-
2404
- <!-- Add-on Configs -->
2405
- <Tab
2406
- v-for="v in addonVersions"
2407
- :key="v.name"
2408
- :name="v.name"
2409
- :label="labelForAddon($store, v.name, false)"
2410
- :weight="9"
2411
- :showHeader="false"
2412
- :error="addonConfigValidation[v.name]===false"
2413
- @active="showAddons(v.name)"
2414
- >
2415
- <AddOnConfig
2416
- :ref="v.name"
2584
+ <Labels
2417
2585
  v-model:value="localValue"
2418
2586
  :mode="mode"
2419
- :version-info="versionInfo"
2420
- :addon-version="v"
2421
- :addons-rev="addonsRev"
2422
- :user-chart-values-temp="userChartValuesTemp"
2423
- :init-yaml-editor="initYamlEditor"
2424
2587
  @update:value="$emit('input', $event)"
2425
- @update-questions="syncChartValues"
2426
- @update-values="updateValues"
2427
- @validationChanged="e => addonConfigValidationChanged(v.name, e)"
2428
- />
2429
- </Tab>
2430
-
2431
- <!-- Add-on Additional Manifest -->
2432
- <Tab
2433
- name="additionalmanifest"
2434
- label-key="cluster.tabs.addOnAdditionalManifest"
2435
- :showHeader="false"
2436
- @active="refreshComponentWithYamls('additionalmanifest')"
2437
- >
2438
- <AddOnAdditionalManifest
2439
- ref="additionalmanifest"
2440
- :value="value"
2441
- :mode="mode"
2442
- @additional-manifest-changed="updateAdditionalManifest"
2443
- />
2444
- </Tab>
2445
-
2446
- <!-- Cluster Agent Configuration -->
2447
- <Tab
2448
- v-if="value.spec.clusterAgentDeploymentCustomization"
2449
- name="clusteragentconfig"
2450
- label-key="cluster.agentConfig.tabs.cluster"
2451
- >
2452
- <AgentConfiguration
2453
- v-model:value="value.spec.clusterAgentDeploymentCustomization"
2454
- data-testid="rke2-cluster-agent-config"
2455
- type="cluster"
2456
- :mode="mode"
2457
- :scheduling-customization-feature-enabled="schedulingCustomizationFeatureEnabled"
2458
- :default-p-c="clusterAgentDefaultPC"
2459
- :default-p-d-b="clusterAgentDefaultPDB"
2460
- :scheduling-customization-originally-enabled="schedulingCustomizationOriginallyEnabled"
2461
- @scheduling-customization-changed="setSchedulingCustomization"
2462
2588
  />
2463
- </Tab>
2464
2589
 
2465
- <!-- Fleet Agent Configuration -->
2466
- <Tab
2467
- name="fleetagentconfig"
2468
- label-key="cluster.agentConfig.tabs.fleet"
2469
- >
2470
- <AgentConfiguration
2471
- v-if="value.spec.fleetAgentDeploymentCustomization"
2472
- v-model:value="value.spec.fleetAgentDeploymentCustomization"
2473
- data-testid="rke2-fleet-agent-config"
2474
- type="fleet"
2475
- :mode="mode"
2476
- />
2477
- </Tab>
2478
-
2479
- <!-- Advanced -->
2480
- <Tab
2481
- v-if="haveArgInfo || agentArgs['protect-kernel-defaults']"
2482
- name="advanced"
2483
- label-key="cluster.tabs.advanced"
2484
- :weight="-1"
2485
- >
2486
- <Advanced
2487
- v-model:value="localValue"
2488
- :mode="mode"
2489
- :have-arg-info="haveArgInfo"
2490
- :selected-version="selectedVersion"
2491
- @update:value="$emit('input', $event)"
2492
- />
2493
- </Tab>
2590
+ <!-- Extension tabs -->
2591
+ <Tab
2592
+ v-for="tab, i in extensionTabs"
2593
+ :key="`${tab.name}${i}`"
2594
+ :name="tab.name"
2595
+ :label="tab.label"
2596
+ :label-key="tab.labelKey"
2597
+ :weight="tab.weight"
2598
+ :tooltip="tab.tooltip"
2599
+ :show-header="tab.showHeader"
2600
+ :display-alert-icon="tab.displayAlertIcon"
2601
+ :error="tab.error"
2602
+ :badge="tab.badge"
2603
+ >
2604
+ <component
2605
+ :is="tab.component"
2606
+ :resource="value"
2607
+ />
2608
+ </Tab>
2609
+ </Tabbed>
2610
+ </div>
2494
2611
 
2495
- <AgentEnv
2496
- v-model:value="localValue"
2497
- :mode="mode"
2498
- @update:value="$emit('input', $event)"
2499
- />
2500
- <Labels
2501
- v-model:value="localValue"
2502
- :mode="mode"
2503
- @update:value="$emit('input', $event)"
2504
- />
2505
-
2506
- <!-- Extension tabs -->
2507
- <Tab
2508
- v-for="tab, i in extensionTabs"
2509
- :key="`${tab.name}${i}`"
2510
- :name="tab.name"
2511
- :label="tab.label"
2512
- :label-key="tab.labelKey"
2513
- :weight="tab.weight"
2514
- :tooltip="tab.tooltip"
2515
- :show-header="tab.showHeader"
2516
- :display-alert-icon="tab.displayAlertIcon"
2517
- :error="tab.error"
2518
- :badge="tab.badge"
2519
- >
2520
- <component
2521
- :is="tab.component"
2522
- :resource="value"
2523
- />
2524
- </Tab>
2525
- </Tabbed>
2612
+ <Banner
2613
+ v-if="unsupportedSelectorConfig"
2614
+ color="warning"
2615
+ :label="t('cluster.banner.warning')"
2616
+ />
2526
2617
  </div>
2527
-
2528
- <Banner
2529
- v-if="unsupportedSelectorConfig"
2530
- color="warning"
2531
- :label="t('cluster.banner.warning')"
2532
- />
2533
-
2534
2618
  <template
2535
- v-if="needCredential && !credentialId"
2619
+ v-if="hideFooter"
2536
2620
  #form-footer
2537
2621
  >
2538
2622
  <div><!-- Hide the outer footer --></div>
@@ -2541,6 +2625,12 @@ export default {
2541
2625
  </template>
2542
2626
 
2543
2627
  <style lang="scss" scoped>
2628
+ .authenticated {
2629
+ display:flex;
2630
+ flex-direction: column;
2631
+ flex-grow: 1;
2632
+ }
2633
+
2544
2634
  .min-height {
2545
2635
  min-height: 40em;
2546
2636
  }