コード例 #1
0
ファイル: api.py プロジェクト: soloxf/dough
def query_usage_report(context, datetime_from=None,
                       datetime_to=None, **kwargs):
    usage_report = dict()
    subscriptions = db.subscription_get_all_by_project(context,
                                                       context.project_id)
    for subscription in subscriptions:
        subscription_id = subscription['id']
        resource_uuid = subscription['resource_uuid']
        resource_name = subscription['resource_name']
        region_name = subscription['product']['region']['name']
        item_name = subscription['product']['item']['name']
        item_type_name = subscription['product']['item_type']['name']
        order_unit = subscription['product']['order_unit']
        price = subscription['product']['price']
        currency = subscription['product']['currency']
        purchases = db.purchase_get_all_by_subscription_and_timeframe(context,
                                                            subscription_id,
                                                            datetime_from,
                                                            datetime_to)
        quantity_sum = sum(map(lambda x: x['quantity'], purchases))
        line_total_sum = sum(map(lambda x: x['line_total'], purchases))
        # TODO(lzyeval): remove
        #assert (line_total_sum == quantity_sum * price)
        usage_datum = (resource_uuid, resource_name, item_type_name,
                       order_unit, price, currency, quantity_sum,
                       line_total_sum)
        item_usage_report = usage_report.get(item_name, dict())
        if not item_usage_report:
            usage_report[item_name] = item_usage_report
        region_usage_data = item_usage_report.get(region_name, list())
        if not region_usage_data:
            item_usage_report[region_name] = region_usage_data
        region_usage_data.append(usage_datum)
    return {'data': usage_report}
コード例 #2
0
ファイル: api.py プロジェクト: pengyuwei/dough
def query_monthly_report(context, timestamp_from=None,
                         timestamp_to=None, **kwargs):

    def find_timeframe(start_time, end_time, target):
        target_utc = target.replace(tzinfo=UTC_TIMEZONE)
        current_frame = start_time
        month_cnt = 1
        while current_frame < end_time:
            # 2012-05-10 00:00:00+00:00-->2012-06-10 00:00:00+00:00
            next_frame = start_time + relativedelta(months=month_cnt)
            if current_frame <= target_utc < next_frame:
                break
            month_cnt += 1
            current_frame = next_frame
        assert(current_frame < end_time)

        return current_frame.isoformat()

    monthly_report = dict()
    datetime_from = iso8601.parse_date(timestamp_from)
    datetime_to = iso8601.parse_date(timestamp_to)
    subscriptions = list()
    _subscriptions = db.subscription_get_all_by_project(context,
                                                        context.project_id)
    for subscription in _subscriptions:
        subscription_id = subscription['id']
        if subscription is None \
           or subscription['product'] is None \
           or subscription['product']['region'] is None \
           or subscription['product']['region']['name'] is None:
            continue
        region_name = subscription['product']['region']['name']
        item_name = subscription['product']['item']['name']
        subscriptions.append([subscription_id, region_name, item_name])
    for subscription_id, region_name, item_name in subscriptions:
        purchases = db.purchase_get_all_by_subscription_and_timeframe(context,
                                                            subscription_id,
                                                            datetime_from,
                                                            datetime_to)
        if not purchases:
            continue
        for purchase in purchases:
            line_total = purchase['line_total']
            timeframe = find_timeframe(datetime_from,
                                       datetime_to,
                                       purchase['created_at'])
            region_usage = monthly_report.setdefault(region_name, dict())
            monthly_usage = region_usage.setdefault(timeframe, dict())
            monthly_usage.setdefault(item_name, 0)
            monthly_usage[item_name] += line_total
    return {'data': monthly_report}
コード例 #3
0
ファイル: api.py プロジェクト: pengyuwei/dough
def query_usage_report(context, timestamp_from=None,
                       timestamp_to=None, **kwargs):
    usage_report = dict()
    datetime_from = iso8601.parse_date(timestamp_from)
    datetime_to = iso8601.parse_date(timestamp_to)
    subscriptions = list()
    _subscriptions = db.subscription_get_all_by_project(context,
                                                        context.project_id)
    for subscription in _subscriptions:
        if subscription is None \
           or subscription['product'] is None \
           or subscription['product']['region'] is None \
           or subscription['product']['region']['name'] is None:
            continue
        subscription_id = subscription['id']
        resource_uuid = subscription['resource_uuid']
        resource_name = subscription['resource_name']
        created_at = subscription['created_at']
        expires_at = subscription['expires_at']
        region_name = subscription['product']['region']['name']
        item_name = subscription['product']['item']['name']
        item_type_name = subscription['product']['item_type']['name']
        order_unit = subscription['product']['order_unit']
        order_size = subscription['product']['order_size']
        price = subscription['product']['price']
        currency = subscription['product']['currency']
        subscriptions.append([subscription_id, resource_uuid, resource_name,
                              created_at, expires_at,
                              region_name, item_name, item_type_name,
                              order_unit, order_size, price, currency])
    for (subscription_id, resource_uuid, resource_name, created_at, expires_at,
         region_name, item_name, item_type_name,
         order_unit, order_size, price, currency) in subscriptions:
        purchases = db.purchase_get_all_by_subscription_and_timeframe(context,
                                                            subscription_id,
                                                            datetime_from,
                                                            datetime_to)
        if not purchases:
            continue
        quantity_sum = sum(map(lambda x: x['quantity'], purchases))
        line_total_sum = sum(map(lambda x: x['line_total'], purchases))
        # TODO(lzyeval): remove
        #assert (line_total_sum == quantity_sum * price)
        usage_datum = (resource_uuid, resource_name, item_type_name,
                       order_unit, order_size, price,
                       currency, quantity_sum, line_total_sum,
                       created_at.isoformat(), expires_at.isoformat())
        region_usage = usage_report.setdefault(region_name, dict())
        item_usage = region_usage.setdefault(item_name, list())
        item_usage.append(usage_datum)
    return {'data': usage_report}
