chef-provisioning-aws 1.4.0 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 19f4ffce05e2b12c1256593ed8132affc94376f8
4
- data.tar.gz: e606311b2689000c0e5098087d5debaff8c2997d
3
+ metadata.gz: e520aad6f6cafb84d380454daf8dd65285e194cd
4
+ data.tar.gz: b2ec1a747718d0cad0c4bdc9ca6561d1e0daeb6f
5
5
  SHA512:
6
- metadata.gz: a37d0a594d564b0a6da4f84b8a4d9d6222654e7bc2ddedb68d22d830cdfea1321cfb4b3d024264e14c81a7462b1f47b3c311ebff79972deb8bba2b4558847f57
7
- data.tar.gz: 8dd82f47ac3c83b52b124d75a316c1c54a348d755c2e892213cd245fdf5f5cfeabebfb67bc81eed26c9362d62ba6c4dbfa3f07a7ecf40dfcc7d00668d00aa800
6
+ metadata.gz: 0c3d1891e4c22d14f3b03506f39105a884dae7bc00ad7dc2ace729f5325f7fbc935b29be11631387563529b19efcad224bb0e2447b77a0365dfd5f6969cfcc1c
7
+ data.tar.gz: a52717acff8c3ccf2945863f616fd8fce022b11fa813b0c8ace68b737be6a797dbb8364cdd94d74884e206357ea786741c657cc1d581ec90502459e8d7e1f6b4
@@ -26,7 +26,8 @@ module AWSDriver
26
26
  # Try to load the credentials from an ordered list of sources and return the first one that
27
27
  # can be loaded successfully.
28
28
  def get_credentials
29
- shared_creds = ::Aws::SharedCredentials.new(:profile_name => profile_name)
29
+ # http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html#cli-environment
30
+ shared_creds = ::Aws::SharedCredentials.new(:profile_name => profile_name, :path => ENV["AWS_CONFIG_FILE"])
30
31
  instance_profile_creds = ::Aws::InstanceProfileCredentials.new(:retries => 1)
31
32
 
32
33
  if ENV["AWS_ACCESS_KEY_ID"] && ENV["AWS_SECRET_ACCESS_KEY"]
@@ -24,10 +24,11 @@ require 'aws-sdk-v1'
24
24
  require 'aws-sdk'
25
25
  require 'retryable'
26
26
  require 'ubuntu_ami'
27
+ require 'base64'
27
28
 
28
29
  # loads the entire aws-sdk
29
30
  AWS.eager_autoload!
30
- AWS_V2_SERVICES = {"EC2" => "ec2", "S3" => "s3", "ElasticLoadBalancing" => "elb"}
31
+ AWS_V2_SERVICES = {"EC2" => "ec2", "S3" => "s3", "ElasticLoadBalancing" => "elb", "IAM" => "iam"}
31
32
  Aws.eager_autoload!(:services => AWS_V2_SERVICES.keys)
32
33
 
33
34
  # Need to load the resources after the SDK because `aws_sdk_types` can mess
@@ -691,19 +692,65 @@ EOD
691
692
  bootstrap_options[:instance_type] ||= default_instance_type
692
693
  image_id = machine_options[:from_image] || bootstrap_options[:image_id] || machine_options[:image_id] || default_ami_for_region(aws_config.region)
693
694
  bootstrap_options[:image_id] = image_id
695
+ bootstrap_options.delete(:key_path)
694
696
  if !bootstrap_options[:key_name]
695
697
  Chef::Log.debug('No key specified, generating a default one...')
696
698
  bootstrap_options[:key_name] = default_aws_keypair(action_handler, machine_spec)
697
699
  end
700
+ if bootstrap_options[:iam_instance_profile] && bootstrap_options[:iam_instance_profile].is_a?(String)
701
+ bootstrap_options[:iam_instance_profile] = {name: bootstrap_options[:iam_instance_profile]}
702
+ end
703
+ if bootstrap_options[:user_data]
704
+ bootstrap_options[:user_data] = Base64.encode64(bootstrap_options[:user_data])
705
+ end
698
706
 
