mirror of
https://github.com/ansible/awx.git
synced 2026-05-09 10:27:37 -02:30
Optimized implicit role creation for new instances of resources
This commit is contained in:
@@ -5,7 +5,6 @@ import json
|
|||||||
|
|
||||||
# Django
|
# Django
|
||||||
from django.db.models.signals import (
|
from django.db.models.signals import (
|
||||||
pre_save,
|
|
||||||
post_save,
|
post_save,
|
||||||
post_delete,
|
post_delete,
|
||||||
)
|
)
|
||||||
@@ -118,7 +117,6 @@ class ImplicitRoleField(models.ForeignKey):
|
|||||||
setattr(cls, '__implicit_role_fields', [])
|
setattr(cls, '__implicit_role_fields', [])
|
||||||
getattr(cls, '__implicit_role_fields').append(self)
|
getattr(cls, '__implicit_role_fields').append(self)
|
||||||
|
|
||||||
pre_save.connect(self._pre_save, cls, True, dispatch_uid='implicit-role-pre-save')
|
|
||||||
post_save.connect(self._post_save, cls, True, dispatch_uid='implicit-role-post-save')
|
post_save.connect(self._post_save, cls, True, dispatch_uid='implicit-role-post-save')
|
||||||
post_delete.connect(self._post_delete, cls, True, dispatch_uid='implicit-role-post-delete')
|
post_delete.connect(self._post_delete, cls, True, dispatch_uid='implicit-role-post-delete')
|
||||||
add_lazy_relation(cls, self, "self", self.bind_m2m_changed)
|
add_lazy_relation(cls, self, "self", self.bind_m2m_changed)
|
||||||
@@ -175,39 +173,44 @@ class ImplicitRoleField(models.ForeignKey):
|
|||||||
getattr(instance, self.name).parents.remove(getattr(obj, field_attr))
|
getattr(instance, self.name).parents.remove(getattr(obj, field_attr))
|
||||||
return _m2m_update
|
return _m2m_update
|
||||||
|
|
||||||
def _create_role_instance_if_not_exists(self, instance):
|
|
||||||
role = getattr(instance, self.name, None)
|
|
||||||
if role:
|
|
||||||
return
|
|
||||||
Role_ = get_current_apps().get_model('main', 'Role')
|
|
||||||
role = Role_.objects.create(
|
|
||||||
created=now(),
|
|
||||||
modified=now(),
|
|
||||||
role_field=self.name,
|
|
||||||
name=self.role_name,
|
|
||||||
description=self.role_description
|
|
||||||
)
|
|
||||||
setattr(instance, self.name, role)
|
|
||||||
|
|
||||||
def _patch_role_content_object(self, instance):
|
|
||||||
role = getattr(instance, self.name)
|
|
||||||
role.content_object = instance
|
|
||||||
role.save()
|
|
||||||
|
|
||||||
def _pre_save(self, instance, *args, **kwargs):
|
|
||||||
for implicit_role_field in getattr(instance.__class__, '__implicit_role_fields'):
|
|
||||||
implicit_role_field._create_role_instance_if_not_exists(instance)
|
|
||||||
|
|
||||||
def _post_save(self, instance, created, *args, **kwargs):
|
def _post_save(self, instance, created, *args, **kwargs):
|
||||||
if created:
|
Role_ = get_current_apps().get_model('main', 'Role')
|
||||||
for implicit_role_field in getattr(instance.__class__, '__implicit_role_fields'):
|
ContentType_ = get_current_apps().get_model('contenttypes', 'ContentType')
|
||||||
implicit_role_field._patch_role_content_object(instance)
|
ct_id = ContentType_.objects.get_for_model(instance).id
|
||||||
|
|
||||||
with batch_role_ancestor_rebuilding():
|
with batch_role_ancestor_rebuilding():
|
||||||
|
# Create any missing role objects
|
||||||
|
missing_roles = []
|
||||||
for implicit_role_field in getattr(instance.__class__, '__implicit_role_fields'):
|
for implicit_role_field in getattr(instance.__class__, '__implicit_role_fields'):
|
||||||
cur_role = getattr(instance, implicit_role_field.name)
|
cur_role = getattr(instance, implicit_role_field.name, None)
|
||||||
|
if cur_role is None:
|
||||||
|
missing_roles.append(
|
||||||
|
Role_(
|
||||||
|
created=now(),
|
||||||
|
modified=now(),
|
||||||
|
role_field=implicit_role_field.name,
|
||||||
|
name=implicit_role_field.role_name,
|
||||||
|
description=implicit_role_field.role_description,
|
||||||
|
content_type_id=ct_id,
|
||||||
|
object_id=instance.id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if len(missing_roles) > 0:
|
||||||
|
Role_.objects.bulk_create(missing_roles)
|
||||||
|
updates = {}
|
||||||
|
role_ids = []
|
||||||
|
for role in Role_.objects.filter(content_type_id=ct_id, object_id=instance.id):
|
||||||
|
setattr(instance, role.role_field, role)
|
||||||
|
updates[role.role_field] = role.id
|
||||||
|
role_ids.append(role.id)
|
||||||
|
type(instance).objects.filter(pk=instance.pk).update(**updates)
|
||||||
|
Role_._simultaneous_ancestry_rebuild(role_ids)
|
||||||
|
|
||||||
|
# Update parentage if necessary
|
||||||
|
for implicit_role_field in getattr(instance.__class__, '__implicit_role_fields'):
|
||||||
|
cur_role = getattr(instance, implicit_role_field.name)
|
||||||
original_parents = set(json.loads(cur_role.implicit_parents))
|
original_parents = set(json.loads(cur_role.implicit_parents))
|
||||||
new_parents = implicit_role_field._resolve_parent_roles(instance)
|
new_parents = implicit_role_field._resolve_parent_roles(instance)
|
||||||
cur_role.parents.remove(*list(original_parents - new_parents))
|
cur_role.parents.remove(*list(original_parents - new_parents))
|
||||||
cur_role.parents.add(*list(new_parents - original_parents))
|
cur_role.parents.add(*list(new_parents - original_parents))
|
||||||
new_parents_list = list(new_parents)
|
new_parents_list = list(new_parents)
|
||||||
|
|||||||
Reference in New Issue
Block a user