foreman_probing 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|