From 40637a93cb6f48708c50eca2806c43321f21c054 Mon Sep 17 00:00:00 2001 From: tyler-ball Date: Fri, 22 May 2015 11:27:14 -0700 Subject: [PATCH 1/2] AWS expects user data to be base64 encoded, fixes https://github.com/test-kitchen/kitchen-ec2/issues/121 --- lib/kitchen/driver/aws/instance_generator.rb | 8 +++++--- spec/kitchen/driver/ec2/instance_generator_spec.rb | 10 ++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/kitchen/driver/aws/instance_generator.rb b/lib/kitchen/driver/aws/instance_generator.rb index d792b284..7e374ebd 100644 --- a/lib/kitchen/driver/aws/instance_generator.rb +++ b/lib/kitchen/driver/aws/instance_generator.rb @@ -17,6 +17,7 @@ # limitations under the License. require "kitchen/logging" +require "base64" module Kitchen @@ -134,14 +135,15 @@ def debug_if_root_device(bdms) def prepared_user_data # If user_data is a file reference, lets read it as such - unless @user_data - if config[:user_data] && File.file?(config[:user_data]) + return nil if config[:user_data].nil? + @user_data ||= begin + if File.file?(config[:user_data]) @user_data = File.read(config[:user_data]) else @user_data = config[:user_data] end + @user_data = Base64.encode64(@user_data) end - @user_data end end diff --git a/spec/kitchen/driver/ec2/instance_generator_spec.rb b/spec/kitchen/driver/ec2/instance_generator_spec.rb index 05cd4e12..f66304c0 100644 --- a/spec/kitchen/driver/ec2/instance_generator_spec.rb +++ b/spec/kitchen/driver/ec2/instance_generator_spec.rb @@ -19,6 +19,7 @@ require "kitchen/driver/aws/instance_generator" require "kitchen/driver/aws/client" require "tempfile" +require "base64" describe Kitchen::Driver::Aws::InstanceGenerator do @@ -70,14 +71,15 @@ end it "reads the file contents" do - expect(generator.prepared_user_data).to eq("foo\nbar") + expect(Base64.decode64(generator.prepared_user_data)).to eq("foo\nbar") end it "memoizes the file contents" do - expect(generator.prepared_user_data).to eq("foo\nbar") + decoded = Base64.decode64(generator.prepared_user_data) + expect(decoded).to eq("foo\nbar") tmp_file.write("other\nvalue") tmp_file.rewind - expect(generator.prepared_user_data).to eq("foo\nbar") + expect(decoded).to eq("foo\nbar") end end end @@ -339,7 +341,7 @@ :subnet_id => "s-456" }], :security_group_ids => ["sg-789"], - :user_data => "foo" + :user_data => Base64.encode64("foo") ) end end From ee9668542e1d02f5e9833fdd9692166678b665c0 Mon Sep 17 00:00:00 2001 From: tyler-ball Date: Fri, 22 May 2015 13:54:28 -0700 Subject: [PATCH 2/2] subnets, security_groups and private_ip needs to be provided in the network_interfaces when network_interfaces is present, fixes https://github.com/test-kitchen/kitchen-ec2/issues/127 --- lib/kitchen/driver/aws/instance_generator.rb | 14 ++- .../driver/ec2/instance_generator_spec.rb | 92 ++++++++++++++++++- 2 files changed, 99 insertions(+), 7 deletions(-) diff --git a/lib/kitchen/driver/aws/instance_generator.rb b/lib/kitchen/driver/aws/instance_generator.rb index 7e374ebd..3fe22da6 100644 --- a/lib/kitchen/driver/aws/instance_generator.rb +++ b/lib/kitchen/driver/aws/instance_generator.rb @@ -63,13 +63,21 @@ def ec2_instance_data # rubocop:disable Metrics/MethodLength, Metrics/AbcSize i[:network_interfaces] = [{ :device_index => 0, - :associate_public_ip_address => config[:associate_public_ip] + :associate_public_ip_address => config[:associate_public_ip], + :delete_on_termination => true }] - # If specifying `:network_interfaces` in the request, you must specify the - # subnet_id in the network_interfaces block and not at the top level + # If specifying `:network_interfaces` in the request, you must specify + # network specific configs in the network_interfaces block and not at + # the top level if config[:subnet_id] i[:network_interfaces][0][:subnet_id] = i.delete(:subnet_id) end + if config[:private_ip_address] + i[:network_interfaces][0][:private_ip_address] = i.delete(:private_ip_address) + end + if config[:security_group_ids] + i[:network_interfaces][0][:groups] = i.delete(:security_group_ids) + end end i end diff --git a/spec/kitchen/driver/ec2/instance_generator_spec.rb b/spec/kitchen/driver/ec2/instance_generator_spec.rb index f66304c0..bf3da4dd 100644 --- a/spec/kitchen/driver/ec2/instance_generator_spec.rb +++ b/spec/kitchen/driver/ec2/instance_generator_spec.rb @@ -282,9 +282,92 @@ :key_name => nil, :subnet_id => nil, :private_ip_address => nil, - :network_interfaces => [{ :device_index => 0, :associate_public_ip_address => true }] + :network_interfaces => [{ + :device_index => 0, + :associate_public_ip_address => true, + :delete_on_termination => true + }] ) end + + context "and subnet is provided" do + let(:config) do + { + :associate_public_ip => true, + :subnet_id => "s-456" + } + end + + it "adds a network_interfaces block" do + expect(generator.ec2_instance_data).to eq( + :placement => { :availability_zone => nil }, + :instance_type => nil, + :ebs_optimized => nil, + :image_id => nil, + :key_name => nil, + :private_ip_address => nil, + :network_interfaces => [{ + :device_index => 0, + :associate_public_ip_address => true, + :delete_on_termination => true, + :subnet_id => "s-456" + }] + ) + end + end + + context "and security_group_ids is provided" do + let(:config) do + { + :associate_public_ip => true, + :security_group_ids => ["sg-789"] + } + end + + it "adds a network_interfaces block" do + expect(generator.ec2_instance_data).to eq( + :placement => { :availability_zone => nil }, + :instance_type => nil, + :ebs_optimized => nil, + :image_id => nil, + :key_name => nil, + :subnet_id => nil, + :private_ip_address => nil, + :network_interfaces => [{ + :device_index => 0, + :associate_public_ip_address => true, + :delete_on_termination => true, + :groups => ["sg-789"] + }] + ) + end + end + + context "and private_ip_address is provided" do + let(:config) do + { + :associate_public_ip => true, + :private_ip_address => "0.0.0.0" + } + end + + it "adds a network_interfaces block" do + expect(generator.ec2_instance_data).to eq( + :placement => { :availability_zone => nil }, + :instance_type => nil, + :ebs_optimized => nil, + :image_id => nil, + :key_name => nil, + :subnet_id => nil, + :network_interfaces => [{ + :device_index => 0, + :associate_public_ip_address => true, + :delete_on_termination => true, + :private_ip_address => "0.0.0.0" + }] + ) + end + end end context "when provided the maximum config" do @@ -321,7 +404,6 @@ :ebs_optimized => true, :image_id => "ami-123", :key_name => "key", - :private_ip_address => "0.0.0.0", :block_device_mappings => [ { :ebs => { @@ -338,9 +420,11 @@ :network_interfaces => [{ :device_index => 0, :associate_public_ip_address => true, - :subnet_id => "s-456" + :subnet_id => "s-456", + :delete_on_termination => true, + :groups => ["sg-789"], + :private_ip_address => "0.0.0.0" }], - :security_group_ids => ["sg-789"], :user_data => Base64.encode64("foo") ) end