Repository: ansible/ansible

Issue:
Exception with `ansible_port` on delegate task result
##### SUMMARY
If we have a task that delegate to localhost, we have an exception thrown : 

````
ERROR! Unexpected Exception, this is probably a bug: 'ansible_port'
````

##### ISSUE TYPE
This seems to be related to #42577. Reverting this commit fix the issue.

##### COMPONENT NAME
delegate_to

##### ANSIBLE VERSION
```
ansible 2.6.1.post0
  config file = /opt/monitoring/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python2.7/dist-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 2.7.15rc1 (default, Apr 15 2018, 21:51:34) [GCC 7.3.0]
```

##### CONFIGURATION
````
DEFAULT_ROLES_PATH(/opt/monitoring/ansible/ansible.cfg) = [u'/opt/monitoring/ansible/.galaxy_roles']
````

##### OS / ENVIRONMENT
Ubuntu 18.04

##### STEPS TO REPRODUCE
<!--- For bugs, show exactly how to reproduce the problem, using a minimal test-case.
For new features, show how the feature would be used. -->

<!--- Paste example playbooks or commands between quotes below -->
```yaml
- hosts: '*'
  tasks:
    - name: Write gossip encryption key locally for use with new servers
      copy:
        content: "{{ consul_raw_key }}"
        dest: '/tmp/consul_raw.key'
      become: no
      no_log: true
      run_once: true
      register: consul_local_key
      delegate_to: localhost
      changed_when: false
      when: consul_raw_key is defined
```

##### EXPECTED RESULTS
Something working, not an exception
##### ACTUAL RESULTS
```
TASK [Write gossip encryption key locally for use with new servers] ******************************************************************************************************
task path: /opt/monitoring/ansible/playbook.yml:8
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: root
<localhost> EXEC /bin/sh -c 'echo ~root && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-tmp-1532011875.95-252544437995818 `" && echo ansible-tmp-1532011875.95-252544437995818="` echo /root/.ansible/tmp/ansible-tmp-1532011875.95-252544437995818 `" ) && sleep 0'
Using module file /usr/local/lib/python2.7/dist-packages/ansible/modules/files/stat.py
<localhost> PUT /root/.ansible/tmp/ansible-local-18955F96q_C/tmplKd6qB TO /root/.ansible/tmp/ansible-tmp-1532011875.95-252544437995818/stat.py
<localhost> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp-1532011875.95-252544437995818/ /root/.ansible/tmp/ansible-tmp-1532011875.95-252544437995818/stat.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python /root/.ansible/tmp/ansible-tmp-1532011875.95-252544437995818/stat.py && sleep 0'
Using module file /usr/local/lib/python2.7/dist-packages/ansible/modules/files/file.py
<localhost> PUT /root/.ansible/tmp/ansible-local-18955F96q_C/tmpFYSMGp TO /root/.ansible/tmp/ansible-tmp-1532011875.95-252544437995818/file.py
<localhost> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp-1532011875.95-252544437995818/ /root/.ansible/tmp/ansible-tmp-1532011875.95-252544437995818/file.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python /root/.ansible/tmp/ansible-tmp-1532011875.95-252544437995818/file.py && sleep 0'
<localhost> EXEC /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-tmp-1532011875.95-252544437995818/ > /dev/null 2>&1 && sleep 0'
ERROR! Unexpected Exception, this is probably a bug: 'ansible_port'
the full traceback was:

