@rancher/shell 0.3.0 → 0.3.2

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 (342) hide show
  1. package/assets/styles/global/_button.scss +5 -1
  2. package/assets/styles/global/_columns.scss +4 -0
  3. package/assets/styles/global/_gauges.scss +1 -1
  4. package/assets/styles/global/_layout.scss +5 -2
  5. package/assets/styles/global/_select.scss +1 -4
  6. package/assets/styles/themes/_dark.scss +5 -4
  7. package/assets/styles/themes/_light.scss +4 -3
  8. package/assets/styles/themes/_suse.scss +1 -1
  9. package/assets/styles/vendor/vue-select.scss +4 -3
  10. package/assets/translations/en-us.yaml +673 -73
  11. package/assets/translations/zh-hans.yaml +720 -207
  12. package/chart/monitoring/steps/uninstall-v1.vue +2 -2
  13. package/cloud-credential/azure.vue +23 -0
  14. package/cloud-credential/harvester.vue +25 -62
  15. package/cloud-credential/pnap.vue +80 -0
  16. package/components/.DS_Store +0 -0
  17. package/components/ActionMenu.vue +28 -7
  18. package/components/AdvancedSection.vue +9 -2
  19. package/components/Alert.vue +2 -2
  20. package/components/ButtonDropdown.vue +0 -2
  21. package/components/ButtonGroup.vue +1 -0
  22. package/components/CollapsibleCard.vue +0 -1
  23. package/components/CruResource.vue +41 -4
  24. package/components/DetailTop.vue +72 -4
  25. package/components/DisableAuthProviderModal.vue +106 -0
  26. package/{rancher-components/components/Utils/DraggableZone → components}/DraggableZone.vue +0 -0
  27. package/components/ExplorerMembers.vue +253 -30
  28. package/components/ExplorerProjectsNamespaces.vue +77 -33
  29. package/components/ExtensionPanel.vue +42 -0
  30. package/components/GrowlManager.vue +3 -3
  31. package/components/IconOrSvg.vue +178 -0
  32. package/components/LogItem.vue +69 -0
  33. package/components/PodSecurityAdmission.vue +302 -0
  34. package/components/PromptModal.vue +1 -0
  35. package/components/ResourceDetail/Masthead.vue +69 -4
  36. package/components/ResourceDetail/index.vue +12 -5
  37. package/components/ResourceList/Masthead.vue +11 -1
  38. package/components/ResourceList/ResourceLoadingIndicator.vue +12 -2
  39. package/components/ResourceList/index.vue +66 -12
  40. package/components/ResourceList/resource-list.config.js +7 -0
  41. package/components/ResourceTable.vue +33 -6
  42. package/components/SimpleBox.vue +1 -1
  43. package/components/SortableTable/THead.vue +21 -14
  44. package/components/SortableTable/filtering.js +1 -1
  45. package/components/SortableTable/index.vue +21 -10
  46. package/components/SortableTable/selection.js +15 -3
  47. package/components/Tabbed/Tab.vue +1 -1
  48. package/components/Tabbed/index.vue +20 -15
  49. package/components/__tests__/.DS_Store +0 -0
  50. package/components/__tests__/AsyncButton.test.ts +140 -0
  51. package/components/__tests__/BackLink.test.ts +33 -0
  52. package/components/__tests__/ButtonGroup.test.ts +124 -0
  53. package/components/__tests__/ClusterBadge.test.ts +32 -0
  54. package/components/__tests__/CollapsibleCard.test.ts +64 -0
  55. package/components/__tests__/ConsumptionGauge.test.ts +88 -0
  56. package/components/__tests__/CruResource.test.ts +3 -2
  57. package/components/__tests__/FixedBanner.test.ts +129 -0
  58. package/components/__tests__/GrowlManager.test.ts +147 -0
  59. package/components/__tests__/NamespaceFilter.test.ts +33 -25
  60. package/components/__tests__/PercentageBar.test.ts +32 -0
  61. package/components/__tests__/PodSecurityAdmission.test.ts +398 -0
  62. package/components/auth/AuthBanner.vue +20 -10
  63. package/components/auth/RoleDetailEdit.vue +26 -17
  64. package/components/auth/SelectPrincipal.vue +36 -5
  65. package/components/form/ArrayList.vue +3 -35
  66. package/components/form/ArrayListGrouped.vue +13 -4
  67. package/components/form/ArrayListSelect.vue +5 -5
  68. package/components/form/Error.vue +8 -0
  69. package/components/form/KeyValue.vue +39 -7
  70. package/components/form/LabeledSelect.vue +5 -2
  71. package/components/form/Labels.vue +46 -16
  72. package/components/form/Members/ClusterPermissionsEditor.vue +17 -17
  73. package/components/form/Members/MembershipEditor.vue +12 -12
  74. package/components/form/NameNsDescription.vue +1 -1
  75. package/components/form/NodeScheduling.vue +1 -1
  76. package/components/form/Probe.vue +3 -3
  77. package/components/form/ResourceQuota/Project.vue +6 -6
  78. package/components/form/ResourceTabs/index.vue +24 -6
  79. package/components/form/Security.vue +7 -6
  80. package/components/form/Select.vue +3 -2
  81. package/components/form/SelectOrCreateAuthSecret.vue +22 -29
  82. package/components/form/ServicePorts.vue +8 -0
  83. package/components/form/WorkloadPorts.vue +7 -1
  84. package/components/form/__tests__/ArrayList.test.ts +74 -0
  85. package/components/form/__tests__/ArrayListGrouped.test.ts +6 -4
  86. package/components/formatter/Checked.vue +1 -1
  87. package/components/formatter/ClusterLink.vue +5 -0
  88. package/components/formatter/IconIsDefault.vue +2 -2
  89. package/components/formatter/InternalExternalIP.vue +11 -8
  90. package/components/formatter/LiveDuration.vue +78 -0
  91. package/components/formatter/WorkloadHealthScale.vue +5 -3
  92. package/components/nav/Header.vue +74 -7
  93. package/components/nav/NamespaceFilter.vue +146 -63
  94. package/components/nav/TopLevelMenu.vue +22 -19
  95. package/components/nav/WindowManager/ContainerLogs.vue +83 -126
  96. package/components/nav/WindowManager/ContainerShell.vue +9 -7
  97. package/components/nav/WindowManager/Window.vue +2 -0
  98. package/components/nav/WindowManager/index.vue +10 -0
  99. package/config/elemental-types.js +9 -0
  100. package/config/features.js +2 -0
  101. package/config/home-links.js +4 -1
  102. package/config/pod-security-admission.ts +82 -0
  103. package/config/product/apps.js +1 -1
  104. package/config/product/auth.js +6 -5
  105. package/config/product/backup.js +1 -1
  106. package/config/product/explorer.js +6 -6
  107. package/config/product/fleet.js +1 -1
  108. package/config/product/manager.js +6 -2
  109. package/config/query-params.js +1 -0
  110. package/config/secret.js +0 -1
  111. package/config/settings.ts +26 -9
  112. package/config/table-headers.js +22 -11
  113. package/config/types.js +4 -1
  114. package/config/uiplugins.js +3 -3
  115. package/content/docs/zh-hans/getting-started.md +113 -137
  116. package/content/docs/zh-hans/whats-new.md +8 -46
  117. package/core/plugin-helpers.js +171 -0
  118. package/core/plugin.ts +61 -1
  119. package/core/plugins.js +33 -0
  120. package/core/types.ts +128 -2
  121. package/creators/pkg/package-lock.json +37 -0
  122. package/creators/pkg/package.json +1 -1
  123. package/detail/catalog.cattle.io.app.vue +1 -1
  124. package/detail/pod.vue +1 -1
  125. package/detail/provisioning.cattle.io.cluster.vue +35 -9
  126. package/detail/service.vue +2 -9
  127. package/detail/workload/index.vue +0 -1
  128. package/dialog/AddClusterMemberDialog.vue +22 -28
  129. package/dialog/AddProjectMemberDialog.vue +53 -9
  130. package/dialog/DiagnosticTimingsDialog.vue +8 -7
  131. package/dialog/DrainNode.vue +44 -48
  132. package/dialog/ForceMachineRemoveDialog.vue +5 -7
  133. package/dialog/GenericPrompt.vue +15 -20
  134. package/dialog/RollbackWorkloadDialog.vue +15 -46
  135. package/dialog/RotateCertificatesDialog.vue +5 -7
  136. package/dialog/RotateEncryptionKeyDialog.vue +5 -9
  137. package/dialog/SaveAsRKETemplateDialog.vue +5 -13
  138. package/dialog/ScaleMachineDownDialog.vue +1 -1
  139. package/dialog/ScalePoolDownDialog.vue +121 -0
  140. package/edit/__tests__/management.cattle.io.setting.test.ts +3 -3
  141. package/edit/auth/azuread.vue +16 -16
  142. package/edit/auth/github.vue +8 -0
  143. package/edit/auth/googleoauth.vue +10 -1
  144. package/edit/auth/ldap/index.vue +10 -0
  145. package/edit/auth/oidc.vue +10 -0
  146. package/edit/auth/saml.vue +10 -0
  147. package/edit/autoscaling.horizontalpodautoscaler/index.vue +1 -1
  148. package/edit/catalog.cattle.io.clusterrepo.vue +3 -0
  149. package/edit/cloudcredential.vue +3 -7
  150. package/edit/logging-flow/Match.vue +39 -8
  151. package/edit/logging-flow/index.vue +27 -4
  152. package/edit/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +107 -0
  153. package/edit/management.cattle.io.project.vue +8 -1
  154. package/edit/management.cattle.io.setting.vue +5 -2
  155. package/edit/management.cattle.io.user.vue +7 -1
  156. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +36 -8
  157. package/edit/monitoring.coreos.com.alertmanagerconfig/types/email.vue +2 -2
  158. package/edit/monitoring.coreos.com.prometheusrule/GroupRules.vue +14 -6
  159. package/edit/namespace.vue +18 -4
  160. package/edit/networking.k8s.io.ingress/Certificate.vue +1 -0
  161. package/edit/networking.k8s.io.ingress/IngressClass.vue +8 -6
  162. package/edit/networking.k8s.io.ingress/RulePath.vue +12 -6
  163. package/edit/networking.k8s.io.ingress/index.vue +8 -6
  164. package/edit/persistentvolume/index.vue +30 -27
  165. package/edit/persistentvolume/plugins/cephfs.vue +29 -29
  166. package/edit/persistentvolume/plugins/csi.vue +102 -62
  167. package/edit/persistentvolume/plugins/fc.vue +19 -19
  168. package/edit/persistentvolume/plugins/iscsi.vue +45 -45
  169. package/edit/persistentvolume/plugins/rbd.vue +39 -39
  170. package/edit/persistentvolumeclaim.vue +78 -75
  171. package/edit/provisioning.cattle.io.cluster/MachinePool.vue +11 -7
  172. package/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue +10 -1
  173. package/edit/provisioning.cattle.io.cluster/RegistryMirrors.vue +87 -27
  174. package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +3 -6
  175. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +96 -0
  176. package/edit/provisioning.cattle.io.cluster/import.vue +1 -1
  177. package/edit/provisioning.cattle.io.cluster/index.vue +29 -6
  178. package/edit/provisioning.cattle.io.cluster/rke2.vue +445 -154
  179. package/edit/secret/index.vue +3 -7
  180. package/edit/service.vue +3 -1
  181. package/edit/storage.k8s.io.storageclass/index.vue +100 -16
  182. package/edit/storage.k8s.io.storageclass/provisioners/driver.harvesterhci.io.vue +114 -0
  183. package/edit/workload/__tests__/index.test.ts +98 -0
  184. package/edit/workload/index.vue +58 -8
  185. package/edit/workload/mixins/workload.js +107 -70
  186. package/edit/workload/storage/ContainerMountPaths.vue +0 -10
  187. package/edit/workload/storage/emptyDir.vue +88 -0
  188. package/edit/workload/storage/ephemeralVolume/index.vue +1 -1
  189. package/edit/workload/storage/index.vue +8 -0
  190. package/edit/workload/storage/persistentVolumeClaim/index.vue +1 -1
  191. package/layouts/default.vue +57 -44
  192. package/list/__tests__/workload.test.ts +5 -2
  193. package/list/catalog.cattle.io.app.vue +1 -0
  194. package/list/cis.cattle.io.clusterscan.vue +1 -0
  195. package/list/fleet.cattle.io.bundle.vue +5 -6
  196. package/list/fleet.cattle.io.cluster.vue +6 -3
  197. package/list/fleet.cattle.io.clusterregistrationtoken.vue +5 -6
  198. package/list/fleet.cattle.io.gitrepo.vue +4 -9
  199. package/list/helm.cattle.io.projecthelmchart.vue +1 -5
  200. package/list/logging.banzaicloud.io.clusterflow.vue +4 -1
  201. package/list/logging.banzaicloud.io.flow.vue +6 -5
  202. package/list/management.cattle.io.cluster.vue +1 -0
  203. package/list/management.cattle.io.feature.vue +3 -4
  204. package/list/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +47 -0
  205. package/list/management.cattle.io.setting.vue +2 -2
  206. package/list/management.cattle.io.user.vue +4 -10
  207. package/list/monitoring.coreos.com.alertmanagerconfig.vue +2 -7
  208. package/list/node.vue +8 -5
  209. package/list/persistentvolume.vue +3 -3
  210. package/list/persistentvolumeclaim.vue +3 -4
  211. package/list/provisioning.cattle.io.cluster.vue +18 -19
  212. package/list/service.vue +6 -14
  213. package/list/workload.vue +43 -38
  214. package/machine-config/azure.vue +429 -60
  215. package/machine-config/pnap.vue +288 -0
  216. package/mixins/auth-config.js +1 -3
  217. package/mixins/browser-tab-visibility.js +8 -14
  218. package/mixins/chart.js +1 -1
  219. package/mixins/create-edit-view/impl.js +4 -0
  220. package/mixins/create-edit-view/index.js +4 -2
  221. package/mixins/resource-fetch-namespaced.js +98 -0
  222. package/mixins/resource-fetch.js +79 -45
  223. package/mixins/resource-manager.js +1 -23
  224. package/models/apps.controllerrevision.js +7 -0
  225. package/models/apps.daemonset.js +18 -0
  226. package/models/apps.deployment.js +44 -0
  227. package/models/apps.replicaset.js +7 -0
  228. package/models/apps.statefulset.js +18 -0
  229. package/models/batch.job.js +7 -14
  230. package/models/cluster/node.js +10 -2
  231. package/models/cluster.x-k8s.io.machine.js +26 -4
  232. package/models/cluster.x-k8s.io.machinedeployment.js +12 -2
  233. package/models/event.js +7 -0
  234. package/models/logging.banzaicloud.io.flow.js +4 -0
  235. package/models/management.cattle.io.cluster.js +1 -1
  236. package/models/management.cattle.io.clusterroletemplatebinding.js +1 -1
  237. package/models/management.cattle.io.globalrole.js +2 -2
  238. package/models/management.cattle.io.node.js +37 -2
  239. package/models/management.cattle.io.podsecurityadmissionconfigurationtemplate.ts +4 -0
  240. package/models/management.cattle.io.project.js +30 -11
  241. package/models/management.cattle.io.setting.js +1 -1
  242. package/models/management.cattle.io.user.js +37 -1
  243. package/models/namespace.js +42 -5
  244. package/models/persistentvolume.js +14 -2
  245. package/models/pod.js +15 -0
  246. package/models/projectroletemplatebinding.js +7 -0
  247. package/models/provisioning.cattle.io.cluster.js +61 -10
  248. package/models/rke-machine.cattle.io.pnapmachinetemplate.js +15 -0
  249. package/models/service.js +14 -13
  250. package/models/storage.k8s.io.storageclass.js +33 -18
  251. package/models/workload.js +38 -7
  252. package/nuxt.config.js +27 -17
  253. package/package.json +7 -7
  254. package/pages/about.vue +14 -2
  255. package/pages/c/_cluster/apps/charts/index.vue +21 -3
  256. package/pages/c/_cluster/apps/charts/install.vue +59 -22
  257. package/pages/c/_cluster/auth/config/_id.vue +6 -0
  258. package/pages/c/_cluster/auth/config/index.vue +8 -6
  259. package/pages/c/_cluster/auth/group.principal/assign-edit.vue +1 -1
  260. package/pages/c/_cluster/auth/roles/index.vue +1 -1
  261. package/pages/c/_cluster/explorer/index.vue +51 -6
  262. package/pages/c/_cluster/longhorn/index.vue +1 -1
  263. package/pages/c/_cluster/monitoring/alertmanagerconfig/_alertmanagerconfigid/receiver.vue +15 -4
  264. package/pages/c/_cluster/monitoring/index.vue +1 -1
  265. package/pages/c/_cluster/neuvector/index.vue +1 -1
  266. package/pages/c/_cluster/settings/performance.vue +48 -2
  267. package/pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue +2 -0
  268. package/pages/c/_cluster/uiplugins/InstallDialog.vue +3 -0
  269. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +42 -2
  270. package/pages/c/_cluster/uiplugins/RemoveUIPlugins.vue +2 -0
  271. package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +1 -0
  272. package/pages/c/_cluster/uiplugins/UninstallDialog.vue +2 -0
  273. package/pages/c/_cluster/uiplugins/index.vue +42 -3
  274. package/pages/diagnostic.vue +5 -4
  275. package/pages/home.vue +105 -30
  276. package/pages/prefs.vue +23 -12
  277. package/pages/rio/mesh.vue +1 -1
  278. package/pkg/dynamic-importer.lib.js +8 -0
  279. package/pkg/vue.config.js +4 -0
  280. package/plugins/dashboard-store/__tests__/mutations.spec.js +406 -0
  281. package/plugins/dashboard-store/actions.js +32 -25
  282. package/plugins/dashboard-store/getters.js +50 -33
  283. package/plugins/dashboard-store/mutations.js +134 -28
  284. package/plugins/dashboard-store/resource-class.js +37 -42
  285. package/plugins/steve/actions.js +30 -0
  286. package/plugins/steve/caches/resourceCache.js +60 -0
  287. package/plugins/steve/getters.js +44 -1
  288. package/plugins/steve/mutations.js +97 -36
  289. package/plugins/steve/resourceWatcher.js +277 -0
  290. package/plugins/steve/schema.utils.js +25 -0
  291. package/plugins/steve/subscribe.js +288 -115
  292. package/plugins/steve/worker/index.js +17 -0
  293. package/plugins/steve/worker/web-worker.advanced.js +302 -0
  294. package/plugins/steve/{web-worker.steve-sub-worker.js → worker/web-worker.basic.js} +3 -44
  295. package/rancher-components/Card/Card.vue +3 -3
  296. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +1 -0
  297. package/rancher-components/StringList/StringList.test.ts +45 -420
  298. package/rancher-components/StringList/StringList.vue +1 -10
  299. package/rancher-components/components/Banner/Banner.test.ts +44 -0
  300. package/rancher-components/components/Banner/Banner.vue +130 -61
  301. package/rancher-components/components/Form/Checkbox/Checkbox.test.ts +13 -22
  302. package/rancher-components/components/Form/Checkbox/Checkbox.vue +8 -6
  303. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.test.ts +9 -9
  304. package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +0 -1
  305. package/rancher-components/components/StringList/StringList.test.ts +7 -7
  306. package/rancher-components/components/StringList/StringList.vue +21 -15
  307. package/scripts/test-plugins-build.sh +8 -0
  308. package/static/loading-indicator.html +1 -1
  309. package/store/action-menu.js +4 -3
  310. package/store/index.js +54 -3
  311. package/store/plugins.js +0 -17
  312. package/store/pnap.js +128 -0
  313. package/store/prefs.js +4 -2
  314. package/store/type-map.js +81 -13
  315. package/types/pod-security-admission.ts +36 -0
  316. package/types/shell/index.d.ts +497 -396
  317. package/utils/__tests__/object.test.ts +17 -1
  318. package/utils/__tests__/pod-security-admission.test.ts +61 -0
  319. package/utils/async.ts +36 -0
  320. package/utils/color.js +45 -0
  321. package/utils/crypto/browserHashUtils.js +18 -0
  322. package/utils/dynamic-importer.js +8 -0
  323. package/utils/install-redirect.js +1 -1
  324. package/utils/object.js +24 -0
  325. package/utils/pod-security-admission.ts +39 -0
  326. package/utils/socket.js +61 -24
  327. package/utils/string.js +2 -0
  328. package/utils/svg-filter.js +301 -0
  329. package/utils/time.js +49 -0
  330. package/utils/validators/cidr.js +4 -0
  331. package/utils/validators/formRules/__tests__/index.test.ts +23 -3
  332. package/utils/validators/formRules/index.ts +14 -0
  333. package/config/product/harvester-manager.js +0 -162
  334. package/edit/harvesterhci.io.management.cluster.vue +0 -153
  335. package/list/harvesterhci.io.management.cluster.vue +0 -241
  336. package/machine-config/harvester.vue +0 -693
  337. package/models/harvesterhci.io.management.cluster.js +0 -228
  338. package/pages/c/_cluster/harvesterManager/index.vue +0 -24
  339. package/rancher-components/Card/Card.test.ts +0 -39
  340. package/rancher-components/Utils/DraggableZone/DraggableZone.vue +0 -181
  341. package/rancher-components/Utils/DraggableZone/index.ts +0 -1
  342. package/rancher-components/components/Utils/DraggableZone/index.ts +0 -1
