From fbf24492d8e1dba42044c92c6120f57995637ba2 Mon Sep 17 00:00:00 2001 From: AlanCoding Date: Mon, 15 May 2017 15:41:57 -0400 Subject: [PATCH] Instance group preference order consistent with docs --- awx/main/models/ad_hoc_commands.py | 13 ++++++ awx/main/models/inventory.py | 5 +- awx/main/models/jobs.py | 2 +- awx/main/models/projects.py | 5 +- awx/main/models/unified_jobs.py | 12 +++-- awx/main/tests/functional/test_instances.py | 51 +++++++++++++++++++++ 6 files changed, 82 insertions(+), 6 deletions(-) diff --git a/awx/main/models/ad_hoc_commands.py b/awx/main/models/ad_hoc_commands.py index 57fb071c53..8b04f457e1 100644 --- a/awx/main/models/ad_hoc_commands.py +++ b/awx/main/models/ad_hoc_commands.py @@ -203,6 +203,19 @@ class AdHocCommand(UnifiedJob, JobNotificationMixin): update_fields.append('name') super(AdHocCommand, self).save(*args, **kwargs) + @property + def preferred_instance_groups(self): + if self.inventory is not None and self.inventory.organization is not None: + organization_groups = [x for x in self.inventory.organization.instance_groups.all()] + else: + organization_groups = [] + if self.inventory is not None: + inventory_groups = [x for x in self.inventory.instance_groups.all()] + selected_groups = inventory_groups + organization_groups + if not selected_groups: + return self.global_instance_groups + return selected_groups + ''' JobNotificationMixin ''' diff --git a/awx/main/models/inventory.py b/awx/main/models/inventory.py index 08d3a6a691..7dcad06c64 100644 --- a/awx/main/models/inventory.py +++ b/awx/main/models/inventory.py @@ -1379,7 +1379,10 @@ class InventoryUpdate(UnifiedJob, InventorySourceOptions, JobNotificationMixin): if self.inventory_source.inventory is not None: inventory_groups = [x for x in self.inventory_source.inventory.instance_groups.all()] template_groups = [x for x in super(InventoryUpdate, self).preferred_instance_groups] - return template_groups + inventory_groups + organization_groups + selected_groups = template_groups + inventory_groups + organization_groups + if not selected_groups: + return self.global_instance_groups + return selected_groups def _build_job_explanation(self): if not self.job_explanation: diff --git a/awx/main/models/jobs.py b/awx/main/models/jobs.py index 2380a707ba..e057a70eac 100644 --- a/awx/main/models/jobs.py +++ b/awx/main/models/jobs.py @@ -669,7 +669,7 @@ class Job(UnifiedJob, JobOptions, SurveyJobMixin, JobNotificationMixin): template_groups = [] selected_groups = template_groups + inventory_groups + organization_groups if not selected_groups: - return super(Job, self).preferred_instance_groups + return self.global_instance_groups return selected_groups # Job Credential required diff --git a/awx/main/models/projects.py b/awx/main/models/projects.py index 5d5693dc23..549b6c01bc 100644 --- a/awx/main/models/projects.py +++ b/awx/main/models/projects.py @@ -524,4 +524,7 @@ class ProjectUpdate(UnifiedJob, ProjectOptions, JobNotificationMixin): else: organization_groups = [] template_groups = [x for x in super(ProjectUpdate, self).preferred_instance_groups] - return template_groups + organization_groups + selected_groups = template_groups + organization_groups + if not selected_groups: + return self.global_instance_groups + return selected_groups diff --git a/awx/main/models/unified_jobs.py b/awx/main/models/unified_jobs.py index 089d4107ab..edcecbcc02 100644 --- a/awx/main/models/unified_jobs.py +++ b/awx/main/models/unified_jobs.py @@ -1066,9 +1066,15 @@ class UnifiedJob(PolymorphicModel, PasswordFieldsModel, CommonModelNameNotUnique ''' Return Instance/Rampart Groups preferred by this unified job templates ''' + if not self.unified_job_template: + return [] + template_groups = [x for x in self.unified_job_template.instance_groups.all()] + return template_groups + + @property + def global_instance_groups(self): from awx.main.models.ha import InstanceGroup default_instance_group = InstanceGroup.objects.filter(name='tower') - template_groups = [x for x in self.unified_job_template.instance_groups.all()] - if not template_groups and default_instance_group.exists(): + if default_instance_group.exists(): return [default_instance_group.first()] - return template_groups + return [] diff --git a/awx/main/tests/functional/test_instances.py b/awx/main/tests/functional/test_instances.py index 6a85cc9cb9..780900b028 100644 --- a/awx/main/tests/functional/test_instances.py +++ b/awx/main/tests/functional/test_instances.py @@ -1,5 +1,7 @@ import pytest +from awx.main.models import AdHocCommand, InventoryUpdate, Job, JobTemplate, ProjectUpdate + @pytest.mark.django_db def test_default_tower_instance_group(default_instance_group, job_factory): @@ -38,3 +40,52 @@ def test_instance_group_capacity(instance_factory, instance_group_factory): assert ig_all.capacity == 300 ig_single = instance_group_factory("single", instances=[i1]) assert ig_single.capacity == 100 + + +@pytest.mark.django_db +class TestInstanceGroupOrdering: + + def test_ad_hoc_instance_groups(self, instance_group_factory, inventory, default_instance_group): + ad_hoc = AdHocCommand.objects.create(inventory=inventory) + assert ad_hoc.preferred_instance_groups == [default_instance_group] + ig_org = instance_group_factory("OrgIstGrp", [default_instance_group.instances.first()]) + ig_inv = instance_group_factory("InvIstGrp", [default_instance_group.instances.first()]) + inventory.organization.instance_groups.add(ig_org) + assert ad_hoc.preferred_instance_groups == [ig_org] + inventory.instance_groups.add(ig_inv) + assert ad_hoc.preferred_instance_groups == [ig_inv, ig_org] + + def test_inventory_update_instance_groups(self, instance_group_factory, inventory_source, default_instance_group): + iu = InventoryUpdate.objects.create(inventory_source=inventory_source) + assert iu.preferred_instance_groups == [default_instance_group] + ig_org = instance_group_factory("OrgIstGrp", [default_instance_group.instances.first()]) + ig_inv = instance_group_factory("InvIstGrp", [default_instance_group.instances.first()]) + ig_tmp = instance_group_factory("TmpIstGrp", [default_instance_group.instances.first()]) + inventory_source.inventory.organization.instance_groups.add(ig_org) + inventory_source.inventory.instance_groups.add(ig_inv) + assert iu.preferred_instance_groups == [ig_inv, ig_org] + inventory_source.instance_groups.add(ig_tmp) + assert iu.preferred_instance_groups == [ig_tmp, ig_inv, ig_org] + + def test_project_update_instance_groups(self, instance_group_factory, project, default_instance_group): + pu = ProjectUpdate.objects.create(project=project) + assert pu.preferred_instance_groups == [default_instance_group] + ig_org = instance_group_factory("OrgIstGrp", [default_instance_group.instances.first()]) + ig_tmp = instance_group_factory("TmpIstGrp", [default_instance_group.instances.first()]) + project.organization.instance_groups.add(ig_org) + assert pu.preferred_instance_groups == [ig_org] + project.instance_groups.add(ig_tmp) + assert pu.preferred_instance_groups == [ig_tmp, ig_org] + + def test_job_instance_groups(self, instance_group_factory, inventory, project, default_instance_group): + jt = JobTemplate.objects.create(inventory=inventory, project=project) + job = Job.objects.create(inventory=inventory, job_template=jt, project=project) + assert job.preferred_instance_groups == [default_instance_group] + ig_org = instance_group_factory("OrgIstGrp", [default_instance_group.instances.first()]) + ig_inv = instance_group_factory("InvIstGrp", [default_instance_group.instances.first()]) + ig_tmp = instance_group_factory("TmpIstGrp", [default_instance_group.instances.first()]) + project.organization.instance_groups.add(ig_org) + inventory.instance_groups.add(ig_inv) + assert job.preferred_instance_groups == [ig_inv, ig_org] + job.job_template.instance_groups.add(ig_tmp) + assert job.preferred_instance_groups == [ig_tmp, ig_inv, ig_org]