foreman_ansible 1.2.1 → 1.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2399ebe8fda7c442e3d7237e348679a9f7d5e09b
4
- data.tar.gz: 10e83333e39d2dce97bb61682d3e4febedeccee6
3
+ metadata.gz: de6e79123f688c3553272ed001f1083956294a83
4
+ data.tar.gz: 943ccf987f9f2069fa51065eb3f44ded9cbefcf2
5
5
  SHA512:
6
- metadata.gz: 1b0898d563f521e97dbb742c86e85c51a83662fd0309b7be06a635980c01c734292c2c50ae1bb891394452a9a34c3cd7ae535c92c1a4774ecbe0777b97a8a388
7
- data.tar.gz: 3043d427ef9a4388c8eda9e07005e644ef03dfd1f3b84f15778f7df7a6748aef1491c522e2fd379b3505ae0a9b287095230f753d9e209d3a66dab865e3331492
6
+ metadata.gz: 60c9771a89b91400ec87794ac3b907cf67417d86aee5b32d80f697544aa3537cc09c65e6c290c34eca2862642c72947bcf4dae0a0ff842fafafe52381b329b93
7
+ data.tar.gz: 9100e43f728698c4c60a657d6cf252ae045505d82d9d8bebe1dccd7430f405e262ce186ef843f8fdb4d8b0932c84bb39a2d77ad0420c5bd01092fc8b5008d318
@@ -0,0 +1,18 @@
1
+ class Setting::Ansible < ::Setting
2
+ def self.load_defaults
3
+ return unless super
4
+ self.transaction do
5
+ [
6
+ self.set('ansible_port', N_('Foreman will use this port to ssh into hosts for running playbooks'), 22, N_('Default port')),
7
+ self.set('ansible_user', N_('Foreman will try to connect as this user to hosts when running Ansible playbooks.'), 'root', N_('Default user')),
8
+ self.set('ansible_ssh_pass', N_('Foreman will use this password when running Ansible playbooks.'), 'ansible', N_('Default password'))
9
+ ].compact.each { |s| self.create s.update(:category => 'Setting::Ansible') }
10
+ end
11
+
12
+ true
13
+ end
14
+
15
+ def self.humanized_category
16
+ N_('Ansible')
17
+ end
18
+ end
@@ -2,13 +2,19 @@ module ForemanAnsible
2
2
  # Override methods from Foreman app/services/fact_importer so that Ansible
3
3
  # facts are recognized in Foreman as ForemanAnsible facts. It supports
4
4
  # nested facts.
5
+ #
6
+ # Only relevant for 1.12 and lower versions
5
7
  class FactImporter < ::FactImporter
6
8
  def fact_name_class
7
9
  ForemanAnsible::FactName
8
10
  end
9
11
 
10
12
  def initialize(host, facts = {})
11
- @host = host
13
+ # Try to assign these facts to the correct host as per the facts say
14
+ # If that host isn't created yet, the host parameter will contain it
15
+ @host = Host.find_by(:name => facts[:ansible_facts][:ansible_fqdn] ||
16
+ facts[:ansible_facts][:fqdn]) ||
17
+ host
12
18
  @facts = normalize(facts[:ansible_facts])
13
19
  @original_facts = FactSparser.unsparse(facts[:ansible_facts])
14
20
  @counters = {}
@@ -23,12 +23,13 @@ module ForemanAnsible
23
23
 
24
24
  def model
25
25
  name = detect_fact([:ansible_product_name, :facter_virtual,
26
- :facter_productname, :facter_model])
26
+ :facter_productname, :facter_model, :model])
27
27
  Model.where(:name => name.strip).first_or_create unless name.blank?
28
28
  end
29
29
 
30
30
  def domain
31
- name = detect_fact([:ansible_domain, :facter_domain, :ohai_domain])
31
+ name = detect_fact([:ansible_domain, :facter_domain,
32
+ :ohai_domain, :domain])
32
33
  Domain.where(:name => name).first_or_create unless name.blank?
33
34
  end
34
35
 
@@ -48,7 +49,7 @@ module ForemanAnsible
48
49
  if pref.present?
49
50
  (facts[:ansible_interfaces] - [pref]).unshift(pref)
50
51
  else
