spiceweasel 1.2.0 → 2.0.0

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.
@@ -0,0 +1,30 @@
1
+ #
2
+ # Author:: Matt Ray (<matt@opscode.com>)
3
+ #
4
+ # Copyright:: 2012, Opscode, Inc <legal@opscode.com>
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'mixlib/log'
20
+
21
+ module Spiceweasel
22
+ class Log
23
+ extend Mixlib::Log
24
+
25
+ #not quite ready for timestamps
26
+ Mixlib::Log::Formatter.show_time = false
27
+
28
+ end
29
+ end
30
+
@@ -0,0 +1,126 @@
1
+ #
2
+ # Author:: Matt Ray (<matt@opscode.com>)
3
+ #
4
+ # Copyright:: 2011-2012, Opscode, Inc <legal@opscode.com>
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ module Spiceweasel
20
+ class Nodes
21
+
22
+ PROVIDERS = %w{bluebox clodo cs ec2 gandi hp lxc openstack rackspace slicehost terremark voxel}
23
+
24
+ attr_reader :create, :delete
25
+
26
+ def initialize(nodes, cookbooks, environments, roles)
27
+ @create = Array.new
28
+ @delete = Array.new
29
+ if nodes
30
+ Spiceweasel::Log.debug("nodes: #{nodes}")
31
+ nodes.each do |node|
32
+ name = node.keys.first
33
+ Spiceweasel::Log.debug("node: '#{name}' '#{node[name]}'")
34
+ if node[name]
35
+ #convert spaces to commas, drop multiple commas
36
+ run_list = node[name]['run_list'] || ''
37
+ run_list = run_list.gsub(/ /,',').gsub(/,+/,',')
38
+ Spiceweasel::Log.debug("node: '#{name}' run_list: '#{run_list}'")
39
+ validateRunList(name, run_list, cookbooks, roles) unless Spiceweasel::Config[:novalidation]
40
+ options = node[name]['options'] || ''
41
+ Spiceweasel::Log.debug("node: '#{name}' options: '#{options}'")
42
+ validateOptions(name, options, environments) unless Spiceweasel::Config[:novalidation]
43
+ end
44
+ #provider support
45
+ provider = name.split()
46
+ if PROVIDERS.member?(provider[0])
47
+ count = 1
48
+ if provider.length == 2
49
+ count = provider[1]
50
+ end
51
+ if Spiceweasel::Config[:parallel]
52
+ parallel = "seq #{count} | parallel -j 0 -v \""
53
+ parallel += "knife #{provider[0]}#{Spiceweasel::Config[:knife_options]} server create #{options}".gsub(/\{\{n\}\}/, '{}')
54
+ parallel += " -r '#{run_list}'" unless run_list.empty?
55
+ parallel += "\""
56
+ @create.push(parallel)
57
+ else
58
+ count.to_i.times do |i|
59
+ server = "knife #{provider[0]}#{Spiceweasel::Config[:knife_options]} server create #{options}".gsub(/\{\{n\}\}/, (i + 1).to_s)
60
+ server += " -r '#{run_list}'" unless run_list.empty?
61
+ @create.push(server)
62
+ end
63
+ end
64
+ @delete.push("knife node#{Spiceweasel::Config[:knife_options]} list | xargs knife #{provider[0]} server delete -y")
65
+ elsif name.start_with?("windows") #windows node bootstrap support
66
+ nodeline = name.split()
67
+ provider = nodeline.shift.split('_') #split on 'windows_ssh' etc
68
+ nodeline.each do |server|
69
+ server = "knife bootstrap #{provider[0]} #{provider[1]}#{Spiceweasel::Config[:knife_options]} #{server} #{options}"
70
+ server += " -r '#{run_list}'" unless run_list.empty?
71
+ @create.push(server)
72
+ @delete.push("knife node#{Spiceweasel::Config[:knife_options]} delete #{server} -y")
73
+ @delete.push("knife client#{Spiceweasel::Config[:knife_options]} delete #{server} -y")
74
+ end
75
+ @delete.push("knife node#{Spiceweasel::Config[:knife_options]} list | xargs knife #{provider[0]} server delete -y")
76
+ else #node bootstrap support
77
+ name.split.each_with_index do |server, i|
78
+ server = "knife bootstrap#{Spiceweasel::Config[:knife_options]} #{server} #{options}".gsub(/\{\{n\}\}/, (i + 1).to_s)
79
+ server += " -r '#{run_list}'" unless run_list.empty?
80
+ @create.push(server)
81
+ @delete.push("knife node#{Spiceweasel::Config[:knife_options]} delete #{server} -y")
82
+ @delete.push("knife client#{Spiceweasel::Config[:knife_options]} delete #{server} -y")
83
+ end
84
+ end
85
+ end
86
+ end
87
+ @delete.push("knife node#{Spiceweasel::Config[:knife_options]} bulk delete .* -y")
88
+ end
89
+
90
+ #ensure run_list contents are listed previously.
91
+ def validateRunList(node, run_list, cookbooks, roles)
92
+ run_list.split(',').each do |item|
93
+ if item.start_with?("recipe[")
94
+ #recipe[foo] or recipe[foo::bar]
95
+ cb = item.split(/\[|\]/)[1].split(':')[0]
96
+ unless cookbooks.member?(cb)
97
+ STDERR.puts "ERROR: '#{node}' run list cookbook '#{cb}' is missing from the list of cookbooks in the manifest."
98
+ exit(-1)
99
+ end
100
+ elsif item.start_with?("role[")
101
+ #role[blah]
102
+ role = item.split(/\[|\]/)[1]
103
+ unless roles.member?(role)
104
+ STDERR.puts "ERROR: '#{node}' run list role '#{role}' is missing from the list of roles in the manifest."
105
+ exit(-1)
106
+ end
107
+ else
108
+ STDERR.puts "ERROR: '#{node}' run list '#{item}' is an invalid run list entry in the manifest."
109
+ exit(-1)
110
+ end
111
+ end
112
+ end
113
+
114
+ #for now, just check that -E is legit
115
+ def validateOptions(node, options, environments)
116
+ if options =~ /-E/ #check for environments
117
+ env = options.split('-E')[1].split()[0]
118
+ unless environments.member?(env)
119
+ STDERR.puts "ERROR: '#{node}' environment '#{env}' is missing from the list of environments in the manifest."
120
+ exit(-1)
121
+ end
122
+ end
123
+ end
124
+
125
+ end
126
+ end
@@ -0,0 +1,131 @@
1
+ #
2
+ # Author:: Matt Ray (<matt@opscode.com>)
3
+ #
4
+ # Copyright:: 2011-2012, Opscode, Inc <legal@opscode.com>
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'json'
20
+
21
+ module Spiceweasel
22
+ class Roles
23
+
24
+ attr_reader :role_list, :create, :delete
25
+
26
+ def initialize(roles = {}, environments = [], cookbooks = {})
27
+ @create = Array.new
28
+ @delete = Array.new
29
+ @role_list = Array.new
30
+ if roles
31
+ Spiceweasel::Log.debug("roles: #{roles}")
32
+ flatroles = roles.collect {|x| x.keys}.flatten
33
+ flatroles.each do |role|
34
+ Spiceweasel::Log.debug("role: #{role}")
35
+ if File.directory?("roles")
36
+ validate(role, environments, cookbooks, flatroles) unless Spiceweasel::Config[:novalidation]
37
+ elsif !Spiceweasel::Config[:novalidation]
38
+ STDERR.puts "ERROR: 'roles' directory not found, unable to validate or load roles"
39
+ exit(-1)
40
+ end
41
+ if File.exists?("roles/#{role}.json")
42
+ @create.push("knife role#{Spiceweasel::Config[:knife_options]} from file #{role}.json")
43
+ else #assume no .json means they want .rb and catchall for misssing dir
44
+ @create.push("knife role#{Spiceweasel::Config[:knife_options]} from file #{role}.rb")
45
+ end
46
+ @delete.push("knife role#{Spiceweasel::Config[:knife_options]} delete #{role} -y")
47
+ @role_list.push(role)
48
+ end
49
+ end
50
+ end
51
+
52
+ #validate the content of the role file
53
+ def validate(role, environments, cookbooks, roles)
54
+ #validate the role passed in match the name of either the .rb or .json
55
+ if File.exists?("roles/#{role}.rb")
56
+ #validate that the name inside the file matches
57
+ name = File.open("roles/#{role}.rb").grep(/^name/)[0].split()[1].gsub(/"/,'').to_s
58
+ Spiceweasel::Log.debug("role: '#{role}' name: '#{name}'")
59
+ if !role.eql?(name)
60
+ STDERR.puts "ERROR: Role '#{role}' listed in the manifest does not match the name '#{name}' within the roles/#{role}.rb file."
61
+ exit(-1)
62
+ end
63
+ #grab any lines with 'recipe[' or 'role['
64
+ rolerl = File.open("roles/#{role}.rb").grep(/recipe\[|role\[/)
65
+ rolerl.each do |line|
66
+ Spiceweasel::Log.debug("role: '#{role}' line: '#{line}'")
67
+ line.strip.split(',').each do |rl|
68
+ if rl =~ /recipe\[/ #it's a cookbook
69
+ #split on the brackets and any colons
70
+ dep = rl.split(/\[|\]/)[1].split(':')[0]
71
+ Spiceweasel::Log.debug("role: '#{role}' cookbook: '#{rl}': dep: '#{dep}'")
72
+ if !cookbooks.member?(dep)
73
+ STDERR.puts "ERROR: Cookbook dependency '#{dep}' from role '#{role}' is missing from the list of cookbooks in the manifest."
74
+ exit(-1)
75
+ end
76
+ elsif rl =~ /role\[/ #it's a role
77
+ #split on the brackets
78
+ dep = rl.split(/\[|\]/)[1]
79
+ Spiceweasel::Log.debug("role: '#{role}' role: '#{rl}': dep: '#{dep}'")
80
+ if !roles.member?(dep)
81
+ STDERR.puts "ERROR: Role dependency '#{dep}' from role '#{role}' is missing from the list of roles in the manifest."
82
+ exit(-1)
83
+ end
84
+ end
85
+ end
86
+ end
87
+ #TODO validate any environment-specific runlists
88
+ elsif File.exists?("roles/#{role}.json")
89
+ #load the json, don't symbolize since we don't need json_class
90
+ f = File.read("roles/#{role}.json")
91
+ JSON.create_id = nil
92
+ rolefile = JSON.parse(f, {:symbolize_names => false})
93
+ #validate that the name inside the file matches
94
+ Spiceweasel::Log.debug("role: '#{role}' name: '#{rolefile['name']}'")
95
+ if !role.eql?(rolefile['name'])
96
+ STDERR.puts "ERROR: Role '#{role}' listed in the manifest does not match the name '#{rolefile['name']}' within the 'roles/#{role}.json' file."
97
+ exit(-1)
98
+ end
99
+ #validate the cookbooks and roles exist if they're mentioned in run_lists
100
+ rolefile['run_list'].each do |rl|
101
+ if rl =~ /recipe\[/ #it's a cookbook
102
+ #split on the brackets and any colons
103
+ dep = rl.split(/\[|\]/)[1].split(':')[0]
104
+ Spiceweasel::Log.debug("role: '#{role}' cookbook: '#{rl}': dep: '#{dep}'")
105
+ if !cookbooks.member?(dep)
106
+ STDERR.puts "ERROR: Cookbook dependency '#{dep}' from role '#{role}' is missing from the list of cookbooks in the manifest."
107
+ exit(-1)
108
+ end
109
+ elsif rl =~ /role\[/ #it's a role
110
+ #split on the brackets
111
+ dep = rl.split(/\[|\]/)[1]
112
+ Spiceweasel::Log.debug("role: '#{role}' role: '#{rl}': dep: '#{dep}'")
113
+ if !roles.member?(dep)
114
+ STDERR.puts "ERROR: Role dependency '#{dep}' from role '#{role}' is missing from the list of roles in the manifest."
115
+ exit(-1)
116
+ end
117
+ end
118
+ end
119
+ #TODO validate any environment-specific runlists
120
+ else #role is not here
121
+ STDERR.puts "ERROR: Invalid Role '#{role}' listed in the manifest but not found in the roles directory."
122
+ exit(-1)
123
+ end
124
+ end
125
+
126
+ def member?(role)
127
+ role_list.include?(role)
128
+ end
129
+
130
+ end
131
+ end
@@ -17,5 +17,5 @@
17
17
  #
18
18
 
19
19
  module Spiceweasel
20
- VERSION = "1.2.0"
20
+ VERSION = '2.0.0'
21
21
  end
@@ -2,8 +2,40 @@
2
2
  describe 'The Spiceweasel binary' do
3
3
  before(:each) do
4
4
  @expected_output = <<-OUTPUT
5
+ knife cookbook delete apache2 -a -y
6
+ knife cookbook delete apt 1.2.0 -a -y
7
+ knife cookbook delete mysql -a -y
8
+ knife environment delete development -y
9
+ knife environment delete qa -y
10
+ knife environment delete production -y
11
+ knife role delete base -y
12
+ knife role delete iisserver -y
13
+ knife role delete monitoring -y
14
+ knife role delete webserver -y
15
+ knife data bag delete users -y
16
+ knife data bag delete data -y
17
+ knife data bag delete passwords -y
18
+ knife node delete knife bootstrap serverA -i ~/.ssh/mray.pem -x user --sudo -r 'role[base]' -y
19
+ knife client delete knife bootstrap serverA -i ~/.ssh/mray.pem -x user --sudo -r 'role[base]' -y
20
+ knife node delete knife bootstrap serverB -i ~/.ssh/mray.pem -x user --sudo -E production -r 'role[base]' -y
21
+ knife client delete knife bootstrap serverB -i ~/.ssh/mray.pem -x user --sudo -E production -r 'role[base]' -y
22
+ knife node delete knife bootstrap serverC -i ~/.ssh/mray.pem -x user --sudo -E production -r 'role[base]' -y
23
+ knife client delete knife bootstrap serverC -i ~/.ssh/mray.pem -x user --sudo -E production -r 'role[base]' -y
24
+ knife node list | xargs knife rackspace server delete -y
25
+ knife node delete knife bootstrap windows winrm winboxA -x Administrator -P 'super_secret_password' -r 'role[base],role[iisserver]' -y
26
+ knife client delete knife bootstrap windows winrm winboxA -x Administrator -P 'super_secret_password' -r 'role[base],role[iisserver]' -y
27
+ knife node list | xargs knife windows server delete -y
28
+ knife node delete knife bootstrap windows ssh winboxB -x Administrator -P 'super_secret_password' -r 'role[base],role[iisserver]' -y
29
+ knife client delete knife bootstrap windows ssh winboxB -x Administrator -P 'super_secret_password' -r 'role[base],role[iisserver]' -y
30
+ knife node delete knife bootstrap windows ssh winboxC -x Administrator -P 'super_secret_password' -r 'role[base],role[iisserver]' -y
31
+ knife client delete knife bootstrap windows ssh winboxC -x Administrator -P 'super_secret_password' -r 'role[base],role[iisserver]' -y
32
+ knife node list | xargs knife windows server delete -y
33
+ knife node bulk delete .* -y
34
+ knife node list | xargs knife ec2 server delete -y
35
+ knife node list | xargs knife ec2 server delete -y
36
+ knife node bulk delete .* -y
5
37
  knife cookbook upload apache2
6
- knife cookbook upload apt
38
+ knife cookbook upload apt --freeze
7
39
  knife cookbook upload mysql
8
40
  knife environment from file development.rb
9
41
  knife environment from file qa.rb
@@ -20,25 +52,25 @@ knife data bag create data
20
52
  knife data bag create passwords
21
53
  knife data bag from file passwords mysql.json --secret-file secret_key
22
54
  knife data bag from file passwords rabbitmq.json --secret-file secret_key
23
- knife bootstrap serverA -i ~/.ssh/mray.pem -x user --sudo -d ubuntu10.04-gems -r 'role[base]'
24
- knife bootstrap serverB -i ~/.ssh/mray.pem -x user --sudo -d ubuntu10.04-gems -E production -r 'role[base]'
25
- knife bootstrap serverC -i ~/.ssh/mray.pem -x user --sudo -d ubuntu10.04-gems -E production -r 'role[base]'
26
- knife ec2 server create -S mray -i ~/.ssh/mray.pem -x ubuntu -G default -I ami-7000f019 -f m1.small -r 'role[webserver],recipe[mysql::client]'
27
- knife ec2 server create -S mray -i ~/.ssh/mray.pem -x ubuntu -G default -I ami-7000f019 -f m1.small -r 'role[webserver],recipe[mysql::client]'
28
- knife ec2 server create -S mray -i ~/.ssh/mray.pem -x ubuntu -G default -I ami-7000f019 -f m1.small -r 'role[webserver],recipe[mysql::client]'
29
- knife ec2 server create -S mray -i ~/.ssh/mray.pem -x ubuntu -G default -I ami-7000f019 -f m1.small -r 'role[webserver],recipe[mysql::client]'
30
- knife rackspace server create --image 49 --flavor 2 -r 'recipe[mysql],role[monitoring]'
31
- knife rackspace server create --image 49 --flavor 2 -r 'recipe[mysql],role[monitoring]'
32
- knife rackspace server create --image 49 --flavor 2 -r 'recipe[mysql],role[monitoring]'
55
+ knife bootstrap serverA -i ~/.ssh/mray.pem -x user --sudo -r 'role[base]'
56
+ knife bootstrap serverB -i ~/.ssh/mray.pem -x user --sudo -E production -r 'role[base]'
57
+ knife bootstrap serverC -i ~/.ssh/mray.pem -x user --sudo -E production -r 'role[base]'
58
+ knife rackspace server create --image 49 --flavor 2 -N db1 -r 'recipe[mysql],role[monitoring]'
59
+ knife rackspace server create --image 49 --flavor 2 -N db2 -r 'recipe[mysql],role[monitoring]'
60
+ knife rackspace server create --image 49 --flavor 2 -N db3 -r 'recipe[mysql],role[monitoring]'
33
61
  knife bootstrap windows winrm winboxA -x Administrator -P 'super_secret_password' -r 'role[base],role[iisserver]'
34
62
  knife bootstrap windows ssh winboxB -x Administrator -P 'super_secret_password' -r 'role[base],role[iisserver]'
35
63
  knife bootstrap windows ssh winboxC -x Administrator -P 'super_secret_password' -r 'role[base],role[iisserver]'
64
+ knife ec2 server create -S mray -i ~/.ssh/mray.pem -x ubuntu -G default -I ami-8af0f326 -f m1.medium -j '{"tags":["amazon+rolemysql"]}' -r 'role[mysql]'
65
+ knife ec2 server create -S mray -i ~/.ssh/mray.pem -x ubuntu -G default -I ami-7000f019 -f m1.small -j '{"tags":["amazon+rolewebserverrecipemysqlclient"]}' -r 'role[webserver],recipe[mysql::client]'
66
+ knife ec2 server create -S mray -i ~/.ssh/mray.pem -x ubuntu -G default -I ami-7000f019 -f m1.small -j '{"tags":["amazon+rolewebserverrecipemysqlclient"]}' -r 'role[webserver],recipe[mysql::client]'
67
+ knife ec2 server create -S mray -i ~/.ssh/mray.pem -x ubuntu -G default -I ami-7000f019 -f m1.small -j '{"tags":["amazon+rolewebserverrecipemysqlclient"]}' -r 'role[webserver],recipe[mysql::client]'
36
68
  OUTPUT
37
69
 
38
70
  @spiceweasel_binary = File.join(File.dirname(__FILE__), *%w[.. .. bin spiceweasel])
39
71
  end
40
72
 
41
73
  it "maintains consistent output from the example config" do
42
- `#{@spiceweasel_binary} --novalidation --dryrun example.yml`.should == @expected_output
74
+ `#{@spiceweasel_binary} -r --novalidation examples/example.yml`.should == @expected_output
43
75
  end
44
76
  end
metadata CHANGED
@@ -1,20 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spiceweasel
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 2.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Matt Ray
9
- - Elliot Crosby-McCullough
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2012-09-06 00:00:00.000000000Z
12
+ date: 2013-01-08 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: json
17
- requirement: &70331172604580 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
18
17
  none: false
19
18
  requirements:
20
19
  - - ! '>='
@@ -22,10 +21,15 @@ dependencies:
22
21
  version: '0'
23
22
  type: :runtime
24
23
  prerelease: false
25
- version_requirements: *70331172604580
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
26
30
  - !ruby/object:Gem::Dependency
27
31
  name: mixlib-cli
28
- requirement: &70331172604160 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
29
33
  none: false
30
34
  requirements:
31
35
  - - ! '>='
@@ -33,10 +37,79 @@ dependencies:
33
37
  version: '0'
34
38
  type: :runtime
35
39
  prerelease: false
36
- version_requirements: *70331172604160
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: mixlib-config
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
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: mixlib-log
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
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
+ - !ruby/object:Gem::Dependency
79
+ name: mixlib-shellout
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: chef
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
37
110
  - !ruby/object:Gem::Dependency
38
111
  name: rspec
39
- requirement: &70331172603740 !ruby/object:Gem::Requirement
112
+ requirement: !ruby/object:Gem::Requirement
40
113
  none: false
41
114
  requirements:
42
115
  - - ! '>='
@@ -44,32 +117,41 @@ dependencies:
44
117
  version: '0'
45
118
  type: :development
46
119
  prerelease: false
47
- version_requirements: *70331172603740
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
48
126
  description: Provides a CLI tool for generating knife commands to build Chef-managed
49
- infrastructure from a simple YAML or JSON file.
127
+ infrastructure from a simple JSON or YAML file.
50
128
  email:
51
129
  - matt@opscode.com
52
- - elliot.cm@gmail.com
53
130
  executables:
54
131
  - spiceweasel
55
132
  extensions: []
56
133
  extra_rdoc_files: []
57
134
  files:
135
+ - LICENSE
136
+ - README.md
58
137
  - bin/spiceweasel
59
138
  - lib/spiceweasel/cli.rb
60
- - lib/spiceweasel/cookbook_data.rb
61
- - lib/spiceweasel/cookbook_list.rb
62
- - lib/spiceweasel/data_bag_list.rb
63
- - lib/spiceweasel/directory_extractor.rb
64
- - lib/spiceweasel/environment_list.rb
65
- - lib/spiceweasel/node_list.rb
66
- - lib/spiceweasel/role_list.rb
139
+ - lib/spiceweasel/clusters.rb
140
+ - lib/spiceweasel/config.rb
141
+ - lib/spiceweasel/cookbooks.rb
142
+ - lib/spiceweasel/data_bags.rb
143
+ - lib/spiceweasel/environments.rb
144
+ - lib/spiceweasel/execute.rb
145
+ - lib/spiceweasel/extract_local.rb
146
+ - lib/spiceweasel/log.rb
147
+ - lib/spiceweasel/nodes.rb
148
+ - lib/spiceweasel/roles.rb
67
149
  - lib/spiceweasel/version.rb
68
150
  - lib/spiceweasel.rb
69
- - README.md
70
151
  - spec/bin/spiceweasel_spec.rb
71
- homepage: http://github.com/mattray/spiceweasel
72
- licenses: []
152
+ homepage: https://github.com/mattray/spiceweasel
153
+ licenses:
154
+ - Apache
73
155
  post_install_message:
74
156
  rdoc_options: []
75
157
  require_paths:
@@ -87,11 +169,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
87
169
  - !ruby/object:Gem::Version
88
170
  version: '0'
89
171
  requirements: []
90
- rubyforge_project: spiceweasel
91
- rubygems_version: 1.8.15
172
+ rubyforge_project:
173
+ rubygems_version: 1.8.24
92
174
  signing_key:
93
175
  specification_version: 3
94
- summary: CLI for generating Chef knife commands from a simple YAML file.
176
+ summary: CLI for generating Chef knife commands from a simple JSON or YAML file.
95
177
  test_files:
96
178
  - spec/bin/spiceweasel_spec.rb
97
- has_rdoc: