foreman_salt 13.2.4 → 14.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fddee03aa8a25bb479f486dff933348cd4d2ecd5f58acfd3a24b0f41e42add81
4
- data.tar.gz: fd3936b47b815c6dde269e4b1a31c31688f32654d77b134d64fec3f9a001c279
3
+ metadata.gz: 287507e11ca2f63bc8341eae5bc832e7d95ad5b848922b9eba44b85486fd9dc3
4
+ data.tar.gz: e1a70ace048abbcf30d57e0631f8b1ad1627bbad3c5261b2196d0a92663ef833
5
5
  SHA512:
6
- metadata.gz: 0cc753435d43457397cab17d476c9bd35a411ce11835f33e664b3032efe847332762e8b1b28efc3f97051cd7015bb0b99662aae6502ad52c3c8f232f62d6029c
7
- data.tar.gz: 9840624a4241c66a91314f1a5a4eff96dada377aa0bf7b33bcb9d928143ed795978b6f874d6e444f4678c1d623e13e5b53601734ad08180fcbc320c3eb9d8780
6
+ metadata.gz: '08395ab98cb79f8dfc725268cfcb9dc8b11c015562625ea56f90315edaa9bcf1c76601d123481d57eed865212cc7212cfa36be6ea1506d8e59d1ac15afaa5f2b'
7
+ data.tar.gz: f7a59b6f52e80340520a8ed4523e39727659612a737fb848c33731013684f09dcbe83e27c02c928a22614f18842120ce3d53908bc2ec4176a153bb69c2124527
data/README.md CHANGED
@@ -17,6 +17,7 @@ This plug-in adds support for Salt to Foreman.
17
17
  | >= 1.22 | 10.3.1 |
18
18
  | >= 1.23 | 11.0.1 |
19
19
  | >= 1.24 | 13.2.0 |
20
+ | >= 2.5 | 14.0.0 |
20
21
 
21
22
  ## Documentation
22
23
 
@@ -4,7 +4,15 @@ module ForemanSalt
4
4
  module Api
5
5
  module V2
6
6
  class SaltAutosignController < ::ForemanSalt::Api::V2::BaseController
7
- before_action :find_proxy, :setup_proxy
7
+ include ::Foreman::Controller::SmartProxyAuth
8
+ include ::Foreman::Controller::Parameters::Host
9
+
10
+ # The add_smart_proxy_filters must be executed first! Otherwise, resource_finder won't work properly
11
+ add_smart_proxy_filters :auth
12
+
13
+ before_action :find_proxy, except: [:auth]
14
+ before_action :find_host, :find_proxy_via_host, only: [:auth]
15
+ before_action :setup_proxy
8
16
 
9
17
  api :GET, '/salt_autosign/:smart_proxy_id', N_('List all autosign records')
10
18
  param :smart_proxy_id, :identifier_dottable, :required => true
@@ -28,6 +36,18 @@ module ForemanSalt
28
36
  render :json => { root_node_name => _('Record deleted.') }
29
37
  end
30
38
 
39
+ api :PUT, '/salt_autosign_auth', N_("Set the salt_status as \'successful authentication\' and remove the corresponding autosign key from the Smart Proxy")
40
+ param :name, String, :required => true
41
+ def auth
42
+ Rails.logger.info("Removing Salt autosign key and update status for host #{@host}")
43
+ @api.autosign_remove_key(@host.salt_autosign_key) unless @host.salt_autosign_key.nil?
44
+ @host.update(:salt_status => ForemanSalt::SaltStatus.minion_auth_success)
45
+ render :json => { :message => "Removed autosign key and updated status succesfully" }, :status => 204
46
+ rescue ::Foreman::Exception => e
47
+ Rails.logger.warn("Cannot delete autosign key of host (id => #{params[:name]}) state: #{e}")
48
+ render :json => { :message => e.to_s }, :status => :unprocessable_entity
49
+ end
50
+
31
51
  def metadata_total
32
52
  @total ||= all_autosign.count
33
53
  end
@@ -50,11 +70,21 @@ module ForemanSalt
50
70
  @_autosigns ||= @api.autosign_list.map { |record| OpenStruct.new(:record => record) }
51
71
  end
52
72
 
73
+ def find_host
74
+ @host = resource_finder(Host.authorized(:view_hosts), params[:name])
75
+ not_found unless @host
76
+ end
77
+
53
78
  def find_proxy
54
79
  @proxy = ::SmartProxy.friendly.find(params[:smart_proxy_id])
55
80
  not_found unless @proxy
56
81
  end
57
82
 
83
+ def find_proxy_via_host
84
+ @proxy = ::SmartProxy.friendly.find(@host.salt_proxy.id)
85
+ not_found unless @proxy
86
+ end
87
+
58
88
  def setup_proxy
