foreman_ansible 6.3.4 → 6.4.0

Sign up to get free protection for your applications and to get access to all the features.
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
- };