@rancher/shell 0.4.0 → 0.5.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.
Files changed (243) hide show
  1. package/assets/images/providers/ovhcloudmks.svg +122 -0
  2. package/assets/images/providers/ovhcloudpubliccloud.svg +122 -0
  3. package/assets/styles/global/_layout.scss +99 -0
  4. package/assets/translations/en-us.yaml +30 -5
  5. package/assets/translations/zh-hans.yaml +1 -1
  6. package/babel.config.js +7 -1
  7. package/chart/monitoring/alerting/index.vue +7 -21
  8. package/chart/monitoring/grafana/index.vue +55 -0
  9. package/chart/monitoring/index.vue +51 -17
  10. package/chart/monitoring/prometheus/index.vue +37 -43
  11. package/chart/rancher-backup/index.vue +2 -1
  12. package/cloud-credential/azure.vue +4 -17
  13. package/components/Certificates.vue +164 -0
  14. package/components/CodeMirror.vue +19 -21
  15. package/components/CruResource.vue +1 -0
  16. package/components/EtcdInfoBanner.vue +1 -1
  17. package/components/ExplorerProjectsNamespaces.vue +25 -1
  18. package/components/IconOrSvg.vue +1 -1
  19. package/components/LandingPagePreference.vue +1 -4
  20. package/components/Questions/index.vue +1 -1
  21. package/components/ResourceDetail/Masthead.vue +16 -3
  22. package/components/ResourceTable.vue +14 -2
  23. package/components/ResourceYaml.vue +5 -0
  24. package/components/SideNav.vue +1 -1
  25. package/components/SingleClusterInfo.vue +1 -4
  26. package/components/Tabbed/index.vue +12 -0
  27. package/components/fleet/FleetRepos.vue +62 -27
  28. package/components/fleet/FleetResources.vue +6 -1
  29. package/components/form/ArrayListSelect.vue +10 -0
  30. package/components/form/KeyValue.vue +4 -0
  31. package/components/form/LabeledSelect.vue +4 -0
  32. package/components/formatter/Checked.vue +11 -3
  33. package/components/formatter/FleetClusterSummaryGraph.vue +27 -0
  34. package/components/formatter/FleetSummaryGraph.vue +23 -11
  35. package/components/formatter/LiveDuration.vue +1 -1
  36. package/components/formatter/PercentageBar.vue +1 -1
  37. package/components/formatter/__tests__/Checked.test.ts +19 -0
  38. package/components/nav/Group.vue +2 -2
  39. package/components/nav/Header.vue +0 -1
  40. package/components/nav/TopLevelMenu.vue +36 -6
  41. package/components/nav/Type.vue +1 -3
  42. package/components/nav/WindowManager/ContainerLogs.vue +101 -3
  43. package/components/nav/WindowManager/ContainerShell.vue +6 -1
  44. package/components/nav/WindowManager/__tests__/ContainerLogs.test.ts +186 -0
  45. package/components/nav/WindowManager/index.vue +11 -10
  46. package/components/nav/__tests__/TopLevelMenu.test.ts +33 -0
  47. package/components/nav/__tests__/Type.test.ts +1 -1
  48. package/components/nuxt/nuxt-child.js +14 -78
  49. package/components/nuxt/nuxt.js +1 -1
  50. package/{layouts → components/templates}/blank.vue +1 -1
  51. package/{layouts → components/templates}/default.vue +8 -98
  52. package/{layouts → components/templates}/error.vue +10 -19
  53. package/{layouts → components/templates}/home.vue +4 -1
  54. package/{layouts → components/templates}/plain.vue +4 -1
  55. package/{layouts → components/templates}/standalone.vue +1 -1
  56. package/{layouts → components/templates}/unauthenticated.vue +1 -1
  57. package/composables/useCompactInput.ts +20 -0
  58. package/composables/useLabeledFormElement.ts +138 -0
  59. package/config/harvester-manager-types.js +2 -0
  60. package/config/private-label.js +22 -0
  61. package/config/product/explorer.js +3 -0
  62. package/config/product/fleet.js +6 -1
  63. package/config/product/manager.js +8 -2
  64. package/config/query-params.js +1 -0
  65. package/config/router.js +385 -364
  66. package/config/settings.ts +1 -0
  67. package/config/store.js +1 -1
  68. package/config/system-namespaces.js +3 -0
  69. package/config/table-headers.js +47 -0
  70. package/core/plugin-routes.ts +56 -114
  71. package/core/plugin.ts +16 -10
  72. package/core/plugins-loader.js +7 -9
  73. package/core/plugins.js +0 -3
  74. package/creators/app/files/.gitlab-ci.yml +1 -1
  75. package/detail/fleet.cattle.io.cluster.vue +11 -1
  76. package/detail/provisioning.cattle.io.cluster.vue +4 -3
  77. package/dialog/ScaleMachineDownDialog.vue +34 -17
  78. package/edit/__tests__/service.test.ts +89 -0
  79. package/edit/auth/googleoauth.vue +1 -5
  80. package/edit/catalog.cattle.io.clusterrepo.vue +18 -0
  81. package/edit/cloudcredential.vue +2 -0
  82. package/edit/configmap.vue +2 -1
  83. package/edit/networking.k8s.io.networkpolicy/__tests__/PolicyRuleTarget.spec.ts +1 -1
  84. package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +15 -7
  85. package/edit/provisioning.cattle.io.cluster/__tests__/Advanced.test.ts +112 -0
  86. package/edit/provisioning.cattle.io.cluster/__tests__/Basics.test.ts +473 -0
  87. package/edit/provisioning.cattle.io.cluster/__tests__/{CustomCommand.tests.ts → CustomCommand.test.ts} +4 -0
  88. package/edit/provisioning.cattle.io.cluster/__tests__/DrainOptions.test.ts +1 -1
  89. package/edit/provisioning.cattle.io.cluster/__tests__/index.test.ts +73 -0
  90. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +7 -1
  91. package/edit/provisioning.cattle.io.cluster/__tests__/utils/cluster.ts +386 -0
  92. package/edit/provisioning.cattle.io.cluster/import.vue +2 -2
  93. package/edit/provisioning.cattle.io.cluster/index.vue +92 -36
  94. package/edit/provisioning.cattle.io.cluster/rke2.vue +171 -583
  95. package/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig.vue +137 -0
  96. package/edit/provisioning.cattle.io.cluster/tabs/Advanced.vue +157 -0
  97. package/edit/provisioning.cattle.io.cluster/{Basics.vue → tabs/Basics.vue} +94 -19
  98. package/edit/provisioning.cattle.io.cluster/{MachinePool.vue → tabs/MachinePool.vue} +1 -0
  99. package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +135 -0
  100. package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +189 -0
  101. package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +144 -0
  102. package/edit/provisioning.cattle.io.cluster/tabs/upgrade/index.vue +76 -0
  103. package/edit/service.vue +12 -0
  104. package/edit/workload/mixins/workload.js +1 -1
  105. package/initialize/App.js +25 -71
  106. package/initialize/client.js +21 -162
  107. package/initialize/index.js +27 -123
  108. package/list/management.cattle.io.feature.vue +1 -7
  109. package/list/node.vue +1 -0
  110. package/machine-config/__tests__/vmwarevsphere.test.ts +100 -21
  111. package/machine-config/vmwarevsphere.vue +73 -51
  112. package/middleware/authenticated.js +10 -17
  113. package/mixins/auth-config.js +2 -7
  114. package/mixins/brand.js +29 -41
  115. package/mixins/labeled-form-element.ts +6 -1
  116. package/models/__tests__/management.cattle.io.node.ts +85 -0
  117. package/models/__tests__/management.cattle.io.nodepool.ts +83 -0
  118. package/models/__tests__/namespace.test.ts +49 -9
  119. package/models/__tests__/workload.test.ts +91 -0
  120. package/models/cluster/node.js +4 -4
  121. package/models/cluster.x-k8s.io.machinedeployment.js +14 -0
  122. package/models/fleet.cattle.io.cluster.js +4 -0
  123. package/models/fleet.cattle.io.gitrepo.js +56 -13
  124. package/models/management.cattle.io.kontainerdriver.js +1 -1
  125. package/models/management.cattle.io.node.js +18 -14
  126. package/models/management.cattle.io.nodepool.js +17 -0
  127. package/models/namespace.js +1 -1
  128. package/models/pod.js +20 -0
  129. package/models/provisioning.cattle.io.cluster.js +20 -3
  130. package/models/secret.js +117 -18
  131. package/models/workload.js +16 -0
  132. package/models/workload.service.js +18 -0
  133. package/package.json +10 -9
  134. package/pages/about.vue +0 -1
  135. package/pages/account/create-key.vue +0 -1
  136. package/pages/account/index.vue +0 -1
  137. package/pages/auth/login.vue +0 -1
  138. package/pages/auth/logout.vue +0 -2
  139. package/pages/auth/setup.vue +0 -4
  140. package/pages/auth/verify.vue +14 -8
  141. package/pages/c/_cluster/apps/charts/install.vue +4 -4
  142. package/pages/c/_cluster/apps/index.vue +0 -2
  143. package/pages/c/_cluster/auth/index.vue +0 -2
  144. package/pages/c/_cluster/ecm/index.vue +0 -2
  145. package/pages/c/_cluster/explorer/index.vue +28 -2
  146. package/pages/c/_cluster/fleet/index.vue +1 -1
  147. package/pages/c/_cluster/index.vue +0 -2
  148. package/pages/c/_cluster/settings/banners.vue +0 -2
  149. package/pages/c/_cluster/settings/brand.vue +0 -2
  150. package/pages/c/_cluster/settings/index.vue +0 -2
  151. package/pages/c/_cluster/settings/links.vue +0 -1
  152. package/pages/c/_cluster/settings/performance.vue +0 -1
  153. package/pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue +2 -1
  154. package/pages/c/_cluster/uiplugins/CatalogList/index.vue +10 -46
  155. package/pages/c/_cluster/uiplugins/index.vue +0 -2
  156. package/pages/diagnostic.vue +1 -2
  157. package/pages/fail-whale.vue +0 -1
  158. package/pages/prefs.vue +0 -1
  159. package/pages/support/index.vue +2 -8
  160. package/pkg/auto-import.js +1 -1
  161. package/plugins/axios.js +0 -36
  162. package/plugins/back-button.js +3 -5
  163. package/plugins/codemirror-loader.js +1 -1
  164. package/plugins/codemirror.js +41 -0
  165. package/plugins/dashboard-store/__tests__/{mutations.spec.ts → mutations.test.ts} +1 -1
  166. package/plugins/dashboard-store/__tests__/resource-class.test.ts +49 -0
  167. package/plugins/dashboard-store/__tests__/utils/store-mocks.ts +7 -0
  168. package/plugins/dashboard-store/actions.js +30 -4
  169. package/plugins/dashboard-store/classify.js +1 -18
  170. package/plugins/dashboard-store/getters.js +10 -5
  171. package/plugins/dashboard-store/index.js +0 -12
  172. package/plugins/dashboard-store/mutations.js +0 -4
  173. package/plugins/dashboard-store/resource-class.js +59 -18
  174. package/plugins/steve/__tests__/steve-class.spec.ts +59 -0
  175. package/plugins/steve/__tests__/utils/steve-mocks.ts +31 -0
  176. package/plugins/steve/getters.js +4 -1
  177. package/plugins/steve/norman-class.js +19 -0
  178. package/plugins/steve/steve-class.js +22 -0
  179. package/plugins/steve/subscribe.js +4 -10
  180. package/rancher-components/Accordion/Accordion.test.ts +45 -0
  181. package/rancher-components/Accordion/Accordion.vue +85 -0
  182. package/rancher-components/Accordion/index.ts +1 -0
  183. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +19 -2
  184. package/rancher-components/Form/LabeledInput/LabeledInput.vue +12 -1
  185. package/rancher-components/Form/Radio/RadioButton.test.ts +7 -3
  186. package/rancher-components/Form/Radio/RadioGroup.test.ts +30 -0
  187. package/rancher-components/Form/Radio/RadioGroup.vue +4 -0
  188. package/rancher-components/StringList/StringList.test.ts +270 -0
  189. package/rancher-components/StringList/StringList.vue +57 -18
  190. package/rancher-components/components/Accordion/Accordion.test.ts +45 -0
  191. package/rancher-components/components/Accordion/Accordion.vue +85 -0
  192. package/rancher-components/components/Accordion/index.ts +1 -0
  193. package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +19 -2
  194. package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +4 -1
  195. package/scripts/.gitlab/workflows/build-extension-catalog.gitlab-ci.yml +50 -0
  196. package/scripts/extension/parse-tag-name +2 -2
  197. package/scripts/publish-shell.sh +10 -0
  198. package/scripts/test-plugins-build.sh +85 -9
  199. package/server/har-file.js +183 -0
  200. package/store/catalog.js +1 -1
  201. package/store/features.js +1 -0
  202. package/store/i18n.js +11 -0
  203. package/store/index.js +10 -11
  204. package/store/prefs.js +33 -35
  205. package/store/type-map.js +8 -7
  206. package/tsconfig.json +35 -9
  207. package/tsconfig.paths.json +18 -0
  208. package/types/shell/index.d.ts +345 -214
  209. package/utils/__tests__/create-yaml.test.ts +60 -0
  210. package/utils/axios.js +0 -19
  211. package/utils/azure.js +24 -0
  212. package/utils/create-yaml.js +17 -10
  213. package/utils/monitoring.js +1 -1
  214. package/utils/nuxt.js +18 -39
  215. package/utils/object.js +14 -0
  216. package/utils/router.scrollBehavior.js +12 -14
  217. package/utils/time.js +1 -1
  218. package/utils/url.ts +1 -1
  219. package/vue.config.js +23 -2
  220. package/.DS_Store +0 -0
  221. package/assets/images/providers/aks-black.svg +0 -28
  222. package/assets/images/providers/aks.svg +0 -31
  223. package/edit/provisioning.cattle.io.cluster/__tests__/Basics.tests.ts +0 -234
  224. package/initialize/layouts.ts +0 -26
  225. package/mixins/fetch.server.js +0 -73
  226. package/pages/c/index.vue +0 -9
  227. package/pages/rio/mesh.vue +0 -508
  228. package/plugins/transitions.js +0 -4
  229. package/scripts/.DS_Store +0 -0
  230. package/scripts/verdaccio.log +0 -205
  231. package/tsconfig.default.json +0 -46
  232. package/yarn-error.log +0 -200
  233. /package/components/form/__tests__/{NameNsDescription.ts → NameNsDescription.test.ts} +0 -0
  234. /package/edit/networking.k8s.io.networkpolicy/__tests__/utils/{selectors.ts → selectors.test.ts} +0 -0
  235. /package/edit/provisioning.cattle.io.cluster/{AgentConfiguration.vue → tabs/AgentConfiguration.vue} +0 -0
  236. /package/edit/provisioning.cattle.io.cluster/{MemberRoles.vue → tabs/MemberRoles.vue} +0 -0
  237. /package/edit/provisioning.cattle.io.cluster/{S3Config.vue → tabs/etcd/S3Config.vue} +0 -0
  238. /package/edit/provisioning.cattle.io.cluster/{ACE.vue → tabs/networking/ACE.vue} +0 -0
  239. /package/edit/provisioning.cattle.io.cluster/{RegistryConfigs.vue → tabs/registries/RegistryConfigs.vue} +0 -0
  240. /package/edit/provisioning.cattle.io.cluster/{RegistryMirrors.vue → tabs/registries/RegistryMirrors.vue} +0 -0
  241. /package/edit/provisioning.cattle.io.cluster/{DrainOptions.vue → tabs/upgrade/DrainOptions.vue} +0 -0
  242. /package/plugins/dashboard-store/__tests__/{actions.spec.ts → actions.test.ts} +0 -0
  243. /package/plugins/dashboard-store/__tests__/{getters.spec.ts → getters.test.ts} +0 -0