59
89
  @api = ProxyAPI::Salt.new(:url => @proxy.url)
60
90
  end
@@ -14,7 +14,7 @@ module ::ProxyAPI
14
14
  def autosign_create(name)
15
15
  parse(post('', "autosign/#{URI.escape(name)}"))
16
16
  rescue => e
17
- raise ProxyException.new(url, e, N_('Unable to set Salt autosign for %s'), name)
17
+ raise ProxyException.new(url, e, N_('Unable to set Salt autosign hostname for %s'), name)
18
18
  end
19
19
 
20
20
  def autosign_remove(name)
@@ -22,7 +22,21 @@ module ::ProxyAPI
22
22
  rescue RestClient::ResourceNotFound
23
23
  true # entry doesn't exists anyway
24
24
  rescue => e
25
- raise ProxyException.new(url, e, N_('Unable to delete Salt autosign for %s'), name)
25
+ raise ProxyException.new(url, e, N_('Unable to delete Salt autosign hostname for %s'), name)
26
+ end
27
+
28
+ def autosign_create_key(key)
29
+ parse(post('', "autosign_key/#{URI.escape(key)}"))
30
+ rescue => e
31
+ raise ProxyException.new(url, e, N_('Unable to create Salt autosign key %s'), key)
32
+ end
33
+
34
+ def autosign_remove_key(key)
35
+ parse(delete("autosign_key/#{URI.escape(key)}"))
36
+ rescue RestClient::ResourceNotFound
37
+ true # entry doesn't exists anyway
38
+ rescue => e
39
+ raise ProxyException.new(url, e, N_('Unable to delete Salt autosign key %s'), key)
26
40
  end
27
41
 
28
42
  def environments_list
@@ -42,9 +42,8 @@ module ForemanSalt
42
42
 
43
43
  validate :salt_modules_in_host_environment
44
44
 
45
- after_build :delete_salt_key, :if => ->(host) { host.salt_proxy }
46
- before_provision :accept_salt_key, :if => ->(host) { host.salt_proxy }
47
- before_destroy :delete_salt_key, :if => ->(host) { host.salt_proxy }
45
+ after_build :ensure_salt_autosign, :if => ->(host) { host.salt_proxy }
46
+ before_destroy :remove_salt_minion, :if => ->(host) { host.salt_proxy }
48
47
  end
49
48
 
50
49
  def salt_params
@@ -58,6 +57,14 @@ module ForemanSalt
58
57
  end
59
58
  end
60
59
 
60
+ def host_params_grains_name
61
+ "salt_grains"
62
+ end
63
+
64
+ def autosign_grain_name
65
+ "autosign_key"
66
+ end
67
+
61
68
  def salt_modules_for_enc
62
69
  all_salt_modules.collect(&:name).uniq
63
70
  end
@@ -95,24 +102,66 @@ module ForemanSalt
95
102
  end
96
103
  end
97
104
 
98
- private
99
-
100
- def accept_salt_key
105
+ def derive_salt_grains(use_autosign: False)
106
+ grains = {}
101
107
  begin
102
- Rails.logger.info("Host #{fqdn} is built, accepting Salt key")
103
- key = ForemanSalt::SmartProxies::SaltKeys.find(salt_proxy, fqdn)
104
- key&.accept
108
+ Rails.logger.info("Derive Salt Grains from host_params and autosign_key")
109
+ grains[autosign_grain_name] = salt_autosign_key if use_autosign && !salt_autosign_key.nil?
110
+ unless host_params[host_params_grains_name].nil? ||
111
+ host_params[host_params_grains_name].class != Hash
112
+ grains.merge!(host_params[host_params_grains_name])
113
+ end
105
114
  rescue Foreman::Exception => e
106
- Rails.logger.warn("Unable to accept key for #{fqdn}: #{e}")
115
+ Rails.logger.warn("Unable to derive Salt Grains: #{e}")
107
116
  end
117
+ grains
118
+ end
119
+
120
+ private
121
+
122
+ def ensure_salt_autosign
123
+ remove_salt_autosign
124
+ create_salt_autosign
125
+ end
126
+
127
+ def remove_salt_minion
128
+ remove_salt_autosign
129
+ remove_salt_key
130
+ end
131
+
132
+ def remove_salt_key
133
+ Rails.logger.info("Remove salt key for host #{fqdn}")
134
+ api = ProxyAPI::Salt.new(:url => salt_proxy.url)
135
+ api.key_delete(name)
136
+ end
137
+
138
+ def remove_salt_autosign
139
+ key = self.salt_autosign_key
140
+ unless key.nil?
141
+ Rails.logger.info("Remove salt autosign key for host #{fqdn}")
142
+ begin
143
+ api = ProxyAPI::Salt.new(:url => salt_proxy.url)
144
+ api.autosign_remove_key(key)
145
+ rescue Foreman::Exception => e
146
+ Rails.logger.warn("Unable to remove salt autosign for #{fqdn}: #{e}")
147
+ end
148
+ end
149
+ end
150
+
151
+ def generate_provisioning_key
152
+ SecureRandom.hex(10)
108
153
  end
109
154
 
110
- def delete_salt_key
155
+ def create_salt_autosign
111
156
  begin
112
- key = ForemanSalt::SmartProxies::SaltKeys.find(salt_proxy, fqdn)
113
- key&.delete
157
+ Rails.logger.info("Create salt autosign key for host #{fqdn}")
158
+ api = ProxyAPI::Salt.new(:url => salt_proxy.url)
159
+ key = generate_provisioning_key
160
+ api.autosign_create_key(key)
161
+ update(:salt_autosign_key => key)
162
+ update(:salt_status => ForemanSalt::SaltStatus.minion_auth_waiting)
114
163
  rescue Foreman::Exception => e
115
- Rails.logger.warn("Unable to delete key for #{fqdn}: #{e}")
164
+ Rails.logger.warn("Unable to create salt autosign for #{fqdn}: #{e}")
116
165
  end
117
166
  end
118
167
  end
@@ -120,5 +169,5 @@ module ForemanSalt
120
169
  end
121
170
 
122
171
  class ::Host::Managed::Jail < Safemode::Jail
123
- allow :salt_environment
172
+ allow :salt_environment, :salt_master, :derive_salt_grains
124
173
  end
@@ -0,0 +1,12 @@
1
+ module ForemanSalt
2
+ # Define the class that holds different states a Salt host become
3
+ class SaltStatus
4
+ def self.minion_auth_waiting
5
+ 'Waiting for Salt Minion to authenticate'
6
+ end
7
+
8
+ def self.minion_auth_success
9
+ 'Salt Minion was authenticated successfully to Salt Master'
10
+ end
11
+ end
12
+ end
@@ -43,7 +43,7 @@ module ForemanSalt
43
43
 
44
44
  @host.save(:validate => false)
45
45
  @host.reload
46
- @host.refresh_statuses
46
+ @host.refresh_statuses([HostStatus.find_status_by_humanized_name("configuration")])
47
47
 
48
48
  logger.info("Imported report for #{@host} in #{(Time.zone.now - start_time).round(2)} seconds")
49
49
  end
data/config/routes.rb CHANGED
@@ -38,6 +38,7 @@ Rails.application.routes.draw do
38
38
  scope '(:apiv)', :defaults => { :apiv => 'v2' },
39
39
  :apiv => /v1|v2/, :constraints => ApiConstraints.new(:version => 2) do
40
40
  match '/jobs/upload' => 'foreman_salt/api/v2/jobs#upload', :via => :post
41
+ match '/salt_autosign_auth' => 'foreman_salt/api/v2/salt_autosign#auth', :via => :put
41
42
 
42
43
  constraints(:smart_proxy_id => /[\w\.-]+/, :name => /[\w\.-]+/, :record => /[^\/]+/) do
43
44
  match '/salt_keys/:smart_proxy_id' => 'foreman_salt/api/v2/salt_keys#index', :via => :get
@@ -0,0 +1,6 @@
1
+ class AddSaltAutosignToHost < ActiveRecord::Migration[4.2]
2
+ def change
3
+ add_column :hosts, :salt_autosign_key, :string, limit: 255, null: true
4
+ add_column :hosts, :salt_status, :string, limit: 255, null: true
5
+ end
6
+ end
@@ -20,7 +20,7 @@ if ForemanSalt.with_remote_execution?
20
20
  sync = !Rails.env.test? && Setting[:remote_execution_sync_templates]
21
21
  template = JobTemplate.import_raw!(File.read(template),
22
22
  :default => true,
23
- :locked => true,
23
+ :lock => true,
24
24
  :update => sync)
25
25
  template.organizations = organizations if template.present?
26
26
  template.locations = locations if template.present?
@@ -38,16 +38,14 @@ module ForemanSalt
38
38
 
39
39
  initializer 'foreman_salt.assets.precompile' do |app|
40
40
  app.config.assets.precompile += %w(foreman_salt/states.js)
41
- end
42
-
43
- initializer 'foreman_salt.assets.precompile' do |app|
44
41
  app.config.assets.precompile += %w[foreman_salt/Salt.png]
45
42
  end
46
43
 
47
44
  initializer 'foreman_salt.configure_assets', :group => :assets do
48
45
  SETTINGS[:foreman_salt] = {
49
46
  :assets => {
50
- :precompile => ['foreman_salt/states.js']
47
+ :precompile => ['foreman_salt/Salt.png',
48
+ 'foreman_salt/states.js']
51
49
  }
52
50
  }
53
51
  end
@@ -1,7 +1,4 @@
1
1
  begin
2
- ::Foreman::Plugin.fact_importer_registry.register(:foreman_salt, ForemanSalt::FactImporter)
3
- ::FactParser.register_fact_parser(:foreman_salt, ForemanSalt::FactParser)
4
-
5
2
  # Helper Extensions
6
3
  ::HostsHelper.send :include, ForemanSalt::HostsHelperExtensions
7
4
  ::SmartProxiesHelper.send :include, ForemanSalt::SmartProxiesHelperExtensions
@@ -1,3 +1,3 @@
1
1
  module ForemanSalt
2
- VERSION = '13.2.4'
2
+ VERSION = '14.0.0'
3
3
  end
@@ -3,6 +3,8 @@ require 'test_plugin_helper'
3
3
  class ::ForemanSalt::Api::V2::SaltAutosignControllerTest < ActionController::TestCase
4
4
  setup do
5
5
  @proxy = FactoryBot.create(:smart_proxy, :with_salt_feature)
6
+ @host = FactoryBot.create(:host, :managed)
7
+ @host.salt_proxy = @proxy
6
8
  ProxyAPI::Salt.any_instance.stubs(:autosign_list).returns((%w(foo bar baz)))
7
9
  end
8
10
 
@@ -19,13 +19,13 @@ module ForemanSalt
19
19
  visit smart_proxy_path(@proxy)
20
20
  assert page.has_link? "Salt Autosign"
21
21
  click_link "Salt Autosign"
22
- assert page.has_content?("Autosign entries for #{@proxy.hostname}"), 'Page title does not appear'
22
+ assert page.has_title?("Autosign entries for #{@proxy.hostname}"), 'Page title does not appear'
23
23
  end
24
24
 
25
25
  test 'index page' do
26
26
  visit smart_proxy_salt_autosign_index_path(:smart_proxy_id => @proxy.id)
27
27
  assert find_link('Keys').visible?, 'Keys is not visible'
28
- assert has_content?("Autosign entries for #{@proxy.hostname}"), 'Page title does not appear'
28
+ assert has_title?("Autosign entries for #{@proxy.hostname}"), 'Page title does not appear'
29
29
  assert has_content?('Displaying'), 'Pagination "Display ..." does not appear'
30
30
  end
31
31
 
@@ -22,13 +22,12 @@ module ForemanSalt
22
22
  visit smart_proxy_path(@proxy)
23
23
  assert page.has_link? "Salt Keys"
24
24
  click_link "Salt Keys"
25
- assert page.has_content?("Salt Keys on #{@proxy.hostname}"), 'Page title does not appear'
25
+ assert page.has_title?("Salt Keys on #{@proxy}"), 'Page title does not appear'
26
26
  end
27
27
 
28
28
  test 'index page' do
29
29
  visit smart_proxy_salt_keys_path(:smart_proxy_id => @proxy.id)
30
- assert find_link('Autosign').visible?, 'Autosign is not visible'
31
- assert has_content?("Salt Keys on #{@proxy.hostname}"), 'Page title does not appear'
30
+ assert has_title?("Salt Keys on #{@proxy}"), 'Page title does not appear'
32
31
  assert has_content?('Displaying'), 'Pagination "Display ..." does not appear'
33
32
  end
34
33
 
@@ -56,23 +56,67 @@ module ForemanSalt
56
56
  assert host.configuration?
57
57
  end
58
58
 
59
- context 'key handling' do
59
+ context 'autosign handling' do
60
60
  before do
61
- @host = FactoryBot.create(:host, :managed, :build => true)
61
+ @host = FactoryBot.create(:host, :managed)
62
62
  @host.salt_proxy = @proxy
63
- @key_stub = stub("key")
64
- ForemanSalt::SmartProxies::SaltKeys.expects(:find).at_least_once.with(@host.salt_proxy, @host.fqdn).returns(@key_stub)
63
+ stub_request(:post, "#{@proxy.url}/salt/autosign_key/asdfasdfasfasdf").
64
+ to_return(status: 200, body: "", headers: {})
65
65
  end
66
66
 
