@rancher/shell 0.5.3 → 2.0.0

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 (581) hide show
  1. package/assets/data/aws-regions.json +9 -0
  2. package/assets/images/vendor/openid.svg +18 -0
  3. package/assets/styles/app.scss +1 -2
  4. package/assets/styles/fonts/_icons.scss +3 -3
  5. package/assets/styles/global/_columns.scss +1 -1
  6. package/assets/styles/global/_labeled-input.scss +2 -0
  7. package/assets/styles/themes/_csp.scss +2 -2
  8. package/assets/styles/themes/_dark.scss +8 -2
  9. package/assets/styles/themes/_light.scss +2 -1
  10. package/assets/styles/themes/_suse.scss +1 -1
  11. package/assets/styles/vendor/vue-select.scss +5 -0
  12. package/assets/translations/en-us.yaml +296 -58
  13. package/assets/translations/zh-hans.yaml +5 -27
  14. package/babel.config.js +1 -1
  15. package/chart/__tests__/S3.test.ts +9 -2
  16. package/chart/monitoring/grafana/index.vue +6 -2
  17. package/chart/monitoring/prometheus/index.vue +2 -2
  18. package/chart/rancher-backup/S3.vue +11 -9
  19. package/chart/rancher-backup/index.vue +15 -5
  20. package/cloud-credential/__tests__/harvester.test.ts +18 -0
  21. package/cloud-credential/generic.vue +18 -9
  22. package/cloud-credential/harvester.vue +11 -3
  23. package/components/AppModal.vue +167 -0
  24. package/components/AssignTo.vue +7 -4
  25. package/components/AsyncButton.vue +18 -5
  26. package/components/BackLink.vue +4 -4
  27. package/components/BannerGraphic.vue +1 -0
  28. package/components/BrandImage.vue +47 -1
  29. package/components/Carousel.vue +14 -8
  30. package/components/Certificates.vue +8 -11
  31. package/components/ClusterBadge.vue +12 -3
  32. package/components/ClusterIconMenu.vue +44 -16
  33. package/components/ClusterProviderIcon.vue +14 -3
  34. package/components/CodeMirror.vue +73 -38
  35. package/components/CommunityLinks.vue +12 -8
  36. package/components/CreateDriver.vue +81 -0
  37. package/components/CruResource.vue +51 -27
  38. package/components/DetailTop.vue +2 -2
  39. package/components/Dialog.vue +6 -5
  40. package/components/DisableAuthProviderModal.vue +14 -8
  41. package/components/DraggableZone.vue +2 -2
  42. package/components/ExplorerMembers.vue +3 -3
  43. package/components/ExplorerProjectsNamespaces.vue +6 -6
  44. package/components/FixedBanner.vue +47 -36
  45. package/components/GlobalRoleBindings.vue +26 -0
  46. package/components/Import.vue +10 -6
  47. package/components/Inactivity.vue +1 -5
  48. package/components/KeyValueView.vue +14 -10
  49. package/components/MessageLink.vue +2 -2
  50. package/components/ModalWithCard.vue +5 -8
  51. package/components/MoveModal.vue +35 -33
  52. package/components/PodSecurityAdmission.vue +3 -3
  53. package/components/PromptChangePassword.vue +33 -33
  54. package/components/PromptModal.vue +11 -21
  55. package/components/PromptRemove.vue +11 -17
  56. package/components/PromptRestore.vue +18 -16
  57. package/components/Questions/__tests__/Boolean.test.ts +9 -19
  58. package/components/Questions/__tests__/Float.test.ts +9 -19
  59. package/components/Questions/__tests__/Int.test.ts +9 -19
  60. package/components/Questions/__tests__/String.test.ts +9 -19
  61. package/components/Questions/__tests__/Yaml.test.ts +9 -20
  62. package/components/Questions/__tests__/utils/questions-defaults.ts +20 -0
  63. package/components/Questions/index.vue +18 -2
  64. package/components/ResourceCancelModal.vue +34 -29
  65. package/components/ResourceDetail/Masthead.vue +23 -7
  66. package/components/ResourceDetail/index.vue +5 -0
  67. package/components/ResourceList/Masthead.vue +28 -10
  68. package/components/ResourceList/index.vue +65 -14
  69. package/components/ResourceTable.vue +73 -19
  70. package/components/ResourceYaml.vue +1 -0
  71. package/components/SelectIconGrid.vue +3 -3
  72. package/components/SideNav.vue +15 -37
  73. package/components/SingleClusterInfo.vue +4 -4
  74. package/components/SortableTable/THead.vue +26 -12
  75. package/components/SortableTable/filtering.js +9 -1
  76. package/components/SortableTable/grouping.js +8 -1
  77. package/components/SortableTable/index.vue +142 -42
  78. package/components/SortableTable/paging.js +36 -7
  79. package/components/SortableTable/selection.js +2 -1
  80. package/components/SortableTable/sorting.js +24 -7
  81. package/components/TabTitle.vue +84 -0
  82. package/components/Tabbed/index.vue +6 -1
  83. package/components/TableDataUserIcon.vue +47 -0
  84. package/components/TypeDescription.vue +1 -0
  85. package/components/Wizard.vue +1 -0
  86. package/components/__tests__/AppModal.test.ts +98 -0
  87. package/components/__tests__/AsyncButton.test.ts +1 -3
  88. package/components/__tests__/BackLink.test.ts +1 -1
  89. package/components/__tests__/ButtonGroup.test.ts +3 -6
  90. package/components/__tests__/Carousel.test.ts +43 -0
  91. package/components/__tests__/Certificates.test.ts +29 -0
  92. package/components/__tests__/{CodeMirror.spec.ts → CodeMirror.test.ts} +5 -17
  93. package/components/__tests__/CruResource.test.ts +10 -9
  94. package/components/__tests__/EtcdInfoBanner.test.ts +37 -0
  95. package/components/__tests__/FixedBanner.test.ts +5 -20
  96. package/components/__tests__/NamespaceFilter.test.ts +9 -18
  97. package/components/__tests__/TabTitle.test.ts +129 -0
  98. package/components/auth/AzureWarning.vue +2 -2
  99. package/components/auth/RoleDetailEdit.vue +10 -0
  100. package/components/auth/__tests__/RoleDetailEdit.test.ts +3 -2
  101. package/components/auth/login/oidc.vue +7 -1
  102. package/components/fleet/FleetClusters.vue +9 -9
  103. package/components/fleet/FleetIntro.vue +11 -17
  104. package/components/fleet/FleetNoWorkspaces.vue +2 -2
  105. package/components/fleet/FleetRepos.vue +1 -0
  106. package/components/fleet/ForceDirectedTreeChart/index.vue +9 -3
  107. package/components/form/ArrayList.vue +30 -19
  108. package/components/form/ArrayListSelect.vue +9 -4
  109. package/components/form/ClusterAppearance.vue +132 -0
  110. package/components/form/ColorInput.vue +1 -0
  111. package/components/form/Error.vue +3 -3
  112. package/components/form/Footer.vue +2 -2
  113. package/components/form/GitPicker.vue +83 -38
  114. package/components/form/KeyValue.vue +67 -48
  115. package/components/form/LabeledSelect.vue +143 -43
  116. package/components/form/Labels.vue +3 -1
  117. package/components/form/NameNsDescription.vue +26 -9
  118. package/components/form/ResourceLabeledSelect.vue +187 -0
  119. package/components/form/ResourceTabs/index.vue +31 -15
  120. package/components/form/SecretSelector.vue +93 -18
  121. package/components/form/Select.vue +1 -1
  122. package/components/form/SelectOrCreateAuthSecret.vue +135 -62
  123. package/components/form/SimpleSecretSelector.vue +88 -28
  124. package/components/form/__tests__/BannerSettings.test.ts +53 -0
  125. package/components/form/__tests__/KeyValue.test.ts +121 -12
  126. package/components/form/__tests__/LabeledSelect.test.ts +0 -18
  127. package/components/form/__tests__/NameNsDescription.test.ts +25 -15
  128. package/components/form/labeled-select-utils/labeled-select-pagination.ts +151 -0
  129. package/components/form/labeled-select-utils/labeled-select.utils.ts +122 -0
  130. package/components/formatter/AppSummaryGraph.vue +2 -2
  131. package/components/formatter/CloudCredPublicData.vue +30 -0
  132. package/components/formatter/ClusterLink.vue +2 -2
  133. package/components/formatter/FleetSummaryGraph.vue +2 -1
  134. package/components/formatter/ImagePercentageBar.vue +0 -4
  135. package/components/formatter/IngressTarget.vue +18 -7
  136. package/components/formatter/Link.vue +2 -2
  137. package/components/formatter/LinkDetail.vue +2 -2
  138. package/components/formatter/LinkDetailImage.vue +2 -2
  139. package/components/formatter/LinkName.vue +2 -2
  140. package/components/formatter/LiveDate.vue +16 -0
  141. package/components/formatter/PrincipalGroupBindings.vue +2 -2
  142. package/components/formatter/SecretType.vue +2 -2
  143. package/components/formatter/VirtualServiceGateways.vue +2 -2
  144. package/components/formatter/__tests__/LinkDetail.test.ts +5 -5
  145. package/components/nav/Group.vue +7 -5
  146. package/components/nav/Header.vue +82 -43
  147. package/components/nav/NamespaceFilter.vue +8 -1
  148. package/components/nav/TopLevelMenu.vue +336 -125
  149. package/components/nav/Type.vue +58 -102
  150. package/components/nav/__tests__/TopLevelMenu.test.ts +370 -9
  151. package/components/nav/__tests__/Type.test.ts +321 -126
  152. package/components/nuxt/nuxt-child.js +0 -5
  153. package/components/nuxt/nuxt-error.vue +1 -1
  154. package/components/nuxt/nuxt-link.client.js +13 -95
  155. package/components/templates/default.vue +3 -3
  156. package/components/templates/error.vue +6 -10
  157. package/components/templates/standalone.vue +0 -4
  158. package/components/templates/unauthenticated.vue +1 -2
  159. package/components/user.retention/user-retention-header.vue +34 -0
  160. package/composables/useCompactInput.test.ts +36 -0
  161. package/composables/useCompactInput.ts +2 -2
  162. package/composables/useI18n.ts +26 -0
  163. package/composables/useLabeledFormElement.test.ts +135 -0
  164. package/composables/useStore.ts +16 -0
  165. package/config/home-links.js +32 -1
  166. package/config/labels-annotations.js +2 -1
  167. package/config/middleware.js +0 -6
  168. package/config/pagination-table-headers.js +57 -0
  169. package/config/pod-security-admission.ts +1 -1
  170. package/config/private-label.js +1 -3
  171. package/config/product/auth.js +1 -0
  172. package/config/product/explorer.js +167 -46
  173. package/config/product/legacy.js +3 -95
  174. package/config/product/manager.js +44 -11
  175. package/config/query-params.js +1 -0
  176. package/config/roles.ts +23 -0
  177. package/config/router/index.js +23 -0
  178. package/config/router/navigation-guards/attempt-first-login.js +73 -0
  179. package/config/router/navigation-guards/authentication.js +63 -0
  180. package/config/router/navigation-guards/index.js +15 -0
  181. package/config/router/navigation-guards/load-initial-settings.js +15 -0
  182. package/config/router/routes.js +487 -0
  183. package/config/settings.ts +38 -2
  184. package/config/store.js +7 -3
  185. package/config/table-headers.js +46 -1
  186. package/config/types.js +36 -16
  187. package/config/uiplugins.js +10 -5
  188. package/core/plugin-helpers.js +1 -1
  189. package/core/plugin.ts +2 -1
  190. package/core/plugins.js +289 -282
  191. package/creators/app/files/.eslintignore +0 -2
  192. package/creators/app/files/.vscode/settings.json +0 -1
  193. package/creators/pkg/files/.github/workflows/build-extension-catalog.yml +2 -6
  194. package/creators/pkg/files/.github/workflows/build-extension-charts.yml +2 -6
  195. package/creators/pkg/init +32 -0
  196. package/detail/__tests__/service.test.ts +62 -0
  197. package/detail/catalog.cattle.io.app.vue +1 -1
  198. package/detail/cis.cattle.io.clusterscan.vue +14 -3
  199. package/detail/fleet.cattle.io.gitrepo.vue +15 -9
  200. package/detail/namespace.vue +2 -2
  201. package/detail/networking.k8s.io.ingress.vue +52 -19
  202. package/detail/node.vue +20 -43
  203. package/detail/pod.vue +1 -68
  204. package/detail/provisioning.cattle.io.cluster.vue +2 -1
  205. package/detail/service.vue +1 -1
  206. package/detail/workload/index.vue +2 -15
  207. package/dialog/AddCustomBadgeDialog.vue +318 -161
  208. package/dialog/DeactivateDriverDialog.vue +118 -0
  209. package/dialog/RollbackWorkloadDialog.vue +2 -2
  210. package/dialog/RotateCertificatesDialog.vue +0 -21
  211. package/directives/clean-html.js +15 -0
  212. package/directives/clean-tooltip.js +32 -0
  213. package/directives/focus.js +41 -0
  214. package/directives/int-number.js +21 -0
  215. package/directives/positive-int-number.js +19 -0
  216. package/directives/trim-whitespace.js +19 -0
  217. package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +3 -2
  218. package/edit/__tests__/kontainerDriver.test.ts +107 -0
  219. package/edit/__tests__/management.cattle.io.clusterroletemplatebinding.test.ts +12 -1
  220. package/edit/__tests__/management.cattle.io.setting.test.ts +2 -1
  221. package/edit/__tests__/monitoring.coreos.com.prometheusrule.test.ts +2 -3
  222. package/edit/__tests__/nodeDriver.test.ts +107 -0
  223. package/edit/__tests__/service.test.ts +1 -5
  224. package/edit/__tests__/ui.cattle.io.navlink.test.ts +3 -1
  225. package/edit/auth/AuthProviderWarningBanners.vue +34 -0
  226. package/edit/auth/__tests__/AuthProviderWarningBanners.test.ts +19 -0
  227. package/edit/auth/__tests__/azuread.test.ts +241 -0
  228. package/edit/auth/__tests__/oidc.test.ts +137 -0
  229. package/edit/auth/azuread.vue +133 -31
  230. package/edit/auth/github.vue +5 -17
  231. package/edit/auth/googleoauth.vue +5 -18
  232. package/edit/auth/ldap/index.vue +5 -17
  233. package/edit/auth/oidc.vue +143 -42
  234. package/edit/auth/saml.vue +5 -14
  235. package/edit/catalog.cattle.io.clusterrepo.vue +175 -20
  236. package/edit/cis.cattle.io.clusterscan.vue +5 -2
  237. package/edit/cis.cattle.io.clusterscanbenchmark.vue +41 -9
  238. package/edit/cloudcredential.vue +26 -4
  239. package/edit/configmap.vue +10 -4
  240. package/edit/fleet.cattle.io.gitrepo.vue +7 -4
  241. package/edit/helm.cattle.io.projecthelmchart.vue +29 -19
  242. package/edit/kontainerDriver.vue +65 -0
  243. package/edit/logging-flow/Match.vue +10 -9
  244. package/edit/logging-flow/index.vue +4 -19
  245. package/edit/logging.banzaicloud.io.output/__tests__/logging.banzaicloud.io.output.test.ts +232 -2
  246. package/edit/logging.banzaicloud.io.output/index.vue +43 -26
  247. package/edit/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +3 -3
  248. package/edit/management.cattle.io.project.vue +2 -1
  249. package/edit/management.cattle.io.setting.vue +20 -0
  250. package/edit/management.cattle.io.user.vue +2 -1
  251. package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +10 -7
  252. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +21 -16
  253. package/edit/monitoring.coreos.com.alertmanagerconfig/types/pagerduty.vue +1 -0
  254. package/edit/monitoring.coreos.com.prometheusrule/AlertingRule.vue +3 -0
  255. package/edit/monitoring.coreos.com.prometheusrule/GroupRules.vue +2 -0
  256. package/edit/monitoring.coreos.com.prometheusrule/RecordingRule.vue +2 -0
  257. package/edit/monitoring.coreos.com.prometheusrule/index.vue +2 -0
  258. package/edit/networking.k8s.io.ingress/Rules.vue +8 -3
  259. package/edit/networking.k8s.io.ingress/index.vue +64 -8
  260. package/edit/networking.k8s.io.networkpolicy/PolicyRule.vue +1 -0
  261. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +6 -2
  262. package/edit/networking.k8s.io.networkpolicy/__tests__/{PolicyRuleTarget.spec.ts → PolicyRuleTarget.test.ts} +45 -6
  263. package/edit/networking.k8s.io.networkpolicy/__tests__/utils/selectors.test.ts +1 -1
  264. package/edit/networking.k8s.io.networkpolicy/index.vue +2 -0
  265. package/edit/nodeDriver.vue +65 -0
  266. package/edit/persistentvolume/index.vue +2 -2
  267. package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +18 -9
  268. package/edit/provisioning.cattle.io.cluster/__tests__/Advanced.test.ts +165 -1
  269. package/edit/provisioning.cattle.io.cluster/__tests__/Basics.test.ts +1 -1
  270. package/edit/provisioning.cattle.io.cluster/__tests__/CustomCommand.test.ts +0 -3
  271. package/edit/provisioning.cattle.io.cluster/__tests__/DirectoryConfig.test.ts +228 -0
  272. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +70 -12
  273. package/edit/provisioning.cattle.io.cluster/__tests__/utils/cluster.ts +5 -0
  274. package/edit/provisioning.cattle.io.cluster/import.vue +2 -2
  275. package/edit/provisioning.cattle.io.cluster/index.vue +21 -15
  276. package/edit/provisioning.cattle.io.cluster/rke2.vue +185 -114
  277. package/edit/provisioning.cattle.io.cluster/tabs/Advanced.vue +67 -7
  278. package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +19 -6
  279. package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +132 -0
  280. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +7 -0
  281. package/edit/provisioning.cattle.io.cluster/tabs/etcd/S3Config.vue +1 -0
  282. package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +1 -0
  283. package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +3 -0
  284. package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +1 -0
  285. package/edit/resources.cattle.io.backup.vue +139 -124
  286. package/edit/resources.cattle.io.restore.vue +146 -126
  287. package/edit/service.vue +1 -0
  288. package/edit/serviceaccount.vue +46 -4
  289. package/edit/workload/__tests__/Job.test.ts +1 -3
  290. package/edit/workload/__tests__/Upgrading.test.ts +2 -2
  291. package/edit/workload/mixins/workload.js +34 -1
  292. package/edit/workload/storage/emptyDir.vue +2 -2
  293. package/initialize/App.vue +75 -0
  294. package/initialize/app-extended.js +128 -0
  295. package/initialize/entry-helpers.js +549 -0
  296. package/initialize/entry.js +32 -0
  297. package/initialize/install-components.js +23 -0
  298. package/initialize/install-directives.js +59 -0
  299. package/initialize/install-plugins.js +123 -0
  300. package/list/__tests__/workload.test.ts +1 -1
  301. package/list/cis.cattle.io.clusterscan.vue +16 -10
  302. package/list/group.principal.vue +2 -2
  303. package/list/management.cattle.io.feature.vue +11 -7
  304. package/list/management.cattle.io.user.vue +36 -3
  305. package/list/networking.k8s.io.ingress.vue +36 -0
  306. package/list/node.vue +211 -73
  307. package/list/provisioning.cattle.io.cluster.vue +17 -4
  308. package/list/ui.cattle.io.navlink.vue +2 -2
  309. package/list/workload.vue +22 -0
  310. package/machine-config/__tests__/vmwarevsphere-pool-config-merge.test.ts +30 -0
  311. package/machine-config/__tests__/vmwarevsphere.test.ts +162 -59
  312. package/machine-config/amazonec2.vue +1 -1
  313. package/machine-config/azure.vue +38 -21
  314. package/machine-config/generic.vue +11 -15
  315. package/machine-config/vmwarevsphere-pool-config-merge.ts +25 -0
  316. package/machine-config/vmwarevsphere.vue +20 -11
  317. package/middleware/authenticated.js +9 -361
  318. package/mixins/__tests__/chart.test.ts +48 -6
  319. package/mixins/__tests__/create-edit-view.test.ts +2 -3
  320. package/mixins/auth-config.js +3 -2
  321. package/mixins/brand.js +75 -57
  322. package/mixins/chart.js +27 -13
  323. package/mixins/create-edit-view/index.js +2 -2
  324. package/mixins/fetch.client.js +42 -48
  325. package/mixins/labeled-form-element.ts +21 -1
  326. package/mixins/page-actions.js +7 -5
  327. package/mixins/resource-fetch-api-pagination.js +304 -0
  328. package/mixins/resource-fetch-namespaced.js +1 -1
  329. package/mixins/resource-fetch.js +46 -5
  330. package/models/__tests__/cluster.test.ts +44 -0
  331. package/models/__tests__/fleet.cattle.io.cluster.test.ts +36 -0
  332. package/models/__tests__/schema.tests.ts +24 -0
  333. package/models/__tests__/steve-schema.test.ts +73 -0
  334. package/models/__tests__/workload.test.ts +1 -1
  335. package/models/catalog.cattle.io.app.js +8 -0
  336. package/models/catalog.cattle.io.clusterrepo.js +9 -1
  337. package/models/catalog.cattle.io.uiplugin.js +7 -8
  338. package/models/cis.cattle.io.clusterscan.js +29 -8
  339. package/models/cloudcredential.js +9 -1
  340. package/models/cluster/node.js +4 -0
  341. package/models/cluster/schema.js +6 -0
  342. package/models/cluster.js +33 -0
  343. package/models/driver.js +62 -0
  344. package/models/fleet.cattle.io.cluster.js +23 -11
  345. package/models/fleet.cattle.io.gitrepo.js +10 -0
  346. package/models/helm.cattle.io.projecthelmchart.js +1 -1
  347. package/models/kontainerdriver.js +68 -0
  348. package/models/management/schema.js +6 -0
  349. package/models/management.cattle.io.authconfig.js +3 -2
  350. package/models/management.cattle.io.cluster.js +5 -4
  351. package/models/management.cattle.io.globalrole.js +2 -0
  352. package/models/management.cattle.io.user.js +67 -2
  353. package/models/monitoring.coreos.com.receiver.js +3 -1
  354. package/models/monitoring.coreos.com.route.js +1 -1
  355. package/models/networking.k8s.io.ingress.js +2 -1
  356. package/models/nodedriver.js +68 -0
  357. package/models/provisioning.cattle.io.cluster.js +34 -1
  358. package/models/schema.js +28 -7
  359. package/models/service.js +2 -0
  360. package/models/steve-schema.ts +254 -0
  361. package/models/workload.js +1 -0
  362. package/package.json +6 -5
  363. package/pages/about.vue +12 -5
  364. package/pages/account/index.vue +7 -2
  365. package/pages/auth/login.vue +106 -102
  366. package/pages/auth/logout.vue +2 -2
  367. package/pages/auth/setup.vue +57 -64
  368. package/pages/auth/verify.vue +17 -17
  369. package/pages/c/_cluster/apps/charts/chart.vue +54 -9
  370. package/pages/c/_cluster/apps/charts/index.vue +37 -13
  371. package/pages/c/_cluster/apps/charts/install.vue +4 -4
  372. package/pages/c/_cluster/auth/config/_id.vue +0 -6
  373. package/pages/c/_cluster/auth/config/index.vue +15 -9
  374. package/pages/c/_cluster/auth/roles/index.vue +8 -10
  375. package/pages/c/_cluster/auth/user.retention/index.vue +384 -0
  376. package/pages/c/_cluster/explorer/ConfigBadge.vue +13 -8
  377. package/pages/c/_cluster/explorer/EventsTable.vue +18 -0
  378. package/pages/c/_cluster/explorer/__tests__/index.test.ts +181 -0
  379. package/pages/c/_cluster/explorer/index.vue +231 -72
  380. package/pages/c/_cluster/explorer/tools/__tests__/index.test.ts +69 -0
  381. package/pages/c/_cluster/explorer/tools/index.vue +12 -176
  382. package/pages/c/_cluster/fleet/index.vue +88 -93
  383. package/pages/c/_cluster/longhorn/__tests__/longhorn.index.test.ts +89 -0
  384. package/pages/c/_cluster/longhorn/index.vue +52 -17
  385. package/pages/c/_cluster/manager/cloudCredential/index.vue +18 -25
  386. package/pages/c/_cluster/manager/drivers/kontainerDriver/_id.vue +12 -0
  387. package/pages/c/_cluster/manager/drivers/kontainerDriver/create.vue +15 -0
  388. package/pages/c/_cluster/manager/drivers/kontainerDriver/index.vue +94 -0
  389. package/pages/c/_cluster/manager/drivers/nodeDriver/_id.vue +12 -0
  390. package/pages/c/_cluster/manager/drivers/nodeDriver/create.vue +15 -0
  391. package/pages/c/_cluster/manager/drivers/nodeDriver/index.vue +63 -0
  392. package/pages/c/_cluster/manager/jwt.authentication/index.vue +235 -0
  393. package/pages/c/_cluster/monitoring/alertmanagerconfig/_alertmanagerconfigid/receiver.vue +4 -0
  394. package/pages/c/_cluster/monitoring/index.vue +1 -17
  395. package/pages/c/_cluster/monitoring/route-receiver/index.vue +2 -2
  396. package/pages/c/_cluster/neuvector/index.vue +1 -0
  397. package/pages/c/_cluster/settings/DefaultLinksEditor.vue +1 -0
  398. package/pages/c/_cluster/settings/banners.vue +86 -8
  399. package/pages/c/_cluster/settings/brand.vue +258 -36
  400. package/pages/c/_cluster/settings/index.vue +4 -4
  401. package/pages/c/_cluster/settings/links.vue +5 -3
  402. package/pages/c/_cluster/settings/performance.vue +71 -2
  403. package/pages/c/_cluster/uiplugins/AddExtensionRepos.vue +5 -2
  404. package/pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue +10 -7
  405. package/pages/c/_cluster/uiplugins/CatalogList/CatalogUninstallDialog.vue +9 -6
  406. package/pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue +11 -5
  407. package/pages/c/_cluster/uiplugins/InstallDialog.vue +53 -18
  408. package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +36 -301
  409. package/pages/c/_cluster/uiplugins/UninstallDialog.vue +14 -6
  410. package/pages/c/_cluster/uiplugins/__tests__/SetupUIPlugins.test.ts +52 -106
  411. package/pages/c/_cluster/uiplugins/index.vue +38 -52
  412. package/pages/diagnostic.vue +1 -0
  413. package/pages/fail-whale.vue +103 -41
  414. package/pages/home.vue +81 -24
  415. package/pages/prefs.vue +8 -3
  416. package/pages/support/index.vue +12 -2
  417. package/plugins/clean-html-directive.js +5 -12
  418. package/plugins/clean-tooltip-directive.js +6 -31
  419. package/plugins/codemirror.js +0 -9
  420. package/plugins/dashboard-store/__tests__/mutations.test.ts +296 -313
  421. package/plugins/dashboard-store/actions.js +140 -32
  422. package/plugins/dashboard-store/getters.js +86 -39
  423. package/plugins/dashboard-store/index.js +0 -99
  424. package/plugins/dashboard-store/mutations.js +150 -48
  425. package/plugins/dashboard-store/resource-class.js +14 -109
  426. package/plugins/directives.js +6 -39
  427. package/plugins/ember-cookie.js +13 -0
  428. package/plugins/global-formatters.js +26 -5
  429. package/plugins/i18n.js +90 -56
  430. package/plugins/int-number.js +6 -20
  431. package/plugins/plugin.js +3 -3
  432. package/plugins/positive-int-number.js +6 -17
  433. package/plugins/steve/__tests__/{getters.spec.ts → getters.test.ts} +124 -31
  434. package/plugins/steve/__tests__/mutations.test.ts +49 -0
  435. package/plugins/steve/__tests__/subscribe.spec.ts +109 -0
  436. package/plugins/steve/__tests__/utils/mutation.test.helpers.ts +105 -0
  437. package/plugins/steve/accept-or-reject-socket-message.ts +103 -0
  438. package/plugins/steve/actions.js +0 -1
  439. package/plugins/steve/getters.js +183 -63
  440. package/plugins/steve/hybrid-class.js +5 -1
  441. package/plugins/steve/mutations.js +29 -5
  442. package/plugins/steve/norman-class.js +123 -2
  443. package/{utils → plugins/steve}/projectAndNamespaceFiltering.utils.ts +28 -10
  444. package/plugins/steve/schema.d.ts +22 -0
  445. package/plugins/steve/steve-pagination-utils.ts +368 -0
  446. package/plugins/steve/subscribe.js +37 -75
  447. package/plugins/trim-whitespace.js +6 -34
  448. package/plugins/vue-js-modal.js +1 -1
  449. package/public/index.html +1 -0
  450. package/rancher-components/Accordion/Accordion.vue +3 -2
  451. package/rancher-components/BadgeState/BadgeState.vue +3 -3
  452. package/rancher-components/Banner/Banner.test.ts +1 -5
  453. package/rancher-components/Banner/Banner.vue +2 -2
  454. package/rancher-components/Card/Card.vue +4 -4
  455. package/rancher-components/Form/Checkbox/Checkbox.vue +4 -3
  456. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +1 -1
  457. package/rancher-components/Form/LabeledInput/LabeledInput.vue +66 -30
  458. package/rancher-components/Form/Radio/RadioButton.test.ts +1 -3
  459. package/rancher-components/Form/Radio/RadioButton.vue +13 -7
  460. package/rancher-components/Form/Radio/RadioGroup.vue +4 -3
  461. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +7 -5
  462. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +7 -4
  463. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +9 -4
  464. package/rancher-components/StringList/StringList.vue +8 -8
  465. package/rancher-components/components/Accordion/Accordion.vue +3 -2
  466. package/rancher-components/components/BadgeState/BadgeState.vue +3 -3
  467. package/rancher-components/components/Banner/Banner.test.ts +1 -5
  468. package/rancher-components/components/Banner/Banner.vue +2 -2
  469. package/rancher-components/components/Card/Card.vue +4 -4
  470. package/rancher-components/components/Form/Checkbox/Checkbox.vue +4 -3
  471. package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +1 -1
  472. package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +66 -30
  473. package/rancher-components/components/Form/Radio/RadioButton.test.ts +1 -3
  474. package/rancher-components/components/Form/Radio/RadioButton.vue +13 -7
  475. package/rancher-components/components/Form/Radio/RadioGroup.vue +4 -3
  476. package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +7 -5
  477. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.vue +7 -4
  478. package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +9 -4
  479. package/rancher-components/components/StringList/StringList.vue +8 -8
  480. package/scripts/.gitlab/workflows/build-extension-catalog.gitlab-ci.yml +27 -8
  481. package/scripts/clean +1 -1
  482. package/scripts/extension/helm/charts/ui-plugin-server/templates/_helpers.tpl +11 -0
  483. package/scripts/extension/helm/charts/ui-plugin-server/templates/cr.yaml +2 -0
  484. package/scripts/extension/helm/charts/ui-plugin-server/values.yaml +2 -0
  485. package/scripts/extension/helm/package/Dockerfile +1 -1
  486. package/scripts/extension/helm/scripts/patch +27 -0
  487. package/scripts/extension/publish +6 -6
  488. package/scripts/serve-pkgs +0 -2
  489. package/scripts/test-plugins-build.sh +6 -6
  490. package/scripts/vue-migrate.js +683 -0
  491. package/store/__tests__/catalog.test.ts +224 -0
  492. package/store/auth.js +23 -4
  493. package/store/aws.js +53 -6
  494. package/store/catalog.js +21 -5
  495. package/store/cru-resource.ts +26 -0
  496. package/store/customisation.js +35 -0
  497. package/store/features.js +6 -4
  498. package/store/index.js +132 -39
  499. package/store/plugins.js +8 -4
  500. package/store/type-map.js +143 -143
  501. package/store/type-map.utils.ts +226 -0
  502. package/tsconfig.json +0 -1
  503. package/tsconfig.paths.json +4 -1
  504. package/types/components/labeledSelect.ts +50 -0
  505. package/types/resources/settings.d.ts +32 -0
  506. package/types/{userPreferences.d.ts → resources/userPreferences.d.ts} +0 -1
  507. package/types/shell/index.d.ts +996 -782
  508. package/types/store/dashboard-store.types.ts +42 -0
  509. package/types/store/pagination.types.ts +457 -0
  510. package/types/store/type-map.ts +30 -0
  511. package/types/store/vuex.d.ts +9 -0
  512. package/types/vue-shim.d.ts +51 -0
  513. package/utils/__tests__/cluster.test.ts +20 -18
  514. package/utils/__tests__/create-yaml.test.ts +359 -2
  515. package/utils/__tests__/kontainer.test.ts +92 -0
  516. package/utils/__tests__/pod-security-admission.test.ts +1 -1
  517. package/utils/alertmanagerconfig.js +19 -0
  518. package/utils/array.ts +40 -1
  519. package/utils/async.ts +2 -0
  520. package/utils/auth.js +152 -4
  521. package/utils/axios.js +2 -2
  522. package/utils/banners.js +103 -0
  523. package/utils/cluster.js +1 -1
  524. package/utils/config.js +4 -0
  525. package/utils/create-yaml.js +54 -27
  526. package/utils/error.js +25 -0
  527. package/utils/formatter.js +5 -3
  528. package/utils/git.ts +1 -1
  529. package/utils/install-redirect.js +1 -1
  530. package/utils/kontainer.ts +186 -0
  531. package/utils/monitoring.js +2 -37
  532. package/utils/pagination-utils.ts +154 -0
  533. package/utils/pod-security-admission.ts +1 -1
  534. package/utils/router.js +86 -0
  535. package/utils/settings.ts +46 -0
  536. package/utils/socket.js +1 -0
  537. package/utils/time.js +1 -0
  538. package/utils/title.ts +3 -0
  539. package/utils/unit-tests/ChildRenderingRouterLinkStub.ts +36 -0
  540. package/utils/validators/formRules/__tests__/index.test.ts +21 -0
  541. package/utils/validators/formRules/index.ts +3 -0
  542. package/utils/validators/index.js +1 -0
  543. package/vue.config.js +376 -421
  544. package/assets/styles/vendor/vue-js-modal.scss +0 -16
  545. package/chart/monitoring/steps/uninstall-v1.vue +0 -135
  546. package/components/EventsTable.vue +0 -67
  547. package/components/TabbedLinks/index.vue +0 -94
  548. package/components/nuxt/nuxt-link.server.js +0 -16
  549. package/components/nuxt/nuxt.js +0 -101
  550. package/config/router.js +0 -425
  551. package/initialize/App.js +0 -152
  552. package/initialize/client.js +0 -734
  553. package/initialize/index.js +0 -287
  554. package/middleware/i18n.js +0 -10
  555. package/middleware/unauthenticated.js +0 -22
  556. package/mixins/v1-workload-metrics.js +0 -43
  557. package/pages/c/_cluster/apps/index.vue +0 -15
  558. package/pages/c/_cluster/auth/index.vue +0 -17
  559. package/pages/c/_cluster/index.vue +0 -15
  560. package/pages/c/_cluster/legacy/index.vue +0 -22
  561. package/pages/c/_cluster/manager/index.vue +0 -22
  562. package/pages/c/_cluster/mcapps/index.vue +0 -21
  563. package/pages/c/_cluster/uiplugins/RemoveUIPlugins.vue +0 -232
  564. package/plugins/dashboard-store/rehydrate-all.js +0 -44
  565. package/plugins/index.js +0 -11
  566. package/plugins/portal-vue.js +0 -4
  567. package/plugins/portal.js +0 -4
  568. package/plugins/resize.js +0 -5
  569. package/plugins/shortkey.js +0 -4
  570. package/plugins/tooltip.js +0 -4
  571. package/plugins/v-select.js +0 -4
  572. package/utils/group.js +0 -70
  573. package/utils/nuxt.js +0 -638
  574. package/utils/router.scrollBehavior.js +0 -78
  575. /package/components/__tests__/{Collapse.spec.ts → Collapse.test.ts} +0 -0
  576. /package/models/__tests__/{node.ts → node.test.ts} +0 -0
  577. /package/plugins/steve/__tests__/{header-warnings.spec.ts → header-warnings.test.ts} +0 -0
  578. /package/plugins/steve/__tests__/{steve-class.spec.ts → steve-class.test.ts} +0 -0
  579. /package/rancher-components/BadgeState/{BadgeState.spec.ts → BadgeState.test.ts} +0 -0
  580. /package/rancher-components/components/BadgeState/{BadgeState.spec.ts → BadgeState.test.ts} +0 -0
  581. /package/types/{pod-security-admission.ts → resources/pod-security-admission.ts} +0 -0
