From 6557fb33f3865762e7cb30af634e6089492c29e2 Mon Sep 17 00:00:00 2001 From: Chris Church Date: Wed, 12 Jun 2013 22:37:25 -0400 Subject: [PATCH] Updated inventory script to only return active groups and active hosts for active inventories. --- ansibleworks/main/base_views.py | 8 +-- .../management/commands/acom_inventory.py | 14 ++--- ansibleworks/main/models/__init__.py | 9 +++ ansibleworks/main/tests/commands.py | 57 ++++++++++++++----- 4 files changed, 62 insertions(+), 26 deletions(-) diff --git a/ansibleworks/main/base_views.py b/ansibleworks/main/base_views.py index ad3b703104..aedb311a18 100644 --- a/ansibleworks/main/base_views.py +++ b/ansibleworks/main/base_views.py @@ -201,9 +201,7 @@ class BaseSubList(BaseList): relationship.remove(sub) else: # resource is just a ForeignKey, can't remove it from the set, just set it inactive - sub.name = "_deleted_%s_%s" % (str(datetime.time()), sub.name) - sub.active = False - sub.save() + sub.mark_inactive() if created: return Response(status=status.HTTP_201_CREATED, data=ser.data) @@ -229,9 +227,7 @@ class BaseDetail(generics.RetrieveUpdateDestroyAPIView): if not check_user_access(request.user, self.model, 'delete', obj): raise PermissionDenied() if isinstance(obj, PrimordialModel): - obj.name = "_deleted_%s_%s" % (str(datetime.time()), obj.name) - obj.active = False - obj.save() + obj.mark_inactive() elif type(obj) == User: obj.username = "_deleted_%s_%s" % (str(datetime.time()), obj.username) obj.is_active = False diff --git a/ansibleworks/main/management/commands/acom_inventory.py b/ansibleworks/main/management/commands/acom_inventory.py index a107502e71..6ad7701442 100755 --- a/ansibleworks/main/management/commands/acom_inventory.py +++ b/ansibleworks/main/management/commands/acom_inventory.py @@ -26,11 +26,12 @@ class Command(NoArgsCommand): def get_list(self, inventory, indent=None): groups = {} - for group in inventory.groups.all(): - # FIXME: Check if group is active? + for group in inventory.groups.filter(active=True): + hosts = group.hosts.filter(active=True) + children = group.children.filter(active=True) group_info = { - 'hosts': list(group.hosts.values_list('name', flat=True)), - 'children': list(group.children.values_list('name', flat=True)), + 'hosts': list(hosts.values_list('name', flat=True)), + 'children': list(children.values_list('name', flat=True)), } if group.variables: group_info['vars'] = group.variables_dict @@ -46,8 +47,7 @@ class Command(NoArgsCommand): from ansibleworks.main.models import Host hostvars = {} try: - # FIXME: Check if active? - host = inventory.hosts.get(name=hostname) + host = inventory.hosts.get(active=True, name=hostname) except Host.DoesNotExist: raise CommandError('Host %s not found in the given inventory' % hostname) hostvars = {} @@ -68,7 +68,7 @@ class Command(NoArgsCommand): if not inventory_id: raise CommandError('No inventory ID specified') try: - inventory = Inventory.objects.get(id=inventory_id) + inventory = Inventory.objects.get(active=True, id=inventory_id) except Inventory.DoesNotExist: raise CommandError('Inventory with ID %d not found' % inventory_id) host = options.get('host', '') diff --git a/ansibleworks/main/models/__init__.py b/ansibleworks/main/models/__init__.py index 1e93168361..bd5d5d9f7c 100644 --- a/ansibleworks/main/models/__init__.py +++ b/ansibleworks/main/models/__init__.py @@ -117,6 +117,15 @@ class PrimordialModel(models.Model): def __unicode__(self): return unicode("%s-%s"% (self.name, self.id)) + def mark_inactive(self, save=True): + '''Use instead of delete to rename and mark inactive.''' + if self.active: + if 'name' in self._meta.get_all_field_names(): + self.name = "_deleted_%s_%s" % (now().isoformat(), self.name) + self.active = False + if save: + self.save() + class CommonModel(PrimordialModel): ''' a base model where the name is unique ''' diff --git a/ansibleworks/main/tests/commands.py b/ansibleworks/main/tests/commands.py index 6f65f5d83c..20b2b0c0bf 100644 --- a/ansibleworks/main/tests/commands.py +++ b/ansibleworks/main/tests/commands.py @@ -117,6 +117,8 @@ class AcomInventoryTest(BaseCommandTest): host = inventory.hosts.create(name='host-%02d-%02d.example.com' % (n, x), inventory=inventory, variables=variables) + if x in (3, 7): + host.mark_inactive() hosts.append(host) self.hosts.extend(hosts) groups = [] @@ -128,6 +130,8 @@ class AcomInventoryTest(BaseCommandTest): group = inventory.groups.create(name='group-%d' % x, inventory=inventory, variables=variables) + if x == 2: + group.mark_inactive() groups.append(group) group.hosts.add(hosts[x]) group.hosts.add(hosts[x + 5]) @@ -146,19 +150,25 @@ class AcomInventoryTest(BaseCommandTest): def test_list_with_inventory_id_as_argument(self): inventory = self.inventories[0] + self.assertTrue(inventory.active) result, stdout, stderr = self.run_command('acom_inventory', list=True, inventory_id=inventory.pk) self.assertEqual(result, None) data = json.loads(stdout) - self.assertEqual(set(data.keys()), - set(inventory.groups.values_list('name', flat=True))) + groups = inventory.groups.filter(active=True) + groupnames = groups.values_list('name', flat=True) + self.assertEqual(set(data.keys()), set(groupnames)) # Groups for this inventory should only have hosts, and no group # variable data or parent/child relationships. for k,v in data.items(): self.assertTrue(isinstance(v, (list, tuple))) - group = inventory.groups.get(name=k) - self.assertEqual(set(v), - set(group.hosts.values_list('name', flat=True))) + group = inventory.groups.get(active=True, name=k) + hosts = group.hosts.filter(active=True) + hostnames = hosts.values_list('name', flat=True) + self.assertEqual(set(v), set(hostnames)) + for group in inventory.groups.filter(active=False): + self.assertFalse(group.name in data.keys(), + 'deleted group %s should not be in data' % group) # Command line argument for inventory ID should take precedence over # environment variable. inventory_pks = set(map(lambda x: x.pk, self.inventories)) @@ -171,32 +181,38 @@ class AcomInventoryTest(BaseCommandTest): def test_list_with_inventory_id_in_environment(self): inventory = self.inventories[1] + self.assertTrue(inventory.active) os.environ['ACOM_INVENTORY_ID'] = str(inventory.pk) result, stdout, stderr = self.run_command('acom_inventory', list=True) self.assertEqual(result, None) data = json.loads(stdout) - self.assertEqual(set(data.keys()), - set(inventory.groups.values_list('name', flat=True))) + groups = inventory.groups.filter(active=True) + groupnames = groups.values_list('name', flat=True) + self.assertEqual(set(data.keys()), set(groupnames)) # Groups for this inventory should have hosts, variable data, and one # parent/child relationship. for k,v in data.items(): self.assertTrue(isinstance(v, dict)) - group = inventory.groups.get(name=k) - self.assertEqual(set(v.get('hosts', [])), - set(group.hosts.values_list('name', flat=True))) + group = inventory.groups.get(active=True, name=k) + hosts = group.hosts.filter(active=True) + hostnames = hosts.values_list('name', flat=True) + self.assertEqual(set(v.get('hosts', [])), set(hostnames)) if group.variables: self.assertEqual(v.get('vars', {}), json.loads(group.variables)) if k == 'group-3': - self.assertEqual(set(v.get('children', [])), - set(group.children.values_list('name', flat=True))) + children = group.children.filter(active=True) + childnames = children.values_list('name', flat=True) + self.assertEqual(set(v.get('children', [])), set(childnames)) else: self.assertFalse('children' in v) def test_valid_host(self): # Host without variable data. inventory = self.inventories[0] + self.assertTrue(inventory.active) host = inventory.hosts.all()[2] + self.assertTrue(host.active) os.environ['ACOM_INVENTORY_ID'] = str(inventory.pk) result, stdout, stderr = self.run_command('acom_inventory', host=host.name) @@ -205,7 +221,9 @@ class AcomInventoryTest(BaseCommandTest): self.assertEqual(data, {}) # Host with variable data. inventory = self.inventories[1] - host = inventory.hosts.all()[3] + self.assertTrue(inventory.active) + host = inventory.hosts.all()[4] + self.assertTrue(host.active) os.environ['ACOM_INVENTORY_ID'] = str(inventory.pk) result, stdout, stderr = self.run_command('acom_inventory', host=host.name) @@ -216,7 +234,9 @@ class AcomInventoryTest(BaseCommandTest): def test_invalid_host(self): # Valid host, but not part of the specified inventory. inventory = self.inventories[0] + self.assertTrue(inventory.active) host = Host.objects.exclude(inventory=inventory)[0] + self.assertTrue(host.active) os.environ['ACOM_INVENTORY_ID'] = str(inventory.pk) result, stdout, stderr = self.run_command('acom_inventory', host=host.name) @@ -250,8 +270,18 @@ class AcomInventoryTest(BaseCommandTest): self.assertTrue(isinstance(result, CommandError)) self.assertEqual(json.loads(stdout), {}) + def test_with_deleted_inventory(self): + inventory = self.inventories[0] + inventory.mark_inactive() + self.assertFalse(inventory.active) + os.environ['ACOM_INVENTORY_ID'] = str(inventory.pk) + result, stdout, stderr = self.run_command('acom_inventory', list=True) + self.assertTrue(isinstance(result, CommandError)) + self.assertEqual(json.loads(stdout), {}) + def test_without_list_or_host_argument(self): inventory = self.inventories[0] + self.assertTrue(inventory.active) os.environ['ACOM_INVENTORY_ID'] = str(inventory.pk) result, stdout, stderr = self.run_command('acom_inventory') self.assertTrue(isinstance(result, CommandError)) @@ -259,6 +289,7 @@ class AcomInventoryTest(BaseCommandTest): def test_with_both_list_and_host_arguments(self): inventory = self.inventories[0] + self.assertTrue(inventory.active) os.environ['ACOM_INVENTORY_ID'] = str(inventory.pk) result, stdout, stderr = self.run_command('acom_inventory', list=True, host='blah')