auger 1.4.5 → 1.4.6

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 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