Example #1
0
    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']
Example #2
0
    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']
Example #3
0
    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)
Example #4
0
    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)
Example #5
0
 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
Example #6
0
    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))
Example #7
0
 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
Example #8
0
    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))
Example #9
0
 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
Example #10
0
 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
Example #11
0
    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)
Example #12
0
    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)
Example #13
0
    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)
Example #14
0
 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']))
Example #15
0
    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
Example #16
0
    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)
Example #17
0
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)
Example #18
0
 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
Example #19
0
 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
Example #20
0
 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
Example #21
0
 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
Example #22
0
    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
Example #23
0
    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
Example #24
0
    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
Example #25
0
    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
Example #26
0
 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
Example #27
0
 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
Example #28
0
 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
Example #29
0
 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']))
Example #30
0
 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']))
Example #31
0
 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
Example #32
0
 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']))
Example #33
0
 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']))
Example #34
0
    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)
Example #35
0
    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'
Example #36
0
    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'
Example #37
0
 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']))
Example #38
0
    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)
Example #39
0
    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)
Example #40
0
 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']))
Example #41
0
 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']))
Example #42
0
    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)
Example #43
0
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
Example #44
0
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
Example #45
0
    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)
Example #46
0
    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)
Example #47
0
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
Example #48
0
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
Example #49
0
 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
Example #50
0
    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)
Example #51
0
 def _from_json(self, datastring):
     try:
         return jsonutils.loads(datastring)
     except ValueError:
         msg = _("cannot understand JSON")
         raise MalformedRequestBody(reason=msg)
Example #52
0
 def _from_json(self, datastring):
     try:
         return jsonutils.loads(datastring)
     except ValueError:
         msg = _("cannot understand JSON")
         raise MalformedRequestBody(reason=msg)
Example #53
0
def _deserialize(data):
    """Deserialization wrapper."""
    LOG.debug(_("Deserializing: %s"), data)
    return jsonutils.loads(data)
Example #54
0
def _deserialize(data):
    """Deserialization wrapper."""
    LOG.debug(_("Deserializing: %s"), data)
    return jsonutils.loads(data)