Skip to content

Commit 6ef32c7

Browse files
committed
Refactored provider creds discovery to be more DRY, added alternate AWS vars.
1 parent 3a2841e commit 6ef32c7

2 files changed

Lines changed: 59 additions & 93 deletions

File tree

client/deis.py

Lines changed: 58 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,37 @@ def dictify(args):
262262
return data
263263

264264

265+
def get_provider_creds(provider, raise_error=False):
266+
"""Query environment variables and return a provider's creds if found.
267+
"""
268+
cred_types = {
269+
'ec2': [[('AWS_ACCESS_KEY_ID', 'access_key', None),
270+
('AWS_SECRET_ACCESS_KEY', 'secret_key', None)],
271+
[('AWS_ACCESS_KEY', 'access_key', None),
272+
('AWS_SECRET_KEY', 'secret_key', None)]],
273+
'rackspace': [[('RACKSPACE_USERNAME', 'username', None),
274+
('RACKSPACE_API_KEY', 'api_key', None),
275+
('CLOUD_ID_TYPE', 'identity_type', 'rackspace')]],
276+
'digitalocean': [[('DIGITALOCEAN_CLIENT_ID', 'client_id', None),
277+
('DIGITALOCEAN_API_KEY', 'api_key', None)]]
278+
}
279+
missing = None
280+
for cred_set in cred_types[provider]:
281+
creds = {}
282+
for envvar, key, default in cred_set:
283+
val = os.environ.get(envvar, default)
284+
if not val:
285+
missing = envvar
286+
break
287+
else:
288+
creds[key] = val
289+
if creds:
290+
return creds
291+
if raise_error:
292+
raise EnvironmentError(
293+
"Missing environment variable: {}".format(missing))
294+
295+
265296
def trim(docstring):
266297
"""
267298
Function to trim whitespace from docstring
@@ -1331,7 +1362,7 @@ def layers_destroy(self, args):
13311362
Usage: deis layers:destroy <formation> <id>
13321363
"""
13331364
formation = args.get('<formation>')
1334-
layer = args['<id>'] # noqa
1365+
layer = args['<id>']
13351366
sys.stdout.write("Destroying {layer} layer... ".format(**locals()))
13361367
sys.stdout.flush()
13371368
try:
@@ -1397,7 +1428,7 @@ def layers_update(self, args):
13971428
13981429
"""
13991430
formation = args.get('<formation>')
1400-
layer = args['<id>'] # noqa
1431+
layer = args['<id>']
14011432
body = {'id': args['<id>']}
14021433
for opt in ('--ssh_username', '--ssh_private_key', '--ssh_public_key',
14031434
'--ssh_port'):
@@ -1644,37 +1675,9 @@ def providers_create(self, args):
16441675
16451676
Usage: deis providers:create <id> <type> <creds>
16461677
"""
1647-
# TODO: This function has a McCabe of 13. Refactor for simplicity.
16481678
type = args.get('<type>') # @ReservedAssignment
1649-
if type == 'ec2':
1650-
# read creds from envvars
1651-
for k in ('AWS_ACCESS_KEY', 'AWS_SECRET_KEY'):
1652-
if not k in os.environ:
1653-
msg = "Missing environment variable: {}".format(k)
1654-
raise EnvironmentError(msg)
1655-
creds = {
1656-
'access_key': os.environ['AWS_ACCESS_KEY'],
1657-
'secret_key': os.environ['AWS_SECRET_KEY'],
1658-
}
1659-
elif type == 'rackspace':
1660-
# read creds from envvars
1661-
for k in ('RACKSPACE_USERNAME', 'RACKSPACE_API_KEY'):
1662-
if not k in os.environ:
1663-
msg = "Missing environment variable: {}".format(k)
1664-
raise EnvironmentError(msg)
1665-
creds = {
1666-
'username': os.environ['RACKSPACE_USERNAME'],
1667-
'api_key': os.environ['RACKSPACE_API_KEY'],
1668-
'identity_type': os.environ.get('CLOUD_ID_TYPE', 'rackspace'),
1669-
}
1670-
elif type == 'digitalocean':
1671-
# read creds from envvars
1672-
for k in ('DIGITALOCEAN_CLIENT_ID', 'DIGITALOCEAN_API_KEY'):
1673-
if not k in os.environ:
1674-
msg = "Missing environment variable: {}".format(k)
1675-
raise EnvironmentError(msg)
1676-
creds = {'client_id': os.environ['DIGITALOCEAN_CLIENT_ID'],
1677-
'api_key': os.environ['DIGITALOCEAN_API_KEY']}
1679+
if type in ['ec2', 'rackspace', 'digitalocean']:
1680+
creds = get_provider_creds(type, raise_error=True)
16781681
else:
16791682
creds = json.loads(args.get('<creds>'))
16801683
id = args.get('<id>') # @ReservedAssignment
@@ -1700,68 +1703,31 @@ def providers_discover(self, args):
17001703
17011704
Usage: deis providers:discover
17021705
"""
1703-
# look for ec2 credentials
1704-
if 'AWS_ACCESS_KEY' in os.environ and 'AWS_SECRET_KEY' in os.environ:
1705-
print("Found EC2 credentials: {}".format(os.environ['AWS_ACCESS_KEY']))
1706-
inp = raw_input('Import these credentials? (y/n) : ')
1707-
if inp.lower().strip('\n') != 'y':
1708-
print('Aborting.')
1709-
else:
1710-
creds = {'access_key': os.environ['AWS_ACCESS_KEY'],
1711-
'secret_key': os.environ['AWS_SECRET_KEY']}
1712-
body = {'creds': json.dumps(creds)}
1713-
sys.stdout.write('Uploading EC2 credentials... ')
1714-
sys.stdout.flush()
1715-
response = self._dispatch('patch', '/api/providers/ec2',
1716-
json.dumps(body))
1717-
if response.status_code == requests.codes.ok: # @UndefinedVariable
1718-
print('done')
1706+
provider_data = [
1707+
# Provider, human-redable provider name, sample field to display
1708+
('ec2', 'EC2', 'access_key'),
1709+
('rackspace', 'Rackspace', 'api_key'),
1710+
('digitalocean', 'DigitalOcean', 'api_key'),
1711+
]
1712+
for provider, name, field in provider_data:
1713+
creds = get_provider_creds(provider)
1714+
if creds:
1715+
print ("Found {} credentials: {}".format(name, creds[field]))
1716+
inp = raw_input('Import these credentials? (y/n) : ')
1717+
if inp.lower().strip('\n') != 'y':
1718+
print('Aborting.')
17191719
else:
1720-
raise ResponseError(response)
1721-
else:
1722-
print('No EC2 credentials discovered. Did you install the EC2 Command Line tools?')
1723-
if 'RACKSPACE_API_KEY' in os.environ and 'RACKSPACE_USERNAME' in os.environ:
1724-
print("Found Rackspace credentials: {}".format(os.environ['RACKSPACE_API_KEY']))
1725-
inp = raw_input('Import these credentials? (y/n) : ')
1726-
if inp.lower().strip('\n') != 'y':
1727-
print('Aborting.')
1728-
else:
1729-
creds = {'username': os.environ['RACKSPACE_USERNAME'],
1730-
'api_key': os.environ['RACKSPACE_API_KEY'],
1731-
'identity_type': os.environ.get('CLOUD_ID_TYPE', 'rackspace')}
1732-
body = {'creds': json.dumps(creds)}
1733-
sys.stdout.write('Uploading Rackspace credentials... ')
1734-
sys.stdout.flush()
1735-
response = self._dispatch('patch', '/api/providers/rackspace',
1736-
json.dumps(body))
1737-
if response.status_code == requests.codes.ok: # @UndefinedVariable
1738-
print('done')
1739-
else:
1740-
raise ResponseError(response)
1741-
else:
1742-
print('No Rackspace credentials discovered.')
1743-
if 'DIGITALOCEAN_API_KEY' in os.environ and 'DIGITALOCEAN_CLIENT_ID' in os.environ:
1744-
print("Found Digitalocean credentials: {}".format(
1745-
os.environ['DIGITALOCEAN_CLIENT_ID']))
1746-
inp = raw_input('Import these credentials? (y/n) : ')
1747-
if inp.lower().strip('\n') != 'y':
1748-
print('Aborting.')
1720+
body = {'creds': json.dumps(creds)}
1721+
sys.stdout.write("Uploading {} credentials... ".format(provider))
1722+
sys.stdout.flush()
1723+
endpoint = "/api/providers/{}".format(provider)
1724+
response = self._dispatch('patch', endpoint, json.dumps(body))
1725+
if response.status_code == requests.codes.ok: # @UndefinedVariable
1726+
print('done')
1727+
else:
1728+
raise ResponseError(response)
17491729
else:
1750-
creds = {
1751-
'client_id': os.environ['DIGITALOCEAN_CLIENT_ID'],
1752-
'api_key': os.environ['DIGITALOCEAN_API_KEY'],
1753-
}
1754-
body = {'creds': json.dumps(creds)}
1755-
sys.stdout.write('Uploading Digitalocean credentials... ')
1756-
sys.stdout.flush()
1757-
response = self._dispatch('patch', 'api/providers/digitalocean',
1758-
json.dumps(body))
1759-
if response.status_code == requests.codes.ok: # @UndefinedVariable
1760-
print('done')
1761-
else:
1762-
raise ResponseError(response)
1763-
else:
1764-
print('No Digitalocean credentials discovered.')
1730+
print("No {} credentials discovered.".format(provider))
17651731

17661732
def providers_info(self, args):
17671733
"""

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
[flake8]
22
max-line-length = 99
33
exclude = */api/migrations/*,*/build/*,*/venv/*,*/virtualenv/*
4-
max-complexity = 14
4+
max-complexity = 12

0 commit comments

Comments
 (0)