コード例 #4
0
ファイル: api.py プロジェクト: young8/dough
def query_monthly_report(context, timestamp_from=None,
                         timestamp_to=None, **kwargs):

    def find_timeframe(start_time, end_time, target):
        target_utc = target.replace(tzinfo=UTC_TIMEZONE)
        current_frame = start_time
        month_cnt = 1
        while current_frame < end_time:
            # 2012-05-10 00:00:00+00:00-->2012-06-10 00:00:00+00:00
            next_frame = start_time + relativedelta(months=month_cnt)
            if current_frame <= target_utc < next_frame:
                break
            month_cnt += 1
            current_frame = next_frame
        assert(current_frame < end_time)

        return current_frame.isoformat()

    monthly_report = dict()
    datetime_from = iso8601.parse_date(timestamp_from)
    datetime_to = iso8601.parse_date(timestamp_to)
    subscriptions = list()
    _subscriptions = db.subscription_get_all_by_project(context,
                                                        context.project_id)
    for subscription in _subscriptions:
        subscription_id = subscription['id']
        if subscription is None \
           or subscription['product'] is None \
           or subscription['product']['region'] is None \
           or subscription['product']['region']['name'] is None:
            continue
        region_name = subscription['product']['region']['name']
        item_name = subscription['product']['item']['name']
        subscriptions.append([subscription_id, region_name, item_name])
    for subscription_id, region_name, item_name in subscriptions:
        purchases = db.purchase_get_all_by_subscription_and_timeframe(context,
                                                            subscription_id,
                                                            datetime_from,
                                                            datetime_to)
        if not purchases:
            continue
        for purchase in purchases:
            line_total = purchase['line_total']
            timeframe = find_timeframe(datetime_from,
                                       datetime_to,
                                       purchase['created_at'])
            region_usage = monthly_report.setdefault(region_name, dict())
            monthly_usage = region_usage.setdefault(timeframe, dict())
            monthly_usage.setdefault(item_name, 0)
            monthly_usage[item_name] += line_total
    return {'data': monthly_report}
コード例 #5
0
ファイル: api.py プロジェクト: young8/dough
def query_usage_report(context, timestamp_from=None,
                       timestamp_to=None, **kwargs):
    usage_report = dict()
    datetime_from = iso8601.parse_date(timestamp_from)
    datetime_to = iso8601.parse_date(timestamp_to)
    subscriptions = list()
    _subscriptions = db.subscription_get_all_by_project(context,
                                                        context.project_id)
    for subscription in _subscriptions:
        if subscription is None \
           or subscription['product'] is None \
           or subscription['product']['region'] is None \
           or subscription['product']['region']['name'] is None:
            continue
        subscription_id = subscription['id']
        resource_uuid = subscription['resource_uuid']
        resource_name = subscription['resource_name']
        created_at = subscription['created_at']
        expires_at = subscription['expires_at']
        region_name = subscription['product']['region']['name']
        item_name = subscription['product']['item']['name']
        item_type_name = subscription['product']['item_type']['name']
        order_unit = subscription['product']['order_unit']
        order_size = subscription['product']['order_size']
        price = subscription['product']['price']
        currency = subscription['product']['currency']
        subscriptions.append([subscription_id, resource_uuid, resource_name,
                              created_at, expires_at,
                              region_name, item_name, item_type_name,
                              order_unit, order_size, price, currency])
    for (subscription_id, resource_uuid, resource_name, created_at, expires_at,
         region_name, item_name, item_type_name,
         order_unit, order_size, price, currency) in subscriptions:
        purchases = db.purchase_get_all_by_subscription_and_timeframe(context,
                                                            subscription_id,
                                                            datetime_from,
                                                            datetime_to)
        if not purchases:
            continue
        quantity_sum = sum(map(lambda x: x['quantity'], purchases))
        line_total_sum = sum(map(lambda x: x['line_total'], purchases))
        # TODO(lzyeval): remove
        #assert (line_total_sum == quantity_sum * price)
        usage_datum = (resource_uuid, resource_name, item_type_name,
                       order_unit, order_size, price,
                       currency, quantity_sum, line_total_sum,
                       created_at.isoformat(), expires_at.isoformat())
        region_usage = usage_report.setdefault(region_name, dict())
        item_usage = region_usage.setdefault(item_name, list())
        item_usage.append(usage_datum)
    return {'data': usage_report}
コード例 #6
0
ファイル: test_api.py プロジェクト: pperezrubio/dough
 def test_query_usage_report(self):
     timestamp_from = '2012-03-24T16:44:21'
     timestamp_to = '2012-03-24T16:46:21'
     datetime_from = iso8601.parse_date(timestamp_from)
     datetime_to = iso8601.parse_date(timestamp_to)
     project_subscriptions = [
         {
             'id': self.subscription_id,
             'resource_uuid': self.resource_uuid,
             'resource_name': self.resource_name,
             'product': {
                 'region': {
                     'name': self.region_name,
                     },
                 'item': {
                     'name': self.item_name,
                     },
                 'item_type': {
                     'name': self.item_type_name,
                     },
                 'order_unit': 'hours',
                 'order_size': 1,
                 'price': self.product_price,
                 'currency': 'CNY',
                 }
             },
         {
             'id': 60,
             'resource_uuid': 'a-fake-uuid-1',
             'resource_name': 'a_fake_name_1',
             'product': {
                 'region': {
                     'name': 'default',
                     },
                 'item': {
                     'name': 'instance',
                     },
                 'item_type': {
                     'name': 'm1.large',
                     },
                 'order_unit': 'months',
                 'order_size': 1,
                 'price': Decimal(2100.00).quantize(Decimal('0.01')),
                 'currency': 'CNY',
                 }
             },
         {
             'id': 61,
             'resource_uuid': 'a-fake-uuid-2',
             'resource_name': '10.211.23.45',
             'product': {
                 'region': {
                     'name': 'default',
                     },
                 'item': {
                     'name': 'floating_ip',
                     },
                 'item_type': {
                     'name': 'default',
                     },
                 'order_unit': 'days',
                 'order_size': 1,
                 'price': Decimal(1.10).quantize(Decimal('0.01')),
                 'currency': 'CNY',
                 }
             },
         {
             'id': 62,
             'resource_uuid': 'a-fake-uuid-3',
             'resource_name': '170.1.223.5',
             'product': {
                 'region': {
                     'name': 'default',
                     },
                 'item': {
                     'name': 'floating_ip',
                     },
                 'item_type': {
                     'name': 'default',
                     },
                 'order_unit': 'days',
                 'order_size': 1,
                 'price': Decimal(1.10).quantize(Decimal('0.01')),
                 'currency': 'CNY',
                 }
             },
         {
             'id': 63,
             'resource_uuid': 'a-fake-uuid-4',
             'resource_name': 'a_fake_name_4',
             'product': {
                 'region': {
                     'name': 'default',
                     },
                 'item': {
                     'name': 'load_balancer',
                     },
                 'item_type': {
                     'name': 'default',
                     },
                 'order_unit': 'days',
                 'order_size': 1,
                 'price': Decimal(2.70).quantize(Decimal('0.01')),
                 'currency': 'CNY',
                 }
             },
         {
             'id': 64,
             'resource_uuid': 'a-fake-uuid-5',
             'resource_name': 'a_fake_name_5',
             'product': {
                 'region': {
                     'name': 'default',
                     },
                 'item': {
                     'name': 'load_balancer',
                     },
                 'item_type': {
                     'name': 'default',
                     },
                 'order_unit': 'days',
                 'order_size': 1,
                 'price': Decimal(2.70).quantize(Decimal('0.01')),
                 'currency': 'CNY',
                 }
             },
         {
             'id': 65,
             'resource_uuid': self.resource_uuid,
             'resource_name': '192.168.0.2',
             'product': {
                 'region': {
                     'name': self.region_name,
                     },
                 'item': {
                     'name': 'network-out',
                     },
                 'item_type': {
                     'name': 'default',
                     },
                 'order_unit': 'KBytes',
                 'order_size': 1,
                 'price': Decimal(0.70).quantize(Decimal('0.01')),
                 'currency': 'CNY',
                 }
             },
         {
             'id': 66,
             'resource_uuid': 'a-fake-uuid-1',
             'resource_name': '192.168.0.3',
             'product': {
                 'region': {
                     'name': 'default',
                     },
                 'item': {
                     'name': 'network-out',
                     },
                 'item_type': {
                     'name': 'default',
                     },
                 'order_unit': 'KBytes',
                 'order_size': 1,
                 'price': Decimal(0.70).quantize(Decimal('0.01')),
                 'currency': 'CNY',
                 }
             },
         ]
     purchases1 = [
         {
             'quantity': 6,
             'line_total': Decimal(14.40).quantize(Decimal('0.01')),
             },
         {
             'quantity': 8,
             'line_total': Decimal(19.20).quantize(Decimal('0.01')),
             },
         {
             'quantity': 2,
             'line_total': Decimal(4.80).quantize(Decimal('0.01')),
             },
         ]
     purchases2 = [
         {
             'quantity': 1,
             'line_total': Decimal(2100.00).quantize(Decimal('0.01')),
             },
         ]
     purchases3 = [
         {
             'quantity': 6,
             'line_total': Decimal(6.60).quantize(Decimal('0.01')),
             },
         {
             'quantity': 8,
             'line_total': Decimal(8.80).quantize(Decimal('0.01')),
             },
         {
             'quantity': 5,
             'line_total': Decimal(5.50).quantize(Decimal('0.01')),
             },
         ]
     purchases4 = [
         {
             'quantity': 6,
             'line_total': Decimal(6.60).quantize(Decimal('0.01')),
             },
         {
             'quantity': 3,
             'line_total': Decimal(3.30).quantize(Decimal('0.01')),
             },
         {
             'quantity': 2,
             'line_total': Decimal(2.20).quantize(Decimal('0.01')),
             },
         ]
     purchases5 = [
         {
             'quantity': 6,
             'line_total': Decimal(16.20).quantize(Decimal('0.01')),
             },
         {
             'quantity': 3,
             'line_total': Decimal(8.10).quantize(Decimal('0.01')),
             },
         {
             'quantity': 4,
             'line_total': Decimal(10.80).quantize(Decimal('0.01')),
             },
         ]
     purchases6 = [
         {
             'quantity': 6,
             'line_total': Decimal(16.20).quantize(Decimal('0.01')),
             },
         {
             'quantity': 8,
             'line_total': Decimal(21.60).quantize(Decimal('0.01')),
             },
         {
             'quantity': 13,
             'line_total': Decimal(35.10).quantize(Decimal('0.01')),
             },
         ]
     purchases7 = [
         {
             'quantity': 1000,
             'line_total': Decimal(700.00).quantize(Decimal('0.01')),
             },
         {
             'quantity': 800,
             'line_total': Decimal(560.00).quantize(Decimal('0.01')),
             },
         {
             'quantity': 52,
             'line_total': Decimal(36.40).quantize(Decimal('0.01')),
             },
         ]
     purchases8 = [
         {
             'quantity': 9000,
             'line_total': Decimal(6300.00).quantize(Decimal('0.01')),
             },
         {
             'quantity': 800,
             'line_total': Decimal(560.00).quantize(Decimal('0.01')),
             },
         {
             'quantity': 53,
             'line_total': Decimal(37.10).quantize(Decimal('0.01')),
             },
         ]
     usage_report = {
         'load_balancer': {
             'default': [
                 ('a-fake-uuid-4', 'a_fake_name_4', 'default', 'days',
                  2.70, 'CNY', 13, 35.10),
                 ('a-fake-uuid-5', 'a_fake_name_5', 'default', 'days',
                  2.70, 'CNY', 27, 72.90),
                 ]
             },
         'instance': {
             'default': [
                 (self.resource_uuid, self.resource_name,
                  self.item_type_name, 'hours',
                  float(self.product_price), 'CNY', 16, 38.40),
                 ('a-fake-uuid-1', 'a_fake_name_1', 'm1.large', 'months',
                  2100.00, 'CNY', 1, 2100.00),
                 ],
             },
         'floating_ip': {
             'default': [
                 ('a-fake-uuid-2', '10.211.23.45', 'default', 'days',
                  1.10, 'CNY', 19, 20.90),
                 ('a-fake-uuid-3', '170.1.223.5', 'default', 'days',
                  1.10, 'CNY', 11, 12.10),
                 ],
             },
         'network-out': {
             'default': [
                 (self.resource_uuid, '192.168.0.2', 'default', 'KBytes',
                  0.70, 'CNY', 1852, 1296.40),
                 ('a-fake-uuid-1', '192.168.0.3', 'default', 'KBytes',
                  0.70, 'CNY', 9853, 6897.10),
                 ]
             },
         }
     self.mox.StubOutWithMock(db, 'subscription_get_all_by_project')
     _purchase_func = 'purchase_get_all_by_subscription_and_timeframe'
     self.mox.StubOutWithMock(db, _purchase_func)
     db.subscription_get_all_by_project(self.context, self.tenant_id).\
             AndReturn(project_subscriptions)
     db.purchase_get_all_by_subscription_and_timeframe(self.context,
             self.subscription_id, datetime_from, datetime_to).\
                     InAnyOrder().AndReturn(purchases1)
     db.purchase_get_all_by_subscription_and_timeframe(self.context,
             60, datetime_from, datetime_to).\
                     InAnyOrder().AndReturn(purchases2)
     db.purchase_get_all_by_subscription_and_timeframe(self.context,
             61, datetime_from, datetime_to).\
                     InAnyOrder().AndReturn(purchases3)
     db.purchase_get_all_by_subscription_and_timeframe(self.context,
             62, datetime_from, datetime_to).\
                     InAnyOrder().AndReturn(purchases4)
     db.purchase_get_all_by_subscription_and_timeframe(self.context,
             63, datetime_from, datetime_to).\
                     InAnyOrder().AndReturn(purchases5)
     db.purchase_get_all_by_subscription_and_timeframe(self.context,
             64, datetime_from, datetime_to).\
                     InAnyOrder().AndReturn(purchases6)
     db.purchase_get_all_by_subscription_and_timeframe(self.context,
             65, datetime_from, datetime_to).\
                     InAnyOrder().AndReturn(purchases7)
     db.purchase_get_all_by_subscription_and_timeframe(self.context,
             66, datetime_from, datetime_to).\
                     InAnyOrder().AndReturn(purchases8)
     self.mox.ReplayAll()
     result = api.query_usage_report(self.context,
                                     timestamp_from,
                                     timestamp_to)
     self.mox.VerifyAll()
     expect_keys = usage_report.keys().sort()
     actual_keys = result['data'].keys().sort()
     self.assertEqual(expect_keys, actual_keys)
     for k, v in result['data'].iteritems():
         self.assertEqual(v, usage_report[k])
コード例 #7
0
ファイル: api.py プロジェクト: pengyuwei/dough
def query_report(context, timestamp_from=None, timestamp_to=None,
                  period=None, item_name=None, resource_name=None, **kwargs):
    """period='days' or 'hours'"""
    print "query_report", timestamp_from, timestamp_to, item_name, resource_name
#    period = int(period)

    if not period in ['days', 'hours', 'months']:
        return {'data': None}

    def find_timeframe(start_time, end_time, target):
        target_utc = target.replace(tzinfo=UTC_TIMEZONE)
        current_frame = start_time
        cnt = 1
        while current_frame < end_time:
            foo = {period: cnt}
            next_frame = start_time + relativedelta(**foo)
            if current_frame <= target_utc < next_frame:
                break
            cnt += 1
            current_frame = next_frame
        assert(current_frame < end_time)
        return current_frame.isoformat()

    monthly_report = dict()
    #usage_report = dict()
    datetime_from = iso8601.parse_date(timestamp_from)
    datetime_to = iso8601.parse_date(timestamp_to)
    subscriptions = list()
    _subscriptions = list()

    __subscriptions = db.subscription_get_all_by_project(context,
                                                        context.project_id)
    if not __subscriptions:
        return {'data': None}
#    print "context.project_id", context.project_id
    for subscription in __subscriptions:
