@rancher/shell 3.0.12-rc.2 → 3.0.12-rc.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (272) hide show
  1. package/apis/impl/apis.ts +6 -0
  2. package/apis/index.ts +26 -0
  3. package/apis/intf/resources-api/cluster-api.ts +18 -0
  4. package/apis/intf/resources-api/mgmt-api.ts +15 -0
  5. package/apis/intf/resources-api/resource-base.ts +107 -0
  6. package/apis/intf/resources-api/resource-constants.ts +147 -0
  7. package/apis/intf/resources-api/resources-api.ts +143 -0
  8. package/apis/intf/resources.ts +49 -0
  9. package/apis/intf/{modal.ts → shell-api/modal.ts} +21 -26
  10. package/apis/intf/shell-api/proxy.ts +216 -0
  11. package/apis/intf/{slide-in.ts → shell-api/slide-in.ts} +4 -3
  12. package/apis/intf/{system.ts → shell-api/system.ts} +4 -1
  13. package/apis/intf/shell.ts +12 -6
  14. package/apis/resources/__tests__/resources-api-class.test.ts +550 -0
  15. package/apis/resources/index.ts +22 -0
  16. package/apis/resources/resources-api-class.ts +187 -0
  17. package/apis/shell/__tests__/proxy.test.ts +369 -0
  18. package/apis/shell/index.ts +8 -1
  19. package/apis/shell/modal.ts +4 -1
  20. package/apis/shell/notifications.ts +9 -6
  21. package/apis/shell/proxy.ts +256 -0
  22. package/apis/shell/slide-in.ts +4 -1
  23. package/apis/vue-shim.d.ts +2 -1
  24. package/assets/data/aws-regions.json +4 -0
  25. package/assets/fonts/lato/LatoLatin-Black.woff +0 -0
  26. package/assets/fonts/lato/LatoLatin-Black.woff2 +0 -0
  27. package/assets/fonts/lato/LatoLatin-BlackItalic.woff +0 -0
  28. package/assets/fonts/lato/LatoLatin-BlackItalic.woff2 +0 -0
  29. package/assets/fonts/lato/LatoLatin-Bold.woff +0 -0
  30. package/assets/fonts/lato/LatoLatin-Bold.woff2 +0 -0
  31. package/assets/fonts/lato/LatoLatin-BoldItalic.woff +0 -0
  32. package/assets/fonts/lato/LatoLatin-BoldItalic.woff2 +0 -0
  33. package/assets/fonts/lato/LatoLatin-Heavy.woff +0 -0
  34. package/assets/fonts/lato/LatoLatin-Heavy.woff2 +0 -0
  35. package/assets/fonts/lato/LatoLatin-HeavyItalic.woff +0 -0
  36. package/assets/fonts/lato/LatoLatin-HeavyItalic.woff2 +0 -0
  37. package/assets/fonts/lato/LatoLatin-Italic.woff +0 -0
  38. package/assets/fonts/lato/LatoLatin-Italic.woff2 +0 -0
  39. package/assets/fonts/lato/LatoLatin-Light.woff +0 -0
  40. package/assets/fonts/lato/LatoLatin-Light.woff2 +0 -0
  41. package/assets/fonts/lato/LatoLatin-LightItalic.woff +0 -0
  42. package/assets/fonts/lato/LatoLatin-LightItalic.woff2 +0 -0
  43. package/assets/fonts/lato/LatoLatin-Medium.woff +0 -0
  44. package/assets/fonts/lato/LatoLatin-Medium.woff2 +0 -0
  45. package/assets/fonts/lato/LatoLatin-MediumItalic.woff +0 -0
  46. package/assets/fonts/lato/LatoLatin-MediumItalic.woff2 +0 -0
  47. package/assets/fonts/lato/LatoLatin-Regular.woff +0 -0
  48. package/assets/fonts/lato/LatoLatin-Regular.woff2 +0 -0
  49. package/assets/fonts/lato/LatoLatin-Semibold.woff +0 -0
  50. package/assets/fonts/lato/LatoLatin-Semibold.woff2 +0 -0
  51. package/assets/fonts/lato/LatoLatin-SemiboldItalic.woff +0 -0
  52. package/assets/fonts/lato/LatoLatin-SemiboldItalic.woff2 +0 -0
  53. package/assets/styles/base/_variables.scss +2 -0
  54. package/assets/styles/fonts/_fontstack.scss +132 -8
  55. package/assets/translations/en-us.yaml +22 -5
  56. package/chart/monitoring/index.vue +10 -1
  57. package/components/ActionDropdownShell.vue +2 -1
  58. package/components/CruResourceFooter.vue +9 -5
  59. package/components/ExplorerProjectsNamespaces.vue +1 -1
  60. package/components/InstallHelmCharts.vue +2 -2
  61. package/components/LandingPagePreference.vue +14 -5
  62. package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +15 -1
  63. package/components/Resource/Detail/Metadata/index.vue +6 -0
  64. package/components/Resource/Detail/ResourcePopover/index.vue +12 -1
  65. package/components/Resource/Detail/SpacedRow.vue +3 -1
  66. package/components/Resource/Detail/TitleBar/index.vue +10 -11
  67. package/components/ResourceList/Masthead.vue +12 -8
  68. package/components/SelectIconGrid.vue +0 -10
  69. package/components/SingleClusterInfo.vue +1 -0
  70. package/components/SortableTable/__tests__/sorting.test.ts +126 -0
  71. package/components/SortableTable/index.vue +6 -9
  72. package/components/SortableTable/selection.js +23 -5
  73. package/components/SortableTable/sorting.js +6 -3
  74. package/components/Wizard.vue +14 -13
  75. package/components/fleet/FleetBundles.vue +100 -12
  76. package/components/fleet/FleetClusterTargets/index.vue +37 -15
  77. package/components/fleet/__tests__/FleetClusterTargets.test.ts +149 -115
  78. package/components/fleet/__tests__/FleetClusters.test.ts +12 -12
  79. package/components/form/LabeledSelect.vue +20 -3
  80. package/components/form/NameNsDescription.vue +11 -0
  81. package/components/form/Security.vue +6 -2
  82. package/components/form/WorkloadPorts.vue +2 -7
  83. package/components/form/__tests__/Security.test.ts +76 -0
  84. package/components/formatter/Autoscaler.vue +4 -4
  85. package/components/formatter/ClusterKubeVersion.vue +27 -0
  86. package/components/formatter/ClusterLink.vue +1 -7
  87. package/components/formatter/ClusterProvider.vue +6 -10
  88. package/components/formatter/FleetSummaryGraph.vue +0 -3
  89. package/components/formatter/MachineSummaryGraph.vue +1 -1
  90. package/components/formatter/PodsUsage.vue +2 -2
  91. package/components/formatter/__tests__/Autoscaler.test.ts +19 -22
  92. package/components/formatter/__tests__/FleetSummaryGraph.test.ts +216 -0
  93. package/components/formatter/__tests__/PodsUsage.test.ts +6 -10
  94. package/components/nav/NamespaceFilter.vue +2 -2
  95. package/components/nav/TopLevelMenu.helper.ts +15 -3
  96. package/components/nav/TopLevelMenu.vue +16 -5
  97. package/components/nav/__tests__/TopLevelMenu.test.ts +145 -21
  98. package/components/templates/home.vue +18 -0
  99. package/components/templates/plain.vue +18 -0
  100. package/components/templates/standalone.vue +17 -0
  101. package/composables/useFormValidation.ts +93 -0
  102. package/composables/useVeeValidateField.test.ts +159 -0
  103. package/composables/useVeeValidateField.ts +67 -0
  104. package/config/pagination-table-headers.js +18 -1
  105. package/config/product/manager.js +82 -21
  106. package/config/router/routes.js +6 -0
  107. package/config/table-headers.js +20 -1
  108. package/config/types.js +2 -1
  109. package/core/__tests__/plugin-products.test.ts +904 -20
  110. package/core/plugin-products-base.ts +107 -7
  111. package/core/plugin-products.ts +4 -0
  112. package/core/plugin-types.ts +111 -1
  113. package/core/plugin.ts +15 -7
  114. package/core/productDebugger.js +9 -4
  115. package/core/types-provisioning.ts +43 -30
  116. package/core/types.ts +57 -20
  117. package/detail/__tests__/pod.test.ts +41 -0
  118. package/detail/harvesterhci.io.management.cluster.vue +6 -2
  119. package/detail/pod.vue +1 -1
  120. package/detail/provisioning.cattle.io.cluster.vue +4 -10
  121. package/edit/auth/__tests__/azuread.test.ts +217 -34
  122. package/edit/auth/azuread.vue +122 -14
  123. package/edit/auth/oidc.vue +2 -2
  124. package/edit/networking.k8s.io.ingress/DefaultBackend.vue +13 -4
  125. package/edit/networking.k8s.io.ingress/RulePath.vue +8 -4
  126. package/edit/networking.k8s.io.ingress/index.vue +75 -20
  127. package/edit/provisioning.cattle.io.cluster/__tests__/MachinePool.test.ts +104 -0
  128. package/edit/provisioning.cattle.io.cluster/index.vue +11 -7
  129. package/edit/provisioning.cattle.io.cluster/rke2.vue +8 -4
  130. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +11 -0
  131. package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +37 -4
  132. package/edit/provisioning.cattle.io.cluster/tabs/registries/__tests__/RegistryConfigs.test.ts +132 -7
  133. package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +2 -1
  134. package/edit/secret/__tests__/ssh.test.ts +5 -6
  135. package/edit/secret/basic.vue +31 -0
  136. package/edit/secret/index.vue +68 -17
  137. package/edit/secret/registry.vue +38 -0
  138. package/edit/secret/ssh.vue +29 -0
  139. package/edit/secret/tls.vue +30 -0
  140. package/edit/service.vue +4 -4
  141. package/edit/workload/Upgrading.vue +3 -3
  142. package/edit/workload/__tests__/Upgrading.test.ts +6 -9
  143. package/edit/workload/mixins/workload.js +2 -1
  144. package/list/fleet.cattle.io.bundle.vue +7 -104
  145. package/list/fleet.cattle.io.clusterregistrationtoken.vue +20 -0
  146. package/list/provisioning.cattle.io.cluster.vue +262 -180
  147. package/list/utils/management.cattle.io.cluster.utils.ts +128 -0
  148. package/mixins/__tests__/chart.test.ts +112 -0
  149. package/mixins/brand.js +2 -1
  150. package/mixins/chart.js +12 -8
  151. package/mixins/resource-fetch-api-pagination.js +41 -5
  152. package/models/__tests__/ext.cattle.io.kubeconfig.test.ts +67 -67
  153. package/models/__tests__/management.cattle.io.cluster.test.ts +1 -1
  154. package/models/__tests__/management.cattle.io.node.ts +6 -5
  155. package/models/__tests__/management.cattle.io.nodepool.ts +5 -4
  156. package/models/__tests__/provisioning.cattle.io.cluster.test.ts +32 -11
  157. package/models/base-cluster.x-k8s.io.js +26 -0
  158. package/models/cluster.js +1 -1
  159. package/models/cluster.x-k8s.io.machine.js +4 -22
  160. package/models/cluster.x-k8s.io.machinedeployment.js +2 -20
  161. package/models/cluster.x-k8s.io.machineset.js +2 -20
  162. package/models/compliance.cattle.io.clusterscan.js +130 -2
  163. package/models/ext.cattle.io.kubeconfig.ts +4 -7
  164. package/models/fleet-application.js +3 -1
  165. package/models/management.cattle.io.cluster.js +417 -40
  166. package/models/management.cattle.io.node.js +6 -4
  167. package/models/management.cattle.io.nodepool.js +1 -1
  168. package/models/networking.k8s.io.ingress.js +12 -4
  169. package/models/provisioning.cattle.io.cluster.js +47 -330
  170. package/models/rke.cattle.io.etcdsnapshot.js +1 -2
  171. package/package.json +11 -29
  172. package/pages/__tests__/readme.test.ts +49 -0
  173. package/pages/auth/setup.vue +2 -3
  174. package/pages/c/_cluster/apps/charts/__tests__/chart.test.ts +76 -0
  175. package/pages/c/_cluster/apps/charts/chart.vue +60 -8
  176. package/pages/c/_cluster/apps/charts/install.vue +10 -7
  177. package/pages/c/_cluster/explorer/__tests__/index.test.ts +23 -25
  178. package/pages/c/_cluster/explorer/index.vue +5 -49
  179. package/pages/c/_cluster/istio/__tests__/istio.index.test.ts +194 -0
  180. package/pages/c/_cluster/istio/index.vue +21 -6
  181. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +1 -0
  182. package/pages/c/_cluster/uiplugins/__tests__/index.test.ts +719 -2
  183. package/pages/c/_cluster/uiplugins/index.vue +203 -197
  184. package/pages/diagnostic.vue +13 -17
  185. package/pages/fail-whale.vue +18 -0
  186. package/pages/home.vue +77 -260
  187. package/pages/readme.vue +88 -0
  188. package/plugins/dashboard-store/__tests__/resource-class.test.ts +88 -0
  189. package/plugins/dashboard-store/actions.js +40 -18
  190. package/plugins/dashboard-store/resource-class.js +5 -2
  191. package/plugins/steve/__tests__/subscribe.spec.ts +6 -3
  192. package/plugins/steve/steve-pagination-utils.ts +11 -3
  193. package/plugins/steve/subscribe.js +35 -5
  194. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +10 -4
  195. package/rancher-components/Form/LabeledInput/LabeledInput.vue +7 -52
  196. package/rancher-components/RcButton/RcButton.test.ts +37 -1
  197. package/rancher-components/RcButton/RcButton.vue +38 -8
  198. package/rancher-components/RcDropdown/RcDropdownTrigger.vue +10 -8
  199. package/store/__tests__/catalog.test.ts +115 -1
  200. package/store/__tests__/type-map.test.ts +556 -1
  201. package/store/action-menu.js +8 -3
  202. package/store/auth.js +1 -1
  203. package/store/aws.js +27 -16
  204. package/store/catalog.js +27 -3
  205. package/store/digitalocean.js +20 -38
  206. package/store/index.js +2 -0
  207. package/store/linode.js +25 -40
  208. package/store/pnap.js +1 -0
  209. package/store/type-map.js +111 -29
  210. package/tsconfig.paths.json +8 -8
  211. package/types/kube/kube-api.ts +14 -1
  212. package/types/rancher/steve.api.ts +12 -12
  213. package/types/resources/settings.d.ts +2 -1
  214. package/types/shell/index.d.ts +102 -2
  215. package/types/store/dashboard-store.types.ts +108 -11
  216. package/types/store/pagination.types.ts +6 -3
  217. package/utils/__tests__/alertmanagerconfig.test.ts +117 -0
  218. package/utils/__tests__/async.test.ts +87 -0
  219. package/utils/__tests__/aws.test.ts +140 -0
  220. package/utils/__tests__/banners.test.ts +176 -0
  221. package/utils/__tests__/chart.test.ts +64 -1
  222. package/utils/__tests__/color.test.ts +226 -0
  223. package/utils/__tests__/duration.test.ts +140 -0
  224. package/utils/__tests__/fleet.test.ts +340 -0
  225. package/utils/__tests__/ingress.test.ts +553 -0
  226. package/utils/__tests__/kube.test.ts +68 -0
  227. package/utils/__tests__/namespace-filter.test.ts +109 -0
  228. package/utils/__tests__/pagination-utils.test.ts +361 -0
  229. package/utils/__tests__/parse-externalid.test.ts +137 -0
  230. package/utils/__tests__/perf-setting.utils.test.ts +98 -0
  231. package/utils/__tests__/poller-sequential.test.ts +177 -0
  232. package/utils/__tests__/poller.test.ts +170 -0
  233. package/utils/__tests__/promise.test.ts +346 -0
  234. package/utils/__tests__/settings.test.ts +140 -0
  235. package/utils/__tests__/sort-utils.test.ts +301 -0
  236. package/utils/__tests__/string-utils.test.ts +798 -0
  237. package/utils/__tests__/string.test.ts +23 -1
  238. package/utils/__tests__/style.test.ts +154 -0
  239. package/utils/__tests__/svg-filter.test.ts +184 -0
  240. package/utils/__tests__/units.test.ts +417 -0
  241. package/utils/__tests__/versions.test.ts +128 -0
  242. package/utils/__tests__/xccdf.test.ts +391 -0
  243. package/utils/chart.js +36 -0
  244. package/utils/fleet.ts +13 -3
  245. package/utils/gatekeeper/__tests__/util.test.ts +174 -0
  246. package/utils/gc/__tests__/gc-interval.test.ts +119 -0
  247. package/utils/gc/__tests__/gc-root-store.test.ts +225 -0
  248. package/utils/gc/__tests__/gc-route-changed.test.ts +96 -0
  249. package/utils/gc/__tests__/gc.test.ts +487 -0
  250. package/utils/ingress.ts +9 -1
  251. package/utils/pagination-utils.ts +2 -1
  252. package/utils/string.js +25 -2
  253. package/utils/uiplugins.ts +5 -5
  254. package/utils/validators/__tests__/cluster-name.test.ts +110 -0
  255. package/utils/validators/__tests__/cron-schedule.test.ts +79 -0
  256. package/utils/validators/__tests__/index.test.ts +481 -0
  257. package/utils/validators/__tests__/kubernetes-name.test.ts +163 -0
  258. package/utils/validators/__tests__/misc-validators.test.ts +246 -0
  259. package/utils/validators/__tests__/pod-affinity.test.ts +382 -0
  260. package/utils/validators/__tests__/prometheusrule.test.ts +211 -0
  261. package/utils/validators/__tests__/role-template.test.ts +149 -0
  262. package/utils/validators/__tests__/service.test.ts +283 -0
  263. package/utils/validators/__tests__/setting.test.js +32 -0
  264. package/utils/validators/formRules/__tests__/index.test.ts +50 -0
  265. package/utils/validators/formRules/index.ts +5 -5
  266. package/utils/validators/machine-pool.ts +1 -1
  267. package/utils/validators/setting.js +18 -3
  268. package/utils/xccdf.ts +418 -0
  269. package/assets/fonts/lato/lato-v17-latin-700.woff +0 -0
  270. package/assets/fonts/lato/lato-v17-latin-700.woff2 +0 -0
  271. package/assets/fonts/lato/lato-v17-latin-regular.woff +0 -0
  272. package/assets/fonts/lato/lato-v17-latin-regular.woff2 +0 -0
@@ -0,0 +1,256 @@
1
+ import { Store } from 'vuex';
2
+ import { ProxyApi, ProxyAuthCloudCredential, ProxyAuthToken, ProxyRequestOptions } from '@shell/apis/intf/shell';
3
+ import { Metadata } from '@shell/types/resources/settings';
4
+ import { MANAGEMENT } from '@shell/config/types';
5
+ import { get } from '@shell/utils/object';
6
+
7
+ /**
8
+ * Shell implementation of the `ProxyApi`.
9
+ *
10
+ * This API centralizes proxy request behavior used across providers:
11
+ * - building `/meta/proxy` URLs
12
+ * - applying credential or token auth headers
13
+ * - dispatching requests via `management/request`
14
+ * - optional de-pagination for list endpoints
15
+ */
16
+ export class ProxyApiImpl implements ProxyApi {
17
+ private store: Store<any>;
18
+
19
+ /**
20
+ * Creates a new Proxy API instance.
21
+ *
22
+ * @param store - Root Vuex store used to dispatch `management/request`.
23
+ */
24
+ constructor(store: Store<any>) {
25
+ this.store = store;
26
+ }
27
+
28
+ /**
29
+ * Executes a generic proxy request.
30
+ *
31
+ * Behavior:
32
+ * - Builds a proxied URL and dispatches `management/request`.
33
+ * - When `dePaginate` is enabled, follows the configured `next` URL and
34
+ * merges results recursively.
35
+ *
36
+ * @param options - Proxy request options.
37
+ * @returns The response payload or accumulated de-paginated output.
38
+ */
39
+ public async request(options: ProxyRequestOptions): Promise<any> {
40
+ const url = this.buildProxyUrl(options);
41
+ const headers = this.buildHeaders(options);
42
+ const req = {
43
+ url,
44
+ method: options.method,
45
+ headers,
46
+ redirectUnauthorized: false,
47
+ } as any;
48
+
49
+ if (options.data) {
50
+ req.body = options.data;
51
+ }
52
+
53
+ const res = await this.store.dispatch('management/request', req, { root: true });
54
+
55
+ if (options.postProcess) {
56
+ return options.postProcess(res);
57
+ }
58
+
59
+ return res;
60
+ }
61
+
62
+ /**
63
+ * Builds a `/meta/proxy` URL by stripping the scheme from `options.url`.
64
+ */
65
+ private buildProxyUrl(options: ProxyRequestOptions): string {
66
+ const raw = options.url.toString();
67
+
68
+ return `/meta/proxy/${ raw.replace(/^https:\/\//, '').replace(/^http:\/\//, 'http:/') }`;
69
+ }
70
+
71
+ /**
72
+ * Builds request headers, including auth headers derived from `options.authentication`.
73
+ */
74
+ private buildHeaders(options: ProxyRequestOptions): Record<string, string> {
75
+ const headers: Record<string, string> = {
76
+ Accept: options.accept || 'application/json',
77
+ ...(options.headers || {})
78
+ };
79
+
80
+ const auth = options.authentication;
81
+
82
+ if (!auth) {
83
+ return headers;
84
+ }
85
+
86
+ if ('id' in auth) {
87
+ // Cloud credential — instruct Rancher to sign the request server-side
88
+ const {
89
+ id, authSigner, usernameField, passwordField
90
+ } = auth as ProxyAuthCloudCredential;
91
+ let value = authSigner ? `${ authSigner } ` : '';
92
+
93
+ value += `credID=${ id } `;
94
+ if (usernameField) {
95
+ value += `usernameField=${ usernameField } `;
96
+ }
97
+ if (passwordField) {
98
+ value += `passwordField=${ passwordField } `;
99
+ }
100
+ headers['x-api-cattleauth-header'] = value.trimEnd();
101
+ } else {
102
+ // Plain token — forwarded verbatim as Authorization by the proxy
103
+ const { token, authSigner } = auth as ProxyAuthToken;
104
+ const scheme = authSigner ?? 'Bearer';
105
+
106
+ headers['x-api-auth-header'] = `${ scheme } ${ token }`;
107
+ }
108
+
109
+ return headers;
110
+ }
111
+
112
+ /**
113
+ * Builds the proxy URL and auth headers for a request without dispatching it.
114
+ *
115
+ * Useful for integrating with lower-level HTTP handlers (e.g. the AWS SDK
116
+ * request handler) that need to apply proxy routing and auth themselves
117
+ * rather than going through the Vuex `management/request` action.
118
+ *
119
+ * @param options - Proxy request options.
120
+ * @returns An object containing the resolved proxy `url` and the `headers`
121
+ * to merge into the outbound request.
122
+ */
123
+ public prepareRequest(options: ProxyRequestOptions): { url: string; headers: Record<string, string> } {
124
+ return {
125
+ url: this.buildProxyUrl(options),
126
+ headers: this.buildHeaders(options),
127
+ };
128
+ }
129
+
130
+ /**
131
+ * Creates a `ProxyEndpoint` CR that registers the given domain patterns
132
+ * with the Rancher `/meta/proxy` allow-list.
133
+ *
134
+ * The CR is cluster-scoped (`management.cattle.io/v3`, kind `ProxyEndpoint`).
135
+ * Each entry in `urls` maps to a `spec.routes[].domain` entry on the CR.
136
+ *
137
+ * @param domains - Bare hostnames or wildcard patterns accepted by the proxy
138
+ * backend (e.g. `api.example.com`, `%.amazonaws.com`).
139
+ * @param name - Optional metadata name for the CR. When omitted a name is
140
+ * auto-generated by the API server.
141
+ * @returns The created `ProxyEndpoint` resource.
142
+ */
143
+ public async allowDomains(domains: string[], name?: string): Promise<any> {
144
+ const metadata = {} as Metadata;
145
+
146
+ if (name) {
147
+ metadata.name = name;
148
+ } else {
149
+ metadata.generateName = 'endpoints-';
150
+ }
151
+ const resource = await this.store.dispatch('management/create', {
152
+ type: MANAGEMENT.PROXY_ENDPOINT,
153
+ metadata,
154
+ spec: { routes: domains.map((domain) => ({ domain })) },
155
+ });
156
+
157
+ return resource.save();
158
+ }
159
+
160
+ /**
161
+ * Checks whether a domain pattern is already present in any existing
162
+ * `ProxyEndpoint` CR.
163
+ *
164
+ * The comparison is a case-insensitive exact match against each
165
+ * `spec.routes[].domain` entry across all CRs — the same format accepted
166
+ * by `allowDomains` (e.g. `api.example.com`, `%.amazonaws.com`).
167
+ *
168
+ * @param domain - The hostname or wildcard pattern to look up.
169
+ * @returns `true` if the pattern is found in at least one `ProxyEndpoint` CR,
170
+ * `false` otherwise.
171
+ */
172
+ public async isDomainAllowed(domain: string): Promise<boolean> {
173
+ const endpoints: any[] = await this.store.dispatch('management/findAll', { type: MANAGEMENT.PROXY_ENDPOINT });
174
+
175
+ const needle = domain.toLowerCase();
176
+
177
+ return endpoints.some((endpoint) => (endpoint?.spec?.routes ?? []).some(
178
+ (route: { domain: string }) => route.domain?.toLowerCase() === needle
179
+ )
180
+ );
181
+ }
182
+
183
+ /**
184
+ * Checks whether a `ProxyEndpoint` CR with the given name exists.
185
+ *
186
+ * Uses `management/find` and treats a 404 response as `false` rather than
187
+ * an error. Any other error is re-thrown.
188
+ *
189
+ * @param name - The metadata name of the `ProxyEndpoint` CR to look up.
190
+ * @returns `true` if the CR exists, `false` if it is not found.
191
+ */
192
+ public async hasProxyEndpoint(name: string): Promise<boolean> {
193
+ try {
194
+ await this.store.dispatch('management/find', {
195
+ type: MANAGEMENT.PROXY_ENDPOINT,
196
+ id: name,
197
+ opt: { force: false },
198
+ });
199
+
200
+ return true;
201
+ } catch (e: any) {
202
+ if (e?.status === 404) {
203
+ return false;
204
+ }
205
+ throw e;
206
+ }
207
+ }
208
+ }
209
+
210
+ /**
211
+ * Creates a `postProcess` callback for use with `ProxyApi.request()` that
212
+ * automatically follows pagination links and merges array results across pages.
213
+ *
214
+ * @param proxyApi - The `ProxyApi` instance used to fetch subsequent pages.
215
+ * @param requestOptions - Base request options (without `postProcess`) reused for each page.
216
+ * @param opts.nextUrlPath - Dot-path or jsonpath to the next-page URL in the response.
217
+ * Defaults to `links.pages.next`.
218
+ * @param opts.mergeKey - Response key whose array value is merged across pages.
219
+ * When omitted the first top-level array key is used.
220
+ *
221
+ * @example
222
+ * ```ts
223
+ * const baseOptions = { url: 'api.example.com/v1/items', authentication };
224
+ * const result = await proxy.request({
225
+ * ...baseOptions,
226
+ * postProcess: createDepaginator(proxy, baseOptions, { mergeKey: 'items' }),
227
+ * });
228
+ * ```
229
+ */
230
+ export function createDepaginator(
231
+ proxyApi: ProxyApi,
232
+ requestOptions: Omit<ProxyRequestOptions, 'postProcess'>,
233
+ opts: { nextUrlPath?: string; mergeKey?: string } = {}
234
+ ): (res: any) => Promise<any> {
235
+ const nextPath = opts.nextUrlPath ?? 'links.pages.next';
236
+ const mergeKey = opts.mergeKey;
237
+
238
+ const paginate = async(res: any, accumulated?: any): Promise<any> => {
239
+ const key = mergeKey ?? Object.keys(res ?? {}).find((k) => Array.isArray(res[k]));
240
+
241
+ // If we have a prior page's data, concatenate this page's array into it; otherwise use this page as-is
242
+ const merged = (accumulated !== undefined && key && Array.isArray(accumulated[key]) && Array.isArray(res?.[key])) ? { ...res, [key]: [...accumulated[key], ...res[key]] } : res;
243
+
244
+ const nextUrl = get(merged, nextPath);
245
+
246
+ if (!nextUrl) {
247
+ return merged;
248
+ }
249
+
250
+ const nextRes = await proxyApi.request({ ...requestOptions, url: new URL(nextUrl) });
251
+
252
+ return paginate(nextRes, merged);
253
+ };
254
+
255
+ return (res: any) => paginate(res);
256
+ }
@@ -14,9 +14,12 @@ export class SlideInApiImpl implements SlideInApi {
14
14
  *
15
15
  * Example:
16
16
  * ```ts
17
+ * import { useShell } from '@shell/apis';
17
18
  * import MyCustomSlideIn from '@/components/MyCustomSlideIn.vue';
18
19
  *
19
- * this.$shell.slideIn.open(MyCustomSlideIn, {
20
+ * const shell = useShell();
21
+ *
22
+ * shell.slideIn.open(MyCustomSlideIn, {
20
23
  * title: 'Hello from SlideIn panel!'
21
24
  * });
22
25
  * ```
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable */
2
- import { ShellApi, ExtensionManagerApi } from '@shell/apis';
2
+ import { ShellApi, ExtensionManagerApi, ResourcesApiProvider } from '@shell/apis';
3
3
 
4
4
  export {};
5
5
 
@@ -7,5 +7,6 @@ declare module 'vue' {
7
7
  interface ComponentCustomProperties {
8
8
  $shell: ShellApi,
9
9
  $extension: ExtensionManagerApi,
10
+ $resources: ResourcesApiProvider,
10
11
  }
11
12
  }
@@ -12,6 +12,7 @@
12
12
  "ap-southeast-3",
13
13
  "ap-southeast-4",
14
14
  "ap-southeast-5",
15
+ "ap-southeast-6",
15
16
  "ap-southeast-7",
16
17
  "ca-central-1",
17
18
  "ca-west-1",
@@ -37,6 +38,9 @@
37
38
  "us-iso-east-1",
38
39
  "us-iso-west-1",
39
40
  "us-isob-east-1",
41
+ "us-isob-west-1",
42
+ "us-isof-east-1",
43
+ "us-isof-south-1",
40
44
  "us-west-1",
41
45
  "us-west-2"
42
46
  ]
