Example #1
0
    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
Example #2
0
 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)
Example #3
0
 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)
Example #4
0
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
Example #5
0
    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)