-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow IAM username suffix to be added to S3 scratch URL #69
Merged
Merged
Changes from 14 commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
8fda70b
Pass scratch_s3_url to BaseCreds constructors
vinceatbluelabs 9f7a4f0
Move fetching of scratch_s3_url to BaseCreds
vinceatbluelabs 8395d01
Move S3 bucket inference to BaseCreds; standardize on PleaseInfer
vinceatbluelabs 9273c34
Initial code to append IAM username to bucket URL
vinceatbluelabs c64ac95
Switch to a different config entry name
vinceatbluelabs a894902
Increase test coverage
vinceatbluelabs 8504d2a
TODONE
vinceatbluelabs afae21b
Handle assumed roles
vinceatbluelabs ae2c4d0
Allow one line slip in setup.py for comment
vinceatbluelabs 880ae7c
Let's go with PleaseInfer
vinceatbluelabs caa6672
Fix flake8 issues
vinceatbluelabs a804428
Fix reference in integration tests
vinceatbluelabs 4a9d0d8
Extract out method; rename from user_id to username
vinceatbluelabs 891445d
Merge remote-tracking branch 'origin/master' into scratch_s3_url_in_c…
vinceatbluelabs 1d3d839
Fix text wrapping
vinceatbluelabs 3f8e3f1
Document group scratch bucket
vinceatbluelabs 4ff3c6f
Merge remote-tracking branch 'origin/master' into scratch_s3_url_in_c…
vinceatbluelabs File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
981 | ||
982 | ||
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 +1 @@ | ||
94.0400 | ||
94.0500 |
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 +1 @@ | ||
92.2700 | ||
92.2800 |
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,7 +1,9 @@ | ||
from db_facts.db_facts_types import DBFacts | ||
from .database import db_facts_from_env | ||
from typing import TYPE_CHECKING, Iterable, Union, Optional | ||
from records_mover.mover_types import NotYetFetched | ||
from records_mover.mover_types import PleaseInfer | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I standardized on the latter here; the difference in semantics was so subtle as to be meaningless for the uses here. |
||
from config_resolver import get_config | ||
import os | ||
import logging | ||
if TYPE_CHECKING: | ||
# see the 'gsheets' extras_require option in setup.py - needed for this! | ||
|
@@ -31,16 +33,19 @@ def __init__(self, | |
default_db_creds_name: Optional[str] = None, | ||
default_aws_creds_name: Optional[str] = None, | ||
default_gcp_creds_name: Optional[str] = None, | ||
default_db_facts: Union[NotYetFetched, DBFacts] = NotYetFetched.token, | ||
default_boto3_session: Union[NotYetFetched, | ||
default_db_facts: Union[PleaseInfer, DBFacts] = PleaseInfer.token, | ||
default_boto3_session: Union[PleaseInfer, | ||
'boto3.session.Session', | ||
None] = NotYetFetched.token, | ||
default_gcp_creds: Union[NotYetFetched, | ||
None] = PleaseInfer.token, | ||
default_gcp_creds: Union[PleaseInfer, | ||
'google.auth.credentials.Credentials', | ||
None] = NotYetFetched.token, | ||
default_gcs_client: Union[NotYetFetched, | ||
None] = PleaseInfer.token, | ||
default_gcs_client: Union[PleaseInfer, | ||
'google.cloud.storage.Client', | ||
None] = NotYetFetched.token) -> None: | ||
None] = PleaseInfer.token, | ||
scratch_s3_url: Union[PleaseInfer, | ||
str, | ||
None] = PleaseInfer.token) -> None: | ||
self._default_db_creds_name = default_db_creds_name | ||
self._default_aws_creds_name = default_aws_creds_name | ||
self._default_gcp_creds_name = default_gcp_creds_name | ||
|
@@ -50,6 +55,8 @@ def __init__(self, | |
self.__default_gcs_client = default_gcs_client | ||
self.__default_boto3_session = default_boto3_session | ||
|
||
self._scratch_s3_url = scratch_s3_url | ||
|
||
def google_sheets(self, gcp_creds_name: str) -> 'google.auth.credentials.Credentials': | ||
scopes = ('https://www.googleapis.com/auth/spreadsheets',) | ||
return self._gcp_creds(gcp_creds_name, scopes) | ||
|
@@ -71,7 +78,7 @@ def boto3_session(self, aws_creds_name: str) -> 'boto3.session.Session': | |
raise NotImplementedError | ||
|
||
def default_boto3_session(self) -> Optional['boto3.session.Session']: | ||
if self.__default_boto3_session is not NotYetFetched.token: | ||
if self.__default_boto3_session is not PleaseInfer.token: | ||
return self.__default_boto3_session | ||
|
||
try: | ||
|
@@ -88,7 +95,7 @@ def default_boto3_session(self) -> Optional['boto3.session.Session']: | |
return self.__default_boto3_session | ||
|
||
def default_gcs_creds(self) -> Optional['google.auth.credentials.Credentials']: | ||
if self.__default_gcs_creds is not NotYetFetched.token: | ||
if self.__default_gcs_creds is not PleaseInfer.token: | ||
return self.__default_gcs_creds | ||
|
||
try: | ||
|
@@ -113,7 +120,7 @@ def default_gcs_creds(self) -> Optional['google.auth.credentials.Credentials']: | |
return self.__default_gcs_creds | ||
|
||
def default_gcs_client(self) -> Optional['google.cloud.storage.Client']: | ||
if self.__default_gcs_client is not NotYetFetched.token: | ||
if self.__default_gcs_client is not PleaseInfer.token: | ||
return self.__default_gcs_client | ||
|
||
gcs_creds = self.default_gcs_creds() | ||
|
@@ -140,11 +147,62 @@ def default_gcs_client(self) -> Optional['google.cloud.storage.Client']: | |
return self.__default_gcs_client | ||
|
||
def default_db_facts(self) -> DBFacts: | ||
if self.__default_db_facts is not NotYetFetched.token: | ||
if self.__default_db_facts is not PleaseInfer.token: | ||
return self.__default_db_facts | ||
|
||
if self._default_db_creds_name is None: | ||
self.__default_db_facts = db_facts_from_env() | ||
else: | ||
self.__default_db_facts = self.db_facts(self._default_db_creds_name) | ||
return self.__default_db_facts | ||
|
||
def _append_aws_username_to_bucket(self, | ||
prefix: str, | ||
boto3_session: 'boto3.session.Session') -> Optional[str]: | ||
sts_client = boto3_session.client('sts') | ||
caller_identity = sts_client.get_caller_identity() | ||
arn = caller_identity['Arn'] | ||
last_section_of_arn = arn.split(':')[-1] | ||
# Check that this is an actual user and not, say, | ||
# an assumed role or something else. | ||
if last_section_of_arn.startswith('user/'): | ||
username = last_section_of_arn.split('/')[-1] | ||
return f"{prefix}{username}/" | ||
else: | ||
logger.warning('Cannot generate S3 scratch URL with IAM username, ' | ||
f'as there is no username in {arn}') | ||
return None | ||
|
||
def _infer_scratch_s3_url(self, | ||
boto3_session: Optional['boto3.session.Session']) -> Optional[str]: | ||
if "SCRATCH_S3_URL" in os.environ: | ||
return os.environ["SCRATCH_S3_URL"] | ||
|
||
config_result = get_config('records_mover', 'bluelabs') | ||
cfg = config_result.config | ||
if 'aws' in cfg: | ||
aws_cfg = cfg['aws'] | ||
s3_scratch_url: Optional[str] = aws_cfg.get('s3_scratch_url') | ||
if s3_scratch_url is not None: | ||
return s3_scratch_url | ||
else: | ||
s3_scratch_url_prefix: Optional[str] =\ | ||
aws_cfg.get('s3_scratch_url_appended_with_iam_username') | ||
if s3_scratch_url_prefix is not None: | ||
if boto3_session is None: | ||
logger.warning('Cannot generate S3 scratch URL with IAM username, ' | ||
'as I have no IAM username') | ||
return None | ||
return self._append_aws_username_to_bucket(s3_scratch_url_prefix, | ||
boto3_session) | ||
else: | ||
logger.debug('No S3 scratch bucket config found') | ||
return None | ||
else: | ||
logger.debug('No config ini file found') | ||
return None | ||
|
||
def default_scratch_s3_url(self) -> Optional[str]: | ||
if self._scratch_s3_url is PleaseInfer.token: | ||
self._scratch_s3_url = self._infer_scratch_s3_url(self.default_boto3_session()) | ||
return self._scratch_s3_url |
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
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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a comment to setup.py to explain a new version constraint.