foreman_ansible 7.1.0 → 7.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/graphql/presenters/ansible_role_presenter.rb +4 -0
- data/app/graphql/types/ansible_role.rb +1 -0
- data/app/graphql/types/inherited_ansible_role.rb +4 -0
- data/app/views/foreman_ansible/job_templates/ansible_roles_-_install_from_git.erb +4 -1
- data/lib/foreman_ansible/register.rb +1 -1
- data/lib/foreman_ansible/remote_execution.rb +0 -6
- data/lib/foreman_ansible/version.rb +1 -1
- data/test/graphql/queries/host_ansible_roles_query_test.rb +61 -0
- data/webpack/components/AnsibleHostDetail/components/RolesTab/EditRolesModal/EditRolesForm.js +26 -24
- data/webpack/components/AnsibleHostDetail/components/RolesTab/EditRolesModal/index.js +3 -2
- data/webpack/components/AnsibleRolesSwitcher/__tests__/AnsibleRolesSwitcher.test.js +0 -2
- data/webpack/components/withLoading.js +7 -12
- metadata +36 -35
- data/app/views/foreman_ansible/job_templates/configure_cloud_connector_-_ansible_default.erb +0 -37
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2754fa1c5a9834d8b174906f4848ce5ba7e5699a9c757e6761b24c1ced021f52
|
4
|
+
data.tar.gz: b9c7d3e372fbde5eb5a6e5b94af335293ec660b81511c23f4cd519868632988a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 933f56fb3c7eb0389397067189f9b64f7fc2ec44fb631e26b0943748b80c80f51b23e2897f4175ff4e8f28b5dbd1232e51641a429b07de1fd2786ba7d44fc4bc
|
7
|
+
data.tar.gz: d9c4973117fa530f4dfbd93720692a9331c1172b120f66aa6df4cb59f9dfe3162b2004c5f7e2e9b1f3bf99283524154fb2e1fe4a8045839c97823895a446a8e6
|
@@ -23,6 +23,9 @@ model: JobTemplate
|
|
23
23
|
---
|
24
24
|
- hosts: all
|
25
25
|
tasks:
|
26
|
-
-
|
26
|
+
- git:
|
27
|
+
repo: "<%= input('git_repository') %>"
|
28
|
+
dest: "<%= input('location') %>"
|
27
29
|
register: out
|
30
|
+
|
28
31
|
- debug: var=out
|
@@ -48,12 +48,6 @@ module ForemanAnsible
|
|
48
48
|
:description => N_('Upgrade Capsules on given Capsule server hosts'),
|
49
49
|
:proxy_selector_override => ::RemoteExecutionProxySelector::INTERNAL_PROXY
|
50
50
|
)
|
51
|
-
RemoteExecutionFeature.register(
|
52
|
-
:ansible_configure_cloud_connector,
|
53
|
-
N_('Configure Cloud Connector on given hosts'),
|
54
|
-
:description => N_('Configure Cloud Connector on given hosts'),
|
55
|
-
:proxy_selector_override => ::RemoteExecutionProxySelector::INTERNAL_PROXY
|
56
|
-
)
|
57
51
|
end
|
58
52
|
end
|
59
53
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'test_plugin_helper'
|
2
|
+
|
3
|
+
module Queries
|
4
|
+
class HostAnsibleRolesQueryTest < GraphQLQueryTestCase
|
5
|
+
let(:role1) { FactoryBot.create(:ansible_role) }
|
6
|
+
let(:role2) { FactoryBot.create(:ansible_role) }
|
7
|
+
let(:hostgroup) { FactoryBot.create(:hostgroup, ansible_roles: [role1]) }
|
8
|
+
let(:host) { FactoryBot.create(:host, hostgroup: hostgroup, ansible_roles: [role2]) }
|
9
|
+
let(:variables) { { id: Foreman::GlobalId.for(host) } }
|
10
|
+
let(:query) do
|
11
|
+
<<-GRAPHQL
|
12
|
+
query ($id: String!) {
|
13
|
+
host(id: $id) {
|
14
|
+
id
|
15
|
+
allAnsibleRoles {
|
16
|
+
totalCount
|
17
|
+
nodes {
|
18
|
+
id
|
19
|
+
name
|
20
|
+
inherited
|
21
|
+
ansibleVariables {
|
22
|
+
totalCount
|
23
|
+
nodes {
|
24
|
+
key
|
25
|
+
override
|
26
|
+
}
|
27
|
+
}
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}
|
31
|
+
}
|
32
|
+
GRAPHQL
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'with admin permissions' do
|
36
|
+
let(:context_user) { FactoryBot.create(:user, :admin) }
|
37
|
+
let(:data) { result['data']['host']['allAnsibleRoles'] }
|
38
|
+
|
39
|
+
it 'allows to fetch inherited roles' do
|
40
|
+
value(data['totalCount']).must_equal(2)
|
41
|
+
r1_data = data['nodes'].first
|
42
|
+
r2_data = data['nodes'].second
|
43
|
+
value(r1_data['name']).must_equal(role1.name)
|
44
|
+
value(r1_data['inherited']).must_equal(true)
|
45
|
+
value(r2_data['name']).must_equal(role2.name)
|
46
|
+
value(r2_data['inherited']).must_equal(false)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'allow fetching variables' do
|
50
|
+
var1 = FactoryBot.create(:ansible_variable, ansible_role: role1, override: true)
|
51
|
+
FactoryBot.create(:ansible_variable, ansible_role: role1)
|
52
|
+
FactoryBot.create(:ansible_variable, ansible_role: role2, override: true)
|
53
|
+
r1_vars = data['nodes'].first['ansibleVariables']
|
54
|
+
r2_vars = data['nodes'].second['ansibleVariables']
|
55
|
+
value(r1_vars['totalCount']).must_equal(2)
|
56
|
+
value(r2_vars['totalCount']).must_equal(1)
|
57
|
+
value(r1_vars['nodes'].first['key']).must_equal(var1.key)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/webpack/components/AnsibleHostDetail/components/RolesTab/EditRolesModal/EditRolesForm.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
import React, { useState
|
1
|
+
import React, { useState } from 'react';
|
2
2
|
import { translate as __ } from 'foremanReact/common/I18n';
|
3
3
|
import PropTypes from 'prop-types';
|
4
|
-
|
4
|
+
import { isEqual } from 'lodash';
|
5
5
|
import { useMutation } from '@apollo/client';
|
6
6
|
|
7
7
|
import { Button, Modal, Spinner } from '@patternfly/react-core';
|
@@ -21,17 +21,15 @@ const EditRolesForm = props => {
|
|
21
21
|
actions,
|
22
22
|
} = props;
|
23
23
|
|
24
|
-
const
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
const initAvailableOpt = availableRoles.map(item => item.name);
|
25
|
+
const initChosenOpt = assignedRoles.map(item => item.name);
|
26
|
+
const [availableOptions, setAvailableOptions] = useState(initAvailableOpt);
|
27
|
+
const [chosenOptions, setChosenOptions] = useState(initChosenOpt);
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
});
|
34
|
-
}, [availableRoles, assignedRoles]);
|
29
|
+
const onListChange = (nextAvailable, nextChosen) => {
|
30
|
+
setAvailableOptions(nextAvailable);
|
31
|
+
setChosenOptions(nextChosen);
|
32
|
+
};
|
35
33
|
|
36
34
|
const [callMutation, { loading }] = useMutation(assignAnsibleRoles, {
|
37
35
|
onCompleted: onCompleted(closeModal),
|
@@ -42,15 +40,19 @@ const EditRolesForm = props => {
|
|
42
40
|
|
43
41
|
const variables = {
|
44
42
|
id: encodeId('Host', hostId),
|
45
|
-
ansibleRoleIds: roleNamesToIds(allRoles,
|
43
|
+
ansibleRoleIds: roleNamesToIds(allRoles, chosenOptions),
|
46
44
|
};
|
47
45
|
|
46
|
+
const didNotModifyOptions = () =>
|
47
|
+
isEqual(initAvailableOpt.sort(), availableOptions.sort()) &&
|
48
|
+
isEqual(initChosenOpt, chosenOptions); // The order of the chosen options is important.
|
49
|
+
|
48
50
|
const formActions = [
|
49
51
|
<Button
|
50
52
|
key="confirm"
|
51
53
|
variant="primary"
|
52
54
|
onClick={() => callMutation({ variables })}
|
53
|
-
isDisabled={loading}
|
55
|
+
isDisabled={loading || didNotModifyOptions()}
|
54
56
|
aria-label="submit ansible roles"
|
55
57
|
>
|
56
58
|
{__('Confirm')}
|
@@ -65,14 +67,9 @@ const EditRolesForm = props => {
|
|
65
67
|
return (
|
66
68
|
<Modal {...baseModalProps} actions={formActions}>
|
67
69
|
<DualList
|
68
|
-
availableOptions={
|
69
|
-
chosenOptions={
|
70
|
-
onListChange={
|
71
|
-
setFormState({
|
72
|
-
availableOptions: newAvailable,
|
73
|
-
chosenOptions: newChosen,
|
74
|
-
})
|
75
|
-
}
|
70
|
+
availableOptions={availableOptions}
|
71
|
+
chosenOptions={chosenOptions}
|
72
|
+
onListChange={onListChange}
|
76
73
|
/>
|
77
74
|
</Modal>
|
78
75
|
);
|
@@ -80,11 +77,16 @@ const EditRolesForm = props => {
|
|
80
77
|
|
81
78
|
EditRolesForm.propTypes = {
|
82
79
|
closeModal: PropTypes.func.isRequired,
|
83
|
-
assignedRoles: PropTypes.array
|
84
|
-
availableRoles: PropTypes.array
|
80
|
+
assignedRoles: PropTypes.array,
|
81
|
+
availableRoles: PropTypes.array,
|
85
82
|
actions: PropTypes.array.isRequired,
|
86
83
|
hostId: PropTypes.number.isRequired,
|
87
84
|
baseModalProps: PropTypes.object.isRequired,
|
88
85
|
};
|
89
86
|
|
87
|
+
EditRolesForm.defaultProps = {
|
88
|
+
assignedRoles: [],
|
89
|
+
availableRoles: [],
|
90
|
+
};
|
91
|
+
|
90
92
|
export default withLoading(EditRolesForm);
|
@@ -20,7 +20,7 @@ const EditRolesModal = ({
|
|
20
20
|
canEditHost,
|
21
21
|
}) => {
|
22
22
|
const baseModalProps = {
|
23
|
-
width: '
|
23
|
+
width: '50%',
|
24
24
|
isOpen,
|
25
25
|
className: 'foreman-modal',
|
26
26
|
showClose: false,
|
@@ -54,6 +54,7 @@ const EditRolesModal = ({
|
|
54
54
|
|
55
55
|
const renameData = data => ({
|
56
56
|
availableRoles: data.host.availableAnsibleRoles.nodes,
|
57
|
+
assignedRoles,
|
57
58
|
});
|
58
59
|
|
59
60
|
return (
|
@@ -64,7 +65,7 @@ const EditRolesModal = ({
|
|
64
65
|
baseModalProps={baseModalProps}
|
65
66
|
fetchFn={useFetchFn}
|
66
67
|
renameData={renameData}
|
67
|
-
renamedDataPath="availableRoles"
|
68
|
+
renamedDataPath="availableRoles.assignedRoles"
|
68
69
|
assignedRoles={assignedRoles}
|
69
70
|
closeModal={closeModal}
|
70
71
|
hostId={hostId}
|
@@ -13,14 +13,12 @@ import {
|
|
13
13
|
} from '../permissionsHelper';
|
14
14
|
import ErrorState from './ErrorState';
|
15
15
|
|
16
|
-
const
|
16
|
+
const getResultsLength = (data, path) => {
|
17
17
|
const split = path.split('.');
|
18
|
-
return split.reduce(
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
throw new Error('Unexpected empty segment in response data path');
|
23
|
-
}, data);
|
18
|
+
return split.reduce(
|
19
|
+
(prevValue, currentValue) => prevValue + data[currentValue]?.length || 0,
|
20
|
+
0
|
21
|
+
);
|
24
22
|
};
|
25
23
|
|
26
24
|
const withLoading = Component => {
|
@@ -79,12 +77,9 @@ const withLoading = Component => {
|
|
79
77
|
}
|
80
78
|
|
81
79
|
const renamedData = renameData(data);
|
82
|
-
const
|
80
|
+
const resultLength = getResultsLength(renamedData, renamedDataPath);
|
83
81
|
|
84
|
-
if (
|
85
|
-
showEmptyState &&
|
86
|
-
((Array.isArray(result) && result.length === 0) || !result)
|
87
|
-
) {
|
82
|
+
if (showEmptyState && !resultLength) {
|
88
83
|
return emptyWrapper(
|
89
84
|
<EmptyState
|
90
85
|
{...{
|
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: 7.1.
|
4
|
+
version: 7.1.3
|
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-08-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: acts_as_list
|
@@ -186,7 +186,6 @@ files:
|
|
186
186
|
- app/views/foreman_ansible/job_templates/ansible_roles_-_install_from_git.erb
|
187
187
|
- app/views/foreman_ansible/job_templates/ansible_windows_updates.erb
|
188
188
|
- app/views/foreman_ansible/job_templates/capsule_upgrade_-_ansible_default.erb
|
189
|
-
- app/views/foreman_ansible/job_templates/configure_cloud_connector_-_ansible_default.erb
|
190
189
|
- app/views/foreman_ansible/job_templates/convert_to_rhel.erb
|
191
190
|
- app/views/foreman_ansible/job_templates/maintenance_plan.erb
|
192
191
|
- app/views/foreman_ansible/job_templates/module_action_-_ansible_default.erb
|
@@ -289,6 +288,7 @@ files:
|
|
289
288
|
- test/functional/ui_ansible_roles_controller_test.rb
|
290
289
|
- test/graphql/mutations/hosts/assign_ansible_roles_mutation_test.rb
|
291
290
|
- test/graphql/queries/ansible_roles_query_test.rb
|
291
|
+
- test/graphql/queries/host_ansible_roles_query_test.rb
|
292
292
|
- test/test_plugin_helper.rb
|
293
293
|
- test/unit/actions/run_ansible_job_test.rb
|
294
294
|
- test/unit/actions/run_proxy_ansible_command_test.rb
|
@@ -458,54 +458,55 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
458
458
|
- !ruby/object:Gem::Version
|
459
459
|
version: '0'
|
460
460
|
requirements: []
|
461
|
-
rubygems_version: 3.
|
461
|
+
rubygems_version: 3.2.26
|
462
462
|
signing_key:
|
463
463
|
specification_version: 4
|
464
464
|
summary: Ansible integration with Foreman (theforeman.org)
|
465
465
|
test_files:
|
466
|
-
- test/
|
466
|
+
- test/factories/ansible_proxy.rb
|
467
|
+
- test/factories/ansible_roles.rb
|
468
|
+
- test/factories/ansible_variables.rb
|
469
|
+
- test/factories/host_ansible_enhancements.rb
|
470
|
+
- test/fixtures/insights_playbook.yaml
|
471
|
+
- test/fixtures/playbooks_example_output.json
|
472
|
+
- test/fixtures/report.json
|
473
|
+
- test/fixtures/sample_facts.json
|
474
|
+
- test/fixtures/sample_playbooks.json
|
475
|
+
- test/foreman_ansible/helpers/ansible_roles_helper_test.rb
|
467
476
|
- test/functional/ansible_roles_controller_test.rb
|
468
|
-
- test/functional/
|
477
|
+
- test/functional/ansible_variables_controller_test.rb
|
478
|
+
- test/functional/api/v2/ansible_inventories_controller_test.rb
|
479
|
+
- test/functional/api/v2/ansible_playbooks_controller_test.rb
|
469
480
|
- test/functional/api/v2/ansible_roles_controller_test.rb
|
481
|
+
- test/functional/api/v2/ansible_variables_controller_test.rb
|
470
482
|
- test/functional/api/v2/hostgroups_controller_test.rb
|
471
|
-
- test/functional/api/v2/ansible_playbooks_controller_test.rb
|
472
|
-
- test/functional/api/v2/ansible_inventories_controller_test.rb
|
473
483
|
- test/functional/api/v2/hosts_controller_test.rb
|
474
|
-
- test/functional/ui_ansible_roles_controller_test.rb
|
475
484
|
- test/functional/hosts_controller_test.rb
|
485
|
+
- test/functional/ui_ansible_roles_controller_test.rb
|
476
486
|
- test/graphql/mutations/hosts/assign_ansible_roles_mutation_test.rb
|
477
487
|
- test/graphql/queries/ansible_roles_query_test.rb
|
478
|
-
- test/
|
488
|
+
- test/graphql/queries/host_ansible_roles_query_test.rb
|
489
|
+
- test/test_plugin_helper.rb
|
479
490
|
- test/unit/actions/run_ansible_job_test.rb
|
480
491
|
- test/unit/actions/run_proxy_ansible_command_test.rb
|
481
|
-
- test/unit/
|
482
|
-
- test/unit/services/ui_roles_importer_test.rb
|
483
|
-
- test/unit/services/ansible_report_importer_test.rb
|
484
|
-
- test/unit/services/insights_plan_runner_test.rb
|
485
|
-
- test/unit/services/override_resolver_test.rb
|
486
|
-
- test/unit/services/roles_importer_test.rb
|
487
|
-
- test/unit/services/inventory_creator_test.rb
|
488
|
-
- test/unit/services/ansible_variables_importer_test.rb
|
489
|
-
- test/unit/lib/proxy_api/ansible_test.rb
|
492
|
+
- test/unit/ansible_provider_test.rb
|
490
493
|
- test/unit/ansible_role_test.rb
|
491
|
-
- test/unit/hostgroup_ansible_role_test.rb
|
492
494
|
- test/unit/ansible_variable_test.rb
|
493
|
-
- test/unit/
|
495
|
+
- test/unit/concerns/config_reports_extensions_test.rb
|
496
|
+
- test/unit/concerns/host_managed_extensions_test.rb
|
497
|
+
- test/unit/concerns/hostgroup_extensions_test.rb
|
494
498
|
- test/unit/helpers/ansible_reports_helper_test.rb
|
495
|
-
- test/unit/
|
499
|
+
- test/unit/host_ansible_role_test.rb
|
500
|
+
- test/unit/hostgroup_ansible_role_test.rb
|
496
501
|
- test/unit/ignore_roles_test.rb
|
497
502
|
- test/unit/import_playbooks_test.rb
|
498
503
|
- test/unit/import_roles_and_variables.rb
|
499
|
-
- test/unit/
|
500
|
-
- test/unit/
|
501
|
-
- test/unit/
|
502
|
-
- test/
|
503
|
-
- test/
|
504
|
-
- test/
|
505
|
-
- test/
|
506
|
-
- test/
|
507
|
-
- test/
|
508
|
-
- test/fixtures/insights_playbook.yaml
|
509
|
-
- test/fixtures/playbooks_example_output.json
|
510
|
-
- test/fixtures/sample_playbooks.json
|
511
|
-
- test/test_plugin_helper.rb
|
504
|
+
- test/unit/lib/proxy_api/ansible_test.rb
|
505
|
+
- test/unit/services/ansible_report_importer_test.rb
|
506
|
+
- test/unit/services/ansible_variables_importer_test.rb
|
507
|
+
- test/unit/services/api_roles_importer_test.rb
|
508
|
+
- test/unit/services/insights_plan_runner_test.rb
|
509
|
+
- test/unit/services/inventory_creator_test.rb
|
510
|
+
- test/unit/services/override_resolver_test.rb
|
511
|
+
- test/unit/services/roles_importer_test.rb
|
512
|
+
- test/unit/services/ui_roles_importer_test.rb
|
data/app/views/foreman_ansible/job_templates/configure_cloud_connector_-_ansible_default.erb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
<%#
|
2
|
-
name: Configure Cloud Connector
|
3
|
-
snippet: false
|
4
|
-
template_inputs:
|
5
|
-
- name: satellite_user
|
6
|
-
required: true
|
7
|
-
input_type: user
|
8
|
-
advanced: false
|
9
|
-
value_type: plain
|
10
|
-
hidden_value: false
|
11
|
-
- name: satellite_password
|
12
|
-
required: true
|
13
|
-
input_type: user
|
14
|
-
advanced: false
|
15
|
-
value_type: plain
|
16
|
-
hidden_value: true
|
17
|
-
- name: http_proxy
|
18
|
-
required: false
|
19
|
-
input_type: user
|
20
|
-
advanced: true
|
21
|
-
value_type: plain
|
22
|
-
hidden_value: false
|
23
|
-
description: You can specify a HTTP proxy address that should be used for Cloud Connector connection to the cloud.redhat.com. Note that it must be HTTP proxy, not HTTPS. The tunelling of SSL (secured web socket connection) in SSL (HTTPS proxy) is currently unsupported.
|
24
|
-
model: JobTemplate
|
25
|
-
job_category: Maintenance Operations
|
26
|
-
description_format: "%{template_name}"
|
27
|
-
provider_type: Ansible
|
28
|
-
kind: job_template
|
29
|
-
feature: ansible_configure_cloud_connector
|
30
|
-
%>
|
31
|
-
|
32
|
-
---
|
33
|
-
- hosts: all
|
34
|
-
vars:
|
35
|
-
satellite_url: "<%= foreman_server_url %>"
|
36
|
-
roles:
|
37
|
-
- project-receptor.satellite_receptor_installer
|