knife-ec2 0.5.14 → 0.6.0
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/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
|