foreman_openscap 5.1.0 → 5.2.0
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.
- checksums.yaml +4 -4
- data/app/graphql/mutations/oval_policies/create.rb +33 -0
- data/app/helpers/policies_helper.rb +1 -1
- data/app/models/concerns/foreman_openscap/data_stream_content.rb +1 -1
- data/app/models/concerns/foreman_openscap/oval_facet_hostgroup_extensions.rb +1 -0
- data/app/models/foreman_openscap/arf_report.rb +1 -1
- data/app/models/foreman_openscap/oval_content.rb +1 -1
- data/app/services/foreman_openscap/oval/configure.rb +16 -13
- data/app/services/foreman_openscap/oval/setup_check.rb +1 -1
- data/lib/foreman_openscap/engine.rb +3 -2
- data/lib/foreman_openscap/version.rb +1 -1
- data/webpack/components/EditableInput.js +16 -10
- data/webpack/components/IndexTable/index.js +7 -2
- data/webpack/components/LinkButton.js +14 -2
- data/webpack/components/withLoading.js +3 -1
- data/webpack/graphql/mutations/createOvalPolicy.gql +22 -0
- data/webpack/graphql/queries/ovalPolicy.gql +3 -0
- data/webpack/helpers/formFieldsHelper.js +51 -1
- data/webpack/helpers/globalIdHelper.js +4 -2
- data/webpack/helpers/pathsHelper.js +5 -3
- data/webpack/helpers/toastsHelper.js +3 -0
- data/webpack/routes/OvalContents/OvalContentsIndex/__tests__/OvalContentsIndex.fixtures.js +6 -1
- data/webpack/routes/OvalPolicies/OvalPoliciesIndex/OvalPoliciesTable.js +18 -1
- data/webpack/routes/OvalPolicies/OvalPoliciesNew/HostgroupSelect.js +135 -0
- data/webpack/routes/OvalPolicies/OvalPoliciesNew/NewOvalPolicyForm.js +119 -0
- data/webpack/routes/OvalPolicies/OvalPoliciesNew/NewOvalPolicyFormHelpers.js +107 -0
- data/webpack/routes/OvalPolicies/OvalPoliciesNew/OvalPoliciesNew.js +32 -0
- data/webpack/routes/OvalPolicies/OvalPoliciesNew/__tests__/OvalPoliciesNew.fixtures.js +147 -0
- data/webpack/routes/OvalPolicies/OvalPoliciesNew/__tests__/OvalPoliciesNew.test.js +172 -0
- data/webpack/routes/OvalPolicies/OvalPoliciesNew/index.js +11 -0
- data/webpack/routes/OvalPolicies/OvalPoliciesShow/CvesTable.js +2 -2
- data/webpack/routes/OvalPolicies/OvalPoliciesShow/DetailsTab.js +2 -0
- data/webpack/routes/OvalPolicies/OvalPoliciesShow/OvalPoliciesShowHelper.js +4 -3
- data/webpack/routes/OvalPolicies/OvalPoliciesShow/__tests__/OvalPoliciesEdit.test.js +27 -0
- data/webpack/routes/OvalPolicies/OvalPoliciesShow/__tests__/OvalPoliciesShow.fixtures.js +11 -1
- data/webpack/routes/routes.js +7 -0
- data/webpack/testHelper.js +22 -0
- metadata +12 -2
@@ -0,0 +1,135 @@
|
|
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 hostroup 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;
|
@@ -0,0 +1,119 @@
|
|
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);
|
@@ -0,0 +1,107 @@
|
|
1
|
+
import * as Yup from 'yup';
|
2
|
+
import { translate as __ } 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: `Failed to create OVAL Policy: ${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
|
+
};
|
@@ -0,0 +1,32 @@
|
|
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;
|
@@ -0,0 +1,147 @@
|
|
1
|
+
import createOvalPolicy from '../../../../graphql/mutations/createOvalPolicy.gql';
|
2
|
+
import hostgroupsQuery from '../../../../graphql/queries/hostgroups.gql';
|
3
|
+
|
4
|
+
import { mockFactory, admin } from '../../../../testHelper';
|
5
|
+
import { decodeId } from '../../../../helpers/globalIdHelper';
|
6
|
+
import { ovalContents } from '../../../OvalContents/OvalContentsIndex/__tests__/OvalContentsIndex.fixtures';
|
7
|
+
|
8
|
+
export const newPolicyName = 'test policy';
|
9
|
+
export const newPolicyDescription = 'random description';
|
10
|
+
export const newPolicyCronline = '5 5 5 5 5';
|
11
|
+
export const newPolicyContentName = ovalContents.nodes[1].name;
|
12
|
+
export const newPolicyContentId = ovalContents.nodes[1].id;
|
13
|
+
const hostgroupId = 3;
|
14
|
+
|
15
|
+
const createPolicyMockFactory = mockFactory(
|
16
|
+
'createOvalPolicy',
|
17
|
+
createOvalPolicy
|
18
|
+
);
|
19
|
+
const hostgroupsMockFactory = mockFactory('hostgroups', hostgroupsQuery);
|
20
|
+
|
21
|
+
const foremanAnsiblePresent = {
|
22
|
+
id: 'foreman_ansible_present',
|
23
|
+
errors: null,
|
24
|
+
failMsg: null,
|
25
|
+
result: 'pass',
|
26
|
+
};
|
27
|
+
const rolePresent = {
|
28
|
+
id: 'foreman_scap_client_role_present',
|
29
|
+
errors: null,
|
30
|
+
failMsg: null,
|
31
|
+
result: 'pass',
|
32
|
+
};
|
33
|
+
const roleVarsPresent = {
|
34
|
+
id: 'foreman_scap_client_vars_present',
|
35
|
+
errors: null,
|
36
|
+
failMsg: null,
|
37
|
+
result: 'pass',
|
38
|
+
};
|
39
|
+
const serverVarOverriden = {
|
40
|
+
id: 'foreman_scap_client_server_overriden',
|
41
|
+
errors: null,
|
42
|
+
failMsg: null,
|
43
|
+
result: 'pass',
|
44
|
+
};
|
45
|
+
const portVarOverriden = {
|
46
|
+
id: 'foreman_scap_client_port_overriden',
|
47
|
+
errors: null,
|
48
|
+
failMsg: null,
|
49
|
+
result: 'pass',
|
50
|
+
};
|
51
|
+
const policiesVarOverriden = {
|
52
|
+
id: 'foreman_scap_client_policies_overriden',
|
53
|
+
errors: null,
|
54
|
+
failMsg: null,
|
55
|
+
result: 'pass',
|
56
|
+
};
|
57
|
+
const policyErrors = {
|
58
|
+
id: 'oval_policy_errors',
|
59
|
+
errors: { name: 'has already been taken' },
|
60
|
+
failMsg: null,
|
61
|
+
result: 'fail',
|
62
|
+
};
|
63
|
+
export const hgWithoutProxy = {
|
64
|
+
id: 'hostgroups_without_proxy',
|
65
|
+
errors: null,
|
66
|
+
failMsg: 'Assign openscap_proxy to first hostgroup before proceeding.',
|
67
|
+
result: 'fail',
|
68
|
+
};
|
69
|
+
export const roleAbsent = {
|
70
|
+
id: 'foreman_scap_client_role_present',
|
71
|
+
errors: null,
|
72
|
+
failMsg:
|
73
|
+
'theforeman.foreman_scap_client Ansible Role not found, please import it before running this action again.',
|
74
|
+
result: 'fail',
|
75
|
+
};
|
76
|
+
|
77
|
+
const varChecks = [
|
78
|
+
roleVarsPresent,
|
79
|
+
serverVarOverriden,
|
80
|
+
portVarOverriden,
|
81
|
+
policiesVarOverriden,
|
82
|
+
];
|
83
|
+
const checkCollectionPass = [foremanAnsiblePresent, rolePresent, ...varChecks];
|
84
|
+
const checkCollectionPreconditionFail = [
|
85
|
+
foremanAnsiblePresent,
|
86
|
+
roleAbsent,
|
87
|
+
...varChecks.map(check => ({ ...check, result: 'skip' })),
|
88
|
+
];
|
89
|
+
const ovalPolicy = {
|
90
|
+
name: newPolicyName,
|
91
|
+
id: 'MDE6Rm9yZW1hbk9wZW5zY2FwOjpPdmFsUG9saWN5LTcw',
|
92
|
+
period: 'custom',
|
93
|
+
cronLine: newPolicyCronline,
|
94
|
+
hostgroups: {
|
95
|
+
nodes: [],
|
96
|
+
},
|
97
|
+
};
|
98
|
+
|
99
|
+
const policyCreateSuccess = {
|
100
|
+
checkCollection: checkCollectionPass,
|
101
|
+
ovalPolicy,
|
102
|
+
};
|
103
|
+
|
104
|
+
const baseVariables = {
|
105
|
+
name: newPolicyName,
|
106
|
+
description: '',
|
107
|
+
ovalContentId: decodeId(newPolicyContentId),
|
108
|
+
cronLine: newPolicyCronline,
|
109
|
+
hostgroupIds: [],
|
110
|
+
period: 'custom',
|
111
|
+
};
|
112
|
+
|
113
|
+
export const firstHg = {
|
114
|
+
id: 'MDE6SG9zdGdyb3VwLTM=',
|
115
|
+
name: 'first hostgroup',
|
116
|
+
};
|
117
|
+
|
118
|
+
const successVariables = {
|
119
|
+
...baseVariables,
|
120
|
+
description: newPolicyDescription,
|
121
|
+
};
|
122
|
+
|
123
|
+
export const policySuccessMock = createPolicyMockFactory(
|
124
|
+
successVariables,
|
125
|
+
policyCreateSuccess
|
126
|
+
);
|
127
|
+
|
128
|
+
export const policyValidationMock = createPolicyMockFactory(baseVariables, {
|
129
|
+
checkCollection: [...checkCollectionPass, policyErrors],
|
130
|
+
ovalPolicy,
|
131
|
+
});
|
132
|
+
|
133
|
+
export const policyPreconditionMock = createPolicyMockFactory(baseVariables, {
|
134
|
+
checkCollection: checkCollectionPreconditionFail,
|
135
|
+
ovalPolicy,
|
136
|
+
});
|
137
|
+
|
138
|
+
export const policyInvalidHgMock = createPolicyMockFactory(
|
139
|
+
{ ...baseVariables, hostgroupIds: [hostgroupId] },
|
140
|
+
{ checkCollection: [...checkCollectionPass, hgWithoutProxy], ovalPolicy }
|
141
|
+
);
|
142
|
+
|
143
|
+
export const hostgroupsMock = hostgroupsMockFactory(
|
144
|
+
{ search: `name ~ first` },
|
145
|
+
{ totalCount: 2, nodes: [firstHg] },
|
146
|
+
{ currentUser: admin }
|
147
|
+
);
|