@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/edit/service.vue CHANGED
@@ -22,7 +22,7 @@ import HarvesterServiceAddOnConfig from '@shell/components/HarvesterServiceAddOn
22
22
  import { clone } from '@shell/utils/object';
23
23
  import { POD, CAPI } from '@shell/config/types';
24
24
  import { matching } from '@shell/utils/selector';
25
- import { NAME as HARVESTER } from '@shell/config/product/harvester';
25
+ import { HARVESTER_NAME as HARVESTER } from '@shell/config/product/harvester-manager';
26
26
  import { allHash } from '@shell/utils/promise';
27
27
  import { isHarvesterSatisfiesVersion } from '@shell/utils/cluster';
28
28
  import { Port } from '@shell/utils/validators/formRules';
@@ -198,7 +198,8 @@ export default {
198
198
  },
199
199
 
200
200
  watch: {
201
- 'value.spec.selector': 'updateMatchingPods',
201
+ 'value.metadata.namespace': 'updateMatchingPods',
202
+ 'value.spec.selector': 'updateMatchingPods',
202
203
  'value.spec.sessionAffinity'(val) {
203
204
  if (val === 'ClientIP') {
204
205
  this.value.spec.sessionAffinityConfig = { clientIP: { timeoutSeconds: null } };
@@ -240,21 +241,22 @@ export default {
240
241
 
241
242
  methods: {
242
243
  updateMatchingPods: throttle(function() {
243
- const { allPods, value: { spec: { selector = { } } } } = this;
244
+ const { value: { spec: { selector = { } } } } = this;
245
+ const allInNamespace = this.allPods.filter(pod => pod.metadata.namespace === this.value?.metadata?.namespace);
244
246
 
245
247
  if (isEmpty(selector)) {
246
248
  this.matchingPods = {
247
249
  matched: 0,
248
- total: allPods.length,
250
+ total: allInNamespace.length,
249
251
  none: true,
250
252
  sample: null,
251
253
  };
252
254
  } else {
253
- const match = matching(allPods, selector);
255
+ const match = matching(allInNamespace, selector);
254
256
 
255
257
  this.matchingPods = {
256
258
  matched: match.length,
257
- total: allPods.length,
259
+ total: allInNamespace.length,
258
260
  none: match.length === 0,
259
261
  sample: match[0] ? match[0].nameDisplay : null,
260
262
  };
@@ -26,6 +26,7 @@ describe('component: Upgrading', () => {
26
26
  });
27
27
 
28
28
  // TODO: #6179: Integrate test with component fix, as the scope is not to check the value of the input
29
+ // eslint-disable-next-line jest/no-disabled-tests
29
30
  it.skip.each([
30
31
  ['surge', 'maxSurge', '%'],
31
32
  ['unavailable', 'maxUnavailable', '%'],
@@ -1,16 +1,12 @@
1
1
  <script>
2
- import WorkloadGeneric from './types/Generic';
3
- import WorkloadDeployment from './types/Deployment';
4
-
2
+ import CreateEditView from '@shell/mixins/create-edit-view';
3
+ import FormValidation from '@shell/mixins/form-validation';
5
4
  import WorkLoadMixin from '@shell/edit/workload/mixins/workload';
6
5
 
7
6
  export default {
8
- name: 'CruWorkload',
9
- components: {
10
- WorkloadGeneric,
11
- WorkloadDeployment
12
- },
13
- props: {
7
+ name: 'WorkloadDeployments',
8
+ mixins: [CreateEditView, FormValidation, WorkLoadMixin], // The order here is important since WorkLoadMixin contains some FormValidation configuration
9
+ props: {
14
10
  value: {
15
11
  type: Object,
16
12
  required: true,
@@ -21,14 +17,378 @@ export default {
21
17
  default: 'create',
22
18
  },
23
19
  },
24
- mixins: [WorkLoadMixin],
20
+ data() {
21
+ return { selectedName: null };
22
+ },
23
+ methods: {
24
+ changed(tab) {
25
+ this.selectedName = tab.selectedName;
26
+ const container = this.containerOptions.find( c => c.name === tab.selectedName);
27
+
28
+ if ( container ) {
29
+ this.selectContainer(container);
30
+ }
31
+ }
32
+ }
25
33
  };
26
34
  </script>
27
35
 
28
36
  <template>
29
- <div>
30
- <Loading v-if="$fetchState.pending" />
31
- <WorkloadDeployment v-else-if="isDeployment" :mode="mode" :value="value" />
32
- <WorkloadGeneric v-else :mode="mode" :value="value" />
33
- </div>
37
+ <Loading v-if="$fetchState.pending" />
38
+ <form v-else class="filled-height">
39
+ <CruResource
40
+ :validation-passed="fvFormIsValid"
41
+ :selected-subtype="type"
42
+ :resource="value"
43
+ :mode="mode"
44
+ :errors="fvUnreportedValidationErrors"
45
+ :done-route="doneRoute"
46
+ :subtypes="workloadSubTypes"
47
+ :apply-hooks="applyHooks"
48
+ :value="value"
49
+ @finish="save"
50
+ @select-type="selectType"
51
+ @error="e=>errors = e"
52
+ >
53
+ <!-- <pre>{{ JSON.stringify(allContainers, null, 2) }}</pre> -->
54
+ <NameNsDescription
55
+ :value="value"
56
+ :mode="mode"
57
+ :rules="{name: fvGetAndReportPathRules('metadata.name'), namespace: fvGetAndReportPathRules('metadata.namespace'), description: []}"
58
+ @change="name=value.metadata.name"
59
+ />
60
+ <div v-if="isCronJob || isReplicable || isStatefulSet || containerOptions.length > 1" class="row mb-20">
61
+ <div v-if="isCronJob" class="col span-3">
62
+ <LabeledInput
63
+ v-model="spec.schedule"
64
+ type="cron"
65
+ required
66
+ :mode="mode"
67
+ :label="t('workload.cronSchedule')"
68
+ :rules="fvGetAndReportPathRules('spec.schedule')"
69
+ placeholder="0 * * * *"
70
+ />
71
+ </div>
72
+ <div v-if="isReplicable" class="col span-3">
73
+ <LabeledInput
74
+ v-model.number="spec.replicas"
75
+ type="number"
76
+ min="0"
77
+ required
78
+ :mode="mode"
79
+ :label="t('workload.replicas')"
80
+ />
81
+ </div>
82
+ <div v-if="isStatefulSet" class="col span-3">
83
+ <LabeledSelect
84
+ v-model="spec.serviceName"
85
+ option-label="metadata.name"
86
+ :reduce="service=>service.metadata.name"
87
+ :mode="mode"
88
+ :label="t('workload.serviceName')"
89
+ :options="headlessServices"
90
+ required
91
+ />
92
+ </div>
93
+ </div>
94
+ <Tabbed class="deployment-tabs" :show-tabs-add-remove="true" :default-tab="defaultTab" @changed="changed">
95
+ <Tab
96
+ v-for="(tab, i) in allContainers"
97
+ :key="i+tab.name"
98
+ :label="tab.name"
99
+ :name="tab.name"
100
+ :weight="tab.weight"
101
+ :error="!!tab.error"
102
+ >
103
+ <Tabbed :side-tabs="true" :weight="99">
104
+ <Tab :label="t('workload.container.titles.general')" name="general" :weight="tabWeightMap['general']" :error="tabErrors.general">
105
+ <template #tab-header-right class="tab-content-controls">
106
+ <button v-if="allContainers.length > 1 && !isView" type="button" class="btn-sm role-link" @click="removeContainer(tab)">
107
+ {{ t('workload.container.removeContainer') }}
108
+ </button>
109
+ </template>
110
+ <div>
111
+ <div :style="{'align-items':'center'}" class="row mb-20">
112
+ <div class="col span-6">
113
+ <LabeledInput v-model="container.name" :mode="mode" :label="t('workload.container.containerName')" />
114
+ </div>
115
+ <div class="col span-6">
116
+ <RadioGroup
117
+ :mode="mode"
118
+ :value="isInitContainer"
119
+ name="initContainer"
120
+ :options="[true, false]"
121
+ :labels="[t('workload.container.init'), t('workload.container.standard')]"
122
+ @input="updateInitContainer"
123
+ />
124
+ </div>
125
+ </div>
126
+ <h3>{{ t('workload.container.titles.image') }}</h3>
127
+ <div class="row mb-20">
128
+ <div class="col span-6">
129
+ <LabeledInput
130
+ v-model.trim="container.image"
131
+ :mode="mode"
132
+ :label="t('workload.container.image')"
133
+ :placeholder="t('generic.placeholder', {text: 'nginx:latest'}, true)"
134
+ :rules="fvGetAndReportPathRules('image')"
135
+ />
136
+ </div>
137
+ <div class="col span-6">
138
+ <LabeledSelect
139
+ v-model="container.imagePullPolicy"
140
+ :label="t('workload.container.imagePullPolicy')"
141
+ :options="pullPolicyOptions"
142
+ :mode="mode"
143
+ />
144
+ </div>
145
+ </div>
146
+ <div class="row">
147
+ <div class="col span-6">
148
+ <LabeledSelect
149
+ v-model="imagePullSecrets"
150
+ :label="t('workload.container.imagePullSecrets')"
151
+ :multiple="true"
152
+ :taggable="true"
153
+ :options="imagePullNamespacedSecrets"
154
+ :mode="mode"
155
+ option-label="metadata.name"
156
+ :reduce="service=>service.metadata.name"
157
+ :create-option="createOption"
158
+ />
159
+ </div>
160
+ </div>
161
+ </div>
162
+ <div class="spacer" />
163
+ <div>
164
+ <h3>{{ t('workload.container.titles.ports') }}</h3>
165
+ <div class="row">
166
+ <WorkloadPorts v-model="allContainers[i].ports" :name="value.metadata.name" :services="servicesOwned" :mode="mode" />
167
+ </div>
168
+ </div>
169
+ <div class="spacer" />
170
+ <div>
171
+ <h3>{{ t('workload.container.titles.command') }}</h3>
172
+ <Command v-model="allContainers[i]" :secrets="namespacedSecrets" :config-maps="namespacedConfigMaps" :mode="mode" />
173
+ </div>
174
+ <ServiceNameSelect
175
+ :value="podTemplateSpec.serviceAccountName"
176
+ :mode="mode"
177
+ :select-label="t('workload.serviceAccountName.label')"
178
+ :select-placeholder="t('workload.serviceAccountName.label')"
179
+ :options="namespacedServiceNames"
180
+ option-label="metadata.name"
181
+ @input="updateServiceAccount"
182
+ />
183
+ <div class="spacer" />
184
+ <div>
185
+ <h3>{{ t('workload.container.titles.lifecycle') }}</h3>
186
+ <LifecycleHooks v-model="allContainers[i].lifecycle" :mode="mode" />
187
+ </div>
188
+ </Tab>
189
+ <Tab :label="t('workload.container.titles.resources')" name="resources" :weight="tabWeightMap['resources']">
190
+ <!-- Resources and Limitations -->
191
+ <ContainerResourceLimit v-model="flatResources" :mode="mode" :show-tip="false" />
192
+ </Tab>
193
+
194
+ <Tab v-if="!isInitContainer" :label="t('workload.container.titles.healthCheck')" name="healthCheck" :weight="tabWeightMap['healthCheck']">
195
+ <HealthCheck :value="allContainers[i]" :mode="mode" @input="Object.assign(allContainers[i], $event)" />
196
+ </Tab>
197
+ <Tab :label="t('workload.container.titles.securityContext')" name="securityContext" :weight="tabWeightMap['securityContext']">
198
+ <Security v-model="allContainers[i].securityContext" :mode="mode" />
199
+ </Tab>
200
+ <Tab :label="t('workload.storage.title')" name="storage" :weight="tabWeightMap['storage']">
201
+ <ContainerMountPaths
202
+ v-model="podTemplateSpec"
203
+ :namespace="value.metadata.namespace"
204
+ :register-before-hook="registerBeforeHook"
205
+ :mode="mode"
206
+ :secrets="namespacedSecrets"
207
+ :config-maps="namespacedConfigMaps"
208
+ :container="allContainers[i]"
209
+ :save-pvc-hook-name="savePvcHookName"
210
+ @removePvcForm="clearPvcFormState"
211
+ />
212
+ </Tab>
213
+ </Tabbed>
214
+ </Tab>
215
+ <Tab v-if="!isPod" :label="nameDisplayFor(type)" :name="nameDisplayFor(type)" :weight="99">
216
+ <Tabbed :side-tabs="true">
217
+ <Tab name="labels" label-key="generic.labelsAndAnnotations" :weight="tabWeightMap['labels']">
218
+ <Labels v-model="value" :mode="mode" />
219
+ </Tab>
220
+ <Tab :label="t('workload.container.titles.upgrading')" name="upgrading" :weight="tabWeightMap['upgrading']">
221
+ <Job v-if="isJob || isCronJob" v-model="spec" :mode="mode" :type="type" />
222
+ <Upgrading v-else v-model="spec" :mode="mode" :type="type" :no-pod-spec="true" />
223
+ </Tab>
224
+ </Tabbed>
225
+ </Tab>
226
+ <Tab :label="t('workload.tabs.labels.pod')" :name="'pod'" :weight="98">
227
+ <Tabbed :side-tabs="true">
228
+ <Tab :label="t('workload.storage.title')" name="storage" :weight="tabWeightMap['storage']">
229
+ <Storage
230
+ v-model="podTemplateSpec"
231
+ :namespace="value.metadata.namespace"
232
+ :register-before-hook="registerBeforeHook"
233
+ :mode="mode"
234
+ :secrets="namespacedSecrets"
235
+ :config-maps="namespacedConfigMaps"
236
+ :save-pvc-hook-name="savePvcHookName"
237
+ @removePvcForm="clearPvcFormState"
238
+ />
239
+ </Tab>
240
+ <Tab :label="t('workload.container.titles.resources')" name="resources" :weight="tabWeightMap['resources']">
241
+ <template>
242
+ <div>
243
+ <h3 class="mb-10">
244
+ <t k="workload.scheduling.titles.tolerations" />
245
+ </h3>
246
+ <div class="row">
247
+ <Tolerations v-model="podTemplateSpec.tolerations" :mode="mode" />
248
+ </div>
249
+ </div>
250
+
251
+ <div>
252
+ <div class="spacer" />
253
+ <h3 class="mb-10">
254
+ <t k="workload.scheduling.titles.priority" />
255
+ </h3>
256
+ <div class="row">
257
+ <div class="col span-6">
258
+ <LabeledInput v-model.number="podTemplateSpec.priority" :mode="mode" :label="t('workload.scheduling.priority.priority')" />
259
+ </div>
260
+ <div class="col span-6">
261
+ <LabeledInput v-model="podTemplateSpec.priorityClassName" :mode="mode" :label="t('workload.scheduling.priority.className')" />
262
+ </div>
263
+ </div>
264
+ </div>
265
+ </template>
266
+ </Tab>
267
+ <Tab :label="t('workload.container.titles.podScheduling')" name="podScheduling" :weight="tabWeightMap['podScheduling']">
268
+ <PodAffinity :mode="mode" :value="podTemplateSpec" :nodes="allNodeObjects" />
269
+ </Tab>
270
+ <Tab :label="t('workload.container.titles.nodeScheduling')" name="nodeScheduling" :weight="tabWeightMap['nodeScheduling']">
271
+ <NodeScheduling :mode="mode" :value="podTemplateSpec" :nodes="allNodes" />
272
+ </Tab>
273
+ <Tab :label="t('workload.container.titles.upgrading')" name="upgrading" :weight="tabWeightMap['upgrading']">
274
+ <Job v-if="isJob || isCronJob" v-model="spec" :mode="mode" :type="type" />
275
+ <Upgrading v-else v-model="spec" :mode="mode" :type="type" :no-deployment-spec="true" />
276
+ </Tab>
277
+ <Tab :label="t('workload.container.titles.securityContext')" name="securityContext" :weight="tabWeightMap['securityContext']">
278
+ <div>
279
+ <h3>{{ t('workload.container.security.podFsGroup') }}</h3>
280
+ <div class="row">
281
+ <div class="col span-6">
282
+ <LabeledInput v-model.number="podFsGroup" type="number" :mode="mode" :label="t('workload.container.security.fsGroup')" />
283
+ </div>
284
+ </div>
285
+ </div>
286
+ </Tab>
287
+ <Tab :label="t('workload.container.titles.networking')" name="networking" :weight="tabWeightMap['networking']">
288
+ <Networking v-model="podTemplateSpec" :mode="mode" />
289
+ </Tab>
290
+ <Tab v-if="isStatefulSet" :label="t('workload.container.titles.volumeClaimTemplates')" name="volumeClaimTemplates" :weight="tabWeightMap['volumeClaimTemplates']">
291
+ <VolumeClaimTemplate v-model="spec" :mode="mode" />
292
+ </Tab>
293
+ <Tab name="labels" label-key="generic.labelsAndAnnotations" :weight="tabWeightMap['labels']">
294
+ <div>
295
+ <h3>{{ t('workload.container.titles.podLabels') }}</h3>
296
+ <div class="row mb-20">
297
+ <KeyValue
298
+ key="labels"
299
+ v-model="podLabels"
300
+ :add-label="t('labels.addLabel')"
301
+ :mode="mode"
302
+ :read-allowed="false"
303
+ :protip="false"
304
+ />
305
+ </div>
306
+ <div class="spacer" />
307
+ <h3>{{ t('workload.container.titles.podAnnotations') }}</h3>
308
+ <div class="row">
309
+ <KeyValue
310
+ key="annotations"
311
+ v-model="podAnnotations"
312
+ :add-label="t('labels.addAnnotation')"
313
+ :mode="mode"
314
+ :read-allowed="false"
315
+ :protip="false"
316
+ />
317
+ </div>
318
+ </div>
319
+ </Tab>
320
+ </Tabbed>
321
+ </Tab>
322
+ <template #tab-row-extras>
323
+ <li class="tablist-controls">
324
+ <button v-if="!isView" type="button" class="btn-sm role-link" @click="addContainerBtn">
325
+ <i class="icon icon-plus icon-lg" /> {{ t('workload.container.addContainer') }}
326
+ </button>
327
+ </li>
328
+ </template>
329
+ </Tabbed>
330
+ </CruResource>
331
+ </form>
34
332
  </template>
333
+
334
+ <style lang='scss'>
335
+ .container-row {
336
+ display: flex;
337
+ align-items: center;
338
+ margin-bottom: 20px;
339
+ }
340
+
341
+ .type-placeholder {
342
+ color: white;
343
+ font-size: 2.5em;
344
+ height: 100%;
345
+ width: 100%;
346
+ background-color: var(--primary);
347
+ display: flex;
348
+ justify-content: center;
349
+ align-items: center;
350
+ }
351
+
352
+ .type-description {
353
+ color: var(--input-label);
354
+ }
355
+
356
+ .next-dropdown {
357
+ display: inline-block;
358
+ }
359
+
360
+ .tab-external-controls {
361
+ display: flex;
362
+ justify-content: right;
363
+ }
364
+
365
+ .tab-content-controls {
366
+ display: flex;
367
+ justify-content: right;
368
+ }
369
+
370
+ .tablist-controls {
371
+ .role-link {
372
+ padding: 10px 15px;
373
+ min-height: unset;
374
+ line-height: unset;
375
+
376
+ &:focus {
377
+ background: none;
378
+ box-shadow: none;
379
+ }
380
+
381
+ &:hover {
382
+ border: none;
383
+ }
384
+ }
385
+
386
+ }
387
+
388
+ .deployment-tabs {
389
+ > .tabs.horizontal {
390
+ border-bottom: 1px solid var(--border);
391
+ margin-bottom: 10px;
392
+ }
393
+ }
394
+ </style>
@@ -9,6 +9,7 @@ import {
9
9
  PVC,
10
10
  SERVICE_ACCOUNT,
11
11
  CAPI,
12
+ POD,
12
13
  } from '@shell/config/types';
13
14
  import Tab from '@shell/components/Tabbed/Tab';
14
15
  import CreateEditView from '@shell/mixins/create-edit-view';
@@ -36,6 +37,7 @@ import CruResource from '@shell/components/CruResource';
36
37
  import Command from '@shell/components/form/Command';
37
38
  import LifecycleHooks from '@shell/components/form/LifecycleHooks';
38
39
  import Storage from '@shell/edit/workload/storage';
40
+ import ContainerMountPaths from '@shell/edit/workload/storage/ContainerMountPaths.vue';
39
41
  import Labels from '@shell/components/form/Labels';
40
42
  import { RadioGroup } from '@components/Form/Radio';
41
43
  import { UI_MANAGED } from '@shell/config/labels-annotations';
@@ -43,6 +45,7 @@ import { removeObject } from '@shell/utils/array';
43
45
  import { BEFORE_SAVE_HOOKS } from '@shell/mixins/child-hook';
44
46
  import NameNsDescription from '@shell/components/form/NameNsDescription';
45
47
  import formRulesGenerator from '@shell/utils/validators/formRules';
48
+ import { TYPES as SECRET_TYPES } from '@shell/models/secret';
46
49
 
47
50
  const TAB_WEIGHT_MAP = {
48
51
  general: 99,
@@ -88,6 +91,7 @@ export default {
88
91
  Upgrading,
89
92
  VolumeClaimTemplate,
90
93
  WorkloadPorts,
94
+ ContainerMountPaths
91
95
  },
92
96
 
93
97
  mixins: [CreateEditView],
@@ -102,6 +106,15 @@ export default {
102
106
  type: String,
103
107
  default: 'create',
104
108
  },
109
+
110
+ createOption: {
111
+ default: (text) => {
112
+ if (text) {
113
+ return { metadata: { name: text } };
114
+ }
115
+ },
116
+ type: Function
117
+ },
105
118
  },
106
119
 
107
120
  async fetch() {
@@ -148,21 +161,42 @@ export default {
148
161
 
149
162
  if (!this.value.spec) {
150
163
  this.value.spec = {};
164
+ if (this.value.type === POD) {
165
+ const podContainers = [{
166
+ imagePullPolicy: 'Always',
167
+ name: `container-0`,
168
+ }];
169
+
170
+ const podSpec = { template: { spec: { containers: podContainers, initContainers: [] } } };
171
+
172
+ this.$set(this.value, 'spec', podSpec);
173
+ }
174
+ }
175
+
176
+ if ((this.mode === _EDIT || this.mode === _VIEW ) && this.value.type === 'pod' ) {
177
+ const podSpec = { ...this.value.spec };
178
+
179
+ this.$set(this.value.spec, 'template', { spec: podSpec });
151
180
  }
152
181
 
153
182
  const spec = this.value.spec;
183
+ let podTemplateSpec = type === WORKLOAD_TYPES.CRON_JOB ? spec.jobTemplate.spec.template.spec : spec?.template?.spec;
184
+
185
+ let containers = podTemplateSpec.containers || [];
154
186
  let container;
155
- const podTemplateSpec =
156
- type === WORKLOAD_TYPES.CRON_JOB ? spec.jobTemplate.spec.template.spec : spec?.template?.spec;
157
- let containers = podTemplateSpec.containers;
187
+
188
+ if (this.mode === _VIEW && this.value.type === 'pod' ) {
189
+ podTemplateSpec = spec;
190
+ }
158
191
 
159
192
  if (
160
193
  this.mode === _CREATE ||
161
194
  this.mode === _VIEW ||
162
- (!createSidecar && !this.value.hasSidecars)
195
+ (!createSidecar && !this.value.hasSidecars) // hasSideCars = containers.length > 1 || initContainers.length;
163
196
  ) {
164
197
  container = containers[0];
165
198
  } else {
199
+ // This means that there are no containers.
166
200
  if (!podTemplateSpec.initContainers) {
167
201
  podTemplateSpec.initContainers = [];
168
202
  }
@@ -176,13 +210,15 @@ export default {
176
210
  imagePullPolicy: 'Always',
177
211
  name: `container-${ allContainers.length }`,
178
212
  });
213
+
179
214
  containers = podTemplateSpec.initContainers;
180
215
  }
181
- if (createSidecar) {
216
+ if (createSidecar || this.value.type === 'pod') {
182
217
  container = {
183
218
  imagePullPolicy: 'Always',
184
219
  name: `container-${ allContainers.length }`,
185
220
  };
221
+
186
222
  containers.push(container);
187
223
  } else {
188
224
  container = containers[0];
@@ -217,7 +253,8 @@ export default {
217
253
  fvFormRuleSets: [{
218
254
  path: 'image', rootObject: this.container, rules: ['required'], translationKey: 'workload.container.image'
219
255
  }],
220
- fvReportedValidationPaths: ['spec']
256
+ fvReportedValidationPaths: ['spec'],
257
+
221
258
  };
222
259
  },
223
260
 
@@ -226,6 +263,14 @@ export default {
226
263
  return { general: this.fvGetPathErrors(['image'])?.length > 0 };
227
264
  },
228
265
 
266
+ defaultTab() {
267
+ if (!!this.$route.query.sidecar || this.$route.query.init || this.mode === _CREATE) {
268
+ return 'container-0';
269
+ }
270
+
271
+ return this.allContainers.length ? this.allContainers[0].name : '';
272
+ },
273
+
229
274
  isEdit() {
230
275
  return this.mode === _EDIT;
231
276
  },
@@ -251,6 +296,10 @@ export default {
251
296
  return this.type === WORKLOAD_TYPES.DEPLOYMENT;
252
297
  },
253
298
 
299
+ isPod() {
300
+ return this.value.type === POD;
301
+ },
302
+
254
303
  isStatefulSet() {
255
304
  return this.type === WORKLOAD_TYPES.STATEFUL_SET;
256
305
  },
@@ -430,6 +479,12 @@ export default {
430
479
  }
431
480
  },
432
481
 
482
+ imagePullNamespacedSecrets() {
483
+ const namespace = this.value?.metadata?.namespace;
484
+
485
+ return this.allSecrets.filter(secret => secret.metadata.namespace === namespace && (secret._type === SECRET_TYPES.DOCKER || secret._type === SECRET_TYPES.DOCKER_JSON));
486
+ },
487
+
433
488
  namespacedConfigMaps() {
434
489
  const namespace = this.value?.metadata?.namespace;
435
490
 
@@ -882,7 +937,7 @@ export default {
882
937
  }
883
938
  },
884
939
  nvidiaIsValid(nvidiaGpuLimit) {
885
- if (!Number.isInteger(nvidiaGpuLimit)) {
940
+ if ( !Number.isInteger(parseInt(nvidiaGpuLimit)) ) {
886
941
  return false;
887
942
  }
888
943
  if (nvidiaGpuLimit === undefined) {