@rancher/shell 0.3.4 → 0.3.5

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 (246) hide show
  1. package/assets/styles/app.scss +1 -1
  2. package/assets/styles/fonts/_fontstack.scss +11 -11
  3. package/assets/styles/vendor/vue-js-modal.scss +3 -3
  4. package/assets/translations/en-us.yaml +92 -22
  5. package/assets/translations/zh-hans.yaml +84 -15
  6. package/babel.config.js +13 -0
  7. package/chart/gatekeeper.vue +77 -0
  8. package/chart/istio.vue +108 -111
  9. package/chart/logging/index.vue +13 -4
  10. package/chart/monitoring/index.vue +15 -5
  11. package/chart/monitoring/steps/uninstall-v1.vue +2 -2
  12. package/chart/rancher-backup/index.vue +10 -3
  13. package/cloud-credential/aws.vue +1 -1
  14. package/cloud-credential/digitalocean.vue +1 -1
  15. package/cloud-credential/gcp.vue +1 -1
  16. package/cloud-credential/generic.vue +2 -2
  17. package/cloud-credential/linode.vue +1 -1
  18. package/cloud-credential/pnap.vue +1 -1
  19. package/components/ActionMenu.vue +3 -4
  20. package/components/AssignTo.vue +1 -1
  21. package/components/AsyncButton.vue +1 -1
  22. package/components/BannerGraphic.vue +1 -1
  23. package/components/ButtonDropdown.vue +2 -3
  24. package/components/ChartPsp.vue +76 -0
  25. package/components/CruResource.vue +6 -2
  26. package/components/DashboardMetrics.vue +12 -10
  27. package/components/DetailText.vue +1 -1
  28. package/components/DisableAuthProviderModal.vue +1 -1
  29. package/components/EmberPage.vue +1 -1
  30. package/components/EtcdInfoBanner.vue +5 -4
  31. package/components/ExplorerMembers.vue +1 -1
  32. package/components/ExplorerProjectsNamespaces.vue +14 -1
  33. package/components/FileDiff.vue +6 -7
  34. package/components/GrafanaDashboard.vue +18 -21
  35. package/components/LazyImage.vue +10 -12
  36. package/components/LogItem.vue +1 -1
  37. package/components/Markdown.vue +1 -1
  38. package/components/PromptRemove.vue +2 -2
  39. package/components/PromptRestore.vue +1 -1
  40. package/components/ResourceDetail/Masthead.vue +16 -0
  41. package/components/ResourceDetail/index.vue +21 -4
  42. package/components/ResourceList/index.vue +1 -1
  43. package/components/ResourceTable.vue +4 -1
  44. package/components/SingleClusterInfo.vue +2 -2
  45. package/components/SortableTable/THead.vue +1 -1
  46. package/components/SortableTable/index.vue +5 -2
  47. package/components/__tests__/AsyncButton.test.ts +3 -1
  48. package/components/__tests__/ChartPsp.test.ts +75 -0
  49. package/components/__tests__/CruResource.test.ts +3 -1
  50. package/components/auth/Principal.vue +1 -1
  51. package/components/fleet/FleetBundles.vue +3 -1
  52. package/components/fleet/FleetClusters.vue +1 -2
  53. package/components/fleet/FleetIntro.vue +9 -1
  54. package/components/fleet/FleetNoWorkspaces.vue +62 -0
  55. package/components/fleet/FleetSummary.vue +7 -1
  56. package/components/form/LabeledSelect.vue +14 -11
  57. package/components/form/MatchExpressions.vue +17 -2
  58. package/components/form/NameNsDescription.vue +31 -45
  59. package/components/form/ResourceSelector.vue +1 -1
  60. package/components/form/SecretSelector.vue +5 -1
  61. package/components/form/ServiceNameSelect.vue +1 -1
  62. package/components/form/SimpleSecretSelector.vue +9 -9
  63. package/components/form/__tests__/LabeledSelect.test.ts +138 -0
  64. package/components/form/__tests__/NameNsDescription.ts +32 -0
  65. package/components/formatter/InternalExternalIP.vue +6 -0
  66. package/components/formatter/InvolvedObjectLink.vue +54 -0
  67. package/components/formatter/Link.vue +20 -4
  68. package/components/formatter/LinkName.vue +6 -1
  69. package/components/formatter/ServiceTargets.vue +1 -1
  70. package/components/nav/Group.vue +2 -2
  71. package/components/nav/NamespaceFilter.vue +15 -11
  72. package/components/nav/TopLevelMenu.vue +2 -4
  73. package/components/nav/Type.vue +1 -1
  74. package/components/nav/WorkspaceSwitcher.vue +46 -5
  75. package/config/labels-annotations.js +17 -0
  76. package/config/product/auth.js +3 -2
  77. package/config/product/explorer.js +11 -4
  78. package/config/product/fleet.js +2 -0
  79. package/config/router.js +414 -0
  80. package/config/table-headers.js +10 -2
  81. package/config/types.js +11 -8
  82. package/config/uiplugins.js +30 -0
  83. package/content/docs/en-us/whats-new.md +10 -0
  84. package/content/docs/zh-hans/whats-new.md +11 -1
  85. package/core/plugin-routes.ts +23 -0
  86. package/creators/app/app.package.json +2 -1
  87. package/creators/app/files/.eslintrc.js +1 -1
  88. package/creators/app/files/babel.config.js +1 -18
  89. package/creators/app/files/vue.config.js +7 -0
  90. package/creators/app/init +5 -5
  91. package/creators/pkg/files/.github/workflows/build-extension.yml +111 -0
  92. package/creators/pkg/init +35 -4
  93. package/creators/update/init +1 -1
  94. package/detail/constraints.gatekeeper.sh.constraint.vue +20 -10
  95. package/detail/fleet.cattle.io.gitrepo.vue +19 -11
  96. package/detail/harvesterhci.io.management.cluster.vue +3 -3
  97. package/detail/provisioning.cattle.io.cluster.vue +54 -12
  98. package/detail/workload/index.vue +3 -3
  99. package/dialog/AddClusterMemberDialog.vue +1 -1
  100. package/dialog/AddProjectMemberDialog.vue +2 -2
  101. package/dialog/AddonConfigConfirmationDialog.vue +27 -15
  102. package/dialog/DiagnosticTimingsDialog.vue +1 -1
  103. package/dialog/ForceMachineRemoveDialog.vue +1 -1
  104. package/dialog/GenericPrompt.vue +18 -6
  105. package/dialog/RotateEncryptionKeyDialog.vue +1 -1
  106. package/dialog/SaveAsRKETemplateDialog.vue +1 -1
  107. package/dialog/ScaleMachineDownDialog.vue +1 -1
  108. package/edit/auth/github.vue +8 -8
  109. package/edit/auth/googleoauth.vue +5 -5
  110. package/edit/auth/ldap/index.vue +1 -1
  111. package/edit/auth/oidc.vue +1 -1
  112. package/edit/auth/saml.vue +1 -1
  113. package/edit/cis.cattle.io.clusterscan.vue +1 -1
  114. package/edit/fleet.cattle.io.clustergroup.vue +6 -4
  115. package/edit/fleet.cattle.io.gitrepo.vue +16 -3
  116. package/edit/helm.cattle.io.projecthelmchart.vue +5 -1
  117. package/edit/management.cattle.io.fleetworkspace.vue +141 -6
  118. package/edit/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +4 -1
  119. package/edit/management.cattle.io.setting.vue +1 -1
  120. package/edit/monitoring.coreos.com.alertmanagerconfig/types/webhook.vue +2 -2
  121. package/edit/monitoring.coreos.com.receiver/tls.vue +18 -18
  122. package/edit/monitoring.coreos.com.receiver/types/webhook.banner.vue +4 -4
  123. package/edit/monitoring.coreos.com.receiver/types/webhook.vue +1 -1
  124. package/edit/namespace.vue +2 -2
  125. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +126 -45
  126. package/edit/networking.k8s.io.networkpolicy/index.vue +1 -1
  127. package/edit/provisioning.cattle.io.cluster/MachinePool.vue +10 -0
  128. package/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue +1 -0
  129. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +202 -2
  130. package/edit/provisioning.cattle.io.cluster/rke2.vue +248 -84
  131. package/edit/resources.cattle.io.backup.vue +1 -1
  132. package/edit/service.vue +1 -1
  133. package/edit/storage.k8s.io.storageclass/provisioners/driver.harvesterhci.io.vue +2 -2
  134. package/edit/workload/__tests__/Job.test.ts +3 -1
  135. package/edit/workload/index.vue +8 -3
  136. package/edit/workload/mixins/workload.js +16 -0
  137. package/layouts/default.vue +7 -3
  138. package/list/fleet.cattle.io.bundle.vue +6 -3
  139. package/list/fleet.cattle.io.clusterregistrationtoken.vue +3 -1
  140. package/list/fleet.cattle.io.gitrepo.vue +44 -5
  141. package/list/management.cattle.io.fleetworkspace.vue +45 -0
  142. package/list/node.vue +69 -16
  143. package/list/provisioning.cattle.io.cluster.vue +30 -1
  144. package/machine-config/azure.vue +97 -38
  145. package/middleware/authenticated.js +34 -0
  146. package/mixins/chart.js +73 -2
  147. package/mixins/resource-fetch.js +2 -2
  148. package/models/apps.statefulset.js +28 -0
  149. package/models/cluster/node.js +23 -2
  150. package/models/cluster.x-k8s.io.machine.js +4 -2
  151. package/models/clusterroletemplatebinding.js +7 -0
  152. package/models/constraints.gatekeeper.sh.constraint.js +9 -0
  153. package/models/fleet.cattle.io.cluster.js +19 -10
  154. package/models/fleet.cattle.io.gitrepo.js +7 -2
  155. package/models/management.cattle.io.cluster.js +1 -1
  156. package/models/management.cattle.io.fleetworkspace.js +12 -0
  157. package/models/management.cattle.io.gitreporestriction.js +5 -0
  158. package/models/management.cattle.io.podsecurityadmissionconfigurationtemplate.js +3 -0
  159. package/models/provisioning.cattle.io.cluster.js +7 -5
  160. package/nuxt/App.js +210 -0
  161. package/nuxt/axios.js +186 -0
  162. package/nuxt/client.js +817 -0
  163. package/nuxt/components/nuxt-build-indicator.vue +143 -0
  164. package/nuxt/components/nuxt-child.js +122 -0
  165. package/nuxt/components/nuxt-error.vue +98 -0
  166. package/nuxt/components/nuxt-link.client.js +98 -0
  167. package/nuxt/components/nuxt-link.server.js +16 -0
  168. package/nuxt/components/nuxt-loading.vue +154 -0
  169. package/nuxt/components/nuxt.js +101 -0
  170. package/nuxt/cookie-universal-nuxt.js +9 -0
  171. package/nuxt/empty.js +1 -0
  172. package/nuxt/index.js +365 -0
  173. package/nuxt/jsonp.js +82 -0
  174. package/nuxt/loading.html +39 -0
  175. package/nuxt/middleware.js +12 -0
  176. package/nuxt/mixins/fetch.client.js +90 -0
  177. package/nuxt/mixins/fetch.server.js +69 -0
  178. package/nuxt/portal-vue.js +4 -0
  179. package/nuxt/server.js +312 -0
  180. package/nuxt/store.js +178 -0
  181. package/nuxt/utils.js +630 -0
  182. package/nuxt/views/app.template.html +9 -0
  183. package/nuxt/views/error.html +23 -0
  184. package/package.json +5 -9
  185. package/pages/auth/setup.vue +2 -2
  186. package/pages/c/_cluster/apps/charts/__tests__/install.helper.test.ts +33 -0
  187. package/pages/c/_cluster/apps/charts/chart.vue +4 -4
  188. package/pages/c/_cluster/apps/charts/install.helpers.js +26 -0
  189. package/pages/c/_cluster/apps/charts/install.vue +40 -66
  190. package/pages/c/_cluster/explorer/EventsTable.vue +5 -19
  191. package/pages/c/_cluster/explorer/index.vue +29 -25
  192. package/pages/c/_cluster/explorer/tools/index.vue +8 -8
  193. package/pages/c/_cluster/fleet/index.vue +95 -34
  194. package/pages/c/_cluster/gatekeeper/index.vue +1 -1
  195. package/pages/c/_cluster/istio/index.vue +5 -5
  196. package/pages/c/_cluster/manager/cloudCredential/index.vue +1 -1
  197. package/pages/c/_cluster/monitoring/index.vue +7 -0
  198. package/pages/c/_cluster/uiplugins/InstallDialog.vue +8 -8
  199. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +20 -7
  200. package/pages/c/_cluster/uiplugins/index.vue +49 -17
  201. package/pages/home.vue +9 -4
  202. package/pages/index.vue +10 -1
  203. package/plugins/clean-html-directive.js +31 -0
  204. package/plugins/dashboard-store/actions.js +32 -9
  205. package/plugins/dashboard-store/mutations.js +5 -2
  206. package/plugins/dashboard-store/resource-class.js +8 -1
  207. package/plugins/steve/mutations.js +3 -2
  208. package/plugins/steve/steve-description-class.js +5 -1
  209. package/plugins/steve/subscribe.js +63 -54
  210. package/plugins/steve-create-worker.js +14 -0
  211. package/promptRemove/management.cattle.io.globalrole.vue +2 -2
  212. package/promptRemove/management.cattle.io.project.vue +2 -2
  213. package/promptRemove/management.cattle.io.roletemplate.vue +2 -2
  214. package/promptRemove/pod.vue +1 -1
  215. package/public/index.html +65 -0
  216. package/rancher-components/components/Banner/Banner.test.ts +9 -1
  217. package/rancher-components/components/Banner/Banner.vue +1 -1
  218. package/rancher-components/components/Form/Checkbox/Checkbox.vue +2 -0
  219. package/rancher-components/components/Form/Radio/RadioButton.vue +1 -1
  220. package/scripts/build-pkg.sh +1 -0
  221. package/scripts/clean +6 -0
  222. package/scripts/extension/bundle +58 -0
  223. package/scripts/extension/helmpatch +89 -0
  224. package/scripts/extension/publish +314 -0
  225. package/scripts/test-plugins-build.sh +4 -0
  226. package/store/__tests__/index.test.ts +110 -0
  227. package/store/index.js +145 -58
  228. package/store/type-map.js +5 -1
  229. package/tsconfig.default.json +36 -0
  230. package/tsconfig.json +24 -0
  231. package/types/shell/index.d.ts +420 -343
  232. package/utils/__tests__/string.test.ts +12 -0
  233. package/utils/auth.js +65 -0
  234. package/utils/monitoring.js +2 -1
  235. package/utils/position.js +5 -8
  236. package/utils/router.scrollBehavior.js +80 -0
  237. package/utils/select.js +1 -3
  238. package/utils/socket.js +1 -0
  239. package/utils/string.js +13 -0
  240. package/utils/time.js +9 -0
  241. package/vue.config.js +679 -0
  242. package/chart/rancher-alerting-drivers.vue +0 -53
  243. package/chart/rancher-gatekeeper.vue +0 -37
  244. package/creators/app/files/nuxt.config.js +0 -6
  245. package/models/management.cattle.io.podsecurityadmissionconfigurationtemplate.ts +0 -4
  246. package/nuxt.config.js +0 -798
