diff --git a/awx/main/models/inventory.py b/awx/main/models/inventory.py index dc43cf8b31..392c011a16 100644 --- a/awx/main/models/inventory.py +++ b/awx/main/models/inventory.py @@ -222,6 +222,9 @@ class Inventory(CommonModel): def update_group_depths(group_pk, current_depth=0): max_depth = group_depths.get(group_pk, -1) + # Arbitrarily limit depth to avoid hitting Python recursion limit (which defaults to 1000). + if current_depth > 100: + return if current_depth > max_depth: group_depths[group_pk] = current_depth for child_pk in group_children_map.get(group_pk, set()): diff --git a/awx/main/tests/commands/commands_monolithic.py b/awx/main/tests/commands/commands_monolithic.py index 7e591d65d2..f6055d27cf 100644 --- a/awx/main/tests/commands/commands_monolithic.py +++ b/awx/main/tests/commands/commands_monolithic.py @@ -96,6 +96,19 @@ lb[01:09:2].example.us even_odd=odd media[0:9][0:9].example.cc ''' +TEST_INVENTORY_INI_WITH_RECURSIVE_GROUPS = '''\ +[family:children] +parent + +[parent:children] +child + +[child:children] +grandchild + +[grandchild:children] +parent +''' class BaseCommandMixin(object): ''' @@ -971,6 +984,16 @@ class InventoryImportTest(BaseCommandMixin, BaseLiveServerTest): source=self.ini_path) self.assertTrue(isinstance(result, ValueError), result) + def test_ini_file_with_recursive_groups(self): + self.create_test_ini(ini_content=TEST_INVENTORY_INI_WITH_RECURSIVE_GROUPS) + new_inv = self.organizations[0].inventories.create(name='new') + self.assertEqual(new_inv.hosts.count(), 0) + self.assertEqual(new_inv.groups.count(), 0) + result, stdout, stderr = self.run_command('inventory_import', + inventory_id=new_inv.pk, + source=self.ini_path) + self.assertEqual(result, None, stdout + stderr) + def test_executable_file(self): # Use existing inventory as source. old_inv = self.inventories[1] diff --git a/awx/plugins/inventory/ec2.py b/awx/plugins/inventory/ec2.py index 112f5c29e8..53c699227d 100755 --- a/awx/plugins/inventory/ec2.py +++ b/awx/plugins/inventory/ec2.py @@ -527,7 +527,8 @@ class Ec2Inventory(object): self.push(self.inventory, key, dest) if self.nested_groups: self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k)) - self.push_group(self.inventory, self.to_safe("tag_" + k), key) + if v: + self.push_group(self.inventory, self.to_safe("tag_" + k), key) # Inventory: Group by Route53 domain names if enabled if self.route53_enabled and self.group_by_route53_names: