@rancher/shell 3.0.12-rc.3 → 3.0.12-rc.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 (315) hide show
  1. package/assets/styles/global/_button.scss +1 -1
  2. package/assets/styles/global/_layout.scss +4 -0
  3. package/assets/translations/en-us.yaml +183 -51
  4. package/assets/translations/zh-hans.yaml +1 -7
  5. package/chart/monitoring/ClusterSelector.vue +0 -21
  6. package/chart/monitoring/prometheus/index.vue +6 -3
  7. package/components/ActionDropdownShell.vue +5 -3
  8. package/components/ButtonGroup.vue +26 -1
  9. package/components/CruResource.vue +212 -16
  10. package/components/ExplorerMembers.vue +8 -4
  11. package/components/ExplorerProjectsNamespaces.vue +10 -6
  12. package/components/GrowlManager.vue +4 -0
  13. package/components/MgmtNodeList.vue +184 -0
  14. package/components/PromptRestore.vue +93 -32
  15. package/components/Questions/index.vue +1 -0
  16. package/components/Resource/Detail/Card/StateCard/__tests__/composables.test.ts +90 -1
  17. package/components/Resource/Detail/Card/StateCard/composables.ts +57 -87
  18. package/components/Resource/Detail/Card/StatusCard/__tests__/StatusCard.test.ts +61 -0
  19. package/components/Resource/Detail/Card/StatusCard/index.vue +61 -15
  20. package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +2 -0
  21. package/components/Resource/Detail/Metadata/KeyValue.vue +5 -2
  22. package/components/Resource/Detail/Metadata/KeyValueRow.vue +2 -6
  23. package/components/ResourceDetail/index.vue +1 -1
  24. package/components/ResourceList/Masthead.vue +7 -1
  25. package/components/ResourceList/index.vue +82 -1
  26. package/components/ResourceTable.vue +1 -0
  27. package/components/RichTranslation.vue +5 -2
  28. package/components/Setting.vue +1 -0
  29. package/components/SortableTable/index.vue +4 -3
  30. package/components/SubtleLink.vue +31 -6
  31. package/components/Tabbed/Tab.vue +29 -3
  32. package/components/Tabbed/index.vue +25 -3
  33. package/components/TableOfContents/TableOfContents.vue +109 -0
  34. package/components/TableOfContents/composables.ts +258 -0
  35. package/components/Window/ContainerShell.vue +21 -11
  36. package/components/Window/__tests__/ContainerShell.test.ts +107 -37
  37. package/components/Wizard.vue +23 -5
  38. package/components/__tests__/ButtonGroup.test.ts +56 -0
  39. package/components/__tests__/PromptRestore.test.ts +169 -19
  40. package/components/fleet/AppCoChartGrid.vue +401 -0
  41. package/components/fleet/AppCoEmptyState.vue +127 -0
  42. package/components/fleet/AppCoPageHeader.vue +119 -0
  43. package/components/fleet/AppCoVersionSelect.vue +70 -0
  44. package/components/fleet/FleetClusterTargets/ClusterSelectionFields.vue +217 -0
  45. package/components/fleet/FleetClusterTargets/TargetsList.vue +123 -35
  46. package/components/fleet/FleetClusterTargets/index.vue +189 -146
  47. package/components/fleet/FleetIntro.vue +7 -3
  48. package/components/fleet/FleetNoWorkspaces.vue +7 -3
  49. package/components/fleet/FleetSecretSelector.vue +5 -3
  50. package/components/fleet/FleetValuesFrom.vue +8 -2
  51. package/components/fleet/GitRepoAdvancedTab.vue +1 -0
  52. package/components/fleet/GitRepoMetadataTab.vue +5 -0
  53. package/components/fleet/GitRepoTargetTab.vue +0 -2
  54. package/components/fleet/HelmOpAdvancedTab.vue +19 -53
  55. package/components/fleet/HelmOpAppCoConfigTab.vue +597 -0
  56. package/components/fleet/HelmOpAppCoResourcesSection.vue +162 -0
  57. package/components/fleet/HelmOpMetadataTab.vue +5 -0
  58. package/components/fleet/HelmOpResourcesSection.vue +82 -0
  59. package/components/fleet/HelmOpTargetOptionsSection.vue +89 -0
  60. package/components/fleet/HelmOpTargetTab.vue +64 -60
  61. package/components/fleet/HelmOpValuesTab.vue +129 -105
  62. package/components/fleet/__tests__/AppCoEmptyState.test.ts +71 -0
  63. package/components/fleet/__tests__/AppCoVersionSelect.test.ts +36 -0
  64. package/components/fleet/__tests__/ClusterSelectionFields.test.ts +62 -0
  65. package/components/fleet/__tests__/FleetClusterTargets.test.ts +253 -0
  66. package/components/fleet/__tests__/FleetSecretSelector.test.ts +16 -0
  67. package/components/fleet/__tests__/FleetValuesFrom.test.ts +44 -0
  68. package/components/fleet/__tests__/HelmOpAppCoConfigTab.test.ts +59 -0
  69. package/components/fleet/__tests__/HelmOpAppCoResourcesSection.test.ts +62 -0
  70. package/components/fleet/__tests__/HelmOpResourcesSection.test.ts +43 -0
  71. package/components/fleet/__tests__/HelmOpTargetOptionsSection.test.ts +34 -0
  72. package/components/fleet/__tests__/HelmOpValuesTab.test.ts +39 -0
  73. package/components/fleet/__tests__/__snapshots__/AppCoEmptyState.test.ts.snap +97 -0
  74. package/components/fleet/__tests__/__snapshots__/AppCoVersionSelect.test.ts.snap +30 -0
  75. package/components/fleet/__tests__/__snapshots__/ClusterSelectionFields.test.ts.snap +209 -0
  76. package/components/fleet/__tests__/__snapshots__/HelmOpTargetOptionsSection.test.ts.snap +140 -0
  77. package/components/fleet/dashboard/Empty.vue +8 -4
  78. package/components/fleet/dashboard/ResourceCard.vue +28 -0
  79. package/components/fleet/dashboard/ResourceDetails.vue +28 -0
  80. package/components/fleet/dashboard/__tests__/ResourceCard.test.ts +87 -0
  81. package/components/form/ArrayList.vue +61 -4
  82. package/components/form/FileSelector.vue +39 -1
  83. package/components/form/KeyValue.vue +23 -2
  84. package/components/form/LabeledSelect.vue +39 -1
  85. package/components/form/Labels.vue +22 -3
  86. package/components/form/NameNsDescription.vue +13 -5
  87. package/components/form/PrivateRegistry.constants.ts +7 -0
  88. package/components/form/PrivateRegistry.vue +253 -18
  89. package/components/form/ResourceTabs/index.vue +1 -0
  90. package/components/form/SelectOrCreateAuthSecret.vue +140 -17
  91. package/components/form/__tests__/FileSelector.test.ts +23 -0
  92. package/components/form/__tests__/NameNsDescription.test.ts +75 -0
  93. package/components/form/__tests__/PrivateRegistry.test.ts +463 -73
  94. package/components/form/__tests__/SelectOrCreateAuthSecret.test.ts +122 -0
  95. package/components/formatter/EtcdSnapshotName.vue +73 -0
  96. package/components/formatter/InternalExternalIP.vue +10 -4
  97. package/components/formatter/ServiceTargets.vue +26 -7
  98. package/components/formatter/__tests__/InternalExternalIP.test.ts +132 -0
  99. package/components/formatter/__tests__/ServiceTargets.test.ts +412 -0
  100. package/components/nav/Header.vue +12 -1
  101. package/components/nav/TopLevelMenu.vue +7 -2
  102. package/components/nav/__tests__/Header.test.ts +15 -0
  103. package/components/nav/__tests__/TopLevelMenu.test.ts +120 -2
  104. package/components/templates/default.vue +16 -4
  105. package/components/templates/home.vue +9 -4
  106. package/components/templates/plain.vue +9 -4
  107. package/composables/useHelmOpResources.test.ts +56 -0
  108. package/composables/useHelmOpResources.ts +32 -0
  109. package/composables/useStateColor.test.ts +325 -0
  110. package/composables/useStateColor.ts +128 -0
  111. package/config/features.js +1 -0
  112. package/config/home-links.js +1 -1
  113. package/config/labels-annotations.js +3 -0
  114. package/config/product/explorer.js +17 -4
  115. package/config/product/manager.js +8 -0
  116. package/config/router/index.js +16 -0
  117. package/config/router/navigation-guards/__tests__/authentication.test.ts +130 -0
  118. package/config/router/navigation-guards/authentication.js +10 -4
  119. package/config/router/routes.js +20 -6
  120. package/config/secret.ts +10 -0
  121. package/config/settings.ts +6 -4
  122. package/config/table-headers.js +3 -4
  123. package/config/types.js +16 -0
  124. package/core/plugin-products-base.ts +3 -3
  125. package/core/plugin-types.ts +83 -30
  126. package/core/plugin.ts +3 -0
  127. package/core/types-provisioning.ts +34 -1
  128. package/core/types.ts +15 -2
  129. package/detail/__tests__/provisioning.cattle.io.cluster.test.ts +114 -0
  130. package/detail/__tests__/workload.test.ts +3 -152
  131. package/detail/catalog.cattle.io.clusterrepo.vue +1 -1
  132. package/detail/provisioning.cattle.io.cluster.vue +109 -7
  133. package/detail/workload/index.vue +12 -55
  134. package/dialog/RotateEncryptionKeyDialog.vue +33 -9
  135. package/dialog/__tests__/RotateEncryptionKeyDialog.test.ts +78 -0
  136. package/edit/__tests__/catalog.cattle.io.clusterrepo.test.ts +248 -0
  137. package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +92 -0
  138. package/edit/__tests__/fleet.cattle.io.helmop.test.ts +206 -0
  139. package/edit/__tests__/management.cattle.io.setting.test.ts +2 -1
  140. package/edit/auditlog.cattle.io.auditpolicy/__tests__/__snapshots__/General.test.ts.snap +6 -0
  141. package/edit/auditlog.cattle.io.auditpolicy/__tests__/__snapshots__/index.test.ts.snap +1 -0
  142. package/edit/auth/__tests__/azuread.test.ts +34 -9
  143. package/edit/auth/__tests__/github.test.ts +234 -0
  144. package/edit/auth/__tests__/oidc.test.ts +26 -6
  145. package/edit/auth/__tests__/saml.test.ts +196 -0
  146. package/edit/auth/azuread.vue +128 -95
  147. package/edit/auth/github.vue +72 -13
  148. package/edit/auth/ldap/__tests__/index.test.ts +206 -0
  149. package/edit/auth/ldap/config.vue +8 -0
  150. package/edit/auth/ldap/index.vue +75 -1
  151. package/edit/auth/oidc.vue +119 -73
  152. package/edit/auth/saml.vue +76 -12
  153. package/edit/catalog.cattle.io.clusterrepo.vue +140 -32
  154. package/edit/compliance.cattle.io.clusterscanprofile.vue +39 -41
  155. package/edit/fleet.cattle.io.gitrepo.vue +70 -16
  156. package/edit/fleet.cattle.io.helmop.vue +542 -141
  157. package/edit/helm.cattle.io.projecthelmchart.vue +1 -0
  158. package/edit/{management.cattle.io.setting.vue → management.cattle.io.setting/index.vue} +32 -9
  159. package/edit/management.cattle.io.setting/system-default-registry-pull-secrets.vue +81 -0
  160. package/edit/management.cattle.io.user.vue +5 -2
  161. package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +3 -12
  162. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +18 -0
  163. package/edit/provisioning.cattle.io.cluster/rke2.vue +89 -11
  164. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +11 -0
  165. package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +0 -1
  166. package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +14 -55
  167. package/list/group.principal.vue +5 -4
  168. package/list/harvesterhci.io.management.cluster.vue +8 -9
  169. package/list/management.cattle.io.user.vue +12 -9
  170. package/list/provisioning.cattle.io.cluster.vue +16 -10
  171. package/mixins/__tests__/auth-config.test.ts +90 -0
  172. package/mixins/__tests__/chart.test.ts +94 -0
  173. package/mixins/__tests__/resource-fetch-api-pagination.test.ts +48 -0
  174. package/mixins/auth-config.js +7 -0
  175. package/mixins/chart.js +11 -2
  176. package/mixins/child-hook.js +12 -6
  177. package/mixins/create-edit-view/impl.js +5 -3
  178. package/mixins/resource-fetch-api-pagination.js +21 -1
  179. package/models/__tests__/catalog.cattle.io.clusterrepo.test.ts +57 -0
  180. package/models/__tests__/compliance.cattle.io.clusterscan.test.ts +144 -0
  181. package/models/__tests__/fleet-application.test.ts +175 -0
  182. package/models/__tests__/fleet.cattle.io.bundle.test.ts +169 -0
  183. package/models/__tests__/fleet.cattle.io.helmop.test.ts +84 -0
  184. package/models/__tests__/management.cattle.io.node.ts +22 -0
  185. package/models/__tests__/namespace.test.ts +36 -0
  186. package/models/__tests__/provisioning.cattle.io.cluster.test.ts +205 -0
  187. package/models/__tests__/secret.test.ts +68 -1
  188. package/models/__tests__/workload.test.ts +401 -26
  189. package/models/catalog.cattle.io.clusterrepo.js +28 -4
  190. package/models/compliance.cattle.io.clusterscan.js +39 -4
  191. package/models/fleet-application.js +4 -0
  192. package/models/fleet.cattle.io.helmop.js +20 -1
  193. package/models/management.cattle.io.cluster.js +39 -5
  194. package/models/management.cattle.io.node.js +44 -3
  195. package/models/namespace.js +1 -1
  196. package/models/pod.js +46 -3
  197. package/models/provisioning.cattle.io.cluster.js +64 -14
  198. package/models/rke.cattle.io.etcdsnapshot.js +17 -9
  199. package/models/secret.js +19 -0
  200. package/models/workload.js +120 -20
  201. package/models/workload.service.js +5 -0
  202. package/package.json +14 -13
  203. package/pages/about.vue +5 -6
  204. package/pages/auth/login.vue +0 -35
  205. package/pages/auth/setup.vue +11 -0
  206. package/pages/c/_cluster/apps/charts/AppChartCardFooter.vue +2 -2
  207. package/pages/c/_cluster/apps/charts/AppChartCardSubHeader.vue +10 -1
  208. package/pages/c/_cluster/apps/charts/__tests__/index.test.ts +93 -0
  209. package/pages/c/_cluster/apps/charts/__tests__/install.test.ts +485 -107
  210. package/pages/c/_cluster/apps/charts/chart.vue +2 -1
  211. package/pages/c/_cluster/apps/charts/index.vue +48 -10
  212. package/pages/c/_cluster/apps/charts/install.vue +236 -144
  213. package/pages/c/_cluster/auth/roles/index.vue +5 -4
  214. package/pages/c/_cluster/explorer/workload-dashboard/ByNamespaceSection.vue +31 -0
  215. package/pages/c/_cluster/explorer/workload-dashboard/ByStateSection.vue +138 -0
  216. package/pages/c/_cluster/explorer/workload-dashboard/ByTypeSection.vue +30 -0
  217. package/pages/c/_cluster/explorer/workload-dashboard/WorkloadCard.vue +155 -0
  218. package/pages/c/_cluster/explorer/workload-dashboard/WorkloadNamespaceCard.vue +142 -0
  219. package/pages/c/_cluster/explorer/workload-dashboard/WorkloadTypeCard.vue +159 -0
  220. package/pages/c/_cluster/explorer/workload-dashboard/__tests__/composable.test.ts +561 -0
  221. package/pages/c/_cluster/explorer/workload-dashboard/composable.ts +440 -0
  222. package/pages/c/_cluster/explorer/workload-dashboard/index.vue +187 -0
  223. package/pages/c/_cluster/explorer/workload-dashboard/types.ts +80 -0
  224. package/pages/c/_cluster/fleet/application/create.vue +187 -136
  225. package/pages/c/_cluster/fleet/application/index.vue +5 -3
  226. package/pages/c/_cluster/fleet/application/suse-app-collection/ChartDetailBody.vue +338 -0
  227. package/pages/c/_cluster/fleet/application/suse-app-collection/ChartDetailHeader.vue +121 -0
  228. package/pages/c/_cluster/fleet/application/suse-app-collection/chart.vue +369 -0
  229. package/pages/c/_cluster/fleet/application/suse-app-collection/charts.vue +248 -0
  230. package/pages/c/_cluster/fleet/application/suse-app-collection/credentials.vue +310 -0
  231. package/pages/c/_cluster/fleet/index.vue +2 -2
  232. package/pages/c/_cluster/uiplugins/__tests__/index.test.ts +96 -0
  233. package/pages/c/_cluster/uiplugins/index.vue +15 -0
  234. package/pages/fail-whale.vue +16 -11
  235. package/pages/home.vue +16 -46
  236. package/pkg/require-asset.lib.js +25 -0
  237. package/pkg/vue.config.js +7 -0
  238. package/plugins/clean-html.d.ts +9 -0
  239. package/plugins/dashboard-store/__tests__/resource-class.test.ts +177 -0
  240. package/plugins/dashboard-store/getters.js +0 -1
  241. package/plugins/dashboard-store/resource-class.js +114 -19
  242. package/plugins/steve/__tests__/actions.test.ts +212 -0
  243. package/plugins/steve/actions.js +96 -0
  244. package/plugins/steve/steve-pagination-utils.ts +1 -1
  245. package/rancher-components/Accordion/Accordion.vue +53 -9
  246. package/rancher-components/Form/Checkbox/Checkbox.vue +14 -0
  247. package/rancher-components/Form/Radio/RadioButton.vue +17 -1
  248. package/rancher-components/Form/Radio/RadioGroup.vue +10 -0
  249. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +30 -0
  250. package/rancher-components/Form/TextArea/__tests__/TextAreaAutoGrow.test.ts +95 -0
  251. package/rancher-components/Pill/RcTag/RcTag.vue +3 -2
  252. package/rancher-components/RcButton/RcButton.test.ts +103 -0
  253. package/rancher-components/RcButton/RcButton.vue +94 -15
  254. package/rancher-components/RcButton/index.ts +1 -1
  255. package/rancher-components/RcButton/types.ts +3 -0
  256. package/rancher-components/RcDropdown/RcDropdownTrigger.vue +6 -1
  257. package/rancher-components/RcItemCard/RcItemCard.test.ts +18 -0
  258. package/rancher-components/RcItemCard/RcItemCard.vue +2 -2
  259. package/rancher-components/RcSection/RcSection.vue +28 -3
  260. package/scripts/extension/helm/package/Dockerfile +1 -1
  261. package/scripts/test-plugins-build.sh +2 -1
  262. package/store/__tests__/features.test.ts +131 -0
  263. package/store/__tests__/growl.test.ts +374 -0
  264. package/store/__tests__/modal.test.ts +131 -0
  265. package/store/__tests__/notifications.test.ts +434 -0
  266. package/store/__tests__/slideInPanel.test.ts +88 -0
  267. package/store/__tests__/type-map.utils.test.ts +433 -0
  268. package/store/catalog.js +57 -0
  269. package/store/features.js +4 -0
  270. package/store/plugins.js +7 -4
  271. package/types/components/buttonGroup.ts +5 -0
  272. package/types/shell/index.d.ts +166 -70
  273. package/utils/__tests__/auth.test.ts +273 -0
  274. package/utils/__tests__/computed.test.ts +193 -0
  275. package/utils/__tests__/cspAdaptor.test.ts +163 -0
  276. package/utils/__tests__/dom.test.ts +81 -0
  277. package/utils/__tests__/duration.test.ts +37 -1
  278. package/utils/__tests__/dynamic-importer.test.ts +102 -0
  279. package/utils/__tests__/fleet-appco.test.ts +312 -0
  280. package/utils/__tests__/monitoring.test.ts +130 -0
  281. package/utils/__tests__/object.test.ts +22 -0
  282. package/utils/__tests__/operation-cr.test.ts +34 -0
  283. package/utils/__tests__/platform.test.ts +91 -0
  284. package/utils/__tests__/position.test.ts +237 -0
  285. package/utils/__tests__/provider.test.ts +51 -1
  286. package/utils/__tests__/queue.test.ts +232 -0
  287. package/utils/__tests__/release-notes.test.ts +221 -0
  288. package/utils/__tests__/router.test.js +254 -1
  289. package/utils/__tests__/select.test.ts +208 -0
  290. package/utils/__tests__/time.test.ts +265 -1
  291. package/utils/__tests__/title.test.ts +47 -0
  292. package/utils/__tests__/width.test.ts +53 -0
  293. package/utils/__tests__/window.test.ts +158 -0
  294. package/utils/__tests__/xccdf.test.ts +126 -6
  295. package/utils/crypto/__tests__/browserHashUtils.test.ts +98 -0
  296. package/utils/crypto/__tests__/index.test.ts +144 -0
  297. package/utils/duration.ts +104 -0
  298. package/utils/dynamic-content/__tests__/notification-handler.test.ts +196 -0
  299. package/utils/dynamic-content/info.ts +2 -1
  300. package/utils/error.js +13 -0
  301. package/utils/fleet-appco.ts +323 -0
  302. package/utils/object.js +22 -2
  303. package/utils/operation-cr.js +19 -0
  304. package/utils/provider.ts +12 -0
  305. package/utils/require-asset.ts +7 -0
  306. package/utils/validators/__tests__/container-images.test.ts +104 -0
  307. package/utils/validators/__tests__/flow-output.test.ts +91 -0
  308. package/utils/validators/__tests__/logging-outputs.test.ts +58 -0
  309. package/utils/validators/__tests__/monitoring-route.test.ts +119 -0
  310. package/utils/validators/__tests__/private-registry.test.ts +27 -15
  311. package/utils/validators/private-registry.ts +15 -4
  312. package/utils/xccdf.ts +39 -42
  313. package/vue.config.js +1 -1
  314. package/pages/support/index.vue +0 -264
  315. package/utils/duration.js +0 -43
