File Coverage

lib/VM/EC2/Security/CredentialCache.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package VM::EC2::Security::CredentialCache;
2             $VM::EC2::Security::CredentialCache::VERSION = '0.21';
3 1     1   1174 use strict;
  1         1  
  1         35  
4 1     1   5 use warnings;
  1         2  
  1         40  
5 1     1   194 use DateTime::Format::ISO8601;
  0            
  0            
6             use VM::EC2::Instance::Metadata;
7              
8             =head1 NAME
9              
10             VM::EC2::Security::CredentialCache -- Cache credentials respecting expriation time for IAM roles.
11              
12             =head1 SYNOPSIS
13              
14             Retrieves the current EC2 instance's IAM credentials and caches them until they expire.
15              
16             use VM::EC2::Security::CredentialCache;
17              
18             # return a VM::EC2::Security::Credentials if avaiable undef otherwise.
19             my $credentials = VM::EC2::Security::CredentialCache->get();
20              
21             =head1 DESCRIPTION
22              
23             This module provides a cache for an EC2's IAM credentials represented by L.
24             Rather than retriving the credentials for every possible call that uses them, cache them until they
25             expire and retreive them again if they have expired.
26              
27             =cut
28              
29             my $credentials;
30             my $credential_expiration_dt;
31              
32             sub get {
33             my ($self, $now) = @_;
34             if (!defined($credentials)) {
35             my $meta = VM::EC2::Instance::Metadata->new;
36             defined($meta) || die("Unable to retrieve instance metadata");
37             $credentials= $meta->iam_credentials;
38             defined($credentials) || die("No IAM credentials retrieved from instance metadata");
39             $credential_expiration_dt = DateTime::Format::ISO8601->parse_datetime($credentials->expiration())->epoch();
40             return $credentials;
41             }
42              
43             # AWS provides new credentials atleast 5 minutes before the expiration of the old
44             # credentials, but we'll only start looking at 4 minutes
45             $now //= time;
46             if ($credential_expiration_dt - $now > 240) {
47             return $credentials;
48             }
49            
50             # These credentials are good for only 4 minutes or less, so clear them and attempt to
51             # retrieve new credentials.
52             $credentials = undef;
53             $credential_expiration_dt = undef;
54             return get();
55             }
56              
57             1;