@rancher/shell 0.1.2 → 0.1.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 (347) hide show
  1. package/assets/brand/suse/dark/rancher-logo.svg +1 -148
  2. package/assets/brand/suse/rancher-logo.svg +1 -130
  3. package/assets/images/featured/img1.jpg +0 -0
  4. package/assets/images/featured.jpg +0 -0
  5. package/assets/images/generic-plugin.svg +7 -0
  6. package/assets/styles/themes/_dark.scss +3 -0
  7. package/assets/styles/themes/_light.scss +3 -0
  8. package/assets/styles/themes/_suse.scss +1 -1
  9. package/assets/translations/en-us.yaml +209 -813
  10. package/assets/translations/zh-hans.yaml +28 -792
  11. package/components/ActionMenu.vue +3 -3
  12. package/components/AsyncButton.vue +17 -2
  13. package/components/ButtonDropdown.vue +4 -0
  14. package/components/Carousel.vue +291 -0
  15. package/components/CodeMirror.vue +6 -8
  16. package/components/CommunityLinks.vue +70 -19
  17. package/components/ContainerResourceLimit.vue +14 -0
  18. package/components/CruResource.vue +11 -3
  19. package/components/Dialog.vue +102 -0
  20. package/components/ExplorerMembers.vue +121 -0
  21. package/components/ExplorerProjectsNamespaces.vue +404 -0
  22. package/components/GrafanaDashboard.vue +17 -2
  23. package/components/IconMessage.vue +9 -1
  24. package/components/LocaleSelector.vue +114 -0
  25. package/components/PromptModal.vue +2 -3
  26. package/components/ResourceList/index.vue +1 -1
  27. package/components/ResourceTable.vue +9 -7
  28. package/components/SimpleBox.vue +6 -4
  29. package/components/SingleClusterInfo.vue +1 -1
  30. package/components/SortableTable/index.vue +18 -25
  31. package/components/SortableTable/selection.js +1 -0
  32. package/components/Tabbed/Tab.vue +5 -0
  33. package/components/Tabbed/index.vue +29 -2
  34. package/components/auth/AzureWarning.vue +5 -1
  35. package/components/auth/Principal.vue +2 -1
  36. package/components/auth/RoleDetailEdit.vue +18 -11
  37. package/components/fleet/FleetBundles.vue +8 -3
  38. package/components/fleet/FleetRepos.vue +0 -2
  39. package/components/fleet/FleetSummary.vue +6 -0
  40. package/components/form/KeyValue.vue +80 -58
  41. package/components/form/NameNsDescription.vue +12 -8
  42. package/components/form/NodeScheduling.vue +1 -1
  43. package/components/form/ResourceTabs/index.vue +5 -1
  44. package/components/form/WorkloadPorts.vue +1 -1
  45. package/components/formatter/ClusterLink.vue +3 -7
  46. package/components/formatter/WorkloadHealthScale.vue +1 -1
  47. package/components/nav/Header.vue +9 -9
  48. package/components/nav/NamespaceFilter.vue +10 -7
  49. package/components/nav/TopLevelMenu.vue +10 -65
  50. package/components/nav/WindowManager/ContainerLogs.vue +1 -1
  51. package/config/footer.js +13 -14
  52. package/config/labels-annotations.js +2 -1
  53. package/config/product/explorer.js +5 -4
  54. package/config/product/harvester-manager.js +64 -2
  55. package/config/product/legacy.js +0 -47
  56. package/config/product/manager.js +9 -0
  57. package/config/product/multi-cluster-apps.js +0 -12
  58. package/config/product/settings.js +12 -1
  59. package/config/product/uiplugins.js +17 -0
  60. package/config/settings.js +37 -72
  61. package/config/table-headers.js +0 -1
  62. package/config/types.js +9 -25
  63. package/config/uiplugins.js +60 -0
  64. package/content/docs/en-us/getting-started.md +1 -26
  65. package/core/plugin-routes.ts +34 -22
  66. package/core/plugin.ts +15 -3
  67. package/core/plugins-loader.js +2 -0
  68. package/core/plugins.js +91 -36
  69. package/core/types.ts +7 -1
  70. package/detail/provisioning.cattle.io.cluster.vue +15 -2
  71. package/detail/workload/index.vue +11 -5
  72. package/{components/dialog → dialog}/AddClusterMemberDialog.vue +0 -0
  73. package/{components/dialog → dialog}/AddCustomBadgeDialog.vue +0 -0
  74. package/{components/dialog → dialog}/AddProjectMemberDialog.vue +0 -0
  75. package/{components/dialog → dialog}/AddonConfigConfirmationDialog.vue +0 -0
  76. package/dialog/DiagnosticTimingsDialog.vue +116 -0
  77. package/{components/dialog → dialog}/DrainNode.vue +0 -0
  78. package/{components/dialog → dialog}/ForceMachineRemoveDialog.vue +0 -0
  79. package/{components/dialog → dialog}/GenericPrompt.vue +0 -0
  80. package/{components/dialog → dialog}/RollbackWorkloadDialog.vue +0 -0
  81. package/{components/dialog → dialog}/RotateCertificatesDialog.vue +9 -3
  82. package/{components/dialog → dialog}/RotateEncryptionKeyDialog.vue +0 -0
  83. package/{components/dialog → dialog}/SaveAsRKETemplateDialog.vue +0 -0
  84. package/{components/dialog → dialog}/ScaleMachineDownDialog.vue +0 -0
  85. package/edit/auth/azuread.vue +44 -6
  86. package/edit/management.cattle.io.project.vue +2 -2
  87. package/edit/namespace.vue +17 -10
  88. package/edit/networking.k8s.io.ingress/index.vue +2 -2
  89. package/edit/persistentvolume/index.vue +3 -0
  90. package/edit/persistentvolumeclaim.vue +1 -0
  91. package/edit/pod.vue +27 -0
  92. package/edit/provisioning.cattle.io.cluster/CustomCommand.vue +1 -1
  93. package/edit/provisioning.cattle.io.cluster/MachinePool.vue +33 -5
  94. package/edit/provisioning.cattle.io.cluster/rke2.vue +76 -5
  95. package/edit/service.vue +8 -6
  96. package/edit/workload/__tests__/Upgrading.test.ts +1 -0
  97. package/edit/workload/index.vue +375 -15
  98. package/edit/workload/mixins/workload.js +62 -7
  99. package/edit/workload/storage/ContainerMountPaths.vue +240 -0
  100. package/edit/workload/storage/Mount.vue +1 -0
  101. package/edit/workload/storage/awsElasticBlockStore.vue +20 -1
  102. package/edit/workload/storage/azureDisk.vue +22 -2
  103. package/edit/workload/storage/azureFile.vue +20 -2
  104. package/edit/workload/storage/csi/index.vue +23 -1
  105. package/edit/workload/storage/gcePersistentDisk.vue +20 -2
  106. package/edit/workload/storage/index.vue +23 -49
  107. package/edit/workload/storage/persistentVolumeClaim/persistentvolumeclaim.vue +1 -0
  108. package/edit/workload/storage/vsphereVolume.vue +11 -1
  109. package/layouts/default.vue +63 -32
  110. package/layouts/error.vue +5 -1
  111. package/layouts/home.vue +14 -5
  112. package/layouts/plain.vue +10 -5
  113. package/list/harvesterhci.io.management.cluster.vue +74 -33
  114. package/list/management.cattle.io.setting.vue +3 -3
  115. package/list/namespace.vue +3 -5
  116. package/list/provisioning.cattle.io.cluster.vue +1 -1
  117. package/machine-config/amazonec2.vue +2 -0
  118. package/machine-config/harvester.vue +100 -51
  119. package/middleware/authenticated.js +56 -52
  120. package/mixins/form-validation.js +1 -1
  121. package/mixins/resource-fetch.js +3 -1
  122. package/models/catalog.cattle.io.uiplugin.js +34 -0
  123. package/models/cluster/node.js +25 -2
  124. package/models/fleet.cattle.io.bundle.js +27 -20
  125. package/models/harvesterhci.io.management.cluster.js +200 -5
  126. package/models/management.cattle.io.cluster.js +1 -1
  127. package/models/management.cattle.io.clusterroletemplatebinding.js +9 -0
  128. package/models/management.cattle.io.project.js +23 -2
  129. package/models/namespace.js +19 -3
  130. package/models/pod.js +19 -2
  131. package/models/provisioning.cattle.io.cluster.js +16 -6
  132. package/models/workload.js +9 -246
  133. package/models/workload.service.js +314 -0
  134. package/nuxt.config.js +80 -34
  135. package/package.json +107 -108
  136. package/pages/auth/login.vue +11 -2
  137. package/pages/auth/setup.vue +1 -1
  138. package/pages/c/_cluster/_product/members/index.vue +3 -93
  139. package/pages/c/_cluster/_product/projectsnamespaces.vue +6 -403
  140. package/pages/c/_cluster/apps/charts/index.vue +46 -1
  141. package/pages/c/_cluster/apps/charts/install.vue +10 -9
  142. package/pages/c/_cluster/explorer/index.vue +72 -9
  143. package/pages/c/_cluster/explorer/tools/index.vue +12 -5
  144. package/pages/c/_cluster/mcapps/index.vue +1 -1
  145. package/pages/c/_cluster/settings/brand.vue +0 -40
  146. package/pages/c/_cluster/settings/links.vue +200 -0
  147. package/pages/c/_cluster/settings/performance.vue +19 -16
  148. package/pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue +232 -0
  149. package/pages/c/_cluster/uiplugins/InstallDialog.vue +242 -0
  150. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +284 -0
  151. package/pages/c/_cluster/uiplugins/RemoveUIPlugins.vue +130 -0
  152. package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +253 -0
  153. package/pages/c/_cluster/uiplugins/UninstallDialog.vue +115 -0
  154. package/pages/c/_cluster/uiplugins/index.vue +694 -0
  155. package/pages/diagnostic.vue +185 -101
  156. package/pages/docs/_doc.vue +3 -1
  157. package/pages/fail-whale.vue +1 -10
  158. package/pages/home.vue +21 -56
  159. package/pages/index.vue +18 -4
  160. package/pages/prefs.vue +108 -86
  161. package/pages/safeMode.vue +17 -0
  162. package/pages/support/index.vue +23 -15
  163. package/pkg/auto-import.js +44 -7
  164. package/pkg/dynamic-importer.lib.js +4 -0
  165. package/pkg/dynamic-plugin-loader.js +28 -0
  166. package/pkg/import.js +2 -2
  167. package/pkg/model-loader-require.lib.js +3 -0
  168. package/pkg/vue.config.js +9 -6
  169. package/plugins/dashboard-store/model-loader-require.js +12 -0
  170. package/plugins/dashboard-store/model-loader.js +4 -1
  171. package/plugins/dashboard-store/resource-class.js +12 -5
  172. package/plugins/formatters.js +15 -0
  173. package/plugins/plugin.js +56 -4
  174. package/plugins/steve/actions.js +1 -1
  175. package/plugins/steve/index.js +6 -4
  176. package/plugins/steve/mutations.js +1 -1
  177. package/plugins/steve/subscribe.js +89 -56
  178. package/plugins/steve/web-worker.steve-sub-worker.js +24 -15
  179. package/promptRemove/management.cattle.io.globalrole.vue +47 -0
  180. package/promptRemove/management.cattle.io.roletemplate.vue +47 -0
  181. package/promptRemove/mixin/roleDeletionCheck.js +97 -0
  182. package/rancher-components/Form/Checkbox/Checkbox.test.ts +77 -0
  183. package/rancher-components/Form/Checkbox/Checkbox.vue +12 -2
  184. package/scripts/build-pkg.sh +48 -2
  185. package/scripts/drone-build-pkg.sh +31 -0
  186. package/scripts/publish-shell.sh +11 -12
  187. package/scripts/serve-pkgs +17 -10
  188. package/scripts/sync-shell-deps +37 -0
  189. package/store/catalog.js +12 -9
  190. package/store/i18n.js +26 -12
  191. package/store/index.js +4 -181
  192. package/store/prefs.js +46 -2
  193. package/store/type-map.js +47 -33
  194. package/store/uiplugins.ts +15 -61
  195. package/utils/__tests__/object.test.ts +0 -24
  196. package/utils/__tests__/selector.test.ts +1 -1
  197. package/utils/cluster.js +1 -1
  198. package/utils/custom-validators.js +1 -12
  199. package/utils/dynamic-importer.js +5 -1
  200. package/utils/grafana.js +2 -6
  201. package/utils/socket.js +41 -20
  202. package/utils/string.js +1 -7
  203. package/utils/validators/formRules/__tests__/index.test.ts +108 -0
  204. package/utils/validators/formRules/index.ts +9 -1
  205. package/utils/validators/setting.js +0 -35
  206. package/yarn-error.log +195 -0
  207. package/components/FilterLabel.vue +0 -254
  208. package/components/HarvesterUpgradeProgressBarList.vue +0 -109
  209. package/components/VMConsoleBar.vue +0 -87
  210. package/components/dialog/harvester/AddHotplugModal.vue +0 -159
  211. package/components/dialog/harvester/BackupModal.vue +0 -117
  212. package/components/dialog/harvester/CloneTemplate.vue +0 -125
  213. package/components/dialog/harvester/EjectCDROMDialog.vue +0 -157
  214. package/components/dialog/harvester/ExportImageDialog.vue +0 -152
  215. package/components/dialog/harvester/MaintenanceDialog.vue +0 -94
  216. package/components/dialog/harvester/MigrationDialog.vue +0 -154
  217. package/components/dialog/harvester/RestoreDialog.vue +0 -153
  218. package/components/dialog/harvester/SupportBundle.vue +0 -217
  219. package/components/dialog/harvester/UnplugVolume.vue +0 -108
  220. package/components/form/SerialConsole/index.vue +0 -267
  221. package/components/formatter/AttachVMWithName.vue +0 -46
  222. package/components/formatter/CloudInitType.vue +0 -27
  223. package/components/formatter/HarvesterBackupTargetValidation.vue +0 -43
  224. package/components/formatter/HarvesterCPUUsed.vue +0 -122
  225. package/components/formatter/HarvesterDiskState.vue +0 -66
  226. package/components/formatter/HarvesterHostName.vue +0 -66
  227. package/components/formatter/HarvesterIpAddress.vue +0 -90
  228. package/components/formatter/HarvesterMemoryUsed.vue +0 -140
  229. package/components/formatter/HarvesterMigrationState.vue +0 -85
  230. package/components/formatter/HarvesterNodeName.vue +0 -49
  231. package/components/formatter/HarvesterStorageUsed.vue +0 -194
  232. package/components/formatter/HarvesterVmState.vue +0 -123
  233. package/components/nav/HarvesterUpgrade.vue +0 -232
  234. package/components/novnc/NovncConsole.vue +0 -93
  235. package/components/novnc/NovncConsoleItem.vue +0 -89
  236. package/components/novnc/NovncConsoleWrapper.vue +0 -243
  237. package/config/harvester-map.js +0 -44
  238. package/config/harvester-table-headers.js +0 -27
  239. package/config/product/harvester.js +0 -305
  240. package/detail/harvesterhci.io.host/HarvesterHostBasic.vue +0 -364
  241. package/detail/harvesterhci.io.host/HarvesterHostDisk.vue +0 -200
  242. package/detail/harvesterhci.io.host/HarvesterHostNetwork.vue +0 -89
  243. package/detail/harvesterhci.io.host/VirtualMachineInstance.vue +0 -134
  244. package/detail/harvesterhci.io.host/index.vue +0 -243
  245. package/detail/harvesterhci.io.virtualmachinebackup/index.vue +0 -221
  246. package/detail/harvesterhci.io.virtualmachineimage.vue +0 -118
  247. package/detail/kubevirt.io.virtualmachine/VirtualMachineTabs/VirtualMachineBasics.vue +0 -279
  248. package/detail/kubevirt.io.virtualmachine/VirtualMachineTabs/VirtualMachineEvents.vue +0 -75
  249. package/detail/kubevirt.io.virtualmachine/VirtualMachineTabs/VirtualMachineKeypairs.vue +0 -114
  250. package/detail/kubevirt.io.virtualmachine/VirtualMachineTabs/VirtualMachineMigration.vue +0 -79
  251. package/detail/kubevirt.io.virtualmachine/index.vue +0 -213
  252. package/edit/harvesterhci.io.cloudtemplate.vue +0 -123
  253. package/edit/harvesterhci.io.host/HarvesterDisk.vue +0 -262
  254. package/edit/harvesterhci.io.host/index.vue +0 -533
  255. package/edit/harvesterhci.io.keypair.vue +0 -112
  256. package/edit/harvesterhci.io.managedchart/index.vue +0 -25
  257. package/edit/harvesterhci.io.managedchart/rancher-monitoring.vue +0 -172
  258. package/edit/harvesterhci.io.networkattachmentdefinition.vue +0 -210
  259. package/edit/harvesterhci.io.setting/additional-ca.vue +0 -36
  260. package/edit/harvesterhci.io.setting/backup-target.vue +0 -182
  261. package/edit/harvesterhci.io.setting/http-proxy.vue +0 -79
  262. package/edit/harvesterhci.io.setting/index.vue +0 -201
  263. package/edit/harvesterhci.io.setting/overcommit-config.vue +0 -94
  264. package/edit/harvesterhci.io.setting/ssl-certificates.vue +0 -117
  265. package/edit/harvesterhci.io.setting/ssl-parameters.vue +0 -161
  266. package/edit/harvesterhci.io.setting/support-bundle-image.vue +0 -134
  267. package/edit/harvesterhci.io.setting/support-bundle-namespaces.vue +0 -73
  268. package/edit/harvesterhci.io.setting/vip-pools.vue +0 -244
  269. package/edit/harvesterhci.io.setting/vm-force-reset-policy.vue +0 -81
  270. package/edit/harvesterhci.io.virtualmachinebackup.vue +0 -256
  271. package/edit/harvesterhci.io.virtualmachineimage.vue +0 -364
  272. package/edit/harvesterhci.io.virtualmachinetemplateversion.vue +0 -340
  273. package/edit/harvesterhci.io.volume.vue +0 -195
  274. package/edit/kubevirt.io.virtualmachine/VirtualMachineAccessCredentials/AccessCredentialsUsers.vue +0 -190
  275. package/edit/kubevirt.io.virtualmachine/VirtualMachineAccessCredentials/index.vue +0 -212
  276. package/edit/kubevirt.io.virtualmachine/VirtualMachineAccessCredentials/type/basicAuth.vue +0 -94
  277. package/edit/kubevirt.io.virtualmachine/VirtualMachineAccessCredentials/type/sshkey.vue +0 -85
  278. package/edit/kubevirt.io.virtualmachine/VirtualMachineCloudConfig/DataTemplate.vue +0 -153
  279. package/edit/kubevirt.io.virtualmachine/VirtualMachineCloudConfig/index.vue +0 -279
  280. package/edit/kubevirt.io.virtualmachine/VirtualMachineCpuMemory.vue +0 -113
  281. package/edit/kubevirt.io.virtualmachine/VirtualMachineNetwork/__tests__/HarvesterEditNetwork.test.ts +0 -41
  282. package/edit/kubevirt.io.virtualmachine/VirtualMachineNetwork/base.vue +0 -281
  283. package/edit/kubevirt.io.virtualmachine/VirtualMachineNetwork/index.vue +0 -142
  284. package/edit/kubevirt.io.virtualmachine/VirtualMachineReserved.vue +0 -54
  285. package/edit/kubevirt.io.virtualmachine/VirtualMachineSSHKey.vue +0 -256
  286. package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/index.vue +0 -391
  287. package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/__tests__/HarvesterEditContainer.test.ts +0 -40
  288. package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/__tests__/HarvesterEditExisting.test.ts +0 -102
  289. package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/__tests__/HarvesterEditVMImage.test.ts +0 -117
  290. package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/__tests__/HarvesterEditVolume.test.ts +0 -74
  291. package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/container.vue +0 -132
  292. package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/existing.vue +0 -303
  293. package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/vmImage.vue +0 -285
  294. package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/volume.vue +0 -188
  295. package/edit/kubevirt.io.virtualmachine/index.vue +0 -642
  296. package/edit/network.harvesterhci.io.clusternetwork/index.vue +0 -19
  297. package/edit/network.harvesterhci.io.clusternetwork/vlan.vue +0 -134
  298. package/edit/workload/types/Deployment.vue +0 -377
  299. package/edit/workload/types/Generic.vue +0 -295
  300. package/list/harvesterhci.io.cloudtemplate.vue +0 -78
  301. package/list/harvesterhci.io.dashboard/HarvesterUpgrade.vue +0 -211
  302. package/list/harvesterhci.io.dashboard/UpgradeInfo.vue +0 -40
  303. package/list/harvesterhci.io.dashboard/index.vue +0 -752
  304. package/list/harvesterhci.io.host/index.vue +0 -186
  305. package/list/harvesterhci.io.networkattachmentdefinition.vue +0 -167
  306. package/list/harvesterhci.io.setting.vue +0 -241
  307. package/list/harvesterhci.io.virtualmachinebackup.vue +0 -172
  308. package/list/harvesterhci.io.virtualmachineimage.vue +0 -80
  309. package/list/harvesterhci.io.virtualmachinetemplateversion.vue +0 -173
  310. package/list/harvesterhci.io.volume.vue +0 -122
  311. package/list/kubevirt.io.virtualmachine.vue +0 -193
  312. package/mixins/harvester-vm/impl.js +0 -267
  313. package/mixins/harvester-vm/index.js +0 -1357
  314. package/models/harvester/configmap.js +0 -32
  315. package/models/harvester/harvesterhci.io.blockdevice.js +0 -55
  316. package/models/harvester/harvesterhci.io.keypair.js +0 -12
  317. package/models/harvester/harvesterhci.io.setting.js +0 -127
  318. package/models/harvester/harvesterhci.io.supportbundle.js +0 -35
  319. package/models/harvester/harvesterhci.io.upgrade.js +0 -226
  320. package/models/harvester/harvesterhci.io.virtualmachinebackup.js +0 -116
  321. package/models/harvester/harvesterhci.io.virtualmachineimage.js +0 -255
  322. package/models/harvester/harvesterhci.io.virtualmachinerestore.js +0 -43
  323. package/models/harvester/harvesterhci.io.virtualmachinetemplate.js +0 -69
  324. package/models/harvester/harvesterhci.io.virtualmachinetemplateversion.js +0 -227
  325. package/models/harvester/k8s.cni.cncf.io.networkattachmentdefinition.js +0 -32
  326. package/models/harvester/kubevirt.io.virtualmachine.js +0 -850
  327. package/models/harvester/kubevirt.io.virtualmachineinstance.js +0 -142
  328. package/models/harvester/management.cattle.io.managedchart.js +0 -191
  329. package/models/harvester/management.cattle.io.setting.js +0 -40
  330. package/models/harvester/network.harvesterhci.io.clusternetwork.js +0 -100
  331. package/models/harvester/network.harvesterhci.io.nodenetwork.js +0 -34
  332. package/models/harvester/node.js +0 -255
  333. package/models/harvester/persistentvolumeclaim.js +0 -166
  334. package/models/harvester/pod.js +0 -185
  335. package/pages/c/_cluster/harvester/airgapupgrade/index.vue +0 -309
  336. package/pages/c/_cluster/harvester/console/_uid/serial.vue +0 -51
  337. package/pages/c/_cluster/harvester/console/_uid/vnc.vue +0 -52
  338. package/pages/c/_cluster/harvester/index.vue +0 -24
  339. package/pages/c/_cluster/harvester/support/index.vue +0 -154
  340. package/pages/plugins.vue +0 -387
  341. package/pkg/model-loader.lib.js +0 -3
  342. package/promptRemove/kubevirt.io.virtualmachine.vue +0 -164
  343. package/server/verdaccio-middleware.js +0 -56
  344. package/store/harvester-common.js +0 -126
  345. package/utils/validators/vm-datavolumes.js +0 -38
  346. package/utils/validators/vm-image.js +0 -32
  347. package/utils/validators/vm.js +0 -221
@@ -13,14 +13,36 @@ import { Banner } from '@components/Banner';
13
13
  import { get } from '@shell/utils/object';
14
14
  import { mapGetters } from 'vuex';
15
15
  import {
16
- HCI, NAMESPACE, MANAGEMENT, CONFIG_MAP, NORMAN, NODE
16
+ HCI,
17
+ NAMESPACE,
18
+ MANAGEMENT,
19
+ CONFIG_MAP,
20
+ NORMAN,
21
+ NODE
17
22
  } from '@shell/config/types';
18
23
  import { base64Decode, base64Encode } from '@shell/utils/crypto';
19
24
  import { allHashSettled } from '@shell/utils/promise';
20
25
  import { podAffinity as podAffinityValidator } from '@shell/utils/validators/pod-affinity';
21
26
  import { stringify, exceptionToErrorsArray } from '@shell/utils/error';
22
27
  import { HCI as HCI_ANNOTATIONS } from '@shell/config/labels-annotations';
23
- import { isReady } from '@shell/models/harvester/harvesterhci.io.virtualmachineimage';
28
+
29
+ export function isReady() {
30
+ function getStatusConditionOfType(type, defaultValue = []) {
31
+ const conditions = Array.isArray(get(this, 'status.conditions')) ? this.status.conditions : defaultValue;
32
+
33
+ return conditions.find( cond => cond.type === type);
34
+ }
35
+
36
+ const initialized = getStatusConditionOfType.call(this, 'Initialized');
37
+ const imported = getStatusConditionOfType.call(this, 'Imported');
38
+ const isCompleted = this.status?.progress === 100;
39
+
40
+ if ([initialized?.status, imported?.status].includes('False')) {
41
+ return false;
42
+ } else {
43
+ return isCompleted && true;
44
+ }
45
+ }
24
46
 
