silo_manager 0.0.3 → 0.0.4
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/bin/silo_manager +464 -464
- data/lib/options.rb +33 -33
- data/lib/test.rb +7 -7
- metadata +54 -33
data/bin/silo_manager
CHANGED
|
@@ -1,465 +1,465 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# TODO: Fix multi-byte problem (copied and pasted from PDF)
|
|
3
|
-
|
|
4
|
-
require 'rubygems'
|
|
5
|
-
require File.expand_path(File.join(File.dirname(__FILE__), '../lib/nexpose'))
|
|
6
|
-
require File.expand_path(File.join(File.dirname(__FILE__), '../lib/options'))
|
|
7
|
-
|
|
8
|
-
################################
|
|
9
|
-
# Multi-Tenant User Attributes #
|
|
10
|
-
################################
|
|
11
|
-
MTU_ATTRS = ['authsrcid:integer:required', 'user-name:string:required',
|
|
12
|
-
'full-name:string:required', 'email:string:optional', 'password:string:required', 'enabled:boolean:required',
|
|
13
|
-
'superuser:boolean:required']
|
|
14
|
-
|
|
15
|
-
SILO_ACCESS_ATTRS = ['all-groups:boolean:required', 'all-sites:boolean:required', 'default-silo:boolean:required',
|
|
16
|
-
'role-name:string:required', 'silo-id:string:required']
|
|
17
|
-
|
|
18
|
-
###########################
|
|
19
|
-
# Silo Profile Attributes #
|
|
20
|
-
###########################
|
|
21
|
-
SILO_PROFILE_ATTRS = ['id:string:required', 'name:string:required', 'description:string:optional',
|
|
22
|
-
'all-licensed-modules:boolean:required', 'all-global-engines:boolean:required', 'all-global-report-templates:boolean:required',
|
|
23
|
-
'all-global-scan-templates:boolean:required']
|
|
24
|
-
|
|
25
|
-
ACCEPTED_REPORT_INPUTS = ['csv', 'db', 'html', 'ns-xml', 'pdf', 'qualys-xml', 'raw-xml', 'rtf', 'scap-xml', 'text']
|
|
26
|
-
|
|
27
|
-
###################
|
|
28
|
-
# Silo Attributes #
|
|
29
|
-
###################
|
|
30
|
-
SILO_CONFIG_ATTRS = ['id:string:required', 'name:string:required', 'silo-profile-id:string:required',
|
|
31
|
-
'description:string:optional', 'max-assets:integer:required', 'max-hosted-assets:integer:required',
|
|
32
|
-
'max-users:integer:required']
|
|
33
|
-
|
|
34
|
-
MERCHANT_ATTRS = ['acquirer-relationship:boolean:required', 'agent-relationship:boolean:required',
|
|
35
|
-
'payment-application:string:required', 'payment-version:string:required', 'ecommerce:boolean:required',
|
|
36
|
-
'grocery:boolean:required', 'mail-order:boolean:required', 'petroleum:boolean:required', 'retail:boolean:required',
|
|
37
|
-
'telecommunication:boolean:required', 'travel:boolean:required', 'url:string:required', 'company:string:required',
|
|
38
|
-
'email-address:string:optional', 'first-name:string:required', 'last-name:string:required', 'phone-number:string:required',
|
|
39
|
-
'title:string:optional']
|
|
40
|
-
|
|
41
|
-
ADDRESS_ATTRS = ['city:string:required', 'country:string:required', 'line1:string:required', 'line2:string:required',
|
|
42
|
-
'state:string:required', 'zip:string:required']
|
|
43
|
-
|
|
44
|
-
QSA_ATTRS = ['url:string:required', 'company:string:required', 'email-address:string:optional', 'first-name:string:required',
|
|
45
|
-
'last-name:string:required', 'phone-number:string:required', 'title:string:optional']
|
|
46
|
-
|
|
47
|
-
ORG_ATTRS = ['url:string:required', 'company:string:required', 'email-address:string:optional', 'first-name:string:required',
|
|
48
|
-
'last-name:string:required', 'phone-number:string:required', 'title:string:optional']
|
|
49
|
-
|
|
50
|
-
#-------------------------------------------------------------------------
|
|
51
|
-
#-------------------------------------------------------------------------
|
|
52
|
-
def get_integer_input name, return_main=false, required
|
|
53
|
-
integer_inputed = false
|
|
54
|
-
while !integer_inputed
|
|
55
|
-
puts "Enter an integer value for #{name}:"
|
|
56
|
-
begin
|
|
57
|
-
input = gets.chomp
|
|
58
|
-
if return_main and input =~ /:main/i
|
|
59
|
-
return :main
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
if input.empty? and required
|
|
63
|
-
puts 'Input is required'
|
|
64
|
-
next
|
|
65
|
-
elsif input.empty?
|
|
66
|
-
return nil
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
begin
|
|
70
|
-
input = Integer input
|
|
71
|
-
integer_inputed = true
|
|
72
|
-
rescue Exception
|
|
73
|
-
puts "Invalid input"
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
input
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
#-------------------------------------------------------------------------
|
|
81
|
-
#-------------------------------------------------------------------------
|
|
82
|
-
def get_string_input name, return_main=false, required
|
|
83
|
-
success = false
|
|
84
|
-
while !success
|
|
85
|
-
puts "Enter an string value for #{name}:"
|
|
86
|
-
input = gets.chomp
|
|
87
|
-
if return_main and input =~ /:main/i
|
|
88
|
-
return :main
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
if input.empty? and required
|
|
92
|
-
puts 'Input is required'
|
|
93
|
-
next
|
|
94
|
-
elsif input.empty?
|
|
95
|
-
return nil
|
|
96
|
-
end
|
|
97
|
-
success = true
|
|
98
|
-
end
|
|
99
|
-
input
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
#-------------------------------------------------------------------------
|
|
103
|
-
#-------------------------------------------------------------------------
|
|
104
|
-
def get_boolean_input name='', return_main=false, required
|
|
105
|
-
boolean_inputed = false
|
|
106
|
-
while !boolean_inputed
|
|
107
|
-
puts "Enter a boolean value (true/1 or false/0) for #{name}:"
|
|
108
|
-
begin
|
|
109
|
-
input = gets.chomp
|
|
110
|
-
if return_main and input =~ /:main/i
|
|
111
|
-
return :main
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
if input.empty? and required
|
|
115
|
-
puts 'Input is required'
|
|
116
|
-
next
|
|
117
|
-
elsif input.empty?
|
|
118
|
-
return nil
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
if input =~ /true|1/i
|
|
122
|
-
input = true
|
|
123
|
-
boolean_inputed = true
|
|
124
|
-
elsif input =~ /false|0/i
|
|
125
|
-
input = false
|
|
126
|
-
boolean_inputed = true
|
|
127
|
-
else
|
|
128
|
-
puts "Invalid input!"
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
end
|
|
132
|
-
input
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
#-------------------------------------------------------------------------
|
|
136
|
-
#-------------------------------------------------------------------------
|
|
137
|
-
def process_attrs attrs, title
|
|
138
|
-
puts title
|
|
139
|
-
puts "To return to the main menu type ':main'"
|
|
140
|
-
|
|
141
|
-
input_hash = {}
|
|
142
|
-
|
|
143
|
-
attrs.each do |attr|
|
|
144
|
-
parts = attr.split ":"
|
|
145
|
-
name = parts[0] + " (#{parts[2]})"
|
|
146
|
-
required = ('required'.eql? parts[2])
|
|
147
|
-
case parts[1]
|
|
148
|
-
when /boolean/
|
|
149
|
-
input = get_boolean_input name, true, required
|
|
150
|
-
when /integer/
|
|
151
|
-
input = get_integer_input name, true, required
|
|
152
|
-
when /string/
|
|
153
|
-
input = get_string_input name, true, required
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
if input == :main
|
|
157
|
-
return nil
|
|
158
|
-
elsif input.nil?
|
|
159
|
-
# don't add the entry
|
|
160
|
-
next
|
|
161
|
-
else
|
|
162
|
-
input_hash[parts[0]] = input
|
|
163
|
-
end
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
input_hash
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
#-------------------------------------------------------------------------
|
|
171
|
-
# Gets an comma separated list of input from the user and parses
|
|
172
|
-
# it into an array
|
|
173
|
-
#
|
|
174
|
-
# integer - if true, the input values must be an integers
|
|
175
|
-
# restricted_values - Input should be of a certain type
|
|
176
|
-
#-------------------------------------------------------------------------
|
|
177
|
-
def get_value_array integer=false, restricted_values=[]
|
|
178
|
-
output = []
|
|
179
|
-
success = false
|
|
180
|
-
while !success
|
|
181
|
-
puts "Enter a comma separated list of values or nothing to skip:"
|
|
182
|
-
if not restricted_values.empty?
|
|
183
|
-
puts "Input is restricted to: #{restricted_values.inspect}"
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
input = gets.chomp
|
|
187
|
-
|
|
188
|
-
if input =~ /:main/
|
|
189
|
-
return nil
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
if input.empty?
|
|
193
|
-
return []
|
|
194
|
-
end
|
|
195
|
-
|
|
196
|
-
begin
|
|
197
|
-
input.split(",").each do |part|
|
|
198
|
-
|
|
199
|
-
# Do validation first
|
|
200
|
-
if not restricted_values.empty?
|
|
201
|
-
if not restricted_values.include? part
|
|
202
|
-
"This is not an allowed input: #{part.to_s}"
|
|
203
|
-
raise
|
|
204
|
-
end
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
output << (integer ? part.to_i : part.to_s)
|
|
208
|
-
end
|
|
209
|
-
success = true
|
|
210
|
-
rescue Exception
|
|
211
|
-
puts "Invalid input!"
|
|
212
|
-
if integer
|
|
213
|
-
puts "Integer input only"
|
|
214
|
-
end
|
|
215
|
-
end
|
|
216
|
-
end
|
|
217
|
-
|
|
218
|
-
output
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
#-------------------------------------------------------------------------
|
|
222
|
-
#-------------------------------------------------------------------------
|
|
223
|
-
def enter_data? type
|
|
224
|
-
while true
|
|
225
|
-
puts "Do you wish to enter #{type} data (yes/no)?"
|
|
226
|
-
input = gets.chomp
|
|
227
|
-
if input =~ /yes/i
|
|
228
|
-
return true
|
|
229
|
-
elsif input =~ /no/i
|
|
230
|
-
return false
|
|
231
|
-
else
|
|
232
|
-
puts "Invalid input!"
|
|
233
|
-
end
|
|
234
|
-
end
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
#-------------------------------------------------------------------------
|
|
238
|
-
# Main method that builds the input map for creating a multi-tenant user
|
|
239
|
-
#-------------------------------------------------------------------------
|
|
240
|
-
def create_multi_tenant_user
|
|
241
|
-
user_config = process_attrs MTU_ATTRS, "User Configuration"
|
|
242
|
-
if not user_config
|
|
243
|
-
return
|
|
244
|
-
end
|
|
245
|
-
|
|
246
|
-
silo_configs = process_attrs SILO_ACCESS_ATTRS, "Silo Configuration"
|
|
247
|
-
if not silo_configs
|
|
248
|
-
return
|
|
249
|
-
end
|
|
250
|
-
|
|
251
|
-
if not silo_configs['all-sites']
|
|
252
|
-
puts "Site ID values:"
|
|
253
|
-
ids = get_value_array true
|
|
254
|
-
if not ids
|
|
255
|
-
return
|
|
256
|
-
end
|
|
257
|
-
if ids and not ids.empty?
|
|
258
|
-
silo_configs['allowed-sites'] = ids
|
|
259
|
-
end
|
|
260
|
-
end
|
|
261
|
-
|
|
262
|
-
if not silo_configs['all-groups']
|
|
263
|
-
puts "Group ID values:"
|
|
264
|
-
ids = get_value_array true
|
|
265
|
-
if not ids
|
|
266
|
-
return
|
|
267
|
-
end
|
|
268
|
-
if ids and not ids.empty?
|
|
269
|
-
silo_configs['allowed-groups'] = ids
|
|
270
|
-
end
|
|
271
|
-
end
|
|
272
|
-
|
|
273
|
-
begin
|
|
274
|
-
@client_api.login
|
|
275
|
-
@client_api.create_multi_tenant_user user_config, silo_configs
|
|
276
|
-
puts "Successfully created multi-tenant user!"
|
|
277
|
-
rescue Exception => e
|
|
278
|
-
puts e.message
|
|
279
|
-
end
|
|
280
|
-
end
|
|
281
|
-
|
|
282
|
-
#-------------------------------------------------------------------------
|
|
283
|
-
# Main method that builds the input map for creating a silo profile
|
|
284
|
-
#-------------------------------------------------------------------------
|
|
285
|
-
def create_silo_profile
|
|
286
|
-
silo_profile_config = process_attrs SILO_PROFILE_ATTRS, "Silo Profile Configuration"
|
|
287
|
-
if not silo_profile_config
|
|
288
|
-
return
|
|
289
|
-
end
|
|
290
|
-
|
|
291
|
-
permissions = {}
|
|
292
|
-
|
|
293
|
-
unless silo_profile_config['all-global-report-templates']
|
|
294
|
-
puts "Global report template names:"
|
|
295
|
-
names = get_value_array
|
|
296
|
-
if not names
|
|
297
|
-
return
|
|
298
|
-
end
|
|
299
|
-
if names and not names.empty?
|
|
300
|
-
permissions['global_report_templates'] = names
|
|
301
|
-
end
|
|
302
|
-
end
|
|
303
|
-
|
|
304
|
-
unless silo_profile_config['all-global-engines']
|
|
305
|
-
puts "Global scan engine names:"
|
|
306
|
-
names = get_value_array
|
|
307
|
-
if not names
|
|
308
|
-
return
|
|
309
|
-
end
|
|
310
|
-
if names and not names.empty?
|
|
311
|
-
permissions['global_scan_engines'] = names
|
|
312
|
-
end
|
|
313
|
-
end
|
|
314
|
-
|
|
315
|
-
unless silo_profile_config['all-global-scan-templates']
|
|
316
|
-
puts "Global scan template names:"
|
|
317
|
-
names = get_value_array
|
|
318
|
-
if not names
|
|
319
|
-
return
|
|
320
|
-
end
|
|
321
|
-
if names and not names.empty?
|
|
322
|
-
permissions['global_scan_templates'] = names
|
|
323
|
-
end
|
|
324
|
-
end
|
|
325
|
-
|
|
326
|
-
unless silo_profile_config['all-licensed-modules']
|
|
327
|
-
puts "Licensed module names:"
|
|
328
|
-
names = get_value_array
|
|
329
|
-
if not names
|
|
330
|
-
return
|
|
331
|
-
end
|
|
332
|
-
if names and not names.empty?
|
|
333
|
-
permissions['licensed_modules'] = names
|
|
334
|
-
end
|
|
335
|
-
end
|
|
336
|
-
|
|
337
|
-
puts "Restricted Report Format names:"
|
|
338
|
-
names = get_value_array false, ACCEPTED_REPORT_INPUTS
|
|
339
|
-
unless names
|
|
340
|
-
return
|
|
341
|
-
end
|
|
342
|
-
if names and not names.empty?
|
|
343
|
-
permissions['restricted_report_formats'] = names
|
|
344
|
-
end
|
|
345
|
-
|
|
346
|
-
puts "Restricted Report Section names:"
|
|
347
|
-
names = get_value_array
|
|
348
|
-
unless names
|
|
349
|
-
return
|
|
350
|
-
end
|
|
351
|
-
if names and not names.empty?
|
|
352
|
-
permissions['restricted_report_sections'] = names
|
|
353
|
-
end
|
|
354
|
-
|
|
355
|
-
begin
|
|
356
|
-
@client_api.login
|
|
357
|
-
@client_api.create_silo_profile silo_profile_config, permissions
|
|
358
|
-
puts "Successfully created silo profile!"
|
|
359
|
-
rescue Exception => e
|
|
360
|
-
puts e.message
|
|
361
|
-
end
|
|
362
|
-
end
|
|
363
|
-
|
|
364
|
-
#-------------------------------------------------------------------------
|
|
365
|
-
# Main method that builds the input map for creating a silo
|
|
366
|
-
#-------------------------------------------------------------------------
|
|
367
|
-
def create_silo
|
|
368
|
-
silo_config = process_attrs SILO_CONFIG_ATTRS, "Silo Configuration"
|
|
369
|
-
if not silo_config
|
|
370
|
-
return
|
|
371
|
-
end
|
|
372
|
-
|
|
373
|
-
if (enter_data? "Organization")
|
|
374
|
-
organization_data = process_attrs ORG_ATTRS, "Organization Data"
|
|
375
|
-
address_data = process_attrs ADDRESS_ATTRS, "Address Data"
|
|
376
|
-
silo_config['organization'] = organization_data
|
|
377
|
-
silo_config['organization']['address'] = address_data
|
|
378
|
-
end
|
|
379
|
-
|
|
380
|
-
if (enter_data? "Merchant")
|
|
381
|
-
merchant_data = process_attrs MERCHANT_ATTRS , "Merchant Data"
|
|
382
|
-
merchant_address = process_attrs ADDRESS_ATTRS, "Merchant Address Data"
|
|
383
|
-
|
|
384
|
-
puts "DBA values"
|
|
385
|
-
dba = get_value_array
|
|
386
|
-
|
|
387
|
-
puts "Industry values"
|
|
388
|
-
industries = get_value_array
|
|
389
|
-
|
|
390
|
-
qsa = process_attrs QSA_ATTRS, "QSA Data"
|
|
391
|
-
qsa_address = process_attrs ADDRESS_ATTRS, "QSA Address Data"
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
silo_config['merchant'] = merchant_data
|
|
395
|
-
silo_config['merchant']['address'] = merchant_address
|
|
396
|
-
silo_config['merchant']['other_industries'] = industries
|
|
397
|
-
silo_config['merchant']['dba'] = dba
|
|
398
|
-
silo_config['merchant']['qsa'] = qsa
|
|
399
|
-
silo_config['merchant']['qsa']['address'] = qsa_address
|
|
400
|
-
end
|
|
401
|
-
|
|
402
|
-
begin
|
|
403
|
-
@client_api.login
|
|
404
|
-
@client_api.create_silo silo_config
|
|
405
|
-
puts "Successfully created silo!"
|
|
406
|
-
rescue Exception => e
|
|
407
|
-
puts e.message
|
|
408
|
-
end
|
|
409
|
-
end
|
|
410
|
-
|
|
411
|
-
#-------------------------------------------------------------------------
|
|
412
|
-
# Main input screen
|
|
413
|
-
#-------------------------------------------------------------------------
|
|
414
|
-
def get_main_select
|
|
415
|
-
id_choosen = false
|
|
416
|
-
while !id_choosen
|
|
417
|
-
puts "\nChoose one of the following IDs:"
|
|
418
|
-
puts "1. Create a new multi-tenant user"
|
|
419
|
-
puts "2. Create a new silo-profile"
|
|
420
|
-
puts "3. Create a new silo"
|
|
421
|
-
|
|
422
|
-
id = gets.chomp
|
|
423
|
-
if id =~ /quit/i
|
|
424
|
-
exit 0
|
|
425
|
-
end
|
|
426
|
-
|
|
427
|
-
begin
|
|
428
|
-
id = id.to_i
|
|
429
|
-
id_choosen = true
|
|
430
|
-
rescue Exception => e
|
|
431
|
-
e.
|
|
432
|
-
puts "Input error"
|
|
433
|
-
end
|
|
434
|
-
end
|
|
435
|
-
id
|
|
436
|
-
end
|
|
437
|
-
|
|
438
|
-
###############
|
|
439
|
-
# ENTRY POINT #
|
|
440
|
-
###############
|
|
441
|
-
begin
|
|
442
|
-
options = Options.parse ARGV
|
|
443
|
-
begin
|
|
444
|
-
@client_api = Nexpose::Connection.new options.host, options.user, options.password, options.port
|
|
445
|
-
@client_api.login
|
|
446
|
-
rescue Exception => e
|
|
447
|
-
puts "Unable to connect to #{options.host}"
|
|
448
|
-
puts e.message
|
|
449
|
-
exit 1
|
|
450
|
-
end
|
|
451
|
-
|
|
452
|
-
while true
|
|
453
|
-
puts "To quit at anytime type 'quit'"
|
|
454
|
-
case get_main_select
|
|
455
|
-
when 1
|
|
456
|
-
create_multi_tenant_user
|
|
457
|
-
when 2
|
|
458
|
-
create_silo_profile
|
|
459
|
-
when 3
|
|
460
|
-
create_silo
|
|
461
|
-
else
|
|
462
|
-
puts "Invalid input"
|
|
463
|
-
end
|
|
464
|
-
end
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# TODO: Fix multi-byte problem (copied and pasted from PDF)
|
|
3
|
+
|
|
4
|
+
require 'rubygems'
|
|
5
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../lib/nexpose'))
|
|
6
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../lib/options'))
|
|
7
|
+
|
|
8
|
+
################################
|
|
9
|
+
# Multi-Tenant User Attributes #
|
|
10
|
+
################################
|
|
11
|
+
MTU_ATTRS = ['authsrcid:integer:required', 'user-name:string:required',
|
|
12
|
+
'full-name:string:required', 'email:string:optional', 'password:string:required', 'enabled:boolean:required',
|
|
13
|
+
'superuser:boolean:required']
|
|
14
|
+
|
|
15
|
+
SILO_ACCESS_ATTRS = ['all-groups:boolean:required', 'all-sites:boolean:required', 'default-silo:boolean:required',
|
|
16
|
+
'role-name:string:required', 'silo-id:string:required']
|
|
17
|
+
|
|
18
|
+
###########################
|
|
19
|
+
# Silo Profile Attributes #
|
|
20
|
+
###########################
|
|
21
|
+
SILO_PROFILE_ATTRS = ['id:string:required', 'name:string:required', 'description:string:optional',
|
|
22
|
+
'all-licensed-modules:boolean:required', 'all-global-engines:boolean:required', 'all-global-report-templates:boolean:required',
|
|
23
|
+
'all-global-scan-templates:boolean:required']
|
|
24
|
+
|
|
25
|
+
ACCEPTED_REPORT_INPUTS = ['csv', 'db', 'html', 'ns-xml', 'pdf', 'qualys-xml', 'raw-xml', 'rtf', 'scap-xml', 'text']
|
|
26
|
+
|
|
27
|
+
###################
|
|
28
|
+
# Silo Attributes #
|
|
29
|
+
###################
|
|
30
|
+
SILO_CONFIG_ATTRS = ['id:string:required', 'name:string:required', 'silo-profile-id:string:required',
|
|
31
|
+
'description:string:optional', 'max-assets:integer:required', 'max-hosted-assets:integer:required',
|
|
32
|
+
'max-users:integer:required']
|
|
33
|
+
|
|
34
|
+
MERCHANT_ATTRS = ['acquirer-relationship:boolean:required', 'agent-relationship:boolean:required',
|
|
35
|
+
'payment-application:string:required', 'payment-version:string:required', 'ecommerce:boolean:required',
|
|
36
|
+
'grocery:boolean:required', 'mail-order:boolean:required', 'petroleum:boolean:required', 'retail:boolean:required',
|
|
37
|
+
'telecommunication:boolean:required', 'travel:boolean:required', 'url:string:required', 'company:string:required',
|
|
38
|
+
'email-address:string:optional', 'first-name:string:required', 'last-name:string:required', 'phone-number:string:required',
|
|
39
|
+
'title:string:optional']
|
|
40
|
+
|
|
41
|
+
ADDRESS_ATTRS = ['city:string:required', 'country:string:required', 'line1:string:required', 'line2:string:required',
|
|
42
|
+
'state:string:required', 'zip:string:required']
|
|
43
|
+
|
|
44
|
+
QSA_ATTRS = ['url:string:required', 'company:string:required', 'email-address:string:optional', 'first-name:string:required',
|
|
45
|
+
'last-name:string:required', 'phone-number:string:required', 'title:string:optional']
|
|
46
|
+
|
|
47
|
+
ORG_ATTRS = ['url:string:required', 'company:string:required', 'email-address:string:optional', 'first-name:string:required',
|
|
48
|
+
'last-name:string:required', 'phone-number:string:required', 'title:string:optional']
|
|
49
|
+
|
|
50
|
+
#-------------------------------------------------------------------------
|
|
51
|
+
#-------------------------------------------------------------------------
|
|
52
|
+
def get_integer_input name, return_main=false, required=false
|
|
53
|
+
integer_inputed = false
|
|
54
|
+
while !integer_inputed
|
|
55
|
+
puts "Enter an integer value for #{name}:"
|
|
56
|
+
begin
|
|
57
|
+
input = gets.chomp
|
|
58
|
+
if return_main and input =~ /:main/i
|
|
59
|
+
return :main
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
if input.empty? and required
|
|
63
|
+
puts 'Input is required'
|
|
64
|
+
next
|
|
65
|
+
elsif input.empty?
|
|
66
|
+
return nil
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
begin
|
|
70
|
+
input = Integer input
|
|
71
|
+
integer_inputed = true
|
|
72
|
+
rescue Exception
|
|
73
|
+
puts "Invalid input"
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
input
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
#-------------------------------------------------------------------------
|
|
81
|
+
#-------------------------------------------------------------------------
|
|
82
|
+
def get_string_input name, return_main=false, required=false
|
|
83
|
+
success = false
|
|
84
|
+
while !success
|
|
85
|
+
puts "Enter an string value for #{name}:"
|
|
86
|
+
input = gets.chomp
|
|
87
|
+
if return_main and input =~ /:main/i
|
|
88
|
+
return :main
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
if input.empty? and required
|
|
92
|
+
puts 'Input is required'
|
|
93
|
+
next
|
|
94
|
+
elsif input.empty?
|
|
95
|
+
return nil
|
|
96
|
+
end
|
|
97
|
+
success = true
|
|
98
|
+
end
|
|
99
|
+
input
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
#-------------------------------------------------------------------------
|
|
103
|
+
#-------------------------------------------------------------------------
|
|
104
|
+
def get_boolean_input name='', return_main=false, required=false
|
|
105
|
+
boolean_inputed = false
|
|
106
|
+
while !boolean_inputed
|
|
107
|
+
puts "Enter a boolean value (true/1 or false/0) for #{name}:"
|
|
108
|
+
begin
|
|
109
|
+
input = gets.chomp
|
|
110
|
+
if return_main and input =~ /:main/i
|
|
111
|
+
return :main
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
if input.empty? and required
|
|
115
|
+
puts 'Input is required'
|
|
116
|
+
next
|
|
117
|
+
elsif input.empty?
|
|
118
|
+
return nil
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
if input =~ /true|1/i
|
|
122
|
+
input = true
|
|
123
|
+
boolean_inputed = true
|
|
124
|
+
elsif input =~ /false|0/i
|
|
125
|
+
input = false
|
|
126
|
+
boolean_inputed = true
|
|
127
|
+
else
|
|
128
|
+
puts "Invalid input!"
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
input
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
#-------------------------------------------------------------------------
|
|
136
|
+
#-------------------------------------------------------------------------
|
|
137
|
+
def process_attrs attrs, title
|
|
138
|
+
puts title
|
|
139
|
+
puts "To return to the main menu type ':main'"
|
|
140
|
+
|
|
141
|
+
input_hash = {}
|
|
142
|
+
|
|
143
|
+
attrs.each do |attr|
|
|
144
|
+
parts = attr.split ":"
|
|
145
|
+
name = parts[0] + " (#{parts[2]})"
|
|
146
|
+
required = ('required'.eql? parts[2])
|
|
147
|
+
case parts[1]
|
|
148
|
+
when /boolean/
|
|
149
|
+
input = get_boolean_input name, true, required
|
|
150
|
+
when /integer/
|
|
151
|
+
input = get_integer_input name, true, required
|
|
152
|
+
when /string/
|
|
153
|
+
input = get_string_input name, true, required
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
if input == :main
|
|
157
|
+
return nil
|
|
158
|
+
elsif input.nil?
|
|
159
|
+
# don't add the entry
|
|
160
|
+
next
|
|
161
|
+
else
|
|
162
|
+
input_hash[parts[0]] = input
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
input_hash
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
#-------------------------------------------------------------------------
|
|
171
|
+
# Gets an comma separated list of input from the user and parses
|
|
172
|
+
# it into an array
|
|
173
|
+
#
|
|
174
|
+
# integer - if true, the input values must be an integers
|
|
175
|
+
# restricted_values - Input should be of a certain type
|
|
176
|
+
#-------------------------------------------------------------------------
|
|
177
|
+
def get_value_array integer=false, restricted_values=[]
|
|
178
|
+
output = []
|
|
179
|
+
success = false
|
|
180
|
+
while !success
|
|
181
|
+
puts "Enter a comma separated list of values or nothing to skip:"
|
|
182
|
+
if not restricted_values.empty?
|
|
183
|
+
puts "Input is restricted to: #{restricted_values.inspect}"
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
input = gets.chomp
|
|
187
|
+
|
|
188
|
+
if input =~ /:main/
|
|
189
|
+
return nil
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
if input.empty?
|
|
193
|
+
return []
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
begin
|
|
197
|
+
input.split(",").each do |part|
|
|
198
|
+
|
|
199
|
+
# Do validation first
|
|
200
|
+
if not restricted_values.empty?
|
|
201
|
+
if not restricted_values.include? part
|
|
202
|
+
"This is not an allowed input: #{part.to_s}"
|
|
203
|
+
raise
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
output << (integer ? part.to_i : part.to_s)
|
|
208
|
+
end
|
|
209
|
+
success = true
|
|
210
|
+
rescue Exception
|
|
211
|
+
puts "Invalid input!"
|
|
212
|
+
if integer
|
|
213
|
+
puts "Integer input only"
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
output
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
#-------------------------------------------------------------------------
|
|
222
|
+
#-------------------------------------------------------------------------
|
|
223
|
+
def enter_data? type
|
|
224
|
+
while true
|
|
225
|
+
puts "Do you wish to enter #{type} data (yes/no)?"
|
|
226
|
+
input = gets.chomp
|
|
227
|
+
if input =~ /yes/i
|
|
228
|
+
return true
|
|
229
|
+
elsif input =~ /no/i
|
|
230
|
+
return false
|
|
231
|
+
else
|
|
232
|
+
puts "Invalid input!"
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
#-------------------------------------------------------------------------
|
|
238
|
+
# Main method that builds the input map for creating a multi-tenant user
|
|
239
|
+
#-------------------------------------------------------------------------
|
|
240
|
+
def create_multi_tenant_user
|
|
241
|
+
user_config = process_attrs MTU_ATTRS, "User Configuration"
|
|
242
|
+
if not user_config
|
|
243
|
+
return
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
silo_configs = process_attrs SILO_ACCESS_ATTRS, "Silo Configuration"
|
|
247
|
+
if not silo_configs
|
|
248
|
+
return
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
if not silo_configs['all-sites']
|
|
252
|
+
puts "Site ID values:"
|
|
253
|
+
ids = get_value_array true
|
|
254
|
+
if not ids
|
|
255
|
+
return
|
|
256
|
+
end
|
|
257
|
+
if ids and not ids.empty?
|
|
258
|
+
silo_configs['allowed-sites'] = ids
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
if not silo_configs['all-groups']
|
|
263
|
+
puts "Group ID values:"
|
|
264
|
+
ids = get_value_array true
|
|
265
|
+
if not ids
|
|
266
|
+
return
|
|
267
|
+
end
|
|
268
|
+
if ids and not ids.empty?
|
|
269
|
+
silo_configs['allowed-groups'] = ids
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
begin
|
|
274
|
+
@client_api.login
|
|
275
|
+
@client_api.create_multi_tenant_user user_config, silo_configs
|
|
276
|
+
puts "Successfully created multi-tenant user!"
|
|
277
|
+
rescue Exception => e
|
|
278
|
+
puts e.message
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
#-------------------------------------------------------------------------
|
|
283
|
+
# Main method that builds the input map for creating a silo profile
|
|
284
|
+
#-------------------------------------------------------------------------
|
|
285
|
+
def create_silo_profile
|
|
286
|
+
silo_profile_config = process_attrs SILO_PROFILE_ATTRS, "Silo Profile Configuration"
|
|
287
|
+
if not silo_profile_config
|
|
288
|
+
return
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
permissions = {}
|
|
292
|
+
|
|
293
|
+
unless silo_profile_config['all-global-report-templates']
|
|
294
|
+
puts "Global report template names:"
|
|
295
|
+
names = get_value_array
|
|
296
|
+
if not names
|
|
297
|
+
return
|
|
298
|
+
end
|
|
299
|
+
if names and not names.empty?
|
|
300
|
+
permissions['global_report_templates'] = names
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
unless silo_profile_config['all-global-engines']
|
|
305
|
+
puts "Global scan engine names:"
|
|
306
|
+
names = get_value_array
|
|
307
|
+
if not names
|
|
308
|
+
return
|
|
309
|
+
end
|
|
310
|
+
if names and not names.empty?
|
|
311
|
+
permissions['global_scan_engines'] = names
|
|
312
|
+
end
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
unless silo_profile_config['all-global-scan-templates']
|
|
316
|
+
puts "Global scan template names:"
|
|
317
|
+
names = get_value_array
|
|
318
|
+
if not names
|
|
319
|
+
return
|
|
320
|
+
end
|
|
321
|
+
if names and not names.empty?
|
|
322
|
+
permissions['global_scan_templates'] = names
|
|
323
|
+
end
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
unless silo_profile_config['all-licensed-modules']
|
|
327
|
+
puts "Licensed module names:"
|
|
328
|
+
names = get_value_array
|
|
329
|
+
if not names
|
|
330
|
+
return
|
|
331
|
+
end
|
|
332
|
+
if names and not names.empty?
|
|
333
|
+
permissions['licensed_modules'] = names
|
|
334
|
+
end
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
puts "Restricted Report Format names:"
|
|
338
|
+
names = get_value_array false, ACCEPTED_REPORT_INPUTS
|
|
339
|
+
unless names
|
|
340
|
+
return
|
|
341
|
+
end
|
|
342
|
+
if names and not names.empty?
|
|
343
|
+
permissions['restricted_report_formats'] = names
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
puts "Restricted Report Section names:"
|
|
347
|
+
names = get_value_array
|
|
348
|
+
unless names
|
|
349
|
+
return
|
|
350
|
+
end
|
|
351
|
+
if names and not names.empty?
|
|
352
|
+
permissions['restricted_report_sections'] = names
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
begin
|
|
356
|
+
@client_api.login
|
|
357
|
+
@client_api.create_silo_profile silo_profile_config, permissions
|
|
358
|
+
puts "Successfully created silo profile!"
|
|
359
|
+
rescue Exception => e
|
|
360
|
+
puts e.message
|
|
361
|
+
end
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
#-------------------------------------------------------------------------
|
|
365
|
+
# Main method that builds the input map for creating a silo
|
|
366
|
+
#-------------------------------------------------------------------------
|
|
367
|
+
def create_silo
|
|
368
|
+
silo_config = process_attrs SILO_CONFIG_ATTRS, "Silo Configuration"
|
|
369
|
+
if not silo_config
|
|
370
|
+
return
|
|
371
|
+
end
|
|
372
|
+
|
|
373
|
+
if (enter_data? "Organization")
|
|
374
|
+
organization_data = process_attrs ORG_ATTRS, "Organization Data"
|
|
375
|
+
address_data = process_attrs ADDRESS_ATTRS, "Address Data"
|
|
376
|
+
silo_config['organization'] = organization_data
|
|
377
|
+
silo_config['organization']['address'] = address_data
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
if (enter_data? "Merchant")
|
|
381
|
+
merchant_data = process_attrs MERCHANT_ATTRS , "Merchant Data"
|
|
382
|
+
merchant_address = process_attrs ADDRESS_ATTRS, "Merchant Address Data"
|
|
383
|
+
|
|
384
|
+
puts "DBA values"
|
|
385
|
+
dba = get_value_array
|
|
386
|
+
|
|
387
|
+
puts "Industry values"
|
|
388
|
+
industries = get_value_array
|
|
389
|
+
|
|
390
|
+
qsa = process_attrs QSA_ATTRS, "QSA Data"
|
|
391
|
+
qsa_address = process_attrs ADDRESS_ATTRS, "QSA Address Data"
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
silo_config['merchant'] = merchant_data
|
|
395
|
+
silo_config['merchant']['address'] = merchant_address
|
|
396
|
+
silo_config['merchant']['other_industries'] = industries
|
|
397
|
+
silo_config['merchant']['dba'] = dba
|
|
398
|
+
silo_config['merchant']['qsa'] = qsa
|
|
399
|
+
silo_config['merchant']['qsa']['address'] = qsa_address
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
begin
|
|
403
|
+
@client_api.login
|
|
404
|
+
@client_api.create_silo silo_config
|
|
405
|
+
puts "Successfully created silo!"
|
|
406
|
+
rescue Exception => e
|
|
407
|
+
puts e.message
|
|
408
|
+
end
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
#-------------------------------------------------------------------------
|
|
412
|
+
# Main input screen
|
|
413
|
+
#-------------------------------------------------------------------------
|
|
414
|
+
def get_main_select
|
|
415
|
+
id_choosen = false
|
|
416
|
+
while !id_choosen
|
|
417
|
+
puts "\nChoose one of the following IDs:"
|
|
418
|
+
puts "1. Create a new multi-tenant user"
|
|
419
|
+
puts "2. Create a new silo-profile"
|
|
420
|
+
puts "3. Create a new silo"
|
|
421
|
+
|
|
422
|
+
id = gets.chomp
|
|
423
|
+
if id =~ /quit/i
|
|
424
|
+
exit 0
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
begin
|
|
428
|
+
id = id.to_i
|
|
429
|
+
id_choosen = true
|
|
430
|
+
rescue Exception => e
|
|
431
|
+
e.
|
|
432
|
+
puts "Input error"
|
|
433
|
+
end
|
|
434
|
+
end
|
|
435
|
+
id
|
|
436
|
+
end
|
|
437
|
+
|
|
438
|
+
###############
|
|
439
|
+
# ENTRY POINT #
|
|
440
|
+
###############
|
|
441
|
+
begin
|
|
442
|
+
options = Options.parse ARGV
|
|
443
|
+
begin
|
|
444
|
+
@client_api = Nexpose::Connection.new options.host, options.user, options.password, options.port
|
|
445
|
+
@client_api.login
|
|
446
|
+
rescue Exception => e
|
|
447
|
+
puts "Unable to connect to #{options.host}"
|
|
448
|
+
puts e.message
|
|
449
|
+
exit 1
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
while true
|
|
453
|
+
puts "To quit at anytime type 'quit'"
|
|
454
|
+
case get_main_select
|
|
455
|
+
when 1
|
|
456
|
+
create_multi_tenant_user
|
|
457
|
+
when 2
|
|
458
|
+
create_silo_profile
|
|
459
|
+
when 3
|
|
460
|
+
create_silo
|
|
461
|
+
else
|
|
462
|
+
puts "Invalid input"
|
|
463
|
+
end
|
|
464
|
+
end
|
|
465
465
|
end
|
data/lib/options.rb
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
require 'ostruct'
|
|
2
|
-
require 'optparse'
|
|
3
|
-
|
|
4
|
-
#------------------------------------------------------------------------------------------------------
|
|
5
|
-
# Defines options to be executed against the NeXpose API
|
|
6
|
-
#------------------------------------------------------------------------------------------------------
|
|
7
|
-
class Options
|
|
8
|
-
def self.parse(args)
|
|
9
|
-
options = OpenStruct.new
|
|
10
|
-
options.port = 3780
|
|
11
|
-
options.host = 'localhost'
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
option_parser = OptionParser.new do |option_parser|
|
|
15
|
-
option_parser.on("-h host", "The network address of the NeXpose instance - Defaults to 'localhost'") { |arg| options.host=arg.chomp }
|
|
16
|
-
option_parser.on("-u user_name", "The NeXpose user name - Required") { |arg| options.user=arg.chomp }
|
|
17
|
-
option_parser.on("-p password", "The NeXpose password - Required") { |arg| options.password=arg.chomp }
|
|
18
|
-
option_parser.on("--port port", "The NSC port - Defaults to 3780") { |arg| options.port=arg.chomp }
|
|
19
|
-
option_parser.on_tail("--help", "Help") do
|
|
20
|
-
puts option_parser
|
|
21
|
-
exit 0
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
begin
|
|
26
|
-
option_parser.parse!(args)
|
|
27
|
-
rescue OptionParser::ParseError => e
|
|
28
|
-
puts "#{e}\n\n#{option_parser}"
|
|
29
|
-
exit 1
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
options
|
|
33
|
-
end
|
|
1
|
+
require 'ostruct'
|
|
2
|
+
require 'optparse'
|
|
3
|
+
|
|
4
|
+
#------------------------------------------------------------------------------------------------------
|
|
5
|
+
# Defines options to be executed against the NeXpose API
|
|
6
|
+
#------------------------------------------------------------------------------------------------------
|
|
7
|
+
class Options
|
|
8
|
+
def self.parse(args)
|
|
9
|
+
options = OpenStruct.new
|
|
10
|
+
options.port = 3780
|
|
11
|
+
options.host = 'localhost'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
option_parser = OptionParser.new do |option_parser|
|
|
15
|
+
option_parser.on("-h host", "The network address of the NeXpose instance - Defaults to 'localhost'") { |arg| options.host=arg.chomp }
|
|
16
|
+
option_parser.on("-u user_name", "The NeXpose user name - Required") { |arg| options.user=arg.chomp }
|
|
17
|
+
option_parser.on("-p password", "The NeXpose password - Required") { |arg| options.password=arg.chomp }
|
|
18
|
+
option_parser.on("--port port", "The NSC port - Defaults to 3780") { |arg| options.port=arg.chomp }
|
|
19
|
+
option_parser.on_tail("--help", "Help") do
|
|
20
|
+
puts option_parser
|
|
21
|
+
exit 0
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
begin
|
|
26
|
+
option_parser.parse!(args)
|
|
27
|
+
rescue OptionParser::ParseError => e
|
|
28
|
+
puts "#{e}\n\n#{option_parser}"
|
|
29
|
+
exit 1
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
options
|
|
33
|
+
end
|
|
34
34
|
end
|
data/lib/test.rb
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
begin
|
|
3
|
-
test = {}
|
|
4
|
-
test['hi-hi'] = true
|
|
5
|
-
unless test['hi-hi']
|
|
6
|
-
puts "Hi"
|
|
7
|
-
end
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
begin
|
|
3
|
+
test = {}
|
|
4
|
+
test['hi-hi'] = true
|
|
5
|
+
unless test['hi-hi']
|
|
6
|
+
puts "Hi"
|
|
7
|
+
end
|
|
8
8
|
end
|
metadata
CHANGED
|
@@ -1,64 +1,85 @@
|
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: silo_manager
|
|
3
|
-
version: !ruby/object:Gem::Version
|
|
4
|
-
|
|
5
|
-
prerelease:
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
hash: 23
|
|
5
|
+
prerelease: false
|
|
6
|
+
segments:
|
|
7
|
+
- 0
|
|
8
|
+
- 0
|
|
9
|
+
- 4
|
|
10
|
+
version: 0.0.4
|
|
6
11
|
platform: ruby
|
|
7
|
-
authors:
|
|
12
|
+
authors:
|
|
8
13
|
- Christopher Lee
|
|
9
14
|
autorequire:
|
|
10
15
|
bindir: bin
|
|
11
16
|
cert_chain: []
|
|
12
|
-
|
|
17
|
+
|
|
18
|
+
date: 2011-10-13 00:00:00 -05:00
|
|
13
19
|
default_executable:
|
|
14
|
-
dependencies:
|
|
15
|
-
- !ruby/object:Gem::Dependency
|
|
20
|
+
dependencies:
|
|
21
|
+
- !ruby/object:Gem::Dependency
|
|
16
22
|
name: nexpose
|
|
17
|
-
|
|
23
|
+
prerelease: false
|
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
18
25
|
none: false
|
|
19
|
-
requirements:
|
|
20
|
-
- -
|
|
21
|
-
- !ruby/object:Gem::Version
|
|
26
|
+
requirements:
|
|
27
|
+
- - ">="
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
hash: 23
|
|
30
|
+
segments:
|
|
31
|
+
- 0
|
|
32
|
+
- 0
|
|
33
|
+
- 4
|
|
22
34
|
version: 0.0.4
|
|
23
35
|
type: :runtime
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
description: ! ' This is a tool is used to provide CRUD silo operations.
|
|
27
|
-
|
|
28
|
-
'
|
|
36
|
+
version_requirements: *id001
|
|
37
|
+
description: " This is a tool is used to provide CRUD silo operations.\n"
|
|
29
38
|
email: christopher_lee@rapid7.com
|
|
30
|
-
executables:
|
|
39
|
+
executables:
|
|
31
40
|
- silo_manager
|
|
32
41
|
extensions: []
|
|
42
|
+
|
|
33
43
|
extra_rdoc_files: []
|
|
34
|
-
|
|
44
|
+
|
|
45
|
+
files:
|
|
35
46
|
- lib/nexpose.rb
|
|
36
|
-
- lib/options.rb
|
|
37
47
|
- lib/test.rb
|
|
48
|
+
- lib/options.rb
|
|
38
49
|
- bin/silo_manager
|
|
39
50
|
has_rdoc: true
|
|
40
|
-
homepage: https://github.com/chrlee/
|
|
51
|
+
homepage: https://github.com/chrlee/Nexpose_silo_manager
|
|
41
52
|
licenses: []
|
|
53
|
+
|
|
42
54
|
post_install_message:
|
|
43
55
|
rdoc_options: []
|
|
44
|
-
|
|
56
|
+
|
|
57
|
+
require_paths:
|
|
45
58
|
- lib
|
|
46
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
47
60
|
none: false
|
|
48
|
-
requirements:
|
|
49
|
-
- -
|
|
50
|
-
- !ruby/object:Gem::Version
|
|
51
|
-
|
|
52
|
-
|
|
61
|
+
requirements:
|
|
62
|
+
- - ">="
|
|
63
|
+
- !ruby/object:Gem::Version
|
|
64
|
+
hash: 3
|
|
65
|
+
segments:
|
|
66
|
+
- 0
|
|
67
|
+
version: "0"
|
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
53
69
|
none: false
|
|
54
|
-
requirements:
|
|
55
|
-
- -
|
|
56
|
-
- !ruby/object:Gem::Version
|
|
57
|
-
|
|
70
|
+
requirements:
|
|
71
|
+
- - ">="
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
hash: 3
|
|
74
|
+
segments:
|
|
75
|
+
- 0
|
|
76
|
+
version: "0"
|
|
58
77
|
requirements: []
|
|
78
|
+
|
|
59
79
|
rubyforge_project:
|
|
60
|
-
rubygems_version: 1.
|
|
80
|
+
rubygems_version: 1.3.7
|
|
61
81
|
signing_key:
|
|
62
82
|
specification_version: 3
|
|
63
83
|
summary: This is a tool is used to provide CRUD silo operations.
|
|
64
84
|
test_files: []
|
|
85
|
+
|