Custom constrain for keystone service
Adds custom constrain for keystone service. implements blueprint keystone-resource-service-endpoint Change-Id: I6a2145ab51688292eb732e578db87fb993d2804e
This commit is contained in:
parent
d7cadf02c9
commit
384d82e04c
@ -69,6 +69,20 @@ class KeystoneClientPlugin(keystone.KeystoneClientPlugin):
|
||||
|
||||
raise exceptions.KeystoneGroupNotFound(group_id=group)
|
||||
|
||||
def get_service_id(self, service):
|
||||
try:
|
||||
service_obj = self.client().client.services.get(service)
|
||||
return service_obj.id
|
||||
except keystone_exceptions.NotFound:
|
||||
service_list = self.client().client.services.list(name=service)
|
||||
|
||||
if len(service_list) == 1:
|
||||
return service_list[0].id
|
||||
elif len(service_list) > 1:
|
||||
raise exceptions.KeystoneServiceNameConflict(service=service)
|
||||
else:
|
||||
raise exceptions.KeystoneServiceNotFound(service_id=service)
|
||||
|
||||
|
||||
class KeystoneRoleConstraint(constraints.BaseCustomConstraint):
|
||||
|
||||
@ -100,3 +114,12 @@ class KeystoneGroupConstraint(constraints.BaseCustomConstraint):
|
||||
|
||||
def validate_with_client(self, client, group):
|
||||
client.client_plugin('keystone').get_group_id(group)
|
||||
|
||||
|
||||
class KeystoneServiceConstraint(constraints.BaseCustomConstraint):
|
||||
|
||||
expected_exceptions = (exceptions.KeystoneServiceNotFound,
|
||||
exceptions.KeystoneServiceNameConflict,)
|
||||
|
||||
def validate_with_client(self, client, service):
|
||||
client.client_plugin('keystone').get_service_id(service)
|
||||
|
@ -29,3 +29,12 @@ class KeystoneDomainNotFound(exception.HeatException):
|
||||
|
||||
class KeystoneGroupNotFound(exception.HeatException):
|
||||
msg_fmt = _("Keystone group %(group_id)s does not found")
|
||||
|
||||
|
||||
class KeystoneServiceNotFound(exception.HeatException):
|
||||
msg_fmt = _("Keystone service %(service_id)s does not found")
|
||||
|
||||
|
||||
class KeystoneServiceNameConflict(exception.HeatException):
|
||||
msg_fmt = _("Keystone has more than one service with same name "
|
||||
"%(service)s. Please use service id instead of name")
|
||||
|
@ -12,13 +12,16 @@
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
import testtools
|
||||
import six
|
||||
|
||||
from keystoneclient import exceptions as keystone_exceptions
|
||||
|
||||
from .. import client # noqa
|
||||
from .. import exceptions # noqa
|
||||
from heat.tests import common
|
||||
|
||||
|
||||
class KeystoneRoleConstraintTest(testtools.TestCase):
|
||||
class KeystoneRoleConstraintTest(common.HeatTestCase):
|
||||
|
||||
def test_expected_exceptions(self):
|
||||
self.assertEqual((exceptions.KeystoneRoleNotFound,),
|
||||
@ -38,7 +41,7 @@ class KeystoneRoleConstraintTest(testtools.TestCase):
|
||||
client_plugin_mock.get_role_id.assert_called_once_with('role_1')
|
||||
|
||||
|
||||
class KeystoneProjectConstraintTest(testtools.TestCase):
|
||||
class KeystoneProjectConstraintTest(common.HeatTestCase):
|
||||
|
||||
def test_expected_exceptions(self):
|
||||
self.assertEqual((exceptions.KeystoneProjectNotFound,),
|
||||
@ -58,7 +61,7 @@ class KeystoneProjectConstraintTest(testtools.TestCase):
|
||||
client_plugin_mock.get_project_id.assert_called_once_with('project_1')
|
||||
|
||||
|
||||
class KeystoneGroupConstraintTest(testtools.TestCase):
|
||||
class KeystoneGroupConstraintTest(common.HeatTestCase):
|
||||
|
||||
def test_expected_exceptions(self):
|
||||
self.assertEqual((exceptions.KeystoneGroupNotFound,),
|
||||
@ -78,7 +81,7 @@ class KeystoneGroupConstraintTest(testtools.TestCase):
|
||||
client_plugin_mock.get_group_id.assert_called_once_with('group_1')
|
||||
|
||||
|
||||
class KeystoneDomainConstraintTest(testtools.TestCase):
|
||||
class KeystoneDomainConstraintTest(common.HeatTestCase):
|
||||
|
||||
def test_expected_exceptions(self):
|
||||
self.assertEqual((exceptions.KeystoneDomainNotFound,),
|
||||
@ -96,3 +99,117 @@ class KeystoneDomainConstraintTest(testtools.TestCase):
|
||||
'domain_1'))
|
||||
|
||||
client_plugin_mock.get_domain_id.assert_called_once_with('domain_1')
|
||||
|
||||
|
||||
class KeystoneServiceConstraintTest(common.HeatTestCase):
|
||||
|
||||
sample_uuid = '477e8273-60a7-4c41-b683-fdb0bc7cd151'
|
||||
|
||||
def test_expected_exceptions(self):
|
||||
self.assertEqual((exceptions.KeystoneServiceNotFound,
|
||||
exceptions.KeystoneServiceNameConflict,),
|
||||
client.KeystoneServiceConstraint.expected_exceptions,
|
||||
"KeystoneServiceConstraint expected exceptions error")
|
||||
|
||||
def test_constrain(self):
|
||||
constrain = client.KeystoneServiceConstraint()
|
||||
client_mock = mock.MagicMock()
|
||||
client_plugin_mock = mock.MagicMock()
|
||||
client_plugin_mock.get_service_id.return_value = self.sample_uuid
|
||||
client_mock.client_plugin.return_value = client_plugin_mock
|
||||
|
||||
self.assertIsNone(constrain.validate_with_client(client_mock,
|
||||
self.sample_uuid))
|
||||
|
||||
client_plugin_mock.get_service_id.assert_called_once_with(
|
||||
self.sample_uuid
|
||||
)
|
||||
|
||||
|
||||
class KeystoneClientPluginServiceTest(common.HeatTestCase):
|
||||
|
||||
sample_uuid = '477e8273-60a7-4c41-b683-fdb0bc7cd152'
|
||||
sample_name = 'sample_service'
|
||||
|
||||
def _get_mock_service(self):
|
||||
srv = mock.MagicMock()
|
||||
srv.id = self.sample_uuid
|
||||
srv.name = self.sample_name
|
||||
return srv
|
||||
|
||||
def setUp(self):
|
||||
super(KeystoneClientPluginServiceTest, self).setUp()
|
||||
self._client = mock.MagicMock()
|
||||
self._client.client = mock.MagicMock()
|
||||
self._client.client.services = mock.MagicMock()
|
||||
|
||||
@mock.patch.object(client.KeystoneClientPlugin, 'client')
|
||||
def test_get_service_id(self, client_keystone):
|
||||
|
||||
self._client.client.services.get.return_value = (self
|
||||
._get_mock_service())
|
||||
|
||||
client_keystone.return_value = self._client
|
||||
client_plugin = client.KeystoneClientPlugin(
|
||||
context=mock.MagicMock()
|
||||
)
|
||||
|
||||
self.assertEqual(self.sample_uuid,
|
||||
client_plugin.get_service_id(self.sample_uuid))
|
||||
|
||||
@mock.patch.object(client.KeystoneClientPlugin, 'client')
|
||||
def test_get_service_id_with_name(self, client_keystone):
|
||||
self._client.client.services.get.side_effect = (keystone_exceptions
|
||||
.NotFound)
|
||||
self._client.client.services.list.return_value = [
|
||||
self._get_mock_service()
|
||||
]
|
||||
|
||||
client_keystone.return_value = self._client
|
||||
client_plugin = client.KeystoneClientPlugin(
|
||||
context=mock.MagicMock()
|
||||
)
|
||||
|
||||
self.assertEqual(self.sample_uuid,
|
||||
client_plugin.get_service_id(self.sample_name))
|
||||
|
||||
@mock.patch.object(client.KeystoneClientPlugin, 'client')
|
||||
def test_get_service_id_with_name_conflict(self, client_keystone):
|
||||
self._client.client.services.get.side_effect = (keystone_exceptions
|
||||
.NotFound)
|
||||
self._client.client.services.list.return_value = [
|
||||
self._get_mock_service(),
|
||||
self._get_mock_service()
|
||||
]
|
||||
|
||||
client_keystone.return_value = self._client
|
||||
client_plugin = client.KeystoneClientPlugin(
|
||||
context=mock.MagicMock()
|
||||
)
|
||||
|
||||
ex = self.assertRaises(exceptions.KeystoneServiceNameConflict,
|
||||
client_plugin.get_service_id,
|
||||
self.sample_name)
|
||||
msg = ("Keystone has more than one service with same name "
|
||||
"%s. Please use service id instead of name" %
|
||||
self.sample_name)
|
||||
self.assertEqual(msg, six.text_type(ex))
|
||||
|
||||
@mock.patch.object(client.KeystoneClientPlugin, 'client')
|
||||
def test_get_service_id_not_found(self, client_keystone):
|
||||
self._client.client.services.get.side_effect = (keystone_exceptions
|
||||
.NotFound)
|
||||
self._client.client.services.list.return_value = [
|
||||
]
|
||||
|
||||
client_keystone.return_value = self._client
|
||||
client_plugin = client.KeystoneClientPlugin(
|
||||
context=mock.MagicMock()
|
||||
)
|
||||
|
||||
ex = self.assertRaises(exceptions.KeystoneServiceNotFound,
|
||||
client_plugin.get_service_id,
|
||||
self.sample_name)
|
||||
msg = ("Keystone service %s does not found" %
|
||||
self.sample_name)
|
||||
self.assertEqual(msg, six.text_type(ex))
|
||||
|
@ -1,6 +1,5 @@
|
||||
[metadata]
|
||||
name = heat-contrib-keystone
|
||||
version = 0.1
|
||||
summary = Heat resources for Keystone
|
||||
description-file =
|
||||
README.md
|
||||
@ -35,6 +34,7 @@ heat.constraints =
|
||||
keystone.domain=heat_keystone.client:KeystoneDomainConstraint
|
||||
keystone.project=heat_keystone.client:KeystoneProjectConstraint
|
||||
keystone.group=heat_keystone.client:KeystoneGroupConstraint
|
||||
keystone.service=heat_keystone.client:KeystoneServiceConstraint
|
||||
|
||||
[global]
|
||||
setup-hooks =
|
||||
|
Loading…
Reference in New Issue
Block a user