ronin-wrapper 0.0.13 → 0.1.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
  SHA1:
3
- metadata.gz: 53e2dbec8e427757f3f6aa4dd83f44da312e738a
4
- data.tar.gz: d9826525467d51515bd6e17b84a7a4d3f0f02fa9
3
+ metadata.gz: cdc6b1775102883bb73d1df58558de222513bbf8
4
+ data.tar.gz: 82b46f7100cba0e521ba1295fd1ef3f420f0ed11
5
5
  SHA512:
6
- metadata.gz: 3caca00937edd64378164774cac21fa6ffe5f21577a9f69960fdabff2ae180ab14d3ac4006ed0b5d6e693f9b96da786d85ea5f2b459d0226315383b62152d6be
7
- data.tar.gz: 2144ce58a9df7fea7f7d68819660bef0e7a3d9dfc0f54789b26b0a9edc930a452ef43b55aac3060075a019f6e8e08b353a43af15439452e7b1c01e54f5102924
6
+ metadata.gz: 2fcfb230bb3273079f56f57b1d03a42b6cd589c56a2e23fcaa2864ae9dfe4bf83d48b4e3351bc74ee5b6934eb489b53b3a94e14ba87295fc4a8ee87802220984
7
+ data.tar.gz: ded1b2e82e6743935a3d65a02f67302359c39848fb43f1acc57d8120b63aa9ad378fcdcf0ee852bd89e19166b5ff767b07ca8b5d749e136c1fd3ce105d211762
data/README.md CHANGED
@@ -1,4 +1,17 @@
1
- ronin
2
- =====
1
+ ## Ronin [![Build Status](https://api.travis-ci.org/nmilford/ronin.png)](https://travis-ci.org/nmilford/ronin) [![Gem Version](https://badge.fury.io/rb/ronin-wrapper.png)](http://badge.fury.io/rb/ronin-wrapper)
2
+
3
+
4
+ Ronin is a tool to enable masterless configuration management.
5
+
6
+ It is built to use [Chef](https://github.com/opscode/chef) or [Puppet](https://github.com/puppetlabs/puppet) as it's configuration interpretor.
7
+
8
+ ### How it works
9
+
10
+ Ronin can source its runlist from a local YAML file or from an [etcd](https://github.com/coreos/etcd) cluster. It can also grab it's configuration from a etcd cluster as well in lieu of it's local config file.
11
+
12
+ When using etcd, you can also specify multiple keys to grab in an order lowest precedence to highest. This enables you to pull a 'common' configuration with other, per node, overrides.
13
+
14
+ Ronin uses [Git](https://github.com/git/git) to grab configuration management artifacts (Chef Cookbooks or Puppet Modules) and cache them locally. You can also specify that it pulls a different branch of an artifact's git repository to isolate testing.
15
+
16
+ Once cached, Ronin will run your chosen interpretor over the artifacts. By default it will on run the interpretor if git pulls any changes.
3
17
 
4
- A wrapper to enable masterless configuration management, using Chef and/or Puppet.
data/bin/ronin CHANGED
@@ -22,4 +22,4 @@ end
22
22
 
23
23
  require 'ronin'
24
24
 
25
- Ronin.run
25
+ Ronin.run
data/lib/ronin.rb CHANGED
@@ -14,13 +14,3 @@
14
14
  # See the License for the specific language governing permissions and
15
15
  # limitations under the License.
16
16
  require 'ronin/ronin'
17
- require 'ronin/config'
18
- require 'ronin/artifact_runner'
19
- require 'ronin/run_list'
20
- require 'ronin/version'
21
- require 'ronin/puppet'
22
- require 'ronin/chef'
23
- require 'ronin/git'
24
- require 'ronin/log'
25
- require 'ronin/etcd'
26
-
@@ -14,6 +14,7 @@
14
14
  # See the License for the specific language governing permissions and
15
15
  # limitations under the License.require 'ronin/run_list'
16
16
  require 'ronin/config'
17
+ require 'ronin/run_list'
17
18
  require 'ronin/util'
18
19
  require 'ronin/git'
19
20
  require 'ronin/log'
@@ -71,4 +72,4 @@ module Ronin
71
72
  end
72
73
  end
73
74
  end
74
- end
75
+ end
data/lib/ronin/chef.rb CHANGED
@@ -46,8 +46,8 @@ module Ronin
46
46
  def run
47
47
  self.create_run_list
48
48
  self.create_solo_conf
49
- Ronin::Log.info("Running Chef, logging to #{Ronin::Config[:log_path]}/ronin-chef.log.")
50
- @cmd = Mixlib::ShellOut.new("#{$CHEFSOLO_BIN} --logfile #{Ronin::Config[:log_path]}/ronin-chef.log --config #{@solo_conf} --json-attributes #{@run_list}")
49
+ Ronin::Log.info("Running Chef, logging to #{Ronin::Config[:interpreter_log_path]}/ronin-chef.log.")
50
+ @cmd = Mixlib::ShellOut.new("#{Ronin::Util.find_cmd("chef-solo")} --logfile #{Ronin::Config[:log_path]}/ronin-chef.log --config #{@solo_conf} --json-attributes #{@run_list}")
51
51
  @cmd.run_command
52
52
  self.clean_up
53
53
  end
@@ -69,4 +69,4 @@ module Ronin
69
69
  end
70
70
 
71
71
  end
72
- end
72
+ end
data/lib/ronin/config.rb CHANGED
@@ -14,7 +14,6 @@
14
14
  # See the License for the specific language governing permissions and
15
15
  # limitations under the License.
16
16
  require 'mixlib/config'
17
- require 'ronin/etcd'
18
17
 
19
18
  module Ronin
20
19
  class Config
@@ -28,25 +27,28 @@ module Ronin
28
27
  puts "No configuration file at #{config_file}, using defaults."
29
28
  end
30
29
 
31
- config_strict_mode true
32
- default :config_from_etcd, false
33
- default :lock_file, '/var/tmp/ronin.lock'
34
- default :log_path, '/var/log/ronin'
35
- default :log_level, :info
36
- default :update_on_change, true
37
- default :interpreter, 'chef'
38
- default :artifact_path, '/var/lib/ronin/artifacts'
39
- default :run_list_type, 'yaml'
40
- default :run_list_file, '/etc/ronin/artifacts.yaml'
41
- default :etcd_host, '127.0.0.1'
42
- default :etcd_port, 4001
30
+ config_strict_mode true
31
+ default :config_from_etcd, false
32
+ default :cache_etcd_data, true
33
+ default :lock_file, '/var/tmp/ronin.lock'
34
+ default :log_path, 'STDOUT'
35
+ default :interpreter_log_path, '/var/log/ronin'
36
+ default :log_level, :info
37
+ default :update_on_change, true
38
+ default :interpreter, 'chef'
39
+ default :cache_path, '/var/lib/ronin/cache'
40
+ default :artifact_path, '/var/lib/ronin/artifacts'
41
+ default :run_list_type, 'yaml'
42
+ default :run_list_file, '/etc/ronin/artifacts.yaml'
43
+ default :etcd_host, '127.0.0.1'
44
+ default :etcd_port, 4001
43
45
  default :etcd_conn_timeout, 5
44
46
  default :etcd_read_timeout, 5
45
- default :etcd_use_ssl, false
46
- default :etcd_ssl_ca_cert, ''
47
- default :etcd_ssl_cert, ''
48
- default :etcd_ssl_key, ''
49
- default :etcd_keys, [ 'common', 'env', 'node' ]
47
+ default :etcd_use_ssl, false
48
+ default :etcd_ssl_ca_cert, ''
49
+ default :etcd_ssl_cert, ''
50
+ default :etcd_ssl_key, ''
51
+ default :etcd_keys, ['common', 'node']
50
52
 
51
53
  end
52
- end
54
+ end
data/lib/ronin/etcd.rb CHANGED
@@ -13,32 +13,18 @@
13
13
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
14
  # See the License for the specific language governing permissions and
15
15
  # limitations under the License.
16
- require 'mixlib/config'
16
+ require 'ronin/config'
17
+ require 'ronin/cache'
17
18
  require 'net/https'
18
19
  require 'net/http'
19
20
  require 'socket'
20
21
  require 'json'
21
22
 
22
- # Add test data thus.
23
-
24
- #curl -L http://127.0.0.1:4001/v2/keys/ronin/config/common -X PUT -d value='{
25
- # "artifacts": [
26
- # "https://github.com/opscode-cookbooks/motd-tail"
27
- # ]
28
- #}'
29
-
30
- #curl -L http://127.0.0.1:4001/v2/keys/ronin/config/common -X PUT -d value='{
31
- # "log_path": "/var/log/ronin",
32
- # "interpreter": ":chef",
33
- # "artifact_path": "/var/lib/ronin/artifacts",
34
- # "update_on_change": "true",
35
- # "run_list_type": ":etcd",
36
- # "run_list_file": "/etc/ronin/artifacts.yaml"
37
- #}'
38
-
39
23
  module Ronin
40
24
  module Etcd
41
25
 
26
+ @hostname = Socket.gethostname
27
+
42
28
  def get_key(type, key)
43
29
  # Will add error handling... one day.
44
30
  @path = "/v2/keys/ronin/#{type}/#{key}"
@@ -61,26 +47,79 @@ module Ronin
61
47
  end
62
48
 
63
49
  @request = Net::HTTP::Get.new(@path)
64
- @result = @http.request(@request)
50
+
51
+ begin
52
+ @result = @http.request(@request)
53
+ rescue Exception => e
54
+ if Ronin::Config[:cache_etcd_data]
55
+ return :down
56
+ else
57
+ abort("Connection refused by etcd host #{Ronin::Config[:etcd_host]}:#{Ronin::Config[:etcd_port]}, exiting...")
58
+ end
59
+ end
60
+
61
+ unless @result.kind_of?(Net::HTTPSuccess)
62
+ if @result.code == 404
63
+ Ronin::Log.info("Key http://#{Ronin::Config[:etcd_host]}:#{Ronin::Config[:etcd_port]}#{@path} not found, returning an empty set.")
64
+ return "{}"
65
+ else
66
+ Ronin::Log.info("Got status #{@result.code} querying http://#{Ronin::Config[:etcd_host]}:#{Ronin::Config[:etcd_port]}#{@path}, returning an empty set.")
67
+ return "{}"
68
+ end
69
+ end
70
+
65
71
  return JSON.parse(@result.body)['node']['value']
66
72
  end
67
73
  module_function :get_key
68
74
 
69
75
  def get_config
70
- @hostname = Socket.gethostname
71
- @common = JSON.parse(Ronin::Etcd.get_key('config', 'common'))
72
- #@specific = JSON.parse(Ronin::Etcd.get_key('config', @hostname))
73
- #return @common.merge(@specific)
76
+ @config = {}
77
+ Ronin::Config[:etcd_keys].each do |key|
78
+ key = @hostname if key == 'node'
79
+
80
+ @payload = Ronin::Etcd.get_key('config', key)
81
+
82
+ if @payload == :down
83
+ Ronin::Log.warn("Connection refused by etcd host #{Ronin::Config[:etcd_host]}:#{Ronin::Config[:etcd_port]}, loading config from cache (#{Ronin::Config[:cache_path]}/config.json)")
84
+
85
+ return Ronin::Cache.load_cached_config
86
+ else
87
+ @parsed_payload = JSON.parse(@payload)
88
+ @config = @config.merge(@parsed_payload)
89
+ end
90
+ end
91
+
92
+ if Ronin::Config[:config_from_etcd] and Ronin::Config[:cache_etcd_data]
93
+ Ronin::Cache.cache_config(@config)
94
+ end
95
+
96
+ return @config
74
97
  end
75
98
  module_function :get_config
76
99
 
77
100
  def get_run_list
78
- @hostname = Socket.gethostname
79
- @common = JSON.parse(Ronin::Etcd.get_key('run_list', 'common'))['artifacts']
80
- #@specific = JSON.parse(Ronin::Etcd.get_key('run_list', @hostname))['artifacts']
81
- #return (@common+@specific).uniq
101
+ @run_list = []
102
+ Ronin::Config[:etcd_keys].each do |key|
103
+ key = @hostname if key == 'node'
104
+
105
+ @payload = Ronin::Etcd.get_key('run_list', key)
106
+
107
+ if @payload == :down
108
+ Ronin::Log.warn("Connection refused by etcd host #{Ronin::Config[:etcd_host]}:#{Ronin::Config[:etcd_port]}, loading run_list from cache (#{Ronin::Config[:cache_path]}/run_list.json)")
109
+ return Ronin::Cache.load_cached_run_list
110
+ else
111
+ @parsed_payload = JSON.parse(@payload)['artifacts']
112
+ @run_list += @parsed_payload unless @parsed_payload.nil?
113
+ end
114
+
115
+ if Ronin::Config[:config_from_etcd] and Ronin::Config[:cache_etcd_data]
116
+ Ronin::Cache.cache_run_list(@run_list.uniq)
117
+ end
118
+ end
119
+
120
+ return @run_list.uniq
82
121
  end
83
122
  module_function :get_run_list
84
123
 
85
124
  end
86
- end
125
+ end
data/lib/ronin/git.rb CHANGED
@@ -15,11 +15,12 @@
15
15
  # limitations under the License.
16
16
  require "mixlib/shellout"
17
17
  require 'ronin/config'
18
+ require 'ronin/util'
18
19
 
19
20
  module Ronin
20
21
  module Git
21
22
  def branch(artifact)
22
- @cmd = Mixlib::ShellOut.new("#{$GIT_BIN} --git-dir=#{Ronin::Config[:artifact_path]}/#{artifact}/.git --work-tree=#{Ronin::Config[:artifact_path]}/#{artifact}/ branch")
23
+ @cmd = Mixlib::ShellOut.new("#{Ronin::Util.find_cmd("git")} --git-dir=#{Ronin::Config[:artifact_path]}/#{artifact}/.git --work-tree=#{Ronin::Config[:artifact_path]}/#{artifact}/ branch")
23
24
  @cmd.run_command
24
25
  @branch = @cmd.stdout.chomp.split(' ')[1]
25
26
  @branch
@@ -27,7 +28,7 @@ module Ronin
27
28
  module_function :branch
28
29
 
29
30
  def pull_and_report_updated(artifact)
30
- @cmd = Mixlib::ShellOut.new("git --git-dir=#{Ronin::Config[:artifact_path]}/#{artifact}/.git --work-tree=#{Ronin::Config[:artifact_path]}/#{artifact}/ pull")
31
+ @cmd = Mixlib::ShellOut.new("#{Ronin::Util.find_cmd("git")} --git-dir=#{Ronin::Config[:artifact_path]}/#{artifact}/.git --work-tree=#{Ronin::Config[:artifact_path]}/#{artifact}/ pull")
31
32
  @cmd.run_command
32
33
  @updated = @cmd.stdout.include?("Updating")
33
34
  @updated ? true : false
@@ -35,10 +36,10 @@ module Ronin
35
36
  module_function :pull_and_report_updated
36
37
 
37
38
  def clone(artifact_data)
38
- @cmd = Mixlib::ShellOut.new("git clone #{artifact_data[:repo]} #{Ronin::Config[:artifact_path]}/#{artifact_data[:name]}/ -b #{artifact_data[:branch]}")
39
+ @cmd = Mixlib::ShellOut.new("#{Ronin::Util.find_cmd("git")} clone #{artifact_data[:repo]} #{Ronin::Config[:artifact_path]}/#{artifact_data[:name]}/ -b #{artifact_data[:branch]}")
39
40
  @cmd.run_command
40
41
  @cmd.stdout
41
42
  end
42
43
  module_function :clone
43
44
  end
44
- end
45
+ end
data/lib/ronin/log.rb CHANGED
@@ -20,9 +20,13 @@ module Ronin
20
20
  class Log
21
21
  extend Mixlib::Log
22
22
 
23
- logfile = "#{Ronin::Config[:log_path]}/ronin.log"
24
-
25
- init(logfile)
26
23
  self.level = Ronin::Config[:log_level]
24
+
25
+ if Ronin::Config[:log_path] == 'STDOUT'
26
+ init(STDOUT)
27
+ else
28
+ init("#{Ronin::Config[:log_path]}/ronin.log")
29
+ end
30
+
27
31
  end
28
- end
32
+ end
data/lib/ronin/puppet.rb CHANGED
@@ -37,8 +37,8 @@ module Ronin
37
37
 
38
38
  def run
39
39
  self.create_run_list
40
- Ronin::Log.info("Running Puppet, logging to #{Ronin::Config[:log_path]}/ronin-puppet.log.")
41
- @cmd = Mixlib::ShellOut.new("#{$PUPPET_BIN} apply --verbose --ordering manifest --logdest #{Ronin::Config[:log_path]}/ronin-puppet.log --modulepath #{Ronin::Config[:artifact_path]} #{@run_list}")
40
+ Ronin::Log.info("Running Puppet, logging to #{Ronin::Config[:interpreter_log_path]}/ronin-puppet.log.")
41
+ @cmd = Mixlib::ShellOut.new("#{Ronin::Util.find_cmd("puppet")} apply --ordering manifest --logdest #{Ronin::Config[:log_path]}/ronin-puppet.log --modulepath #{Ronin::Config[:artifact_path]} #{@run_list}")
42
42
  @cmd.run_command
43
43
  self.clean_up
44
44
  end
@@ -49,4 +49,4 @@ module Ronin
49
49
  end
50
50
 
51
51
  end
52
- end
52
+ end
data/lib/ronin/ronin.rb CHANGED
@@ -13,10 +13,11 @@
13
13
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
14
  # See the License for the specific language governing permissions and
15
15
  # limitations under the License.
16
- $LOAD_PATH << "."
17
16
  require 'ronin/artifact_runner'
18
17
  require 'ronin/run_list'
19
18
  require 'ronin/config'
19
+ require 'ronin/puppet'
20
+ require 'ronin/chef'
20
21
  require 'ronin/util'
21
22
  require 'ronin/log'
22
23
 
@@ -30,7 +31,7 @@ module Ronin
30
31
  Ronin::Log.info("Setting #{k} to #{v}.")
31
32
 
32
33
  if v.start_with?(':')
33
- v = v[1..-1].to_sym
34
+ v = v[1..-1].to_sym
34
35
  end
35
36
 
36
37
  Ronin::Config["#{k}"] = v
@@ -41,20 +42,14 @@ module Ronin
41
42
 
42
43
  if Ronin::Util.find_cmd("git").nil?
43
44
  abort("You need to have git installed to perform this command.")
44
- else
45
- $GIT_BIN = Ronin::Util.find_cmd("git")
46
45
  end
47
46
 
48
- if Ronin::Util.find_cmd("puppet").nil? and Ronin::Config[:interpreter] == :puppet
47
+ if Ronin::Util.find_cmd("puppet").nil? and Ronin::Config[:interpreter] == 'puppet'
49
48
  abort("You need to have Puppet installed to perform this command with Puppet set as the interpreter.")
50
- else
51
- $PUPPET_BIN = Ronin::Util.find_cmd("puppet")
52
49
  end
53
50
 
54
- if Ronin::Util.find_cmd("chef-solo").nil? and Ronin::Config[:interpreter] == :puppet
51
+ if Ronin::Util.find_cmd("chef-solo").nil? and Ronin::Config[:interpreter] == 'chef'
55
52
  abort("You need to have Chef-Solo installed to perform this command with Chef set as the interpreter.")
56
- else
57
- $CHEFSOLO_BIN = Ronin::Util.find_cmd("chef-solo")
58
53
  end
59
54
 
60
55
  unless File.exists?(Ronin::Config[:lock_file])
@@ -31,10 +31,9 @@ module Ronin
31
31
  end
32
32
 
33
33
  unless @artifacts_raw.nil?
34
-
35
34
  @artifacts_raw.each do |a|
36
35
  if a.include?(";")
37
- @repo = a.split(";")[0].sub(/(\/)+$/,'')
36
+ @repo = a.split(";")[0].sub(/(\/)+$/, '')
38
37
  @branch = a.split(";")[1]
39
38
  else
40
39
  @repo = a
@@ -52,15 +51,17 @@ module Ronin
52
51
 
53
52
  def artifacts
54
53
  @arts = []
55
- @run_list.each { |k,v| @arts << k }
54
+ @run_list.each { |k, v| @arts << k }
56
55
  @arts
57
56
  end
58
57
 
59
58
  def items
60
59
  @items = []
61
- @run_list.each { |k,v| @items << { :name => v[:name], :repo => v[:repo], :branch => v[:branch] } }
60
+ @run_list.each do |k, v|
61
+ @items << { :name => v[:name], :repo => v[:repo], :branch => v[:branch] }
62
+ end
62
63
  @items
63
64
  end
64
65
 
65
66
  end
66
- end
67
+ end
data/lib/ronin/util.rb CHANGED
@@ -32,4 +32,4 @@ module Ronin
32
32
  module_function :num_cores
33
33
 
34
34
  end
35
- end
35
+ end
data/lib/ronin/version.rb CHANGED
@@ -13,6 +13,7 @@
13
13
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
14
  # See the License for the specific language governing permissions and
15
15
  # limitations under the License.
16
+
16
17
  module Ronin
17
- VERSION = '0.0.13'
18
+ VERSION = '0.1.0'
18
19
  end
metadata CHANGED
@@ -1,99 +1,197 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ronin-wrapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.13
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Milford
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-30 00:00:00.000000000 Z
11
+ date: 2014-01-02 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: parallel
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 0.9.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 0.9.1
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: yajl-ruby
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
- - - '>='
31
+ - - ~>
18
32
  - !ruby/object:Gem::Version
19
33
  version: 1.2.0
20
34
  type: :runtime
21
35
  prerelease: false
22
36
  version_requirements: !ruby/object:Gem::Requirement
23
37
  requirements:
24
- - - '>='
38
+ - - ~>
25
39
  - !ruby/object:Gem::Version
26
40
  version: 1.2.0
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: mixlib-log
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
- - - '>='
45
+ - - ~>
32
46
  - !ruby/object:Gem::Version
33
47
  version: 1.6.0
34
48
  type: :runtime
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
- - - '>='
52
+ - - ~>
39
53
  - !ruby/object:Gem::Version
40
54
  version: 1.6.0
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: mixlib-config
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
- - - '>='
59
+ - - ~>
46
60
  - !ruby/object:Gem::Version
47
61
  version: 2.1.0
48
62
  type: :runtime
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
- - - '>='
66
+ - - ~>
53
67
  - !ruby/object:Gem::Version
54
68
  version: 2.1.0
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: mixlib-shellout
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
- - - '>='
73
+ - - ~>
60
74
  - !ruby/object:Gem::Version
61
75
  version: 1.3.0
62
76
  type: :runtime
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
- - - '>='
80
+ - - ~>
67
81
  - !ruby/object:Gem::Version
68
82
  version: 1.3.0
69
83
  - !ruby/object:Gem::Dependency
70
- name: mixlib-shellout
84
+ name: rack
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
- - - '>='
87
+ - - ~>
74
88
  - !ruby/object:Gem::Version
75
- version: 0.9.1
76
- type: :runtime
89
+ version: 1.5.2
90
+ type: :development
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
- - - '>='
94
+ - - ~>
81
95
  - !ruby/object:Gem::Version
82
- version: 0.9.1
96
+ version: 1.5.2
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: rake
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
- - - '>='
101
+ - - ~>
88
102
  - !ruby/object:Gem::Version
89
103
  version: 10.1.1
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
- - - '>='
108
+ - - ~>
95
109
  - !ruby/object:Gem::Version
96
110
  version: 10.1.1
111
+ - !ruby/object:Gem::Dependency
112
+ name: tailor
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: 1.3.0
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ~>
123
+ - !ruby/object:Gem::Version
124
+ version: 1.3.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: sinatra
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ~>
130
+ - !ruby/object:Gem::Version
131
+ version: 1.4.4
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ~>
137
+ - !ruby/object:Gem::Version
138
+ version: 1.4.4
139
+ - !ruby/object:Gem::Dependency
140
+ name: travis-lint
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ~>
144
+ - !ruby/object:Gem::Version
145
+ version: 1.7.0
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ~>
151
+ - !ruby/object:Gem::Version
152
+ version: 1.7.0
153
+ - !ruby/object:Gem::Dependency
154
+ name: rspec-core
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ~>
158
+ - !ruby/object:Gem::Version
159
+ version: 2.14.7
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ~>
165
+ - !ruby/object:Gem::Version
166
+ version: 2.14.7
167
+ - !ruby/object:Gem::Dependency
168
+ name: rspec-mocks
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ~>
172
+ - !ruby/object:Gem::Version
173
+ version: 2.14.4
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ~>
179
+ - !ruby/object:Gem::Version
180
+ version: 2.14.4
181
+ - !ruby/object:Gem::Dependency
182
+ name: rspec-expectations
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ~>
186
+ - !ruby/object:Gem::Version
187
+ version: 2.14.4
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ~>
193
+ - !ruby/object:Gem::Version
194
+ version: 2.14.4
97
195
  description: A wrapper to enable masterless configuration management, using Chef and/or
98
196
  Puppet.
99
197
  email: nathan@milford.io