diff --git a/awx/main/fields.py b/awx/main/fields.py index 3d541d524a..a4519610c3 100644 --- a/awx/main/fields.py +++ b/awx/main/fields.py @@ -48,7 +48,9 @@ from awx.main.models.rbac import batch_role_ancestor_rebuilding, Role from awx.main import utils -__all__ = ['AutoOneToOneField', 'ImplicitRoleField', 'JSONField', 'SmartFilterField'] +__all__ = ['AutoOneToOneField', 'ImplicitRoleField', 'JSONField', + 'SmartFilterField', 'update_role_parentage_for_instance', + 'is_implicit_parent'] # Provide a (better) custom error message for enum jsonschema validation @@ -181,6 +183,23 @@ def is_implicit_parent(parent_role, child_role): return False +def update_role_parentage_for_instance(instance): + '''update_role_parentage_for_instance + updates the parents listing for all the roles + of a given instance if they have changed + ''' + for implicit_role_field in getattr(instance.__class__, '__implicit_role_fields'): + cur_role = getattr(instance, implicit_role_field.name) + new_parents = implicit_role_field._resolve_parent_roles(instance) + cur_role.parents.set(new_parents) + new_parents_list = list(new_parents) + new_parents_list.sort() + new_parents_json = json.dumps(new_parents_list) + if cur_role.implicit_parents != new_parents_json: + cur_role.implicit_parents = new_parents_json + cur_role.save() + + class ImplicitRoleDescriptor(ForwardManyToOneDescriptor): pass @@ -303,19 +322,7 @@ class ImplicitRoleField(models.ForeignKey): type(latest_instance).objects.filter(pk=latest_instance.pk).update(**updates) Role.rebuild_role_ancestor_list(role_ids, []) - # Update parentage if necessary - for implicit_role_field in getattr(latest_instance.__class__, '__implicit_role_fields'): - cur_role = getattr(latest_instance, implicit_role_field.name) - original_parents = set(json.loads(cur_role.implicit_parents)) - new_parents = implicit_role_field._resolve_parent_roles(latest_instance) - cur_role.parents.remove(*list(original_parents - new_parents)) - cur_role.parents.add(*list(new_parents - original_parents)) - new_parents_list = list(new_parents) - new_parents_list.sort() - new_parents_json = json.dumps(new_parents_list) - if cur_role.implicit_parents != new_parents_json: - cur_role.implicit_parents = new_parents_json - cur_role.save() + update_role_parentage_for_instance(latest_instance) instance.refresh_from_db() diff --git a/awx/main/signals.py b/awx/main/signals.py index f75fa50bf0..ea4a5ae927 100644 --- a/awx/main/signals.py +++ b/awx/main/signals.py @@ -34,7 +34,10 @@ from awx.api.serializers import * # noqa from awx.main.utils import model_instance_diff, model_to_dict, camelcase_to_underscore from awx.main.utils import ignore_inventory_computed_fields, ignore_inventory_group_removal, _inventory_updates from awx.main.tasks import update_inventory_computed_fields -from awx.main.fields import is_implicit_parent +from awx.main.fields import ( + is_implicit_parent, + update_role_parentage_for_instance, +) from awx.main import consumers @@ -256,20 +259,7 @@ def save_related_job_templates(sender, instance, **kwargs): if instance.__original_org != instance.organization: jtq = JobTemplate.objects.filter(**{sender.__name__.lower(): instance}) for jt in jtq: - for implicit_role_field in getattr(JobTemplate, '__implicit_role_fields'): - role = getattr(jt, implicit_role_field.name) - original_parents = set(json.loads(role.implicit_parents)) - new_parents = implicit_role_field._resolve_parent_roles(instance) - - role.parents.remove(*list(original_parents - new_parents)) - role.parents.add(*list(new_parents - original_parents)) - - new_parents_list = list(new_parents) - new_parents_list.sort() - new_parents_json = json.dumps(new_parents_list) - if role.implicit_parents != new_parents_json: - role.implicit_parents = new_parents_json - role.save() + update_role_parentage_for_instance(jt) def connect_computed_field_signals():