@rancher/shell 0.1.1 → 0.1.3

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 (294) hide show
  1. package/assets/translations/en-us.yaml +33 -769
  2. package/assets/translations/zh-hans.yaml +153 -781
  3. package/components/ActionMenu.vue +3 -3
  4. package/components/CodeMirror.vue +6 -8
  5. package/components/CommunityLinks.vue +1 -1
  6. package/components/ContainerResourceLimit.vue +14 -0
  7. package/components/ExplorerMembers.vue +123 -0
  8. package/components/ExplorerProjectsNamespaces.vue +405 -0
  9. package/components/GrafanaDashboard.vue +17 -2
  10. package/components/LocaleSelector.vue +81 -0
  11. package/components/PromptModal.vue +2 -3
  12. package/components/ResourceList/index.vue +1 -1
  13. package/components/ResourceTable.vue +3 -6
  14. package/components/SingleClusterInfo.vue +1 -1
  15. package/components/SortableTable/index.vue +23 -20
  16. package/components/SortableTable/selection.js +1 -0
  17. package/components/auth/AzureWarning.vue +5 -1
  18. package/components/auth/Principal.vue +1 -1
  19. package/components/auth/RoleDetailEdit.vue +32 -12
  20. package/components/fleet/FleetRepos.vue +0 -2
  21. package/components/form/NameNsDescription.vue +4 -6
  22. package/components/form/NodeScheduling.vue +1 -1
  23. package/components/form/ResourceTabs/index.vue +27 -18
  24. package/components/form/WorkloadPorts.vue +1 -1
  25. package/components/formatter/ClusterLink.vue +13 -0
  26. package/components/formatter/PodImages.vue +11 -1
  27. package/components/formatter/RKETemplateName.vue +37 -0
  28. package/components/formatter/WorkloadHealthScale.vue +1 -1
  29. package/components/nav/Header.vue +9 -9
  30. package/components/nav/NamespaceFilter.vue +7 -4
  31. package/components/nav/TopLevelMenu.vue +6 -43
  32. package/components/nav/WindowManager/ContainerLogs.vue +1 -1
  33. package/config/product/harvester-manager.js +64 -2
  34. package/config/product/manager.js +9 -0
  35. package/config/settings.js +17 -71
  36. package/config/table-headers.js +0 -1
  37. package/config/types.js +8 -26
  38. package/core/plugin-routes.ts +34 -22
  39. package/core/plugin.ts +15 -3
  40. package/core/plugins-loader.js +2 -0
  41. package/core/plugins.js +79 -36
  42. package/core/types.ts +7 -1
  43. package/creators/app/tsconfig.json +6 -1
  44. package/creators/pkg/init +3 -0
  45. package/creators/pkg/tsconfig.json +7 -2
  46. package/detail/provisioning.cattle.io.cluster.vue +23 -0
  47. package/detail/workload/index.vue +11 -5
  48. package/{components/dialog → dialog}/AddClusterMemberDialog.vue +0 -0
  49. package/{components/dialog → dialog}/AddCustomBadgeDialog.vue +0 -0
  50. package/{components/dialog → dialog}/AddProjectMemberDialog.vue +0 -0
  51. package/{components/dialog → dialog}/AddonConfigConfirmationDialog.vue +0 -0
  52. package/{components/dialog → dialog}/DrainNode.vue +0 -0
  53. package/{components/dialog → dialog}/ForceMachineRemoveDialog.vue +0 -0
  54. package/{components/dialog → dialog}/GenericPrompt.vue +0 -0
  55. package/{components/dialog → dialog}/RollbackWorkloadDialog.vue +0 -0
  56. package/{components/dialog → dialog}/RotateCertificatesDialog.vue +0 -0
  57. package/{components/dialog → dialog}/RotateEncryptionKeyDialog.vue +0 -0
  58. package/{components/dialog → dialog}/SaveAsRKETemplateDialog.vue +0 -0
  59. package/{components/dialog → dialog}/ScaleMachineDownDialog.vue +0 -0
  60. package/edit/auth/azuread.vue +20 -1
  61. package/edit/cloudcredential.vue +7 -1
  62. package/edit/management.cattle.io.project.vue +2 -2
  63. package/edit/namespace.vue +17 -10
  64. package/edit/networking.k8s.io.ingress/index.vue +2 -1
  65. package/edit/persistentvolumeclaim.vue +33 -2
  66. package/edit/provisioning.cattle.io.cluster/CustomCommand.vue +1 -1
  67. package/edit/provisioning.cattle.io.cluster/MachinePool.vue +34 -6
  68. package/edit/provisioning.cattle.io.cluster/index.vue +1 -1
  69. package/edit/provisioning.cattle.io.cluster/rke2.vue +21 -6
  70. package/edit/service.vue +1 -1
  71. package/edit/workload/index.vue +363 -15
  72. package/edit/workload/mixins/workload.js +62 -7
  73. package/edit/workload/storage/persistentVolumeClaim/persistentvolumeclaim.vue +1 -0
  74. package/layouts/default.vue +52 -27
  75. package/layouts/error.vue +5 -1
  76. package/layouts/home.vue +6 -2
  77. package/list/harvesterhci.io.management.cluster.vue +74 -33
  78. package/list/namespace.vue +3 -5
  79. package/list/provisioning.cattle.io.cluster.vue +6 -0
  80. package/machine-config/amazonec2.vue +2 -0
  81. package/machine-config/harvester.vue +96 -49
  82. package/middleware/authenticated.js +56 -52
  83. package/mixins/brand.js +3 -4
  84. package/mixins/create-edit-view/impl.js +0 -8
  85. package/mixins/form-validation.js +1 -1
  86. package/mixins/resource-fetch.js +3 -1
  87. package/models/chart.js +1 -1
  88. package/models/cluster/node.js +12 -1
  89. package/models/fleet.cattle.io.bundle.js +26 -19
  90. package/models/harvesterhci.io.management.cluster.js +194 -5
  91. package/models/management.cattle.io.cluster.js +1 -1
  92. package/models/management.cattle.io.clusterroletemplatebinding.js +9 -0
  93. package/models/management.cattle.io.globalrole.js +0 -19
  94. package/models/management.cattle.io.project.js +23 -2
  95. package/models/management.cattle.io.roletemplate.js +2 -21
  96. package/models/namespace.js +19 -3
  97. package/models/pod.js +19 -2
  98. package/models/provisioning.cattle.io.cluster.js +71 -0
  99. package/models/service.js +5 -1
  100. package/models/workload.js +4 -243
  101. package/models/workload.service.js +314 -0
  102. package/nuxt.config.js +14 -12
  103. package/package.json +3 -3
  104. package/pages/auth/login.vue +11 -2
  105. package/pages/auth/setup.vue +1 -1
  106. package/pages/c/_cluster/_product/members/index.vue +3 -93
  107. package/pages/c/_cluster/_product/projectsnamespaces.vue +6 -403
  108. package/pages/c/_cluster/apps/charts/install.vue +0 -6
  109. package/pages/c/_cluster/settings/performance.vue +19 -16
  110. package/pages/fail-whale.vue +1 -10
  111. package/pages/index.vue +18 -4
  112. package/pages/plugins.vue +2 -2
  113. package/pages/prefs.vue +8 -6
  114. package/pkg/auto-import.js +44 -7
  115. package/pkg/dynamic-plugin-loader.js +28 -0
  116. package/pkg/import.js +2 -2
  117. package/pkg/model-loader-require.lib.js +3 -0
  118. package/pkg/vue.config.js +9 -6
  119. package/plugins/console.js +10 -5
  120. package/plugins/dashboard-store/actions.js +8 -3
  121. package/plugins/dashboard-store/getters.js +7 -2
  122. package/plugins/dashboard-store/model-loader-require.js +12 -0
  123. package/plugins/dashboard-store/model-loader.js +4 -1
  124. package/plugins/dashboard-store/resource-class.js +10 -3
  125. package/plugins/steve/actions.js +1 -1
  126. package/plugins/steve/index.js +6 -4
  127. package/plugins/steve/steve-description-class.js +32 -0
  128. package/plugins/steve/subscribe.js +34 -23
  129. package/rancher-components/Banner/Banner.vue +2 -2
  130. package/rancher-components/Form/Checkbox/Checkbox.test.ts +77 -0
  131. package/rancher-components/Form/Checkbox/Checkbox.vue +12 -2
  132. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +0 -2
  133. package/rancher-components/Form/LabeledInput/LabeledInput.vue +2 -0
  134. package/rancher-components/Form/Radio/RadioButton.vue +14 -1
  135. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.test.ts +107 -0
  136. package/{components/form → rancher-components/Form/ToggleSwitch}/ToggleSwitch.vue +18 -8
  137. package/rancher-components/Form/ToggleSwitch/index.ts +1 -0
  138. package/rancher-components/Form/index.ts +1 -0
  139. package/scripts/build-pkg.sh +48 -2
  140. package/scripts/drone-build-pkg.sh +31 -0
  141. package/scripts/publish-shell.sh +10 -11
  142. package/scripts/serve-pkgs +17 -10
  143. package/scripts/test-plugins-build.sh +18 -1
  144. package/store/catalog.js +3 -1
  145. package/store/i18n.js +16 -11
  146. package/store/index.js +4 -181
  147. package/store/prefs.js +30 -2
  148. package/store/type-map.js +16 -29
  149. package/types/{index.d.ts → rancher/index.d.ts} +0 -0
  150. package/utils/cluster.js +1 -1
  151. package/utils/custom-validators.js +1 -12
  152. package/utils/dynamic-importer.js +1 -1
  153. package/utils/validators/setting.js +0 -35
  154. package/components/FilterLabel.vue +0 -254
  155. package/components/HarvesterUpgradeProgressBarList.vue +0 -109
  156. package/components/VMConsoleBar.vue +0 -87
  157. package/components/dialog/harvester/AddHotplugModal.vue +0 -159
  158. package/components/dialog/harvester/BackupModal.vue +0 -117
  159. package/components/dialog/harvester/CloneTemplate.vue +0 -125
  160. package/components/dialog/harvester/EjectCDROMDialog.vue +0 -157
  161. package/components/dialog/harvester/ExportImageDialog.vue +0 -152
  162. package/components/dialog/harvester/MaintenanceDialog.vue +0 -94
  163. package/components/dialog/harvester/MigrationDialog.vue +0 -154
  164. package/components/dialog/harvester/RestoreDialog.vue +0 -153
  165. package/components/dialog/harvester/SupportBundle.vue +0 -217
  166. package/components/dialog/harvester/UnplugVolume.vue +0 -108
  167. package/components/form/SerialConsole/index.vue +0 -267
  168. package/components/formatter/AttachVMWithName.vue +0 -46
  169. package/components/formatter/CloudInitType.vue +0 -27
  170. package/components/formatter/HarvesterBackupTargetValidation.vue +0 -43
  171. package/components/formatter/HarvesterCPUUsed.vue +0 -122
  172. package/components/formatter/HarvesterDiskState.vue +0 -66
  173. package/components/formatter/HarvesterHostName.vue +0 -66
  174. package/components/formatter/HarvesterIpAddress.vue +0 -90
  175. package/components/formatter/HarvesterMemoryUsed.vue +0 -140
  176. package/components/formatter/HarvesterMigrationState.vue +0 -85
  177. package/components/formatter/HarvesterNodeName.vue +0 -49
  178. package/components/formatter/HarvesterStorageUsed.vue +0 -194
  179. package/components/formatter/HarvesterVmState.vue +0 -123
  180. package/components/nav/HarvesterUpgrade.vue +0 -232
  181. package/components/novnc/NovncConsole.vue +0 -93
  182. package/components/novnc/NovncConsoleItem.vue +0 -89
  183. package/components/novnc/NovncConsoleWrapper.vue +0 -243
  184. package/config/harvester-map.js +0 -44
  185. package/config/harvester-table-headers.js +0 -27
  186. package/config/product/harvester.js +0 -305
  187. package/detail/harvesterhci.io.host/HarvesterHostBasic.vue +0 -364
  188. package/detail/harvesterhci.io.host/HarvesterHostDisk.vue +0 -200
  189. package/detail/harvesterhci.io.host/HarvesterHostNetwork.vue +0 -89
  190. package/detail/harvesterhci.io.host/VirtualMachineInstance.vue +0 -134
  191. package/detail/harvesterhci.io.host/index.vue +0 -243
  192. package/detail/harvesterhci.io.virtualmachinebackup/index.vue +0 -221
  193. package/detail/harvesterhci.io.virtualmachineimage.vue +0 -118
  194. package/detail/kubevirt.io.virtualmachine/VirtualMachineTabs/VirtualMachineBasics.vue +0 -279
  195. package/detail/kubevirt.io.virtualmachine/VirtualMachineTabs/VirtualMachineEvents.vue +0 -75
  196. package/detail/kubevirt.io.virtualmachine/VirtualMachineTabs/VirtualMachineKeypairs.vue +0 -114
  197. package/detail/kubevirt.io.virtualmachine/VirtualMachineTabs/VirtualMachineMigration.vue +0 -79
  198. package/detail/kubevirt.io.virtualmachine/index.vue +0 -213
  199. package/edit/harvesterhci.io.cloudtemplate.vue +0 -123
  200. package/edit/harvesterhci.io.host/HarvesterDisk.vue +0 -262
  201. package/edit/harvesterhci.io.host/index.vue +0 -533
  202. package/edit/harvesterhci.io.keypair.vue +0 -112
  203. package/edit/harvesterhci.io.managedchart/index.vue +0 -25
  204. package/edit/harvesterhci.io.managedchart/rancher-monitoring.vue +0 -172
  205. package/edit/harvesterhci.io.networkattachmentdefinition.vue +0 -210
  206. package/edit/harvesterhci.io.setting/additional-ca.vue +0 -36
  207. package/edit/harvesterhci.io.setting/backup-target.vue +0 -182
  208. package/edit/harvesterhci.io.setting/http-proxy.vue +0 -79
  209. package/edit/harvesterhci.io.setting/index.vue +0 -201
  210. package/edit/harvesterhci.io.setting/overcommit-config.vue +0 -94
  211. package/edit/harvesterhci.io.setting/ssl-certificates.vue +0 -117
  212. package/edit/harvesterhci.io.setting/ssl-parameters.vue +0 -161
  213. package/edit/harvesterhci.io.setting/support-bundle-image.vue +0 -134
  214. package/edit/harvesterhci.io.setting/support-bundle-namespaces.vue +0 -73
  215. package/edit/harvesterhci.io.setting/vip-pools.vue +0 -244
  216. package/edit/harvesterhci.io.setting/vm-force-reset-policy.vue +0 -81
  217. package/edit/harvesterhci.io.virtualmachinebackup.vue +0 -256
  218. package/edit/harvesterhci.io.virtualmachineimage.vue +0 -364
  219. package/edit/harvesterhci.io.virtualmachinetemplateversion.vue +0 -340
  220. package/edit/harvesterhci.io.volume.vue +0 -195
  221. package/edit/kubevirt.io.virtualmachine/VirtualMachineAccessCredentials/AccessCredentialsUsers.vue +0 -190
  222. package/edit/kubevirt.io.virtualmachine/VirtualMachineAccessCredentials/index.vue +0 -212
  223. package/edit/kubevirt.io.virtualmachine/VirtualMachineAccessCredentials/type/basicAuth.vue +0 -94
  224. package/edit/kubevirt.io.virtualmachine/VirtualMachineAccessCredentials/type/sshkey.vue +0 -85
  225. package/edit/kubevirt.io.virtualmachine/VirtualMachineCloudConfig/DataTemplate.vue +0 -153
  226. package/edit/kubevirt.io.virtualmachine/VirtualMachineCloudConfig/index.vue +0 -279
  227. package/edit/kubevirt.io.virtualmachine/VirtualMachineCpuMemory.vue +0 -113
  228. package/edit/kubevirt.io.virtualmachine/VirtualMachineNetwork/__tests__/HarvesterEditNetwork.test.ts +0 -41
  229. package/edit/kubevirt.io.virtualmachine/VirtualMachineNetwork/base.vue +0 -281
  230. package/edit/kubevirt.io.virtualmachine/VirtualMachineNetwork/index.vue +0 -142
  231. package/edit/kubevirt.io.virtualmachine/VirtualMachineReserved.vue +0 -54
  232. package/edit/kubevirt.io.virtualmachine/VirtualMachineSSHKey.vue +0 -256
  233. package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/index.vue +0 -391
  234. package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/__tests__/HarvesterEditContainer.test.ts +0 -40
  235. package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/__tests__/HarvesterEditExisting.test.ts +0 -102
  236. package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/__tests__/HarvesterEditVMImage.test.ts +0 -117
  237. package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/__tests__/HarvesterEditVolume.test.ts +0 -74
  238. package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/container.vue +0 -132
  239. package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/existing.vue +0 -303
  240. package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/vmImage.vue +0 -285
  241. package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/volume.vue +0 -188
  242. package/edit/kubevirt.io.virtualmachine/index.vue +0 -642
  243. package/edit/network.harvesterhci.io.clusternetwork/index.vue +0 -19
  244. package/edit/network.harvesterhci.io.clusternetwork/vlan.vue +0 -134
  245. package/edit/workload/types/Deployment.vue +0 -377
  246. package/edit/workload/types/Generic.vue +0 -295
  247. package/list/harvesterhci.io.cloudtemplate.vue +0 -78
  248. package/list/harvesterhci.io.dashboard/HarvesterUpgrade.vue +0 -211
  249. package/list/harvesterhci.io.dashboard/UpgradeInfo.vue +0 -40
  250. package/list/harvesterhci.io.dashboard/index.vue +0 -752
  251. package/list/harvesterhci.io.host/index.vue +0 -186
  252. package/list/harvesterhci.io.networkattachmentdefinition.vue +0 -167
  253. package/list/harvesterhci.io.setting.vue +0 -241
  254. package/list/harvesterhci.io.virtualmachinebackup.vue +0 -172
  255. package/list/harvesterhci.io.virtualmachineimage.vue +0 -80
  256. package/list/harvesterhci.io.virtualmachinetemplateversion.vue +0 -173
  257. package/list/harvesterhci.io.volume.vue +0 -122
  258. package/list/kubevirt.io.virtualmachine.vue +0 -193
  259. package/mixins/harvester-vm/impl.js +0 -267
  260. package/mixins/harvester-vm/index.js +0 -1357
  261. package/models/harvester/configmap.js +0 -32
  262. package/models/harvester/harvesterhci.io.blockdevice.js +0 -55
  263. package/models/harvester/harvesterhci.io.keypair.js +0 -12
  264. package/models/harvester/harvesterhci.io.setting.js +0 -127
  265. package/models/harvester/harvesterhci.io.supportbundle.js +0 -35
  266. package/models/harvester/harvesterhci.io.upgrade.js +0 -226
  267. package/models/harvester/harvesterhci.io.virtualmachinebackup.js +0 -116
  268. package/models/harvester/harvesterhci.io.virtualmachineimage.js +0 -255
  269. package/models/harvester/harvesterhci.io.virtualmachinerestore.js +0 -43
  270. package/models/harvester/harvesterhci.io.virtualmachinetemplate.js +0 -69
  271. package/models/harvester/harvesterhci.io.virtualmachinetemplateversion.js +0 -227
  272. package/models/harvester/k8s.cni.cncf.io.networkattachmentdefinition.js +0 -32
  273. package/models/harvester/kubevirt.io.virtualmachine.js +0 -850
  274. package/models/harvester/kubevirt.io.virtualmachineinstance.js +0 -142
  275. package/models/harvester/management.cattle.io.managedchart.js +0 -191
  276. package/models/harvester/management.cattle.io.setting.js +0 -40
  277. package/models/harvester/network.harvesterhci.io.clusternetwork.js +0 -100
  278. package/models/harvester/network.harvesterhci.io.nodenetwork.js +0 -34
  279. package/models/harvester/node.js +0 -255
  280. package/models/harvester/persistentvolumeclaim.js +0 -166
  281. package/models/harvester/pod.js +0 -185
  282. package/pages/c/_cluster/harvester/airgapupgrade/index.vue +0 -309
  283. package/pages/c/_cluster/harvester/console/_uid/serial.vue +0 -51
  284. package/pages/c/_cluster/harvester/console/_uid/vnc.vue +0 -52
  285. package/pages/c/_cluster/harvester/index.vue +0 -24
  286. package/pages/c/_cluster/harvester/support/index.vue +0 -154
  287. package/pkg/model-loader.lib.js +0 -3
  288. package/plugins/lookup.js +0 -50
  289. package/promptRemove/kubevirt.io.virtualmachine.vue +0 -164
  290. package/store/harvester-common.js +0 -126
  291. package/utils/validators/vm-datavolumes.js +0 -38
  292. package/utils/validators/vm-image.js +0 -32
  293. package/utils/validators/vm.js +0 -221
  294. package/yarn-error.log +0 -196
