knife-hitori 0.0.1 → 0.0.2
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/lib/chef/knife/hitori/run_list_options.rb +22 -0
- data/lib/chef/knife/hitori/version.rb +1 -1
- data/lib/chef/knife/hitori_bootstrap.rb +34 -0
- data/lib/chef/knife/hitori_config.rb +1 -1
- data/lib/chef/knife/hitori_cook.rb +16 -136
- data/lib/chef/knife/hitori_data_bag_dec.rb +48 -0
- data/lib/chef/knife/hitori_data_bag_enc.rb +63 -0
- data/lib/chef/knife/hitori_hello.rb +1 -0
- data/lib/chef/knife/hitori_prepare.rb +1 -1
- data/lib/knife-hitori/{interactive_configure.rb → lib/interactive_configure.rb} +0 -0
- data/lib/knife-hitori/lib/run_remote_cook.rb +121 -0
- data/spec/knife/hitori_bootstrap_spec.rb +17 -0
- data/spec/knife/hitori_cook_spec.rb +113 -6
- metadata +10 -3
@@ -0,0 +1,22 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'chef/knife'
|
4
|
+
|
5
|
+
class Chef
|
6
|
+
class Knife
|
7
|
+
module RunListOptions
|
8
|
+
def self.included(receiver)
|
9
|
+
receiver.class_eval do
|
10
|
+
option :roles,
|
11
|
+
:short => '-R ROLE1[,ROLE2]',
|
12
|
+
:long => '--roles ROLE1[,ROLE2]',
|
13
|
+
:description => 'override run_list by roles'
|
14
|
+
|
15
|
+
option :recipes,
|
16
|
+
:long => '--recipes RECIPE1[,RECIPE2]',
|
17
|
+
:description => 'override run_list by recipes'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'chef/knife/hitori_base'
|
4
|
+
require 'chef/knife/hitori_prepare'
|
5
|
+
require 'chef/knife/hitori_cook'
|
6
|
+
require 'chef/knife/hitori/run_list_options'
|
7
|
+
|
8
|
+
|
9
|
+
class Chef
|
10
|
+
class Knife
|
11
|
+
class HitoriBootstrap < Knife
|
12
|
+
banner 'knife hitori bootstrap (options)'
|
13
|
+
include HitoriBase
|
14
|
+
include RunListOptions
|
15
|
+
|
16
|
+
def load_deps
|
17
|
+
Chef::Knife::HitoriPrepare.load_deps
|
18
|
+
Chef::Knife::HitoriCook.load_deps
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
def run
|
23
|
+
hitori_prepare = Chef::Knife::HitoriPrepare.new
|
24
|
+
hitori_prepare.config = config.dup
|
25
|
+
hitori_prepare.run
|
26
|
+
|
27
|
+
hitori_cook = Chef::Knife::HitoriCook.new
|
28
|
+
hitori_cook.config = config.dup
|
29
|
+
hitori_cook.run_remote([hitori_prepare.server])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
@@ -3,17 +3,17 @@
|
|
3
3
|
require 'chef/knife/hitori_base'
|
4
4
|
require 'set'
|
5
5
|
|
6
|
+
require 'knife-hitori/lib/run_remote_cook'
|
7
|
+
require 'chef/knife/hitori/run_list_options'
|
8
|
+
|
6
9
|
class Chef
|
7
10
|
class Knife
|
8
11
|
class HitoriCook < Knife
|
9
|
-
|
10
12
|
banner 'knife hitori cook (options)'
|
11
|
-
|
12
13
|
include HitoriBase
|
14
|
+
include RunListOptions
|
13
15
|
|
14
16
|
deps do
|
15
|
-
require 'net/ssh'
|
16
|
-
require 'net/scp'
|
17
17
|
require 'fog'
|
18
18
|
end
|
19
19
|
|
@@ -21,15 +21,6 @@ class Chef
|
|
21
21
|
:long => '--local',
|
22
22
|
:description => 'run chef-solo locally'
|
23
23
|
|
24
|
-
option :roles,
|
25
|
-
:short => '-R ROLE1[,ROLE2]',
|
26
|
-
:long => '--roles ROLE1[,ROLE2]',
|
27
|
-
:description => 'override run_list by roles'
|
28
|
-
|
29
|
-
option :recipes,
|
30
|
-
:long => '--recipes RECIPE1[,RECIPE2]',
|
31
|
-
:description => 'override run_list by recipes'
|
32
|
-
|
33
24
|
option :install_chef,
|
34
25
|
:long => '--install-chef',
|
35
26
|
:description => 'Install chef before run cookbook. This process usually have done by hitori-prepare.'
|
@@ -81,6 +72,8 @@ class Chef
|
|
81
72
|
end
|
82
73
|
end
|
83
74
|
|
75
|
+
|
76
|
+
# @return [Hash]
|
84
77
|
def json_attrs
|
85
78
|
attrs = load_settings || {}
|
86
79
|
# Chef::Mixin::DeepMerge.merge(normal_attrs,normal_attrs_to_merge)
|
@@ -112,20 +105,23 @@ class Chef
|
|
112
105
|
|
113
106
|
|
114
107
|
#########################################################
|
115
|
-
## 盛大なコピペ
|
116
108
|
########################################################
|
117
|
-
def run_remote
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
109
|
+
def run_remote(server_list=nil)
|
110
|
+
if server_list
|
111
|
+
servers = server_list
|
112
|
+
else
|
113
|
+
servers = find_ec2_servers
|
114
|
+
unless servers && !servers.empty?
|
115
|
+
ui.warn ui.color('no server found', :red)
|
116
|
+
return
|
117
|
+
end
|
122
118
|
end
|
123
119
|
|
124
120
|
run_list = new_run_list
|
125
121
|
threads = []
|
126
122
|
servers.each_with_index do |server, idx|
|
127
123
|
threads << Thread.new {
|
128
|
-
RunRemoteCook.new(Chef::Config, config, server, :idx => idx, :ui => ui, :run_list => run_list).run
|
124
|
+
KnifeHitori::RunRemoteCook.new(Chef::Config, config, server, :idx => idx, :ui => ui, :run_list => run_list).run
|
129
125
|
}
|
130
126
|
end
|
131
127
|
threads.each do |t|
|
@@ -171,121 +167,5 @@ class Chef
|
|
171
167
|
connection.servers.all.to_a
|
172
168
|
end
|
173
169
|
end
|
174
|
-
|
175
|
-
#############################################
|
176
|
-
class RunRemoteCook
|
177
|
-
attr_reader :config, :run_config, :server, :opts, :ui, :knife
|
178
|
-
def initialize(chef_config, run_config, server, opts)
|
179
|
-
@config = chef_config
|
180
|
-
@run_config = run_config
|
181
|
-
@server = server
|
182
|
-
@opts = opts
|
183
|
-
@ui = opts[:ui]
|
184
|
-
@knife = config.knife
|
185
|
-
end
|
186
|
-
|
187
|
-
def run
|
188
|
-
# Install Chef if needed
|
189
|
-
install_chef if run_config[:install_chef]
|
190
|
-
|
191
|
-
# Remove Old Cookbooks
|
192
|
-
console_log "Remove Old Chef Cookbooks in #{server.public_ip_address}\n"
|
193
|
-
mkdir_cmd = <<-EOS
|
194
|
-
[ -e #{knife[:remote_chef_dir]} ] && sudo rm -rf #{knife[:remote_chef_dir]}
|
195
|
-
sudo mkdir -p #{knife[:remote_chef_dir]}
|
196
|
-
sudo chmod 777 #{knife[:remote_chef_dir]}
|
197
|
-
EOS
|
198
|
-
exec_remote(mkdir_cmd)
|
199
|
-
# Upload Cookbooks
|
200
|
-
console_log "Uploading Chef Cookbooks to #{server.public_ip_address}\n"
|
201
|
-
remote_dir = "#{knife[:remote_chef_dir]}/#{File.basename(config[:chef_solo_base_dir])}"
|
202
|
-
chef_solo_filename = 'do_cook.sh'
|
203
|
-
files_info = []
|
204
|
-
files_info << {src: config[:chef_solo_base_dir], dest: knife[:remote_chef_dir], opts: {:recursive => true, :verbose => true}}
|
205
|
-
files_info << {src: KnifeHitori::resource(chef_solo_filename), dest: remote_dir, opts: {:verbose => true}}
|
206
|
-
upload_files(files_info)
|
207
|
-
console_log "Upload is done #{server.public_ip_address}\n"
|
208
|
-
# run chef-solo
|
209
|
-
script = <<-EOS
|
210
|
-
cd #{remote_dir}
|
211
|
-
tr -d '\\r' < #{chef_solo_filename} > .a
|
212
|
-
mv .a #{chef_solo_filename}
|
213
|
-
#{make_run_list_cmd}
|
214
|
-
sudo CHEF_ENV=#{config[:solo_environment]} sh #{chef_solo_filename}
|
215
|
-
EOS
|
216
|
-
exec_remote(script)
|
217
|
-
end
|
218
|
-
|
219
|
-
def install_chef
|
220
|
-
Chef::Log.debug 'install_chef'
|
221
|
-
console_log "Install Chef in #{server.public_ip_address}\n"
|
222
|
-
remote_filename = '/tmp/.install_chef_script'
|
223
|
-
upload_files([{src: knife[:template_file], dest: remote_filename, opts: {:verbose => true}}])
|
224
|
-
exec_remote("sudo sh #{remote_filename}; rm #{remote_filename}")
|
225
|
-
end
|
226
|
-
|
227
|
-
def make_run_list_cmd
|
228
|
-
script = ''
|
229
|
-
if opts[:run_list] && !opts[:run_list].empty?
|
230
|
-
script = <<-EOS
|
231
|
-
[ -d run_list/#{config[:solo_environment]} ] || mkdir -p run_list/#{config[:solo_environment]}
|
232
|
-
echo '#{opts[:run_list].join(',')}' > run_list/#{config[:solo_environment]}/`hostname`
|
233
|
-
EOS
|
234
|
-
end
|
235
|
-
script
|
236
|
-
end
|
237
|
-
|
238
|
-
#######################
|
239
|
-
def bg_color(text)
|
240
|
-
#Background colors
|
241
|
-
#40 Black
|
242
|
-
#41 Red
|
243
|
-
#42 Green
|
244
|
-
#43 Yellow
|
245
|
-
#44 Blue
|
246
|
-
#45 Magenta
|
247
|
-
#46 Cyan
|
248
|
-
#47 White
|
249
|
-
c = 47 - ((opts[:idx].to_i + 3) % 7)
|
250
|
-
"\e[#{c}m#{text}\e[0m"
|
251
|
-
end
|
252
|
-
|
253
|
-
def upload_files(files_info)
|
254
|
-
Net::SCP.start(server.public_ip_address, knife[:ssh_user], :keys => [knife[:identity_file]], :compression => true) do |scp|
|
255
|
-
channels = []
|
256
|
-
files_info.each do |info|
|
257
|
-
channels << scp.upload(info[:src], info[:dest], info[:opts])
|
258
|
-
end
|
259
|
-
channels.each do |ch|
|
260
|
-
ch.wait
|
261
|
-
end
|
262
|
-
end
|
263
|
-
end
|
264
|
-
|
265
|
-
def exec_remote(command)
|
266
|
-
Net::SSH.start(server.public_ip_address, knife[:ssh_user], :keys => [knife[:identity_file]]) do |ssh|
|
267
|
-
ssh.open_channel do |ch|
|
268
|
-
ch.request_pty do |pty, success|
|
269
|
-
raise 'Could not obtain pty' unless success
|
270
|
-
end
|
271
|
-
ch.exec(command) do |c, success|
|
272
|
-
abort 'could not execute command' unless success
|
273
|
-
ch.on_data do |c, data|
|
274
|
-
console_log data
|
275
|
-
end
|
276
|
-
|
277
|
-
ch.on_extended_data do |c, type, data|
|
278
|
-
console_log data
|
279
|
-
end
|
280
|
-
end
|
281
|
-
end
|
282
|
-
end
|
283
|
-
end
|
284
|
-
|
285
|
-
def console_log(msg)
|
286
|
-
print bg_color(msg)
|
287
|
-
end
|
288
|
-
end
|
289
|
-
|
290
170
|
end
|
291
171
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'chef/knife/hitori_base'
|
4
|
+
|
5
|
+
class Chef
|
6
|
+
class Knife
|
7
|
+
class HitoriDataBagDec < Knife
|
8
|
+
banner 'knife hitori data bag dec BAG ITEM (options)'
|
9
|
+
include HitoriBase
|
10
|
+
|
11
|
+
option :secret_file,
|
12
|
+
:long => '--secret-file SECRET_FILE',
|
13
|
+
:description => 'A file containing the secret key to use to encrypt data bag item values'
|
14
|
+
|
15
|
+
def run
|
16
|
+
config[:bag], config[:item] = @name_args
|
17
|
+
exit 1 unless validate
|
18
|
+
|
19
|
+
decrypt_data_bag
|
20
|
+
end
|
21
|
+
|
22
|
+
def decrypt_data_bag
|
23
|
+
secret = Chef::EncryptedDataBagItem.load_secret(secret_file_path)
|
24
|
+
spr_creds = Chef::EncryptedDataBagItem.load(config[:bag], config[:item], secret)
|
25
|
+
puts JSON.pretty_generate(spr_creds.to_hash)
|
26
|
+
end
|
27
|
+
|
28
|
+
def secret_file_path
|
29
|
+
config[:secret_file] || Chef::Config[:encrypted_data_bag_secret]
|
30
|
+
end
|
31
|
+
|
32
|
+
def validate
|
33
|
+
if config[:bag].nil? || config[:item].nil?
|
34
|
+
ui.error('Please specify BAG and ITEM')
|
35
|
+
return false
|
36
|
+
end
|
37
|
+
|
38
|
+
unless secret_file_path
|
39
|
+
ui.error('Please specify EncryptKey by Chef Config "encrypted_data_bag_secret" or --secret-file')
|
40
|
+
return false
|
41
|
+
end
|
42
|
+
|
43
|
+
return true
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'chef/knife/hitori_base'
|
4
|
+
|
5
|
+
class Chef
|
6
|
+
class Knife
|
7
|
+
class HitoriDataBagEnc < Knife
|
8
|
+
banner 'knife hitori data bag enc BAG ITEM (options)'
|
9
|
+
include HitoriBase
|
10
|
+
|
11
|
+
option :json_file,
|
12
|
+
:short => '-j JSON_FILE',
|
13
|
+
:description => 'A json file for encryption'
|
14
|
+
|
15
|
+
option :secret_file,
|
16
|
+
:long => '--secret-file SECRET_FILE',
|
17
|
+
:description => 'A file containing the secret key to use to encrypt data bag item values'
|
18
|
+
|
19
|
+
def run
|
20
|
+
config[:bag], config[:item] = @name_args
|
21
|
+
exit 1 unless validate
|
22
|
+
|
23
|
+
create_data_bag
|
24
|
+
end
|
25
|
+
|
26
|
+
def create_data_bag
|
27
|
+
data_bag_path = Chef::Config[:data_bag_path]
|
28
|
+
secret = Chef::EncryptedDataBagItem.load_secret(secret_file_path)
|
29
|
+
data = JSON.parse(File.read(config[:json_file]))
|
30
|
+
encrypted_data = Chef::EncryptedDataBagItem.encrypt_data_bag_item(data, secret)
|
31
|
+
bag_dir = "#{data_bag_path}/#{config[:bag]}"
|
32
|
+
FileUtils.mkpath(bag_dir)
|
33
|
+
write_path = "#{bag_dir}/#{config[:item]}.json"
|
34
|
+
File.write(write_path, encrypted_data.to_json)
|
35
|
+
ui.info ui.color("Created encrypted data bag item at #{write_path}", :green)
|
36
|
+
end
|
37
|
+
|
38
|
+
def secret_file_path
|
39
|
+
config[:secret_file] || Chef::Config[:encrypted_data_bag_secret]
|
40
|
+
end
|
41
|
+
|
42
|
+
def validate
|
43
|
+
if config[:bag].nil? || config[:item].nil?
|
44
|
+
ui.error('Please specify BAG and ITEM')
|
45
|
+
return false
|
46
|
+
end
|
47
|
+
|
48
|
+
if config[:json_file].nil?
|
49
|
+
ui.error('You have not provided a json file for encryption')
|
50
|
+
return false
|
51
|
+
end
|
52
|
+
|
53
|
+
unless secret_file_path
|
54
|
+
ui.error('Please specify EncryptKey by Chef Config "encrypted_data_bag_secret" or --secret-file')
|
55
|
+
return false
|
56
|
+
end
|
57
|
+
|
58
|
+
return true
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
File without changes
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'net/ssh'
|
4
|
+
require 'net/scp'
|
5
|
+
|
6
|
+
module KnifeHitori
|
7
|
+
class RunRemoteCook
|
8
|
+
attr_reader :config, :run_config, :server, :opts, :ui, :knife
|
9
|
+
|
10
|
+
def initialize(chef_config, run_config, server, opts)
|
11
|
+
@config = chef_config
|
12
|
+
@run_config = run_config
|
13
|
+
@server = server
|
14
|
+
@opts = opts
|
15
|
+
@ui = opts[:ui]
|
16
|
+
@knife = config.knife
|
17
|
+
end
|
18
|
+
|
19
|
+
def run
|
20
|
+
# Install Chef if needed
|
21
|
+
install_chef if run_config[:install_chef]
|
22
|
+
|
23
|
+
# Remove Old Cookbooks
|
24
|
+
console_log "Remove Old Chef Cookbooks in #{server.public_ip_address}\n"
|
25
|
+
mkdir_cmd = <<-EOS
|
26
|
+
[ -e #{knife[:remote_chef_dir]} ] && sudo rm -rf #{knife[:remote_chef_dir]}
|
27
|
+
sudo mkdir -p #{knife[:remote_chef_dir]}
|
28
|
+
sudo chmod 777 #{knife[:remote_chef_dir]}
|
29
|
+
EOS
|
30
|
+
exec_remote(mkdir_cmd)
|
31
|
+
# Upload Cookbooks
|
32
|
+
console_log "Uploading Chef Cookbooks to #{server.public_ip_address}\n"
|
33
|
+
remote_dir = "#{knife[:remote_chef_dir]}/#{::File.basename(config[:chef_solo_base_dir])}"
|
34
|
+
chef_solo_filename = 'do_cook.sh'
|
35
|
+
files_info = []
|
36
|
+
files_info << {src: config[:chef_solo_base_dir], dest: knife[:remote_chef_dir], opts: {:recursive => true, :verbose => true}}
|
37
|
+
files_info << {src: KnifeHitori::resource(chef_solo_filename), dest: remote_dir, opts: {:verbose => true}}
|
38
|
+
upload_files(files_info)
|
39
|
+
console_log "Upload is done #{server.public_ip_address}\n"
|
40
|
+
# run chef-solo
|
41
|
+
script = <<-EOS
|
42
|
+
cd #{remote_dir}
|
43
|
+
tr -d '\\r' < #{chef_solo_filename} > .a
|
44
|
+
mv .a #{chef_solo_filename}
|
45
|
+
#{make_run_list_cmd}
|
46
|
+
sudo CHEF_ENV=#{config[:solo_environment]} sh #{chef_solo_filename}
|
47
|
+
EOS
|
48
|
+
exec_remote(script)
|
49
|
+
end
|
50
|
+
|
51
|
+
def install_chef
|
52
|
+
Chef::Log.debug 'install_chef'
|
53
|
+
console_log "Install Chef in #{server.public_ip_address}\n"
|
54
|
+
remote_filename = '/tmp/.install_chef_script'
|
55
|
+
upload_files([{src: knife[:template_file], dest: remote_filename, opts: {:verbose => true}}])
|
56
|
+
exec_remote("sudo sh #{remote_filename}; rm #{remote_filename}")
|
57
|
+
end
|
58
|
+
|
59
|
+
def make_run_list_cmd
|
60
|
+
script = ''
|
61
|
+
if opts[:run_list] && !opts[:run_list].empty?
|
62
|
+
script = <<-EOS
|
63
|
+
[ -d run_list/#{config[:solo_environment]} ] || mkdir -p run_list/#{config[:solo_environment]}
|
64
|
+
echo '#{opts[:run_list].join(',')}' > run_list/#{config[:solo_environment]}/`hostname`
|
65
|
+
EOS
|
66
|
+
end
|
67
|
+
script
|
68
|
+
end
|
69
|
+
|
70
|
+
#######################
|
71
|
+
def bg_color(text)
|
72
|
+
#Background colors
|
73
|
+
#40 Black
|
74
|
+
#41 Red
|
75
|
+
#42 Green
|
76
|
+
#43 Yellow
|
77
|
+
#44 Blue
|
78
|
+
#45 Magenta
|
79
|
+
#46 Cyan
|
80
|
+
#47 White
|
81
|
+
c = 47 - ((opts[:idx].to_i + 3) % 7)
|
82
|
+
"\e[#{c}m#{text}\e[0m"
|
83
|
+
end
|
84
|
+
|
85
|
+
def upload_files(files_info)
|
86
|
+
Net::SCP.start(server.public_ip_address, knife[:ssh_user], :keys => [knife[:identity_file]], :compression => true) do |scp|
|
87
|
+
channels = []
|
88
|
+
files_info.each do |info|
|
89
|
+
channels << scp.upload(info[:src], info[:dest], info[:opts])
|
90
|
+
end
|
91
|
+
channels.each do |ch|
|
92
|
+
ch.wait
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def exec_remote(command)
|
98
|
+
Net::SSH.start(server.public_ip_address, knife[:ssh_user], :keys => [knife[:identity_file]]) do |ssh|
|
99
|
+
ssh.open_channel do |ch|
|
100
|
+
ch.request_pty do |pty, success|
|
101
|
+
raise 'Could not obtain pty' unless success
|
102
|
+
end
|
103
|
+
ch.exec(command) do |c, success|
|
104
|
+
abort 'could not execute command' unless success
|
105
|
+
ch.on_data do |c, data|
|
106
|
+
console_log data
|
107
|
+
end
|
108
|
+
|
109
|
+
ch.on_extended_data do |c, type, data|
|
110
|
+
console_log data
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def console_log(msg)
|
118
|
+
print bg_color(msg)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'chef/knife/hitori_bootstrap'
|
4
|
+
|
5
|
+
describe 'HitoriBootstrap' do
|
6
|
+
before do
|
7
|
+
@obj = Chef::Knife::HitoriBootstrap.new(%w(-R api))
|
8
|
+
end
|
9
|
+
|
10
|
+
describe :run do
|
11
|
+
it 'should call HitoriPrepare and HitoriCook' do
|
12
|
+
Chef::Knife::HitoriPrepare.any_instance.should_receive(:run).once
|
13
|
+
Chef::Knife::HitoriCook.any_instance.should_receive(:run_remote).once
|
14
|
+
@obj.run
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -5,6 +5,7 @@ require 'fileutils'
|
|
5
5
|
require 'spec_helper'
|
6
6
|
|
7
7
|
require 'chef/knife/hitori_cook'
|
8
|
+
require 'chef/client'
|
8
9
|
|
9
10
|
|
10
11
|
describe 'hitori_cook' do
|
@@ -28,9 +29,32 @@ describe 'hitori_cook' do
|
|
28
29
|
template_file: 'my_template',
|
29
30
|
}
|
30
31
|
end
|
32
|
+
|
33
|
+
it 'should call run_local if config[:local]' do
|
34
|
+
@obj.should_receive(:run_local)
|
35
|
+
@obj.config[:local] = true
|
36
|
+
@obj.run
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should call run_remote if not config[:local]' do
|
40
|
+
@obj.should_receive(:run_remote)
|
41
|
+
@obj.config[:local] = nil
|
42
|
+
@obj.run
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe :run_local do
|
47
|
+
it 'should call ChefClient.run' do
|
48
|
+
@obj.config[:environment] = nil
|
49
|
+
chef_client = double('chef_client')
|
50
|
+
Chef::Client.should_receive(:new).with({json: 'attrs'}).and_return(chef_client)
|
51
|
+
@obj.stub(:json_attrs => {json: 'attrs'})
|
52
|
+
chef_client.should_receive(:run)
|
53
|
+
@obj.run_local
|
54
|
+
end
|
31
55
|
end
|
32
56
|
|
33
|
-
describe :
|
57
|
+
describe :update_environment do
|
34
58
|
before(:each) do
|
35
59
|
Chef::Config[:data_bag_path_tpl] = 'databag/%s'
|
36
60
|
Chef::Config[:settings_path_tpl] = 'settings/%s'
|
@@ -44,6 +68,27 @@ describe 'hitori_cook' do
|
|
44
68
|
its(:encrypted_data_bag_secret) {should == 'enc/my_env'}
|
45
69
|
end
|
46
70
|
|
71
|
+
describe :json_attrs do
|
72
|
+
before() do
|
73
|
+
@data = {'my' => 'data', 'run_list' => 'role[magic]'}
|
74
|
+
temp = Tempfile.open('hitori-')
|
75
|
+
Chef::Config[:settings_path] = temp.path
|
76
|
+
temp.write JSON.dump(@data)
|
77
|
+
temp.close
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should return json data of Config[:settings_path]' do
|
81
|
+
@obj.json_attrs.should == @data
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should update run_list if options is specified' do
|
85
|
+
@obj.config[:recipes] = 'cat'
|
86
|
+
@obj.config[:roles] = 'dog'
|
87
|
+
ret = @obj.json_attrs
|
88
|
+
ret['run_list'].sort.should == %w(recipe[cat] role[dog]).sort
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
47
92
|
describe :new_run_list do
|
48
93
|
before(:each) do
|
49
94
|
@obj.config[:roles] = 'role1, role2'
|
@@ -57,11 +102,73 @@ describe 'hitori_cook' do
|
|
57
102
|
it {should include('recipe[rcp2]')}
|
58
103
|
end
|
59
104
|
|
60
|
-
describe :
|
61
|
-
|
62
|
-
@obj.
|
63
|
-
|
64
|
-
|
105
|
+
describe :run_remote do
|
106
|
+
before do
|
107
|
+
@obj.should_receive(:find_ec2_servers).and_return(%w(s1 s2))
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'should call RunRemoteCook.run' do
|
111
|
+
rrc = double('RunRemoteCook')
|
112
|
+
KnifeHitori::RunRemoteCook.should_receive(:new).
|
113
|
+
with(Chef::Config, @obj.config, 's1', anything).
|
114
|
+
and_return(rrc)
|
115
|
+
KnifeHitori::RunRemoteCook.should_receive(:new).
|
116
|
+
with(Chef::Config, @obj.config, 's2', anything).
|
117
|
+
and_return(rrc)
|
118
|
+
rrc.should_receive(:run).twice
|
119
|
+
@obj.run_remote
|
65
120
|
end
|
66
121
|
end
|
122
|
+
|
123
|
+
describe :fetch_server_info do
|
124
|
+
before do
|
125
|
+
@s1, @s2, @s3 = %w(s1 s2 s3).map{|s|
|
126
|
+
x = double(s).as_null_object
|
127
|
+
x.stub_chain(:tags, :[])
|
128
|
+
x.stub_chain(:tags, :[]).with('Name').and_return(s)
|
129
|
+
x.stub_chain(:tags, :[]).with('my_tag').and_return('tag_' + s)
|
130
|
+
x.stub(:groups => [s])
|
131
|
+
x.stub(:public_ip_address => 'ip_'+s)
|
132
|
+
x
|
133
|
+
}
|
134
|
+
@obj.should_receive(:server_info_list).and_return([@s1, @s2, @s3])
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'should return servers by tag' do
|
138
|
+
@obj.config[:tag] = 'my_tag=tag_s2'
|
139
|
+
ret = @obj.fetch_server_info
|
140
|
+
ret.size.should == 1
|
141
|
+
ret[0].should == @s2
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'should return servers by groups' do
|
145
|
+
@obj.config[:groups] = 's1,s3'
|
146
|
+
ret = @obj.fetch_server_info
|
147
|
+
ret.size.should == 2
|
148
|
+
ret.should == [@s1, @s3]
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'should return servers by Name' do
|
152
|
+
@obj.config[:name] = 's1'
|
153
|
+
ret = @obj.fetch_server_info
|
154
|
+
ret.size.should == 1
|
155
|
+
ret.should == [@s1]
|
156
|
+
end
|
157
|
+
|
158
|
+
it 'should return servers by public_ip_address' do
|
159
|
+
@obj.config[:public_ip_address] = 'ip_s3'
|
160
|
+
ret = @obj.fetch_server_info
|
161
|
+
ret.size.should == 1
|
162
|
+
ret.should == [@s3]
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'should return nil if no server matches' do
|
166
|
+
ret = @obj.fetch_server_info
|
167
|
+
ret.should == nil
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
|
172
|
+
|
173
|
+
|
67
174
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knife-hitori
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-06-
|
12
|
+
date: 2013-06-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: chef
|
@@ -120,14 +120,19 @@ files:
|
|
120
120
|
- README.md
|
121
121
|
- Rakefile
|
122
122
|
- knife-hitori.gemspec
|
123
|
+
- lib/chef/knife/hitori/run_list_options.rb
|
123
124
|
- lib/chef/knife/hitori/version.rb
|
124
125
|
- lib/chef/knife/hitori_base.rb
|
126
|
+
- lib/chef/knife/hitori_bootstrap.rb
|
125
127
|
- lib/chef/knife/hitori_config.rb
|
126
128
|
- lib/chef/knife/hitori_cook.rb
|
129
|
+
- lib/chef/knife/hitori_data_bag_dec.rb
|
130
|
+
- lib/chef/knife/hitori_data_bag_enc.rb
|
127
131
|
- lib/chef/knife/hitori_hello.rb
|
128
132
|
- lib/chef/knife/hitori_prepare.rb
|
129
133
|
- lib/knife-hitori.rb
|
130
|
-
- lib/knife-hitori/interactive_configure.rb
|
134
|
+
- lib/knife-hitori/lib/interactive_configure.rb
|
135
|
+
- lib/knife-hitori/lib/run_remote_cook.rb
|
131
136
|
- lib/knife-hitori/resources/centos_bootstrap.erb
|
132
137
|
- lib/knife-hitori/resources/do_cook.sh
|
133
138
|
- lib/knife-hitori/resources/knife.erb
|
@@ -137,6 +142,7 @@ files:
|
|
137
142
|
- refs/run_chef_solo.sh
|
138
143
|
- refs/util/create_encrypt_databag.rb
|
139
144
|
- refs/util/crypt_file.rb
|
145
|
+
- spec/knife/hitori_bootstrap_spec.rb
|
140
146
|
- spec/knife/hitori_config_spec.rb
|
141
147
|
- spec/knife/hitori_cook_spec.rb
|
142
148
|
- spec/knife/hitori_hello_spec.rb
|
@@ -168,6 +174,7 @@ signing_key:
|
|
168
174
|
specification_version: 3
|
169
175
|
summary: knife subcommand
|
170
176
|
test_files:
|
177
|
+
- spec/knife/hitori_bootstrap_spec.rb
|
171
178
|
- spec/knife/hitori_config_spec.rb
|
172
179
|
- spec/knife/hitori_cook_spec.rb
|
173
180
|
- spec/knife/hitori_hello_spec.rb
|