@rancher/shell 0.3.0 → 0.3.2

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 (342) hide show
  1. package/assets/styles/global/_button.scss +5 -1
  2. package/assets/styles/global/_columns.scss +4 -0
  3. package/assets/styles/global/_gauges.scss +1 -1
  4. package/assets/styles/global/_layout.scss +5 -2
  5. package/assets/styles/global/_select.scss +1 -4
  6. package/assets/styles/themes/_dark.scss +5 -4
  7. package/assets/styles/themes/_light.scss +4 -3
  8. package/assets/styles/themes/_suse.scss +1 -1
  9. package/assets/styles/vendor/vue-select.scss +4 -3
  10. package/assets/translations/en-us.yaml +673 -73
  11. package/assets/translations/zh-hans.yaml +720 -207
  12. package/chart/monitoring/steps/uninstall-v1.vue +2 -2
  13. package/cloud-credential/azure.vue +23 -0
  14. package/cloud-credential/harvester.vue +25 -62
  15. package/cloud-credential/pnap.vue +80 -0
  16. package/components/.DS_Store +0 -0
  17. package/components/ActionMenu.vue +28 -7
  18. package/components/AdvancedSection.vue +9 -2
  19. package/components/Alert.vue +2 -2
  20. package/components/ButtonDropdown.vue +0 -2
  21. package/components/ButtonGroup.vue +1 -0
  22. package/components/CollapsibleCard.vue +0 -1
  23. package/components/CruResource.vue +41 -4
  24. package/components/DetailTop.vue +72 -4
  25. package/components/DisableAuthProviderModal.vue +106 -0
  26. package/{rancher-components/components/Utils/DraggableZone → components}/DraggableZone.vue +0 -0
  27. package/components/ExplorerMembers.vue +253 -30
  28. package/components/ExplorerProjectsNamespaces.vue +77 -33
  29. package/components/ExtensionPanel.vue +42 -0
  30. package/components/GrowlManager.vue +3 -3
  31. package/components/IconOrSvg.vue +178 -0
  32. package/components/LogItem.vue +69 -0
  33. package/components/PodSecurityAdmission.vue +302 -0
  34. package/components/PromptModal.vue +1 -0
  35. package/components/ResourceDetail/Masthead.vue +69 -4
  36. package/components/ResourceDetail/index.vue +12 -5
  37. package/components/ResourceList/Masthead.vue +11 -1
  38. package/components/ResourceList/ResourceLoadingIndicator.vue +12 -2
  39. package/components/ResourceList/index.vue +66 -12
  40. package/components/ResourceList/resource-list.config.js +7 -0
  41. package/components/ResourceTable.vue +33 -6
  42. package/components/SimpleBox.vue +1 -1
  43. package/components/SortableTable/THead.vue +21 -14
  44. package/components/SortableTable/filtering.js +1 -1
  45. package/components/SortableTable/index.vue +21 -10
  46. package/components/SortableTable/selection.js +15 -3
  47. package/components/Tabbed/Tab.vue +1 -1
  48. package/components/Tabbed/index.vue +20 -15
  49. package/components/__tests__/.DS_Store +0 -0
  50. package/components/__tests__/AsyncButton.test.ts +140 -0
  51. package/components/__tests__/BackLink.test.ts +33 -0
  52. package/components/__tests__/ButtonGroup.test.ts +124 -0
  53. package/components/__tests__/ClusterBadge.test.ts +32 -0
  54. package/components/__tests__/CollapsibleCard.test.ts +64 -0
  55. package/components/__tests__/ConsumptionGauge.test.ts +88 -0
  56. package/components/__tests__/CruResource.test.ts +3 -2
  57. package/components/__tests__/FixedBanner.test.ts +129 -0
  58. package/components/__tests__/GrowlManager.test.ts +147 -0
  59. package/components/__tests__/NamespaceFilter.test.ts +33 -25
  60. package/components/__tests__/PercentageBar.test.ts +32 -0
  61. package/components/__tests__/PodSecurityAdmission.test.ts +398 -0
  62. package/components/auth/AuthBanner.vue +20 -10
  63. package/components/auth/RoleDetailEdit.vue +26 -17
  64. package/components/auth/SelectPrincipal.vue +36 -5
  65. package/components/form/ArrayList.vue +3 -35
  66. package/components/form/ArrayListGrouped.vue +13 -4
  67. package/components/form/ArrayListSelect.vue +5 -5
  68. package/components/form/Error.vue +8 -0
  69. package/components/form/KeyValue.vue +39 -7
  70. package/components/form/LabeledSelect.vue +5 -2
  71. package/components/form/Labels.vue +46 -16
  72. package/components/form/Members/ClusterPermissionsEditor.vue +17 -17
  73. package/components/form/Members/MembershipEditor.vue +12 -12
  74. package/components/form/NameNsDescription.vue +1 -1
  75. package/components/form/NodeScheduling.vue +1 -1
  76. package/components/form/Probe.vue +3 -3
  77. package/components/form/ResourceQuota/Project.vue +6 -6
  78. package/components/form/ResourceTabs/index.vue +24 -6
  79. package/components/form/Security.vue +7 -6
  80. package/components/form/Select.vue +3 -2
  81. package/components/form/SelectOrCreateAuthSecret.vue +22 -29
  82. package/components/form/ServicePorts.vue +8 -0
  83. package/components/form/WorkloadPorts.vue +7 -1
  84. package/components/form/__tests__/ArrayList.test.ts +74 -0
  85. package/components/form/__tests__/ArrayListGrouped.test.ts +6 -4
  86. package/components/formatter/Checked.vue +1 -1
  87. package/components/formatter/ClusterLink.vue +5 -0
  88. package/components/formatter/IconIsDefault.vue +2 -2
  89. package/components/formatter/InternalExternalIP.vue +11 -8
  90. package/components/formatter/LiveDuration.vue +78 -0
  91. package/components/formatter/WorkloadHealthScale.vue +5 -3
  92. package/components/nav/Header.vue +74 -7
  93. package/components/nav/NamespaceFilter.vue +146 -63
  94. package/components/nav/TopLevelMenu.vue +22 -19
  95. package/components/nav/WindowManager/ContainerLogs.vue +83 -126
  96. package/components/nav/WindowManager/ContainerShell.vue +9 -7
  97. package/components/nav/WindowManager/Window.vue +2 -0
  98. package/components/nav/WindowManager/index.vue +10 -0
  99. package/config/elemental-types.js +9 -0
  100. package/config/features.js +2 -0
  101. package/config/home-links.js +4 -1
  102. package/config/pod-security-admission.ts +82 -0
  103. package/config/product/apps.js +1 -1
  104. package/config/product/auth.js +6 -5
  105. package/config/product/backup.js +1 -1
  106. package/config/product/explorer.js +6 -6
  107. package/config/product/fleet.js +1 -1
  108. package/config/product/manager.js +6 -2
  109. package/config/query-params.js +1 -0
  110. package/config/secret.js +0 -1
  111. package/config/settings.ts +26 -9
  112. package/config/table-headers.js +22 -11
  113. package/config/types.js +4 -1
  114. package/config/uiplugins.js +3 -3
  115. package/content/docs/zh-hans/getting-started.md +113 -137
  116. package/content/docs/zh-hans/whats-new.md +8 -46
  117. package/core/plugin-helpers.js +171 -0
  118. package/core/plugin.ts +61 -1
  119. package/core/plugins.js +33 -0
  120. package/core/types.ts +128 -2
  121. package/creators/pkg/package-lock.json +37 -0
  122. package/creators/pkg/package.json +1 -1
  123. package/detail/catalog.cattle.io.app.vue +1 -1
  124. package/detail/pod.vue +1 -1
  125. package/detail/provisioning.cattle.io.cluster.vue +35 -9
  126. package/detail/service.vue +2 -9
  127. package/detail/workload/index.vue +0 -1
  128. package/dialog/AddClusterMemberDialog.vue +22 -28
  129. package/dialog/AddProjectMemberDialog.vue +53 -9
  130. package/dialog/DiagnosticTimingsDialog.vue +8 -7
  131. package/dialog/DrainNode.vue +44 -48
  132. package/dialog/ForceMachineRemoveDialog.vue +5 -7
  133. package/dialog/GenericPrompt.vue +15 -20
  134. package/dialog/RollbackWorkloadDialog.vue +15 -46
  135. package/dialog/RotateCertificatesDialog.vue +5 -7
  136. package/dialog/RotateEncryptionKeyDialog.vue +5 -9
  137. package/dialog/SaveAsRKETemplateDialog.vue +5 -13
  138. package/dialog/ScaleMachineDownDialog.vue +1 -1
  139. package/dialog/ScalePoolDownDialog.vue +121 -0
  140. package/edit/__tests__/management.cattle.io.setting.test.ts +3 -3
  141. package/edit/auth/azuread.vue +16 -16
  142. package/edit/auth/github.vue +8 -0
  143. package/edit/auth/googleoauth.vue +10 -1
  144. package/edit/auth/ldap/index.vue +10 -0
  145. package/edit/auth/oidc.vue +10 -0
  146. package/edit/auth/saml.vue +10 -0
  147. package/edit/autoscaling.horizontalpodautoscaler/index.vue +1 -1
  148. package/edit/catalog.cattle.io.clusterrepo.vue +3 -0
  149. package/edit/cloudcredential.vue +3 -7
  150. package/edit/logging-flow/Match.vue +39 -8
  151. package/edit/logging-flow/index.vue +27 -4
  152. package/edit/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +107 -0
  153. package/edit/management.cattle.io.project.vue +8 -1
  154. package/edit/management.cattle.io.setting.vue +5 -2
  155. package/edit/management.cattle.io.user.vue +7 -1
  156. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +36 -8
  157. package/edit/monitoring.coreos.com.alertmanagerconfig/types/email.vue +2 -2
  158. package/edit/monitoring.coreos.com.prometheusrule/GroupRules.vue +14 -6
  159. package/edit/namespace.vue +18 -4
  160. package/edit/networking.k8s.io.ingress/Certificate.vue +1 -0
  161. package/edit/networking.k8s.io.ingress/IngressClass.vue +8 -6
  162. package/edit/networking.k8s.io.ingress/RulePath.vue +12 -6
  163. package/edit/networking.k8s.io.ingress/index.vue +8 -6
  164. package/edit/persistentvolume/index.vue +30 -27
  165. package/edit/persistentvolume/plugins/cephfs.vue +29 -29
  166. package/edit/persistentvolume/plugins/csi.vue +102 -62
  167. package/edit/persistentvolume/plugins/fc.vue +19 -19
  168. package/edit/persistentvolume/plugins/iscsi.vue +45 -45
  169. package/edit/persistentvolume/plugins/rbd.vue +39 -39
  170. package/edit/persistentvolumeclaim.vue +78 -75
  171. package/edit/provisioning.cattle.io.cluster/MachinePool.vue +11 -7
  172. package/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue +10 -1
  173. package/edit/provisioning.cattle.io.cluster/RegistryMirrors.vue +87 -27
  174. package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +3 -6
  175. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +96 -0
  176. package/edit/provisioning.cattle.io.cluster/import.vue +1 -1
  177. package/edit/provisioning.cattle.io.cluster/index.vue +29 -6
  178. package/edit/provisioning.cattle.io.cluster/rke2.vue +445 -154
  179. package/edit/secret/index.vue +3 -7
  180. package/edit/service.vue +3 -1
  181. package/edit/storage.k8s.io.storageclass/index.vue +100 -16
  182. package/edit/storage.k8s.io.storageclass/provisioners/driver.harvesterhci.io.vue +114 -0
  183. package/edit/workload/__tests__/index.test.ts +98 -0
  184. package/edit/workload/index.vue +58 -8
  185. package/edit/workload/mixins/workload.js +107 -70
  186. package/edit/workload/storage/ContainerMountPaths.vue +0 -10
  187. package/edit/workload/storage/emptyDir.vue +88 -0
  188. package/edit/workload/storage/ephemeralVolume/index.vue +1 -1
  189. package/edit/workload/storage/index.vue +8 -0
  190. package/edit/workload/storage/persistentVolumeClaim/index.vue +1 -1
  191. package/layouts/default.vue +57 -44
  192. package/list/__tests__/workload.test.ts +5 -2
  193. package/list/catalog.cattle.io.app.vue +1 -0
  194. package/list/cis.cattle.io.clusterscan.vue +1 -0
  195. package/list/fleet.cattle.io.bundle.vue +5 -6
  196. package/list/fleet.cattle.io.cluster.vue +6 -3
  197. package/list/fleet.cattle.io.clusterregistrationtoken.vue +5 -6
  198. package/list/fleet.cattle.io.gitrepo.vue +4 -9
  199. package/list/helm.cattle.io.projecthelmchart.vue +1 -5
  200. package/list/logging.banzaicloud.io.clusterflow.vue +4 -1
  201. package/list/logging.banzaicloud.io.flow.vue +6 -5
  202. package/list/management.cattle.io.cluster.vue +1 -0
  203. package/list/management.cattle.io.feature.vue +3 -4
  204. package/list/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +47 -0
  205. package/list/management.cattle.io.setting.vue +2 -2
  206. package/list/management.cattle.io.user.vue +4 -10
  207. package/list/monitoring.coreos.com.alertmanagerconfig.vue +2 -7
  208. package/list/node.vue +8 -5
  209. package/list/persistentvolume.vue +3 -3
  210. package/list/persistentvolumeclaim.vue +3 -4
  211. package/list/provisioning.cattle.io.cluster.vue +18 -19
  212. package/list/service.vue +6 -14
  213. package/list/workload.vue +43 -38
  214. package/machine-config/azure.vue +429 -60
  215. package/machine-config/pnap.vue +288 -0
  216. package/mixins/auth-config.js +1 -3
  217. package/mixins/browser-tab-visibility.js +8 -14
  218. package/mixins/chart.js +1 -1
  219. package/mixins/create-edit-view/impl.js +4 -0
  220. package/mixins/create-edit-view/index.js +4 -2
  221. package/mixins/resource-fetch-namespaced.js +98 -0
  222. package/mixins/resource-fetch.js +79 -45
  223. package/mixins/resource-manager.js +1 -23
  224. package/models/apps.controllerrevision.js +7 -0
  225. package/models/apps.daemonset.js +18 -0
  226. package/models/apps.deployment.js +44 -0
  227. package/models/apps.replicaset.js +7 -0
  228. package/models/apps.statefulset.js +18 -0
  229. package/models/batch.job.js +7 -14
  230. package/models/cluster/node.js +10 -2
  231. package/models/cluster.x-k8s.io.machine.js +26 -4
  232. package/models/cluster.x-k8s.io.machinedeployment.js +12 -2
  233. package/models/event.js +7 -0
  234. package/models/logging.banzaicloud.io.flow.js +4 -0
  235. package/models/management.cattle.io.cluster.js +1 -1
  236. package/models/management.cattle.io.clusterroletemplatebinding.js +1 -1
  237. package/models/management.cattle.io.globalrole.js +2 -2
  238. package/models/management.cattle.io.node.js +37 -2
  239. package/models/management.cattle.io.podsecurityadmissionconfigurationtemplate.ts +4 -0
  240. package/models/management.cattle.io.project.js +30 -11
  241. package/models/management.cattle.io.setting.js +1 -1
  242. package/models/management.cattle.io.user.js +37 -1
  243. package/models/namespace.js +42 -5
  244. package/models/persistentvolume.js +14 -2
  245. package/models/pod.js +15 -0
  246. package/models/projectroletemplatebinding.js +7 -0
  247. package/models/provisioning.cattle.io.cluster.js +61 -10
  248. package/models/rke-machine.cattle.io.pnapmachinetemplate.js +15 -0
  249. package/models/service.js +14 -13
  250. package/models/storage.k8s.io.storageclass.js +33 -18
  251. package/models/workload.js +38 -7
  252. package/nuxt.config.js +27 -17
  253. package/package.json +7 -7
  254. package/pages/about.vue +14 -2
  255. package/pages/c/_cluster/apps/charts/index.vue +21 -3
  256. package/pages/c/_cluster/apps/charts/install.vue +59 -22
  257. package/pages/c/_cluster/auth/config/_id.vue +6 -0
  258. package/pages/c/_cluster/auth/config/index.vue +8 -6
  259. package/pages/c/_cluster/auth/group.principal/assign-edit.vue +1 -1
  260. package/pages/c/_cluster/auth/roles/index.vue +1 -1
  261. package/pages/c/_cluster/explorer/index.vue +51 -6
  262. package/pages/c/_cluster/longhorn/index.vue +1 -1
  263. package/pages/c/_cluster/monitoring/alertmanagerconfig/_alertmanagerconfigid/receiver.vue +15 -4
  264. package/pages/c/_cluster/monitoring/index.vue +1 -1
  265. package/pages/c/_cluster/neuvector/index.vue +1 -1
  266. package/pages/c/_cluster/settings/performance.vue +48 -2
  267. package/pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue +2 -0
  268. package/pages/c/_cluster/uiplugins/InstallDialog.vue +3 -0
  269. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +42 -2
  270. package/pages/c/_cluster/uiplugins/RemoveUIPlugins.vue +2 -0
  271. package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +1 -0
  272. package/pages/c/_cluster/uiplugins/UninstallDialog.vue +2 -0
  273. package/pages/c/_cluster/uiplugins/index.vue +42 -3
  274. package/pages/diagnostic.vue +5 -4
  275. package/pages/home.vue +105 -30
  276. package/pages/prefs.vue +23 -12
  277. package/pages/rio/mesh.vue +1 -1
  278. package/pkg/dynamic-importer.lib.js +8 -0
  279. package/pkg/vue.config.js +4 -0
  280. package/plugins/dashboard-store/__tests__/mutations.spec.js +406 -0
  281. package/plugins/dashboard-store/actions.js +32 -25
  282. package/plugins/dashboard-store/getters.js +50 -33
  283. package/plugins/dashboard-store/mutations.js +134 -28
  284. package/plugins/dashboard-store/resource-class.js +37 -42
  285. package/plugins/steve/actions.js +30 -0
  286. package/plugins/steve/caches/resourceCache.js +60 -0
  287. package/plugins/steve/getters.js +44 -1
  288. package/plugins/steve/mutations.js +97 -36
  289. package/plugins/steve/resourceWatcher.js +277 -0
  290. package/plugins/steve/schema.utils.js +25 -0
  291. package/plugins/steve/subscribe.js +288 -115
  292. package/plugins/steve/worker/index.js +17 -0
  293. package/plugins/steve/worker/web-worker.advanced.js +302 -0
  294. package/plugins/steve/{web-worker.steve-sub-worker.js → worker/web-worker.basic.js} +3 -44
  295. package/rancher-components/Card/Card.vue +3 -3
  296. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +1 -0
  297. package/rancher-components/StringList/StringList.test.ts +45 -420
  298. package/rancher-components/StringList/StringList.vue +1 -10
  299. package/rancher-components/components/Banner/Banner.test.ts +44 -0
  300. package/rancher-components/components/Banner/Banner.vue +130 -61
  301. package/rancher-components/components/Form/Checkbox/Checkbox.test.ts +13 -22
  302. package/rancher-components/components/Form/Checkbox/Checkbox.vue +8 -6
  303. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.test.ts +9 -9
  304. package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +0 -1
  305. package/rancher-components/components/StringList/StringList.test.ts +7 -7
  306. package/rancher-components/components/StringList/StringList.vue +21 -15
  307. package/scripts/test-plugins-build.sh +8 -0
  308. package/static/loading-indicator.html +1 -1
  309. package/store/action-menu.js +4 -3
  310. package/store/index.js +54 -3
  311. package/store/plugins.js +0 -17
  312. package/store/pnap.js +128 -0
  313. package/store/prefs.js +4 -2
  314. package/store/type-map.js +81 -13
  315. package/types/pod-security-admission.ts +36 -0
  316. package/types/shell/index.d.ts +497 -396
  317. package/utils/__tests__/object.test.ts +17 -1
  318. package/utils/__tests__/pod-security-admission.test.ts +61 -0
  319. package/utils/async.ts +36 -0
  320. package/utils/color.js +45 -0
  321. package/utils/crypto/browserHashUtils.js +18 -0
  322. package/utils/dynamic-importer.js +8 -0
  323. package/utils/install-redirect.js +1 -1
  324. package/utils/object.js +24 -0
  325. package/utils/pod-security-admission.ts +39 -0
  326. package/utils/socket.js +61 -24
  327. package/utils/string.js +2 -0
  328. package/utils/svg-filter.js +301 -0
  329. package/utils/time.js +49 -0
  330. package/utils/validators/cidr.js +4 -0
  331. package/utils/validators/formRules/__tests__/index.test.ts +23 -3
  332. package/utils/validators/formRules/index.ts +14 -0
  333. package/config/product/harvester-manager.js +0 -162
  334. package/edit/harvesterhci.io.management.cluster.vue +0 -153
  335. package/list/harvesterhci.io.management.cluster.vue +0 -241
  336. package/machine-config/harvester.vue +0 -693
  337. package/models/harvesterhci.io.management.cluster.js +0 -228
  338. package/pages/c/_cluster/harvesterManager/index.vue +0 -24
  339. package/rancher-components/Card/Card.test.ts +0 -39
  340. package/rancher-components/Utils/DraggableZone/DraggableZone.vue +0 -181
  341. package/rancher-components/Utils/DraggableZone/index.ts +0 -1
  342. package/rancher-components/components/Utils/DraggableZone/index.ts +0 -1
