@rancher/shell 3.0.4 → 3.0.5-rc.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.
- package/assets/images/providers/sks.svg +1 -0
- package/assets/styles/base/_basic.scss +6 -0
- package/assets/styles/base/_helpers.scss +4 -0
- package/assets/styles/base/_variables.scss +1 -0
- package/assets/styles/global/_button.scss +1 -0
- package/assets/translations/en-us.yaml +65 -15
- package/assets/translations/zh-hans.yaml +4 -3
- package/chart/monitoring/index.vue +3 -1
- package/cloud-credential/aws.vue +2 -0
- package/components/ActionDropdownShell.vue +71 -0
- package/components/AppModal.vue +18 -4
- package/components/AsyncButton.vue +24 -7
- package/components/BannerGraphic.vue +1 -0
- package/components/CommunityLinks.vue +4 -59
- package/components/CopyToClipboardText.vue +2 -1
- package/components/CruResource.vue +6 -1
- package/components/DetailText.vue +5 -0
- package/components/ExplorerMembers.vue +1 -1
- package/components/ExplorerProjectsNamespaces.vue +68 -18
- package/components/GlobalRoleBindings.vue +5 -1
- package/components/GrowlManager.vue +1 -0
- package/components/LandingPagePreference.vue +7 -3
- package/components/LocaleSelector.vue +39 -95
- package/components/ModalManager.vue +55 -0
- package/components/ModalWithCard.vue +1 -0
- package/components/PromptModal.vue +47 -8
- package/components/PromptRemove.vue +1 -0
- package/components/PromptRestore.vue +1 -0
- package/components/ResourceCancelModal.vue +1 -0
- package/components/ResourceDetail/Masthead.vue +38 -12
- package/components/ResourceDetail/__tests__/Masthead.test.ts +5 -1
- package/components/ResourceDetail/index.vue +47 -12
- package/components/ResourceTable.vue +54 -19
- package/components/SideNav.vue +5 -1
- package/components/SlideInPanelManager.vue +126 -0
- package/components/SortableTable/THead.vue +5 -2
- package/components/SortableTable/actions.js +1 -1
- package/components/SortableTable/index.vue +64 -51
- package/components/SortableTable/paging.js +16 -19
- package/components/SortableTable/selection.js +0 -11
- package/components/Wizard.vue +2 -2
- package/components/__tests__/AsyncButton.test.ts +2 -2
- package/components/__tests__/ModalManager.spec.ts +176 -0
- package/components/__tests__/PromptModal.test.ts +148 -0
- package/components/__tests__/SlideInPanelManager.spec.ts +166 -0
- package/components/auth/AuthBanner.vue +13 -11
- package/components/auth/Principal.vue +1 -0
- package/components/auth/__tests__/RoleDetailEdit.test.ts +3 -2
- package/components/auth/login/ldap.vue +1 -1
- package/components/fleet/FleetResources.vue +21 -6
- package/components/form/ArrayList.vue +76 -60
- package/components/form/BannerSettings.vue +17 -2
- package/components/form/ColorInput.vue +35 -6
- package/components/form/Command.vue +6 -15
- package/components/form/EnvVars.vue +16 -8
- package/components/form/HealthCheck.vue +3 -3
- package/components/form/HookOption.vue +11 -16
- package/components/form/LabeledSelect.vue +18 -22
- package/components/form/LifecycleHooks.vue +3 -3
- package/components/form/MatchExpressions.vue +14 -8
- package/components/form/NameNsDescription.vue +128 -104
- package/components/form/Networking.vue +20 -12
- package/components/form/NodeAffinity.vue +31 -23
- package/components/form/NodeScheduling.vue +13 -3
- package/components/form/NotificationSettings.vue +15 -1
- package/components/form/Password.vue +1 -0
- package/components/form/PodAffinity.vue +43 -43
- package/components/form/Probe.vue +68 -66
- package/components/form/ResourceQuota/Project.vue +5 -1
- package/components/form/ResourceSelector.vue +7 -9
- package/components/form/SSHKnownHosts/__tests__/KnownHostsEditDialog.test.ts +16 -24
- package/components/form/SSHKnownHosts/index.vue +30 -13
- package/components/form/Security.vue +54 -56
- package/components/form/Select.vue +32 -21
- package/components/form/ShellInput.vue +5 -1
- package/components/form/Tolerations.vue +5 -1
- package/components/form/ValueFromResource.vue +134 -121
- package/components/form/WorkloadPorts.vue +18 -18
- package/components/form/__tests__/ArrayList.test.ts +5 -2
- package/components/form/__tests__/ColorInput.test.ts +35 -0
- package/components/form/__tests__/LabeledSelect.test.ts +40 -0
- package/components/form/__tests__/MatchExpressions.test.ts +12 -12
- package/components/form/__tests__/NameNsDescription.test.ts +115 -14
- package/components/form/__tests__/Probe.test.ts +12 -8
- package/components/form/__tests__/SSHKnownHosts.test.ts +22 -2
- package/components/form/__tests__/Select.test.ts +37 -0
- package/components/formatter/InternalExternalIP.vue +2 -0
- package/components/formatter/SecretData.vue +20 -7
- package/components/nav/Group.vue +27 -5
- package/components/nav/Header.vue +17 -43
- package/components/nav/NamespaceFilter.vue +134 -86
- package/components/nav/TopLevelMenu.vue +4 -5
- package/components/nav/Type.vue +12 -1
- package/components/nav/WindowManager/ContainerLogs.vue +87 -61
- package/components/nav/WindowManager/ContainerLogsActions.vue +76 -0
- package/components/templates/blank.vue +4 -1
- package/components/templates/default.vue +8 -3
- package/components/templates/home.vue +10 -1
- package/components/templates/plain.vue +10 -4
- package/composables/focusTrap.ts +12 -4
- package/composables/useRuntimeFlag.ts +29 -0
- package/config/router/routes.js +20 -13
- package/config/store.js +4 -0
- package/config/uiplugins.js +5 -1
- package/core/types.ts +12 -6
- package/detail/catalog.cattle.io.app.vue +6 -1
- package/detail/fleet.cattle.io.bundle.vue +70 -6
- package/detail/fleet.cattle.io.gitrepo.vue +1 -1
- package/detail/namespace.vue +0 -3
- package/detail/node.vue +17 -13
- package/detail/provisioning.cattle.io.cluster.vue +72 -6
- package/dialog/AddCustomBadgeDialog.vue +1 -1
- package/{pages/c/_cluster/uiplugins/AddExtensionRepos.vue → dialog/AddExtensionReposDialog.vue} +72 -42
- package/{components/AssignTo.vue → dialog/AssignToDialog.vue} +71 -80
- package/dialog/ChangePasswordDialog.vue +106 -0
- package/dialog/DeactivateDriverDialog.vue +1 -0
- package/{pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue → dialog/DeveloperLoadExtensionDialog.vue} +74 -71
- package/dialog/DisableAuthProviderDialog.vue +101 -0
- package/dialog/DrainNode.vue +1 -1
- package/{pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue → dialog/ExtensionCatalogInstallDialog.vue} +100 -88
- package/{pages/c/_cluster/uiplugins/CatalogList/CatalogUninstallDialog.vue → dialog/ExtensionCatalogUninstallDialog.vue} +69 -57
- package/dialog/FeatureFlagListDialog.vue +288 -0
- package/dialog/ForceMachineRemoveDialog.vue +5 -2
- package/{components/Import.vue → dialog/ImportDialog.vue} +0 -5
- package/{pages/c/_cluster/uiplugins/InstallDialog.vue → dialog/InstallExtensionDialog.vue} +124 -106
- package/{components/form/SSHKnownHosts → dialog}/KnownHostsEditDialog.vue +52 -59
- package/dialog/MoveNamespaceDialog.vue +157 -0
- package/dialog/ScalePoolDownDialog.vue +1 -1
- package/{components/nav/Jump.vue → dialog/SearchDialog.vue} +34 -14
- package/{pages/c/_cluster/uiplugins/UninstallDialog.vue → dialog/UninstallExtensionDialog.vue} +67 -58
- package/dialog/WechatDialog.vue +57 -0
- package/edit/__tests__/monitoring.coreos.com.prometheusrule.test.ts +16 -3
- package/edit/auth/__tests__/oidc.test.ts +152 -109
- package/edit/auth/azuread.vue +2 -1
- package/edit/auth/github.vue +1 -1
- package/edit/auth/googleoauth.vue +5 -1
- package/edit/auth/ldap/index.vue +1 -1
- package/edit/auth/oidc.vue +38 -5
- package/edit/auth/saml.vue +1 -1
- package/edit/cloudcredential.vue +24 -9
- package/edit/logging.banzaicloud.io.output/__tests__/logging.banzaicloud.io.output.test.ts +40 -9
- package/edit/management.cattle.io.user.vue +28 -3
- package/edit/namespace.vue +1 -4
- package/edit/networking.k8s.io.ingress/IngressClass.vue +7 -3
- package/edit/networking.k8s.io.ingress/__tests__/IngressClass.test.ts +58 -0
- package/edit/persistentvolume/__tests__/persistentvolume.test.ts +14 -2
- package/edit/provisioning.cattle.io.cluster/CustomCommand.vue +4 -1
- package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +26 -9
- package/edit/provisioning.cattle.io.cluster/__tests__/Advanced.test.ts +8 -8
- package/edit/provisioning.cattle.io.cluster/__tests__/DirectoryConfig.test.ts +26 -12
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +66 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/utils/rke2-test-data.ts +58 -0
- package/edit/provisioning.cattle.io.cluster/rke2.vue +49 -41
- package/edit/provisioning.cattle.io.cluster/tabs/AgentConfiguration.vue +6 -1
- package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +5 -3
- package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +33 -2
- package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +2 -2
- package/edit/token.vue +2 -0
- package/edit/workload/index.vue +1 -0
- package/edit/workload/mixins/workload.js +0 -2
- package/initialize/install-plugins.js +2 -1
- package/list/harvesterhci.io.management.cluster.vue +4 -1
- package/list/management.cattle.io.feature.vue +4 -287
- package/list/provisioning.cattle.io.cluster.vue +20 -12
- package/machine-config/azure.vue +16 -4
- package/mixins/vue-select-overrides.js +0 -4
- package/models/__tests__/namespace.test.ts +25 -1
- package/models/cloudcredential.js +5 -0
- package/models/fleet.cattle.io.cluster.js +8 -2
- package/models/fleet.cattle.io.gitrepo.js +8 -34
- package/models/kontainerdriver.js +6 -3
- package/models/management.cattle.io.feature.js +7 -1
- package/models/management.cattle.io.node.js +3 -3
- package/models/namespace.js +11 -6
- package/models/nodedriver.js +6 -3
- package/models/workload.js +4 -1
- package/package.json +3 -3
- package/pages/about.vue +13 -3
- package/pages/account/index.vue +16 -6
- package/pages/auth/login.vue +18 -7
- package/pages/auth/logout.vue +4 -1
- package/pages/auth/setup.vue +2 -0
- package/pages/auth/verify.vue +13 -8
- package/pages/c/_cluster/apps/charts/chart.vue +1 -1
- package/pages/c/_cluster/apps/charts/install.vue +26 -26
- package/pages/c/_cluster/auth/config/index.vue +10 -12
- package/pages/c/_cluster/explorer/EventsTable.vue +38 -33
- package/pages/c/_cluster/explorer/index.vue +17 -15
- package/pages/c/_cluster/istio/index.vue +2 -2
- package/pages/c/_cluster/longhorn/index.vue +1 -1
- package/pages/c/_cluster/monitoring/index.vue +1 -1
- package/pages/c/_cluster/monitoring/monitor/_namespace/_id.vue +4 -2
- package/pages/c/_cluster/monitoring/monitor/create.vue +4 -2
- package/pages/c/_cluster/monitoring/route-receiver/_id.vue +4 -2
- package/pages/c/_cluster/monitoring/route-receiver/create.vue +5 -2
- package/pages/c/_cluster/neuvector/index.vue +1 -1
- package/pages/c/_cluster/settings/banners.vue +4 -3
- package/pages/c/_cluster/uiplugins/CatalogList/index.vue +8 -10
- package/pages/c/_cluster/uiplugins/__tests__/AddExtensionRepos.test.ts +4 -7
- package/pages/c/_cluster/uiplugins/index.vue +98 -55
- package/pages/diagnostic.vue +59 -11
- package/pages/fail-whale.vue +14 -8
- package/pages/home.vue +24 -18
- package/pages/prefs.vue +7 -6
- package/pages/support/index.vue +4 -1
- package/plugins/internal-api/index.ts +37 -0
- package/plugins/internal-api/shared/base-api.ts +13 -0
- package/plugins/internal-api/shell/shell.api.ts +108 -0
- package/plugins/steve/actions.js +0 -12
- package/public/index.html +1 -0
- package/rancher-components/Card/Card.vue +1 -1
- package/rancher-components/Form/Checkbox/Checkbox.test.ts +59 -1
- package/rancher-components/Form/Checkbox/Checkbox.vue +27 -3
- package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +47 -0
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +20 -2
- package/rancher-components/Form/Radio/RadioButton.test.ts +36 -1
- package/rancher-components/Form/Radio/RadioButton.vue +20 -4
- package/rancher-components/Form/Radio/RadioGroup.test.ts +60 -0
- package/rancher-components/Form/Radio/RadioGroup.vue +52 -10
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.test.ts +17 -0
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +5 -0
- package/rancher-components/LabeledTooltip/LabeledTooltip.vue +10 -1
- package/rancher-components/RcButton/RcButton.vue +2 -1
- package/rancher-components/RcButton/types.ts +1 -0
- package/rancher-components/RcDropdown/RcDropdown.vue +18 -6
- package/rancher-components/RcDropdown/RcDropdownItem.vue +3 -56
- package/rancher-components/RcDropdown/RcDropdownItemCheckbox.vue +68 -0
- package/rancher-components/RcDropdown/RcDropdownItemSelect.vue +92 -0
- package/rancher-components/RcDropdown/RcDropdownTrigger.vue +10 -0
- package/rancher-components/RcDropdown/index.ts +2 -0
- package/rancher-components/RcDropdown/useDropdownCollection.ts +8 -0
- package/rancher-components/RcDropdown/useDropdownContext.ts +9 -3
- package/rancher-components/RcDropdown/useDropdownItem.ts +63 -0
- package/scripts/extension/bundle +20 -0
- package/scripts/extension/helm/charts/ui-plugin-server/templates/cr.yaml +2 -1
- package/scripts/extension/helm/charts/ui-plugin-server/values.yaml +2 -0
- package/scripts/extension/helmpatch +44 -31
- package/scripts/extension/publish +12 -12
- package/scripts/typegen.sh +2 -4
- package/server/har-file.js +25 -3
- package/store/action-menu.js +26 -56
- package/store/features.js +2 -1
- package/store/index.js +5 -0
- package/store/modal.ts +71 -0
- package/store/slideInPanel.ts +47 -0
- package/store/type-map.js +12 -1
- package/store/type-map.utils.ts +4 -4
- package/types/global-vue.d.ts +5 -0
- package/types/internal-api/shell/growl.d.ts +25 -0
- package/types/internal-api/shell/modal.d.ts +77 -0
- package/types/internal-api/shell/slideIn.d.ts +15 -0
- package/types/resources/fleet.d.ts +0 -14
- package/types/shell/index.d.ts +43 -24
- package/types/vue-shim.d.ts +4 -1
- package/utils/__mocks__/tabbable.js +13 -0
- package/utils/__tests__/object.test.ts +38 -4
- package/utils/cluster.js +35 -0
- package/utils/fleet.ts +15 -73
- package/utils/object.js +48 -5
- package/utils/validators/formRules/__tests__/index.test.ts +10 -1
- package/utils/validators/formRules/index.ts +27 -3
- package/utils/validators/machine-pool.ts +20 -0
- package/components/DisableAuthProviderModal.vue +0 -114
- package/components/MoveModal.vue +0 -166
- package/components/PromptChangePassword.vue +0 -123
- package/components/fleet/FleetBundleResources.vue +0 -86
- package/components/formatter/ExtensionCache.vue +0 -74
- package/components/formatter/Port.vue +0 -24
- package/components/formatter/SecretType.vue +0 -41
- package/types/vue-shim.d +0 -20
|
@@ -81,6 +81,30 @@ export default {
|
|
|
81
81
|
},
|
|
82
82
|
|
|
83
83
|
computed: {
|
|
84
|
+
hasCustomCloudCredentialComponent() {
|
|
85
|
+
const driverName = this.driverName;
|
|
86
|
+
|
|
87
|
+
return this.$store.getters['type-map/hasCustomCloudCredentialComponent'](driverName);
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
cloudCredentialComponent() {
|
|
91
|
+
const driverName = this.driverName;
|
|
92
|
+
|
|
93
|
+
return this.$store.getters['type-map/importCloudCredential'](driverName);
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
genericCloudCredentialComponent() {
|
|
97
|
+
return this.$store.getters['type-map/importCloudCredential']('generic');
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
cloudComponent() {
|
|
101
|
+
if (this.hasCustomCloudCredentialComponent) {
|
|
102
|
+
return this.cloudCredentialComponent;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return this.genericCloudCredentialComponent;
|
|
106
|
+
},
|
|
107
|
+
|
|
84
108
|
isNone() {
|
|
85
109
|
return this.credentialId === null || this.credentialId === _NONE;
|
|
86
110
|
},
|
|
@@ -140,14 +164,6 @@ export default {
|
|
|
140
164
|
return out;
|
|
141
165
|
},
|
|
142
166
|
|
|
143
|
-
createComponent() {
|
|
144
|
-
if (this.$store.getters['type-map/hasCustomCloudCredentialComponent'](this.driverName)) {
|
|
145
|
-
return this.$store.getters['type-map/importCloudCredential'](this.driverName);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
return this.$store.getters['type-map/importCloudCredential']('generic');
|
|
149
|
-
},
|
|
150
|
-
|
|
151
167
|
validationPassed() {
|
|
152
168
|
if ( this.credentialId === _NONE ) {
|
|
153
169
|
return false;
|
|
@@ -175,6 +191,7 @@ export default {
|
|
|
175
191
|
},
|
|
176
192
|
|
|
177
193
|
methods: {
|
|
194
|
+
|
|
178
195
|
async save(btnCb) {
|
|
179
196
|
if ( this.errors ) {
|
|
180
197
|
clear(this.errors);
|
|
@@ -266,7 +283,7 @@ export default {
|
|
|
266
283
|
/>
|
|
267
284
|
|
|
268
285
|
<component
|
|
269
|
-
:is="
|
|
286
|
+
:is="cloudComponent"
|
|
270
287
|
ref="create"
|
|
271
288
|
v-model:value="newCredential"
|
|
272
289
|
mode="create"
|
|
@@ -176,7 +176,7 @@ describe('component: Advanced', () => {
|
|
|
176
176
|
const selectorContainer = wrapper.find('[data-testid="selector-kubelet-arg"]');
|
|
177
177
|
|
|
178
178
|
const globalInputElem = globalContainer;
|
|
179
|
-
const selectorInputElem = selectorContainer.find('[data-testid="input-0"]').element as HTMLInputElement;
|
|
179
|
+
const selectorInputElem = selectorContainer.find('[data-testid="array-list-input-0"]').element as HTMLInputElement;
|
|
180
180
|
|
|
181
181
|
expect(globalInputElem.exists()).toBe(false);
|
|
182
182
|
expect(selectorInputElem.value).toContain('config-from-machineSelectorConfig');
|
|
@@ -199,7 +199,7 @@ describe('component: Advanced', () => {
|
|
|
199
199
|
const selectorContainer = wrapper.find('[data-testid="selector-kubelet-arg"]');
|
|
200
200
|
|
|
201
201
|
const selectorInputElem = selectorContainer;
|
|
202
|
-
const globalInputElem = globalContainer.find('[data-testid="input-0"]').element as HTMLInputElement;
|
|
202
|
+
const globalInputElem = globalContainer.find('[data-testid="array-list-input-0"]').element as HTMLInputElement;
|
|
203
203
|
|
|
204
204
|
expect(selectorInputElem.exists()).toBe(false);
|
|
205
205
|
expect(globalInputElem.value).toContain('config-from-machineGlobalConfig');
|
|
@@ -222,8 +222,8 @@ describe('component: Advanced', () => {
|
|
|
222
222
|
const globalContainer = wrapper.find('[data-testid="global-kubelet-arg"]');
|
|
223
223
|
const selectorContainer = wrapper.find('[data-testid="selector-kubelet-arg"]');
|
|
224
224
|
|
|
225
|
-
const selectorInputElem = selectorContainer.find('[data-testid="input-0"]').element as HTMLInputElement;
|
|
226
|
-
const globalInputElem = globalContainer.find('[data-testid="input-0"]').element as HTMLInputElement;
|
|
225
|
+
const selectorInputElem = selectorContainer.find('[data-testid="array-list-input-0"]').element as HTMLInputElement;
|
|
226
|
+
const globalInputElem = globalContainer.find('[data-testid="array-list-input-0"]').element as HTMLInputElement;
|
|
227
227
|
|
|
228
228
|
expect(selectorInputElem.value).toContain('config-from-machineSelectorConfig');
|
|
229
229
|
expect(globalInputElem.value).toContain('config-from-machineGlobalConfig');
|
|
@@ -247,8 +247,8 @@ describe('component: Advanced', () => {
|
|
|
247
247
|
const globalContainer = wrapper.find('[data-testid="global-kubelet-arg"]');
|
|
248
248
|
const selectorContainer = wrapper.find('[data-testid="selector-kubelet-arg"]');
|
|
249
249
|
|
|
250
|
-
const selectorInputElem = selectorContainer.find('[data-testid="input-0"]');
|
|
251
|
-
const globalInputElem = globalContainer.find('[data-testid="input-0"]');
|
|
250
|
+
const selectorInputElem = selectorContainer.find('[data-testid="array-list-input-0"]');
|
|
251
|
+
const globalInputElem = globalContainer.find('[data-testid="array-list-input-0"]');
|
|
252
252
|
|
|
253
253
|
const emptyCharacter = wrapper.find('.info-box').find('.text-muted').element;
|
|
254
254
|
|
|
@@ -282,8 +282,8 @@ describe('component: Advanced', () => {
|
|
|
282
282
|
const globalContainer = wrapper.find('[data-testid="global-kubelet-arg"]');
|
|
283
283
|
const selectorContainer = wrapper.find('[data-testid="selector-kubelet-arg"]');
|
|
284
284
|
|
|
285
|
-
const selectorInputElem = selectorContainer.find('[data-testid="input-0"]');
|
|
286
|
-
const globalInputElem = globalContainer.find('[data-testid="input-0"]');
|
|
285
|
+
const selectorInputElem = selectorContainer.find('[data-testid="array-list-input-0"]');
|
|
286
|
+
const globalInputElem = globalContainer.find('[data-testid="array-list-input-0"]');
|
|
287
287
|
|
|
288
288
|
const emptyCharacter = wrapper.find('.info-box').find('.text-muted');
|
|
289
289
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { nextTick } from 'vue';
|
|
2
2
|
/* eslint-disable jest/no-hooks */
|
|
3
3
|
import { mount, Wrapper } from '@vue/test-utils';
|
|
4
|
-
import DirectoryConfig, { DATA_DIR_RADIO_OPTIONS, DEFAULT_SUBDIRS } from '@shell/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue';
|
|
4
|
+
import DirectoryConfig, { DATA_DIR_RADIO_OPTIONS, DEFAULT_SUBDIRS, DEFAULT_COMMON_BASE_PATH } from '@shell/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue';
|
|
5
5
|
import { _EDIT, _CREATE } from '@shell/config/query-params';
|
|
6
6
|
import { clone } from '@shell/utils/object';
|
|
7
7
|
|
|
@@ -54,7 +54,7 @@ describe('component: DirectoryConfig', () => {
|
|
|
54
54
|
expect(k8sDistroInput.exists()).toBe(false);
|
|
55
55
|
});
|
|
56
56
|
|
|
57
|
-
it('
|
|
57
|
+
it('setting the radio option to "common" should set the correct values on each data dir variable', async() => {
|
|
58
58
|
const newMountOptions = clone(mountOptions);
|
|
59
59
|
|
|
60
60
|
wrapper = mount(
|
|
@@ -68,17 +68,12 @@ describe('component: DirectoryConfig', () => {
|
|
|
68
68
|
}
|
|
69
69
|
);
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
// update radio to the "common" option
|
|
72
|
+
await wrapper.vm.handleRadioInput(DATA_DIR_RADIO_OPTIONS.COMMON);
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
expect(
|
|
76
|
-
|
|
77
|
-
await nextTick();
|
|
78
|
-
|
|
79
|
-
expect(wrapper.vm.value.systemAgent).toStrictEqual(`${ inputPath }/${ DEFAULT_SUBDIRS.AGENT }`);
|
|
80
|
-
expect(wrapper.vm.value.provisioning).toStrictEqual(`${ inputPath }/${ DEFAULT_SUBDIRS.PROVISIONING }`);
|
|
81
|
-
expect(wrapper.vm.value.k8sDistro).toStrictEqual(`${ inputPath }/${ DEFAULT_SUBDIRS.K8S_DISTRO_K3S }`);
|
|
74
|
+
expect(wrapper.vm.value.systemAgent).toStrictEqual(`${ DEFAULT_COMMON_BASE_PATH }/${ DEFAULT_SUBDIRS.AGENT }`);
|
|
75
|
+
expect(wrapper.vm.value.provisioning).toStrictEqual(`${ DEFAULT_COMMON_BASE_PATH }/${ DEFAULT_SUBDIRS.PROVISIONING }`);
|
|
76
|
+
expect(wrapper.vm.value.k8sDistro).toStrictEqual(`${ DEFAULT_COMMON_BASE_PATH }/${ DEFAULT_SUBDIRS.K8S_DISTRO_K3S }`);
|
|
82
77
|
});
|
|
83
78
|
|
|
84
79
|
it('updating each individual data dir should set the correct values on each data dir variable', async() => {
|
|
@@ -179,4 +174,23 @@ describe('component: DirectoryConfig', () => {
|
|
|
179
174
|
expect(wrapper.vm.value.provisioning).toStrictEqual(`${ inputPath }/${ DEFAULT_SUBDIRS.PROVISIONING }`);
|
|
180
175
|
expect(wrapper.vm.value.k8sDistro).toStrictEqual(`${ inputPath }/${ DEFAULT_SUBDIRS.K8S_DISTRO_K3S }`);
|
|
181
176
|
});
|
|
177
|
+
|
|
178
|
+
it('updating the k8s version for the "common" config should only update the sub dir for the k8sDistro value', async() => {
|
|
179
|
+
wrapper = mount(
|
|
180
|
+
DirectoryConfig,
|
|
181
|
+
mountOptions
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
// update radio to the "common" option
|
|
185
|
+
await wrapper.vm.handleRadioInput(DATA_DIR_RADIO_OPTIONS.COMMON);
|
|
186
|
+
|
|
187
|
+
expect(wrapper.vm.value.systemAgent).toStrictEqual(`${ DEFAULT_COMMON_BASE_PATH }/${ DEFAULT_SUBDIRS.AGENT }`);
|
|
188
|
+
expect(wrapper.vm.value.provisioning).toStrictEqual(`${ DEFAULT_COMMON_BASE_PATH }/${ DEFAULT_SUBDIRS.PROVISIONING }`);
|
|
189
|
+
expect(wrapper.vm.value.k8sDistro).toStrictEqual(`${ DEFAULT_COMMON_BASE_PATH }/${ DEFAULT_SUBDIRS.K8S_DISTRO_K3S }`);
|
|
190
|
+
|
|
191
|
+
// let's update the k8s version
|
|
192
|
+
await wrapper.setProps({ k8sVersion: 'v1.32.4+rke2r1' });
|
|
193
|
+
|
|
194
|
+
expect(wrapper.vm.value.k8sDistro).toStrictEqual(`${ DEFAULT_COMMON_BASE_PATH }/${ DEFAULT_SUBDIRS.K8S_DISTRO_RKE2 }`);
|
|
195
|
+
});
|
|
182
196
|
});
|
|
@@ -3,6 +3,7 @@ import { SECRET } from '@shell/config/types';
|
|
|
3
3
|
import { _CREATE } from '@shell/config/query-params';
|
|
4
4
|
import rke2 from '@shell/edit/provisioning.cattle.io.cluster/rke2.vue';
|
|
5
5
|
import { get } from '@shell/utils/object';
|
|
6
|
+
import { rke2TestTable } from './utils/rke2-test-data';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* DISCLAIMER ***************************************************************************************
|
|
@@ -543,4 +544,69 @@ describe('component: rke2', () => {
|
|
|
543
544
|
|
|
544
545
|
expect(azureOption.disabled).toBe(value);
|
|
545
546
|
});
|
|
547
|
+
|
|
548
|
+
it.each(rke2TestTable)('should preserve valid user-supplied chart values', (chartValues, expected) => {
|
|
549
|
+
const wrapper = mount(rke2, {
|
|
550
|
+
props: {
|
|
551
|
+
mode: _CREATE,
|
|
552
|
+
value: {
|
|
553
|
+
spec: {
|
|
554
|
+
...defaultSpec,
|
|
555
|
+
chartValues,
|
|
556
|
+
kubernetesVersion: 'v1.32.3+rke2r1',
|
|
557
|
+
rkeConfig: {
|
|
558
|
+
machineGlobalConfig: {
|
|
559
|
+
cni: 'calico',
|
|
560
|
+
'disable-kube-proxy': false,
|
|
561
|
+
'etcd-expose-metrics': false
|
|
562
|
+
},
|
|
563
|
+
}
|
|
564
|
+
},
|
|
565
|
+
agentConfig: { 'cloud-provider-name': 'any' }
|
|
566
|
+
},
|
|
567
|
+
provider: 'custom'
|
|
568
|
+
},
|
|
569
|
+
data: () => ({
|
|
570
|
+
credentialId: 'I am authenticated',
|
|
571
|
+
userChartValues: chartValues,
|
|
572
|
+
rke2Versions: [
|
|
573
|
+
{
|
|
574
|
+
id: 'v1.32.3+rke2r1',
|
|
575
|
+
type: 'release',
|
|
576
|
+
links: { self: 'https://127.0.0.1:8005/v1-rke2-release/releases/v1.32.3+rke2r1' },
|
|
577
|
+
version: 'v1.32.3+rke2r1',
|
|
578
|
+
minChannelServerVersion: 'v2.11.0-alpha1',
|
|
579
|
+
maxChannelServerVersion: 'v2.11.99',
|
|
580
|
+
serverArgs: {},
|
|
581
|
+
agentArgs: {},
|
|
582
|
+
featureVersions: { 'encryption-key-rotation': '2.0.0' },
|
|
583
|
+
charts: {
|
|
584
|
+
'rke2-ingress-nginx': {
|
|
585
|
+
repo: 'rancher-rke2-charts',
|
|
586
|
+
version: '4.12.100'
|
|
587
|
+
},
|
|
588
|
+
'rke2-metrics-server': {
|
|
589
|
+
repo: 'rancher-rke2-charts',
|
|
590
|
+
version: '3.12.200'
|
|
591
|
+
},
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
]
|
|
595
|
+
}),
|
|
596
|
+
|
|
597
|
+
global: {
|
|
598
|
+
mocks: {
|
|
599
|
+
...defaultMocks,
|
|
600
|
+
$store: { dispatch: () => jest.fn(), getters: defaultGetters },
|
|
601
|
+
$plugin: { getDynamic: jest.fn(() => undefined ) },
|
|
602
|
+
},
|
|
603
|
+
|
|
604
|
+
stubs: defaultStubs,
|
|
605
|
+
},
|
|
606
|
+
});
|
|
607
|
+
|
|
608
|
+
wrapper.vm.applyChartValues(wrapper.vm.value.spec.rkeConfig);
|
|
609
|
+
|
|
610
|
+
expect(wrapper.vm.value.spec.rkeConfig.chartValues).toStrictEqual(expected);
|
|
611
|
+
});
|
|
546
612
|
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export const rke2TestTable = [
|
|
2
|
+
[
|
|
3
|
+
{
|
|
4
|
+
'rke2-calico': {},
|
|
5
|
+
'rke2-ingress-nginx': {
|
|
6
|
+
controller: {
|
|
7
|
+
extraArgs: {
|
|
8
|
+
'enable-ssl-passthrough': true,
|
|
9
|
+
'watch-ingress-without-class': true
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
'rke2-calico': {},
|
|
16
|
+
'rke2-ingress-nginx': {
|
|
17
|
+
controller: {
|
|
18
|
+
extraArgs: {
|
|
19
|
+
'enable-ssl-passthrough': true,
|
|
20
|
+
'watch-ingress-without-class': true
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
[
|
|
27
|
+
{
|
|
28
|
+
'rke2-calico': {},
|
|
29
|
+
'rke2-ingress-nginx': {
|
|
30
|
+
controller: {
|
|
31
|
+
extraArgs: {
|
|
32
|
+
'enable-ssl-passthrough': true,
|
|
33
|
+
'watch-ingress-without-class': true
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
'rke2-ingress-nginx-invalid': {
|
|
38
|
+
controller: {
|
|
39
|
+
extraArgs: {
|
|
40
|
+
'enable-ssl-passthrough': true,
|
|
41
|
+
'watch-ingress-without-class': true
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
'rke2-calico': {},
|
|
48
|
+
'rke2-ingress-nginx': {
|
|
49
|
+
controller: {
|
|
50
|
+
extraArgs: {
|
|
51
|
+
'enable-ssl-passthrough': true,
|
|
52
|
+
'watch-ingress-without-class': true
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
];
|
|
@@ -22,10 +22,12 @@ import { _CREATE, _EDIT, _VIEW } from '@shell/config/query-params';
|
|
|
22
22
|
import { findBy, removeObject, clear } from '@shell/utils/array';
|
|
23
23
|
import { createYaml } from '@shell/utils/create-yaml';
|
|
24
24
|
import {
|
|
25
|
-
clone, diff, set, get, isEmpty,
|
|
25
|
+
clone, diff, set, get, isEmpty, mergeWithReplace
|
|
26
26
|
} from '@shell/utils/object';
|
|
27
27
|
import { allHash } from '@shell/utils/promise';
|
|
28
|
-
import {
|
|
28
|
+
import {
|
|
29
|
+
getAllOptionsAfterCurrentVersion, filterOutDeprecatedPatchVersions, isHarvesterSatisfiesVersion, labelForAddon, initSchedulingCustomization
|
|
30
|
+
} from '@shell/utils/cluster';
|
|
29
31
|
|
|
30
32
|
import { BadgeState } from '@components/BadgeState';
|
|
31
33
|
import { Banner } from '@components/Banner';
|
|
@@ -63,7 +65,6 @@ import ClusterAppearance from '@shell/components/form/ClusterAppearance';
|
|
|
63
65
|
import AddOnAdditionalManifest from '@shell/edit/provisioning.cattle.io.cluster/tabs/AddOnAdditionalManifest';
|
|
64
66
|
import VsphereUtils, { VMWARE_VSPHERE } from '@shell/utils/v-sphere';
|
|
65
67
|
import { mapGetters } from 'vuex';
|
|
66
|
-
import { SCHEDULING_CUSTOMIZATION } from '@shell/store/features';
|
|
67
68
|
const HARVESTER = 'harvester';
|
|
68
69
|
const HARVESTER_CLOUD_PROVIDER = 'harvester-cloud-provider';
|
|
69
70
|
const NETBIOS_TRUNCATION_LENGTH = 15;
|
|
@@ -149,7 +150,13 @@ export default {
|
|
|
149
150
|
await this.initSpecs();
|
|
150
151
|
await this.initAddons();
|
|
151
152
|
await this.initRegistry();
|
|
152
|
-
await this.
|
|
153
|
+
const sc = await initSchedulingCustomization(this.value.spec, this.features, this.$store, this.mode);
|
|
154
|
+
|
|
155
|
+
this.clusterAgentDefaultPC = sc.clusterAgentDefaultPC;
|
|
156
|
+
this.clusterAgentDefaultPDB = sc.clusterAgentDefaultPDB;
|
|
157
|
+
this.schedulingCustomizationFeatureEnabled = sc.schedulingCustomizationFeatureEnabled;
|
|
158
|
+
this.schedulingCustomizationOriginallyEnabled = sc.schedulingCustomizationOriginallyEnabled;
|
|
159
|
+
this.errors = this.errors.concat(sc.errors);
|
|
153
160
|
|
|
154
161
|
Object.entries(this.chartValues).forEach(([name, value]) => {
|
|
155
162
|
const key = this.chartVersionKey(name);
|
|
@@ -243,20 +250,21 @@ export default {
|
|
|
243
250
|
fvFormRuleSets: [{
|
|
244
251
|
path: 'metadata.name', rules: ['subDomain'], translationKey: 'nameNsDescription.name.label'
|
|
245
252
|
}],
|
|
246
|
-
harvesterVersionRange:
|
|
247
|
-
cisOverride:
|
|
253
|
+
harvesterVersionRange: {},
|
|
254
|
+
cisOverride: false,
|
|
248
255
|
truncateLimit,
|
|
249
|
-
busy:
|
|
250
|
-
machinePoolValidation:
|
|
251
|
-
machinePoolErrors:
|
|
252
|
-
addonConfigValidation:
|
|
253
|
-
allNamespaces:
|
|
254
|
-
extensionTabs:
|
|
255
|
-
clusterAgentDeploymentCustomization:
|
|
256
|
-
schedulingCustomizationFeatureEnabled:
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
256
|
+
busy: false,
|
|
257
|
+
machinePoolValidation: {}, // map of validation states for each machine pool
|
|
258
|
+
machinePoolErrors: {},
|
|
259
|
+
addonConfigValidation: {}, // validation state of each addon config (boolean of whether codemirror's yaml lint passed)
|
|
260
|
+
allNamespaces: [],
|
|
261
|
+
extensionTabs: getApplicableExtensionEnhancements(this, ExtensionPoint.TAB, TabLocation.CLUSTER_CREATE_RKE2, this.$route, this),
|
|
262
|
+
clusterAgentDeploymentCustomization: null,
|
|
263
|
+
schedulingCustomizationFeatureEnabled: false,
|
|
264
|
+
schedulingCustomizationOriginallyEnabled: false,
|
|
265
|
+
clusterAgentDefaultPC: null,
|
|
266
|
+
clusterAgentDefaultPDB: null,
|
|
267
|
+
activeTab: null,
|
|
260
268
|
REGISTRIES_TAB_NAME,
|
|
261
269
|
labelForAddon
|
|
262
270
|
|
|
@@ -289,6 +297,21 @@ export default {
|
|
|
289
297
|
return this.value.spec.rkeConfig.chartValues;
|
|
290
298
|
},
|
|
291
299
|
|
|
300
|
+
kubernetesVersion() {
|
|
301
|
+
return this.value.spec.kubernetesVersion;
|
|
302
|
+
},
|
|
303
|
+
|
|
304
|
+
rke2Charts() {
|
|
305
|
+
const rke2Versions = this.rke2Versions || [];
|
|
306
|
+
const kubernetesVersion = this.kubernetesVersion;
|
|
307
|
+
|
|
308
|
+
const charts = rke2Versions
|
|
309
|
+
.find((version) => version.id === kubernetesVersion)
|
|
310
|
+
?.charts ?? {};
|
|
311
|
+
|
|
312
|
+
return Object.keys(charts);
|
|
313
|
+
},
|
|
314
|
+
|
|
292
315
|
serverConfig() {
|
|
293
316
|
return this.value.spec.rkeConfig.machineGlobalConfig;
|
|
294
317
|
},
|
|
@@ -568,7 +591,7 @@ export default {
|
|
|
568
591
|
out.tooltip[role] = this.t(`cluster.machinePool.nodeTotals.tooltip.${ role }`, { count: counts[role] });
|
|
569
592
|
}
|
|
570
593
|
|
|
571
|
-
if (counts.etcd
|
|
594
|
+
if (counts.etcd <= 0) {
|
|
572
595
|
out.color.etcd = NODE_TOTAL.error.color;
|
|
573
596
|
out.icon.etcd = NODE_TOTAL.error.icon;
|
|
574
597
|
} else if (counts.etcd === 1 || counts.etcd % 2 === 0 || counts.etcd > 7) {
|
|
@@ -576,7 +599,7 @@ export default {
|
|
|
576
599
|
out.icon.etcd = NODE_TOTAL.warning.icon;
|
|
577
600
|
}
|
|
578
601
|
|
|
579
|
-
if (counts.controlPlane
|
|
602
|
+
if (counts.controlPlane <= 0) {
|
|
580
603
|
out.color.controlPlane = NODE_TOTAL.error.color;
|
|
581
604
|
out.icon.controlPlane = NODE_TOTAL.error.icon;
|
|
582
605
|
} else if (counts.controlPlane === 1) {
|
|
@@ -584,7 +607,7 @@ export default {
|
|
|
584
607
|
out.icon.controlPlane = NODE_TOTAL.warning.icon;
|
|
585
608
|
}
|
|
586
609
|
|
|
587
|
-
if (counts.worker
|
|
610
|
+
if (counts.worker <= 0) {
|
|
588
611
|
out.color.worker = NODE_TOTAL.error.color;
|
|
589
612
|
out.icon.worker = NODE_TOTAL.error.icon;
|
|
590
613
|
} else if (counts.worker === 1) {
|
|
@@ -1062,24 +1085,6 @@ export default {
|
|
|
1062
1085
|
}
|
|
1063
1086
|
},
|
|
1064
1087
|
|
|
1065
|
-
async initSchedulingCustomization() {
|
|
1066
|
-
this.schedulingCustomizationFeatureEnabled = this.features(SCHEDULING_CUSTOMIZATION);
|
|
1067
|
-
try {
|
|
1068
|
-
this.clusterAgentDefaultPC = JSON.parse((await this.$store.dispatch('management/find', { type: MANAGEMENT.SETTING, id: SETTING.CLUSTER_AGENT_DEFAULT_PRIORITY_CLASS })).value) || null;
|
|
1069
|
-
} catch (e) {
|
|
1070
|
-
this.errors.push(e);
|
|
1071
|
-
}
|
|
1072
|
-
try {
|
|
1073
|
-
this.clusterAgentDefaultPDB = JSON.parse((await this.$store.dispatch('management/find', { type: MANAGEMENT.SETTING, id: SETTING.CLUSTER_AGENT_DEFAULT_POD_DISTRIBUTION_BUDGET })).value) || null;
|
|
1074
|
-
} catch (e) {
|
|
1075
|
-
this.errors.push(e);
|
|
1076
|
-
}
|
|
1077
|
-
|
|
1078
|
-
if (this.schedulingCustomizationFeatureEnabled && this.mode === _CREATE && isEmpty(this.value?.spec?.clusterAgentDeploymentCustomization?.schedulingCustomization)) {
|
|
1079
|
-
set(this.value, 'spec.clusterAgentDeploymentCustomization.schedulingCustomization', { priorityClass: this.clusterAgentDefaultPC, podDisruptionBudget: this.clusterAgentDefaultPDB });
|
|
1080
|
-
}
|
|
1081
|
-
},
|
|
1082
|
-
|
|
1083
1088
|
setSchedulingCustomization(val) {
|
|
1084
1089
|
if (val) {
|
|
1085
1090
|
set(this.value, 'spec.clusterAgentDeploymentCustomization.schedulingCustomization', { priorityClass: this.clusterAgentDefaultPC, podDisruptionBudget: this.clusterAgentDefaultPDB });
|
|
@@ -1315,7 +1320,7 @@ export default {
|
|
|
1315
1320
|
delete clonedCurrentConfig.metadata;
|
|
1316
1321
|
|
|
1317
1322
|
if (this.provider === VMWARE_VSPHERE) {
|
|
1318
|
-
machinePool.config =
|
|
1323
|
+
machinePool.config = mergeWithReplace(clonedLatestConfig, clonedCurrentConfig, { mutateOriginal: true });
|
|
1319
1324
|
} else {
|
|
1320
1325
|
machinePool.config = merge(clonedLatestConfig, clonedCurrentConfig);
|
|
1321
1326
|
}
|
|
@@ -1701,7 +1706,7 @@ export default {
|
|
|
1701
1706
|
const defaultChartValue = this.versionInfo[name];
|
|
1702
1707
|
const key = this.chartVersionKey(name);
|
|
1703
1708
|
|
|
1704
|
-
return
|
|
1709
|
+
return mergeWithReplace(defaultChartValue?.values, this.userChartValues[key]);
|
|
1705
1710
|
},
|
|
1706
1711
|
|
|
1707
1712
|
initServerAgentArgs() {
|
|
@@ -1860,7 +1865,9 @@ export default {
|
|
|
1860
1865
|
|
|
1861
1866
|
applyChartValues(rkeConfig) {
|
|
1862
1867
|
rkeConfig.chartValues = {};
|
|
1863
|
-
this.addonNames.
|
|
1868
|
+
const charts = [...this.addonNames, ...this.rke2Charts];
|
|
1869
|
+
|
|
1870
|
+
charts.forEach((name) => {
|
|
1864
1871
|
const key = this.chartVersionKey(name);
|
|
1865
1872
|
const userValues = this.userChartValues[key];
|
|
1866
1873
|
|
|
@@ -2450,6 +2457,7 @@ export default {
|
|
|
2450
2457
|
:scheduling-customization-feature-enabled="schedulingCustomizationFeatureEnabled"
|
|
2451
2458
|
:default-p-c="clusterAgentDefaultPC"
|
|
2452
2459
|
:default-p-d-b="clusterAgentDefaultPDB"
|
|
2460
|
+
:scheduling-customization-originally-enabled="schedulingCustomizationOriginallyEnabled"
|
|
2453
2461
|
@scheduling-customization-changed="setSchedulingCustomization"
|
|
2454
2462
|
/>
|
|
2455
2463
|
</Tab>
|
|
@@ -48,6 +48,11 @@ export default {
|
|
|
48
48
|
type: Boolean,
|
|
49
49
|
required: false
|
|
50
50
|
},
|
|
51
|
+
schedulingCustomizationOriginallyEnabled: {
|
|
52
|
+
type: Boolean,
|
|
53
|
+
default: false
|
|
54
|
+
},
|
|
55
|
+
|
|
51
56
|
defaultPC: {
|
|
52
57
|
type: Object,
|
|
53
58
|
default: () => {},
|
|
@@ -149,7 +154,7 @@ export default {
|
|
|
149
154
|
},
|
|
150
155
|
|
|
151
156
|
schedulingCustomizationVisible() {
|
|
152
|
-
return this.schedulingCustomizationFeatureEnabled ||
|
|
157
|
+
return this.schedulingCustomizationFeatureEnabled || this.schedulingCustomizationOriginallyEnabled;
|
|
153
158
|
},
|
|
154
159
|
|
|
155
160
|
affinityOptions() {
|
|
@@ -78,8 +78,8 @@ export default {
|
|
|
78
78
|
this.k8sDistroSubDir = DEFAULT_SUBDIRS.K8S_DISTRO_RKE2;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
if (this.
|
|
82
|
-
this.value.k8sDistro = `${
|
|
81
|
+
if (this.dataConfigRadioValue === DATA_DIR_RADIO_OPTIONS.COMMON && this.commonConfig) {
|
|
82
|
+
this.value.k8sDistro = `${ this.commonConfig }/${ this.k8sDistroSubDir }`;
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
}
|
|
@@ -129,9 +129,11 @@ export default {
|
|
|
129
129
|
this.commonConfig = DEFAULT_COMMON_BASE_PATH;
|
|
130
130
|
|
|
131
131
|
this.dataConfigRadioValue = DATA_DIR_RADIO_OPTIONS.COMMON;
|
|
132
|
+
|
|
133
|
+
// individual data for each field is set on the watcher for commonConfig a bit further above
|
|
132
134
|
break;
|
|
133
|
-
// default is custom config
|
|
134
135
|
default:
|
|
136
|
+
// switch "default" is for the "custom" config
|
|
135
137
|
if (this.mode === _CREATE) {
|
|
136
138
|
this.commonConfig = '';
|
|
137
139
|
}
|
|
@@ -8,6 +8,8 @@ import AdvancedSection from '@shell/components/AdvancedSection.vue';
|
|
|
8
8
|
import { Banner } from '@components/Banner';
|
|
9
9
|
import UnitInput from '@shell/components/form/UnitInput.vue';
|
|
10
10
|
import { randomStr } from '@shell/utils/string';
|
|
11
|
+
import FormValidation from '@shell/mixins/form-validation';
|
|
12
|
+
import { MACHINE_POOL_VALIDATION } from '@shell/utils/validators/machine-pool';
|
|
11
13
|
|
|
12
14
|
export default {
|
|
13
15
|
|
|
@@ -25,6 +27,8 @@ export default {
|
|
|
25
27
|
UnitInput
|
|
26
28
|
},
|
|
27
29
|
|
|
30
|
+
mixins: [FormValidation],
|
|
31
|
+
|
|
28
32
|
props: {
|
|
29
33
|
value: {
|
|
30
34
|
type: Object,
|
|
@@ -122,6 +126,12 @@ export default {
|
|
|
122
126
|
uuid: randomStr(),
|
|
123
127
|
|
|
124
128
|
unhealthyNodeTimeoutInteger: this.value.pool.unhealthyNodeTimeout ? parseDuration(this.value.pool.unhealthyNodeTimeout) : 0,
|
|
129
|
+
|
|
130
|
+
validationErrors: [],
|
|
131
|
+
|
|
132
|
+
MACHINE_POOL_VALIDATION,
|
|
133
|
+
|
|
134
|
+
fvFormRuleSets: MACHINE_POOL_VALIDATION.RULESETS,
|
|
125
135
|
};
|
|
126
136
|
},
|
|
127
137
|
|
|
@@ -136,7 +146,7 @@ export default {
|
|
|
136
146
|
|
|
137
147
|
isWindows() {
|
|
138
148
|
return this.value?.config?.os === 'windows';
|
|
139
|
-
}
|
|
149
|
+
}
|
|
140
150
|
},
|
|
141
151
|
|
|
142
152
|
watch: {
|
|
@@ -148,6 +158,20 @@ export default {
|
|
|
148
158
|
} else {
|
|
149
159
|
this.value.pool.machineOS = 'linux';
|
|
150
160
|
}
|
|
161
|
+
},
|
|
162
|
+
|
|
163
|
+
validationErrors: {
|
|
164
|
+
handler(newValue) {
|
|
165
|
+
this.$emit('validationChanged', newValue.length === 0);
|
|
166
|
+
},
|
|
167
|
+
deep: true
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
fvFormIsValid: {
|
|
171
|
+
handler(newValue) {
|
|
172
|
+
this.$emit('validationChanged', newValue);
|
|
173
|
+
},
|
|
174
|
+
deep: true
|
|
151
175
|
}
|
|
152
176
|
},
|
|
153
177
|
|
|
@@ -227,6 +251,8 @@ export default {
|
|
|
227
251
|
:label="t('cluster.machinePool.name.label')"
|
|
228
252
|
:required="true"
|
|
229
253
|
:disabled="!value.config || !!value.config.id || busy"
|
|
254
|
+
:rules="fvGetAndReportPathRules(MACHINE_POOL_VALIDATION.FIELDS.NAME)"
|
|
255
|
+
data-testid="machine-pool-name-input"
|
|
230
256
|
/>
|
|
231
257
|
</div>
|
|
232
258
|
<div class="col span-4">
|
|
@@ -238,6 +264,8 @@ export default {
|
|
|
238
264
|
type="number"
|
|
239
265
|
min="0"
|
|
240
266
|
:required="true"
|
|
267
|
+
:rules="fvGetAndReportPathRules(MACHINE_POOL_VALIDATION.FIELDS.QUANTITY)"
|
|
268
|
+
data-testid="machine-pool-quantity-input"
|
|
241
269
|
/>
|
|
242
270
|
</div>
|
|
243
271
|
<div class="col span-4 pt-5">
|
|
@@ -264,7 +292,10 @@ export default {
|
|
|
264
292
|
/>
|
|
265
293
|
</div>
|
|
266
294
|
</div>
|
|
267
|
-
<hr
|
|
295
|
+
<hr
|
|
296
|
+
class="mt-10"
|
|
297
|
+
role="none"
|
|
298
|
+
>
|
|
268
299
|
<component
|
|
269
300
|
:is="configComponent"
|
|
270
301
|
v-if="value.config && configComponent"
|
|
@@ -90,8 +90,8 @@ export default {
|
|
|
90
90
|
v-model:value="etcd.snapshotRetention"
|
|
91
91
|
:mode="mode"
|
|
92
92
|
:label="t('cluster.rke2.etcd.snapshotRetention.label')"
|
|
93
|
-
:suffix="t('cluster.rke2.snapshots.suffix')"
|
|
94
|
-
:tooltip="t('cluster.rke2.etcd.snapshotRetention.tooltip')"
|
|
93
|
+
:suffix="s3Backup ? t('cluster.rke2.snapshots.s3Suffix') : t('cluster.rke2.snapshots.suffix')"
|
|
94
|
+
:tooltip="s3Backup ? t('cluster.rke2.etcd.snapshotRetention.tooltip') : undefined"
|
|
95
95
|
/>
|
|
96
96
|
</div>
|
|
97
97
|
</div>
|
package/edit/token.vue
CHANGED
|
@@ -210,6 +210,7 @@ export default {
|
|
|
210
210
|
:disabled="form.expiryType !== 'custom'"
|
|
211
211
|
type="number"
|
|
212
212
|
:mode="mode"
|
|
213
|
+
:aria-label="t('accountAndKeys.apiKeys.add.ariaLabel.expiration')"
|
|
213
214
|
>
|
|
214
215
|
<Select
|
|
215
216
|
v-model:value="form.customExpiryUnits"
|
|
@@ -217,6 +218,7 @@ export default {
|
|
|
217
218
|
:options="expiryUnitsOptions"
|
|
218
219
|
:clearable="false"
|
|
219
220
|
:reduce="opt=>opt.value"
|
|
221
|
+
:aria-label="t('accountAndKeys.apiKeys.add.ariaLabel.expirationUnits')"
|
|
220
222
|
/>
|
|
221
223
|
</div>
|
|
222
224
|
</div>
|
package/edit/workload/index.vue
CHANGED