51
- facts[:ansible_interfaces].sort
52
+ (facts[:ansible_interfaces].sort unless facts[:ansible_interfaces].nil?) || []
52
53
  end
53
54
  end
54
55
 
@@ -75,7 +76,8 @@ module ForemanAnsible
75
76
 
76
77
  def os_major
77
78
  facts[:ansible_distribution_major_version] ||
78
- facts[:ansible_lsb] && facts[:ansible_lsb]['major_release']
79
+ facts[:ansible_lsb] && facts[:ansible_lsb]['major_release'] ||
80
+ (facts[:version].split('R')[0] if os_name == 'junos')
79
81
  end
80
82
 
81
83
  def os_release
@@ -84,7 +86,8 @@ module ForemanAnsible
84
86
  end
85
87
 
86
88
  def os_minor
87
- _, minor = os_release.split('.')
89
+ _, minor = (os_release.split('.') unless os_release.nil?) ||
90
+ (facts[:version].split('R') if os_name == 'junos')
88
91
  minor || ''
89
92
  end
90
93
 
@@ -17,18 +17,36 @@ module ForemanAnsible
17
17
  # with all hosts.
18
18
  def to_hash
19
19
  { 'all' => { 'hosts' => hosts.map(&:fqdn) },
20
- '_meta' => { 'hostvars' => host_vars } }
20
+ '_meta' => { 'hostvars' => hosts_vars } }
21
21
  end
22
22
 
23
- def host_vars
23
+ def hosts_vars
24
24
  hosts.reduce({}) do |hash, host|
25
- hash.update(host.fqdn =>
26
- { 'foreman' => host_attributes(host),
27
- 'foreman_params' => host_params(host),
28
- 'foreman_ansible_roles' => host_roles(host) })
25
+ hash.update(host.fqdn => host_vars(host))
29
26
  end
30
27
  end
31
28
 
29
+ def host_vars(host)
30
+ {
31
+ 'foreman' => host_attributes(host),
32
+ 'foreman_params' => host_params(host),
33
+ 'foreman_ansible_roles' => host_roles(host)
34
+ }.merge(connection_params(host))
35
+ end
36
+
37
+ def connection_params(host)
38
+ params = {
39
+ 'ansible_port' => host_port(host),
40
+ 'ansible_user' => host_user(host),
41
+ 'ansible_ssh_pass' => host_ssh_pass(host)
42
+ }
43
+
44
+ #Backward compatibility for Ansible 1.x
45
+ params['ansible_ssh_port'] = params['ansible_port']
46
+ params['ansible_ssh_user'] = params['ansible_user']
47
+ params
48
+ end
49
+
32
50
  def host_roles(host)
33
51
  host.all_ansible_roles.map(&:name)
34
52
  end
@@ -41,6 +59,18 @@ module ForemanAnsible
41
59
  host.host_params
42
60
  end
43
61
 
62
+ def host_port(host)
63
+ host.host_params['ansible_port'] || Setting[:ansible_port]
64
+ end
65
+
66
+ def host_user(host)
67
+ host.host_params['ansible_user'] || Setting[:ansible_user]
68
+ end
69
+
70
+ def host_ssh_pass(host)
71
+ host.host_params['ansible_ssh_port'] || Setting[:ansible_ssh_pass]
72
+ end
73
+
44
74
  private
45
75
 
46
76
  def render_rabl(host, template)
@@ -0,0 +1,19 @@
1
+ module ForemanAnsible
2
+ # On 1.13+ , use the parser for structured facts (like Facter 2) that comes
3
+ # from core
4
+ class StructuredFactImporter < ::StructuredFactImporter
5
+ def fact_name_class
6
+ ForemanAnsible::FactName
7
+ end
8
+
9
+ def initialize(host, facts = {})
10
+ # Try to assign these facts to the correct host as per the facts say
11
+ # If that host isn't created yet, the host parameter will contain it
12
+ @host = Host.find_by(:name => facts[:ansible_facts][:ansible_fqdn] ||
13
+ facts[:ansible_facts][:fqdn]) ||
14
+ host
15
+ @facts = normalize(facts[:ansible_facts])
16
+ @counters = {}
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ class AutomaticallySetRoleTimestamps < ActiveRecord::Migration
2
+ def up
3
+ change_column :ansible_roles, :created_at, :datetime, :null => true, :default => nil
4
+ change_column :ansible_roles, :updated_at, :datetime, :null => true, :default => nil
5
+ end
6
+
7
+ def down
8
+ change_column :ansible_roles, :created_at, :datetime, :null => false, :default => Time.now.utc
9
+ change_column :ansible_roles, :updated_at, :datetime, :null => false, :default => Time.now.utc
10
+ end
11
+ end
@@ -9,12 +9,19 @@ module ForemanAnsible
9
9
  engine_name 'foreman_ansible'
