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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dc6d250a74d7e811600edfd0f78551286d8800644512d4346fd6d5794fe451f3
4
- data.tar.gz: f7057a56a7e5fda90510ab9aa13b70b59efa90f07a8e7fb3460140102e36d390
3
+ metadata.gz: 2754fa1c5a9834d8b174906f4848ce5ba7e5699a9c757e6761b24c1ced021f52
4
+ data.tar.gz: b9c7d3e372fbde5eb5a6e5b94af335293ec660b81511c23f4cd519868632988a
5
5
  SHA512:
6
- metadata.gz: 99dbfada521e9075ae164312cdf3eecb85e663beca47e558b5d3fd61cde68bb2a632e29f80ca9dcbf5519be3122a15b6c2777f4400b6bd685c84f2488a02baf4
7
- data.tar.gz: b8a5fde3a9bb62aaf578b5d08ef24afe6bd9ddc2ac7af33b732a6c8eadfeb077dc92f0db86496975f44d3b9ad0c59acdb176f1722e964de5a4afb7a7c826182c
6
+ metadata.gz: 933f56fb3c7eb0389397067189f9b64f7fc2ec44fb631e26b0943748b80c80f51b23e2897f4175ff4e8f28b5dbd1232e51641a429b07de1fd2786ba7d44fc4bc
7
+ data.tar.gz: d9c4973117fa530f4dfbd93720692a9331c1172b120f66aa6df4cb59f9dfe3162b2004c5f7e2e9b1f3bf99283524154fb2e1fe4a8045839c97823895a446a8e6
@@ -4,6 +4,10 @@ module Presenters
4
4
 
5
5
  delegate :id, :name, :association, :to => :ansible_role
6
6
 
7
+ def self.graphql_type
8
+ 'Types::InheritedAnsibleRole'
9
+ end
10
+
7
11
  def initialize(ansible_role, inherited)
8
12
  @ansible_role = ansible_role
9
13
  @inherited = inherited
@@ -6,5 +6,6 @@ module Types
6
6
 
7
7
  field :name, String, :null => false
8
8
  field :path, resolver: Resolvers::AnsibleRole::Path
9
+ has_many :ansible_variables, ::Types::AnsibleVariable
9
10
  end
10
11
  end
@@ -2,6 +2,10 @@ module Types
2
2
  class InheritedAnsibleRole < ::Types::AnsibleRole
3
3
  field :inherited, Boolean, :null => false
4
4
 
5
+ def self.record_for(object)
6
+ object.ansible_role
7
+ end
8
+
5
9
  def object_class
6
10
  object.ansible_role.class
7
11
  end
@@ -23,6 +23,9 @@ model: JobTemplate
23
23
  ---
24
24
  - hosts: all
25
25
  tasks:
26
- - command: git clone <%= input('git_repository') %> <%= input('location') %>
26
+ - git:
27
+ repo: "<%= input('git_repository') %>"
28
+ dest: "<%= input('location') %>"
27
29
  register: out
30
+
28
31
  - debug: var=out
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Foreman::Plugin.register :foreman_ansible do
4
- requires_foreman '>= 3.0'
4
+ requires_foreman '>= 3.3'
5
5
 
6
6
  settings do
7
7
  category :ansible, N_('Ansible') do
@@ -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
@@ -4,5 +4,5 @@
4
4
  # This way other parts of Foreman can just call ForemanAnsible::VERSION
5
5
  # and detect what version the plugin is running.
6
6
  module ForemanAnsible
7
- VERSION = '7.1.0'
7
+ VERSION = '7.1.3'
8
8
  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
@@ -1,7 +1,7 @@
1
- import React, { useState, useEffect } from 'react';
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 [formState, setFormState] = useState({
25
- availableOptions: [],
26
- chosenOptions: [],
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
- useEffect(() => {
30
- setFormState({
31
- availableOptions: availableRoles.map(item => item.name),
32
- chosenOptions: assignedRoles.map(item => item.name) || [],
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, formState.chosenOptions),
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={formState.availableOptions}
69
- chosenOptions={formState.chosenOptions}
70
- onListChange={(newAvailable, newChosen) =>
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.isRequired,
84
- availableRoles: PropTypes.array.isRequired,
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: '70%',
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}
@@ -2,8 +2,6 @@ import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
2
2
 
3
3
  import AnsibleRolesSwitcher from '../AnsibleRolesSwitcher';
4
4
 
5
- jest.mock('foremanReact/components/Pagination/PaginationWrapper');
6
-
7
5
  const noop = () => {};
8
6
 
9
7
  const fixtures = {
@@ -13,14 +13,12 @@ import {
13
13
  } from '../permissionsHelper';
14
14
  import ErrorState from './ErrorState';
15
15
 
16
- const pluckData = (data, path) => {
16
+ const getResultsLength = (data, path) => {
17
17
  const split = path.split('.');
18
- return split.reduce((memo, item) => {
19
- if (item) {
20
- return memo[item];
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 result = pluckData(renamedData, renamedDataPath);
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.0
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-03-14 00:00:00.000000000 Z
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.3.4
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/functional/ansible_variables_controller_test.rb
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/api/v2/ansible_variables_controller_test.rb
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/foreman_ansible/helpers/ansible_roles_helper_test.rb
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/services/api_roles_importer_test.rb
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/host_ansible_role_test.rb
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/ansible_provider_test.rb
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/concerns/config_reports_extensions_test.rb
500
- - test/unit/concerns/host_managed_extensions_test.rb
501
- - test/unit/concerns/hostgroup_extensions_test.rb
502
- - test/factories/ansible_proxy.rb
503
- - test/factories/host_ansible_enhancements.rb
504
- - test/factories/ansible_variables.rb
505
- - test/factories/ansible_roles.rb
506
- - test/fixtures/report.json
507
- - test/fixtures/sample_facts.json
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
@@ -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