def connect_ec2_endpoint(url, aws_access_key_id=None, aws_secret_access_key=None, **kwargs): """ Connect to an EC2 Api endpoint. Additional arguments are passed through to connect_ec2. :type url: string :param url: A url for the ec2 api endpoint to connect to :type aws_access_key_id: string :param aws_access_key_id: Your AWS Access Key ID :type aws_secret_access_key: string :param aws_secret_access_key: Your AWS Secret Access Key :rtype: :class:`boto.ec2.connection.EC2Connection` :return: A connection to Eucalyptus server """ from boto.ec2.regioninfo import RegionInfo purl = urlparse(url) kwargs['port'] = purl.port kwargs['host'] = purl.hostname kwargs['path'] = purl.path if not 'is_secure' in kwargs: kwargs['is_secure'] = (purl.scheme == "https") kwargs['region'] = RegionInfo(name=purl.hostname, endpoint=purl.hostname) kwargs['aws_access_key_id'] = aws_access_key_id kwargs['aws_secret_access_key'] = aws_secret_access_key return(connect_ec2(**kwargs))
def _wrapper(self): # Check if flags are explicitly set. env_use_sigv4_flag = os.environ.get('S3_USE_SIGV4') cfg_use_sigv4_flag = boto.config.get('s3', 'use-sigv4') for flag in env_use_sigv4_flag, cfg_use_sigv4_flag: flag = convert_to_bool(flag) if flag is not None: return ['hmac-v4-s3'] if flag else func(self) # Use default for non-aws hosts. Adding a url scheme is necessary if # not present for urlparse to properly function. host = self.host if not self.host.startswith('http://') or \ self.host.startswith('https://'): host = 'https://' + host netloc = urlparse(host).netloc if not (netloc.endswith('amazonaws.com') or netloc.endswith('amazonaws.com.cn')): return func(self) # Use anonymous if enabled. if hasattr(self, 'anon') and self.anon: return func(self) # Default to sigv4 for aws hosts return ['hmac-v4-s3']
def _wrapper(self): if os.environ.get('S3_USE_SIGV4', False): return ['hmac-v4-s3'] if boto.config.get('s3', 'use-sigv4', False): return ['hmac-v4-s3'] if not hasattr(self, 'host'): return func(self) # Keep the old explicit logic in case somebody was adding to the list. for test in SIGV4_DETECT: if test in self.host: return ['hmac-v4-s3'] # Use default for non-aws hosts. Adding a url scheme is necessary if # not present for urlparse to properly function. host = self.host if not self.host.startswith('http://') or \ self.host.startswith('https://'): host = 'https://' + host netloc = urlparse(host).netloc if not (netloc.endswith('amazonaws.com') or netloc.endswith('amazonaws.com.cn')): return func(self) # Use the default for the global endpoint if netloc.endswith('s3.amazonaws.com'): return func(self) # Use the default for regions that support sigv4 and sigv2 if any(test in self.host for test in S3_AUTH_DETECT): return func(self) # Use anonymous if enabled. if hasattr(self, 'anon') and self.anon: return func(self) # Default to sigv4 for aws hosts outside of regions that are known # to support sigv2 return ['hmac-v4-s3']
def _mexe(self, request, sender=None, override_num_retries=None, retry_handler=None): """ mexe - Multi-execute inside a loop, retrying multiple times to handle transient Internet errors by simply trying again. Also handles redirects. This code was inspired by the S3Utils classes posted to the boto-users Google group by Larry Bates. Thanks! """ boto.log.debug('Method: %s' % request.method) boto.log.debug('Path: %s' % request.path) boto.log.debug('Data: %s' % request.body) boto.log.debug('Headers: %s' % request.headers) boto.log.debug('Host: %s' % request.host) boto.log.debug('Port: %s' % request.port) boto.log.debug('Params: %s' % request.params) response = None body = None e = None if override_num_retries is None: num_retries = config.getint('Boto', 'num_retries', self.num_retries) else: num_retries = override_num_retries i = 0 connection = self.get_http_connection(request.host, request.port, self.is_secure) # Convert body to bytes if needed if not isinstance(request.body, bytes) and hasattr(request.body, 'encode'): request.body = request.body.encode('utf-8') while i <= num_retries: # Use binary exponential backoff to desynchronize client requests. next_sleep = min(random.random() * (2 ** i), boto.config.get('Boto', 'max_retry_delay', 60)) try: # we now re-sign each request before it is retried boto.log.debug('Token: %s' % self.provider.security_token) request.authorize(connection=self) # Only force header for non-s3 connections, because s3 uses # an older signing method + bucket resource URLs that include # the port info. All others should be now be up to date and # not include the port. if 's3' not in self._required_auth_capability(): if not getattr(self, 'anon', False): self.set_host_header(request) boto.log.debug('Final headers: %s' % request.headers) request.start_time = datetime.now() if callable(sender): response = sender(connection, request.method, request.path, request.body, request.headers) else: connection.request(request.method, request.path, request.body, request.headers) response = connection.getresponse() boto.log.debug('Response headers: %s' % response.getheaders()) location = response.getheader('location') # -- gross hack -- # http_client gets confused with chunked responses to HEAD requests # so I have to fake it out if request.method == 'HEAD' and getattr(response, 'chunked', False): response.chunked = 0 if callable(retry_handler): status = retry_handler(response, i, next_sleep) if status: msg, i, next_sleep = status if msg: boto.log.debug(msg) time.sleep(next_sleep) continue if response.status in [500, 502, 503, 504]: msg = 'Received %d response. ' % response.status msg += 'Retrying in %3.1f seconds' % next_sleep boto.log.debug(msg) body = response.read() if isinstance(body, bytes): body = body.decode('utf-8') elif response.status < 300 or response.status >= 400 or \ not location: # don't return connection to the pool if response contains # Connection:close header, because the connection has been # closed and default reconnect behavior may do something # different than new_http_connection. Also, it's probably # less efficient to try to reuse a closed connection. conn_header_value = response.getheader('connection') if conn_header_value == 'close': connection.close() else: self.put_http_connection(request.host, request.port, self.is_secure, connection) if self.request_hook is not None: self.request_hook.handle_request_data(request, response) return response else: scheme, request.host, request.path, \ params, query, fragment = urlparse(location) if query: request.path += '?' + query # urlparse can return both host and port in netloc, so if # that's the case we need to split them up properly if ':' in request.host: request.host, request.port = request.host.split(':', 1) msg = 'Redirecting: %s' % scheme + '://' msg += request.host + request.path boto.log.debug(msg) connection = self.get_http_connection(request.host, request.port, scheme == 'https') response = None continue except PleaseRetryException as e: boto.log.debug('encountered a retry exception: %s' % e) connection = self.new_http_connection(request.host, request.port, self.is_secure) response = e.response except self.http_exceptions as e: for unretryable in self.http_unretryable_exceptions: if isinstance(e, unretryable): boto.log.debug( 'encountered unretryable %s exception, re-raising' % e.__class__.__name__) raise boto.log.debug('encountered %s exception, reconnecting' % \ e.__class__.__name__) connection = self.new_http_connection(request.host, request.port, self.is_secure) time.sleep(next_sleep) i += 1 # If we made it here, it's because we have exhausted our retries # and stil haven't succeeded. So, if we have a response object, # use it to raise an exception. # Otherwise, raise the exception that must have already happened. if self.request_hook is not None: self.request_hook.handle_request_data(request, response, error=True) if response: raise BotoServerError(response.status, response.reason, body) elif e: raise else: msg = 'Please report this exception as a Boto Issue!' raise BotoClientError(msg)