nexpose_ticketing 0.8.1 → 0.8.2
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 +4 -4
- data/Gemfile.lock +1 -1
- data/lib/nexpose_ticketing/config/ticket_service.config +5 -2
- data/lib/nexpose_ticketing/helpers/jira_helper.rb +20 -20
- data/lib/nexpose_ticketing/helpers/remedy_helper.rb +34 -34
- data/lib/nexpose_ticketing/helpers/servicedesk_helper.rb +15 -15
- data/lib/nexpose_ticketing/helpers/servicenow_helper.rb +19 -19
- data/lib/nexpose_ticketing/queries.rb +40 -15
- data/lib/nexpose_ticketing/ticket_repository.rb +208 -141
- data/lib/nexpose_ticketing/ticket_service.rb +123 -56
- metadata +4 -3
@@ -107,15 +107,15 @@ class ServiceNowHelper
|
|
107
107
|
# * *Returns* :
|
108
108
|
# - List of JSON-formated tickets for creating within ServiceNow.
|
109
109
|
#
|
110
|
-
def prepare_create_tickets(vulnerability_list,
|
110
|
+
def prepare_create_tickets(vulnerability_list, nexpose_identifier_id)
|
111
111
|
@ticket = Hash.new(-1)
|
112
112
|
case @options[:ticket_mode]
|
113
113
|
# 'D' Default mode: IP *-* Vulnerability
|
114
114
|
when 'D'
|
115
|
-
prepare_create_tickets_default(vulnerability_list,
|
115
|
+
prepare_create_tickets_default(vulnerability_list, nexpose_identifier_id)
|
116
116
|
# 'I' IP address mode: IP address -* Vulnerability
|
117
117
|
when 'I'
|
118
|
-
prepare_create_tickets_by_ip(vulnerability_list,
|
118
|
+
prepare_create_tickets_by_ip(vulnerability_list, nexpose_identifier_id)
|
119
119
|
else
|
120
120
|
fail 'No ticketing mode selected.'
|
121
121
|
end
|
@@ -133,14 +133,14 @@ class ServiceNowHelper
|
|
133
133
|
# * *Returns* :
|
134
134
|
# - List of JSON-formated tickets for creating within ServiceNow.
|
135
135
|
#
|
136
|
-
def prepare_create_tickets_default(vulnerability_list,
|
136
|
+
def prepare_create_tickets_default(vulnerability_list, nexpose_identifier_id)
|
137
137
|
@log.log_message('Preparing tickets by default method.')
|
138
138
|
tickets = []
|
139
139
|
CSV.parse(vulnerability_list.chomp, headers: :first_row) do |row|
|
140
140
|
# ServiceNow doesn't allow new line characters in the incident short description.
|
141
141
|
summary = row['summary'].gsub(/\n/, ' ')
|
142
142
|
|
143
|
-
@log.log_message("Creating ticket with IP address: #{row['ip_address']},
|
143
|
+
@log.log_message("Creating ticket with IP address: #{row['ip_address']}, Nexpose identifier id: #{nexpose_identifier_id} and summary: #{summary}")
|
144
144
|
# NXID in the u_work_notes is a unique identifier used to query incidents to update/resolve
|
145
145
|
# incidents as they are resolved in Nexpose.
|
146
146
|
|
@@ -155,7 +155,7 @@ class ServiceNowHelper
|
|
155
155
|
Fix: #{row['fix']}
|
156
156
|
----------------------------------------------------------------------------
|
157
157
|
URL: #{row['url']}
|
158
|
-
NXID: #{
|
158
|
+
NXID: #{nexpose_identifier_id}#{row['asset_id']}#{row['vulnerability_id']}#{row['solution_id']}"
|
159
159
|
}.to_json
|
160
160
|
tickets.push(ticket)
|
161
161
|
end
|
@@ -173,14 +173,14 @@ class ServiceNowHelper
|
|
173
173
|
# * *Returns* :
|
174
174
|
# - List of JSON-formated tickets for creating within ServiceNow.
|
175
175
|
#
|
176
|
-
def prepare_create_tickets_by_ip(vulnerability_list,
|
176
|
+
def prepare_create_tickets_by_ip(vulnerability_list, nexpose_identifier_id)
|
177
177
|
@log.log_message('Preparing tickets by IP address.')
|
178
178
|
tickets = []
|
179
179
|
current_ip = -1
|
180
180
|
CSV.parse(vulnerability_list.chomp, headers: :first_row) do |row|
|
181
181
|
if current_ip == -1
|
182
182
|
current_ip = row['ip_address']
|
183
|
-
@log.log_message("Creating ticket with IP address: #{row['ip_address']} for
|
183
|
+
@log.log_message("Creating ticket with IP address: #{row['ip_address']} for Nexpose identifier with ID: #{nexpose_identifier_id}")
|
184
184
|
@ticket = {
|
185
185
|
'sysparm_action' => 'insert',
|
186
186
|
'u_caller_id' => "#{@servicenow_data[:username]}",
|
@@ -208,7 +208,7 @@ class ServiceNowHelper
|
|
208
208
|
unless current_ip == row['ip_address']
|
209
209
|
# NXID in the u_work_notes is the unique identifier used to query incidents to update them.
|
210
210
|
@log.log_message("Found new IP address. Finishing ticket with with IP address: #{current_ip} and moving onto IP #{row['ip_address']}")
|
211
|
-
@ticket['u_work_notes'] += "\nNXID: #{
|
211
|
+
@ticket['u_work_notes'] += "\nNXID: #{nexpose_identifier_id}#{current_ip}"
|
212
212
|
@ticket = @ticket.to_json
|
213
213
|
tickets.push(@ticket)
|
214
214
|
current_ip = -1
|
@@ -216,7 +216,7 @@ class ServiceNowHelper
|
|
216
216
|
end
|
217
217
|
end
|
218
218
|
# NXID in the u_work_notes is the unique identifier used to query incidents to update them.
|
219
|
-
@ticket['u_work_notes'] += "\nNXID: #{
|
219
|
+
@ticket['u_work_notes'] += "\nNXID: #{nexpose_identifier_id}#{current_ip}" unless (@ticket.size == 0)
|
220
220
|
tickets.push(@ticket.to_json) unless @ticket.nil?
|
221
221
|
tickets
|
222
222
|
end
|
@@ -231,7 +231,7 @@ class ServiceNowHelper
|
|
231
231
|
# * *Returns* :
|
232
232
|
# - List of JSON-formated tickets for updating within ServiceNow.
|
233
233
|
#
|
234
|
-
def prepare_update_tickets(vulnerability_list,
|
234
|
+
def prepare_update_tickets(vulnerability_list, nexpose_identifier_id)
|
235
235
|
fail 'Ticket updates are only supported in IP-address mode.' if @options[:ticket_mode] == 'D'
|
236
236
|
@ticket = Hash.new(-1)
|
237
237
|
|
@@ -243,7 +243,7 @@ class ServiceNowHelper
|
|
243
243
|
if current_ip == -1
|
244
244
|
current_ip = row['ip_address']
|
245
245
|
ticket_status = row['comparison']
|
246
|
-
@log.log_message("Creating ticket update with IP address: #{row['ip_address']} and
|
246
|
+
@log.log_message("Creating ticket update with IP address: #{row['ip_address']} and Nexpose identifier ID: #{nexpose_identifier_id}")
|
247
247
|
@log.log_message("Ticket status #{ticket_status}")
|
248
248
|
action = 'update'
|
249
249
|
if ticket_status == 'New'
|
@@ -251,7 +251,7 @@ class ServiceNowHelper
|
|
251
251
|
end
|
252
252
|
@ticket = {
|
253
253
|
'sysparm_action' => action,
|
254
|
-
'sysparm_query' => "u_work_notesCONTAINSNXID: #{
|
254
|
+
'sysparm_query' => "u_work_notesCONTAINSNXID: #{nexpose_identifier_id}#{row['ip_address']}",
|
255
255
|
'u_work_notes' =>
|
256
256
|
"\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
257
257
|
++ #{row['comparison']} Vulnerabilities +++++++++++++++++++++++++++++++++++++
|
@@ -282,7 +282,7 @@ class ServiceNowHelper
|
|
282
282
|
end
|
283
283
|
unless current_ip == row['ip_address']
|
284
284
|
# NXID in the u_work_notes is the unique identifier used to query incidents to update them.
|
285
|
-
@ticket['u_work_notes'] += "\nNXID: #{
|
285
|
+
@ticket['u_work_notes'] += "\nNXID: #{nexpose_identifier_id}#{current_ip}"
|
286
286
|
@ticket = @ticket.to_json
|
287
287
|
tickets.push(@ticket)
|
288
288
|
current_ip = -1
|
@@ -290,7 +290,7 @@ class ServiceNowHelper
|
|
290
290
|
end
|
291
291
|
end
|
292
292
|
# NXID in the u_work_notes is the unique identifier used to query incidents to update them.
|
293
|
-
@ticket['u_work_notes'] += "\nNXID: #{
|
293
|
+
@ticket['u_work_notes'] += "\nNXID: #{nexpose_identifier_id}#{current_ip}" unless (@ticket.size == 0)
|
294
294
|
tickets.push(@ticket.to_json) unless @ticket.nil?
|
295
295
|
tickets
|
296
296
|
end
|
@@ -305,7 +305,7 @@ class ServiceNowHelper
|
|
305
305
|
# * *Returns* :
|
306
306
|
# - List of JSON-formated tickets for closing within ServiceNow.
|
307
307
|
#
|
308
|
-
def prepare_close_tickets(vulnerability_list,
|
308
|
+
def prepare_close_tickets(vulnerability_list, nexpose_identifier_id)
|
309
309
|
@log.log_message("Preparing ticket closures for mode #{@options[:ticket_mode]}.")
|
310
310
|
tickets = []
|
311
311
|
@nxid = nil
|
@@ -313,13 +313,13 @@ class ServiceNowHelper
|
|
313
313
|
case @options[:ticket_mode]
|
314
314
|
# 'D' Default mode: IP *-* Vulnerability
|
315
315
|
when 'D'
|
316
|
-
@nxid = "#{
|
316
|
+
@nxid = "#{nexpose_identifier_id}#{row['asset_id']}#{row['vulnerability_id']}#{row['solution_id']}"
|
317
317
|
# 'I' IP address mode: IP address -* Vulnerability
|
318
318
|
when 'I'
|
319
|
-
@nxid = "#{
|
319
|
+
@nxid = "#{nexpose_identifier_id}#{row['ip_address']}"
|
320
320
|
# 'V' Vulnerability mode: Vulnerability -* IP address
|
321
321
|
## when 'V'
|
322
|
-
## @nxid = "#{
|
322
|
+
## @nxid = "#{nexpose_identifier_id}#{row['asset_id']}#{row['vulnerability_id']}"
|
323
323
|
else
|
324
324
|
fail 'Could not close tickets - do not understand the ticketing mode!'
|
325
325
|
end
|
@@ -22,8 +22,25 @@ module NexposeTicketing
|
|
22
22
|
return riskString
|
23
23
|
end
|
24
24
|
|
25
|
+
# Formats SQL query for filtering per asset based on user config options.
|
26
|
+
#
|
27
|
+
# * *Args* :
|
28
|
+
# - +options+ - User configured options for the ticketing service.
|
29
|
+
#
|
30
|
+
# * *Returns* :
|
31
|
+
# - Returns String - Formatted SQL string for inserting into queries.
|
32
|
+
#
|
25
33
|
|
26
|
-
|
34
|
+
def self.createAssetString(options)
|
35
|
+
if options[:tag_run] && options[:nexpose_item]
|
36
|
+
assetString = "WHERE asset_id = #{options[:nexpose_item]}"
|
37
|
+
else
|
38
|
+
assetString = ""
|
39
|
+
end
|
40
|
+
return assetString
|
41
|
+
end
|
42
|
+
|
43
|
+
# Gets all the latest scans for sites.
|
27
44
|
# Returns |site.id| |last_scan_id| |finished|
|
28
45
|
def self.last_scans
|
29
46
|
'SELECT ds.site_id, ds.last_scan_id, dsc.finished
|
@@ -31,6 +48,14 @@ module NexposeTicketing
|
|
31
48
|
JOIN dim_scan dsc ON ds.last_scan_id = dsc.scan_id'
|
32
49
|
end
|
33
50
|
|
51
|
+
# Gets all the latest scans for tags.
|
52
|
+
# Returns |tag.id| |asset.id| |last_scan_id| |finished|
|
53
|
+
def self.last_tag_scans
|
54
|
+
'select dta.tag_id, dta.asset_id, fa.last_scan_id, fa.scan_finished
|
55
|
+
from dim_tag_asset dta
|
56
|
+
join fact_asset fa using (asset_id)
|
57
|
+
order by dta.tag_id, dta.asset_id, fa.last_scan_id, fa.scan_finished'
|
58
|
+
end
|
34
59
|
|
35
60
|
# Gets all delta vulns for all sites sorted by IP.
|
36
61
|
#
|
@@ -47,7 +72,7 @@ module NexposeTicketing
|
|
47
72
|
JOIN
|
48
73
|
(
|
49
74
|
SELECT asset_id, previousScan(asset_id) AS baseline_scan, lastScan(asset_id) AS current_scan
|
50
|
-
FROM dim_asset) s
|
75
|
+
FROM dim_asset #{createAssetString(options)}) s
|
51
76
|
ON s.asset_id = fasv.asset_id AND (fasv.scan_id = s.baseline_scan OR fasv.scan_id = s.current_scan)
|
52
77
|
GROUP BY fasv.asset_id, fasv.vulnerability_id, s.current_scan, fasv.scan_id
|
53
78
|
HAVING NOT baselineComparison(fasv.scan_id, current_scan) = 'Old'
|
@@ -77,7 +102,7 @@ module NexposeTicketing
|
|
77
102
|
JOIN
|
78
103
|
(
|
79
104
|
SELECT asset_id, previousScan(asset_id) AS baseline_scan, lastScan(asset_id) AS current_scan
|
80
|
-
FROM dim_asset) s
|
105
|
+
FROM dim_asset #{createAssetString(options)}) s
|
81
106
|
ON s.asset_id = fasv.asset_id AND (fasv.scan_id = s.baseline_scan OR fasv.scan_id = s.current_scan)
|
82
107
|
GROUP BY fasv.asset_id, fasv.vulnerability_id, s.current_scan, fasv.scan_id
|
83
108
|
HAVING NOT baselineComparison(fasv.scan_id, current_scan) = 'Old'
|
@@ -87,7 +112,7 @@ module NexposeTicketing
|
|
87
112
|
JOIN dim_asset da ON subs.asset_id = da.asset_id
|
88
113
|
JOIN dim_vulnerability dv ON subs.vulnerability_id = dv.vulnerability_id
|
89
114
|
JOIN fact_asset fa ON fa.asset_id = da.asset_id
|
90
|
-
|
115
|
+
#{createRiskString(options[:riskScore])}
|
91
116
|
ORDER BY subs.vulnerability_id, subs.asset_id, davs.solution_id"
|
92
117
|
end
|
93
118
|
|
@@ -108,7 +133,7 @@ module NexposeTicketing
|
|
108
133
|
JOIN
|
109
134
|
(
|
110
135
|
SELECT asset_id, previousScan(asset_id) AS baseline_scan, lastScan(asset_id) AS current_scan
|
111
|
-
FROM dim_asset) s
|
136
|
+
FROM dim_asset #{createAssetString(options)}) s
|
112
137
|
ON s.asset_id = fasv.asset_id AND (fasv.scan_id >= #{options[:scan_id]} OR fasv.scan_id = s.current_scan)
|
113
138
|
GROUP BY fasv.asset_id, fasv.vulnerability_id, s.current_scan
|
114
139
|
HAVING baselineComparison(fasv.scan_id, current_scan) = 'New'
|
@@ -140,7 +165,7 @@ module NexposeTicketing
|
|
140
165
|
JOIN
|
141
166
|
(
|
142
167
|
SELECT asset_id, previousScan(asset_id) AS baseline_scan, lastScan(asset_id) AS current_scan
|
143
|
-
FROM dim_asset) s
|
168
|
+
FROM dim_asset #{createAssetString(options)}) s
|
144
169
|
ON s.asset_id = fasv.asset_id AND (fasv.scan_id >= #{options[:scan_id]} OR fasv.scan_id = s.current_scan)
|
145
170
|
GROUP BY fasv.asset_id, fasv.vulnerability_id, s.current_scan
|
146
171
|
HAVING baselineComparison(fasv.scan_id, current_scan) = 'New'
|
@@ -172,7 +197,7 @@ module NexposeTicketing
|
|
172
197
|
FROM fact_asset_scan_vulnerability_finding fasv
|
173
198
|
JOIN (
|
174
199
|
SELECT asset_id, previousScan(asset_id) AS baseline_scan, lastScan(asset_id) AS current_scan
|
175
|
-
FROM dim_asset
|
200
|
+
FROM dim_asset #{createAssetString(options)}
|
176
201
|
) s ON s.asset_id = fasv.asset_id AND (fasv.scan_id >= #{options[:scan_id]} OR fasv.scan_id = s.current_scan)
|
177
202
|
GROUP BY fasv.asset_id, fasv.vulnerability_id, s.current_scan
|
178
203
|
HAVING baselineComparison(fasv.scan_id, current_scan) = 'Old'
|
@@ -205,7 +230,7 @@ module NexposeTicketing
|
|
205
230
|
FROM fact_asset_scan_vulnerability_finding fasv
|
206
231
|
JOIN (
|
207
232
|
SELECT asset_id, previousScan(asset_id) AS baseline_scan, lastScan(asset_id) AS current_scan
|
208
|
-
FROM dim_asset
|
233
|
+
FROM dim_asset #{createAssetString(options)}
|
209
234
|
) s ON s.asset_id = fasv.asset_id AND (fasv.scan_id >= #{options[:scan_id]} OR fasv.scan_id = s.current_scan)
|
210
235
|
GROUP BY fasv.asset_id, fasv.vulnerability_id, s.current_scan
|
211
236
|
HAVING baselineComparison(fasv.scan_id, current_scan) = 'Old'
|
@@ -228,7 +253,7 @@ module NexposeTicketing
|
|
228
253
|
JOIN
|
229
254
|
(
|
230
255
|
SELECT asset_id,lastScan(asset_id) AS current_scan
|
231
|
-
FROM dim_asset
|
256
|
+
FROM dim_asset #{createAssetString(options)}
|
232
257
|
) s ON s.asset_id = fasv.asset_id AND (fasv.scan_id >= #{options[:scan_id]} OR fasv.scan_id = s.current_scan)
|
233
258
|
GROUP BY fasv.asset_id, fasv.vulnerability_id, s.current_scan
|
234
259
|
HAVING baselineComparison(fasv.scan_id, current_scan) IN ('Same','New')
|
@@ -261,7 +286,7 @@ module NexposeTicketing
|
|
261
286
|
FROM fact_asset_scan_vulnerability_finding fasv
|
262
287
|
JOIN (
|
263
288
|
SELECT asset_id, previousScan(asset_id) AS baseline_scan, lastScan(asset_id) AS current_scan
|
264
|
-
FROM dim_asset
|
289
|
+
FROM dim_asset #{createAssetString(options)}
|
265
290
|
) s ON s.asset_id = fasv.asset_id AND (fasv.scan_id >= #{options[:scan_id]} OR fasv.scan_id = s.current_scan)
|
266
291
|
GROUP BY fasv.asset_id, fasv.vulnerability_id, s.current_scan
|
267
292
|
HAVING baselineComparison(fasv.scan_id, current_scan) = 'Old'
|
@@ -285,7 +310,7 @@ module NexposeTicketing
|
|
285
310
|
JOIN
|
286
311
|
(
|
287
312
|
SELECT asset_id,lastScan(asset_id) AS current_scan
|
288
|
-
FROM dim_asset
|
313
|
+
FROM dim_asset #{createAssetString(options)}
|
289
314
|
) s ON s.asset_id = fasv.asset_id AND (fasv.scan_id >= #{options[:scan_id]} OR fasv.scan_id = s.current_scan)
|
290
315
|
GROUP BY fasv.asset_id, fasv.vulnerability_id, s.current_scan
|
291
316
|
HAVING baselineComparison(fasv.scan_id, current_scan) IN ('Same','New')
|
@@ -317,7 +342,7 @@ module NexposeTicketing
|
|
317
342
|
FROM fact_asset_scan_vulnerability_finding fasv
|
318
343
|
JOIN (
|
319
344
|
SELECT asset_id, ip_address, previousScan(asset_id) AS baseline_scan, lastScan(asset_id) AS current_scan
|
320
|
-
FROM dim_asset
|
345
|
+
FROM dim_asset #{createAssetString(options)}
|
321
346
|
) s ON s.asset_id = fasv.asset_id AND (fasv.scan_id >= #{options[:scan_id]} OR fasv.scan_id = s.current_scan)
|
322
347
|
GROUP BY fasv.asset_id, fasv.vulnerability_id, s.ip_address, s.current_scan
|
323
348
|
HAVING baselineComparison(fasv.scan_id, current_scan) = 'Old'
|
@@ -329,7 +354,7 @@ module NexposeTicketing
|
|
329
354
|
JOIN
|
330
355
|
(
|
331
356
|
SELECT asset_id, ip_address, lastScan(asset_id) AS current_scan
|
332
|
-
FROM dim_asset
|
357
|
+
FROM dim_asset #{createAssetString(options)}
|
333
358
|
) s ON s.asset_id = fasv.asset_id AND (fasv.scan_id >= #{options[:scan_id]} OR fasv.scan_id = s.current_scan)
|
334
359
|
GROUP BY s.ip_address, s.current_scan
|
335
360
|
HAVING baselineComparison(fasv.scan_id, current_scan) IN ('Same','New')
|
@@ -354,7 +379,7 @@ module NexposeTicketing
|
|
354
379
|
FROM fact_asset_scan_vulnerability_finding fasv
|
355
380
|
JOIN (
|
356
381
|
SELECT asset_id, ip_address, previousScan(asset_id) AS baseline_scan, lastScan(asset_id) AS current_scan
|
357
|
-
FROM dim_asset
|
382
|
+
FROM dim_asset #{createAssetString(options)}
|
358
383
|
) s ON s.asset_id = fasv.asset_id AND (fasv.scan_id >= #{options[:scan_id]} OR fasv.scan_id = s.current_scan)
|
359
384
|
JOIN fact_asset fa ON fa.asset_id = fasv.asset_id
|
360
385
|
#{createRiskString(options[:riskScore])}
|
@@ -368,7 +393,7 @@ module NexposeTicketing
|
|
368
393
|
JOIN
|
369
394
|
(
|
370
395
|
SELECT da.asset_id, da.ip_address, lastScan(da.asset_id) AS current_scan, fa.riskscore
|
371
|
-
FROM dim_asset da
|
396
|
+
FROM dim_asset da #{createAssetString(options)}
|
372
397
|
JOIN fact_asset fa ON fa.asset_id = da.asset_id
|
373
398
|
#{createRiskString(options[:riskScore])}
|
374
399
|
) s ON s.asset_id = fasv.asset_id AND (fasv.scan_id >= #{options[:scan_id]} OR fasv.scan_id = s.current_scan)
|
@@ -28,7 +28,7 @@ module NexposeTicketing
|
|
28
28
|
@nsc.sites
|
29
29
|
end
|
30
30
|
|
31
|
-
# Reads
|
31
|
+
# Reads a nexpose identifier (tag ID, site ID etc) scan history from disk.
|
32
32
|
#
|
33
33
|
# * *Args* :
|
34
34
|
# - +csv_file_name+ - CSV File name.
|
@@ -37,11 +37,11 @@ module NexposeTicketing
|
|
37
37
|
# - A hash with site_ids => last_scan_id
|
38
38
|
#
|
39
39
|
def read_last_scans(csv_file_name)
|
40
|
-
|
40
|
+
file_identifier_histories = Hash.new(-1)
|
41
41
|
CSV.foreach(csv_file_name, headers: true) do |row|
|
42
|
-
|
42
|
+
file_identifier_histories[row[0]] = row[1]
|
43
43
|
end
|
44
|
-
|
44
|
+
file_identifier_histories
|
45
45
|
end
|
46
46
|
|
47
47
|
# Saves the last scan info to disk.
|
@@ -51,7 +51,7 @@ module NexposeTicketing
|
|
51
51
|
#
|
52
52
|
def save_last_scans(csv_file_name, options = {}, saved_file = nil)
|
53
53
|
current_scan_state = load_last_scans(options)
|
54
|
-
|
54
|
+
save_to_file(csv_file_name, current_scan_state, saved_file)
|
55
55
|
end
|
56
56
|
|
57
57
|
# Loads the last scan info to memory.
|
@@ -60,32 +60,132 @@ module NexposeTicketing
|
|
60
60
|
# - +csv_file_name+ - CSV File name.
|
61
61
|
#
|
62
62
|
def load_last_scans(options = {}, report_config = Nexpose::AdhocReportConfig.new(nil, 'sql'))
|
63
|
-
sites = Array(options[:sites])
|
64
63
|
report_config.add_filter('version', '1.2.0')
|
65
|
-
|
64
|
+
sites = Array(options[:sites])
|
65
|
+
tags = Array(options[:tags])
|
66
|
+
if(options[:tag_run])
|
67
|
+
report_config.add_filter('query', Queries.last_tag_scans)
|
68
|
+
tags.each do |tag|
|
69
|
+
report_config.add_filter('tag', tag)
|
70
|
+
end
|
71
|
+
else
|
72
|
+
report_config.add_filter('query', Queries.last_scans)
|
73
|
+
end
|
66
74
|
|
67
75
|
report_output = report_config.generate(@nsc, @timeout)
|
68
76
|
csv_output = CSV.parse(report_output.chomp, headers: :first_row)
|
69
77
|
|
70
78
|
#We only care about sites we are monitoring.
|
71
79
|
trimmed_csv = []
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
80
|
+
if(options[:tag_run])
|
81
|
+
trimmed_csv << 'tag_id, last_scan_fingerprint'
|
82
|
+
current_tag_id = nil
|
83
|
+
tag_finger_print = ''
|
84
|
+
csv_output.each do |row|
|
85
|
+
if (tags.include? row[0].to_s) && (row[0].to_i != current_tag_id)
|
86
|
+
if(current_tag_id.nil?)
|
87
|
+
#Initial run
|
88
|
+
current_tag_id = row[0].to_i
|
89
|
+
else
|
90
|
+
#New tag ID, finish off the old fingerprint and start on the new one
|
91
|
+
trimmed_csv << CSV::Row.new('tag_id, last_scan_fingerprint'.split(','), "#{current_tag_id},#{Digest::MD5::hexdigest(tag_finger_print)}".split(','))
|
92
|
+
tag_finger_print.clear
|
93
|
+
current_tag_id = row[0].to_i
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
if(current_tag_id == row[0].to_i)
|
98
|
+
#yield current_tag_id, row[1].to_s, row[2].to_s if block_given?
|
99
|
+
tag_finger_print << row[1].to_s
|
100
|
+
tag_finger_print << row[2].to_s
|
101
|
+
end
|
102
|
+
end
|
103
|
+
unless tag_finger_print.empty?
|
104
|
+
trimmed_csv << CSV::Row.new('tag_id, last_scan_fingerprint'.split(','), "#{current_tag_id},#{Digest::MD5::hexdigest(tag_finger_print)}".split(','))
|
105
|
+
end
|
106
|
+
else
|
107
|
+
trimmed_csv << report_output.lines.first
|
108
|
+
csv_output.each do |row|
|
109
|
+
if sites.include? row[0].to_s
|
110
|
+
trimmed_csv << row
|
111
|
+
end
|
76
112
|
end
|
77
113
|
end
|
78
114
|
trimmed_csv
|
79
115
|
end
|
80
116
|
|
117
|
+
# Parses user-configured vulnerability filter categories and returns aforementioned categories in a
|
118
|
+
# format used by the Nexpose::AdhocReportConfig class.
|
119
|
+
#
|
120
|
+
# * *Args* :
|
121
|
+
# - +options+ - A Hash with site(s), reported_scan_id and severity level.
|
122
|
+
#
|
123
|
+
# * *Returns* :
|
124
|
+
# - Returns String @vulnerability_categories
|
125
|
+
#
|
126
|
+
def createVulnerabilityFilter(options = {})
|
127
|
+
@vulnerability_categories = nil
|
128
|
+
if options.has_key?(:vulnerabilityCategories)
|
129
|
+
if not options[:vulnerabilityCategories].nil? and not options[:vulnerabilityCategories].empty?
|
130
|
+
@vulnerability_categories = options[:vulnerabilityCategories].strip.split(',').map {|category| "include:#{category}"}.join(',')
|
131
|
+
end
|
132
|
+
end
|
133
|
+
@vulnerability_categories
|
134
|
+
end
|
135
|
+
|
136
|
+
def read_tag_asset_list(cvs_file_name)
|
137
|
+
file_identifier_histories = Hash.new(-1)
|
138
|
+
CSV.foreach(cvs_file_name, headers: true) do |row|
|
139
|
+
file_identifier_histories[row[0]] = row[1]
|
140
|
+
end
|
141
|
+
file_identifier_histories
|
142
|
+
end
|
143
|
+
|
144
|
+
def generate_tag_asset_list(options = {}, report_config = Nexpose::AdhocReportConfig.new(nil, 'sql'))
|
145
|
+
report_config.add_filter('version', '1.2.0')
|
146
|
+
tags = Array(options[:tags])
|
147
|
+
report_config.add_filter('query', Queries.last_tag_scans)
|
148
|
+
tags.each do |tag|
|
149
|
+
report_config.add_filter('tag', tag)
|
150
|
+
end
|
151
|
+
|
152
|
+
report_output = report_config.generate(@nsc, @timeout)
|
153
|
+
csv_output = CSV.parse(report_output.chomp, headers: :first_row)
|
154
|
+
trimmed_csv = []
|
155
|
+
trimmed_csv << 'asset_id, last_scan_id'
|
156
|
+
current_tag_id = nil
|
157
|
+
csv_output.each do |row|
|
158
|
+
if (tags.include? row[0].to_s) && (row[0].to_i != current_tag_id)
|
159
|
+
if(current_tag_id.nil?)
|
160
|
+
#Initial run
|
161
|
+
current_tag_id = row[0].to_i
|
162
|
+
else
|
163
|
+
#New tag ID, finish off the previous tag asset list and start on the new one
|
164
|
+
save_to_file(options[:csv_file], trimmed_csv)
|
165
|
+
current_tag_id = row[0].to_i
|
166
|
+
trimmed_csv = []
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
if(current_tag_id == row[0].to_i)
|
171
|
+
trimmed_csv << "#{row[1].to_s},#{row[2].to_s}"
|
172
|
+
end
|
173
|
+
end
|
174
|
+
save_to_file(options[:csv_file], trimmed_csv) if trimmed_csv.any?
|
175
|
+
end
|
176
|
+
|
81
177
|
# Saves CSV scan information to disk
|
82
178
|
#
|
83
179
|
# * *Args* :
|
84
180
|
# - +csv_file_name+ - CSV File name.
|
85
181
|
#
|
86
|
-
def
|
182
|
+
def save_to_file(csv_file_name, trimmed_csv, saved_file = nil)
|
87
183
|
saved_file.open(csv_file_name, 'w') { |file| file.puts(trimmed_csv) } unless saved_file.nil?
|
88
184
|
if saved_file.nil?
|
185
|
+
dir = File.dirname(csv_file_name)
|
186
|
+
unless File.directory?(dir)
|
187
|
+
FileUtils.mkdir_p(dir)
|
188
|
+
end
|
89
189
|
File.open(csv_file_name, 'w') { |file| file.puts(trimmed_csv) }
|
90
190
|
end
|
91
191
|
end
|
@@ -93,131 +193,143 @@ module NexposeTicketing
|
|
93
193
|
# Gets the last scan information from nexpose sans the CSV headers.
|
94
194
|
#
|
95
195
|
# * *Returns* :
|
96
|
-
# - A hash with
|
196
|
+
# - A hash with nexpose_ids (site ID or tag ID) => last_scan_id
|
97
197
|
#
|
98
198
|
def last_scans(options = {})
|
99
|
-
|
199
|
+
nexpose_ids= Hash.new(-1)
|
100
200
|
trimmed_csv = load_last_scans(options)
|
101
201
|
trimmed_csv.drop(1).each do |row|
|
102
|
-
|
202
|
+
nexpose_ids[row[0]] = row[1]
|
103
203
|
end
|
104
|
-
|
204
|
+
nexpose_ids
|
105
205
|
end
|
106
206
|
|
107
207
|
# Gets all the vulnerabilities for a new site or fresh install.
|
108
208
|
#
|
109
209
|
# * *Args* :
|
110
|
-
# - +
|
111
|
-
# - +
|
210
|
+
# - +options+ - A Hash with user configuration information.
|
211
|
+
# - +nexpose_item_override+ - Override for user-configured tag/site options
|
112
212
|
#
|
113
213
|
# * *Returns* :
|
114
214
|
# - Returns CSV |asset_id| |ip_address| |current_scan| |vulnerability_id| |solution_id| |nexpose_id|
|
115
215
|
# |url| |summary| |fix|
|
116
216
|
#
|
117
|
-
def all_vulns(options = {},
|
118
|
-
if site_override.nil?
|
119
|
-
sites = Array(options[:sites])
|
120
|
-
else
|
121
|
-
sites = Array(site_override)
|
122
|
-
end
|
217
|
+
def all_vulns(options = {}, nexpose_item_override = nil)
|
123
218
|
report_config = @report_helper.generate_sql_report_config()
|
124
219
|
severity = options[:severity].nil? ? 0 : options[:severity]
|
125
220
|
report_config.add_filter('version', '1.2.0')
|
126
221
|
if options[:ticket_mode] == 'V'
|
127
222
|
report_config.add_filter('query', Queries.all_new_vulns_by_vuln_id(options))
|
128
223
|
else
|
129
|
-
|
224
|
+
report_config.add_filter('query', Queries.all_new_vulns(options))
|
130
225
|
end
|
131
|
-
|
132
|
-
|
133
|
-
|
226
|
+
|
227
|
+
if nexpose_item_override.nil?
|
228
|
+
if(options[:tag_run])
|
229
|
+
nexpose_items = Array(options[:tags])
|
230
|
+
else
|
231
|
+
nexpose_items = Array(options[:sites])
|
134
232
|
end
|
233
|
+
else
|
234
|
+
nexpose_items = Array(nexpose_item_override)
|
135
235
|
end
|
236
|
+
|
237
|
+
if options[:tag_run]
|
238
|
+
unless nexpose_items.nil? || nexpose_items.empty?
|
239
|
+
nexpose_items.each do |tag_id|
|
240
|
+
report_config.add_filter('tag', tag_id)
|
241
|
+
end
|
242
|
+
end
|
243
|
+
else
|
244
|
+
unless nexpose_items.nil? || nexpose_items.empty?
|
245
|
+
nexpose_items.each do |site_id|
|
246
|
+
report_config.add_filter('site', site_id)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
136
251
|
report_config.add_filter('vuln-severity', severity)
|
137
252
|
|
138
253
|
vuln_filter_cats = createVulnerabilityFilter(options)
|
139
|
-
vuln_filer_tags = createTagFilters(options)
|
140
254
|
|
141
255
|
if not vuln_filter_cats.nil? and not vuln_filter_cats.empty?
|
142
256
|
report_config.add_filter('vuln-categories', vuln_filter_cats)
|
143
257
|
end
|
144
258
|
|
145
|
-
if not vuln_filer_tags.nil? and not vuln_filer_tags.empty?
|
146
|
-
vuln_filer_tags.map {|tag| report_config.add_filter('tag', tag.id) }
|
147
|
-
end
|
148
|
-
|
149
259
|
@report_helper.save_generate_cleanup_report_config(report_config)
|
150
260
|
end
|
151
261
|
|
152
262
|
# Gets the new vulns from base scan reported_scan_id and the newest / latest scan from a site.
|
153
263
|
#
|
154
264
|
# * *Args* :
|
155
|
-
# - +
|
265
|
+
# - +options+ - A Hash with user configuration information.
|
156
266
|
#
|
157
267
|
# * *Returns* :
|
158
268
|
# - Returns CSV |asset_id| |ip_address| |current_scan| |vulnerability_id| |solution_id| |nexpose_id|
|
159
269
|
# |url| |summary| |fix|
|
160
270
|
#
|
161
|
-
def
|
271
|
+
def new_vulns(options = {})
|
162
272
|
report_config = @report_helper.generate_sql_report_config()
|
163
|
-
|
164
|
-
reported_scan_id =
|
165
|
-
fail '
|
166
|
-
severity =
|
273
|
+
nexpose_item = options[:nexpose_item]
|
274
|
+
reported_scan_id = options[:scan_id]
|
275
|
+
fail 'Nexpose item cannot be null or empty' if nexpose_item.nil? || reported_scan_id.nil?
|
276
|
+
severity = options[:severity].nil? ? 0 : options[:severity]
|
167
277
|
report_config.add_filter('version', '1.2.0')
|
168
|
-
if
|
169
|
-
report_config.add_filter('query', Queries.new_vulns_by_vuln_id_since_scan(
|
278
|
+
if options[:ticket_mode] == 'V'
|
279
|
+
report_config.add_filter('query', Queries.new_vulns_by_vuln_id_since_scan(options))
|
170
280
|
else
|
171
|
-
report_config.add_filter('query', Queries.new_vulns_since_scan(
|
281
|
+
report_config.add_filter('query', Queries.new_vulns_since_scan(options))
|
172
282
|
end
|
173
|
-
|
283
|
+
|
284
|
+
if(options[:tag_run])
|
285
|
+
report_config.add_filter('tag', options[:tag])
|
286
|
+
else
|
287
|
+
report_config.add_filter('site', nexpose_item)
|
288
|
+
end
|
289
|
+
|
174
290
|
report_config.add_filter('vuln-severity', severity)
|
175
291
|
|
176
|
-
vuln_filter_cats = createVulnerabilityFilter(
|
177
|
-
vuln_filer_tags = createTagFilters(site_options)
|
292
|
+
vuln_filter_cats = createVulnerabilityFilter(options)
|
178
293
|
|
179
294
|
if not vuln_filter_cats.nil? and not vuln_filter_cats.empty?
|
180
295
|
report_config.add_filter('vuln-categories', vuln_filter_cats)
|
181
296
|
end
|
182
297
|
|
183
|
-
if not vuln_filer_tags.nil? and not vuln_filer_tags.empty?
|
184
|
-
vuln_filer_tags.map {|tag| report_config.add_filter('tag', tag.id) }
|
185
|
-
end
|
186
|
-
|
187
298
|
@report_helper.save_generate_cleanup_report_config(report_config)
|
188
299
|
end
|
189
300
|
|
190
301
|
# Gets the old vulns from base scan reported_scan_id and the newest / latest scan from a site.
|
191
302
|
#
|
192
303
|
# * *Args* :
|
193
|
-
# - +
|
304
|
+
# - +options+ - A Hash with user configuration information.
|
194
305
|
#
|
195
306
|
# * *Returns* :
|
196
307
|
# - Returns CSV |asset_id| |ip_address| |current_scan| |vulnerability_id| |solution_id| |nexpose_id|
|
197
308
|
# |url| |summary| |fix|
|
198
309
|
#
|
199
|
-
def
|
310
|
+
def old_vulns(options = {})
|
200
311
|
report_config = @report_helper.generate_sql_report_config()
|
201
|
-
|
202
|
-
reported_scan_id =
|
203
|
-
fail '
|
204
|
-
severity =
|
312
|
+
nexpose_item = options[:nexpose_item]
|
313
|
+
reported_scan_id = options[:scan_id]
|
314
|
+
fail 'Nexpose item cannot be null or empty' if nexpose_item.nil? || reported_scan_id.nil?
|
315
|
+
severity = options[:severity].nil? ? 0 : options[:severity]
|
205
316
|
report_config.add_filter('version', '1.2.0')
|
206
|
-
report_config.add_filter('query', Queries.old_vulns_since_scan(
|
207
|
-
|
317
|
+
report_config.add_filter('query', Queries.old_vulns_since_scan(options))
|
318
|
+
|
319
|
+
if(options[:tag_run])
|
320
|
+
report_config.add_filter('tag', options[:tag])
|
321
|
+
else
|
322
|
+
report_config.add_filter('site', nexpose_item)
|
323
|
+
end
|
324
|
+
|
208
325
|
report_config.add_filter('vuln-severity', severity)
|
209
326
|
|
210
|
-
vuln_filter_cats = createVulnerabilityFilter(
|
211
|
-
vuln_filer_tags = createTagFilters(site_options)
|
327
|
+
vuln_filter_cats = createVulnerabilityFilter(options)
|
212
328
|
|
213
329
|
if not vuln_filter_cats.nil? and not vuln_filter_cats.empty?
|
214
330
|
report_config.add_filter('vuln-categories', vuln_filter_cats)
|
215
331
|
end
|
216
332
|
|
217
|
-
if not vuln_filer_tags.nil? and not vuln_filer_tags.empty?
|
218
|
-
vuln_filer_tags.map {|tag| report_config.add_filter('tag', tag.id) }
|
219
|
-
end
|
220
|
-
|
221
333
|
@report_helper.save_generate_cleanup_report_config(report_config)
|
222
334
|
end
|
223
335
|
|
@@ -225,37 +337,38 @@ module NexposeTicketing
|
|
225
337
|
# Based on IP address (for 'I' mode) or vuln ID ('V' mode).
|
226
338
|
#
|
227
339
|
# * *Args* :
|
228
|
-
# - +
|
340
|
+
# - +options+ - A Hash with user configuration information.
|
229
341
|
#
|
230
342
|
# * *Returns* :
|
231
343
|
# - Returns CSV |asset_id| |ip_address| |current_scan| |vulnerability_id| |comparison|
|
232
344
|
#
|
233
|
-
def tickets_to_close(
|
345
|
+
def tickets_to_close(options = {})
|
234
346
|
report_config = @report_helper.generate_sql_report_config()
|
235
|
-
|
236
|
-
reported_scan_id =
|
237
|
-
fail '
|
238
|
-
severity =
|
347
|
+
nexpose_item = options[:nexpose_item]
|
348
|
+
reported_scan_id = options[:scan_id]
|
349
|
+
fail 'Nexpose item cannot be null or empty' if nexpose_item.nil? || reported_scan_id.nil?
|
350
|
+
severity = options[:severity].nil? ? 0 : options[:severity]
|
239
351
|
report_config.add_filter('version', '1.2.0')
|
240
|
-
if
|
241
|
-
report_config.add_filter('query', Queries.old_tickets_by_vuln_id(
|
352
|
+
if options[:ticket_mode] == 'V'
|
353
|
+
report_config.add_filter('query', Queries.old_tickets_by_vuln_id(options))
|
242
354
|
else
|
243
|
-
report_config.add_filter('query', Queries.old_tickets_by_ip(
|
355
|
+
report_config.add_filter('query', Queries.old_tickets_by_ip(options))
|
244
356
|
end
|
245
|
-
|
357
|
+
|
358
|
+
if(options[:tag_run])
|
359
|
+
report_config.add_filter('tag', options[:tag])
|
360
|
+
else
|
361
|
+
report_config.add_filter('site', nexpose_item)
|
362
|
+
end
|
363
|
+
|
246
364
|
report_config.add_filter('vuln-severity', severity)
|
247
365
|
|
248
|
-
vuln_filter_cats = createVulnerabilityFilter(
|
249
|
-
vuln_filer_tags = createTagFilters(site_options)
|
366
|
+
vuln_filter_cats = createVulnerabilityFilter(options)
|
250
367
|
|
251
368
|
if not vuln_filter_cats.nil? and not vuln_filter_cats.empty?
|
252
369
|
report_config.add_filter('vuln-categories', vuln_filter_cats)
|
253
370
|
end
|
254
371
|
|
255
|
-
if not vuln_filer_tags.nil? and not vuln_filer_tags.empty?
|
256
|
-
vuln_filer_tags.map {|tag| report_config.add_filter('tag', tag.id) }
|
257
|
-
end
|
258
|
-
|
259
372
|
@report_helper.save_generate_cleanup_report_config(report_config)
|
260
373
|
end
|
261
374
|
|
@@ -264,85 +377,39 @@ module NexposeTicketing
|
|
264
377
|
# used for IP-based issue updating. Includes the baseline comparision value ('Old','New', or 'Same').
|
265
378
|
#
|
266
379
|
# * *Args* :
|
267
|
-
# - +
|
380
|
+
# - +options+ - A Hash with user configuration information.
|
268
381
|
#
|
269
382
|
# * *Returns* :
|
270
383
|
# - Returns CSV |asset_id| |ip_address| |current_scan| |vulnerability_id| |solution_id| |nexpose_id|
|
271
384
|
# |url| |summary| |fix| |comparison|
|
272
385
|
#
|
273
|
-
def
|
386
|
+
def all_vulns_since(options = {})
|
274
387
|
report_config = @report_helper.generate_sql_report_config()
|
275
|
-
|
276
|
-
reported_scan_id =
|
277
|
-
fail '
|
278
|
-
severity =
|
388
|
+
nexpose_item = options[:nexpose_item]
|
389
|
+
reported_scan_id = options[:scan_id]
|
390
|
+
fail 'Nexpose item cannot be null or empty' if nexpose_item.nil? || reported_scan_id.nil?
|
391
|
+
severity = options[:severity].nil? ? 0 : options[:severity]
|
279
392
|
report_config.add_filter('version', '1.2.0')
|
280
|
-
if
|
281
|
-
report_config.add_filter('query', Queries.all_vulns_by_vuln_id_since_scan(
|
393
|
+
if options[:ticket_mode] == 'V'
|
394
|
+
report_config.add_filter('query', Queries.all_vulns_by_vuln_id_since_scan(options))
|
395
|
+
else
|
396
|
+
report_config.add_filter('query', Queries.all_vulns_since_scan(options))
|
397
|
+
end
|
398
|
+
|
399
|
+
if(options[:tag_run])
|
400
|
+
report_config.add_filter('tag', options[:tag])
|
282
401
|
else
|
283
|
-
report_config.add_filter('
|
402
|
+
report_config.add_filter('site', nexpose_item)
|
284
403
|
end
|
285
|
-
report_config.add_filter('site', site)
|
286
404
|
report_config.add_filter('vuln-severity', severity)
|
287
405
|
|
288
|
-
vuln_filter_cats = createVulnerabilityFilter(
|
289
|
-
vuln_filer_tags = createTagFilters(site_options)
|
406
|
+
vuln_filter_cats = createVulnerabilityFilter(options)
|
290
407
|
|
291
408
|
if not vuln_filter_cats.nil? and not vuln_filter_cats.empty?
|
292
409
|
report_config.add_filter('vuln-categories', vuln_filter_cats)
|
293
410
|
end
|
294
411
|
|
295
|
-
if not vuln_filer_tags.nil? and not vuln_filer_tags.empty?
|
296
|
-
vuln_filer_tags.map {|tag| report_config.add_filter('tag', tag.id) }
|
297
|
-
end
|
298
|
-
|
299
412
|
@report_helper.save_generate_cleanup_report_config(report_config)
|
300
413
|
end
|
301
|
-
|
302
|
-
|
303
|
-
# Parses user-configured vulnerability filter categories and returns aforementioned categories in a
|
304
|
-
# format used by the Nexpose::AdhocReportConfig class.
|
305
|
-
#
|
306
|
-
# * *Args* :
|
307
|
-
# - +site_options+ - A Hash with site(s), reported_scan_id and severity level.
|
308
|
-
#
|
309
|
-
# * *Returns* :
|
310
|
-
# - Returns String @vulnerability_categories
|
311
|
-
#
|
312
|
-
def createVulnerabilityFilter(options = {})
|
313
|
-
@vulnerability_categories = nil
|
314
|
-
if options.has_key?(:vulnerabilityCategories)
|
315
|
-
if not options[:vulnerabilityCategories].nil? and not options[:vulnerabilityCategories].empty?
|
316
|
-
@vulnerability_categories = options[:vulnerabilityCategories].strip.split(',').map {|category| "include:#{category}"}.join(',')
|
317
|
-
end
|
318
|
-
end
|
319
|
-
@vulnerability_categories
|
320
|
-
end
|
321
|
-
|
322
|
-
# Parses user-configured tags and returns aforementioned tags in an array containing
|
323
|
-
# strings in the format used by the Nexpose::AdhocReportConfig class.
|
324
|
-
#
|
325
|
-
# * *Args* :
|
326
|
-
# - +site_options+ - A Hash with site(s), reported_scan_id and severity level.
|
327
|
-
#
|
328
|
-
# * *Returns* :
|
329
|
-
# - Returns Array @definedTags
|
330
|
-
#
|
331
|
-
def createTagFilters(options = {})
|
332
|
-
@defined_tags = nil
|
333
|
-
if options.has_key?(:tags)
|
334
|
-
return if options[:tags].nil?
|
335
|
-
if options[:tags].is_a?(Fixnum)
|
336
|
-
@defined_tags = @nsc.list_tags.select{ |nexposeTag| nexposeTag.id == options[:tags] }
|
337
|
-
else
|
338
|
-
## Split the tags into an array
|
339
|
-
tag_strings = options[:tags].strip.split(',')
|
340
|
-
## Grab the tag info for the ones we are looking for (if the exist in Nexpose).
|
341
|
-
@defined_tags = @nsc.list_tags.select {|nexposeTag| tag_strings.include?(nexposeTag.name)}
|
342
|
-
end
|
343
|
-
end
|
344
|
-
@defined_tags
|
345
|
-
end
|
346
|
-
|
347
414
|
end
|
348
415
|
end
|