foreman_discovery 3.0.0 → 4.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.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/app/controllers/api/v2/discovered_hosts_controller.rb +31 -11
- data/app/controllers/api/v2/discovery_rules_controller.rb +8 -16
- data/app/controllers/concerns/foreman/controller/discovered_extensions.rb +47 -2
- data/app/controllers/discovered_hosts_controller.rb +30 -55
- data/app/controllers/discovery_rules_controller.rb +2 -4
- data/app/helpers/discovered_hosts_helper.rb +27 -5
- data/app/lib/facter_utils.rb +18 -0
- data/app/lib/puppet_fact_parser_extensions.rb +18 -32
- data/app/models/discovery_rule.rb +33 -2
- data/app/models/host/discovered.rb +47 -61
- data/app/models/host/managed_extensions.rb +12 -3
- data/app/models/setting/discovered.rb +18 -6
- data/app/services/foreman_discovery/host_converter.rb +22 -0
- data/app/views/api/v2/discovered_hosts/main.json.rabl +1 -1
- data/app/views/api/v2/discovery_rules/main.json.rabl +6 -1
- data/app/views/api/v2/discovery_rules/show.json.rabl +4 -0
- data/app/views/dashboard/_discovery_widget.html.erb +6 -4
- data/app/views/dashboard/_discovery_widget_host.html.erb +4 -0
- data/app/views/dashboard/_discovery_widget_host_list.html.erb +2 -3
- data/app/views/discovered_hosts/_discovered_host.html.erb +3 -5
- data/app/views/discovered_hosts/_discovered_hosts_list.html.erb +7 -7
- data/app/views/discovered_hosts/index.html.erb +1 -0
- data/app/views/discovery_rules/_form.html.erb +51 -32
- data/config/routes.rb +4 -4
- data/db/migrate/20150310153859_remove_discovery_attribute_sets_from_managed_hosts.rb +8 -0
- data/db/migrate/20150331132115_remove_old_permissions.rb +16 -0
- data/db/migrate/20150505111345_remove_leftover_tokens.rb +13 -0
- data/db/migrate/20150512150432_remove_old_discovery_reader_permissions.rb +10 -0
- data/db/migrate/20150714144500_review_discovery_permissions.rb +17 -0
- data/lib/foreman_discovery/engine.rb +46 -16
- data/lib/foreman_discovery/version.rb +1 -1
- data/locale/de/LC_MESSAGES/foreman_discovery.mo +0 -0
- data/locale/de/foreman_discovery.po +74 -72
- data/locale/de/foreman_discovery.pox +40 -0
- data/locale/en_GB/LC_MESSAGES/foreman_discovery.mo +0 -0
- data/locale/en_GB/foreman_discovery.po +90 -88
- data/locale/en_GB/foreman_discovery.pox +0 -0
- data/locale/es/LC_MESSAGES/foreman_discovery.mo +0 -0
- data/locale/es/foreman_discovery.po +3 -3
- data/locale/es/foreman_discovery.pox +41 -0
- data/locale/fr/LC_MESSAGES/foreman_discovery.mo +0 -0
- data/locale/fr/foreman_discovery.po +3 -3
- data/locale/fr/foreman_discovery.pox +69 -0
- data/locale/gl/LC_MESSAGES/foreman_discovery.mo +0 -0
- data/locale/gl/foreman_discovery.po +3 -3
- data/locale/gl/foreman_discovery.pox +21 -0
- data/locale/it/LC_MESSAGES/foreman_discovery.mo +0 -0
- data/locale/it/foreman_discovery.po +3 -3
- data/locale/it/foreman_discovery.pox +0 -0
- data/locale/ja/LC_MESSAGES/foreman_discovery.mo +0 -0
- data/locale/ja/foreman_discovery.po +67 -66
- data/locale/ja/foreman_discovery.pox +29 -0
- data/locale/ko/LC_MESSAGES/foreman_discovery.mo +0 -0
- data/locale/ko/foreman_discovery.po +3 -3
- data/locale/ko/foreman_discovery.pox +189 -0
- data/locale/messages.mo +0 -0
- data/locale/pt_BR/LC_MESSAGES/foreman_discovery.mo +0 -0
- data/locale/pt_BR/foreman_discovery.po +7 -7
- data/locale/pt_BR/foreman_discovery.pox +0 -0
- data/locale/ru/LC_MESSAGES/foreman_discovery.mo +0 -0
- data/locale/ru/foreman_discovery.po +98 -96
- data/locale/ru/foreman_discovery.pox +0 -0
- data/locale/sv_SE/LC_MESSAGES/foreman_discovery.mo +0 -0
- data/locale/sv_SE/foreman_discovery.po +3 -3
- data/locale/zh_CN/LC_MESSAGES/foreman_discovery.mo +0 -0
- data/locale/zh_CN/foreman_discovery.po +3 -3
- data/locale/zh_CN/foreman_discovery.pox +33 -0
- data/locale/zh_TW/LC_MESSAGES/foreman_discovery.mo +0 -0
- data/locale/zh_TW/foreman_discovery.po +3 -3
- data/locale/zh_TW/foreman_discovery.pox +23 -0
- data/test/functional/api/v2/discovered_hosts_controller_test.rb +45 -7
- data/test/functional/discovered_hosts_controller_test.rb +52 -11
- data/test/unit/discovered_extensions_test.rb +40 -17
- data/test/unit/discovery_rule_test.rb +59 -0
- data/test/unit/host_discovered_test.rb +69 -6
- data/test/unit/puppet_fact_parser_extensions_test.rb +55 -40
- metadata +103 -81
- data/app/services/host_converter.rb +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fa7dff0a0f4756c41176a4e6b6be41f2815375cc
|
4
|
+
data.tar.gz: 7f83b17405564440f5939d66e15527363d07ad27
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a588c3c7c19787aa5fa1cb36557e786889f294c0005bd4f1cb12dd614be77b88b2a8dbf3f46483ecf5129ad4cabc8f2a9a8cfd025eda077c9f160e0dc10debd0
|
7
|
+
data.tar.gz: 0e0e298f9a57c4a310e474f7dd3c6dd38b226d407a55a4a02a8e5c687b06c7149fd5c65da5cd951a61aa01e79833b7dd06539ad522a7e15f3d010aa268e1349d
|
data/README.md
CHANGED
@@ -4,7 +4,7 @@ This plugin enables MaaS hardware discovery in Foreman.
|
|
4
4
|
|
5
5
|
# Documentation
|
6
6
|
|
7
|
-
The main documentation can be found in [Foreman Discovery
|
7
|
+
The main documentation can be found in the [Foreman Discovery manual] (http://theforeman.org/plugins/foreman_discovery/).
|
8
8
|
|
9
9
|
## Latest code
|
10
10
|
|
@@ -3,7 +3,7 @@ module Api
|
|
3
3
|
class DiscoveredHostsController < ::Api::V2::BaseController
|
4
4
|
include Foreman::Controller::DiscoveredExtensions
|
5
5
|
|
6
|
-
before_filter :find_resource, :except => %w{index create facts auto_provision_all}
|
6
|
+
before_filter :find_resource, :except => %w{index create facts auto_provision_all reboot_all}
|
7
7
|
skip_before_filter :authorize, :only => :facts
|
8
8
|
|
9
9
|
resource_description do
|
@@ -36,7 +36,7 @@ module Api
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
api :POST, "/discovered_hosts/", N_("Create a discovered host")
|
39
|
+
api :POST, "/discovered_hosts/", N_("Create a discovered host for testing (use /facts to create new hosts)")
|
40
40
|
param_group :discovered_host, :as => :create
|
41
41
|
|
42
42
|
def create
|
@@ -92,7 +92,7 @@ module Api
|
|
92
92
|
end
|
93
93
|
|
94
94
|
api :POST, "/discovered_hosts/facts", N_("Upload facts for a host, creating the host if required")
|
95
|
-
param :facts, Hash, :required => true, :desc => N_("hash containing facts for the host")
|
95
|
+
param :facts, Hash, :required => true, :desc => N_("hash containing facts for the host with minimum set of facts: discovery_bootif, macaddress_eth0, ipaddress, ipaddress_eth0, interfaces: eth0 (example in case primary interface is named eth0)")
|
96
96
|
|
97
97
|
def facts
|
98
98
|
state = true
|
@@ -100,7 +100,7 @@ module Api
|
|
100
100
|
@discovered_host, state = Host::Discovered.import_host_and_facts(params[:facts])
|
101
101
|
end
|
102
102
|
if Setting['discovery_auto']
|
103
|
-
|
103
|
+
Host.transaction do
|
104
104
|
if state && rule = find_discovery_rule(@discovered_host)
|
105
105
|
state = perform_auto_provision(@discovered_host, rule)
|
106
106
|
else
|
@@ -109,7 +109,9 @@ module Api
|
|
109
109
|
end
|
110
110
|
end
|
111
111
|
process_response state
|
112
|
-
rescue
|
112
|
+
rescue Exception => e
|
113
|
+
logger.warn "Host discovery failed, facts: #{params[:facts]}"
|
114
|
+
logger.debug e.message + "\n" + e.backtrace.join("\n")
|
113
115
|
render :json => {'message'=>e.to_s}, :status => :unprocessable_entity
|
114
116
|
end
|
115
117
|
|
@@ -117,12 +119,15 @@ module Api
|
|
117
119
|
param :id, :identifier, :required => true
|
118
120
|
|
119
121
|
def auto_provision
|
120
|
-
|
122
|
+
Host.transaction do
|
121
123
|
if rule = find_discovery_rule(@discovered_host)
|
122
124
|
msg = _("Host %{host} was provisioned with rule %{rule}") % {:host => @discovered_host.name, :rule => rule.name}
|
123
125
|
process_response perform_auto_provision(@discovered_host, rule), msg
|
124
126
|
else
|
125
|
-
|
127
|
+
render_error :custom_error, :status => :not_found,
|
128
|
+
:locals => {
|
129
|
+
:message => _("No rule found for host %s") % @discovered_host.name
|
130
|
+
}
|
126
131
|
end
|
127
132
|
end
|
128
133
|
rescue ::Foreman::Exception => e
|
@@ -185,6 +190,21 @@ module Api
|
|
185
190
|
render :json => {'message'=>e.to_s}
|
186
191
|
end
|
187
192
|
|
193
|
+
api :PUT, "/discovered_hosts/reboot_all", N_("Rebooting all discovered hosts")
|
194
|
+
|
195
|
+
def reboot_all
|
196
|
+
error_message = perform_reboot_all
|
197
|
+
if error_message
|
198
|
+
render_error :custom_error,
|
199
|
+
:status => :unprocessable_entity,
|
200
|
+
:locals => {
|
201
|
+
:message => error_message
|
202
|
+
}
|
203
|
+
else
|
204
|
+
process_success _("Discovered hosts are rebooting now")
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
188
208
|
private
|
189
209
|
|
190
210
|
def resource_class
|
@@ -197,12 +217,12 @@ module Api
|
|
197
217
|
|
198
218
|
def action_permission
|
199
219
|
case params[:action]
|
200
|
-
when 'auto_provision'
|
220
|
+
when 'auto_provision', 'auto_provision_all'
|
201
221
|
:auto_provision
|
202
|
-
when '
|
203
|
-
:auto_provision_all
|
204
|
-
when 'refresh_facts', 'reboot'
|
222
|
+
when 'refresh_facts', 'reboot', 'reboot_all'
|
205
223
|
:edit
|
224
|
+
when 'facts', 'create'
|
225
|
+
:submit
|
206
226
|
else
|
207
227
|
super
|
208
228
|
end
|
@@ -28,13 +28,13 @@ module Api
|
|
28
28
|
|
29
29
|
def_param_group :discovery_rule do
|
30
30
|
param :discovery_rule, Hash, :action_aware => true do
|
31
|
-
param :name, String, :required => true
|
32
|
-
param :search, String, :required => true
|
33
|
-
param :hostgroup_id, Integer, :required => true
|
34
|
-
param :hostname, String, :
|
35
|
-
param :max_count, Integer
|
36
|
-
param :priority, Integer
|
37
|
-
param :enabled, :bool
|
31
|
+
param :name, String, :required => true, :desc => N_("represents rule name shown to the users")
|
32
|
+
param :search, String, :required => true, :desc => N_("query to match discovered hosts for the particular rule")
|
33
|
+
param :hostgroup_id, Integer, :required => true, :desc => N_("the hostgroup that is used to auto provision a host")
|
34
|
+
param :hostname, String, :desc => N_("defines a pattern to assign human-readable hostnames to the matching hosts")
|
35
|
+
param :max_count, Integer, :desc => N_("enables to limit maximum amount of provisioned hosts per rule")
|
36
|
+
param :priority, Integer, :desc => N_("puts the rules in order, low numbers go first. Must be greater then zero")
|
37
|
+
param :enabled, :bool, :desc => N_("flag is used for temporary shutdown of rules")
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
@@ -48,15 +48,7 @@ module Api
|
|
48
48
|
|
49
49
|
api :PUT, "/discovery_rules/:id/", N_("Update a rule")
|
50
50
|
param :id, :identifier, :required => true
|
51
|
-
|
52
|
-
param :name, String, :required => true
|
53
|
-
param :search, String, :required => true
|
54
|
-
param :hostgroup_id, Integer, :required => true
|
55
|
-
param :hostname, String, :required => true
|
56
|
-
param :max_count, Integer
|
57
|
-
param :priority, Integer
|
58
|
-
param :enabled, :bool
|
59
|
-
end
|
51
|
+
param_group :discovery_rule, :as => :update
|
60
52
|
|
61
53
|
def update
|
62
54
|
process_response @discovery_rule.update_attributes(params[:discovery_rule])
|
@@ -3,6 +3,7 @@ module Foreman::Controller::DiscoveredExtensions
|
|
3
3
|
|
4
4
|
# return auto provision rule or false when not present
|
5
5
|
def find_discovery_rule host
|
6
|
+
raise(::Foreman::Exception.new(N_("Unable to find a discovery rule, no host provided (check permissions)"))) if host.nil?
|
6
7
|
Rails.logger.debug "Finding auto discovery rule for host #{host.name} (#{host.id})"
|
7
8
|
# for each discovery rule ordered by priority
|
8
9
|
DiscoveryRule.where(:enabled => true).order(:priority).each do |rule|
|
@@ -14,8 +15,12 @@ module Foreman::Controller::DiscoveredExtensions
|
|
14
15
|
# try to match the search
|
15
16
|
begin
|
16
17
|
if Host::Discovered.where(:id => host.id).search_for(rule.search).size > 0
|
17
|
-
|
18
|
-
|
18
|
+
if validate_rule_by_taxonomy(rule, host)
|
19
|
+
Rails.logger.info "Match found for host #{host.name} (#{host.id}) rule #{rule.name} (#{rule.id})"
|
20
|
+
return rule
|
21
|
+
else
|
22
|
+
Rails.logger.warn "Rule #{rule.name} (#{rule.id}) can not be applied due to a difference in organization/location from host #{host.name} (#{host.id})"
|
23
|
+
end
|
19
24
|
end
|
20
25
|
rescue ScopedSearch::QueryNotSupported => e
|
21
26
|
Rails.logger.warn "Invalid query for rule #{rule.name} (#{rule.id}): #{e.message}"
|
@@ -27,6 +32,16 @@ module Foreman::Controller::DiscoveredExtensions
|
|
27
32
|
return false
|
28
33
|
end
|
29
34
|
|
35
|
+
def validate_rule_by_taxonomy rule, host
|
36
|
+
if SETTINGS[:organizations_enabled]
|
37
|
+
return false unless rule.organizations.include?(host.organization)
|
38
|
+
end
|
39
|
+
if SETTINGS[:locations_enabled]
|
40
|
+
return false unless rule.locations.include?(host.location)
|
41
|
+
end
|
42
|
+
true
|
43
|
+
end
|
44
|
+
|
30
45
|
# trigger the provisioning
|
31
46
|
def perform_auto_provision original_host, rule
|
32
47
|
Host.transaction do
|
@@ -44,5 +59,35 @@ module Foreman::Controller::DiscoveredExtensions
|
|
44
59
|
end
|
45
60
|
end
|
46
61
|
|
62
|
+
def perform_reboot_all hosts = Host::Discovered.all
|
63
|
+
result = true
|
64
|
+
error_message = _("Errors during reboot: %s")
|
65
|
+
overall_errors = ""
|
66
|
+
|
67
|
+
if hosts.count > 0
|
68
|
+
Host.transaction do
|
69
|
+
hosts.each do |discovered_host|
|
70
|
+
begin
|
71
|
+
unless discovered_host.reboot
|
72
|
+
error = "#{discovered_host.name}: failed to reboot "
|
73
|
+
overall_errors << error
|
74
|
+
logger.error error
|
75
|
+
end
|
76
|
+
rescue Exception => e
|
77
|
+
error = "#{discovered_host.name}: #{e.to_s} "
|
78
|
+
overall_errors << error
|
79
|
+
logger.error error
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
else
|
84
|
+
error_message = _("No discovered hosts to reboot")
|
85
|
+
result = false
|
86
|
+
end
|
87
|
+
|
88
|
+
if overall_errors.present? || !result
|
89
|
+
error_message % overall_errors.strip
|
90
|
+
end
|
91
|
+
end
|
47
92
|
|
48
93
|
end
|
@@ -4,45 +4,23 @@ class DiscoveredHostsController < ::ApplicationController
|
|
4
4
|
include Foreman::Controller::DiscoveredExtensions
|
5
5
|
unloadable
|
6
6
|
|
7
|
-
# Avoid auth for discovered host creation
|
8
|
-
skip_before_filter :require_login, :require_ssl, :authorize, :verify_authenticity_token, :set_taxonomy, :session_expiry, :update_activity_time, :only => :create
|
9
|
-
|
10
7
|
before_filter :find_by_name, :only => %w[show edit update destroy refresh_facts convert reboot auto_provision]
|
11
8
|
before_filter :find_multiple, :only => [:multiple_destroy, :submit_multiple_destroy]
|
12
9
|
before_filter :taxonomy_scope, :only => [:edit]
|
13
10
|
|
11
|
+
around_filter :skip_bullet, :only => [:edit]
|
12
|
+
|
14
13
|
helper :hosts
|
15
14
|
|
16
15
|
layout 'layouts/application'
|
17
16
|
|
18
17
|
def index
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
# Importing yaml is restricted to puppetmasters, so instead we take the ip
|
29
|
-
# as a parameter and use refresh_facts to get the rest
|
30
|
-
def create
|
31
|
-
Taxonomy.no_taxonomy_scope do
|
32
|
-
host, imported = Host::Discovered.new(:ip => get_ip_from_env).refresh_facts
|
33
|
-
respond_to do |format|
|
34
|
-
format.yml {
|
35
|
-
if imported
|
36
|
-
render :text => _("Imported discovered host"), :status => 200 and return
|
37
|
-
else
|
38
|
-
render :text => _("Failed to import facts for discovered host"), :status => 400
|
39
|
-
end
|
40
|
-
}
|
41
|
-
end
|
42
|
-
end
|
43
|
-
rescue Exception => e
|
44
|
-
logger.warn "Failed to import facts for discovered host: #{e}"
|
45
|
-
render :text => _("Failed to import facts for discovered host: %s") % (e), :status => 400
|
18
|
+
@hosts = resource_base.search_for(params[:search], :order => params[:order]).includes([
|
19
|
+
:location,
|
20
|
+
:organization,
|
21
|
+
:model,
|
22
|
+
:discovery_attribute_set
|
23
|
+
], {:interfaces => :subnet}).paginate(:page => params[:page])
|
46
24
|
end
|
47
25
|
|
48
26
|
def show
|
@@ -60,14 +38,14 @@ class DiscoveredHostsController < ::ApplicationController
|
|
60
38
|
|
61
39
|
def edit
|
62
40
|
Host.transaction do
|
63
|
-
@host = ::ForemanDiscovery::HostConverter.to_managed(@host) unless @host.nil?
|
41
|
+
@host = ::ForemanDiscovery::HostConverter.to_managed(@host, true, false) unless @host.nil?
|
64
42
|
render :template => 'hosts/edit'
|
65
43
|
end
|
66
44
|
end
|
67
45
|
|
68
46
|
def update
|
69
47
|
Host.transaction do
|
70
|
-
@host = ::ForemanDiscovery::HostConverter.to_managed(@host
|
48
|
+
@host = ::ForemanDiscovery::HostConverter.to_managed(@host)
|
71
49
|
forward_url_options
|
72
50
|
Taxonomy.no_taxonomy_scope do
|
73
51
|
if @host.update_attributes(params[:host])
|
@@ -105,6 +83,16 @@ class DiscoveredHostsController < ::ApplicationController
|
|
105
83
|
:redirect => :back
|
106
84
|
end
|
107
85
|
|
86
|
+
def reboot_all
|
87
|
+
error_message = perform_reboot_all
|
88
|
+
|
89
|
+
if error_message
|
90
|
+
process_error :error_msg => error_message, :redirect => :back
|
91
|
+
else
|
92
|
+
process_success :success_msg => _("Discovered hosts are rebooting now"), :success_redirect => :back
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
108
96
|
def multiple_destroy
|
109
97
|
end
|
110
98
|
|
@@ -137,7 +125,7 @@ class DiscoveredHostsController < ::ApplicationController
|
|
137
125
|
end
|
138
126
|
|
139
127
|
def auto_provision
|
140
|
-
|
128
|
+
Host.transaction do
|
141
129
|
if rule = find_discovery_rule(@host)
|
142
130
|
if perform_auto_provision(@host, rule)
|
143
131
|
process_success :success_msg => _("Host %{host} was provisioned with rule %{rule}") % {:host => @host.name, :rule => rule.name}, :success_redirect => discovered_hosts_path
|
@@ -214,18 +202,12 @@ class DiscoveredHostsController < ::ApplicationController
|
|
214
202
|
|
215
203
|
def action_permission
|
216
204
|
case params[:action]
|
217
|
-
when 'refresh_facts', 'reboot'
|
218
|
-
:view
|
219
|
-
when 'new', 'create'
|
220
|
-
:provision
|
221
|
-
when 'update_multiple_location', 'select_multiple_organization', 'update_multiple_organization', 'select_multiple_location'
|
205
|
+
when 'refresh_facts', 'reboot', 'reboot_all', 'update_multiple_location', 'select_multiple_organization', 'update_multiple_organization', 'select_multiple_location'
|
222
206
|
:edit
|
223
207
|
when 'submit_multiple_destroy', 'multiple_destroy'
|
224
208
|
:destroy
|
225
|
-
when 'auto_provision'
|
209
|
+
when 'auto_provision', 'auto_provision_all'
|
226
210
|
:auto_provision
|
227
|
-
when 'auto_provision_all'
|
228
|
-
:auto_provision_all
|
229
211
|
else
|
230
212
|
super
|
231
213
|
end
|
@@ -257,20 +239,6 @@ class DiscoveredHostsController < ::ApplicationController
|
|
257
239
|
redirect_to discovered_hosts_path
|
258
240
|
end
|
259
241
|
|
260
|
-
def get_ip_from_env
|
261
|
-
# try to find host based on our client ip address
|
262
|
-
ip = request.env['REMOTE_ADDR']
|
263
|
-
|
264
|
-
# check if someone is asking on behave of another system (load balance etc)
|
265
|
-
ip = request.env['HTTP_X_FORWARDED_FOR'] if request.env['HTTP_X_FORWARDED_FOR'].present?
|
266
|
-
|
267
|
-
# Check for explicit parameter override
|
268
|
-
ip = params.delete('ip') if params.include?('ip')
|
269
|
-
|
270
|
-
# in case we got back multiple ips (see #1619)
|
271
|
-
ip = ip.split(',').first
|
272
|
-
end
|
273
|
-
|
274
242
|
def taxonomy_scope
|
275
243
|
if @host
|
276
244
|
@organization = @host.organization
|
@@ -287,4 +255,11 @@ class DiscoveredHostsController < ::ApplicationController
|
|
287
255
|
end
|
288
256
|
end
|
289
257
|
|
258
|
+
# particular actions will always raise N+1 queries
|
259
|
+
def skip_bullet
|
260
|
+
Bullet.enable = false if defined? Bullet
|
261
|
+
yield
|
262
|
+
ensure
|
263
|
+
Bullet.enable = true if defined? Bullet
|
264
|
+
end
|
290
265
|
end
|
@@ -24,16 +24,15 @@ module DiscoveredHostsHelper
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def multiple_discovered_hosts_actions_select
|
27
|
-
actions = [[_('Delete hosts'), multiple_destroy_discovered_hosts_path]]
|
28
|
-
actions << [_('Assign Organization'), select_multiple_organization_discovered_hosts_path] if SETTINGS[:organizations_enabled]
|
29
|
-
actions << [_('Assign Location'), select_multiple_location_discovered_hosts_path] if SETTINGS[:locations_enabled]
|
27
|
+
actions = [[_('Delete hosts'), multiple_destroy_discovered_hosts_path, hash_for_multiple_destroy_discovered_hosts_path]]
|
28
|
+
actions << [_('Assign Organization'), select_multiple_organization_discovered_hosts_path, hash_for_select_multiple_organization_discovered_hosts_path] if SETTINGS[:organizations_enabled]
|
29
|
+
actions << [_('Assign Location'), select_multiple_location_discovered_hosts_path, hash_for_select_multiple_location_discovered_hosts_path] if SETTINGS[:locations_enabled]
|
30
30
|
|
31
31
|
select_action_button( _("Select Action"), {:id => 'submit_multiple'},
|
32
32
|
actions.map do |action|
|
33
|
-
link_to_function(action[0], "build_modal(this, '#{action[1]}')", :'data-dialog-title' => _("%s - The following hosts are about to be changed") % action[0])
|
33
|
+
link_to_function(action[0], "build_modal(this, '#{action[1]}')", :'data-dialog-title' => _("%s - The following hosts are about to be changed") % action[0]) if authorized_for(action[2])
|
34
34
|
end.flatten
|
35
35
|
)
|
36
|
-
|
37
36
|
end
|
38
37
|
|
39
38
|
def turn_zero_to_not_available(value)
|
@@ -44,4 +43,27 @@ module DiscoveredHostsHelper
|
|
44
43
|
host.try(:discovery_attribute_set).try(attr) || default_value
|
45
44
|
end
|
46
45
|
|
46
|
+
def authorized_for_edit_destroy?
|
47
|
+
authorized_for(:controller => :discovered_hosts, :action => :edit) or
|
48
|
+
authorized_for(:controller => :discovered_hosts, :action => :destroy)
|
49
|
+
end
|
50
|
+
|
51
|
+
def discovery_status_icon(host)
|
52
|
+
if host.created_at > 1.day.ago
|
53
|
+
status_glyph = 'glyphicon-plus-sign'
|
54
|
+
status_message = _('New in the last 24 hours')
|
55
|
+
status_color = '#89A54E'
|
56
|
+
elsif host.last_report < 7.days.ago
|
57
|
+
status_glyph = 'glyphicon-exclamation-sign'
|
58
|
+
status_message = _('Not reported in more than 7 days')
|
59
|
+
status_color = '#AA4643'
|
60
|
+
else
|
61
|
+
status_glyph = 'glyphicon-ok-sign'
|
62
|
+
status_message = _('Reported in the last 7 days')
|
63
|
+
status_color = '#4572A7'
|
64
|
+
end
|
65
|
+
|
66
|
+
"<span class='glyphicon #{status_glyph}' style='color: #{status_color}'
|
67
|
+
title='#{status_message}'/>".html_safe
|
68
|
+
end
|
47
69
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module FacterUtils
|
2
|
+
class << self
|
3
|
+
# booted interface fact name
|
4
|
+
def bootif_name
|
5
|
+
Setting[:discovery_fact] || 'discovery_bootif'
|
6
|
+
end
|
7
|
+
|
8
|
+
# booted interface fact is present
|
9
|
+
def bootif_present(facts)
|
10
|
+
! bootif_mac(facts).nil?
|
11
|
+
end
|
12
|
+
|
13
|
+
# booted interface MAC address (nil when not present)
|
14
|
+
def bootif_mac(facts)
|
15
|
+
facts[bootif_name]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -2,42 +2,28 @@ module PuppetFactParserExtensions
|
|
2
2
|
extend ActiveSupport::Concern
|
3
3
|
|
4
4
|
included do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
5
|
+
begin
|
6
|
+
raise "method: suggested_primary_interface" unless instance_methods.include?(:suggested_primary_interface)
|
7
|
+
raise "method: parse_interfaces?" unless instance_methods.include?(:parse_interfaces?)
|
8
|
+
alias_method_chain :suggested_primary_interface, :bootif
|
9
|
+
alias_method_chain :parse_interfaces?, :bootif
|
10
|
+
rescue Exception => e
|
11
|
+
raise ::Foreman::WrappedException.new(e, N_("Incompatible version of puppet fact parser"))
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
#
|
16
|
-
def
|
17
|
-
if
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
primary_interface_without_discovery_fact # fallback if we didn't find interface with such macaddress
|
15
|
+
# discovery has its own method of finding primary iface
|
16
|
+
def suggested_primary_interface_with_bootif(host)
|
17
|
+
return suggested_primary_interface_without_bootif(host) if host.type != "Host::Discovered"
|
18
|
+
bootif_mac = FacterUtils::bootif_mac(facts).try(:downcase)
|
19
|
+
detected = interfaces.detect { |_, values| values[:macaddress].try(:downcase) == bootif_mac }
|
20
|
+
Rails.logger.debug "Detected primary interface: #{detected}"
|
21
|
+
# return the detected interface as array [name, facts]
|
22
|
+
detected || raise(::Foreman::Exception.new(N_("Unable to detect primary interface using MAC '%{mac}' specified by discovery_fact '%{fact}'") % {:mac => bootif_mac, :fact => FacterUtils::bootif_name}))
|
24
23
|
end
|
25
24
|
|
26
|
-
#
|
27
|
-
def
|
28
|
-
|
29
|
-
facts[:interfaces].split(',').each do |interface|
|
30
|
-
if facts["macaddress_#{interface}"].try(:downcase) == facts[discovery_mac_fact_name].try(:downcase)
|
31
|
-
return facts["ipaddress_#{interface}"]
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
ip_without_discovery_fact # fallback if IP was not found
|
36
|
-
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
def discovery_mac_fact_name
|
41
|
-
Setting[:discovery_fact] || 'discovery_bootif'
|
25
|
+
# make 'ignore_puppet_facts_for_provisioning' setting non-effective
|
26
|
+
def parse_interfaces_with_bootif?
|
27
|
+
true
|
42
28
|
end
|
43
29
|
end
|
@@ -3,8 +3,7 @@ class DiscoveryRule < ActiveRecord::Base
|
|
3
3
|
extend FriendlyId
|
4
4
|
friendly_id :name
|
5
5
|
include Parameterizable::ByIdName
|
6
|
-
|
7
|
-
attr_accessible :name, :enabled, :hostgroup_id, :hostname, :max_count, :priority, :search
|
6
|
+
include Taxonomix
|
8
7
|
|
9
8
|
validates :name, :presence => true, :uniqueness => true,
|
10
9
|
:format => { :with => /\A(\S+)\Z/, :message => N_("can't contain white spaces.") }
|
@@ -15,6 +14,8 @@ class DiscoveryRule < ActiveRecord::Base
|
|
15
14
|
validates :max_count, :numericality => { :only_integer => true, :greater_than_or_equal_to => 0 }
|
16
15
|
validates :priority, :presence => true, :numericality => { :only_integer => true, :greater_than_or_equal_to => 0 }
|
17
16
|
validates_lengths_from_database
|
17
|
+
before_validation :default_int_attributes
|
18
|
+
before_validation :enforce_taxonomy
|
18
19
|
|
19
20
|
belongs_to :hostgroup
|
20
21
|
has_many :hosts
|
@@ -23,4 +24,34 @@ class DiscoveryRule < ActiveRecord::Base
|
|
23
24
|
scoped_search :on => :priority
|
24
25
|
scoped_search :on => :search
|
25
26
|
scoped_search :on => :enabled
|
27
|
+
scoped_search :in => :hostgroup, :on => :name, :complete_value => true, :rename => :hostgroup
|
28
|
+
|
29
|
+
# with proc support, default_scope can no longer be chained
|
30
|
+
# include all default scoping here
|
31
|
+
default_scope lambda {
|
32
|
+
with_taxonomy_scope do
|
33
|
+
order("discovery_rules.name")
|
34
|
+
end
|
35
|
+
}
|
36
|
+
|
37
|
+
def default_int_attributes
|
38
|
+
self.max_count ||= 0
|
39
|
+
self.priority ||= 0
|
40
|
+
end
|
41
|
+
|
42
|
+
def enforce_taxonomy
|
43
|
+
return if hostgroup.nil?
|
44
|
+
if SETTINGS[:organizations_enabled]
|
45
|
+
unless (ms = hostgroup.organizations - organizations).empty?
|
46
|
+
names = ms.collect(&:name).to_sentence
|
47
|
+
errors.add(:organizations, n_("Host group organization %s must also be associated to the discovery rule", "Host group organizations %s must also be associated to the discovery rule", ms.size) % names)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
if SETTINGS[:locations_enabled]
|
51
|
+
unless (ms = hostgroup.locations - locations).empty?
|
52
|
+
names = ms.collect(&:name).to_sentence
|
53
|
+
errors.add(:locations, n_("Host group location %s must also be associated to the discovery rule", "Host group locations %s must also be associated to the discovery rule", ms.size) % names)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
26
57
|
end
|