@@ -40,8 +40,8 @@ export default {
40
40
  methods: {
41
41
  uninstall(buttonCb) {
42
42
  this.$store.dispatch('cluster/promptModal', {
43
- component: 'GenericPrompt',
44
- resources: {
43
+ component: 'GenericPrompt',
44
+ componentProps: {
45
45
  applyMode: 'uninstall',
46
46
  applyAction: async(buttonDone) => {
47
47
  await this.$store.getters['currentCluster'].doAction('disableMonitoring');
@@ -4,6 +4,9 @@ import { LabeledInput } from '@components/Form/LabeledInput';
4
4
  import { azureEnvironments } from '@shell/machine-config/azure';
5
5
  import LabeledSelect from '@shell/components/form/LabeledSelect';
6
6
 
7
+ const AZURE_ERROR_MSG_REGEX = /^.*Message=\"(.*)\"$/;
8
+ const AZURE_ERROR_JSON_REGEX = /^.*Response body: ({.*})/;
9
+
7
10
  export default {
8
11
  components: { LabeledInput, LabeledSelect },
9
12
  mixins: [CreateEditView],
@@ -53,6 +56,26 @@ export default {
53
56
 
54
57
  return true;
55
58
  } catch (e) {
59
+ if (e.error) {
60
+ // Try and parse the response from Azure a couple of ways
61
+ const msgMatch = e.error.match(AZURE_ERROR_MSG_REGEX);
62
+
63
+ if (msgMatch?.length === 2) {
64
+ return { errors: [msgMatch[1]] };
65
+ } else {
66
+ const jsonMatch = e.error.match(AZURE_ERROR_JSON_REGEX);
67
+
68
+ if (jsonMatch?.length === 2) {
69
+ try {
70
+ const errorObj = JSON.parse(jsonMatch[1]);
71
+
72
+ return { errors: [errorObj.error_description] };
73
+ } catch (e) {}
74
+ }
75
+ }
76
+ }
77
+
78
+ // Can't parse error, so go with the generic 'auth failed' error message
56
79
  return false;
57
80
  }
58
81
  },
@@ -1,19 +1,13 @@
1
1
  <script>
2
2
  import CreateEditView from '@shell/mixins/create-edit-view';
3
- import { LabeledInput } from '@components/Form/LabeledInput';
4
3
  import LabeledSelect from '@shell/components/form/LabeledSelect';
5
- import { RadioGroup } from '@components/Form/Radio';
6
4
 
7
5
  import { get, set } from '@shell/utils/object';
8
6
  import { MANAGEMENT, VIRTUAL_HARVESTER_PROVIDER } from '@shell/config/types';
9
7
 
10
- const IMPORTED = 'imported';
11
-
12
8
  export default {
13
- components: {
14
- LabeledInput, LabeledSelect, RadioGroup
15
- },
16
- mixins: [CreateEditView],
9
+ components: { LabeledSelect },
10
+ mixins: [CreateEditView],
17
11
 
18
12
  async fetch() {
19
13
  this.clusters = await this.$store.dispatch('management/findAll', { type: MANAGEMENT.CLUSTER });
@@ -22,16 +16,11 @@ export default {
22
16
  data() {
23
17
  this.$emit('validationChanged', true);
24
18
 
25
- if (!this.value.decodedData.clusterType) {
26
- this.value.setData('clusterType', IMPORTED);
27
- }
28
-
29
19
  const cluster = get(this.value, 'harvestercredentialConfig.clusterId') || '';
30
20
 
31
21
  return {
32
22
  clusters: [],
33
23
  cluster,
34
- IMPORTED,
35
24
  };
36
25
  },
37
26
 
@@ -44,22 +33,9 @@ export default {
44
33
  };
45
34
  });
46
35
  },
47
-
48
- isImportCluster() {
49
- return this.value.decodedData.clusterType === IMPORTED;
50
- }
51
36
  },
52
37
 
53
38
  watch: {
54
- 'value.decodedData.clusterType': {
55
- handler(neu) {
56
- if (this.isCreate) {
57
- this.value.setData('kubeconfigContent', '');
58
- this.cluster = '';
59
- }
60
- },
61
- },
62
-
63
39
  async cluster(neu) {
64
40
  if (!neu) {
65
41
  return;
@@ -78,51 +54,51 @@ export default {
78
54
  this.$nuxt.$loading.finish();
79
55
 
80
56
  this.value.setData('kubeconfigContent', kubeconfigContent);
81
- }
57
+ },
58
+
59
+ 'value.decodedData.clusterId': {
60
+ handler() {
61
+ this.emitValidation();
62
+ },
63
+ immediate: true,
64
+ },
65
+ 'value.decodedData.kubeconfigContent': {
66
+ handler() {
67
+ this.emitValidation();
68
+ },
69
+ immediate: true,
70
+ },
82
71
  },
83
72
 
84
73
  methods: {
85
74
  test() {
86
75
  const t = this.$store.getters['i18n/t'];
87
76
 
88
- if (!this.cluster && this.isImportCluster) {
77
+ if (!this.cluster) {
89
78
  const cluster = t('cluster.credential.harvester.cluster');
90
79
  const errors = [t('validation.required', { key: cluster })];
91
80
 
92
81
  return { errors };
82
+ } else {
83
+ return true;
93
84
  }
85
+ },
94
86
 
95
- if (!this.value.decodedData.kubeconfigContent) {
96
- const kubeconfigContent = t('cluster.credential.harvester.kubeconfigContent.label');
97
-
98
- const errors = [t('validation.required', { key: kubeconfigContent })];
99
-
100
- return { errors };
87
+ emitValidation() {
88
+ if (this.test() === true) {
89
+ this.$emit('validationChanged', true);
101
90
  } else {
102
- return true;
91
+ this.$emit('validationChanged', false);
103
92
  }
104
93
  },
105
- }
94
+ },
106
95
  };
107
96
  </script>
108
97
 
109
98
  <template>
110
99
  <div>
111
- <div class="row mb-10">
112
- <RadioGroup
113
- v-model="value.decodedData.clusterType"
114
- :mode="mode"
115
- :disabled="isEdit"
116
- name="clusterType"
117
- :labels="[t('cluster.credential.harvester.import'),t('cluster.credential.harvester.external')]"
118
- :options="[IMPORTED, 'external']"
119
- @input="value.setData('clusterType', $event);"
120
- />
121
- </div>
122
-
123
100
  <div class="row mb-10">
124
101
  <div
125
- v-if="isImportCluster"
126
102
  class="col span-6"
127
103
  >
128
104
  <LabeledSelect
@@ -134,19 +110,6 @@ export default {
134
110
  :label="t('cluster.credential.harvester.cluster')"
135
111
  />
136
112
  </div>
137
-
138
- <div class="col span-6">
139
- <LabeledInput
140
- v-if="!isImportCluster"
141
- :value="value.decodedData.kubeconfigContent"
142
- label-key="cluster.credential.harvester.kubeconfigContent.label"
143
- :required="true"
144
- type="multiline"
145
- :min-height="160"
146
- :mode="mode"
147
- @input="value.setData('kubeconfigContent', $event);"
148
- />
149
- </div>
150
113
  </div>
151
114
  </div>
152
115
  </template>
@@ -0,0 +1,80 @@
1
+ <script>
2
+ import CreateEditView from '@shell/mixins/create-edit-view';
3
+ import { LabeledInput } from '@components/Form/LabeledInput';
4
+ import { base64Encode } from '@shell/utils/crypto';
5
+
6
+ export default {
7
+ components: { LabeledInput },
8
+ mixins: [CreateEditView],
9
+
10
+ watch: {
11
+ 'value.decodedData.clientIdentifier'(neu) {
12
+ this.$emit('validationChanged', !!neu);
13
+ },
14
+ 'value.decodedData.clientSecret'(neu) {
15
+ this.$emit('validationChanged', !!neu);
16
+ }
17
+ },
18
+
19
+ methods: {
20
+ async test() {
21
+ try {
22
+ const credentials = `${ this.value.decodedData.clientIdentifier }:${ this.value.decodedData.clientSecret }`;
23
+ const encoded = base64Encode(credentials);
24
+
25
+ const requestOptions = {
26
+ url: 'meta/proxy/auth.phoenixnap.com/auth/realms/BMC/protocol/openid-connect/token/',
27
+ method: 'POST',
28
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'X-API-Auth-Header': `Basic ${ encoded }` },
29
+ data: 'grant_type=client_credentials',
30
+ redirectUnauthorized: false,
31
+ };
32
+
33
+ const response = await this.$store.dispatch('management/request', requestOptions);
34
+ const data = await response;
35
+
36
+ if (data.access_token !== undefined && data.access_token !== null && data.access_token !== '') {
37
+ return true;
38
+ }
39
+
40
+ return false;
41
+ } catch (e) {
42
+ return false;
43
+ }
44
+ }
45
+ }
46
+ };
47
+ </script>
48
+
49
+ <template>
50
+ <div>
51
+ <div class="row mt-20">
52
+ <div class="col span-6">
53
+ <LabeledInput
54
+ :value="value.decodedData.clientIdentifier"
55
+ label-key="cluster.credential.pnap.clientIdentifier.label"
56
+ placeholder-key="cluster.credential.pnap.clientIdentifier.placeholder"
57
+ type="text"
58
+ :mode="mode"
59
+ @input="value.setData('clientIdentifier', $event);"
60
+ />
61
+ </div>
62
+ <div class="col span-6">
63
+ <LabeledInput
64
+ :value="value.decodedData.clientSecret"
65
+ label-key="cluster.credential.pnap.clientSecret.label"
66
+ placeholder-key="cluster.credential.pnap.clientSecret.placeholder"
67
+ type="text"
68
+ :mode="mode"
69
+ @input="value.setData('clientSecret', $event);"
70
+ />
71
+ </div>
72
+ </div>
73
+ <div class="row mt-5">
74
+ <p
75
+ class="text-muted mt-10"
76
+ v-html="t('cluster.credential.pnap.clientSecret.help', {}, true)"
77
+ />
78
+ </div>
79
+ </div>
80
+ </template>
Binary file
@@ -3,15 +3,16 @@ import { mapGetters } from 'vuex';
3
3
  import $ from 'jquery';
4
4
  import { AUTO, CENTER, fitOnScreen } from '@shell/utils/position';
5
5
  import { isAlternate } from '@shell/utils/platform';
6
+ import IconOrSvg from '@shell/components/IconOrSvg';
6
7
 
7
8
  const HIDDEN = 'hide';
8
9
  const CALC = 'calculate';
9
10
  const SHOW = 'show';
10
11
 
11
12
  export default {
12
- name: 'ActionMenu',
13
-
14
- props: {
13
+ name: 'ActionMenu',
14
+ components: { IconOrSvg },
15
+ props: {
15
16
  customActions: {
16
17
  // Custom actions can be used if you need the action
17
18
  // menu to work for something that is not a Kubernetes
@@ -194,7 +195,23 @@ export default {
194
195
  return;
195
196
  }
196
197
 
197
- if (this.useCustomTargetElement) {
198
+ // this will come from extensions...
199
+ if (action.invoke) {
200
+ const fn = action.invoke;
201
+
202
+ if (fn && action.enabled) {
203
+ const resources = this.$store.getters['action-menu/resources'];
204
+ const opts = {
205
+ event,
206
+ action,
207
+ isAlt: isAlternate(event)
208
+ };
209
+
210
+ if (resources.length === 1) {
211
+ fn.apply(this, [opts, resources]);
212
+ }
213
+ }
214
+ } else if (this.useCustomTargetElement) {
198
215
  // If the state of this component is controlled
199
216
  // by props instead of Vuex, we assume you wouldn't want
200
217
  // the mutation to have a dependency on Vuex either.
@@ -247,12 +264,16 @@ export default {
247
264
  :data-testid="componentTestid + '-' + i + '-item'"
248
265
  @click="execute(opt, $event)"
249
266
  >
250
- <i
251
- v-if="opt.icon"
252
- :class="{icon: true, [opt.icon]: true}"
267
+ <IconOrSvg
268
+ v-if="opt.icon || opt.svg"
269
+ :icon="opt.icon"
270
+ :src="opt.svg"
271
+ class="icon"
272
+ color="header"
253
273
  />
254
274
  <span v-html="opt.label" />
255
275
  </li>
276
+
256
277
  <li
257
278
  v-if="!hasOptions(menuOptions)"
258
279
  class="no-actions"
@@ -5,10 +5,17 @@ export default {
5
5
  type: String,
6
6
  required: true,
7
7
  },
8
+ isOpenByDefault: {
9
+ // It may be useful to keep the advanced options open
10
+ // if the form is in edit mode and it has non-default
11
+ // advanced options configured.
12
+ type: Boolean,
13
+ default: false
14
+ }
8
15
  },
9
16
 
10
- data() {
11
- return { show: false };
17
+ data(props) {
18
+ return { show: props.isOpenByDefault };
12
19
  },
13
20
 
14
21
  methods: {
@@ -8,11 +8,11 @@ const STATUS_CLASS_MAP = {
8
8
  },
9
9
  warning: {
10
10
  color: 'bg-warning',
11
- icon: 'icon-error'
11
+ icon: 'icon-warning'
12
12
  },
13
13
  info: {
14
14
  color: 'bg-info',
15
- icon: 'icon-error'
15
+ icon: 'icon-info'
16
16
  },
17
17
  error: {
18
18
  color: 'bg-error',
@@ -277,12 +277,10 @@ export default {
277
277
  background: transparent;
278
278
 
279
279
  .vs__actions {
280
- justify-content: center;
281
280
 
282
281
  &:after {
283
282
  color: var(--link);
284
283
  line-height: 1;
285
- padding-top: 5px;
286
284
  }
287
285
  }
288
286
  }
@@ -76,6 +76,7 @@ export default {
76
76
  v-for="(opt,idx) in optionObjects"
77
77
  :key="idx"
78
78
  v-tooltip="opt.tooltipKey ? t(opt.tooltipKey) : opt.tooltip"
79
+ :data-testid="`button-group-child-${idx}`"
79
80
  type="button"
80
81
  :class="opt.class"
81
82
  :disabled="disabled || opt.disabled"
@@ -105,7 +105,6 @@ export default {
105
105
  }
106
106
 
107
107
  &-collapse-icon {
108
- font-size: 24px;
109
108
  color: #B7B8BB;
110
109
  }
111
110
 
@@ -75,6 +75,14 @@ export default {
75
75
  default: () => []
76
76
  },
77
77
 
78
+ /**
79
+ * Set of maps to convert error messages to something more user friendly and apply icons
80
+ */
81
+ errorsMap: {
82
+ type: Object,
83
+ default: null
84
+ },
85
+
78
86
  // Is the edit as yaml button allowed
79
87
  canYaml: {
80
88
  type: Boolean,
@@ -128,6 +136,11 @@ export default {
128
136
  componentTestid: {
129
137
  type: String,
130
138
  default: 'form'
139
+ },
140
+
141
+ description: {
142
+ type: String,
143
+ default: ''
131
144
  }
132
145
  },
133
146
 
@@ -152,7 +165,7 @@ export default {
152
165
  4: '18px',
153
166
  5: '16px',
154
167
  6: '14px'
155
- }
168
+ },
156
169
  };
157
170
  },
158
171
 
@@ -225,6 +238,19 @@ export default {
225
238
  hasErrors() {
226
239
  return this.errors?.length && Array.isArray(this.errors);
227
240
  },
241
+
242
+ /**
243
+ * Replace returned string with new picked value and icon
244
+ */
245
+ mappedErrors() {
246
+ return !this.errors ? {} : this.errorsMap || this.errors.reduce((acc, error) => ({
247
+ ...acc,
248
+ [error]: {
249
+ message: error,
250
+ icon: null
251
+ }
252
+ }), {});
253
+ },
228
254
  },
229
255
 
230
256
  created() {
@@ -358,6 +384,12 @@ export default {
358
384
  <template>
359
385
  <section class="cru">
360
386
  <slot name="noticeBanner" />
387
+ <p
388
+ v-if="description"
389
+ class="description"
390
+ >
391
+ {{ description }}
392
+ </p>
361
393
  <form
362
394
  :is="(isView? 'div' : 'form')"
363
395
  class="create-resource-container cru__form"
@@ -373,8 +405,8 @@ export default {
373
405
  v-for="(err, i) in errors"
374
406
  :key="i"
375
407
  color="error"
376
- :label="stringify(err)"
377
- :stacked="true"
408
+ :label="stringify(mappedErrors[err].message)"
409
+ :icon="mappedErrors[err].icon"
378
410
  :closable="true"
379
411
  @close="closeError(i)"
380
412
  />
@@ -619,7 +651,7 @@ export default {
619
651
  </template>
620
652
  <!------ YAML ------>
621
653
  <section
622
- v-else
654
+ v-else-if="showYaml"
623
655
  class="cru-resource-yaml-container resource-container cru__content"
624
656
  >
625
657
  <ResourceYaml
@@ -805,4 +837,9 @@ form.create-resource-container .cru {
805
837
  }
806
838
  }
807
839
 
840
+ .description {
841
+ margin-bottom: 15px;
842
+ margin-top: 5px;
843
+ }
844
+
808
845
  </style>
@@ -3,11 +3,15 @@ import Tag from '@shell/components/Tag';
3
3
  import isEmpty from 'lodash/isEmpty';
4
4
  import DetailText from '@shell/components/DetailText';
5
5
  import { _VIEW } from '@shell/config/query-params';
6
+ import { ExtensionPoint, PanelLocation } from '@shell/core/types';
7
+ import ExtensionPanel from '@shell/components/ExtensionPanel';
6
8
 
7
9
  export const SEPARATOR = { separator: true };
8
10
 
9
11
  export default {
10
- components: { DetailText, Tag },
12
+ components: {
13
+ DetailText, Tag, ExtensionPanel
14
+ },
11
15
 
12
16
  props: {
13
17
  value: {
@@ -22,11 +26,35 @@ export default {
22
26
  default: () => {
23
27
  return [];
24
28
  }
29
+ },
30
+
31
+ /**
32
+ * Optionally replace key/value and display tooltips for the tab
33
+ * Dictionary key based
34
+ */
35
+ tooltips: {
36
+ type: Object,
37
+ default: () => {
38
+ return {};
39
+ }
40
+ },
41
+
42
+ /**
43
+ * Optionally display icons next to the tab
44
+ * Dictionary key based
45
+ */
46
+ icons: {
47
+ type: Object,
48
+ default: () => {
49
+ return {};
50
+ }
25
51
  }
26
52
  },
27
53
 
28
54
  data() {
29
55
  return {
56
+ extensionType: ExtensionPoint.PANEL,
57
+ extensionLocation: PanelLocation.DETAIL_TOP,
30
58
  annotationsVisible: false,
31
59
  showAllLabels: false,
32
60
  view: _VIEW
@@ -68,13 +96,21 @@ export default {
68
96
  },
69
97
 
70
98
  labels() {
71
- if (this.showAllLabels || !this.showFilteredSystemLabels) {
99
+ if (!this.showFilteredSystemLabels) {
72
100
  return this.value?.labels || {};
73
101
  }
74
102
 
75
103
  return this.value?.filteredSystemLabels;
76
104
  },
77
105
 
106
+ internalTooltips() {
107
+ return this.value?.detailTopTooltips || this.tooltips;
108
+ },
109
+
110
+ internalIcons() {
111
+ return this.value?.detailTopIcons || this.icons;
112
+ },
113
+
78
114
  annotations() {
79
115
  return this.value?.annotations || {};
80
116
  },
@@ -114,7 +150,16 @@ export default {
114
150
  },
115
151
 
116
152
  showFilteredSystemLabels() {
117
- return !!this.value.filteredSystemLabels;
153
+ // It would be nicer to use hasSystemLabels here, but not all places have implemented it
154
+ // Instead check that there's a discrepancy between all labels and all labels without system ones
155
+ if (this.value?.labels && this.value?.filteredSystemLabels) {
156
+ const labelCount = Object.keys(this.value.labels).length;
157
+ const filteredSystemLabelsCount = Object.keys(this.value.filteredSystemLabels).length;
158
+
159
+ return labelCount !== filteredSystemLabelsCount;
160
+ }
161
+
162
+ return false;
118
163
  },
119
164
  },
120
165
  methods: {
@@ -200,7 +245,19 @@ export default {
200
245
  v-for="(prop, key) in labels"
201
246
  :key="key + prop"
202
247
  >
203
- {{ key }}<span v-if="prop">: </span>{{ prop }}
248
+ <i
249
+ v-if="internalIcons[key]"
250
+ class="icon"
251
+ :class="internalIcons[key]"
252
+ />
253
+ <span
254
+ v-if="internalTooltips[key]"
255
+ v-tooltip="prop ? `${key} : ${prop}` : key"
256
+ >
257
+ <span>{{ internalTooltips[key] ? internalTooltips[key] : key }}</span>
258
+ <span v-if="showAllLabels">: {{ key }}</span>
259
+ </span>
260
+ <span v-else>{{ prop ? `${key} : ${prop}` : key }}</span>
204
261
  </Tag>
205
262
  <a
206
263
  v-if="showFilteredSystemLabels"
@@ -236,6 +293,13 @@ export default {
236
293
  />
237
294
  </div>
238
295
  </div>
296
+
297
+ <!-- Extensions area -->
298
+ <ExtensionPanel
299
+ :resource="value"
300
+ :type="extensionType"
301
+ :location="extensionLocation"
302
+ />
239
303
  </div>
240
304
  </template>
241
305
 
@@ -304,5 +368,9 @@ export default {
304
368
  margin-bottom: $spacing;
305
369
  }
306
370
  }
371
+
372
+ .icon {
373
+ vertical-align: top;
374
+ }
307
375
  }
308
376
  </style>