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 process_notification(self, message, state=None): payload = get_payload(message) LOG.warn('Do action for event: %s, resource_id: %s', message['event_type'], payload['id']) self.send_email_notification(message) # Generate uuid of an order order_id = uuidutils.generate_uuid() unit_price = 0 unit = 'hour' # Create subscriptions for this order for ext in self.product_items.extensions: if ext.name.startswith('suspend'): sub = ext.obj.create_subscription(message, order_id, type=const.STATE_SUSPEND) if sub and state == const.STATE_SUSPEND: price_data = None if 'extra' in sub and sub['extra']: try: extra_data = jsonutils.loads(sub['extra']) price_data = extra_data.get('price', None) except (Exception): LOG.warning('Decode subscription["extra"] failed') unit_price += pricing.calculate_price( sub['quantity'], sub['unit_price'], price_data) elif ext.name.startswith('running'): sub = ext.obj.create_subscription(message, order_id, type=const.STATE_RUNNING) if sub and (not state or state == const.STATE_RUNNING): price_data = None if 'extra' in sub and sub['extra']: try: extra_data = jsonutils.loads(sub['extra']) price_data = extra_data.get('price', None) except (Exception): LOG.warning('Decode subscription["extra"] failed') unit_price += pricing.calculate_price( sub['quantity'], sub['unit_price'], price_data) # Create an order for this instance self.create_order(order_id, unit_price, unit, message, state=state) # Notify master, just give master messages it needs remarks = 'Floating IP Has Been Created.' action_time = message['timestamp'] if state: self.resource_created_again(order_id, action_time, remarks) else: self.resource_created(order_id, action_time, remarks)
def parse_app_result(self, body, result, user_id, project_id): resources = [] try: result = jsonutils.loads(result[0]) if 'floatingip' in result: fip = result['floatingip'] resources.append( base.Resource(resource_id=fip['id'], resource_name=fip.get('name'), type=const.RESOURCE_FLOATINGIP, status=const.STATE_RUNNING, user_id=user_id, project_id=project_id)) elif 'router' in result: router = result['router'] resources.append( base.Resource(resource_id=router['id'], resource_name=router.get('name'), type=const.RESOURCE_ROUTER, status=const.STATE_RUNNING, user_id=user_id, project_id=project_id)) elif 'listener' in result: listener = result['listener'] resources.append( base.Resource(resource_id=listener['id'], resource_name=listener.get('name'), type=const.RESOURCE_LISTENER, status=const.STATE_RUNNING, user_id=user_id, project_id=project_id)) except Exception: return [] return resources
def _decode_esek(self, key, source, target, timestamp, esek): """This function decrypts the esek buffer passed in and returns a KeyStore to be used to check and decrypt the received message. :param key: The key to use to decrypt the ticket (esek) :param source: The name of the source service :param traget: The name of the target service :param timestamp: The incoming message timestamp :param esek: a base64 encoded encrypted block containing a JSON string """ rkey = None try: s = self._crypto.decrypt(key, esek) j = jsonutils.loads(s) rkey = base64.b64decode(j['key']) expiration = j['timestamp'] + j['ttl'] if j['timestamp'] > timestamp or timestamp > expiration: raise InvalidExpiredTicket(source, target) except Exception: raise InvalidEncryptedTicket(source, target) info = '%s,%s,%s' % (source, target, str(j['timestamp'])) sek = self._hkdf.expand(rkey, info, len(key) * 2) return self._split_key(sek, len(key))
def parse_app_result(self, body, result, user_id, project_id): resources = [] try: result = jsonutils.loads(result[0]) if 'volume' in result: volume = result['volume'] if 'display_name' in volume: resource_name = volume['display_name'] # v1 elif 'name' in volume: resource_name = volume['name'] # v2 else: resource_name = None resources.append(base.Resource( resource_id=volume['id'], resource_name=resource_name, type=const.RESOURCE_VOLUME, status=const.STATE_RUNNING, user_id=user_id, project_id=project_id)) elif 'snapshot' in result: snapshot = result['snapshot'] resources.append(base.Resource( resource_id=snapshot['id'], resource_name=snapshot['name'], type=const.RESOURCE_SNAPSHOT, status=const.STATE_RUNNING, user_id=user_id, project_id=project_id)) except Exception: return [] return resources
def parse_app_result(self, body, result, user_id, project_id): resources = [] try: result = jsonutils.loads(result[0]) if 'floatingip' in result: fip = result['floatingip'] resources.append(base.Resource( resource_id=fip['id'], resource_name=fip.get('uos:name'), type=const.RESOURCE_FLOATINGIP, status=const.STATE_RUNNING, user_id=user_id, project_id=project_id )) elif 'floatingipset' in result: fipset = result['floatingipset'] resources.append(base.Resource( resource_id=fipset['id'], resource_name=fipset.get('uos:name'), type=const.RESOURCE_FLOATINGIPSET, status=const.STATE_RUNNING, user_id=user_id, project_id=project_id )) elif 'router' in result: pass except Exception: return [] return resources
def load_json(cls, data, default_rule=None): """Allow loading of JSON rule data.""" # Suck in the JSON data and parse the rules rules = dict((k, parse_rule(v)) for k, v in jsonutils.loads(data).items()) return cls(rules, default_rule)
def load_json(cls, data, default_rule=None): """Allow loading of JSON rule data.""" # Suck in the JSON data and parse the rules rules = dict( (k, parse_rule(v)) for k, v in jsonutils.loads(data).items()) return cls(rules, default_rule)
def get_all(self, purchase): """Get price of a group of products.""" if purchase.bill_method not in ['hour', 'month', 'year']: err = 'Should specify bill_method among hour, month and year' raise exception.InvalidParameterValue(err=err) if not isinstance(purchase.bill_period, int): purchase.bill_period = 1 conn = pecan.request.db_conn unit_price = quantize_decimal(0) unit = purchase.bill_method for p in purchase.purchases: if all([p.product_id, p.quantity]): try: product = conn.get_product(request.context, p.product_id) except exception.ProductIdNotFound: LOG.warn("Product %s not found" % p.product_id) raise elif all([p.product_name, p.service, p.region_id, p.quantity]): filters = dict(name=p.product_name, service=p.service, region_id=p.region_id) products = list(conn.get_products( request.context, filters=filters)) if len(products) == 0: LOG.error('Product %s of region %s not found', p.product_name, p.region_id) raise exception.ProductNameNotFound( product_name=p.product_name) product = products[0] else: err = "Every purchase item should specify product_name, "\ "service, region_id and quantity or "\ "product_id and quantity." raise exception.MissingRequiredParams(reason=err) try: if product.unit_price: unit_price_data = jsonutils.loads(product.unit_price) price_data = pricing.get_price_data(unit_price_data, unit) else: price_data = None unit_price += pricing.calculate_price( p.quantity, price_data) except (Exception) as e: LOG.error('Calculate price of product %s failed, %s', p.product_name, e) raise e total_price = unit_price * purchase.bill_period return models.Price.transform(unit_price=unit_price, unit=unit, total_price=total_price)
def test_create_product_segmented_price_with_zero_price(self): price_data = self.build_segmented_price_data('5.0000', [[0, '0']]) extra = {'price': price_data} product_ref = self.new_product_ref( 'network', '0.1', 'hour', extra=extra) resp = self.post(self.product_path, headers=self.admin_headers, body=product_ref, expected_status=200) product_new_ref = resp.json_body self.assertProductEqual(product_ref, product_new_ref) self.assertEqual(extra, jsonutils.loads(product_new_ref['extra']))
def _decode_body(resp): if resp.text: try: body_resp = jsonutils.loads(resp.text) except (ValueError, TypeError): body_resp = None else: body_resp = None return body_resp
def get_all(self, purchase): """Get price of a group of products.""" if purchase.bill_method not in ['hour', 'month', 'year']: err = 'Should specify bill_method among hour, month and year' raise exception.InvalidParameterValue(err=err) if not isinstance(purchase.bill_period, int): purchase.bill_period = 1 conn = pecan.request.db_conn unit_price = quantize_decimal(0) unit = purchase.bill_method for p in purchase.purchases: if all([p.product_id, p.quantity]): try: product = conn.get_product(request.context, p.product_id) except exception.ProductIdNotFound: LOG.warn("Product %s not found" % p.product_id) raise elif all([p.product_name, p.service, p.region_id, p.quantity]): filters = dict(name=p.product_name, service=p.service, region_id=p.region_id) products = list( conn.get_products(request.context, filters=filters)) if len(products) == 0: LOG.error('Product %s of region %s not found', p.product_name, p.region_id) raise exception.ProductNameNotFound( product_name=p.product_name) product = products[0] else: err = "Every purchase item should specify product_name, "\ "service, region_id and quantity or "\ "product_id and quantity." raise exception.MissingRequiredParams(reason=err) try: if product.unit_price: unit_price_data = jsonutils.loads(product.unit_price) price_data = pricing.get_price_data(unit_price_data, unit) else: price_data = None unit_price += pricing.calculate_price(p.quantity, price_data) except (Exception) as e: LOG.error('Calculate price of product %s failed, %s', p.product_name, e) raise e total_price = unit_price * purchase.bill_period return models.Price.transform(unit_price=unit_price, unit=unit, total_price=total_price)
def get_price_data(extra, method=None): if not extra: return None extra_data = jsonutils.loads(extra) if not method or method == 'hour': return extra_data.get('price', None) elif method == 'month': return extra_data.get('monthly_price', None) elif method == 'year': return extra_data.get('yearly_price', None)
def parse_user_result(self, body, result): users = [] try: for r in result: user = jsonutils.loads(r)['user'] users.append(User( user_id=user['id'], user_name=user['name'], domain_id=user['domain_id'])) except Exception: return [] return users
def parse_project_result(self, body, result): projects = [] try: for r in result: project = jsonutils.loads(r)['project'] projects.append( Project(project_id=project['id'], project_name=project['name'], domain_id=project['domain_id'])) except Exception: return [] return projects
def parse_user_result(self, body, result): users = [] try: for r in result: user = jsonutils.loads(r)['user'] users.append( User(user_id=user['id'], user_name=user['name'], domain_id=user['domain_id'])) except Exception: return [] return users
def parse_project_result(self, body, result): projects = [] try: for r in result: project = jsonutils.loads(r)['project'] projects.append(Project( project_id=project['id'], project_name=project['name'], domain_id=project['domain_id'])) except Exception: return [] return projects
def _decode_body(resp): if resp.text: try: body_resp = jsonutils.loads(resp.text) except (ValueError, TypeError): body_resp = None _logger.debug("Could not decode JSON from body: %s" % resp.text) else: _logger.debug("No body was returned.") body_resp = None return body_resp
def _get_reply(self, url, resp): if resp.text: try: body = jsonutils.loads(resp.text) reply = body['reply'] except (KeyError, TypeError, ValueError): msg = "Failed to decode reply: %s" % resp.text raise CommunicationError(url, msg) else: msg = "No reply data was returned." raise CommunicationError(url, msg) return reply
def parse_app_result(self, body, result, user_id, project_id): resources = [] count = body['server'].get('max_count') or 1 if count == 1: try: if body['server'].get('return_reservation_id'): resv_id = jsonutils.loads(result[0])['reservation_id'] servers = nova.server_list_by_resv_id( resv_id, region_name=cfg.CONF.billing.region_name) server = servers[0].to_dict() else: server = jsonutils.loads(result[0])['server'] resources.append( base.Resource(resource_id=server['id'], resource_name=body['server']['name'], type=const.RESOURCE_INSTANCE, status=const.STATE_RUNNING, user_id=user_id, project_id=project_id)) except Exception: return [] else: try: resv_id = jsonutils.loads(result[0])['reservation_id'] servers = nova.server_list_by_resv_id( resv_id, region_name=cfg.CONF.billing.region_name) for server in servers: server = server.to_dict() resources.append( base.Resource(resource_id=server['id'], resource_name=server['name'], type=const.RESOURCE_INSTANCE, status=const.STATE_RUNNING, user_id=user_id, project_id=project_id)) except Exception: return [] return resources
def parse_app_result(self, body, result, user_id, project_id): resources = [] count = body['server'].get('max_count') or 1 if count == 1: try: if body['server'].get('return_reservation_id'): resv_id = jsonutils.loads(result[0])['reservation_id'] servers = nova.server_list_by_resv_id( resv_id, region_name=cfg.CONF.billing.region_name) server = servers[0].to_dict() else: server = jsonutils.loads(result[0])['server'] resources.append(base.Resource( resource_id=server['id'], resource_name=body['server']['name'], type=const.RESOURCE_INSTANCE, status=const.STATE_RUNNING, user_id=user_id, project_id=project_id)) except Exception: return [] else: try: resv_id = jsonutils.loads(result[0])['reservation_id'] servers = nova.server_list_by_resv_id( resv_id, region_name=cfg.CONF.billing.region_name) for server in servers: server = server.to_dict() resources.append(base.Resource( resource_id=server['id'], resource_name=server['name'], type=const.RESOURCE_INSTANCE, status=const.STATE_RUNNING, user_id=user_id, project_id=project_id)) except Exception: return [] return resources
def parse_app_result(self, body, result, user_id, project_id): resources = [] try: result = jsonutils.loads(result[0]) resources.append(base.Resource( resource_id=result['image']['id'], resource_name=result['image']['name'], type=const.RESOURCE_SNAPSHOT, status=const.STATE_RUNNING, user_id=user_id, project_id=project_id)) except Exception: return [] return resources
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 test_create_product_segmented_price_with_zero_price(self): price_data = self.build_segmented_price_data('5.0000', [[0, '0']]) extra = {'price': price_data} product_ref = self.new_product_ref('network', '0.1', 'hour', extra=extra) resp = self.post(self.product_path, headers=self.admin_headers, body=product_ref, expected_status=200) product_new_ref = resp.json_body self.assertProductEqual(product_ref, product_new_ref) self.assertEqual(extra, jsonutils.loads(product_new_ref['extra']))
def parse_app_result(self, body, result, user_id, project_id): resources = [] try: result = jsonutils.loads(result[0]) resources.append( base.Resource(resource_id=result['image']['id'], resource_name=result['image']['name'], type=const.RESOURCE_IMAGE, status=const.STATE_RUNNING, user_id=user_id, project_id=project_id)) except Exception: return [] return resources
def test_create_product_with_unsorted_segmented_price(self): price_data = self.build_segmented_price_data( '5.0000', [[0, '0.4'], [2, '0.3'], [4, '0.2'], [10, '0.1']]) product_ref = self.new_product_ref( 'network', '0.1', 'hour', extra={'price': price_data}) resp = self.post(self.product_path, headers=self.admin_headers, body=product_ref, expected_status=200) product_new_ref = resp.json_body self.assertProductEqual(product_ref, product_new_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_new_ref['extra']))
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 _test_volume_create_unit_price(self, size, volume_type=None, is_segmented_price=False): if is_segmented_price: product = self._set_product_volume_to_segmented_price(volume_type) extra = jsonutils.loads(product.extra) price = pricing.calculate_price(size, product.unit_price, extra["price"]) else: product = self._get_product_by_volume_type(volume_type) price = pricing.calculate_price(size, product.unit_price) resource_id = self._create_volume(volume_type, size, self.project_id) order = self.dbconn.get_order_by_resource_id(self.admin_req_context, resource_id) self.assertDecimalEqual(price, order.unit_price) bill = self.dbconn.get_latest_bill(self.admin_req_context, order.order_id) self.assertDecimalEqual(price, bill.unit_price)
def _unpack_json_msg(self, msg): """Load the JSON data in msg if msg.content_type indicates that it is necessary. Put the loaded data back into msg.content and update msg.content_type appropriately. A Qpid Message containing a dict will have a content_type of 'amqp/map', whereas one containing a string that needs to be converted back from JSON will have a content_type of JSON_CONTENT_TYPE. :param msg: a Qpid Message object :returns: None """ if msg.content_type == JSON_CONTENT_TYPE: msg.content = jsonutils.loads(msg.content) msg.content_type = 'amqp/map'
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 decode(self, version, metadata, message, signature): """This is the main decoding function. It takes a version, metadata, message and signature strings and returns a tuple with a (decrypted) message and metadata or raises an exception in case of error. :param version: the current envelope version :param metadata: a JSON serialized object with metadata for validation :param message: a JSON serialized (base64 encoded encrypted) message :param signature: a base64 encoded signature """ md = jsonutils.loads(metadata) check_args = ('source', 'destination', 'timestamp', 'nonce', 'esek', 'encryption') for arg in check_args: if arg not in md: raise InvalidMetadata('Missing metadata "%s"' % arg) if md['destination'] != self._name: # TODO(simo) handle group keys by checking target raise UnknownDestinationName(md['destination']) try: skey, ekey = self._decode_esek(self._key, md['source'], md['destination'], md['timestamp'], md['esek']) except InvalidExpiredTicket: raise except Exception: raise InvalidMetadata('Failed to decode ESEK for %s/%s' % (md['source'], md['destination'])) sig = self._crypto.sign(skey, version + metadata + message) if sig != signature: raise InvalidSignature(md['source'], md['destination']) if md['encryption'] is True: msg = self._crypto.decrypt(ekey, message) else: msg = message return (md, msg)
def decode(self, version, metadata, message, signature): """This is the main decoding function. It takes a version, metadata, message and signature strings and returns a tuple with a (decrypted) message and metadata or raises an exception in case of error. :param version: the current envelope version :param metadata: a JSON serialized object with metadata for validation :param message: a JSON serialized (base64 encoded encrypted) message :param signature: a base64 encoded signature """ md = jsonutils.loads(metadata) check_args = ('source', 'destination', 'timestamp', 'nonce', 'esek', 'encryption') for arg in check_args: if arg not in md: raise InvalidMetadata('Missing metadata "%s"' % arg) if md['destination'] != self._name: # TODO(simo) handle group keys by checking target raise UnknownDestinationName(md['destination']) try: skey, ekey = self._decode_esek(self._key, md['source'], md['destination'], md['timestamp'], md['esek']) except InvalidExpiredTicket: raise except Exception: raise InvalidMetadata('Failed to decode ESEK for %s/%s' % ( md['source'], md['destination'])) sig = self._crypto.sign(skey, version + metadata + message) if sig != signature: raise InvalidSignature(md['source'], md['destination']) if md['encryption'] is True: msg = self._crypto.decrypt(ekey, message) else: msg = message return (md, msg)
def test_create_product_with_unsorted_segmented_price(self): price_data = self.build_segmented_price_data( '5.0000', [[0, '0.4'], [2, '0.3'], [4, '0.2'], [10, '0.1']]) product_ref = self.new_product_ref('network', '0.1', 'hour', extra={'price': price_data}) resp = self.post(self.product_path, headers=self.admin_headers, body=product_ref, expected_status=200) product_new_ref = resp.json_body self.assertProductEqual(product_ref, product_new_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_new_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_floatingip_create_end_segmented_price(self): product = self.set_product_floatingip_to_segmented_price() extra = jsonutils.loads(product.extra) project_id = self.admin_account.project_id def _test_floatingip_created_segmented_price(rate_limit): price = pricing.calculate_price( pricing.rate_limit_to_unit(rate_limit), product.unit_price, extra['price']) resource_id = self.create_floatingip(rate_limit, project_id) order = self.dbconn.get_order_by_resource_id( self.admin_req_context, resource_id) self.assertDecimalEqual(price, order.unit_price) bill = self.dbconn.get_latest_bill(self.admin_req_context, order.order_id) self.assertDecimalEqual(price, bill.unit_price) _test_floatingip_created_segmented_price(1024) _test_floatingip_created_segmented_price(1024 * 11)
def deserialize_msg(msg): # NOTE(russellb): Hang on to your hats, this road is about to # get a little bumpy. # # Robustness Principle: # "Be strict in what you send, liberal in what you accept." # # At this point we have to do a bit of guessing about what it # is we just received. Here is the set of possibilities: # # 1) We received a dict. This could be 2 things: # # a) Inspect it to see if it looks like a standard message envelope. # If so, great! # # b) If it doesn't look like a standard message envelope, it could either # be a notification, or a message from before we added a message # envelope (referred to as version 1.0). # Just return the message as-is. # # 2) It's any other non-dict type. Just return it and hope for the best. # This case covers return values from rpc.call() from before message # envelopes were used. (messages to call a method were always a dict) if not isinstance(msg, dict): # See #2 above. return msg base_envelope_keys = (_VERSION_KEY, _MESSAGE_KEY) if not all(map(lambda key: key in msg, base_envelope_keys)): # See #1.b above. return msg # At this point we think we have the message envelope # format we were expecting. (#1.a above) if not version_is_compatible(_RPC_ENVELOPE_VERSION, msg[_VERSION_KEY]): raise UnsupportedRpcEnvelopeVersion(version=msg[_VERSION_KEY]) raw_msg = jsonutils.loads(msg[_MESSAGE_KEY]) return raw_msg
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 _test_volume_create_unit_price(self, size, volume_type=None, is_segmented_price=False): if is_segmented_price: product = self._set_product_volume_to_segmented_price(volume_type) extra = jsonutils.loads(product.extra) price = pricing.calculate_price(size, product.unit_price, extra['price']) else: product = self._get_product_by_volume_type(volume_type) price = pricing.calculate_price(size, product.unit_price) resource_id = self._create_volume(volume_type, size, self.project_id) order = self.dbconn.get_order_by_resource_id(self.admin_req_context, resource_id) self.assertDecimalEqual(price, order.unit_price) bill = self.dbconn.get_latest_bill(self.admin_req_context, order.order_id) self.assertDecimalEqual(price, bill.unit_price)
def deserialize_remote_exception(conf, data): failure = jsonutils.loads(str(data)) trace = failure.get('tb', []) message = failure.get('message', "") + "\n" + "\n".join(trace) name = failure.get('class') module = failure.get('module') # NOTE(ameade): We DO NOT want to allow just any module to be imported, in # order to prevent arbitrary code execution. if module not in conf.allowed_rpc_exception_modules: return RemoteError(name, failure.get('message'), trace) try: mod = importutils.import_module(module) klass = getattr(mod, name) if not issubclass(klass, Exception): raise TypeError("Can only deserialize Exceptions") failure = klass(*failure.get('args', []), **failure.get('kwargs', {})) except (AttributeError, TypeError, ImportError): return RemoteError(name, failure.get('message'), trace) ex_type = type(failure) str_override = lambda self: message new_ex_type = type(ex_type.__name__ + _REMOTE_POSTFIX, (ex_type,), {'__str__': str_override, '__unicode__': str_override}) new_ex_type.__module__ = '%s%s' % (module, _REMOTE_POSTFIX) try: # NOTE(ameade): Dynamically create a new exception type and swap it in # as the new type for the exception. This only works on user defined # Exceptions and not core python exceptions. This is important because # we cannot necessarily change an exception message so we must override # the __str__ method. failure.__class__ = new_ex_type except TypeError: # NOTE(ameade): If a core exception then just add the traceback to the # first exception argument. failure.args = (message,) + failure.args[1:] return failure
def parse_app_result(self, body, result, user_id, project_id): resources = [] try: result = jsonutils.loads(result[0]) if 'floatingip' in result: fip = result['floatingip'] resources.append(base.Resource( resource_id=fip['id'], resource_name=fip.get('name'), type=const.RESOURCE_FLOATINGIP, status=const.STATE_RUNNING, user_id=user_id, project_id=project_id )) elif 'router' in result: router = result['router'] resources.append(base.Resource( resource_id=router['id'], resource_name=router.get('name'), type=const.RESOURCE_ROUTER, status=const.STATE_RUNNING, user_id=user_id, project_id=project_id )) elif 'listener' in result: listener = result['listener'] resources.append(base.Resource( resource_id=listener['id'], resource_name=listener.get('name'), type=const.RESOURCE_LISTENER, status=const.STATE_RUNNING, user_id=user_id, project_id=project_id )) except Exception: return [] return resources
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 _from_json(self, datastring): try: return jsonutils.loads(datastring) except ValueError: msg = _("cannot understand JSON") raise MalformedRequestBody(reason=msg)
def _deserialize(data): """Deserialization wrapper.""" LOG.debug(_("Deserializing: %s"), data) return jsonutils.loads(data)