@rancher/shell 0.3.5 → 0.3.7

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 (120) hide show
  1. package/assets/images/providers/outscale.svg +19 -0
  2. package/assets/styles/base/_basic.scss +18 -0
  3. package/assets/styles/base/_mixins.scss +0 -11
  4. package/assets/styles/base/_variables.scss +2 -4
  5. package/assets/styles/global/_button.scss +12 -2
  6. package/assets/translations/en-us.yaml +35 -1
  7. package/assets/translations/zh-hans.yaml +30 -10
  8. package/chart/gatekeeper.vue +3 -2
  9. package/chart/istio.vue +29 -3
  10. package/components/BrandImage.vue +1 -4
  11. package/components/Carousel.vue +85 -37
  12. package/components/EtcdInfoBanner.vue +7 -3
  13. package/components/ExplorerMembers.vue +100 -5
  14. package/components/ExplorerProjectsNamespaces.vue +32 -2
  15. package/components/GrafanaDashboard.vue +9 -2
  16. package/components/SortableTable/index.vue +23 -11
  17. package/components/SortableTable/selection.js +58 -50
  18. package/components/Wizard.vue +4 -2
  19. package/components/auth/AuthBanner.vue +6 -0
  20. package/components/auth/RoleDetailEdit.vue +2 -2
  21. package/components/form/HookOption.vue +14 -10
  22. package/components/form/Labels.vue +32 -27
  23. package/components/form/MatchExpressions.vue +2 -2
  24. package/components/form/Members/ClusterPermissionsEditor.vue +32 -7
  25. package/components/form/NameNsDescription.vue +1 -1
  26. package/components/form/ProjectMemberEditor.vue +46 -21
  27. package/components/form/Tolerations.vue +4 -1
  28. package/components/form/ValueFromResource.vue +14 -9
  29. package/components/form/WorkloadPorts.vue +2 -2
  30. package/components/form/__tests__/NameNsDescription.ts +27 -0
  31. package/components/formatter/WorkloadHealthScale.vue +8 -2
  32. package/components/nav/NamespaceFilter.vue +8 -0
  33. package/{nuxt/components → components/nuxt}/nuxt.js +1 -1
  34. package/{nuxt → config}/middleware.js +8 -8
  35. package/config/product/explorer.js +24 -3
  36. package/config/query-params.js +1 -0
  37. package/config/router.js +1 -1
  38. package/{nuxt → config}/store.js +82 -79
  39. package/config/table-headers.js +46 -12
  40. package/config/types.js +7 -0
  41. package/core/plugin.ts +4 -2
  42. package/core/types.ts +258 -1
  43. package/creators/app/files/tsconfig.json +0 -1
  44. package/creators/app/files/vue.config.js +0 -1
  45. package/creators/pkg/files/.github/workflows/build-extension.yml +3 -4
  46. package/creators/pkg/files/tsconfig.json +0 -1
  47. package/creators/pkg/pkg.package.json +3 -3
  48. package/detail/constraints.gatekeeper.sh.constraint.vue +14 -7
  49. package/detail/fleet.cattle.io.clustergroup.vue +7 -1
  50. package/edit/auth/ldap/config.vue +21 -1
  51. package/edit/auth/saml.vue +132 -37
  52. package/edit/fleet.cattle.io.gitrepo.vue +16 -1
  53. package/edit/logging.banzaicloud.io.output/index.vue +18 -5
  54. package/edit/logging.banzaicloud.io.output/providers/loki.vue +1 -0
  55. package/edit/namespace.vue +12 -8
  56. package/edit/provisioning.cattle.io.cluster/MachinePool.vue +11 -4
  57. package/edit/provisioning.cattle.io.cluster/import.vue +23 -25
  58. package/edit/provisioning.cattle.io.cluster/rke2.vue +96 -18
  59. package/edit/workload/mixins/workload.js +6 -7
  60. package/edit/workload/storage/Mount.vue +3 -3
  61. package/initialize/App.js +206 -0
  62. package/{nuxt → initialize}/client.js +406 -360
  63. package/{nuxt → initialize}/index.js +21 -22
  64. package/layouts/standalone.vue +13 -0
  65. package/list/catalog.cattle.io.clusterrepo.vue +1 -0
  66. package/list/rbac.authorization.k8s.io.clusterrolebinding.vue +48 -0
  67. package/list/workload.vue +6 -4
  68. package/mixins/chart.js +29 -1
  69. package/mixins/fetch.client.js +95 -0
  70. package/{nuxt/mixins → mixins}/fetch.server.js +30 -26
  71. package/mixins/labeled-form-element.ts +2 -2
  72. package/models/constraints.gatekeeper.sh.constraint.js +37 -0
  73. package/models/pod.js +4 -0
  74. package/models/rbac.authorization.k8s.io.clusterrolebinding.js +16 -0
  75. package/models/rbac.authorization.k8s.io.rolebinding.js +16 -0
  76. package/package.json +9 -13
  77. package/pages/c/_cluster/apps/charts/install.vue +61 -39
  78. package/pages/diagnostic.vue +32 -25
  79. package/pages/rio/mesh.vue +1 -2
  80. package/pkg/tsconfig.json +0 -1
  81. package/plugins/clean-html-directive.js +3 -0
  82. package/plugins/dashboard-store/index.js +1 -1
  83. package/plugins/plugin.js +0 -14
  84. package/plugins/portal-vue.js +4 -0
  85. package/rancher-components/components/Banner/Banner.test.ts +3 -5
  86. package/rancher-components/components/Banner/Banner.vue +1 -0
  87. package/rancher-components/components/Form/Radio/RadioButton.test.ts +31 -0
  88. package/rancher-components/components/Form/Radio/RadioButton.vue +14 -3
  89. package/scripts/extension/publish +42 -23
  90. package/scripts/serve-pkgs +6 -2
  91. package/store/type-map.js +1 -1
  92. package/tsconfig.json +0 -1
  93. package/types/rancher/index.d.ts +2 -0
  94. package/types/shell/index.d.ts +353 -284
  95. package/utils/__tests__/grafana.test.ts +44 -0
  96. package/utils/axios.js +190 -0
  97. package/{nuxt → utils}/cookie-universal-nuxt.js +7 -6
  98. package/utils/dom.js +15 -0
  99. package/utils/gc/gc.ts +1 -1
  100. package/utils/grafana.js +35 -16
  101. package/{nuxt/utils.js → utils/nuxt.js} +265 -236
  102. package/utils/router.scrollBehavior.js +1 -1
  103. package/vue.config.js +30 -19
  104. package/nuxt/App.js +0 -210
  105. package/nuxt/axios.js +0 -186
  106. package/nuxt/empty.js +0 -1
  107. package/nuxt/jsonp.js +0 -82
  108. package/nuxt/loading.html +0 -39
  109. package/nuxt/mixins/fetch.client.js +0 -90
  110. package/nuxt/portal-vue.js +0 -4
  111. package/nuxt/server.js +0 -312
  112. package/nuxt/views/app.template.html +0 -9
  113. package/nuxt/views/error.html +0 -23
  114. package/plugins/dashboard-store/extensions.js +0 -22
  115. /package/{nuxt/components → components/nuxt}/nuxt-build-indicator.vue +0 -0
  116. /package/{nuxt/components → components/nuxt}/nuxt-child.js +0 -0
  117. /package/{nuxt/components → components/nuxt}/nuxt-error.vue +0 -0
  118. /package/{nuxt/components → components/nuxt}/nuxt-link.client.js +0 -0
  119. /package/{nuxt/components → components/nuxt}/nuxt-link.server.js +0 -0
  120. /package/{nuxt/components → components/nuxt}/nuxt-loading.vue +0 -0
