@rancher/shell 0.3.4 → 0.3.6

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 (289) hide show
  1. package/assets/images/providers/outscale.svg +19 -0
  2. package/assets/styles/app.scss +1 -1
  3. package/assets/styles/base/_basic.scss +18 -0
  4. package/assets/styles/base/_mixins.scss +0 -11
  5. package/assets/styles/base/_variables.scss +2 -4
  6. package/assets/styles/fonts/_fontstack.scss +11 -11
  7. package/assets/styles/global/_button.scss +12 -2
  8. package/assets/styles/vendor/vue-js-modal.scss +3 -3
  9. package/assets/translations/en-us.yaml +113 -22
  10. package/assets/translations/zh-hans.yaml +113 -24
  11. package/babel.config.js +13 -0
  12. package/chart/gatekeeper.vue +78 -0
  13. package/chart/istio.vue +135 -112
  14. package/chart/logging/index.vue +13 -4
  15. package/chart/monitoring/index.vue +15 -5
  16. package/chart/monitoring/steps/uninstall-v1.vue +2 -2
  17. package/chart/rancher-backup/index.vue +10 -3
  18. package/cloud-credential/aws.vue +1 -1
  19. package/cloud-credential/digitalocean.vue +1 -1
  20. package/cloud-credential/gcp.vue +1 -1
  21. package/cloud-credential/generic.vue +2 -2
  22. package/cloud-credential/linode.vue +1 -1
  23. package/cloud-credential/pnap.vue +1 -1
  24. package/components/ActionMenu.vue +3 -4
  25. package/components/AssignTo.vue +1 -1
  26. package/components/AsyncButton.vue +1 -1
  27. package/components/BannerGraphic.vue +1 -1
  28. package/components/BrandImage.vue +1 -4
  29. package/components/ButtonDropdown.vue +2 -3
  30. package/components/Carousel.vue +85 -37
  31. package/components/ChartPsp.vue +76 -0
  32. package/components/CruResource.vue +6 -2
  33. package/components/DashboardMetrics.vue +12 -10
  34. package/components/DetailText.vue +1 -1
  35. package/components/DisableAuthProviderModal.vue +1 -1
  36. package/components/EmberPage.vue +1 -1
  37. package/components/EtcdInfoBanner.vue +12 -7
  38. package/components/ExplorerMembers.vue +101 -6
  39. package/components/ExplorerProjectsNamespaces.vue +46 -3
  40. package/components/FileDiff.vue +6 -7
  41. package/components/GrafanaDashboard.vue +27 -23
  42. package/components/LazyImage.vue +10 -12
  43. package/components/LogItem.vue +1 -1
  44. package/components/Markdown.vue +1 -1
  45. package/components/PromptRemove.vue +2 -2
  46. package/components/PromptRestore.vue +1 -1
  47. package/components/ResourceDetail/Masthead.vue +16 -0
  48. package/components/ResourceDetail/index.vue +21 -4
  49. package/components/ResourceList/index.vue +1 -1
  50. package/components/ResourceTable.vue +4 -1
  51. package/components/SingleClusterInfo.vue +2 -2
  52. package/components/SortableTable/THead.vue +1 -1
  53. package/components/SortableTable/index.vue +28 -13
  54. package/components/SortableTable/selection.js +58 -50
  55. package/components/Wizard.vue +4 -2
  56. package/components/__tests__/AsyncButton.test.ts +3 -1
  57. package/components/__tests__/ChartPsp.test.ts +75 -0
  58. package/components/__tests__/CruResource.test.ts +3 -1
  59. package/components/auth/Principal.vue +1 -1
  60. package/components/auth/RoleDetailEdit.vue +2 -2
  61. package/components/fleet/FleetBundles.vue +3 -1
  62. package/components/fleet/FleetClusters.vue +1 -2
  63. package/components/fleet/FleetIntro.vue +9 -1
  64. package/components/fleet/FleetNoWorkspaces.vue +62 -0
  65. package/components/fleet/FleetSummary.vue +7 -1
  66. package/components/form/HookOption.vue +14 -10
  67. package/components/form/LabeledSelect.vue +14 -11
  68. package/components/form/Labels.vue +32 -27
  69. package/components/form/MatchExpressions.vue +19 -4
  70. package/components/form/Members/ClusterPermissionsEditor.vue +32 -7
  71. package/components/form/NameNsDescription.vue +32 -46
  72. package/components/form/ProjectMemberEditor.vue +46 -21
  73. package/components/form/ResourceSelector.vue +1 -1
  74. package/components/form/SecretSelector.vue +5 -1
  75. package/components/form/ServiceNameSelect.vue +1 -1
  76. package/components/form/SimpleSecretSelector.vue +9 -9
  77. package/components/form/Tolerations.vue +4 -1
  78. package/components/form/ValueFromResource.vue +14 -9
  79. package/components/form/WorkloadPorts.vue +2 -2
  80. package/components/form/__tests__/LabeledSelect.test.ts +138 -0
  81. package/components/form/__tests__/NameNsDescription.ts +59 -0
  82. package/components/formatter/InternalExternalIP.vue +6 -0
  83. package/components/formatter/InvolvedObjectLink.vue +54 -0
  84. package/components/formatter/Link.vue +20 -4
  85. package/components/formatter/LinkName.vue +6 -1
  86. package/components/formatter/ServiceTargets.vue +1 -1
  87. package/components/formatter/WorkloadHealthScale.vue +8 -2
  88. package/components/nav/Group.vue +2 -2
  89. package/components/nav/NamespaceFilter.vue +23 -11
  90. package/components/nav/TopLevelMenu.vue +2 -4
  91. package/components/nav/Type.vue +1 -1
  92. package/components/nav/WorkspaceSwitcher.vue +46 -5
  93. package/components/nuxt/nuxt-build-indicator.vue +143 -0
  94. package/components/nuxt/nuxt-child.js +122 -0
  95. package/components/nuxt/nuxt-error.vue +98 -0
  96. package/components/nuxt/nuxt-link.client.js +98 -0
  97. package/components/nuxt/nuxt-link.server.js +16 -0
  98. package/components/nuxt/nuxt-loading.vue +154 -0
  99. package/components/nuxt/nuxt.js +101 -0
  100. package/config/labels-annotations.js +17 -0
  101. package/config/middleware.js +12 -0
  102. package/config/product/auth.js +3 -2
  103. package/config/product/explorer.js +34 -6
  104. package/config/product/fleet.js +2 -0
  105. package/config/query-params.js +1 -0
  106. package/config/router.js +414 -0
  107. package/config/store.js +181 -0
  108. package/config/table-headers.js +54 -12
  109. package/config/types.js +18 -8
  110. package/config/uiplugins.js +30 -0
  111. package/content/docs/en-us/whats-new.md +10 -0
  112. package/content/docs/zh-hans/whats-new.md +11 -1
  113. package/core/plugin-routes.ts +23 -0
  114. package/core/plugin.ts +4 -2
  115. package/core/types.ts +258 -1
  116. package/creators/app/app.package.json +2 -1
  117. package/creators/app/files/.eslintrc.js +1 -1
  118. package/creators/app/files/babel.config.js +1 -18
  119. package/creators/app/files/tsconfig.json +0 -1
  120. package/creators/app/files/vue.config.js +6 -0
  121. package/creators/app/init +5 -5
  122. package/creators/pkg/files/.github/workflows/build-extension.yml +110 -0
  123. package/creators/pkg/files/tsconfig.json +0 -1
  124. package/creators/pkg/init +35 -4
  125. package/creators/pkg/pkg.package.json +3 -3
  126. package/creators/update/init +1 -1
  127. package/detail/constraints.gatekeeper.sh.constraint.vue +34 -17
  128. package/detail/fleet.cattle.io.clustergroup.vue +7 -1
  129. package/detail/fleet.cattle.io.gitrepo.vue +19 -11
  130. package/detail/harvesterhci.io.management.cluster.vue +3 -3
  131. package/detail/provisioning.cattle.io.cluster.vue +54 -12
  132. package/detail/workload/index.vue +3 -3
  133. package/dialog/AddClusterMemberDialog.vue +1 -1
  134. package/dialog/AddProjectMemberDialog.vue +2 -2
  135. package/dialog/AddonConfigConfirmationDialog.vue +27 -15
  136. package/dialog/DiagnosticTimingsDialog.vue +1 -1
  137. package/dialog/ForceMachineRemoveDialog.vue +1 -1
  138. package/dialog/GenericPrompt.vue +18 -6
  139. package/dialog/RotateEncryptionKeyDialog.vue +1 -1
  140. package/dialog/SaveAsRKETemplateDialog.vue +1 -1
  141. package/dialog/ScaleMachineDownDialog.vue +1 -1
  142. package/edit/auth/github.vue +8 -8
  143. package/edit/auth/googleoauth.vue +5 -5
  144. package/edit/auth/ldap/index.vue +1 -1
  145. package/edit/auth/oidc.vue +1 -1
  146. package/edit/auth/saml.vue +1 -1
  147. package/edit/cis.cattle.io.clusterscan.vue +1 -1
  148. package/edit/fleet.cattle.io.clustergroup.vue +6 -4
  149. package/edit/fleet.cattle.io.gitrepo.vue +32 -4
  150. package/edit/helm.cattle.io.projecthelmchart.vue +5 -1
  151. package/edit/logging.banzaicloud.io.output/index.vue +18 -5
  152. package/edit/logging.banzaicloud.io.output/providers/loki.vue +1 -0
  153. package/edit/management.cattle.io.fleetworkspace.vue +141 -6
  154. package/edit/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +4 -1
  155. package/edit/management.cattle.io.setting.vue +1 -1
  156. package/edit/monitoring.coreos.com.alertmanagerconfig/types/webhook.vue +2 -2
  157. package/edit/monitoring.coreos.com.receiver/tls.vue +18 -18
  158. package/edit/monitoring.coreos.com.receiver/types/webhook.banner.vue +4 -4
  159. package/edit/monitoring.coreos.com.receiver/types/webhook.vue +1 -1
  160. package/edit/namespace.vue +14 -10
  161. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +126 -45
  162. package/edit/networking.k8s.io.networkpolicy/index.vue +1 -1
  163. package/edit/provisioning.cattle.io.cluster/MachinePool.vue +21 -4
  164. package/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue +1 -0
  165. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +202 -2
  166. package/edit/provisioning.cattle.io.cluster/import.vue +23 -25
  167. package/edit/provisioning.cattle.io.cluster/rke2.vue +344 -102
  168. package/edit/resources.cattle.io.backup.vue +1 -1
  169. package/edit/service.vue +1 -1
  170. package/edit/storage.k8s.io.storageclass/provisioners/driver.harvesterhci.io.vue +2 -2
  171. package/edit/workload/__tests__/Job.test.ts +3 -1
  172. package/edit/workload/index.vue +8 -3
  173. package/edit/workload/mixins/workload.js +22 -7
  174. package/edit/workload/storage/Mount.vue +3 -3
  175. package/initialize/App.js +206 -0
  176. package/initialize/client.js +863 -0
  177. package/initialize/index.js +364 -0
  178. package/layouts/default.vue +7 -3
  179. package/layouts/standalone.vue +13 -0
  180. package/list/catalog.cattle.io.clusterrepo.vue +1 -0
  181. package/list/fleet.cattle.io.bundle.vue +6 -3
  182. package/list/fleet.cattle.io.clusterregistrationtoken.vue +3 -1
  183. package/list/fleet.cattle.io.gitrepo.vue +44 -5
  184. package/list/management.cattle.io.fleetworkspace.vue +45 -0
  185. package/list/node.vue +69 -16
  186. package/list/provisioning.cattle.io.cluster.vue +30 -1
  187. package/list/rbac.authorization.k8s.io.clusterrolebinding.vue +48 -0
  188. package/list/workload.vue +6 -4
  189. package/machine-config/azure.vue +97 -38
  190. package/middleware/authenticated.js +34 -0
  191. package/mixins/chart.js +101 -2
  192. package/mixins/fetch.client.js +95 -0
  193. package/mixins/fetch.server.js +73 -0
  194. package/mixins/labeled-form-element.ts +2 -2
  195. package/mixins/resource-fetch.js +2 -2
  196. package/models/apps.statefulset.js +28 -0
  197. package/models/cluster/node.js +23 -2
  198. package/models/cluster.x-k8s.io.machine.js +4 -2
  199. package/models/clusterroletemplatebinding.js +7 -0
  200. package/models/constraints.gatekeeper.sh.constraint.js +46 -0
  201. package/models/fleet.cattle.io.cluster.js +19 -10
  202. package/models/fleet.cattle.io.gitrepo.js +7 -2
  203. package/models/management.cattle.io.cluster.js +1 -1
  204. package/models/management.cattle.io.fleetworkspace.js +12 -0
  205. package/models/management.cattle.io.gitreporestriction.js +5 -0
  206. package/models/management.cattle.io.podsecurityadmissionconfigurationtemplate.js +3 -0
  207. package/models/pod.js +4 -0
  208. package/models/provisioning.cattle.io.cluster.js +7 -5
  209. package/models/rbac.authorization.k8s.io.clusterrolebinding.js +16 -0
  210. package/models/rbac.authorization.k8s.io.rolebinding.js +16 -0
  211. package/package.json +13 -21
  212. package/pages/auth/setup.vue +2 -2
  213. package/pages/c/_cluster/apps/charts/__tests__/install.helper.test.ts +33 -0
  214. package/pages/c/_cluster/apps/charts/chart.vue +4 -4
  215. package/pages/c/_cluster/apps/charts/install.helpers.js +26 -0
  216. package/pages/c/_cluster/apps/charts/install.vue +98 -102
  217. package/pages/c/_cluster/explorer/EventsTable.vue +5 -19
  218. package/pages/c/_cluster/explorer/index.vue +29 -25
  219. package/pages/c/_cluster/explorer/tools/index.vue +8 -8
  220. package/pages/c/_cluster/fleet/index.vue +95 -34
  221. package/pages/c/_cluster/gatekeeper/index.vue +1 -1
  222. package/pages/c/_cluster/istio/index.vue +5 -5
  223. package/pages/c/_cluster/manager/cloudCredential/index.vue +1 -1
  224. package/pages/c/_cluster/monitoring/index.vue +7 -0
  225. package/pages/c/_cluster/uiplugins/InstallDialog.vue +8 -8
  226. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +20 -7
  227. package/pages/c/_cluster/uiplugins/index.vue +49 -17
  228. package/pages/diagnostic.vue +32 -25
  229. package/pages/home.vue +9 -4
  230. package/pages/index.vue +10 -1
  231. package/pages/rio/mesh.vue +1 -2
  232. package/pkg/tsconfig.json +0 -1
  233. package/plugins/clean-html-directive.js +34 -0
  234. package/plugins/dashboard-store/actions.js +32 -9
  235. package/plugins/dashboard-store/index.js +1 -1
  236. package/plugins/dashboard-store/mutations.js +5 -2
  237. package/plugins/dashboard-store/resource-class.js +8 -1
  238. package/plugins/plugin.js +0 -14
  239. package/plugins/portal-vue.js +4 -0
  240. package/plugins/steve/mutations.js +3 -2
  241. package/plugins/steve/steve-description-class.js +5 -1
  242. package/plugins/steve/subscribe.js +63 -54
  243. package/plugins/steve-create-worker.js +14 -0
  244. package/promptRemove/management.cattle.io.globalrole.vue +2 -2
  245. package/promptRemove/management.cattle.io.project.vue +2 -2
  246. package/promptRemove/management.cattle.io.roletemplate.vue +2 -2
  247. package/promptRemove/pod.vue +1 -1
  248. package/public/index.html +65 -0
  249. package/rancher-components/components/Banner/Banner.test.ts +7 -1
  250. package/rancher-components/components/Banner/Banner.vue +2 -1
  251. package/rancher-components/components/Form/Checkbox/Checkbox.vue +2 -0
  252. package/rancher-components/components/Form/Radio/RadioButton.test.ts +31 -0
  253. package/rancher-components/components/Form/Radio/RadioButton.vue +14 -3
  254. package/scripts/build-pkg.sh +1 -0
  255. package/scripts/clean +6 -0
  256. package/scripts/extension/bundle +58 -0
  257. package/scripts/extension/helmpatch +89 -0
  258. package/scripts/extension/publish +333 -0
  259. package/scripts/serve-pkgs +6 -2
  260. package/scripts/test-plugins-build.sh +4 -0
  261. package/store/__tests__/index.test.ts +110 -0
  262. package/store/index.js +145 -58
  263. package/store/type-map.js +6 -2
  264. package/tsconfig.default.json +36 -0
  265. package/tsconfig.json +23 -0
  266. package/types/rancher/index.d.ts +2 -0
  267. package/types/shell/index.d.ts +466 -320
  268. package/utils/__tests__/grafana.test.ts +44 -0
  269. package/utils/__tests__/string.test.ts +12 -0
  270. package/utils/auth.js +65 -0
  271. package/utils/axios.js +190 -0
  272. package/utils/cookie-universal-nuxt.js +10 -0
  273. package/utils/dom.js +15 -0
  274. package/utils/grafana.js +35 -16
  275. package/utils/monitoring.js +2 -1
  276. package/utils/nuxt.js +659 -0
  277. package/utils/position.js +5 -8
  278. package/utils/router.scrollBehavior.js +80 -0
  279. package/utils/select.js +1 -3
  280. package/utils/socket.js +1 -0
  281. package/utils/string.js +13 -0
  282. package/utils/time.js +9 -0
  283. package/vue.config.js +690 -0
  284. package/chart/rancher-alerting-drivers.vue +0 -53
  285. package/chart/rancher-gatekeeper.vue +0 -37
  286. package/creators/app/files/nuxt.config.js +0 -6
  287. package/models/management.cattle.io.podsecurityadmissionconfigurationtemplate.ts +0 -4
  288. package/nuxt.config.js +0 -798
  289. package/plugins/dashboard-store/extensions.js +0 -22
