knife-sharp 0.1.4 → 0.1.6

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/ext/sharp-config.yml CHANGED
@@ -10,3 +10,4 @@ notification:
10
10
  url: "http://your.hubot.lan:18080/hubot/chef/bump/"
11
11
  channel: "foo"
12
12
  username: "Nicolas"
13
+ skip: [dev]
@@ -4,7 +4,7 @@ require 'grit'
4
4
  module KnifeSharp
5
5
  class SharpAlign < Chef::Knife
6
6
 
7
- banner "knife sharp align BRANCH ENVIRONMENT [--debug] [--quiet]"
7
+ banner "knife sharp align BRANCH ENVIRONMENT [--debug]"
8
8
 
9
9
  option :debug,
10
10
  :short => '-d',
@@ -12,12 +12,6 @@ module KnifeSharp
12
12
  :description => "turn debug on",
13
13
  :default => false
14
14
 
15
- option :quiet,
16
- :short => '-q',
17
- :long => '--quiet',
18
- :description => 'does not notifies',
19
- :default => false
20
-
21
15
  deps do
22
16
  require 'chef/cookbook/metadata'
23
17
  require 'chef/cookbook_loader'
@@ -26,6 +20,7 @@ module KnifeSharp
26
20
 
27
21
  def run
28
22
  setup()
23
+ ui.msg "On server #{@chef_server}" if @chef_server
29
24
  ui.msg "Aligning cookbooks"
30
25
  align_cookbooks()
31
26
  ui.msg "Aligning data bags"
@@ -65,6 +60,18 @@ module KnifeSharp
65
60
  exit 1
66
61
  end
67
62
 
63
+ # Logger
64
+ if @cfg["logging"]["enabled"]
65
+ begin
66
+ require "logger"
67
+ log_file = File.expand_path(@cfg["logging"]["destination"])
68
+ @log = Logger.new(log_file)
69
+ rescue Exception => e
70
+ ui.error "Unable to set up logger (#{e.inspect})."
71
+ exit 1
72
+ end
73
+ end
74
+
68
75
  # Env setup
69
76
  @branch, @environment = name_args
70
77
  @chef_path = @cfg["global"]["git_cookbook_path"]
@@ -74,6 +81,9 @@ module KnifeSharp
74
81
  @db_path = chefcfg.data_bag_path.is_a?(Array) ? chefcfg.data_bag_path.first : chefcfg.data_bag_path
75
82
  @role_path = chefcfg.role_path.is_a?(Array) ? chefcfg.role_path.first : chefcfg.role_path
76
83
 
84
+ @chef_server = SharpServer.new.current_server
85
+ @loader = Chef::CookbookLoader.new(@cb_path)
86
+
77
87
  # Checking current branch
78
88
  current_branch = Grit::Repo.new(@chef_path).head.name
79
89
  if @branch != current_branch then
@@ -86,8 +96,8 @@ module KnifeSharp
86
96
 
87
97
  def align_cookbooks
88
98
  updated_versions = Hash.new()
89
- local_versions = get_cookbook_local_versions()
90
- remote_versions = get_cookbook_versions_from_env(@environment)
99
+ local_versions = Hash[Dir.glob("#{@cb_path}/*").map {|cb| [File.basename(cb), @loader[File.basename(cb)].version] }]
100
+ remote_versions = Chef::Environment.load(@environment).cookbook_versions.each_value {|v| v.gsub!("= ", "")}
91
101
 
92
102
  (local_versions.keys - remote_versions.keys).each do |cb|
93
103
  updated_versions[cb] = local_versions[cb]
@@ -101,36 +111,37 @@ module KnifeSharp
101
111
  end
102
112
  end
103
113
 
104
- bumped = Hash.new
105
114
  if !updated_versions.empty?
106
115
  all = false
116
+ bumped = Array.new
107
117
  env = Chef::Environment.load(@environment)
108
- loader = Chef::CookbookLoader.new(@cb_path)
109
118
  updated_versions.each_pair do |cb,version|
110
119
  answer = ui.ask_question("Update #{cb} cookbook item on server ? Y/N/(A)ll/(Q)uit ", :default => "N").upcase unless all
111
120
 
112
121
  if answer == "A"
113
122
  all = true
114
123
  elsif answer == "Q"
115
- ui.msg "> Aborting cookbook alignment."
124
+ ui.msg "> Skipping next cookbooks alignment."
116
125
  break
117
126
  end
