knife-ec2 0.8.0 → 0.10.0.rc.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.
- 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
|