def __init__(self, status, reason, body=None, *args): super(NiftycloudServerError, self).__init__(status, reason, body, *args) self.status = status self.reason = reason self.body = body or '' self.request_id = None self.error_code = None self._error_message = None self.message = '' self.box_usage = None if isinstance(self.body, bytes): try: self.body = self.body.decode('utf-8') except UnicodeDecodeError: niftycloud.log.debug('Unable to decode body from bytes!') # Attempt to parse the error response. If body isn't present, # then just ignore the error response. if self.body: # Check if it looks like a ``dict``. if hasattr(self.body, 'items'): # It's not a string, so trying to parse it will fail. # But since it's data, we can work with that. self.request_id = self.body.get('RequestId', None) if 'Error' in self.body: # XML-style error = self.body.get('Error', {}) self.error_code = error.get('Code', None) self.message = error.get('Message', None) else: # JSON-style. self.message = self.body.get('message', None) else: try: h = handler.XmlHandlerWrapper(self, self) h.parseString(self.body) except (TypeError, xml.sax.SAXParseException): # What if it's JSON? Let's try that. try: parsed = json.loads(self.body) if 'RequestId' in parsed: self.request_id = parsed['RequestId'] if 'Error' in parsed: if 'Code' in parsed['Error']: self.error_code = parsed['Error']['Code'] if 'Message' in parsed['Error']: self.message = parsed['Error']['Message'] except (TypeError, ValueError): # Remove unparsable message body so we don't include garbage # in exception. But first, save self.body in self.error_message # because occasionally we get error messages from Eucalyptus # that are just text strings that we want to preserve. self.message = self.body self.body = None
def make_request(self, action, body): headers = { 'X-Amz-Target': '%s.%s' % (self.TargetPrefix, action), 'Host': self.region.endpoint, 'Content-Type': 'application/x-amz-json-1.1', 'Content-Length': str(len(body)), } http_request = self.build_base_http_request( method='POST', path='/', auth_path='/', params={}, headers=headers, data=body) response = self._mexe(http_request, sender=None, override_num_retries=10) response_body = response.read().decode('utf-8') niftycloud.log.debug(response_body) if response.status == 200: if response_body: return json.loads(response_body) else: json_body = json.loads(response_body) fault_name = json_body.get('__type', None) exception_class = self._faults.get(fault_name, self.ResponseError) raise exception_class(response.status, response.reason, body=json_body)
def load_from_sdb(self, domain_name, item_name): from niftycloud.compat import json sdb = niftycloud.connect_sdb() domain = sdb.lookup(domain_name) item = domain.get_item(item_name) for section in item.keys(): if not self.has_section(section): self.add_section(section) d = json.loads(item[section]) for attr_name in d.keys(): attr_value = d[attr_name] if attr_value is None: attr_value = 'None' if isinstance(attr_value, bool): self.setbool(section, attr_name, attr_value) else: self.set(section, attr_name, attr_value)
def get_instance_identity(version='latest', url='http://169.254.169.254', timeout=None, num_retries=5): """ Returns the instance identity as a nested Python dictionary. """ iid = {} base_url = _build_instance_metadata_url(url, version, 'dynamic/instance-identity/') try: data = retry_url(base_url, num_retries=num_retries, timeout=timeout) fields = data.split('\n') for field in fields: val = retry_url(base_url + '/' + field + '/', num_retries=num_retries, timeout=timeout) if val[0] == '{': val = json.loads(val) if field: iid[field] = val return iid except urllib.error.URLError: return None
def __getitem__(self, key): if key not in self: # allow dict to throw the KeyError return super(LazyLoadMetadata, self).__getitem__(key) # already loaded val = super(LazyLoadMetadata, self).__getitem__(key) if val is not None: return val if key in self._leaves: resource = self._leaves[key] last_exception = None for i in range(0, self._num_retries): try: val = niftycloud.utils.retry_url( self._url + urllib.parse.quote(resource, safe="/:"), num_retries=self._num_retries, timeout=self._timeout) if val and val[0] == '{': val = json.loads(val) break else: p = val.find('\n') if p > 0: val = val.split('\n') break except JSONDecodeError as e: niftycloud.log.debug( "encountered '%s' exception: %s" % ( e.__class__.__name__, e)) niftycloud.log.debug( 'corrupted JSON data found: %s' % val) last_exception = e except Exception as e: niftycloud.log.debug("encountered unretryable" + " '%s' exception, re-raising" % ( e.__class__.__name__)) last_exception = e raise niftycloud.log.error("Caught exception reading meta data" + " for the '%s' try" % (i + 1)) if i + 1 != self._num_retries: next_sleep = min( random.random() * 2 ** i, niftycloud.config.get('Niftycloud', 'max_retry_delay', 60)) time.sleep(next_sleep) else: niftycloud.log.error('Unable to read meta data, giving up') niftycloud.log.error( "encountered '%s' exception: %s" % ( last_exception.__class__.__name__, last_exception)) raise last_exception self[key] = val elif key in self._dicts: self[key] = LazyLoadMetadata(self._url + key + '/', self._num_retries) return super(LazyLoadMetadata, self).__getitem__(key)