foreman_openscap 8.0.2 → 9.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) 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/lib/foreman_openscap/engine.rb +2 -56
  8. data/lib/foreman_openscap/version.rb +1 -1
  9. data/test/factories/compliance_host_factory.rb +0 -12
  10. data/test/test_plugin_helper.rb +0 -2
  11. data/webpack/global_index.js +0 -4
  12. metadata +7 -168
  13. data/app/controllers/api/v2/compliance/oval_contents_controller.rb +0 -72
  14. data/app/controllers/api/v2/compliance/oval_policies_controller.rb +0 -111
  15. data/app/controllers/api/v2/compliance/oval_reports_controller.rb +0 -47
  16. data/app/controllers/concerns/foreman/controller/parameters/oval_content.rb +0 -22
  17. data/app/controllers/concerns/foreman/controller/parameters/oval_policy.rb +0 -22
  18. data/app/graphql/mutations/oval_contents/delete.rb +0 -9
  19. data/app/graphql/mutations/oval_policies/create.rb +0 -33
  20. data/app/graphql/mutations/oval_policies/delete.rb +0 -9
  21. data/app/graphql/mutations/oval_policies/update.rb +0 -15
  22. data/app/graphql/types/cve.rb +0 -17
  23. data/app/graphql/types/oval_check.rb +0 -11
  24. data/app/graphql/types/oval_content.rb +0 -19
  25. data/app/graphql/types/oval_policy.rb +0 -24
  26. data/app/models/concerns/foreman_openscap/oval_facet_host_extensions.rb +0 -38
  27. data/app/models/concerns/foreman_openscap/oval_facet_hostgroup_extensions.rb +0 -31
  28. data/app/models/foreman_openscap/cve.rb +0 -23
  29. data/app/models/foreman_openscap/host/oval_facet.rb +0 -14
  30. data/app/models/foreman_openscap/host_cve.rb +0 -7
  31. data/app/models/foreman_openscap/hostgroup/oval_facet.rb +0 -14
  32. data/app/models/foreman_openscap/hostgroup_oval_facet_oval_policy.rb +0 -6
  33. data/app/models/foreman_openscap/oval_content.rb +0 -28
  34. data/app/models/foreman_openscap/oval_facet_oval_policy.rb +0 -6
  35. data/app/models/foreman_openscap/oval_policy.rb +0 -54
  36. data/app/models/foreman_openscap/oval_status.rb +0 -45
  37. data/app/services/foreman_openscap/oval/check_collection.rb +0 -45
  38. data/app/services/foreman_openscap/oval/configure.rb +0 -83
  39. data/app/services/foreman_openscap/oval/cves.rb +0 -41
  40. data/app/services/foreman_openscap/oval/setup.rb +0 -93
  41. data/app/services/foreman_openscap/oval/setup_check.rb +0 -58
  42. data/app/services/foreman_openscap/oval/sync_oval_contents.rb +0 -42
  43. data/app/views/api/v2/compliance/oval_contents/base.json.rabl +0 -6
  44. data/app/views/api/v2/compliance/oval_contents/create.json.rabl +0 -3
  45. data/app/views/api/v2/compliance/oval_contents/destroy.json.rabl +0 -3
  46. data/app/views/api/v2/compliance/oval_contents/index.json.rabl +0 -3
  47. data/app/views/api/v2/compliance/oval_contents/show.json.rabl +0 -3
  48. data/app/views/api/v2/compliance/oval_contents/sync.json.rabl +0 -3
  49. data/app/views/api/v2/compliance/oval_contents/sync_result.json.rabl +0 -11
  50. data/app/views/api/v2/compliance/oval_contents/update.json.rabl +0 -3
  51. data/app/views/api/v2/compliance/oval_policies/create.json.rabl +0 -3
  52. data/app/views/api/v2/compliance/oval_policies/index.json.rabl +0 -3
  53. data/app/views/api/v2/compliance/oval_policies/main.json.rabl +0 -15
  54. data/app/views/api/v2/compliance/oval_policies/show.json.rabl +0 -3
  55. data/app/views/job_templates/run_oval_scans.erb +0 -24
  56. data/locale/cs_CZ/foreman_openscap.edit.po +0 -1863
  57. data/locale/cs_CZ/foreman_openscap.po.time_stamp +0 -0
  58. data/locale/de/foreman_openscap.edit.po +0 -1873
  59. data/locale/de/foreman_openscap.po.time_stamp +0 -0
  60. data/locale/en/foreman_openscap.edit.po +0 -1863
  61. data/locale/en/foreman_openscap.po.time_stamp +0 -0
  62. data/locale/en_GB/foreman_openscap.edit.po +0 -1863
  63. data/locale/en_GB/foreman_openscap.po.time_stamp +0 -0
  64. data/locale/es/foreman_openscap.edit.po +0 -1868
  65. data/locale/es/foreman_openscap.po.time_stamp +0 -0
  66. data/locale/fr/foreman_openscap.edit.po +0 -1874
  67. data/locale/fr/foreman_openscap.po.time_stamp +0 -0
  68. data/locale/gl/foreman_openscap.edit.po +0 -1863
  69. data/locale/gl/foreman_openscap.po.time_stamp +0 -0
  70. data/locale/it/foreman_openscap.edit.po +0 -1865
  71. data/locale/it/foreman_openscap.po.time_stamp +0 -0
  72. data/locale/ja/foreman_openscap.edit.po +0 -1869
  73. data/locale/ja/foreman_openscap.po.time_stamp +0 -0
  74. data/locale/ka/foreman_openscap.edit.po +0 -1863
  75. data/locale/ka/foreman_openscap.po.time_stamp +0 -0
  76. data/locale/ko/foreman_openscap.edit.po +0 -1863
  77. data/locale/ko/foreman_openscap.po.time_stamp +0 -0
  78. data/locale/pt_BR/foreman_openscap.edit.po +0 -1873
  79. data/locale/pt_BR/foreman_openscap.po.time_stamp +0 -0
  80. data/locale/ru/foreman_openscap.edit.po +0 -1867
  81. data/locale/ru/foreman_openscap.po.time_stamp +0 -0
  82. data/locale/sv_SE/foreman_openscap.edit.po +0 -1863
  83. data/locale/sv_SE/foreman_openscap.po.time_stamp +0 -0
  84. data/locale/zh_CN/foreman_openscap.edit.po +0 -1868
  85. data/locale/zh_CN/foreman_openscap.po.time_stamp +0 -0
  86. data/locale/zh_TW/foreman_openscap.edit.po +0 -1864
  87. data/locale/zh_TW/foreman_openscap.po.time_stamp +0 -0
  88. data/test/factories/oval_content_factory.rb +0 -7
  89. data/test/factories/oval_policy_factory.rb +0 -9
  90. data/test/fixtures/cve_fixtures.rb +0 -104
  91. data/test/functional/api/v2/compliance/oval_contents_controller_test.rb +0 -39
  92. data/test/functional/api/v2/compliance/oval_policies_controller_test.rb +0 -141
  93. data/test/functional/api/v2/compliance/oval_reports_controller_test.rb +0 -32
  94. data/test/graphql/mutations/oval_policies/delete_mutation_test.rb +0 -63
  95. data/test/graphql/queries/oval_content_query_test.rb +0 -29
  96. data/test/graphql/queries/oval_contents_query_test.rb +0 -35
  97. data/test/graphql/queries/oval_policies_query_test.rb +0 -35
  98. data/test/unit/oval_host_test.rb +0 -45
  99. data/test/unit/oval_policy_test.rb +0 -133
  100. data/test/unit/oval_status_test.rb +0 -47
  101. data/test/unit/services/oval/cves_test.rb +0 -81
  102. data/test/unit/services/oval/setup_check_test.rb +0 -37
  103. data/test/unit/services/oval/setup_test.rb +0 -87
  104. data/webpack/graphql/mutations/createOvalPolicy.gql +0 -22
  105. data/webpack/graphql/mutations/deleteOvalContent.gql +0 -9
  106. data/webpack/graphql/mutations/deleteOvalPolicy.gql +0 -9
  107. data/webpack/graphql/mutations/updateOvalPolicy.gql +0 -14
  108. data/webpack/graphql/queries/currentUserAttributes.gql +0 -11
  109. data/webpack/graphql/queries/cves.gql +0 -23
  110. data/webpack/graphql/queries/hostgroups.gql +0 -14
  111. data/webpack/graphql/queries/ovalContent.gql +0 -8
  112. data/webpack/graphql/queries/ovalContents.gql +0 -19
  113. data/webpack/graphql/queries/ovalPolicies.gql +0 -20
  114. data/webpack/graphql/queries/ovalPolicy.gql +0 -29
  115. data/webpack/helpers/pathsHelper.js +0 -29
  116. data/webpack/routes/OvalContents/OvalContentsIndex/OvalContentsIndex.js +0 -71
  117. data/webpack/routes/OvalContents/OvalContentsIndex/OvalContentsTable.js +0 -83
  118. data/webpack/routes/OvalContents/OvalContentsIndex/__tests__/OvalContentsDestroy.fixtures.js +0 -105
  119. data/webpack/routes/OvalContents/OvalContentsIndex/__tests__/OvalContentsDestroy.test.js +0 -124
  120. data/webpack/routes/OvalContents/OvalContentsIndex/__tests__/OvalContentsIndex.fixtures.js +0 -127
  121. data/webpack/routes/OvalContents/OvalContentsIndex/__tests__/OvalContentsIndex.test.js +0 -89
  122. data/webpack/routes/OvalContents/OvalContentsIndex/index.js +0 -13
  123. data/webpack/routes/OvalContents/OvalContentsNew/OvalContentsNew.js +0 -138
  124. data/webpack/routes/OvalContents/OvalContentsNew/OvalContentsNew.scss +0 -3
  125. data/webpack/routes/OvalContents/OvalContentsNew/OvalContentsNewHelper.js +0 -73
  126. data/webpack/routes/OvalContents/OvalContentsNew/__tests__/OvalContentsNew.test.js +0 -104
  127. data/webpack/routes/OvalContents/OvalContentsNew/index.js +0 -13
  128. data/webpack/routes/OvalContents/OvalContentsShow/OvalContentsShow.js +0 -62
  129. data/webpack/routes/OvalContents/OvalContentsShow/OvalContentsShow.test.js +0 -45
  130. data/webpack/routes/OvalContents/OvalContentsShow/OvalContentsShowHelper.js +0 -0
  131. data/webpack/routes/OvalContents/OvalContentsShow/index.js +0 -35
  132. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/OvalPoliciesIndex.js +0 -62
  133. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/OvalPoliciesTable.js +0 -74
  134. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/__tests__/OvalPoliciesDestroy.fixtures.js +0 -101
  135. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/__tests__/OvalPoliciesDestroy.test.js +0 -117
  136. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/__tests__/OvalPoliciesIndex.fixtures.js +0 -111
  137. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/__tests__/OvalPoliciesIndex.test.js +0 -81
  138. data/webpack/routes/OvalPolicies/OvalPoliciesIndex/index.js +0 -13
  139. data/webpack/routes/OvalPolicies/OvalPoliciesNew/HostgroupSelect.js +0 -135
  140. data/webpack/routes/OvalPolicies/OvalPoliciesNew/NewOvalPolicyForm.js +0 -119
  141. data/webpack/routes/OvalPolicies/OvalPoliciesNew/NewOvalPolicyFormHelpers.js +0 -107
  142. data/webpack/routes/OvalPolicies/OvalPoliciesNew/OvalPoliciesNew.js +0 -32
  143. data/webpack/routes/OvalPolicies/OvalPoliciesNew/__tests__/OvalPoliciesNew.fixtures.js +0 -147
  144. data/webpack/routes/OvalPolicies/OvalPoliciesNew/__tests__/OvalPoliciesNew.test.js +0 -172
  145. data/webpack/routes/OvalPolicies/OvalPoliciesNew/index.js +0 -11
  146. data/webpack/routes/OvalPolicies/OvalPoliciesShow/CvesTab.js +0 -49
  147. data/webpack/routes/OvalPolicies/OvalPoliciesShow/CvesTable.js +0 -63
  148. data/webpack/routes/OvalPolicies/OvalPoliciesShow/DetailsTab.js +0 -87
  149. data/webpack/routes/OvalPolicies/OvalPoliciesShow/HostgroupsTab.js +0 -49
  150. data/webpack/routes/OvalPolicies/OvalPoliciesShow/HostgroupsTable.js +0 -38
  151. data/webpack/routes/OvalPolicies/OvalPoliciesShow/OvalPoliciesShow.js +0 -82
  152. data/webpack/routes/OvalPolicies/OvalPoliciesShow/OvalPoliciesShowHelper.js +0 -117
  153. data/webpack/routes/OvalPolicies/OvalPoliciesShow/__tests__/OvalPoliciesEdit.fixtures.js +0 -48
  154. data/webpack/routes/OvalPolicies/OvalPoliciesShow/__tests__/OvalPoliciesEdit.test.js +0 -202
  155. data/webpack/routes/OvalPolicies/OvalPoliciesShow/__tests__/OvalPoliciesShow.fixtures.js +0 -124
  156. data/webpack/routes/OvalPolicies/OvalPoliciesShow/__tests__/OvalPoliciesShow.test.js +0 -172
  157. data/webpack/routes/OvalPolicies/OvalPoliciesShow/index.js +0 -39
  158. 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;