strategy: linear: Inspect the delegated host on delegated tasks.

The purpose of the 'physical_host_addrs' variable was to create a
mapping with all the physical hosts and their IP addresses. However,
the function was broken because it used the 'physical_host' task
variable to obtain the name of the physical host for the running task.
As such, the dictionary only contained a single entry. This breaks
delegation between hosts, since there was no entry in the dictionary for
the delegated host. So if a task targetting containerA on hostA was
delegated to containerB on hostB, the IP address of the hostB was not
in the dictionary. The connection plugin code then used the 'hostB'
hostname to connect to the host instead of its IP. However, if there
is no central DNS to translate hostB to an IP or if the deployer
did not add such mapping to /etc/hosts we observed the following
problem.

fatal: [compute00]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh:
Could not resolve hostname controller00: Name or service not known\r\n", "unreachable": true}

In order to fix that, we now examine the delegated host and create the
appropriate mappings if the task is delegated. This ensures that the
physical_host_addrs variable also contains information for the delegated
hosts instead of just the original one.

Change-Id: Ic84ad3ccdd8283a4ab3fb3130d4d5e520ab736de
This commit is contained in:
Markos Chandras 2018-08-14 16:42:00 +03:00
parent f91991913b
commit f56d1242c9
1 changed files with 28 additions and 7 deletions

View File

@ -126,13 +126,34 @@ class StrategyModule(LINEAR.StrategyModule):
_play_context = copy.deepcopy(play_context)
pha = task_vars['physical_host_addrs'] = dict()
physical_host_item = task_vars.get('physical_host')
if physical_host_item:
LINEAR.display.verbose(
u'The "physical_host" variable was found.',
host=host,
caplevel=0
)
physical_host_items = [task_vars.get('physical_host')]
if task.delegate_to:
# For delegated tasks, we also need the information from the delegated hosts
for delegated_host in task_vars.get('ansible_delegated_vars', dict()).keys():
LINEAR.display.verbose(
u'Task is delegated to %s.' % delegated_host,
host=host,
caplevel=0
)
delegated_host_info = self._inventory.get_host(u'%s' % delegated_host)
# This checks if we are delegating to a host which does not exist
# in the inventory (possibly using its IP address)
if delegated_host_info is None:
continue
physical_host_vars = delegated_host_info.get_vars()
physical_host_templar = LINEAR.Templar(loader=self._loader,
variables=physical_host_vars)
delegated_physical_host = physical_host_templar.template(
physical_host_vars.get('physical_host'))
if delegated_physical_host:
physical_host_items.append(delegated_physical_host)
LINEAR.display.verbose(
u'Task is delegated to %s. Adding its physical host %s'
% (delegated_host, delegated_physical_host),
host=host,
caplevel=0
)
for physical_host_item in physical_host_items:
ph = self._inventory.get_host(physical_host_item)
if ph:
LINEAR.display.verbose(