@rancher/shell 0.3.8 → 0.3.10
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 +47 -26
- package/assets/translations/zh-hans.yaml +82 -16
- package/babel.config.js +17 -4
- package/chart/istio.vue +11 -11
- package/chart/rancher-backup/S3.vue +1 -1
- package/components/AsyncButton.vue +2 -2
- package/components/ButtonGroup.vue +1 -1
- package/components/CodeMirror.vue +146 -14
- package/components/CompoundStatusBadge.vue +1 -1
- package/components/ContainerResourceLimit.vue +14 -1
- package/components/CopyCode.vue +1 -1
- package/components/CruResource.vue +21 -5
- package/components/DetailTop.vue +1 -1
- package/components/ExplorerProjectsNamespaces.vue +8 -4
- package/components/GlobalRoleBindings.vue +1 -1
- package/components/GroupPanel.vue +57 -0
- package/components/HarvesterServiceAddOnConfig.vue +2 -117
- package/components/ResourceDetail/Masthead.vue +1 -1
- package/components/ResourceList/Masthead.vue +0 -6
- package/components/ResourceList/ResourceLoadingIndicator.vue +1 -9
- package/components/ResourceList/index.vue +7 -6
- package/components/ResourceTable.vue +13 -3
- package/components/SortableTable/THead.vue +3 -3
- package/components/SortableTable/index.vue +3 -3
- package/components/Tabbed/Tab.vue +1 -1
- package/components/Tabbed/index.vue +1 -1
- package/components/Wizard.vue +9 -6
- package/components/YamlEditor.vue +2 -2
- package/components/__tests__/NamespaceFilter.test.ts +26 -7
- package/components/auth/RoleDetailEdit.vue +1 -1
- package/components/auth/SelectPrincipal.vue +1 -1
- package/components/fleet/FleetRepos.vue +1 -1
- package/components/form/ArrayList.vue +2 -2
- package/components/form/KeyValue.vue +37 -3
- package/components/form/Labels.vue +34 -14
- package/components/form/MatchExpressions.vue +120 -21
- package/components/form/Members/ClusterPermissionsEditor.vue +1 -1
- package/components/form/NameNsDescription.vue +1 -1
- package/components/form/NodeAffinity.vue +54 -4
- package/components/form/PlusMinus.vue +2 -2
- package/components/form/PodAffinity.vue +160 -47
- package/components/form/Probe.vue +1 -1
- package/components/form/ProjectMemberEditor.vue +8 -4
- package/components/form/ResourceQuota/NamespaceRow.vue +1 -1
- package/components/form/ServicePorts.vue +2 -2
- package/components/form/Tolerations.vue +70 -7
- package/components/form/WorkloadPorts.vue +2 -1
- package/components/form/__tests__/ArrayList.test.ts +3 -3
- package/components/form/__tests__/KeyValue.test.ts +17 -0
- package/components/form/__tests__/MatchExpressions.test.ts +1 -1
- package/components/formatter/ClusterLink.vue +3 -3
- package/components/formatter/LiveDate.vue +1 -1
- package/components/formatter/PodImages.vue +1 -1
- package/components/formatter/RKETemplateName.vue +1 -1
- package/components/formatter/Shortened.vue +1 -1
- package/components/nav/Header.vue +9 -7
- package/components/nav/NamespaceFilter.vue +103 -54
- package/config/labels-annotations.js +8 -5
- package/config/settings.ts +8 -6
- package/config/types.js +6 -4
- package/core/plugin-routes.ts +26 -7
- package/detail/provisioning.cattle.io.cluster.vue +4 -4
- package/edit/cis.cattle.io.clusterscan.vue +1 -1
- package/edit/configmap.vue +33 -6
- package/edit/k8s.cni.cncf.io.networkattachmentdefinition.vue +19 -149
- package/edit/logging-flow/index.vue +2 -2
- package/edit/logging.banzaicloud.io.output/providers/elasticsearch.vue +12 -0
- package/edit/logging.banzaicloud.io.output/providers/opensearch.vue +12 -0
- package/edit/management.cattle.io.project.vue +7 -0
- package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +1 -1
- package/edit/monitoring.coreos.com.alertmanagerconfig/routeConfig.vue +2 -2
- package/edit/monitoring.coreos.com.prometheusrule/GroupRules.vue +11 -8
- package/edit/networking.k8s.io.networkpolicy/PolicyRule.vue +2 -2
- package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +12 -4
- package/edit/networking.k8s.io.networkpolicy/__tests__/PolicyRuleTarget.spec.ts +140 -0
- package/edit/networking.k8s.io.networkpolicy/__tests__/utils/mock.json +158 -0
- package/edit/networking.k8s.io.networkpolicy/__tests__/utils/selectors.ts +45 -0
- package/edit/networking.k8s.io.networkpolicy/index.vue +1 -1
- package/edit/provisioning.cattle.io.cluster/AgentConfiguration.vue +326 -0
- package/edit/provisioning.cattle.io.cluster/MachinePool.vue +1 -1
- package/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue +1 -1
- package/edit/provisioning.cattle.io.cluster/RegistryMirrors.vue +2 -2
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +143 -169
- package/edit/provisioning.cattle.io.cluster/index.vue +1 -0
- package/edit/provisioning.cattle.io.cluster/rke2.vue +75 -6
- package/edit/resources.cattle.io.restore.vue +2 -2
- package/edit/service.vue +22 -3
- package/edit/storage.k8s.io.storageclass/index.vue +1 -1
- package/edit/workload/Job.vue +2 -2
- package/edit/workload/index.vue +1 -1
- package/edit/workload/mixins/workload.js +7 -1
- package/edit/workload/storage/__tests__/Storage.test.ts +84 -5
- package/initialize/index.js +1 -0
- package/layouts/default.vue +1 -1
- package/mixins/chart.js +1 -1
- package/mixins/resource-fetch-namespaced.js +19 -27
- package/mixins/resource-fetch.js +0 -5
- package/models/__tests__/namespace.test.ts +125 -0
- package/models/batch.cronjob.js +18 -3
- package/models/management.cattle.io.project.js +6 -1
- package/models/persistentvolume.js +1 -1
- package/models/workload.js +1 -1
- package/models/workload.service.js +22 -7
- package/package.json +17 -6
- package/pages/auth/login.vue +47 -49
- package/pages/c/_cluster/apps/charts/chart.vue +1 -1
- package/pages/c/_cluster/apps/charts/install.vue +42 -51
- package/pages/c/_cluster/explorer/index.vue +1 -1
- package/pages/c/_cluster/monitoring/index.vue +1 -1
- package/pages/c/_cluster/settings/performance.vue +53 -18
- package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +1 -1
- package/pages/c/_cluster/uiplugins/index.vue +16 -5
- package/pages/home.vue +1 -1
- package/pages/prefs.vue +18 -2
- package/plugins/clean-html-directive.js +1 -1
- package/plugins/clean-tooltip-directive.js +33 -0
- package/plugins/codemirror.js +158 -0
- package/plugins/dashboard-store/actions.js +4 -2
- package/plugins/dashboard-store/getters.js +6 -0
- package/plugins/dashboard-store/mutations.js +2 -2
- package/plugins/plugin.js +6 -1
- package/plugins/steve/actions.js +1 -1
- package/plugins/steve/getters.js +14 -3
- package/plugins/steve/resourceWatcher.js +36 -62
- package/plugins/steve/subscribe.js +137 -21
- package/plugins/steve/worker/index.js +7 -1
- package/plugins/steve/worker/web-worker.advanced.js +26 -8
- package/plugins/steve/worker/web-worker.basic.js +23 -4
- package/public/index.html +1 -1
- package/rancher-components/components/Form/Checkbox/Checkbox.vue +2 -2
- package/rancher-components/components/Form/Radio/RadioGroup.vue +2 -2
- package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +1 -1
- package/store/index.js +16 -61
- package/store/store-types.js +5 -0
- package/store/type-map.js +1 -1
- package/types/shell/index.d.ts +42 -7
- package/utils/__tests__/create-yaml.test.ts +63 -0
- package/utils/array.ts +4 -0
- package/utils/create-yaml.js +105 -8
- package/utils/namespace-filter.js +17 -5
- package/utils/projectAndNamespaceFiltering.utils.ts +62 -0
- package/utils/selector.js +6 -5
- package/utils/settings.ts +17 -7
- package/vue.config.js +2 -2
- package/models/k8s.cni.cncf.io.networkattachmentdefinition.js +0 -93
|
@@ -77,7 +77,7 @@ export default {
|
|
|
77
77
|
<h3>
|
|
78
78
|
{{ t('registryMirror.header') }}
|
|
79
79
|
<i
|
|
80
|
-
v-tooltip="t('registryMirror.toolTip')"
|
|
80
|
+
v-clean-tooltip="t('registryMirror.toolTip')"
|
|
81
81
|
class="icon icon-info"
|
|
82
82
|
/>
|
|
83
83
|
</h3>
|
|
@@ -116,7 +116,7 @@ export default {
|
|
|
116
116
|
<h3>
|
|
117
117
|
{{ t('registryMirrorRewrite.header') }}
|
|
118
118
|
<i
|
|
119
|
-
v-tooltip="t('registryMirrorRewrite.toolTip')"
|
|
119
|
+
v-clean-tooltip="t('registryMirrorRewrite.toolTip')"
|
|
120
120
|
class="icon icon-info"
|
|
121
121
|
/>
|
|
122
122
|
</h3>
|
|
@@ -1,8 +1,80 @@
|
|
|
1
1
|
import { mount } from '@vue/test-utils';
|
|
2
2
|
import rke2 from '@shell/edit/provisioning.cattle.io.cluster/rke2.vue';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* DISCLAIMER ***************************************************************************************
|
|
6
|
+
* Declarations should not be done outside the tests!!
|
|
7
|
+
* This component is overwhelming for test and requires too much initialization.
|
|
8
|
+
* In this way the tests are more readable and we can avoid annoying repetitions.
|
|
9
|
+
****************************************************************************************************
|
|
10
|
+
*/
|
|
11
|
+
const defaultStubs = {
|
|
12
|
+
CruResource: { template: '<div><slot></slot></div>' }, // Required to render the slot content
|
|
13
|
+
Banner: true,
|
|
14
|
+
LabeledSelect: true,
|
|
15
|
+
ACE: true,
|
|
16
|
+
AgentEnv: true,
|
|
17
|
+
ArrayList: true,
|
|
18
|
+
ArrayListGrouped: true,
|
|
19
|
+
BadgeState: true,
|
|
20
|
+
Checkbox: true,
|
|
21
|
+
ClusterMembershipEditor: true,
|
|
22
|
+
DrainOptions: true,
|
|
23
|
+
LabeledInput: true,
|
|
24
|
+
Labels: true,
|
|
25
|
+
Loading: true,
|
|
26
|
+
MachinePool: true,
|
|
27
|
+
MatchExpressions: true,
|
|
28
|
+
NameNsDescription: true,
|
|
29
|
+
Questions: true,
|
|
30
|
+
RadioGroup: true,
|
|
31
|
+
RegistryConfigs: true,
|
|
32
|
+
RegistryMirrors: true,
|
|
33
|
+
S3Config: true,
|
|
34
|
+
SelectCredential: true,
|
|
35
|
+
SelectOrCreateAuthSecret: true,
|
|
36
|
+
Tab: true,
|
|
37
|
+
Tabbed: true,
|
|
38
|
+
UnitInput: true,
|
|
39
|
+
YamlEditor: true,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const defaultComputed = {
|
|
43
|
+
showForm() {
|
|
44
|
+
return true;
|
|
45
|
+
},
|
|
46
|
+
showk8s21LegacyWarning() {
|
|
47
|
+
return false;
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const defaultGetters = {
|
|
52
|
+
currentStore: () => 'current_store',
|
|
53
|
+
'management/schemaFor': jest.fn(),
|
|
54
|
+
'current_store/all': jest.fn(),
|
|
55
|
+
'i18n/t': jest.fn(),
|
|
56
|
+
'i18n/withFallback': jest.fn(),
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const defaultMocks = {
|
|
60
|
+
$fetchState: { pending: false },
|
|
61
|
+
$route: {
|
|
62
|
+
name: 'anything',
|
|
63
|
+
query: { AS: 'yaml' },
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const defaultSpec = {
|
|
68
|
+
rkeConfig: { etcd: { disableSnapshots: false } },
|
|
69
|
+
chartValues: {},
|
|
70
|
+
};
|
|
71
|
+
|
|
4
72
|
describe('component: rke2', () => {
|
|
5
|
-
|
|
73
|
+
/**
|
|
74
|
+
* DISCLAIMER ***************************************************************************************
|
|
75
|
+
* Logs are prevented to avoid polluting the test output.
|
|
76
|
+
****************************************************************************************************
|
|
77
|
+
*/
|
|
6
78
|
// eslint-disable-next-line jest/no-hooks
|
|
7
79
|
beforeEach(() => {
|
|
8
80
|
jest.spyOn(console, 'log').mockImplementation(() => {});
|
|
@@ -23,76 +95,25 @@ describe('component: rke2', () => {
|
|
|
23
95
|
mode: 'create',
|
|
24
96
|
value: {
|
|
25
97
|
spec: {
|
|
26
|
-
|
|
27
|
-
chartValues: {},
|
|
98
|
+
...defaultSpec,
|
|
28
99
|
defaultPodSecurityAdmissionConfigurationTemplateName: label,
|
|
29
100
|
kubernetesVersion: k8s
|
|
30
101
|
}
|
|
31
102
|
},
|
|
32
103
|
provider: 'whatever',
|
|
33
|
-
resource: {}
|
|
34
104
|
},
|
|
35
|
-
computed:
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
},
|
|
39
|
-
hasMachinePools() {
|
|
40
|
-
return false;
|
|
41
|
-
},
|
|
42
|
-
showk8s21LegacyWarning() {
|
|
43
|
-
return false;
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
mocks: {
|
|
47
|
-
$fetchState: { pending: false },
|
|
48
|
-
$route: {
|
|
49
|
-
name: 'anything',
|
|
50
|
-
query: { AS: 'yaml' },
|
|
51
|
-
},
|
|
105
|
+
computed: defaultComputed,
|
|
106
|
+
mocks: {
|
|
107
|
+
...defaultMocks,
|
|
52
108
|
$store: {
|
|
53
|
-
getters:
|
|
54
|
-
currentStore: () => 'current_store',
|
|
55
|
-
'management/schemaFor': jest.fn(),
|
|
56
|
-
'current_store/all': jest.fn(),
|
|
57
|
-
'i18n/t': jest.fn(),
|
|
58
|
-
'i18n/withFallback': jest.fn(),
|
|
59
|
-
},
|
|
109
|
+
getters: defaultGetters,
|
|
60
110
|
dispatch: {
|
|
61
111
|
'management/find': jest.fn(),
|
|
62
112
|
'management/findAll': () => ([option]),
|
|
63
113
|
}
|
|
64
114
|
},
|
|
65
115
|
},
|
|
66
|
-
stubs:
|
|
67
|
-
CruResource: { template: '<div><slot></slot></div>' }, // Required to render the slot content
|
|
68
|
-
Banner: true,
|
|
69
|
-
LabeledSelect: true,
|
|
70
|
-
ACE: true,
|
|
71
|
-
AgentEnv: true,
|
|
72
|
-
ArrayList: true,
|
|
73
|
-
ArrayListGrouped: true,
|
|
74
|
-
BadgeState: true,
|
|
75
|
-
Checkbox: true,
|
|
76
|
-
ClusterMembershipEditor: true,
|
|
77
|
-
DrainOptions: true,
|
|
78
|
-
LabeledInput: true,
|
|
79
|
-
Labels: true,
|
|
80
|
-
Loading: true,
|
|
81
|
-
MachinePool: true,
|
|
82
|
-
MatchExpressions: true,
|
|
83
|
-
NameNsDescription: true,
|
|
84
|
-
Questions: true,
|
|
85
|
-
RadioGroup: true,
|
|
86
|
-
RegistryConfigs: true,
|
|
87
|
-
RegistryMirrors: true,
|
|
88
|
-
S3Config: true,
|
|
89
|
-
SelectCredential: true,
|
|
90
|
-
SelectOrCreateAuthSecret: true,
|
|
91
|
-
Tab: true,
|
|
92
|
-
Tabbed: true,
|
|
93
|
-
UnitInput: true,
|
|
94
|
-
YamlEditor: true,
|
|
95
|
-
}
|
|
116
|
+
stubs: defaultStubs
|
|
96
117
|
});
|
|
97
118
|
|
|
98
119
|
const select = wrapper.find('[data-testid="rke2-custom-edit-psa"]');
|
|
@@ -115,76 +136,25 @@ describe('component: rke2', () => {
|
|
|
115
136
|
mode: 'create',
|
|
116
137
|
value: {
|
|
117
138
|
spec: {
|
|
118
|
-
|
|
119
|
-
chartValues: {},
|
|
139
|
+
...defaultSpec,
|
|
120
140
|
defaultPodSecurityAdmissionConfigurationTemplateName: label,
|
|
121
141
|
kubernetesVersion: k8s
|
|
122
142
|
}
|
|
123
143
|
},
|
|
124
144
|
provider: 'whatever',
|
|
125
|
-
resource: {}
|
|
126
|
-
},
|
|
127
|
-
computed: {
|
|
128
|
-
showForm() {
|
|
129
|
-
return true;
|
|
130
|
-
},
|
|
131
|
-
hasMachinePools() {
|
|
132
|
-
return false;
|
|
133
|
-
},
|
|
134
|
-
showk8s21LegacyWarning() {
|
|
135
|
-
return false;
|
|
136
|
-
},
|
|
137
145
|
},
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
name: 'anything',
|
|
142
|
-
query: { AS: 'yaml' },
|
|
143
|
-
},
|
|
146
|
+
computed: defaultComputed,
|
|
147
|
+
mocks: {
|
|
148
|
+
...defaultMocks,
|
|
144
149
|
$store: {
|
|
145
|
-
getters:
|
|
146
|
-
currentStore: () => 'current_store',
|
|
147
|
-
'management/schemaFor': jest.fn(),
|
|
148
|
-
'current_store/all': jest.fn(),
|
|
149
|
-
'i18n/t': jest.fn(),
|
|
150
|
-
'i18n/withFallback': jest.fn(),
|
|
151
|
-
},
|
|
150
|
+
getters: defaultGetters,
|
|
152
151
|
dispatch: {
|
|
153
152
|
'management/find': jest.fn(),
|
|
154
153
|
'management/findAll': () => ([option]),
|
|
155
154
|
}
|
|
156
155
|
},
|
|
157
156
|
},
|
|
158
|
-
stubs:
|
|
159
|
-
CruResource: { template: '<div><slot></slot></div>' }, // Required to render the slot content
|
|
160
|
-
Banner: true,
|
|
161
|
-
LabeledSelect: true,
|
|
162
|
-
ACE: true,
|
|
163
|
-
AgentEnv: true,
|
|
164
|
-
ArrayList: true,
|
|
165
|
-
ArrayListGrouped: true,
|
|
166
|
-
BadgeState: true,
|
|
167
|
-
Checkbox: true,
|
|
168
|
-
ClusterMembershipEditor: true,
|
|
169
|
-
DrainOptions: true,
|
|
170
|
-
LabeledInput: true,
|
|
171
|
-
Labels: true,
|
|
172
|
-
Loading: true,
|
|
173
|
-
MachinePool: true,
|
|
174
|
-
MatchExpressions: true,
|
|
175
|
-
NameNsDescription: true,
|
|
176
|
-
Questions: true,
|
|
177
|
-
RadioGroup: true,
|
|
178
|
-
RegistryConfigs: true,
|
|
179
|
-
RegistryMirrors: true,
|
|
180
|
-
S3Config: true,
|
|
181
|
-
SelectCredential: true,
|
|
182
|
-
SelectOrCreateAuthSecret: true,
|
|
183
|
-
Tab: true,
|
|
184
|
-
Tabbed: true,
|
|
185
|
-
UnitInput: true,
|
|
186
|
-
YamlEditor: true,
|
|
187
|
-
}
|
|
157
|
+
stubs: defaultStubs
|
|
188
158
|
});
|
|
189
159
|
|
|
190
160
|
const select = wrapper.find('[data-testid="rke2-custom-edit-psa"]');
|
|
@@ -206,25 +176,15 @@ describe('component: rke2', () => {
|
|
|
206
176
|
value: {
|
|
207
177
|
agentConfig: { profile: cis },
|
|
208
178
|
spec: {
|
|
209
|
-
|
|
210
|
-
chartValues: {},
|
|
179
|
+
...defaultSpec,
|
|
211
180
|
defaultPodSecurityAdmissionConfigurationTemplateName: label,
|
|
212
181
|
kubernetesVersion: k8s
|
|
213
182
|
}
|
|
214
183
|
},
|
|
215
184
|
provider: 'custom',
|
|
216
|
-
resource: {}
|
|
217
185
|
},
|
|
218
186
|
computed: {
|
|
219
|
-
|
|
220
|
-
return true;
|
|
221
|
-
},
|
|
222
|
-
hasMachinePools() {
|
|
223
|
-
return false;
|
|
224
|
-
},
|
|
225
|
-
showk8s21LegacyWarning() {
|
|
226
|
-
return false;
|
|
227
|
-
},
|
|
187
|
+
...defaultComputed,
|
|
228
188
|
agentArgs: () => ({ profile: { options: [cis] } }),
|
|
229
189
|
versionOptions: () => [
|
|
230
190
|
{
|
|
@@ -236,55 +196,16 @@ describe('component: rke2', () => {
|
|
|
236
196
|
]
|
|
237
197
|
},
|
|
238
198
|
mocks: {
|
|
239
|
-
|
|
240
|
-
$route: {
|
|
241
|
-
name: 'anything',
|
|
242
|
-
query: { AS: 'yaml' },
|
|
243
|
-
},
|
|
199
|
+
...defaultMocks,
|
|
244
200
|
$store: {
|
|
245
|
-
getters:
|
|
246
|
-
currentStore: () => 'current_store',
|
|
247
|
-
'management/schemaFor': jest.fn(),
|
|
248
|
-
'current_store/all': jest.fn(),
|
|
249
|
-
'i18n/t': jest.fn(),
|
|
250
|
-
'i18n/withFallback': jest.fn(),
|
|
251
|
-
},
|
|
201
|
+
getters: defaultGetters,
|
|
252
202
|
dispatch: {
|
|
253
203
|
'management/find': jest.fn(),
|
|
254
204
|
'management/findAll': () => ([option]),
|
|
255
205
|
}
|
|
256
206
|
},
|
|
257
207
|
},
|
|
258
|
-
stubs:
|
|
259
|
-
CruResource: { template: '<div><slot></slot></div>' }, // Required to render the slot content
|
|
260
|
-
Banner: true,
|
|
261
|
-
LabeledSelect: true,
|
|
262
|
-
ACE: true,
|
|
263
|
-
AgentEnv: true,
|
|
264
|
-
ArrayList: true,
|
|
265
|
-
ArrayListGrouped: true,
|
|
266
|
-
BadgeState: true,
|
|
267
|
-
Checkbox: true,
|
|
268
|
-
ClusterMembershipEditor: true,
|
|
269
|
-
DrainOptions: true,
|
|
270
|
-
LabeledInput: true,
|
|
271
|
-
Labels: true,
|
|
272
|
-
Loading: true,
|
|
273
|
-
MachinePool: true,
|
|
274
|
-
MatchExpressions: true,
|
|
275
|
-
NameNsDescription: true,
|
|
276
|
-
Questions: true,
|
|
277
|
-
RadioGroup: true,
|
|
278
|
-
RegistryConfigs: true,
|
|
279
|
-
RegistryMirrors: true,
|
|
280
|
-
S3Config: true,
|
|
281
|
-
SelectCredential: true,
|
|
282
|
-
SelectOrCreateAuthSecret: true,
|
|
283
|
-
Tab: true,
|
|
284
|
-
Tabbed: true,
|
|
285
|
-
UnitInput: true,
|
|
286
|
-
YamlEditor: true,
|
|
287
|
-
}
|
|
208
|
+
stubs: defaultStubs
|
|
288
209
|
});
|
|
289
210
|
|
|
290
211
|
wrapper.setData({ cisOverride: override });
|
|
@@ -293,4 +214,57 @@ describe('component: rke2', () => {
|
|
|
293
214
|
|
|
294
215
|
expect((select.vm as unknown as any).disabled).toBe(disabled);
|
|
295
216
|
});
|
|
217
|
+
|
|
218
|
+
it.each([
|
|
219
|
+
['custom', true],
|
|
220
|
+
['anything else', false] // without proper data, machine pool is always not present
|
|
221
|
+
])('should allow creation of RKE2 cluster with provider %p if pool machines are missing (%p)', (provider, result) => {
|
|
222
|
+
const k8s = 'v1.25.0+rke2r1';
|
|
223
|
+
const wrapper = mount(rke2, {
|
|
224
|
+
propsData: {
|
|
225
|
+
mode: 'create',
|
|
226
|
+
value: {
|
|
227
|
+
spec: {
|
|
228
|
+
...defaultSpec,
|
|
229
|
+
kubernetesVersion: k8s,
|
|
230
|
+
|
|
231
|
+
}
|
|
232
|
+
},
|
|
233
|
+
provider,
|
|
234
|
+
},
|
|
235
|
+
computed: defaultComputed,
|
|
236
|
+
mocks: {
|
|
237
|
+
...defaultMocks,
|
|
238
|
+
$store: { getters: defaultGetters },
|
|
239
|
+
},
|
|
240
|
+
stubs: defaultStubs
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
expect(wrapper.vm.validationPassed()).toBe(result);
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
it('should allow creation of K3 clusters if pool machines are missing', () => {
|
|
247
|
+
const k8s = 'v1.25.0+k3s1';
|
|
248
|
+
const wrapper = mount(rke2, {
|
|
249
|
+
propsData: {
|
|
250
|
+
mode: 'create',
|
|
251
|
+
value: {
|
|
252
|
+
spec: {
|
|
253
|
+
...defaultSpec,
|
|
254
|
+
kubernetesVersion: k8s
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
provider: 'custom'
|
|
258
|
+
},
|
|
259
|
+
data: () => ({ credentialId: 'I am authenticated' }),
|
|
260
|
+
computed: defaultComputed,
|
|
261
|
+
mocks: {
|
|
262
|
+
...defaultMocks,
|
|
263
|
+
$store: { getters: defaultGetters },
|
|
264
|
+
},
|
|
265
|
+
stubs: defaultStubs
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
expect(wrapper.vm.validationPassed()).toBe(true);
|
|
269
|
+
});
|
|
296
270
|
});
|
|
@@ -69,6 +69,7 @@ import S3Config from './S3Config';
|
|
|
69
69
|
import SelectCredential from './SelectCredential';
|
|
70
70
|
import AdvancedSection from '@shell/components/AdvancedSection.vue';
|
|
71
71
|
import { ELEMENTAL_SCHEMA_IDS, KIND, ELEMENTAL_CLUSTER_PROVIDER } from '../../config/elemental-types';
|
|
72
|
+
import AgentConfiguration, { cleanAgentConfiguration } from './AgentConfiguration';
|
|
72
73
|
|
|
73
74
|
const PUBLIC = 'public';
|
|
74
75
|
const PRIVATE = 'private';
|
|
@@ -96,6 +97,8 @@ const NODE_TOTAL = {
|
|
|
96
97
|
icon: 'icon-checkmark'
|
|
97
98
|
}
|
|
98
99
|
};
|
|
100
|
+
const CLUSTER_AGENT_CUSTOMIZATION = 'clusterAgentDeploymentCustomization';
|
|
101
|
+
const FLEET_AGENT_CUSTOMIZATION = 'fleetAgentDeploymentCustomization';
|
|
99
102
|
|
|
100
103
|
export default {
|
|
101
104
|
components: {
|
|
@@ -107,6 +110,7 @@ export default {
|
|
|
107
110
|
BadgeState,
|
|
108
111
|
Banner,
|
|
109
112
|
Checkbox,
|
|
113
|
+
AgentConfiguration,
|
|
110
114
|
ClusterMembershipEditor,
|
|
111
115
|
CruResource,
|
|
112
116
|
DrainOptions,
|
|
@@ -274,6 +278,18 @@ export default {
|
|
|
274
278
|
|
|
275
279
|
this.userChartValues[key] = value;
|
|
276
280
|
});
|
|
281
|
+
|
|
282
|
+
// Ensure we have empty models for the two agent configurations
|
|
283
|
+
|
|
284
|
+
// Cluster Agent Configuration
|
|
285
|
+
if ( !this.value.spec[CLUSTER_AGENT_CUSTOMIZATION]) {
|
|
286
|
+
set(this.value.spec, CLUSTER_AGENT_CUSTOMIZATION, {});
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// Fleet Agent Configuration
|
|
290
|
+
if ( !this.value.spec[FLEET_AGENT_CUSTOMIZATION] ) {
|
|
291
|
+
set(this.value.spec, FLEET_AGENT_CUSTOMIZATION, {});
|
|
292
|
+
}
|
|
277
293
|
},
|
|
278
294
|
|
|
279
295
|
data() {
|
|
@@ -702,7 +718,7 @@ export default {
|
|
|
702
718
|
},
|
|
703
719
|
|
|
704
720
|
unremovedMachinePools() {
|
|
705
|
-
return this.machinePools.filter(x => !x.remove);
|
|
721
|
+
return (this.machinePools || []).filter(x => !x.remove);
|
|
706
722
|
},
|
|
707
723
|
|
|
708
724
|
machineConfigSchema() {
|
|
@@ -1081,6 +1097,7 @@ export default {
|
|
|
1081
1097
|
created() {
|
|
1082
1098
|
this.registerBeforeHook(this.saveMachinePools, 'save-machine-pools');
|
|
1083
1099
|
this.registerBeforeHook(this.setRegistryConfig, 'set-registry-config');
|
|
1100
|
+
this.registerBeforeHook(this.agentConfigurationCleanup, 'cleanup-agent-config');
|
|
1084
1101
|
this.registerAfterHook(this.cleanupMachinePools, 'cleanup-machine-pools');
|
|
1085
1102
|
this.registerAfterHook(this.saveRoleBindings, 'save-role-bindings');
|
|
1086
1103
|
},
|
|
@@ -1089,6 +1106,12 @@ export default {
|
|
|
1089
1106
|
nlToBr,
|
|
1090
1107
|
set,
|
|
1091
1108
|
|
|
1109
|
+
agentConfigurationCleanup() {
|
|
1110
|
+
// Clean agent configuration objects, so we only send values when the user has configured something
|
|
1111
|
+
cleanAgentConfiguration(this.value.spec, CLUSTER_AGENT_CUSTOMIZATION);
|
|
1112
|
+
cleanAgentConfiguration(this.value.spec, FLEET_AGENT_CUSTOMIZATION);
|
|
1113
|
+
},
|
|
1114
|
+
|
|
1092
1115
|
/**
|
|
1093
1116
|
* set instanceNameLimit to 15 to all pool machine if truncateHostnames checkbox is clicked
|
|
1094
1117
|
*/
|
|
@@ -1110,6 +1133,10 @@ export default {
|
|
|
1110
1133
|
return isRequiredVersion;
|
|
1111
1134
|
},
|
|
1112
1135
|
|
|
1136
|
+
/**
|
|
1137
|
+
* Get machine pools from the cluster configuration
|
|
1138
|
+
* this.value.spec.rkeConfig.machinePools
|
|
1139
|
+
*/
|
|
1113
1140
|
async initMachinePools(existing) {
|
|
1114
1141
|
const out = [];
|
|
1115
1142
|
|
|
@@ -1467,7 +1494,20 @@ export default {
|
|
|
1467
1494
|
delete this.value.spec.rkeConfig.machineGlobalConfig.profile;
|
|
1468
1495
|
}
|
|
1469
1496
|
|
|
1497
|
+
// store the current data for fleet and cluster agent so that we can re-apply it later if the save fails
|
|
1498
|
+
// we also have a before hook (check created() hooks) where the cleanup of the data occurs
|
|
1499
|
+
const clusterAgentDeploymentCustomization = JSON.parse(JSON.stringify(this.value.spec[CLUSTER_AGENT_CUSTOMIZATION]));
|
|
1500
|
+
const fleetAgentDeploymentCustomization = JSON.parse(JSON.stringify(this.value.spec[FLEET_AGENT_CUSTOMIZATION]));
|
|
1501
|
+
|
|
1470
1502
|
await this.save(btnCb);
|
|
1503
|
+
|
|
1504
|
+
// comes from createEditView mixin
|
|
1505
|
+
// if there are any errors saving, restore the agent config data
|
|
1506
|
+
if (this.errors?.length) {
|
|
1507
|
+
// Ensure the agent configuration is set back to the values before we changed (cleaned) it
|
|
1508
|
+
set(this.value.spec, CLUSTER_AGENT_CUSTOMIZATION, clusterAgentDeploymentCustomization);
|
|
1509
|
+
set(this.value.spec, FLEET_AGENT_CUSTOMIZATION, fleetAgentDeploymentCustomization);
|
|
1510
|
+
}
|
|
1471
1511
|
},
|
|
1472
1512
|
// create a secret to reference the harvester cluster kubeconfig in rkeConfig
|
|
1473
1513
|
async createKubeconfigSecret(kubeconfig = '') {
|
|
@@ -1993,6 +2033,11 @@ export default {
|
|
|
1993
2033
|
|
|
1994
2034
|
this.previousKubernetesVersion = value;
|
|
1995
2035
|
}
|
|
2036
|
+
|
|
2037
|
+
// If Harvester driver, reset cloud provider if not compatible
|
|
2038
|
+
if (this.isHarvesterDriver && this.mode === _CREATE && this.isHarvesterIncompatible) {
|
|
2039
|
+
this.setHarvesterDefaultCloudProvider();
|
|
2040
|
+
}
|
|
1996
2041
|
}
|
|
1997
2042
|
},
|
|
1998
2043
|
|
|
@@ -2084,21 +2129,21 @@ export default {
|
|
|
2084
2129
|
class="pull-right"
|
|
2085
2130
|
>
|
|
2086
2131
|
<BadgeState
|
|
2087
|
-
v-tooltip="nodeTotals.tooltip.etcd"
|
|
2132
|
+
v-clean-tooltip="nodeTotals.tooltip.etcd"
|
|
2088
2133
|
:color="nodeTotals.color.etcd"
|
|
2089
2134
|
:icon="nodeTotals.icon.etcd"
|
|
2090
2135
|
:label="nodeTotals.label.etcd"
|
|
2091
2136
|
class="mr-10"
|
|
2092
2137
|
/>
|
|
2093
2138
|
<BadgeState
|
|
2094
|
-
v-tooltip="nodeTotals.tooltip.controlPlane"
|
|
2139
|
+
v-clean-tooltip="nodeTotals.tooltip.controlPlane"
|
|
2095
2140
|
:color="nodeTotals.color.controlPlane"
|
|
2096
2141
|
:icon="nodeTotals.icon.controlPlane"
|
|
2097
2142
|
:label="nodeTotals.label.controlPlane"
|
|
2098
2143
|
class="mr-10"
|
|
2099
2144
|
/>
|
|
2100
2145
|
<BadgeState
|
|
2101
|
-
v-tooltip="nodeTotals.tooltip.worker"
|
|
2146
|
+
v-clean-tooltip="nodeTotals.tooltip.worker"
|
|
2102
2147
|
:color="nodeTotals.color.worker"
|
|
2103
2148
|
:icon="nodeTotals.icon.worker"
|
|
2104
2149
|
:label="nodeTotals.label.worker"
|
|
@@ -2515,7 +2560,7 @@ export default {
|
|
|
2515
2560
|
<h3>
|
|
2516
2561
|
{{ t('cluster.rke2.address.header') }}
|
|
2517
2562
|
<i
|
|
2518
|
-
v-tooltip="t('cluster.rke2.address.tooltip')"
|
|
2563
|
+
v-clean-tooltip="t('cluster.rke2.address.tooltip')"
|
|
2519
2564
|
class="icon icon-info"
|
|
2520
2565
|
/>
|
|
2521
2566
|
</h3>
|
|
@@ -2807,7 +2852,7 @@ export default {
|
|
|
2807
2852
|
<h3>
|
|
2808
2853
|
{{ t('cluster.addOns.additionalManifest.title') }}
|
|
2809
2854
|
<i
|
|
2810
|
-
v-tooltip="t('cluster.addOns.additionalManifest.tooltip')"
|
|
2855
|
+
v-clean-tooltip="t('cluster.addOns.additionalManifest.tooltip')"
|
|
2811
2856
|
class="icon icon-info"
|
|
2812
2857
|
/>
|
|
2813
2858
|
</h3>
|
|
@@ -2821,6 +2866,30 @@ export default {
|
|
|
2821
2866
|
</div>
|
|
2822
2867
|
</Tab>
|
|
2823
2868
|
|
|
2869
|
+
<!-- Cluster Agent Configuration -->
|
|
2870
|
+
<Tab
|
|
2871
|
+
name="clusteragentconfig"
|
|
2872
|
+
label-key="cluster.agentConfig.tabs.cluster"
|
|
2873
|
+
>
|
|
2874
|
+
<AgentConfiguration
|
|
2875
|
+
v-model="value.spec.clusterAgentDeploymentCustomization"
|
|
2876
|
+
type="cluster"
|
|
2877
|
+
:mode="mode"
|
|
2878
|
+
/>
|
|
2879
|
+
</Tab>
|
|
2880
|
+
|
|
2881
|
+
<!-- Fleet Agent Configuration -->
|
|
2882
|
+
<Tab
|
|
2883
|
+
name="fleetagentconfig"
|
|
2884
|
+
label-key="cluster.agentConfig.tabs.fleet"
|
|
2885
|
+
>
|
|
2886
|
+
<AgentConfiguration
|
|
2887
|
+
v-model="value.spec.fleetAgentDeploymentCustomization"
|
|
2888
|
+
type="fleet"
|
|
2889
|
+
:mode="mode"
|
|
2890
|
+
/>
|
|
2891
|
+
</Tab>
|
|
2892
|
+
|
|
2824
2893
|
<!-- Advanced -->
|
|
2825
2894
|
<Tab
|
|
2826
2895
|
v-if="haveArgInfo || agentArgs['protect-kernel-defaults']"
|
|
@@ -274,7 +274,7 @@ export default {
|
|
|
274
274
|
>
|
|
275
275
|
<template #label>
|
|
276
276
|
<span
|
|
277
|
-
v-tooltip="t('backupRestoreOperator.prune.tip')"
|
|
277
|
+
v-clean-tooltip="t('backupRestoreOperator.prune.tip')"
|
|
278
278
|
class="text-label"
|
|
279
279
|
>
|
|
280
280
|
{{ t('backupRestoreOperator.prune.label') }} <i class="icon icon-info" />
|
|
@@ -290,7 +290,7 @@ export default {
|
|
|
290
290
|
>
|
|
291
291
|
<template #label>
|
|
292
292
|
<label
|
|
293
|
-
v-tooltip="t('backupRestoreOperator.deleteTimeout.tip')"
|
|
293
|
+
v-clean-tooltip="t('backupRestoreOperator.deleteTimeout.tip')"
|
|
294
294
|
class="has-tooltip"
|
|
295
295
|
>
|
|
296
296
|
{{ t('backupRestoreOperator.deleteTimeout.label') }} <i class="icon icon-info" />
|
package/edit/service.vue
CHANGED
|
@@ -20,12 +20,13 @@ import { Banner } from '@components/Banner';
|
|
|
20
20
|
import Labels from '@shell/components/form/Labels';
|
|
21
21
|
import HarvesterServiceAddOnConfig from '@shell/components/HarvesterServiceAddOnConfig';
|
|
22
22
|
import { clone } from '@shell/utils/object';
|
|
23
|
-
import { POD, CAPI } from '@shell/config/types';
|
|
23
|
+
import { POD, CAPI, HCI } from '@shell/config/types';
|
|
24
24
|
import { matching } from '@shell/utils/selector';
|
|
25
25
|
import { HARVESTER_NAME as HARVESTER } from '@shell/config/features';
|
|
26
26
|
import { allHash } from '@shell/utils/promise';
|
|
27
27
|
import { isHarvesterSatisfiesVersion } from '@shell/utils/cluster';
|
|
28
28
|
import { Port } from '@shell/utils/validators/formRules';
|
|
29
|
+
import { HCI as HCI_LABELS_ANNOTATIONS } from '@shell/config/labels-annotations';
|
|
29
30
|
|
|
30
31
|
const SESSION_AFFINITY_ACTION_VALUES = {
|
|
31
32
|
NONE: 'None',
|
|
@@ -268,8 +269,9 @@ export default {
|
|
|
268
269
|
const inStore = this.$store.getters['currentStore'](POD);
|
|
269
270
|
|
|
270
271
|
const hash = {
|
|
271
|
-
provClusters:
|
|
272
|
-
pods:
|
|
272
|
+
provClusters: this.$store.dispatch('management/findAll', { type: CAPI.RANCHER_CLUSTER }),
|
|
273
|
+
pods: this.$store.dispatch(`${ inStore }/findAll`, { type: POD }),
|
|
274
|
+
harvesterConfigs: this.$store.dispatch(`management/findAll`, { type: HCI.HARVESTER_CONFIG }),
|
|
273
275
|
};
|
|
274
276
|
|
|
275
277
|
const res = await allHash(hash);
|
|
@@ -313,6 +315,23 @@ export default {
|
|
|
313
315
|
if (ports && ports.length > 0) {
|
|
314
316
|
this.value.spec.ports = this.targetPortsStrOrInt(this.value.spec.ports);
|
|
315
317
|
}
|
|
318
|
+
|
|
319
|
+
if (this.showHarvesterAddOnConfig) {
|
|
320
|
+
const clusters = this.$store.getters['management/all'](CAPI.RANCHER_CLUSTER);
|
|
321
|
+
const configs = this.$store.getters['management/all'](HCI.HARVESTER_CONFIG);
|
|
322
|
+
const cluster = clusters.find(c => c.status.clusterName === this.currentCluster.id);
|
|
323
|
+
|
|
324
|
+
const machinePools = cluster?.spec?.rkeConfig?.machinePools || [];
|
|
325
|
+
const machineConfigName = machinePools[0]?.machineConfigRef?.name;
|
|
326
|
+
const config = configs.find(c => c.id === `fleet-default/${ machineConfigName }`);
|
|
327
|
+
|
|
328
|
+
if (config) {
|
|
329
|
+
const { vmNamespace, networkName } = config;
|
|
330
|
+
|
|
331
|
+
this.value.metadata.annotations[HCI_LABELS_ANNOTATIONS.CLOUD_PROVIDER_NAMESPACE] = vmNamespace;
|
|
332
|
+
this.value.metadata.annotations[HCI_LABELS_ANNOTATIONS.CLOUD_PROVIDER_NETWORK] = networkName;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
316
335
|
},
|
|
317
336
|
},
|
|
318
337
|
};
|
|
@@ -125,7 +125,7 @@ export default {
|
|
|
125
125
|
if (driver.metadata.name === LONGHORN_DRIVER || provisionerOptionsDrivers.includes(driver.metadata.name)) {
|
|
126
126
|
return;
|
|
127
127
|
}
|
|
128
|
-
const fallback = `${ driver.metadata.name } ${ this.t('persistentVolume.csi.
|
|
128
|
+
const fallback = `${ driver.metadata.name } ${ this.t('persistentVolume.csi.suffix') }`;
|
|
129
129
|
|
|
130
130
|
dropdownOptions.push({
|
|
131
131
|
value: driver.metadata.name,
|