@@ -1,256 +0,0 @@
1
- <script>
2
- import { mapGetters } from 'vuex';
3
- import { randomStr } from '@shell/utils/string';
4
-
5
- import { LabeledInput } from '@components/Form/LabeledInput';
6
- import LabeledSelect from '@shell/components/form/LabeledSelect';
7
- import ModalWithCard from '@shell/components/ModalWithCard';
8
-
9
- import { HCI } from '@shell/config/types';
10
- import { clone } from '@shell/utils/object';
11
- import { _VIEW } from '@shell/config/query-params';
12
-
13
- const _NEW = '_NEW';
14
-
15
- export default {
16
- components: {
17
- LabeledInput,
18
- ModalWithCard,
19
- LabeledSelect,
20
- },
21
-
22
- props: {
23
- value: {
24
- type: Array,
25
- default: () => {
26
- return [];
27
- }
28
- },
29
-
30
- mode: {
31
- type: String,
32
- default: 'create',
33
- },
34
-
35
- disableCreate: {
36
- type: Boolean,
37
- default: false
38
- },
39
-
40
- namespace: {
41
- type: String,
42
- default: ''
43
- },
44
-
45
- searchable: {
46
- type: Boolean,
47
- default: true,
48
- },
49
-
50
- disabled: {
51
- type: Boolean,
52
- default: false
53
- }
54
- },
55
-
56
- data() {
57
- return {
58
- checkedSsh: this.value,
59
- publicKey: '',
60
- sshName: '',
61
- randomStr: randomStr(5).toLowerCase(),
62
- errors: [],
63
- isAll: false,
64
- checkAll: false
65
- };
66
- },
67
-
68
- computed: {
69
- ...mapGetters({ t: 'i18n/t' }),
70
-
71
- schema() {
72
- return this.$store.getters['harvester/schemaFor']( HCI.SSH );
73
- },
74
-
75
- isCreatable() {
76
- if ( this.schema && !this.schema?.collectionMethods.find(x => ['blocked-post', 'post'].includes(x.toLowerCase())) ) {
77
- return false;
78
- }
79
-
80
- return true ;
81
- },
82
-
83
- sshOption() {
84
- const out = this.$store.getters['harvester/all'](HCI.SSH).map( (O) => {
85
- return {
86
- label: O.id,
87
- value: O.id
88
- };
89
- });
90
-
91
- if (!(this.disableCreate || this.mode === _VIEW) && this.isCreatable) {
92
- out.unshift({
93
- label: this.t('harvester.virtualMachine.createSSHKey'),
94
- value: _NEW,
95
- });
96
- }
97
-
98
- return out;
99
- },
100
- },
101
-
102
- watch: {
103
- publicKey(neu) {
104
- const splitSSH = neu.split(/\s+/);
105
-
106
- if (splitSSH.length === 3) {
107
- if (splitSSH[2].includes('@')) {
108
- if (splitSSH[2].split('@')) {
109
- if (!this.sshName) {
110
- this.sshName = splitSSH[2].split('@')[0];
111
- }
112
- }
113
- }
114
- }
115
- },
116
-
117
- value(neu) {
118
- this.checkedSsh = neu;
119
- },
120
-
121
- checkedSsh(val, old) {
122
- if ( val.includes(_NEW)) {
123
- this.$set(this, 'checkedSsh', old);
124
- this.update();
125
- this.show();
126
- }
127
- }
128
- },
129
-
130
- methods: {
131
- show() {
132
- this.$modal.show(this.randomStr);
133
- },
134
-
135
- hide() {
136
- this.$modal.hide(this.randomStr);
137
- },
138
-
139
- async save(buttonCb) {
140
- this.errors = [];
141
-
142
- if (!this.sshName) {
143
- const fieldName = this.t('harvester.virtualMachine.input.name');
144
- const message = this.t('validation.required', { key: fieldName });
145
-
146
- this.errors.push(message);
147
- }
148
-
149
- if (!this.publicKey) {
150
- const fieldName = this.t('harvester.virtualMachine.input.sshKeyValue');
151
- const message = this.t('validation.required', { key: fieldName });
152
-
153
- this.errors.push(message);
154
- }
155
-
156
- if (this.sshName.length > 63) {
157
- const message = this.t('harvester.validation.custom.tooLongName', { max: 63 });
158
-
159
- this.errors.push(message);
160
- }
161
-
162
- if (this.errors.length > 0) {
163
- buttonCb(false);
164
-
165
- return;
166
- }
167
-
168
- try {
169
- const sshValue = await this.$store.dispatch('harvester/create', {
170
- metadata: {
171
- name: this.sshName,
172
- namespace: this.namespace
173
- },
174
- spec: { publicKey: this.publicKey },
175
- type: HCI.SSH
176
- });
177
-
178
- const res = await sshValue.save();
179
-
180
- if (res.id) {
181
- this.checkedSsh.push(`${ this.namespace }/${ this.sshName }`);
182
- }
183
-
184
- buttonCb(true);
185
- this.cancel();
186
- } catch (err) {
187
- this.errors = [err.message];
188
- buttonCb(false);
189
- }
190
- },
191
-
192
- cancel() {
193
- this.hide();
194
- this.resetFields();
195
- },
196
-
197
- resetFields() {
198
- this.sshName = '';
199
- this.publicKey = '';
200
- this.errors = [];
201
- },
202
-
203
- update() {
204
- this.$emit('update:sshKey', clone(this.checkedSsh));
205
- },
206
- }
207
- };
208
- </script>
209
-
210
- <template>
211
- <div>
212
- <LabeledSelect
213
- v-model="checkedSsh"
214
- :label="t('harvester.virtualMachine.input.sshKey')"
215
- :taggable="true"
216
- :mode="mode"
217
- :multiple="true"
218
- :searchable="searchable"
219
- :disabled="disabled"
220
- :options="sshOption"
221
- @input="update"
222
- />
223
-
224
- <ModalWithCard
225
- :ref="randomStr"
226
- :name="randomStr"
227
- width="40%"
228
- :errors="errors"
229
- @finish="save"
230
- @close="cancel"
231
- >
232
- <template #title>
233
- {{ t('harvester.virtualMachine.sshTitle') }}
234
- </template>
235
-
236
- <template #content>
237
- <LabeledInput
238
- v-model="sshName"
239
- :label="t('harvester.virtualMachine.input.name')"
240
- class="mb-20"
241
- required
242
- @keydown.native.enter.prevent="()=>{}"
243
- />
244
-
245
- <LabeledInput
246
- v-model="publicKey"
247
- :label="t('harvester.virtualMachine.input.sshKeyValue')"
248
- :min-height="160"
249
- class="mb-20"
250
- type="multiline"
251
- required
252
- />
253
- </template>
254
- </ModalWithCard>
255
- </div>
256
- </template>
@@ -1,391 +0,0 @@
1
- <script>
2
- import draggable from 'vuedraggable';
3
- import InfoBox from '@shell/components/InfoBox';
4
- import { Banner } from '@components/Banner';
5
- import BadgeStateFormatter from '@shell/components/formatter/BadgeStateFormatter';
6
- import UnitInput from '@shell/components/form/UnitInput';
7
- import { LabeledInput } from '@components/Form/LabeledInput';
8
- import LabeledSelect from '@shell/components/form/LabeledSelect';
9
- import ModalWithCard from '@shell/components/ModalWithCard';
10
-
11
- import { PVC, HCI } from '@shell/config/types';
12
- import { clone } from '@shell/utils/object';
13
- import { removeObject } from '@shell/utils/array';
14
- import { randomStr } from '@shell/utils/string';
15
- import { SOURCE_TYPE } from '@shell/config/harvester-map';
16
- import { _VIEW, _EDIT, _CREATE } from '@shell/config/query-params';
17
-
18
- export default {
19
- components: {
20
- Banner, BadgeStateFormatter, draggable, InfoBox, LabeledInput, UnitInput, LabeledSelect, ModalWithCard
21
- },
22
-
23
- props: {
24
- vm: {
25
- type: Object,
26
- default: () => {
27
- return {};
28
- }
29
- },
30
-
31
- mode: {
32
- type: String,
33
- default: _CREATE
34
- },
35
-
36
- value: {
37
- type: Array,
38
- default: () => {
39
- return [];
40
- }
41
- },
42
-
43
- namespace: {
44
- type: String,
45
- default: null
46
- },
47
-
48
- existingVolumeDisabled: {
49
- type: Boolean,
50
- default: false
51
- },
52
-
53
- validateRequired: {
54
- type: Boolean,
55
- default: false
56
- },
57
-
58
- customVolumeMode: {
59
- type: String,
60
- default: 'Block'
61
- },
62
-
63
- customAccessMode: {
64
- type: String,
65
- default: 'ReadWriteMany'
66
- },
67
-
68
- resourceType: {
69
- type: String,
70
- default: ''
71
- }
72
- },
73
-
74
- async fetch() {
75
- await this.$store.dispatch('harvester/findAll', { type: PVC });
76
- },
77
-
78
- data() {
79
- return {
80
- SOURCE_TYPE,
81
- rows: clone(this.value),
82
- nameIdx: 1,
83
- vol: null
84
- };
85
- },
86
-
87
- computed: {
88
- isVirtualType() {
89
- return this.resourceType === HCI.VM;
90
- },
91
-
92
- isView() {
93
- return this.mode === _VIEW;
94
- },
95
-
96
- isEdit() {
97
- return this.mode === _EDIT;
98
- },
99
-
100
- isCreate() {
101
- return this.mode === _CREATE;
102
- },
103
-
104
- showVolumeTip() {
105
- const imageName = this.getImageDisplayName(this.rows[0]?.image);
106
-
107
- if (this.rows.length === 1 && this.rows[0].type === 'cd-rom' && /.iso$/i.test(imageName)) {
108
- return true;
109
- }
110
-
111
- return false;
112
- },
113
-
114
- pvcs() {
115
- return this.$store.getters['harvester/all'](PVC) || [];
116
- },
117
- },
118
-
119
- watch: {
120
- value: {
121
- handler(neu) {
122
- const rows = neu.map((V) => {
123
- if (!this.isCreate && V.source !== SOURCE_TYPE.CONTAINER && !V.newCreateId) {
124
- V.to = {
125
- name: 'c-cluster-product-resource-namespace-id',
126
- params: {
127
- product: 'harvester',
128
- resource: HCI.VOLUME,
129
- namespace: this.namespace,
130
- id: V.realName
131
- },
132
- query: { mode: _EDIT }
133
- };
134
-
135
- V.pvc = this.pvcs.find(pvc => pvc.metadata.name === V.realName);
136
- }
137
-
138
- return V;
139
- });
140
-
141
- this.$set(this, 'rows', rows);
142
- },
143
- deep: true,
144
- immediate: true,
145
- },
146
- },
147
-
148
- methods: {
149
- addVolume(type) {
150
- const name = this.generateName();
151
- const neu = {
152
- id: randomStr(5),
153
- name,
154
- source: type,
155
- size: '10Gi',
156
- type: 'disk',
157
- accessMode: this.customAccessMode,
158
- volumeMode: this.customVolumeMode,
159
- volumeName: '',
160
- bus: 'virtio',
161
- newCreateId: randomStr(10), // judge whether it is a disk that has been created
162
- };
163
-
164
- this.rows.push(neu);
165
- this.update();
166
- },
167
-
168
- generateName() {
169
- let name = '';
170
- let hasName = true;
171
-
172
- while (hasName) {
173
- name = `disk-${ this.nameIdx }`;
174
- hasName = this.rows.find(O => O.name === name);
175
- this.nameIdx++;
176
- }
177
-
178
- return name;
179
- },
180
-
181
- removeVolume(vol) {
182
- this.vol = vol;
183
- if (!vol.newCreateId && this.isEdit && this.isVirtualType) {
184
- this.$refs.deleteTip.open();
185
- } else {
186
- removeObject(this.rows, vol);
187
- this.update();
188
- }
189
- },
190
-
191
- unplugVolume(volume) {
192
- this.vm.unplugVolume(volume.name);
193
- },
194
-
195
- componentFor(type) {
196
- switch (type) {
197
- case SOURCE_TYPE.NEW:
198
- return require(`@shell/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/volume.vue`).default;
199
- case SOURCE_TYPE.IMAGE:
200
- return require(`@shell/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/vmImage.vue`).default;
201
- case SOURCE_TYPE.ATTACH_VOLUME:
202
- return require(`@shell/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/existing.vue`).default;
203
- case SOURCE_TYPE.CONTAINER:
204
- return require(`@shell/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/container.vue`).default;
205
- }
206
- },
207
-
208
- headerFor(type) {
209
- return {
210
- [SOURCE_TYPE.NEW]: this.$store.getters['i18n/t']('harvester.virtualMachine.volume.title.volume'),
211
- [SOURCE_TYPE.IMAGE]: this.$store.getters['i18n/t']('harvester.virtualMachine.volume.title.vmImage'),
212
- [SOURCE_TYPE.ATTACH_VOLUME]: this.$store.getters['i18n/t']('harvester.virtualMachine.volume.title.existingVolume'),
213
- [SOURCE_TYPE.CONTAINER]: this.$store.getters['i18n/t']('harvester.virtualMachine.volume.title.container'),
214
- }[type];
215
- },
216
-
217
- update() {
218
- this.$emit('input', this.rows);
219
- },
220
-
221
- deleteVolume() {
222
- removeObject(this.rows, this.vol);
223
- this.update();
224
- this.cancel();
225
- },
226
-
227
- cancel() {
228
- this.$refs.deleteTip.hide();
229
- },
230
-
231
- changeSort(idx, type) {
232
- // true: down, false: up
233
- this.rows.splice(type ? idx : idx - 1, 1, ...this.rows.splice(type ? idx + 1 : idx, 1, this.rows[type ? idx : idx - 1]));
234
- this.update();
235
- },
236
-
237
- getImageDisplayName(id) {
238
- return this.$store.getters['harvester/all'](HCI.IMAGE).find(image => image.id === id)?.spec?.displayName;
239
- }
240
- },
241
- };
242
- </script>
243
-
244
- <template>
245
- <div>
246
- <Banner v-if="!isView" color="info" label-key="harvester.virtualMachine.volume.dragTip" />
247
- <draggable v-model="rows" :disabled="isView" @end="update">
248
- <transition-group>
249
- <div v-for="(volume, i) in rows" :key="volume.id">
250
- <InfoBox class="box">
251
- <button v-if="!isView" type="button" class="role-link btn btn-sm remove" @click="removeVolume(volume)">
252
- <i class="icon icon-2x icon-x" />
253
- </button>
254
- <button v-if="volume.hotpluggable && isView" type="button" class="role-link btn remove" @click="unplugVolume(volume)">
255
- {{ t('harvester.virtualMachine.unplug.detachVolume') }}
256
- </button>
257
- <h3>
258
- <span v-if="volume.to && isVirtualType" class="title">
259
- <n-link :to="volume.to">
260
- {{ t('harvester.virtualMachine.volume.edit') }} {{ headerFor(volume.source) }}
261
- </n-link>
262
-
263
- <BadgeStateFormatter v-if="volume.pvc" class="ml-10 state" :arbitrary="true" :row="volume.pvc" :value="volume.pvc.state" />
264
- </span>
265
-
266
- <span v-else>
267
- {{ headerFor(volume.source) }}
268
- </span>
269
- </h3>
270
- <div>
271
- <component
272
- :is="componentFor(volume.source)"
273
- v-model="rows[i]"
274
- :rows="rows"
275
- :namespace="namespace"
276
- :is-create="isCreate"
277
- :is-edit="isEdit"
278
- :is-view="isView"
279
- :is-virtual-type="isVirtualType"
280
- :mode="mode"
281
- :idx="i"
282
- :validate-required="validateRequired"
283
- @update="update"
284
- />
285
- </div>
286
-
287
- <div class="bootOrder">
288
- <div v-if="!isView" class="mr-15">
289
- <button :disabled="i === 0" class="btn btn-sm role-primary" @click.prevent="changeSort(i, false)">
290
- <i class="icon icon-lg icon-chevron-up"></i>
291
- </button>
292
-
293
- <button :disabled="i === rows.length -1" class="btn btn-sm role-primary" @click.prevent="changeSort(i, true)">
294
- <i class="icon icon-lg icon-chevron-down"></i>
295
- </button>
296
- </div>
297
-
298
- <div class="text-muted">
299
- bootOrder: {{ i + 1 }}
300
- </div>
301
- </div>
302
-
303
- <Banner v-if="volume.volumeStatus" class="mt-15" color="warning" :label="volume.volumeStatus.status" />
304
- </InfoBox>
305
- </div>
306
- </transition-group>
307
- </draggable>
308
- <Banner v-if="showVolumeTip" color="warning" :label="t('harvester.virtualMachine.volume.volumeTip')" />
309
-
310
- <div v-if="!isView">
311
- <button
312
- type="button"
313
- class="btn btn-sm bg-primary mr-15 mb-10"
314
- :disabled="rows.length === 0"
315
- @click="addVolume(SOURCE_TYPE.NEW)"
316
- >
317
- {{ t('harvester.virtualMachine.volume.addVolume') }}
318
- </button>
319
-
320
- <button v-if="!existingVolumeDisabled" type="button" class="btn btn-sm bg-primary mr-15 mb-10" @click="addVolume(SOURCE_TYPE.ATTACH_VOLUME)">
321
- {{ t('harvester.virtualMachine.volume.addExistingVolume') }}
322
- </button>
323
-
324
- <button type="button" class="btn btn-sm bg-primary mr-15 mb-10" @click="addVolume(SOURCE_TYPE.IMAGE)">
325
- {{ t('harvester.virtualMachine.volume.addVmImage') }}
326
- </button>
327
-
328
- <button
329
- type="button"
330
- class="btn btn-sm bg-primary mb-10"
331
- @click="addVolume(SOURCE_TYPE.CONTAINER)"
332
- >
333
- {{ t('harvester.virtualMachine.volume.addContainer') }}
334
- </button>
335
- </div>
336
-
337
- <ModalWithCard ref="deleteTip" name="deleteTip" :width="400">
338
- <template #title>
339
- {{ t('harvester.virtualMachine.volume.unmount.title') }}
340
- </template>
341
-
342
- <template #content>
343
- <span>{{ t('harvester.virtualMachine.volume.unmount.message') }}</span>
344
- </template>
345
-
346
- <template #footer>
347
- <div class="buttons">
348
- <button class="btn role-secondary mr-20" @click.prevent="cancel">
349
- {{ t('generic.no') }}
350
- </button>
351
-
352
- <button class="btn bg-primary mr-20" @click.prevent="deleteVolume">
353
- {{ t('generic.yes') }}
354
- </button>
355
- </div>
356
- </template>
357
- </ModalWithCard>
358
- </div>
359
- </template>
360
-
361
- <style lang='scss' scoped>
362
- .box {
363
- position: relative;
364
- }
365
-
366
- .title {
367
- display: flex;
368
-
369
- .state {
370
- font-size: 16px;
371
- }
372
- }
373
-
374
- .remove {
375
- position: absolute;
376
- top: 10px;
377
- right: 10px;
378
- padding: 0px;
379
- }
380
-
381
- .bootOrder {
382
- display: flex;
383
- align-items: center;
384
- }
385
-
386
- .buttons {
387
- width: 100%;
388
- display: flex;
389
- justify-content: flex-end;
390
- }
391
- </style>
@@ -1,40 +0,0 @@
1
- import { mount } from '@vue/test-utils';
2
- import HarvesterEditContainer from '@shell/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/container.vue';
3
- import { _EDIT } from '@shell/config/query-params';
4
-
5
- describe('component: HarvesterEditContainer', () => {
6
- it('should display all the inputs', () => {
7
- const wrapper = mount(HarvesterEditContainer, { propsData: { mode: _EDIT, value: {} } });
8
-
9
- const inputWraps = wrapper.findAll('[data-testid^=input-hec-]');
10
-
11
- expect(inputWraps).toHaveLength(4);
12
- });
13
-
14
- it.each([
15
- 'name',
16
- 'container',
17
- ])('should emit an update on %p input', (field) => {
18
- const wrapper = mount(HarvesterEditContainer, { propsData: { mode: _EDIT, value: {} } });
19
- const input = wrapper.find(`[data-testid="input-hec-${ field }"]`).find('input');
20
- const newValue = 123;
21
-
22
- input.setValue(newValue);
23
-
24
- expect(wrapper.emitted('update')).toHaveLength(1);
25
- });
26
-
27
- it.each([
28
- 'type',
29
- 'bus',
30
- ])('should emit an update on %p selection change', async(field) => {
31
- const wrapper = mount(HarvesterEditContainer, { propsData: { mode: _EDIT, value: {} } });
32
- const select = wrapper.find(`[data-testid="input-hec-${ field }"]`);
33
-
34
- select.find('button').trigger('click');
35
- await wrapper.trigger('keydown.down');
36
- await wrapper.trigger('keydown.enter');
37
-
38
- expect(wrapper.emitted('update')).toHaveLength(1);
39
- });
40
- });