Initial (editable) pass of adding JT.organization

This is the old version of this feature from 2019
  this allows setting the organization in the data sent
  to the API when creating a JT, and exposes the field
  in the UI as well

Subsequent commit changes the field from editable
  to read-only, but as of this commit, the machinery
  is not hooked up to infer it from project
This commit is contained in:
AlanCoding
2020-01-16 14:59:43 -05:00
parent 1876849d89
commit daa9282790
46 changed files with 985 additions and 377 deletions

View File

@@ -56,7 +56,8 @@ from awx.main import utils
__all__ = ['AutoOneToOneField', 'ImplicitRoleField', 'JSONField',
'SmartFilterField', 'OrderedManyToManyField',
'update_role_parentage_for_instance', 'is_implicit_parent']
'update_role_parentage_for_instance',
'is_implicit_parent']
# Provide a (better) custom error message for enum jsonschema validation
@@ -140,8 +141,9 @@ def resolve_role_field(obj, field):
return []
if len(field_components) == 1:
role_cls = str(utils.get_current_apps().get_model('main', 'Role'))
if not str(type(obj)) == role_cls:
# use extremely generous duck typing to accomidate all possible forms
# of the model that may be used during various migrations
if obj._meta.model_name != 'role' or obj._meta.app_label != 'main':
raise Exception(smart_text('{} refers to a {}, not a Role'.format(field, type(obj))))
ret.append(obj.id)
else:
@@ -197,18 +199,30 @@ def update_role_parentage_for_instance(instance):
updates the parents listing for all the roles
of a given instance if they have changed
'''
changed_ct = 0
for implicit_role_field in getattr(instance.__class__, '__implicit_role_fields'):
changed = False
cur_role = getattr(instance, implicit_role_field.name)
original_parents = set(json.loads(cur_role.implicit_parents))
new_parents = implicit_role_field._resolve_parent_roles(instance)
cur_role.parents.remove(*list(original_parents - new_parents))
cur_role.parents.add(*list(new_parents - original_parents))
removals = original_parents - new_parents
if removals:
changed = True
cur_role.parents.remove(*list(removals))
additions = new_parents - original_parents
if additions:
changed = True
cur_role.parents.add(*list(additions))
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:
changed = True
cur_role.implicit_parents = new_parents_json
cur_role.save()
if changed:
changed_ct += 1
return changed_ct
class ImplicitRoleDescriptor(ForwardManyToOneDescriptor):
@@ -256,20 +270,18 @@ class ImplicitRoleField(models.ForeignKey):
field_names = [field_names]
for field_name in field_names:
# Handle the OR syntax for role parents
if type(field_name) == tuple:
continue
if type(field_name) == bytes:
field_name = field_name.decode('utf-8')
if field_name.startswith('singleton:'):
continue
field_name, sep, field_attr = field_name.partition('.')
field = getattr(cls, field_name)
# Non existent fields will occur if ever a parent model is
# moved inside a migration, needed for job_template_organization_field
# migration in particular
# consistency is assured by unit test awx.main.tests.functional
field = getattr(cls, field_name, None)
if type(field) is ReverseManyToOneDescriptor or \
if field and type(field) is ReverseManyToOneDescriptor or \
type(field) is ManyToManyDescriptor:
if '.' in field_attr: