@rancher/shell 3.0.8-rc.1 → 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 (323) 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/styles/base/_typography.scss +1 -0
  27. package/assets/styles/fonts/_fontstack.scss +53 -1
  28. package/assets/styles/global/_cards.scss +0 -3
  29. package/assets/styles/global/_layout.scss +21 -35
  30. package/assets/styles/themes/_dark.scss +1 -1
  31. package/assets/styles/themes/_light.scss +1 -1
  32. package/assets/styles/themes/_modern.scss +11 -3
  33. package/assets/styles/themes/_suse.scss +116 -24
  34. package/assets/translations/en-us.yaml +94 -10
  35. package/components/AutoscalerCard.vue +113 -0
  36. package/components/AutoscalerTab.vue +94 -0
  37. package/components/BackLink.vue +8 -0
  38. package/components/BannerGraphic.vue +36 -21
  39. package/components/BrandImage.vue +17 -6
  40. package/components/ClusterIconMenu.vue +1 -1
  41. package/components/ClusterProviderIcon.vue +1 -1
  42. package/components/Cron/CronExpressionEditor.vue +1 -1
  43. package/components/Cron/CronExpressionEditorModal.vue +1 -1
  44. package/components/Drawer/Chrome.vue +2 -6
  45. package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +4 -9
  46. package/components/Drawer/ResourceDetailDrawer/YamlTab.vue +3 -8
  47. package/components/Drawer/ResourceDetailDrawer/composables.ts +3 -4
  48. package/components/Drawer/ResourceDetailDrawer/index.vue +4 -9
  49. package/components/Drawer/ResourceDetailDrawer/types.ts +17 -0
  50. package/components/Drawer/types.ts +3 -0
  51. package/components/DynamicContent/DynamicContentBanner.vue +102 -0
  52. package/components/DynamicContent/DynamicContentCloseButton.vue +42 -0
  53. package/components/DynamicContent/DynamicContentIcon.vue +132 -0
  54. package/components/DynamicContent/DynamicContentPanel.vue +112 -0
  55. package/components/DynamicContent/content.ts +78 -0
  56. package/components/EmberPage.vue +1 -1
  57. package/components/IconOrSvg.vue +2 -2
  58. package/components/PaginatedResourceTable.vue +2 -6
  59. package/components/PopoverCard.vue +192 -0
  60. package/components/Questions/__tests__/index.test.ts +159 -0
  61. package/components/Resource/Detail/CopyToClipboard.vue +4 -1
  62. package/components/Resource/Detail/FetchLoader/composables.ts +18 -4
  63. package/components/Resource/Detail/Metadata/Annotations/index.vue +2 -2
  64. package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/identifying-fields.test.ts +1 -1
  65. package/components/Resource/Detail/Metadata/IdentifyingInformation/identifying-fields.ts +4 -0
  66. package/components/Resource/Detail/Metadata/KeyValueRow.vue +1 -1
  67. package/components/Resource/Detail/Metadata/Labels/index.vue +2 -2
  68. package/components/Resource/Detail/Metadata/composables.ts +9 -9
  69. package/components/Resource/Detail/Metadata/index.vue +3 -3
  70. package/components/Resource/Detail/ResourcePopover/ResourcePopoverCard.vue +2 -19
  71. package/components/Resource/Detail/ResourcePopover/__tests__/ResourcePopoverCard.test.ts +0 -29
  72. package/components/Resource/Detail/ResourcePopover/__tests__/index.test.ts +132 -150
  73. package/components/Resource/Detail/ResourcePopover/index.vue +54 -159
  74. package/components/Resource/Detail/TitleBar/__tests__/index.test.ts +0 -2
  75. package/components/Resource/Detail/TitleBar/composables.ts +2 -1
  76. package/components/Resource/Detail/TitleBar/index.vue +10 -6
  77. package/components/Resource/Detail/composables.ts +12 -0
  78. package/components/ResourceDetail/Masthead/latest.vue +29 -0
  79. package/components/ResourceDetail/index.vue +4 -1
  80. package/components/ResourceList/Masthead.vue +1 -1
  81. package/components/SortableTable/index.vue +1 -0
  82. package/components/Tabbed/__tests__/index.test.ts +86 -0
  83. package/components/{nav/WindowManager → Window}/ContainerLogs.vue +1 -1
  84. package/components/{nav/WindowManager → Window}/ContainerLogsActions.vue +1 -0
  85. package/components/{nav/WindowManager → Window}/__tests__/ContainerLogs.test.ts +1 -1
  86. package/components/{nav/WindowManager → Window}/__tests__/ContainerShell.test.ts +2 -2
  87. package/components/__tests__/AutoscalerCard.test.ts +154 -0
  88. package/components/__tests__/AutoscalerTab.test.ts +125 -0
  89. package/components/__tests__/PopoverCard.test.ts +204 -0
  90. package/components/auth/SelectPrincipal.vue +24 -6
  91. package/components/auth/__tests__/SelectPrincipal.test.ts +119 -0
  92. package/components/formatter/Autoscaler.vue +97 -0
  93. package/components/formatter/InternalExternalIP.vue +198 -24
  94. package/components/formatter/__tests__/Autoscaler.test.ts +156 -0
  95. package/components/formatter/__tests__/InternalExternalIP.test.ts +133 -0
  96. package/components/google/util/__tests__/formatter.test.ts +47 -0
  97. package/components/google/util/formatter.ts +5 -2
  98. package/components/nav/Group.vue +12 -3
  99. package/components/nav/Header.vue +36 -16
  100. package/components/nav/NamespaceFilter.vue +13 -1
  101. package/components/nav/NotificationCenter/index.vue +2 -1
  102. package/components/nav/TopLevelMenu.helper.ts +16 -6
  103. package/components/nav/TopLevelMenu.vue +4 -2
  104. package/components/{DraggableZone.vue → nav/WindowManager/PinArea.vue} +47 -80
  105. package/components/nav/WindowManager/composables/useComponentsMount.ts +70 -0
  106. package/components/nav/WindowManager/composables/useDimensionsHandler.ts +105 -0
  107. package/components/nav/WindowManager/composables/useDragHandler.ts +99 -0
  108. package/components/nav/WindowManager/composables/usePanelHandler.ts +72 -0
  109. package/components/nav/WindowManager/composables/usePanelsHandler.ts +14 -0
  110. package/components/nav/WindowManager/composables/useResizeHandler.ts +167 -0
  111. package/components/nav/WindowManager/composables/useTabsHandler.ts +51 -0
  112. package/components/nav/WindowManager/constants.ts +23 -0
  113. package/components/nav/WindowManager/index.vue +61 -575
  114. package/components/nav/WindowManager/panels/HorizontalPanel.vue +265 -0
  115. package/components/nav/WindowManager/panels/TabBodyContainer.vue +39 -0
  116. package/components/nav/WindowManager/panels/VerticalPanel.vue +308 -0
  117. package/components/templates/default.vue +4 -40
  118. package/components/templates/home.vue +31 -5
  119. package/components/templates/plain.vue +30 -4
  120. package/components/templates/standalone.vue +1 -1
  121. package/composables/useI18n.ts +10 -1
  122. package/composables/useInterval.ts +15 -0
  123. package/config/__test__/uiplugins.test.ts +309 -0
  124. package/config/labels-annotations.js +9 -1
  125. package/config/product/explorer.js +3 -1
  126. package/config/product/manager.js +20 -9
  127. package/config/router/routes.js +10 -2
  128. package/config/settings.ts +2 -1
  129. package/config/store.js +4 -2
  130. package/config/table-headers.js +8 -0
  131. package/config/types.js +9 -0
  132. package/config/uiplugins.js +46 -2
  133. package/config/version.js +1 -1
  134. package/core/__test__/extension-manager-impl.test.js +236 -0
  135. package/core/extension-manager-impl.js +23 -6
  136. package/core/plugin-helpers.ts +2 -0
  137. package/core/types-provisioning.ts +4 -1
  138. package/detail/pod.vue +1 -0
  139. package/detail/provisioning.cattle.io.cluster.vue +13 -1
  140. package/dialog/DeveloperLoadExtensionDialog.vue +12 -3
  141. package/dialog/RollbackWorkloadDialog.vue +2 -5
  142. package/directives/ui-context.ts +103 -0
  143. package/edit/__tests__/fleet.cattle.io.helmop.test.ts +2 -2
  144. package/edit/auth/__tests__/oidc.test.ts +26 -0
  145. package/edit/auth/github.vue +5 -0
  146. package/edit/auth/oidc.vue +5 -1
  147. package/edit/autoscaling.horizontalpodautoscaler/index.vue +1 -0
  148. package/edit/cloudcredential.vue +1 -1
  149. package/edit/configmap.vue +1 -0
  150. package/edit/constraints.gatekeeper.sh.constraint/index.vue +1 -0
  151. package/edit/fleet.cattle.io.gitrepo.vue +0 -10
  152. package/edit/fleet.cattle.io.helmop.vue +6 -6
  153. package/edit/helm.cattle.io.projecthelmchart.vue +1 -0
  154. package/edit/k8s.cni.cncf.io.networkattachmentdefinition.vue +1 -0
  155. package/edit/logging-flow/index.vue +1 -0
  156. package/edit/logging.banzaicloud.io.output/index.vue +1 -0
  157. package/edit/management.cattle.io.fleetworkspace.vue +1 -1
  158. package/edit/management.cattle.io.project.vue +1 -0
  159. package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +4 -1
  160. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +2 -1
  161. package/edit/monitoring.coreos.com.prometheusrule/index.vue +1 -0
  162. package/edit/monitoring.coreos.com.receiver/index.vue +2 -1
  163. package/edit/monitoring.coreos.com.route.vue +1 -1
  164. package/edit/namespace.vue +1 -0
  165. package/edit/networking.istio.io.destinationrule/index.vue +1 -0
  166. package/edit/networking.k8s.io.ingress/index.vue +1 -0
  167. package/edit/networking.k8s.io.networkpolicy/PolicyRules.vue +1 -0
  168. package/edit/networking.k8s.io.networkpolicy/index.vue +1 -0
  169. package/edit/node.vue +1 -0
  170. package/edit/persistentvolume/index.vue +27 -22
  171. package/edit/persistentvolume/plugins/awsElasticBlockStore.vue +13 -14
  172. package/edit/persistentvolume/plugins/azureDisk.vue +49 -48
  173. package/edit/persistentvolume/plugins/azureFile.vue +15 -14
  174. package/edit/persistentvolume/plugins/cephfs.vue +15 -14
  175. package/edit/persistentvolume/plugins/cinder.vue +15 -14
  176. package/edit/persistentvolume/plugins/csi.vue +18 -16
  177. package/edit/persistentvolume/plugins/fc.vue +13 -14
  178. package/edit/persistentvolume/plugins/flexVolume.vue +15 -14
  179. package/edit/persistentvolume/plugins/flocker.vue +1 -3
  180. package/edit/persistentvolume/plugins/gcePersistentDisk.vue +13 -14
  181. package/edit/persistentvolume/plugins/glusterfs.vue +15 -14
  182. package/edit/persistentvolume/plugins/hostPath.vue +40 -39
  183. package/edit/persistentvolume/plugins/iscsi.vue +13 -14
  184. package/edit/persistentvolume/plugins/local.vue +1 -3
  185. package/edit/persistentvolume/plugins/longhorn.vue +23 -22
  186. package/edit/persistentvolume/plugins/nfs.vue +15 -14
  187. package/edit/persistentvolume/plugins/photonPersistentDisk.vue +1 -14
  188. package/edit/persistentvolume/plugins/portworxVolume.vue +15 -14
  189. package/edit/persistentvolume/plugins/quobyte.vue +15 -14
  190. package/edit/persistentvolume/plugins/rbd.vue +15 -14
  191. package/edit/persistentvolume/plugins/scaleIO.vue +15 -14
  192. package/edit/persistentvolume/plugins/storageos.vue +15 -14
  193. package/edit/persistentvolume/plugins/vsphereVolume.vue +1 -3
  194. package/edit/provisioning.cattle.io.cluster/CustomCommand.vue +32 -5
  195. package/edit/provisioning.cattle.io.cluster/__tests__/CustomCommand.test.ts +35 -0
  196. package/edit/provisioning.cattle.io.cluster/__tests__/Networking.test.ts +155 -0
  197. package/edit/provisioning.cattle.io.cluster/index.vue +25 -15
  198. package/edit/provisioning.cattle.io.cluster/rke2.vue +42 -8
  199. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +107 -5
  200. package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +92 -4
  201. package/edit/secret/index.vue +1 -1
  202. package/edit/service.vue +9 -4
  203. package/edit/serviceaccount.vue +1 -0
  204. package/edit/storage.k8s.io.storageclass/index.vue +1 -0
  205. package/edit/workload/index.vue +2 -1
  206. package/edit/workload/mixins/workload.js +1 -1
  207. package/initialize/App.vue +4 -4
  208. package/initialize/install-directives.js +2 -0
  209. package/initialize/install-plugins.js +19 -2
  210. package/list/provisioning.cattle.io.cluster.vue +15 -2
  211. package/machine-config/amazonec2.vue +42 -135
  212. package/machine-config/components/EC2Networking.vue +490 -0
  213. package/machine-config/components/__tests__/EC2Networking.test.ts +148 -0
  214. package/machine-config/components/__tests__/utils/vpcSubnetMockData.js +294 -0
  215. package/machine-config/digitalocean.vue +11 -0
  216. package/machine-config/google.vue +1 -1
  217. package/mixins/__tests__/brand.spec.ts +2 -2
  218. package/mixins/__tests__/chart.test.ts +21 -0
  219. package/mixins/brand.js +1 -7
  220. package/mixins/chart.js +7 -1
  221. package/mixins/create-edit-view/index.js +5 -0
  222. package/models/__tests__/chart.test.ts +33 -4
  223. package/models/__tests__/provisioning.cattle.io.cluster.test.ts +112 -5
  224. package/models/chart.js +25 -13
  225. package/models/cluster/node.js +13 -6
  226. package/models/cluster.x-k8s.io.machine.js +10 -20
  227. package/models/cluster.x-k8s.io.machinedeployment.js +5 -1
  228. package/models/management.cattle.io.cluster.js +21 -3
  229. package/models/management.cattle.io.kontainerdriver.js +1 -0
  230. package/models/provisioning.cattle.io.cluster.js +249 -33
  231. package/package.json +6 -5
  232. package/pages/auth/login.vue +38 -2
  233. package/pages/c/_cluster/apps/charts/__tests__/chart.test.ts +135 -0
  234. package/pages/c/_cluster/apps/charts/chart.vue +33 -15
  235. package/pages/c/_cluster/apps/charts/index.vue +11 -13
  236. package/pages/c/_cluster/apps/charts/install.vue +1 -1
  237. package/pages/c/_cluster/explorer/index.vue +8 -6
  238. package/pages/c/_cluster/manager/hostedprovider/index.vue +220 -0
  239. package/pages/c/_cluster/settings/brand.vue +1 -1
  240. package/pages/c/_cluster/uiplugins/__tests__/index.test.ts +7 -0
  241. package/pages/c/_cluster/uiplugins/catalogs.vue +147 -0
  242. package/pages/c/_cluster/uiplugins/index.vue +126 -184
  243. package/pages/home.vue +14 -4
  244. package/pkg/dynamic-importer.lib.js +4 -0
  245. package/plugins/dashboard-client-init.js +3 -0
  246. package/plugins/dashboard-store/getters.js +18 -1
  247. package/plugins/dashboard-store/resource-class.js +4 -4
  248. package/plugins/dynamic-content.js +13 -0
  249. package/plugins/i18n.js +8 -0
  250. package/plugins/steve/__tests__/steve-pagination-utils.test.ts +333 -0
  251. package/plugins/steve/steve-pagination-utils.ts +39 -20
  252. package/plugins/steve/subscribe.js +17 -9
  253. package/plugins/subscribe-events.ts +4 -2
  254. package/rancher-components/Form/Checkbox/Checkbox.vue +1 -1
  255. package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.vue +6 -34
  256. package/rancher-components/Pill/RcStatusBadge/index.ts +0 -1
  257. package/rancher-components/Pill/RcStatusBadge/types.ts +1 -1
  258. package/rancher-components/Pill/RcStatusIndicator/RcStatusIndicator.vue +5 -28
  259. package/rancher-components/Pill/RcStatusIndicator/types.ts +2 -1
  260. package/rancher-components/Pill/types.ts +0 -1
  261. package/rancher-components/RcDropdown/RcDropdownItem.vue +1 -0
  262. package/rancher-components/RcDropdown/RcDropdownItemSelect.vue +5 -1
  263. package/rancher-components/RcIcon/RcIcon.test.ts +51 -0
  264. package/rancher-components/RcIcon/RcIcon.vue +46 -0
  265. package/rancher-components/RcIcon/index.ts +1 -0
  266. package/rancher-components/RcIcon/types.ts +160 -0
  267. package/rancher-components/utils/status.test.ts +67 -0
  268. package/rancher-components/utils/status.ts +77 -0
  269. package/scripts/typegen.sh +1 -0
  270. package/store/action-menu.js +8 -0
  271. package/store/auth.js +3 -3
  272. package/store/catalog.js +6 -0
  273. package/store/features.js +1 -0
  274. package/store/index.js +36 -17
  275. package/store/notifications.ts +51 -4
  276. package/store/plugins.js +7 -3
  277. package/store/prefs.js +6 -6
  278. package/store/type-map.js +3 -3
  279. package/store/ui-context.ts +86 -0
  280. package/store/wm.ts +244 -0
  281. package/types/notifications/index.ts +27 -3
  282. package/types/shell/index.d.ts +79 -4
  283. package/types/store/__tests__/pagination.types.spec.ts +137 -0
  284. package/types/store/pagination.types.ts +157 -9
  285. package/types/store/subscribe-events.types.ts +8 -1
  286. package/types/store/subscribe.types.ts +1 -0
  287. package/types/window-manager.ts +24 -0
  288. package/utils/__tests__/object.test.ts +19 -0
  289. package/utils/__tests__/provider.test.ts +98 -0
  290. package/utils/__tests__/selector-typed.test.ts +263 -0
  291. package/utils/__tests__/version.test.ts +19 -1
  292. package/utils/autoscaler-utils.ts +7 -0
  293. package/utils/back-off.ts +3 -3
  294. package/utils/brand.ts +29 -0
  295. package/utils/chart.js +18 -0
  296. package/utils/color.js +1 -1
  297. package/utils/dynamic-content/__tests__/announcement.test.ts +498 -0
  298. package/utils/dynamic-content/__tests__/info.test.ts +21 -9
  299. package/utils/dynamic-content/announcement.ts +142 -0
  300. package/utils/dynamic-content/example.json +40 -0
  301. package/utils/dynamic-content/index.ts +6 -2
  302. package/utils/dynamic-content/info.ts +44 -2
  303. package/utils/dynamic-content/new-release.ts +1 -1
  304. package/utils/dynamic-content/notification-handler.ts +48 -0
  305. package/utils/dynamic-content/types.d.ts +53 -1
  306. package/utils/dynamic-importer.js +2 -2
  307. package/utils/favicon.js +4 -4
  308. package/utils/object.js +20 -2
  309. package/utils/pagination-wrapper.ts +12 -8
  310. package/utils/provider.ts +14 -0
  311. package/utils/scroll.js +7 -0
  312. package/utils/selector-typed.ts +6 -2
  313. package/utils/settings.ts +15 -0
  314. package/utils/validators/machine-pool.ts +13 -3
  315. package/utils/version.js +15 -0
  316. package/assets/images/icons/document.svg +0 -3
  317. package/plugins/nuxt-client-init.js +0 -3
  318. package/store/wm.js +0 -95
  319. /package/components/{nav/WindowManager → Window}/ChartReadme.vue +0 -0
  320. /package/components/{nav/WindowManager → Window}/ContainerShell.vue +0 -0
  321. /package/components/{nav/WindowManager → Window}/KubectlShell.vue +0 -0
  322. /package/components/{nav/WindowManager → Window}/MachineSsh.vue +0 -0
  323. /package/components/{nav/WindowManager → Window}/Window.vue +0 -0
