@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
package/store/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import Steve from '@shell/plugins/steve';
2
2
  import {
3
- COUNT, NAMESPACE, NORMAN, MANAGEMENT, FLEET, UI, VIRTUAL_HARVESTER_PROVIDER, HCI, DEFAULT_WORKSPACE
3
+ COUNT, NAMESPACE, NORMAN, MANAGEMENT, FLEET, UI, VIRTUAL_HARVESTER_PROVIDER, DEFAULT_WORKSPACE
4
4
  } from '@shell/config/types';
5
5
  import { CLUSTER as CLUSTER_PREF, NAMESPACE_FILTERS, LAST_NAMESPACE, WORKSPACE } from '@shell/store/prefs';
6
6
  import { allHash, allHashSettled } from '@shell/utils/promise';
@@ -14,7 +14,6 @@ import { setBrand, setVendor } from '@shell/config/private-label';
14
14
  import { addParam } from '@shell/utils/url';
15
15
  import { SETTING } from '@shell/config/settings';
16
16
  import semver from 'semver';
17
- import { NAME as VIRTUAL } from '@shell/config/product/harvester';
18
17
  import { BACK_TO } from '@shell/config/local-storage';
19
18
  import { STEVE_MODEL_TYPES } from '@shell/plugins/steve/getters';
20
19
  import { BY_TYPE } from '@shell/plugins/dashboard-store/classify';
@@ -52,12 +51,6 @@ export const plugins = [
52
51
  supportsStream: false, // The norman API doesn't support streaming
53
52
  modelBaseClass: STEVE_MODEL_TYPES.NORMAN,
54
53
  }),
55
- Steve({
56
- namespace: 'harvester',
57
- baseUrl: '', // URL is dynamically set for the selected cluster
58
- supportsStream: false, // true, -- Disabled due to report that it's sometimes much slower in Chrome
59
- }),
60
-
61
54
  ];
62
55
 
