Keystone::User observe reality implementation
Add override parse_live_resource_data method implementation for OS::Keystone::User resource. Also, add translation rule Resolve for correct handling domain, groups and default_project properties. implements bp get-reality-for-resources Change-Id: I6479dc1fb5672c1f2abd5b4272755b057057f3bf
This commit is contained in:
parent
21af1d55e5
commit
da1af078fe
|
@ -17,6 +17,7 @@ from heat.engine import properties
|
|||
from heat.engine import resource
|
||||
from heat.engine.resources.openstack.keystone import role_assignments
|
||||
from heat.engine import support
|
||||
from heat.engine import translation
|
||||
|
||||
|
||||
class KeystoneUser(resource.Resource,
|
||||
|
@ -52,7 +53,7 @@ class KeystoneUser(resource.Resource,
|
|||
),
|
||||
DOMAIN: properties.Schema(
|
||||
properties.Schema.STRING,
|
||||
_('Name of keystone domain.'),
|
||||
_('Name or ID of keystone domain.'),
|
||||
default='default',
|
||||
update_allowed=True,
|
||||
constraints=[constraints.CustomConstraint('keystone.domain')]
|
||||
|
@ -81,7 +82,7 @@ class KeystoneUser(resource.Resource,
|
|||
),
|
||||
DEFAULT_PROJECT: properties.Schema(
|
||||
properties.Schema.STRING,
|
||||
_('Default project of keystone user.'),
|
||||
_('Name or ID of default project of keystone user.'),
|
||||
update_allowed=True,
|
||||
constraints=[constraints.CustomConstraint('keystone.project')]
|
||||
),
|
||||
|
@ -100,6 +101,31 @@ class KeystoneUser(resource.Resource,
|
|||
properties_schema.update(
|
||||
role_assignments.KeystoneRoleAssignmentMixin.mixin_properties_schema)
|
||||
|
||||
def translation_rules(self, properties):
|
||||
return [
|
||||
translation.TranslationRule(
|
||||
properties,
|
||||
translation.TranslationRule.RESOLVE,
|
||||
[self.DOMAIN],
|
||||
client_plugin=self.client_plugin(),
|
||||
finder='get_domain_id'
|
||||
),
|
||||
translation.TranslationRule(
|
||||
properties,
|
||||
translation.TranslationRule.RESOLVE,
|
||||
[self.DEFAULT_PROJECT],
|
||||
client_plugin=self.client_plugin(),
|
||||
finder='get_project_id'
|
||||
),
|
||||
translation.TranslationRule(
|
||||
properties,
|
||||
translation.TranslationRule.RESOLVE,
|
||||
[self.GROUPS],
|
||||
client_plugin=self.client_plugin(),
|
||||
finder='get_group_id'
|
||||
),
|
||||
]
|
||||
|
||||
def validate(self):
|
||||
super(KeystoneUser, self).validate()
|
||||
self.validate_assignment_properties()
|
||||
|
@ -138,40 +164,27 @@ class KeystoneUser(resource.Resource,
|
|||
return
|
||||
|
||||
values['user'] = user_id
|
||||
domain = (self.client_plugin().get_domain_id(domain))
|
||||
|
||||
values['domain'] = domain
|
||||
|
||||
return self.client().users.update(**values)
|
||||
|
||||
def _add_user_to_groups(self, user_id, groups):
|
||||
if groups is not None:
|
||||
group_ids = [self.client_plugin().get_group_id(group)
|
||||
for group in groups]
|
||||
|
||||
for group_id in group_ids:
|
||||
for group_id in groups:
|
||||
self.client().users.add_to_group(user_id,
|
||||
group_id)
|
||||
|
||||
def _remove_user_from_groups(self, user_id, groups):
|
||||
if groups is not None:
|
||||
group_ids = [self.client_plugin().get_group_id(group)
|
||||
for group in groups]
|
||||
|
||||
for group_id in group_ids:
|
||||
for group_id in groups:
|
||||
self.client().users.remove_from_group(user_id,
|
||||
group_id)
|
||||
|
||||
def _find_diff(self, updated_prps, stored_prps):
|
||||
new_group_ids = [self.client_plugin().get_group_id(group)
|
||||
for group in
|
||||
(set(updated_prps or []) -
|
||||
set(stored_prps or []))]
|
||||
new_group_ids = list(set(updated_prps or []) - set(stored_prps or []))
|
||||
|
||||
removed_group_ids = [self.client_plugin().get_group_id(group)
|
||||
for group in
|
||||
(set(stored_prps or []) -
|
||||
set(updated_prps or []))]
|
||||
removed_group_ids = list(set(stored_prps or []) -
|
||||
set(updated_prps or []))
|
||||
|
||||
return new_group_ids, removed_group_ids
|
||||
|
||||
|
@ -179,13 +192,11 @@ class KeystoneUser(resource.Resource,
|
|||
user_name = (self.properties[self.NAME] or
|
||||
self.physical_resource_name())
|
||||
description = self.properties[self.DESCRIPTION]
|
||||
domain = self.client_plugin().get_domain_id(
|
||||
self.properties[self.DOMAIN])
|
||||
domain = self.properties[self.DOMAIN]
|
||||
enabled = self.properties[self.ENABLED]
|
||||
email = self.properties[self.EMAIL]
|
||||
password = self.properties[self.PASSWORD]
|
||||
default_project = self.client_plugin().get_project_id(
|
||||
self.properties[self.DEFAULT_PROJECT])
|
||||
default_project = self.properties[self.DEFAULT_PROJECT]
|
||||
groups = self.properties[self.GROUPS]
|
||||
|
||||
user = self.client().users.create(
|
||||
|
@ -244,15 +255,26 @@ class KeystoneUser(resource.Resource,
|
|||
self.update_assignment(prop_diff=prop_diff,
|
||||
user_id=self.resource_id)
|
||||
|
||||
def parse_live_resource_data(self, resource_properties, resource_data):
|
||||
user_reality = {
|
||||
self.ROLES: self.parse_list_assignments(user_id=self.resource_id),
|
||||
self.DEFAULT_PROJECT: resource_data.get('default_project_id'),
|
||||
self.DOMAIN: resource_data.get('domain_id'),
|
||||
self.GROUPS: [group.id for group in self.client().groups.list(
|
||||
user=self.resource_id)]
|
||||
}
|
||||
props_keys = [self.NAME, self.DESCRIPTION, self.ENABLED, self.EMAIL]
|
||||
for key in props_keys:
|
||||
user_reality.update({key: resource_data.get(key)})
|
||||
return user_reality
|
||||
|
||||
def handle_delete(self):
|
||||
if self.resource_id is not None:
|
||||
with self.client_plugin().ignore_not_found:
|
||||
if self.properties[self.GROUPS] is not None:
|
||||
self._remove_user_from_groups(
|
||||
self.resource_id,
|
||||
[self.client_plugin().get_group_id(group)
|
||||
for group in
|
||||
self.properties[self.GROUPS]])
|
||||
self.properties[self.GROUPS])
|
||||
|
||||
self.client().users.delete(self.resource_id)
|
||||
|
||||
|
|
|
@ -280,3 +280,39 @@ class KeystoneUserTest(common.HeatTestCase):
|
|||
self.users.get.return_value = user
|
||||
res = self.test_user._show_resource()
|
||||
self.assertEqual({'attr': 'val'}, res)
|
||||
|
||||
def test_get_live_state(self):
|
||||
user = mock.MagicMock()
|
||||
user.to_dict.return_value = {
|
||||
'description': '',
|
||||
'enabled': True,
|
||||
'domain_id': 'default',
|
||||
'email': 'fake@312.com',
|
||||
'default_project_id': '859aee961e30408e813853e1cffad089',
|
||||
'id': '4060e773e26842a88b7490528d78de4f',
|
||||
'name': 'user1-user-275g3vdmwuo5'}
|
||||
self.users.get.return_value = user
|
||||
role = mock.MagicMock()
|
||||
role.to_dict.return_value = {
|
||||
'scope': {'domain': {'id': '1234'}}, 'role': {'id': '4321'}
|
||||
}
|
||||
self.keystoneclient.role_assignments.list.return_value = [role]
|
||||
group = mock.MagicMock()
|
||||
group.id = '39393'
|
||||
self.keystoneclient.groups.list.return_value = [group]
|
||||
self.test_user.resource_id = '1111'
|
||||
|
||||
reality = self.test_user.get_live_state(self.test_user.properties)
|
||||
expected = {
|
||||
'description': '',
|
||||
'enabled': True,
|
||||
'domain': 'default',
|
||||
'email': 'fake@312.com',
|
||||
'default_project': '859aee961e30408e813853e1cffad089',
|
||||
'name': 'user1-user-275g3vdmwuo5',
|
||||
'groups': ['39393'],
|
||||
'roles': [{'role': '4321', 'domain': '1234', 'project': None}]
|
||||
}
|
||||
self.assertEqual(set(expected.keys()), set(reality.keys()))
|
||||
for key in expected:
|
||||
self.assertEqual(expected[key], reality[key])
|
||||
|
|
Loading…
Reference in New Issue