@@ -24,6 +24,7 @@ import { isHarvesterCluster } from '@shell/utils/cluster';
24
24
  import { CAPI, CATALOG } from '@shell/config/labels-annotations';
25
25
  import { SECRET_TYPES } from '@shell/config/secret';
26
26
  import { checkSchemasForFindAllHash } from '@shell/utils/auth';
27
+ import Checkbox from '@components/Form/Checkbox/Checkbox.vue';
27
28
 
28
29
  const _VERIFY = 'verify';
29
30
  const _SKIP = 'skip';
@@ -33,6 +34,7 @@ export default {
33
34
  name: 'CruGitRepo',
34
35
 
35
36
  components: {
37
+ Checkbox,
36
38
  ArrayList,
37
39
  Banner,
38
40
  CruResource,
@@ -601,7 +603,20 @@ export default {
601
603
  </div>
602
604
  </template>
603
605
  <div class="spacer" />
604
-
606
+ <h2 v-t="'fleet.gitRepo.resources.label'" />
607
+ <Checkbox
608
+ v-model="value.spec.keepResources"
609
+ class="check"
610
+ type="checkbox"
611
+ label-key="fleet.gitRepo.resources.keepResources"
612
+ :mode="mode"
613
+ />
614
+ <Banner
615
+ color="info"
616
+ >
617
+ {{ t('fleet.gitRepo.resources.resourceBanner') }}
618
+ </Banner>
619
+ <div class="spacer" />
605
620
  <h2 v-t="'fleet.gitRepo.paths.label'" />
606
621
  <ArrayList
607
622
  v-model="value.spec.paths"
@@ -100,9 +100,6 @@ export default {
100
100
  }
101
101
  },
102
102
 
103
- created() {
104
- this.registerBeforeHook(this.willSave, 'willSave');
105
- },
106
103
  methods: {
107
104
  getComponent(name) {
108
105
  return require(`./providers/${ name }`).default;
@@ -110,7 +107,22 @@ export default {
110
107
  launch(provider) {
111
108
  this.$refs.tabbed.select(provider.name);
112
109
  },
113
- willSave() {
110
+ saveSettings(done) {
111
+ const t = this.$store.getters['i18n/t'];
112
+
113
+ if (this.selectedProvider === 'loki') {
114
+ const urlCheck = ['https://', 'http://'].some(checkValue => this.value.spec['loki'].url.toLowerCase().startsWith(checkValue));
115
+ const isLokiHttps = this.value.spec['loki'].url ? urlCheck : undefined;
116
+
117
+ if (!isLokiHttps) {
118
+ this.errors = [t('logging.loki.urlInvalid')];
119
+
120
+ return done(false);
121
+ }
122
+ }
123
+
124
+ this.errors = [];
125
+
114
126
  this.value.spec = { [this.selectedProvider]: this.value.spec[this.selectedProvider] };
115
127
 
116
128
  const bufferJson = jsyaml.load(this.bufferYaml);
@@ -120,6 +132,7 @@ export default {
120
132
  } else {
121
133
  this.$delete(this.value.spec[this.selectedProvider], 'buffer');
122
134
  }
135
+ this.save(done);
123
136
  },
124
137
  tabChanged({ tab }) {
125
138
  if ( tab.name === 'buffer' ) {
@@ -151,7 +164,7 @@ export default {
151
164
  :errors="errors"
152
165
  :can-yaml="true"
153
166
  @error="e=>errors = e"
154
- @finish="save"
167
+ @finish="saveSettings"
155
168
  @cancel="done"
156
169
  >
157
170
  <NameNsDescription
@@ -47,6 +47,7 @@ export default {
47
47
  :mode="mode"
48
48
  :disabled="disabled"
49
49
  class="url"
50
+ placeholder="https://127.0.0.1:8000"
50
51
  :label="t('logging.loki.url')"
51
52
  />
52
53
  </div>
@@ -10,7 +10,7 @@ import PodSecurityAdmission from '@shell/components/PodSecurityAdmission';
10
10
  import Tabbed from '@shell/components/Tabbed';
11
11
  import Tab from '@shell/components/Tabbed/Tab';
12
12
  import CruResource from '@shell/components/CruResource';
13
- import { PROJECT_ID, _VIEW } from '@shell/config/query-params';
13
+ import { PROJECT_ID, _VIEW, FLAT_VIEW, _CREATE } from '@shell/config/query-params';
14
14
  import MoveModal from '@shell/components/MoveModal';
15
15
  import ResourceQuota from '@shell/components/form/ResourceQuota/Namespace';
16
16
  import Loading from '@shell/components/Loading';
@@ -67,6 +67,10 @@ export default {
67
67
  computed: {
68
68
  ...mapGetters(['isSingleProduct']),
69
69
 
70
+ isCreate() {
71
+ return this.mode === _CREATE;
72
+ },
73
+
70
74
  isSingleHarvester() {
71
75
  return this.$store.getters['currentProduct'].inStore === HARVESTER && this.isSingleProduct;
72
76
  },
@@ -77,7 +81,6 @@ export default {
77
81
 
78
82
  // Filter out projects not for the current cluster
79
83
  projects = projects.filter(c => c.spec?.clusterName === clusterId);
80
-
81
84
  const out = projects.map((project) => {
82
85
  return {
83
86
  label: project.nameDisplay,
@@ -86,7 +89,7 @@ export default {
86
89
  });
87
90
 
88
91
  out.unshift({
89
- label: '(None)',
92
+ label: this.t('namespace.project.none'),
90
93
  value: null,
91
94
  });
92
95
 
@@ -105,6 +108,9 @@ export default {
105
108
  return !this.isSingleHarvester;
106
109
  },
107
110
 
111
+ flatView() {
112
+ return (this.$route.query[FLAT_VIEW] || false);
113
+ }
108
114
  },
109
115
 
110
116
  watch: {
@@ -139,13 +145,11 @@ export default {
139
145
  }
140
146
 
141
147
  const projects = this.$store.getters['management/all'](MANAGEMENT.PROJECT);
142
-
143
148
  const project = projects.find(p => p.id.includes(projectName));
144
149
 
145
150
  return project?.spec?.containerDefaultResourceLimit || {};
146
151
  }
147
- }
148
-
152
+ },
149
153
  };
150
154
  </script>
151
155
 
@@ -169,9 +173,10 @@ export default {
169
173
  :value="value"
170
174
  :namespaced="false"
171
175
  :mode="mode"
176
+ :extra-columns="['project-col']"
172
177
  >
173
178
  <template
174
- v-if="project"
179
+ v-if="flatView && isCreate"
175
180
  #project-col
176
181
  >
177
182
  <LabeledSelect
@@ -181,7 +186,6 @@ export default {
181
186
  />
182
187
  </template>
183
188
  </NameNsDescription>
184
-
185
189
  <Tabbed :side-tabs="true">
186
190
  <Tab
187
191
  v-if="showResourceQuota"
@@ -173,6 +173,14 @@ export default {
173
173
 
174
174
  <template>
175
175
  <div>
176
+ <Banner
177
+ v-if="value.pool.hostnameLengthLimit"
178
+ color="info"
179
+ >
180
+ <div class="text">
181
+ {{ t('cluster.machinePool.truncationPool', { limit: value.pool.hostnameLengthLimit }) }}
182
+ </div>
183
+ </Banner>
176
184
  <div class="row">
177
185
  <div class="col span-4">
178
186
  <LabeledInput
@@ -200,19 +208,19 @@ export default {
200
208
  <Checkbox
201
209
  v-model="value.pool.etcdRole"
202
210
  :mode="mode"
203
- label="etcd"
211
+ :label="t('cluster.machinePool.role.etcd')"
204
212
  :disabled="isWindows"
205
213
  />
206
214
  <Checkbox
207
215
  v-model="value.pool.controlPlaneRole"
208
216
  :mode="mode"
209
- label="Control Plane"
217
+ :label="t('cluster.machinePool.role.controlPlane')"
210
218
  :disabled="isWindows"
211
219
  />
212
220
  <Checkbox
213
221
  v-model="value.pool.workerRole"
214
222
  :mode="mode"
215
- label="Worker"
223
+ :label="t('cluster.machinePool.role.worker')"
216
224
  />
217
225
  </div>
218
226
  </div>
@@ -294,7 +302,6 @@ export default {
294
302
  :read-allowed="false"
295
303
  :value-can-be-empty="true"
296
304
  />
297
-
298
305
  <div class="spacer" />
299
306
 
300
307
  <Taints
@@ -135,31 +135,29 @@ export default {
135
135
  @finish="saveOverride"
136
136
  @error="e=>errors = e"
137
137
  >
138
- <div class="mt-20">
139
- <Banner
140
- v-if="harvesterLocation"
141
- color="info"
142
- :closable="true"
143
- class="mb-20"
144
- @close="hideHarvesterNotice"
145
- >
146
- {{ t('cluster.harvester.importNotice') }}
147
- <nuxt-link :to="harvesterLocation">
148
- {{ t('product.harvesterManager') }}
149
- </nuxt-link>
150
- </Banner>
151
-
152
- <NameNsDescription
153
- v-if="!isView"
154
- v-model="value"
155
- :mode="mode"
156
- :namespaced="false"
157
- name-label="cluster.name.label"
158
- name-placeholder="cluster.name.placeholder"
159
- description-label="cluster.description.label"
160
- description-placeholder="cluster.description.placeholder"
161
- />
162
- </div>
138
+ <Banner
139
+ v-if="harvesterLocation"
140
+ color="info"
141
+ :closable="true"
142
+ class="mb-20"
143
+ @close="hideHarvesterNotice"
144
+ >
145
+ {{ t('cluster.harvester.importNotice') }}
146
+ <nuxt-link :to="harvesterLocation">
147
+ {{ t('product.harvesterManager') }}
148
+ </nuxt-link>
149
+ </Banner>
150
+
151
+ <NameNsDescription
152
+ v-if="!isView"
153
+ v-model="value"
154
+ :mode="mode"
155
+ :namespaced="false"
156
+ name-label="cluster.name.label"
157
+ name-placeholder="cluster.name.placeholder"
158
+ description-label="cluster.description.label"
159
+ description-placeholder="cluster.description.placeholder"
160
+ />
163
161
 
164
162
  <Tabbed :side-tabs="true">
165
163
  <Tab
@@ -77,6 +77,26 @@ const ADVANCED = 'advanced';
77
77
  const HARVESTER = 'harvester';
78
78
  const HARVESTER_CLOUD_PROVIDER = 'harvester-cloud-provider';
79
79
 
80
+ const NETBIOS_TRUNCATION_LENGTH = 15;
81
+
82
+ /**
83
+ * Classes to be adopted by the node badges in Machine pools
84
+ */
85
+ const NODE_TOTAL = {
86
+ error: {
87
+ color: 'bg-error',
88
+ icon: 'icon-x',
89
+ },
90
+ warning: {
91
+ color: 'bg-warning',
92
+ icon: 'icon-warning',
93
+ },
94
+ success: {
95
+ color: 'bg-success',
96
+ icon: 'icon-checkmark'
97
+ }
98
+ };
99
+
80
100
  export default {
81
101
  components: {
82
102
  ACE,
@@ -286,6 +306,13 @@ export default {
286
306
  const lastDefaultPodSecurityPolicyTemplateName = this.value.spec.defaultPodSecurityPolicyTemplateName;
287
307
  const previousKubernetesVersion = this.value.spec.kubernetesVersion;
288
308
 
309
+ const truncateLimit = this.value.machinePoolDefaults?.hostnameLengthLimit;
310
+
311
+ // Is hostname truncation supported by the backend?
312
+ const provSchema = this.$store.getters['management/schemaFor'](CAPI.RANCHER_CLUSTER);
313
+ const specSchemaName = provSchema?.resourceFields?.spec?.type;
314
+ const specSchema = specSchemaName ? this.$store.getters['management/schemaFor'](specSchemaName) : {};
315
+
289
316
  return {
290
317
  loadedOnce: false,
291
318
  lastIdx: 0,
@@ -321,6 +348,9 @@ export default {
321
348
  cisOverride: false,
322
349
  cisPsaChangeBanner: false,
323
350
  psps: null, // List of policies if any
351
+ truncateHostnames: truncateLimit === NETBIOS_TRUNCATION_LENGTH,
352
+ truncateLimit,
353
+ supportsTruncation: !!specSchema?.resourceFields?.machinePoolDefaults,
324
354
  };
325
355
  },
326
356
 
@@ -337,6 +367,10 @@ export default {
337
367
  return this.value.spec.rkeConfig;
338
368
  },
339
369
 
370
+ hostnameTruncationManuallySet() {
371
+ return this.truncateLimit && this.truncateLimit !== NETBIOS_TRUNCATION_LENGTH;
372
+ },
373
+
340
374
  /**
341
375
  * Check presence of PSPs as template or CLI creation
342
376
  */
@@ -703,11 +737,11 @@ export default {
703
737
 
704
738
  for ( const role of roles ) {
705
739
  counts[role] = 0;
706
- out.color[role] = 'bg-success';
707
- out.icon[role] = 'icon-checkmark';
740
+ out.color[role] = NODE_TOTAL.success.color;
741
+ out.icon[role] = NODE_TOTAL.success.icon;
708
742
  }
709
743
 
710
- for ( const row of this.machinePools ) {
744
+ for ( const row of this.machinePools || [] ) {
711
745
  if ( row.remove ) {
712
746
  continue;
713
747
  }
@@ -729,27 +763,27 @@ export default {
729
763
  }
730
764
 
731
765
  if ( counts.etcd === 0 ) {
732
- out.color.etcd = 'bg-error';
733
- out.icon.etcd = 'icon-x';
766
+ out.color.etcd = NODE_TOTAL.error.color;
767
+ out.icon.etcd = NODE_TOTAL.error.icon;
734
768
  } else if ( counts.etcd === 1 || counts.etcd % 2 === 0 || counts.etcd > 7 ) {
735
- out.color.etcd = 'bg-warning';
736
- out.icon.etcd = 'icon-warning';
769
+ out.color.etcd = NODE_TOTAL.warning.color;
770
+ out.icon.etcd = NODE_TOTAL.warning.icon;
737
771
  }
738
772
 
739
773
  if ( counts.controlPlane === 0 ) {
740
- out.color.controlPlane = 'bg-error';
741
- out.icon.controlPlane = 'icon-x';
774
+ out.color.controlPlane = NODE_TOTAL.error.color;
775
+ out.icon.controlPlane = NODE_TOTAL.error.icon;
742
776
  } else if ( counts.controlPlane === 1 ) {
743
- out.color.controlPlane = 'bg-warning';
744
- out.icon.controlPlane = 'icon-warning';
777
+ out.color.controlPlane = NODE_TOTAL.warning.color;
778
+ out.icon.controlPlane = NODE_TOTAL.warning.icon;
745
779
  }
746
780
 
747
781
  if ( counts.worker === 0 ) {
748
- out.color.worker = 'bg-error';
749
- out.icon.worker = 'icon-x';
782
+ out.color.worker = NODE_TOTAL.error.color;
783
+ out.icon.worker = NODE_TOTAL.error.icon;
750
784
  } else if ( counts.worker === 1 ) {
751
- out.color.worker = 'bg-warning';
752
- out.icon.worker = 'icon-warning';
785
+ out.color.worker = NODE_TOTAL.warning.color;
786
+ out.icon.worker = NODE_TOTAL.warning.icon;
753
787
  }
754
788
 
755
789
  return out;
@@ -1061,6 +1095,21 @@ export default {
1061
1095
  nlToBr,
1062
1096
  set,
1063
1097
 
1098
+ /**
1099
+ * set instanceNameLimit to 15 to all pool machine if truncateHostnames checkbox is clicked
1100
+ */
1101
+ truncateName() {
1102
+ if (this.truncateHostnames) {
1103
+ this.value.machinePoolDefaults = this.value.machinePoolDefaults || {};
1104
+ this.value.machinePoolDefaults.hostnameLengthLimit = 15;
1105
+ } else {
1106
+ delete this.value.machinePoolDefaults.hostnameLengthLimit;
1107
+
1108
+ if (Object.keys(this.value.machinePoolDefaults).length === 0) {
1109
+ delete this.value.machinePoolDefaults;
1110
+ }
1111
+ }
1112
+ },
1064
1113
  /**
1065
1114
  * Define PSP deprecation and restrict use of PSP based on min k8s version and current/edited mode
1066
1115
  */
@@ -1219,7 +1268,6 @@ export default {
1219
1268
  }
1220
1269
 
1221
1270
  await this.syncMachineConfigWithLatest(entry);
1222
-
1223
1271
  // Capitals and such aren't allowed;
1224
1272
  set(entry.pool, 'name', normalizeName(entry.pool.name) || 'pool');
1225
1273
 
@@ -1269,8 +1317,17 @@ export default {
1269
1317
  }
1270
1318
  },
1271
1319
 
1320
+ /**
1321
+ * Ensure that all the existing node roles pool are at least 1 each
1322
+ */
1323
+ hasRequiredNodes() {
1324
+ return this.nodeTotals?.color && Object.values(this.nodeTotals.color).every(color => color !== NODE_TOTAL.error.color);
1325
+ },
1326
+
1272
1327
  validationPassed() {
1273
- return (this.provider === 'custom' || this.isElementalCluster || !!this.credentialId);
1328
+ const validMachinePools = this.hasMachinePools ? this.hasRequiredNodes() : true;
1329
+
1330
+ return (this.provider === 'custom' || this.isElementalCluster || !!this.credentialId) && validMachinePools;
1274
1331
  },
1275
1332
 
1276
1333
  cancelCredential() {
@@ -2540,8 +2597,29 @@ export default {
2540
2597
  :label="t('cluster.rke2.address.nodePortRange.label')"
2541
2598
  />
2542
2599
  </div>
2600
+ <div
2601
+ v-if="supportsTruncation"
2602
+ class="col span-6"
2603
+ >
2604
+ <Checkbox
2605
+ v-if="!isView || isView && !hostnameTruncationManuallySet"
2606
+ v-model="truncateHostnames"
2607
+ class="mt-20"
2608
+ :disabled="isEdit || isView || hostnameTruncationManuallySet"
2609
+ :mode="mode"
2610
+ :label="t('cluster.rke2.truncateHostnames')"
2611
+ @input="truncateName"
2612
+ />
2613
+ <Banner
2614
+ v-if="hostnameTruncationManuallySet"
2615
+ color="info"
2616
+ >
2617
+ <div class="text">
2618
+ {{ t('cluster.machinePool.truncationCluster', { limit: truncateLimit }) }}
2619
+ </div>
2620
+ </Banner>
2621
+ </div>
2543
2622
  </div>
2544
-
2545
2623
  <div
2546
2624
  v-if="serverArgs['tls-san']"
2547
2625
  class="row mb-20"
@@ -11,6 +11,7 @@ import {
11
11
  SERVICE_ACCOUNT,
12
12
  CAPI,
13
13
  POD,
14
+ LIST_WORKLOAD_TYPES,
14
15
  } from '@shell/config/types';
15
16
  import Tab from '@shell/components/Tabbed/Tab';
16
17
  import CreateEditView from '@shell/mixins/create-edit-view';
@@ -490,21 +491,19 @@ export default {
490
491
  return this.$store.getters['cluster/schemaFor'](this.type);
491
492
  },
492
493
 
493
- workloadTypes() {
494
- return omitBy(WORKLOAD_TYPES, (type) => {
494
+ // array of id, label, description, initials for type selection step
495
+ workloadSubTypes() {
496
+ const workloadTypes = omitBy(LIST_WORKLOAD_TYPES, (type) => {
495
497
  return (
496
498
  type === WORKLOAD_TYPES.REPLICA_SET ||
497
499
  type === WORKLOAD_TYPES.REPLICATION_CONTROLLER
498
500
  );
499
501
  });
500
- },
501
502
 
502
- // array of id, label, description, initials for type selection step
503
- workloadSubTypes() {
504
503
  const out = [];
505
504
 
506
- for (const prop in this.workloadTypes) {
507
- const type = this.workloadTypes[prop];
505
+ for (const prop in workloadTypes) {
506
+ const type = workloadTypes[prop];
508
507
  const subtype = {
509
508
  id: type,
510
509
  description: `workload.typeDescriptions.'${ type }'`,
@@ -138,13 +138,13 @@ export default {
138
138
  <style lang='scss'>
139
139
  .mount-headers, .mount-rows{
140
140
  display: grid;
141
- grid-template-columns: 35% 35% auto auto;
141
+ grid-template-columns: 42% 42% 5% auto;
142
142
  grid-gap: $column-gutter;
143
143
  margin-bottom: 10px;
144
144
  align-items: center;
145
145
 
146
- .remove {
147
- text-align: right;
146
+ .remove BUTTON {
147
+ padding: 0px;
148
148
  }
149
149
  }
150
150