@rancher/shell 3.0.12-rc.2 → 3.0.12-rc.4

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 (473) hide show
  1. package/apis/impl/apis.ts +6 -0
  2. package/apis/index.ts +26 -0
  3. package/apis/intf/resources-api/cluster-api.ts +18 -0
  4. package/apis/intf/resources-api/mgmt-api.ts +15 -0
  5. package/apis/intf/resources-api/resource-base.ts +107 -0
  6. package/apis/intf/resources-api/resource-constants.ts +147 -0
  7. package/apis/intf/resources-api/resources-api.ts +143 -0
  8. package/apis/intf/resources.ts +49 -0
  9. package/apis/intf/{modal.ts → shell-api/modal.ts} +21 -26
  10. package/apis/intf/shell-api/proxy.ts +216 -0
  11. package/apis/intf/{slide-in.ts → shell-api/slide-in.ts} +4 -3
  12. package/apis/intf/{system.ts → shell-api/system.ts} +4 -1
  13. package/apis/intf/shell.ts +12 -6
  14. package/apis/resources/__tests__/resources-api-class.test.ts +550 -0
  15. package/apis/resources/index.ts +22 -0
  16. package/apis/resources/resources-api-class.ts +187 -0
  17. package/apis/shell/__tests__/proxy.test.ts +369 -0
  18. package/apis/shell/index.ts +8 -1
  19. package/apis/shell/modal.ts +4 -1
  20. package/apis/shell/notifications.ts +9 -6
  21. package/apis/shell/proxy.ts +256 -0
  22. package/apis/shell/slide-in.ts +4 -1
  23. package/apis/vue-shim.d.ts +2 -1
  24. package/assets/data/aws-regions.json +4 -0
  25. package/assets/fonts/lato/LatoLatin-Black.woff +0 -0
  26. package/assets/fonts/lato/LatoLatin-Black.woff2 +0 -0
  27. package/assets/fonts/lato/LatoLatin-BlackItalic.woff +0 -0
  28. package/assets/fonts/lato/LatoLatin-BlackItalic.woff2 +0 -0
  29. package/assets/fonts/lato/LatoLatin-Bold.woff +0 -0
  30. package/assets/fonts/lato/LatoLatin-Bold.woff2 +0 -0
  31. package/assets/fonts/lato/LatoLatin-BoldItalic.woff +0 -0
  32. package/assets/fonts/lato/LatoLatin-BoldItalic.woff2 +0 -0
  33. package/assets/fonts/lato/LatoLatin-Heavy.woff +0 -0
  34. package/assets/fonts/lato/LatoLatin-Heavy.woff2 +0 -0
  35. package/assets/fonts/lato/LatoLatin-HeavyItalic.woff +0 -0
  36. package/assets/fonts/lato/LatoLatin-HeavyItalic.woff2 +0 -0
  37. package/assets/fonts/lato/LatoLatin-Italic.woff +0 -0
  38. package/assets/fonts/lato/LatoLatin-Italic.woff2 +0 -0
  39. package/assets/fonts/lato/LatoLatin-Light.woff +0 -0
  40. package/assets/fonts/lato/LatoLatin-Light.woff2 +0 -0
  41. package/assets/fonts/lato/LatoLatin-LightItalic.woff +0 -0
  42. package/assets/fonts/lato/LatoLatin-LightItalic.woff2 +0 -0
  43. package/assets/fonts/lato/LatoLatin-Medium.woff +0 -0
  44. package/assets/fonts/lato/LatoLatin-Medium.woff2 +0 -0
  45. package/assets/fonts/lato/LatoLatin-MediumItalic.woff +0 -0
  46. package/assets/fonts/lato/LatoLatin-MediumItalic.woff2 +0 -0
  47. package/assets/fonts/lato/LatoLatin-Regular.woff +0 -0
  48. package/assets/fonts/lato/LatoLatin-Regular.woff2 +0 -0
  49. package/assets/fonts/lato/LatoLatin-Semibold.woff +0 -0
  50. package/assets/fonts/lato/LatoLatin-Semibold.woff2 +0 -0
  51. package/assets/fonts/lato/LatoLatin-SemiboldItalic.woff +0 -0
  52. package/assets/fonts/lato/LatoLatin-SemiboldItalic.woff2 +0 -0
  53. package/assets/styles/base/_variables.scss +2 -0
  54. package/assets/styles/fonts/_fontstack.scss +132 -8
  55. package/assets/styles/global/_layout.scss +4 -0
  56. package/assets/translations/en-us.yaml +165 -45
  57. package/assets/translations/zh-hans.yaml +1 -7
  58. package/chart/monitoring/ClusterSelector.vue +0 -21
  59. package/chart/monitoring/index.vue +10 -1
  60. package/chart/monitoring/prometheus/index.vue +6 -3
  61. package/components/ActionDropdownShell.vue +2 -1
  62. package/components/CruResource.vue +161 -14
  63. package/components/CruResourceFooter.vue +9 -5
  64. package/components/ExplorerMembers.vue +8 -4
  65. package/components/ExplorerProjectsNamespaces.vue +11 -7
  66. package/components/GrowlManager.vue +4 -0
  67. package/components/InstallHelmCharts.vue +2 -2
  68. package/components/LandingPagePreference.vue +14 -5
  69. package/components/MgmtNodeList.vue +184 -0
  70. package/components/Resource/Detail/Card/StateCard/__tests__/composables.test.ts +90 -1
  71. package/components/Resource/Detail/Card/StateCard/composables.ts +57 -87
  72. package/components/Resource/Detail/Card/StatusCard/__tests__/StatusCard.test.ts +61 -0
  73. package/components/Resource/Detail/Card/StatusCard/index.vue +61 -15
  74. package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +17 -1
  75. package/components/Resource/Detail/Metadata/KeyValue.vue +5 -2
  76. package/components/Resource/Detail/Metadata/KeyValueRow.vue +2 -6
  77. package/components/Resource/Detail/Metadata/index.vue +6 -0
  78. package/components/Resource/Detail/ResourcePopover/index.vue +12 -1
  79. package/components/Resource/Detail/SpacedRow.vue +3 -1
  80. package/components/Resource/Detail/TitleBar/index.vue +10 -11
  81. package/components/ResourceDetail/index.vue +1 -1
  82. package/components/ResourceList/Masthead.vue +19 -9
  83. package/components/ResourceList/index.vue +82 -1
  84. package/components/RichTranslation.vue +5 -2
  85. package/components/SelectIconGrid.vue +0 -10
  86. package/components/Setting.vue +1 -0
  87. package/components/SingleClusterInfo.vue +1 -0
  88. package/components/SortableTable/__tests__/sorting.test.ts +126 -0
  89. package/components/SortableTable/index.vue +6 -9
  90. package/components/SortableTable/selection.js +23 -5
  91. package/components/SortableTable/sorting.js +6 -3
  92. package/components/SubtleLink.vue +31 -6
  93. package/components/Tabbed/Tab.vue +29 -3
  94. package/components/Tabbed/index.vue +25 -3
  95. package/components/TableOfContents/TableOfContents.vue +109 -0
  96. package/components/TableOfContents/composables.ts +258 -0
  97. package/components/Window/ContainerShell.vue +21 -11
  98. package/components/Window/__tests__/ContainerShell.test.ts +107 -37
  99. package/components/Wizard.vue +23 -17
  100. package/components/fleet/AppCoChartGrid.vue +401 -0
  101. package/components/fleet/AppCoEmptyState.vue +127 -0
  102. package/components/fleet/AppCoPageHeader.vue +119 -0
  103. package/components/fleet/AppCoVersionSelect.vue +70 -0
  104. package/components/fleet/FleetBundles.vue +100 -12
  105. package/components/fleet/FleetClusterTargets/ClusterSelectionFields.vue +217 -0
  106. package/components/fleet/FleetClusterTargets/TargetsList.vue +123 -35
  107. package/components/fleet/FleetClusterTargets/index.vue +226 -161
  108. package/components/fleet/FleetIntro.vue +7 -3
  109. package/components/fleet/FleetNoWorkspaces.vue +7 -3
  110. package/components/fleet/FleetSecretSelector.vue +5 -3
  111. package/components/fleet/FleetValuesFrom.vue +8 -2
  112. package/components/fleet/GitRepoTargetTab.vue +0 -2
  113. package/components/fleet/HelmOpAdvancedTab.vue +19 -53
  114. package/components/fleet/HelmOpAppCoConfigTab.vue +593 -0
  115. package/components/fleet/HelmOpAppCoResourcesSection.vue +162 -0
  116. package/components/fleet/HelmOpResourcesSection.vue +82 -0
  117. package/components/fleet/HelmOpTargetOptionsSection.vue +89 -0
  118. package/components/fleet/HelmOpTargetTab.vue +64 -60
  119. package/components/fleet/HelmOpValuesTab.vue +129 -105
  120. package/components/fleet/__tests__/AppCoEmptyState.test.ts +71 -0
  121. package/components/fleet/__tests__/AppCoVersionSelect.test.ts +36 -0
  122. package/components/fleet/__tests__/ClusterSelectionFields.test.ts +62 -0
  123. package/components/fleet/__tests__/FleetClusterTargets.test.ts +402 -115
  124. package/components/fleet/__tests__/FleetClusters.test.ts +12 -12
  125. package/components/fleet/__tests__/FleetSecretSelector.test.ts +16 -0
  126. package/components/fleet/__tests__/FleetValuesFrom.test.ts +44 -0
  127. package/components/fleet/__tests__/HelmOpAppCoConfigTab.test.ts +59 -0
  128. package/components/fleet/__tests__/HelmOpAppCoResourcesSection.test.ts +62 -0
  129. package/components/fleet/__tests__/HelmOpResourcesSection.test.ts +43 -0
  130. package/components/fleet/__tests__/HelmOpTargetOptionsSection.test.ts +34 -0
  131. package/components/fleet/__tests__/HelmOpValuesTab.test.ts +39 -0
  132. package/components/fleet/__tests__/__snapshots__/AppCoEmptyState.test.ts.snap +97 -0
  133. package/components/fleet/__tests__/__snapshots__/AppCoVersionSelect.test.ts.snap +30 -0
  134. package/components/fleet/__tests__/__snapshots__/ClusterSelectionFields.test.ts.snap +209 -0
  135. package/components/fleet/__tests__/__snapshots__/HelmOpTargetOptionsSection.test.ts.snap +140 -0
  136. package/components/fleet/dashboard/Empty.vue +8 -4
  137. package/components/fleet/dashboard/ResourceCard.vue +28 -0
  138. package/components/fleet/dashboard/ResourceDetails.vue +28 -0
  139. package/components/fleet/dashboard/__tests__/ResourceCard.test.ts +87 -0
  140. package/components/form/ArrayList.vue +61 -4
  141. package/components/form/KeyValue.vue +23 -2
  142. package/components/form/LabeledSelect.vue +59 -4
  143. package/components/form/Labels.vue +22 -3
  144. package/components/form/NameNsDescription.vue +24 -5
  145. package/components/form/ResourceTabs/index.vue +1 -0
  146. package/components/form/Security.vue +6 -2
  147. package/components/form/WorkloadPorts.vue +2 -7
  148. package/components/form/__tests__/NameNsDescription.test.ts +75 -0
  149. package/components/form/__tests__/Security.test.ts +76 -0
  150. package/components/formatter/Autoscaler.vue +4 -4
  151. package/components/formatter/ClusterKubeVersion.vue +27 -0
  152. package/components/formatter/ClusterLink.vue +1 -7
  153. package/components/formatter/ClusterProvider.vue +6 -10
  154. package/components/formatter/FleetSummaryGraph.vue +0 -3
  155. package/components/formatter/InternalExternalIP.vue +10 -4
  156. package/components/formatter/MachineSummaryGraph.vue +1 -1
  157. package/components/formatter/PodsUsage.vue +2 -2
  158. package/components/formatter/ServiceTargets.vue +26 -7
  159. package/components/formatter/__tests__/Autoscaler.test.ts +19 -22
  160. package/components/formatter/__tests__/FleetSummaryGraph.test.ts +216 -0
  161. package/components/formatter/__tests__/InternalExternalIP.test.ts +132 -0
  162. package/components/formatter/__tests__/PodsUsage.test.ts +6 -10
  163. package/components/formatter/__tests__/ServiceTargets.test.ts +412 -0
  164. package/components/nav/Header.vue +4 -0
  165. package/components/nav/NamespaceFilter.vue +2 -2
  166. package/components/nav/TopLevelMenu.helper.ts +15 -3
  167. package/components/nav/TopLevelMenu.vue +22 -6
  168. package/components/nav/__tests__/Header.test.ts +15 -0
  169. package/components/nav/__tests__/TopLevelMenu.test.ts +263 -21
  170. package/components/templates/default.vue +9 -4
  171. package/components/templates/home.vue +23 -0
  172. package/components/templates/plain.vue +23 -0
  173. package/components/templates/standalone.vue +17 -0
  174. package/composables/useFormValidation.ts +93 -0
  175. package/composables/useHelmOpResources.test.ts +56 -0
  176. package/composables/useHelmOpResources.ts +32 -0
  177. package/composables/useStateColor.test.ts +325 -0
  178. package/composables/useStateColor.ts +128 -0
  179. package/composables/useVeeValidateField.test.ts +159 -0
  180. package/composables/useVeeValidateField.ts +67 -0
  181. package/config/home-links.js +1 -1
  182. package/config/labels-annotations.js +1 -0
  183. package/config/pagination-table-headers.js +18 -1
  184. package/config/product/explorer.js +17 -4
  185. package/config/product/manager.js +84 -21
  186. package/config/router/index.js +16 -0
  187. package/config/router/navigation-guards/__tests__/authentication.test.ts +130 -0
  188. package/config/router/navigation-guards/authentication.js +10 -4
  189. package/config/router/routes.js +26 -6
  190. package/config/settings.ts +0 -2
  191. package/config/table-headers.js +23 -5
  192. package/config/types.js +11 -1
  193. package/core/__tests__/plugin-products.test.ts +904 -20
  194. package/core/plugin-products-base.ts +110 -10
  195. package/core/plugin-products.ts +4 -0
  196. package/core/plugin-types.ts +194 -31
  197. package/core/plugin.ts +18 -7
  198. package/core/productDebugger.js +9 -4
  199. package/core/types-provisioning.ts +77 -31
  200. package/core/types.ts +72 -22
  201. package/detail/__tests__/pod.test.ts +41 -0
  202. package/detail/__tests__/provisioning.cattle.io.cluster.test.ts +114 -0
  203. package/detail/__tests__/workload.test.ts +3 -152
  204. package/detail/catalog.cattle.io.clusterrepo.vue +1 -1
  205. package/detail/harvesterhci.io.management.cluster.vue +6 -2
  206. package/detail/pod.vue +1 -1
  207. package/detail/provisioning.cattle.io.cluster.vue +34 -14
  208. package/detail/workload/index.vue +12 -55
  209. package/edit/__tests__/catalog.cattle.io.clusterrepo.test.ts +248 -0
  210. package/edit/__tests__/fleet.cattle.io.helmop.test.ts +105 -0
  211. package/edit/auditlog.cattle.io.auditpolicy/__tests__/__snapshots__/General.test.ts.snap +6 -0
  212. package/edit/auditlog.cattle.io.auditpolicy/__tests__/__snapshots__/index.test.ts.snap +1 -0
  213. package/edit/auth/__tests__/azuread.test.ts +247 -39
  214. package/edit/auth/__tests__/github.test.ts +234 -0
  215. package/edit/auth/__tests__/oidc.test.ts +26 -6
  216. package/edit/auth/__tests__/saml.test.ts +196 -0
  217. package/edit/auth/azuread.vue +197 -56
  218. package/edit/auth/github.vue +72 -13
  219. package/edit/auth/ldap/__tests__/index.test.ts +206 -0
  220. package/edit/auth/ldap/config.vue +8 -0
  221. package/edit/auth/ldap/index.vue +75 -1
  222. package/edit/auth/oidc.vue +119 -73
  223. package/edit/auth/saml.vue +76 -12
  224. package/edit/catalog.cattle.io.clusterrepo.vue +140 -32
  225. package/edit/fleet.cattle.io.helmop.vue +491 -136
  226. package/edit/management.cattle.io.user.vue +5 -2
  227. package/edit/networking.k8s.io.ingress/DefaultBackend.vue +13 -4
  228. package/edit/networking.k8s.io.ingress/RulePath.vue +8 -4
  229. package/edit/networking.k8s.io.ingress/index.vue +75 -20
  230. package/edit/provisioning.cattle.io.cluster/__tests__/MachinePool.test.ts +104 -0
  231. package/edit/provisioning.cattle.io.cluster/index.vue +11 -7
  232. package/edit/provisioning.cattle.io.cluster/rke2.vue +92 -14
  233. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +22 -0
  234. package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +37 -4
  235. package/edit/provisioning.cattle.io.cluster/tabs/registries/__tests__/RegistryConfigs.test.ts +132 -7
  236. package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +2 -1
  237. package/edit/secret/__tests__/ssh.test.ts +5 -6
  238. package/edit/secret/basic.vue +31 -0
  239. package/edit/secret/index.vue +68 -17
  240. package/edit/secret/registry.vue +38 -0
  241. package/edit/secret/ssh.vue +29 -0
  242. package/edit/secret/tls.vue +30 -0
  243. package/edit/service.vue +4 -4
  244. package/edit/workload/Upgrading.vue +3 -3
  245. package/edit/workload/__tests__/Upgrading.test.ts +6 -9
  246. package/edit/workload/mixins/workload.js +2 -1
  247. package/list/fleet.cattle.io.bundle.vue +7 -104
  248. package/list/fleet.cattle.io.clusterregistrationtoken.vue +20 -0
  249. package/list/group.principal.vue +5 -4
  250. package/list/harvesterhci.io.management.cluster.vue +8 -9
  251. package/list/management.cattle.io.user.vue +12 -9
  252. package/list/provisioning.cattle.io.cluster.vue +268 -180
  253. package/list/utils/management.cattle.io.cluster.utils.ts +128 -0
  254. package/mixins/__tests__/auth-config.test.ts +90 -0
  255. package/mixins/__tests__/chart.test.ts +206 -0
  256. package/mixins/__tests__/resource-fetch-api-pagination.test.ts +48 -0
  257. package/mixins/auth-config.js +7 -0
  258. package/mixins/brand.js +2 -1
  259. package/mixins/chart.js +22 -9
  260. package/mixins/child-hook.js +12 -6
  261. package/mixins/create-edit-view/impl.js +5 -3
  262. package/mixins/resource-fetch-api-pagination.js +62 -6
  263. package/models/__tests__/catalog.cattle.io.clusterrepo.test.ts +57 -0
  264. package/models/__tests__/compliance.cattle.io.clusterscan.test.ts +144 -0
  265. package/models/__tests__/ext.cattle.io.kubeconfig.test.ts +67 -67
  266. package/models/__tests__/fleet-application.test.ts +175 -0
  267. package/models/__tests__/fleet.cattle.io.bundle.test.ts +169 -0
  268. package/models/__tests__/fleet.cattle.io.helmop.test.ts +84 -0
  269. package/models/__tests__/management.cattle.io.cluster.test.ts +1 -1
  270. package/models/__tests__/management.cattle.io.node.ts +28 -5
  271. package/models/__tests__/management.cattle.io.nodepool.ts +5 -4
  272. package/models/__tests__/namespace.test.ts +36 -0
  273. package/models/__tests__/provisioning.cattle.io.cluster.test.ts +81 -11
  274. package/models/__tests__/workload.test.ts +401 -26
  275. package/models/base-cluster.x-k8s.io.js +26 -0
  276. package/models/catalog.cattle.io.clusterrepo.js +28 -4
  277. package/models/cluster.js +1 -1
  278. package/models/cluster.x-k8s.io.machine.js +4 -22
  279. package/models/cluster.x-k8s.io.machinedeployment.js +2 -20
  280. package/models/cluster.x-k8s.io.machineset.js +2 -20
  281. package/models/compliance.cattle.io.clusterscan.js +165 -2
  282. package/models/ext.cattle.io.kubeconfig.ts +4 -7
  283. package/models/fleet-application.js +7 -1
  284. package/models/fleet.cattle.io.helmop.js +20 -1
  285. package/models/management.cattle.io.cluster.js +434 -41
  286. package/models/management.cattle.io.node.js +50 -7
  287. package/models/management.cattle.io.nodepool.js +1 -1
  288. package/models/namespace.js +1 -1
  289. package/models/networking.k8s.io.ingress.js +12 -4
  290. package/models/pod.js +33 -1
  291. package/models/provisioning.cattle.io.cluster.js +51 -334
  292. package/models/rke.cattle.io.etcdsnapshot.js +1 -2
  293. package/models/workload.js +108 -13
  294. package/models/workload.service.js +5 -0
  295. package/package.json +22 -39
  296. package/pages/__tests__/readme.test.ts +49 -0
  297. package/pages/about.vue +5 -6
  298. package/pages/auth/login.vue +0 -35
  299. package/pages/auth/setup.vue +13 -3
  300. package/pages/c/_cluster/apps/charts/AppChartCardFooter.vue +2 -2
  301. package/pages/c/_cluster/apps/charts/AppChartCardSubHeader.vue +10 -1
  302. package/pages/c/_cluster/apps/charts/__tests__/chart.test.ts +76 -0
  303. package/pages/c/_cluster/apps/charts/__tests__/index.test.ts +93 -0
  304. package/pages/c/_cluster/apps/charts/chart.vue +62 -9
  305. package/pages/c/_cluster/apps/charts/index.vue +48 -10
  306. package/pages/c/_cluster/apps/charts/install.vue +122 -113
  307. package/pages/c/_cluster/auth/roles/index.vue +5 -4
  308. package/pages/c/_cluster/explorer/__tests__/index.test.ts +23 -25
  309. package/pages/c/_cluster/explorer/index.vue +5 -49
  310. package/pages/c/_cluster/explorer/workload-dashboard/ByNamespaceSection.vue +31 -0
  311. package/pages/c/_cluster/explorer/workload-dashboard/ByStateSection.vue +138 -0
  312. package/pages/c/_cluster/explorer/workload-dashboard/ByTypeSection.vue +30 -0
  313. package/pages/c/_cluster/explorer/workload-dashboard/WorkloadCard.vue +155 -0
  314. package/pages/c/_cluster/explorer/workload-dashboard/WorkloadNamespaceCard.vue +142 -0
  315. package/pages/c/_cluster/explorer/workload-dashboard/WorkloadTypeCard.vue +159 -0
  316. package/pages/c/_cluster/explorer/workload-dashboard/__tests__/composable.test.ts +561 -0
  317. package/pages/c/_cluster/explorer/workload-dashboard/composable.ts +440 -0
  318. package/pages/c/_cluster/explorer/workload-dashboard/index.vue +187 -0
  319. package/pages/c/_cluster/explorer/workload-dashboard/types.ts +80 -0
  320. package/pages/c/_cluster/fleet/application/create.vue +187 -136
  321. package/pages/c/_cluster/fleet/application/index.vue +5 -3
  322. package/pages/c/_cluster/fleet/application/suse-app-collection/ChartDetailBody.vue +338 -0
  323. package/pages/c/_cluster/fleet/application/suse-app-collection/ChartDetailHeader.vue +121 -0
  324. package/pages/c/_cluster/fleet/application/suse-app-collection/chart.vue +369 -0
  325. package/pages/c/_cluster/fleet/application/suse-app-collection/charts.vue +248 -0
  326. package/pages/c/_cluster/fleet/application/suse-app-collection/credentials.vue +310 -0
  327. package/pages/c/_cluster/fleet/index.vue +2 -2
  328. package/pages/c/_cluster/istio/__tests__/istio.index.test.ts +194 -0
  329. package/pages/c/_cluster/istio/index.vue +21 -6
  330. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +1 -0
  331. package/pages/c/_cluster/uiplugins/__tests__/index.test.ts +815 -2
  332. package/pages/c/_cluster/uiplugins/index.vue +218 -197
  333. package/pages/diagnostic.vue +13 -17
  334. package/pages/fail-whale.vue +30 -7
  335. package/pages/home.vue +93 -306
  336. package/pages/readme.vue +88 -0
  337. package/plugins/clean-html.d.ts +9 -0
  338. package/plugins/dashboard-store/__tests__/resource-class.test.ts +181 -0
  339. package/plugins/dashboard-store/actions.js +40 -18
  340. package/plugins/dashboard-store/resource-class.js +67 -9
  341. package/plugins/steve/__tests__/actions.test.ts +212 -0
  342. package/plugins/steve/__tests__/subscribe.spec.ts +6 -3
  343. package/plugins/steve/actions.js +96 -0
  344. package/plugins/steve/steve-pagination-utils.ts +12 -4
  345. package/plugins/steve/subscribe.js +35 -5
  346. package/rancher-components/Accordion/Accordion.vue +53 -9
  347. package/rancher-components/Form/Checkbox/Checkbox.vue +14 -0
  348. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +10 -4
  349. package/rancher-components/Form/LabeledInput/LabeledInput.vue +7 -52
  350. package/rancher-components/Form/Radio/RadioButton.vue +17 -1
  351. package/rancher-components/Form/Radio/RadioGroup.vue +10 -0
  352. package/rancher-components/Pill/RcTag/RcTag.vue +3 -2
  353. package/rancher-components/RcButton/RcButton.test.ts +140 -1
  354. package/rancher-components/RcButton/RcButton.vue +126 -17
  355. package/rancher-components/RcButton/types.ts +3 -0
  356. package/rancher-components/RcDropdown/RcDropdownTrigger.vue +10 -8
  357. package/rancher-components/RcItemCard/RcItemCard.test.ts +18 -0
  358. package/rancher-components/RcItemCard/RcItemCard.vue +2 -2
  359. package/rancher-components/RcSection/RcSection.vue +28 -3
  360. package/scripts/extension/helm/package/Dockerfile +1 -1
  361. package/scripts/test-plugins-build.sh +2 -1
  362. package/store/__tests__/catalog.test.ts +115 -1
  363. package/store/__tests__/notifications.test.ts +434 -0
  364. package/store/__tests__/type-map.test.ts +556 -1
  365. package/store/action-menu.js +8 -3
  366. package/store/auth.js +1 -1
  367. package/store/aws.js +27 -16
  368. package/store/catalog.js +84 -3
  369. package/store/digitalocean.js +20 -38
  370. package/store/index.js +2 -0
  371. package/store/linode.js +25 -40
  372. package/store/plugins.js +7 -4
  373. package/store/pnap.js +1 -0
  374. package/store/type-map.js +111 -29
  375. package/tsconfig.paths.json +8 -8
  376. package/types/components/buttonGroup.ts +5 -0
  377. package/types/kube/kube-api.ts +14 -1
  378. package/types/rancher/steve.api.ts +12 -12
  379. package/types/resources/settings.d.ts +2 -1
  380. package/types/shell/index.d.ts +206 -72
  381. package/types/store/dashboard-store.types.ts +108 -11
  382. package/types/store/pagination.types.ts +6 -3
  383. package/utils/__tests__/alertmanagerconfig.test.ts +117 -0
  384. package/utils/__tests__/async.test.ts +87 -0
  385. package/utils/__tests__/auth.test.ts +273 -0
  386. package/utils/__tests__/aws.test.ts +140 -0
  387. package/utils/__tests__/banners.test.ts +176 -0
  388. package/utils/__tests__/chart.test.ts +64 -1
  389. package/utils/__tests__/color.test.ts +226 -0
  390. package/utils/__tests__/computed.test.ts +193 -0
  391. package/utils/__tests__/cspAdaptor.test.ts +163 -0
  392. package/utils/__tests__/dom.test.ts +81 -0
  393. package/utils/__tests__/duration.test.ts +176 -0
  394. package/utils/__tests__/dynamic-importer.test.ts +102 -0
  395. package/utils/__tests__/fleet-appco.test.ts +312 -0
  396. package/utils/__tests__/fleet.test.ts +340 -0
  397. package/utils/__tests__/ingress.test.ts +553 -0
  398. package/utils/__tests__/kube.test.ts +68 -0
  399. package/utils/__tests__/monitoring.test.ts +130 -0
  400. package/utils/__tests__/namespace-filter.test.ts +109 -0
  401. package/utils/__tests__/object.test.ts +22 -0
  402. package/utils/__tests__/pagination-utils.test.ts +361 -0
  403. package/utils/__tests__/parse-externalid.test.ts +137 -0
  404. package/utils/__tests__/perf-setting.utils.test.ts +98 -0
  405. package/utils/__tests__/platform.test.ts +91 -0
  406. package/utils/__tests__/poller-sequential.test.ts +177 -0
  407. package/utils/__tests__/poller.test.ts +170 -0
  408. package/utils/__tests__/position.test.ts +237 -0
  409. package/utils/__tests__/promise.test.ts +346 -0
  410. package/utils/__tests__/provider.test.ts +51 -1
  411. package/utils/__tests__/queue.test.ts +232 -0
  412. package/utils/__tests__/release-notes.test.ts +221 -0
  413. package/utils/__tests__/router.test.js +254 -1
  414. package/utils/__tests__/select.test.ts +208 -0
  415. package/utils/__tests__/settings.test.ts +140 -0
  416. package/utils/__tests__/sort-utils.test.ts +301 -0
  417. package/utils/__tests__/string-utils.test.ts +798 -0
  418. package/utils/__tests__/string.test.ts +23 -1
  419. package/utils/__tests__/style.test.ts +154 -0
  420. package/utils/__tests__/svg-filter.test.ts +184 -0
  421. package/utils/__tests__/time.test.ts +265 -1
  422. package/utils/__tests__/title.test.ts +47 -0
  423. package/utils/__tests__/units.test.ts +417 -0
  424. package/utils/__tests__/versions.test.ts +128 -0
  425. package/utils/__tests__/width.test.ts +53 -0
  426. package/utils/__tests__/window.test.ts +158 -0
  427. package/utils/__tests__/xccdf.test.ts +511 -0
  428. package/utils/chart.js +36 -0
  429. package/utils/crypto/__tests__/browserHashUtils.test.ts +98 -0
  430. package/utils/crypto/__tests__/index.test.ts +144 -0
  431. package/utils/duration.ts +104 -0
  432. package/utils/dynamic-content/__tests__/notification-handler.test.ts +196 -0
  433. package/utils/dynamic-content/info.ts +2 -1
  434. package/utils/error.js +13 -0
  435. package/utils/fleet-appco.ts +323 -0
  436. package/utils/fleet.ts +13 -3
  437. package/utils/gatekeeper/__tests__/util.test.ts +174 -0
  438. package/utils/gc/__tests__/gc-interval.test.ts +119 -0
  439. package/utils/gc/__tests__/gc-root-store.test.ts +225 -0
  440. package/utils/gc/__tests__/gc-route-changed.test.ts +96 -0
  441. package/utils/gc/__tests__/gc.test.ts +487 -0
  442. package/utils/ingress.ts +9 -1
  443. package/utils/object.js +22 -2
  444. package/utils/pagination-utils.ts +2 -1
  445. package/utils/provider.ts +12 -0
  446. package/utils/string.js +25 -2
  447. package/utils/uiplugins.ts +5 -5
  448. package/utils/validators/__tests__/cluster-name.test.ts +110 -0
  449. package/utils/validators/__tests__/container-images.test.ts +104 -0
  450. package/utils/validators/__tests__/cron-schedule.test.ts +79 -0
  451. package/utils/validators/__tests__/flow-output.test.ts +91 -0
  452. package/utils/validators/__tests__/index.test.ts +481 -0
  453. package/utils/validators/__tests__/kubernetes-name.test.ts +163 -0
  454. package/utils/validators/__tests__/logging-outputs.test.ts +58 -0
  455. package/utils/validators/__tests__/misc-validators.test.ts +246 -0
  456. package/utils/validators/__tests__/monitoring-route.test.ts +119 -0
  457. package/utils/validators/__tests__/pod-affinity.test.ts +382 -0
  458. package/utils/validators/__tests__/prometheusrule.test.ts +211 -0
  459. package/utils/validators/__tests__/role-template.test.ts +149 -0
  460. package/utils/validators/__tests__/service.test.ts +283 -0
  461. package/utils/validators/__tests__/setting.test.js +32 -0
  462. package/utils/validators/formRules/__tests__/index.test.ts +50 -0
  463. package/utils/validators/formRules/index.ts +5 -5
  464. package/utils/validators/machine-pool.ts +1 -1
  465. package/utils/validators/setting.js +18 -3
  466. package/utils/xccdf.ts +415 -0
  467. package/vue.config.js +1 -1
  468. package/assets/fonts/lato/lato-v17-latin-700.woff +0 -0
  469. package/assets/fonts/lato/lato-v17-latin-700.woff2 +0 -0
  470. package/assets/fonts/lato/lato-v17-latin-regular.woff +0 -0
  471. package/assets/fonts/lato/lato-v17-latin-regular.woff2 +0 -0
  472. package/pages/support/index.vue +0 -264
  473. package/utils/duration.js +0 -43
@@ -0,0 +1,169 @@
1
+ import FleetBundle from '@shell/models/fleet.cattle.io.bundle.js';
2
+
3
+ describe('class FleetBundle', () => {
4
+ afterEach(() => {
5
+ jest.restoreAllMocks();
6
+ });
7
+
8
+ describe('targetClusters', () => {
9
+ function createFleetBundle(targets: any[], clusters: any[], workspaceId = 'fleet-default', groups: any[] = []) {
10
+ const workspace = {
11
+ id: workspaceId,
12
+ clusters,
13
+ clusterGroups: groups,
14
+ };
15
+
16
+ jest.spyOn(FleetBundle.prototype, '$getters', 'get').mockReturnValue({ byId: () => workspace });
17
+
18
+ return new FleetBundle({
19
+ metadata: { namespace: workspaceId },
20
+ spec: { targets },
21
+ });
22
+ }
23
+
24
+ it.each([
25
+ [
26
+ 'metadata.name',
27
+ [{ clusterName: 'c-m-abc123' }],
28
+ [{
29
+ id: 'fleet-default/c-m-abc123', metadata: { name: 'c-m-abc123' }, nameDisplay: 'my-cluster'
30
+ }],
31
+ [{
32
+ id: 'fleet-default/c-m-abc123', metadata: { name: 'c-m-abc123' }, nameDisplay: 'my-cluster'
33
+ }],
34
+ ],
35
+ [
36
+ 'nameDisplay when metadata.name does not match',
37
+ [{ clusterName: 'my-display-name' }],
38
+ [{
39
+ id: 'fleet-default/c-m-abc123', metadata: { name: 'c-m-abc123' }, nameDisplay: 'my-display-name'
40
+ }],
41
+ [{
42
+ id: 'fleet-default/c-m-abc123', metadata: { name: 'c-m-abc123' }, nameDisplay: 'my-display-name'
43
+ }],
44
+ ],
45
+ ])('should find cluster by %s', (_label, targets, clusters, expected) => {
46
+ const bundle = createFleetBundle(targets, clusters);
47
+
48
+ expect(bundle.targetClusters).toStrictEqual(expected);
49
+ });
50
+
51
+ it('should prefer metadata.name match over nameDisplay match', () => {
52
+ const clusters = [
53
+ {
54
+ id: 'fleet-default/exact-match',
55
+ metadata: { name: 'exact-match' },
56
+ nameDisplay: 'display-a',
57
+ },
58
+ {
59
+ id: 'fleet-default/c-m-other',
60
+ metadata: { name: 'c-m-other' },
61
+ nameDisplay: 'exact-match',
62
+ }
63
+ ];
64
+
65
+ const bundle = createFleetBundle([{ clusterName: 'exact-match' }], clusters);
66
+
67
+ expect(bundle.targetClusters).toStrictEqual([clusters[0]]);
68
+ });
69
+
70
+ it('should return empty array when no cluster matches by name or nameDisplay', () => {
71
+ const clusters = [
72
+ {
73
+ id: 'fleet-default/c-m-abc123',
74
+ metadata: { name: 'c-m-abc123' },
75
+ nameDisplay: 'my-cluster',
76
+ }
77
+ ];
78
+
79
+ const bundle = createFleetBundle([{ clusterName: 'non-existent' }], clusters);
80
+
81
+ expect(bundle.targetClusters).toStrictEqual([]);
82
+ });
83
+
84
+ it('should handle multiple targets with mixed name and nameDisplay matches', () => {
85
+ const clusters = [
86
+ {
87
+ id: 'fleet-default/c-m-abc123',
88
+ metadata: { name: 'c-m-abc123' },
89
+ nameDisplay: 'cluster-alpha',
90
+ },
91
+ {
92
+ id: 'fleet-default/c-m-def456',
93
+ metadata: { name: 'c-m-def456' },
94
+ nameDisplay: 'cluster-beta',
95
+ }
96
+ ];
97
+
98
+ const targets = [
99
+ { clusterName: 'c-m-abc123' },
100
+ { clusterName: 'cluster-beta' },
101
+ ];
102
+
103
+ const bundle = createFleetBundle(targets, clusters);
104
+
105
+ expect(bundle.targetClusters).toStrictEqual([clusters[0], clusters[1]]);
106
+ });
107
+
108
+ it('should return empty array when workspace has no clusters', () => {
109
+ const bundle = createFleetBundle([{ clusterName: 'any-name' }], []);
110
+
111
+ expect(bundle.targetClusters).toStrictEqual([]);
112
+ });
113
+
114
+ it('should handle cluster with undefined nameDisplay gracefully', () => {
115
+ const clusters = [
116
+ {
117
+ id: 'fleet-default/c-m-abc123',
118
+ metadata: { name: 'c-m-abc123' },
119
+ nameDisplay: undefined,
120
+ }
121
+ ];
122
+
123
+ const bundle = createFleetBundle([{ clusterName: 'c-m-abc123' }], clusters);
124
+
125
+ expect(bundle.targetClusters).toStrictEqual([clusters[0]]);
126
+ });
127
+
128
+ it('should not match by nameDisplay when nameDisplay is undefined and target uses a different name', () => {
129
+ const clusters = [
130
+ {
131
+ id: 'fleet-default/c-m-abc123',
132
+ metadata: { name: 'c-m-abc123' },
133
+ nameDisplay: undefined,
134
+ }
135
+ ];
136
+
137
+ const bundle = createFleetBundle([{ clusterName: 'some-other-name' }], clusters);
138
+
139
+ expect(bundle.targetClusters).toStrictEqual([]);
140
+ });
141
+
142
+ it('should return local cluster targets when workspace is fleet-local', () => {
143
+ const localTargetClusters = [
144
+ {
145
+ id: 'fleet-local/local',
146
+ metadata: { name: 'local' },
147
+ nameDisplay: 'local',
148
+ }
149
+ ];
150
+
151
+ const groups = [
152
+ {
153
+ id: 'fleet-local/default',
154
+ targetClusters: localTargetClusters,
155
+ }
156
+ ];
157
+
158
+ const bundle = createFleetBundle([], [], 'fleet-local', groups);
159
+
160
+ expect(bundle.targetClusters).toStrictEqual(localTargetClusters);
161
+ });
162
+
163
+ it('should return empty array when workspace is fleet-local and default group is missing', () => {
164
+ const bundle = createFleetBundle([], [], 'fleet-local', []);
165
+
166
+ expect(bundle.targetClusters).toStrictEqual([]);
167
+ });
168
+ });
169
+ });
@@ -1,8 +1,17 @@
1
1
  import HelmOp from '@shell/models/fleet.cattle.io.helmop.js';
2
+ import { SUSE_APP_COLLECTION_REPO_URL } from '@shell/utils/fleet-appco';
3
+
4
+ const mockIsRancherPrime = jest.fn(() => true);
5
+
6
+ jest.mock('@shell/config/version', () => ({ isRancherPrime: () => mockIsRancherPrime() }));
2
7
 
3
8
  describe('class HelmOp', () => {
4
9
  let instance;
5
10
 
11
+ beforeEach(() => {
12
+ mockIsRancherPrime.mockReturnValue(true);
13
+ });
14
+
6
15
  describe('source getter', () => {
7
16
  it('should return correct source for SOURCE_TYPE.REPO (HTTPS)', () => {
8
17
  instance = new HelmOp({
@@ -221,4 +230,79 @@ describe('class HelmOp', () => {
221
230
  expect(sourceSub.display).toBe('');
222
231
  });
223
232
  });
233
+
234
+ describe('isSuseAppCollectionFromUI', () => {
235
+ it('should return true when annotation is set', () => {
236
+ instance = new HelmOp({ metadata: { annotations: { 'catalog.cattle.io/suse-application-collection': 'true' } }, spec: { helm: {} } });
237
+
238
+ expect(instance.isSuseAppCollectionFromUI).toBe(true);
239
+ });
240
+
241
+ it('should return false when annotation is missing', () => {
242
+ instance = new HelmOp({ metadata: { annotations: {} }, spec: { helm: {} } });
243
+
244
+ expect(instance.isSuseAppCollectionFromUI).toBe(false);
245
+ });
246
+ });
247
+
248
+ describe('isSuseAppCollection', () => {
249
+ it('should return true even when not Rancher Prime if annotation is set', () => {
250
+ mockIsRancherPrime.mockReturnValue(false);
251
+ instance = new HelmOp({
252
+ metadata: { annotations: { 'catalog.cattle.io/suse-application-collection': 'true' } },
253
+ spec: { helm: {} }
254
+ });
255
+
256
+ expect(instance.isSuseAppCollection).toBe(true);
257
+ });
258
+
259
+ it('should return true when annotation is set and Rancher Prime', () => {
260
+ instance = new HelmOp({
261
+ metadata: { annotations: { 'catalog.cattle.io/suse-application-collection': 'true' } },
262
+ spec: { helm: {} }
263
+ });
264
+
265
+ expect(instance.isSuseAppCollection).toBe(true);
266
+ });
267
+
268
+ it('should return true when repo URL starts with SUSE_APP_COLLECTION_REPO_URL', () => {
269
+ instance = new HelmOp({
270
+ metadata: {},
271
+ spec: { helm: { repo: `${ SUSE_APP_COLLECTION_REPO_URL }/my-chart` } }
272
+ });
273
+
274
+ expect(instance.isSuseAppCollection).toBe(true);
275
+ });
276
+
277
+ it('should return false when no annotation and different repo URL', () => {
278
+ instance = new HelmOp({
279
+ metadata: {},
280
+ spec: { helm: { repo: 'oci://other-registry.io/charts' } }
281
+ });
282
+
283
+ expect(instance.isSuseAppCollection).toBe(false);
284
+ });
285
+ });
286
+
287
+ describe('applicationType', () => {
288
+ it('should return "SUSE AppCo" when isSuseAppCollectionFromUI is true', () => {
289
+ instance = new HelmOp({
290
+ metadata: { annotations: { 'catalog.cattle.io/suse-application-collection': 'true' } },
291
+ spec: { helm: {} },
292
+ kind: 'HelmOp'
293
+ });
294
+
295
+ expect(instance.applicationType).toStrictEqual('SUSE AppCo');
296
+ });
297
+
298
+ it('should return kind when not SUSE App Collection from UI', () => {
299
+ instance = new HelmOp({
300
+ metadata: {},
301
+ spec: { helm: {} },
302
+ kind: 'HelmOp'
303
+ });
304
+
305
+ expect(instance.applicationType).toStrictEqual('HelmOp');
306
+ });
307
+ });
224
308
  });
@@ -7,7 +7,7 @@ jest.mock('@shell/utils/clipboard', () => {
7
7
  describe('class MgmtCluster', () => {
8
8
  describe('provisioner', () => {
9
9
  const testCases = [
10
- [{ provider: 'rke', driver: 'imported' }, 'imported'],
10
+ [{ provider: 'rke2', driver: 'imported' }, 'rke2'],
11
11
  [{ provider: 'k3s', driver: 'K3S' }, 'K3S'],
12
12
  [{ provider: 'aks', driver: 'AKS' }, 'AKS'],
13
13
  [{}, 'imported'],
@@ -94,6 +94,28 @@ describe('class MgmtNode', () => {
94
94
  });
95
95
  });
96
96
 
97
+ describe('pool', () => {
98
+ it('should return undefined if nodePoolName is not set', () => {
99
+ const mgmtNode = new MgmtNode({ spec: {} });
100
+
101
+ expect(mgmtNode.pool).toBeUndefined();
102
+ });
103
+
104
+ it('should return the node pool when nodePoolName is set', () => {
105
+ const nodePool = { id: 'fleet-local/np1' };
106
+ const mgmtNodeCtx = {
107
+ rootGetters: {
108
+ 'i18n/t': t,
109
+ 'management/byId': jest.fn(() => nodePool)
110
+ }
111
+ };
112
+ const mgmtNode = new MgmtNode({ spec: { nodePoolName: 'fleet-local:np1' } }, mgmtNodeCtx);
113
+
114
+ expect(mgmtNode.pool).toStrictEqual(nodePool);
115
+ expect(mgmtNodeCtx.rootGetters['management/byId']).toHaveBeenCalledWith('management.cattle.io.nodepool', 'fleet-local/np1');
116
+ });
117
+ });
118
+
97
119
  describe('canScaleDown', () => {
98
120
  const mgmtClusterId = 'test';
99
121
  const nodeId = 'test/id';
@@ -167,11 +189,12 @@ describe('class MgmtNode', () => {
167
189
  id: nodeId
168
190
  }, {
169
191
  ...baseCtx,
170
- getters: {
171
- all: () => [{
172
- mgmtClusterId,
173
- nodes
174
- }]
192
+ rootGetters: {
193
+ ...baseCtx.rootGetters,
194
+ 'management/byId': () => ({
195
+ id: mgmtClusterId,
196
+ provCluster: { nodes }
197
+ })
175
198
  }
176
199
  });
177
200
 
@@ -66,14 +66,15 @@ describe('class MgmtNodePool', () => {
66
66
  const { spec, nodes } = data;
67
67
  const mgmtNode = new MgmtNodePool({
68
68
  spec,
69
- id: nodeId
69
+ metadata: {},
70
+ id: nodeId
70
71
  }, {
71
72
  ...baseCtx,
72
73
  getters: {
73
- all: () => [{
74
- mgmtClusterId,
74
+ byId: () => ({
75
+ id: mgmtClusterId,
75
76
  nodes
76
- }]
77
+ })
77
78
  }
78
79
  });
79
80
 
@@ -150,6 +150,42 @@ describe('class Namespace', () => {
150
150
  it.todo('should disableAutoInjection');
151
151
  it.todo('should check if confirmRemove');
152
152
 
153
+ describe('move action availability', () => {
154
+ const SteveModelProto = Object.getPrototypeOf(Namespace.prototype);
155
+
156
+ const makeNamespace = ({ canUpdate }: { canUpdate: boolean }) => {
157
+ const namespace = new Namespace({});
158
+
159
+ jest.spyOn(namespace, '$rootGetters', 'get').mockReturnValue({
160
+ isRancher: true,
161
+ isSingleProduct: false,
162
+ 'i18n/t': (key: string) => key,
163
+ });
164
+ Object.defineProperty(namespace, 'istioInstalled', { get: () => false, configurable: true });
165
+ Object.defineProperty(namespace, 'canUpdate', { get: () => canUpdate, configurable: true });
166
+ jest.spyOn(SteveModelProto, '_availableActions', 'get').mockReturnValue([]);
167
+
168
+ return namespace;
169
+ };
170
+
171
+ it('should include the move action when user can update the namespace', () => {
172
+ const namespace = makeNamespace({ canUpdate: true });
173
+
174
+ const moveAction = namespace.availableActions.find((a: any) => a.action === 'move');
175
+
176
+ expect(moveAction).toBeDefined();
177
+ expect(moveAction.enabled).toBe(true);
178
+ });
179
+
180
+ it('should exclude the move action when user cannot update the namespace', () => {
181
+ const namespace = makeNamespace({ canUpdate: false });
182
+
183
+ const moveAction = namespace.availableActions.find((a: any) => a.action === 'move');
184
+
185
+ expect(moveAction).toBeUndefined();
186
+ });
187
+ });
188
+
153
189
  describe('handling listLocation', () => {
154
190
  it.each([
155
191
  ['c-cluster-product-projectsnamespaces', true],
@@ -1,29 +1,39 @@
1
1
  import ProvCluster from '@shell/models/provisioning.cattle.io.cluster';
2
+ import MgmtCluster from '@shell/models/management.cattle.io.cluster';
3
+
2
4
  jest.mock('@shell/utils/provider', () => ({
3
5
  isHostedProvider: jest.fn().mockImplementation((context, provider) => {
4
6
  return ['GKE', 'EKS', 'AKS'].includes(provider);
7
+ }),
8
+ isCAPIProvider: jest.fn().mockImplementation((context, provider) => {
9
+ return ['capa', 'capv'].includes(provider.toLowerCase());
5
10
  })
6
11
  }));
12
+
13
+ jest.mock('@shell/utils/clipboard', () => {
14
+ return { copyTextToClipboard: jest.fn(() => Promise.resolve({})) };
15
+ });
16
+
7
17
  describe('class ProvCluster', () => {
8
18
  const gkeClusterWithPrivateEndpoint = {
9
19
  clusterName: 'test',
10
20
  provisioner: 'GKE',
11
21
  spec: { },
12
- mgmt: { spec: { gkeConfig: { privateClusterConfig: { enablePrivateEndpoint: true } } } }
22
+ mgmt: new MgmtCluster({ spec: { gkeConfig: { privateClusterConfig: { enablePrivateEndpoint: true } } } }),
13
23
  };
14
24
 
15
25
  const eksClusterWithPrivateEndpoint = {
16
26
  clusterName: 'test',
17
27
  provisioner: 'EKS',
18
28
  spec: { },
19
- mgmt: { spec: { eksConfig: { privateAccess: true } } }
29
+ mgmt: new MgmtCluster({ spec: { eksConfig: { privateAccess: true } } }),
20
30
  };
21
31
 
22
32
  const aksClusterWithPrivateEndpoint = {
23
33
  clusterName: 'test',
24
34
  provisioner: 'AKS',
25
35
  spec: { },
26
- mgmt: { spec: { aksConfig: { privateCluster: true } } }
36
+ mgmt: new MgmtCluster({ spec: { aksConfig: { privateCluster: true } } }),
27
37
  };
28
38
 
29
39
  // Related to https://github.com/rancher/dashboard/issues/9402
@@ -41,10 +51,14 @@ describe('class ProvCluster', () => {
41
51
  it.each(testCases)('should return the isHostedKubernetesProvider and isPrivateHostedProvider values properly based on the props data', (clusterData: Object, expected: Boolean) => {
42
52
  const cluster = new ProvCluster({ spec: clusterData.spec });
43
53
 
54
+ jest.spyOn(clusterData.mgmt, 'provCluster', 'get').mockReturnValue(
55
+ clusterData
56
+ );
57
+
44
58
  jest.spyOn(cluster, 'mgmt', 'get').mockReturnValue(
45
59
  clusterData.mgmt
46
60
  );
47
- jest.spyOn(cluster, 'provisioner', 'get').mockReturnValue(
61
+ jest.spyOn(clusterData.mgmt, 'provisioner', 'get').mockReturnValue(
48
62
  clusterData.provisioner
49
63
  );
50
64
 
@@ -54,6 +68,7 @@ describe('class ProvCluster', () => {
54
68
  resetMocks();
55
69
  });
56
70
  });
71
+
57
72
  describe('isImported', () => {
58
73
  const testCases = [
59
74
  {
@@ -114,7 +129,8 @@ describe('class ProvCluster', () => {
114
129
  clusterData: {
115
130
  isLocal: false,
116
131
  isHostedKubernetesProvider: true,
117
- providerConfig: { imported: true }
132
+ providerConfig: { imported: true },
133
+ mgmt: { status: { provider: '', driver: 'EKS' } }
118
134
  },
119
135
  expected: true
120
136
  },
@@ -123,7 +139,8 @@ describe('class ProvCluster', () => {
123
139
  clusterData: {
124
140
  isLocal: false,
125
141
  isHostedKubernetesProvider: true,
126
- providerConfig: { imported: false }
142
+ providerConfig: { imported: false },
143
+ mgmt: { status: { provider: '', driver: 'EKS' } }
127
144
  },
128
145
  expected: false
129
146
  },
@@ -150,23 +167,27 @@ describe('class ProvCluster', () => {
150
167
  };
151
168
 
152
169
  it.each(testCases)('$description', ({ clusterData, expected }) => {
170
+ const mgmtCluster = new MgmtCluster(clusterData.mgmt || {});
153
171
  const cluster = new ProvCluster({});
154
172
 
155
173
  // Mock getters
156
174
  jest.spyOn(cluster, 'mgmt', 'get').mockReturnValue(
157
- clusterData.mgmt
175
+ mgmtCluster
176
+ );
177
+ jest.spyOn(mgmtCluster, 'provCluster', 'get').mockReturnValue(
178
+ cluster
158
179
  );
159
180
  if (clusterData.isLocal !== undefined) {
160
- jest.spyOn(cluster, 'isLocal', 'get').mockReturnValue(clusterData.isLocal);
181
+ jest.spyOn(mgmtCluster, 'isLocal', 'get').mockReturnValue(clusterData.isLocal);
161
182
  }
162
183
  if (clusterData.isHostedKubernetesProvider !== undefined) {
163
- jest.spyOn(cluster, 'isHostedKubernetesProvider', 'get').mockReturnValue(clusterData.isHostedKubernetesProvider);
184
+ jest.spyOn(mgmtCluster, 'isHostedKubernetesProvider', 'get').mockReturnValue(clusterData.isHostedKubernetesProvider);
164
185
  }
165
186
  if (clusterData.providerConfig !== undefined) {
166
187
  jest.spyOn(cluster, 'providerConfig', 'get').mockReturnValue(clusterData.providerConfig);
167
188
  }
168
189
  if (clusterData.provisioner !== undefined) {
169
- jest.spyOn(cluster, 'provisioner', 'get').mockReturnValue(clusterData.provisioner);
190
+ jest.spyOn(mgmtCluster, 'provisioner', 'get').mockReturnValue(clusterData.provisioner);
170
191
  }
171
192
 
172
193
  expect(cluster.isImported).toBe(expected);
@@ -268,7 +289,10 @@ describe('class ProvCluster', () => {
268
289
 
269
290
  it.each(testCases)('should return the hasError value properly based on the "status.conditions" props data for testcase %p', (testName: string, conditions: Array, expected: Boolean) => {
270
291
  const ctx = { rootGetters: { 'management/byId': jest.fn() } };
271
- const cluster = new ProvCluster({ status: { conditions } }, ctx);
292
+ const mgmtCluster = new MgmtCluster({ status: { conditions } }, ctx);
293
+ const cluster = new ProvCluster({}, ctx);
294
+
295
+ jest.spyOn(cluster, 'mgmt', 'get').mockReturnValue(mgmtCluster);
272
296
 
273
297
  expect(cluster.hasError).toBe(expected);
274
298
  resetMocks();
@@ -371,4 +395,50 @@ describe('class ProvCluster', () => {
371
395
  jest.clearAllMocks();
372
396
  });
373
397
  });
398
+
399
+ describe('isCapiWithoutExtension', () => {
400
+ const testCases = [
401
+ {
402
+ description: 'should return undefined when mgmt is undefined',
403
+ isCapiHybrid: undefined,
404
+ isCAPIProvider: undefined,
405
+ expected: undefined,
406
+ },
407
+ {
408
+ description: 'should return false when not a CAPI cluster',
409
+ isCapiHybrid: false,
410
+ isCAPIProvider: false,
411
+ expected: false,
412
+ },
413
+ {
414
+ description: 'should return false when CAPI cluster and a registered CAPI provider extension exists',
415
+ isCapiHybrid: true,
416
+ isCAPIProvider: true,
417
+ expected: false,
418
+ },
419
+ {
420
+ description: 'should return true when CAPI cluster but no registered CAPI provider extension',
421
+ isCapiHybrid: true,
422
+ isCAPIProvider: false,
423
+ expected: true,
424
+ },
425
+ ];
426
+
427
+ it.each(testCases)('$description', ({ isCapiHybrid, isCAPIProvider, expected }) => {
428
+ const cluster = new ProvCluster({});
429
+
430
+ if (isCapiHybrid === undefined) {
431
+ jest.spyOn(cluster, 'mgmt', 'get').mockReturnValue(undefined);
432
+ } else {
433
+ const mgmtCluster = new MgmtCluster({});
434
+
435
+ jest.spyOn(mgmtCluster, 'isCapiHybrid', 'get').mockReturnValue(isCapiHybrid);
436
+ jest.spyOn(mgmtCluster, 'isCAPIProvider', 'get').mockReturnValue(isCAPIProvider);
437
+ jest.spyOn(cluster, 'mgmt', 'get').mockReturnValue(mgmtCluster);
438
+ }
439
+
440
+ expect(cluster.isCapiWithoutExtension).toStrictEqual(expected);
441
+ jest.clearAllMocks();
442
+ });
443
+ });
374
444
  });