spectre-core 1.8.0 → 1.9.0
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/exe/spectre +43 -19
- data/lib/spectre.rb +1 -1
- data/lib/spectre/curl.rb +2 -2
- data/lib/spectre/helpers.rb +17 -7
- data/lib/spectre/http.rb +38 -22
- data/lib/spectre/http/basic_auth.rb +2 -2
- data/lib/spectre/http/keystone.rb +3 -3
- data/lib/spectre/logger/console.rb +1 -1
- data/lib/spectre/logger/file.rb +1 -1
- data/lib/spectre/mixin.rb +2 -2
- data/lib/spectre/resources.rb +2 -2
- metadata +14 -74
- data/lib/spectre/database/postgres.rb +0 -78
- data/lib/spectre/ftp.rb +0 -195
- data/lib/spectre/mysql.rb +0 -97
- data/lib/spectre/ssh.rb +0 -149
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4b3c5faed7a6a34d2c9fe9e2c3b637ce8cc818e8ea597649e7b1c386dd444fde
|
4
|
+
data.tar.gz: 330492cacaad784dea242b35bd539a75660268022485afde75e47cdc99d374a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 02b2682ae4911e462be2c9e48622c0dca079916719a9b2ce519bae1d7945290a989572e16c8c21768201f811177ef5580d3077f2a0f50ce0225639a93c1c1b9a
|
7
|
+
data.tar.gz: 140ebcba6bbbd1056510bd8c231fe16b0e63a6d0a4209abb69701fdfc9d99b2a2655742e334880e31e3fbda55cf0a434d2dee1290a95a7513a5a64699bb5a288
|
data/exe/spectre
CHANGED
@@ -48,6 +48,7 @@ DEFAULT_CONFIG = {
|
|
48
48
|
},
|
49
49
|
'debug' => false,
|
50
50
|
'out_path' => './reports',
|
51
|
+
'secure_keys' => ['password', 'secret', 'token', 'secure', 'authorization'],
|
51
52
|
'spec_patterns' => ['./specs/**/*.spec.rb'],
|
52
53
|
'mixin_patterns' => ['../common/mixins/**/*.mixin.rb', './mixins/**/*.mixin.rb'],
|
53
54
|
'env_patterns' => ['./environments/**/*.env.yml'],
|
@@ -68,10 +69,6 @@ DEFAULT_CONFIG = {
|
|
68
69
|
'spectre/http/basic_auth',
|
69
70
|
'spectre/http/keystone',
|
70
71
|
'spectre/resources',
|
71
|
-
'spectre/ssh',
|
72
|
-
'spectre/ftp',
|
73
|
-
'spectre/mysql',
|
74
|
-
# 'spectre/postgres',
|
75
72
|
],
|
76
73
|
'include' => [
|
77
74
|
|
@@ -102,7 +99,7 @@ Specific options:}
|
|
102
99
|
cmd_options['specs'] = specs
|
103
100
|
end
|
104
101
|
|
105
|
-
opts.on('-t TAG,TAG', '--tags TAG,TAG', Array, 'Run only specs with
|
102
|
+
opts.on('-t TAG,TAG', '--tags TAG,TAG', Array, 'Run only specs with given tags') do |tags|
|
106
103
|
cmd_options['tags'] = tags
|
107
104
|
end
|
108
105
|
|
@@ -126,12 +123,16 @@ Specific options:}
|
|
126
123
|
cmd_options['colored'] = false
|
127
124
|
end
|
128
125
|
|
126
|
+
opts.on('--ignore-failure', 'Always exit with code 0') do
|
127
|
+
cmd_options['ignore_failure'] = true
|
128
|
+
end
|
129
|
+
|
129
130
|
opts.on('-o PATH', '--out PATH', 'Output directory path') do |path|
|
130
|
-
cmd_options['out_path'] = path
|
131
|
+
cmd_options['out_path'] = File.absolute_path(path)
|
131
132
|
end
|
132
133
|
|
133
|
-
opts.on('-r NAME', '--
|
134
|
-
cmd_options['
|
134
|
+
opts.on('-r NAME', '--reporters NAME', Array, "A list of reporters to use") do |reporters|
|
135
|
+
cmd_options['reporters'] = reporters
|
135
136
|
end
|
136
137
|
|
137
138
|
opts.on('-d', '--debug', "Run in debug mode") do
|
@@ -147,7 +148,7 @@ Specific options:}
|
|
147
148
|
|
148
149
|
curr_opt = cmd_options
|
149
150
|
(key.split '.').each do |k|
|
150
|
-
curr_opt[k] = {} if not curr_opt.
|
151
|
+
curr_opt[k] = {} if not curr_opt.key? k
|
151
152
|
end
|
152
153
|
curr_opt = val
|
153
154
|
|
@@ -205,10 +206,11 @@ envs = {}
|
|
205
206
|
read_env_files = {}
|
206
207
|
cfg['env_patterns'].each do |pattern|
|
207
208
|
Dir.glob(pattern).each do|f|
|
208
|
-
spec_env = YAML.load_file(f)
|
209
|
-
name = spec_env.delete('name') || 'default'
|
209
|
+
spec_env = YAML.load_file(f) || {}
|
210
210
|
|
211
|
-
|
211
|
+
name = spec_env['name'] || 'default'
|
212
|
+
|
213
|
+
if envs.key? name
|
212
214
|
existing_env_file = read_env_files[name]
|
213
215
|
puts "Duplicate environment definition detected with name #{name} in '#{f}'. Previously defined in '#{existing_env_file}'"
|
214
216
|
exit 1
|
@@ -224,7 +226,7 @@ cfg['env_partial_patterns'].each do |pattern|
|
|
224
226
|
Dir.glob(pattern).each do|f|
|
225
227
|
partial_env = YAML.load_file(f)
|
226
228
|
name = partial_env.delete('name') || 'default'
|
227
|
-
next if not envs.
|
229
|
+
next if not envs.key? name
|
228
230
|
|
229
231
|
envs[name].deep_merge! partial_env
|
230
232
|
end
|
@@ -295,7 +297,7 @@ if action == 'run'
|
|
295
297
|
})
|
296
298
|
|
297
299
|
log_dir = File.dirname cfg['log_file']
|
298
|
-
|
300
|
+
FileUtils.makedirs log_dir if !Dir.exists? log_dir
|
299
301
|
|
300
302
|
# Load Modules
|
301
303
|
cfg['modules']
|
@@ -303,12 +305,19 @@ if action == 'run'
|
|
303
305
|
.select { |mod| !cfg['exclude'].include? mod }
|
304
306
|
.each do |mod|
|
305
307
|
begin
|
306
|
-
|
307
|
-
|
308
|
-
|
308
|
+
spectre_lib_mod = File.join('../lib', mod)
|
309
|
+
|
310
|
+
if File.exists? mod
|
309
311
|
require_relative mod
|
312
|
+
|
313
|
+
elsif File.exists? spectre_lib_mod
|
314
|
+
require_relative spectre_lib_mod
|
315
|
+
|
316
|
+
else
|
317
|
+
require mod
|
310
318
|
end
|
311
|
-
|
319
|
+
|
320
|
+
rescue LoadError => e
|
312
321
|
puts "Unable to load module #{mod}. Check if the module exists or remove it from your spectre config:\n#{e.message}"
|
313
322
|
exit 1
|
314
323
|
end
|
@@ -337,7 +346,11 @@ if action == 'run'
|
|
337
346
|
reporter.report(run_infos)
|
338
347
|
end
|
339
348
|
|
340
|
-
|
349
|
+
errors = run_infos.select { |x| x.error != nil or x.failure != nil }
|
350
|
+
|
351
|
+
exit 0 if cfg['ignore_failure'] or errors.count == 0
|
352
|
+
|
353
|
+
exit 1
|
341
354
|
end
|
342
355
|
|
343
356
|
|
@@ -464,6 +477,16 @@ reports/
|
|
464
477
|
**/environments/*.env.secret.yml
|
465
478
|
]
|
466
479
|
|
480
|
+
DEFAULT_GEMFILE = %[source 'https://rubygems.org'
|
481
|
+
|
482
|
+
gem 'spectre-core', '>= #{Spectre::VERSION}'
|
483
|
+
# gem 'spectre-mysql', '>= 1.0.0'
|
484
|
+
# gem 'spectre-ssh', '>= 1.0.0'
|
485
|
+
# gem 'spectre-ftp', '>= 1.0.0'
|
486
|
+
# gem 'spectre-curl', '>= 1.0.0'
|
487
|
+
# gem 'spectre-git', '>= 0.1.0'
|
488
|
+
]
|
489
|
+
|
467
490
|
if action == 'init'
|
468
491
|
DEFAULT_FILES = [
|
469
492
|
['./environments/default.env.yml', DEFAULT_ENV_CFG],
|
@@ -471,6 +494,7 @@ if action == 'init'
|
|
471
494
|
['./specs/sample.spec.rb', SAMPLE_SPEC],
|
472
495
|
['./spectre.yml', DEFAULT_SPECTRE_CFG],
|
473
496
|
['./.gitignore', DEFAULT_GITIGNORE],
|
497
|
+
['./Gemfile', DEFAULT_GEMFILE],
|
474
498
|
]
|
475
499
|
|
476
500
|
%w(environments logs specs).each do |dir_name|
|
data/lib/spectre.rb
CHANGED
data/lib/spectre/curl.rb
CHANGED
@@ -159,7 +159,7 @@ module Spectre::Curl
|
|
159
159
|
'use_ssl' => secure,
|
160
160
|
}
|
161
161
|
|
162
|
-
if @@http_cfg.
|
162
|
+
if @@http_cfg.key? name
|
163
163
|
req.merge! @@http_cfg[name]
|
164
164
|
raise "No `base_url' set for HTTP client '#{name}'. Check your HTTP config in your environment." if !req['base_url']
|
165
165
|
else
|
@@ -355,7 +355,7 @@ module Spectre::Curl
|
|
355
355
|
|
356
356
|
@@curl_path = config['curl_path'] || 'curl'
|
357
357
|
|
358
|
-
if config.
|
358
|
+
if config.key? 'http'
|
359
359
|
@@http_cfg = {}
|
360
360
|
|
361
361
|
config['http'].each do |name, cfg|
|
data/lib/spectre/helpers.rb
CHANGED
@@ -17,12 +17,22 @@ class ::String
|
|
17
17
|
file_content = File.read(self)
|
18
18
|
|
19
19
|
if with
|
20
|
-
with
|
21
|
-
|
22
|
-
|
20
|
+
file_content.with(with)
|
21
|
+
else
|
22
|
+
file_content
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def with mapping
|
27
|
+
return self unless mapping and mapping.is_a? Hash
|
28
|
+
|
29
|
+
new_string = self
|
30
|
+
|
31
|
+
mapping.each do |key, value|
|
32
|
+
new_string = new_string.gsub '#{' + key.to_s + '}', value.to_s
|
23
33
|
end
|
24
34
|
|
25
|
-
|
35
|
+
new_string
|
26
36
|
end
|
27
37
|
|
28
38
|
def exists?
|
@@ -35,9 +45,9 @@ class ::String
|
|
35
45
|
File.delete self
|
36
46
|
end
|
37
47
|
|
38
|
-
def trim count=50
|
48
|
+
def trim count = 50
|
39
49
|
if (self.length + 3) > count
|
40
|
-
return self[0..count] + '...'
|
50
|
+
return self[0..count-4] + '...'
|
41
51
|
end
|
42
52
|
|
43
53
|
self
|
@@ -60,5 +70,5 @@ end
|
|
60
70
|
|
61
71
|
|
62
72
|
def uuid length = 5
|
63
|
-
SecureRandom.uuid().gsub('-', '')[0..length]
|
73
|
+
SecureRandom.uuid().gsub('-', '')[0..length-1]
|
64
74
|
end
|
data/lib/spectre/http.rb
CHANGED
@@ -62,8 +62,7 @@ module Spectre
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def body body_content
|
65
|
-
|
66
|
-
@__req['body'] = body_content
|
65
|
+
@__req['body'] = body_content.to_s
|
67
66
|
end
|
68
67
|
|
69
68
|
def ensure_success!
|
@@ -102,6 +101,7 @@ module Spectre
|
|
102
101
|
end
|
103
102
|
|
104
103
|
def [] key
|
104
|
+
return nil if not @headers.has_key?(key.downcase)
|
105
105
|
@headers[key.downcase].first
|
106
106
|
end
|
107
107
|
|
@@ -166,6 +166,7 @@ module Spectre
|
|
166
166
|
@@response = nil
|
167
167
|
@@request = nil
|
168
168
|
@@modules = []
|
169
|
+
@@secure_keys = []
|
169
170
|
|
170
171
|
def https name, &block
|
171
172
|
http(name, secure: true, &block)
|
@@ -174,7 +175,7 @@ module Spectre
|
|
174
175
|
def http name, secure: nil, &block
|
175
176
|
req = {}
|
176
177
|
|
177
|
-
if @@http_cfg.
|
178
|
+
if @@http_cfg.key? name
|
178
179
|
req.merge! @@http_cfg[name]
|
179
180
|
raise "No `base_url' set for HTTP client '#{name}'. Check your HTTP config in your environment." if !req['base_url']
|
180
181
|
else
|
@@ -209,20 +210,35 @@ module Spectre
|
|
209
210
|
return str unless str or str.empty?
|
210
211
|
|
211
212
|
begin
|
212
|
-
json = JSON.parse
|
213
|
+
json = JSON.parse(str)
|
214
|
+
json.obfuscate!(@@secure_keys) if not @@debug
|
213
215
|
|
214
216
|
if pretty
|
215
217
|
str = JSON.pretty_generate(json)
|
216
218
|
else
|
217
219
|
str = JSON.dump(json)
|
218
220
|
end
|
219
|
-
rescue
|
220
|
-
|
221
|
+
# rescue => e
|
222
|
+
# # do nothing
|
223
|
+
# @@logger.error(e)
|
221
224
|
end
|
222
225
|
|
223
226
|
str
|
224
227
|
end
|
225
228
|
|
229
|
+
def is_secure? key
|
230
|
+
@@secure_keys.any? { |x| key.to_s.downcase.include? x.downcase }
|
231
|
+
end
|
232
|
+
|
233
|
+
def header_to_s headers
|
234
|
+
s = ''
|
235
|
+
headers.each_header.each do |header, value|
|
236
|
+
value = '*****' if is_secure?(header) and not @@debug
|
237
|
+
s += "#{header.to_s.ljust(30, '.')}: #{value.to_s}\n"
|
238
|
+
end
|
239
|
+
s
|
240
|
+
end
|
241
|
+
|
226
242
|
def invoke req
|
227
243
|
@@request = nil
|
228
244
|
|
@@ -254,7 +270,7 @@ module Spectre
|
|
254
270
|
if uri.scheme == 'https'
|
255
271
|
net_http.use_ssl = true
|
256
272
|
|
257
|
-
if req.
|
273
|
+
if req.key? 'cert'
|
258
274
|
raise "Certificate '#{req['cert']}' does not exist" unless File.exists? req['cert']
|
259
275
|
net_http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
260
276
|
net_http.ca_file = req['cert']
|
@@ -275,28 +291,28 @@ module Spectre
|
|
275
291
|
|
276
292
|
req_id = SecureRandom.uuid()[0..5]
|
277
293
|
|
294
|
+
# Run HTTP modules
|
295
|
+
|
296
|
+
@@modules.each do |mod|
|
297
|
+
mod.on_req(net_http, net_req, req) if mod.respond_to? :on_req
|
298
|
+
end
|
299
|
+
|
278
300
|
# Log request
|
279
301
|
|
280
|
-
req_log = "[>] #{req_id} #{req['method']} #{uri}"
|
281
|
-
|
282
|
-
|
283
|
-
end if req['headers']
|
284
|
-
req_log += "\n" + try_format_json(req['body'], pretty: true) if req['body'] != nil and not req['body'].empty?
|
302
|
+
req_log = "[>] #{req_id} #{req['method']} #{uri}\n"
|
303
|
+
req_log += header_to_s(net_req)
|
304
|
+
req_log += try_format_json(req['body'], pretty: true) if req['body'] != nil and not req['body'].empty?
|
285
305
|
|
286
306
|
@@logger.info req_log
|
287
307
|
|
288
308
|
# Request
|
289
309
|
|
290
310
|
start_time = Time.now
|
291
|
-
|
292
|
-
@@modules.each do |mod|
|
293
|
-
mod.on_req(net_http, net_req, req) if mod.respond_to? :on_req
|
294
|
-
end
|
295
|
-
|
296
311
|
net_res = net_http.request(net_req)
|
297
|
-
|
298
312
|
end_time = Time.now
|
299
313
|
|
314
|
+
# Run HTTP modules
|
315
|
+
|
300
316
|
@@modules.each do |mod|
|
301
317
|
mod.on_res(net_http, net_res, req) if mod.respond_to? :on_res
|
302
318
|
end
|
@@ -304,9 +320,7 @@ module Spectre
|
|
304
320
|
# Log response
|
305
321
|
|
306
322
|
res_log = "[<] #{req_id} #{net_res.code} #{net_res.message} (#{end_time - start_time}s)\n"
|
307
|
-
|
308
|
-
res_log += "#{header.to_s.ljust(30, '.')}: #{value}\n"
|
309
|
-
end
|
323
|
+
res_log += header_to_s(net_res)
|
310
324
|
res_log += try_format_json(net_res.body, pretty: true) if net_res.body != nil and !net_res.body.empty?
|
311
325
|
|
312
326
|
@@logger.info(res_log)
|
@@ -328,8 +342,10 @@ module Spectre
|
|
328
342
|
|
329
343
|
Spectre.register do |config|
|
330
344
|
@@logger = ::Logger.new config['log_file'], progname: 'spectre/http'
|
345
|
+
@@secure_keys = config['secure_keys'] || []
|
346
|
+
@@debug = config['debug']
|
331
347
|
|
332
|
-
if config.
|
348
|
+
if config.key? 'http'
|
333
349
|
@@http_cfg = {}
|
334
350
|
|
335
351
|
config['http'].each do |name, cfg|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Spectre::Http
|
2
2
|
class SpectreHttpRequest
|
3
3
|
def basic_auth username, password
|
4
|
-
@__req['basic_auth'] = {} if not @__req.
|
4
|
+
@__req['basic_auth'] = {} if not @__req.key? 'basic_auth'
|
5
5
|
|
6
6
|
@__req['basic_auth']['username'] = username
|
7
7
|
@__req['basic_auth']['password'] = password
|
@@ -12,7 +12,7 @@ module Spectre::Http
|
|
12
12
|
|
13
13
|
module BasicAuth
|
14
14
|
def self.on_req http, net_req, req
|
15
|
-
return unless req.
|
15
|
+
return unless req.key? 'basic_auth' and req['auth'] == 'basic_auth'
|
16
16
|
basic_auth_cfg = req['basic_auth']
|
17
17
|
net_req.basic_auth(basic_auth_cfg['username'], basic_auth_cfg['password'])
|
18
18
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class HttpRequest
|
2
2
|
def keystone url, username, password, project, domain, cert
|
3
|
-
@__req['keystone'] = {} if not @__req.
|
3
|
+
@__req['keystone'] = {} if not @__req.key? 'keystone'
|
4
4
|
|
5
5
|
@__req['keystone']['url'] = url
|
6
6
|
@__req['keystone']['username'] = username
|
@@ -18,11 +18,11 @@ module Spectre::Http::Keystone
|
|
18
18
|
@@cache = {}
|
19
19
|
|
20
20
|
def self.on_req http, net_req, req
|
21
|
-
return unless req.
|
21
|
+
return unless req.key? 'keystone' and req['auth'] == 'keystone'
|
22
22
|
|
23
23
|
keystone_cfg = req['keystone']
|
24
24
|
|
25
|
-
if @@cache.
|
25
|
+
if @@cache.key? keystone_cfg
|
26
26
|
token = @@cache[keystone_cfg]
|
27
27
|
else
|
28
28
|
token, _ = authenticate(
|
@@ -4,7 +4,7 @@ module Spectre
|
|
4
4
|
module Logger
|
5
5
|
class Console
|
6
6
|
def initialize config
|
7
|
-
raise 'No log format section in config for console logger' unless config.
|
7
|
+
raise 'No log format section in config for console logger' unless config.key? 'log_format' and config['log_format'].key? 'console'
|
8
8
|
|
9
9
|
@config = config['log_format']['console']
|
10
10
|
@indent = @config['indent'] || 2
|
data/lib/spectre/logger/file.rb
CHANGED
@@ -2,7 +2,7 @@ module Spectre
|
|
2
2
|
module Logger
|
3
3
|
class File
|
4
4
|
def initialize config
|
5
|
-
raise 'No log format section in config for console logger' unless config.
|
5
|
+
raise 'No log format section in config for console logger' unless config.key? 'log_format' and config['log_format'].key? 'file'
|
6
6
|
|
7
7
|
@config = config['log_format']['file']
|
8
8
|
@fmt_start_group = @config['start_group']
|
data/lib/spectre/mixin.rb
CHANGED
@@ -10,7 +10,7 @@ module Spectre
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def run desc, with: []
|
13
|
-
raise "no mixin with desc '#{desc}' defined" unless @@mixins.
|
13
|
+
raise "no mixin with desc '#{desc}' defined" unless @@mixins.key? desc
|
14
14
|
Logger.log_debug "running mixin '#{desc}'"
|
15
15
|
|
16
16
|
if with.is_a? Array
|
@@ -25,7 +25,7 @@ module Spectre
|
|
25
25
|
end
|
26
26
|
|
27
27
|
Spectre.register do |config|
|
28
|
-
if not config.
|
28
|
+
if not config.key? 'mixin_patterns'
|
29
29
|
return
|
30
30
|
end
|
31
31
|
|
data/lib/spectre/resources.rb
CHANGED
@@ -12,7 +12,7 @@ module Spectre
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def [] name
|
15
|
-
raise "Resource with name '#{name}' does not exist" if not @items.
|
15
|
+
raise "Resource with name '#{name}' does not exist" if not @items.key? name
|
16
16
|
@items[name]
|
17
17
|
end
|
18
18
|
end
|
@@ -26,7 +26,7 @@ module Spectre
|
|
26
26
|
end
|
27
27
|
|
28
28
|
Spectre.register do |config|
|
29
|
-
return if !config.
|
29
|
+
return if !config.key? 'resource_paths'
|
30
30
|
|
31
31
|
config['resource_paths'].each do |resource_path|
|
32
32
|
resource_files = Dir.glob File.join(resource_path, '**/*')
|
metadata
CHANGED
@@ -1,85 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spectre-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Christian Neubauer
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-07-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ectoplasm
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.
|
19
|
+
version: 1.2.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: openssl
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 2.2.0
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: 2.2.0
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: net-ssh
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: 6.1.0
|
48
|
-
type: :runtime
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: 6.1.0
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: net-sftp
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: 3.0.0
|
62
|
-
type: :runtime
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: 3.0.0
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: mysql2
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - "~>"
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: 0.5.3
|
76
|
-
type: :runtime
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - "~>"
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: 0.5.3
|
26
|
+
version: 1.2.0
|
83
27
|
description: A DSL and command line tool to describe and run automated tests
|
84
28
|
email:
|
85
29
|
- me@christianneubauer.de
|
@@ -93,10 +37,8 @@ files:
|
|
93
37
|
- lib/spectre/assertion.rb
|
94
38
|
- lib/spectre/bag.rb
|
95
39
|
- lib/spectre/curl.rb
|
96
|
-
- lib/spectre/database/postgres.rb
|
97
40
|
- lib/spectre/diagnostic.rb
|
98
41
|
- lib/spectre/environment.rb
|
99
|
-
- lib/spectre/ftp.rb
|
100
42
|
- lib/spectre/helpers.rb
|
101
43
|
- lib/spectre/http.rb
|
102
44
|
- lib/spectre/http/basic_auth.rb
|
@@ -105,20 +47,18 @@ files:
|
|
105
47
|
- lib/spectre/logger/console.rb
|
106
48
|
- lib/spectre/logger/file.rb
|
107
49
|
- lib/spectre/mixin.rb
|
108
|
-
- lib/spectre/mysql.rb
|
109
50
|
- lib/spectre/reporter/console.rb
|
110
51
|
- lib/spectre/reporter/junit.rb
|
111
52
|
- lib/spectre/resources.rb
|
112
|
-
|
113
|
-
homepage: https://bitbucket.org/cneubaur/spectre-core
|
53
|
+
homepage: https://github.com/cneubauer/spectre-core
|
114
54
|
licenses:
|
115
55
|
- MIT
|
116
56
|
metadata:
|
117
57
|
allowed_push_host: https://rubygems.org/
|
118
|
-
homepage_uri: https://
|
119
|
-
source_code_uri: https://
|
120
|
-
changelog_uri: https://
|
121
|
-
post_install_message:
|
58
|
+
homepage_uri: https://github.com/cneubauer/spectre-core
|
59
|
+
source_code_uri: https://github.com/cneubauer/spectre-core
|
60
|
+
changelog_uri: https://github.com/cneubauer/spectre-core/blob/master/CHANGELOG.md
|
61
|
+
post_install_message:
|
122
62
|
rdoc_options: []
|
123
63
|
require_paths:
|
124
64
|
- lib
|
@@ -133,8 +73,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
133
73
|
- !ruby/object:Gem::Version
|
134
74
|
version: '0'
|
135
75
|
requirements: []
|
136
|
-
rubygems_version: 3.
|
137
|
-
signing_key:
|
76
|
+
rubygems_version: 3.0.8
|
77
|
+
signing_key:
|
138
78
|
specification_version: 4
|
139
79
|
summary: Describe and run automated tests
|
140
80
|
test_files: []
|
@@ -1,78 +0,0 @@
|
|
1
|
-
require 'pg'
|
2
|
-
|
3
|
-
|
4
|
-
class PG::Result
|
5
|
-
alias :count :ntuples
|
6
|
-
end
|
7
|
-
|
8
|
-
|
9
|
-
module Spectre
|
10
|
-
module Database
|
11
|
-
module Postgres
|
12
|
-
@@modules = []
|
13
|
-
|
14
|
-
class SQLStatement
|
15
|
-
attr_accessor :query, :params
|
16
|
-
|
17
|
-
def initialize
|
18
|
-
@query = nil
|
19
|
-
@params = []
|
20
|
-
end
|
21
|
-
|
22
|
-
def statement query
|
23
|
-
@query = query
|
24
|
-
end
|
25
|
-
|
26
|
-
def param val
|
27
|
-
@params << val
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
|
32
|
-
class << self
|
33
|
-
def postgres name, &block
|
34
|
-
raise "postgres '#{name}' not configured" unless @@db_cfg.has_key? name
|
35
|
-
|
36
|
-
statement = SQLStatement.new
|
37
|
-
statement.instance_eval &block
|
38
|
-
|
39
|
-
cfg = @@db_cfg[name]
|
40
|
-
|
41
|
-
begin
|
42
|
-
con = PG.connect({
|
43
|
-
host: cfg['host'],
|
44
|
-
port: cfg['port'],
|
45
|
-
dbname: cfg['database'],
|
46
|
-
user: cfg['username'],
|
47
|
-
password: cfg['username'],
|
48
|
-
})
|
49
|
-
|
50
|
-
if statement.params
|
51
|
-
@@result = con.exec_params(statement.query, statement.params)
|
52
|
-
else
|
53
|
-
@@result = con.exec(statement.query)
|
54
|
-
end
|
55
|
-
|
56
|
-
ensure
|
57
|
-
con.close if con
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
|
62
|
-
def result
|
63
|
-
@@result
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
Spectre.register do |config|
|
68
|
-
@@db_cfg = {}
|
69
|
-
|
70
|
-
config['postgres'].each do |name, cfg|
|
71
|
-
@@db_cfg[name] = cfg
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
Spectre.delegate :postgres, :result, to: self
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
data/lib/spectre/ftp.rb
DELETED
@@ -1,195 +0,0 @@
|
|
1
|
-
require 'net/ftp'
|
2
|
-
require 'net/sftp'
|
3
|
-
require 'logger'
|
4
|
-
require 'json'
|
5
|
-
|
6
|
-
|
7
|
-
module Spectre
|
8
|
-
module FTP
|
9
|
-
@@cfg = {}
|
10
|
-
|
11
|
-
class FTPConnection < DslClass
|
12
|
-
def initialize host, username, password, opts, logger
|
13
|
-
@__logger = logger
|
14
|
-
@__session = nil
|
15
|
-
|
16
|
-
@__host = host
|
17
|
-
@__username = username
|
18
|
-
@__password = password
|
19
|
-
@__opts = opts
|
20
|
-
end
|
21
|
-
|
22
|
-
def connect!
|
23
|
-
return unless @__session == nil or @__session.closed?
|
24
|
-
@__logger.info "Connecting to '#{@__host}' with user '#{@__username}'"
|
25
|
-
@__session = Net::FTP.new(@__host, @__opts)
|
26
|
-
@__session.login @__username, @__password
|
27
|
-
end
|
28
|
-
|
29
|
-
def close
|
30
|
-
return unless @__session and not @__session.closed?
|
31
|
-
@__session.close
|
32
|
-
end
|
33
|
-
|
34
|
-
def can_connect?
|
35
|
-
begin
|
36
|
-
connect!
|
37
|
-
return true
|
38
|
-
rescue
|
39
|
-
return false
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def download remotefile, to: File.basename(remotefile)
|
44
|
-
connect!
|
45
|
-
@__logger.info "Downloading '#{@__username}@#{@__host}:#{File.join @__session.pwd, remotefile}' to '#{File.expand_path to}'"
|
46
|
-
@__session.getbinaryfile(remotefile, to)
|
47
|
-
end
|
48
|
-
|
49
|
-
def upload localfile, to: File.basename(localfile)
|
50
|
-
connect!
|
51
|
-
@__logger.info "Uploading '#{File.expand_path localfile}' to '#{@__username}@#{@__host}:#{File.join @__session.pwd, to}'"
|
52
|
-
@__session.putbinaryfile(localfile, to)
|
53
|
-
end
|
54
|
-
|
55
|
-
def list
|
56
|
-
connect!
|
57
|
-
file_list = @__session.list
|
58
|
-
@__logger.info "Listing file in #{@__session.pwd}\n#{file_list}"
|
59
|
-
file_list
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
|
64
|
-
class SFTPConnection < DslClass
|
65
|
-
def initialize host, username, opts, logger
|
66
|
-
opts[:non_interactive] = true
|
67
|
-
|
68
|
-
@__logger = logger
|
69
|
-
@__session = nil
|
70
|
-
@__host = host
|
71
|
-
@__username = username
|
72
|
-
@__opts = opts
|
73
|
-
end
|
74
|
-
|
75
|
-
def connect!
|
76
|
-
return unless @__session == nil or @__session.closed?
|
77
|
-
@__logger.info "Connecting to '#{@__host}' with user '#{@__username}'"
|
78
|
-
@__session = Net::SFTP.start(@__host, @__username, @__opts)
|
79
|
-
@__session.connect!
|
80
|
-
end
|
81
|
-
|
82
|
-
def close
|
83
|
-
return unless @__session and not @__session.closed?
|
84
|
-
# @__session.close!
|
85
|
-
end
|
86
|
-
|
87
|
-
def can_connect?
|
88
|
-
begin
|
89
|
-
connect!
|
90
|
-
return true
|
91
|
-
rescue
|
92
|
-
return false
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def download remotefile, to: File.basename(remotefile)
|
97
|
-
@__logger.info "Downloading '#{@__username}@#{@__host}:#{remotefile}' to '#{File.expand_path to}'"
|
98
|
-
connect!
|
99
|
-
@__session.download!(remotefile, to)
|
100
|
-
end
|
101
|
-
|
102
|
-
def upload localfile, to: File.basename(localfile)
|
103
|
-
@__logger.info "Uploading '#{File.expand_path localfile}' to '#{@__username}@#{@__host}:#{to}'"
|
104
|
-
connect!
|
105
|
-
@__session.upload!(localfile, to)
|
106
|
-
end
|
107
|
-
|
108
|
-
def stat path
|
109
|
-
connect!
|
110
|
-
file_info = @__session.stat! path
|
111
|
-
@__logger.info "Stat '#{path}'\n#{JSON.pretty_generate file_info.attributes}"
|
112
|
-
file_info.attributes
|
113
|
-
end
|
114
|
-
|
115
|
-
def exists path
|
116
|
-
begin
|
117
|
-
file_info = @__session.stat! path
|
118
|
-
|
119
|
-
rescue Net::SFTP::StatusException => e
|
120
|
-
return false if e.description == 'no such file'
|
121
|
-
raise e
|
122
|
-
end
|
123
|
-
|
124
|
-
return true
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
|
129
|
-
class << self
|
130
|
-
def ftp name, config={}, &block
|
131
|
-
raise "FTP connection '#{name}' not configured" unless @@cfg.has_key?(name) or config.count > 0
|
132
|
-
cfg = @@cfg[name] || {}
|
133
|
-
|
134
|
-
host = config[:host] || cfg['host'] || name
|
135
|
-
username = config[:username] || cfg['username']
|
136
|
-
password = config[:password] || cfg['password']
|
137
|
-
|
138
|
-
opts = {}
|
139
|
-
opts[:ssl] = config[:ssl]
|
140
|
-
opts[:port] = config[:port] || cfg['port'] || 21
|
141
|
-
|
142
|
-
@@logger.info "Connecting to #{host} with user #{username}"
|
143
|
-
|
144
|
-
ftp_conn = FTPConnection.new(host, username, password, opts, @@logger)
|
145
|
-
|
146
|
-
begin
|
147
|
-
ftp_conn.instance_eval &block
|
148
|
-
ensure
|
149
|
-
ftp_conn.close
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
def sftp name, config={}, &block
|
154
|
-
raise "FTP connection '#{name}' not configured" unless @@cfg.has_key?(name) or config.count > 0
|
155
|
-
|
156
|
-
cfg = @@cfg[name] || {}
|
157
|
-
|
158
|
-
host = config[:host] || cfg['host'] || name
|
159
|
-
username = config[:username] || cfg['username']
|
160
|
-
password = config[:password] || cfg['password']
|
161
|
-
|
162
|
-
opts = {}
|
163
|
-
opts[:password] = password
|
164
|
-
opts[:port] = config[:port] || cfg['port'] || 22
|
165
|
-
opts[:keys] = [cfg['key']] if cfg.has_key? 'key'
|
166
|
-
opts[:passphrase] = cfg['passphrase'] if cfg.has_key? 'passphrase'
|
167
|
-
|
168
|
-
opts[:auth_methods] = []
|
169
|
-
opts[:auth_methods].push 'publickey' if opts[:keys]
|
170
|
-
opts[:auth_methods].push 'password' if opts[:password]
|
171
|
-
|
172
|
-
sftp_con = SFTPConnection.new(host, username, opts, @@logger)
|
173
|
-
|
174
|
-
begin
|
175
|
-
sftp_con.instance_eval &block
|
176
|
-
ensure
|
177
|
-
sftp_con.close
|
178
|
-
end
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
Spectre.register do |config|
|
183
|
-
@@logger = ::Logger.new config['log_file'], progname: 'spectre/ftp'
|
184
|
-
|
185
|
-
if config.has_key? 'ftp'
|
186
|
-
|
187
|
-
config['ftp'].each do |name, cfg|
|
188
|
-
@@cfg[name] = cfg
|
189
|
-
end
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
Spectre.delegate :ftp, :sftp, to: self
|
194
|
-
end
|
195
|
-
end
|
data/lib/spectre/mysql.rb
DELETED
@@ -1,97 +0,0 @@
|
|
1
|
-
require 'mysql2'
|
2
|
-
|
3
|
-
module Spectre
|
4
|
-
module MySQL
|
5
|
-
|
6
|
-
class MySqlQuery < DslClass
|
7
|
-
def initialize query
|
8
|
-
@__query = query
|
9
|
-
end
|
10
|
-
|
11
|
-
def host hostname
|
12
|
-
@__query['host'] = hostname
|
13
|
-
end
|
14
|
-
|
15
|
-
def username user
|
16
|
-
@__query['username'] = user
|
17
|
-
end
|
18
|
-
|
19
|
-
def password pass
|
20
|
-
@__query['password'] = pass
|
21
|
-
end
|
22
|
-
|
23
|
-
def database name
|
24
|
-
@__query['database'] = name
|
25
|
-
end
|
26
|
-
|
27
|
-
def query statement
|
28
|
-
@__query['query'] = [] if not @__query.has_key? 'query'
|
29
|
-
@__query['query'].append(statement)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
class << self
|
34
|
-
@@mysql_cfg = {}
|
35
|
-
@@result = nil
|
36
|
-
@@last_conn = nil
|
37
|
-
|
38
|
-
def mysql name = nil, &block
|
39
|
-
query = {}
|
40
|
-
|
41
|
-
if name != nil and @@mysql_cfg.has_key? name
|
42
|
-
query.merge! @@mysql_cfg[name]
|
43
|
-
raise "No `host' set for MySQL client '#{name}'. Check your MySQL config in your environment." if !query['host']
|
44
|
-
elsif name != nil
|
45
|
-
query['host'] = name
|
46
|
-
elsif @@last_conn == nil
|
47
|
-
raise 'No name given and there was no previous MySQL connection to use'
|
48
|
-
end
|
49
|
-
|
50
|
-
MySqlQuery.new(query).instance_eval(&block) if block_given?
|
51
|
-
|
52
|
-
if name != nil
|
53
|
-
@@last_conn = {
|
54
|
-
host: query['host'],
|
55
|
-
username: query['username'],
|
56
|
-
password: query['password'],
|
57
|
-
database: query['database']
|
58
|
-
}
|
59
|
-
end
|
60
|
-
|
61
|
-
@@logger.info "Connecting to database #{query['username']}@#{query['host']}:#{query['database']}"
|
62
|
-
|
63
|
-
client = ::Mysql2::Client.new(**@@last_conn)
|
64
|
-
|
65
|
-
res = []
|
66
|
-
|
67
|
-
query['query'].each do |statement|
|
68
|
-
@@logger.info 'Executing statement "' + statement + '"'
|
69
|
-
res = client.query(statement, cast_booleans: true)
|
70
|
-
end if query['query']
|
71
|
-
|
72
|
-
@@result = res.map { |row| OpenStruct.new row } if res
|
73
|
-
|
74
|
-
client.close
|
75
|
-
end
|
76
|
-
|
77
|
-
def result
|
78
|
-
raise 'No MySQL query has been executed yet' unless @@result
|
79
|
-
@@result
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
Spectre.register do |config|
|
84
|
-
@@logger = ::Logger.new config['log_file'], progname: 'spectre/mysql'
|
85
|
-
|
86
|
-
if config.has_key? 'mysql'
|
87
|
-
@@mysql_cfg = {}
|
88
|
-
|
89
|
-
config['mysql'].each do |name, cfg|
|
90
|
-
@@mysql_cfg[name] = cfg
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
Spectre.delegate :mysql, :result, to: self
|
96
|
-
end
|
97
|
-
end
|
data/lib/spectre/ssh.rb
DELETED
@@ -1,149 +0,0 @@
|
|
1
|
-
require 'net/ssh'
|
2
|
-
require 'logger'
|
3
|
-
|
4
|
-
|
5
|
-
module Spectre
|
6
|
-
module SSH
|
7
|
-
@@cfg = {}
|
8
|
-
|
9
|
-
class SSHConnection < DslClass
|
10
|
-
def initialize host, username, opts, logger
|
11
|
-
opts[:non_interactive] = true
|
12
|
-
|
13
|
-
@__logger = logger
|
14
|
-
@__host = host
|
15
|
-
@__username = username
|
16
|
-
@__opts = opts
|
17
|
-
@__session = nil
|
18
|
-
@__exit_code = nil
|
19
|
-
@__output = ''
|
20
|
-
end
|
21
|
-
|
22
|
-
def file_exists path
|
23
|
-
exec "ls #{path}"
|
24
|
-
exit_code == 0
|
25
|
-
end
|
26
|
-
|
27
|
-
def owner_of path
|
28
|
-
exec "stat -c %U #{path}"
|
29
|
-
output.chomp
|
30
|
-
end
|
31
|
-
|
32
|
-
def connect!
|
33
|
-
return unless @__session == nil or @__session.closed?
|
34
|
-
@__session = Net::SSH.start(@__host, @__username, @__opts)
|
35
|
-
end
|
36
|
-
|
37
|
-
def close
|
38
|
-
return unless @__session and not @__session.closed?
|
39
|
-
@__session.close
|
40
|
-
end
|
41
|
-
|
42
|
-
def can_connect?
|
43
|
-
@__output = nil
|
44
|
-
|
45
|
-
begin
|
46
|
-
connect!
|
47
|
-
@__session.open_channel.close
|
48
|
-
@__output = "successfully connected to #{@__host} with user #{@__username}"
|
49
|
-
@__exit_code = 0
|
50
|
-
return true
|
51
|
-
rescue Exception => e
|
52
|
-
@__logger.error e.message
|
53
|
-
@__output = "unable to connect to #{@__host} with user #{@__username}"
|
54
|
-
@__exit_code = 1
|
55
|
-
end
|
56
|
-
|
57
|
-
return false
|
58
|
-
end
|
59
|
-
|
60
|
-
def exec command
|
61
|
-
connect!
|
62
|
-
|
63
|
-
log_str = "#{@__session.options[:user]}@#{@__session.host} -p #{@__session.options[:port]} #{command}"
|
64
|
-
|
65
|
-
@channel = @__session.open_channel do |channel|
|
66
|
-
channel.exec(command) do |ch, success|
|
67
|
-
abort "could not execute #{command} on #{@__session.host}" unless success
|
68
|
-
|
69
|
-
@__output = ''
|
70
|
-
|
71
|
-
channel.on_data do |ch, data|
|
72
|
-
@__output += data
|
73
|
-
end
|
74
|
-
|
75
|
-
channel.on_extended_data do |ch,type,data|
|
76
|
-
@__output += data
|
77
|
-
end
|
78
|
-
|
79
|
-
channel.on_request('exit-status') do |ch, data|
|
80
|
-
@__exit_code = data.read_long
|
81
|
-
end
|
82
|
-
|
83
|
-
# channel.on_request('exit-signal') do |ch, data|
|
84
|
-
# exit_code = data.read_long
|
85
|
-
# end
|
86
|
-
end
|
87
|
-
|
88
|
-
end
|
89
|
-
|
90
|
-
@channel.wait
|
91
|
-
@__session.loop
|
92
|
-
|
93
|
-
log_str += "\n" + @__output
|
94
|
-
@__logger.info log_str
|
95
|
-
end
|
96
|
-
|
97
|
-
def output
|
98
|
-
@__output
|
99
|
-
end
|
100
|
-
|
101
|
-
def exit_code
|
102
|
-
@__exit_code
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
|
107
|
-
class << self
|
108
|
-
def ssh name, config = {}, &block
|
109
|
-
raise "SSH connection '#{name}' not configured" unless @@cfg.has_key?(name) or config.count > 0
|
110
|
-
|
111
|
-
cfg = @@cfg[name] || {}
|
112
|
-
|
113
|
-
host = cfg['host'] || name
|
114
|
-
username = config[:username] || cfg['username']
|
115
|
-
password = config[:password] || cfg['password']
|
116
|
-
|
117
|
-
opts = {}
|
118
|
-
opts[:password] = password
|
119
|
-
opts[:port] = config[:port] || cfg['port'] || 22
|
120
|
-
opts[:keys] = [cfg['key']] if cfg.has_key? 'key'
|
121
|
-
opts[:passphrase] = cfg['passphrase'] if cfg.has_key? 'passphrase'
|
122
|
-
|
123
|
-
opts[:auth_methods] = []
|
124
|
-
opts[:auth_methods].push 'publickey' if opts[:keys]
|
125
|
-
opts[:auth_methods].push 'password' if opts[:password]
|
126
|
-
|
127
|
-
ssh_con = SSHConnection.new(host, username, opts, @@logger)
|
128
|
-
|
129
|
-
begin
|
130
|
-
ssh_con.instance_eval &block
|
131
|
-
ensure
|
132
|
-
ssh_con.close
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
Spectre.register do |config|
|
138
|
-
@@logger = ::Logger.new config['log_file'], progname: 'spectre/ssh'
|
139
|
-
|
140
|
-
if config.has_key? 'ssh'
|
141
|
-
config['ssh'].each do |name, cfg|
|
142
|
-
@@cfg[name] = cfg
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
Spectre.delegate :ssh, to: self
|
148
|
-
end
|
149
|
-
end
|