foreman_ansible 6.3.4 → 6.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/app/helpers/foreman_ansible/ansible_reports_helper.rb +35 -54
  3. data/app/helpers/foreman_ansible/ansible_roles_data_preparations.rb +22 -22
  4. data/app/models/concerns/foreman_ansible/hostgroup_extensions.rb +1 -1
  5. data/app/models/foreman_ansible/ansible_provider.rb +54 -2
  6. data/app/views/foreman_ansible/config_reports/_ansible.html.erb +14 -5
  7. data/app/views/foreman_ansible/job_templates/ansible_roles_-_ansible_default.erb +4 -0
  8. data/app/views/foreman_ansible/job_templates/convert_to_rhel.erb +1 -1
  9. data/lib/foreman_ansible/engine.rb +0 -1
  10. data/lib/foreman_ansible/register.rb +4 -3
  11. data/lib/foreman_ansible/version.rb +1 -1
  12. data/package.json +7 -5
  13. data/test/unit/ansible_provider_test.rb +6 -3
  14. data/test/unit/helpers/ansible_reports_helper_test.rb +4 -30
  15. data/test/unit/hostgroup_ansible_role_test.rb +0 -13
  16. data/webpack/components/AnsibleHostDetail/AnsibleHostDetail.js +35 -0
  17. data/webpack/components/AnsibleHostDetail/AnsibleHostDetail.scss +6 -0
  18. data/webpack/components/AnsibleHostDetail/AnsibleHostDetail.test.js +14 -0
  19. data/webpack/components/AnsibleHostDetail/index.js +6 -0
  20. data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AnsiblePermissionDenied.test.js.snap +2 -0
  21. data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AssignedRolesList.test.js.snap +4 -4
  22. data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AvailableRolesList.test.js.snap +5 -0
  23. data/webpack/global_index.js +12 -0
  24. metadata +14 -35
  25. data/test/unit/lib/foreman_ansible_core/ansible_runner_test.rb +0 -51
  26. data/test/unit/lib/foreman_ansible_core/command_creator_test.rb +0 -64
  27. data/test/unit/lib/foreman_ansible_core/playbook_runner_test.rb +0 -110
  28. data/webpack/__mocks__/foremanReact/common/I18n.js +0 -1
  29. data/webpack/__mocks__/foremanReact/common/helpers.js +0 -13
  30. data/webpack/__mocks__/foremanReact/components/Pagination/PaginationWrapper.js +0 -2
  31. data/webpack/__mocks__/foremanReact/components/common/EmptyState.js +0 -5
  32. data/webpack/__mocks__/foremanReact/components/common/forms/OrderableSelect/helpers.js +0 -5
  33. data/webpack/__mocks__/foremanReact/redux/API.js +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 70ef5c59ee6bba3f3b62db1288f39776cf0661b2e12c7145212345e7e291b8cf
4
- data.tar.gz: bb25459005a758c693a97cfcd6ef202ddffb8831374417be1588073f7ef97ff5
3
+ metadata.gz: 05c975cb77fe5add41b7281dfa1c2451bb22a09ab5dc6251ab06fd4d00b834e2
4
+ data.tar.gz: 86613f4be767b5af80a06f83b9e13f8f030cd80bc362d866323111b61a0b23a9
5
5
  SHA512:
6
- metadata.gz: c2a37f0db636e45970d8c3c34584d44912e5d0569af15915112a7ab9438717651e3fbe3291e7fcc82a052ea985833beb393e30347dcf8b2e83341ed5d1cd2377
7
- data.tar.gz: 2fae33324c5c41462ad4375f68344e34872b45085a64c91f08f5a2465cd77e08c22b1087fb17a5f06299bb887ada63c40f0953de8e012e960ae2bf74b0e1c66f
6
+ metadata.gz: dc27695cef374e8b709ddc3c3882056587cbf975ac7d497c1fec5aaa1885f85bcb3677c2c7fd3f2602f529cba0a6736017703f6d7ca413eb5f2ed7a6de112a94
7
+ data.tar.gz: ba0c5f9b94a51b7328cc0df73bfcc0f47831b1004b275be935fa73a83ae9c6f12b81086071ebe69292c8aa5ad436c5389a6a6f1ac457720bcefe034b456c0ec8
@@ -4,21 +4,19 @@ module ForemanAnsible
4
4
  # This module takes the config reports stored in Foreman for Ansible and
5
5
  # modifies them to be properly presented in views
6
6
  module AnsibleReportsHelper
7
- ANSIBLE_META_KEYS = %w[
8
- _ansible_parsed _ansible_no_log _ansible_item_result
9
- _ansible_ignore_errors _ansible_verbose_always _ansible_verbose_override
10
- ].freeze
11
- ANSIBLE_HIDDEN_KEYS = %w[
12
- invocation module_args results ansible_facts
13
- stdout stderr
14
- ].freeze
15
-
16
7
  def ansible_module_name(log)
17
8
  source_value = log.source&.value
18
9
  name = source_value.split(':')[0].strip if source_value&.include?(':')
19
10
  name
20
11
  end
21
12
 
13
+ def ansible_task_name(log)
14
+ source_value = log.source&.value
15
+ return source_value || no_data_message unless source_value.include? ':'
16
+ name = source_value.split(':')[1].strip if source_value.include?(':')
17
+ name || no_data_message
18
+ end
19
+
22
20
  def ansible_run_in_check_mode?(log)
23
21
  log.message&.value == 'check_mode_enabled' if check_mode_log?(log)
24
22
  end
@@ -27,12 +25,36 @@ module ForemanAnsible
27
25
  log.source&.value == 'check_mode'
28
26
  end
29
27
 
