Allow multiple required_service_extension
In some cases, some resources may require more than one service_extension. In this case, we should allow resources to define a list of required resources. Change-Id: Iee0104a741cc050047824d23b8ab5ee9871c4f28
This commit is contained in:
parent
380d087067
commit
5e14163f9c
@ -16,6 +16,7 @@ import contextlib
|
|||||||
import datetime as dt
|
import datetime as dt
|
||||||
import itertools
|
import itertools
|
||||||
import pydoc
|
import pydoc
|
||||||
|
import re
|
||||||
import tenacity
|
import tenacity
|
||||||
import weakref
|
import weakref
|
||||||
|
|
||||||
@ -807,16 +808,21 @@ class Resource(status.ResourceStatus):
|
|||||||
service_name=cls.default_client_name)
|
service_name=cls.default_client_name)
|
||||||
if endpoint_exists:
|
if endpoint_exists:
|
||||||
req_extension = cls.required_service_extension
|
req_extension = cls.required_service_extension
|
||||||
is_ext_available = (
|
if not req_extension:
|
||||||
not req_extension or client_plugin.has_extension(
|
return(True, None)
|
||||||
req_extension))
|
if isinstance(req_extension, str):
|
||||||
|
req_extension = re.split(' |,', req_extension)
|
||||||
|
for ext in req_extension:
|
||||||
|
is_ext_available = (
|
||||||
|
client_plugin.has_extension(ext))
|
||||||
|
if not is_ext_available:
|
||||||
|
reason = _('Required extension {0} in {1} service '
|
||||||
|
'is not available.')
|
||||||
|
reason = reason.format(ext,
|
||||||
|
cls.default_client_name)
|
||||||
|
break
|
||||||
if is_ext_available:
|
if is_ext_available:
|
||||||
return (True, None)
|
return (True, None)
|
||||||
else:
|
|
||||||
reason = _('Required extension {0} in {1} service '
|
|
||||||
'is not available.')
|
|
||||||
reason = reason.format(req_extension,
|
|
||||||
cls.default_client_name)
|
|
||||||
else:
|
else:
|
||||||
reason = _('{0} {1} endpoint is not in service catalog.')
|
reason = _('{0} {1} endpoint is not in service catalog.')
|
||||||
reason = reason.format(cls.default_client_name, service_type)
|
reason = reason.format(cls.default_client_name, service_type)
|
||||||
|
@ -317,6 +317,20 @@ class ResourceWithDefaultClientNameExt(resource.Resource):
|
|||||||
properties_schema = {}
|
properties_schema = {}
|
||||||
|
|
||||||
|
|
||||||
|
class ResourceWithDefaultClientNameMultiStrExt(resource.Resource):
|
||||||
|
default_client_name = 'sample'
|
||||||
|
required_service_extension = 'foo,bar'
|
||||||
|
|
||||||
|
properties_schema = {}
|
||||||
|
|
||||||
|
|
||||||
|
class ResourceWithDefaultClientNameMultiExt(resource.Resource):
|
||||||
|
default_client_name = 'sample'
|
||||||
|
required_service_extension = ['foo', 'bar']
|
||||||
|
|
||||||
|
properties_schema = {}
|
||||||
|
|
||||||
|
|
||||||
class ResourceWithFnGetAttType(GenericResource):
|
class ResourceWithFnGetAttType(GenericResource):
|
||||||
def get_attribute(self, name):
|
def get_attribute(self, name):
|
||||||
pass
|
pass
|
||||||
|
@ -4064,6 +4064,84 @@ class ResourceAvailabilityTest(common.HeatTestCase):
|
|||||||
|
|
||||||
self.assertRaises(MyException, res.handle_delete)
|
self.assertRaises(MyException, res.handle_delete)
|
||||||
|
|
||||||
|
@mock.patch.object(clients.OpenStackClients, 'client_plugin')
|
||||||
|
def test_service_deployed_required_extension_true_string(
|
||||||
|
self,
|
||||||
|
mock_client_plugin_method):
|
||||||
|
"""Test availability of resource with a required extension. """
|
||||||
|
|
||||||
|
mock_service_types, mock_client_plugin = self._mock_client_plugin(
|
||||||
|
['test_type']
|
||||||
|
)
|
||||||
|
mock_client_plugin.has_extension = mock.Mock(
|
||||||
|
side_effect=[True, True])
|
||||||
|
mock_client_plugin_method.return_value = mock_client_plugin
|
||||||
|
|
||||||
|
rsrc = generic_rsrc.ResourceWithDefaultClientNameMultiStrExt
|
||||||
|
rsrc.is_service_available(
|
||||||
|
context=mock.Mock())[0]
|
||||||
|
mock_client_plugin_method.assert_called_once_with(
|
||||||
|
generic_rsrc.ResourceWithDefaultClientName.default_client_name)
|
||||||
|
mock_service_types.assert_called_once_with()
|
||||||
|
mock_client_plugin.does_endpoint_exist.assert_called_once_with(
|
||||||
|
service_type='test_type',
|
||||||
|
service_name=(generic_rsrc.ResourceWithDefaultClientName
|
||||||
|
.default_client_name))
|
||||||
|
mock_client_plugin.has_extension.has_calls(
|
||||||
|
[('foo'), ('bar')])
|
||||||
|
|
||||||
|
@mock.patch.object(clients.OpenStackClients, 'client_plugin')
|
||||||
|
def test_service_deployed_required_extension_true_list(
|
||||||
|
self,
|
||||||
|
mock_client_plugin_method):
|
||||||
|
"""Test availability of resource with a required extension. """
|
||||||
|
|
||||||
|
mock_service_types, mock_client_plugin = self._mock_client_plugin(
|
||||||
|
['test_type']
|
||||||
|
)
|
||||||
|
mock_client_plugin.has_extension = mock.Mock(
|
||||||
|
side_effect=[True, True])
|
||||||
|
mock_client_plugin_method.return_value = mock_client_plugin
|
||||||
|
|
||||||
|
rsrc = generic_rsrc.ResourceWithDefaultClientNameMultiExt
|
||||||
|
rsrc.is_service_available(
|
||||||
|
context=mock.Mock())[0]
|
||||||
|
mock_client_plugin_method.assert_called_once_with(
|
||||||
|
generic_rsrc.ResourceWithDefaultClientName.default_client_name)
|
||||||
|
mock_service_types.assert_called_once_with()
|
||||||
|
mock_client_plugin.does_endpoint_exist.assert_called_once_with(
|
||||||
|
service_type='test_type',
|
||||||
|
service_name=(generic_rsrc.ResourceWithDefaultClientName
|
||||||
|
.default_client_name))
|
||||||
|
mock_client_plugin.has_extension.has_calls(
|
||||||
|
[('foo'), ('bar')])
|
||||||
|
|
||||||
|
@mock.patch.object(clients.OpenStackClients, 'client_plugin')
|
||||||
|
def test_service_deployed_required_extension_true_list_fail(
|
||||||
|
self,
|
||||||
|
mock_client_plugin_method):
|
||||||
|
"""Test availability of resource with a required extension. """
|
||||||
|
|
||||||
|
mock_service_types, mock_client_plugin = self._mock_client_plugin(
|
||||||
|
['test_type']
|
||||||
|
)
|
||||||
|
mock_client_plugin.has_extension = mock.Mock(
|
||||||
|
side_effect=[True, False])
|
||||||
|
mock_client_plugin_method.return_value = mock_client_plugin
|
||||||
|
|
||||||
|
rsrc = generic_rsrc.ResourceWithDefaultClientNameMultiExt
|
||||||
|
self.assertFalse(rsrc.is_service_available(
|
||||||
|
context=mock.Mock())[0])
|
||||||
|
mock_client_plugin_method.assert_called_once_with(
|
||||||
|
generic_rsrc.ResourceWithDefaultClientName.default_client_name)
|
||||||
|
mock_service_types.assert_called_once_with()
|
||||||
|
mock_client_plugin.does_endpoint_exist.assert_called_once_with(
|
||||||
|
service_type='test_type',
|
||||||
|
service_name=(generic_rsrc.ResourceWithDefaultClientName
|
||||||
|
.default_client_name))
|
||||||
|
mock_client_plugin.has_extension.has_calls(
|
||||||
|
[('foo'), ('bar')])
|
||||||
|
|
||||||
|
|
||||||
class TestLiveStateUpdate(common.HeatTestCase):
|
class TestLiveStateUpdate(common.HeatTestCase):
|
||||||
|
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
other:
|
||||||
|
- |
|
||||||
|
Allow Heat resources to accept more than one required_service_extension.
|
||||||
|
For cases where a resource required multiple service extensions. A
|
||||||
|
developer can now provide a list of those extensions.
|
Loading…
Reference in New Issue
Block a user