foreman_ansible 9.0.1 → 10.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.
- checksums.yaml +4 -4
- data/app/graphql/types/ansible_variable_override.rb +1 -1
- data/app/helpers/foreman_ansible/ansible_hostgroups_helper.rb +1 -1
- data/lib/foreman_ansible/register.rb +2 -2
- data/lib/foreman_ansible/version.rb +1 -1
- data/package.json +0 -1
- data/test/graphql/mutations/hosts/assign_ansible_roles_mutation_test.rb +7 -7
- data/test/integration/hostgroup_js_test.rb +30 -0
- data/webpack/components/AnsibleHostDetail/AnsibleHostDetail.js +1 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/AnsibleVariableOverridesTable.js +10 -4
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/AnsibleVariableOverridesTableHelper.js +1 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/EditableAction.js +3 -0
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/EditableValue.js +4 -2
- data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/EditableValueHelper.js +5 -1
- data/webpack/components/AnsibleHostDetail/components/JobsTab/NewRecurringJobModal.js +3 -0
- data/webpack/components/AnsibleHostDetail/components/JobsTab/PreviousJobsTable.js +10 -4
- data/webpack/components/AnsibleHostDetail/components/JobsTab/RecurringJobsTable.js +3 -3
- data/webpack/components/AnsibleHostDetail/components/JobsTab/index.js +5 -1
- data/webpack/components/AnsibleHostDetail/components/RolesTab/AllRolesModal/AllRolesTable.js +10 -4
- data/webpack/components/AnsibleHostDetail/components/RolesTab/AllRolesModal/index.js +1 -0
- data/webpack/components/AnsibleHostDetail/components/RolesTab/EditRolesModal/EditRolesForm.js +2 -1
- data/webpack/components/AnsibleHostDetail/components/RolesTab/EditRolesModal/index.js +7 -1
- data/webpack/components/AnsibleHostDetail/components/RolesTab/RolesTable.js +14 -5
- data/webpack/components/AnsibleHostDetail/components/RolesTab/__test__/EditRoles.test.js +2 -1
- data/webpack/components/AnsibleHostDetail/components/RolesTab/__test__/RolesTab.test.js +3 -1
- data/webpack/components/AnsibleHostDetail/components/RolesTab/index.js +27 -2
- data/webpack/components/AnsibleHostDetail/components/SecondaryTabRoutes.js +1 -1
- data/webpack/testHelper.js +12 -3
- metadata +8 -7
- data/lib/foreman_ansible/register.rb.orig +0 -257
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 98a2c9aa6bcc8e2feb5b8eee62d111926d0dab191561f808399587d7462debbc
|
4
|
+
data.tar.gz: 2fc48fc5f59725cd8000229bdf08e68f5e8e53a1158271ce2d6db3766ab5826b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a8be9228e0b1532cdbef43e88b0f7ba84f9bd8edc5a9d9e21e1ee6d601f63bbccf16eff5e146f33d18ea06d7cdd5adc528d310d7ddb723ff3a6b91ce3a6774c6
|
7
|
+
data.tar.gz: 35b55ca402a155fae45abd89c6fecde949d133e50b855473a25dba13df9452a13a5b9342b93e49fefd553902909a565dd59f9d57afb07d4f8efec6f0311057a9
|
@@ -4,7 +4,7 @@ module ForemanAnsible
|
|
4
4
|
module AnsibleHostgroupsHelper
|
5
5
|
def ansible_hostgroups_actions(hostgroup)
|
6
6
|
play_roles = if hostgroup.all_ansible_roles.empty?
|
7
|
-
{ action: (link_to _('Run all Ansible roles'), 'javascript:void(0);', disabled: true, title: 'No
|
7
|
+
{ action: { content: (link_to _('Run all Ansible roles'), 'javascript:void(0);', disabled: true, title: 'No roles assigned', class: 'disabled'), options: { class: 'disabled' } }, priority: 31 }
|
8
8
|
else
|
9
9
|
{ action: display_link_if_authorized(_('Run all Ansible roles'), hash_for_play_roles_hostgroup_path(id: hostgroup), 'data-no-turbolink': true, title: _('Run all Ansible roles on hosts belonging to this host group')), priority: 31 }
|
10
10
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
Foreman::Plugin.register :foreman_ansible do
|
4
|
-
requires_foreman '>= 3.
|
4
|
+
requires_foreman '>= 3.5'
|
5
5
|
|
6
6
|
settings do
|
7
7
|
category :ansible, N_('Ansible') do
|
@@ -188,7 +188,7 @@ Foreman::Plugin.register :foreman_ansible do
|
|
188
188
|
register_global_js_file 'global'
|
189
189
|
|
190
190
|
extend_graphql_type :type => '::Types::Host' do
|
191
|
-
field :all_ansible_roles, ::Types::InheritedAnsibleRole.connection_type, :null => true, :
|
191
|
+
field :all_ansible_roles, ::Types::InheritedAnsibleRole.connection_type, :null => true, :resolver_method => :present_all_ansible_roles
|
192
192
|
field :own_ansible_roles, ::Types::AnsibleRole.connection_type, :null => true
|
193
193
|
field :available_ansible_roles, ::Types::AnsibleRole.connection_type, :null => true
|
194
194
|
field :ansible_variables_with_overrides, Types::OverridenAnsibleVariable.connection_type, :null => false
|
data/package.json
CHANGED
@@ -3,15 +3,15 @@ require 'test_plugin_helper'
|
|
3
3
|
module Mutations
|
4
4
|
module Hosts
|
5
5
|
class CreateMutationTest < GraphQLQueryTestCase
|
6
|
-
let(:tax_location) { FactoryBot.create(:location) }
|
6
|
+
let(:tax_location) { as_admin { FactoryBot.create(:location) } }
|
7
7
|
let(:location_id) { Foreman::GlobalId.for(tax_location) }
|
8
|
-
let(:organization) { FactoryBot.create(:organization) }
|
8
|
+
let(:organization) { as_admin { FactoryBot.create(:organization) } }
|
9
9
|
let(:organization_id) { Foreman::GlobalId.for(organization) }
|
10
10
|
|
11
|
-
let(:role1) { FactoryBot.create(:ansible_role) }
|
12
|
-
let(:role2) { FactoryBot.create(:ansible_role) }
|
13
|
-
let(:role3) { FactoryBot.create(:ansible_role) }
|
14
|
-
let(:host) { FactoryBot.create(:host, :ansible_roles => [role1, role2, role3], :organization => organization, :location => tax_location) }
|
11
|
+
let(:role1) { as_admin { FactoryBot.create(:ansible_role) } }
|
12
|
+
let(:role2) { as_admin { FactoryBot.create(:ansible_role) } }
|
13
|
+
let(:role3) { as_admin { FactoryBot.create(:ansible_role) } }
|
14
|
+
let(:host) { as_admin { FactoryBot.create(:host, :ansible_roles => [role1, role2, role3], :organization => organization, :location => tax_location) } }
|
15
15
|
|
16
16
|
let(:variables) { { id: Foreman::GlobalId.for(host), ansibleRoleIds: [role3.id, role2.id, role1.id] } }
|
17
17
|
let(:query) do
|
@@ -37,7 +37,7 @@ module Mutations
|
|
37
37
|
end
|
38
38
|
|
39
39
|
context 'with admin permissions' do
|
40
|
-
let(:context_user) { FactoryBot.create(:user, :admin) }
|
40
|
+
let(:context_user) { as_admin { FactoryBot.create(:user, :admin) } }
|
41
41
|
let(:data) { result['data']['assignAnsibleRoles']['host'] }
|
42
42
|
|
43
43
|
it 'reorderes ansible roles' do
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require_relative '../test_plugin_helper'
|
2
|
+
require 'integration_test_helper'
|
3
|
+
|
4
|
+
class HostgroupJsTest < IntegrationTestWithJavascript
|
5
|
+
let(:hostgroup) { FactoryBot.create(:hostgroup, :name => 'HostgroupWithoutRoles') }
|
6
|
+
let(:hostgroup_with_roles) { FactoryBot.create(:hostgroup, :with_ansible_roles, :name => 'HostgroupWithRoles') }
|
7
|
+
|
8
|
+
setup do
|
9
|
+
FactoryBot.create(:host, :hostgroup_id => hostgroup.id)
|
10
|
+
FactoryBot.create(:host, :hostgroup_id => hostgroup_with_roles.id)
|
11
|
+
end
|
12
|
+
|
13
|
+
test 'hostgroup without roles should have disabled link' do
|
14
|
+
visit hostgroups_path(search: hostgroup.name)
|
15
|
+
|
16
|
+
first_row = page.find('table > tbody > tr:nth-child(1)')
|
17
|
+
first_row.find('td:nth-child(4) > div > a').click
|
18
|
+
|
19
|
+
assert_includes first(:link, 'Run all Ansible roles')[:class], 'disabled'
|
20
|
+
end
|
21
|
+
|
22
|
+
test 'hostgroup with roles should have clickable link' do
|
23
|
+
visit hostgroups_path(search: hostgroup_with_roles.name)
|
24
|
+
|
25
|
+
first_row = page.find('table > tbody > tr:nth-child(1)')
|
26
|
+
first_row.find('td:nth-child(4) > div > a').click
|
27
|
+
|
28
|
+
assert_not first(:link, 'Run all Ansible roles')[:class].include?('disabled')
|
29
|
+
end
|
30
|
+
end
|
@@ -148,12 +148,17 @@ const AnsibleVariableOverridesTable = ({
|
|
148
148
|
<React.Fragment>
|
149
149
|
<Flex direction={{ default: 'column' }}>
|
150
150
|
<FlexItem align={{ default: 'alignRight' }}>
|
151
|
-
<Pagination
|
151
|
+
<Pagination
|
152
|
+
ouiaId="pagination-top"
|
153
|
+
updateParamsByUrl
|
154
|
+
itemCount={totalCount}
|
155
|
+
variant="top"
|
156
|
+
/>
|
152
157
|
</FlexItem>
|
153
158
|
<FlexItem>
|
154
|
-
<TableComposable variant="compact">
|
159
|
+
<TableComposable ouiaId="table-composable-compact" variant="compact">
|
155
160
|
<Thead>
|
156
|
-
<Tr>
|
161
|
+
<Tr ouiaId="row-header">
|
157
162
|
{columns.map(col => (
|
158
163
|
<Th key={col}>{col}</Th>
|
159
164
|
))}
|
@@ -162,7 +167,7 @@ const AnsibleVariableOverridesTable = ({
|
|
162
167
|
</Thead>
|
163
168
|
<Tbody>
|
164
169
|
{variables.map((variable, idx) => (
|
165
|
-
<Tr key={idx}>
|
170
|
+
<Tr key={idx} ouiaId={`row-${idx}`}>
|
166
171
|
<Td>
|
167
172
|
<a href={variable.path}>{variable.key}</a>
|
168
173
|
</Td>
|
@@ -202,6 +207,7 @@ const AnsibleVariableOverridesTable = ({
|
|
202
207
|
</FlexItem>
|
203
208
|
<FlexItem align={{ default: 'alignRight' }}>
|
204
209
|
<Pagination
|
210
|
+
ouiaId="pagination-bottom"
|
205
211
|
updateParamsByUrl
|
206
212
|
itemCount={totalCount}
|
207
213
|
variant="bottom"
|
data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/EditableAction.js
CHANGED
@@ -111,6 +111,7 @@ const EditableAction = ({
|
|
111
111
|
onClick={onClose}
|
112
112
|
isDisabled={state.working}
|
113
113
|
aria-label="Cancel editing override button"
|
114
|
+
ouiaId="cancel-editing-override-button"
|
114
115
|
>
|
115
116
|
<TimesIcon />
|
116
117
|
</Button>
|
@@ -119,6 +120,7 @@ const EditableAction = ({
|
|
119
120
|
onClick={onSubmit}
|
120
121
|
isDisabled={state.working || hasError(state)}
|
121
122
|
aria-label="Submit editing override button"
|
123
|
+
ouiaId="submit-editing-override-button"
|
122
124
|
>
|
123
125
|
<CheckIcon />
|
124
126
|
</Button>
|
@@ -136,6 +138,7 @@ const EditableAction = ({
|
|
136
138
|
onClick={onOpen}
|
137
139
|
variant="plain"
|
138
140
|
aria-label="Edit override button"
|
141
|
+
ouiaId="edit-override-button"
|
139
142
|
>
|
140
143
|
<PencilAltIcon />
|
141
144
|
</Button>
|
data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/EditableValue.js
CHANGED
@@ -17,11 +17,12 @@ const EditableValue = props => {
|
|
17
17
|
|
18
18
|
const type = props.variable.parameterType;
|
19
19
|
|
20
|
-
if (
|
20
|
+
if (['json', 'yaml', 'array', 'hash'].includes(type)) {
|
21
21
|
return (
|
22
22
|
<TextAreaField
|
23
|
+
aria-label="Edit override field"
|
23
24
|
onChange={props.onChange}
|
24
|
-
value={props.value}
|
25
|
+
value={JSON.stringify(props.value)}
|
25
26
|
validation={props.validation}
|
26
27
|
isDisabled={props.working}
|
27
28
|
/>
|
@@ -31,6 +32,7 @@ const EditableValue = props => {
|
|
31
32
|
if (type === 'boolean') {
|
32
33
|
return (
|
33
34
|
<SelectField
|
35
|
+
aria-label="Edit override field"
|
34
36
|
selectItems={[
|
35
37
|
{ id: 'trueSelectOpt', value: true, name: __('true') },
|
36
38
|
{ id: 'falseSelectOpt', value: false, name: __('false') },
|
data/webpack/components/AnsibleHostDetail/components/AnsibleVariableOverrides/EditableValueHelper.js
CHANGED
@@ -23,7 +23,11 @@ const withFormGroup = Component => componentProps => {
|
|
23
23
|
export const SelectField = componentProps => {
|
24
24
|
const { selectItems, ...rest } = componentProps;
|
25
25
|
return (
|
26
|
-
<FormSelect
|
26
|
+
<FormSelect
|
27
|
+
className="without_select2"
|
28
|
+
ouiaId="without-form-select"
|
29
|
+
{...rest}
|
30
|
+
>
|
27
31
|
{selectItems.map(item => (
|
28
32
|
<FormSelectOption key={item.id} value={item.value} label={item.name} />
|
29
33
|
))}
|
@@ -57,6 +57,7 @@ const NewRecurringJobModal = props => {
|
|
57
57
|
const actions = [
|
58
58
|
<Button
|
59
59
|
aria-label="submit creating job"
|
60
|
+
ouiaId="submit-creating-job"
|
60
61
|
key="confirm"
|
61
62
|
variant="primary"
|
62
63
|
onClick={formProps.handleSubmit}
|
@@ -66,6 +67,7 @@ const NewRecurringJobModal = props => {
|
|
66
67
|
</Button>,
|
67
68
|
<Button
|
68
69
|
aria-label="cancel creating job"
|
70
|
+
ouiaId="cancel-creating-job"
|
69
71
|
key="cancel"
|
70
72
|
variant="link"
|
71
73
|
onClick={onClose}
|
@@ -83,6 +85,7 @@ const NewRecurringJobModal = props => {
|
|
83
85
|
<Modal
|
84
86
|
variant={ModalVariant.large}
|
85
87
|
title="Create New Recurring Ansible Run"
|
88
|
+
ouiaId="modal-recurring-ansible-run"
|
86
89
|
isOpen={props.isOpen}
|
87
90
|
className="foreman-modal modal-high"
|
88
91
|
showClose={false}
|
@@ -32,12 +32,17 @@ const PreviousJobsTable = ({ history, totalCount, jobs, pagination }) => {
|
|
32
32
|
<h3>{__('Previously executed jobs')}</h3>
|
33
33
|
<Flex direction={{ default: 'column' }} className="pf-u-pt-md">
|
34
34
|
<FlexItem align={{ default: 'alignRight' }}>
|
35
|
-
<Pagination
|
35
|
+
<Pagination
|
36
|
+
ouiaId="pagination-top"
|
37
|
+
updateParamsByUrl
|
38
|
+
itemCount={totalCount}
|
39
|
+
variant="top"
|
40
|
+
/>
|
36
41
|
</FlexItem>
|
37
42
|
<FlexItem>
|
38
|
-
<TableComposable variant="compact">
|
43
|
+
<TableComposable ouiaId="table-composable-compact" variant="compact">
|
39
44
|
<Thead>
|
40
|
-
<Tr>
|
45
|
+
<Tr ouiaId="row-header">
|
41
46
|
{columns.map(col => (
|
42
47
|
<Th key={col}>{col}</Th>
|
43
48
|
))}
|
@@ -45,7 +50,7 @@ const PreviousJobsTable = ({ history, totalCount, jobs, pagination }) => {
|
|
45
50
|
</Thead>
|
46
51
|
<Tbody>
|
47
52
|
{jobs.map(job => (
|
48
|
-
<Tr key={job.id}>
|
53
|
+
<Tr key={job.id} ouiaId={`row-${job.id}`}>
|
49
54
|
<Td>
|
50
55
|
<a
|
51
56
|
onClick={() =>
|
@@ -72,6 +77,7 @@ const PreviousJobsTable = ({ history, totalCount, jobs, pagination }) => {
|
|
72
77
|
</FlexItem>
|
73
78
|
<FlexItem align={{ default: 'alignRight' }}>
|
74
79
|
<Pagination
|
80
|
+
ouiaId="pagination-bottom"
|
75
81
|
updateParamsByUrl
|
76
82
|
itemCount={totalCount}
|
77
83
|
variant="bottom"
|
@@ -60,9 +60,9 @@ const RecurringJobsTable = ({
|
|
60
60
|
return (
|
61
61
|
<React.Fragment>
|
62
62
|
<h3>{__('Scheduled recurring jobs')}</h3>
|
63
|
-
<TableComposable variant="compact">
|
63
|
+
<TableComposable ouiaId="table-composable-compact" variant="compact">
|
64
64
|
<Thead>
|
65
|
-
<Tr>
|
65
|
+
<Tr ouiaId="row-header">
|
66
66
|
{columns.map(col => (
|
67
67
|
<Th key={col}>{col}</Th>
|
68
68
|
))}
|
@@ -71,7 +71,7 @@ const RecurringJobsTable = ({
|
|
71
71
|
</Thead>
|
72
72
|
<Tbody>
|
73
73
|
{jobs.map(job => (
|
74
|
-
<Tr key={job.id}>
|
74
|
+
<Tr key={job.id} ouiaId={`row-${job.id}`}>
|
75
75
|
<Td>
|
76
76
|
<a
|
77
77
|
onClick={() =>
|
@@ -33,7 +33,11 @@ const JobsTab = ({ resourceName, resourceId, hostGroupId, history }) => {
|
|
33
33
|
];
|
34
34
|
|
35
35
|
const scheduleBtn = (
|
36
|
-
<Button
|
36
|
+
<Button
|
37
|
+
aria-label="schedule recurring job"
|
38
|
+
ouiaId="schedule-recurring-job"
|
39
|
+
onClick={toggleModal}
|
40
|
+
>
|
37
41
|
{__('Schedule recurring job')}
|
38
42
|
</Button>
|
39
43
|
);
|
data/webpack/components/AnsibleHostDetail/components/RolesTab/AllRolesModal/AllRolesTable.js
CHANGED
@@ -21,11 +21,16 @@ const AllRolesTable = ({ allAnsibleRoles, totalCount }) => {
|
|
21
21
|
<React.Fragment>
|
22
22
|
<Flex direction={{ default: 'column' }} className="pf-u-pt-md">
|
23
23
|
<FlexItem align={{ default: 'alignRight' }}>
|
24
|
-
<Pagination
|
24
|
+
<Pagination
|
25
|
+
ouiaId="pagination-top"
|
26
|
+
updateParamsByUrl
|
27
|
+
itemCount={totalCount}
|
28
|
+
variant="top"
|
29
|
+
/>
|
25
30
|
</FlexItem>
|
26
|
-
<TableComposable variant="compact">
|
31
|
+
<TableComposable ouiaId="table-composable-compact" variant="compact">
|
27
32
|
<Thead>
|
28
|
-
<Tr>
|
33
|
+
<Tr ouiaId="row-header">
|
29
34
|
<Th />
|
30
35
|
{columns.map(col => (
|
31
36
|
<Th key={`${col}-all`}>{col}</Th>
|
@@ -34,7 +39,7 @@ const AllRolesTable = ({ allAnsibleRoles, totalCount }) => {
|
|
34
39
|
</Thead>
|
35
40
|
<Tbody>
|
36
41
|
{allAnsibleRoles.map(role => (
|
37
|
-
<Tr key={`${role.id}-all`} id={role.id}>
|
42
|
+
<Tr key={`${role.id}-all`} id={role.id} ouiaId={`row-${role.id}`}>
|
38
43
|
<Td />
|
39
44
|
<Td>{role.name}</Td>
|
40
45
|
<Td>
|
@@ -58,6 +63,7 @@ const AllRolesTable = ({ allAnsibleRoles, totalCount }) => {
|
|
58
63
|
</TableComposable>
|
59
64
|
<FlexItem align={{ default: 'alignRight' }}>
|
60
65
|
<Pagination
|
66
|
+
ouiaId="pagination-bottom"
|
61
67
|
updateParamsByUrl
|
62
68
|
itemCount={totalCount}
|
63
69
|
variant="bottom"
|
data/webpack/components/AnsibleHostDetail/components/RolesTab/EditRolesModal/EditRolesForm.js
CHANGED
@@ -54,6 +54,7 @@ const EditRolesForm = props => {
|
|
54
54
|
onClick={() => callMutation({ variables })}
|
55
55
|
isDisabled={loading || didNotModifyOptions()}
|
56
56
|
aria-label="submit ansible roles"
|
57
|
+
ouiaId="submit-ansible-roles-button"
|
57
58
|
>
|
58
59
|
{__('Confirm')}
|
59
60
|
</Button>,
|
@@ -65,7 +66,7 @@ const EditRolesForm = props => {
|
|
65
66
|
}
|
66
67
|
|
67
68
|
return (
|
68
|
-
<Modal {...baseModalProps} actions={formActions}>
|
69
|
+
<Modal ouiaId="modal-edit-roles" {...baseModalProps} actions={formActions}>
|
69
70
|
<DualList
|
70
71
|
availableOptions={availableOptions}
|
71
72
|
chosenOptions={chosenOptions}
|
@@ -20,6 +20,7 @@ const EditRolesModal = ({
|
|
20
20
|
canEditHost,
|
21
21
|
}) => {
|
22
22
|
const baseModalProps = {
|
23
|
+
ouiaId: 'edit-ansible-roles-modal',
|
23
24
|
width: '50%',
|
24
25
|
isOpen,
|
25
26
|
className: 'foreman-modal',
|
@@ -32,7 +33,12 @@ const EditRolesModal = ({
|
|
32
33
|
};
|
33
34
|
|
34
35
|
const actions = [
|
35
|
-
<Button
|
36
|
+
<Button
|
37
|
+
ouiaId="close-button"
|
38
|
+
variant="link"
|
39
|
+
onClick={event => closeModal()}
|
40
|
+
key="close"
|
41
|
+
>
|
36
42
|
{__('Close')}
|
37
43
|
</Button>,
|
38
44
|
];
|
@@ -32,7 +32,10 @@ const RolesTable = ({
|
|
32
32
|
const editBtn = canEditHost ? (
|
33
33
|
<FlexItem>
|
34
34
|
<Link to="/Ansible/roles/edit">
|
35
|
-
<Button
|
35
|
+
<Button
|
36
|
+
aria-label="edit ansible roles"
|
37
|
+
ouiaId="edit-ansible-roles-button"
|
38
|
+
>
|
36
39
|
{__('Edit Ansible roles')}
|
37
40
|
</Button>
|
38
41
|
</Link>
|
@@ -53,14 +56,19 @@ const RolesTable = ({
|
|
53
56
|
<Flex>
|
54
57
|
<FlexItem>{editBtn}</FlexItem>
|
55
58
|
<FlexItem align={{ default: 'alignRight' }}>
|
56
|
-
<Pagination
|
59
|
+
<Pagination
|
60
|
+
ouiaId="pagination-top"
|
61
|
+
updateParamsByUrl
|
62
|
+
itemCount={totalCount}
|
63
|
+
variant="top"
|
64
|
+
/>
|
57
65
|
</FlexItem>
|
58
66
|
</Flex>
|
59
67
|
<Flex direction={{ default: 'column' }}>
|
60
68
|
<FlexItem>
|
61
|
-
<TableComposable variant="compact">
|
69
|
+
<TableComposable variant="compact" ouiaId="table-composable-compact">
|
62
70
|
<Thead>
|
63
|
-
<Tr>
|
71
|
+
<Tr ouiaId="row-header">
|
64
72
|
{columns.map(col => (
|
65
73
|
<Th key={col}>{col}</Th>
|
66
74
|
))}
|
@@ -68,7 +76,7 @@ const RolesTable = ({
|
|
68
76
|
</Thead>
|
69
77
|
<Tbody>
|
70
78
|
{ansibleRoles.map(role => (
|
71
|
-
<Tr key={role.id}>
|
79
|
+
<Tr key={role.id} ouiaId={`row-${role.id}`}>
|
72
80
|
<Td>
|
73
81
|
<a href={role.path}>{role.name}</a>
|
74
82
|
</Td>
|
@@ -88,6 +96,7 @@ const RolesTable = ({
|
|
88
96
|
</FlexItem>
|
89
97
|
<FlexItem align={{ default: 'alignRight' }}>
|
90
98
|
<Pagination
|
99
|
+
ouiaId="pagination-bottom"
|
91
100
|
updateParamsByUrl
|
92
101
|
itemCount={totalCount}
|
93
102
|
variant="bottom"
|
@@ -21,7 +21,8 @@ import {
|
|
21
21
|
assignRolesErrorMock,
|
22
22
|
} from './RolesTab.fixtures';
|
23
23
|
|
24
|
-
|
24
|
+
jest.mock('axios');
|
25
|
+
const TestComponent = withRedux(withReactRouter(withMockedProvider(RolesTab)));
|
25
26
|
|
26
27
|
describe('assigning Ansible roles', () => {
|
27
28
|
it('should assign Ansible roles', async () => {
|
@@ -6,6 +6,7 @@ import {
|
|
6
6
|
tick,
|
7
7
|
withMockedProvider,
|
8
8
|
withReactRouter,
|
9
|
+
withRedux,
|
9
10
|
} from '../../../../../testHelper';
|
10
11
|
|
11
12
|
import {
|
@@ -18,7 +19,8 @@ import {
|
|
18
19
|
|
19
20
|
import RolesTab from '../';
|
20
21
|
|
21
|
-
|
22
|
+
jest.mock('axios');
|
23
|
+
const TestComponent = withRedux(withReactRouter(withMockedProvider(RolesTab)));
|
22
24
|
|
23
25
|
describe('RolesTab', () => {
|
24
26
|
it('should load Ansible Roles as admin', async () => {
|
@@ -2,7 +2,10 @@ import React, { useState } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
3
3
|
import { useQuery } from '@apollo/client';
|
4
4
|
import { Button } from '@patternfly/react-core';
|
5
|
+
import { Link, Route } from 'react-router-dom';
|
5
6
|
import { translate as __ } from 'foremanReact/common/I18n';
|
7
|
+
import { foremanUrl } from 'foremanReact/common/helpers';
|
8
|
+
import { useAPI } from 'foremanReact/common/hooks/API/APIHooks';
|
6
9
|
|
7
10
|
import ansibleRolesQuery from '../../../../graphql/queries/hostAnsibleRoles.gql';
|
8
11
|
import { encodeId } from '../../../../globalIdHelper';
|
@@ -12,6 +15,7 @@ import {
|
|
12
15
|
useCurrentPagination,
|
13
16
|
} from '../../../../helpers/pageParamsHelper';
|
14
17
|
import EditRolesModal from './EditRolesModal';
|
18
|
+
import AllRolesModal from './AllRolesModal';
|
15
19
|
|
16
20
|
const RolesTab = ({ hostId, history, canEditHost }) => {
|
17
21
|
const hostGlobalId = encodeId('Host', hostId);
|
@@ -32,10 +36,30 @@ const RolesTab = ({ hostId, history, canEditHost }) => {
|
|
32
36
|
<Button
|
33
37
|
onClick={() => setAssignModal(true)}
|
34
38
|
aria-label="edit ansible roles"
|
39
|
+
ouiaId="edit-ansible-roles-button"
|
35
40
|
>
|
36
|
-
{__('Assign
|
41
|
+
{__('Assign roles directly to the host')}
|
37
42
|
</Button>
|
38
43
|
) : null;
|
44
|
+
|
45
|
+
const url = hostId && foremanUrl(`/api/v2/hosts/${hostId}/ansible_roles`);
|
46
|
+
const { response: allAnsibleRoles } = useAPI('get', url, {
|
47
|
+
key: 'ANSIBLE_ROLES',
|
48
|
+
});
|
49
|
+
const emptyStateDescription = allAnsibleRoles.length > 0 && (
|
50
|
+
<>
|
51
|
+
<Route path="/Ansible/roles/all">
|
52
|
+
<AllRolesModal
|
53
|
+
onClose={() => history.push('/Ansible/roles')}
|
54
|
+
isOpen
|
55
|
+
hostGlobalId={hostGlobalId}
|
56
|
+
history={history}
|
57
|
+
/>
|
58
|
+
</Route>
|
59
|
+
<Link to="/Ansible/roles/all">{__('View inherited roles')}</Link>
|
60
|
+
</>
|
61
|
+
);
|
62
|
+
|
39
63
|
return (
|
40
64
|
<>
|
41
65
|
<RolesTable
|
@@ -46,8 +70,9 @@ const RolesTab = ({ hostId, history, canEditHost }) => {
|
|
46
70
|
history={history}
|
47
71
|
hostGlobalId={hostGlobalId}
|
48
72
|
emptyStateProps={{
|
49
|
-
header: __('No
|
73
|
+
header: __('No roles assigned directly to the host'),
|
50
74
|
action: editBtn,
|
75
|
+
description: emptyStateDescription,
|
51
76
|
}}
|
52
77
|
pagination={pagination}
|
53
78
|
canEditHost={canEditHost}
|
@@ -12,7 +12,7 @@ import { ANSIBLE_KEY } from '../constants';
|
|
12
12
|
import { route } from '../helpers';
|
13
13
|
|
14
14
|
const SecondaryTabRoutes = ({ response, router, history }) => (
|
15
|
-
<Switch>
|
15
|
+
<Switch ouiaId="switch">
|
16
16
|
<Route exact path={`/${ANSIBLE_KEY}`}>
|
17
17
|
<Redirect to={route('roles')} />
|
18
18
|
</Route>
|
data/webpack/testHelper.js
CHANGED
@@ -1,15 +1,24 @@
|
|
1
1
|
import React from 'react';
|
2
2
|
import { Provider } from 'react-redux';
|
3
|
+
import thunk from 'redux-thunk';
|
4
|
+
import { applyMiddleware, createStore, compose, combineReducers } from 'redux';
|
3
5
|
import { MockedProvider } from '@apollo/react-testing';
|
4
6
|
import { Router, MemoryRouter } from 'react-router-dom';
|
5
7
|
import { createMemoryHistory } from 'history';
|
6
8
|
|
7
|
-
import
|
8
|
-
import ConfirmModal
|
9
|
+
import { reducers as apiReducer, APIMiddleware } from 'foremanReact/redux/API';
|
10
|
+
import ConfirmModal, {
|
11
|
+
reducers as confirmModalReducers,
|
12
|
+
} from 'foremanReact/components/ConfirmModal';
|
9
13
|
import { getForemanContext } from 'foremanReact/Root/Context/ForemanContext';
|
10
14
|
|
15
|
+
const reducers = combineReducers({ ...apiReducer, ...confirmModalReducers });
|
16
|
+
|
17
|
+
export const generateStore = () =>
|
18
|
+
createStore(reducers, compose(applyMiddleware(thunk, APIMiddleware)));
|
19
|
+
|
11
20
|
export const withRedux = Component => props => (
|
12
|
-
<Provider store={
|
21
|
+
<Provider store={generateStore()}>
|
13
22
|
<Component {...props} />
|
14
23
|
<ConfirmModal />
|
15
24
|
</Provider>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman_ansible
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 10.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Lobato Garcia
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-10-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: acts_as_list
|
@@ -44,28 +44,28 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 8.0.0
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 8.0.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: foreman-tasks
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 7.0.0
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 7.0.0
|
69
69
|
description: Ansible integration with Foreman
|
70
70
|
email:
|
71
71
|
- elobatocs@gmail.com
|
@@ -222,7 +222,6 @@ files:
|
|
222
222
|
- lib/foreman_ansible.rb
|
223
223
|
- lib/foreman_ansible/engine.rb
|
224
224
|
- lib/foreman_ansible/register.rb
|
225
|
-
- lib/foreman_ansible/register.rb.orig
|
226
225
|
- lib/foreman_ansible/remote_execution.rb
|
227
226
|
- lib/foreman_ansible/version.rb
|
228
227
|
- locale/Makefile
|
@@ -325,6 +324,7 @@ files:
|
|
325
324
|
- test/graphql/mutations/hosts/assign_ansible_roles_mutation_test.rb
|
326
325
|
- test/graphql/queries/ansible_roles_query_test.rb
|
327
326
|
- test/graphql/queries/host_ansible_roles_query_test.rb
|
327
|
+
- test/integration/hostgroup_js_test.rb
|
328
328
|
- test/test_plugin_helper.rb
|
329
329
|
- test/unit/actions/run_ansible_job_test.rb
|
330
330
|
- test/unit/actions/run_proxy_ansible_command_test.rb
|
@@ -547,3 +547,4 @@ test_files:
|
|
547
547
|
- test/unit/import_playbooks_test.rb
|
548
548
|
- test/unit/import_roles_and_variables.rb
|
549
549
|
- test/test_plugin_helper.rb
|
550
|
+
- test/integration/hostgroup_js_test.rb
|
@@ -1,257 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
Foreman::Plugin.register :foreman_ansible do
|
4
|
-
requires_foreman '>= 3.3'
|
5
|
-
|
6
|
-
settings do
|
7
|
-
category :ansible, N_('Ansible') do
|
8
|
-
setting 'ansible_ssh_private_key_file',
|
9
|
-
type: :string,
|
10
|
-
description: N_('Use this to supply a path to an SSH Private Key '\
|
11
|
-
'that Ansible will use in lieu of a password '\
|
12
|
-
'Override with "ansible_ssh_private_key_file" '\
|
13
|
-
'host parameter'),
|
14
|
-
default: '',
|
15
|
-
full_name: N_('Private Key Path')
|
16
|
-
setting 'ansible_connection',
|
17
|
-
type: :string,
|
18
|
-
description: N_('Use this connection type by default when running '\
|
19
|
-
'Ansible playbooks. You can override this on hosts by '\
|
20
|
-
'adding a parameter "ansible_connection"'),
|
21
|
-
default: 'ssh',
|
22
|
-
full_name: N_('Connection type')
|
23
|
-
setting 'ansible_winrm_server_cert_validation',
|
24
|
-
type: :string,
|
25
|
-
description: N_('Enable/disable WinRM server certificate '\
|
26
|
-
'validation when running Ansible playbooks. You can override '\
|
27
|
-
'this on hosts by adding a parameter '\
|
28
|
-
'"ansible_winrm_server_cert_validation"'),
|
29
|
-
default: 'validate',
|
30
|
-
full_name: N_('WinRM cert Validation')
|
31
|
-
setting 'ansible_verbosity',
|
32
|
-
type: :integer,
|
33
|
-
description: N_('Foreman will add this level of verbosity for '\
|
34
|
-
'additional debugging output when running Ansible playbooks.'),
|
35
|
-
default: '0',
|
36
|
-
full_name: N_('Default verbosity level'),
|
37
|
-
value: nil,
|
38
|
-
collection: proc {
|
39
|
-
{ '0' => N_('Disabled'),
|
40
|
-
'1' => N_('Level 1 (-v)'),
|
41
|
-
'2' => N_('Level 2 (-vv)'),
|
42
|
-
'3' => N_('Level 3 (-vvv)'),
|
43
|
-
'4' => N_('Level 4 (-vvvv)') }
|
44
|
-
}
|
45
|
-
setting 'ansible_post_provision_timeout',
|
46
|
-
type: :integer,
|
47
|
-
description: N_('Timeout (in seconds) to set when Foreman will trigger a '\
|
48
|
-
'play Ansible roles task after a host is fully provisioned. '\
|
49
|
-
'Set this to the maximum time you expect a host to take '\
|
50
|
-
'until it is ready after a reboot.'),
|
51
|
-
default: '360',
|
52
|
-
full_name: N_('Post-provision timeout')
|
53
|
-
setting 'ansible_interval',
|
54
|
-
type: :integer,
|
55
|
-
description: N_('Timeout (in minutes) when hosts should have reported.'),
|
56
|
-
default: '30',
|
57
|
-
full_name: N_('Ansible report timeout')
|
58
|
-
setting 'ansible_out_of_sync_disabled',
|
59
|
-
type: :boolean,
|
60
|
-
description: format(N_('Disable host configuration status turning to out of'\
|
61
|
-
' sync for %{cfgmgmt} after report does not arrive within'\
|
62
|
-
' configured interval'), :cfgmgmt => 'Ansible'),
|
63
|
-
default: false,
|
64
|
-
full_name: format(N_('%{cfgmgmt} out of sync disabled'), :cfgmgmt => 'Ansible')
|
65
|
-
setting 'ansible_inventory_template',
|
66
|
-
type: :string,
|
67
|
-
description: N_('Foreman will use this template to schedule the report '\
|
68
|
-
'with Ansible inventory'),
|
69
|
-
default: 'Ansible - Ansible Inventory',
|
70
|
-
full_name: N_('Default Ansible inventory report template')
|
71
|
-
setting 'ansible_roles_to_ignore',
|
72
|
-
type: :array,
|
73
|
-
description: N_('Those roles will be excluded when importing roles from smart proxy, '\
|
74
|
-
'The expected input is comma separated values and you can use * wildcard metacharacters'\
|
75
|
-
'For example: foo*, *b*,*bar'),
|
76
|
-
default: [],
|
77
|
-
full_name: N_('Ansible roles to ignore')
|
78
|
-
setting 'foreman_ansible_proxy_batch_size',
|
79
|
-
type: :integer,
|
80
|
-
description: N_('Number of tasks which should be sent to the smart proxy in one request, '\
|
81
|
-
'if foreman_tasks_proxy_batch_trigger is enabled. '\
|
82
|
-
'If set, overrides foreman_tasks_proxy_batch_size setting for Ansible jobs.'),
|
83
|
-
default: nil,
|
84
|
-
full_name: N_('Proxy tasks batch size for Ansible')
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
security_block :foreman_ansible do
|
89
|
-
permission :play_roles_on_host,
|
90
|
-
{ :hosts => [:play_roles, :multiple_play_roles],
|
91
|
-
:'api/v2/hosts' => [:play_roles,
|
92
|
-
:multiple_play_roles] },
|
93
|
-
:resource_type => 'Host'
|
94
|
-
permission :play_roles_on_hostgroup,
|
95
|
-
{ :hostgroups => [:play_roles],
|
96
|
-
:'api/v2/hostgroups' => [:play_roles,
|
97
|
-
:multiple_play_roles] },
|
98
|
-
:resource_type => 'Hostgroup'
|
99
|
-
permission :view_ansible_roles,
|
100
|
-
{ :ansible_roles => [:index, :auto_complete_search],
|
101
|
-
:'api/v2/ansible_roles' => [:index, :show, :fetch],
|
102
|
-
:ui_ansible_roles => [:index] },
|
103
|
-
:resource_type => 'AnsibleRole'
|
104
|
-
permission :destroy_ansible_roles,
|
105
|
-
{ :ansible_roles => [:destroy],
|
106
|
-
:'api/v2/ansible_roles' => [:destroy, :obsolete] },
|
107
|
-
:resource_type => 'AnsibleRole'
|
108
|
-
permission :import_ansible_roles,
|
109
|
-
{ :ansible_roles => [:import, :confirm_import],
|
110
|
-
:'api/v2/ansible_roles' => [:import, :sync] },
|
111
|
-
:resource_type => 'AnsibleRole'
|
112
|
-
permission :view_ansible_variables,
|
113
|
-
{
|
114
|
-
:lookup_values => [:index],
|
115
|
-
:ansible_variables => [:index, :auto_complete_search],
|
116
|
-
:'api/v2/ansible_variables' => [:index, :show]
|
117
|
-
},
|
118
|
-
:resource_type => 'AnsibleVariable'
|
119
|
-
permission :edit_ansible_variables,
|
120
|
-
{ :lookup_values => [:update],
|
121
|
-
:ansible_variables => [:edit, :update],
|
122
|
-
:'api/v2/ansible_variables' => [:update],
|
123
|
-
:'api/v2/ansible_override_values' => [:create, :destroy] },
|
124
|
-
:resource_type => 'AnsibleVariable'
|
125
|
-
permission :destroy_ansible_variables,
|
126
|
-
{
|
127
|
-
:lookup_values => [:destroy],
|
128
|
-
:ansible_variables => [:destroy],
|
129
|
-
:'api/v2/ansible_variables' => [:destroy, :obsolete]
|
130
|
-
},
|
131
|
-
:resource_type => 'AnsibleVariable'
|
132
|
-
permission :create_ansible_variables,
|
133
|
-
{
|
134
|
-
:lookup_values => [:create],
|
135
|
-
:ansible_variables => [:new, :create],
|
136
|
-
:'api/v2/ansible_variables' => [:create]
|
137
|
-
},
|
138
|
-
:resource_type => 'AnsibleVariable'
|
139
|
-
permission :import_ansible_variables,
|
140
|
-
{
|
141
|
-
:ansible_variables => [:import, :confirm_import],
|
142
|
-
:'api/v2/ansible_variables' => [:import]
|
143
|
-
},
|
144
|
-
:resource_type => 'AnsibleVariable'
|
145
|
-
permission :view_hosts,
|
146
|
-
{ :'api/v2/hosts' => [:ansible_roles],
|
147
|
-
:'api/v2/ansible_inventories' => [:hosts] },
|
148
|
-
:resource_type => 'Host'
|
149
|
-
permission :view_hostgroups,
|
150
|
-
{ :'api/v2/hostgroups' => [:ansible_roles],
|
151
|
-
:'api/v2/ansible_inventories' => [:hostgroups] },
|
152
|
-
:resource_type => 'Hostgroup'
|
153
|
-
permission :edit_hosts,
|
154
|
-
{ :'api/v2/hosts' => [:assign_ansible_roles] },
|
155
|
-
:resource_type => 'Host'
|
156
|
-
permission :edit_hostgroups,
|
157
|
-
{ :'api/v2/hostgroups' => [:assign_ansible_roles] },
|
158
|
-
:resource_type => 'Hostgroup'
|
159
|
-
permission :generate_ansible_inventory,
|
160
|
-
{ :'api/v2/ansible_inventories' => [:schedule] }
|
161
|
-
permission :import_ansible_playbooks,
|
162
|
-
{ :'api/v2/ansible_playbooks' => [:sync, :fetch] }
|
163
|
-
end
|
164
|
-
|
165
|
-
role 'Ansible Roles Manager',
|
166
|
-
[:play_roles_on_host, :play_roles_on_hostgroup,
|
167
|
-
:create_job_invocations, :view_job_templates, # to allow the play_roles
|
168
|
-
:create_template_invocations, :view_smart_proxies, # ...
|
169
|
-
:view_ansible_roles, :destroy_ansible_roles,
|
170
|
-
:import_ansible_roles, :view_ansible_variables,
|
171
|
-
:create_ansible_variables, :import_ansible_variables,
|
172
|
-
:edit_ansible_variables, :destroy_ansible_variables, :import_ansible_playbooks]
|
173
|
-
|
174
|
-
role 'Ansible Tower Inventory Reader',
|
175
|
-
[:view_hosts, :view_hostgroups, :view_facts, :generate_report_templates, :generate_ansible_inventory,
|
176
|
-
:view_report_templates],
|
177
|
-
'Permissions required for the user which is used by Ansible Tower Dynamic Inventory Item'
|
178
|
-
|
179
|
-
add_all_permissions_to_default_roles
|
180
|
-
extend_template_helpers ForemanAnsible::RendererMethods
|
181
|
-
allowed_template_helpers :insights_remediation
|
182
|
-
|
183
|
-
base_role_assignment_params = { :ansible_role_ids => [],
|
184
|
-
:ansible_roles => [] }
|
185
|
-
parameter_filter Host::Managed, base_role_assignment_params.merge(:host_ansible_roles_attributes => {})
|
186
|
-
parameter_filter Hostgroup, base_role_assignment_params.merge(:hostgroup_ansible_roles_attributes => {})
|
187
|
-
|
188
|
-
register_global_js_file 'global'
|
189
|
-
|
190
|
-
extend_graphql_type :type => '::Types::Host' do
|
191
|
-
field :all_ansible_roles, ::Types::InheritedAnsibleRole.connection_type, :null => true, :method => :present_all_ansible_roles
|
192
|
-
field :own_ansible_roles, ::Types::AnsibleRole.connection_type, :null => true
|
193
|
-
field :available_ansible_roles, ::Types::AnsibleRole.connection_type, :null => true
|
194
|
-
field :ansible_variables_with_overrides, Types::OverridenAnsibleVariable.connection_type, :null => false
|
195
|
-
|
196
|
-
def present_all_ansible_roles
|
197
|
-
inherited_ansible_roles = object.inherited_ansible_roles.map { |role| ::Presenters::AnsibleRolePresenter.new(role, true) }
|
198
|
-
ansible_roles = object.ansible_roles.map { |role| ::Presenters::AnsibleRolePresenter.new(role, false) }
|
199
|
-
(inherited_ansible_roles + ansible_roles).uniq
|
200
|
-
end
|
201
|
-
|
202
|
-
def ansible_variables_with_overrides
|
203
|
-
resolver = ::ForemanAnsible::OverrideResolver.new(object)
|
204
|
-
AnsibleVariable.where(:ansible_role_id => object.all_ansible_roles.pluck(:id), :override => true).map { |variable| ::Presenters::OverridenAnsibleVariablePresenter.new variable, resolver }
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
register_graphql_query_field :ansible_roles, '::Types::AnsibleRole', :collection_field
|
209
|
-
register_graphql_mutation_field :assign_ansible_roles, '::Mutations::Hosts::AssignAnsibleRoles'
|
210
|
-
register_graphql_mutation_field :delete_ansible_variable_override, ::Mutations::AnsibleVariableOverrides::Delete
|
211
|
-
register_graphql_mutation_field :update_ansible_variable_override, ::Mutations::AnsibleVariableOverrides::Update
|
212
|
-
register_graphql_mutation_field :create_ansible_variable_override, ::Mutations::AnsibleVariableOverrides::Create
|
213
|
-
|
214
|
-
divider :top_menu, :caption => N_('Ansible'), :parent => :configure_menu
|
215
|
-
menu :top_menu, :ansible_roles,
|
216
|
-
:caption => N_('Roles'),
|
217
|
-
:url_hash => { :controller => :ansible_roles, :action => :index },
|
218
|
-
:parent => :configure_menu
|
219
|
-
menu :top_menu, :ansible_variables,
|
220
|
-
:caption => N_('Variables'),
|
221
|
-
:url_hash => { :controller => :ansible_variables, :action => :index },
|
222
|
-
:parent => :configure_menu
|
223
|
-
|
224
|
-
apipie_documented_controllers [
|
225
|
-
"#{ForemanAnsible::Engine.root}/app/controllers/api/v2/*.rb"
|
226
|
-
]
|
227
|
-
ApipieDSL.configuration.dsl_classes_matchers += [
|
228
|
-
"#{ForemanAnsible::Engine.root}/app/models/*.rb",
|
229
|
-
"#{ForemanAnsible::Engine.root}/app/services/foreman_ansible/*.rb"
|
230
|
-
]
|
231
|
-
|
232
|
-
register_info_provider ForemanAnsible::AnsibleInfo
|
233
|
-
|
234
|
-
# For backwards compatiblity with 1.17
|
235
|
-
if respond_to?(:register_report_scanner)
|
236
|
-
register_report_scanner ForemanAnsible::AnsibleReportScanner
|
237
|
-
register_report_origin 'Ansible', 'ConfigReport'
|
238
|
-
end
|
239
|
-
|
240
|
-
<<<<<<< HEAD
|
241
|
-
describe_host do
|
242
|
-
multiple_actions_provider :ansible_hosts_multiple_actions
|
243
|
-
=======
|
244
|
-
extend_page('smart_proxies/show') do |context|
|
245
|
-
context.add_pagelet :smart_proxy_title_actions,
|
246
|
-
:name => _('Update Smart Proxy'),
|
247
|
-
:partial => 'foreman/smart_proxies/update_smart_proxy',
|
248
|
-
:onlyif => ->(proxy, view) { view.can_update_proxy?(proxy) }
|
249
|
-
end
|
250
|
-
extend_page('smart_proxies/index') do |context|
|
251
|
-
context.add_pagelet :smart_proxy_title_actions,
|
252
|
-
:name => _('Update Smart Proxy'),
|
253
|
-
:partial => 'foreman/smart_proxies/update_smart_proxy',
|
254
|
-
:onlyif => ->(proxy, view) { view.can_update_proxy?(proxy) }
|
255
|
-
>>>>>>> a707dab (Fixes #35143 - Add a smart proxy update button)
|
256
|
-
end
|
257
|
-
end
|