spectre-core 1.8.4 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7998a15470727e16f944045357a1e089ea6a120bc5c10f8a9986dbb98bf52c54
4
- data.tar.gz: 4c2ad03dfad8712359cf715f86f2eabc81e485c1f57619b8c257930d39d48140
3
+ metadata.gz: 4b3c5faed7a6a34d2c9fe9e2c3b637ce8cc818e8ea597649e7b1c386dd444fde
4
+ data.tar.gz: 330492cacaad784dea242b35bd539a75660268022485afde75e47cdc99d374a7
5
5
  SHA512:
6
- metadata.gz: ef2767b0d3dd65ff86a0925fbe08bd2b93c408f6e808c03f52389ca5eae9b0b324db92e04ce8f26dcef3c84a077b85a4789ea687a774fd49340998016afff3db
7
- data.tar.gz: 61f62091ebbef3ed05b3cdd0aa4ae2a172b31a42dbc97f32eca0736b8ab1928b7d4a04262f793035653c95484aa26ec0cecacdd8a122a750df43fc0ff8e1db7c
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
 
@@ -126,11 +123,15 @@ 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', '--reporter NAME', Array, "A list of reporters to use") do |reporters|
134
+ opts.on('-r NAME', '--reporters NAME', Array, "A list of reporters to use") do |reporters|
134
135
  cmd_options['reporters'] = reporters
135
136
  end
136
137
 
@@ -205,8 +206,9 @@ 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
+
211
+ name = spec_env['name'] || 'default'
210
212
 
211
213
  if envs.key? name
212
214
  existing_env_file = read_env_files[name]
@@ -344,7 +346,11 @@ if action == 'run'
344
346
  reporter.report(run_infos)
345
347
  end
346
348
 
347
- exit 0
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
348
354
  end
349
355
 
350
356
 
@@ -471,6 +477,16 @@ reports/
471
477
  **/environments/*.env.secret.yml
472
478
  ]
473
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
+
474
490
  if action == 'init'
475
491
  DEFAULT_FILES = [
476
492
  ['./environments/default.env.yml', DEFAULT_ENV_CFG],
@@ -478,6 +494,7 @@ if action == 'init'
478
494
  ['./specs/sample.spec.rb', SAMPLE_SPEC],
479
495
  ['./spectre.yml', DEFAULT_SPECTRE_CFG],
480
496
  ['./.gitignore', DEFAULT_GITIGNORE],
497
+ ['./Gemfile', DEFAULT_GEMFILE],
481
498
  ]
482
499
 
483
500
  %w(environments logs specs).each do |dir_name|
data/lib/spectre.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  module Spectre
2
2
  module Version
3
3
  MAJOR = 1
4
- MINOR = 8
5
- TINY = 4
4
+ MINOR = 9
5
+ TINY = 0
6
6
  end
7
7
 
8
8
  VERSION = [Version::MAJOR, Version::MINOR, Version::TINY].compact * '.'
@@ -17,12 +17,22 @@ class ::String
17
17
  file_content = File.read(self)
18
18
 
19
19
  if with
20
- with.each do |key, value|
21
- file_content = file_content.gsub '#{' + key.to_s + '}', value.to_s
22
- end
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
- file_content
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
- raise 'Body value must be a string' if not body_content.is_a? String
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)
@@ -209,20 +210,35 @@ module Spectre
209
210
  return str unless str or str.empty?
210
211
 
211
212
  begin
212
- json = JSON.parse str
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
- # do nothing
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
 
@@ -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
- req['headers'].each do |header|
282
- req_log += "\n#{header[0].to_s.ljust(30, '.')}: #{header[1].to_s}"
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
- net_res.each_header do |header, value|
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,6 +342,8 @@ 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
348
  if config.key? 'http'
333
349
  @@http_cfg = {}
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.8.4
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-06-01 00:00:00.000000000 Z
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.1.0
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.1.0
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
- - lib/spectre/ssh.rb
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://bitbucket.org/cneubaur/spectre-core
119
- source_code_uri: https://bitbucket.org/cneubaur/spectre-core
120
- changelog_uri: https://bitbucket.org/cneubaur/spectre-core/src/master/CHANGELOG.md
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.2.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.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.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.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.key? 'key'
166
- opts[:passphrase] = cfg['passphrase'] if cfg.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.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.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.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.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.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.key? 'key'
121
- opts[:passphrase] = cfg['passphrase'] if cfg.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.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