63
56
  const getActiveNamespaces = (state, getters) => {
@@ -450,47 +443,14 @@ export const getters = {
450
443
  return '/';
451
444
  },
452
445
 
453
- isSingleProduct(state, rootGetters) {
446
+ isSingleProduct(state) {
454
447
  if (state.isSingleProduct !== undefined) {
455
448
  return state.isSingleProduct;
456
449
  }
457
450
 
458
- if (rootGetters.isSingleVirtualCluster) {
459
- return {
460
- logo: require('~shell/assets/images/providers/harvester.svg'),
461
- productNameKey: 'product.harvester',
462
- version: rootGetters['harvester/byId'](HCI.SETTING, 'server-version')?.value,
463
- afterLoginRoute: {
464
- name: 'c-cluster-product',
465
- params: { product: VIRTUAL },
466
- },
467
- logoRoute: {
468
- name: 'c-cluster-product-resource',
469
- params: {
470
- product: VIRTUAL,
471
- resource: HCI.DASHBOARD,
472
- }
473
- },
474
- enableSessionCheck: true
475
- };
476
- }
477
-
478
451
  return false;
479
452
  },
480
453
 
481
- isSingleVirtualCluster(state, getters, rootState, rootGetters) {
482
- const clusterId = getters.defaultClusterId;
483
- const cluster = rootGetters['management/byId'](MANAGEMENT.CLUSTER, clusterId);
484
-
485
- return !getters.isMultiCluster && cluster?.status?.provider === VIRTUAL_HARVESTER_PROVIDER;
486
- },
487
-
488
- isMultiVirtualCluster(state, getters, rootState, rootGetters) {
489
- const localCluster = rootGetters['management/byId'](MANAGEMENT.CLUSTER, 'local');
490
-
491
- return getters.isMultiCluster && localCluster?.status?.provider !== VIRTUAL_HARVESTER_PROVIDER;
492
- },
493
-
494
454
  isVirtualCluster(state, getters) {
495
455
  const cluster = getters['currentCluster'];
496
456
 
@@ -509,9 +469,7 @@ export const mutations = {
509
469
  state.clusterReady = ready;
510
470
  },
511
471
 
512
- updateNamespaces(state, getters) {
513
- const { filters, all } = getters;
514
-
472
+ updateNamespaces(state, { filters, all }) {
515
473
  state.namespaceFilters = filters.filter(x => !!x);
516
474
 
517
475
  if ( all ) {
@@ -644,7 +602,7 @@ export const actions = {
644
602
  }
645
603
 
646
604
  res = await allHash(promises);
647
-
605
+ dispatch('i18n/init');
648
606
  let isMultiCluster = true;
649
607
 
650
608
  if ( res.clusters.length === 1 && res.clusters[0].metadata?.name === 'local' ) {
@@ -701,11 +659,6 @@ export const actions = {
701
659
  return;
702
660
  }
703
661
 
704
- if (oldProduct === VIRTUAL) {
705
- await dispatch('harvester/unsubscribe');
706
- commit('harvester/reset');
707
- }
708
-
709
662
  const oldPkgClusterStore = oldPkg?.stores.find(
710
663
  s => getters[`${ s.storeName }/isClusterStore`]
711
664
  )?.storeName;
@@ -767,7 +720,6 @@ export const actions = {
767
720
  // If we've entered a new store ensure everything has loaded correctly
768
721
  if (newPkgClusterStore) {
769
722
  // Mirror actions on the 'cluster' store for our specific pkg `cluster` store
770
- dispatch(`${ newPkgClusterStore }/loadSchemas`, true);
771
723
  await dispatch(`${ newPkgClusterStore }/loadCluster`, { id });
772
724
 
773
725
  commit('clusterReady', true);
@@ -872,135 +824,6 @@ export const actions = {
872
824
  commit('updateNamespaces', { filters: ids, ...getters });
873
825
  },
874
826
 
875
- async loadVirtual({
876
- state, commit, dispatch, getters
877
- }, { id, oldProduct }) {
878
- const isMultiCluster = getters['isMultiCluster'];
879
-
880
- if (isMultiCluster && id === 'local') {
881
- return;
882
- }
883
-
884
- if ( state.clusterId && state.clusterId === id && oldProduct === VIRTUAL) {
885
- // Do nothing, we're already connected/connecting to this cluster
886
- return;
887
- }
888
-
889
- if (oldProduct !== VIRTUAL) {
890
- await dispatch('cluster/unsubscribe');
891
- commit('cluster/reset');
892
- }
893
-
894
- if ( state.clusterId && id ) {
895
- commit('clusterReady', false);
896
-
897
- await dispatch('harvester/unsubscribe');
898
- commit('harvester/reset');
899
-
900
- await dispatch('management/watch', {
901
- type: MANAGEMENT.PROJECT,
902
- namespace: state.clusterId,
903
- stop: true
904
- });
905
-
906
- commit('management/forgetType', MANAGEMENT.PROJECT);
907
- }
908
-
909
- if (id) {
910
- commit('clusterId', id);
911
- }
912
-
913
- console.log(`Loading ${ isMultiCluster ? 'ECM ' : '' }cluster...`); // eslint-disable-line no-console
914
-
915
- // This is a workaround for a timing issue where the mgmt cluster schema may not be available
916
- // Try and wait until the schema exists before proceeding
917
- await dispatch('management/waitForSchema', { type: MANAGEMENT.CLUSTER });
918
-
919
- // See if it really exists
920
- const cluster = await dispatch('management/find', {
921
- type: MANAGEMENT.CLUSTER,
922
- id,
923
- opt: { url: `${ MANAGEMENT.CLUSTER }s/${ escape(id) }` }
924
- });
925
-
926
- let virtualBase = `/k8s/clusters/${ escape(id) }/v1/harvester`;
927
-
928
- if (id === 'local') {
929
- virtualBase = `/v1/harvester`;
930
- }
931
-
932
- if ( !cluster ) {
933
- commit('clusterId', null);
934
- commit('harvester/applyConfig', { baseUrl: null });
935
- throw new ClusterNotFoundError(id);
936
- }
937
-
938
- // Update the Steve client URLs
939
- commit('harvester/applyConfig', { baseUrl: virtualBase });
940
-
941
- await Promise.all([
942
- dispatch('harvester/loadSchemas', true),
943
- ]);
944
-
945
- dispatch('harvester/subscribe');
946
-
947
- let isRancher = false;
948
- const projectArgs = {
949
- type: MANAGEMENT.PROJECT,
950
- opt: {
951
- url: `${ MANAGEMENT.PROJECT }/${ escape(id) }`,
952
- watchNamespace: id
953
- }
954
- };
955
-
956
- if (getters['management/schemaFor'](MANAGEMENT.PROJECT)) {
957
- isRancher = true;
958
- }
959
-
960
- if (id !== 'local' && getters['harvester/schemaFor'](MANAGEMENT.SETTING)) { // multi-cluster
961
- const settings = await dispatch('harvester/findAll', {
962
- type: MANAGEMENT.SETTING,
963
- id: SETTING.SYSTEM_NAMESPACES,
964
- opt: { url: `${ virtualBase }/${ MANAGEMENT.SETTING }s/`, force: true }
965
- });
966
-
967
- const systemNamespaces = settings?.find(x => x.id === SETTING.SYSTEM_NAMESPACES);
968
-
969
- if (systemNamespaces) {
970
- const namespace = (systemNamespaces.value || systemNamespaces.default)?.split(',');
971
-
972
- commit('setSystemNamespaces', namespace);
973
- }
974
- }
975
-
976
- const hash = {
977
- projects: isRancher && dispatch('management/findAll', projectArgs),
978
- virtualCount: dispatch('harvester/findAll', { type: COUNT }),
979
- virtualNamespaces: dispatch('harvester/findAll', { type: NAMESPACE }),
980
- settings: dispatch('harvester/findAll', { type: HCI.SETTING }),
981
- };
982
-
983
- if (getters['harvester/schemaFor'](HCI.UPGRADE)) {
984
- hash.upgrades = dispatch('harvester/findAll', { type: HCI.UPGRADE });
985
- }
986
-
987
- const res = await allHash(hash);
988
-
989
- await dispatch('cleanNamespaces');
990
-
991
- const filters = getters['prefs/get'](NAMESPACE_FILTERS)?.[id];
992
-
993
- commit('updateNamespaces', {
994
- filters: filters || [ALL_USER],
995
- all: res.virtualNamespaces,
996
- ...getters
997
- });
998
-
999
- commit('clusterReady', true);
1000
-
1001
- console.log('Done loading virtual cluster.'); // eslint-disable-line no-console
1002
- },
1003
-
1004
827
  async cleanNamespaces({ getters, dispatch }) {
1005
828
  // Initialise / Remove any filters that the user no-longer has access to
1006
829
  await dispatch('management/findAll', { type: MANAGEMENT.CLUSTER }); // So they can be got byId below
package/store/prefs.js CHANGED
@@ -4,12 +4,18 @@ import { clone } from '@shell/utils/object';
4
4
  import { SETTING } from '@shell/config/settings';
5
5
 
6
6
  const definitions = {};
7
+ /**
8
+ * Key/value of prefrences are stored before login here and cookies due lack of access permission.
9
+ * Once user is logged in while setting asUserPreference, update stored before login Key/value to the backend in loadServer function.
10
+ */
11
+ let prefsBeforeLogin = {};
7
12
 
8
13
  export const create = function(name, def, opt = {}) {
9
14
  const parseJSON = opt.parseJSON === true;
10
15
  const asCookie = opt.asCookie === true;
11
16
  const asUserPreference = opt.asUserPreference !== false;
12
17
  const options = opt.options;
18
+ const inheritFrom = opt.inheritFrom;
13
19
 
14
20
  definitions[name] = {
15
21
  def,
@@ -17,6 +23,7 @@ export const create = function(name, def, opt = {}) {
17
23
  parseJSON,
18
24
  asCookie,
19
25
  asUserPreference,
26
+ inheritFrom, // if value is not defined on server, we can default it to another pref
20
27
  mangleRead: opt.mangleRead, // Alter the value read from the API (to match old Rancher expectations)
21
28
  mangleWrite: opt.mangleWrite, // Alter the value written back to the API (ditto)
22
29
  };
@@ -67,6 +74,7 @@ export const HIDE_REPOS = create('hide-repos', [], { parseJSON });
67
74
  export const HIDE_DESC = create('hide-desc', [], { parseJSON });
68
75
  export const HIDE_SENSITIVE = create('hide-sensitive', true, { options: [true, false], parseJSON });
69
76
  export const SHOW_PRE_RELEASE = create('show-pre-release', false, { options: [false, true], parseJSON });
77
+ export const SHOW_CHART_MODE = create('chartMode', 'featured', { parseJSON });
70
78
 
71
79
  export const DATE_FORMAT = create('date-format', 'ddd, MMM D YYYY', {
72
80
  options: [
@@ -86,12 +94,18 @@ export const TIME_FORMAT = create('time-format', 'h:mm:ss a', {
86
94
  });
87
95
 
88
96
  export const TIME_ZONE = create('time-zone', 'local');
97
+ // DEV will be deprecated on v2.7.0, but is needed so that we can grab the value for the new settings that derived from it
98
+ // such as: VIEW_IN_API, ALL_NAMESPACES, THEME_SHORTCUT
89
99
  export const DEV = create('dev', false, { parseJSON });
100
+ export const VIEW_IN_API = create('view-in-api', false, { parseJSON, inheritFrom: DEV });
101
+ export const ALL_NAMESPACES = create('all-namespaces', false, { parseJSON, inheritFrom: DEV });
102
+ export const THEME_SHORTCUT = create('theme-shortcut', false, { parseJSON, inheritFrom: DEV });
90
103
  export const LAST_VISITED = create('last-visited', 'home', { parseJSON });
91
104
  export const SEEN_WHATS_NEW = create('seen-whatsnew', '', { parseJSON });
92
105
  export const READ_WHATS_NEW = create('read-whatsnew', '', { parseJSON });
93
106
  export const AFTER_LOGIN_ROUTE = create('after-login-route', 'home', { parseJSON } );
94
107
  export const HIDE_HOME_PAGE_CARDS = create('home-page-cards', {}, { parseJSON } );
108
+ export const PLUGIN_DEVELOPER = create('plugin-developer', false, { parseJSON, inheritFrom: DEV }); // Is the user a plugin developer?
95
109
 
96
110
  export const _RKE1 = 'rke1';
97
111
  export const _RKE2 = 'rke2';
@@ -100,6 +114,9 @@ export const PROVISIONER = create('provisioner', _RKE1, { options: [_RKE1, _RKE2
100
114
  // Promo for Cluster Tools feature on Cluster Dashboard page
101
115
  export const CLUSTER_TOOLS_TIP = create('hide-cluster-tools-tip', false, { parseJSON });
102
116
 
117
+ // Promo for Pod Security Policies (PSPs) being deprecated on kube version 1.25 on Cluster Dashboard page
118
+ export const PSP_DEPRECATION_BANNER = create('hide-psp-deprecation-banner', false, { parseJSON });
119
+
103
120
  // Maximum number of clusters to show in the slide-in menu
104
121
  export const MENU_MAX_CLUSTERS = create('menu-max-clusters', 4, { options: [2, 3, 4, 5, 6, 7, 8, 9, 10], parseJSON });
105
122
 
@@ -243,7 +260,7 @@ export const mutations = {
243
260
  };
244
261
 
245
262
  export const actions = {
246
- async set({ dispatch, commit }, opt) {
263
+ async set({ dispatch, commit, rootGetters }, opt) {
247
264
  let { key, value } = opt; // eslint-disable-line prefer-const
248
265
  const definition = definitions[key];
249
266
  let server;
@@ -264,6 +281,15 @@ export const actions = {
264
281
  }
265
282
 
266
283
  if ( definition.asUserPreference ) {
284
+ const checkLogin = rootGetters['auth/loggedIn'];
285
+
286
+ // Check for login status
287
+ if (!checkLogin) {
288
+ prefsBeforeLogin[key] = value;
289
+
290
+ return;
291
+ }
292
+
267
293
  try {
268
294
  server = await dispatch('loadServer', key); // There's no watch on prefs, so get before set...
269
295
 
@@ -373,7 +399,9 @@ export const actions = {
373
399
  }
374
400
  },
375
401
 
376
- async loadServer({ state, dispatch, commit }, ignoreKey) {
402
+ async loadServer( {
403
+ state, dispatch, commit, rootState, rootGetters
404
+ }, ignoreKey) {
377
405
  let server = { data: {} };
378
406
 
379
407
  try {
@@ -399,10 +427,26 @@ export const actions = {
399
427
  return;
400
428
  }
401
429
 
430
+ // if prefsBeforeLogin has values from login page, update the backend
431
+ if (Object.keys(prefsBeforeLogin).length > 0) {
432
+ Object.keys(prefsBeforeLogin).forEach((key) => {
433
+ server.data[key] = prefsBeforeLogin[key];
434
+ });
435
+
436
+ await server.save({ redirectUnauthorized: false });
437
+
438
+ // Clear prefsBeforeLogin, as we have now saved theses
439
+ prefsBeforeLogin = {};
440
+ }
441
+
402
442
  for (const key in definitions) {
403
443
  const definition = definitions[key];
404
444
  let value = clone(server.data[key]);
405
445
 
446
+ if (value === undefined && definition.inheritFrom) {
447
+ value = clone(server.data[definition.inheritFrom]);
448
+ }
449
+
406
450
  if ( value === undefined || key === ignoreKey) {
407
451
  continue;
408
452
  }
package/store/type-map.js CHANGED
@@ -41,6 +41,7 @@
41
41
  // public, -- If true, show to all users. If false, only show when the Developer Tools pref is on (default true)
42
42
  // category, -- Group to show the product in for the nav hamburger menu
43
43
  // typeStoreMap, -- An object mapping types to the store that should be used to retrieve information about the type
44
+ // hideSystemResources -- Hide resources in namespaces where namespace.isSystem === true, or a namespace managed by fleet (per its annotation) and hide those namespaces from ns/project list and nsfilter (default false)
44
45
  // })
45
46
  //
46
47
  // externalLink(stringOrFn) The product has an external page (function gets context object
@@ -121,7 +122,7 @@
121
122
  // )
122
123
  import { AGE, NAME, NAMESPACE as NAMESPACE_COL, STATE } from '@shell/config/table-headers';
123
124
  import { COUNT, SCHEMA, MANAGEMENT, NAMESPACE } from '@shell/config/types';
124
- import { DEV, EXPANDED_GROUPS, FAVORITE_TYPES } from '@shell/store/prefs';
125
+ import { VIEW_IN_API, EXPANDED_GROUPS, FAVORITE_TYPES } from '@shell/store/prefs';
125
126
  import {
126
127
  addObject, findBy, insertAt, isArray, removeObject, filterBy
127
128
  } from '@shell/utils/array';
@@ -130,8 +131,7 @@ import {
130
131
  ensureRegex, escapeHtml, escapeRegex, ucFirst, pluralize
131
132
  } from '@shell/utils/string';
132
133
  import {
133
- importList, importDetail, importEdit, listProducts, loadProduct, importCustomPromptRemove, resolveList, resolveEdit, resolveWindowComponent, importWindowComponent, resolveDetail
134
-
134
+ importChart, importList, importDetail, importEdit, listProducts, loadProduct, importCustomPromptRemove, resolveList, resolveEdit, resolveWindowComponent, importWindowComponent, resolveChart, resolveDetail, importDialog
135
135
  } from '@shell/utils/dynamic-importer';
136
136
 
137
137
  import { NAME as EXPLORER } from '@shell/config/product/explorer';
@@ -167,8 +167,8 @@ export const IF_HAVE = {
167
167
  NO_PROJECT: 'no-project',
168
168
  NOT_V1_ISTIO: 'not-v1-istio',
169
169
  MULTI_CLUSTER: 'multi-cluster',
170
- HARVESTER_SINGLE_CLUSTER: 'harv-multi-cluster',
171
170
  NEUVECTOR_NAMESPACE: 'neuvector-namespace',
171
+ ADMIN: 'admin-user',
172
172
  };
173
173
 
174
174
  export function DSL(store, product, module = 'type-map') {
@@ -217,7 +217,7 @@ export function DSL(store, product, module = 'type-map') {
217
217
  headers(type, headers) {
218
218
  headers.forEach((header) => {
219
219
  // If on the client, then use the value getter if there is one
220
- if (process.client && header.getValue) {
220
+ if (header.getValue) {
221
221
  header.value = header.getValue;
222
222
  }
223
223
 
@@ -361,6 +361,7 @@ export const state = function() {
361
361
  groupLabel: {},
362
362
  ignore: {},
363
363
  list: {},
364
+ chart: {},
364
365
  detail: {},
365
366
  edit: {},
366
367
  componentFor: {},
@@ -803,7 +804,7 @@ export const getters = {
803
804
  const module = findBy(state.products, 'name', product).inStore;
804
805
  const schemas = rootGetters[`${ module }/all`](SCHEMA);
805
806
  const counts = rootGetters[`${ module }/all`](COUNT)?.[0]?.counts || {};
806
- const isDev = rootGetters['prefs/get'](DEV);
807
+ const isDev = rootGetters['prefs/get'](VIEW_IN_API);
807
808
  const isBasic = mode === BASIC;
808
809
 
809
810
  const out = {};
@@ -1056,6 +1057,14 @@ export const getters = {
1056
1057
  };
1057
1058
  },
1058
1059
 
1060
+ hasCustomChart(state, getters, rootState) {
1061
+ return (rawType) => {
1062
+ const key = getters.componentFor(rawType);
1063
+
1064
+ return hasCustom(state, rootState, 'chart', key, key => resolveChart(key));
1065
+ };
1066
+ },
1067
+
1059
1068
  hasCustomDetail(state, getters, rootState) {
1060
1069
  return (rawType, subType) => {
1061
1070
  const key = getters.componentFor(rawType, subType);
@@ -1090,24 +1099,11 @@ export const getters = {
1090
1099
  };
1091
1100
  },
1092
1101
 
1093
- hasCustomPromptRemove(state, getters) {
1094
- return (rawType) => {
1095
- const type = getters.componentFor(rawType);
1096
-
1097
- const cache = state.cache.promptRemove;
1098
-
1099
- if ( cache[type] !== undefined ) {
1100
- return cache[type];
1101
- }
1102
-
1103
- try {
1104
- require.resolve(`@shell/promptRemove/${ type }`);
1105
- cache[type] = true;
1106
- } catch (e) {
1107
- cache[type] = false;
1108
- }
1102
+ hasCustomPromptRemove(state, getters, rootState) {
1103
+ return (rawType, subType) => {
1104
+ const key = getters.componentFor(rawType, subType);
1109
1105
 
1110
- return cache[type];
1106
+ return hasCustom(state, rootState, 'promptRemove', key, () => require.resolve(`@shell/promptRemove/${ key }`));
1111
1107
  };
1112
1108
  },
1113
1109
 
@@ -1125,12 +1121,24 @@ export const getters = {
1125
1121
  };
1126
1122
  },
1127
1123
 
1124
+ importDialog(state, getters, rootState) {
1125
+ return (rawType, subType) => {
1126
+ return loadExtension(rootState, 'dialog', getters.componentFor(rawType, subType), importDialog);
1127
+ };
1128
+ },
1129
+
1128
1130
  importList(state, getters, rootState) {
1129
1131
  return (rawType) => {
1130
1132
  return loadExtension(rootState, 'list', getters.componentFor(rawType), importList);
1131
1133
  };
1132
1134
  },
1133
1135
 
1136
+ importChart(state, getters, rootState) {
1137
+ return (rawType) => {
1138
+ return loadExtension(rootState, 'chart', getters.componentFor(rawType), importChart);
1139
+ };
1140
+ },
1141
+
1134
1142
  importDetail(state, getters, rootState) {
1135
1143
  return (rawType, subType) => {
1136
1144
  return loadExtension(rootState, 'detail', getters.componentFor(rawType, subType), importDetail);
@@ -1143,11 +1151,9 @@ export const getters = {
1143
1151
  };
1144
1152
  },
1145
1153
 
1146
- importCustomPromptRemove(state, getters) {
1147
- return (rawType) => {
1148
- const type = getters.componentFor(rawType);
1149
-
1150
- return importCustomPromptRemove(type);
1154
+ importCustomPromptRemove(state, getters, rootState) {
1155
+ return (rawType, subType) => {
1156
+ return loadExtension(rootState, 'promptRemove', getters.componentFor(rawType, subType), importCustomPromptRemove);
1151
1157
  };
1152
1158
  },
1153
1159
 
@@ -1225,7 +1231,7 @@ export const getters = {
1225
1231
  activeProducts(state, getters, rootState, rootGetters) {
1226
1232
  const knownTypes = {};
1227
1233
  const knownGroups = {};
1228
- const isDev = rootGetters['prefs/get'](DEV);
1234
+ const isDev = rootGetters['prefs/get'](VIEW_IN_API);
1229
1235
 
1230
1236
  if ( state.schemaGeneration < 0 ) {
1231
1237
  // This does nothing, but makes activeProducts depend on schemaGeneration
@@ -1554,7 +1560,7 @@ export const mutations = {
1554
1560
  let obj = { ...options, match };
1555
1561
 
1556
1562
  if ( idx >= 0 ) {
1557
- obj = Object.assign(obj, state.typeOptions[idx]);
1563
+ obj = Object.assign(state.typeOptions[idx], obj);
1558
1564
  state.typeOptions.splice(idx, 1, obj);
1559
1565
  } else {
1560
1566
  const obj = Object.assign({}, options, { match });
@@ -1739,17 +1745,25 @@ function ifHave(getters, option) {
1739
1745
  case IF_HAVE.MULTI_CLUSTER: {
1740
1746
  return getters.isMultiCluster;
1741
1747
  }
1742
- case IF_HAVE.HARVESTER_SINGLE_CLUSTER: {
1743
- return getters.isSingleVirtualCluster;
1744
- }
1745
1748
  case IF_HAVE.NEUVECTOR_NAMESPACE: {
1746
1749
  return getters[`cluster/all`](NAMESPACE).find(n => n.metadata.name === NEU_VECTOR_NAMESPACE);
1747
1750
  }
1751
+ case IF_HAVE.ADMIN: {
1752
+ return isAdminUser(getters);
1753
+ }
1748
1754
  default:
1749
1755
  return false;
1750
1756
  }
1751
1757
  }
1752
1758
 
1759
+ // Could list a larger set of resources that typically only an admin user would have
1760
+ export function isAdminUser(getters) {
1761
+ const canEditSettings = (getters['management/schemaFor'](MANAGEMENT.SETTING)?.resourceMethods || []).includes('PUT');
1762
+ const canEditFeatureFlags = (getters['management/schemaFor'](MANAGEMENT.FEATURE)?.resourceMethods || []).includes('PUT');
1763
+
1764
+ return canEditSettings && canEditFeatureFlags;
1765
+ }
1766
+
1753
1767
  // Is V1 Istio installed?
1754
1768
  function isV1Istio(getters) {
1755
1769
  const cluster = getters['currentCluster'];
@@ -3,20 +3,22 @@
3
3
 
4
4
  // import { addObject, removeObject } from '@shell/utils/array';
5
5
 
6
- import { allHash } from '@shell/utils/promise';
7
6
  import { Plugin } from '@shell/core/plugin';
8
7
 
9
8
  interface UIPluginState {
10
9
  plugins: Plugin[],
11
- catalog: any[],
12
- catalogs: string[],
10
+ errors: any,
11
+ }
12
+
13
+ interface LoadError {
14
+ name: string,
15
+ error: boolean,
13
16
  }
14
17
 
15
18
  export const state = function(): UIPluginState {
16
19
  return {
17
20
  plugins: [],
18
- catalog: [],
19
- catalogs: [''],
21
+ errors: {},
20
22
  };
21
23
  };
22
24
 
@@ -25,16 +27,16 @@ export const getters = {
25
27
  return state.plugins;
26
28
  },
27
29
 
28
- catalog: (state: any) => {
29
- return state.catalog;
30
- },
31
-
32
- catalogs: (state: any) => {
33
- return state.catalogs;
30
+ errors: (state: any) => {
31
+ return state.errors;
34
32
  },
35
33
  };
36
34
 
37
35
  export const mutations = {
36
+ setError(state: UIPluginState, error: LoadError) {
37
+ state.errors[error.name] = error.error;
38
+ },
39
+
38
40
  addPlugin(state: UIPluginState, plugin: Plugin) {
39
41
  // TODO: Duplicates?
40
42
  state.plugins.push(plugin);
@@ -47,59 +49,11 @@ export const mutations = {
47
49
  state.plugins.splice(index, 1);
48
50
  }
49
51
  },
50
-
51
- setCatalog(state: UIPluginState, catalog: any) {
52
- state.catalog = catalog;
53
- },
54
-
55
- addCatalog(state: UIPluginState, catalog: string) {
56
- state.catalogs.push(catalog);
57
- }
58
52
  };
59
53
 
60
54
  export const actions = {
61
- addCatalog( { commit, dispatch }: any, url: string ) {
62
- commit('addCatalog', url);
63
- },
64
-
65
- // This is just for PoC - we wouldn't get the catalog from Verdaccio
66
- // This fetches the catalog each time
67
- async loadCatalogs( { getters, commit, dispatch }: any) {
68
- const packages: any[] = [];
69
- const catalogHash = {} as any;
70
- const catalogs = getters['catalogs'];
71
-
72
- catalogs.forEach((url: string) => {
73
- const base = url;
74
-
75
- if (!url) {
76
- url = '/verdaccio/data/packages';
77
- } else {
78
- url = `/uiplugins-catalog/?${ url }`;
79
- }
80
-
81
- try {
82
- catalogHash[base] = dispatch('rancher/request', { url }, { root: true });
83
- } catch (err) {
84
- // Ignore errors... or all plugins fail
85
- console.warn('Unable to fetch catalog: ', url, err); // eslint-disable-line no-console
86
- }
87
- });
88
-
89
- const res = await allHash(catalogHash);
90
-
91
- Object.keys(res as any).forEach((r: string) => {
92
- const v: any = (res as any)[r];
93
-
94
- v.forEach((p: any) => {
95
- p.location = r;
96
- packages.push(p);
97
- });
98
- });
99
-
100
- const uiPackages = packages.filter((pkg: any) => pkg.rancher);
101
-
102
- commit('setCatalog', uiPackages);
55
+ setError( { commit }: any, error: LoadError ) {
56
+ commit('setError', error);
103
57
  },
104
58
 
105
59
  addPlugin({ commit }: any, plugin: Plugin) {