nexpose 0.0.9 → 0.0.91
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.
- data/lib/nexpose.rb +13 -3236
- data/lib/nexpose/api_request.rb +144 -0
- data/lib/nexpose/connection.rb +106 -0
- data/lib/nexpose/creds.rb +189 -0
- data/lib/nexpose/error.rb +21 -0
- data/lib/nexpose/misc.rb +122 -0
- data/lib/nexpose/report.rb +570 -0
- data/lib/nexpose/scan.rb +280 -0
- data/lib/nexpose/scan_engine.rb +147 -0
- data/lib/nexpose/silo.rb +347 -0
- data/lib/nexpose/site.rb +877 -0
- data/lib/nexpose/ticket.rb +108 -0
- data/lib/nexpose/util.rb +35 -0
- data/lib/nexpose/vuln.rb +520 -0
- data/nexpose.gemspec +3 -3
- metadata +22 -11
data/lib/nexpose/scan.rb
ADDED
@@ -0,0 +1,280 @@
|
|
1
|
+
module Nexpose
|
2
|
+
module NexposeAPI
|
3
|
+
include XMLUtils
|
4
|
+
|
5
|
+
def scan_stop(param)
|
6
|
+
r = execute(make_xml('ScanStopRequest', {'scan-id' => param}))
|
7
|
+
r.success
|
8
|
+
end
|
9
|
+
|
10
|
+
def scan_status(param)
|
11
|
+
r = execute(make_xml('ScanStatusRequest', {'scan-id' => param}))
|
12
|
+
r.success ? r.attributes['status'] : nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def scan_activity
|
16
|
+
r = execute(make_xml('ScanActivityRequest', {}))
|
17
|
+
if (r.success)
|
18
|
+
res = []
|
19
|
+
r.res.elements.each("//ScanSummary") do |scan|
|
20
|
+
res << {
|
21
|
+
:scan_id => scan.attributes['scan-id'].to_i,
|
22
|
+
:site_id => scan.attributes['site-id'].to_i,
|
23
|
+
:engine_id => scan.attributes['engine-id'].to_i,
|
24
|
+
:status => scan.attributes['status'].to_s,
|
25
|
+
:start_time => Date.parse(scan.attributes['startTime'].to_s).to_time
|
26
|
+
}
|
27
|
+
end
|
28
|
+
res
|
29
|
+
else
|
30
|
+
false
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def scan_statistics(param)
|
35
|
+
r = execute(make_xml('ScanStatisticsRequest', {'scan-id' => param}))
|
36
|
+
if (r.success)
|
37
|
+
res = {}
|
38
|
+
r.res.elements.each("//ScanSummary/nodes") do |node|
|
39
|
+
res[:nodes] = {}
|
40
|
+
node.attributes.keys.each do |k|
|
41
|
+
res[:nodes][k] = node.attributes[k].to_i
|
42
|
+
end
|
43
|
+
end
|
44
|
+
r.res.elements.each("//ScanSummary/tasks") do |task|
|
45
|
+
res[:task] = {}
|
46
|
+
task.attributes.keys.each do |k|
|
47
|
+
res[:task][k] = task.attributes[k].to_i
|
48
|
+
end
|
49
|
+
end
|
50
|
+
r.res.elements.each("//ScanSummary/vulnerabilities") do |vuln|
|
51
|
+
res[:vulns] ||= {}
|
52
|
+
k = vuln.attributes['status'] + (vuln.attributes['severity'] ? ("-" + vuln.attributes['severity']) : '')
|
53
|
+
res[:vulns][k] = vuln.attributes['count'].to_i
|
54
|
+
end
|
55
|
+
r.res.elements.each("//ScanSummary") do |summ|
|
56
|
+
res[:summary] = {}
|
57
|
+
summ.attributes.keys.each do |k|
|
58
|
+
res[:summary][k] = summ.attributes[k]
|
59
|
+
if (res[:summary][k] =~ /^\d+$/)
|
60
|
+
res[:summary][k] = res[:summary][k].to_i
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
r.res.elements.each("//ScanSummary/message") do |message|
|
65
|
+
res[:message] = message.text
|
66
|
+
end
|
67
|
+
res
|
68
|
+
else
|
69
|
+
false
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# === Description
|
75
|
+
# Object that represents a summary of a scan.
|
76
|
+
#
|
77
|
+
class ScanSummary
|
78
|
+
# The Scan ID of the Scan
|
79
|
+
attr_reader :scan_id
|
80
|
+
# The Engine ID used to perform the scan
|
81
|
+
attr_reader :engine_id
|
82
|
+
# TODO: add description
|
83
|
+
attr_reader :name
|
84
|
+
# The scan start time
|
85
|
+
attr_reader :startTime
|
86
|
+
# The scan finish time
|
87
|
+
attr_reader :endTime
|
88
|
+
# The scan status (running|finished|stopped|error| dispatched|paused|aborted|uknown)
|
89
|
+
attr_reader :status
|
90
|
+
# The number of pending tasks
|
91
|
+
attr_reader :tasks_pending
|
92
|
+
# The number of active tasks
|
93
|
+
attr_reader :tasks_active
|
94
|
+
# The number of completed tasks
|
95
|
+
attr_reader :tasks_completed
|
96
|
+
# The number of "live" nodes
|
97
|
+
attr_reader :nodes_live
|
98
|
+
# The number of "dead" nodes
|
99
|
+
attr_reader :nodes_dead
|
100
|
+
# The number of filtered nodes
|
101
|
+
attr_reader :nodes_filtered
|
102
|
+
# The number of unresolved nodes
|
103
|
+
attr_reader :nodes_unresolved
|
104
|
+
# The number of "other" nodes
|
105
|
+
attr_reader :nodes_other
|
106
|
+
# Confirmed vulnerabilities found (indexed by severity)
|
107
|
+
# Associative array, indexed by severity
|
108
|
+
attr_reader :vuln_exploit
|
109
|
+
# Unconfirmed vulnerabilities found (indexed by severity)
|
110
|
+
# Associative array, indexed by severity
|
111
|
+
attr_reader :vuln_version
|
112
|
+
# Not vulnerable checks run (confirmed)
|
113
|
+
attr_reader :not_vuln_exploit
|
114
|
+
# Not vulnerable checks run (unconfirmed)
|
115
|
+
attr_reader :not_vuln_version
|
116
|
+
# Vulnerability check errors
|
117
|
+
attr_reader :vuln_error
|
118
|
+
# Vulnerability checks disabled
|
119
|
+
attr_reader :vuln_disabled
|
120
|
+
# Vulnerability checks other
|
121
|
+
attr_reader :vuln_other
|
122
|
+
|
123
|
+
# Constructor
|
124
|
+
# ScanSummary(can_id, $engine_id, $name, tartTime, $endTime, tatus)
|
125
|
+
def initialize(scan_id, engine_id, name, startTime, endTime, status)
|
126
|
+
|
127
|
+
@scan_id = scan_id
|
128
|
+
@engine_id = engine_id
|
129
|
+
@name = name
|
130
|
+
@startTime = startTime
|
131
|
+
@endTime = endTime
|
132
|
+
@status = status
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
# TODO
|
139
|
+
# === Description
|
140
|
+
# Object that represents the overview statistics for a particular scan.
|
141
|
+
#
|
142
|
+
# === Examples
|
143
|
+
#
|
144
|
+
# # Create a new Nexpose Connection on the default port and Login
|
145
|
+
# nsc = Connection.new("10.1.40.10","nxadmin","password")
|
146
|
+
# nsc.login()
|
147
|
+
#
|
148
|
+
# # Get a Site (Site ID = 12) from the NSC
|
149
|
+
# site = new Site(nsc,12)
|
150
|
+
#
|
151
|
+
# # Start a Scan of this site and pause for 1 minute
|
152
|
+
# scan1 = site.scanSite()
|
153
|
+
# sleep(60)
|
154
|
+
#
|
155
|
+
# # Get the Scan Statistics for this scan
|
156
|
+
# scanStatistics = new ScanStatistics(nsc,scan1["scan_id"])
|
157
|
+
#
|
158
|
+
# # Print out number of confirmed vulnerabilities with a 10 severity
|
159
|
+
# puts scanStatistics.scansummary.vuln_exploit[10]
|
160
|
+
#
|
161
|
+
# # Print out the number of pending tasks left in the scan
|
162
|
+
# puts scanStatistics.scan_summary.tasks_pending
|
163
|
+
#
|
164
|
+
class ScanStatistics
|
165
|
+
# true if an error condition exists; false otherwise
|
166
|
+
attr_reader :error
|
167
|
+
# Error message string
|
168
|
+
attr_reader :error_msg
|
169
|
+
# The last XML request sent by this object
|
170
|
+
attr_reader :request_xml
|
171
|
+
# The last XML response received by this object
|
172
|
+
attr_reader :reseponse_xml
|
173
|
+
# The Scan ID
|
174
|
+
attr_reader :scan_id
|
175
|
+
# The ScanSummary of the scan
|
176
|
+
attr_reader :scan_summary
|
177
|
+
# The NSC Connection associated with this object
|
178
|
+
attr_reader :connection
|
179
|
+
|
180
|
+
# Vulnerability checks other
|
181
|
+
attr_reader :vuln_other
|
182
|
+
|
183
|
+
def initialize(connection, scan_id)
|
184
|
+
@error = false
|
185
|
+
@connection = connection
|
186
|
+
@scan_id = scan_id
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
# TODO add engineID
|
191
|
+
# === Description
|
192
|
+
# Object that represents the scanning configuration for a Site.
|
193
|
+
#
|
194
|
+
class ScanConfig
|
195
|
+
# A unique ID for this scan configuration
|
196
|
+
attr_reader :configID
|
197
|
+
# The name of the scan template
|
198
|
+
attr_reader :name
|
199
|
+
# The ID of the scan template used full-audit, exhaustive-audit, web-audit, dos-audit, internet-audit, network-audit
|
200
|
+
attr_reader :templateID
|
201
|
+
# The configuration version (default is 2)
|
202
|
+
attr_reader :configVersion
|
203
|
+
# Array of (Schedule)*
|
204
|
+
attr_reader :schedules
|
205
|
+
# Array of (ScanTrigger)*
|
206
|
+
attr_reader :scanTriggers
|
207
|
+
|
208
|
+
def initialize(configID, name, templateID, configVersion = 2)
|
209
|
+
|
210
|
+
@configID = configID
|
211
|
+
@name = name
|
212
|
+
@templateID = templateID
|
213
|
+
@configVersion = configVersion
|
214
|
+
@schedules = Array.new()
|
215
|
+
@scanTriggers = Array.new()
|
216
|
+
|
217
|
+
end
|
218
|
+
|
219
|
+
# Adds a new Schedule for this ScanConfig
|
220
|
+
def addSchedule(schedule)
|
221
|
+
@schedules.push(schedule)
|
222
|
+
end
|
223
|
+
|
224
|
+
# Adds a new ScanTrigger to the scanTriggers array
|
225
|
+
def addScanTrigger(scanTrigger)
|
226
|
+
@scanTriggers.push(scanTrigger)
|
227
|
+
end
|
228
|
+
|
229
|
+
def _set_configID(configID)
|
230
|
+
@configID = configID
|
231
|
+
end
|
232
|
+
|
233
|
+
def _set_name(name)
|
234
|
+
@name = name
|
235
|
+
end
|
236
|
+
|
237
|
+
end
|
238
|
+
|
239
|
+
# TODO: review
|
240
|
+
# <scanFilter scanStop='0' scanFailed='0' scanStart='1'/>
|
241
|
+
# === Description
|
242
|
+
#
|
243
|
+
class ScanFilter
|
244
|
+
|
245
|
+
attr_reader :scanStop
|
246
|
+
attr_reader :scanFailed
|
247
|
+
attr_reader :scanStart
|
248
|
+
|
249
|
+
def initialize(scanstop, scanFailed, scanStart)
|
250
|
+
|
251
|
+
@scanStop = scanStop
|
252
|
+
@scanFailed = scanFailed
|
253
|
+
@scanStart = scanStart
|
254
|
+
|
255
|
+
end
|
256
|
+
|
257
|
+
end
|
258
|
+
|
259
|
+
|
260
|
+
# === Description
|
261
|
+
# Object that holds an event that triggers the start of a scan.
|
262
|
+
#
|
263
|
+
class ScanTrigger
|
264
|
+
# Type of Trigger (AutoUpdate)
|
265
|
+
attr_reader :type
|
266
|
+
# Enable or disable this scan trigger
|
267
|
+
attr_reader :enabled
|
268
|
+
# Sets the trigger to start an incremental scan or a full scan
|
269
|
+
attr_reader :incremental
|
270
|
+
|
271
|
+
def initialize(type, incremental, enabled = 1)
|
272
|
+
|
273
|
+
@type = type
|
274
|
+
@incremental = incremental
|
275
|
+
@enabled = enabled
|
276
|
+
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
module Nexpose
|
2
|
+
|
3
|
+
# ==== Description
|
4
|
+
# Object that represents a listing of all of the scan engines available on to an NSC.
|
5
|
+
#
|
6
|
+
class EngineListing
|
7
|
+
# true if an error condition exists; false otherwise
|
8
|
+
attr_reader :error
|
9
|
+
# Error message string
|
10
|
+
attr_reader :error_msg
|
11
|
+
# The last XML request sent by this object
|
12
|
+
attr_reader :request_xml
|
13
|
+
# The last XML response received by this object
|
14
|
+
attr_reader :response_xml
|
15
|
+
# The NSC Connection associated with this object
|
16
|
+
attr_reader :connection
|
17
|
+
# Array containing (EngineSummary*)
|
18
|
+
attr_reader :engines
|
19
|
+
# The number of scan engines
|
20
|
+
attr_reader :engine_count
|
21
|
+
|
22
|
+
# Constructor
|
23
|
+
# EngineListing (connection)
|
24
|
+
def initialize(connection)
|
25
|
+
@connection = connection
|
26
|
+
@engines = []
|
27
|
+
@engine_count = 0
|
28
|
+
@error = false
|
29
|
+
r = @connection.execute('<EngineListingRequest session-id="' + @connection.session_id + '"/>', '1.2')
|
30
|
+
|
31
|
+
if (r.success)
|
32
|
+
r.res.elements.each('EngineListingResponse/EngineSummary') do |v|
|
33
|
+
@engines.push(EngineSummary.new(v.attributes['id'], v.attributes['name'], v.attributes['address'],
|
34
|
+
v.attributes['port'], v.attributes['status']))
|
35
|
+
end
|
36
|
+
else
|
37
|
+
@error = true
|
38
|
+
@error_msg = 'EngineListingRequest Parse Error'
|
39
|
+
end
|
40
|
+
@engine_count = @engines.length
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# TODO
|
45
|
+
class EngineActivity
|
46
|
+
# true if an error condition exists; false otherwise
|
47
|
+
attr_reader :error
|
48
|
+
# Error message string
|
49
|
+
attr_reader :error_msg
|
50
|
+
# The last XML request sent by this object
|
51
|
+
attr_reader :request_xml
|
52
|
+
# The last XML response received by this object
|
53
|
+
attr_reader :response_xml
|
54
|
+
# The NSC Connection associated with this object
|
55
|
+
attr_reader :connection
|
56
|
+
# The Engine ID
|
57
|
+
attr_reader :engine_id
|
58
|
+
# Array containing (ScanSummary*)
|
59
|
+
attr_reader :scan_summaries
|
60
|
+
end
|
61
|
+
|
62
|
+
# ==== Description
|
63
|
+
# Object that represents the summary of a scan engine.
|
64
|
+
#
|
65
|
+
# ==== Examples
|
66
|
+
#
|
67
|
+
# # Create a new Nexpose Connection on the default port and Login
|
68
|
+
# nsc = Connection.new("10.1.40.10","nxadmin","password")
|
69
|
+
# nsc.login()
|
70
|
+
#
|
71
|
+
# # Get the engine listing for the connection
|
72
|
+
# enginelisting = EngineListing.new(nsc)
|
73
|
+
#
|
74
|
+
# # Print out the status of the first scan engine
|
75
|
+
# puts enginelisting.engines[0].status
|
76
|
+
#
|
77
|
+
class EngineSummary
|
78
|
+
# A unique ID that identifies this scan engine
|
79
|
+
attr_reader :id
|
80
|
+
# The name of this scan engine
|
81
|
+
attr_reader :name
|
82
|
+
# The hostname or IP address of the engine
|
83
|
+
attr_reader :address
|
84
|
+
# The port there the engine is listening
|
85
|
+
attr_reader :port
|
86
|
+
# The engine status (active|pending-auth| incompatible|not-responding|unknown)
|
87
|
+
attr_reader :status
|
88
|
+
|
89
|
+
# Constructor
|
90
|
+
# EngineSummary(id, name, address, port, status)
|
91
|
+
def initialize(id, name, address, port, status)
|
92
|
+
@id = id
|
93
|
+
@name = name
|
94
|
+
@address = address
|
95
|
+
@port = port
|
96
|
+
@status = status
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
#-------------------------------------------------------------------------------------------------------------------
|
102
|
+
#
|
103
|
+
#-------------------------------------------------------------------------------------------------------------------
|
104
|
+
class EngineConfig
|
105
|
+
attr_accessor :id
|
106
|
+
attr_accessor :address
|
107
|
+
attr_accessor :name
|
108
|
+
attr_accessor :port
|
109
|
+
attr_accessor :scope
|
110
|
+
attr_accessor :sites
|
111
|
+
attr_accessor :priority
|
112
|
+
|
113
|
+
def initialize(connection, engine_id)
|
114
|
+
@connection = connection
|
115
|
+
@id = nil
|
116
|
+
@address = nil
|
117
|
+
@name = nil
|
118
|
+
@port = nil
|
119
|
+
@scope = nil
|
120
|
+
@priority = 'global'
|
121
|
+
@sites = []
|
122
|
+
|
123
|
+
r = @connection.execute('<EngineConfigRequest session-id="' + @connection.session_id + '" engine-id="' + engine_id + '"/>', '1.2')
|
124
|
+
|
125
|
+
if (r.success)
|
126
|
+
r.res.elements.each('EngineConfigResponse/EngineConfig') do |v|
|
127
|
+
@id = v.attributes['id']
|
128
|
+
@address = v.attributes['address']
|
129
|
+
@name = v.attributes['name']
|
130
|
+
@port = v.attributes['port']
|
131
|
+
@scope = v.attributes['scope']
|
132
|
+
v.elements.each('Site') do |s|
|
133
|
+
@sites << s.attributes['id']
|
134
|
+
end
|
135
|
+
end
|
136
|
+
else
|
137
|
+
@error = true
|
138
|
+
@error_msg = 'EngineConfigRequest Parse Error'
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def save
|
143
|
+
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
data/lib/nexpose/silo.rb
ADDED
@@ -0,0 +1,347 @@
|
|
1
|
+
module Nexpose
|
2
|
+
module NexposeAPI
|
3
|
+
include XMLUtils
|
4
|
+
|
5
|
+
###################
|
6
|
+
# SILO MANAGEMENT #
|
7
|
+
###################
|
8
|
+
|
9
|
+
#########################
|
10
|
+
# MULTI-TENANT USER OPS #
|
11
|
+
#########################
|
12
|
+
|
13
|
+
#-------------------------------------------------------------------------
|
14
|
+
# Creates a multi-tenant user
|
15
|
+
#
|
16
|
+
# user_config - A map of the user data.
|
17
|
+
#
|
18
|
+
# REQUIRED PARAMS
|
19
|
+
# user-id, authsrcid, user-name, full-name, enabled, superuser
|
20
|
+
#
|
21
|
+
# OPTIONAL PARAMS
|
22
|
+
# email, password
|
23
|
+
#
|
24
|
+
# silo_configs - An array of maps of silo specific data
|
25
|
+
#
|
26
|
+
# REQUIRED PARAMS
|
27
|
+
# silo-id, role-name, all-groups, all-sites, default-silo
|
28
|
+
#
|
29
|
+
# allowed_groups/allowed_sites - An array of ids
|
30
|
+
#-------------------------------------------------------------------------
|
31
|
+
def create_multi_tenant_user(user_config, silo_configs)
|
32
|
+
xml = make_xml('MultiTenantUserCreateRequest')
|
33
|
+
mtu_config_xml = make_xml('MultiTenantUserConfig', user_config, '', false)
|
34
|
+
|
35
|
+
# Add the silo access
|
36
|
+
silo_xml = make_xml('SiloAccesses', {}, '', false)
|
37
|
+
silo_config_xml = make_xml('SiloAccess', {}, '', false)
|
38
|
+
silo_configs.keys.each do |k|
|
39
|
+
if k.eql? 'allowed_sites'
|
40
|
+
allowed_sites_xml = make_xml('AllowedSites', {}, '', false)
|
41
|
+
silo_configs['allowed_sites'].each do |allowed_site|
|
42
|
+
allowed_sites_xml.add_element make_xml('AllowedSite', {'id' => allowed_site}, '', false)
|
43
|
+
end
|
44
|
+
silo_config_xml.add_element allowed_sites_xml
|
45
|
+
elsif k.eql? 'allowed_groups'
|
46
|
+
allowed_groups_xml = make_xml('AllowedGroups', {}, '', false)
|
47
|
+
silo_configs['allowed_groups'].each do |allowed_group|
|
48
|
+
allowed_groups_xml.add_element make_xml('AllowedGroup', {'id' => allowed_group}, '', false)
|
49
|
+
end
|
50
|
+
silo_config_xml.add_element allowed_groups_xml
|
51
|
+
else
|
52
|
+
silo_config_xml.attributes[k] = silo_configs[k]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
silo_xml.add_element silo_config_xml
|
56
|
+
mtu_config_xml.add_element silo_xml
|
57
|
+
xml.add_element mtu_config_xml
|
58
|
+
r = execute xml, '1.2'
|
59
|
+
r.success
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
#-------------------------------------------------------------------------
|
64
|
+
# Lists all the multi-tenant users and their attributes.
|
65
|
+
#-------------------------------------------------------------------------
|
66
|
+
def list_mtu
|
67
|
+
xml = make_xml('MultiTenantUserListingRequest')
|
68
|
+
r = execute xml, '1.2'
|
69
|
+
|
70
|
+
if r.success
|
71
|
+
res = []
|
72
|
+
r.res.elements.each("//MultiTenantUserSummary") do |mtu|
|
73
|
+
res << {
|
74
|
+
:id => mtu.attributes['id'],
|
75
|
+
:full_name => mtu.attributes['full-name'],
|
76
|
+
:user_name => mtu.attributes['user-name'],
|
77
|
+
:email => mtu.attributes['email'],
|
78
|
+
:super_user => mtu.attributes['superuser'],
|
79
|
+
:enabled => mtu.attributes['enabled'],
|
80
|
+
:auth_module => mtu.attributes['auth-module'],
|
81
|
+
:silo_count => mtu.attributes['silo-count'],
|
82
|
+
:locked => mtu.attributes['locked']
|
83
|
+
}
|
84
|
+
end
|
85
|
+
res
|
86
|
+
else
|
87
|
+
false
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
#-------------------------------------------------------------------------
|
92
|
+
# Delete a multi-tenant user
|
93
|
+
#-------------------------------------------------------------------------
|
94
|
+
def delete_mtu user_name, user_id
|
95
|
+
using_user_name = (user_name and not user_name.empty?)
|
96
|
+
xml = make_xml('MultiTenantUserDeleteRequest', (using_user_name ? {'user-name' => user_name} : {'user-id' => user_id}))
|
97
|
+
r = execute xml, '1.2'
|
98
|
+
r.success
|
99
|
+
end
|
100
|
+
|
101
|
+
####################
|
102
|
+
# SILO PROFILE OPS #
|
103
|
+
####################
|
104
|
+
|
105
|
+
#-------------------------------------------------------------------------
|
106
|
+
# Creates a silo profile
|
107
|
+
#
|
108
|
+
# silo_config - A map of the silo data.
|
109
|
+
#
|
110
|
+
# REQUIRED PARAMS
|
111
|
+
# id, name, all‐licensed-modules, all‐global-engines, all-global-report-templates, all‐global-scan‐templates
|
112
|
+
#
|
113
|
+
# OPTIONAL PARAMS
|
114
|
+
# description
|
115
|
+
#
|
116
|
+
# permissions - A map of an array of maps of silo specific data
|
117
|
+
#
|
118
|
+
# REQUIRED PARAMS
|
119
|
+
# silo-id, role-name, all-groups, all-sites, default-silo
|
120
|
+
#
|
121
|
+
# allowed_groups/allowed_sites - An array of ids
|
122
|
+
#-------------------------------------------------------------------------
|
123
|
+
def create_silo_profile silo_profile_config, permissions
|
124
|
+
xml = make_xml 'SiloProfileCreateRequest'
|
125
|
+
spc_xml = make_xml('SiloProfileConfig', silo_profile_config, '', false)
|
126
|
+
|
127
|
+
# Add the permissions
|
128
|
+
if permissions['global_report_templates']
|
129
|
+
grt_xml = make_xml('GlobalReportTemplates', {}, '', false)
|
130
|
+
permissions['global_report_templates'].each do |name|
|
131
|
+
grt_xml.add_element make_xml('GlobalReportTemplate', {'name' => name}, '', false)
|
132
|
+
end
|
133
|
+
spc_xml.add_element grt_xml
|
134
|
+
end
|
135
|
+
|
136
|
+
if permissions['global_scan_engines']
|
137
|
+
gse_xml = make_xml('GlobalScanEngines', {}, '', false)
|
138
|
+
permissions['global_scan_engines'].each do |name|
|
139
|
+
gse_xml.add_element make_xml('GlobalScanEngine', {'name' => name}, '', false)
|
140
|
+
end
|
141
|
+
spc_xml.add_element gse_xml
|
142
|
+
end
|
143
|
+
|
144
|
+
if permissions['global_scan_templates']
|
145
|
+
gst_xml = make_xml('GlobalScanTemplates', {}, '', false)
|
146
|
+
permissions['global_scan_templates'].each do |name|
|
147
|
+
gst_xml.add_element make_xml('GlobalScanTemplate', {'name' => name}, '', false)
|
148
|
+
end
|
149
|
+
spc_xml.add_element gst_xml
|
150
|
+
end
|
151
|
+
|
152
|
+
if permissions['licensed_modules']
|
153
|
+
lm_xml = make_xml('LicensedModules', {}, '', false)
|
154
|
+
permissions['licensed_modules'].each do |name|
|
155
|
+
lm_xml.add_element make_xml('LicensedModule', {'name' => name}, '', false)
|
156
|
+
end
|
157
|
+
spc_xml.add_element lm_xml
|
158
|
+
end
|
159
|
+
|
160
|
+
if permissions['restricted_report_formats']
|
161
|
+
rrf_xml = make_xml('RestrictedReportFormats', {}, '', false)
|
162
|
+
permissions['restricted_report_formats'].each do |name|
|
163
|
+
rrf_xml.add_element make_xml('RestrictedReportFormat', {'name' => name}, '', false)
|
164
|
+
end
|
165
|
+
spc_xml.add_element rrf_xml
|
166
|
+
end
|
167
|
+
|
168
|
+
if permissions['restricted_report_sections']
|
169
|
+
rrs_xml = make_xml('RestrictedReportSections', {}, '', false)
|
170
|
+
permissions['restricted_report_sections'].each do |name|
|
171
|
+
rrs_xml.add_element make_xml('RestrictedReportSection', {'name' => name}, '', false)
|
172
|
+
end
|
173
|
+
spc_xml.add_element rrs_xml
|
174
|
+
end
|
175
|
+
|
176
|
+
xml.add_element spc_xml
|
177
|
+
r = execute xml, '1.2'
|
178
|
+
r.success
|
179
|
+
end
|
180
|
+
|
181
|
+
#-------------------------------------------------------------------------
|
182
|
+
# Lists all the silo profiles and their attributes.
|
183
|
+
#-------------------------------------------------------------------------
|
184
|
+
def list_silo_profiles
|
185
|
+
xml = make_xml('SiloProfileListingRequest')
|
186
|
+
r = execute xml, '1.2'
|
187
|
+
|
188
|
+
if r.success
|
189
|
+
res = []
|
190
|
+
r.res.elements.each("//SiloProfileSummary") do |silo_profile|
|
191
|
+
res << {
|
192
|
+
:id => silo_profile.attributes['id'],
|
193
|
+
:name => silo_profile.attributes['name'],
|
194
|
+
:description => silo_profile.attributes['description'],
|
195
|
+
:global_report_template_count => silo_profile.attributes['global-report-template-count'],
|
196
|
+
:global_scan_engine_count => silo_profile.attributes['global-scan-engine-count'],
|
197
|
+
:global_scan_template_count => silo_profile.attributes['global-scan-template-count'],
|
198
|
+
:licensed_module_count => silo_profile.attributes['licensed-module-count'],
|
199
|
+
:restricted_report_section_count => silo_profile.attributes['restricted-report-section-count'],
|
200
|
+
:all_licensed_modules => silo_profile.attributes['all-licensed-modules'],
|
201
|
+
:all_global_engines => silo_profile.attributes['all-global-engines'],
|
202
|
+
:all_global_report_templates => silo_profile.attributes['all-global-report-templates'],
|
203
|
+
:all_global_scan_templates => silo_profile.attributes['all-global-scan-templates']
|
204
|
+
}
|
205
|
+
end
|
206
|
+
res
|
207
|
+
else
|
208
|
+
false
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
#-------------------------------------------------------------------------
|
213
|
+
# Delete a silo profile
|
214
|
+
#-------------------------------------------------------------------------
|
215
|
+
def delete_silo_profile name, id
|
216
|
+
using_name = (name and not name.empty?)
|
217
|
+
xml = make_xml('SiloProfileDeleteRequest', (using_name ? {'name' => name} : {'silo-profile-id' => id}))
|
218
|
+
r = execute xml, '1.2'
|
219
|
+
r.success
|
220
|
+
end
|
221
|
+
|
222
|
+
####################
|
223
|
+
# SILO OPS #
|
224
|
+
####################
|
225
|
+
|
226
|
+
#-------------------------------------------------------------------------
|
227
|
+
# Creates a silo
|
228
|
+
#
|
229
|
+
# silo_config - A map of the silo creation data.
|
230
|
+
#
|
231
|
+
# REQUIRED PARAMS
|
232
|
+
# id, name, silo-profile-id, max-assets, max-hosted-assets, max-users
|
233
|
+
#
|
234
|
+
# OPTIONAL PARAMS
|
235
|
+
# description
|
236
|
+
#-------------------------------------------------------------------------
|
237
|
+
def create_silo silo_config
|
238
|
+
xml = make_xml 'SiloCreateRequest'
|
239
|
+
silo_config_xml = make_xml 'SiloConfig', {}, '', false
|
240
|
+
|
241
|
+
# Add the attributes
|
242
|
+
silo_config.keys.each do |key|
|
243
|
+
if not 'merchant'.eql? key and not 'organization'.eql? key
|
244
|
+
silo_config_xml.attributes[key] = silo_config[key]
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
# Add Organization info
|
249
|
+
if silo_config['organization']
|
250
|
+
org_xml = make_xml 'Organization', {}, '', false
|
251
|
+
silo_config['organization'].keys.each do |key|
|
252
|
+
if not 'address'.eql? key
|
253
|
+
org_xml.attributes[key] = silo_config['organization'][key]
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
address_xml = make_xml 'Address', silo_config['organization']['address'], '', false
|
258
|
+
org_xml.add_element address_xml
|
259
|
+
silo_config_xml.add_element org_xml
|
260
|
+
end
|
261
|
+
|
262
|
+
# Add Merchant info
|
263
|
+
if silo_config['merchant']
|
264
|
+
merchant_xml = make_xml 'Merchant', {}, '', false
|
265
|
+
|
266
|
+
silo_config['merchant'].keys.each do |key|
|
267
|
+
if not 'dba'.eql? key and not 'other_industries'.eql? key and not 'qsa'.eql? key and not 'address'.eql? key
|
268
|
+
merchant_xml.attributes[key] = silo_config['merchant'][key]
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
# Add the merchant address
|
273
|
+
merchant_address_xml = make_xml 'Address', silo_config['merchant']['address'], '', false
|
274
|
+
merchant_xml.add_element merchant_address_xml
|
275
|
+
|
276
|
+
#Now add the complex data types
|
277
|
+
if silo_config['merchant']['dba']
|
278
|
+
dba_xml = make_xml 'DBAs', {}, '', false
|
279
|
+
silo_config['merchant']['dba'].each do |name|
|
280
|
+
dba_xml.add_element make_xml('DBA', {'name' => name}, '', false)
|
281
|
+
end
|
282
|
+
merchant_xml.add_element dba_xml
|
283
|
+
end
|
284
|
+
|
285
|
+
if silo_config['merchant']['other_industries']
|
286
|
+
ois_xml = make_xml 'OtherIndustries', {}, '', false
|
287
|
+
silo_config['merchant']['other_industries'].each do |name|
|
288
|
+
ois_xml.add_element make_xml('Industry', {'name' => name}, '', false)
|
289
|
+
end
|
290
|
+
merchant_xml.add_element ois_xml
|
291
|
+
end
|
292
|
+
|
293
|
+
if silo_config['merchant']['qsa']
|
294
|
+
qsa_xml = make_xml 'QSA', {}, '', false
|
295
|
+
silo_config['merchant']['qsa'].keys.each do |key|
|
296
|
+
if not 'address'.eql? key
|
297
|
+
qsa_xml.attributes[key] = silo_config['merchant']['qsa'][key]
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
# Add the address for this QSA
|
302
|
+
address_xml = make_xml 'Address', silo_config['merchant']['qsa']['address'], '', false
|
303
|
+
|
304
|
+
qsa_xml.add_element address_xml
|
305
|
+
merchant_xml.add_element qsa_xml
|
306
|
+
end
|
307
|
+
silo_config_xml.add_element merchant_xml
|
308
|
+
end
|
309
|
+
|
310
|
+
xml.add_element silo_config_xml
|
311
|
+
r = execute xml, '1.2'
|
312
|
+
r.success
|
313
|
+
end
|
314
|
+
|
315
|
+
#-------------------------------------------------------------------------
|
316
|
+
# Lists all the silos and their attributes.
|
317
|
+
#-------------------------------------------------------------------------
|
318
|
+
def list_silos
|
319
|
+
xml = make_xml('SiloListingRequest')
|
320
|
+
r = execute xml, '1.2'
|
321
|
+
|
322
|
+
if r.success
|
323
|
+
res = []
|
324
|
+
r.res.elements.each("//SiloSummary") do |silo_profile|
|
325
|
+
res << {
|
326
|
+
:id => silo_profile.attributes['id'],
|
327
|
+
:name => silo_profile.attributes['name'],
|
328
|
+
:description => silo_profile.attributes['description']
|
329
|
+
}
|
330
|
+
end
|
331
|
+
res
|
332
|
+
else
|
333
|
+
false
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
#-------------------------------------------------------------------------
|
338
|
+
# Delete a silo
|
339
|
+
#-------------------------------------------------------------------------
|
340
|
+
def delete_silo name, id
|
341
|
+
using_name = (name and not name.empty?)
|
342
|
+
xml = make_xml('SiloDeleteRequest', (using_name ? {'silo-name' => name} : {'silo-id' => id}))
|
343
|
+
r = execute xml, '1.2'
|
344
|
+
r.success
|
345
|
+
end
|
346
|
+
end
|
347
|
+
end
|