foreman_discovery 11.0.0 → 12.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.
Files changed (90) hide show
  1. checksums.yaml +5 -5
  2. data/app/controllers/api/v2/discovered_hosts_controller.rb +1 -2
  3. data/app/controllers/concerns/foreman/controller/discovered_extensions.rb +1 -1
  4. data/app/controllers/discovered_hosts_controller.rb +21 -11
  5. data/app/controllers/foreman_discovery/concerns/hosts_controller_extensions.rb +1 -1
  6. data/app/helpers/discovered_hosts_helper.rb +9 -11
  7. data/app/models/discovery_rule.rb +3 -0
  8. data/app/models/host/discovered.rb +59 -19
  9. data/app/models/setting/discovered.rb +1 -0
  10. data/app/services/foreman_discovery/fact_parser.rb +6 -2
  11. data/app/services/foreman_discovery/ui_notifications/new_host.rb +3 -1
  12. data/app/views/dashboard/_discovery_widget_host_list.html.erb +1 -1
  13. data/app/views/discovered_hosts/_discovered_hosts_list.html.erb +2 -3
  14. data/app/views/discovered_hosts/_selected_hosts.html.erb +1 -1
  15. data/app/views/discovered_hosts/index.html.erb +0 -2
  16. data/app/views/discovered_hosts/multiple_auto_provision.html.erb +4 -0
  17. data/app/views/discovered_hosts/multiple_reboot.html.erb +4 -0
  18. data/app/views/discovered_hosts/show.html.erb +27 -15
  19. data/app/views/discovery_rules/_form.html.erb +9 -3
  20. data/app/views/discovery_rules/edit.html.erb +1 -1
  21. data/app/views/discovery_rules/index.html.erb +2 -2
  22. data/app/views/foreman_discovery/debian_kexec.erb +1 -1
  23. data/app/views/foreman_discovery/redhat_kexec.erb +1 -1
  24. data/config/as_deprecation_whitelist.yaml +395 -0
  25. data/config/routes.rb +7 -5
  26. data/db/migrate/20171222120314_add_constraints_on_discovery_rules_hostgroups.rb +10 -0
  27. data/db/migrate/20180412124505_add_priority_score_to_discovery_rules.rb +24 -0
  28. data/extra/discover-host +7 -5
  29. data/extra/discovery/simple-bond.json +167 -0
  30. data/lib/foreman_discovery/engine.rb +9 -3
  31. data/lib/foreman_discovery/version.rb +1 -1
  32. data/locale/ca/LC_MESSAGES/foreman_discovery.mo +0 -0
  33. data/locale/ca/foreman_discovery.edit.po +148 -221
  34. data/locale/ca/foreman_discovery.po +25 -19
  35. data/locale/de/LC_MESSAGES/foreman_discovery.mo +0 -0
  36. data/locale/de/foreman_discovery.edit.po +147 -221
  37. data/locale/de/foreman_discovery.po +26 -20
  38. data/locale/en/foreman_discovery.edit.po +106 -98
  39. data/locale/en/foreman_discovery.po +24 -18
  40. data/locale/en_GB/LC_MESSAGES/foreman_discovery.mo +0 -0
  41. data/locale/en_GB/foreman_discovery.edit.po +149 -222
  42. data/locale/en_GB/foreman_discovery.po +26 -20
  43. data/locale/es/LC_MESSAGES/foreman_discovery.mo +0 -0
  44. data/locale/es/foreman_discovery.edit.po +149 -222
  45. data/locale/es/foreman_discovery.po +26 -20
  46. data/locale/foreman_discovery.pot +115 -103
  47. data/locale/fr/LC_MESSAGES/foreman_discovery.mo +0 -0
  48. data/locale/fr/foreman_discovery.edit.po +147 -221
  49. data/locale/fr/foreman_discovery.po +26 -20
  50. data/locale/gl/foreman_discovery.edit.po +147 -220
  51. data/locale/gl/foreman_discovery.po +24 -18
  52. data/locale/it/LC_MESSAGES/foreman_discovery.mo +0 -0
  53. data/locale/it/foreman_discovery.edit.po +148 -221
  54. data/locale/it/foreman_discovery.po +25 -19
  55. data/locale/ja/LC_MESSAGES/foreman_discovery.mo +0 -0
  56. data/locale/ja/foreman_discovery.edit.po +149 -222
  57. data/locale/ja/foreman_discovery.po +26 -20
  58. data/locale/ko/LC_MESSAGES/foreman_discovery.mo +0 -0
  59. data/locale/ko/foreman_discovery.edit.po +149 -221
  60. data/locale/ko/foreman_discovery.po +26 -20
  61. data/locale/pt_BR/LC_MESSAGES/foreman_discovery.mo +0 -0
  62. data/locale/pt_BR/foreman_discovery.edit.po +149 -222
  63. data/locale/pt_BR/foreman_discovery.po +26 -20
  64. data/locale/ru/LC_MESSAGES/foreman_discovery.mo +0 -0
  65. data/locale/ru/foreman_discovery.edit.po +152 -223
  66. data/locale/ru/foreman_discovery.po +26 -20
  67. data/locale/sv_SE/LC_MESSAGES/foreman_discovery.mo +0 -0
  68. data/locale/sv_SE/foreman_discovery.edit.po +147 -220
  69. data/locale/sv_SE/foreman_discovery.po +24 -18
  70. data/locale/zh_CN/LC_MESSAGES/foreman_discovery.mo +0 -0
  71. data/locale/zh_CN/foreman_discovery.edit.po +155 -224
  72. data/locale/zh_CN/foreman_discovery.po +26 -20
  73. data/locale/zh_TW/LC_MESSAGES/foreman_discovery.mo +0 -0
  74. data/locale/zh_TW/foreman_discovery.edit.po +151 -222
  75. data/locale/zh_TW/foreman_discovery.po +26 -20
  76. data/test/functional/api/v2/discovered_hosts_controller_test.rb +2 -0
  77. data/test/functional/api/v2/discovery_rules_controller_test.rb +96 -9
  78. data/test/functional/api/v2/settings_controller_test.rb +22 -0
  79. data/test/functional/discovered_hosts_controller_test.rb +20 -21
  80. data/test/functional/discovery_rules_controller_test.rb +5 -4
  81. data/test/integration/discovered_hosts_test.rb +20 -10
  82. data/test/models/setting_test.rb +11 -0
  83. data/test/test_helper_discovery.rb +1 -0
  84. data/test/unit/discovered_extensions_test.rb +2 -13
  85. data/test/unit/discovery_rule_test.rb +87 -1
  86. data/test/unit/fact_parser_test.rb +2 -2
  87. data/test/unit/host_discovered_test.rb +60 -28
  88. data/test/unit/ui_notifications/destroy_host_test.rb +14 -4
  89. data/test/unit/ui_notifications/new_host_test.rb +8 -1
  90. metadata +22 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 221ad5eb42c9d10c313e6e827beb5d0156a56275
4
- data.tar.gz: 6b6df98bf5b4611aeb3734152b5463c2edef7453
2
+ SHA256:
3
+ metadata.gz: 057e3a38102117de8da88c00a3cb4f7d7bcf56c73264bec062b6c5b0a26d879b
4
+ data.tar.gz: 3fa992f91692c8ff8ead22f5fe1dd1f68c53f68ec50d4226cfc7d13ea43e2f00
5
5
  SHA512:
6
- metadata.gz: 4a67ce08394ba37b05dba6947d2bfc2ccd0de5ab13ded18dc208ce29b7ec069634ba68a42611b17a7987c90f013540d94e136b06a553764192df9b07e29bd237
7
- data.tar.gz: 8f57149cce4c007f15858483c9aaf3bb9dac723c2e5a544aef8a94662e1b7f064c777442e9f69596d39152ace62a9a92fd8ca4c097448283bf5f57bbbafbad2c
6
+ metadata.gz: 2a1b935890e1563516cbb65aaa0f69bc35509a0f379fb0bfe7f9c4e221c26663573c22a6bcab5efdaf3c239f228c846d6465b5d8b5380f5a9f70b69f24c337f2
7
+ data.tar.gz: 2a0c18633011f2d16f5ac91985e2ed10e3fab325e143cd029258fb710c9cd6db3398a8160105584ff47f5a7f4e6c18f7e79e3756c9de607d112c905ecc72d4ae
@@ -109,8 +109,7 @@ module Api
109
109
  end
110
110
  process_response state
111
111
  rescue Exception => e
112
- logger.warn "Host discovery failed, facts: #{facts}"
113
- logger.debug e.message + "\n" + e.backtrace.join("\n")
112
+ Foreman::Logging.exception("Host discovery failed, facts: #{facts}", e)
114
113
  render :json => {'message'=>e.to_s}, :status => :unprocessable_entity
115
114
  end
116
115
 
@@ -6,7 +6,7 @@ module Foreman::Controller::DiscoveredExtensions
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
8
  # rule with *lower* priority wins (older wins for same priority)
9
- DiscoveryRule.where(:enabled => true).reorder(:priority, :created_at).each do |rule|
9
+ DiscoveryRule.where(:enabled => true).reorder(:priority).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}]"
@@ -7,7 +7,7 @@ class DiscoveredHostsController < ::ApplicationController
7
7
 
8
8
  before_action :find_by_name, :only => %w[edit update destroy refresh_facts convert reboot auto_provision]
9
9
  before_action :find_by_name_incl_subnet, :only => [:show]
10
- before_action :find_multiple, :only => [:multiple_destroy, :submit_multiple_destroy]
10
+ before_action :find_multiple, :only => [:multiple_destroy, :submit_multiple_destroy, :multiple_reboot, :submit_multiple_reboot, :multiple_auto_provision, :submit_multiple_auto_provision]
11
11
  before_action :taxonomy_scope, :only => [:edit]
12
12
 
13
13
  around_action :skip_bullet, :only => [:edit]
@@ -21,12 +21,12 @@ class DiscoveredHostsController < ::ApplicationController
21
21
  end
22
22
 
23
23
  def index
24
- @hosts = resource_base.search_for(params[:search], :order => params[:order]).includes([
24
+ @hosts = resource_base_search_and_page.includes([
25
25
  :location,
26
26
  :organization,
27
27
  :model,
28
28
  :discovery_attribute_set
29
- ], {:interfaces => :subnet}).paginate(:page => params[:page])
29
+ ], {:interfaces => :subnet})
30
30
  fact_array = @hosts.collect do |host|
31
31
  [host.id, Hash[host.fact_values.joins(:fact_name).where('fact_names.name' => Setting::Discovered.discovery_fact_column_array).pluck(:name, :value)]]
32
32
  end
@@ -54,10 +54,12 @@ class DiscoveredHostsController < ::ApplicationController
54
54
  end
55
55
 
56
56
  def edit
57
+ quick = params.delete(:quick_submit)
57
58
  @host = ::ForemanDiscovery::HostConverter.to_managed(@host, true, false, discovered_host_params_host) unless @host.nil?
58
59
  setup_host_class_variables
59
60
  @override_taxonomy = true
60
- if params[:quick_submit]
61
+ # need to permit this one but don't know how
62
+ if quick
61
63
  perform_update(@host, _('Successfully provisioned %s') % @host.name)
62
64
  else
63
65
  @host.build = true
@@ -69,6 +71,7 @@ class DiscoveredHostsController < ::ApplicationController
69
71
  @host = ::ForemanDiscovery::HostConverter.to_managed(@host, true, true, managed_host_params_host)
70
72
  forward_url_options
71
73
 
74
+ @override_taxonomy = true
72
75
  perform_update(@host)
73
76
  end
74
77
 
@@ -116,8 +119,8 @@ class DiscoveredHostsController < ::ApplicationController
116
119
  process_error :error_msg => exception.message, :redirect => :back
117
120
  end
118
121
 
119
- def reboot_all
120
- error_message = perform_reboot_all
122
+ def submit_multiple_reboot
123
+ error_message = perform_reboot_all(@hosts)
121
124
 
122
125
  if error_message
123
126
  process_error :error_msg => error_message, :redirect => :back
@@ -133,11 +136,17 @@ class DiscoveredHostsController < ::ApplicationController
133
136
  def multiple_destroy
134
137
  end
135
138
 
139
+ def multiple_reboot
140
+ end
141
+
142
+ def multiple_auto_provision
143
+ end
144
+
136
145
  def submit_multiple_destroy
137
146
  # keep all the ones that were not deleted for notification.
138
147
  missed_hosts = @hosts.select {|host| !host.destroy }
139
148
  if missed_hosts
140
- notice _("Destroyed selected hosts")
149
+ success _("Destroyed selected hosts")
141
150
  else
142
151
  error _("The following hosts were not deleted: %s") % missed_hosts
143
152
  end
@@ -158,7 +167,7 @@ class DiscoveredHostsController < ::ApplicationController
158
167
  end
159
168
  end
160
169
 
161
- def auto_provision_all
170
+ def submit_multiple_auto_provision
162
171
  result = true
163
172
  error_message = _("Errors during auto provisioning: %s")
164
173
 
@@ -168,7 +177,7 @@ class DiscoveredHostsController < ::ApplicationController
168
177
  end
169
178
 
170
179
  overall_errors = ""
171
- Host::Discovered.all.each do |discovered_host|
180
+ @hosts.each do |discovered_host|
172
181
  if rule = find_discovery_rule(discovered_host)
173
182
  result &= perform_auto_provision(discovered_host, rule)
174
183
  unless discovered_host.errors.empty?
@@ -259,11 +268,12 @@ class DiscoveredHostsController < ::ApplicationController
259
268
 
260
269
  def action_permission
261
270
  case params[:action]
262
- when 'refresh_facts', 'reboot', 'reboot_all', 'update_multiple_location', 'select_multiple_organization', 'update_multiple_organization', 'select_multiple_location'
271
+ when 'refresh_facts', 'reboot', 'multiple_reboot', 'update_multiple_location',
272
+ 'select_multiple_organization', 'update_multiple_organization', 'select_multiple_location', 'submit_multiple_reboot'
263
273
  :edit
264
274
  when 'submit_multiple_destroy', 'multiple_destroy'
265
275
  :destroy
266
- when 'auto_provision', 'auto_provision_all'
276
+ when 'auto_provision', 'multiple_auto_provision', 'submit_multiple_auto_provision'
267
277
  :auto_provision
268
278
  else
269
279
  super
@@ -11,7 +11,7 @@ module ForemanDiscovery
11
11
  # etc.. expect a params[:host] to work.
12
12
  def set_discovered_params
13
13
  return if params[:discovered_host].nil?
14
- params[:host] ||= params[:discovered_host]
14
+ params[:host] ||= params.delete(:discovered_host)
15
15
  end
16
16
  end
17
17
  end
@@ -19,10 +19,6 @@ module DiscoveredHostsHelper
19
19
  link_to(_("Back"), :back, :class => "btn btn-default")
20
20
  ),
21
21
  select_action_button( _("Select Action"), {}, provision_button(host, hash_for_edit_discovered_host_path(:id => host)), actions.map { |action| display_link_if_authorized(action[0] , action[1], action[2] || {}) }.flatten ),
22
- button_group(
23
- link_to(_("Expand All"),"#", :id => "expand_all", :class => "btn btn-default"
24
- )
25
- ),
26
22
  button_group(
27
23
  display_delete_if_authorized(hash_for_discovered_host_path(:id => host).merge(:auth_object => host, :permission => :destroy_discovered_hosts), :class => "btn btn-default", :data => { :confirm => _('Delete %s?') % host.name })
28
24
  )
@@ -30,9 +26,11 @@ module DiscoveredHostsHelper
30
26
  end
31
27
 
32
28
  def multiple_discovered_hosts_actions_select
33
- actions = [[_('Delete hosts'), multiple_destroy_discovered_hosts_path, hash_for_multiple_destroy_discovered_hosts_path]]
29
+ actions = [[_('Auto Provision'), multiple_auto_provision_discovered_hosts_path, hash_for_multiple_auto_provision_discovered_hosts_path]]
30
+ actions << [_('Reboot'), multiple_reboot_discovered_hosts_path, hash_for_multiple_reboot_discovered_hosts_path]
34
31
  actions << [_('Assign Organization'), select_multiple_organization_discovered_hosts_path, hash_for_select_multiple_organization_discovered_hosts_path] if SETTINGS[:organizations_enabled]
