@rancher/shell 3.0.7 → 3.0.8-rc.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.
Files changed (375) hide show
  1. package/assets/brand/suse/banner.svg +1 -0
  2. package/assets/brand/suse/dark/banner.svg +1 -0
  3. package/assets/brand/suse/dark/login-landscape.svg +1 -0
  4. package/assets/brand/suse/dark/rancher-logo.svg +1 -1
  5. package/assets/brand/suse/favicon.png +0 -0
  6. package/assets/brand/suse/login-landscape.svg +1 -0
  7. package/assets/brand/suse/metadata.json +11 -1
  8. package/assets/brand/suse/rancher-logo.svg +1 -1
  9. package/assets/fonts/suse/suse-v2-latin-300.woff +0 -0
  10. package/assets/fonts/suse/suse-v2-latin-300.woff2 +0 -0
  11. package/assets/fonts/suse/suse-v2-latin-600.woff +0 -0
  12. package/assets/fonts/suse/suse-v2-latin-600.woff2 +0 -0
  13. package/assets/fonts/suse/suse-v2-latin-700.woff +0 -0
  14. package/assets/fonts/suse/suse-v2-latin-700.woff2 +0 -0
  15. package/assets/fonts/suse/suse-v2-latin-800.woff +0 -0
  16. package/assets/fonts/suse/suse-v2-latin-800.woff2 +0 -0
  17. package/assets/fonts/suse/suse-v2-latin-regular.woff +0 -0
  18. package/assets/fonts/suse/suse-v2-latin-regular.woff2 +0 -0
  19. package/assets/images/content/README.md +5 -0
  20. package/assets/images/content/cloud-native.svg +84 -0
  21. package/assets/images/content/dark/cloud-native.svg +21 -0
  22. package/assets/images/content/dark/shield.svg +59 -0
  23. package/assets/images/content/dark/suse.svg +10 -0
  24. package/assets/images/content/shield.svg +59 -0
  25. package/assets/images/content/suse.svg +10 -0
  26. package/assets/images/vendor/githubapp.svg +13 -0
  27. package/assets/styles/base/_typography.scss +2 -1
  28. package/assets/styles/fonts/_fontstack.scss +53 -1
  29. package/assets/styles/global/_cards.scss +0 -3
  30. package/assets/styles/global/_layout.scss +21 -35
  31. package/assets/styles/themes/_dark.scss +1 -1
  32. package/assets/styles/themes/_light.scss +1 -1
  33. package/assets/styles/themes/_modern.scss +16 -8
  34. package/assets/styles/themes/_suse.scss +116 -24
  35. package/assets/translations/en-us.yaml +185 -21
  36. package/assets/translations/zh-hans.yaml +0 -4
  37. package/components/AutoscalerCard.vue +113 -0
  38. package/components/AutoscalerTab.vue +94 -0
  39. package/components/BackLink.vue +8 -0
  40. package/components/BannerGraphic.vue +36 -21
  41. package/components/BrandImage.vue +17 -6
  42. package/components/ClusterIconMenu.vue +1 -1
  43. package/components/ClusterProviderIcon.vue +1 -1
  44. package/components/Cron/CronExpressionEditor.vue +1 -1
  45. package/components/Cron/CronExpressionEditorModal.vue +1 -1
  46. package/components/Drawer/Chrome.vue +2 -6
  47. package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +4 -9
  48. package/components/Drawer/ResourceDetailDrawer/YamlTab.vue +3 -8
  49. package/components/Drawer/ResourceDetailDrawer/composables.ts +3 -4
  50. package/components/Drawer/ResourceDetailDrawer/index.vue +4 -9
  51. package/components/Drawer/ResourceDetailDrawer/types.ts +17 -0
  52. package/components/Drawer/types.ts +3 -0
  53. package/components/DynamicContent/DynamicContentBanner.vue +102 -0
  54. package/components/DynamicContent/DynamicContentCloseButton.vue +42 -0
  55. package/components/DynamicContent/DynamicContentIcon.vue +132 -0
  56. package/components/DynamicContent/DynamicContentPanel.vue +112 -0
  57. package/components/DynamicContent/content.ts +78 -0
  58. package/components/EmberPage.vue +1 -1
  59. package/components/IconOrSvg.vue +2 -2
  60. package/components/Inactivity.vue +222 -106
  61. package/components/InstallHelmCharts.vue +2 -2
  62. package/components/PaginatedResourceTable.vue +2 -6
  63. package/components/PopoverCard.vue +192 -0
  64. package/components/Questions/__tests__/index.test.ts +159 -0
  65. package/components/Resource/Detail/CopyToClipboard.vue +4 -1
  66. package/components/Resource/Detail/FetchLoader/composables.ts +18 -4
  67. package/components/Resource/Detail/Metadata/Annotations/index.vue +2 -2
  68. package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/identifying-fields.test.ts +1 -1
  69. package/components/Resource/Detail/Metadata/IdentifyingInformation/identifying-fields.ts +4 -0
  70. package/components/Resource/Detail/Metadata/KeyValueRow.vue +1 -1
  71. package/components/Resource/Detail/Metadata/Labels/index.vue +2 -2
  72. package/components/Resource/Detail/Metadata/composables.ts +9 -9
  73. package/components/Resource/Detail/Metadata/index.vue +3 -3
  74. package/components/Resource/Detail/ResourcePopover/ResourcePopoverCard.vue +2 -19
  75. package/components/Resource/Detail/ResourcePopover/__tests__/ResourcePopoverCard.test.ts +0 -29
  76. package/components/Resource/Detail/ResourcePopover/__tests__/index.test.ts +132 -150
  77. package/components/Resource/Detail/ResourcePopover/index.vue +54 -159
  78. package/components/Resource/Detail/TitleBar/__tests__/index.test.ts +0 -2
  79. package/components/Resource/Detail/TitleBar/composables.ts +2 -1
  80. package/components/Resource/Detail/TitleBar/index.vue +10 -6
  81. package/components/Resource/Detail/composables.ts +12 -0
  82. package/components/ResourceDetail/Masthead/latest.vue +29 -0
  83. package/components/ResourceDetail/index.vue +5 -2
  84. package/components/ResourceList/Masthead.vue +1 -1
  85. package/components/SortableTable/index.vue +18 -2
  86. package/components/Tabbed/__tests__/index.test.ts +86 -0
  87. package/components/{nav/WindowManager → Window}/ContainerLogs.vue +1 -1
  88. package/components/{nav/WindowManager → Window}/ContainerLogsActions.vue +1 -0
  89. package/components/{nav/WindowManager → Window}/__tests__/ContainerLogs.test.ts +1 -1
  90. package/components/{nav/WindowManager → Window}/__tests__/ContainerShell.test.ts +2 -2
  91. package/components/__tests__/AutoscalerCard.test.ts +154 -0
  92. package/components/__tests__/AutoscalerTab.test.ts +125 -0
  93. package/components/__tests__/PopoverCard.test.ts +204 -0
  94. package/components/auth/SelectPrincipal.vue +24 -6
  95. package/components/auth/__tests__/SelectPrincipal.test.ts +119 -0
  96. package/components/fleet/FleetConfigMapSelector.vue +117 -0
  97. package/components/fleet/FleetSecretSelector.vue +127 -0
  98. package/components/fleet/__tests__/FleetConfigMapSelector.test.ts +125 -0
  99. package/components/fleet/__tests__/FleetSecretSelector.test.ts +82 -0
  100. package/components/form/FileImageSelector.vue +13 -4
  101. package/components/form/FileSelector.vue +11 -2
  102. package/components/form/ResourceLabeledSelect.vue +1 -0
  103. package/components/form/__tests__/ResourceLabeledSelect.test.ts +90 -0
  104. package/components/formatter/Autoscaler.vue +97 -0
  105. package/components/formatter/InternalExternalIP.vue +198 -24
  106. package/components/formatter/__tests__/Autoscaler.test.ts +156 -0
  107. package/components/formatter/__tests__/InternalExternalIP.test.ts +133 -0
  108. package/components/google/util/__tests__/formatter.test.ts +47 -0
  109. package/components/google/util/formatter.ts +5 -2
  110. package/components/nav/Group.vue +12 -3
  111. package/components/nav/Header.vue +37 -16
  112. package/components/nav/NamespaceFilter.vue +13 -1
  113. package/components/nav/NotificationCenter/index.vue +2 -1
  114. package/components/nav/TopLevelMenu.helper.ts +16 -6
  115. package/components/nav/TopLevelMenu.vue +4 -2
  116. package/components/{DraggableZone.vue → nav/WindowManager/PinArea.vue} +47 -80
  117. package/components/nav/WindowManager/composables/useComponentsMount.ts +70 -0
  118. package/components/nav/WindowManager/composables/useDimensionsHandler.ts +105 -0
  119. package/components/nav/WindowManager/composables/useDragHandler.ts +99 -0
  120. package/components/nav/WindowManager/composables/usePanelHandler.ts +72 -0
  121. package/components/nav/WindowManager/composables/usePanelsHandler.ts +14 -0
  122. package/components/nav/WindowManager/composables/useResizeHandler.ts +167 -0
  123. package/components/nav/WindowManager/composables/useTabsHandler.ts +51 -0
  124. package/components/nav/WindowManager/constants.ts +23 -0
  125. package/components/nav/WindowManager/index.vue +61 -575
  126. package/components/nav/WindowManager/panels/HorizontalPanel.vue +265 -0
  127. package/components/nav/WindowManager/panels/TabBodyContainer.vue +39 -0
  128. package/components/nav/WindowManager/panels/VerticalPanel.vue +308 -0
  129. package/components/templates/default.vue +4 -40
  130. package/components/templates/home.vue +31 -5
  131. package/components/templates/plain.vue +30 -4
  132. package/components/templates/standalone.vue +1 -1
  133. package/composables/useI18n.ts +10 -1
  134. package/composables/useInterval.ts +15 -0
  135. package/config/__test__/uiplugins.test.ts +309 -0
  136. package/config/labels-annotations.js +9 -1
  137. package/config/product/auth.js +1 -0
  138. package/config/product/explorer.js +3 -1
  139. package/config/product/manager.js +20 -9
  140. package/config/query-params.js +1 -0
  141. package/config/router/routes.js +10 -2
  142. package/config/settings.ts +10 -2
  143. package/config/store.js +4 -2
  144. package/config/table-headers.js +8 -0
  145. package/config/types.js +11 -0
  146. package/config/uiplugins.js +46 -2
  147. package/config/version.js +1 -1
  148. package/core/__test__/extension-manager-impl.test.js +236 -0
  149. package/core/extension-manager-impl.js +23 -6
  150. package/core/plugin-helpers.ts +2 -0
  151. package/core/types-provisioning.ts +4 -1
  152. package/detail/pod.vue +1 -0
  153. package/detail/provisioning.cattle.io.cluster.vue +13 -1
  154. package/dialog/AddonConfigConfirmationDialog.vue +45 -1
  155. package/dialog/DeveloperLoadExtensionDialog.vue +12 -3
  156. package/dialog/RollbackWorkloadDialog.vue +2 -5
  157. package/directives/ui-context.ts +103 -0
  158. package/edit/__tests__/fleet.cattle.io.helmop.test.ts +52 -11
  159. package/edit/auth/AuthProviderWarningBanners.vue +14 -1
  160. package/edit/auth/__tests__/oidc.test.ts +26 -0
  161. package/edit/auth/github-app-steps.vue +97 -0
  162. package/edit/auth/github-steps.vue +75 -0
  163. package/edit/auth/github.vue +99 -65
  164. package/edit/auth/oidc.vue +5 -1
  165. package/edit/autoscaling.horizontalpodautoscaler/index.vue +1 -0
  166. package/edit/cloudcredential.vue +1 -1
  167. package/edit/configmap.vue +1 -0
  168. package/edit/constraints.gatekeeper.sh.constraint/index.vue +1 -0
  169. package/edit/fleet.cattle.io.gitrepo.vue +0 -10
  170. package/edit/fleet.cattle.io.helmop.vue +51 -2
  171. package/edit/helm.cattle.io.projecthelmchart.vue +1 -0
  172. package/edit/k8s.cni.cncf.io.networkattachmentdefinition.vue +1 -0
  173. package/edit/logging-flow/index.vue +1 -0
  174. package/edit/logging.banzaicloud.io.output/index.vue +1 -0
  175. package/edit/management.cattle.io.fleetworkspace.vue +1 -1
  176. package/edit/management.cattle.io.project.vue +1 -0
  177. package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +4 -1
  178. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +2 -1
  179. package/edit/monitoring.coreos.com.prometheusrule/index.vue +1 -0
  180. package/edit/monitoring.coreos.com.receiver/index.vue +2 -1
  181. package/edit/monitoring.coreos.com.route.vue +1 -1
  182. package/edit/namespace.vue +1 -0
  183. package/edit/networking.istio.io.destinationrule/index.vue +1 -0
  184. package/edit/networking.k8s.io.ingress/index.vue +1 -0
  185. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +15 -5
  186. package/edit/networking.k8s.io.networkpolicy/PolicyRules.vue +1 -0
  187. package/edit/networking.k8s.io.networkpolicy/index.vue +1 -0
  188. package/edit/node.vue +1 -0
  189. package/edit/persistentvolume/index.vue +27 -22
  190. package/edit/persistentvolume/plugins/awsElasticBlockStore.vue +13 -14
  191. package/edit/persistentvolume/plugins/azureDisk.vue +49 -48
  192. package/edit/persistentvolume/plugins/azureFile.vue +15 -14
  193. package/edit/persistentvolume/plugins/cephfs.vue +15 -14
  194. package/edit/persistentvolume/plugins/cinder.vue +15 -14
  195. package/edit/persistentvolume/plugins/csi.vue +18 -16
  196. package/edit/persistentvolume/plugins/fc.vue +13 -14
  197. package/edit/persistentvolume/plugins/flexVolume.vue +15 -14
  198. package/edit/persistentvolume/plugins/flocker.vue +1 -3
  199. package/edit/persistentvolume/plugins/gcePersistentDisk.vue +13 -14
  200. package/edit/persistentvolume/plugins/glusterfs.vue +15 -14
  201. package/edit/persistentvolume/plugins/hostPath.vue +40 -39
  202. package/edit/persistentvolume/plugins/iscsi.vue +13 -14
  203. package/edit/persistentvolume/plugins/local.vue +1 -3
  204. package/edit/persistentvolume/plugins/longhorn.vue +23 -22
  205. package/edit/persistentvolume/plugins/nfs.vue +15 -14
  206. package/edit/persistentvolume/plugins/photonPersistentDisk.vue +1 -14
  207. package/edit/persistentvolume/plugins/portworxVolume.vue +15 -14
  208. package/edit/persistentvolume/plugins/quobyte.vue +15 -14
  209. package/edit/persistentvolume/plugins/rbd.vue +15 -14
  210. package/edit/persistentvolume/plugins/scaleIO.vue +15 -14
  211. package/edit/persistentvolume/plugins/storageos.vue +15 -14
  212. package/edit/persistentvolume/plugins/vsphereVolume.vue +1 -3
  213. package/edit/provisioning.cattle.io.cluster/CustomCommand.vue +32 -5
  214. package/edit/provisioning.cattle.io.cluster/__tests__/CustomCommand.test.ts +35 -0
  215. package/edit/provisioning.cattle.io.cluster/__tests__/Networking.test.ts +155 -0
  216. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +11 -9
  217. package/edit/provisioning.cattle.io.cluster/index.vue +25 -15
  218. package/edit/provisioning.cattle.io.cluster/rke2.vue +98 -17
  219. package/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig.vue +28 -2
  220. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +107 -5
  221. package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +92 -4
  222. package/edit/secret/index.vue +1 -1
  223. package/edit/service.vue +9 -4
  224. package/edit/serviceaccount.vue +1 -0
  225. package/edit/storage.k8s.io.storageclass/index.vue +1 -0
  226. package/edit/workload/index.vue +2 -1
  227. package/edit/workload/mixins/workload.js +1 -1
  228. package/initialize/App.vue +4 -4
  229. package/initialize/install-directives.js +2 -0
  230. package/initialize/install-plugins.js +19 -2
  231. package/list/projectsecret.vue +1 -1
  232. package/list/provisioning.cattle.io.cluster.vue +15 -2
  233. package/machine-config/amazonec2.vue +42 -135
  234. package/machine-config/azure.vue +1 -1
  235. package/machine-config/components/EC2Networking.vue +490 -0
  236. package/machine-config/components/__tests__/EC2Networking.test.ts +148 -0
  237. package/machine-config/components/__tests__/utils/vpcSubnetMockData.js +294 -0
  238. package/machine-config/digitalocean.vue +11 -0
  239. package/machine-config/google.vue +1 -1
  240. package/mixins/__tests__/brand.spec.ts +2 -2
  241. package/mixins/__tests__/chart.test.ts +21 -0
  242. package/mixins/brand.js +1 -7
  243. package/mixins/chart.js +8 -2
  244. package/mixins/create-edit-view/index.js +5 -0
  245. package/models/__tests__/chart.test.ts +49 -12
  246. package/models/__tests__/compliance.cattle.io.clusterscanprofile.spec.js +30 -0
  247. package/models/__tests__/provisioning.cattle.io.cluster.test.ts +112 -5
  248. package/models/catalog.cattle.io.app.js +1 -1
  249. package/models/chart.js +28 -14
  250. package/models/cluster/node.js +13 -6
  251. package/models/cluster.x-k8s.io.machine.js +10 -20
  252. package/models/cluster.x-k8s.io.machinedeployment.js +5 -1
  253. package/models/compliance.cattle.io.clusterscanprofile.js +1 -1
  254. package/models/management.cattle.io.authconfig.js +1 -0
  255. package/models/management.cattle.io.cluster.js +21 -3
  256. package/models/management.cattle.io.kontainerdriver.js +1 -0
  257. package/models/provisioning.cattle.io.cluster.js +249 -33
  258. package/package.json +6 -5
  259. package/pages/auth/login.vue +43 -4
  260. package/pages/auth/verify.vue +1 -1
  261. package/pages/c/_cluster/apps/charts/AppChartCardSubHeader.vue +3 -2
  262. package/pages/c/_cluster/apps/charts/__tests__/chart.test.ts +135 -0
  263. package/pages/c/_cluster/apps/charts/chart.vue +35 -17
  264. package/pages/c/_cluster/apps/charts/index.vue +11 -13
  265. package/pages/c/_cluster/apps/charts/install.vue +1 -1
  266. package/pages/c/_cluster/explorer/EventsTable.vue +89 -3
  267. package/pages/c/_cluster/explorer/index.vue +8 -6
  268. package/pages/c/_cluster/explorer/tools/index.vue +3 -3
  269. package/pages/c/_cluster/manager/hostedprovider/index.vue +220 -0
  270. package/pages/c/_cluster/settings/brand.vue +1 -1
  271. package/pages/c/_cluster/settings/performance.vue +12 -25
  272. package/pages/c/_cluster/uiplugins/__tests__/index.test.ts +7 -0
  273. package/pages/c/_cluster/uiplugins/catalogs.vue +147 -0
  274. package/pages/c/_cluster/uiplugins/index.vue +126 -184
  275. package/pages/home.vue +327 -16
  276. package/pkg/dynamic-importer.lib.js +4 -0
  277. package/plugins/axios.js +2 -1
  278. package/plugins/dashboard-client-init.js +3 -0
  279. package/plugins/dashboard-store/actions.js +1 -1
  280. package/plugins/dashboard-store/getters.js +18 -1
  281. package/plugins/dashboard-store/resource-class.js +21 -6
  282. package/plugins/dynamic-content.js +13 -0
  283. package/plugins/i18n.js +8 -0
  284. package/plugins/steve/__tests__/steve-pagination-utils.test.ts +333 -0
  285. package/plugins/steve/steve-pagination-utils.ts +41 -22
  286. package/plugins/steve/subscribe.js +17 -9
  287. package/plugins/subscribe-events.ts +4 -2
  288. package/rancher-components/Form/Checkbox/Checkbox.vue +1 -1
  289. package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.vue +6 -34
  290. package/rancher-components/Pill/RcStatusBadge/index.ts +0 -1
  291. package/rancher-components/Pill/RcStatusBadge/types.ts +1 -1
  292. package/rancher-components/Pill/RcStatusIndicator/RcStatusIndicator.vue +5 -28
  293. package/rancher-components/Pill/RcStatusIndicator/types.ts +2 -1
  294. package/rancher-components/Pill/types.ts +0 -1
  295. package/rancher-components/RcDropdown/RcDropdownItem.vue +1 -0
  296. package/rancher-components/RcDropdown/RcDropdownItemSelect.vue +5 -1
  297. package/rancher-components/RcIcon/RcIcon.test.ts +51 -0
  298. package/rancher-components/RcIcon/RcIcon.vue +46 -0
  299. package/rancher-components/RcIcon/index.ts +1 -0
  300. package/rancher-components/RcIcon/types.ts +160 -0
  301. package/rancher-components/utils/status.test.ts +67 -0
  302. package/rancher-components/utils/status.ts +77 -0
  303. package/scripts/extension/publish +1 -1
  304. package/scripts/typegen.sh +1 -0
  305. package/store/action-menu.js +8 -0
  306. package/store/auth.js +11 -6
  307. package/store/aws.js +8 -6
  308. package/store/catalog.js +6 -0
  309. package/store/features.js +2 -0
  310. package/store/index.js +45 -20
  311. package/store/notifications.ts +51 -4
  312. package/store/plugins.js +7 -3
  313. package/store/prefs.js +12 -6
  314. package/store/type-map.js +3 -3
  315. package/store/ui-context.ts +86 -0
  316. package/store/wm.ts +244 -0
  317. package/types/kube/kube-api.ts +2 -1
  318. package/types/notifications/index.ts +27 -3
  319. package/types/rancher/index.d.ts +1 -0
  320. package/types/resources/settings.d.ts +29 -7
  321. package/types/shell/index.d.ts +138 -4
  322. package/types/store/__tests__/pagination.types.spec.ts +137 -0
  323. package/types/store/pagination.types.ts +157 -9
  324. package/types/store/subscribe-events.types.ts +8 -1
  325. package/types/store/subscribe.types.ts +1 -0
  326. package/types/window-manager.ts +24 -0
  327. package/utils/__tests__/cluster.test.ts +379 -1
  328. package/utils/__tests__/object.test.ts +19 -0
  329. package/utils/__tests__/provider.test.ts +98 -0
  330. package/utils/__tests__/selector-typed.test.ts +263 -0
  331. package/utils/__tests__/version.test.ts +19 -1
  332. package/utils/autoscaler-utils.ts +7 -0
  333. package/utils/back-off.ts +3 -3
  334. package/utils/brand.ts +29 -0
  335. package/utils/chart.js +18 -0
  336. package/utils/cluster.js +157 -3
  337. package/utils/color.js +1 -1
  338. package/utils/dynamic-content/__tests__/announcement.test.ts +498 -0
  339. package/utils/dynamic-content/__tests__/config.test.ts +187 -0
  340. package/utils/dynamic-content/__tests__/index.test.ts +390 -0
  341. package/utils/dynamic-content/__tests__/info.test.ts +275 -0
  342. package/utils/dynamic-content/__tests__/new-release.test.ts +216 -0
  343. package/utils/dynamic-content/__tests__/support-notice.test.ts +262 -0
  344. package/utils/dynamic-content/__tests__/util.test.ts +235 -0
  345. package/utils/dynamic-content/announcement.ts +142 -0
  346. package/utils/dynamic-content/config.ts +55 -0
  347. package/utils/dynamic-content/example.json +40 -0
  348. package/utils/dynamic-content/index.ts +277 -0
  349. package/utils/dynamic-content/info.ts +261 -0
  350. package/utils/dynamic-content/new-release.ts +126 -0
  351. package/utils/dynamic-content/notification-handler.ts +48 -0
  352. package/utils/dynamic-content/support-notice.ts +169 -0
  353. package/utils/dynamic-content/types.d.ts +153 -0
  354. package/utils/dynamic-content/util.ts +122 -0
  355. package/utils/dynamic-importer.js +2 -2
  356. package/utils/favicon.js +4 -4
  357. package/utils/inactivity.ts +104 -0
  358. package/utils/object.js +20 -2
  359. package/utils/pagination-utils.ts +19 -4
  360. package/utils/pagination-wrapper.ts +12 -8
  361. package/utils/provider.ts +14 -0
  362. package/utils/release-notes.ts +1 -1
  363. package/utils/scroll.js +7 -0
  364. package/utils/selector-typed.ts +6 -2
  365. package/utils/settings.ts +15 -0
  366. package/utils/validators/machine-pool.ts +13 -3
  367. package/utils/version.js +15 -0
  368. package/assets/images/icons/document.svg +0 -3
  369. package/plugins/nuxt-client-init.js +0 -3
  370. package/store/wm.js +0 -95
  371. /package/components/{nav/WindowManager → Window}/ChartReadme.vue +0 -0
  372. /package/components/{nav/WindowManager → Window}/ContainerShell.vue +0 -0
  373. /package/components/{nav/WindowManager → Window}/KubectlShell.vue +0 -0
  374. /package/components/{nav/WindowManager → Window}/MachineSsh.vue +0 -0
  375. /package/components/{nav/WindowManager → Window}/Window.vue +0 -0
@@ -0,0 +1,263 @@
1
+ import { labelSelectorToSelector } from '@shell/utils/selector-typed';
2
+ import { KubeLabelSelector } from '@shell/types/kube/kube-api';
3
+
4
+ describe('selector-typed', () => {
5
+ describe('labelSelectorToSelector', () => {
6
+ describe('empty label selectors', () => {
7
+ it('should return empty string for undefined label selector', () => {
8
+ const result = labelSelectorToSelector(undefined);
9
+
10
+ expect(result).toBe('');
11
+ });
12
+
13
+ it('should return empty string for label selector with no matchLabels and no matchExpressions', () => {
14
+ const labelSelector: KubeLabelSelector = {};
15
+ const result = labelSelectorToSelector(labelSelector);
16
+
17
+ expect(result).toBe('');
18
+ });
19
+
20
+ it('should return empty string for label selector with empty matchLabels', () => {
21
+ const labelSelector: KubeLabelSelector = { matchLabels: {} };
22
+ const result = labelSelectorToSelector(labelSelector);
23
+
24
+ expect(result).toBe('');
25
+ });
26
+
27
+ it('should return empty string for label selector with empty matchExpressions', () => {
28
+ const labelSelector: KubeLabelSelector = { matchExpressions: [] };
29
+ const result = labelSelectorToSelector(labelSelector);
30
+
31
+ expect(result).toBe('');
32
+ });
33
+
34
+ it('should return empty string for label selector with both empty matchLabels and matchExpressions', () => {
35
+ const labelSelector: KubeLabelSelector = {
36
+ matchLabels: {},
37
+ matchExpressions: []
38
+ };
39
+ const result = labelSelectorToSelector(labelSelector);
40
+
41
+ expect(result).toBe('');
42
+ });
43
+ });
44
+
45
+ describe('matchLabels conversion', () => {
46
+ it('should convert single matchLabel to selector string', () => {
47
+ const labelSelector: KubeLabelSelector = { matchLabels: { app: 'nginx' } };
48
+ const result = labelSelectorToSelector(labelSelector);
49
+
50
+ expect(result).toBe('app=nginx');
51
+ });
52
+
53
+ it('should convert multiple matchLabels to comma-separated selector string', () => {
54
+ const labelSelector: KubeLabelSelector = {
55
+ matchLabels: {
56
+ app: 'nginx',
57
+ version: 'v1.0',
58
+ env: 'production'
59
+ }
60
+ };
61
+ const result = labelSelectorToSelector(labelSelector);
62
+
63
+ expect(result).toBe('app=nginx,version=v1.0,env=production');
64
+ });
65
+
66
+ it('should handle matchLabels with special characters', () => {
67
+ const labelSelector: KubeLabelSelector = { matchLabels: { 'app.kubernetes.io/name': 'my-app' } };
68
+ const result = labelSelectorToSelector(labelSelector);
69
+
70
+ expect(result).toBe('app.kubernetes.io/name=my-app');
71
+ });
72
+
73
+ it('should handle matchLabels with numeric values', () => {
74
+ const labelSelector: KubeLabelSelector = { matchLabels: { tier: '3' } };
75
+ const result = labelSelectorToSelector(labelSelector);
76
+
77
+ expect(result).toBe('tier=3');
78
+ });
79
+ });
80
+
81
+ describe('matchExpressions conversion with In operator', () => {
82
+ it('should convert matchExpression with In operator and single value to equality selector', () => {
83
+ const labelSelector: KubeLabelSelector = {
84
+ matchExpressions: [
85
+ {
86
+ key: 'app',
87
+ operator: 'In',
88
+ values: ['nginx']
89
+ }
90
+ ]
91
+ };
92
+ const result = labelSelectorToSelector(labelSelector);
93
+
94
+ expect(result).toBe('app=nginx');
95
+ });
96
+
97
+ it('should convert matchExpression with In operator and multiple values to in() selector', () => {
98
+ const labelSelector: KubeLabelSelector = {
99
+ matchExpressions: [
100
+ {
101
+ key: 'env',
102
+ operator: 'In',
103
+ values: ['dev', 'staging', 'prod']
104
+ }
105
+ ]
106
+ };
107
+ const result = labelSelectorToSelector(labelSelector);
108
+
109
+ expect(result).toBe('env in (dev,staging,prod)');
110
+ });
111
+
112
+ it('should convert multiple matchExpressions with In operator', () => {
113
+ const labelSelector: KubeLabelSelector = {
114
+ matchExpressions: [
115
+ {
116
+ key: 'app',
117
+ operator: 'In',
118
+ values: ['nginx']
119
+ },
120
+ {
121
+ key: 'env',
122
+ operator: 'In',
123
+ values: ['dev', 'staging']
124
+ }
125
+ ]
126
+ };
127
+ const result = labelSelectorToSelector(labelSelector);
128
+
129
+ expect(result).toBe('app=nginx,env in (dev,staging)');
130
+ });
131
+
132
+ it('should handle matchExpression with empty values array for In operator', () => {
133
+ const labelSelector: KubeLabelSelector = {
134
+ matchExpressions: [
135
+ {
136
+ key: 'app',
137
+ operator: 'In',
138
+ values: []
139
+ }
140
+ ]
141
+ };
142
+ const result = labelSelectorToSelector(labelSelector);
143
+
144
+ // With empty values array, it should create an in() with no values
145
+ expect(result).toBe('app in ()');
146
+ });
147
+ });
148
+
149
+ describe('combined matchLabels and matchExpressions', () => {
150
+ it('should combine matchLabels and matchExpressions with single values', () => {
151
+ const labelSelector: KubeLabelSelector = {
152
+ matchLabels: { tier: 'frontend' },
153
+ matchExpressions: [
154
+ {
155
+ key: 'env',
156
+ operator: 'In',
157
+ values: ['prod']
158
+ }
159
+ ]
160
+ };
161
+ const result = labelSelectorToSelector(labelSelector);
162
+
163
+ expect(result).toBe('tier=frontend,env=prod');
164
+ });
165
+
166
+ it('should combine multiple matchLabels and matchExpressions', () => {
167
+ const labelSelector: KubeLabelSelector = {
168
+ matchLabels: {
169
+ tier: 'frontend',
170
+ version: 'v2'
171
+ },
172
+ matchExpressions: [
173
+ {
174
+ key: 'env',
175
+ operator: 'In',
176
+ values: ['dev', 'staging']
177
+ },
178
+ {
179
+ key: 'region',
180
+ operator: 'In',
181
+ values: ['us-west-1']
182
+ }
183
+ ]
184
+ };
185
+ const result = labelSelectorToSelector(labelSelector);
186
+
187
+ expect(result).toBe('tier=frontend,version=v2,env in (dev,staging),region=us-west-1');
188
+ });
189
+
190
+ it('should combine matchLabels with multiple matchExpressions using in() notation', () => {
191
+ const labelSelector: KubeLabelSelector = {
192
+ matchLabels: { 'app.kubernetes.io/name': 'myapp' },
193
+ matchExpressions: [
194
+ {
195
+ key: 'env',
196
+ operator: 'In',
197
+ values: ['dev', 'test', 'prod']
198
+ }
199
+ ]
200
+ };
201
+ const result = labelSelectorToSelector(labelSelector);
202
+
203
+ expect(result).toBe('app.kubernetes.io/name=myapp,env in (dev,test,prod)');
204
+ });
205
+ });
206
+
207
+ describe('unsupported operators', () => {
208
+ it('should throw error for NotIn operator', () => {
209
+ const labelSelector: KubeLabelSelector = {
210
+ matchExpressions: [
211
+ {
212
+ key: 'env',
213
+ operator: 'NotIn',
214
+ values: ['prod']
215
+ }
216
+ ]
217
+ };
218
+
219
+ expect(() => labelSelectorToSelector(labelSelector)).toThrow('Unsupported matchExpression found when converting to selector string.');
220
+ });
221
+ });
222
+
223
+ describe('edge cases', () => {
224
+ it('should handle matchExpression with In operator but undefined values', () => {
225
+ const labelSelector: KubeLabelSelector = {
226
+ matchExpressions: [
227
+ {
228
+ key: 'app',
229
+ operator: 'In',
230
+ values: undefined
231
+ }
232
+ ]
233
+ };
234
+
235
+ // When values is undefined, the function throws an error
236
+ expect(() => labelSelectorToSelector(labelSelector)).toThrow('Unsupported matchExpression found when converting to selector string.');
237
+ });
238
+
239
+ it('should preserve order of matchLabels and matchExpressions', () => {
240
+ const labelSelector: KubeLabelSelector = {
241
+ matchLabels: {
242
+ first: 'value1',
243
+ second: 'value2'
244
+ },
245
+ matchExpressions: [
246
+ {
247
+ key: 'third',
248
+ operator: 'In',
249
+ values: ['value3']
250
+ }
251
+ ]
252
+ };
253
+ const result = labelSelectorToSelector(labelSelector);
254
+
255
+ // matchLabels come before matchExpressions
256
+ expect(result).toContain('first=value1');
257
+ expect(result).toContain('second=value2');
258
+ expect(result).toContain('third=value3');
259
+ expect(result.indexOf('first')).toBeLessThan(result.indexOf('third'));
260
+ });
261
+ });
262
+ });
263
+ });
@@ -1,4 +1,4 @@
1
- import { isDevBuild } from '@shell/utils/version';
1
+ import { isDevBuild, isUpgradeFromPreToStable } from '@shell/utils/version';
2
2
 
3
3
  describe('fx: isDevBuild', () => {
4
4
  it.each([
@@ -16,3 +16,21 @@ describe('fx: isDevBuild', () => {
16
16
  }
17
17
  );
18
18
  });
19
+
20
+ describe('fx: isUpgradeFromPreToStable', () => {
21
+ it('should be true when going from pre-release to stable of same version', () => {
22
+ expect(isUpgradeFromPreToStable('1.0.0-rc1', '1.0.0')).toBe(true);
23
+ });
24
+
25
+ it('should be false when going from stable to pre-release', () => {
26
+ expect(isUpgradeFromPreToStable('1.0.0', '1.0.0-rc1')).toBe(false );
27
+ });
28
+
29
+ it('should be false for stable to stable', () => {
30
+ expect(isUpgradeFromPreToStable('1.0.0', '1.1.0')).toBe(false);
31
+ });
32
+
33
+ it('should be false for pre-release to pre-release', () => {
34
+ expect(isUpgradeFromPreToStable('1.0.0-rc1', '1.0.0-rc2')).toBe(false);
35
+ });
36
+ });
@@ -0,0 +1,7 @@
1
+ import { AUTOSCALER } from '@shell/store/features';
2
+
3
+ export function isAutoscalerFeatureFlagEnabled(store: any): boolean {
4
+ const rootGetters = store.rootGetters || store.getters;
5
+
6
+ return rootGetters['features/get'](AUTOSCALER);
7
+ }
package/utils/back-off.ts CHANGED
@@ -137,9 +137,9 @@ class BackOff {
137
137
 
138
138
  // First step is immediate (0.001s)
139
139
  // Second and others are exponential
140
- // 1, 2, 3, 4, 5, 6, 7, 8, 9
141
- // 1, 4, 9, 16, 25, 36, 49, 64, 81
142
- // 0.25s, 1s, 2.25s, 4s, 6.25s, 9s, 12.25s, 16s, 20.25s
140
+ // Try: 1, 2, 3, 4, 5, 6, 7, 8, 9
141
+ // Multiple: 1, 4, 9, 16, 25, 36, 49, 64, 81
142
+ // Actual Time: 0.25s, 1s, 2.25s, 4s, 6.25s, 9s, 12.25s, 16s, 20.25s
143
143
  const delay = backOffTry === 0 ? 1 : Math.pow(backOffTry, 2) * 250;
144
144
 
145
145
  this.log('info', id, `Delaying call (attempt ${ backOffTry + 1 }, delayed by ${ delay }ms)`, description);
package/utils/brand.ts ADDED
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Brand/Theme metadata
3
+ */
4
+ export interface BrandMeta {
5
+ // Does the banner have a stylesheet?
6
+ hasStylesheet?: string;
7
+ banner?: {
8
+ // Text alignment for the banner text overlayed on the banner image
9
+ textAlign?: string;
10
+ }
11
+ }
12
+
13
+ /**
14
+ * Get the brand/theme meta information for the specified brand
15
+ *
16
+ * @param brand - The brand identifier
17
+ * @returns Brand meta information or empty object if none available
18
+ */
19
+ export function getBrandMeta(brand: string): BrandMeta {
20
+ let brandMeta: BrandMeta = {};
21
+
22
+ if (brand) {
23
+ try {
24
+ brandMeta = require(`~shell/assets/brand/${ brand }/metadata.json`);
25
+ } catch {}
26
+ }
27
+
28
+ return brandMeta;
29
+ }
package/utils/chart.js ADDED
@@ -0,0 +1,18 @@
1
+ import { compatibleVersionsFor } from '@shell/store/catalog';
2
+
3
+ /**
4
+ * Get the latest chart version that is compatible with the cluster's OS and user's pre-release preference.
5
+ * @param {Object} chart - The chart object.
6
+ * @param {Array<string>} workerOSs - The list of worker OSs for the cluster.
7
+ * @param {boolean} showPrerelease - Whether to include pre-release versions.
8
+ * @returns {Object} The latest compatible chart version object.
9
+ */
10
+ export function getLatestCompatibleVersion(chart, workerOSs, showPrerelease) {
11
+ if (!chart?.versions?.length) {
12
+ return {};
13
+ }
14
+
15
+ const compatible = compatibleVersionsFor(chart, workerOSs, showPrerelease);
16
+
17
+ return (compatible.length ? compatible[0] : chart.versions[0]) || {};
18
+ }
package/utils/cluster.js CHANGED
@@ -8,8 +8,8 @@ import { compare, sortable } from '@shell/utils/version';
8
8
  import { sortBy } from '@shell/utils/sort';
9
9
  import { HARVESTER_CONTAINER, SCHEDULING_CUSTOMIZATION } from '@shell/store/features';
10
10
  import { _CREATE, _EDIT } from '@shell/config/query-params';
11
- import isEmpty from 'lodash/isEmpty';
12
- import { set } from '@shell/utils/object';
11
+ import isEmptyLodash from 'lodash/isEmpty';
12
+ import { set, diff, isEmpty, clone } from '@shell/utils/object';
13
13
 
14
14
  /**
15
15
  * Combination of paginationFilterHiddenLocalCluster and paginationFilterOnlyKubernetesClusters
@@ -323,7 +323,7 @@ export async function initSchedulingCustomization(value, features, store, mode)
323
323
  errors.push(e);
324
324
  }
325
325
 
326
- if (schedulingCustomizationFeatureEnabled && mode === _CREATE && isEmpty(value?.clusterAgentDeploymentCustomization?.schedulingCustomization)) {
326
+ if (schedulingCustomizationFeatureEnabled && mode === _CREATE && isEmptyLodash(value?.clusterAgentDeploymentCustomization?.schedulingCustomization)) {
327
327
  set(value, 'clusterAgentDeploymentCustomization.schedulingCustomization', { priorityClass: clusterAgentDefaultPC, podDisruptionBudget: clusterAgentDefaultPDB });
328
328
  }
329
329
 
@@ -335,3 +335,157 @@ export async function initSchedulingCustomization(value, features, store, mode)
335
335
  clusterAgentDefaultPC, clusterAgentDefaultPDB, schedulingCustomizationFeatureEnabled, schedulingCustomizationOriginallyEnabled, errors
336
336
  };
337
337
  }
338
+
339
+ /**
340
+ * Recursively filters a `diffs` object to only include differences that are relevant to the user.
341
+ * A difference is considered relevant if the user has provided a custom value for that specific field.
342
+ *
343
+ * @param {object} diffs - The object representing the differences between two chart versions' default values.
344
+ * @param {object} userVals - The object containing the user's custom values.
345
+ * @returns {object} A new object containing only the relevant differences.
346
+ */
347
+ export function _addonConfigPreserveFilter(diffs, userVals) {
348
+ const filtered = {};
349
+
350
+ for (const key of Object.keys(diffs)) {
351
+ const diffVal = diffs[key];
352
+ const userVal = userVals?.[key];
353
+
354
+ const isDiffObject = typeof diffVal === 'object' && diffVal !== null && !Array.isArray(diffVal);
355
+ const isUserObject = typeof userVal === 'object' && userVal !== null && !Array.isArray(userVal);
356
+
357
+ // If both the diff and user value are objects, we need to recurse into them.
358
+ if (isDiffObject && isUserObject) {
359
+ const nestedFiltered = _addonConfigPreserveFilter(diffVal, userVal);
360
+
361
+ if (!isEmpty(nestedFiltered)) {
362
+ filtered[key] = nestedFiltered;
363
+ }
364
+ } else if (userVal !== undefined) {
365
+ // If the user has provided a value for this key, the difference is relevant.
366
+ filtered[key] = diffVal;
367
+ }
368
+ }
369
+
370
+ return filtered;
371
+ }
372
+
373
+ /**
374
+ * Processes a single add-on version change. It fetches the old and new chart information,
375
+ * calculates the differences in default values, and filters them based on user's customizations.
376
+ * If there are no significant differences, it preserves the user's custom values for the new version.
377
+ *
378
+ * @param {object} store The Vuex store.
379
+ * @param {object} userChartValues The user's customized chart values.
380
+ * @param {string} chartName The name of the chart to process.
381
+ * @param {object} oldAddon The addon information from the previous Kubernetes version.
382
+ * @param {object} newAddon The addon information from the new Kubernetes version.
383
+ * @returns {object|null} An object containing the diff and a preserve flag, or null on error.
384
+ */
385
+ async function _addonConfigPreserveProcess(store, userChartValues, chartName, oldAddon, newAddon) {
386
+ if (chartName.includes('none')) {
387
+ return null;
388
+ }
389
+
390
+ try {
391
+ const [oldVersionInfo, newVersionInfo] = await Promise.all([
392
+ store.dispatch('catalog/getVersionInfo', {
393
+ repoType: 'cluster',
394
+ repoName: oldAddon.repo,
395
+ chartName,
396
+ versionName: oldAddon.version,
397
+ }),
398
+ store.dispatch('catalog/getVersionInfo', {
399
+ repoType: 'cluster',
400
+ repoName: newAddon.repo,
401
+ chartName,
402
+ versionName: newAddon.version,
403
+ })
404
+ ]);
405
+
406
+ const oldDefaults = oldVersionInfo.values;
407
+ const newDefaults = newVersionInfo.values;
408
+ const defaultsDifferences = diff(oldDefaults, newDefaults);
409
+
410
+ const userOldValues = userChartValues[`${ chartName }-${ oldAddon.version }`];
411
+
412
+ // We only care about differences in values that the user has actually customized.
413
+ // If the user hasn't touched a value, a change in its default should not be considered a breaking change.
414
+ const defaultsAndUserDifferences = userOldValues ? _addonConfigPreserveFilter(defaultsDifferences, userOldValues) : {};
415
+
416
+ return {
417
+ diff: defaultsAndUserDifferences,
418
+ preserve: isEmpty(defaultsAndUserDifferences)
419
+ };
420
+ } catch (e) {
421
+ console.error(`Failed to get chart version info for diff for chart ${ chartName }`, e); // eslint-disable-line no-console
422
+
423
+ return null;
424
+ }
425
+ }
426
+
427
+ /**
428
+ * @typedef {object} AddonPreserveContext
429
+ * @property {object} addonConfigDiffs - An object that stores the diffs.
430
+ * @property {string[]} addonNames - An array of addon names to check.
431
+ * @property {object} $store - The Vuex store.
432
+ * @property {object} userChartValues - The user's customized chart values.
433
+ *
434
+ * When the Kubernetes version is changed, this method is called to handle the add-on configurations
435
+ * for all enabled addons. It checks if an addon's version has changed and, if so, determines if the
436
+ * user's custom configurations should be preserved for the new version.
437
+ *
438
+ * The goal is to avoid showing a confirmation dialog for changes in default values that the user has not customized.
439
+ *
440
+ * @param {AddonPreserveContext} context The context object from the component.
441
+ * @param {object} oldCharts The charts object from the K8s release object being changed from.
442
+ * @param {object} newCharts The charts object from the K8s release object being changed to.
443
+ */
444
+ export async function addonConfigPreserve(context, oldCharts, newCharts) {
445
+ const {
446
+ addonConfigDiffs,
447
+ addonNames,
448
+ $store,
449
+ userChartValues
450
+ } = context;
451
+
452
+ if (!oldCharts || !newCharts) {
453
+ return;
454
+ }
455
+
456
+ // Clear the diffs object for the new run
457
+ for (const key in addonConfigDiffs) {
458
+ delete addonConfigDiffs[key];
459
+ }
460
+
461
+ // Iterate through the addons that are enabled for the cluster.
462
+ for (const chartName of addonNames) {
463
+ const oldAddon = oldCharts[chartName];
464
+ const newAddon = newCharts[chartName];
465
+
466
+ // If the addon didn't exist in the old K8s version, there's nothing to compare.
467
+ if (!oldAddon) {
468
+ continue;
469
+ }
470
+
471
+ // Check if the add-on version has changed.
472
+ if (newAddon && newAddon.version !== oldAddon.version) {
473
+ const result = await _addonConfigPreserveProcess($store, userChartValues, chartName, oldAddon, newAddon);
474
+
475
+ if (result) {
476
+ addonConfigDiffs[chartName] = result.diff;
477
+
478
+ if (result.preserve) {
479
+ const oldKey = `${ chartName }-${ oldAddon.version }`;
480
+ const newKey = `${ chartName }-${ newAddon.version }`;
481
+
482
+ // If custom values exist for the old version, and none exist for the new version,
483
+ // copy the values to the new key to preserve them.
484
+ if (userChartValues[oldKey] && !userChartValues[newKey]) {
485
+ userChartValues[newKey] = clone(userChartValues[oldKey]);
486
+ }
487
+ }
488
+ }
489
+ }
490
+ }
491
+ }
package/utils/color.js CHANGED
@@ -13,7 +13,7 @@ Primary color classes from _light.scss
13
13
 
14
14
  */
15
15
 
16
- const Color = require('color');
16
+ import Color from 'color';
17
17
 
18
18
  export function createCssVars(color, theme = 'light', name = 'primary') {
19
19
  const contrastOpts = theme === 'light' ? LIGHT_CONTRAST_COLORS : DARK_CONTRAST_COLORS;