@rancher/shell 2.0.1 → 2.0.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 (112) hide show
  1. package/assets/translations/en-us.yaml +73 -34
  2. package/assets/translations/zh-hans.yaml +1 -0
  3. package/components/AssignTo.vue +2 -0
  4. package/components/PromptRemove.vue +8 -3
  5. package/components/Questions/index.vue +2 -2
  6. package/components/ResourceDetail/Masthead.vue +1 -0
  7. package/components/auth/RoleDetailEdit.vue +5 -4
  8. package/components/fleet/FleetClusters.vue +0 -3
  9. package/components/form/Members/ClusterPermissionsEditor.vue +1 -1
  10. package/components/form/ProjectMemberEditor.vue +1 -1
  11. package/components/form/ResourceLabeledSelect.vue +11 -3
  12. package/components/form/labeled-select-utils/labeled-select.utils.ts +1 -1
  13. package/components/formatter/CloudCredExpired.vue +69 -0
  14. package/components/formatter/Date.vue +1 -1
  15. package/components/nav/Header.vue +9 -5
  16. package/components/nav/TopLevelMenu.vue +115 -51
  17. package/components/nav/__tests__/TopLevelMenu.test.ts +53 -27
  18. package/config/labels-annotations.js +2 -0
  19. package/config/pagination-table-headers.js +5 -4
  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 +1 -1
  24. package/config/router/navigation-guards/index.js +2 -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/catalog.cattle.io.app.vue +17 -4
  32. package/detail/fleet.cattle.io.cluster.vue +11 -9
  33. package/detail/fleet.cattle.io.gitrepo.vue +1 -1
  34. package/edit/provisioning.cattle.io.cluster/__tests__/Basics.test.ts +86 -13
  35. package/edit/provisioning.cattle.io.cluster/__tests__/DirectoryConfig.test.ts +3 -134
  36. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +209 -0
  37. package/edit/provisioning.cattle.io.cluster/index.vue +8 -4
  38. package/edit/provisioning.cattle.io.cluster/rke2.vue +128 -17
  39. package/edit/provisioning.cattle.io.cluster/tabs/AddOnAdditionalManifest.vue +50 -0
  40. package/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig.vue +29 -64
  41. package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +42 -3
  42. package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +22 -86
  43. package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +8 -2
  44. package/edit/provisioning.cattle.io.cluster/tabs/registries/__tests__/RegistryConfigs.test.ts +61 -0
  45. package/initialize/entry-helpers.js +4 -21
  46. package/list/provisioning.cattle.io.cluster.vue +56 -5
  47. package/mixins/__tests__/chart.test.ts +4 -1
  48. package/mixins/chart.js +36 -16
  49. package/models/__tests__/apps.deployment.test.ts +93 -0
  50. package/models/apps.deployment.js +18 -4
  51. package/models/catalog.cattle.io.app.js +108 -21
  52. package/models/cloudcredential.js +159 -2
  53. package/models/fleet.cattle.io.gitrepo.js +4 -13
  54. package/models/management.cattle.io.cluster.js +15 -4
  55. package/models/management.cattle.io.user.js +3 -3
  56. package/models/nodedriver.js +5 -0
  57. package/models/provisioning.cattle.io.cluster.js +41 -3
  58. package/package.json +1 -1
  59. package/pages/404.vue +15 -0
  60. package/pages/auth/login.vue +4 -1
  61. package/pages/auth/setup.vue +4 -1
  62. package/pages/c/_cluster/apps/charts/install.vue +2 -1
  63. package/pages/c/_cluster/explorer/__tests__/index.test.ts +1 -1
  64. package/pages/c/_cluster/explorer/index.vue +6 -2
  65. package/pages/c/_cluster/fleet/index.vue +11 -5
  66. package/pages/c/_cluster/manager/cloudCredential/index.vue +68 -4
  67. package/pages/c/_cluster/manager/jwt.authentication/index.vue +10 -4
  68. package/pages/c/_cluster/settings/performance.vue +2 -2
  69. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +7 -10
  70. package/pages/c/_cluster/uiplugins/index.vue +28 -18
  71. package/pages/home.vue +2 -13
  72. package/plugins/dashboard-store/actions.js +1 -1
  73. package/plugins/dashboard-store/getters.js +1 -1
  74. package/plugins/steve/__tests__/getters.test.ts +5 -5
  75. package/plugins/steve/getters.js +6 -4
  76. package/plugins/steve/hybrid-class.js +1 -5
  77. package/scripts/extension/bundle +1 -1
  78. package/scripts/extension/helm/charts/ui-plugin-server/Chart.yaml +1 -1
  79. package/scripts/publish-shell.sh +56 -59
  80. package/scripts/test-plugins-build.sh +45 -39
  81. package/scripts/typegen.sh +26 -23
  82. package/store/type-map.js +4 -2
  83. package/types/shell/index.d.ts +10 -0
  84. package/types/store/pagination.types.ts +1 -1
  85. package/utils/cluster.js +9 -0
  86. package/utils/settings.ts +3 -1
  87. package/utils/string.js +9 -0
  88. package/utils/v-sphere.ts +251 -0
  89. package/creators/app/app.package.json +0 -14
  90. package/creators/app/files/.eslintignore +0 -16
  91. package/creators/app/files/.eslintrc.js +0 -173
  92. package/creators/app/files/.gitignore +0 -70
  93. package/creators/app/files/.gitlab-ci.yml +0 -14
  94. package/creators/app/files/.vscode/settings.json +0 -21
  95. package/creators/app/files/babel.config.js +0 -1
  96. package/creators/app/files/tsconfig.json +0 -42
  97. package/creators/app/files/vue.config.js +0 -6
  98. package/creators/app/init +0 -120
  99. package/creators/app/package.json +0 -25
  100. package/creators/pkg/files/.github/workflows/build-extension-catalog.yml +0 -24
  101. package/creators/pkg/files/.github/workflows/build-extension-charts.yml +0 -22
  102. package/creators/pkg/files/babel.config.js +0 -1
  103. package/creators/pkg/files/index.ts +0 -14
  104. package/creators/pkg/files/tsconfig.json +0 -53
  105. package/creators/pkg/files/vue.config.js +0 -1
  106. package/creators/pkg/init +0 -286
  107. package/creators/pkg/package.json +0 -19
  108. package/creators/pkg/pkg.package.json +0 -21
  109. package/creators/pkg/vue-shim.ts +0 -4
  110. package/creators/update/init +0 -56
  111. package/creators/update/package.json +0 -20
  112. package/creators/update/upgrade +0 -56
