knife-sharp 0.1.4 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/ext/sharp-config.yml +1 -0
- data/lib/chef/knife/sharp-align.rb +54 -62
- data/lib/chef/knife/sharp-server.rb +43 -20
- data/lib/knife-sharp.rb +1 -1
- metadata +62 -43
data/ext/sharp-config.yml
CHANGED
@@ -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]
|
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 =
|
90
|
-
remote_versions =
|
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 ">
|
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]
|
130
|
+
bumped << @loader[cb]
|
126
131
|
else
|
127
132
|
ui.msg "* Skipping #{cb} cookbook"
|
128
133
|
end
|
129
134
|
end
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
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
|
-
|
324
|
-
|
325
|
-
if @
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
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
|
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(
|
348
|
-
|
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 "
|
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
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
24
|
-
|
25
|
-
|
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
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
-
|
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
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
|
-
|
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
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
74
|
-
|
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
|
-
|
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.
|
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
|
+
|