@rancher/shell 3.0.9-rc.5 → 3.0.9-rc.6
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/images/providers/oci-open-containers.svg +22 -0
- package/assets/images/providers/traefik.png +0 -0
- package/assets/styles/themes/_dark.scss +2 -0
- package/assets/styles/themes/_light.scss +2 -0
- package/assets/styles/themes/_modern.scss +6 -0
- package/assets/translations/en-us.yaml +129 -25
- package/components/CruResource.vue +3 -1
- package/components/ExplorerProjectsNamespaces.vue +12 -12
- package/components/Resource/Detail/Card/StatusCard/__tests__/StatusCard.test.ts +109 -0
- package/components/Resource/Detail/Card/StatusCard/index.vue +21 -4
- package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/identifying-fields.test.ts +19 -2
- package/components/Resource/Detail/Metadata/IdentifyingInformation/identifying-fields.ts +19 -11
- package/components/Resource/Detail/ResourcePopover/__tests__/index.test.ts +12 -0
- package/components/Resource/Detail/ResourcePopover/index.vue +2 -0
- package/components/Resource/Detail/ResourceRow.vue +2 -2
- package/components/ResourceList/index.vue +7 -4
- package/components/Window/ContainerLogs.vue +48 -37
- package/components/fleet/FleetClusterTargets/TargetsList.vue +2 -2
- package/components/fleet/FleetClusterTargets/index.vue +6 -1
- package/components/fleet/GitRepoAdvancedTab.vue +333 -0
- package/components/fleet/GitRepoMetadataTab.vue +43 -0
- package/components/fleet/GitRepoRepositoryTab.vue +101 -0
- package/components/fleet/GitRepoTargetTab.vue +77 -0
- package/components/fleet/HelmOpAdvancedTab.vue +247 -0
- package/components/fleet/HelmOpChartTab.vue +158 -0
- package/components/fleet/HelmOpMetadataTab.vue +46 -0
- package/components/fleet/HelmOpTargetTab.vue +84 -0
- package/components/fleet/HelmOpValuesTab.vue +147 -0
- package/components/fleet/__tests__/FleetClusterTargets.test.ts +119 -70
- package/components/form/NodeScheduling.vue +81 -7
- package/components/form/PodAffinity.vue +1 -36
- package/components/form/ResourceLabeledSelect.vue +8 -4
- package/components/form/ResourceQuota/Namespace.vue +30 -9
- package/components/form/ResourceQuota/NamespaceRow.vue +25 -7
- package/components/form/ResourceQuota/Project.vue +140 -82
- package/components/form/ResourceQuota/ResourceQuotaEntry.vue +145 -0
- package/components/form/ResourceQuota/__tests__/Namespace.test.ts +307 -0
- package/components/form/ResourceQuota/__tests__/NamespaceRow.test.ts +281 -0
- package/components/form/ResourceQuota/__tests__/Project.test.ts +274 -27
- package/components/form/ResourceQuota/__tests__/ResourceQuotaEntry.test.ts +215 -0
- package/components/form/SchedulingCustomization.vue +14 -6
- package/components/form/SelectOrCreateAuthSecret.vue +107 -18
- package/components/form/__tests__/NodeScheduling.test.ts +12 -9
- package/components/form/__tests__/PodAffinity.test.ts +21 -2
- package/components/form/__tests__/SchedulingCustomization.test.ts +240 -0
- package/components/formatter/ClusterLink.vue +8 -0
- package/components/formatter/SecretOrigin.vue +79 -0
- package/config/labels-annotations.js +7 -6
- package/config/pagination-table-headers.js +6 -4
- package/config/product/explorer.js +1 -11
- package/config/query-params.js +3 -0
- package/config/settings.ts +15 -2
- package/config/table-headers.js +21 -17
- package/config/types.js +23 -8
- package/detail/workload/index.vue +11 -16
- package/dialog/DeactivateDriverDialog.vue +1 -1
- package/dialog/Ipv6NetworkingDialog.vue +156 -0
- package/dialog/ScalePoolDownDialog.vue +2 -2
- package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +1 -1
- package/edit/__tests__/fleet.cattle.io.helmop.test.ts +1 -0
- package/edit/__tests__/management.cattle.io.project.test.js +56 -128
- package/edit/auth/oidc.vue +1 -1
- package/edit/catalog.cattle.io.clusterrepo.vue +155 -25
- package/edit/fleet.cattle.io.gitrepo.vue +153 -283
- package/edit/fleet.cattle.io.helmop.vue +190 -332
- package/edit/management.cattle.io.project.vue +5 -42
- package/edit/management.cattle.io.setting.vue +6 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/Basics.test.ts +55 -24
- package/edit/provisioning.cattle.io.cluster/__tests__/Networking.test.ts +1 -103
- package/edit/provisioning.cattle.io.cluster/__tests__/index.test.ts +13 -1
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2-fleet-cluster-agent.test.ts +283 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +65 -49
- package/edit/provisioning.cattle.io.cluster/ingress/IngressCards.vue +112 -0
- package/edit/provisioning.cattle.io.cluster/ingress/IngressConfiguration.vue +158 -0
- package/edit/provisioning.cattle.io.cluster/rke2.vue +171 -72
- package/edit/provisioning.cattle.io.cluster/shared.ts +36 -1
- package/edit/provisioning.cattle.io.cluster/tabs/AgentConfiguration.vue +2 -1
- package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +55 -7
- package/edit/provisioning.cattle.io.cluster/tabs/Ingress.vue +319 -0
- package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +2 -1
- package/edit/provisioning.cattle.io.cluster/tabs/etcd/__tests__/S3Config.test.ts +13 -1
- package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +10 -44
- package/edit/secret/index.vue +1 -1
- package/edit/token.vue +68 -29
- package/edit/workload/__tests__/index.test.ts +2 -37
- package/edit/workload/index.vue +6 -2
- package/edit/workload/mixins/workload.js +0 -32
- package/list/__tests__/management.cattle.io.setting.test.ts +198 -0
- package/list/management.cattle.io.setting.vue +13 -0
- package/list/provisioning.cattle.io.cluster.vue +50 -1
- package/list/secret.vue +4 -9
- package/list/service.vue +6 -8
- package/machine-config/amazonec2.vue +11 -4
- package/machine-config/components/EC2Networking.vue +46 -30
- package/machine-config/components/__tests__/EC2Networking.test.ts +7 -7
- package/machine-config/components/__tests__/utils/vpcSubnetMockData.js +0 -9
- package/machine-config/digitalocean.vue +3 -3
- package/models/__tests__/namespace.test.ts +11 -0
- package/models/__tests__/provisioning.cattle.io.cluster.test.ts +96 -0
- package/models/__tests__/workload.test.ts +42 -1
- package/models/catalog.cattle.io.clusterrepo.js +30 -4
- package/models/ext.cattle.io.token.js +48 -0
- package/models/kontainerdriver.js +2 -2
- package/models/namespace.js +7 -1
- package/models/nodedriver.js +2 -2
- package/models/provisioning.cattle.io.cluster.js +28 -7
- package/models/secret.js +0 -17
- package/models/service.js +44 -1
- package/models/token.js +4 -0
- package/models/workload.js +12 -6
- package/package.json +1 -1
- package/pages/account/index.vue +96 -67
- package/pages/auth/setup.vue +5 -14
- package/pages/c/_cluster/apps/charts/__tests__/install.test.ts +4 -1
- package/pages/c/_cluster/apps/charts/index.vue +93 -4
- package/pages/c/_cluster/apps/charts/install.vue +317 -42
- package/pages/c/_cluster/manager/drivers/kontainerDriver/index.vue +5 -4
- package/pages/c/_cluster/settings/index.vue +3 -1
- package/plugins/dashboard-store/__tests__/getters.test.ts +108 -0
- package/plugins/dashboard-store/__tests__/resource-class.test.ts +27 -0
- package/plugins/dashboard-store/actions.js +3 -8
- package/plugins/dashboard-store/getters.js +7 -5
- package/plugins/dashboard-store/mutations.js +4 -1
- package/plugins/dashboard-store/resource-class.js +3 -3
- package/plugins/steve/__tests__/steve-class.test.ts +102 -141
- package/plugins/steve/steve-class.js +12 -3
- package/plugins/steve/steve-pagination-utils.ts +6 -2
- package/rancher-components/RcIcon/types.ts +2 -0
- package/rancher-components/RcItemCard/RcItemCard.vue +64 -19
- package/store/prefs.js +3 -0
- package/types/aws-sdk.d.ts +121 -0
- package/types/resources/node.ts +15 -0
- package/types/shell/index.d.ts +536 -506
- package/types/store/pagination.types.ts +5 -5
- package/utils/__tests__/array.test.ts +1 -29
- package/utils/__tests__/cluster-agent-configuration.test.ts +203 -0
- package/utils/array.ts +0 -11
- package/utils/aws.ts +21 -0
- package/utils/cluster.js +22 -2
- package/utils/selector-typed.ts +1 -1
- package/components/__tests__/ProjectRow.test.ts +0 -206
- package/components/form/ResourceQuota/ProjectRow.vue +0 -277
|
@@ -162,6 +162,12 @@ export default {
|
|
|
162
162
|
class="edit-help"
|
|
163
163
|
/>
|
|
164
164
|
|
|
165
|
+
<Banner
|
|
166
|
+
v-if="setting.agent"
|
|
167
|
+
color="info"
|
|
168
|
+
:label="t('advancedSettings.edit.agentConfigBanner.text', { agent: t('advancedSettings.edit.agentConfigBanner.' + setting.agent) })"
|
|
169
|
+
data-testid="setting-agent-config-banner"
|
|
170
|
+
/>
|
|
165
171
|
<div class="edit-change mt-20">
|
|
166
172
|
<h5 v-t="'advancedSettings.edit.changeSetting'" />
|
|
167
173
|
<button
|
|
@@ -2,17 +2,20 @@ import { nextTick } from 'vue';
|
|
|
2
2
|
import { mount } from '@vue/test-utils';
|
|
3
3
|
import Basics from '@shell/edit/provisioning.cattle.io.cluster/tabs/Basics.vue';
|
|
4
4
|
// import Checkbox from '@components/Form/Checkbox/Checkbox.vue';
|
|
5
|
+
import { RKE2_INGRESS_NGINX, RKE2_TRAEFIK } from '@shell/edit/provisioning.cattle.io.cluster/shared';
|
|
5
6
|
|
|
6
7
|
const defaultStubs = {
|
|
7
|
-
Banner:
|
|
8
|
-
LabeledSelect:
|
|
9
|
-
YamlEditor:
|
|
10
|
-
Checkbox:
|
|
8
|
+
Banner: true,
|
|
9
|
+
LabeledSelect: true,
|
|
10
|
+
YamlEditor: true,
|
|
11
|
+
Checkbox: true,
|
|
12
|
+
RichTranslation: true
|
|
11
13
|
};
|
|
12
14
|
|
|
13
15
|
const defaultCiliumStubs = {
|
|
14
|
-
LabeledSelect:
|
|
15
|
-
YamlEditor:
|
|
16
|
+
LabeledSelect: true,
|
|
17
|
+
YamlEditor: true,
|
|
18
|
+
RichTranslation: true
|
|
16
19
|
};
|
|
17
20
|
|
|
18
21
|
// const defaultComputed = {
|
|
@@ -25,46 +28,65 @@ const defaultCiliumStubs = {
|
|
|
25
28
|
// };
|
|
26
29
|
|
|
27
30
|
const mockAgentArgs = { 'cloud-provider-name': { options: [], profile: { options: [{ anything: 'yes' }] } } };
|
|
28
|
-
const mockServerArgs = { disable: {}, cni: { options: [] } };
|
|
29
|
-
|
|
31
|
+
const mockServerArgs = { disable: { options: [] }, cni: { options: [] } };
|
|
32
|
+
|
|
33
|
+
jest.mock('@shell/edit/provisioning.cattle.io.cluster/shared', () => ({
|
|
34
|
+
RETENTION_DEFAULT: 5,
|
|
35
|
+
RKE2_INGRESS_NGINX: 'rke2-ingress-nginx',
|
|
36
|
+
RKE2_TRAEFIK: 'rke2-traefik',
|
|
37
|
+
INGRESS_NGINX: 'ingress-nginx',
|
|
38
|
+
INGRESS_CONTROLLER: 'ingress-controller',
|
|
39
|
+
TRAEFIK: 'traefik',
|
|
40
|
+
HARVESTER: 'harvester',
|
|
41
|
+
INGRESS_DUAL: 'dual',
|
|
42
|
+
INGRESS_NONE: 'none',
|
|
43
|
+
INGRESS_OPTIONS: [],
|
|
44
|
+
INGRESS_MIGRATION_KB_LINK: 'mock-link'
|
|
45
|
+
}));
|
|
46
|
+
const mockRke2Charts = {
|
|
47
|
+
[RKE2_INGRESS_NGINX]: {},
|
|
48
|
+
[RKE2_TRAEFIK]: {},
|
|
49
|
+
'rke2-cilium': {}
|
|
50
|
+
};
|
|
51
|
+
const mockK3sCharts = { 'rke2-cilium': {} };
|
|
30
52
|
const rke2Versions = [
|
|
31
53
|
{
|
|
32
|
-
id: 'v1.31.0+rke2r1', value: 'v1.31.0+rke2r1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts:
|
|
54
|
+
id: 'v1.31.0+rke2r1', value: 'v1.31.0+rke2r1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts: mockRke2Charts
|
|
33
55
|
},
|
|
34
56
|
{
|
|
35
|
-
id: 'v1.30.0+rke2r1', value: 'v1.30.0+rke2r1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts:
|
|
57
|
+
id: 'v1.30.0+rke2r1', value: 'v1.30.0+rke2r1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts: mockRke2Charts
|
|
36
58
|
},
|
|
37
59
|
{
|
|
38
|
-
id: 'v1.29.1+rke2r1', value: 'v1.29.1+rke2r1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts:
|
|
60
|
+
id: 'v1.29.1+rke2r1', value: 'v1.29.1+rke2r1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts: mockRke2Charts
|
|
39
61
|
},
|
|
40
62
|
{
|
|
41
|
-
id: 'v1.25.0+rke2r1', value: 'v1.25.0+rke2r1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts:
|
|
63
|
+
id: 'v1.25.0+rke2r1', value: 'v1.25.0+rke2r1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts: mockRke2Charts
|
|
42
64
|
},
|
|
43
65
|
{
|
|
44
|
-
id: 'v1.24.0+rke2r1', value: 'v1.24.0+rke2r1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts:
|
|
66
|
+
id: 'v1.24.0+rke2r1', value: 'v1.24.0+rke2r1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts: mockRke2Charts
|
|
45
67
|
},
|
|
46
68
|
{
|
|
47
|
-
id: 'v1.23.0+rke2r1', value: 'v1.23.0+rke2r1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts:
|
|
69
|
+
id: 'v1.23.0+rke2r1', value: 'v1.23.0+rke2r1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts: mockRke2Charts
|
|
48
70
|
}
|
|
49
71
|
];
|
|
50
72
|
const k3sVersions = [
|
|
51
73
|
{
|
|
52
|
-
id: 'v1.31.0+k3s1', value: 'v1.31.0+k3s1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts:
|
|
74
|
+
id: 'v1.31.0+k3s1', value: 'v1.31.0+k3s1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts: mockK3sCharts
|
|
53
75
|
},
|
|
54
76
|
{
|
|
55
|
-
id: 'v1.30.0+k3s1', value: 'v1.30.0+k3s1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts:
|
|
77
|
+
id: 'v1.30.0+k3s1', value: 'v1.30.0+k3s1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts: mockK3sCharts
|
|
56
78
|
},
|
|
57
79
|
{
|
|
58
|
-
id: 'v1.29.1+k3s1', value: 'v1.29.1+k3s1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts:
|
|
80
|
+
id: 'v1.29.1+k3s1', value: 'v1.29.1+k3s1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts: mockK3sCharts
|
|
59
81
|
},
|
|
60
82
|
{
|
|
61
|
-
id: 'v1.25.0+k3s1', value: 'v1.25.0+k3s1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts:
|
|
83
|
+
id: 'v1.25.0+k3s1', value: 'v1.25.0+k3s1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts: mockK3sCharts
|
|
62
84
|
},
|
|
63
85
|
{
|
|
64
|
-
id: 'v1.24.0+k3s1', value: 'v1.24.0+k3s1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts:
|
|
86
|
+
id: 'v1.24.0+k3s1', value: 'v1.24.0+k3s1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts: mockK3sCharts
|
|
65
87
|
},
|
|
66
88
|
{
|
|
67
|
-
id: 'v1.23.0+k3s1', value: 'v1.23.0+k3s1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts:
|
|
89
|
+
id: 'v1.23.0+k3s1', value: 'v1.23.0+k3s1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts: mockK3sCharts
|
|
68
90
|
}
|
|
69
91
|
];
|
|
70
92
|
const mockVersionOptions = [...rke2Versions, ...k3sVersions];
|
|
@@ -83,7 +105,7 @@ const defaultMocks = {
|
|
|
83
105
|
$route: {
|
|
84
106
|
name: 'anything',
|
|
85
107
|
query: { AS: 'yaml' },
|
|
86
|
-
}
|
|
108
|
+
}
|
|
87
109
|
};
|
|
88
110
|
|
|
89
111
|
const defaultSpec = {
|
|
@@ -103,6 +125,9 @@ const bmOffValue = { bandwidthManager: { enabled: false } };
|
|
|
103
125
|
function createBasicsTab(version : string, userChartValues: any, options = {}) {
|
|
104
126
|
const k8s = mockVersionOptions.find((v) => v.id === version) || mockVersionOptions[0];
|
|
105
127
|
const label = 'whatever';
|
|
128
|
+
const providedUserChartValues = userChartValues || {};
|
|
129
|
+
const providedVersionInfo = k8s.charts || {};
|
|
130
|
+
|
|
106
131
|
const wrapper = mount(Basics, {
|
|
107
132
|
props: {
|
|
108
133
|
mode: 'create',
|
|
@@ -116,7 +141,8 @@ function createBasicsTab(version : string, userChartValues: any, options = {}) {
|
|
|
116
141
|
},
|
|
117
142
|
addonVersions: [],
|
|
118
143
|
provider: 'custom',
|
|
119
|
-
userChartValues:
|
|
144
|
+
userChartValues: providedUserChartValues,
|
|
145
|
+
versionInfo: providedVersionInfo,
|
|
120
146
|
cisOverride: false,
|
|
121
147
|
cisPsaChangeBanner: true,
|
|
122
148
|
allPsas: [],
|
|
@@ -142,7 +168,6 @@ function createBasicsTab(version : string, userChartValues: any, options = {}) {
|
|
|
142
168
|
...defaultMocks,
|
|
143
169
|
$store: { getters: defaultGetters },
|
|
144
170
|
},
|
|
145
|
-
|
|
146
171
|
stubs: defaultCiliumStubs,
|
|
147
172
|
},
|
|
148
173
|
});
|
|
@@ -176,6 +201,8 @@ describe('component: Basics', () => {
|
|
|
176
201
|
},
|
|
177
202
|
provider: 'whatever',
|
|
178
203
|
userChartValues: {},
|
|
204
|
+
addonVersions: [],
|
|
205
|
+
versionInfo: {},
|
|
179
206
|
cisOverride: false,
|
|
180
207
|
cisPsaChangeBanner: true,
|
|
181
208
|
allPsas: [],
|
|
@@ -228,6 +255,8 @@ describe('component: Basics', () => {
|
|
|
228
255
|
},
|
|
229
256
|
provider: 'whatever',
|
|
230
257
|
userChartValues: {},
|
|
258
|
+
addonVersions: [],
|
|
259
|
+
versionInfo: {},
|
|
231
260
|
cisOverride: false,
|
|
232
261
|
cisPsaChangeBanner: true,
|
|
233
262
|
allPsas: [],
|
|
@@ -277,6 +306,8 @@ describe('component: Basics', () => {
|
|
|
277
306
|
},
|
|
278
307
|
provider: 'custom',
|
|
279
308
|
userChartValues: {},
|
|
309
|
+
addonVersions: [],
|
|
310
|
+
versionInfo: {},
|
|
280
311
|
cisPsaChangeBanner: true,
|
|
281
312
|
allPsas: [],
|
|
282
313
|
cisOverride: override,
|
|
@@ -284,7 +315,7 @@ describe('component: Basics', () => {
|
|
|
284
315
|
versionOptions: [{
|
|
285
316
|
value: k8s,
|
|
286
317
|
agentArgs: { profile: { options: [cis] } },
|
|
287
|
-
charts:
|
|
318
|
+
charts: mockRke2Charts,
|
|
288
319
|
profile: { options: [cis] }
|
|
289
320
|
}],
|
|
290
321
|
isHarvesterDriver: false,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { shallowMount } from '@vue/test-utils';
|
|
2
2
|
import Networking from '@shell/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue';
|
|
3
3
|
|
|
4
4
|
const mockServerArgs = { disable: {}, cni: { options: [] } };
|
|
@@ -47,34 +47,6 @@ describe('component: RKE2Networking', () => {
|
|
|
47
47
|
expect(dropdown.props('options')).toHaveLength(3);
|
|
48
48
|
});
|
|
49
49
|
|
|
50
|
-
it('should show an error when an ipv6 pool is present and the user selects the ipv4-only stack preference when creating a new cluster', async() => {
|
|
51
|
-
const spec = { ...defaultSpec, rkeConfig: { ...defaultSpec.rkeConfig, networking: { stackPreference: 'ipv4' } } };
|
|
52
|
-
const wrapper = mount(Networking, {
|
|
53
|
-
propsData: {
|
|
54
|
-
mode: 'create',
|
|
55
|
-
value: { spec },
|
|
56
|
-
selectedVersion: { serverArgs: mockServerArgs },
|
|
57
|
-
hasSomeIpv6Pools: true,
|
|
58
|
-
},
|
|
59
|
-
global: {
|
|
60
|
-
mocks: {
|
|
61
|
-
...defaultMocks,
|
|
62
|
-
$store: { getters: defaultGetters },
|
|
63
|
-
},
|
|
64
|
-
},
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
expect(wrapper.emitted('validationChanged')?.[0]?.[0]).toBe(false);
|
|
68
|
-
expect(wrapper.emitted('validationChanged')).toHaveLength(1);
|
|
69
|
-
|
|
70
|
-
spec.rkeConfig.networking.stackPreference = 'ipv6';
|
|
71
|
-
wrapper.setProps({ value: { spec } });
|
|
72
|
-
await wrapper.vm.$nextTick();
|
|
73
|
-
|
|
74
|
-
expect(wrapper.emitted('validationChanged')?.[1]?.[0]).toBe(true);
|
|
75
|
-
expect(wrapper.emitted('validationChanged')).toHaveLength(2);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
50
|
it('should show a flannel masq input when provisioning k3s and flannel is enabled', () => {
|
|
79
51
|
const spec = { ...defaultSpec } as any;
|
|
80
52
|
|
|
@@ -119,78 +91,4 @@ describe('component: RKE2Networking', () => {
|
|
|
119
91
|
expect(wrapper.vm.showFlannelMasq).toBe(false);
|
|
120
92
|
expect(input.exists()).toBe(false);
|
|
121
93
|
});
|
|
122
|
-
|
|
123
|
-
it('should automatically check the flannel masq input when stack preference is changed from ipv4 to ipv6 or dual', async() => {
|
|
124
|
-
const spec = { ...defaultSpec } as any;
|
|
125
|
-
|
|
126
|
-
spec.rkeConfig.networking.stackPreference = 'ipv4';
|
|
127
|
-
|
|
128
|
-
const wrapper = shallowMount(Networking, {
|
|
129
|
-
propsData: {
|
|
130
|
-
mode: 'create',
|
|
131
|
-
value: { spec },
|
|
132
|
-
selectedVersion: { serverArgs: mockServerArgs, label: 'k3s' },
|
|
133
|
-
},
|
|
134
|
-
global: { mocks: {} }
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
const newSpec = { ...spec };
|
|
138
|
-
|
|
139
|
-
newSpec.rkeConfig.networking.stackPreference = 'dual';
|
|
140
|
-
|
|
141
|
-
await wrapper.setProps({ value: { spec: newSpec } });
|
|
142
|
-
|
|
143
|
-
expect(wrapper.emitted('enable-flannel-masq-changed')?.[0]?.[0]).toBe(true);
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
it('should automatically un-check the flannel masq input when stack preference is changed from ipv6 or dual to ipv4', async() => {
|
|
147
|
-
const spec = { ...defaultSpec } as any;
|
|
148
|
-
|
|
149
|
-
spec.rkeConfig.networking.stackPreference = 'ipv6';
|
|
150
|
-
|
|
151
|
-
const wrapper = shallowMount(Networking, {
|
|
152
|
-
propsData: {
|
|
153
|
-
mode: 'create',
|
|
154
|
-
value: { spec },
|
|
155
|
-
selectedVersion: { serverArgs: mockServerArgs, label: 'k3s' },
|
|
156
|
-
},
|
|
157
|
-
global: {
|
|
158
|
-
mocks: {
|
|
159
|
-
...defaultMocks,
|
|
160
|
-
$store: { getters: defaultGetters },
|
|
161
|
-
},
|
|
162
|
-
},
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
const newSpec = { ...spec };
|
|
166
|
-
|
|
167
|
-
newSpec.rkeConfig.networking.stackPreference = 'ipv4';
|
|
168
|
-
|
|
169
|
-
await wrapper.setProps({ value: { spec: newSpec } });
|
|
170
|
-
|
|
171
|
-
expect(wrapper.emitted('enable-flannel-masq-changed')?.[0]?.[0]).toBe(false);
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
it('should not automatically update stack preference or validate it when editing an existing cluster even if its set to ipv4 and the user appears to have ipv6 pools', async() => {
|
|
175
|
-
const spec = { ...defaultSpec, rkeConfig: { ...defaultSpec.rkeConfig, networking: { stackPreference: 'ipv4' } } };
|
|
176
|
-
const wrapper = mount(Networking, {
|
|
177
|
-
propsData: {
|
|
178
|
-
mode: 'edit',
|
|
179
|
-
value: { spec },
|
|
180
|
-
selectedVersion: { serverArgs: mockServerArgs },
|
|
181
|
-
hasSomeIpv6Pools: true,
|
|
182
|
-
},
|
|
183
|
-
global: {
|
|
184
|
-
mocks: {
|
|
185
|
-
...defaultMocks,
|
|
186
|
-
$store: { getters: defaultGetters },
|
|
187
|
-
},
|
|
188
|
-
},
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
await wrapper.vm.$nextTick();
|
|
192
|
-
|
|
193
|
-
expect(wrapper.emitted('validationChanged')?.[0]?.[0]).toBe(true);
|
|
194
|
-
expect(wrapper.emitted('stack-preference-changed')).toBeUndefined();
|
|
195
|
-
});
|
|
196
94
|
});
|
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
import { shallowMount } from '@vue/test-utils';
|
|
2
2
|
import { createStore } from 'vuex';
|
|
3
3
|
import ClusterCreate from '@shell/edit/provisioning.cattle.io.cluster/index.vue';
|
|
4
|
-
|
|
4
|
+
jest.mock('@shell/edit/provisioning.cattle.io.cluster/shared', () => ({
|
|
5
|
+
RETENTION_DEFAULT: 5,
|
|
6
|
+
RKE2_INGRESS_NGINX: 'rke2-ingress-nginx',
|
|
7
|
+
RKE2_TRAEFIK: 'rke2-traefik',
|
|
8
|
+
INGRESS_NGINX: 'ingress-nginx',
|
|
9
|
+
INGRESS_CONTROLLER: 'ingress-controller',
|
|
10
|
+
TRAEFIK: 'traefik',
|
|
11
|
+
HARVESTER: 'harvester',
|
|
12
|
+
INGRESS_DUAL: 'dual',
|
|
13
|
+
INGRESS_NONE: 'none',
|
|
14
|
+
INGRESS_OPTIONS: [],
|
|
15
|
+
INGRESS_MIGRATION_KB_LINK: 'mock-link'
|
|
16
|
+
}));
|
|
5
17
|
describe('component: Cluster: Create', () => {
|
|
6
18
|
it('should hide RKE1 and RKE2 toggle button if RKE1 ui feature flag is NOT set', () => {
|
|
7
19
|
const store = createStore({
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import { shallowMount } from '@vue/test-utils';
|
|
2
|
+
import { nextTick } from 'vue';
|
|
3
|
+
import RKE2 from '@shell/edit/provisioning.cattle.io.cluster/rke2.vue';
|
|
4
|
+
import { AGENT_CONFIGURATION_TYPES } from '@shell/config/settings';
|
|
5
|
+
|
|
6
|
+
jest.mock('@shell/edit/provisioning.cattle.io.cluster/shared', () => ({
|
|
7
|
+
RETENTION_DEFAULT: 5,
|
|
8
|
+
RKE2_INGRESS_NGINX: 'rke2-ingress-nginx',
|
|
9
|
+
RKE2_TRAEFIK: 'rke2-traefik',
|
|
10
|
+
INGRESS_NGINX: 'ingress-nginx',
|
|
11
|
+
INGRESS_CONTROLLER: 'ingress-controller',
|
|
12
|
+
TRAEFIK: 'traefik',
|
|
13
|
+
HARVESTER: 'harvester',
|
|
14
|
+
INGRESS_DUAL: 'dual',
|
|
15
|
+
INGRESS_NONE: 'none',
|
|
16
|
+
INGRESS_OPTIONS: [],
|
|
17
|
+
INGRESS_MIGRATION_KB_LINK: 'mock-link'
|
|
18
|
+
}));
|
|
19
|
+
const mockStore = {
|
|
20
|
+
getters: {
|
|
21
|
+
'management/schemaFor': jest.fn().mockReturnValue(null),
|
|
22
|
+
'management/byId': jest.fn().mockReturnValue({}),
|
|
23
|
+
'management/canList': jest.fn().mockReturnValue(true),
|
|
24
|
+
'management/all': jest.fn().mockReturnValue([]),
|
|
25
|
+
'rancher/all': jest.fn().mockReturnValue([]),
|
|
26
|
+
'rancher/byId': jest.fn().mockReturnValue({}),
|
|
27
|
+
'i18n/t': jest.fn().mockImplementation((key) => key),
|
|
28
|
+
'i18n/withFallback': jest.fn().mockImplementation((key) => key),
|
|
29
|
+
'features/get': jest.fn().mockReturnValue(() => true),
|
|
30
|
+
'plugins/cloudProviderForDriver': jest.fn().mockReturnValue(undefined),
|
|
31
|
+
currentCluster: {},
|
|
32
|
+
'customisation/getPreviewCluster': {
|
|
33
|
+
badge: {
|
|
34
|
+
iconText: '', color: '', text: ''
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
productId: 'rancher',
|
|
38
|
+
currentStore: jest.fn().mockReturnValue('management')
|
|
39
|
+
},
|
|
40
|
+
dispatch: jest.fn().mockResolvedValue({ data: [] })
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const mockRoute = {
|
|
44
|
+
query: {},
|
|
45
|
+
name: 'test'
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const mockValue = {
|
|
49
|
+
metadata: {
|
|
50
|
+
name: 'test-cluster',
|
|
51
|
+
annotations: {}
|
|
52
|
+
},
|
|
53
|
+
spec: {
|
|
54
|
+
kubernetesVersion: 'v1.25.0+rke2r1',
|
|
55
|
+
rkeConfig: {
|
|
56
|
+
machineGlobalConfig: {},
|
|
57
|
+
networking: { stackPreference: 'ipv4' },
|
|
58
|
+
machineSelectorConfig: [{ config: {} }],
|
|
59
|
+
dataDirectories: {}
|
|
60
|
+
},
|
|
61
|
+
clusterAgentDeploymentCustomization: {},
|
|
62
|
+
fleetAgentDeploymentCustomization: {}
|
|
63
|
+
},
|
|
64
|
+
agentConfig: {}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const createWrapper = (propsData: any = {}) => {
|
|
68
|
+
return shallowMount(RKE2, {
|
|
69
|
+
propsData: {
|
|
70
|
+
mode: 'create',
|
|
71
|
+
value: { ...mockValue, ...propsData.value },
|
|
72
|
+
provider: 'custom',
|
|
73
|
+
...propsData
|
|
74
|
+
},
|
|
75
|
+
global: {
|
|
76
|
+
mocks: {
|
|
77
|
+
$store: mockStore,
|
|
78
|
+
$route: mockRoute,
|
|
79
|
+
$router: { replace: jest.fn() },
|
|
80
|
+
t: jest.fn().mockImplementation((key) => key),
|
|
81
|
+
$extension: { getDynamic: jest.fn().mockReturnValue(undefined) },
|
|
82
|
+
$fetchState: { pending: false, error: null }
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
data() {
|
|
86
|
+
return {
|
|
87
|
+
loadedOnce: true,
|
|
88
|
+
rke2Versions: null,
|
|
89
|
+
k3sVersions: null,
|
|
90
|
+
defaultRke2: 'v1.25.0+rke2r1',
|
|
91
|
+
defaultK3s: 'v1.25.0+k3s1'
|
|
92
|
+
} as any;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
describe('component: RKE2 - Fleet Agent Configuration', () => {
|
|
98
|
+
let wrapper: any;
|
|
99
|
+
|
|
100
|
+
beforeEach(() => {
|
|
101
|
+
jest.clearAllMocks();
|
|
102
|
+
wrapper = createWrapper();
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
afterEach(() => {
|
|
106
|
+
if (wrapper) {
|
|
107
|
+
wrapper.unmount();
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
describe('fleet Agent Scheduling Customization', () => {
|
|
112
|
+
beforeEach(async() => {
|
|
113
|
+
// Initialize the component with fleet agent defaults
|
|
114
|
+
wrapper.vm.fleetAgentDefaultPC = { value: 100, preemptionPolicy: 'PreemptLowerPriority' };
|
|
115
|
+
wrapper.vm.fleetAgentDefaultPDB = { maxUnavailable: 1 };
|
|
116
|
+
wrapper.vm.schedulingCustomizationFeatureEnabled = true;
|
|
117
|
+
await nextTick();
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('should enable Fleet Agent scheduling customization when event is true', async() => {
|
|
121
|
+
const event = { event: true, agentType: AGENT_CONFIGURATION_TYPES.FLEET };
|
|
122
|
+
|
|
123
|
+
wrapper.vm.setSchedulingCustomization(event);
|
|
124
|
+
|
|
125
|
+
expect(wrapper.vm.value.spec.fleetAgentDeploymentCustomization.schedulingCustomization).toStrictEqual({
|
|
126
|
+
priorityClass: wrapper.vm.fleetAgentDefaultPC,
|
|
127
|
+
podDisruptionBudget: wrapper.vm.fleetAgentDefaultPDB
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('should disable Fleet Agent scheduling customization when event is false', async() => {
|
|
132
|
+
// First enable it
|
|
133
|
+
const enableEvent = { event: true, agentType: AGENT_CONFIGURATION_TYPES.FLEET };
|
|
134
|
+
|
|
135
|
+
wrapper.vm.setSchedulingCustomization(enableEvent);
|
|
136
|
+
|
|
137
|
+
// Then disable it
|
|
138
|
+
const disableEvent = { event: false, agentType: AGENT_CONFIGURATION_TYPES.FLEET };
|
|
139
|
+
|
|
140
|
+
wrapper.vm.setSchedulingCustomization(disableEvent);
|
|
141
|
+
|
|
142
|
+
expect(wrapper.vm.value.spec.fleetAgentDeploymentCustomization.schedulingCustomization).toBeUndefined();
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('should enable Cluster Agent scheduling customization when event is true', async() => {
|
|
146
|
+
// Initialize cluster agent defaults
|
|
147
|
+
wrapper.vm.clusterAgentDefaultPC = { value: 200, preemptionPolicy: 'PreemptLowerPriority' };
|
|
148
|
+
wrapper.vm.clusterAgentDefaultPDB = { maxUnavailable: 2 };
|
|
149
|
+
|
|
150
|
+
const event = { event: true, agentType: AGENT_CONFIGURATION_TYPES.CLUSTER };
|
|
151
|
+
|
|
152
|
+
wrapper.vm.setSchedulingCustomization(event);
|
|
153
|
+
|
|
154
|
+
expect(wrapper.vm.value.spec.clusterAgentDeploymentCustomization.schedulingCustomization).toStrictEqual({
|
|
155
|
+
priorityClass: wrapper.vm.clusterAgentDefaultPC,
|
|
156
|
+
podDisruptionBudget: wrapper.vm.clusterAgentDefaultPDB
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it('should disable Cluster Agent scheduling customization when event is false', async() => {
|
|
161
|
+
// Initialize cluster agent defaults
|
|
162
|
+
wrapper.vm.clusterAgentDefaultPC = { value: 200, preemptionPolicy: 'PreemptLowerPriority' };
|
|
163
|
+
wrapper.vm.clusterAgentDefaultPDB = { maxUnavailable: 2 };
|
|
164
|
+
|
|
165
|
+
// First enable it
|
|
166
|
+
const enableEvent = { event: true, agentType: AGENT_CONFIGURATION_TYPES.CLUSTER };
|
|
167
|
+
|
|
168
|
+
wrapper.vm.setSchedulingCustomization(enableEvent);
|
|
169
|
+
|
|
170
|
+
// Then disable it
|
|
171
|
+
const disableEvent = { event: false, agentType: AGENT_CONFIGURATION_TYPES.CLUSTER };
|
|
172
|
+
|
|
173
|
+
wrapper.vm.setSchedulingCustomization(disableEvent);
|
|
174
|
+
|
|
175
|
+
expect(wrapper.vm.value.spec.clusterAgentDeploymentCustomization.schedulingCustomization).toBeUndefined();
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it('should handle unknown agent types gracefully', async() => {
|
|
179
|
+
const event = { event: true, agentType: 'unknown' };
|
|
180
|
+
|
|
181
|
+
// Should not throw an error
|
|
182
|
+
expect(() => wrapper.vm.setSchedulingCustomization(event)).not.toThrow();
|
|
183
|
+
|
|
184
|
+
// Should not modify any agent configuration
|
|
185
|
+
expect(wrapper.vm.value.spec.clusterAgentDeploymentCustomization.schedulingCustomization).toBeUndefined();
|
|
186
|
+
expect(wrapper.vm.value.spec.fleetAgentDeploymentCustomization.schedulingCustomization).toBeUndefined();
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it('should pass the correct agent type to SchedulingCustomization components', async() => {
|
|
190
|
+
await wrapper.vm.$nextTick();
|
|
191
|
+
|
|
192
|
+
// Check if AGENT_CONFIGURATION_TYPES is available in the component data
|
|
193
|
+
expect(wrapper.vm.AGENT_CONFIGURATION_TYPES).toBeDefined();
|
|
194
|
+
expect(wrapper.vm.AGENT_CONFIGURATION_TYPES.CLUSTER).toBe('cluster');
|
|
195
|
+
expect(wrapper.vm.AGENT_CONFIGURATION_TYPES.FLEET).toBe('fleet');
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
describe('fleet Agent Configuration Data Initialization', () => {
|
|
200
|
+
it('should initialize fleet agent default configuration properties', () => {
|
|
201
|
+
expect(wrapper.vm.fleetAgentDefaultPC).toBeDefined();
|
|
202
|
+
expect(wrapper.vm.fleetAgentDefaultPDB).toBeDefined();
|
|
203
|
+
expect(wrapper.vm.AGENT_CONFIGURATION_TYPES).toBeDefined();
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it('should have AGENT_CONFIGURATION_TYPES with correct values', () => {
|
|
207
|
+
expect(wrapper.vm.AGENT_CONFIGURATION_TYPES).toStrictEqual({
|
|
208
|
+
CLUSTER: 'cluster',
|
|
209
|
+
FLEET: 'fleet'
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
describe('fleet Agent Configuration Template', () => {
|
|
215
|
+
it('should render AgentConfiguration for fleet agent with correct props', async() => {
|
|
216
|
+
// Set up fleet agent configuration to ensure it renders
|
|
217
|
+
wrapper.vm.value.spec.fleetAgentDeploymentCustomization = {};
|
|
218
|
+
wrapper.vm.schedulingCustomizationFeatureEnabled = true;
|
|
219
|
+
wrapper.vm.fleetAgentDefaultPC = { value: 100 };
|
|
220
|
+
wrapper.vm.fleetAgentDefaultPDB = { maxUnavailable: 1 };
|
|
221
|
+
await nextTick();
|
|
222
|
+
|
|
223
|
+
// Force re-render
|
|
224
|
+
await wrapper.vm.$forceUpdate();
|
|
225
|
+
await nextTick();
|
|
226
|
+
|
|
227
|
+
// The template should contain fleet agent configuration
|
|
228
|
+
// This tests the template structure even if the component isn't fully mounted
|
|
229
|
+
expect(wrapper.vm.value.spec.fleetAgentDeploymentCustomization).toBeDefined();
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
describe('flannel Masquerade Configuration', () => {
|
|
234
|
+
let k3sWrapper: any;
|
|
235
|
+
|
|
236
|
+
beforeEach(() => {
|
|
237
|
+
const k3sValue = {
|
|
238
|
+
...mockValue,
|
|
239
|
+
spec: {
|
|
240
|
+
...mockValue.spec,
|
|
241
|
+
rkeConfig: {
|
|
242
|
+
...mockValue.spec.rkeConfig,
|
|
243
|
+
machineGlobalConfig: { 'flannel-backend': 'vxlan' } // flannel enabled
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
k3sWrapper = createWrapper({ value: k3sValue });
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
afterEach(() => {
|
|
252
|
+
if (k3sWrapper) {
|
|
253
|
+
k3sWrapper.unmount();
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
it('should handle flannel masquerade configuration change', async() => {
|
|
258
|
+
k3sWrapper.vm.handleFlannelMasqChanged(true);
|
|
259
|
+
|
|
260
|
+
expect(k3sWrapper.vm.serverConfig['flannel-ipv6-masq']).toBe(true);
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
it('should remove flannel masquerade configuration when set to false', async() => {
|
|
264
|
+
// First set it to true
|
|
265
|
+
k3sWrapper.vm.handleFlannelMasqChanged(true);
|
|
266
|
+
expect(k3sWrapper.vm.serverConfig['flannel-ipv6-masq']).toBe(true);
|
|
267
|
+
|
|
268
|
+
// Then set it to false
|
|
269
|
+
k3sWrapper.vm.handleFlannelMasqChanged(false);
|
|
270
|
+
expect(k3sWrapper.vm.serverConfig['flannel-ipv6-masq']).toBe(false);
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
it('should remove flannel masquerade configuration when set to null/undefined', async() => {
|
|
274
|
+
// First set it to true
|
|
275
|
+
k3sWrapper.vm.handleFlannelMasqChanged(true);
|
|
276
|
+
expect(k3sWrapper.vm.serverConfig['flannel-ipv6-masq']).toBe(true);
|
|
277
|
+
|
|
278
|
+
// Then set it to null
|
|
279
|
+
k3sWrapper.vm.handleFlannelMasqChanged(null);
|
|
280
|
+
expect(k3sWrapper.vm.serverConfig['flannel-ipv6-masq']).toBeUndefined();
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
});
|