30
- def ansible_module_args(log)
31
- report_json_viewer module_invocations parsed_message_json(log)
28
+ def ansible_module_message(log)
29
+ msg_json = parsed_message_json(log)
30
+ module_action = msg_json['module']
31
+ case module_action
32
+ when 'package'
33
+ msg_json['results'].empty? ? msg_json['msg'] : msg_json['results']
34
+ when 'template'
35
+ module_args = msg_json['invocation']['module_args']
36
+ _("Rendered template #{module_args['_original_basename']} to #{msg_json['dest']}")
37
+ when 'service'
38
+ _("Service #{msg_json['name']} #{msg_json['state']} (enabled: #{msg_json['enabled']})")
39
+ when 'group'
40
+ _("User group #{msg_json['name']} #{msg_json['state']}, gid: #{msg_json['gid']}")
41
+ when 'user'
42
+ _("User #{msg_json['name']} #{msg_json['state']}, uid: #{msg_json['uid']}")
43
+ when 'cron'
44
+ module_args = msg_json['invocation']['module_args']
45
+ _("Cron job: #{module_args['minute']} #{module_args['hour']} #{module_args['day']} #{module_args['month']} #{module_args['weekday']} #{module_args['job']} (disabled: #{module_args['disabled']})")
46
+ when 'copy'
47
+ module_args = msg_json['invocation']['module_args']
48
+ _("Copy #{module_args['_original_basename']} to #{msg_json['dest']}")
49
+ when 'command', 'shell'
50
+ msg_json['stdout_lines']
51
+ else
52
+ no_data_message
53
+ end
32
54
  end
33
55
 
34
- def ansible_module_message(log)
35
- report_json_viewer hash_with_keys_removed parsed_message_json(log)
56
+ def no_data_message
57
+ _('No additional data')
36
58
  end
37
59
 
38
60
  def ansible_report_origin_icon
@@ -49,49 +71,8 @@ module ForemanAnsible
49
71
  false
50
72
  end
51
73
 
52
- def report_json_viewer(json)
53
- react_component('ReportJsonViewer', data: json)
54
- end
55
-
56
74
  private
57
75
 
58
- def module_invocations(hash)
59
- invocations = []
60
- invocations << hash.delete('invocation')
61
- results = hash.delete('results')
62
- invocations << results
63
- invocations = invocations.compact.flatten.map do |ih|
64
- ih.is_a?(Hash) ? remove_keys(ih) : ih
65
- end
66
- invocations
67
- end
68
-
69
- def pretty_print_hash(hash)
70
- prettyp = JSON.pretty_generate(remove_keys(hash))
71
- prettyp.gsub!(/{\n*/, "\n")
72
- prettyp.gsub!(/},*\n*/, "\n")
73
- prettyp.gsub!(/^(\[|\])/, '')
74
- prettyp.gsub!(/^[\s]*$\n/, '')
75
- paragraph_style = 'white-space:pre;padding: 2em 0'
76
- tag(:p, prettyp, :style => paragraph_style)
77
- end
78
-
79
- def hash_with_keys_removed(hash)
80
- new_hash = remove_keys(hash)
81
- remove_keys(new_hash, ANSIBLE_HIDDEN_KEYS)
82
- end
83
-
84
- def remove_keys(hash, keys = ANSIBLE_META_KEYS)
85
- hash.each do |key, value|
86
- if value.is_a? Array
87
- value.each { |h| remove_keys(h) if h.is_a? Hash }
88
- elsif value.is_a? Hash
89
- remove_keys(value)
90
- end
91
- hash.delete(key) if keys.include? key
92
- end
93
- end
94
-
95
76
  def parsed_message_json(log)
96
77
  JSON.parse(log.message.value)
97
78
  rescue StandardError => e
@@ -2,22 +2,22 @@
2
2
 
3
3
  module ForemanAnsible
4
4
  module AnsibleRolesDataPreparations
5
- VARIABLE_ACTION_NAMES = { 'new' => _('Add'), 'obsolete' => _('Remove'), 'update' => _('Update') }.freeze
6
- ROLE_ACTION_NAMES = { 'new' => _('Import Role'), 'obsolete' => _('Remove Role'), 'old' => _('Update Role Variables') }.freeze
5
+ VARIABLE_ACTION_NAMES = { 'new' => N_('Add'), 'obsolete' => N_('Remove'), 'update' => N_('Update') }.freeze
6
+ ROLE_ACTION_NAMES = { 'new' => N_('Import Role'), 'obsolete' => N_('Remove Role'), 'old' => N_('Update Role Variables') }.freeze
7
7
 
8
- def variable_action_name(kind)
9
- VARIABLE_ACTION_NAMES[kind]
8
+ def get_variable_action(kind)
9
+ _(VARIABLE_ACTION_NAMES[kind])
10
10
  end
11
11
 
12
- def role_action_name(kind)
13
- ROLE_ACTION_NAMES[kind]
12
+ def get_role_action(kind)
13
+ _(ROLE_ACTION_NAMES[kind])
14
14
  end
15
15
 
16
16
  def get_old_roles_variables(imported_variables, role)
17
- variables = { 'new' => [], 'obsolete' => [], 'update' => [] }
17
+ variables = { 'Add' => [], 'Remove' => [], 'Update' => [] }
18
18
  imported_variables.each do |kind, temp_variables|
19
19
  temp_variables.each do |temp_variable|
20
- variables[kind].append(temp_variable.key) if temp_variable.ansible_role_id == role.id
20
+ variables[get_variable_action(kind)].append(temp_variable.key) if temp_variable.ansible_role_id == role.id
21
21
  end
22
22
  end
23
23
  variables
@@ -26,16 +26,16 @@ module ForemanAnsible
26
26
  def variables_to_s(variables)
27
27
  str = ''
28
28
  variables.each do |action, temp_variables|
29
- str += "#{variable_action_name action}: #{temp_variables.size}, " unless temp_variables.empty?
29
+ str += "#{action}: #{temp_variables.size}, " unless temp_variables.empty?
30
30
  end
31
31
  str[0..-3]
32
32
  end
33
33
 
34
34
  def get_roles_variables(imported_variables, variables_importer, kind, role)
35
35
  if kind == 'new'
36
- variables = { 'new' => variables_importer.get_variables_names(role.name) }
36
+ variables = { 'Add' => variables_importer.get_variables_names(role.name) }
37
37
  elsif kind == 'obsolete'
38
- variables = { 'obsolete' => role.ansible_variables.map(&:key) }
38
+ variables = { 'Remove' => role.ansible_variables.map(&:key) }
39
39
  elsif kind == 'old'
40
40
  variables = get_old_roles_variables(imported_variables, role)
41
41
  end
@@ -51,25 +51,24 @@ module ForemanAnsible
51
51
  match.to_s.empty? ? nil : match
52
52
  end
53
53
 