10
10
 
11
11
  config.autoload_paths += Dir["#{config.root}/app/controllers/concerns"]
12
+ config.autoload_paths += Dir["#{config.root}/app/models"]
12
13
  config.autoload_paths += Dir["#{config.root}/app/helpers"]
13
14
  config.autoload_paths += Dir["#{config.root}/app/overrides"]
14
15
  config.autoload_paths += Dir["#{config.root}/app/services"]
15
16
  config.autoload_paths += Dir["#{config.root}/app/views"]
16
17
  config.autoload_paths += Dir["#{config.root}/app/lib"]
17
18
 
19
+ initializer 'foreman_ansible.load_default_settings',
20
+ :before => :load_config_initializers do
21
+ require_dependency(File.join(ForemanAnsible::Engine.root,
22
+ 'app/models/setting/ansible.rb'))
23
+ end
24
+
18
25
  initializer 'foreman_ansible.register_gettext',
19
26
  :after => :load_config_initializers do
20
27
  locale_dir = File.join(File.expand_path('../../..', __FILE__), 'locale')
@@ -30,7 +37,7 @@ module ForemanAnsible
30
37
  security_block :foreman_ansible do
31
38
  permission :play_roles,
32
39
  { :hosts => [:play_roles, :multiple_play_roles] },
33
- :resource_type => 'Host::Managed'
40
+ :resource_type => 'Host'
34
41
  permission :view_ansible_roles,
35
42
  { :ansible_roles => [:index],
36
43
  :'api/v2/ansible_roles' => [:index, :show] },
@@ -45,6 +52,10 @@ module ForemanAnsible
45
52
  :resource_type => 'AnsibleRole'
46
53
  end
47
54
 
55
+ role 'Ansible Roles Manager',
56
+ [:play_roles, :view_ansible_roles, :destroy_ansible_roles,
57
+ :import_ansible_roles]
58
+
48
59
  role_assignment_params = { :ansible_role_ids => [],
49
60
  :ansible_roles => [] }
50
61
  parameter_filter Host::Managed, role_assignment_params
@@ -57,7 +68,8 @@ module ForemanAnsible
57
68
  :parent => :configure_menu
58
69
 
59
70
  apipie_documented_controllers [
60
- "#{ForemanAnsible::Engine.root}/app/controllers/api/v2/*.rb"]
71
+ "#{ForemanAnsible::Engine.root}/app/controllers/api/v2/*.rb"
72
+ ]
61
73
  end
62
74
  end
63
75
 
@@ -83,8 +95,17 @@ module ForemanAnsible
83
95
 
84
96
  config.to_prepare do
85
97
  begin
86
- ::FactImporter.register_fact_importer(:ansible,
87
- ForemanAnsible::FactImporter)
98
+ foreman_version = ::Foreman::Version.new
99
+ if Rails.env.test? ||
100
+ foreman_version.major.to_i == 1 && foreman_version.minor.to_i < 13
101
+ ::FactImporter.register_fact_importer(:ansible,
102
+ ForemanAnsible::FactImporter)
103
+ else
104
+ ::FactImporter.register_fact_importer(
105
+ :ansible,
106
+ ForemanAnsible::StructuredFactImporter
107
+ )
108
+ end
88
109
  ::FactParser.register_fact_parser(:ansible, ForemanAnsible::FactParser)
89
110
  ::Host::Managed.send(:include, ForemanAnsible::HostManagedExtensions)
90
111
  ::Hostgroup.send(:include, ForemanAnsible::HostgroupExtensions)
@@ -2,5 +2,5 @@
2
2
  # This way other parts of Foreman can just call ForemanAnsible::VERSION
