forked from wal-e/wal-e
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for AWS IAM Instance Profiles
By using the command line option --aws-instance-profile, WAL-E can request and use credentials from the instance metadata. This option has high precedence and is mutually exclusive with assigning one's own AWS credentials. Editorialized by Daniel Farina <[email protected]>
- Loading branch information
Showing
5 changed files
with
122 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import pytest | ||
|
||
import boto | ||
import boto.provider | ||
from boto import utils | ||
|
||
from wal_e.blobstore.s3 import s3_credentials | ||
|
||
META_DATA_CREDENTIALS = { | ||
"Code": "Success", | ||
"LastUpdated": "2014-01-11T02:13:53Z", | ||
"Type": "AWS-HMAC", | ||
"AccessKeyId": None, | ||
"SecretAccessKey": None, | ||
"Token": None, | ||
"Expiration": "2014-01-11T08:16:59Z" | ||
} | ||
|
||
|
||
def boto_flat_metadata(): | ||
return tuple(int(x) for x in boto.__version__.split('.')) >= (2, 9, 0) | ||
|
||
|
||
@pytest.fixture() | ||
def metadata(monkeypatch): | ||
m = dict(**META_DATA_CREDENTIALS) | ||
m['AccessKeyId'] = 'foo' | ||
m['SecretAccessKey'] = 'bar' | ||
m['Token'] = 'baz' | ||
monkeypatch.setattr(boto.provider.Provider, | ||
'_credentials_need_refresh', | ||
lambda self: False) | ||
if boto_flat_metadata(): | ||
m = {'irrelevant': m} | ||
else: | ||
m = {'iam': {'security-credentials': {'irrelevant': m}}} | ||
monkeypatch.setattr(utils, 'get_instance_metadata', | ||
lambda *args, **kwargs: m) | ||
|
||
|
||
def test_profile_provider(metadata): | ||
ipp = s3_credentials.InstanceProfileCredentials() | ||
assert ipp.get_access_key() == 'foo' | ||
assert ipp.get_secret_key() == 'bar' | ||
assert ipp.get_security_token() == 'baz' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,33 @@ | ||
from boto import provider | ||
from functools import partial | ||
from wal_e.exception import UserException | ||
|
||
|
||
class InstanceProfileProvider(provider.Provider): | ||
"""Override boto Provider to control use of the AWS metadata store | ||
In particular, prevent boto from looking in a series of places for | ||
keys outside off WAL-E's control (e.g. boto.cfg, environment | ||
variables, and so on). As-is that precedence and detection code | ||
is in one big ream, and so a method override and some internal | ||
symbols are used to excise most of that cleverness. | ||
Also take this opportunity to inject a WAL-E-friendly exception to | ||
help the user with missing keys. | ||
""" | ||
|
||
def get_credentials(self, access_key=None, secret_key=None, | ||
security_token=None): | ||
if self.MetadataServiceSupport[self.name]: | ||
self._populate_keys_from_metadata_server() | ||
|
||
if not self._secret_key: | ||
raise UserException('Could not retrieve secret key from instance ' | ||
'profile.', | ||
hint='Check that your instance has an IAM ' | ||
'profile or set --aws-access-key-id') | ||
|
||
|
||
Credentials = partial(provider.Provider, "aws") | ||
InstanceProfileCredentials = partial(InstanceProfileProvider, 'aws') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters