Fix validation of required services

Cinder team decided to remove Cinder V1 (which is ok since they already
have V3 API) but our logic of required_service validator was not ready
for such step.

This patch includes the next changes of the validaotr:

* Check for nova-network before initializing clients. This is a simple
  check which does not require initialized clients. Since the keystone
  token is fetched while initializing clients, it can be time wasting.
  Also, it is time to fail on this check.

* In case of NotFound error while direct search by service type, use the
  default one
  NOTE: actually, the default service type should be the same as  what
        we have in consts file...

Change-Id: I2018a9b9323cce05ee226fefdc3fe50c356aed9a
This commit is contained in:
Andrey Kurilin 2019-02-19 18:56:39 +02:00
parent ed524c07c1
commit fb8a67740b
2 changed files with 26 additions and 18 deletions

View File

@ -455,14 +455,16 @@ class RequiredServicesValidator(validation.Validator):
self.services.extend(args)
def validate(self, context, config, plugin_cls, plugin_cfg):
if consts.Service.NOVA_NET in self.services:
self.fail("We are sorry, but Nova-network was deprecated for a "
"long time and latest novaclient doesn't support it, so "
"we too.")
creds = (context.get("admin", {}).get("credential", None)
or context["users"][0]["credential"])
available_services = creds.clients().services().values()
if consts.Service.NOVA_NET in self.services:
LOG.warning("We are sorry, but Nova-network was deprecated for "
"a long time and latest novaclient doesn't support "
"it, so we too.")
clients = creds.clients()
available_services = clients.services().values()
if "api_versions" in config.get("contexts", {}):
api_versions = config["contexts"]["api_versions"]
@ -471,18 +473,24 @@ class RequiredServicesValidator(validation.Validator):
"api_versions@openstack", {})
for service in self.services:
# NOTE(andreykurilin): validator should ignore services configured
# via context(a proper validation should be in context)
service_config = api_versions.get(service, {})
if ("service_type" in service_config
or "service_name" in service_config):
# NOTE(andreykurilin): validator should ignore services
# configured via api_versions@openstack since the context
# plugin itself should perform a proper validation
continue
if (service not in available_services and
not ("service_type" in service_config or
"service_name" in service_config)):
self.fail(
("'{0}' service is not available. Hint: If '{0}' "
"service has non-default service_type, try to"
" setup it via 'api_versions'"
" context.").format(service))
if service not in available_services:
service_client = getattr(clients, service)
default_st = service_client._meta_get("default_service_type")
if default_st not in clients.services():
self.fail(
("'{0}' service is not available. Hint: If '{0}' "
"service has non-default service_type, try to setup "
"it via 'api_versions@openstack' context."
).format(service))
@validation.add("required_platform", platform="openstack", users=True)

View File

@ -655,8 +655,7 @@ class RequiredServicesValidatorTestCase(test.TestCase):
super(RequiredServicesValidatorTestCase, self).setUp()
self.validator = validators.RequiredServicesValidator([
consts.Service.KEYSTONE,
consts.Service.NOVA,
consts.Service.NOVA_NET])
consts.Service.NOVA])
self.config = config
self.context = context
@ -707,7 +706,8 @@ class RequiredServicesValidatorTestCase(test.TestCase):
validator.validate, self.context, {}, None, None)
expected_msg = ("'{0}' service is not available. Hint: If '{0}'"
" service has non-default service_type, try to setup"
" it via 'api_versions' context.").format("lol")
" it via 'api_versions@openstack' context."
).format("lol")
self.assertEqual(expected_msg, e.message)