Create telemetry client
Create telemetry client for tempest
Change-Id: I08c9b6a02bcddd8cab2d066928513b4ae40431ec
Partially implements: blueprint add-basic-ceilometer-tests
diff --git a/tempest/clients.py b/tempest/clients.py
index 65b603b..4c40ce0 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -143,6 +143,10 @@
ObjectClientCustomizedHeader
from tempest.services.orchestration.json.orchestration_client import \
OrchestrationClient
+from tempest.services.telemetry.json.telemetry_client import \
+ TelemetryClientJSON
+from tempest.services.telemetry.xml.telemetry_client import \
+ TelemetryClientXML
from tempest.services.volume.json.admin.volume_hosts_client import \
VolumeHostsClientJSON
from tempest.services.volume.json.admin.volume_types_client import \
@@ -256,6 +260,8 @@
if client_args_v3_auth:
self.servers_client_v3_auth = ServersClientXML(
*client_args_v3_auth)
+ if CONF.service_available.ceilometer:
+ self.telemetry_client = TelemetryClientXML(*client_args)
elif interface == 'json':
self.certificates_client = CertificatesClientJSON(*client_args)
@@ -318,6 +324,8 @@
self.volumes_extension_client = VolumeExtensionClientJSON(
*client_args)
self.hosts_v3_client = HostsV3ClientJSON(*client_args)
+ if CONF.service_available.ceilometer:
+ self.telemetry_client = TelemetryClientJSON(*client_args)
if client_args_v3_auth:
self.servers_client_v3_auth = ServersClientJSON(
diff --git a/tempest/services/telemetry/__init__.py b/tempest/services/telemetry/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/services/telemetry/__init__.py
diff --git a/tempest/services/telemetry/json/__init__.py b/tempest/services/telemetry/json/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/services/telemetry/json/__init__.py
diff --git a/tempest/services/telemetry/json/telemetry_client.py b/tempest/services/telemetry/json/telemetry_client.py
new file mode 100644
index 0000000..8d46bf3
--- /dev/null
+++ b/tempest/services/telemetry/json/telemetry_client.py
@@ -0,0 +1,52 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2014 OpenStack Foundation
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest.common.rest_client import RestClient
+from tempest.openstack.common import jsonutils as json
+import tempest.services.telemetry.telemetry_client_base as client
+
+
+class TelemetryClientJSON(client.TelemetryClientBase):
+
+ def get_rest_client(self, config, username,
+ password, auth_url, tenant_name=None):
+ return RestClient(config, username, password, auth_url, tenant_name)
+
+ def deserialize(self, body):
+ return json.loads(body.replace("\n", ""))
+
+ def serialize(self, body):
+ return json.dumps(body)
+
+ def create_alarm(self, **kwargs):
+ uri = "%s/alarms" % self.uri_prefix
+ return self.post(uri, kwargs)
+
+ def add_sample(self, sample_list, meter_name, meter_unit, volume,
+ sample_type, resource_id, **kwargs):
+ sample = {"counter_name": meter_name, "counter_unit": meter_unit,
+ "counter_volume": volume, "counter_type": sample_type,
+ "resource_id": resource_id}
+ for key in kwargs:
+ sample[key] = kwargs[key]
+
+ sample_list.append(self.serialize(sample))
+ return sample_list
+
+ def create_sample(self, meter_name, sample_list):
+ uri = "%s/meters/%s" % (self.uri_prefix, meter_name)
+ return self.post(uri, str(sample_list))
diff --git a/tempest/services/telemetry/telemetry_client_base.py b/tempest/services/telemetry/telemetry_client_base.py
new file mode 100644
index 0000000..59127b9
--- /dev/null
+++ b/tempest/services/telemetry/telemetry_client_base.py
@@ -0,0 +1,133 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 OpenStack Foundation
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import abc
+import six
+import urllib
+
+
+@six.add_metaclass(abc.ABCMeta)
+class TelemetryClientBase(object):
+
+ """
+ Tempest REST client for Ceilometer V2 API.
+ Implements the following basic Ceilometer abstractions:
+ resources
+ meters
+ alarms
+ queries
+ statistics
+ """
+
+ def __init__(self, config, username, password, auth_url, tenant_name=None):
+ self.rest_client = self.get_rest_client(config, username, password,
+ auth_url, tenant_name)
+ self.rest_client.service = \
+ self.rest_client.config.telemetry.catalog_type
+ self.headers = self.rest_client.headers
+ self.version = '2'
+ self.uri_prefix = "v%s" % self.version
+
+ @abc.abstractmethod
+ def get_rest_client(self, config, username, password,
+ auth_url, tenant_name):
+ """
+ :param config:
+ :param username:
+ :param password:
+ :param auth_url:
+ :param tenant_name:
+ :return: RestClient
+ """
+
+ @abc.abstractmethod
+ def deserialize(self, body):
+ """
+ :param body:
+ :return: Deserialize body
+ """
+
+ @abc.abstractmethod
+ def serialize(self, body):
+ """
+ :param body:
+ :return: Serialize body
+ """
+
+ def post(self, uri, body):
+ body = self.serialize(body)
+ resp, body = self.rest_client.post(uri, body, self.headers)
+ body = self.deserialize(body)
+ return resp, body
+
+ def put(self, uri, body):
+ return self.rest_client.put(uri, body, self.headers)
+
+ def get(self, uri):
+ resp, body = self.rest_client.get(uri)
+ body = self.deserialize(body)
+ return resp, body
+
+ def delete(self, uri):
+ resp, body = self.rest_client.delete(uri)
+ if body:
+ body = self.deserialize(body)
+ return resp, body
+
+ def helper_list(self, uri, query=None, period=None):
+ uri_dict = {}
+ if query:
+ uri_dict = {'q.field': query[0],
+ 'q.op': query[1],
+ 'q.value': query[2]}
+ if period:
+ uri_dict['period'] = period
+ if uri_dict:
+ uri += "?%s" % urllib.urlencode(uri_dict)
+ return self.get(uri)
+
+ def list_resources(self):
+ uri = '%s/resources' % self.uri_prefix
+ return self.get(uri)
+
+ def list_meters(self):
+ uri = '%s/meters' % self.uri_prefix
+ return self.get(uri)
+
+ def list_alarms(self):
+ uri = '%s/alarms' % self.uri_prefix
+ return self.get(uri)
+
+ def list_statistics(self, meter, period=None, query=None):
+ uri = "%s/meters/%s/statistics" % (self.uri_prefix, meter)
+ return self.helper_list(uri, query, period)
+
+ def list_samples(self, meter_id, query=None):
+ uri = '%s/meters/%s' % (self.uri_prefix, meter_id)
+ return self.helper_list(uri, query)
+
+ def get_resource(self, resource_id):
+ uri = '%s/resources/%s' % (self.uri_prefix, resource_id)
+ return self.get(uri)
+
+ def get_alarm(self, alarm_id):
+ uri = '%s/meter/%s' % (self.uri_prefix, alarm_id)
+ return self.get(uri)
+
+ def delete_alarm(self, alarm_id):
+ uri = "%s/alarms/%s" % (self.uri_prefix, alarm_id)
+ return self.delete(uri)
diff --git a/tempest/services/telemetry/xml/__init__.py b/tempest/services/telemetry/xml/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/services/telemetry/xml/__init__.py
diff --git a/tempest/services/telemetry/xml/telemetry_client.py b/tempest/services/telemetry/xml/telemetry_client.py
new file mode 100644
index 0000000..245ccb5
--- /dev/null
+++ b/tempest/services/telemetry/xml/telemetry_client.py
@@ -0,0 +1,42 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2014 OpenStack Foundation
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from lxml import etree
+
+from tempest.common.rest_client import RestClientXML
+from tempest.services.compute.xml.common import Document
+from tempest.services.compute.xml.common import xml_to_json
+import tempest.services.telemetry.telemetry_client_base as client
+
+
+class TelemetryClientXML(client.TelemetryClientBase):
+
+ def get_rest_client(self, config, username,
+ password, auth_url, tenant_name=None):
+ return RestClientXML(config, username, password, auth_url, tenant_name)
+
+ def _parse_array(self, body):
+ array = []
+ for child in body.getchildren():
+ array.append(xml_to_json(child))
+ return array
+
+ def serialize(self, body):
+ return str(Document(body))
+
+ def deserialize(self, body):
+ return self._parse_array(etree.fromstring(body))