@rancher/shell 2.0.0 → 2.0.2-rc.1

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 (154) hide show
  1. package/assets/translations/en-us.yaml +69 -29
  2. package/assets/translations/zh-hans.yaml +1 -0
  3. package/components/AlertTable.vue +17 -7
  4. package/components/AssignTo.vue +2 -0
  5. package/components/GrafanaDashboard.vue +6 -4
  6. package/components/PromptRemove.vue +1 -0
  7. package/components/Questions/index.vue +2 -2
  8. package/components/auth/RoleDetailEdit.vue +5 -4
  9. package/components/form/KeyValue.vue +1 -0
  10. package/components/form/Members/ClusterPermissionsEditor.vue +1 -1
  11. package/components/form/ProjectMemberEditor.vue +1 -1
  12. package/components/form/ResourceLabeledSelect.vue +11 -3
  13. package/components/form/Taints.vue +13 -7
  14. package/components/form/__tests__/Taints.test.ts +70 -0
  15. package/components/form/labeled-select-utils/labeled-select.utils.ts +1 -1
  16. package/components/nav/Header.vue +1 -1
  17. package/components/nav/TopLevelMenu.vue +1 -4
  18. package/config/pagination-table-headers.js +5 -4
  19. package/config/product/auth.js +1 -1
  20. package/config/roles.ts +34 -19
  21. package/config/router/navigation-guards/attempt-first-login.js +1 -1
  22. package/config/router/navigation-guards/authentication.js +1 -1
  23. package/config/router/navigation-guards/i18n.js +13 -0
  24. package/config/router/navigation-guards/index.js +3 -1
  25. package/config/router/navigation-guards/load-initial-settings.js +1 -1
  26. package/config/router/navigation-guards/runtime-extension-route.js +31 -0
  27. package/config/router/routes.js +10 -1
  28. package/config/uiplugins.js +130 -61
  29. package/core/plugin.ts +5 -0
  30. package/core/plugins.js +7 -1
  31. package/detail/__tests__/provisioning.cattle.io.cluster.test.ts +42 -0
  32. package/detail/provisioning.cattle.io.cluster.vue +4 -4
  33. package/dialog/DeactivateDriverDialog.vue +30 -11
  34. package/edit/auth/__tests__/oidc.test.ts +2 -2
  35. package/edit/provisioning.cattle.io.cluster/__tests__/Basics.test.ts +86 -13
  36. package/edit/provisioning.cattle.io.cluster/__tests__/DirectoryConfig.test.ts +3 -134
  37. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +209 -0
  38. package/edit/provisioning.cattle.io.cluster/index.vue +8 -4
  39. package/edit/provisioning.cattle.io.cluster/rke2.vue +115 -17
  40. package/edit/provisioning.cattle.io.cluster/tabs/AddOnAdditionalManifest.vue +50 -0
  41. package/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig.vue +29 -64
  42. package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +42 -3
  43. package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +22 -86
  44. package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +8 -2
  45. package/edit/provisioning.cattle.io.cluster/tabs/registries/__tests__/RegistryConfigs.test.ts +61 -0
  46. package/edit/token.vue +2 -1
  47. package/initialize/entry-helpers.js +4 -24
  48. package/list/management.cattle.io.feature.vue +4 -2
  49. package/middleware/authenticated.js +0 -19
  50. package/mixins/__tests__/chart.test.ts +4 -1
  51. package/mixins/auth-config.js +1 -1
  52. package/mixins/chart.js +30 -14
  53. package/models/__tests__/apps.deployment.test.ts +93 -0
  54. package/models/apps.deployment.js +18 -4
  55. package/models/driver.js +3 -2
  56. package/models/kontainerdriver.js +30 -13
  57. package/models/management.cattle.io.authconfig.js +2 -2
  58. package/models/management.cattle.io.cluster.js +2 -2
  59. package/models/management.cattle.io.user.js +3 -3
  60. package/models/nodedriver.js +35 -13
  61. package/models/provisioning.cattle.io.cluster.js +4 -0
  62. package/package.json +3 -2
  63. package/pages/404.vue +15 -0
  64. package/pages/auth/login.vue +4 -1
  65. package/pages/auth/setup.vue +4 -1
  66. package/pages/c/_cluster/apps/charts/install.vue +3 -2
  67. package/pages/c/_cluster/explorer/index.vue +5 -0
  68. package/pages/c/_cluster/manager/drivers/kontainerDriver/index.vue +0 -3
  69. package/pages/c/_cluster/manager/drivers/nodeDriver/index.vue +1 -4
  70. package/pages/c/_cluster/manager/jwt.authentication/index.vue +10 -4
  71. package/pages/c/_cluster/settings/performance.vue +2 -2
  72. package/pages/c/_cluster/uiplugins/InstallDialog.vue +2 -1
  73. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +7 -10
  74. package/pages/c/_cluster/uiplugins/index.vue +24 -16
  75. package/pages/home.vue +1 -13
  76. package/plugins/dashboard-store/actions.js +1 -1
  77. package/plugins/dashboard-store/getters.js +1 -1
  78. package/plugins/steve/__tests__/getters.test.ts +5 -5
  79. package/plugins/steve/getters.js +6 -4
  80. package/plugins/steve/hybrid-class.js +1 -5
  81. package/promptRemove/pod.vue +15 -7
  82. package/scripts/extension/helm/charts/ui-plugin-server/Chart.yaml +1 -1
  83. package/scripts/publish-shell.sh +54 -55
  84. package/scripts/test-plugins-build.sh +45 -39
  85. package/shell/types/shell/index.d.ts +2 -0
  86. package/store/auth.js +1 -1
  87. package/store/index.js +1 -1
  88. package/store/type-map.js +4 -2
  89. package/types/store/pagination.types.ts +1 -1
  90. package/utils/__tests__/kontainer.test.ts +89 -1
  91. package/utils/auth.js +1 -1
  92. package/utils/cluster.js +9 -0
  93. package/utils/kontainer.ts +5 -1
  94. package/utils/settings.ts +3 -1
  95. package/utils/version.js +2 -1
  96. package/creators/app/app.package.json +0 -13
  97. package/creators/app/files/.eslintignore +0 -16
  98. package/creators/app/files/.eslintrc.js +0 -173
  99. package/creators/app/files/.gitignore +0 -70
  100. package/creators/app/files/.gitlab-ci.yml +0 -14
  101. package/creators/app/files/.vscode/settings.json +0 -21
  102. package/creators/app/files/babel.config.js +0 -1
  103. package/creators/app/files/tsconfig.json +0 -42
  104. package/creators/app/files/vue.config.js +0 -6
  105. package/creators/app/init +0 -120
  106. package/creators/app/package.json +0 -25
  107. package/creators/pkg/files/.github/workflows/build-extension-catalog.yml +0 -24
  108. package/creators/pkg/files/.github/workflows/build-extension-charts.yml +0 -22
  109. package/creators/pkg/files/babel.config.js +0 -1
  110. package/creators/pkg/files/index.ts +0 -14
  111. package/creators/pkg/files/tsconfig.json +0 -53
  112. package/creators/pkg/files/vue.config.js +0 -1
  113. package/creators/pkg/init +0 -286
  114. package/creators/pkg/package.json +0 -19
  115. package/creators/pkg/pkg.package.json +0 -21
  116. package/creators/pkg/vue-shim.ts +0 -4
  117. package/creators/update/init +0 -56
  118. package/creators/update/package.json +0 -20
  119. package/creators/update/upgrade +0 -56
  120. package/rancher-components/components/Accordion/Accordion.test.ts +0 -45
  121. package/rancher-components/components/Accordion/Accordion.vue +0 -86
  122. package/rancher-components/components/Accordion/index.ts +0 -1
  123. package/rancher-components/components/BadgeState/BadgeState.test.ts +0 -12
  124. package/rancher-components/components/BadgeState/BadgeState.vue +0 -111
  125. package/rancher-components/components/BadgeState/index.ts +0 -1
  126. package/rancher-components/components/Banner/Banner.test.ts +0 -59
  127. package/rancher-components/components/Banner/Banner.vue +0 -244
  128. package/rancher-components/components/Banner/index.ts +0 -1
  129. package/rancher-components/components/Card/Card.test.ts +0 -37
  130. package/rancher-components/components/Card/Card.vue +0 -167
  131. package/rancher-components/components/Card/index.ts +0 -1
  132. package/rancher-components/components/Form/Checkbox/Checkbox.test.ts +0 -68
  133. package/rancher-components/components/Form/Checkbox/Checkbox.vue +0 -421
  134. package/rancher-components/components/Form/Checkbox/index.ts +0 -1
  135. package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +0 -40
  136. package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +0 -402
  137. package/rancher-components/components/Form/LabeledInput/index.ts +0 -1
  138. package/rancher-components/components/Form/Radio/RadioButton.test.ts +0 -33
  139. package/rancher-components/components/Form/Radio/RadioButton.vue +0 -293
  140. package/rancher-components/components/Form/Radio/RadioGroup.test.ts +0 -30
  141. package/rancher-components/components/Form/Radio/RadioGroup.vue +0 -259
  142. package/rancher-components/components/Form/Radio/index.ts +0 -2
  143. package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +0 -172
  144. package/rancher-components/components/Form/TextArea/index.ts +0 -1
  145. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.test.ts +0 -94
  146. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.vue +0 -152
  147. package/rancher-components/components/Form/ToggleSwitch/index.ts +0 -1
  148. package/rancher-components/components/Form/index.ts +0 -5
  149. package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +0 -156
  150. package/rancher-components/components/LabeledTooltip/index.ts +0 -1
  151. package/rancher-components/components/StringList/StringList.test.ts +0 -754
  152. package/rancher-components/components/StringList/StringList.vue +0 -650
  153. package/rancher-components/components/StringList/index.ts +0 -1
  154. package/types/shell/index.d.ts +0 -4585
