def parse_error(self): context = self.connection.context status = int(self.status) # FIXME: Probably ditch this as the forbidden message will have # corresponding XML. if status == httplib.FORBIDDEN: if not self.body: raise InvalidCredsError(str(self.status) + ': ' + self.error) else: raise InvalidCredsError(self.body) try: body = ET.XML(self.body) except Exception: raise MalformedResponseError('Failed to parse XML', body=self.body, driver=self.connection.driver) if self.xpath: errs = findall(element=body, xpath=self.xpath, namespace=self.namespace) else: errs = [body] msgs = [] for err in errs: code = findtext(element=err, xpath='Code', namespace=self.namespace) message = findtext(element=err, xpath='Message', namespace=self.namespace) exceptionCls = self.exceptions.get(code, None) if exceptionCls is None: msgs.append('%s: %s' % (code, message)) continue # Custom exception class is defined, immediately throw an exception params = {} if hasattr(exceptionCls, 'kwargs'): for key in exceptionCls.kwargs: if key in context: params[key] = context[key] raise exceptionCls(value=message, driver=self.connection.driver, **params) return "\n".join(msgs)
def parse_body(self): if not self.body: return self.body try: data = json.loads(self.body) except: raise MalformedResponseError("Failed to parse JSON", body=self.body, driver=ElasticHostsBaseNodeDriver) return data
def _to_images(self, images_dict): try: images = images_dict['images'] except KeyError: raise MalformedResponseError(value='no images clause', body=images_dict, driver=self) #filter out all inactive images, since there's no way to tell client image is not ok return [ self._to_image(image) for image in images if image.get('status') == 'ACTIVE' ]
def parse_body(self): if len(self.body) == 0 and not self.parse_zero_length_body: return self.body try: body = json.loads(self.body) except Exception: raise MalformedResponseError( 'Failed to parse JSON', body=self.body, driver=self.connection.driver) return body
def success(self): if self.status == 403: raise InvalidCredsError('Invalid credentials', self.driver) if self.status == 401: raise InvalidCredsError('API Key has insufficient rights', self.driver) if not self.body: return None try: return self.parse_body()['status'] == 'success' except ValueError: raise MalformedResponseError('Malformed reply', body=self.body, driver=self.driver)
def parse_body(self): if not self.body: return None if self.status in (202, 204): return self.body try: body = json.loads(self.body) except: raise MalformedResponseError("Failed to parse JSON", body=self.body, driver=OpenStackNodeDriver_v1_1) return body
def parse_error(self): try: body = ET.XML(self.body) except: raise MalformedResponseError("Failed to parse XML", body=self.body, driver=OpenStackNodeDriver) try: text = "; ".join( [err.text or '' for err in body.getiterator() if err.text]) except ExpatError: text = self.body return '%s %s %s' % (self.status, self.error, text)
def _parse_url_headers(self, headers): try: server_url = headers['x-server-management-url'] #due to bug in openstack it always redirect to v1.0 self.server_url = server_url.replace('v1.1', self.version) self.auth_token = headers['x-auth-token'] except KeyError, e: # Returned 204 but has missing information in the header, something is wrong raise MalformedResponseError('Malformed response', body='Missing header: %s' % (str(e)), driver=self.driver)
def list_images(self, location=None): images_dict = self.connection.request('/images/detail').object try: images = images_dict['images'] values = images except KeyError: raise MalformedResponseError(value='no images-values clause', body=images_dict, driver=self) return [ self._to_image(value) for value in values if value.get('status') == 'ACTIVE' ]
def _sync_request(self, command, **kwargs): """This method handles synchronous calls which are generally fast information retrieval requests and thus return 'quickly'.""" kwargs['command'] = command result = self.request(self.driver.path, params=kwargs) command = command.lower() + 'response' if command not in result.object: raise MalformedResponseError("Unknown response format", body=result.body, driver=self.driver) result = result.object[command] return result
def success(self): if self.status == 403: raise InvalidCredsError("Invalid credentials", self.driver) if self.status == 401: raise InvalidCredsError("API Key has insufficient rights", self.driver) if not self.body: return None try: return self.parse_body()["status"] == "success" except ValueError: raise MalformedResponseError("Malformed reply", body=self.body, driver=self.driver)
def parse_body(self): if self.status == httplib.NO_CONTENT or not self.body: return None if self.has_content_type('application/xml'): try: return ET.XML(self.body) except: raise MalformedResponseError( 'Failed to parse XML', body=self.body, driver=self.node_driver) elif self.has_content_type('application/json'): try: return json.loads(self.body) except: raise MalformedResponseError( 'Failed to parse JSON', body=self.body, driver=self.node_driver) else: return self.body
def parse_error(self): # TODO: fixup, Rackspace only uses response codes really! try: body = ET.XML(self.body) except: raise MalformedResponseError("Failed to parse XML", body=self.body, driver=RackspaceNodeDriver) try: text = "; ".join( [err.text or '' for err in body.getiterator() if err.text]) except ExpatError: text = self.body return '%s %s %s' % (self.status, self.error, text)
def parse_body(self): if len(self.body) == 0 and not self.parse_zero_length_body: return self.body try: try: body = ET.XML(self.body) except ValueError: # lxml wants a bytes and tests are basically hard-coded to str body = ET.XML(self.body.encode('utf-8')) except: raise MalformedResponseError('Failed to parse XML', body=self.body, driver=self.connection.driver) return body
def parse_body(self): if len(self.body) == 0 and not self.parse_zero_length_body: return self.body try: if PY3: parser = ET.XMLParser(encoding='utf-8') body = ET.XML(self.body.encode('utf-8'), parser=parser) else: body = ET.XML(self.body) except: raise MalformedResponseError("Failed to parse XML", body=self.body, driver=self.connection.driver) return body
def _sync_request(self, command, action=None, params=None, data=None, headers=None, method="GET"): """ This method handles synchronous calls which are generally fast information retrieval requests and thus return 'quickly'. """ # command is always sent as part of "command" query parameter if params: params = copy.deepcopy(params) else: params = {} params["command"] = command # pylint: disable=maybe-no-member result = self.request( action=self.driver.path, params=params, data=data, headers=headers, method=method, ) command = command.lower() # Work around for older verions which don't return "response" suffix # in delete ingress rule response command name if (command == "revokesecuritygroupingress" and "revokesecuritygroupingressresponse" not in result.object): command = command elif (command == "restorevirtualmachine" and "restorevmresponse" in result.object): command = "restorevmresponse" else: command = command + "response" if command not in result.object: raise MalformedResponseError( "Unknown response format {}".format(command), body=result.body, driver=self.driver, ) result = result.object[command] return result
def parse_body(self): """ OSSResponse body is in utf-8 encoding. """ if len(self.body) == 0 and not self.parse_zero_length_body: return self.body try: if PY3: parser = ET.XMLParser(encoding="utf-8") body = ET.XML(self.body.encode("utf-8"), parser=parser) else: body = ET.XML(self.body) except Exception: raise MalformedResponseError("Failed to parse XML", body=self.body, driver=self.connection.driver) return body
def _sync_request(self, command, action=None, params=None, data=None, headers=None, method='GET'): """ This method handles synchronous calls which are generally fast information retrieval requests and thus return 'quickly'. """ # command is always sent as part of "command" query parameter if params: params = copy.deepcopy(params) else: params = {} params['command'] = command result = self.request(action=self.driver.path, params=params, data=data, headers=headers, method=method) command = command.lower() # Work around for older verions which don't return "response" suffix # in delete ingress rule response command name if (command == 'revokesecuritygroupingress' and 'revokesecuritygroupingressresponse' not in result.object): command = command else: command = command + 'response' if command not in result.object: raise MalformedResponseError("Unknown response format", body=result.body, driver=self.driver) result = result.object[command] return result
def create_node(self, **kwargs): """Create a new node See L{NodeDriver.create_node} for more keyword args. @keyword ex_metadata: Key/Value metadata to associate with a node @type ex_metadata: C{dict} @keyword ex_files: List of personalities => File contents to create on the node @type ex_files: C{dict} """ name = kwargs['name'] node_image = kwargs['image'] node_size = kwargs['size'] ex_metadata = kwargs.get('ex_metadata') ex_personality = kwargs.get('ex_personality') flavorRef = node_size.links[0]['href'] imageRef = node_image.extra['links'][0]['href'] request = { 'server': { 'name': name, 'flavorRef': flavorRef, 'imageRef': imageRef } } if ex_metadata: request['server']['metadata'] = ex_metadata if ex_personality: request['server']['personality'] = ex_personality data = json.dumps(request) resp = self.connection.request("/servers", method='POST', data=data) try: server_dict = resp.object['server'] except KeyError: raise MalformedResponseError(value='no server clause', body=resp.object, driver=self) return self._to_node(server_dict=server_dict)
def parse_error(self): if self.status == 401: raise InvalidCredsError(self.body) if self.status == 403: raise InvalidCredsError(self.body) try: body = ET.XML(self.body) except: raise MalformedResponseError("Failed to parse XML", body=self.body, driver=OpsourceNodeDriver) if self.status == 400: code = findtext(body, 'resultCode', SERVER_NS) message = findtext(body, 'resultDetail', SERVER_NS) raise OpsourceAPIException(code, message, driver=OpsourceNodeDriver) return self.body
def parse_error(self): try: body = ET.XML(self.body) except: raise MalformedResponseError('Failed to parse XML', body=self.body, driver=ProfitBricksNodeDriver) for e in body.findall('.//detail'): if ET.iselement(e[0].find('httpCode')): http_code = e[0].find('httpCode').text else: http_code = None if ET.iselement(e[0].find('faultCode')): fault_code = e[0].find('faultCode').text else: fault_code = None if ET.iselement(e[0].find('message')): message = e[0].find('message').text else: message = None return LibcloudError('HTTP Code: %s, Fault Code: %s, Message: %s' % (http_code, fault_code, message), driver=self)