@@ -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,8 @@ 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';
67
+ import VsphereUtils from '@shell/utils/v-sphere';
65
68
 
66
69
  const HARVESTER = 'harvester';
67
70
  const HARVESTER_CLOUD_PROVIDER = 'harvester-cloud-provider';
@@ -89,6 +92,8 @@ const NODE_TOTAL = {
89
92
  const CLUSTER_AGENT_CUSTOMIZATION = 'clusterAgentDeploymentCustomization';
90
93
  const FLEET_AGENT_CUSTOMIZATION = 'fleetAgentDeploymentCustomization';
91
94
 
95
+ const isAzureK8sUnsupported = (version) => semver.gte(version, '1.30.0');
96
+
92
97
  export default {
93
98
  components: {
94
99
  AgentEnv,
@@ -111,7 +116,8 @@ export default {
111
116
  Registries,
112
117
  AddOnConfig,
113
118
  Advanced,
114
- ClusterAppearance
119
+ ClusterAppearance,
120
+ AddOnAdditionalManifest
115
121
  },
116
122
 
117
123
  mixins: [CreateEditView, FormValidation],
@@ -171,6 +177,7 @@ export default {
171
177
  });
172
178
  }
173
179
 
180
+ // default for dataDirectories configuration obj
174
181
  if (!this.value.spec.rkeConfig.dataDirectories) {
175
182
  set(this.value.spec.rkeConfig, 'dataDirectories', {
176
183
  systemAgent: '',
@@ -179,6 +186,19 @@ export default {
179
186
  });
180
187
  }
181
188
 
189
+ // default for dataDirectories configuration systemAgent config
190
+ if (!this.value.spec.rkeConfig.dataDirectories.systemAgent) {
191
+ set(this.value.spec.rkeConfig.dataDirectories, 'systemAgent', '');
192
+ }
193
+ // default for dataDirectories configuration provisioning config
194
+ if (!this.value.spec.rkeConfig.dataDirectories.provisioning) {
195
+ set(this.value.spec.rkeConfig.dataDirectories, 'provisioning', '');
196
+ }
197
+ // default for dataDirectories configuration k8sDistro config
198
+ if (!this.value.spec.rkeConfig.dataDirectories.k8sDistro) {
199
+ set(this.value.spec.rkeConfig.dataDirectories, 'k8sDistro', '');
200
+ }
201
+
182
202
  if (!this.value.spec.rkeConfig.machineGlobalConfig) {
183
203
  set(this.value.spec, 'rkeConfig.machineGlobalConfig', {});
184
204
  }
@@ -230,6 +250,7 @@ export default {
230
250
  machinePoolErrors: {},
231
251
  allNamespaces: [],
232
252
  extensionTabs: getApplicableExtensionEnhancements(this, ExtensionPoint.TAB, TabLocation.CLUSTER_CREATE_RKE2, this.$route, this),
253
+ labelForAddon
233
254
  };
234
255
  },
235
256
 
@@ -297,6 +318,7 @@ export default {
297
318
  const cur = this.liveValue?.spec?.kubernetesVersion || '';
298
319
  const existingRke2 = this.mode === _EDIT && cur.includes('rke2');
299
320
  const existingK3s = this.mode === _EDIT && cur.includes('k3s');
321
+ const isAzure = this.agentConfig?.['cloud-provider-name'] === 'azure';
300
322
 
301
323
  let allValidRke2Versions = this.getAllOptionsAfterCurrentVersion(this.rke2Versions, (existingRke2 ? cur : null), this.defaultRke2);
302
324
  let allValidK3sVersions = this.getAllOptionsAfterCurrentVersion(this.k3sVersions, (existingK3s ? cur : null), this.defaultK3s);
@@ -309,6 +331,11 @@ export default {
309
331
  allValidK3sVersions = this.filterOutDeprecatedPatchVersions(allValidK3sVersions, cur);
310
332
  }
311
333
 
334
+ if (isAzure) {
335
+ allValidRke2Versions = allValidRke2Versions.filter((v) => !isAzureK8sUnsupported(v.value));
336
+ allValidK3sVersions = allValidK3sVersions.filter((v) => !isAzureK8sUnsupported(v.value));
337
+ }
338
+
312
339
  const showRke2 = allValidRke2Versions.length && !existingK3s;
313
340
  const showK3s = allValidK3sVersions.length && !existingRke2;
314
341
  const out = [];
@@ -356,7 +383,7 @@ export default {
356
383
  // https://github.com/rancher/dashboard/issues/10338
357
384
  // there's an update loop on refresh that might include 'none'
358
385
  // multiple times... Prevent that
359
- if (out.serverArgs?.cni?.options && !out.serverArgs?.cni?.options.includes('none')) {
386
+ if (out?.serverArgs?.cni?.options && !out.serverArgs?.cni?.options.includes('none')) {
360
387
  out.serverArgs.cni.options.push('none');
361
388
  }
362
389
 
@@ -385,11 +412,22 @@ export default {
385
412
  },
386
413
 
387
414
  needCredential() {
388
- if (this.provider === 'custom' || this.provider === 'import' || this.isElementalCluster || this.mode === _VIEW || (this.providerConfig?.spec?.builtin === false && this.providerConfig?.spec?.addCloudCredential === false)) {
415
+ // Check non-provider specific config
416
+ if (
417
+ this.provider === 'custom' ||
418
+ this.provider === 'import' ||
419
+ this.isElementalCluster || // Elemental cluster can make use of `cloud-credential`: false
420
+ this.mode === _VIEW
421
+ ) {
389
422
  return false;
390
423
  }
391
424
 
392
- if (this.customCredentialComponentRequired === false) {
425
+ // Check provider specific config
426
+ if (this.cloudCredentialsOverride === true || this.cloudCredentialsOverride === false) {
427
+ return this.cloudCredentialsOverride;
428
+ }
429
+
430
+ if (this.providerConfig?.spec?.builtin === false && this.providerConfig?.spec?.addCloudCredential === false) {
393
431
  return false;
394
432
  }
395
433
 
@@ -397,10 +435,21 @@ export default {
397
435
  },
398
436
 
399
437
  /**
400
- * Only for extensions - extension can register a 'false' cloud credential to indicate that a cloud credential is not needed
438
+ * Override the native way of determining if cloud credentials are required (builtin ++ node driver spec.addCloudCredentials)
439
+ *
440
+ * 1) Override via extensions
441
+ * - `true` or actual component - return true
442
+ * - `false` - return false
443
+ * 2) Override via hardcoded setting
401
444
  */
402
- customCredentialComponentRequired() {
403
- return this.$plugin.getDynamic('cloud-credential', this.provider);
445
+ cloudCredentialsOverride() {
446
+ const cloudCredential = this.$plugin.getDynamic('cloud-credential', this.provider);
447
+
448
+ if (cloudCredential === undefined) {
449
+ return CLOUD_CREDENTIAL_OVERRIDE[this.provider];
450
+ }
451
+
452
+ return !!cloudCredential;
404
453
  },
405
454
 
406
455
  hasMachinePools() {
@@ -580,8 +629,9 @@ export default {
580
629
 
581
630
  cloudProviderOptions() {
582
631
  const out = [{
583
- label: this.$store.getters['i18n/t']('cluster.rke2.cloudProvider.defaultValue.label'),
584
- value: '',
632
+ label: this.$store.getters['i18n/t']('cluster.rke2.cloudProvider.defaultValue.label'),
633
+ value: '',
634
+ disabled: this.canAzureMigrateOnEdit
585
635
  }];
586
636
 
587
637
  if (!!this.agentArgs['cloud-provider-name']?.options) {
@@ -593,12 +643,22 @@ export default {
593
643
  // If we have a preferred provider... only show default, preferred and external
594
644
  const isPreferred = opt === preferred;
595
645
  const isExternal = opt === 'external';
646
+ const isAzure = opt === 'azure';
647
+
596
648
  let disabled = false;
597
649
 
598
650
  if ((this.isHarvesterExternalCredential || this.isHarvesterIncompatible) && isPreferred) {
599
651
  disabled = true;
600
652
  }
601
653
 
654
+ if (isAzure && isAzureK8sUnsupported(this.value.spec.kubernetesVersion)) {
655
+ disabled = true;
656
+ }
657
+
658
+ if (!isAzure && !isExternal && this.canAzureMigrateOnEdit) {
659
+ disabled = true;
660
+ }
661
+
602
662
  if (showAllOptions || isPreferred || isExternal) {
603
663
  out.push({
604
664
  label: this.$store.getters['i18n/withFallback'](`cluster.cloudProvider."${ opt }".label`, null, opt),
@@ -618,6 +678,25 @@ export default {
618
678
  return out;
619
679
  },
620
680
 
681
+ isAzureProviderUnsupported() {
682
+ const isAzureAvailable = !!this.cloudProviderOptions.find((p) => p.value === 'azure');
683
+ const isAzureSelected = this.agentConfig['cloud-provider-name'] === 'azure';
684
+
685
+ return isAzureAvailable && (isAzureK8sUnsupported(this.value.spec.kubernetesVersion) || isAzureSelected);
686
+ },
687
+
688
+ canAzureMigrateOnEdit() {
689
+ if (!this.isEdit) {
690
+ return false;
691
+ }
692
+
693
+ const isAzureLiveProvider = this.liveValue.agentConfig['cloud-provider-name'] === 'azure';
694
+
695
+ return isAzureLiveProvider &&
696
+ semver.gte(this.liveValue?.spec?.kubernetesVersion, '1.27.0') &&
697
+ semver.lt(this.liveValue?.spec?.kubernetesVersion, '1.30.0');
698
+ },
699
+
621
700
  canManageMembers() {
622
701
  return canViewClusterMembershipEditor(this.$store);
623
702
  },
@@ -814,6 +893,8 @@ export default {
814
893
  created() {
815
894
  this.registerBeforeHook(this.saveMachinePools, 'save-machine-pools', 1);
816
895
  this.registerBeforeHook(this.setRegistryConfig, 'set-registry-config');
896
+ this.registerBeforeHook(this.handleVsphereCpiSecret, 'sync-vsphere-cpi');
897
+ this.registerBeforeHook(this.handleVsphereCsiSecret, 'sync-vsphere-csi');
817
898
  this.registerAfterHook(this.cleanupMachinePools, 'cleanup-machine-pools');
818
899
  this.registerAfterHook(this.saveRoleBindings, 'save-role-bindings');
819
900
 
@@ -826,6 +907,14 @@ export default {
826
907
  methods: {
827
908
  set,
828
909
 
910
+ async handleVsphereCpiSecret() {
911
+ return VsphereUtils.handleVsphereCpiSecret(this);
912
+ },
913
+
914
+ async handleVsphereCsiSecret() {
915
+ return VsphereUtils.handleVsphereCsiSecret(this);
916
+ },
917
+
829
918
  /**
830
919
  * Initialize all the cluster specs
831
920
  */
@@ -1508,7 +1597,9 @@ export default {
1508
1597
  refreshComponentWithYamls(key) {
1509
1598
  const component = this.$refs[key];
1510
1599
 
1511
- if (component) {
1600
+ if (Array.isArray(component) && component.length > 0) {
1601
+ this.refreshYamls(component[0].$refs);
1602
+ } else if (component) {
1512
1603
  this.refreshYamls(component.$refs);
1513
1604
  }
1514
1605
  },
@@ -2225,6 +2316,8 @@ export default {
2225
2316
  :show-cni="showCni"
2226
2317
  :show-cloud-provider="showCloudProvider"
2227
2318
  :cloud-provider-options="cloudProviderOptions"
2319
+ :is-azure-provider-unsupported="isAzureProviderUnsupported"
2320
+ :can-azure-migrate-on-edit="canAzureMigrateOnEdit"
2228
2321
  @cilium-values-changed="handleCiliumValuesChanged"
2229
2322
  @enabled-system-services-changed="handleEnabledSystemServicesChanged"
2230
2323
  @kubernetes-changed="handleKubernetesChange"
@@ -2309,23 +2402,41 @@ export default {
2309
2402
  />
2310
2403
  </Tab>
2311
2404
 
2312
- <!-- Add-on Config -->
2405
+ <!-- Add-on Configs -->
2313
2406
  <Tab
2314
- name="addons"
2315
- label-key="cluster.tabs.addons"
2316
- @active="showAddons('tab-addOnConfig')"
2407
+ v-for="v in addonVersions"
2408
+ :key="v.name"
2409
+ :name="v.name"
2410
+ :label="labelForAddon(v.name, false)"
2411
+ :weight="9"
2412
+ :showHeader="false"
2413
+ @active="showAddons(v.name)"
2317
2414
  >
2318
2415
  <AddOnConfig
2319
- ref="tab-addOnConfig"
2416
+ :ref="v.name"
2320
2417
  v-model="value"
2321
2418
  :mode="mode"
2322
2419
  :version-info="versionInfo"
2323
- :addon-versions="addonVersions"
2420
+ :addon-version="v"
2324
2421
  :addons-rev="addonsRev"
2325
2422
  :user-chart-values-temp="userChartValuesTemp"
2326
2423
  :init-yaml-editor="initYamlEditor"
2327
2424
  @update-questions="syncChartValues"
2328
2425
  @update-values="updateValues"
2426
+ />
2427
+ </Tab>
2428
+
2429
+ <!-- Add-on Additional Manifest -->
2430
+ <Tab
2431
+ name="additionalmanifest"
2432
+ label-key="cluster.tabs.addOnAdditionalManifest"
2433
+ :showHeader="false"
2434
+ @active="refreshComponentWithYamls('additionalmanifest')"
2435
+ >
2436
+ <AddOnAdditionalManifest
2437
+ ref="additionalmanifest"
2438
+ :value="value"
2439
+ :mode="mode"
2329
2440
  @additional-manifest-changed="updateAdditionalManifest"
2330
2441
  />
2331
2442
  </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"