@@ -83,7 +83,7 @@ export default {
83
83
  class="pl-10 pr-10"
84
84
  >
85
85
  <span
86
- v-html="t('promptForceRemove.removeWarning', { nameToMatch }, true)"
86
+ v-clean-html="t('promptForceRemove.removeWarning', { nameToMatch }, true)"
87
87
  />
88
88
  <div class="mt-10 mb-10">
89
89
  {{ t('promptForceRemove.confirmName') }}
@@ -3,6 +3,7 @@ import AsyncButton from '@shell/components/AsyncButton';
3
3
  import { Card } from '@components/Card';
4
4
  import { Banner } from '@components/Banner';
5
5
  import { exceptionToErrorsArray } from '@shell/utils/error';
6
+ import { decodeHtml } from '@shell/utils/string';
6
7
 
7
8
  export default {
8
9
  components: {
@@ -26,28 +27,39 @@ export default {
26
27
  body: {
27
28
  type: String,
28
29
  default: ''
29
- }
30
+ },
31
+
32
+ /**
33
+ * Callback to identify response of the prompt
34
+ */
35
+ confirm: {
36
+ type: Function,
37
+ default: () => { }
38
+ },
30
39
  },
31
40
  data() {
32
41
  return { errors: [] };
33
42
  },
34
43
 
35
44
  methods: {
45
+ decodeHtml,
36
46
  close() {
37
- this.$emit('close');
47
+ this.confirm(false);
48
+ this.$emit('close', false);
38
49
  },
39
50
 
40
51
  async apply(buttonDone) {
41
52
  try {
42
53
  await this.applyAction(buttonDone);
43
- this.close();
54
+ this.confirm(true);
55
+ this.$emit('close', true);
44
56
  } catch (err) {
45
57
  console.error(err); // eslint-disable-line
46
58
  this.errors = exceptionToErrorsArray(err);
47
59
  buttonDone(false);
48
60
  }
49
61
  }
50
- }
62
+ },
51
63
  };
