spiceweasel 1.2.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/spiceweasel CHANGED
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # Author:: Matt Ray (<matt@opscode.com>)
5
5
  #
6
- # Copyright:: 2011, Opscode, Inc <legal@opscode.com>
6
+ # Copyright:: 2011-2012, Opscode, Inc <legal@opscode.com>
7
7
  #
8
8
  # Licensed under the Apache License, Version 2.0 (the "License");
9
9
  # you may not use this file except in compliance with the License.
@@ -18,108 +18,6 @@
18
18
  # limitations under the License.
19
19
  #
20
20
 
21
- require 'json'
22
- require 'yaml'
23
-
24
21
  require 'spiceweasel'
25
22
 
26
- options={'knife_options' => ''}
27
-
28
- #process command line options
29
- begin
30
- ARGV << "-h" if ARGV.empty?
31
- cli = Spiceweasel::CLI.new
32
- cli.parse_options
33
- Spiceweasel::DEBUG = cli.config[:debug]
34
- Spiceweasel::PARALLEL = cli.config[:parallel]
35
- Spiceweasel::SITEINSTALL = cli.config[:siteinstall]
36
- Spiceweasel::NOVALIDATION = cli.config[:novalidation]
37
- Spiceweasel::EXTRACTLOCAL = cli.config[:extractlocal]
38
- Spiceweasel::EXTRACTYAML = cli.config[:extractyaml]
39
- Spiceweasel::EXTRACTJSON = cli.config[:extractjson]
40
- rescue OptionParser::InvalidOption => e
41
- STDERR.puts e.message
42
- puts cli.opt_parser.to_s
43
- exit(-1)
44
- end
45
-
46
- if cli.config[:knifeconfig]
47
- options['knife_options'] += " -c " + cli.config[:knifeconfig]
48
- end
49
-
50
- if cli.config[:serverurl]
51
- options['knife_options'] += " --server-url " + cli.config[:serverurl]
52
- end
53
-
54
- if Spiceweasel::EXTRACTLOCAL || Spiceweasel::EXTRACTJSON || Spiceweasel::EXTRACTYAML
55
- input = Spiceweasel::DirectoryExtractor.parse_objects
56
- STDOUT.puts "DEBUG: extract input: #{input}" if Spiceweasel::DEBUG
57
- else
58
- begin
59
- file = ARGV.last
60
- STDOUT.puts "DEBUG: file: #{file}" if Spiceweasel::DEBUG
61
- if (file.end_with?(".yml"))
62
- input = YAML.load_file ARGV.last
63
- elsif (file.end_with?(".json"))
64
- input = JSON.parse(File.read(ARGV.last))
65
- else
66
- STDERR.puts "ERROR: Unknown file type, please use a file ending with either '.json' or '.yml'."
67
- exit(-1)
68
- end
69
- rescue Psych::SyntaxError => e
70
- STDERR.puts e.message
71
- STDERR.puts "ERROR: Parsing error in #{file}."
72
- exit(-1)
73
- rescue JSON::ParserError => e
74
- STDERR.puts e.message
75
- STDERR.puts "ERROR: Parsing error in #{file}."
76
- exit(-1)
77
- rescue Exception
78
- STDERR.puts "ERROR: No infrastructure .json or .yml file provided."
79
- puts cli.opt_parser.to_s
80
- exit(-1)
81
- end
82
- STDOUT.puts "DEBUG: file input: #{input}" if Spiceweasel::DEBUG
83
- end
84
-
85
- create = String.new()
86
- delete = String.new()
87
-
88
- cookbook_list = Spiceweasel::CookbookList.new(input['cookbooks'], options)
89
- environment_list = Spiceweasel::EnvironmentList.new(input['environments'], cookbook_list, options)
90
- role_list = Spiceweasel::RoleList.new(input['roles'], environment_list, cookbook_list, options)
91
- data_bag_list = Spiceweasel::DataBagList.new(input['data bags'], options)
92
- node_list = Spiceweasel::NodeList.new(input['nodes'], cookbook_list, environment_list, role_list, options)
93
-
94
- create += cookbook_list.create
95
- create += environment_list.create
96
- create += role_list.create
97
- create += data_bag_list.create
98
- create += node_list.create
99
-
100
- delete += cookbook_list.delete
101
- delete += environment_list.delete
102
- delete += role_list.delete
103
- delete += data_bag_list.delete
104
- delete += node_list.delete
105
-
106
- #just print the knife commands, do not execute
107
- #if cli.config[:dryrun]
108
- if cli.config[:delete]
109
- puts delete unless delete.empty?
110
- elsif cli.config[:rebuild]
111
- puts delete unless delete.empty?
112
- puts create unless create.empty?
113
- else
114
- if Spiceweasel::EXTRACTJSON
115
- puts JSON.pretty_generate(input)
116
- elsif Spiceweasel::EXTRACTYAML
117
- puts input.to_yaml
118
- else
119
- puts create unless create.empty?
120
- end
121
- end
122
- #else
123
- #eventually we will execute instead of printing knife commands
124
- #puts "BAM!"
125
- #end
23
+ Spiceweasel::CLI.new.run
data/lib/spiceweasel.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  #
2
2
  # Author:: Matt Ray (<matt@opscode.com>)
