122 lines
4.3 KiB
Python
122 lines
4.3 KiB
Python
from __future__ import print_function
|
|
import os
|
|
import urlparse
|
|
import boto
|
|
import boto.connection
|
|
import boto.jsonresponse
|
|
import boto.exception
|
|
from boto.roboto import awsqueryrequest
|
|
|
|
class NoCredentialsError(boto.exception.BotoClientError):
|
|
|
|
def __init__(self):
|
|
s = 'Unable to find credentials'
|
|
super(NoCredentialsError, self).__init__(s)
|
|
|
|
class AWSQueryService(boto.connection.AWSQueryConnection):
|
|
|
|
Name = ''
|
|
Description = ''
|
|
APIVersion = ''
|
|
Authentication = 'sign-v2'
|
|
Path = '/'
|
|
Port = 443
|
|
Provider = 'aws'
|
|
EnvURL = 'AWS_URL'
|
|
|
|
Regions = []
|
|
|
|
def __init__(self, **args):
|
|
self.args = args
|
|
self.check_for_credential_file()
|
|
self.check_for_env_url()
|
|
if 'host' not in self.args:
|
|
if self.Regions:
|
|
region_name = self.args.get('region_name',
|
|
self.Regions[0]['name'])
|
|
for region in self.Regions:
|
|
if region['name'] == region_name:
|
|
self.args['host'] = region['endpoint']
|
|
if 'path' not in self.args:
|
|
self.args['path'] = self.Path
|
|
if 'port' not in self.args:
|
|
self.args['port'] = self.Port
|
|
try:
|
|
super(AWSQueryService, self).__init__(**self.args)
|
|
self.aws_response = None
|
|
except boto.exception.NoAuthHandlerFound:
|
|
raise NoCredentialsError()
|
|
|
|
def check_for_credential_file(self):
|
|
"""
|
|
Checks for the existence of an AWS credential file.
|
|
If the environment variable AWS_CREDENTIAL_FILE is
|
|
set and points to a file, that file will be read and
|
|
will be searched credentials.
|
|
Note that if credentials have been explicitelypassed
|
|
into the class constructor, those values always take
|
|
precedence.
|
|
"""
|
|
if 'AWS_CREDENTIAL_FILE' in os.environ:
|
|
path = os.environ['AWS_CREDENTIAL_FILE']
|
|
path = os.path.expanduser(path)
|
|
path = os.path.expandvars(path)
|
|
if os.path.isfile(path):
|
|
fp = open(path)
|
|
lines = fp.readlines()
|
|
fp.close()
|
|
for line in lines:
|
|
if line[0] != '#':
|
|
if '=' in line:
|
|
name, value = line.split('=', 1)
|
|
if name.strip() == 'AWSAccessKeyId':
|
|
if 'aws_access_key_id' not in self.args:
|
|
value = value.strip()
|
|
self.args['aws_access_key_id'] = value
|
|
elif name.strip() == 'AWSSecretKey':
|
|
if 'aws_secret_access_key' not in self.args:
|
|
value = value.strip()
|
|
self.args['aws_secret_access_key'] = value
|
|
else:
|
|
print('Warning: unable to read AWS_CREDENTIAL_FILE')
|
|
|
|
def check_for_env_url(self):
|
|
"""
|
|
First checks to see if a url argument was explicitly passed
|
|
in. If so, that will be used. If not, it checks for the
|
|
existence of the environment variable specified in ENV_URL.
|
|
If this is set, it should contain a fully qualified URL to the
|
|
service you want to use.
|
|
Note that any values passed explicitly to the class constructor
|
|
will take precedence.
|
|
"""
|
|
url = self.args.get('url', None)
|
|
if url:
|
|
del self.args['url']
|
|
if not url and self.EnvURL in os.environ:
|
|
url = os.environ[self.EnvURL]
|
|
if url:
|
|
rslt = urlparse.urlparse(url)
|
|
if 'is_secure' not in self.args:
|
|
if rslt.scheme == 'https':
|
|
self.args['is_secure'] = True
|
|
else:
|
|
self.args['is_secure'] = False
|
|
|
|
host = rslt.netloc
|
|
port = None
|
|
l = host.split(':')
|
|
if len(l) > 1:
|
|
host = l[0]
|
|
port = int(l[1])
|
|
if 'host' not in self.args:
|
|
self.args['host'] = host
|
|
if port and 'port' not in self.args:
|
|
self.args['port'] = port
|
|
|
|
if rslt.path and 'path' not in self.args:
|
|
self.args['path'] = rslt.path
|
|
|
|
def _required_auth_capability(self):
|
|
return [self.Authentication]
|
|
|