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