3
3
  #
4
- # Copyright:: 2011, Opscode, Inc <legal@opscode.com>
4
+ # Copyright:: 2011-2012, Opscode, Inc <legal@opscode.com>
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
7
7
  # you may not use this file except in compliance with the License.
@@ -16,13 +16,7 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
- module Spiceweasel
20
- autoload :CLI, 'spiceweasel/cli'
21
- autoload :CookbookList, 'spiceweasel/cookbook_list'
22
- autoload :EnvironmentList, 'spiceweasel/environment_list'
23
- autoload :RoleList, 'spiceweasel/role_list'
24
- autoload :DataBagList, 'spiceweasel/data_bag_list'
25
- autoload :NodeList, 'spiceweasel/node_list'
26
- autoload :DirectoryExtractor, 'spiceweasel/directory_extractor'
27
- autoload :CookbookData, 'spiceweasel/cookbook_data'
28
- end
19
+ require 'spiceweasel/version'
20
+ require 'spiceweasel/cli'
21
+ require 'spiceweasel/config'
22
+ require 'spiceweasel/log'
@@ -1,85 +1,251 @@
1
- require 'mixlib/cli'
2
- require 'spiceweasel/version'
3
-
4
- class Spiceweasel::CLI
5
- include Mixlib::CLI
6
-
7
- banner("Usage: spiceweasel [option] file\n spiceweasel [option] --extractlocal")
8
-
9
- option :extractlocal,
10
- :long => "--extractlocal",
11
- :description => "Use contents of local chef repository directories to generate knife commands to build infrastructure"
12
-
13
- option :extractjson,
14
- :long => "--extractjson",
15
- :description => "Use contents of local chef repository directories to generate JSON spiceweasel manifest"
16
-
17
- option :extractyaml,
18
- :long => "--extractyaml",
19
- :description => "Use contents of local chef repository directories to generate YAML spiceweasel manifest"
20
-
21
- option :debug,
22
- :long => "--debug",
23
- :description => "Verbose debugging messages",
24
- :boolean => true
25
-
26
- option :delete,
27
- :short => "-d",
28
- :long => "--delete",
29
- :description => "Print the knife commands to delete the infrastructure",
30
- :boolean => true
31
-
32
- option :dryrun,
33
- :long => "--dryrun",
34
- :description => "Print the knife commands to be executed to STDOUT",
35
- :boolean => true
36
-
37
- option :help,
38
- :short => "-h",
39
- :long => "--help",
40
- :description => "Show this message",
41
- :on => :tail,
42
- :boolean => true,
43
- :show_options => true,
44
- :exit => 0
45
-
46
- option :serverurl,
47
- :short => "-s URL",
48
- :long => "--server-url URL",
49
- :description => "Specify the Chef Server URL"
50
-
51
- option :knifeconfig,
52
- :short => "-c CONFIG",
53
- :long => "--knifeconfig CONFIG",
54
- :description => "Specify the knife.rb configuration file"
55
-
56
- option :novalidation,
57
- :long => "--novalidation",
58
- :description => "Disable validation",
59
- :boolean => true
60
-
61
- option :parallel,
62
- :long => "--parallel",
63
- :description => "Use the GNU 'parallel' command to parallelize 'knife VENDOR server create' commands that are not order-dependent",
64
- :boolean => true
65
-
66
- option :rebuild,
67
- :short => "-r",
68
- :long => "--rebuild",
69
- :description => "Print the knife commands to be delete and recreate the infrastructure",
70
- :boolean => true
71
-
72
- option :siteinstall,
73
- :long => "--siteinstall",
74
- :description => "Use the 'install' command with 'knife cookbook site' instead of the default 'download'",
75
- :boolean => true
76
-
77
- option :version,
78
- :short => "-v",
79
- :long => "--version",
80
- :description => "Show spiceweasel version",
81
- :boolean => true,
82
- :proc => lambda {|v| puts "Spiceweasel: #{Spiceweasel::VERSION}" },
83
- :exit => 0
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
+ #
84
18
 
19
+ require 'mixlib/cli'
20
+ require 'json'
21
+ require 'yaml'
22
+
23
+ require 'spiceweasel'
24
+ require 'spiceweasel/cookbooks'
25
+ require 'spiceweasel/environments'
26
+ require 'spiceweasel/roles'
27
+ require 'spiceweasel/data_bags'
28
+ require 'spiceweasel/nodes'
29
+ require 'spiceweasel/clusters'
30
+ require 'spiceweasel/extract_local'
31
+ require 'spiceweasel/execute'
32
+
33
+ module Spiceweasel
34
+ class CLI
35
+ include Mixlib::CLI
36
+
37
+ banner('Usage: spiceweasel [option] file
38
+ spiceweasel [option] --extractlocal')
39
+
40
+ option :clusterfile,
41
+ :long => '--cluster-file file',
42
+ :description => 'Specify an additional cluster manifest file, overriding any other node or cluster definitions'
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 delete the infrastructure',
53
+ :boolean => true
54
+
55
+ option :execute,
56
+ :short => '-e',
57
+ :long => '--execute',
58
+ :description => 'Execute the knife commands to create the infrastructure directly',
59
+ :boolean => true
60
+
61
+ option :extractlocal,
62
+ :long => '--extractlocal',
63
+ :description => 'Use contents of local chef repository directories to generate knife commands to build infrastructure'
64
+
65
+ option :extractjson,
66
+ :long => '--extractjson',
67
+ :description => 'Use contents of local chef repository directories to generate JSON spiceweasel manifest'
68
+
69
+ option :extractyaml,
70
+ :long => '--extractyaml',
71
+ :description => 'Use contents of local chef repository directories to generate YAML spiceweasel manifest'
72
+
73
+ option :help,
74
+ :short => '-h',
75
+ :long => '--help',
76
+ :description => 'Show this message',
77
+ :on => :tail,
78
+ :boolean => true,
79
+ :show_options => true,
80
+ :exit => 0
81
+
82
+ option :knifeconfig,
83
+ :short => '-c CONFIG',
84
+ :long => '--knifeconfig CONFIG',
85
+ :description => 'Specify the knife.rb configuration file'
86
+
87
+ option :log_level,
88
+ :short => "-l LEVEL",
89
+ :long => "--log_level LEVEL",
90
+ :description => "Set the log level (debug, info, warn, error, fatal)",
91
+ :proc => lambda { |l| l.to_sym }
92
+
93
+ option :log_location,
94
+ :short => "-L LOGLOCATION",
95
+ :long => "--logfile LOGLOCATION",
96
+ :description => "Set the log file location, defaults to STDOUT",
97
+ :proc => nil
98
+
99
+ option :novalidation,
100
+ :long => '--novalidation',
101
+ :description => 'Disable validation',
102
+ :boolean => true
103
+
104
+ option :parallel,
105
+ :long => '--parallel',
106
+ :description => "Use the GNU 'parallel' command to parallelize 'knife VENDOR server create' commands where applicable",
107
+ :boolean => true
108
+
109
+ option :rebuild,
110
+ :short => '-r',
111
+ :long => '--rebuild',
112
+ :description => 'Print the knife commands to delete and recreate the infrastructure',
113
+ :boolean => true
114
+
115
+ option :serverurl,
116
+ :short => '-s URL',
117
+ :long => '--server-url URL',
118
+ :description => 'Specify the Chef Server URL'
119
+
120
+ option :siteinstall,
121
+ :long => '--siteinstall',
122
+ :description => "Use the 'install' command with 'knife cookbook site' instead of the default 'download'",
123
+ :boolean => true
124
+
125
+ option :version,
126
+ :short => '-v',
127
+ :long => '--version',
128
+ :description => 'Show spiceweasel version',
129
+ :boolean => true,
130
+ :proc => lambda { |v| puts "Spiceweasel: #{::Spiceweasel::VERSION}" },
131
+ :exit => 0
132
+
133
+ def run
134
+ if Spiceweasel::Config[:extractlocal] || Spiceweasel::Config[:extractjson] || Spiceweasel::Config[:extractyaml]
135
+ manifest = Spiceweasel::ExtractLocal.parse_objects
136
+ else
137
+ manifest = parse_and_validate_input(ARGV.last)
138
+ if Spiceweasel::Config[:clusterfile]
139
+ # if we have a cluster file, override any nodes or clusters in the original manifest
140
+ manifest['nodes'] = manifest['clusters'] = {}
141
+ manifest.merge!(parse_and_validate_input(Spiceweasel::Config[:clusterfile]))
142
+ end
143
+ end
144
+ Spiceweasel::Log.debug("file manifest: #{manifest}")
145
+
146
+ cookbooks = Cookbooks.new(manifest['cookbooks'])
147
+ environments = Environments.new(manifest['environments'], cookbooks)
148
+ roles = Roles.new(manifest['roles'], environments, cookbooks)
149
+ data_bags = DataBags.new(manifest['data bags'])
150
+ nodes = Nodes.new(manifest['nodes'], cookbooks, environments, roles)
151
+ clusters = Clusters.new(manifest['clusters'], cookbooks, environments, roles)
152
+
153
+ create = cookbooks.create + environments.create + roles.create + data_bags.create + nodes.create + clusters.create
154
+ delete = cookbooks.delete + environments.delete + roles.delete + data_bags.delete + nodes.delete + clusters.delete
155
+
156
+ #trim trailing whitespace
157
+ create.each {|x| x.rstrip!}
158
+ delete.each {|x| x.rstrip!}
159
+
160
+ if Spiceweasel::Config[:extractjson]
161
+ puts JSON.pretty_generate(manifest)
162
+ elsif Spiceweasel::Config[:extractyaml]
163
+ puts manifest.to_yaml
164
+ elsif Spiceweasel::Config[:delete]
165
+ if Spiceweasel::Config[:execute]
166
+ Execute.new(delete)
167
+ else
168
+ puts delete unless delete.empty?
169
+ end
170
+ elsif Spiceweasel::Config[:rebuild]
171
+ if Spiceweasel::Config[:execute]
172
+ Execute.new(delete)
173
+ Execute.new(create)
174
+ else
175
+ puts delete unless delete.empty?
176
+ puts create unless create.empty?
177
+ end
178
+ else
179
+ if Spiceweasel::Config[:execute]
180
+ Execute.new(create)
181
+ else
182
+ puts create unless create.empty?
183
+ end
184
+ end
185
+ exit 0
186
+ end
187
+
188
+ def initialize(argv=[])
189
+ super()
190
+ parse_and_validate_options
191
+ Config.merge!(@config)
192
+ configure_logging
193
+ Spiceweasel::Log.debug("Validation of the manifest has been turned off.") if Spiceweasel::Config[:novalidation]
194
+ end
195
+
196
+ def parse_and_validate_options
197
+ ARGV << "-h" if ARGV.empty?
198
+ begin
199
+ parse_options
200
+ if Spiceweasel::Config[:knifeconfig]
201
+ Spiceweasel::Config[:knife_options] = "-c #{Spiceweasel::Config[:knifeconfig]} "
202
+ end
203
+ if Spiceweasel::Config[:serverurl]
204
+ Spiceweasel::Config[:knife_options] += "--server-url #{Spiceweasel::Config[:serverurl]} "
205
+ end
206
+ rescue OptionParser::InvalidOption => e
207
+ STDERR.puts e.message
208
+ puts opt_parser.to_s
209
+ exit(-1)
210
+ end
211
+ end
212
+
213
+ def configure_logging
214
+ Spiceweasel::Log.init(Spiceweasel::Config[:log_location])
215
+ Spiceweasel::Log.level = Spiceweasel::Config[:log_level]
216
+ Spiceweasel::Log.level = :debug if Spiceweasel::Config[:debug]
217
+ end
218
+
219
+ def parse_and_validate_input(file)
220
+ begin
221
+ Spiceweasel::Log.debug("file: #{file}")
222
+ if !File.file?(file)
223
+ STDERR.puts "ERROR: #{file} is an invalid manifest file, please check your path."
224
+ exit(-1)
225
+ end
226
+ if (file.end_with?(".yml"))
227
+ output = YAML.load_file(file)
228
+ elsif (file.end_with?(".json"))
229
+ output = JSON.parse(File.read(file))
230
+ else
231
+ STDERR.puts "ERROR: #{file} is an unknown file type, please use a file ending with either '.json' or '.yml'."
232
+ exit(-1)
233
+ end
234
+ rescue Psych::SyntaxError => e
235
+ STDERR.puts e.message
236
+ STDERR.puts "ERROR: Parsing error in #{file}."
237
+ exit(-1)
238
+ rescue JSON::ParserError => e
239
+ STDERR.puts e.message
240
+ STDERR.puts "ERROR: Parsing error in #{file}."
241
+ exit(-1)
242
+ rescue Exception
243
+ STDERR.puts "ERROR: No manifest .json or .yml file provided."
244
+ puts opt_parser.to_s
245
+ exit(-1)
246
+ end
247
+ output
248
+ end
249
+
250
+ end
85
251
  end