@@ -108,8 +108,8 @@ export default {
108
108
  },
109
109
 
110
110
  watch: {
111
- project(newProject) {
112
- const limits = this.getDefaultContainerResourceLimits(newProject);
111
+ project() {
112
+ const limits = this.getDefaultContainerResourceLimits(this.projectName);
113
113
 
114
114
  this.$set(this, 'containerResourceLimits', limits);
115
115
  },
@@ -11,9 +11,12 @@ import { Banner } from '@components/Banner';
11
11
  import throttle from 'lodash/throttle';
12
12
  import { isValidCIDR } from '@shell/utils/validators/cidr';
13
13
 
14
- const TARGET_OPTION_IP_BLOCK = 'ipBlock';
15
- const TARGET_OPTION_NAMESPACE_SELECTOR = 'namespaceSelector';
16
- const TARGET_OPTION_POD_SELECTOR = 'podSelector';
14
+ const TARGET_OPTIONS = {
15
+ IP_BLOCK: 'ipBlock',
16
+ NAMESPACE_SELECTOR: 'namespaceSelector',
17
+ POD_SELECTOR: 'podSelector',
18
+ NAMESPACE_AND_POD_SELECTOR: 'namespaceAndPodSelector',
19
+ };
17
20
 
18
21
  export default {
19
22
  components: {
@@ -52,53 +55,48 @@ export default {
52
55
  },
53
56
  },
54
57
  data() {
55
- if (!this.value[TARGET_OPTION_IP_BLOCK] && !this.value[TARGET_OPTION_POD_SELECTOR] && !this.value[TARGET_OPTION_NAMESPACE_SELECTOR]) {
58
+ if (!this.value[TARGET_OPTIONS.IP_BLOCK] &&
59
+ !this.value[TARGET_OPTIONS.POD_SELECTOR] &&
60
+ !this.value[TARGET_OPTIONS.NAMESPACE_SELECTOR] &&
61
+ !this.value[TARGET_OPTIONS.NAMESPACE_AND_POD_SELECTOR]
62
+ ) {
56
63
  this.$nextTick(() => {
57
- this.$set(this.value, TARGET_OPTION_IP_BLOCK, {});
64
+ this.$set(this.value, TARGET_OPTIONS.IP_BLOCK, {});
58
65
  });
59
66
  }
60
67
 
61
- const matchingPods = this.getMatchingPods();
62
- const matchingNamespaces = this.getMatchingNamespaces();
63
-
64
68
  return {
65
- portOptions: ['TCP', 'UDP'],
66
- matchingPods,
67
- matchingNamespaces,
68
- invalidCidr: null,
69
- invalidCidrs: [],
70
- TARGET_OPTION_IP_BLOCK,
71
- TARGET_OPTION_NAMESPACE_SELECTOR,
72
- TARGET_OPTION_POD_SELECTOR,
69
+ portOptions: ['TCP', 'UDP'],
70
+ matchingPods: {},
71
+ matchingNamespaces: {},
72
+ invalidCidr: null,
73
+ invalidCidrs: [],
73
74
  POD,
74
- targetOptions: [
75
- TARGET_OPTION_IP_BLOCK,
76
- TARGET_OPTION_NAMESPACE_SELECTOR,
77
- TARGET_OPTION_POD_SELECTOR
78
- ],
75
+ TARGET_OPTIONS,
76
+ targetOptions: Object.values(TARGET_OPTIONS),
79
77
  };
80
78
  },
81
79
  computed: {
82
80
  podSelectorExpressions: {
83
81
  get() {
84
82
  return convert(
85
- this.value[TARGET_OPTION_POD_SELECTOR]?.matchLabels || {},
86
- this.value[TARGET_OPTION_POD_SELECTOR]?.matchExpressions || []
83
+ this.value[TARGET_OPTIONS.POD_SELECTOR]?.matchLabels || {},
84
+ this.value[TARGET_OPTIONS.POD_SELECTOR]?.matchExpressions || []
87
85
  );
88
86
  },
89
87
  set(podSelectorExpressions) {
90
- this.$set(this.value, TARGET_OPTION_POD_SELECTOR, simplify(podSelectorExpressions));
88
+ this.$set(this.value, TARGET_OPTIONS.POD_SELECTOR, simplify(podSelectorExpressions));
91
89
  }
92
90
  },
93
91
  namespaceSelectorExpressions: {
94
92
  get() {
95
93
  return convert(
96
- this.value[TARGET_OPTION_NAMESPACE_SELECTOR]?.matchLabels || {},
97
- this.value[TARGET_OPTION_NAMESPACE_SELECTOR]?.matchExpressions || []
94
+ this.value[TARGET_OPTIONS.NAMESPACE_SELECTOR]?.matchLabels || {},
95
+ this.value[TARGET_OPTIONS.NAMESPACE_SELECTOR]?.matchExpressions || []
98
96
  );
99
97
  },
100
98
  set(namespaceSelectorExpressions) {
101
- this.$set(this.value, TARGET_OPTION_NAMESPACE_SELECTOR, simplify(namespaceSelectorExpressions));
99
+ this.$set(this.value, TARGET_OPTIONS.NAMESPACE_SELECTOR, simplify(namespaceSelectorExpressions));
102
100
  }
103
101
  },
104
102
  selectTargetOptions() {
@@ -116,6 +114,9 @@ export default {
116
114
  targetType: {
117
115
  get() {
118
116
  for (const option of this.targetOptions) {
117
+ if (this.value[TARGET_OPTIONS.NAMESPACE_AND_POD_SELECTOR] || (this.value[TARGET_OPTIONS.NAMESPACE_SELECTOR] && this.value[TARGET_OPTIONS.POD_SELECTOR])) {
118
+ return TARGET_OPTIONS.NAMESPACE_AND_POD_SELECTOR;
119
+ }
119
120
  if (this.value[option]) {
120
121
  return option;
121
122
  }
@@ -124,13 +125,30 @@ export default {
124
125
  return null;
125
126
  },
126
127
  set(targetType) {
127
- this.$delete(this.value, TARGET_OPTION_IP_BLOCK);
128
- this.$delete(this.value, TARGET_OPTION_NAMESPACE_SELECTOR);
129
- this.$delete(this.value, TARGET_OPTION_POD_SELECTOR);
128
+ this.$delete(this.value, TARGET_OPTIONS.IP_BLOCK);
129
+ this.$delete(this.value, TARGET_OPTIONS.NAMESPACE_SELECTOR);
130
+ this.$delete(this.value, TARGET_OPTIONS.POD_SELECTOR);
131
+ this.$delete(this.value, TARGET_OPTIONS.NAMESPACE_AND_POD_SELECTOR);
130
132
  this.$nextTick(() => {
131
133
  this.$set(this.value, targetType, {});
132
134
  });
133
135
  }
136
+ },
137
+ updateMatches() {
138
+ return {
139
+ handler: throttle(function() {
140
+ this.matchingNamespaces = this.getMatchingNamespaces();
141
+ this.matchingPods = this.getMatchingPods();
142
+ }, 250, { leading: true }),
143
+ immediate: true
144
+ };
145
+ },
146
+ matchingNamespacesAndPods() {
147
+ return {
148
+ policyNamespace: this.namespace,
149
+ ...Object.keys(this.matchingNamespaces).reduce((acc, k) => ({ ...acc, [`${ k }Namespaces`]: this.matchingNamespaces[k] }), {}),
150
+ ...Object.keys(this.matchingPods).reduce((acc, k) => ({ ...acc, [`${ k }Pods`]: this.matchingPods[k] }), {}),
151
+ };
134
152
  }
135
153
  },
136
154
  watch: {
@@ -144,24 +162,21 @@ export default {
144
162
  },
145
163
  methods: {
146
164
  validateCIDR() {
147
- const exceptCidrs = this.value[TARGET_OPTION_IP_BLOCK]?.except || [];
165
+ const exceptCidrs = this.value[TARGET_OPTIONS.IP_BLOCK]?.except || [];
148
166
 
149
167
  this.invalidCidrs = exceptCidrs
150
168
  .filter(cidr => !isValidCIDR(cidr))
151
169
  .map(invalidCidr => invalidCidr || '<blank>');
152
170
 
153
- if (this.value[TARGET_OPTION_IP_BLOCK]?.cidr && !isValidCIDR(this.value[TARGET_OPTION_IP_BLOCK].cidr)) {
154
- this.invalidCidr = this.value[TARGET_OPTION_IP_BLOCK].cidr;
171
+ if (this.value[TARGET_OPTIONS.IP_BLOCK]?.cidr && !isValidCIDR(this.value[TARGET_OPTIONS.IP_BLOCK].cidr)) {
172
+ this.invalidCidr = this.value[TARGET_OPTIONS.IP_BLOCK].cidr;
155
173
  } else {
156
174
  this.invalidCidr = null;
157
175
  }
158
176
  },
159
- updateMatches: throttle(function() {
160
- this.matchingPods = this.getMatchingPods();
161
- this.matchingNamespaces = this.getMatchingNamespaces();
162
- }, 250, { leading: true }),
163
177
  getMatchingPods() {
164
- const allInNamespace = this.allPods.filter(pod => pod.metadata.namespace === this.namespace);
178
+ const namespaces = this.targetType === TARGET_OPTIONS.NAMESPACE_AND_POD_SELECTOR ? this.matchingNamespaces.matches : [{ id: this.namespace }];
179
+ const allInNamespace = this.allPods.filter(pod => namespaces.some(ns => ns.id === pod.metadata.namespace));
165
180
  const match = matching(allInNamespace, this.podSelectorExpressions);
166
181
  const matched = match.length || 0;
167
182
  const sample = match[0]?.nameDisplay;
@@ -199,17 +214,18 @@ export default {
199
214
  <LabeledSelect
200
215
  v-model="targetType"
201
216
  :mode="mode"
217
+ :tooltip="targetType === TARGET_OPTIONS.NAMESPACE_AND_POD_SELECTOR ? t('networkpolicy.selectors.matchingNamespacesAndPods.tooltip') : null"
202
218
  :options="selectTargetOptions"
203
219
  :multiple="false"
204
220
  :label="t('networkpolicy.rules.type')"
205
221
  />
206
222
  </div>
207
223
  </div>
208
- <div v-if="targetType === TARGET_OPTION_IP_BLOCK">
224
+ <div v-if="targetType === TARGET_OPTIONS.IP_BLOCK">
209
225
  <div class="row">
210
226
  <div class="col span-6">
211
227
  <LabeledInput
212
- v-model="value[TARGET_OPTION_IP_BLOCK].cidr"
228
+ v-model="value[TARGET_OPTIONS.IP_BLOCK].cidr"
213
229
  :mode="mode"
214
230
  :placeholder="t('networkpolicy.rules.ipBlock.cidr.placeholder')"
215
231
  :label="t('networkpolicy.rules.ipBlock.cidr.label')"
@@ -229,7 +245,7 @@ export default {
229
245
  <div class="row mt-20">
230
246
  <div class="col span-12">
231
247
  <ArrayList
232
- v-model="value[TARGET_OPTION_IP_BLOCK].except"
248
+ v-model="value[TARGET_OPTIONS.IP_BLOCK].except"
233
249
  :add-label="t('networkpolicy.rules.ipBlock.addExcept')"
234
250
  :mode="mode"
235
251
  :show-header="true"
@@ -249,11 +265,11 @@ export default {
249
265
  </div>
250
266
  </div>
251
267
  </div>
252
- <div v-if="targetType === TARGET_OPTION_POD_SELECTOR">
268
+ <div v-if="targetType === TARGET_OPTIONS.POD_SELECTOR">
253
269
  <div class="row">
254
270
  <div class="col span-12">
255
271
  <Banner color="success">
256
- <span v-html="t('networkpolicy.selectors.matchingPods.matchesSome', matchingPods)" />
272
+ <span v-clean-html="t('networkpolicy.selectors.matchingPods.matchesSome', matchingPods)" />
257
273
  </Banner>
258
274
  </div>
259
275
  </div>
@@ -269,11 +285,11 @@ export default {
269
285
  </div>
270
286
  </div>
271
287
  </div>
272
- <div v-if="targetType === TARGET_OPTION_NAMESPACE_SELECTOR">
288
+ <div v-if="targetType === TARGET_OPTIONS.NAMESPACE_SELECTOR">
273
289
  <div class="row">
274
290
  <div class="col span-12">
275
291
  <Banner color="success">
276
- <span v-html="t('networkpolicy.selectors.matchingNamespaces.matchesSome', matchingNamespaces)" />
292
+ <span v-clean-html="t('networkpolicy.selectors.matchingNamespaces.matchesSome', matchingNamespaces)" />
277
293
  </Banner>
278
294
  </div>
279
295
  </div>
@@ -289,5 +305,70 @@ export default {
289
305
  </div>
290
306
  </div>
291
307
  </div>
308
+ <div v-if="targetType === TARGET_OPTIONS.NAMESPACE_AND_POD_SELECTOR">
309
+ <div class="row">
310
+ <div class="col span-12">
311
+ <Banner color="success">
312
+ <span
313
+ v-if="!namespaceSelectorExpressions.length"
314
+ v-clean-html="t('networkpolicy.selectors.matchingPods.matchesSome', matchingPods)"
315
+ />
316
+ <span
317
+ v-else
318
+ v-clean-html="t('networkpolicy.selectors.matchingNamespacesAndPods.matchesSome', matchingNamespacesAndPods)"
319
+ />
320
+ </Banner>
321
+ </div>
322
+ </div>
323
+ <div class="row mb-0">
324
+ <div class="col span-1 namespace-pod-rule">
325
+ <span class="label">
326
+ {{ t('networkpolicy.rules.namespace') }}
327
+ </span>
328
+ </div>
329
+ <div class="col span-11">
330
+ <MatchExpressions
331
+ v-model="namespaceSelectorExpressions"
332
+ :mode="mode"
333
+ :show-add-button="false"
334
+ :show-remove-button="false"
335
+ :show-remove="false"
336
+ :initial-empty-row="true"
337
+ :type="POD"
338
+ />
339
+ </div>
340
+ </div>
341
+ <div class="row mb-0">
342
+ <div class="col span-1 namespace-pod-rule">
343
+ <span class="label">
344
+ {{ t('networkpolicy.rules.pod') }}
345
+ </span>
346
+ </div>
347
+ <div class="col span-11">
348
+ <MatchExpressions
349
+ v-model="podSelectorExpressions"
350
+ :mode="mode"
351
+ :show-add-button="false"
352
+ :show-remove-button="false"
353
+ :show-remove="false"
354
+ :initial-empty-row="true"
355
+ :type="POD"
356
+ />
357
+ </div>
358
+ </div>
359
+ </div>
292
360
  </div>
293
361
  </template>
362
+
363
+ <style lang='scss' scoped>
364
+ .namespace-pod-rule {
365
+ width: 100px;
366
+ margin: 0;
367
+ text-align: center;
368
+
369
+ .label {
370
+ display: block;
371
+ margin-top: 32px;
372
+ }
373
+ }
374
+ </style>
@@ -258,7 +258,7 @@ export default {
258
258
  <div class="row">
259
259
  <div class="col span-12">
260
260
  <Banner color="success">
261
- <span v-html="t('networkpolicy.selectors.matchingPods.matchesSome', matchingPods)" />
261
+ <span v-clean-html="t('networkpolicy.selectors.matchingPods.matchesSome', matchingPods)" />
262
262
  </Banner>
263
263
  </div>
264
264
  </div>
@@ -158,6 +158,14 @@ export default {
158
158
  // (only used on Elemental because it comes from "machineinventoryselectortemplate" machine-config)
159
159
  updateMachineCount(val) {
160
160
  this.value.pool.quantity = val || 1;
161
+ },
162
+
163
+ expandAdvanced() {
164
+ const advancedComponent = this.$refs.advanced;
165
+
166
+ if (advancedComponent && !advancedComponent.show) {
167
+ advancedComponent.toggle();
168
+ }
161
169
  }
162
170
  }
163
171
  };
@@ -223,6 +231,7 @@ export default {
223
231
  :machine-pools="machinePools"
224
232
  @error="e=>errors = e"
225
233
  @updateMachineCount="updateMachineCount"
234
+ @expandAdvanced="expandAdvanced"
226
235
  />
227
236
  <Banner
228
237
  v-else-if="value.configMissing"
@@ -236,6 +245,7 @@ export default {
236
245
  />
237
246
 
238
247
  <AdvancedSection
248
+ ref="advanced"
239
249
  :mode="mode"
240
250
  class="advanced"
241
251
  >
@@ -159,6 +159,7 @@ export default {
159
159
  <div class="col span-6">
160
160
  <SecretSelector
161
161
  v-model="row.value.tlsSecretName"
162
+ in-store="management"
162
163
  :mode="mode"
163
164
  :types="[TLS]"
164
165
  :namespace="value.metadata.namespace"
@@ -2,6 +2,12 @@ import { mount } from '@vue/test-utils';
2
2
  import rke2 from '@shell/edit/provisioning.cattle.io.cluster/rke2.vue';
3
3
 
4
4
  describe('component: rke2', () => {
5
+ // Disable existing log to avoid pollution
6
+ // eslint-disable-next-line jest/no-hooks
7
+ beforeEach(() => {
8
+ jest.spyOn(console, 'log').mockImplementation(() => {});
9
+ });
10
+
5
11
  it.each([
6
12
  'v1.25.0+rke2r1',
7
13
  'v1.24.0+rke2r1',
@@ -9,7 +15,7 @@ describe('component: rke2', () => {
9
15
  'v1.25.0+k3s1',
10
16
  'v1.24.0+k3s1',
11
17
  'v1.23.0+k3s1',
12
- ])('should display PSA option', () => {
18
+ ])('should display PSA option', (k8s) => {
13
19
  const label = 'whatever';
14
20
  const option = { label, value: label };
15
21
  const wrapper = mount(rke2, {
@@ -20,7 +26,7 @@ describe('component: rke2', () => {
20
26
  rkeConfig: { etcd: { disableSnapshots: false } },
21
27
  chartValues: {},
22
28
  defaultPodSecurityAdmissionConfigurationTemplateName: label,
23
- kubernetesVersion: 'v1.25.0+rke2r1'
29
+ kubernetesVersion: k8s
24
30
  }
25
31
  },
26
32
  provider: 'whatever',
@@ -93,4 +99,198 @@ describe('component: rke2', () => {
93
99
 
94
100
  expect((select.vm as unknown as any).options[0].label).toBe(`${ label } (Current)`);
95
101
  });
102
+
103
+ it.each([
104
+ ['v1.25.0+rke2r1', 'none'],
105
+ ['v1.24.0+rke2r1', 'default'],
106
+ ['v1.23.0+rke2r1', 'default'],
107
+ ['v1.25.0+k3s1', 'none'],
108
+ ['v1.24.0+k3s1', 'default'],
109
+ ['v1.23.0+k3s1', 'default'],
110
+ ])('should display for version %p PSA option label %p', (k8s, partialLabel) => {
111
+ const label = `cluster.rke2.defaultPodSecurityAdmissionConfigurationTemplateName.option.${ partialLabel }`;
112
+ const option = { label, value: label };
113
+ const wrapper = mount(rke2, {
114
+ propsData: {
115
+ mode: 'create',
116
+ value: {
117
+ spec: {
118
+ rkeConfig: { etcd: { disableSnapshots: false } },
119
+ chartValues: {},
120
+ defaultPodSecurityAdmissionConfigurationTemplateName: label,
121
+ kubernetesVersion: k8s
122
+ }
123
+ },
124
+ provider: 'whatever',
125
+ resource: {}
126
+ },
127
+ computed: {
128
+ showForm() {
129
+ return true;
130
+ },
131
+ hasMachinePools() {
132
+ return false;
133
+ },
134
+ showk8s21LegacyWarning() {
135
+ return false;
136
+ },
137
+ },
138
+ mocks: {
139
+ $fetchState: { pending: false },
140
+ $route: {
141
+ name: 'anything',
142
+ query: { AS: 'yaml' },
143
+ },
144
+ $store: {
145
+ getters: {
146
+ currentStore: () => 'current_store',
147
+ 'management/schemaFor': jest.fn(),
148
+ 'current_store/all': jest.fn(),
149
+ 'i18n/t': jest.fn(),
150
+ 'i18n/withFallback': jest.fn(),
151
+ },
152
+ dispatch: {
153
+ 'management/find': jest.fn(),
154
+ 'management/findAll': () => ([option]),
155
+ }
156
+ },
157
+ },
158
+ stubs: {
159
+ CruResource: { template: '<div><slot></slot></div>' }, // Required to render the slot content
160
+ Banner: true,
161
+ LabeledSelect: true,
162
+ ACE: true,
163
+ AgentEnv: true,
164
+ ArrayList: true,
165
+ ArrayListGrouped: true,
166
+ BadgeState: true,
167
+ Checkbox: true,
168
+ ClusterMembershipEditor: true,
169
+ DrainOptions: true,
170
+ LabeledInput: true,
171
+ Labels: true,
172
+ Loading: true,
173
+ MachinePool: true,
174
+ MatchExpressions: true,
175
+ NameNsDescription: true,
176
+ Questions: true,
177
+ RadioGroup: true,
178
+ RegistryConfigs: true,
179
+ RegistryMirrors: true,
180
+ S3Config: true,
181
+ SelectCredential: true,
182
+ SelectOrCreateAuthSecret: true,
183
+ Tab: true,
184
+ Tabbed: true,
185
+ UnitInput: true,
186
+ YamlEditor: true,
187
+ }
188
+ });
189
+
190
+ const select = wrapper.find('[data-testid="rke2-custom-edit-psa"]');
191
+
192
+ expect((select.vm as unknown as any).options[0].label).toStrictEqual(`${ label } (Current)`);
193
+ });
194
+
195
+ it.each([
196
+ ['anything', false, true],
197
+ ['', false, false],
198
+ ['', true, false],
199
+ ])('given CIS value as %p and its override as %p, it should set PSA dropdown as disabled %p', (cis, override, disabled) => {
200
+ const label = 'whatever';
201
+ const k8s = 'v1.25.0+rke2r1';
202
+ const option = { label, value: label };
203
+ const wrapper = mount(rke2, {
204
+ propsData: {
205
+ mode: 'create',
206
+ value: {
207
+ agentConfig: { profile: cis },
208
+ spec: {
209
+ rkeConfig: { etcd: { disableSnapshots: false } },
210
+ chartValues: {},
211
+ defaultPodSecurityAdmissionConfigurationTemplateName: label,
212
+ kubernetesVersion: k8s
213
+ }
214
+ },
215
+ provider: 'custom',
216
+ resource: {}
217
+ },
218
+ computed: {
219
+ showForm() {
220
+ return true;
221
+ },
222
+ hasMachinePools() {
223
+ return false;
224
+ },
225
+ showk8s21LegacyWarning() {
226
+ return false;
227
+ },
228
+ agentArgs: () => ({ profile: { options: [cis] } }),
229
+ versionOptions: () => [
230
+ {
231
+ value: k8s,
232
+ agentArgs: { profile: { options: [cis] } },
233
+ charts: {},
234
+ profile: { options: [cis] }
235
+ }
236
+ ]
237
+ },
238
+ mocks: {
239
+ $fetchState: { pending: false },
240
+ $route: {
241
+ name: 'anything',
242
+ query: { AS: 'yaml' },
243
+ },
244
+ $store: {
245
+ getters: {
246
+ currentStore: () => 'current_store',
247
+ 'management/schemaFor': jest.fn(),
248
+ 'current_store/all': jest.fn(),
249
+ 'i18n/t': jest.fn(),
250
+ 'i18n/withFallback': jest.fn(),
251
+ },
252
+ dispatch: {
253
+ 'management/find': jest.fn(),
254
+ 'management/findAll': () => ([option]),
255
+ }
256
+ },
257
+ },
258
+ stubs: {
259
+ CruResource: { template: '<div><slot></slot></div>' }, // Required to render the slot content
260
+ Banner: true,
261
+ LabeledSelect: true,
262
+ ACE: true,
263
+ AgentEnv: true,
264
+ ArrayList: true,
265
+ ArrayListGrouped: true,
266
+ BadgeState: true,
267
+ Checkbox: true,
268
+ ClusterMembershipEditor: true,
269
+ DrainOptions: true,
270
+ LabeledInput: true,
271
+ Labels: true,
272
+ Loading: true,
273
+ MachinePool: true,
274
+ MatchExpressions: true,
275
+ NameNsDescription: true,
276
+ Questions: true,
277
+ RadioGroup: true,
278
+ RegistryConfigs: true,
279
+ RegistryMirrors: true,
280
+ S3Config: true,
281
+ SelectCredential: true,
282
+ SelectOrCreateAuthSecret: true,
283
+ Tab: true,
284
+ Tabbed: true,
285
+ UnitInput: true,
286
+ YamlEditor: true,
287
+ }
288
+ });
289
+
290
+ wrapper.setData({ cisOverride: override });
291
+
292
+ const select = wrapper.find('[data-testid="rke2-custom-edit-psa"]');
293
+
294
+ expect((select.vm as unknown as any).disabled).toBe(disabled);
295
+ });
96
296
  });