diff --git a/awx/main/management/commands/inventory_import.py b/awx/main/management/commands/inventory_import.py index 8150936054..582af9d03b 100644 --- a/awx/main/management/commands/inventory_import.py +++ b/awx/main/management/commands/inventory_import.py @@ -458,12 +458,19 @@ class Command(BaseCommand): # TODO: We disable variable overwrite here in case user-defined inventory variables get # mangled. But we still need to figure out a better way of processing multiple inventory # update variables mixing with each other. - all_obj = self.inventory - db_variables = all_obj.variables_dict - db_variables.update(self.all_group.variables) - if db_variables != all_obj.variables_dict: - all_obj.variables = json.dumps(db_variables) - all_obj.save(update_fields=['variables']) + # issue for this: https://github.com/ansible/awx/issues/11623 + + if self.inventory.kind == 'constructed' and self.inventory_source.overwrite_vars: + # NOTE: we had to add a exception case to not merge variables + # to make constructed inventory coherent + db_variables = self.all_group.variables + else: + db_variables = self.inventory.variables_dict + db_variables.update(self.all_group.variables) + + if db_variables != self.inventory.variables_dict: + self.inventory.variables = json.dumps(db_variables) + self.inventory.save(update_fields=['variables']) logger.debug('Inventory variables updated from "all" group') else: logger.debug('Inventory variables unmodified') @@ -522,16 +529,32 @@ class Command(BaseCommand): def _update_db_host_from_mem_host(self, db_host, mem_host): # Update host variables. db_variables = db_host.variables_dict - if self.overwrite_vars: - db_variables = mem_host.variables - else: - db_variables.update(mem_host.variables) + mem_variables = mem_host.variables update_fields = [] + + # Update host instance_id. + instance_id = self._get_instance_id(mem_variables) + if instance_id != db_host.instance_id: + old_instance_id = db_host.instance_id + db_host.instance_id = instance_id + update_fields.append('instance_id') + + if self.inventory.kind == 'constructed': + # remote towervars so the constructed hosts do not have extra variables + for prefix in ('host', 'tower'): + for var in ('remote_{}_enabled', 'remote_{}_id'): + mem_variables.pop(var.format(prefix), None) + + if self.overwrite_vars: + db_variables = mem_variables + else: + db_variables.update(mem_variables) + if db_variables != db_host.variables_dict: db_host.variables = json.dumps(db_variables) update_fields.append('variables') # Update host enabled flag. - enabled = self._get_enabled(mem_host.variables) + enabled = self._get_enabled(mem_variables) if enabled is not None and db_host.enabled != enabled: db_host.enabled = enabled update_fields.append('enabled') @@ -540,12 +563,6 @@ class Command(BaseCommand): old_name = db_host.name db_host.name = mem_host.name update_fields.append('name') - # Update host instance_id. - instance_id = self._get_instance_id(mem_host.variables) - if instance_id != db_host.instance_id: - old_instance_id = db_host.instance_id - db_host.instance_id = instance_id - update_fields.append('instance_id') # Update host and display message(s) on what changed. if update_fields: db_host.save(update_fields=update_fields) diff --git a/awx/main/models/inventory.py b/awx/main/models/inventory.py index 6bc03190a2..a4ddaabafd 100644 --- a/awx/main/models/inventory.py +++ b/awx/main/models/inventory.py @@ -458,7 +458,9 @@ class Inventory(CommonModelNameNotUnique, ResourceMixin, RelatedJobsMixin): """ if self.kind == 'constructed': if not self.inventory_sources.exists(): - self.inventory_sources.create(source='constructed', name=f'Auto-created source for: {self.name}'[:512], overwrite=True, update_on_launch=True) + self.inventory_sources.create( + source='constructed', name=f'Auto-created source for: {self.name}'[:512], overwrite=True, overwrite_vars=True, update_on_launch=True + ) def save(self, *args, **kwargs): self._update_host_smart_inventory_memeberships()