@rancher/shell 0.3.24 → 0.3.25
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/themes/_light.scss +1 -1
- package/assets/translations/en-us.yaml +29 -7
- package/assets/translations/zh-hans.yaml +1 -1
- package/components/ClusterIconMenu.vue +143 -0
- package/components/CruResource.vue +7 -1
- package/components/ExplorerProjectsNamespaces.vue +11 -1
- package/components/FixedBanner.vue +17 -1
- package/components/Markdown.vue +1 -1
- package/components/Questions/__tests__/Yaml.test.ts +3 -2
- package/components/SortableTable/index.vue +3 -2
- package/components/auth/RoleDetailEdit.vue +15 -2
- package/components/auth/login/saml.vue +12 -1
- package/components/form/LabeledSelect.vue +12 -5
- package/components/form/Members/ClusterPermissionsEditor.vue +1 -1
- package/components/form/Members/MembershipEditor.vue +6 -1
- package/components/form/__tests__/KeyValue.test.ts +6 -3
- package/components/form/__tests__/LabeledSelect.test.ts +18 -0
- package/components/formatter/PodsUsage.vue +11 -36
- package/components/formatter/PrincipalGroupBindings.vue +8 -5
- package/components/formatter/__tests__/PodsUsage.test.ts +36 -19
- package/components/nav/Group.vue +25 -27
- package/components/nav/Header.vue +12 -5
- package/components/nav/Pinned.vue +47 -0
- package/components/nav/TopLevelMenu.vue +233 -60
- package/components/nav/Type.vue +57 -3
- package/config/home-links.js +1 -1
- package/config/product/istio.js +15 -5
- package/config/router.js +3 -9
- package/config/table-headers.js +5 -6
- package/config/uiplugins.js +1 -0
- package/core/plugin-helpers.js +3 -0
- package/core/types.ts +6 -1
- package/creators/app/files/.vscode/settings.json +0 -1
- package/detail/__tests__/autoscaling.horizontalpodautoscaler.test.ts +118 -0
- package/detail/autoscaling.horizontalpodautoscaler/index.vue +4 -4
- package/detail/provisioning.cattle.io.cluster.vue +7 -5
- package/edit/__tests__/management.cattle.io.clusterroletemplatebinding.test.ts +58 -0
- package/edit/__tests__/namespace.test.ts +5 -3
- package/edit/management.cattle.io.clusterroletemplatebinding.vue +3 -11
- package/edit/namespace.vue +8 -4
- package/edit/provisioning.cattle.io.cluster/Basics.vue +662 -0
- package/edit/provisioning.cattle.io.cluster/CustomCommand.vue +6 -0
- package/edit/provisioning.cattle.io.cluster/DrainOptions.vue +13 -8
- package/edit/provisioning.cattle.io.cluster/MachinePool.vue +11 -2
- package/edit/provisioning.cattle.io.cluster/MemberRoles.vue +40 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/Basics.tests.ts +237 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/CustomCommand.tests.ts +71 -23
- package/edit/provisioning.cattle.io.cluster/__tests__/DrainOptions.test.ts +52 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +65 -142
- package/edit/provisioning.cattle.io.cluster/rke2.vue +194 -598
- package/edit/workload/storage/__tests__/Storage.test.ts +2 -2
- package/edit/workload/storage/persistentVolumeClaim/__tests__/persistentvolumeclaim.test.ts +36 -0
- package/edit/workload/storage/persistentVolumeClaim/persistentvolumeclaim.vue +15 -7
- package/initialize/index.js +5 -5
- package/layouts/default.vue +6 -6
- package/layouts/home.vue +6 -2
- package/layouts/plain.vue +9 -2
- package/list/fleet.cattle.io.cluster.vue +2 -2
- package/list/management.cattle.io.feature.vue +1 -1
- package/machine-config/vmwarevsphere.vue +48 -7
- package/mixins/brand.js +0 -8
- package/mixins/child-hook.js +2 -2
- package/mixins/create-edit-view/impl.js +3 -3
- package/models/__tests__/management.cattle.io.node.ts +96 -0
- package/models/__tests__/node.ts +74 -0
- package/models/cluster/node.js +6 -5
- package/models/cluster.x-k8s.io.machinedeployment.js +2 -2
- package/models/management.cattle.io.cluster.js +22 -1
- package/models/management.cattle.io.clusterroletemplatebinding.js +3 -3
- package/models/management.cattle.io.globalrole.js +17 -2
- package/models/management.cattle.io.node.js +6 -4
- package/models/management.cattle.io.projectroletemplatebinding.js +3 -3
- package/models/management.cattle.io.roletemplate.js +17 -2
- package/package.json +2 -6
- package/pages/about.vue +2 -0
- package/pages/auth/setup.vue +5 -4
- package/pages/c/_cluster/monitoring/index.vue +8 -3
- package/pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue +9 -66
- package/pages/c/_cluster/uiplugins/CatalogList/CatalogUninstallDialog.vue +182 -0
- package/pages/c/_cluster/uiplugins/CatalogList/index.vue +15 -32
- package/pages/c/_cluster/uiplugins/UninstallDialog.vue +8 -46
- package/pages/c/_cluster/uiplugins/index.vue +64 -64
- package/pages/diagnostic.vue +0 -39
- package/pages/home.vue +1 -1
- package/plugins/dashboard-store/normalize.js +4 -4
- package/plugins/int-number.js +5 -2
- package/plugins/positive-int-number.js +19 -0
- package/plugins/steve/__tests__/getters.spec.ts +15 -0
- package/plugins/steve/getters.js +22 -10
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +0 -8
- package/rancher-components/Form/Radio/RadioButton.test.ts +3 -7
- package/store/index.js +4 -0
- package/store/prefs.js +1 -0
- package/types/shell/index.d.ts +13 -4
- package/utils/__tests__/cluster.test.ts +55 -0
- package/utils/__tests__/object.test.ts +21 -2
- package/utils/cluster.js +47 -1
- package/utils/object.js +12 -5
- package/utils/validators/formRules/__tests__/index.test.ts +13 -1
- package/utils/validators/formRules/index.ts +4 -0
- package/utils/validators/role-template.js +9 -1
- package/utils/version.js +1 -1
- package/yarn-error.log +16 -16
- package/components/ClusterProviderIconMenu.vue +0 -161
- package/content/docs/en-us/getting-started.md +0 -224
- package/content/docs/en-us/whats-new.md +0 -29
- package/content/docs/zh-hans/getting-started.md +0 -224
- package/content/docs/zh-hans/whats-new.md +0 -28
- package/pages/docs/_doc.vue +0 -345
- package/pages/docs/toc.js +0 -27
- package/plugins/console.js +0 -34
package/types/shell/index.d.ts
CHANGED
|
@@ -2049,8 +2049,8 @@ declare namespace _default {
|
|
|
2049
2049
|
namespace methods {
|
|
2050
2050
|
function done(): any;
|
|
2051
2051
|
function done(): any;
|
|
2052
|
-
function conflict(): any
|
|
2053
|
-
function conflict(): any
|
|
2052
|
+
function conflict(): Promise<any>;
|
|
2053
|
+
function conflict(): Promise<any>;
|
|
2054
2054
|
function save(buttonDone: any, url: any, depth?: number): any;
|
|
2055
2055
|
function save(buttonDone: any, url: any, depth?: number): any;
|
|
2056
2056
|
function actuallySave(url: any): Promise<void>;
|
|
@@ -2069,7 +2069,7 @@ declare var _default: import("vue/types/vue").ExtendedVue<Vue<Record<string, any
|
|
|
2069
2069
|
errors: any[];
|
|
2070
2070
|
}, {
|
|
2071
2071
|
done(): any;
|
|
2072
|
-
conflict(): any
|
|
2072
|
+
conflict(): Promise<any>;
|
|
2073
2073
|
save(buttonDone: any, url: any, depth?: number): any;
|
|
2074
2074
|
actuallySave(url: any): Promise<void>;
|
|
2075
2075
|
setErrors(errors: any): void;
|
|
@@ -2407,7 +2407,7 @@ export const SELF: "__[[SELF]]__";
|
|
|
2407
2407
|
declare module '@shell/plugins/dashboard-store/normalize' {
|
|
2408
2408
|
export function keyFieldFor(type: any): string;
|
|
2409
2409
|
export function normalizeType(type: any): any;
|
|
2410
|
-
export function handleConflict(initialValueJSON: any, value: any, liveValue: any, rootGetters: any, store: any): false | any[]
|
|
2410
|
+
export function handleConflict(initialValueJSON: any, value: any, liveValue: any, rootGetters: any, store: any, storeNamespace: any): Promise<false | any[]>;
|
|
2411
2411
|
export const KEY_FIELD_FOR: {
|
|
2412
2412
|
[x: number]: string;
|
|
2413
2413
|
default: string;
|
|
@@ -2836,6 +2836,7 @@ export const NAMESPACE_FILTERS: any;
|
|
|
2836
2836
|
export const WORKSPACE: any;
|
|
2837
2837
|
export const EXPANDED_GROUPS: any;
|
|
2838
2838
|
export const FAVORITE_TYPES: any;
|
|
2839
|
+
export const PINNED_CLUSTERS: any;
|
|
2839
2840
|
export const GROUP_RESOURCES: any;
|
|
2840
2841
|
export const DIFF: any;
|
|
2841
2842
|
export const THEME: any;
|
|
@@ -3052,6 +3053,14 @@ export function filterOnlyKubernetesClusters(mgmtClusters: any, store: any): any
|
|
|
3052
3053
|
export function isHarvesterCluster(mgmtCluster: any): boolean;
|
|
3053
3054
|
export function isHarvesterSatisfiesVersion(version?: string): any;
|
|
3054
3055
|
export function filterHiddenLocalCluster(mgmtClusters: any, store: any): any;
|
|
3056
|
+
/**
|
|
3057
|
+
* Shortens an input string based on the number of segments it contains.
|
|
3058
|
+
* @param {string} input - The input string to be shortened.
|
|
3059
|
+
* @returns {string} - The shortened string.
|
|
3060
|
+
* @example smallIdentifier('local') => 'lcl'
|
|
3061
|
+
* @example smallIdentifier('word-wide-web') => 'www'
|
|
3062
|
+
*/
|
|
3063
|
+
export function abbreviateClusterName(input: string): string;
|
|
3055
3064
|
}
|
|
3056
3065
|
|
|
3057
3066
|
// @shell/utils/color
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { abbreviateClusterName } from '@shell/utils/cluster';
|
|
2
|
+
|
|
3
|
+
describe('fx: abbreviateClusterName', () => {
|
|
4
|
+
it.each([
|
|
5
|
+
['local', 'lcl'],
|
|
6
|
+
['world-wide-web', 'www'],
|
|
7
|
+
['a', 'a'],
|
|
8
|
+
['ab', 'ab'],
|
|
9
|
+
['abc', 'abc'],
|
|
10
|
+
['', ''],
|
|
11
|
+
['1', '1'],
|
|
12
|
+
['12', '12'],
|
|
13
|
+
['123', '123'],
|
|
14
|
+
['a1', 'a1'],
|
|
15
|
+
['aa1', 'aa1'],
|
|
16
|
+
['aaa1', 'aa1'],
|
|
17
|
+
['a-b', 'a-b'],
|
|
18
|
+
['1-2', '1-2'],
|
|
19
|
+
['a-b-c', 'abc'],
|
|
20
|
+
['abc-def-ghi', 'adg'],
|
|
21
|
+
['abcd-efgh', 'adh'],
|
|
22
|
+
['a-bc', 'abc'],
|
|
23
|
+
['ab-c', 'abc'],
|
|
24
|
+
['ab-cd', 'abd'],
|
|
25
|
+
['a-bcd', 'abd'],
|
|
26
|
+
['abc-d', 'acd'],
|
|
27
|
+
['0123-4567-89ab-cdef', '048'],
|
|
28
|
+
['0123-4567-89ab-cdef-ghij', '048'],
|
|
29
|
+
['0123-4567-8901-2345', '048'],
|
|
30
|
+
['0123-4567-8901-2345-6789', '048'],
|
|
31
|
+
['a1b', 'a1b'],
|
|
32
|
+
['a1b2', 'a1b'],
|
|
33
|
+
['ab12cd34', 'a1c'],
|
|
34
|
+
['test-cluster-one', 'tco'],
|
|
35
|
+
['test-cluster-1', 'tc1'],
|
|
36
|
+
['customer-support-team-1', 'cst'],
|
|
37
|
+
['customer-support-team-one', 'cst'],
|
|
38
|
+
['customer-support-team-prod', 'cst'],
|
|
39
|
+
['customer-support-team-dev', 'cst'],
|
|
40
|
+
['customer-support-team-prod-1', 'cst'],
|
|
41
|
+
['customer-support-team-dev-1', 'cst'],
|
|
42
|
+
['customer-support-team-prod-2', 'cst'],
|
|
43
|
+
['customer-support-team-dev-2', 'cst'],
|
|
44
|
+
|
|
45
|
+
['s322', 's32'],
|
|
46
|
+
['sowmya2', 'sa2'],
|
|
47
|
+
['sowmya4', 'sa4'],
|
|
48
|
+
['sowmya', 'sma'],
|
|
49
|
+
['sowmyatest4', 'st4'],
|
|
50
|
+
])('should evaluate %p as %p', (value, expected) => {
|
|
51
|
+
const result = abbreviateClusterName(value);
|
|
52
|
+
|
|
53
|
+
expect(result).toStrictEqual(expected);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
clone, get, getter, isEmpty, toDictionary
|
|
2
|
+
clone, get, getter, isEmpty, toDictionary, remove
|
|
3
3
|
} from '@shell/utils/object';
|
|
4
4
|
|
|
5
5
|
describe('fx: get', () => {
|
|
@@ -129,7 +129,7 @@ describe('fx: isEmpty', () => {
|
|
|
129
129
|
});
|
|
130
130
|
});
|
|
131
131
|
|
|
132
|
-
describe('
|
|
132
|
+
describe('fx: toDictionary', () => {
|
|
133
133
|
it('should return a dictionary from an array', () => {
|
|
134
134
|
const array = ['a', 'b', 'c'];
|
|
135
135
|
const asd = (value: string) => value.toUpperCase();
|
|
@@ -142,3 +142,22 @@ describe('fX: toDictionary', () => {
|
|
|
142
142
|
expect(result).toStrictEqual(expectation);
|
|
143
143
|
});
|
|
144
144
|
});
|
|
145
|
+
|
|
146
|
+
describe('fx: remove', () => {
|
|
147
|
+
it.each([
|
|
148
|
+
[{}, '', {}],
|
|
149
|
+
[{}, 'not_there', {}],
|
|
150
|
+
[{}, 'not.there.again', {}],
|
|
151
|
+
[{ level1: true }, 'level1', {}],
|
|
152
|
+
[{ level1: true }, 'not_there', { level1: true }],
|
|
153
|
+
[{ level1: { level2: true } }, 'level1.level2', { level1: { } }],
|
|
154
|
+
[{ level1: { level2: true, other: true } }, 'level1.level2', { level1: { other: true } }],
|
|
155
|
+
[{ level1: { level2: true }, other: true }, 'level1.level2', { level1: { }, other: true }],
|
|
156
|
+
[{ level1: { level2: true }, other: true }, 'not_there.level1.level2', { level1: { level2: true }, other: true }],
|
|
157
|
+
[{ level1: { level2: true }, other: true }, 'level1', { other: true }],
|
|
158
|
+
])('should evaluate %p as %p', (obj, path, expected) => {
|
|
159
|
+
const result = remove(obj, path);
|
|
160
|
+
|
|
161
|
+
expect(result).toStrictEqual(expected);
|
|
162
|
+
});
|
|
163
|
+
});
|
package/utils/cluster.js
CHANGED
|
@@ -8,7 +8,7 @@ export function filterOnlyKubernetesClusters(mgmtClusters, store) {
|
|
|
8
8
|
const openHarvesterContainerWorkload = store.getters['features/get']('harvester-baremetal-container-workload');
|
|
9
9
|
|
|
10
10
|
return mgmtClusters.filter((c) => {
|
|
11
|
-
return openHarvesterContainerWorkload ? true : !c
|
|
11
|
+
return openHarvesterContainerWorkload ? true : !isHarvesterCluster(c);
|
|
12
12
|
});
|
|
13
13
|
}
|
|
14
14
|
|
|
@@ -44,3 +44,49 @@ export function filterHiddenLocalCluster(mgmtClusters, store) {
|
|
|
44
44
|
return !target.isLocal;
|
|
45
45
|
});
|
|
46
46
|
}
|
|
47
|
+
|
|
48
|
+
const clusterNameSegments = /([A-Za-z]+|\d+)/g;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Shortens an input string based on the number of segments it contains.
|
|
52
|
+
* @param {string} input - The input string to be shortened.
|
|
53
|
+
* @returns {string} - The shortened string.
|
|
54
|
+
* @example smallIdentifier('local') => 'lcl'
|
|
55
|
+
* @example smallIdentifier('word-wide-web') => 'www'
|
|
56
|
+
*/
|
|
57
|
+
export function abbreviateClusterName(input) {
|
|
58
|
+
if (!input) {
|
|
59
|
+
return '';
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (input.length <= 3) {
|
|
63
|
+
return input;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const segments = input.match(clusterNameSegments);
|
|
67
|
+
|
|
68
|
+
if (!segments) return ''; // In case no valid segments are found
|
|
69
|
+
|
|
70
|
+
let result = '';
|
|
71
|
+
|
|
72
|
+
switch (segments.length) {
|
|
73
|
+
case 1: {
|
|
74
|
+
const word = segments[0];
|
|
75
|
+
|
|
76
|
+
result = `${ word[0] }${ word[Math.floor(word.length / 2)] }${ word[word.length - 1] }`;
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
case 2: {
|
|
80
|
+
const w1 = `${ segments[0][0] }`;
|
|
81
|
+
const w2 = `${ segments[0].length >= 2 ? segments[0][segments[0].length - 1] : segments[1][0] }`;
|
|
82
|
+
const w3 = `${ segments[1][segments[1].length - 1] }`;
|
|
83
|
+
|
|
84
|
+
result = w1 + w2 + w3;
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
default:
|
|
88
|
+
result = segments.slice(0, 3).map((segment) => segment[0]).join('');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return result;
|
|
92
|
+
}
|
package/utils/object.js
CHANGED
|
@@ -91,13 +91,20 @@ export function get(obj, path) {
|
|
|
91
91
|
|
|
92
92
|
export function remove(obj, path) {
|
|
93
93
|
const parentAry = splitObjectPath(path);
|
|
94
|
-
const leafKey = parentAry.pop();
|
|
95
94
|
|
|
96
|
-
|
|
95
|
+
// Remove the very last part of the path
|
|
97
96
|
|
|
98
|
-
if (
|
|
99
|
-
Vue.set(
|
|
100
|
-
delete
|
|
97
|
+
if (parentAry.length === 1) {
|
|
98
|
+
Vue.set(obj, path, undefined);
|
|
99
|
+
delete obj[path];
|
|
100
|
+
} else {
|
|
101
|
+
const leafKey = parentAry.pop();
|
|
102
|
+
const parent = get(obj, joinObjectPath(parentAry));
|
|
103
|
+
|
|
104
|
+
if ( parent ) {
|
|
105
|
+
Vue.set(parent, leafKey, undefined);
|
|
106
|
+
delete parent[leafKey];
|
|
107
|
+
}
|
|
101
108
|
}
|
|
102
109
|
|
|
103
110
|
return obj;
|
|
@@ -393,6 +393,18 @@ describe('formRules', () => {
|
|
|
393
393
|
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
394
394
|
});
|
|
395
395
|
|
|
396
|
+
it('"roleTemplateRules" : returns correct message when type is RBAC role rule defines both resources and nonResourceURLs', () => {
|
|
397
|
+
const testValue: [{}] = [
|
|
398
|
+
{
|
|
399
|
+
verbs: ['verb1'], resources: ['resource1'], apiGroups: ['apiGroup1'], nonResourceURLs: ['nonResourceUrl1']
|
|
400
|
+
}
|
|
401
|
+
];
|
|
402
|
+
const formRuleResult = formRules.roleTemplateRules('rbac.authorization.k8s.io.role')(testValue);
|
|
403
|
+
const expectedResult = JSON.stringify({ message: 'validation.roleTemplate.roleTemplateRules.noResourceAndNonResource' });
|
|
404
|
+
|
|
405
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
406
|
+
});
|
|
407
|
+
|
|
396
408
|
it('"roleTemplateRules" : returns correct message when type is RBAC role and value is missing apiGroups', () => {
|
|
397
409
|
const testValue: [{}] = [
|
|
398
410
|
{
|
|
@@ -408,7 +420,7 @@ describe('formRules', () => {
|
|
|
408
420
|
it('"roleTemplateRules" : returns undefined when type is not RBAC role and value contains valid rules', () => {
|
|
409
421
|
const testValue: [{}] = [
|
|
410
422
|
{
|
|
411
|
-
verbs: ['verb1'],
|
|
423
|
+
verbs: ['verb1'], resources: ['resource1'], apiGroups: ['apiGroup1']
|
|
412
424
|
}
|
|
413
425
|
];
|
|
414
426
|
const formRuleResult = formRules.roleTemplateRules('nonrbactype')(testValue);
|
|
@@ -370,6 +370,10 @@ export default function(t: Translation, { key = 'Value' }: ValidationOptions): {
|
|
|
370
370
|
return t('validation.roleTemplate.roleTemplateRules.missingVerb');
|
|
371
371
|
}
|
|
372
372
|
|
|
373
|
+
if (val.some((rule: any) => rule.resources?.length && rule.nonResourceURLs?.length)) {
|
|
374
|
+
return t('validation.roleTemplate.roleTemplateRules.noResourceAndNonResource');
|
|
375
|
+
}
|
|
376
|
+
|
|
373
377
|
if (type === RBAC.ROLE) {
|
|
374
378
|
if (val.some((rule: any) => isEmpty(rule.resources))) {
|
|
375
379
|
return t('validation.roleTemplate.roleTemplateRules.missingResource');
|
|
@@ -6,6 +6,10 @@ export function roleTemplateRules(rules = [], getters, errors, validatorArgs = [
|
|
|
6
6
|
errors.push(getters['i18n/t']('validation.roleTemplate.roleTemplateRules.missingVerb'));
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
if (rules.some((rule) => rule.resources?.length && rule.nonResourceURLs?.length)) {
|
|
10
|
+
errors.push(getters['i18n/t']('validation.roleTemplate.roleTemplateRules.noResourceAndNonResource'));
|
|
11
|
+
}
|
|
12
|
+
|
|
9
13
|
if (validatorArgs[0] === RBAC.ROLE) {
|
|
10
14
|
if (rules.some((rule) => isEmpty(rule.resources))) {
|
|
11
15
|
errors.push(getters['i18n/t']('validation.roleTemplate.roleTemplateRules.missingResource'));
|
|
@@ -13,7 +17,11 @@ export function roleTemplateRules(rules = [], getters, errors, validatorArgs = [
|
|
|
13
17
|
if (rules.some((rule) => isEmpty(rule.apiGroups))) {
|
|
14
18
|
errors.push(getters['i18n/t']('validation.roleTemplate.roleTemplateRules.missingApiGroup'));
|
|
15
19
|
}
|
|
16
|
-
} else if (rules.some((rule) =>
|
|
20
|
+
} else if (rules.some((rule) => rule.resources?.length && rule.nonResourceUrls?.length)) {
|
|
21
|
+
errors.push(getters['i18n/t']('validation.roleTemplate.roleTemplateRules.noResourceAndNonResource'));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (rules.some((rule) => isEmpty(rule.resources) && isEmpty(rule.nonResourceURLs) && isEmpty(rule.apiGroups))) {
|
|
17
25
|
errors.push(getters['i18n/t']('validation.roleTemplate.roleTemplateRules.missingOneResource'));
|
|
18
26
|
}
|
|
19
27
|
}
|
package/utils/version.js
CHANGED
|
@@ -74,7 +74,7 @@ export function isPrerelease(version) {
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
export function isDevBuild(version) {
|
|
77
|
-
if ( ['dev', 'master', 'head'].includes(version) || version.endsWith('-head') || version.match(/-rc\d+$/) ) {
|
|
77
|
+
if ( ['dev', 'master', 'head'].includes(version) || version.endsWith('-head') || version.match(/-rc\d+$/) || version.match(/-alpha\d+$/) ) {
|
|
78
78
|
return true;
|
|
79
79
|
}
|
|
80
80
|
|
package/yarn-error.log
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
1
|
Arguments:
|
|
2
|
-
/
|
|
2
|
+
/Users/aalves/.nvm/versions/node/v16.19.1/bin/node /Users/aalves/.nvm/versions/node/v16.19.1/bin/yarn publish . --new-version 0.3.22 --no-git-tag-version --access public
|
|
3
3
|
|
|
4
4
|
PATH:
|
|
5
|
-
/Users/
|
|
5
|
+
/Users/aalves/.rd/bin:/Users/aalves/.nvm/versions/node/v16.19.1/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/aalves/.rd/bin:/Users/aalves/.nvm/versions/node/v16.19.1/bin:/opt/homebrew/bin:/opt/homebrew/sbin
|
|
6
6
|
|
|
7
7
|
Yarn version:
|
|
8
8
|
1.22.19
|
|
9
9
|
|
|
10
10
|
Node version:
|
|
11
|
-
16.
|
|
11
|
+
16.19.1
|
|
12
12
|
|
|
13
13
|
Platform:
|
|
14
|
-
darwin
|
|
14
|
+
darwin arm64
|
|
15
15
|
|
|
16
16
|
Trace:
|
|
17
|
-
Error:
|
|
18
|
-
at
|
|
19
|
-
at
|
|
20
|
-
at
|
|
21
|
-
at
|
|
22
|
-
at
|
|
23
|
-
at
|
|
24
|
-
at
|
|
25
|
-
at
|
|
26
|
-
at
|
|
27
|
-
at
|
|
17
|
+
Error: https://registry.yarnpkg.com/-/user/org.couchdb.user:aalves08: failed to authenticate: Could not authenticate aalves08: bad password
|
|
18
|
+
at Request.params.callback [as _callback] (/Users/aalves/.nvm/versions/node/v16.19.1/lib/node_modules/yarn/lib/cli.js:66145:18)
|
|
19
|
+
at Request.self.callback (/Users/aalves/.nvm/versions/node/v16.19.1/lib/node_modules/yarn/lib/cli.js:140890:22)
|
|
20
|
+
at Request.emit (node:events:513:28)
|
|
21
|
+
at Request.<anonymous> (/Users/aalves/.nvm/versions/node/v16.19.1/lib/node_modules/yarn/lib/cli.js:141862:10)
|
|
22
|
+
at Request.emit (node:events:513:28)
|
|
23
|
+
at IncomingMessage.<anonymous> (/Users/aalves/.nvm/versions/node/v16.19.1/lib/node_modules/yarn/lib/cli.js:141784:12)
|
|
24
|
+
at Object.onceWrapper (node:events:627:28)
|
|
25
|
+
at IncomingMessage.emit (node:events:525:35)
|
|
26
|
+
at endReadableNT (node:internal/streams/readable:1358:12)
|
|
27
|
+
at processTicksAndRejections (node:internal/process/task_queues:83:21)
|
|
28
28
|
|
|
29
29
|
npm manifest:
|
|
30
30
|
{
|
|
31
31
|
"name": "@rancher/shell",
|
|
32
|
-
"version": "0.3.
|
|
32
|
+
"version": "0.3.22",
|
|
33
33
|
"description": "Rancher Dashboard Shell",
|
|
34
34
|
"repository": "https://github.com/rancherlabs/dashboard",
|
|
35
35
|
"license": "Apache-2.0",
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
export default {
|
|
3
|
-
props: {
|
|
4
|
-
cluster: {
|
|
5
|
-
type: Object,
|
|
6
|
-
required: true,
|
|
7
|
-
},
|
|
8
|
-
},
|
|
9
|
-
computed: {
|
|
10
|
-
isEnabled() {
|
|
11
|
-
return !!this.cluster?.ready;
|
|
12
|
-
},
|
|
13
|
-
},
|
|
14
|
-
methods: {
|
|
15
|
-
/**
|
|
16
|
-
* Shortens an input string based on the number of segments it contains.
|
|
17
|
-
* @param {string} input - The input string to be shortened.
|
|
18
|
-
* @returns {string} - The shortened string.
|
|
19
|
-
* @example smallIdentifier('local') => 'lcl'
|
|
20
|
-
* @example smallIdentifier('word-wide-web') => 'www'
|
|
21
|
-
*/
|
|
22
|
-
smallIdentifier(input) {
|
|
23
|
-
if (this.cluster.badge?.iconText) {
|
|
24
|
-
return this.cluster.badge?.iconText;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
if (!input) {
|
|
28
|
-
return '';
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
if (input.length <= 3) {
|
|
32
|
-
return input;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const segments = input.match(/([A-Za-z]+|\d+)/g);
|
|
36
|
-
|
|
37
|
-
if (!segments) return ''; // In case no valid segments are found
|
|
38
|
-
|
|
39
|
-
let result = '';
|
|
40
|
-
|
|
41
|
-
switch (segments.length) {
|
|
42
|
-
case 1:
|
|
43
|
-
// eslint-disable-next-line no-case-declarations
|
|
44
|
-
const word = segments[0];
|
|
45
|
-
|
|
46
|
-
result = `${ word[0] }${ word[Math.floor(word.length / 2)] }${ word[word.length - 1] }`;
|
|
47
|
-
break;
|
|
48
|
-
case 2:
|
|
49
|
-
result = `${ segments[0][0] }${ segments[1][0] }${ segments[1][segments[1].length - 1] }`;
|
|
50
|
-
break;
|
|
51
|
-
default:
|
|
52
|
-
result = segments.slice(0, 3).map((segment) => segment[0]).join('');
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return result;
|
|
56
|
-
},
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
</script>
|
|
61
|
-
|
|
62
|
-
<template>
|
|
63
|
-
<div
|
|
64
|
-
v-if="cluster"
|
|
65
|
-
class="cluster-icon-menu"
|
|
66
|
-
>
|
|
67
|
-
<div
|
|
68
|
-
class="cluster-badge-logo"
|
|
69
|
-
:class="{ 'disabled': !isEnabled }"
|
|
70
|
-
:style="{borderBottom: cluster.badge?.color ? `4px solid ${cluster.badge?.color}` : ''}"
|
|
71
|
-
>
|
|
72
|
-
<span
|
|
73
|
-
class="cluster-badge-logo-text"
|
|
74
|
-
>
|
|
75
|
-
{{ smallIdentifier(cluster.label) }}
|
|
76
|
-
</span>
|
|
77
|
-
<!-- {{ cluster.badge.iconText }} -->
|
|
78
|
-
</div>
|
|
79
|
-
<!-- eslint-enable -->
|
|
80
|
-
<svg
|
|
81
|
-
v-if="cluster.isLocal && !cluster.isHarvester"
|
|
82
|
-
id="local-cluster-icon-menu"
|
|
83
|
-
class="cluster-os-logo"
|
|
84
|
-
version="1.1"
|
|
85
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
86
|
-
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
87
|
-
viewBox="0 0 100 100"
|
|
88
|
-
style="enable-background:new 0 0 100 100;"
|
|
89
|
-
>
|
|
90
|
-
<g>
|
|
91
|
-
<g>
|
|
92
|
-
<path
|
|
93
|
-
class="rancher-icon-fill"
|
|
94
|
-
d="M26.0862026,44.4953918H8.6165142c-5.5818157,0-9.3979139-4.6252708-8.4802637-10.1311035l2.858391-17.210701
|
|
95
|
-
C3.912292,11.6477556,6.1382647,7.1128125,7.8419709,7.1128125s3.1788611,4.5368752,3.1788611,10.1186218v4.4837742
|
|
96
|
-
c0,5.5817471,4.4044495,9.5409164,9.9862652,9.5409164h5.0791054V44.4953918z"
|
|
97
|
-
/>
|
|
98
|
-
</g>
|
|
99
|
-
<path
|
|
100
|
-
class="rancher-icon-fill"
|
|
101
|
-
d="M63.0214729,92.8871841H37.0862045c-6.0751343,0-11.0000019-4.9248657-11.0000019-11V30.3864384
|
|
102
|
-
c0-6.0751324,4.9248676-11,11.0000019-11h25.9352684c6.0751305,0,11.0000038,4.9248676,11.0000038,11v51.5007477
|
|
103
|
-
C74.0214767,87.9623184,69.0966034,92.8871841,63.0214729,92.8871841z"
|
|
104
|
-
/>
|
|
105
|
-
<g>
|
|
106
|
-
<path
|
|
107
|
-
class="rancher-icon-fill"
|
|
108
|
-
d="M73.9137955,44.4953918h17.4696884c5.5818176,0,9.3979187-4.6252708,8.4802628-10.1311035
|
|
109
|
-
l-2.8583908-17.210701c-0.9176483-5.5058317-3.1436234-10.0407753-4.8473282-10.0407753
|
|
110
|
-
s-3.1788635,4.5368752-3.1788635,10.1186218v4.4837742c0,5.5817471-4.4044418,9.5409164-9.9862595,9.5409164h-5.0791092
|
|
111
|
-
V44.4953918z"
|
|
112
|
-
/>
|
|
113
|
-
</g>
|
|
114
|
-
</g>
|
|
115
|
-
</svg>
|
|
116
|
-
<img
|
|
117
|
-
v-else
|
|
118
|
-
class="cluster-os-logo"
|
|
119
|
-
:src="cluster.providerNavLogo"
|
|
120
|
-
>
|
|
121
|
-
</div>
|
|
122
|
-
</template>
|
|
123
|
-
|
|
124
|
-
<style lang="scss" scoped>
|
|
125
|
-
|
|
126
|
-
.cluster-icon-menu {
|
|
127
|
-
position: relative;
|
|
128
|
-
align-items: center;
|
|
129
|
-
display: flex;
|
|
130
|
-
height: 28px;
|
|
131
|
-
justify-content: center;
|
|
132
|
-
width: 42px;
|
|
133
|
-
}
|
|
134
|
-
.cluster-os-logo {
|
|
135
|
-
position: absolute;
|
|
136
|
-
top: -6px;
|
|
137
|
-
right: -4px;
|
|
138
|
-
width: 14px;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
.cluster-badge-logo {
|
|
142
|
-
width: 42px;
|
|
143
|
-
height: 28px;
|
|
144
|
-
display: flex;
|
|
145
|
-
align-items: center;
|
|
146
|
-
justify-content: center;
|
|
147
|
-
color: var(--default-active-text);
|
|
148
|
-
font-weight: bold;
|
|
149
|
-
background: var(--nav-icon-badge-bg);
|
|
150
|
-
border: 1px solid var(--default-border);
|
|
151
|
-
border-radius: 5px;
|
|
152
|
-
padding-top: 2px;
|
|
153
|
-
font-size: 12px;
|
|
154
|
-
text-transform: uppercase;
|
|
155
|
-
|
|
156
|
-
&.disabled {
|
|
157
|
-
filter: grayscale(1);
|
|
158
|
-
color: var(--muted);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
</style>
|