spiceweasel 0.7.1 → 0.8

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.
data/README.md CHANGED
@@ -2,6 +2,8 @@ Description
2
2
  ===========
3
3
  Spiceweasel is a command-line tool for batch loading Chef infrastructure. It provides a simple syntax in either JSON or YAML for describing and deploying infrastructure in order with the Chef command-line tool `knife`.
4
4
 
5
+ The `examples` directory provides examples based on the Quick Starts provided at [http://help.opscode.com/kb/otherhelp](http://help.opscode.com/kb/otherhelp).
6
+
5
7
  CHANGELOG.md covers current, previous and future development milestones and contains the features backlog.
6
8
 
7
9
  Requirements
@@ -12,7 +14,7 @@ Written with Chef 0.9.12 and 0.10.0 and supports cookbooks, environments, roles,
12
14
 
13
15
  Testing
14
16
  -------
15
- Tested with Ubuntu 10.04 and 10.10 and Chef 0.9.16 and 0.10.0.rc.1.
17
+ Tested with Ubuntu 10.04 and Chef 0.9.16 and 0.10.2.
16
18
 
17
19
  File Syntax
18
20
  ===========
data/bin/spiceweasel CHANGED
@@ -1,92 +1,17 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'json'
4
- require 'mixlib/cli'
5
- require 'spiceweasel/version'
6
4
  require 'yaml'
7
5
 
8
- #ensure that the run_list contents are present in either the cookbooks or roles
9
- def validate_run_list(run_list, cookbooks, environments, roles)
10
- run_list.each do |item|
11
- if item.start_with?("recipe")
12
- #recipe[foo] or recipe[foo::bar]
13
- recipe = item.slice(7..-2).split("::")[0]
14
- unless cookbooks.member?(recipe)
15
- raise "'#{item}' is an invalid run_list recipe not managed by spiceweasel"
16
- exit(-1)
17
- end
18
- elsif item.start_with?("environment")
19
- #environment[blah]
20
- environment = item.slice(12..-2)
21
- unless environments.member?(environment)
22
- raise "'#{item}' is an invalid run_list environment not managed by spiceweasel"
23
- exit(-1)
24
- end
25
- elsif item.start_with?("role")
26
- #role[blah]
27
- role = item.slice(5..-2)
28
- unless roles.member?(role)
29
- raise "'#{item}' is an invalid run_list role not managed by spiceweasel"
30
- exit(-1)
31
- end
32
- else
33
- raise "'#{item}' is an invalid run_list component"
34
- exit(-1)
35
- end
36
- end
37
- end
38
-
39
- class SpiceweaselCLI
40
- include Mixlib::CLI
41
-
42
- banner("Usage: spiceweasel [option] file")
43
-
44
- option :debug,
45
- :long => "--debug",
46
- :description => "Verbose debugging messages.",
47
- :boolean => true
48
-
49
- option :delete,
50
- :short => "-d",
51
- :long => "--delete",
52
- :description => "Print the knife commands to be delete the infrastructure",
53
- :boolean => true
54
-
55
- option :dryrun,
56
- :long => "--dryrun",
57
- :description => "Print the knife commands to be executed to STDOUT",
58
- :boolean => true
59
-
60
- option :help,
61
- :short => "-h",
62
- :long => "--help",
63
- :description => "Show this message",
64
- :on => :tail,
65
- :boolean => true,
66
- :show_options => true,
67
- :exit => 0
68
-
69
- option :rebuild,
70
- :short => "-r",
71
- :long => "--rebuild",
72
- :description => "Print the knife commands to be delete and recreate the infrastructure",
73
- :boolean => true
74
-
75
- option :version,
76
- :short => "-v",
77
- :long => "--version",
78
- :description => "Version",
79
- :boolean => true,
80
- :proc => lambda {|v| puts "Spiceweasel: #{Spiceweasel::VERSION}" },
81
- :exit => 0
82
- end
6
+ require 'spiceweasel'
83
7
 
84
8
  #process command line options
85
9
  begin
86
- ARGV << "-h" if ARGV.empty?
87
- cli = SpiceweaselCLI.new
10
+ ARGV << "-h" if ARGV.empty?
11
+ cli = Spiceweasel::CLI.new
88
12
  cli.parse_options
89
- rescue OptionParser::InvalidOption => e
13
+ DEBUG = cli.config[:debug]
14
+ rescue OptionParser::InvalidOption => e
90
15
  STDERR.puts e.message
91
16
  puts cli.opt_parser.to_s
92
17
  exit(-1)
@@ -94,7 +19,7 @@ end
94
19
 
95
20
  begin
96
21
  file = ARGV.last
97
- STDOUT.puts "DEBUG: file: #{file}" if cli.config[:debug]
22
+ STDOUT.puts "DEBUG: file: #{file}" if cli.config[:debug]
98
23
  if (file.end_with?(".yml"))
99
24
  input = YAML.load_file ARGV.last
100
25
  elsif (file.end_with?(".json"))
@@ -116,130 +41,35 @@ end
116
41
  create = String.new()
117
42
  delete = String.new()
118
43
 
119
- #cookbooks
120
- cookbooks = input['cookbooks'] || []
121
- cookbook_list = []
122
- cookbooks.each do |cookbook|
123
- cb = cookbook.keys.first
124
- if cookbook[cb] and cookbook[cb].length > 0
125
- version = cookbook[cb][0].to_s || ""
126
- args = cookbook[cb][1] || ""
127
- end
128
- STDOUT.puts "DEBUG: cookbook: #{cb} #{version}" if cli.config[:debug]
129
- delete += "knife cookbook delete #{cb} #{version} -y\n"
130
- if File.directory?("cookbooks")
131
- if version and File.directory?("cookbooks/#{cb}")
132
- #check metadata.rb for requested version
133
- metadata = File.open("cookbooks/#{cb}/metadata.rb").grep(/^version/)[0].split()[1].gsub(/"/,'').to_s
134
- if (metadata != version)
135
- raise "Invalid version #{version} of '#{cb}' requested, #{metadata} is already in the cookbooks directory."
136
- exit(-1)
137
- end
138
- elsif !File.directory?("cookbooks/#{cb}")
139
- create += "knife cookbook site download #{cb} #{version} --file cookbooks/#{cb}.tgz #{args}\n"
140
- create += "tar -C cookbooks/ -xf cookbooks/#{cb}.tgz\n"
141
- end
142
- else
143
- STDERR.puts "cookbooks directory not found, validation and downloading skipped"
144
- end
145
- create += "knife cookbook upload #{cb}\n"
146
- #flatten list of cookbooks for validation later
147
- cookbook_list.push(cb)
148
- end
44
+ cookbook_list = Spiceweasel::CookbookList.new(input['cookbooks'])
45
+ environment_list = Spiceweasel::EnvironmentList.new(input['environments'])
46
+ role_list = Spiceweasel::RoleList.new(input['roles'])
47
+ data_bag_list = Spiceweasel::DataBagList.new(input['data bags'])
149
48
 
150
- #environments
151
- environments = input['environments'] || []
152
- environment_list = []
153
- environments.each do |environment|
154
- STDOUT.puts "DEBUG: environment: #{environment.keys[0]}" if cli.config[:debug]
155
- delete += "knife environment delete #{environment.keys[0]} -y\n"
156
- create += "knife environment from file #{environment.keys[0]}.rb\n"
157
- #flatten list of environments for validation later
158
- environment_list.push(environment.keys[0])
159
- end
49
+ node_list = Spiceweasel::NodeList.new(input['nodes'], cookbook_list, environment_list, role_list)
160
50
 
161
- #roles
162
- roles = input['roles'] || []
163
- role_list = []
164
- roles.each do |role|
165
- STDOUT.puts "DEBUG: role: #{role.keys[0]}" if cli.config[:debug]
166
- delete += "knife role delete #{role.keys[0]} -y\n"
167
- create += "knife role from file #{role.keys[0]}.rb\n"
168
- #flatten list of roles for validation later
169
- role_list.push(role.keys[0])
170
- end
51
+ create += cookbook_list.create
52
+ create += environment_list.create
53
+ create += role_list.create
54
+ create += data_bag_list.create
55
+ create += node_list.create
171
56
 
172
- #data bags
173
- bags = input['data bags'] || []
174
- bags.each do |bag|
175
- STDOUT.puts "DEBUG: data bag: #{bag.keys[0]}" if cli.config[:debug]
176
- delete += "knife data bag delete #{bag.keys[0]} -y\n"
177
- create += "knife data bag create #{bag.keys[0]}\n"
178
- items = bag[bag.keys[0]] || []
179
- secret = nil
180
- while item = items.shift
181
- STDOUT.puts "DEBUG: data bag #{bag.keys[0]} item: #{item}" if cli.config[:debug]
182
- if item.start_with?("secret")
183
- secret = item.split()[1]
184
- next
185
- end
186
- if item =~ /\*/ #wildcard support
187
- files = Dir.glob("data_bags/#{bag.keys[0]}/#{item}.json")
188
- items += files.collect {|x| x[x.rindex('/')+1..-6]}
189
- puts items
190
- next
191
- end
192
- if secret
193
- create += "knife data bag from file #{bag.keys[0]} data_bags/#{bag.keys[0]}/#{item}.json --secret-file #{secret}\n"
194
- else
195
- create += "knife data bag from file #{bag.keys[0]} data_bags/#{bag.keys[0]}/#{item}.json\n"
196
- end
197
- end
198
- end
199
-
200
- nodes = input['nodes'] || []
201
- #currently use bulk_delete for deleting, add provider support real soon
202
- delete += "knife node bulk_delete .* -y\n"
203
- nodes.each do |node|
204
- STDOUT.puts "DEBUG: node: #{node.keys[0]}" if cli.config[:debug]
205
- # delete += "knife node delete #{node[node.keys[0]}\n"
206
- run_list = node[node.keys[0]][0].gsub(/ /,',').split(',')
207
- STDOUT.puts "DEBUG: node run_list: #{run_list}" if cli.config[:debug]
208
- validate_run_list(run_list, cookbook_list, environment_list, role_list)
209
- #provider support
210
- if node.keys[0].start_with?("bluebox","ec2","openstack","rackspace","slicehost","terremark")
211
- provider = node.keys[0].split()
212
- count = 1
213
- if (provider.length == 2)
214
- count = provider[1]
215
- end
216
- #create the instances
217
- count.to_i.times do
218
- create += "knife #{provider[0]} server create #{node[node.keys[0]][1]}"
219
- if run_list.length > 0
220
- create += " -r '#{node[node.keys[0]][0].gsub(/ /,',')}'\n"
221
- end
222
- end
223
- else #multinode support
224
- node.keys[0].split.each do |server|
225
- create += "knife bootstrap #{server} #{node[node.keys[0]][1]}"
226
- if run_list.length > 0
227
- create += " -r '#{node[node.keys[0]][0].gsub(/ /,',')}'\n"
228
- end
229
- end
230
- end
231
- end
57
+ delete += cookbook_list.delete
58
+ delete += environment_list.delete
59
+ delete += role_list.delete
60
+ delete += data_bag_list.delete
61
+ delete += node_list.delete
232
62
 
233
63
  #just print the knife commands, do not execute
234
64
  #if cli.config[:dryrun]
235
- if cli.config[:delete]
65
+ if cli.config[:delete]
236
66
  puts delete unless delete.empty?
237
67
  elsif cli.config[:rebuild]
238
68
  puts delete unless delete.empty?
239
69
  puts create unless create.empty?
240
70
  else
241
71
  puts create unless create.empty?
242
- end
72
+ end
243
73
  #else
244
74
  #eventually we will execute instead of printing knife commands
245
75
  #puts "BAM!"
data/lib/spiceweasel.rb CHANGED
@@ -1,3 +1,9 @@
1
1
  module Spiceweasel
2
- # Your code goes here...
2
+ autoload :CLI, 'spiceweasel/cli'
3
+ autoload :RunList, 'spiceweasel/run_list'
4
+ autoload :CookbookList, 'spiceweasel/cookbook_list'
5
+ autoload :EnvironmentList, 'spiceweasel/environment_list'
6
+ autoload :RoleList, 'spiceweasel/role_list'
7
+ autoload :DataBagList, 'spiceweasel/data_bag_list'
8
+ autoload :NodeList, 'spiceweasel/node_list'
3
9
  end
@@ -0,0 +1,47 @@
1
+ require 'mixlib/cli'
2
+ require 'spiceweasel/version'
3
+
4
+ class Spiceweasel::CLI
5
+ include Mixlib::CLI
6
+
7
+ banner("Usage: spiceweasel [option] file")
8
+
9
+ option :debug,
10
+ :long => "--debug",
11
+ :description => "Verbose debugging messages.",
12
+ :boolean => true
13
+
14
+ option :delete,
15
+ :short => "-d",
16
+ :long => "--delete",
17
+ :description => "Print the knife commands to be delete the infrastructure",
18
+ :boolean => true
19
+
20
+ option :dryrun,
21
+ :long => "--dryrun",
22
+ :description => "Print the knife commands to be executed to STDOUT",
23
+ :boolean => true
24
+
25
+ option :help,
26
+ :short => "-h",
27
+ :long => "--help",
28
+ :description => "Show this message",
29
+ :on => :tail,
30
+ :boolean => true,
31
+ :show_options => true,
32
+ :exit => 0
33
+
34
+ option :rebuild,
35
+ :short => "-r",
36
+ :long => "--rebuild",
37
+ :description => "Print the knife commands to be delete and recreate the infrastructure",
38
+ :boolean => true
39
+
40
+ option :version,
41
+ :short => "-v",
42
+ :long => "--version",
43
+ :description => "Version",
44
+ :boolean => true,
45
+ :proc => lambda {|v| puts "Spiceweasel: #{Spiceweasel::VERSION}" },
46
+ :exit => 0
47
+ end
@@ -0,0 +1,39 @@
1
+ class Spiceweasel::CookbookList
2
+ def initialize(cookbooks = [])
3
+ @create = @delete = ''
4
+ @cookbooks = []
5
+ cookbooks.each do |cookbook|
6
+ cb = cookbook.keys.first
7
+ if cookbook[cb] and cookbook[cb].length > 0
8
+ version = cookbook[cb][0].to_s || ""
9
+ args = cookbook[cb][1] || ""
10
+ end
11
+ STDOUT.puts "DEBUG: cookbook: #{cb} #{version}" if DEBUG
12
+ @delete += "knife cookbook @delete #{cb} #{version} -y\n"
13
+ if File.directory?("cookbooks")
14
+ if version and File.directory?("cookbooks/#{cb}")
15
+ #check metadata.rb for requested version
16
+ metadata = File.open("cookbooks/#{cb}/metadata.rb").grep(/^version/)[0].split()[1].gsub(/"/,'').to_s
17
+ if (metadata != version)
18
+ raise "Invalid version #{version} of '#{cb}' requested, #{metadata} is already in the cookbooks directory."
19
+ exit(-1)
20
+ end
21
+ elsif !File.directory?("cookbooks/#{cb}")
22
+ @create += "knife cookbook site download #{cb} #{version} --file cookbooks/#{cb}.tgz #{args}\n"
23
+ @create += "tar -C cookbooks/ -xf cookbooks/#{cb}.tgz\n"
24
+ end
25
+ else
26
+ STDERR.puts "cookbooks directory not found, validation and downloading skipped"
27
+ end
28
+ @create += "knife cookbook upload #{cb}\n"
29
+
30
+ @cookbooks << cb
31
+ end
32
+ end
33
+
34
+ attr_reader :cookbooks, :create, :delete
35
+
36
+ def member?(cookbook)
37
+ cookbooks.include?(cookbook)
38
+ end
39
+ end
@@ -0,0 +1,32 @@
1
+ class Spiceweasel::DataBagList
2
+ def initialize(data_bags = [])
3
+ @create = @delete = ''
4
+ data_bags.each do |data_bag|
5
+ STDOUT.puts "DEBUG: data bag: #{data_bag.keys[0]}" if DEBUG
6
+ @delete += "knife data bag delete #{data_bag.keys[0]} -y\n"
7
+ @create += "knife data bag create #{data_bag.keys[0]}\n"
8
+ items = data_bag[data_bag.keys[0]] || []
9
+ secret = nil
10
+ while item = items.shift
11
+ STDOUT.puts "DEBUG: data bag #{data_bag.keys[0]} item: #{item}" if DEBUG
12
+ if item.start_with?("secret")
13
+ secret = item.split()[1]
14
+ next
15
+ end
16
+ if item =~ /\*/ #wildcard support
17
+ files = Dir.glob("data_bags/#{data_bag.keys[0]}/#{item}.json")
18
+ items += files.collect {|x| x[x.rindex('/')+1..-6]}
19
+ puts items
20
+ next
21
+ end
22
+ if secret
23
+ @create += "knife data bag from file #{data_bag.keys[0]} data_bags/#{data_bag.keys[0]}/#{item}.json --secret-file #{secret}\n"
24
+ else
25
+ @create += "knife data bag from file #{data_bag.keys[0]} data_bags/#{data_bag.keys[0]}/#{item}.json\n"
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ attr_reader :create, :delete
32
+ end
@@ -0,0 +1,18 @@
1
+ class Spiceweasel::EnvironmentList
2
+ def initialize(environments = [])
3
+ @create = @delete = ''
4
+ @environments = []
5
+ environments.each do |environment|
6
+ STDOUT.puts "DEBUG: environment: #{environment.keys[0]}" if DEBUG
7
+ @delete += "knife environment delete #{environment.keys[0]} -y\n"
8
+ @create += "knife environment from file #{environment.keys[0]}.rb\n"
9
+ @environments << environment.keys[0]
10
+ end
11
+ end
12
+
13
+ attr_reader :environments, :create, :delete
14
+
15
+ def member?(environment)
16
+ environments.include?(environment)
17
+ end
18
+ end
@@ -0,0 +1,38 @@
1
+ class Spiceweasel::NodeList
2
+ def initialize(nodes, cookbook_list, environment_list, role_list)
3
+ nodes ||= []
4
+ @create = @delete = ''
5
+
6
+ @delete += "knife node bulk_delete .* -y\n"
7
+ nodes.each do |node|
8
+ STDOUT.puts "DEBUG: node: #{node.keys[0]}" if DEBUG
9
+ run_list = node[node.keys[0]][0].gsub(/ /,',').split(',')
10
+ STDOUT.puts "DEBUG: node run_list: #{run_list}" if DEBUG
11
+ Spiceweasel::RunList.new(run_list).validate(cookbook_list, environment_list, role_list)
12
+ #provider support
13
+ if node.keys[0].start_with?("bluebox","ec2","openstack","rackspace","slicehost","terremark")
14
+ provider = node.keys[0].split()
15
+ count = 1
16
+ if (provider.length == 2)
17
+ count = provider[1]
18
+ end
19
+ #create the instances
20
+ count.to_i.times do
21
+ @create += "knife #{provider[0]} server create #{node[node.keys[0]][1]}"
22
+ if run_list.length > 0
23
+ @create += " -r '#{node[node.keys[0]][0].gsub(/ /,',')}'\n"
24
+ end
25
+ end
26
+ else #multinode support
27
+ node.keys[0].split.each do |server|
28
+ @create += "knife bootstrap #{server} #{node[node.keys[0]][1]}"
29
+ if run_list.length > 0
30
+ @create += " -r '#{node[node.keys[0]][0].gsub(/ /,',')}'\n"
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ attr_reader :create, :delete
38
+ end
@@ -0,0 +1,18 @@
1
+ class Spiceweasel::RoleList
2
+ def initialize(roles = [])
3
+ @create = @delete = ''
4
+ @roles = []
5
+ roles.each do |role|
6
+ STDOUT.puts "DEBUG: role: #{role.keys[0]}" if DEBUG
7
+ @delete += "knife role delete #{role.keys[0]} -y\n"
8
+ @create += "knife role from file #{role.keys[0]}.rb\n"
9
+ @roles << role.keys[0]
10
+ end
11
+ end
12
+
13
+ attr_reader :roles, :create, :delete
14
+
15
+ def member?(role)
16
+ roles.include?(role)
17
+ end
18
+ end
@@ -0,0 +1,36 @@
1
+ class Spiceweasel::RunList
2
+ def initialize(run_list)
3
+ @run_list = run_list
4
+ end
5
+
6
+ def validate(cookbooks, environments, roles)
7
+ @run_list.each do |item|
8
+ if item.start_with?("recipe")
9
+ #recipe[foo] or recipe[foo::bar]
10
+ recipe = item.slice(7..-2).split("::")[0]
11
+ unless cookbooks.member?(recipe)
12
+ raise "'#{item}' is an invalid run_list recipe not managed by spiceweasel"
13
+ exit(-1)
14
+ end
15
+ elsif item.start_with?("environment")
16
+ #environment[blah]
17
+ environment = item.slice(12..-2)
18
+ unless environments.member?(environment)
19
+ raise "'#{item}' is an invalid run_list environment not managed by spiceweasel"
20
+ exit(-1)
21
+ end
22
+ elsif item.start_with?("role")
23
+ #role[blah]
24
+ role = item.slice(5..-2)
25
+ unless roles.member?(role)
26
+ raise "'#{item}' is an invalid run_list role not managed by spiceweasel"
27
+ exit(-1)
28
+ end
29
+ else
30
+ raise "'#{item}' is an invalid run_list component"
31
+ exit(-1)
32
+ end
33
+ end
34
+ end
35
+
36
+ end
@@ -1,3 +1,3 @@
1
1
  module Spiceweasel
2
- VERSION = "0.7.1"
2
+ VERSION = "0.8"
3
3
  end
@@ -0,0 +1,39 @@
1
+ # Cover-all spec to prevent regressions during refactor
2
+ describe 'The Spiceweasel binary' do
3
+ before(:each) do
4
+ @expected_output = <<-OUTPUT
5
+ knife cookbook upload apache2
6
+ knife cookbook upload apt
7
+ knife cookbook upload mysql
8
+ knife environment from file development.rb
9
+ knife environment from file qa.rb
10
+ knife environment from file production.rb
11
+ knife role from file base.rb
12
+ knife role from file monitoring.rb
13
+ knife role from file webserver.rb
14
+ knife data bag create users
15
+ knife data bag from file users data_bags/users/alice.json
16
+ knife data bag from file users data_bags/users/bob.json
17
+ knife data bag from file users data_bags/users/chuck.json
18
+ knife data bag create data
19
+ knife data bag create passwords
20
+ knife data bag from file passwords data_bags/passwords/mysql.json --secret-file secret_key
21
+ knife data bag from file passwords data_bags/passwords/rabbitmq.json --secret-file secret_key
22
+ knife bootstrap serverA -i ~/.ssh/mray.pem -x user --sudo -d ubuntu10.04-gems -r 'role[base]'
23
+ knife bootstrap serverB -i ~/.ssh/mray.pem -x user --sudo -d ubuntu10.04-gems -r 'role[base]'
24
+ knife bootstrap serverC -i ~/.ssh/mray.pem -x user --sudo -d ubuntu10.04-gems -r 'role[base]'
25
+ 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]'
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 rackspace server create --image 49 --flavor 2 -r 'recipe[mysql],role[monitoring]'
29
+ knife rackspace server create --image 49 --flavor 2 -r 'recipe[mysql],role[monitoring]'
30
+ knife rackspace server create --image 49 --flavor 2 -r 'recipe[mysql],role[monitoring]'
31
+ OUTPUT
32
+
33
+ @spiceweasel_binary = File.join(File.dirname(__FILE__), *%w[.. .. bin spiceweasel])
34
+ end
35
+
36
+ it "maintains consistent output from the example config" do
37
+ `#{@spiceweasel_binary} --dryrun example.yml`.should == @expected_output
38
+ end
39
+ end
metadata CHANGED
@@ -1,27 +1,62 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spiceweasel
3
3
  version: !ruby/object:Gem::Version
4
- hash: 1
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 7
9
- - 1
10
- version: 0.7.1
4
+ version: "0.8"
11
5
  platform: ruby
12
6
  authors:
13
7
  - Matt Ray
8
+ - Elliot Crosby-McCullough
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
12
 
18
- date: 2011-05-05 00:00:00 -05:00
13
+ date: 2011-07-21 00:00:00 -05:00
19
14
  default_executable:
20
- dependencies: []
21
-
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: chef
18
+ type: :runtime
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
25
+ version:
26
+ - !ruby/object:Gem::Dependency
27
+ name: json
28
+ type: :runtime
29
+ version_requirement:
30
+ version_requirements: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ version:
36
+ - !ruby/object:Gem::Dependency
37
+ name: mixlib-cli
38
+ type: :runtime
39
+ version_requirement:
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: "0"
45
+ version:
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ type: :development
49
+ version_requirement:
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ version:
22
56
  description: This provides a CLI for generating knife commands to build Chef-managed infrastructure from a simple YAML file.
23
57
  email:
24
58
  - matt@opscode.com
59
+ - elliot.cm@gmail.com
25
60
  executables:
26
61
  - spiceweasel
27
62
  extensions: []
@@ -29,20 +64,19 @@ extensions: []
29
64
  extra_rdoc_files: []
30
65
 
31
66
  files:
32
- - .gitignore
33
- - CHANGELOG.md
34
- - Gemfile
35
- - README.md
36
- - Rakefile
37
67
  - bin/spiceweasel
38
- - example.json
39
- - example.yml
40
- - lib/spiceweasel.rb
68
+ - lib/spiceweasel/cli.rb
69
+ - lib/spiceweasel/cookbook_list.rb
70
+ - lib/spiceweasel/data_bag_list.rb
71
+ - lib/spiceweasel/environment_list.rb
72
+ - lib/spiceweasel/node_list.rb
73
+ - lib/spiceweasel/role_list.rb
74
+ - lib/spiceweasel/run_list.rb
41
75
  - lib/spiceweasel/version.rb
42
- - spiceweasel.gemspec
43
- - test.sh
76
+ - lib/spiceweasel.rb
77
+ - README.md
44
78
  has_rdoc: true
45
- homepage: ""
79
+ homepage: http://github.com/mattray/spiceweasel
46
80
  licenses: []
47
81
 
48
82
  post_install_message:
@@ -51,29 +85,23 @@ rdoc_options: []
51
85
  require_paths:
52
86
  - lib
53
87
  required_ruby_version: !ruby/object:Gem::Requirement
54
- none: false
55
88
  requirements:
56
89
  - - ">="
57
90
  - !ruby/object:Gem::Version
58
- hash: 3
59
- segments:
60
- - 0
61
91
  version: "0"
92
+ version:
62
93
  required_rubygems_version: !ruby/object:Gem::Requirement
63
- none: false
64
94
  requirements:
65
95
  - - ">="
66
96
  - !ruby/object:Gem::Version
67
- hash: 3
68
- segments:
69
- - 0
70
97
  version: "0"
98
+ version:
71
99
  requirements: []
72
100
 
73
101
  rubyforge_project: spiceweasel
74
- rubygems_version: 1.3.7
102
+ rubygems_version: 1.3.5
75
103
  signing_key:
76
104
  specification_version: 3
77
105
  summary: CLI for generating Chef knife commands from a simple YAML file.
78
- test_files: []
79
-
106
+ test_files:
107
+ - spec/bin/spiceweasel_spec.rb
data/.gitignore DELETED
@@ -1,4 +0,0 @@
1
- *.gem
2
- .bundle
3
- Gemfile.lock
4
- pkg/*
data/CHANGELOG.md DELETED
@@ -1,83 +0,0 @@
1
- This is the current, previous and future development milestones and contains the features backlog.
2
-
3
- 0.1
4
- ===
5
- * initial README.md describing goals
6
- * command-line tool
7
- * basic options all supported
8
- * create repo on GitHub
9
- * publish as a gem on RubyGems
10
-
11
- 0.2
12
- ===
13
- * switch to mixlib-cli
14
- * --dryrun The option `--dryrun` will print the commands to run, but not actually execute them (the default behavior)
15
- * --delete The option `--delete` will delete each cookbook, role, data bag, environment and node described in the yml file. All nodes from the system are deleted with `knife node bulk_delete`.
16
- * --rebuild The option `--rebuild` will remove all currently managed infrastructure for this chef repository and rebuild it from scratch.
17
-
18
- 0.3
19
- ===
20
- * renamed MILESTONES.md to CHANGELOG.md
21
- * fixed version number
22
- * updated YAML schema and examples because Ruby 1.8 does not order hashes.
23
- * validate that the recipes and roles listed in the nodes are loaded
24
-
25
- 0.4
26
- ===
27
- * support versions for cookbooks
28
- * support site vendor for cookbooks
29
-
30
- 0.5
31
- ===
32
- * support JSON and YAML
33
-
34
- 0.6
35
- ===
36
- * add support for cookbook options
37
-
38
- 0.7
39
- =============
40
- * add support for environments
41
- * rescue from parser errors
42
- * update cookbook download syntax
43
- * multiple nodes with same runlists syntax
44
- * add support for encrypted data bags
45
- * wildcard support for data bag items
46
-
47
- 0.7.1 *CURRENT*
48
- ===============
49
- * fixed run list parsing
50
- * updated examples for Chef 0.10
51
- * relaxed validation on existing cookbooks
52
-
53
- BACKLOG
54
- =======
55
- Next
56
- ----
57
- * make spiceweasel a library rather than an executable
58
- * switch to using lib/ directory
59
- * convert to a knife plugin
60
- * knife batch create from file infrastructure.yml
61
- * knife batch delete from file infrastructure.json
62
- * knife batch rebuild from file infrastructure.yml
63
- Future
64
- ------
65
- * --chef-client The option `--chef-client` will make a `knife ssh` call to each box and run `chef-client` on each.
66
- * --chef-client validation that nodes are added
67
- * -e/--execute execute the commands
68
- * catching return codes and retrying (with retry count?)
69
- * make the JSON calls directly with Chef APIs
70
- * execution-phase validation
71
- * check metadata.rb of cookbooks for their dependencies
72
- * validate within role files rather than the names of files (assumption that they are the same)
73
- * validate cookbooks referenced in roles
74
- * validate not trying to use environments with 0.9.x
75
- * validate within environment files rather than the names of files (assumption that they are the same)
76
- * validate cookbooks referenced in environments
77
- * validate recipes from cookbooks in run_lists
78
- * wildcards for environments and roles
79
- * on provider delete take count of vendor-specific, delete if match (ec2 server delete and node delete)
80
- * knife winrm bootstrap FQDN [RUN LIST...] (options)
81
- * use GNU parallel with knife?
82
- * extract existing infrastructure
83
- * knife batch extract
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- # Specify your gem's dependencies in spiceweasel.gemspec
4
- gemspec
data/Rakefile DELETED
@@ -1,2 +0,0 @@
1
- require 'bundler'
2
- Bundler::GemHelper.install_tasks
data/example.json DELETED
@@ -1,73 +0,0 @@
1
- {
2
- "cookbooks":
3
- [
4
- {"apache2":[]},
5
- {"apt":
6
- [
7
- "1.1.1"
8
- ]
9
- },
10
- {"mysql":[]}
11
- ],
12
- "environments":
13
- [
14
- {"development":[]},
15
- {"qa":[]},
16
- {"production":[]}
17
- ],
18
- "roles":
19
- [
20
- {"base":[]},
21
- {"monitoring":[]},
22
- {"webserver":[]}
23
- ],
24
- "data bags":
25
- [
26
- {"users":
27
- [
28
- "alice",
29
- "bob",
30
- "chuck"
31
- ]
32
- },
33
- {"data":
34
- [
35
- "*"
36
- ]
37
- },
38
- {"passwords":
39
- [
40
- "secret secret_key",
41
- "mysql",
42
- "rabbitmq"
43
- ]
44
- }
45
- ],
46
- "nodes":
47
- [
48
- {"serverA":
49
- [
50
- "role[base]",
51
- "-i ~/.ssh/mray.pem -x user --sudo -d ubuntu10.04-gems"
52
- ]
53
- },
54
- {"serverB serverC":
55
- [
56
- "role[base]",
57
- "-i ~/.ssh/mray.pem -x user --sudo -d ubuntu10.04-gems"
58
- ]
59
- },
60
- {"ec2 3":
61
- [
62
- "role[webserver] recipe[mysql::client]",
63
- "-S mray -i ~/.ssh/mray.pem -x ubuntu -G default -I ami-7000f019 -f m1.small"
64
- ]
65
- },
66
- {"rackspace 3":
67
- [
68
- "recipe[mysql],role[monitoring]",
69
- "--image 49 --flavor 2"
70
- ]
71
- }
72
- ]
73
- }
data/example.yml DELETED
@@ -1,41 +0,0 @@
1
- cookbooks:
2
- - apache2:
3
- - apt:
4
- - 1.1.1
5
- - mysql:
6
-
7
- environments:
8
- - development:
9
- - qa:
10
- - production:
11
-
12
- roles:
13
- - base:
14
- - monitoring:
15
- - webserver:
16
-
17
- data bags:
18
- - users:
19
- - alice
20
- - bob
21
- - chuck
22
- - data:
23
- - *
24
- - passwords:
25
- - secret secret_key
26
- - mysql
27
- - rabbitmq
28
-
29
- nodes:
30
- - serverA:
31
- - role[base]
32
- - -i ~/.ssh/mray.pem -x user --sudo -d ubuntu10.04-gems
33
- - serverB serverC:
34
- - role[base]
35
- - -i ~/.ssh/mray.pem -x user --sudo -d ubuntu10.04-gems
36
- - ec2 3:
37
- - role[webserver] recipe[mysql::client]
38
- - -S mray -i ~/.ssh/mray.pem -x ubuntu -G default -I ami-7000f019 -f m1.small
39
- - rackspace 3:
40
- - recipe[mysql],role[monitoring]
41
- - --image 49 --flavor 2
data/spiceweasel.gemspec DELETED
@@ -1,25 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require "json"
4
- require "mixlib/cli"
5
- require "spiceweasel/version"
6
- require "yaml"
7
-
8
-
9
- Gem::Specification.new do |s|
10
- s.name = "spiceweasel"
11
- s.version = Spiceweasel::VERSION
12
- s.platform = Gem::Platform::RUBY
13
- s.authors = ["Matt Ray"]
14
- s.email = ["matt@opscode.com"]
15
- s.homepage = ""
16
- s.summary = %q{CLI for generating Chef knife commands from a simple YAML file.}
17
- s.description = %q{This provides a CLI for generating knife commands to build Chef-managed infrastructure from a simple YAML file.}
18
-
19
- s.rubyforge_project = "spiceweasel"
20
-
21
- s.files = `git ls-files`.split("\n")
22
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
23
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
24
- s.require_paths = ["lib"]
25
- end
data/test.sh DELETED
@@ -1,48 +0,0 @@
1
- echo "------------>spiceweasel"
2
- spiceweasel
3
- echo "------------>Return code:$?"
4
- echo "------------>spiceweasel -h"
5
- spiceweasel -h
6
- echo "------------>Return code:$?"
7
- echo "------------>spiceweasel -h example.yml"
8
- spiceweasel -h example.yml
9
- echo "------------>Return code:$?"
10
- echo "------------>spiceweasel -v"
11
- spiceweasel -v
12
- echo "------------>Return code:$?"
13
- echo "------------>spiceweasel -v example.yml"
14
- spiceweasel -v example.yml
15
- echo "------------>Return code:$?"
16
- echo "------------>spiceweasel --version"
17
- spiceweasel --version
18
- echo "------------>Return code:$?"
19
- echo "------------>spiceweasel example.yml"
20
- spiceweasel example.yml
21
- echo "------------>Return code:$?"
22
- echo "------------>spiceweasel --dryrun"
23
- spiceweasel --dryrun
24
- echo "------------>Return code:$?"
25
- echo "------------>spiceweasel --dryrun example.yml"
26
- spiceweasel --dryrun example.yml
27
- echo "------------>Return code:$?"
28
- echo "------------>spiceweasel --help"
29
- spiceweasel --help
30
- echo "------------>Return code:$?"
31
- echo "------------>spiceweasel -d"
32
- spiceweasel -d
33
- echo "------------>Return code:$?"
34
- echo "------------>spiceweasel -d example.yml"
35
- spiceweasel -d example.yml
36
- echo "------------>Return code:$?"
37
- echo "------------>spiceweasel --delete example.yml"
38
- spiceweasel --delete example.yml
39
- echo "------------>Return code:$?"
40
- echo "------------>spiceweasel -r"
41
- spiceweasel -r
42
- echo "------------>Return code:$?"
43
- echo "------------>spiceweasel -r example.yml"
44
- spiceweasel -r example.yml
45
- echo "------------>Return code:$?"
46
- echo "------------>spiceweasel --rebuild example.yml"
47
- spiceweasel --rebuild example.yml
48
- echo "------------>Return code:$?"