knife-ec2 0.6.6 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/CHANGELOG.md +27 -0
- data/CONTRIBUTING.md +71 -0
- data/DOC_CHANGES.md +21 -0
- data/README.md +14 -7
- data/knife-ec2.gemspec +7 -6
- data/lib/chef/knife/ec2_base.rb +1 -1
- data/lib/chef/knife/ec2_server_create.rb +192 -139
- data/lib/knife-ec2/version.rb +1 -1
- data/spec/spec_helper.rb +10 -0
- data/spec/unit/ec2_server_create_spec.rb +91 -2
- metadata +33 -30
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
YTdhZGU4M2U0NDY2Mzc2NjdlMzkxNGI2ZTkxMDcyMDZjODI4Mzk1Ng==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
NzMzNmEyMDUwM2VkNTZkOGQ0MmYxZDBjZWIyODRkMzI4MzVlZmRkOA==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
OTlmZjliMzM5MjRlYzc4NGQ4ZDU4YTM4ZDVkNzIwN2VkMjJhNzY1NDdiMjk0
|
10
|
+
MTJlYjU4ODdiOWJmODBlODdiNzVjYTc0YTY5MWQ3YzQzYzExOWE5MTMzY2Ew
|
11
|
+
MDc0ZDg2NmZiNDIxMGU3ZWQxMjg2NWRhOGU3MDAwOWQ5OTFiYjE=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
OGMwNGVlMjgwNjY5ZTAwZTk3MGZlZDU4MWExNzUzNTVjYmU5MjY5MTkxMGVi
|
14
|
+
NDYwNjAyYmMwMTA3NWEzNTQ3MzU5YTBmMGU1ZTg2ZWYwZWRlZmQ4ZTE2YWZj
|
15
|
+
MGZhMmJjZDk5MzRkNzIyNzk2ZTQyNmQxZGFkOWE3NGU3MGZhNjM=
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# knife-ec2 change log
|
2
|
+
|
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
|
5
|
+
prior to release 0.8.0, please visit the [source repository](https://github.com/opscode/knife-ec2/commits).
|
6
|
+
|
7
|
+
## Unreleased changes
|
8
|
+
|
9
|
+
None.
|
10
|
+
|
11
|
+
## Last release: 0.8.0 (2014-03-10)
|
12
|
+
|
13
|
+
* [KNIFE-458](https://tickets.opscode.com/browse/KNIFE-458) Docs: Increase detail about necessary
|
14
|
+
options for VPC instance creation
|
15
|
+
* [KNIFE-456](https://tickets.opscode.com/browse/KNIFE-456) Documentation for :aws\_credential\_file difficult to read
|
16
|
+
* [KNIFE-455](https://tickets.opscode.com/browse/KNIFE-455) knife ec2 may try to use private ip for vpc bootstrap even with --associate-public-ip flag
|
17
|
+
* [KNIFE-453](https://tickets.opscode.com/browse/KNIFE-453) knife-ec2 doesn't handle aws credentials files with windows line endings
|
18
|
+
* [KNIFE-451](https://tickets.opscode.com/browse/KNIFE-451) Update Fog version to 1.20.0
|
19
|
+
* [KNIFE-430](https://tickets.opscode.com/browse/KNIFE-430) server creation tunnelling should wait for a valid banner before continuing
|
20
|
+
* [KNIFE-381](https://tickets.opscode.com/browse/KNIFE-381) Gabriel Rosendorf Add ability to associate public ip with VPC
|
21
|
+
instance on creation
|
22
|
+
|
23
|
+
## Releases prior to 0.8.0
|
24
|
+
Please see <https://github.com/opscode/knife-ec2/commits> to view changes in
|
25
|
+
the form of commits to the source repository for releases before 0.8.0.
|
26
|
+
|
27
|
+
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# Contributing to knife-ec2
|
2
|
+
|
3
|
+
We are glad you want to contribute to Chef's knife-ec2 plugin! The first step is the desire to improve the project.
|
4
|
+
|
5
|
+
You can find the answers to additional frequently asked questions [on the wiki](http://wiki.opscode.com/display/chef/How+to+Contribute).
|
6
|
+
|
7
|
+
## Quick-contribute
|
8
|
+
|
9
|
+
* Create an account on our [bug tracker](http://tickets.opscode.com/browse/KNIFE)
|
10
|
+
* Sign our contributor agreement (CLA) [
|
11
|
+
online](https://secure.echosign.com/public/hostedForm?formid=PJIF5694K6L)
|
12
|
+
(keep reading if you're contributing on behalf of your employer)
|
13
|
+
* Create a ticket for your change on the [bug tracker](http://tickets.opscode.com/browse/KNIFE)
|
14
|
+
* Link to your patch as a rebased git branch or pull request from the ticket
|
15
|
+
* Resolve the ticket as fixed
|
16
|
+
|
17
|
+
We regularly review contributions and will get back to you if we have any suggestions or concerns.
|
18
|
+
|
19
|
+
## The Apache License and the CLA/CCLA
|
20
|
+
|
21
|
+
Licensing is very important to open source projects, it helps ensure the software continues to be available under the terms that the author desired.
|
22
|
+
Chef uses the Apache 2.0 license to strike a balance between open contribution and allowing you to use the software however you would like to.
|
23
|
+
|
24
|
+
The license tells you what rights you have that are provided by the copyright holder. It is important that the contributor fully understands what rights
|
25
|
+
they are licensing and agrees to them. Sometimes the copyright holder isn't the contributor, most often when the contributor is doing work for a company.
|
26
|
+
|
27
|
+
To make a good faith effort to ensure these criteria are met, Opscode requires a Contributor License Agreement (CLA) or a Corporate Contributor License
|
28
|
+
Agreement (CCLA) for all contributions. This is without exception due to some matters not being related to copyright and to avoid having to continually
|
29
|
+
check with our lawyers about small patches.
|
30
|
+
|
31
|
+
It only takes a few minutes to complete a CLA, and you retain the copyright to your contribution.
|
32
|
+
|
33
|
+
You can complete our contributor agreement (CLA) [
|
34
|
+
online](https://secure.echosign.com/public/hostedForm?formid=PJIF5694K6L). If you're contributing on behalf of your employer, have
|
35
|
+
your employer fill out our [Corporate CLA](https://secure.echosign.com/public/hostedForm?formid=PIE6C7AX856) instead.
|
36
|
+
|
37
|
+
## Issue Tracking
|
38
|
+
|
39
|
+
You can file tickets to describe the bug you'd like to fix or feature you'd
|
40
|
+
like to add via the [knife-ec2 project](http://tickets.opscode.com/browse/KNIFE). For your contribution to be reviewed
|
41
|
+
and merged, you **must** file a ticket.
|
42
|
+
|
43
|
+
## Contribution Details
|
44
|
+
|
45
|
+
Once you've created the ticket, you can make a pull request to
|
46
|
+
knife-ec2 on GitHub at <https://github.com/opscode/knife-ec2> that references
|
47
|
+
that ticket.
|
48
|
+
|
49
|
+
## Testing Instructions
|
50
|
+
|
51
|
+
To run tests, run the following Ruby tool commands from the root of your local checkout of
|
52
|
+
knife-ec2:
|
53
|
+
|
54
|
+
bundle install
|
55
|
+
bundle exec rspec spec
|
56
|
+
|
57
|
+
**All tests must pass** before your contribution can be merged. Thus it's a good idea
|
58
|
+
to execute the tests without your change to be sure you understand how to run
|
59
|
+
them, as well as after to validate that you've avoided regressions.
|
60
|
+
|
61
|
+
All but the most trivial changes should include **at least one unit test case** to exercise the
|
62
|
+
new / changed code; please add tests to your pull request in this common case.
|
63
|
+
|
64
|
+
## Further Resources
|
65
|
+
|
66
|
+
### Fog
|
67
|
+
|
68
|
+
Knife-ec2 uses the Fog gem to interact with EC2's API. When there's a new
|
69
|
+
feature of EC2 that you'd like to utilize in knife-ec2 use cases, that feature
|
70
|
+
will probably be exposed by Fog. You can read about Fog
|
71
|
+
at its [project page](https://github.com/fog/fog).
|
data/DOC_CHANGES.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
<!---
|
2
|
+
This file is reset everytime when a new release is done. Contents of this file is for the currently unreleased version.
|
3
|
+
-->
|
4
|
+
|
5
|
+
# knife-ec2 doc changes
|
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.
|
10
|
+
|
11
|
+
### server create
|
12
|
+
|
13
|
+
### options
|
14
|
+
|
15
|
+
```
|
16
|
+
--associate-public-ip
|
17
|
+
```
|
18
|
+
|
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
|
+
|
data/README.md
CHANGED
@@ -4,8 +4,13 @@ Knife EC2
|
|
4
4
|
[![Build Status](https://travis-ci.org/opscode/knife-ec2.png?branch=master)](https://travis-ci.org/opscode/knife-ec2)
|
5
5
|
[![Dependency Status](https://gemnasium.com/opscode/knife-ec2.png)](https://gemnasium.com/opscode/knife-ec2)
|
6
6
|
|
7
|
-
This is the official
|
7
|
+
This is the official Chef Knife plugin for EC2. This plugin gives knife the ability to create, bootstrap, and manage EC2 instances.
|
8
8
|
|
9
|
+
* Documentation: <http://docs.opscode.com/plugin_knife_ec2.html>
|
10
|
+
* Source: <http://github.com/opscode/knife-ec2/tree/master>
|
11
|
+
* Tickets/Issues: <http://tickets.opscode.com/browse/KNIFE>
|
12
|
+
* IRC: `#chef` and `#chef-hacking` on Freenode
|
13
|
+
* Mailing list: <http://lists.opscode.com>
|
9
14
|
|
10
15
|
Installation
|
11
16
|
------------
|
@@ -56,10 +61,12 @@ you already have a file with these keys somewhere in this format:
|
|
56
61
|
AWSAccessKeyId=Your AWS Access Key ID
|
57
62
|
AWSSecretKey=Your AWS Secret Access Key
|
58
63
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
64
|
+
In this case, you can point the <tt>aws_credential_file</tt> option to
|
65
|
+
this file in your <tt>knife.rb</tt> file, like so:
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
knife[:aws_credential_file] = "/path/to/credentials/file/in/above/format"
|
69
|
+
```
|
63
70
|
|
64
71
|
Additionally the following options may be set in your `knife.rb`:
|
65
72
|
|
@@ -106,10 +113,10 @@ In-depth usage instructions can be found on the [Chef Wiki](http://wiki.opscode.
|
|
106
113
|
|
107
114
|
License and Authors
|
108
115
|
-------------------
|
109
|
-
- Author:: Adam Jacob (<adam@
|
116
|
+
- Author:: Adam Jacob (<adam@getchef.com>)
|
110
117
|
|
111
118
|
```text
|
112
|
-
Copyright 2009-
|
119
|
+
Copyright 2009-2014 Opscode, Inc.
|
113
120
|
|
114
121
|
Licensed under the Apache License, Version 2.0 (the "License");
|
115
122
|
you may not use this file except in compliance with the License.
|
data/knife-ec2.gemspec
CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.authors = ['Adam Jacob', 'Seth Chisamore']
|
9
9
|
s.email = ['adam@opscode.com', 'schisamo@opscode.com']
|
10
10
|
s.homepage = 'https://github.com/opscode/knife-ec2'
|
11
|
-
s.summary = %q{EC2 Support for Chef
|
11
|
+
s.summary = %q{EC2 Support for Chef's Knife Command}
|
12
12
|
s.description = s.summary
|
13
13
|
s.license = 'Apache 2.0'
|
14
14
|
|
@@ -16,13 +16,14 @@ Gem::Specification.new do |s|
|
|
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 'chef', '>= 0.10.10'
|
19
|
+
s.add_dependency 'fog', '~> 1.20.0'
|
21
20
|
s.add_dependency 'knife-windows', '>= 0.5.12'
|
22
21
|
|
23
|
-
s.add_development_dependency '
|
24
|
-
s.add_development_dependency '
|
25
|
-
s.add_development_dependency '
|
22
|
+
s.add_development_dependency 'mixlib-config', '~> 2.0'
|
23
|
+
s.add_development_dependency 'chef', '>= 0.10.10'
|
24
|
+
s.add_development_dependency 'rspec', '~> 2.14'
|
25
|
+
s.add_development_dependency 'rake', '~> 10.1'
|
26
|
+
s.add_development_dependency 'sdoc', '~> 0.3'
|
26
27
|
|
27
28
|
s.require_paths = ['lib']
|
28
29
|
end
|
data/lib/chef/knife/ec2_base.rb
CHANGED
@@ -95,7 +95,7 @@ class Chef
|
|
95
95
|
# File format:
|
96
96
|
# AWSAccessKeyId=somethingsomethingdarkside
|
97
97
|
# AWSSecretKey=somethingsomethingcomplete
|
98
|
-
entries = Hash[*File.read(Chef::Config[:knife][:aws_credential_file]).split(/[=\n]/)]
|
98
|
+
entries = Hash[*File.read(Chef::Config[:knife][:aws_credential_file]).split(/[=\n]/).map(&:chomp)]
|
99
99
|
Chef::Config[:knife][:aws_access_key_id] = entries['AWSAccessKeyId']
|
100
100
|
Chef::Config[:knife][:aws_secret_access_key] = entries['AWSSecretKey']
|
101
101
|
end
|
@@ -71,6 +71,10 @@ class Chef
|
|
71
71
|
:long => "--associate-eip IP_ADDRESS",
|
72
72
|
:description => "Associate existing elastic IP address with instance after launch"
|
73
73
|
|
74
|
+
option :dedicated_instance,
|
75
|
+
:long => "--dedicated_instance",
|
76
|
+
:description => "Launch as a Dedicated instance (VPC ONLY)"
|
77
|
+
|
74
78
|
option :placement_group,
|
75
79
|
:long => "--placement-group PLACEMENT_GROUP",
|
76
80
|
:description => "The placement group to place a cluster compute instance",
|
@@ -137,11 +141,11 @@ class Chef
|
|
137
141
|
:long => "--bootstrap-version VERSION",
|
138
142
|
:description => "The version of Chef to install",
|
139
143
|
:proc => Proc.new { |v| Chef::Config[:knife][:bootstrap_version] = v }
|
140
|
-
|
144
|
+
|
141
145
|
option :bootstrap_proxy,
|
142
|
-
|
143
|
-
|
144
|
-
|
146
|
+
:long => "--bootstrap-proxy PROXY_URL",
|
147
|
+
:description => "The proxy server for the node being bootstrapped",
|
148
|
+
:proc => Proc.new { |p| Chef::Config[:knife][:bootstrap_proxy] = p }
|
145
149
|
|
146
150
|
option :distro,
|
147
151
|
:short => "-d DISTRO",
|
@@ -212,7 +216,7 @@ class Chef
|
|
212
216
|
:long => "--bootstrap-protocol protocol",
|
213
217
|
:description => "protocol to bootstrap windows servers. options: winrm/ssh",
|
214
218
|
:proc => Proc.new { |key| Chef::Config[:knife][:bootstrap_protocol] = key },
|
215
|
-
:default =>
|
219
|
+
:default => nil
|
216
220
|
|
217
221
|
option :fqdn,
|
218
222
|
:long => "--fqdn FQDN",
|
@@ -245,101 +249,14 @@ class Chef
|
|
245
249
|
option :server_connect_attribute,
|
246
250
|
:long => "--server-connect-attribute ATTRIBUTE",
|
247
251
|
:short => "-a ATTRIBUTE",
|
248
|
-
:description => "The EC2 server attribute to use for SSH connection",
|
252
|
+
:description => "The EC2 server attribute to use for SSH connection. Use this attr for creating VPC instances along with --associate-eip",
|
249
253
|
:default => nil
|
250
254
|
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
sleep 2
|
257
|
-
false
|
258
|
-
rescue Errno::ETIMEDOUT
|
259
|
-
false
|
260
|
-
rescue Errno::EPERM
|
261
|
-
false
|
262
|
-
rescue Errno::ECONNREFUSED
|
263
|
-
sleep 2
|
264
|
-
false
|
265
|
-
rescue Errno::EHOSTUNREACH
|
266
|
-
sleep 2
|
267
|
-
false
|
268
|
-
rescue Errno::ENETUNREACH
|
269
|
-
sleep 2
|
270
|
-
false
|
271
|
-
ensure
|
272
|
-
tcp_socket && tcp_socket.close
|
273
|
-
end
|
274
|
-
|
275
|
-
def tcp_test_ssh(hostname, ssh_port)
|
276
|
-
tcp_socket = TCPSocket.new(hostname, ssh_port)
|
277
|
-
readable = IO.select([tcp_socket], nil, nil, 5)
|
278
|
-
if readable
|
279
|
-
Chef::Log.debug("sshd accepting connections on #{hostname}, banner is #{tcp_socket.gets}")
|
280
|
-
yield
|
281
|
-
true
|
282
|
-
else
|
283
|
-
false
|
284
|
-
end
|
285
|
-
rescue SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ENETUNREACH, IOError
|
286
|
-
sleep 2
|
287
|
-
false
|
288
|
-
rescue Errno::EPERM, Errno::ETIMEDOUT
|
289
|
-
false
|
290
|
-
# This happens on some mobile phone networks
|
291
|
-
rescue Errno::ECONNRESET
|
292
|
-
sleep 2
|
293
|
-
false
|
294
|
-
ensure
|
295
|
-
tcp_socket && tcp_socket.close
|
296
|
-
end
|
297
|
-
|
298
|
-
def decrypt_admin_password(encoded_password, key)
|
299
|
-
require 'base64'
|
300
|
-
require 'openssl'
|
301
|
-
private_key = OpenSSL::PKey::RSA.new(key)
|
302
|
-
encrypted_password = Base64.decode64(encoded_password)
|
303
|
-
password = private_key.private_decrypt(encrypted_password)
|
304
|
-
password
|
305
|
-
end
|
306
|
-
|
307
|
-
def check_windows_password_available(server_id)
|
308
|
-
response = connection.get_password_data(server_id)
|
309
|
-
if not response.body["passwordData"]
|
310
|
-
return false
|
311
|
-
end
|
312
|
-
response.body["passwordData"]
|
313
|
-
end
|
314
|
-
|
315
|
-
def windows_password
|
316
|
-
if not locate_config_value(:winrm_password)
|
317
|
-
if locate_config_value(:identity_file)
|
318
|
-
print "\n#{ui.color("Waiting for Windows Admin password to be available", :magenta)}"
|
319
|
-
print(".") until check_windows_password_available(@server.id) {
|
320
|
-
sleep 1000 #typically is available after 30 mins
|
321
|
-
puts("done")
|
322
|
-
}
|
323
|
-
response = connection.get_password_data(@server.id)
|
324
|
-
data = File.read(locate_config_value(:identity_file))
|
325
|
-
config[:winrm_password] = decrypt_admin_password(response.body["passwordData"], data)
|
326
|
-
else
|
327
|
-
ui.error("Cannot find SSH Identity file, required to fetch dynamically generated password")
|
328
|
-
exit 1
|
329
|
-
end
|
330
|
-
else
|
331
|
-
locate_config_value(:winrm_password)
|
332
|
-
end
|
333
|
-
end
|
334
|
-
|
335
|
-
def load_winrm_deps
|
336
|
-
require 'winrm'
|
337
|
-
require 'em-winrm'
|
338
|
-
require 'chef/knife/winrm'
|
339
|
-
require 'chef/knife/bootstrap_windows_winrm'
|
340
|
-
require 'chef/knife/bootstrap_windows_ssh'
|
341
|
-
require 'chef/knife/core/windows_bootstrap_context'
|
342
|
-
end
|
255
|
+
option :associate_public_ip,
|
256
|
+
:long => "--associate-public-ip",
|
257
|
+
:description => "Associate public ip to VPC instance.",
|
258
|
+
:boolean => true,
|
259
|
+
:default => false
|
343
260
|
|
344
261
|
def run
|
345
262
|
$stdout.sync = true
|
@@ -398,7 +315,7 @@ class Chef
|
|
398
315
|
begin
|
399
316
|
create_tags(hashed_tags) unless hashed_tags.empty?
|
400
317
|
associate_eip(elastic_ip) if config[:associate_eip]
|
401
|
-
rescue Fog::Compute::AWS::NotFound, Fog::Errors::Error
|
318
|
+
rescue Fog::Compute::AWS::NotFound, Fog::Errors::Error
|
402
319
|
raise if (tries -= 1) <= 0
|
403
320
|
ui.warn("server not ready, retrying tag application (retries left: #{tries})")
|
404
321
|
sleep 5
|
@@ -407,6 +324,10 @@ class Chef
|
|
407
324
|
|
408
325
|
if vpc_mode?
|
409
326
|
msg_pair("Subnet ID", @server.subnet_id)
|
327
|
+
msg_pair("Tenancy", @server.tenancy)
|
328
|
+
if config[:associate_public_ip]
|
329
|
+
msg_pair("Public DNS Name", @server.dns_name)
|
330
|
+
end
|
410
331
|
if elastic_ip
|
411
332
|
msg_pair("Public IP Address", @server.public_ip_address)
|
412
333
|
end
|
@@ -417,10 +338,10 @@ class Chef
|
|
417
338
|
end
|
418
339
|
msg_pair("Private IP Address", @server.private_ip_address)
|
419
340
|
|
420
|
-
|
421
341
|
#Check if Server is Windows or Linux
|
422
342
|
if is_image_windows?
|
423
343
|
protocol = locate_config_value(:bootstrap_protocol)
|
344
|
+
protocol ||= 'winrm'
|
424
345
|
# Set distro to windows-chef-client-msi
|
425
346
|
config[:distro] = "windows-chef-client-msi" if (config[:distro].nil? || config[:distro] == "chef-full")
|
426
347
|
if protocol == 'winrm'
|
@@ -439,11 +360,12 @@ class Chef
|
|
439
360
|
}
|
440
361
|
ssh_override_winrm
|
441
362
|
end
|
442
|
-
bootstrap_for_windows_node(@server,ssh_connect_host).run
|
363
|
+
bootstrap_for_windows_node(@server, ssh_connect_host).run
|
443
364
|
else
|
444
|
-
|
445
|
-
|
446
|
-
|
365
|
+
print "\n#{ui.color("Waiting for sshd", :magenta)}"
|
366
|
+
wait_for_sshd(ssh_connect_host)
|
367
|
+
ssh_override_winrm
|
368
|
+
bootstrap_for_linux_node(@server, ssh_connect_host).run
|
447
369
|
end
|
448
370
|
|
449
371
|
puts "\n"
|
@@ -480,6 +402,10 @@ class Chef
|
|
480
402
|
end
|
481
403
|
if vpc_mode?
|
482
404
|
msg_pair("Subnet ID", @server.subnet_id)
|
405
|
+
msg_pair("Tenancy", @server.tenancy)
|
406
|
+
if config[:associate_public_ip]
|
407
|
+
msg_pair("Public DNS Name", @server.dns_name)
|
408
|
+
end
|
483
409
|
else
|
484
410
|
msg_pair("Public DNS Name", @server.dns_name)
|
485
411
|
msg_pair("Public IP Address", @server.public_ip_address)
|
@@ -511,36 +437,35 @@ class Chef
|
|
511
437
|
end
|
512
438
|
|
513
439
|
def fetch_server_fqdn(ip_addr)
|
514
|
-
|
515
|
-
|
440
|
+
require 'resolv'
|
441
|
+
Resolv.getname(ip_addr)
|
516
442
|
end
|
517
443
|
|
518
444
|
def bootstrap_for_windows_node(server, fqdn)
|
519
|
-
if locate_config_value(:bootstrap_protocol) == 'winrm'
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
445
|
+
if locate_config_value(:bootstrap_protocol) == 'winrm' || locate_config_value(:bootstrap_protocol) == nil
|
446
|
+
if locate_config_value(:kerberos_realm)
|
447
|
+
#Fetch AD/WINS based fqdn if any for Kerberos-based Auth
|
448
|
+
fqdn = locate_config_value(:fqdn) || fetch_server_fqdn(server.private_ip_address)
|
449
|
+
end
|
450
|
+
bootstrap = Chef::Knife::BootstrapWindowsWinrm.new
|
451
|
+
bootstrap.config[:winrm_user] = locate_config_value(:winrm_user)
|
452
|
+
bootstrap.config[:winrm_password] = windows_password
|
453
|
+
bootstrap.config[:winrm_transport] = locate_config_value(:winrm_transport)
|
454
|
+
bootstrap.config[:kerberos_keytab_file] = locate_config_value(:kerberos_keytab_file)
|
455
|
+
bootstrap.config[:kerberos_realm] = locate_config_value(:kerberos_realm)
|
456
|
+
bootstrap.config[:kerberos_service] = locate_config_value(:kerberos_service)
|
457
|
+
bootstrap.config[:ca_trust_file] = locate_config_value(:ca_trust_file)
|
458
|
+
bootstrap.config[:winrm_port] = locate_config_value(:winrm_port)
|
534
459
|
elsif locate_config_value(:bootstrap_protocol) == 'ssh'
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
460
|
+
bootstrap = Chef::Knife::BootstrapWindowsSsh.new
|
461
|
+
bootstrap.config[:ssh_user] = locate_config_value(:ssh_user)
|
462
|
+
bootstrap.config[:ssh_password] = locate_config_value(:ssh_password)
|
463
|
+
bootstrap.config[:ssh_port] = locate_config_value(:ssh_port)
|
464
|
+
bootstrap.config[:identity_file] = locate_config_value(:identity_file)
|
465
|
+
bootstrap.config[:no_host_key_verify] = locate_config_value(:no_host_key_verify)
|
541
466
|
else
|
542
|
-
|
543
|
-
|
467
|
+
ui.error("Unsupported Bootstrapping Protocol. Supported : winrm, ssh")
|
468
|
+
exit 1
|
544
469
|
end
|
545
470
|
bootstrap.name_args = [fqdn]
|
546
471
|
bootstrap.config[:chef_node_name] = config[:chef_node_name] || server.id
|
@@ -572,7 +497,6 @@ class Chef
|
|
572
497
|
end
|
573
498
|
|
574
499
|
def validate!
|
575
|
-
|
576
500
|
super([:image, :aws_ssh_key_id, :aws_access_key_id, :aws_secret_access_key])
|
577
501
|
|
578
502
|
if ami.nil?
|
@@ -584,11 +508,22 @@ class Chef
|
|
584
508
|
ui.error("You are using a VPC, security groups specified with '-G' are not allowed, specify one or more security group ids with '-g' instead.")
|
585
509
|
exit 1
|
586
510
|
end
|
511
|
+
|
587
512
|
if !vpc_mode? and !!config[:private_ip_address]
|
588
513
|
ui.error("You can only specify a private IP address if you are using VPC.")
|
589
514
|
exit 1
|
590
515
|
end
|
591
516
|
|
517
|
+
if config[:dedicated_instance] and !vpc_mode?
|
518
|
+
ui.error("You can only specify a Dedicated Instance if you are using VPC.")
|
519
|
+
exit 1
|
520
|
+
end
|
521
|
+
|
522
|
+
if !vpc_mode? and config[:associate_public_ip]
|
523
|
+
ui.error("--associate-public-ip option only applies to VPC instances, and you have not specified a subnet id.")
|
524
|
+
exit 1
|
525
|
+
end
|
526
|
+
|
592
527
|
if config[:associate_eip]
|
593
528
|
eips = connection.addresses.collect{|addr| addr if addr.domain == eip_scope}.compact
|
594
529
|
|
@@ -629,6 +564,8 @@ class Chef
|
|
629
564
|
server_def[:private_ip_address] = locate_config_value(:private_ip_address) if vpc_mode?
|
630
565
|
server_def[:placement_group] = locate_config_value(:placement_group)
|
631
566
|
server_def[:iam_instance_profile_name] = locate_config_value(:iam_instance_profile)
|
567
|
+
server_def[:tenancy] = "dedicated" if vpc_mode? and locate_config_value(:dedicated_instance)
|
568
|
+
server_def[:associate_public_ip] = locate_config_value(:associate_public_ip) if vpc_mode? and config[:associate_public_ip]
|
632
569
|
|
633
570
|
if Chef::Config[:knife][:aws_user_data]
|
634
571
|
begin
|
@@ -683,9 +620,14 @@ class Chef
|
|
683
620
|
end
|
684
621
|
|
685
622
|
def wait_for_tunnelled_sshd(hostname)
|
686
|
-
|
687
|
-
print(".") until tunnel_test_ssh(
|
688
|
-
|
623
|
+
initial = true
|
624
|
+
print(".") until tunnel_test_ssh(hostname) {
|
625
|
+
if initial
|
626
|
+
initial = false
|
627
|
+
sleep (vpc_mode? ? 40 : 10)
|
628
|
+
else
|
629
|
+
sleep 10
|
630
|
+
end
|
689
631
|
puts("done")
|
690
632
|
}
|
691
633
|
end
|
@@ -707,18 +649,28 @@ class Chef
|
|
707
649
|
end
|
708
650
|
|
709
651
|
def wait_for_direct_sshd(hostname, ssh_port)
|
710
|
-
|
711
|
-
|
652
|
+
initial = true
|
653
|
+
print(".") until tcp_test_ssh(hostname, ssh_port) {
|
654
|
+
if initial
|
655
|
+
initial = false
|
656
|
+
sleep (vpc_mode? ? 40 : 10)
|
657
|
+
else
|
658
|
+
sleep 10
|
659
|
+
end
|
712
660
|
puts("done")
|
713
661
|
}
|
714
662
|
end
|
715
663
|
|
716
664
|
def ssh_connect_host
|
717
665
|
@ssh_connect_host ||= if config[:server_connect_attribute]
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
666
|
+
server.send(config[:server_connect_attribute])
|
667
|
+
else
|
668
|
+
if vpc_mode? && !config[:associate_public_ip]
|
669
|
+
server.private_ip_address
|
670
|
+
else
|
671
|
+
server.dns_name
|
672
|
+
end
|
673
|
+
end
|
722
674
|
end
|
723
675
|
|
724
676
|
def create_tags(hashed_tags)
|
@@ -754,6 +706,107 @@ class Chef
|
|
754
706
|
config[:identity_file] = locate_config_value(:kerberos_keytab_file)
|
755
707
|
end
|
756
708
|
end
|
709
|
+
|
710
|
+
def tcp_test_winrm(ip_addr, port)
|
711
|
+
tcp_socket = TCPSocket.new(ip_addr, port)
|
712
|
+
yield
|
713
|
+
true
|
714
|
+
rescue SocketError
|
715
|
+
sleep 2
|
716
|
+
false
|
717
|
+
rescue Errno::ETIMEDOUT
|
718
|
+
false
|
719
|
+
rescue Errno::EPERM
|
720
|
+
false
|
721
|
+
rescue Errno::ECONNREFUSED
|
722
|
+
sleep 2
|
723
|
+
false
|
724
|
+
rescue Errno::EHOSTUNREACH
|
725
|
+
sleep 2
|
726
|
+
false
|
727
|
+
rescue Errno::ENETUNREACH
|
728
|
+
sleep 2
|
729
|
+
false
|
730
|
+
ensure
|
731
|
+
tcp_socket && tcp_socket.close
|
732
|
+
end
|
733
|
+
|
734
|
+
def tcp_test_ssh(hostname, ssh_port)
|
735
|
+
tcp_socket = TCPSocket.new(hostname, ssh_port)
|
736
|
+
readable = IO.select([tcp_socket], nil, nil, 5)
|
737
|
+
if readable
|
738
|
+
ssh_banner = tcp_socket.gets
|
739
|
+
if ssh_banner.nil? or ssh_banner.empty?
|
740
|
+
false
|
741
|
+
else
|
742
|
+
Chef::Log.debug("sshd accepting connections on #{hostname}, banner is #{ssh_banner}")
|
743
|
+
yield
|
744
|
+
true
|
745
|
+
end
|
746
|
+
else
|
747
|
+
false
|
748
|
+
end
|
749
|
+
rescue SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ENETUNREACH, IOError
|
750
|
+
Chef::Log.debug("ssh failed to connect: #{hostname}")
|
751
|
+
sleep 2
|
752
|
+
false
|
753
|
+
rescue Errno::EPERM, Errno::ETIMEDOUT
|
754
|
+
Chef::Log.debug("ssh timed out: #{hostname}")
|
755
|
+
false
|
756
|
+
# This happens on some mobile phone networks
|
757
|
+
rescue Errno::ECONNRESET
|
758
|
+
Chef::Log.debug("ssh reset its connection: #{hostname}")
|
759
|
+
sleep 2
|
760
|
+
false
|
761
|
+
ensure
|
762
|
+
tcp_socket && tcp_socket.close
|
763
|
+
end
|
764
|
+
|
765
|
+
def decrypt_admin_password(encoded_password, key)
|
766
|
+
require 'base64'
|
767
|
+
require 'openssl'
|
768
|
+
private_key = OpenSSL::PKey::RSA.new(key)
|
769
|
+
encrypted_password = Base64.decode64(encoded_password)
|
770
|
+
password = private_key.private_decrypt(encrypted_password)
|
771
|
+
password
|
772
|
+
end
|
773
|
+
|
774
|
+
def check_windows_password_available(server_id)
|
775
|
+
response = connection.get_password_data(server_id)
|
776
|
+
if not response.body["passwordData"]
|
777
|
+
return false
|
778
|
+
end
|
779
|
+
response.body["passwordData"]
|
780
|
+
end
|
781
|
+
|
782
|
+
def windows_password
|
783
|
+
if not locate_config_value(:winrm_password)
|
784
|
+
if locate_config_value(:identity_file)
|
785
|
+
print "\n#{ui.color("Waiting for Windows Admin password to be available", :magenta)}"
|
786
|
+
print(".") until check_windows_password_available(@server.id) {
|
787
|
+
sleep 1000 #typically is available after 30 mins
|
788
|
+
puts("done")
|
789
|
+
}
|
790
|
+
response = connection.get_password_data(@server.id)
|
791
|
+
data = File.read(locate_config_value(:identity_file))
|
792
|
+
config[:winrm_password] = decrypt_admin_password(response.body["passwordData"], data)
|
793
|
+
else
|
794
|
+
ui.error("Cannot find SSH Identity file, required to fetch dynamically generated password")
|
795
|
+
exit 1
|
796
|
+
end
|
797
|
+
else
|
798
|
+
locate_config_value(:winrm_password)
|
799
|
+
end
|
800
|
+
end
|
801
|
+
|
802
|
+
def load_winrm_deps
|
803
|
+
require 'winrm'
|
804
|
+
require 'em-winrm'
|
805
|
+
require 'chef/knife/winrm'
|
806
|
+
require 'chef/knife/bootstrap_windows_winrm'
|
807
|
+
require 'chef/knife/bootstrap_windows_ssh'
|
808
|
+
require 'chef/knife/core/windows_bootstrap_context'
|
809
|
+
end
|
757
810
|
end
|
758
811
|
end
|
759
812
|
end
|
data/lib/knife-ec2/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -5,3 +5,13 @@ require 'chef/knife/ec2_server_create'
|
|
5
5
|
require 'chef/knife/ec2_instance_data'
|
6
6
|
require 'chef/knife/ec2_server_delete'
|
7
7
|
require 'chef/knife/ec2_server_list'
|
8
|
+
|
9
|
+
# Clear config between each example
|
10
|
+
# to avoid dependencies between examples
|
11
|
+
RSpec.configure do |c|
|
12
|
+
c.before(:each) do
|
13
|
+
Chef::Config.reset
|
14
|
+
Chef::Config[:knife] ={}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -23,7 +23,7 @@ require 'chef/knife/bootstrap_windows_winrm'
|
|
23
23
|
require 'chef/knife/bootstrap_windows_ssh'
|
24
24
|
|
25
25
|
describe Chef::Knife::Ec2ServerCreate do
|
26
|
-
before do
|
26
|
+
before(:each) do
|
27
27
|
@knife_ec2_create = Chef::Knife::Ec2ServerCreate.new
|
28
28
|
@knife_ec2_create.initial_sleep_delay = 0
|
29
29
|
@knife_ec2_create.stub(:tcp_test_ssh).and_return(true)
|
@@ -494,6 +494,33 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
494
494
|
@knife_ec2_create.ui.stub(:error)
|
495
495
|
end
|
496
496
|
|
497
|
+
describe "when reading aws_credential_file" do
|
498
|
+
before do
|
499
|
+
Chef::Config[:knife].delete(:aws_access_key_id)
|
500
|
+
Chef::Config[:knife].delete(:aws_secret_access_key)
|
501
|
+
|
502
|
+
Chef::Config[:knife][:aws_credential_file] = '/apple/pear'
|
503
|
+
@access_key_id = 'access_key_id'
|
504
|
+
@secret_key = 'secret_key'
|
505
|
+
end
|
506
|
+
|
507
|
+
it "reads UNIX Line endings" do
|
508
|
+
File.stub(:read).
|
509
|
+
and_return("AWSAccessKeyId=#{@access_key_id}\nAWSSecretKey=#{@secret_key}")
|
510
|
+
@knife_ec2_create.validate!
|
511
|
+
Chef::Config[:knife][:aws_access_key_id].should == @access_key_id
|
512
|
+
Chef::Config[:knife][:aws_secret_access_key].should == @secret_key
|
513
|
+
end
|
514
|
+
|
515
|
+
it "reads DOS Line endings" do
|
516
|
+
File.stub(:read).
|
517
|
+
and_return("AWSAccessKeyId=#{@access_key_id}\r\nAWSSecretKey=#{@secret_key}")
|
518
|
+
@knife_ec2_create.validate!
|
519
|
+
Chef::Config[:knife][:aws_access_key_id].should == @access_key_id
|
520
|
+
Chef::Config[:knife][:aws_secret_access_key].should == @secret_key
|
521
|
+
end
|
522
|
+
end
|
523
|
+
|
497
524
|
it "disallows security group names when using a VPC" do
|
498
525
|
@knife_ec2_create.config[:subnet_id] = 'subnet-1a2b3c4d'
|
499
526
|
@knife_ec2_create.config[:security_group_ids] = 'sg-aabbccdd'
|
@@ -514,6 +541,13 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
514
541
|
|
515
542
|
lambda { @knife_ec2_create.validate! }.should raise_error SystemExit
|
516
543
|
end
|
544
|
+
|
545
|
+
it "disallows associate public ip option when not using a VPC" do
|
546
|
+
@knife_ec2_create.config[:associate_public_ip] = true
|
547
|
+
@knife_ec2_create.config[:subnet_id] = nil
|
548
|
+
|
549
|
+
lambda { @knife_ec2_create.validate! }.should raise_error SystemExit
|
550
|
+
end
|
517
551
|
end
|
518
552
|
|
519
553
|
describe "when creating the server definition" do
|
@@ -597,6 +631,37 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
597
631
|
|
598
632
|
server_def[:iam_instance_profile_name].should == nil
|
599
633
|
end
|
634
|
+
|
635
|
+
it 'Set Tenancy Dedicated when both VPC mode and Flag is True' do
|
636
|
+
@knife_ec2_create.config[:dedicated_instance] = true
|
637
|
+
@knife_ec2_create.stub(:vpc_mode? => true)
|
638
|
+
|
639
|
+
server_def = @knife_ec2_create.create_server_def
|
640
|
+
server_def[:tenancy].should == "dedicated"
|
641
|
+
end
|
642
|
+
|
643
|
+
it 'Tenancy should be default with no vpc mode even is specified' do
|
644
|
+
@knife_ec2_create.config[:dedicated_instance] = true
|
645
|
+
|
646
|
+
server_def = @knife_ec2_create.create_server_def
|
647
|
+
server_def[:tenancy].should == nil
|
648
|
+
end
|
649
|
+
|
650
|
+
it 'Tenancy should be default with vpc but not requested' do
|
651
|
+
@knife_ec2_create.stub(:vpc_mode? => true)
|
652
|
+
|
653
|
+
server_def = @knife_ec2_create.create_server_def
|
654
|
+
server_def[:tenancy].should == nil
|
655
|
+
end
|
656
|
+
|
657
|
+
it "sets associate_public_ip to true if specified and in vpc_mode" do
|
658
|
+
@knife_ec2_create.config[:subnet_id] = 'subnet-1a2b3c4d'
|
659
|
+
@knife_ec2_create.config[:associate_public_ip] = true
|
660
|
+
server_def = @knife_ec2_create.create_server_def
|
661
|
+
|
662
|
+
server_def[:subnet_id].should == 'subnet-1a2b3c4d'
|
663
|
+
server_def[:associate_public_ip].should == true
|
664
|
+
end
|
600
665
|
end
|
601
666
|
|
602
667
|
describe "ssh_connect_host" do
|
@@ -620,7 +685,6 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
620
685
|
@knife_ec2_create.stub(:vpc_mode? => true)
|
621
686
|
@knife_ec2_create.ssh_connect_host.should == 'private_ip'
|
622
687
|
end
|
623
|
-
|
624
688
|
end
|
625
689
|
|
626
690
|
describe "with custom server attribute" do
|
@@ -630,4 +694,29 @@ describe Chef::Knife::Ec2ServerCreate do
|
|
630
694
|
end
|
631
695
|
end
|
632
696
|
end
|
697
|
+
|
698
|
+
describe "tcp_test_ssh" do
|
699
|
+
# Normally we would only get the header after we send a client header, e.g. 'SSH-2.0-client'
|
700
|
+
it "should return true if we get an ssh header" do
|
701
|
+
@knife_ec2_create = Chef::Knife::Ec2ServerCreate.new
|
702
|
+
TCPSocket.stub(:new).and_return(StringIO.new("SSH-2.0-OpenSSH_6.1p1 Debian-4"))
|
703
|
+
IO.stub(:select).and_return(true)
|
704
|
+
@knife_ec2_create.should_receive(:tcp_test_ssh).and_yield.and_return(true)
|
705
|
+
@knife_ec2_create.tcp_test_ssh("blackhole.ninja", 22) {nil}
|
706
|
+
end
|
707
|
+
|
708
|
+
it "should return false if we do not get an ssh header" do
|
709
|
+
@knife_ec2_create = Chef::Knife::Ec2ServerCreate.new
|
710
|
+
TCPSocket.stub(:new).and_return(StringIO.new(""))
|
711
|
+
IO.stub(:select).and_return(true)
|
712
|
+
@knife_ec2_create.tcp_test_ssh("blackhole.ninja", 22).should be_false
|
713
|
+
end
|
714
|
+
|
715
|
+
it "should return false if the socket isn't ready" do
|
716
|
+
@knife_ec2_create = Chef::Knife::Ec2ServerCreate.new
|
717
|
+
TCPSocket.stub(:new)
|
718
|
+
IO.stub(:select).and_return(false)
|
719
|
+
@knife_ec2_create.tcp_test_ssh("blackhole.ninja", 22).should be_false
|
720
|
+
end
|
721
|
+
end
|
633
722
|
end
|
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knife-ec2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.8.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Adam Jacob
|
@@ -10,60 +9,67 @@ authors:
|
|
10
9
|
autorequire:
|
11
10
|
bindir: bin
|
12
11
|
cert_chain: []
|
13
|
-
date:
|
12
|
+
date: 2014-03-10 00:00:00.000000000 Z
|
14
13
|
dependencies:
|
15
14
|
- !ruby/object:Gem::Dependency
|
16
15
|
name: fog
|
17
16
|
requirement: !ruby/object:Gem::Requirement
|
18
|
-
none: false
|
19
17
|
requirements:
|
20
18
|
- - ~>
|
21
19
|
- !ruby/object:Gem::Version
|
22
|
-
version: 1.
|
20
|
+
version: 1.20.0
|
23
21
|
type: :runtime
|
24
22
|
prerelease: false
|
25
23
|
version_requirements: !ruby/object:Gem::Requirement
|
26
|
-
none: false
|
27
24
|
requirements:
|
28
25
|
- - ~>
|
29
26
|
- !ruby/object:Gem::Version
|
30
|
-
version: 1.
|
27
|
+
version: 1.20.0
|
31
28
|
- !ruby/object:Gem::Dependency
|
32
|
-
name:
|
29
|
+
name: knife-windows
|
33
30
|
requirement: !ruby/object:Gem::Requirement
|
34
|
-
none: false
|
35
31
|
requirements:
|
36
32
|
- - ! '>='
|
37
33
|
- !ruby/object:Gem::Version
|
38
|
-
version: 0.
|
34
|
+
version: 0.5.12
|
39
35
|
type: :runtime
|
40
36
|
prerelease: false
|
41
37
|
version_requirements: !ruby/object:Gem::Requirement
|
42
|
-
none: false
|
43
38
|
requirements:
|
44
39
|
- - ! '>='
|
45
40
|
- !ruby/object:Gem::Version
|
46
|
-
version: 0.
|
41
|
+
version: 0.5.12
|
47
42
|
- !ruby/object:Gem::Dependency
|
48
|
-
name:
|
43
|
+
name: mixlib-config
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ~>
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '2.0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ~>
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '2.0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: chef
|
49
58
|
requirement: !ruby/object:Gem::Requirement
|
50
|
-
none: false
|
51
59
|
requirements:
|
52
60
|
- - ! '>='
|
53
61
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0.
|
55
|
-
type: :
|
62
|
+
version: 0.10.10
|
63
|
+
type: :development
|
56
64
|
prerelease: false
|
57
65
|
version_requirements: !ruby/object:Gem::Requirement
|
58
|
-
none: false
|
59
66
|
requirements:
|
60
67
|
- - ! '>='
|
61
68
|
- !ruby/object:Gem::Version
|
62
|
-
version: 0.
|
69
|
+
version: 0.10.10
|
63
70
|
- !ruby/object:Gem::Dependency
|
64
71
|
name: rspec
|
65
72
|
requirement: !ruby/object:Gem::Requirement
|
66
|
-
none: false
|
67
73
|
requirements:
|
68
74
|
- - ~>
|
69
75
|
- !ruby/object:Gem::Version
|
@@ -71,7 +77,6 @@ dependencies:
|
|
71
77
|
type: :development
|
72
78
|
prerelease: false
|
73
79
|
version_requirements: !ruby/object:Gem::Requirement
|
74
|
-
none: false
|
75
80
|
requirements:
|
76
81
|
- - ~>
|
77
82
|
- !ruby/object:Gem::Version
|
@@ -79,7 +84,6 @@ dependencies:
|
|
79
84
|
- !ruby/object:Gem::Dependency
|
80
85
|
name: rake
|
81
86
|
requirement: !ruby/object:Gem::Requirement
|
82
|
-
none: false
|
83
87
|
requirements:
|
84
88
|
- - ~>
|
85
89
|
- !ruby/object:Gem::Version
|
@@ -87,7 +91,6 @@ dependencies:
|
|
87
91
|
type: :development
|
88
92
|
prerelease: false
|
89
93
|
version_requirements: !ruby/object:Gem::Requirement
|
90
|
-
none: false
|
91
94
|
requirements:
|
92
95
|
- - ~>
|
93
96
|
- !ruby/object:Gem::Version
|
@@ -95,7 +98,6 @@ dependencies:
|
|
95
98
|
- !ruby/object:Gem::Dependency
|
96
99
|
name: sdoc
|
97
100
|
requirement: !ruby/object:Gem::Requirement
|
98
|
-
none: false
|
99
101
|
requirements:
|
100
102
|
- - ~>
|
101
103
|
- !ruby/object:Gem::Version
|
@@ -103,12 +105,11 @@ dependencies:
|
|
103
105
|
type: :development
|
104
106
|
prerelease: false
|
105
107
|
version_requirements: !ruby/object:Gem::Requirement
|
106
|
-
none: false
|
107
108
|
requirements:
|
108
109
|
- - ~>
|
109
110
|
- !ruby/object:Gem::Version
|
110
111
|
version: '0.3'
|
111
|
-
description: EC2 Support for Chef
|
112
|
+
description: EC2 Support for Chef's Knife Command
|
112
113
|
email:
|
113
114
|
- adam@opscode.com
|
114
115
|
- schisamo@opscode.com
|
@@ -118,6 +119,9 @@ extra_rdoc_files: []
|
|
118
119
|
files:
|
119
120
|
- .gitignore
|
120
121
|
- .travis.yml
|
122
|
+
- CHANGELOG.md
|
123
|
+
- CONTRIBUTING.md
|
124
|
+
- DOC_CHANGES.md
|
121
125
|
- Gemfile
|
122
126
|
- LICENSE
|
123
127
|
- README.md
|
@@ -136,28 +140,27 @@ files:
|
|
136
140
|
homepage: https://github.com/opscode/knife-ec2
|
137
141
|
licenses:
|
138
142
|
- Apache 2.0
|
143
|
+
metadata: {}
|
139
144
|
post_install_message:
|
140
145
|
rdoc_options: []
|
141
146
|
require_paths:
|
142
147
|
- lib
|
143
148
|
required_ruby_version: !ruby/object:Gem::Requirement
|
144
|
-
none: false
|
145
149
|
requirements:
|
146
150
|
- - ! '>='
|
147
151
|
- !ruby/object:Gem::Version
|
148
152
|
version: '0'
|
149
153
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
150
|
-
none: false
|
151
154
|
requirements:
|
152
155
|
- - ! '>='
|
153
156
|
- !ruby/object:Gem::Version
|
154
157
|
version: '0'
|
155
158
|
requirements: []
|
156
159
|
rubyforge_project:
|
157
|
-
rubygems_version: 1.
|
160
|
+
rubygems_version: 2.1.11
|
158
161
|
signing_key:
|
159
|
-
specification_version:
|
160
|
-
summary: EC2 Support for Chef
|
162
|
+
specification_version: 4
|
163
|
+
summary: EC2 Support for Chef's Knife Command
|
161
164
|
test_files:
|
162
165
|
- spec/spec_helper.rb
|
163
166
|
- spec/unit/ec2_server_create_spec.rb
|