mirror of
https://github.com/ansible/awx.git
synced 2026-05-21 07:47:44 -02:30
Merge pull request #322 from wwitzel3/issue-7501
Update HostManager to return distinct hostnames
This commit is contained in:
@@ -41,8 +41,10 @@ class HostManager(models.Manager):
|
|||||||
# If we don't disable this, a filter of {'inventory': self.instance} gets automatically
|
# If we don't disable this, a filter of {'inventory': self.instance} gets automatically
|
||||||
# injected by the related object mapper.
|
# injected by the related object mapper.
|
||||||
self.core_filters = {}
|
self.core_filters = {}
|
||||||
|
|
||||||
qs = qs & q
|
qs = qs & q
|
||||||
return qs.distinct()
|
unique_by_name = qs.order_by('name', 'pk').distinct('name')
|
||||||
|
return qs.filter(pk__in=unique_by_name)
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1195,25 +1195,9 @@ class JobEvent(CreatedModifiedModel):
|
|||||||
pass
|
pass
|
||||||
return hostnames
|
return hostnames
|
||||||
|
|
||||||
def _update_smart_inventory_hosts(self, hostnames):
|
|
||||||
'''If the job the job_event is for was run using a Smart Inventory
|
|
||||||
update the hosts fields related to job history and summary.
|
|
||||||
'''
|
|
||||||
with ignore_inventory_computed_fields():
|
|
||||||
if hasattr(self.job, 'inventory') and self.job.inventory.kind == 'smart':
|
|
||||||
logger.debug(self.job.inventory)
|
|
||||||
smart_hosts = self.job.inventory.hosts.filter(name__in=hostnames)
|
|
||||||
for smart_host in smart_hosts:
|
|
||||||
host_summary = self.job.job_host_summaries.get(host_name=smart_host.name)
|
|
||||||
smart_host.inventory.jobs.add(self.job)
|
|
||||||
smart_host.last_job_id = self.job_id
|
|
||||||
smart_host.last_job_host_summary_id = host_summary.pk
|
|
||||||
smart_host.save()
|
|
||||||
|
|
||||||
def _update_host_summary_from_stats(self, hostnames):
|
def _update_host_summary_from_stats(self, hostnames):
|
||||||
with ignore_inventory_computed_fields():
|
with ignore_inventory_computed_fields():
|
||||||
from awx.main.models.inventory import Host
|
qs = self.job.inventory.hosts.filter(name__in=hostnames)
|
||||||
qs = Host.objects.filter(inventory__jobs__id=self.job_id, name__in=hostnames)
|
|
||||||
job = self.job
|
job = self.job
|
||||||
for host in hostnames:
|
for host in hostnames:
|
||||||
host_stats = {}
|
host_stats = {}
|
||||||
@@ -1269,7 +1253,6 @@ class JobEvent(CreatedModifiedModel):
|
|||||||
|
|
||||||
hostnames = self._hostnames()
|
hostnames = self._hostnames()
|
||||||
self._update_host_summary_from_stats(hostnames)
|
self._update_host_summary_from_stats(hostnames)
|
||||||
self._update_smart_inventory_hosts(hostnames)
|
|
||||||
self.job.inventory.update_computed_fields()
|
self.job.inventory.update_computed_fields()
|
||||||
|
|
||||||
emit_channel_notification('jobs-summary', dict(group_name='jobs', unified_job_id=self.job.id))
|
emit_channel_notification('jobs-summary', dict(group_name='jobs', unified_job_id=self.job.id))
|
||||||
|
|||||||
@@ -204,22 +204,6 @@ def test_delete_inventory_group(delete, group, alice, role_field, expected_statu
|
|||||||
delete(reverse('api:group_detail', kwargs={'pk': group.id}), alice, expect=expected_status_code)
|
delete(reverse('api:group_detail', kwargs={'pk': group.id}), alice, expect=expected_status_code)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
|
||||||
def test_create_inventory_smarthost(post, get, inventory, admin_user, organization):
|
|
||||||
data = { 'name': 'Host 1', 'description': 'Test Host'}
|
|
||||||
smart_inventory = Inventory(name='smart',
|
|
||||||
kind='smart',
|
|
||||||
organization=organization,
|
|
||||||
host_filter='inventory_sources__source=ec2')
|
|
||||||
smart_inventory.save()
|
|
||||||
post(reverse('api:inventory_hosts_list', kwargs={'pk': smart_inventory.id}), data, admin_user)
|
|
||||||
resp = get(reverse('api:inventory_hosts_list', kwargs={'pk': smart_inventory.id}), admin_user)
|
|
||||||
jdata = json.loads(resp.content)
|
|
||||||
|
|
||||||
assert getattr(smart_inventory, 'kind') == 'smart'
|
|
||||||
assert jdata['count'] == 0
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
def test_create_inventory_smartgroup(post, get, inventory, admin_user, organization):
|
def test_create_inventory_smartgroup(post, get, inventory, admin_user, organization):
|
||||||
data = { 'name': 'Group 1', 'description': 'Test Group'}
|
data = { 'name': 'Group 1', 'description': 'Test Group'}
|
||||||
|
|||||||
@@ -18,20 +18,6 @@ def test_empty_inventory(post, get, admin_user, organization, group_factory):
|
|||||||
assert jdata == {}
|
assert jdata == {}
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
|
||||||
def test_empty_smart_inventory(post, get, admin_user, organization, group_factory):
|
|
||||||
smart_inventory = Inventory(name='smart',
|
|
||||||
kind='smart',
|
|
||||||
organization=organization,
|
|
||||||
host_filter='enabled=True')
|
|
||||||
smart_inventory.save()
|
|
||||||
resp = get(reverse('api:inventory_script_view', kwargs={'version': 'v2', 'pk': smart_inventory.pk}), admin_user)
|
|
||||||
smartjdata = json.loads(resp.content)
|
|
||||||
|
|
||||||
assert smart_inventory.hosts.count() == 0
|
|
||||||
assert smartjdata == {}
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
def test_ungrouped_hosts(post, get, admin_user, organization, group_factory):
|
def test_ungrouped_hosts(post, get, admin_user, organization, group_factory):
|
||||||
inventory = Inventory(name='basic_inventory',
|
inventory = Inventory(name='basic_inventory',
|
||||||
@@ -44,32 +30,3 @@ def test_ungrouped_hosts(post, get, admin_user, organization, group_factory):
|
|||||||
jdata = json.loads(resp.content)
|
jdata = json.loads(resp.content)
|
||||||
assert inventory.hosts.count() == 2
|
assert inventory.hosts.count() == 2
|
||||||
assert len(jdata['all']['hosts']) == 2
|
assert len(jdata['all']['hosts']) == 2
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
|
||||||
def test_grouped_hosts_smart_inventory(post, get, admin_user, organization, group_factory):
|
|
||||||
inventory = Inventory(name='basic_inventory',
|
|
||||||
kind='',
|
|
||||||
organization=organization)
|
|
||||||
inventory.save()
|
|
||||||
groupA = group_factory('test_groupA')
|
|
||||||
host1 = Host.objects.create(name='first_host', inventory=inventory)
|
|
||||||
host2 = Host.objects.create(name='second_host', inventory=inventory)
|
|
||||||
Host.objects.create(name='third_host', inventory=inventory)
|
|
||||||
groupA.hosts.add(host1)
|
|
||||||
groupA.hosts.add(host2)
|
|
||||||
smart_inventory = Inventory(name='smart_inventory',
|
|
||||||
kind='smart',
|
|
||||||
organization=organization,
|
|
||||||
host_filter='enabled=True')
|
|
||||||
smart_inventory.save()
|
|
||||||
resp = get(reverse('api:inventory_script_view', kwargs={'version': 'v2', 'pk': inventory.pk}), admin_user)
|
|
||||||
jdata = json.loads(resp.content)
|
|
||||||
resp = get(reverse('api:inventory_script_view', kwargs={'version': 'v2', 'pk': smart_inventory.pk}), admin_user)
|
|
||||||
smartjdata = json.loads(resp.content)
|
|
||||||
|
|
||||||
assert getattr(smart_inventory, 'kind') == 'smart'
|
|
||||||
assert inventory.hosts.count() == 3
|
|
||||||
assert len(jdata['all']['hosts']) == 1
|
|
||||||
assert smart_inventory.hosts.count() == 3
|
|
||||||
assert len(smartjdata['all']['hosts']) == 3
|
|
||||||
|
|||||||
@@ -104,40 +104,8 @@ def setup_inventory_groups(inventory, group_factory):
|
|||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
class TestHostManager:
|
class TestHostManager:
|
||||||
def test_host_filter_change(self, setup_ec2_gce, organization):
|
|
||||||
smart_inventory = Inventory(name='smart',
|
|
||||||
kind='smart',
|
|
||||||
organization=organization,
|
|
||||||
host_filter='inventory_sources__source=ec2')
|
|
||||||
smart_inventory.save()
|
|
||||||
assert len(smart_inventory.hosts.all()) == 2
|
|
||||||
|
|
||||||
smart_inventory.host_filter = 'inventory_sources__source=gce'
|
|
||||||
smart_inventory.save()
|
|
||||||
assert len(smart_inventory.hosts.all()) == 1
|
|
||||||
|
|
||||||
def test_host_filter_not_smart(self, setup_ec2_gce, organization):
|
def test_host_filter_not_smart(self, setup_ec2_gce, organization):
|
||||||
smart_inventory = Inventory(name='smart',
|
smart_inventory = Inventory(name='smart',
|
||||||
organization=organization,
|
organization=organization,
|
||||||
host_filter='inventory_sources__source=ec2')
|
host_filter='inventory_sources__source=ec2')
|
||||||
assert len(smart_inventory.hosts.all()) == 0
|
assert len(smart_inventory.hosts.all()) == 0
|
||||||
|
|
||||||
def test_host_objects_manager(self, setup_ec2_gce, organization):
|
|
||||||
smart_inventory = Inventory(kind='smart',
|
|
||||||
name='smart',
|
|
||||||
organization=organization,
|
|
||||||
host_filter='inventory_sources__source=ec2')
|
|
||||||
smart_inventory.save()
|
|
||||||
|
|
||||||
hosts = smart_inventory.hosts.all()
|
|
||||||
assert len(hosts) == 2
|
|
||||||
assert hosts[0].inventory_sources.first().source == 'ec2'
|
|
||||||
assert hosts[1].inventory_sources.first().source == 'ec2'
|
|
||||||
|
|
||||||
def test_host_objects_no_dupes(self, setup_inventory_groups, organization):
|
|
||||||
smart_inventory = Inventory(name='smart',
|
|
||||||
kind='smart',
|
|
||||||
organization=organization,
|
|
||||||
host_filter='groups__name=test_groupA or groups__name=test_groupB')
|
|
||||||
smart_inventory.save()
|
|
||||||
assert len(smart_inventory.hosts.all()) == 1
|
|
||||||
|
|||||||
Reference in New Issue
Block a user