From e076f1ee2aa6604b97c7a212597364751210ff5f Mon Sep 17 00:00:00 2001 From: John Westcott IV Date: Fri, 9 Sep 2022 12:11:14 -0400 Subject: [PATCH] Making labels additive and not adding a many item to config if already in parent --- awx/main/models/jobs.py | 10 +++++----- awx/main/models/unified_jobs.py | 5 ++++- awx/main/utils/common.py | 5 ++++- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/awx/main/models/jobs.py b/awx/main/models/jobs.py index 63cbb89842..4316b968bc 100644 --- a/awx/main/models/jobs.py +++ b/awx/main/models/jobs.py @@ -976,11 +976,11 @@ class LaunchTimeConfigBase(BaseModel): if isinstance(field, models.ManyToManyField): if not self.pk: continue # unsaved object can't have related many-to-many - prompt_val = set(getattr(self, prompt_name).all()) - if len(prompt_val) > 0: - # We used to return a set but that will cause issues with order for ordered fields (like instance_groups) - # So instead we will return an array of items - data[prompt_name] = [item for item in getattr(self, prompt_name).all()] + prompt_values = list(getattr(self, prompt_name).all()) + # Many to manys can't distinguish between None and [] + # Because of this, from a config perspective, we assume [] is none and we don't save [] into the config + if len(prompt_values) > 0: + data[prompt_name] = prompt_values elif prompt_name == 'extra_vars': if self.extra_vars: if display: diff --git a/awx/main/models/unified_jobs.py b/awx/main/models/unified_jobs.py index b3d8bc4bee..fbfb0c32f4 100644 --- a/awx/main/models/unified_jobs.py +++ b/awx/main/models/unified_jobs.py @@ -1007,8 +1007,11 @@ class UnifiedJob( # Here we are doing a loop to make sure we preserve order in case this is a Ordered field job_item = kwargs.get(field_name, []) if job_item: + parent_items = getattr(parent, field_name, []).all() for item in job_item: - getattr(config, field_name).add(item) + # Do not include this item in the config if its in the parent + if item not in parent_items: + getattr(config, field_name).add(item) return config diff --git a/awx/main/utils/common.py b/awx/main/utils/common.py index c01be9957d..3366190ecf 100644 --- a/awx/main/utils/common.py +++ b/awx/main/utils/common.py @@ -531,13 +531,16 @@ def copy_m2m_relationships(obj1, obj2, fields, kwargs=None): src_field_value = getattr(obj1, field_name) if kwargs and field_name in kwargs: override_field_val = kwargs[field_name] - # TODO: Should we spike this our or just put the for loop inside the next if and make everything respect order? if field_name == 'instance_groups': # instance_groups are a list but we need to preserve the order for ig_id in override_field_val: getattr(obj2, field_name).add(ig_id) continue if isinstance(override_field_val, (set, list, QuerySet)): + # Labels are additive so we are going to add any src labels in addition to the override labels + if field_name == 'labels': + for jt_label in src_field_value.all(): + getattr(obj2, field_name).add(jt_label.id) getattr(obj2, field_name).add(*override_field_val) continue if override_field_val.__class__.__name__ == 'ManyRelatedManager':