foreman_openscap 8.0.2 → 9.0.1

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 (159) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +0 -1
  3. data/app/services/foreman_openscap/client_config/ansible.rb +1 -10
  4. data/config/initializers/inflections.rb +0 -2
  5. data/config/routes.rb +0 -15
  6. data/db/migrate/20240313111822_drop_oval.rb +17 -0
  7. data/db/migrate/20240617105409_remove_oval_permissions.rb +24 -0
  8. data/lib/foreman_openscap/engine.rb +2 -56
  9. data/lib/foreman_openscap/version.rb +1 -1
  10. data/test/factories/compliance_host_factory.rb +0 -12
  11. data/test/test_plugin_helper.rb +0 -2
  12. data/webpack/global_index.js +0 -4
  13. metadata +8 -168
  14. data/app/controllers/api/v2/compliance/oval_contents_controller.rb +0 -72
  15. data/app/controllers/api/v2/compliance/oval_policies_controller.rb +0 -111
  16. data/app/controllers/api/v2/compliance/oval_reports_controller.rb +0 -47
  17. data/app/controllers/concerns/foreman/controller/parameters/oval_content.rb +0 -22
  18. data/app/controllers/concerns/foreman/controller/parameters/oval_policy.rb +0 -22
  19. data/app/graphql/mutations/oval_contents/delete.rb +0 -9
  20. data/app/graphql/mutations/oval_policies/create.rb +0 -33
  21. data/app/graphql/mutations/oval_policies/delete.rb +0 -9
  22. data/app/graphql/mutations/oval_policies/update.rb +0 -15
  23. data/app/graphql/types/cve.rb +0 -17
  24. data/app/graphql/types/oval_check.rb +0 -11
  25. data/app/graphql/types/oval_content.rb +0 -19
  26. data/app/graphql/types/oval_policy.rb +0 -24
  27. data/app/models/concerns/foreman_openscap/oval_facet_host_extensions.rb +0 -38
  28. data/app/models/concerns/foreman_openscap/oval_facet_hostgroup_extensions.rb +0 -31
  29. data/app/models/foreman_openscap/cve.rb +0 -23
  30. data/app/models/foreman_openscap/host/oval_facet.rb +0 -14
  31. data/app/models/foreman_openscap/host_cve.rb +0 -7
  32. data/app/models/foreman_openscap/hostgroup/oval_facet.rb +0 -14
  33. data/app/models/foreman_openscap/hostgroup_oval_facet_oval_policy.rb +0 -6
  34. data/app/models/foreman_openscap/oval_content.rb +0 -28
  35. data/app/models/foreman_openscap/oval_facet_oval_policy.rb +0 -6
  36. data/app/models/foreman_openscap/oval_policy.rb +0 -54
  37. data/app/models/foreman_openscap/oval_status.rb +0 -45
  38. data/app/services/foreman_openscap/oval/check_collection.rb +0 -45
  39. data/app/services/foreman_openscap/oval/configure.rb +0 -83
  40. data/app/services/foreman_openscap/oval/cves.rb +0 -41
  41. data/app/services/foreman_openscap/oval/setup.rb +0 -93
  42. data/app/services/foreman_openscap/oval/setup_check.rb +0 -58
  43. data/app/services/foreman_openscap/oval/sync_oval_contents.rb +0 -42
  44. data/app/views/api/v2/compliance/oval_contents/base.json.rabl +0 -6
  45. data/app/views/api/v2/compliance/oval_contents/create.json.rabl +0 -3
  46. data/app/views/api/v2/compliance/oval_contents/destroy.json.rabl +0 -3
  47. data/app/views/api/v2/compliance/oval_contents/index.json.rabl +0 -3
  48. data/app/views/api/v2/compliance/oval_contents/show.json.rabl +0 -3
  49. data/app/views/api/v2/compliance/oval_contents/sync.json.rabl +0 -3
  50. data/app/views/api/v2/compliance/oval_contents/sync_result.json.rabl +0 -11
  51. data/app/views/api/v2/compliance/oval_contents/update.json.rabl +0 -3
  52. data/app/views/api/v2/compliance/oval_policies/create.json.rabl +0 -3
  53. data/app/views/api/v2/compliance/oval_policies/index.json.rabl +0 -3
  54. data/app/views/api/v2/compliance/oval_policies/main.json.rabl +0 -15
  55. data/app/views/api/v2/compliance/oval_policies/show.json.rabl +0 -3
  56. data/app/views/job_templates/run_oval_scans.erb +0 -24
  57. data/locale/cs_CZ/foreman_openscap.edit.po +0 -1863
  58. data/locale/cs_CZ/foreman_openscap.po.time_stamp +0 -0
  59. data/locale/de/foreman_openscap.edit.po +0 -1873
  60. data/locale/de/foreman_openscap.po.time_stamp +0 -0
  61. data/locale/en/foreman_openscap.edit.po +0 -1863
  62. data/locale/en/foreman_openscap.po.time_stamp +0 -0
  63. data/locale/en_GB/foreman_openscap.edit.po +0 -1863
  64. data/locale/en_GB/foreman_openscap.po.time_stamp +0 -0
  65. data/locale/es/foreman_openscap.edit.po +0 -1868
  66. data/locale/es/foreman_openscap.po.time_stamp +0 -0
  67. data/locale/fr/foreman_openscap.edit.po +0 -1874
  68. data/locale/fr/foreman_openscap.po.time_stamp +0 -0
  69. data/locale/gl/foreman_openscap.edit.po +0 -1863
  70. data/locale/gl/foreman_openscap.po.time_stamp +0 -0
  71. data/locale/it/foreman_openscap.edit.po +0 -1865
  72. data/locale/it/foreman_openscap.po.time_stamp +0 -0
  73. data/locale/ja/foreman_openscap.edit.po +0 -1869
  74. data/locale/ja/foreman_openscap.po.time_stamp +0 -0
  75. data/locale/ka/foreman_openscap.edit.po +0 -1863
  76. data/locale/ka/foreman_openscap.po.time_stamp +0 -0
  77. data/locale/ko/foreman_openscap.edit.po +0 -1863
  78. data/locale/ko/foreman_openscap.po.time_stamp +0 -0
  79. data/locale/pt_BR/foreman_openscap.edit.po +0 -1873
  80. data/locale/pt_BR/foreman_openscap.po.time_stamp +0 -0
  81. data/locale/ru/foreman_openscap.edit.po +0 -1867
  82. data/locale/ru/foreman_openscap.po.time_stamp +0 -0
  83. data/locale/sv_SE/foreman_openscap.edit.po +0 -1863
  84. data/locale/sv_SE/foreman_openscap.po.time_stamp +0 -0
  85. data/locale/zh_CN/foreman_openscap.edit.po +0 -1868
  86. data/locale/zh_CN/foreman_openscap.po.time_stamp +0 -0
  87. data/locale/zh_TW/foreman_openscap.edit.po +0 -1864
  88. data/locale/zh_TW/foreman_openscap.po.time_stamp +0 -0
  89. data/test/factories/oval_content_factory.rb +0 -7
  90. data/test/factories/oval_policy_factory.rb +0 -9
  91. data/test/fixtures/cve_fixtures.rb +0 -104
  92. data/test/functional/api/v2/compliance/oval_contents_controller_test.rb +0 -39
  93. data/test/functional/api/v2/compliance/oval_policies_controller_test.rb +0 -141
  94. data/test/functional/api/v2/compliance/oval_reports_controller_test.rb +0 -32
  95. data/test/graphql/mutations/oval_policies/delete_mutation_test.rb +0 -63
  96. data/test/graphql/queries/oval_content_query_test.rb +0 -29
  97. data/test/graphql/queries/oval_contents_query_test.rb +0 -35
  98. data/test/graphql/queries/oval_policies_query_test.rb +0 -35
  99. data/test/unit/oval_host_test.rb +0 -45
  100. data/test/unit/oval_policy_test.rb +0 -133
  101. data/test/unit/oval_status_test.rb +0 -47
  102. data/test/unit/services/oval/cves_test.rb +0 -81
  103. data/test/unit/services/oval/setup_check_test.rb +0 -37
  104. data/test/unit/services/oval/setup_test.rb +0 -87
  105. data/webpack/graphql/mutations/createOvalPolicy.gql +0 -22
  106. data/webpack/graphql/mutations/deleteOvalContent.gql +0 -9
  107. data/webpack/graphql/mutations/deleteOvalPolicy.gql +0 -9
  108. data/webpack/graphql/mutations/updateOvalPolicy.gql +0 -14
  109. data/webpack/graphql/queries/currentUserAttributes.gql +0 -11
  110. data/webpack/graphql/queries/cves.gql +0 -23
  111. data/webpack/graphql/queries/hostgroups.gql +0 -14
  112. data/webpack/graphql/queries/ovalContent.gql +0 -8
  113. data/webpack/graphql/queries/ovalContents.gql +0 -19
  114. data/webpack/graphql/queries/ovalPolicies.gql +0 -20
  115. data/webpack/graphql/queries/ovalPolicy.gql +0 -29
  116. data/webpack/helpers/pathsHelper.js +0 -29
  117. data/webpack/routes/OvalContents/OvalContentsIndex/OvalContentsIndex.js +0 -71
  118. data/webpack/routes/OvalContents/OvalContentsIndex/OvalContentsTable.js +0 -83
  119. data/webpack/routes/OvalContents/OvalContentsIndex/__tests__/OvalContentsDestroy.fixtures.js +0 -105
  120. data/webpack/routes/OvalContents/OvalContentsIndex/__tests__/OvalContentsDestroy.test.js +0 -124
  121. data/webpack/routes/OvalContents/OvalContentsIndex/__tests__/OvalContentsIndex.fixtures.js +0 -127
  122. data/webpack/routes/OvalContents/OvalContentsIndex/__tests__/OvalContentsIndex.test.js +0 -89
  123. data/webpack/routes/OvalContents/OvalContentsIndex/index.js +0 -13
  124. data/webpack/routes/OvalContents/OvalContentsNew/OvalContentsNew.js +0 -138
  125. data/webpack/routes/OvalContents/OvalContentsNew/OvalContentsNew.scss +0 -3
  126. data/webpack/routes/OvalContents/OvalContentsNew/OvalContentsNewHelper.js +0 -73
  127. data/webpack/routes/OvalContents/OvalContentsNew/__tests__/OvalContentsNew.test.js +0 -104
  128. data/webpack/routes/OvalContents/OvalContentsNew/index.js +0 -13
  129. data/webpack/routes/OvalContents/OvalContentsShow/OvalContentsShow.js +0 -62
  130. data/webpack/routes/OvalContents/OvalContentsShow/OvalContentsShow.test.js +0 -45
  131. data/webpack/routes/OvalContents/OvalContentsShow/OvalContentsShowHelper.js +0 -0
  132. data/webpack/routes/OvalContents/OvalContentsShow/index.js +0 -35
  133. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/OvalPoliciesIndex.js +0 -62
  134. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/OvalPoliciesTable.js +0 -74
  135. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/__tests__/OvalPoliciesDestroy.fixtures.js +0 -101
  136. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/__tests__/OvalPoliciesDestroy.test.js +0 -117
  137. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/__tests__/OvalPoliciesIndex.fixtures.js +0 -111
  138. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/__tests__/OvalPoliciesIndex.test.js +0 -81
  139. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/index.js +0 -13
  140. data/webpack/routes/OvalPolicies/OvalPoliciesNew/HostgroupSelect.js +0 -135
  141. data/webpack/routes/OvalPolicies/OvalPoliciesNew/NewOvalPolicyForm.js +0 -119
  142. data/webpack/routes/OvalPolicies/OvalPoliciesNew/NewOvalPolicyFormHelpers.js +0 -107
  143. data/webpack/routes/OvalPolicies/OvalPoliciesNew/OvalPoliciesNew.js +0 -32
  144. data/webpack/routes/OvalPolicies/OvalPoliciesNew/__tests__/OvalPoliciesNew.fixtures.js +0 -147
  145. data/webpack/routes/OvalPolicies/OvalPoliciesNew/__tests__/OvalPoliciesNew.test.js +0 -172
  146. data/webpack/routes/OvalPolicies/OvalPoliciesNew/index.js +0 -11
  147. data/webpack/routes/OvalPolicies/OvalPoliciesShow/CvesTab.js +0 -49
  148. data/webpack/routes/OvalPolicies/OvalPoliciesShow/CvesTable.js +0 -63
  149. data/webpack/routes/OvalPolicies/OvalPoliciesShow/DetailsTab.js +0 -87
  150. data/webpack/routes/OvalPolicies/OvalPoliciesShow/HostgroupsTab.js +0 -49
  151. data/webpack/routes/OvalPolicies/OvalPoliciesShow/HostgroupsTable.js +0 -38
  152. data/webpack/routes/OvalPolicies/OvalPoliciesShow/OvalPoliciesShow.js +0 -82
  153. data/webpack/routes/OvalPolicies/OvalPoliciesShow/OvalPoliciesShowHelper.js +0 -117
  154. data/webpack/routes/OvalPolicies/OvalPoliciesShow/__tests__/OvalPoliciesEdit.fixtures.js +0 -48
  155. data/webpack/routes/OvalPolicies/OvalPoliciesShow/__tests__/OvalPoliciesEdit.test.js +0 -202
  156. data/webpack/routes/OvalPolicies/OvalPoliciesShow/__tests__/OvalPoliciesShow.fixtures.js +0 -124
  157. data/webpack/routes/OvalPolicies/OvalPoliciesShow/__tests__/OvalPoliciesShow.test.js +0 -172
  158. data/webpack/routes/OvalPolicies/OvalPoliciesShow/index.js +0 -39
  159. data/webpack/routes/routes.js +0 -49
