Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 24 additions & 12 deletions S3/Config.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,18 +261,19 @@ class Config(object):
max_retries = 5

## Creating a singleton
def __new__(self, configfile = None, access_key=None, secret_key=None, access_token=None):
def __new__(self, configfile = None, access_key=None, secret_key=None, access_token=None, profile=None):
if self._instance is None:
self._instance = object.__new__(self)
return self._instance

def __init__(self, configfile = None, access_key=None, secret_key=None, access_token=None):
def __init__(self, configfile = None, access_key=None, secret_key=None, access_token=None, profile=None):
if configfile:
debug("Config: Initializing with config file '%s', profile '%s'" % (configfile, profile))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Except this one, you can probably get ride of the other debug logs that I don't think are necessary once you will have a working code.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, removed all other newly created debug lines.

try:
self.read_config_file(configfile)
self.read_config_file(configfile, profile)
except IOError:
if 'AWS_SHARED_CREDENTIALS_FILE' in os.environ or 'AWS_CREDENTIAL_FILE' in os.environ or 'AWS_PROFILE' in os.environ:
self.aws_credential_file()
self.aws_credential_file(profile)

# override these if passed on the command-line
# Allow blank secret_key
Expand Down Expand Up @@ -335,7 +336,7 @@ def role_config(self):
'%s=%s' % (k, s3_quote(v, unicode_output=True))
for k, v in params.items()
])
sts_endpoint = os.environ.get("AWS_STS_ENDPOINT", sts_endpoint)
sts_endpoint = os.environ.get("AWS_STS_ENDPOINT", sts_endpoint)
if os.environ.get("AWS_STS_REGIONAL_ENDPOINTS") == "regional":
# Check if the AWS_REGION variable is available to use as a region.
region = os.environ.get("AWS_REGION")
Expand Down Expand Up @@ -441,7 +442,7 @@ def role_refresh(self):
except Exception:
warning("Could not refresh role")

def aws_credential_file(self):
def aws_credential_file(self, profile=None):
try:
aws_credential_file = os.path.expanduser('~/.aws/credentials')
credential_file_from_env = os.environ.get('AWS_SHARED_CREDENTIALS_FILE') \
Expand Down Expand Up @@ -482,7 +483,8 @@ def aws_credential_file(self):
"Error reading aws_credential_file "
"(%s): %s" % (aws_credential_file, str(exc)))

profile = base_unicodise(os.environ.get('AWS_PROFILE', "default"))
if profile is None:
profile = base_unicodise(os.environ.get('AWS_PROFILE', "default"))
debug("Using AWS profile '%s'" % (profile))

# get_key - helper function to read the aws profile credentials
Expand Down Expand Up @@ -559,8 +561,14 @@ def option_list(self):
retval.append(option)
return retval

def read_config_file(self, configfile):
cp = ConfigParser(configfile)
def read_config_file(self, configfile, profile=None):
if profile is None:
profile = os.environ.get('AWS_PROFILE', 'default')

cp = ConfigParser(configfile, ["default"])
if profile and profile != "default":
cp.parse_file(configfile, [profile])

for option in self.option_list():
_option = cp.get(option)
if _option is not None:
Expand Down Expand Up @@ -655,7 +663,8 @@ def parse_file(self, file, sections = []):
debug("ConfigParser: Reading file '%s'" % file)
if type(sections) != type([]):
sections = [sections]
in_our_section = True
in_our_section = not sections # If no sections specified, read all
current_section = "default"
r_comment = re.compile(r'^\s*#.*')
r_empty = re.compile(r'^\s*$')
r_section = re.compile(r'^\[([^\]]+)\]')
Expand All @@ -667,8 +676,8 @@ def parse_file(self, file, sections = []):
continue
is_section = r_section.match(line)
if is_section:
section = is_section.groups()[0]
in_our_section = (section in sections) or (len(sections) == 0)
current_section = is_section.groups()[0]
in_our_section = (current_section in sections) or (not sections)
continue
is_data = r_data.match(line)
if is_data and in_our_section:
Expand All @@ -682,6 +691,9 @@ def parse_file(self, file, sections = []):
print_value = data["value"]
debug("ConfigParser: %s->%s" % (data["key"], print_value))
continue
if is_data and not in_our_section:
# Skip data in sections we're not interested in
continue
warning("Ignoring invalid line in '%s': %s" % (file, line))

def __getitem__(self, name):
Expand Down
3 changes: 2 additions & 1 deletion s3cmd
Original file line number Diff line number Diff line change
Expand Up @@ -3158,6 +3158,7 @@ def main():
optparser.add_option( "--access_key", dest="access_key", help="AWS Access Key")
optparser.add_option( "--secret_key", dest="secret_key", help="AWS Secret Key")
optparser.add_option( "--access_token", dest="access_token", help="AWS Access Token")
optparser.add_option( "--profile", dest="profile", metavar="PROFILE", help="Profile to use from .s3cfg file")

optparser.add_option("-n", "--dry-run", dest="dry_run", action="store_true", help="Only show what should be uploaded or downloaded but don't actually do it. May still perform S3 requests to get bucket listings and other information though (only for file transfer commands)")

Expand Down Expand Up @@ -3316,7 +3317,7 @@ def main():
sys.exit(EX_CONFIG)

try:
cfg = Config(options.config, options.access_key, options.secret_key, options.access_token)
cfg = Config(options.config, options.access_key, options.secret_key, options.access_token, options.profile)
except ValueError as exc:
raise ParameterError(unicode(exc))
except IOError as e:
Expand Down