@rancher/shell 0.3.27 → 0.3.28

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 (65) hide show
  1. package/assets/translations/en-us.yaml +4 -20
  2. package/assets/translations/zh-hans.yaml +0 -23
  3. package/chart/gatekeeper.vue +2 -11
  4. package/chart/istio.vue +1 -10
  5. package/chart/logging/index.vue +2 -11
  6. package/chart/monitoring/index.vue +1 -9
  7. package/chart/rancher-backup/index.vue +1 -9
  8. package/components/Carousel.vue +2 -1
  9. package/components/formatter/ClusterProvider.vue +1 -18
  10. package/components/nav/WindowManager/ContainerLogs.vue +22 -19
  11. package/config/product/manager.js +0 -13
  12. package/config/types.js +0 -4
  13. package/edit/management.cattle.io.project.vue +1 -52
  14. package/edit/management.cattle.io.setting.vue +31 -2
  15. package/edit/provisioning.cattle.io.cluster/Basics.vue +6 -107
  16. package/edit/provisioning.cattle.io.cluster/__tests__/Basics.tests.ts +0 -3
  17. package/edit/provisioning.cattle.io.cluster/rke2.vue +3 -128
  18. package/middleware/authenticated.js +4 -2
  19. package/models/__tests__/management.cattle.io.cluster.test.ts +19 -0
  20. package/models/__tests__/provisioning.cattle.io.cluster.test.ts +90 -0
  21. package/models/cluster.x-k8s.io.machine.js +1 -1
  22. package/models/management.cattle.io.cluster.js +4 -0
  23. package/models/management.cattle.io.project.js +0 -36
  24. package/models/management.cattle.io.setting.js +11 -7
  25. package/models/provisioning.cattle.io.cluster.js +16 -4
  26. package/package.json +1 -1
  27. package/pages/auth/setup.vue +38 -1
  28. package/pages/c/_cluster/apps/charts/__tests__/install.helper.test.ts +2 -17
  29. package/pages/c/_cluster/apps/charts/index.vue +0 -15
  30. package/pages/c/_cluster/apps/charts/install.helpers.js +2 -13
  31. package/pages/c/_cluster/apps/charts/install.vue +1 -1
  32. package/pages/c/_cluster/explorer/index.vue +0 -47
  33. package/pages/c/_cluster/manager/pages/_page.vue +4 -5
  34. package/rancher-components/BadgeState/BadgeState.vue +1 -5
  35. package/rancher-components/Banner/Banner.test.ts +1 -51
  36. package/rancher-components/Banner/Banner.vue +53 -134
  37. package/rancher-components/Card/Card.vue +7 -24
  38. package/rancher-components/Form/Checkbox/Checkbox.test.ts +29 -20
  39. package/rancher-components/Form/Checkbox/Checkbox.vue +20 -45
  40. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +8 -2
  41. package/rancher-components/Form/LabeledInput/LabeledInput.vue +10 -22
  42. package/rancher-components/Form/Radio/RadioButton.vue +13 -30
  43. package/rancher-components/Form/Radio/RadioGroup.vue +7 -26
  44. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +6 -7
  45. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.test.ts +38 -25
  46. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +11 -23
  47. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +5 -19
  48. package/rancher-components/StringList/StringList.test.ts +49 -453
  49. package/rancher-components/StringList/StringList.vue +58 -92
  50. package/rancher-components/components/StringList/StringList.test.ts +270 -0
  51. package/rancher-components/components/StringList/StringList.vue +57 -18
  52. package/store/prefs.js +0 -3
  53. package/types/shell/index.d.ts +22 -16
  54. package/utils/custom-validators.js +0 -2
  55. package/utils/error.js +16 -1
  56. package/utils/validators/formRules/__tests__/index.test.ts +49 -4
  57. package/utils/validators/formRules/index.ts +12 -9
  58. package/utils/validators/setting.js +6 -10
  59. package/.DS_Store +0 -0
  60. package/components/ChartPsp.vue +0 -76
  61. package/components/__tests__/ChartPsp.test.ts +0 -75
  62. package/components/formatter/__tests__/ClusterProvider.test.ts +0 -28
  63. package/rancher-components/Card/Card.test.ts +0 -37
  64. package/rancher-components/Form/Radio/RadioButton.test.ts +0 -31
  65. package/yarn-error.log +0 -200
