foreman_ansible 0.2.2 → 0.3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of foreman_ansible might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 651683d29fb40dbd94af8c41c17aac05d338da63
4
- data.tar.gz: 08b2873008325af3d6108f2cebe5cfef7e3a3198
3
+ metadata.gz: f98cfedfee37e7a9829abe818b80cfc7d553b001
4
+ data.tar.gz: 008f22e68ec44bf9aa46e75d9006608df8c2821a
5
5
  SHA512:
6
- metadata.gz: 1e2d6381c31429e26137a351e8125f7475a9328f3fa58f46b5b59d60f0590f7ff4f85be8d72b11bc822c4db3711e77497c49b30c1395745374787a73a0808a78
7
- data.tar.gz: 8e6cdf7a6c43694f79a1587fd10cc30b4d74543ea329dff02628d2c03e0aa7a9b9272abf1c353e1c52b4a7eef1a5c769d6509d5f7eb0ed379677d487dd6d8f93
6
+ metadata.gz: 1b1a8c519e2f29aaf1cfdb5b8c604e06db5d8dcbf3a7646a25b1e9a2a935e9dab4b0977ae21d56e4623fd022fd6b68db4358efddcb9f1a32ab83755f4b2921cf
7
+ data.tar.gz: 54eace7707e28bcb0870cb8e24a270fb473c208c4845bb85c3fbdcf925a1690f0c31577072a5a076502564dde7a1b4ec9c2202336c21bf4b4bc4ea828ffbd2fb
data/README.md CHANGED
@@ -15,8 +15,19 @@ Deploy `extras/foreman_callback.py` as a callback on your Ansible installation.
15
15
  callback_plugins = ~/.ansible/plugins/callback_plugins/
16
16
  bin_ansible_callbacks = True
17
17
  ```
18
+ And copy `extras/foreman_callback.py` from this repo to `~/.ansible/plugins/callback_plugins/`.
18
19
 
19
- And copy `extras/foreman_callback.py` from this repo to `~/.ansible/plugins/callback_plugins/`. That's it!
20
+ You can configure it via the following environment variables:
21
+
22
+ * FOREMAN_URL: the URL of your Foreman installation (default "http://localhost:3000")
23
+ * FOREMAN_SSL_CERT: The public key when using SSL client certificates (default "/etc/foreman/client_cert.pem")
24
+ * FOREMAN_SSL_KEY: The private key when using SSL client certificates (default "/etc/foreman/client_key.pem")
25
+ * FOREMAN_SSL_VERIFY: wether to verify SSL certificates. Use *False*
26
+ to disable certificate checks. You can also set it to CA bundle (default is "True").
27
+
28
+ See the [python-requests documentation](http://docs.python-requests.org/en/master/user/advanced/#ssl-cert-verification) on the details of certificate setup.
29
+
30
+ That's it!
20
31
 
21
32
  Now, every time you run a playbook or `ansible -m setup $HOSTNAME`, Ansible will automatically submit facts and a small report for $HOSTNAME to Foreman. See 'Extra information' below if you find any error.
22
33
 
@@ -62,3 +73,6 @@ GNU General Public License for more details.
62
73
 
63
74
  You should have received a copy of the GNU General Public License
64
75
  along with this program. If not, see <http://www.gnu.org/licenses/>.
76
+
77
+
78
+
@@ -0,0 +1,27 @@
1
+ module ForemanAnsible
2
+ # This module takes the config reports stored in Foreman for Ansible and
3
+ # modifies them to be properly presented in views
4
+ module AnsibleReportsHelper
5
+ def module_name(log)
6
+ JSON.parse(log.source.value)['module_name']
7
+ end
8
+
9
+ def module_args(log)
10
+ JSON.parse(log.source.value)['module_args']
11
+ end
12
+
13
+ def ansible_module_message(log)
14
+ paragraph_style = 'margin:0px;font-family:Menlo,Monaco,Consolas,monospace'
15
+ JSON.parse(log.message.value).except('invocation').map do |name, value|
16
+ next if value.blank?
17
+ "<p style=#{paragraph_style}>#{name}: #{value}</p>"
18
+ end.join.html_safe
19
+ end
20
+
21
+ def ansible_report?(log)
22
+ module_name(log).present?
23
+ rescue # Failures when parsing the log indicates it's not an Ansible report
24
+ false
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,6 @@
1
+ Deface::Override.new(
2
+ :virtual_path => 'config_reports/_output',
3
+ :name => 'report_output',
4
+ :surround => '#report_log',
5
+ :partial => 'foreman_ansible/config_reports/output'
6
+ )
@@ -53,7 +53,7 @@ module ForemanAnsible
53
53
 
54
54
  # Returns pairs [id, fact_name]
55
55
  def fact_names
56
- @fact_names ||= fact_name_class.group('name').maximum(:id)
56
+ fact_name_class.group('name').maximum(:id)
57
57
  end
58
58
 
59
59
  # Fact fully qualified name contains an unambiguous name for a fact
@@ -72,8 +72,9 @@ module ForemanAnsible
72
72
  def add_fact_value(value, fact_name)
73
73
  return unless missing_facts.include?(fact_name.name)
74
74
  method = host.new_record? ? :build : :create!
75
- #value = nil if compose?(value)
76
- host.fact_values.send(method, :value => value.to_s, :fact_name => fact_name)
75
+ host.fact_values.send(method,
76
+ :value => value.to_s,
77
+ :fact_name => fact_name)
77
78
  @counters[:added] += 1
78
79
  end
79
80
 
@@ -0,0 +1,23 @@
1
+ <table id='report_log' class="table table-bordered table-striped">
2
+ <thead>
3
+ <tr>
4
+ <th><%= _("Level") %></th>
5
+ <th><%= _("Module") %></th>
6
+ <th><%= _("Arguments") %></th>
7
+ <th><%= _("Message") %></th>
8
+ </tr>
9
+ </thead>
10
+ <tbody>
11
+ <% logs.each do |log| %>
12
+ <tr>
13
+ <td><span <%= report_tag log.level %>><%= h log.level %></span></td>
14
+ <td><%= h module_name(log) %></td>
15
+ <td><%= h module_args(log) %></td>
16
+ <td><%= ansible_module_message(log) %></td>
17
+ </tr>
18
+ <% end %>
19
+ <tr id='ntsh' <%= "style='display: none;'".html_safe if logs.size > 0%>><td colspan="3">
20
+ <%= _("Nothing to show") %>
21
+ </td></tr>
22
+ </tbody>
23
+ </table>
@@ -0,0 +1,15 @@
1
+ <!--
2
+ We parse a few parts of the report log, to check if it's an Ansible report
3
+ An alternative to this would be to subclass Ansible < ConfigReport and change
4
+ the API endpoint at api/v2/config_reports to accept a :type argument with the
5
+ config management system type.
6
+
7
+ However, that solution breaks compatibility of this plugin with older versions
8
+ of Foreman that do not have that endpoint.
9
+ -->
10
+ <% if ansible_report?(logs.first) %>
11
+ <%= render :partial => 'foreman_ansible/config_reports/ansible',
12
+ :locals => { :logs => logs } %>
13
+ <% else %>
14
+ <%= render_original, :locals => { :logs => logs } %>
15
+ <% end %>
@@ -1,14 +1,17 @@
1
+ require 'deface'
1
2
  module ForemanAnsible
2
3
  # This engine connects ForemanAnsible with Foreman core
3
4
  class Engine < ::Rails::Engine
4
5
  engine_name 'foreman_ansible'
5
6
 
7
+ config.autoload_paths += Dir["#{config.root}/app/helpers"]
6
8
  config.autoload_paths += Dir["#{config.root}/app/overrides"]
7
9
  config.autoload_paths += Dir["#{config.root}/app/services"]
10
+ config.autoload_paths += Dir["#{config.root}/app/views"]
8
11
 
9
- initializer 'foreman_ansible.register_plugin', :after => :finisher_hook do
12
+ initializer 'foreman_ansible.register_plugin', :before => :finisher_hook do
10
13
  Foreman::Plugin.register :foreman_ansible do
11
- requires_foreman '>= 1.6'
14
+ requires_foreman '>= 1.9'
12
15
  end
13
16
  end
14
17
 
@@ -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 = '0.2.2'
5
+ VERSION = '0.3'
6
6
  end
@@ -1,13 +1,3 @@
1
- # Tasks
2
- namespace :foreman_ansible do
3
- namespace :example do
4
- desc 'Example Task'
5
- task :task => :environment do
6
- # Task goes here
7
- end
8
- end
9
- end
10
-
11
1
  # Tests
12
2
  namespace :test do
13
3
  desc 'Test ForemanAnsible'
@@ -1 +1,10 @@
1
1
  require 'test_helper'
2
+
3
+ def sample_facts_file
4
+ File.read(File.join(
5
+ ForemanAnsible::Engine.root, 'test', 'fixtures', 'sample_facts.json'))
6
+ end
7
+
8
+ def facts_json
9
+ HashWithIndifferentAccess.new(JSON.parse(sample_facts_file))
10
+ end
@@ -0,0 +1,47 @@
1
+ require 'test_plugin_helper'
2
+
3
+ module ForemanAnsible
4
+ class FactImporterTest < ActiveSupport::TestCase
5
+ setup do
6
+ @host = FactoryGirl.build_stubbed(:host)
7
+ end
8
+
9
+ test 'add new facts adds all fact names in the fixture' do
10
+ @fact_importer = FactImporter.new(@host, facts_json)
11
+ facts_to_be_added = FactSparser.sparse(facts_json[:ansible_facts]).keys +
12
+ FactSparser.unsparse(facts_json[:ansible_facts]).keys
13
+ @fact_importer.send(:add_new_facts)
14
+ assert (facts_to_be_added - FactName.all.map(&:name)).empty?
15
+ end
16
+
17
+ test 'missing_facts returns facts we do not have in the database' do
18
+ @fact_importer = FactImporter.new(@host, facts_json)
19
+ @fact_importer.expects(:db_facts).returns('ansible_cmdline' => 'fakevalue')
20
+ refute @fact_importer.send(:missing_facts).include?('ansible_cmdline')
21
+ end
22
+
23
+ describe '#add_fact_value' do
24
+ setup do
25
+ @fact_importer = FactImporter.new(@host, :ansible_facts => {})
26
+ end
27
+ test 'does not add existing facts' do
28
+ existing_fact = FactoryGirl.build(:fact_name)
29
+ @fact_importer.expects(:missing_facts).returns([])
30
+ assert_nil @fact_importer.send(:add_fact_value, nil, existing_fact)
31
+ end
32
+
33
+ test 'adds missing facts' do
34
+ missing_fact = FactoryGirl.build(:fact_name)
35
+ @fact_importer.expects(:missing_facts).returns([missing_fact.name])
36
+ @fact_importer.counters[:added] = 0
37
+ assert_difference('@host.fact_values.count', 1) do
38
+ @fact_importer.send(:add_fact_value, 'missing_value', missing_fact)
39
+ end
40
+ end
41
+ end
42
+
43
+ test 'add_fact_value works for hosts that have not been created yet' do
44
+ end
45
+ end
46
+ end
47
+
@@ -3,40 +3,39 @@ require 'test_plugin_helper'
3
3
  module ForemanAnsible
4
4
  class FactParserTest < ActiveSupport::TestCase
5
5
  setup do
6
- facts_json = HashWithIndifferentAccess.new(JSON.parse(sample_facts_file))
7
- @facts_importer = ForemanAnsible::FactParser.new(facts_json)
6
+ @facts_parser = ForemanAnsible::FactParser.new(facts_json)
8
7
  end
9
8
 
10
9
  test 'finds facter domain even if ansible_domain is empty' do
11
- expect_where(Domain, @facts_importer.facts[:facter_domain])
12
- @facts_importer.domain
10
+ expect_where(Domain, @facts_parser.facts[:facter_domain])
11
+ @facts_parser.domain
13
12
  end
14
13
 
15
14
  test 'finds model' do
16
- expect_where(Model, @facts_importer.facts[:ansible_product_name])
17
- @facts_importer.model
15
+ expect_where(Model, @facts_parser.facts[:ansible_product_name])
16
+ @facts_parser.model
18
17
  end
19
18
 
20
19
  test 'finds architecture' do
21
- expect_where(Architecture, @facts_importer.facts[:ansible_architecture])
22
- @facts_importer.architecture
20
+ expect_where(Architecture, @facts_parser.facts[:ansible_architecture])
21
+ @facts_parser.architecture
23
22
  end
24
23
 
25
24
  test 'does not set environment' do
26
- refute @facts_importer.environment
25
+ refute @facts_parser.environment
27
26
  end
28
27
 
29
28
  test 'creates operatingsystem from operating system options' do
30
29
  sample_mock = mock
31
- major_fact = @facts_importer.facts['ansible_distribution_major_version']
32
- _, minor_fact = @facts_importer.
30
+ major_fact = @facts_parser.facts['ansible_distribution_major_version']
31
+ _, minor_fact = @facts_parser.
33
32
  facts['ansible_distribution_version'].split('.')
34
33
  Operatingsystem.expects(:where).
35
- with(:name => @facts_importer.facts['ansible_distribution'],
34
+ with(:name => @facts_parser.facts['ansible_distribution'],
36
35
  :major => major_fact, :minor => minor_fact || '').
37
36
  returns(sample_mock)
38
37
  sample_mock.expects(:first)
39
- @facts_importer.operatingsystem
38
+ @facts_parser.operatingsystem
40
39
  end
41
40
 
42
41
  private
@@ -48,9 +47,5 @@ module ForemanAnsible
48
47
  returns(sample_mock)
49
48
  sample_mock.expects(:first_or_create)
50
49
  end
51
-
52
- def sample_facts_file
53
- File.read(File.join(Engine.root, 'test', 'fixtures', 'sample_facts.json'))
54
- end
55
50
  end
56
51
  end
@@ -7,17 +7,17 @@ module ForemanAnsible
7
7
  'name' => 'Fedora' } }
8
8
  @sparsed_os_facts = { 'operatingsystem::major' => 20,
9
9
  'operatingsystem::minor' => 1,
10
- 'operatingsystem::name' => 'Fedora'}
10
+ 'operatingsystem::name' => 'Fedora' }
11
11
  end
12
12
 
13
13
  test 'sparses simple hash' do
14
14
  assert_equal @sparsed_os_facts,
15
- ForemanAnsible::FactSparser.sparse(@original_os_facts)
15
+ ForemanAnsible::FactSparser.sparse(@original_os_facts)
16
16
  end
17
17
 
18
18
  test 'unsparse simple hash' do
19
19
  assert_equal @original_os_facts,
20
- ForemanAnsible::FactSparser.unsparse(@sparsed_os_facts)
20
+ ForemanAnsible::FactSparser.unsparse(@sparsed_os_facts)
21
21
  end
22
22
  end
23
23
  end
@@ -0,0 +1,23 @@
1
+ require 'test_plugin_helper'
2
+
3
+ module ForemanAnsible
4
+ module Helpers
5
+ class AnsibleReportsHelperTest < ActiveSupport::TestCase
6
+ include ForemanAnsible::AnsibleReportsHelper
7
+
8
+ test 'ansible_report? returns false when log is not parseable' do
9
+ refute ansible_report?('')
10
+ end
11
+
12
+ test 'ansible_report? returns false when log is from Puppet' do
13
+ refute ansible_report?(FactoryGirl.build(:log))
14
+ end
15
+
16
+ test 'ansible_report? returns true when log contains module_name' do
17
+ log = FactoryGirl.build(:log)
18
+ log.source.value = '{ "module_name" : "foo" }'
19
+ assert ansible_report?(log)
20
+ end
21
+ end
22
+ end
23
+ 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: 0.2.2
4
+ version: '0.3'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Lobato Garcia
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-05 00:00:00.000000000 Z
11
+ date: 2016-02-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubocop
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: deface
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "<"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "<"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
27
41
  description: Ansible integration with Foreman
28
42
  email:
29
43
  - elobatocs@gmail.com
@@ -34,10 +48,14 @@ files:
34
48
  - LICENSE
35
49
  - README.md
36
50
  - Rakefile
51
+ - app/helpers/foreman_ansible/ansible_reports_helper.rb
37
52
  - app/models/foreman_ansible/fact_name.rb
53
+ - app/overrides/report_output.rb
38
54
  - app/services/foreman_ansible/fact_importer.rb
39
55
  - app/services/foreman_ansible/fact_parser.rb
40
56
  - app/services/foreman_ansible/fact_sparser.rb
57
+ - app/views/foreman_ansible/config_reports/_ansible.html.erb
58
+ - app/views/foreman_ansible/config_reports/_output.html.erb
41
59
  - lib/foreman_ansible.rb
42
60
  - lib/foreman_ansible/engine.rb
43
61
  - lib/foreman_ansible/version.rb
@@ -48,8 +66,10 @@ files:
48
66
  - locale/gemspec.rb
49
67
  - test/fixtures/sample_facts.json
50
68
  - test/test_plugin_helper.rb
69
+ - test/unit/fact_importer_test.rb
51
70
  - test/unit/fact_parser_test.rb
52
71
  - test/unit/fact_sparser_test.rb
72
+ - test/unit/helpers/foreman_ansible/ansible_reports_helper_test.rb
53
73
  homepage: https://github.com/theforeman/foreman_ansible
54
74
  licenses:
55
75
  - GPL-3
@@ -78,4 +98,6 @@ test_files:
78
98
  - test/fixtures/sample_facts.json
79
99
  - test/test_plugin_helper.rb
80
100
  - test/unit/fact_parser_test.rb
101
+ - test/unit/fact_importer_test.rb
81
102
  - test/unit/fact_sparser_test.rb
103
+ - test/unit/helpers/foreman_ansible/ansible_reports_helper_test.rb