Variable loading infrastructure problems

Hi,
I seem to have stumbled upon an issue with the variable loading infrastructure in the context of vars plugins.

What I tried to accomplish is to merge variables not globally based on "hash_behaviour=merge" but by explicitly stating it in the data using a key like “__combine: merge” in the data. So I looked at the code of the “host_group_vars.py” file in the Ansible codebase and it looked like this file already does 99% of what I intended to do so I copied it into a local “vars_plugins” directory and adapted it. This is were I ran into trouble as the code in the plugin does not seem to work as intended.

First the get_vars() function gets called multiple times instead of once. Second the plugin seems to assume it gets passed in a list of names in “entities” it then tries to iterate over but that is not the case as “entities” always only contains one name even if the host in question is part of multiple groups.

What it looks like to me is that the merge logic for the setting "hash_behaviour" was once part of the plugin but then the loading of the variables was rewritten and the iteration that was done in the plugin was uplifted into the variable manger which now iterates over the hosts and groups and calls the plugins get_vars() for each iteration. this makes some of the code in the plugin obsolete e.g. in the combine_vars(a, b) call the variable “a” is always an empty dictionary making the call pointless.

The fact that the combination of the variables has been moved from the plugin to the variable manager means that variable plugins have been severly limited in how they can load variables i.e. a combination of variables has basically been made impossible.

This leaves me with the question of how to get the desired behaviour. As a sort of prototype I have implemented a version that uses a module variable to keep track of the results of previous calls of get_vars() to be able to merge data. This is obviously fairly ugly and makes assumptions about the ordering of the get_vars() call by the manager (e.g. it will first be called for the “all” group, then for other groups in the correct order, then for the host, etc.)

A proper way to deal with this would require the manager to give the vars plugin an opportunity to handle the combination itself by specifying its own combine_vars() function that would be called instead of the “hard-coded” one in Ansibles code (which potentially could still be called if the plugin doesn’t define its own).

Would something like this be considered? What would be potential alternatives to this that would make it possible to create the desired behaviour?

(I’ve contributed a similar plugin for Saltstack called “varstack” and we are currently using this in our infrastructure.)

Regards,
Dennis