foreman_discovery 3.0.0 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|