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

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 (258) hide show
  1. package/assets/styles/global/_layout.scss +4 -0
  2. package/assets/translations/en-us.yaml +144 -41
  3. package/assets/translations/zh-hans.yaml +1 -7
  4. package/chart/monitoring/ClusterSelector.vue +0 -21
  5. package/chart/monitoring/prometheus/index.vue +6 -3
  6. package/components/CruResource.vue +161 -14
  7. package/components/ExplorerMembers.vue +8 -4
  8. package/components/ExplorerProjectsNamespaces.vue +10 -6
  9. package/components/GrowlManager.vue +4 -0
  10. package/components/MgmtNodeList.vue +184 -0
  11. package/components/Resource/Detail/Card/StateCard/__tests__/composables.test.ts +90 -1
  12. package/components/Resource/Detail/Card/StateCard/composables.ts +57 -87
  13. package/components/Resource/Detail/Card/StatusCard/__tests__/StatusCard.test.ts +61 -0
  14. package/components/Resource/Detail/Card/StatusCard/index.vue +61 -15
  15. package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +2 -0
  16. package/components/Resource/Detail/Metadata/KeyValue.vue +5 -2
  17. package/components/Resource/Detail/Metadata/KeyValueRow.vue +2 -6
  18. package/components/ResourceDetail/index.vue +1 -1
  19. package/components/ResourceList/Masthead.vue +7 -1
  20. package/components/ResourceList/index.vue +82 -1
  21. package/components/RichTranslation.vue +5 -2
  22. package/components/Setting.vue +1 -0
  23. package/components/SubtleLink.vue +31 -6
  24. package/components/Tabbed/Tab.vue +29 -3
  25. package/components/Tabbed/index.vue +25 -3
  26. package/components/TableOfContents/TableOfContents.vue +109 -0
  27. package/components/TableOfContents/composables.ts +258 -0
  28. package/components/Window/ContainerShell.vue +21 -11
  29. package/components/Window/__tests__/ContainerShell.test.ts +107 -37
  30. package/components/Wizard.vue +9 -4
  31. package/components/fleet/AppCoChartGrid.vue +401 -0
  32. package/components/fleet/AppCoEmptyState.vue +127 -0
  33. package/components/fleet/AppCoPageHeader.vue +119 -0
  34. package/components/fleet/AppCoVersionSelect.vue +70 -0
  35. package/components/fleet/FleetClusterTargets/ClusterSelectionFields.vue +217 -0
  36. package/components/fleet/FleetClusterTargets/TargetsList.vue +123 -35
  37. package/components/fleet/FleetClusterTargets/index.vue +189 -146
  38. package/components/fleet/FleetIntro.vue +7 -3
  39. package/components/fleet/FleetNoWorkspaces.vue +7 -3
  40. package/components/fleet/FleetSecretSelector.vue +5 -3
  41. package/components/fleet/FleetValuesFrom.vue +8 -2
  42. package/components/fleet/GitRepoTargetTab.vue +0 -2
  43. package/components/fleet/HelmOpAdvancedTab.vue +19 -53
  44. package/components/fleet/HelmOpAppCoConfigTab.vue +593 -0
  45. package/components/fleet/HelmOpAppCoResourcesSection.vue +162 -0
  46. package/components/fleet/HelmOpResourcesSection.vue +82 -0
  47. package/components/fleet/HelmOpTargetOptionsSection.vue +89 -0
  48. package/components/fleet/HelmOpTargetTab.vue +64 -60
  49. package/components/fleet/HelmOpValuesTab.vue +129 -105
  50. package/components/fleet/__tests__/AppCoEmptyState.test.ts +71 -0
  51. package/components/fleet/__tests__/AppCoVersionSelect.test.ts +36 -0
  52. package/components/fleet/__tests__/ClusterSelectionFields.test.ts +62 -0
  53. package/components/fleet/__tests__/FleetClusterTargets.test.ts +253 -0
  54. package/components/fleet/__tests__/FleetSecretSelector.test.ts +16 -0
  55. package/components/fleet/__tests__/FleetValuesFrom.test.ts +44 -0
  56. package/components/fleet/__tests__/HelmOpAppCoConfigTab.test.ts +59 -0
  57. package/components/fleet/__tests__/HelmOpAppCoResourcesSection.test.ts +62 -0
  58. package/components/fleet/__tests__/HelmOpResourcesSection.test.ts +43 -0
  59. package/components/fleet/__tests__/HelmOpTargetOptionsSection.test.ts +34 -0
  60. package/components/fleet/__tests__/HelmOpValuesTab.test.ts +39 -0
  61. package/components/fleet/__tests__/__snapshots__/AppCoEmptyState.test.ts.snap +97 -0
  62. package/components/fleet/__tests__/__snapshots__/AppCoVersionSelect.test.ts.snap +30 -0
  63. package/components/fleet/__tests__/__snapshots__/ClusterSelectionFields.test.ts.snap +209 -0
  64. package/components/fleet/__tests__/__snapshots__/HelmOpTargetOptionsSection.test.ts.snap +140 -0
  65. package/components/fleet/dashboard/Empty.vue +8 -4
  66. package/components/fleet/dashboard/ResourceCard.vue +28 -0
  67. package/components/fleet/dashboard/ResourceDetails.vue +28 -0
  68. package/components/fleet/dashboard/__tests__/ResourceCard.test.ts +87 -0
  69. package/components/form/ArrayList.vue +61 -4
  70. package/components/form/KeyValue.vue +23 -2
  71. package/components/form/LabeledSelect.vue +39 -1
  72. package/components/form/Labels.vue +22 -3
  73. package/components/form/NameNsDescription.vue +13 -5
  74. package/components/form/ResourceTabs/index.vue +1 -0
  75. package/components/form/__tests__/NameNsDescription.test.ts +75 -0
  76. package/components/formatter/InternalExternalIP.vue +10 -4
  77. package/components/formatter/ServiceTargets.vue +26 -7
  78. package/components/formatter/__tests__/InternalExternalIP.test.ts +132 -0
  79. package/components/formatter/__tests__/ServiceTargets.test.ts +412 -0
  80. package/components/nav/Header.vue +4 -0
  81. package/components/nav/TopLevelMenu.vue +7 -2
  82. package/components/nav/__tests__/Header.test.ts +15 -0
  83. package/components/nav/__tests__/TopLevelMenu.test.ts +120 -2
  84. package/components/templates/default.vue +9 -4
  85. package/components/templates/home.vue +9 -4
  86. package/components/templates/plain.vue +9 -4
  87. package/composables/useHelmOpResources.test.ts +56 -0
  88. package/composables/useHelmOpResources.ts +32 -0
  89. package/composables/useStateColor.test.ts +325 -0
  90. package/composables/useStateColor.ts +128 -0
  91. package/config/home-links.js +1 -1
  92. package/config/labels-annotations.js +1 -0
  93. package/config/product/explorer.js +17 -4
  94. package/config/product/manager.js +2 -0
  95. package/config/router/index.js +16 -0
  96. package/config/router/navigation-guards/__tests__/authentication.test.ts +130 -0
  97. package/config/router/navigation-guards/authentication.js +10 -4
  98. package/config/router/routes.js +20 -6
  99. package/config/settings.ts +0 -2
  100. package/config/table-headers.js +3 -4
  101. package/config/types.js +9 -0
  102. package/core/plugin-products-base.ts +3 -3
  103. package/core/plugin-types.ts +83 -30
  104. package/core/plugin.ts +3 -0
  105. package/core/types-provisioning.ts +34 -1
  106. package/core/types.ts +15 -2
  107. package/detail/__tests__/provisioning.cattle.io.cluster.test.ts +114 -0
  108. package/detail/__tests__/workload.test.ts +3 -152
  109. package/detail/catalog.cattle.io.clusterrepo.vue +1 -1
  110. package/detail/provisioning.cattle.io.cluster.vue +30 -4
  111. package/detail/workload/index.vue +12 -55
  112. package/edit/__tests__/catalog.cattle.io.clusterrepo.test.ts +248 -0
  113. package/edit/__tests__/fleet.cattle.io.helmop.test.ts +105 -0
  114. package/edit/auditlog.cattle.io.auditpolicy/__tests__/__snapshots__/General.test.ts.snap +6 -0
  115. package/edit/auditlog.cattle.io.auditpolicy/__tests__/__snapshots__/index.test.ts.snap +1 -0
  116. package/edit/auth/__tests__/azuread.test.ts +34 -9
  117. package/edit/auth/__tests__/github.test.ts +234 -0
  118. package/edit/auth/__tests__/oidc.test.ts +26 -6
  119. package/edit/auth/__tests__/saml.test.ts +196 -0
  120. package/edit/auth/azuread.vue +128 -95
  121. package/edit/auth/github.vue +72 -13
  122. package/edit/auth/ldap/__tests__/index.test.ts +206 -0
  123. package/edit/auth/ldap/config.vue +8 -0
  124. package/edit/auth/ldap/index.vue +75 -1
  125. package/edit/auth/oidc.vue +119 -73
  126. package/edit/auth/saml.vue +76 -12
  127. package/edit/catalog.cattle.io.clusterrepo.vue +140 -32
  128. package/edit/fleet.cattle.io.helmop.vue +491 -136
  129. package/edit/management.cattle.io.user.vue +5 -2
  130. package/edit/provisioning.cattle.io.cluster/rke2.vue +84 -10
  131. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +11 -0
  132. package/list/group.principal.vue +5 -4
  133. package/list/harvesterhci.io.management.cluster.vue +8 -9
  134. package/list/management.cattle.io.user.vue +12 -9
  135. package/list/provisioning.cattle.io.cluster.vue +16 -10
  136. package/mixins/__tests__/auth-config.test.ts +90 -0
  137. package/mixins/__tests__/chart.test.ts +94 -0
  138. package/mixins/__tests__/resource-fetch-api-pagination.test.ts +48 -0
  139. package/mixins/auth-config.js +7 -0
  140. package/mixins/chart.js +11 -2
  141. package/mixins/child-hook.js +12 -6
  142. package/mixins/create-edit-view/impl.js +5 -3
  143. package/mixins/resource-fetch-api-pagination.js +21 -1
  144. package/models/__tests__/catalog.cattle.io.clusterrepo.test.ts +57 -0
  145. package/models/__tests__/compliance.cattle.io.clusterscan.test.ts +144 -0
  146. package/models/__tests__/fleet-application.test.ts +175 -0
  147. package/models/__tests__/fleet.cattle.io.bundle.test.ts +169 -0
  148. package/models/__tests__/fleet.cattle.io.helmop.test.ts +84 -0
  149. package/models/__tests__/management.cattle.io.node.ts +22 -0
  150. package/models/__tests__/namespace.test.ts +36 -0
  151. package/models/__tests__/provisioning.cattle.io.cluster.test.ts +49 -0
  152. package/models/__tests__/workload.test.ts +401 -26
  153. package/models/catalog.cattle.io.clusterrepo.js +28 -4
  154. package/models/compliance.cattle.io.clusterscan.js +39 -4
  155. package/models/fleet-application.js +4 -0
  156. package/models/fleet.cattle.io.helmop.js +20 -1
  157. package/models/management.cattle.io.cluster.js +18 -2
  158. package/models/management.cattle.io.node.js +44 -3
  159. package/models/namespace.js +1 -1
  160. package/models/pod.js +33 -1
  161. package/models/provisioning.cattle.io.cluster.js +5 -5
  162. package/models/workload.js +108 -13
  163. package/models/workload.service.js +5 -0
  164. package/package.json +14 -13
  165. package/pages/about.vue +5 -6
  166. package/pages/auth/login.vue +0 -35
  167. package/pages/auth/setup.vue +11 -0
  168. package/pages/c/_cluster/apps/charts/AppChartCardFooter.vue +2 -2
  169. package/pages/c/_cluster/apps/charts/AppChartCardSubHeader.vue +10 -1
  170. package/pages/c/_cluster/apps/charts/__tests__/index.test.ts +93 -0
  171. package/pages/c/_cluster/apps/charts/chart.vue +2 -1
  172. package/pages/c/_cluster/apps/charts/index.vue +48 -10
  173. package/pages/c/_cluster/apps/charts/install.vue +122 -116
  174. package/pages/c/_cluster/auth/roles/index.vue +5 -4
  175. package/pages/c/_cluster/explorer/workload-dashboard/ByNamespaceSection.vue +31 -0
  176. package/pages/c/_cluster/explorer/workload-dashboard/ByStateSection.vue +138 -0
  177. package/pages/c/_cluster/explorer/workload-dashboard/ByTypeSection.vue +30 -0
  178. package/pages/c/_cluster/explorer/workload-dashboard/WorkloadCard.vue +155 -0
  179. package/pages/c/_cluster/explorer/workload-dashboard/WorkloadNamespaceCard.vue +142 -0
  180. package/pages/c/_cluster/explorer/workload-dashboard/WorkloadTypeCard.vue +159 -0
  181. package/pages/c/_cluster/explorer/workload-dashboard/__tests__/composable.test.ts +561 -0
  182. package/pages/c/_cluster/explorer/workload-dashboard/composable.ts +440 -0
  183. package/pages/c/_cluster/explorer/workload-dashboard/index.vue +187 -0
  184. package/pages/c/_cluster/explorer/workload-dashboard/types.ts +80 -0
  185. package/pages/c/_cluster/fleet/application/create.vue +187 -136
  186. package/pages/c/_cluster/fleet/application/index.vue +5 -3
  187. package/pages/c/_cluster/fleet/application/suse-app-collection/ChartDetailBody.vue +338 -0
  188. package/pages/c/_cluster/fleet/application/suse-app-collection/ChartDetailHeader.vue +121 -0
  189. package/pages/c/_cluster/fleet/application/suse-app-collection/chart.vue +369 -0
  190. package/pages/c/_cluster/fleet/application/suse-app-collection/charts.vue +248 -0
  191. package/pages/c/_cluster/fleet/application/suse-app-collection/credentials.vue +310 -0
  192. package/pages/c/_cluster/fleet/index.vue +2 -2
  193. package/pages/c/_cluster/uiplugins/__tests__/index.test.ts +96 -0
  194. package/pages/c/_cluster/uiplugins/index.vue +15 -0
  195. package/pages/fail-whale.vue +16 -11
  196. package/pages/home.vue +16 -46
  197. package/plugins/clean-html.d.ts +9 -0
  198. package/plugins/dashboard-store/__tests__/resource-class.test.ts +93 -0
  199. package/plugins/dashboard-store/resource-class.js +62 -7
  200. package/plugins/steve/__tests__/actions.test.ts +212 -0
  201. package/plugins/steve/actions.js +96 -0
  202. package/plugins/steve/steve-pagination-utils.ts +1 -1
  203. package/rancher-components/Accordion/Accordion.vue +53 -9
  204. package/rancher-components/Form/Checkbox/Checkbox.vue +14 -0
  205. package/rancher-components/Form/Radio/RadioButton.vue +17 -1
  206. package/rancher-components/Form/Radio/RadioGroup.vue +10 -0
  207. package/rancher-components/Pill/RcTag/RcTag.vue +3 -2
  208. package/rancher-components/RcButton/RcButton.test.ts +103 -0
  209. package/rancher-components/RcButton/RcButton.vue +94 -15
  210. package/rancher-components/RcButton/types.ts +3 -0
  211. package/rancher-components/RcItemCard/RcItemCard.test.ts +18 -0
  212. package/rancher-components/RcItemCard/RcItemCard.vue +2 -2
  213. package/rancher-components/RcSection/RcSection.vue +28 -3
  214. package/scripts/extension/helm/package/Dockerfile +1 -1
  215. package/scripts/test-plugins-build.sh +2 -1
  216. package/store/__tests__/notifications.test.ts +434 -0
  217. package/store/catalog.js +57 -0
  218. package/store/plugins.js +7 -4
  219. package/types/components/buttonGroup.ts +5 -0
  220. package/types/shell/index.d.ts +104 -70
  221. package/utils/__tests__/auth.test.ts +273 -0
  222. package/utils/__tests__/computed.test.ts +193 -0
  223. package/utils/__tests__/cspAdaptor.test.ts +163 -0
  224. package/utils/__tests__/dom.test.ts +81 -0
  225. package/utils/__tests__/duration.test.ts +37 -1
  226. package/utils/__tests__/dynamic-importer.test.ts +102 -0
  227. package/utils/__tests__/fleet-appco.test.ts +312 -0
  228. package/utils/__tests__/monitoring.test.ts +130 -0
  229. package/utils/__tests__/object.test.ts +22 -0
  230. package/utils/__tests__/platform.test.ts +91 -0
  231. package/utils/__tests__/position.test.ts +237 -0
  232. package/utils/__tests__/provider.test.ts +51 -1
  233. package/utils/__tests__/queue.test.ts +232 -0
  234. package/utils/__tests__/release-notes.test.ts +221 -0
  235. package/utils/__tests__/router.test.js +254 -1
  236. package/utils/__tests__/select.test.ts +208 -0
  237. package/utils/__tests__/time.test.ts +265 -1
  238. package/utils/__tests__/title.test.ts +47 -0
  239. package/utils/__tests__/width.test.ts +53 -0
  240. package/utils/__tests__/window.test.ts +158 -0
  241. package/utils/__tests__/xccdf.test.ts +126 -6
  242. package/utils/crypto/__tests__/browserHashUtils.test.ts +98 -0
  243. package/utils/crypto/__tests__/index.test.ts +144 -0
  244. package/utils/duration.ts +104 -0
  245. package/utils/dynamic-content/__tests__/notification-handler.test.ts +196 -0
  246. package/utils/dynamic-content/info.ts +2 -1
  247. package/utils/error.js +13 -0
  248. package/utils/fleet-appco.ts +323 -0
  249. package/utils/object.js +22 -2
  250. package/utils/provider.ts +12 -0
  251. package/utils/validators/__tests__/container-images.test.ts +104 -0
  252. package/utils/validators/__tests__/flow-output.test.ts +91 -0
  253. package/utils/validators/__tests__/logging-outputs.test.ts +58 -0
  254. package/utils/validators/__tests__/monitoring-route.test.ts +119 -0
  255. package/utils/xccdf.ts +39 -42
  256. package/vue.config.js +1 -1
  257. package/pages/support/index.vue +0 -264
  258. package/utils/duration.js +0 -43