118
127
 
119
128
  if all or answer == "Y"
120
- log_action("* Uploading cookbook #{cb} version #{version}")
121
- cb_obj = loader[cb]
122
- uploader = Chef::CookbookUploader.new(cb_obj, @cb_path)
123
- uploader.upload_cookbooks
124
129
  env.cookbook_versions[cb] = version
125
- bumped[cb] = version
130
+ bumped << @loader[cb]
126
131
  else
127
132
  ui.msg "* Skipping #{cb} cookbook"
128
133
  end
129
134
  end
130
- if env.save
131
- bumped.each do |cb, version|
132
- log_action("* Bumping cookbook #{cb} to #{version} for environment #{@environment}")
133
- hubot_notify(cb, version, @environment)
135
+
136
+ unless bumped.empty?
137
+ ui.msg "* Uploading cookbook(s) #{bumped.map{|cb| cb.name.to_s}.join(",")}"
138
+ uploader = Chef::CookbookUploader.new(bumped, @cb_path)
139
+ uploader.upload_cookbooks
140
+ if env.save
141
+ bumped.each do |cb|
142
+ ui.msg "* Bumping #{cb.name.to_s} to #{cb.version} for environment #{@environment}"
143
+ log_action("bumping #{cb.name.to_s} to #{cb.version} for environment #{@environment}")
144
+ end
134
145
  end
135
146
  end
136
147
  else
@@ -138,22 +149,6 @@ module KnifeSharp
138
149
  end
139
150
  end
140
151
 
141
- # get cookbook for a known environment
142
- def get_cookbook_versions_from_env(env_name)
143
- Chef::Environment.load(env_name).cookbook_versions.each_value {|v| v.gsub!("= ", "")}
144
- end
145
-
146
- # in your local dealer !
147
- def get_cookbook_local_versions
148
- cbs = Hash.new
149
- Dir.glob("#{@cb_path}/*").each do |cookbook|
150
- md = Chef::Cookbook::Metadata.new
151
- md.from_file("#{cookbook}/metadata.rb")
152
- cbs[File.basename(cookbook)] = md.version
153
- end
154
- return cbs
155
- end
156
-
157
152
  ### Databag methods ###
158
153
 
159
154
  def align_databags
@@ -220,6 +215,7 @@ module KnifeSharp
220
215
 
221
216
  if all or answer == "Y"
222
217
  ui.msg "* Updating #{name.join("/")} data bag item"
218
+ log_action("updating #{name.join("/")} data bag item")
223
219
  db = Chef::DataBagItem.new
224
220
  db.data_bag(name.first)
225
221
  db.raw_data = obj
@@ -307,6 +303,7 @@ module KnifeSharp
307
303
 
308
304
  if all or answer == "Y"
309
305
  ui.msg "* Updating #{name} role"
306
+ log_action("updating #{name} role")
310
307
  obj.save
311
308
  else
312
309
  ui.msg "* Skipping #{name} role"
@@ -320,40 +317,35 @@ module KnifeSharp
320
317
  ### Utility methods ###
321
318
 
322
319
  def log_action(message)
323
- ui.msg(message)
324
-
325
- if @cfg["logging"]["enabled"]
326
- begin
327
- require "logger"
328
- log_file = File.expand_path(@cfg["logging"]["destination"])
329
- log = Logger.new(log_file)
330
- log.info(message)
331
- log.close
332
- rescue Exception => e
333
- ui.error "Oops ! #{e.inspect} ! message to log was #{message}"
320
+ # log file if enabled
321
+ log_message = message
322
+ log_message += " on server #{@chef_server}" if @chef_server
323
+ @log.info(log_message) if @cfg["logging"]["enabled"]
324
+
325
+ # any defined notification method (currently, only hubot, defined below)
326
+ if @cfg["notification"]
327
+ @cfg["notification"].each do |carrier, data|
328
+ skipped = Array.new
329
+ skipped = data["skip"] if data["skip"]
330
+
331
+ if data["enabled"] and !skipped.include?(@chef_server)
332
+ send(carrier, message, data)
333
+ end
334
334
  end
335
335
  end
336
336
  end
337
337
 
338
- def hubot_notify(cookbook, to_version, environment)
339
- unless @cfg["notification"]["hubot"]["enabled"] == true and config[:quiet] == false
340
- ui.msg "Aborting due to quiet or config disabled" if config[:debug]
341
- return
342
- end
343
-
338
+ def hubot(message, config={})
344
339
  begin
345
340
  require "net/http"
346
341
  require "uri"
347
- uri = URI.parse(@cfg["notification"]["hubot"]["url"] + @cfg["notification"]["hubot"]["channel"])
348
- user = @cfg["notification"]["hubot"]["username"]
349
-
350
- Net::HTTP.post_form(uri, { "cookbook" => cookbook,
351
- "user" => user,
352
- "to_version" => to_version,
353
- "environment" => environment })
342
+ uri = URI.parse("#{config["url"]}/#{config["channel"]}")
343
+ notif = "chef: #{message} by #{config["username"]}"
344
+ Net::HTTP.post_form(uri, { "message" => notif })
354
345
  rescue
355
- ui.error "Oops ! could not notify hubot !"
346
+ ui.error "Unable to notify via hubot."
356
347
  end
357
348
  end
349
+
358
350
  end
359
351
  end
@@ -1,28 +1,33 @@
1
1
  module KnifeSharp
2
2
  class SharpServer < Chef::Knife
3
3
 
4
- banner "knife sharp server [SERVERNAME]"
4
+ banner "knife sharp server [SERVERNAME] [--machine]"
5
+
6
+ option :machine,
7
+ :short => '-m',
8
+ :long => '--machine',
9
+ :description => "turn machine output on",
10
+ :default => false
5
11
 
6
12
  def run
7
- if File.exists?(knife_conf)
8
- if !File.symlink?(knife_conf)
9
- ui.error "#{knife_conf} is not a symlink."
10
- ui.msg "Copy it to #{knife_conf("<server name>")} and try again."
11
- exit 1
12
- end
13
+ if File.exists?(knife_conf) and !File.symlink?(knife_conf)
14
+ ui.error "#{knife_conf} is not a symlink."
15
+ ui.msg "Copy it to #{knife_conf("<server name>")} and try again."
16
+ exit 1
13
17
  end
14
18
  unless name_args.size == 1
15
19
  list_configs
16
20
  exit 0
17
21
  end
18
-
19
22
  update_config(name_args.first)
20
23
  end
21
24
 
22
25
  def update_config(new_server)
23
- if File.exists?(knife_conf(new_server))
24
- File.unlink(knife_conf) if File.exists?(knife_conf)
25
- File.symlink(knife_conf(new_server), knife_conf)
26
+ cur_conf = knife_conf
27
+ new_conf = knife_conf(new_server)
28
+ if File.exists?(new_conf)
29
+ File.unlink(cur_conf) if File.exists?(cur_conf)
30
+ File.symlink(new_conf, cur_conf)
26
31
  ui.msg "The knife configuration has been updated to use #{new_server}."
27
32
  else
28
33
  ui.error "Knife configuration for #{new_server} not found."
@@ -32,23 +37,41 @@ module KnifeSharp
32
37
  end
33
38
 
34
39
  def list_configs
35
- current_conf = File.readlink(knife_conf) if File.exists?(knife_conf)
36
- avail_confs = Dir.glob(File.join(Chef::Knife::chef_config_dir, "knife-*.rb"))
37
- if !avail_confs.empty?
38
- ui.msg "Available servers:"
39
- avail_confs.each do |file|
40
- name = file.match(/#{Chef::Knife::chef_config_dir}\/knife-(\w+)\.rb/)
41
- prefix = (file == current_conf) ? ">> " : " "
42
- ui.msg "#{prefix}#{name[1]} (#{file})"
40
+ if config[:machine] == true
41
+ server = current_server()
42
+ if server
43
+ ui.msg server
44
+ else
45
+ ui.msg "invalid"
43
46
  end
44
47
  else
45
- ui.msg "No knife server configuration file found."
48
+ avail_confs = Dir.glob(File.join(Chef::Knife::chef_config_dir, "knife-*.rb"))
49
+ if !avail_confs.empty?
50
+ ui.msg "Available servers:"
51
+ avail_confs.each do |file|
52
+ server = extract_server(file)
53
+ prefix = (server == current_server) ? ">> " : " "
54
+ ui.msg "#{prefix}#{server} (#{file})"
55
+ end
56
+ else
57
+ ui.msg "No knife server configuration file found."
58
+ end
46
59
  end
47
60
  end
48
61
 
62
+ def extract_server(config_filename)
63
+ match = config_filename.match(/#{Chef::Knife::chef_config_dir}\/knife-(\w+)\.rb/)
64
+ match ? match[1] : nil
65
+ end
66
+
49
67
  def knife_conf(server = nil)
50
68
  srv = server ? "-#{server}" : ""
51
69
  File.join(Chef::Knife::chef_config_dir, "knife#{srv}.rb")
52
70
  end
71
+
72
+ def current_server
73
+ cur_conf = knife_conf
74
+ extract_server(File.readlink(cur_conf)) if File.exists?(cur_conf) and File.symlink?(cur_conf)
75
+ end
53
76
  end
54
77
  end
data/lib/knife-sharp.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module KnifeSharp
2
- VERSION = "0.1.4"
2
+ VERSION = "0.1.6"
3
3
  end
metadata CHANGED
@@ -1,57 +1,66 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: knife-sharp
3
- version: !ruby/object:Gem::Version
4
- version: 0.1.4
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
5
  prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 6
10
+ version: 0.1.6
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Nicolas Szalay
9
14
  - Jonathan Amiez
10
15
  autorequire:
11
16
  bindir: bin
12
17
  cert_chain: []
13
- date: 2013-02-04 00:00:00.000000000 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
18
+
19
+ date: 2013-02-25 00:00:00 Z
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
16
22
  name: chef
17
- requirement: !ruby/object:Gem::Requirement
18
- none: false
19
- requirements:
20
- - - ! '>='
21
- - !ruby/object:Gem::Version
22
- version: 10.14.0
23
- type: :runtime
24
23
  prerelease: false
25
- version_requirements: !ruby/object:Gem::Requirement
24
+ requirement: &id001 !ruby/object:Gem::Requirement
26
25
  none: false
27
- requirements:
28
- - - ! '>='
29
- - !ruby/object:Gem::Version
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 119
30
+ segments:
31
+ - 10
32
+ - 14
33
+ - 0
30
34
  version: 10.14.0
31
- - !ruby/object:Gem::Dependency
32
- name: grit
33
- requirement: !ruby/object:Gem::Requirement
34
- none: false
35
- requirements:
36
- - - ~>
37
- - !ruby/object:Gem::Version
38
- version: 2.5.0
39
35
  type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: grit
40
39
  prerelease: false
41
- version_requirements: !ruby/object:Gem::Requirement
40
+ requirement: &id002 !ruby/object:Gem::Requirement
42
41
  none: false
43
- requirements:
42
+ requirements:
44
43
  - - ~>
45
- - !ruby/object:Gem::Version
44
+ - !ruby/object:Gem::Version
45
+ hash: 27
46
+ segments:
47
+ - 2
48
+ - 5
49
+ - 0
46
50
  version: 2.5.0
51
+ type: :runtime
52
+ version_requirements: *id002
47
53
  description: Sharpen your knife
48
- email:
54
+ email:
49
55
  - nico@rottenbytes.info
50
56
  - jonathan.amiez@gmail.com
51
57
  executables: []
58
+
52
59
  extensions: []
60
+
53
61
  extra_rdoc_files: []
54
- files:
62
+
63
+ files:
55
64
  - README.md
56
65
  - ext/sharp-config.yml
57
66
  - lib/knife-sharp.rb
@@ -61,26 +70,36 @@ files:
61
70
  - lib/chef/knife/sharp-server.rb
62
71
  homepage: https://github.com/Fotolia/knife-sharp
63
72
  licenses: []
73
+
64
74
  post_install_message:
65
75
  rdoc_options: []
66
- require_paths:
76
+
77
+ require_paths:
67
78
  - lib
68
- required_ruby_version: !ruby/object:Gem::Requirement
79
+ required_ruby_version: !ruby/object:Gem::Requirement
69
80
  none: false
70
- requirements:
71
- - - ! '>='
72
- - !ruby/object:Gem::Version
73
- version: '0'
74
- required_rubygems_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ hash: 3
85
+ segments:
86
+ - 0
87
+ version: "0"
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
89
  none: false
76
- requirements:
77
- - - ! '>='
78
- - !ruby/object:Gem::Version
79
- version: '0'
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ hash: 3
94
+ segments:
95
+ - 0
96
+ version: "0"
80
97
  requirements: []
98
+
81
99
  rubyforge_project:
82
- rubygems_version: 1.8.24
100
+ rubygems_version: 1.8.15
83
101
  signing_key:
84
102
  specification_version: 3
85
103
  summary: Knife sharp plugin
86
104
  test_files: []
105
+