Skip to content

Commit 7fa55ae

Browse files
authored
Merge pull request #2621 from anibalsolon/enh/aws_credentials
ENH: S3 access using instance role
2 parents ad506f2 + 5abe1c9 commit 7fa55ae

File tree

1 file changed

+48
-29
lines changed

1 file changed

+48
-29
lines changed

nipype/interfaces/io.py

Lines changed: 48 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,35 @@ def add_traits(base, names, trait_type=None):
123123
return base
124124

125125

126+
def _get_head_bucket(s3_resource, bucket_name):
127+
""" Try to get the header info of a bucket, in order to
128+
check if it exists and its permissions
129+
"""
130+
131+
import botocore
132+
133+
# Try fetch the bucket with the name argument
134+
try:
135+
s3_resource.meta.client.head_bucket(Bucket=bucket_name)
136+
except botocore.exceptions.ClientError as exc:
137+
error_code = int(exc.response['Error']['Code'])
138+
if error_code == 403:
139+
err_msg = 'Access to bucket: %s is denied; check credentials'\
140+
% bucket_name
141+
raise Exception(err_msg)
142+
elif error_code == 404:
143+
err_msg = 'Bucket: %s does not exist; check spelling and try '\
144+
'again' % bucket_name
145+
raise Exception(err_msg)
146+
else:
147+
err_msg = 'Unable to connect to bucket: %s. Error message:\n%s'\
148+
% (bucket_name, exc)
149+
except Exception as exc:
150+
err_msg = 'Unable to connect to bucket: %s. Error message:\n%s'\
151+
% (bucket_name, exc)
152+
raise Exception(err_msg)
153+
154+
126155
class IOBase(BaseInterface):
127156
def _run_interface(self, runtime):
128157
return runtime
@@ -535,43 +564,35 @@ def _fetch_bucket(self, bucket_name):
535564
session = boto3.session.Session(
536565
aws_access_key_id=aws_access_key_id,
537566
aws_secret_access_key=aws_secret_access_key)
538-
s3_resource = session.resource('s3', use_ssl=True)
539567

540-
# Otherwise, connect anonymously
541568
else:
542-
iflogger.info('Connecting to AWS: %s anonymously...', bucket_name)
569+
iflogger.info('Connecting to S3 bucket: %s with IAM role...',
570+
bucket_name)
571+
572+
# Lean on AWS environment / IAM role authentication and authorization
543573
session = boto3.session.Session()
544-
s3_resource = session.resource('s3', use_ssl=True)
545-
s3_resource.meta.client.meta.events.register(
546-
'choose-signer.s3.*', botocore.handlers.disable_signing)
547574

548-
# Explicitly declare a secure SSL connection for bucket object
549-
bucket = s3_resource.Bucket(bucket_name)
575+
s3_resource = session.resource('s3', use_ssl=True)
550576

551577
# And try fetch the bucket with the name argument
552578
try:
553-
s3_resource.meta.client.head_bucket(Bucket=bucket_name)
554-
except botocore.exceptions.ClientError as exc:
555-
error_code = int(exc.response['Error']['Code'])
556-
if error_code == 403:
557-
err_msg = 'Access to bucket: %s is denied; check credentials'\
558-
% bucket_name
559-
raise Exception(err_msg)
560-
elif error_code == 404:
561-
err_msg = 'Bucket: %s does not exist; check spelling and try '\
562-
'again' % bucket_name
563-
raise Exception(err_msg)
564-
else:
565-
err_msg = 'Unable to connect to bucket: %s. Error message:\n%s'\
566-
% (bucket_name, exc)
579+
_get_head_bucket(s3_resource, bucket_name)
567580
except Exception as exc:
568-
err_msg = 'Unable to connect to bucket: %s. Error message:\n%s'\
569-
% (bucket_name, exc)
570-
raise Exception(err_msg)
581+
582+
# Try to connect anonymously
583+
s3_resource.meta.client.meta.events.register(
584+
'choose-signer.s3.*', botocore.handlers.disable_signing)
585+
586+
iflogger.info('Connecting to AWS: %s anonymously...', bucket_name)
587+
_get_head_bucket(s3_resource, bucket_name)
588+
589+
# Explicitly declare a secure SSL connection for bucket object
590+
bucket = s3_resource.Bucket(bucket_name)
571591

572592
# Return the bucket
573593
return bucket
574594

595+
575596
# Send up to S3 method
576597
def _upload_to_s3(self, bucket, src, dst):
577598
'''
@@ -590,10 +611,8 @@ def _upload_to_s3(self, bucket, src, dst):
590611
s3_prefix = s3_str + bucket.name
591612

592613
# Explicitly lower-case the "s3"
593-
if dst.lower().startswith(s3_str):
594-
dst_sp = dst.split('/')
595-
dst_sp[0] = dst_sp[0].lower()
596-
dst = '/'.join(dst_sp)
614+
if dst[:len(s3_str)].lower() == s3_str:
615+
dst = s3_str + dst[len(s3_str):]
597616

598617
# If src is a directory, collect files (this assumes dst is a dir too)
599618
if os.path.isdir(src):

0 commit comments

Comments
 (0)