Suupport to generate resource consumption list.

Change-Id: I691cad21e63772e00602cb0048974e635dc144a1
This commit is contained in:
lvdongbing 2016-08-14 23:05:17 -04:00
parent 673374761e
commit a1f01ab73e
5 changed files with 54 additions and 14 deletions

View File

@ -68,10 +68,15 @@ class ConsumptionController(object):
'user_id': 'single', 'user_id': 'single',
'start_time': 'single', 'start_time': 'single',
'end_time': 'single', 'end_time': 'single',
'summary': 'single',
} }
params = util.get_allowed_params(req.params, param_whitelist) params = util.get_allowed_params(req.params, param_whitelist)
filters = util.get_allowed_params(req.params, filter_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: if not filters:
filters = None filters = None
statistics = self.rpc_client.consumption_statistics(req.context, statistics = self.rpc_client.consumption_statistics(req.context,

View File

@ -54,11 +54,11 @@ ACTION_STATUSES = (
RPC_PARAMS = ( RPC_PARAMS = (
PARAM_SHOW_DELETED, PARAM_SHOW_NESTED, PARAM_LIMIT, PARAM_MARKER, PARAM_SHOW_DELETED, PARAM_SHOW_NESTED, PARAM_LIMIT, PARAM_MARKER,
PARAM_GLOBAL_PROJECT, PARAM_SHOW_DETAILS, 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', 'show_deleted', 'show_nested', 'limit', 'marker',
'global_project', 'show_details', 'global_project', 'show_details',
'sort_dir', 'sort_keys', 'sort_dir', 'sort_keys', 'summary',
) )
USER_KEYS = ( USER_KEYS = (

View File

@ -167,7 +167,10 @@ def format_time_to_seconds(t):
if isinstance(t, datetime.datetime): if isinstance(t, datetime.datetime):
return (t - epoch).total_seconds() return (t - epoch).total_seconds()
if isinstance(t, six.string_types): if isinstance(t, six.string_types):
try:
dt = timeutils.parse_strtime(t) dt = timeutils.parse_strtime(t)
except ValueError:
dt = timeutils.normalize_time(timeutils.parse_isotime(t))
return (dt - epoch).total_seconds() return (dt - epoch).total_seconds()
return t return t

View File

@ -690,6 +690,7 @@ class EngineService(service.Service):
def consumption_list(self, cnxt, user_id=None, limit=None, def consumption_list(self, cnxt, user_id=None, limit=None,
marker=None, sort_keys=None, sort_dir=None, marker=None, sort_keys=None, sort_dir=None,
filters=None, project_safe=True): filters=None, project_safe=True):
user_id = user_id or cnxt.project
if limit is not None: if limit is not None:
limit = utils.parse_int_param('limit', limit) limit = utils.parse_int_param('limit', limit)
@ -705,8 +706,9 @@ class EngineService(service.Service):
@request_context @request_context
def consumption_statistics(self, cnxt, user_id=None, filters=None, 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): project_safe=True):
user_id = user_id or cnxt.project
result = {} result = {}
if start_time is None: if start_time is None:
start_time = 0 start_time = 0
@ -732,10 +734,18 @@ class EngineService(service.Service):
st = max(cons.start_time, start_time) st = max(cons.start_time, start_time)
seconds = et - st seconds = et - st
cost = cons.rate * seconds cost = cons.rate * seconds
if summary:
if cons.resource_type not in result: if cons.resource_type not in result:
result[cons.resource_type] = cost result[cons.resource_type] = cost
else: else:
result[cons.resource_type] += cost result[cons.resource_type] += cost
else:
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, resources = plugin_base.Resource.load_all(cnxt, user_id=user_id,
filters=filters, filters=filters,
@ -747,11 +757,32 @@ class EngineService(service.Service):
st = max(res.last_bill, start_time) st = max(res.last_bill, start_time)
seconds = et - st seconds = et - st
cost = res.rate * seconds cost = res.rate * seconds
if summary:
if res.resource_type not in result: if res.resource_type not in result:
result[res.resource_type] = cost result[res.resource_type] = cost
else: else:
result[res.resource_type] += cost result[res.resource_type] += cost
else:
if res.id not in result:
tmp = {'resource_type': res.resource_type,
'cost': cost}
result[res.id] = tmp
else:
result[res.id]['cost'] += cost
if summary:
for key in six.iterkeys(result): for key in six.iterkeys(result):
result[key] = utils.dec2str(result[key]) result[key] = utils.dec2str(result[key])
return result 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

View File

@ -224,11 +224,12 @@ class EngineClient(object):
project_safe=project_safe)) project_safe=project_safe))
def consumption_statistics(self, ctxt, user_id=None, filters=None, 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): project_safe=True):
return self.call(ctxt, self.make_msg('consumption_statistics', return self.call(ctxt, self.make_msg('consumption_statistics',
user_id=user_id, user_id=user_id,
filters=filters, filters=filters,
start_time=start_time, start_time=start_time,
end_time=end_time, end_time=end_time,
summary=summary,
project_safe=project_safe)) project_safe=project_safe))