auger 1.4.5 → 1.4.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 883a8cf1dff3b527ffa8e3b93c2ec3a78bfb2185
4
- data.tar.gz: c8075d2b4e78e760b3ac0db94af1f54f49eaecd8
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZTUwZGFmMzJlMWE1NDQwZGZlOWUyNDZiNDYxNTk1YjU1NzE5ZTViZg==
5
+ data.tar.gz: !binary |-
6
+ MjY3MjQzZmY0ZWY2Y2MyNGRiYTc3MWQ2MTU2ZWVlYWU4NjdjNzIyNw==
5
7
  SHA512:
6
- metadata.gz: b01ffc92070ddfb21a7111888387573166ba2e070ba41fec75ba5699269f652b0d114925f0653b4dfbd9a49b7ca3daabe51e4fb40c6f6ba8db1a6b760f6d95c5
7
- data.tar.gz: 8e7e33c9a3c00d0518a375f84cc03d8a4464348fbffa57aa5f78ab5d55095659073af4e30e5f7831a8df4429f67e5fccdb5ed33a405a083d57b248604044e264
8
+ metadata.gz: !binary |-
9
+ ZGQ3YTQxMjZiMmUwZDZjMzg5OWE3YzE1ZjA3YjllYTUxNGYwNTdmMzc0MDRl
10
+ ZmQzYzYwMGExZDI0ZjNiMGRjM2QwMWI4OWU5NWJmY2Q1MDdkMWZmYWQzNGFm
11
+ NDQ5OGUwMzc0OGIxNGEyN2NjZDM4YjdjYjdiNzYzNmZiNzNmYWU=
12
+ data.tar.gz: !binary |-
13
+ OTA1YWZiNmRiNGM1Yzk1ZDkxYWQ5MGYyNDg3MzdmYTUyZjdiM2VjMDc2ZWJl
14
+ YWU4MjIwNDY2MzY4NTFjNTE3ZDQyNmJjNDc1NTc0OTAxNGFmOTg0YmU5Mjhm
15
+ OTM0YjRiMzNlYjAwNDM0MTE5YmU3NDIwMjE0MDdkNWE4ZjAyNGQ=
data/.gitignore CHANGED
@@ -15,3 +15,5 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ .ruby-gemset
19
+ .ruby-version
data/Gemfile CHANGED
@@ -10,4 +10,5 @@ gem 'net-ssh-gateway'
10
10
 
11
11
  group :development do
12
12
  gem 'gemcutter'
13
+ gem 'pry'
13
14
  end
