@rancher/shell 3.0.9 → 3.0.11
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/base/_color.scss +4 -0
- package/assets/styles/themes/_light.scss +6 -6
- package/assets/styles/themes/_modern.scss +14 -6
- package/assets/translations/en-us.yaml +9 -10
- package/chart/__tests__/rancher-backup-index.test.ts +248 -0
- package/chart/rancher-backup/index.vue +41 -2
- package/components/BrandImage.vue +6 -5
- package/components/ConsumptionGauge.vue +12 -4
- package/components/CopyToClipboard.vue +28 -0
- package/components/CopyToClipboardText.vue +4 -0
- package/components/CruResource.vue +1 -0
- package/components/DynamicContent/DynamicContentIcon.vue +3 -2
- package/components/ExplorerProjectsNamespaces.vue +1 -4
- package/components/GlobalRoleBindings.vue +1 -5
- package/components/LazyImage.vue +2 -1
- package/components/Resource/Detail/Card/Scaler.vue +4 -4
- package/components/ResourceDetail/index.vue +0 -21
- package/components/Tabbed/index.vue +6 -0
- package/components/__tests__/ConsumptionGauge.test.ts +31 -0
- package/components/__tests__/CruResource.test.ts +35 -1
- package/components/form/ProjectMemberEditor.vue +0 -10
- package/components/nav/TopLevelMenu.helper.ts +7 -79
- package/components/nav/__tests__/TopLevelMenu.helper.test.ts +2 -53
- package/composables/useIsNewDetailPageEnabled.test.ts +98 -0
- package/composables/useIsNewDetailPageEnabled.ts +12 -0
- package/config/private-label.js +2 -1
- package/config/product/apps.js +1 -0
- package/config/product/explorer.js +11 -1
- package/config/table-headers.js +0 -9
- package/config/types.js +0 -1
- package/core/__tests__/extension-manager-impl.test.js +187 -2
- package/core/extension-manager-impl.js +4 -2
- package/core/plugin-helpers.ts +31 -0
- package/detail/__tests__/node.test.ts +83 -0
- package/detail/management.cattle.io.oidcclient.vue +2 -1
- package/detail/node.vue +1 -0
- package/edit/auth/github-app-steps.vue +2 -0
- package/edit/auth/github-steps.vue +2 -0
- package/edit/catalog.cattle.io.clusterrepo.vue +17 -3
- package/edit/cloudcredential.vue +2 -1
- package/edit/management.cattle.io.user.vue +60 -35
- package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +11 -6
- package/edit/provisioning.cattle.io.cluster/index.vue +5 -4
- package/edit/provisioning.cattle.io.cluster/shared.ts +4 -2
- package/edit/secret/generic.vue +1 -0
- package/edit/secret/index.vue +2 -1
- package/edit/service.vue +2 -14
- package/edit/token.vue +29 -68
- package/list/management.cattle.io.feature.vue +7 -1
- package/list/provisioning.cattle.io.cluster.vue +0 -49
- package/mixins/brand.js +2 -1
- package/models/catalog.cattle.io.clusterrepo.js +9 -0
- package/models/cluster.x-k8s.io.machinedeployment.js +8 -3
- package/models/management.cattle.io.authconfig.js +2 -1
- package/models/management.cattle.io.cluster.js +4 -3
- package/models/monitoring.coreos.com.receiver.js +11 -6
- package/models/provisioning.cattle.io.cluster.js +2 -2
- package/models/token.js +0 -4
- package/package.json +12 -12
- package/pages/account/index.vue +67 -96
- package/pages/c/_cluster/apps/charts/AppChartCardFooter.vue +66 -9
- package/pages/c/_cluster/apps/charts/index.vue +3 -8
- package/pages/c/_cluster/apps/charts/install.vue +8 -9
- package/pages/c/_cluster/explorer/index.vue +2 -19
- package/pages/c/_cluster/istio/index.vue +4 -2
- package/pages/c/_cluster/longhorn/index.vue +2 -1
- package/pages/c/_cluster/monitoring/index.vue +2 -2
- package/pages/c/_cluster/neuvector/index.vue +2 -1
- package/pages/c/_cluster/settings/performance.vue +0 -5
- package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +2 -1
- package/pages/c/_cluster/uiplugins/index.vue +2 -1
- package/pkg/auto-import.js +41 -0
- package/plugins/dashboard-store/resource-class.js +2 -2
- package/plugins/steve/__tests__/steve-class.test.ts +1 -1
- package/plugins/steve/steve-class.js +3 -3
- package/plugins/steve/steve-pagination-utils.ts +2 -5
- package/plugins/steve/subscribe.js +29 -4
- package/rancher-components/Pill/RcCounterBadge/RcCounterBadge.vue +7 -7
- package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.vue +5 -2
- package/rancher-components/RcButton/RcButton.vue +3 -3
- package/rancher-components/RcButtonSplit/RcButtonSplit.test.ts +253 -0
- package/rancher-components/RcButtonSplit/RcButtonSplit.vue +158 -0
- package/rancher-components/RcButtonSplit/index.ts +1 -0
- package/rancher-components/RcIcon/types.ts +2 -2
- package/rancher-components/RcSection/RcSection.test.ts +323 -0
- package/rancher-components/RcSection/RcSection.vue +252 -0
- package/rancher-components/RcSection/RcSectionActions.test.ts +212 -0
- package/rancher-components/RcSection/RcSectionActions.vue +85 -0
- package/rancher-components/RcSection/RcSectionBadges.test.ts +149 -0
- package/rancher-components/RcSection/RcSectionBadges.vue +29 -0
- package/rancher-components/RcSection/index.ts +12 -0
- package/rancher-components/RcSection/types.ts +86 -0
- package/scripts/test-plugins-build.sh +9 -8
- package/types/shell/index.d.ts +93 -108
- package/utils/__tests__/require-asset.test.ts +98 -0
- package/utils/async.ts +1 -5
- package/utils/brand.ts +3 -1
- package/utils/favicon.js +4 -3
- package/utils/require-asset.ts +95 -0
- package/utils/style.ts +17 -0
- package/utils/units.js +14 -5
- package/vue.config.js +4 -3
- package/components/HarvesterServiceAddOnConfig.vue +0 -207
- package/models/ext.cattle.io.token.js +0 -48
|
@@ -13,6 +13,11 @@ import ButtonDropdown from '@shell/components/ButtonDropdown';
|
|
|
13
13
|
import { _CREATE, _VIEW } from '@shell/config/query-params';
|
|
14
14
|
import FormValidation from '@shell/mixins/form-validation';
|
|
15
15
|
import { fetchAlertManagerConfigSpecs } from '@shell/utils/alertmanagerconfig';
|
|
16
|
+
import slackLogo from '@shell/assets/images/vendor/slack.svg';
|
|
17
|
+
import emailLogo from '@shell/assets/images/vendor/email.svg';
|
|
18
|
+
import pagerdutyLogo from '@shell/assets/images/vendor/pagerduty.svg';
|
|
19
|
+
import webhookLogo from '@shell/assets/images/vendor/webhook.svg';
|
|
20
|
+
import customLogo from '@shell/assets/images/vendor/custom.svg';
|
|
16
21
|
|
|
17
22
|
// i18n-uses monitoringReceiver.slack.*, monitoringReceiver.email.*, monitoringReceiver.pagerduty.*
|
|
18
23
|
// i18n-uses monitoringReceiver.opsgenie.*, monitoringReceiver.webhook.*, monitoringReceiver.custom.*
|
|
@@ -23,14 +28,14 @@ export const RECEIVERS_TYPES = [
|
|
|
23
28
|
title: 'monitoringReceiver.slack.title',
|
|
24
29
|
info: 'monitoringReceiver.slack.info',
|
|
25
30
|
key: 'slackConfigs',
|
|
26
|
-
logo:
|
|
31
|
+
logo: slackLogo
|
|
27
32
|
},
|
|
28
33
|
{
|
|
29
34
|
name: 'email',
|
|
30
35
|
label: 'monitoringReceiver.email.label',
|
|
31
36
|
title: 'monitoringReceiver.email.title',
|
|
32
37
|
key: 'emailConfigs',
|
|
33
|
-
logo:
|
|
38
|
+
logo: emailLogo
|
|
34
39
|
},
|
|
35
40
|
{
|
|
36
41
|
name: 'pagerduty',
|
|
@@ -38,21 +43,21 @@ export const RECEIVERS_TYPES = [
|
|
|
38
43
|
title: 'monitoringReceiver.pagerduty.title',
|
|
39
44
|
info: 'monitoringReceiver.pagerduty.info',
|
|
40
45
|
key: 'pagerdutyConfigs',
|
|
41
|
-
logo:
|
|
46
|
+
logo: pagerdutyLogo
|
|
42
47
|
},
|
|
43
48
|
{
|
|
44
49
|
name: 'opsgenie',
|
|
45
50
|
label: 'monitoringReceiver.opsgenie.label',
|
|
46
51
|
title: 'monitoringReceiver.opsgenie.title',
|
|
47
52
|
key: 'opsgenieConfigs',
|
|
48
|
-
logo:
|
|
53
|
+
logo: emailLogo
|
|
49
54
|
},
|
|
50
55
|
{
|
|
51
56
|
name: 'webhook',
|
|
52
57
|
label: 'monitoringReceiver.webhook.label',
|
|
53
58
|
title: 'monitoringReceiver.webhook.title',
|
|
54
59
|
key: 'webhookConfigs',
|
|
55
|
-
logo:
|
|
60
|
+
logo: webhookLogo,
|
|
56
61
|
},
|
|
57
62
|
{
|
|
58
63
|
name: 'custom',
|
|
@@ -60,7 +65,7 @@ export const RECEIVERS_TYPES = [
|
|
|
60
65
|
title: 'monitoringReceiver.custom.title',
|
|
61
66
|
info: 'monitoringReceiver.custom.info',
|
|
62
67
|
key: 'webhookConfigs',
|
|
63
|
-
logo:
|
|
68
|
+
logo: customLogo
|
|
64
69
|
},
|
|
65
70
|
];
|
|
66
71
|
|
|
@@ -20,6 +20,7 @@ import { BLANK_CLUSTER } from '@shell/store/store-types.js';
|
|
|
20
20
|
import { ELEMENTAL_PRODUCT_NAME, ELEMENTAL_CLUSTER_PROVIDER } from '../../config/elemental-types';
|
|
21
21
|
import Rke2Config from './rke2';
|
|
22
22
|
import { DRIVER_TO_IMPORT } from '@shell/models/management.cattle.io.kontainerdriver';
|
|
23
|
+
import { requireAsset } from '@shell/utils/require-asset';
|
|
23
24
|
|
|
24
25
|
const SORT_GROUPS = {
|
|
25
26
|
template: 1,
|
|
@@ -343,7 +344,7 @@ export default {
|
|
|
343
344
|
id: `chart:${ chart.id }`,
|
|
344
345
|
label: chart.chartNameDisplay,
|
|
345
346
|
description: chart.chartDescription,
|
|
346
|
-
icon: chart.icon ||
|
|
347
|
+
icon: chart.icon || requireAsset('~shell/assets/images/generic-catalog.svg'),
|
|
347
348
|
group: 'template',
|
|
348
349
|
tag: getters['i18n/t']('generic.techPreview')
|
|
349
350
|
});
|
|
@@ -389,7 +390,7 @@ export default {
|
|
|
389
390
|
if (icon) {
|
|
390
391
|
iconClass = undefined;
|
|
391
392
|
} else if (!iconClass) {
|
|
392
|
-
icon =
|
|
393
|
+
icon = requireAsset('~shell/assets/images/generic-driver.svg');
|
|
393
394
|
}
|
|
394
395
|
|
|
395
396
|
const subtype = {
|
|
@@ -420,14 +421,14 @@ export default {
|
|
|
420
421
|
|
|
421
422
|
if (!icon) {
|
|
422
423
|
try {
|
|
423
|
-
icon =
|
|
424
|
+
icon = requireAsset(`~shell/assets/images/providers/${ id }.svg`);
|
|
424
425
|
} catch (e) {}
|
|
425
426
|
}
|
|
426
427
|
|
|
427
428
|
if (icon) {
|
|
428
429
|
iconClass = undefined;
|
|
429
430
|
} else if (!iconClass) {
|
|
430
|
-
icon =
|
|
431
|
+
icon = requireAsset('~shell/assets/images/generic-driver.svg');
|
|
431
432
|
}
|
|
432
433
|
|
|
433
434
|
const subtype = {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { requireAsset } from '@shell/utils/require-asset';
|
|
2
|
+
|
|
1
3
|
export const RETENTION_DEFAULT = 5;
|
|
2
4
|
export const RKE2_INGRESS_NGINX = 'rke2-ingress-nginx';
|
|
3
5
|
export const RKE2_TRAEFIK = 'rke2-traefik';
|
|
@@ -10,7 +12,7 @@ export const INGRESS_NONE = 'none';
|
|
|
10
12
|
export const INGRESS_OPTIONS = [
|
|
11
13
|
{
|
|
12
14
|
id: TRAEFIK,
|
|
13
|
-
image: { src:
|
|
15
|
+
image: { src: requireAsset('@shell/assets/images/providers/traefik.png'), alt: 'Traefik' },
|
|
14
16
|
header: { title: { key: 'cluster.ingress.traefik.header' } },
|
|
15
17
|
subHeader: { label: { key: 'cluster.ingress.recommended' } },
|
|
16
18
|
content: { key: 'cluster.ingress.traefik.content' },
|
|
@@ -18,7 +20,7 @@ export const INGRESS_OPTIONS = [
|
|
|
18
20
|
},
|
|
19
21
|
{
|
|
20
22
|
id: INGRESS_NGINX,
|
|
21
|
-
image: { src:
|
|
23
|
+
image: { src: requireAsset('@shell/assets/images/providers/kubernetes.svg'), alt: 'NGINX' },
|
|
22
24
|
header: { title: { key: 'cluster.ingress.nginx.header' } },
|
|
23
25
|
subHeader: { label: { key: 'cluster.ingress.legacy' } },
|
|
24
26
|
content: { key: 'cluster.ingress.nginx.content' },
|
package/edit/secret/generic.vue
CHANGED
package/edit/secret/index.vue
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { SECRET_TYPES as TYPES } from '@shell/config/secret';
|
|
3
|
+
import { requireAsset } from '@shell/utils/require-asset';
|
|
3
4
|
import {
|
|
4
5
|
SECRET_SCOPE, SECRET_QUERY_PARAMS,
|
|
5
6
|
CLOUD_CREDENTIAL, _CLONE, _CREATE, _EDIT, _FLAGGED
|
|
@@ -211,7 +212,7 @@ export default {
|
|
|
211
212
|
let bannerImage, bannerAbbrv;
|
|
212
213
|
|
|
213
214
|
try {
|
|
214
|
-
bannerImage =
|
|
215
|
+
bannerImage = requireAsset(`~shell/assets/images/providers/${ id }.svg`);
|
|
215
216
|
} catch (e) {
|
|
216
217
|
bannerImage = null;
|
|
217
218
|
bannerAbbrv = this.initialDisplayFor(id);
|
package/edit/service.vue
CHANGED
|
@@ -18,7 +18,6 @@ import { ucFirst } from '@shell/utils/string';
|
|
|
18
18
|
import CruResource from '@shell/components/CruResource';
|
|
19
19
|
import { Banner } from '@components/Banner';
|
|
20
20
|
import Labels from '@shell/components/form/Labels';
|
|
21
|
-
import HarvesterServiceAddOnConfig from '@shell/components/HarvesterServiceAddOnConfig';
|
|
22
21
|
import { clone } from '@shell/utils/object';
|
|
23
22
|
import { POD, CAPI, HCI } from '@shell/config/types';
|
|
24
23
|
import { matching } from '@shell/utils/selector-typed';
|
|
@@ -58,7 +57,6 @@ export default {
|
|
|
58
57
|
Tab,
|
|
59
58
|
Tabbed,
|
|
60
59
|
UnitInput,
|
|
61
|
-
HarvesterServiceAddOnConfig,
|
|
62
60
|
},
|
|
63
61
|
|
|
64
62
|
mixins: [CreateEditView, FormValidation],
|
|
@@ -350,8 +348,10 @@ export default {
|
|
|
350
348
|
|
|
351
349
|
<Tabbed
|
|
352
350
|
:side-tabs="true"
|
|
351
|
+
:resource="value"
|
|
353
352
|
:use-hash="useTabbedHash"
|
|
354
353
|
:default-tab="defaultTab"
|
|
354
|
+
:extension-params="{ showHarvesterAddOnConfig: String(showHarvesterAddOnConfig) }"
|
|
355
355
|
>
|
|
356
356
|
<Tab
|
|
357
357
|
v-if="checkTypeIs('ExternalName')"
|
|
@@ -471,18 +471,6 @@ export default {
|
|
|
471
471
|
</div>
|
|
472
472
|
</div>
|
|
473
473
|
</Tab>
|
|
474
|
-
<Tab
|
|
475
|
-
v-if="showHarvesterAddOnConfig"
|
|
476
|
-
name="add-on-config"
|
|
477
|
-
:label="t('servicesPage.harvester.title')"
|
|
478
|
-
:weight="-1"
|
|
479
|
-
>
|
|
480
|
-
<HarvesterServiceAddOnConfig
|
|
481
|
-
:mode="mode"
|
|
482
|
-
:value="value"
|
|
483
|
-
:register-before-hook="registerBeforeHook"
|
|
484
|
-
/>
|
|
485
|
-
</Tab>
|
|
486
474
|
<Tab
|
|
487
475
|
v-if="!checkTypeIs('ExternalName') && !checkTypeIs('Headless')"
|
|
488
476
|
name="session-affinity"
|
package/edit/token.vue
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { mapGetters } from 'vuex';
|
|
3
3
|
import day from 'dayjs';
|
|
4
4
|
import sortBy from 'lodash/sortBy';
|
|
5
|
-
import { MANAGEMENT,
|
|
5
|
+
import { MANAGEMENT, NORMAN } from '@shell/config/types';
|
|
6
6
|
import { Banner } from '@components/Banner';
|
|
7
7
|
import DetailText from '@shell/components/DetailText';
|
|
8
8
|
import Footer from '@shell/components/form/Footer';
|
|
@@ -14,7 +14,6 @@ import CreateEditView from '@shell/mixins/create-edit-view';
|
|
|
14
14
|
import { diffFrom } from '@shell/utils/time';
|
|
15
15
|
import { filterHiddenLocalCluster, filterOnlyKubernetesClusters } from '@shell/utils/cluster';
|
|
16
16
|
import { SETTING } from '@shell/config/settings';
|
|
17
|
-
import Checkbox from '@components/Form/Checkbox/Checkbox.vue';
|
|
18
17
|
|
|
19
18
|
export default {
|
|
20
19
|
components: {
|
|
@@ -25,7 +24,6 @@ export default {
|
|
|
25
24
|
LabeledSelect,
|
|
26
25
|
RadioGroup,
|
|
27
26
|
Select,
|
|
28
|
-
Checkbox,
|
|
29
27
|
},
|
|
30
28
|
|
|
31
29
|
mixins: [CreateEditView],
|
|
@@ -43,11 +41,7 @@ export default {
|
|
|
43
41
|
|
|
44
42
|
return {
|
|
45
43
|
errors: null,
|
|
46
|
-
user: null,
|
|
47
44
|
form: {
|
|
48
|
-
enabled: true,
|
|
49
|
-
description: '',
|
|
50
|
-
clusterName: '',
|
|
51
45
|
expiryType: 'never',
|
|
52
46
|
customExpiry: 0,
|
|
53
47
|
customExpiryUnits: 'minute',
|
|
@@ -57,13 +51,11 @@ export default {
|
|
|
57
51
|
accessKey: '',
|
|
58
52
|
secretKey: '',
|
|
59
53
|
maxTTL,
|
|
60
|
-
ttl: ''
|
|
61
54
|
};
|
|
62
55
|
},
|
|
63
56
|
|
|
64
57
|
computed: {
|
|
65
58
|
...mapGetters({ t: 'i18n/t' }),
|
|
66
|
-
|
|
67
59
|
scopes() {
|
|
68
60
|
const all = this.$store.getters['management/all'](MANAGEMENT.CLUSTER);
|
|
69
61
|
const kubeClusters = filterHiddenLocalCluster(filterOnlyKubernetesClusters(all, this.$store), this.$store);
|
|
@@ -79,20 +71,16 @@ export default {
|
|
|
79
71
|
const options = ['never', 'day', 'month', 'year', 'custom'];
|
|
80
72
|
let opts = options.map((opt) => ({ value: opt, label: this.t(`accountAndKeys.apiKeys.add.expiry.options.${ opt }`) }));
|
|
81
73
|
|
|
82
|
-
// When the TTL is
|
|
74
|
+
// When the TTL is anything other than 0, present only two options
|
|
83
75
|
// (1) The maximum allowed
|
|
84
76
|
// (2) Custom
|
|
85
|
-
if (this.maxTTL
|
|
77
|
+
if (this.maxTTL !== 0 ) {
|
|
86
78
|
const now = day();
|
|
87
79
|
const expiry = now.add(this.maxTTL, 'minute');
|
|
88
80
|
const max = diffFrom(expiry, now, this.t);
|
|
89
81
|
|
|
90
82
|
opts = opts.filter((opt) => opt.value === 'custom');
|
|
91
83
|
opts.unshift({ value: 'max', label: this.t('accountAndKeys.apiKeys.add.expiry.options.maximum', { value: max.string }) });
|
|
92
|
-
} else {
|
|
93
|
-
// maxTTL <= 0 means there is no maximum, so we can show the 'never' option which results in an infinite TTL
|
|
94
|
-
// OR if we set a positive TTL, then it assumes that value
|
|
95
|
-
opts = opts.filter((opt) => opt.value === 'never' || opt.value === 'custom');
|
|
96
84
|
}
|
|
97
85
|
|
|
98
86
|
return opts;
|
|
@@ -103,9 +91,6 @@ export default {
|
|
|
103
91
|
|
|
104
92
|
return filtered.map((opt) => ({ value: opt, label: this.t(`accountAndKeys.apiKeys.add.customExpiry.options.${ opt }`) }));
|
|
105
93
|
},
|
|
106
|
-
hasNeverOption() {
|
|
107
|
-
return this.expiryOptions?.filter((opt) => opt.value === 'never')?.length === 1;
|
|
108
|
-
}
|
|
109
94
|
},
|
|
110
95
|
|
|
111
96
|
mounted() {
|
|
@@ -130,33 +115,31 @@ export default {
|
|
|
130
115
|
});
|
|
131
116
|
},
|
|
132
117
|
|
|
133
|
-
async actuallySave() {
|
|
134
|
-
// update expiration value before save
|
|
118
|
+
async actuallySave(url) {
|
|
135
119
|
this.updateExpiry();
|
|
136
|
-
|
|
137
120
|
if ( this.isCreate ) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
ttl: this.ttl
|
|
147
|
-
// userID: not needed as it will be set by the backend to the current user
|
|
148
|
-
}
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
const steveTokenSaved = await steveToken.save();
|
|
152
|
-
|
|
153
|
-
this.created = steveTokenSaved;
|
|
154
|
-
this.ttlLimited = this.created?.spec?.ttl !== this.ttl;
|
|
155
|
-
const token = this.created?.status?.bearerToken?.split(':');
|
|
121
|
+
// Description is a bit weird, so need to clone and set this
|
|
122
|
+
// rather than use this.value - need to find a way to set this if we ever
|
|
123
|
+
// want to allow edit (which I don't think we do)
|
|
124
|
+
const res = await this.value.save();
|
|
125
|
+
|
|
126
|
+
this.created = res;
|
|
127
|
+
this.ttlLimited = res.ttl !== this.value.ttl;
|
|
128
|
+
const token = this.created.token.split(':');
|
|
156
129
|
|
|
157
130
|
this.accessKey = token[0];
|
|
158
131
|
this.secretKey = (token.length > 1) ? token[1] : '';
|
|
159
|
-
this.token = this.created
|
|
132
|
+
this.token = this.created.token;
|
|
133
|
+
|
|
134
|
+
// Force a refresh of the token so we get the expiry date correctly
|
|
135
|
+
await this.$store.dispatch('rancher/find', {
|
|
136
|
+
type: NORMAN.TOKEN,
|
|
137
|
+
id: res.id,
|
|
138
|
+
opt: { force: true }
|
|
139
|
+
}, { root: true });
|
|
140
|
+
} else {
|
|
141
|
+
// Note: update of existing key not supported currently
|
|
142
|
+
await this.value.save();
|
|
160
143
|
}
|
|
161
144
|
},
|
|
162
145
|
|
|
@@ -176,9 +159,7 @@ export default {
|
|
|
176
159
|
const units = (v === 'custom') ? this.form.customExpiryUnits : v;
|
|
177
160
|
let ttl = 0;
|
|
178
161
|
|
|
179
|
-
if (
|
|
180
|
-
ttl = -1;
|
|
181
|
-
} else if (units === 'max') {
|
|
162
|
+
if (units === 'max') {
|
|
182
163
|
ttl = this.maxTTL * 60 * 1000;
|
|
183
164
|
} else if ( units !== 'never' ) {
|
|
184
165
|
const now = day();
|
|
@@ -186,8 +167,7 @@ export default {
|
|
|
186
167
|
|
|
187
168
|
ttl = expiry.diff(now);
|
|
188
169
|
}
|
|
189
|
-
|
|
190
|
-
this.ttl = ttl;
|
|
170
|
+
this.value.ttl = ttl;
|
|
191
171
|
}
|
|
192
172
|
}
|
|
193
173
|
};
|
|
@@ -198,7 +178,7 @@ export default {
|
|
|
198
178
|
<div class="pl-10 pr-10">
|
|
199
179
|
<LabeledInput
|
|
200
180
|
key="description"
|
|
201
|
-
v-model:value="
|
|
181
|
+
v-model:value="value.description"
|
|
202
182
|
:placeholder="t('accountAndKeys.apiKeys.add.description.placeholder')"
|
|
203
183
|
label-key="accountAndKeys.apiKeys.add.description.label"
|
|
204
184
|
mode="edit"
|
|
@@ -206,30 +186,13 @@ export default {
|
|
|
206
186
|
/>
|
|
207
187
|
|
|
208
188
|
<LabeledSelect
|
|
209
|
-
v-model:value="
|
|
189
|
+
v-model:value="value.clusterId"
|
|
210
190
|
class="mt-20 scope-select"
|
|
211
191
|
label-key="accountAndKeys.apiKeys.add.scope"
|
|
212
192
|
:options="scopes"
|
|
213
193
|
/>
|
|
214
194
|
|
|
215
|
-
<
|
|
216
|
-
v-model:value="form.enabled"
|
|
217
|
-
class="mt-20 mb-20"
|
|
218
|
-
:mode="mode"
|
|
219
|
-
label-key="accountAndKeys.apiKeys.add.enabled"
|
|
220
|
-
/>
|
|
221
|
-
|
|
222
|
-
<Banner
|
|
223
|
-
v-if="hasNeverOption"
|
|
224
|
-
color="warning"
|
|
225
|
-
class="mt-20"
|
|
226
|
-
>
|
|
227
|
-
<div>
|
|
228
|
-
{{ t('accountAndKeys.apiKeys.info.expiryOptionsWithNever') }}
|
|
229
|
-
</div>
|
|
230
|
-
</Banner>
|
|
231
|
-
|
|
232
|
-
<h5 class="mb-20">
|
|
195
|
+
<h5 class="pt-20">
|
|
233
196
|
{{ t('accountAndKeys.apiKeys.add.expiry.label') }}
|
|
234
197
|
</h5>
|
|
235
198
|
|
|
@@ -241,9 +204,7 @@ export default {
|
|
|
241
204
|
class="mr-20"
|
|
242
205
|
name="expiryGroup"
|
|
243
206
|
/>
|
|
244
|
-
<div
|
|
245
|
-
class="ml-20 mt-10 expiry"
|
|
246
|
-
>
|
|
207
|
+
<div class="ml-20 mt-10 expiry">
|
|
247
208
|
<input
|
|
248
209
|
v-model="form.customExpiry"
|
|
249
210
|
:disabled="form.expiryType !== 'custom'"
|
|
@@ -3,6 +3,12 @@ import { mapGetters } from 'vuex';
|
|
|
3
3
|
import ResourceTable from '@shell/components/ResourceTable';
|
|
4
4
|
import { MANAGEMENT } from '@shell/config/types';
|
|
5
5
|
import ResourceFetch from '@shell/mixins/resource-fetch';
|
|
6
|
+
import { STEVE_CACHE } from '@shell/store/features';
|
|
7
|
+
|
|
8
|
+
const hideFeatureFlags = [
|
|
9
|
+
'fleet', // Note - this is the id of the ff we want, not sure what FLEET in store/features is
|
|
10
|
+
STEVE_CACHE
|
|
11
|
+
];
|
|
6
12
|
|
|
7
13
|
export default {
|
|
8
14
|
components: { ResourceTable },
|
|
@@ -32,7 +38,7 @@ export default {
|
|
|
32
38
|
...mapGetters({ t: 'i18n/t' }),
|
|
33
39
|
|
|
34
40
|
filteredRows() {
|
|
35
|
-
return this.rows.filter((x) => x.name
|
|
41
|
+
return this.rows.filter((x) => hideFeatureFlags.indexOf(x.metadata.name) === -1);
|
|
36
42
|
},
|
|
37
43
|
|
|
38
44
|
enableRowActions() {
|
|
@@ -167,12 +167,6 @@ export default {
|
|
|
167
167
|
|
|
168
168
|
},
|
|
169
169
|
|
|
170
|
-
methods: {
|
|
171
|
-
getCustomDetailLink(cluster) {
|
|
172
|
-
return cluster.isCapiHybrid ? null : cluster.detailLocation;
|
|
173
|
-
}
|
|
174
|
-
},
|
|
175
|
-
|
|
176
170
|
$loadingResources() {
|
|
177
171
|
// results are filtered so we wouldn't get the correct count on indicator...
|
|
178
172
|
return { loadIndeterminate: true };
|
|
@@ -226,7 +220,6 @@ export default {
|
|
|
226
220
|
:use-query-params-for-simple-filtering="useQueryParamsForSimpleFiltering"
|
|
227
221
|
:data-testid="'cluster-list'"
|
|
228
222
|
:force-update-live-and-delayed="forceUpdateLiveAndDelayed"
|
|
229
|
-
:get-custom-detail-link="getCustomDetailLink"
|
|
230
223
|
:sub-rows="true"
|
|
231
224
|
>
|
|
232
225
|
<!-- Why are state column and subrow overwritten here? -->
|
|
@@ -273,48 +266,6 @@ export default {
|
|
|
273
266
|
{{ t('cluster.explore') }}
|
|
274
267
|
</button>
|
|
275
268
|
</template>
|
|
276
|
-
<template #additional-sub-row="{row, fullColspan, tableActions}">
|
|
277
|
-
<tr
|
|
278
|
-
class="capi-unsupported"
|
|
279
|
-
:class="{'has-description': !!row.stateDescription}"
|
|
280
|
-
>
|
|
281
|
-
<td
|
|
282
|
-
v-if="row.isCapiHybrid"
|
|
283
|
-
class="row-check"
|
|
284
|
-
/>
|
|
285
|
-
<td
|
|
286
|
-
v-if="row.isCapiHybrid"
|
|
287
|
-
:data-testid="`capi-unsupported-warning-${row?.metadata?.name}`"
|
|
288
|
-
:colspan="fullColspan - (tableActions ? 1: 0)"
|
|
289
|
-
>
|
|
290
|
-
<div
|
|
291
|
-
class="text-warning"
|
|
292
|
-
:class="{'mt-5': !!row.stateDescription.trim()}"
|
|
293
|
-
>
|
|
294
|
-
<i class="icon icon-warning" />{{ t('cluster.capi.notSupported') }}
|
|
295
|
-
</div>
|
|
296
|
-
</td>
|
|
297
|
-
</tr>
|
|
298
|
-
</template>
|
|
299
269
|
</ResourceTable>
|
|
300
270
|
</div>
|
|
301
271
|
</template>
|
|
302
|
-
|
|
303
|
-
<style scoped lang="scss">
|
|
304
|
-
.capi-unsupported {
|
|
305
|
-
&.has-description {
|
|
306
|
-
border-bottom: none;
|
|
307
|
-
padding: 0px;
|
|
308
|
-
td {
|
|
309
|
-
padding-top: 0px;
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
& div {
|
|
314
|
-
& i {
|
|
315
|
-
margin-right: 0.1em;
|
|
316
|
-
}
|
|
317
|
-
display: flex;
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
</style>
|
package/mixins/brand.js
CHANGED
|
@@ -3,6 +3,7 @@ import { MANAGEMENT } from '@shell/config/types';
|
|
|
3
3
|
import { SETTING } from '@shell/config/settings';
|
|
4
4
|
import { createCssVars } from '@shell/utils/color';
|
|
5
5
|
import { setTitle } from '@shell/config/private-label';
|
|
6
|
+
import { requireJson } from '@shell/utils/require-asset';
|
|
6
7
|
import { setFavIcon, haveSetFavIcon } from '@shell/utils/favicon';
|
|
7
8
|
import { allHash } from '@shell/utils/promise';
|
|
8
9
|
import { fetchInitialSettings } from '@shell/utils/settings';
|
|
@@ -187,7 +188,7 @@ export default {
|
|
|
187
188
|
|
|
188
189
|
if ( this.brand ) {
|
|
189
190
|
try {
|
|
190
|
-
const brandMeta =
|
|
191
|
+
const brandMeta = requireJson(`~shell/assets/brand/${ this.brand }/metadata.json`);
|
|
191
192
|
|
|
192
193
|
if (brandMeta?.hasStylesheet === 'true') {
|
|
193
194
|
bodyClass = `${ cssClass } ${ this.brand } theme-${ this.theme }`;
|
|
@@ -3,6 +3,7 @@ import { CATALOG } from '@shell/config/labels-annotations';
|
|
|
3
3
|
import { insertAt } from '@shell/utils/array';
|
|
4
4
|
import { CLUSTER_REPO_APPCO_AUTH_GENERATE_NAME, CATALOG as CATALOG_TYPE } from '@shell/config/types';
|
|
5
5
|
import { colorForState, stateDisplay } from '@shell/plugins/dashboard-store/resource-class';
|
|
6
|
+
import { _CREATE } from '@shell/config/query-params';
|
|
6
7
|
|
|
7
8
|
import SteveModel from '@shell/plugins/steve/steve-class';
|
|
8
9
|
|
|
@@ -173,6 +174,14 @@ export default class ClusterRepo extends SteveModel {
|
|
|
173
174
|
return this.$rootGetters['i18n/withFallback'](key, null, name);
|
|
174
175
|
}
|
|
175
176
|
|
|
177
|
+
detailPageHeaderActionOverride(realMode) {
|
|
178
|
+
if (realMode === _CREATE) {
|
|
179
|
+
return this.t('catalog.repo.add');
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
|
|
176
185
|
get urlDisplay() {
|
|
177
186
|
return this.status?.url || this.spec.gitRepo || this.spec.url;
|
|
178
187
|
}
|
|
@@ -111,12 +111,17 @@ export default class CapiMachineDeployment extends SteveModel {
|
|
|
111
111
|
return `${ this.spec?.template?.metadata?.labels?.[MACHINE_ROLES.ETCD] }` === 'true';
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
// use this pool's definition in the cluster
|
|
114
|
+
// use this pool's definition in the provisioning cluster spec to scale, not this.spec.replicas
|
|
115
115
|
get inClusterSpec() {
|
|
116
|
-
|
|
116
|
+
// infra from Rancher node driver: provisioning cluster has reference to Rancher-generated crd <provider name>Config from the rke-machine-config.cattle.io api group
|
|
117
|
+
const rkeMachineConfigName = this.template?.metadata?.annotations['rke.cattle.io/cloned-from-name'];
|
|
118
|
+
// infra from upstream CAPI provider: provisioning cluster has reference to an upstream provider-specific machine template crd in the infrastructure.cluster.x-k8s.io api group
|
|
119
|
+
const infrastructureRefName = this.spec?.template?.spec?.infrastructureRef?.name;
|
|
120
|
+
const machineTemplateName = rkeMachineConfigName || infrastructureRefName;
|
|
121
|
+
|
|
117
122
|
const machinePools = this.cluster.spec.rkeConfig.machinePools;
|
|
118
123
|
|
|
119
|
-
return machinePools.find((pool) => pool.machineConfigRef.name ===
|
|
124
|
+
return machinePools.find((pool) => pool.machineConfigRef.name === machineTemplateName);
|
|
120
125
|
}
|
|
121
126
|
|
|
122
127
|
scalePool(delta, save = true, depth = 0) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { insertAt } from '@shell/utils/array';
|
|
2
2
|
import SteveModel from '@shell/plugins/steve/steve-class';
|
|
3
|
+
import { requireAsset } from '@shell/utils/require-asset';
|
|
3
4
|
|
|
4
5
|
export const configType = {
|
|
5
6
|
activedirectory: 'ldap',
|
|
@@ -56,7 +57,7 @@ export default class AuthConfig extends SteveModel {
|
|
|
56
57
|
|
|
57
58
|
get icon() {
|
|
58
59
|
try {
|
|
59
|
-
return
|
|
60
|
+
return requireAsset(`~shell/assets/images/vendor/${ imageOverrides[this.id] || this.id }.svg`);
|
|
60
61
|
} catch (e) {
|
|
61
62
|
return '';
|
|
62
63
|
}
|
|
@@ -13,6 +13,7 @@ import { isHarvesterCluster } from '@shell/utils/cluster';
|
|
|
13
13
|
import SteveModel from '@shell/plugins/steve/steve-class';
|
|
14
14
|
import { LINUX, WINDOWS } from '@shell/store/catalog';
|
|
15
15
|
import { KONTAINER_TO_DRIVER } from './management.cattle.io.kontainerdriver';
|
|
16
|
+
import { requireAsset } from '@shell/utils/require-asset';
|
|
16
17
|
import { PINNED_CLUSTERS } from '@shell/store/prefs';
|
|
17
18
|
import { copyTextToClipboard } from '@shell/utils/clipboard';
|
|
18
19
|
import { isHostedProvider } from '@shell/utils/provider';
|
|
@@ -221,7 +222,7 @@ export default class MgmtCluster extends SteveModel {
|
|
|
221
222
|
}
|
|
222
223
|
|
|
223
224
|
get providerOsLogo() {
|
|
224
|
-
return
|
|
225
|
+
return requireAsset(`~shell/assets/images/vendor/${ this.providerOs }.svg`);
|
|
225
226
|
}
|
|
226
227
|
|
|
227
228
|
get workerOSs() {
|
|
@@ -282,11 +283,11 @@ export default class MgmtCluster extends SteveModel {
|
|
|
282
283
|
let icon;
|
|
283
284
|
|
|
284
285
|
try {
|
|
285
|
-
icon =
|
|
286
|
+
icon = requireAsset(`~shell/assets/images/providers/${ prv }.svg`);
|
|
286
287
|
} catch (e) {
|
|
287
288
|
console.warn(`Can not find provider logo for provider ${ logo }`); // eslint-disable-line no-console
|
|
288
289
|
// Use fallback generic Kubernetes icon
|
|
289
|
-
icon =
|
|
290
|
+
icon = requireAsset(`~shell/assets/images/providers/kubernetes.svg`);
|
|
290
291
|
}
|
|
291
292
|
|
|
292
293
|
return icon;
|