'''Plugin to override the default output logic.'''

# upstream: https://gist.github.com/cliffano/9868180

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


# For some reason this has to be done
import imp
import os

ANSIBLE_PATH = imp.find_module('ansible')[1]
DEFAULT_PATH = os.path.join(ANSIBLE_PATH, 'plugins/callback/default.py')
DEFAULT_MODULE = imp.load_source(
    'ansible.plugins.callback.default',
    DEFAULT_PATH
)

try:
    from ansible.plugins.callback import CallbackBase
    BASECLASS = CallbackBase
except ImportError: # < ansible 2.1
    BASECLASS = DEFAULT_MODULE.CallbackModule


class CallbackModule(DEFAULT_MODULE.CallbackModule):  # pylint: disable=too-few-public-methods,no-init
    '''
    Override for the default callback module.

    Render std err/out outside of the rest of the result which it prints with
    indentation.
    '''
    CALLBACK_VERSION = 2.0
    CALLBACK_TYPE = 'stdout'
    CALLBACK_NAME = 'default'

    def _dump_results(self, result):
        '''Return the text to output for a result.'''
        result['_ansible_verbose_always'] = True

        save = {}
        for key in ['stdout', 'stdout_lines', 'stderr', 'stderr_lines', 'msg']:
            if key in result:
                save[key] = result.pop(key)

        output = BASECLASS._dump_results(self, result) # pylint: disable=protected-access

        for key in ['stdout', 'stderr', 'msg']:
            if key in save and save[key]:
                output += '\n\n%s:\n\n%s\n' % (key.upper(), save[key])

        for key, value in save.items():
            result[key] = value

        return output

callback_plugins/default.py
'''Plugin to override the default output logic.'''

# upstream: https://gist.github.com/cliffano/9868180

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


# For some reason this has to be done
import imp
import os

ANSIBLE_PATH = imp.find_module('ansible')[1]
DEFAULT_PATH = os.path.join(ANSIBLE_PATH, 'plugins/callback/default.py')
DEFAULT_MODULE = imp.load_source(
    'ansible.plugins.callback.default',
    DEFAULT_PATH
)

try:
    from ansible.plugins.callback import CallbackBase
    BASECLASS = CallbackBase
except ImportError: # < ansible 2.1
    BASECLASS = DEFAULT_MODULE.CallbackModule


class CallbackModule(DEFAULT_MODULE.CallbackModule):  # pylint: disable=too-few-public-methods,no-init
    '''
    Override for the default callback module.

    Render std err/out outside of the rest of the result which it prints with
    indentation.
    '''
    CALLBACK_VERSION = 2.0
    CALLBACK_TYPE = 'stdout'
    CALLBACK_NAME = 'default'

    def __init__(self, *args, **kwargs):
        BASECLASS.__init__(self, *args, **kwargs)

    def _dump_results(self, result):
        '''Return the text to output for a result.'''
        result['_ansible_verbose_always'] = True

        save = {}
        for key in ['stdout', 'stdout_lines', 'stderr', 'stderr_lines', 'msg']:
            if key in result:
                save[key] = result.pop(key)

        output = BASECLASS._dump_results(self, result) # pylint: disable=protected-access

        for key in ['stdout', 'stderr', 'msg']:
            if key in save and save[key]:
                output += '\n\n%s:\n\n%s\n' % (key.upper(), save[key])

        for key, value in save.items():
            result[key] = value

        return output

callback_plugins/default.py
diff --git a/callback_plugins/default.py b/callback_plugins/default.py
index bc0b207bb08..c64145b5c39 100644
--- a/callback_plugins/default.py
+++ b/callback_plugins/default.py
@@ -45,6 +45,9 @@ class CallbackModule(DEFAULT_MODULE.CallbackModule):  # pylint: disable=too-few-
     CALLBACK_TYPE = 'stdout'
     CALLBACK_NAME = 'default'
 
+    def __init__(self, *args, **kwargs):
+        BASECLASS.__init__(self, *args, **kwargs)
+
     def _dump_results(self, result):
         '''Return the text to output for a result.'''
         result['_ansible_verbose_always'] = True

maximum recursion depth exceeded -- related to callback/default.py
Running the `ansible-playbook -b --become-user root -i ansible-ose-inventory  /usr/share/ansible/openshift-ansible/playbooks/byo/config.yml`

i am getting

