Browse Source

Don't use name of a service as a key

Name of a service shouldn't be used as a key in structures as the name is
a user-facing name and it's not intended to be machine-parseable:
https://docs.openstack.org/keystone/stein/contributor/service-catalog.html#services

Story: 2006892
Task: 37526

Change-Id: I9621aee957e8a043f6ac251b96abafd80ef167f1
tags/2.4.0^0
Martin Kopec 10 months ago
parent
commit
6a616e5db2
25 changed files with 96 additions and 87 deletions
  1. +2
    -2
      config_tempest/services/alarming.py
  2. +2
    -2
      config_tempest/services/aws.py
  3. +2
    -2
      config_tempest/services/baremetal.py
  4. +4
    -4
      config_tempest/services/base.py
  5. +2
    -2
      config_tempest/services/ceilometer.py
  6. +2
    -2
      config_tempest/services/compute.py
  7. +2
    -2
      config_tempest/services/data-processing.py
  8. +2
    -2
      config_tempest/services/database.py
  9. +2
    -2
      config_tempest/services/dns.py
  10. +2
    -2
      config_tempest/services/event.py
  11. +2
    -2
      config_tempest/services/identity.py
  12. +2
    -2
      config_tempest/services/image.py
  13. +2
    -2
      config_tempest/services/messaging.py
  14. +2
    -2
      config_tempest/services/metric.py
  15. +2
    -2
      config_tempest/services/network.py
  16. +2
    -2
      config_tempest/services/object_storage.py
  17. +2
    -2
      config_tempest/services/octavia.py
  18. +2
    -2
      config_tempest/services/orchestration.py
  19. +39
    -25
      config_tempest/services/services.py
  20. +2
    -2
      config_tempest/services/share.py
  21. +2
    -2
      config_tempest/services/telemetry.py
  22. +2
    -2
      config_tempest/services/volume.py
  23. +2
    -2
      config_tempest/services/workflowv2.py
  24. +6
    -2
      config_tempest/tests/services/test_aws.py
  25. +5
    -14
      config_tempest/tests/services/test_services.py

+ 2
- 2
config_tempest/services/alarming.py View File

@@ -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():


+ 2
- 2
config_tempest/services/aws.py View File

@@ -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']

+ 2
- 2
config_tempest/services/baremetal.py View File

@@ -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():


+ 4
- 4
config_tempest/services/base.py View File

@@ -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 []



+ 2
- 2
config_tempest/services/ceilometer.py View File

@@ -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():


+ 2
- 2
config_tempest/services/compute.py View File

@@ -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():


+ 2
- 2
config_tempest/services/data-processing.py View File

@@ -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():


+ 2
- 2
config_tempest/services/database.py View File

@@ -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():


+ 2
- 2
config_tempest/services/dns.py View File

@@ -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():


+ 2
- 2
config_tempest/services/event.py View File

@@ -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():


+ 2
- 2
config_tempest/services/identity.py View File

@@ -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


+ 2
- 2
config_tempest/services/image.py View File

@@ -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():


+ 2
- 2
config_tempest/services/messaging.py View File

@@ -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():


+ 2
- 2
config_tempest/services/metric.py View File

@@ -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():


+ 2
- 2
config_tempest/services/network.py View File

@@ -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():


+ 2
- 2
config_tempest/services/object_storage.py View File

@@ -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():


+ 2
- 2
config_tempest/services/octavia.py View File

@@ -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():


+ 2
- 2
config_tempest/services/orchestration.py View File

@@ -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():


+ 39
- 25
config_tempest/services/services.py View File

@@ -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 discover(self):
token, auth_data = self._clients.auth_provider.get_auth()

auth_entries = {e['type']: e for e in auth_data[self.service_catalog]}
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):
# 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):


+ 2
- 2
config_tempest/services/share.py View File

@@ -35,5 +35,5 @@ class ShareService(VersionedService):
return 'share'

@staticmethod
def get_service_name():
return ['manila', 'manilav2']
def get_service_type():
return ['share', 'sharev2']

+ 2
- 2
config_tempest/services/telemetry.py View File

@@ -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():


+ 2
- 2
config_tempest/services/volume.py View File

@@ -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


+ 2
- 2
config_tempest/services/workflowv2.py View File

@@ -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():


+ 6
- 2
config_tempest/tests/services/test_aws.py View File

@@ -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)


+ 5
- 14
config_tempest/tests/services/test_services.py View File

@@ -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"


Loading…
Cancel
Save