puppetdb_foreman 4.0.0 → 6.0.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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -23
  3. data/Rakefile +9 -6
  4. data/app/controllers/api/v2/puppetdb_nodes_controller.rb +8 -6
  5. data/app/controllers/puppetdb_foreman/nodes_controller.rb +32 -7
  6. data/app/helpers/concerns/puppetdb_foreman/hosts_helper_extensions.rb +28 -0
  7. data/app/models/concerns/orchestration/puppetdb.rb +13 -6
  8. data/app/models/puppetdb_foreman/host_extensions.rb +5 -4
  9. data/app/services/puppetdb.rb +8 -12
  10. data/app/services/puppetdb_client/base.rb +12 -6
  11. data/app/services/puppetdb_client/v4.rb +48 -1
  12. data/app/services/puppetdb_host.rb +5 -3
  13. data/app/views/api/v2/puppetdb_nodes/import.json.rabl +2 -0
  14. data/app/views/api/v2/puppetdb_nodes/index.json.rabl +2 -0
  15. data/app/views/api/v2/puppetdb_nodes/unknown.json.rabl +2 -0
  16. data/app/views/puppetdb_foreman/nodes/index.html.erb +1 -0
  17. data/app/views/puppetdb_foreman/nodes/show.html.erb +69 -0
  18. data/config/routes.rb +11 -11
  19. data/db/migrate/20170717140010_migrate_puppetdb_api_version_setting.rb +4 -2
  20. data/db/migrate/20181001113836_remove_puppetdb_dashboard_address_setting.puppetdb_foreman.rb +7 -0
  21. data/lib/puppetdb_foreman/engine.rb +58 -33
  22. data/lib/puppetdb_foreman/version.rb +3 -1
  23. data/lib/puppetdb_foreman.rb +2 -0
  24. data/lib/tasks/puppetdb_foreman_tasks.rake +4 -4
  25. data/test/controllers/api/v2/puppetdb_nodes_controller_test.rb +60 -55
  26. data/test/controllers/nodes_controller_test.rb +34 -9
  27. data/test/models/host_test.rb +5 -4
  28. data/test/static_fixtures/resources.json +41 -0
  29. data/test/test_plugin_helper.rb +2 -4
  30. data/test/unit/puppetdb_host_test.rb +5 -4
  31. data/test/unit/puppetdb_test.rb +34 -85
  32. metadata +20 -23
  33. data/app/controllers/puppetdb_foreman/puppetdb_controller.rb +0 -30
  34. data/app/models/setting/puppetdb.rb +0 -52
  35. data/app/services/puppetdb_client/v1.rb +0 -29
  36. data/app/services/puppetdb_client/v3.rb +0 -45
  37. data/app/views/puppetdb_foreman/puppetdb/error.html.erb +0 -6
  38. data/test/static_fixtures/query_nodes.json +0 -61
@@ -1,58 +1,83 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PuppetdbForeman
2
4
  class Engine < ::Rails::Engine
3
5
  engine_name 'puppetdb_foreman'
4
6
 
5
- initializer 'puppetdb_foreman.load_default_settings', :before => :load_config_initializers do |_app|
6
- require_dependency File.expand_path('../../../app/models/setting/puppetdb.rb', __FILE__) if begin
7
- Setting.table_exists?
8
- rescue StandardError
9
- (false)
10
- end
11
- end
12
-
13
7
  initializer 'puppetdb_foreman.load_app_instance_data' do |app|
14
8
  PuppetdbForeman::Engine.paths['db/migrate'].existent.each do |path|
15
9
  app.config.paths['db/migrate'] << path
16
10
  end
17
11
  end
18
12
 
19
- initializer 'puppetdb_foreman.register_plugin', :before => :finisher_hook do |_app|
13
+ initializer 'puppetdb_foreman.register_plugin', before: :finisher_hook do |_app|
20
14
  Foreman::Plugin.register :puppetdb_foreman do
21
- requires_foreman '>= 1.17'
15
+ requires_foreman '>= 3.1'
22
16
 
23
17
  apipie_documented_controllers ["#{PuppetdbForeman::Engine.root}/app/controllers/api/v2/*.rb"]
24
18
 
19
+ settings do
20
+ category :puppetdb, N_('PuppetDB') do
21
+ setting :puppetdb_enabled,
22
+ type: :boolean,
23
+ default: false,
24
+ description: _("Integration with PuppetDB, enabled will deactivate a host in PuppetDB when it's deleted in Foreman") # rubocop:disable Layout/LineLength
25
+
26
+ setting :puppetdb_address,
27
+ type: :string,
28
+ default: 'https://puppetdb:8081/pdb/cmd/v1',
29
+ description: _('Foreman will send PuppetDB requests to this address')
30
+
31
+ setting :puppetdb_ssl_ca_file,
32
+ type: :string,
33
+ default: SETTINGS[:ssl_ca_file],
34
+ description: _('Foreman will send PuppetDB requests with this CA file')
35
+
36
+ setting :puppetdb_ssl_certificate,
37
+ type: :string,
38
+ default: SETTINGS[:ssl_certificate],
39
+ description: _('Foreman will send PuppetDB requests with this certificate file')
40
+
41
+ setting :puppetdb_ssl_private_key,
42
+ type: :string,
43
+ default: SETTINGS[:ssl_priv_key],
44
+ description: _('Foreman will send PuppetDB requests with this key file')
45
+
46
+ setting :puppetdb_api_version,
47
+ type: :integer,
48
+ default: 4,
49
+ full_name: N_('PuppetDB API Version'),
50
+ description: _('Foreman will use this PuppetDB API version'),
51
+ collection: proc { ::Puppetdb::API_VERSIONS }
52
+ end
53
+ end
54
+
25
55
  security_block :puppetdb_foreman do
26
- permission :view_puppetdb_dashboard, :'puppetdb_foreman/puppetdb' => [:index]
27
- permission :view_puppetdb_nodes, :'puppetdb_foreman/nodes' => [:index],
28
- :'api/v2/puppetdb_nodes' => [:index, :unknown]
29
- permission :destroy_puppetdb_nodes, :'puppetdb_foreman/nodes' => [:destroy],
30
- :'api/v2/puppetdb_nodes' => [:destroy]
31
- permission :import_puppetdb_nodes, :'puppetdb_foreman/nodes' => [:import],
32
- :'api/v2/puppetdb_nodes' => [:import]
56
+ permission :view_puppetdb_nodes, 'puppetdb_foreman/nodes': %i[index show],
57
+ 'api/v2/puppetdb_nodes': %i[index unknown]
58
+
59
+ permission :destroy_puppetdb_nodes, 'puppetdb_foreman/nodes': [:destroy],
60
+ 'api/v2/puppetdb_nodes': [:destroy]
61
+
62
+ permission :import_puppetdb_nodes, 'puppetdb_foreman/nodes': [:import],
63
+ 'api/v2/puppetdb_nodes': [:import]
33
64
  end
34
65
 
35
- role 'PuppetDB Dashboard', [:view_puppetdb_dashboard]
36
66
  role 'PuppetDB Node Viewer', [:view_puppetdb_nodes]
37
- role 'PuppetDB Node Manager', [:view_puppetdb_nodes, :destroy_puppetdb_nodes, :import_puppetdb_nodes]
38
-
39
- menu :top_menu, :puppetdb, :caption => N_('PuppetDB Dashboard'),
40
- :url_hash => { :controller => 'puppetdb_foreman/puppetdb', :action => 'index', :puppetdb => 'puppetdb' },
41
- :parent => :monitor_menu,
42
- :last => :true
43
- menu :top_menu, :nodes, :caption => N_('PuppetDB Nodes'),
44
- :url_hash => { :controller => 'puppetdb_foreman/nodes', :action => 'index' },
45
- :parent => :monitor_menu,
46
- :after => :puppetdb
67
+ role 'PuppetDB Node Manager', %i[view_puppetdb_nodes destroy_puppetdb_nodes import_puppetdb_nodes]
68
+
69
+ menu :top_menu, :nodes, caption: N_('PuppetDB Nodes'),
70
+ url_hash: { controller: 'puppetdb_foreman/nodes', action: 'index' },
71
+ parent: :monitor_menu,
72
+ after: :puppetdb
47
73
  end
48
74
  end
49
75
 
50
76
  config.to_prepare do
51
- begin
52
- Host::Managed.send :include, PuppetdbForeman::HostExtensions
53
- rescue StandardError => e
54
- Rails.logger.warn "PuppetdbForeman: skipping engine hook (#{e})"
55
- end
77
+ Host::Managed.include PuppetdbForeman::HostExtensions
78
+ HostsHelper.include PuppetdbForeman::HostsHelperExtensions
79
+ rescue StandardError => e
80
+ Rails.logger.warn "PuppetdbForeman: skipping engine hook (#{e})"
56
81
  end
57
82
  end
58
83
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PuppetdbForeman
2
- VERSION = '4.0.0'.freeze
4
+ VERSION = '6.0.0'
3
5
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PuppetdbForeman
2
4
  require 'puppetdb_foreman/engine'
3
5
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Tests
2
4
  namespace :test do
3
5
  desc 'Test PuppetdbForeman'
@@ -11,7 +13,7 @@ namespace :test do
11
13
  end
12
14
 
13
15
  namespace :puppetdb_foreman do
14
- task :rubocop do
16
+ task rubocop: :environment do
15
17
  begin
16
18
  require 'rubocop/rake_task'
17
19
  RuboCop::RakeTask.new(:rubocop_puppetdb_foreman) do |task|
@@ -30,6 +32,4 @@ end
30
32
  Rake::Task[:test].enhance ['test:puppetdb_foreman']
31
33
 
32
34
  load 'tasks/jenkins.rake'
33
- if Rake::Task.task_defined?(:'jenkins:unit')
34
- Rake::Task['jenkins:unit'].enhance ['test:puppetdb_foreman', 'puppetdb_foreman:rubocop']
35
- end
35
+ Rake::Task['jenkins:unit'].enhance ['test:puppetdb_foreman', 'puppetdb_foreman:rubocop'] if Rake::Task.task_defined?(:'jenkins:unit')
@@ -1,68 +1,73 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_plugin_helper'
2
4
 
3
- class Api::V2::PuppetdbNodesControllerTest < ActionController::TestCase
4
- setup do
5
- setup_settings
6
- User.current = users(:admin)
7
- @host = FactoryBot.create(:host, :managed)
8
- end
5
+ module Api
6
+ module V2
7
+ class PuppetdbNodesControllerTest < ActionController::TestCase
8
+ setup do
9
+ User.current = users(:admin)
10
+ @host = FactoryBot.create(:host, :managed)
11
+ end
9
12
 
10
- context '#index' do
11
- test 'lists puppetdb nodes unknown to foreman' do
12
- ::PuppetdbClient::V4.any_instance.stubs(:query_nodes).returns(['one.example.com', 'two.example.com'])
13
- get :index, session: set_session_user
14
- assert_response :success
15
- response = ActiveSupport::JSON.decode(@response.body)
16
- hosts = response['results']
17
- assert_includes hosts, 'name' => 'one.example.com'
18
- assert_includes hosts, 'name' => 'two.example.com'
19
- end
20
- end
13
+ context '#index' do
14
+ test 'lists puppetdb nodes unknown to foreman' do
15
+ ::PuppetdbClient::V4.any_instance.stubs(:query_nodes).returns(['one.example.com', 'two.example.com'])
16
+ get :index, session: set_session_user
17
+ assert_response :success
18
+ response = ActiveSupport::JSON.decode(@response.body)
19
+ hosts = response['results']
20
+ assert_includes hosts, 'name' => 'one.example.com'
21
+ assert_includes hosts, 'name' => 'two.example.com'
22
+ end
23
+ end
21
24
 
22
- context '#unknown' do
23
- test 'lists puppetdb nodes unknown to foreman' do
24
- host = FactoryBot.create(:host, :managed)
25
- ::PuppetdbClient::V4.any_instance.stubs(:query_nodes).returns([host.name, 'two.example.com'])
26
- get :unknown, session: set_session_user
27
- assert_response :success
28
- response = ActiveSupport::JSON.decode(@response.body)
29
- hosts = response['results']
30
- refute_includes hosts, 'name' => host.name
31
- assert_includes hosts, 'name' => 'two.example.com'
32
- end
33
- end
25
+ context '#unknown' do
26
+ test 'lists puppetdb nodes unknown to foreman' do
27
+ host = FactoryBot.create(:host, :managed)
28
+ ::PuppetdbClient::V4.any_instance.stubs(:query_nodes).returns([host.name, 'two.example.com'])
29
+ get :unknown, session: set_session_user
30
+ assert_response :success
31
+ response = ActiveSupport::JSON.decode(@response.body)
32
+ hosts = response['results']
33
+ assert_not_includes hosts, 'name' => host.name
34
+ assert_includes hosts, 'name' => 'two.example.com'
35
+ end
36
+ end
34
37
 
35
- context '#destroy' do
36
- let(:node) { 'test.example.com' }
37
- let(:uuid) { SecureRandom.uuid }
38
+ context '#destroy' do
39
+ let(:node) { 'test.example.com' }
40
+ let(:uuid) { SecureRandom.uuid }
38
41
 
39
- before do
40
- ::PuppetdbClient::V4.any_instance.expects(:deactivate_node).with(node).returns(uuid)
41
- end
42
+ before do
43
+ ::PuppetdbClient::V4.any_instance.expects(:deactivate_node).with(node).returns(uuid)
44
+ end
42
45
 
43
- test 'imports a host by puppetdb facts' do
44
- delete :destroy, params: { :id => node }, session: set_session_user
45
- assert_response :success
46
- response = ActiveSupport::JSON.decode(@response.body)
47
- expected = { 'job' => { 'uuid' => uuid } }
48
- assert_equal expected, response
49
- end
50
- end
46
+ test 'imports a host by puppetdb facts' do
47
+ delete :destroy, params: { id: node }, session: set_session_user
48
+ assert_response :success
49
+ response = ActiveSupport::JSON.decode(@response.body)
50
+ expected = { 'job' => { 'uuid' => uuid } }
51
+ assert_equal expected, response
52
+ end
53
+ end
51
54
 
52
- context '#import' do
53
- let(:node) { 'test.example.com' }
54
- let(:host) { FactoryBot.create(:host) }
55
+ context '#import' do
56
+ let(:node) { 'test.example.com' }
57
+ let(:host) { FactoryBot.create(:host) }
55
58
 
56
- before do
57
- ::PuppetdbClient::V4.any_instance.expects(:facts).with(node).returns({})
58
- PuppetdbHost.any_instance.expects(:to_host).returns(host)
59
- end
59
+ before do
60
+ ::PuppetdbClient::V4.any_instance.expects(:facts).with(node).returns({})
61
+ PuppetdbHost.any_instance.expects(:to_host).returns(host)
62
+ end
60
63
 
61
- test 'imports a host by puppetdb facts' do
62
- put :import, params: { :id => node }, session: set_session_user
63
- assert_response :success
64
- response = ActiveSupport::JSON.decode(@response.body)
65
- assert_equal host.id, response['id']
64
+ test 'imports a host by puppetdb facts' do
65
+ put :import, params: { id: node }, session: set_session_user
66
+ assert_response :success
67
+ response = ActiveSupport::JSON.decode(@response.body)
68
+ assert_equal host.id, response['id']
69
+ end
70
+ end
66
71
  end
67
72
  end
68
73
  end
@@ -1,10 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_plugin_helper'
2
4
 
3
5
  class NodesControllerTest < ActionController::TestCase
4
6
  tests ::PuppetdbForeman::NodesController
5
7
 
6
8
  setup do
7
- setup_settings
8
9
  User.current = users(:admin)
9
10
  @host = FactoryBot.create(:host, :managed)
10
11
  end
@@ -15,21 +16,45 @@ class NodesControllerTest < ActionController::TestCase
15
16
  ::PuppetdbClient::V4.any_instance.stubs(:query_nodes).returns([host.name, 'two.example.com'])
16
17
  get :index, session: set_session_user
17
18
  assert_response :success
18
- refute response.body =~ /#{host.name}/m
19
+ assert_not response.body =~ /#{host.name}/m
19
20
  assert response.body =~ /two.example.com/m
20
21
  end
21
22
  end
22
23
 
24
+ context '#show' do
25
+ let(:host) { FactoryBot.create(:host, :managed) }
26
+
27
+ before do
28
+ resources_resp = [
29
+ { 'type' => 'Class', 'title' => 'main' },
30
+ { 'type' => 'Class', 'title' => 'Settings' },
31
+ { 'type' => 'Stage', 'title' => 'main' },
32
+ ]
33
+
34
+ ::PuppetdbClient::V4.any_instance.stubs(:resources).returns(resources_resp)
35
+ end
36
+
37
+ test 'displays puppet classes information about a given node' do
38
+ get :show, params: { id: host.name }, session: set_session_user
39
+
40
+ assert_response :success
41
+ assert_includes response.body, '<tr><td>main</td></tr>'
42
+ assert_includes response.body, '<tr><td>Settings</td></tr>'
43
+ assert_includes response.body, '2</span> Classes'
44
+ assert_includes response.body, '2</span> Types'
45
+ end
46
+ end
47
+
23
48
  context '#destroy' do
24
49
  let(:node) { 'test.example.com' }
25
50
  test 'deactivating a node in puppetdb' do
26
51
  ::PuppetdbClient::V4.any_instance.expects(:deactivate_node).with(node).returns(true)
27
- delete :destroy, params: { :id => node }, session: set_session_user
52
+ delete :destroy, params: { id: node }, session: set_session_user
28
53
  assert_response :found
29
54
  assert_redirected_to puppetdb_foreman_nodes_path
30
55
  assert_nil flash[:error]
31
- assert_not_nil flash[:notice]
32
- assert_equal "Deactivated node #{node} in PuppetDB", flash[:notice]
56
+ assert_not_nil flash[:notice] || flash[:success]
57
+ assert_equal "Deactivated node #{node} in PuppetDB", flash[:notice] || flash[:success]
33
58
  end
34
59
  end
35
60
 
@@ -43,12 +68,12 @@ class NodesControllerTest < ActionController::TestCase
43
68
  end
44
69
 
45
70
  test 'imports a host from puppetdb facts' do
46
- put :import, params: { :id => node }, session: set_session_user
71
+ put :import, params: { id: node }, session: set_session_user
47
72
  assert_response :found
48
- assert_redirected_to host_path(:id => host)
73
+ assert_redirected_to host_path(id: host)
49
74
  assert_nil flash[:error]
50
- assert_not_nil flash[:notice]
51
- assert_equal "Imported host #{node} from PuppetDB", flash[:notice]
75
+ assert_not_nil flash[:notice] || flash[:success]
76
+ assert_equal "Imported host #{node} from PuppetDB", flash[:notice] || flash[:success]
52
77
  end
53
78
  end
54
79
  end
@@ -1,9 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_plugin_helper'
2
4
 
3
5
  class HostTest < ActiveSupport::TestCase
4
6
  setup do
5
7
  User.current = FactoryBot.build(:user, :admin)
6
- setup_settings
7
8
  disable_orchestration
8
9
  end
9
10
 
@@ -24,9 +25,9 @@ class HostTest < ActiveSupport::TestCase
24
25
  assert_equal 1, tasks.size
25
26
  end
26
27
 
27
- test '#delPuppetdb' do
28
+ test '#del_puppetdb' do
28
29
  ::PuppetdbClient::V4.any_instance.expects(:deactivate_node).with(host.name).returns(true)
29
- host.send(:delPuppetdb)
30
+ host.send(:del_puppetdb)
30
31
  end
31
32
  end
32
33
 
@@ -40,7 +41,7 @@ class HostTest < ActiveSupport::TestCase
40
41
  host.queue.clear
41
42
  host.send(:queue_puppetdb_destroy)
42
43
  tasks = host.queue.all.map(&:name)
43
- assert_equal [], tasks
44
+ assert_empty tasks
44
45
  end
45
46
  end
46
47
  end
@@ -0,0 +1,41 @@
1
+ [{
2
+ "tags": ["params", "class"],
3
+ "file": null,
4
+ "type": "Class",
5
+ "title": "Cron",
6
+ "line": null,
7
+ "resource": "f13ec266-2914-420c-8d71-13e3466c5856",
8
+ "certname": "host.example.com",
9
+ "parameters": {},
10
+ "exported": false
11
+ }, {
12
+ "tags": ["class"],
13
+ "file": null,
14
+ "type": "Anchor",
15
+ "title": "postgresql",
16
+ "line": null,
17
+ "resource": "9b007f50-87f3-48a1-a4c5-584f2f9d1740",
18
+ "certname": "host.example.com",
19
+ "parameters": {},
20
+ "exported": false
21
+ }, {
22
+ "tags": ["class"],
23
+ "file": null,
24
+ "type": "Class",
25
+ "title": "SomeClass",
26
+ "line": 21,
27
+ "resource": "4b68c39a-b1cc-45ab-96c2-690dbc045f76",
28
+ "certname": "host.example.com",
29
+ "parameters": {},
30
+ "exported": false
31
+ }, {
32
+ "tags": ["class", "params"],
33
+ "file": null,
34
+ "type": "Class",
35
+ "title": "AnotherClass::Params",
36
+ "line": null,
37
+ "resource": "69293889-3e16-48e1-943f-5602096f6c47",
38
+ "certname": "host.example.com",
39
+ "parameters": {},
40
+ "exported": false
41
+ }]
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This calls the main test_helper in Foreman-core
2
4
  require 'test_helper'
3
5
  require 'database_cleaner'
@@ -6,10 +8,6 @@ require 'webmock/minitest'
6
8
  # Foreman's setup doesn't handle cleaning up for Minitest::Spec
7
9
  DatabaseCleaner.strategy = :transaction
8
10
 
9
- def setup_settings
10
- Setting::Puppetdb.load_defaults
11
- end
12
-
13
11
  def fixture(name)
14
12
  File.read(File.expand_path("../static_fixtures/#{name}", __FILE__))
15
13
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_plugin_helper'
2
4
 
3
5
  class PuppetdbHostTest < ActiveSupport::TestCase
@@ -7,7 +9,6 @@ class PuppetdbHostTest < ActiveSupport::TestCase
7
9
  setup do
8
10
  User.current = FactoryBot.create(:user, :admin)
9
11
  disable_orchestration
10
- setup_settings
11
12
  end
12
13
 
13
14
  let(:sample_facts) do
@@ -15,7 +16,7 @@ class PuppetdbHostTest < ActiveSupport::TestCase
15
16
  end
16
17
 
17
18
  let(:pdbhost) do
18
- PuppetdbHost.new(:facts => sample_facts)
19
+ PuppetdbHost.new(facts: sample_facts)
19
20
  end
20
21
 
21
22
  test 'parses facts' do
@@ -35,12 +36,12 @@ class PuppetdbHostTest < ActiveSupport::TestCase
35
36
 
36
37
  test 'updates an existing host by facts' do
37
38
  Setting[:update_subnets_from_facts] = true
38
- FactoryBot.create(:host, :managed, :hostname => 'host', :domain => FactoryBot.create(:domain, :name => 'example.com'))
39
+ FactoryBot.create(:host, :managed, hostname: 'host', domain: FactoryBot.create(:domain, name: 'example.com'))
39
40
  pdbhost.to_host
40
41
  host = Host.find_by(name: 'host.example.com')
41
42
  assert_equal 'host.example.com', host.name
42
43
  # foreman core does not delete old interfaces when importing interfaces from facts
43
- assert host.interfaces.where(:ip => '1.1.1.174').first
44
+ assert host.interfaces.where(ip: '1.1.1.174').first
44
45
  assert_equal Operatingsystem.find_by(title: 'RedHat 7.3'), host.operatingsystem
45
46
  end
46
47
  end