1from __future__ import print_function 2import os 3import urlparse 4import boto 5import boto.connection 6import boto.jsonresponse 7import boto.exception 8from boto.roboto import awsqueryrequest 9 10class NoCredentialsError(boto.exception.BotoClientError): 11 12 def __init__(self): 13 s = 'Unable to find credentials' 14 super(NoCredentialsError, self).__init__(s) 15 16class AWSQueryService(boto.connection.AWSQueryConnection): 17 18 Name = '' 19 Description = '' 20 APIVersion = '' 21 Authentication = 'sign-v2' 22 Path = '/' 23 Port = 443 24 Provider = 'aws' 25 EnvURL = 'AWS_URL' 26 27 Regions = [] 28 29 def __init__(self, **args): 30 self.args = args 31 self.check_for_credential_file() 32 self.check_for_env_url() 33 if 'host' not in self.args: 34 if self.Regions: 35 region_name = self.args.get('region_name', 36 self.Regions[0]['name']) 37 for region in self.Regions: 38 if region['name'] == region_name: 39 self.args['host'] = region['endpoint'] 40 if 'path' not in self.args: 41 self.args['path'] = self.Path 42 if 'port' not in self.args: 43 self.args['port'] = self.Port 44 try: 45 super(AWSQueryService, self).__init__(**self.args) 46 self.aws_response = None 47 except boto.exception.NoAuthHandlerFound: 48 raise NoCredentialsError() 49 50 def check_for_credential_file(self): 51 """ 52 Checks for the existence of an AWS credential file. 53 If the environment variable AWS_CREDENTIAL_FILE is 54 set and points to a file, that file will be read and 55 will be searched credentials. 56 Note that if credentials have been explicitelypassed 57 into the class constructor, those values always take 58 precedence. 59 """ 60 if 'AWS_CREDENTIAL_FILE' in os.environ: 61 path = os.environ['AWS_CREDENTIAL_FILE'] 62 path = os.path.expanduser(path) 63 path = os.path.expandvars(path) 64 if os.path.isfile(path): 65 fp = open(path) 66 lines = fp.readlines() 67 fp.close() 68 for line in lines: 69 if line[0] != '#': 70 if '=' in line: 71 name, value = line.split('=', 1) 72 if name.strip() == 'AWSAccessKeyId': 73 if 'aws_access_key_id' not in self.args: 74 value = value.strip() 75 self.args['aws_access_key_id'] = value 76 elif name.strip() == 'AWSSecretKey': 77 if 'aws_secret_access_key' not in self.args: 78 value = value.strip() 79 self.args['aws_secret_access_key'] = value 80 else: 81 print('Warning: unable to read AWS_CREDENTIAL_FILE') 82 83 def check_for_env_url(self): 84 """ 85 First checks to see if a url argument was explicitly passed 86 in. If so, that will be used. If not, it checks for the 87 existence of the environment variable specified in ENV_URL. 88 If this is set, it should contain a fully qualified URL to the 89 service you want to use. 90 Note that any values passed explicitly to the class constructor 91 will take precedence. 92 """ 93 url = self.args.get('url', None) 94 if url: 95 del self.args['url'] 96 if not url and self.EnvURL in os.environ: 97 url = os.environ[self.EnvURL] 98 if url: 99 rslt = urlparse.urlparse(url) 100 if 'is_secure' not in self.args: 101 if rslt.scheme == 'https': 102 self.args['is_secure'] = True 103 else: 104 self.args['is_secure'] = False 105 106 host = rslt.netloc 107 port = None 108 l = host.split(':') 109 if len(l) > 1: 110 host = l[0] 111 port = int(l[1]) 112 if 'host' not in self.args: 113 self.args['host'] = host 114 if port and 'port' not in self.args: 115 self.args['port'] = port 116 117 if rslt.path and 'path' not in self.args: 118 self.args['path'] = rslt.path 119 120 def _required_auth_capability(self): 121 return [self.Authentication] 122 123