Traceback (most recent call last):
  File "/usr/local/bin/ansible-playbook", line 118, in <module>
    exit_code = cli.run()
  File "/usr/local/lib/python2.7/dist-packages/ansible/cli/playbook.py", line 122, in run
    results = pbex.run()
  File "/usr/local/lib/python2.7/dist-packages/ansible/executor/playbook_executor.py", line 159, in run
    result = self._tqm.run(play=play)
  File "/usr/local/lib/python2.7/dist-packages/ansible/executor/task_queue_manager.py", line 289, in run
    play_return = strategy.run(iterator, play_context)
  File "/usr/local/lib/python2.7/dist-packages/ansible/plugins/strategy/linear.py", line 323, in run
    results += self._wait_on_pending_results(iterator)
  File "/usr/local/lib/python2.7/dist-packages/ansible/plugins/strategy/__init__.py", line 674, in _wait_on_pending_results
    results = self._process_pending_results(iterator)
  File "/usr/local/lib/python2.7/dist-packages/ansible/plugins/strategy/__init__.py", line 117, in inner
    results = func(self, iterator, one_pass=one_pass, max_passes=max_passes)
  File "/usr/local/lib/python2.7/dist-packages/ansible/plugins/strategy/__init__.py", line 636, in _process_pending_results
    self._tqm.send_callback('v2_runner_on_ok', task_result)
  File "/usr/local/lib/python2.7/dist-packages/ansible/executor/task_queue_manager.py", line 366, in send_callback
    new_args.append(arg.clean_copy())
  File "/usr/local/lib/python2.7/dist-packages/ansible/executor/task_result.py", line 127, in clean_copy
    x[sub][key] = self._result[sub][key]
KeyError: 'ansible_port'
```


The error is in #42577


Discussion:
Files identified in the description:
* [lib/ansible/playbook/task.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/playbook/task.py)

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
I cannot reproduce the error, i don't see how you get an undefined `ansible_port` at that point, but i can see how the code would cause the error if that were the case.

Can you give us more information to reproduce the issue? probably something in inventory is causing the absence of the key.
It seems that there is nothing related to in the inventory. `ansible_port` should not be defined, because it is delegating to localhost (not an ssh connection). I try to execute the `ansible-consul` role, which is throwing the exception. How could I help you more ?
PR above should fix the issue, but i would like to create a test that reproduces the problem, to avoid it from happening again. 

Since i cannot reproduce locally, im unsure how to proceed.
Just tested your fix but I have the same issue. Commenting the whole block fixes.
@bcoca I also have the same issue with latest master.

I've managed to reduce it to this `playbook.yaml`

```yaml
- hosts: localhost
  tasks:
    - name: test issue
      become: false
      local_action: "command echo 'this will fail'"
      no_log: true
```

Ran with ```ansible-playbook playbook.yaml```

Failed with `ERROR! Unexpected Exception, this is probably a bug: 'ansible_port'`

Removing `no_log: true` makes it pass again.
i had typo in my fix, try again with my PR
I confirm your patch works

Resolving patch:
diff --git a/lib/ansible/executor/task_result.py b/lib/ansible/executor/task_result.py
--- a/lib/ansible/executor/task_result.py
+++ b/lib/ansible/executor/task_result.py
@@ -124,7 +124,8 @@ def clean_copy(self):
                 if sub in self._result:
                     x[sub] = {}
                     for key in _SUB_PRESERVE[sub]:
-                        x[sub][key] = self._result[sub][key]
+                        if key in self._result[sub]:
+                            x[sub][key] = self._result[sub][key]
 
             result._result = x
         elif self._result:


Test patch:
diff --git a/test/integration/targets/delegate_to/delegate_and_nolog.yml b/test/integration/targets/delegate_to/delegate_and_nolog.yml
new file mode 100644
--- /dev/null
+++ b/test/integration/targets/delegate_to/delegate_and_nolog.yml
@@ -0,0 +1,8 @@
+- hosts: testhost
+  gather_facts: false
+  tasks:
+    - name: no log filtering caused delegation to fail https://github.com/ansible/ansible/issues/43026
+      become: False
+      no_log: true
+      debug:
+      delegate_to: localhost
diff --git a/test/integration/targets/delegate_to/runme.sh b/test/integration/targets/delegate_to/runme.sh
--- a/test/integration/targets/delegate_to/runme.sh
+++ b/test/integration/targets/delegate_to/runme.sh
@@ -6,3 +6,5 @@ ANSIBLE_SSH_ARGS='-C -o ControlMaster=auto -o ControlPersist=60s -o UserKnownHos
     ANSIBLE_HOST_KEY_CHECKING=false ansible-playbook test_delegate_to.yml -i ../../inventory -v "$@"
 
 ansible-playbook test_loop_control.yml -v "$@"
+
+ansible-playbook delegate_and_nolog.yml -v "$@"