25
47
  export default {
26
48
  name: 'ConfigComponentHarvester',
@@ -34,12 +56,12 @@ export default {
34
56
  props: {
35
57
  credentialId: {
36
58
  type: String,
37
- required: true,
59
+ required: true
38
60
  },
39
61
 
40
62
  uuid: {
41
63
  type: String,
42
- required: true,
64
+ required: true
43
65
  },
44
66
 
45
67
  disabled: {
@@ -49,47 +71,55 @@ export default {
49
71
 
50
72
  poolIndex: {
51
73
  type: Number,
52
- required: true,
74
+ required: true
53
75
  },
54
76
 
55
77
  machinePools: {
56
78
  type: Array,
57
79
  default: () => []
58
- },
80
+ }
59
81
  },
60
82
 
61
83
  async fetch() {
62
84
  this.errors = [];
63
85
 
64
86
  try {
65
- this.credential = await this.$store.dispatch('rancher/find', { type: NORMAN.CLOUD_CREDENTIAL, id: this.credentialId });
87
+ this.credential = await this.$store.dispatch('rancher/find', {
88
+ type: NORMAN.CLOUD_CREDENTIAL,
89
+ id: this.credentialId
90
+ });
66
91
  const clusterId = get(this.credential, 'decodedData.clusterId');
67
92
 
68
93
  const url = `/k8s/clusters/${ clusterId }/v1`;
69
94
 
70
- const isImportCluster = this.credential.decodedData.clusterType === 'imported';
95
+ const isImportCluster =
96
+ this.credential.decodedData.clusterType === 'imported';
71
97
 
72
98
  this.isImportCluster = isImportCluster;
73
99
 
74
100
  if (clusterId && isImportCluster) {
75
101
  const res = await allHashSettled({
76
- namespaces: this.$store.dispatch('harvester/findAll', { type: NAMESPACE, opt: { url: `${ url }/${ NAMESPACE }s` } }),
102
+ namespaces: this.$store.dispatch('cluster/request', { url: `${ url }/${ NAMESPACE }s` }),
77
103
  images: this.$store.dispatch('cluster/request', { url: `${ url }/${ HCI.IMAGE }s` }),
78
104
  configMaps: this.$store.dispatch('cluster/request', { url: `${ url }/${ CONFIG_MAP }s` }),
79
105
  networks: this.$store.dispatch('cluster/request', { url: `${ url }/k8s.cni.cncf.io.network-attachment-definitions` }),
80
106
  });
81
107
 
82
- for ( const key of Object.keys(res) ) {
108
+ for (const key of Object.keys(res)) {
83
109
  const obj = res[key];
84
110
 
85
- if ( obj.status === 'rejected' ) {
111
+ if (obj.status === 'rejected') {
86
112
  this.errors.push(stringify(obj.reason));
87
113
  continue;
88
114
  }
89
115
  }
90
116
 
91
- if (this.errors.length > 0) { // If an error is reported in the request data, see if it is due to a cluster error
92
- const cluster = await this.$store.dispatch('management/find', { type: MANAGEMENT.CLUSTER, id: clusterId });
117
+ if (this.errors.length > 0) {
118
+ // If an error is reported in the request data, see if it is due to a cluster error
119
+ const cluster = await this.$store.dispatch('management/find', {
120
+ type: MANAGEMENT.CLUSTER,
121
+ id: clusterId
122
+ });
93
123
 
94
124
  if (cluster.stateDescription && !cluster.isReady) {
95
125
  this.errors = [cluster.stateDescription];
@@ -100,7 +130,8 @@ export default {
100
130
  const networkDataOptions = [];
101
131
 
102
132
  (res.configMaps.value?.data || []).map((O) => {
103
- const cloudTemplate = O.metadata?.labels?.[HCI_ANNOTATIONS.CLOUD_INIT];
133
+ const cloudTemplate =
134
+ O.metadata?.labels?.[HCI_ANNOTATIONS.CLOUD_INIT];
104
135
 
105
136
  if (cloudTemplate === 'user') {
106
137
  userDataOptions.push({
@@ -120,7 +151,7 @@ export default {
120
151
  this.userDataOptions = userDataOptions;
121
152
  this.networkDataOptions = networkDataOptions;
122
153
  this.images = res.images.value?.data;
123
- this.networkOptions = (res.networks.value?.data || []).map( (O) => {
154
+ this.networkOptions = (res.networks.value?.data || []).map((O) => {
124
155
  let value;
125
156
  let label;
126
157
 
@@ -139,8 +170,10 @@ export default {
139
170
  };
140
171
  });
141
172
 
142
- (res.namespaces.value || []).forEach((namespace) => {
143
- if (!namespace.isSystem) {
173
+ (res.namespaces.value.data || []).forEach(async(namespace) => {
174
+ const proxyNamespace = await this.$store.dispatch('cluster/create', namespace);
175
+
176
+ if (!proxyNamespace.isSystem && namespace.links.update) {
144
177
  const value = namespace.metadata.name;
145
178
  const label = namespace.metadata.name;
146
179
 
@@ -239,11 +272,11 @@ export default {
239
272
 
240
273
  namespaceDisabled() {
241
274
  return this.disabledEdit || this.poolIndex > 0;
242
- },
275
+ }
243
276
  },
244
277
 
245
278
  watch: {
246
- 'credentialId'() {
279
+ credentialId() {
247
280
  if (!this.isEdit) {
248
281
  this.imageOptions = [];
249
282
  this.networkOptions = [];
@@ -277,7 +310,7 @@ export default {
277
310
  this.value.vmNamespace = vmNamespace;
278
311
  }
279
312
  },
280
- deep: true,
313
+ deep: true
281
314
  }
282
315
  },
283
316
 
@@ -288,43 +321,57 @@ export default {
288
321
  const errors = [];
289
322
 
290
323
  if (!this.value.cpuCount) {
291
- const message = this.validatorRequiredField(this.t('cluster.credential.harvester.cpu'));
324
+ const message = this.validatorRequiredField(
325
+ this.t('cluster.credential.harvester.cpu')
326
+ );
292
327
 
293
328
  errors.push(message);
294
329
  }
295
330
 
296
331
  if (!this.value.vmNamespace) {
297
- const message = this.validatorRequiredField(this.t('cluster.credential.harvester.namespace'));
332
+ const message = this.validatorRequiredField(
333
+ this.t('cluster.credential.harvester.namespace')
334
+ );
298
335
 
299
336
  errors.push(message);
300
337
  }
301
338
 
302
339
  if (!this.value.memorySize) {
303
- const message = this.validatorRequiredField(this.t('cluster.credential.harvester.memory'));
340
+ const message = this.validatorRequiredField(
341
+ this.t('cluster.credential.harvester.memory')
342
+ );
304
343
 
305
344
  errors.push(message);
306
345
  }
307
346
 
308
347
  if (!this.value.diskSize) {
309
- const message = this.validatorRequiredField(this.t('cluster.credential.harvester.disk'));
348
+ const message = this.validatorRequiredField(
349
+ this.t('cluster.credential.harvester.disk')
350
+ );
310
351
 
311
352
  errors.push(message);
312
353
  }
313
354
 
314
355
  if (!this.value.imageName) {
315
- const message = this.validatorRequiredField(this.t('cluster.credential.harvester.image'));
356
+ const message = this.validatorRequiredField(
357
+ this.t('cluster.credential.harvester.image')
358
+ );
316
359
 
317
360
  errors.push(message);
318
361
  }
319
362
 
320
363
  if (!this.value.sshUser) {
321
- const message = this.validatorRequiredField(this.t('cluster.credential.harvester.sshUser'));
364
+ const message = this.validatorRequiredField(
365
+ this.t('cluster.credential.harvester.sshUser')
366
+ );
322
367
 
323
368
  errors.push(message);
324
369
  }
325
370
 
326
371
  if (!this.value.networkName) {
327
- const message = this.validatorRequiredField(this.t('cluster.credential.harvester.network'));
372
+ const message = this.validatorRequiredField(
373
+ this.t('cluster.credential.harvester.network')
374
+ );
328
375
 
329
376
  errors.push(message);
330
377
  }
@@ -384,7 +431,7 @@ export default {
384
431
 
385
432
  this.updateScheduling(this.vmAffinity);
386
433
  }
387
- },
434
+ }
388
435
  };
389
436
  </script>
390
437
 
@@ -447,7 +494,9 @@ export default {
447
494
  :required="true"
448
495
  :disabled="namespaceDisabled"
449
496
  label-key="cluster.credential.harvester.namespace"
450
- :placeholder="t('cluster.harvester.machinePool.namespace.placeholder')"
497
+ :placeholder="
498
+ t('cluster.harvester.machinePool.namespace.placeholder')
499
+ "
451
500
  />
452
501
 
453
502
  <LabeledInput
@@ -457,7 +506,9 @@ export default {
457
506
  :required="true"
458
507
  :mode="mode"
459
508
  :disabled="namespaceDisabled"
460
- :placeholder="t('cluster.harvester.machinePool.namespace.placeholder')"
509
+ :placeholder="
510
+ t('cluster.harvester.machinePool.namespace.placeholder')
511
+ "
461
512
  />
462
513
  </div>
463
514
  </div>
@@ -470,7 +521,7 @@ export default {
470
521
  :options="imageOptions"
471
522
  :required="true"
472
523
  :searchable="true"
473
- :disabled="disabledEdit"
524
+ :disabled="disabled"
474
525
  label-key="cluster.credential.harvester.image"
475
526
  :placeholder="t('cluster.harvester.machinePool.image.placeholder')"
476
527
  @on-open="onOpen"
@@ -485,7 +536,9 @@ export default {
485
536
  :required="true"
486
537
  :disabled="disabledEdit"
487
538
  label-key="cluster.credential.harvester.network"
488
- :placeholder="t('cluster.harvester.machinePool.network.placeholder')"
539
+ :placeholder="
540
+ t('cluster.harvester.machinePool.network.placeholder')
541
+ "
489
542
  />
490
543
  </div>
491
544
  </div>
@@ -522,7 +575,9 @@ export default {
522
575
  :required="true"
523
576
  :mode="mode"
524
577
  :disabled="disabled"
525
- :placeholder="t('cluster.harvester.machinePool.sshUser.placeholder')"
578
+ :placeholder="
579
+ t('cluster.harvester.machinePool.sshUser.placeholder')
580
+ "
526
581
  tooltip-key="cluster.harvester.machinePool.sshUser.toolTip"
527
582
  />
528
583
  </div>
@@ -574,7 +629,7 @@ export default {
574
629
  />
575
630
  </div>
576
631
 
577
- <h3>{{ t("cluster.credential.harvester.networkData.title") }}</h3>
632
+ <h3>{{ t('cluster.credential.harvester.networkData.title') }}</h3>
578
633
  <div>
579
634
  <LabeledSelect
580
635
  v-if="isImportCluster && isCreate"
@@ -599,29 +654,23 @@ export default {
599
654
  </portal>
600
655
  </div>
601
656
  <div v-if="errors.length">
602
- <div
603
- v-for="(err, idx) in errors"
604
- :key="idx"
605
- >
606
- <Banner
607
- color="error"
608
- :label="stringify(err.Message || err)"
609
- />
657
+ <div v-for="(err, idx) in errors" :key="idx">
658
+ <Banner color="error" :label="stringify(err.Message || err)" />
610
659
  </div>
611
660
  </div>
612
661
  </div>
613
662
  </template>
614
663
 
615
664
  <style lang="scss" scoped>
616
- $yaml-height: 200px;
617
-
618
- ::v-deep .yaml-editor{
619
- flex: 1;
665
+ $yaml-height: 200px;
666
+
667
+ ::v-deep .yaml-editor {
668
+ flex: 1;
669
+ min-height: $yaml-height;
670
+ & .code-mirror .CodeMirror {
671
+ position: initial;
672
+ height: auto;
620
673
  min-height: $yaml-height;
621
- & .code-mirror .CodeMirror {
622
- position: initial;
623
- height: auto;
624
- min-height: $yaml-height;
625
- }
626
674
  }
675
+ }
627
676
  </style>
@@ -10,10 +10,10 @@ import { applyProducts } from '@shell/store/type-map';
10
10
  import { findBy } from '@shell/utils/array';
11
11
  import { ClusterNotFoundError } from '@shell/utils/error';
12
12
  import { get } from '@shell/utils/object';
13
+ import { setFavIcon, haveSetFavIcon } from '@shell/utils/favicon';
14
+ import dynamicPluginLoader from '@shell/pkg/dynamic-plugin-loader';
13
15
  import { AFTER_LOGIN_ROUTE, WORKSPACE } from '@shell/store/prefs';
14
- import { NAME as VIRTUAL } from '@shell/config/product/harvester';
15
16
  import { BACK_TO } from '@shell/config/local-storage';
16
- import { setFavIcon, haveSetFavIcon } from '@shell/utils/favicon';
17
17
  import { NAME as FLEET_NAME } from '@shell/config/product/fleet.js';
18
18
 
19
19
  const getPackageFromRoute = (route) => {
@@ -28,7 +28,7 @@ const getPackageFromRoute = (route) => {
28
28
 
29
29
  let beforeEachSetup = false;
30
30
 
31
- function getProduct(to) {
31
+ export function getProductFromRoute(to) {
32
32
  let product = to.params?.product;
33
33
 
34
34
  if ( !product ) {
@@ -43,7 +43,7 @@ function getProduct(to) {
43
43
  }
44
44
 
45
45
  function setProduct(store, to) {
46
- let product = getProduct(to);
46
+ let product = getProductFromRoute(to);
47
47
 
48
48
  if ( !product ) {
49
49
  product = EXPLORER;
@@ -66,7 +66,7 @@ function setProduct(store, to) {
66
66
  }
67
67
 
68
68
  export default async function({
69
- route, app, store, redirect, $cookies, req, isDev, from, $plugin
69
+ route, app, store, redirect, $cookies, req, isDev, from, $plugin, next
70
70
  }) {
71
71
  if ( route.path && typeof route.path === 'string') {
72
72
  // Ignore webpack hot module reload requests
@@ -245,10 +245,8 @@ export default async function({
245
245
  window.location.href = backTo;
246
246
  }
247
247
  }
248
-
249
248
  // Load stuff
250
249
  await applyProducts(store, $plugin);
251
-
252
250
  // Setup a beforeEach hook once to keep track of the current product
253
251
  if ( !beforeEachSetup ) {
254
252
  beforeEachSetup = true;
@@ -276,10 +274,10 @@ export default async function({
276
274
  let clusterId = get(route, 'params.cluster');
277
275
 
278
276
  const pkg = getPackageFromRoute(route);
279
- const product = getProduct(route);
277
+ const product = getProductFromRoute(route);
280
278
 
281
279
  const oldPkg = getPackageFromRoute(from);
282
- const oldProduct = getProduct(from);
280
+ const oldProduct = getProductFromRoute(from);
283
281
 
284
282
  // Leave an old pkg where we weren't before?
285
283
  const oldPkgPlugin = oldPkg ? Object.values($plugin.getPlugins()).find(p => p.name === oldPkg) : null;
@@ -316,6 +314,24 @@ export default async function({
316
314
  });
317
315
  }
318
316
 
317
+ if (!route.matched?.length) {
318
+ // If there are no matching routes we could be trying to nav to a page belonging to a dynamic plugin which needs loading
319
+ await Promise.all([
320
+ ...always,
321
+ ]);
322
+
323
+ // If a plugin claims the route and is loaded correctly we'll get a route back
324
+ const newLocation = await dynamicPluginLoader.check({ route, store });
325
+
326
+ // If we have a new location, double check that it's actually valid
327
+ const resolvedRoute = newLocation ? store.app.router.resolve(newLocation) : null;
328
+
329
+ if (resolvedRoute?.route.matched.length) {
330
+ // Note - don't use `redirect` or `store.app.route` (breaks feature by failing to run middleware in default layout)
331
+ return next(newLocation);
332
+ }
333
+ }
334
+
319
335
  // Ensure that the activeNamespaceCache is updated given the change of context either from or to a place where it uses workspaces
320
336
  // When fleet moves to it's own package this should be moved to pkg onEnter/onLeave
321
337
  if ((oldProduct === FLEET_NAME || product === FLEET_NAME) && oldProduct !== product) {
@@ -327,49 +343,37 @@ export default async function({
327
343
  });
328
344
  }
329
345
 
330
- if (product === VIRTUAL || route.name === `c-cluster-${ VIRTUAL }` || route.name?.startsWith(`c-cluster-${ VIRTUAL }-`)) {
331
- setProduct(store, route);
332
- const res = [
333
- ...always,
334
- store.dispatch('loadVirtual', {
335
- id: clusterId,
336
- oldProduct,
337
- }),
338
- ];
339
-
340
- await Promise.all(res);
341
- } else {
342
- // Always run loadCluster, it handles 'unload' as well
343
- // Run them in parallel
344
- await Promise.all([
345
- ...always,
346
- store.dispatch('loadCluster', {
347
- id: clusterId,
348
- oldPkg: oldPkgPlugin,
349
- newPkg: newPkgPlugin,
350
- product,
351
- oldProduct,
352
- })]);
353
-
354
- if (!clusterId) {
355
- clusterId = store.getters['defaultClusterId']; // This needs the cluster list, so no parallel
356
- const isSingleProduct = store.getters['isSingleProduct'];
357
-
358
- if (isSingleProduct?.afterLoginRoute) {
359
- const value = {
360
- name: 'c-cluster-product',
361
- ...isSingleProduct.afterLoginRoute,
362
- params: {
363
- cluster: clusterId,
364
- ...isSingleProduct.afterLoginRoute?.params
365
- },
366
- };
367
-
368
- await store.dispatch('prefs/set', {
369
- key: AFTER_LOGIN_ROUTE,
370
- value,
371
- });
372
- }
346
+ // Always run loadCluster, it handles 'unload' as well
347
+ // Run them in parallel
348
+ await Promise.all([
349
+ ...always,
350
+ store.dispatch('loadCluster', {
351
+ id: clusterId,
352
+ oldPkg: oldPkgPlugin,
353
+ newPkg: newPkgPlugin,
354
+ product,
355
+ oldProduct,
356
+ })
357
+ ]);
358
+
359
+ if (!clusterId) {
360
+ clusterId = store.getters['defaultClusterId']; // This needs the cluster list, so no parallel
361
+ const isSingleProduct = store.getters['isSingleProduct'];
362
+
363
+ if (isSingleProduct?.afterLoginRoute) {
364
+ const value = {
365
+ name: 'c-cluster-product',
366
+ ...isSingleProduct.afterLoginRoute,
367
+ params: {
368
+ cluster: clusterId,
369
+ ...isSingleProduct.afterLoginRoute?.params
370
+ },
371
+ };
372
+
373
+ await store.dispatch('prefs/set', {
374
+ key: AFTER_LOGIN_ROUTE,
375
+ value,
376
+ });
373
377
  }
374
378
  }
375
379
  } catch (e) {
@@ -1,5 +1,5 @@
1
1
  import { getAllValues } from '@shell/utils/object';
2
- import formRulesGenerator from '@shell/utils/validators/formRules';
2
+ import formRulesGenerator from '@shell/utils/validators/formRules/index';
3
3
 
4
4
  export default {
5
5
  data() {
@@ -2,7 +2,7 @@ import { mapGetters } from 'vuex';
2
2
  import {
3
3
  COUNT, MANAGEMENT, POD, WORKLOAD_TYPES, WORKLOAD, SECRET
4
4
  } from '@shell/config/types';
5
- import { SETTING } from '@shell/config/settings';
5
+ import { SETTING, DEFAULT_PERF_SETTING } from '@shell/config/settings';
6
6
 
7
7
  // Number of pages to fetch when loading incrementally
8
8
  const PAGES = 4;
@@ -33,6 +33,8 @@ export default {
33
33
  } catch (e) {
34
34
  console.warn('ui-performance setting contains invalid data'); // eslint-disable-line no-console
35
35
  }
36
+ } else {
37
+ perfConfig = DEFAULT_PERF_SETTING;
36
38
  }
37
39
 
38
40
  return {
@@ -0,0 +1,34 @@
1
+ import SteveModel from '@shell/plugins/steve/steve-class';
2
+
3
+ const CACHED_STATUS = 'cached';
4
+
5
+ export default class UIPlugin extends SteveModel {
6
+ get name() {
7
+ return this.spec?.plugin?.name;
8
+ }
9
+
10
+ get description() {
11
+ return this.spec?.plugin?.description;
12
+ }
13
+
14
+ get version() {
15
+ return this.spec?.plugin?.version;
16
+ }
17
+
18
+ get willBeCached() {
19
+ return this.spec?.plugin?.noCache === false;
20
+ }
21
+
22
+ // Has the plugin been cached?
23
+ get isCached() {
24
+ return !this.willBeCached || (this.willBeCached && this.status?.cacheState === CACHED_STATUS);
25
+ }
26
+
27
+ get pluginMetadata() {
28
+ return this.spec?.plugin?.metadata || {};
29
+ }
30
+
31
+ get isDeveloper() {
32
+ return this.pluginMetadata?.developer === 'true';
33
+ }
34
+ }
@@ -153,6 +153,14 @@ export default class ClusterNode extends SteveModel {
153
153
  }
154
154
 
155
155
  get cpuUsage() {
156
+ /*
157
+ With EKS nodes that have been migrated from norman,
158
+ cpu/memory usage is by the annotation `management.cattle.io/pod-requests`
159
+ */
160
+ if ( this.isFromNorman && this.provider === 'eks' ) {
161
+ return parseSi(this.podRequests.cpu || '0');
162
+ }
163
+
156
164
  return parseSi(this.$rootGetters['cluster/byId'](METRIC.NODE, this.id)?.usage?.cpu || '0');
157
165
  }
158
166
 
@@ -165,6 +173,10 @@ export default class ClusterNode extends SteveModel {
165
173
  }
166
174
 
167
175
  get ramUsage() {
176
+ if ( this.isFromNorman && this.provider === 'eks' ) {
177
+ return parseSi(this.podRequests.memory || '0');
178
+ }
179
+
168
180
  return parseSi(this.$rootGetters['cluster/byId'](METRIC.NODE, this.id)?.usage?.memory || '0');
169
181
  }
170
182
 
@@ -192,6 +204,10 @@ export default class ClusterNode extends SteveModel {
192
204
  return this.pods.length;
193
205
  }
194
206
 
207
+ get podRequests() {
208
+ return JSON.parse(this.metadata.annotations['management.cattle.io/pod-requests'] || '{}');
209
+ }
210
+
195
211
  get isPidPressureOk() {
196
212
  return this.isCondition('PIDPressure', 'False');
197
213
  }
@@ -368,14 +384,13 @@ export default class ClusterNode extends SteveModel {
368
384
  }
369
385
 
370
386
  get canDelete() {
371
- const provider = this.$rootGetters['currentCluster'].provisioner.toLowerCase();
372
387
  const cloudProviders = [
373
388
  'aks', 'azureaks', 'azurekubernetesservice',
374
389
  'eks', 'amazoneks',
375
390
  'gke', 'googlegke'
376
391
  ];
377
392
 
378
- return !cloudProviders.includes(provider);
393
+ return !cloudProviders.includes(this.provider);
379
394
  }
380
395
 
381
396
  // You need to preload CAPI.MACHINEs to use this
@@ -389,6 +404,14 @@ export default class ClusterNode extends SteveModel {
389
404
 
390
405
  return null;
391
406
  }
407
+
408
+ get isFromNorman() {
409
+ return (this.$rootGetters['currentCluster'].metadata.labels || {})['cattle.io/creator'] === 'norman';
410
+ }
411
+
412
+ get provider() {
413
+ return this.$rootGetters['currentCluster'].provisioner.toLowerCase();
414
+ }
392
415
  }
393
416
 
394
417
  function calculatePercentage(allocatable, capacity) {