data/README.md CHANGED
@@ -1,383 +1,2 @@
1
- # Auger
2
-
3
- The Auger library implements a ruby DSL for describing tests to be run
4
- against remote applications on multiple servers. The gem includes
5
- 'aug', a multi-process command-line client.
6
-
7
- The primary goal of Auger is test-driven operations: unit testing for
8
- application admins. The library can also be used as a framework for
9
- implmenting automated tests.
10
-
11
- These are the sorts of questions auger can answer:
12
-
13
- * is port :80 on my application webservers open? does /index.html
14
- contain a response tag that we know should be served from a given
15
- backend data source?
16
-
17
- * is redis running? is it configured as a master? a slave?
18
-
19
- * is elasticsearch responding on all my hosts it should be? what's
20
- the cluster state? do I have the number of data nodes responding
21
- that we're supposed to have?
22
-
23
- Clearly a lot of this information includes things you should be
24
- graphing. What auger wants to do is give you a quick overview
25
- of current status: green == good, red == ruh roh!
26
-
27
- ## What's it look like?
28
-
29
- ![Auger Screenshot](https://raw.github.com/brewster/assets/master/img/auger/cmdline_screenshot.png "Auger Command Line")
30
-
31
-
32
- ## Plugins
33
-
34
- Specific protocols are implemented using plugins, which are designed
35
- to be easy to write wrappers on existing gems. Auger currently includes
36
- the following plugins:
37
-
38
- * socket - test whether a port is open
39
- * telnet - send arbitrary commands to a port using `net/telnet`
40
- * http - http and https requests using `net/http`
41
- * redis - query redis db info, keys, etc
42
- * dns - domain and query requests for testing a DNS server
43
-
44
- ## Installation
45
-
46
- gem install auger
47
-
48
- ### If you want to run the latest source:
49
-
50
- git clone git@github.com/brewster/auger
51
- cd auger; bundle install && rake install
52
-
53
- ## Command-line client usage
54
-
55
- `aug -h` will print usage details.
56
-
57
- Sample configs are included in `auger/cfg/examples` (if installed as a
58
- gem, look in `$GEM_HOME/gems/auger-x.x.x/cfg/examples`). Use them as a
59
- basis to write your own tests, which auger can find in one of three ways:
60
-
61
- * in the directory `auger/cfg`
62
- * from the config load path defined in environment variable `AUGER_CFG`.
63
- e.g. `AUGER_CFG=~/aug_cfg/prod:~/aug_cfg/staging`
64
- * using a relative path
65
-
66
- Reference config files using `aug foo`, to find `foo.rb` in
67
- `auger/cfg` or `AUGER_CFG` path, or `aug path/to/foo.rb` to find it directly.
68
-
69
- `aug -l` will print available config files in `AUGER_CFG` path.
70
-
71
- ### Example 1 - testing a webserver response
72
-
73
- ```ruby
74
- project "Front-end Web Servers" do
75
- server "web-fe-[01-02]"
76
-
77
- http 8000 do
78
- get '/' do
79
- test 'status code is 200' do |response|
80
- response.code == '200'
81
- end
82
- end
83
- end
84
-
85
- end
86
- ```
87
-
88
- The `project` command takes a project description, and a block containing multiple
89
- tests to be run together for that project.
90
-
91
- `server` lists hosts that should be tested. It may be called multiple times, and
92
- also parses host range expressions using the HostRange gem.
93
-
94
- `http` is an example of a connection, it takes an argument with the port to
95
- connect, and a block containing multiple requests to make.
96
-
97
- `get` is a request, in this case an HTTP GET to the provided url, and takes a block
98
- with multiple tests to run on the response. Plugins can return any object from
99
- a request, in the case of `http` the response is an HTTP::Reponse object.
100
-
101
- `test` describes a test to run on the provided response; it takes a description,
102
- and the response is passed to a block. The result of executing the block is
103
- presented as the result of this test (in this case true or false).
104
-
105
- For better control over the result, it is possible to construct and
106
- return an Auger::Result object, with an outcome (string to be
107
- printed) and a boolean status (which aug client will use to print
108
- the result in green or red), for example:
109
-
110
- ```ruby
111
- test 'http status code' do |response|
112
- Result(response.code, response.code == '200')
113
- end
114
- ```
115
-
116
- will always show the code, in green if 200, red otherwise.
117
-
118
- Save the config to a file `fe_web` and run with the `aug` command:
119
-
120
- $ aug ./fe_web
121
- [web-fe-01]
122
- status code is 200 ✓
123
- [web-fe-02]
124
- status code is 200 ✓
125
-
126
- ### Example 2 - adding more tests
127
-
128
- Let's extend our example to be more interesting.
129
-
130
- ```ruby
131
- project "Front-end Web Servers" do
132
- server 'web-fe-[01-02]', :web
133
- server 'www.mydomain.com', :vip, :port => 80
134
-
135
- socket 8000 do
136
- roles :web
137
- open? do
138
- test "port 8000 is open?"
139
- end
140
- end
141
-
142
- http 8000 do
143
- roles :web, :vip
144
-
145
- get '/' do
146
- test 'status code is 200' do |response|
147
- response.code == '200'
148
- end
149
-
150
- test 'document title' do |response|
151
- response.body.match /<title>([\w\s]+)<\/title>/
152
- end
153
- end
154
-
155
- get '/image.png' do
156
- header 'user-agent: Auger Test'
157
-
158
- test 'image.png has correct content-type' do |respose|
159
- response['Content-Type'] == 'image/png'
160
- end
161
- end
162
- end
163
-
164
- end
165
- ```
166
-
167
- Servers can have roles attached to them, in this case `:web` and
168
- `:vip`. By default a connection will be run for all servers, but the
169
- `roles` command allows connections to be limited to the given roles.
170
-
171
- Servers can also have a hash of options, which will override
172
- the matching connection options for just that server. In this case
173
- we want to connect to port 80 on the vip rather than 8000.
174
-
175
- Server names may be given as strings (which will be parsed by HostRange),
176
- as arrays (or expressions returning arrays), or as a block returning
177
- an array. All arrays will be flattened. Hence the following are all
178
- equivalent:
179
-
180
- ```ruby
181
- server "foo1", "foo2", "foo3"
182
- server "foo[1-3]"
183
- server HostRange.parse("foo[1-3]")
184
- server [ "foo1", "foo2", "foo3" ]
185
- server do
186
- %w{ foo1 foo2 foo3 }
187
- end
188
- ```
189
-
190
- The `header` command demonstrates setting options for a request,
191
- in this case setting an http request header.
192
-
193
- The `socket` command creates a connection to the given port, and
194
- `open?` returns true if the port is open. We just apply this to
195
- the real web servers and not the vip.
196
-
197
- The document title test demonstrates how to extract and return a regex
198
- match. Tests can return almost any object (including Exceptions), and
199
- auger will try to display the result using the `.to_s` method. Ruby's
200
- MatchData object, however, gets special treatment. If the MatchData
201
- has captures (captured using parentheses in the regex) they will be
202
- displayed, as in this case. If no captures, the MatchData will be
203
- treated as a boolean. The `aug` cmdline client displays booleans with
204
- a checkmark or an 'x'.
205
-
206
- ### Example 3 - testing ElasticSearch
207
-
208
- ```ruby
209
- require 'json'
210
-
211
- project "Elasticsearch" do
212
- server 'prod-es-[01-04]'
213
-
214
- http 9200 do
215
- get "/_cluster/health" do
216
-
217
- # this runs after request returns, but before tests
218
- # use it to munge response body from json string into a hash
219
- before_tests do |r|
220
- r.body = JSON.parse(r.body)
221
- end
222
-
223
- test "Status 200" do |r|
224
- r.code == '200'
225
- end
226
-
227
- # Now we'll define an array called stats, which contains all the keys we
228
- # want to retrieve values from in our /_cluster/health output. In this
229
- # case, we'll just return the body of the response, as it's relatively
230
- # small. You can of course parse this however you'd like for this or
231
- # other cases.
232
- stats = %w[
233
- cluster_name
234
- status
235
- timed_out
236
- number_of_nodes
237
- number_of_data_nodes
238
- active_primary_shards
239
- active_shards
240
- relocating_shards
241
- initializing_shards
242
- unassigned_shards
243
- ]
244
-
245
- stats.each do |stat|
246
- test "#{stat}" do |r|
247
- r.body[stat]
248
- end
249
- end
250
-
251
- # I've discovered that a typical fail case with elasticsearch is
252
- # that on occassion, nodes will come up and not join the cluster
253
- # This is an easy way to see if the number of nodes that the host
254
- # actually sees (actual_data_nodes) matches what we're
255
- # expecting (expected_data_nodes).
256
- # TODO: dynamically update expected_data_nodes based on defined hosts:
257
- test "Expected vs Actual Nodes" do |r|
258
- r.body['number_of_data_nodes'] == 8
259
- end
260
-
261
- end
262
-
263
- end
264
- ```
265
-
266
- ## Writing plugins
267
-
268
- Let's look at a simplified http plugin.
269
-
270
- ```ruby
271
- require "net/http"
272
-
273
- module Auger
274
-
275
- class Project
276
- def http(port = 80, &block)
277
- @connections << Http.load(port, &block)
278
- end
279
- end
280
-
281
- class Http < Auger::Connection
282
- def open(host, options)
283
- http = Net::HTTP.new(host, options[:port])
284
- http.start
285
- http
286
- end
287
-
288
- def close(http)
289
- http.finish
290
- end
291
-
292
- def get(url, &block)
293
- @requests << Auger::HttpRequest.load(url, &block)
294
- end
295
- end
296
-
297
- class HttpRequest < Auger::Request
298
- def run(http)
299
- get = Net::HTTP::Get.new(@arg)
300
- http.request(get)
301
- end
302
- end
303
-
304
- end
305
- ```
306
-
307
- First, we add the `http` method to the Project class. This simply causes
308
- the 'http' command to add a connection of class Http to the project's
309
- list of connections.
310
-
311
- Next, we define the Http connection class by sub-classing `Auger::Connection`.
312
- A connection class needs to define `open` and `close` methods, which will
313
- create and destroy a connection object (in this case a Net::HTTP object).
314
- `open` takes a hostname and the connection @options hash, and returns an
315
- instance of the relevant request object.
316
-
317
-
318
- ## Command Line Auto-completion for aug tool
319
-
320
- BASH completion (with file completion and a rolling cache, if you're incredibly impatient like me):
321
- ```bash
322
- _augcomp()
323
- {
324
- count=100
325
- augcache="/tmp/.aug_cache"
326
- augcounter="/tmp/.aug_counter"
327
-
328
- # if the cache or the counter don't exist, create
329
- if [ ! -f "$augcache" ] || [ ! -f "$augcounter" ]
330
- then
331
- aug -l >$augcache && echo 0 >$augcounter
332
- else
333
- # if the counter reaches $count, re-generate the complete list
334
- if [ $(cat "$augcounter") -eq "$count" ]
335
- then
336
- aug -l >$augcache && echo 0 >$augcounter
337
- # if the counter hasn't reached $count, increment it
338
- else
339
- expr $(cat $augcounter) + 1 >$augcounter
340
- fi
341
- fi
342
- augcfgs=$(cat "$augcache" | xargs)
343
-
344
- word=${COMP_WORDS[COMP_CWORD]}
345
-
346
- _compopt_o_filenames
347
- COMPREPLY=($(compgen -f -W "$augcfgs" -- "${word}"))
348
- }
349
- complete -F _augcomp aug
350
- ```
351
-
352
- ZSH completion:
353
-
354
- _augprojects () { _files; compadd $(aug -l) }
355
- compdef _augprojects aug
356
-
357
- ## Augweb
358
-
359
- Auger now has a simple web interface,
360
- [augweb](http://github.com/brewster/augweb), showing tabulated test
361
- results and charts of response times.
362
-
363
- ## Ports
364
-
365
- [Augen](https://github.com/simoneb/augen) is an ongoing attempt to
366
- port auger to .NET.
367
-
368
- ## Pull Requests
369
-
370
- Yes please.
371
-
372
- New plugins and general bug fixes, updates, etc are all welcome.
373
-
374
- Generally, we'd prefer you do the following to submit a pull:
375
- * fork
376
- * create a local topic branch
377
- * make your changes and push
378
- * submit your pull request
379
-
380
- ## License
381
-
382
- Auger is distributed under the MIT license. See the attached LICENSE
383
- file for all the sordid details.
1
+ ## This repository has moved!
2
+ * The authoritative copy can be found at: [rlister/auger](https://github.com/rlister/auger)
data/Rakefile CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env rake
2
2
  require "bundler/gem_tasks"
3
- require "rainbow"
3
+ require 'rainbow/ext/string'
4
+
4
5
 
5
6
  ## begin version management
6
7
  def valid? version
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.4.5
1
+ 1.4.6
data/bin/aug CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # -*- coding: utf-8 -*-
3
3
 
4
- require 'rainbow'
4
+ require 'rainbow/ext/string'
5
5
  require 'optparse'
6
6
 
7
7
  AUGER_DIR = File.dirname(File.dirname(__FILE__))
@@ -15,7 +15,7 @@ require 'auger'
15
15
  ## set opts
16
16
  options = {}
17
17
  OptionParser.new do |opts|
18
- opts.banner = "Usage: aug [-h|--help] [-l|--list] [-v|--version] cfg"
18
+ opts.banner = "Usage: aug [-h|--help] [-l|--list] [-v|--verbose] [-V|--version] cfg"
19
19
 
20
20
  if ARGV[0] == nil
21
21
  puts opts.banner.color(:yellow)
@@ -27,7 +27,7 @@ OptionParser.new do |opts|
27
27
  exit
28
28
  end
29
29
 
30
- opts.on('-v', '--version', 'Display version and exit.') do
30
+ opts.on('-V', '--version', 'Display version and exit.') do
31
31
  puts Auger::VERSION
32
32
  exit
33
33
  end
@@ -43,41 +43,25 @@ OptionParser.new do |opts|
43
43
  options[:tunnel] = t
44
44
  end
45
45
 
46
+ opts.on('-v', '--verbose', 'Display error backtraces.') do
47
+ options[:verbose] = true
48
+ end
49
+
50
+ opts.on('-s', '--single-thread', 'Do not fork when running tests.') do
51
+ options[:single_thread] = true
52
+ end
53
+
46
54
  end.parse!
47
55
 
48
56
  ## load plugins
49
57
  Dir["#{File.dirname(File.dirname(__FILE__))}/lib/plugins/*.rb"].each { |file| require file }
50
58
 
51
- ## pretty-print Result object
52
- module Auger
53
- class Result
54
-
55
- def format
56
- output =
57
- case self.outcome
58
- when TrueClass then "\u2713"
59
- when MatchData then outcome.captures.empty? ? "\u2713" : outcome.captures.join(' ')
60
- when FalseClass then "\u2717"
61
- when NilClass then "nil"
62
- when Exception then "#{outcome.class}: #{outcome.to_s}"
63
- else outcome.to_s
64
- end
65
-
66
- color =
67
- case self.status
68
- when FalseClass, NilClass then :red
69
- when Exception then :magenta
70
- when Status then
71
- case self.status.value
72
- when :ok then :green
73
- when :warn then :yellow
74
- when :exception then :magenta
75
- else :red
76
- end
77
- else :green
78
- end
79
-
80
- return output.color(color)
59
+ def runner(options)
60
+ if options[:single_thread]
61
+ yield
62
+ else
63
+ Process.fork do
64
+ yield
81
65
  end
82
66
  end
83
67
  end
@@ -98,8 +82,7 @@ Auger::Config.load(cfg).projects.each do |project|
98
82
  pipes = project.connections(*server.roles).map do |connection|
99
83
  read, write = IO.pipe
100
84
 
101
- Process.fork do
102
- read.close # child does not need
85
+ runner(options) do
103
86
  conn = connection.try_open(server)
104
87
 
105
88
  responses = connection.requests.map do |request|
@@ -126,14 +109,19 @@ Auger::Config.load(cfg).projects.each do |project|
126
109
  max_test_length = project.tests.map { |test| test.name.length }.max
127
110
 
128
111
  ## print results
112
+ failed = false
129
113
  servers.each do |server, pipes|
130
114
  puts "[#{server.name.color(:cyan)}]"
131
115
 
132
116
  pipes.each do |pipe|
133
117
  Marshal.load(pipe).flatten(1).each do |test, result|
118
+ if !failed && !result.include?("✓")
119
+ failed = true
120
+ end
134
121
  puts " %+#{max_test_length}s %-30s" % [ test, result ]
135
122
  end
136
123
  end
137
124
  end
138
125
 
126
+ exit(failed ? 1 : 0)
139
127
  end
@@ -4,19 +4,17 @@ module Auger
4
4
  attr_accessor :projects
5
5
  def self.load(filename)
6
6
  config = new
7
- config.instance_eval(File.read(filename))
7
+ config.instance_eval(File.read(filename), filename)
8
8
  config
9
9
  end
10
-
10
+
11
11
  def initialize
12
12
  @projects = []
13
13
  self
14
14
  end
15
-
15
+
16
16
  def project(name, &block)
17
17
  @projects << Project.load(name, &block)
18
18
  end
19
-
20
19
  end
21
-
22
20
  end
@@ -8,6 +8,38 @@ module Auger
8
8
  @status = status
9
9
  end
10
10
 
11
- end
11
+ def format
12
+ output =
13
+ case self.outcome
14
+ when TrueClass then "\u2713"
15
+ when MatchData then outcome.captures.empty? ? "\u2713" : outcome.captures.join(' ')
16
+ when FalseClass then puts "false"; "\u2717"
17
+ when NilClass then puts "nillly"; "nil"
18
+ when Exception
19
+ "#{outcome.class}: #{outcome.to_s}" +
20
+ "\n\tBacktrace:\n\t#{outcome.backtrace.join("\n\t")}"
21
+ else outcome.to_s
22
+ end
23
+
24
+ color =
25
+ case self.status
26
+ when FalseClass, NilClass then :red
27
+ when Exception then :magenta
28
+ when Status then
29
+ case self.status.value
30
+ when :ok then :green
31
+ when :warn then :yellow
32
+ when :exception then :magenta
33
+ else :red
34
+ end
35
+ else :green
36
+ end
37
+
38
+ return output.color(color)
39
+ end
12
40
 
41
+ def verbose?
42
+ !!AUGER_OPS[:verbose]
43
+ end
44
+ end
13
45
  end
@@ -1,5 +1,5 @@
1
1
  module Auger
2
-
2
+
3
3
  class Test
4
4
  attr_accessor :name, :block, :id
5
5
 
@@ -7,7 +7,7 @@ module Auger
7
7
  @name = name
8
8
  @block = block
9
9
  end
10
-
10
+
11
11
  ## return Auger::Result object with outcome of test
12
12
  def run(response)
13
13
  outcome =
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: auger
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.5
4
+ version: 1.4.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ric Lister
@@ -9,93 +9,93 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-12 00:00:00.000000000 Z
12
+ date: 2014-06-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - '>='
18
+ - - ! '>='
19
19
  - !ruby/object:Gem::Version
20
20
  version: 1.7.3
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - '>='
25
+ - - ! '>='
26
26
  - !ruby/object:Gem::Version
27
27
  version: 1.7.3
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: redis
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - '>='
32
+ - - ! '>='
33
33
  - !ruby/object:Gem::Version
34
34
  version: 3.0.1
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - '>='
39
+ - - ! '>='
40
40
  - !ruby/object:Gem::Version
41
41
  version: 3.0.1
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: net-dns
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
- - - '>='
46
+ - - ! '>='
47
47
  - !ruby/object:Gem::Version
48
48
  version: 0.7.1
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
- - - '>='
53
+ - - ! '>='
54
54
  - !ruby/object:Gem::Version
55
55
  version: 0.7.1
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: rainbow
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
- - - '>='
60
+ - - ! '>='
61
61
  - !ruby/object:Gem::Version
62
62
  version: 1.1.4
63
63
  type: :runtime
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
- - - '>='
67
+ - - ! '>='
68
68
  - !ruby/object:Gem::Version
69
69
  version: 1.1.4
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: host_range
72
72
  requirement: !ruby/object:Gem::Requirement
73
73
  requirements:
74
- - - '>='
74
+ - - ! '>='
75
75
  - !ruby/object:Gem::Version
76
76
  version: 0.0.1
77
77
  type: :runtime
78
78
  prerelease: false
79
79
  version_requirements: !ruby/object:Gem::Requirement
80
80
  requirements:
81
- - - '>='
81
+ - - ! '>='
82
82
  - !ruby/object:Gem::Version
83
83
  version: 0.0.1
84
84
  - !ruby/object:Gem::Dependency
85
85
  name: net-ssh-gateway
86
86
  requirement: !ruby/object:Gem::Requirement
87
87
  requirements:
88
- - - '>='
88
+ - - ! '>='
89
89
  - !ruby/object:Gem::Version
90
90
  version: 1.2.0
91
91
  type: :runtime
92
92
  prerelease: false
93
93
  version_requirements: !ruby/object:Gem::Requirement
94
94
  requirements:
95
- - - '>='
95
+ - - ! '>='
96
96
  - !ruby/object:Gem::Version
97
97
  version: 1.2.0
98
- description: 'Auger: test-driven ops'
98
+ description: ! 'Auger: test-driven ops'
99
99
  email:
100
100
  - rlister@gmail.com
101
101
  - heffergm@gmail.com
@@ -142,17 +142,17 @@ require_paths:
142
142
  - lib
143
143
  required_ruby_version: !ruby/object:Gem::Requirement
144
144
  requirements:
145
- - - '>='
145
+ - - ! '>='
146
146
  - !ruby/object:Gem::Version
147
147
  version: '0'
148
148
  required_rubygems_version: !ruby/object:Gem::Requirement
149
149
  requirements:
150
- - - '>='
150
+ - - ! '>='
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
153
  requirements: []
154
154
  rubyforge_project:
155
- rubygems_version: 2.0.3
155
+ rubygems_version: 2.2.2
156
156
  signing_key:
157
157
  specification_version: 4
158
158
  summary: App && infrastructure testing DSL