@@ -10,6 +10,8 @@ $unlabeled-input-height: 40px;
10
10
  $unlabaled-select-padding: 3px 0;
11
11
  $footer-height: 60px;
12
12
 
13
+ $resource-detail-min-width: 740px;
14
+
13
15
  $input-padding-lg: 18px;
14
16
  $input-padding-sm: 10px;
15
17
  $input-line-height: 18px;
@@ -18,24 +18,148 @@
18
18
  url('~@shell/assets/fonts/poppins/poppins-v15-latin-500.woff') format('woff'), /* Modern Browsers */
19
19
  }
20
20
 
21
- /* lato-regular - latin */
21
+ /**
22
+ * Lato Font (Latin) (see: https://www.latofonts.com/)
23
+ **/
24
+
25
+ /* Webfont: Lato-Light (300) */
26
+ @font-face {
27
+ font-family: 'Lato';
28
+ font-style: normal;
29
+ font-weight: 300;
30
+ text-rendering: optimizeLegibility;
31
+ src: url('~@shell/assets/fonts/lato/LatoLatin-Light.woff2') format('woff2'), /* Modern Browsers */
32
+ url('~@shell/assets/fonts/lato/LatoLatin-Light.woff') format('woff'); /* Modern Browsers */
33
+ }
34
+
35
+ /* Webfont: Lato-LightItalic (300) */
36
+ @font-face {
37
+ font-family: 'Lato';
38
+ font-style: italic;
39
+ font-weight: 300;
40
+ text-rendering: optimizeLegibility;
41
+ src: url('~@shell/assets/fonts/lato/LatoLatin-LightItalic.woff2') format('woff2'), /* Modern Browsers */
42
+ url('~@shell/assets/fonts/lato/LatoLatin-LightItalic.woff') format('woff'); /* Modern Browsers */
43
+ }
44
+
45
+ /* Webfont: Lato-Regular (400) */
22
46
  @font-face {
23
47
  font-family: 'Lato';
24
48
  font-style: normal;
25
49
  font-weight: normal;
26
- src: local(''),
27
- url('~@shell/assets/fonts/lato/lato-v17-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
28
- url('~@shell/assets/fonts/lato/lato-v17-latin-regular.woff') format('woff'), /* Modern Browsers */
50
+ text-rendering: optimizeLegibility;
51
+ src: url('~@shell/assets/fonts/lato/LatoLatin-Regular.woff2') format('woff2'), /* Modern Browsers */
52
+ url('~@shell/assets/fonts/lato/LatoLatin-Regular.woff') format('woff'); /* Modern Browsers */
53
+ }
54
+
55
+ /* Webfont: Lato-Italic (400) */
56
+ @font-face {
57
+ font-family: 'Lato';
58
+ font-style: italic;
59
+ font-weight: normal;
60
+ text-rendering: optimizeLegibility;
61
+ src: url('~@shell/assets/fonts/lato/LatoLatin-Italic.woff2') format('woff2'), /* Modern Browsers */
62
+ url('~@shell/assets/fonts/lato/LatoLatin-Italic.woff') format('woff'); /* Modern Browsers */
63
+ }
64
+
65
+ /* Webfont: Lato-Medium (500) */
66
+ @font-face {
67
+ font-family: 'Lato';
68
+ font-style: normal;
69
+ font-weight: 500;
70
+ text-rendering: optimizeLegibility;
71
+ src: url('~@shell/assets/fonts/lato/LatoLatin-Medium.woff2') format('woff2'), /* Modern Browsers */
72
+ url('~@shell/assets/fonts/lato/LatoLatin-Medium.woff') format('woff'); /* Modern Browsers */
73
+ }
74
+
75
+ /* Webfont: Lato-MediumItalic (500) */
76
+ @font-face {
77
+ font-family: 'Lato';
78
+ font-style: italic;
79
+ font-weight: 500;
80
+ text-rendering: optimizeLegibility;
81
+ src: url('~@shell/assets/fonts/lato/LatoLatin-MediumItalic.woff2') format('woff2'), /* Modern Browsers */
82
+ url('~@shell/assets/fonts/lato/LatoLatin-MediumItalic.woff') format('woff'); /* Modern Browsers */
83
+ }
84
+
85
+ /* Webfont: LatoLatin-Semibold (600) */
86
+ @font-face {
87
+ font-family: 'Lato';
88
+ font-style: normal;
89
+ font-weight: 600;
90
+ text-rendering: optimizeLegibility;
91
+ src: url('~@shell/assets/fonts/lato/LatoLatin-Semibold.woff2') format('woff2'), /* Modern Browsers */
92
+ url('~@shell/assets/fonts/lato/LatoLatin-Semibold.woff') format('woff'); /* Modern Browsers */
93
+ }
94
+
95
+ /* Webfont: LatoLatin-SemiboldItalic (600) */
96
+ @font-face {
97
+ font-family: 'Lato';
98
+ font-style: italic;
99
+ font-weight: 600;
100
+ text-rendering: optimizeLegibility;
101
+ src: url('~@shell/assets/fonts/lato/LatoLatin-SemiboldItalic.woff2') format('woff2'), /* Modern Browsers */
102
+ url('~@shell/assets/fonts/lato/LatoLatin-SemiboldItalic.woff') format('woff'); /* Modern Browsers */
29
103
  }
30
104
 
31
- /* lato-700 - latin */
105
+ /* Webfont: LatoLatin-Bold (700) */
32
106
  @font-face {
33
107
  font-family: 'Lato';
34
108
  font-style: normal;
35
109
  font-weight: bold;
36
- src: local(''),
37
- url('~@shell/assets/fonts/lato/lato-v17-latin-700.woff2') format('woff2'), /* Super Modern Browsers */
38
- url('~@shell/assets/fonts/lato/lato-v17-latin-700.woff') format('woff'), /* Modern Browsers */
110
+ text-rendering: optimizeLegibility;
111
+ src: url('~@shell/assets/fonts/lato/LatoLatin-Bold.woff2') format('woff2'), /* Modern Browsers */
112
+ url('~@shell/assets/fonts/lato/LatoLatin-Bold.woff') format('woff'); /* Modern Browsers */
113
+ }
114
+
115
+ /* Webfont: LatoLatin-BoldItalic (700) */
116
+ @font-face {
117
+ font-family: 'Lato';
118
+ font-style: italic;
119
+ font-weight: bold;
120
+ text-rendering: optimizeLegibility;
121
+ src: url('~@shell/assets/fonts/lato/LatoLatin-BoldItalic.woff2') format('woff2'), /* Modern Browsers */
122
+ url('~@shell/assets/fonts/lato/LatoLatin-BoldItalic.woff') format('woff'); /* Modern Browsers */
123
+ }
124
+
125
+ /* Webfont: Lato-Heavy (800) */
126
+ @font-face {
127
+ font-family: 'Lato';
128
+ font-style: normal;
129
+ font-weight: 800;
130
+ text-rendering: optimizeLegibility;
131
+ src: url('~@shell/assets/fonts/lato/LatoLatin-Heavy.woff2') format('woff2'), /* Modern Browsers */
132
+ url('~@shell/assets/fonts/lato/LatoLatin-Heavy.woff') format('woff'); /* Modern Browsers */
133
+ }
134
+
135
+ /* Webfont: Lato-HeavyItalic (800) */
136
+ @font-face {
137
+ font-family: 'Lato';
138
+ font-style: italic;
139
+ font-weight: 800;
140
+ text-rendering: optimizeLegibility;
141
+ src: url('~@shell/assets/fonts/lato/LatoLatin-HeavyItalic.woff2') format('woff2'), /* Modern Browsers */
142
+ url('~@shell/assets/fonts/lato/LatoLatin-HeavyItalic.woff') format('woff'); /* Modern Browsers */
143
+ }
144
+
145
+ /* Webfont: Lato-Black (900) */
146
+ @font-face {
147
+ font-family: 'Lato';
148
+ font-style: normal;
149
+ font-weight: 900;
150
+ text-rendering: optimizeLegibility;
151
+ src: url('~@shell/assets/fonts/lato/LatoLatin-Black.woff2') format('woff2'), /* Modern Browsers */
152
+ url('~@shell/assets/fonts/lato/LatoLatin-Black.woff') format('woff'); /* Modern Browsers */
153
+ }
154
+
155
+ /* Webfont: Lato-BlackItalic (900) */
156
+ @font-face {
157
+ font-family: 'Lato';
158
+ font-style: italic;
159
+ font-weight: 900;
160
+ text-rendering: optimizeLegibility;
161
+ src: url('~@shell/assets/fonts/lato/LatoLatin-BlackItalic.woff2') format('woff2'), /* Modern Browsers */
162
+ url('~@shell/assets/fonts/lato/LatoLatin-BlackItalic.woff') format('woff'); /* Modern Browsers */
39
163
  }
40
164
 
41
165
  /* roboto-mono-regular - latin */
@@ -500,7 +500,7 @@ authConfig:
500
500
  unrestricted: Allow any valid user
501
501
  allowedPrincipalIds:
502
502
  title: Authorized Users & Groups
503
- associatedWarning: 'The {provider} account that is used to enable the external provider will be granted admin permissions. If you use a test account or non-admin account, that account will still be granted admin-level permissions. See <a href="{docsBase}/how-to-guides/new-user-guides/authentication-permissions-and-global-configuration/authentication-config#external-authentication-configuration-and-principal-users" target="_blank" rel="noopener noreferrer nofollow">External Authentication Configuration and Principal Users</a> to understand why.'
503
+ associatedWarning: 'The {provider} account that is used to enable the external provider will be granted permissions equal to the currently logged in Rancher user. See <a href="{docsBase}/how-to-guides/new-user-guides/authentication-permissions-and-global-configuration/authentication-config#external-authentication-configuration-and-principal-users" target="_blank" rel="noopener noreferrer nofollow">External Authentication Configuration and Principal Users</a> to understand why.'
504
504
  githubapp:
505
505
  clientId:
506
506
  label: Client ID
@@ -734,6 +734,9 @@ authConfig:
734
734
  label: Token Endpoint
735
735
  authEndpoint:
736
736
  label: Auth Endpoint
737
+ endSessionEndpoint:
738
+ title: End Session Endpoint
739
+ tooltip: Azure AD URL used for logging a user out of their session (e.g. https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/logout)
737
740
  groupMembershipFilter:
738
741
  label: Group Membership Filter
739
742
  enable: Limit users by group membership
@@ -1156,6 +1159,9 @@ catalog:
1156
1159
  deprecatedWarning: '{chartName} has been marked as deprecated. Use caution when installing this helm chart as it might be removed in the future.'
1157
1160
  experimentalWarning: '{chartName} has been marked as experimental. Use caution when installing this helm chart as it might not function as expected.'
1158
1161
  deprecatedAndExperimentalWarning: '{chartName} has been marked as deprecated and experimental. Use caution when installing this helm chart as it might be removed in the future and might not function as expected.'
1162
+ viewReadmeSeparately:
1163
+ label: View separately
1164
+ tooltip: Open the readme in a new tab
1159
1165
  installedAppsSelector:
1160
1166
  ariaLabel: Select installed app instance
1161
1167
  chartButton:
@@ -1511,9 +1517,12 @@ compliance:
1511
1517
  =1 { Any scheduled scans using this profile will no longer work. }
1512
1518
  other { Any scheduled scans using either of these profiles will no longer work. }
1513
1519
  }
1514
- downloadAllReports: Download All Saved Reports
1515
- downloadLatestReport: Download Latest Report
1516
- downloadReport: Download Report
1520
+ downloadAllReports: Download All Saved Reports (CSV)
1521
+ downloadAllReportsXCCDF: Download All Saved Reports (XCCDF)
1522
+ downloadLatestReport: Download Latest Report (CSV)
1523
+ downloadLatestReportXCCDF: Download Latest Report (XCCDF)
1524
+ downloadReport: Download Report (CSV)
1525
+ downloadReportXCCDF: Download Report (XCCDF)
1517
1526
  maxKubernetesVersion: Maximum allowed Kubernetes version
1518
1527
  minKubernetesVersion: Minimum required Kubernetes version
1519
1528
  noProfiles: There are no valid ClusterScanProfiles for this cluster type to select.
@@ -1522,6 +1531,8 @@ compliance:
1522
1531
  reports: Reports
1523
1532
  retention: Retention Count
1524
1533
  scan:
1534
+ errorNoParsedNodes: No nodes were parsed from the scan results, so no report can be generated.
1535
+ errorDownload: Error downloading file
1525
1536
  description: Description
1526
1537
  fail: Fail
1527
1538
  lastScanTime: Last Scan Time
@@ -2338,7 +2349,9 @@ cluster:
2338
2349
  etcdControlPlaneWarning: We don't recommend using Autoscaler with machine pools that have the etcd or Control Plane roles. You can modify the yaml if you want to override the current value.
