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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YTdhZGU4M2U0NDY2Mzc2NjdlMzkxNGI2ZTkxMDcyMDZjODI4Mzk1Ng==
4
+ YzVmMmJhMWJhZWZhNjMzNDUzOWMyOGYzNDQzNjlkNWMyMDkxNjg1Mw==
5
5
  data.tar.gz: !binary |-
6
- NzMzNmEyMDUwM2VkNTZkOGQ0MmYxZDBjZWIyODRkMzI4MzVlZmRkOA==
6
+ OGU2MTdkOThjYjkzNjQ4MjJmMmZhNjk1YjM5MjE5ZGQzYjIxMWM4Yg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- OTlmZjliMzM5MjRlYzc4NGQ4ZDU4YTM4ZDVkNzIwN2VkMjJhNzY1NDdiMjk0
10
- MTJlYjU4ODdiOWJmODBlODdiNzVjYTc0YTY5MWQ3YzQzYzExOWE5MTMzY2Ew
11
- MDc0ZDg2NmZiNDIxMGU3ZWQxMjg2NWRhOGU3MDAwOWQ5OTFiYjE=
9
+ YTM2YWE1OTM2MDc5OTI4MjlhMmEzNzAxMGQxN2FlYWI3YzFjNjFmZjg0NGQy
10
+ MTc3ZWU3YTJjNTM0Mjc3ZTU4NWI5ZTkxZmM3MTI2ODAwOTZjMjk2NmVlNGY5
11
+ ZjkzNTMzYjJiNDQ1OTU2ZGFmYzQ0MzQ0ZDYyYjA4MjdhZmU1MTk=
12
12
  data.tar.gz: !binary |-
13
- OGMwNGVlMjgwNjY5ZTAwZTk3MGZlZDU4MWExNzUzNTVjYmU5MjY5MTkxMGVi
14
- NDYwNjAyYmMwMTA3NWEzNTQ3MzU5YTBmMGU1ZTg2ZWYwZWRlZmQ4ZTE2YWZj
15
- MGZhMmJjZDk5MzRkNzIyNzk2ZTQyNmQxZGFkOWE3NGU3MGZhNjM=
13
+ Njg1YTU2ZDhhYjc1NzZlOTNlZTkwZTIzYzIyZWIzMzQwZGEzYjM1YzBjN2Ew
14
+ OGIzMTgwY2UyYjNmODQ3ODk1ZjVjOTEyNmUxMGVjODUyYjI2ODhjYTNkNGFj
15
+ ODEzMmJjYmNjMTQ0NTYyOTMwNzllYzQzYzBkNzZhOGQ4MDEzOTk=
@@ -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 release. To view change history
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
- ## Last release: 0.8.0 (2014-03-10)
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
@@ -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)
@@ -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
- ## Command-line flag option --associate-ip for server create
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
- ### server create
9
+ ## Provisioned IOPS support for `server create` command
12
10
 
13
- ### options
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
 
@@ -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
@@ -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 2.0'
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.0'
20
- s.add_dependency 'knife-windows', '>= 0.5.12'
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. Please note the short option for this value recently changed from '-i' to '-I'.")
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
- config[:ssh_gateway] ? wait_for_tunnelled_sshd(hostname) : wait_for_direct_sshd(hostname, config[:ssh_port])
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) {
@@ -1,6 +1,6 @@
1
1
  module Knife
2
2
  module Ec2
3
- VERSION = "0.8.0"
3
+ VERSION = "0.10.0.rc.0"
4
4
  MAJOR, MINOR, TINY = VERSION.split('.')
5
5
  end
6
6
  end
@@ -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 be_false
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 be_true
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 be_true
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 be_false
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 be_false
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.8.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-03-10 00:00:00.000000000 Z
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.0
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.20.0
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.5.12
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.5.12
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 2.0
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: '0'
159
+ version: 1.3.1
158
160
  requirements: []
159
161
  rubyforge_project:
160
162
  rubygems_version: 2.1.11