@@ -0,0 +1,119 @@
1
+ import { matching, interval } from '@shell/utils/validators/monitoring-route';
2
+
3
+ const mockGetters = {
4
+ 'i18n/t': (key: string, args?: object) => (args ? `${ key }:${ JSON.stringify(args) }` : key),
5
+ 'i18n/exists': () => false,
6
+ };
7
+
8
+ describe('validators/monitoring-route', () => {
9
+ describe('matching', () => {
10
+ it('adds error when both match and match_re are empty', () => {
11
+ const errors: string[] = [];
12
+
13
+ matching({ match: {}, match_re: {} }, mockGetters, errors, []);
14
+
15
+ expect(errors).toStrictEqual(['validation.monitoring.route.match']);
16
+ });
17
+
18
+ it('adds error when spec is empty object', () => {
19
+ const errors: string[] = [];
20
+
21
+ matching({}, mockGetters, errors, []);
22
+
23
+ expect(errors).toStrictEqual(['validation.monitoring.route.match']);
24
+ });
25
+
26
+ it('adds error when spec is null or undefined', () => {
27
+ const errors: string[] = [];
28
+
29
+ matching(null, mockGetters, errors, []);
30
+
31
+ expect(errors).toStrictEqual(['validation.monitoring.route.match']);
32
+ });
33
+
34
+ it('adds no error when match has entries', () => {
35
+ const errors: string[] = [];
36
+
37
+ matching({ match: { severity: 'critical' } }, mockGetters, errors, []);
38
+
39
+ expect(errors).toStrictEqual([]);
40
+ });
41
+
42
+ it('adds no error when match_re has entries', () => {
43
+ const errors: string[] = [];
44
+
45
+ matching({ match_re: { alertname: '.*' } }, mockGetters, errors, []);
46
+
47
+ expect(errors).toStrictEqual([]);
48
+ });
49
+
50
+ it('adds no error when both match and match_re have entries', () => {
51
+ const errors: string[] = [];
52
+
53
+ matching(
54
+ { match: { severity: 'warning' }, match_re: { alertname: '.*' } },
55
+ mockGetters,
56
+ errors,
57
+ []
58
+ );
59
+
60
+ expect(errors).toStrictEqual([]);
61
+ });
62
+ });
63
+
64
+ describe('interval', () => {
65
+ it.each([
66
+ {
67
+ desc: 'seconds unit',
68
+ value: '30s',
69
+ },
70
+ {
71
+ desc: 'minutes unit',
72
+ value: '5m',
73
+ },
74
+ {
75
+ desc: 'hours unit',
76
+ value: '2h',
77
+ },
78
+ {
79
+ desc: 'multi-digit seconds',
80
+ value: '120s',
81
+ },
82
+ ])('adds no error for valid interval: $desc', ({ value }) => {
83
+ const errors: string[] = [];
84
+
85
+ interval(value, mockGetters, errors, [], 'Interval');
86
+
87
+ expect(errors).toStrictEqual([]);
88
+ });
89
+
90
+ it.each([
91
+ {
92
+ desc: 'no unit',
93
+ value: '30',
94
+ },
95
+ {
96
+ desc: 'unknown unit',
97
+ value: '5d',
98
+ },
99
+ {
100
+ desc: 'empty string',
101
+ value: '',
102
+ },
103
+ {
104
+ desc: 'fractional value',
105
+ value: '1.5s',
106
+ },
107
+ {
108
+ desc: 'letters only',
109
+ value: 'abc',
110
+ },
111
+ ])('adds error for invalid interval: $desc', ({ value }) => {
112
+ const errors: string[] = [];
113
+
114
+ interval(value, mockGetters, errors, [], 'Interval');
115
+
116
+ expect(errors).toStrictEqual(['validation.monitoring.route.interval:{"key":"Interval"}']);
117
+ });
118
+ });
119
+ });
package/utils/xccdf.ts CHANGED
@@ -61,16 +61,17 @@ export interface BenchmarkMetadata {
61
61
  source?: string;
62
62
  }
63
63
 
64
- export interface StigCheckMetadata {
64
+ export interface CheckDecoration {
65
65
  ruleId?: string;
66
66
  version?: string;
67
67
  severity?: string;
68
68
  fixId?: string;
69
69
  checkId?: string;
70
- cci?: string[];
70
+ /** Generic XCCDF idents — STIG populates with CCIs, CIS with control IDs, etc. */
71
+ idents?: { system: string; value: string }[];
71
72
  }
72
73
 
73
- export type StigChecks = Record<string, StigCheckMetadata>;
74
+ export type CheckDecorations = Record<string, CheckDecoration>;
74
75
 
75
76
  export interface XccdfTargetFact {
76
77
  name: string;
@@ -82,7 +83,7 @@ export interface GenerateXccdfArgs {
82
83
  report: XccdfReport;
83
84
  benchmarkVersion: string;
84
85
  metadata?: BenchmarkMetadata;
85
- stigChecks?: StigChecks;
86
+ decorations?: CheckDecorations;
86
87
  targetAddresses?: string[];
87
88
  targetFacts?: XccdfTargetFact[];
88
89
  /** Override the cluster name used for the <target> element. Falls back to metadata.clusterName, then derived node names. */
@@ -101,32 +102,27 @@ const fixIdFor = (checkId: string): string => `${ ruleIdFor(checkId) }_fix`;
101
102
 
102
103
  const profileIdFor = (benchmarkVersion: string): string => `${ ID_PREFIX }_profile_${ safeId(benchmarkVersion) }`;
103
104
 
104
- const stigGroupId = (checkId: string): string => {
105
- const parts = checkId.split('-');
106
-
107
- if (parts.length >= 2) {
108
- return `${ parts[0] }-${ parts[1] }`;
105
+ const effectiveRuleId = (decoration: CheckDecoration, groupId: string, checkId: string, hitGroupKey: boolean): string => {
106
+ if (!decoration.ruleId) {
107
+ return ruleIdFor(checkId);
109
108
  }
109
+ if (!hitGroupKey) {
110
+ return decoration.ruleId;
111
+ }
112
+ const suffix = checkId.startsWith(`${ groupId }-`) ? checkId.slice(groupId.length + 1) : checkId;
110
113
 
111
- return checkId;
114
+ return `${ decoration.ruleId }_${ suffix }`;
112
115
  };
113
116
 
114
- const effectiveRuleId = (stig: StigCheckMetadata, checkId: string): string => {
115
- if (!stig.ruleId) {
116
- return ruleIdFor(checkId);
117
+ const lookupDecoration = (decorations: CheckDecorations, groupId: string, checkId: string): { decoration: CheckDecoration; hitGroupKey: boolean } => {
118
+ if (decorations[checkId]) {
119
+ return { decoration: decorations[checkId], hitGroupKey: false };
117
120
  }
118
- const gid = stigGroupId(checkId);
119
-
120
- if (checkId === gid) {
121
- return stig.ruleId;
121
+ if (decorations[groupId]) {
122
+ return { decoration: decorations[groupId], hitGroupKey: true };
122
123
  }
123
- const suffix = checkId.startsWith(`${ gid }-`) ? checkId.slice(gid.length + 1) : checkId;
124
-
125
- return `${ stig.ruleId }_${ suffix }`;
126
- };
127
124
 
128
- const lookupStig = (stigChecks: StigChecks, checkId: string): StigCheckMetadata => {
129
- return stigChecks[stigGroupId(checkId)] || {};
125
+ return { decoration: {}, hitGroupKey: false };
130
126
  };
131
127
 
132
128
  const mapResult = (state?: string): string => {
@@ -142,18 +138,18 @@ const mapResult = (state?: string): string => {
142
138
 
143
139
  const severityFor = (scored?: boolean): string => (scored ? 'medium' : 'low');
144
140
 
145
- const stigSeverity = (stigSev: string | undefined, scored?: boolean): string => stigSev || severityFor(scored);
141
+ const decorationSeverity = (sev: string | undefined, scored?: boolean): string => sev || severityFor(scored);
146
142
 
147
143
  const ruleWeight = (scored?: boolean): string => (scored ? '10' : '0');
148
144
 
149
145
  const ruleRole = (scored?: boolean): string => (scored ? 'full' : 'unscored');
150
146
 
151
- const stigIdents = (ccis?: string[]): { system: string; value: string }[] => {
152
- if (!ccis || ccis.length === 0) {
147
+ const decorationIdents = (idents?: { system: string; value: string }[]): { system: string; value: string }[] => {
148
+ if (!idents || idents.length === 0) {
153
149
  return [{ system: NA, value: NA }];
154
150
  }
155
151
 
156
- return ccis.map((cci) => ({ system: 'http://cyber.mil/cci', value: cci }));
152
+ return idents;
157
153
  };
158
154
 
159
155
  const collectTargets = (report: XccdfReport): string[] => {
@@ -187,7 +183,7 @@ export function generateXCCDF({
187
183
  report,
188
184
  benchmarkVersion,
189
185
  metadata = {},
190
- stigChecks = {},
186
+ decorations = {},
191
187
  targetAddresses,
192
188
  targetFacts,
193
189
  clusterName,
@@ -239,7 +235,7 @@ export function generateXCCDF({
239
235
  profile.ele('title').txt(benchmarkTitle);
240
236
  profile.ele('description').txt(na(metadata.description));
241
237
 
242
- const ruleResults: { check: XccdfReportCheck; effectiveId: string; stig: StigCheckMetadata }[] = [];
238
+ const ruleResults: { check: XccdfReportCheck; effectiveId: string; decoration: CheckDecoration }[] = [];
243
239
  const groups = report.results || [];
244
240
 
245
241
  groups.forEach((group) => {
@@ -250,10 +246,11 @@ export function generateXCCDF({
250
246
 
251
247
  (group.checks || []).forEach((check) => {
252
248
  const checkId = check.id || '';
253
- const stig = lookupStig(stigChecks, checkId);
254
- const effectiveId = effectiveRuleId(stig, checkId);
255
- const ruleFixId = stig.fixId || fixIdFor(checkId);
256
- const ruleCheckSystem = stig.checkId || CHECK_SYSTEM;
249
+ const groupId = group.id || '';
250
+ const { decoration, hitGroupKey } = lookupDecoration(decorations, groupId, checkId);
251
+ const effectiveId = effectiveRuleId(decoration, groupId, checkId, hitGroupKey);
252
+ const ruleFixId = decoration.fixId || fixIdFor(checkId);
253
+ const ruleCheckSystem = decoration.checkId || CHECK_SYSTEM;
257
254
  const checkHref = na(metadata.checkHref);
258
255
  const checkName = na(metadata.checkName);
259
256
 
@@ -262,10 +259,10 @@ export function generateXCCDF({
262
259
  selected: 'true',
263
260
  weight: ruleWeight(check.scored),
264
261
  role: ruleRole(check.scored),
265
- severity: stigSeverity(stig.severity, check.scored),
262
+ severity: decorationSeverity(decoration.severity, check.scored),
266
263
  });
267
264
 
268
- rule.ele('version').txt(na(stig.version));
265
+ rule.ele('version').txt(na(decoration.version));
269
266
  rule.ele('title').txt(na(`${ checkId } ${ check.description || '' }`));
270
267
  rule.ele('description').txt(na(check.description));
271
268
 
@@ -277,7 +274,7 @@ export function generateXCCDF({
277
274
  ruleRef.ele('type').txt(na(metadata.referenceType));
278
275
  ruleRef.ele('identifier').txt(na(metadata.referenceIdentifier));
279
276
 
280
- stigIdents(stig.cci).forEach((ident) => {
277
+ decorationIdents(decoration.idents).forEach((ident) => {
281
278
  rule.ele('ident', { system: ident.system }).txt(ident.value);
282
279
  });
283
280
 
@@ -290,7 +287,7 @@ export function generateXCCDF({
290
287
  ruleCheck.ele('check-content').txt(na(check.audit));
291
288
 
292
289
  ruleResults.push({
293
- check, effectiveId, stig
290
+ check, effectiveId, decoration
294
291
  });
295
292
  });
296
293
  });
@@ -348,8 +345,8 @@ export function generateXCCDF({
348
345
  rrCheck.ele('check-content-ref', { name: NA, href: NA });
349
346
  rrCheck.ele('check-content').txt(NA);
350
347
  } else {
351
- ruleResults.forEach(({ check, effectiveId, stig }) => {
352
- const ruleCheckSystem = stig.checkId || CHECK_SYSTEM;
348
+ ruleResults.forEach(({ check, effectiveId, decoration }) => {
349
+ const ruleCheckSystem = decoration.checkId || CHECK_SYSTEM;
353
350
  const checkHref = na(metadata.checkHref);
354
351
  const checkName = na(metadata.checkName);
355
352
 
@@ -357,12 +354,12 @@ export function generateXCCDF({
357
354
  idref: effectiveId,
358
355
  role: ruleRole(check.scored),
359
356
  time: timeStr,
360
- severity: stigSeverity(stig.severity, check.scored),
361
- version: na(stig.version),
357
+ severity: decorationSeverity(decoration.severity, check.scored),
358
+ version: na(decoration.version),
362
359
  weight: ruleWeight(check.scored),
363
360
  });
364
361
 
365
- stigIdents(stig.cci).forEach((ident) => {
362
+ decorationIdents(decoration.idents).forEach((ident) => {
366
363
  rr.ele('ident', { system: ident.system }).txt(ident.value);
367
364
  });
368
365
  rr.ele('result').txt(mapResult(check.state));
package/vue.config.js CHANGED
@@ -520,7 +520,7 @@ module.exports = function(dir, appConfig = {}) {
520
520
  @import "~shell/assets/styles/base/_variables.scss";
521
521
  @import "~shell/assets/styles/base/_functions.scss";
522
522
  @import "~shell/assets/styles/base/_mixins.scss";
523
- @import 'node_modules/xterm/css/xterm.css';
523
+ @import 'node_modules/@xterm/xterm/css/xterm.css';
524
524
  `
525
525
  }
526
526
  }
@@ -1,264 +0,0 @@
1
- <script>
2
- import BannerGraphic from '@shell/components/BannerGraphic';
3
- import IndentedPanel from '@shell/components/IndentedPanel';
4
- import CommunityLinks from '@shell/components/CommunityLinks';
5
- import { MANAGEMENT } from '@shell/config/types';
6
- import { getVendor } from '@shell/config/private-label';
7
- import { SETTING } from '@shell/config/settings';
8
- import { addParam } from '@shell/utils/url';
9
- import { isRancherPrime } from '@shell/config/version';
10
- import TabTitle from '@shell/components/TabTitle';
11
- import CspAdapterUtils from '@shell/utils/cspAdaptor';
12
-
13
- export default {
14
-
15
- components: {
16
- BannerGraphic,
17
- IndentedPanel,
18
- CommunityLinks,
19
- TabTitle
20
- },
21
-
22
- async fetch() {
23
- const fetchOrCreateSetting = async(id, val) => {
24
- let setting;
25
-
26
- try {
27
- setting = await this.$store.dispatch('management/find', { type: MANAGEMENT.SETTING, id });
28
- } catch {
29
- const schema = this.$store.getters['management/schemaFor'](MANAGEMENT.SETTING);
30
- const url = schema.linkFor('collection');
31
-
32
- setting = await this.$store.dispatch('management/create', {
33
- type: MANAGEMENT.SETTING,
34
- metadata: { name: id },
35
- value: val,
36
- default: val || ''
37
- });
38
-
39
- setting.save({ url });
40
- }
41
-
42
- return setting;
43
- };
44
-
45
- this.apps = await CspAdapterUtils.fetchCspAdaptorApp(this.$store);
46
- this.brandSetting = await fetchOrCreateSetting(SETTING.BRAND, '');
47
- this.serverUrlSetting = await fetchOrCreateSetting(SETTING.SERVER_URL, '');
48
- this.uiIssuesSetting = await this.$store.dispatch('management/find', { type: MANAGEMENT.SETTING, id: SETTING.ISSUES });
49
- this.settings = await this.$store.dispatch('management/findAll', { type: MANAGEMENT.SETTING });
50
- },
51
-
52
- data() {
53
- return {
54
- apps: [],
55
- vendor: getVendor(),
56
- supportKey: '',
57
- brandSetting: null,
58
- uiIssuesSetting: null,
59
- serverSetting: null,
60
- settings: null,
61
- // i18n-uses support.promos.one.*
62
- // i18n-uses support.promos.two.*
63
- // i18n-uses support.promos.three.*
64
- // i18n-uses support.promos.four.*
65
- promos: [
66
- 'support.promos.one',
67
- 'support.promos.two',
68
- 'support.promos.three',
69
- 'support.promos.four',
70
- ]
71
- };
72
- },
73
-
74
- computed: {
75
- cspAdapter() {
76
- return CspAdapterUtils.hasCspAdapter({ $store: this.$store, apps: this.apps });
77
- },
78
-
79
- hasSupport() {
80
- return this.hasAWSSupport || isRancherPrime();
81
- },
82
-
83
- hasAWSSupport() {
84
- return !!this.cspAdapter;
85
- },
86
-
87
- serverUrl() {
88
- // Client-side rendered: use the current window location
89
- return window.location.origin;
90
- },
91
-
92
- supportConfigLink() {
93
- const adapter = this.cspAdapter;
94
-
95
- if (!adapter) {
96
- return false;
97
- }
98
-
99
- if (adapter.metadata.name === 'rancher-csp-billing-adapter') {
100
- return `${ this.serverUrl }/v1/generateSUSERancherSupportConfig?usePAYG=true`;
101
- } else {
102
- return `${ this.serverUrl }/v1/generateSUSERancherSupportConfig`;
103
- }
104
- },
105
-
106
- title() {
107
- return this.hasSupport ? 'support.suse.title' : 'support.community.title';
108
- },
109
-
110
- sccLink() {
111
- return this.hasAWSSupport ? addParam('https://scc.suse.com', 'from_marketplace', '1') : 'https://scc.suse.com';
112
- }
113
- },
114
-
115
- };
116
- </script>
117
- <template>
118
- <div>
119
- <BannerGraphic
120
- :title="t(title, {}, true)"
121
- :alt="t('support.bannerImage')"
122
- />
123
-
124
- <IndentedPanel>
125
- <div class="content mt-20">
126
- <div class="promo col main-panel">
127
- <div class="box mb-20 box-primary">
128
- <h2>
129
- <TabTitle breadcrumb="vendor-only">
130
- {{ t('support.suse.access.title') }}
131
- </TabTitle>
132
- </h2>
133
- <div
134
- v-if="!hasSupport"
135
- class="external support-links mt-20"
136
- >
137
- <div class="support-link">
138
- <a
139
- class="support-link"
140
- href="https://www.rancher.com/support"
141
- target="_blank"
142
- rel="noopener noreferrer nofollow"
143
- >{{ t('support.community.learnMore') }}</a>
144
- </div>
145
- <div class="support-link">
146
- <a
147
- class="support-link"
148
- href="https://rancher.com/pricing"
149
- target="_blank"
150
- rel="noopener noreferrer nofollow"
151
- >{{ t('support.community.pricing') }}</a>
152
- </div>
153
- </div>
154
- <div v-else>
155
- <p class="pb-10">
156
- {{ hasAWSSupport ? t("support.suse.access.aws.text") : t("support.suse.access.text") }}
157
- </p>
158
- <a
159
- v-if="hasAWSSupport"
160
- class="mr-5 btn role-secondary btn-sm"
161
- :href="supportConfigLink"
162
- >
163
- {{ t('support.suse.access.aws.generateConfig') }}
164
- </a>
165
- <a
166
- :href="sccLink"
167
- target="_blank"
168
- rel="noopener noreferrer nofollow"
169
- >
170
- {{ t('support.suse.access.action') }} <i class="icon icon-external-link" />
171
- </a>
172
- </div>
173
- </div>
174
- <div class="boxes">
175
- <div
176
- v-for="(key, i) in promos"
177
- :key="i"
178
- class="box"
179
- >
180
- <h2>{{ t(`${key}.title`) }}</h2>
181
- <div>{{ t(`${key}.text`) }}</div>
182
- </div>
183
- </div>
184
- </div>
185
- <CommunityLinks
186
- :is-support-page="true"
187
- class="community col side-panel span-3"
188
- />
189
- </div>
190
- </IndentedPanel>
191
- </div>
192
- </template>
193
- <style lang="scss" scoped>
194
- .content {
195
-
196
- display: flex;
197
- align-items: stretch;
198
- .col {
199
- margin: 0
200
- }
201
- .main-panel {
202
- flex: auto;
203
- }
204
-
205
- .side-panel {
206
- margin-left: 1.75%;
207
- }
208
- }
209
-
210
- .toggle-support {
211
- height: 100%;
212
-
213
- &.card-container {
214
- box-shadow: none;
215
- }
216
-
217
- &:deep() .card-actions {
218
- display: flex;
219
- justify-content: space-between;
220
- }
221
- }
222
-
223
- .support-link:not(:first-child) {
224
- margin: 15px 0 0 0;
225
- }
226
-
227
- .register {
228
- display: flex;
229
- align-items: center;
230
- margin-top: 20px;
231
- font-size: 16px;
232
- }
233
- .remove-link {
234
- cursor: pointer;
235
- font-size: 14px;
236
- }
237
- .boxes {
238
- display: grid;
239
- grid-column-gap: 20px;
240
- grid-row-gap: 20px;
241
- grid-template-columns: 50% 50%;
242
- margin-right: 20px;
243
- }
244
-
245
- .box {
246
- padding: 20px;
247
- border: 1px solid var(--border);
248
-
249
- &.box-primary {
250
- border-color: var(--primary);
251
- }
252
-
253
- > h2 {
254
- font-size: 20px;
255
- font-weight: 300;
256
- }
257
-
258
- > div {
259
- font-weight: 300;
260
- line-height: 18px;
261
- opacity: 0.8;
262
- }
263
- }
264
- </style>
package/utils/duration.js DELETED
@@ -1,43 +0,0 @@
1
- const UNIT_TO_MS =
2
- {
3
- ms: 1,
4
- s: 1000,
5
- m: 60 * 1000,
6
- h: 60 * 60 * 1000,
7
- d: 24 * 60 * 60 * 1000,
8
- w: 7 * 24 * 60 * 60 * 1000,
9
- y: 365 * 24 * 60 * 60 * 1000
10
- };
11
-
12
- const DURATION_REGEX = /^(?:([0-9]+)y)?(?:([0-9]+)w)?(?:([0-9]+)d)?(?:([0-9]+)h)?(?:([0-9]+)m)?(?:([0-9]+)s)?(?:([0-9]+)ms)?$/;
13
-
14
- export function toMilliseconds(input) {
15
- if (!input) {
16
- return 0;
17
- }
18
- const d = `${ input }`.match(DURATION_REGEX);
19
-
20
- if (d) {
21
- const properties = d.slice(1);
22
- const numberD = properties.map((value) => ([null, undefined].includes(value) ? 0 : Number(value)));
23
- const data = {};
24
-
25
- [
26
- data.y,
27
- data.w,
28
- data.d,
29
- data.h,
30
- data.m,
31
- data.s,
32
- data.ms
33
- ] = numberD;
34
-
35
- return Object.keys(data).reduce((total, unit) => (total + ((data[unit] || 0) * UNIT_TO_MS[unit])), 0);
36
- }
37
-
38
- return 0;
39
- }
40
-
41
- export function toSeconds(input) {
42
- return Math.floor(toMilliseconds(input) / 1000);
43
- }