foreman_discovery 16.3.6 → 17.0.3

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 (94) 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 +3 -4
  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/discovered_hosts/welcome.html.erb +1 -1
  13. data/app/views/discovery_rules/clone.erb +3 -0
  14. data/app/views/discovery_rules/index.html.erb +4 -0
  15. data/app/views/discovery_rules/welcome.html.erb +15 -0
  16. data/config/routes.rb +2 -0
  17. data/db/seeds.d/80_discovery_ui_notification.rb +11 -5
  18. data/lib/foreman_discovery/engine.rb +3 -7
  19. data/lib/foreman_discovery/version.rb +1 -1
  20. data/locale/ca/LC_MESSAGES/foreman_discovery.mo +0 -0
  21. data/locale/ca/foreman_discovery.edit.po +44 -40
  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.edit.po +42 -38
  25. data/locale/de/foreman_discovery.po +45 -18
  26. data/locale/en/LC_MESSAGES/foreman_discovery.mo +0 -0
  27. data/locale/en/foreman_discovery.edit.po +37 -29
  28. data/locale/en/foreman_discovery.po +31 -4
  29. data/locale/en_GB/LC_MESSAGES/foreman_discovery.mo +0 -0
  30. data/locale/en_GB/foreman_discovery.edit.po +39 -35
  31. data/locale/en_GB/foreman_discovery.po +36 -9
  32. data/locale/es/LC_MESSAGES/foreman_discovery.mo +0 -0
  33. data/locale/es/foreman_discovery.edit.po +42 -38
  34. data/locale/es/foreman_discovery.po +70 -41
  35. data/locale/foreman_discovery.pot +142 -97
  36. data/locale/fr/LC_MESSAGES/foreman_discovery.mo +0 -0
  37. data/locale/fr/foreman_discovery.edit.po +88 -84
  38. data/locale/fr/foreman_discovery.po +76 -49
  39. data/locale/gl/LC_MESSAGES/foreman_discovery.mo +0 -0
  40. data/locale/gl/foreman_discovery.edit.po +42 -38
  41. data/locale/gl/foreman_discovery.po +32 -5
  42. data/locale/it/LC_MESSAGES/foreman_discovery.mo +0 -0
  43. data/locale/it/foreman_discovery.edit.po +42 -38
  44. data/locale/it/foreman_discovery.po +44 -17
  45. data/locale/ja/LC_MESSAGES/foreman_discovery.mo +0 -0
  46. data/locale/ja/foreman_discovery.edit.po +74 -70
  47. data/locale/ja/foreman_discovery.po +79 -54
  48. data/locale/ko/LC_MESSAGES/foreman_discovery.mo +0 -0
  49. data/locale/ko/foreman_discovery.edit.po +42 -38
  50. data/locale/ko/foreman_discovery.po +43 -16
  51. data/locale/pt_BR/LC_MESSAGES/foreman_discovery.mo +0 -0
  52. data/locale/pt_BR/foreman_discovery.edit.po +42 -38
  53. data/locale/pt_BR/foreman_discovery.po +69 -39
  54. data/locale/ru/LC_MESSAGES/foreman_discovery.mo +0 -0
  55. data/locale/ru/foreman_discovery.edit.po +46 -42
  56. data/locale/ru/foreman_discovery.po +43 -16
  57. data/locale/sv_SE/LC_MESSAGES/foreman_discovery.mo +0 -0
  58. data/locale/sv_SE/foreman_discovery.edit.po +42 -38
  59. data/locale/sv_SE/foreman_discovery.po +34 -7
  60. data/locale/zh_CN/LC_MESSAGES/foreman_discovery.mo +0 -0
  61. data/locale/zh_CN/foreman_discovery.edit.po +90 -86
  62. data/locale/zh_CN/foreman_discovery.po +114 -90
  63. data/locale/zh_TW/LC_MESSAGES/foreman_discovery.mo +0 -0
  64. data/locale/zh_TW/foreman_discovery.edit.po +42 -38
  65. data/locale/zh_TW/foreman_discovery.po +43 -16
  66. data/package.json +6 -6
  67. data/test/functional/api/v2/discovered_hosts_controller_test.rb +9 -0
  68. data/test/functional/discovery_rules_controller_test.rb +6 -1
  69. data/test/integration/discovered_hosts_test.rb +53 -5
  70. data/test/test_helper_discovery.rb +5 -0
  71. data/test/unit/discovery_rule_test.rb +24 -2
  72. data/test/unit/fact_to_category_resolver_test.rb +41 -0
  73. data/test/unit/ui_notifications/destroy_host_test.rb +2 -9
  74. data/test/unit/ui_notifications/new_host_test.rb +3 -3
  75. data/webpack/__mocks__/foremanReact/common/I18n.js +3 -0
  76. data/webpack/__mocks__/foremanReact/common/helpers.js +1 -0
  77. data/webpack/__mocks__/foremanReact/common/index.js +5 -0
  78. data/webpack/__mocks__/foremanReact/components/common/EmptyState/DefaultEmptyState.js +69 -0
  79. data/webpack/__mocks__/foremanReact/components/common/EmptyState/EmptyStatePattern.js +77 -0
  80. data/webpack/__mocks__/foremanReact/components/common/EmptyState/EmptyStatePropTypes.js +29 -0
  81. data/webpack/__mocks__/foremanReact/components/common/EmptyState/index.js +5 -0
  82. data/webpack/index.js +9 -8
  83. data/webpack/src/ForemanDiscovery/DiscoveredHosts/Components/EmptyState/EmptyState.js +7 -7
  84. data/webpack/src/ForemanDiscovery/DiscoveredHosts/Components/EmptyState/__test__/EmptyState.test.js +12 -0
  85. data/webpack/src/ForemanDiscovery/DiscoveredHosts/Components/EmptyState/__test__/__snapshots__/EmptyState.test.js.snap +16 -0
  86. data/webpack/src/ForemanDiscovery/DiscoveredHosts/Components/EmptyState/index.js +1 -1
  87. data/webpack/src/ForemanDiscovery/DiscoveredHosts/index.js +3 -3
  88. data/webpack/src/ForemanDiscovery/DiscoveryRules/Components/EmptyState/EmptyState.js +34 -0
  89. data/webpack/src/ForemanDiscovery/DiscoveryRules/Components/EmptyState/index.js +1 -0
  90. data/webpack/src/ForemanDiscovery/DiscoveryRules/Components/__test__/EmptyState.test.js +19 -0
  91. data/webpack/src/ForemanDiscovery/DiscoveryRules/Components/__test__/__snapshots__/EmptyState.test.js.snap +22 -0
  92. data/webpack/src/ForemanDiscovery/DiscoveryRules/index.js +6 -0
  93. data/webpack/src/reducers.js +0 -2
  94. metadata +31 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5404d1b999eff25f29e39cf14d77a7e85473e29a50a677ac3254aadfd1bc53a4
4
- data.tar.gz: 803b2278dd981b8123cd88593f7fb00fd974b69711e848da60f31fd85dabbb90
3
+ metadata.gz: 4d8d075f8a3a3048021cb510037e84ce925e805d3cb915a2d739bd188a99d08f
4
+ data.tar.gz: 2851a8920c2e7da750c92104e26ce286cd723aab684e8f3e08d452ea458f5d3e
5
5
  SHA512:
6
- metadata.gz: b4d290ab7aeb3cd8ed2254159ccead4c2ad69138b68e3758c9724e9eac5e99cfefcc654af9a12dda964201cca307f87f161682000f878a70dbcb1241996a57ad
7
- data.tar.gz: 6398fa38e8625aee40bc6bc4ea387cced9ee50eba1e06fcdd711256e587f96c3d4d782738fd3efaf5b3bc0a3c2330f0f733088fdc5f8eafa8e3360a8bdeaea09
6
+ metadata.gz: 1ddc4a716ab29ec7cf78c052e8238184962c97d528592f171e074664e2542e603ffc9d3bce44bf255c787c82cc3df82faf6a7d61a98d9046fca544a957589e4a
7
+ data.tar.gz: 3d72b88c68fb69a56e1f691c1df6a93bc42b5c2157f79ee0ad9293ea85b4aa15510ebd130e1d8464fdb6593d6aed01e0adee3c688f6d698a8194cca8f281158a
@@ -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.deep_clone except: [:name, :priority], include: [:organizations, :locations]
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)
@@ -98,8 +98,7 @@ module DiscoveredHostsHelper
98
98
  discovered_host_path(host)
99
99
  end
100
100
 
101
- def discovery_doc_url
102
- doc_version = Foreman::Plugin.find(:foreman_discovery).version.scan(/\d+\.\d+/).first
103
- "https://theforeman.org/plugins/foreman_discovery/#{doc_version}"
101
+ def discovery_doc_version
102
+ Foreman::Plugin.find(:foreman_discovery).version.scan(/\d+\.\d+/).first
104
103
  end
105
104
  end
@@ -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">
@@ -11,5 +11,5 @@
11
11
  <%= notifications %>
12
12
  <div id="organization-id" data-id="<%= Organization.current.id if Organization.current %>" ></div>
13
13
  <div id="user-id" data-id="<%= User.current.id if User.current %>" ></div>
14
- <%= react_component('DiscoveredHosts', docUrl: discovery_doc_url ) %>
14
+ <%= react_component('DiscoveredHosts', docUrl: external_link_path(type: 'plugin_manual', name: 'foreman_discovery', version: discovery_doc_version)) %>
15
15
  <% end %>
@@ -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: external_link_path(type: 'plugin_manual', name: 'foreman_discovery', version: discovery_doc_version, section: '#4.3Automaticprovisioning') ) %>
15
+ <% end %>
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.3"
3
3
  end