67
- test 'host key is accepted when host is built' do
68
- @key_stub.expects(:accept).at_least_once.returns(true)
69
- assert @host.built
70
- @host.run_callbacks(:commit) # callbacks don't run with Foreman's transactional fixtures
67
+ test 'host autosign is created when host is built' do
68
+ autosign_key = "asdfasdfasfasdf"
69
+ @host.expects(:generate_provisioning_key).returns(autosign_key)
70
+ @host.build = true
71
+ assert @host.save!
72
+ @host.clear_host_parameters_cache!
73
+ assert_equal autosign_key, @host.salt_autosign_key
74
+ end
75
+ end
76
+
77
+ context 'function derive_salt_grains' do
78
+ before do
79
+ @host = FactoryBot.create(:host, :managed)
80
+ @host.salt_proxy = @proxy
81
+ end
82
+
83
+ test 'host returns autosign when deriving salt grains' do
84
+ autosign_key = "asdfasdfasfasdf"
85
+ expected_hash = { @host.autosign_grain_name => autosign_key }
86
+ @host.salt_autosign_key = autosign_key
87
+ assert_equal expected_hash, @host.instance_eval { derive_salt_grains(:use_autosign => true) }
88
+ end
89
+
90
+ test 'host returns empty hash when deriving salt grains without any given' do
91
+ expected_hash = {}
92
+ assert_equal expected_hash, @host.instance_eval { derive_salt_grains(:use_autosign => true) }
93
+ end
94
+
95
+ test 'host returns empty hash when deriving salt grains without autosign' do
96
+ expected_hash = {}
97
+ assert_equal expected_hash, @host.instance_eval { derive_salt_grains(:use_autosign => false) }
98
+ end
99
+
100
+ test 'host returns host param grains when deriving salt grains' do
101
+ expected_hash = { "Some key": "Some value", "Another key": "An extraordinary value" }
102
+ @host.host_params[@host.host_params_grains_name] = expected_hash
103
+ assert_equal expected_hash, @host.instance_eval { derive_salt_grains(:use_autosign => false) }
104
+ end
105
+
106
+ test 'host returns only host param grains when deriving salt grains' do
107
+ expected_hash = { "Some key": "Some value", "Another key": "An extraordinary value" }
108
+ @host.host_params[@host.host_params_grains_name] = expected_hash
109
+ assert_equal expected_hash, @host.instance_eval { derive_salt_grains(:use_autosign => true) }
71
110
  end
72
111
 
73
- test 'host key is deleted when host is removed' do
74
- @key_stub.expects(:delete).at_least_once.returns(true)
75
- assert @host.destroy
112
+ test 'host returns host param grains plus autosign when deriving salt grains' do
113
+ autosign_key = "asdfasdfasfasdf"
114
+ host_param_grains = { "Some key": "Some value",
115
+ "Another key": "An extraordinary value" }
116
+ expected_hash = host_param_grains.merge(@host.autosign_grain_name => autosign_key)
117
+ @host.salt_autosign_key = autosign_key
118
+ @host.host_params[@host.host_params_grains_name] = host_param_grains
119
+ assert_equal expected_hash, @host.instance_eval { derive_salt_grains(:use_autosign => true) }
76
120
  end
77
121
  end
78
122
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_salt
3
3
  version: !ruby/object:Gem::Version
4
- version: 13.2.4
4
+ version: 14.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen Benjamin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-09 00:00:00.000000000 Z
11
+ date: 2021-08-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: deface
@@ -56,14 +56,14 @@ dependencies:
56
56
  name: rubocop
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: 0.71.0
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: 0.71.0
69
69
  description: Foreman Plug-in for Salt
@@ -110,21 +110,19 @@ files:
110
110
  - app/lib/proxy_api/salt.rb
111
111
  - app/models/foreman_salt/concerns/host_managed_extensions.rb
112
112
  - app/models/foreman_salt/concerns/hostgroup_extensions.rb
113
- - app/models/foreman_salt/fact_name.rb
114
113
  - app/models/foreman_salt/host_salt_module.rb
115
114
  - app/models/foreman_salt/hostgroup_salt_module.rb
116
115
  - app/models/foreman_salt/salt_environment.rb
117
116
  - app/models/foreman_salt/salt_module.rb
118
117
  - app/models/foreman_salt/salt_module_environment.rb
119
118
  - app/models/foreman_salt/salt_provider.rb
119
+ - app/models/foreman_salt/salt_status.rb
120
120
  - app/models/foreman_salt/salt_variable.rb
121
121
  - app/models/setting/salt.rb
122
122
  - app/overrides/salt_environment_host_selector.rb
123
123
  - app/overrides/salt_environment_hostgroup_selector.rb
124
124
  - app/overrides/salt_modules_selector.rb
125
125
  - app/overrides/salt_proxy_selector.rb
126
- - app/services/foreman_salt/fact_importer.rb
127
- - app/services/foreman_salt/fact_parser.rb
128
126
  - app/services/foreman_salt/report_importer.rb
129
127
  - app/services/foreman_salt/smart_proxies/salt_keys.rb
130
128
  - app/views/foreman_salt/api/v2/salt_autosign/base.json.rabl
@@ -190,6 +188,7 @@ files:
190
188
  - db/migrate/20150509101505_add_primary_keys.rb
191
189
  - db/migrate/20161103104146_add_index_to_join_tables.rb
192
190
  - db/migrate/20190515112233_add_salt_module_id_to_lookup_keys.rb
191
+ - db/migrate/20210312150333_add_salt_autosign_to_host.rb
193
192
  - db/seeds.d/75-salt_seeds.rb
194
193
  - db/seeds.d/76-job_templates.rb
195
194
  - lib/foreman_salt.rb
@@ -258,15 +257,12 @@ files:
258
257
  - test/integration/salt_module_test.rb
259
258
  - test/integration/salt_variable_test.rb
260
259
  - test/test_plugin_helper.rb
261
- - test/unit/grains_centos.json
262
260
  - test/unit/grains_importer_test.rb
263
261
  - test/unit/highstate.json
264
262
  - test/unit/highstate_pchanges.json
265
263
  - test/unit/host_extensions_test.rb
266
264
  - test/unit/hostgroup_extensions_test.rb
267
265
  - test/unit/report_importer_test.rb
268
- - test/unit/salt_fact_importer_test.rb
269
- - test/unit/salt_fact_parser_test.rb
270
266
  - test/unit/salt_keys_test.rb
271
267
  - test/unit/salt_modules_test.rb
272
268
  - test/unit/salt_variables_test.rb
@@ -306,10 +302,7 @@ test_files:
306
302
  - test/unit/highstate_pchanges.json
307
303
  - test/unit/hostgroup_extensions_test.rb
308
304
  - test/unit/highstate.json
309
- - test/unit/salt_fact_parser_test.rb
310
305
  - test/unit/salt_modules_test.rb
311
- - test/unit/grains_centos.json
312
- - test/unit/salt_fact_importer_test.rb
313
306
  - test/unit/report_importer_test.rb
314
307
  - test/unit/salt_variables_test.rb
315
308
  - test/unit/salt_keys_test.rb
@@ -1,14 +0,0 @@
1
- module ForemanSalt
2
- # Define the class that fact names that come from Salt should have
3
- # It allows us to filter facts by origin, and also to display the origin
4
- # in the fact values table (/fact_values)
5
- class FactName < ::FactName
6
- def origin
7
- 'Salt'
8
- end
9
-
10
- def icon_path
11
- 'foreman_salt/Salt'
12
- end
13
- end
14
- end
@@ -1,15 +0,0 @@
1
- module ForemanSalt
2
- class FactImporter < ::StructuredFactImporter
3
- def fact_name_class
4
- ForemanSalt::FactName
5
- end
6
-
7
- def self.support_background
8
- true
9
- end
10
-
11
- def self.authorized_smart_proxy_features
12
- 'Salt'
13
- end
14
- end
15
- end
@@ -1,114 +0,0 @@
1
- module ForemanSalt
2
- class FactParser < ::FactParser
3
- attr_reader :facts
4
-
5
- def operatingsystem
6
- os = Operatingsystem.where(os_hash).first_or_initialize
7
- if os.new_record?
8
- os.deduce_family
9
- os.release_name = facts[:lsb_distrib_codename]
10
- os.save
11
- end
12
- os if os.persisted?
13
- end
14
-
15
- def architecture
16
- name = facts[:osarch]
17
- name = 'x86_64' if name == 'amd64'
18
- Architecture.where(:name => name).first_or_create unless name.blank?
19
- end
20
-
21
- def environment
22
- # Don't touch the Puppet environment field
23
- end
24
-
25
- def model
26
- name = facts[:productname]
27
- Model.where(:name => name.strip).first_or_create unless name.blank?
28
- end
29
-
30
- def domain
31
- name = facts[:domain]
32
- Domain.where(:name => name).first_or_create unless name.blank?
33
- end
34
-
35
- def ip
36
- ip = facts.find { |fact, value| fact =~ /^fqdn_ip4/ && value && value != '127.0.0.1' }
37
- ip[1] if ip
38
- end
39
-
40
- def primary_interface
41
- interface = interfaces.find { |_, value| value[:ipaddress] == ip }
42
- interface[0] if interface
43
- end
44
-
45
- def mac
46
- interface = interfaces.find { |_, value| value[:ipaddress] == ip }
47
- interface[1][:macaddress] if interface
48
- end
49
-
50
- def ipmi_interface
51
- nil
52
- end
53
-
54
- def interfaces
55
- interfaces = {}
56
-
57
- facts.each do |fact, value|
58
- next unless value && fact.to_s =~ /^ip_interfaces/
59
-
60
- (_, interface_name) = fact.split(FactName::SEPARATOR)
61
-
62
- next if (IPAddr.new('fe80::/10').include?(value) rescue false)
63
-
64
- if !interface_name.blank? && interface_name != 'lo'
65
- interface = interfaces.fetch(interface_name, {})
66
- interface[:macaddress] = macs[interface_name]
67
- if Net::Validations.validate_ip6(value)
68
- interface[:ipaddress6] = value unless interface.include?(:ipaddress6)
69
- else
70
- interface[:ipaddress] = value unless interface.include?(:ipaddress)
71
- end
72
- interfaces[interface_name] = interface
73
- end
74
- end
75
-
76
- interfaces.each do |name, interface|
77
- set_additional_attributes(interface, name)
78
- end
79
-
80
- interfaces
81
- end
82
-
83
- def support_interfaces_parsing?
84
- true
85
- end
86
-
87
- private
88
-
89
- def os_hash
90
- name = facts[:os]
91
- (_, major, minor, sub) = /(\d+)\.?(\d+)?\.?(\d+)?/.match(facts[:osrelease]).to_a
92
- if name == 'CentOS'
93
- if sub
94
- minor += '.' + sub
95
- end
96
- end
97
- { :name => name, :major => major, :minor => minor }
98
- end
99
-
100
- def macs
101
- unless @macs
102
- @macs = {}
103
- facts.each do |fact, value|
104
- next unless value && fact.to_s =~ /^hwaddr_interfaces/
105
-
106
- data = fact.split(FactName::SEPARATOR)
107
- interface = data[1]
108
- macs[interface] = value
109
- end
110
- end
111
- @macs
112
- end
113
- end
114
- end
@@ -1,113 +0,0 @@
1
- {
2
- "facts": {
3
- "kernelrelease": "2.6.32-431.23.3.el6.x86_64",
4
- "ipv6::0": "::1",
5
- "ipv6::1": "fe80::5054:ff:fe35:302a",
6
- "saltversioninfo": [
7
- 2014,
8
- 1,
9
- 7
10
- ],
11
- "operatingsystem": "CentOS",
12
- "lsb_distrib_id": "CentOS",
13
- "pythonversion::2": 6,
14
- "pythonversion::3": "final",
15
- "pythonversion::0": 2,
16
- "pythonversion::1": 6,
17
- "cpu_model": "QEMU Virtual CPU version (cpu64-rhel6)",
18
- "pythonversion::4": 0,
19
- "oscodename": "Final",
20
- "num_gpus": 1,
21
- "productname": "KVM",
22
- "osarch": "x86_64",
23
- "biosversion": "0.5.1",
24
- "kernel": "Linux",
25
- "domain": "example.com",
26
- "pythonpath::4": "/usr/lib64/python2.6/lib-tk",
27
- "pythonpath::5": "/usr/lib64/python2.6/lib-old",
28
- "pythonpath::6": "/usr/lib64/python2.6/lib-dynload",
29
- "pythonpath::7": "/usr/lib64/python2.6/site-packages",
30
- "pythonpath::0": "/usr/bin",
31
- "mem_total": 742,
32
- "pythonpath::2": "/usr/lib64/python2.6",
33
- "pythonpath::3": "/usr/lib64/python2.6/plat-linux2",
34
- "pythonpath::8": "/usr/lib/python2.6/site-packages",
35
- "cpu_flags::25": "pni",
36
- "cpu_flags::24": "unfair_spinlock",
37
- "cpu_flags::27": "hypervisor",
38
- "cpu_flags::26": "cx16",
39
- "cpu_flags::21": "nx",
40
- "cpu_flags::20": "syscall",
41
- "cpu_flags::23": "up",
42
- "cpu_flags::22": "lm",
43
- "cpu_flags::28": "lahf_lm",
44
- "defaultlanguage": "en_US",
45
- "osfullname": "CentOS",
46
- "localhost": "saltclient01.example.com",
47
- "lsb_distrib_release": "6.5",
48
- "saltpath": "/usr/lib/python2.6/site-packages/salt",
49
- "biosreleasedate": "01/01/2007",
50
- "host": "saltclient01",
51
- "defaultencoding": "UTF8",
52
- "path": "/sbin:/usr/sbin:/bin:/usr/bin",
53
- "ip_interfaces::eth0::0": "10.7.13.141",
54
- "ip_interfaces::eth0::1": "10.7.23.141",
55
- "manufacturer": "Red Hat",
56
- "fqdn": "saltclient01.example.com",
57
- "os": "CentOS",
58
- "osfinger": "CentOS-6",
59
- "ps": "ps -efH",
60
- "server_id": 654860635,
61
- "zmqversion": "3.2.4",
62
- "osmajorrelease::1": "5",
63
- "osmajorrelease::0": "6",
64
- "ip_interfaces::lo::0": "127.0.0.1",
65
- "master": "saltstack.example.com",
66
- "shell": "/bin/sh",
67
- "saltversion": "2014.1.7",
68
- "hwaddr_interfaces::lo": "00:00:00:00:00:00",
69
- "_timestamp": "2014-08-28 10:02:16 ",
70
- "cpu_flags::18": "sse",
71
- "cpu_flags::19": "sse2",
72
- "cpu_flags::14": "pse36",
73
- "cpu_flags::15": "clflush",
74
- "cpu_flags::16": "mmx",
75
- "cpu_flags::17": "fxsr",
76
- "cpu_flags::10": "mtrr",
77
- "cpu_flags::11": "pge",
78
- "cpu_flags::12": "mca",
79
- "cpu_flags::13": "cmov",
80
- "cpuarch": "x86_64",
81
- "pythonpath::1": "/usr/lib64/python26.zip",
82
- "cpu_flags::6": "mce",
83
- "cpu_flags::7": "cx8",
84
- "cpu_flags::4": "msr",
85
- "cpu_flags::5": "pae",
86
- "cpu_flags::2": "pse",
87
- "cpu_flags::3": "tsc",
88
- "cpu_flags::0": "fpu",
89
- "cpu_flags::1": "de",
90
- "serialnumber": "Not Specified",
91
- "hwaddr_interfaces::eth0": "52:54:00:35:30:2a",
92
- "cpu_flags::8": "apic",
93
- "cpu_flags::9": "sep",
94
- "gpus::0::model": "GD 5446",
95
- "id": "saltclient01.example.com",
96
- "osrelease": "6.5",
97
- "num_cpus": 1,
98
- "virtual": "kvm",
99
- "ipv4::0": "10.7.23.141",
100
- "ipv4::1": "10.7.13.141",
101
- "ipv4::2": "127.0.0.1",
102
- "_type": "foreman_salt",
103
- "nodename": "saltclient01.example.com",
104
- "os_family": "RedHat",
105
- "operatingsystemrelease": "6.5",
106
- "gpus::0::vendor": "unknown",
107
- "lsb_distrib_codename": "Final",
108
- "fqdn_ip4::0": "10.7.13.141",
109
- "ip_interfaces::eth1::0": "1.2.3.4",
110
- "hwaddr_interfaces::eth1": "DE:AD:BE:EF:07:13"
111
- },
112
- "name": "saltclient01.example.com"
113
- }
@@ -1,24 +0,0 @@
1
- require 'test_plugin_helper'
2
-
3
- module ForemanSalt
4
- class SaltFactImpoterTest < ActiveSupport::TestCase
5
- def setup
6
- @host = FactoryBot.build(:host)
7
- end
8
-
9
- test 'should have fact set' do
10
- importer = FactImporter.new(@host, 'a' => 'b')
11
- assert_equal({ 'a' => 'b' }, importer.send(:facts))
12
- end
13
-
14
- test 'should have Salt as origin' do
15
- importer = FactImporter.new(@host, 'a' => 'b')
16
- importer.stubs(:ensure_no_active_transaction).returns(true)
17
- importer.import!
18
- imported_fact = FactName.find_by_name('a')
19
- assert_equal 'a', imported_fact.name
20
- assert_equal 'Salt', imported_fact.origin
21
- assert_equal 'foreman_salt/Salt', imported_fact.icon_path
22
- end
23
- end
24
- end
@@ -1,44 +0,0 @@
1
- require 'test_plugin_helper'
2
-
3
- module ForemanSalt
4
- class SaltFactsParserTest < ActiveSupport::TestCase
5
- def setup
6
- grains = JSON.parse(File.read(File.join(Engine.root, 'test', 'unit', 'grains_centos.json')))
7
- @facts_parser = FactParser.new grains["facts"]
8
- User.current = users :admin
9
- end
10
-
11
- test "should return list of interfaces" do
12
- assert @facts_parser.interfaces.present?
13
- assert_not_nil @facts_parser.suggested_primary_interface(FactoryBot.build(:host))
14
- assert @facts_parser.interfaces.key?(@facts_parser.suggested_primary_interface(FactoryBot.build(:host)).first)
15
- end
16
-
17
- test "should set operatingsystem correctly" do
18
- os = @facts_parser.operatingsystem
19
- assert os.present?
20
- assert_equal 'CentOS', os.name
21
- assert_equal '6', os.major
22
- assert_equal '5', os.minor
23
- assert_equal 'CentOS 6.5', os.title
24
- end
25
-
26
- test "should set domain correctly" do
27
- domain = @facts_parser.domain
28
- assert domain.present?
29
- assert_equal 'example.com', domain.name
30
- end
31
-
32
- test "should set ip correctly" do
33
- assert_equal '10.7.13.141', @facts_parser.ip
34
- end
35
-
36
- test "should set primary_interface correctly" do
37
- assert_equal 'eth0', @facts_parser.primary_interface
38
- end
39
-
40
- test "should set mac correctly" do
41
- assert_equal '52:54:00:35:30:2a', @facts_parser.mac
42
- end
43
- end
44
- end