diff --git a/bilean/api/openstack/v1/consumptions.py b/bilean/api/openstack/v1/consumptions.py index 6efab17..0e9b872 100644 --- a/bilean/api/openstack/v1/consumptions.py +++ b/bilean/api/openstack/v1/consumptions.py @@ -68,10 +68,15 @@ class ConsumptionController(object): 'user_id': 'single', 'start_time': 'single', 'end_time': 'single', + 'summary': 'single', } params = util.get_allowed_params(req.params, param_whitelist) filters = util.get_allowed_params(req.params, filter_whitelist) + key = consts.PARAM_SUMMARY + if key in params: + params[key] = utils.parse_bool_param(key, params[key]) + if not filters: filters = None statistics = self.rpc_client.consumption_statistics(req.context, diff --git a/bilean/common/consts.py b/bilean/common/consts.py index d377551..18ea73c 100644 --- a/bilean/common/consts.py +++ b/bilean/common/consts.py @@ -54,11 +54,11 @@ ACTION_STATUSES = ( RPC_PARAMS = ( PARAM_SHOW_DELETED, PARAM_SHOW_NESTED, PARAM_LIMIT, PARAM_MARKER, PARAM_GLOBAL_PROJECT, PARAM_SHOW_DETAILS, - PARAM_SORT_DIR, PARAM_SORT_KEYS, + PARAM_SORT_DIR, PARAM_SORT_KEYS, PARAM_SUMMARY, ) = ( 'show_deleted', 'show_nested', 'limit', 'marker', 'global_project', 'show_details', - 'sort_dir', 'sort_keys', + 'sort_dir', 'sort_keys', 'summary', ) USER_KEYS = ( diff --git a/bilean/common/utils.py b/bilean/common/utils.py index 17bc9cb..1b2bbd5 100644 --- a/bilean/common/utils.py +++ b/bilean/common/utils.py @@ -167,7 +167,10 @@ def format_time_to_seconds(t): if isinstance(t, datetime.datetime): return (t - epoch).total_seconds() if isinstance(t, six.string_types): - dt = timeutils.parse_strtime(t) + try: + dt = timeutils.parse_strtime(t) + except ValueError: + dt = timeutils.normalize_time(timeutils.parse_isotime(t)) return (dt - epoch).total_seconds() return t diff --git a/bilean/engine/service.py b/bilean/engine/service.py index c4f9f73..24da767 100644 --- a/bilean/engine/service.py +++ b/bilean/engine/service.py @@ -690,6 +690,7 @@ class EngineService(service.Service): def consumption_list(self, cnxt, user_id=None, limit=None, marker=None, sort_keys=None, sort_dir=None, filters=None, project_safe=True): + user_id = user_id or cnxt.project if limit is not None: limit = utils.parse_int_param('limit', limit) @@ -705,8 +706,9 @@ class EngineService(service.Service): @request_context def consumption_statistics(self, cnxt, user_id=None, filters=None, - start_time=None, end_time=None, + start_time=None, end_time=None, summary=False, project_safe=True): + user_id = user_id or cnxt.project result = {} if start_time is None: start_time = 0 @@ -732,10 +734,18 @@ class EngineService(service.Service): st = max(cons.start_time, start_time) seconds = et - st cost = cons.rate * seconds - if cons.resource_type not in result: - result[cons.resource_type] = cost + if summary: + if cons.resource_type not in result: + result[cons.resource_type] = cost + else: + result[cons.resource_type] += cost else: - result[cons.resource_type] += cost + if cons.resource_id not in result: + tmp = {'resource_type': cons.resource_type, + 'cost': cost} + result[cons.resource_id] = tmp + else: + result[cons.resource_id]['cost'] += cost resources = plugin_base.Resource.load_all(cnxt, user_id=user_id, filters=filters, @@ -747,11 +757,32 @@ class EngineService(service.Service): st = max(res.last_bill, start_time) seconds = et - st cost = res.rate * seconds - if res.resource_type not in result: - result[res.resource_type] = cost + if summary: + if res.resource_type not in result: + result[res.resource_type] = cost + else: + result[res.resource_type] += cost else: - result[res.resource_type] += cost + if res.id not in result: + tmp = {'resource_type': res.resource_type, + 'cost': cost} + result[res.id] = tmp + else: + result[res.id]['cost'] += cost - for key in six.iterkeys(result): - result[key] = utils.dec2str(result[key]) - return result + if summary: + for key in six.iterkeys(result): + result[key] = utils.dec2str(result[key]) + return result + else: + consumptions = [] + for key in six.iterkeys(result): + consumption = cons_mod.Consumption( + user_id, + resource_id=key, + resource_type=result[key]['resource_type'], + cost=result[key]['cost'], + start_time=start_time, + end_time=end_time) + consumptions.append(consumption.to_dict()) + return consumptions diff --git a/bilean/rpc/client.py b/bilean/rpc/client.py index a0ea46c..f9848f9 100644 --- a/bilean/rpc/client.py +++ b/bilean/rpc/client.py @@ -224,11 +224,12 @@ class EngineClient(object): project_safe=project_safe)) def consumption_statistics(self, ctxt, user_id=None, filters=None, - start_time=None, end_time=None, + start_time=None, end_time=None, summary=False, project_safe=True): return self.call(ctxt, self.make_msg('consumption_statistics', user_id=user_id, filters=filters, start_time=start_time, end_time=end_time, + summary=summary, project_safe=project_safe))