foreman_discovery 16.3.6 → 17.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/api/v2/discovered_hosts_controller.rb +1 -0
  3. data/app/controllers/discovered_hosts_controller.rb +24 -35
  4. data/app/controllers/discovery_rules_controller.rb +12 -1
  5. data/app/helpers/discovered_hosts_helper.rb +1 -1
  6. data/app/helpers/discovery_rules_helper.rb +1 -0
  7. data/app/models/discovery_rule.rb +10 -5
  8. data/app/services/foreman_discovery/fact_to_category_resolver.rb +106 -0
  9. data/app/services/foreman_discovery/ui_notifications/failed_discovery.rb +34 -0
  10. data/app/services/foreman_discovery/ui_notifications/new_host.rb +2 -1
  11. data/app/views/discovered_hosts/_discovered_hosts_list.html.erb +44 -40
  12. data/app/views/discovery_rules/clone.erb +3 -0
  13. data/app/views/discovery_rules/index.html.erb +4 -0
  14. data/app/views/discovery_rules/welcome.html.erb +15 -0
  15. data/app/views/foreman_discovery/debian_kexec.erb +1 -1
  16. data/app/views/foreman_discovery/redhat_kexec.erb +1 -1
  17. data/config/routes.rb +2 -0
  18. data/db/seeds.d/80_discovery_ui_notification.rb +11 -5
  19. data/lib/foreman_discovery/engine.rb +3 -7
  20. data/lib/foreman_discovery/version.rb +1 -1
  21. data/locale/ca/LC_MESSAGES/foreman_discovery.mo +0 -0
  22. data/locale/ca/foreman_discovery.po +36 -9
  23. data/locale/de/LC_MESSAGES/foreman_discovery.mo +0 -0
  24. data/locale/de/foreman_discovery.po +45 -18
  25. data/locale/en/LC_MESSAGES/foreman_discovery.mo +0 -0
  26. data/locale/en/foreman_discovery.po +31 -4
  27. data/locale/en_GB/LC_MESSAGES/foreman_discovery.mo +0 -0
  28. data/locale/en_GB/foreman_discovery.po +36 -9
  29. data/locale/es/LC_MESSAGES/foreman_discovery.mo +0 -0
  30. data/locale/es/foreman_discovery.po +70 -41
  31. data/locale/foreman_discovery.pot +142 -97
  32. data/locale/fr/LC_MESSAGES/foreman_discovery.mo +0 -0
  33. data/locale/fr/foreman_discovery.po +76 -49
  34. data/locale/gl/LC_MESSAGES/foreman_discovery.mo +0 -0
  35. data/locale/gl/foreman_discovery.po +32 -5
  36. data/locale/it/LC_MESSAGES/foreman_discovery.mo +0 -0
  37. data/locale/it/foreman_discovery.po +44 -17
  38. data/locale/ja/LC_MESSAGES/foreman_discovery.mo +0 -0
  39. data/locale/ja/foreman_discovery.po +79 -54
  40. data/locale/ko/LC_MESSAGES/foreman_discovery.mo +0 -0
  41. data/locale/ko/foreman_discovery.po +43 -16
  42. data/locale/pt_BR/LC_MESSAGES/foreman_discovery.mo +0 -0
  43. data/locale/pt_BR/foreman_discovery.po +69 -39
  44. data/locale/ru/LC_MESSAGES/foreman_discovery.mo +0 -0
  45. data/locale/ru/foreman_discovery.po +43 -16
  46. data/locale/sv_SE/LC_MESSAGES/foreman_discovery.mo +0 -0
  47. data/locale/sv_SE/foreman_discovery.po +34 -7
  48. data/locale/zh_CN/LC_MESSAGES/foreman_discovery.mo +0 -0
  49. data/locale/zh_CN/foreman_discovery.po +114 -90
  50. data/locale/zh_TW/LC_MESSAGES/foreman_discovery.mo +0 -0
  51. data/locale/zh_TW/foreman_discovery.po +43 -16
  52. data/package.json +6 -6
  53. data/test/functional/api/v2/discovered_hosts_controller_test.rb +9 -0
  54. data/test/functional/discovery_rules_controller_test.rb +6 -1
  55. data/test/integration/discovered_hosts_test.rb +53 -5
  56. data/test/test_helper_discovery.rb +5 -0
  57. data/test/unit/discovery_rule_test.rb +24 -2
  58. data/test/unit/fact_to_category_resolver_test.rb +41 -0
  59. data/test/unit/ui_notifications/destroy_host_test.rb +2 -9
  60. data/test/unit/ui_notifications/new_host_test.rb +3 -3
  61. data/webpack/__mocks__/foremanReact/common/I18n.js +3 -0
  62. data/webpack/__mocks__/foremanReact/common/helpers.js +1 -0
  63. data/webpack/__mocks__/foremanReact/common/index.js +5 -0
  64. data/webpack/__mocks__/foremanReact/components/common/EmptyState/DefaultEmptyState.js +69 -0
  65. data/webpack/__mocks__/foremanReact/components/common/EmptyState/EmptyStatePattern.js +77 -0
  66. data/webpack/__mocks__/foremanReact/components/common/EmptyState/EmptyStatePropTypes.js +29 -0
  67. data/webpack/__mocks__/foremanReact/components/common/EmptyState/index.js +5 -0
  68. data/webpack/index.js +9 -8
  69. data/webpack/src/ForemanDiscovery/DiscoveredHosts/Components/EmptyState/EmptyState.js +7 -7
  70. data/webpack/src/ForemanDiscovery/DiscoveredHosts/Components/EmptyState/__test__/EmptyState.test.js +12 -0
  71. data/webpack/src/ForemanDiscovery/DiscoveredHosts/Components/EmptyState/__test__/__snapshots__/EmptyState.test.js.snap +16 -0
  72. data/webpack/src/ForemanDiscovery/DiscoveredHosts/Components/EmptyState/index.js +1 -1
  73. data/webpack/src/ForemanDiscovery/DiscoveredHosts/index.js +3 -3
  74. data/webpack/src/ForemanDiscovery/DiscoveryRules/Components/EmptyState/EmptyState.js +34 -0
  75. data/webpack/src/ForemanDiscovery/DiscoveryRules/Components/EmptyState/index.js +1 -0
  76. data/webpack/src/ForemanDiscovery/DiscoveryRules/Components/__test__/EmptyState.test.js +19 -0
  77. data/webpack/src/ForemanDiscovery/DiscoveryRules/Components/__test__/__snapshots__/EmptyState.test.js.snap +22 -0
  78. data/webpack/src/ForemanDiscovery/DiscoveryRules/index.js +6 -0
  79. data/webpack/src/reducers.js +0 -2
  80. metadata +25 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5404d1b999eff25f29e39cf14d77a7e85473e29a50a677ac3254aadfd1bc53a4
4
- data.tar.gz: 803b2278dd981b8123cd88593f7fb00fd974b69711e848da60f31fd85dabbb90
3
+ metadata.gz: 72a3be5def914f11b7186ee0dee5289a2ab43d7294404843736dd3097af42a82
4
+ data.tar.gz: 3bc20158d91425e487c81b115230c09b6a7d40bfaf604149e429f2e485cf0f04
5
5
  SHA512:
6
- metadata.gz: b4d290ab7aeb3cd8ed2254159ccead4c2ad69138b68e3758c9724e9eac5e99cfefcc654af9a12dda964201cca307f87f161682000f878a70dbcb1241996a57ad
7
- data.tar.gz: 6398fa38e8625aee40bc6bc4ea387cced9ee50eba1e06fcdd711256e587f96c3d4d782738fd3efaf5b3bc0a3c2330f0f733088fdc5f8eafa8e3360a8bdeaea09
6
+ metadata.gz: bf1f325066358628d3d0682efe0819cb7e3511b175bb709d97a8c977cf4cd77d49648730dc6bf98749d317adb01e404baacd5995b0c88d9d6bda44c4e715e952
7
+ data.tar.gz: 14197db5b6c073d1b1a490cb06a226687a38b3cb73db4c48c900848df986325ce0204c6d4f0bf95eb1eab27a363591bb8cda50ab6e0f75a62833a69dbc48ab19
@@ -122,6 +122,7 @@ module Api
122
122
  end
123
123
  process_response state
124
124
  rescue Exception => e
125
+ ForemanDiscovery::UINotifications::FailedDiscovery.new(e).deliver!
125
126
  Foreman::Logging.exception("Host discovery failed, facts: #{facts}", e)
126
127
  render :json => {'message'=>e.to_s}, :status => :unprocessable_entity
127
128
  end
@@ -9,6 +9,7 @@ class DiscoveredHostsController < ::ApplicationController
9
9
  before_action :find_by_name_incl_subnet, :only => [:show]
10
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
+ before_action :check_for_subnet, :only => [:reboot, :auto_provision, :submit_multiple_reboot, :submit_multiple_auto_provision]
12
13
 
13
14
  around_action :skip_bullet, :only => [:edit]
14
15
 
@@ -38,14 +39,10 @@ class DiscoveredHostsController < ::ApplicationController
38
39
  @range = nil
39
40
  # summary report text
40
41
  @report_summary = nil
41
- init_regex_and_categories
42
- @interfaces = []
43
- get_interfaces
44
- @host.facts_hash.each do |key, value|
45
- value = number_to_human_size(value) if /size$/.match(key)
46
- assign_fact_to_category(key, value)
47
- end
48
- add_custom_facts
42
+ resolver = ForemanDiscovery::FactToCategoryResolver.new(@host)
43
+ @categories_names = ForemanDiscovery::FactToCategoryResolver::CATEGORIES_NAMES
44
+ @categories = resolver.categories
45
+ @interfaces = resolver.interfaces
49
46
  end
50
47
 
51
48
  def destroy
@@ -214,33 +211,6 @@ class DiscoveredHostsController < ::ApplicationController
214
211
  end
215
212
  end
216
213
 
217
- def init_regex_and_categories
218
- hightlights = Setting[:discovery_facts_highlights].empty? ? /^(productname|memorysize|manufacturer|architecture|macaddress$|processorcount|physicalprocessorcount|discovery_subnet|discovery_boot|ipaddress$)/ : Regexp.new(Setting[:discovery_facts_highlights])
219
- storage = Setting[:discovery_facts_storage].empty? ? /^blockdevice/ : Regexp.new(Setting[:discovery_facts_storage])
220
- hardware = Setting[:discovery_facts_hardware].empty? ? /^(hardw|manufacturer|memo|process)/ : Regexp.new(Setting[:discovery_facts__hardware])
221
- network = Setting[:discovery_facts_network].empty? ? /^(interfaces|dhcp|fqdn|hostname)/ : Regexp.new(Setting[:discovery_facts_network])
222
- software = Setting[:discovery_facts_software].empty? ? /^(bios|os|discovery)/ : Regexp.new(Setting[:discovery_facts_software])
223
- ipmi = Setting[:discovery_facts_ipmi].empty? ? /^ipmi/ : Regexp.new(Setting[:discovery_facts_ipmi])
224
- @regex_array = [hightlights, storage, hardware, network, software, ipmi, false]
225
- @categories = Array.new(7) { Hash.new }
226
- @categories_names = [N_("Highlights"), N_("Storage"), N_("Hardware"), N_("Network"), N_("Software"), N_("IPMI"), N_("Miscellaneous")]
227
- end
228
-
229
- def assign_fact_to_category(key, value)
230
- if @interfaces.any? {|interface| key.include? interface[:identifier]}
231
- @categories[3][key] = value
232
- return
233
- end
234
- @regex_array.each_with_index do |regex, index|
235
- if !regex
236
- @categories[index][key] = value
237
- elsif regex.match key
238
- @categories[index][key] = value
239
- break
240
- end
241
- end
242
- end
243
-
244
214
  def resource_base
245
215
  @resource_base ||= ::Host::Discovered.authorized(current_permission, ::Host::Discovered)
246
216
  end
@@ -292,6 +262,21 @@ class DiscoveredHostsController < ::ApplicationController
292
262
  @host
293
263
  end
294
264
 
265
+ def check_for_subnet
266
+ hosts_without_subnet = []
267
+ case params[:action]
268
+ when 'reboot', 'auto_provision'
269
+ if @host.subnet.nil?
270
+ process_warning :warning_msg => _("Discovered host reported from unknown subnet, communication will not be proxied.")
271
+ end
272
+ when 'submit_multiple_reboot', 'submit_multiple_auto_provision'
273
+ hosts_without_subnet = @hosts.limit(3).select { |host| host.subnet.nil? }.pluck(:name)
274
+ if hosts_without_subnet.present?
275
+ process_warning :warning_msg => _("Discovered hosts reported from unknown subnet are %s, communication will not be proxied.") % hosts_without_subnet.join(', ')
276
+ end
277
+ end
278
+ end
279
+
295
280
  def find_by_name_incl_subnet
296
281
  find_by_name({:interfaces => :subnet})
297
282
  end
@@ -347,4 +332,8 @@ class DiscoveredHostsController < ::ApplicationController
347
332
  assign_fact_to_category("discovery_subnet", discovery_subnet)
348
333
  end
349
334
  end
335
+
336
+ def process_warning(hash = {})
337
+ warning hash[:warning_msg]
338
+ end
350
339
  end
@@ -4,7 +4,11 @@ class DiscoveryRulesController < ApplicationController
4
4
 
5
5
  include Foreman::Controller::Parameters::DiscoveryRule
6
6
 
7
- before_action :find_resource, :only => [:edit, :update, :destroy, :enable, :disable, :auto_provision]
7
+ before_action :find_resource, :only => [:edit, :update, :destroy, :enable, :disable, :auto_provision, :clone]
8
+
9
+ def model_of_controller
10
+ DiscoveryRule
11
+ end
8
12
 
9
13
  def index
10
14
  base = resource_base.search_for(params[:search], :order => (params[:order]))
@@ -15,6 +19,11 @@ class DiscoveryRulesController < ApplicationController
15
19
  @discovery_rule = DiscoveryRule.new(:priority => DiscoveryRule.suggest_priority)
16
20
  end
17
21
 
22
+ def clone
23
+ @discovery_rule = @discovery_rule.deep_clone except: [:name, :priority]
24
+ @discovery_rule.priority = DiscoveryRule.suggest_priority
25
+ end
26
+
18
27
  def create
19
28
  @discovery_rule = DiscoveryRule.new(discovery_rule_params)
20
29
  if @discovery_rule.save
@@ -55,6 +64,8 @@ class DiscoveryRulesController < ApplicationController
55
64
 
56
65
  def action_permission
57
66
  case params[:action]
67
+ when 'clone'
68
+ :create
58
69
  when 'enable', 'disable'
59
70
  :edit
60
71
  else
@@ -7,7 +7,7 @@ module DiscoveredHostsHelper
7
7
  end
8
8
 
9
9
  def disc_report_column(record)
10
- record.last_report? ? (_("%s ago") % time_ago_in_words(record.last_report.getlocal)) : ""
10
+ record.last_report? ? date_time_relative(record.last_report.getlocal) : ""
11
11
  end
12
12
 
13
13
  def discovered_hosts_title_actions(host)
@@ -30,6 +30,7 @@ module DiscoveryRulesHelper
30
30
  else
31
31
  actions << display_link_if_authorized(_('Enable'), hash_for_enable_discovery_rule_path(:id => rule).merge(:auth_object => rule, :authorizer => authorizer), :data => { :confirm => _("Enable rule '%s'?") % rule })
32
32
  end
33
+ actions << display_link_if_authorized(_("Clone"), hash_for_clone_discovery_rule_path(id: rule).merge(auth_object: rule, authorizer: authorizer))
33
34
  actions << display_delete_if_authorized(hash_for_discovery_rule_path(:id => rule).merge(:auth_object => rule, :authorizer => authorizer), :data => { :confirm => _("Delete rule '%s'?") % rule })
34
35
  end
35
36
  end
@@ -17,7 +17,6 @@ class DiscoveryRule < ApplicationRecord
17
17
  validates :max_count, :numericality => { :only_integer => true, :greater_than_or_equal_to => 0, :less_than => 2**31 }
18
18
  validates :priority, :presence => true, :numericality => { :only_integer => true, :greater_than_or_equal_to => 0, :less_than => 2**31 }
19
19
  validates_lengths_from_database
20
- validates_uniqueness_of :priority
21
20
  before_validation :default_int_attributes
22
21
  before_validation :enforce_taxonomy
23
22
 
@@ -41,19 +40,25 @@ class DiscoveryRule < ApplicationRecord
41
40
  self.priority ||= 0
42
41
  end
43
42
 
44
- def self.suggest_priority
45
- self.unscoped.maximum(:priority).to_i + STEP
43
+ def self.suggest_priority(organization = Organization.current)
44
+ discovery_rules = DiscoveryRule.unscoped
45
+ return (discovery_rules.maximum(:priority).to_i + STEP) if organization.nil?
46
+ discovery_rule_ids = TaxableTaxonomy.where(
47
+ taxable_type: 'DiscoveryRule',
48
+ taxonomy_id: organization.id).pluck(:taxable_id)
49
+ discovery_rules = discovery_rules.where(id: discovery_rule_ids)
50
+ discovery_rules.maximum(:priority).to_i + STEP
46
51
  end
47
52
 
48
53
  def enforce_taxonomy
49
54
  return if hostgroup.nil?
50
55
  unless (ms = hostgroup.organizations - organizations).empty?
51
56
  names = ms.collect(&:name).to_sentence
52
- 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)
57
+ errors.add(:base, 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)
53
58
  end
54
59
  unless (ms = hostgroup.locations - locations).empty?
55
60
  names = ms.collect(&:name).to_sentence
56
- 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)
61
+ errors.add(:base, 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)
57
62
  end
58
63
  end
59
64
  end
@@ -0,0 +1,106 @@
1
+ module ForemanDiscovery
2
+ class FactToCategoryResolver
3
+ include ActionView::Helpers::NumberHelper
4
+
5
+ attr_reader :categories, :interfaces
6
+
7
+ CATEGORIES_NAMES = [N_("Highlights"),
8
+ N_("Storage"),
9
+ N_("Hardware"),
10
+ N_("Network"),
11
+ N_("Software"),
12
+ N_("IPMI"),
13
+ N_("Miscellaneous")].freeze
14
+
15
+ def initialize(host)
16
+ categories = %i[highlights storage hardware network software ipmi]
17
+
18
+ @regex_array = categories.map do |category|
19
+ settings_category = settings_discovery_fact_prefix(category)
20
+ if settings_category.empty?
21
+ send(category)
22
+ else
23
+ Regexp.new(settings_category)
24
+ end
25
+ end
26
+
27
+ @regex_array << false
28
+
29
+ @categories = []
30
+
31
+ @interfaces = host.interfaces.map do |interface|
32
+ {
33
+ identifier: interface["identifier"],
34
+ type: interface["type"],
35
+ mac: interface["mac"],
36
+ ip: interface["ip"] || "N/A",
37
+ primary: interface["primary"],
38
+ provision: interface["provision"],
39
+ }
40
+ end
41
+
42
+ assign_facts(host)
43
+ end
44
+
45
+ private
46
+
47
+ def assign_facts(host)
48
+ host.facts_hash.each do |key, value|
49
+ value = number_to_human_size(value) if /size$/.match(key)
50
+ assign_fact_to_category(key, value)
51
+ end
52
+
53
+ return if host.primary_interface.subnet.nil?
54
+
55
+ discovery_subnet = "#{host.primary_interface.subnet.name} (#{host.primary_interface.subnet.network})"
56
+ assign_fact_to_category("discovery_subnet", discovery_subnet)
57
+ end
58
+
59
+ def assign_fact_to_category(key, value)
60
+ if @interfaces.any? { |interface| key.include? interface[:identifier] }
61
+ @categories[3] = {} if @categories[3].nil?
62
+ @categories[3][key] = value
63
+ return
64
+ end
65
+
66
+ @regex_array.each_with_index do |regex, index|
67
+ @categories[index] = {} if @categories[index].nil?
68
+ if !regex
69
+ @categories[index][key] = value
70
+ elsif regex.match key
71
+ @categories[index][key] = value
72
+ break
73
+ end
74
+ end
75
+ end
76
+
77
+ def highlights
78
+ /^(productname|memorysize|manufacturer|architecture|macaddress$|processorcount|physicalprocessorcount|discovery_subnet|discovery_boot|ipaddress$)/
79
+ end
80
+
81
+ def storage
82
+ /^blockdevice/
83
+ end
84
+
85
+ def hardware
86
+ /^(hardw|manufacturer|memo|process)/
87
+ end
88
+
89
+ def network
90
+ /^(interfaces|dhcp|fqdn|hostname)/
91
+ end
92
+
93
+ def software
94
+ /^(bios|os|discovery)/
95
+ end
96
+
97
+ def ipmi
98
+ /^ipmi/
99
+ end
100
+
101
+ def settings_discovery_fact_prefix(name)
102
+ Setting["discovery_facts_#{name}".to_sym]
103
+ end
104
+ end
105
+ end
106
+
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+ module ForemanDiscovery
3
+ module UINotifications
4
+ # Adds notification upon failed discovery
5
+ class FailedDiscovery < ::UINotifications::Base
6
+ def initialize(message)
7
+ @message = message
8
+ end
9
+
10
+ private
11
+
12
+ def create
13
+ add_notification if update_notifications.zero?
14
+ end
15
+
16
+ def update_notifications
17
+ blueprint.mass_update_expiry
18
+ end
19
+
20
+ def add_notification
21
+ Notification.create!(
22
+ initiator: initiator,
23
+ audience: ::Notification::AUDIENCE_ADMIN,
24
+ message: _("One or more hosts with failed discovery due to error: #{@message}"),
25
+ notification_blueprint: blueprint,
26
+ )
27
+ end
28
+
29
+ def blueprint
30
+ @blueprint ||= NotificationBlueprint.find_by(name: 'failed_discovery')
31
+ end
32
+ end
33
+ end
34
+ end
@@ -8,7 +8,7 @@ module ForemanDiscovery
8
8
  private
9
9
 
10
10
  def create
11
- add_notification if update_notifications.zero?
11
+ add_notification
12
12
  end
13
13
 
14
14
  def update_notifications
@@ -19,6 +19,7 @@ module ForemanDiscovery
19
19
  Notification.create!(
20
20
  initiator: initiator,
21
21
  audience: ::Notification::AUDIENCE_SUBJECT,
22
+ message: _("Host %s has been dicovered") % subject.name,
22
23
  subject: subject,
23
24
  notification_blueprint: blueprint
24
25
  )
@@ -1,47 +1,51 @@
1
1
  <% title _('Discovered Hosts') %>
2
2
  <table class="<%= table_css_classes('table-condensed') %>" >