package/models/chart.js CHANGED
@@ -1,8 +1,10 @@
1
- import { compatibleVersionsFor, APP_UPGRADE_STATUS } from '@shell/store/catalog';
1
+ import { APP_UPGRADE_STATUS } from '@shell/store/catalog';
2
2
  import {
3
3
  REPO_TYPE, REPO, CHART, VERSION, _FLAGGED, HIDE_SIDE_NAV, CATEGORY, TAG, DEPRECATED as DEPRECATED_QUERY
4
4
  } from '@shell/config/query-params';
5
5
  import { BLANK_CLUSTER } from '@shell/store/store-types.js';
6
+ import { SHOW_PRE_RELEASE } from '@shell/store/prefs';
7
+ import { getLatestCompatibleVersion } from '@shell/utils/chart';
6
8
  import SteveModel from '@shell/plugins/steve/steve-class';
7
9
  import { CATALOG, ZERO_TIME } from '@shell/config/types';
8
10
  import { CATALOG as CATALOG_ANNOTATIONS } from '@shell/config/labels-annotations';
@@ -10,17 +12,7 @@ import day from 'dayjs';
10
12
 
11
13
  export default class Chart extends SteveModel {
12
14
  queryParams(from, hideSideNav) {
13
- let version;
14
- const chartVersions = this.versions;
15
- const currentCluster = this.$rootGetters['currentCluster'];
16
- const workerOSs = currentCluster?.workerOSs;
17
- const compatibleVersions = compatibleVersionsFor(this, workerOSs);
18
-
19
- if (compatibleVersions.length) {
20
- version = compatibleVersions[0].version;
21
- } else {
22
- version = chartVersions[0].version;
23
- }
15
+ const version = this.latestCompatibleVersion.version;
24
16
 
25
17
  const out = {
26
18
  [REPO_TYPE]: this.repoType,
@@ -115,6 +107,26 @@ export default class Chart extends SteveModel {
115
107
  return this.isInstalled && this.matchingInstalledApps[0].upgradeAvailable === APP_UPGRADE_STATUS.SINGLE_UPGRADE;
116
108
  }
117
109
 
110
+ /**
111
+ * Retrieves the latest chart version that is compatible with the current cluster's OS and user's pre-release preference.
112
+ * It caches the result for efficiency.
113
+ *
114
+ * @returns {Object} The latest compatible chart version object.
115
+ */
116
+ get latestCompatibleVersion() {
117
+ if (this._latestCompatibleVersion) {
118
+ return this._latestCompatibleVersion;
119
+ }
120
+
121
+ const currentCluster = this.$rootGetters['currentCluster'];
122
+ const workerOSs = currentCluster?.workerOSs;
123
+ const showPrerelease = this.$rootGetters['prefs/get'](SHOW_PRE_RELEASE);
124
+
125
+ this._latestCompatibleVersion = getLatestCompatibleVersion(this, workerOSs, showPrerelease);
126
+
127
+ return this._latestCompatibleVersion;
128
+ }
129
+
118
130
  /**
119
131
  * Builds structured metadata for display in RcItemCard.vue:
120
132
  * - Sub-header (version and last updated)
@@ -125,7 +137,7 @@ export default class Chart extends SteveModel {
125
137
  */
126
138
  get cardContent() {
127
139
  if (!this._cardContent) {
128
- const latestVersion = this.versions?.[0] || {};
140
+ const latestVersion = this.latestCompatibleVersion;
129
141
  const subHeaderItems = [];
130
142
 
131
143
  if (latestVersion) {
@@ -4,7 +4,6 @@ import {
4
4
  CAPI, MANAGEMENT, METRIC, NORMAN, POD
5
5
  } from '@shell/config/types';
6
6
  import { parseSi } from '@shell/utils/units';
7
- import findLast from 'lodash/findLast';
8
7
 
9
8
  import SteveModel from '@shell/plugins/steve/steve-class';
10
9
  import { LOCAL } from '@shell/config/query-params';
@@ -96,15 +95,23 @@ export default class ClusterNode extends SteveModel {
96
95
  return this.status?.addresses || [];
97
96
  }
98
97
 
99
- get internalIp() {
100
- return findLast(this.addresses, (address) => address.type === 'InternalIP')?.address;
98
+ get internalIps() {
99
+ return this.addresses.filter((address) => address.type === 'InternalIP').map((address) => address.address);
101
100
  }
102
101
 
103
- get externalIp() {
102
+ get externalIps() {
104
103
  const annotationAddress = this.metadata.annotations[RKE.EXTERNAL_IP];
105
- const statusAddress = findLast(this.addresses, (address) => address.type === 'ExternalIP')?.address;
104
+ const statusAddresses = this.addresses.filter((address) => address.type === 'ExternalIP').map((address) => address.address);
105
+
106
+ return statusAddresses.concat(annotationAddress || []);
107
+ }
106
108
 
107
- return statusAddress || annotationAddress;
109
+ get internalIp() {
110
+ return this.internalIps[0];
111
+ }
112
+
113
+ get externalIp() {
114
+ return this.externalIps[0];
108
115
  }
109
116
 
110
117
  get labels() {
@@ -244,29 +244,19 @@ export default class CapiMachine extends SteveModel {
244
244
  return this.status?.phase === 'Running';
245
245
  }
246
246
 
247
- get internalIp() {
248
- // This shows in the IP address column for RKE2 nodes in the
249
- // list of nodes in the cluster detail page of Cluster Management.
250
- const internal = this.status?.addresses?.find(({ type }) => {
251
- return type === ADDRESSES.INTERNAL_IP;
252
- })?.address;
253
-
254
- if (internal) {
255
- return internal;
256
- }
257
-
258
- return this.t('generic.none');
247
+ get internalIps() {
248
+ return this.status?.addresses?.filter(({ type }) => type === ADDRESSES.INTERNAL_IP).map((addr) => addr.address) || [];
259
249
  }
260
250
 
261
- get externalIp() {
262
- const external = this.status?.addresses?.find(({ type }) => {
263
- return type === ADDRESSES.EXTERNAL_IP;
264
- })?.address;
251
+ get externalIps() {
252
+ return this.status?.addresses?.filter(({ type }) => type === ADDRESSES.EXTERNAL_IP).map((addr) => addr.address) || [];
253
+ }
265
254
 
266
- if (external) {
267
- return external;
268
- }
255
+ get internalIp() {
256
+ return this.internalIps[0];
257
+ }
269
258
 
270
- return this.t('generic.none');
259
+ get externalIp() {
260
+ return this.externalIps[0];
271
261
  }
272
262
  }
@@ -4,7 +4,7 @@ import { sortBy } from '@shell/utils/sort';
4
4
  import SteveModel from '@shell/plugins/steve/steve-class';
5
5
  import { exceptionToErrorsArray } from '@shell/utils/error';
6
6
  import { handleConflict } from '@shell/plugins/dashboard-store/normalize';
7
- import { MACHINE_ROLES } from '@shell/config/labels-annotations';
7
+ import { CAPI as CAPI_ANNOTATIONS, MACHINE_ROLES } from '@shell/config/labels-annotations';
8
8
  import { notOnlyOfRole } from '@shell/models/cluster.x-k8s.io.machine';
9
9
  import { KIND } from '../config/elemental-types';
10
10
  import { KIND as HARVESTER_KIND } from '../config/harvester-manager-types';
@@ -173,6 +173,10 @@ export default class CapiMachineDeployment extends SteveModel {
173
173
  }, 1000);
174
174
  }
175
175
 
176
+ get isAutoscalerEnabled() {
177
+ return this.annotations?.[CAPI_ANNOTATIONS.AUTOSCALER_MACHINE_POOL_MIN_SIZE] || this.annotations?.[CAPI_ANNOTATIONS.AUTOSCALER_MACHINE_POOL_MAX_SIZE];
178
+ }
179
+
176
180
  // prevent scaling pool to 0 if it would scale down the only etcd or control plane node
177
181
  canScaleDownPool() {
178
182
  if (!this.canUpdate || this.inClusterSpec?.quantity === 0 || this.infrastructureRefKind === KIND.MACHINE_INV_SELECTOR_TEMPLATES) {
@@ -15,6 +15,7 @@ import { LINUX, WINDOWS } from '@shell/store/catalog';
15
15
  import { KONTAINER_TO_DRIVER } from './management.cattle.io.kontainerdriver';
16
16
  import { PINNED_CLUSTERS } from '@shell/store/prefs';
17
17
  import { copyTextToClipboard } from '@shell/utils/clipboard';
18
+ import { isHostedProvider } from '@shell/utils/provider';
18
19
 
19
20
  const DEFAULT_BADGE_COLOR = '#707070';
20
21
 
@@ -171,9 +172,20 @@ export default class MgmtCluster extends SteveModel {
171
172
  return this.isCondition('Ready');
172
173
  }
173
174
 
175
+ get config() {
176
+ if (!this.spec?.[`${ this.provisioner }Config`]) {
177
+ const allKeys = Object.keys(this.spec);
178
+ const configKey = allKeys.find( (k) => k.endsWith('Config'));
179
+
180
+ return this.spec[configKey];
181
+ }
182
+
183
+ return this.spec?.[`${ this.provisioner }Config`];
184
+ }
185
+
174
186
  get kubernetesVersionRaw() {
175
187
  const fromStatus = this.status?.version?.gitVersion;
176
- const fromSpec = this.spec?.[`${ this.provisioner }Config`]?.kubernetesVersion;
188
+ const fromSpec = this.config?.kubernetesVersion;
177
189
 
178
190
  return fromStatus || fromSpec;
179
191
  }
@@ -239,9 +251,15 @@ export default class MgmtCluster extends SteveModel {
239
251
  }
240
252
 
241
253
  get isHostedKubernetesProvider() {
242
- const providers = ['AKS', 'EKS', 'GKE'];
254
+ const context = {
255
+ dispatch: this.$dispatch,
256
+ getters: this.$getters,
257
+ axios: this.$axios,
258
+ $extension: this.$plugin,
259
+ t: (...args) => this.t.apply(this, args),
260
+ };
243
261
 
244
- return providers.includes(this.provisioner);
262
+ return isHostedProvider(context, this.provisioner);
245
263
  }
246
264
 
247
265
  get providerLogo() {
@@ -41,6 +41,7 @@ export const DRIVER_TO_IMPORT = {
41
41
  googlegke: 'gke',
42
42
  amazoneks: 'eks',
43
43
  azureaks: 'aks',
44
+ alibaba: 'alibabacloud'
44
45
  };
45
46
 
46
47
  export default class KontainerDriver extends HybridModel {
@@ -1,5 +1,7 @@
1
1
  import {
2
- CAPI, MANAGEMENT, NAMESPACE, NORMAN, SNAPSHOT, HCI, LOCAL_CLUSTER
2
+ CAPI, MANAGEMENT, NAMESPACE, NORMAN, SNAPSHOT, HCI, LOCAL_CLUSTER,
3
+ CONFIG_MAP, AUTOSCALER_CONFIG_MAP_ID,
4
+ EVENT
3
5
  } from '@shell/config/types';
4
6
  import SteveModel from '@shell/plugins/steve/steve-class';
5
7
  import { findBy } from '@shell/utils/array';
@@ -7,10 +9,14 @@ import { get, set } from '@shell/utils/object';
7
9
  import { sortBy } from '@shell/utils/sort';
8
10
  import { ucFirst } from '@shell/utils/string';
9
11
  import { compare } from '@shell/utils/version';
10
- import { AS, MODE, _VIEW, _YAML } from '@shell/config/query-params';
11
12
  import { HARVESTER_NAME as HARVESTER } from '@shell/config/features';
12
13
  import { CAPI as CAPI_ANNOTATIONS, NODE_ARCHITECTURE } from '@shell/config/labels-annotations';
13
14
  import { KEV1 } from '@shell/models/management.cattle.io.kontainerdriver';
15
+ import jsyaml from 'js-yaml';
16
+ import { defineAsyncComponent, markRaw } from 'vue';
17
+ import stevePaginationUtils from '@shell/plugins/steve/steve-pagination-utils';
18
+ import { PaginationFilterField, PaginationParamFilter } from '@shell/types/store/pagination.types';
19
+ import { isHostedProvider } from '@shell/utils/provider';
14
20
 
15
21
  const RKE1_ALLOWED_ACTIONS = [
16
22
  'promptRemove',
@@ -21,6 +27,11 @@ const RKE1_ALLOWED_ACTIONS = [
21
27
  'viewInApi'
22
28
  ];
23
29
 
30
+ const AUTOSCALER_STATUS = {
31
+ PROVISIONING: 'provisioning',
32
+ UNAVAILABLE: 'unavailable'
33
+ };
34
+
24
35
  /**
25
36
  * Class representing Cluster resource.
26
37
  * @extends SteveModel
@@ -48,6 +59,17 @@ export default class ProvCluster extends SteveModel {
48
59
  label: this.t('cluster.detail.machines'),
49
60
  content: this.desired,
50
61
  },
62
+ {
63
+ label: 'Autoscaler',
64
+ content: this.isAutoscalerEnabled,
65
+ valueOverride: {
66
+ component: markRaw(defineAsyncComponent(() => import('@shell/components/formatter/Autoscaler.vue'))),
67
+ props: {
68
+ value: true,
69
+ row: this
70
+ }
71
+ }
72
+ }
51
73
  ].filter((x) => !!x.content);
52
74
 
53
75
  if (!this.machineProvider) {
@@ -148,7 +170,14 @@ export default class ProvCluster extends SteveModel {
148
170
  label: this.$rootGetters['i18n/t']('nav.rotateEncryptionKeys'),
149
171
  icon: 'icon icon-refresh',
150
172
  enabled: canEditRKE2cluster
151
- }, { divider: true }];
173
+ },
174
+ {
175
+ action: 'toggleAutoscalerRunner',
176
+ label: this.isAutoscalerPaused ? 'Resume Autoscaler' : 'Pause Autoscaler',
177
+ icon: `icon ${ this.isAutoscalerPaused ? 'icon-play' : 'icon-pause' }`,
178
+ enabled: this.canPauseResumeAutoscaler
179
+ },
180
+ { divider: true }];
152
181
 
153
182
  const all = actions.concat(out);
154
183
 
@@ -231,26 +260,6 @@ export default class ProvCluster extends SteveModel {
231
260
  }
232
261
  }
233
262
 
234
- goToViewYaml() {
235
- let location;
236
-
237
- if ( !this.isRke2 ) {
238
- location = this.mgmt?.detailLocation;
239
- }
240
-
241
- if ( !location ) {
242
- location = this.detailLocation;
243
- }
244
-
245
- location.query = {
246
- ...location.query,
247
- [MODE]: _VIEW,
248
- [AS]: _YAML
249
- };
250
-
251
- this.currentRouter().push(location);
252
- }
253
-
254
263
  get canDelete() {
255
264
  return super.canDelete && this.stateObj?.name !== 'removing';
256
265
  }
@@ -264,9 +273,26 @@ export default class ProvCluster extends SteveModel {
264
273
  }
265
274
 
266
275
  get isHostedKubernetesProvider() {
267
- const providers = ['AKS', 'EKS', 'GKE'];
276
+ const context = {
277
+ dispatch: this.$dispatch,
278
+ getters: this.$getters,
279
+ axios: this.$axios,
280
+ $extension: this.$plugin,
281
+ t: (...args) => this.t.apply(this, args),
282
+ };
283
+
284
+ return isHostedProvider(context, this.provisioner);
285
+ }
268
286
 
269
- return providers.includes(this.provisioner);
287
+ get providerConfig() {
288
+ if ( this.isRke2 ) {
289
+ return this.spec.rkeConfig;
290
+ }
291
+ if (this.mgmt && this.mgmt.config) {
292
+ return this.mgmt.config;
293
+ }
294
+
295
+ return null;
270
296
  }
271
297
 
272
298
  get isPrivateHostedProvider() {
@@ -306,13 +332,7 @@ export default class ProvCluster extends SteveModel {
306
332
 
307
333
  // imported KEv2
308
334
  // we can't rely on this.provisioner to determine imported-ness for these clusters, as it will return 'aks' 'eks' 'gke' for both provisioned and imported clusters
309
- const kontainerConfigs = ['aksConfig', 'eksConfig', 'gkeConfig'];
310
-
311
- const isImportedKontainer = kontainerConfigs.filter((key) => {
312
- return this.mgmt?.spec?.[key]?.imported === true;
313
- }).length;
314
-
315
- if (isImportedKontainer) {
335
+ if (this.isHostedKubernetesProvider && !!this.providerConfig.imported) {
316
336
  return true;
317
337
  }
318
338
 
@@ -361,7 +381,11 @@ export default class ProvCluster extends SteveModel {
361
381
  }
362
382
 
363
383
  get mgmtClusterId() {
364
- return this.status?.clusterName;
384
+ // when a cluster is created `this` instance isn't immediately updated with `status.clusterName`
385
+ // Workaround - Get fresh copy from the store
386
+ const pCluster = this.$rootGetters['management/byId'](CAPI.RANCHER_CLUSTER, this.id);
387
+
388
+ return this.status?.clusterName || pCluster?.status?.clusterName;
365
389
  }
366
390
 
367
391
  get mgmt() {
@@ -1023,4 +1047,196 @@ export default class ProvCluster extends SteveModel {
1023
1047
  get fullDetailPageOverride() {
1024
1048
  return true;
1025
1049
  }
1050
+
1051
+ async loadAutoscalerEvents() {
1052
+ const autoscalerConfigMap = await this.loadAutoscalerConfigMap();
1053
+ const eventSchema = this.$rootGetters['management/schemaFor'](EVENT);
1054
+ const fields = [new PaginationFilterField({
1055
+ field: 'involvedObject.uid',
1056
+ value: autoscalerConfigMap.metadata.uid,
1057
+ exact: true,
1058
+ }),
1059
+ new PaginationFilterField({
1060
+ field: 'metadata.namespace',
1061
+ value: 'kube-system',
1062
+ exact: true,
1063
+ })];
1064
+ const pagination = {
1065
+ page: 1,
1066
+ pageSize: 200,
1067
+ filters: [
1068
+ new PaginationParamFilter({ fields })
1069
+ ]
1070
+
1071
+ };
1072
+ const params = stevePaginationUtils.createParamsForPagination({ schema: eventSchema, opt: { pagination } });
1073
+ const url = `/k8s/clusters/${ this.mgmtClusterId }/v1/${ EVENT }?${ params }`;
1074
+
1075
+ const events = (await this.$dispatch('cluster/request', { url }, { root: true }))?.data || [];
1076
+
1077
+ return events.filter((event) => event.involvedObject.name === 'cluster-autoscaler-status');
1078
+ }
1079
+
1080
+ get hasAccessToAutoscalerConfigMap() {
1081
+ // This may change but for now this is the best proxy we have for access to the configmap without attempting to access it and getting a 404.
1082
+ return this.canEdit;
1083
+ }
1084
+
1085
+ async loadAutoscalerConfigMap() {
1086
+ const url = `/k8s/clusters/${ this.mgmtClusterId }/v1/${ CONFIG_MAP }/${ AUTOSCALER_CONFIG_MAP_ID }`;
1087
+
1088
+ return await this.$dispatch('cluster/request', { url }, { root: true });
1089
+ }
1090
+
1091
+ get canPauseResumeAutoscaler() {
1092
+ return this.isAutoscalerEnabled && this.canExplore && this.hasAccessToAutoscalerConfigMap;
1093
+ }
1094
+
1095
+ async loadAutoscalerStatus() {
1096
+ if (!this.canExplore) {
1097
+ return AUTOSCALER_STATUS.PROVISIONING;
1098
+ }
1099
+
1100
+ if (!this.hasAccessToAutoscalerConfigMap) {
1101
+ return AUTOSCALER_STATUS.UNAVAILABLE;
1102
+ }
1103
+
1104
+ try {
1105
+ const configMap = await this.loadAutoscalerConfigMap();
1106
+ const yaml = configMap?.data?.status || '';
1107
+
1108
+ return jsyaml.load(yaml);
1109
+ } catch (ex) {
1110
+ console.error(ex); // eslint-disable-line no-console
1111
+
1112
+ return AUTOSCALER_STATUS.UNAVAILABLE;
1113
+ }
1114
+ }
1115
+
1116
+ async loadAutoscalerDetails() {
1117
+ const out = [];
1118
+
1119
+ if (this.isAutoscalerPaused) {
1120
+ out.push({
1121
+ label: this.t('autoscaler.card.details.status'),
1122
+ value: this.t('autoscaler.card.details.paused')
1123
+ });
1124
+
1125
+ return out;
1126
+ }
1127
+
1128
+ const status = await this.loadAutoscalerStatus();
1129
+
1130
+ if (status === AUTOSCALER_STATUS.UNAVAILABLE) {
1131
+ out.push({
1132
+ label: this.t('autoscaler.card.details.status'),
1133
+ value: this.t('autoscaler.card.details.unavailable')
1134
+ });
1135
+
1136
+ return out;
1137
+ }
1138
+
1139
+ if (status === AUTOSCALER_STATUS.PROVISIONING) {
1140
+ out.push({
1141
+ label: this.t('autoscaler.card.details.status'),
1142
+ value: this.t('autoscaler.card.details.provisioning')
1143
+ });
1144
+
1145
+ return out;
1146
+ }
1147
+
1148
+ if (status.autoscalerStatus) {
1149
+ out.push({
1150
+ label: this.t('autoscaler.card.details.status'),
1151
+ value: status.autoscalerStatus
1152
+ });
1153
+ }
1154
+
1155
+ if (status.clusterWide?.health?.status) {
1156
+ const statusValue = status.clusterWide.health.status;
1157
+
1158
+ out.push({
1159
+ label: this.t('autoscaler.card.details.health'),
1160
+ value: {
1161
+ component: 'BadgeStateFormatter',
1162
+ props: {
1163
+ value: statusValue, arbitrary: true, row: {}
1164
+ },
1165
+ }
1166
+ });
1167
+ }
1168
+
1169
+ if (status.clusterWide?.scaleDown?.lastTransitionTime) {
1170
+ out.push({
1171
+ label: this.t('autoscaler.card.details.scaleDown'),
1172
+ value: {
1173
+ component: 'LiveDate',
1174
+ props: {
1175
+ value: status.clusterWide.scaleDown.lastTransitionTime,
1176
+ addSuffix: true
1177
+ }
1178
+ }
1179
+ });
1180
+ }
1181
+
1182
+ if (status.clusterWide?.scaleUp?.lastTransitionTime) {
1183
+ out.push({
1184
+ label: this.t('autoscaler.card.details.scaleUp'),
1185
+ value: {
1186
+ component: 'LiveDate',
1187
+ props: {
1188
+ value: status.clusterWide.scaleUp.lastTransitionTime,
1189
+ addSuffix: true
1190
+ }
1191
+ }
1192
+ });
1193
+ }
1194
+
1195
+ if (status.clusterWide?.health?.nodeCounts?.registered) {
1196
+ out.push({ label: this.t('autoscaler.card.details.nodes') });
1197
+
1198
+ out.push({
1199
+ label: this.t('autoscaler.card.details.ready'),
1200
+ value: status.clusterWide.health.nodeCounts.registered.ready || '0'
1201
+ });
1202
+ out.push({
1203
+ label: this.t('autoscaler.card.details.notStarted'),
1204
+ value: status.clusterWide.health.nodeCounts.registered.notStarted || '0'
1205
+ });
1206
+ out.push({
1207
+ label: this.t('autoscaler.card.details.inTotal'),
1208
+ value: status.clusterWide.health.nodeCounts.registered.total || '0'
1209
+ });
1210
+ }
1211
+
1212
+ return out;
1213
+ }
1214
+
1215
+ get isAutoscalerEnabled() {
1216
+ return !!this.spec?.rkeConfig?.machinePools?.some((pool) => {
1217
+ return typeof pool.autoscalingMinSize !== 'undefined' || typeof pool.autoscalingMaxSize !== 'undefined';
1218
+ });
1219
+ }
1220
+
1221
+ get isAutoscalerPaused() {
1222
+ return !!this.metadata?.annotations?.[CAPI_ANNOTATIONS.AUTOSCALER_CLUSTER_PAUSE];
1223
+ }
1224
+
1225
+ pauseAutoscaler() {
1226
+ this.setAnnotation(CAPI_ANNOTATIONS.AUTOSCALER_CLUSTER_PAUSE, 'true');
1227
+ }
1228
+
1229
+ resumeAutoscaler() {
1230
+ this.setAnnotation(CAPI_ANNOTATIONS.AUTOSCALER_CLUSTER_PAUSE, undefined);
1231
+ }
1232
+
1233
+ toggleAutoscalerRunner() {
1234
+ if (this.isAutoscalerPaused) {
1235
+ this.resumeAutoscaler();
1236
+ } else {
1237
+ this.pauseAutoscaler();
1238
+ }
1239
+
1240
+ return this.save();
1241
+ }
1026
1242
  }
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@rancher/shell",
3
- "version": "3.0.8-rc.1",
3
+ "version": "3.0.8-rc.10",
4
4
  "description": "Rancher Dashboard Shell",
5
5
  "repository": "https://github.com/rancherlabs/dashboard",
6
6
  "license": "Apache-2.0",
7
7
  "author": "SUSE",
8
8
  "private": false,
9
+ "types": "types/shell/index.d.ts",
9
10
  "engines": {
10
11
  "node": ">=20.0.0"
11
12
  },
@@ -38,7 +39,7 @@
38
39
  "@babel/preset-typescript": "7.16.7",
39
40
  "@novnc/novnc": "1.2.0",
40
41
  "@popperjs/core": "2.11.8",
41
- "@rancher/icons": "2.0.49",
42
+ "@rancher/icons": "2.0.54",
42
43
  "@types/is-url": "1.2.30",
43
44
  "@types/node": "20.10.8",
44
45
  "@types/semver": "^7.5.8",
@@ -61,7 +62,7 @@
61
62
  "clipboard-polyfill": "4.0.1",
62
63
  "codemirror-editor-vue3": "2.8.0",
63
64
  "codemirror": ">=5.64.0 <6",
64
- "color": "4.2.3",
65
+ "color": "5.0.3",
65
66
  "cookie-universal": "2.2.2",
66
67
  "cookie": "0.7.0",
67
68
  "core-js": "3.45.0",
@@ -105,7 +106,7 @@
105
106
  "jquery": "3.5.1",
106
107
  "js-cookie": "3.0.5",
107
108
  "js-yaml-loader": "1.2.2",
108
- "js-yaml": "4.1.0",
109
+ "js-yaml": "4.1.1",
109
110
  "jsdiff": "1.1.1",
110
111
  "jsonpath-plus": "10.3.0",
111
112
  "jsrsasign": "11.0.0",
@@ -114,7 +115,7 @@
114
115
  "marked": "4.0.17",
115
116
  "node-polyfill-webpack-plugin": "3.0.0",
116
117
  "nodemon": "2.0.22",
117
- "nyc": "15.1.0",
118
+ "nyc": "17.1.0",
118
119
  "papaparse": "5.3.0",
119
120
  "portal-vue": "~3.0.0",
120
121
  "sass-loader": "12.6.0",