def test_dict_to_querystring(self): expected = [ "start=2016-02-10T13%3A54%3A53%2B00%3A00" "&stop=2016-02-10T13%3A56%3A42%2B02%3A00", "stop=2016-02-10T13%3A56%3A42%2B02%3A00" "&start=2016-02-10T13%3A54%3A53%2B00%3A00" ] self.assertIn( utils.dict_to_querystring({ "start": "2016-02-10T13:54:53+00:00", "stop": "2016-02-10T13:56:42+02:00" }), expected) self.assertEqual( "groupby=foo&groupby=bar", utils.dict_to_querystring({"groupby": ["foo", "bar"]}), ) self.assertEqual( "groupby=foo&groupby=bar&overlap=0", utils.dict_to_querystring({ "groupby": ["foo", "bar"], "overlap": 0, }), )
def test_dict_to_querystring(self): expected = ["start=2016-02-10T13%3A54%3A53%2B00%3A00" "&stop=2016-02-10T13%3A56%3A42%2B02%3A00", "stop=2016-02-10T13%3A56%3A42%2B02%3A00" "&start=2016-02-10T13%3A54%3A53%2B00%3A00"] self.assertIn(utils.dict_to_querystring( {"start": "2016-02-10T13:54:53+00:00", "stop": "2016-02-10T13:56:42+02:00"}), expected) self.assertEqual( "groupby=foo&groupby=bar", utils.dict_to_querystring({ "groupby": ["foo", "bar"] }), ) self.assertEqual( "groupby=foo&groupby=bar&overlap=0", utils.dict_to_querystring({ "groupby": ["foo", "bar"], "overlap": 0, }), )
def search(self, resource_type="generic", query=None, details=False, history=False, limit=None, marker=None, sorts=None): """List resources. :param resource_type: Type of the resource :type resource_type: str :param query: The query dictionary :type query: dict :param details: Show all attributes of resources :type details: bool :param history: Show the history of resources :type history: bool :param limit: maximum number of resources to return :type limit: int :param marker: the last item of the previous page; we returns the next results after this value. :type marker: str :param sorts: list of resource attributes to order by. (example ["user_id:desc-nullslast", "project_id:asc"] :type sorts: list of str See Gnocchi REST API documentation for the format of *query dictionary* http://gnocchi.osci.io/rest.html#searching-for-resources """ query = query or {} params = utils.build_pagination_options(details, history, limit, marker, sorts) url = "v1/search/resource/%s?%%s" % resource_type if isinstance(query, dict): return self._post(url % utils.dict_to_querystring(params), headers={ 'Content-Type': "application/json" }, data=ujson.dumps(query)).json() params['filter'] = query return self._post(url % utils.dict_to_querystring(params), headers={ 'Content-Type': "application/json" }).json()
def list(self, limit=None, marker=None, sorts=None): """List metrics. :param limit: maximum number of resources to return :type limit: int :param marker: the last item of the previous page; we return the next results after this value. :type marker: str :param sorts: list of resource attributes to order by. (example ["user_id:desc-nullslast", "project_id:asc"] :type sorts: list of str """ params = utils.build_pagination_options(False, False, limit, marker, sorts) metrics = [] page_url = "%s?%s" % (self.metric_url[:-1], utils.dict_to_querystring(params)) while page_url: page = self._get(page_url) metrics.extend(page.json()) if limit is None or len(metrics) < limit: page_url = page.links.get("next", {'url': None})['url'] else: break return metrics
def history(self, resource_type, resource_id, details=False, limit=None, marker=None, sorts=None): """Get a resource. :param resource_type: Type of the resource :type resource_type: str :param resource_id: ID of the resource :type resource_id: str :param details: Show all attributes of resources :type details: bool :param limit: maximum number of resources to return :type limit: int :param marker: the last item of the previous page; we returns the next results after this value. :type marker: str :param sorts: list of resource attributes to order by. (example ["user_id:desc-nullslast", "project_id:asc"] :type sorts: list of str """ params = utils.build_pagination_options(details, False, limit, marker, sorts) url = "%s%s/%s/history?%s" % (self.url, resource_type, resource_id, utils.dict_to_querystring(params)) return self._get(url).json()
def test_dict_to_querystring(self): expected = ["start=2016-02-10T13%3A54%3A53%2B00%3A00" "&stop=2016-02-10T13%3A56%3A42%2B02%3A00", "stop=2016-02-10T13%3A56%3A42%2B02%3A00" "&start=2016-02-10T13%3A54%3A53%2B00%3A00"] self.assertIn(utils.dict_to_querystring( {"start": "2016-02-10T13:54:53+00:00", "stop": "2016-02-10T13:56:42+02:00"}), expected)
def test_dict_to_querystring(self): expected = [ "start=2016-02-10T13%3A54%3A53%2B00%3A00" "&stop=2016-02-10T13%3A56%3A42%2B02%3A00", "stop=2016-02-10T13%3A56%3A42%2B02%3A00" "&start=2016-02-10T13%3A54%3A53%2B00%3A00" ] self.assertIn( utils.dict_to_querystring({ "start": "2016-02-10T13:54:53+00:00", "stop": "2016-02-10T13:56:42+02:00" }), expected)
def aggregation(self, metrics, query=None, start=None, stop=None, aggregation=None, needed_overlap=None, resource_type="generic"): """Get measurements of a aggregated metrics :param metrics: IDs of metric or metric name :type metric: list or str :param query: The query dictionary :type query: dict :param start: beginning of the period :type start: timestamp :param stop: end of the period :type stop: timestamp :param aggregation: aggregation to retrieve :type aggregation: str :param resource_type: type of resource for the query :type resource_type: str See Gnocchi REST API documentation for the format of *query dictionary* http://docs.openstack.org/developer/gnocchi/rest.html#searching-for-resources """ if isinstance(start, datetime.datetime): start = start.isoformat() if isinstance(stop, datetime.datetime): stop = stop.isoformat() params = dict(start=start, stop=stop, aggregation=aggregation, needed_overlap=needed_overlap) if query is None: for metric in metrics: self._ensure_metric_is_uuid(metric) params['metric'] = metrics return self._get("v1/aggregation/metric", params=params).json() else: return self._post( "v1/aggregation/resource/%s/metric/%s?%s" % (resource_type, metrics, utils.dict_to_querystring(params)), headers={ 'Content-Type': "application/json" }, data=jsonutils.dumps(query)).json()
def aggregation(self, metrics, query=None, start=None, stop=None, aggregation=None, needed_overlap=None, resource_type="generic"): """Get measurements of a aggregated metrics :param metrics: IDs of metric or metric name :type metric: list or str :param query: The query dictionary :type query: dict :param start: beginning of the period :type start: timestamp :param stop: end of the period :type stop: timestamp :param aggregation: aggregation to retrieve :type aggregation: str :param resource_type: type of resource for the query :type resource_type: str See Gnocchi REST API documentation for the format of *query dictionary* http://docs.openstack.org/developer/gnocchi/rest.html#searching-for-resources """ if isinstance(start, datetime.datetime): start = start.isoformat() if isinstance(stop, datetime.datetime): stop = stop.isoformat() params = dict(start=start, stop=stop, aggregation=aggregation, needed_overlap=needed_overlap) if query is None: for metric in metrics: self._ensure_metric_is_uuid(metric) params['metric'] = metrics return self._get("v1/aggregation/metric", params=params).json() else: return self._post( "v1/aggregation/resource/%s/metric/%s?%s" % ( resource_type, metrics, utils.dict_to_querystring(params)), headers={'Content-Type': "application/json"}, data=jsonutils.dumps(query)).json()
def aggregation(self, metrics, query=None, start=None, stop=None, aggregation=None, reaggregation=None, granularity=None, needed_overlap=None, resource_type="generic", groupby=None, refresh=False, resample=None, fill=None): """Get measurements of an aggregated metrics :param metrics: IDs of metric or metric name :type metric: list or str :param query: The query dictionary :type query: dict :param start: beginning of the period :type start: timestamp :param stop: end of the period :type stop: timestamp :param aggregation: granularity aggregation function to retrieve :type aggregation: str :param reaggregation: groupby aggregation function to retrieve :type reaggregation: str :param granularity: granularity to retrieve (in seconds) :type granularity: int :param needed_overlap: percent of datapoints in each metrics required :type needed_overlap: float :param resource_type: type of resource for the query :type resource_type: str :param groupby: list of attribute to group by :type groupby: list :param refresh: force aggregation of all known measures :type refresh: bool :param resample: resample measures to new granularity :type resample: float :param fill: value to use when backfilling missing datapoints :type fill: float or 'null' See Gnocchi REST API documentation for the format of *query dictionary* http://docs.openstack.org/developer/gnocchi/rest.html#searching-for-resources """ if isinstance(start, datetime.datetime): start = start.isoformat() if isinstance(stop, datetime.datetime): stop = stop.isoformat() params = dict(start=start, stop=stop, aggregation=aggregation, reaggregation=reaggregation, granularity=granularity, needed_overlap=needed_overlap, groupby=groupby, refresh=refresh, resample=resample, fill=fill) if query is None: for metric in metrics: self._ensure_metric_is_uuid(metric) params['metric'] = metrics measures = self._get("v1/aggregation/metric", params=params).json() else: measures = self._post( "v1/aggregation/resource/%s/metric/%s?%s" % (resource_type, metrics, utils.dict_to_querystring(params)), headers={ 'Content-Type': "application/json" }, data=ujson.dumps(query)).json() if groupby is None: return [(iso8601.parse_date(ts), g, value) for ts, g, value in measures] for group in measures: group["measures"] = [(iso8601.parse_date(ts), g, value) for ts, g, value in group["measures"]] return measures
def fetch(self, operations, search=None, resource_type='generic', start=None, stop=None, granularity=None, needed_overlap=None, groupby=None, fill=None, details=False): """Get measurements of an aggregated metrics. :param operations: operations :type operations: list or str :param start: beginning of the period :type start: timestamp :param stop: end of the period :type stop: timestamp :param granularity: granularity to retrieve (in seconds) :type granularity: int :param needed_overlap: percent of datapoints in each metrics required :type needed_overlap: float :param groupby: list of attribute to group by :type groupby: list :param fill: value to use when backfilling missing datapoints :type fill: float or 'null' :param details: also returns the list of metrics or resources associated to the operations :type details: boolean See Gnocchi REST API documentation for the format of *query dictionary* http://docs.openstack.org/developer/gnocchi/rest.html#aggregates """ if isinstance(start, datetime.datetime): start = start.isoformat() if isinstance(stop, datetime.datetime): stop = stop.isoformat() params = dict(start=start, stop=stop, granularity=granularity, needed_overlap=needed_overlap, fill=fill, details=details) data = dict(operations=operations) if search is not None: data["search"] = search data["resource_type"] = resource_type params["groupby"] = groupby aggregates = self._post("v1/aggregates?%s" % (utils.dict_to_querystring(params)), headers={ 'Content-Type': "application/json" }, data=ujson.dumps(data)).json() if search is not None and groupby is not None: for group in aggregates: self._convert_dates(group["measures"]["measures"]) else: self._convert_dates(aggregates["measures"]) return aggregates
def aggregation(self, metrics, query=None, start=None, stop=None, aggregation=None, reaggregation=None, granularity=None, needed_overlap=None, resource_type="generic", groupby=None, refresh=False, resample=None, fill=None): """Get measurements of an aggregated metrics :param metrics: IDs of metric or metric name :type metric: list or str :param query: The query dictionary :type query: dict :param start: beginning of the period :type start: timestamp :param stop: end of the period :type stop: timestamp :param aggregation: granularity aggregation function to retrieve :type aggregation: str :param reaggregation: groupby aggregation function to retrieve :type reaggregation: str :param granularity: granularity to retrieve (in seconds) :type granularity: int :param needed_overlap: percent of datapoints in each metrics required :type needed_overlap: float :param resource_type: type of resource for the query :type resource_type: str :param groupby: list of attribute to group by :type groupby: list :param refresh: force aggregation of all known measures :type refresh: bool :param resample: resample measures to new granularity :type resample: float :param fill: value to use when backfilling missing datapoints :type fill: float or 'null' See Gnocchi REST API documentation for the format of *query dictionary* http://docs.openstack.org/developer/gnocchi/rest.html#searching-for-resources """ if isinstance(start, datetime.datetime): start = start.isoformat() if isinstance(stop, datetime.datetime): stop = stop.isoformat() params = dict(start=start, stop=stop, aggregation=aggregation, reaggregation=reaggregation, granularity=granularity, needed_overlap=needed_overlap, groupby=groupby, refresh=refresh, resample=resample, fill=fill) if query is None: for metric in metrics: self._ensure_metric_is_uuid(metric) params['metric'] = metrics measures = self._get("v1/aggregation/metric", params=params).json() else: measures = self._post( "v1/aggregation/resource/%s/metric/%s?%s" % ( resource_type, metrics, utils.dict_to_querystring(params)), headers={'Content-Type': "application/json"}, data=ujson.dumps(query)).json() if groupby is None: return [(iso8601.parse_date(ts), g, value) for ts, g, value in measures] for group in measures: group["measures"] = [ (iso8601.parse_date(ts), g, value) for ts, g, value in group["measures"] ] return measures