@@ -0,0 +1,473 @@
1
+ import { mount } from '@vue/test-utils';
2
+ import Basics from '@shell/edit/provisioning.cattle.io.cluster/tabs/Basics';
3
+ import Checkbox from '@components/Form/Checkbox/Checkbox.vue';
4
+
5
+ const defaultStubs = {
6
+ Banner: true,
7
+ LabeledSelect: true,
8
+ YamlEditor: true,
9
+ Checkbox: true
10
+ };
11
+
12
+ const defaultCiliumStubs = {
13
+ Banner: true,
14
+ LabeledSelect: true,
15
+ YamlEditor: true,
16
+ };
17
+
18
+ const defaultComputed = {
19
+ showk8s21LegacyWarning() {
20
+ return false;
21
+ },
22
+ profileOptions() {
23
+ return [{ label: 'anything', value: 'anything' }];
24
+ }
25
+ };
26
+
27
+ const mockAgentArgs = { 'cloud-provider-name': { options: [], profile: { options: [{ anything: 'yes' }] } } };
28
+ const mockServerArgs = { disable: {}, cni: { options: [] } };
29
+
30
+ const rke2Versions =
31
+ [
32
+ {
33
+ id: 'v1.25.0+rke2r1', value: 'v1.25.0+rke2r1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts: {}
34
+ },
35
+ {
36
+ id: 'v1.24.0+rke2r1', value: 'v1.24.0+rke2r1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts: {}
37
+ },
38
+ {
39
+ id: 'v1.23.0+rke2r1', value: 'v1.23.0+rke2r1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts: {}
40
+ }
41
+ ];
42
+ const k3sVersions = [
43
+ {
44
+ id: 'v1.25.0+k3s1', value: 'v1.25.0+k3s1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts: {}
45
+ },
46
+ {
47
+ id: 'v1.24.0+k3s1', value: 'v1.24.0+k3s1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts: {}
48
+ },
49
+ {
50
+ id: 'v1.23.0+k3s1', value: 'v1.23.0+k3s1', serverArgs: mockServerArgs, agentArgs: mockAgentArgs, charts: {}
51
+ }
52
+ ];
53
+ const mockVersionOptions = [...rke2Versions, ...k3sVersions];
54
+
55
+ const defaultGetters = {
56
+ currentStore: () => 'current_store',
57
+ 'management/schemaFor': jest.fn(),
58
+ 'current_store/all': jest.fn(),
59
+ 'i18n/t': jest.fn(),
60
+ 'i18n/withFallback': jest.fn(),
61
+ 'plugins/cloudProviderForDriver': jest.fn()
62
+ };
63
+
64
+ const defaultMocks = {
65
+ $route: {
66
+ name: 'anything',
67
+ query: { AS: 'yaml' },
68
+ },
69
+ };
70
+
71
+ const defaultSpec = {
72
+ rkeConfig: { etcd: { disableSnapshots: false }, machineGlobalConfig: { cni: 'calico' } },
73
+ chartValues: {},
74
+ };
75
+
76
+ const defaultCiliumSpec = {
77
+ rkeConfig: { etcd: { disableSnapshots: false }, machineGlobalConfig: { cni: 'cilium' } },
78
+ chartValues: {},
79
+ };
80
+
81
+ // ipv6
82
+ const legacyOnValue = { cilium: { ipv6: { enabled: true } } };
83
+ const legacyOffValue = { cilium: { ipv6: { enabled: false } } };
84
+ const newOnValue = { ipv6: { enabled: true } };
85
+ const newOffValue = { ipv6: { enabled: false } };
86
+
87
+ // bandwidth manager
88
+ const bmOnValue = { bandwidthManager: { enabled: true } };
89
+ const bmOffValue = { bandwidthManager: { enabled: false } };
90
+
91
+ function createBasicsTab(version : string, userChartValues: any) {
92
+ const k8s = mockVersionOptions.find((v) => v.id === version) || mockVersionOptions[0];
93
+ const label = 'whatever';
94
+ const wrapper = mount(Basics, {
95
+ propsData: {
96
+ mode: 'create',
97
+ value: {
98
+ spec: {
99
+ ...defaultCiliumSpec,
100
+ defaultPodSecurityAdmissionConfigurationTemplateName: label,
101
+ kubernetesVersion: k8s.value
102
+ },
103
+ agentConfig: { 'cloud-provider-name': '' },
104
+ },
105
+ addonVersions: [],
106
+ provider: 'custom',
107
+ userChartValues: userChartValues || {},
108
+ cisOverride: false,
109
+ cisPsaChangeBanner: true,
110
+ allPsas: [],
111
+ selectedVersion: k8s,
112
+ versionOptions: mockVersionOptions,
113
+ isHarvesterDriver: false,
114
+ isHarvesterIncompatible: false,
115
+ showDeprecatedPatchVersions: false,
116
+ clusterIsAlreadyCreated: false,
117
+ isElementalCluster: false,
118
+ hasPsaTemplates: false,
119
+ isK3s: false,
120
+ haveArgInfo: false,
121
+ showCni: true,
122
+ showCloudProvider: false,
123
+ unsupportedCloudProvider: false,
124
+ cloudProviderOptions: [{ label: 'Default - RKE2 Embedded', value: '' }],
125
+ },
126
+ computed: defaultComputed,
127
+ mocks: {
128
+ ...defaultMocks,
129
+ $store: { getters: defaultGetters },
130
+ },
131
+ stubs: defaultCiliumStubs
132
+ });
133
+
134
+ return wrapper;
135
+ }
136
+
137
+ describe('component: Basics', () => {
138
+ /**
139
+ * DISCLAIMER ***************************************************************************************
140
+ * Logs are prevented to avoid polluting the test output.
141
+ ****************************************************************************************************
142
+ */
143
+ // eslint-disable-next-line jest/no-hooks
144
+ beforeEach(() => {
145
+ jest.spyOn(console, 'log').mockImplementation(() => { });
146
+ });
147
+
148
+ it.each(mockVersionOptions)('should display PSA option', (k8s) => {
149
+ const label = 'whatever';
150
+ const wrapper = mount(Basics, {
151
+ propsData: {
152
+ mode: 'create',
153
+ value: {
154
+ spec: {
155
+ ...defaultSpec,
156
+ defaultPodSecurityAdmissionConfigurationTemplateName: label,
157
+ kubernetesVersion: k8s.value
158
+ },
159
+ agentConfig: { 'cloud-provider-name': '' },
160
+ },
161
+ provider: 'whatever',
162
+ userChartValues: {},
163
+ cisOverride: false,
164
+ cisPsaChangeBanner: true,
165
+ allPsas: [],
166
+ selectedVersion: k8s,
167
+ versionOptions: mockVersionOptions,
168
+ isHarvesterDriver: false,
169
+ isHarvesterIncompatible: false,
170
+ showDeprecatedPatchVersions: false,
171
+ isElementalCluster: false,
172
+ hasPsaTemplates: false,
173
+ haveArgInfo: false,
174
+ showCni: true,
175
+ showCloudProvider: true,
176
+ unsupportedCloudProvider: false,
177
+ cloudProviderOptions: [{ label: 'Default - RKE2 Embedded', value: '' }],
178
+ },
179
+ computed: defaultComputed,
180
+ mocks: {
181
+ ...defaultMocks,
182
+ $store: { getters: defaultGetters },
183
+ },
184
+ stubs: defaultStubs
185
+ });
186
+
187
+ const select = wrapper.find('[data-testid="rke2-custom-edit-psa"]');
188
+
189
+ expect((select.vm as unknown as any).options[0].label).toBe(`${ label } (Current)`);
190
+ });
191
+
192
+ it.each([
193
+ ['v1.25.0+rke2r1', 'none'],
194
+ ['v1.24.0+rke2r1', 'default'],
195
+ ['v1.23.0+rke2r1', 'default'],
196
+ ['v1.25.0+k3s1', 'none'],
197
+ ['v1.24.0+k3s1', 'default'],
198
+ ['v1.23.0+k3s1', 'default'],
199
+ ])('should display for version %p PSA option label %p', (k8s, partialLabel) => {
200
+ const label = `cluster.rke2.defaultPodSecurityAdmissionConfigurationTemplateName.option.${ partialLabel }`;
201
+ const wrapper = mount(Basics, {
202
+ propsData: {
203
+ mode: 'create',
204
+ value: {
205
+ spec: {
206
+ ...defaultSpec,
207
+ defaultPodSecurityAdmissionConfigurationTemplateName: label,
208
+ kubernetesVersion: k8s
209
+ },
210
+ agentConfig: { 'cloud-provider-name': '' },
211
+ },
212
+ provider: 'whatever',
213
+ userChartValues: {},
214
+ cisOverride: false,
215
+ cisPsaChangeBanner: true,
216
+ allPsas: [],
217
+ selectedVersion: mockVersionOptions[0],
218
+ versionOptions: mockVersionOptions,
219
+ isHarvesterDriver: false,
220
+ isHarvesterIncompatible: false,
221
+ showDeprecatedPatchVersions: false,
222
+ isElementalCluster: false,
223
+ hasPsaTemplates: false,
224
+ haveArgInfo: false,
225
+ showCni: true,
226
+ showCloudProvider: true,
227
+ unsupportedCloudProvider: false,
228
+ cloudProviderOptions: [{ label: 'Default - RKE2 Embedded', value: '' }],
229
+ },
230
+ computed: defaultComputed,
231
+ mocks: {
232
+ ...defaultMocks,
233
+ $store: { getters: defaultGetters },
234
+ },
235
+ stubs: defaultStubs
236
+ });
237
+
238
+ const select = wrapper.find('[data-testid="rke2-custom-edit-psa"]');
239
+
240
+ expect((select.vm as unknown as any).options[0].label).toStrictEqual(`${ label } (Current)`);
241
+ });
242
+
243
+ it.each([
244
+ ['anything', false, true],
245
+ ['', false, false],
246
+ ['', true, false],
247
+ ])('given CIS value as %p and its override as %p, it should set PSA dropdown as disabled %p', (cis, override, disabled) => {
248
+ const label = 'whatever';
249
+ const k8s = 'v1.25.0+rke2r1';
250
+ const wrapper = mount(Basics, {
251
+ propsData: {
252
+ mode: 'create',
253
+ value: {
254
+ agentConfig: { profile: cis, 'cloud-provider-name': '' },
255
+ spec: {
256
+ ...defaultSpec,
257
+ defaultPodSecurityAdmissionConfigurationTemplateName: label,
258
+ kubernetesVersion: k8s
259
+ }
260
+ },
261
+ provider: 'custom',
262
+ userChartValues: {},
263
+ cisPsaChangeBanner: true,
264
+ allPsas: [],
265
+ cisOverride: override,
266
+ selectedVersion: mockVersionOptions[0],
267
+ versionOptions: [{
268
+ value: k8s,
269
+ agentArgs: { profile: { options: [cis] } },
270
+ charts: {},
271
+ profile: { options: [cis] }
272
+ }],
273
+ isHarvesterDriver: false,
274
+ isHarvesterIncompatible: false,
275
+ showDeprecatedPatchVersions: false,
276
+ isElementalCluster: false,
277
+ hasPsaTemplates: true,
278
+ haveArgInfo: false,
279
+ showCni: true,
280
+ showCloudProvider: true,
281
+ unsupportedCloudProvider: false,
282
+ cloudProviderOptions: [{ label: 'Default - RKE2 Embedded', value: '' }],
283
+ },
284
+ computed: { ...defaultComputed },
285
+ mocks: {
286
+ ...defaultMocks,
287
+ $store: { getters: defaultGetters },
288
+ },
289
+ stubs: defaultStubs
290
+ });
291
+
292
+ const select = wrapper.find('[data-testid="rke2-custom-edit-psa"]');
293
+
294
+ expect((select.vm as unknown as any).disabled).toBe(disabled);
295
+ });
296
+
297
+ describe('cilium CNI', () => {
298
+ it('should toggle ipv6 on/off with the legacy structure', async() => {
299
+ const wrapper = createBasicsTab('v1.23.0+rke2r1', {});
300
+ const ipv6Checkbox = wrapper.find('[data-testid="cluster-rke2-cni-ipv6-checkbox"]');
301
+
302
+ expect(ipv6Checkbox.exists()).toBe(true);
303
+ expect(ipv6Checkbox.isVisible()).toBe(true);
304
+
305
+ // Click the checkbox - should enable ipv6
306
+ await ipv6Checkbox.find('label').trigger('click');
307
+ await ipv6Checkbox.vm.$nextTick();
308
+ await wrapper.vm.$nextTick();
309
+
310
+ // Check and update user values with the emitted value
311
+ let latest = (wrapper.emitted()['cilium-values-changed'] || [])[0][0];
312
+
313
+ expect(JSON.stringify(latest)).toStrictEqual(JSON.stringify(legacyOnValue));
314
+
315
+ await wrapper.setProps({ userChartValues: { 'rke2-cilium': latest } });
316
+
317
+ // Click the checkbox to turn ipv6 off again
318
+ await ipv6Checkbox.find('label').trigger('click');
319
+ await ipv6Checkbox.vm.$nextTick();
320
+ await wrapper.vm.$nextTick();
321
+
322
+ // Update from the emitted value
323
+ latest = (wrapper.emitted()['cilium-values-changed'] || [])[1][0];
324
+
325
+ expect(JSON.stringify(latest)).toStrictEqual(JSON.stringify(legacyOffValue));
326
+ });
327
+
328
+ it('should toggle ipv6 on/off with the new structure', async() => {
329
+ const wrapper = createBasicsTab('v1.25.0+rke2r1', {});
330
+ const ipv6Checkbox = wrapper.find('[data-testid="cluster-rke2-cni-ipv6-checkbox"]');
331
+
332
+ expect(ipv6Checkbox.exists()).toBe(true);
333
+ expect(ipv6Checkbox.isVisible()).toBe(true);
334
+
335
+ // Click the checkbox - should enable ipv6
336
+ await ipv6Checkbox.find('label').trigger('click');
337
+ await ipv6Checkbox.vm.$nextTick();
338
+ await wrapper.vm.$nextTick();
339
+
340
+ // Check and update user values with the emitted value
341
+ let latest = (wrapper.emitted()['cilium-values-changed'] || [])[0][0];
342
+
343
+ expect(JSON.stringify(latest)).toStrictEqual(JSON.stringify(newOnValue));
344
+
345
+ await wrapper.setProps({ userChartValues: { 'rke2-cilium': latest } });
346
+
347
+ // Click the checkbox to turn ipv6 off again
348
+ await ipv6Checkbox.find('label').trigger('click');
349
+ await ipv6Checkbox.vm.$nextTick();
350
+ await wrapper.vm.$nextTick();
351
+
352
+ // Update from the emitted value
353
+ latest = (wrapper.emitted()['cilium-values-changed'] || [])[1][0];
354
+
355
+ expect(JSON.stringify(latest)).toStrictEqual(JSON.stringify(newOffValue));
356
+ });
357
+
358
+ it('should migrate when the k8s version is changed', async() => {
359
+ const userChartValues = { 'rke2-cilium': { ipv6: { enabled: true } } };
360
+ const wrapper = createBasicsTab('v1.25.0+rke2r1', userChartValues);
361
+
362
+ // Check that the checkbox is checked
363
+ const ipv6Checkbox = wrapper.find('[data-testid="cluster-rke2-cni-ipv6-checkbox"]') as Checkbox;
364
+
365
+ expect(ipv6Checkbox.exists()).toBe(true);
366
+ expect(ipv6Checkbox.isVisible()).toBe(true);
367
+ expect(ipv6Checkbox.vm.value).toBe(true);
368
+
369
+ // Change the kubernetes version that needs the legacy format
370
+ const k8s123 = mockVersionOptions.find((v) => v.id === 'v1.23.0+rke2r1');
371
+
372
+ await wrapper.setProps({ selectedVersion: k8s123 });
373
+
374
+ let latest = (wrapper.emitted()['cilium-values-changed'] || [])[0][0];
375
+
376
+ expect(JSON.stringify(latest)).toStrictEqual(JSON.stringify(legacyOnValue));
377
+
378
+ // Change back the version so that the new format should be used
379
+ const k8s125 = mockVersionOptions.find((v) => v.id === 'v1.25.0+rke2r1');
380
+
381
+ await wrapper.setProps({ selectedVersion: k8s125 });
382
+
383
+ latest = (wrapper.emitted()['cilium-values-changed'] || [])[1][0];
384
+ expect(JSON.stringify(latest)).toStrictEqual(JSON.stringify(newOnValue));
385
+ });
386
+ });
387
+
388
+ it('should toggle bandwidth manager support on/off', async() => {
389
+ const wrapper = createBasicsTab('v1.25.0+rke2r1', {});
390
+ const bmCheckbox = wrapper.find('[data-testid="cluster-rke2-cni-cilium-bandwidth-manager-checkbox"]');
391
+
392
+ expect(bmCheckbox.exists()).toBe(true);
393
+ expect(bmCheckbox.isVisible()).toBe(true);
394
+
395
+ // Click the checkbox - should enable bandwidth manager
396
+ await bmCheckbox.find('label').trigger('click');
397
+ await bmCheckbox.vm.$nextTick();
398
+ await wrapper.vm.$nextTick();
399
+
400
+ // Check and update user values with the emitted value
401
+ let latest = (wrapper.emitted()['cilium-values-changed'] || [])[0][0];
402
+
403
+ expect(JSON.stringify(latest)).toStrictEqual(JSON.stringify(bmOnValue));
404
+
405
+ await wrapper.setProps({ userChartValues: { 'rke2-cilium': latest } });
406
+
407
+ // Click the checkbox to turn ipv6 off again
408
+ await bmCheckbox.find('label').trigger('click');
409
+ await bmCheckbox.vm.$nextTick();
410
+ await wrapper.vm.$nextTick();
411
+
412
+ // Update from the emitted value
413
+ latest = (wrapper.emitted()['cilium-values-changed'] || [])[1][0];
414
+
415
+ expect(JSON.stringify(latest)).toStrictEqual(JSON.stringify(bmOffValue));
416
+ });
417
+
418
+ it('should support ipv6 and bandwidth manager', async() => {
419
+ const wrapper = createBasicsTab('v1.25.0+rke2r1', {});
420
+ const bmCheckbox = wrapper.find('[data-testid="cluster-rke2-cni-cilium-bandwidth-manager-checkbox"]');
421
+ const ipv6Checkbox = wrapper.find('[data-testid="cluster-rke2-cni-ipv6-checkbox"]');
422
+
423
+ // Click the checkbox - should enable bandwidth manager
424
+ await bmCheckbox.find('label').trigger('click');
425
+ await bmCheckbox.vm.$nextTick();
426
+ await wrapper.vm.$nextTick();
427
+
428
+ let latest = (wrapper.emitted()['cilium-values-changed'] || [])[0][0];
429
+
430
+ await wrapper.setProps({ userChartValues: { 'rke2-cilium': latest } });
431
+
432
+ // Click the checkbox - should enable ipv6
433
+ await ipv6Checkbox.find('label').trigger('click');
434
+ await ipv6Checkbox.vm.$nextTick();
435
+ await wrapper.vm.$nextTick();
436
+
437
+ // Check and update user values with the emitted value
438
+ latest = (wrapper.emitted()['cilium-values-changed'] || [])[1][0];
439
+
440
+ const combined = {
441
+ bandwidthManager: { enabled: true },
442
+ ipv6: { enabled: true }
443
+ };
444
+
445
+ expect(JSON.stringify(latest)).toStrictEqual(JSON.stringify(combined));
446
+
447
+ // Check that other properties are preserved
448
+ latest = {
449
+ ...latest,
450
+ bandwidthManager: {
451
+ test: true,
452
+ enabled: false
453
+ },
454
+ ipv6: {
455
+ test: true,
456
+ enabled: false
457
+ }
458
+ };
459
+
460
+ await wrapper.setProps({ userChartValues: { 'rke2-cilium': latest } });
461
+
462
+ // Click the checkbox to turn bandwidth manager off again
463
+ await bmCheckbox.find('label').trigger('click');
464
+ await bmCheckbox.vm.$nextTick();
465
+ await wrapper.vm.$nextTick();
466
+
467
+ latest = (wrapper.emitted()['cilium-values-changed'] || [])[2][0];
468
+
469
+ const expected = '{"bandwidthManager":{"test":true,"enabled":true},"ipv6":{"test":true,"enabled":false}}';
470
+
471
+ expect(JSON.stringify(latest)).toStrictEqual(expected);
472
+ });
473
+ });
@@ -1,8 +1,10 @@
1
1
  import { mount } from '@vue/test-utils';
