nexpose_ticketing 1.0.1 → 1.0.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 +5 -13
- data/README.md +14 -1
- data/bin/nexpose_jira +4 -0
- data/bin/nexpose_remedy +4 -0
- data/bin/nexpose_servicedesk +4 -0
- data/bin/nexpose_servicenow +4 -0
- data/lib/nexpose_ticketing/helpers/jira_helper.rb +63 -49
- data/lib/nexpose_ticketing/helpers/servicenow_helper.rb +7 -5
- data/lib/nexpose_ticketing/nx_logger.rb +1 -1
- data/lib/nexpose_ticketing/report_helper.rb +1 -0
- data/lib/nexpose_ticketing/version.rb +1 -1
- metadata +21 -21
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
NGJlOWNhNmE5NGJiZDAwYjFkYjJhZDBiODhjNWY5NmNjMTk4Mjk3Zg==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f87999035739237fdbbb5c978292fb1327b95d35
|
4
|
+
data.tar.gz: 6d917864b7f2a5d9246fc2214bbea37b464323e1
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
YTFjNWQ2OGFjNWM0NWFmMDVlODMxNjA0MWFlYzI2Y2FjOWIxNDA1NzUxNDZi
|
11
|
-
ODUwNWI4YTkzMzY2MTk1NTMyYzJjNzRmMjQ0MTAzNWQyMGQ1ZjI=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
NTE4ZDZlY2I5NDFhMmM2YTMxMjcwZWY2MDcxZTU4NzVlNDZjNDRjODI4OGZm
|
14
|
-
ODM0YWIzZGMyMTRlZWU1YzlhNTkxYmQyNTVmMzNjMTY1Yjg5YTRmMjI5Zjhm
|
15
|
-
ZWI2ZmI1MjcyMmM5MmIxNzgwYjc5Y2JlMGU3YzM0MDJlMGFjYjk=
|
6
|
+
metadata.gz: 3f8f1a3907e9ba7c3e556b75253c8833946a65c59efd62e06816f54853d894796f1bfd733323f94459ff0e2dada0d6d17a86549cc0e53a3fe1182ef5647a236f
|
7
|
+
data.tar.gz: 374e3350847992ee22d5abc9377d64867f2670da2b6f5c48f256ef02e0d6906cc3e33af87ad5cf23aaeb9f397228364d1f3bf0c945065842228cc67d784d30ad
|
data/README.md
CHANGED
@@ -72,8 +72,21 @@ We welcome contributions to this package. We ask only that pull requests and pat
|
|
72
72
|
|
73
73
|
##Changelog
|
74
74
|
|
75
|
+
###1.0.2
|
76
|
+
08-02-2016
|
77
|
+
- Encoding is now enforced as UTF-8 when parsing CSV files - fixes environment-specific errors.
|
78
|
+
|
79
|
+
Jira Helper:
|
80
|
+
- Non-200 return codes are now logged when creating or updating tickets.
|
81
|
+
|
82
|
+
NX Logger:
|
83
|
+
- Fixed Windows-specific, input-related errors.
|
84
|
+
|
85
|
+
ServiceNow:
|
86
|
+
- No longer queries for existing incident if ticket is new.
|
87
|
+
|
75
88
|
###1.0.1
|
76
|
-
19-01-
|
89
|
+
19-01-2016
|
77
90
|
|
78
91
|
ServiceNow Helper:
|
79
92
|
- New update set.
|
data/bin/nexpose_jira
CHANGED
@@ -12,6 +12,8 @@ log.setup_logging(true, 'info')
|
|
12
12
|
JIRA_CONFIG_PATH = File.join(File.dirname(__FILE__),
|
13
13
|
'../lib/nexpose_ticketing/config/jira.config')
|
14
14
|
|
15
|
+
current_encoding = Encoding.default_external=Encoding.find("UTF-8")
|
16
|
+
|
15
17
|
# Read in JIRA options from jira.config.
|
16
18
|
jira_options = begin
|
17
19
|
YAML.load_file(JIRA_CONFIG_PATH)
|
@@ -19,5 +21,7 @@ rescue ArgumentError => e
|
|
19
21
|
raise "Could not parse YAML #{JIRA_CONFIG_PATH} : #{e.message}"
|
20
22
|
end
|
21
23
|
|
24
|
+
log.log_message("Current Encoding set to: #{current_encoding}")
|
25
|
+
|
22
26
|
# Initialize Ticket Service using JIRA.
|
23
27
|
NexposeTicketing.start(jira_options)
|
data/bin/nexpose_remedy
CHANGED
@@ -12,6 +12,8 @@ log.setup_logging(true, 'info')
|
|
12
12
|
REMEDY_CONFIG_PATH = File.join(File.dirname(__FILE__),
|
13
13
|
'../lib/nexpose_ticketing/config/remedy.config')
|
14
14
|
|
15
|
+
current_encoding = Encoding.default_external=Encoding.find("UTF-8")
|
16
|
+
|
15
17
|
# Read in ServiceNow options from servicenow.config
|
16
18
|
remedy_options = begin
|
17
19
|
YAML.load_file(REMEDY_CONFIG_PATH)
|
@@ -19,5 +21,7 @@ rescue ArgumentError => e
|
|
19
21
|
raise "Could not parse YAML #{REMEDY_CONFIG_PATH} : #{e.message}"
|
20
22
|
end
|
21
23
|
|
24
|
+
log.log_message("Current Encoding set to: #{current_encoding}")
|
25
|
+
|
22
26
|
# Initialize Nexpose Ticket Service using Remedy
|
23
27
|
NexposeTicketing.start(remedy_options)
|
data/bin/nexpose_servicedesk
CHANGED
@@ -12,6 +12,8 @@ log.setup_logging(true, 'info')
|
|
12
12
|
SERVICEDESK_CONFIG_PATH = File.join(File.dirname(__FILE__),
|
13
13
|
'../lib/nexpose_ticketing/config/servicedesk.config')
|
14
14
|
|
15
|
+
current_encoding = Encoding.default_external=Encoding.find("UTF-8")
|
16
|
+
|
15
17
|
# Read in ServiceDesk options from servicenow.config
|
16
18
|
servicedesk_options = begin
|
17
19
|
YAML.load_file(SERVICEDESK_CONFIG_PATH)
|
@@ -19,5 +21,7 @@ rescue ArgumentError => e
|
|
19
21
|
raise "Could not parse YAML #{SERVICEDESK_CONFIG_PATH} : #{e.message}"
|
20
22
|
end
|
21
23
|
|
24
|
+
log.log_message("Current Encoding set to: #{current_encoding}")
|
25
|
+
|
22
26
|
# Initialize Nexpose Ticket Service using ServiceDesk
|
23
27
|
NexposeTicketing.start(servicedesk_options)
|
data/bin/nexpose_servicenow
CHANGED
@@ -12,6 +12,8 @@ log.setup_logging(true, 'info')
|
|
12
12
|
SERVICENOW_CONFIG_PATH = File.join(File.dirname(__FILE__),
|
13
13
|
'../lib/nexpose_ticketing/config/servicenow.config')
|
14
14
|
|
15
|
+
current_encoding = Encoding.default_external=Encoding.find("UTF-8")
|
16
|
+
|
15
17
|
# Read in ServiceNow options from servicenow.config
|
16
18
|
servicenow_options = begin
|
17
19
|
YAML.load_file(SERVICENOW_CONFIG_PATH)
|
@@ -19,5 +21,7 @@ rescue ArgumentError => e
|
|
19
21
|
raise "Could not parse YAML #{SERVICENOW_CONFIG_PATH} : #{e.message}"
|
20
22
|
end
|
21
23
|
|
24
|
+
log.log_message("Current Encoding set to: #{current_encoding}")
|
25
|
+
|
22
26
|
# Initialize Nexpose Ticket Service using ServiceNow
|
23
27
|
NexposeTicketing.start(servicenow_options)
|
@@ -37,15 +37,7 @@ class JiraHelper
|
|
37
37
|
uri = URI.parse(("#{@jira_data[:jira_url]}".split("/")[0..-2].join('/') + '/search'))
|
38
38
|
uri.query = [uri.query, URI.escape(jql_query)].compact.join('&')
|
39
39
|
req = Net::HTTP::Get.new(uri.to_s, headers)
|
40
|
-
|
41
|
-
resp = Net::HTTP.new(uri.host, uri.port)
|
42
|
-
|
43
|
-
# Enable this line for debugging the https call.
|
44
|
-
# resp.set_debug_output(@log)
|
45
|
-
|
46
|
-
resp.use_ssl = true if uri.scheme == 'https'
|
47
|
-
resp.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
48
|
-
response = resp.request(req)
|
40
|
+
response = send_jira_request(uri, req)
|
49
41
|
|
50
42
|
issues = JSON.parse(response.body)['issues']
|
51
43
|
if issues.nil? || !issues.any? || issues.size > 1
|
@@ -54,7 +46,62 @@ class JiraHelper
|
|
54
46
|
@log.log_message("Jira returned no key or too many keys for query result! Response was <#{issues}>")
|
55
47
|
return nil
|
56
48
|
end
|
57
|
-
|
49
|
+
return issues[0]['key']
|
50
|
+
end
|
51
|
+
|
52
|
+
# Sends a HTTP request to the JIRA console.
|
53
|
+
#
|
54
|
+
# * *Args* :
|
55
|
+
# - +uri+ - Address of the JIRA endpoint.
|
56
|
+
# - +request+ - Request containing the query or ticket object.
|
57
|
+
#
|
58
|
+
# * *Returns* :
|
59
|
+
# - HTTPResponse containing result from the JIRA console.
|
60
|
+
#
|
61
|
+
def send_request(uri, request, ticket=false)
|
62
|
+
request.basic_auth @jira_data[:username], @jira_data[:password]
|
63
|
+
resp = Net::HTTP.new(uri.host, uri.port)
|
64
|
+
|
65
|
+
# Enable this line for debugging the https call.
|
66
|
+
# resp.set_debug_output(@log)
|
67
|
+
|
68
|
+
resp.use_ssl = uri.scheme == 'https'
|
69
|
+
resp.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
70
|
+
|
71
|
+
return resp.request(request) unless ticket
|
72
|
+
|
73
|
+
resp.start do |http|
|
74
|
+
res = http.request(request)
|
75
|
+
next if res.code.to_i.between?(200,299)
|
76
|
+
@log.log_error_message("Error submitting ticket data: #{res.message}, #{res.body}")
|
77
|
+
res
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Sends a request to the JIRA console.
|
82
|
+
#
|
83
|
+
# * *Args* :
|
84
|
+
# - +uri+ - Address of the JIRA endpoint.
|
85
|
+
# - +request+ - Request containing the query.
|
86
|
+
#
|
87
|
+
# * *Returns* :
|
88
|
+
# - HTTPResponse containing result from the JIRA console.
|
89
|
+
#
|
90
|
+
def send_jira_request(uri, request)
|
91
|
+
send_request(uri, request)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Sends a ticket object to the JIRA console.
|
95
|
+
#
|
96
|
+
# * *Args* :
|
97
|
+
# - +uri+ - Address of the JIRA endpoint.
|
98
|
+
# - +request+ - Request containing the ticket object.
|
99
|
+
#
|
100
|
+
# * *Returns* :
|
101
|
+
# - HTTPResponse containing result from the JIRA console.
|
102
|
+
#
|
103
|
+
def send_ticket(uri, request)
|
104
|
+
send_request(uri, request, true)
|
58
105
|
end
|
59
106
|
|
60
107
|
# Fetches the Jira ticket transition details for the given Jira ticket key. Tries to match the response to the
|
@@ -75,16 +122,7 @@ class JiraHelper
|
|
75
122
|
|
76
123
|
uri = URI.parse(("#{@jira_data[:jira_url]}#{jira_key}/transitions?expand=transitions.fields."))
|
77
124
|
req = Net::HTTP::Get.new(uri.to_s, headers)
|
78
|
-
|
79
|
-
resp = Net::HTTP.new(uri.host, uri.port)
|
80
|
-
|
81
|
-
# Enable this line for debugging the https call.
|
82
|
-
# resp.set_debug_output(@log)
|
83
|
-
|
84
|
-
resp.use_ssl = true if uri.scheme == 'https'
|
85
|
-
resp.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
86
|
-
|
87
|
-
response = resp.request(req)
|
125
|
+
response = send_jira_request(uri, req)
|
88
126
|
|
89
127
|
transitions = JSON.parse(response.body)
|
90
128
|
|
@@ -108,16 +146,8 @@ class JiraHelper
|
|
108
146
|
|
109
147
|
uri = URI.parse("#{@jira_data[:jira_url]}")
|
110
148
|
req = Net::HTTP::Post.new(@jira_data[:jira_url], headers)
|
111
|
-
req.basic_auth @jira_data[:username], @jira_data[:password]
|
112
149
|
req.body = ticket
|
113
|
-
|
114
|
-
|
115
|
-
# Enable this line for debugging the https call.
|
116
|
-
#resp.set_debug_output(@log)
|
117
|
-
|
118
|
-
resp.use_ssl = true if uri.scheme == 'https'
|
119
|
-
resp.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
120
|
-
resp.start { |http| http.request(req) }
|
150
|
+
send_ticket(uri, req)
|
121
151
|
end
|
122
152
|
end
|
123
153
|
|
@@ -196,10 +226,9 @@ class JiraHelper
|
|
196
226
|
headers = { 'Content-Type' => 'application/json',
|
197
227
|
'Accept' => 'application/json' }
|
198
228
|
|
199
|
-
tickets.each
|
229
|
+
tickets.each do |ticket|
|
200
230
|
uri = URI.parse(("#{@jira_data[:jira_url]}#{ticket}/transitions"))
|
201
231
|
req = Net::HTTP::Post.new(uri.to_s, headers)
|
202
|
-
req.basic_auth @jira_data[:username], @jira_data[:password]
|
203
232
|
|
204
233
|
transition = get_jira_transition_details(ticket, @jira_data[:close_step_id])
|
205
234
|
if transition.nil?
|
@@ -227,15 +256,8 @@ class JiraHelper
|
|
227
256
|
end
|
228
257
|
|
229
258
|
req.body = "{\"transition\" : {\"id\" : #{transition['id']}}, \"fields\" : { #{required_fields.join(",")}}}"
|
230
|
-
|
231
|
-
|
232
|
-
# Enable this line for debugging the https call.
|
233
|
-
#resp.set_debug_output(@log)
|
234
|
-
|
235
|
-
resp.use_ssl = true if uri.scheme == 'https'
|
236
|
-
resp.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
237
|
-
resp.start { |http| http.request(req) }
|
238
|
-
}
|
259
|
+
send_ticket(uri, req)
|
260
|
+
end
|
239
261
|
end
|
240
262
|
end
|
241
263
|
|
@@ -287,19 +309,11 @@ class JiraHelper
|
|
287
309
|
|
288
310
|
send_whole_ticket ? req = Net::HTTP::Post.new(uri.to_s, headers) : req = Net::HTTP::Put.new(uri.to_s, headers)
|
289
311
|
|
290
|
-
req.basic_auth @jira_data[:username], @jira_data[:password]
|
291
312
|
send_whole_ticket ?
|
292
313
|
req.body = ticket_details.last :
|
293
314
|
req.body = {'update' => {'description' => [{'set' => "#{JSON.parse(ticket_details[1])['fields']['description']}"}]}}.to_json
|
294
315
|
|
295
|
-
|
296
|
-
|
297
|
-
# Enable this line for debugging the https call.
|
298
|
-
#resp.set_debug_output(@log)
|
299
|
-
|
300
|
-
resp.use_ssl = true if uri.scheme == 'https'
|
301
|
-
resp.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
302
|
-
resp.start { |http| http.request(req) }
|
316
|
+
send_ticket(uri, req)
|
303
317
|
end
|
304
318
|
end
|
305
319
|
end
|
@@ -188,7 +188,7 @@ class ServiceNowHelper
|
|
188
188
|
#
|
189
189
|
def prepare_tickets(vulnerability_list, nexpose_identifier_id, matching_fields)
|
190
190
|
@ticket = Hash.new(-1)
|
191
|
-
|
191
|
+
|
192
192
|
@log.log_message("Preparing tickets in #{options[:ticket_mode]} address.")
|
193
193
|
tickets = []
|
194
194
|
previous_row = nil
|
@@ -200,10 +200,10 @@ class ServiceNowHelper
|
|
200
200
|
previous_row = row.dup
|
201
201
|
nxid = @common_helper.generate_nxid(nexpose_identifier_id, row)
|
202
202
|
|
203
|
-
action =
|
204
|
-
'update'
|
205
|
-
else
|
203
|
+
action = if row['comparison'].nil? || row['comparison'] == 'New'
|
206
204
|
'insert'
|
205
|
+
else
|
206
|
+
'update'
|
207
207
|
end
|
208
208
|
|
209
209
|
@ticket = {
|
@@ -229,7 +229,9 @@ class ServiceNowHelper
|
|
229
229
|
description = nil
|
230
230
|
redo
|
231
231
|
else
|
232
|
-
|
232
|
+
unless row['comparison'].nil? || row['comparison'] == 'New'
|
233
|
+
@ticket['sysparm_action'] = 'update'
|
234
|
+
end
|
233
235
|
description = @common_helper.update_description(description, row)
|
234
236
|
end
|
235
237
|
end
|
@@ -46,7 +46,7 @@ module NexposeTicketing
|
|
46
46
|
require 'logger'
|
47
47
|
directory = File.dirname(@logger_file)
|
48
48
|
FileUtils.mkdir_p(directory) unless File.directory?(directory)
|
49
|
-
io = IO.for_fd(IO.sysopen(@logger_file, 'a'))
|
49
|
+
io = IO.for_fd(IO.sysopen(@logger_file, 'a'), 'a')
|
50
50
|
io.autoclose = false
|
51
51
|
io.sync = true
|
52
52
|
@log = Logger.new(io, 'weekly')
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nexpose_ticketing
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Damian Finol
|
@@ -10,94 +10,94 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2016-
|
13
|
+
date: 2016-02-08 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: nexpose
|
17
17
|
requirement: !ruby/object:Gem::Requirement
|
18
18
|
requirements:
|
19
|
-
- - ~>
|
19
|
+
- - "~>"
|
20
20
|
- !ruby/object:Gem::Version
|
21
21
|
version: '2.1'
|
22
|
-
- -
|
22
|
+
- - ">="
|
23
23
|
- !ruby/object:Gem::Version
|
24
24
|
version: 2.1.0
|
25
25
|
type: :runtime
|
26
26
|
prerelease: false
|
27
27
|
version_requirements: !ruby/object:Gem::Requirement
|
28
28
|
requirements:
|
29
|
-
- - ~>
|
29
|
+
- - "~>"
|
30
30
|
- !ruby/object:Gem::Version
|
31
31
|
version: '2.1'
|
32
|
-
- -
|
32
|
+
- - ">="
|
33
33
|
- !ruby/object:Gem::Version
|
34
34
|
version: 2.1.0
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: savon
|
37
37
|
requirement: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
|
-
- - ~>
|
39
|
+
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: '2.1'
|
42
42
|
type: :runtime
|
43
43
|
prerelease: false
|
44
44
|
version_requirements: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
|
-
- - ~>
|
46
|
+
- - "~>"
|
47
47
|
- !ruby/object:Gem::Version
|
48
48
|
version: '2.1'
|
49
49
|
- !ruby/object:Gem::Dependency
|
50
50
|
name: nokogiri
|
51
51
|
requirement: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
|
-
- - ~>
|
53
|
+
- - "~>"
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
version: '1.6'
|
56
56
|
type: :runtime
|
57
57
|
prerelease: false
|
58
58
|
version_requirements: !ruby/object:Gem::Requirement
|
59
59
|
requirements:
|
60
|
-
- - ~>
|
60
|
+
- - "~>"
|
61
61
|
- !ruby/object:Gem::Version
|
62
62
|
version: '1.6'
|
63
63
|
- !ruby/object:Gem::Dependency
|
64
64
|
name: rspec
|
65
65
|
requirement: !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
|
-
- - ~>
|
67
|
+
- - "~>"
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
version: '3.2'
|
70
|
-
- -
|
70
|
+
- - ">="
|
71
71
|
- !ruby/object:Gem::Version
|
72
72
|
version: 3.2.0
|
73
73
|
type: :development
|
74
74
|
prerelease: false
|
75
75
|
version_requirements: !ruby/object:Gem::Requirement
|
76
76
|
requirements:
|
77
|
-
- - ~>
|
77
|
+
- - "~>"
|
78
78
|
- !ruby/object:Gem::Version
|
79
79
|
version: '3.2'
|
80
|
-
- -
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: 3.2.0
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rspec-mocks
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - ~>
|
87
|
+
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '3.2'
|
90
|
-
- -
|
90
|
+
- - ">="
|
91
91
|
- !ruby/object:Gem::Version
|
92
92
|
version: 3.2.0
|
93
93
|
type: :development
|
94
94
|
prerelease: false
|
95
95
|
version_requirements: !ruby/object:Gem::Requirement
|
96
96
|
requirements:
|
97
|
-
- - ~>
|
97
|
+
- - "~>"
|
98
98
|
- !ruby/object:Gem::Version
|
99
99
|
version: '3.2'
|
100
|
-
- -
|
100
|
+
- - ">="
|
101
101
|
- !ruby/object:Gem::Version
|
102
102
|
version: 3.2.0
|
103
103
|
description: This gem provides a Ruby implementation of different integrations with
|
@@ -149,17 +149,17 @@ require_paths:
|
|
149
149
|
- lib
|
150
150
|
required_ruby_version: !ruby/object:Gem::Requirement
|
151
151
|
requirements:
|
152
|
-
- -
|
152
|
+
- - ">="
|
153
153
|
- !ruby/object:Gem::Version
|
154
154
|
version: '1.9'
|
155
155
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
156
156
|
requirements:
|
157
|
-
- -
|
157
|
+
- - ">="
|
158
158
|
- !ruby/object:Gem::Version
|
159
159
|
version: '0'
|
160
160
|
requirements: []
|
161
161
|
rubyforge_project:
|
162
|
-
rubygems_version: 2.
|
162
|
+
rubygems_version: 2.4.8
|
163
163
|
signing_key:
|
164
164
|
specification_version: 4
|
165
165
|
summary: Ruby Nexpose Ticketing Engine.
|