tempest: migrate api and scnario tests from tempest
tempest: use ceilometer client manager instead of tempest one
This patch replaces client manager used in base test class from tempest
one to ceilometer dedicated manager which only has clients necessary to
specific ceilometer test cases.
The conflicts in config parameter are solved by adding '_plugin' in
paramter names as suffix.
This patch also includes the following changes in tempest.
- Ie99bbbe7655138c4c3ecae69ae0b361198a9651d
- I340d96c27f0e906df5b8a109494920e9cd3b21d1
- I14e16a1a7d9813b324ee40545c07f0e88fb637b7
Closes-Bug: 1549424
Depends-On: Ifc29617743b76b01eb6cd30a375cf47b56e4f635
Implements: blueprint tempest-plugin
Change-Id: Ifbe3152c486ddba79bb851c0ec3097213975f95c
diff --git a/ceilometer/tests/tempest/api/base.py b/ceilometer/tests/tempest/api/base.py
index 938bc88..103a123 100644
--- a/ceilometer/tests/tempest/api/base.py
+++ b/ceilometer/tests/tempest/api/base.py
@@ -13,27 +13,43 @@
import time
from oslo_utils import timeutils
-from tempest_lib import exceptions as lib_exc
-
from tempest.common import compute
from tempest.common.utils import data_utils
from tempest import config
from tempest import exceptions
+from tempest.lib import exceptions as lib_exc
import tempest.test
+from ceilometer.tests.tempest.service import client
+
+
CONF = config.CONF
+class ClientManager(client.Manager):
+
+ load_clients = [
+ 'servers_client',
+ 'compute_networks_client',
+ 'compute_floating_ips_client',
+ 'flavors_client',
+ 'image_client',
+ 'image_client_v2',
+ 'telemetry_client',
+ ]
+
+
class BaseTelemetryTest(tempest.test.BaseTestCase):
"""Base test case class for all Telemetry API tests."""
credentials = ['primary']
+ client_manager = ClientManager
@classmethod
def skip_checks(cls):
super(BaseTelemetryTest, cls).skip_checks()
- if not CONF.service_available.ceilometer:
+ if not CONF.service_available.ceilometer_plugin:
raise cls.skipException("Ceilometer support is required")
@classmethod
@@ -44,11 +60,11 @@
@classmethod
def setup_clients(cls):
super(BaseTelemetryTest, cls).setup_clients()
- cls.telemetry_client = cls.os.telemetry_client
- cls.servers_client = cls.os.servers_client
- cls.flavors_client = cls.os.flavors_client
- cls.image_client = cls.os.image_client
- cls.image_client_v2 = cls.os.image_client_v2
+ cls.telemetry_client = cls.os_primary.telemetry_client
+ cls.servers_client = cls.os_primary.servers_client
+ cls.flavors_client = cls.os_primary.flavors_client
+ cls.image_client = cls.os_primary.image_client
+ cls.image_client_v2 = cls.os_primary.image_client_v2
@classmethod
def resource_setup(cls):
@@ -67,7 +83,7 @@
def create_server(cls):
tenant_network = cls.get_tenant_network()
body, server = compute.create_test_server(
- cls.os,
+ cls.os_primary,
tenant_network=tenant_network,
name=data_utils.rand_name('ceilometer-instance'),
wait_until='ACTIVE')
@@ -75,10 +91,11 @@
return body
@classmethod
- def create_image(cls, client):
- body = client.create_image(
- data_utils.rand_name('image'), container_format='bare',
- disk_format='raw', visibility='private')
+ def create_image(cls, client, **kwargs):
+ body = client.create_image(name=data_utils.rand_name('image'),
+ container_format='bare',
+ disk_format='raw',
+ **kwargs)
# TODO(jswarren) Move ['image'] up to initial body value assignment
# once both v1 and v2 glance clients include the full response
# object.
diff --git a/ceilometer/tests/tempest/api/test_telemetry_notification_api.py b/ceilometer/tests/tempest/api/test_telemetry_notification_api.py
new file mode 100644
index 0000000..6c1ee6b
--- /dev/null
+++ b/ceilometer/tests/tempest/api/test_telemetry_notification_api.py
@@ -0,0 +1,87 @@
+# 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.
+
+# Change-Id: I14e16a1a7d9813b324ee40545c07f0e88fb637b7
+
+import testtools
+
+from ceilometer.tests.tempest.api import base
+from tempest import config
+from tempest.lib import decorators
+from tempest import test
+
+
+CONF = config.CONF
+
+
+class TelemetryNotificationAPITest(base.BaseTelemetryTest):
+
+ @test.idempotent_id('d7f8c1c8-d470-4731-8604-315d3956caae')
+ @test.services('compute')
+ def test_check_nova_notification(self):
+
+ body = self.create_server()
+
+ query = ('resource', 'eq', body['id'])
+
+ for metric in self.nova_notifications:
+ self.await_samples(metric, query)
+
+ @test.attr(type="smoke")
+ @test.idempotent_id('04b10bfe-a5dc-47af-b22f-0460426bf499')
+ @test.services("image")
+ @testtools.skipIf(not CONF.image_feature_enabled.api_v1,
+ "Glance api v1 is disabled")
+ def test_check_glance_v1_notifications(self):
+ body = self.create_image(self.image_client, is_public=False)
+ self.image_client.update_image(body['id'], data='data')
+
+ query = 'resource', 'eq', body['id']
+
+ self.image_client.delete_image(body['id'])
+
+ for metric in self.glance_notifications:
+ self.await_samples(metric, query)
+
+ @test.attr(type="smoke")
+ @test.idempotent_id('c240457d-d943-439b-8aea-85e26d64fe8f')
+ @test.services("image")
+ @testtools.skipIf(not CONF.image_feature_enabled.api_v2,
+ "Glance api v2 is disabled")
+ def test_check_glance_v2_notifications(self):
+ body = self.create_image(self.image_client_v2, visibility='private')
+
+ self.image_client_v2.store_image_file(body['id'], "file")
+ self.image_client_v2.show_image_file(body['id'])
+
+ query = 'resource', 'eq', body['id']
+
+ for metric in self.glance_v2_notifications:
+ self.await_samples(metric, query)
+
+
+class TelemetryNotificationAdminAPITest(base.BaseTelemetryAdminTest):
+
+ @test.idempotent_id('29604198-8b45-4fc0-8af8-1cae4f94ebea')
+ @test.services('compute')
+ @decorators.skip_because(bug='1480490')
+ def test_check_nova_notification_event_and_meter(self):
+
+ body = self.create_server()
+
+ if CONF.telemetry_plugin.event_enabled:
+ query = ('instance_id', 'eq', body['id'])
+ self.await_events(query)
+
+ query = ('resource', 'eq', body['id'])
+ for metric in self.nova_notifications:
+ self.await_samples(metric, query)
diff --git a/ceilometer/tests/tempest/client.py b/ceilometer/tests/tempest/client.py
deleted file mode 100644
index b0173ef..0000000
--- a/ceilometer/tests/tempest/client.py
+++ /dev/null
@@ -1,116 +0,0 @@
-# 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 oslo_serialization import jsonutils as json
-from six.moves.urllib import parse as urllib
-
-from tempest.common import service_client
-from tempest import config
-from tempest import manager
-
-
-CONF = config.CONF
-
-
-class TelemetryClient(service_client.ServiceClient):
-
- version = '2'
- uri_prefix = "v2"
-
- def deserialize(self, body):
- return json.loads(body.replace("\n", ""))
-
- def serialize(self, body):
- return json.dumps(body)
-
- 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)
- body = self.serialize(sample_list)
- resp, body = self.post(uri, body)
- self.expected_success(200, resp.status)
- body = self.deserialize(body)
- return service_client.ResponseBody(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)
- resp, body = self.get(uri)
- self.expected_success(200, resp.status)
- body = self.deserialize(body)
- return service_client.ResponseBodyList(resp, body)
-
- def list_resources(self, query=None):
- uri = '%s/resources' % self.uri_prefix
- return self._helper_list(uri, query)
-
- def list_meters(self, query=None):
- uri = '%s/meters' % self.uri_prefix
- return self._helper_list(uri, query)
-
- 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 list_events(self, query=None):
- uri = '%s/events' % self.uri_prefix
- return self._helper_list(uri, query)
-
- def show_resource(self, resource_id):
- uri = '%s/resources/%s' % (self.uri_prefix, resource_id)
- resp, body = self.get(uri)
- self.expected_success(200, resp.status)
- body = self.deserialize(body)
- return service_client.ResponseBody(resp, body)
-
-
-class Manager(manager.Manager):
-
- def __init__(self, credentials=None, service=None):
- super(Manager, self).__init__(credentials, service)
- self._set_telemetry_client()
-
- def _set_telemetry_client(self):
- if CONF.service_available.ceilometer:
- self.telemetry_client = TelemetryClient(
- self.auth_provider,
- CONF.telemetry.catalog_type,
- CONF.identity.region,
- endpoint_type=CONF.telemetry.endpoint_type,
- disable_ssl_certificate_validation=(
- CONF.identity.disable_ssl_certificate_validation),
- ca_certs=CONF.identity.ca_certificates_file,
- trace_requests=CONF.debug.trace_requests)
diff --git a/ceilometer/tests/tempest/config.py b/ceilometer/tests/tempest/config.py
index 96dc6a2..a83a509 100644
--- a/ceilometer/tests/tempest/config.py
+++ b/ceilometer/tests/tempest/config.py
@@ -20,12 +20,12 @@
title="Available OpenStack Services")
ServiceAvailableGroup = [
- cfg.BoolOpt('ceilometer',
+ cfg.BoolOpt('ceilometer_plugin',
default=True,
help="Whether or not Ceilometer is expected to be available"),
]
-telemetry_group = cfg.OptGroup(name='telemetry',
+telemetry_group = cfg.OptGroup(name='telemetry_plugin',
title='Telemetry Service Options')
TelemetryGroup = [
@@ -37,4 +37,7 @@
choices=['public', 'admin', 'internal',
'publicURL', 'adminURL', 'internalURL'],
help="The endpoint type to use for the telemetry service."),
+ cfg.BoolOpt('event_enabled',
+ default=True,
+ help="Runs Ceilometer event-related tests"),
]
diff --git a/ceilometer/tests/tempest/scenario/__init__.py b/ceilometer/tests/tempest/scenario/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ceilometer/tests/tempest/scenario/__init__.py
diff --git a/ceilometer/tests/tempest/scenario/test_object_storage_telemetry_middleware.py b/ceilometer/tests/tempest/scenario/test_object_storage_telemetry_middleware.py
new file mode 100644
index 0000000..4bb287d
--- /dev/null
+++ b/ceilometer/tests/tempest/scenario/test_object_storage_telemetry_middleware.py
@@ -0,0 +1,146 @@
+# Copyright 2014 Red Hat
+#
+# 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 oslo_log import log as logging
+from tempest.common.utils import data_utils
+from tempest import config
+from tempest import test
+
+from ceilometer.tests.tempest.service import client
+
+
+CONF = config.CONF
+
+LOG = logging.getLogger(__name__)
+
+# Loop for up to 120 seconds waiting on notifications
+# NOTE(chdent): The choice of 120 seconds is fairly
+# arbitrary: Long enough to give the notifications the
+# chance to travel across a highly latent bus but not
+# so long as to allow excessive latency to never be visible.
+# TODO(chdent): Ideally this value would come from configuration.
+NOTIFICATIONS_WAIT = 120
+NOTIFICATIONS_SLEEP = 1
+
+
+class ClientManager(client.Manager):
+
+ load_clients = [
+ 'telemetry_client',
+ 'container_client',
+ 'object_client',
+ ]
+
+
+class TestObjectStorageTelemetry(test.BaseTestCase):
+ """Test that swift uses the ceilometer middleware.
+
+ * create container.
+ * upload a file to the created container.
+ * retrieve the file from the created container.
+ * wait for notifications from ceilometer.
+ """
+
+ credentials = ['primary']
+ client_manager = ClientManager
+
+ @classmethod
+ def skip_checks(cls):
+ super(TestObjectStorageTelemetry, cls).skip_checks()
+ if not CONF.service_available.swift:
+ skip_msg = ("%s skipped as swift is not available" %
+ cls.__name__)
+ raise cls.skipException(skip_msg)
+ if not CONF.service_available.ceilometer_plugin:
+ skip_msg = ("%s skipped as ceilometer is not available" %
+ cls.__name__)
+ raise cls.skipException(skip_msg)
+
+ @classmethod
+ def setup_credentials(cls):
+ cls.set_network_resources()
+ super(TestObjectStorageTelemetry, cls).setup_credentials()
+
+ @classmethod
+ def setup_clients(cls):
+ super(TestObjectStorageTelemetry, cls).setup_clients()
+ cls.telemetry_client = cls.os_primary.telemetry_client
+ cls.container_client = cls.os_primary.container_client
+ cls.object_client = cls.os_primary.object_client
+
+ def _confirm_notifications(self, container_name, obj_name):
+ # NOTE: Loop seeking for appropriate notifications about the containers
+ # and objects sent to swift.
+
+ def _check_samples():
+ # NOTE: Return True only if we have notifications about some
+ # containers and some objects and the notifications are about
+ # the expected containers and objects.
+ # Otherwise returning False will case _check_samples to be
+ # called again.
+ results = self.telemetry_client.list_samples(
+ 'storage.objects.incoming.bytes')
+ LOG.debug('got samples %s', results)
+
+ # Extract container info from samples.
+ containers, objects = [], []
+ for sample in results:
+ meta = sample['resource_metadata']
+ if meta.get('container') and meta['container'] != 'None':
+ containers.append(meta['container'])
+ elif (meta.get('target.metadata:container') and
+ meta['target.metadata:container'] != 'None'):
+ containers.append(meta['target.metadata:container'])
+
+ if meta.get('object') and meta['object'] != 'None':
+ objects.append(meta['object'])
+ elif (meta.get('target.metadata:object') and
+ meta['target.metadata:object'] != 'None'):
+ objects.append(meta['target.metadata:object'])
+
+ return (container_name in containers and obj_name in objects)
+
+ self.assertTrue(test.call_until_true(_check_samples,
+ NOTIFICATIONS_WAIT,
+ NOTIFICATIONS_SLEEP),
+ 'Correct notifications were not received after '
+ '%s seconds.' % NOTIFICATIONS_WAIT)
+
+ def create_container(self):
+ name = data_utils.rand_name('swift-scenario-container')
+ self.container_client.create_container(name)
+ # look for the container to assure it is created
+ self.container_client.list_container_contents(name)
+ LOG.debug('Container %s created' % (name))
+ self.addCleanup(self.container_client.delete_container,
+ name)
+ return name
+
+ def upload_object_to_container(self, container_name):
+ obj_name = data_utils.rand_name('swift-scenario-object')
+ obj_data = data_utils.arbitrary_string()
+ self.object_client.create_object(container_name, obj_name, obj_data)
+ self.addCleanup(self.object_client.delete_object,
+ container_name,
+ obj_name)
+ return obj_name
+
+ @test.idempotent_id('6d6b88e5-3e38-41bc-b34a-79f713a6cb85')
+ @test.services('object_storage', 'telemetry')
+ def test_swift_middleware_notifies(self):
+ container_name = self.create_container()
+ obj_name = self.upload_object_to_container(container_name)
+ self._confirm_notifications(container_name, obj_name)
diff --git a/ceilometer/tests/tempest/service/__init__.py b/ceilometer/tests/tempest/service/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ceilometer/tests/tempest/service/__init__.py
diff --git a/ceilometer/tests/tempest/service/client.py b/ceilometer/tests/tempest/service/client.py
new file mode 100644
index 0000000..81d67d8
--- /dev/null
+++ b/ceilometer/tests/tempest/service/client.py
@@ -0,0 +1,190 @@
+# 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 oslo_serialization import jsonutils as json
+from six.moves.urllib import parse as urllib
+
+from tempest import config
+from tempest.lib.common import rest_client
+from tempest.lib.services.compute.flavors_client import FlavorsClient
+from tempest.lib.services.compute.floating_ips_client import FloatingIPsClient
+from tempest.lib.services.compute.networks_client import NetworksClient
+from tempest.lib.services.compute.servers_client import ServersClient
+from tempest import manager
+from tempest.services.image.v1.json.images_client import ImagesClient
+from tempest.services.image.v2.json.images_client import ImagesClientV2
+from tempest.services.object_storage.container_client import ContainerClient
+from tempest.services.object_storage.object_client import ObjectClient
+
+
+CONF = config.CONF
+
+
+class TelemetryClient(rest_client.RestClient):
+
+ version = '2'
+ uri_prefix = "v2"
+
+ def deserialize(self, body):
+ return json.loads(body.replace("\n", ""))
+
+ def serialize(self, body):
+ return json.dumps(body)
+
+ def create_sample(self, meter_name, sample_list):
+ uri = "%s/meters/%s" % (self.uri_prefix, meter_name)
+ body = self.serialize(sample_list)
+ resp, body = self.post(uri, body)
+ self.expected_success(200, resp.status)
+ body = self.deserialize(body)
+ return rest_client.ResponseBody(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)
+ resp, body = self.get(uri)
+ self.expected_success(200, resp.status)
+ body = self.deserialize(body)
+ return rest_client.ResponseBodyList(resp, body)
+
+ def list_resources(self, query=None):
+ uri = '%s/resources' % self.uri_prefix
+ return self._helper_list(uri, query)
+
+ def list_meters(self, query=None):
+ uri = '%s/meters' % self.uri_prefix
+ return self._helper_list(uri, query)
+
+ 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 list_events(self, query=None):
+ uri = '%s/events' % self.uri_prefix
+ return self._helper_list(uri, query)
+
+ def show_resource(self, resource_id):
+ uri = '%s/resources/%s' % (self.uri_prefix, resource_id)
+ resp, body = self.get(uri)
+ self.expected_success(200, resp.status)
+ body = self.deserialize(body)
+ return rest_client.ResponseBody(resp, body)
+
+
+class Manager(manager.Manager):
+
+ load_clients = [
+ 'servers_client',
+ 'compute_networks_client',
+ 'compute_floating_ips_client',
+ 'flavors_client',
+ 'image_client',
+ 'image_client_v2',
+ 'telemetry_client',
+ 'container_client',
+ 'object_client',
+ ]
+
+ default_params = {
+ 'disable_ssl_certificate_validation':
+ CONF.identity.disable_ssl_certificate_validation,
+ 'ca_certs': CONF.identity.ca_certificates_file,
+ 'trace_requests': CONF.debug.trace_requests
+ }
+
+ compute_params = {
+ 'service': CONF.compute.catalog_type,
+ 'region': CONF.compute.region or CONF.identity.region,
+ 'endpoint_type': CONF.compute.endpoint_type,
+ 'build_interval': CONF.compute.build_interval,
+ 'build_timeout': CONF.compute.build_timeout,
+ }
+ compute_params.update(default_params)
+
+ image_params = {
+ 'catalog_type': CONF.image.catalog_type,
+ 'region': CONF.image.region or CONF.identity.region,
+ 'endpoint_type': CONF.image.endpoint_type,
+ 'build_interval': CONF.image.build_interval,
+ 'build_timeout': CONF.image.build_timeout,
+ }
+ image_params.update(default_params)
+
+ telemetry_params = {
+ 'service': CONF.telemetry_plugin.catalog_type,
+ 'region': CONF.identity.region,
+ 'endpoint_type': CONF.telemetry_plugin.endpoint_type,
+ }
+ telemetry_params.update(default_params)
+
+ object_storage_params = {
+ 'service': CONF.object_storage.catalog_type,
+ 'region': CONF.object_storage.region or CONF.identity.region,
+ 'endpoint_type': CONF.object_storage.endpoint_type
+ }
+ object_storage_params.update(default_params)
+
+ def __init__(self, credentials=None, service=None):
+ super(Manager, self).__init__(credentials)
+ for client in self.load_clients:
+ getattr(self, 'set_%s' % client)()
+
+ def set_servers_client(self):
+ self.servers_client = ServersClient(self.auth_provider,
+ **self.compute_params)
+
+ def set_compute_networks_client(self):
+ self.compute_networks_client = NetworksClient(self.auth_provider,
+ **self.compute_params)
+
+ def set_compute_floating_ips_client(self):
+ self.compute_floating_ips_client = FloatingIPsClient(
+ self.auth_provider,
+ **self.compute_params)
+
+ def set_flavors_client(self):
+ self.flavors_client = FlavorsClient(self.auth_provider,
+ **self.compute_params)
+
+ def set_image_client(self):
+ self.image_client = ImagesClient(self.auth_provider,
+ **self.image_params)
+
+ def set_image_client_v2(self):
+ self.image_client_v2 = ImagesClientV2(self.auth_provider,
+ **self.image_params)
+
+ def set_telemetry_client(self):
+ self.telemetry_client = TelemetryClient(self.auth_provider,
+ **self.telemetry_params)
+
+ def set_container_client(self):
+ self.container_client = ContainerClient(self.auth_provider,
+ **self.object_storage_params)
+
+ def set_object_client(self):
+ self.object_client = ObjectClient(self.auth_provider,
+ **self.object_storage_params)