1
0
Fork 0
mirror of https://github.com/fog/fog.git synced 2022-11-09 13:51:43 -05:00

[aws|sts] Add support for the AssumeRole STS method. Also enable the ability for the STS

service to use IAM profiles to grab credentials off the EC2 instance, as is in place
          for the other AWS services.
This commit is contained in:
Caleb Tennis 2013-07-16 09:23:38 -04:00
parent e6ce26742f
commit d521b84889
4 changed files with 117 additions and 6 deletions

View file

@ -0,0 +1,30 @@
module Fog
module Parsers
module AWS
module STS
class AssumeRole < Fog::Parsers::Base
def reset
@response = {}
end
def end_element(name)
case name
when 'SessionToken', 'SecretAccessKey', 'Expiration', 'AccessKeyId'
@response[name] = @value.strip
when 'Arn', 'AssumedRoleId'
@response[name] = @value.strip
when 'PackedPolicySize'
@response[name] = @value
when 'RequestId'
@response[name] = @value
end
end
end
end
end
end
end

View file

@ -0,0 +1,46 @@
module Fog
module AWS
class STS
class Real
require 'fog/aws/parsers/sts/assume_role'
# Assume Role
#
# ==== Parameters
# * role_session_name<~String> - An identifier for the assumed role.
# * role_arn<~String> - The ARN of the role the caller is assuming.
# * external_id<~String> - An optional unique identifier required by the assuming role's trust identity.
# * policy<~String> - An optional JSON policy document
# * duration<~Integer> - Duration (of seconds) for the assumed role credentials to be valid (default 3600)
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'Arn'<~String>: The ARN of the assumed role/user
# * 'AccessKeyId'<~String>: The AWS access key of the temporary credentials for the assumed role
# * 'SecretAccessKey'<~String>: The AWS secret key of the temporary credentials for the assumed role
# * 'SessionToken'<~String>: The AWS session token of the temporary credentials for the assumed role
# * 'Expiration'<~Time>: The expiration time of the temporary credentials for the assumed role
#
# ==== See Also
# http://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html
#
def assume_role(role_session_name, role_arn, external_id=nil, policy=nil, duration=3600)
request({
'Action' => 'AssumeRole',
'RoleSessionName' => role_session_name,
'RoleArn' => role_arn,
'Policy' => policy && Fog::JSON.encode(policy),
'DurationSeconds' => duration,
'ExternalId' => external_id,
:idempotent => true,
:parser => Fog::Parsers::AWS::STS::AssumeRole.new
})
end
end
end
end
end

View file

@ -3,16 +3,18 @@ require 'fog/aws'
module Fog module Fog
module AWS module AWS
class STS < Fog::Service class STS < Fog::Service
extend Fog::AWS::CredentialFetcher::ServiceMethods
class EntityAlreadyExists < Fog::AWS::STS::Error; end class EntityAlreadyExists < Fog::AWS::STS::Error; end
class ValidationError < Fog::AWS::STS::Error; end class ValidationError < Fog::AWS::STS::Error; end
requires :aws_access_key_id, :aws_secret_access_key requires :aws_access_key_id, :aws_secret_access_key
recognizes :host, :path, :port, :scheme, :persistent recognizes :host, :path, :port, :scheme, :persistent, :aws_session_token, :use_iam_profile, :aws_credentials_expire_at
request_path 'fog/aws/requests/sts' request_path 'fog/aws/requests/sts'
request :get_federation_token request :get_federation_token
request :get_session_token request :get_session_token
request :assume_role
class Mock class Mock
def self.data def self.data
@ -33,7 +35,8 @@ module Fog
end end
def initialize(options={}) def initialize(options={})
@aws_access_key_id = options[:aws_access_key_id] @use_iam_profile = options[:use_iam_profile]
setup_credentials(options)
end end
def data def data
@ -43,10 +46,14 @@ module Fog
def reset_data def reset_data
self.class.data.delete(@aws_access_key_id) self.class.data.delete(@aws_access_key_id)
end end
def setup_credentials(options)
@aws_access_key_id = options[:aws_access_key_id]
end
end end
class Real class Real
include Fog::AWS::CredentialFetcher::ConnectionMethods
# Initialize connection to STS # Initialize connection to STS
# #
# ==== Notes # ==== Notes
@ -67,10 +74,10 @@ module Fog
def initialize(options={}) def initialize(options={})
require 'fog/core/parser' require 'fog/core/parser'
@aws_access_key_id = options[:aws_access_key_id] @use_iam_profile = options[:use_iam_profile]
@aws_secret_access_key = options[:aws_secret_access_key] setup_credentials(options)
@connection_options = options[:connection_options] || {} @connection_options = options[:connection_options] || {}
@hmac = Fog::HMAC.new('sha256', @aws_secret_access_key)
@host = options[:host] || 'sts.amazonaws.com' @host = options[:host] || 'sts.amazonaws.com'
@path = options[:path] || '/' @path = options[:path] || '/'
@persistent = options[:persistent] || false @persistent = options[:persistent] || false
@ -85,6 +92,14 @@ module Fog
private private
def setup_credentials(options)
@aws_access_key_id = options[:aws_access_key_id]
@aws_secret_access_key = options[:aws_secret_access_key]
@aws_session_token = options[:aws_session_token]
@aws_credentials_expire_at = options[:aws_credentials_expire_at]
@hmac = Fog::HMAC.new('sha256', @aws_secret_access_key)
end
def request(params) def request(params)
idempotent = params.delete(:idempotent) idempotent = params.delete(:idempotent)
parser = params.delete(:parser) parser = params.delete(:parser)
@ -93,6 +108,7 @@ module Fog
params, params,
{ {
:aws_access_key_id => @aws_access_key_id, :aws_access_key_id => @aws_access_key_id,
:aws_session_token => @aws_session_token,
:hmac => @hmac, :hmac => @hmac,
:host => @host, :host => @host,
:path => @path, :path => @path,

View file

@ -0,0 +1,19 @@
Shindo.tests('AWS::STS | assume role', ['aws']) do
@policy = {"Statement" => [{"Effect" => "Allow", "Action" => "*", "Resource" => "*"}]}
@response_format = {
'SessionToken' => String,
'SecretAccessKey' => String,
'Expiration' => String,
'AccessKeyId' => String,
'Arn' => String,
'RequestId' => String
}
tests("#assume_role('rolename', 'assumed_role_session', 'external_id', #{@policy.inspect}, 900)").formats(@response_format) do
pending if Fog.mocking?
Fog::AWS[:sts].assume_role("rolename","assumed_role_session","external_id", @policy, 900).body
end
end