foreman_probing 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +619 -0
  3. data/README.md +102 -0
  4. data/Rakefile +47 -0
  5. data/app/controllers/foreman_probing/api/v2/scans_controller.rb +66 -0
  6. data/app/controllers/foreman_probing/hosts_controller.rb +14 -0
  7. data/app/controllers/foreman_probing/scans_controller.rb +47 -0
  8. data/app/helpers/concerns/foreman_probing/hosts_helper_extensions.rb +9 -0
  9. data/app/helpers/concerns/foreman_probing/subnet_helper_extensions.rb +7 -0
  10. data/app/helpers/foreman_probing/scans_helper.rb +42 -0
  11. data/app/lib/actions/create_subnets.rb +27 -0
  12. data/app/lib/actions/import_host_facts.rb +85 -0
  13. data/app/lib/actions/perform_scan.rb +26 -0
  14. data/app/lib/actions/process_host.rb +18 -0
  15. data/app/lib/actions/process_scan.rb +21 -0
  16. data/app/lib/actions/scan_host.rb +35 -0
  17. data/app/lib/actions/update_probing_facet.rb +44 -0
  18. data/app/models/concerns/foreman_probing/foreman_tasks_task_extensions.rb +9 -0
  19. data/app/models/concerns/foreman_probing/host_extensions.rb +10 -0
  20. data/app/models/concerns/foreman_probing/subnet_extensions.rb +21 -0
  21. data/app/models/foreman_probing/fact_name.rb +11 -0
  22. data/app/models/foreman_probing/port.rb +21 -0
  23. data/app/models/foreman_probing/probing_facet.rb +27 -0
  24. data/app/models/foreman_probing/scan.rb +42 -0
  25. data/app/models/foreman_probing/scan_composer.rb +75 -0
  26. data/app/models/foreman_probing/scan_host.rb +8 -0
  27. data/app/models/foreman_probing/service.rb +14 -0
  28. data/app/models/foreman_probing/targeting/direct.rb +50 -0
  29. data/app/models/foreman_probing/targeting/search.rb +23 -0
  30. data/app/models/foreman_probing/targeting/subnet.rb +17 -0
  31. data/app/models/foreman_probing/targeting/subnet_discovery.rb +12 -0
  32. data/app/models/foreman_probing/targeting.rb +12 -0
  33. data/app/overrides/dashboard/index/sample_override.html.erb.deface +4 -0
  34. data/app/overrides/open_ports_tab.rb +14 -0
  35. data/app/services/foreman_probing/fact_parser.rb +47 -0
  36. data/app/services/foreman_probing/structured_fact_importer.rb +20 -0
  37. data/app/views/dashboard/_foreman_probing_widget.html.erb +2 -0
  38. data/app/views/foreman_probing/api/v2/scans/base.json.rabl +3 -0
  39. data/app/views/foreman_probing/api/v2/scans/index.json.rabl +3 -0
  40. data/app/views/foreman_probing/api/v2/scans/show.json.rabl +3 -0
  41. data/app/views/foreman_probing/hosts/_open_ports.html.erb +19 -0
  42. data/app/views/foreman_probing/hosts/hosts/new_action.html.erb +1 -0
  43. data/app/views/foreman_probing/hosts/new_action.html.erb +1 -0
  44. data/app/views/foreman_probing/layouts/layouts/new_layout.html.erb +0 -0
  45. data/app/views/foreman_probing/layouts/new_layout.html.erb +0 -0
  46. data/app/views/foreman_probing/probing_facets/_open_ports_tab_content.html.erb +6 -0
  47. data/app/views/foreman_probing/probing_facets/_open_ports_tab_title.html.erb +4 -0
  48. data/app/views/foreman_probing/scans/index.html.erb +31 -0
  49. data/app/views/foreman_probing/scans/new.html.erb +51 -0
  50. data/app/views/foreman_probing/scans/show.html.erb +41 -0
  51. data/app/views/foreman_probing/scans/show.js.erb +0 -0
  52. data/app/views/templates/ssh/add_public_keys.erb +22 -0
  53. data/app/views/templates/ssh/register_content_host.erb +34 -0
  54. data/app/views/templates/ssh/register_puppet.erb +19 -0
  55. data/config/routes.rb +28 -0
  56. data/db/migrate/20170401154201_create_foreman_probing_facets.rb +9 -0
  57. data/db/migrate/20170401154714_create_foreman_probing_ports.rb +13 -0
  58. data/db/migrate/20170401154726_create_foreman_probing_services.rb +10 -0
  59. data/db/migrate/20170620180935_create_foreman_probing_scans.rb +15 -0
  60. data/db/migrate/20170701190511_create_foreman_probing_targetings.rb +9 -0
  61. data/db/seeds.d/70-job_templates.rb +7 -0
  62. data/lib/foreman_probing/engine.rb +124 -0
  63. data/lib/foreman_probing/version.rb +3 -0
  64. data/lib/foreman_probing.rb +5 -0
  65. data/locale/Makefile +60 -0
  66. data/locale/en/foreman_probing.po +19 -0
  67. data/locale/foreman_probing.pot +19 -0
  68. data/locale/gemspec.rb +2 -0
  69. data/test/factories/foreman_probing_factories.rb +5 -0
  70. data/test/test_plugin_helper.rb +6 -0
  71. data/test/unit/foreman_probing_test.rb +11 -0
  72. metadata +159 -0
@@ -0,0 +1,21 @@
1
+ module ForemanProbing
2
+ class Port < ActiveRecord::Base
3
+ belongs_to :probing_facet, :class_name => '::ForemanProbing::ProbingFacet'
4
+ has_many :services
5
+
6
+ def update_from_facts(protocol, number, facts)
7
+ self.protocol = protocol
8
+ self.number = number
9
+ self.state = facts[:state]
10
+ end
11
+
12
+ def update_from_port(port)
13
+ protocol = port.protocol
14
+ number = port.number
15
+ state = port.state
16
+ port.services.reject { |service| self.services.map(&:name).include? service.name }.each do |service|
17
+ self.services << service
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,27 @@
1
+ module ForemanProbing
2
+ class ProbingFacet < ActiveRecord::Base
3
+ include Facets::Base
4
+
5
+ def self.table_name
6
+ 'foreman_probing_probing_facets'
7
+ end
8
+
9
+ validates :host, :presence => true, :allow_blank => false
10
+
11
+ has_many :scanned_ports, :class_name => 'Port'
12
+ has_many :services, :through => :scanned_ports
13
+
14
+ def online?
15
+
16
+ end
17
+
18
+ def refresh
19
+
20
+ end
21
+
22
+ def ping!
23
+
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,42 @@
1
+ module ForemanProbing
2
+ class Scan < ActiveRecord::Base
3
+ include Taxonomix
4
+
5
+ default_scope -> do
6
+ with_taxonomy_scope do
7
+ order(:id => 'desc')
8
+ end
9
+ end
10
+
11
+ belongs_to :task, :class_name => '::ForemanTasks::Task'
12
+ has_one :targeting
13
+ has_one :scan_host
14
+ has_many :hosts, :through => :scan_host, :class_name => 'Host::Managed'
15
+ belongs_to :smart_proxy
16
+
17
+ attr_accessor :direct, :target_kind, :search_query, :subnet_id
18
+
19
+ def ports
20
+ if @ports.nil?
21
+ return [] if raw_ports.nil?
22
+ ranges = raw_ports.split(',')
23
+ ports = ranges.map do |range|
24
+ range.split('-').map do |from, to|
25
+ to.nil? ? from : (from..to).entries
26
+ end
27
+ end
28
+ @ports = ports.flatten.map(&:chomp).map(&:to_i)
29
+ end
30
+ @ports
31
+ end
32
+
33
+ def available_scan_types
34
+ ['TCP', 'UDP', 'ICMP']
35
+ end
36
+
37
+ def target_kinds
38
+ ['Direct', 'Subnet', 'Host', 'Proxy']
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,75 @@
1
+ module ForemanProbing
2
+ class ScanComposer
3
+
4
+ attr_accessor :targeting, :ports, :probe, :proxy
5
+
6
+ TARGETING_TYPES = %w(direct subnet host proxy).freeze
7
+
8
+ def self.new_from_params(params)
9
+ self.new.tap do |c|
10
+ c.targeting = c.targeting_from_params(params)
11
+ c.ports = c.ports_from_params(params)
12
+ c.probe = params[:scan_type]
13
+ c.proxy = c.proxy_from_params(params)
14
+ end
15
+ end
16
+
17
+ def self.new_from_scan(scan)
18
+ self.new.tap do |c|
19
+ c.targeting = scan.targeting.dup
20
+ c.ports = scan.raw_ports
21
+ c.probe = scan.scan_type
22
+ c.proxy = scan.smart_proxy
23
+ end
24
+ end
25
+
26
+ def compose!
27
+ if @scan.nil?
28
+ @scan = ForemanProbing::Scan.new
29
+ @scan.targeting = targeting
30
+ @scan.target_kind = targeting.target_kind
31
+ @scan.smart_proxy = proxy
32
+ @scan.scan_type = probe
33
+ @scan.raw_ports = ports
34
+
35
+ case targeting
36
+ when ::ForemanProbing::Targeting::Direct
37
+ @scan.direct = targeting.raw_targets
38
+ when ::ForemanProbing::Targeting::Subnet
39
+ @scan.subnet_id = targeting.raw_targets.to_i
40
+ when ::ForemanProbing::Targeting::Search
41
+ @scan.search_query = targeting.raw_targets
42
+ end
43
+ end
44
+ @scan
45
+ end
46
+
47
+ def proxy_from_params(params)
48
+ SmartProxy.authorized.find(params['smart_proxy_id'])
49
+ end
50
+
51
+ def ports_from_params(params)
52
+ # ranges = params[:ports].split(',')
53
+ # ports = ranges.map do |range|
54
+ # range.split('-').map do |from, to|
55
+ # to.nil? ? from : (from..to).entries
56
+ # end
57
+ # end
58
+ # ports.flatten.map(&:chomp).map(&:to_i)
59
+ params[:raw_ports]
60
+ end
61
+
62
+ def targeting_from_params(params)
63
+ case params[:target_kind].downcase
64
+ when 'direct'
65
+ ::ForemanProbing::Targeting::Direct.new(:raw_targets => params[:direct])
66
+ when 'subnet'
67
+ ::ForemanProbing::Targeting::Subnet.new(:raw_targets => params[:subnet_id])
68
+ when 'host'
69
+ ::ForemanProbing::Targeting::Search.new(:raw_targets => params[:search_query])
70
+ when 'proxy'
71
+ ::ForemanProbing::Targeting::SubnetDiscovery.new
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,8 @@
1
+ module ForemanProbing
2
+ class ScanHost < ActiveRecord::Base
3
+
4
+ belongs_to :scan
5
+ belongs_to :host
6
+
7
+ end
8
+ end
@@ -0,0 +1,14 @@
1
+ module ForemanProbing
2
+ class Service < ActiveRecord::Base
3
+ belongs_to :port
4
+
5
+ def self.new_from_facts(name, facts)
6
+ service = self.new
7
+ service.name = name
8
+ service.confidence = facts.fetch('confidence', 0)
9
+ service.method = facts.fetch('method', 'table')
10
+ # TODO: Process the rest of the attributes
11
+ service
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,50 @@
1
+ module ForemanProbing
2
+ class Targeting::Direct < Targeting
3
+
4
+ # Either ip address or subnet in CIDR notation
5
+ # def initialize(address_string)
6
+ # @addresses = parse_address_string!(address_string)
7
+ # end
8
+
9
+ def targets
10
+ parse_address_string!(raw_targets).map do |addr|
11
+ str = ''
12
+ case addr[:family].to_s
13
+ when 'inet'
14
+ str += addr[:addr]
15
+ str += '/' + addr[:netmask] unless addr[:netmask].nil?
16
+ when 'inet6'
17
+ # TODO: ipv6
18
+ raise NotImplementedError
19
+ else
20
+ raise ArgumentError, "Unknown address family #{addr[:family]}"
21
+ end
22
+ str
23
+ end
24
+ end
25
+
26
+ def target_kind
27
+ 'direct'
28
+ end
29
+
30
+ private
31
+
32
+ # TODO: Do some validation
33
+ def parse_address_string!(str)
34
+ if str.is_a?(Array)
35
+ str.map { |item| parse_address_string! item }.flatten
36
+ elsif str.is_a? Hash
37
+ str
38
+ else
39
+ # TODO: Somehow use IPAddr
40
+ str.split(',').map do |ip|
41
+ if ip =~ /(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})(\/(\d{1,2}))?/
42
+ { :family => :inet, :addr => $1, :netmask => $3 }
43
+ else
44
+ # TODO: Match ipv6 here
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,23 @@
1
+ module ForemanProbing
2
+ class Targeting::Search < ::ForemanProbing::Targeting
3
+ # def initialize(search_query, hosts = nil)
4
+ # @search_query = search_query
5
+ # @hosts = hosts
6
+ # end
7
+
8
+ def targets
9
+ @hosts ||= resolve_hosts!
10
+ @targets ||= @hosts.map { |host| host.interfaces.map(&:ip) }.flatten
11
+ end
12
+
13
+ def target_kind
14
+ 'host'
15
+ end
16
+
17
+ def resolve_hosts!
18
+ # @hosts = Host.authorized(RESOLVE_PERMISSION, Host)
19
+ # .search_for(@search_query)
20
+ ::Host.authorized.search_for(raw_targets)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,17 @@
1
+ module ForemanProbing
2
+ class Targeting::Subnet < ForemanProbing::Targeting
3
+ def target_kind
4
+ 'subnet'
5
+ end
6
+
7
+ def subnet
8
+ @subnet ||= ::Subnet.authorized.find(raw_targets.to_i)
9
+ end
10
+
11
+ def targets
12
+ # TODO: This is ugly
13
+ cidr = IPAddr.new(subnet.mask).to_i.to_s(2).count('1')
14
+ @targets ||= "#{subnet.network}/#{cidr}"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,12 @@
1
+ module ForemanProbing
2
+ class Targeting::SubnetDiscovery < Targeting
3
+
4
+ def target_kind
5
+ 'proxy'
6
+ end
7
+
8
+ def targets
9
+ []
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module ForemanProbing
2
+ class Targeting < ActiveRecord::Base
3
+ belongs_to :scan
4
+
5
+ # Returns array of strings, suitable for direct passing into nmap
6
+ def targets
7
+ raise NotImplementedError
8
+ end
9
+
10
+ require_dependency(File.join(__FILE__.gsub(/\.rb$/, ''), '..', 'targeting', 'subnet.rb'))
11
+ end
12
+ end
@@ -0,0 +1,4 @@
1
+ <!-- insert_before 'div:contains("title_action")' -->
2
+ <%= title_actions "<h2>ForemanProbing</h2>" %>
3
+
4
+ <!-- vim: set ft=eruby : -->
@@ -0,0 +1,14 @@
1
+ # Displays opened ports as a tab in host details
2
+ Deface::Override.new(
3
+ :virtual_path => 'hosts/show',
4
+ :name => 'open_ports_tab',
5
+ :surround_contents => 'ul.nav.nav-tabs',
6
+ :partial => 'foreman_probing/probing_facets/open_ports_tab_title',
7
+ )
8
+
9
+ Deface::Override.new(
10
+ :virtual_path => 'hosts/show',
11
+ :name => 'open_ports_content',
12
+ :surround_contents => 'div.tab-content',
13
+ :partial => 'foreman_probing/probing_facets/open_ports_tab_content',
14
+ )
@@ -0,0 +1,47 @@
1
+ module ForemanProbing
2
+ class FactParser < ::FactParser
3
+
4
+ attr_reader :facts
5
+
6
+ def initialize(facts)
7
+ @facts = HashWithIndifferentAccess.new(facts)
8
+ end
9
+
10
+ # We don't know anything about those
11
+ def architecture; end
12
+ def domain; end
13
+ def environment; end
14
+ def model; end
15
+ def operatingsystem; end
16
+
17
+ def support_interfaces_parsing?
18
+ true
19
+ end
20
+
21
+ def ipmi_interface; end
22
+
23
+ def get_interfaces # rubocop:disable Style/AccessorMethodName
24
+ identifiers = facts['addresses'].values_at(*%w(ipv4 ipv6 hwaddr))
25
+ .compact.map do |hash|
26
+ hash.values.map { |value| value['identifier'] }
27
+ end
28
+ identifiers.flatten.compact.uniq
29
+ end
30
+
31
+ def get_facts_for_interface(interface)
32
+ addresses = facts['addresses']
33
+ result = { :ipaddress => 'ipv4',
34
+ :ip6address => 'ipv6',
35
+ :macaddress => 'hwaddr' }.reduce({}) do |acc, (key, kind)|
36
+ acc.merge(key => address_by_identifier(addresses, kind, interface))
37
+ end
38
+ HashWithIndifferentAccess.new(result)
39
+ end
40
+
41
+ private
42
+
43
+ def address_by_identifier(addresses, kind, identifier)
44
+ addresses.fetch(kind, {}).find { |(_ip, value)| value['identifier'] == identifier }.try(:first)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,20 @@
1
+ module ForemanProbing
2
+ class StructuredFactImporter < ::StructuredFactImporter
3
+ def fact_name_class
4
+ ForemanProbing::FactName
5
+ end
6
+
7
+ def initialize(host, facts = {})
8
+ @host = find_host(host, facts)
9
+ @facts = normalize(facts)
10
+ @counters = {}
11
+ end
12
+
13
+ private
14
+
15
+ def find_host(fallback, facts)
16
+ # TODO: go through facts
17
+ fallback
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,2 @@
1
+ <h4 class="header ca"><%= _('ForemanProbing') %></h4>
2
+ <%= _('Widget content') %>
@@ -0,0 +1,3 @@
1
+ object @scan
2
+
3
+ attributes :id, :scan_type, :raw_ports, :smart_proxy_id, :task_id
@@ -0,0 +1,3 @@
1
+ collection @scans
2
+
3
+ extends 'foreman_probing/api/v2/scans/base'
@@ -0,0 +1,3 @@
1
+ object @scan
2
+
3
+ extends 'foreman_probing/api/v2/scans/base'
@@ -0,0 +1,19 @@
1
+ <% if @host.probing_facet.scanned_ports.count.zero? %>
2
+ <div class="alert alert-info"><%= _('This host has no known open ports') %></div>
3
+ <% else %>
4
+ <table id="open_ports_table" class="<%= table_css_classes %>">
5
+ <thead>
6
+ <tr>
7
+ <th><%= _('Port') %></th>
8
+ <th><%= _('Updated at') %></th>
9
+ </tr>
10
+ </thead>
11
+ <% @host.probing_facet.scanned_ports.each do |port| %>
12
+ <tr>
13
+ <td><%= port.number %>/<%= port.protocol %></td>
14
+ <td><%= port.updated_at %></td>
15
+ </tr>
16
+ <% end %>
17
+ </table>
18
+ <% end %>
19
+ <br>
@@ -0,0 +1 @@
1
+ Welcome to <b>ForemanProbing</b>
@@ -0,0 +1 @@
1
+ Welcome to <b>ForemanProbing</b>
@@ -0,0 +1,6 @@
1
+ <%= render_original %>
2
+ <% unless @host.probing_facet.nil? %>
3
+ <div id="open-ports" class="tab-pane" data-ajax-url='<%= open_ports_foreman_probing_host_path(@host)%>'>
4
+ <%= spinner(_('Loading information about opened ports ...')) %>
5
+ </div>
6
+ <% end %>
@@ -0,0 +1,4 @@
1
+ <%= render_original %>
2
+ <% unless @host.probing_facet.nil? %>
3
+ <li><a href="#open-ports" data-toggle="tab"><%= _('Open ports') %></a></li>
4
+ <% end %>
@@ -0,0 +1,31 @@
1
+ <% title _('Scans') %>
2
+
3
+ <% title_actions([new_link(_('Run Scan'))]) %>
4
+
5
+ <table class="table table-bordered table-condensed">
6
+ <thead>
7
+ <tr>
8
+ <th>ID</th>
9
+ <th>Scan type</th>
10
+ <th>Ports</th>
11
+ <th>Smart Proxy</th>
12
+ <th>Targeting</th>
13
+ <th>Run at</th>
14
+ <th>Actions</th>
15
+ </tr>
16
+ </thead>
17
+ <tbody>
18
+ <% @scans.each do |scan| %>
19
+ <tr>
20
+ <td><a href="<%= url_for(scan) %>"><%= scan.id %></a></td>
21
+ <td><%= scan.scan_type %></td>
22
+ <td><%= scan.ports.join(', ') %></td>
23
+ <td><%= scan.smart_proxy.name %></td>
24
+ <td><%= targeting_label(scan.targeting) %></td>
25
+ <td><%= scan.task && scan.task.started_at %></td>
26
+ <td><a href="<%= rerun_foreman_probing_scan_path(:id => scan.id) %>" class="btn">Rerun</a></td>
27
+ </tr>
28
+ <% end %>
29
+ </tbody>
30
+ </table>
31
+ <%= will_paginate_with_info @scans %>
@@ -0,0 +1,51 @@
1
+ <script>
2
+ var target_kind_change_handler = function(element) {
3
+ var value = element.value.toLowerCase();
4
+ $('div.kind').each(function(child) {
5
+ if(this.classList.contains('kind-' + value)) {
6
+ $(this).show();
7
+ } else {
8
+ $(this).hide();
9
+ }
10
+ });
11
+ };
12
+ var scan_type_change_handler = function(element) {
13
+ var value = element.value;
14
+ var target = $('input#foreman_probing_scan_raw_ports').closest('div.clearfix');
15
+ if(element.value != 'ICMP') {
16
+ target.show();
17
+ } else {
18
+ target.hide();
19
+ }
20
+ };
21
+ </script>
22
+
23
+ <%= title _('Scan') %>
24
+ <%= form_for @scan do |f| %>
25
+
26
+ <%= selectable_f f, :target_kind, @scan.target_kinds.map { |kind| [kind, kind.downcase] }, {}, :label => _('Target kind'), :onchange => 'target_kind_change_handler(this)' %>
27
+
28
+ <div class="kind kind-subnet <%= @scan.target_kind != 'subnet' ? 'hidden' : '' %>">
29
+ <%= selectable_f f, :subnet_id, Subnet.authorized.map { |s| ["#{s.name} (#{s.network}/#{s.mask}", s.id] },
30
+ {}, :label => 'Subnet' %>
31
+ </div>
32
+
33
+ <div class="kind kind-host <%= @scan.target_kind != 'host' ? 'hidden' : '' %>">
34
+ <%= textarea_f f, :search_query, :label => _('Search query') %>
35
+ </div>
36
+
37
+ <div class="kind kind-direct <%= @scan.target_kind != 'direct' ? 'hidden' : '' %>">
38
+ <%= text_f f, :direct, :label => _('IP Address'), :help_inline => _('Comma separated list of IPv4 addresses, subnets or ranges') %>
39
+ </div>
40
+
41
+ <%= selectable_f f, 'smart_proxy_id', SmartProxy.authorized.map { |p| [p.name, p.id] }, {}, :label => 'Smart proxy', :help_inline => _('Smart Proxy to run the scan from') %>
42
+
43
+ <%= selectable_f f, :scan_type, @scan.available_scan_types, {}, :label => _('Scan type'), :onchange => 'scan_type_change_handler(this)' %>
44
+
45
+ <div class="raw-ports <%= @scan.scan_type == 'ICMP' ? 'hidden' : '' %>">
46
+ <%= text_f f, :raw_ports, :label => _('Ports'), :help_inline => 'Single, port, coma-separated list or range FROM-TO' %>
47
+ </div>
48
+
49
+ <%= submit_or_cancel f, false, :cancel_path => foreman_probing_scans_path %>
50
+
51
+ <% end %>
@@ -0,0 +1,41 @@
1
+ <% title 'Scan' %>
2
+
3
+ <!-- TODO: Buttons -->
4
+ <% if @scan.task %>
5
+ <% title_actions(button_group(scan_task_buttons(@scan))) %>
6
+ <% end %>
7
+
8
+ <div class="col-md-6">
9
+ <h4>Details</h4>
10
+ <b><%= _("Smart proxy") %></b>: <a href="<%= url_for(@scan.smart_proxy) %>"><%= @scan.smart_proxy.name %></a><br>
11
+ <b><%= _("Scan type") %></b>: <%= @scan.scan_type %><br>
12
+ <% if @scan.scan_type != 'ICMP' %>
13
+ <b><%= _("Ports") %></b>: <%= @scan.ports.join(', ') %><br>
14
+ <% end %>
15
+ </div>
16
+
17
+ <div class="col-md-6 infoblock">
18
+ <h4>Scanned hosts</h4>
19
+ <% if @scan.task && %w(stopped paused).include?(@scan.task.state) %>
20
+ <table class="table table-bordered table-condensed">
21
+ <tr><th>Host</th><th>State</th></tr>
22
+ <% @scan.hosts.each do |host| %>
23
+ <tr><td><a href="<%= url_for(host) %>"><%= host.name %></a></td>
24
+ <td><%= host.probing_facet && host.probing_facet.status %></td>
25
+ </tr>
26
+ <% end %>
27
+ </table>
28
+ <% else %>
29
+ <div class="alert alert-info">
30
+ The task is still running.
31
+ </div>
32
+ <% end %>
33
+ </div>
34
+
35
+ <% if @auto_refresh %>
36
+ <script id="scan_show_refresh">
37
+ setTimeout(function () {
38
+ location.reload();
39
+ }, 10000);
40
+ </script>
41
+ <% end %>
File without changes
@@ -0,0 +1,22 @@
1
+ <%#
2
+ kind: job_template
3
+ name: Add Public Keys - SSH Default
4
+ job_category: Commands
5
+ description_format: "Add Public Key %{public key}"
6
+ provider_type: SSH
7
+ template_inputs:
8
+ - name: public key
9
+ description: Public key to add to the host
10
+ input_type: user
11
+ required: true
12
+ %>
13
+ PUBLIC_KEY="<%= input("public key") %>"
14
+ SSH_DIR="${HOME}/.ssh"
15
+ AUTHORIZED_KEYS="${SSH_DIR/authorized_keys"
16
+
17
+ umask 077
18
+ [ -d "$SSH_DIR" ] || mkdir -p "$SSH_DIR"
19
+
20
+ if ! grep -q "$PUBLIC_KEY" "$SSH_DIR"; then
21
+ echo "$PUBLIC_KEY" >> "$AUTHORIZED_KEYS"
22
+ fi
@@ -0,0 +1,34 @@
1
+ <%#
2
+ kind: job_template
3
+ name: Register Content Host - SSH Default
4
+ job_category: Commands
5
+ description_format: "Register Content Host using activation key %{activation key}"
6
+ provider_type: SSH
7
+ template_inputs:
8
+ - name: activation key
9
+ description: Name of the Activation Key to use for registering the host
10
+ input_type: user
11
+ required: true
12
+ - name: organization name
13
+ description: Name of the Organization to register the host to
14
+ input_type: user
15
+ required: true
16
+ %>
17
+ # Install Katello's certificates
18
+ yum localinstall -y <%= foreman_server_url %>/pub/katello-ca-consumer-latest.noarch.rpm
19
+
20
+ # Install subscription-manager
21
+ yum install -y subscription-manager
22
+
23
+ # Register the host
24
+ subscription-manager register \
25
+ --org="<%= input("organization name") %> \
26
+ --activationkey="<%= input("activation key") %>
27
+
28
+ # Enable repository with katello-agent
29
+ yum install -y http://fedorapeople.org/groups/katello/releases/yum/3.4/client/el7/x86_64/katello-client-repos-latest.rpm
30
+
31
+ # Install katello-agent
32
+ yum -y install katello-agent
33
+ systemctl enable goferd
34
+ systemctl start goferd