Repository: ansible/ansible

Issue:
firewalld: Provisioning with docker container exits with DBUS_ERROR
##### ISSUE TYPE
 - Bug Report
 
##### COMPONENT NAME
firewalld

##### ANSIBLE VERSION
```
ansible 2.4.2.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, May  3 2017, 07:55:04) [GCC 4.8.5 20150623 (Red Hat 4.8.5-14)]
```

##### CONFIGURATION
DEFAULT_ROLES_PATH(/etc/ansible/ansible.cfg) = [u'/etc/ansible/roles', u'/usr/share/ansible/roles']
##### OS / ENVIRONMENT
RHEL 7 Host with RHEL 7 docker image

##### SUMMARY
When provisioning firewall rules with a docker container, the module fails with an exception, firewall.errors.FirewallError: DBUS_ERROR: Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory

There is currently a test to determine if the firewall is offline, but it fails to catch this case. The firewall-offline-cmd can be ran fine in this environment (via command module). 

This is useful for provisioning an offline image before deploying.
##### STEPS TO REPRODUCE
Run the following in a docker container:
```yaml
- name: Allow NTP
  firewalld:
    service: ntp
    zone: public
    permanent: true
    state: enabled
```

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->
The firewalld module to detect the firewallis offline, continue in offline mode (fw_offline=True), and apply the rule

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->

<!--- Paste verbatim command output between quotes below -->
```
TASK [Allow NTP] *******************************************************************************************************************************
task path: /root/test.yml:3
Using module file /usr/lib/python2.7/site-packages/ansible/modules/system/firewalld.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: root
<localhost> EXEC /bin/sh -c 'echo ~ && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-tmp-1519192803.32-133706138019513 `" && echo ansible-tmp-1519192803.32-133706138019513="` echo /root/.ansible/tmp/ansible-tmp-1519192803.32-133706138019513 `" ) && sleep 0'
<localhost> PUT /tmp/tmpyDI1rl TO /root/.ansible/tmp/ansible-tmp-1519192803.32-133706138019513/firewalld.py
<localhost> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp-1519192803.32-133706138019513/ /root/.ansible/tmp/ansible-tmp-1519192803.32-133706138019513/firewalld.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python /root/.ansible/tmp/ansible-tmp-1519192803.32-133706138019513/firewalld.py; rm -rf "/root/.ansible/tmp/ansible-tmp-1519192803.32-133706138019513/" > /dev/null 2>&1 && sleep 0'
The full traceback is:
Traceback (most recent call last):
  File "/tmp/ansible_UBuWgI/ansible_module_firewalld.py", line 157, in <module>
    fw = FirewallClient()
  File "<string>", line 2, in __init__
  File "/usr/lib/python2.7/site-packages/firewall/client.py", line 53, in handle_exceptions
    return func(*args, **kwargs)
  File "/usr/lib/python2.7/site-packages/firewall/client.py", line 2480, in __init__
    e.get_dbus_message())
firewall.errors.FirewallError: DBUS_ERROR: Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory

fatal: [localhost]: FAILED! => {
    "changed": false, 
    "module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_UBuWgI/ansible_module_firewalld.py\", line 157, in <module>\n    fw = FirewallClient()\n  File \"<string>\", line 2, in __init__\n  File \"/usr/lib/python2.7/site-packages/firewall/client.py\", line 53, in handle_exceptions\n    return func(*args, **kwargs)\n  File \"/usr/lib/python2.7/site-packages/firewall/client.py\", line 2480, in __init__\n    e.get_dbus_message())\nfirewall.errors.FirewallError: DBUS_ERROR: Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory\n", 
    "module_stdout": "", 
    "msg": "MODULE FAILURE", 
    "rc": 0
}
```



Discussion:
Files identified in the description:
* [lib/ansible/modules/system/firewalld.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/system/firewalld.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 --->
cc @maxamillion
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->

Resolving patch:
diff --git a/lib/ansible/modules/system/firewalld.py b/lib/ansible/modules/system/firewalld.py
--- a/lib/ansible/modules/system/firewalld.py
+++ b/lib/ansible/modules/system/firewalld.py
@@ -164,6 +164,7 @@
     from firewall.client import Rich_Rule
     from firewall.client import FirewallClient
     from firewall.client import FirewallClientZoneSettings
+    from firewall.errors import FirewallError
     fw = None
     fw_offline = False
     import_failure = False
@@ -171,7 +172,7 @@
     try:
         fw = FirewallClient()
         fw.getDefaultZone()
-    except AttributeError:
+    except (AttributeError, FirewallError):
         # Firewalld is not currently running, permanent-only operations
         fw_offline = True
 


Test patch: