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.
- checksums.yaml +7 -0
- data/LICENSE +619 -0
- data/README.md +102 -0
- data/Rakefile +47 -0
- data/app/controllers/foreman_probing/api/v2/scans_controller.rb +66 -0
- data/app/controllers/foreman_probing/hosts_controller.rb +14 -0
- data/app/controllers/foreman_probing/scans_controller.rb +47 -0
- data/app/helpers/concerns/foreman_probing/hosts_helper_extensions.rb +9 -0
- data/app/helpers/concerns/foreman_probing/subnet_helper_extensions.rb +7 -0
- data/app/helpers/foreman_probing/scans_helper.rb +42 -0
- data/app/lib/actions/create_subnets.rb +27 -0
- data/app/lib/actions/import_host_facts.rb +85 -0
- data/app/lib/actions/perform_scan.rb +26 -0
- data/app/lib/actions/process_host.rb +18 -0
- data/app/lib/actions/process_scan.rb +21 -0
- data/app/lib/actions/scan_host.rb +35 -0
- data/app/lib/actions/update_probing_facet.rb +44 -0
- data/app/models/concerns/foreman_probing/foreman_tasks_task_extensions.rb +9 -0
- data/app/models/concerns/foreman_probing/host_extensions.rb +10 -0
- data/app/models/concerns/foreman_probing/subnet_extensions.rb +21 -0
- data/app/models/foreman_probing/fact_name.rb +11 -0
- data/app/models/foreman_probing/port.rb +21 -0
- data/app/models/foreman_probing/probing_facet.rb +27 -0
- data/app/models/foreman_probing/scan.rb +42 -0
- data/app/models/foreman_probing/scan_composer.rb +75 -0
- data/app/models/foreman_probing/scan_host.rb +8 -0
- data/app/models/foreman_probing/service.rb +14 -0
- data/app/models/foreman_probing/targeting/direct.rb +50 -0
- data/app/models/foreman_probing/targeting/search.rb +23 -0
- data/app/models/foreman_probing/targeting/subnet.rb +17 -0
- data/app/models/foreman_probing/targeting/subnet_discovery.rb +12 -0
- data/app/models/foreman_probing/targeting.rb +12 -0
- data/app/overrides/dashboard/index/sample_override.html.erb.deface +4 -0
- data/app/overrides/open_ports_tab.rb +14 -0
- data/app/services/foreman_probing/fact_parser.rb +47 -0
- data/app/services/foreman_probing/structured_fact_importer.rb +20 -0
- data/app/views/dashboard/_foreman_probing_widget.html.erb +2 -0
- data/app/views/foreman_probing/api/v2/scans/base.json.rabl +3 -0
- data/app/views/foreman_probing/api/v2/scans/index.json.rabl +3 -0
- data/app/views/foreman_probing/api/v2/scans/show.json.rabl +3 -0
- data/app/views/foreman_probing/hosts/_open_ports.html.erb +19 -0
- data/app/views/foreman_probing/hosts/hosts/new_action.html.erb +1 -0
- data/app/views/foreman_probing/hosts/new_action.html.erb +1 -0
- data/app/views/foreman_probing/layouts/layouts/new_layout.html.erb +0 -0
- data/app/views/foreman_probing/layouts/new_layout.html.erb +0 -0
- data/app/views/foreman_probing/probing_facets/_open_ports_tab_content.html.erb +6 -0
- data/app/views/foreman_probing/probing_facets/_open_ports_tab_title.html.erb +4 -0
- data/app/views/foreman_probing/scans/index.html.erb +31 -0
- data/app/views/foreman_probing/scans/new.html.erb +51 -0
- data/app/views/foreman_probing/scans/show.html.erb +41 -0
- data/app/views/foreman_probing/scans/show.js.erb +0 -0
- data/app/views/templates/ssh/add_public_keys.erb +22 -0
- data/app/views/templates/ssh/register_content_host.erb +34 -0
- data/app/views/templates/ssh/register_puppet.erb +19 -0
- data/config/routes.rb +28 -0
- data/db/migrate/20170401154201_create_foreman_probing_facets.rb +9 -0
- data/db/migrate/20170401154714_create_foreman_probing_ports.rb +13 -0
- data/db/migrate/20170401154726_create_foreman_probing_services.rb +10 -0
- data/db/migrate/20170620180935_create_foreman_probing_scans.rb +15 -0
- data/db/migrate/20170701190511_create_foreman_probing_targetings.rb +9 -0
- data/db/seeds.d/70-job_templates.rb +7 -0
- data/lib/foreman_probing/engine.rb +124 -0
- data/lib/foreman_probing/version.rb +3 -0
- data/lib/foreman_probing.rb +5 -0
- data/locale/Makefile +60 -0
- data/locale/en/foreman_probing.po +19 -0
- data/locale/foreman_probing.pot +19 -0
- data/locale/gemspec.rb +2 -0
- data/test/factories/foreman_probing_factories.rb +5 -0
- data/test/test_plugin_helper.rb +6 -0
- data/test/unit/foreman_probing_test.rb +11 -0
- 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,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 < 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,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,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>
|
File without changes
|
File without changes
|
@@ -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
|