Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add explicit option for using iam profile for authentication #107

Merged
merged 14 commits into from
Apr 10, 2015
Merged
15 changes: 8 additions & 7 deletions lib/kitchen/driver/ec2.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ module Driver
#
# @author Fletcher Nichol <[email protected]>
class Ec2 < Kitchen::Driver::SSHBase

extend Fog::AWS::CredentialFetcher::ServiceMethods
default_config :region, 'us-east-1'
default_config :availability_zone, 'us-east-1b'
Expand All @@ -41,14 +40,16 @@ class Ec2 < Kitchen::Driver::SSHBase
default_config :private_ip_address, nil
default_config :iam_profile_name, nil
default_config :price, nil
default_config :use_iam_profile, false
default_config :aws_access_key_id do |driver|
ENV['AWS_ACCESS_KEY'] || ENV['AWS_ACCESS_KEY_ID'] || iam_creds[:aws_access_key_id]
ENV['AWS_ACCESS_KEY'] || ENV['AWS_ACCESS_KEY_ID'] || driver.iam_creds[:aws_access_key_id]
end
default_config :aws_secret_access_key do |driver|
ENV['AWS_SECRET_KEY'] || ENV['AWS_SECRET_ACCESS_KEY'] || iam_creds[:aws_secret_access_key]
ENV['AWS_SECRET_KEY'] || ENV['AWS_SECRET_ACCESS_KEY'] \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to break this across multiple lines you don't need the \ - just leave the || at the end of the line

|| driver.iam_creds[:aws_secret_access_key]
end
default_config :aws_session_token do |driver|
ENV['AWS_SESSION_TOKEN'] || ENV['AWS_TOKEN'] || iam_creds[:aws_session_token]
ENV['AWS_SESSION_TOKEN'] || ENV['AWS_TOKEN'] || driver.iam_creds[:aws_session_token]
end
default_config :aws_ssh_key_id do |driver|
ENV['AWS_SSH_KEY_ID']
Expand Down Expand Up @@ -98,10 +99,10 @@ class Ec2 < Kitchen::Driver::SSHBase
end
end

def self.iam_creds
def iam_creds
@iam_creds ||= begin
fetch_credentials(use_iam_profile:true)
rescue RuntimeError => e
config[:use_iam_profile] ? fetch_credentials(use_iam_profile: true) : {}
rescue RuntimeError, NoMethodError => e
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where do you expect the NoMethodError to come from?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fetch_credentials calls super when it fails, so since we don't have a super for it to fail over to we need to catch NoMethodError, I think I made a note in the commit message.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still have the same question about NoMethodError - why is it needed? After including the ServiceMethods, you shouldn't ever encounter a NoMethodError. Or am I missing something?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NM, I was able to reproduce the error from https://github.com/test-kitchen/kitchen-ec2/pull/104/files locally and I see why you have the NoMethodError check

debug("fetch_credentials failed with exception #{e.message}:#{e.backtrace.join("\n")}")
{}
end
Expand Down
31 changes: 31 additions & 0 deletions spec/create_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,37 @@

end

describe '#iam_creds' do
context 'when use_iam_profile is not set' do
it 'returns an empty hash' do
expect(driver.iam_creds).to eq({})
end
end

context 'when use_iam_profile is set to true' do
let(:credentials) do
{
aws_access_key_id: 'secret',
aws_secret_access_key: 'moarsecret',
aws_session_token: 'randomsecret'
}
end

it 'calls fetch_credentials' do
config[:use_iam_profile] = true

allow(driver)
.to receive(:fetch_credentials).and_return(credentials)

expect(driver)
.to receive(:fetch_credentials)
.with(use_iam_profile: true)

expect(driver.iam_creds).to eq(credentials)
end
end
end

describe '#block_device_mappings' do
let(:connection) { double(Fog::Compute) }
let(:image) { double('Image', :root_device_name => 'name') }
Expand Down