def __call__(self, target, creds, enforcer): """Check http: rules by calling to a remote server. This example implementation simply verifies that the response is exactly 'True'. """ url = ('http:' + self.match) % target data = {'target': jsonutils.dumps(target), 'credentials': jsonutils.dumps(creds)} post_data = urllib.urlencode(data) f = urllib2.urlopen(url, post_data) return f.read() == "True"
def __call__(self, target, creds, enforcer): """Check http: rules by calling to a remote server. This example implementation simply verifies that the response is exactly 'True'. """ url = ('http:' + self.match) % target data = { 'target': jsonutils.dumps(target), 'credentials': jsonutils.dumps(creds) } post_data = urllib.urlencode(data) f = urllib2.urlopen(url, post_data) return f.read() == "True"
def _pack_json_msg(self, msg): """Qpid cannot serialize dicts containing strings longer than 65535 characters. This function dumps the message content to a JSON string, which Qpid is able to handle. :param msg: May be either a Qpid Message object or a bare dict. :returns: A Qpid Message with its content field JSON encoded. """ try: msg.content = jsonutils.dumps(msg.content) except AttributeError: # Need to have a Qpid message so we can set the content_type. msg = qpid_messaging.Message(jsonutils.dumps(msg)) msg.content_type = JSON_CONTENT_TYPE return msg
def serialize_msg(raw_msg): # NOTE(russellb) See the docstring for _RPC_ENVELOPE_VERSION for more # information about this format. msg = {_VERSION_KEY: _RPC_ENVELOPE_VERSION, _MESSAGE_KEY: jsonutils.dumps(raw_msg)} return msg
def __init__(self, conf, session, node_name, node_opts=None): """Init the Publisher class with the exchange_name, routing_key, and other options """ self.sender = None self.session = session if conf.qpid_topology_version == 1: addr_opts = { "create": "always", "node": { "type": "topic", "x-declare": { "durable": False, # auto-delete isn't implemented for exchanges in qpid, # but put in here anyway "auto-delete": True, }, }, } if node_opts: addr_opts["node"]["x-declare"].update(node_opts) self.address = "%s ; %s" % (node_name, jsonutils.dumps(addr_opts)) elif conf.qpid_topology_version == 2: self.address = node_name else: raise_invalid_topology_version() self.reconnect(session)
def format(self, record): message = {'message': record.getMessage(), 'asctime': self.formatTime(record, self.datefmt), 'name': record.name, 'msg': record.msg, 'args': record.args, 'levelname': record.levelname, 'levelno': record.levelno, 'pathname': record.pathname, 'filename': record.filename, 'module': record.module, 'lineno': record.lineno, 'funcname': record.funcName, 'created': record.created, 'msecs': record.msecs, 'relative_created': record.relativeCreated, 'thread': record.thread, 'thread_name': record.threadName, 'process_name': record.processName, 'process': record.process, 'traceback': None} if hasattr(record, 'extra'): message['extra'] = record.extra if record.exc_info: message['traceback'] = self.formatException(record.exc_info) return jsonutils.dumps(message)
def format(self, record): message = { 'message': record.getMessage(), 'asctime': self.formatTime(record, self.datefmt), 'name': record.name, 'msg': record.msg, 'args': record.args, 'levelname': record.levelname, 'levelno': record.levelno, 'pathname': record.pathname, 'filename': record.filename, 'module': record.module, 'lineno': record.lineno, 'funcname': record.funcName, 'created': record.created, 'msecs': record.msecs, 'relative_created': record.relativeCreated, 'thread': record.thread, 'thread_name': record.threadName, 'process_name': record.processName, 'process': record.process, 'traceback': None } if hasattr(record, 'extra'): message['extra'] = record.extra if record.exc_info: message['traceback'] = self.formatException(record.exc_info) return jsonutils.dumps(message)
def format(self, record): message = { "message": record.getMessage(), "asctime": self.formatTime(record, self.datefmt), "name": record.name, "msg": record.msg, "args": record.args, "levelname": record.levelname, "levelno": record.levelno, "pathname": record.pathname, "filename": record.filename, "module": record.module, "lineno": record.lineno, "funcname": record.funcName, "created": record.created, "msecs": record.msecs, "relative_created": record.relativeCreated, "thread": record.thread, "thread_name": record.threadName, "process_name": record.processName, "process": record.process, "traceback": None, } if hasattr(record, "extra"): message["extra"] = record.extra if record.exc_info: message["traceback"] = self.formatException(record.exc_info) return jsonutils.dumps(message)
def encode(self, version, target, json_msg): """This is the main encoding function. It takes a target and a message and returns a tuple consisting of a JSON serialized metadata object, a JSON serialized (and optionally encrypted) message, and a signature. :param version: the current envelope version :param target: The name of the target service (usually with hostname) :param json_msg: a serialized json message object """ ticket = self._get_ticket(target) metadata = jsonutils.dumps({ 'source': self._name, 'destination': target, 'timestamp': time.time(), 'nonce': _get_nonce(), 'esek': ticket.esek, 'encryption': self._encrypt }) message = json_msg if self._encrypt: message = self._crypto.encrypt(ticket.ekey, message) signature = self._crypto.sign(ticket.skey, version + metadata + message) return (metadata, message, signature)
def get_ticket(self, source, target, crypto, key): # prepare metadata md = { 'requestor': source, 'target': target, 'timestamp': time.time(), 'nonce': struct.unpack('Q', os.urandom(8))[0] } metadata = base64.b64encode(jsonutils.dumps(md)) # sign metadata signature = crypto.sign(key, metadata) # HTTP request reply = self._get_ticket({ 'metadata': metadata, 'signature': signature }) # verify reply signature = crypto.sign(key, (reply['metadata'] + reply['ticket'])) if signature != reply['signature']: raise InvalidEncryptedTicket(md['source'], md['destination']) md = jsonutils.loads(base64.b64decode(reply['metadata'])) if ((md['source'] != source or md['destination'] != target or md['expiration'] < time.time())): raise InvalidEncryptedTicket(md['source'], md['destination']) # return ticket data tkt = jsonutils.loads(crypto.decrypt(key, reply['ticket'])) return tkt, md['expiration']
def get_ticket(self, source, target, crypto, key): # prepare metadata md = {'requestor': source, 'target': target, 'timestamp': time.time(), 'nonce': struct.unpack('Q', os.urandom(8))[0]} metadata = base64.b64encode(jsonutils.dumps(md)) # sign metadata signature = crypto.sign(key, metadata) # HTTP request reply = self._get_ticket({'metadata': metadata, 'signature': signature}) # verify reply signature = crypto.sign(key, (reply['metadata'] + reply['ticket'])) if signature != reply['signature']: raise InvalidEncryptedTicket(md['source'], md['destination']) md = jsonutils.loads(base64.b64decode(reply['metadata'])) if ((md['source'] != source or md['destination'] != target or md['expiration'] < time.time())): raise InvalidEncryptedTicket(md['source'], md['destination']) # return ticket data tkt = jsonutils.loads(crypto.decrypt(key, reply['ticket'])) return tkt, md['expiration']
def encode(self, version, target, json_msg): """This is the main encoding function. It takes a target and a message and returns a tuple consisting of a JSON serialized metadata object, a JSON serialized (and optionally encrypted) message, and a signature. :param version: the current envelope version :param target: The name of the target service (usually with hostname) :param json_msg: a serialized json message object """ ticket = self._get_ticket(target) metadata = jsonutils.dumps({'source': self._name, 'destination': target, 'timestamp': time.time(), 'nonce': _get_nonce(), 'esek': ticket.esek, 'encryption': self._encrypt}) message = json_msg if self._encrypt: message = self._crypto.encrypt(ticket.ekey, message) signature = self._crypto.sign(ticket.skey, version + metadata + message) return (metadata, message, signature)
def default(self, data): def sanitizer(obj): if isinstance(obj, datetime.datetime): _dtime = obj - datetime.timedelta(microseconds=obj.microsecond) return _dtime.isoformat() return six.text_type(obj) return jsonutils.dumps(data, default=sanitizer)
def request(self, path, method, **kwargs): path = self.version + path headers = kwargs.pop('headers', dict()) headers['User-Agent'] = 'python-gringclient' # TODO(liuchenhong): not support SSL request right now try: kwargs.pop('cert') except (KeyError): pass try: kwargs.pop('verify') except (KeyError): pass # request params try: params = kwargs.pop('params') except (KeyError): params = None if params: query_vars = [ '%s=%s' % (k, v) for k, v in six.iteritems(params) if v ] path += '?%s' % ('&'.join(query_vars)) # request body try: body = kwargs.pop('body') if not isinstance(body, str): body = jsonutils.dumps(body) json_body = body headers['Content-Type'] = 'application/json' except (KeyError): json_body = None # authenticate headers headers.update( self.auth_plugin.get_auth_headers(params=params, body=json_body)) LOG.debug('HTTP request headers: %s', headers) LOG.debug('%s %s', method, path) resp = self.app.request(path, headers=headers, body=json_body, method=method, **kwargs) # The first argument returned here is not a request.Response # object, but a webob.response.Response. if caller need to get # anything from it, it should be mocked. return resp, self._decode_body(resp)
def __init__(self, conf, session, callback, node_name, node_opts, link_name, link_opts): """Declare a queue on an amqp session. 'session' is the amqp session to use 'callback' is the callback to call when messages are received 'node_name' is the first part of the Qpid address string, before ';' 'node_opts' will be applied to the "x-declare" section of "node" in the address string. 'link_name' goes into the "name" field of the "link" in the address string 'link_opts' will be applied to the "x-declare" section of "link" in the address string. """ self.callback = callback self.receiver = None self.session = None if conf.qpid_topology_version == 1: addr_opts = { "create": "always", "node": { "type": "topic", "x-declare": { "durable": True, "auto-delete": True, }, }, "link": { "name": link_name, "durable": True, "x-declare": { "durable": False, "auto-delete": True, "exclusive": False, }, }, } addr_opts["node"]["x-declare"].update(node_opts) elif conf.qpid_topology_version == 2: addr_opts = { "link": { "x-declare": { "auto-delete": True, }, }, } else: raise_invalid_topology_version() addr_opts["link"]["x-declare"].update(link_opts) self.address = "%s ; %s" % (node_name, jsonutils.dumps(addr_opts)) self.connect(session)
def _serialize(data): """Serialization wrapper. We prefer using JSON, but it cannot encode all types. Error if a developer passes us bad data. """ try: return jsonutils.dumps(data, ensure_ascii=True) except TypeError: with excutils.save_and_reraise_exception(): LOG.error(_("JSON serialization failed."))
def _update_product_with_price_data_failed( self, product, price_list=None, price_data=None, restr=None): if not price_data: price_data = self.build_segmented_price_data('0', price_list) extra = {'price': price_data} body = {'extra': jsonutils.dumps(extra)} query_url = self.build_product_query_url(product.product_id) self.put(query_url, headers=self.admin_headers, body=body, expected_status=400) if restr: self.assertLogging(restr)
def _update_product_with_base_price_failed(self, product, base_price, restr=None): price_list = [[10, '0.1'], [4, '0.2'], [0, '0.3']] price_data = self.build_segmented_price_data( base_price, price_list) extra = {'price': price_data} body = {'extra': jsonutils.dumps(extra)} query_url = self.build_product_query_url(product.product_id) self.put(query_url, headers=self.admin_headers, body=body, expected_status=400) if restr: self.assertLogging(restr)
def notify(_context, message): """Notifies the recipient of the desired event given the model. Log notifications using OpenStack's default logging system. """ priority = message.get('priority', CONF.default_notification_level) priority = priority.lower() logger = logging.getLogger( 'gringotts.openstack.common.notification.%s' % message['event_type']) getattr(logger, priority)(jsonutils.dumps(message))
def update_product_in_db(self, product_id, unit_price=None, extra=None): product = self.dbconn.get_product(self.admin_req_context, product_id) if unit_price: self.assertIsInstance(unit_price, six.text_type) product['unit_price'] = self.quantize(unit_price) if extra: if not isinstance(extra, six.text_type): product['extra'] = jsonutils.dumps(extra) else: product['extra'] = extra return self.dbconn.update_product(self.admin_req_context, product)
def test_update_product_to_segmented_price(self): product = self.product_fixture.ip_products[0] price_data = self.build_segmented_price_data( '5.0000', [[10, '0.1'], [4, '0.2'], [0, '0.3']]) extra = {'price': price_data} data = {'extra': jsonutils.dumps(extra)} query_url = self.build_product_query_url(product.product_id) resp = self.put(query_url, headers=self.admin_headers, body=data, expected_status=200) product_ref = resp.json_body self.assertProductEqual(product.as_dict(), product_ref) self.assertEqual(extra, jsonutils.loads(product_ref['extra']))
def __str__(self): """Dumps a string representation of the rules.""" # Start by building the canonical strings for the rules out_rules = {} for key, value in self.items(): # Use empty string for singleton TrueCheck instances if isinstance(value, TrueCheck): out_rules[key] = '' else: out_rules[key] = str(value) # Dump a pretty-printed JSON representation return jsonutils.dumps(out_rules, indent=4)
def new_product_ref(self, service, unit_price, unit, extra=None): ref = self.new_ref() del ref['id'] ref['service'] = service ref['unit_price'] = str(unit_price) ref['unit'] = unit ref['type'] = 'regular' if extra: ref['extra'] = extra if isinstance(extra, six.text_type) else \ jsonutils.dumps(extra) else: ref['extra'] = None return ref
def test_update_product_to_segmented_price(self): product = self.product_fixture.ip_products[0] price_data = self.build_segmented_price_data( '5.0000', [[10, '0.1'], [4, '0.2'], [0, '0.3']]) extra = {'price': price_data} data = { 'extra': jsonutils.dumps(extra) } query_url = self.build_product_query_url(product.product_id) resp = self.put(query_url, headers=self.admin_headers, body=data, expected_status=200) product_ref = resp.json_body self.assertProductEqual(product.as_dict(), product_ref) self.assertEqual(extra, jsonutils.loads(product_ref['extra']))
def request(self, path, method='GET', body=None, headers=None, expected_status=None, **kwargs): headers = {} if not headers else headers headers['Accept'] = 'application/json' json_body = body if body: if not isinstance(body, str): json_body = jsonutils.dumps(body) headers['Content-Type'] = 'application/json' resp = self.app.request(path, headers=headers, body=json_body, status=expected_status, method=method, **kwargs) return resp
def _update_product_with_base_price_failed(self, product, base_price, restr=None): price_list = [[10, '0.1'], [4, '0.2'], [0, '0.3']] price_data = self.build_segmented_price_data(base_price, price_list) extra = {'price': price_data} body = {'extra': jsonutils.dumps(extra)} query_url = self.build_product_query_url(product.product_id) self.put(query_url, headers=self.admin_headers, body=body, expected_status=400) if restr: self.assertLogging(restr)
def request(self, path, method, **kwargs): path = self.version + path headers = kwargs.pop("headers", dict()) headers["User-Agent"] = "python-gringclient" # TODO(liuchenhong): not support SSL request right now try: kwargs.pop("cert") except (KeyError): pass try: kwargs.pop("verify") except (KeyError): pass # request params try: params = kwargs.pop("params") except (KeyError): params = None if params: query_vars = ["%s=%s" % (k, v) for k, v in six.iteritems(params) if v] path += "?%s" % ("&".join(query_vars)) # request body try: body = kwargs.pop("body") if not isinstance(body, str): body = jsonutils.dumps(body) json_body = body headers["Content-Type"] = "application/json" except (KeyError): json_body = None # authenticate headers headers.update(self.auth_plugin.get_auth_headers(params=params, body=json_body)) LOG.debug("HTTP request headers: %s", headers) LOG.debug("%s %s", method, path) resp = self.app.request(path, headers=headers, body=json_body, method=method, **kwargs) # The first argument returned here is not a request.Response # object, but a webob.response.Response. if caller need to get # anything from it, it should be mocked. return resp, self._decode_body(resp)
def _update_product_with_price_data_failed(self, product, price_list=None, price_data=None, restr=None): if not price_data: price_data = self.build_segmented_price_data('0', price_list) extra = {'price': price_data} body = {'extra': jsonutils.dumps(extra)} query_url = self.build_product_query_url(product.product_id) self.put(query_url, headers=self.admin_headers, body=body, expected_status=400) if restr: self.assertLogging(restr)
def _do_get(self, url, request): req_kwargs = dict() req_kwargs['headers'] = dict() req_kwargs['headers']['User-Agent'] = self.USER_AGENT req_kwargs['headers']['Content-Type'] = 'application/json' req_kwargs['data'] = jsonutils.dumps({'request': request}) if self.timeout is not None: req_kwargs['timeout'] = self.timeout try: resp = requests.get(url, **req_kwargs) except requests.ConnectionError as e: err = "Unable to establish connection. %s" % e raise CommunicationError(url, err) return resp
def test_update_product_with_unsorted_segmented_price(self): product = self.product_fixture.ip_products[0] price_data = self.build_segmented_price_data( '5.0000', [[0, '0.4'], [2, '0.3'], [4, '0.2'], [10, '0.1']]) extra = {'price': price_data} body = {'extra': jsonutils.dumps(extra)} query_url = self.build_product_query_url(product.product_id) resp = self.put(query_url, headers=self.admin_headers, body=body, expected_status=200) product_ref = resp.json_body self.assertProductEqual(product.as_dict(), product_ref) # price list must be sorted after successfully created price_data['segmented'] = [ [10, '0.1'], [4, '0.2'], [2, '0.3'], [0, '0.4'] ] self.assertEqual({'price': price_data}, jsonutils.loads(product_ref['extra']))
def test_update_product_with_unsorted_segmented_price(self): product = self.product_fixture.ip_products[0] price_data = self.build_segmented_price_data( '5.0000', [[0, '0.4'], [2, '0.3'], [4, '0.2'], [10, '0.1']]) extra = {'price': price_data} body = {'extra': jsonutils.dumps(extra)} query_url = self.build_product_query_url(product.product_id) resp = self.put(query_url, headers=self.admin_headers, body=body, expected_status=200) product_ref = resp.json_body self.assertProductEqual(product.as_dict(), product_ref) # price list must be sorted after successfully created price_data['segmented'] = [[10, '0.1'], [4, '0.2'], [2, '0.3'], [0, '0.4']] self.assertEqual({'price': price_data}, jsonutils.loads(product_ref['extra']))
def test_update_product_with_segmented_price_and_reset(self): product = self.product_fixture.ip_products[0] quantity = 11 resource_type = gring_const.RESOURCE_FLOATINGIP order_id = self.new_order_id() user_id = self.admin_account.user_id project_id = self.admin_account.project_id running_subs = self.create_subs_in_db(product, quantity, gring_const.STATE_RUNNING, order_id, project_id, user_id) order = self.create_order_in_db(running_subs.unit_price, running_subs.unit, user_id, project_id, resource_type, running_subs.type, order_id=order_id) price_data = self.build_segmented_price_data( '0.0000', [[10, '0.1'], [4, '0.2'], [0, '0.3']]) extra = {'price': price_data} body = { 'extra': jsonutils.dumps(extra), 'reset': True, } query_url = self.build_product_query_url(product.product_id) self.put(query_url, headers=self.admin_headers, body=body, expected_status=200) expected_price = pricing.calculate_price(quantity, product.unit_price, price_data) order = self.dbconn.get_order(self.admin_req_context, order.order_id) subs = list( self.dbconn.get_subscriptions_by_order_id(self.admin_req_context, order.order_id)) for sub in subs: self.assertEqual(extra, jsonutils.loads(sub.extra)) self.assertDecimalEqual(expected_price, order.unit_price)
def serialize_remote_exception(failure_info, log_failure=True): """Prepares exception data to be sent over rpc. Failure_info should be a sys.exc_info() tuple. """ tb = traceback.format_exception(*failure_info) failure = failure_info[1] if log_failure: LOG.error(_("Returning exception %s to caller"), six.text_type(failure)) LOG.error(tb) kwargs = {} if hasattr(failure, 'kwargs'): kwargs = failure.kwargs # NOTE(matiu): With cells, it's possible to re-raise remote, remote # exceptions. Lets turn it back into the original exception type. cls_name = str(failure.__class__.__name__) mod_name = str(failure.__class__.__module__) if (cls_name.endswith(_REMOTE_POSTFIX) and mod_name.endswith(_REMOTE_POSTFIX)): cls_name = cls_name[:-len(_REMOTE_POSTFIX)] mod_name = mod_name[:-len(_REMOTE_POSTFIX)] data = { 'class': cls_name, 'module': mod_name, 'message': six.text_type(failure), 'tb': tb, 'args': failure.args, 'kwargs': kwargs } json_data = jsonutils.dumps(data) return json_data
def test_update_product_with_segmented_price_and_reset(self): product = self.product_fixture.ip_products[0] quantity = 11 resource_type = gring_const.RESOURCE_FLOATINGIP order_id = self.new_order_id() user_id = self.admin_account.user_id project_id = self.admin_account.project_id running_subs = self.create_subs_in_db( product, quantity, gring_const.STATE_RUNNING, order_id, project_id, user_id ) order = self.create_order_in_db( running_subs.unit_price, running_subs.unit, user_id, project_id, resource_type, running_subs.type, order_id=order_id ) price_data = self.build_segmented_price_data( '0.0000', [[10, '0.1'], [4, '0.2'], [0, '0.3']]) extra = {'price': price_data} body = { 'extra': jsonutils.dumps(extra), 'reset': True, } query_url = self.build_product_query_url(product.product_id) self.put(query_url, headers=self.admin_headers, body=body, expected_status=200) expected_price = pricing.calculate_price( quantity, product.unit_price, price_data) order = self.dbconn.get_order(self.admin_req_context, order.order_id) subs = list(self.dbconn.get_subscriptions_by_order_id( self.admin_req_context, order.order_id)) for sub in subs: self.assertEqual(extra, jsonutils.loads(sub.extra)) self.assertDecimalEqual(expected_price, order.unit_price)
def request(self, url, method, **kwargs): """Send an http request with the specified characteristics. Wrapper around requests.request to handle tasks such as setting headers, JSON encoding/decoding, and error handling. """ # url url = self.auth_plugin.get_endpoint() + url # headers headers = kwargs.setdefault('headers', dict()) headers['User-Agent'] = "python-gringclient" # others if self.cert: kwargs.setdefault('cert', self.cert) if self.timeout is not None: kwargs.setdefault('timeout', self.timeout) kwargs.setdefault('verify', self.verify) # body try: kwargs['data'] = jsonutils.dumps(kwargs.pop('body')) headers['Content-Type'] = 'application/json' except KeyError: pass # params try: kwargs['params'] = self.auth_plugin.filter_params(kwargs['params']) except KeyError: pass # NOTE(suo): It is because signauture auth method will sign the # body, so we should put headers after body headers.update(self.auth_plugin.get_auth_headers(**kwargs)) # build curl log string_parts = ['curl -i'] if method: string_parts.extend([' -X ', method]) query_string = "?%s" % urlencode(kwargs.get('params')) if kwargs.get('params') else "" string_parts.extend([' ', url + query_string]) if headers: for header in six.iteritems(headers): string_parts.append(' -H "%s: %s"' % header) data = kwargs.get('data') if data: string_parts.append(' -d \'%s\'' % data) _logger.debug('REQ: %s', ''.join(string_parts)) # send request resp = self._send_request(url, method, **kwargs) if resp.status_code >= 400: _logger.debug('Request returned failure status: %s', resp.status_code) raise exception.from_response(resp, method, url) return resp, self._decode_body(resp)
def get_raw_token_from_identity_service(self, auth_url=None, user_id=None, username=None, user_domain_id=None, user_domain_name=None, project_id=None, project_name=None, project_domain_id=None, project_domain_name=None, password=None): # headers headers = {'Content-Type': 'application/json'} if auth_url is None: raise ValueError("Cannot authenticate without a valid auth_url") # body url = auth_url + "/auth/tokens" body = {'auth': {'identity': {}}} ident = body['auth']['identity'] if password: ident['methods'] = ['password'] ident['password'] = {} ident['password']['user'] = {} user = ident['password']['user'] user['password'] = password if user_id: user['id'] = user_id elif username: user['name'] = username if user_domain_id or user_domain_name: user['domain'] = {} if user_domain_id: user['domain']['id'] = user_domain_id elif user_domain_name: user['domain']['name'] = user_domain_name if project_id or project_name: body['auth']['scope'] = {} scope = body['auth']['scope'] scope['project'] = {} if project_id: scope['project']['id'] = project_id elif project_name: scope['project']['name'] = project_name if project_domain_id or project_domain_name: scope['project']['domain'] = {} if project_domain_id: scope['project']['domain']['id'] = project_domain_id elif project_domain_name: scope['project']['domain']['name'] = project_domain_name try: resp = requests.post(url, data=jsonutils.dumps(body), headers=headers) except requests.exceptions.SSLError: msg = 'SSL exception connecting to %s' % url raise exception.SSLError(msg) except requests.exceptions.Timeout: msg = 'Request to %s timed out' % url raise exception.Timeout(msg) except requests.exceptions.ConnectionError: msg = 'Unable to establish connection to %s' % url raise exception.ConnectionError(message=msg) return resp, self._decode_body(resp)
def request(self, url, method, **kwargs): """Send an http request with the specified characteristics. Wrapper around requests.request to handle tasks such as setting headers, JSON encoding/decoding, and error handling. """ # url url = self.auth_plugin.get_endpoint() + url # headers headers = kwargs.setdefault('headers', dict()) headers['User-Agent'] = "python-gringclient" # others if self.cert: kwargs.setdefault('cert', self.cert) if self.timeout is not None: kwargs.setdefault('timeout', self.timeout) kwargs.setdefault('verify', self.verify) # body try: kwargs['data'] = jsonutils.dumps(kwargs.pop('body')) headers['Content-Type'] = 'application/json' except KeyError: pass # params try: kwargs['params'] = self.auth_plugin.filter_params(kwargs['params']) except KeyError: pass # NOTE(suo): It is because signauture auth method will sign the # body, so we should put headers after body headers.update(self.auth_plugin.get_auth_headers(**kwargs)) # build curl log string_parts = ['curl -i'] if method: string_parts.extend([' -X ', method]) query_string = "?%s" % urlencode(kwargs.get('params')) if kwargs.get( 'params') else "" string_parts.extend([' ', url + query_string]) if headers: for header in six.iteritems(headers): string_parts.append(' -H "%s: %s"' % header) data = kwargs.get('data') if data: string_parts.append(' -d \'%s\'' % data) _logger.debug('REQ: %s', ''.join(string_parts)) # send request resp = self._send_request(url, method, **kwargs) if resp.status_code >= 400: _logger.debug('Request returned failure status: %s', resp.status_code) raise exception.from_response(resp, method, url) return resp, self._decode_body(resp)