#        print subscription['id'], subscription['resource_name'], subscription['product']['item']['name']
        if subscription['resource_name'] != resource_name:
            continue
        elif subscription['product']['item']['name'] != item_name:
            continue
        _subscriptions.append(subscription)

    for subscription in _subscriptions:
        subscription_id = subscription['id']
        resource_uuid = subscription['resource_uuid']
        resource_name = subscription['resource_name']
        created_at = subscription['created_at']
        expires_at = subscription['expires_at']
        region_name = subscription['product']['region']['name']
        item_name = subscription['product']['item']['name']
        item_type_name = subscription['product']['item_type']['name']
        order_unit = subscription['product']['order_unit']
        order_size = subscription['product']['order_size']
        price = subscription['product']['price']
        currency = subscription['product']['currency']
        subscriptions.append([subscription_id, resource_uuid, resource_name,
                              created_at, expires_at,
                              region_name, item_name, item_type_name,
                              order_unit, order_size, price, currency])
    for (subscription_id, resource_uuid, resource_name, created_at, expires_at,
         region_name, item_name, item_type_name,
         order_unit, order_size, price, currency) in subscriptions:
        purchases = db.purchase_get_all_by_subscription_and_timeframe(context,
                                                            subscription_id,
                                                            datetime_from,
                                                            datetime_to)
        if not purchases:
            continue
        i = 0
        for purchase in purchases:
            line_total = purchase['line_total']
            quantity = purchase['quantity']
            timeframe = find_timeframe(datetime_from,
                                       datetime_to,
                                       purchase['created_at'])
#            print timeframe
            i += 1
            usage_datum = (resource_uuid, resource_name, item_type_name,
                           order_unit, order_size, price,
                           currency, quantity, line_total,
                           created_at.isoformat(), expires_at.isoformat())
            region_usage = monthly_report.setdefault(region_name, dict())
            monthly_usage = region_usage.setdefault(timeframe, dict())
            monthly_usage.setdefault(item_name, 0)
            monthly_usage[item_name] = usage_datum
            monthly_usage.setdefault("quantity", 0)
            monthly_usage.setdefault("line_total", 0)
            monthly_usage["quantity"] += quantity
            monthly_usage["line_total"] += line_total
        print "total:", i
    return {'data': monthly_report}
コード例 #8
0
 def test_query_usage_report(self):
     timestamp_from = '2012-03-24T16:44:21+00:00'
     timestamp_to = '2012-03-24T16:46:21+00:00'
     datetime_from = iso8601.parse_date(timestamp_from)
     datetime_to = iso8601.parse_date(timestamp_to)
     project_subscriptions = [
         {
             'id': self.subscription_id,
             'resource_uuid': self.resource_uuid,
             'resource_name': self.resource_name,
             'created_at': datetime_from,
             'expires_at': datetime_to,
             'product': {
                 'region': {
                     'name': self.region_name,
                     },
                 'item': {
                     'name': self.item_name,
                     },
                 'item_type': {
                     'name': self.item_type_name,
                     },
                 'order_unit': 'hours',
                 'order_size': 1,
                 'price': self.product_price,
                 'currency': 'CNY',
                 }
             },
         {
             'id': 60,
             'resource_uuid': 'a-fake-uuid-1',
             'resource_name': 'a_fake_name_1',
             'created_at': datetime_from,
             'expires_at': datetime_to,
             'product': {
                 'region': {
                     'name': 'default',
                     },
                 'item': {
                     'name': 'instance',
                     },
                 'item_type': {
                     'name': 'm1.large',
                     },
                 'order_unit': 'months',
                 'order_size': 1,
                 'price': 2100.00,
                 'currency': 'CNY',
                 }
             },
         {
             'id': 61,
             'resource_uuid': 'a-fake-uuid-2',
             'resource_name': '10.211.23.45',
             'created_at': datetime_from,
             'expires_at': datetime_to,
             'product': {
                 'region': {
                     'name': 'default',
                     },
                 'item': {
                     'name': 'floating_ip',
                     },
                 'item_type': {
                     'name': 'default',
                     },
                 'order_unit': 'days',
                 'order_size': 1,
                 'price': 1.10,
                 'currency': 'CNY',
                 }
             },
         {
             'id': 62,
             'resource_uuid': 'a-fake-uuid-3',
             'resource_name': '170.1.223.5',
             'created_at': datetime_from,
             'expires_at': datetime_to,
             'product': {
                 'region': {
                     'name': 'default',
                     },
                 'item': {
                     'name': 'floating_ip',
                     },
                 'item_type': {
                     'name': 'default',
                     },
                 'order_unit': 'days',
                 'order_size': 1,
                 'price': 1.10,
                 'currency': 'CNY',
                 }
             },
         {
             'id': 63,
             'resource_uuid': 'a-fake-uuid-4',
             'resource_name': 'a_fake_name_4',
             'created_at': datetime_from,
             'expires_at': datetime_to,
             'product': {
                 'region': {
                     'name': 'default',
                     },
                 'item': {
                     'name': 'load_balancer',
                     },
                 'item_type': {
                     'name': 'default',
                     },
                 'order_unit': 'days',
                 'order_size': 1,
                 'price': 2.70,
                 'currency': 'CNY',
                 }
             },
         {
             'id': 64,
             'resource_uuid': 'a-fake-uuid-5',
             'resource_name': 'a_fake_name_5',
             'created_at': datetime_from,
             'expires_at': datetime_to,
             'product': {
                 'region': {
                     'name': 'default',
                     },
                 'item': {
                     'name': 'load_balancer',
                     },
                 'item_type': {
                     'name': 'default',
                     },
                 'order_unit': 'days',
                 'order_size': 1,
                 'price': 2.70,
                 'currency': 'CNY',
                 }
             },
         {
             'id': 65,
             'resource_uuid': self.resource_uuid,
             'resource_name': '192.168.0.2',
             'created_at': datetime_from,
             'expires_at': datetime_to,
             'product': {
                 'region': {
                     'name': self.region_name,
                     },
                 'item': {
                     'name': 'network',
                     },
                 'item_type': {
                     'name': 'default',
                     },
                 'order_unit': 'KBytes',
                 'order_size': 1,
                 'price': 0.70,
                 'currency': 'CNY',
                 }
             },
         {
             'id': 66,
             'resource_uuid': 'a-fake-uuid-1',
             'resource_name': '192.168.0.3',
             'created_at': datetime_from,
             'expires_at': datetime_to,
             'product': {
                 'region': {
                     'name': 'default',
                     },
                 'item': {
                     'name': 'network',
                     },
                 'item_type': {
                     'name': 'default',
                     },
                 'order_unit': 'KBytes',
                 'order_size': 1,
                 'price': 0.70,
                 'currency': 'CNY',
                 }
             },
         ]
     purchases1 = [
         {
             'quantity': 6,
             'line_total': 14.40,
             },
         {
             'quantity': 8,
             'line_total': 19.20,
             },
         {
             'quantity': 2,
             'line_total': 4.80,
             },
         ]
     purchases2 = [
         {
             'quantity': 1,
             'line_total': 2100.00,
             },
         ]
     purchases3 = [
         {
             'quantity': 6,
             'line_total': 6.60,
             },
         {
             'quantity': 8,
             'line_total': 8.80,
             },
         {
             'quantity': 5,
             'line_total': 5.50,
             },
         ]
     purchases4 = [
         {
             'quantity': 6,
             'line_total': 6.60,
             },
         {
             'quantity': 3,
             'line_total': 3.30,
             },
         {
             'quantity': 2,
             'line_total': 2.20,
             },
         ]
     purchases5 = [
         {
             'quantity': 6,
             'line_total': 16.20,
             },
         {
             'quantity': 3,
             'line_total': 8.10,
             },
         {
             'quantity': 4,
             'line_total': 10.80,
             },
         ]
     purchases6 = [
         {
             'quantity': 6,
             'line_total': 16.20,
             },
         {
             'quantity': 8,
             'line_total': 21.60,
             },
         {
             'quantity': 13,
             'line_total': 35.10,
             },
         ]
     purchases7 = [
         {
             'quantity': 1000,
             'line_total': 700.00,
             },
         {
             'quantity': 800,
             'line_total': 560.00,
             },
         {
             'quantity': 52,
             'line_total': 36.40,
             },
         ]
     purchases8 = [
         {
             'quantity': 9000,
             'line_total': 6300.00,
             },
         {
             'quantity': 800,
             'line_total': 560.00,
             },
         {
             'quantity': 53,
             'line_total': 37.10,
             },
         ]
     usage_report = {
         'default': {
             'load_balancer': [
                 ('a-fake-uuid-4', 'a_fake_name_4', 'default', 'days',
                  2.70, 'CNY', 13, 35.10, timestamp_from, timestamp_to),
                 ('a-fake-uuid-5', 'a_fake_name_5', 'default', 'days',
                  2.70, 'CNY', 27, 72.90, timestamp_from, timestamp_to),
                 ],
             'instance': [
                 (self.resource_uuid, self.resource_name,
                  self.item_type_name, 'hours',
                  self.product_price, 'CNY', 16, 38.40,
                  timestamp_from, timestamp_to),
                 ('a-fake-uuid-1', 'a_fake_name_1', 'm1.large', 'months',
                  2100.00, 'CNY', 1, 2100.00, timestamp_from, timestamp_to),
                 ],
             'floating_ip': [
                 ('a-fake-uuid-2', '10.211.23.45', 'default', 'days',
                  1.10, 'CNY', 19, 20.90, timestamp_from, timestamp_to),
                 ('a-fake-uuid-3', '170.1.223.5', 'default', 'days',
                  1.10, 'CNY', 11, 12.10, timestamp_from, timestamp_to),
                 ],
             'network': [
                 (self.resource_uuid, '192.168.0.2', 'default', 'KBytes',
                  0.70, 'CNY', 1852, 1296.40, timestamp_from, timestamp_to),
                 ('a-fake-uuid-1', '192.168.0.3', 'default', 'KBytes',
                  0.70, 'CNY', 9853, 6897.10, timestamp_from, timestamp_to),
                 ],
             },
         }
     self.mox.StubOutWithMock(db, 'subscription_get_all_by_project')
     _purchase_func = 'purchase_get_all_by_subscription_and_timeframe'
     self.mox.StubOutWithMock(db, _purchase_func)
     db.subscription_get_all_by_project(self.context, self.tenant_id).\
             AndReturn(project_subscriptions)
     db.purchase_get_all_by_subscription_and_timeframe(self.context,
             self.subscription_id, datetime_from, datetime_to).\
                     InAnyOrder().AndReturn(purchases1)
     db.purchase_get_all_by_subscription_and_timeframe(self.context,
             60, datetime_from, datetime_to).\
                     InAnyOrder().AndReturn(purchases2)
     db.purchase_get_all_by_subscription_and_timeframe(self.context,
             61, datetime_from, datetime_to).\
                     InAnyOrder().AndReturn(purchases3)
     db.purchase_get_all_by_subscription_and_timeframe(self.context,
             62, datetime_from, datetime_to).\
                     InAnyOrder().AndReturn(purchases4)
     db.purchase_get_all_by_subscription_and_timeframe(self.context,
             63, datetime_from, datetime_to).\
                     InAnyOrder().AndReturn(purchases5)
     db.purchase_get_all_by_subscription_and_timeframe(self.context,
             64, datetime_from, datetime_to).\
                     InAnyOrder().AndReturn(purchases6)
     db.purchase_get_all_by_subscription_and_timeframe(self.context,
             65, datetime_from, datetime_to).\
                     InAnyOrder().AndReturn(purchases7)
     db.purchase_get_all_by_subscription_and_timeframe(self.context,
             66, datetime_from, datetime_to).\
                     InAnyOrder().AndReturn(purchases8)
     self.mox.ReplayAll()
     result = api.query_usage_report(self.context,
                                     timestamp_from,
                                     timestamp_to)
     self.mox.VerifyAll()
     expect_keys = usage_report.keys().sort()
     actual_keys = result['data'].keys().sort()
     self.assertEqual(expect_keys, actual_keys)
     for k, v in result['data'].iteritems():
         new_report = dict()
         for region_name, usage_data in v.iteritems():
             new_data = new_report.setdefault(region_name, list())
             for a, b, c, d, e, f, g, h, i, j in usage_data:
                 datum = (a, b, c, d, e, f, g,
                          float(Decimal(h).quantize(Decimal('0.01'))), i, j)
                 new_data.append(datum)
         self.assertEqual(new_report, usage_report[k])
