lib/cfer/cfn/cfer_credentials_provider.rb
require 'yaml'
module Cfer
module Cfn
class CferCredentialsProvider < Aws::SharedCredentials
private
def load_from_path
profile = load_profile
credentials = Aws::Credentials.new(
profile['aws_access_key_id'],
profile['aws_secret_access_key'],
profile['aws_session_token']
)
@credentials =
if role_arn = profile['role_arn']
role_creds =
begin
YAML::load_file('.cfer-role')
rescue
{}
end
if stored_creds = role_creds[profile_name]
if (Time.now.to_i + 5 * 60) > stored_creds[:expiration].to_i
stored_creds = nil
end
end
if stored_creds == nil
role_credentials_options = {
role_session_name: [*('A'..'Z')].sample(16).join,
role_arn: role_arn,
credentials: credentials
}
if profile['mfa_serial']
role_credentials_options[:serial_number] ||= profile['mfa_serial']
role_credentials_options[:token_code] ||= HighLine.new($stdin, $stderr).ask('Enter MFA Code:')
end
creds = Aws::AssumeRoleCredentials.new(role_credentials_options)
stored_creds = {
expiration: creds.expiration,
credentials: creds.credentials
}
role_creds[profile_name] = stored_creds
end
IO.write('.cfer-role', YAML.dump(role_creds))
stored_creds[:credentials]
else
credentials
end
end
def load_profile
if profile = profiles[profile_name]
# Add all options from source profile
if source = profile.delete('source_profile')
profiles[source].merge(profile)
else
profile
end
else
msg = "Profile `#{profile_name}' not found in #{path}"
raise Aws::Errors::NoSuchProfileError, msg
end
end
end
end
end