@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
package/layouts/home.vue
CHANGED
|
@@ -3,7 +3,7 @@ import Header from '@shell/components/nav/Header';
|
|
|
3
3
|
import Brand from '@shell/mixins/brand';
|
|
4
4
|
import FixedBanner from '@shell/components/FixedBanner';
|
|
5
5
|
import GrowlManager from '@shell/components/GrowlManager';
|
|
6
|
-
import { mapPref,
|
|
6
|
+
import { mapPref, THEME_SHORTCUT } from '@shell/store/prefs';
|
|
7
7
|
import AwsComplianceBanner from '@shell/components/AwsComplianceBanner';
|
|
8
8
|
import AzureWarning from '@shell/components/auth/AzureWarning';
|
|
9
9
|
import BrowserTabVisibility from '@shell/mixins/browser-tab-visibility';
|
|
@@ -26,12 +26,13 @@ export default {
|
|
|
26
26
|
data() {
|
|
27
27
|
return {
|
|
28
28
|
// Assume home pages have routes where the name is the key to use for string lookup
|
|
29
|
-
name:
|
|
29
|
+
name: this.$route.name,
|
|
30
|
+
noLocaleShortcut: process.env.dev || false
|
|
30
31
|
};
|
|
31
32
|
},
|
|
32
33
|
|
|
33
34
|
computed: {
|
|
34
|
-
|
|
35
|
+
themeShortcut: mapPref(THEME_SHORTCUT),
|
|
35
36
|
...mapState(['managementReady']),
|
|
36
37
|
},
|
|
37
38
|
|
|
@@ -39,6 +40,9 @@ export default {
|
|
|
39
40
|
toggleTheme() {
|
|
40
41
|
this.$store.dispatch('prefs/toggleTheme');
|
|
41
42
|
},
|
|
43
|
+
toggleNoneLocale() {
|
|
44
|
+
this.$store.dispatch('i18n/toggleNone');
|
|
45
|
+
},
|
|
42
46
|
}
|
|
43
47
|
|
|
44
48
|
};
|
|
@@ -59,7 +63,8 @@ export default {
|
|
|
59
63
|
</div>
|
|
60
64
|
<FixedBanner :footer="true" />
|
|
61
65
|
<GrowlManager />
|
|
62
|
-
<button v-if="
|
|
66
|
+
<button v-if="themeShortcut" v-shortkey.once="['shift','t']" class="hide" @shortkey="toggleTheme()" />
|
|
67
|
+
<button v-if="noLocaleShortcut" v-shortkey.once="['shift','l']" class="hide" @shortkey="toggleNoneLocale()" />
|
|
63
68
|
</div>
|
|
64
69
|
</template>
|
|
65
70
|
|
package/layouts/plain.vue
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import { mapPref,
|
|
2
|
+
import { mapPref, THEME_SHORTCUT } from '@shell/store/prefs';
|
|
3
3
|
import ActionMenu from '@shell/components/ActionMenu';
|
|
4
4
|
import Header from '@shell/components/nav/Header';
|
|
5
5
|
import PromptRemove from '@shell/components/PromptRemove';
|
|
@@ -33,16 +33,20 @@ export default {
|
|
|
33
33
|
data() {
|
|
34
34
|
return {
|
|
35
35
|
// Assume home pages have routes where the name is the key to use for string lookup
|
|
36
|
-
name:
|
|
36
|
+
name: this.$route.name,
|
|
37
|
+
noLocaleShortcut: process.env.dev || false,
|
|
37
38
|
};
|
|
38
39
|
},
|
|
39
40
|
|
|
40
|
-
computed: {
|
|
41
|
+
computed: { themeShortcut: mapPref(THEME_SHORTCUT) },
|
|
41
42
|
|
|
42
43
|
methods: {
|
|
43
44
|
toggleTheme() {
|
|
44
45
|
this.$store.dispatch('prefs/toggleTheme');
|
|
45
|
-
}
|
|
46
|
+
},
|
|
47
|
+
toggleNoneLocale() {
|
|
48
|
+
this.$store.dispatch('i18n/toggleNone');
|
|
49
|
+
},
|
|
46
50
|
}
|
|
47
51
|
};
|
|
48
52
|
</script>
|
|
@@ -62,7 +66,8 @@ export default {
|
|
|
62
66
|
<ActionMenu />
|
|
63
67
|
<PromptRemove />
|
|
64
68
|
<AssignTo />
|
|
65
|
-
<button v-if="
|
|
69
|
+
<button v-if="themeShortcut" v-shortkey.once="['shift','t']" class="hide" @shortkey="toggleTheme()" />
|
|
70
|
+
<button v-if="noLocaleShortcut" v-shortkey.once="['shift','l']" class="hide" @shortkey="toggleNoneLocale()" />
|
|
66
71
|
</main>
|
|
67
72
|
</div>
|
|
68
73
|
|
|
@@ -4,13 +4,13 @@ import { MANAGEMENT } from '@shell/config/types';
|
|
|
4
4
|
import { ALLOWED_SETTINGS } from '@shell/config/settings';
|
|
5
5
|
import { Banner } from '@components/Banner';
|
|
6
6
|
import Loading from '@shell/components/Loading';
|
|
7
|
-
import {
|
|
7
|
+
import { VIEW_IN_API } from '@shell/store/prefs';
|
|
8
8
|
|
|
9
9
|
export default {
|
|
10
10
|
components: { Banner, Loading },
|
|
11
11
|
|
|
12
12
|
async fetch() {
|
|
13
|
-
const
|
|
13
|
+
const viewInApi = this.$store.getters['prefs/get'](VIEW_IN_API);
|
|
14
14
|
const rows = await this.$store.dispatch(`management/findAll`, { type: MANAGEMENT.SETTING });
|
|
15
15
|
const t = this.$store.getters['i18n/t'];
|
|
16
16
|
// Map settings from array to object keyed by id
|
|
@@ -51,7 +51,7 @@ export default {
|
|
|
51
51
|
}
|
|
52
52
|
// There are only 2 actions that can be enabled - Edit Setting or View in API
|
|
53
53
|
// If neither is available for this setting then we hide the action menu button
|
|
54
|
-
s.hasActions = (!s.readOnly ||
|
|
54
|
+
s.hasActions = (!s.readOnly || viewInApi) && setting.availableActions?.length;
|
|
55
55
|
settings.push(s);
|
|
56
56
|
}
|
|
57
57
|
|
|
@@ -149,7 +149,7 @@ export default {
|
|
|
149
149
|
<template #cell:explorer="{row}">
|
|
150
150
|
<span v-if="row.mgmt && row.mgmt.isHarvester"></span>
|
|
151
151
|
<n-link
|
|
152
|
-
v-else-if="row.mgmt && row.mgmt.isReady"
|
|
152
|
+
v-else-if="row.mgmt && row.mgmt.isReady && !row.hasError"
|
|
153
153
|
data-testid="cluster-manager-list-explore-management"
|
|
154
154
|
class="btn btn-sm role-secondary"
|
|
155
155
|
:to="{name: 'c-cluster', params: {cluster: row.mgmt.id}}"
|
|
@@ -170,8 +170,10 @@ export default {
|
|
|
170
170
|
};
|
|
171
171
|
});
|
|
172
172
|
|
|
173
|
-
(res.namespaces.value.data || []).forEach((namespace) => {
|
|
174
|
-
|
|
173
|
+
(res.namespaces.value.data || []).forEach(async(namespace) => {
|
|
174
|
+
const proxyNamespace = await this.$store.dispatch('cluster/create', namespace);
|
|
175
|
+
|
|
176
|
+
if (!proxyNamespace.isSystem && namespace.links.update) {
|
|
175
177
|
const value = namespace.metadata.name;
|
|
176
178
|
const label = namespace.metadata.name;
|
|
177
179
|
|
|
@@ -519,7 +521,7 @@ export default {
|
|
|
519
521
|
:options="imageOptions"
|
|
520
522
|
:required="true"
|
|
521
523
|
:searchable="true"
|
|
522
|
-
:disabled="
|
|
524
|
+
:disabled="disabled"
|
|
523
525
|
label-key="cluster.credential.harvester.image"
|
|
524
526
|
:placeholder="t('cluster.harvester.machinePool.image.placeholder')"
|
|
525
527
|
@on-open="onOpen"
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import SteveModel from '@shell/plugins/steve/steve-class';
|
|
2
|
+
|
|
3
|
+
const CACHED_STATUS = 'cached';
|
|
4
|
+
|
|
5
|
+
export default class UIPlugin extends SteveModel {
|
|
6
|
+
get name() {
|
|
7
|
+
return this.spec?.plugin?.name;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
get description() {
|
|
11
|
+
return this.spec?.plugin?.description;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
get version() {
|
|
15
|
+
return this.spec?.plugin?.version;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
get willBeCached() {
|
|
19
|
+
return this.spec?.plugin?.noCache === false;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Has the plugin been cached?
|
|
23
|
+
get isCached() {
|
|
24
|
+
return !this.willBeCached || (this.willBeCached && this.status?.cacheState === CACHED_STATUS);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
get pluginMetadata() {
|
|
28
|
+
return this.spec?.plugin?.metadata || {};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
get isDeveloper() {
|
|
32
|
+
return this.pluginMetadata?.developer === 'true';
|
|
33
|
+
}
|
|
34
|
+
}
|
package/models/cluster/node.js
CHANGED
|
@@ -153,6 +153,14 @@ export default class ClusterNode extends SteveModel {
|
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
get cpuUsage() {
|
|
156
|
+
/*
|
|
157
|
+
With EKS nodes that have been migrated from norman,
|
|
158
|
+
cpu/memory usage is by the annotation `management.cattle.io/pod-requests`
|
|
159
|
+
*/
|
|
160
|
+
if ( this.isFromNorman && this.provider === 'eks' ) {
|
|
161
|
+
return parseSi(this.podRequests.cpu || '0');
|
|
162
|
+
}
|
|
163
|
+
|
|
156
164
|
return parseSi(this.$rootGetters['cluster/byId'](METRIC.NODE, this.id)?.usage?.cpu || '0');
|
|
157
165
|
}
|
|
158
166
|
|
|
@@ -165,6 +173,10 @@ export default class ClusterNode extends SteveModel {
|
|
|
165
173
|
}
|
|
166
174
|
|
|
167
175
|
get ramUsage() {
|
|
176
|
+
if ( this.isFromNorman && this.provider === 'eks' ) {
|
|
177
|
+
return parseSi(this.podRequests.memory || '0');
|
|
178
|
+
}
|
|
179
|
+
|
|
168
180
|
return parseSi(this.$rootGetters['cluster/byId'](METRIC.NODE, this.id)?.usage?.memory || '0');
|
|
169
181
|
}
|
|
170
182
|
|
|
@@ -192,6 +204,10 @@ export default class ClusterNode extends SteveModel {
|
|
|
192
204
|
return this.pods.length;
|
|
193
205
|
}
|
|
194
206
|
|
|
207
|
+
get podRequests() {
|
|
208
|
+
return JSON.parse(this.metadata.annotations['management.cattle.io/pod-requests'] || '{}');
|
|
209
|
+
}
|
|
210
|
+
|
|
195
211
|
get isPidPressureOk() {
|
|
196
212
|
return this.isCondition('PIDPressure', 'False');
|
|
197
213
|
}
|
|
@@ -368,14 +384,13 @@ export default class ClusterNode extends SteveModel {
|
|
|
368
384
|
}
|
|
369
385
|
|
|
370
386
|
get canDelete() {
|
|
371
|
-
const provider = this.$rootGetters['currentCluster'].provisioner.toLowerCase();
|
|
372
387
|
const cloudProviders = [
|
|
373
388
|
'aks', 'azureaks', 'azurekubernetesservice',
|
|
374
389
|
'eks', 'amazoneks',
|
|
375
390
|
'gke', 'googlegke'
|
|
376
391
|
];
|
|
377
392
|
|
|
378
|
-
return !cloudProviders.includes(provider);
|
|
393
|
+
return !cloudProviders.includes(this.provider);
|
|
379
394
|
}
|
|
380
395
|
|
|
381
396
|
// You need to preload CAPI.MACHINEs to use this
|
|
@@ -389,6 +404,14 @@ export default class ClusterNode extends SteveModel {
|
|
|
389
404
|
|
|
390
405
|
return null;
|
|
391
406
|
}
|
|
407
|
+
|
|
408
|
+
get isFromNorman() {
|
|
409
|
+
return (this.$rootGetters['currentCluster'].metadata.labels || {})['cattle.io/creator'] === 'norman';
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
get provider() {
|
|
413
|
+
return this.$rootGetters['currentCluster'].provisioner.toLowerCase();
|
|
414
|
+
}
|
|
392
415
|
}
|
|
393
416
|
|
|
394
417
|
function calculatePercentage(allocatable, capacity) {
|
|
@@ -79,11 +79,11 @@ export default class HciCluster extends ProvCluster {
|
|
|
79
79
|
const pkgName = `${ HARVESTER_NAME }-1.0.3`;
|
|
80
80
|
|
|
81
81
|
if (uiOfflinePreferred === 'true') {
|
|
82
|
-
// Embedded (aka give me the
|
|
83
|
-
const embeddedPath =
|
|
82
|
+
// Embedded (aka give me the embedded plugin that was in the last rancher release)
|
|
83
|
+
const embeddedPath = `${ pkgName }/${ pkgName }.umd.min.js`;
|
|
84
84
|
|
|
85
85
|
return {
|
|
86
|
-
pkgUrl: process.env.dev ? `${ process.env.api }/${ embeddedPath }` : embeddedPath,
|
|
86
|
+
pkgUrl: process.env.dev ? `${ process.env.api }/dashboard/${ embeddedPath }` : embeddedPath,
|
|
87
87
|
pkgName
|
|
88
88
|
};
|
|
89
89
|
}
|
|
@@ -111,15 +111,21 @@ export default class HciCluster extends ProvCluster {
|
|
|
111
111
|
* Determine the harvester plugin's package name and url for clusters that provide the plugin
|
|
112
112
|
*/
|
|
113
113
|
_supportedClusterPkgDetails(uiInfo, clusterId) {
|
|
114
|
-
|
|
114
|
+
let pkgName = `${ HARVESTER_NAME }-${ uiInfo['ui-plugin-bundled-version'] }`;
|
|
115
115
|
const fileName = `${ pkgName }.umd.min.js`;
|
|
116
116
|
let pkgUrl;
|
|
117
117
|
|
|
118
118
|
if (uiInfo['ui-source'] === 'bundled' ) { // offline bundled
|
|
119
|
-
pkgUrl =
|
|
119
|
+
pkgUrl = `/k8s/clusters/${ clusterId }/v1/harvester/plugin-assets/${ fileName }`;
|
|
120
120
|
} else if (uiInfo['ui-source'] === 'external') {
|
|
121
121
|
if (uiInfo['ui-plugin-index']) {
|
|
122
122
|
pkgUrl = uiInfo['ui-plugin-index'];
|
|
123
|
+
|
|
124
|
+
// When using an external address, the pkgName should also be get from the url
|
|
125
|
+
const names = pkgUrl.split('/');
|
|
126
|
+
const jsName = names[names.length - 1];
|
|
127
|
+
|
|
128
|
+
pkgName = jsName?.split('.umd.min.js')[0];
|
|
123
129
|
} else {
|
|
124
130
|
throw new Error('Harvester cluster requested the plugin at `ui-plugin-index` is used, however did not provide a value for it');
|
|
125
131
|
}
|
|
@@ -197,12 +197,10 @@ export default class ProvCluster extends SteveModel {
|
|
|
197
197
|
return super.canEditYaml;
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
-
get
|
|
201
|
-
|
|
202
|
-
}
|
|
200
|
+
get isHostedKubernetesProvider() {
|
|
201
|
+
const providers = ['AKS', 'EKS', 'GKE'];
|
|
203
202
|
|
|
204
|
-
|
|
205
|
-
return this.provisioner === 'EKS';
|
|
203
|
+
return providers.includes(this.provisioner);
|
|
206
204
|
}
|
|
207
205
|
|
|
208
206
|
get isImported() {
|
|
@@ -230,13 +228,17 @@ export default class ProvCluster extends SteveModel {
|
|
|
230
228
|
get isImportedK3s() {
|
|
231
229
|
// As of Rancher v2.6.7, this returns false for imported K3s clusters,
|
|
232
230
|
// in which this.provisioner is `k3s`.
|
|
233
|
-
return this.isImported && this.
|
|
231
|
+
return this.isImported && this.isK3s;
|
|
234
232
|
}
|
|
235
233
|
|
|
236
234
|
get isImportedRke2() {
|
|
237
235
|
return this.isImported && this.mgmt?.status?.provider?.startsWith('rke2');
|
|
238
236
|
}
|
|
239
237
|
|
|
238
|
+
get isK3s() {
|
|
239
|
+
return this.mgmt?.status?.provider === 'k3s';
|
|
240
|
+
}
|
|
241
|
+
|
|
240
242
|
get isRke2() {
|
|
241
243
|
return !!this.spec?.rkeConfig;
|
|
242
244
|
}
|
|
@@ -764,4 +766,8 @@ export default class ProvCluster extends SteveModel {
|
|
|
764
766
|
await this.$dispatch('ws.resource.remove', { data: this });
|
|
765
767
|
}
|
|
766
768
|
}
|
|
769
|
+
|
|
770
|
+
get hasError() {
|
|
771
|
+
return this.status?.conditions?.some(condition => condition.error === true);
|
|
772
|
+
}
|
|
767
773
|
}
|
package/models/workload.js
CHANGED
|
@@ -218,7 +218,7 @@ export default class Workload extends WorkloadService {
|
|
|
218
218
|
path: 'metadata.name',
|
|
219
219
|
required: true,
|
|
220
220
|
translationKey: 'generic.name',
|
|
221
|
-
type: '
|
|
221
|
+
type: 'subDomain',
|
|
222
222
|
},
|
|
223
223
|
{
|
|
224
224
|
nullable: false,
|
|
@@ -405,7 +405,7 @@ export default class Workload extends WorkloadService {
|
|
|
405
405
|
case WORKLOAD_TYPES.CRON_JOB:
|
|
406
406
|
out.push(detailItem.endpoint);
|
|
407
407
|
break;
|
|
408
|
-
case
|
|
408
|
+
case POD:
|
|
409
409
|
out.push(detailItem.ready);
|
|
410
410
|
break;
|
|
411
411
|
default: break;
|
|
@@ -612,8 +612,10 @@ export default class Workload extends WorkloadService {
|
|
|
612
612
|
|
|
613
613
|
async matchingPods() {
|
|
614
614
|
const all = await this.$dispatch('findAll', { type: POD });
|
|
615
|
+
const allInNamespace = all.filter(pod => pod.metadata.namespace === this.metadata.namespace);
|
|
616
|
+
|
|
615
617
|
const selector = convertSelectorObj(this.spec.selector);
|
|
616
618
|
|
|
617
|
-
return matching(
|
|
619
|
+
return matching(allInNamespace, selector);
|
|
618
620
|
}
|
|
619
621
|
}
|
package/nuxt.config.js
CHANGED
|
@@ -185,8 +185,6 @@ export default function(dir, _appConfig) {
|
|
|
185
185
|
|
|
186
186
|
// Serve up the dist-pkg folder under /pkg
|
|
187
187
|
serverMiddleware.push({ path: `/pkg/`, handler: serveStatic(`${ dir }/dist-pkg/`) });
|
|
188
|
-
// Endpoint to download and unpack a tgz from the local verdaccio rgistry (dev)
|
|
189
|
-
serverMiddleware.push(path.resolve(dir, SHELL, 'server', 'verdaccio-middleware'));
|
|
190
188
|
// Add the standard dashboard server middleware after the middleware added to serve up UI packages
|
|
191
189
|
serverMiddleware.push(path.resolve(dir, SHELL, 'server', 'server-middleware'));
|
|
192
190
|
|
|
@@ -202,6 +200,8 @@ export default function(dir, _appConfig) {
|
|
|
202
200
|
process.env.DRONE_VERSION ||
|
|
203
201
|
require('./package.json').version;
|
|
204
202
|
|
|
203
|
+
const prime = process.env.PRIME;
|
|
204
|
+
|
|
205
205
|
const dev = (process.env.NODE_ENV !== 'production');
|
|
206
206
|
const devPorts = dev || process.env.DEV_PORTS === 'true';
|
|
207
207
|
const pl = process.env.PL || STANDARD;
|
|
@@ -496,7 +496,8 @@ export default function(dir, _appConfig) {
|
|
|
496
496
|
plugins: [
|
|
497
497
|
// TODO: Browser support
|
|
498
498
|
// ['@babel/plugin-transform-modules-commonjs'],
|
|
499
|
-
['@babel/plugin-proposal-private-property-in-object', { loose: true }]
|
|
499
|
+
['@babel/plugin-proposal-private-property-in-object', { loose: true }],
|
|
500
|
+
'babel-plugin-istanbul'
|
|
500
501
|
],
|
|
501
502
|
}
|
|
502
503
|
},
|
|
@@ -554,7 +555,7 @@ export default function(dir, _appConfig) {
|
|
|
554
555
|
plugins: [
|
|
555
556
|
// Extensions
|
|
556
557
|
path.relative(dir, path.join(SHELL, 'core/plugins.js')),
|
|
557
|
-
path.relative(dir, path.join(SHELL, 'core/plugins-loader.js')),
|
|
558
|
+
path.relative(dir, path.join(SHELL, 'core/plugins-loader.js')), // Load builtin plugins
|
|
558
559
|
|
|
559
560
|
// Third-party
|
|
560
561
|
path.join(NUXT_SHELL, 'plugins/axios'),
|
|
@@ -578,33 +579,33 @@ export default function(dir, _appConfig) {
|
|
|
578
579
|
{ src: path.join(NUXT_SHELL, 'plugins/nuxt-client-init'), ssr: false },
|
|
579
580
|
path.join(NUXT_SHELL, 'plugins/replaceall'),
|
|
580
581
|
path.join(NUXT_SHELL, 'plugins/back-button'),
|
|
581
|
-
{ src: path.join(NUXT_SHELL, 'plugins/plugin'), ssr: false },
|
|
582
|
+
{ src: path.join(NUXT_SHELL, 'plugins/plugin'), ssr: false }, // Load dyanmic plugins
|
|
582
583
|
{ src: path.join(NUXT_SHELL, 'plugins/codemirror-loader'), ssr: false },
|
|
584
|
+
{ src: path.join(NUXT_SHELL, 'plugins/formatters'), ssr: false }, // Populate formatters cache for sorted table
|
|
583
585
|
],
|
|
584
586
|
|
|
585
587
|
// Proxy: https://github.com/nuxt-community/proxy-module#options
|
|
586
588
|
proxy: {
|
|
587
|
-
'/k8s':
|
|
588
|
-
'/pp':
|
|
589
|
-
'/api':
|
|
590
|
-
'/apis':
|
|
591
|
-
'/v1':
|
|
592
|
-
'/v3':
|
|
593
|
-
'/v3-public':
|
|
594
|
-
'/api-ui':
|
|
595
|
-
'/meta':
|
|
596
|
-
'/
|
|
589
|
+
'/k8s': proxyWsOpts(api), // Straight to a remote cluster (/k8s/clusters/<id>/)
|
|
590
|
+
'/pp': proxyWsOpts(api), // For (epinio) standalone API
|
|
591
|
+
'/api': proxyWsOpts(api), // Management k8s API
|
|
592
|
+
'/apis': proxyWsOpts(api), // Management k8s API
|
|
593
|
+
'/v1': proxyWsOpts(api), // Management Steve API
|
|
594
|
+
'/v3': proxyWsOpts(api), // Rancher API
|
|
595
|
+
'/v3-public': proxyOpts(api), // Rancher Unauthed API
|
|
596
|
+
'/api-ui': proxyOpts(api), // Browser API UI
|
|
597
|
+
'/meta': proxyMetaOpts(api), // Browser API UI
|
|
598
|
+
'/rancherversion': proxyPrimeOpts(api), // Rancher version endpoint
|
|
599
|
+
'/v1-*': proxyOpts(api), // SAML, KDM, etc
|
|
597
600
|
// These are for Ember embedding
|
|
598
|
-
'/c/*/edit':
|
|
599
|
-
'/k/':
|
|
600
|
-
'/g/':
|
|
601
|
-
'/n/':
|
|
602
|
-
'/p/':
|
|
603
|
-
'/assets':
|
|
604
|
-
'/translations':
|
|
605
|
-
'/engines-dist':
|
|
606
|
-
// Plugin dev
|
|
607
|
-
'/verdaccio/': proxyOpts('http://127.0.0.1:4873/-'),
|
|
601
|
+
'/c/*/edit': proxyOpts('https://127.0.0.1:8000'), // Can't proxy all of /c because that's used by Vue too
|
|
602
|
+
'/k/': proxyOpts('https://127.0.0.1:8000'),
|
|
603
|
+
'/g/': proxyOpts('https://127.0.0.1:8000'),
|
|
604
|
+
'/n/': proxyOpts('https://127.0.0.1:8000'),
|
|
605
|
+
'/p/': proxyOpts('https://127.0.0.1:8000'),
|
|
606
|
+
'/assets': proxyOpts('https://127.0.0.1:8000'),
|
|
607
|
+
'/translations': proxyOpts('https://127.0.0.1:8000'),
|
|
608
|
+
'/engines-dist': proxyOpts('https://127.0.0.1:8000'),
|
|
608
609
|
},
|
|
609
610
|
|
|
610
611
|
// Nuxt server
|
|
@@ -663,6 +664,49 @@ export default function(dir, _appConfig) {
|
|
|
663
664
|
};
|
|
664
665
|
}
|
|
665
666
|
|
|
667
|
+
// Intercept the /rancherversion API call wnad modify the 'RancherPrime' value
|
|
668
|
+
// if configured to do so by the environment variable PRIME
|
|
669
|
+
function proxyPrimeOpts(target) {
|
|
670
|
+
const opts = proxyOpts(target);
|
|
671
|
+
|
|
672
|
+
// Don't intercept if the PRIME environment variable is not set
|
|
673
|
+
if (!prime?.length) {
|
|
674
|
+
return opts;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
opts.onProxyRes = (proxyRes, req, res) => {
|
|
678
|
+
const _end = res.end;
|
|
679
|
+
let body = '';
|
|
680
|
+
|
|
681
|
+
proxyRes.on( 'data', (data) => {
|
|
682
|
+
data = data.toString('utf-8');
|
|
683
|
+
body += data;
|
|
684
|
+
});
|
|
685
|
+
|
|
686
|
+
res.write = () => {};
|
|
687
|
+
|
|
688
|
+
res.end = () => {
|
|
689
|
+
let output = body;
|
|
690
|
+
|
|
691
|
+
try {
|
|
692
|
+
const out = JSON.parse(body);
|
|
693
|
+
|
|
694
|
+
out.RancherPrime = prime;
|
|
695
|
+
output = JSON.stringify(out);
|
|
696
|
+
} catch (err) {}
|
|
697
|
+
|
|
698
|
+
res.setHeader('content-length', output.length );
|
|
699
|
+
res.setHeader('content-type', 'application/json' );
|
|
700
|
+
res.setHeader('transfer-encoding', '');
|
|
701
|
+
res.setHeader('cache-control', 'no-cache');
|
|
702
|
+
res.writeHead(proxyRes.statusCode);
|
|
703
|
+
_end.apply(res, [output]);
|
|
704
|
+
};
|
|
705
|
+
};
|
|
706
|
+
|
|
707
|
+
return opts;
|
|
708
|
+
}
|
|
709
|
+
|
|
666
710
|
function onProxyRes(proxyRes, req, res) {
|
|
667
711
|
if (devPorts) {
|
|
668
712
|
proxyRes.headers['X-Frame-Options'] = 'ALLOWALL';
|