diff --git a/cloudkitty/api/v1/controllers/rating.py b/cloudkitty/api/v1/controllers/rating.py index 56bca26d..fa422b2e 100644 --- a/cloudkitty/api/v1/controllers/rating.py +++ b/cloudkitty/api/v1/controllers/rating.py @@ -14,6 +14,7 @@ # under the License. # from oslo_concurrency import lockutils +from oslo_log import log import pecan from pecan import rest from stevedore import extension @@ -26,6 +27,8 @@ from cloudkitty import utils as ck_utils PROCESSORS_NAMESPACE = 'cloudkitty.rating.processors' +LOG = log.getLogger(__name__) + class RatingModulesMixin(object): def reload_extensions(self): @@ -202,7 +205,8 @@ class RatingController(rest.RestController): json_data = res.to_json() res_dict[res.service].extend(json_data[res.service]) - res = client.call({}, 'quote', res_data=[{'usage': res_dict}]) + LOG.debug("Calling quote method with data: [%s].", res_dict) + res = client.call({}, 'quote', res_data={'usage': res_dict}) return res @wsme_pecan.wsexpose(None) diff --git a/cloudkitty/orchestrator.py b/cloudkitty/orchestrator.py index 97a4eaa7..5546c879 100644 --- a/cloudkitty/orchestrator.py +++ b/cloudkitty/orchestrator.py @@ -115,9 +115,41 @@ class RatingEndpoint(object): return module_list def quote(self, ctxt, res_data): - LOG.debug('Received quote from RPC.') + LOG.debug('Received quote request [%s] from RPC.', res_data) worker = APIWorker() - return str(worker.quote(res_data)) + + start = tzutils.localized_now() + end = tzutils.add_delta(start, timedelta(seconds=CONF.collect.period)) + + # Need to prepare data to support the V2 processing format + usage = {} + for k in res_data['usage']: + all_data_points_for_metric = [] + all_quote_data_entries = res_data['usage'][k] + for p in all_quote_data_entries: + vol = p['vol'] + desc = p.get('desc', {}) + + data_point = dataframe.DataPoint( + vol['unit'], + vol['qty'], + 0, + desc.get('groupby', []), + desc.get('metadata', []), + ) + all_data_points_for_metric.append(data_point) + usage[k] = all_data_points_for_metric + + frame = dataframe.DataFrame( + start=start, + end=end, + usage=usage, + ) + + quote_result = worker.quote(frame) + LOG.debug("Quote result [%s] for input data [%s].", + quote_result, res_data) + return str(quote_result) def reload_modules(self, ctxt): LOG.info('Received reload modules command.') @@ -219,15 +251,13 @@ class APIWorker(BaseWorker): super(APIWorker, self).__init__(tenant_id) def quote(self, res_data): + quote_result = res_data for processor in self._processors: - processor.obj.quote(res_data) + quote_result = processor.obj.quote(quote_result) price = decimal.Decimal(0) - for res in res_data: - for res_usage in res['usage'].values(): - for data in res_usage: - price += data.get('rating', {}).get('price', - decimal.Decimal(0)) + for _, point in quote_result.iterpoints(): + price += point.price return price diff --git a/releasenotes/notes/fix-quote-v1-api-7282f01b596f0f3b.yaml b/releasenotes/notes/fix-quote-v1-api-7282f01b596f0f3b.yaml new file mode 100644 index 00000000..9dca5285 --- /dev/null +++ b/releasenotes/notes/fix-quote-v1-api-7282f01b596f0f3b.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Fixes the quote API method. See story 2009022 + `_ for more details.