54
- def prepare_api_row(role, kind, variables)
54
+ def prepare_api_row(role, kind, variables, role_action)
55
55
  {
56
56
  name: role.name,
57
57
  id: role.id,
58
- role_action: role_action_name(kind),
58
+ role_action: role_action,
59
59
  variables: variables,
60
- hosts_count: kind == 'obsolete' ? role.hosts.count : '',
61
- hostgroup_count: kind == 'obsolete' ? role.hostgroups.count : '',
60
+ hosts_count: role_action == 'Remove Role' ? role.hosts.count : '',
61
+ hostgroup_count: role_action == 'Remove Role' ? role.hostgroups.count : '',
62
62
  kind: kind
63
63
  }
64
64
  end
65
65
 
66
- def prepare_ui_row(role, kind, variables)
66
+ def prepare_ui_row(role, kind, variables, role_action)
67
67
  { cells: [
68
68
  role.name,
69
- role_action_name(kind),
70
- variables,
71
- kind == 'obsolete' ? role.hosts.count : '',
72
- kind == 'obsolete' ? role.hostgroups.count : ''
69
+ role_action, variables,
70
+ role_action == 'Remove Role' ? role.hosts.count : '',
71
+ role_action == 'Remove Role' ? role.hostgroups.count : ''
73
72
  ],
74
73
  role: role, kind: kind, id: role.name }
75
74
  end
@@ -82,10 +81,11 @@ module ForemanAnsible
82
81
  next if role_match_excluded_roles(role.name)
83
82
  variables = get_roles_variables(imported_variables, variables_importer, kind, role)
84
83
  next if variables.empty? && kind['old']
84
+ role_action = get_role_action(kind)
85
85
  if is_ui
86
- rows.append(prepare_ui_row(role, kind, variables))
86
+ rows.append(prepare_ui_row(role, kind, variables, role_action))
87
87
  else
88
- rows.append(prepare_api_row(role, kind, variables))
88
+ rows.append(prepare_api_row(role, kind, variables, role_action))
89
89
  end
90
90
  end
91
91
  end
@@ -6,7 +6,7 @@ module ForemanAnsible
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  included do
9
- has_many :hostgroup_ansible_roles, -> { order('hostgroup_ansible_roles.position ASC') }, :foreign_key => :hostgroup_id
9
+ has_many :hostgroup_ansible_roles, :foreign_key => :hostgroup_id
10
10
  has_many :ansible_roles,
11
11
  -> { order('hostgroup_ansible_roles.position ASC') },
12
12
  :through => :hostgroup_ansible_roles,
@@ -18,6 +18,10 @@ if defined? ForemanRemoteExecution
18
18
  'Ansible'
19
19
  end
20
20
 
21
+ def provider_input_namespace
22
+ :ansible
23
+ end
24
+
21
25
  def proxy_command_options(template_invocation, host)