699
- if machine_options[:is_windows]
700
- Chef::Log.debug "Setting WinRM userdata..."
701
- bootstrap_options[:user_data] = user_data if bootstrap_options[:user_data].nil?
702
- else
703
- Chef::Log.debug "Non-windows, not setting userdata"
707
+ # V1 -> V2 backwards compatability support
708
+ unless bootstrap_options.fetch(:monitoring_enabled, nil).nil?
709
+ bootstrap_options[:monitoring] = {enabled: bootstrap_options.delete(:monitoring_enabled)}
710
+ end
711
+ placement = {}
712
+ if bootstrap_options[:availability_zone]
713
+ placement[:availability_zone] = bootstrap_options.delete(:availability_zone)
714
+ end
715
+ if bootstrap_options[:placement_group]
716
+ placement[:group_name] = bootstrap_options.delete(:placement_group)
717
+ end
718
+ unless bootstrap_options.fetch(:dedicated_tenancy, nil).nil?
719
+ placement[:tenancy] = bootstrap_options.delete(:dedicated_tenancy) ? "dedicated" : "default"
720
+ end
721
+ unless placement.empty?
722
+ bootstrap_options[:placement] = placement
723
+ end
724
+ if bootstrap_options[:subnet]
725
+ bootstrap_options[:subnet_id] = bootstrap_options.delete(:subnet)
704
726
  end
705
727
 
706
728
  bootstrap_options = AWSResource.lookup_options(bootstrap_options, managed_entry_store: machine_spec.managed_entry_store, driver: self)
729
+
730
+ # In the migration from V1 to V2 we still support associate_public_ip_address at the top level
731
+ # we do this after the lookup because we have to copy any present subnets, etc. into the
732
+ # network interfaces block
733
+ unless bootstrap_options.fetch(:associate_public_ip_address, nil).nil?
734
+ if bootstrap_options[:network_interfaces]
735
+ raise "If you specify network_interfaces you must specify associate_public_ip_address in that list"
736
+ end
737
+ network_interface = {
738
+ :device_index => 0,
739
+ :associate_public_ip_address => bootstrap_options.delete(:associate_public_ip_address),
740
+ :delete_on_termination => true
741
+ }
742
+ if bootstrap_options[:subnet_id]
743
+ network_interface[:subnet_id] = bootstrap_options.delete(:subnet_id)
744
+ end
745
+ if bootstrap_options[:private_ip_address]
746
+ network_interface[:private_ip_address] = bootstrap_options.delete(:private_ip_address)
747
+ end
748
+ if bootstrap_options[:security_group_ids]
749
+ network_interface[:groups] = bootstrap_options.delete(:security_group_ids)
750
+ end
751
+ bootstrap_options[:network_interfaces] = [network_interface]
752
+ end
753
+
707
754
  Chef::Log.debug "AWS Bootstrap options: #{bootstrap_options.inspect}"
708
755
  bootstrap_options
709
756
  end
@@ -1,7 +1,7 @@
1
1
  class Chef
2
2
  module Provisioning
3
3
  module AWSDriver
4
- VERSION = '1.4.0'
4
+ VERSION = '1.4.1'
5
5
  end
6
6
  end
7
7
  end
@@ -5,7 +5,7 @@ require 'chef/resource/aws_eip_address'
5
5
  class Chef::Resource::AwsNetworkInterface < Chef::Provisioning::AWSDriver::AWSResourceWithEntry
6
6
  include Chef::Provisioning::AWSDriver::AWSTaggable
7
7
 
8
- aws_sdk_type AWS::EC2::NetworkInterface
8
+ aws_sdk_type AWS::EC2::NetworkInterface, option_names: []
9
9
 
10
10
  attribute :name, kind_of: String, name_attribute: true
11
11
 
@@ -16,7 +16,7 @@ require 'chef/provisioning/aws_driver/aws_resource_with_entry'
16
16
  class Chef::Resource::AwsSubnet < Chef::Provisioning::AWSDriver::AWSResourceWithEntry
17
17
  include Chef::Provisioning::AWSDriver::AWSTaggable
18
18
 
19
- aws_sdk_type AWS::EC2::Subnet
19
+ aws_sdk_type AWS::EC2::Subnet, :id => :id
20
20
 
21
21
  require 'chef/resource/aws_vpc'
22
22
  require 'chef/resource/aws_network_acl'
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require 'openssl'
2
3
 
3
4
  describe Chef::Resource::Machine do
4
5
  extend AWSSupport
@@ -53,6 +54,224 @@ describe Chef::Resource::Machine do
53
54
  ).and be_idempotent
54
55
  end
55
56
 
57
+ it "base64 encodes the user data", :super_slow do
58
+ uniq = Random.rand(100)
59
+ expect_recipe {
60
+ machine "test_machine_#{uniq}" do
61
+ machine_options bootstrap_options: {
62
+ subnet_id: 'test_public_subnet',
63
+ key_name: 'test_key_pair',
64
+ user_data: 'echo \'foo\''
65
+ }
66
+ action :allocate
67
+ end
68
+ }.to create_an_aws_instance("test_machine_#{uniq}"
69
+ ).and be_idempotent
70
+ expect(
71
+ driver.ec2_client.describe_instance_attribute(
72
+ instance_id: driver.ec2_resource.instances(filters: [{name: "tag:Name", values:["test_machine_#{uniq}"]}]).first.id,
73
+ attribute: "userData"
74
+ ).user_data.value
75
+ ).to eq("ZWNobyAnZm9vJw==\n")
76
+ end
77
+
78
+ it "respects the network_interfaces block with maximum attributes", :super_slow do
79
+ private_ip_address_start = Random.rand(30)+10
80
+ expect_recipe {
81
+ machine "test_machine" do
82
+ machine_options bootstrap_options: {
83
+ key_name: 'test_key_pair',
84
+ instance_type: 'm3.medium',
85
+ network_interfaces: [
86
+ {
87
+ # Cannot set associate_public_ip_address and network_interface_id
88
+ # network_interface_id: "eth0",
89
+ device_index: 0,
90
+ subnet_id: test_public_subnet.aws_object.id,
91
+ description: "network interface description",
92
+ private_ip_address: "10.0.0.#{private_ip_address_start}",
93
+ delete_on_termination: true,
94
+ groups: [test_security_group.aws_object.id],
95
+ private_ip_addresses: [
96
+ {
97
+ private_ip_address: "10.0.0.#{private_ip_address_start+1}",
98
+ primary: false
99
+ },
100
+ {
101
+ private_ip_address: "10.0.0.#{private_ip_address_start+2}",
102
+ primary: false
103
+ }
104
+ ],
105
+ # cannot specify both `private_ip_addresses` and `secondary_private_ip_address_count`
106
+ #secondary_private_ip_address_count: 2,
107
+ associate_public_ip_address: true
108
+ }
109
+ ]
110
+ }
111
+ action :ready
112
+ end
113
+ }.to create_an_aws_instance("test_machine",
114
+ network_interfaces: [{
115
+ network_interface_id: /^eni-/,
116
+ subnet_id: test_public_subnet.aws_object.id,
117
+ vpc_id: test_vpc.aws_object.id,
118
+ description: "network interface description",
119
+ status: "in-use",
120
+ private_ip_address: "10.0.0.#{private_ip_address_start}",
121
+ groups: [{group_name: 'test_security_group'}],
122
+ attachment: {
123
+ device_index: 0,
124
+ delete_on_termination: true,
125
+ status: "attached"
126
+ },
127
+ private_ip_addresses: [
128
+ {
129
+ private_ip_address: "10.0.0.#{private_ip_address_start}",
130
+ primary: true,
131
+ # the action must be :ready to give the public ip time to be assigned
132
+ association: {
133
+ public_ip: /\d+/
134
+ }
135
+ },
136
+ {
137
+ private_ip_address: "10.0.0.#{private_ip_address_start+1}",
138
+ primary: false
139
+ },
140
+ {
141
+ private_ip_address: "10.0.0.#{private_ip_address_start+2}",
142
+ primary: false
143
+ }
144
+ ]
145
+ }]
146
+ ).and be_idempotent
147
+ end
148
+
149
+ it "converts associate_public_ip_address at the top level to the network interface", :super_slow do
150
+ private_ip_address_start = Random.rand(30)+10
151
+ expect_recipe {
152
+ machine "test_machine" do
153
+ machine_options bootstrap_options: {
154
+ key_name: 'test_key_pair',
155
+ instance_type: 'm3.medium',
156
+ associate_public_ip_address: true,
157
+ subnet_id: test_public_subnet.aws_object.id,
158
+ security_group_ids: [test_security_group.aws_object.id],
159
+ private_ip_address: "10.0.0.#{private_ip_address_start}"
160
+ }
161
+ action :ready
162
+ end
163
+ }.to create_an_aws_instance("test_machine",
164
+ network_interfaces: [{
165
+ network_interface_id: /^eni-/,
166
+ subnet_id: test_public_subnet.aws_object.id,
167
+ vpc_id: test_vpc.aws_object.id,
168
+ status: "in-use",
169
+ private_ip_address: "10.0.0.#{private_ip_address_start}",
170
+ groups: [{group_name: 'test_security_group'}],
171
+ attachment: {
172
+ device_index: 0,
173
+ delete_on_termination: true,
174
+ status: "attached"
175
+ },
176
+ private_ip_addresses: [
177
+ {
178
+ private_ip_address: "10.0.0.#{private_ip_address_start}",
179
+ primary: true,
180
+ association: {
181
+ public_ip: /\d+/
182
+ }
183
+ }
184
+ ]
185
+ }]
186
+ ).and be_idempotent
187
+ end
188
+
189
+ context "with a placement group" do
190
+ before(:context) {
191
+ driver.ec2_client.create_placement_group({
192
+ group_name: "agroup",
193
+ strategy: "cluster"
194
+ })
195
+ }
196
+
197
+ # Must do after the context so we have waited for the instance to terminate
198
+ after(:context) {
199
+ driver.ec2_client.delete_placement_group group_name: "agroup"
200
+ }
201
+
202
+ it "converts V1 keys to V2 keys", :super_slow do
203
+ expect_recipe {
204
+ machine "test_machine" do
205
+ machine_options bootstrap_options: {
206
+ key_name: 'test_key_pair',
207
+ instance_type: 'm4.large',
208
+ monitoring_enabled: false,
209
+ availability_zone: test_public_subnet.aws_object.availability_zone_name,
210
+ placement_group: "agroup",
211
+ dedicated_tenancy: false, # cannot do true, was getting API error
212
+ subnet: 'test_public_subnet'
213
+ }
214
+ action :allocate
215
+ end
216
+ }.to create_an_aws_instance("test_machine",
217
+ monitoring: {state: "disabled"},
218
+ placement: {
219
+ availability_zone: test_public_subnet.aws_object.availability_zone_name,
220
+ group_name: "agroup",
221
+ tenancy: "default",
222
+ },
223
+ subnet_id: test_public_subnet.aws_object.id
224
+ ).and be_idempotent
225
+ end
226
+ end
227
+
228
+ context "with a custom iam role" do
229
+ # TODO when we have IAM support, use the resources
230
+ before(:context) do
231
+ assume_role_policy_document = '{"Version":"2008-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":["ec2.amazonaws.com"]},"Action":["sts:AssumeRole"]}]}'
232
+ driver.iam_client.create_role({
233
+ role_name: "machine_test_custom_role",
234
+ assume_role_policy_document: assume_role_policy_document
235
+ }).role
236
+ driver.iam_client.create_instance_profile({
237
+ instance_profile_name: "machine_test_custom_role"
238
+ })
239
+ driver.iam_client.add_role_to_instance_profile({
240
+ instance_profile_name: "machine_test_custom_role",
241
+ role_name: "machine_test_custom_role"
242
+ })
243
+ sleep 5 # grrrrrr, the resource should take care of the polling for us
244
+ end
245
+
246
+ after(:context) do
247
+ driver.iam_client.remove_role_from_instance_profile({
248
+ instance_profile_name: "machine_test_custom_role",
249
+ role_name: "machine_test_custom_role"
250
+ })
251
+ driver.iam_client.delete_instance_profile({
252
+ instance_profile_name: "machine_test_custom_role"
253
+ })
254
+ driver.iam_client.delete_role({
255
+ role_name: "machine_test_custom_role"
256
+ })
257
+ end
258
+
259
+ it "converts iam_instance_profile from a string to a hash", :super_slow do
260
+ expect_recipe {
261
+ machine 'test_machine' do
262
+ machine_options bootstrap_options: {
263
+ subnet_id: 'test_public_subnet',
264
+ key_name: 'test_key_pair',
265
+ iam_instance_profile: "machine_test_custom_role"
266
+ }
267
+ action :allocate
268
+ end
269
+ }.to create_an_aws_instance('test_machine',
270
+ iam_instance_profile: {arn: /machine_test_custom_role/}
271
+ ).and be_idempotent
272
+ end
273
+ end
274
+
56
275
  it "machine with from_image option is created from correct image", :super_slow do
