Amazon-Credentials
view release on metacpan or search on metacpan
lib/Amazon/Credentials.pm view on Meta::CPAN
package Amazon::Credentials;
use strict;
use warnings;
use parent qw/Class::Accessor Exporter/;
__PACKAGE__->follow_best_practice;
__PACKAGE__->mk_accessors(qw/aws_secret_access_key aws_access_key_id token region
user_agent profile debug expiration role container order
serialized logger
/);
use Data::Dumper;
use Date::Format;
use Exporter;
use HTTP::Request;
use JSON;
use LWP::UserAgent;
use POSIX::strptime qw/strptime/;
lib/Amazon/Credentials.pm view on Meta::CPAN
use constant AWS_IAM_SECURITY_CREDENTIALS_URL => 'http://169.254.169.254/latest/meta-data/iam/security-credentials/';
use constant AWS_AVAILABILITY_ZONE_URL => 'http://169.254.169.254/latest/meta-data/placement/availability-zone';
use constant AWS_CONTAINER_CREDENTIALS_URL => 'http://169.254.170.2';
use vars qw/$VERSION @EXPORT/;
$VERSION = '1.0.10-1'; $VERSION=~s/\-.*$//;
@EXPORT = qw/$VERSION/;
# we only log at debug level, create a default logger
{
no strict 'refs';
*{'Amazon::Credentials::Logger::debug'} = sub {
shift;
my @tm = localtime(time);
print STDERR sprintf("%s [%s] %s", strftime("%c", @tm), $$, @_);
};
}
=pod
=head1 NAME
lib/Amazon/Credentials.pm view on Meta::CPAN
to determine the order in which the class will look for credentials.
The default order is I<environent>, I<file>, I<container>, I<instance
meta-data>. See L</new>.
=head1 METHODS
=head2 new
new( options );
my $aws_creds = new Amazon::Credential( { profile => 'sandbox', debug => 1 });
C<options> is a hash of keys that represent options. Any of the
options can also be retrieved using their corresponding 'get_{option}
method.
Options are listed below.
=over 5
=item aws_access_key_id
AWS access key.
=item aws_secret_access_key
AWS secret access key.
I<Note: If you pass the access keys in the constructor then the
constructor will not look in other places for credentials.>
=item debug
Set to true for verbose troubleshooting information.
=item logger
Pass in your own logger that has a C<debug()> method. Otherwise the
default logger will output debug messages to STDERR.
=item user_agent
Pass in your own user agent, otherwise LWP will be used. I<Probably
only useful to override this for testing purposes.>
=item profile
The profile name in the configuration file (F<~/.aws/config> or
F<~/.aws/credentials>).
lib/Amazon/Credentials.pm view on Meta::CPAN
$creds->{aws_access_key_id} = $1;
}
elsif (/^\s*aws_session_token\s*=\s*(.*)$/) {
last if defined $creds->{token};
$creds->{token} = $1;
}
}
close $fh;
$self->get_logger->debug(Dumper [ $creds ])
if $self->get_debug;
$creds->{source} = $config if $creds->{aws_secret_access_key} && $creds->{aws_access_key_id};
}
last if $creds->{source};
};
}
foreach ( keys %$creds) {
$self->set($_, $creds->{$_});
lib/Amazon/Credentials.pm view on Meta::CPAN
if ( defined $expiration_date ) {
# AWS recommends getting credentials 5 minutes prior to expiration
my $g = _iso8601_to_time($expiration_date);
# shave 5 minutes or window interval off of the expiration time
$g -= $window_interval * 60;
# (expiration_time - window_interval) - current_time = # of seconds left before expiration
my $seconds_left = $g - time;
if ( $self->get_debug ) {
my $hours = int($seconds_left/3600);
my $minutes = int(($seconds_left - $hours * 3600)/60);
my $seconds = $seconds_left - ($hours * 3600 + $minutes * 60);
$self->get_logger->debug(sprintf("%d hours %d minutes %d seconds until expiry\n", $hours, $minutes, $seconds));
}
$expired = ($seconds_left < 0) ? 1 : 0;
$self->get_logger->debug(Dumper [ "EXPIRATION TIME: " . $expiration_date, "EXPIRED: " . $expired])
if $self->get_debug;
}
return $expired;
}
sub _iso8601_to_time {
my $iso8601 = shift;
$iso8601 =~s/^(.*)Z$/$1\+00:00/;
lib/Amazon/Credentials.pm view on Meta::CPAN
eval {
# could be infinite, but I don't think so. Either we get an
# error ($@), or a non-200 response code
while ( ! $creds->{token} ) {
$url .= $role if $role;
my $req = HTTP::Request->new( GET => $url );
$self->get_logger->debug(Dumper [ "HTTP REQUEST:\n", $req ])
if $self->get_debug;
my $rsp = $ua->request($req);
$self->get_logger->debug(Dumper [ "HTTP RESPONSE:\n", $rsp ])
if $self->get_debug;
# if not 200, then get out of Dodge
last unless $rsp->is_success;
if ( $role ) {
$creds->{serialized} = $rsp->content;
my $this = from_json($creds->{serialized});
@{$creds}{qw/source role aws_access_key_id aws_secret_access_key token expiration/} =
('IAM',$role, @{$this}{qw/AccessKeyId SecretAccessKey Token Expiration/});
}
else {
$role = $rsp->content;
$self->get_logger->debug(Dumper ['role', $role])
if $self->get_debug;
last unless $role;
}
}
};
$creds->{error} = $@ if $@;
$creds;
}
lib/Amazon/Credentials.pm view on Meta::CPAN
my $self = shift;
my $creds;
if ( $self->get_role && $self->get_role eq 'ECS' ) {
$creds = $self->get_creds_from_container;
}
elsif ( $self->get_role ) {
$creds = $self->get_creds_from_role;
}
$self->get_logger->debug(Dumper [$creds])
if $self->get_debug;
die "unable to refresh token!"
unless ref($creds);
$self->set_credentials($creds);
}
sub get_creds_from_container {
my $self = shift;
lib/Amazon/Credentials.pm view on Meta::CPAN
my $creds = {};
if ( exists $ENV{AWS_CONTAINER_CREDENTIALS_RELATIVE_URI} ) {
# try to get credentials from instance role
my $url = sprintf("%s%s", AWS_CONTAINER_CREDENTIALS_URL, $ENV{AWS_CONTAINER_CREDENTIALS_RELATIVE_URI});
my $ua = $self->get_user_agent;
my $req = HTTP::Request->new( GET => $url );
$req->header("Accept", "*/*");
$self->get_logger->debug(Dumper [ "HTTP REQUEST:\n", $req ])
if $self->get_debug;
$self->get_logger->debug(Dumper [ $req->as_string ])
if $self->get_debug;
my $rsp = $ua->request($req);
$self->get_logger->debug(Dumper [ "HTTP RESPONSE:\n", $rsp ])
if $self->get_debug;
# if not 200, then get out of Dodge
if ( $rsp->is_success ) {
$creds->{serialized} = $rsp->content;
my $this = from_json($rsp->content);
@{$creds}{qw/source container aws_access_key_id aws_secret_access_key token expiration/} =
('IAM','ECS', @{$this}{qw/AccessKeyId SecretAccessKey Token Expiration/});
}
else {
$self->get_logger->debug( "return code: " . $rsp->status_line . "\n");
}
$creds->{error} = $@ if $@;
}
$creds;
}
=pod
t/02-credentials.t view on Meta::CPAN
aws_access_key_id=bar-aws-access-key-id
aws_secret_access_key=bar-aws-secret-access-key
eot
close $fh;
"$home/.aws/credentials";
};
$ENV{HOME} = "$home";
$ENV{AWS_PROFILE} = undef;
my $creds = new Amazon::Credentials({ order => [qw/file/], debug => $ENV{DEBUG} ? 1 : 0 });
ok(ref($creds), 'find credentials');
my %new_creds = (
aws_access_key_id => 'biz-aws-access-key-id',
aws_secret_access_key => 'biz-aws-secret-access-key',
token => 'biz',
expiration => time2str("%Y-%m-%dT%H:%M:%SZ", time + -5 + (5 * 60), "GMT")
);
$creds->set_credentials(\%new_creds);
( run in 0.249 second using v1.01-cache-2.11-cpan-3cd7ad12f66 )