2339
2350
  name:
2340
2351
  label: Pool Name
2352
+ notNamed: (Not Named)
2341
2353
  placeholder: A random one will be generated by default
2354
+ unique: Pool names should be unique
2342
2355
  nodeTotals:
2343
2356
  label:
2344
2357
  controlPlane: '{count} Control Plane'
@@ -2391,7 +2404,7 @@ cluster:
2391
2404
  label: Auto Replace
2392
2405
  toolTip: If greater than 0, nodes that are unreachable for this duration will be automatically deleted and replaced.
2393
2406
  unit: "Seconds"
2394
- managementTimeout: The cluster to become available. It's possible the cluster was created. We suggest checking the clusters page before trying to create another.
2407
+ managementTimeout: The {type} {name} to become available. It's possible the cluster was created. We suggest checking the clusters page before trying to create another.
2395
2408
  memberRoles:
2396
2409
  removeMessage: 'Note: Removing a user will not remove their project permissions'
2397
2410
  addClusterMember:
@@ -6182,6 +6195,7 @@ resourceTable:
6182
6195
  cluster: Group by Cluster
6183
6196
  device: Group by Device
6184
6197
  pool: Group by Pool
6198
+ workspace: Group by Workspace
6185
6199
  groupLabel:
6186
6200
  cluster: "<span>Cluster:</span> {name}"
6187
6201
  notInACluster: Not in a Cluster
@@ -8786,6 +8800,9 @@ registryConfig:
8786
8800
  toolTip: 'When an image needs to be pulled from the given registry hostname, this information will be used to verify the identity of the registry and authenticate to it.'
8787
8801
  addLabel: Add Registry
8788
8802
  description: "Define the TLS and credential configuration for each registry hostname and mirror."
8803
+ caBundle:
8804
+ tooltip: Accepts a CA PEM certificate or a base64 encoded CA PEM.
8805
+ validationError: Invalid CA cert bundle. Must be a CA PEM certificate or a base64 encoded CA PEM.
8789
8806
 
8790
8807
  ##############################
8791
8808
  ### Advanced Settings
@@ -17,6 +17,7 @@ import Tabbed from '@shell/components/Tabbed';
17
17
  import { allHash } from '@shell/utils/promise';
18
18
  import { STORAGE_CLASS, PVC, SECRET, WORKLOAD_TYPES } from '@shell/config/types';
19
19
  import { CATTLE_MONITORING_NAMESPACE } from '@shell/utils/monitoring';
20
+ import { CATALOG as CATALOG_ANNOTATIONS } from '@shell/config/labels-annotations';
20
21
 
21
22
  export default {
22
23
  emits: ['register-before-hook', 'input'],
@@ -50,6 +51,12 @@ export default {
50
51
  return {};
51
52
  },
52
53
  },
54
+
55
+ // The selected chart version object, passed from install.vue
56
+ version: {
57
+ type: Object,
58
+ default: null,
59
+ },
53
60
  },
54
61
 
55
62
  async fetch() {
@@ -92,7 +99,9 @@ export default {
92
99
 
93
100
  const hash = await allHash(hashPromises);
94
101
 
95
- this.targetNamespace = hash.namespaces[this.chart.targetNamespace] || false;
102
+ const ns = this.version?.annotations?.[CATALOG_ANNOTATIONS.NAMESPACE] || this.chart.targetNamespace;
103
+
104
+ this.targetNamespace = hash.namespaces[ns] || false;
96
105
 
97
106
  if (!isEmpty(hash.storageClasses)) {
98
107
  this.storageClasses = hash.storageClasses;