@@ -4,7 +4,6 @@ import throttle from 'lodash/throttle';
4
4
  import isArray from 'lodash/isArray';
5
5
  import merge from 'lodash/merge';
6
6
  import { mapGetters } from 'vuex';
7
-
8
7
  import CreateEditView from '@shell/mixins/create-edit-view';
9
8
  import FormValidation from '@shell/mixins/form-validation';
10
9
 
@@ -29,6 +28,7 @@ import { sortBy } from '@shell/utils/sort';
29
28
  import { camelToTitle, nlToBr } from '@shell/utils/string';
30
29
  import { compare, sortable } from '@shell/utils/version';
31
30
  import { isHarvesterSatisfiesVersion } from '@shell/utils/cluster';
31
+ import * as VERSION from '@shell/utils/version';
32
32
 
33
33
  import ArrayList from '@shell/components/form/ArrayList';
34
34
  import ArrayListGrouped from '@shell/components/form/ArrayListGrouped';
@@ -66,6 +66,8 @@ import RegistryConfigs from './RegistryConfigs';
66
66
  import RegistryMirrors from './RegistryMirrors';
67
67
  import S3Config from './S3Config';
68
68
  import SelectCredential from './SelectCredential';
69
+ import AdvancedSection from '@shell/components/AdvancedSection.vue';
70
+ import { ELEMENTAL_SCHEMA_IDS, KIND, ELEMENTAL_CLUSTER_PROVIDER } from '../../config/elemental-types';
69
71
 
70
72
  const PUBLIC = 'public';
71
73
  const PRIVATE = 'private';
@@ -77,6 +79,7 @@ const HARVESTER_CLOUD_PROVIDER = 'harvester-cloud-provider';
77
79
  export default {
78
80
  components: {
79
81
  ACE,
82
+ AdvancedSection,
80
83
  AgentEnv,
81
84
  ArrayList,
82
85
  ArrayListGrouped,
@@ -136,6 +139,10 @@ export default {
136
139
  hash.allPSPs = await this.$store.dispatch('management/findAll', { type: MANAGEMENT.POD_SECURITY_POLICY_TEMPLATE });
137
140
  }
138
141
 
142
+ if (this.$store.getters['management/canList'](MANAGEMENT.PSA)) {
143
+ hash.allPSAs = await this.$store.dispatch('management/findAll', { type: MANAGEMENT.PSA });
144
+ }
145
+
139
146
  // Get the latest versions from the global settings if possible
140
147
  const globalSettings = await this.$store.getters['management/all'](MANAGEMENT.SETTING) || [];
141
148
  const defaultRke2Setting = globalSettings.find(setting => setting.id === 'rke2-default-version') || {};
@@ -157,6 +164,7 @@ export default {
157
164
  const res = await allHash(hash);
158
165
 
159
166
  this.allPSPs = res.allPSPs || [];
167
+ this.allPSAs = res.allPSAs || [];
160
168
  this.rke2Versions = res.rke2Versions.data || [];
161
169
  this.k3sVersions = res.k3sVersions.data || [];
162
170
 
@@ -230,6 +238,10 @@ export default {
230
238
  set(this.value.spec, 'defaultPodSecurityPolicyTemplateName', '');
231
239
  }
232
240
 
241
+ if ( this.value.spec.defaultPodSecurityAdmissionConfigurationTemplateName === undefined ) {
242
+ set(this.value.spec, 'defaultPodSecurityAdmissionConfigurationTemplateName', '');
243
+ }
244
+
233
245
  await this.initAddons();
234
246
  await this.initRegistry();
235
247
 
@@ -266,34 +278,43 @@ export default {
266
278
  set(this.value.spec, 'rkeConfig.machineSelectorConfig', [{ config: {} }]);
267
279
  }
268
280
 
281
+ // Store the initial PSP template name, so we can set it back if needed
282
+ const lastDefaultPodSecurityPolicyTemplateName = this.value.spec.defaultPodSecurityPolicyTemplateName;
283
+ const previousKubernetesVersion = this.value.spec.kubernetesVersion;
284
+
269
285
  return {
270
- loadedOnce: false,
271
- lastIdx: 0,
272
- allPSPs: null,
273
- nodeComponent: null,
274
- credentialId: null,
275
- credential: null,
276
- machinePools: null,
277
- rke2Versions: null,
278
- k3sVersions: null,
279
- defaultRke2: '',
280
- defaultK3s: '',
281
- s3Backup: false,
282
- versionInfo: {},
283
- membershipUpdate: {},
284
- showDeprecatedPatchVersions: false,
285
- systemRegistry: null,
286
- registryHost: null,
287
- registryMode: null,
288
- registrySecret: null,
289
- userChartValues: {},
290
- userChartValuesTemp: {},
291
- addonsRev: 0,
292
- clusterIsAlreadyCreated: !!this.value.id,
293
- fvFormRuleSets: [{
286
+ loadedOnce: false,
287
+ lastIdx: 0,
288
+ allPSPs: null,
289
+ allPSAs: [],
290
+ nodeComponent: null,
291
+ credentialId: null,
292
+ credential: null,
293
+ machinePools: null,
294
+ rke2Versions: null,
295
+ k3sVersions: null,
296
+ defaultRke2: '',
297
+ defaultK3s: '',
298
+ s3Backup: false,
299
+ versionInfo: {},
300
+ membershipUpdate: {},
301
+ showDeprecatedPatchVersions: false,
302
+ systemRegistry: null,
303
+ registryHost: null,
304
+ showCustomRegistryInput: false,
305
+ showCustomRegistryAdvancedInput: false,
306
+ registrySecret: null,
307
+ userChartValues: {},
308
+ userChartValuesTemp: {},
309
+ addonsRev: 0,
310
+ clusterIsAlreadyCreated: !!this.value.id,
311
+ fvFormRuleSets: [{
294
312
  path: 'metadata.name', rules: ['subDomain'], translationKey: 'nameNsDescription.name.label'
295
313
  }],
296
314
  harvesterVersionRange: {},
315
+ lastDefaultPodSecurityPolicyTemplateName,
316
+ previousKubernetesVersion,
317
+ harvesterVersion: ''
297
318
  };
298
319
  },
299
320
 
@@ -309,6 +330,10 @@ export default {
309
330
  return this.value.spec.rkeConfig;
310
331
  },
311
332
 
333
+ isElementalCluster() {
334
+ return this.provider === ELEMENTAL_CLUSTER_PROVIDER || this.value?.machineProvider?.toLowerCase() === KIND.MACHINE_INV_SELECTOR_TEMPLATES.toLowerCase();
335
+ },
336
+
312
337
  advancedTitleAlt() {
313
338
  const machineSelectorLength = this.rkeConfig.machineSelectorConfig.length;
314
339
 
@@ -327,9 +352,34 @@ export default {
327
352
  return this.value.agentConfig;
328
353
  },
329
354
 
355
+ /**
356
+ * Return need of PSA if RKE and min k8s version
357
+ */
358
+ needsPSA() {
359
+ const release = this.value?.spec?.kubernetesVersion || '';
360
+ const version = release.match(/\d+/g);
361
+ const isRequiredVersion = version?.length ? +version[0] > 1 || +version[1] >= 23 : false;
362
+
363
+ return isRequiredVersion;
364
+ },
365
+
366
+ /**
367
+ * Restrict use of PSP based on min k8s version
368
+ */
369
+ needsPSP() {
370
+ const release = this.value?.spec?.kubernetesVersion || '';
371
+ const version = release.match(/\d+/g);
372
+ const isRequiredVersion = version?.length ? +version[0] === 1 && +version[1] < 25 : false;
373
+
374
+ return isRequiredVersion;
375
+ },
376
+
330
377
  // kubeletConfigs() {
331
378
  // return this.value.spec.rkeConfig.machineSelectorConfig.filter(x => !!x.machineLabelSelector);
332
379
  // },
380
+ /**
381
+ * Check if k8s release version used is RKE2 ^1.25
382
+ */
333
383
 
334
384
  unsupportedSelectorConfig() {
335
385
  let global = 0;
@@ -419,7 +469,10 @@ export default {
419
469
  return { label: x, value: x };
420
470
  });
421
471
 
422
- out.unshift({ label: '(None)', value: '' });
472
+ out.unshift({
473
+ label: this.$store.getters['i18n/t']('cluster.rke2.cisProfile.option'),
474
+ value: ''
475
+ });
423
476
 
424
477
  return out;
425
478
  },
@@ -429,7 +482,10 @@ export default {
429
482
  return null;
430
483
  }
431
484
 
432
- const out = [{ label: 'RKE2 Default', value: '' }];
485
+ const out = [{
486
+ label: this.$store.getters['i18n/t']('cluster.rke2.defaultPodSecurityPolicyTemplateName.option'),
487
+ value: ''
488
+ }];
433
489
 
434
490
  if ( this.allPSPs ) {
435
491
  for ( const pspt of this.allPSPs ) {
@@ -449,6 +505,35 @@ export default {
449
505
  return out;
450
506
  },
451
507
 
508
+ /**
509
+ * Convert PSA templates into options, sorting and flagging if any selected
510
+ */
511
+ psaOptions() {
512
+ if ( !this.needsPSA ) {
513
+ return [];
514
+ }
515
+ const out = [{
516
+ label: this.$store.getters['i18n/t']('cluster.rke2.defaultPodSecurityAdmissionConfigurationTemplateName.option'),
517
+ value: ''
518
+ }];
519
+
520
+ if ( this.allPSAs ) {
521
+ for ( const psa of this.allPSAs ) {
522
+ out.push({
523
+ label: psa.nameDisplay,
524
+ value: psa.id,
525
+ });
526
+ }
527
+ }
528
+ const cur = this.value.spec.defaultPodSecurityAdmissionConfigurationTemplateName;
529
+
530
+ if ( cur && !out.find(x => x.value === cur) ) {
531
+ out.unshift({ label: `${ cur } (Current)`, value: cur });
532
+ }
533
+
534
+ return out;
535
+ },
536
+
452
537
  disableOptions() {
453
538
  return this.serverArgs.disable.options.map((value) => {
454
539
  return {
@@ -459,7 +544,10 @@ export default {
459
544
  },
460
545
 
461
546
  cloudProviderOptions() {
462
- const out = [{ label: '(None)', value: '' }];
547
+ const out = [{
548
+ label: this.$store.getters['i18n/t']('cluster.rke2.cloudProvider.defaultValue.label'),
549
+ value: '',
550
+ }];
463
551
 
464
552
  const preferred = this.$store.getters['plugins/cloudProviderForDriver'](this.provider);
465
553
 
@@ -506,11 +594,7 @@ export default {
506
594
  },
507
595
 
508
596
  haveArgInfo() {
509
- if ( this.selectedVersion?.serverArgs && this.selectedVersion?.agentArgs ) {
510
- return true;
511
- }
512
-
513
- return false;
597
+ return Boolean(this.selectedVersion?.serverArgs && this.selectedVersion?.agentArgs);
514
598
  },
515
599
 
516
600
  serverArgs() {
@@ -526,20 +610,11 @@ export default {
526
610
  },
527
611
 
528
612
  showCisProfile() {
529
- return this.provider === 'custom' && ( this.serverArgs.profile || this.agentArgs.profile );
530
- },
531
-
532
- registryOptions() {
533
- return [PUBLIC, PRIVATE, ADVANCED].map((opt) => {
534
- return {
535
- label: this.$store.getters['i18n/withFallback'](`cluster.privateRegistry.mode."${ opt }"`, null, opt),
536
- value: opt,
537
- };
538
- });
613
+ return (this.provider === 'custom' || this.isElementalCluster) && ( this.serverArgs.profile || this.agentArgs.profile );
539
614
  },
540
615
 
541
616
  needCredential() {
542
- if ( this.provider === 'custom' || this.provider === 'import' || this.mode === _VIEW ) {
617
+ if ( this.provider === 'custom' || this.provider === 'import' || this.isElementalCluster || this.mode === _VIEW ) {
543
618
  return false;
544
619
  }
545
620
 
@@ -559,13 +634,17 @@ export default {
559
634
  },
560
635
 
561
636
  machineConfigSchema() {
637
+ let schema;
638
+
562
639
  if ( !this.hasMachinePools ) {
563
640
  return null;
641
+ } else if (this.isElementalCluster) {
642
+ schema = ELEMENTAL_SCHEMA_IDS.MACHINE_INV_SELECTOR_TEMPLATES;
643
+ } else {
644
+ schema = `${ CAPI.MACHINE_CONFIG_GROUP }.${ this.provider }config`;
564
645
  }
565
646
 
566
- const schema = this.$store.getters['management/schemaFor'](`${ CAPI.MACHINE_CONFIG_GROUP }.${ this.provider }config`);
567
-
568
- return schema;
647
+ return this.$store.getters['management/schemaFor'](schema);
569
648
  },
570
649
 
571
650
  nodeTotals() {
@@ -824,6 +903,7 @@ export default {
824
903
  },
825
904
 
826
905
  isHarvesterIncompatible() {
906
+ const CompareVersion = '<v1.2';
827
907
  let ccmRke2Version = (this.chartVersions['harvester-cloud-provider'] || {})['version'];
828
908
  let csiRke2Version = (this.chartVersions['harvester-csi-driver'] || {})['version'];
829
909
 
@@ -839,8 +919,12 @@ export default {
839
919
  }
840
920
 
841
921
  if (ccmVersion && csiVersion) {
842
- if (semver.satisfies(ccmRke2Version, ccmVersion) &&
843
- semver.satisfies(csiRke2Version, csiVersion)) {
922
+ if (semver.satisfies(this.harvesterVersion, CompareVersion) || !(this.harvesterVersion || '').startsWith('v')) {
923
+ // When harveste version is less than `CompareVersion`, compatibility is not determined,
924
+ // At the same time, version numbers like this will not be checked: master-14bbee2c-head
925
+ return false;
926
+ } else if (semver.satisfies(ccmRke2Version, ccmVersion) &&
927
+ semver.satisfies(csiRke2Version, csiVersion)) {
844
928
  return false;
845
929
  } else {
846
930
  return true;
@@ -849,6 +933,19 @@ export default {
849
933
  return false;
850
934
  }
851
935
  },
936
+
937
+ displayInvalidPspsBanner() {
938
+ const version = VERSION.parse(this.value.spec.kubernetesVersion);
939
+
940
+ const major = parseInt(version?.[0] || 0);
941
+ const minor = parseInt(version?.[1] || 0);
942
+
943
+ if (major === 1 && minor >= 25) {
944
+ return this.allPSPs?.length > 0;
945
+ }
946
+
947
+ return false;
948
+ }
852
949
  },
853
950
 
854
951
  watch: {
@@ -943,8 +1040,16 @@ export default {
943
1040
 
944
1041
  if ( existing?.length ) {
945
1042
  for ( const pool of existing ) {
946
- const type = `${ CAPI.MACHINE_CONFIG_GROUP }.${ pool.machineConfigRef.kind.toLowerCase() }`;
1043
+ let type;
1044
+
1045
+ if (this.isElementalCluster) {
1046
+ type = ELEMENTAL_SCHEMA_IDS.MACHINE_INV_SELECTOR_TEMPLATES;
1047
+ } else {
1048
+ type = `${ CAPI.MACHINE_CONFIG_GROUP }.${ pool.machineConfigRef.kind.toLowerCase() }`;
1049
+ }
1050
+
947
1051
  let config;
1052
+ let configMissing = false;
948
1053
 
949
1054
  if ( this.$store.getters['management/canList'](type) ) {
950
1055
  try {
@@ -954,6 +1059,12 @@ export default {
954
1059
  });
955
1060
  } catch (e) {
956
1061
  // Some users can't see the config, that's ok.
1062
+ // we will display a banner for a 404 only for elemental
1063
+ if (e?.status === 404) {
1064
+ if (this.isElementalCluster) {
1065
+ configMissing = true;
1066
+ }
1067
+ }
957
1068
  }
958
1069
  }
959
1070
 
@@ -967,6 +1078,7 @@ export default {
967
1078
  update: true,
968
1079
  pool: clone(pool),
969
1080
  config: config ? await this.$store.dispatch('management/clone', { resource: config }) : null,
1081
+ configMissing
970
1082
  });
971
1083
  }
972
1084
  }
@@ -1014,6 +1126,11 @@ export default {
1014
1126
  if (this.provider === 'vmwarevsphere') {
1015
1127
  pool.pool.machineOS = 'linux';
1016
1128
  }
1129
+
1130
+ if (this.isElementalCluster) {
1131
+ pool.pool.machineConfigRef.apiVersion = `${ this.machineConfigSchema.attributes.group }/${ this.machineConfigSchema.attributes.version }`;
1132
+ }
1133
+
1017
1134
  this.machinePools.push(pool);
1018
1135
 
1019
1136
  this.$nextTick(() => {
@@ -1086,6 +1203,11 @@ export default {
1086
1203
  entry.config = await entry.config.save();
1087
1204
  }
1088
1205
 
1206
+ // Ensure Elemental clusters have a hostname prefix
1207
+ if (this.isElementalCluster && !entry.pool.hostnamePrefix ) {
1208
+ entry.pool.hostnamePrefix = `${ prefix }-`;
1209
+ }
1210
+
1089
1211
  finalPools.push(entry.pool);
1090
1212
  }
1091
1213
 
@@ -1111,7 +1233,7 @@ export default {
1111
1233
  },
1112
1234
 
1113
1235
  validationPassed() {
1114
- return (this.provider === 'custom' || !!this.credentialId);
1236
+ return (this.provider === 'custom' || this.isElementalCluster || !!this.credentialId);
1115
1237
  },
1116
1238
 
1117
1239
  cancelCredential() {
@@ -1205,6 +1327,7 @@ export default {
1205
1327
  url: `/k8s/clusters/${ clusterId }/v1/harvester/kubeconfig`,
1206
1328
  method: 'POST',
1207
1329
  data: {
1330
+ csiClusterRoleName: 'harvesterhci.io:csi-driver',
1208
1331
  clusterRoleName: 'harvesterhci.io:cloudprovider',
1209
1332
  namespace,
1210
1333
  serviceAccountName: this.value.metadata.name,
@@ -1393,13 +1516,23 @@ export default {
1393
1516
  },
1394
1517
 
1395
1518
  async initRegistry() {
1396
- let registryMode = PUBLIC;
1397
- let registryHost = this.agentConfig?.['system-default-registry'] || '';
1398
- let registrySecret = null;
1399
- let regs = this.rkeConfig.registries;
1519
+ // Check for an existing cluster scoped registry
1520
+ const clusterRegistry = this.agentConfig?.['system-default-registry'] || '';
1400
1521
 
1522
+ // Check for the global registry
1401
1523
  this.systemRegistry = (await this.$store.dispatch('management/find', { type: MANAGEMENT.SETTING, id: SETTING.SYSTEM_DEFAULT_REGISTRY })).value || '';
1402
1524
 
1525
+ // The order of precedence is to use the cluster scoped registry
1526
+ // if it exists, then use the global scoped registry as a fallback
1527
+ if (clusterRegistry) {
1528
+ this.registryHost = clusterRegistry;
1529
+ } else {
1530
+ this.registryHost = this.systemRegistry;
1531
+ }
1532
+
1533
+ let registrySecret = null;
1534
+ let regs = this.rkeConfig.registries;
1535
+
1403
1536
  if ( !regs ) {
1404
1537
  regs = {};
1405
1538
  set(this.rkeConfig, 'registries', regs);
@@ -1413,75 +1546,85 @@ export default {
1413
1546
  set(regs, 'mirrors', {});
1414
1547
  }
1415
1548
 
1416
- if ( registryHost ) {
1417
- registryMode = PRIVATE;
1418
- } else if ( this.systemRegistry ) {
1419
- registryHost = this.systemRegistry;
1420
- registryMode = PRIVATE;
1549
+ const hostname = Object.keys(regs.configs)[0];
1550
+ const config = regs.configs[hostname];
1551
+
1552
+ if ( config ) {
1553
+ registrySecret = config.authConfigSecretName;
1421
1554
  }
1422
1555
 
1423
- if ( Object.keys(regs.mirrors || {}).length || Object.keys(regs.configs || {}).length > 1 ) {
1424
- registryMode = ADVANCED;
1425
- } else {
1426
- const hostname = Object.keys(regs.configs)[0];
1427
- const config = regs.configs[hostname];
1556
+ this.registrySecret = registrySecret;
1428
1557
 
1429
- if ( config ) {
1430
- if ( hostname !== registryHost || config.caBundle || config.insecureSkipVerify || config.tlsSecretName ) {
1431
- registryMode = ADVANCED;
1432
- } else {
1433
- registryMode = PRIVATE;
1434
- registrySecret = config.authConfigSecretName;
1435
- }
1558
+ const hasMirrorsOrAuthConfig = Object.keys(regs.configs).length > 0 || Object.keys(regs.mirrors).length > 0;
1559
+
1560
+ if (this.registryHost || registrySecret || hasMirrorsOrAuthConfig) {
1561
+ this.showCustomRegistryInput = true;
1562
+
1563
+ if (hasMirrorsOrAuthConfig) {
1564
+ this.showCustomRegistryAdvancedInput = true;
1436
1565
  }
1437
1566
  }
1438
-
1439
- this.registryHost = registryHost;
1440
- this.registryMode = registryMode;
1441
- this.registrySecret = registrySecret;
1442
1567
  },
1443
1568
 
1444
1569
  setRegistryConfig() {
1445
1570
  const hostname = (this.registryHost || '').trim();
1446
1571
 
1447
- if ( this.registryMode === PUBLIC ) {
1448
- if ( this.systemRegistry ) {
1449
- // Empty string overrides the system default to nothing
1450
- set(this.agentConfig, 'system-default-registry', '');
1451
- } else {
1452
- // No need to set anything
1453
- set(this.agentConfig, 'system-default-registry', undefined);
1454
- }
1455
- } else if ( !hostname || hostname === this.systemRegistry ) {
1572
+ if ( this.systemRegistry ) {
1573
+ // Empty string overrides the system default to nothing
1574
+ set(this.agentConfig, 'system-default-registry', '');
1575
+ } else {
1576
+ // No need to set anything
1577
+ set(this.agentConfig, 'system-default-registry', undefined);
1578
+ }
1579
+ if ( !hostname || hostname === this.systemRegistry ) {
1456
1580
  // Undefined removes the key which uses the global setting without hardcoding it into the config
1457
1581
  set(this.agentConfig, 'system-default-registry', undefined);
1458
1582
  } else {
1459
1583
  set(this.agentConfig, 'system-default-registry', hostname);
1460
1584
  }
1461
1585
 
1462
- if ( this.registryMode === ADVANCED ) {
1463
- // Leave it alone...
1464
- } else if ( this.registryMode === PRIVATE ) {
1465
- set(this.rkeConfig.registries, 'mirrors', {});
1586
+ if ( hostname && this.registrySecret ) {
1587
+ // For a registry with basic auth, but no mirrors,
1588
+ // add a single registry config with the basic auth secret.
1589
+ const basicAuthConfig = {
1590
+ [hostname]: {
1591
+ authConfigSecretName: this.registrySecret,
1592
+ caBundle: null,
1593
+ insecureSkipVerify: false,
1594
+ tlsSecretName: null,
1595
+ }
1596
+ };
1466
1597
 
1467
- if ( this.registrySecret ) {
1468
- set(this.rkeConfig.registries, 'configs', {
1469
- [hostname]: {
1470
- authConfigSecretName: this.registrySecret,
1471
- caBundle: null,
1472
- insecureSkipVerify: false,
1473
- tlsSecretName: null,
1474
- }
1475
- });
1598
+ const rkeConfig = this.value.spec.rkeConfig;
1599
+
1600
+ if (!rkeConfig) {
1601
+ this.value.spec.rkeConfig = { registries: { configs: basicAuthConfig } };
1602
+ } else if (rkeConfig.registries.configs && Object.keys(rkeConfig.registries.configs).length > 0) {
1603
+ // If some existing authentication secrets are already configured
1604
+ // for registry mirrors, the basic auth is added to the existing ones.
1605
+ const existingConfigs = rkeConfig.registries.configs;
1606
+
1607
+ this.value.spec.rkeConfig.registries.configs = { ...basicAuthConfig, ...existingConfigs };
1476
1608
  } else {
1477
- set(this.rkeConfig.registries, 'configs', {});
1609
+ const existingMirrorAndAuthConfig = this.value.spec.rkeConfig.registries;
1610
+
1611
+ this.value.spec.rkeConfig.registries = {
1612
+ ...existingMirrorAndAuthConfig,
1613
+ configs: basicAuthConfig
1614
+ };
1478
1615
  }
1479
- } else {
1480
- set(this.rkeConfig.registries, 'configs', {});
1481
- set(this.rkeConfig.registries, 'mirrors', {});
1482
1616
  }
1483
1617
  },
1484
1618
 
1619
+ updateConfigs(configs) {
1620
+ // Update authentication configuration
1621
+ // for each mirror
1622
+ if (!this.value.spec?.rkeConfig) {
1623
+ this.value.spec.rkeConfig = { registries: {} };
1624
+ }
1625
+ set(this.value.spec.rkeConfig.registries, 'configs', configs);
1626
+ },
1627
+
1485
1628
  getAllOptionsAfterMinVersion(versions, minVersion, defaultVersion) {
1486
1629
  const out = (versions || []).filter(obj => !!obj.serverArgs).map((obj) => {
1487
1630
  let disabled = false;
@@ -1614,7 +1757,10 @@ export default {
1614
1757
  const res = await this.$store.dispatch('cluster/request', { url: `${ url }/${ HCI.SETTING }s` });
1615
1758
 
1616
1759
  const version = (res?.data || []).find(s => s.id === 'harvester-csi-ccm-versions');
1760
+ // get harvester server-version
1761
+ const serverVersion = (res?.data || []).find(s => s.id === 'server-version');
1617
1762
 
1763
+ this.harvesterVersion = serverVersion.value;
1618
1764
  if (version) {
1619
1765
  this.harvesterVersionRange = JSON.parse(version.value || version.default || '{}');
1620
1766
  } else {
@@ -1623,6 +1769,59 @@ export default {
1623
1769
  }
1624
1770
  this.setHarvesterDefaultCloudProvider();
1625
1771
  },
1772
+ toggleCustomRegistry(e) {
1773
+ if (this.registryHost) {
1774
+ this.registryHost = null;
1775
+ this.registrySecret = null;
1776
+ } else {
1777
+ this.initRegistry();
1778
+ }
1779
+ },
1780
+ updateCisProfile() {
1781
+ // If the user selects any Worker CIS Profile,
1782
+ // protect-kernel-defaults should be set to false
1783
+ // in the RKE2 worker/agent config.
1784
+ const selectedCisProfile = this.agentConfig?.profile;
1785
+
1786
+ if (selectedCisProfile) {
1787
+ set(this.agentConfig, 'protect-kernel-defaults', true);
1788
+ } else {
1789
+ set(this.agentConfig, 'protect-kernel-defaults', false);
1790
+ }
1791
+ },
1792
+
1793
+ /**
1794
+ * Handle k8s changes side effects, like PSP and PSA resets
1795
+ */
1796
+ handleKubernetesChange(value) {
1797
+ if (value) {
1798
+ const version = VERSION.parse(value);
1799
+ const major = parseInt(version?.[0] || 0);
1800
+ const minor = parseInt(version?.[1] || 0);
1801
+
1802
+ // Reset PSA if not RKE2
1803
+ if (!value.includes('rke2')) {
1804
+ set(this.value.spec, 'defaultPodSecurityPolicyTemplateName', '');
1805
+ } else {
1806
+ // Reset PSP if it's legacy due k8s version 1.25+
1807
+ if (major === 1 && minor >= 25) {
1808
+ set(this.value.spec, 'defaultPodSecurityPolicyTemplateName', '');
1809
+ } else {
1810
+ set(this.value.spec, 'defaultPodSecurityPolicyTemplateName', this.lastDefaultPodSecurityPolicyTemplateName);
1811
+ }
1812
+
1813
+ this.previousKubernetesVersion = value;
1814
+ }
1815
+ }
1816
+ },
1817
+
1818
+ /**
1819
+ * Keep last PSP value
1820
+ */
1821
+ handlePspChange(value) {
1822
+ this.lastDefaultPodSecurityPolicyTemplateName = value;
1823
+ },
1824
+
1626
1825
  },
1627
1826
  };
1628
1827
  </script>
@@ -1652,12 +1851,14 @@ export default {
1652
1851
  @cancel="cancel"
1653
1852
  @error="fvUnreportedValidationErrors"
1654
1853
  >
1655
- <Banner
1656
- v-if="isEdit"
1657
- color="warning"
1658
- >
1659
- <span v-html="t('cluster.banner.rke2-k3-reprovisioning', {}, true)" />
1660
- </Banner>
1854
+ <div class="header-warnings">
1855
+ <Banner
1856
+ v-if="isEdit"
1857
+ color="warning"
1858
+ >
1859
+ <span v-html="t('cluster.banner.rke2-k3-reprovisioning', {}, true)" />
1860
+ </Banner>
1861
+ </div>
1661
1862
  <SelectCredential
1662
1863
  v-if="needCredential"
1663
1864
  v-model="credentialId"
@@ -1690,6 +1891,7 @@ export default {
1690
1891
  {{ appsOSWarning }}
1691
1892
  </Banner>
1692
1893
 
1894
+ <!-- Pools Extras -->
1693
1895
  <template v-if="hasMachinePools">
1694
1896
  <div class="clearfix">
1695
1897
  <h2
@@ -1723,6 +1925,7 @@ export default {
1723
1925
  </div>
1724
1926
  </div>
1725
1927
 
1928
+ <!-- Extra Tabs for Machine Pool -->
1726
1929
  <Tabbed
1727
1930
  ref="pools"
1728
1931
  :side-tabs="true"
@@ -1752,17 +1955,19 @@ export default {
1752
1955
  </Tab>
1753
1956
  </template>
1754
1957
  <div v-if="!unremovedMachinePools.length">
1755
- You do not have any machine pools defined, click the plus to add one.
1958
+ {{ t('cluster.machinePool.noPoolsDisclaimer') }}
1756
1959
  </div>
1757
1960
  </Tabbed>
1758
1961
  <div class="spacer" />
1759
1962
  </template>
1760
1963
 
1964
+ <!-- Cluster Tabs -->
1761
1965
  <h2 v-t="'cluster.tabs.cluster'" />
1762
1966
  <Tabbed
1763
1967
  :side-tabs="true"
1764
1968
  class="min-height"
1765
1969
  >
1970
+ <!-- Basic -->
1766
1971
  <Tab
1767
1972
  name="basic"
1768
1973
  label-key="cluster.tabs.basic"
@@ -1772,7 +1977,7 @@ export default {
1772
1977
  <Banner
1773
1978
  v-if="!haveArgInfo"
1774
1979
  color="warning"
1775
- label="Configuration information is not available for the selected Kubernetes version. The options available in this screen will be limited, you may want to use the YAML editor."
1980
+ :label="t('cluster.banner.haveArgInfo')"
1776
1981
  />
1777
1982
  <Banner
1778
1983
  v-if="showk8s21LegacyWarning"
@@ -1794,6 +1999,7 @@ export default {
1794
1999
  :mode="mode"
1795
2000
  :options="versionOptions"
1796
2001
  label-key="cluster.kubernetesVersion.label"
2002
+ @input="handleKubernetesChange($event)"
1797
2003
  />
1798
2004
  <Checkbox
1799
2005
  v-model="showDeprecatedPatchVersions"
@@ -1868,16 +2074,56 @@ export default {
1868
2074
  <h3>
1869
2075
  {{ t('cluster.rke2.security.header') }}
1870
2076
  </h3>
1871
- <div class="row">
2077
+ <Banner
2078
+ v-if="isEdit && displayInvalidPspsBanner"
2079
+ color="warning"
2080
+ >
2081
+ <span v-html="t('cluster.banner.invalidPsps', {}, true)" />
2082
+ </Banner>
2083
+ <Banner
2084
+ v-else-if="isCreate && !needsPSP"
2085
+ color="info"
2086
+ >
2087
+ <span v-html="t('cluster.banner.removedPsp', {}, true)" />
2088
+ </Banner>
2089
+ <Banner
2090
+ v-else-if="isCreate"
2091
+ color="info"
2092
+ >
2093
+ <span v-html="t('cluster.banner.deprecatedPsp', {}, true)" />
2094
+ </Banner>
2095
+ <div
2096
+ v-if="needsPSA"
2097
+ class="row mb-10"
2098
+ >
1872
2099
  <div class="col span-6">
2100
+ <!-- PSA template selector -->
2101
+ <LabeledSelect
2102
+ v-model="value.spec.defaultPodSecurityAdmissionConfigurationTemplateName"
2103
+ :mode="mode"
2104
+ data-testid="rke2-custom-edit-psa"
2105
+ :options="psaOptions"
2106
+ :label="t('cluster.rke2.defaultPodSecurityAdmissionConfigurationTemplateName.label')"
2107
+ />
2108
+ </div>
2109
+ </div>
2110
+
2111
+ <div class="row">
2112
+ <div
2113
+ v-if="pspOptions && needsPSP"
2114
+ class="col span-6"
2115
+ >
2116
+ <!-- PSP template selector -->
1873
2117
  <LabeledSelect
1874
- v-if="pspOptions"
1875
2118
  v-model="value.spec.defaultPodSecurityPolicyTemplateName"
2119
+ data-testid="rke2-custom-edit-psp"
1876
2120
  :mode="mode"
1877
2121
  :options="pspOptions"
1878
2122
  :label="t('cluster.rke2.defaultPodSecurityPolicyTemplateName.label')"
2123
+ @input="handlePspChange($event)"
1879
2124
  />
1880
2125
  </div>
2126
+
1881
2127
  <div
1882
2128
  v-if="showCisProfile"
1883
2129
  class="col span-6"
@@ -1894,7 +2140,8 @@ export default {
1894
2140
  v-model="agentConfig.profile"
1895
2141
  :mode="mode"
1896
2142
  :options="profileOptions"
1897
- label="Worker CIS Profile"
2143
+ :label="t('cis.workerProfile')"
2144
+ @input="updateCisProfile"
1898
2145
  />
1899
2146
  </div>
1900
2147
  </div>
@@ -1951,6 +2198,7 @@ export default {
1951
2198
  </div>
1952
2199
  </Tab>
1953
2200
 
2201
+ <!-- Member Roles -->
1954
2202
  <Tab
1955
2203
  v-if="canManageMembers"
1956
2204
  name="memberRoles"
@@ -1970,6 +2218,7 @@ export default {
1970
2218
  />
1971
2219
  </Tab>
1972
2220
 
2221
+ <!-- etcd -->
1973
2222
  <Tab
1974
2223
  name="etcd"
1975
2224
  label-key="cluster.tabs.etcd"
@@ -2047,6 +2296,7 @@ export default {
2047
2296
  </div>
2048
2297
  </Tab>
2049
2298
 
2299
+ <!-- Networking -->
2050
2300
  <Tab
2051
2301
  v-if="haveArgInfo"
2052
2302
  name="networking"
@@ -2148,6 +2398,7 @@ export default {
2148
2398
  />
2149
2399
  </Tab>
2150
2400
 
2401
+ <!-- Upgrade -->
2151
2402
  <Tab
2152
2403
  name="upgrade"
2153
2404
  label-key="cluster.tabs.upgrade"
@@ -2192,55 +2443,91 @@ export default {
2192
2443
  </div>
2193
2444
  </Tab>
2194
2445
 
2446
+ <!-- Registries -->
2195
2447
  <Tab
2196
2448
  name="registry"
2197
2449
  label-key="cluster.tabs.registry"
2198
2450
  >
2199
- <RadioGroup
2200
- v-model="registryMode"
2201
- name="registry-mode"
2202
- :options="registryOptions"
2203
- :mode="mode"
2204
- />
2205
-
2206
- <LabeledInput
2207
- v-if="registryMode !== PUBLIC"
2208
- v-model="registryHost"
2209
- class="mt-20"
2210
- :mode="mode"
2211
- :required="true"
2212
- :label="t('cluster.privateRegistry.systemDefaultRegistry.label')"
2213
- />
2214
-
2215
- <SelectOrCreateAuthSecret
2216
- v-if="registryMode === PRIVATE"
2217
- v-model="registrySecret"
2218
- :register-before-hook="registerBeforeHook"
2219
- :hook-priority="1"
2220
- :mode="mode"
2221
- in-store="management"
2222
- :allow-ssh="false"
2223
- :allow-rke="true"
2224
- :vertical="true"
2225
- :namespace="value.metadata.namespace"
2226
- generate-name="registryconfig-auth-"
2227
- />
2228
- <template v-else-if="registryMode === ADVANCED">
2229
- <RegistryMirrors
2230
- v-model="value"
2231
- class="mt-20"
2232
- :mode="mode"
2233
- />
2234
-
2235
- <RegistryConfigs
2236
- v-model="value"
2237
- class="mt-20"
2238
- :mode="mode"
2239
- :cluster-register-before-hook="registerBeforeHook"
2451
+ <div class="row">
2452
+ <h3>Registry for Rancher System Container Images</h3>
2453
+ </div>
2454
+ <div class="row">
2455
+ <div class="col span-12">
2456
+ <Banner
2457
+ :closable="false"
2458
+ class="cluster-tools-tip"
2459
+ color="info"
2460
+ label-key="cluster.privateRegistry.description"
2461
+ />
2462
+ </div>
2463
+ </div>
2464
+ <div class="row">
2465
+ <Checkbox
2466
+ v-model="showCustomRegistryInput"
2467
+ class="mb-20"
2468
+ :label="t('cluster.privateRegistry.label')"
2469
+ @input="toggleCustomRegistry"
2240
2470
  />
2471
+ </div>
2472
+ <div
2473
+ v-if="showCustomRegistryInput"
2474
+ class="row"
2475
+ >
2476
+ <div class="col span-6">
2477
+ <LabeledInput
2478
+ v-model="registryHost"
2479
+ label-key="catalog.chart.registry.custom.inputLabel"
2480
+ placeholder-key="catalog.chart.registry.custom.placeholder"
2481
+ :min-height="30"
2482
+ />
2483
+ <SelectOrCreateAuthSecret
2484
+ v-model="registrySecret"
2485
+ :register-before-hook="registerBeforeHook"
2486
+ :hook-priority="1"
2487
+ :mode="mode"
2488
+ in-store="management"
2489
+ :allow-ssh="false"
2490
+ :allow-rke="true"
2491
+ :vertical="true"
2492
+ :namespace="value.metadata.namespace"
2493
+ generate-name="registryconfig-auth-"
2494
+ />
2495
+ </div>
2496
+ </div>
2497
+ <template>
2498
+ <div
2499
+ v-if="showCustomRegistryInput"
2500
+ class="row"
2501
+ >
2502
+ <AdvancedSection
2503
+ class="col span-12 advanced"
2504
+ :is-open-by-default="showCustomRegistryAdvancedInput"
2505
+ :mode="mode"
2506
+ >
2507
+ <Banner
2508
+ :closable="false"
2509
+ class="cluster-tools-tip"
2510
+ color="info"
2511
+ :label-key="isK3s ? 'cluster.privateRegistry.docsLinkK3s' : 'cluster.privateRegistry.docsLinkRke2'"
2512
+ />
2513
+ <RegistryMirrors
2514
+ v-model="value"
2515
+ class="mt-20"
2516
+ :mode="mode"
2517
+ />
2518
+ <RegistryConfigs
2519
+ v-model="value"
2520
+ class="mt-20"
2521
+ :mode="mode"
2522
+ :cluster-register-before-hook="registerBeforeHook"
2523
+ @updateConfigs="updateConfigs"
2524
+ />
2525
+ </AdvancedSection>
2526
+ </div>
2241
2527
  </template>
2242
2528
  </Tab>
2243
2529
 
2530
+ <!-- Add-on Config -->
2244
2531
  <Tab
2245
2532
  name="addons"
2246
2533
  label-key="cluster.tabs.addons"
@@ -2304,6 +2591,7 @@ export default {
2304
2591
  </div>
2305
2592
  </Tab>
2306
2593
 
2594
+ <!-- Advanced -->
2307
2595
  <Tab
2308
2596
  v-if="haveArgInfo || agentArgs['protect-kernel-defaults']"
2309
2597
  name="advanced"
@@ -2420,4 +2708,7 @@ export default {
2420
2708
  .patch-version {
2421
2709
  margin-top: 5px;
2422
2710
  }
2711
+ .header-warnings .banner {
2712
+ margin-bottom: 0;
2713
+ }
2423
2714
  </style>