Support property 'domain' for keystone role
Adds property 'domain' for keystone role resource: 1. the default value of the property is 'default' 2. the property is non-updatalbe Change-Id: I829921dc35e2754eb6c6ccc293423c755806b0df Closes-Bug: #1684558
This commit is contained in:
parent
d2cb548fa4
commit
6a18fb0d43
|
@ -12,9 +12,11 @@
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from heat.common.i18n import _
|
from heat.common.i18n import _
|
||||||
|
from heat.engine import constraints
|
||||||
from heat.engine import properties
|
from heat.engine import properties
|
||||||
from heat.engine import resource
|
from heat.engine import resource
|
||||||
from heat.engine import support
|
from heat.engine import support
|
||||||
|
from heat.engine import translation
|
||||||
|
|
||||||
|
|
||||||
class KeystoneRole(resource.Resource):
|
class KeystoneRole(resource.Resource):
|
||||||
|
@ -22,7 +24,8 @@ class KeystoneRole(resource.Resource):
|
||||||
|
|
||||||
Roles dictate the level of authorization the end user can obtain. Roles can
|
Roles dictate the level of authorization the end user can obtain. Roles can
|
||||||
be granted at either the domain or project level. Role can be assigned to
|
be granted at either the domain or project level. Role can be assigned to
|
||||||
the individual user or at the group level. Role names are globally unique.
|
the individual user or at the group level. Role name is unique within the
|
||||||
|
owning domain.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
support_status = support.SupportStatus(
|
support_status = support.SupportStatus(
|
||||||
|
@ -34,9 +37,9 @@ class KeystoneRole(resource.Resource):
|
||||||
entity = 'roles'
|
entity = 'roles'
|
||||||
|
|
||||||
PROPERTIES = (
|
PROPERTIES = (
|
||||||
NAME
|
NAME, DOMAIN,
|
||||||
) = (
|
) = (
|
||||||
'name'
|
'name', 'domain',
|
||||||
)
|
)
|
||||||
|
|
||||||
properties_schema = {
|
properties_schema = {
|
||||||
|
@ -44,17 +47,36 @@ class KeystoneRole(resource.Resource):
|
||||||
properties.Schema.STRING,
|
properties.Schema.STRING,
|
||||||
_('Name of keystone role.'),
|
_('Name of keystone role.'),
|
||||||
update_allowed=True
|
update_allowed=True
|
||||||
|
),
|
||||||
|
DOMAIN: properties.Schema(
|
||||||
|
properties.Schema.STRING,
|
||||||
|
_('Name or id of keystone domain.'),
|
||||||
|
default='default',
|
||||||
|
constraints=[constraints.CustomConstraint('keystone.domain')],
|
||||||
|
support_status=support.SupportStatus(version='10.0.0')
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def translation_rules(self, properties):
|
||||||
|
return [
|
||||||
|
translation.TranslationRule(
|
||||||
|
properties,
|
||||||
|
translation.TranslationRule.RESOLVE,
|
||||||
|
[self.DOMAIN],
|
||||||
|
client_plugin=self.client_plugin(),
|
||||||
|
finder='get_domain_id'
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
def client(self):
|
def client(self):
|
||||||
return super(KeystoneRole, self).client().client
|
return super(KeystoneRole, self).client().client
|
||||||
|
|
||||||
def handle_create(self):
|
def handle_create(self):
|
||||||
role_name = (self.properties[self.NAME] or
|
role_name = (self.properties[self.NAME] or
|
||||||
self.physical_resource_name())
|
self.physical_resource_name())
|
||||||
|
domain = self.properties[self.DOMAIN]
|
||||||
role = self.client().roles.create(name=role_name)
|
role = self.client().roles.create(name=role_name,
|
||||||
|
domain=domain)
|
||||||
|
|
||||||
self.resource_id_set(role.id)
|
self.resource_id_set(role.id)
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import copy
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
from heat.engine import resource
|
from heat.engine import resource
|
||||||
|
@ -41,14 +42,6 @@ class KeystoneRoleTest(common.HeatTestCase):
|
||||||
super(KeystoneRoleTest, self).setUp()
|
super(KeystoneRoleTest, self).setUp()
|
||||||
|
|
||||||
self.ctx = utils.dummy_context()
|
self.ctx = utils.dummy_context()
|
||||||
|
|
||||||
self.stack = stack.Stack(
|
|
||||||
self.ctx, 'test_stack_keystone',
|
|
||||||
template.Template(keystone_role_template)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.test_role = self.stack['test_role']
|
|
||||||
|
|
||||||
# Mock client
|
# Mock client
|
||||||
self.keystoneclient = mock.Mock()
|
self.keystoneclient = mock.Mock()
|
||||||
self.patchobject(resource.Resource, 'client',
|
self.patchobject(resource.Resource, 'client',
|
||||||
|
@ -56,53 +49,75 @@ class KeystoneRoleTest(common.HeatTestCase):
|
||||||
client=self.keystoneclient))
|
client=self.keystoneclient))
|
||||||
self.roles = self.keystoneclient.roles
|
self.roles = self.keystoneclient.roles
|
||||||
|
|
||||||
def _get_mock_role(self):
|
def _get_rsrc(self, domain='default', without_name=False):
|
||||||
|
t = template.Template(keystone_role_template)
|
||||||
|
tmpl = copy.deepcopy(t)
|
||||||
|
tmpl['resources']['test_role']['Properties']['domain'] = domain
|
||||||
|
if without_name:
|
||||||
|
tmpl['resources']['test_role']['Properties'].pop('name')
|
||||||
|
test_stack = stack.Stack(self.ctx, 'test_keystone_role', tmpl)
|
||||||
|
test_role = test_stack['test_role']
|
||||||
|
return test_role
|
||||||
|
|
||||||
|
def _get_mock_role(self, domain='default'):
|
||||||
value = mock.MagicMock()
|
value = mock.MagicMock()
|
||||||
role_id = '477e8273-60a7-4c41-b683-fdb0bc7cd151'
|
role_id = '477e8273-60a7-4c41-b683-fdb0bc7cd151'
|
||||||
|
domain_id = domain
|
||||||
value.id = role_id
|
value.id = role_id
|
||||||
|
value.domain_id = domain_id
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def test_role_handle_create(self):
|
def _test_handle_create(self, domain='default'):
|
||||||
mock_role = self._get_mock_role()
|
test_role = self._get_rsrc(domain)
|
||||||
|
mock_role = self._get_mock_role(domain)
|
||||||
self.roles.create.return_value = mock_role
|
self.roles.create.return_value = mock_role
|
||||||
|
|
||||||
# validate the properties
|
# validate the properties
|
||||||
self.assertEqual('test_role_1',
|
self.assertEqual('test_role_1',
|
||||||
self.test_role.properties.get(role.KeystoneRole.NAME))
|
test_role.properties.get(role.KeystoneRole.NAME))
|
||||||
|
self.assertEqual(domain,
|
||||||
|
test_role.properties.get(role.KeystoneRole.DOMAIN))
|
||||||
|
|
||||||
self.test_role.handle_create()
|
test_role.handle_create()
|
||||||
|
|
||||||
# validate role creation with given name
|
# validate role creation with given name
|
||||||
self.roles.create.assert_called_once_with(name='test_role_1')
|
self.roles.create.assert_called_once_with(name='test_role_1',
|
||||||
|
domain=domain)
|
||||||
|
|
||||||
# validate physical resource id
|
# validate physical resource id
|
||||||
self.assertEqual(mock_role.id, self.test_role.resource_id)
|
self.assertEqual(mock_role.id, test_role.resource_id)
|
||||||
|
|
||||||
|
def test_role_handle_create(self):
|
||||||
|
self._test_handle_create()
|
||||||
|
|
||||||
|
def test_role_handle_create_with_domain(self):
|
||||||
|
self._test_handle_create(domain='d_test')
|
||||||
|
|
||||||
def test_role_handle_create_default_name(self):
|
def test_role_handle_create_default_name(self):
|
||||||
# reset the NAME value to None, to make sure role is
|
# reset the NAME value to None, to make sure role is
|
||||||
# created with physical_resource_name
|
# created with physical_resource_name
|
||||||
self.test_role.properties = mock.MagicMock()
|
test_role = self._get_rsrc(without_name=True)
|
||||||
self.test_role.properties.__getitem__.return_value = None
|
test_role.physical_resource_name = mock.Mock(
|
||||||
|
return_value='phy_role_name')
|
||||||
self.test_role.handle_create()
|
test_role.handle_create()
|
||||||
|
|
||||||
# validate role creation with default name
|
# validate role creation with default name
|
||||||
physical_resource_name = self.test_role.physical_resource_name()
|
self.roles.create.assert_called_once_with(name='phy_role_name',
|
||||||
self.roles.create.assert_called_once_with(name=physical_resource_name)
|
domain='default')
|
||||||
|
|
||||||
def test_role_handle_update(self):
|
def test_role_handle_update(self):
|
||||||
self.test_role.resource_id = '477e8273-60a7-4c41-b683-fdb0bc7cd151'
|
test_role = self._get_rsrc()
|
||||||
|
test_role.resource_id = '477e8273-60a7-4c41-b683-fdb0bc7cd151'
|
||||||
|
|
||||||
# update the name property
|
# update the name property
|
||||||
prop_diff = {role.KeystoneRole.NAME: 'test_role_1_updated'}
|
prop_diff = {role.KeystoneRole.NAME: 'test_role_1_updated'}
|
||||||
|
|
||||||
self.test_role.handle_update(json_snippet=None,
|
test_role.handle_update(json_snippet=None,
|
||||||
tmpl_diff=None,
|
tmpl_diff=None,
|
||||||
prop_diff=prop_diff)
|
prop_diff=prop_diff)
|
||||||
|
|
||||||
self.roles.update.assert_called_once_with(
|
self.roles.update.assert_called_once_with(
|
||||||
role=self.test_role.resource_id,
|
role=test_role.resource_id,
|
||||||
name=prop_diff[role.KeystoneRole.NAME]
|
name=prop_diff[role.KeystoneRole.NAME]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -110,5 +125,6 @@ class KeystoneRoleTest(common.HeatTestCase):
|
||||||
role = mock.Mock()
|
role = mock.Mock()
|
||||||
role.to_dict.return_value = {'attr': 'val'}
|
role.to_dict.return_value = {'attr': 'val'}
|
||||||
self.roles.get.return_value = role
|
self.roles.get.return_value = role
|
||||||
res = self.test_role._show_resource()
|
test_role = self._get_rsrc()
|
||||||
|
res = test_role._show_resource()
|
||||||
self.assertEqual({'attr': 'val'}, res)
|
self.assertEqual({'attr': 'val'}, res)
|
||||||
|
|
Loading…
Reference in New Issue