@@ -40,12 +40,6 @@ export default {
40
40
  required: true,
41
41
  },
42
42
 
43
- psps: {
44
- type: Object,
45
- default: null,
46
- required: false
47
- },
48
-
49
43
  credential: {
50
44
  type: Object,
51
45
  default: null,
@@ -61,15 +55,6 @@ export default {
61
55
  required: true
62
56
  },
63
57
 
64
- cisPsaChangeBanner: {
65
- type: Boolean,
66
- required: true
67
- },
68
- allPsps: {
69
- type: Array,
70
- required: false,
71
- default: null
72
- },
73
58
  allPsas: {
74
59
  type: Array,
75
60
  required: true
@@ -80,10 +65,7 @@ export default {
80
65
  required: false,
81
66
  default: null
82
67
  },
83
- needsPsp: {
84
- type: Boolean,
85
- required: true
86
- },
68
+
87
69
  selectedVersion: {
88
70
  type: Object,
89
71
  required: true
@@ -112,10 +94,6 @@ export default {
112
94
  type: Boolean,
113
95
  required: true
114
96
  },
115
- hasPsaTemplates: {
116
- type: Boolean,
117
- required: true
118
- },
119
97
  isK3s: {
120
98
  type: Boolean,
121
99
  required: true
@@ -145,14 +123,6 @@ export default {
145
123
  computed: {
146
124
  ...mapGetters({ features: 'features/get' }),
147
125
 
148
- /**
149
- * Check presence of PSPs as template or CLI creation
150
- */
151
-
152
- hasPsps() {
153
- return !!this.psps?.count;
154
- },
155
-
156
126
  serverConfig() {
157
127
  return this.value.spec.rkeConfig.machineGlobalConfig;
158
128
  },
@@ -161,17 +131,6 @@ export default {
161
131
  return this.value.agentConfig;
162
132
  },
163
133
 
164
- /**
165
- * Define introduction of PSA and return need of PSA templates based on min k8s version
166
- */
167
- needsPSA() {
168
- const release = this.value?.spec?.kubernetesVersion || '';
169
- const version = release.match(/\d+/g);
170
- const isRequiredVersion = version?.length ? +version[0] > 1 || +version[1] >= 23 : false;
171
-
172
- return isRequiredVersion;
173
- },
174
-
175
134
  profileOptions() {
176
135
  const out = (this.agentArgs?.profile?.options || []).map((x) => {
177
136
  return { label: x, value: x };
@@ -189,35 +148,9 @@ export default {
189
148
  * Allow to display override if PSA is needed and profile is set
190
149
  */
191
150
  hasCisOverride() {
192
- return (this.serverConfig?.profile || this.agentConfig?.profile) && this.needsPSA &&
151
+ return (this.serverConfig?.profile || this.agentConfig?.profile) &&
193
152
  // Also check other cases on when to display the override
194
- this.hasPsaTemplates && this.showCisProfile && this.isCisSupported;
195
- },
196
-
197
- pspOptions() {
198
- if ( this.isK3s ) {
199
- return null;
200
- }
201
- const out = [{
202
- label: this.$store.getters['i18n/t']('cluster.rke2.defaultPodSecurityPolicyTemplateName.option'),
203
- value: ''
204
- }];
205
-
206
- if ( this.allPsps ) {
207
- for ( const pspt of this.allPsps ) {
208
- out.push({
209
- label: pspt.nameDisplay,
210
- value: pspt.id,
211
- });
212
- }
213
- }
214
- const cur = this.value.spec.defaultPodSecurityPolicyTemplateName;
215
-
216
- if ( cur && !out.find((x) => x.value === cur) ) {
217
- out.unshift({ label: `${ cur } (Current)`, value: cur });
218
- }
219
-
220
- return out;
153
+ this.showCisProfile && this.isCisSupported;
221
154
  },
222
155
 
223
156
  /**
@@ -226,14 +159,14 @@ export default {
226
159
  isPsaDisabled() {
227
160
  const cisValue = this.agentConfig?.profile || this.serverConfig?.profile;
228
161
 
229
- return !(!cisValue || this.cisOverride) && this.hasPsaTemplates && this.isCisSupported;
162
+ return !(!cisValue || this.cisOverride) && this.isCisSupported;
230
163
  },
231
164
 
232
165
  /**
233
166
  * Get the default label for the PSA template option
234
167
  */
235
168
  defaultPsaOptionLabel() {
236
- const optionCase = !this.needsPsp && !this.isK3s ? 'default' : 'none';
169
+ const optionCase = !this.isK3s ? 'default' : 'none';
237
170
 
238
171
  return this.$store.getters['i18n/t'](`cluster.rke2.defaultPodSecurityAdmissionConfigurationTemplateName.option.${ optionCase }`);
239
172
  },
@@ -242,9 +175,6 @@ export default {
242
175
  * Convert PSA templates into options, sorting and flagging if any selected
243
176
  */
244
177
  psaOptions() {
245
- if ( !this.needsPSA ) {
246
- return [];
247
- }
248
178
  const out = [{
249
179
  label: this.defaultPsaOptionLabel,
250
180
  value: ''
@@ -515,21 +445,6 @@ export default {
515
445
  <h3>
516
446
  {{ t('cluster.rke2.security.header') }}
517
447
  </h3>
518
- <Banner
519
- v-if="isEdit && !needsPsp && hasPsps"
520
- color="warning"
521
- :label="t('cluster.banner.invalidPsps')"
522
- />
523
- <Banner
524
- v-else-if="isCreate && !needsPsp"
525
- color="info"
526
- :label="t('cluster.banner.removedPsp')"
527
- />
528
- <Banner
529
- v-else-if="isCreate && hasPsps"
530
- color="info"
531
- :label="t('cluster.banner.deprecatedPsp')"
532
- />
533
448
 
534
449
  <Banner
535
450
  v-if="showCisProfile && !isCisSupported && isEdit"
@@ -539,21 +454,6 @@ export default {
539
454
  </Banner>
540
455
 
541
456
  <div class="row mb-10">
542
- <div
543
- v-if="pspOptions && needsPsp"
544
- class="col span-6"
545
- >
546
- <!-- PSP template selector -->
547
- <LabeledSelect
548
- v-model="value.spec.defaultPodSecurityPolicyTemplateName"
549
- data-testid="rke2-custom-edit-psp"
550
- :mode="mode"
551
- :options="pspOptions"
552
- :label="t('cluster.rke2.defaultPodSecurityPolicyTemplateName.label')"
553
- @input="$emit('psp-changed', $event)"
554
- />
555
- </div>
556
-
557
457
  <div
558
458
  v-if="showCisProfile"
559
459
  class="col span-6"
@@ -592,14 +492,13 @@ export default {
592
492
  :label="t('cluster.rke2.banner.cisOverride')"
593
493
  />
594
494
  <Banner
595
- v-if="cisPsaChangeBanner && !cisOverride"
495
+ v-if="!cisOverride"
596
496
  color="info"
597
497
  :label="t('cluster.rke2.banner.psaChange')"
598
498
  />
599
499
  </template>
600
500
 
601
501
  <div
602
- v-if="needsPSA"
603
502
  class="row mb-10 mt-10"
604
503
  >
605
504
  <div class="col span-6">
@@ -95,7 +95,6 @@ describe('component: Basics', () => {
95
95
  cisOverride: false,
96
96
  cisPsaChangeBanner: true,
97
97
  allPsas: [],
98
- needsPsp: false,
99
98
  selectedVersion: k8s,
100
99
  versionOptions: mockVersionOptions,
101
100
  isHarvesterDriver: false,
@@ -149,7 +148,6 @@ describe('component: Basics', () => {
149
148
  cisOverride: false,
150
149
  cisPsaChangeBanner: true,
151
150
  allPsas: [],
152
- needsPsp: false,
153
151
  selectedVersion: mockVersionOptions[0],
154
152
  versionOptions: mockVersionOptions,
155
153
  isHarvesterDriver: false,
@@ -200,7 +198,6 @@ describe('component: Basics', () => {
200
198
  userChartValues: {},
201
199
  cisPsaChangeBanner: true,
202
200
  allPsas: [],
203
- needsPsp: false,
204
201
  cisOverride: override,
205
202
  selectedVersion: mockVersionOptions[0],
206
203
  versionOptions: [{
@@ -16,7 +16,6 @@ import {
16
16
  DEFAULT_WORKSPACE,
17
17
  SECRET,
18
18
  HCI,
19
- PSPS,
20
19
  } from '@shell/config/types';
21
20
  import { _CREATE, _EDIT, _VIEW } from '@shell/config/query-params';
22
21
 
@@ -31,7 +30,6 @@ import { sortBy } from '@shell/utils/sort';
31
30
  import { camelToTitle } from '@shell/utils/string';
32
31
  import { compare, sortable } from '@shell/utils/version';
33
32
  import { isHarvesterSatisfiesVersion } from '@shell/utils/cluster';
34
- import * as VERSION from '@shell/utils/version';
35
33
 
36
34
  import ArrayList from '@shell/components/form/ArrayList';
37
35
  import ArrayListGrouped from '@shell/components/form/ArrayListGrouped';
@@ -155,7 +153,6 @@ export default {
155
153
  },
156
154
 
157
155
  async fetch() {
158
- this.psps = await this.getPsps();
159
156
  await this.fetchRke2Versions();
160
157
  await this.initSpecs();
161
158
  await this.initAddons();
@@ -196,16 +193,11 @@ export default {
196
193
  set(this.value.spec, 'rkeConfig.machineSelectorConfig', [{ config: {} }]);
197
194
  }
198
195
 
199
- // Store the initial PSP template name, so we can set it back if needed
200
- const lastDefaultPodSecurityPolicyTemplateName = this.value.spec.defaultPodSecurityPolicyTemplateName;
201
- const previousKubernetesVersion = this.value.spec.kubernetesVersion;
202
-
203
196
  const truncateLimit = this.value.defaultHostnameLengthLimit;
204
197
 
205
198
  return {
206
199
  loadedOnce: false,
207
200
  lastIdx: 0,
208
- allPSPs: null,
209
201
  allPSAs: [],
210
202
  credentialId: '',
211
203
  credential: null,
@@ -238,11 +230,7 @@ export default {
238
230
  path: 'metadata.name', rules: ['subDomain'], translationKey: 'nameNsDescription.name.label'
239
231
  }],
240
232
  harvesterVersionRange: {},
241
- lastDefaultPodSecurityPolicyTemplateName, // Used for reset on k8s version changes
242
- previousKubernetesVersion,
243
233
  cisOverride: false,
244
- cisPsaChangeBanner: false,
245
- psps: null, // List of policies if any
246
234
  truncateHostnames: truncateLimit === NETBIOS_TRUNCATION_LENGTH,
247
235
  truncateLimit,
248
236
  busy: false,
@@ -286,20 +274,6 @@ export default {
286
274
  return this.value.agentConfig;
287
275
  },
288
276
 
289
- /**
290
- * Define PSP deprecation and restrict use of PSP based on min k8s version
291
- */
292
- needsPSP() {
293
- return this.getNeedsPSP();
294
- },
295
-
296
- /**
297
- * Define introduction of Rancher defined PSA templates
298
- */
299
- hasPsaTemplates() {
300
- return !this.needsPSP;
301
- },
302
-
303
277
  unsupportedSelectorConfig() {
304
278
  let global = 0;
305
279
  let kubeletOnly = 0;
@@ -933,10 +907,6 @@ export default {
933
907
  }
934
908
  }
935
909
 
936
- if ( this.value.spec.defaultPodSecurityPolicyTemplateName === undefined ) {
937
- set(this.value.spec, 'defaultPodSecurityPolicyTemplateName', '');
938
- }
939
-
940
910
  if ( this.value.spec.defaultPodSecurityAdmissionConfigurationTemplateName === undefined ) {
941
911
  set(this.value.spec, 'defaultPodSecurityAdmissionConfigurationTemplateName', '');
942
912
  }
@@ -952,10 +922,6 @@ export default {
952
922
  k3sVersions: this.$store.dispatch('management/request', { url: '/v1-k3s-release/releases' }),
953
923
  };
954
924
 
955
- if ( this.$store.getters['management/canList'](MANAGEMENT.POD_SECURITY_POLICY_TEMPLATE) ) {
956
- hash.allPSPs = await this.$store.dispatch('management/findAll', { type: MANAGEMENT.POD_SECURITY_POLICY_TEMPLATE });
957
- }
958
-
959
925
  if (this.$store.getters['management/canList'](MANAGEMENT.PSA)) {
960
926
  hash.allPSAs = await this.$store.dispatch('management/findAll', { type: MANAGEMENT.PSA });
961
927
  }
@@ -980,7 +946,6 @@ export default {
980
946
 
981
947
  const res = await allHash(hash);
982
948
 
983
- this.allPSPs = res.allPSPs || [];
984
949
  this.allPSAs = res.allPSAs || [];
985
950
  this.rke2Versions = res.rke2Versions.data || [];
986
951
  this.k3sVersions = res.k3sVersions.data || [];
@@ -1069,16 +1034,6 @@ export default {
1069
1034
  this.value.removeDefaultHostnameLengthLimit();
1070
1035
  }
1071
1036
  },
1072
- /**
1073
- * Define PSP deprecation and restrict use of PSP based on min k8s version and current/edited mode
1074
- */
1075
- getNeedsPSP(value = this.value) {
1076
- const release = value?.spec?.kubernetesVersion || '';
1077
- const version = release.match(/\d+/g);
1078
- const isRequiredVersion = version?.length ? +version[0] === 1 && +version[1] < 25 : false;
1079
-
1080
- return isRequiredVersion;
1081
- },
1082
1037
 
1083
1038
  /**
1084
1039
  * Get machine pools from the cluster configuration
@@ -1359,23 +1314,6 @@ export default {
1359
1314
  });
1360
1315
  },
1361
1316
 
1362
- /**
1363
- * Inform user to remove PSP for current cluster due deprecation
1364
- */
1365
- showPspConfirmation() {
1366
- return new Promise((resolve, reject) => {
1367
- this.$store.dispatch('cluster/promptModal', {
1368
- component: 'GenericPrompt',
1369
- componentProps: {
1370
- title: this.t('cluster.rke2.modal.pspChange.title'),
1371
- body: this.t('cluster.rke2.modal.pspChange.body'),
1372
- applyMode: 'continue',
1373
- confirm: resolve
1374
- },
1375
- });
1376
- });
1377
- },
1378
-
1379
1317
  // Set busy before save and clear after save
1380
1318
  async saveOverride(btnCb) {
1381
1319
  this.$set(this, 'busy', true);
@@ -1413,13 +1351,6 @@ export default {
1413
1351
  }
1414
1352
 
1415
1353
  const isEditVersion = this.isEdit && this.liveValue?.spec?.kubernetesVersion !== this.value?.spec?.kubernetesVersion;
1416
- const hasPspManuallyAdded = !!this.value.spec.rkeConfig?.machineGlobalConfig?.['kube-apiserver-arg'];
1417
-
1418
- if (isEditVersion && !this.needsPSP && hasPspManuallyAdded) {
1419
- if (!await this.showPspConfirmation()) {
1420
- return btnCb('cancelled');
1421
- }
1422
- }
1423
1354
 
1424
1355
  if (isEditVersion) {
1425
1356
  const shouldContinue = await this.showAddonConfirmation();
@@ -1969,28 +1900,6 @@ export default {
1969
1900
  }
1970
1901
  },
1971
1902
 
1972
- /**
1973
- * Get provisioned RKE2 cluster PSPs in edit mode
1974
- */
1975
- async getPsps() {
1976
- // As server returns 500 we exclude all the possible cases
1977
- if (
1978
- this.mode !== _CREATE &&
1979
- !this.isK3s &&
1980
- this.value.state !== 'reconciling' &&
1981
- this.getNeedsPSP(this.liveValue) // We consider editing only possible PSP cases
1982
- ) {
1983
- const clusterId = this.value.mgmtClusterId;
1984
- const url = `/k8s/clusters/${ clusterId }/v1/${ PSPS }`;
1985
-
1986
- try {
1987
- return await this.$store.dispatch('cluster/request', { url });
1988
- } catch (error) {
1989
- // PSP may not exists for this cluster and an error is returned without need to handle
1990
- }
1991
- }
1992
- },
1993
-
1994
1903
  /**
1995
1904
  * Reset PSA on several input changes for given conditions
1996
1905
  */
@@ -2000,11 +1909,9 @@ export default {
2000
1909
  const cisValue = this.agentConfig?.profile || this.serverConfig?.profile;
2001
1910
 
2002
1911
  if (!this.cisOverride) {
2003
- if (this.hasPsaTemplates && cisValue) {
1912
+ if (cisValue) {
2004
1913
  set(this.value.spec, 'defaultPodSecurityAdmissionConfigurationTemplateName', hardcodedTemplate);
2005
1914
  }
2006
-
2007
- this.cisPsaChangeBanner = this.hasPsaTemplates;
2008
1915
  }
2009
1916
  },
2010
1917
 
@@ -2027,28 +1934,11 @@ export default {
2027
1934
  },
2028
1935
 
2029
1936
  /**
2030
- * Handle k8s changes side effects, like PSP and PSA resets
1937
+ * Handle k8s changes side effects, like PSA resets
2031
1938
  */
2032
1939
  handleKubernetesChange(value) {
2033
1940
  if (value) {
2034
1941
  this.togglePsaDefault();
2035
- const version = VERSION.parse(value);
2036
- const major = parseInt(version?.[0] || 0);
2037
- const minor = parseInt(version?.[1] || 0);
2038
-
2039
- // Reset PSA if not RKE2
2040
- if (!value.includes('rke2')) {
2041
- set(this.value.spec, 'defaultPodSecurityPolicyTemplateName', '');
2042
- } else {
2043
- // Reset PSP if it's legacy due k8s version 1.25+
2044
- if (major === 1 && minor >= 25) {
2045
- set(this.value.spec, 'defaultPodSecurityPolicyTemplateName', '');
2046
- } else {
2047
- set(this.value.spec, 'defaultPodSecurityPolicyTemplateName', this.lastDefaultPodSecurityPolicyTemplateName);
2048
- }
2049
-
2050
- this.previousKubernetesVersion = value;
2051
- }
2052
1942
 
2053
1943
  // If Harvester driver, reset cloud provider if not compatible
2054
1944
  if (this.isHarvesterDriver && this.mode === _CREATE && this.isHarvesterIncompatible) {
@@ -2069,13 +1959,6 @@ export default {
2069
1959
  }
2070
1960
  },
2071
1961
 
2072
- /**
2073
- * Keep last PSP value
2074
- */
2075
- handlePspChange(value) {
2076
- this.lastDefaultPodSecurityPolicyTemplateName = value;
2077
- },
2078
-
2079
1962
  handleShowDeprecatedPatchVersionsChanged(value) {
2080
1963
  this.showDeprecatedPatchVersions = value;
2081
1964
  },
@@ -2110,9 +1993,7 @@ export default {
2110
1993
  }
2111
1994
  });
2112
1995
  },
2113
- handlePspChanged(neu) {
2114
- this.handlePspChange(neu);
2115
- },
1996
+
2116
1997
  handleCisChanged() {
2117
1998
  this.handleCisChange();
2118
1999
  },
@@ -2317,23 +2198,18 @@ export default {
2317
2198
  :live-value="liveValue"
2318
2199
  :mode="mode"
2319
2200
  :provider="provider"
2320
- :psps="psps"
2321
2201
  :user-chart-values="userChartValues"
2322
2202
  :credential="credential"
2323
2203
  :cis-override="cisOverride"
2324
- :cis-psa-change-banner="cisPsaChangeBanner"
2325
- :all-psps="allPSPs"
2326
2204
  :all-psas="allPSAs"
2327
2205
  :addon-versions="addonVersions"
2328
2206
  :show-deprecated-patch-versions="showDeprecatedPatchVersions"
2329
- :needs-psp="needsPSP"
2330
2207
  :selected-version="selectedVersion"
2331
2208
  :is-harvester-driver="isHarvesterDriver"
2332
2209
  :is-harvester-incompatible="isHarvesterIncompatible"
2333
2210
  :version-options="versionOptions"
2334
2211
  :cluster-is-already-created="clusterIsAlreadyCreated"
2335
2212
  :is-elemental-cluster="isElementalCluster"
2336
- :has-psa-templates="hasPsaTemplates"
2337
2213
  :is-k3s="isK3s"
2338
2214
  :have-arg-info="haveArgInfo"
2339
2215
  :show-cni="showCni"
@@ -2343,7 +2219,6 @@ export default {
2343
2219
  @cilium-ipv6-changed="handleCiliumIpv6Changed"
2344
2220
  @enabled-system-services-changed="handleEnabledSystemServicesChanged"
2345
2221
  @kubernetes-changed="handleKubernetesChange"
2346
- @psp-changed="handlePspChanged"
2347
2222
  @cis-changed="handleCisChanged"
2348
2223
  @psa-default-changed="handlePsaDefaultChanged"
2349
2224
  @show-deprecated-patch-versions-changed="handleShowDeprecatedPatchVersionsChanged"
@@ -8,7 +8,7 @@ import { MANAGEMENT, NORMAN, DEFAULT_WORKSPACE } from '@shell/config/types';
8
8
  import { _ALL_IF_AUTHED } from '@shell/plugins/dashboard-store/actions';
9
9
  import { applyProducts } from '@shell/store/type-map';
10
10
  import { findBy } from '@shell/utils/array';
11
- import { ClusterNotFoundError } from '@shell/utils/error';
11
+ import { ClusterNotFoundError, RedirectToError } from '@shell/utils/error';
12
12
  import { get } from '@shell/utils/object';
13
13
  import { setFavIcon, haveSetFavIcon } from '@shell/utils/favicon';
14
14
  import dynamicPluginLoader from '@shell/pkg/dynamic-plugin-loader';
@@ -502,8 +502,10 @@ export default async function({
502
502
  }
503
503
  }
504
504
  } catch (e) {
505
- if ( e instanceof ClusterNotFoundError ) {
505
+ if ( e.name === ClusterNotFoundError.name ) {
506
506
  return redirect(302, '/home');
507
+ } if ( e.name === RedirectToError.name ) {
508
+ return redirect(302, e.url);
507
509
  } else {
508
510
  // Sets error 500 if lost connection to API
509
511
  store.commit('setError', { error: e, locationError: new Error(store.getters['i18n/t']('nav.failWhale.authMiddleware')) });
@@ -0,0 +1,19 @@
1
+ import MgmtCluster from '@shell/models/management.cattle.io.cluster';
2
+
3
+ describe('class MgmtCluster', () => {
4
+ describe('provisioner', () => {
5
+ const testCases = [
6
+ [{ provider: 'rke', driver: 'imported' }, 'rke'],
7
+ [{ provider: 'k3s', driver: 'K3S' }, 'k3s'],
8
+ [{ provider: 'aks', driver: 'AKS' }, 'aks'],
9
+ [{}, 'imported'],
10
+ ];
11
+
12
+ it.each(testCases)('should return provisioner value properly based on the props data', (clusterData: Object, expected: String) => {
13
+ const cluster = new MgmtCluster({ status: clusterData });
14
+
15
+ expect(cluster.provisioner).toBe(expected);
16
+ }
17
+ );
18
+ });
19
+ });
@@ -0,0 +1,90 @@
1
+ import ProvCluster from '@shell/models/provisioning.cattle.io.cluster';
2
+
3
+ describe('class ProvCluster', () => {
4
+ const importedClusterInfo = {
5
+ clusterName: 'test', provisioner: 'imported', mgmt: { spec: { gkeConfig: {} } }, spec: {}
6
+ };
7
+ const importedGkeClusterInfo = {
8
+ clusterName: 'test', provisioner: 'rke2', mgmt: { spec: { gkeConfig: { imported: true } } }
9
+ };
10
+ const importedAksClusterInfo = {
11
+ clusterName: 'test', provisioner: 'rke2', mgmt: { spec: { aksConfig: { imported: true } } }
12
+ };
13
+ const importedEksClusterInfo = {
14
+ clusterName: 'test', provisioner: 'rke2', mgmt: { spec: { eksConfig: { imported: true } } }
15
+ };
16
+ const notImportedGkeClusterInfo = {
17
+ clusterName: 'test', provisioner: 'rke2', mgmt: { spec: { gkeConfig: { imported: false } }, rkeConfig: {} }
18
+ };
19
+ const importedClusterInfoWithProviderForEmberParam = {
20
+ clusterName: 'test', provisioner: 'rke2', mgmt: { providerForEmberParam: 'import' }
21
+ };
22
+ const localClusterInfo = {
23
+ clusterName: 'test', provisioner: 'imported', mgmt: { isLocal: true, spec: { gkeConfig: {} } }, spec: {}
24
+ };
25
+ const doRke2Info = {
26
+ clusterName: 'test', provisioner: 'rke2', mgmt: { isLocal: false, providerForEmberParam: 'import' }, spec: { rkeConfig: {} }
27
+ };
28
+
29
+ describe('isImported', () => {
30
+ const testCases = [
31
+ [importedClusterInfo, true],
32
+ [importedGkeClusterInfo, true],
33
+ [importedAksClusterInfo, true],
34
+ [importedEksClusterInfo, true],
35
+ [notImportedGkeClusterInfo, false],
36
+ [importedClusterInfoWithProviderForEmberParam, true],
37
+ [localClusterInfo, false],
38
+ [doRke2Info, false],
39
+ [{}, false],
40
+ ];
41
+ const resetMocks = () => {
42
+ // Clear all mock function calls:
43
+ jest.clearAllMocks();
44
+ };
45
+
46
+ it.each(testCases)('should return the isImported value properly based on the props data', (clusterData: Object, expected: Boolean) => {
47
+ const cluster = new ProvCluster({ spec: clusterData.spec });
48
+
49
+ jest.spyOn(cluster, 'mgmt', 'get').mockReturnValue(
50
+ clusterData.mgmt
51
+ );
52
+ jest.spyOn(cluster, 'provisioner', 'get').mockReturnValue(
53
+ clusterData.provisioner
54
+ );
55
+
56
+ expect(cluster.isImported).toBe(expected);
57
+ resetMocks();
58
+ }
59
+ );
60
+ });
61
+
62
+ describe('mgmt', () => {
63
+ const testCases = [
64
+ [importedClusterInfo, importedClusterInfo.mgmt],
65
+ [importedGkeClusterInfo, importedGkeClusterInfo.mgmt],
66
+ [importedAksClusterInfo, importedAksClusterInfo.mgmt],
67
+ [importedEksClusterInfo, importedEksClusterInfo.mgmt],
68
+ [notImportedGkeClusterInfo, notImportedGkeClusterInfo.mgmt],
69
+ [importedClusterInfoWithProviderForEmberParam, importedClusterInfoWithProviderForEmberParam.mgmt],
70
+ [localClusterInfo, localClusterInfo.mgmt],
71
+ [doRke2Info, doRke2Info.mgmt],
72
+ [{}, null],
73
+ ];
74
+
75
+ const resetMocks = () => {
76
+ // Clear all mock function calls:
77
+ jest.clearAllMocks();
78
+ };
79
+
80
+ it.each(testCases)('should return the isImported value properly based on the props data', (clusterData: Object, expected: Object) => {
81
+ const clusterMock = jest.fn(() => clusterData.mgmt);
82
+ const ctx = { rootGetters: { 'management/byId': clusterMock } };
83
+ const cluster = new ProvCluster({ status: { clusterName: clusterData.clusterName } }, ctx);
84
+
85
+ expect(cluster.mgmt).toBe(expected);
86
+ resetMocks();
87
+ }
88
+ );
89
+ });
90
+ });
@@ -231,7 +231,7 @@ export default class CapiMachine extends SteveModel {
231
231
  return false;
232
232
  }
233
233
 
234
- return notOnlyOfRole(this, this.cluster.machines);
234
+ return notOnlyOfRole(this, this.cluster?.machines);
235
235
  }
236
236
 
237
237
  get roles() {
@@ -88,6 +88,10 @@ export default class MgmtCluster extends HybridModel {
88
88
  }
89
89
 
90
90
  get provisioner() {
91
+ if (this.status?.provider ) {
92
+ return this.status.provider;
93
+ }
94
+
91
95
  // For imported K3s clusters, this.status.driver is 'k3s.'
92
96
  return this.status?.driver ? this.status.driver : 'imported';
93
97
  }