@rancher/shell 3.0.5-rc.1 → 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/_helpers.scss +4 -0
- package/assets/styles/base/_variables.scss +1 -0
- package/assets/translations/en-us.yaml +31 -15
- package/assets/translations/zh-hans.yaml +4 -3
- package/chart/monitoring/index.vue +3 -1
- package/components/ActionDropdownShell.vue +71 -0
- package/components/AppModal.vue +18 -4
- package/components/CommunityLinks.vue +3 -58
- package/components/CruResource.vue +6 -1
- package/components/ExplorerProjectsNamespaces.vue +12 -4
- package/components/GlobalRoleBindings.vue +5 -1
- package/components/GrowlManager.vue +1 -0
- package/components/LandingPagePreference.vue +2 -0
- package/components/LocaleSelector.vue +1 -1
- package/components/ModalManager.vue +55 -0
- package/components/PromptModal.vue +47 -8
- 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 +54 -40
- package/components/SortableTable/paging.js +16 -19
- package/components/SortableTable/selection.js +0 -11
- package/components/Wizard.vue +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/login/ldap.vue +1 -1
- package/components/fleet/FleetResources.vue +21 -6
- package/components/form/ArrayList.vue +10 -6
- package/components/form/BannerSettings.vue +17 -2
- package/components/form/ColorInput.vue +35 -6
- package/components/form/EnvVars.vue +1 -0
- package/components/form/LabeledSelect.vue +18 -23
- package/components/form/MatchExpressions.vue +4 -1
- package/components/form/NameNsDescription.vue +5 -1
- package/components/form/NotificationSettings.vue +15 -1
- package/components/form/Password.vue +1 -0
- package/components/form/Probe.vue +1 -0
- package/components/form/SSHKnownHosts/__tests__/KnownHostsEditDialog.test.ts +15 -34
- package/components/form/SSHKnownHosts/index.vue +14 -11
- package/components/form/Select.vue +1 -15
- package/components/form/ValueFromResource.vue +12 -12
- package/components/form/__tests__/ArrayList.test.ts +2 -2
- package/components/form/__tests__/ColorInput.test.ts +35 -0
- package/components/form/__tests__/LabeledSelect.test.ts +40 -0
- package/components/form/__tests__/SSHKnownHosts.test.ts +11 -2
- package/components/nav/Group.vue +12 -4
- package/components/nav/Header.vue +16 -43
- package/components/nav/NamespaceFilter.vue +134 -86
- package/components/nav/TopLevelMenu.vue +4 -5
- package/components/nav/WindowManager/ContainerLogs.vue +87 -61
- package/components/nav/WindowManager/ContainerLogsActions.vue +76 -0
- package/components/templates/default.vue +6 -3
- package/components/templates/home.vue +6 -0
- package/components/templates/plain.vue +6 -3
- package/composables/focusTrap.ts +12 -4
- package/config/store.js +4 -0
- package/config/uiplugins.js +5 -1
- package/core/types.ts +7 -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 +0 -1
- package/{pages/c/_cluster/uiplugins/AddExtensionRepos.vue → dialog/AddExtensionReposDialog.vue} +72 -42
- package/dialog/AssignToDialog.vue +176 -0
- package/dialog/ChangePasswordDialog.vue +106 -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 +1 -1
- 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 -62
- 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/auth/azuread.vue +1 -1
- package/edit/auth/github.vue +1 -1
- package/edit/auth/googleoauth.vue +1 -1
- package/edit/auth/ldap/index.vue +1 -1
- package/edit/auth/oidc.vue +1 -1
- package/edit/auth/saml.vue +1 -1
- package/edit/cloudcredential.vue +24 -10
- package/edit/management.cattle.io.user.vue +28 -3
- package/edit/namespace.vue +1 -4
- package/edit/provisioning.cattle.io.cluster/CustomCommand.vue +4 -1
- package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +26 -10
- 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 +24 -7
- package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +5 -3
- package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +4 -1
- package/initialize/install-plugins.js +2 -1
- package/list/harvesterhci.io.management.cluster.vue +4 -1
- package/list/management.cattle.io.feature.vue +4 -288
- package/machine-config/azure.vue +16 -4
- package/mixins/vue-select-overrides.js +0 -4
- package/models/fleet.cattle.io.cluster.js +8 -2
- package/models/fleet.cattle.io.gitrepo.js +8 -34
- package/models/management.cattle.io.feature.js +7 -1
- package/models/namespace.js +7 -1
- package/package.json +1 -1
- package/pages/about.vue +13 -3
- package/pages/account/index.vue +12 -5
- package/pages/auth/login.vue +7 -4
- package/pages/auth/setup.vue +1 -0
- package/pages/auth/verify.vue +9 -7
- 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 +12 -9
- package/pages/fail-whale.vue +8 -5
- package/pages/prefs.vue +7 -6
- 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 +75 -35
- 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 +17 -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/index.ts +2 -0
- 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 -13
- package/scripts/typegen.sh +2 -4
- package/store/action-menu.js +26 -56
- package/store/index.js +5 -0
- package/store/modal.ts +71 -0
- package/store/slideInPanel.ts +47 -0
- package/store/type-map.js +8 -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 +35 -23
- 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/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/components/AssignTo.vue +0 -199
- package/components/DisableAuthProviderModal.vue +0 -115
- package/components/MoveModal.vue +0 -167
- package/components/PromptChangePassword.vue +0 -123
- package/components/fleet/FleetBundleResources.vue +0 -86
- package/types/vue-shim.d +0 -20
package/edit/auth/oidc.vue
CHANGED
package/edit/auth/saml.vue
CHANGED
package/edit/cloudcredential.vue
CHANGED
|
@@ -100,6 +100,30 @@ export default {
|
|
|
100
100
|
computed: {
|
|
101
101
|
rke2Enabled: mapFeature(RKE2_FEATURE),
|
|
102
102
|
|
|
103
|
+
hasCustomCloudCredentialComponent() {
|
|
104
|
+
const driverName = this.driverName;
|
|
105
|
+
|
|
106
|
+
return this.$store.getters['type-map/hasCustomCloudCredentialComponent'](driverName);
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
cloudCredentialComponent() {
|
|
110
|
+
const driverName = this.driverName;
|
|
111
|
+
|
|
112
|
+
return this.$store.getters['type-map/importCloudCredential'](driverName);
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
genericCloudCredentialComponent() {
|
|
116
|
+
return this.$store.getters['type-map/importCloudCredential']('generic');
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
cloudComponent() {
|
|
120
|
+
if (this.hasCustomCloudCredentialComponent) {
|
|
121
|
+
return this.cloudCredentialComponent;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return this.genericCloudCredentialComponent;
|
|
125
|
+
},
|
|
126
|
+
|
|
103
127
|
validationPassed() {
|
|
104
128
|
return this.credCustomComponentValidation && this.nameRequiredValidation;
|
|
105
129
|
},
|
|
@@ -112,14 +136,6 @@ export default {
|
|
|
112
136
|
return this.value?.provider;
|
|
113
137
|
},
|
|
114
138
|
|
|
115
|
-
cloudComponent() {
|
|
116
|
-
if (this.$store.getters['type-map/hasCustomCloudCredentialComponent'](this.driverName)) {
|
|
117
|
-
return this.$store.getters['type-map/importCloudCredential'](this.driverName);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
return this.$store.getters['type-map/importCloudCredential']('generic');
|
|
121
|
-
},
|
|
122
|
-
|
|
123
139
|
// array of id, label, description, initials for type selection step
|
|
124
140
|
secretSubTypes() {
|
|
125
141
|
const out = [];
|
|
@@ -194,7 +210,6 @@ export default {
|
|
|
194
210
|
},
|
|
195
211
|
|
|
196
212
|
methods: {
|
|
197
|
-
|
|
198
213
|
createValidationChanged(passed) {
|
|
199
214
|
this.credCustomComponentValidation = passed;
|
|
200
215
|
},
|
|
@@ -276,7 +291,6 @@ export default {
|
|
|
276
291
|
<Loading v-if="$fetchState.pending" />
|
|
277
292
|
<CruResource
|
|
278
293
|
v-else
|
|
279
|
-
:done-params="$attrs['done-params'] /* Without this, changes to the validationPassed prop end up propagating all the way to the root of the app and force a re-render when the input becomes valid. I haven't found a reasonable explanation for why this happens. */"
|
|
280
294
|
:mode="mode"
|
|
281
295
|
:validation-passed="validationPassed"
|
|
282
296
|
:selected-subtype="value._type"
|
|
@@ -15,6 +15,8 @@ export default {
|
|
|
15
15
|
ChangePassword, GlobalRoleBindings, CruResource, LabeledInput, Loading
|
|
16
16
|
},
|
|
17
17
|
|
|
18
|
+
emits: ['update:mode'],
|
|
19
|
+
|
|
18
20
|
mixins: [
|
|
19
21
|
CreateEditView
|
|
20
22
|
],
|
|
@@ -40,6 +42,7 @@ export default {
|
|
|
40
42
|
roles: !showGlobalRoles,
|
|
41
43
|
rolesChanged: false,
|
|
42
44
|
},
|
|
45
|
+
watchOverride: false,
|
|
43
46
|
};
|
|
44
47
|
},
|
|
45
48
|
|
|
@@ -115,7 +118,11 @@ export default {
|
|
|
115
118
|
this.$router.replace({ name: this.doneRoute });
|
|
116
119
|
buttonDone(true);
|
|
117
120
|
} catch (err) {
|
|
118
|
-
|
|
121
|
+
if (err?.message?.includes('errors due to escalation')) {
|
|
122
|
+
this.errors = [this.t('rbac.errors.escalation')];
|
|
123
|
+
} else {
|
|
124
|
+
this.errors = exceptionToErrorsArray(err);
|
|
125
|
+
}
|
|
119
126
|
buttonDone(false);
|
|
120
127
|
}
|
|
121
128
|
},
|
|
@@ -150,7 +157,7 @@ export default {
|
|
|
150
157
|
|
|
151
158
|
const normanUser = await this.$store.dispatch('rancher/find', {
|
|
152
159
|
type: NORMAN.USER,
|
|
153
|
-
id: this.value.id,
|
|
160
|
+
id: this.value.id || this.user?.id,
|
|
154
161
|
});
|
|
155
162
|
|
|
156
163
|
// Save change of password
|
|
@@ -181,8 +188,25 @@ export default {
|
|
|
181
188
|
},
|
|
182
189
|
|
|
183
190
|
async updateRoles(userId) {
|
|
184
|
-
if (this.$refs.grb) {
|
|
191
|
+
if (!this.$refs.grb) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
try {
|
|
185
196
|
await this.$refs.grb.save(userId);
|
|
197
|
+
} catch (err) {
|
|
198
|
+
if (this.isCreate) {
|
|
199
|
+
this.watchOverride = true;
|
|
200
|
+
this.$emit(
|
|
201
|
+
'update:mode',
|
|
202
|
+
{
|
|
203
|
+
userId,
|
|
204
|
+
mode: _EDIT,
|
|
205
|
+
resource: 'management.cattle.io.user',
|
|
206
|
+
}
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
throw err;
|
|
186
210
|
}
|
|
187
211
|
}
|
|
188
212
|
}
|
|
@@ -255,6 +279,7 @@ export default {
|
|
|
255
279
|
:user-id="value.id || liveValue.id"
|
|
256
280
|
:mode="mode"
|
|
257
281
|
:real-mode="realMode"
|
|
282
|
+
:watch-override="watchOverride"
|
|
258
283
|
type="user"
|
|
259
284
|
@hasChanges="validation.rolesChanged = $event"
|
|
260
285
|
@canLogIn="validation.roles = $event"
|
package/edit/namespace.vue
CHANGED
|
@@ -11,7 +11,6 @@ import Tab from '@shell/components/Tabbed/Tab';
|
|
|
11
11
|
import ResourceTabs from '@shell/components/form/ResourceTabs/index.vue';
|
|
12
12
|
import CruResource from '@shell/components/CruResource';
|
|
13
13
|
import { PROJECT_ID, _VIEW, FLAT_VIEW, _CREATE } from '@shell/config/query-params';
|
|
14
|
-
import MoveModal from '@shell/components/MoveModal';
|
|
15
14
|
import ResourceQuota from '@shell/components/form/ResourceQuota/Namespace';
|
|
16
15
|
import Loading from '@shell/components/Loading';
|
|
17
16
|
import { HARVESTER_TYPES, RANCHER_TYPES } from '@shell/components/form/ResourceQuota/shared';
|
|
@@ -31,8 +30,7 @@ export default {
|
|
|
31
30
|
PodSecurityAdmission,
|
|
32
31
|
ResourceQuota,
|
|
33
32
|
Tab,
|
|
34
|
-
ResourceTabs
|
|
35
|
-
MoveModal
|
|
33
|
+
ResourceTabs
|
|
36
34
|
},
|
|
37
35
|
|
|
38
36
|
mixins: [CreateEditView],
|
|
@@ -277,6 +275,5 @@ export default {
|
|
|
277
275
|
/>
|
|
278
276
|
</Tab>
|
|
279
277
|
</ResourceTabs>
|
|
280
|
-
<MoveModal v-if="projects" />
|
|
281
278
|
</CruResource>
|
|
282
279
|
</template>
|
|
@@ -260,7 +260,10 @@ export default {
|
|
|
260
260
|
/>
|
|
261
261
|
|
|
262
262
|
<template v-if="cluster.supportsWindows">
|
|
263
|
-
<hr
|
|
263
|
+
<hr
|
|
264
|
+
class="mt-20 mb-20"
|
|
265
|
+
role="none"
|
|
266
|
+
>
|
|
264
267
|
<h4 v-t="'cluster.custom.registrationCommand.windowsDetail'" />
|
|
265
268
|
<Banner
|
|
266
269
|
v-if="readyForWindows"
|
|
@@ -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);
|
|
@@ -236,7 +253,6 @@ export default {
|
|
|
236
253
|
<Loading v-if="$fetchState.pending" />
|
|
237
254
|
<CruResource
|
|
238
255
|
v-else
|
|
239
|
-
:done-params="$attrs['done-params'] /* Without this, changes to the validationPassed prop end up propagating all the way to the root of the app and force a re-render when the input becomes valid. I haven't found a reasonable explanation for why this happens. */"
|
|
240
256
|
:mode="mode"
|
|
241
257
|
:validation-passed="validationPassed"
|
|
242
258
|
:resource="newCredential"
|
|
@@ -267,7 +283,7 @@ export default {
|
|
|
267
283
|
/>
|
|
268
284
|
|
|
269
285
|
<component
|
|
270
|
-
:is="
|
|
286
|
+
:is="cloudComponent"
|
|
271
287
|
ref="create"
|
|
272
288
|
v-model:value="newCredential"
|
|
273
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,7 +22,7 @@ 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
28
|
import {
|
|
@@ -297,6 +297,21 @@ export default {
|
|
|
297
297
|
return this.value.spec.rkeConfig.chartValues;
|
|
298
298
|
},
|
|
299
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
|
+
|
|
300
315
|
serverConfig() {
|
|
301
316
|
return this.value.spec.rkeConfig.machineGlobalConfig;
|
|
302
317
|
},
|
|
@@ -576,7 +591,7 @@ export default {
|
|
|
576
591
|
out.tooltip[role] = this.t(`cluster.machinePool.nodeTotals.tooltip.${ role }`, { count: counts[role] });
|
|
577
592
|
}
|
|
578
593
|
|
|
579
|
-
if (counts.etcd
|
|
594
|
+
if (counts.etcd <= 0) {
|
|
580
595
|
out.color.etcd = NODE_TOTAL.error.color;
|
|
581
596
|
out.icon.etcd = NODE_TOTAL.error.icon;
|
|
582
597
|
} else if (counts.etcd === 1 || counts.etcd % 2 === 0 || counts.etcd > 7) {
|
|
@@ -584,7 +599,7 @@ export default {
|
|
|
584
599
|
out.icon.etcd = NODE_TOTAL.warning.icon;
|
|
585
600
|
}
|
|
586
601
|
|
|
587
|
-
if (counts.controlPlane
|
|
602
|
+
if (counts.controlPlane <= 0) {
|
|
588
603
|
out.color.controlPlane = NODE_TOTAL.error.color;
|
|
589
604
|
out.icon.controlPlane = NODE_TOTAL.error.icon;
|
|
590
605
|
} else if (counts.controlPlane === 1) {
|
|
@@ -592,7 +607,7 @@ export default {
|
|
|
592
607
|
out.icon.controlPlane = NODE_TOTAL.warning.icon;
|
|
593
608
|
}
|
|
594
609
|
|
|
595
|
-
if (counts.worker
|
|
610
|
+
if (counts.worker <= 0) {
|
|
596
611
|
out.color.worker = NODE_TOTAL.error.color;
|
|
597
612
|
out.icon.worker = NODE_TOTAL.error.icon;
|
|
598
613
|
} else if (counts.worker === 1) {
|
|
@@ -1305,7 +1320,7 @@ export default {
|
|
|
1305
1320
|
delete clonedCurrentConfig.metadata;
|
|
1306
1321
|
|
|
1307
1322
|
if (this.provider === VMWARE_VSPHERE) {
|
|
1308
|
-
machinePool.config =
|
|
1323
|
+
machinePool.config = mergeWithReplace(clonedLatestConfig, clonedCurrentConfig, { mutateOriginal: true });
|
|
1309
1324
|
} else {
|
|
1310
1325
|
machinePool.config = merge(clonedLatestConfig, clonedCurrentConfig);
|
|
1311
1326
|
}
|
|
@@ -1691,7 +1706,7 @@ export default {
|
|
|
1691
1706
|
const defaultChartValue = this.versionInfo[name];
|
|
1692
1707
|
const key = this.chartVersionKey(name);
|
|
1693
1708
|
|
|
1694
|
-
return
|
|
1709
|
+
return mergeWithReplace(defaultChartValue?.values, this.userChartValues[key]);
|
|
1695
1710
|
},
|
|
1696
1711
|
|
|
1697
1712
|
initServerAgentArgs() {
|
|
@@ -1850,7 +1865,9 @@ export default {
|
|
|
1850
1865
|
|
|
1851
1866
|
applyChartValues(rkeConfig) {
|
|
1852
1867
|
rkeConfig.chartValues = {};
|
|
1853
|
-
this.addonNames.
|
|
1868
|
+
const charts = [...this.addonNames, ...this.rke2Charts];
|
|
1869
|
+
|
|
1870
|
+
charts.forEach((name) => {
|
|
1854
1871
|
const key = this.chartVersionKey(name);
|
|
1855
1872
|
const userValues = this.userChartValues[key];
|
|
1856
1873
|
|
|
@@ -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
|
}
|
|
@@ -26,6 +26,7 @@ import replaceAll from '@shell/plugins/replaceall';
|
|
|
26
26
|
import steveCreateWorker from '@shell/plugins/steve-create-worker';
|
|
27
27
|
import emberCookie from '@shell/plugins/ember-cookie';
|
|
28
28
|
import ShortKey from '@shell/plugins/shortkey';
|
|
29
|
+
import internalApiPlugin from '@shell/plugins/internal-api';
|
|
29
30
|
|
|
30
31
|
import 'floating-vue/dist/style.css';
|
|
31
32
|
import { floatingVueOptions } from '@shell/plugins/floating-vue';
|
|
@@ -46,7 +47,7 @@ export async function installPlugins(vueApp) {
|
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
export async function installInjectedPlugins(app, vueApp) {
|
|
49
|
-
const pluginDefinitions = [config, cookieUniversal, axios, plugins, pluginsLoader, axiosShell, intNumber, codeMirror, nuxtClientInit, replaceAll, plugin, steveCreateWorker, emberCookie];
|
|
50
|
+
const pluginDefinitions = [config, cookieUniversal, axios, plugins, pluginsLoader, axiosShell, intNumber, codeMirror, nuxtClientInit, replaceAll, plugin, steveCreateWorker, emberCookie, internalApiPlugin];
|
|
50
51
|
|
|
51
52
|
const installations = pluginDefinitions.map(async(pluginDefinition) => {
|
|
52
53
|
if (typeof pluginDefinition === 'function') {
|
|
@@ -178,7 +178,10 @@ export default {
|
|
|
178
178
|
<div class="no-clusters">
|
|
179
179
|
{{ t('harvesterManager.cluster.none') }}
|
|
180
180
|
</div>
|
|
181
|
-
<hr
|
|
181
|
+
<hr
|
|
182
|
+
class="info-section"
|
|
183
|
+
role="none"
|
|
184
|
+
>
|
|
182
185
|
<div class="logo">
|
|
183
186
|
<BrandImage
|
|
184
187
|
file-name="harvester.png"
|