@rancher/shell 0.3.0 → 0.3.1

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 (322) 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/_layout.scss +1 -2
  4. package/assets/styles/global/_select.scss +1 -4
  5. package/assets/styles/themes/_dark.scss +4 -4
  6. package/assets/styles/themes/_light.scss +4 -3
  7. package/assets/styles/themes/_suse.scss +1 -1
  8. package/assets/styles/vendor/vue-select.scss +4 -3
  9. package/assets/translations/en-us.yaml +669 -73
  10. package/assets/translations/zh-hans.yaml +547 -165
  11. package/chart/monitoring/steps/uninstall-v1.vue +2 -2
  12. package/cloud-credential/azure.vue +23 -0
  13. package/cloud-credential/harvester.vue +25 -62
  14. package/cloud-credential/pnap.vue +80 -0
  15. package/components/.DS_Store +0 -0
  16. package/components/AdvancedSection.vue +9 -2
  17. package/components/Alert.vue +2 -2
  18. package/components/ButtonDropdown.vue +0 -2
  19. package/components/ButtonGroup.vue +1 -0
  20. package/components/CollapsibleCard.vue +0 -1
  21. package/components/CruResource.vue +41 -4
  22. package/components/DetailTop.vue +58 -3
  23. package/components/DisableAuthProviderModal.vue +106 -0
  24. package/{rancher-components/components/Utils/DraggableZone → components}/DraggableZone.vue +0 -0
  25. package/components/ExplorerMembers.vue +253 -30
  26. package/components/ExplorerProjectsNamespaces.vue +77 -33
  27. package/components/GrowlManager.vue +3 -3
  28. package/components/IconOrSvg.vue +149 -0
  29. package/components/LogItem.vue +69 -0
  30. package/components/PodSecurityAdmission.vue +302 -0
  31. package/components/PromptModal.vue +1 -0
  32. package/components/ResourceDetail/Masthead.vue +54 -2
  33. package/components/ResourceDetail/index.vue +12 -5
  34. package/components/ResourceList/Masthead.vue +11 -1
  35. package/components/ResourceList/ResourceLoadingIndicator.vue +12 -2
  36. package/components/ResourceList/index.vue +53 -12
  37. package/components/ResourceList/resource-list.config.js +7 -0
  38. package/components/ResourceTable.vue +31 -6
  39. package/components/SimpleBox.vue +1 -1
  40. package/components/SortableTable/THead.vue +15 -5
  41. package/components/SortableTable/index.vue +21 -10
  42. package/components/Tabbed/index.vue +20 -15
  43. package/components/__tests__/.DS_Store +0 -0
  44. package/components/__tests__/AsyncButton.test.ts +140 -0
  45. package/components/__tests__/BackLink.test.ts +33 -0
  46. package/components/__tests__/ButtonGroup.test.ts +124 -0
  47. package/components/__tests__/ClusterBadge.test.ts +32 -0
  48. package/components/__tests__/CollapsibleCard.test.ts +64 -0
  49. package/components/__tests__/ConsumptionGauge.test.ts +88 -0
  50. package/components/__tests__/CruResource.test.ts +3 -2
  51. package/components/__tests__/FixedBanner.test.ts +129 -0
  52. package/components/__tests__/GrowlManager.test.ts +147 -0
  53. package/components/__tests__/NamespaceFilter.test.ts +33 -25
  54. package/components/__tests__/PercentageBar.test.ts +32 -0
  55. package/components/__tests__/PodSecurityAdmission.test.ts +398 -0
  56. package/components/auth/AuthBanner.vue +20 -10
  57. package/components/auth/RoleDetailEdit.vue +26 -17
  58. package/components/auth/SelectPrincipal.vue +36 -5
  59. package/components/form/ArrayList.vue +3 -35
  60. package/components/form/ArrayListGrouped.vue +13 -4
  61. package/components/form/ArrayListSelect.vue +5 -5
  62. package/components/form/Error.vue +8 -0
  63. package/components/form/KeyValue.vue +39 -7
  64. package/components/form/LabeledSelect.vue +5 -2
  65. package/components/form/Labels.vue +46 -16
  66. package/components/form/Members/ClusterPermissionsEditor.vue +17 -17
  67. package/components/form/Members/MembershipEditor.vue +12 -12
  68. package/components/form/NameNsDescription.vue +1 -1
  69. package/components/form/NodeScheduling.vue +1 -1
  70. package/components/form/Probe.vue +3 -3
  71. package/components/form/ResourceQuota/Project.vue +6 -6
  72. package/components/form/ResourceTabs/index.vue +1 -6
  73. package/components/form/Security.vue +7 -6
  74. package/components/form/Select.vue +3 -2
  75. package/components/form/SelectOrCreateAuthSecret.vue +22 -29
  76. package/components/form/ServicePorts.vue +8 -0
  77. package/components/form/WorkloadPorts.vue +7 -1
  78. package/components/form/__tests__/ArrayList.test.ts +74 -0
  79. package/components/form/__tests__/ArrayListGrouped.test.ts +6 -4
  80. package/components/formatter/Checked.vue +1 -1
  81. package/components/formatter/ClusterLink.vue +5 -0
  82. package/components/formatter/IconIsDefault.vue +2 -2
  83. package/components/formatter/InternalExternalIP.vue +11 -8
  84. package/components/formatter/LiveDuration.vue +78 -0
  85. package/components/formatter/WorkloadHealthScale.vue +5 -3
  86. package/components/nav/Header.vue +6 -3
  87. package/components/nav/NamespaceFilter.vue +146 -63
  88. package/components/nav/TopLevelMenu.vue +22 -19
  89. package/components/nav/WindowManager/ContainerLogs.vue +83 -126
  90. package/components/nav/WindowManager/ContainerShell.vue +9 -7
  91. package/components/nav/WindowManager/Window.vue +2 -0
  92. package/components/nav/WindowManager/index.vue +10 -0
  93. package/config/elemental-types.js +9 -0
  94. package/config/features.js +2 -0
  95. package/config/home-links.js +4 -1
  96. package/config/pod-security-admission.ts +82 -0
  97. package/config/product/apps.js +1 -1
  98. package/config/product/auth.js +6 -5
  99. package/config/product/explorer.js +6 -6
  100. package/config/product/fleet.js +1 -1
  101. package/config/product/manager.js +6 -2
  102. package/config/secret.js +0 -1
  103. package/config/settings.ts +26 -9
  104. package/config/table-headers.js +22 -11
  105. package/config/types.js +4 -1
  106. package/content/docs/zh-hans/getting-started.md +113 -137
  107. package/content/docs/zh-hans/whats-new.md +8 -46
  108. package/creators/pkg/package-lock.json +37 -0
  109. package/creators/pkg/package.json +1 -1
  110. package/detail/catalog.cattle.io.app.vue +1 -1
  111. package/detail/pod.vue +1 -1
  112. package/detail/provisioning.cattle.io.cluster.vue +35 -9
  113. package/detail/service.vue +2 -9
  114. package/detail/workload/index.vue +0 -1
  115. package/dialog/AddClusterMemberDialog.vue +22 -28
  116. package/dialog/AddProjectMemberDialog.vue +53 -9
  117. package/dialog/DiagnosticTimingsDialog.vue +8 -7
  118. package/dialog/DrainNode.vue +44 -48
  119. package/dialog/ForceMachineRemoveDialog.vue +5 -7
  120. package/dialog/GenericPrompt.vue +15 -20
  121. package/dialog/RollbackWorkloadDialog.vue +15 -46
  122. package/dialog/RotateCertificatesDialog.vue +5 -7
  123. package/dialog/RotateEncryptionKeyDialog.vue +5 -9
  124. package/dialog/SaveAsRKETemplateDialog.vue +5 -13
  125. package/dialog/ScaleMachineDownDialog.vue +1 -1
  126. package/dialog/ScalePoolDownDialog.vue +121 -0
  127. package/edit/__tests__/management.cattle.io.setting.test.ts +3 -3
  128. package/edit/auth/azuread.vue +16 -16
  129. package/edit/auth/github.vue +8 -0
  130. package/edit/auth/googleoauth.vue +10 -1
  131. package/edit/auth/ldap/index.vue +10 -0
  132. package/edit/auth/oidc.vue +10 -0
  133. package/edit/auth/saml.vue +10 -0
  134. package/edit/autoscaling.horizontalpodautoscaler/index.vue +1 -1
  135. package/edit/cloudcredential.vue +3 -7
  136. package/edit/logging-flow/Match.vue +39 -8
  137. package/edit/logging-flow/index.vue +27 -4
  138. package/edit/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +107 -0
  139. package/edit/management.cattle.io.project.vue +8 -1
  140. package/edit/management.cattle.io.setting.vue +5 -2
  141. package/edit/management.cattle.io.user.vue +7 -1
  142. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +23 -7
  143. package/edit/monitoring.coreos.com.alertmanagerconfig/types/email.vue +2 -2
  144. package/edit/monitoring.coreos.com.prometheusrule/GroupRules.vue +14 -6
  145. package/edit/namespace.vue +18 -4
  146. package/edit/networking.k8s.io.ingress/Certificate.vue +1 -0
  147. package/edit/networking.k8s.io.ingress/IngressClass.vue +8 -6
  148. package/edit/networking.k8s.io.ingress/RulePath.vue +12 -6
  149. package/edit/networking.k8s.io.ingress/index.vue +8 -6
  150. package/edit/persistentvolume/index.vue +30 -27
  151. package/edit/persistentvolume/plugins/cephfs.vue +29 -29
  152. package/edit/persistentvolume/plugins/csi.vue +102 -62
  153. package/edit/persistentvolume/plugins/fc.vue +19 -19
  154. package/edit/persistentvolume/plugins/iscsi.vue +45 -45
  155. package/edit/persistentvolume/plugins/rbd.vue +39 -39
  156. package/edit/persistentvolumeclaim.vue +78 -75
  157. package/edit/provisioning.cattle.io.cluster/MachinePool.vue +11 -7
  158. package/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue +10 -1
  159. package/edit/provisioning.cattle.io.cluster/RegistryMirrors.vue +87 -27
  160. package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +3 -6
  161. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +93 -0
  162. package/edit/provisioning.cattle.io.cluster/import.vue +1 -1
  163. package/edit/provisioning.cattle.io.cluster/index.vue +29 -6
  164. package/edit/provisioning.cattle.io.cluster/rke2.vue +440 -152
  165. package/edit/secret/index.vue +3 -7
  166. package/edit/service.vue +3 -1
  167. package/edit/storage.k8s.io.storageclass/index.vue +100 -16
  168. package/edit/storage.k8s.io.storageclass/provisioners/driver.harvesterhci.io.vue +114 -0
  169. package/edit/workload/__tests__/index.test.ts +98 -0
  170. package/edit/workload/index.vue +58 -8
  171. package/edit/workload/mixins/workload.js +107 -70
  172. package/edit/workload/storage/ContainerMountPaths.vue +0 -10
  173. package/edit/workload/storage/emptyDir.vue +88 -0
  174. package/edit/workload/storage/ephemeralVolume/index.vue +1 -1
  175. package/edit/workload/storage/index.vue +8 -0
  176. package/edit/workload/storage/persistentVolumeClaim/index.vue +1 -1
  177. package/layouts/default.vue +57 -44
  178. package/list/__tests__/workload.test.ts +5 -2
  179. package/list/catalog.cattle.io.app.vue +1 -0
  180. package/list/cis.cattle.io.clusterscan.vue +1 -0
  181. package/list/fleet.cattle.io.bundle.vue +5 -6
  182. package/list/fleet.cattle.io.cluster.vue +6 -3
  183. package/list/fleet.cattle.io.clusterregistrationtoken.vue +5 -6
  184. package/list/fleet.cattle.io.gitrepo.vue +4 -9
  185. package/list/helm.cattle.io.projecthelmchart.vue +1 -5
  186. package/list/logging.banzaicloud.io.clusterflow.vue +4 -1
  187. package/list/logging.banzaicloud.io.flow.vue +6 -5
  188. package/list/management.cattle.io.cluster.vue +1 -0
  189. package/list/management.cattle.io.feature.vue +3 -4
  190. package/list/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +47 -0
  191. package/list/management.cattle.io.setting.vue +2 -2
  192. package/list/management.cattle.io.user.vue +4 -10
  193. package/list/monitoring.coreos.com.alertmanagerconfig.vue +2 -7
  194. package/list/node.vue +8 -5
  195. package/list/persistentvolume.vue +3 -3
  196. package/list/persistentvolumeclaim.vue +3 -4
  197. package/list/provisioning.cattle.io.cluster.vue +18 -19
  198. package/list/service.vue +6 -14
  199. package/list/workload.vue +43 -38
  200. package/machine-config/azure.vue +429 -60
  201. package/machine-config/pnap.vue +288 -0
  202. package/mixins/auth-config.js +1 -3
  203. package/mixins/browser-tab-visibility.js +8 -14
  204. package/mixins/chart.js +1 -1
  205. package/mixins/create-edit-view/impl.js +4 -0
  206. package/mixins/create-edit-view/index.js +4 -2
  207. package/mixins/resource-fetch-namespaced.js +98 -0
  208. package/mixins/resource-fetch.js +79 -45
  209. package/mixins/resource-manager.js +1 -23
  210. package/models/apps.controllerrevision.js +7 -0
  211. package/models/apps.daemonset.js +18 -0
  212. package/models/apps.deployment.js +44 -0
  213. package/models/apps.replicaset.js +7 -0
  214. package/models/apps.statefulset.js +18 -0
  215. package/models/batch.job.js +7 -14
  216. package/models/cluster/node.js +10 -2
  217. package/models/cluster.x-k8s.io.machine.js +26 -4
  218. package/models/cluster.x-k8s.io.machinedeployment.js +12 -2
  219. package/models/event.js +7 -0
  220. package/models/logging.banzaicloud.io.flow.js +4 -0
  221. package/models/management.cattle.io.cluster.js +1 -1
  222. package/models/management.cattle.io.clusterroletemplatebinding.js +1 -1
  223. package/models/management.cattle.io.globalrole.js +2 -2
  224. package/models/management.cattle.io.node.js +37 -2
  225. package/models/management.cattle.io.podsecurityadmissionconfigurationtemplate.ts +4 -0
  226. package/models/management.cattle.io.project.js +30 -11
  227. package/models/management.cattle.io.setting.js +1 -1
  228. package/models/management.cattle.io.user.js +37 -1
  229. package/models/namespace.js +42 -5
  230. package/models/persistentvolume.js +14 -2
  231. package/models/pod.js +15 -0
  232. package/models/projectroletemplatebinding.js +7 -0
  233. package/models/provisioning.cattle.io.cluster.js +61 -10
  234. package/models/rke-machine.cattle.io.pnapmachinetemplate.js +15 -0
  235. package/models/service.js +14 -13
  236. package/models/storage.k8s.io.storageclass.js +33 -18
  237. package/models/workload.js +38 -7
  238. package/nuxt.config.js +27 -17
  239. package/package.json +7 -7
  240. package/pages/about.vue +14 -2
  241. package/pages/c/_cluster/apps/charts/index.vue +4 -3
  242. package/pages/c/_cluster/apps/charts/install.vue +59 -22
  243. package/pages/c/_cluster/auth/config/_id.vue +6 -0
  244. package/pages/c/_cluster/auth/config/index.vue +8 -6
  245. package/pages/c/_cluster/auth/group.principal/assign-edit.vue +1 -1
  246. package/pages/c/_cluster/auth/roles/index.vue +1 -1
  247. package/pages/c/_cluster/explorer/index.vue +12 -6
  248. package/pages/c/_cluster/longhorn/index.vue +1 -1
  249. package/pages/c/_cluster/monitoring/alertmanagerconfig/_alertmanagerconfigid/receiver.vue +15 -4
  250. package/pages/c/_cluster/monitoring/index.vue +1 -1
  251. package/pages/c/_cluster/neuvector/index.vue +1 -1
  252. package/pages/c/_cluster/settings/performance.vue +48 -2
  253. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +34 -1
  254. package/pages/c/_cluster/uiplugins/index.vue +28 -2
  255. package/pages/diagnostic.vue +5 -4
  256. package/pages/home.vue +105 -30
  257. package/pages/prefs.vue +23 -12
  258. package/pages/rio/mesh.vue +1 -1
  259. package/pkg/dynamic-importer.lib.js +8 -0
  260. package/pkg/vue.config.js +4 -0
  261. package/plugins/dashboard-store/__tests__/mutations.spec.js +406 -0
  262. package/plugins/dashboard-store/actions.js +32 -25
  263. package/plugins/dashboard-store/getters.js +50 -33
  264. package/plugins/dashboard-store/mutations.js +134 -28
  265. package/plugins/dashboard-store/resource-class.js +21 -41
  266. package/plugins/steve/actions.js +30 -0
  267. package/plugins/steve/caches/resourceCache.js +60 -0
  268. package/plugins/steve/getters.js +44 -1
  269. package/plugins/steve/mutations.js +97 -36
  270. package/plugins/steve/resourceWatcher.js +277 -0
  271. package/plugins/steve/schema.utils.js +25 -0
  272. package/plugins/steve/subscribe.js +288 -115
  273. package/plugins/steve/worker/index.js +17 -0
  274. package/plugins/steve/worker/web-worker.advanced.js +302 -0
  275. package/plugins/steve/{web-worker.steve-sub-worker.js → worker/web-worker.basic.js} +3 -44
  276. package/rancher-components/Card/Card.vue +3 -3
  277. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +1 -0
  278. package/rancher-components/StringList/StringList.test.ts +45 -420
  279. package/rancher-components/StringList/StringList.vue +1 -10
  280. package/rancher-components/components/Banner/Banner.test.ts +44 -0
  281. package/rancher-components/components/Banner/Banner.vue +129 -61
  282. package/rancher-components/components/Form/Checkbox/Checkbox.test.ts +13 -22
  283. package/rancher-components/components/Form/Checkbox/Checkbox.vue +8 -6
  284. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.test.ts +9 -9
  285. package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +0 -1
  286. package/rancher-components/components/StringList/StringList.test.ts +7 -7
  287. package/rancher-components/components/StringList/StringList.vue +21 -15
  288. package/scripts/test-plugins-build.sh +8 -0
  289. package/static/loading-indicator.html +1 -1
  290. package/store/index.js +54 -3
  291. package/store/plugins.js +0 -17
  292. package/store/pnap.js +128 -0
  293. package/store/prefs.js +4 -2
  294. package/store/type-map.js +55 -13
  295. package/types/pod-security-admission.ts +36 -0
  296. package/types/shell/index.d.ts +496 -396
  297. package/utils/__tests__/object.test.ts +17 -1
  298. package/utils/__tests__/pod-security-admission.test.ts +61 -0
  299. package/utils/async.ts +36 -0
  300. package/utils/color.js +45 -0
  301. package/utils/crypto/browserHashUtils.js +18 -0
  302. package/utils/dynamic-importer.js +8 -0
  303. package/utils/install-redirect.js +1 -1
  304. package/utils/object.js +24 -0
  305. package/utils/pod-security-admission.ts +39 -0
  306. package/utils/socket.js +61 -24
  307. package/utils/string.js +2 -0
  308. package/utils/svg-filter.js +301 -0
  309. package/utils/time.js +49 -0
  310. package/utils/validators/cidr.js +4 -0
  311. package/utils/validators/formRules/__tests__/index.test.ts +23 -3
  312. package/utils/validators/formRules/index.ts +14 -0
  313. package/config/product/harvester-manager.js +0 -162
  314. package/edit/harvesterhci.io.management.cluster.vue +0 -153
  315. package/list/harvesterhci.io.management.cluster.vue +0 -241
  316. package/machine-config/harvester.vue +0 -693
  317. package/models/harvesterhci.io.management.cluster.js +0 -228
  318. package/pages/c/_cluster/harvesterManager/index.vue +0 -24
  319. package/rancher-components/Card/Card.test.ts +0 -39
  320. package/rancher-components/Utils/DraggableZone/DraggableZone.vue +0 -181
  321. package/rancher-components/Utils/DraggableZone/index.ts +0 -1
  322. 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
