File Coverage

lib/VM/EC2/Security/CredentialCache.pm
Criterion Covered Total %
statement 12 26 46.1
branch 0 8 0.0
condition 0 3 0.0
subroutine 4 5 80.0
pod 0 1 0.0
total 16 43 37.2


line stmt bran cond sub pod time code
1             package VM::EC2::Security::CredentialCache;
2             $VM::EC2::Security::CredentialCache::VERSION = '0.25';
3 1     1   468 use strict;
  1         1  
  1         50  
4 1     1   5 use warnings;
  1         2  
  1         56  
5 1     1   747 use DateTime::Format::ISO8601;
  1         193849  
  1         38  
6 1     1   980 use VM::EC2::Instance::Metadata;
  1         45054  
  1         157  
7              
8             =head1 NAME
9              
10             VM::EC2::Security::CredentialCache -- Cache credentials respecting expiration 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 available 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 0     0 0   my ($self, $now) = @_;
34 0 0         if (!defined($credentials)) {
35 0           my $meta = VM::EC2::Instance::Metadata->new;
36 0 0         defined($meta) || die("Unable to retrieve instance metadata");
37 0           $credentials= $meta->iam_credentials;
38 0 0         defined($credentials) || die("No IAM credentials retrieved from instance metadata");
39 0           $credential_expiration_dt = DateTime::Format::ISO8601->parse_datetime($credentials->expiration())->epoch();
40 0           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 0   0       $now //= time;
46 0 0         if ($credential_expiration_dt - $now > 240) {
47 0           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 0           $credentials = undef;
53 0           $credential_expiration_dt = undef;
54 0           return get();
55             }
56              
57             1;