22
26
  super(template_invocation, host).merge(
23
27
  'ansible_inventory' => ::ForemanAnsible::InventoryCreator.new(
@@ -34,7 +38,6 @@ if defined? ForemanRemoteExecution
34
38
 
35
39
  def secrets(host)
36
40
  {
37
- :key_passphrase => Setting[:remote_execution_ssh_key_passphrase],
38
41
  'per-host' => {
39
42
  host.name => {
40
43
  'ansible_password' => rex_ssh_password(host),
@@ -52,16 +55,65 @@ if defined? ForemanRemoteExecution
52
55
  host_setting(host, 'remote_execution_effective_user_password')
53
56
  end
54
57
 
58
+ def host_setting(host, setting)
59
+ host.params[setting.to_s] || Setting[setting]
60
+ end
61
+
55
62
  def supports_effective_user?
56
63
  true
57
64
  end
58
65
 
66
+ def provider_inputs
67
+ [
68
+ ForemanRemoteExecution::ProviderInput.new(
69
+ name: 'tags',
70
+ label: _('Tags'),
71
+ value: '',
72
+ value_type: 'plain',
73
+ description: 'Tags used for Ansible execution'
74
+ ),
75
+ ForemanRemoteExecution::ProviderInput.new(
76
+ name: 'tags_flag',
77
+ label: _('Include/Exclude Tags'),
78
+ value: 'include',
79
+ description: 'Option whether to include or exclude tags',
80
+ options: "include\nexclude"
81
+ )
82
+ ]
83
+ end
84
+
85
+ def provider_inputs_doc
86
+ opts = provider_inputs.find { |input| input.name == 'tags_flag' }.options.split("\n")
87
+ {
88
+ :namespace => provider_input_namespace,
89
+ :opts => { :desc => N_('Ansible provider specific inputs') },
90
+ :children => [
91
+ {
92
+ :name => :tags,
93
+ :type => Array,
94
+ :opts => { :required => false, :desc => N_('A comma separated list of tags to use for Ansible run') }
95
+ },
96
+ {
97
+ :name => :tags_flag,
98
+ :type => opts,
99
+ :opts => { :required => false, :desc => N_('Include\Exclude tags for Ansible run') }
100
+ }
101
+ ]
102
+ }
103
+ end
104
+
105
+ def proxy_command_provider_inputs(template_invocation)
106
+ tags = template_invocation.provider_input_values.find_by(:name => 'tags')&.value || ''
107
+ tags_flag = template_invocation.provider_input_values.find_by(:name => 'tags_flag')&.value || ''
108
+ { :tags => tags, :tags_flag => tags_flag }
109
+ end
110
+
59
111
  def proxy_operation_name
60
112
  'ansible-runner'
61
113
  end
62
114
 
63
115
  def proxy_action_class
64
- 'ForemanAnsibleCore::TaskLauncher::Playbook::PlaybookRunnerAction'
116
+ 'Proxy::Ansible::TaskLauncher::Playbook::PlaybookRunnerAction'
65
117
  end
66
118
 
67
119
  private
@@ -10,8 +10,7 @@
10
10
  <thead>
11
11
  <tr>
12
12
  <th><%= _("Level") %></th>
13
- <th><%= _("Module") %></th>
14
- <th><%= _("Arguments") %></th>
13
+ <th><%= _("Task") %></th>
15
14
  <th><%= _("Message") %></th>
16
15
  </tr>
17
16
  </thead>
@@ -20,9 +19,19 @@
20
19
  <% unless check_mode_log?(log) %>
21
20
  <tr>
22
21
  <td><span <%= report_tag log.level %>><%= h log.level %></span></td>
23
- <td><%= ansible_module_name(log) %></td>
24
- <td><%= ansible_module_args(log) %></td>
25
- <td><%= ansible_module_message(log) %></td>
22
+ <td><span title=<%= ansible_module_name(log) %>><%= ansible_task_name(log) %></span></td>
23
+ <td>
24
+ <% log_message = ansible_module_message(log) %>
25
+ <% if log_message.is_a? Array %>
26
+ <ul>
27
+ <% log_message.each do |message_line| %>
28
+ <li><%= message_line %></li>
29
+ <% end %>
30
+ </ul>
31
+ <% else %>
32
+ <%= log_message %>
33
+ <% end %>
34
+ </td>
26
35
  </tr>
27
36
  <% end %>
28
37
  <% end %>
@@ -15,10 +15,14 @@ model: JobTemplate
15
15
  - name: Display all parameters known for the Foreman host
16
16
  debug:
17
17
  var: foreman
18
+ tags:
19
+ - always
18
20
  tasks:
19
21
  - name: Apply roles
20
22
  include_role:
21
23
  name: "{{ role }}"
24
+ tags:
25
+ - always
22
26
  loop: "{{ foreman_ansible_roles }}"
23
27
  loop_control:
24
28
  loop_var: role
@@ -34,7 +34,7 @@ kind: job_template
34
34
  url: <%= subscription_manager_configuration_url(@host) %>
35
35
  dest: /usr/share/convert2rhel/subscription-manager/katello-ca-consumer-latest.noarch.rpm
36
36
  - name: Start convert2rhel
37
- command: convert2rhel -y --activationkey "<%= input('Activation Key') %>" --org "<%= @host.organization.label %>" --keep-rhsm
37
+ command: convert2rhel -y --activationkey "<%= input('Activation Key') %>" --org "<%= @host.organization.label %>" > /root/convert2rhel.log
38
38
  <%- if input('Restart') == "yes" -%>
39
39
  - name: Reboot the machine
40
40
  reboot:
@@ -4,7 +4,6 @@ require 'deface'
4
4
  require 'acts_as_list'
5
5
  require 'fast_gettext'
6
6
  require 'gettext_i18n_rails'
7
- require 'foreman_ansible_core' if Rails.env.test?
8
7
  require 'foreman_ansible/remote_execution'
9
8
 
10
9
  module ForemanAnsible
@@ -76,10 +76,9 @@ Foreman::Plugin.register :foreman_ansible do
76
76
 
77
77
  role 'Ansible Roles Manager',
78
78
  [:play_roles_on_host, :play_roles_on_hostgroup,
79
- :create_job_invocations, :view_job_templates, # to allow the play_roles
80
- :create_template_invocations, :view_smart_proxies, # ...
81
79
  :view_ansible_roles, :destroy_ansible_roles,
82
- :import_ansible_roles, :view_ansible_variables,
80
+ :import_ansible_roles,
81
+ :view_ansible_variables,
83
82
  :create_ansible_variables, :import_ansible_variables,
84
83
  :edit_ansible_variables, :destroy_ansible_variables]
85
84
 
@@ -97,6 +96,8 @@ Foreman::Plugin.register :foreman_ansible do
97
96
  parameter_filter Host::Managed, base_role_assignment_params.merge(:host_ansible_roles_attributes => {})
98
97
  parameter_filter Hostgroup, base_role_assignment_params.merge(:hostgroup_ansible_roles_attributes => {})
99
98
 
99
+ register_global_js_file 'global'
100
+
100
101
  divider :top_menu, :caption => N_('Ansible'), :parent => :configure_menu
101
102
  menu :top_menu, :ansible_roles,
102
103
  :caption => N_('Roles'),
@@ -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 = '6.3.4'
7
+ VERSION = '6.4.0'
8
8
  end
data/package.json CHANGED
@@ -14,16 +14,18 @@
14
14
  },
15
15
  "devDependencies": {
16
16
  "@babel/core": "^7.7.0",
17
- "@theforeman/builder": "^6.0.0",
18
- "@theforeman/eslint-plugin-foreman": "6.0.0",
19
- "@theforeman/test": "^6.0.0",
20
- "@theforeman/vendor-dev": "^6.0.0",
17
+ "@theforeman/builder": "^8.4.1",
18
+ "@theforeman/eslint-plugin-foreman": "^8.4.1",
19
+ "@theforeman/find-foreman": "^8.4.1",
20
+ "@theforeman/stories": "^8.4.1",
21
+ "@theforeman/test": "^8.4.1",
22
+ "@theforeman/vendor-dev": "^8.4.1",
21
23
  "babel-eslint": "^10.0.3",
22
24
  "eslint": "^6.7.2",
23
25
  "prettier": "^1.13.5"
24
26
  },
25
27
  "scripts": {
26
- "test": "tfm-test --plugin",
28
+ "test": "tfm-test --plugin --config jest.config.js",
27
29
  "lint": "tfm-lint --plugin -d webpack"
28
30
  },
29
31
  "repository": {
@@ -30,11 +30,14 @@ class AnsibleProviderTest < ActiveSupport::TestCase
30
30
  end
31
31
 
32
32
  context 'when using secrets' do
33
- let(:host) { FactoryBot.create(:host) }
33
+ let(:host) { FactoryBot.build(:host) }
34
34
 
35
35
  it 'generates secrets properly' do
36
- host.parameters << HostParameter.new(name: 'remote_execution_ssh_password', value: 'password')
37
- host.parameters << HostParameter.new(name: 'remote_execution_effective_user_password', value: 'letmein')
36
+ params = {
37
+ 'remote_execution_ssh_password' => 'password',
38
+ 'remote_execution_effective_user_password' => 'letmein'
39
+ }
40
+ host.expects(:params).twice.returns(params)
38
41
  secrets = ForemanAnsible::AnsibleProvider.secrets(host)
39
42
  host_secrets = secrets['per-host'][host.name]
40
43
  assert_equal host_secrets['ansible_password'], 'password'
@@ -6,43 +6,17 @@ class AnsibleReportsHelperTest < ActiveSupport::TestCase
6
6
  include ForemanAnsible::AnsibleReportsHelper
7
7
  include ActionView::Helpers::TagHelper
8
8
 
9
- test 'is able to print a string instead of a hash' do
9
+ test 'module message extraction' do
10
10
  log_value = <<-ANSIBLELOG.strip_heredoc
11
- {"_ansible_parsed": true, "_ansible_no_log": false, "changed": false, "results": ["ntp-4.2.8p10-3.fc27.x86_64 providing ntp is already installed"], "rc": 0, "invocation": {"module_args": {"allow_downgrade": false, "name": ["ntp"], "list": null, "disable_gpg_check": false, "conf_file": null, "install_repoquery": true, "state": "installed", "disablerepo": null, "update_cache": false, "enablerepo": null, "exclude": null, "security": false, "validate_certs": true, "installroot": "/", "skip_broken": false}}, "msg": ""}
11
+ {"msg": "Nothing to do", "changed": false, "results": [], "rc": 0, "invocation": {"module_args": {"name": ["openssh"], "state": "present", "allow_downgrade": false, "autoremove": false, "bugfix": false, "disable_gpg_check": false, "disable_plugin": [], "disablerepo": [], "download_only": false, "enable_plugin": [], "enablerepo": [], "exclude": [], "installroot": "/", "install_repoquery": true, "install_weak_deps": true, "security": false, "skip_broken": false, "update_cache": false, "update_only": false, "validate_certs": true, "lock_timeout": 30, "conf_file": null, "disable_excludes": null, "download_dir": null, "list": null, "releasever": null}}, "_ansible_no_log": false, "failed": false, "module": "package"}
12
12
  ANSIBLELOG
13
13
  message = FactoryBot.build(:message)
14
14
  message.value = log_value
15
15
  log = FactoryBot.build(:log)
16
16
  log.message = message
17
17
  assert_match(
18
- /ntp-4.2.8p10-3.fc27.x86_64 providing ntp is already installed/,
19
- module_invocations(parsed_message_json(log)).to_s
20
- )
21
- end
22
-
23
- test 'pretty print is able to print a hash' do
24
- hash = {
25
- 'allow_downgrade' => false,
26
- 'name' => ['ntp'],
27
- 'list' => nil,
28
- 'disable_gpg_check' => false,
29
- 'conf_file' => nil,
30
- 'install_repoquery' => true,
31
- 'state' => 'installed',
32
- 'disablerepo' => nil,
33
- 'update_cache' => false,
34
- 'enablerepo' => nil,
35
- 'exclude' => nil,
36
- 'security' => false,
37
- 'validate_certs' => true,
38
- 'installroot' => '/',
39
- 'skip_broken' => false
40
- }
41
- assert_equal(
42
- hash,
43
- remove_keys(
44
- hash
45
- )
18
+ /Nothing to do/,
19
+ ansible_module_message(log).to_s
46
20
  )
47
21
  end
48
22
  end
@@ -19,17 +19,4 @@ class HostgroupAnsibleRoleTest < ActiveSupport::TestCase
19
19
  end
20
20
  should validate_uniqueness_of(:ansible_role_id).scoped_to(:hostgroup_id)
21
21
  end
22
-
23
- describe 'ordering' do
24
- test 'should list roles in correct order' do
25
- hg = FactoryBot.create(:hostgroup)
26
- 5.times do |idx|
27
- HostgroupAnsibleRole.create(:hostgroup => hg, :ansible_role => FactoryBot.create(:ansible_role), :position => idx)
28
- end
29
-
30
- hg.hostgroup_ansible_roles.each_with_index do |item, idx|
31
- assert_equal(item.position, idx + 1)
32
- end
33
- end
34
- end
35
22
  end
@@ -0,0 +1,35 @@
1
+ import React, { useState } from 'react';
2
+ import { Tabs, Tab, TabTitleText, Label } from '@patternfly/react-core';
3
+ import { InfoCircleIcon } from '@patternfly/react-icons';
4
+
5
+ import { translate as __ } from 'foremanReact/common/I18n';
6
+
7
+ import './AnsibleHostDetail.scss';
8
+
9
+ const AnsibleHostDetail = props => {
10
+ // https://projects.theforeman.org/issues/32398
11
+ const [activeTab] = useState('variables');
12
+
13
+ return (
14
+ <Tabs activeKey={activeTab} isSecondary>
15
+ <Tab
16
+ eventKey="variables"
17
+ title={<TabTitleText>{__('Variables')}</TabTitleText>}
18
+ >
19
+ <div className="host-details-tab-item">
20
+ <div className="ansible-host-detail">
21
+ <Label
22
+ color="blue"
23
+ icon={<InfoCircleIcon />}
24
+ style={{ marginTop: '1.5rem' }}
25
+ >
26
+ Ansible Variables coming soon!
27
+ </Label>
28
+ </div>
29
+ </div>
30
+ </Tab>
31
+ </Tabs>
32
+ );
33
+ };
34
+
35
+ export default AnsibleHostDetail;
@@ -0,0 +1,6 @@
1
+ @import '~@patternfly/patternfly/base/patternfly-variables';
2
+
3
+ .ansible-host-detail {
4
+ background-color: $pf-color-white;
5
+ padding: 1.8rem;
6
+ }
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import '@testing-library/jest-dom';
4
+
5
+ import AnsibleHostDetail from './';
6
+
7
+ describe('AnsibleHostDetail', () => {
8
+ it('should show content', () => {
9
+ render(<AnsibleHostDetail />);
10
+ expect(
11
+ screen.getByText('Ansible Variables coming soon!')
12
+ ).toBeInTheDocument();
13
+ });
14
+ });
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import AnsibleHostDetail from './AnsibleHostDetail';
3
+
4
+ const WrappedAnsibleHostDetail = props => <AnsibleHostDetail {...props} />;
5
+
6
+ export default WrappedAnsibleHostDetail;
@@ -2,6 +2,7 @@
2
2
 
3
3
  exports[`AnsiblePermissionDenied should render 1`] = `
4
4
  <EmptyStatePattern
5
+ action={null}
5
6
  description={
6
7
  <span>
7
8
  You are not authorized to perform this action.
@@ -22,5 +23,6 @@ exports[`AnsiblePermissionDenied should render 1`] = `
22
23
  header="Permission Denied"
23
24
  icon="lock"
24
25
  iconType="fa"
26
+ secondaryActions={Array []}
25
27
  />
26
28
  `;
@@ -1,13 +1,13 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`AssignedRolesList should render 1`] = `
4
- <DndProvider
4
+ <Memo(DndProvider)
5
5
  backend={[Function]}
6
6
  >
7
7
  <ListView
8
8
  className=""
9
9
  >
10
- <Component
10
+ <DropTarget(DragSource(Orderable(AnsibleRole)))
11
11
  icon="fa fa-minus-circle"
12
12
  index={0}
13
13
  key="1"
@@ -21,7 +21,7 @@ exports[`AssignedRolesList should render 1`] = `
21
21
  }
22
22
  }
23
23
  />
24
- <Component
24
+ <DropTarget(DragSource(Orderable(AnsibleRole)))
25
25
  icon="fa fa-minus-circle"
26
26
  index={1}
27
27
  key="2"
@@ -60,5 +60,5 @@ exports[`AssignedRolesList should render 1`] = `
60
60
  }
61
61
  />
62
62
  </div>
63
- </DndProvider>
63
+ </Memo(DndProvider)>
64
64
  `;
@@ -8,9 +8,14 @@ exports[`AvailableRolesList should render 1`] = `
8
8
  className="sticky-pagination"
9
9
  >
10
10
  <PaginationWrapper
11
+ className=""
12
+ disableNext={false}
13
+ disablePrev={false}
11
14
  dropdownButtonId="available-ansible-roles-pagination-row-dropdown"
12
15
  itemCount={2}
13
16
  onChange={[Function]}
17
+ onPageSet={[Function]}
18
+ onPerPageSelect={[Function]}
14
19
  pagination={
15
20
  Object {
16
21
  "page": 1,
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+
3
+ import { addGlobalFill } from 'foremanReact/components/common/Fill/GlobalFill';
4
+
5
+ import AnsibleHostDetail from './components/AnsibleHostDetail';
6
+
7
+ addGlobalFill(
8
+ 'host-details-page-tabs',
9
+ 'Ansible',
10
+ <AnsibleHostDetail key="ansible-host-detail" />,
11
+ 500
12
+ );
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_ansible
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.3.4
4
+ version: 6.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Lobato Garcia
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-24 00:00:00.000000000 Z
11
+ date: 2021-06-23 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: foreman_ansible_core
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '3.0'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '3.0'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: acts_as_list
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -302,9 +288,6 @@ files:
302
288
  - test/unit/hostgroup_ansible_role_test.rb
303
289
  - test/unit/ignore_roles_test.rb
304
290
  - test/unit/import_roles_and_variables.rb
305
- - test/unit/lib/foreman_ansible_core/ansible_runner_test.rb
306
- - test/unit/lib/foreman_ansible_core/command_creator_test.rb
307
- - test/unit/lib/foreman_ansible_core/playbook_runner_test.rb
308
291
  - test/unit/lib/proxy_api/ansible_test.rb
309
292
  - test/unit/services/ansible_report_importer_test.rb
310
293
  - test/unit/services/ansible_variables_importer_test.rb
@@ -317,12 +300,10 @@ files:
317
300
  - test/unit/services/roles_importer_test.rb
318
301
  - test/unit/services/structured_fact_importer_test.rb
319
302
  - test/unit/services/ui_roles_importer_test.rb
320
- - webpack/__mocks__/foremanReact/common/I18n.js
321
- - webpack/__mocks__/foremanReact/common/helpers.js
322
- - webpack/__mocks__/foremanReact/components/Pagination/PaginationWrapper.js
323
- - webpack/__mocks__/foremanReact/components/common/EmptyState.js
324
- - webpack/__mocks__/foremanReact/components/common/forms/OrderableSelect/helpers.js
325
- - webpack/__mocks__/foremanReact/redux/API.js
303
+ - webpack/components/AnsibleHostDetail/AnsibleHostDetail.js
304
+ - webpack/components/AnsibleHostDetail/AnsibleHostDetail.scss
305
+ - webpack/components/AnsibleHostDetail/AnsibleHostDetail.test.js
306
+ - webpack/components/AnsibleHostDetail/index.js
326
307
  - webpack/components/AnsibleRolesAndVariables/AnsibleRolesAndVariables.js
327
308
  - webpack/components/AnsibleRolesAndVariables/AnsibleRolesAndVariables.scss
328
309
  - webpack/components/AnsibleRolesAndVariables/AnsibleRolesAndVariablesActions.js
@@ -368,13 +349,14 @@ files:
368
349
  - webpack/components/AnsibleRolesSwitcher/components/withProtectedView.js
369
350
  - webpack/components/AnsibleRolesSwitcher/index.js
370
351
  - webpack/components/ReportJsonViewer.js
352
+ - webpack/global_index.js
371
353
  - webpack/index.js
372
354
  - webpack/reducer.js
373
355
  homepage: https://github.com/theforeman/foreman_ansible
374
356
  licenses:
375
357
  - GPL-3.0
376
358
  metadata: {}
377
- post_install_message:
359
+ post_install_message:
378
360
  rdoc_options: []
379
361
  require_paths:
380
362
  - lib
@@ -390,7 +372,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
390
372
  version: '0'
391
373
  requirements: []
392
374
  rubygems_version: 3.1.2
393
- signing_key:
375
+ signing_key:
394
376
  specification_version: 4
395
377
  summary: Ansible integration with Foreman (theforeman.org)
396
378
  test_files:
@@ -399,8 +381,8 @@ test_files:
399
381
  - test/factories/ansible_roles.rb
400
382
  - test/factories/host_ansible_enhancements.rb
401
383
  - test/fixtures/insights_playbook.yaml
402
- - test/fixtures/report.json
403
384
  - test/fixtures/sample_facts.json
385
+ - test/fixtures/report.json
404
386
  - test/functional/ansible_roles_controller_test.rb
405
387
  - test/functional/api/v2/ansible_inventories_controller_test.rb
406
388
  - test/functional/api/v2/ansible_variables_controller_test.rb
@@ -419,24 +401,21 @@ test_files:
419
401
  - test/unit/concerns/host_managed_extensions_test.rb
420
402
  - test/unit/concerns/hostgroup_extensions_test.rb
421
403
  - test/unit/helpers/ansible_reports_helper_test.rb
422
- - test/unit/lib/foreman_ansible_core/command_creator_test.rb
423
- - test/unit/lib/foreman_ansible_core/ansible_runner_test.rb
424
- - test/unit/lib/foreman_ansible_core/playbook_runner_test.rb
425
404
  - test/unit/lib/proxy_api/ansible_test.rb
426
405
  - test/unit/services/ansible_report_importer_test.rb
427
- - test/unit/services/fact_importer_test.rb
428
406
  - test/unit/services/fact_sparser_test.rb
429
407
  - test/unit/services/insights_plan_runner_test.rb
430
408
  - test/unit/services/roles_importer_test.rb
431
409
  - test/unit/services/structured_fact_importer_test.rb
410
+ - test/unit/services/fact_importer_test.rb
432
411
  - test/unit/services/ansible_variables_importer_test.rb
433
412
  - test/unit/services/ui_roles_importer_test.rb
434
413
  - test/unit/services/api_roles_importer_test.rb
435
414
  - test/unit/services/fact_parser_test.rb
436
415
  - test/unit/services/inventory_creator_test.rb
416
+ - test/unit/ansible_provider_test.rb
437
417
  - test/unit/host_ansible_role_test.rb
418
+ - test/unit/hostgroup_ansible_role_test.rb
438
419
  - test/unit/import_roles_and_variables.rb
439
420
  - test/unit/ignore_roles_test.rb
440
- - test/unit/hostgroup_ansible_role_test.rb
441
- - test/unit/ansible_provider_test.rb
442
421
  - test/foreman_ansible/helpers/ansible_roles_helper_test.rb
@@ -1,51 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'test_helper'
4
-
5
- module ForemanAnsibleCore
6
- module Runner
7
- class AnsibleRunnerTest < ActiveSupport::TestCase
8
- describe AnsibleRunner do
9
- it 'parses files without event data' do
10
- content = <<~JSON
11
- {"uuid": "a29d8592-f805-4d0e-b73d-7a53cc35a92e", "stdout": " [WARNING]: Consider using the yum module rather than running 'yum'. If you", "counter": 8, "end_line": 8, "runner_ident": "e2d9ae11-026a-4f9f-9679-401e4b852ab0", "start_line": 7, "event": "verbose"}
12
- JSON
13
-
14
- File.expects(:read).with('fake.json').returns(content)
15
- runner = AnsibleRunner.allocate
16
- runner.expects(:handle_broadcast_data)
17
- assert runner.send(:handle_event_file, 'fake.json')
18
- end
19
- end
20
-
21
- describe '#rebuild_secrets' do
22
- let(:inventory) do
23
- { 'all' => { 'hosts' => ['foreman.example.com'] },
24
- '_meta' => { 'hostvars' => { 'foreman.example.com' => {} } } }
25
- end
26
- let(:input) do
27
- host_secrets = { 'ansible_password' => 'letmein', 'ansible_become_password' => 'iamroot' }
28
- secrets = { 'per-host' => { 'foreman.example.com' => host_secrets } }
29
- host_input = { 'input' => { 'action_input' => { 'secrets' => secrets } } }
30
- { 'foreman.example.com' => host_input }
31
- end
32
- let(:runner) { ForemanAnsibleCore::Runner::AnsibleRunner.allocate }
33
-
34
- test 'uses secrets from inventory' do
35
- test_inventory = inventory.merge('ssh_password' => 'sshpass', 'effective_user_password' => 'mypass')
36
- rebuilt = runner.send(:rebuild_secrets, test_inventory, input)
37
- host_vars = rebuilt.dig('_meta', 'hostvars', 'foreman.example.com')
38
- assert_equal 'sshpass', host_vars['ansible_password']
39
- assert_equal 'mypass', host_vars['ansible_become_password']
40
- end
41
-
42
- test 'host secrets are used when not overriden by inventory secrest' do
43
- rebuilt = runner.send(:rebuild_secrets, inventory, input)
44
- host_vars = rebuilt.dig('_meta', 'hostvars', 'foreman.example.com')
45
- assert_equal 'letmein', host_vars['ansible_password']
46
- assert_equal 'iamroot', host_vars['ansible_become_password']
47
- end
48
- end
49
- end
50
- end
51
- end
@@ -1,64 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'test_helper'
4
-
5
- class CommandCreatorTest < ActiveSupport::TestCase
6
- let(:inventory_file) { 'test_inventory' }
7
- let(:playbook_file) { 'test_palybook.yml' }
8
- subject do
9
- ForemanAnsibleCore::CommandCreator.new(inventory_file, playbook_file, {})
10
- end
11
-
12
- test 'returns a command array including the ansible-playbook command' do
13
- assert command_parts.include?('ansible-playbook')
14
- end
15
-
16
- test 'the last argument is the playbook_file' do
17
- assert command_parts.last == playbook_file
18
- end
19
-
20
- describe 'environment variables' do
21
- let(:environment_variables) { subject.command.first }
22
-
23
- test 'has a JSON_INVENTORY_FILE set' do
24
- assert environment_variables['JSON_INVENTORY_FILE']
25
- end
26
-
27
- test 'has no ANSIBLE_CALLBACK_WHITELIST set by default' do
28
- assert_not environment_variables['ANSIBLE_CALLBACK_WHITELIST']
29
- end
30
-
31
- test 'with a REX command it sets ANSIBLE_CALLBACK_WHITELIST to empty' do
32
- set_command_options(:remote_execution_command, true)
33
- assert environment_variables['ANSIBLE_CALLBACK_WHITELIST']
34
- end
35
- end
36
-
37
- describe 'command options' do
38
- it 'can have verbosity set' do
39
- level = '3'
40
- level_string = Array.new(level.to_i).map { 'v' }.join
41
- set_command_options(:verbosity_level, level)
42
- assert command_parts.any? do |part|
43
- part == "-#{level_string}"
44
- end
45
- end
46
-
47
- it 'can have a timeout set' do
48
- timeout = '5555'
49
- set_command_options(:timeout, timeout)
50
- assert command_parts.include?(timeout)
51
- end
52
- end
53
-
54
- private
55
-
56
- def command_parts
57
- subject.command.flatten.map(&:to_s)
58
- end
59
-
60
- def set_command_options(option, value)
61
- subject.instance_eval("@options[:#{option}] = \"#{value}\"",
62
- __FILE__, __LINE__ - 1)
63
- end
64
- end
@@ -1,110 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'test_helper'
4
-
5
- # Playbook Runner - this class uses foreman_tasks_core
6
- # to run playbooks
7
- class PlaybookRunnerTest < ActiveSupport::TestCase
8
- context 'roles dir' do
9
- test 'reads default when none provided' do
10
- ForemanAnsibleCore::Runner::Playbook.any_instance.stubs(:unknown_hosts).
11
- returns([])
12
- File.expects(:exist?).with(Dir.home).returns(true)
13
- ForemanAnsibleCore::Runner::Playbook.any_instance.expects(:rebuild_secrets).returns(nil)
14
- runner = ForemanAnsibleCore::Runner::Playbook.new(nil, nil, :suspended_action => nil)
15
- assert '/etc/ansible', runner.instance_variable_get('@ansible_dir')
16
- end
17
- end
18
-
19
- context 'working_dir' do
20
- setup do
21
- ForemanAnsibleCore::Runner::Playbook.any_instance.stubs(:unknown_hosts).
22
- returns([])
23
- end
24
-
25
- test 'creates temp one if not provided' do
26
- Dir.expects(:mktmpdir)
27
- File.expects(:exist?).with(Dir.home).returns(true)
28
- ForemanAnsibleCore::Runner::Playbook.any_instance.expects(:rebuild_secrets).returns(nil)
29
- ForemanAnsibleCore::Runner::Playbook.new(nil, nil, :suspended_action => nil)
30
- end
31
-
32
- test 'reads it when provided' do
33
- settings = { :working_dir => '/foo', :ansible_dir => '/etc/foo' }
34
- ForemanAnsibleCore.expects(:settings).returns(settings)
35
- File.expects(:exist?).with(settings[:ansible_dir]).returns(true)
36
- Dir.expects(:mktmpdir).never
37
- ForemanAnsibleCore::Runner::Playbook.any_instance.expects(:rebuild_secrets).returns(nil)
38
- runner = ForemanAnsibleCore::Runner::Playbook.new(nil, nil, :suspended_action => nil)
39
- assert '/foo', runner.instance_variable_get('@working_dir')
40
- end
41
- end
42
-
43
- context 'TOFU policy' do # Trust On First Use
44
- setup do
45
- @inventory = { 'all' => { 'hosts' => ['foreman.example.com'] } }
46
- @output = StringIO.new
47
- logger = Logger.new(@output)
48
- ForemanAnsibleCore::Runner::Playbook.any_instance.stubs(:logger).
49
- returns(logger)
50
- end
51
-
52
- test 'ignores known hosts' do
53
- Net::SSH::KnownHosts.expects(:search_for).
54
- with('foreman.example.com').returns(['somekey'])
55
- ForemanAnsibleCore::Runner::Playbook.any_instance.
56
- expects(:add_to_known_hosts).never
57
- ForemanAnsibleCore::Runner::Playbook.any_instance.expects(:rebuild_secrets).returns(@inventory)
58
- ForemanAnsibleCore::Runner::Playbook.new(@inventory, nil, :suspended_action => nil)
59
- end
60
-
61
- test 'adds unknown hosts to known_hosts' do
62
- Net::SSH::KnownHosts.expects(:search_for).
63
- with('foreman.example.com').returns([])
64
- ForemanAnsibleCore::Runner::Playbook.any_instance.
65
- expects(:add_to_known_hosts).with('foreman.example.com')
66
- ForemanAnsibleCore::Runner::Playbook.any_instance.expects(:rebuild_secrets).returns(@inventory)
67
- ForemanAnsibleCore::Runner::Playbook.new(@inventory, nil, :suspended_action => nil)
68
- end
69
-
70
- test 'logs error when it cannot add to known_hosts' do
71
- Net::SSH::KnownHosts.expects(:search_for).
72
- with('foreman.example.com').returns([])
73
- Net::SSH::Transport::Session.expects(:new).with('foreman.example.com').
74
- raises(Net::Error)
75
- ForemanAnsibleCore::Runner::Playbook.any_instance.expects(:rebuild_secrets).returns(@inventory)
76
- ForemanAnsibleCore::Runner::Playbook.new(@inventory, nil, :suspended_action => nil)
77
- assert_match(
78
- /ERROR.*Failed to save host key for foreman.example.com: Net::Error/,
79
- @output.string
80
- )
81
- end
82
- end
83
-
84
- context 'rebuild secrets' do
85
- let(:inventory) do
86
- { 'all' => { 'hosts' => ['foreman.example.com'] },
87
- '_meta' => { 'hostvars' => { 'foreman.example.com' => {} } } }
88
- end
89
- let(:secrets) do
90
- host_secrets = { 'ansible_password' => 'letmein', 'ansible_become_password' => 'iamroot' }
91
- { 'per-host' => { 'foreman.example.com' => host_secrets } }
92
- end
93
- let(:runner) { ForemanAnsibleCore::Runner::Playbook.allocate }
94
-
95
- test 'uses secrets from inventory' do
96
- test_inventory = inventory.merge('ssh_password' => 'sshpass', 'effective_user_password' => 'mypass')
97
- rebuilt = runner.send(:rebuild_secrets, test_inventory, secrets)
98
- host_vars = rebuilt.dig('_meta', 'hostvars', 'foreman.example.com')
99
- assert_equal 'sshpass', host_vars['ansible_password']
100
- assert_equal 'mypass', host_vars['ansible_become_password']
101
- end
102
-
103
- test 'host secrets are used when not overriden by inventory secrest' do
104
- rebuilt = runner.send(:rebuild_secrets, inventory, secrets)
105
- host_vars = rebuilt.dig('_meta', 'hostvars', 'foreman.example.com')
106
- assert_equal 'letmein', host_vars['ansible_password']
107
- assert_equal 'iamroot', host_vars['ansible_become_password']
108
- end
109
- end
110
- end
@@ -1 +0,0 @@
1
- export const translate = s => s;
@@ -1,13 +0,0 @@
1
- import { camelCase } from 'lodash';
2
-
3
- export const propsToCamelCase = ob =>
4
- propsToCase(camelCase, 'propsToCamelCase only takes objects', ob);
5
-
6
- const propsToCase = (casingFn, errorMsg, ob) => {
7
- if (typeof ob !== 'object') throw Error(errorMsg);
8
-
9
- return Object.keys(ob).reduce((memo, key) => {
10
- memo[casingFn(key)] = ob[key];
11
- return memo;
12
- }, {});
13
- };
@@ -1,2 +0,0 @@
1
- const PaginationWrapper = () => jest.fn();
2
- export default PaginationWrapper;
@@ -1,5 +0,0 @@
1
- const EmptyState = () => jest.fn();
2
-
3
- export const EmptyStatePattern = () => jest.fn();
4
-
5
- export default EmptyState;
@@ -1,5 +0,0 @@
1
- import React from 'react';
2
-
3
- export const orderable = (Component, orderableProps) => props => (
4
- <Component {...orderableProps} {...props} />
5
- );
@@ -1,7 +0,0 @@
1
- export const API = {
2
- get: jest.fn(),
3
- put: jest.fn(),
4
- post: jest.fn(),
5
- delete: jest.fn(),
6
- patch: jest.fn(),
7
- };