@rancher/shell 3.0.2-rc.5 → 3.0.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/nutanix.svg +12 -1
- package/assets/styles/base/_basic.scss +2 -1
- package/assets/styles/base/_helpers.scss +4 -0
- package/assets/styles/base/_variables.scss +2 -0
- package/assets/styles/global/_labeled-input.scss +5 -13
- package/assets/styles/global/_layout.scss +4 -1
- package/assets/styles/global/_select.scss +5 -0
- package/assets/styles/themes/_dark.scss +1 -3
- package/assets/styles/themes/_light.scss +5 -1
- package/assets/translations/en-us.yaml +130 -23
- package/assets/translations/zh-hans.yaml +0 -3
- package/cloud-credential/azure.vue +1 -1
- package/components/ActionMenuShell.vue +105 -0
- package/components/AppModal.vue +2 -2
- package/components/AsyncButton.vue +2 -0
- package/components/ButtonGroup.vue +9 -2
- package/components/ClusterBadge.vue +1 -0
- package/components/ClusterIconMenu.vue +3 -0
- package/components/ClusterProviderIcon.vue +14 -1
- package/components/CodeMirror.vue +96 -5
- package/components/Collapse.vue +16 -3
- package/components/CruResource.vue +9 -0
- package/components/CruResourceFooter.vue +1 -1
- package/components/ExplorerMembers.vue +2 -1
- package/components/FixedBanner.vue +19 -12
- package/components/Import.vue +14 -1
- package/components/LandingPagePreference.vue +4 -2
- package/components/PodSecurityAdmission.vue +8 -6
- package/components/PromptChangePassword.vue +1 -0
- package/components/PromptRemove.vue +23 -21
- package/components/ResourceDetail/Masthead.vue +30 -11
- package/components/ResourceDetail/__tests__/Masthead.test.ts +61 -0
- package/components/ResourceDetail/index.vue +6 -0
- package/components/ResourceTable.vue +6 -1
- package/components/ResourceYaml.vue +1 -0
- package/components/Setting.vue +115 -0
- package/components/SortableTable/THead.vue +2 -0
- package/components/SortableTable/index.vue +7 -12
- package/components/StatusBadge.vue +71 -0
- package/components/Tabbed/index.vue +16 -15
- package/components/Wizard.vue +108 -104
- package/components/YamlEditor.vue +12 -2
- package/components/__tests__/Collapse.test.ts +2 -2
- package/components/__tests__/FixedBanner.test.ts +3 -3
- package/components/auth/Principal.vue +29 -17
- package/components/auth/__tests__/Principal.test.ts +40 -0
- package/components/auth/login/ldap.vue +7 -0
- package/components/fleet/FleetBundles.vue +1 -1
- package/components/fleet/FleetRepos.vue +1 -1
- package/components/fleet/FleetResources.vue +0 -2
- package/components/fleet/FleetSummary.vue +60 -65
- package/components/fleet/ForceDirectedTreeChart/index.vue +5 -1
- package/components/fleet/__tests__/FleetSummary.test.ts +49 -9
- package/components/form/ArrayList.vue +6 -2
- package/components/form/ColorInput.vue +1 -0
- package/components/form/KeyValue.vue +11 -12
- package/components/form/LabeledSelect.vue +15 -3
- package/components/form/Labels.vue +8 -1
- package/components/form/Members/MembershipEditor.vue +230 -222
- package/components/form/Members/__tests__/MembershipEditor.test.ts +62 -0
- package/components/form/Password.vue +3 -0
- package/components/form/ProjectMemberEditor.vue +6 -3
- package/components/form/ResourceTabs/index.vue +15 -13
- package/components/form/SSHKnownHosts/KnownHostsEditDialog.vue +5 -4
- package/components/form/SchedulingCustomization.vue +85 -0
- package/components/form/Select.vue +3 -2
- package/components/form/SelectOrCreateAuthSecret.vue +2 -1
- package/components/form/UnitInput.vue +3 -4
- package/components/form/__tests__/ArrayList.test.ts +9 -6
- package/components/form/__tests__/LabeledSelect.test.ts +37 -0
- package/components/form/__tests__/SelectOrCreateAuthSecret.test.ts +34 -0
- package/components/form/__tests__/UnitInput.test.ts +4 -5
- package/components/formatter/LiveDate.vue +3 -1
- package/components/formatter/ServiceType.vue +12 -4
- package/components/formatter/WorkloadHealthScale.vue +2 -1
- package/components/nav/Header.vue +35 -2
- package/components/nav/HeaderPageActionMenu.vue +11 -40
- package/components/nav/Jump.vue +8 -2
- package/components/nav/NamespaceFilter.vue +5 -4
- package/components/nav/Pinned.vue +1 -1
- package/components/nav/TopLevelMenu.helper.ts +5 -5
- package/components/nav/TopLevelMenu.vue +1 -12
- package/components/nav/WindowManager/ContainerLogs.vue +96 -58
- package/components/nav/WindowManager/ContainerShell.vue +99 -18
- package/components/nav/WindowManager/index.vue +74 -6
- package/components/nav/__tests__/TopLevelMenu.test.ts +0 -40
- package/components/templates/default.vue +2 -47
- package/config/features.js +1 -0
- package/config/labels-annotations.js +11 -1
- package/config/router/navigation-guards/index.js +2 -1
- package/config/router/navigation-guards/record-last-route.js +24 -0
- package/config/settings.ts +66 -98
- package/config/version.js +1 -1
- package/core/types-provisioning.ts +7 -0
- package/detail/fleet.cattle.io.bundle.vue +7 -0
- package/detail/fleet.cattle.io.cluster.vue +0 -3
- package/detail/fleet.cattle.io.gitrepo.vue +8 -15
- package/detail/provisioning.cattle.io.cluster.vue +8 -2
- package/dialog/DeactivateDriverDialog.vue +5 -5
- package/dialog/GitRepoForceUpdateDialog.vue +132 -0
- package/directives/strip-html-aria-label.js +19 -0
- package/edit/__tests__/cis.cattle.io.clusterscan.test.ts +87 -0
- package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +217 -37
- package/edit/auth/__tests__/oidc.test.ts +60 -12
- package/edit/auth/ldap/__tests__/config.test.ts +40 -0
- package/edit/auth/ldap/config.vue +67 -89
- package/edit/auth/oidc.vue +16 -2
- package/edit/catalog.cattle.io.clusterrepo.vue +12 -8
- package/edit/cis.cattle.io.clusterscan.vue +13 -1
- package/edit/fleet.cattle.io.gitrepo.vue +198 -72
- package/edit/logging-flow/Match.vue +0 -21
- package/edit/management.cattle.io.project.vue +1 -1
- package/edit/monitoring.coreos.com.prometheusrule/AlertingRule.vue +10 -3
- package/edit/monitoring.coreos.com.prometheusrule/RecordingRule.vue +5 -1
- package/edit/monitoring.coreos.com.prometheusrule/index.vue +5 -2
- package/edit/provisioning.cattle.io.cluster/CustomCommand.vue +8 -1
- package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +2 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/Advanced.test.ts +0 -2
- package/edit/provisioning.cattle.io.cluster/__tests__/CustomCommand.test.ts +55 -15
- package/edit/provisioning.cattle.io.cluster/index.vue +28 -30
- package/edit/provisioning.cattle.io.cluster/rke2.vue +64 -13
- package/edit/provisioning.cattle.io.cluster/tabs/AgentConfiguration.vue +37 -2
- package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +3 -2
- package/edit/resources.cattle.io.backup.vue +150 -15
- package/edit/secret/__tests__/ssh.test.ts +79 -0
- package/edit/secret/ssh.vue +7 -1
- package/edit/service.vue +0 -3
- package/edit/workload/Job.vue +8 -8
- package/edit/workload/__tests__/Job.test.ts +0 -1
- package/edit/workload/index.vue +3 -1
- package/initialize/install-directives.js +2 -0
- package/initialize/install-plugins.js +6 -1
- package/list/catalog.cattle.io.app.vue +21 -4
- package/list/fleet.cattle.io.bundle.vue +1 -1
- package/list/management.cattle.io.setting.vue +34 -132
- package/list/provisioning.cattle.io.cluster.vue +11 -3
- package/machine-config/vmwarevsphere.vue +15 -8
- package/mixins/__tests__/auth-config.test.ts +74 -0
- package/mixins/__tests__/chart.test.ts +5 -4
- package/mixins/__tests__/create-edit-view.test.ts +38 -0
- package/mixins/auth-config.js +8 -0
- package/mixins/chart.js +2 -2
- package/mixins/create-edit-view/impl.js +4 -1
- package/mixins/vue-select-overrides.js +10 -0
- package/models/__tests__/catalog.cattle.io.app.test.ts +148 -0
- package/models/__tests__/fleet.cattle.io.gitrepo.test.ts +157 -0
- package/models/__tests__/secret.test.ts +56 -13
- package/models/catalog.cattle.io.app.js +112 -37
- package/models/cluster.js +11 -0
- package/models/fleet.cattle.io.bundle.js +40 -2
- package/models/fleet.cattle.io.gitrepo.js +169 -109
- package/models/management.cattle.io.fleetworkspace.js +4 -0
- package/models/management.cattle.io.kontainerdriver.js +7 -0
- package/models/nodedriver.js +4 -1
- package/models/provisioning.cattle.io.cluster.js +24 -0
- package/models/secret.js +1 -1
- package/package.json +5 -5
- package/pages/auth/login.vue +5 -11
- package/pages/auth/verify.vue +11 -1
- package/pages/c/_cluster/apps/charts/index.vue +6 -4
- package/pages/c/_cluster/apps/charts/install.vue +1 -1
- package/pages/c/_cluster/explorer/ConfigBadge.vue +3 -5
- package/pages/c/_cluster/explorer/EventsTable.vue +3 -2
- package/pages/c/_cluster/explorer/__tests__/index.test.ts +9 -9
- package/pages/c/_cluster/explorer/index.vue +33 -35
- package/pages/c/_cluster/explorer/tools/index.vue +3 -3
- package/pages/c/_cluster/fleet/index.vue +0 -5
- package/pages/c/_cluster/legacy/project/index.vue +1 -1
- package/pages/c/_cluster/settings/performance.vue +52 -53
- package/pages/c/_cluster/uiplugins/index.vue +19 -22
- package/pages/home.vue +17 -12
- package/pages/prefs.vue +5 -1
- package/plugins/shortkey.js +10 -1
- package/plugins/steve/steve-pagination-utils.ts +58 -8
- package/promptRemove/management.cattle.io.fleetworkspace.vue +98 -0
- package/promptRemove/management.cattle.io.globalrole.vue +1 -1
- package/promptRemove/management.cattle.io.project.vue +2 -8
- package/promptRemove/management.cattle.io.roletemplate.vue +1 -1
- package/promptRemove/mixin/roleDeletionCheck.js +1 -7
- package/promptRemove/pod.vue +7 -28
- package/rancher-components/Card/Card.vue +9 -1
- package/rancher-components/Form/Checkbox/Checkbox.vue +42 -6
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +30 -3
- package/rancher-components/Form/Radio/RadioButton.vue +18 -3
- package/rancher-components/Form/Radio/RadioGroup.vue +39 -5
- package/rancher-components/LabeledTooltip/LabeledTooltip.vue +13 -1
- package/rancher-components/RcButton/RcButton.test.ts +97 -0
- package/rancher-components/RcButton/RcButton.vue +14 -9
- package/rancher-components/RcDropdown/RcDropdown.vue +3 -1
- package/rancher-components/RcDropdown/RcDropdownItem.vue +8 -2
- package/rancher-components/RcDropdown/RcDropdownMenu.vue +66 -0
- package/rancher-components/RcDropdown/index.ts +1 -0
- package/rancher-components/RcDropdown/types.ts +27 -0
- package/rancher-components/RcDropdown/useDropdownContext.ts +5 -2
- package/scripts/extension/helm/charts/ui-plugin-server/templates/_helpers.tpl +2 -2
- package/scripts/typegen.sh +1 -0
- package/store/__tests__/auth.test.ts +120 -0
- package/store/action-menu.js +13 -3
- package/store/auth.js +14 -9
- package/store/aws.js +9 -2
- package/store/catalog.js +14 -7
- package/store/features.js +1 -0
- package/store/prefs.js +9 -28
- package/store/type-map.utils.ts +4 -0
- package/types/resources/settings.d.ts +27 -20
- package/types/shell/index.d.ts +18 -12
- package/utils/__tests__/array.test.ts +13 -1
- package/utils/__tests__/string.test.ts +80 -1
- package/utils/array.ts +13 -0
- package/utils/auth.js +4 -0
- package/utils/banners.js +0 -45
- package/utils/cluster.js +1 -1
- package/{edit/monitoring.coreos.com.prometheusrule → utils}/duration.js +5 -3
- package/utils/object.js +0 -3
- package/utils/pagination-utils.ts +15 -2
- package/utils/string.js +31 -7
- package/utils/validators/formRules/__tests__/index.test.ts +27 -0
- package/utils/validators/formRules/index.ts +16 -0
- package/edit/provisioning.cattle.io.cluster/import.vue +0 -198
|
@@ -11,7 +11,7 @@ import NameNsDescription from '@shell/components/form/NameNsDescription';
|
|
|
11
11
|
import Loading from '@shell/components/Loading';
|
|
12
12
|
import S3 from '@shell/chart/rancher-backup/S3';
|
|
13
13
|
import { mapGetters } from 'vuex';
|
|
14
|
-
import { SECRET, BACKUP_RESTORE, CATALOG } from '@shell/config/types';
|
|
14
|
+
import { SECRET, BACKUP_RESTORE, CATALOG, COUNT } from '@shell/config/types';
|
|
15
15
|
import { allHash } from '@shell/utils/promise';
|
|
16
16
|
import { NAMESPACE, _VIEW, _CREATE } from '@shell/config/query-params';
|
|
17
17
|
import { sortBy } from '@shell/utils/sort';
|
|
@@ -20,6 +20,10 @@ import { formatEncryptionSecretNames } from '@shell/utils/formatter';
|
|
|
20
20
|
import { FilterArgs, PaginationParamFilter } from '@shell/types/store/pagination.types';
|
|
21
21
|
import { SECRET_TYPES } from '@shell/config/secret';
|
|
22
22
|
|
|
23
|
+
const DEFAULT_RANCHER_BACKUP_RESOURCE_SET_ID = 'rancher-resource-set-basic';
|
|
24
|
+
const FULL_RANCHER_BACKUP_RESOURCE_SET_ID = 'rancher-resource-set-full';
|
|
25
|
+
const CUSTOM_RESOURCE_SET_ID = 'custom';
|
|
26
|
+
|
|
23
27
|
export default {
|
|
24
28
|
|
|
25
29
|
components: {
|
|
@@ -50,18 +54,38 @@ export default {
|
|
|
50
54
|
|
|
51
55
|
async fetch() {
|
|
52
56
|
const hash = await allHash({
|
|
53
|
-
catalog:
|
|
54
|
-
|
|
55
|
-
apps:
|
|
57
|
+
catalog: this.$store.dispatch('catalog/load'),
|
|
58
|
+
allResourceSets: this.$store.dispatch('cluster/findAll', { type: BACKUP_RESTORE.RESOURCE_SET }),
|
|
59
|
+
apps: this.$store.dispatch('cluster/findAll', { type: CATALOG.APP })
|
|
56
60
|
});
|
|
57
61
|
|
|
58
62
|
this.apps = hash.apps;
|
|
59
|
-
this.
|
|
63
|
+
this.allResourceSets = hash.allResourceSets;
|
|
60
64
|
|
|
61
65
|
const BRORelease = this.apps.filter((release) => get(release, 'spec.name') === 'rancher-backup')[0];
|
|
62
66
|
|
|
63
67
|
this.chartNamespace = BRORelease?.spec.namespace || '';
|
|
64
68
|
|
|
69
|
+
if (!this.value.spec.resourceSetName) {
|
|
70
|
+
this.value.spec.resourceSetName = this.defaultExistingResourceSetOptionIds[0] || this.allResourceSets[0].id;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const computeResourceSetSelection = () => {
|
|
74
|
+
if (!this.value?.spec?.resourceSetName) {
|
|
75
|
+
const defaults = this.defaultExistingResourceSetOptionIds;
|
|
76
|
+
|
|
77
|
+
if (defaults.length > 0) {
|
|
78
|
+
return defaults[0];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return this.allResourceSets[0].id;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return this.defaultResourceSetOptionIds.includes(this.value?.spec?.resourceSetName) ? this.value?.spec?.resourceSetName : CUSTOM_RESOURCE_SET_ID;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
this.resourceSetSelection = computeResourceSetSelection();
|
|
88
|
+
|
|
65
89
|
if (this.$store.getters[`cluster/paginationEnabled`](SECRET)) {
|
|
66
90
|
const findPageArgs = { // Of type ActionFindPageArgs
|
|
67
91
|
namespaced: this.chartNamespace,
|
|
@@ -105,17 +129,25 @@ export default {
|
|
|
105
129
|
s3 = this.value.spec.storageLocation.s3;
|
|
106
130
|
}
|
|
107
131
|
|
|
132
|
+
const counts = this.$store.getters[`cluster/all`](COUNT);
|
|
133
|
+
const defaultResourceSetOptionIds = [DEFAULT_RANCHER_BACKUP_RESOURCE_SET_ID, FULL_RANCHER_BACKUP_RESOURCE_SET_ID];
|
|
134
|
+
|
|
108
135
|
return {
|
|
109
|
-
secrets:
|
|
110
|
-
|
|
136
|
+
secrets: [],
|
|
137
|
+
resourceSetCounts: counts?.[0]?.counts?.[BACKUP_RESTORE.RESOURCE_SET]?.summary?.count,
|
|
138
|
+
defaultResourceSetOptionIds,
|
|
139
|
+
allResourceSets: [],
|
|
140
|
+
resourceSetSelection: null,
|
|
111
141
|
s3,
|
|
112
142
|
storageSource,
|
|
113
143
|
useEncryption,
|
|
114
|
-
apps:
|
|
144
|
+
apps: [],
|
|
115
145
|
setSchedule,
|
|
116
|
-
name:
|
|
117
|
-
fvFormRuleSets:
|
|
118
|
-
path:
|
|
146
|
+
name: this.value?.metadata?.name,
|
|
147
|
+
fvFormRuleSets: [{
|
|
148
|
+
path: 'metadata.name',
|
|
149
|
+
rules: ['dnsLabel', 'noUpperCase'],
|
|
150
|
+
translationKey: 'nameNsDescription.name.label'
|
|
119
151
|
}],
|
|
120
152
|
chartNamespace: null,
|
|
121
153
|
};
|
|
@@ -144,6 +176,48 @@ export default {
|
|
|
144
176
|
return { options, labels };
|
|
145
177
|
},
|
|
146
178
|
|
|
179
|
+
defaultExistingResourceSetOptionIds() {
|
|
180
|
+
return this.defaultResourceSetOptionIds.filter((id) => {
|
|
181
|
+
return this.allResourceSetIds.includes(id);
|
|
182
|
+
});
|
|
183
|
+
},
|
|
184
|
+
|
|
185
|
+
resourceSetOptions() {
|
|
186
|
+
const optionIds = [...this.defaultExistingResourceSetOptionIds];
|
|
187
|
+
const addCustom = !optionIds.includes(this.value.spec?.resourceSetName) || this.allResourceSetIds.length > optionIds.length;
|
|
188
|
+
|
|
189
|
+
if (addCustom) {
|
|
190
|
+
optionIds.push(CUSTOM_RESOURCE_SET_ID);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return optionIds.map((id) => {
|
|
194
|
+
return {
|
|
195
|
+
label: this.t(`backupRestoreOperator.backup.resourceSetOptions.${ id }`),
|
|
196
|
+
value: id
|
|
197
|
+
};
|
|
198
|
+
});
|
|
199
|
+
},
|
|
200
|
+
|
|
201
|
+
allResourceSetIds() {
|
|
202
|
+
return this.allResourceSets.map((rs) => rs.id);
|
|
203
|
+
},
|
|
204
|
+
|
|
205
|
+
customResourceSetOptions() {
|
|
206
|
+
return this.allResourceSetIds.filter((id) => !this.defaultResourceSetOptionIds.includes(id));
|
|
207
|
+
},
|
|
208
|
+
|
|
209
|
+
showCustomResourceSetOptions() {
|
|
210
|
+
return this.resourceSetSelection === CUSTOM_RESOURCE_SET_ID;
|
|
211
|
+
},
|
|
212
|
+
|
|
213
|
+
showEncryptionWarningBanner() {
|
|
214
|
+
return this.resourceSetSelection === 'rancher-resource-set-full';
|
|
215
|
+
},
|
|
216
|
+
|
|
217
|
+
showMissingResourceSetWarningBanner() {
|
|
218
|
+
return !this.allResourceSetIds.includes(this.value.spec.resourceSetName);
|
|
219
|
+
},
|
|
220
|
+
|
|
147
221
|
namespaces() {
|
|
148
222
|
const choices = this.$store.getters['cluster/all'](NAMESPACE);
|
|
149
223
|
const out = sortBy(choices.map((obj) => {
|
|
@@ -172,9 +246,16 @@ export default {
|
|
|
172
246
|
}
|
|
173
247
|
},
|
|
174
248
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
249
|
+
resourceSetSelection(neu, old) {
|
|
250
|
+
// We don't want to handle this when this gets triggered in fetch
|
|
251
|
+
if (!old) {
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if (neu === CUSTOM_RESOURCE_SET_ID) {
|
|
256
|
+
this.value.spec.resourceSetName = this.customResourceSetOptions[0];
|
|
257
|
+
} else {
|
|
258
|
+
this.value.spec.resourceSetName = neu;
|
|
178
259
|
}
|
|
179
260
|
},
|
|
180
261
|
|
|
@@ -212,7 +293,7 @@ export default {
|
|
|
212
293
|
:rules="{name: fvGetAndReportPathRules('metadata.name')}"
|
|
213
294
|
@change="name=value.metadata.name"
|
|
214
295
|
/>
|
|
215
|
-
<template v-if="
|
|
296
|
+
<template v-if="resourceSetCounts > 0">
|
|
216
297
|
<div class="bordered-section">
|
|
217
298
|
<RadioGroup
|
|
218
299
|
v-model:value="setSchedule"
|
|
@@ -245,6 +326,60 @@ export default {
|
|
|
245
326
|
</div>
|
|
246
327
|
</div>
|
|
247
328
|
</div>
|
|
329
|
+
<div class="bordered-section">
|
|
330
|
+
<div class="row mb-10">
|
|
331
|
+
<div class="col span-12">
|
|
332
|
+
<h3>{{ t('backupRestoreOperator.backup.label') }}</h3>
|
|
333
|
+
<div>{{ t('backupRestoreOperator.backup.description') }}</div>
|
|
334
|
+
</div>
|
|
335
|
+
</div>
|
|
336
|
+
<div class="row">
|
|
337
|
+
<div class="col span-12">
|
|
338
|
+
<RadioGroup
|
|
339
|
+
v-model:value="resourceSetSelection"
|
|
340
|
+
name="resourceSet"
|
|
341
|
+
:options="resourceSetOptions"
|
|
342
|
+
:mode="mode"
|
|
343
|
+
/>
|
|
344
|
+
</div>
|
|
345
|
+
</div>
|
|
346
|
+
<div
|
|
347
|
+
v-if="showCustomResourceSetOptions"
|
|
348
|
+
class="row mt-10"
|
|
349
|
+
>
|
|
350
|
+
<div class="col span-6">
|
|
351
|
+
<LabeledSelect
|
|
352
|
+
v-model:value="value.spec.resourceSetName"
|
|
353
|
+
:mode="mode"
|
|
354
|
+
:options="customResourceSetOptions"
|
|
355
|
+
:label="t('backupRestoreOperator.backup.resourceSetOptions.customResourceSetLabel')"
|
|
356
|
+
/>
|
|
357
|
+
</div>
|
|
358
|
+
</div>
|
|
359
|
+
<div
|
|
360
|
+
v-if="showEncryptionWarningBanner"
|
|
361
|
+
class="row mt-10"
|
|
362
|
+
>
|
|
363
|
+
<div class="col span-12">
|
|
364
|
+
<Banner
|
|
365
|
+
color="warning"
|
|
366
|
+
role="alert"
|
|
367
|
+
>
|
|
368
|
+
<span v-clean-html="t('backupRestoreOperator.backup.enableEncryptionWarning')" />
|
|
369
|
+
</Banner>
|
|
370
|
+
</div>
|
|
371
|
+
</div>
|
|
372
|
+
<div
|
|
373
|
+
v-if="showMissingResourceSetWarningBanner"
|
|
374
|
+
class="row mt-10"
|
|
375
|
+
>
|
|
376
|
+
<div class="col span-12">
|
|
377
|
+
<Banner color="warning">
|
|
378
|
+
<span v-clean-html="t('backupRestoreOperator.backup.missingResourceSetWarning', {resourceSet: value.spec.resourceSetName})" />
|
|
379
|
+
</Banner>
|
|
380
|
+
</div>
|
|
381
|
+
</div>
|
|
382
|
+
</div>
|
|
248
383
|
|
|
249
384
|
<div class="bordered-section">
|
|
250
385
|
<div class="row">
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils';
|
|
2
|
+
import { _VIEW, _EDIT, _CREATE } from '@shell/config/query-params';
|
|
3
|
+
import Ssh from '@shell/edit/secret/ssh.vue';
|
|
4
|
+
|
|
5
|
+
const mockedStore = () => {
|
|
6
|
+
return { getters: { 'i18n/t': jest.fn() } };
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const mockedRoute = { query: {} };
|
|
10
|
+
|
|
11
|
+
const requiredSetup = () => {
|
|
12
|
+
return {
|
|
13
|
+
global: {
|
|
14
|
+
mocks: {
|
|
15
|
+
$store: mockedStore(),
|
|
16
|
+
$route: mockedRoute,
|
|
17
|
+
$fetchState: {},
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const decodedData = {
|
|
24
|
+
known_hosts: 'S05PV05fSE9TVFM=',
|
|
25
|
+
'ssh-privatekey': 'dGVzdDE=',
|
|
26
|
+
'ssh-publickey': 'dGVzdDE='
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
describe.each([
|
|
30
|
+
_CREATE,
|
|
31
|
+
_EDIT,
|
|
32
|
+
_VIEW
|
|
33
|
+
])('component: Ssh.vue', (mode) => {
|
|
34
|
+
it(`mode: ${ mode }, should show input fields`, () => {
|
|
35
|
+
const wrapper = mount(Ssh, {
|
|
36
|
+
...requiredSetup(),
|
|
37
|
+
props: {
|
|
38
|
+
value: {
|
|
39
|
+
name: 'foo',
|
|
40
|
+
decodedData,
|
|
41
|
+
supportsSshKnownHosts: true
|
|
42
|
+
},
|
|
43
|
+
mode,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const publicKey = wrapper.find('[data-testid="ssh-public-key"]').element as HTMLInputElement;
|
|
48
|
+
const privateKey = wrapper.find('[data-testid="ssh-private-key"]').element as HTMLInputElement;
|
|
49
|
+
const knownHosts = wrapper.find('[data-testid="ssh-known-hosts"]').element as HTMLInputElement;
|
|
50
|
+
|
|
51
|
+
expect(publicKey.value).toBe('dGVzdDE=');
|
|
52
|
+
expect(privateKey.value).toBe('dGVzdDE=');
|
|
53
|
+
expect(knownHosts.value).toBe('S05PV05fSE9TVFM=');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it.each([
|
|
57
|
+
['show', true],
|
|
58
|
+
['hide', false],
|
|
59
|
+
])(`mode: ${ mode }, should %p known_hosts`, (
|
|
60
|
+
_,
|
|
61
|
+
supportsSshKnownHosts,
|
|
62
|
+
) => {
|
|
63
|
+
const wrapper = mount(Ssh, {
|
|
64
|
+
...requiredSetup(),
|
|
65
|
+
props: {
|
|
66
|
+
value: {
|
|
67
|
+
name: 'foo',
|
|
68
|
+
decodedData,
|
|
69
|
+
supportsSshKnownHosts
|
|
70
|
+
},
|
|
71
|
+
mode: _EDIT,
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const knownHosts = wrapper.find('[data-testid="ssh-known-hosts"]');
|
|
76
|
+
|
|
77
|
+
expect(knownHosts.exists()).toBe(supportsSshKnownHosts);
|
|
78
|
+
});
|
|
79
|
+
});
|
package/edit/secret/ssh.vue
CHANGED
|
@@ -44,7 +44,10 @@ export default {
|
|
|
44
44
|
update() {
|
|
45
45
|
this.value.setData('ssh-publickey', this.username);
|
|
46
46
|
this.value.setData('ssh-privatekey', this.password);
|
|
47
|
-
|
|
47
|
+
|
|
48
|
+
if (this.showKnownHosts) {
|
|
49
|
+
this.value.setData('known_hosts', this.knownHosts);
|
|
50
|
+
}
|
|
48
51
|
}
|
|
49
52
|
}
|
|
50
53
|
};
|
|
@@ -57,6 +60,7 @@ export default {
|
|
|
57
60
|
<LabeledInput
|
|
58
61
|
v-model:value="username"
|
|
59
62
|
type="multiline"
|
|
63
|
+
data-testid="ssh-public-key"
|
|
60
64
|
:label="t('secret.ssh.public')"
|
|
61
65
|
:mode="mode"
|
|
62
66
|
required
|
|
@@ -72,6 +76,7 @@ export default {
|
|
|
72
76
|
<LabeledInput
|
|
73
77
|
v-model:value="password"
|
|
74
78
|
type="multiline"
|
|
79
|
+
data-testid="ssh-private-key"
|
|
75
80
|
:label="t('secret.ssh.private')"
|
|
76
81
|
:mode="mode"
|
|
77
82
|
required
|
|
@@ -90,6 +95,7 @@ export default {
|
|
|
90
95
|
v-if="showKnownHosts"
|
|
91
96
|
v-model:value="knownHosts"
|
|
92
97
|
type="multiline"
|
|
98
|
+
data-testid="ssh-known-hosts"
|
|
93
99
|
:label="t('secret.ssh.knownHosts')"
|
|
94
100
|
:mode="mode"
|
|
95
101
|
:placeholder="t('secret.ssh.knownHostsPlaceholder')"
|
package/edit/service.vue
CHANGED
|
@@ -521,9 +521,6 @@ export default {
|
|
|
521
521
|
"
|
|
522
522
|
:label="t('servicesPage.affinity.timeout.label')"
|
|
523
523
|
:placeholder="t('servicesPage.affinity.timeout.placeholder')"
|
|
524
|
-
@input="
|
|
525
|
-
(e) => value.spec.sessionAffinityConfig.clientIP.timeoutSeconds = e
|
|
526
|
-
"
|
|
527
524
|
/>
|
|
528
525
|
</div>
|
|
529
526
|
</div>
|
package/edit/workload/Job.vue
CHANGED
|
@@ -161,7 +161,7 @@ export default {
|
|
|
161
161
|
:suffix="t('suffix.times', {count: completions})"
|
|
162
162
|
label-key="workload.job.completions.label"
|
|
163
163
|
tooltip-key="workload.job.completions.tip"
|
|
164
|
-
@
|
|
164
|
+
@update:value="update"
|
|
165
165
|
/>
|
|
166
166
|
</div>
|
|
167
167
|
<div
|
|
@@ -174,7 +174,7 @@ export default {
|
|
|
174
174
|
:suffix="t('suffix.times', {count: parallelism})"
|
|
175
175
|
label-key="workload.job.parallelism.label"
|
|
176
176
|
tooltip-key="workload.job.parallelism.tip"
|
|
177
|
-
@
|
|
177
|
+
@update:value="update"
|
|
178
178
|
/>
|
|
179
179
|
</div>
|
|
180
180
|
</div>
|
|
@@ -189,7 +189,7 @@ export default {
|
|
|
189
189
|
:suffix="t('suffix.times', {count: backoffLimit})"
|
|
190
190
|
label-key="workload.job.backoffLimit.label"
|
|
191
191
|
tooltip-key="workload.job.backoffLimit.tip"
|
|
192
|
-
@
|
|
192
|
+
@update:value="update"
|
|
193
193
|
/>
|
|
194
194
|
</div>
|
|
195
195
|
<div
|
|
@@ -202,7 +202,7 @@ export default {
|
|
|
202
202
|
:suffix="t('suffix.seconds', {count: activeDeadlineSeconds})"
|
|
203
203
|
label-key="workload.job.activeDeadlineSeconds.label"
|
|
204
204
|
tooltip-key="workload.job.activeDeadlineSeconds.tip"
|
|
205
|
-
@
|
|
205
|
+
@update:value="update"
|
|
206
206
|
/>
|
|
207
207
|
</div>
|
|
208
208
|
</div>
|
|
@@ -245,7 +245,7 @@ export default {
|
|
|
245
245
|
:suffix="t('suffix.seconds', {count: startingDeadlineSeconds})"
|
|
246
246
|
label-key="workload.job.startingDeadlineSeconds.label"
|
|
247
247
|
tooltip-key="workload.job.startingDeadlineSeconds.tip"
|
|
248
|
-
@
|
|
248
|
+
@update:value="update"
|
|
249
249
|
/>
|
|
250
250
|
</div>
|
|
251
251
|
<div
|
|
@@ -254,10 +254,10 @@ export default {
|
|
|
254
254
|
>
|
|
255
255
|
<UnitInput
|
|
256
256
|
v-model:value="terminationGracePeriodSeconds"
|
|
257
|
-
:suffix="
|
|
257
|
+
:suffix="t('suffix.seconds', { count: terminationGracePeriodSeconds })"
|
|
258
258
|
:label="t('workload.upgrading.activeDeadlineSeconds.label')"
|
|
259
259
|
:mode="mode"
|
|
260
|
-
@
|
|
260
|
+
@update:value="update"
|
|
261
261
|
>
|
|
262
262
|
<template #label>
|
|
263
263
|
<label
|
|
@@ -316,7 +316,7 @@ export default {
|
|
|
316
316
|
>
|
|
317
317
|
<UnitInput
|
|
318
318
|
v-model:value="terminationGracePeriodSeconds"
|
|
319
|
-
:suffix="
|
|
319
|
+
:suffix="t('suffix.seconds', { count: terminationGracePeriodSeconds })"
|
|
320
320
|
:label="t('workload.upgrading.activeDeadlineSeconds.label')"
|
|
321
321
|
:mode="mode"
|
|
322
322
|
>
|
package/edit/workload/index.vue
CHANGED
|
@@ -262,8 +262,10 @@ export default {
|
|
|
262
262
|
<h3>
|
|
263
263
|
{{ t('workload.container.ports.expose') }}
|
|
264
264
|
<i
|
|
265
|
-
v-clean-tooltip="t('workload.container.ports.toolTip')"
|
|
265
|
+
v-clean-tooltip="{content: t('workload.container.ports.toolTip'), triggers: ['hover', 'touch', 'focus'] }"
|
|
266
|
+
v-stripped-aria-label="t('workload.container.ports.toolTip')"
|
|
266
267
|
class="icon icon-info"
|
|
268
|
+
tabindex="0"
|
|
267
269
|
/>
|
|
268
270
|
</h3>
|
|
269
271
|
<p class="padded">
|
|
@@ -10,6 +10,7 @@ import cleanTooltipDirective from '@shell/directives/clean-tooltip';
|
|
|
10
10
|
import positiveIntNumberDirective from '@shell/directives/positive-int-number.js';
|
|
11
11
|
import trimWhitespaceDirective from '@shell/directives/trim-whitespace';
|
|
12
12
|
import intNumberDirective from '@shell/directives/int-number';
|
|
13
|
+
import htmlStrippedAriaLabelDirective from '@shell/directives/strip-html-aria-label';
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Prevent extensions from overriding existing directives
|
|
@@ -47,6 +48,7 @@ function addDirectives(vueApp) {
|
|
|
47
48
|
vueApp.directive('focus', focusDirective);
|
|
48
49
|
vueApp.directive('intNumber', intNumberDirective);
|
|
49
50
|
vueApp.directive('positiveIntNumber', positiveIntNumberDirective);
|
|
51
|
+
vueApp.directive('stripped-aria-label', htmlStrippedAriaLabelDirective);
|
|
50
52
|
}
|
|
51
53
|
|
|
52
54
|
/**
|
|
@@ -35,7 +35,12 @@ export async function installPlugins(vueApp) {
|
|
|
35
35
|
vueApp.use(PortalVue);
|
|
36
36
|
vueApp.use(Vue3Resize);
|
|
37
37
|
vueApp.use(FloatingVue, floatingVueOptions);
|
|
38
|
-
vueApp.use(
|
|
38
|
+
vueApp.use(
|
|
39
|
+
ShortKey,
|
|
40
|
+
{
|
|
41
|
+
prevent: ['input', 'textarea', 'select'],
|
|
42
|
+
preventContainer: ['#modal-container-element']
|
|
43
|
+
});
|
|
39
44
|
vueApp.use(InstallCodeMirror);
|
|
40
45
|
vueApp.component('v-select', vSelect);
|
|
41
46
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import PaginatedResourceTable from '@shell/components/PaginatedResourceTable';
|
|
3
|
+
import { APP_UPGRADE_STATUS } from '@shell/store/catalog';
|
|
3
4
|
|
|
4
5
|
export default {
|
|
5
6
|
name: 'ListApps',
|
|
@@ -21,6 +22,10 @@ export default {
|
|
|
21
22
|
}
|
|
22
23
|
},
|
|
23
24
|
|
|
25
|
+
data() {
|
|
26
|
+
return { APP_UPGRADE_STATUS };
|
|
27
|
+
},
|
|
28
|
+
|
|
24
29
|
async fetch() {
|
|
25
30
|
await this.$store.dispatch('catalog/load');
|
|
26
31
|
},
|
|
@@ -36,18 +41,30 @@ export default {
|
|
|
36
41
|
>
|
|
37
42
|
<template #cell:upgrade="{row}">
|
|
38
43
|
<span
|
|
39
|
-
v-if="row.upgradeAvailable"
|
|
44
|
+
v-if="row.upgradeAvailable === APP_UPGRADE_STATUS.SINGLE_UPGRADE"
|
|
40
45
|
class="badge-state bg-warning hand"
|
|
41
|
-
@click="row.goToUpgrade(row.
|
|
46
|
+
@click="row.goToUpgrade(row.upgradeAvailableVersion)"
|
|
42
47
|
>
|
|
43
|
-
{{ row.
|
|
48
|
+
{{ row.upgradeAvailableVersion }}
|
|
44
49
|
<i class="icon icon-upload" />
|
|
45
50
|
</span>
|
|
46
51
|
<span
|
|
47
|
-
v-else-if="row.upgradeAvailable ===
|
|
52
|
+
v-else-if="row.upgradeAvailable === APP_UPGRADE_STATUS.NOT_APPLICABLE"
|
|
48
53
|
v-t="'catalog.app.managed'"
|
|
49
54
|
class="text-muted"
|
|
50
55
|
/>
|
|
56
|
+
<span
|
|
57
|
+
v-else-if="row.upgradeAvailable === APP_UPGRADE_STATUS.NO_UPGRADE"
|
|
58
|
+
class="text-muted"
|
|
59
|
+
/>
|
|
60
|
+
<span
|
|
61
|
+
v-else-if="row.upgradeAvailable === APP_UPGRADE_STATUS.MULTIPLE_UPGRADES"
|
|
62
|
+
>
|
|
63
|
+
<i
|
|
64
|
+
v-clean-tooltip="t('catalog.app.upgrade.uncertainUpgradeWarningTooltip')"
|
|
65
|
+
class="icon icon-info"
|
|
66
|
+
/>
|
|
67
|
+
</span>
|
|
51
68
|
</template>
|
|
52
69
|
</PaginatedResourceTable>
|
|
53
70
|
</template>
|
|
@@ -118,7 +118,7 @@ export default {
|
|
|
118
118
|
v-if="row.status && row.status.summary && (row.status.summary.desiredReady !== row.status.summary.ready)"
|
|
119
119
|
class="text-warning"
|
|
120
120
|
>
|
|
121
|
-
{{ row.status.summary.ready }}/{{ row.status.summary.desiredReady }}</span>
|
|
121
|
+
{{ row.status.summary.ready || 0 }}/{{ row.status.summary.desiredReady }}</span>
|
|
122
122
|
<span v-else-if="row.status && row.status.summary">{{ row.status.summary.desiredReady }}</span>
|
|
123
123
|
<span v-else>-</span>
|
|
124
124
|
</template>
|