@rancher/shell 1.2.2 → 1.2.5-rc.1
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/translations/en-us.yaml +8 -0
- package/assets/translations/zh-hans.yaml +1 -0
- package/cloud-credential/__tests__/harvester.test.ts +18 -0
- package/cloud-credential/harvester.vue +9 -1
- package/components/AlertTable.vue +17 -7
- package/components/GrafanaDashboard.vue +6 -4
- package/components/nav/TopLevelMenu.vue +1 -4
- package/config/product/explorer.js +11 -4
- package/config/settings.ts +9 -2
- package/config/types.js +1 -1
- package/config/uiplugins.js +2 -2
- package/edit/management.cattle.io.setting.vue +15 -2
- package/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue +8 -2
- package/edit/provisioning.cattle.io.cluster/__tests__/RegistryConfigs.test.ts +61 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/utils/cluster.ts +386 -0
- package/package.json +1 -1
- package/plugins/dashboard-store/actions.js +3 -2
- package/scripts/publish-shell.sh +59 -51
- package/scripts/test-plugins-build.sh +111 -29
- package/shell/types/shell/index.d.ts +2 -0
- package/store/catalog.js +1 -1
- package/store/type-map.utils.ts +44 -0
- package/types/store/dashboard-store.types.ts +23 -0
- package/types/store/vuex.d.ts +9 -0
- package/.DS_Store +0 -0
- package/creators/app/app.package.json +0 -13
- package/creators/app/files/.eslintignore +0 -18
- package/creators/app/files/.eslintrc.js +0 -173
- package/creators/app/files/.gitignore +0 -70
- package/creators/app/files/.vscode/settings.json +0 -22
- package/creators/app/files/babel.config.js +0 -1
- package/creators/app/files/tsconfig.json +0 -42
- package/creators/app/files/vue.config.js +0 -6
- package/creators/app/init +0 -101
- package/creators/app/package.json +0 -25
- package/creators/pkg/files/.github/workflows/build-extension-catalog.yml +0 -28
- package/creators/pkg/files/.github/workflows/build-extension-charts.yml +0 -26
- package/creators/pkg/files/babel.config.js +0 -1
- package/creators/pkg/files/index.ts +0 -14
- package/creators/pkg/files/tsconfig.json +0 -53
- package/creators/pkg/files/vue.config.js +0 -1
- package/creators/pkg/init +0 -254
- package/creators/pkg/package.json +0 -19
- package/creators/pkg/pkg.package.json +0 -21
- package/creators/pkg/vue-shim.ts +0 -4
- package/creators/update/init +0 -56
- package/creators/update/package.json +0 -20
- package/creators/update/upgrade +0 -56
- package/types/shell/index.d.ts +0 -4310
|
@@ -1300,6 +1300,7 @@ cluster:
|
|
|
1300
1300
|
placeholder: 'Namespace/Name'
|
|
1301
1301
|
cluster: Imported Harvester Cluster
|
|
1302
1302
|
installGuestAgent: Install guest agent
|
|
1303
|
+
tokenExpirationWarning: 'Warning: Harvester Cloud Credentials use an underlying authentication token that may have an expiry time - please see the following <a href="https://harvesterhci.io/kb/renew_harvester_cloud_credentials" target="_blank" rel="noopener nofollow">knowledge base article</a> for possible implications on management operations.'
|
|
1303
1304
|
description:
|
|
1304
1305
|
label: Cluster Description
|
|
1305
1306
|
placeholder: Any text you want that better describes this cluster
|
|
@@ -1818,6 +1819,7 @@ cluster:
|
|
|
1818
1819
|
oracleoke: Oracle OKE
|
|
1819
1820
|
otc: Open Telekom Cloud
|
|
1820
1821
|
other: Other
|
|
1822
|
+
ovhcloudmks: OVHcloud MKS
|
|
1821
1823
|
packet: Equinix Metal
|
|
1822
1824
|
pinganyunecs: Pinganyun ECS
|
|
1823
1825
|
pnap: phoenixNAP
|
|
@@ -7128,6 +7130,9 @@ advancedSettings:
|
|
|
7128
7130
|
'ui-default-landing': 'The default page users land on after login.'
|
|
7129
7131
|
'brand': Folder name for an alternative theme defined in '/assets/brand'
|
|
7130
7132
|
'hide-local-cluster': Hide the local cluster
|
|
7133
|
+
'agent-tls-mode': "Rancher Certificate Verification. In `strict` mode the agents (system, cluster, fleet, etc) will only trust Rancher installations which are using a certificate signed by the CABundle in the `cacerts` setting. When the mode is system-store, the agents will trust any certificate signed by a CABundle in the operating system’s trust store."
|
|
7134
|
+
warnings:
|
|
7135
|
+
'agent-tls-mode': 'Changing this setting will cause all agents to be redeployed.'
|
|
7131
7136
|
editHelp:
|
|
7132
7137
|
'ui-banners': This setting takes a JSON object containing 3 root parameters; <code>banner</code>, <code>showHeader</code>, <code>showFooter</code>. <code>banner</code> is an object containing; <code>textColor</code>, <code>background</code>, and <code>text</code>, where <code>textColor</code> and <code>background</code> are any valid CSS color value.
|
|
7133
7138
|
enum:
|
|
@@ -7150,6 +7155,9 @@ advancedSettings:
|
|
|
7150
7155
|
info: Info
|
|
7151
7156
|
debug: Debug
|
|
7152
7157
|
trace: Trace
|
|
7158
|
+
'agent-tls-mode':
|
|
7159
|
+
strict: 'Strict'
|
|
7160
|
+
system-store: 'System Store'
|
|
7153
7161
|
|
|
7154
7162
|
featureFlags:
|
|
7155
7163
|
label: Feature Flags
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils';
|
|
2
|
+
import HarvesterCloudCreds from '@shell/cloud-credential/harvester.vue';
|
|
3
|
+
|
|
4
|
+
const mockStore = { getters: { 'i18n/t': jest.fn() } };
|
|
5
|
+
|
|
6
|
+
describe('cloud credentials: Harvester', () => {
|
|
7
|
+
const wrapper = mount(HarvesterCloudCreds, {
|
|
8
|
+
propsData: { value: {} },
|
|
9
|
+
mocks: { $store: mockStore }
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('should display the warning banner for token expiration', async() => {
|
|
13
|
+
const warningBanner = wrapper.find('[data-testid="harvester-token-expiration-warning-banner"]');
|
|
14
|
+
|
|
15
|
+
expect(warningBanner.exists()).toBe(true);
|
|
16
|
+
expect(warningBanner.isVisible()).toBe(true);
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import CreateEditView from '@shell/mixins/create-edit-view';
|
|
3
3
|
import LabeledSelect from '@shell/components/form/LabeledSelect';
|
|
4
|
+
import { Banner } from '@components/Banner';
|
|
4
5
|
|
|
5
6
|
import { get, set } from '@shell/utils/object';
|
|
6
7
|
import { MANAGEMENT, VIRTUAL_HARVESTER_PROVIDER } from '@shell/config/types';
|
|
7
8
|
|
|
8
9
|
export default {
|
|
9
|
-
components: { LabeledSelect },
|
|
10
|
+
components: { LabeledSelect, Banner },
|
|
10
11
|
mixins: [CreateEditView],
|
|
11
12
|
|
|
12
13
|
async fetch() {
|
|
@@ -97,6 +98,13 @@ export default {
|
|
|
97
98
|
|
|
98
99
|
<template>
|
|
99
100
|
<div>
|
|
101
|
+
<div class="row mb-10">
|
|
102
|
+
<Banner
|
|
103
|
+
color="warning"
|
|
104
|
+
label-key="cluster.credential.harvester.tokenExpirationWarning"
|
|
105
|
+
data-testid="harvester-token-expiration-warning-banner"
|
|
106
|
+
/>
|
|
107
|
+
</div>
|
|
100
108
|
<div class="row mb-10">
|
|
101
109
|
<div
|
|
102
110
|
class="col span-6"
|
|
@@ -49,6 +49,7 @@ export default {
|
|
|
49
49
|
];
|
|
50
50
|
|
|
51
51
|
return {
|
|
52
|
+
inStore: this.$store.getters['currentProduct'].inStore,
|
|
52
53
|
alertManagerPoller: new Poller(
|
|
53
54
|
this.loadAlertManagerEvents,
|
|
54
55
|
ALERTMANAGER_POLL_RATE_MS,
|
|
@@ -69,15 +70,24 @@ export default {
|
|
|
69
70
|
},
|
|
70
71
|
|
|
71
72
|
methods: {
|
|
72
|
-
async
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
{ url: `/k8s/clusters/${ this.currentCluster.id }/api/v1/namespaces/${ this.monitoringNamespace }/services/http:${ this.alertServiceEndpoint }:9093/proxy/api/v1/alerts` }
|
|
73
|
+
async fetchAlertManagerEvents(version) {
|
|
74
|
+
return await this.$store.dispatch(
|
|
75
|
+
`${ this.inStore }/request`,
|
|
76
|
+
{ url: `/k8s/clusters/${ this.currentCluster.id }/api/v1/namespaces/${ this.monitoringNamespace }/services/http:${ this.alertServiceEndpoint }:9093/proxy/api/${ version }/alerts` }
|
|
77
77
|
);
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
async loadAlertManagerEvents() {
|
|
81
|
+
let alertEvents;
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
alertEvents = await this.fetchAlertManagerEvents('v2');
|
|
85
|
+
} catch (err) {
|
|
86
|
+
alertEvents = await this.fetchAlertManagerEvents('v1').then((res) => res?.data);
|
|
87
|
+
}
|
|
78
88
|
|
|
79
|
-
if (
|
|
80
|
-
this.allAlerts =
|
|
89
|
+
if (alertEvents) {
|
|
90
|
+
this.allAlerts = alertEvents;
|
|
81
91
|
}
|
|
82
92
|
},
|
|
83
93
|
|
|
@@ -114,10 +114,12 @@ export default {
|
|
|
114
114
|
this.interval = setInterval(() => {
|
|
115
115
|
try {
|
|
116
116
|
const graphWindow = this.$refs.frame?.contentWindow;
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const
|
|
120
|
-
const
|
|
117
|
+
|
|
118
|
+
// Note. getElementsByClassName won't work, following a grafana bump class names are now unique - for example css-2qng6u-panel-container
|
|
119
|
+
const errorElements = graphWindow.document.querySelectorAll('[class$="alert-error');
|
|
120
|
+
const errorCornerElements = graphWindow.document.querySelectorAll('[class$="panel-info-corner--error');
|
|
121
|
+
const panelInFullScreenElements = graphWindow.document.querySelectorAll('[class$="panel-in-fullscreen');
|
|
122
|
+
const panelContainerElements = graphWindow.document.querySelectorAll('[class$="panel-container');
|
|
121
123
|
const error = errorElements.length > 0 || errorCornerElements.length > 0;
|
|
122
124
|
const loaded = panelInFullScreenElements.length > 0 || panelContainerElements.length > 0;
|
|
123
125
|
const errorMessageElms = graphWindow.document.getElementsByTagName('pre');
|
|
@@ -855,7 +855,7 @@ export default {
|
|
|
855
855
|
}
|
|
856
856
|
}
|
|
857
857
|
|
|
858
|
-
> i {
|
|
858
|
+
> i, > img {
|
|
859
859
|
display: block;
|
|
860
860
|
width: 42px;
|
|
861
861
|
font-size: $icon-size;
|
|
@@ -867,9 +867,6 @@ export default {
|
|
|
867
867
|
margin-right: 16px;
|
|
868
868
|
fill: var(--link);
|
|
869
869
|
}
|
|
870
|
-
img {
|
|
871
|
-
margin-right: 16px;
|
|
872
|
-
}
|
|
873
870
|
|
|
874
871
|
&.nuxt-link-active {
|
|
875
872
|
background: var(--primary-hover-bg);
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
} from '@shell/config/table-headers';
|
|
23
23
|
|
|
24
24
|
import { DSL } from '@shell/store/type-map';
|
|
25
|
+
import { configureConditionalDepaginate } from '@shell/store/type-map.utils';
|
|
25
26
|
|
|
26
27
|
export const NAME = 'explorer';
|
|
27
28
|
|
|
@@ -49,7 +50,9 @@ export function init(store) {
|
|
|
49
50
|
typeStoreMap: {
|
|
50
51
|
[MANAGEMENT.PROJECT]: 'management',
|
|
51
52
|
[MANAGEMENT.CLUSTER_ROLE_TEMPLATE_BINDING]: 'management',
|
|
52
|
-
[MANAGEMENT.PROJECT_ROLE_TEMPLATE_BINDING]: 'management'
|
|
53
|
+
[MANAGEMENT.PROJECT_ROLE_TEMPLATE_BINDING]: 'management',
|
|
54
|
+
[NORMAN.CLUSTER_ROLE_TEMPLATE_BINDING]: 'rancher',
|
|
55
|
+
[NORMAN.PROJECT_ROLE_TEMPLATE_BINDING]: 'rancher',
|
|
53
56
|
}
|
|
54
57
|
});
|
|
55
58
|
|
|
@@ -156,12 +159,16 @@ export function init(store) {
|
|
|
156
159
|
mapGroup(/^(.*\.)?cluster\.x-k8s\.io$/, 'clusterProvisioning');
|
|
157
160
|
mapGroup(/^(aks|eks|gke|rke|rke-machine-config|rke-machine|provisioning)\.cattle\.io$/, 'clusterProvisioning');
|
|
158
161
|
|
|
162
|
+
const dePaginateBindings = configureConditionalDepaginate({ maxResourceCount: 5000 });
|
|
163
|
+
const dePaginateNormanBindings = configureConditionalDepaginate({ maxResourceCount: 5000, isNorman: true }) ;
|
|
164
|
+
|
|
159
165
|
configureType(NODE, { isCreatable: false, isEditable: true });
|
|
160
166
|
configureType(WORKLOAD_TYPES.JOB, { isEditable: false, match: WORKLOAD_TYPES.JOB });
|
|
161
|
-
configureType(MANAGEMENT.CLUSTER_ROLE_TEMPLATE_BINDING, { isEditable: false });
|
|
162
|
-
configureType(MANAGEMENT.PROJECT_ROLE_TEMPLATE_BINDING, { isEditable: false, depaginate:
|
|
167
|
+
configureType(MANAGEMENT.CLUSTER_ROLE_TEMPLATE_BINDING, { isEditable: false, depaginate: dePaginateBindings });
|
|
168
|
+
configureType(MANAGEMENT.PROJECT_ROLE_TEMPLATE_BINDING, { isEditable: false, depaginate: dePaginateBindings });
|
|
163
169
|
configureType(MANAGEMENT.PROJECT, { displayName: store.getters['i18n/t']('namespace.project.label') });
|
|
164
|
-
configureType(NORMAN.
|
|
170
|
+
configureType(NORMAN.CLUSTER_ROLE_TEMPLATE_BINDING, { depaginate: dePaginateNormanBindings });
|
|
171
|
+
configureType(NORMAN.PROJECT_ROLE_TEMPLATE_BINDING, { depaginate: dePaginateNormanBindings });
|
|
165
172
|
|
|
166
173
|
configureType(EVENT, { limit: 500 });
|
|
167
174
|
weightType(EVENT, -1, true);
|
package/config/settings.ts
CHANGED
|
@@ -19,7 +19,8 @@ interface GlobalSetting {
|
|
|
19
19
|
/**
|
|
20
20
|
* Function used from the form validation
|
|
21
21
|
*/
|
|
22
|
-
|
|
22
|
+
ruleSet?: GlobalSettingRuleset[],
|
|
23
|
+
warning?: string
|
|
23
24
|
};
|
|
24
25
|
}
|
|
25
26
|
|
|
@@ -90,8 +91,9 @@ export const SETTING = {
|
|
|
90
91
|
FLEET_AGENT_DEFAULT_AFFINITY: 'fleet-agent-default-affinity',
|
|
91
92
|
/**
|
|
92
93
|
* manage rancher repositories in extensions (official, partners repos)
|
|
93
|
-
|
|
94
|
+
*/
|
|
94
95
|
ADD_EXTENSION_REPOS_BANNER_DISPLAY: 'display-add-extension-repos-banner',
|
|
96
|
+
AGENT_TLS_MODE: 'agent-tls-mode',
|
|
95
97
|
/**
|
|
96
98
|
* User retention settings
|
|
97
99
|
*/
|
|
@@ -152,6 +154,11 @@ export const ALLOWED_SETTINGS: GlobalSetting = {
|
|
|
152
154
|
options: ['prompt', 'in', 'out']
|
|
153
155
|
},
|
|
154
156
|
[SETTING.HIDE_LOCAL_CLUSTER]: { kind: 'boolean' },
|
|
157
|
+
[SETTING.AGENT_TLS_MODE]: {
|
|
158
|
+
kind: 'enum',
|
|
159
|
+
options: ['strict', 'system-store'],
|
|
160
|
+
warning: 'agent-tls-mode'
|
|
161
|
+
},
|
|
155
162
|
};
|
|
156
163
|
|
|
157
164
|
/**
|
package/config/types.js
CHANGED
|
@@ -14,7 +14,7 @@ export const NORMAN = {
|
|
|
14
14
|
ETCD_BACKUP: 'etcdbackup',
|
|
15
15
|
CLUSTER: 'cluster',
|
|
16
16
|
CLUSTER_TOKEN: 'clusterregistrationtoken',
|
|
17
|
-
CLUSTER_ROLE_TEMPLATE_BINDING: '
|
|
17
|
+
CLUSTER_ROLE_TEMPLATE_BINDING: 'clusterroletemplatebinding',
|
|
18
18
|
CLOUD_CREDENTIAL: 'cloudcredential',
|
|
19
19
|
FLEET_WORKSPACES: 'fleetworkspace',
|
|
20
20
|
GLOBAL_ROLE: 'globalRole',
|
package/config/uiplugins.js
CHANGED
|
@@ -178,7 +178,7 @@ export function isChartVersionAvailableForInstall(versionsData, returnObj = fals
|
|
|
178
178
|
|
|
179
179
|
const parsedRancherVersion = rancherVersion.split('-')?.[0];
|
|
180
180
|
const regexHashString = new RegExp('^[A-Za-z0-9]{9}$');
|
|
181
|
-
const
|
|
181
|
+
const isRancherVersionHashStringOrHead = regexHashString.test(rancherVersion) || rancherVersion.includes('head');
|
|
182
182
|
const requiredUiVersion = version.annotations?.[UI_PLUGIN_CHART_ANNOTATIONS.UI_VERSION];
|
|
183
183
|
const requiredKubeVersion = version.annotations?.[UI_PLUGIN_CHART_ANNOTATIONS.KUBE_VERSION];
|
|
184
184
|
const versionObj = { ...version };
|
|
@@ -187,7 +187,7 @@ export function isChartVersionAvailableForInstall(versionsData, returnObj = fals
|
|
|
187
187
|
versionObj.isCompatibleWithKubeVersion = true;
|
|
188
188
|
|
|
189
189
|
// if it's a head version of Rancher, then we skip the validation and enable them all
|
|
190
|
-
if (!
|
|
190
|
+
if (!isRancherVersionHashStringOrHead && requiredUiVersion && !semver.satisfies(parsedRancherVersion, requiredUiVersion)) {
|
|
191
191
|
if (!returnObj) {
|
|
192
192
|
return false;
|
|
193
193
|
}
|
|
@@ -4,6 +4,7 @@ import { LabeledInput } from '@components/Form/LabeledInput';
|
|
|
4
4
|
import LabeledSelect from '@shell/components/form/LabeledSelect';
|
|
5
5
|
import CreateEditView from '@shell/mixins/create-edit-view';
|
|
6
6
|
import { TextAreaAutoGrow } from '@components/Form/TextArea';
|
|
7
|
+
import { Banner } from '@components/Banner';
|
|
7
8
|
import formRulesGenerator from '@shell/utils/validators/formRules/index';
|
|
8
9
|
|
|
9
10
|
import { ALLOWED_SETTINGS, SETTING } from '@shell/config/settings';
|
|
@@ -18,7 +19,8 @@ export default {
|
|
|
18
19
|
LabeledInput,
|
|
19
20
|
LabeledSelect,
|
|
20
21
|
RadioGroup,
|
|
21
|
-
TextAreaAutoGrow
|
|
22
|
+
TextAreaAutoGrow,
|
|
23
|
+
Banner,
|
|
22
24
|
},
|
|
23
25
|
|
|
24
26
|
mixins: [CreateEditView, FormValidation],
|
|
@@ -63,7 +65,11 @@ export default {
|
|
|
63
65
|
|
|
64
66
|
return factoryArg ? rule(factoryArg) : rule;
|
|
65
67
|
}) : {};
|
|
66
|
-
}
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
showWarningBanner() {
|
|
71
|
+
return this.setting?.warning;
|
|
72
|
+
},
|
|
67
73
|
},
|
|
68
74
|
|
|
69
75
|
methods: {
|
|
@@ -118,6 +124,13 @@ export default {
|
|
|
118
124
|
@finish="saveSettings"
|
|
119
125
|
@cancel="done"
|
|
120
126
|
>
|
|
127
|
+
<Banner
|
|
128
|
+
v-if="showWarningBanner"
|
|
129
|
+
color="warning"
|
|
130
|
+
:label="t(`advancedSettings.warnings.${ setting.warning }`)"
|
|
131
|
+
data-testid="advanced_settings_warning_banner"
|
|
132
|
+
/>
|
|
133
|
+
|
|
121
134
|
<h4>{{ description }}</h4>
|
|
122
135
|
|
|
123
136
|
<h5
|
|
@@ -7,6 +7,7 @@ import SelectOrCreateAuthSecret from '@shell/components/form/SelectOrCreateAuthS
|
|
|
7
7
|
import CreateEditView from '@shell/mixins/create-edit-view';
|
|
8
8
|
import SecretSelector from '@shell/components/form/SecretSelector';
|
|
9
9
|
import { SECRET_TYPES as TYPES } from '@shell/config/secret';
|
|
10
|
+
import { base64Decode, base64Encode } from '@shell/utils/crypto';
|
|
10
11
|
|
|
11
12
|
export default {
|
|
12
13
|
components: {
|
|
@@ -55,7 +56,7 @@ export default {
|
|
|
55
56
|
if (configMap[hostname]) {
|
|
56
57
|
configMap[hostname].insecureSkipVerify = configMap[hostname].insecureSkipVerify ?? defaultAddValue.insecureSkipVerify;
|
|
57
58
|
configMap[hostname].authConfigSecretName = configMap[hostname].authConfigSecretName ?? defaultAddValue.authConfigSecretName;
|
|
58
|
-
configMap[hostname].caBundle = configMap[hostname].caBundle ?? defaultAddValue.caBundle;
|
|
59
|
+
configMap[hostname].caBundle = base64Decode(configMap[hostname].caBundle ?? defaultAddValue.caBundle);
|
|
59
60
|
configMap[hostname].tlsSecretName = configMap[hostname].tlsSecretName ?? defaultAddValue.tlsSecretName;
|
|
60
61
|
}
|
|
61
62
|
entries.push({
|
|
@@ -94,7 +95,11 @@ export default {
|
|
|
94
95
|
continue;
|
|
95
96
|
}
|
|
96
97
|
|
|
97
|
-
configs[h] = {
|
|
98
|
+
configs[h] = {
|
|
99
|
+
...entry,
|
|
100
|
+
caBundle: base64Encode(entry.caBundle)
|
|
101
|
+
};
|
|
102
|
+
|
|
98
103
|
delete configs[h].hostname;
|
|
99
104
|
}
|
|
100
105
|
|
|
@@ -174,6 +179,7 @@ export default {
|
|
|
174
179
|
|
|
175
180
|
<LabeledInput
|
|
176
181
|
v-model="row.value.caBundle"
|
|
182
|
+
:data-testid="`registry-caBundle-${i}`"
|
|
177
183
|
class="mt-20"
|
|
178
184
|
type="multiline"
|
|
179
185
|
label="CA Cert Bundle"
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { mount, Wrapper } from '@vue/test-utils';
|
|
2
|
+
import { clone } from '@shell/utils/object';
|
|
3
|
+
import { _EDIT } from '@shell/config/query-params';
|
|
4
|
+
import { PROV_CLUSTER } from '@shell/edit/provisioning.cattle.io.cluster/__tests__/utils/cluster';
|
|
5
|
+
import RegistryConfigs from '@shell/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue';
|
|
6
|
+
|
|
7
|
+
describe('component: RegistryConfigs', () => {
|
|
8
|
+
let wrapper: Wrapper<InstanceType<typeof RegistryConfigs> & { [key: string]: any }>;
|
|
9
|
+
|
|
10
|
+
const mountOptions = {
|
|
11
|
+
propsData: {
|
|
12
|
+
value: {},
|
|
13
|
+
mode: _EDIT,
|
|
14
|
+
clusterRegisterBeforeHook: () => {}
|
|
15
|
+
},
|
|
16
|
+
stubs: {
|
|
17
|
+
SelectOrCreateAuthSecret: true,
|
|
18
|
+
SecretSelector: true,
|
|
19
|
+
},
|
|
20
|
+
mocks: { $store: { getters: { 'i18n/t': jest.fn() } } }
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
describe('key CA Cert Bundle', () => {
|
|
24
|
+
it('should display default key', () => {
|
|
25
|
+
const value = clone(PROV_CLUSTER);
|
|
26
|
+
|
|
27
|
+
value.spec.rkeConfig.registries.configs = { foo: { caBundle: 'Zm9vYmFy' } };
|
|
28
|
+
|
|
29
|
+
mountOptions.propsData.value = value;
|
|
30
|
+
|
|
31
|
+
wrapper = mount(
|
|
32
|
+
RegistryConfigs,
|
|
33
|
+
mountOptions
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
const registry = wrapper.find('[data-testid^="registry-caBundle"]').element as HTMLTextAreaElement;
|
|
37
|
+
|
|
38
|
+
expect(registry.value).toBe('foobar');
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('should update key in base64 format', async() => {
|
|
42
|
+
const value = clone(PROV_CLUSTER);
|
|
43
|
+
|
|
44
|
+
value.spec.rkeConfig.registries.configs = { foo: { caBundle: 'Zm9vYmFy' } };
|
|
45
|
+
|
|
46
|
+
mountOptions.propsData.value = value;
|
|
47
|
+
|
|
48
|
+
wrapper = mount(
|
|
49
|
+
RegistryConfigs,
|
|
50
|
+
mountOptions
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
const registry = wrapper.find('[data-testid^="registry-caBundle"]');
|
|
54
|
+
|
|
55
|
+
await registry.setValue('ssh key');
|
|
56
|
+
wrapper.vm.update();
|
|
57
|
+
|
|
58
|
+
expect(wrapper.emitted('updateConfigs')![0][0]['foo']['caBundle']).toBe('c3NoIGtleQ==');
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
});
|