foreman_ansible 6.4.1 → 7.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/api/v2/ansible_inventories_controller.rb +1 -1
- data/app/graphql/mutations/ansible_variable_overrides/create.rb +26 -0
- data/app/graphql/mutations/ansible_variable_overrides/delete.rb +38 -0
- data/app/graphql/mutations/ansible_variable_overrides/update.rb +26 -0
- data/app/graphql/mutations/hosts/assign_ansible_roles.rb +37 -0
- data/app/graphql/presenters/ansible_role_presenter.rb +12 -0
- data/app/graphql/presenters/overriden_ansible_variable_presenter.rb +19 -0
- data/app/graphql/types/ansible_role.rb +9 -0
- data/app/graphql/types/ansible_variable.rb +23 -0
- data/app/graphql/types/ansible_variable_override.rb +9 -0
- data/app/graphql/types/inherited_ansible_role.rb +13 -0
- data/app/graphql/types/overriden_ansible_variable.rb +27 -0
- data/app/helpers/foreman_ansible/ansible_roles_data_preparations.rb +22 -22
- data/app/models/concerns/foreman_ansible/host_managed_extensions.rb +23 -4
- data/app/models/concerns/foreman_ansible/hostgroup_extensions.rb +2 -1
- data/app/models/foreman_ansible/ansible_provider.rb +7 -5
- data/app/services/foreman_ansible/ansible_report_importer.rb +2 -2
- data/app/services/foreman_ansible/inventory_creator.rb +1 -1
- data/app/services/foreman_ansible/override_resolver.rb +22 -0
- data/app/views/api/v2/ansible_override_values/index.json.rabl +3 -0
- data/app/views/api/v2/ansible_variables/show.json.rabl +1 -1
- data/app/views/foreman_ansible/ansible_roles/_hostgroup_ansible_roles_button.erb +3 -0
- data/app/views/foreman_ansible/job_templates/convert_to_rhel.erb +6 -2
- data/app/views/foreman_ansible/job_templates/run_openscap_scans_-_ansible_default.erb +20 -0
- data/config/routes.rb +3 -0
- data/db/migrate/20210818083407_fix_ansible_setting_category_to_dsl.rb +5 -0
- data/lib/foreman_ansible/engine.rb +0 -17
- data/lib/foreman_ansible/register.rb +115 -4
- data/lib/foreman_ansible/version.rb +1 -1
- data/package.json +4 -2
- data/test/functional/api/v2/ansible_inventories_controller_test.rb +1 -2
- data/test/graphql/mutations/hosts/assign_ansible_roles_mutation_test.rb +96 -0
- data/test/graphql/queries/ansible_roles_query_test.rb +35 -0
- data/test/unit/ansible_provider_test.rb +3 -6
- data/test/unit/concerns/host_managed_extensions_test.rb +8 -0
- data/test/unit/concerns/hostgroup_extensions_test.rb +6 -0
- data/test/unit/hostgroup_ansible_role_test.rb +13 -0
- data/test/unit/services/override_resolver_test.rb +34 -0
- data/webpack/components/AnsibleHostDetail/AnsibleHostDetail.js +51 -27
- data/webpack/components/AnsibleHostDetail/AnsibleHostDetail.test.js +12 -6
- data/webpack/components/AnsibleHostDetail/components/AnsibleHostInventory/AnsibleHostInventory.js +22 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleHostInventory/AnsibleHostInventory.scss +4 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleHostInventory/AnsibleHostInventory.test.js +104 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleHostInventory/index.js +38 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/AnsibleVariableOverrides.scss +3 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/AnsibleVariableOverridesTable.js +238 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/AnsibleVariableOverridesTableHelper.js +111 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/EditableAction.js +161 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/EditableAction.scss +7 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/EditableActionHelper.js +49 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/EditableValue.js +70 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/EditableValueHelper.js +35 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/__test__/AnsibleVariableOverrides.fixtures.js +429 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/__test__/AnsibleVariableOverrides.test.js +71 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/__test__/AnsibleVariableOverridesDelete.test.js +74 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/__test__/AnsibleVariableOverridesUpdate.test.js +188 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/index.js +58 -0
- data/webpack/components/AnsibleHostDetail/components/JobsTab/JobsTabHelper.js +79 -0
- data/webpack/components/AnsibleHostDetail/components/JobsTab/NewRecurringJobHelper.js +106 -0
- data/webpack/components/AnsibleHostDetail/components/JobsTab/NewRecurringJobModal.js +129 -0
- data/webpack/components/AnsibleHostDetail/components/JobsTab/NewRecurringJobModal.scss +7 -0
- data/webpack/components/AnsibleHostDetail/components/JobsTab/PreviousJobsTable.js +103 -0
- data/webpack/components/AnsibleHostDetail/components/JobsTab/RecurringJobsTable.js +96 -0
- data/webpack/components/AnsibleHostDetail/components/JobsTab/__test__/JobsTab.fixtures.js +184 -0
- data/webpack/components/AnsibleHostDetail/components/JobsTab/__test__/JobsTab.test.js +195 -0
- data/webpack/components/AnsibleHostDetail/components/JobsTab/index.js +88 -0
- data/webpack/components/AnsibleHostDetail/components/RolesTab/AllRolesModal/AllRolesTable.js +89 -0
- data/webpack/components/AnsibleHostDetail/components/RolesTab/AllRolesModal/index.js +80 -0
- data/webpack/components/AnsibleHostDetail/components/RolesTab/EditRolesModal/EditRolesForm.js +90 -0
- data/webpack/components/AnsibleHostDetail/components/RolesTab/EditRolesModal/EditRolesModal.scss +3 -0
- data/webpack/components/AnsibleHostDetail/components/RolesTab/EditRolesModal/EditRolesModalHelper.js +40 -0
- data/webpack/components/AnsibleHostDetail/components/RolesTab/EditRolesModal/index.js +82 -0
- data/webpack/components/AnsibleHostDetail/components/RolesTab/RolesTable.js +129 -0
- data/webpack/components/AnsibleHostDetail/components/RolesTab/__test__/EditRoles.test.js +85 -0
- data/webpack/components/AnsibleHostDetail/components/RolesTab/__test__/RolesTab.fixtures.js +180 -0
- data/webpack/components/AnsibleHostDetail/components/RolesTab/__test__/RolesTab.test.js +75 -0
- data/webpack/components/AnsibleHostDetail/components/RolesTab/index.js +51 -0
- data/webpack/components/AnsibleHostDetail/components/SecondaryTabRoutes.js +60 -0
- data/webpack/components/AnsibleHostDetail/components/TabLayout.js +12 -0
- data/webpack/components/AnsibleHostDetail/constants.js +9 -0
- data/webpack/components/AnsibleHostDetail/helpers.js +4 -0
- data/webpack/components/AnsibleRolesAndVariables/__test__/AnsibleRolesAndVariablesImport.test.js +15 -10
- data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRole.js +29 -0
- data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRole.test.js +3 -0
- data/webpack/components/AnsibleRolesSwitcher/components/AvailableRolesList.js +2 -1
- data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AnsibleRole.test.js.snap +3 -3
- data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AvailableRolesList.test.js.snap +4 -0
- data/webpack/components/DualList/DualList.scss +3 -0
- data/webpack/components/DualList/ListControls.js +65 -0
- data/webpack/components/DualList/ListHeader.js +16 -0
- data/webpack/components/DualList/ListItem.js +69 -0
- data/webpack/components/DualList/ListPane.js +95 -0
- data/webpack/components/DualList/SelectedStatus.js +21 -0
- data/webpack/components/DualList/index.js +103 -0
- data/webpack/components/ErrorState.js +16 -0
- data/webpack/components/withLoading.js +135 -0
- data/webpack/components/withPagination.js +0 -0
- data/webpack/formHelper.js +131 -0
- data/webpack/globalIdHelper.js +13 -0
- data/webpack/global_index.js +7 -1
- data/webpack/graphql/mutations/assignAnsibleRoles.gql +17 -0
- data/webpack/graphql/mutations/cancelRecurringLogic.gql +12 -0
- data/webpack/graphql/mutations/createAnsibleVariableOverride.gql +28 -0
- data/webpack/graphql/mutations/createJobInvocation.gql +11 -0
- data/webpack/graphql/mutations/deleteAnsibleVariableOverride.gql +17 -0
- data/webpack/graphql/mutations/updateAnsibleVariableOverride.gql +29 -0
- data/webpack/graphql/queries/allAnsibleRoles.gql +13 -0
- data/webpack/graphql/queries/ansibleRoles.gql +13 -0
- data/webpack/graphql/queries/currentUserAttributes.gql +11 -0
- data/webpack/graphql/queries/hostAnsibleRoles.gql +17 -0
- data/webpack/graphql/queries/hostAvailableAnsibleRoles.gql +11 -0
- data/webpack/graphql/queries/hostVariableOverrides.gql +39 -0
- data/webpack/graphql/queries/recurringJobs.gql +28 -0
- data/webpack/helpers/pageParamsHelper.js +40 -0
- data/webpack/helpers/paginationHelper.js +9 -0
- data/webpack/permissionsHelper.js +58 -0
- data/webpack/routes/HostgroupJobs/__test__/HostgroupJobs.fixtures.js +63 -0
- data/webpack/routes/HostgroupJobs/__test__/HostgroupJobs.test.js +112 -0
- data/webpack/routes/HostgroupJobs/index.js +26 -0
- data/webpack/routes/routes.js +10 -0
- data/webpack/testHelper.js +165 -0
- data/webpack/toastHelper.js +4 -0
- metadata +127 -54
- data/app/assets/images/foreman_ansible/Ansible.png +0 -0
- data/app/models/foreman_ansible/fact_name.rb +0 -16
- data/app/models/setting/ansible.rb +0 -106
- data/app/services/foreman_ansible/fact_importer.rb +0 -99
- data/app/services/foreman_ansible/fact_parser.rb +0 -126
- data/app/services/foreman_ansible/fact_sparser.rb +0 -37
- data/app/services/foreman_ansible/operating_system_parser.rb +0 -102
- data/app/services/foreman_ansible/structured_fact_importer.rb +0 -25
- data/test/unit/services/fact_importer_test.rb +0 -52
- data/test/unit/services/fact_parser_test.rb +0 -281
- data/test/unit/services/fact_sparser_test.rb +0 -24
- data/test/unit/services/structured_fact_importer_test.rb +0 -30
- data/webpack/components/AnsibleRolesAndVariables/__test__/__snapshots__/AnsibleRolesAndVariablesImport.test.js.snap +0 -177
@@ -0,0 +1,49 @@
|
|
1
|
+
import { translate as __, sprintf } from 'foremanReact/common/I18n';
|
2
|
+
import { showToast } from '../../../../toastHelper';
|
3
|
+
|
4
|
+
export const formatError = error =>
|
5
|
+
sprintf(
|
6
|
+
__(
|
7
|
+
'There was a following error when changing Ansible variable override: %s'
|
8
|
+
),
|
9
|
+
error
|
10
|
+
);
|
11
|
+
|
12
|
+
export const joinErrors = errors => errors.map(err => err.message).join(', ');
|
13
|
+
|
14
|
+
export const onCompleted = (
|
15
|
+
dataPath,
|
16
|
+
onValidationError,
|
17
|
+
toggleWorking,
|
18
|
+
onSubmitSuccess
|
19
|
+
) => data => {
|
20
|
+
const { errors, overridenAnsibleVariable } = data[dataPath];
|
21
|
+
if (Array.isArray(errors) && errors.length > 0) {
|
22
|
+
if (
|
23
|
+
errors.length === 1 &&
|
24
|
+
errors[0].path.join(' ') === 'attributes value'
|
25
|
+
) {
|
26
|
+
onValidationError(errors[0].message);
|
27
|
+
} else {
|
28
|
+
toggleWorking(false);
|
29
|
+
showToast({
|
30
|
+
type: 'error',
|
31
|
+
message: formatError(joinErrors(errors)),
|
32
|
+
});
|
33
|
+
}
|
34
|
+
} else {
|
35
|
+
onSubmitSuccess(overridenAnsibleVariable.currentValue.value);
|
36
|
+
showToast({
|
37
|
+
type: 'success',
|
38
|
+
message: __('Ansible variable override successfully changed.'),
|
39
|
+
});
|
40
|
+
}
|
41
|
+
};
|
42
|
+
|
43
|
+
export const onError = toggleWorking => error => {
|
44
|
+
toggleWorking(false);
|
45
|
+
showToast({ type: 'error', message: formatError(error.message) });
|
46
|
+
};
|
47
|
+
|
48
|
+
export const hasError = state => state.validation.key === 'error';
|
49
|
+
export const createMatcher = value => `fqdn=${value}`;
|
data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/EditableValue.js
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
4
|
+
|
5
|
+
import { formatValue } from './AnsibleVariableOverridesTableHelper';
|
6
|
+
|
7
|
+
import {
|
8
|
+
TextAreaField,
|
9
|
+
TextInputField,
|
10
|
+
SelectField,
|
11
|
+
} from './EditableValueHelper';
|
12
|
+
|
13
|
+
const EditableValue = props => {
|
14
|
+
if (!props.editing) {
|
15
|
+
return formatValue(props.variable);
|
16
|
+
}
|
17
|
+
|
18
|
+
const type = props.variable.parameterType;
|
19
|
+
|
20
|
+
if (type === 'array' || type === 'hash') {
|
21
|
+
return (
|
22
|
+
<TextAreaField
|
23
|
+
onChange={props.onChange}
|
24
|
+
value={props.value}
|
25
|
+
validation={props.validation}
|
26
|
+
isDisabled={props.working}
|
27
|
+
/>
|
28
|
+
);
|
29
|
+
}
|
30
|
+
|
31
|
+
if (type === 'boolean') {
|
32
|
+
return (
|
33
|
+
<SelectField
|
34
|
+
selectItems={[
|
35
|
+
{ id: 'trueSelectOpt', value: true, name: __('true') },
|
36
|
+
{ id: 'falseSelectOpt', value: false, name: __('false') },
|
37
|
+
]}
|
38
|
+
onChange={props.onChange}
|
39
|
+
validation={props.validation}
|
40
|
+
isDisabled={props.working}
|
41
|
+
value={props.value}
|
42
|
+
/>
|
43
|
+
);
|
44
|
+
}
|
45
|
+
|
46
|
+
return (
|
47
|
+
<TextInputField
|
48
|
+
onChange={props.onChange}
|
49
|
+
value={props.value}
|
50
|
+
validation={props.validation}
|
51
|
+
isDisabled={props.working}
|
52
|
+
aria-label="Edit override field"
|
53
|
+
/>
|
54
|
+
);
|
55
|
+
};
|
56
|
+
|
57
|
+
EditableValue.propTypes = {
|
58
|
+
editing: PropTypes.bool.isRequired,
|
59
|
+
variable: PropTypes.object.isRequired,
|
60
|
+
onChange: PropTypes.func.isRequired,
|
61
|
+
value: PropTypes.any,
|
62
|
+
validation: PropTypes.object.isRequired,
|
63
|
+
working: PropTypes.bool.isRequired,
|
64
|
+
};
|
65
|
+
|
66
|
+
EditableValue.defaultProps = {
|
67
|
+
value: '',
|
68
|
+
};
|
69
|
+
|
70
|
+
export default EditableValue;
|
data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/EditableValueHelper.js
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import {
|
3
|
+
TextInput,
|
4
|
+
TextArea,
|
5
|
+
FormGroup,
|
6
|
+
FormSelect,
|
7
|
+
FormSelectOption,
|
8
|
+
} from '@patternfly/react-core';
|
9
|
+
|
10
|
+
const withFormGroup = Component => componentProps => {
|
11
|
+
const { validation, ...rest } = componentProps;
|
12
|
+
return (
|
13
|
+
<FormGroup
|
14
|
+
label=""
|
15
|
+
helperTextInvalid={validation.msg}
|
16
|
+
validated={validation.key}
|
17
|
+
>
|
18
|
+
<Component {...rest} validated={validation.key} />
|
19
|
+
</FormGroup>
|
20
|
+
);
|
21
|
+
};
|
22
|
+
|
23
|
+
export const SelectField = componentProps => {
|
24
|
+
const { selectItems, ...rest } = componentProps;
|
25
|
+
return (
|
26
|
+
<FormSelect className="without_select2" {...rest}>
|
27
|
+
{selectItems.map(item => (
|
28
|
+
<FormSelectOption key={item.id} value={item.value} label={item.name} />
|
29
|
+
))}
|
30
|
+
</FormSelect>
|
31
|
+
);
|
32
|
+
};
|
33
|
+
|
34
|
+
export const TextInputField = withFormGroup(TextInput);
|
35
|
+
export const TextAreaField = withFormGroup(TextArea);
|
@@ -0,0 +1,429 @@
|
|
1
|
+
/* eslint-disable max-lines */
|
2
|
+
import variableOverridesQuery from '../../../../../graphql/queries/hostVariableOverrides.gql';
|
3
|
+
import deleteAnsibleVariableOverride from '../../../../../graphql/mutations/deleteAnsibleVariableOverride.gql';
|
4
|
+
import updateAnsibleVariableOverride from '../../../../../graphql/mutations/updateAnsibleVariableOverride.gql';
|
5
|
+
import createAnsibleVariableOverride from '../../../../../graphql/mutations/createAnsibleVariableOverride.gql';
|
6
|
+
import { admin } from '../../../../../testHelper';
|
7
|
+
|
8
|
+
export const hostId = 3;
|
9
|
+
const hostGlobalId = 'MDE6SG9zdC0z';
|
10
|
+
const name = 'centos-random.example.com';
|
11
|
+
const match = `fqdn=${name}`;
|
12
|
+
|
13
|
+
export const hostAttrs = {
|
14
|
+
name,
|
15
|
+
};
|
16
|
+
|
17
|
+
const overrideUpdateDeleteId = 'MDE6TG9va3VwVmFsdWUtODQ=';
|
18
|
+
const ansibleVariableId = 'MDE6QW5zaWJsZVZhcmlhYmxlLTY2';
|
19
|
+
const variableId = 66;
|
20
|
+
|
21
|
+
const barVariableGlobalId = 'MDE6QW5zaWJsZVZhcmlhYmxlLTU3Mw==';
|
22
|
+
const barVariableId = 573;
|
23
|
+
|
24
|
+
const withFqdnOverride = canEdit => ({
|
25
|
+
__typename: 'OverridenAnsibleVariable',
|
26
|
+
meta: {
|
27
|
+
__typename: 'Meta',
|
28
|
+
canEdit,
|
29
|
+
},
|
30
|
+
id: ansibleVariableId,
|
31
|
+
key: 'rectangle',
|
32
|
+
defaultValue: 17,
|
33
|
+
parameterType: 'integer',
|
34
|
+
ansibleRoleName: 'test.role',
|
35
|
+
validatorType: '',
|
36
|
+
validatorRule: null,
|
37
|
+
required: false,
|
38
|
+
lookupValues: {
|
39
|
+
nodes: [
|
40
|
+
{
|
41
|
+
__typename: 'LookupValue',
|
42
|
+
id: overrideUpdateDeleteId,
|
43
|
+
match,
|
44
|
+
value: 21,
|
45
|
+
omit: false,
|
46
|
+
},
|
47
|
+
],
|
48
|
+
},
|
49
|
+
currentValue: {
|
50
|
+
__typename: 'AnsibleVariableOverride',
|
51
|
+
value: 21,
|
52
|
+
element: 'fqdn',
|
53
|
+
elementName: name,
|
54
|
+
},
|
55
|
+
});
|
56
|
+
|
57
|
+
const withDomainOverride = canEdit => ({
|
58
|
+
__typename: 'OverridenAnsibleVariable',
|
59
|
+
meta: {
|
60
|
+
__typename: 'Meta',
|
61
|
+
canEdit,
|
62
|
+
},
|
63
|
+
id: 'MDE6QW5zaWJsZVZhcmlhYmxlLTc4',
|
64
|
+
key: 'circle',
|
65
|
+
defaultValue: 'd',
|
66
|
+
parameterType: 'string',
|
67
|
+
ansibleRoleName: 'test.role',
|
68
|
+
validatorType: '',
|
69
|
+
validatorRule: null,
|
70
|
+
required: false,
|
71
|
+
lookupValues: {
|
72
|
+
nodes: [],
|
73
|
+
},
|
74
|
+
currentValue: {
|
75
|
+
__typename: 'AnsibleVariableOverride',
|
76
|
+
value: 'c',
|
77
|
+
element: 'domain',
|
78
|
+
elementName: 'example.com',
|
79
|
+
},
|
80
|
+
});
|
81
|
+
|
82
|
+
export const unauthorizedMocks = [
|
83
|
+
{
|
84
|
+
request: {
|
85
|
+
query: variableOverridesQuery,
|
86
|
+
variables: {
|
87
|
+
id: hostGlobalId,
|
88
|
+
match,
|
89
|
+
first: 20,
|
90
|
+
last: 20,
|
91
|
+
},
|
92
|
+
},
|
93
|
+
result: {
|
94
|
+
data: {
|
95
|
+
currentUser: admin,
|
96
|
+
host: {
|
97
|
+
id: hostGlobalId,
|
98
|
+
ansibleVariablesWithOverrides: {
|
99
|
+
totalCount: 2,
|
100
|
+
nodes: [withFqdnOverride(false), withDomainOverride(false)],
|
101
|
+
},
|
102
|
+
},
|
103
|
+
},
|
104
|
+
},
|
105
|
+
},
|
106
|
+
];
|
107
|
+
|
108
|
+
export const mocks = [
|
109
|
+
{
|
110
|
+
request: {
|
111
|
+
query: variableOverridesQuery,
|
112
|
+
variables: {
|
113
|
+
id: hostGlobalId,
|
114
|
+
match,
|
115
|
+
first: 20,
|
116
|
+
last: 20,
|
117
|
+
},
|
118
|
+
},
|
119
|
+
result: {
|
120
|
+
data: {
|
121
|
+
currentUser: admin,
|
122
|
+
host: {
|
123
|
+
id: hostGlobalId,
|
124
|
+
ansibleVariablesWithOverrides: {
|
125
|
+
totalCount: 8,
|
126
|
+
nodes: [
|
127
|
+
withFqdnOverride(true),
|
128
|
+
{
|
129
|
+
__typename: 'OverridenAnsibleVariable',
|
130
|
+
meta: {
|
131
|
+
__typename: 'Meta',
|
132
|
+
canEdit: true,
|
133
|
+
},
|
134
|
+
id: barVariableGlobalId,
|
135
|
+
key: 'bar',
|
136
|
+
defaultValue: 'a',
|
137
|
+
parameterType: 'string',
|
138
|
+
ansibleRoleName: 'test.role',
|
139
|
+
validatorType: 'list',
|
140
|
+
validatorRule: 'a,b,c',
|
141
|
+
required: true,
|
142
|
+
lookupValues: {
|
143
|
+
nodes: [
|
144
|
+
{
|
145
|
+
__typename: 'LookupValue',
|
146
|
+
id: 'MDE6TG9va3VwVmFsdWUtODE=',
|
147
|
+
match,
|
148
|
+
value: 'b',
|
149
|
+
omit: false,
|
150
|
+
},
|
151
|
+
],
|
152
|
+
},
|
153
|
+
currentValue: null,
|
154
|
+
},
|
155
|
+
{
|
156
|
+
__typename: 'OverridenAnsibleVariable',
|
157
|
+
meta: {
|
158
|
+
__typename: 'Meta',
|
159
|
+
canEdit: true,
|
160
|
+
},
|
161
|
+
id: 'MDE6QW5zaWJsZVZhcmlhYmxlLTY1',
|
162
|
+
key: 'square',
|
163
|
+
defaultValue: true,
|
164
|
+
parameterType: 'boolean',
|
165
|
+
ansibleRoleName: 'test.role',
|
166
|
+
validatorType: '',
|
167
|
+
validatorRule: null,
|
168
|
+
required: false,
|
169
|
+
lookupValues: {
|
170
|
+
nodes: [],
|
171
|
+
},
|
172
|
+
currentValue: null,
|
173
|
+
},
|
174
|
+
{
|
175
|
+
__typename: 'OverridenAnsibleVariable',
|
176
|
+
meta: {
|
177
|
+
__typename: 'Meta',
|
178
|
+
canEdit: true,
|
179
|
+
},
|
180
|
+
id: 'MDE6QW5zaWJsZVZhcmlhYmxlLTc4',
|
181
|
+
key: 'circle',
|
182
|
+
defaultValue: 'd',
|
183
|
+
parameterType: 'string',
|
184
|
+
ansibleRoleName: 'test.role',
|
185
|
+
validatorType: '',
|
186
|
+
validatorRule: null,
|
187
|
+
required: false,
|
188
|
+
lookupValues: {
|
189
|
+
nodes: [],
|
190
|
+
},
|
191
|
+
currentValue: {
|
192
|
+
__typename: 'AnsibleVariableOverride',
|
193
|
+
value: 'c',
|
194
|
+
element: 'domain',
|
195
|
+
elementName: 'example.com',
|
196
|
+
},
|
197
|
+
},
|
198
|
+
{
|
199
|
+
__typename: 'OverridenAnsibleVariable',
|
200
|
+
meta: {
|
201
|
+
__typename: 'Meta',
|
202
|
+
canEdit: true,
|
203
|
+
},
|
204
|
+
id: 'MDE6QW5zaWJsZVZhcmlhYmxlLTc5',
|
205
|
+
key: 'ellipse',
|
206
|
+
defaultValue: ['seven', 'eight'],
|
207
|
+
parameterType: 'array',
|
208
|
+
ansibleRoleName: 'test.role',
|
209
|
+
validatorType: '',
|
210
|
+
validatorRule: null,
|
211
|
+
required: false,
|
212
|
+
lookupValues: {
|
213
|
+
nodes: [],
|
214
|
+
},
|
215
|
+
currentValue: {
|
216
|
+
__typename: 'AnsibleVariableOverride',
|
217
|
+
value: ['nine'],
|
218
|
+
element: 'hostgroup',
|
219
|
+
elementName: 'parent hostgroup',
|
220
|
+
},
|
221
|
+
},
|
222
|
+
{
|
223
|
+
__typename: 'OverridenAnsibleVariable',
|
224
|
+
meta: {
|
225
|
+
__typename: 'Meta',
|
226
|
+
canEdit: true,
|
227
|
+
},
|
228
|
+
id: 'MDE6QW5zaWJsZVZhcmlhYmxlLTY2Ng==',
|
229
|
+
key: 'spiral',
|
230
|
+
defaultValue: { one: 'one', two: 'two' },
|
231
|
+
parameterType: 'hash',
|
232
|
+
ansibleRoleName: 'test.role',
|
233
|
+
validatorType: '',
|
234
|
+
validatorRule: null,
|
235
|
+
required: false,
|
236
|
+
lookupValues: {
|
237
|
+
nodes: [],
|
238
|
+
},
|
239
|
+
currentValue: null,
|
240
|
+
},
|
241
|
+
{
|
242
|
+
__typename: 'OverridenAnsibleVariable',
|
243
|
+
meta: {
|
244
|
+
__typename: 'Meta',
|
245
|
+
canEdit: true,
|
246
|
+
},
|
247
|
+
id: 'MDE6QW5zaWJsZVZhcmlhYmxlLTY3Mg==',
|
248
|
+
key: 'sun',
|
249
|
+
defaultValue: "{ one: 'one', two: 'two' }",
|
250
|
+
parameterType: 'json',
|
251
|
+
ansibleRoleName: 'test.role',
|
252
|
+
validatorType: '',
|
253
|
+
validatorRule: null,
|
254
|
+
required: false,
|
255
|
+
lookupValues: {
|
256
|
+
nodes: [],
|
257
|
+
},
|
258
|
+
currentValue: null,
|
259
|
+
},
|
260
|
+
{
|
261
|
+
__typename: 'OverridenAnsibleVariable',
|
262
|
+
meta: {
|
263
|
+
__typename: 'Meta',
|
264
|
+
canEdit: true,
|
265
|
+
},
|
266
|
+
id: 'MDE6QW5zaWJsZVZhcmlhYmxlLTY3Mw==',
|
267
|
+
key: 'moon',
|
268
|
+
defaultValue: [
|
269
|
+
{ hosts: 'all', become: 'true', roles: ['foo'] },
|
270
|
+
],
|
271
|
+
parameterType: 'yaml',
|
272
|
+
ansibleRoleName: 'test.role',
|
273
|
+
validatorType: '',
|
274
|
+
validatorRule: null,
|
275
|
+
required: false,
|
276
|
+
lookupValues: {
|
277
|
+
nodes: [],
|
278
|
+
},
|
279
|
+
currentValue: null,
|
280
|
+
},
|
281
|
+
],
|
282
|
+
},
|
283
|
+
},
|
284
|
+
},
|
285
|
+
},
|
286
|
+
},
|
287
|
+
];
|
288
|
+
|
289
|
+
export const deleteMocks = [
|
290
|
+
{
|
291
|
+
request: {
|
292
|
+
query: deleteAnsibleVariableOverride,
|
293
|
+
variables: { id: overrideUpdateDeleteId, hostId, variableId },
|
294
|
+
},
|
295
|
+
result: {
|
296
|
+
data: {
|
297
|
+
deleteAnsibleVariableOverride: {
|
298
|
+
errors: [],
|
299
|
+
id: overrideUpdateDeleteId,
|
300
|
+
overridenAnsibleVariable: {
|
301
|
+
__typename: 'OverridenAnsibleVariable',
|
302
|
+
id: ansibleVariableId,
|
303
|
+
currentValue: {
|
304
|
+
__typename: 'AnsibleVariableOverride',
|
305
|
+
element: 'os',
|
306
|
+
elementName: 'CentOS 7.8',
|
307
|
+
value: 101,
|
308
|
+
},
|
309
|
+
},
|
310
|
+
},
|
311
|
+
},
|
312
|
+
},
|
313
|
+
},
|
314
|
+
];
|
315
|
+
|
316
|
+
const updateMockFactory = (variableValue, returnValue, errors = []) => {
|
317
|
+
const mockArray = [
|
318
|
+
{
|
319
|
+
request: {
|
320
|
+
query: updateAnsibleVariableOverride,
|
321
|
+
variables: {
|
322
|
+
id: overrideUpdateDeleteId,
|
323
|
+
hostId,
|
324
|
+
ansibleVariableId: variableId,
|
325
|
+
value: variableValue,
|
326
|
+
match: `fqdn=${hostAttrs.name}`,
|
327
|
+
},
|
328
|
+
},
|
329
|
+
result: {
|
330
|
+
data: {
|
331
|
+
updateAnsibleVariableOverride: {
|
332
|
+
__typename: 'UpdateAnsibleVariableOverrideMutationPayload',
|
333
|
+
overridenAnsibleVariable: {
|
334
|
+
__typename: 'OverridenAnsibleVariable',
|
335
|
+
id: ansibleVariableId,
|
336
|
+
lookupValues: {
|
337
|
+
__typename: 'LookupValueConnection',
|
338
|
+
nodes: [
|
339
|
+
{
|
340
|
+
__typename: 'LookupValue',
|
341
|
+
id: 'MDE6TG9va3VwVmFsdWUtOTY=',
|
342
|
+
match: 'fqdn=centos-random.example.com',
|
343
|
+
value: returnValue,
|
344
|
+
omit: false,
|
345
|
+
},
|
346
|
+
],
|
347
|
+
},
|
348
|
+
currentValue: {
|
349
|
+
__typename: 'AnsibleVariableOverride',
|
350
|
+
element: 'fqdn',
|
351
|
+
elementName: 'centos-random.example.com',
|
352
|
+
value: returnValue,
|
353
|
+
},
|
354
|
+
},
|
355
|
+
errors,
|
356
|
+
},
|
357
|
+
},
|
358
|
+
},
|
359
|
+
},
|
360
|
+
];
|
361
|
+
|
362
|
+
return mockArray;
|
363
|
+
};
|
364
|
+
|
365
|
+
const createMockFactory = (variableValue, returnValue, errors = []) => {
|
366
|
+
const variables = {
|
367
|
+
hostId,
|
368
|
+
lookupKeyId: barVariableId,
|
369
|
+
value: variableValue,
|
370
|
+
match: `fqdn=${hostAttrs.name}`,
|
371
|
+
};
|
372
|
+
|
373
|
+
const mockArray = [
|
374
|
+
{
|
375
|
+
request: {
|
376
|
+
query: createAnsibleVariableOverride,
|
377
|
+
variables,
|
378
|
+
},
|
379
|
+
result: {
|
380
|
+
data: {
|
381
|
+
createAnsibleVariableOverride: {
|
382
|
+
overridenAnsibleVariable: {
|
383
|
+
__typename: 'OverridenAnsibleVariable',
|
384
|
+
id: ansibleVariableId,
|
385
|
+
lookupValues: {
|
386
|
+
nodes: [
|
387
|
+
{
|
388
|
+
__typename: 'LookupValue',
|
389
|
+
id: 'MDE6TG9va3VwVmFsdWUtOTY=',
|
390
|
+
match: 'fqdn=centos-random.example.com',
|
391
|
+
value: returnValue,
|
392
|
+
omit: false,
|
393
|
+
},
|
394
|
+
],
|
395
|
+
},
|
396
|
+
currentValue: {
|
397
|
+
__typename: 'AnsibleVariableOverride',
|
398
|
+
element: 'fqdn',
|
399
|
+
elementName: 'centos-random.example.com',
|
400
|
+
value: returnValue,
|
401
|
+
},
|
402
|
+
},
|
403
|
+
errors,
|
404
|
+
},
|
405
|
+
},
|
406
|
+
},
|
407
|
+
},
|
408
|
+
];
|
409
|
+
|
410
|
+
return mockArray;
|
411
|
+
};
|
412
|
+
|
413
|
+
export const updateMocks = updateMockFactory('2177', 2177);
|
414
|
+
export const createMocks = createMockFactory('b', 'b');
|
415
|
+
export const updateErrorMocks = updateMockFactory('2177', 21, [
|
416
|
+
{
|
417
|
+
path: ['base'],
|
418
|
+
message: 'Not enough minerals',
|
419
|
+
__typename: 'AttributeError',
|
420
|
+
},
|
421
|
+
]);
|
422
|
+
|
423
|
+
export const updateValidationMocks = updateMockFactory('foo', 21, [
|
424
|
+
{
|
425
|
+
path: ['attributes', 'value'],
|
426
|
+
message: 'is invalid integer',
|
427
|
+
__typename: 'AttributeError',
|
428
|
+
},
|
429
|
+
]);
|
@@ -0,0 +1,71 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { render, screen, waitFor } from '@testing-library/react';
|
3
|
+
import '@testing-library/jest-dom';
|
4
|
+
|
5
|
+
import AnsibleVariableOverrides from '../';
|
6
|
+
import {
|
7
|
+
mocks,
|
8
|
+
unauthorizedMocks,
|
9
|
+
hostId,
|
10
|
+
hostAttrs,
|
11
|
+
} from './AnsibleVariableOverrides.fixtures';
|
12
|
+
import {
|
13
|
+
withMockedProvider,
|
14
|
+
withRedux,
|
15
|
+
tick,
|
16
|
+
historyMock,
|
17
|
+
} from '../../../../../testHelper';
|
18
|
+
|
19
|
+
const TestComponent = withRedux(withMockedProvider(AnsibleVariableOverrides));
|
20
|
+
|
21
|
+
describe('AnsibleVariableOverrides', () => {
|
22
|
+
it('should show skeleton when page is loading', () => {
|
23
|
+
const { container } = render(
|
24
|
+
<TestComponent
|
25
|
+
hostId={hostId}
|
26
|
+
hostAttrs={hostAttrs}
|
27
|
+
mocks={mocks}
|
28
|
+
history={historyMock}
|
29
|
+
/>
|
30
|
+
);
|
31
|
+
expect(
|
32
|
+
container.getElementsByClassName('react-loading-skeleton')
|
33
|
+
).toHaveLength(5);
|
34
|
+
});
|
35
|
+
it('should load', async () => {
|
36
|
+
render(
|
37
|
+
<TestComponent
|
38
|
+
hostId={hostId}
|
39
|
+
mocks={mocks}
|
40
|
+
hostAttrs={hostAttrs}
|
41
|
+
history={historyMock}
|
42
|
+
/>
|
43
|
+
);
|
44
|
+
await waitFor(tick);
|
45
|
+
expect(screen.getByText('rectangle')).toBeInTheDocument();
|
46
|
+
expect(screen.getByText('square')).toBeInTheDocument();
|
47
|
+
expect(screen.getByText('circle')).toBeInTheDocument();
|
48
|
+
expect(screen.getByText('ellipse')).toBeInTheDocument();
|
49
|
+
expect(screen.getByText('sun')).toBeInTheDocument();
|
50
|
+
expect(screen.getByText('moon')).toBeInTheDocument();
|
51
|
+
});
|
52
|
+
it('should not allow editing when user does not have permissions', async () => {
|
53
|
+
render(
|
54
|
+
<TestComponent
|
55
|
+
hostId={hostId}
|
56
|
+
mocks={unauthorizedMocks}
|
57
|
+
hostAttrs={hostAttrs}
|
58
|
+
history={historyMock}
|
59
|
+
/>
|
60
|
+
);
|
61
|
+
await waitFor(tick);
|
62
|
+
expect(screen.getByText('rectangle')).toBeInTheDocument();
|
63
|
+
expect(screen.getByText('circle')).toBeInTheDocument();
|
64
|
+
const editBtns = screen.queryAllByRole('button', {
|
65
|
+
name: 'Edit override button',
|
66
|
+
});
|
67
|
+
expect(editBtns).toHaveLength(0);
|
68
|
+
const actions = screen.queryAllByRole('button', { name: 'Actions' });
|
69
|
+
expect(actions).toHaveLength(0);
|
70
|
+
});
|
71
|
+
});
|