@rancher/shell 3.0.5-rc.6 → 3.0.5-rc.8
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.
- package/assets/brand/classic/metadata.json +3 -0
- package/assets/styles/app.scss +1 -0
- package/assets/styles/base/_color.scss +16 -0
- package/assets/styles/base/_helpers.scss +10 -0
- package/assets/styles/base/_variables.scss +18 -12
- package/assets/styles/fonts/_icons.scss +1 -32
- package/assets/styles/global/_layout.scss +1 -1
- package/assets/styles/themes/_dark.scss +262 -258
- package/assets/styles/themes/_light.scss +538 -509
- package/assets/styles/themes/_modern.scss +914 -0
- package/assets/translations/en-us.yaml +110 -29
- package/chart/__tests__/S3.test.ts +2 -1
- package/cloud-credential/generic.vue +18 -10
- package/cloud-credential/harvester.vue +1 -9
- package/components/AdvancedSection.vue +8 -0
- package/components/ChartReadme.vue +17 -7
- package/components/CodeMirror.vue +1 -1
- package/components/Drawer/Chrome.vue +0 -1
- package/components/Drawer/ResourceDetailDrawer/__tests__/composables.test.ts +27 -28
- package/components/Drawer/ResourceDetailDrawer/composables.ts +4 -24
- package/components/Drawer/ResourceDetailDrawer/index.vue +18 -4
- package/components/InstallHelmCharts.vue +656 -0
- package/components/LazyImage.vue +60 -4
- package/components/Loading.vue +1 -1
- package/components/LocaleSelector.vue +7 -2
- package/components/Markdown.vue +4 -0
- package/components/PaginatedResourceTable.vue +46 -1
- package/components/PromptRestore.vue +22 -44
- package/components/Resource/Detail/Masthead/composable.ts +16 -0
- package/components/Resource/Detail/Masthead/index.vue +37 -0
- package/components/Resource/Detail/Metadata/IdentifyingInformation/composable.ts +10 -2
- package/components/Resource/Detail/Metadata/IdentifyingInformation/identifying-fields.ts +26 -7
- package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +8 -1
- package/components/Resource/Detail/Metadata/KeyValue.vue +12 -10
- package/components/Resource/Detail/Metadata/Rectangle.vue +3 -1
- package/components/Resource/Detail/Metadata/__tests__/composables.test.ts +10 -17
- package/components/Resource/Detail/Metadata/composables.ts +9 -7
- package/components/Resource/Detail/Metadata/index.vue +17 -2
- package/components/Resource/Detail/Page.vue +35 -21
- package/components/Resource/Detail/SpacedRow.vue +1 -1
- package/components/Resource/Detail/TitleBar/__tests__/composables.test.ts +8 -9
- package/components/Resource/Detail/TitleBar/composables.ts +5 -5
- package/components/Resource/Detail/TitleBar/index.vue +12 -3
- package/components/ResourceDetail/Masthead/legacy.vue +1 -1
- package/components/ResourceDetail/index.vue +569 -72
- package/components/ResourceList/index.vue +1 -0
- package/components/ResourceTable.vue +6 -1
- package/components/ResourceYaml.vue +1 -1
- package/components/RichTranslation.vue +106 -0
- package/components/SlideInPanelManager.vue +13 -10
- package/components/SortableTable/index.vue +5 -5
- package/components/SortableTable/selection.js +0 -1
- package/components/Tabbed/index.vue +35 -4
- package/components/__tests__/LazyImage.spec.ts +121 -0
- package/components/__tests__/PromptRestore.test.ts +1 -65
- package/components/__tests__/RichTranslation.test.ts +115 -0
- package/components/fleet/FleetStatus.vue +4 -0
- package/components/fleet/dashboard/ResourcePanel.vue +2 -1
- package/components/form/ClusterAppearance.vue +5 -0
- package/components/form/FileImageSelector.vue +1 -1
- package/components/form/Members/ClusterPermissionsEditor.vue +1 -1
- package/components/form/NameNsDescription.vue +1 -0
- package/components/form/Networking.vue +24 -19
- package/components/form/ProjectMemberEditor.vue +1 -1
- package/components/form/ResourceLabeledSelect.vue +22 -8
- package/components/form/ResourceTabs/index.vue +20 -0
- package/components/form/SecretSelector.vue +9 -0
- package/components/form/SelectOrCreateAuthSecret.vue +6 -3
- package/components/form/__tests__/Networking.test.ts +116 -0
- package/components/form/labeled-select-utils/labeled-select-pagination.ts +3 -38
- package/components/formatter/FleetApplicationSource.vue +25 -17
- package/components/formatter/PodImages.vue +1 -1
- package/components/formatter/__tests__/LiveDate.test.ts +10 -2
- package/components/google/AccountAccess.vue +44 -46
- package/components/nav/Favorite.vue +4 -0
- package/components/nav/Group.vue +4 -1
- package/components/nav/NotificationCenter/Notification.vue +1 -27
- package/components/nav/WindowManager/index.vue +3 -3
- package/composables/resources.ts +2 -2
- package/config/labels-annotations.js +3 -2
- package/config/pagination-table-headers.js +8 -1
- package/config/product/explorer.js +27 -2
- package/config/product/manager.js +0 -1
- package/config/query-params.js +10 -0
- package/config/router/routes.js +21 -1
- package/config/system-namespaces.js +1 -1
- package/config/table-headers.js +30 -1
- package/config/types.js +1 -1
- package/config/version.js +1 -1
- package/detail/__tests__/provisioning.cattle.io.cluster.test.ts +11 -0
- package/detail/__tests__/workload.test.ts +164 -0
- package/detail/configmap.vue +33 -75
- package/detail/projectsecret.vue +11 -0
- package/detail/provisioning.cattle.io.cluster.vue +351 -369
- package/detail/secret.vue +49 -308
- package/detail/workload/index.vue +38 -21
- package/dialog/InstallExtensionDialog.vue +8 -5
- package/dialog/RotateEncryptionKeyDialog.vue +10 -30
- package/edit/__tests__/fleet.cattle.io.helmop.test.ts +224 -0
- package/edit/auth/ldap/__tests__/config.test.ts +14 -0
- package/edit/auth/ldap/config.vue +24 -0
- package/edit/compliance.cattle.io.clusterscan.vue +1 -1
- package/edit/configmap.vue +4 -1
- package/edit/fleet.cattle.io.gitrepo.vue +5 -6
- package/edit/fleet.cattle.io.helmop.vue +78 -56
- package/edit/logging.banzaicloud.io.output/index.vue +1 -1
- package/edit/logging.banzaicloud.io.output/providers/awsElasticsearch.vue +5 -6
- package/edit/networking.k8s.io.ingress/Certificate.vue +20 -22
- package/edit/networking.k8s.io.ingress/DefaultBackend.vue +8 -3
- package/edit/networking.k8s.io.ingress/Rule.vue +2 -5
- package/edit/networking.k8s.io.ingress/RulePath.vue +17 -11
- package/edit/networking.k8s.io.ingress/__tests__/Certificate.test.ts +165 -0
- package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +11 -10
- package/edit/networking.k8s.io.networkpolicy/PolicyRules.vue +1 -3
- package/edit/networking.k8s.io.networkpolicy/index.vue +17 -17
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +3 -2
- package/edit/provisioning.cattle.io.cluster/rke2.vue +123 -61
- package/edit/provisioning.cattle.io.cluster/tabs/AgentConfiguration.vue +9 -7
- package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +22 -13
- package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +10 -12
- package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +39 -38
- package/edit/provisioning.cattle.io.cluster/tabs/etcd/S3Config.vue +41 -19
- package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +16 -3
- package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +32 -33
- package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryMirrors.vue +9 -10
- package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +1 -3
- package/edit/provisioning.cattle.io.cluster/tabs/upgrade/DrainOptions.vue +16 -9
- package/edit/secret/basic.vue +1 -0
- package/edit/secret/index.vue +126 -15
- package/edit/workload/index.vue +5 -14
- package/list/projectsecret.vue +345 -0
- package/list/provisioning.cattle.io.cluster.vue +1 -69
- package/list/secret.vue +109 -0
- package/machine-config/__tests__/vmwarevsphere.test.ts +5 -7
- package/machine-config/google.vue +9 -1
- package/machine-config/vmwarevsphere.vue +7 -17
- package/mixins/__tests__/brand.spec.ts +2 -2
- package/mixins/chart.js +0 -2
- package/mixins/create-edit-view/impl.js +10 -1
- package/mixins/resource-fetch-api-pagination.js +11 -12
- package/mixins/resource-fetch.js +3 -1
- package/models/__tests__/chart.test.ts +111 -80
- package/models/__tests__/fleet.cattle.io.helmop.test.ts +224 -0
- package/models/__tests__/node.test.ts +7 -63
- package/models/catalog.cattle.io.app.js +1 -1
- package/models/catalog.cattle.io.operation.js +1 -1
- package/models/chart.js +36 -20
- package/models/cloudcredential.js +2 -163
- package/models/cluster/node.js +7 -7
- package/models/cluster.x-k8s.io.machine.js +3 -3
- package/models/cluster.x-k8s.io.machinedeployment.js +11 -2
- package/models/compliance.cattle.io.clusterscan.js +2 -2
- package/models/configmap.js +4 -0
- package/models/constraints.gatekeeper.sh.constraint.js +1 -1
- package/models/fleet-application.js +0 -17
- package/models/fleet.cattle.io.cluster.js +2 -2
- package/models/fleet.cattle.io.gitrepo.js +15 -1
- package/models/fleet.cattle.io.helmop.js +26 -22
- package/models/management.cattle.io.setting.js +4 -0
- package/models/persistentvolumeclaim.js +1 -1
- package/models/pod.js +2 -2
- package/models/provisioning.cattle.io.cluster.js +39 -67
- package/models/rke.cattle.io.etcdsnapshot.js +1 -1
- package/models/secret.js +161 -2
- package/models/storage.k8s.io.storageclass.js +2 -2
- package/models/workload.js +3 -3
- package/package.json +11 -10
- package/pages/c/_cluster/apps/charts/AppChartCardFooter.vue +1 -0
- package/pages/c/_cluster/apps/charts/AppChartCardSubHeader.vue +4 -1
- package/pages/c/_cluster/apps/charts/__tests__/AppChartCardFooter.spec.js +41 -0
- package/pages/c/_cluster/apps/charts/chart.vue +422 -174
- package/pages/c/_cluster/apps/charts/index.vue +46 -35
- package/pages/c/_cluster/apps/charts/install.vue +1 -1
- package/pages/c/_cluster/explorer/projectsecret.vue +24 -0
- package/pages/c/_cluster/fleet/__tests__/index.test.ts +608 -314
- package/pages/c/_cluster/fleet/index.vue +103 -45
- package/pages/c/_cluster/manager/cloudCredential/index.vue +2 -59
- package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +10 -3
- package/pages/c/_cluster/uiplugins/index.vue +36 -25
- package/plugins/dashboard-store/__tests__/normalize.test.ts +223 -0
- package/plugins/dashboard-store/__tests__/resource-class.test.ts +191 -0
- package/plugins/dashboard-store/__tests__/utils/normalize-usecases.ts +1526 -0
- package/plugins/dashboard-store/actions.js +42 -22
- package/plugins/dashboard-store/normalize.js +29 -17
- package/plugins/dashboard-store/resource-class.js +83 -17
- package/plugins/steve/__tests__/getters.test.ts +1 -1
- package/plugins/steve/__tests__/subscribe.spec.ts +259 -1
- package/plugins/steve/getters.js +8 -2
- package/plugins/steve/resourceWatcher.js +10 -3
- package/plugins/steve/steve-pagination-utils.ts +14 -3
- package/plugins/steve/subscribe.js +192 -19
- package/plugins/steve/worker/web-worker.advanced.js +2 -0
- package/rancher-components/Card/Card.vue +0 -18
- package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.test.ts +15 -0
- package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.vue +65 -0
- package/rancher-components/Pill/RcStatusBadge/index.ts +2 -0
- package/rancher-components/Pill/RcStatusBadge/types.ts +5 -0
- package/rancher-components/Pill/RcStatusIndicator/RcStatusIndicator.test.ts +33 -0
- package/rancher-components/Pill/RcStatusIndicator/RcStatusIndicator.vue +75 -0
- package/rancher-components/Pill/RcStatusIndicator/index.ts +2 -0
- package/rancher-components/Pill/RcStatusIndicator/types.ts +7 -0
- package/rancher-components/Pill/types.ts +2 -0
- package/rancher-components/RcButton/RcButton.vue +1 -1
- package/rancher-components/RcDropdown/RcDropdown.test.ts +98 -0
- package/rancher-components/RcDropdown/RcDropdown.vue +5 -0
- package/rancher-components/RcDropdown/RcDropdownItem.vue +7 -1
- package/rancher-components/RcDropdown/RcDropdownItemCheckbox.vue +2 -1
- package/rancher-components/RcDropdown/RcDropdownItemSelect.vue +2 -1
- package/rancher-components/RcDropdown/useDropdownContext.ts +21 -0
- package/rancher-components/RcDropdown/useDropdownItem.ts +30 -1
- package/rancher-components/RcItemCard/RcItemCard.test.ts +20 -0
- package/rancher-components/RcItemCard/RcItemCard.vue +40 -6
- package/store/__tests__/catalog.test.ts +93 -1
- package/store/aws.js +19 -8
- package/store/catalog.js +8 -3
- package/types/kube/kube-api.ts +12 -0
- package/types/resources/settings.d.ts +1 -1
- package/types/shell/index.d.ts +643 -585
- package/types/store/pagination.types.ts +16 -6
- package/types/uiplugins.ts +73 -0
- package/utils/__tests__/back-off.test.ts +354 -0
- package/utils/__tests__/create-yaml.test.ts +235 -0
- package/utils/__tests__/kontainer.test.ts +19 -0
- package/utils/__tests__/uiplugins.test.ts +84 -0
- package/utils/back-off.ts +176 -0
- package/utils/create-yaml.js +103 -9
- package/utils/dynamic-importer.js +8 -0
- package/utils/kontainer.ts +3 -5
- package/utils/pagination-utils.ts +18 -0
- package/utils/style.ts +3 -0
- package/utils/uiplugins.ts +29 -2
- package/utils/validators/__tests__/setting.test.js +92 -0
- package/utils/validators/formRules/__tests__/index.test.ts +88 -7
- package/utils/validators/formRules/index.ts +83 -8
- package/utils/validators/setting.js +17 -0
- package/cloud-credential/__tests__/harvester.test.ts +0 -18
- package/components/ResourceDetail/__tests__/index.test.ts +0 -135
- package/components/ResourceDetail/legacy.vue +0 -562
- package/components/formatter/CloudCredExpired.vue +0 -69
- package/models/etcdbackup.js +0 -45
- package/pages/explorer/resource/detail/configmap.vue +0 -42
- package/pages/explorer/resource/detail/secret.vue +0 -50
- package/utils/aws.js +0 -0
|
@@ -7,6 +7,7 @@ import CreateEditView from '@shell/mixins/create-edit-view';
|
|
|
7
7
|
import FormValidation from '@shell/mixins/form-validation';
|
|
8
8
|
import { normalizeName } from '@shell/utils/kube';
|
|
9
9
|
import AccountAccess from '@shell/components/google/AccountAccess.vue';
|
|
10
|
+
import { handleConflict } from '@shell/plugins/dashboard-store/normalize';
|
|
10
11
|
|
|
11
12
|
import {
|
|
12
13
|
CAPI,
|
|
@@ -170,7 +171,7 @@ export default {
|
|
|
170
171
|
this.setAgentConfiguration();
|
|
171
172
|
},
|
|
172
173
|
|
|
173
|
-
|
|
174
|
+
beforeCreate() {
|
|
174
175
|
if (!this.value.spec.rkeConfig) {
|
|
175
176
|
this.value.spec.rkeConfig = {};
|
|
176
177
|
}
|
|
@@ -217,15 +218,16 @@ export default {
|
|
|
217
218
|
if (!this.value.spec.rkeConfig.machineSelectorConfig?.length) {
|
|
218
219
|
this.value.spec.rkeConfig.machineSelectorConfig = [{ config: {} }];
|
|
219
220
|
}
|
|
221
|
+
},
|
|
220
222
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
+
data() {
|
|
223
224
|
return {
|
|
224
225
|
loadedOnce: false,
|
|
225
226
|
lastIdx: 0,
|
|
226
227
|
allPSAs: [],
|
|
227
228
|
credentialId: '',
|
|
228
229
|
credential: null,
|
|
230
|
+
initialMachinePoolsValues: {},
|
|
229
231
|
machinePools: null,
|
|
230
232
|
rke2Versions: null,
|
|
231
233
|
k3sVersions: null,
|
|
@@ -255,7 +257,7 @@ export default {
|
|
|
255
257
|
}],
|
|
256
258
|
harvesterVersionRange: {},
|
|
257
259
|
complianceOverride: false,
|
|
258
|
-
truncateLimit,
|
|
260
|
+
truncateLimit: this.value.defaultHostnameLengthLimit || 0,
|
|
259
261
|
busy: false,
|
|
260
262
|
machinePoolValidation: {}, // map of validation states for each machine pool
|
|
261
263
|
machinePoolErrors: {},
|
|
@@ -271,13 +273,14 @@ export default {
|
|
|
271
273
|
isAuthenticated: this.provider !== GOOGLE || this.mode === _EDIT,
|
|
272
274
|
projectId: null,
|
|
273
275
|
REGISTRIES_TAB_NAME,
|
|
274
|
-
labelForAddon
|
|
275
|
-
|
|
276
|
+
labelForAddon,
|
|
277
|
+
etcdConfigValid: true,
|
|
276
278
|
};
|
|
277
279
|
},
|
|
278
280
|
|
|
279
281
|
computed: {
|
|
280
282
|
...mapGetters({ features: 'features/get' }),
|
|
283
|
+
|
|
281
284
|
isActiveTabRegistries() {
|
|
282
285
|
return this.activeTab?.selectedName === REGISTRIES_TAB_NAME;
|
|
283
286
|
},
|
|
@@ -856,7 +859,16 @@ export default {
|
|
|
856
859
|
set(newValue) {
|
|
857
860
|
this.$emit('update:value', newValue);
|
|
858
861
|
}
|
|
859
|
-
}
|
|
862
|
+
},
|
|
863
|
+
hideFooter() {
|
|
864
|
+
return this.needCredential && !this.credential;
|
|
865
|
+
},
|
|
866
|
+
|
|
867
|
+
overallFormValidationPassed() {
|
|
868
|
+
return this.validationPassed &&
|
|
869
|
+
this.fvFormIsValid &&
|
|
870
|
+
this.etcdConfigValid;
|
|
871
|
+
},
|
|
860
872
|
},
|
|
861
873
|
|
|
862
874
|
watch: {
|
|
@@ -946,6 +958,7 @@ export default {
|
|
|
946
958
|
this.registerBeforeHook(this.setRegistryConfig, 'set-registry-config');
|
|
947
959
|
this.registerBeforeHook(this.handleVsphereCpiSecret, 'sync-vsphere-cpi');
|
|
948
960
|
this.registerBeforeHook(this.handleVsphereCsiSecret, 'sync-vsphere-csi');
|
|
961
|
+
this.registerBeforeHook(this.setHarvesterChartValues, 'set-harvester-chart-values');
|
|
949
962
|
this.registerAfterHook(this.cleanupMachinePools, 'cleanup-machine-pools');
|
|
950
963
|
this.registerAfterHook(this.saveRoleBindings, 'save-role-bindings');
|
|
951
964
|
|
|
@@ -1214,7 +1227,7 @@ export default {
|
|
|
1214
1227
|
// @TODO what if the pool is missing?
|
|
1215
1228
|
const id = `pool${ ++this.lastIdx }`;
|
|
1216
1229
|
|
|
1217
|
-
|
|
1230
|
+
const poolData = {
|
|
1218
1231
|
id,
|
|
1219
1232
|
remove: false,
|
|
1220
1233
|
create: false,
|
|
@@ -1222,7 +1235,15 @@ export default {
|
|
|
1222
1235
|
pool: clone(pool),
|
|
1223
1236
|
config: config ? await this.$store.dispatch('management/clone', { resource: config }) : null,
|
|
1224
1237
|
configMissing
|
|
1225
|
-
}
|
|
1238
|
+
};
|
|
1239
|
+
|
|
1240
|
+
// add data to machine pools array
|
|
1241
|
+
out.push(poolData);
|
|
1242
|
+
|
|
1243
|
+
// but we also store the initial data so that we can handle conflicts
|
|
1244
|
+
if (poolData?.config?.id) {
|
|
1245
|
+
this.initialMachinePoolsValues[poolData.config.id] = structuredClone(poolData.config);
|
|
1246
|
+
}
|
|
1226
1247
|
}
|
|
1227
1248
|
}
|
|
1228
1249
|
|
|
@@ -1317,17 +1338,25 @@ export default {
|
|
|
1317
1338
|
const _latestConfig = await this.$store.dispatch('management/request', { url: `/v1/${ machinePool.config.type }s/${ machinePool.config.id }` });
|
|
1318
1339
|
const latestConfig = await this.$store.dispatch('management/create', _latestConfig);
|
|
1319
1340
|
|
|
1320
|
-
const
|
|
1321
|
-
const
|
|
1322
|
-
|
|
1323
|
-
//
|
|
1324
|
-
//
|
|
1325
|
-
|
|
1341
|
+
const _initialMachinePoolValue = this.initialMachinePoolsValues[machinePool?.config?.id] || {};
|
|
1342
|
+
const initialMachinePoolValue = await this.$store.dispatch('management/create', _initialMachinePoolValue);
|
|
1343
|
+
|
|
1344
|
+
// if there's the initial machine pool config, we are in a good position to apply the handleConflict function
|
|
1345
|
+
// to deal with out-of-sync data between machinePools configs. This also mutates the data inside machinePool.config through object reference
|
|
1346
|
+
const conflict = await handleConflict(
|
|
1347
|
+
initialMachinePoolValue,
|
|
1348
|
+
machinePool.config,
|
|
1349
|
+
latestConfig,
|
|
1350
|
+
{
|
|
1351
|
+
dispatch: this.$store.dispatch,
|
|
1352
|
+
getters: this.$store.getters
|
|
1353
|
+
},
|
|
1354
|
+
'management'
|
|
1355
|
+
);
|
|
1326
1356
|
|
|
1327
|
-
if
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
machinePool.config = merge(clonedLatestConfig, clonedCurrentConfig);
|
|
1357
|
+
// if there's conflicts, throw Error stops save process and surfaces error to user
|
|
1358
|
+
if (conflict) {
|
|
1359
|
+
throw Error(conflict);
|
|
1331
1360
|
}
|
|
1332
1361
|
}
|
|
1333
1362
|
},
|
|
@@ -1536,41 +1565,7 @@ export default {
|
|
|
1536
1565
|
}
|
|
1537
1566
|
|
|
1538
1567
|
try {
|
|
1539
|
-
const clusterId = get(this.credential, 'decodedData.clusterId') || '';
|
|
1540
|
-
|
|
1541
1568
|
this.applyChartValues(this.value.spec.rkeConfig);
|
|
1542
|
-
|
|
1543
|
-
const isUpgrade = this.isEdit && this.liveValue?.spec?.kubernetesVersion !== this.value?.spec?.kubernetesVersion;
|
|
1544
|
-
|
|
1545
|
-
if (this.agentConfig?.['cloud-provider-name'] === HARVESTER && clusterId && (this.isCreate || isUpgrade)) {
|
|
1546
|
-
const namespace = this.machinePools?.[0]?.config?.vmNamespace;
|
|
1547
|
-
|
|
1548
|
-
const res = await this.$store.dispatch('management/request', {
|
|
1549
|
-
url: `/k8s/clusters/${ clusterId }/v1/harvester/kubeconfig`,
|
|
1550
|
-
method: 'POST',
|
|
1551
|
-
data: {
|
|
1552
|
-
csiClusterRoleName: 'harvesterhci.io:csi-driver',
|
|
1553
|
-
clusterRoleName: 'harvesterhci.io:cloudprovider',
|
|
1554
|
-
namespace,
|
|
1555
|
-
serviceAccountName: this.value.metadata.name,
|
|
1556
|
-
},
|
|
1557
|
-
});
|
|
1558
|
-
|
|
1559
|
-
const kubeconfig = res.data;
|
|
1560
|
-
|
|
1561
|
-
const harvesterKubeconfigSecret = await this.createKubeconfigSecret(kubeconfig);
|
|
1562
|
-
|
|
1563
|
-
this.agentConfig['cloud-provider-config'] = `secret://fleet-default:${ harvesterKubeconfigSecret?.metadata?.name }`;
|
|
1564
|
-
|
|
1565
|
-
if (this.isCreate) {
|
|
1566
|
-
set(this.chartValues, `${ HARVESTER_CLOUD_PROVIDER }.global.cattle.clusterName`, this.value.metadata.name);
|
|
1567
|
-
}
|
|
1568
|
-
|
|
1569
|
-
const distroSubdir = this.value?.spec?.kubernetesVersion?.includes('k3s') ? DEFAULT_SUBDIRS.K8S_DISTRO_K3S : DEFAULT_SUBDIRS.K8S_DISTRO_RKE2;
|
|
1570
|
-
const distroRoot = this.value?.spec?.rkeConfig?.dataDirectories?.k8sDistro?.length ? this.value?.spec?.rkeConfig?.dataDirectories?.k8sDistro : `${ DEFAULT_COMMON_BASE_PATH }/${ distroSubdir }`;
|
|
1571
|
-
|
|
1572
|
-
set(this.chartValues, `${ HARVESTER_CLOUD_PROVIDER }.cloudConfigPath`, `${ distroRoot }/etc/config-files/cloud-provider-config`);
|
|
1573
|
-
}
|
|
1574
1569
|
} catch (err) {
|
|
1575
1570
|
this.errors.push(err);
|
|
1576
1571
|
|
|
@@ -1617,6 +1612,62 @@ export default {
|
|
|
1617
1612
|
}
|
|
1618
1613
|
},
|
|
1619
1614
|
|
|
1615
|
+
async setHarvesterChartValues() {
|
|
1616
|
+
const isHarvester = this.agentConfig?.['cloud-provider-name'] === HARVESTER;
|
|
1617
|
+
|
|
1618
|
+
if (!isHarvester) {
|
|
1619
|
+
return;
|
|
1620
|
+
}
|
|
1621
|
+
try {
|
|
1622
|
+
const clusterId = get(this.credential, 'decodedData.clusterId') || '';
|
|
1623
|
+
const isUpgrade = this.isEdit && this.liveValue?.spec?.kubernetesVersion !== this.value?.spec?.kubernetesVersion;
|
|
1624
|
+
|
|
1625
|
+
if (!this.value?.metadata?.name) {
|
|
1626
|
+
const err = this.t('cluster.harvester.kubeconfigSecret.nameRequired');
|
|
1627
|
+
|
|
1628
|
+
throw new Error(err);
|
|
1629
|
+
}
|
|
1630
|
+
|
|
1631
|
+
if (clusterId && (this.isCreate || isUpgrade)) {
|
|
1632
|
+
const namespace = this.machinePools?.[0]?.config?.vmNamespace;
|
|
1633
|
+
|
|
1634
|
+
const res = await this.$store.dispatch('management/request', {
|
|
1635
|
+
url: `/k8s/clusters/${ clusterId }/v1/harvester/kubeconfig`,
|
|
1636
|
+
method: 'POST',
|
|
1637
|
+
data: {
|
|
1638
|
+
csiClusterRoleName: 'harvesterhci.io:csi-driver',
|
|
1639
|
+
clusterRoleName: 'harvesterhci.io:cloudprovider',
|
|
1640
|
+
namespace,
|
|
1641
|
+
serviceAccountName: this.value.metadata.name,
|
|
1642
|
+
},
|
|
1643
|
+
});
|
|
1644
|
+
|
|
1645
|
+
const kubeconfig = res.data;
|
|
1646
|
+
|
|
1647
|
+
const harvesterKubeconfigSecret = await this.createKubeconfigSecret(kubeconfig);
|
|
1648
|
+
|
|
1649
|
+
this.agentConfig['cloud-provider-config'] = `secret://fleet-default:${ harvesterKubeconfigSecret?.metadata?.name }`;
|
|
1650
|
+
|
|
1651
|
+
const harvesterCloudProviderKey = this.chartVersionKey(HARVESTER_CLOUD_PROVIDER);
|
|
1652
|
+
|
|
1653
|
+
if (this.isCreate) {
|
|
1654
|
+
set(this.userChartValues, `'${ harvesterCloudProviderKey }'.global.cattle.clusterName`, this.value.metadata.name);
|
|
1655
|
+
}
|
|
1656
|
+
|
|
1657
|
+
const distroSubdir = this.value?.spec?.kubernetesVersion?.includes('k3s') ? DEFAULT_SUBDIRS.K8S_DISTRO_K3S : DEFAULT_SUBDIRS.K8S_DISTRO_RKE2;
|
|
1658
|
+
const distroRoot = this.value?.spec?.rkeConfig?.dataDirectories?.k8sDistro?.length ? this.value?.spec?.rkeConfig?.dataDirectories?.k8sDistro : `${ DEFAULT_COMMON_BASE_PATH }/${ distroSubdir }`;
|
|
1659
|
+
|
|
1660
|
+
set(this.userChartValues, `'${ harvesterCloudProviderKey }'.cloudConfigPath`, `${ distroRoot }/etc/config-files/cloud-provider-config`);
|
|
1661
|
+
}
|
|
1662
|
+
} catch (e) {
|
|
1663
|
+
const cause = e.errors ? e.errors.join('; ') : e?.message;
|
|
1664
|
+
const msg = this.t('cluster.harvester.kubeconfigSecret.error', { err: cause });
|
|
1665
|
+
|
|
1666
|
+
this.errors.push(msg);
|
|
1667
|
+
throw new Error(msg);
|
|
1668
|
+
}
|
|
1669
|
+
},
|
|
1670
|
+
|
|
1620
1671
|
// create a secret to reference the harvester cluster kubeconfig in rkeConfig
|
|
1621
1672
|
async createKubeconfigSecret(kubeconfig = '') {
|
|
1622
1673
|
const clusterName = this.value.metadata.name;
|
|
@@ -1806,12 +1857,12 @@ export default {
|
|
|
1806
1857
|
|
|
1807
1858
|
const hasMirrorsOrAuthConfig = Object.keys(regs.configs).length > 0 || Object.keys(regs.mirrors).length > 0;
|
|
1808
1859
|
|
|
1809
|
-
if (this.registryHost || registrySecret
|
|
1860
|
+
if (this.registryHost || registrySecret) {
|
|
1810
1861
|
this.showCustomRegistryInput = true;
|
|
1862
|
+
}
|
|
1811
1863
|
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
}
|
|
1864
|
+
if (hasMirrorsOrAuthConfig) {
|
|
1865
|
+
this.showCustomRegistryAdvancedInput = true;
|
|
1815
1866
|
}
|
|
1816
1867
|
},
|
|
1817
1868
|
|
|
@@ -1893,6 +1944,7 @@ export default {
|
|
|
1893
1944
|
|
|
1894
1945
|
charts.forEach((name) => {
|
|
1895
1946
|
const key = this.chartVersionKey(name);
|
|
1947
|
+
|
|
1896
1948
|
const userValues = this.userChartValues[key];
|
|
1897
1949
|
|
|
1898
1950
|
if (userValues) {
|
|
@@ -2126,7 +2178,7 @@ export default {
|
|
|
2126
2178
|
|
|
2127
2179
|
handleTabChange(data) {
|
|
2128
2180
|
this.activeTab = data;
|
|
2129
|
-
}
|
|
2181
|
+
},
|
|
2130
2182
|
}
|
|
2131
2183
|
};
|
|
2132
2184
|
</script>
|
|
@@ -2142,7 +2194,7 @@ export default {
|
|
|
2142
2194
|
v-else
|
|
2143
2195
|
ref="cruresource"
|
|
2144
2196
|
:mode="mode"
|
|
2145
|
-
:validation-passed="
|
|
2197
|
+
:validation-passed="overallFormValidationPassed"
|
|
2146
2198
|
:resource="value"
|
|
2147
2199
|
:errors="errors"
|
|
2148
2200
|
:cancel-event="true"
|
|
@@ -2174,7 +2226,10 @@ export default {
|
|
|
2174
2226
|
@error="e=>errors.push(e)"
|
|
2175
2227
|
@cancel-credential="cancelCredential"
|
|
2176
2228
|
/>
|
|
2177
|
-
<div
|
|
2229
|
+
<div
|
|
2230
|
+
v-else
|
|
2231
|
+
class="authenticated"
|
|
2232
|
+
>
|
|
2178
2233
|
<SelectCredential
|
|
2179
2234
|
v-if="needCredential"
|
|
2180
2235
|
v-model:value="credentialId"
|
|
@@ -2376,6 +2431,7 @@ export default {
|
|
|
2376
2431
|
@update:value="$emit('input', $event)"
|
|
2377
2432
|
@s3-backup-changed="handleS3BackupChanged"
|
|
2378
2433
|
@config-etcd-expose-metrics-changed="handleConfigEtcdExposeMetricsChanged"
|
|
2434
|
+
@etcd-validation-changed="(val)=>etcdConfigValid = val"
|
|
2379
2435
|
/>
|
|
2380
2436
|
</Tab>
|
|
2381
2437
|
|
|
@@ -2568,7 +2624,7 @@ export default {
|
|
|
2568
2624
|
/>
|
|
2569
2625
|
</div>
|
|
2570
2626
|
<template
|
|
2571
|
-
v-if="
|
|
2627
|
+
v-if="hideFooter"
|
|
2572
2628
|
#form-footer
|
|
2573
2629
|
>
|
|
2574
2630
|
<div><!-- Hide the outer footer --></div>
|
|
@@ -2577,6 +2633,12 @@ export default {
|
|
|
2577
2633
|
</template>
|
|
2578
2634
|
|
|
2579
2635
|
<style lang="scss" scoped>
|
|
2636
|
+
.authenticated {
|
|
2637
|
+
display:flex;
|
|
2638
|
+
flex-direction: column;
|
|
2639
|
+
flex-grow: 1;
|
|
2640
|
+
}
|
|
2641
|
+
|
|
2580
2642
|
.min-height {
|
|
2581
2643
|
min-height: 40em;
|
|
2582
2644
|
}
|
|
@@ -81,6 +81,14 @@ export default {
|
|
|
81
81
|
},
|
|
82
82
|
|
|
83
83
|
data() {
|
|
84
|
+
return {
|
|
85
|
+
defaultAffinity: {},
|
|
86
|
+
affinitySetting: DEFAULT,
|
|
87
|
+
nodeAffinity: {}
|
|
88
|
+
};
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
created() {
|
|
84
92
|
const nodeAffinity = this.value?.overrideAffinity?.nodeAffinity;
|
|
85
93
|
const podAffinity = this.value?.overrideAffinity?.podAffinity;
|
|
86
94
|
const podAntiAffinity = this.value?.overrideAffinity?.podAntiAffinity;
|
|
@@ -93,14 +101,8 @@ export default {
|
|
|
93
101
|
hasAffinityPopulated = true;
|
|
94
102
|
}
|
|
95
103
|
|
|
96
|
-
|
|
97
|
-
defaultAffinity: {},
|
|
98
|
-
affinitySetting: hasAffinityPopulated ? CUSTOM : DEFAULT,
|
|
99
|
-
nodeAffinity: {}
|
|
100
|
-
};
|
|
101
|
-
},
|
|
104
|
+
this.affinitySetting = hasAffinityPopulated ? CUSTOM : DEFAULT;
|
|
102
105
|
|
|
103
|
-
created() {
|
|
104
106
|
this.ensureValue();
|
|
105
107
|
},
|
|
106
108
|
|
|
@@ -3,7 +3,6 @@ import difference from 'lodash/difference';
|
|
|
3
3
|
import { mapGetters } from 'vuex';
|
|
4
4
|
import CreateEditView from '@shell/mixins/create-edit-view';
|
|
5
5
|
import FormValidation from '@shell/mixins/form-validation';
|
|
6
|
-
|
|
7
6
|
import { set, get } from '@shell/utils/object';
|
|
8
7
|
import { Banner } from '@components/Banner';
|
|
9
8
|
import { Checkbox } from '@components/Form/Checkbox';
|
|
@@ -11,7 +10,6 @@ import LabeledSelect from '@shell/components/form/LabeledSelect';
|
|
|
11
10
|
import YamlEditor from '@shell/components/YamlEditor';
|
|
12
11
|
import { LEGACY } from '@shell/store/features';
|
|
13
12
|
import semver from 'semver';
|
|
14
|
-
import { _CREATE, _EDIT } from '@shell/config/query-params';
|
|
15
13
|
|
|
16
14
|
const HARVESTER = 'harvester';
|
|
17
15
|
|
|
@@ -119,12 +117,23 @@ export default {
|
|
|
119
117
|
}
|
|
120
118
|
},
|
|
121
119
|
|
|
120
|
+
data() {
|
|
121
|
+
return {
|
|
122
|
+
showEnablingComplianceWarning: false,
|
|
123
|
+
initialAgentProfile: this.value.agentConfig?.profile || ''
|
|
124
|
+
};
|
|
125
|
+
},
|
|
126
|
+
|
|
122
127
|
watch: {
|
|
123
128
|
selectedVersion(neu, old) {
|
|
124
129
|
if (neu?.value !== old?.value && this.ciliumIpv6) {
|
|
125
130
|
// Re-assign so that the setter updates the structure for the new k8s version if needed
|
|
126
131
|
this.ciliumIpv6 = !!this.ciliumIpv6;
|
|
127
132
|
}
|
|
133
|
+
},
|
|
134
|
+
|
|
135
|
+
'agentConfig.profile'(newValue) {
|
|
136
|
+
this.showEnablingComplianceWarning = this.provider === 'custom' && this.isEdit && !!newValue && newValue !== this.initialAgentProfile;
|
|
128
137
|
}
|
|
129
138
|
},
|
|
130
139
|
|
|
@@ -382,10 +391,6 @@ export default {
|
|
|
382
391
|
}
|
|
383
392
|
},
|
|
384
393
|
|
|
385
|
-
isEdit() {
|
|
386
|
-
return this.mode === _EDIT;
|
|
387
|
-
},
|
|
388
|
-
|
|
389
394
|
canNotEditCloudProvider() {
|
|
390
395
|
if (!this.isEdit) {
|
|
391
396
|
return false;
|
|
@@ -405,14 +410,14 @@ export default {
|
|
|
405
410
|
* Display warning about unsupported Azure provider if k8s >= 1.30
|
|
406
411
|
*/
|
|
407
412
|
showCloudProviderUnsupportedAzureWarning() {
|
|
408
|
-
return this.showCloudProvider && this.
|
|
413
|
+
return this.showCloudProvider && this.isCreate && this.isAzureProviderUnsupported;
|
|
409
414
|
},
|
|
410
415
|
|
|
411
416
|
/**
|
|
412
417
|
* Display warning about Azure provider migration from k8s versions >= 1.27 to External provider
|
|
413
418
|
*/
|
|
414
419
|
showCloudProviderMigrateAzureWarning() {
|
|
415
|
-
return this.showCloudProvider && this.
|
|
420
|
+
return this.showCloudProvider && this.isEdit && this.canAzureMigrateOnEdit;
|
|
416
421
|
}
|
|
417
422
|
},
|
|
418
423
|
|
|
@@ -579,11 +584,8 @@ export default {
|
|
|
579
584
|
<p v-clean-html="t('cluster.rke2.banner.complianceUnsupported', {profile: serverConfig.profile || agentConfig.profile}, true)" />
|
|
580
585
|
</Banner>
|
|
581
586
|
|
|
582
|
-
<div
|
|
583
|
-
<div
|
|
584
|
-
v-if="showComplianceProfile"
|
|
585
|
-
class="col span-6"
|
|
586
|
-
>
|
|
587
|
+
<div v-if="showComplianceProfile">
|
|
588
|
+
<div class="col span-6">
|
|
587
589
|
<LabeledSelect
|
|
588
590
|
v-if="serverArgs && serverArgs.profile && serverConfig"
|
|
589
591
|
v-model:value="serverConfig.profile"
|
|
@@ -602,6 +604,13 @@ export default {
|
|
|
602
604
|
@update:value="$emit('compliance-changed')"
|
|
603
605
|
/>
|
|
604
606
|
</div>
|
|
607
|
+
<div class="row mb-10">
|
|
608
|
+
<Banner
|
|
609
|
+
v-if="showEnablingComplianceWarning"
|
|
610
|
+
color="warning"
|
|
611
|
+
label-key="cluster.rke2.compliance.warning"
|
|
612
|
+
/>
|
|
613
|
+
</div>
|
|
605
614
|
</div>
|
|
606
615
|
|
|
607
616
|
<template v-if="hasComplianceOverride">
|
|
@@ -44,23 +44,21 @@ export default {
|
|
|
44
44
|
},
|
|
45
45
|
},
|
|
46
46
|
data() {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
return {
|
|
48
|
+
DATA_DIR_RADIO_OPTIONS,
|
|
49
|
+
dataConfigRadioValue: DATA_DIR_RADIO_OPTIONS.DEFAULT,
|
|
50
|
+
k8sDistroSubDir: DEFAULT_SUBDIRS.K8S_DISTRO_RKE2,
|
|
51
|
+
commonConfig: '',
|
|
52
|
+
};
|
|
53
|
+
},
|
|
54
|
+
created() {
|
|
50
55
|
if (this.k8sVersion && this.k8sVersion.includes('k3s')) {
|
|
51
|
-
k8sDistroSubDir = DEFAULT_SUBDIRS.K8S_DISTRO_K3S;
|
|
56
|
+
this.k8sDistroSubDir = DEFAULT_SUBDIRS.K8S_DISTRO_K3S;
|
|
52
57
|
}
|
|
53
58
|
|
|
54
59
|
if (this.mode !== _CREATE) {
|
|
55
|
-
dataConfigRadioValue = DATA_DIR_RADIO_OPTIONS.CUSTOM;
|
|
60
|
+
this.dataConfigRadioValue = DATA_DIR_RADIO_OPTIONS.CUSTOM;
|
|
56
61
|
}
|
|
57
|
-
|
|
58
|
-
return {
|
|
59
|
-
DATA_DIR_RADIO_OPTIONS,
|
|
60
|
-
dataConfigRadioValue,
|
|
61
|
-
k8sDistroSubDir,
|
|
62
|
-
commonConfig: '',
|
|
63
|
-
};
|
|
64
62
|
},
|
|
65
63
|
watch: {
|
|
66
64
|
commonConfig(neu) {
|
|
@@ -89,47 +89,10 @@ export default {
|
|
|
89
89
|
},
|
|
90
90
|
|
|
91
91
|
data() {
|
|
92
|
-
const parseDuration = (duration) => {
|
|
93
|
-
// The back end stores the timeout in Duration format, for example, "42d31h10m30s".
|
|
94
|
-
// Here we convert that string to an integer and return the duration as seconds.
|
|
95
|
-
const splitStr = duration.split(/([a-z])/);
|
|
96
|
-
|
|
97
|
-
const durationsAsSeconds = splitStr.reduce((old, neu, idx) => {
|
|
98
|
-
const parsed = parseInt(neu);
|
|
99
|
-
|
|
100
|
-
if ( isNaN(parsed) ) {
|
|
101
|
-
return old;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const interval = splitStr[(idx + 1)];
|
|
105
|
-
|
|
106
|
-
switch (interval) {
|
|
107
|
-
case 'd':
|
|
108
|
-
old.push(parsed * 24 * 60 * 60);
|
|
109
|
-
break;
|
|
110
|
-
case 'h':
|
|
111
|
-
old.push(parsed * 60 * 60);
|
|
112
|
-
break;
|
|
113
|
-
case 'm':
|
|
114
|
-
old.push(parsed * 60);
|
|
115
|
-
break;
|
|
116
|
-
case 's':
|
|
117
|
-
old.push(parsed);
|
|
118
|
-
break;
|
|
119
|
-
default:
|
|
120
|
-
break;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return old;
|
|
124
|
-
}, []);
|
|
125
|
-
|
|
126
|
-
return durationsAsSeconds.reduce((old, neu) => old + neu);
|
|
127
|
-
};
|
|
128
|
-
|
|
129
92
|
return {
|
|
130
93
|
uuid: randomStr(),
|
|
131
94
|
|
|
132
|
-
unhealthyNodeTimeoutInteger:
|
|
95
|
+
unhealthyNodeTimeoutInteger: 0,
|
|
133
96
|
|
|
134
97
|
validationErrors: [],
|
|
135
98
|
|
|
@@ -183,6 +146,8 @@ export default {
|
|
|
183
146
|
* On creation, ensure that the pool is marked valid - custom machine pools can emit further validation events
|
|
184
147
|
*/
|
|
185
148
|
created() {
|
|
149
|
+
this.unhealthyNodeTimeoutInteger = this.value.pool.unhealthyNodeTimeout ? this.parseDuration(this.value.pool.unhealthyNodeTimeout) : 0;
|
|
150
|
+
|
|
186
151
|
this.$emit('validationChanged', true);
|
|
187
152
|
},
|
|
188
153
|
|
|
@@ -192,6 +157,42 @@ export default {
|
|
|
192
157
|
},
|
|
193
158
|
|
|
194
159
|
methods: {
|
|
160
|
+
parseDuration(duration) {
|
|
161
|
+
// The back end stores the timeout in Duration format, for example, "42d31h10m30s".
|
|
162
|
+
// Here we convert that string to an integer and return the duration as seconds.
|
|
163
|
+
const splitStr = duration.split(/([a-z])/);
|
|
164
|
+
|
|
165
|
+
const durationsAsSeconds = splitStr.reduce((old, neu, idx) => {
|
|
166
|
+
const parsed = parseInt(neu);
|
|
167
|
+
|
|
168
|
+
if ( isNaN(parsed) ) {
|
|
169
|
+
return old;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const interval = splitStr[(idx + 1)];
|
|
173
|
+
|
|
174
|
+
switch (interval) {
|
|
175
|
+
case 'd':
|
|
176
|
+
old.push(parsed * 24 * 60 * 60);
|
|
177
|
+
break;
|
|
178
|
+
case 'h':
|
|
179
|
+
old.push(parsed * 60 * 60);
|
|
180
|
+
break;
|
|
181
|
+
case 'm':
|
|
182
|
+
old.push(parsed * 60);
|
|
183
|
+
break;
|
|
184
|
+
case 's':
|
|
185
|
+
old.push(parsed);
|
|
186
|
+
break;
|
|
187
|
+
default:
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return old;
|
|
192
|
+
}, []);
|
|
193
|
+
|
|
194
|
+
return durationsAsSeconds.reduce((old, neu) => old + neu);
|
|
195
|
+
},
|
|
195
196
|
emitError(e) {
|
|
196
197
|
this.$emit('error', e);
|
|
197
198
|
},
|