def memory_inventory(): inventory = MemInventory() h = inventory.get_host('my_host') h.variables = {'foo': 'bar'} g = inventory.get_group('my_group') g.variables = {'foobar': 'barfoo'} h2 = inventory.get_host('group_host') g.add_host(h2) return inventory
def test_create_child_group(): inventory = MemInventory() g1 = inventory.get_group('g1') # Create new group by name as child of g1 g2 = inventory.get_group('g2', g1) # Check that child is in the children of the parent group assert g1.children == [g2] # Check that _only_ the parent group is listed as a root group assert inventory.all_group.children == [g1] # Check that _both_ are tracked by the global `all_groups` dict assert set(inventory.all_group.all_groups.values()) == set([g1, g2])
def perform_update(self, options, data, inventory_update): """Shared method for both awx-manage CLI updates and inventory updates from the tasks system. This saves the inventory data to the database, calling load_into_database but also wraps that method in a host of options processing """ # outside of normal options, these are needed as part of programatic interface self.inventory = inventory_update.inventory self.inventory_source = inventory_update.inventory_source self.inventory_update = inventory_update # the update options, could be parser object or dict self.overwrite = bool(options.get('overwrite', False)) self.overwrite_vars = bool(options.get('overwrite_vars', False)) self.enabled_var = options.get('enabled_var', None) self.enabled_value = options.get('enabled_value', None) self.group_filter = options.get('group_filter', None) or r'^.+$' self.host_filter = options.get('host_filter', None) or r'^.+$' self.exclude_empty_groups = bool(options.get('exclude_empty_groups', False)) self.instance_id_var = options.get('instance_id_var', None) try: self.group_filter_re = re.compile(self.group_filter) except re.error: raise CommandError('invalid regular expression for --group-filter') try: self.host_filter_re = re.compile(self.host_filter) except re.error: raise CommandError('invalid regular expression for --host-filter') begin = time.time() # Since perform_update can be invoked either through the awx-manage CLI # or from the task system, we need to create a new lock at this level # (even though inventory_import.Command.handle -- which calls # perform_update -- has its own lock, inventory_ID_import) with advisory_lock('inventory_{}_perform_update'.format(self.inventory.id)): try: self.check_license() except PermissionDenied as e: self.mark_license_failure(save=True) raise e try: # Check the per-org host limits self.check_org_host_limit() except PermissionDenied as e: self.mark_org_limits_failure(save=True) raise e if settings.SQL_DEBUG: queries_before = len(connection.queries) # Update inventory update for this command line invocation. with ignore_inventory_computed_fields(): # TODO: move this to before perform_update iu = self.inventory_update if iu.status != 'running': with transaction.atomic(): self.inventory_update.status = 'running' self.inventory_update.save() logger.info('Processing JSON output...') inventory = MemInventory(group_filter_re=self.group_filter_re, host_filter_re=self.host_filter_re) inventory = dict_to_mem_data(data, inventory=inventory) logger.info('Loaded %d groups, %d hosts', len(inventory.all_group.all_groups), len(inventory.all_group.all_hosts)) if self.exclude_empty_groups: inventory.delete_empty_groups() self.all_group = inventory.all_group if settings.DEBUG: # depending on inventory source, this output can be # *exceedingly* verbose - crawling a deeply nested # inventory/group data structure and printing metadata about # each host and its memberships # # it's easy for this scale of data to overwhelm pexpect, # (and it's likely only useful for purposes of debugging the # actual inventory import code), so only print it if we have to: # https://github.com/ansible/ansible-tower/issues/7414#issuecomment-321615104 self.all_group.debug_tree() with batch_role_ancestor_rebuilding(): # If using with transaction.atomic() with try ... catch, # with transaction.atomic() must be inside the try section of the code as per Django docs try: # Ensure that this is managed as an atomic SQL transaction, # and thus properly rolled back if there is an issue. with transaction.atomic(): # Merge/overwrite inventory into database. if settings.SQL_DEBUG: logger.warning('loading into database...') with ignore_inventory_computed_fields(): if getattr(settings, 'ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC', True): self.load_into_database() else: with disable_activity_stream(): self.load_into_database() if settings.SQL_DEBUG: queries_before2 = len(connection.queries) self.inventory.update_computed_fields() if settings.SQL_DEBUG: logger.warning('update computed fields took %d queries', len(connection.queries) - queries_before2) # Check if the license is valid. # If the license is not valid, a CommandError will be thrown, # and inventory update will be marked as invalid. # with transaction.atomic() will roll back the changes. license_fail = True self.check_license() # Check the per-org host limits license_fail = False self.check_org_host_limit() except PermissionDenied as e: if license_fail: self.mark_license_failure(save=True) else: self.mark_org_limits_failure(save=True) raise e if settings.SQL_DEBUG: logger.warning('Inventory import completed for %s in %0.1fs', self.inventory_source.name, time.time() - begin) else: logger.info('Inventory import completed for %s in %0.1fs', self.inventory_source.name, time.time() - begin) # If we're in debug mode, then log the queries and time # used to do the operation. if settings.SQL_DEBUG: queries_this_import = connection.queries[queries_before:] sqltime = sum(float(x['time']) for x in queries_this_import) logger.warning('Inventory import required %d queries ' 'taking %0.3fs', len(queries_this_import), sqltime)
def test_ungrouped_mechanics(): # ansible-inventory returns a group called `ungrouped` # we can safely treat this the same as the `all_group` inventory = MemInventory() ug = inventory.get_group('ungrouped') assert ug is inventory.all_group
def test_inventory_create_all_group(): inventory = MemInventory() assert inventory.all_group.name == 'all'