Skip to content
This repository has been archived by the owner on May 10, 2024. It is now read-only.

Commit

Permalink
Merge branch 'release-2.9.9'
Browse files Browse the repository at this point in the history
* release-2.9.9: (39 commits)
  Bumping version to 2.9.9
  Added release notes for v2.9.9.
  Revert "Added "lookup" and "new_item" to dynamodb2.table, which makes it more"
  Updated Opsworks for support AMI ID & configuration managers.
  Add unit tests for #1555 to ensure behavior works as expected
  Added a try block around json.loads call, and code to look for 403 errors
  Fix compatibility issues with python 2.5
  Set secure connection to elb api as default, as for any other connection
  Reformat SES unit tests for PEP8
  using from clause to import TestCase
  Changing to unittest2 Changing call  to super for setUp
  pep8 standards
  Adding unit test for detach_internet_gateway
  Fix for Issue#1417
  add unit tests for InstanceGroup instantation
  don't require the price to be a string, and then report 'must be specified' if I pass a float.
  Updated erroneous test.
  Updated a test to match current autoscale output.
  Fixed up BotoServerException's use of message
  Fixed the ability to specify ``logging`` on ``DistributionConfig``.
  ...
  • Loading branch information
toastdriven committed Jul 24, 2013
2 parents 3c56d13 + 35617d8 commit 15c650e
Show file tree
Hide file tree
Showing 37 changed files with 1,345 additions and 241 deletions.
4 changes: 2 additions & 2 deletions README.rst
Original file line number Original file line Diff line number Diff line change
@@ -1,9 +1,9 @@
#### ####
boto boto
#### ####
boto 2.9.8 boto 2.9.9


Released: 18-July-2013 Released: 24-July-2013


.. image:: https://travis-ci.org/boto/boto.png?branch=develop .. image:: https://travis-ci.org/boto/boto.png?branch=develop
:target: https://travis-ci.org/boto/boto :target: https://travis-ci.org/boto/boto
Expand Down
2 changes: 1 addition & 1 deletion boto/__init__.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
import urlparse import urlparse
from boto.exception import InvalidUriError from boto.exception import InvalidUriError


__version__ = '2.9.8' __version__ = '2.9.9'
Version = __version__ # for backware compatibility Version = __version__ # for backware compatibility


UserAgent = 'Boto/%s (%s)' % (__version__, sys.platform) UserAgent = 'Boto/%s (%s)' % (__version__, sys.platform)
Expand Down
5 changes: 3 additions & 2 deletions boto/auth.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -385,8 +385,9 @@ def signed_headers(self, headers_to_sign):


def canonical_uri(self, http_request): def canonical_uri(self, http_request):
path = http_request.auth_path path = http_request.auth_path
# Normalize the path. # Normalize the path
normalized = posixpath.normpath(path) # in windows normpath('/') will be '\\' so we chane it back to '/'
normalized = posixpath.normpath(path).replace('\\','/')
# Then urlencode whatever's left. # Then urlencode whatever's left.
encoded = urllib.quote(normalized) encoded = urllib.quote(normalized)
if len(path) > 1 and path.endswith('/'): if len(path) > 1 and path.endswith('/'):
Expand Down
5 changes: 4 additions & 1 deletion boto/cloudformation/stack.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ def endElement(self, name, value, connection):
elif name == "Description": elif name == "Description":
self.description = value self.description = value
elif name == "DisableRollback": elif name == "DisableRollback":
self.disable_rollback = bool(value) if str(value).lower() == 'true':
self.disable_rollback = True
else:
self.disable_rollback = False
elif name == 'StackId': elif name == 'StackId':
self.stack_id = value self.stack_id = value
elif name == 'StackName': elif name == 'StackName':
Expand Down
22 changes: 12 additions & 10 deletions boto/cloudfront/distribution.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
from boto.cloudfront.origin import S3Origin, CustomOrigin from boto.cloudfront.origin import S3Origin, CustomOrigin
from boto.s3.acl import ACL from boto.s3.acl import ACL


class DistributionConfig: class DistributionConfig(object):


def __init__(self, connection=None, origin=None, enabled=False, def __init__(self, connection=None, origin=None, enabled=False,
caller_reference='', cnames=None, comment='', caller_reference='', cnames=None, comment='',
Expand Down Expand Up @@ -100,7 +100,7 @@ def __init__(self, connection=None, origin=None, enabled=False,
self.cnames = cnames self.cnames = cnames
self.comment = comment self.comment = comment
self.trusted_signers = trusted_signers self.trusted_signers = trusted_signers
self.logging = None self.logging = logging
self.default_root_object = default_root_object self.default_root_object = default_root_object


def to_xml(self): def to_xml(self):
Expand Down Expand Up @@ -214,7 +214,7 @@ def to_xml(self):
s += '</StreamingDistributionConfig>\n' s += '</StreamingDistributionConfig>\n'
return s return s


class DistributionSummary: class DistributionSummary(object):


def __init__(self, connection=None, domain_name='', id='', def __init__(self, connection=None, domain_name='', id='',
last_modified_time=None, status='', origin=None, last_modified_time=None, status='', origin=None,
Expand Down Expand Up @@ -279,7 +279,7 @@ class StreamingDistributionSummary(DistributionSummary):
def get_distribution(self): def get_distribution(self):
return self.connection.get_streaming_distribution_info(self.id) return self.connection.get_streaming_distribution_info(self.id)


class Distribution: class Distribution(object):


def __init__(self, connection=None, config=None, domain_name='', def __init__(self, connection=None, config=None, domain_name='',
id='', last_modified_time=None, status=''): id='', last_modified_time=None, status=''):
Expand Down Expand Up @@ -654,12 +654,14 @@ def _sign_string(message, private_key_file=None, private_key_string=None):
raise ValueError("Only specify the private_key_file or the private_key_string not both") raise ValueError("Only specify the private_key_file or the private_key_string not both")
if not private_key_file and not private_key_string: if not private_key_file and not private_key_string:
raise ValueError("You must specify one of private_key_file or private_key_string") raise ValueError("You must specify one of private_key_file or private_key_string")
# If private_key_file is a file, read its contents. Otherwise, open it and then read it # If private_key_file is a file name, open it and read it
if isinstance(private_key_file, file): if private_key_string is None:
private_key_string = private_key_file.read() if isinstance(private_key_file, basestring):
elif private_key_file: with open(private_key_file, 'r') as file_handle:
with open(private_key_file, 'r') as file_handle: private_key_string = file_handle.read()
private_key_string = file_handle.read() # Otherwise, treat it like a file
else:
private_key_string = private_key_file.read()


# Sign it! # Sign it!
private_key = rsa.PrivateKey.load_pkcs1(private_key_string) private_key = rsa.PrivateKey.load_pkcs1(private_key_string)
Expand Down
14 changes: 13 additions & 1 deletion boto/cloudsearch/search.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -289,7 +289,19 @@ def __call__(self, query):
params = query.to_params() params = query.to_params()


r = requests.get(url, params=params) r = requests.get(url, params=params)
data = json.loads(r.content) try:
data = json.loads(r.content)
except json.JSONDecodeError,e:
if r.status_code == 403:
msg = ''
import re
g = re.search('<html><body><h1>403 Forbidden</h1>([^<]+)<', r.content)
try:
msg = ': %s' % (g.groups()[0].strip())
except AttributeError:
pass
raise SearchServiceException('Authentication error from Amazon%s' % msg)
raise SearchServiceException("Got non-json response from Amazon")
data['query'] = query data['query'] = query
data['search_service'] = self data['search_service'] = self


Expand Down
23 changes: 21 additions & 2 deletions boto/connection.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -673,6 +673,8 @@ def handle_proxy(self, proxy, proxy_port, proxy_user, proxy_pass):
print "http_proxy environment variable does not specify " \ print "http_proxy environment variable does not specify " \
"a port, using default" "a port, using default"
self.proxy_port = self.port self.proxy_port = self.port

self.no_proxy = os.environ.get('no_proxy', '') or os.environ.get('NO_PROXY', '')
self.use_proxy = (self.proxy != None) self.use_proxy = (self.proxy != None)


def get_http_connection(self, host, is_secure): def get_http_connection(self, host, is_secure):
Expand All @@ -682,16 +684,33 @@ def get_http_connection(self, host, is_secure):
else: else:
return self.new_http_connection(host, is_secure) return self.new_http_connection(host, is_secure)


def skip_proxy(self, host):
if not self.no_proxy:
return False

if self.no_proxy == "*":
return True

hostonly = host
hostonly = host.split(':')[0]

for name in self.no_proxy.split(','):
if name and (hostonly.endswith(name) or host.endswith(name)):
return True

return False

def new_http_connection(self, host, is_secure): def new_http_connection(self, host, is_secure):
if self.use_proxy and not is_secure: if self.use_proxy and not is_secure and \
not self.skip_proxy(host):
host = '%s:%d' % (self.proxy, int(self.proxy_port)) host = '%s:%d' % (self.proxy, int(self.proxy_port))
if host is None: if host is None:
host = self.server_name() host = self.server_name()
if is_secure: if is_secure:
boto.log.debug( boto.log.debug(
'establishing HTTPS connection: host=%s, kwargs=%s', 'establishing HTTPS connection: host=%s, kwargs=%s',
host, self.http_connection_kwargs) host, self.http_connection_kwargs)
if self.use_proxy: if self.use_proxy and not self.skip_proxy(host):
connection = self.proxy_ssl(host, is_secure and 443 or 80) connection = self.proxy_ssl(host, is_secure and 443 or 80)
elif self.https_connection_factory: elif self.https_connection_factory:
connection = self.https_connection_factory(host) connection = self.https_connection_factory(host)
Expand Down
3 changes: 1 addition & 2 deletions boto/ec2/autoscale/__init__.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -224,8 +224,7 @@ def create_launch_configuration(self, launch_config):
if launch_config.ramdisk_id: if launch_config.ramdisk_id:
params['RamdiskId'] = launch_config.ramdisk_id params['RamdiskId'] = launch_config.ramdisk_id
if launch_config.block_device_mappings: if launch_config.block_device_mappings:
self.build_list_params(params, launch_config.block_device_mappings, [x.build_list_params(params) for x in launch_config.block_device_mappings]
'BlockDeviceMappings')
if launch_config.security_groups: if launch_config.security_groups:
self.build_list_params(params, launch_config.security_groups, self.build_list_params(params, launch_config.security_groups,
'SecurityGroups') 'SecurityGroups')
Expand Down
4 changes: 2 additions & 2 deletions boto/ec2/elb/__init__.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ class ELBConnection(AWSQueryConnection):
'elasticloadbalancing.us-east-1.amazonaws.com') 'elasticloadbalancing.us-east-1.amazonaws.com')


def __init__(self, aws_access_key_id=None, aws_secret_access_key=None, def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
is_secure=False, port=None, proxy=None, proxy_port=None, is_secure=True, port=None, proxy=None, proxy_port=None,
proxy_user=None, proxy_pass=None, debug=0, proxy_user=None, proxy_pass=None, debug=0,
https_connection_factory=None, region=None, path='/', https_connection_factory=None, region=None, path='/',
security_token=None, validate_certs=True): security_token=None, validate_certs=True):
Expand Down Expand Up @@ -616,5 +616,5 @@ def detach_lb_from_subnets(self, name, subnets):
params = {'LoadBalancerName': name} params = {'LoadBalancerName': name}
self.build_list_params(params, subnets, self.build_list_params(params, subnets,
'Subnets.member.%d') 'Subnets.member.%d')
return self.get_list('DettachLoadBalancerFromSubnets', return self.get_list('DetachLoadBalancerFromSubnets',
params, None) params, None)
3 changes: 3 additions & 0 deletions boto/elasticache/__init__.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ def regions():
RegionInfo(name='ap-southeast-1', RegionInfo(name='ap-southeast-1',
endpoint='elasticache.ap-southeast-1.amazonaws.com', endpoint='elasticache.ap-southeast-1.amazonaws.com',
connection_cls=ElastiCacheConnection), connection_cls=ElastiCacheConnection),
RegionInfo(name='ap-southeast-2',
endpoint='elasticache.ap-southeast-2.amazonaws.com',
connection_cls=ElastiCacheConnection),
RegionInfo(name='sa-east-1', RegionInfo(name='sa-east-1',
endpoint='elasticache.sa-east-1.amazonaws.com', endpoint='elasticache.sa-east-1.amazonaws.com',
connection_cls=ElastiCacheConnection), connection_cls=ElastiCacheConnection),
Expand Down
4 changes: 2 additions & 2 deletions boto/emr/instance_group.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ def __init__(self, num_instances, role, type, market, name, bidprice=None):
self.market = market self.market = market
self.name = name self.name = name
if market == 'SPOT': if market == 'SPOT':
if not isinstance(bidprice, basestring): if not bidprice:
raise ValueError('bidprice must be specified if market == SPOT') raise ValueError('bidprice must be specified if market == SPOT')
self.bidprice = bidprice self.bidprice = str(bidprice)


def __repr__(self): def __repr__(self):
if self.market == 'SPOT': if self.market == 'SPOT':
Expand Down
18 changes: 12 additions & 6 deletions boto/exception.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def __init__(self, status, reason, body=None, *args):
self.body = body or '' self.body = body or ''
self.request_id = None self.request_id = None
self.error_code = None self.error_code = None
self.error_message = None self._error_message = None
self.box_usage = None self.box_usage = None


# Attempt to parse the error response. If body isn't present, # Attempt to parse the error response. If body isn't present,
Expand All @@ -90,16 +90,22 @@ def __init__(self, status, reason, body=None, *args):
# in exception. But first, save self.body in self.error_message # in exception. But first, save self.body in self.error_message
# because occasionally we get error messages from Eucalyptus # because occasionally we get error messages from Eucalyptus
# that are just text strings that we want to preserve. # that are just text strings that we want to preserve.
self.error_message = self.body self.message = self.body
self.body = None self.body = None


def __getattr__(self, name): def __getattr__(self, name):
if name == 'message': if name == 'error_message':
return self.error_message return self.message
if name == 'code': if name == 'code':
return self.error_code return self.error_code
raise AttributeError raise AttributeError


def __setattr__(self, name, value):
if name == 'error_message':
self.message = value
else:
super(BotoServerError, self).__setattr__(name, value)

def __repr__(self): def __repr__(self):
return '%s: %s %s\n%s' % (self.__class__.__name__, return '%s: %s %s\n%s' % (self.__class__.__name__,
self.status, self.reason, self.body) self.status, self.reason, self.body)
Expand All @@ -117,15 +123,15 @@ def endElement(self, name, value, connection):
elif name == 'Code': elif name == 'Code':
self.error_code = value self.error_code = value
elif name == 'Message': elif name == 'Message':
self.error_message = value self.message = value
elif name == 'BoxUsage': elif name == 'BoxUsage':
self.box_usage = value self.box_usage = value
return None return None


def _cleanupParsedProperties(self): def _cleanupParsedProperties(self):
self.request_id = None self.request_id = None
self.error_code = None self.error_code = None
self.error_message = None self.message = None
self.box_usage = None self.box_usage = None


class ConsoleOutput: class ConsoleOutput:
Expand Down
Loading

0 comments on commit 15c650e

Please sign in to comment.