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; |