@rancher/shell 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/brand/suse/dark/rancher-logo.svg +1 -148
- package/assets/brand/suse/rancher-logo.svg +1 -130
- package/assets/images/featured/img1.jpg +0 -0
- package/assets/images/featured.jpg +0 -0
- package/assets/images/generic-plugin.svg +7 -0
- package/assets/styles/themes/_dark.scss +3 -0
- package/assets/styles/themes/_light.scss +3 -0
- package/assets/styles/themes/_suse.scss +1 -1
- package/assets/translations/en-us.yaml +183 -45
- package/assets/translations/zh-hans.yaml +21 -24
- package/components/AsyncButton.vue +17 -2
- package/components/ButtonDropdown.vue +4 -0
- package/components/Carousel.vue +291 -0
- package/components/CommunityLinks.vue +69 -18
- package/components/CruResource.vue +11 -3
- package/components/Dialog.vue +102 -0
- package/components/ExplorerMembers.vue +2 -4
- package/components/ExplorerProjectsNamespaces.vue +6 -7
- package/components/IconMessage.vue +9 -1
- package/components/LocaleSelector.vue +62 -29
- package/components/ResourceTable.vue +7 -2
- package/components/SimpleBox.vue +6 -4
- package/components/SortableTable/index.vue +11 -21
- package/components/Tabbed/Tab.vue +5 -0
- package/components/Tabbed/index.vue +29 -2
- package/components/auth/Principal.vue +1 -0
- package/components/fleet/FleetBundles.vue +8 -3
- package/components/fleet/FleetSummary.vue +6 -0
- package/components/form/KeyValue.vue +80 -58
- package/components/form/NameNsDescription.vue +10 -4
- package/components/form/ResourceTabs/index.vue +5 -1
- package/components/formatter/ClusterLink.vue +3 -7
- package/components/nav/NamespaceFilter.vue +3 -3
- package/components/nav/TopLevelMenu.vue +10 -28
- package/config/footer.js +13 -14
- package/config/labels-annotations.js +2 -1
- package/config/product/explorer.js +5 -4
- package/config/product/legacy.js +0 -47
- package/config/product/multi-cluster-apps.js +0 -12
- package/config/product/settings.js +12 -1
- package/config/product/uiplugins.js +17 -0
- package/config/settings.js +21 -2
- package/config/types.js +5 -1
- package/config/uiplugins.js +60 -0
- package/content/docs/en-us/getting-started.md +1 -26
- package/core/plugins.js +12 -0
- package/detail/provisioning.cattle.io.cluster.vue +3 -3
- package/detail/workload/index.vue +2 -2
- package/dialog/DiagnosticTimingsDialog.vue +116 -0
- package/dialog/RotateCertificatesDialog.vue +9 -3
- package/edit/auth/azuread.vue +28 -9
- package/edit/networking.k8s.io.ingress/index.vue +2 -2
- package/edit/persistentvolume/index.vue +3 -0
- package/edit/pod.vue +27 -0
- package/edit/provisioning.cattle.io.cluster/rke2.vue +76 -5
- package/edit/service.vue +7 -5
- package/edit/workload/__tests__/Upgrading.test.ts +1 -0
- package/edit/workload/index.vue +13 -1
- package/edit/workload/mixins/workload.js +13 -13
- package/edit/workload/storage/ContainerMountPaths.vue +240 -0
- package/edit/workload/storage/Mount.vue +1 -0
- package/edit/workload/storage/awsElasticBlockStore.vue +20 -1
- package/edit/workload/storage/azureDisk.vue +22 -2
- package/edit/workload/storage/azureFile.vue +20 -2
- package/edit/workload/storage/csi/index.vue +23 -1
- package/edit/workload/storage/gcePersistentDisk.vue +20 -2
- package/edit/workload/storage/index.vue +23 -49
- package/edit/workload/storage/vsphereVolume.vue +11 -1
- package/layouts/default.vue +14 -8
- package/layouts/home.vue +9 -4
- package/layouts/plain.vue +10 -5
- package/list/management.cattle.io.setting.vue +3 -3
- package/list/provisioning.cattle.io.cluster.vue +1 -1
- package/machine-config/harvester.vue +5 -3
- package/models/catalog.cattle.io.uiplugin.js +34 -0
- package/models/cluster/node.js +25 -2
- package/models/fleet.cattle.io.bundle.js +1 -1
- package/models/harvesterhci.io.management.cluster.js +11 -5
- package/models/provisioning.cattle.io.cluster.js +12 -6
- package/models/workload.js +5 -3
- package/nuxt.config.js +69 -25
- package/package.json +108 -109
- package/pages/auth/login.vue +1 -1
- package/pages/c/_cluster/apps/charts/index.vue +46 -1
- package/pages/c/_cluster/apps/charts/install.vue +10 -9
- package/pages/c/_cluster/explorer/index.vue +72 -9
- package/pages/c/_cluster/explorer/tools/index.vue +12 -5
- package/pages/c/_cluster/mcapps/index.vue +1 -1
- package/pages/c/_cluster/settings/brand.vue +0 -40
- package/pages/c/_cluster/settings/links.vue +200 -0
- package/pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue +232 -0
- package/pages/c/_cluster/uiplugins/InstallDialog.vue +242 -0
- package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +284 -0
- package/pages/c/_cluster/uiplugins/RemoveUIPlugins.vue +130 -0
- package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +253 -0
- package/pages/c/_cluster/uiplugins/UninstallDialog.vue +115 -0
- package/pages/c/_cluster/uiplugins/index.vue +694 -0
- package/pages/diagnostic.vue +185 -101
- package/pages/docs/_doc.vue +3 -1
- package/pages/home.vue +21 -56
- package/pages/prefs.vue +108 -88
- package/pages/safeMode.vue +17 -0
- package/pages/support/index.vue +23 -15
- package/pkg/dynamic-importer.lib.js +4 -0
- package/plugins/dashboard-store/resource-class.js +2 -2
- package/plugins/formatters.js +15 -0
- package/plugins/plugin.js +56 -4
- package/plugins/steve/mutations.js +1 -1
- package/plugins/steve/subscribe.js +94 -72
- package/plugins/steve/web-worker.steve-sub-worker.js +24 -15
- package/promptRemove/management.cattle.io.globalrole.vue +47 -0
- package/promptRemove/management.cattle.io.roletemplate.vue +47 -0
- package/promptRemove/mixin/roleDeletionCheck.js +97 -0
- package/scripts/publish-shell.sh +1 -1
- package/scripts/sync-shell-deps +37 -0
- package/store/catalog.js +9 -8
- package/store/i18n.js +10 -1
- package/store/prefs.js +16 -0
- package/store/type-map.js +32 -5
- package/store/uiplugins.ts +15 -61
- package/utils/__tests__/object.test.ts +0 -24
- package/utils/__tests__/selector.test.ts +1 -1
- package/utils/dynamic-importer.js +4 -0
- package/utils/grafana.js +2 -6
- package/utils/socket.js +41 -20
- package/utils/string.js +1 -7
- package/utils/validators/formRules/__tests__/index.test.ts +108 -0
- package/utils/validators/formRules/index.ts +9 -1
- package/yarn-error.log +195 -0
- package/pages/plugins.vue +0 -387
- package/server/verdaccio-middleware.js +0 -56
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import BrandImage from '@shell/components/BrandImage';
|
|
3
3
|
import ClusterProviderIcon from '@shell/components/ClusterProviderIcon';
|
|
4
|
-
import LocaleSelector from '@shell/components/LocaleSelector';
|
|
5
4
|
import { mapGetters } from 'vuex';
|
|
6
5
|
import $ from 'jquery';
|
|
7
6
|
import { CAPI, MANAGEMENT } from '@shell/config/types';
|
|
8
|
-
import { mapPref,
|
|
7
|
+
import { mapPref, MENU_MAX_CLUSTERS } from '@shell/store/prefs';
|
|
9
8
|
import { sortBy } from '@shell/utils/sort';
|
|
10
9
|
import { ucFirst } from '@shell/utils/string';
|
|
11
10
|
import { KEY } from '@shell/utils/platform';
|
|
@@ -20,9 +19,7 @@ const UI_COMMIT = process.env.COMMIT || UNKNOWN;
|
|
|
20
19
|
|
|
21
20
|
export default {
|
|
22
21
|
|
|
23
|
-
components: {
|
|
24
|
-
BrandImage, ClusterProviderIcon, LocaleSelector
|
|
25
|
-
},
|
|
22
|
+
components: { BrandImage, ClusterProviderIcon },
|
|
26
23
|
|
|
27
24
|
data() {
|
|
28
25
|
const { displayVersion, fullVersion } = getVersionInfo(this.$store);
|
|
@@ -68,9 +65,10 @@ export default {
|
|
|
68
65
|
clusters() {
|
|
69
66
|
const all = this.$store.getters['management/all'](MANAGEMENT.CLUSTER);
|
|
70
67
|
let kubeClusters = filterHiddenLocalCluster(filterOnlyKubernetesClusters(all), this.$store);
|
|
68
|
+
let pClusters = null;
|
|
71
69
|
|
|
72
70
|
if (this.hasProvCluster) {
|
|
73
|
-
|
|
71
|
+
pClusters = this.$store.getters['management/all'](CAPI.RANCHER_CLUSTER);
|
|
74
72
|
const available = pClusters.reduce((p, c) => {
|
|
75
73
|
p[c.mgmt] = true;
|
|
76
74
|
|
|
@@ -84,10 +82,12 @@ export default {
|
|
|
84
82
|
}
|
|
85
83
|
|
|
86
84
|
return kubeClusters.map((x) => {
|
|
85
|
+
const pCluster = pClusters?.find(c => c.mgmt.id === x.id);
|
|
86
|
+
|
|
87
87
|
return {
|
|
88
88
|
id: x.id,
|
|
89
89
|
label: x.nameDisplay,
|
|
90
|
-
ready: x.isReady,
|
|
90
|
+
ready: x.isReady && !pCluster?.hasError,
|
|
91
91
|
osLogo: x.providerOsLogo,
|
|
92
92
|
providerNavLogo: x.providerMenuLogo,
|
|
93
93
|
badge: x.badge,
|
|
@@ -101,13 +101,11 @@ export default {
|
|
|
101
101
|
|
|
102
102
|
const out = search ? this.clusters.filter(item => item.label.toLowerCase().includes(search)) : this.clusters;
|
|
103
103
|
|
|
104
|
-
const sorted = sortBy(out, ['
|
|
104
|
+
const sorted = sortBy(out, ['name:desc', 'label']);
|
|
105
105
|
|
|
106
106
|
return sorted;
|
|
107
107
|
},
|
|
108
108
|
|
|
109
|
-
dev: mapPref(DEV),
|
|
110
|
-
|
|
111
109
|
maxClustersToShow: mapPref(MENU_MAX_CLUSTERS),
|
|
112
110
|
|
|
113
111
|
multiClusterApps() {
|
|
@@ -125,22 +123,7 @@ export default {
|
|
|
125
123
|
configurationApps() {
|
|
126
124
|
const options = this.options;
|
|
127
125
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
// Add plugin page
|
|
131
|
-
// Ony when developing for now
|
|
132
|
-
if (process.env.dev) {
|
|
133
|
-
items.push({
|
|
134
|
-
label: 'Plugins',
|
|
135
|
-
inStore: 'management',
|
|
136
|
-
icon: 'icon-gear',
|
|
137
|
-
value: 'plugins',
|
|
138
|
-
weight: 1,
|
|
139
|
-
to: { name: 'plugins' },
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
return items;
|
|
126
|
+
return options.filter(opt => opt.category === 'configuration');
|
|
144
127
|
},
|
|
145
128
|
|
|
146
129
|
options() {
|
|
@@ -186,7 +169,7 @@ export default {
|
|
|
186
169
|
watch: {
|
|
187
170
|
$route() {
|
|
188
171
|
this.shown = false;
|
|
189
|
-
}
|
|
172
|
+
}
|
|
190
173
|
},
|
|
191
174
|
|
|
192
175
|
mounted() {
|
|
@@ -349,7 +332,6 @@ export default {
|
|
|
349
332
|
v-html="displayVersion"
|
|
350
333
|
/>
|
|
351
334
|
</div>
|
|
352
|
-
<LocaleSelector></LocaleSelector>
|
|
353
335
|
</div>
|
|
354
336
|
</div>
|
|
355
337
|
</transition>
|
package/config/footer.js
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
import { DOCS_BASE } from '@shell/config/private-label';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
// Deprecated
|
|
4
|
+
export function options(isSupport, issuesUrl) {
|
|
5
|
+
const links = {
|
|
6
|
+
docs: DOCS_BASE,
|
|
7
|
+
forums: 'https://forums.rancher.com/',
|
|
8
|
+
slack: 'https://slack.rancher.io',
|
|
9
|
+
issues: !!issuesUrl ? issuesUrl : 'https://github.com/rancher/dashboard/issues/new',
|
|
10
|
+
getStarted: '/docs/getting-started'
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
if (!isSupport) {
|
|
14
|
+
links['commercialSupport'] = '/support';
|
|
11
15
|
}
|
|
12
16
|
|
|
13
|
-
return
|
|
14
|
-
'footer.docs': DOCS_BASE,
|
|
15
|
-
'footer.forums': 'https://forums.rancher.com/',
|
|
16
|
-
'footer.slack': 'https://slack.rancher.io',
|
|
17
|
-
'footer.issue': issues,
|
|
18
|
-
};
|
|
17
|
+
return links;
|
|
19
18
|
}
|
|
@@ -65,6 +65,7 @@ export const CATALOG = {
|
|
|
65
65
|
EXPERIMENTAL: 'catalog.cattle.io/experimental',
|
|
66
66
|
NAMESPACE: 'catalog.cattle.io/namespace',
|
|
67
67
|
RELEASE_NAME: 'catalog.cattle.io/release-name',
|
|
68
|
+
FEATURED: 'catalog.cattle.io/featured',
|
|
68
69
|
|
|
69
70
|
REQUIRES_GVK: 'catalog.cattle.io/requires-gvr',
|
|
70
71
|
PROVIDES: 'catalog.cattle.io/provides-gvr',
|
|
@@ -94,7 +95,7 @@ export const CATALOG = {
|
|
|
94
95
|
DEPLOYED_OS: 'catalog.cattle.io/deploys-on-os',
|
|
95
96
|
|
|
96
97
|
MIGRATED: 'apps.cattle.io/migrated',
|
|
97
|
-
MANAGED: 'catalog.cattle.io/managed'
|
|
98
|
+
MANAGED: 'catalog.cattle.io/managed',
|
|
98
99
|
};
|
|
99
100
|
|
|
100
101
|
export const FLEET = {
|
|
@@ -58,6 +58,7 @@ export function init(store) {
|
|
|
58
58
|
'namespaces',
|
|
59
59
|
NODE,
|
|
60
60
|
VIRTUAL_TYPES.CLUSTER_MEMBERS,
|
|
61
|
+
EVENT,
|
|
61
62
|
], 'cluster');
|
|
62
63
|
basicType([
|
|
63
64
|
SERVICE,
|
|
@@ -142,6 +143,7 @@ export function init(store) {
|
|
|
142
143
|
configureType(NORMAN.PROJECT_ROLE_TEMPLATE_BINDING, { depaginate: true });
|
|
143
144
|
|
|
144
145
|
configureType(EVENT, { limit: 500 });
|
|
146
|
+
weightType(EVENT, -1, true);
|
|
145
147
|
|
|
146
148
|
// Allow Pods to be grouped by node
|
|
147
149
|
configureType(POD, {
|
|
@@ -158,13 +160,12 @@ export function init(store) {
|
|
|
158
160
|
|
|
159
161
|
setGroupDefaultType('serviceDiscovery', SERVICE);
|
|
160
162
|
|
|
161
|
-
configureType(
|
|
162
|
-
displayName: '
|
|
163
|
+
configureType(WORKLOAD, {
|
|
164
|
+
displayName: store.getters['i18n/t'](`typeLabel.${ WORKLOAD }`, { count: 1 }).trim(),
|
|
163
165
|
location: {
|
|
164
166
|
name: 'c-cluster-product-resource',
|
|
165
|
-
params: { resource:
|
|
167
|
+
params: { resource: WORKLOAD },
|
|
166
168
|
},
|
|
167
|
-
resource: WORKLOAD_TYPES.DEPLOYMENT
|
|
168
169
|
});
|
|
169
170
|
|
|
170
171
|
headers(PV, [STATE, NAME_COL, RECLAIM_POLICY, PERSISTENT_VOLUME_CLAIM, PERSISTENT_VOLUME_SOURCE, PV_REASON, AGE]);
|
package/config/product/legacy.js
CHANGED
|
@@ -46,16 +46,6 @@ export function init(store) {
|
|
|
46
46
|
exact: true
|
|
47
47
|
});
|
|
48
48
|
|
|
49
|
-
virtualType({
|
|
50
|
-
labelKey: 'legacy.cis-scans',
|
|
51
|
-
name: 'v1-cis-scans',
|
|
52
|
-
group: 'Root',
|
|
53
|
-
namespaced: true,
|
|
54
|
-
weight: 111,
|
|
55
|
-
route: { name: 'c-cluster-legacy-pages-page', params: { page: 'cis' } },
|
|
56
|
-
exact: true
|
|
57
|
-
});
|
|
58
|
-
|
|
59
49
|
virtualType({
|
|
60
50
|
ifHave: IF_HAVE.PROJECT,
|
|
61
51
|
labelKey: 'legacy.project.label',
|
|
@@ -82,7 +72,6 @@ export function init(store) {
|
|
|
82
72
|
'v1-alerts',
|
|
83
73
|
'v1-catalogs',
|
|
84
74
|
'v1-notifiers',
|
|
85
|
-
'v1-cis-scans',
|
|
86
75
|
'v1-project-overview'
|
|
87
76
|
]);
|
|
88
77
|
|
|
@@ -121,17 +110,6 @@ export function init(store) {
|
|
|
121
110
|
overview: false,
|
|
122
111
|
});
|
|
123
112
|
|
|
124
|
-
virtualType({
|
|
125
|
-
ifHave: IF_HAVE.PROJECT,
|
|
126
|
-
labelKey: 'legacy.logging',
|
|
127
|
-
namespaced: true,
|
|
128
|
-
name: 'project-logging',
|
|
129
|
-
weight: 105,
|
|
130
|
-
route: { name: 'c-cluster-legacy-project-page', params: { page: 'logging' } },
|
|
131
|
-
exact: true,
|
|
132
|
-
overview: false,
|
|
133
|
-
});
|
|
134
|
-
|
|
135
113
|
virtualType({
|
|
136
114
|
ifHave: IF_HAVE.PROJECT,
|
|
137
115
|
labelKey: 'legacy.monitoring',
|
|
@@ -143,28 +121,6 @@ export function init(store) {
|
|
|
143
121
|
overview: false,
|
|
144
122
|
});
|
|
145
123
|
|
|
146
|
-
virtualType({
|
|
147
|
-
ifHave: IF_HAVE.PROJECT,
|
|
148
|
-
labelKey: 'legacy.istio',
|
|
149
|
-
namespaced: true,
|
|
150
|
-
name: 'project-istio',
|
|
151
|
-
weight: 105,
|
|
152
|
-
route: { name: 'c-cluster-legacy-project-page', params: { page: 'istio' } },
|
|
153
|
-
exact: true,
|
|
154
|
-
overview: false,
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
virtualType({
|
|
158
|
-
ifHave: IF_HAVE.PROJECT,
|
|
159
|
-
labelKey: 'legacy.pipelines',
|
|
160
|
-
namespaced: true,
|
|
161
|
-
name: 'project-pipelines',
|
|
162
|
-
weight: 104,
|
|
163
|
-
route: { name: 'c-cluster-legacy-project-pipelines' },
|
|
164
|
-
exact: true,
|
|
165
|
-
overview: false,
|
|
166
|
-
});
|
|
167
|
-
|
|
168
124
|
virtualType({
|
|
169
125
|
ifHave: IF_HAVE.PROJECT,
|
|
170
126
|
labelKey: 'legacy.secrets',
|
|
@@ -192,10 +148,7 @@ export function init(store) {
|
|
|
192
148
|
'project-alerts',
|
|
193
149
|
'project-catalogs',
|
|
194
150
|
'project-config-maps',
|
|
195
|
-
'project-logging',
|
|
196
|
-
'project-istio',
|
|
197
151
|
'project-monitoring',
|
|
198
|
-
'project-pipelines',
|
|
199
152
|
'project-secrets',
|
|
200
153
|
], 'Project');
|
|
201
154
|
}
|
|
@@ -20,17 +20,6 @@ export function init(store) {
|
|
|
20
20
|
showWorkspaceSwitcher: false,
|
|
21
21
|
});
|
|
22
22
|
|
|
23
|
-
virtualType({
|
|
24
|
-
labelKey: 'legacy.apps',
|
|
25
|
-
name: 'mc-apps',
|
|
26
|
-
group: 'Root',
|
|
27
|
-
namespaced: false,
|
|
28
|
-
weight: 112,
|
|
29
|
-
icon: 'folder',
|
|
30
|
-
route: { name: 'c-cluster-mcapps-pages-page', params: { cluster: 'local', page: 'apps' } },
|
|
31
|
-
exact: true
|
|
32
|
-
});
|
|
33
|
-
|
|
34
23
|
virtualType({
|
|
35
24
|
labelKey: 'legacy.catalogs',
|
|
36
25
|
name: 'mc-catalogs',
|
|
@@ -65,7 +54,6 @@ export function init(store) {
|
|
|
65
54
|
});
|
|
66
55
|
|
|
67
56
|
basicType([
|
|
68
|
-
'mc-apps',
|
|
69
57
|
'mc-catalogs',
|
|
70
58
|
'global-dns-entries',
|
|
71
59
|
'global-dns-providers',
|
|
@@ -90,12 +90,23 @@ export function init(store) {
|
|
|
90
90
|
route: { name: 'c-cluster-settings-performance' }
|
|
91
91
|
});
|
|
92
92
|
|
|
93
|
+
virtualType({
|
|
94
|
+
ifHaveType: MANAGEMENT.SETTING,
|
|
95
|
+
labelKey: 'customLinks.label',
|
|
96
|
+
name: 'links',
|
|
97
|
+
namespaced: false,
|
|
98
|
+
weight: 96,
|
|
99
|
+
icon: 'folder',
|
|
100
|
+
route: { name: 'c-cluster-settings-links' }
|
|
101
|
+
});
|
|
102
|
+
|
|
93
103
|
basicType([
|
|
94
104
|
'settings',
|
|
95
105
|
'features',
|
|
96
106
|
'brand',
|
|
97
107
|
'banners',
|
|
98
|
-
'performance'
|
|
108
|
+
'performance',
|
|
109
|
+
'links'
|
|
99
110
|
]);
|
|
100
111
|
|
|
101
112
|
configureType(MANAGEMENT.SETTING, {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { DSL, IF_HAVE } from '@shell/store/type-map';
|
|
2
|
+
|
|
3
|
+
export const NAME = 'uiplugins';
|
|
4
|
+
|
|
5
|
+
export function init(store) {
|
|
6
|
+
const { product } = DSL(store, NAME);
|
|
7
|
+
|
|
8
|
+
// Add a product for UI Plugins - will appear in the top-level menu
|
|
9
|
+
product({
|
|
10
|
+
ifHave: IF_HAVE.ADMIN, // Only admins can see the UI Plugin Custom Resource by default
|
|
11
|
+
inStore: 'management',
|
|
12
|
+
icon: 'gear',
|
|
13
|
+
removable: false,
|
|
14
|
+
showClusterSwitcher: false,
|
|
15
|
+
category: 'configuration',
|
|
16
|
+
});
|
|
17
|
+
}
|
package/config/settings.js
CHANGED
|
@@ -55,6 +55,7 @@ export const SETTING = {
|
|
|
55
55
|
COMMUNITY_LINKS: 'ui-community-links',
|
|
56
56
|
FAVICON: 'ui-favicon',
|
|
57
57
|
UI_PERFORMANCE: 'ui-performance',
|
|
58
|
+
UI_CUSTOM_LINKS: 'ui-custom-links',
|
|
58
59
|
/**
|
|
59
60
|
* Allow the backend to force a light/dark theme. Used in non-rancher world and results in the theme used
|
|
60
61
|
* both pre and post log in. If not present defaults to the usual process
|
|
@@ -86,7 +87,7 @@ export const ALLOWED_SETTINGS = {
|
|
|
86
87
|
kind: 'enum',
|
|
87
88
|
options: ['dynamic', 'true', 'false']
|
|
88
89
|
},
|
|
89
|
-
[SETTING.BRAND]: {},
|
|
90
|
+
[SETTING.BRAND]: { canReset: true },
|
|
90
91
|
[SETTING.CLUSTER_TEMPLATE_ENFORCEMENT]: { kind: 'boolean' },
|
|
91
92
|
[SETTING.TELEMETRY]: {
|
|
92
93
|
kind: 'enum',
|
|
@@ -104,7 +105,7 @@ export const DEFAULT_PERF_SETTING = {
|
|
|
104
105
|
enabled: false,
|
|
105
106
|
threshold: 1500,
|
|
106
107
|
},
|
|
107
|
-
disableWebsocketNotification:
|
|
108
|
+
disableWebsocketNotification: true
|
|
108
109
|
};
|
|
109
110
|
|
|
110
111
|
export const fetchOrCreateSetting = async(store, id, val, save = true) => {
|
|
@@ -135,3 +136,21 @@ export const setSetting = async(store, id, val) => {
|
|
|
135
136
|
|
|
136
137
|
return setting;
|
|
137
138
|
};
|
|
139
|
+
|
|
140
|
+
export const getPerformanceSetting = (rootGetters) => {
|
|
141
|
+
const perfSetting = rootGetters['management/byId'](MANAGEMENT.SETTING, SETTING.UI_PERFORMANCE);
|
|
142
|
+
let perfConfig = {};
|
|
143
|
+
|
|
144
|
+
if (perfSetting && perfSetting.value) {
|
|
145
|
+
try {
|
|
146
|
+
perfConfig = JSON.parse(perfSetting.value);
|
|
147
|
+
} catch (e) {
|
|
148
|
+
console.warn('ui-performance setting contains invalid data'); // eslint-disable-line no-console
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Start with the default and overwrite the values from the setting - ensures we have defaults for newly added options
|
|
153
|
+
perfConfig = Object.assign(DEFAULT_PERF_SETTING, perfConfig);
|
|
154
|
+
|
|
155
|
+
return perfConfig;
|
|
156
|
+
};
|
package/config/types.js
CHANGED
|
@@ -51,6 +51,7 @@ export const NAMESPACE = 'namespace';
|
|
|
51
51
|
export const NODE = 'node';
|
|
52
52
|
export const NETWORK_POLICY = 'networking.k8s.io.networkpolicy';
|
|
53
53
|
export const POD = 'pod';
|
|
54
|
+
export const PSP = 'policy.podsecuritypolicy';
|
|
54
55
|
export const PV = 'persistentvolume';
|
|
55
56
|
export const PVC = 'persistentvolumeclaim';
|
|
56
57
|
export const RESOURCE_QUOTA = 'resourcequota';
|
|
@@ -80,7 +81,6 @@ export const WORKLOAD_TYPES = {
|
|
|
80
81
|
STATEFUL_SET: 'apps.statefulset',
|
|
81
82
|
REPLICA_SET: 'apps.replicaset',
|
|
82
83
|
REPLICATION_CONTROLLER: 'replicationcontroller',
|
|
83
|
-
POD: 'pod'
|
|
84
84
|
};
|
|
85
85
|
|
|
86
86
|
const {
|
|
@@ -101,6 +101,9 @@ export const CATALOG = {
|
|
|
101
101
|
REPO: 'catalog.cattle.io.repo',
|
|
102
102
|
};
|
|
103
103
|
|
|
104
|
+
// UI Plugin type
|
|
105
|
+
export const UI_PLUGIN = 'catalog.cattle.io.uiplugin';
|
|
106
|
+
|
|
104
107
|
export const HELM = { PROJECTHELMCHART: 'helm.cattle.io.projecthelmchart' };
|
|
105
108
|
|
|
106
109
|
export const MONITORING = {
|
|
@@ -271,6 +274,7 @@ export const HCI = {
|
|
|
271
274
|
CLUSTER: 'harvesterhci.io.management.cluster',
|
|
272
275
|
DASHBOARD: 'harvesterhci.io.dashboard',
|
|
273
276
|
IMAGE: 'harvesterhci.io.virtualmachineimage',
|
|
277
|
+
SETTING: 'harvesterhci.io.setting',
|
|
274
278
|
};
|
|
275
279
|
|
|
276
280
|
export const VIRTUAL_HARVESTER_PROVIDER = 'harvester';
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import semver from 'semver';
|
|
2
|
+
|
|
3
|
+
// Version of the plugin API supported
|
|
4
|
+
export const UI_PLUGIN_API_VERSION = '1.0.0';
|
|
5
|
+
|
|
6
|
+
export const UI_PLUGIN_BASE_URL = '/api/v1/namespaces/cattle-ui-plugin-system/services/http:ui-plugin-operator:80/proxy';
|
|
7
|
+
|
|
8
|
+
export const UI_PLUGIN_NAMESPACE = 'cattle-ui-plugin-system';
|
|
9
|
+
|
|
10
|
+
// Annotation name and value that indicate a chart is a UI plugin
|
|
11
|
+
export const UI_PLUGIN_ANNOTATION_NAME = 'catalog.cattle.io/ui-component';
|
|
12
|
+
export const UI_PLUGIN_ANNOTATION_VALUE = 'plugins';
|
|
13
|
+
|
|
14
|
+
export const UI_PLUGIN_OPERATOR_CRD_CHART_NAME = 'ui-plugin-operator-crd';
|
|
15
|
+
export const UI_PLUGIN_OPERATOR_CHART_NAME = 'ui-plugin-operator';
|
|
16
|
+
|
|
17
|
+
export const UI_PLUGIN_CHARTS = [
|
|
18
|
+
UI_PLUGIN_OPERATOR_CHART_NAME,
|
|
19
|
+
UI_PLUGIN_OPERATOR_CRD_CHART_NAME,
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
// Expected chart repo name for the UI Plugins operator
|
|
23
|
+
export const UI_PLUGIN_OPERATOR_REPO_NAME = 'rancher-charts';
|
|
24
|
+
|
|
25
|
+
// Info for the Helm Chart Repository that we will add
|
|
26
|
+
export const UI_PLUGINS_REPO_NAME = 'rancher-ui-plugins';
|
|
27
|
+
|
|
28
|
+
export const UI_PLUGINS_REPO_URL = 'https://github.com/rancher/ui-plugin-charts';
|
|
29
|
+
export const UI_PLUGINS_REPO_BRANCH = 'main';
|
|
30
|
+
|
|
31
|
+
// Plugin Metadata properties
|
|
32
|
+
const UI_PLUGIN_METADATA_API_VERSION = 'apiVersion';
|
|
33
|
+
|
|
34
|
+
export function isUIPlugin(chart) {
|
|
35
|
+
return !!chart?.versions.find((v) => {
|
|
36
|
+
return v.annotations && v.annotations[UI_PLUGIN_ANNOTATION_NAME] === UI_PLUGIN_ANNOTATION_VALUE;
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function uiPluginHasAnnotation(chart, name, value) {
|
|
41
|
+
return !!chart?.versions.find((v) => {
|
|
42
|
+
return v.annotations && v.annotations[name] === value;
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Should we load a plugin, based on the metadata returned by the backend?
|
|
47
|
+
export function shouldLoadPlugin(plugin) {
|
|
48
|
+
if (!plugin.name || !plugin.version || !plugin.endpoint) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Plugin specified a required API version
|
|
53
|
+
const requiredAPI = plugin.metadata?.[UI_PLUGIN_METADATA_API_VERSION];
|
|
54
|
+
|
|
55
|
+
if (requiredAPI) {
|
|
56
|
+
return semver.satisfies(UI_PLUGIN_API_VERSION, requiredAPI);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
@@ -72,11 +72,6 @@ As of version 2.6, Cluster Manager is no longer provided as a separate UI. The d
|
|
|
72
72
|
<tr class="table-group">
|
|
73
73
|
<td colspan="3">Global</td>
|
|
74
74
|
</tr>
|
|
75
|
-
<tr>
|
|
76
|
-
<td>Apps</td>
|
|
77
|
-
<td>Global → Apps</td>
|
|
78
|
-
<td>Menu → Multi-cluster Apps → Apps</td>
|
|
79
|
-
</tr>
|
|
80
75
|
<tr>
|
|
81
76
|
<td>Settings</td>
|
|
82
77
|
<td>Global → Settings</td>
|
|
@@ -100,7 +95,7 @@ As of version 2.6, Cluster Manager is no longer provided as a separate UI. The d
|
|
|
100
95
|
<tr>
|
|
101
96
|
<td>Pod Security Policies</td>
|
|
102
97
|
<td>Global → Security → Pod Security Policies</td>
|
|
103
|
-
<td>Menu → Cluster Management →
|
|
98
|
+
<td>Menu → Cluster Management → Pod Security Policies</td>
|
|
104
99
|
</tr>
|
|
105
100
|
<!-- -->
|
|
106
101
|
<tr class="table-group">
|
|
@@ -136,26 +131,11 @@ As of version 2.6, Cluster Manager is no longer provided as a separate UI. The d
|
|
|
136
131
|
<td>(Cluster) → Tools → Notifiers</td>
|
|
137
132
|
<td>Menu → (Cluster) → Legacy -> Notifiers</td>
|
|
138
133
|
</tr>
|
|
139
|
-
<tr>
|
|
140
|
-
<td>Logging (V1)</td>
|
|
141
|
-
<td>(Cluster) → Tools → Logging</td>
|
|
142
|
-
<td>Menu → (Cluster) → Cluster Tools -> Logging (Legacy)</td>
|
|
143
|
-
</tr>
|
|
144
134
|
<tr>
|
|
145
135
|
<td>Monitoring (V1)</td>
|
|
146
136
|
<td>(Cluster) → Tools → Monitoring</td>
|
|
147
137
|
<td>Menu → (Cluster) → Cluster Tools -> Monitoring (Legacy)</td>
|
|
148
138
|
</tr>
|
|
149
|
-
<tr>
|
|
150
|
-
<td>Istio (V1)</td>
|
|
151
|
-
<td>(Cluster) → Tools → Istio</td>
|
|
152
|
-
<td>Menu → (Cluster) → Cluster Tools -> Istio (Legacy)</td>
|
|
153
|
-
</tr>
|
|
154
|
-
<tr>
|
|
155
|
-
<td>CIS Scans (V1)</td>
|
|
156
|
-
<td>(Cluster) → Tools → CIS Scans</td>
|
|
157
|
-
<td>Menu → (Cluster) → Legacy -> CIS Scans</td>
|
|
158
|
-
</tr>
|
|
159
139
|
<tr class="table-group">
|
|
160
140
|
<td colspan="3">V1 Monitoring</td>
|
|
161
141
|
<tr>
|
|
@@ -212,11 +192,6 @@ As of version 2.6, Cluster Manager is no longer provided as a separate UI. The d
|
|
|
212
192
|
<td>(Cluster) → (Project) → Tools → Monitoring</td>
|
|
213
193
|
<td>Menu → (Cluster) → Legacy → Project → (Project) → Monitoring</td>
|
|
214
194
|
</tr>
|
|
215
|
-
<tr>
|
|
216
|
-
<td>Pipeline</td>
|
|
217
|
-
<td>(Cluster) → (Project) → Tools → Pipeline</td>
|
|
218
|
-
<td>Menu → (Cluster) → Legacy → Project → (Project) → Pipelines → Configuration</td>
|
|
219
|
-
</tr>
|
|
220
195
|
<tr class="table-group">
|
|
221
196
|
<td colspan="3">Other</td>
|
|
222
197
|
</tr>
|
package/core/plugins.js
CHANGED
|
@@ -2,6 +2,7 @@ import { productsLoaded } from '@shell/store/type-map';
|
|
|
2
2
|
import { clearModelCache } from '@shell/plugins/dashboard-store/model-loader';
|
|
3
3
|
import { Plugin } from './plugin';
|
|
4
4
|
import { PluginRoutes } from './plugin-routes';
|
|
5
|
+
import { UI_PLUGIN_BASE_URL } from '@shell/config/uiplugins';
|
|
5
6
|
|
|
6
7
|
const MODEL_TYPE = 'models';
|
|
7
8
|
|
|
@@ -35,6 +36,17 @@ export default function({
|
|
|
35
36
|
return internal;
|
|
36
37
|
},
|
|
37
38
|
|
|
39
|
+
// Load a plugin from a UI package
|
|
40
|
+
loadAsyncByNameAndVersion(name, version, url) {
|
|
41
|
+
const id = `${ name }-${ version }`;
|
|
42
|
+
|
|
43
|
+
if (!url) {
|
|
44
|
+
url = `${ UI_PLUGIN_BASE_URL }/${ name }/${ version }/plugin/${ id }.umd.min.js`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return this.loadAsync(id, url);
|
|
48
|
+
},
|
|
49
|
+
|
|
38
50
|
// Load a plugin from a UI package
|
|
39
51
|
loadAsync(id, mainFile) {
|
|
40
52
|
return new Promise((resolve, reject) => {
|
|
@@ -93,7 +93,7 @@ export default {
|
|
|
93
93
|
fetchOne.snapshots = this.$store.dispatch('management/findAll', { type: SNAPSHOT });
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
if ( this.value.isImported || this.value.isCustom || this.value.
|
|
96
|
+
if ( this.value.isImported || this.value.isCustom || this.value.isHostedKubernetesProvider ) {
|
|
97
97
|
fetchOne.clusterToken = this.value.getOrCreateToken();
|
|
98
98
|
}
|
|
99
99
|
|
|
@@ -322,7 +322,7 @@ export default {
|
|
|
322
322
|
},
|
|
323
323
|
|
|
324
324
|
showEksNodeGroupWarning() {
|
|
325
|
-
if ( this.value.
|
|
325
|
+
if ( this.value.provisioner === 'EKS' ) {
|
|
326
326
|
const desiredTotal = this.value.eksNodeGroups.filter(g => g.desiredSize === 0);
|
|
327
327
|
|
|
328
328
|
if ( desiredTotal.length === this.value.eksNodeGroups.length ) {
|
|
@@ -451,7 +451,7 @@ export default {
|
|
|
451
451
|
return true;
|
|
452
452
|
}
|
|
453
453
|
|
|
454
|
-
if (
|
|
454
|
+
if ( this.value.isHostedKubernetesProvider && !this.isClusterReady ) {
|
|
455
455
|
return true;
|
|
456
456
|
}
|
|
457
457
|
|
|
@@ -121,7 +121,7 @@ export default {
|
|
|
121
121
|
},
|
|
122
122
|
|
|
123
123
|
isPod() {
|
|
124
|
-
return this.value.type ===
|
|
124
|
+
return this.value.type === POD;
|
|
125
125
|
},
|
|
126
126
|
|
|
127
127
|
podSchema() {
|
|
@@ -141,7 +141,7 @@ export default {
|
|
|
141
141
|
return this.value.spec.jobTemplate.spec.template.spec;
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
-
if ( this.value.type ===
|
|
144
|
+
if ( this.value.type === POD ) {
|
|
145
145
|
return this.value;
|
|
146
146
|
}
|
|
147
147
|
|