@@ -29,7 +29,7 @@ import { sortBy } from '@shell/utils/sort';
29
29
  import { vspherePoolConfigMerge } from '@shell/machine-config/vmwarevsphere-pool-config-merge';
30
30
 
31
31
  import { compare, sortable } from '@shell/utils/version';
32
- import { isHarvesterSatisfiesVersion } from '@shell/utils/cluster';
32
+ import { isHarvesterSatisfiesVersion, labelForAddon } from '@shell/utils/cluster';
33
33
 
34
34
  import { BadgeState } from '@components/BadgeState';
35
35
  import { Banner } from '@components/Banner';
@@ -42,6 +42,7 @@ import Tabbed from '@shell/components/Tabbed';
42
42
  import { canViewClusterMembershipEditor } from '@shell/components/form/Members/ClusterMembershipEditor';
43
43
  import semver from 'semver';
44
44
 
45
+ import { CLOUD_CREDENTIAL_OVERRIDE } from '@shell/models/nodedriver';
45
46
  import { SETTING } from '@shell/config/settings';
46
47
  import { base64Encode } from '@shell/utils/crypto';
47
48
  import { CAPI as CAPI_ANNOTATIONS, CLUSTER_BADGE } from '@shell/config/labels-annotations';
@@ -62,6 +63,7 @@ import Registries from '@shell/edit/provisioning.cattle.io.cluster/tabs/registri
62
63
  import AddOnConfig from '@shell/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig';
63
64
  import Advanced from '@shell/edit/provisioning.cattle.io.cluster/tabs/Advanced';
64
65
  import ClusterAppearance from '@shell/components/form/ClusterAppearance';
66
+ import AddOnAdditionalManifest from '@shell/edit/provisioning.cattle.io.cluster/tabs/AddOnAdditionalManifest';
65
67
 
66
68
  const HARVESTER = 'harvester';
67
69
  const HARVESTER_CLOUD_PROVIDER = 'harvester-cloud-provider';
@@ -89,6 +91,8 @@ const NODE_TOTAL = {
89
91
  const CLUSTER_AGENT_CUSTOMIZATION = 'clusterAgentDeploymentCustomization';
90
92
  const FLEET_AGENT_CUSTOMIZATION = 'fleetAgentDeploymentCustomization';
91
93
 
94
+ const isAzureK8sUnsupported = (version) => semver.gte(version, '1.30.0');
95
+
92
96
  export default {
93
97
  components: {
94
98
  AgentEnv,
@@ -111,7 +115,8 @@ export default {
111
115
  Registries,
112
116
  AddOnConfig,
113
117
  Advanced,
114
- ClusterAppearance
118
+ ClusterAppearance,
119
+ AddOnAdditionalManifest
115
120
  },
116
121
 
117
122
  mixins: [CreateEditView, FormValidation],
@@ -171,6 +176,7 @@ export default {
171
176
  });
172
177
  }
173
178
 
179
+ // default for dataDirectories configuration obj
174
180
  if (!this.value.spec.rkeConfig.dataDirectories) {
175
181
  set(this.value.spec.rkeConfig, 'dataDirectories', {
176
182
  systemAgent: '',
@@ -179,6 +185,19 @@ export default {
179
185
  });
180
186
  }
181
187
 
188
+ // default for dataDirectories configuration systemAgent config
189
+ if (!this.value.spec.rkeConfig.dataDirectories.systemAgent) {
190
+ set(this.value.spec.rkeConfig.dataDirectories, 'systemAgent', '');
191
+ }
192
+ // default for dataDirectories configuration provisioning config
193
+ if (!this.value.spec.rkeConfig.dataDirectories.provisioning) {
194
+ set(this.value.spec.rkeConfig.dataDirectories, 'provisioning', '');
195
+ }
196
+ // default for dataDirectories configuration k8sDistro config
197
+ if (!this.value.spec.rkeConfig.dataDirectories.k8sDistro) {
198
+ set(this.value.spec.rkeConfig.dataDirectories, 'k8sDistro', '');
199
+ }
200
+
182
201
  if (!this.value.spec.rkeConfig.machineGlobalConfig) {
183
202
  set(this.value.spec, 'rkeConfig.machineGlobalConfig', {});
184
203
  }
@@ -230,6 +249,7 @@ export default {
230
249
  machinePoolErrors: {},
231
250
  allNamespaces: [],
232
251
  extensionTabs: getApplicableExtensionEnhancements(this, ExtensionPoint.TAB, TabLocation.CLUSTER_CREATE_RKE2, this.$route, this),
252
+ labelForAddon
233
253
  };
234
254
  },
235
255
 
@@ -297,6 +317,7 @@ export default {
297
317
  const cur = this.liveValue?.spec?.kubernetesVersion || '';
298
318
  const existingRke2 = this.mode === _EDIT && cur.includes('rke2');
299
319
  const existingK3s = this.mode === _EDIT && cur.includes('k3s');
320
+ const isAzure = this.agentConfig?.['cloud-provider-name'] === 'azure';
300
321
 
301
322
  let allValidRke2Versions = this.getAllOptionsAfterCurrentVersion(this.rke2Versions, (existingRke2 ? cur : null), this.defaultRke2);
302
323
  let allValidK3sVersions = this.getAllOptionsAfterCurrentVersion(this.k3sVersions, (existingK3s ? cur : null), this.defaultK3s);
@@ -309,6 +330,11 @@ export default {
309
330
  allValidK3sVersions = this.filterOutDeprecatedPatchVersions(allValidK3sVersions, cur);
310
331
  }
311
332
 
333
+ if (isAzure) {
334
+ allValidRke2Versions = allValidRke2Versions.filter((v) => !isAzureK8sUnsupported(v.value));
335
+ allValidK3sVersions = allValidK3sVersions.filter((v) => !isAzureK8sUnsupported(v.value));
336
+ }
337
+
312
338
  const showRke2 = allValidRke2Versions.length && !existingK3s;
313
339
  const showK3s = allValidK3sVersions.length && !existingRke2;
314
340
  const out = [];
@@ -356,7 +382,7 @@ export default {
356
382
  // https://github.com/rancher/dashboard/issues/10338
357
383
  // there's an update loop on refresh that might include 'none'
358
384
  // multiple times... Prevent that
359
- if (out.serverArgs?.cni?.options && !out.serverArgs?.cni?.options.includes('none')) {
385
+ if (out?.serverArgs?.cni?.options && !out.serverArgs?.cni?.options.includes('none')) {
360
386
  out.serverArgs.cni.options.push('none');
361
387
  }
362
388
 
@@ -385,11 +411,22 @@ export default {
385
411
  },
386
412
 
387
413
  needCredential() {
388
- if (this.provider === 'custom' || this.provider === 'import' || this.isElementalCluster || this.mode === _VIEW || (this.providerConfig?.spec?.builtin === false && this.providerConfig?.spec?.addCloudCredential === false)) {
414
+ // Check non-provider specific config
415
+ if (
416
+ this.provider === 'custom' ||
417
+ this.provider === 'import' ||
418
+ this.isElementalCluster || // Elemental cluster can make use of `cloud-credential`: false
419
+ this.mode === _VIEW
420
+ ) {
389
421
  return false;
390
422
  }
391
423
 
392
- if (this.customCredentialComponentRequired === false) {
424
+ // Check provider specific config
425
+ if (this.cloudCredentialsOverride === true || this.cloudCredentialsOverride === false) {
426
+ return this.cloudCredentialsOverride;
427
+ }
428
+
429
+ if (this.providerConfig?.spec?.builtin === false && this.providerConfig?.spec?.addCloudCredential === false) {
393
430
  return false;
394
431
  }
395
432
 
@@ -397,10 +434,21 @@ export default {
397
434
  },
398
435
 
399
436
  /**
400
- * Only for extensions - extension can register a 'false' cloud credential to indicate that a cloud credential is not needed
437
+ * Override the native way of determining if cloud credentials are required (builtin ++ node driver spec.addCloudCredentials)
438
+ *
439
+ * 1) Override via extensions
440
+ * - `true` or actual component - return true
441
+ * - `false` - return false
442
+ * 2) Override via hardcoded setting
401
443
  */
402
- customCredentialComponentRequired() {
403
- return this.$plugin.getDynamic('cloud-credential', this.provider);
444
+ cloudCredentialsOverride() {
445
+ const cloudCredential = this.$plugin.getDynamic('cloud-credential', this.provider);
446
+
447
+ if (cloudCredential === undefined) {
448
+ return CLOUD_CREDENTIAL_OVERRIDE[this.provider];
449
+ }
450
+
451
+ return !!cloudCredential;
404
452
  },
405
453
 
406
454
  hasMachinePools() {
@@ -580,8 +628,9 @@ export default {
580
628
 
581
629
  cloudProviderOptions() {
582
630
  const out = [{
583
- label: this.$store.getters['i18n/t']('cluster.rke2.cloudProvider.defaultValue.label'),
584
- value: '',
631
+ label: this.$store.getters['i18n/t']('cluster.rke2.cloudProvider.defaultValue.label'),
632
+ value: '',
633
+ disabled: this.canAzureMigrateOnEdit
585
634
  }];
586
635
 
587
636
  if (!!this.agentArgs['cloud-provider-name']?.options) {
@@ -593,12 +642,22 @@ export default {
593
642
  // If we have a preferred provider... only show default, preferred and external
594
643
  const isPreferred = opt === preferred;
595
644
  const isExternal = opt === 'external';
645
+ const isAzure = opt === 'azure';
646
+
596
647
  let disabled = false;
597
648
 
598
649
  if ((this.isHarvesterExternalCredential || this.isHarvesterIncompatible) && isPreferred) {
599
650
  disabled = true;
600
651
  }
601
652
 
653
+ if (isAzure && isAzureK8sUnsupported(this.value.spec.kubernetesVersion)) {
654
+ disabled = true;
655
+ }
656
+
657
+ if (!isAzure && !isExternal && this.canAzureMigrateOnEdit) {
658
+ disabled = true;
659
+ }
660
+
602
661
  if (showAllOptions || isPreferred || isExternal) {
603
662
  out.push({
604
663
  label: this.$store.getters['i18n/withFallback'](`cluster.cloudProvider."${ opt }".label`, null, opt),
@@ -618,6 +677,25 @@ export default {
618
677
  return out;
619
678
  },
620
679
 
680
+ isAzureProviderUnsupported() {
681
+ const isAzureAvailable = !!this.cloudProviderOptions.find((p) => p.value === 'azure');
682
+ const isAzureSelected = this.agentConfig['cloud-provider-name'] === 'azure';
683
+
684
+ return isAzureAvailable && (isAzureK8sUnsupported(this.value.spec.kubernetesVersion) || isAzureSelected);
685
+ },
686
+
687
+ canAzureMigrateOnEdit() {
688
+ if (!this.isEdit) {
689
+ return false;
690
+ }
691
+
692
+ const isAzureLiveProvider = this.liveValue.agentConfig['cloud-provider-name'] === 'azure';
693
+
694
+ return isAzureLiveProvider &&
695
+ semver.gte(this.liveValue?.spec?.kubernetesVersion, '1.27.0') &&
696
+ semver.lt(this.liveValue?.spec?.kubernetesVersion, '1.30.0');
697
+ },
698
+
621
699
  canManageMembers() {
622
700
  return canViewClusterMembershipEditor(this.$store);
623
701
  },
@@ -1508,7 +1586,9 @@ export default {
1508
1586
  refreshComponentWithYamls(key) {
1509
1587
  const component = this.$refs[key];
1510
1588
 
1511
- if (component) {
1589
+ if (Array.isArray(component) && component.length > 0) {
1590
+ this.refreshYamls(component[0].$refs);
1591
+ } else if (component) {
1512
1592
  this.refreshYamls(component.$refs);
1513
1593
  }
1514
1594
  },
@@ -2225,6 +2305,8 @@ export default {
2225
2305
  :show-cni="showCni"
2226
2306
  :show-cloud-provider="showCloudProvider"
2227
2307
  :cloud-provider-options="cloudProviderOptions"
2308
+ :is-azure-provider-unsupported="isAzureProviderUnsupported"
2309
+ :can-azure-migrate-on-edit="canAzureMigrateOnEdit"
2228
2310
  @cilium-values-changed="handleCiliumValuesChanged"
2229
2311
  @enabled-system-services-changed="handleEnabledSystemServicesChanged"
2230
2312
  @kubernetes-changed="handleKubernetesChange"
@@ -2309,23 +2391,39 @@ export default {
2309
2391
  />
2310
2392
  </Tab>
2311
2393
 
2312
- <!-- Add-on Config -->
2394
+ <!-- Add-on Configs -->
2313
2395
  <Tab
2314
- name="addons"
2315
- label-key="cluster.tabs.addons"
2316
- @active="showAddons('tab-addOnConfig')"
2396
+ v-for="v in addonVersions"
2397
+ :key="v.name"
2398
+ :name="v.name"
2399
+ :label="labelForAddon(v.name, false)"
2400
+ :weight="9"
2401
+ :showHeader="false"
2402
+ @active="showAddons(v.name)"
2317
2403
  >
2318
2404
  <AddOnConfig
2319
- ref="tab-addOnConfig"
2405
+ :ref="v.name"
2320
2406
  v-model="value"
2321
2407
  :mode="mode"
2322
2408
  :version-info="versionInfo"
2323
- :addon-versions="addonVersions"
2409
+ :addon-version="v"
2324
2410
  :addons-rev="addonsRev"
2325
2411
  :user-chart-values-temp="userChartValuesTemp"
2326
2412
  :init-yaml-editor="initYamlEditor"
2327
2413
  @update-questions="syncChartValues"
2328
2414
  @update-values="updateValues"
2415
+ />
2416
+ </Tab>
2417
+
2418
+ <!-- Add-on Additional Manifest -->
2419
+ <Tab
2420
+ name="additionalmanifest"
2421
+ label-key="cluster.tabs.addOnAdditionalManifest"
2422
+ :showHeader="false"
2423
+ >
2424
+ <AddOnAdditionalManifest
2425
+ :value="value"
2426
+ :mode="mode"
2329
2427
  @additional-manifest-changed="updateAdditionalManifest"
2330
2428
  />
2331
2429
  </Tab>
@@ -0,0 +1,50 @@
1
+ <script>
2
+ import YamlEditor from '@shell/components/YamlEditor';
3
+
4
+ export default {
5
+ components: { YamlEditor },
6
+
7
+ props: {
8
+ mode: {
9
+ type: String,
10
+ required: true,
11
+ },
12
+
13
+ value: {
14
+ type: Object,
15
+ required: true,
16
+ }
17
+
18
+ },
19
+
20
+ computed: {
21
+ additionalManifest: {
22
+ get() {
23
+ return this.value.spec.rkeConfig.additionalManifest;
24
+ },
25
+ set(neu) {
26
+ this.$emit('additional-manifest-changed', neu);
27
+ }
28
+ }
29
+ }
30
+ };
31
+ </script>
32
+
33
+ <template>
34
+ <div>
35
+ <h3>
36
+ {{ t('cluster.addOns.additionalManifest.title') }}
37
+ <i
38
+ v-clean-tooltip="t('cluster.addOns.additionalManifest.tooltip')"
39
+ class="icon icon-info"
40
+ />
41
+ </h3>
42
+ <YamlEditor
43
+ ref="yaml-additional"
44
+ v-model="additionalManifest"
45
+ :editor-mode="mode === 'view' ? 'VIEW_CODE' : 'EDIT_CODE'"
46
+ initial-yaml-values="# Additional Manifest YAML"
47
+ class="yaml-editor"
48
+ />
49
+ </div>
50
+ </template>
@@ -3,7 +3,7 @@ import { Banner } from '@components/Banner';
3
3
 
4
4
  import Questions from '@shell/components/Questions';
5
5
  import YamlEditor from '@shell/components/YamlEditor';
6
- import { camelToTitle } from '@shell/utils/string';
6
+ import { labelForAddon } from '@shell/utils/cluster';
7
7
  import { _EDIT } from '@shell/config/query-params';
8
8
 
9
9
  export default {
@@ -29,8 +29,8 @@ export default {
29
29
  required: true,
30
30
  },
31
31
 
32
- addonVersions: {
33
- type: Array,
32
+ addonVersion: {
33
+ type: Object,
34
34
  required: false,
35
35
  default: null
36
36
  },
@@ -50,28 +50,15 @@ export default {
50
50
 
51
51
  },
52
52
 
53
+ data() {
54
+ return { labelForAddon };
55
+ },
56
+
53
57
  computed: {
54
- additionalManifest: {
55
- get() {
56
- return this.value.spec.rkeConfig.additionalManifest;
57
- },
58
- set(neu) {
59
- this.$emit('additional-manifest-changed', neu);
60
- }
61
- },
62
58
  isEdit() {
63
59
  return this.mode === _EDIT;
64
60
  },
65
- },
66
-
67
- methods: {
68
-
69
- labelForAddon(name) {
70
- const fallback = `${ camelToTitle(name.replace(/^(rke|rke2|rancher)-/, '')) } Configuration`;
71
-
72
- return this.$store.getters['i18n/withFallback'](`cluster.addonChart."${ name }"`, null, fallback);
73
- },
74
- },
61
+ }
75
62
  };
76
63
  </script>
77
64
 
@@ -84,54 +71,32 @@ export default {
84
71
  {{ t('cluster.addOns.dependencyBanner') }}
85
72
  </Banner>
86
73
  <div
87
- v-if="versionInfo && addonVersions.length"
74
+ v-if="versionInfo && addonVersion"
88
75
  :key="addonsRev"
89
76
  >
90
- <div
91
- v-for="v in addonVersions"
92
- :key="v._key"
93
- >
94
- <h3>{{ labelForAddon(v.name) }}</h3>
95
- <Questions
96
- v-if="versionInfo[v.name] && versionInfo[v.name].questions && v.name && userChartValuesTemp[v.name]"
97
- v-model="userChartValuesTemp[v.name]"
98
- :emit="true"
99
- in-store="management"
100
- :mode="mode"
101
- :tabbed="false"
102
- :source="versionInfo[v.name]"
103
- :target-namespace="value.metadata.namespace"
104
- @updated="$emit('update-questions', v.name)"
105
- />
106
- <YamlEditor
107
- v-else
108
- ref="yaml-values"
109
- :value="initYamlEditor(v.name)"
110
- :scrolling="true"
111
- :as-object="true"
112
- :editor-mode="mode === 'view' ? 'VIEW_CODE' : 'EDIT_CODE'"
113
- :hide-preview-buttons="true"
114
- @input="data => $emit('update-values', v.name, data)"
115
- />
116
- <div class="spacer" />
117
- </div>
118
- </div>
119
-
120
- <div>
121
- <h3>
122
- {{ t('cluster.addOns.additionalManifest.title') }}
123
- <i
124
- v-clean-tooltip="t('cluster.addOns.additionalManifest.tooltip')"
125
- class="icon icon-info"
126
- />
127
- </h3>
77
+ <h3>{{ labelForAddon(addonVersion.name) }}</h3>
78
+ <Questions
79
+ v-if="versionInfo[addonVersion.name] && versionInfo[addonVersion.name].questions && addonVersion.name && userChartValuesTemp[addonVersion.name]"
80
+ v-model="userChartValuesTemp[addonVersion.name]"
81
+ :emit="true"
82
+ in-store="management"
83
+ :mode="mode"
84
+ :tabbed="false"
85
+ :source="versionInfo[addonVersion.name]"
86
+ :target-namespace="value.metadata.namespace"
87
+ @updated="$emit('update-questions', addonVersion.name)"
88
+ />
128
89
  <YamlEditor
129
- ref="yaml-additional"
130
- v-model="additionalManifest"
90
+ v-else
91
+ ref="yaml-values"
92
+ :value="initYamlEditor(addonVersion.name)"
93
+ :scrolling="true"
94
+ :as-object="true"
131
95
  :editor-mode="mode === 'view' ? 'VIEW_CODE' : 'EDIT_CODE'"
132
- initial-yaml-values="# Additional Manifest YAML"
133
- class="yaml-editor"
96
+ :hide-preview-buttons="true"
97
+ @input="data => $emit('update-values', addonVersion.name, data)"
134
98
  />
99
+ <div class="spacer" />
135
100
  </div>
136
101
  </div>
137
102
  </template>
@@ -11,7 +11,7 @@ import LabeledSelect from '@shell/components/form/LabeledSelect';
11
11
  import YamlEditor from '@shell/components/YamlEditor';
12
12
  import { LEGACY } from '@shell/store/features';
13
13
  import semver from 'semver';
14
- import { _EDIT } from '@shell/config/query-params';
14
+ import { _CREATE, _EDIT } from '@shell/config/query-params';
15
15
 
16
16
  const HARVESTER = 'harvester';
17
17
 
@@ -106,6 +106,14 @@ export default {
106
106
  cloudProviderOptions: {
107
107
  type: Array,
108
108
  required: true
109
+ },
110
+ isAzureProviderUnsupported: {
111
+ type: Boolean,
112
+ required: true
113
+ },
114
+ canAzureMigrateOnEdit: {
115
+ type: Boolean,
116
+ required: true
109
117
  }
110
118
  },
111
119
 
@@ -377,9 +385,11 @@ export default {
377
385
  },
378
386
 
379
387
  canNotEditCloudProvider() {
380
- const canNotEdit = this.isEdit;
388
+ if (!this.isEdit) {
389
+ return false;
390
+ }
381
391
 
382
- return canNotEdit;
392
+ return !this.canAzureMigrateOnEdit;
383
393
  },
384
394
 
385
395
  /**
@@ -387,6 +397,20 @@ export default {
387
397
  */
388
398
  showCloudProviderAmazonAdditionalConfigWarning() {
389
399
  return !!semver.gte(this.value.spec.kubernetesVersion, 'v1.27.0') && this.agentConfig?.['cloud-provider-name'] === 'aws';
400
+ },
401
+
402
+ /**
403
+ * Display warning about unsupported Azure provider if k8s >= 1.30
404
+ */
405
+ showCloudProviderUnsupportedAzureWarning() {
406
+ return this.showCloudProvider && this.mode === _CREATE && this.isAzureProviderUnsupported;
407
+ },
408
+
409
+ /**
410
+ * Display warning about Azure provider migration from k8s versions >= 1.27 to External provider
411
+ */
412
+ showCloudProviderMigrateAzureWarning() {
413
+ return this.showCloudProvider && this.mode === _EDIT && this.canAzureMigrateOnEdit;
390
414
  }
391
415
  },
392
416
 
@@ -423,6 +447,20 @@ export default {
423
447
  v-clean-html="t('cluster.harvester.warning.cloudProvider.incompatible', null, true)"
424
448
  />
425
449
  </Banner>
450
+ <Banner
451
+ v-if="showCloudProviderUnsupportedAzureWarning"
452
+ color="warning"
453
+ data-testid="clusterBasics__showCloudProviderUnsupportedAzureWarning"
454
+ >
455
+ <span v-clean-html="t('cluster.banner.cloudProviderUnsupportedAzure', {}, true)" />
456
+ </Banner>
457
+ <Banner
458
+ v-if="showCloudProviderMigrateAzureWarning"
459
+ color="warning"
460
+ data-testid="clusterBasics__showCloudProviderMigrateAzureWarning"
461
+ >
462
+ <span v-clean-html="t('cluster.banner.cloudProviderMigrateAzure', {}, true)" />
463
+ </Banner>
426
464
  <Banner
427
465
  v-if="showCloudProviderAmazonAdditionalConfigWarning"
428
466
  color="warning"
@@ -461,6 +499,7 @@ export default {
461
499
  <LabeledSelect
462
500
  v-if="agentConfig"
463
501
  v-model="agentConfig['cloud-provider-name']"
502
+ data-testid="clusterBasics__cloudProvider"
464
503
  :mode="mode"
465
504
  :disabled="canNotEditCloudProvider"
466
505
  :options="cloudProviderOptions"