35
32
  actions << [_('Assign Location'), select_multiple_location_discovered_hosts_path, hash_for_select_multiple_location_discovered_hosts_path] if SETTINGS[:locations_enabled]
33
+ actions << [_('Delete'), multiple_destroy_discovered_hosts_path, hash_for_multiple_destroy_discovered_hosts_path]
36
34
 
37
35
  select_action_button( _("Select Action"), {:id => 'submit_multiple'},
38
36
  actions.map do |action|
@@ -56,17 +54,17 @@ module DiscoveredHostsHelper
56
54
 
57
55
  def discovery_status_icon(host)
58
56
  if host.created_at > 1.day.ago
59
- status_glyph = 'glyphicon-plus-sign'
57
+ status_glyph = 'pficon-on-running'
60
58
  status_message = _('New in the last 24 hours')
61
- status_color = '#89A54E'
59
+ status_color = '#0088ce'
62
60
  elsif host.last_report.present? && host.last_report < 7.days.ago
63
- status_glyph = 'glyphicon-exclamation-sign'
61
+ status_glyph = 'pficon-paused'
64
62
  status_message = _('Not reported in more than 7 days')
65
- status_color = '#AA4643'
63
+ status_color = '#ec7a08'
66
64
  else
67
- status_glyph = 'glyphicon-ok-sign'
65
+ status_glyph = 'pficon-on'
68
66
  status_message = _('Reported in the last 7 days')
69
- status_color = '#4572A7'
67
+ status_color = '#72767b'
70
68
  end
71
69
 
72
70
  "<span class='glyphicon #{status_glyph}' style='color: #{status_color}'
@@ -1,4 +1,5 @@
1
1
  class DiscoveryRule < ApplicationRecord
2
+ audited :associated_with => :hostgroup
2
3
  include Authorizable
3
4
  extend FriendlyId
4
5
  friendly_id :name
@@ -11,9 +12,11 @@ class DiscoveryRule < ApplicationRecord
11
12
  validates :hostname, :format => { :with => /\A[a-zA-Z<]/, :message => N_("must start with a letter or ERB.") },
12
13
  :allow_blank => true
13
14
  validates :hostgroup_id, :presence => true
15
+ validates :hostgroup, :presence => {:message => N_("must be present.")}
14
16
  validates :max_count, :numericality => { :only_integer => true, :greater_than_or_equal_to => 0, :less_than => 2**31 }
15
17
  validates :priority, :presence => true, :numericality => { :only_integer => true, :greater_than_or_equal_to => 0, :less_than => 2**31 }
16
18
  validates_lengths_from_database
19
+ validates_uniqueness_of :priority
17
20
  before_validation :default_int_attributes
18
21
  before_validation :enforce_taxonomy
19
22
 
@@ -1,16 +1,19 @@
1
1
  class Host::Discovered < ::Host::Base
2
+ audited :except => [:last_report]
3
+ has_associated_audits
4
+ # redefine audits relation because of the type change (by default the relation will look for auditable_type = 'Host::Managed')
5
+ has_many :audits, -> { where(:auditable_type => 'Host::Base') }, :foreign_key => :auditable_id, :class_name => 'Audited::Audit'
6
+
2
7
  include ScopedSearchExtensions
3
8
  include Foreman::Renderer
4
9
  include BelongsToProxies
5
10
  include ::Hostext::OperatingSystem
6
11
 
7
- belongs_to :hostgroup
8
- has_one :discovery_attribute_set, :foreign_key => :host_id, :dependent => :destroy
12
+ has_one :discovery_attribute_set, :foreign_key => :host_id, :dependent => :destroy
9
13
 
10
14
  validates :discovery_attribute_set, :presence => true
11
15
 
12
- delegate :memory, :cpu_count, :disk_count, :disks_size, :to => :discovery_attribute_set
13
- after_create :create_notification
16
+ delegate :memory, :cpu_count, :disk_count, :disks_size, :to => :discovery_attribute_set, :allow_nil => true
14
17
  after_destroy :delete_notification
15
18
 
16
19
  scoped_search :on => :name, :complete_value => true
@@ -39,6 +42,11 @@ class Host::Discovered < ::Host::Base
39
42
  where(taxonomy_conditions).order("hosts.created_at DESC")
40
43
  }
41
44
 
45
+ # Discovery import workflow:
46
+ # discovered#import_host ->
47
+ # discovered#import_facts -> base#import_facts -> base#parse_facts ->
48
+ # discovered#populate_fields_from_facts -> base#populate_fields_from_facts -> base#set_interfaces
49
+ # discovered#populate_discovery_fields_from_facts
42
50
  def self.import_host facts
43
51
  raise(::Foreman::Exception.new(N_("Invalid facts, must be a Hash"))) unless facts.is_a?(Hash) || facts.is_a?(ActionController::Parameters)
44
52
 
@@ -56,16 +64,25 @@ class Host::Discovered < ::Host::Base
56
64
  hostname = normalize_string_for_hostname("#{hostname_prefix}#{name_fact}")
57
65
  Rails.logger.warn "Hostname does not start with an alphabetical character" unless hostname.downcase.match(/^[a-z]/)
58
66
 
59
- # find existing or create new host record
67
+ # check for existing managed hosts and fail or warn
60
68
  bootif_mac = FacterUtils::bootif_mac(facts).try(:downcase)
61
- hosts = ::Nic::Managed.where(:mac => bootif_mac, :primary => true)
62
- if hosts.empty?
69
+ existing_managed = Nic::Managed.joins(:host).where(:mac => bootif_mac, :provision => true, :hosts => {:type => "Host::Managed"}).limit(1)
70
+ if existing_managed.count > 0
71
+ if Setting[:discovery_error_on_existing]
72
+ raise ::Foreman::Exception.new("One or more existing managed hosts found: %s", "#{existing_managed.first.name}/#{bootif_mac}")
73
+ else
74
+ Rails.logger.warn("One or more existing managed hosts found: #{existing_managed.first.name}/#{bootif_mac}")
75
+ end
76
+ end
77
+
78
+ # find existing discovered host (pick the oldest if multiple) or create new discovery host record
79
+ existing_discovery_hosts = Nic::Managed.joins(:host).where(:mac => bootif_mac, :provision => true, :hosts => {:type => "Host::Discovered"}).order('created_at DESC')
80
+ if existing_discovery_hosts.empty?
63
81
  host = Host.new(:name => hostname, :type => "Host::Discovered")
64
82
  else
65
- Rails.logger.warn "Multiple discovered hosts found with MAC address #{name_fact}, choosing one" if hosts.size > 1
66
- host = hosts.first.host
83
+ Rails.logger.warn "Multiple (#{existing_discovery_hosts.count}) discovery hosts found with MAC address #{name_fact} - picking most recent NIC entry" if existing_discovery_hosts.count > 1
84
+ host = existing_discovery_hosts.first.host
67
85
  end
68
- raise ::Foreman::Exception.new("Host already exists as managed: %s", "#{host.name}/#{bootif_mac}") if host.type != "Host::Discovered"
69
86
 
70
87
  # and save (interfaces are created via puppet parser extension)
71
88
  host.save(:validate => false) if host.new_record?
@@ -105,10 +122,14 @@ class Host::Discovered < ::Host::Base
105
122
  end
106
123
 
107
124
  populate_discovery_fields_from_facts(facts)
125
+ create_notification
108
126
  parser
109
127
  end
110
128
 
111
129
  def populate_discovery_fields_from_facts(facts)
130
+ # set discovery search attributes first
131
+ self.discovery_attribute_set = DiscoveryAttributeSet.where(:host_id => id).first_or_create
132
+ self.discovery_attribute_set.update_attributes(import_from_facts)
112
133
  # set additional discovery attributes
113
134
  primary_ip = self.primary_interface.ip
114
135
  unless primary_ip.nil?
@@ -136,12 +157,12 @@ class Host::Discovered < ::Host::Base
136
157
  Rails.logger.info "Assigned organization: #{self.organization}"
137
158
  end
138
159
  else
139
- raise(::Foreman::Exception.new(N_("Unable to assign subnet, primary interface is missing IP address")))
160
+ Rails.logger.warn "Unable to assign subnet - reboot trigger may not be possible, primary interface is missing IP address"
140
161
  end
141
- self.discovery_attribute_set = DiscoveryAttributeSet.where(:host_id => id).first_or_create
142
- self.discovery_attribute_set.update_attributes(import_from_facts)
162
+
143
163
  # lock the host into discovery via PXE, if feature is enabled in settings
144
164
  lock_templates if Setting::Discovered.discovery_lock? && self.subnet.tftp?
165
+ ensure
145
166
  self.save!
146
167
  end
147
168
 
@@ -174,11 +195,6 @@ class Host::Discovered < ::Host::Base
174
195
  {:cpu_count => cpu_count, :memory => memory, :disk_count => disk_count, :disks_size => disks_size}
175
196
  end
176
197
 
177
- # no need to store anything in the db if the password is our default
178
- def root_pass
179
- read_attribute(:root_pass).blank? ? (hostgroup.try(:root_pass) || Setting[:root_pass]) : read_attribute(:root_pass)
180
- end
181
-
182
198
  def proxied?
183
199
  subnet.present? && subnet.discovery.present?
184
200
  end
@@ -196,7 +212,7 @@ class Host::Discovered < ::Host::Base
196
212
  raise ::Foreman::WrappedException.new(e, N_("Could not get facts from proxy %{url}: %{error}"), :url => proxy_url, :error => e)
197
213
  end
198
214
 
199
- def reboot
215
+ def reboot
200
216
  resource = ::ForemanDiscovery::NodeAPI::Power.service(:url => proxy_url)
201
217
  resource.reboot
202
218
  rescue => e
@@ -247,4 +263,28 @@ class Host::Discovered < ::Host::Base
247
263
  def delete_notification
248
264
  ForemanDiscovery::UINotifications::DestroyHost.deliver!(self)
249
265
  end
266
+
267
+ def notification_recipients_ids
268
+ org_recipients = find_organization_users if Taxonomy.organizations_enabled
269
+ org_recipients ||= []
270
+
271
+ admins = User.unscoped.only_admin.except_hidden.
272
+ reorder('').distinct.pluck(:id)
273
+ (org_recipients + admins).uniq
274
+ end
275
+
276
+ private
277
+
278
+ def find_organization_users
279
+ return [] unless organization.present?
280
+ organization_users = if organization.ignore_types.include? 'User'
281
+ User.unscoped.all
282
+ else
283
+ organization.users
284
+ end
285
+
286
+ organization_users.find_all do |user|
287
+ user.can? :create_hosts
288
+ end.pluck(:id)
289
+ end
250
290
  end
@@ -34,6 +34,7 @@ class Setting::Discovered < ::Setting
34
34
  self.set('discovery_pxegrub_lock_template', N_("PXEGrub template to be used when pinning a host to discovery"), 'pxegrub_discovery', N_("Locked PXEGrub template name"), nil, { :collection => Proc.new {Hash[ProvisioningTemplate.where(:template_kind => TemplateKind.find_by_name(:snippet)).map{|template| [template[:name], template[:name]]}]} }),
35
35
  self.set('discovery_pxegrub2_lock_template', N_("PXEGrub2 template to be used when pinning a host to discovery"), 'pxegrub2_discovery', N_("Locked PXEGrub2 template name"), nil, { :collection => Proc.new {Hash[ProvisioningTemplate.where(:template_kind => TemplateKind.find_by_name(:snippet)).map{|template| [template[:name], template[:name]]}]} }),
36
36
  self.set('discovery_always_rebuild_dns', N_("Force DNS entries creation when provisioning discovered host"), true, N_("Force DNS")),
37
+ self.set('discovery_error_on_existing', N_("Do not allow to discover existing managed host matching MAC of a provisioning NIC (errors out early)"), false, N_("Error on existing NIC")),
37
38
  ].compact.each { |s| self.create s.update(:category => "Setting::Discovered")}
38
39
  end
39
40
 
@@ -1,12 +1,16 @@
1
1
  module ForemanDiscovery
2
2
  class FactParser < ::PuppetFactParser
3
3
  def suggested_primary_interface(host)
4
- raise("Discovery fact parser does not work with non-discovery host #{host}") if host.type != "Host::Discovered"
4
+ raise(::Foreman::Exception.new(N_("Discovery fact parser does not work with non-discovery host '%{host}'") %
5
+ {:host => host})) if host.type != "Host::Discovered"
6
+ raise(::Foreman::Exception.new(N_("Discovered host '%{host}' has all NICs filtered out, filter: %{filter}") %
7
+ {:host => host, :filter => Setting[:ignored_interface_identifiers]})) if interfaces.size == 0
5
8
  bootif_mac = FacterUtils::bootif_mac(facts).try(:downcase)
6
9
  detected = interfaces.detect { |_, values| values[:macaddress].try(:downcase) == bootif_mac }
7
10
  Rails.logger.debug "Discovery fact parser detected primary interface: #{detected}"
8
11
  # return the detected interface as array [name, facts]
9
- 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}))
12
+ detected || raise(::Foreman::Exception.new(N_("Unable to find primary NIC with %{mac} specified via '%{fact}', NIC filter: %{filter}") %
13
+ {:mac => bootif_mac, :fact => FacterUtils::bootif_name, :filter => Setting[:ignored_interface_identifiers]}))
10
14
  end
11
15
 
12
16
  def parse_interfaces?
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ForemanDiscovery
2
3
  module UINotifications
3
4
  # Adds notification upon newly discovered Hosts
@@ -17,7 +18,8 @@ module ForemanDiscovery
17
18
  def add_notification
18
19
  Notification.create!(
19
20
  initiator: initiator,
20
- audience: ::Notification::AUDIENCE_ADMIN,
21
+ audience: ::Notification::AUDIENCE_SUBJECT,
22
+ subject: subject,
21
23
  notification_blueprint: blueprint
22
24
  )
23
25
  end
@@ -1,4 +1,4 @@
1
- <table class="table table-striped table-fixed">
1
+ <table class="<%= table_css_classes('table-fixed') %>">
2
2
  <thead>
3
3
  <th width="30%"><%= _('Host') %></th>
4
4
  <th class="hidden-tablet hidden-xs"><%= _('Model') %></th>
@@ -1,6 +1,6 @@
1
1
  <%= javascript "host_checkbox" %>
2
2
  <% title _('Discovered Hosts') %>
3
- <table class="table table-bordered table-striped table-condensed" >
3
+ <table class="<%= table_css_classes('table-condensed') %>" >
4
4
  <tr>
5
5
  <th class="ca"><%= check_box_tag "check_all", "", false, { :onclick => "toggleCheck()", :'check-title' => _("Select all items in this page"), :'uncheck-title'=> _("items selected. Uncheck to Clear") } %></th>
6
6
  <th class=''><%= sort :name, :as => _('Name') %></th>
@@ -70,5 +70,4 @@
70
70
  </div><!-- /.modal-dialog -->
71
71
  </div><!-- /.modal -->
72
72
 
73
- <%= page_entries_info @hosts %>
74
- <%= will_paginate @hosts %>
73
+ <%= will_paginate_with_info @hosts %>
@@ -1,7 +1,7 @@
1
1
  <div class="row">
2
2
  <div class="col-md-12">
3
3
 
4
- <table class="table table-bordered table-striped">
4
+ <table class="<%= table_css_classes %>">
5
5
  <thead>
6
6
  <tr>
7
7
  <th><%= _('Name') %></th>
@@ -1,4 +1,2 @@
1
1
  <% title_actions multiple_discovered_hosts_actions_select -%>
2
- <% title_actions display_link_if_authorized(_("Reboot All"), hash_for_reboot_all_discovered_hosts_path, {:class => 'btn btn-default', :method => :put, :disabled => @hosts.empty?}) %>
3
- <% title_actions display_link_if_authorized(_("Auto Provision All"), hash_for_auto_provision_all_discovered_hosts_path, {:class => 'btn btn-default', :method => :post, :disabled => @hosts.empty?}) %>
4
2
  <%= render 'discovered_hosts_list' %>