52
64
  </script>
53
65
 
@@ -58,16 +70,16 @@ export default {
58
70
  >
59
71
  <h4
60
72
  slot="title"
73
+ v-clean-html="title"
61
74
  class="text-default-text"
62
- v-html="title"
63
75
  />
64
76
 
65
77
  <template slot="body">
66
78
  <slot name="body">
67
79
  <div
80
+ v-clean-html="decodeHtml(body)"
68
81
  class="pl-10 pr-10"
69
82
  style="min-height: 50px; display: flex;"
70
- v-html="body"
71
83
  />
72
84
  </slot>
73
85
  </template>
@@ -124,8 +124,8 @@ export default {
124
124
  >
125
125
  <h4
126
126
  slot="title"
127
+ v-clean-html="t('promptRotateEncryptionKey.title')"
127
128
  class="text-default-text"
128
- v-html="t('promptRotateEncryptionKey.title')"
129
129
  />
130
130
 
131
131
  <div
@@ -74,8 +74,8 @@ export default {
74
74
  >
75
75
  <h4
76
76
  slot="title"
77
+ v-clean-html="t('promptSaveAsRKETemplate.title', { cluster: cluster.displayName }, true)"
77
78
  class="text-default-text"
78
- v-html="t('promptSaveAsRKETemplate.title', { cluster: cluster.displayName }, true)"
79
79
  />
80
80
 
81
81
  <div
@@ -116,7 +116,7 @@ export default {
116
116
  <span
117
117
  v-for="i in ignored"
118
118
  :key="i.name"
119
- v-html="t('promptScaleMachineDown.retainedMachine2', { name: i.name }, true)"
119
+ v-clean-html="t('promptScaleMachineDown.retainedMachine2', { name: i.name }, true)"
120
120
  />
121
121
  </div>
122
122
  </div>
@@ -187,9 +187,9 @@ export default {
187
187
  class="step-box"
188
188
  >
189
189
  <ul class="step-list">
190
- <li v-html="t(`authConfig.${NAME}.form.prefix.1`, tArgs, true)" />
191
- <li v-html="t(`authConfig.${NAME}.form.prefix.2`, tArgs, true)" />
192
- <li v-html="t(`authConfig.${NAME}.form.prefix.3`, tArgs, true)" />
190
+ <li v-clean-html="t(`authConfig.${NAME}.form.prefix.1`, tArgs, true)" />
191
+ <li v-clean-html="t(`authConfig.${NAME}.form.prefix.2`, tArgs, true)" />
192
+ <li v-clean-html="t(`authConfig.${NAME}.form.prefix.3`, tArgs, true)" />
193
193
  </ul>
194
194
  </InfoBox>
195
195
  <InfoBox
@@ -200,7 +200,7 @@ export default {
200
200
  <li>
201
201
  {{ t(`authConfig.${NAME}.form.instruction`, tArgs, true) }}
202
202
  <ul class="mt-10">
203
- <li><b>{{ t(`authConfig.${NAME}.form.app.label`) }}</b>: <span v-html="t(`authConfig.${NAME}.form.app.value`, tArgs, true)" /></li>
203
+ <li><b>{{ t(`authConfig.${NAME}.form.app.label`) }}</b>: <span v-clean-html="t(`authConfig.${NAME}.form.app.value`, tArgs, true)" /></li>
204
204
  <li>
205
205
  <b>{{ t(`authConfig.${NAME}.form.homepage.label`) }}</b>: {{ serverUrl }} <CopyToClipboard
206
206
  label-as="tooltip"
@@ -209,7 +209,7 @@ export default {
209
209
  action-color="bg-transparent"
210
210
  />
211
211
  </li>
212
- <li><b>{{ t(`authConfig.${NAME}.form.description.label`) }}</b>: <span v-html="t(`authConfig.${NAME}.form.description.value`, tArgs, true)" /></li>
212
+ <li><b>{{ t(`authConfig.${NAME}.form.description.label`) }}</b>: <span v-clean-html="t(`authConfig.${NAME}.form.description.value`, tArgs, true)" /></li>
213
213
  <li>
214
214
  <b>{{ t(`authConfig.${NAME}.form.callback.label`) }}</b>: {{ serverUrl }} <CopyToClipboard
215
215
  :text="serverUrl"
@@ -227,8 +227,8 @@ export default {
227
227
  class="mb-20"
228
228
  >
229
229
  <ul class="step-list">
230
- <li v-html="t(`authConfig.${NAME}.form.suffix.1`, tArgs, true)" />
231
- <li v-html="t(`authConfig.${NAME}.form.suffix.2`, tArgs, true)" />
230
+ <li v-clean-html="t(`authConfig.${NAME}.form.suffix.1`, tArgs, true)" />
231
+ <li v-clean-html="t(`authConfig.${NAME}.form.suffix.2`, tArgs, true)" />
232
232
  </ul>
233
233
  </InfoBox>
234
234
 
@@ -255,8 +255,8 @@ export default {
255
255
  >
256
256
  <div class="col span-12">
257
257
  <Banner
258
+ v-clean-html="t('authConfig.associatedWarning', tArgs, true)"
258
259
  color="info"
259
- v-html="t('authConfig.associatedWarning', tArgs, true)"
260
260
  />
261
261
  </div>
262
262
  </div>
@@ -141,7 +141,7 @@ export default {
141
141
  :step="1"
142
142
  class=" mt-20 mb-20"
143
143
  >
144
- <h3 v-html="t('authConfig.googleoauth.steps.1.title', tArgs, true)" />
144
+ <h3 v-clean-html="t('authConfig.googleoauth.steps.1.title', tArgs, true)" />
145
145
  <ul class="mt-0 step-list">
146
146
  <li>{{ t('authConfig.googleoauth.steps.1.body.1', {}, true) }} </li>
147
147
  <li>
@@ -165,7 +165,7 @@ export default {
165
165
  class="mb-20"
166
166
  >
167
167
  <div class="row">
168
- <h3 v-html="t('authConfig.googleoauth.steps.2.title', tArgs, true)" />
168
+ <h3 v-clean-html="t('authConfig.googleoauth.steps.2.title', tArgs, true)" />
169
169
  </div>
170
170
  <div class="row">
171
171
  <div class="col span-6">
@@ -211,11 +211,11 @@ export default {
211
211
  class="mb-20"
212
212
  >
213
213
  <div class="row">
214
- <h3 v-html="t('authConfig.googleoauth.steps.3.title', tArgs, true)" />
214
+ <h3 v-clean-html="t('authConfig.googleoauth.steps.3.title', tArgs, true)" />
215
215
  </div>
216
216
  <div class="row">
217
217
  <div class="col span-6">
218
- <div v-html="t('authConfig.googleoauth.steps.3.introduction', tArgs, true)" />
218
+ <div v-clean-html="t('authConfig.googleoauth.steps.3.introduction', tArgs, true)" />
219
219
  <ul class="mt-10 step-list">
220
220
  <li>{{ t('authConfig.googleoauth.steps.3.body.1', {}, true) }} </li>
221
221
  <li>{{ t('authConfig.googleoauth.steps.3.body.2', {}, true) }} </li>
@@ -248,8 +248,8 @@ export default {
248
248
  >
249
249
  <div class="col span-12 google">
250
250
  <Banner
251
+ v-clean-html="t('authConfig.associatedWarning', tArgs, true)"
251
252
  color="info"
252
- v-html="t('authConfig.associatedWarning', tArgs, true)"
253
253
  />
254
254
  </div>
255
255
  </div>
@@ -148,8 +148,8 @@ export default {
148
148
  >
149
149
  <div class="col span-12">
150
150
  <Banner
151
+ v-clean-html="t('authConfig.associatedWarning', tArgs, true)"
151
152
  color="info"
152
- v-html="t('authConfig.associatedWarning', tArgs, true)"
153
153
  />
154
154
  </div>
155
155
  </div>
@@ -277,8 +277,8 @@ export default {
277
277
  >
278
278
  <div class="col span-12">
279
279
  <Banner
280
+ v-clean-html="t('authConfig.associatedWarning', tArgs, true)"
280
281
  color="info"
281
- v-html="t('authConfig.associatedWarning', tArgs, true)"
282
282
  />
283
283
  </div>
284
284
  </div>
@@ -257,8 +257,8 @@ export default {
257
257
  >
258
258
  <div class="col span-12">
259
259
  <Banner
260
+ v-clean-html="t('authConfig.associatedWarning', tArgs, true)"
260
261
  color="info"
261
- v-html="t('authConfig.associatedWarning', tArgs, true)"
262
262
  />
263
263
  </div>
264
264
  </div>
@@ -322,7 +322,7 @@ export default {
322
322
  class="mt-0"
323
323
  :color="hasAlertManager ? 'info' : 'warning'"
324
324
  >
325
- <span v-html="t('cis.alertNeeded', {link: monitoringUrl}, true)" />
325
+ <span v-clean-html="t('cis.alertNeeded', {link: monitoringUrl}, true)" />
326
326
  </banner>
327
327
  <Checkbox
328
328
  v-model="scanAlertRule.alertOnComplete"
@@ -27,7 +27,9 @@ export default {
27
27
  mixins: [CreateEditView],
28
28
 
29
29
  async fetch() {
30
- this.allClusters = await this.$store.dispatch('management/findAll', { type: FLEET.CLUSTER });
30
+ if (this.$store.getters['management/schemaFor']( FLEET.CLUSTER )) {
31
+ this.allClusters = await this.$store.getters['management/all'](FLEET.CLUSTER);
32
+ }
31
33
  this.allWorkspaces = await this.$store.dispatch('management/findAll', { type: FLEET.WORKSPACE });
32
34
 
33
35
  if ( !this.value.spec?.selector ) {
@@ -146,15 +148,15 @@ export default {
146
148
  >
147
149
  <span
148
150
  v-if="matchingClusters.isAll"
149
- v-html="t('fleet.clusterGroup.selector.matchesAll', matchingClusters)"
151
+ v-clean-html="t('fleet.clusterGroup.selector.matchesAll', matchingClusters)"
150
152
  />
151
153
  <span
152
154
  v-else-if="matchingClusters.isNone"
153
- v-html="t('fleet.clusterGroup.selector.matchesNone', matchingClusters)"
155
+ v-clean-html="t('fleet.clusterGroup.selector.matchesNone', matchingClusters)"
154
156
  />
155
157
  <span
156
158
  v-else
157
- v-html="t('fleet.clusterGroup.selector.matchesSome', matchingClusters)"
159
+ v-clean-html="t('fleet.clusterGroup.selector.matchesSome', matchingClusters)"
158
160
  />
159
161
  </Banner>
160
162
 
@@ -23,6 +23,8 @@ import { _CREATE } from '@shell/config/query-params';
23
23
  import { isHarvesterCluster } from '@shell/utils/cluster';
24
24
  import { CAPI, CATALOG } from '@shell/config/labels-annotations';
25
25
  import { SECRET_TYPES } from '@shell/config/secret';
26
+ import { checkSchemasForFindAllHash } from '@shell/utils/auth';
27
+ import Checkbox from '@components/Form/Checkbox/Checkbox.vue';
26
28
 
27
29
  const _VERIFY = 'verify';
28
30
  const _SKIP = 'skip';
@@ -32,6 +34,7 @@ export default {
32
34
  name: 'CruGitRepo',
33
35
 
34
36
  components: {
37
+ Checkbox,
35
38
  ArrayList,
36
39
  Banner,
37
40
  CruResource,
@@ -48,8 +51,20 @@ export default {
48
51
  mixins: [CreateEditView],
49
52
 
50
53
  async fetch() {
51
- this.allClusters = await this.$store.dispatch('management/findAll', { type: FLEET.CLUSTER });
52
- this.allClusterGroups = await this.$store.dispatch('management/findAll', { type: FLEET.CLUSTER_GROUP });
54
+ const hash = await checkSchemasForFindAllHash({
55
+ allClusters: {
56
+ inStoreType: 'management',
57
+ type: FLEET.CLUSTER
58
+ },
59
+
60
+ allClusterGroups: {
61
+ inStoreType: 'management',
62
+ type: FLEET.CLUSTER_GROUP
63
+ }
64
+ }, this.$store);
65
+
66
+ this.allClusters = hash.allClusters || [];
67
+ this.allClusterGroups = hash.allClusterGroups || [];
53
68
 
54
69
  let tls = _VERIFY;
55
70
 
@@ -412,7 +427,7 @@ export default {
412
427
  await secret.save();
413
428
 
414
429
  await this.$nextTick(() => {
415
- this.updateAuth(secret.id, name);
430
+ this.updateAuth(secret.metadata.name, name);
416
431
  });
417
432
 
418
433
  return secret;
@@ -588,7 +603,20 @@ export default {
588
603
  </div>
589
604
  </template>
590
605
  <div class="spacer" />
591
-
606
+ <h2 v-t="'fleet.gitRepo.resources.label'" />
607
+ <Checkbox
608
+ v-model="value.spec.keepResources"
609
+ class="check"
610
+ type="checkbox"
611
+ label-key="fleet.gitRepo.resources.keepResources"
612
+ :mode="mode"
613
+ />
614
+ <Banner
615
+ color="info"
616
+ >
617
+ {{ t('fleet.gitRepo.resources.resourceBanner') }}
618
+ </Banner>
619
+ <div class="spacer" />
592
620
  <h2 v-t="'fleet.gitRepo.paths.label'" />
593
621
  <ArrayList
594
622
  v-model="value.spec.paths"
@@ -48,6 +48,10 @@ export default {
48
48
  },
49
49
 
50
50
  data() {
51
+ if (!this.value.spec.values) {
52
+ this.$set(this.value.spec, 'values', {});
53
+ }
54
+
51
55
  return {
52
56
  systemNamespaces: null,
53
57
  namespaces: [],
@@ -128,7 +132,7 @@ export default {
128
132
  :side-tabs="true"
129
133
  >
130
134
  <Questions
131
- v-model="value"
135
+ v-model="value.spec.values"
132
136
  tabbed="multiple"
133
137
  :target-namespace="value.metadata.namespace"
134
138
  :source="selectedNamespaceQuestions"
@@ -100,9 +100,6 @@ export default {
100
100
  }
101
101
  },
102
102
 
103
- created() {
104
- this.registerBeforeHook(this.willSave, 'willSave');
105
- },
106
103
  methods: {
107
104
  getComponent(name) {
108
105
  return require(`./providers/${ name }`).default;
@@ -110,7 +107,22 @@ export default {
110
107
  launch(provider) {
111
108
  this.$refs.tabbed.select(provider.name);
112
109
  },
113
- willSave() {
110
+ saveSettings(done) {
111
+ const t = this.$store.getters['i18n/t'];
112
+
113
+ if (this.selectedProvider === 'loki') {
114
+ const urlCheck = ['https://', 'http://'].some(checkValue => this.value.spec['loki'].url.toLowerCase().startsWith(checkValue));
115
+ const isLokiHttps = this.value.spec['loki'].url ? urlCheck : undefined;
116
+
117
+ if (!isLokiHttps) {
118
+ this.errors = [t('logging.loki.urlInvalid')];
119
+
120
+ return done(false);
121
+ }
122
+ }
123
+
124
+ this.errors = [];
125
+
114
126
  this.value.spec = { [this.selectedProvider]: this.value.spec[this.selectedProvider] };
115
127
 
116
128
  const bufferJson = jsyaml.load(this.bufferYaml);
@@ -120,6 +132,7 @@ export default {
120
132
  } else {
121
133
  this.$delete(this.value.spec[this.selectedProvider], 'buffer');
122
134
  }
135
+ this.save(done);
123
136
  },
124
137
  tabChanged({ tab }) {
125
138
  if ( tab.name === 'buffer' ) {
@@ -151,7 +164,7 @@ export default {
151
164
  :errors="errors"
152
165
  :can-yaml="true"
153
166
  @error="e=>errors = e"
154
- @finish="save"
167
+ @finish="saveSettings"
155
168
  @cancel="done"
156
169
  >
157
170
  <NameNsDescription
@@ -47,6 +47,7 @@ export default {
47
47
  :mode="mode"
48
48
  :disabled="disabled"
49
49
  class="url"
50
+ placeholder="https://127.0.0.1:8000"
50
51
  :label="t('logging.loki.url')"
51
52
  />
52
53
  </div>
@@ -4,12 +4,18 @@ import CruResource from '@shell/components/CruResource';
4
4
  import Labels from '@shell/components/form/Labels';
5
5
  import Loading from '@shell/components/Loading';
6
6
  import NameNsDescription from '@shell/components/form/NameNsDescription';
7
- import { FLEET, MANAGEMENT } from '@shell/config/types';
7
+ import { FLEET, MANAGEMENT, SCHEMA } from '@shell/config/types';
8
8
  // import RoleBindings from '@shell/components/RoleBindings';
9
9
  import Tabbed from '@shell/components/Tabbed';
10
10
  import Tab from '@shell/components/Tabbed/Tab';
11
11
  import { SCOPE_NAMESPACE, SCOPE_CLUSTER } from '@shell/components/RoleBindings.vue';
12
12
  import { NAME as FLEET_NAME } from '@shell/config/product/fleet';
13
+ // import KeyValue from '@shell/components/form/KeyValue.vue';
14
+ import { mapState } from 'vuex';
15
+ import { LAST_NAMESPACE, WORKSPACE } from '@shell/store/prefs';
16
+ import { exceptionToErrorsArray } from '@shell/utils/error';
17
+ import Banner from '@components/Banner/Banner.vue';
18
+ import ArrayList from '@shell/components/form/ArrayList.vue';
13
19
 
14
20
  export default {
15
21
  name: 'FleetCruWorkspace',
@@ -19,26 +25,123 @@ export default {
19
25
  Labels,
20
26
  Loading,
21
27
  NameNsDescription,
22
- // RoleBindings,
23
28
  Tabbed,
24
29
  Tab,
30
+ Banner,
31
+ ArrayList
25
32
  },
26
33
 
27
34
  mixins: [CreateEditView],
28
35
 
29
36
  async fetch() {
30
37
  this.rancherClusters = await this.$store.dispatch('management/findAll', { type: MANAGEMENT.CLUSTER });
31
- this.fleetClusters = await this.$store.dispatch('management/findAll', { type: FLEET.CLUSTER });
38
+
39
+ if (this.$store.getters['management/schemaFor']( FLEET.CLUSTER )) {
40
+ this.fleetClusters = await this.$store.dispatch('management/findAll', { type: FLEET.CLUSTER });
41
+ }
42
+
43
+ if (this.hasRepoRestrictionSchema) {
44
+ const restrictions = await this.$store.dispatch('management/findAll', { type: FLEET.GIT_REPO_RESTRICTION });
45
+
46
+ const workSpaceRestriction = restrictions.find((item) => {
47
+ return item.metadata.namespace === this.value.metadata.name && item.metadata.name.startsWith(`restriction-${ this.value.metadata.name }`);
48
+ });
49
+
50
+ if (workSpaceRestriction) {
51
+ this.workSpaceRestriction = workSpaceRestriction;
52
+ }
53
+ }
54
+
55
+ this.restrictionsOptions = await this.$store.getters[`type-map/optionsFor`](FLEET.GIT_REPO_RESTRICTION);
56
+ this.restrictionsSchema = await this.$store.getters[`management/schemaFor`](FLEET.GIT_REPO_RESTRICTION);
32
57
  },
33
58
 
34
59
  data() {
60
+ this.$set(this.value, 'spec', this.value.spec || {});
61
+
35
62
  return {
36
- fleetClusters: null,
37
- rancherClusters: null,
63
+ fleetClusters: null,
64
+ rancherClusters: null,
65
+ workSpaceRestriction: null,
66
+ restrictions: [],
67
+ targetNamespaces: [],
68
+ restrictionsSchema: { spec: {} },
69
+ namespace: this.$store.getters['prefs/get'](LAST_NAMESPACE),
70
+ hasRepoRestrictionSchema: !!this.$store.getters['management/schemaFor']( FLEET.GIT_REPO_RESTRICTION )
38
71
  };
39
72
  },
40
73
 
74
+ methods: {
75
+ async saveAll(buttonCb) {
76
+ // Anyone who can edit workspace
77
+
78
+ try {
79
+ await this.value.save();
80
+
81
+ // IF there is a restriction update it
82
+ if (this.workSpaceRestriction) {
83
+ await this.workSpaceRestriction.save();
84
+ }
85
+
86
+ // If there is no restriction and targetnamespace is set then create it.
87
+ if (!this.workSpaceRestriction && this.targetNamespaces.length) {
88
+ // For users with more limited permissions the gitreporestriction schema may not be visible until they create a workspace
89
+ if (!this.hasRepoRestrictionSchema) {
90
+ await this.$store.dispatch('management/find', { type: SCHEMA, id: FLEET.GIT_REPO_RESTRICTION }, { force: true });
91
+ }
92
+ const model = await this.$store.dispatch(`management/create`, {
93
+ type: FLEET.GIT_REPO_RESTRICTION,
94
+ allowedTargetNamespaces: this.targetNamespaces,
95
+ metadata: {
96
+ // restriction- prefix is added to the workspace name
97
+ // to identify automatically created GitRepoRestrictions
98
+ // when adding targetNamespaces at the point of workspace creation
99
+ name: `restriction-${ this.value.metadata.name }-${ Date.now() }`,
100
+ namespace: this.value.metadata.name // what the user types
101
+ }
102
+ });
103
+
104
+ await model.save();
105
+ }
106
+
107
+ await this.value.waitForWorkspaceSchema(20000, (schema) => {
108
+ // For standard user if there are no workspaces, user can't list workspaces
109
+ // Therefore wait for it.
110
+ return schema.collectionMethods?.includes('GET');
111
+ });
112
+
113
+ await this.$store.dispatch( 'management/findAll', { type: FLEET.WORKSPACE });
114
+
115
+ this.$store.commit('updateWorkspace', { value: this.value.metadata.name, getters: this.$store.getters } );
116
+ this.$store.dispatch('prefs/set', { key: WORKSPACE, value: this.value.metadata.name });
117
+
118
+ buttonCb(true);
119
+ this.done();
120
+ } catch (err) {
121
+ console.error(err) ; // eslint-disable-line no-console
122
+ buttonCb(false);
123
+ this.errors = exceptionToErrorsArray(err);
124
+ }
125
+ },
126
+ },
127
+
41
128
  computed: {
129
+ ...mapState(['allWorkspaces', 'workspace']),
130
+
131
+ allowedTargetNamespaces: {
132
+ get() {
133
+ return this.workSpaceRestriction?.allowedTargetNamespaces || [];
134
+ },
135
+
136
+ set(value) {
137
+ if (this.workSpaceRestriction) {
138
+ this.workSpaceRestriction.allowedTargetNamespaces = value;
139
+ }
140
+
141
+ this.targetNamespaces = value;
142
+ }
143
+ },
144
+
42
145
  SCOPE_NAMESPACE() {
43
146
  return SCOPE_NAMESPACE;
44
147
  },
@@ -65,7 +168,7 @@ export default {
65
168
  :validation-passed="true"
66
169
  :errors="errors"
67
170
  @error="e=>errors = e"
68
- @finish="save"
171
+ @finish="saveAll"
69
172
  @cancel="done"
70
173
  >
71
174
  <NameNsDescription
@@ -100,6 +203,38 @@ export default {
100
203
  :mode="mode"
101
204
  />
102
205
  </Tab>
206
+ <Tab
207
+ name="allowedtargetnamespaces"
208
+ label-key="fleet.workspaces.tabs.restrictions"
209
+ >
210
+ <Banner
211
+ color="info"
212
+ >
213
+ <div>
214
+ <t
215
+ k="fleet.restrictions.banner"
216
+ :count="allowedTargetNamespaces.length"
217
+ :raw="true"
218
+ />
219
+ <a
220
+ v-if="!!allowedTargetNamespaces.length"
221
+ @click="workSpaceRestriction.goToDetail()"
222
+ >
223
+ {{ t('generic.here') }}
224
+ </a>
225
+ </div>
226
+ </Banner>
227
+
228
+ <ArrayList
229
+ key="labels"
230
+ v-model="allowedTargetNamespaces"
231
+ :add-label="t('fleet.restrictions.addLabel')"
232
+ :mode="mode"
233
+ :title="t('fleet.restrictions.addTitle')"
234
+ :read-allowed="false"
235
+ :value-can-be-empty="true"
236
+ />
237
+ </Tab>
103
238
  </Tabbed>
104
239
  </CruResource>
105
240
  </template>
@@ -86,15 +86,18 @@ export default (Vue as VueConstructor<Vue & InstanceType<typeof CreateEditView>>
86
86
  :resource="value"
87
87
  :errors="errors"
88
88
  :cancel-event="true"
89
+ :done-route="doneRoute"
89
90
  @error="setErrors"
90
91
  @finish="save"
91
- @cancel="done()"
92
+ @cancel="done"
92
93
  >
93
94
  <NameNsDescription
94
95
  :value="value"
95
96
  :namespaced="false"
96
97
  :mode="mode"
98
+ description-key="description"
97
99
  />
100
+
98
101
  <PodSecurityAdmission
99
102
  :labels="defaults"
100
103
  :labels-always-active="true"
@@ -122,8 +122,8 @@ export default {
122
122
 
123
123
  <h5
124
124
  v-if="editHelp"
125
+ v-clean-html="editHelp"
125
126
  class="edit-help"
126
- v-html="editHelp"
127
127
  />
128
128
 
129
129
  <div class="edit-change mt-20">