diff --git a/config_tempest/services/alarming.py b/config_tempest/services/alarming.py index d186ad0d..afc5726b 100644 --- a/config_tempest/services/alarming.py +++ b/config_tempest/services/alarming.py @@ -19,8 +19,8 @@ from config_tempest.services.base import Service class AlarmingService(Service): @staticmethod - def get_service_name(): - return ['aodh'] + def get_service_type(): + return ['alarming'] @staticmethod def get_codename(): diff --git a/config_tempest/services/aws.py b/config_tempest/services/aws.py index 36fb965a..e010eebd 100644 --- a/config_tempest/services/aws.py +++ b/config_tempest/services/aws.py @@ -22,7 +22,7 @@ class Ec2Service(Service): conf.set('aws', 'ec2_url', self.service_url) @staticmethod - def get_service_name(): + def get_service_type(): return ['ec2'] @@ -32,5 +32,5 @@ class S3Service(Service): conf.set('aws', 's3_url', self.service_url) @staticmethod - def get_service_name(): + def get_service_type(): return ['s3'] diff --git a/config_tempest/services/baremetal.py b/config_tempest/services/baremetal.py index 2d9a4810..13f43020 100644 --- a/config_tempest/services/baremetal.py +++ b/config_tempest/services/baremetal.py @@ -19,8 +19,8 @@ from config_tempest.services.base import Service class BaremetalService(Service): @staticmethod - def get_service_name(): - return ['ironic'] + def get_service_type(): + return ['baremetal'] @staticmethod def get_codename(): diff --git a/config_tempest/services/base.py b/config_tempest/services/base.py index 90c529c2..81d4dbfe 100644 --- a/config_tempest/services/base.py +++ b/config_tempest/services/base.py @@ -89,11 +89,11 @@ class Service(object): return self.extensions @staticmethod - def get_service_name(): - """Return the service name. + def get_service_type(): + """Return the service type. - This returns a list because you can have different services for the - same type, like volume, volumev2, volumev3 + This returns a list because you can have services with more types, + like volume, volumev2, volumev3. """ return [] diff --git a/config_tempest/services/ceilometer.py b/config_tempest/services/ceilometer.py index efbb87a5..dd6df56a 100644 --- a/config_tempest/services/ceilometer.py +++ b/config_tempest/services/ceilometer.py @@ -34,8 +34,8 @@ class MeteringService(Service): conf.set('service_available', 'ceilometer', 'True') @staticmethod - def get_service_name(): - return ['ceilometer'] + def get_service_type(): + return ['metering'] @staticmethod def get_codename(): diff --git a/config_tempest/services/compute.py b/config_tempest/services/compute.py index 9f39e0be..1ba88ad4 100644 --- a/config_tempest/services/compute.py +++ b/config_tempest/services/compute.py @@ -62,8 +62,8 @@ class ComputeService(VersionedService): str(is_service(**{'type': 'key-manager'}))) @staticmethod - def get_service_name(): - return ['nova'] + def get_service_type(): + return ['compute'] @staticmethod def get_codename(): diff --git a/config_tempest/services/data-processing.py b/config_tempest/services/data-processing.py index d1f5f2ff..b1f635a1 100644 --- a/config_tempest/services/data-processing.py +++ b/config_tempest/services/data-processing.py @@ -19,8 +19,8 @@ from config_tempest.services.base import Service class DataProcessingService(Service): @staticmethod - def get_service_name(): - return ['sahara'] + def get_service_type(): + return ['data-processing'] @staticmethod def get_codename(): diff --git a/config_tempest/services/database.py b/config_tempest/services/database.py index f5a8a11a..6d400cdb 100644 --- a/config_tempest/services/database.py +++ b/config_tempest/services/database.py @@ -19,8 +19,8 @@ from config_tempest.services.base import Service class DatabaseService(Service): @staticmethod - def get_service_name(): - return ['trove'] + def get_service_type(): + return ['database'] @staticmethod def get_codename(): diff --git a/config_tempest/services/dns.py b/config_tempest/services/dns.py index 8e7f803f..bff54cf5 100644 --- a/config_tempest/services/dns.py +++ b/config_tempest/services/dns.py @@ -19,8 +19,8 @@ from config_tempest.services.base import Service class DnsService(Service): @staticmethod - def get_service_name(): - return ['designate'] + def get_service_type(): + return ['dns'] @staticmethod def get_codename(): diff --git a/config_tempest/services/event.py b/config_tempest/services/event.py index dddc3168..6b15d19e 100644 --- a/config_tempest/services/event.py +++ b/config_tempest/services/event.py @@ -19,8 +19,8 @@ from config_tempest.services.base import Service class EventService(Service): @staticmethod - def get_service_name(): - return ['panko'] + def get_service_type(): + return ['event'] @staticmethod def get_codename(): diff --git a/config_tempest/services/identity.py b/config_tempest/services/identity.py index 15ba31be..9b5ee63d 100644 --- a/config_tempest/services/identity.py +++ b/config_tempest/services/identity.py @@ -61,8 +61,8 @@ class IdentityService(VersionedService): return ['v2', 'v3'] @staticmethod - def get_service_name(): - return ['keystone'] + def get_service_type(): + return ['identity'] def set_identity_v3_extensions(self): """Returns discovered identity v3 extensions diff --git a/config_tempest/services/image.py b/config_tempest/services/image.py index 3f4f39dd..0f7b98a2 100644 --- a/config_tempest/services/image.py +++ b/config_tempest/services/image.py @@ -74,8 +74,8 @@ class ImageService(VersionedService): return ['v1', 'v2'] @staticmethod - def get_service_name(): - return ['glance'] + def get_service_type(): + return ['image'] @staticmethod def get_codename(): diff --git a/config_tempest/services/messaging.py b/config_tempest/services/messaging.py index 5395fa5b..b7cf0dea 100644 --- a/config_tempest/services/messaging.py +++ b/config_tempest/services/messaging.py @@ -19,8 +19,8 @@ from config_tempest.services.base import Service class MessagingService(Service): @staticmethod - def get_service_name(): - return ['zaqar'] + def get_service_type(): + return ['messaging'] @staticmethod def get_codename(): diff --git a/config_tempest/services/metric.py b/config_tempest/services/metric.py index 60cc4e15..27a2ac7e 100644 --- a/config_tempest/services/metric.py +++ b/config_tempest/services/metric.py @@ -19,8 +19,8 @@ from config_tempest.services.base import Service class MetricService(Service): @staticmethod - def get_service_name(): - return ['gnocchi'] + def get_service_type(): + return ['metric'] @staticmethod def get_codename(): diff --git a/config_tempest/services/network.py b/config_tempest/services/network.py index 149160b8..c086e4a7 100644 --- a/config_tempest/services/network.py +++ b/config_tempest/services/network.py @@ -93,8 +93,8 @@ class NetworkService(VersionedService): 'discovered and must be specified') @staticmethod - def get_service_name(): - return ['neutron'] + def get_service_type(): + return ['network'] @staticmethod def get_codename(): diff --git a/config_tempest/services/object_storage.py b/config_tempest/services/object_storage.py index 1f1045f5..7fec4011 100644 --- a/config_tempest/services/object_storage.py +++ b/config_tempest/services/object_storage.py @@ -106,8 +106,8 @@ class ObjectStorageService(Service): self.list_create_roles(conf, self.client.roles) @staticmethod - def get_service_name(): - return ['swift'] + def get_service_type(): + return ['object-store'] @staticmethod def get_codename(): diff --git a/config_tempest/services/octavia.py b/config_tempest/services/octavia.py index 9087c980..d00c1a58 100644 --- a/config_tempest/services/octavia.py +++ b/config_tempest/services/octavia.py @@ -28,8 +28,8 @@ class LoadBalancerService(VersionedService): conf.set('load_balancer', 'RBAC_test_type', 'owner_or_admin') @staticmethod - def get_service_name(): - return ['octavia'] + def get_service_type(): + return ['load-balancer'] @staticmethod def get_codename(): diff --git a/config_tempest/services/orchestration.py b/config_tempest/services/orchestration.py index 2ca4c770..db964867 100644 --- a/config_tempest/services/orchestration.py +++ b/config_tempest/services/orchestration.py @@ -22,8 +22,8 @@ from config_tempest.services.base import Service class OrchestrationService(Service): @staticmethod - def get_service_name(): - return ['heat'] + def get_service_type(): + return ['orchestration'] @staticmethod def get_codename(): diff --git a/config_tempest/services/services.py b/config_tempest/services/services.py index 38016b35..1dd2648b 100644 --- a/config_tempest/services/services.py +++ b/config_tempest/services/services.py @@ -64,39 +64,50 @@ class Services(object): def get_available_services(self): try: services = self._clients.service_client.list_services()['services'] - return {s['name']: s['type'] for s in services} except exceptions.Forbidden: C.LOG.warning("User has no permissions to list services, using " "catalog. Services without endpoint will not be " "discovered.") - token, auth_data = self._clients.auth_provider.get_auth() - return {s['name']: s['type'] for s - in auth_data[self.service_catalog]} + services = self.catalog + return services + + def get_service_data(self, s_name, s_type): + for s in self.catalog: + if s['name'] == s_name and s['type'] == s_type: + return s + return None def discover(self): - token, auth_data = self._clients.auth_provider.get_auth() - - auth_entries = {e['type']: e for e in auth_data[self.service_catalog]} - # We loop through the classes we have for each service, and if we find # a class that match a service enabled, we add it in our services list. # some services doesn't have endpoints, so we need to check first for s_class in self.service_classes: - s_names = s_class.get_service_name() - for s_name in s_names: - s_type = self.available_services.get(s_name, None) - if s_type: - endpoint_data = auth_entries.get(s_type, None) + s_types = s_class.get_service_type() + for s_type in s_types: + s_name = [t['name'] for t in self.available_services + if t['type'] == s_type] + if s_name: + # In the general case, there should only be one service in + # a deployment per service type + # https://docs.openstack.org/keystone/latest/contributor/ + # service-catalog.html#services + if len(s_name) > 1: + C.LOG.warning("There are more service names ('%s') for" + " '%s' service type, which is undefined" + " behavior. Continuing with '%s'.", + str(s_name), s_type, s_name[0]) + s_name = s_name[0] + service_data = self.get_service_data(s_name, s_type) url = None - if not endpoint_data: - C.LOG.Warning('No endpoint data found for {}'.format( + if not service_data: + C.LOG.warning('No endpoint data found for {}'.format( s_name)) else: url = self.parse_endpoints(self.get_endpoints( - endpoint_data), s_type) + service_data), s_type) # Create the service class and add it to services list - service = s_class(s_name, s_type, url, token, + service = s_class(s_name, s_type, url, self.token, self._ssl_validation, self._clients.get_service_client( s_type)) @@ -153,11 +164,13 @@ class Services(object): def set_catalog_and_url(self): if self._creds.api_version == 3: - self.service_catalog = 'catalog' + service_catalog = 'catalog' self.public_url = 'url' else: - self.service_catalog = 'serviceCatalog' + service_catalog = 'serviceCatalog' self.public_url = 'publicURL' + self.token, auth_data = self._clients.auth_provider.get_auth() + self.catalog = auth_data[service_catalog] def parse_endpoints(self, ep, name): """Parse an endpoint(s). @@ -214,15 +227,16 @@ class Services(object): :param kwargs: Search parameters (accepts service name or type) :rtype: boolean """ + a_s = self.available_services if kwargs.get('name'): - if kwargs.get('name') not in self.available_services.keys(): - return False - return True + if [s for s in a_s if s['name'] == kwargs.get('name')]: + return True + return False if kwargs.get('type'): - if kwargs.get('type') not in self.available_services.values(): - return False - return True + if [s for s in a_s if s['type'] == kwargs.get('type')]: + return True + return False return False def post_configuration(self): diff --git a/config_tempest/services/share.py b/config_tempest/services/share.py index 14d355da..5ae3eb78 100644 --- a/config_tempest/services/share.py +++ b/config_tempest/services/share.py @@ -35,5 +35,5 @@ class ShareService(VersionedService): return 'share' @staticmethod - def get_service_name(): - return ['manila', 'manilav2'] + def get_service_type(): + return ['share', 'sharev2'] diff --git a/config_tempest/services/telemetry.py b/config_tempest/services/telemetry.py index 659fb03f..08904a6d 100644 --- a/config_tempest/services/telemetry.py +++ b/config_tempest/services/telemetry.py @@ -19,8 +19,8 @@ from config_tempest.services.base import Service class TelemetryService(Service): @staticmethod - def get_service_name(): - return ['ceilometer'] + def get_service_type(): + return ['telemetry'] @staticmethod def get_codename(): diff --git a/config_tempest/services/volume.py b/config_tempest/services/volume.py index 48eca8bb..14db6a9e 100644 --- a/config_tempest/services/volume.py +++ b/config_tempest/services/volume.py @@ -56,8 +56,8 @@ class VolumeService(VersionedService): return 'volume' @staticmethod - def get_service_name(): - return ['cinderv2', 'cinderv3'] + def get_service_type(): + return ['volumev2', 'volumev3'] def post_configuration(self, conf, is_service): # Verify if the cinder backup service is enabled diff --git a/config_tempest/services/workflowv2.py b/config_tempest/services/workflowv2.py index e2ccfac6..51cb35c4 100644 --- a/config_tempest/services/workflowv2.py +++ b/config_tempest/services/workflowv2.py @@ -19,8 +19,8 @@ from config_tempest.services.base import Service class Workflowv2Service(Service): @staticmethod - def get_service_name(): - return ['mistral'] + def get_service_type(): + return ['workflow'] @staticmethod def get_codename(): diff --git a/config_tempest/tests/services/test_aws.py b/config_tempest/tests/services/test_aws.py index 422112c7..5fad030b 100644 --- a/config_tempest/tests/services/test_aws.py +++ b/config_tempest/tests/services/test_aws.py @@ -26,9 +26,11 @@ class TestEc2Service(BaseConfigTempestTest): FAKE_URL = "http://10.200.16.10:8774/" @mock.patch('config_tempest.services.services.Services.discover') + @mock.patch('config_tempest.services.services.Services.' + 'set_catalog_and_url') @mock.patch('config_tempest.services.services.Services.' 'get_available_services') - def setUp(self, mock_set_avail, mock_discover): + def setUp(self, mock_set_avail, mock_catalog, mock_discover): super(TestEc2Service, self).setUp() conf = self._get_conf('v2', 'v3') self.clients = self._get_clients(conf) @@ -46,9 +48,11 @@ class TestS3Service(BaseConfigTempestTest): FAKE_URL = "http://10.200.16.10:8774/" @mock.patch('config_tempest.services.services.Services.discover') + @mock.patch('config_tempest.services.services.Services.' + 'set_catalog_and_url') @mock.patch('config_tempest.services.services.Services.' 'get_available_services') - def setUp(self, mock_set_avail, mock_discover): + def setUp(self, mock_set_avail, mock_catalog, mock_discover): super(TestS3Service, self).setUp() conf = self._get_conf('v2', 'v3') self.clients = self._get_clients(conf) diff --git a/config_tempest/tests/services/test_services.py b/config_tempest/tests/services/test_services.py index 5a438504..0afcc5a0 100644 --- a/config_tempest/tests/services/test_services.py +++ b/config_tempest/tests/services/test_services.py @@ -37,10 +37,13 @@ class TestServices(BaseConfigTempestTest): super(TestServices, self).setUp() @mock.patch('config_tempest.services.services.Services.discover') + @mock.patch('config_tempest.services.services.Services.' + 'set_catalog_and_url') @mock.patch('config_tempest.services.services.Services.' 'get_available_services') - def _create_services_instance(self, mock_avail, mock_discover, v2=False): - mock_avail.return_value = {'my_service': 'my_type'} + def _create_services_instance(self, mock_avail, mock_catalog, + mock_discover, v2=False): + mock_avail.return_value = [{'name': 'my_service', 'type': 'my_type'}] conf = self._get_conf('v2', 'v3') creds = self._get_creds(conf, v2=v2) clients = mock.Mock() @@ -74,18 +77,6 @@ class TestServices(BaseConfigTempestTest): resp = services.get_endpoints({'endpoints': []}) self.assertEqual(resp, []) - def test_set_catalog_and_url(self): - # api version = 2 - services = self._create_services_instance(v2=True) - services.set_catalog_and_url() - self.assertEqual(services.service_catalog, 'serviceCatalog') - self.assertEqual(services.public_url, 'publicURL') - # api version = 3 - services = self._create_services_instance() - services.set_catalog_and_url() - self.assertEqual(services.service_catalog, 'catalog') - self.assertEqual(services.public_url, 'url') - def test_parse_endpoints_empty(self): services = self._create_services_instance() services.public_url = "url"