@@ -1,111 +0,0 @@
1
- import policiesQuery from '../../../../graphql/queries/ovalPolicies.gql';
2
- import { ovalPoliciesPath } from '../../../../helpers/pathsHelper';
3
- import {
4
- mockFactory,
5
- admin,
6
- intruder,
7
- userFactory,
8
- } from '../../../../testHelper';
9
-
10
- const policiesMockFactory = mockFactory('ovalPolicies', policiesQuery);
11
-
12
- export const pushMock = jest.fn();
13
-
14
- export const pageParamsHistoryMock = {
15
- location: {
16
- search: '?page=2&perPage=5',
17
- pathname: ovalPoliciesPath,
18
- },
19
- push: pushMock,
20
- };
21
-
22
- const viewer = userFactory('viewer', [
23
- {
24
- __typename: 'Permission',
25
- id: 'MDE6UGVybWlzc2lvbi0yOTY=',
26
- name: 'view_oval_policies',
27
- },
28
- ]);
29
-
30
- const firstPolicy = (meta = { canDestroy: true }) => ({
31
- __typename: 'ForemanOpenscap::OvalPolicy',
32
- id: 'MDE6Rm9yZW1hbk9wZW5zY2FwOjpPdmFsUG9saWN5LTE=',
33
- name: 'first policy',
34
- meta,
35
- ovalContent: { name: 'first content' },
36
- });
37
- const secondPolicy = (meta = { canDestroy: true }) => ({
38
- __typename: 'ForemanOpenscap::OvalPolicy',
39
- id: 'MDE6Rm9yZW1hbk9wZW5zY2FwOjpPdmFsUG9saWN5LTQw',
40
- name: 'second policy',
41
- meta,
42
- ovalContent: { name: 'second content' },
43
- });
44
- const policiesData = {
45
- totalCount: 2,
46
- nodes: [firstPolicy(), secondPolicy()],
47
- };
48
-
49
- export const mocks = policiesMockFactory(
50
- { first: 20, last: 20 },
51
- policiesData,
52
- { currentUser: admin }
53
- );
54
- export const pageParamsMocks = policiesMockFactory(
55
- { first: 10, last: 5 },
56
- {
57
- totalCount: 7,
58
- nodes: [
59
- {
60
- __typename: 'ForemanOpenscap::OvalPolicy',
61
- id: 'MDE6Rm9yZW1hbk9wZW5zY2FwOjpPdmFsUG9saWN5LTQx',
62
- name: 'sixth policy',
63
- meta: { canDestroy: true },
64
- ovalContent: { name: 'sixth content' },
65
- },
66
- {
67
- __typename: 'ForemanOpenscap::OvalPolicy',
68
- id: 'MDE6Rm9yZW1hbk9wZW5zY2FwOjpPdmFsUG9saWN5LTQy',
69
- name: 'seventh policy',
70
- meta: { canDestroy: true },
71
- ovalContent: { name: 'seventh content' },
72
- },
73
- ],
74
- },
75
- { currentUser: admin }
76
- );
77
-
78
- export const emptyMocks = policiesMockFactory(
79
- { first: 20, last: 20 },
80
- { totalCount: 0, nodes: [] },
81
- { currentUser: admin }
82
- );
83
- export const errorMocks = policiesMockFactory(
84
- { first: 20, last: 20 },
85
- { totalCount: 0, nodes: [] },
86
- {
87
- errors: [{ message: 'Something very bad happened.', path: 'base' }],
88
- currentUser: admin,
89
- }
90
- );
91
- export const viewerMocks = policiesMockFactory(
92
- { first: 20, last: 20 },
93
- policiesData,
94
- { currentUser: viewer }
95
- );
96
- export const unauthorizedMocks = policiesMockFactory(
97
- { first: 20, last: 20 },
98
- policiesData,
99
- { currentUser: intruder }
100
- );
101
- export const noDeleteMocks = policiesMockFactory(
102
- { first: 20, last: 20 },
103
- {
104
- totalCount: 2,
105
- nodes: [
106
- firstPolicy({ canDestroy: false }),
107
- secondPolicy({ canDestroy: false }),
108
- ],
109
- },
110
- { currentUser: admin }
111
- );
@@ -1,81 +0,0 @@
1
- import React from 'react';
2
- import { render, screen, waitFor } from '@testing-library/react';
3
- import '@testing-library/jest-dom';
4
-
5
- import {
6
- withMockedProvider,
7
- withRouter,
8
- withRedux,
9
- tick,
10
- historyMock,
11
- } from '../../../../testHelper';
12
-
13
- import {
14
- mocks,
15
- emptyMocks,
16
- errorMocks,
17
- viewerMocks,
18
- unauthorizedMocks,
19
- } from './OvalPoliciesIndex.fixtures';
20
-
21
- import OvalPoliciesIndex from '../index';
22
-
23
- const TestComponent = withRouter(
24
- withRedux(withMockedProvider(OvalPoliciesIndex))
25
- );
26
-
27
- describe('OvalPoliciesIndex', () => {
28
- it('should load page', async () => {
29
- render(<TestComponent history={historyMock} mocks={mocks} />);
30
- expect(screen.getByText('Loading')).toBeInTheDocument();
31
- await waitFor(tick);
32
- expect(screen.getByText('first policy')).toBeInTheDocument();
33
- expect(screen.getByText('second policy')).toBeInTheDocument();
34
- expect(screen.getByText('first content')).toBeInTheDocument();
35
- expect(screen.getByText('second content')).toBeInTheDocument();
36
-
37
- expect(screen.getByText('first policy').closest('a')).toHaveAttribute(
38
- 'href',
39
- '/experimental/compliance/oval_policies/1'
40
- );
41
- expect(screen.getByText('second policy').closest('a')).toHaveAttribute(
42
- 'href',
43
- '/experimental/compliance/oval_policies/40'
44
- );
45
- });
46
- it('should show empty state', async () => {
47
- render(<TestComponent history={historyMock} mocks={emptyMocks} />);
48
- expect(screen.getByText('Loading')).toBeInTheDocument();
49
- await waitFor(tick);
50
- expect(screen.queryByText('Loading')).not.toBeInTheDocument();
51
- expect(screen.getByText('No OVAL Policies found')).toBeInTheDocument();
52
- });
53
- it('should show errors', async () => {
54
- render(<TestComponent history={historyMock} mocks={errorMocks} />);
55
- expect(screen.getByText('Loading')).toBeInTheDocument();
56
- await waitFor(tick);
57
- expect(screen.queryByText('Loading')).not.toBeInTheDocument();
58
- expect(
59
- screen.getByText('Something very bad happened.')
60
- ).toBeInTheDocument();
61
- expect(screen.getByText('Error!')).toBeInTheDocument();
62
- });
63
- it('should load page for user with permissions', async () => {
64
- render(<TestComponent history={historyMock} mocks={viewerMocks} />);
65
- await waitFor(tick);
66
- expect(screen.queryByText('Loading')).not.toBeInTheDocument();
67
- expect(screen.getByText('first policy')).toBeInTheDocument();
68
- });
69
- it('should not load page for user without permissions', async () => {
70
- render(<TestComponent history={historyMock} mocks={unauthorizedMocks} />);
71
- await waitFor(tick);
72
- expect(screen.queryByText('Loading')).not.toBeInTheDocument();
73
- expect(screen.queryByText('first policy')).not.toBeInTheDocument();
74
- expect(
75
- screen.getByText(
76
- 'You are not authorized to view the page. Request the following permissions from administrator: view_oval_policies.'
77
- )
78
- ).toBeInTheDocument();
79
- expect(screen.getByText('Permission denied')).toBeInTheDocument();
80
- });
81
- });
@@ -1,13 +0,0 @@
1
- import React from 'react';
2
- import { useDispatch } from 'react-redux';
3
- import { showToast } from '../../../helpers/toastHelper';
4
-
5
- import OvalPoliciesIndex from './OvalPoliciesIndex';
6
-
7
- const WrappedOvalPoliciesIndex = props => {
8
- const dispatch = useDispatch();
9
-
10
- return <OvalPoliciesIndex {...props} showToast={showToast(dispatch)} />;
11
- };
12
-
13
- export default WrappedOvalPoliciesIndex;
@@ -1,135 +0,0 @@
1
- import React, { useState } from 'react';
2
- import PropTypes from 'prop-types';
3
- import { useLazyQuery } from '@apollo/client';
4
- import { translate as __, sprintf } from 'foremanReact/common/I18n';
5
- import {
6
- Select,
7
- SelectOption,
8
- SelectVariant,
9
- FormGroup,
10
- } from '@patternfly/react-core';
11
- import { ExclamationCircleIcon } from '@patternfly/react-icons';
12
- import hostgroupsQuery from '../../../graphql/queries/hostgroups.gql';
13
-
14
- const HostgroupSelect = ({
15
- selected,
16
- setSelected,
17
- hgsError,
18
- showError,
19
- setShowError,
20
- }) => {
21
- const [isOpen, setIsOpen] = useState(false);
22
-
23
- const [typingTimeout, setTypingTimeout] = useState(null);
24
-
25
- const [fetchHostgroups, { loading, data, error }] = useLazyQuery(
26
- hostgroupsQuery
27
- );
28
- const results = data?.hostgroups?.nodes ? data.hostgroups.nodes : [];
29
-
30
- const onSelect = (event, selection) => {
31
- if (selected.find(item => item.name === selection)) {
32
- setSelected(selected.filter(item => item.name !== selection));
33
- } else {
34
- const hg = results.find(item => item.name === selection);
35
- setSelected([...selected, hg]);
36
- }
37
- };
38
-
39
- const onClear = () => {
40
- if (showError) {
41
- setShowError(false);
42
- }
43
- setSelected([]);
44
- };
45
-
46
- const onInputChange = value => {
47
- if (showError) {
48
- setShowError(false);
49
- }
50
- if (typingTimeout) {
51
- clearTimeout(typingTimeout);
52
- }
53
- const variables = { search: `name ~ ${value}` };
54
- setTypingTimeout(setTimeout(() => fetchHostgroups({ variables }), 500));
55
- };
56
-
57
- const shouldValidate = (err, shouldShowError) => {
58
- if (shouldShowError) {
59
- return err ? 'error' : 'success';
60
- }
61
- return 'noval';
62
- };
63
-
64
- const prepareOptions = fetchedResults => {
65
- if (loading) {
66
- return [
67
- <SelectOption isDisabled key={0}>
68
- {__('Loading...')}
69
- </SelectOption>,
70
- ];
71
- }
72
-
73
- if (error) {
74
- return [
75
- <SelectOption isDisabled key={0}>
76
- {sprintf('Failed to fetch hostgroups, cause: %s', error.message)}
77
- </SelectOption>,
78
- ];
79
- }
80
-
81
- if (fetchedResults.length > 20) {
82
- return [
83
- <SelectOption isDisabled key={0}>
84
- {sprintf(
85
- 'You have %s hostgroups to display. Please refine your search.',
86
- fetchedResults.length
87
- )}
88
- </SelectOption>,
89
- ];
90
- }
91
-
92
- return fetchedResults.map((hg, idx) => (
93
- <SelectOption key={hg.id} value={hg.name} />
94
- ));
95
- };
96
-
97
- return (
98
- <FormGroup
99
- label={__('Hostgroups')}
100
- helperTextInvalidIcon={<ExclamationCircleIcon />}
101
- helperTextInvalid={showError && hgsError}
102
- validated={shouldValidate(hgsError, showError)}
103
- >
104
- <Select
105
- variant={SelectVariant.typeaheadMulti}
106
- typeAheadAriaLabel="Select a hostgroup"
107
- placeholderText={__('Type a hostgroup name...')}
108
- onToggle={() => setIsOpen(!isOpen)}
109
- onSelect={onSelect}
110
- onClear={onClear}
111
- selections={selected.map(item => item.name)}
112
- isOpen={isOpen}
113
- onTypeaheadInputChanged={onInputChange}
114
- validated={shouldValidate(hgsError, showError)}
115
- >
116
- {prepareOptions(results)}
117
- </Select>
118
- </FormGroup>
119
- );
120
- };
121
-
122
- HostgroupSelect.propTypes = {
123
- selected: PropTypes.array,
124
- setSelected: PropTypes.func.isRequired,
125
- hgsError: PropTypes.string,
126
- showError: PropTypes.bool.isRequired,
127
- setShowError: PropTypes.func.isRequired,
128
- };
129
-
130
- HostgroupSelect.defaultProps = {
131
- selected: [],
132
- hgsError: '',
133
- };
134
-
135
- export default HostgroupSelect;
@@ -1,119 +0,0 @@
1
- import React, { useState } from 'react';
2
- import PropTypes from 'prop-types';
3
- import { Formik, Field as FormikField } from 'formik';
4
- import { useMutation } from '@apollo/client';
5
- import { translate as __ } from 'foremanReact/common/I18n';
6
- import { Button, Form as PfForm, ActionGroup } from '@patternfly/react-core';
7
-
8
- import createOvalPolicy from '../../../graphql/mutations/createOvalPolicy.gql';
9
-
10
- import {
11
- TextField,
12
- TextAreaField,
13
- SelectField,
14
- } from '../../../helpers/formFieldsHelper';
15
- import HostgroupSelect from './HostgroupSelect';
16
- import withLoading from '../../../components/withLoading';
17
-
18
- import { ovalPoliciesPath } from '../../../helpers/pathsHelper';
19
- import LinkButton from '../../../components/LinkButton';
20
-
21
- import {
22
- createValidationSchema,
23
- onSubmit,
24
- initialValues,
25
- } from './NewOvalPolicyFormHelpers';
26
-
27
- const NewOvalPolicyForm = ({ history, showToast, ovalContents }) => {
28
- const [callMutation] = useMutation(createOvalPolicy);
29
-
30
- const [assignedHgs, setAssignedHgs] = useState([]);
31
- const [hgsShowError, setHgsShowError] = useState(false);
32
- const [hgsError, setHgsError] = useState('');
33
-
34
- const onHgsError = error => {
35
- setHgsShowError(true);
36
- setHgsError(error);
37
- };
38
-
39
- return (
40
- <Formik
41
- onSubmit={onSubmit(
42
- history,
43
- showToast,
44
- callMutation,
45
- assignedHgs,
46
- onHgsError
47
- )}
48
- initialValues={initialValues}
49
- validationSchema={createValidationSchema()}
50
- >
51
- {formProps => (
52
- <PfForm>
53
- <FormikField
54
- name="name"
55
- component={TextField}
56
- label={__('Name')}
57
- isRequired
58
- />
59
- <FormikField
60
- name="description"
61
- component={TextAreaField}
62
- label={__('Description')}
63
- />
64
- <FormikField
65
- name="cronLine"
66
- component={TextField}
67
- label={__('Schedule')}
68
- isRequired
69
- />
70
- <FormikField
71
- name="ovalContentId"
72
- component={SelectField}
73
- selectItems={ovalContents}
74
- label={__('OVAL Content')}
75
- isRequired
76
- blankLabel={__('Choose OVAL Content')}
77
- />
78
- <HostgroupSelect
79
- selected={assignedHgs}
80
- setSelected={setAssignedHgs}
81
- showError={hgsShowError}
82
- setShowError={setHgsShowError}
83
- hgsError={hgsError}
84
- isDisabled={formProps.isSubmitting}
85
- />
86
- <ActionGroup>
87
- <Button
88
- variant="primary"
89
- onClick={formProps.handleSubmit}
90
- isDisabled={
91
- !formProps.isValid ||
92
- formProps.isSubmitting ||
93
- (hgsShowError && hgsError)
94
- }
95
- aria-label="submit"
96
- >
97
- {__('Submit')}
98
- </Button>
99
- <LinkButton
100
- path={ovalPoliciesPath}
101
- btnVariant="link"
102
- btnText={__('Cancel')}
103
- btnAriaLabel="cancel"
104
- isDisabled={formProps.isSubmitting}
105
- />
106
- </ActionGroup>
107
- </PfForm>
108
- )}
109
- </Formik>
110
- );
111
- };
112
-
113
- NewOvalPolicyForm.propTypes = {
114
- history: PropTypes.object.isRequired,
115
- showToast: PropTypes.func.isRequired,
116
- ovalContents: PropTypes.array.isRequired,
117
- };
118
-
119
- export default withLoading(NewOvalPolicyForm);
@@ -1,107 +0,0 @@
1
- import * as Yup from 'yup';
2
- import { translate as __, sprintf } from 'foremanReact/common/I18n';
3
-
4
- import { ovalPoliciesPath } from '../../../helpers/pathsHelper';
5
- import { decodeId, decodeModelId } from '../../../helpers/globalIdHelper';
6
-
7
- export const createValidationSchema = () => {
8
- const cantBeBlank = __("can't be blank");
9
-
10
- return Yup.object().shape({
11
- name: Yup.string().required(cantBeBlank),
12
- ovalContentId: Yup.string().required(cantBeBlank),
13
- cronLine: Yup.string().test(
14
- 'is-cron',
15
- __('is not a valid cronline'),
16
- value => value && value.trim().split(' ').length === 5
17
- ),
18
- });
19
- };
20
-
21
- const partitionById = (array, name) => {
22
- const res = array.reduce(
23
- (memo, item) => {
24
- if (item.id === name) {
25
- memo.left.push(item);
26
- } else {
27
- memo.right.push(item);
28
- }
29
- return memo;
30
- },
31
- { left: [], right: [] }
32
- );
33
- return [res.left, res.right];
34
- };
35
-
36
- const checksToMessage = checks =>
37
- checks.reduce((memo, check) => [...memo, check.failMsg], []).join(' ');
38
-
39
- export const onSubmit = (
40
- history,
41
- showToast,
42
- callMutation,
43
- assignedHgs,
44
- setHgsError
45
- ) => (values, actions) => {
46
- const onCompleted = response => {
47
- const failedChecks = response.data.createOvalPolicy.checkCollection.filter(
48
- check => check.result === 'fail'
49
- );
50
- if (failedChecks.length === 0) {
51
- history.push(ovalPoliciesPath);
52
- showToast({
53
- type: 'success',
54
- message: __('OVAL Policy succesfully created.'),
55
- });
56
- } else {
57
- actions.setSubmitting(false);
58
-
59
- const [validationChecks, withoutValidationChecks] = partitionById(
60
- failedChecks,
61
- 'oval_policy_errors'
62
- );
63
-
64
- const [hgChecks, remainingChecks] = partitionById(
65
- withoutValidationChecks,
66
- 'hostgroups_without_proxy'
67
- );
68
- if (validationChecks.length === 1) {
69
- actions.setErrors(validationChecks[0].errors);
70
- }
71
- if (hgChecks.length > 0) {
72
- setHgsError(checksToMessage(hgChecks));
73
- }
74
- if (remainingChecks.length > 0) {
75
- showToast({
76
- type: 'error',
77
- message: checksToMessage(remainingChecks),
78
- });
79
- }
80
- }
81
- };
82
-
83
- const onError = response => {
84
- showToast({
85
- type: 'error',
86
- message: sprintf(__('Failed to create OVAL Policy: %s'), response.error),
87
- });
88
- actions.setSubmitting(false);
89
- };
90
-
91
- const hostgroupIds = assignedHgs.map(decodeModelId);
92
- const variables = {
93
- ...values,
94
- ovalContentId: decodeId(values.ovalContentId),
95
- period: 'custom',
96
- hostgroupIds,
97
- };
98
- // eslint-disable-next-line promise/prefer-await-to-then
99
- callMutation({ variables }).then(onCompleted, onError);
100
- };
101
-
102
- export const initialValues = {
103
- name: '',
104
- description: '',
105
- ovalContentId: '',
106
- cronLine: '',
107
- };
@@ -1,32 +0,0 @@
1
- import React from 'react';
2
- import { useQuery } from '@apollo/client';
3
- import { translate as __ } from 'foremanReact/common/I18n';
4
- import IndexLayout from '../../../components/IndexLayout';
5
-
6
- import ovalContentsQuery from '../../../graphql/queries/ovalContents.gql';
7
- import NewOvalPolicyForm from './NewOvalPolicyForm';
8
-
9
- const OvalPoliciesNew = props => {
10
- const useFetchFn = () => useQuery(ovalContentsQuery);
11
-
12
- const renameData = data => ({
13
- ovalContents: data.ovalContents.nodes,
14
- });
15
-
16
- return (
17
- <IndexLayout pageTitle={__('Create OVAL Policy')}>
18
- <NewOvalPolicyForm
19
- fetchFn={useFetchFn}
20
- renameData={renameData}
21
- resultPath="ovalContents.nodes"
22
- emptyStateTitle={__('No OVAL Content found')}
23
- emptyStateBody={__(
24
- 'OVAL Content is required to create OVAL Policy. Please create one before proceeding.'
25
- )}
26
- {...props}
27
- />
28
- </IndexLayout>
29
- );
30
- };
31
-
32
- export default OvalPoliciesNew;