57
276
  expect_recipe {
58
277
 
@@ -113,6 +332,48 @@ describe Chef::Resource::Machine do
113
332
  end
114
333
  }.converge }.to_not raise_error
115
334
  end
335
+
336
+ # https://github.com/chef/chef-provisioning-aws/pull/295
337
+ context "with a custom key" do
338
+ let(:private_key) {
339
+ k = OpenSSL::PKey::RSA.new(2048)
340
+ f = Pathname.new(private_key_path)
341
+ f.write(k.to_pem)
342
+ k
343
+ }
344
+ let(:public_key) {private_key.public_key}
345
+ let(:private_key_path) {
346
+ Pathname.new(ENV['HOME']).join(".ssh", key_pair_name).expand_path
347
+ }
348
+ let(:key_pair_name) { "test_key_pair_#{Random.rand(100)}" }
349
+
350
+ before do
351
+ driver.ec2_client.import_key_pair({
352
+ key_name: key_pair_name, # required
353
+ public_key_material: "#{public_key.ssh_type} #{[public_key.to_blob].pack('m0')}", # required
354
+ })
355
+ end
356
+
357
+ after do
358
+ driver.ec2_client.delete_key_pair({
359
+ key_name: key_pair_name, # required
360
+ })
361
+ Pathname.new(private_key_path).delete
362
+ end
363
+
364
+ it "strips key_path from the bootstrap options when creating the machine", :super_slow do
365
+ expect_recipe {
366
+ machine 'test_machine' do
367
+ machine_options bootstrap_options: {
368
+ key_name: key_pair_name,
369
+ key_path: private_key_path
370
+ }
371
+ end
372
+ }.to create_an_aws_instance('test_machine'
373
+ ).and be_idempotent
374
+ end
375
+ end
376
+
116
377
  end