@@ -1,73 +1,102 @@
1
1
  import { mount } from '@vue/test-utils';
2
2
  import vmwarevsphere, { DEFAULT_VALUES, SENTINEL } from '@shell/machine-config/vmwarevsphere.vue';
3
- import { cleanHtmlDirective } from '@shell/plugins/clean-html-directive';
4
3
 
5
4
  describe('component: vmwarevsphere', () => {
6
5
  const defaultGetters = { 'i18n/t': jest.fn().mockImplementation((key: string) => key) };
7
- const defaultSetup = {
6
+ const poolId = 'poolId';
7
+ const baseSetup = {
8
8
  propsData: {
9
- poolId: 'poolId',
9
+ poolId,
10
10
  credentialId: 'credentialId',
11
11
  disabled: false,
12
- mode: 'create',
13
- value: { initted: false },
14
12
  provider: 'vmwarevsphere'
15
13
  },
16
14
  mocks: {
17
15
  $fetchState: { pending: false },
18
16
  $store: { getters: defaultGetters },
19
17
  },
20
- stubs: { CodeMirror: true },
21
- directives: { cleanHtmlDirective }
18
+ stubs: { CodeMirror: true },
19
+ };
20
+ const defaultCreateSetup = {
21
+ ...baseSetup,
22
+ propsData: {
23
+ ...baseSetup.propsData,
24
+ mode: 'create',
25
+ poolCreateMode: true,
26
+ value: { initted: false },
27
+ }
28
+ };
29
+ const defaultEditSetup = {
30
+ ...baseSetup,
31
+ propsData: {
32
+ ...baseSetup.propsData,
33
+ mode: 'edit',
34
+ poolCreateMode: false,
35
+ value: { initted: false },
36
+ }
37
+ };
38
+ const editModeWithPoolInCreateModeSetup = {
39
+ ...defaultEditSetup,
40
+ propsData: {
41
+ ...defaultEditSetup.propsData,
42
+ poolCreateMode: true
43
+ }
22
44
  };
23
45
 
24
- it('should mount successfully with correct default values', () => {
25
- const wrapper = mount(vmwarevsphere, defaultSetup);
26
-
27
- const dataCenterElement = wrapper.find(`[data-testid="datacenter"]`).element;
28
- const resourcePoolElement = wrapper.find(`[data-testid="resourcePool"]`).element;
29
- const dataStoreElement = wrapper.find(`[data-testid="dataStore"]`).element;
30
- const folderElement = wrapper.find(`[data-testid="folder"]`).element;
31
- const hostElement = wrapper.find(`[data-testid="host"]`).element;
32
- const gracefulShutdownTimeoutElement = wrapper.find(`[data-testid="gracefulShutdownTimeout"]`).element;
33
-
34
- expect(dataCenterElement).toBeDefined();
35
- expect(resourcePoolElement).toBeDefined();
36
- expect(dataStoreElement).toBeDefined();
37
- expect(folderElement).toBeDefined();
38
- expect(hostElement).toBeDefined();
39
- expect(gracefulShutdownTimeoutElement).toBeDefined();
40
-
41
- const {
42
- cpuCount: defaultCpuCount,
43
- diskSize: defaultDiskSize,
44
- memorySize: defaultMemorySize,
45
- hostsystem: defaultHostsystem,
46
- cloudConfig: defaultCloudConfig,
47
- gracefulShutdownTimeout: defaultGracefulShutdownTimeout,
48
- cfgparam: defaultCfgparam,
49
- os: defaultOs
50
- } = DEFAULT_VALUES;
51
-
52
- const {
53
- cpuCount,
54
- diskSize,
55
- memorySize,
56
- hostsystem,
57
- cloudConfig,
58
- gracefulShutdownTimeout,
59
- cfgparam,
60
- os
61
- } = wrapper.vm.$options.propsData.value;
62
-
63
- expect(cpuCount).toStrictEqual(defaultCpuCount);
64
- expect(diskSize).toStrictEqual(defaultDiskSize);
65
- expect(memorySize).toStrictEqual(defaultMemorySize);
66
- expect(hostsystem).toStrictEqual(defaultHostsystem);
67
- expect(cloudConfig).toStrictEqual(defaultCloudConfig);
68
- expect(gracefulShutdownTimeout).toStrictEqual(defaultGracefulShutdownTimeout);
69
- expect(cfgparam).toStrictEqual(defaultCfgparam);
70
- expect(os).toStrictEqual(defaultOs);
46
+ describe('default values', () => {
47
+ const testCases = [
48
+ defaultCreateSetup,
49
+ editModeWithPoolInCreateModeSetup
50
+ ];
51
+
52
+ it.each(testCases)('should mount successfully with correct default values', (setup) => {
53
+ const wrapper = mount(vmwarevsphere, setup);
54
+
55
+ const dataCenterElement = wrapper.find(`[data-testid="datacenter"]`).element;
56
+ const resourcePoolElement = wrapper.find(`[data-testid="resourcePool"]`).element;
57
+ const dataStoreElement = wrapper.find(`[data-testid="dataStore"]`).element;
58
+ const folderElement = wrapper.find(`[data-testid="folder"]`).element;
59
+ const hostElement = wrapper.find(`[data-testid="host"]`).element;
60
+ const gracefulShutdownTimeoutElement = wrapper.find(`[data-testid="gracefulShutdownTimeout"]`).element;
61
+
62
+ expect(dataCenterElement).toBeDefined();
63
+ expect(resourcePoolElement).toBeDefined();
64
+ expect(dataStoreElement).toBeDefined();
65
+ expect(folderElement).toBeDefined();
66
+ expect(hostElement).toBeDefined();
67
+ expect(gracefulShutdownTimeoutElement).toBeDefined();
68
+
69
+ const {
70
+ cpuCount: defaultCpuCount,
71
+ diskSize: defaultDiskSize,
72
+ memorySize: defaultMemorySize,
73
+ hostsystem: defaultHostsystem,
74
+ cloudConfig: defaultCloudConfig,
75
+ gracefulShutdownTimeout: defaultGracefulShutdownTimeout,
76
+ cfgparam: defaultCfgparam,
77
+ os: defaultOs
78
+ } = DEFAULT_VALUES;
79
+
80
+ const {
81
+ cpuCount,
82
+ diskSize,
83
+ memorySize,
84
+ hostsystem,
85
+ cloudConfig,
86
+ gracefulShutdownTimeout,
87
+ cfgparam,
88
+ os
89
+ } = wrapper.vm.$options.propsData.value;
90
+
91
+ expect(cpuCount).toStrictEqual(defaultCpuCount);
92
+ expect(diskSize).toStrictEqual(defaultDiskSize);
93
+ expect(memorySize).toStrictEqual(defaultMemorySize);
94
+ expect(hostsystem).toStrictEqual(defaultHostsystem);
95
+ expect(cloudConfig).toStrictEqual(defaultCloudConfig);
96
+ expect(gracefulShutdownTimeout).toStrictEqual(defaultGracefulShutdownTimeout);
97
+ expect(cfgparam).toStrictEqual(defaultCfgparam);
98
+ expect(os).toStrictEqual(defaultOs);
99
+ });
71
100
  });
72
101
 
73
102
  describe('mapPathOptionsToContent', () => {
@@ -78,7 +107,7 @@ describe('component: vmwarevsphere', () => {
78
107
  ];
79
108
 
80
109
  it.each(testCases)('should generate label/value object without manipultion', (rawData, expected) => {
81
- const wrapper = mount(vmwarevsphere, defaultSetup);
110
+ const wrapper = mount(vmwarevsphere, defaultCreateSetup);
82
111
 
83
112
  expect(wrapper.vm.mapPathOptionsToContent(rawData)).toStrictEqual(expected);
84
113
  });
@@ -95,7 +124,7 @@ describe('component: vmwarevsphere', () => {
95
124
  ];
96
125
 
97
126
  it.each(testCases)('should generate label/value object for host options properly', (rawData, expected) => {
98
- const wrapper = mount(vmwarevsphere, defaultSetup);
127
+ const wrapper = mount(vmwarevsphere, defaultCreateSetup);
99
128
 
100
129
  expect(wrapper.vm.mapHostOptionsToContent(rawData)).toStrictEqual(expected);
101
130
  });
@@ -114,7 +143,7 @@ describe('component: vmwarevsphere', () => {
114
143
  ];
115
144
 
116
145
  it.each(testCases)('should generate label/value object for folder options properly', (rawData, expected) => {
117
- const wrapper = mount(vmwarevsphere, defaultSetup);
146
+ const wrapper = mount(vmwarevsphere, defaultCreateSetup);
118
147
 
119
148
  expect(wrapper.vm.mapFolderOptionsToContent(rawData)).toStrictEqual(expected);
120
149
  });
@@ -127,7 +156,7 @@ describe('component: vmwarevsphere', () => {
127
156
  ];
128
157
 
129
158
  it.each(testCases)('should generate label/value object for custom attributes options properly', (rawData, expected) => {
130
- const wrapper = mount(vmwarevsphere, defaultSetup);
159
+ const wrapper = mount(vmwarevsphere, defaultCreateSetup);
131
160
 
132
161
  expect(wrapper.vm.mapCustomAttributesToContent(rawData)).toStrictEqual(expected);
133
162
  });
@@ -143,9 +172,83 @@ describe('component: vmwarevsphere', () => {
143
172
  const expectedReslut = [{
144
173
  ...tag, label: `${ tag.category } / ${ tag.name }`, value: tag.id
145
174
  }];
146
- const wrapper = mount(vmwarevsphere, defaultSetup);
175
+ const wrapper = mount(vmwarevsphere, defaultCreateSetup);
147
176
 
148
177
  expect(wrapper.vm.mapTagsToContent([tag])).toStrictEqual(expectedReslut);
149
178
  });
150
179
  });
180
+
181
+ describe('resetValueIfNecessary', () => {
182
+ const hostsystemOptions = ['', '/Datacenter/host/Cluster/111.11.11.1'];
183
+ const folderOptions = ['', '/Datacenter/vm', '/Datacenter/vm/sub-folder'];
184
+ const contentLibraryOptions = ['', 'some-content-library'];
185
+ const networkOptions = ['', 'some-network'];
186
+ const tagOptions = ['', 'some-tag'];
187
+
188
+ it('should add errors to validationError collection when values are NOT in the options', () => {
189
+ const setup = {
190
+ ...defaultEditSetup,
191
+ propsData: {
192
+ ...defaultEditSetup.propsData,
193
+ value: {
194
+ ...defaultEditSetup.propsData.value,
195
+ hostsystem: 'something that is not included in the options',
196
+ folder: 'same as above',
197
+ constentLibrary: 'same as above'
198
+ }
199
+ }
200
+ };
201
+
202
+ const wrapper = mount(vmwarevsphere, setup);
203
+
204
+ const hostsystemContent = wrapper.vm.mapHostOptionsToContent(hostsystemOptions);
205
+ const folderContent = wrapper.vm.mapHostOptionsToContent(folderOptions);
206
+ const contentLibraryContent = wrapper.vm.mapPathOptionsToContent(contentLibraryOptions);
207
+
208
+ wrapper.vm.resetValueIfNecessary('hostsystem', hostsystemContent, hostsystemOptions);
209
+ wrapper.vm.resetValueIfNecessary('folder', folderContent, folderOptions);
210
+ wrapper.vm.resetValueIfNecessary('contentLibrary', contentLibraryContent, contentLibraryOptions);
211
+
212
+ expect(wrapper.vm.$data.validationErrors[poolId]).toContain('hostsystem');
213
+ expect(wrapper.vm.$data.validationErrors[poolId]).toContain('folder');
214
+ expect(wrapper.vm.$data.validationErrors[poolId]).toContain('contentLibrary');
215
+ });
216
+
217
+ describe('hostsystem, folder, contentLibrary, network and tag', () => {
218
+ const testCases = [null, ''];
219
+
220
+ it.each(testCases)('should NOT be added to validationError collection if they are null or ""', (data) => {
221
+ const setup = {
222
+ ...defaultEditSetup,
223
+ propsData: {
224
+ ...defaultEditSetup.propsData,
225
+ value: {
226
+ ...defaultEditSetup.propsData.value,
227
+ hostsystem: data,
228
+ folder: data,
229
+ contentLibrary: data,
230
+ network: [data],
231
+ tag: [data]
232
+ }
233
+ }
234
+ };
235
+
236
+ const wrapper = mount(vmwarevsphere, setup);
237
+
238
+ const hostsystemContent = wrapper.vm.mapHostOptionsToContent(hostsystemOptions);
239
+ const folderContent = wrapper.vm.mapHostOptionsToContent(folderOptions);
240
+ const contentLibraryContent = wrapper.vm.mapPathOptionsToContent(contentLibraryOptions);
241
+ const networkContent = wrapper.vm.mapPathOptionsToContent(networkOptions);
242
+ const tagContent = wrapper.vm.mapPathOptionsToContent(tagOptions);
243
+
244
+ wrapper.vm.resetValueIfNecessary('hostsystem', hostsystemContent, hostsystemOptions);
245
+ wrapper.vm.resetValueIfNecessary('folder', folderContent, folderOptions);
246
+ wrapper.vm.resetValueIfNecessary('contentLibrary', contentLibraryContent, contentLibraryOptions);
247
+ wrapper.vm.resetValueIfNecessary('network', networkContent, networkOptions, true);
248
+ wrapper.vm.resetValueIfNecessary('tag', tagContent, tagOptions, true);
249
+
250
+ expect(wrapper.vm.$data.validationErrors[poolId]).toBeUndefined();
251
+ });
252
+ });
253
+ });
151
254
  });
@@ -70,7 +70,7 @@ export default {
70
70
  this.kmsClient = await this.$store.dispatch('aws/kms', { region, cloudCredentialId: this.credentialId });
71
71
 
72
72
  if ( !this.instanceInfo ) {
73
- this.instanceInfo = await this.$store.dispatch('aws/instanceInfo', { client: this.ec2Client } );
73
+ this.instanceInfo = await this.$store.dispatch('aws/describeInstanceTypes', { client: this.ec2Client } );
74
74
  }
75
75
 
76
76
  const hash = {};
@@ -12,6 +12,8 @@ import { Checkbox } from '@components/Form/Checkbox';
12
12
  import ArrayList from '@shell/components/form/ArrayList';
13
13
  import { randomStr } from '@shell/utils/string';
14
14
  import { addParam, addParams } from '@shell/utils/url';
15
+ import { NORMAN } from '@shell/config/types';
16
+ import { findBy } from '@shell/utils/array';
15
17
  import KeyValue from '@shell/components/form/KeyValue';
16
18
  import { RadioGroup } from '@components/Form/Radio';
17
19
  import { _CREATE, _EDIT } from '@shell/config/query-params';
@@ -92,7 +94,6 @@ const storageTypes = [
92
94
  value: 'StandardSSD_LRS'
93
95
  }
94
96
  ];
95
- const DEFAULT_REGION = 'westus';
96
97
 
97
98
  export default {
98
99
  components: {
@@ -148,6 +149,12 @@ export default {
148
149
  }
149
150
  if (!isEmpty(environment)) {
150
151
  this.value.environment = environment;
152
+ } else if (this.loadedCredentialIdFor !== this.credentialId) {
153
+ this.allCredentials = await this.$store.dispatch('rancher/findAll', { type: NORMAN.CLOUD_CREDENTIAL });
154
+
155
+ const currentCredential = this.allCredentials.find((obj) => obj.id === this.credentialId);
156
+
157
+ this.value.environment = currentCredential.azurecredentialConfig.environment;
151
158
  }
152
159
  if (!isEmpty(subscriptionId)) {
153
160
  this.value.subscriptionId = subscriptionId;
@@ -156,19 +163,20 @@ export default {
156
163
  this.value.tenantId = tenantId;
157
164
  }
158
165
 
159
- this.locationOptions = await this.$store.dispatch('management/request', {
160
- url: addParam('/meta/aksLocations', 'cloudCredentialId', this.credentialId),
161
- method: 'GET',
162
- });
166
+ if (this.loadedCredentialIdFor !== this.credentialId) {
167
+ this.locationOptions = await this.$store.dispatch('management/request', {
168
+ url: addParam('/meta/aksLocations', 'cloudCredentialId', this.credentialId),
169
+ method: 'GET',
170
+ });
163
171
 
164
- if (this.mode === _CREATE) {
165
- this.value.location = DEFAULT_REGION;
172
+ this.loadedCredentialIdFor = this.credentialId;
173
+ }
166
174
 
167
175
  // when you edit an Azure cluster and add a new machine pool (edit)
168
176
  // the location field doesn't come populated which causes the vmSizes request
169
177
  // to return 200 but with a null response (also a bunch of other fields are undefined...)
170
178
  // so let's prefill them with the defaults
171
- } else if (this.mode === _EDIT && !this.value?.location) {
179
+ if (this.mode === _EDIT && !this.value?.location) {
172
180
  for (const key in this.defaultConfig) {
173
181
  if (this.value[key] === undefined) {
174
182
  this.$set(this.value, key, this.defaultConfig[key]);
@@ -176,6 +184,10 @@ export default {
176
184
  }
177
185
  }
178
186
 
187
+ if (!this.value.location || !findBy(this.locationOptions, 'name', this.value.location)) {
188
+ this.locationOptions?.length && this.setLocation(this.locationOptions[this.locationOptions.length - 1]);
189
+ }
190
+
179
191
  this.vmSizes = await this.$store.dispatch('management/request', {
180
192
  url: addParams('/meta/aksVMSizesV2', {
181
193
  cloudCredentialId: this.credentialId,
@@ -206,6 +218,8 @@ export default {
206
218
  useAvailabilitySet: false,
207
219
  vmSizes: [],
208
220
  valueCopy: this.value,
221
+
222
+ loadedCredentialIdFor: null
209
223
  };
210
224
  },
211
225
 
@@ -214,6 +228,10 @@ export default {
214
228
  this.$fetch();
215
229
  },
216
230
 
231
+ 'value.location'() {
232
+ this.$fetch();
233
+ },
234
+
217
235
  'value.availabilityZone'(neu) {
218
236
  if (neu && (!this.value.managedDisks || !this.value.enablePublicIpStandardSku || !this.value.staticPublicIp)) {
219
237
  this.$emit('expandAdvanced');
@@ -499,19 +517,6 @@ export default {
499
517
  </div>
500
518
  <div v-else>
501
519
  <div class="row mt-20">
502
- <div class="col span-6">
503
- <LabeledSelect
504
- v-model="value.environment"
505
- :mode="mode"
506
- :options="azureEnvironments"
507
- option-key="value"
508
- option-label="value"
509
- :searchable="false"
510
- :required="true"
511
- :label="t('cluster.machineConfig.azure.environment.label')"
512
- :disabled="disabled"
513
- />
514
- </div>
515
520
  <div class="col span-6">
516
521
  <LabeledSelect
517
522
  :value="value.location"
@@ -523,9 +528,21 @@ export default {
523
528
  :required="true"
524
529
  :label="t('cluster.machineConfig.azure.location.label')"
525
530
  :disabled="disabled"
531
+ data-testid="machineConfig-azure-location"
526
532
  @input="setLocation"
527
533
  />
528
534
  </div>
535
+ <div data-testid="machineConfig-azure-environment-value">
536
+ <label
537
+ v-clean-tooltip="t('cluster.machineConfig.azure.environment.tooltip')"
538
+ :style="{'display':'block'}"
539
+ class="text-label"
540
+ >
541
+ {{ t('cluster.machineConfig.azure.environment.label') }}
542
+ <i class="icon icon-sm icon-info" />
543
+ </label>
544
+ <span>{{ value.environment }}</span>
545
+ </div>
529
546
  </div>
530
547
  <div class="row mt-20">
531
548
  <div class="col span-4">
@@ -29,11 +29,11 @@ export default {
29
29
  },
30
30
  },
31
31
 
32
- fetch() {
32
+ async fetch() {
33
33
  this.errors = [];
34
34
 
35
35
  try {
36
- this.fields = this.$store.getters['plugins/fieldsForDriver'](this.provider);
36
+ this.fields = await this.$store.getters['plugins/fieldsForDriver'](this.provider);
37
37
  const name = `rke-machine-config.cattle.io.${ this.provider }config`;
38
38
 
39
39
  if ( !this.fields ) {
@@ -42,6 +42,15 @@ export default {
42
42
  } catch (e) {
43
43
  this.errors = exceptionToErrorsArray(e);
44
44
  }
45
+
46
+ const normanType = this.$store.getters['plugins/credentialFieldForDriver'](this.provider);
47
+ const normanSchema = this.$store.getters['rancher/schemaFor'](`${ normanType }credentialconfig`);
48
+
49
+ if ( normanSchema ) {
50
+ this.cloudCredentialKeys = Object.keys(normanSchema.resourceFields || {});
51
+ } else {
52
+ this.cloudCredentialKeys = await this.$store.getters['plugins/fieldNamesForDriver'](this.provider);
53
+ }
45
54
  },
46
55
 
47
56
  data() {
@@ -51,19 +60,6 @@ export default {
51
60
  };
52
61
  },
53
62
 
54
- computed: {
55
- cloudCredentialKeys() {
56
- const normanType = this.$store.getters['plugins/credentialFieldForDriver'](this.provider);
57
- const normanSchema = this.$store.getters['rancher/schemaFor'](`${ normanType }credentialconfig`);
58
-
59
- if ( normanSchema ) {
60
- return Object.keys(normanSchema.resourceFields || {});
61
- } else {
62
- return this.$store.getters['plugins/fieldNamesForDriver'](this.provider);
63
- }
64
- }
65
- },
66
-
67
63
  watch: {
68
64
  'credentialId'() {
69
65
  this.$fetch();
@@ -0,0 +1,25 @@
1
+ import mergeWith from 'lodash/mergeWith';
2
+
3
+ /**
4
+ * Helper function to alter Lodash merge function default behaviour on merging arrays while updating machine pool configuration.
5
+ *
6
+ * In rke2.vue, the syncMachineConfigWithLatest function updates machine pool configuration by
7
+ * merging the latest configuration received from the backend with the current configuration updated by the user.
8
+ * However, Lodash's merge function treats arrays like object so index values are merged and not appended to arrays
9
+ * resulting in undesired outcomes for us, Example:
10
+ *
11
+ * const lastSavedConfigFromBE = { a: ["test"] };
12
+ * const currentConfigByUser = { a: [] };
13
+ * merge(lastSavedConfigFromBE, currentConfigByUser); // returns { a: ["test"] }; but we expect { a: [] };
14
+ *
15
+ * More info: https://github.com/lodash/lodash/issues/1313
16
+ *
17
+ * This helper function addresses the issue by always replacing the old array with the new array during the merge process.
18
+ */
19
+ export function vspherePoolConfigMerge(obj1 = {}, obj2 = {}): Object {
20
+ return mergeWith(obj1, obj2, (obj1Value, obj2Value) => {
21
+ if (Array.isArray(obj1Value) && Array.isArray(obj2Value)) {
22
+ return obj2Value;
23
+ }
24
+ });
25
+ }
@@ -16,6 +16,7 @@ import { integerString, keyValueStrings } from '@shell/utils/computed';
16
16
  import { _CREATE, _EDIT, _VIEW } from '@shell/config/query-params';
17
17
 
18
18
  export const SENTINEL = '__SENTINEL__';
19
+ const NULLABLE_EMPTY_FIELDS = ['contentLibrary', 'folder', 'hostsystem'];
19
20
  const VAPP_MODE = {
20
21
  DISABLED: 'disabled',
21
22
  AUTO: 'auto',
@@ -168,7 +169,11 @@ export default {
168
169
  },
169
170
  disabled: {
170
171
  type: Boolean,
171
- default: false
172
+ default: false,
173
+ },
174
+ poolCreateMode: {
175
+ type: Boolean,
176
+ required: true,
172
177
  },
173
178
  },
174
179
 
@@ -223,7 +228,7 @@ export default {
223
228
  },
224
229
  ];
225
230
 
226
- if (this.mode === _CREATE && !this.value.initted) {
231
+ if ((this.mode === _CREATE || this.poolCreateMode) && !this.value.initted) {
227
232
  Object.defineProperty(this.value, 'initted', { value: true, enumerable: false });
228
233
 
229
234
  const {
@@ -444,13 +449,13 @@ export default {
444
449
  const valueInContent = content.find((c) => c.value === this.value.datacenter );
445
450
 
446
451
  if (!valueInContent) {
447
- if (this.mode === _CREATE) {
452
+ if (this.mode === _CREATE || this.poolCreateMode) {
448
453
  set(this.value, 'datacenter', options[0]);
449
454
  set(this.value, 'cloneFrom', undefined);
450
455
  set(this.value, 'useDataStoreCluster', false);
451
456
  }
452
457
 
453
- if ([_EDIT, _VIEW].includes(this.mode)) {
458
+ if ([_EDIT, _VIEW].includes(this.mode) && !this.poolCreateMode) {
454
459
  this.manageErrors(errorActions.CREATE, 'datacenter');
455
460
  }
456
461
  } else {
@@ -650,15 +655,19 @@ export default {
650
655
  };
651
656
 
652
657
  if (!isValueInContent()) {
653
- if (this.mode === _CREATE) {
654
- const value = isArray ? [] : content[0]?.value;
655
-
656
- if (value !== SENTINEL) {
657
- set(this.value, key, value);
658
- }
658
+ const value = isArray ? [] : content[0]?.value;
659
+ const isNullOrEmpty = NULLABLE_EMPTY_FIELDS.includes(key) && (this.value[key] === null || this.value[key] === '');
660
+ const shouldHandleError =
661
+ [_EDIT, _VIEW].includes(this.mode) && // error messages should only be displayed in Edit or View mode
662
+ !this.poolCreateMode && // almost identical to Create mode
663
+ !isNullOrEmpty && // null and empty string are valid values for some fields e.g. contentLibrary, folder and hostsystem
664
+ !isArray; // this flag is used for network and tag fields, and should not display error for them
665
+
666
+ if ((this.mode === _CREATE || this.poolCreateMode) && value !== SENTINEL) {
667
+ set(this.value, key, value);
659
668
  }
660
669
 
661
- if ([_EDIT, _VIEW].includes(this.mode)) {
670
+ if (shouldHandleError) {
662
671
  this.manageErrors(errorActions.CREATE, key);
663
672
  }
664
673
  } else {