コード例 #9
0
ファイル: api.py プロジェクト: young8/dough
def query_report(context, timestamp_from=None, timestamp_to=None,
                  period=None, item_name=None, resource_name=None, **kwargs):
    """period='days' or 'hours'"""
    print "query_report", timestamp_from, timestamp_to, item_name, resource_name

    if not period in ['days', 'hours', 'months']:
        return {'data': None}

    def find_timeframe(start_time, end_time, target):
        target_utc = target.replace(tzinfo=UTC_TIMEZONE)
        current_frame = start_time
        cnt = 1
        while current_frame < end_time:
            foo = {period: cnt}
            next_frame = start_time + relativedelta(**foo)
            if current_frame <= target_utc < next_frame:
                break
            cnt += 1
            current_frame = next_frame
        assert(current_frame < end_time)
        return current_frame.isoformat()

    monthly_report = dict()
    datetime_from = iso8601.parse_date(timestamp_from)
    datetime_to = iso8601.parse_date(timestamp_to)
    subscriptions = list()
    _subscriptions = list()

    __subscriptions = db.subscription_get_all_by_project(context,
                                                        context.project_id)
    if not __subscriptions:
        return {'data': None}
    for subscription in __subscriptions:
        if subscription['resource_name'] != resource_name:
            continue
        elif subscription['product']['item']['name'] != item_name:
            continue
        _subscriptions.append(subscription)

    for subscription in _subscriptions:
        subscription_id = subscription['id']
        resource_uuid = subscription['resource_uuid']
        resource_name = subscription['resource_name']
        created_at = subscription['created_at']
        expires_at = subscription['expires_at']
        region_name = subscription['product']['region']['name']
        item_name = subscription['product']['item']['name']
        item_type_name = subscription['product']['item_type']['name']
        order_unit = subscription['product']['order_unit']
        order_size = subscription['product']['order_size']
        price = subscription['product']['price']
        currency = subscription['product']['currency']
        subscriptions.append([subscription_id, resource_uuid, resource_name,
                              created_at, expires_at,
                              region_name, item_name, item_type_name,
                              order_unit, order_size, price, currency])
    for (subscription_id, resource_uuid, resource_name, created_at, expires_at,
         region_name, item_name, item_type_name,
         order_unit, order_size, price, currency) in subscriptions:
        purchases = db.purchase_get_all_by_subscription_and_timeframe(context,
                                                            subscription_id,
                                                            datetime_from,
                                                            datetime_to)
        if not purchases:
            continue
        i = 0
        for purchase in purchases:
            line_total = purchase['line_total']
            quantity = purchase['quantity']
            timeframe = find_timeframe(datetime_from,
                                       datetime_to,
                                       purchase['created_at'])
#            print timeframe
            i += 1
            usage_datum = (resource_uuid, resource_name, item_type_name,
                           order_unit, order_size, price,
                           currency, quantity, line_total,
                           created_at.isoformat(), expires_at.isoformat())
            region_usage = monthly_report.setdefault(region_name, dict())
            monthly_usage = region_usage.setdefault(timeframe, dict())
            monthly_usage.setdefault(item_name, 0)
            monthly_usage[item_name] = usage_datum
            monthly_usage.setdefault("quantity", 0)
            monthly_usage.setdefault("line_total", 0)
            monthly_usage["quantity"] += quantity
            monthly_usage["line_total"] += line_total
        print "total:", i
    return {'data': monthly_report}