@rancher/shell 0.1.21 → 0.2.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/styles/global/_button.scss +1 -0
- package/assets/translations/en-us.yaml +56 -10
- package/assets/translations/zh-hans.yaml +346 -117
- package/components/Carousel.vue +25 -9
- package/components/HarvesterServiceAddOnConfig.vue +10 -10
- package/components/Import.vue +7 -1
- package/components/ResourceList/index.vue +34 -14
- package/components/ResourceTable.vue +19 -0
- package/components/SortableTable/THead.vue +311 -70
- package/components/SortableTable/advanced-filtering.js +272 -0
- package/components/SortableTable/filtering.js +90 -29
- package/components/SortableTable/index.vue +480 -271
- package/components/form/MatchExpressions.vue +15 -3
- package/components/form/WorkloadPorts.vue +2 -2
- package/components/nav/Header.vue +14 -1
- package/config/product/settings.js +1 -0
- package/config/product/uiplugins.js +1 -0
- package/config/uiplugins.js +13 -0
- package/creators/app/init +2 -2
- package/creators/app/package.json +1 -1
- package/creators/pkg/package.json +1 -1
- package/detail/cis.cattle.io.clusterscan.vue +6 -2
- package/detail/provisioning.cattle.io.cluster.vue +3 -3
- package/edit/provisioning.cattle.io.cluster/DrainOptions.vue +0 -1
- package/edit/provisioning.cattle.io.cluster/MachinePool.vue +5 -3
- package/edit/provisioning.cattle.io.cluster/rke2.vue +25 -24
- package/edit/service.vue +1 -1
- package/list/node.vue +7 -2
- package/mixins/resource-manager.js +5 -0
- package/models/cluster.x-k8s.io.machinedeployment.js +8 -0
- package/models/management.cattle.io.cluster.js +14 -1
- package/nuxt.config.js +113 -108
- package/package.json +1 -1
- package/pages/c/_cluster/apps/charts/index.vue +1 -1
- package/pages/c/_cluster/apps/charts/install.vue +106 -32
- package/pages/c/_cluster/settings/performance.vue +11 -0
- package/pages/c/_cluster/uiplugins/InstallDialog.vue +16 -2
- package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +5 -2
- package/pages/c/_cluster/uiplugins/RemoveUIPlugins.vue +28 -6
- package/pages/c/_cluster/uiplugins/UninstallDialog.vue +1 -1
- package/pages/c/_cluster/uiplugins/index.vue +49 -12
- package/promptRemove/mixin/roleDeletionCheck.js +15 -1
- package/scripts/record-deps.js +3 -3
- package/scripts/test-plugins-build.sh +1 -0
- package/scripts/typegen.sh +2 -2
- package/store/type-map.js +13 -2
- package/types/vue-shim.d +20 -0
- package/utils/create-yaml.js +30 -6
- package/creators/update/yarn-error.log +0 -54
- package/rancher-components/BadgeState/BadgeState.spec.ts +0 -12
- package/rancher-components/BadgeState/BadgeState.vue +0 -107
- package/rancher-components/BadgeState/index.ts +0 -1
- package/rancher-components/Banner/Banner.test.ts +0 -13
- package/rancher-components/Banner/Banner.vue +0 -163
- package/rancher-components/Banner/index.ts +0 -1
- package/rancher-components/Card/Card.vue +0 -150
- package/rancher-components/Card/index.ts +0 -1
- package/rancher-components/Form/Checkbox/Checkbox.test.ts +0 -77
- package/rancher-components/Form/Checkbox/Checkbox.vue +0 -395
- package/rancher-components/Form/Checkbox/index.ts +0 -1
- package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +0 -29
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +0 -343
- package/rancher-components/Form/LabeledInput/index.ts +0 -1
- package/rancher-components/Form/Radio/RadioButton.vue +0 -270
- package/rancher-components/Form/Radio/RadioGroup.vue +0 -235
- package/rancher-components/Form/Radio/index.ts +0 -2
- package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +0 -168
- package/rancher-components/Form/TextArea/index.ts +0 -1
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.test.ts +0 -107
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +0 -137
- package/rancher-components/Form/ToggleSwitch/index.ts +0 -1
- package/rancher-components/Form/index.ts +0 -5
- package/rancher-components/LabeledTooltip/LabeledTooltip.vue +0 -137
- package/rancher-components/LabeledTooltip/index.ts +0 -1
- package/rancher-components/components/BadgeState/BadgeState.spec.ts +0 -12
- package/rancher-components/components/BadgeState/BadgeState.vue +0 -107
- package/rancher-components/components/BadgeState/index.ts +0 -1
- package/rancher-components/components/Banner/Banner.test.ts +0 -13
- package/rancher-components/components/Banner/Banner.vue +0 -163
- package/rancher-components/components/Banner/index.ts +0 -1
- package/rancher-components/components/Card/Card.vue +0 -150
- package/rancher-components/components/Card/index.ts +0 -1
- package/rancher-components/components/Form/Checkbox/Checkbox.test.ts +0 -77
- package/rancher-components/components/Form/Checkbox/Checkbox.vue +0 -395
- package/rancher-components/components/Form/Checkbox/index.ts +0 -1
- package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +0 -29
- package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +0 -343
- package/rancher-components/components/Form/LabeledInput/index.ts +0 -1
- package/rancher-components/components/Form/Radio/RadioButton.vue +0 -270
- package/rancher-components/components/Form/Radio/RadioGroup.vue +0 -235
- package/rancher-components/components/Form/Radio/index.ts +0 -2
- package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +0 -168
- package/rancher-components/components/Form/TextArea/index.ts +0 -1
- package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.test.ts +0 -107
- package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.vue +0 -137
- package/rancher-components/components/Form/ToggleSwitch/index.ts +0 -1
- package/rancher-components/components/Form/index.ts +0 -5
- package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +0 -137
- package/rancher-components/components/LabeledTooltip/index.ts +0 -1
|
@@ -24,6 +24,7 @@ export default {
|
|
|
24
24
|
|
|
25
25
|
data() {
|
|
26
26
|
return {
|
|
27
|
+
currentVersion: '',
|
|
27
28
|
defaultRegistrySetting: null,
|
|
28
29
|
plugin: undefined,
|
|
29
30
|
busy: false,
|
|
@@ -43,7 +44,16 @@ export default {
|
|
|
43
44
|
return [];
|
|
44
45
|
}
|
|
45
46
|
|
|
46
|
-
|
|
47
|
+
// Don't allow update/rollback to curent version
|
|
48
|
+
const versions = this.plugin.versions.filter((v) => {
|
|
49
|
+
if (this.currentVersion) {
|
|
50
|
+
return v.version !== this.currentVersion;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return true;
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
return versions.map((version) => {
|
|
47
57
|
return {
|
|
48
58
|
label: version.version,
|
|
49
59
|
value: version.version,
|
|
@@ -65,6 +75,8 @@ export default {
|
|
|
65
75
|
this.version = plugin.displayVersion;
|
|
66
76
|
|
|
67
77
|
if (mode === 'update') {
|
|
78
|
+
this.currentVersion = plugin.displayVersion;
|
|
79
|
+
|
|
68
80
|
// Update to latest version, so take the first version
|
|
69
81
|
if (plugin.versions.length > 0) {
|
|
70
82
|
this.version = plugin.versions[0].version;
|
|
@@ -73,6 +85,8 @@ export default {
|
|
|
73
85
|
// Find the newest version once we remove the current version
|
|
74
86
|
const versionNames = plugin.versions.filter(v => v.version !== plugin.displayVersion);
|
|
75
87
|
|
|
88
|
+
this.currentVersion = plugin.displayVersion;
|
|
89
|
+
|
|
76
90
|
if (versionNames.length > 0) {
|
|
77
91
|
this.version = versionNames[0].version;
|
|
78
92
|
}
|
|
@@ -208,7 +222,7 @@ export default {
|
|
|
208
222
|
>
|
|
209
223
|
<div v-if="plugin" class="plugin-install-dialog">
|
|
210
224
|
<h4 class="mt-10">
|
|
211
|
-
{{ t(`plugins.${ mode }.title`, { name: plugin.
|
|
225
|
+
{{ t(`plugins.${ mode }.title`, { name: plugin.label }) }}
|
|
212
226
|
</h4>
|
|
213
227
|
<div class="custom mt-10">
|
|
214
228
|
<div class="dialog-panel">
|
|
@@ -117,8 +117,11 @@ export default {
|
|
|
117
117
|
</div>
|
|
118
118
|
<div>
|
|
119
119
|
<Banner v-if="info.error" color="error" :label="info.error" class="mt-10" />
|
|
120
|
-
<Banner v-if="
|
|
121
|
-
<
|
|
120
|
+
<Banner v-if="info.builtin" color="warning" :label="t('plugins.descriptions.built-in')" class="mt-10" />
|
|
121
|
+
<template v-else>
|
|
122
|
+
<Banner v-if="!info.certified" color="warning" :label="t('plugins.descriptions.third-party')" class="mt-10" />
|
|
123
|
+
<Banner v-if="info.experimental" color="warning" :label="t('plugins.descriptions.experimental')" class="mt-10" />
|
|
124
|
+
</template>
|
|
122
125
|
</div>
|
|
123
126
|
|
|
124
127
|
<h3 v-if="info.versions.length">
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
UI_PLUGIN_CHARTS,
|
|
8
8
|
UI_PLUGINS_REPO_NAME,
|
|
9
9
|
UI_PLUGINS_REPO_URL,
|
|
10
|
+
UI_PLUGIN_OPERATOR_CRD_CHART_NAME,
|
|
10
11
|
} from '@shell/config/uiplugins';
|
|
11
12
|
|
|
12
13
|
export default {
|
|
@@ -21,13 +22,23 @@ export default {
|
|
|
21
22
|
|
|
22
23
|
this.defaultRepo = repos.find(r => r.name === UI_PLUGINS_REPO_NAME && r.spec.gitRepo === UI_PLUGINS_REPO_URL);
|
|
23
24
|
}
|
|
25
|
+
|
|
26
|
+
if (this.$store.getters['management/schemaFor'](UI_PLUGIN)) {
|
|
27
|
+
const plugins = await this.$store.dispatch('management/findAll', { type: UI_PLUGIN });
|
|
28
|
+
|
|
29
|
+
// Are there any plugins installed?
|
|
30
|
+
this.hasPluginsInstalled = (plugins || []).length > 0;
|
|
31
|
+
this.removeCRD = !this.hasPluginsInstalled;
|
|
32
|
+
}
|
|
24
33
|
},
|
|
25
34
|
|
|
26
35
|
data() {
|
|
27
36
|
return {
|
|
28
|
-
errors:
|
|
29
|
-
defaultRepo:
|
|
30
|
-
removeRepo:
|
|
37
|
+
errors: [],
|
|
38
|
+
defaultRepo: undefined,
|
|
39
|
+
removeRepo: false,
|
|
40
|
+
removeCRD: true,
|
|
41
|
+
hasPluginsInstalled: false,
|
|
31
42
|
};
|
|
32
43
|
},
|
|
33
44
|
|
|
@@ -42,8 +53,8 @@ export default {
|
|
|
42
53
|
return found.remove();
|
|
43
54
|
}
|
|
44
55
|
|
|
45
|
-
//
|
|
46
|
-
return
|
|
56
|
+
// Return rejected promise - could not find the required chart
|
|
57
|
+
return Promise.reject(new Error(`Could not find chart §{ name }`));
|
|
47
58
|
},
|
|
48
59
|
|
|
49
60
|
showDialog() {
|
|
@@ -55,7 +66,12 @@ export default {
|
|
|
55
66
|
this.errors = [];
|
|
56
67
|
|
|
57
68
|
// Remove the charts in the reverse order that we install them in
|
|
58
|
-
|
|
69
|
+
let uninstall = [...UI_PLUGIN_CHARTS].reverse();
|
|
70
|
+
|
|
71
|
+
if (!this.removeCRD) {
|
|
72
|
+
// User does not want to uninstall the CRD, so remove the chart
|
|
73
|
+
uninstall = uninstall.filter(chart => chart !== UI_PLUGIN_OPERATOR_CRD_CHART_NAME);
|
|
74
|
+
}
|
|
59
75
|
|
|
60
76
|
for (let i = 0; i < uninstall.length; i++) {
|
|
61
77
|
const chart = uninstall[i];
|
|
@@ -103,6 +119,12 @@ export default {
|
|
|
103
119
|
{{ t('plugins.setup.remove.registry.prompt') }}
|
|
104
120
|
</div>
|
|
105
121
|
</div>
|
|
122
|
+
<div v-if="hasPluginsInstalled" class="mt-20">
|
|
123
|
+
<Checkbox v-model="removeCRD" :primary="true" label-key="plugins.setup.remove.crd.title" />
|
|
124
|
+
<div class="checkbox-info">
|
|
125
|
+
{{ t('plugins.setup.remove.crd.prompt') }}
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
106
128
|
</template>
|
|
107
129
|
</Dialog>
|
|
108
130
|
</template>
|
|
@@ -69,7 +69,7 @@ export default {
|
|
|
69
69
|
>
|
|
70
70
|
<div v-if="plugin" class="plugin-install-dialog">
|
|
71
71
|
<h4 class="mt-10">
|
|
72
|
-
{{ t('plugins.uninstall.title', { name: plugin.
|
|
72
|
+
{{ t('plugins.uninstall.title', { name: plugin.label }) }}
|
|
73
73
|
</h4>
|
|
74
74
|
<div class="mt-10 dialog-panel">
|
|
75
75
|
<div class="dialog-info">
|
|
@@ -6,7 +6,7 @@ import { sortBy } from '@shell/utils/sort';
|
|
|
6
6
|
import { allHash } from '@shell/utils/promise';
|
|
7
7
|
import { CATALOG, UI_PLUGIN, SERVICE } from '@shell/config/types';
|
|
8
8
|
import { CATALOG as CATALOG_ANNOTATIONS } from '@shell/config/labels-annotations';
|
|
9
|
-
|
|
9
|
+
import { NAME as APP_PRODUCT } from '@shell/config/product/apps';
|
|
10
10
|
import ActionMenu from '@shell/components/ActionMenu';
|
|
11
11
|
import Tabbed from '@shell/components/Tabbed/index.vue';
|
|
12
12
|
import Tab from '@shell/components/Tabbed/Tab.vue';
|
|
@@ -18,7 +18,14 @@ import DeveloperInstallDialog from './DeveloperInstallDialog.vue';
|
|
|
18
18
|
import PluginInfoPanel from './PluginInfoPanel.vue';
|
|
19
19
|
import SetupUIPlugins from './SetupUIPlugins';
|
|
20
20
|
import RemoveUIPlugins from './RemoveUIPlugins';
|
|
21
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
isUIPlugin,
|
|
23
|
+
uiPluginAnnotation,
|
|
24
|
+
uiPluginHasAnnotation,
|
|
25
|
+
isSupportedChartVersion,
|
|
26
|
+
UI_PLUGIN_NAMESPACE,
|
|
27
|
+
UI_PLUGIN_CHART_ANNOTATIONS
|
|
28
|
+
} from '@shell/config/uiplugins';
|
|
22
29
|
|
|
23
30
|
const MAX_DESCRIPTION_LENGTH = 200;
|
|
24
31
|
|
|
@@ -100,17 +107,25 @@ export default {
|
|
|
100
107
|
menuActions() {
|
|
101
108
|
const menuActions = [];
|
|
102
109
|
|
|
110
|
+
// Add link to go to the Repos view of the local cluster
|
|
111
|
+
menuActions.push({
|
|
112
|
+
action: 'manageRepos',
|
|
113
|
+
label: this.t('plugins.manageRepos'),
|
|
114
|
+
enabled: true
|
|
115
|
+
});
|
|
116
|
+
|
|
103
117
|
// Only show Developer Load action if the user has this enabled in preferences
|
|
104
118
|
if (this.pluginDeveloper) {
|
|
119
|
+
menuActions.push( { divider: true });
|
|
105
120
|
menuActions.push({
|
|
106
121
|
action: 'devLoad',
|
|
107
122
|
label: this.t('plugins.developer.label'),
|
|
108
123
|
enabled: true
|
|
109
124
|
});
|
|
110
|
-
menuActions.push( { divider: true });
|
|
111
125
|
}
|
|
112
126
|
|
|
113
127
|
if (this.hasService) {
|
|
128
|
+
menuActions.push( { divider: true });
|
|
114
129
|
menuActions.push({
|
|
115
130
|
action: 'removePluginSupport',
|
|
116
131
|
label: this.t('plugins.setup.remove.label'),
|
|
@@ -156,8 +171,11 @@ export default {
|
|
|
156
171
|
all = all.filter(c => !uiPluginHasAnnotation(c, CATALOG_ANNOTATIONS.HIDDEN, 'true'));
|
|
157
172
|
|
|
158
173
|
all = all.map((chart) => {
|
|
174
|
+
// Label can be overridden by chart annotation
|
|
175
|
+
const label = uiPluginAnnotation(UI_PLUGIN_CHART_ANNOTATIONS.DISPLAY_NAME) || chart.chartNameDisplay;
|
|
159
176
|
const item = {
|
|
160
177
|
name: chart.chartNameDisplay,
|
|
178
|
+
label,
|
|
161
179
|
description: chart.chartDescription,
|
|
162
180
|
id: chart.id,
|
|
163
181
|
versions: [],
|
|
@@ -197,7 +215,9 @@ export default {
|
|
|
197
215
|
// A pluign is loaded, but there is no chart, so add an item so that it shows up
|
|
198
216
|
const item = {
|
|
199
217
|
name: p.name,
|
|
218
|
+
label: p.name,
|
|
200
219
|
description: p.metadata?.description,
|
|
220
|
+
icon: p.metadata?.icon,
|
|
201
221
|
id: p.id,
|
|
202
222
|
versions: [],
|
|
203
223
|
displayVersion: p.metadata?.version || '-',
|
|
@@ -229,6 +249,7 @@ export default {
|
|
|
229
249
|
// No chart, so add a card for the plugin based on its Custom resource being present
|
|
230
250
|
const item = {
|
|
231
251
|
name: p.name,
|
|
252
|
+
label: p.name,
|
|
232
253
|
description: p.description || '-',
|
|
233
254
|
id: `${ p.name }-${ p.version }`,
|
|
234
255
|
versions: [],
|
|
@@ -317,11 +338,11 @@ export default {
|
|
|
317
338
|
|
|
318
339
|
plugins(neu, old) {
|
|
319
340
|
const installed = this.$store.getters['uiplugins/plugins'];
|
|
320
|
-
|
|
341
|
+
const shouldHaveLoaded = (installed || []).filter(p => !this.uiErrors[p.name] && !p.builtin);
|
|
321
342
|
let changes = 0;
|
|
322
343
|
|
|
323
344
|
// Did the user remove an extension
|
|
324
|
-
if (neu?.length <
|
|
345
|
+
if (neu?.length < shouldHaveLoaded.length) {
|
|
325
346
|
changes++;
|
|
326
347
|
}
|
|
327
348
|
|
|
@@ -329,7 +350,9 @@ export default {
|
|
|
329
350
|
const existing = installed.find(p => !p.removed && p.name === plugin.name && p.version === plugin.version);
|
|
330
351
|
|
|
331
352
|
if (!existing && plugin.isCached) {
|
|
332
|
-
|
|
353
|
+
if (!this.uiErrors[plugin.name]) {
|
|
354
|
+
changes++;
|
|
355
|
+
}
|
|
333
356
|
|
|
334
357
|
this.updatePluginInstallStatus(plugin.name, false);
|
|
335
358
|
}
|
|
@@ -441,6 +464,17 @@ export default {
|
|
|
441
464
|
|
|
442
465
|
reload() {
|
|
443
466
|
this.$router.go();
|
|
467
|
+
},
|
|
468
|
+
|
|
469
|
+
manageRepos() {
|
|
470
|
+
this.$router.push({
|
|
471
|
+
name: 'c-cluster-product-resource',
|
|
472
|
+
params: {
|
|
473
|
+
cluster: 'local',
|
|
474
|
+
product: APP_PRODUCT,
|
|
475
|
+
resource: CATALOG.CLUSTER_REPO
|
|
476
|
+
}
|
|
477
|
+
});
|
|
444
478
|
}
|
|
445
479
|
}
|
|
446
480
|
};
|
|
@@ -479,6 +513,7 @@ export default {
|
|
|
479
513
|
@close="setMenu(false)"
|
|
480
514
|
@devLoad="showDeveloperLoaddDialog"
|
|
481
515
|
@removePluginSupport="removePluginSupport"
|
|
516
|
+
@manageRepos="manageRepos"
|
|
482
517
|
/>
|
|
483
518
|
</div>
|
|
484
519
|
|
|
@@ -528,14 +563,11 @@ export default {
|
|
|
528
563
|
</div>
|
|
529
564
|
<div class="plugin-metadata">
|
|
530
565
|
<div class="plugin-name">
|
|
531
|
-
{{ plugin.
|
|
566
|
+
{{ plugin.label }}
|
|
532
567
|
</div>
|
|
533
568
|
<div>{{ plugin.description }}</div>
|
|
534
|
-
<div v-if="plugin.builtin" class="plugin-builtin">
|
|
535
|
-
{{ t('plugins.labels.builtin') }}
|
|
536
|
-
</div>
|
|
537
569
|
<div class="plugin-version">
|
|
538
|
-
<span v-if="plugin.installing
|
|
570
|
+
<span v-if="plugin.installing" class="plugin-installing">
|
|
539
571
|
-
|
|
540
572
|
</span>
|
|
541
573
|
<span v-else>
|
|
@@ -543,7 +575,12 @@ export default {
|
|
|
543
575
|
<span v-if="plugin.upgrade" v-tooltip="t('plugins.upgradeAvailable')"> -> {{ plugin.upgrade }}</span>
|
|
544
576
|
</span>
|
|
545
577
|
</div>
|
|
546
|
-
<div class="plugin-badges">
|
|
578
|
+
<div v-if="plugin.builtin" class="plugin-badges">
|
|
579
|
+
<div class="plugin-builtin">
|
|
580
|
+
{{ t('plugins.labels.builtin') }}
|
|
581
|
+
</div>
|
|
582
|
+
</div>
|
|
583
|
+
<div v-else class="plugin-badges">
|
|
547
584
|
<div v-if="!plugin.certified" v-tooltip="t('plugins.descriptions.third-party')">
|
|
548
585
|
{{ t('plugins.labels.third-party') }}
|
|
549
586
|
</div>
|
|
@@ -66,12 +66,26 @@ export default {
|
|
|
66
66
|
method: 'get',
|
|
67
67
|
}, { root: true });
|
|
68
68
|
|
|
69
|
+
// We need to fetch the users here in order to get an accurate count when selecting global roles.
|
|
70
|
+
const users = await this.$store.dispatch('management/request', {
|
|
71
|
+
url: `/v1/${ MANAGEMENT.USER }`,
|
|
72
|
+
method: 'get',
|
|
73
|
+
}, { root: true });
|
|
74
|
+
|
|
75
|
+
const userMap = users.data?.reduce((map, user) => {
|
|
76
|
+
if ( user.username ) {
|
|
77
|
+
map[user.id] = user;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return map;
|
|
81
|
+
}, {});
|
|
82
|
+
|
|
69
83
|
if (request.data && request.data.length) {
|
|
70
84
|
rolesToRemove.forEach((toRemove) => {
|
|
71
85
|
const usedRoles = request.data.filter(item => item[propToMatch] === toRemove.id);
|
|
72
86
|
|
|
73
87
|
if (usedRoles.length) {
|
|
74
|
-
const uniqueUsers = [...new Set(usedRoles.map(item => item.userName))];
|
|
88
|
+
const uniqueUsers = [...new Set(usedRoles.map(item => item.userName).filter(user => userMap[user]))];
|
|
75
89
|
|
|
76
90
|
if (uniqueUsers.length) {
|
|
77
91
|
numberOfRolesWithBinds++;
|
package/scripts/record-deps.js
CHANGED
|
@@ -2,7 +2,7 @@ const fs = require('fs');
|
|
|
2
2
|
const path = require('path');
|
|
3
3
|
|
|
4
4
|
// Script lives in shell/scripts, so work out top-level dir from there
|
|
5
|
-
const topDir = path.resolve(__dirname, '..', '..')
|
|
5
|
+
const topDir = path.resolve(__dirname, '..', '..');
|
|
6
6
|
const dir = process.cwd();
|
|
7
7
|
|
|
8
8
|
// Read the package.json file
|
|
@@ -17,10 +17,10 @@ if (mainPkg._requires) {
|
|
|
17
17
|
// Map each one to the same version as the main package
|
|
18
18
|
const out = {};
|
|
19
19
|
|
|
20
|
-
mainPkg._requires.forEach(name => {
|
|
20
|
+
mainPkg._requires.forEach((name) => {
|
|
21
21
|
let ver = topPkg.dependencies?.[name] || topPkg.devDependencies?.[name];
|
|
22
22
|
|
|
23
|
-
if (name === '@rancher/components') {
|
|
23
|
+
if (name === '@rancher/components') {
|
|
24
24
|
const componentsPkgFile = path.join(topDir, 'pkg', 'rancher-components', 'package.json');
|
|
25
25
|
const componentsPkg = JSON.parse(fs.readFileSync(componentsPkgFile));
|
|
26
26
|
|
package/scripts/typegen.sh
CHANGED
|
@@ -46,8 +46,8 @@ echo "// Auto-generated type definitions for shell" > ${INDEX}
|
|
|
46
46
|
echo "// Do not modify this file as changes will get overwritten" >> ${INDEX}
|
|
47
47
|
|
|
48
48
|
# Copy in the vue shim type definitions
|
|
49
|
-
if [ -f "$BASE_DIR/vue-shim.d
|
|
50
|
-
cat "$BASE_DIR/vue-shim.d
|
|
49
|
+
if [ -f "$BASE_DIR/shell/types/vue-shim.d" ]; then
|
|
50
|
+
cat "$BASE_DIR/shell/types/vue-shim.d" >> ${INDEX}
|
|
51
51
|
fi
|
|
52
52
|
|
|
53
53
|
function processDir() {
|
package/store/type-map.js
CHANGED
|
@@ -121,7 +121,13 @@
|
|
|
121
121
|
// continueOnMatch
|
|
122
122
|
// )
|
|
123
123
|
import { AGE, NAME, NAMESPACE as NAMESPACE_COL, STATE } from '@shell/config/table-headers';
|
|
124
|
-
import {
|
|
124
|
+
import {
|
|
125
|
+
CATALOG,
|
|
126
|
+
COUNT,
|
|
127
|
+
SCHEMA,
|
|
128
|
+
MANAGEMENT,
|
|
129
|
+
NAMESPACE
|
|
130
|
+
} from '@shell/config/types';
|
|
125
131
|
import { VIEW_IN_API, EXPANDED_GROUPS, FAVORITE_TYPES } from '@shell/store/prefs';
|
|
126
132
|
import {
|
|
127
133
|
addObject, findBy, insertAt, isArray, removeObject, filterBy
|
|
@@ -218,6 +224,8 @@ export function DSL(store, product, module = 'type-map') {
|
|
|
218
224
|
headers.forEach((header) => {
|
|
219
225
|
// If on the client, then use the value getter if there is one
|
|
220
226
|
if (header.getValue) {
|
|
227
|
+
// we need to store the .value prop for the advanced filtering
|
|
228
|
+
header.valueProp = header.value;
|
|
221
229
|
header.value = header.getValue;
|
|
222
230
|
}
|
|
223
231
|
|
|
@@ -1760,8 +1768,11 @@ function ifHave(getters, option) {
|
|
|
1760
1768
|
export function isAdminUser(getters) {
|
|
1761
1769
|
const canEditSettings = (getters['management/schemaFor'](MANAGEMENT.SETTING)?.resourceMethods || []).includes('PUT');
|
|
1762
1770
|
const canEditFeatureFlags = (getters['management/schemaFor'](MANAGEMENT.FEATURE)?.resourceMethods || []).includes('PUT');
|
|
1771
|
+
const canInstallApps = (getters['management/schemaFor'](CATALOG.APP)?.resourceMethods || []).includes('PUT');
|
|
1772
|
+
const canAddRepos = (getters['management/schemaFor'](CATALOG.CLUSTER_REPO)?.resourceMethods || []).includes('PUT');
|
|
1773
|
+
const canPutHelmOperations = (getters['management/schemaFor'](CATALOG.OPERATION)?.resourceMethods || []).includes('PUT');
|
|
1763
1774
|
|
|
1764
|
-
return canEditSettings && canEditFeatureFlags;
|
|
1775
|
+
return canEditSettings && canEditFeatureFlags && canInstallApps && canAddRepos && canPutHelmOperations;
|
|
1765
1776
|
}
|
|
1766
1777
|
|
|
1767
1778
|
// Is V1 Istio installed?
|
package/types/vue-shim.d
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
declare module '*.vue' {
|
|
2
|
+
import Vue from 'vue';
|
|
3
|
+
export default Vue;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
// This is required to keep typescript from complaining. It is required for
|
|
7
|
+
// our i18n plugin. For more info see:
|
|
8
|
+
// https://v2.vuejs.org/v2/guide/typescript.html?redirect=true#Augmenting-Types-for-Use-with-Plugins
|
|
9
|
+
declare module 'vue/types/vue' {
|
|
10
|
+
// eslint-disable-next-line no-unused-vars
|
|
11
|
+
interface Vue {
|
|
12
|
+
/**
|
|
13
|
+
* Lookup a given string with the given arguments
|
|
14
|
+
* @param raw if set, do not do HTML escaping.
|
|
15
|
+
*/
|
|
16
|
+
t: (key: string, args?: Record<string, any>, raw?: boolean) => string,
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
declare module 'js-yaml';
|
package/utils/create-yaml.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { indent as _indent } from '@shell/utils/string';
|
|
2
2
|
import { addObject, findBy, removeObject, removeObjects } from '@shell/utils/array';
|
|
3
3
|
import jsyaml from 'js-yaml';
|
|
4
|
-
import { cleanUp } from '@shell/utils/object';
|
|
4
|
+
import { cleanUp, isEmpty } from '@shell/utils/object';
|
|
5
5
|
|
|
6
6
|
export const SIMPLE_TYPES = [
|
|
7
7
|
'string',
|
|
@@ -114,7 +114,7 @@ export function createYaml(schemas, type, data, processAlwaysAdd = true, depth =
|
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
//
|
|
117
|
+
// Include all fields in schema's resourceFields as comments
|
|
118
118
|
const commentFields = Object.keys(schema.resourceFields || {});
|
|
119
119
|
|
|
120
120
|
commentFields.forEach((key) => {
|
|
@@ -123,12 +123,14 @@ export function createYaml(schemas, type, data, processAlwaysAdd = true, depth =
|
|
|
123
123
|
}
|
|
124
124
|
});
|
|
125
125
|
|
|
126
|
+
// add any fields defined in data as uncommented fields in yaml
|
|
126
127
|
for ( const key in data ) {
|
|
127
128
|
if ( typeof data[key] !== 'undefined' ) {
|
|
128
129
|
addObject(regularFields, key);
|
|
129
130
|
}
|
|
130
131
|
}
|
|
131
132
|
|
|
133
|
+
// ACTIVELY_REMOVE are fields that should be removed even if they are defined in data
|
|
132
134
|
for ( const entry of ACTIVELY_REMOVE ) {
|
|
133
135
|
const parts = entry.split(/\./);
|
|
134
136
|
const key = parts[parts.length - 1];
|
|
@@ -139,6 +141,7 @@ export function createYaml(schemas, type, data, processAlwaysAdd = true, depth =
|
|
|
139
141
|
}
|
|
140
142
|
}
|
|
141
143
|
|
|
144
|
+
// NEVER_ADD are fields that should not be added as comments, but may added as regular fields if already defined in data
|
|
142
145
|
for ( const entry of NEVER_ADD ) {
|
|
143
146
|
const parts = entry.split(/\./);
|
|
144
147
|
const key = parts[parts.length - 1];
|
|
@@ -149,6 +152,7 @@ export function createYaml(schemas, type, data, processAlwaysAdd = true, depth =
|
|
|
149
152
|
}
|
|
150
153
|
}
|
|
151
154
|
|
|
155
|
+
// do not include commented fields if already defined in data
|
|
152
156
|
removeObjects(commentFields, regularFields);
|
|
153
157
|
|
|
154
158
|
const regular = regularFields.map(k => stringifyField(k));
|
|
@@ -183,6 +187,7 @@ export function createYaml(schemas, type, data, processAlwaysAdd = true, depth =
|
|
|
183
187
|
out = 'type:';
|
|
184
188
|
}
|
|
185
189
|
|
|
190
|
+
// if a key on data is not listed in the schema's resourceFields, just convert it to yaml, add indents where needed, and return
|
|
186
191
|
if ( !field ) {
|
|
187
192
|
if (data[key]) {
|
|
188
193
|
try {
|
|
@@ -209,7 +214,9 @@ export function createYaml(schemas, type, data, processAlwaysAdd = true, depth =
|
|
|
209
214
|
const arrayOf = typeRef('array', type);
|
|
210
215
|
const referenceTo = typeRef('reference', type);
|
|
211
216
|
|
|
217
|
+
// type == map[mapOf]
|
|
212
218
|
if ( mapOf ) {
|
|
219
|
+
// if key is defined in data, convert the value to yaml, add newline+indent and add to output yaml string
|
|
213
220
|
if (data[key]) {
|
|
214
221
|
try {
|
|
215
222
|
const cleaned = cleanUp(data);
|
|
@@ -224,17 +231,20 @@ export function createYaml(schemas, type, data, processAlwaysAdd = true, depth =
|
|
|
224
231
|
if ( SIMPLE_TYPES.includes(mapOf) ) {
|
|
225
232
|
out += `\n# key: ${ mapOf }`;
|
|
226
233
|
} else {
|
|
234
|
+
// If not a simple type ie some sort of object/array, recusively build out commented fields (note data = null here) per the type's (mapOf's) schema
|
|
227
235
|
const chunk = createYaml(schemas, mapOf, null, processAlwaysAdd, depth + 1, (path ? `${ path }.${ key }` : key), rootType);
|
|
228
|
-
let indented = indent(chunk
|
|
236
|
+
let indented = indent(chunk);
|
|
229
237
|
|
|
238
|
+
// convert "# foo" to "#foo"
|
|
230
239
|
indented = indented.replace(/^(#)?\s\s\s\s/, '$1');
|
|
231
240
|
|
|
232
|
-
out += `\n
|
|
241
|
+
out += `\n${ indented }`;
|
|
233
242
|
}
|
|
234
243
|
|
|
235
244
|
return out;
|
|
236
245
|
}
|
|
237
246
|
|
|
247
|
+
// type == array[arrayOf]
|
|
238
248
|
if ( arrayOf ) {
|
|
239
249
|
if (data[key]) {
|
|
240
250
|
try {
|
|
@@ -256,6 +266,7 @@ export function createYaml(schemas, type, data, processAlwaysAdd = true, depth =
|
|
|
256
266
|
const chunk = createYaml(schemas, arrayOf, null, false, depth + 1, (path ? `${ path }.${ key }` : key), rootType);
|
|
257
267
|
let indented = indent(chunk, 2);
|
|
258
268
|
|
|
269
|
+
// turn "# foo" into "# - foo"
|
|
259
270
|
indented = indented.replace(/^(#)?\s*\s\s([^\s])/, '$1 - $2');
|
|
260
271
|
|
|
261
272
|
out += `\n${ indented }`;
|
|
@@ -303,8 +314,21 @@ export function createYaml(schemas, type, data, processAlwaysAdd = true, depth =
|
|
|
303
314
|
|
|
304
315
|
const subDef = findBy(schemas, 'id', type);
|
|
305
316
|
|
|
306
|
-
if ( subDef
|
|
307
|
-
|
|
317
|
+
if ( subDef) {
|
|
318
|
+
let chunk;
|
|
319
|
+
|
|
320
|
+
if (subDef?.resourceFields && !isEmpty(subDef?.resourceFields)) {
|
|
321
|
+
chunk = createYaml(schemas, type, data[key], processAlwaysAdd, depth + 1, (path ? `${ path }.${ key }` : key), rootType);
|
|
322
|
+
} else if (data[key]) {
|
|
323
|
+
// if there are no fields defined on the schema but there are in the data, just format data as yaml and add to output yaml
|
|
324
|
+
try {
|
|
325
|
+
const parsed = jsyaml.dump(data[key]);
|
|
326
|
+
|
|
327
|
+
chunk = parsed.trim();
|
|
328
|
+
} catch (e) {
|
|
329
|
+
console.error(`Error: Unale to parse data for yaml of type: ${ type }`, e); // eslint-disable-line no-console
|
|
330
|
+
}
|
|
331
|
+
}
|
|
308
332
|
|
|
309
333
|
out += `\n${ indent(chunk) }`;
|
|
310
334
|
} else {
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
Arguments:
|
|
2
|
-
/usr/local/bin/node /usr/local/Cellar/yarn/1.22.11/libexec/bin/yarn.js add @rancher/pkg@0.0.0
|
|
3
|
-
|
|
4
|
-
PATH:
|
|
5
|
-
/Users/nwm/.gem/ruby/3.1.2/bin:/Users/nwm/.rubies/ruby-3.1.2/lib/ruby/gems/3.1.0/bin:/Users/nwm/.rubies/ruby-3.1.2/bin:/Users/nwm/.deno/bin:/usr/local/sbin:/opt/local/bin:/opt/local/sbin:/Users/nwm/.rd/bin:/Users/nwm/go/bin:/usr/local/bin:/Users/nwm/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/go/bin:/usr/local/MacGPG2/bin:/Library/Apple/usr/bin:/Users/nwm/.deno/bin:/usr/local/sbin:/Users/nwm/google-cloud-sdk/bin:/opt/local/bin:/opt/local/sbin:/Users/nwm/.rd/bin:/Users/nwm/go/bin:/Users/nwm/bin:/Applications/Utilities/kdiff3.app/Contents/MacOS/:/Applications/Visual Studio Code.app/Contents/Resources/app/bin:/Applications/Utilities/kdiff3.app/Contents/MacOS/:/Applications/Visual Studio Code.app/Contents/Resources/app/bin
|
|
6
|
-
|
|
7
|
-
Yarn version:
|
|
8
|
-
1.22.11
|
|
9
|
-
|
|
10
|
-
Node version:
|
|
11
|
-
16.16.0
|
|
12
|
-
|
|
13
|
-
Platform:
|
|
14
|
-
darwin x64
|
|
15
|
-
|
|
16
|
-
Trace:
|
|
17
|
-
Error: https://registry.yarnpkg.com/@rancher%2fpkg: Not found
|
|
18
|
-
at Request.params.callback [as _callback] (/usr/local/Cellar/yarn/1.22.11/libexec/lib/cli.js:66992:18)
|
|
19
|
-
at Request.self.callback (/usr/local/Cellar/yarn/1.22.11/libexec/lib/cli.js:140763:22)
|
|
20
|
-
at Request.emit (node:events:527:28)
|
|
21
|
-
at Request.<anonymous> (/usr/local/Cellar/yarn/1.22.11/libexec/lib/cli.js:141735:10)
|
|
22
|
-
at Request.emit (node:events:527:28)
|
|
23
|
-
at IncomingMessage.<anonymous> (/usr/local/Cellar/yarn/1.22.11/libexec/lib/cli.js:141657:12)
|
|
24
|
-
at Object.onceWrapper (node:events:641:28)
|
|
25
|
-
at IncomingMessage.emit (node:events:539:35)
|
|
26
|
-
at endReadableNT (node:internal/streams/readable:1345:12)
|
|
27
|
-
at processTicksAndRejections (node:internal/process/task_queues:83:21)
|
|
28
|
-
|
|
29
|
-
npm manifest:
|
|
30
|
-
{
|
|
31
|
-
"name": "@rancher/create-app",
|
|
32
|
-
"description": "Rancher UI Upgrade helper",
|
|
33
|
-
"version": "0.0.0",
|
|
34
|
-
"license": "Apache-2.0",
|
|
35
|
-
"author": "SUSE",
|
|
36
|
-
"private": false,
|
|
37
|
-
"bin": "./init",
|
|
38
|
-
"files": [
|
|
39
|
-
"*.*",
|
|
40
|
-
"init"
|
|
41
|
-
],
|
|
42
|
-
"engines": {
|
|
43
|
-
"node": ">=12"
|
|
44
|
-
},
|
|
45
|
-
"dependencies": {
|
|
46
|
-
"fs-extra": "^10.0.0"
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
yarn manifest:
|
|
51
|
-
No manifest
|
|
52
|
-
|
|
53
|
-
Lockfile:
|
|
54
|
-
No lockfile
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { shallowMount } from '@vue/test-utils';
|
|
2
|
-
import { BadgeState } from './index';
|
|
3
|
-
|
|
4
|
-
describe('BadgeState.vue', () => {
|
|
5
|
-
it('renders props.msg when passed', () => {
|
|
6
|
-
const label = 'Hello, World!';
|
|
7
|
-
|
|
8
|
-
const wrapper = shallowMount(BadgeState, { propsData: { label } });
|
|
9
|
-
|
|
10
|
-
expect(wrapper.find('span').text()).toMatch(label);
|
|
11
|
-
});
|
|
12
|
-
});
|