@@ -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>
@@ -22,6 +22,28 @@ export default {
22
22
  default: () => {
23
23
  return [];
24
24
  }
25
+ },
26
+
27
+ /**
28
+ * Optionally replace key/value and display tooltips for the tab
29
+ * Dictionary key based
30
+ */
31
+ tooltips: {
32
+ type: Object,
33
+ default: () => {
34
+ return {};
35
+ }
36
+ },
37
+
38
+ /**
39
+ * Optionally display icons next to the tab
40
+ * Dictionary key based
41
+ */
42
+ icons: {
43
+ type: Object,
44
+ default: () => {
45
+ return {};
46
+ }
25
47
  }
26
48
  },
27
49
 
@@ -68,13 +90,21 @@ export default {
68
90
  },
69
91
 
70
92
  labels() {
71
- if (this.showAllLabels || !this.showFilteredSystemLabels) {
93
+ if (!this.showFilteredSystemLabels) {
72
94
  return this.value?.labels || {};
73
95
  }
74
96
 
75
97
  return this.value?.filteredSystemLabels;
76
98
  },
77
99
 
100
+ internalTooltips() {
101
+ return this.value?.detailTopTooltips || this.tooltips;
102
+ },
103
+
104
+ internalIcons() {
105
+ return this.value?.detailTopIcons || this.icons;
106
+ },
107
+
78
108
  annotations() {
79
109
  return this.value?.annotations || {};
80
110
  },
@@ -114,7 +144,16 @@ export default {
114
144
  },
115
145
 
116
146
  showFilteredSystemLabels() {
117
- return !!this.value.filteredSystemLabels;
147
+ // It would be nicer to use hasSystemLabels here, but not all places have implemented it
148
+ // Instead check that there's a discrepancy between all labels and all labels without system ones
149
+ if (this.value?.labels && this.value?.filteredSystemLabels) {
150
+ const labelCount = Object.keys(this.value.labels).length;
151
+ const filteredSystemLabelsCount = Object.keys(this.value.filteredSystemLabels).length;
152
+
153
+ return labelCount !== filteredSystemLabelsCount;
154
+ }
155
+
156
+ return false;
118
157
  },
119
158
  },
120
159
  methods: {
@@ -200,7 +239,19 @@ export default {
200
239
  v-for="(prop, key) in labels"
201
240
  :key="key + prop"
202
241
  >
203
- {{ key }}<span v-if="prop">: </span>{{ prop }}
242
+ <i
243
+ v-if="internalIcons[key]"
244
+ class="icon"
245
+ :class="internalIcons[key]"
246
+ />
247
+ <span
248
+ v-if="internalTooltips[key]"
249
+ v-tooltip="prop ? `${key} : ${prop}` : key"
250
+ >
251
+ <span>{{ internalTooltips[key] ? internalTooltips[key] : key }}</span>
252
+ <span v-if="showAllLabels">: {{ key }}</span>
253
+ </span>
254
+ <span v-else>{{ prop ? `${key} : ${prop}` : key }}</span>
204
255
  </Tag>
205
256
  <a
206
257
  v-if="showFilteredSystemLabels"
@@ -304,5 +355,9 @@ export default {
304
355
  margin-bottom: $spacing;
305
356
  }
306
357
  }
358
+
359
+ .icon {
360
+ vertical-align: top;
361
+ }
307
362
  }
308
363
  </style>
@@ -0,0 +1,106 @@
1
+ <script>
2
+ import { Card } from '@components/Card';
3
+ export default {
4
+ name: 'PromptRemove',
5
+ components: { Card },
6
+ props: {
7
+ /**
8
+ * Inherited global identifier prefix for tests
9
+ * Define a term based on the parent component to avoid conflicts on multiple components
10
+ */
11
+ componentTestid: {
12
+ type: String,
13
+ default: 'disable-auth-provider'
14
+ }
15
+ },
16
+ methods: {
17
+ show() {
18
+ this.$modal.show('disableAuthProviderModal');
19
+ },
20
+ close() {
21
+ this.$modal.hide('disableAuthProviderModal');
22
+ },
23
+ disable() {
24
+ this.$modal.hide('disableAuthProviderModal');
25
+ this.$emit('disable');
26
+ },
27
+ }
28
+ };
29
+ </script>
30
+
31
+ <template>
32
+ <modal
33
+ class="remove-modal"
34
+ name="disableAuthProviderModal"
35
+ :width="400"
36
+ height="auto"
37
+ styles="max-height: 100vh;"
38
+ @closed="close"
39
+ >
40
+ <Card
41
+ class="disable-auth-provider"
42
+ :show-highlight-border="false"
43
+ >
44
+ <h4
45
+ slot="title"
46
+ class="text-default-text"
47
+ >
48
+ {{ t('promptRemove.title') }}
49
+ </h4>
50
+ <div slot="body">
51
+ <div class="mb-10">
52
+ <p v-html="t('promptRemove.attemptingToRemoveAuthConfig', null, true)" />
53
+ </div>
54
+ </div>
55
+ <template #actions>
56
+ <button
57
+ class="btn role-secondary"
58
+ @click="close"
59
+ >
60
+ {{ t('generic.cancel') }}
61
+ </button>
62
+ <div class="spacer" />
63
+ <button
64
+ class="btn role-primary bg-error ml-10"
65
+ :data-testid="componentTestid + '-confirm-button'"
66
+ @click="disable"
67
+ >
68
+ {{ t('generic.disable') }}
69
+ </button>
70
+ </template>
71
+ </Card>
72
+ </modal>
73
+ </template>
74
+
75
+ <style lang='scss'>
76
+ .disable-auth-provider {
77
+ &.card-container {
78
+ box-shadow: none;
79
+ }
80
+ #confirm {
81
+ width: 90%;
82
+ margin-left: 3px;
83
+ }
84
+
85
+ .remove-modal {
86
+ border-radius: var(--border-radius);
87
+ overflow: scroll;
88
+ max-height: 100vh;
89
+ & ::-webkit-scrollbar-corner {
90
+ background: rgba(0,0,0,0);
91
+ }
92
+ }
93
+
94
+ .actions {
95
+ text-align: right;
96
+ }
97
+
98
+ .card-actions {
99
+ display: flex;
100
+
101
+ .spacer {
102
+ flex: 1;
103
+ }
104
+ }
105
+ }
106
+ </style>