117
378
  end
118
379
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chef-provisioning-aws
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Ewart
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-16 00:00:00.000000000 Z
11
+ date: 2015-09-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chef-provisioning
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.3'
19
+ version: '1.4'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.3'
26
+ version: '1.4'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: aws-sdk-v1
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -233,7 +233,6 @@ files:
233
233
  - lib/chef/resource/aws_subnet.rb
234
234
  - lib/chef/resource/aws_vpc.rb
235
235
  - lib/chef/resource/aws_vpc_peering_connection.rb
236
- - spec/acceptance/aws_ebs_volume/nodes/ettores-mbp.lan.json
237
236
  - spec/aws_support.rb
238
237
  - spec/aws_support/aws_resource_run_wrapper.rb
239
238
  - spec/aws_support/deep_matcher.rb
@@ -290,9 +289,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
290
289
  version: '0'
291
290
  requirements: []
292
291
  rubyforge_project:
293
- rubygems_version: 2.4.5
292
+ rubygems_version: 2.4.7
294
293
  signing_key:
295
294
  specification_version: 4
296
295
  summary: Provisioner for creating aws containers in Chef Provisioning.
297
296
  test_files: []
298
- has_rdoc:
@@ -1,3 +0,0 @@
1
- {
2
- "name": "ettores-mbp.lan"
3
- }