3
3
  # and detect what version the plugin is running.
4
4
  module ForemanAnsible
5
- VERSION = '1.2.1'.freeze
5
+ VERSION = '1.3.0'.freeze
6
6
  end
@@ -0,0 +1,28 @@
1
+ require 'test_plugin_helper'
2
+
3
+ module ForemanAnsible
4
+ # Test for the structured facts importer - its code mostly lives in Foreman
5
+ # core, so only details have to be tested here.
6
+ class StructuredFactImporterTest < ActiveSupport::TestCase
7
+ test 'if host is not in Foreman, use hostname provided by call' do
8
+ fake_host = Host.new(:name => 'fake')
9
+ importer = ForemanAnsible::StructuredFactImporter.new(
10
+ fake_host,
11
+ facts_json
12
+ )
13
+ assert_equal fake_host, importer.send(:host)
14
+ end
15
+
16
+ test 'if host is in Foreman, use hostname provided by Ansible' do
17
+ ansible_fqdn_host = FactoryGirl.build(:host)
18
+ ansible_fqdn_host.name = facts_json[:ansible_facts][:ansible_fqdn]
19
+ ansible_fqdn_host.save
20
+ importer = ForemanAnsible::StructuredFactImporter.new(
21
+ Host.new(:name => 'fake'),
22
+ facts_json
23
+ )
24
+
25
+ assert_equal ansible_fqdn_host, importer.send(:host)
26
+ end
27
+ end
28
+ end
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: 1.2.1
4
+ version: 1.3.0
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: 2016-10-03 00:00:00.000000000 Z
11
+ date: 2016-12-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubocop
@@ -108,6 +108,7 @@ files:
108
108
  - app/models/foreman_ansible/fact_name.rb
109
109
  - app/models/host_ansible_role.rb
110
110
  - app/models/hostgroup_ansible_role.rb
111
+ - app/models/setting/ansible.rb
111
112
  - app/overrides/ansible_roles_tab.rb
112
113
  - app/overrides/hostgroup_ansible_roles_tab.rb
113
114
  - app/overrides/report_output.rb
@@ -119,6 +120,7 @@ files:
119
120
  - app/services/foreman_ansible/playbook_creator.rb
120
121
  - app/services/foreman_ansible/proxy_selector.rb
121
122
  - app/services/foreman_ansible/roles_importer.rb
123
+ - app/services/foreman_ansible/structured_fact_importer.rb
122
124
  - app/services/foreman_ansible/ui_roles_importer.rb
123
125
  - app/views/ansible_roles/import.html.erb
124
126
  - app/views/ansible_roles/index.html.erb
@@ -142,6 +144,7 @@ files:
142
144
  - db/migrate/20160729094457_add_columns_to_ansible_role.rb
143
145
  - db/migrate/20160802153302_create_join_table_hostgroup_ansible_roles.rb
144
146
  - db/migrate/20160805094233_add_primary_key_hostgroup_ansible_roles.rb
147
+ - db/migrate/20161122154057_automatically_set_role_timestamps.rb
145
148
  - db/seeds.d/62_ansible_proxy_feature.rb
146
149
  - lib/foreman_ansible.rb
147
150
  - lib/foreman_ansible/engine.rb
@@ -175,6 +178,7 @@ files:
175
178
  - test/unit/services/fact_sparser_test.rb
176
179
  - test/unit/services/proxy_selector_test.rb
177
180
  - test/unit/services/roles_importer_test.rb
181
+ - test/unit/services/structured_fact_importer_test.rb
178
182
  - test/unit/services/ui_roles_importer_test.rb
179
183
  homepage: https://github.com/theforeman/foreman_ansible
180
184
  licenses:
@@ -215,6 +219,7 @@ test_files:
215
219
  - test/unit/concerns/hostgroup_extensions_test.rb
216
220
  - test/unit/concerns/host_managed_extensions_test.rb
217
221
  - test/unit/services/fact_parser_test.rb
222
+ - test/unit/services/structured_fact_importer_test.rb
218
223
  - test/unit/services/proxy_selector_test.rb
219
224
  - test/unit/services/fact_importer_test.rb
220
225
  - test/unit/services/ui_roles_importer_test.rb