chef-sync 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .bin
5
+ .config
6
+ coverage
7
+ InstalledFiles
8
+ lib/bundler/man
9
+ pkg
10
+ rdoc
11
+ spec/reports
12
+ test/tmp
13
+ test/version_tmp
14
+ tmp
15
+
16
+ # YARD artifacts
17
+ .yardoc
18
+ _yardoc
19
+ doc/
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in chef-sync.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,81 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ chef-sync (0.0.1)
5
+ chef
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ bunny (0.7.9)
11
+ chef (0.10.8)
12
+ bunny (>= 0.6.0)
13
+ erubis
14
+ highline
15
+ json (>= 1.4.4, <= 1.6.1)
16
+ mixlib-authentication (>= 1.1.0)
17
+ mixlib-cli (>= 1.1.0)
18
+ mixlib-config (>= 1.1.2)
19
+ mixlib-log (>= 1.3.0)
20
+ moneta
21
+ net-ssh (~> 2.1.3)
22
+ net-ssh-multi (~> 1.1.0)
23
+ ohai (>= 0.6.0)
24
+ rest-client (>= 1.0.4, < 1.7.0)
25
+ treetop (~> 1.4.9)
26
+ uuidtools
27
+ diff-lcs (1.1.3)
28
+ erubis (2.7.0)
29
+ highline (1.6.11)
30
+ ipaddress (0.8.0)
31
+ json (1.6.1)
32
+ metaclass (0.0.1)
33
+ mime-types (1.18)
34
+ mixlib-authentication (1.1.4)
35
+ mixlib-log
36
+ mixlib-cli (1.2.2)
37
+ mixlib-config (1.1.2)
38
+ mixlib-log (1.3.0)
39
+ mocha (0.11.3)
40
+ metaclass (~> 0.0.1)
41
+ moneta (0.6.0)
42
+ net-ssh (2.1.4)
43
+ net-ssh-gateway (1.1.0)
44
+ net-ssh (>= 1.99.1)
45
+ net-ssh-multi (1.1)
46
+ net-ssh (>= 2.1.4)
47
+ net-ssh-gateway (>= 0.99.0)
48
+ ohai (0.6.12)
49
+ ipaddress
50
+ mixlib-cli
51
+ mixlib-config
52
+ mixlib-log
53
+ systemu
54
+ yajl-ruby
55
+ polyglot (0.3.3)
56
+ rake (0.9.2.2)
57
+ rest-client (1.6.7)
58
+ mime-types (>= 1.16)
59
+ rspec (2.9.0)
60
+ rspec-core (~> 2.9.0)
61
+ rspec-expectations (~> 2.9.0)
62
+ rspec-mocks (~> 2.9.0)
63
+ rspec-core (2.9.0)
64
+ rspec-expectations (2.9.1)
65
+ diff-lcs (~> 1.1.3)
66
+ rspec-mocks (2.9.0)
67
+ systemu (2.5.0)
68
+ treetop (1.4.10)
69
+ polyglot
70
+ polyglot (>= 0.3.1)
71
+ uuidtools (2.1.2)
72
+ yajl-ruby (1.1.0)
73
+
74
+ PLATFORMS
75
+ ruby
76
+
77
+ DEPENDENCIES
78
+ chef-sync!
79
+ mocha
80
+ rake
81
+ rspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Winfield Peterson
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,46 @@
1
+ chef-sync
2
+ =========
3
+
4
+ Synchronize Chef nodes w/ Capistrano and other config
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'chef-sync'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install chef-sync
19
+
20
+ ## Usage
21
+
22
+ $ > chef-sync
23
+ $ Target: ../katama_server
24
+ $ ----------------------------------------------------------
25
+ $ - Synchronizing Cap config/stages.yml w/ Chef Node Set
26
+ $ ----------------------------------------------------------
27
+ $ - production/app web ...
28
+ $ - production/resque ...
29
+ $ - qa/app web ...
30
+ $ - qa/resque ...
31
+ $ - staging/app web ...
32
+ $ - staging/resque ...
33
+ $ ----------------------------------------------------------
34
+ $ - Synchronizing config/mongo.yml w/ Chef Node Set
35
+ $ ----------------------------------------------------------
36
+ $ - qa...
37
+ $ - staging...
38
+ $ - production...
39
+
40
+ ## Contributing
41
+
42
+ 1. Fork it
43
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
44
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
45
+ 4. Push to the branch (`git push origin my-new-feature`)
46
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require "bundler"
4
+ Bundler.setup
5
+ Bundler::GemHelper.install_tasks
6
+
7
+ require "rake"
8
+ require "yaml"
9
+
10
+ require "rspec/core/rake_task"
11
+ require "rspec/core/version"
12
+
13
+ desc "Run all examples"
14
+ RSpec::Core::RakeTask.new(:spec) do |t|
15
+ t.ruby_opts = %w[-w]
16
+ end
17
+
18
+ task :default => :spec
data/bin/chef-sync ADDED
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'yaml'
5
+ require 'chef-sync'
6
+
7
+ options = {
8
+ :stages => true,
9
+ :mongo => true,
10
+ :target => Dir.pwd
11
+ }
12
+ parser = OptionParser.new do |opts|
13
+ opts.banner = <<EOL
14
+ chef-sync is a utility to synchronize data from Chef node-sets into
15
+ Capistrano multi-stage configuration, mongo server configuration, etc
16
+
17
+ Usage: chef-sync [options]
18
+ EOL
19
+
20
+ opts.on('-t', '--target [DIR]', "Target Directory (defaults to current)") {|v| options[:target] = v }
21
+ opts.on('-s', '--[no-]stages', "Sync config/stages.yml") {|v| options[:stages] = v }
22
+ opts.on('-m', '--[no-]mongo', "Sync config/mongo.yml") {|v| options[:mongo] = v }
23
+ opts.on_tail("-h", "--help", "Show this message") do
24
+ puts opts
25
+ exit
26
+ end
27
+ end
28
+ parser.parse!(ARGV)
29
+
30
+ def transform_yaml(yaml_path, &block)
31
+ unless File.exists?(yaml_path)
32
+ puts "Skipping #{yaml_path}"
33
+ return
34
+ end
35
+
36
+ yaml_hash = YAML.load_file(yaml_path)
37
+
38
+ yield(yaml_hash)
39
+
40
+ File.open(yaml_path,'w') {|f| YAML.dump(yaml_hash, f) }
41
+ end
42
+
43
+ def sync_stages(base_dir)
44
+ yaml_path = File.join(base_dir, 'config', 'stages.yml')
45
+ transform_yaml(yaml_path) do |stages_hash|
46
+ synchronized_roles = {
47
+ 'rails_server' => [:app, :web],
48
+ 'rails_utility' => :resque
49
+ }
50
+
51
+ puts "----------------------------------------------------------"
52
+ puts "- Synchronizing Cap config/stages.yml w/ Chef Node Set"
53
+ puts "----------------------------------------------------------"
54
+ Chef::Sync::Utils.update_stages_from_chef(stages_hash, synchronized_roles) do |role, environment|
55
+ puts "- #{environment}/#{role} ..."
56
+ end
57
+ end
58
+ end
59
+
60
+ def sync_mongo(base_dir)
61
+ yaml_path = File.join(base_dir, 'config', 'mongo.yml')
62
+ transform_yaml(yaml_path) do |mongo_hash|
63
+ puts "----------------------------------------------------------"
64
+ puts "- Synchronizing config/mongo.yml w/ Chef Node Set"
65
+ puts "----------------------------------------------------------"
66
+ Chef::Sync::Utils.update_mongo_from_chef(mongo_hash) do |environment|
67
+ puts "- #{environment}..."
68
+ end
69
+ end
70
+ end
71
+
72
+ puts 'Target: '+options[:target]
73
+
74
+
75
+ sync_stages(options[:target]) if options[:stages]
76
+ sync_mongo(options[:target]) if options[:mongo]
data/chef-sync.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/chef-sync/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Winfield Peterson"]
6
+ gem.email = ["wpeterson@brightcove.com"]
7
+ gem.description = %q{Synchronize Chef w/ Cap, Mongro, etc}
8
+ gem.summary = %q{Synchronize Chef nodes w/ Capistrano and other config}
9
+ gem.homepage = "http://github.com/wpeterson/chef-sync"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "chef-sync"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Chef::Sync::VERSION
17
+
18
+ gem.add_runtime_dependency 'chef'
19
+
20
+ gem.add_development_dependency "rake"
21
+ gem.add_development_dependency "rspec"
22
+ gem.add_development_dependency "mocha"
23
+ end
@@ -0,0 +1,47 @@
1
+ require 'json'
2
+
3
+ module Chef::Sync::Utils
4
+ def self.node_list(environment)
5
+ exec_knife_node_list.split
6
+ end
7
+
8
+ def self.public_hostnames_by_role(role, environment)
9
+ results = JSON.parse(exec_knife_node_search(role, environment))
10
+ hostnames = Array(results['rows']).map {|node| node['ec2']['public_hostname'] }
11
+ hostnames.sort
12
+ end
13
+
14
+ def self.update_stages_from_chef(stages_hash, synchronized_roles, &block)
15
+ stages_hash.keys.each do |environment|
16
+ synchronized_roles.each do |chef_role, cap_roles|
17
+ cap_roles = Array(cap_roles)
18
+ yield(cap_roles.join(' '), environment) if block_given?
19
+
20
+ chef_server_list = public_hostnames_by_role(chef_role, environment).sort
21
+ cap_roles.each {|cap_role| stages_hash[environment]['roles'][cap_role.to_s] = chef_server_list }
22
+ end
23
+ end
24
+ end
25
+
26
+ def self.update_mongo_from_chef(mongo_hash)
27
+ excluded_keys = %w(defaults test development)
28
+ (mongo_hash.keys - excluded_keys).each do |environment|
29
+ chef_server_list = public_hostnames_by_role('mongo', environment)
30
+
31
+ yield(environment) if block_given?
32
+
33
+ mongo_hash[environment]['hosts'] = chef_server_list.map do |hostname|
34
+ ["#{hostname}:27017"]
35
+ end if chef_server_list.any?
36
+ end
37
+ end
38
+
39
+ private
40
+ def self.exec_knife_node_search(role, environment)
41
+ `knife search node 'role:#{ role } AND chef_environment:#{ environment }' -a ec2 -Fj`
42
+ end
43
+
44
+ def self.exec_knife_node_list(environment)
45
+ `knife node list -E #{environment}`
46
+ end
47
+ end
@@ -0,0 +1,5 @@
1
+ module Chef
2
+ module Sync
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
data/lib/chef-sync.rb ADDED
@@ -0,0 +1,8 @@
1
+ require "chef-sync/version"
2
+ require "chef-sync/utils"
3
+
4
+ module Chef
5
+ module Sync
6
+ # Your code goes here...
7
+ end
8
+ end
@@ -0,0 +1,14 @@
1
+ ---
2
+ defaults:
3
+ port: 27017
4
+ test:
5
+ port: 27017
6
+ hosts:
7
+ - - test-host:27017
8
+ database: katama_test
9
+ production:
10
+ port: 27017
11
+ hosts:
12
+ - - prod-existing-1.amazonaws.com:27017
13
+ - - prod-existing-2.amazonaws.com:27017
14
+ database: katama_production
@@ -0,0 +1,15 @@
1
+ ---
2
+ production:
3
+ rails_env: production
4
+ roles:
5
+ app: &app ec2-107-22-89-198.compute-1.amazonaws.com
6
+ web: *app
7
+ ios:
8
+ - ios_hostname
9
+ qa:
10
+ rails_env: qa
11
+ roles:
12
+ app: &app ec2-23-20-177-134.compute-1.amazonaws.com
13
+ web: *app
14
+ ios:
15
+ - ios_hostname
@@ -0,0 +1,3 @@
1
+ mongo106.dav
2
+ mongo107.dav
3
+ mongo108.dav
@@ -0,0 +1,61 @@
1
+ {
2
+ "results": 2,
3
+ "rows": [
4
+ {
5
+ "ec2": {
6
+ "kernel_id": "aki-825ea7eb",
7
+ "public_ipv4": "107.22.89.198",
8
+ "reservation_id": "r-020ac561",
9
+ "public_keys_0_openssh_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCKUUG53xhavex/7g/mjlX8qnff6i+xtY+DiLzu1Z+OFu3SD6a3McGDt+vUp7RTTfnKLURMgHsxREomCMxAMrM6oksK+UU3sAD+8xOZRK2R+wQmcZg1aGPKZm6UteYxUSoyDK4RBw127FO63llrU/VBZZcsbxr3nZH3iIGvtL31M2KH4XC/p6YQ6urCIfARNuhAZKwMPtZCw0Y3fkCSzcViZ1LbMi2d1/kJYkVWY6bvV7IFkXAFhYyaFFlsD0ihk9jt/IOQUBLX0qzXSfQ72FvEqN7lGaw0B2c2C7+RBs1EE3ElgCT8ld+a0Sn+BWDwUaz7H7tN8+jRXPvmLtLSyUED katama-prod\n",
10
+ "local_ipv4": "10.242.67.15",
11
+ "local_hostname": "ip-10-242-67-15.ec2.internal",
12
+ "security_groups": [
13
+ "private_web"
14
+ ],
15
+ "hostname": "ip-10-242-67-15.ec2.internal",
16
+ "ami_id": "ami-4fa37426",
17
+ "placement_availability_zone": "us-east-1b",
18
+ "public_hostname": "ec2-107-22-89-198.compute-1.amazonaws.com",
19
+ "block_device_mapping_ami": "sda1",
20
+ "ami_launch_index": "0",
21
+ "ami_manifest_path": "ubuntu-us-east-1/images/ubuntu-oneiric-11.10-amd64-server-20120108.manifest.xml",
22
+ "instance_id": "i-d1da9ab5",
23
+ "userdata": null,
24
+ "profile": "default-paravirtual",
25
+ "instance_type": "m1.large",
26
+ "block_device_mapping_root": "/dev/sda1",
27
+ "block_device_mapping_ephemeral1": "sdc",
28
+ "block_device_mapping_ephemeral0": "sdb"
29
+ },
30
+ "id": "resque103.dav"
31
+ },
32
+ {
33
+ "ec2": {
34
+ "profile": "default-paravirtual",
35
+ "ami_id": "ami-4fa37426",
36
+ "local_ipv4": "10.46.214.63",
37
+ "local_hostname": "ip-10-46-214-63.ec2.internal",
38
+ "public_ipv4": "23.20.177.134",
39
+ "hostname": "ip-10-46-214-63.ec2.internal",
40
+ "userdata": null,
41
+ "security_groups": [
42
+ "private_web"
43
+ ],
44
+ "reservation_id": "r-d0f53ab3",
45
+ "ami_launch_index": "0",
46
+ "kernel_id": "aki-825ea7eb",
47
+ "block_device_mapping_ephemeral1": "sdc",
48
+ "placement_availability_zone": "us-east-1a",
49
+ "block_device_mapping_ephemeral0": "sdb",
50
+ "public_hostname": "ec2-23-20-177-134.compute-1.amazonaws.com",
51
+ "instance_id": "i-6fce8e0b",
52
+ "instance_type": "m1.large",
53
+ "ami_manifest_path": "ubuntu-us-east-1/images/ubuntu-oneiric-11.10-amd64-server-20120108.manifest.xml",
54
+ "public_keys_0_openssh_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCKUUG53xhavex/7g/mjlX8qnff6i+xtY+DiLzu1Z+OFu3SD6a3McGDt+vUp7RTTfnKLURMgHsxREomCMxAMrM6oksK+UU3sAD+8xOZRK2R+wQmcZg1aGPKZm6UteYxUSoyDK4RBw127FO63llrU/VBZZcsbxr3nZH3iIGvtL31M2KH4XC/p6YQ6urCIfARNuhAZKwMPtZCw0Y3fkCSzcViZ1LbMi2d1/kJYkVWY6bvV7IFkXAFhYyaFFlsD0ihk9jt/IOQUBLX0qzXSfQ72FvEqN7lGaw0B2c2C7+RBs1EE3ElgCT8ld+a0Sn+BWDwUaz7H7tN8+jRXPvmLtLSyUED katama-prod\n",
55
+ "block_device_mapping_root": "/dev/sda1",
56
+ "block_device_mapping_ami": "sda1"
57
+ },
58
+ "id": "resque102.dav"
59
+ }
60
+ ]
61
+ }
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'chef-sync'
5
+
6
+ RSpec.configure do |config|
7
+ config.mock_with :mocha
8
+ end
@@ -0,0 +1,73 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Chef::Sync::Utils do
4
+ describe "#node_list" do
5
+ it 'should parse node names from list' do
6
+ list = File.read( File.expand_path(File.dirname(__FILE__) + '/fixtures/knife/node_list.txt') )
7
+ Chef::Sync::Utils.expects(:exec_knife_node_list).returns(list)
8
+
9
+ names = Chef::Sync::Utils.node_list('production')
10
+ names.should == ["mongo106.dav", "mongo107.dav", "mongo108.dav"]
11
+ end
12
+ end
13
+
14
+ describe "#public_hostnames_by_role" do
15
+ it "should extract hostnames from knife search" do
16
+ json = File.read( File.expand_path(File.dirname(__FILE__) + '/fixtures/knife/node_search_ec2.json') )
17
+ Chef::Sync::Utils.expects(:exec_knife_node_search).returns(json)
18
+
19
+ hostnames = Chef::Sync::Utils.public_hostnames_by_role('rails_utility', 'production')
20
+ hostnames.should == ["ec2-107-22-89-198.compute-1.amazonaws.com", "ec2-23-20-177-134.compute-1.amazonaws.com"]
21
+ end
22
+ end
23
+
24
+ describe "#update_stages_from_chef" do
25
+ before(:each) do
26
+ @stages = YAML.load_file( File.expand_path(File.dirname(__FILE__) + '/fixtures/config/stages.yml') )
27
+ json = File.read( File.expand_path(File.dirname(__FILE__) + '/fixtures/knife/node_search_ec2.json') )
28
+ Chef::Sync::Utils.stubs(:exec_knife_node_search => json)
29
+
30
+ Chef::Sync::Utils.update_stages_from_chef(@stages, {'rails_server' => :app})
31
+ end
32
+
33
+ it 'should preserve rails_env' do
34
+ @stages['production']['rails_env'].should == 'production'
35
+ @stages['qa']['rails_env'].should == 'qa'
36
+ end
37
+
38
+ it 'should update server lists for included roles' do
39
+ expected_hostnames = ["ec2-107-22-89-198.compute-1.amazonaws.com", "ec2-23-20-177-134.compute-1.amazonaws.com"]
40
+ @stages['production']['roles']['app'].should == expected_hostnames
41
+ @stages['qa']['roles']['app'].should == expected_hostnames
42
+ end
43
+
44
+ it 'should NOT update server lists for other roles' do
45
+ ios_expected = %w(ios_hostname)
46
+ @stages['production']['roles']['ios'].should == ios_expected
47
+ @stages['qa']['roles']['ios'].should == ios_expected
48
+ end
49
+ end
50
+
51
+ describe '#update_mongo_from_chef' do
52
+ before(:each) do
53
+ @mongos = YAML.load_file( File.expand_path(File.dirname(__FILE__) + '/fixtures/config/mongo.yml') )
54
+ json = File.read( File.expand_path(File.dirname(__FILE__) + '/fixtures/knife/node_search_ec2.json') )
55
+ Chef::Sync::Utils.stubs(:exec_knife_node_search => json)
56
+
57
+ Chef::Sync::Utils.update_mongo_from_chef(@mongos)
58
+ end
59
+
60
+ it 'should preserve defaults' do
61
+ @mongos['defaults']['port'].should == 27017
62
+ end
63
+
64
+ it 'should set hosts based on chef nodes' do
65
+ expected_hosts = [["ec2-107-22-89-198.compute-1.amazonaws.com:27017"], ["ec2-23-20-177-134.compute-1.amazonaws.com:27017"]]
66
+ @mongos['production']['hosts'].should == expected_hosts
67
+ end
68
+
69
+ it 'should NOT over-write hosts in excluded environments' do
70
+ @mongos['test']['hosts'].should == [['test-host:27017']]
71
+ end
72
+ end
73
+ end
metadata ADDED
@@ -0,0 +1,134 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: chef-sync
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Winfield Peterson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: chef
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: mocha
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: Synchronize Chef w/ Cap, Mongro, etc
79
+ email:
80
+ - wpeterson@brightcove.com
81
+ executables:
82
+ - chef-sync
83
+ extensions: []
84
+ extra_rdoc_files: []
85
+ files:
86
+ - .gitignore
87
+ - .rspec
88
+ - Gemfile
89
+ - Gemfile.lock
90
+ - LICENSE
91
+ - README.md
92
+ - Rakefile
93
+ - bin/chef-sync
94
+ - chef-sync.gemspec
95
+ - lib/chef-sync.rb
96
+ - lib/chef-sync/utils.rb
97
+ - lib/chef-sync/version.rb
98
+ - spec/fixtures/config/mongo.yml
99
+ - spec/fixtures/config/stages.yml
100
+ - spec/fixtures/knife/node_list.txt
101
+ - spec/fixtures/knife/node_search_ec2.json
102
+ - spec/spec_helper.rb
103
+ - spec/utils_spec.rb
104
+ homepage: http://github.com/wpeterson/chef-sync
105
+ licenses: []
106
+ post_install_message:
107
+ rdoc_options: []
108
+ require_paths:
109
+ - lib
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ none: false
112
+ requirements:
113
+ - - ! '>='
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ required_rubygems_version: !ruby/object:Gem::Requirement
117
+ none: false
118
+ requirements:
119
+ - - ! '>='
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ requirements: []
123
+ rubyforge_project:
124
+ rubygems_version: 1.8.23
125
+ signing_key:
126
+ specification_version: 3
127
+ summary: Synchronize Chef nodes w/ Capistrano and other config
128
+ test_files:
129
+ - spec/fixtures/config/mongo.yml
130
+ - spec/fixtures/config/stages.yml
131
+ - spec/fixtures/knife/node_list.txt
132
+ - spec/fixtures/knife/node_search_ec2.json
133
+ - spec/spec_helper.rb
134
+ - spec/utils_spec.rb