2
2
  import CustomCommand from '@shell/edit/provisioning.cattle.io.cluster/CustomCommand.vue';
3
+ import { cleanHtmlDirective } from '@shell/plugins/clean-html-directive';
3
4
  jest.mock('@shell/utils/clipboard', () => {
4
5
  return { copyTextToClipboard: jest.fn(() => Promise.resolve({})) };
5
6
  });
7
+
6
8
  describe('component: CustomCommand', () => {
7
9
  const token = 'MY_TOKEN';
8
10
  const ip = 'MY_IP';
@@ -37,6 +39,8 @@ describe('component: CustomCommand', () => {
37
39
  taints: [],
38
40
  worker: true,
39
41
  }),
42
+
43
+ directives: { cleanHtmlDirective }
40
44
  });
41
45
 
42
46
  it('should return linux commands with the right flags based on cluster information', () => {
@@ -1,5 +1,5 @@
1
1
  import { mount } from '@vue/test-utils';
2
- import DrainOptions from '@shell/edit/provisioning.cattle.io.cluster/DrainOptions.vue';
2
+ import DrainOptions from '@shell/edit/provisioning.cattle.io.cluster/tabs/upgrade/DrainOptions';
3
3
  import { DefaultProps } from 'vue/types/options';
4
4
  import { ExtendedVue, Vue } from 'vue/types/vue';
5
5
 
@@ -0,0 +1,73 @@
1
+ import { shallowMount, createLocalVue } from '@vue/test-utils';
2
+ import Vuex from 'vuex';
3
+ import ClusterCreate from '@shell/edit/provisioning.cattle.io.cluster/index.vue';
4
+
5
+ describe('component: Cluster: Create', () => {
6
+ it('should hide RKE1 and RKE2 toggle button if RKE1 ui feature flag is NOT set', () => {
7
+ const localVue = createLocalVue();
8
+
9
+ localVue.use(Vuex);
10
+
11
+ const store = new Vuex.Store({
12
+ modules: {
13
+ i18n: {
14
+ namespaced: true,
15
+ getters: {
16
+ t: jest.fn(),
17
+ withFallback: () => jest.fn(),
18
+ }
19
+ },
20
+ features: {
21
+ namespaced: true,
22
+ getters: {
23
+ get: () => jest.fn(),
24
+ withFallback: jest.fn(),
25
+ }
26
+ },
27
+ prefs: {
28
+ namespaced: true,
29
+ getters: { get: jest.fn() }
30
+ },
31
+ mapFeature: {
32
+ namespaced: true,
33
+ getters: { get: jest.fn() }
34
+ },
35
+ 'type-map': {
36
+ namespaced: true,
37
+ getters: { activeProducts: () => [] }
38
+ },
39
+ catalog: {
40
+ namespaced: true,
41
+ getters: { charts: () => [] }
42
+ }
43
+ },
44
+ getters: {
45
+ defaultClusterId: jest.fn(),
46
+ clusterId: jest.fn()
47
+ }
48
+ });
49
+
50
+ const wrapper = shallowMount(ClusterCreate, {
51
+ computed: { rke1UiEnabled: () => false },
52
+ propsData: {
53
+ value: { metadata: {}, spec: { template: {} } },
54
+ realMode: '',
55
+ mode: 'edit',
56
+ componentTestid: 'cluster-manager-create',
57
+ },
58
+ mixins: [],
59
+ store,
60
+ localVue,
61
+ mocks: {
62
+ $route: { params: {}, query: {} },
63
+ $router: { applyQuery: jest.fn() },
64
+ $fetchState: { pending: false },
65
+ },
66
+ stubs: { CruResource: { template: '<div><slot name="subtypes"></slot></div>' } }
67
+ });
68
+
69
+ const element = wrapper.find('[data-testid="cluster-manager-create-rke-switch"]').element;
70
+
71
+ expect(element).not.toBeDefined();
72
+ });
73
+ });
@@ -39,7 +39,13 @@ const defaultStubs = {
39
39
  UnitInput: true,
40
40
  YamlEditor: true,
41
41
  MemberRoles: true,
42
- Basics: true
42
+ Basics: true,
43
+ Etcd: true,
44
+ Networking: true,
45
+ Upgrade: true,
46
+ Registries: true,
47
+ AddOnConfig: true,
48
+ Advanced: true
43
49
  };
44
50
 
45
51
  const mockAgentArgs = { 'cloud-provider-name': { options: [], profile: { options: [{ anything: 'yes' }] } } };