```
statically included: /usr/share/ansible/openshift-ansible/roles/openshift_hosted/tasks/registry/registry.yml
statically included: /usr/share/ansible/openshift-ansible/roles/openshift_metrics/tasks/install.yml
ERROR! Unexpected Exception: maximum recursion depth exceeded while calling a Python object
the full traceback was:

Traceback (most recent call last):
  File "/bin/ansible-playbook", line 103, in <module>
    exit_code = cli.run()
  File "/usr/lib/python2.7/site-packages/ansible/cli/playbook.py", line 159, in run
    results = pbex.run()
  File "/usr/lib/python2.7/site-packages/ansible/executor/playbook_executor.py", line 89, in run
    self._tqm.load_callbacks()
  File "/usr/lib/python2.7/site-packages/ansible/executor/task_queue_manager.py", line 172, in load_callbacks
    self._stdout_callback = callback_loader.get(self._stdout_callback)
  File "/usr/lib/python2.7/site-packages/ansible/plugins/__init__.py", line 358, in get
    obj = obj(*args, **kwargs)
  File "/usr/lib/python2.7/site-packages/ansible/plugins/callback/default.py", line 41, in __init__
    super(CallbackModule, self).__init__()
...
    super(CallbackModule, self).__init__()
  File "/usr/lib/python2.7/site-packages/ansible/plugins/callback/default.py", line 41, in __init__
    super(CallbackModule, self).__init__()
  File "/usr/lib/python2.7/site-packages/ansible/plugins/callback/default.py", line 41, in __init__
    super(CallbackModule, self).__init__()
RuntimeError: maximum recursion depth exceeded while calling a Python object
```
##### Version

```
atomic-openshift-utils-3.3.37-1.git.0.10ff25b.el7.noarch
openshift-ansible-3.3.37-1.git.0.10ff25b.el7.noarch
```

The playbooks are installed from AtomicOpenShift/3.3/2016-10-18.2
The 3.4 has same problem. 3.2 Doesn't

```
openshift-ansible.noarch                  3.3.37-1.git.0.10ff25b.el7 @AtomicOpenShift-3.3-Puddle
openshift-ansible-callback-plugins.noarch 3.3.37-1.git.0.10ff25b.el7 @AtomicOpenShift-3.3-Puddle
openshift-ansible-docs.noarch             3.3.37-1.git.0.10ff25b.el7 @AtomicOpenShift-3.3-Puddle
openshift-ansible-filter-plugins.noarch   3.3.37-1.git.0.10ff25b.el7 @AtomicOpenShift-3.3-Puddle
openshift-ansible-lookup-plugins.noarch   3.3.37-1.git.0.10ff25b.el7 @AtomicOpenShift-3.3-Puddle
openshift-ansible-playbooks.noarch        3.3.37-1.git.0.10ff25b.el7 @AtomicOpenShift-3.3-Puddle
openshift-ansible-roles.noarch            3.3.37-1.git.0.10ff25b.el7 @AtomicOpenShift-3.3-Puddle

ansible-playbook 2.2.0.0
  config file = /root/ansible.cfg
  configured module search path = Default w/o overrides
```
##### Steps To Reproduce

In description
##### Current Result

Infinite recursion with ansible 2.2.0.0
No problem with ansible 2.1.2.0

 The difference seems to be that the 2.1.2.0 do not have the `__init__` in  the

```
   /usr/lib/python2.7/site-packages/ansible/plugins/callback/default.py
```

```
class CallbackModule(CallbackBase):
...
    def __init__(self):

        self._play = None
        self._last_task_banner = None
        super(CallbackModule, self).__init__()
```

If I remove it from the same file on the old ansible, deployment seems
to work. Though I have no idea why it get's to the infinite recursion.
It doesn't make sense to me.
##### Expected Result

No problems with the infinite recursion
##### Additional Information

Red Hat Enterprise Linux Server release 7.2 (Maipo)

The inventory file

```
[OSEv3:children]
masters
nodes

[OSEv3:vars]
deployment_type=openshift-enterprise
ansible_ssh_user=cloud-user
ansible_sudo=true
ansible_sudo_user=root
openshift_use_manageiq=True
#use_cluster_metrics=true

openshift_additional_repos=[{'id': 'ose-devel', 'name': 'ose-devel', 'baseurl': 'http://download.xxx.redhat.com/rcm-guest/puddles/RHAOS/AtomicOpenShift-errata/3.3/latest/RH7-RHAOS-3.3/x86_64/os/', 'enabled': 1, 'gpgcheck': 0, 'skip_if_unavailable': 1}, {'id':'rhel-extras-candidate','name':'rhel-extras-candidate','baseurl':'http://download.xxx..redhat.com/brewroot/repos/extras-rhel-7.2-candidate/latest/x86_64/', 'enabled': 1, 'gpgcheck': 0, 'skip_if_unavailable': 1}]
openshift_docker_additional_registries=brew-pulp-docker01.web.prod.ext.phx2.redhat.com:8888
openshift_docker_insecure_registries=brew-pulp-docker01.web.prod.ext.phx2.redhat.com:8888

[masters]
ose3-master-08w85 openshift_scheduleable=True openshift_hostname=ose3-master-08w85 openshift_public_hostname=ose3-master-08w85

[nodes]
ose3-master-08w85 openshift_node_labels="{'region':'infra','zone':'default'}" openshift_hostname=ose3-master-08w85 openshift_public_hostname=ose3-master-08w85

ose3-node0-08w85 openshift_node_labels="{'region':'primary','zone':'east'}" openshift_hostname=ose3-node0-08w85 openshift_public_hostname=ose3-node0-08w85
ose3-node1-08w85 openshift_node_labels="{'region':'primary','zone':'west'}" openshift_hostname=ose3-node1-08w85 openshift_public_hostname=ose3-node1-08w85
```