3
- <tr>
4
- <th class="ca"><%= check_box_tag "check_all", "", false, { :onclick => "tfm.hosts.table.toggleCheck()", :'check-title' => _("Select all items in this page"), :'uncheck-title'=> _("items selected. Uncheck to Clear") } %></th>
5
- <th class=''><%= sort :name, :as => _('Name') %></th>
6
- <th class="hidden-tablet hidden-xs"><%= sort :model, :as => _('Model') %></th>
7
- <th class="hidden-tablet hidden-xs"><%= sort :ip, :as => _('IP Address') %></th>
8
- <th class="hidden-tablet hidden-xs"><%= sort :cpu_count, :as => _('CPUs') %></th>
9
- <th class="hidden-tablet hidden-xs"><%= sort :memory, :as => _('Memory') %></th>
10
- <th class="hidden-tablet hidden-xs"><%= sort :disk_count, :as => _('Disk Count') %></th>
11
- <th class="hidden-tablet hidden-xs"><%= sort :disks_size, :as => _('Disks Size') %></th>
12
- <% Setting::Discovered.discovery_fact_column_array.each do |fact_column| %>
13
- <th class="hidden-tablet hidden-xs"><%= fact_column.capitalize %></th>
14
- <% end %>
15
- <th class="hidden-tablet hidden-xs"><%= sort :location, :as => _('Location') %></th>
16
- <th class="hidden-tablet hidden-xs"><%= sort :organization, :as => _('Organization') %></th>
17
- <th class="hidden-tablet hidden-xs"><%= sort :subnet, :as => _("Subnet") %></th>
18
- <th class="hidden-tablet hidden-xs"><%= sort :last_report, :as => _("Last Facts Upload") %></th>
19
- <th class="hidden-tablet hidden-xs"><%= _("Actions") %></th>
20
- </tr>
21
- <% @hosts.each do |host| -%>
3
+ <thead>
22
4
  <tr>
23
- <td class="ca">
24
- <%= check_box_tag "host_ids[]", nil, false, :id => "host_ids_#{host.id}", :disabled => !authorized_for_edit_destroy?, :class => 'host_select_boxes', :onclick => 'tfm.hosts.table.hostChecked(this)' -%>
25
- </td>
26
- <%= render :partial => "discovered_host", :locals => {:host => host} %>
27
- <td class="hidden-tablet hidden-xs"><%= host.location.try(:title) %></td>
28
- <td class="hidden-tablet hidden-xs"><%= host.organization.try(:title) %></td>
29
- <td class="hidden-tablet hidden-xs"><%= host.primary_interface.try(:subnet).try(:to_label) %></td>
30
- <td class="hidden-tablet hidden-xs"><%= disc_report_column(host) %></td>
31
- <td>
32
- <!-- Modal -->
33
- <%= render :partial => "discovered_host_modal", :locals => {:host => host} %>
34
- </div>
35
- <%= action_buttons(
36
- provision_button(host, hash_for_edit_discovered_host_path(:id => host)),
37
- display_link_if_authorized(_("Auto Provision"), hash_for_auto_provision_discovered_host_path(:id => host), :method => :post),
38
- display_link_if_authorized(_("Refresh facts"), hash_for_refresh_facts_discovered_host_path(:id => host)),
39
- display_link_if_authorized(_("Reboot"), hash_for_reboot_discovered_host_path(:id => host), :method => :put),
40
- display_delete_if_authorized(hash_for_discovered_host_path(:id => host), :data => { :confirm => _("Delete %s?") % host.name }, :action => :destroy)) %>
5
+ <th class="ca"><%= check_box_tag "check_all", "", false, { :onclick => "tfm.hosts.table.toggleCheck()", :'check-title' => _("Select all items in this page"), :'uncheck-title'=> _("items selected. Uncheck to Clear") } %></th>
6
+ <th class=''><%= sort :name, :as => _('Name') %></th>
7
+ <th class="hidden-tablet hidden-xs"><%= sort :model, :as => _('Model') %></th>
8
+ <th class="hidden-tablet hidden-xs"><%= sort :ip, :as => _('IP Address') %></th>
9
+ <th class="hidden-tablet hidden-xs"><%= sort :cpu_count, :as => _('CPUs') %></th>
10
+ <th class="hidden-tablet hidden-xs"><%= sort :memory, :as => _('Memory') %></th>
11
+ <th class="hidden-tablet hidden-xs"><%= sort :disk_count, :as => _('Disk Count') %></th>
12
+ <th class="hidden-tablet hidden-xs"><%= sort :disks_size, :as => _('Disks Size') %></th>
13
+ <% Setting::Discovered.discovery_fact_column_array.each do |fact_column| %>
14
+ <th class="hidden-tablet hidden-xs"><%= fact_column.capitalize %></th>
15
+ <% end %>
16
+ <th class="hidden-tablet hidden-xs"><%= sort :location, :as => _('Location') %></th>
17
+ <th class="hidden-tablet hidden-xs"><%= sort :organization, :as => _('Organization') %></th>
18
+ <th class="hidden-tablet hidden-xs"><%= sort :subnet, :as => _("Subnet") %></th>
19
+ <th class="hidden-tablet hidden-xs"><%= sort :last_report, :as => _("Last Facts Upload") %></th>
20
+ <th class="hidden-tablet hidden-xs"><%= _("Actions") %></th>
21
+ </tr>
22
+ </thead>
23
+ <tbody>
24
+ <% @hosts.each do |host| -%>
25
+ <tr>
26
+ <td class="ca">
27
+ <%= check_box_tag "host_ids[]", nil, false, :id => "host_ids_#{host.id}", :disabled => !authorized_for_edit_destroy?, :class => 'host_select_boxes', :onclick => 'tfm.hosts.table.hostChecked(this)' -%>
41
28
  </td>
42
- </tr>
43
- <% end -%>
44
- </table>
29
+ <%= render :partial => "discovered_host", :locals => {:host => host} %>
30
+ <td class="hidden-tablet hidden-xs"><%= host.location.try(:title) %></td>
31
+ <td class="hidden-tablet hidden-xs"><%= host.organization.try(:title) %></td>
32
+ <td class="hidden-tablet hidden-xs"><%= host.primary_interface.try(:subnet).try(:to_label) %></td>
33
+ <td class="hidden-tablet hidden-xs"><%= disc_report_column(host) %></td>
34
+ <td>
35
+ <!-- Modal -->
36
+ <%= render :partial => "discovered_host_modal", :locals => {:host => host} %>
37
+ </div>
38
+ <%= action_buttons(
39
+ provision_button(host, hash_for_edit_discovered_host_path(:id => host)),
40
+ display_link_if_authorized(_("Auto Provision"), hash_for_auto_provision_discovered_host_path(:id => host), :method => :post),
41
+ display_link_if_authorized(_("Refresh facts"), hash_for_refresh_facts_discovered_host_path(:id => host)),
42
+ display_link_if_authorized(_("Reboot"), hash_for_reboot_discovered_host_path(:id => host), :method => :put),
43
+ display_delete_if_authorized(hash_for_discovered_host_path(:id => host), :data => { :confirm => _("Delete %s?") % host.name }, :action => :destroy)) %>
44
+ </td>
45
+ </tr>
46
+ <% end -%>
47
+ </tbody>
48
+ </table>
45
49
 
46
50
  <div id="confirmation-modal" class="modal fade">
47
51
  <div class="modal-dialog">
@@ -0,0 +1,3 @@
1
+ <% title _("Clone %s") % @discovered_rules.to_s %>
2
+
3
+ <%= render :partial => 'form' %>
@@ -8,6 +8,8 @@
8
8
  <th><%= sort :search, :as => s_("DiscoveryRule|Query") %></th>
9
9
  <th><%= _("Host Group") %></th>
10
10
  <th><%= _("Hosts/Limit") %></th>
11
+ <th><%= sort :location, :as => _('Location') %></th>
12
+ <th><%= sort :organization, :as => _('Organization') %></th>
11
13
  <th><%= sort :enabled, :as => s_("DiscoveryRule|Enabled") %></th>
12
14
  <th><%= _("Actions") %></th>
13
15
  </tr>
@@ -18,6 +20,8 @@
18
20
  <td><%= trunc_with_tooltip(rule.search) %></td>
19
21
  <td><%= label_with_link(rule.hostgroup, 26, authorizer) %></td>
20
22
  <td><%= rule.hosts.count %> / <%= rule.max_count %></td>
23
+ <td><%= rule.locations.find_by(title: Location.current.try(:title)).try(:title) || rule.locations.pluck(:title).join(",") %></td>
24
+ <td><%= rule.organizations.find_by(title: Organization.current.try(:title)).try(:title) || rule.organizations.pluck(:title).join(",") %></td>
21
25
  <td><%= checked_icon rule.enabled %></td>
22
26
  <td><%= action_buttons(*permitted_discovery_actions(rule)) %></td>
23
27
  </tr>
@@ -0,0 +1,15 @@
1
+ <% content_for(:javascripts) do %>
2
+ <%= webpacked_plugins_js_for :'foreman_discovery' %>
3
+ <% end %>
4
+ <% content_for(:stylesheets) do %>
5
+ <%= webpacked_plugins_css_for :'foreman_discovery' %>
6
+ <% end %>
7
+
8
+ <% content_for(:title, _("Discovered Rules")) %>
9
+
10
+ <% content_for(:content) do %>
11
+ <%= notifications %>
12
+ <div id="organization-id" data-id="<%= Organization.current.id if Organization.current %>" ></div>
13
+ <div id="user-id" data-id="<%= User.current.id if User.current %>" ></div>
14
+ <%= react_component('DiscoveryRules', docUrl: discovery_doc_url + '/#4.3Automaticprovisioning' ) %>
15
+ <% end %>
@@ -19,7 +19,7 @@ Extra options like --reset-vga can be set via "extra" array.
19
19
  -%>
20
20
  <%
21
21
  mac = @host.facts['discovery_bootif']
22
- bootif = host_param("hardware_type", "01") + '-' + mac.gsub(':', '-') if mac
22
+ bootif = host_param("hardware_type", "01") + mac.gsub(':', '-') if mac
23
23
  ip_cidr = @host.facts['discovery_ip_cidr']
24
24
  ip = @host.facts['discovery_ip']
25
25
  mask = @host.facts['discovery_netmask']
@@ -29,7 +29,7 @@ Extra options like --reset-vga can be set via "extra" array.
29
29
  -%>
30
30
  <%
31
31
  mac = @host.facts['discovery_bootif']
32
- bootif = host_param("hardware_type", "01") + '-' + mac.gsub(':', '-') if mac
32
+ bootif = host_param("hardware_type", "01") + mac.gsub(':', '-') if mac
33
33
  ip_cidr = @host.facts['discovery_ip_cidr']
34
34
  ip = @host.facts['discovery_ip']
35
35
  mask = @host.facts['discovery_netmask']
data/config/routes.rb CHANGED
@@ -7,6 +7,7 @@ Rails.application.routes.draw do
7
7
  post 'medium_selected_discovered_hosts' => 'hosts#medium_selected'
8
8
 
9
9
  get 'discovered_hosts/help', :action => :welcome, :controller => 'discovered_hosts'
10
+ get 'discovery_rules/help', :action => :welcome, :controller => 'discovery_rules'
10
11
 
11
12
  constraints(:id => /[^\/]+/) do
12
13
  resources :discovered_hosts, :except => [:new, :create] do
@@ -33,6 +34,7 @@ Rails.application.routes.draw do
33
34
 
34
35
  resources :discovery_rules, :except => [:show] do
35
36
  member do
37
+ get :clone
36
38
  get :enable
37
39
  get :disable
38
40
  end
@@ -1,7 +1,7 @@
1
1
  # seeds UI notification blueprints that are supported by Disocvery.
2
2
  [
3
3
  {
4
- group: _('Hosts'),
4
+ group: _('New hosts'),
5
5
  name: 'new_discovered_host',
6
6
  message: _('One or more hosts have been discovered'),
7
7
  level: 'info',
@@ -10,8 +10,14 @@
10
10
  links:
11
11
  [
12
12
  path_method: :discovered_hosts_path,
13
- title: _('Details')
14
- ]
15
- }
16
- }
13
+ title: _('Details'),
14
+ ],
15
+ },
16
+ },
17
+ {
18
+ group: _('Hosts'),
19
+ name: 'failed_discovery',
20
+ message: _('Error message goes here'),
21
+ level: 'error',
22
+ },
17
23
  ].each { |blueprint| UINotifications::Seed.new(blueprint).configure }
@@ -43,7 +43,7 @@ module ForemanDiscovery
43
43
 
44
44
  initializer 'foreman_discovery.register_plugin', :before => :finisher_hook do |app|
45
45
  Foreman::Plugin.register :foreman_discovery do
46
- requires_foreman '>= 2.3'
46
+ requires_foreman '>= 2.4'
47
47
 
48
48
  # discovered hosts permissions
49
49
  security_block :discovery do
@@ -86,11 +86,11 @@ module ForemanDiscovery
86
86
  # discovery rules permissions
87
87
  security_block :discovery_rules do
88
88
  permission :view_discovery_rules, {
89
- :discovery_rules => [:index, :show, :auto_complete_search],
89
+ :discovery_rules => [:index, :show, :auto_complete_search, :welcome],
90
90
  :"api/v2/discovery_rules" => [:index, :show]
91
91
  }, :resource_type => 'DiscoveryRule'
92
92
  permission :create_discovery_rules, {
93
- :discovery_rules => [:new, :create],
93
+ :discovery_rules => [:new, :create, :clone],
94
94
  :"api/v2/discovery_rules" => [:create]
95
95
  }, :resource_type => 'DiscoveryRule'
96
96
  permission :edit_discovery_rules, {
@@ -173,10 +173,6 @@ module ForemanDiscovery
173
173
  # add dashboard widget
174
174
  widget 'discovery_widget', :name=>N_('Discovered Hosts'), :sizex => 6, :sizey =>1
175
175
 
176
- # allowed helpers and variables
177
- allowed_template_helpers :rand
178
- allowed_template_variables :kexec_kernel, :kexec_initrd
179
-
180
176
  template_labels 'kexec' => N_('Discovery Kexec template')
181
177
 
182
178
  # apipie API documentation
@@ -1,3 +1,3 @@
1
1
  module ForemanDiscovery
2
- VERSION = "16.3.6"
2
+ VERSION = "17.0.0"
3
3
  end