foreman_discovery 5.0.2 → 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.
- checksums.yaml +4 -4
- data/app/controllers/api/v2/discovered_hosts_controller.rb +4 -7
- data/app/controllers/api/v2/discovery_rules_controller.rb +1 -0
- data/app/controllers/api/v2/fact_values_controller_extensions.rb +11 -0
- data/app/controllers/concerns/foreman/controller/discovered_extensions.rb +6 -3
- data/app/controllers/discovered_hosts_controller.rb +46 -11
- data/app/controllers/discovery_rules_controller.rb +1 -1
- data/app/helpers/discovered_hosts_helper.rb +33 -16
- data/app/models/concerns/discovery_taxonomy_extensions.rb +7 -0
- data/app/models/concerns/fact_value_extensions.rb +8 -0
- data/app/models/discovery_rule.rb +4 -6
- data/app/models/host/discovered.rb +29 -10
- data/app/models/host/managed_extensions.rb +2 -10
- data/app/models/setting/discovered.rb +22 -28
- data/app/services/foreman_discovery/host_converter.rb +19 -10
- data/app/views/api/v2/discovered_hosts/main.json.rabl +1 -1
- data/app/views/dashboard/_discovery_widget_host.html.erb +1 -1
- data/app/views/discovered_hosts/_discovered_host.html.erb +1 -1
- data/app/views/discovered_hosts/_discovered_hosts_list.html.erb +32 -1
- data/app/views/discovered_hosts/index.html.erb +2 -2
- data/app/views/discovered_hosts/show.html.erb +5 -5
- data/app/views/discovered_mailer/_discovered_host.html.erb +1 -1
- data/app/views/discovered_mailer/discovered_summary.text.erb +2 -2
- data/app/views/discovery_rules/_form.html.erb +2 -19
- data/app/views/discovery_rules/_template_inline.erb +10 -0
- data/app/views/discovery_rules/index.html.erb +1 -1
- data/app/views/foreman_discovery/debian_kexec.erb +34 -0
- data/app/views/foreman_discovery/redhat_kexec.erb +5 -4
- data/config/routes.rb +4 -0
- data/db/migrate/20141223142759_fill_discovery_attribute_sets_for_existing_hosts.rb +15 -1
- data/db/migrate/20160719124942_add_missing_view_permissions.rb +18 -0
- data/db/seeds.d/50_discovery_templates.rb +15 -13
- data/lib/discovery.rake +1 -0
- data/lib/foreman_discovery/engine.rb +24 -10
- data/lib/foreman_discovery/version.rb +1 -1
- data/locale/ca/LC_MESSAGES/foreman_discovery.mo +0 -0
- data/locale/ca/foreman_discovery.edit.po +274 -136
- data/locale/ca/foreman_discovery.po +396 -328
- data/locale/de/LC_MESSAGES/foreman_discovery.mo +0 -0
- data/locale/de/foreman_discovery.edit.po +309 -171
- data/locale/de/foreman_discovery.po +419 -361
- data/locale/en/LC_MESSAGES/foreman_discovery.mo +0 -0
- data/locale/en/foreman_discovery.edit.po +881 -0
- data/locale/en/foreman_discovery.po +665 -0
- data/locale/en_GB/LC_MESSAGES/foreman_discovery.mo +0 -0
- data/locale/en_GB/foreman_discovery.edit.po +279 -141
- data/locale/en_GB/foreman_discovery.po +446 -391
- data/locale/es/LC_MESSAGES/foreman_discovery.mo +0 -0
- data/locale/es/foreman_discovery.edit.po +277 -139
- data/locale/es/foreman_discovery.po +415 -362
- data/locale/foreman_discovery.pot +241 -135
- data/locale/fr/LC_MESSAGES/foreman_discovery.mo +0 -0
- data/locale/fr/foreman_discovery.edit.po +289 -151
- data/locale/fr/foreman_discovery.po +439 -411
- data/locale/gl/LC_MESSAGES/foreman_discovery.mo +0 -0
- data/locale/gl/foreman_discovery.edit.po +266 -128
- data/locale/gl/foreman_discovery.po +320 -246
- data/locale/it/LC_MESSAGES/foreman_discovery.mo +0 -0
- data/locale/it/foreman_discovery.edit.po +277 -139
- data/locale/it/foreman_discovery.po +407 -352
- data/locale/ja/LC_MESSAGES/foreman_discovery.mo +0 -0
- data/locale/ja/foreman_discovery.edit.po +279 -141
- data/locale/ja/foreman_discovery.po +411 -339
- data/locale/ko/LC_MESSAGES/foreman_discovery.mo +0 -0
- data/locale/ko/foreman_discovery.edit.po +277 -139
- data/locale/ko/foreman_discovery.po +411 -339
- data/locale/pt_BR/LC_MESSAGES/foreman_discovery.mo +0 -0
- data/locale/pt_BR/foreman_discovery.edit.po +282 -144
- data/locale/pt_BR/foreman_discovery.po +430 -394
- data/locale/ru/LC_MESSAGES/foreman_discovery.mo +0 -0
- data/locale/ru/foreman_discovery.edit.po +371 -232
- data/locale/ru/foreman_discovery.po +448 -385
- data/locale/sv_SE/LC_MESSAGES/foreman_discovery.mo +0 -0
- data/locale/sv_SE/foreman_discovery.edit.po +270 -132
- data/locale/sv_SE/foreman_discovery.po +336 -260
- data/locale/zh_CN/LC_MESSAGES/foreman_discovery.mo +0 -0
- data/locale/zh_CN/foreman_discovery.edit.po +279 -141
- data/locale/zh_CN/foreman_discovery.po +412 -336
- data/locale/zh_TW/LC_MESSAGES/foreman_discovery.mo +0 -0
- data/locale/zh_TW/foreman_discovery.edit.po +279 -141
- data/locale/zh_TW/foreman_discovery.po +412 -338
- data/test/functional/api/v2/discovered_hosts_controller_test.rb +30 -22
- data/test/functional/api/v2/discovery_rules_controller_test.rb +7 -0
- data/test/functional/api/v2/fact_value_extensions_test.rb +37 -0
- data/test/functional/discovered_hosts_controller_test.rb +89 -16
- data/test/functional/discovery_rules_controller_test.rb +1 -1
- data/test/test_helper_discovery.rb +1 -1
- data/test/unit/discovered_extensions_test.rb +65 -21
- data/test/unit/discovery_attribute_set_test.rb +4 -4
- data/test/unit/discovery_taxonomy_extensions_test.rb +31 -0
- data/test/unit/host_discovered_test.rb +110 -14
- metadata +121 -110
- data/app/helpers/concerns/foreman_discovery/settings_helper_extensions.rb +0 -34
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 50f5e89c539ec3eb3bee287fc9251f4e0dad65f9
|
|
4
|
+
data.tar.gz: ccad5c9dcb424f30bd2802aaec3489b55aba7e71
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 110b9578fc4bcf83d47e11254cbcd2c157268f2ba17c4aae6a9a21a47beeb68511b460f55d4427cbd88d7137d92dac1922589c2d4b20e48182799103e746f95c
|
|
7
|
+
data.tar.gz: c10cd4e42f0ac2c5d5a7eaa2b600a471a7f641e2d8a86fe3433201659813bba3f312a219f8efed4159697f0bbfd94ad39bd5c5d79f23fe95e43cdd738f796b11
|
|
@@ -94,13 +94,10 @@ module Api
|
|
|
94
94
|
|
|
95
95
|
def facts
|
|
96
96
|
state = true
|
|
97
|
-
@discovered_host
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
else
|
|
102
|
-
Rails.logger.warn "Discovered facts import unsuccessful, skipping auto provisioning"
|
|
103
|
-
end
|
|
97
|
+
@discovered_host = Host::Discovered.import_host(params[:facts])
|
|
98
|
+
Rails.logger.warn "Discovered facts import unsuccessful, skipping auto provisioning" unless @discovered_host
|
|
99
|
+
if Setting['discovery_auto'] && @discovered_host && rule = find_discovery_rule(@discovered_host)
|
|
100
|
+
state = perform_auto_provision(@discovered_host, rule)
|
|
104
101
|
end
|
|
105
102
|
process_response state
|
|
106
103
|
rescue Exception => e
|
|
@@ -35,6 +35,7 @@ module Api
|
|
|
35
35
|
param :max_count, Integer, :desc => N_("enables to limit maximum amount of provisioned hosts per rule")
|
|
36
36
|
param :priority, Integer, :desc => N_("puts the rules in order, low numbers go first. Must be greater then zero")
|
|
37
37
|
param :enabled, :bool, :desc => N_("flag is used for temporary shutdown of rules")
|
|
38
|
+
param_group :taxonomies, ::Api::V2::BaseController
|
|
38
39
|
end
|
|
39
40
|
end
|
|
40
41
|
|
|
@@ -5,8 +5,8 @@ module Foreman::Controller::DiscoveredExtensions
|
|
|
5
5
|
def find_discovery_rule host
|
|
6
6
|
raise(::Foreman::Exception.new(N_("Unable to find a discovery rule, no host provided (check permissions)"))) if host.nil?
|
|
7
7
|
Rails.logger.debug "Finding auto discovery rule for host #{host.name} (#{host.id})"
|
|
8
|
-
#
|
|
9
|
-
DiscoveryRule.where(:enabled => true).
|
|
8
|
+
# rule with *lower* priority wins (older wins for same priority)
|
|
9
|
+
DiscoveryRule.where(:enabled => true).reorder(:priority, :created_at).each do |rule|
|
|
10
10
|
max = rule.max_count
|
|
11
11
|
usage = rule.hosts.size
|
|
12
12
|
Rails.logger.debug "Found rule #{rule.name} (#{rule.id}) [#{usage}/#{max}]"
|
|
@@ -54,8 +54,11 @@ module Foreman::Controller::DiscoveredExtensions
|
|
|
54
54
|
host.name = host.render_template(rule.hostname) unless rule.hostname.empty?
|
|
55
55
|
# fallback to the original if template did not expand
|
|
56
56
|
host.name = original_name if host.name.empty?
|
|
57
|
+
# explicitly set all inheritable attributes from hostgroup
|
|
58
|
+
host.attributes = host.apply_inherited_attributes(hostgroup_id: rule.hostgroup_id)
|
|
59
|
+
host.set_hostgroup_defaults
|
|
57
60
|
# save! does not work here
|
|
58
|
-
host.save
|
|
61
|
+
host.save ? host : false
|
|
59
62
|
end
|
|
60
63
|
|
|
61
64
|
def perform_reboot_all hosts = Host::Discovered.all
|
|
@@ -38,7 +38,7 @@ class DiscoveredHostsController < ::ApplicationController
|
|
|
38
38
|
get_interfaces
|
|
39
39
|
@host.facts_hash.each do |key, value|
|
|
40
40
|
value = number_to_human_size(value) if /size$/.match(key)
|
|
41
|
-
assign_fact_to_category(key, value)
|
|
41
|
+
assign_fact_to_category(key, value)
|
|
42
42
|
end
|
|
43
43
|
add_custom_facts
|
|
44
44
|
end
|
|
@@ -50,20 +50,37 @@ class DiscoveredHostsController < ::ApplicationController
|
|
|
50
50
|
|
|
51
51
|
def edit
|
|
52
52
|
@host = ::ForemanDiscovery::HostConverter.to_managed(@host, true, false) unless @host.nil?
|
|
53
|
-
|
|
53
|
+
@host.attributes = @host.apply_inherited_attributes(params[:host]) unless params[:host].empty?
|
|
54
|
+
@host.set_hostgroup_defaults
|
|
55
|
+
setup_host_class_variables(@host)
|
|
56
|
+
@override_taxonomy = true
|
|
57
|
+
if params[:quick_submit]
|
|
58
|
+
perform_update(@host, _('Successfully provisioned %s') % @host.name)
|
|
59
|
+
else
|
|
60
|
+
render :template => 'hosts/edit'
|
|
61
|
+
end
|
|
54
62
|
end
|
|
55
63
|
|
|
56
64
|
def update
|
|
57
65
|
@host = ::ForemanDiscovery::HostConverter.to_managed(@host)
|
|
58
66
|
forward_url_options
|
|
67
|
+
@host.attributes = params[:host]
|
|
68
|
+
|
|
69
|
+
perform_update(@host)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def perform_update(host, success_message = nil)
|
|
59
73
|
Taxonomy.no_taxonomy_scope do
|
|
60
|
-
|
|
61
|
-
|
|
74
|
+
::ForemanDiscovery::HostConverter.set_build_clean_facts(host)
|
|
75
|
+
if host.save
|
|
76
|
+
success_options = { :success_redirect => host_path(host), :redirect_xhr => request.xhr? }
|
|
77
|
+
success_options[:success_msg] = success_message if success_message
|
|
78
|
+
process_success success_options
|
|
62
79
|
else
|
|
63
80
|
taxonomy_scope
|
|
64
81
|
load_vars_for_ajax
|
|
65
82
|
offer_to_overwrite_conflicts
|
|
66
|
-
process_error :object =>
|
|
83
|
+
process_error :object => host, :render => 'hosts/edit'
|
|
67
84
|
end
|
|
68
85
|
end
|
|
69
86
|
end
|
|
@@ -184,11 +201,23 @@ class DiscoveredHostsController < ::ApplicationController
|
|
|
184
201
|
|
|
185
202
|
private
|
|
186
203
|
|
|
204
|
+
def setup_host_class_variables(host)
|
|
205
|
+
if host.hostgroup
|
|
206
|
+
@architecture = host.hostgroup.architecture
|
|
207
|
+
@operatingsystem = host.hostgroup.operatingsystem
|
|
208
|
+
@environment = host.hostgroup.environment
|
|
209
|
+
@domain = host.hostgroup.domain
|
|
210
|
+
@subnet = host.hostgroup.subnet
|
|
211
|
+
@compute_profile = host.hostgroup.compute_profile
|
|
212
|
+
@realm = host.hostgroup.realm
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
187
216
|
def init_regex_and_categories
|
|
188
217
|
hightlights = Setting[:discovery_facts_highlights].empty? ? /^(productname|memorysize|manufacturer|architecture|macaddress$|processorcount|physicalprocessorcount|discovery_subnet|discovery_boot|ipaddress$)/ : Regexp.new(Setting[:discovery_facts_highlights])
|
|
189
218
|
storage = Setting[:discovery_facts_storage].empty? ? /^blockdevice/ : Regexp.new(Setting[:discovery_facts_storage])
|
|
190
219
|
hardware = Setting[:discovery_facts_hardware].empty? ? /^(hardw|manufacturer|memo|process)/ : Regexp.new(Setting[:discovery_facts__hardware])
|
|
191
|
-
network = Setting[:discovery_facts_network].empty? ? /^(
|
|
220
|
+
network = Setting[:discovery_facts_network].empty? ? /^(interfaces|dhcp|fqdn|hostname)/ : Regexp.new(Setting[:discovery_facts_network])
|
|
192
221
|
software = Setting[:discovery_facts_software].empty? ? /^(bios|os|discovery)/ : Regexp.new(Setting[:discovery_facts_software])
|
|
193
222
|
ipmi = Setting[:discovery_facts_ipmi].empty? ? /^ipmi/ : Regexp.new(Setting[:discovery_facts_ipmi])
|
|
194
223
|
@regex_array = [hightlights, storage, hardware, network, software, ipmi, false]
|
|
@@ -196,7 +225,11 @@ class DiscoveredHostsController < ::ApplicationController
|
|
|
196
225
|
@categories_names = [N_("Highlights"), N_("Storage"), N_("Hardware"), N_("Network"), N_("Software"), N_("IPMI"), N_("Miscellaneous")]
|
|
197
226
|
end
|
|
198
227
|
|
|
199
|
-
def assign_fact_to_category(key, value
|
|
228
|
+
def assign_fact_to_category(key, value)
|
|
229
|
+
if @interfaces.any? {|interface| key.include? interface[:identifier]}
|
|
230
|
+
@categories[3][key] = value
|
|
231
|
+
return
|
|
232
|
+
end
|
|
200
233
|
@regex_array.each_with_index do |regex, index|
|
|
201
234
|
if !regex
|
|
202
235
|
@categories[index][key] = value
|
|
@@ -249,10 +282,12 @@ class DiscoveredHostsController < ::ApplicationController
|
|
|
249
282
|
end
|
|
250
283
|
|
|
251
284
|
def find_by_name(*includes)
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
@host
|
|
255
|
-
|
|
285
|
+
not_found and return false if (id = params[:id]).blank?
|
|
286
|
+
id.downcase!
|
|
287
|
+
@host = includes.empty? ? resource_base.find_by_id(id) : resource_base.includes(includes).find_by_id(id)
|
|
288
|
+
@host ||= includes.empty? ? resource_base.find_by_name(id) : resource_base.includes(includes).find_by_name(id)
|
|
289
|
+
not_found and return(false) unless @host
|
|
290
|
+
@host
|
|
256
291
|
end
|
|
257
292
|
|
|
258
293
|
def find_by_name_incl_subnet
|
|
@@ -5,7 +5,7 @@ class DiscoveryRulesController < ApplicationController
|
|
|
5
5
|
before_filter :find_resource, :only => [:edit, :update, :destroy, :enable, :disable, :auto_provision]
|
|
6
6
|
|
|
7
7
|
def index
|
|
8
|
-
base = resource_base.search_for(params[:search], :order => (params[:order]
|
|
8
|
+
base = resource_base.search_for(params[:search], :order => (params[:order]))
|
|
9
9
|
@discovery_rules = base.paginate(:page => params[:page]).includes(:hostgroup)
|
|
10
10
|
end
|
|
11
11
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
module DiscoveredHostsHelper
|
|
2
|
-
|
|
3
2
|
def attach_flags(interface)
|
|
4
3
|
flags = ""
|
|
5
4
|
flags += "flag-primary " if interface[:primary]
|
|
@@ -12,28 +11,22 @@ module DiscoveredHostsHelper
|
|
|
12
11
|
end
|
|
13
12
|
|
|
14
13
|
def discovered_hosts_title_actions(host)
|
|
15
|
-
actions = [[_('Provision'),
|
|
16
|
-
actions << [_('Auto Provision'), hash_for_auto_provision_discovered_host_path(:id => host), :method => :post]
|
|
17
|
-
actions << [_('Refresh facts') ,hash_for_refresh_facts_discovered_host_path(:id => host)]
|
|
18
|
-
actions << [_('Reboot') ,hash_for_reboot_discovered_host_path(:id => host), :method => :put]
|
|
14
|
+
actions = [[_('Provision'), hash_for_edit_discovered_host_path(:id => host).merge(:auth_object => host, :permission => :provision_discovered_hosts)]]
|
|
15
|
+
actions << [_('Auto Provision'), hash_for_auto_provision_discovered_host_path(:id => host).merge(:auth_object => host, :permission => :auto_provision_discovered_hosts), :method => :post]
|
|
16
|
+
actions << [_('Refresh facts') ,hash_for_refresh_facts_discovered_host_path(:id => host).merge(:auth_object => host, :permission => :edit_discovered_hosts)]
|
|
17
|
+
actions << [_('Reboot') ,hash_for_reboot_discovered_host_path(:id => host).merge(:auth_object => host, :permission => :edit_discovered_hosts), :method => :put]
|
|
19
18
|
title_actions(
|
|
20
19
|
button_group(
|
|
21
|
-
link_to(_("Back"), :back)
|
|
22
|
-
),
|
|
23
|
-
select_action_button( _("Select Action"), {},
|
|
24
|
-
actions.map do |action|
|
|
25
|
-
method = action[2] if action.size > 1
|
|
26
|
-
link_to(action[0] , action[1], method)
|
|
27
|
-
end.flatten
|
|
20
|
+
link_to(_("Back"), :back, :class => "btn btn-default")
|
|
28
21
|
),
|
|
22
|
+
select_action_button( _("Select Action"), {}, actions.map { |action| display_link_if_authorized(action[0] , action[1], action[2] || {}) }.flatten ),
|
|
29
23
|
button_group(
|
|
30
|
-
link_to(_("Expand All"),"#",:class => "btn ",:onclick => "$('.glyphicon-plus-sign').toggleClass('glyphicon glyphicon-minus-sign glyphicon glyphicon-plus-sign');
|
|
24
|
+
link_to(_("Expand All"),"#",:class => "btn btn-default",:onclick => "$('.glyphicon-plus-sign').toggleClass('glyphicon glyphicon-minus-sign glyphicon glyphicon-plus-sign');
|
|
31
25
|
$('.facts-panel').addClass('collapse in').height('auto');"
|
|
32
26
|
)
|
|
33
27
|
),
|
|
34
28
|
button_group(
|
|
35
|
-
|
|
36
|
-
:class => "btn btn-danger", :confirm => _('Are you sure?'), :method => :delete)
|
|
29
|
+
display_delete_if_authorized(hash_for_discovered_host_path(:id => host).merge(:auth_object => host, :permission => :destroy_discovered_hosts), :class => "btn btn-danger", :data => { :confirm => _('Delete %s?') % host.name })
|
|
37
30
|
)
|
|
38
31
|
)
|
|
39
32
|
end
|
|
@@ -68,7 +61,7 @@ module DiscoveredHostsHelper
|
|
|
68
61
|
status_glyph = 'glyphicon-plus-sign'
|
|
69
62
|
status_message = _('New in the last 24 hours')
|
|
70
63
|
status_color = '#89A54E'
|
|
71
|
-
elsif host.last_report < 7.days.ago
|
|
64
|
+
elsif host.last_report.present? && host.last_report < 7.days.ago
|
|
72
65
|
status_glyph = 'glyphicon-exclamation-sign'
|
|
73
66
|
status_message = _('Not reported in more than 7 days')
|
|
74
67
|
status_color = '#AA4643'
|
|
@@ -81,4 +74,28 @@ module DiscoveredHostsHelper
|
|
|
81
74
|
"<span class='glyphicon #{status_glyph}' style='color: #{status_color}'
|
|
82
75
|
title='#{status_message}'/>".html_safe
|
|
83
76
|
end
|
|
77
|
+
|
|
78
|
+
def host_taxonomy_select(f, taxonomy)
|
|
79
|
+
# Add hidden field with taxonomy value to be updated by the form on submit
|
|
80
|
+
tax_html = super
|
|
81
|
+
tax_id = "#{taxonomy.to_s.downcase}_id"
|
|
82
|
+
selected_taxonomy = params[:host][tax_id] if params[:host]
|
|
83
|
+
if @override_taxonomy && selected_taxonomy
|
|
84
|
+
hidden_tax = f.hidden_field tax_id.to_sym, :value => selected_taxonomy
|
|
85
|
+
tax_html += hidden_tax
|
|
86
|
+
end
|
|
87
|
+
tax_html
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def provision_button(host, authorization_options)
|
|
91
|
+
return '' unless authorized_for(authorization_options)
|
|
92
|
+
|
|
93
|
+
button_tag(
|
|
94
|
+
_('Provision'),
|
|
95
|
+
:type => :button,
|
|
96
|
+
:class => 'btn btn-sm btn-default',
|
|
97
|
+
:data => {
|
|
98
|
+
:toggle => 'modal',
|
|
99
|
+
:target => "#fixedPropertiesSelector-#{host.id}"})
|
|
100
|
+
end
|
|
84
101
|
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
module FactValueExtensions
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
included do
|
|
5
|
+
belongs_to :discovered_host, :class_name => "Host::Discovered", :foreign_key => :host_id
|
|
6
|
+
scoped_search :in => :discovered_host, :on => :id, :complete_enabled => false, :only_explicit => true, :rename => :discovered_host
|
|
7
|
+
end
|
|
8
|
+
end
|
|
@@ -28,13 +28,11 @@ class DiscoveryRule < ActiveRecord::Base
|
|
|
28
28
|
scoped_search :on => :enabled
|
|
29
29
|
scoped_search :in => :hostgroup, :on => :name, :complete_value => true, :rename => :hostgroup
|
|
30
30
|
|
|
31
|
-
# with proc support, default_scope can no longer be chained
|
|
32
|
-
# include all default scoping here
|
|
33
31
|
default_scope lambda {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
32
|
+
with_taxonomy_scope do
|
|
33
|
+
order('discovery_rules.priority, discovery_rules.created_at')
|
|
34
|
+
end
|
|
35
|
+
}
|
|
38
36
|
|
|
39
37
|
def default_int_attributes
|
|
40
38
|
self.max_count ||= 0
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
class Host::Discovered < ::Host::Base
|
|
2
2
|
include ScopedSearchExtensions
|
|
3
|
+
include Foreman::Renderer
|
|
3
4
|
|
|
4
5
|
attr_accessible :discovery_rule_id
|
|
5
6
|
|
|
@@ -30,7 +31,7 @@ class Host::Discovered < ::Host::Base
|
|
|
30
31
|
where(taxonomy_conditions).order("hosts.created_at DESC")
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
def self.
|
|
34
|
+
def self.import_host facts
|
|
34
35
|
raise(::Foreman::Exception.new(N_("Invalid facts, must be a Hash"))) unless facts.is_a?(Hash)
|
|
35
36
|
|
|
36
37
|
# filter facts
|
|
@@ -47,15 +48,21 @@ class Host::Discovered < ::Host::Base
|
|
|
47
48
|
hostname = normalize_string_for_hostname("#{hostname_prefix}#{name_fact}")
|
|
48
49
|
Rails.logger.warn "Hostname does not start with an alphabetical character" unless hostname.downcase.match /^[a-z]/
|
|
49
50
|
|
|
50
|
-
# create new host record
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
# find existing or create new host record
|
|
52
|
+
bootif_mac = FacterUtils::bootif_mac(facts).try(:downcase)
|
|
53
|
+
hosts = ::Nic::Managed.where(:mac => bootif_mac, :primary => true)
|
|
54
|
+
if hosts.size == 0
|
|
55
|
+
host = Host.new(:name => hostname, :type => "Host::Discovered")
|
|
56
|
+
else
|
|
57
|
+
Rails.logger.warn "Multiple discovered hosts found with MAC address #{name_fact}, choosing one" if hosts.size > 1
|
|
58
|
+
host = hosts.first.host
|
|
59
|
+
end
|
|
53
60
|
host.type = "Host::Discovered"
|
|
54
61
|
|
|
55
62
|
# and save (interfaces are created via puppet parser extension)
|
|
56
63
|
host.save(:validate => false) if host.new_record?
|
|
57
|
-
|
|
58
|
-
|
|
64
|
+
raise ::Foreman::Exception.new(N_("Facts could not be imported")) unless host.import_facts(facts)
|
|
65
|
+
host
|
|
59
66
|
end
|
|
60
67
|
|
|
61
68
|
def import_facts facts
|
|
@@ -75,7 +82,7 @@ class Host::Discovered < ::Host::Base
|
|
|
75
82
|
super
|
|
76
83
|
end
|
|
77
84
|
|
|
78
|
-
def populate_fields_from_facts(facts = self.facts_hash, ignored_type)
|
|
85
|
+
def populate_fields_from_facts(facts = self.facts_hash, ignored_type = nil)
|
|
79
86
|
# detect interfaces and primary interface using extensions
|
|
80
87
|
parser = super(facts, :foreman_discovery)
|
|
81
88
|
|
|
@@ -92,13 +99,13 @@ class Host::Discovered < ::Host::Base
|
|
|
92
99
|
self.primary_interface.subnet = subnet
|
|
93
100
|
# set location and organization
|
|
94
101
|
if SETTINGS[:locations_enabled]
|
|
95
|
-
self.location = Location.
|
|
102
|
+
self.location = Location.find_by_title(Setting[:discovery_location]) ||
|
|
96
103
|
subnet.try(:locations).try(:first) ||
|
|
97
104
|
Location.first
|
|
98
105
|
Rails.logger.info "Assigned location: #{self.location}"
|
|
99
106
|
end
|
|
100
107
|
if SETTINGS[:organizations_enabled]
|
|
101
|
-
self.organization = Organization.
|
|
108
|
+
self.organization = Organization.find_by_title(Setting[:discovery_organization]) ||
|
|
102
109
|
subnet.try(:organizations).try(:first) ||
|
|
103
110
|
Organization.first
|
|
104
111
|
Rails.logger.info "Assigned organization: #{self.organization}"
|
|
@@ -108,6 +115,17 @@ class Host::Discovered < ::Host::Base
|
|
|
108
115
|
end
|
|
109
116
|
self.discovery_attribute_set = DiscoveryAttributeSet.where(:host_id => id).first_or_create
|
|
110
117
|
self.discovery_attribute_set.update_attributes(import_from_facts)
|
|
118
|
+
# lock the host into discovery via PXE, if feature is enabled in settings
|
|
119
|
+
if Setting::Discovered.discovery_lock? && self.subnet.tftp?
|
|
120
|
+
begin
|
|
121
|
+
@host = self
|
|
122
|
+
Rails.logger.info "Locking discovered host #{self.mac} in subnet #{subnet}"
|
|
123
|
+
template = unattended_render(::ProvisioningTemplate.find_by_name(Setting['discovery_lock_template']).template)
|
|
124
|
+
subnet.tftp_proxy.set mac, :pxeconfig => template
|
|
125
|
+
rescue ::Foreman::Exception => e
|
|
126
|
+
::Foreman::Logging.exception("Could not set tftp_proxy from proxy", e)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
111
129
|
self.save!
|
|
112
130
|
parser
|
|
113
131
|
end
|
|
@@ -144,7 +162,8 @@ class Host::Discovered < ::Host::Base
|
|
|
144
162
|
|
|
145
163
|
def refresh_facts
|
|
146
164
|
facts = ::ForemanDiscovery::NodeAPI::Inventory.new(:url => proxy_url).facter
|
|
147
|
-
self.class.
|
|
165
|
+
self.class.import_host facts
|
|
166
|
+
import_facts facts
|
|
148
167
|
rescue Exception => e
|
|
149
168
|
raise _("Could not get facts from proxy %{url}: %{error}") % {:url => proxy_url, :error => e}
|
|
150
169
|
end
|
|
@@ -41,20 +41,12 @@ module Host::ManagedExtensions
|
|
|
41
41
|
# no reboot on orchestration rollback
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
def boot_url pxe_file
|
|
45
|
-
raise ::Foreman::Exception.new(N_("Operating system not set for host/hostgroup")) unless operatingsystem
|
|
46
|
-
base = operatingsystem.medium_uri(self)
|
|
47
|
-
raise ::Foreman::Exception.new(N_("Medium not set for host/hostgroup")) unless base
|
|
48
|
-
path = operatingsystem.url_for_boot(pxe_file)
|
|
49
|
-
operatingsystem.medium_vars_to_uri("#{base}/#{path}", architecture.name, operatingsystem).to_s
|
|
50
|
-
end
|
|
51
|
-
|
|
52
44
|
def setKexec
|
|
53
45
|
template = provisioning_template(:kind => 'kexec')
|
|
54
46
|
raise ::Foreman::Exception.new(N_("Kexec template not associated with operating system")) unless template
|
|
55
47
|
@host = self
|
|
56
|
-
|
|
57
|
-
@initrd =
|
|
48
|
+
# the following two attributes are overwritten by TFTP in preview mode (kept for compatibility)
|
|
49
|
+
@kernel, @initrd = operatingsystem.boot_files_uri(@host.medium, @host.architecture)
|
|
58
50
|
json = unattended_render(template)
|
|
59
51
|
old.becomes(Host::Discovered).kexec json
|
|
60
52
|
true
|
|
@@ -16,50 +16,40 @@ class Setting::Discovered < ::Setting
|
|
|
16
16
|
|
|
17
17
|
Setting.transaction do
|
|
18
18
|
[
|
|
19
|
-
self.set('discovery_fact', N_("Fact name to use for primary interface detection"), "discovery_bootif"),
|
|
20
|
-
self.set('
|
|
21
|
-
self.set('
|
|
22
|
-
self.set('
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
self.set('
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
self.set('discovery_fact_column', N_("Extra facter columns to show in host lists (separate by comma)"), ""),
|
|
19
|
+
self.set('discovery_fact', N_("Fact name to use for primary interface detection"), "discovery_bootif", N_("Interface fact")),
|
|
20
|
+
self.set('discovery_clean_facts', N_("Clean all reported facts during provisioning (except discovery facts)"), false, N_("Clean all facts")),
|
|
21
|
+
self.set('discovery_hostname', N_("List of facts to use for the hostname (separated by comma, first wins)"), "discovery_bootif", N_("Hostname facts")),
|
|
22
|
+
self.set('discovery_auto', N_("Automatically provision newly discovered hosts, according to the provisioning rules"), false, N_("Auto provisioning")),
|
|
23
|
+
self.set('discovery_reboot', N_("Automatically reboot or kexec discovered host during provisioning"), true, N_("Reboot")),
|
|
24
|
+
self.set('discovery_prefix', N_("The default prefix to use for the host name, must start with a letter"), "mac", N_("Hostname prefix")),
|
|
25
|
+
self.set('discovery_fact_column', N_("Extra facter columns to show in host lists (separate by comma)"), "", N_("Fact columns")),
|
|
26
|
+
self.set('discovery_facts_highlights', N_("Regex to organize facts for highlights section - e.g. ^(abc|cde)$"), "", N_("Highlighted facts")),
|
|
27
|
+
self.set('discovery_facts_storage', N_("Regex to organize facts for storage section"), "", N_("Storage facts")),
|
|
28
|
+
self.set('discovery_facts_software', N_("Regex to organize facts for software section"), "", N_("Software facts")),
|
|
29
|
+
self.set('discovery_facts_hardware', N_("Regex to organize facts for hardware section"), "", N_("Hardware facts")),
|
|
30
|
+
self.set('discovery_facts_network', N_("Regex to organize facts for network section"), "", N_("Network facts")),
|
|
31
|
+
self.set('discovery_facts_ipmi', N_("Regex to organize facts for ipmi section"), "", N_("IPMI facts")),
|
|
32
|
+
self.set('discovery_lock', N_("Automatically generate PXE configuration to pin a newly discovered host to discovery"), false, N_("Lock PXE")),
|
|
33
|
+
self.set('discovery_lock_template', N_("PXE template to be used when pinning a host to discovery"), 'pxelinux_discovery', N_("Locked template name"),nil,{ :collection => Proc.new {Hash[ProvisioningTemplate.all.map{|template| [template[:name], template[:name]]}]} }),
|
|
35
34
|
].compact.each { |s| self.create s.update(:category => "Setting::Discovered")}
|
|
36
35
|
end
|
|
37
36
|
|
|
38
37
|
if SETTINGS[:locations_enabled]
|
|
39
38
|
Setting.transaction do
|
|
40
39
|
[
|
|
41
|
-
self.set('discovery_location', N_("The default location to place discovered hosts in"), ""),
|
|
40
|
+
self.set('discovery_location', N_("The default location to place discovered hosts in"), "", N_("Discovery location"), nil, { :collection => Proc.new {Hash[Location.all.map{|loc| [loc[:title], loc[:title]]}]} }),
|
|
42
41
|
].compact.each { |s| self.create s.update(:category => "Setting::Discovered")}
|
|
43
42
|
end
|
|
44
43
|
end
|
|
44
|
+
|
|
45
45
|
if SETTINGS[:organizations_enabled]
|
|
46
46
|
Setting.transaction do
|
|
47
47
|
[
|
|
48
|
-
self.set('discovery_organization', N_("The default organization to place discovered hosts in"), "" ),
|
|
48
|
+
self.set('discovery_organization', N_("The default organization to place discovered hosts in"), "", N_("Discovery organization"), nil, { :collection => Proc.new {Hash[Organization.all.map{|org| [org[:title], org[:title]]}]} }),
|
|
49
49
|
].compact.each { |s| self.create s.update(:category => "Setting::Discovered")}
|
|
50
50
|
end
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
-
Setting.transaction do
|
|
54
|
-
[
|
|
55
|
-
self.set('discovery_facts_highlights', N_("Regex to organize facts for highlights section - e.g. ^(abc|cde)$"), ""),
|
|
56
|
-
self.set('discovery_facts_storage', N_("Regex to organize facts for storage section"), ""),
|
|
57
|
-
self.set('discovery_facts_software', N_("Regex to organize facts for software section"), ""),
|
|
58
|
-
self.set('discovery_facts_hardware', N_("Regex to organize facts for hardware section"), ""),
|
|
59
|
-
self.set('discovery_facts_network', N_("Regex to organize facts for network section"), ""),
|
|
60
|
-
self.set('discovery_facts_ipmi', N_("Regex to organize facts for ipmi section"), ""),
|
|
61
|
-
].compact.each { |s| self.create s.update(:category => "Setting::Discovered")}
|
|
62
|
-
end
|
|
63
53
|
true
|
|
64
54
|
end
|
|
65
55
|
|
|
@@ -72,6 +62,10 @@ class Setting::Discovered < ::Setting
|
|
|
72
62
|
from_array Setting['discovery_hostname']
|
|
73
63
|
end
|
|
74
64
|
|
|
65
|
+
def self.discovery_lock?
|
|
66
|
+
Foreman::Cast.to_bool(Setting['discovery_lock']) && !Setting['discovery_lock_template'].blank? && ProvisioningTemplate.exists?(:name => Setting['discovery_lock_template'])
|
|
67
|
+
end
|
|
68
|
+
|
|
75
69
|
def self.from_array(setting)
|
|
76
70
|
return [] unless setting.present?
|
|
77
71
|
setting.to_s.split(",").map(&:strip)
|