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