@@ -19,6 +19,7 @@ export const NODE_ARCHITECTURE = 'kubernetes.io/arch';
19
19
  export const IMPORTED_CLUSTER_VERSION_MANAGEMENT = 'rancher.io/imported-cluster-version-management';
20
20
  export const UI_PROJECT_SECRET = 'management.cattle.io/project-scoped-secret';
21
21
  export const UI_PROJECT_SECRET_COPY = 'management.cattle.io/project-scoped-secret-copy';
22
+ export const SERVICE_LINKS = 'ui.rancher/service-links';
22
23
 
23
24
  export const KUBERNETES = {
24
25
  SERVICE_ACCOUNT_UID: 'kubernetes.io/service-account.uid',
@@ -149,6 +150,8 @@ export const RKE = { EXTERNAL_IP: 'rke.cattle.io/external-ip' };
149
150
 
150
151
  export const SNAPSHOT = { CLUSTER_NAME: 'rke.cattle.io/cluster-name' };
151
152
 
153
+ export const OPERATION_ANNOTATIONS = { ENABLED: 'operations.cattle.io/ops-enabled' };
154
+
152
155
  export const ISTIO = { AUTO_INJECTION: 'istio-injection' };
153
156
 
154
157
  const CATTLE_REGEX = /cattle\.io\//;
@@ -10,6 +10,7 @@ import {
10
10
  SNAPSHOT,
11
11
  VIRTUAL_TYPES,
12
12
  CAPI,
13
+ WORKLOAD_DASHBOARD,
13
14
  } from '@shell/config/types';
14
15
 
15
16
  import {
@@ -103,6 +104,7 @@ export function init(store) {
103
104
  CONFIG_MAP
104
105
  ], 'storage');
105
106
  basicType([
107
+ WORKLOAD_DASHBOARD,
106
108
  WORKLOAD,
107
109
  WORKLOAD_TYPES.DEPLOYMENT,
108
110
  WORKLOAD_TYPES.DAEMON_SET,
@@ -112,10 +114,6 @@ export function init(store) {
112
114
  POD,
113
115
  ], 'workload');
114
116
 
115
- setGroupDefaultType('workload', () => {
116
- return store.getters['features/get'](STEVE_CACHE) ? WORKLOAD_TYPES.DEPLOYMENT : undefined;
117
- });
118
-
119
117
  weightGroup('cluster', 99, true);
120
118
  weightGroup('workload', 98, true);
121
119
  weightGroup('serviceDiscovery', 96, true);
@@ -586,6 +584,21 @@ export function init(store) {
586
584
  overview: true,
587
585
  });
588
586
 
587
+ // Workload Dashboard - overview page using the Resource Summary API
588
+ virtualType({
589
+ label: store.getters['i18n/t'](`typeLabel.${ WORKLOAD }`, { count: 2 }),
590
+ group: 'Root',
591
+ namespaced: true,
592
+ name: WORKLOAD_DASHBOARD,
593
+ weight: 100,
594
+ icon: 'folder',
595
+ ifHaveSubTypes: Object.values(WORKLOAD_TYPES),
596
+ ifFeature: STEVE_CACHE,
597
+ route: { name: 'c-cluster-explorer-workload-dashboard' },
598
+ exact: true,
599
+ overview: true,
600
+ });
601
+
589
602
  virtualType({
590
603
  labelKey: 'members.clusterAndProject',
591
604
  group: 'cluster',
@@ -10,6 +10,7 @@ import {
10
10
  HCI,
11
11
  MANAGEMENT,
12
12
  SNAPSHOT,
13
+ OPERATION,
13
14
  VIRTUAL_TYPES,
14
15
  HOSTED_PROVIDER,
15
16
  SAVED_COUNTS
@@ -80,6 +81,11 @@ export function init(store) {
80
81
  configureType(SNAPSHOT, { depaginate: true });
81
82
  configureType(CATALOG.CLUSTER_REPO, { listCreateButtonLabelKey: 'catalog.repo.add' });
82
83
 
84
+ // Day 2 operation CRDs - read-only, not user-creatable or editable
85
+ configureType(OPERATION.ETCD_SNAPSHOT, { isCreatable: false, isEditable: false });
86
+ configureType(OPERATION.ETCD_SNAPSHOT_RESTORE, { isCreatable: false, isEditable: false });
87
+ configureType(OPERATION.ENCRYPTION_KEY_ROTATE, { isCreatable: false, isEditable: false });
88
+
83
89
  configureType(CAPI.RANCHER_CLUSTER, {
84
90
  showListMasthead: false, namespaced: false, alias: [HCI.CLUSTER]
85
91
  });
@@ -130,10 +136,12 @@ export function init(store) {
130
136
 
131
137
  basicType([
132
138
  HOSTED_PROVIDER,
139
+ CAPI.CAPI_PROVIDER,
133
140
  'rke-kontainer-providers',
134
141
  'rke-node-providers',
135
142
  ], 'providers');
136
143
 
144
+ weightType(CAPI.CAPI_PROVIDER, 4, true);
137
145
  weightType(CAPI.MACHINE_DEPLOYMENT, 4, true);
138
146
  weightType(CAPI.MACHINE_SET, 3, true);
139
147
  weightType(CAPI.MACHINE, 2, true);
@@ -9,6 +9,22 @@ export const routerOptions = {
9
9
  base: process.env.routerBase || '/',
10
10
  routes: Routes,
11
11
  fallback: false,
12
+ scrollBehavior(to, from, savedPosition) {
13
+ // Returning the savedPosition will result in a native-like behavior when
14
+ // navigating with back/forward buttons
15
+ if (savedPosition) {
16
+ return savedPosition;
17
+ }
18
+
19
+ // Handle the "skip to main content" link
20
+ if (to.hash === '#main-content') {
21
+ const el = document.getElementById('main-content');
22
+
23
+ el?.focus();
24
+
25
+ return { el: to.hash };
26
+ }
27
+ },
12
28
  };
13
29
 
14
30
  export function extendRouter(config, context) {
@@ -0,0 +1,130 @@
1
+ import { authenticate } from '@shell/config/router/navigation-guards/authentication';
2
+
3
+ jest.mock('@shell/utils/router', () => ({ routeRequiresAuthentication: () => true }));
4
+
5
+ const isLoggedInMock = jest.fn();
6
+ const findMeMock = jest.fn();
7
+ const notLoggedInMock = jest.fn();
8
+ const noAuthMock = jest.fn();
9
+
10
+ jest.mock('@shell/utils/auth', () => {
11
+ const actual = jest.requireActual('@shell/utils/auth');
12
+
13
+ return {
14
+ ...actual,
15
+ isLoggedIn: (...args: any[]) => isLoggedInMock(...args),
16
+ findMe: (...args: any[]) => findMeMock(...args),
17
+ notLoggedIn: (...args: any[]) => notLoggedInMock(...args),
18
+ noAuth: (...args: any[]) => noAuthMock(...args),
19
+ };
20
+ });
21
+
22
+ function makeStore({ user, fromHeader }: { user: any, fromHeader: string }) {
23
+ const getters: Record<string, any> = {
24
+ 'auth/enabled': true,
25
+ 'auth/loggedIn': false,
26
+ 'auth/user': user,
27
+ 'auth/fromHeader': fromHeader,
28
+ };
29
+
30
+ return {
31
+ dispatch: jest.fn().mockResolvedValue(undefined),
32
+ commit: jest.fn(),
33
+ getters,
34
+ };
35
+ }
36
+
37
+ const to = { name: 'c-cluster-explorer', query: {} };
38
+
39
+ describe('navigation-guards/authentication: mustChangePassword', () => {
40
+ beforeEach(() => {
41
+ isLoggedInMock.mockReset().mockResolvedValue(undefined);
42
+ findMeMock.mockReset();
43
+ notLoggedInMock.mockReset();
44
+ noAuthMock.mockReset();
45
+ });
46
+
47
+ it('redirects local users with mustChangePassword to auth-setup', async() => {
48
+ const store = makeStore({
49
+ user: { mustChangePassword: true, principalIds: ['local://user-1'] },
50
+ fromHeader: 'true',
51
+ });
52
+
53
+ findMeMock.mockResolvedValue({ id: 'local://user-1', provider: 'local' });
54
+
55
+ const next = jest.fn();
56
+
57
+ await authenticate(to as any, {} as any, next, { store } as any);
58
+
59
+ expect(next).toHaveBeenCalledWith({ name: 'auth-setup' });
60
+ expect(isLoggedInMock).not.toHaveBeenCalled();
61
+ });
62
+
63
+ it('lets SSO users with mustChangePassword reach the requested route', async() => {
64
+ const me = { id: 'oidc_user://user@example.com', provider: 'genericoidc' };
65
+ const store = makeStore({
66
+ user: { mustChangePassword: true, principalIds: ['local://user-1', me.id] },
67
+ fromHeader: 'true',
68
+ });
69
+
70
+ findMeMock.mockResolvedValue(me);
71
+
72
+ const next = jest.fn();
73
+
74
+ await authenticate(to as any, {} as any, next, { store } as any);
75
+
76
+ expect(next).toHaveBeenCalledWith();
77
+ expect(next).not.toHaveBeenCalledWith({ name: 'auth-setup' });
78
+ expect(isLoggedInMock).toHaveBeenCalledTimes(1);
79
+ });
80
+
81
+ it('does not redirect when mustChangePassword is false, regardless of provider', async() => {
82
+ const store = makeStore({
83
+ user: { mustChangePassword: false, principalIds: ['local://user-1'] },
84
+ fromHeader: 'true',
85
+ });
86
+
87
+ findMeMock.mockResolvedValue({ id: 'local://user-1', provider: 'local' });
88
+
89
+ const next = jest.fn();
90
+
91
+ await authenticate(to as any, {} as any, next, { store } as any);
92
+
93
+ expect(next).toHaveBeenCalledWith();
94
+ expect(isLoggedInMock).toHaveBeenCalledTimes(1);
95
+ });
96
+
97
+ it('redirects local users with mustChangePassword to auth-setup for older-style fromHeader', async() => {
98
+ const store = makeStore({
99
+ user: { mustChangePassword: true, principalIds: ['local://user-1'] },
100
+ fromHeader: 'unknown',
101
+ });
102
+
103
+ findMeMock.mockResolvedValue({ id: 'local://user-1', provider: 'local' });
104
+
105
+ const next = jest.fn();
106
+
107
+ await authenticate(to as any, {} as any, next, { store } as any);
108
+
109
+ expect(next).toHaveBeenCalledWith({ name: 'auth-setup' });
110
+ expect(isLoggedInMock).not.toHaveBeenCalled();
111
+ });
112
+
113
+ it('lets SSO users with mustChangePassword through for older-style fromHeader', async() => {
114
+ const me = { id: 'saml_user://user', provider: 'saml' };
115
+ const store = makeStore({
116
+ user: { mustChangePassword: true, principalIds: ['local://user-1', me.id] },
117
+ fromHeader: 'unknown',
118
+ });
119
+
120
+ findMeMock.mockResolvedValue(me);
121
+
122
+ const next = jest.fn();
123
+
124
+ await authenticate(to as any, {} as any, next, { store } as any);
125
+
126
+ expect(next).toHaveBeenCalledWith();
127
+ expect(next).not.toHaveBeenCalledWith({ name: 'auth-setup' });
128
+ expect(isLoggedInMock).toHaveBeenCalledTimes(1);
129
+ });
130
+ });
@@ -61,19 +61,21 @@ export async function authenticate(to, from, next, { store }) {
61
61
  await store.dispatch('auth/getUser');
62
62
  const user = store.getters['auth/user'] || {};
63
63
 
64
- if (user?.mustChangePassword) {
65
- return next({ name: 'auth-setup' });
66
- }
67
-
68
64
  // In newer versions the API calls return the auth state instead of having to make a new call all the time.
69
65
  const fromHeader = store.getters['auth/fromHeader'];
70
66
 
67
+ const mustChangePasswordFor = (me) => user?.mustChangePassword && me?.provider === 'local';
68
+
71
69
  if ( fromHeader === 'none' ) {
72
70
  noAuth(store);
73
71
  handleOidcRedirectToCallbackUrl();
74
72
  } else if ( fromHeader === 'true' ) {
75
73
  const me = await findMe(store);
76
74
 
75
+ if (mustChangePasswordFor(me)) {
76
+ return next({ name: 'auth-setup' });
77
+ }
78
+
77
79
  await isLoggedIn(store, getUserObject(user, me));
78
80
  handleOidcRedirectToCallbackUrl();
79
81
  } else if ( fromHeader === 'false' ) {
@@ -85,6 +87,10 @@ export async function authenticate(to, from, next, { store }) {
85
87
  try {
86
88
  const me = await findMe(store);
87
89
 
90
+ if (mustChangePasswordFor(me)) {
91
+ return next({ name: 'auth-setup' });
92
+ }
93
+
88
94
  await isLoggedIn(store, getUserObject(user, me));
89
95
  handleOidcRedirectToCallbackUrl();
90
96
  } catch (e) {
@@ -58,12 +58,7 @@ export default [
58
58
  path: '/home',
59
59
  component: () => interopDefault(import('@shell/pages/home.vue')),
60
60
  name: 'home'
61
- },
62
- {
63
- path: '/support',
64
- component: () => interopDefault(import('@shell/pages/support/index.vue')),
65
- name: 'support'
66
- },
61
+ }
67
62
  ]
68
63
  },
69
64
  {
@@ -238,6 +233,21 @@ export default [
238
233
  path: '/c/:cluster/fleet/application/create',
239
234
  component: () => interopDefault(import('@shell/pages/c/_cluster/fleet/application/create.vue')),
240
235
  name: 'c-cluster-fleet-application-create',
236
+ }, {
237
+ path: '/c/:cluster/fleet/application/suse-app-collection/credentials',
238
+ component: () => interopDefault(import('@shell/pages/c/_cluster/fleet/application/suse-app-collection/credentials.vue')),
239
+ name: 'c-cluster-fleet-application-appco-credentials',
240
+ meta: { disableWorkspaceSwitcher: true },
241
+ }, {
242
+ path: '/c/:cluster/fleet/application/suse-app-collection/charts',
243
+ component: () => interopDefault(import('@shell/pages/c/_cluster/fleet/application/suse-app-collection/charts.vue')),
244
+ name: 'c-cluster-fleet-application-appco-charts',
245
+ meta: { disableWorkspaceSwitcher: true },
246
+ }, {
247
+ path: '/c/:cluster/fleet/application/suse-app-collection/chart',
248
+ component: () => interopDefault(import('@shell/pages/c/_cluster/fleet/application/suse-app-collection/chart.vue')),
249
+ name: 'c-cluster-fleet-application-appco-chart',
250
+ meta: { disableWorkspaceSwitcher: true },
241
251
  }, {
242
252
  path: '/c/:cluster/fleet/application/:resource/create',
243
253
  component: () => interopDefault(import('@shell/pages/c/_cluster/fleet/application/_resource/create.vue')),
@@ -349,6 +359,10 @@ export default [
349
359
  path: '/c/:cluster/explorer/explorer-utils',
350
360
  component: () => interopDefault(import('@shell/pages/c/_cluster/explorer/explorer-utils.js')),
351
361
  name: 'c-cluster-explorer-explorer-utils'
362
+ }, {
363
+ path: '/c/:cluster/explorer/workload-dashboard',
364
+ component: () => interopDefault(import('@shell/pages/c/_cluster/explorer/workload-dashboard/index.vue')),
365
+ name: 'c-cluster-explorer-workload-dashboard'
352
366
  }, {
353
367
  path: '/c/:cluster/explorer/tools',
354
368
  component: () => interopDefault(import('@shell/pages/c/_cluster/explorer/tools/index.vue')),
package/config/secret.ts CHANGED
@@ -13,3 +13,13 @@ export const SECRET_TYPES = {
13
13
  RKE_AUTH_CONFIG: 'rke.cattle.io/auth-config',
14
14
  FLEET_OCI_STORAGE: 'fleet.cattle.io/bundle-oci-storage/v1alpha1'
15
15
  };
16
+
17
+ /**
18
+ * Data keys for a Fleet GitHub App authentication secret (stored as an Opaque secret).
19
+ * Shared so the create flows stay in sync.
20
+ */
21
+ export const GITHUB_APP_SECRET_KEYS = {
22
+ APP_ID: 'github_app_id',
23
+ INSTALLATION_ID: 'github_app_installation_id',
24
+ PRIVATE_KEY: 'github_app_private_key',
25
+ };
@@ -63,11 +63,11 @@ export const SETTING = {
63
63
  AUTH_USER_INFO_RESYNC_CRON: 'auth-user-info-resync-cron',
64
64
  AUTH_LOCAL_VALIDATE_DESC: 'auth-password-requirements-description',
65
65
  PASSWORD_MIN_LENGTH: 'password-min-length', // CATTLE_PASSWORD_MIN_LENGTH
66
- UI_INDEX: 'ui-index',
67
66
  UI_DASHBOARD_INDEX: 'ui-dashboard-index',
68
67
  UI_DASHBOARD_HARVESTER_LEGACY_PLUGIN: 'ui-dashboard-harvester-legacy-plugin',
69
68
  UI_OFFLINE_PREFERRED: 'ui-offline-preferred',
70
69
  SYSTEM_DEFAULT_REGISTRY: 'system-default-registry',
70
+ SYSTEM_DEFAULT_REGISTRY_PULL_SECRETS: 'system-default-registry-pull-secrets',
71
71
  UI_ISSUES: 'ui-issues',
72
72
  PL: 'ui-pl',
73
73
  PL_RANCHER_VALUE: 'rancher',
@@ -125,6 +125,7 @@ export const SETTING = {
125
125
  */
126
126
  DYNAMIC_CONTENT_ENABLED: 'ui-content-enabled',
127
127
  DYNAMIC_CONTENT_ENDPOINT: 'ui-content-endpoint',
128
+ IMPORTED_CLUSTER_DAY2_OPS_DEFAULT: 'imported-cluster-day2-ops-enabled'
128
129
  } as const;
129
130
 
130
131
  // These are the settings that are allowed to be edited via the UI
@@ -164,7 +165,7 @@ export const ALLOWED_SETTINGS: GlobalSetting = {
164
165
  [SETTING.SERVER_URL]: { kind: 'url', canReset: true },
165
166
  [SETTING.RKE_METADATA_CONFIG]: { kind: 'json' },
166
167
  [SETTING.SYSTEM_DEFAULT_REGISTRY]: {},
167
- [SETTING.UI_INDEX]: {},
168
+ [SETTING.SYSTEM_DEFAULT_REGISTRY_PULL_SECRETS]: {},
168
169
  [SETTING.UI_DASHBOARD_INDEX]: {},
169
170
  [SETTING.UI_OFFLINE_PREFERRED]: {
170
171
  kind: 'enum',
@@ -186,12 +187,12 @@ export const ALLOWED_SETTINGS: GlobalSetting = {
186
187
  ruleSet: [{ name: 'minValue', factoryArg: 1 }]
187
188
  },
188
189
  [SETTING.IMPORTED_CLUSTER_VERSION_MANAGEMENT]: { kind: 'boolean' },
190
+ [SETTING.IMPORTED_CLUSTER_DAY2_OPS_DEFAULT]: { kind: 'boolean' },
189
191
  // Configuration setup for agent configuration. Setting this up will activate the specific banner configuration.
190
192
  [SETTING.CLUSTER_AGENT_DEFAULT_PRIORITY_CLASS]: { kind: 'json', agent: AGENT_CONFIGURATION_TYPES.CLUSTER },
191
193
  [SETTING.CLUSTER_AGENT_DEFAULT_POD_DISTRIBUTION_BUDGET]: { kind: 'json', agent: AGENT_CONFIGURATION_TYPES.CLUSTER },
192
194
  [SETTING.FLEET_AGENT_DEFAULT_PRIORITY_CLASS]: { kind: 'json', agent: AGENT_CONFIGURATION_TYPES.FLEET },
193
- [SETTING.FLEET_AGENT_DEFAULT_POD_DISTRIBUTION_BUDGET]: { kind: 'json', agent: AGENT_CONFIGURATION_TYPES.FLEET }
194
-
195
+ [SETTING.FLEET_AGENT_DEFAULT_POD_DISTRIBUTION_BUDGET]: { kind: 'json', agent: AGENT_CONFIGURATION_TYPES.FLEET },
195
196
  };
196
197
 
197
198
  /**
@@ -208,6 +209,7 @@ export const PROVISIONING_SETTINGS = [
208
209
  SETTING.CLUSTER_AGENT_DEFAULT_POD_DISTRIBUTION_BUDGET,
209
210
  SETTING.FLEET_AGENT_DEFAULT_PRIORITY_CLASS,
210
211
  SETTING.FLEET_AGENT_DEFAULT_POD_DISTRIBUTION_BUDGET,
212
+ SETTING.IMPORTED_CLUSTER_DAY2_OPS_DEFAULT
211
213
  ];
212
214
 
213
215
  /**
@@ -793,11 +793,10 @@ export const FLEET_SUMMARY = {
793
793
  export const FLEET_APPLICATION_TYPE = {
794
794
  name: 'applicationType',
795
795
  labelKey: 'fleet.tableHeaders.applicationType',
796
- value: 'kind',
797
- sort: 'kind',
796
+ value: 'applicationType',
797
+ sort: 'applicationType',
798
798
  search: false,
799
- align: 'center',
800
- width: 100,
799
+ width: 200,
801
800
  };
802
801
 
803
802
  export const FLEET_APPLICATION_SOURCE = {
package/config/types.js CHANGED
@@ -81,6 +81,7 @@ export const RBAC = {
81
81
  };
82
82
 
83
83
  export const WORKLOAD = 'workload';
84
+ export const WORKLOAD_DASHBOARD = 'workload-dashboard';
84
85
 
85
86
  /**
86
87
  * Rancher Workload types
@@ -218,6 +219,12 @@ export const LONGHORN_VERSION_V2 = 'LonghornV2';
218
219
 
219
220
  export const SNAPSHOT = 'rke.cattle.io.etcdsnapshot';
220
221
 
222
+ export const OPERATION = {
223
+ ETCD_SNAPSHOT: 'operation.cattle.io.etcdsnapshotsave',
224
+ ETCD_SNAPSHOT_RESTORE: 'operation.cattle.io.etcdsnapshotrestore',
225
+ ENCRYPTION_KEY_ROTATE: 'operation.cattle.io.encryptionkeyrotation',
226
+ };
227
+
221
228
  // --------------------------------------
222
229
  // 2. Only if Rancher is installed
223
230
  // --------------------------------------
@@ -279,6 +286,7 @@ export const CAPI = {
279
286
  MACHINE: 'cluster.x-k8s.io.machine',
280
287
  RANCHER_CLUSTER: 'provisioning.cattle.io.cluster',
281
288
  MACHINE_CONFIG_GROUP: 'rke-machine-config.cattle.io',
289
+ CAPI_PROVIDER: 'turtles-capi.cattle.io.capiprovider'
282
290
  };
283
291
 
284
292
  // --------------------------------------
@@ -295,6 +303,7 @@ export const FLEET = {
295
303
  DASHBOARD: 'fleet.cattle.io.dashboard',
296
304
  GIT_REPO: 'fleet.cattle.io.gitrepo',
297
305
  HELM_OP: 'fleet.cattle.io.helmop',
306
+ SUSE_APP_COLLECTION: 'suse-application-collection',
298
307
  WORKSPACE: 'management.cattle.io.fleetworkspace',
299
308
  TOKEN: 'fleet.cattle.io.clusterregistrationtoken',
300
309
  BUNDLE_NAMESPACE_MAPPING: 'fleet.cattle.io.bundlenamespacemapping',
@@ -397,6 +406,7 @@ export const AUTH_TYPE = {
397
406
  _S3: '_S3',
398
407
  _RKE: '_RKE',
399
408
  _IMAGE_PULL_SECRET: '_IPS',
409
+ _GITHUB_APP: '_GITHUB_APP',
400
410
  };
401
411
 
402
412
  export const LOCAL_CLUSTER = 'local';
@@ -420,6 +430,12 @@ export const CLUSTER_REPO_APPCO_AUTH_GENERATE_NAME = 'clusterrepo-appco-auth-';
420
430
  */
421
431
  export const CLUSTER_REPO_AUTH_GENERATE_NAME = 'clusterrepo-auth-';
422
432
 
433
+ /**
434
+ * The `generateName` prefix used when creating Helm Op authentication secrets
435
+ * for standard Helm sources.
436
+ */
437
+ export const AUTH_GENERATE_NAME = 'auth-';
438
+
423
439
  export const ZERO_TIME = '0001-01-01T00:00:00Z';
424
440
 
425
441
  export const DEFAULT_GRAFANA_STORAGE_SIZE = '10Gi';
@@ -1,7 +1,7 @@
1
1
  import { IExtension } from '@shell/core/types';
2
2
  import {
3
3
  ProductChild, ProductMetadata,
4
- ConfigureTypeConfiguration, VirtualTypeConfiguration,
4
+ ResourcePageConfiguration, CustomPageConfiguration,
5
5
  ProductChildCustomPage, VueRouteComponent,
6
6
  OverviewPageRoutingMetadata
7
7
  } from '@shell/core/plugin-types';
@@ -343,7 +343,7 @@ export abstract class BasePluginProduct {
343
343
  this.registeredPageNames.add(finalName);
344
344
  this.pageIdMap.set(item.name, finalName);
345
345
 
346
- const virtualTypeConfig: VirtualTypeConfiguration = {
346
+ const virtualTypeConfig: CustomPageConfiguration = {
347
347
  label: item.label,
348
348
  labelKey: item.labelKey,
349
349
  namespaced: false,
@@ -377,7 +377,7 @@ export abstract class BasePluginProduct {
377
377
 
378
378
  const route = pluginProductsHelpers.generateConfigureTypeRoute(parentName, item, { extendProduct: !this.isNewProduct });
379
379
 
380
- const configureTypeConfig: ConfigureTypeConfiguration = {
380
+ const configureTypeConfig: ResourcePageConfiguration = {
381
381
  isCreatable: true,
382
382
  isEditable: true,
383
383
  isRemovable: true,