File Coverage

blib/lib/Paws/Credential/ECSContainerProfile.pm
Criterion Covered Total %
statement 41 41 100.0
branch 7 10 70.0
condition n/a
subroutine 10 10 100.0
pod 0 3 0.0
total 58 64 90.6


line stmt bran cond sub pod time code
1             package Paws::Credential::ECSContainerProfile;
2 1     1   1010 use JSON::MaybeXS;
  1         2  
  1         81  
3 1     1   8 use Moose;
  1         2  
  1         8  
4 1     1   6802 use DateTime::Format::ISO8601;
  1         3  
  1         33  
5 1     1   452 use URI;
  1         3552  
  1         137  
6             with 'Paws::Credential';
7              
8             has container_local_uri => (
9             is => 'ro',
10             isa => 'Str|Undef',
11             default => sub {
12             $ENV{ AWS_CONTAINER_CREDENTIALS_RELATIVE_URI }
13             }
14             );
15              
16             has metadata_url => (
17             is => 'ro',
18             isa => 'Str|Undef',
19             lazy => 1,
20             default => sub {
21             my $self = shift;
22             return undef if (not defined $self->container_local_uri);
23             my $url = URI->new("http://169.254.170.2");
24             $url->path($self->container_local_uri);
25             return $url->as_string;
26             }
27             );
28              
29             has timeout => (is => 'ro', isa => 'Int', default => 1);
30              
31             has ua => (
32             is => 'ro',
33             lazy => 1,
34             default => sub {
35             my $self = shift;
36 1     1   6 use HTTP::Tiny;
  1         3  
  1         292  
37             HTTP::Tiny->new(
38             agent => 'AWS Perl SDK',
39             timeout => $self->timeout,
40             );
41             }
42             );
43              
44             has expiration => (
45             is => 'rw',
46             isa => 'Int',
47             default => sub { 0 }
48             );
49              
50             has actual_creds => (is => 'rw', default => sub { {} });
51              
52             around are_set => sub {
53             my ($orig, $self) = @_;
54             return 0 if (not defined $self->container_local_uri);
55             return $self->$orig;
56             };
57              
58             sub access_key {
59 3     3 0 96 my $self = shift;
60 3         15 $self->_refresh;
61 2         57 $self->actual_creds->{AccessKeyId};
62             }
63              
64             sub secret_key {
65 2     2 0 5 my $self = shift;
66 2         6 $self->_refresh;
67 2         51 $self->actual_creds->{SecretAccessKey};
68             }
69              
70             sub session_token {
71 2     2 0 5 my $self = shift;
72 2         5 $self->_refresh;
73 2         50 $self->actual_creds->{Token};
74             }
75              
76             #TODO: Raise exceptions if HTTP get didn't return success
77             sub _refresh {
78 7     7   13 my $self = shift;
79              
80 7 100       318 return if $self->expiration >= time;
81 3 50       84 return if ! $self->metadata_url;
82              
83 3         80 my $ua = $self->ua;
84 3         8 $DB::single=1;
85              
86 3         76 my $r = $ua->get($self->metadata_url);
87 3 50       2858 return unless $r->{success};
88 3 50       9 return unless $r->{content};
89              
90 3         7 my $json = eval { decode_json($r->{content}) };
  3         51  
91 3 100       10 if ($@) { die "Error in JSON from metadata URL" }
  1         12  
92              
93 2         68 $self->actual_creds($json);
94 2         53 $self->expiration(DateTime::Format::ISO8601->parse_datetime($json->{Expiration})->epoch);
95             }
96              
97 1     1   7 no Moose;
  1         2  
  1         7  
98             1;
99             ### main pod documentation begin ###
100              
101             =encoding UTF-8
102              
103             =head1 NAME
104              
105             Paws::Credential::ECSContainerProfile
106              
107             =head1 SYNOPSIS
108              
109             use Paws::Credential::ECSContainerProfile;
110              
111             my $paws = Paws->new(config => {
112             credentials => Paws::Credential::ECSContainerProfile->new(
113             metadata_url => 'http://localhost:8000/security-credentials',
114             timeout => 5,
115             )
116             });
117              
118             =head1 DESCRIPTION
119              
120             The InstanceProfile credential provider is used to call retrieve AWS credentials from conatiners running on AWS ECS
121              
122             When running in an ECS Container on AWS, if said container has a Role attached to it, Paws
123             can retrieve short-term credentials (and refresh them when needed) from the AWS provided "metadata service".
124              
125             =head2 metadata_url: Str
126              
127             The url where credentials will be retrieved. Defaults to documented endpoint for container profile retrieval. Should not
128             normally need to be overriden.
129              
130             =head2 timetout: Int
131              
132             Number of seconds to wait before timinig out a connection to the metadata service. It defaults to 1 second, as
133             the metadata service is almost local, and very fast responding. Note that if set too high, and the metadata
134             service is not present (not running on an AWS instance), the connection has to time out
135              
136             =head2 ua
137              
138             A user agent that has a C<get> method. Defaults to HTTP::Tiny
139              
140             =cut