knife-ec2 0.8.0 → 0.10.0.rc.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/CHANGELOG.md +9 -3
- data/CONTRIBUTIONS.md +10 -0
- data/DOC_CHANGES.md +25 -10
- data/RELEASE_NOTES.md +41 -0
- data/knife-ec2.gemspec +3 -3
- data/lib/chef/knife/ec2_server_create.rb +125 -14
- data/lib/knife-ec2/version.rb +1 -1
- data/spec/unit/ec2_server_create_spec.rb +216 -5
- metadata +13 -11
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YzVmMmJhMWJhZWZhNjMzNDUzOWMyOGYzNDQzNjlkNWMyMDkxNjg1Mw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
OGU2MTdkOThjYjkzNjQ4MjJmMmZhNjk1YjM5MjE5ZGQzYjIxMWM4Yg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YTM2YWE1OTM2MDc5OTI4MjlhMmEzNzAxMGQxN2FlYWI3YzFjNjFmZjg0NGQy
|
10
|
+
MTc3ZWU3YTJjNTM0Mjc3ZTU4NWI5ZTkxZmM3MTI2ODAwOTZjMjk2NmVlNGY5
|
11
|
+
ZjkzNTMzYjJiNDQ1OTU2ZGFmYzQ0MzQ0ZDYyYjA4MjdhZmU1MTk=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
Njg1YTU2ZDhhYjc1NzZlOTNlZTkwZTIzYzIyZWIzMzQwZGEzYjM1YzBjN2Ew
|
14
|
+
OGIzMTgwY2UyYjNmODQ3ODk1ZjVjOTEyNmUxMGVjODUyYjI2ODhjYTNkNGFj
|
15
|
+
ODEzMmJjYmNjMTQ0NTYyOTMwNzllYzQzYzBkNzZhOGQ4MDEzOTk=
|
data/CHANGELOG.md
CHANGED
@@ -1,14 +1,20 @@
|
|
1
1
|
# knife-ec2 change log
|
2
2
|
|
3
3
|
Note: this log contains only changes from knife-ec2 release 0.8.0 and later
|
4
|
-
-- it does not contain the changes from prior
|
4
|
+
-- it does not contain the changes from prior releases. To view change history
|
5
5
|
prior to release 0.8.0, please visit the [source repository](https://github.com/opscode/knife-ec2/commits).
|
6
6
|
|
7
7
|
## Unreleased changes
|
8
|
-
|
9
8
|
None.
|
10
9
|
|
11
|
-
##
|
10
|
+
## Latest release: 0.10.0.rc.0
|
11
|
+
* Update `knife-windows` gem dependency to `knife-windows 0.8.rc.0` for improved Windows authentication integration
|
12
|
+
* Update `fog` gem dependency to `fog 1.23.0`
|
13
|
+
* Provisioned IOPS support via the `--provisioned-iops` and `--ebs-volume-type` options
|
14
|
+
* [KNIFE-464](https://tickets.opscode.com/browse/KNIFE-466) Knife ec2 should use gateway from net::ssh config if available
|
15
|
+
* [KNIFE-422](https://tickets.opscode.com/browse/KNIFE-422) Knife ec2 server create doesn't respect identity file of gateway server from ssh\_config
|
16
|
+
|
17
|
+
## Release: 0.8.0 (2014-03-10)
|
12
18
|
|
13
19
|
* [KNIFE-458](https://tickets.opscode.com/browse/KNIFE-458) Docs: Increase detail about necessary
|
14
20
|
options for VPC instance creation
|
data/CONTRIBUTIONS.md
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
<!---
|
2
|
+
This file is reset every time a new release is done. The contents of this file are for the currently unreleased version.
|
3
|
+
|
4
|
+
Example Contribution:
|
5
|
+
* **kalistec**: Improved file resource greatly.
|
6
|
+
-->
|
7
|
+
# knife-ec2 0.10.0:
|
8
|
+
|
9
|
+
* **mdellanoce**: Added ability to use SSH config (KNIFE-466)
|
10
|
+
* **victorlin**: Added ability to pass identify file for SSH Gateway on the command line (KNIFE-422)
|
data/DOC_CHANGES.md
CHANGED
@@ -4,18 +4,33 @@ This file is reset everytime when a new release is done. Contents of this file i
|
|
4
4
|
|
5
5
|
# knife-ec2 doc changes
|
6
6
|
|
7
|
-
|
8
|
-
The option --associate-ip was added to the knife-ec2 server create
|
9
|
-
subcommand.
|
7
|
+
Documentation changes are given below for **knife-ec2 version 0.10.0**.
|
10
8
|
|
11
|
-
|
9
|
+
## Provisioned IOPS support for `server create` command
|
12
10
|
|
13
|
-
|
11
|
+
Options are now available in the `knife ec2 server create` subcommand to
|
12
|
+
specify provisioned IOPS for the created instance.
|
13
|
+
|
14
|
+
### Option `--ebs-volume-type`
|
15
|
+
|
16
|
+
This command line option and associated plugin configuration `:ebs_volume_type` allow you to specify an EBS volume of type `standard` or `io1` as a `string` parameter to this option. The former is the default, the latter will allow the specification of a provisioned IOPS rate through the `--provisioned-iops` option.
|
17
|
+
|
18
|
+
### Option `--provisioned-iops`
|
19
|
+
This command line option and the associated `:ebs_provisioned_iops` plugin
|
20
|
+
confugration enables the EC2 instance to be configured with the specified
|
21
|
+
provisioned IOPS rate given as an argument to this option. It is only valid if
|
22
|
+
the EBS volume type is `io1` as specified by the `--ebs-volume-type` option
|
23
|
+
for this plugin.
|
24
|
+
|
25
|
+
## SSH Gateway from SSH Config
|
26
|
+
Any available SSH Gateway settings in your SSH configuration file are now used
|
27
|
+
by default. This includes using any SSH keys specified for the target host.
|
28
|
+
This allows simpler command-line usage of the knife plugin with less of a need
|
29
|
+
for complex command line invocations.
|
30
|
+
|
31
|
+
## Pass seperate SSH Gateway key
|
32
|
+
You can pass an SSH key to be used for authenticating to the SSH Gateway with
|
33
|
+
the --ssh-gateway-identity option.
|
14
34
|
|
15
|
-
```
|
16
|
-
--associate-public-ip
|
17
|
-
```
|
18
35
|
|
19
|
-
Associate public IP address to the VPC instance so that the public IP is available
|
20
|
-
during bootstrapping. Only valid with VPC instances.
|
21
36
|
|
data/RELEASE_NOTES.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
<!---
|
2
|
+
This file is reset every time a new release is done. The contents of this file are for the currently unreleased version.
|
3
|
+
|
4
|
+
Example Note:
|
5
|
+
|
6
|
+
## Example Heading
|
7
|
+
Details about the thing that changed that needs to get included in the Release Notes in markdown.
|
8
|
+
-->
|
9
|
+
# knife-ec2 0.10.rc.0 release notes:
|
10
|
+
This release of `knife-ec2` adds improvements around ssh configuration and EC2
|
11
|
+
IOPS provisioning. There is also a dependency update for the `fog` and `knife-windows` gems
|
12
|
+
to improve support for additional EC2 capabilities and Windows authentication
|
13
|
+
enhancements respectively.
|
14
|
+
|
15
|
+
Our MVP for this release is **Michael Dellanoce**, who contributed improvements
|
16
|
+
that allow re-use of your existing SSH configuration with knife-ec2,
|
17
|
+
particularly useful when dealing with SSH gateways. Michael, thank you for
|
18
|
+
taking the time to develop this feature.
|
19
|
+
|
20
|
+
See the [CHANGELOG](https://github.com/opscode/knife-ec2/blob/master/CHANGELOG.md) for a list of all changes in this release, and review
|
21
|
+
[DOC_CHANGES.md](https://github.com/opscode/knife-ec2/blob/master/DOC_CHANGES.md) for relevant documentation updates.
|
22
|
+
|
23
|
+
Issues with `knife-ec2` should be reported in the issue system at
|
24
|
+
https://github.com/opscode/knife-ec2/issues. Learn more about how you can
|
25
|
+
contribute features and bug fixes to `knife-ec2` at https://github.com/opscode/knife-ec2/blob/master/CONTRIBUTING.md.
|
26
|
+
|
27
|
+
## Features added in knife-ec2 0.10.0
|
28
|
+
|
29
|
+
* Provisioned IOPS support
|
30
|
+
* SSH workstation configuration integration (from Michael Dellanoce and Victor Lin)
|
31
|
+
|
32
|
+
## knife-ec2 on RubyGems and Github
|
33
|
+
https://rubygems.org/gems/knife-ec2
|
34
|
+
https://github.com/opscode/knife-ec2
|
35
|
+
|
36
|
+
## Issues fixed in knife-ec2 0.10.0
|
37
|
+
|
38
|
+
* Update `knife-windows` gem dependency to `knife-windows 0.8.0` for improved Windows authentication integration
|
39
|
+
* Update `fog` gem dependency to `fog 1.23.0`
|
40
|
+
* [KNIFE-464](https://tickets.opscode.com/browse/KNIFE-466) Knife ec2 should use gateway from net::ssh config if available
|
41
|
+
* [KNIFE-422](https://tickets.opscode.com/browse/KNIFE-422) Knife ec2 server create doesn't respect identity file of gateway server from ssh\_config
|
data/knife-ec2.gemspec
CHANGED
@@ -10,14 +10,14 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.homepage = 'https://github.com/opscode/knife-ec2'
|
11
11
|
s.summary = %q{EC2 Support for Chef's Knife Command}
|
12
12
|
s.description = s.summary
|
13
|
-
s.license = 'Apache
|
13
|
+
s.license = 'Apache-2.0'
|
14
14
|
|
15
15
|
s.files = `git ls-files`.split("\n")
|
16
16
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
17
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
18
|
|
19
|
-
s.add_dependency 'fog', '~> 1.
|
20
|
-
s.add_dependency 'knife-windows', '
|
19
|
+
s.add_dependency 'fog', '~> 1.23.0'
|
20
|
+
s.add_dependency 'knife-windows', '0.8.0.rc.0'
|
21
21
|
|
22
22
|
s.add_development_dependency 'mixlib-config', '~> 2.0'
|
23
23
|
s.add_development_dependency 'chef', '>= 0.10.10'
|
@@ -125,9 +125,14 @@ class Chef
|
|
125
125
|
option :ssh_gateway,
|
126
126
|
:short => "-w GATEWAY",
|
127
127
|
:long => "--ssh-gateway GATEWAY",
|
128
|
-
:description => "The ssh gateway server",
|
128
|
+
:description => "The ssh gateway server. Any proxies configured in your ssh config are automatically used by default.",
|
129
129
|
:proc => Proc.new { |key| Chef::Config[:knife][:ssh_gateway] = key }
|
130
130
|
|
131
|
+
option :ssh_gateway_identity,
|
132
|
+
:long => "--ssh-gateway-identity IDENTITY_FILE",
|
133
|
+
:description => "The private key for ssh gateway server",
|
134
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:ssh_gateway_identity] = key }
|
135
|
+
|
131
136
|
option :identity_file,
|
132
137
|
:short => "-i IDENTITY_FILE",
|
133
138
|
:long => "--identity-file IDENTITY_FILE",
|
@@ -258,6 +263,23 @@ class Chef
|
|
258
263
|
:boolean => true,
|
259
264
|
:default => false
|
260
265
|
|
266
|
+
option :ebs_volume_type,
|
267
|
+
:long => "--ebs-volume-type TYPE",
|
268
|
+
:description => "Standard or Provisioned (io1) IOPS or General Purpose (gp2)",
|
269
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:ebs_volume_type] = key },
|
270
|
+
:default => "standard"
|
271
|
+
|
272
|
+
option :ebs_provisioned_iops,
|
273
|
+
:long => "--provisioned-iops IOPS",
|
274
|
+
:description => "IOPS rate, only used when ebs volume type is 'io1'",
|
275
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:provisioned_iops] = key },
|
276
|
+
:default => nil
|
277
|
+
|
278
|
+
option :auth_timeout,
|
279
|
+
:long => "--windows-auth-timeout MINUTES",
|
280
|
+
:description => "The maximum time in minutes to wait to for authentication over the transport to the node to succeed. The default value is 25 minutes.",
|
281
|
+
:default => 25
|
282
|
+
|
261
283
|
def run
|
262
284
|
$stdout.sync = true
|
263
285
|
|
@@ -303,7 +325,7 @@ class Chef
|
|
303
325
|
msg_pair("Tags", printed_tags)
|
304
326
|
msg_pair("SSH Key", @server.key_name)
|
305
327
|
|
306
|
-
print "\n#{ui.color("Waiting for instance", :magenta)}"
|
328
|
+
print "\n#{ui.color("Waiting for EC2 to create the instance", :magenta)}"
|
307
329
|
|
308
330
|
# wait for instance to come up before acting against it
|
309
331
|
@server.wait_for { print "."; ready? }
|
@@ -346,13 +368,13 @@ class Chef
|
|
346
368
|
config[:distro] = "windows-chef-client-msi" if (config[:distro].nil? || config[:distro] == "chef-full")
|
347
369
|
if protocol == 'winrm'
|
348
370
|
load_winrm_deps
|
349
|
-
print "\n#{ui.color("Waiting for winrm", :magenta)}"
|
371
|
+
print "\n#{ui.color("Waiting for winrm access to become available", :magenta)}"
|
350
372
|
print(".") until tcp_test_winrm(ssh_connect_host, locate_config_value(:winrm_port)) {
|
351
373
|
sleep 10
|
352
374
|
puts("done")
|
353
375
|
}
|
354
376
|
else
|
355
|
-
print "\n#{ui.color("Waiting for sshd", :magenta)}"
|
377
|
+
print "\n#{ui.color("Waiting for sshd access to become available", :magenta)}"
|
356
378
|
#If FreeSSHd, winsshd etc are available
|
357
379
|
print(".") until tcp_test_ssh(ssh_connect_host, config[:ssh_port]) {
|
358
380
|
sleep @initial_sleep_delay ||= (vpc_mode? ? 40 : 10)
|
@@ -362,7 +384,7 @@ class Chef
|
|
362
384
|
end
|
363
385
|
bootstrap_for_windows_node(@server, ssh_connect_host).run
|
364
386
|
else
|
365
|
-
print "\n#{ui.color("Waiting for sshd", :magenta)}"
|
387
|
+
print "\n#{ui.color("Waiting for sshd access to become available", :magenta)}"
|
366
388
|
wait_for_sshd(ssh_connect_host)
|
367
389
|
ssh_override_winrm
|
368
390
|
bootstrap_for_linux_node(@server, ssh_connect_host).run
|
@@ -386,6 +408,8 @@ class Chef
|
|
386
408
|
msg_pair("Root Volume ID", device_map['volumeId'])
|
387
409
|
msg_pair("Root Device Name", device_map['deviceName'])
|
388
410
|
msg_pair("Root Device Delete on Terminate", device_map['deleteOnTermination'])
|
411
|
+
msg_pair("Standard or Provisioned IOPS", device_map['volumeType'])
|
412
|
+
msg_pair("IOPS rate", device_map['iops'])
|
389
413
|
|
390
414
|
if config[:ebs_size]
|
391
415
|
if ami.block_device_mapping.first['volumeSize'].to_i < config[:ebs_size].to_i
|
@@ -456,6 +480,7 @@ class Chef
|
|
456
480
|
bootstrap.config[:kerberos_service] = locate_config_value(:kerberos_service)
|
457
481
|
bootstrap.config[:ca_trust_file] = locate_config_value(:ca_trust_file)
|
458
482
|
bootstrap.config[:winrm_port] = locate_config_value(:winrm_port)
|
483
|
+
bootstrap.config[:auth_timeout] = locate_config_value(:auth_timeout)
|
459
484
|
elsif locate_config_value(:bootstrap_protocol) == 'ssh'
|
460
485
|
bootstrap = Chef::Knife::BootstrapWindowsSsh.new
|
461
486
|
bootstrap.config[:ssh_user] = locate_config_value(:ssh_user)
|
@@ -500,7 +525,7 @@ class Chef
|
|
500
525
|
super([:image, :aws_ssh_key_id, :aws_access_key_id, :aws_secret_access_key])
|
501
526
|
|
502
527
|
if ami.nil?
|
503
|
-
ui.error("You have not provided a valid image (AMI) value.
|
528
|
+
ui.error("You have not provided a valid image (AMI) value.")
|
504
529
|
exit 1
|
505
530
|
end
|
506
531
|
|
@@ -532,6 +557,22 @@ class Chef
|
|
532
557
|
exit 1
|
533
558
|
end
|
534
559
|
end
|
560
|
+
|
561
|
+
if config[:ebs_provisioned_iops] and config[:ebs_volume_type] != 'io1'
|
562
|
+
ui.error("--provisioned-iops option is only supported for volume type of 'io1'")
|
563
|
+
exit 1
|
564
|
+
end
|
565
|
+
|
566
|
+
if config[:ebs_volume_type] == 'io1' and config[:ebs_provisioned_iops].nil?
|
567
|
+
ui.error("--provisioned-iops option is required when using volume type of 'io1'")
|
568
|
+
exit 1
|
569
|
+
end
|
570
|
+
|
571
|
+
if config[:ebs_volume_type] and ! %w(gp2 io1 standard).include?(config[:ebs_volume_type])
|
572
|
+
ui.error("--ebs-volume-type must be 'standard' or 'io1' or 'gp2'")
|
573
|
+
msg opt_parser
|
574
|
+
exit 1
|
575
|
+
end
|
535
576
|
end
|
536
577
|
|
537
578
|
def tags
|
@@ -599,13 +640,26 @@ class Chef
|
|
599
640
|
else
|
600
641
|
ami_map["deleteOnTermination"]
|
601
642
|
end
|
643
|
+
iops_rate = begin
|
644
|
+
if config[:ebs_provisioned_iops]
|
645
|
+
Integer(config[:ebs_provisioned_iops]).to_s
|
646
|
+
else
|
647
|
+
ami_map["iops"].to_s
|
648
|
+
end
|
649
|
+
rescue ArgumentError
|
650
|
+
puts "--provisioned-iops must be an integer"
|
651
|
+
msg opt_parser
|
652
|
+
exit 1
|
653
|
+
end
|
602
654
|
|
603
655
|
server_def[:block_device_mapping] =
|
604
656
|
[{
|
605
657
|
'DeviceName' => ami_map["deviceName"],
|
606
658
|
'Ebs.VolumeSize' => ebs_size,
|
607
|
-
'Ebs.DeleteOnTermination' => delete_term
|
659
|
+
'Ebs.DeleteOnTermination' => delete_term,
|
660
|
+
'Ebs.VolumeType' => config[:ebs_volume_type],
|
608
661
|
}]
|
662
|
+
server_def[:block_device_mapping].first['Ebs.Iops'] = iops_rate unless iops_rate.empty?
|
609
663
|
end
|
610
664
|
|
611
665
|
(config[:ephemeral] || []).each_with_index do |device_name, i|
|
@@ -616,12 +670,44 @@ class Chef
|
|
616
670
|
end
|
617
671
|
|
618
672
|
def wait_for_sshd(hostname)
|
619
|
-
|
673
|
+
ssh_gateway = get_ssh_gateway_for(hostname)
|
674
|
+
ssh_gateway ? wait_for_tunnelled_sshd(ssh_gateway, hostname) : wait_for_direct_sshd(hostname, config[:ssh_port])
|
675
|
+
end
|
676
|
+
|
677
|
+
def get_ssh_gateway_for(hostname)
|
678
|
+
if config[:ssh_gateway]
|
679
|
+
# The ssh_gateway specified in the knife config (if any) takes
|
680
|
+
# precedence over anything in the SSH configuration
|
681
|
+
Chef::Log.debug("Using ssh gateway #{config[:ssh_gateway]} from knife config")
|
682
|
+
config[:ssh_gateway]
|
683
|
+
else
|
684
|
+
# Next, check if the SSH configuration has a ProxyCommand
|
685
|
+
# directive for this host. If there is one, parse out the
|
686
|
+
# host from the proxy command
|
687
|
+
ssh_proxy = Net::SSH::Config.for(hostname)[:proxy]
|
688
|
+
if ssh_proxy.respond_to?(:command_line_template)
|
689
|
+
# ssh gateway_hostname nc %h %p
|
690
|
+
proxy_pattern = /ssh\s+(\S+)\s+nc/
|
691
|
+
matchdata = proxy_pattern.match(ssh_proxy.command_line_template)
|
692
|
+
if matchdata.nil?
|
693
|
+
Chef::Log.debug("Unable to determine ssh gateway for '#{hostname}' from ssh config template: #{ssh_proxy.command_line_template}")
|
694
|
+
nil
|
695
|
+
else
|
696
|
+
# Return hostname extracted from command line template
|
697
|
+
Chef::Log.debug("Using ssh gateway #{matchdata[1]} from ssh config")
|
698
|
+
matchdata[1]
|
699
|
+
end
|
700
|
+
else
|
701
|
+
# Return nil if we cannot find an ssh_gateway
|
702
|
+
Chef::Log.debug("No ssh gateway found, making a direct connection")
|
703
|
+
nil
|
704
|
+
end
|
705
|
+
end
|
620
706
|
end
|
621
707
|
|
622
|
-
def wait_for_tunnelled_sshd(hostname)
|
708
|
+
def wait_for_tunnelled_sshd(ssh_gateway, hostname)
|
623
709
|
initial = true
|
624
|
-
print(".") until tunnel_test_ssh(hostname) {
|
710
|
+
print(".") until tunnel_test_ssh(ssh_gateway, hostname) {
|
625
711
|
if initial
|
626
712
|
initial = false
|
627
713
|
sleep (vpc_mode? ? 40 : 10)
|
@@ -632,11 +718,9 @@ class Chef
|
|
632
718
|
}
|
633
719
|
end
|
634
720
|
|
635
|
-
def tunnel_test_ssh(hostname, &block)
|
636
|
-
gw_host, gw_user = config[:ssh_gateway].split('@').reverse
|
637
|
-
gw_host, gw_port = gw_host.split(':')
|
638
|
-
gateway = Net::SSH::Gateway.new(gw_host, gw_user, :port => gw_port || 22)
|
721
|
+
def tunnel_test_ssh(ssh_gateway, hostname, &block)
|
639
722
|
status = false
|
723
|
+
gateway = configure_ssh_gateway(ssh_gateway)
|
640
724
|
gateway.open(hostname, config[:ssh_port]) do |local_tunnel_port|
|
641
725
|
status = tcp_test_ssh('localhost', local_tunnel_port, &block)
|
642
726
|
end
|
@@ -648,6 +732,33 @@ class Chef
|
|
648
732
|
false
|
649
733
|
end
|
650
734
|
|
735
|
+
def configure_ssh_gateway(ssh_gateway)
|
736
|
+
gw_host, gw_user = ssh_gateway.split('@').reverse
|
737
|
+
gw_host, gw_port = gw_host.split(':')
|
738
|
+
gateway_options = { :port => gw_port || 22 }
|
739
|
+
|
740
|
+
# Load the SSH config for the SSH gateway host.
|
741
|
+
# Set the gateway user if it was not part of the
|
742
|
+
# SSH gateway string, and use any configured
|
743
|
+
# SSH keys.
|
744
|
+
ssh_gateway_config = Net::SSH::Config.for(gw_host)
|
745
|
+
gw_user ||= ssh_gateway_config[:user]
|
746
|
+
|
747
|
+
# Always use the gateway keys from the SSH Config
|
748
|
+
gateway_keys = ssh_gateway_config[:keys]
|
749
|
+
|
750
|
+
# Use the keys specificed on the command line if available (overrides SSH Config)
|
751
|
+
if config[:ssh_gateway_identity]
|
752
|
+
gateway_keys = Array(locate_config_value(:ssh_gateway_identity))
|
753
|
+
end
|
754
|
+
|
755
|
+
unless gateway_keys.nil?
|
756
|
+
gateway_options[:keys] = gateway_keys
|
757
|
+
end
|
758
|
+
|
759
|
+
Net::SSH::Gateway.new(gw_host, gw_user, gateway_options)
|
760
|
+
end
|
761
|
+
|
651
762
|
def wait_for_direct_sshd(hostname, ssh_port)
|
652
763
|
initial = true
|
653
764
|
print(".") until tcp_test_ssh(hostname, ssh_port) {
|
data/lib/knife-ec2/version.rb
CHANGED
@@ -17,6 +17,9 @@
|
|
17
17
|
#
|
18
18
|
|
19
19
|
require File.expand_path('../../spec_helper', __FILE__)
|
20
|
+
require 'net/ssh/proxy/http'
|
21
|
+
require 'net/ssh/proxy/command'
|
22
|
+
require 'net/ssh/gateway'
|
20
23
|
require 'fog'
|
21
24
|
require 'chef/knife/bootstrap'
|
22
25
|
require 'chef/knife/bootstrap_windows_winrm'
|
@@ -399,12 +402,12 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
399
402
|
end
|
400
403
|
|
401
404
|
it "configures the bootstrap to use prerelease versions of chef if specified" do
|
402
|
-
@bootstrap.config[:prerelease].should
|
405
|
+
@bootstrap.config[:prerelease].should be_falsey
|
403
406
|
|
404
407
|
@knife_ec2_create.config[:prerelease] = true
|
405
408
|
|
406
409
|
bootstrap = @knife_ec2_create.bootstrap_for_linux_node(@new_ec2_server, @new_ec2_server.dns_name)
|
407
|
-
bootstrap.config[:prerelease].should
|
410
|
+
bootstrap.config[:prerelease].should == true
|
408
411
|
end
|
409
412
|
|
410
413
|
it "configures the bootstrap to use the desired distro-specific bootstrap script" do
|
@@ -412,7 +415,7 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
412
415
|
end
|
413
416
|
|
414
417
|
it "configures the bootstrap to use sudo" do
|
415
|
-
@bootstrap.config[:use_sudo].should
|
418
|
+
@bootstrap.config[:use_sudo].should == true
|
416
419
|
end
|
417
420
|
|
418
421
|
it "configured the bootstrap to use the desired template" do
|
@@ -486,12 +489,23 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
486
489
|
it "configures sets the bootstrap's run_list" do
|
487
490
|
@bootstrap.config[:run_list].should == ['role[base]']
|
488
491
|
end
|
492
|
+
|
493
|
+
it "configures auth_timeout for bootstrap to default to 25 minutes" do
|
494
|
+
expect(@knife_ec2_create.options[:auth_timeout][:default]).to eq(25)
|
495
|
+
end
|
496
|
+
|
497
|
+
it "configures auth_timeout for bootstrap according to plugin auth_timeout config" do
|
498
|
+
@knife_ec2_create.config[:auth_timeout] = 5
|
499
|
+
bootstrap = @knife_ec2_create.bootstrap_for_windows_node(@new_ec2_server, @new_ec2_server.dns_name)
|
500
|
+
expect(bootstrap.config[:auth_timeout]).to eq(5)
|
501
|
+
end
|
489
502
|
end
|
490
503
|
|
491
504
|
describe "when validating the command-line parameters" do
|
492
505
|
before do
|
493
506
|
Fog::Compute::AWS.stub(:new).and_return(@ec2_connection)
|
494
507
|
@knife_ec2_create.ui.stub(:error)
|
508
|
+
@knife_ec2_create.ui.stub(:msg)
|
495
509
|
end
|
496
510
|
|
497
511
|
describe "when reading aws_credential_file" do
|
@@ -548,6 +562,34 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
548
562
|
|
549
563
|
lambda { @knife_ec2_create.validate! }.should raise_error SystemExit
|
550
564
|
end
|
565
|
+
|
566
|
+
it "disallows ebs provisioned iops option when not using ebs volume type" do
|
567
|
+
@knife_ec2_create.config[:ebs_provisioned_iops] = "123"
|
568
|
+
@knife_ec2_create.config[:ebs_volume_type] = nil
|
569
|
+
|
570
|
+
lambda { @knife_ec2_create.validate! }.should raise_error SystemExit
|
571
|
+
end
|
572
|
+
|
573
|
+
it "disallows ebs provisioned iops option when not using ebs volume type 'io1'" do
|
574
|
+
@knife_ec2_create.config[:ebs_provisioned_iops] = "123"
|
575
|
+
@knife_ec2_create.config[:ebs_volume_type] = "standard"
|
576
|
+
|
577
|
+
lambda { @knife_ec2_create.validate! }.should raise_error SystemExit
|
578
|
+
end
|
579
|
+
|
580
|
+
it "disallows ebs volume type if its other than 'io1' or 'gp2' or 'standard'" do
|
581
|
+
@knife_ec2_create.config[:ebs_provisioned_iops] = "123"
|
582
|
+
@knife_ec2_create.config[:ebs_volume_type] = 'invalid'
|
583
|
+
|
584
|
+
lambda { @knife_ec2_create.validate! }.should raise_error SystemExit
|
585
|
+
end
|
586
|
+
|
587
|
+
it "disallows 'io1' ebs volume type when not using ebs provisioned iops" do
|
588
|
+
@knife_ec2_create.config[:ebs_provisioned_iops] = nil
|
589
|
+
@knife_ec2_create.config[:ebs_volume_type] = 'io1'
|
590
|
+
|
591
|
+
lambda { @knife_ec2_create.validate! }.should raise_error SystemExit
|
592
|
+
end
|
551
593
|
end
|
552
594
|
|
553
595
|
describe "when creating the server definition" do
|
@@ -662,6 +704,108 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
662
704
|
server_def[:subnet_id].should == 'subnet-1a2b3c4d'
|
663
705
|
server_def[:associate_public_ip].should == true
|
664
706
|
end
|
707
|
+
|
708
|
+
context "when using ebs volume type and ebs provisioned iops rate options" do
|
709
|
+
before do
|
710
|
+
@knife_ec2_create.stub_chain(:ami, :root_device_type).and_return("ebs")
|
711
|
+
@knife_ec2_create.stub_chain(:ami, :block_device_mapping).and_return([{"iops" => 123}])
|
712
|
+
@knife_ec2_create.stub(:msg)
|
713
|
+
@knife_ec2_create.stub(:puts)
|
714
|
+
end
|
715
|
+
|
716
|
+
it "sets the specified 'standard' ebs volume type" do
|
717
|
+
@knife_ec2_create.config[:ebs_volume_type] = 'standard'
|
718
|
+
server_def = @knife_ec2_create.create_server_def
|
719
|
+
|
720
|
+
server_def[:block_device_mapping].first['Ebs.VolumeType'].should == 'standard'
|
721
|
+
end
|
722
|
+
|
723
|
+
it "sets the specified 'io1' ebs volume type" do
|
724
|
+
@knife_ec2_create.config[:ebs_volume_type] = 'io1'
|
725
|
+
server_def = @knife_ec2_create.create_server_def
|
726
|
+
|
727
|
+
server_def[:block_device_mapping].first['Ebs.VolumeType'].should == 'io1'
|
728
|
+
end
|
729
|
+
|
730
|
+
it "sets the specified 'gp2' ebs volume type" do
|
731
|
+
@knife_ec2_create.config[:ebs_volume_type] = 'gp2'
|
732
|
+
server_def = @knife_ec2_create.create_server_def
|
733
|
+
|
734
|
+
server_def[:block_device_mapping].first['Ebs.VolumeType'].should == 'gp2'
|
735
|
+
end
|
736
|
+
|
737
|
+
it "sets the specified ebs provisioned iops rate" do
|
738
|
+
@knife_ec2_create.config[:ebs_provisioned_iops] = '1234'
|
739
|
+
@knife_ec2_create.config[:ebs_volume_type] = 'io1'
|
740
|
+
server_def = @knife_ec2_create.create_server_def
|
741
|
+
|
742
|
+
server_def[:block_device_mapping].first['Ebs.Iops'].should == '1234'
|
743
|
+
end
|
744
|
+
|
745
|
+
it "disallows non integer ebs provisioned iops rate" do
|
746
|
+
@knife_ec2_create.config[:ebs_provisioned_iops] = "123abcd"
|
747
|
+
|
748
|
+
lambda { @knife_ec2_create.create_server_def }.should raise_error SystemExit
|
749
|
+
end
|
750
|
+
|
751
|
+
it "sets the iops rate from ami" do
|
752
|
+
@knife_ec2_create.config[:ebs_volume_type] = 'io1'
|
753
|
+
server_def = @knife_ec2_create.create_server_def
|
754
|
+
|
755
|
+
server_def[:block_device_mapping].first['Ebs.Iops'].should == '123'
|
756
|
+
end
|
757
|
+
end
|
758
|
+
end
|
759
|
+
|
760
|
+
describe "wait_for_sshd" do
|
761
|
+
let(:gateway) { 'test.gateway.com' }
|
762
|
+
let(:hostname) { 'test.host.com' }
|
763
|
+
|
764
|
+
it "should wait for tunnelled ssh if a ssh gateway is provided" do
|
765
|
+
@knife_ec2_create.stub(:get_ssh_gateway_for).and_return(gateway)
|
766
|
+
@knife_ec2_create.should_receive(:wait_for_tunnelled_sshd).with(gateway, hostname)
|
767
|
+
@knife_ec2_create.wait_for_sshd(hostname)
|
768
|
+
end
|
769
|
+
|
770
|
+
it "should wait for direct ssh if a ssh gateway is not provided" do
|
771
|
+
@knife_ec2_create.stub(:get_ssh_gateway_for).and_return(nil)
|
772
|
+
@knife_ec2_create.config[:ssh_port] = 22
|
773
|
+
@knife_ec2_create.should_receive(:wait_for_direct_sshd).with(hostname, 22)
|
774
|
+
@knife_ec2_create.wait_for_sshd(hostname)
|
775
|
+
end
|
776
|
+
end
|
777
|
+
|
778
|
+
describe "get_ssh_gateway_for" do
|
779
|
+
let(:gateway) { 'test.gateway.com' }
|
780
|
+
let(:hostname) { 'test.host.com' }
|
781
|
+
|
782
|
+
it "should give precedence to the ssh gateway specified in the knife configuration" do
|
783
|
+
Net::SSH::Config.stub(:for).and_return(:proxy => Net::SSH::Proxy::Command.new("ssh some.other.gateway.com nc %h %p"))
|
784
|
+
@knife_ec2_create.config[:ssh_gateway] = gateway
|
785
|
+
@knife_ec2_create.get_ssh_gateway_for(hostname).should == gateway
|
786
|
+
end
|
787
|
+
|
788
|
+
it "should return the ssh gateway specified in the ssh configuration even if the config option is not set" do
|
789
|
+
# This should already be false, but test this explicitly for regression
|
790
|
+
@knife_ec2_create.config[:ssh_gateway] = false
|
791
|
+
Net::SSH::Config.stub(:for).and_return(:proxy => Net::SSH::Proxy::Command.new("ssh #{gateway} nc %h %p"))
|
792
|
+
@knife_ec2_create.get_ssh_gateway_for(hostname).should == gateway
|
793
|
+
end
|
794
|
+
|
795
|
+
it "should return nil if the ssh gateway cannot be parsed from the ssh proxy command" do
|
796
|
+
Net::SSH::Config.stub(:for).and_return(:proxy => Net::SSH::Proxy::Command.new("cannot parse host"))
|
797
|
+
@knife_ec2_create.get_ssh_gateway_for(hostname).should be_nil
|
798
|
+
end
|
799
|
+
|
800
|
+
it "should return nil if the ssh proxy is not a proxy command" do
|
801
|
+
Net::SSH::Config.stub(:for).and_return(:proxy => Net::SSH::Proxy::HTTP.new("httphost.com"))
|
802
|
+
@knife_ec2_create.get_ssh_gateway_for(hostname).should be_nil
|
803
|
+
end
|
804
|
+
|
805
|
+
it "returns nil if the ssh config has no proxy" do
|
806
|
+
Net::SSH::Config.stub(:for).and_return(:user => "darius")
|
807
|
+
@knife_ec2_create.get_ssh_gateway_for(hostname).should be_nil
|
808
|
+
end
|
665
809
|
end
|
666
810
|
|
667
811
|
describe "ssh_connect_host" do
|
@@ -695,6 +839,73 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
695
839
|
end
|
696
840
|
end
|
697
841
|
|
842
|
+
describe "tunnel_test_ssh" do
|
843
|
+
let(:gateway_host) { 'test.gateway.com' }
|
844
|
+
let(:gateway) { double('gateway') }
|
845
|
+
let(:hostname) { 'test.host.com' }
|
846
|
+
let(:local_port) { 23 }
|
847
|
+
|
848
|
+
before(:each) do
|
849
|
+
@knife_ec2_create.stub(:configure_ssh_gateway).and_return(gateway)
|
850
|
+
end
|
851
|
+
|
852
|
+
it "should test ssh through a gateway" do
|
853
|
+
@knife_ec2_create.config[:ssh_port] = 22
|
854
|
+
gateway.should_receive(:open).with(hostname, 22).and_yield(local_port)
|
855
|
+
@knife_ec2_create.should_receive(:tcp_test_ssh).with('localhost', local_port).and_return(true)
|
856
|
+
@knife_ec2_create.tunnel_test_ssh(gateway_host, hostname).should == true
|
857
|
+
end
|
858
|
+
end
|
859
|
+
|
860
|
+
describe "configure_ssh_gateway" do
|
861
|
+
let(:gateway_host) { 'test.gateway.com' }
|
862
|
+
let(:gateway_user) { 'gateway_user' }
|
863
|
+
|
864
|
+
it "configures a ssh gateway with no user and the default port when the SSH Config is empty" do
|
865
|
+
Net::SSH::Config.stub(:for).and_return({})
|
866
|
+
Net::SSH::Gateway.should_receive(:new).with(gateway_host, nil, :port => 22)
|
867
|
+
@knife_ec2_create.configure_ssh_gateway(gateway_host)
|
868
|
+
end
|
869
|
+
|
870
|
+
it "configures a ssh gateway with the user specified in the SSH Config" do
|
871
|
+
Net::SSH::Config.stub(:for).and_return({ :user => gateway_user })
|
872
|
+
Net::SSH::Gateway.should_receive(:new).with(gateway_host, gateway_user, :port => 22)
|
873
|
+
@knife_ec2_create.configure_ssh_gateway(gateway_host)
|
874
|
+
end
|
875
|
+
|
876
|
+
it "configures a ssh gateway with the user specified in the ssh gateway string" do
|
877
|
+
Net::SSH::Config.stub(:for).and_return({ :user => gateway_user })
|
878
|
+
Net::SSH::Gateway.should_receive(:new).with(gateway_host, 'override_user', :port => 22)
|
879
|
+
@knife_ec2_create.configure_ssh_gateway("override_user@#{gateway_host}")
|
880
|
+
end
|
881
|
+
|
882
|
+
it "configures a ssh gateway with the port specified in the ssh gateway string" do
|
883
|
+
Net::SSH::Config.stub(:for).and_return({})
|
884
|
+
Net::SSH::Gateway.should_receive(:new).with(gateway_host, nil, :port => '24')
|
885
|
+
@knife_ec2_create.configure_ssh_gateway("#{gateway_host}:24")
|
886
|
+
end
|
887
|
+
|
888
|
+
it "configures a ssh gateway with the keys specified in the SSH Config" do
|
889
|
+
Net::SSH::Config.stub(:for).and_return({ :keys => ['configuredkey'] })
|
890
|
+
Net::SSH::Gateway.should_receive(:new).with(gateway_host, nil, :port => 22, :keys => ['configuredkey'])
|
891
|
+
@knife_ec2_create.configure_ssh_gateway(gateway_host)
|
892
|
+
end
|
893
|
+
|
894
|
+
it "configures the ssh gateway with the key specified on the knife config / command line" do
|
895
|
+
@knife_ec2_create.config[:ssh_gateway_identity] = "/home/fireman/.ssh/gateway.pem"
|
896
|
+
#Net::SSH::Config.stub(:for).and_return({ :keys => ['configuredkey'] })
|
897
|
+
Net::SSH::Gateway.should_receive(:new).with(gateway_host, nil, :port => 22, :keys => ['/home/fireman/.ssh/gateway.pem'])
|
898
|
+
@knife_ec2_create.configure_ssh_gateway(gateway_host)
|
899
|
+
end
|
900
|
+
|
901
|
+
it "prefers the knife config over the ssh config for the gateway keys" do
|
902
|
+
@knife_ec2_create.config[:ssh_gateway_identity] = "/home/fireman/.ssh/gateway.pem"
|
903
|
+
Net::SSH::Config.stub(:for).and_return({ :keys => ['not_this_key_dude'] })
|
904
|
+
Net::SSH::Gateway.should_receive(:new).with(gateway_host, nil, :port => 22, :keys => ['/home/fireman/.ssh/gateway.pem'])
|
905
|
+
@knife_ec2_create.configure_ssh_gateway(gateway_host)
|
906
|
+
end
|
907
|
+
end
|
908
|
+
|
698
909
|
describe "tcp_test_ssh" do
|
699
910
|
# Normally we would only get the header after we send a client header, e.g. 'SSH-2.0-client'
|
700
911
|
it "should return true if we get an ssh header" do
|
@@ -709,14 +920,14 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
709
920
|
@knife_ec2_create = Chef::Knife::Ec2ServerCreate.new
|
710
921
|
TCPSocket.stub(:new).and_return(StringIO.new(""))
|
711
922
|
IO.stub(:select).and_return(true)
|
712
|
-
@knife_ec2_create.tcp_test_ssh("blackhole.ninja", 22).should
|
923
|
+
@knife_ec2_create.tcp_test_ssh("blackhole.ninja", 22).should be_falsey
|
713
924
|
end
|
714
925
|
|
715
926
|
it "should return false if the socket isn't ready" do
|
716
927
|
@knife_ec2_create = Chef::Knife::Ec2ServerCreate.new
|
717
928
|
TCPSocket.stub(:new)
|
718
929
|
IO.stub(:select).and_return(false)
|
719
|
-
@knife_ec2_create.tcp_test_ssh("blackhole.ninja", 22).should
|
930
|
+
@knife_ec2_create.tcp_test_ssh("blackhole.ninja", 22).should be_falsey
|
720
931
|
end
|
721
932
|
end
|
722
933
|
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.10.0.rc.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Jacob
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-09-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: fog
|
@@ -17,28 +17,28 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - ~>
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: 1.
|
20
|
+
version: 1.23.0
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - ~>
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: 1.
|
27
|
+
version: 1.23.0
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: knife-windows
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
|
-
- -
|
32
|
+
- - '='
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: 0.
|
34
|
+
version: 0.8.0.rc.0
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
|
-
- -
|
39
|
+
- - '='
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version: 0.
|
41
|
+
version: 0.8.0.rc.0
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: mixlib-config
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -121,10 +121,12 @@ files:
|
|
121
121
|
- .travis.yml
|
122
122
|
- CHANGELOG.md
|
123
123
|
- CONTRIBUTING.md
|
124
|
+
- CONTRIBUTIONS.md
|
124
125
|
- DOC_CHANGES.md
|
125
126
|
- Gemfile
|
126
127
|
- LICENSE
|
127
128
|
- README.md
|
129
|
+
- RELEASE_NOTES.md
|
128
130
|
- Rakefile
|
129
131
|
- knife-ec2.gemspec
|
130
132
|
- lib/chef/knife/ec2_base.rb
|
@@ -139,7 +141,7 @@ files:
|
|
139
141
|
- spec/unit/ec2_server_delete_spec.rb
|
140
142
|
homepage: https://github.com/opscode/knife-ec2
|
141
143
|
licenses:
|
142
|
-
- Apache
|
144
|
+
- Apache-2.0
|
143
145
|
metadata: {}
|
144
146
|
post_install_message:
|
145
147
|
rdoc_options: []
|
@@ -152,9 +154,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
152
154
|
version: '0'
|
153
155
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
154
156
|
requirements:
|
155
|
-
- - ! '
|
157
|
+
- - ! '>'
|
156
158
|
- !ruby/object:Gem::Version
|
157
|
-
version:
|
159
|
+
version: 1.3.1
|
158
160
|
requirements: []
|
159
161
|
rubyforge_project:
|
160
162
|
rubygems_version: 2.1.11
|