foreman_probing 0.0.1

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 (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