knife-sharp 0.4.5 → 0.5.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b78ccd3e3e6bbc90de1f096bbacbabf3d0c425d0
4
- data.tar.gz: d0c0aa39d3c612b4967af96edbe28b297ba3ac19
3
+ metadata.gz: ca5eb5868e371ab216bf8009f49fc1341b0884dd
4
+ data.tar.gz: 4f2471fc8a99e9372dd459c9c0da29e7e5d9f862
5
5
  SHA512:
6
- metadata.gz: 3988ac9a8e7986a48000f517aba4d507dee19291a619fcb87db86cc82aa544be2bcd7a583661902650df9c226ad124613fde5ce066fc7c58748cfd134356d8f8
7
- data.tar.gz: 0576546edf62936eb81209157f56d8dab59f4b0540d963e535a05ded5fbaa44587b421d25eba8b50799c01cd058f51ecab2e5c1dafe463a89abf68c0eca646c4
6
+ metadata.gz: bdf6f7d68cfc0806231fedec65d4e074ea97bddbef433ee8f58ec9f180200c7337f8accf8e530919275a3d12f0f8dbb13672756faa8c482aeff8b82373f74be2
7
+ data.tar.gz: 732dcc82d02814c8d7e4fba9d00b1aaa2dd2037fae214cbb5e36d1e91769369ecdad99ac512adbc96b005913bf9f9aa954b50b90cc805a9382512e282637104b
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ pkg
3
+ .ruby-gemset
4
+ .ruby-version
data/Gemfile ADDED
@@ -0,0 +1 @@
1
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,92 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ knife-sharp (0.5.0)
5
+ chef (>= 11)
6
+ grit (~> 2.5)
7
+
8
+ GEM
9
+ specs:
10
+ chef (12.0.3)
11
+ chef-zero (~> 3.2)
12
+ diff-lcs (~> 1.2, >= 1.2.4)
13
+ erubis (~> 2.7)
14
+ ffi-yajl (~> 1.2)
15
+ highline (~> 1.6, >= 1.6.9)
16
+ mixlib-authentication (~> 1.3)
17
+ mixlib-cli (~> 1.4)
18
+ mixlib-config (~> 2.0)
19
+ mixlib-log (~> 1.3)
20
+ mixlib-shellout (>= 2.0.0.rc.0, < 3.0)
21
+ net-ssh (~> 2.6)
22
+ net-ssh-multi (~> 1.1)
23
+ ohai (~> 8.0)
24
+ plist (~> 3.1.0)
25
+ pry (~> 0.9)
26
+ chef-zero (3.2.1)
27
+ ffi-yajl (~> 1.1)
28
+ hashie (~> 2.0)
29
+ mixlib-log (~> 1.3)
30
+ rack
31
+ uuidtools (~> 2.1)
32
+ coderay (1.1.0)
33
+ diff-lcs (1.2.5)
34
+ erubis (2.7.0)
35
+ ffi (1.9.6)
36
+ ffi-yajl (1.3.1)
37
+ ffi (~> 1.5)
38
+ libyajl2 (~> 1.2)
39
+ grit (2.5.0)
40
+ diff-lcs (~> 1.1)
41
+ mime-types (~> 1.15)
42
+ posix-spawn (~> 0.3.6)
43
+ hashie (2.1.2)
44
+ highline (1.6.21)
45
+ ipaddress (0.8.0)
46
+ libyajl2 (1.2.0)
47
+ method_source (0.8.2)
48
+ mime-types (1.25.1)
49
+ mixlib-authentication (1.3.0)
50
+ mixlib-log
51
+ mixlib-cli (1.5.0)
52
+ mixlib-config (2.1.0)
53
+ mixlib-log (1.6.0)
54
+ mixlib-shellout (2.0.1)
55
+ net-dhcp (1.3.2)
56
+ net-ssh (2.9.2)
57
+ net-ssh-gateway (1.2.0)
58
+ net-ssh (>= 2.6.5)
59
+ net-ssh-multi (1.2.0)
60
+ net-ssh (>= 2.6.5)
61
+ net-ssh-gateway (>= 1.2.0)
62
+ ohai (8.0.1)
63
+ ffi (~> 1.9)
64
+ ffi-yajl (~> 1.1)
65
+ ipaddress
66
+ mime-types (~> 1.16)
67
+ mixlib-cli
68
+ mixlib-config (~> 2.0)
69
+ mixlib-log
70
+ mixlib-shellout (~> 2.0)
71
+ net-dhcp
72
+ rake (~> 10.1)
73
+ systemu (~> 2.6.4)
74
+ wmi-lite (~> 1.0)
75
+ plist (3.1.0)
76
+ posix-spawn (0.3.9)
77
+ pry (0.10.1)
78
+ coderay (~> 1.1.0)
79
+ method_source (~> 0.8.1)
80
+ slop (~> 3.4)
81
+ rack (1.6.0)
82
+ rake (10.1.0)
83
+ slop (3.6.0)
84
+ systemu (2.6.4)
85
+ uuidtools (2.1.5)
86
+ wmi-lite (1.0.0)
87
+
88
+ PLATFORMS
89
+ ruby
90
+
91
+ DEPENDENCIES
92
+ knife-sharp!
data/Rakefile ADDED
@@ -0,0 +1,35 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+
5
+ def name
6
+ @name ||= Dir['*.gemspec'].first.split('.').first
7
+ end
8
+
9
+ def version
10
+ line = File.read("lib/#{name}.rb")[/^\s*VERSION\s*=\s*.*/]
11
+ line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
12
+ end
13
+
14
+ def gemspec_file
15
+ "#{name}.gemspec"
16
+ end
17
+
18
+ def gem_file
19
+ "#{name}-#{version}.gem"
20
+ end
21
+
22
+
23
+ # tasks
24
+
25
+ desc "Open an irb session preloaded with this library"
26
+ task :console do
27
+ sh "irb -rubygems -r ./lib/#{name}.rb"
28
+ end
29
+
30
+ desc "Build #{gem_file} into the pkg directory"
31
+ task :build do
32
+ sh "mkdir -p pkg"
33
+ sh "gem build #{gemspec_file}"
34
+ sh "mv #{gem_file} pkg"
35
+ end
@@ -0,0 +1,20 @@
1
+ require 'date'
2
+ require File.join(File.dirname(__FILE__), "lib", "knife-sharp.rb")
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'knife-sharp'
6
+ s.version = KnifeSharp::VERSION
7
+ s.date = Date.today.to_s
8
+ s.summary = "Knife sharp plugin"
9
+ s.description = "Sharpen your knife"
10
+ s.homepage = "https://github.com/Fotolia/knife-sharp"
11
+ s.authors = [ "Nicolas Szalay", "Jonathan Amiez" ]
12
+ s.email = [ "nico@rottenbytes.info", "jonathan.amiez@gmail.com" ]
13
+ s.license = "3-BSD"
14
+
15
+ s.files = %x(git ls-files).split("\n")
16
+ s.require_paths = [ "lib" ]
17
+
18
+ s.add_dependency "chef", ">= 11"
19
+ s.add_dependency "grit", "~> 2.5"
20
+ end
@@ -1,8 +1,10 @@
1
1
  require 'chef/knife'
2
+ require 'knife-sharp/common'
2
3
  require 'grit'
3
4
 
4
5
  module KnifeSharp
5
6
  class SharpAlign < Chef::Knife
7
+ include KnifeSharp::Common
6
8
 
7
9
  banner "knife sharp align BRANCH ENVIRONMENT [OPTS]"
8
10
 
@@ -26,483 +28,42 @@ module KnifeSharp
26
28
  :description => "dump items not present locally (roles/databags)",
27
29
  :default => false
28
30
 
29
- deps do
30
- require 'chef/environment'
31
- require 'chef/role'
32
- require 'chef/cookbook/metadata'
33
- require 'chef/cookbook_loader'
34
- require 'chef/cookbook_uploader'
35
- end
36
-
37
31
  def run
38
- setup()
39
- ui.msg(ui.color("On server #{@chef_server}", :bold)) if @chef_server
40
- check_cookbooks if @do_cookbooks
41
- check_databags if @do_databags
42
- check_roles if @do_roles
43
-
44
- # All questions asked, can we proceed ?
45
- if @cookbooks.empty? and @databags.empty? and @roles.empty?
46
- ui.msg "Nothing else to do"
47
- exit 0
48
- end
49
-
50
- ui.confirm(ui.color("> Proceed ", :bold))
51
- bump_cookbooks if @do_cookbooks
52
- update_databags if @do_databags
53
- update_roles if @do_roles
54
- end
55
-
56
- def setup
57
32
  # Checking args
58
- if name_args.count != 2
59
- show_usage
60
- exit 1
61
- end
33
+ ensure_branch_and_environment_provided!
34
+
35
+ # Checking repo branch
36
+ ensure_correct_branch_provided!
62
37
 
63
38
  # check cli flags
64
39
  if config[:cookbooks] or config[:databags] or config[:roles]
65
- @do_cookbooks, @do_databags, @do_roles = config[:cookbooks], config[:databags], config[:roles]
66
- else
67
- @do_cookbooks, @do_databags, @do_roles = true, true, true
68
- end
69
-
70
- # Sharp config
71
- cfg_files = [ "/etc/sharp-config.yml", "~/.chef/sharp-config.yml" ]
72
- loaded = false
73
- cfg_files.each do |cfg_file|
74
- begin
75
- @cfg = YAML::load_file(File.expand_path(cfg_file))
76
- loaded = true
77
- rescue Exception => e
78
- ui.error "Error on loading config : #{e.inspect}" if config[:verbosity] > 0
79
- end
80
- end
81
- unless loaded == true
82
- ui.error "config could not be loaded ! Tried the following files : #{cfg_files.join(", ")}"
83
- exit 1
84
- end
85
-
86
- # Env setup
87
- @branch, @environment = name_args
88
- @chef_path = @cfg["global"]["git_cookbook_path"]
89
-
90
- # Checking current branch
91
- current_branch = Grit::Repo.new(@chef_path).head.name
92
- if @branch != current_branch then
93
- ui.error "Git repo is actually on branch #{current_branch} but you want to align using #{@branch}. Checkout to the desired one."
94
- exit 1
95
- end
96
-
97
- # Knife config
98
- if Chef::Knife.chef_config_dir && File.exists?(File.join(Chef::Knife.chef_config_dir, "knife.rb"))
99
- Chef::Config.from_file(File.join(Chef::Knife.chef_config_dir, "knife.rb"))
100
- else
101
- ui.error "Cannot find knife.rb config file"
102
- exit 1
103
- end
104
-
105
- # Logger
106
- if @cfg["logging"]["enabled"]
107
- begin
108
- require "logger"
109
- log_file = File.expand_path(@cfg["logging"]["destination"])
110
- @log = Logger.new(log_file)
111
- rescue Exception => e
112
- ui.error "Unable to set up logger (#{e.inspect})."
113
- exit 1
114
- end
115
- end
116
-
117
- chefcfg = Chef::Config
118
- @cb_path = chefcfg.cookbook_path.is_a?(Array) ? chefcfg.cookbook_path.first : chefcfg.cookbook_path
119
- @db_path = chefcfg.data_bag_path.is_a?(Array) ? chefcfg.data_bag_path.first : chefcfg.data_bag_path
120
- @role_path = chefcfg.role_path.is_a?(Array) ? chefcfg.role_path.first : chefcfg.role_path
121
-
122
- @chef_server = SharpServer.new.current_server
123
- @loader = Chef::CookbookLoader.new(@cb_path)
124
-
125
- @cookbooks = Array.new
126
- @databags = Hash.new
127
- @roles = Hash.new
128
- end
129
-
130
- ### Cookbook methods ###
131
-
132
- def check_cookbooks
133
- unless File.exists?(@cb_path)
134
- ui.warn "Bad cookbook path, skipping cookbook sync."
135
- return
136
- end
137
-
138
- ui.msg(ui.color("== Cookbooks ==", :bold))
139
-
140
- updated_versions = Hash.new
141
- local_versions = Hash[Dir.glob("#{@cb_path}/*").select {|cb| File.directory?(cb)}.map {|cb| [File.basename(cb), @loader[File.basename(cb)].version] }]
142
- remote_versions = Chef::Environment.load(@environment).cookbook_versions.each_value {|v| v.gsub!("= ", "")}
143
-
144
- if local_versions.empty?
145
- ui.warn "No local cookbooks found, is the cookbook path correct ? (#{@cb_path})"
146
- return
147
- end
148
-
149
- # get local-only cookbooks
150
- (local_versions.keys - remote_versions.keys).each do |cb|
151
- updated_versions[cb] = local_versions[cb]
152
- ui.msg "* #{cb} is local only (version #{local_versions[cb]})"
153
- end
154
-
155
- # get cookbooks not up-to-date
156
- (remote_versions.keys & local_versions.keys).each do |cb|
157
- if Chef::VersionConstraint.new("> #{remote_versions[cb]}").include?(local_versions[cb])
158
- updated_versions[cb] = local_versions[cb]
159
- ui.msg "* #{cb} is not up-to-date (local: #{local_versions[cb]}/remote: #{remote_versions[cb]})"
160
- elsif Chef::VersionConstraint.new("> #{local_versions[cb]}").include?(remote_versions[cb]) and config[:force_align]
161
- updated_versions[cb] = local_versions[cb]
162
- ui.msg "* #{cb} is to be downgraded (local: #{local_versions[cb]}/remote: #{remote_versions[cb]})"
163
- end
164
- end
165
-
166
- if @cfg[@chef_server] and @cfg[@chef_server].has_key?("ignore_cookbooks")
167
- (updated_versions.keys & @cfg[@chef_server]["ignore_cookbooks"]).each do |cb|
168
- updated_versions.delete(cb)
169
- ui.msg "* Skipping #{cb} cookbook (ignore list)"
170
- end
171
- end
172
-
173
- if !updated_versions.empty?
174
- all = false
175
- updated_versions.each_pair do |cb,version|
176
- answer = ui.ask_question("> Update #{cb} cookbook to #{version} on server ? Y/N/(A)ll/(Q)uit ", :default => "N").upcase unless all
177
-
178
- if answer == "A"
179
- all = true
180
- elsif answer == "Q"
181
- ui.msg "* Skipping next cookbooks alignment."
182
- break
183
- end
184
-
185
- if all or answer == "Y"
186
- @cookbooks << cb
187
- else
188
- ui.msg "* Skipping #{cb} cookbook"
189
- end
190
- end
191
- else
192
- ui.msg "* Environment #{@environment} is up-to-date."
193
- end
194
- end
195
-
196
-
197
- def bump_cookbooks
198
- unless @cookbooks.empty?
199
- env = Chef::Environment.load(@environment)
200
- cbs = Array.new
201
- backup_data = Hash.new
202
- backup_data["environment"] = @environment
203
- backup_data["cookbook_versions"] = Hash.new
204
- @cookbooks.each do |cb_name|
205
- cb = @loader[cb_name]
206
- if @cfg["rollback"] && @cfg["rollback"]["enabled"] == true
207
- backup_data["cookbook_versions"][cb_name] = env.cookbook_versions[cb_name]
208
- end
209
- # Force "= a.b.c" in cookbook version, as chef11 will not accept "a.b.c"
210
- env.cookbook_versions[cb_name] = "= #{cb.version}"
211
- cbs << cb
212
- end
213
-
214
- ui.msg "* Uploading cookbook(s) #{@cookbooks.join(", ")}"
215
- cookbook_uploader(cbs).upload_cookbooks
216
-
217
-
218
- if env.save
219
- cbs.each do |cb|
220
- ui.msg "* Bumping #{cb.name} to #{cb.version} for environment #{@environment}"
221
- log_action("bumping #{cb.name} to #{cb.version} for environment #{@environment}")
222
- end
223
- end
224
-
225
- if @cfg["rollback"] && @cfg["rollback"]["enabled"] == true
226
- identifier = Time.now.to_i
227
- Dir.mkdir(@cfg["rollback"]["destination"]) unless File.exists?(@cfg["rollback"]["destination"])
228
- fp = open(File.join(@cfg["rollback"]["destination"], "#{identifier}.json"), "w")
229
- fp.write(JSON.pretty_generate(backup_data))
230
- fp.close()
231
- end
232
- end
233
- end
234
-
235
- ### Databag methods ###
236
-
237
- def check_databags
238
- unless File.exists?(@db_path)
239
- ui.warn "Bad data bag path, skipping data bag sync."
240
- return
241
- end
242
-
243
- ui.msg(ui.color("== Data bags ==", :bold))
244
-
245
- updated_dbs = Hash.new
246
- local_dbs = Dir.glob(File.join(@db_path, "**/*.json")).map {|f| [File.dirname(f).split("/").last, File.basename(f, ".json")]}
247
- remote_dbs = Chef::DataBag.list.keys.map {|db| Chef::DataBag.load(db).keys.map{|dbi| [db, dbi]}}.flatten(1)
248
-
249
- if local_dbs.empty?
250
- ui.warn "No local data bags found, is the data bag path correct ? (#{@db_path})"
251
- return
252
- end
253
-
254
- # Dump missing data bags locally
255
- (remote_dbs - local_dbs).each do |db|
256
- ui.msg "* #{db.join("/")} data bag item is remote only"
257
- if config[:dump_remote_only]
258
- ui.msg "* Dumping to #{File.join(@db_path, "#{db.join("/")}.json")}"
259
- begin
260
- remote_db = Chef::DataBagItem.load(db.first, db.last).raw_data
261
- Dir.mkdir(File.join(@db_path, db.first)) unless File.exists?(File.join(@db_path, db.first))
262
- File.open(File.join(@db_path, "#{db.join("/")}.json"), "w") do |file|
263
- file.puts JSON.pretty_generate(remote_db)
264
- end
265
- rescue Exception => e
266
- ui.error "Unable to dump #{db.join("/")} data bag item (#{e.message})"
267
- end
268
- end
269
- end
270
-
271
- # Create new data bags on server
272
- (local_dbs - remote_dbs).each do |db|
273
- begin
274
- local_db = JSON::load(File.read(File.join(@db_path, "#{db.join("/")}.json")))
275
- updated_dbs[db] = local_db
276
- ui.msg "* #{db.join("/")} data bag item is local only"
277
- rescue Exception => e
278
- ui.error "Unable to load #{db.join("/")} data bag item (#{e.message})"
279
- end
280
- end
281
-
282
- # Compare roles common to local and remote
283
- (remote_dbs & local_dbs).each do |db|
284
- begin
285
- remote_db = Chef::DataBagItem.load(db.first, db.last).raw_data
286
- local_db = JSON::load(File.read(File.join(@db_path, "#{db.join("/")}.json")))
287
- if remote_db != local_db
288
- updated_dbs[db] = local_db
289
- ui.msg("* #{db.join("/")} data bag item is not up-to-date")
290
- end
291
- rescue Exception => e
292
- ui.error "Unable to load #{db.join("/")} data bag item (#{e.message})"
293
- end
294
- end
295
-
296
- if @cfg[@chef_server] and @cfg[@chef_server].has_key?("ignore_databags")
297
- (updated_dbs.keys.map{|k| k.join("/")} & @cfg[@chef_server]["ignore_databags"]).each do |db|
298
- updated_dbs.delete(db.split("/"))
299
- ui.msg "* Skipping #{db} data bag (ignore list)"
300
- end
301
- end
302
-
303
- if !updated_dbs.empty?
304
- all = false
305
- updated_dbs.each do |name, obj|
306
- answer = nil
307
- answer = ui.ask_question("> Update #{name.join("/")} data bag item on server ? Y/N/(A)ll/(Q)uit ", :default => "N").upcase unless all
308
-
309
- if answer == "A"
310
- all = true
311
- elsif answer == "Q"
312
- ui.msg "* Aborting data bag alignment."
313
- break
314
- end
315
-
316
- if all or answer == "Y"
317
- @databags[name] = obj
318
- else
319
- ui.msg "* Skipping #{name.join("/")} data bag item"
320
- end
321
- end
322
- else
323
- ui.msg "* Data bags are up-to-date."
324
- end
325
- end
326
-
327
- def update_databags
328
- parent_databags = Chef::DataBag.list.keys
329
- unless @databags.empty?
330
- @databags.each do |name, obj|
331
- begin
332
- # create the parent if needed
333
- unless parent_databags.include?(name.first)
334
- db = Chef::DataBag.new
335
- db.name(name.first)
336
- db.create
337
- # add it to the list to avoid trying to recreate it
338
- parent_databags.push(name.first)
339
- ui.msg("* Creating data bag #{name.first}")
340
- log_action("creating data bag #{name.first}")
341
- end
342
- db = Chef::DataBagItem.new
343
- db.data_bag(name.first)
344
- db.raw_data = obj
345
- db.save
346
- ui.msg "* Updating #{name.join("/")} data bag item"
347
- log_action("updating #{name.join("/")} data bag item")
348
- rescue Exception => e
349
- ui.error "Unable to update #{name.join("/")} data bag item"
350
- end
351
- end
352
- end
353
- end
354
-
355
- ### Role methods ###
356
-
357
- def check_roles
358
- # role sections to compare (methods)
359
- to_check = {
360
- "env_run_lists" => "run list",
361
- "default_attributes" => "default attributes",
362
- "override_attributes" => "override attributes"
363
- }
364
-
365
- unless File.exists?(@role_path)
366
- ui.warn "Bad role path, skipping role sync."
367
- return
368
- end
369
-
370
- ui.msg(ui.color("== Roles ==", :bold))
371
-
372
- updated_roles = Hash.new
373
- local_roles = Dir.glob(File.join(@role_path, "*.json")).map {|file| File.basename(file, ".json")}
374
- remote_roles = Chef::Role.list.keys
375
-
376
- if local_roles.empty?
377
- ui.warn "No local roles found, is the role path correct ? (#{@role_path})"
378
- return
379
- end
380
-
381
- # Dump missing roles locally
382
- (remote_roles - local_roles).each do |role|
383
- ui.msg "* #{role} role is remote only"
384
- if config[:dump_remote_only]
385
- ui.msg "* Dumping to #{File.join(@role_path, "#{role}.json")}"
386
- begin
387
- remote_role = Chef::Role.load(role)
388
- File.open(File.join(@role_path, "#{role}.json"), "w") do |file|
389
- file.puts JSON.pretty_generate(remote_role)
390
- end
391
- rescue Exception => e
392
- ui.error "Unable to dump #{role} role (#{e.message})"
393
- end
394
- end
395
- end
396
-
397
- # Create new roles on server
398
- (local_roles - remote_roles).each do |role|
399
- begin
400
- local_role = Chef::Role.from_disk(role)
401
- updated_roles[role] = local_role
402
- ui.msg "* #{role} role is local only"
403
- rescue Exception => e
404
- ui.error "Unable to load #{role} role (#{e.message})"
405
- end
406
- end
407
-
408
- # Compare roles common to local and remote
409
- (remote_roles & local_roles).each do |role|
410
- remote_role = Chef::Role.load(role)
411
- local_role = Chef::Role.from_disk(role)
412
-
413
- diffs = Array.new
414
- to_check.each do |method, display|
415
- if remote_role.send(method) != local_role.send(method)
416
- updated_roles[role] = local_role
417
- diffs << display
418
- end
419
- end
420
- ui.msg("* #{role} role is not up-to-date (#{diffs.join(",")})") unless diffs.empty?
421
- end
422
-
423
- if @cfg[@chef_server] and @cfg[@chef_server].has_key?("ignore_roles")
424
- (updated_roles.keys & @cfg[@chef_server]["ignore_roles"]).each do |r|
425
- updated_roles.delete(r)
426
- ui.msg "* Skipping #{r} role (ignore list)"
427
- end
428
- end
429
-
430
- if !updated_roles.empty?
431
- all = false
432
- updated_roles.each do |name, obj|
433
- answer = ui.ask_question("> Update #{name} role on server ? Y/N/(A)ll/(Q)uit ", :default => "N").upcase unless all
434
-
435
- if answer == "A"
436
- all = true
437
- elsif answer == "Q"
438
- ui.msg "* Aborting role alignment."
439
- break
440
- end
441
-
442
- if all or answer == "Y"
443
- @roles[name] = obj
444
- else
445
- ui.msg "* Skipping #{name} role"
446
- end
447
- end
40
+ do_cookbooks, do_databags, do_roles = config[:cookbooks], config[:databags], config[:roles]
448
41
  else
449
- ui.msg "* Roles are up-to-date."
42
+ do_cookbooks, do_databags, do_roles = true, true, true
450
43
  end
451
- end
452
44
 
453
- def update_roles
454
- unless @roles.empty?
455
- @roles.each do |name, obj|
456
- begin
457
- obj.save
458
- ui.msg "* Updating #{name} role"
459
- log_action("updating #{name} role")
460
- rescue Exception => e
461
- ui.error "Unable to update #{name} role"
462
- end
463
- end
464
- end
465
- end
466
-
467
- ### Utility methods ###
468
-
469
- def log_action(message)
470
- # log file if enabled
471
- log_message = message
472
- log_message += " on server #{@chef_server}" if @chef_server
473
- @log.info(log_message) if @cfg["logging"]["enabled"]
45
+ ui.msg(ui.color("On server #{chef_server}", :bold)) if chef_server
474
46
 
475
- # any defined notification method (currently, only hubot, defined below)
476
- if @cfg["notification"]
477
- @cfg["notification"].each do |carrier, data|
478
- skipped = Array.new
479
- skipped = data["skip"] if data["skip"]
480
-
481
- if data["enabled"] and !skipped.include?(@chef_server)
482
- send(carrier, message, data)
483
- end
484
- end
485
- end
486
- end
47
+ SharpCookbookAlign.load_deps
48
+ sca = SharpCookbookAlign.new
49
+ cookbooks_to_update = do_cookbooks ? sca.check_cookbooks(environment) : []
50
+ SharpDataBagAlign.load_deps
51
+ sda = SharpDataBagAlign.new
52
+ databags_to_update = do_databags ? sda.check_databags : {}
53
+ SharpRoleAlign.load_deps
54
+ sra = SharpRoleAlign.new
55
+ roles_to_update = do_roles ? sra.check_roles : {}
487
56
 
488
- def hubot(message, config={})
489
- begin
490
- require "net/http"
491
- require "uri"
492
- uri = URI.parse("#{config["url"]}/#{config["channel"]}")
493
- notif = "chef: #{message} by #{config["username"]}"
494
- Net::HTTP.post_form(uri, { "message" => notif })
495
- rescue
496
- ui.error "Unable to notify via hubot."
57
+ # All questions asked, can we proceed ?
58
+ if cookbooks_to_update.empty? and databags_to_update.empty? and roles_to_update.empty?
59
+ ui.msg "Nothing else to do"
60
+ exit 0
497
61
  end
498
- end
499
62
 
500
- def cookbook_uploader(cookbooks)
501
- if Gem::Version.new(Chef::VERSION).release >= Gem::Version.new('12.0.0')
502
- uploader = Chef::CookbookUploader.new(cookbooks)
503
- else
504
- uploader = Chef::CookbookUploader.new(cookbooks, Chef::Config.cookbook_path)
505
- end
63
+ ui.confirm(ui.color("> Proceed ", :bold))
64
+ sca.bump_cookbooks(environment, cookbooks_to_update) if do_cookbooks
65
+ sda.update_databags(databags_to_update) if do_databags
66
+ sra.update_roles(roles_to_update) if do_roles
506
67
  end
507
68
  end
508
69
  end