knife-ec2 0.5.14 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/knife-ec2.gemspec +1 -1
- data/lib/chef/knife/ec2_base.rb +0 -1
- data/lib/chef/knife/ec2_server_create.rb +117 -50
- data/lib/chef/knife/ec2_server_list.rb +41 -4
- data/lib/knife-ec2/version.rb +1 -1
- data/spec/unit/ec2_server_create_spec.rb +50 -0
- metadata +5 -4
data/knife-ec2.gemspec
CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.files = `git ls-files`.split("\n")
|
17
17
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
18
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
-
s.add_dependency "fog", "~> 1.
|
19
|
+
s.add_dependency "fog", "~> 1.6"
|
20
20
|
s.add_dependency "chef", ">= 0.10.10"
|
21
21
|
%w(rspec-core rspec-expectations rspec-mocks rspec_junit_formatter).each { |gem| s.add_development_dependency gem }
|
22
22
|
|
data/lib/chef/knife/ec2_base.rb
CHANGED
@@ -42,8 +42,7 @@ class Chef
|
|
42
42
|
:short => "-f FLAVOR",
|
43
43
|
:long => "--flavor FLAVOR",
|
44
44
|
:description => "The flavor of server (m1.small, m1.medium, etc)",
|
45
|
-
:proc => Proc.new { |f| Chef::Config[:knife][:flavor] = f }
|
46
|
-
:default => "m1.small"
|
45
|
+
:proc => Proc.new { |f| Chef::Config[:knife][:flavor] = f }
|
47
46
|
|
48
47
|
option :image,
|
49
48
|
:short => "-I IMAGE",
|
@@ -73,13 +72,13 @@ class Chef
|
|
73
72
|
:short => "-Z ZONE",
|
74
73
|
:long => "--availability-zone ZONE",
|
75
74
|
:description => "The Availability Zone",
|
76
|
-
:default => "us-east-1b",
|
77
75
|
:proc => Proc.new { |key| Chef::Config[:knife][:availability_zone] = key }
|
78
76
|
|
79
77
|
option :chef_node_name,
|
80
78
|
:short => "-N NAME",
|
81
79
|
:long => "--node-name NAME",
|
82
|
-
:description => "The Chef node name for your new node"
|
80
|
+
:description => "The Chef node name for your new node",
|
81
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:chef_node_name] = key }
|
83
82
|
|
84
83
|
option :ssh_key_name,
|
85
84
|
:short => "-S KEY",
|
@@ -105,6 +104,13 @@ class Chef
|
|
105
104
|
:default => "22",
|
106
105
|
:proc => Proc.new { |key| Chef::Config[:knife][:ssh_port] = key }
|
107
106
|
|
107
|
+
option :ssh_gateway,
|
108
|
+
:short => "-w GATEWAY",
|
109
|
+
:long => "--ssh-gateway GATEWAY",
|
110
|
+
:description => "The ssh gateway server",
|
111
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:ssh_gateway] = key }
|
112
|
+
|
113
|
+
|
108
114
|
option :identity_file,
|
109
115
|
:short => "-i IDENTITY_FILE",
|
110
116
|
:long => "--identity-file IDENTITY_FILE",
|
@@ -123,8 +129,7 @@ class Chef
|
|
123
129
|
:short => "-d DISTRO",
|
124
130
|
:long => "--distro DISTRO",
|
125
131
|
:description => "Bootstrap a distro using a template; default is 'chef-full'",
|
126
|
-
:proc => Proc.new { |d| Chef::Config[:knife][:distro] = d }
|
127
|
-
:default => "chef-full"
|
132
|
+
:proc => Proc.new { |d| Chef::Config[:knife][:distro] = d }
|
128
133
|
|
129
134
|
option :template_file,
|
130
135
|
:long => "--template-file TEMPLATE",
|
@@ -136,30 +141,31 @@ class Chef
|
|
136
141
|
:long => "--ebs-size SIZE",
|
137
142
|
:description => "The size of the EBS volume in GB, for EBS-backed instances"
|
138
143
|
|
144
|
+
option :ebs_optimized,
|
145
|
+
:long => "--ebs-optimized",
|
146
|
+
:description => "Enabled optimized EBS I/O"
|
147
|
+
|
139
148
|
option :ebs_no_delete_on_term,
|
140
149
|
:long => "--ebs-no-delete-on-term",
|
141
|
-
:description => "Do not delete EBS
|
150
|
+
:description => "Do not delete EBS volume on instance termination"
|
142
151
|
|
143
152
|
option :run_list,
|
144
153
|
:short => "-r RUN_LIST",
|
145
154
|
:long => "--run-list RUN_LIST",
|
146
155
|
:description => "Comma separated list of roles/recipes to apply",
|
147
|
-
:proc => lambda { |o| o.split(/[\s,]+/) }
|
148
|
-
:default => []
|
156
|
+
:proc => lambda { |o| o.split(/[\s,]+/) }
|
149
157
|
|
150
158
|
option :json_attributes,
|
151
159
|
:short => "-j JSON",
|
152
160
|
:long => "--json-attributes JSON",
|
153
161
|
:description => "A JSON string to be added to the first run of chef-client",
|
154
|
-
:proc => lambda { |o| JSON.parse(o) }
|
155
|
-
:default => {}
|
156
|
-
|
162
|
+
:proc => lambda { |o| JSON.parse(o) }
|
157
163
|
|
158
164
|
option :subnet_id,
|
159
165
|
:short => "-s SUBNET-ID",
|
160
166
|
:long => "--subnet SUBNET-ID",
|
161
167
|
:description => "create node in this Virtual Private Cloud Subnet ID (implies VPC mode)",
|
162
|
-
:
|
168
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:subnet_id] = key }
|
163
169
|
|
164
170
|
option :host_key_verify,
|
165
171
|
:long => "--[no-]host-key-verify",
|
@@ -174,8 +180,29 @@ class Chef
|
|
174
180
|
:proc => Proc.new { |m| Chef::Config[:knife][:aws_user_data] = m },
|
175
181
|
:default => nil
|
176
182
|
|
177
|
-
|
178
|
-
|
183
|
+
Chef::Config[:knife][:hints] ||= {"ec2" => {}}
|
184
|
+
option :hint,
|
185
|
+
:long => "--hint HINT_NAME[=HINT_FILE]",
|
186
|
+
:description => "Specify Ohai Hint to be set on the bootstrap target. Use multiple --hint options to specify multiple hints.",
|
187
|
+
:proc => Proc.new { |h|
|
188
|
+
name, path = h.split("=")
|
189
|
+
Chef::Config[:knife][:hints][name] = path ? JSON.parse(::File.read(path)) : Hash.new
|
190
|
+
}
|
191
|
+
|
192
|
+
option :ephemeral,
|
193
|
+
:long => "--ephemeral EPHEMERAL_DEVICES",
|
194
|
+
:description => "Comma separated list of device locations (eg - /dev/sdb) to map ephemeral devices",
|
195
|
+
:proc => lambda { |o| o.split(/[\s,]+/) },
|
196
|
+
:default => []
|
197
|
+
|
198
|
+
option :server_connect_attribute,
|
199
|
+
:long => "--server-connect-attribute ATTRIBUTE",
|
200
|
+
:short => "-a ATTRIBUTE",
|
201
|
+
:description => "The EC2 server attribute to use for SSH connection",
|
202
|
+
:default => nil
|
203
|
+
|
204
|
+
def tcp_test_ssh(hostname, ssh_port)
|
205
|
+
tcp_socket = TCPSocket.new(hostname, ssh_port)
|
179
206
|
readable = IO.select([tcp_socket], nil, nil, 5)
|
180
207
|
if readable
|
181
208
|
Chef::Log.debug("sshd accepting connections on #{hostname}, banner is #{tcp_socket.gets}")
|
@@ -184,23 +211,10 @@ class Chef
|
|
184
211
|
else
|
185
212
|
false
|
186
213
|
end
|
187
|
-
rescue SocketError
|
214
|
+
rescue SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ENETUNREACH, IOError
|
188
215
|
sleep 2
|
189
216
|
false
|
190
|
-
rescue Errno::ETIMEDOUT
|
191
|
-
false
|
192
|
-
rescue Errno::EPERM
|
193
|
-
false
|
194
|
-
rescue Errno::ECONNREFUSED
|
195
|
-
sleep 2
|
196
|
-
false
|
197
|
-
# This happens on EC2 quite often
|
198
|
-
rescue Errno::EHOSTUNREACH
|
199
|
-
sleep 2
|
200
|
-
false
|
201
|
-
# This happens on EC2 sometimes
|
202
|
-
rescue Errno::ENETUNREACH
|
203
|
-
sleep 2
|
217
|
+
rescue Errno::EPERM, Errno::ETIMEDOUT
|
204
218
|
false
|
205
219
|
ensure
|
206
220
|
tcp_socket && tcp_socket.close
|
@@ -236,7 +250,7 @@ class Chef
|
|
236
250
|
# default security group id at this point unless we look it up, hence
|
237
251
|
# 'default' is printed if no id was specified.
|
238
252
|
printed_security_groups = "default"
|
239
|
-
printed_security_groups = @server.groups.join(", ") if @server.groups
|
253
|
+
printed_security_groups = @server.groups.join(", ") if @server.groups
|
240
254
|
msg_pair("Security Groups", printed_security_groups) unless vpc_mode? or (@server.groups.nil? and @server.security_group_ids)
|
241
255
|
|
242
256
|
printed_security_group_ids = "default"
|
@@ -264,14 +278,9 @@ class Chef
|
|
264
278
|
|
265
279
|
print "\n#{ui.color("Waiting for sshd", :magenta)}"
|
266
280
|
|
267
|
-
|
281
|
+
wait_for_sshd(ssh_connect_host)
|
268
282
|
|
269
|
-
|
270
|
-
sleep @initial_sleep_delay ||= (vpc_mode? ? 40 : 10)
|
271
|
-
puts("done")
|
272
|
-
}
|
273
|
-
|
274
|
-
bootstrap_for_node(@server,fqdn).run
|
283
|
+
bootstrap_for_node(@server,ssh_connect_host).run
|
275
284
|
|
276
285
|
puts "\n"
|
277
286
|
msg_pair("Instance ID", @server.id)
|
@@ -300,6 +309,9 @@ class Chef
|
|
300
309
|
end
|
301
310
|
end
|
302
311
|
end
|
312
|
+
if config[:ebs_optimized]
|
313
|
+
msg_pair("EBS is Optimized", @server.ebs_optimized.to_s)
|
314
|
+
end
|
303
315
|
if vpc_mode?
|
304
316
|
msg_pair("Subnet ID", @server.subnet_id)
|
305
317
|
else
|
@@ -309,22 +321,23 @@ class Chef
|
|
309
321
|
end
|
310
322
|
msg_pair("Private IP Address", @server.private_ip_address)
|
311
323
|
msg_pair("Environment", config[:environment] || '_default')
|
312
|
-
msg_pair("Run List", config[:run_list].join(', '))
|
313
|
-
msg_pair("JSON Attributes",config[:json_attributes]) unless config[:json_attributes].empty?
|
324
|
+
msg_pair("Run List", (config[:run_list] || []).join(', '))
|
325
|
+
msg_pair("JSON Attributes",config[:json_attributes]) unless !config[:json_attributes] || config[:json_attributes].empty?
|
314
326
|
end
|
315
327
|
|
316
|
-
def bootstrap_for_node(server,
|
328
|
+
def bootstrap_for_node(server,ssh_host)
|
317
329
|
bootstrap = Chef::Knife::Bootstrap.new
|
318
|
-
bootstrap.name_args = [
|
319
|
-
bootstrap.config[:run_list] =
|
330
|
+
bootstrap.name_args = [ssh_host]
|
331
|
+
bootstrap.config[:run_list] = locate_config_value(:run_list) || []
|
320
332
|
bootstrap.config[:ssh_user] = config[:ssh_user]
|
321
333
|
bootstrap.config[:ssh_port] = config[:ssh_port]
|
334
|
+
bootstrap.config[:ssh_gateway] = config[:ssh_gateway]
|
322
335
|
bootstrap.config[:identity_file] = config[:identity_file]
|
323
|
-
bootstrap.config[:chef_node_name] =
|
336
|
+
bootstrap.config[:chef_node_name] = locate_config_value(:chef_node_name) || server.id
|
324
337
|
bootstrap.config[:prerelease] = config[:prerelease]
|
325
338
|
bootstrap.config[:bootstrap_version] = locate_config_value(:bootstrap_version)
|
326
|
-
bootstrap.config[:first_boot_attributes] =
|
327
|
-
bootstrap.config[:distro] = locate_config_value(:distro)
|
339
|
+
bootstrap.config[:first_boot_attributes] = locate_config_value(:json_attributes) || {}
|
340
|
+
bootstrap.config[:distro] = locate_config_value(:distro) || "chef-full"
|
328
341
|
bootstrap.config[:use_sudo] = true unless config[:ssh_user] == 'root'
|
329
342
|
bootstrap.config[:template_file] = locate_config_value(:template_file)
|
330
343
|
bootstrap.config[:environment] = config[:environment]
|
@@ -336,7 +349,7 @@ class Chef
|
|
336
349
|
def vpc_mode?
|
337
350
|
# Amazon Virtual Private Cloud requires a subnet_id. If
|
338
351
|
# present, do a few things differently
|
339
|
-
!!
|
352
|
+
!!locate_config_value(:subnet_id)
|
340
353
|
end
|
341
354
|
|
342
355
|
def ami
|
@@ -351,7 +364,7 @@ class Chef
|
|
351
364
|
ui.error("You have not provided a valid image (AMI) value. Please note the short option for this value recently changed from '-i' to '-I'.")
|
352
365
|
exit 1
|
353
366
|
end
|
354
|
-
|
367
|
+
|
355
368
|
if vpc_mode? and !!config[:security_groups]
|
356
369
|
ui.error("You are using a VPC, security groups specified with '-G' are not allowed, specify one or more security group ids with '-g' instead.")
|
357
370
|
exit 1
|
@@ -372,12 +385,12 @@ class Chef
|
|
372
385
|
server_def = {
|
373
386
|
:image_id => locate_config_value(:image),
|
374
387
|
:groups => config[:security_groups],
|
375
|
-
:security_group_ids =>
|
388
|
+
:security_group_ids => locate_config_value(:security_group_ids),
|
376
389
|
:flavor_id => locate_config_value(:flavor),
|
377
390
|
:key_name => Chef::Config[:knife][:aws_ssh_key_id],
|
378
391
|
:availability_zone => locate_config_value(:availability_zone)
|
379
392
|
}
|
380
|
-
server_def[:subnet_id] =
|
393
|
+
server_def[:subnet_id] = locate_config_value(:subnet_id) if vpc_mode?
|
381
394
|
|
382
395
|
if Chef::Config[:knife][:aws_user_data]
|
383
396
|
begin
|
@@ -387,6 +400,12 @@ class Chef
|
|
387
400
|
end
|
388
401
|
end
|
389
402
|
|
403
|
+
if config[:ebs_optimized]
|
404
|
+
server_def[:ebs_optimized] = "true"
|
405
|
+
else
|
406
|
+
server_def[:ebs_optimized] = "false"
|
407
|
+
end
|
408
|
+
|
390
409
|
if ami.root_device_type == "ebs"
|
391
410
|
ami_map = ami.block_device_mapping.first
|
392
411
|
ebs_size = begin
|
@@ -405,6 +424,7 @@ class Chef
|
|
405
424
|
else
|
406
425
|
ami_map["deleteOnTermination"]
|
407
426
|
end
|
427
|
+
|
408
428
|
server_def[:block_device_mapping] =
|
409
429
|
[{
|
410
430
|
'DeviceName' => ami_map["deviceName"],
|
@@ -413,8 +433,55 @@ class Chef
|
|
413
433
|
}]
|
414
434
|
end
|
415
435
|
|
436
|
+
(config[:ephemeral] || []).each_with_index do |device_name, i|
|
437
|
+
server_def[:block_device_mapping] = (server_def[:block_device_mapping] || []) << {'VirtualName' => "ephemeral#{i}", 'DeviceName' => device_name}
|
438
|
+
end
|
439
|
+
|
416
440
|
server_def
|
417
441
|
end
|
442
|
+
|
443
|
+
def wait_for_sshd(hostname)
|
444
|
+
config[:ssh_gateway] ? wait_for_tunnelled_sshd(hostname) : wait_for_direct_sshd(hostname, config[:ssh_port])
|
445
|
+
end
|
446
|
+
|
447
|
+
def wait_for_tunnelled_sshd(hostname)
|
448
|
+
print(".")
|
449
|
+
print(".") until tunnel_test_ssh(ssh_connect_host) {
|
450
|
+
sleep @initial_sleep_delay ||= (vpc_mode? ? 40 : 10)
|
451
|
+
puts("done")
|
452
|
+
}
|
453
|
+
end
|
454
|
+
|
455
|
+
def tunnel_test_ssh(hostname, &block)
|
456
|
+
gw_host, gw_user = config[:ssh_gateway].split('@').reverse
|
457
|
+
gw_host, gw_port = gw_host.split(':')
|
458
|
+
gateway = Net::SSH::Gateway.new(gw_host, gw_user, :port => gw_port || 22)
|
459
|
+
status = false
|
460
|
+
gateway.open(hostname, config[:ssh_port]) do |local_tunnel_port|
|
461
|
+
status = tcp_test_ssh('localhost', local_tunnel_port, &block)
|
462
|
+
end
|
463
|
+
status
|
464
|
+
rescue SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ENETUNREACH, IOError
|
465
|
+
sleep 2
|
466
|
+
false
|
467
|
+
rescue Errno::EPERM, Errno::ETIMEDOUT
|
468
|
+
false
|
469
|
+
end
|
470
|
+
|
471
|
+
def wait_for_direct_sshd(hostname, ssh_port)
|
472
|
+
print(".") until tcp_test_ssh(ssh_connect_host, ssh_port) {
|
473
|
+
sleep @initial_sleep_delay ||= (vpc_mode? ? 40 : 10)
|
474
|
+
puts("done")
|
475
|
+
}
|
476
|
+
end
|
477
|
+
|
478
|
+
def ssh_connect_host
|
479
|
+
@ssh_connect_host ||= if config[:server_connect_attribute]
|
480
|
+
server.send(config[:server_connect_attribute])
|
481
|
+
else
|
482
|
+
vpc_mode? ? server.private_ip_address : server.dns_name
|
483
|
+
end
|
484
|
+
end
|
418
485
|
end
|
419
486
|
end
|
420
487
|
end
|
@@ -27,6 +27,18 @@ class Chef
|
|
27
27
|
|
28
28
|
banner "knife ec2 server list (options)"
|
29
29
|
|
30
|
+
option :name,
|
31
|
+
:short => "-n",
|
32
|
+
:long => "--no-name",
|
33
|
+
:boolean => true,
|
34
|
+
:default => true,
|
35
|
+
:description => "Do not display name tag in output"
|
36
|
+
|
37
|
+
option :tags,
|
38
|
+
:short => "-t TAG1,TAG2",
|
39
|
+
:long => "--tags TAG1,TAG2",
|
40
|
+
:description => "List of tags to output"
|
41
|
+
|
30
42
|
def run
|
31
43
|
$stdout.sync = true
|
32
44
|
|
@@ -34,22 +46,49 @@ class Chef
|
|
34
46
|
|
35
47
|
server_list = [
|
36
48
|
ui.color('Instance ID', :bold),
|
49
|
+
|
50
|
+
if config[:name]
|
51
|
+
ui.color("Name", :bold)
|
52
|
+
end,
|
53
|
+
|
37
54
|
ui.color('Public IP', :bold),
|
38
55
|
ui.color('Private IP', :bold),
|
39
56
|
ui.color('Flavor', :bold),
|
40
57
|
ui.color('Image', :bold),
|
41
58
|
ui.color('SSH Key', :bold),
|
42
59
|
ui.color('Security Groups', :bold),
|
60
|
+
|
61
|
+
if config[:tags]
|
62
|
+
config[:tags].split(",").collect do |tag_name|
|
63
|
+
ui.color("Tag:#{tag_name}", :bold)
|
64
|
+
end
|
65
|
+
end,
|
66
|
+
|
43
67
|
ui.color('State', :bold)
|
44
|
-
]
|
68
|
+
].flatten.compact
|
69
|
+
|
70
|
+
output_column_count = server_list.length
|
71
|
+
|
45
72
|
connection.servers.all.each do |server|
|
46
73
|
server_list << server.id.to_s
|
74
|
+
|
75
|
+
if config[:name]
|
76
|
+
server_list << server.tags["Name"].to_s
|
77
|
+
end
|
78
|
+
|
47
79
|
server_list << server.public_ip_address.to_s
|
48
80
|
server_list << server.private_ip_address.to_s
|
49
81
|
server_list << server.flavor_id.to_s
|
50
82
|
server_list << server.image_id.to_s
|
51
83
|
server_list << server.key_name.to_s
|
52
84
|
server_list << server.groups.join(", ")
|
85
|
+
|
86
|
+
if config[:tags]
|
87
|
+
config[:tags].split(",").each do |tag_name|
|
88
|
+
server_list << server.tags[tag_name].to_s
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
53
92
|
server_list << begin
|
54
93
|
state = server.state.to_s.downcase
|
55
94
|
case state
|
@@ -62,11 +101,9 @@ class Chef
|
|
62
101
|
end
|
63
102
|
end
|
64
103
|
end
|
65
|
-
puts ui.list(server_list, :uneven_columns_across,
|
104
|
+
puts ui.list(server_list, :uneven_columns_across, output_column_count)
|
66
105
|
|
67
106
|
end
|
68
107
|
end
|
69
108
|
end
|
70
109
|
end
|
71
|
-
|
72
|
-
|
data/lib/knife-ec2/version.rb
CHANGED
@@ -128,6 +128,7 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
128
128
|
@knife_ec2_create.config[:ssh_user] = "ubuntu"
|
129
129
|
@knife_ec2_create.config[:identity_file] = "~/.ssh/aws-key.pem"
|
130
130
|
@knife_ec2_create.config[:ssh_port] = 22
|
131
|
+
@knife_ec2_create.config[:ssh_gateway] = 'bastion.host.com'
|
131
132
|
@knife_ec2_create.config[:chef_node_name] = "blarf"
|
132
133
|
@knife_ec2_create.config[:template_file] = '~/.chef/templates/my-bootstrap.sh.erb'
|
133
134
|
@knife_ec2_create.config[:distro] = 'ubuntu-10.04-magic-sparkles'
|
@@ -153,6 +154,10 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
153
154
|
@bootstrap.config[:ssh_user].should == 'ubuntu'
|
154
155
|
end
|
155
156
|
|
157
|
+
it "configures the bootstrap to use the correct ssh_gateway host" do
|
158
|
+
@bootstrap.config[:ssh_gateway].should == 'bastion.host.com'
|
159
|
+
end
|
160
|
+
|
156
161
|
it "configures the bootstrap to use the correct ssh identity file" do
|
157
162
|
@bootstrap.config[:identity_file].should == "~/.ssh/aws-key.pem"
|
158
163
|
end
|
@@ -192,6 +197,10 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
192
197
|
it "configured the bootstrap to use the desired template" do
|
193
198
|
@bootstrap.config[:template_file].should == '~/.chef/templates/my-bootstrap.sh.erb'
|
194
199
|
end
|
200
|
+
|
201
|
+
it "configured the bootstrap to set an ec2 hint (via Chef::Config)" do
|
202
|
+
Chef::Config[:knife][:hints]["ec2"].should_not be_nil
|
203
|
+
end
|
195
204
|
end
|
196
205
|
|
197
206
|
describe "when validating the command-line parameters" do
|
@@ -251,6 +260,47 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
251
260
|
|
252
261
|
server_def[:availability_zone].should == "dis-one"
|
253
262
|
end
|
263
|
+
|
264
|
+
it "adds the specified ephemeral device mappings" do
|
265
|
+
@knife_ec2_create.config[:ephemeral] = [ "/dev/sdb", "/dev/sdc", "/dev/sdd", "/dev/sde" ]
|
266
|
+
server_def = @knife_ec2_create.create_server_def
|
267
|
+
|
268
|
+
server_def[:block_device_mapping].should == [{ "VirtualName" => "ephemeral0", "DeviceName" => "/dev/sdb" },
|
269
|
+
{ "VirtualName" => "ephemeral1", "DeviceName" => "/dev/sdc" },
|
270
|
+
{ "VirtualName" => "ephemeral2", "DeviceName" => "/dev/sdd" },
|
271
|
+
{ "VirtualName" => "ephemeral3", "DeviceName" => "/dev/sde" }]
|
272
|
+
end
|
254
273
|
end
|
255
274
|
|
275
|
+
describe "ssh_connect_host" do
|
276
|
+
before(:each) do
|
277
|
+
@new_ec2_server.stub!(
|
278
|
+
:dns_name => 'public_name',
|
279
|
+
:private_ip_address => 'private_ip',
|
280
|
+
:custom => 'custom'
|
281
|
+
)
|
282
|
+
@knife_ec2_create.stub!(:server => @new_ec2_server)
|
283
|
+
end
|
284
|
+
|
285
|
+
describe "by default" do
|
286
|
+
it 'should use public dns name' do
|
287
|
+
@knife_ec2_create.ssh_connect_host.should == 'public_name'
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
describe "with vpc_mode?" do
|
292
|
+
it 'should use private ip' do
|
293
|
+
@knife_ec2_create.stub!(:vpc_mode? => true)
|
294
|
+
@knife_ec2_create.ssh_connect_host.should == 'private_ip'
|
295
|
+
end
|
296
|
+
|
297
|
+
end
|
298
|
+
|
299
|
+
describe "with custom server attribute" do
|
300
|
+
it 'should use custom server attribute' do
|
301
|
+
@knife_ec2_create.config[:server_connect_attribute] = 'custom'
|
302
|
+
@knife_ec2_create.ssh_connect_host.should == 'custom'
|
303
|
+
end
|
304
|
+
end
|
305
|
+
end
|
256
306
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knife-ec2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-
|
13
|
+
date: 2012-10-16 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: fog
|
@@ -19,7 +19,7 @@ dependencies:
|
|
19
19
|
requirements:
|
20
20
|
- - ~>
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '1.
|
22
|
+
version: '1.6'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -27,7 +27,7 @@ dependencies:
|
|
27
27
|
requirements:
|
28
28
|
- - ~>
|
29
29
|
- !ruby/object:Gem::Version
|
30
|
-
version: '1.
|
30
|
+
version: '1.6'
|
31
31
|
- !ruby/object:Gem::Dependency
|
32
32
|
name: chef
|
33
33
|
requirement: !ruby/object:Gem::Requirement
|
@@ -162,3 +162,4 @@ summary: EC2 Support for Chef's Knife Command
|
|
162
162
|
test_files:
|
163
163
|
- spec/spec_helper.rb
|
164
164
|
- spec/unit/ec2_server_create_spec.rb
|
165
|
+
has_rdoc: true
|