diff --git a/lib/ansible/module_utils/manageiq.py b/lib/ansible/module_utils/manageiq.py index f335b2468f9..0e0072646cc 100644 --- a/lib/ansible/module_utils/manageiq.py +++ b/lib/ansible/module_utils/manageiq.py @@ -28,11 +28,16 @@ import os +import traceback +from ansible.module_utils.basic import missing_required_lib + +CLIENT_IMP_ERR = None try: from manageiq_client.api import ManageIQClient HAS_CLIENT = True except ImportError: + CLIENT_IMP_ERR = traceback.format_exc() HAS_CLIENT = False @@ -55,7 +60,7 @@ def manageiq_argument_spec(): def check_client(module): if not HAS_CLIENT: - module.fail_json(msg='manageiq_client.api is required for this module') + module.fail_json(msg=missing_required_lib('manageiq-client'), exception=CLIENT_IMP_ERR) def validate_connection_params(module): diff --git a/lib/ansible/module_utils/oneview.py b/lib/ansible/module_utils/oneview.py index caedae6dfc0..0d3116c8e68 100644 --- a/lib/ansible/module_utils/oneview.py +++ b/lib/ansible/module_utils/oneview.py @@ -34,14 +34,16 @@ import json import os import traceback +HPE_ONEVIEW_IMP_ERR = None try: from hpOneView.oneview_client import OneViewClient HAS_HPE_ONEVIEW = True except ImportError: + HPE_ONEVIEW_IMP_ERR = traceback.format_exc() HAS_HPE_ONEVIEW = False from ansible.module_utils import six -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils._text import to_native from ansible.module_utils.common._collections_compat import Mapping @@ -202,7 +204,6 @@ class OneViewModuleBase(object): MSG_ALREADY_PRESENT = 'Resource is already present.' MSG_ALREADY_ABSENT = 'Resource is already absent.' MSG_DIFF_AT_KEY = 'Difference found at key \'{0}\'. ' - HPE_ONEVIEW_SDK_REQUIRED = 'HPE OneView Python SDK is required for this module.' ONEVIEW_COMMON_ARGS = dict( config=dict(type='path'), @@ -257,7 +258,7 @@ class OneViewModuleBase(object): def _check_hpe_oneview_sdk(self): if not HAS_HPE_ONEVIEW: - self.module.fail_json(msg=self.HPE_ONEVIEW_SDK_REQUIRED) + self.module.fail_json(msg=missing_required_lib('hpOneView'), exception=HPE_ONEVIEW_IMP_ERR) def _create_oneview_client(self): if self.module.params.get('hostname'): diff --git a/lib/ansible/module_utils/remote_management/ucs.py b/lib/ansible/module_utils/remote_management/ucs.py index 1a8a9609113..f7255509227 100644 --- a/lib/ansible/module_utils/remote_management/ucs.py +++ b/lib/ansible/module_utils/remote_management/ucs.py @@ -27,11 +27,16 @@ # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # +import traceback +from ansible.module_utils.basic import missing_required_lib + +UCSMSDK_IMP_ERR = None try: import ucsmsdk HAS_UCSMSDK = True except Exception: + UCSMSDK_IMP_ERR = traceback.format_exc() HAS_UCSMSDK = False ucs_argument_spec = dict( @@ -51,7 +56,7 @@ class UCSModule(): self.module = module self.result = {} if not HAS_UCSMSDK: - self.module.fail_json(msg='ucsmsdk is required for this module') + self.module.fail_json(msg=missing_required_lib('ucsmsdk'), exception=UCSMSDK_IMP_ERR) self.login() def __del__(self): diff --git a/lib/ansible/modules/net_tools/dnsimple.py b/lib/ansible/modules/net_tools/dnsimple.py index 4538c1f9edb..ad5dfc4299c 100644 --- a/lib/ansible/modules/net_tools/dnsimple.py +++ b/lib/ansible/modules/net_tools/dnsimple.py @@ -140,17 +140,20 @@ EXAMPLES = ''' RETURN = r"""# """ import os +import traceback from distutils.version import LooseVersion +DNSIMPLE_IMP_ERR = None try: from dnsimple import DNSimple from dnsimple.dnsimple import __version__ as dnsimple_version from dnsimple.dnsimple import DNSimpleException HAS_DNSIMPLE = True except ImportError: + DNSIMPLE_IMP_ERR = traceback.format_exc() HAS_DNSIMPLE = False -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib def main(): @@ -176,7 +179,7 @@ def main(): ) if not HAS_DNSIMPLE: - module.fail_json(msg="dnsimple required for this module") + module.fail_json(msg=missing_required_lib('dnsimple'), exception=DNSIMPLE_IMP_ERR) if LooseVersion(dnsimple_version) < LooseVersion('1.0.0'): module.fail_json(msg="Current version of dnsimple Python module [%s] uses 'v1' API which is deprecated." diff --git a/lib/ansible/modules/net_tools/ldap/ldap_attr.py b/lib/ansible/modules/net_tools/ldap/ldap_attr.py index f1640812b6c..848ec24045c 100644 --- a/lib/ansible/modules/net_tools/ldap/ldap_attr.py +++ b/lib/ansible/modules/net_tools/ldap/ldap_attr.py @@ -151,15 +151,17 @@ modlist: import traceback -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils._text import to_native, to_bytes from ansible.module_utils.ldap import LdapGeneric, gen_specs +LDAP_IMP_ERR = None try: import ldap HAS_LDAP = True except ImportError: + LDAP_IMP_ERR = traceback.format_exc() HAS_LDAP = False @@ -246,8 +248,8 @@ def main(): ) if not HAS_LDAP: - module.fail_json( - msg="Missing required 'ldap' module (pip install python-ldap)") + module.fail_json(msg=missing_required_lib('python-ldap'), + exception=LDAP_IMP_ERR) # Update module parameters with user's parameters if defined if 'params' in module.params and isinstance(module.params['params'], dict): diff --git a/lib/ansible/modules/net_tools/ldap/ldap_entry.py b/lib/ansible/modules/net_tools/ldap/ldap_entry.py index 5fca7034a35..0a354b6c460 100644 --- a/lib/ansible/modules/net_tools/ldap/ldap_entry.py +++ b/lib/ansible/modules/net_tools/ldap/ldap_entry.py @@ -108,16 +108,18 @@ RETURN = """ import traceback -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils.six import string_types from ansible.module_utils._text import to_native, to_bytes from ansible.module_utils.ldap import LdapGeneric, gen_specs +LDAP_IMP_ERR = None try: import ldap.modlist HAS_LDAP = True except ImportError: + LDAP_IMP_ERR = traceback.format_exc() HAS_LDAP = False @@ -199,8 +201,8 @@ def main(): ) if not HAS_LDAP: - module.fail_json( - msg="Missing required 'ldap' module (pip install python-ldap).") + module.fail_json(msg=missing_required_lib('python-ldap'), + exception=LDAP_IMP_ERR) state = module.params['state'] diff --git a/lib/ansible/modules/net_tools/ldap/ldap_passwd.py b/lib/ansible/modules/net_tools/ldap/ldap_passwd.py index bf8a22e0a77..b8eaa275c73 100644 --- a/lib/ansible/modules/net_tools/ldap/ldap_passwd.py +++ b/lib/ansible/modules/net_tools/ldap/ldap_passwd.py @@ -67,14 +67,18 @@ modlist: sample: '[[2, "olcRootDN", ["cn=root,dc=example,dc=com"]]]' """ -from ansible.module_utils.basic import AnsibleModule +import traceback + +from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils.ldap import LdapGeneric, gen_specs +LDAP_IMP_ERR = None try: import ldap HAS_LDAP = True except ImportError: + LDAP_IMP_ERR = traceback.format_exc() HAS_LDAP = False @@ -130,8 +134,8 @@ def main(): ) if not HAS_LDAP: - module.fail_json( - msg="Missing required 'ldap' module (pip install python-ldap).") + module.fail_json(msg=missing_required_lib('python-ldap'), + exception=LDAP_IMP_ERR) ldap = LdapPasswd(module) diff --git a/lib/ansible/modules/net_tools/netbox/netbox_device.py b/lib/ansible/modules/net_tools/netbox/netbox_device.py index 775f36c8821..a08be6e8ab8 100644 --- a/lib/ansible/modules/net_tools/netbox/netbox_device.py +++ b/lib/ansible/modules/net_tools/netbox/netbox_device.py @@ -171,13 +171,18 @@ msg: type: str ''' -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.net_tools.netbox.netbox_utils import find_ids, normalize_data, DEVICE_STATUS, FACE_ID import json +import traceback + +from ansible.module_utils.basic import AnsibleModule, missing_required_lib +from ansible.module_utils.net_tools.netbox.netbox_utils import find_ids, normalize_data, DEVICE_STATUS, FACE_ID + +PYNETBOX_IMP_ERR = None try: import pynetbox HAS_PYNETBOX = True except ImportError: + PYNETBOX_IMP_ERR = traceback.format_exc() HAS_PYNETBOX = False @@ -198,7 +203,7 @@ def main(): # Fail module if pynetbox is not installed if not HAS_PYNETBOX: - module.fail_json(msg='pynetbox is required for this module') + module.fail_json(msg=missing_required_lib('pynetbox'), exception=PYNETBOX_IMP_ERR) # Assign variables to be used with module app = 'dcim' diff --git a/lib/ansible/modules/net_tools/netbox/netbox_ip_address.py b/lib/ansible/modules/net_tools/netbox/netbox_ip_address.py index af4ad569b00..2334b02cac4 100644 --- a/lib/ansible/modules/net_tools/netbox/netbox_ip_address.py +++ b/lib/ansible/modules/net_tools/netbox/netbox_ip_address.py @@ -163,14 +163,18 @@ meta: type: list ''' -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.net_tools.netbox.netbox_utils import find_ids, normalize_data, IP_ADDRESS_ROLE, IP_ADDRESS_STATUS import json +import traceback + +from ansible.module_utils.basic import AnsibleModule, missing_required_lib +from ansible.module_utils.net_tools.netbox.netbox_utils import find_ids, normalize_data, IP_ADDRESS_ROLE, IP_ADDRESS_STATUS +PYNETBOX_IMP_ERR = None try: import pynetbox HAS_PYNETBOX = True except ImportError: + PYNETBOX_IMP_ERR = traceback.format_exc() HAS_PYNETBOX = False @@ -247,7 +251,7 @@ def main(): # Fail module if pynetbox is not installed if not HAS_PYNETBOX: - module.fail_json(msg='pynetbox is required for this module') + module.fail_json(msg=missing_required_lib('pynetbox'), exception=PYNETBOX_IMP_ERR) # Assign variables to be used with module changed = False diff --git a/lib/ansible/modules/net_tools/netcup_dns.py b/lib/ansible/modules/net_tools/netcup_dns.py index 5c7b48065e3..acecd0eccd3 100644 --- a/lib/ansible/modules/net_tools/netcup_dns.py +++ b/lib/ansible/modules/net_tools/netcup_dns.py @@ -161,14 +161,18 @@ records: sample: 12345 ''' -from ansible.module_utils.basic import AnsibleModule +import traceback +from ansible.module_utils.basic import AnsibleModule, missing_required_lib + +NCDNSAPI_IMP_ERR = None try: import nc_dnsapi from nc_dnsapi import DNSRecord HAS_NCDNSAPI = True except ImportError: + NCDNSAPI_IMP_ERR = traceback.format_exc() HAS_NCDNSAPI = False @@ -192,7 +196,7 @@ def main(): ) if not HAS_NCDNSAPI: - module.fail_json(msg="nc-dnsapi is required for this module") + module.fail_json(msg=missing_required_lib('nc-dnsapi'), exception=NCDNSAPI_IMP_ERR) api_key = module.params.get('api_key') api_password = module.params.get('api_password') diff --git a/lib/ansible/modules/net_tools/nmcli.py b/lib/ansible/modules/net_tools/nmcli.py index 6a6dfed7bc8..0f888676198 100644 --- a/lib/ansible/modules/net_tools/nmcli.py +++ b/lib/ansible/modules/net_tools/nmcli.py @@ -501,12 +501,17 @@ EXAMPLES = ''' RETURN = r"""# """ +import traceback + +DBUS_IMP_ERR = None try: import dbus HAVE_DBUS = True except ImportError: + DBUS_IMP_ERR = traceback.format_exc() HAVE_DBUS = False +NM_CLIENT_IMP_ERR = None try: import gi gi.require_version('NMClient', '1.0') @@ -515,9 +520,10 @@ try: from gi.repository import NetworkManager, NMClient HAVE_NM_CLIENT = True except (ImportError, ValueError): + NM_CLIENT_IMP_ERR = traceback.format_exc() HAVE_NM_CLIENT = False -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils._text import to_native @@ -1435,10 +1441,10 @@ def main(): ) if not HAVE_DBUS: - module.fail_json(msg="This module requires dbus python bindings") + module.fail_json(msg=missing_required_lib('dbus'), exception=DBUS_IMP_ERR) if not HAVE_NM_CLIENT: - module.fail_json(msg="This module requires NetworkManager glib API") + module.fail_json(msg=missing_required_lib('NetworkManager glib API'), exception=NM_CLIENT_IMP_ERR) nmcli = Nmcli(module) diff --git a/lib/ansible/modules/net_tools/nsupdate.py b/lib/ansible/modules/net_tools/nsupdate.py index 265c518a2c5..a6056134022 100644 --- a/lib/ansible/modules/net_tools/nsupdate.py +++ b/lib/ansible/modules/net_tools/nsupdate.py @@ -156,9 +156,12 @@ dns_rc_str: sample: 'REFUSED' ''' +import traceback + from binascii import Error as binascii_error from socket import error as socket_error +DNSPYTHON_IMP_ERR = None try: import dns.update import dns.query @@ -168,9 +171,10 @@ try: HAVE_DNSPYTHON = True except ImportError: + DNSPYTHON_IMP_ERR = traceback.format_exc() HAVE_DNSPYTHON = False -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils._text import to_native @@ -396,7 +400,7 @@ def main(): ) if not HAVE_DNSPYTHON: - module.fail_json(msg='python library dnspython required: pip install dnspython') + module.fail_json(msg=missing_required_lib('dnspython'), exception=DNSPYTHON_IMP_ERR) if len(module.params["record"]) == 0: module.fail_json(msg='record cannot be empty.') diff --git a/lib/ansible/modules/net_tools/omapi_host.py b/lib/ansible/modules/net_tools/omapi_host.py index 32eb2a8c161..9e5df7a4c29 100644 --- a/lib/ansible/modules/net_tools/omapi_host.py +++ b/lib/ansible/modules/net_tools/omapi_host.py @@ -131,15 +131,17 @@ import socket import struct import traceback +PUREOMAPI_IMP_ERR = None try: from pypureomapi import Omapi, OmapiMessage, OmapiError, OmapiErrorNotFound from pypureomapi import pack_ip, unpack_ip, pack_mac, unpack_mac from pypureomapi import OMAPI_OP_STATUS, OMAPI_OP_UPDATE pureomapi_found = True except ImportError: + PUREOMAPI_IMP_ERR = traceback.format_exc() pureomapi_found = False -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils._text import to_bytes, to_native @@ -290,7 +292,7 @@ def main(): ) if not pureomapi_found: - module.fail_json(msg="pypureomapi library is required by this module.") + module.fail_json(msg=missing_required_lib('pypureomapi'), exception=PUREOMAPI_IMP_ERR) if module.params['key'] is None or len(module.params["key"]) == 0: module.fail_json(msg="'key' parameter cannot be empty.") diff --git a/lib/ansible/modules/net_tools/snmp_facts.py b/lib/ansible/modules/net_tools/snmp_facts.py index 7de197dd038..098aaa0ec53 100644 --- a/lib/ansible/modules/net_tools/snmp_facts.py +++ b/lib/ansible/modules/net_tools/snmp_facts.py @@ -164,15 +164,18 @@ ansible_interfaces: ''' import binascii +import traceback from collections import defaultdict +PYSNMP_IMP_ERR = None try: from pysnmp.entity.rfc3413.oneliner import cmdgen has_pysnmp = True except Exception: + PYSNMP_IMP_ERR = traceback.format_exc() has_pysnmp = False -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils._text import to_text @@ -275,7 +278,7 @@ def main(): m_args = module.params if not has_pysnmp: - module.fail_json(msg='Missing required pysnmp module (check docs)') + module.fail_json(msg=missing_required_lib('pysnmp'), exception=PYSNMP_IMP_ERR) cmdGen = cmdgen.CommandGenerator() diff --git a/lib/ansible/modules/notification/jabber.py b/lib/ansible/modules/notification/jabber.py index d756fc44b2c..1007cab198c 100644 --- a/lib/ansible/modules/notification/jabber.py +++ b/lib/ansible/modules/notification/jabber.py @@ -83,12 +83,14 @@ import time import traceback HAS_XMPP = True +XMPP_IMP_ERR = None try: import xmpp except ImportError: + XMPP_IMP_ERR = traceback.format_exc() HAS_XMPP = False -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils._text import to_native @@ -108,7 +110,7 @@ def main(): ) if not HAS_XMPP: - module.fail_json(msg="The required python xmpp library (xmpppy) is not installed") + module.fail_json(msg=missing_required_lib('xmpppy'), exception=XMPP_IMP_ERR) jid = xmpp.JID(module.params['user']) user = jid.getNode() diff --git a/lib/ansible/modules/notification/matrix.py b/lib/ansible/modules/notification/matrix.py index 622dbba290c..658b9a6e6cc 100644 --- a/lib/ansible/modules/notification/matrix.py +++ b/lib/ansible/modules/notification/matrix.py @@ -72,11 +72,15 @@ EXAMPLES = ''' RETURN = ''' ''' -from ansible.module_utils.basic import AnsibleModule +import traceback +from ansible.module_utils.basic import AnsibleModule, missing_required_lib + +MATRIX_IMP_ERR = None try: from matrix_client.client import MatrixClient except ImportError: + MATRIX_IMP_ERR = traceback.format_exc() matrix_found = False else: matrix_found = True @@ -107,7 +111,7 @@ def run_module(): ) if not matrix_found: - module.fail_json(msg="Python 'matrix-client' module is required. Install via: $ pip install matrix-client") + module.fail_json(msg=missing_required_lib('matrix-client'), exception=MATRIX_IMP_ERR) if module.check_mode: return result diff --git a/lib/ansible/modules/notification/mqtt.py b/lib/ansible/modules/notification/mqtt.py index 6a7444e85a1..a962a811866 100644 --- a/lib/ansible/modules/notification/mqtt.py +++ b/lib/ansible/modules/notification/mqtt.py @@ -112,13 +112,15 @@ import os import traceback HAS_PAHOMQTT = True +PAHOMQTT_IMP_ERR = None try: import socket import paho.mqtt.publish as mqtt except ImportError: + PAHOMQTT_IMP_ERR = traceback.format_exc() HAS_PAHOMQTT = False -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils._text import to_native @@ -147,7 +149,7 @@ def main(): ) if not HAS_PAHOMQTT: - module.fail_json(msg="Paho MQTT is not installed") + module.fail_json(msg=missing_required_lib('paho-mqtt'), exception=PAHOMQTT_IMP_ERR) server = module.params.get("server", 'localhost') port = module.params.get("port", 1883) diff --git a/lib/ansible/modules/notification/pushbullet.py b/lib/ansible/modules/notification/pushbullet.py index f912b489f50..92c68fd60a8 100644 --- a/lib/ansible/modules/notification/pushbullet.py +++ b/lib/ansible/modules/notification/pushbullet.py @@ -84,15 +84,19 @@ EXAMPLES = ''' body: Error rate on signup service is over 90% for more than 2 minutes ''' +import traceback + +PUSHBULLET_IMP_ERR = None try: from pushbullet import PushBullet from pushbullet.errors import InvalidKeyError, PushError except ImportError: + PUSHBULLET_IMP_ERR = traceback.format_exc() pushbullet_found = False else: pushbullet_found = True -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib # =========================================== @@ -125,7 +129,7 @@ def main(): url = module.params['url'] if not pushbullet_found: - module.fail_json(msg="Python 'pushbullet.py' module is required. Install via: $ pip install pushbullet.py") + module.fail_json(msg=missing_required_lib('pushbullet.py'), exception=PUSHBULLET_IMP_ERR) # Init pushbullet try: diff --git a/lib/ansible/modules/notification/sendgrid.py b/lib/ansible/modules/notification/sendgrid.py index 478d502d4b5..3e93e5d897b 100644 --- a/lib/ansible/modules/notification/sendgrid.py +++ b/lib/ansible/modules/notification/sendgrid.py @@ -115,14 +115,17 @@ EXAMPLES = ''' # sendgrid module support methods # import os +import traceback +SENDGRID_IMP_ERR = None try: import sendgrid HAS_SENDGRID = True except ImportError: + SENDGRID_IMP_ERR = traceback.format_exc() HAS_SENDGRID = False -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils.six.moves.urllib.parse import urlencode from ansible.module_utils._text import to_bytes from ansible.module_utils.urls import fetch_url @@ -234,8 +237,10 @@ def main(): sendgrid_lib_args = [api_key, bcc, cc, headers, from_name, html_body, attachments] if any(lib_arg is not None for lib_arg in sendgrid_lib_args) and not HAS_SENDGRID: - module.fail_json(msg='You must install the sendgrid python library if you want to use any of the following arguments: ' - 'api_key, bcc, cc, headers, from_name, html_body, attachments') + reason = 'when using any of the following arguments: ' \ + 'api_key, bcc, cc, headers, from_name, html_body, attachments' + module.fail_json(msg=missing_required_lib('sendgrid', reason=reason), + exception=SENDGRID_IMP_ERR) response, info = post_sendgrid_api(module, username, password, from_address, to_addresses, subject, body, attachments=attachments, diff --git a/lib/ansible/modules/notification/snow_record.py b/lib/ansible/modules/notification/snow_record.py index e9208dc7d23..d0c9ef9d051 100644 --- a/lib/ansible/modules/notification/snow_record.py +++ b/lib/ansible/modules/notification/snow_record.py @@ -146,18 +146,20 @@ attached_file: ''' import os +import traceback -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils._text import to_bytes, to_native # Pull in pysnow HAS_PYSNOW = False +PYSNOW_IMP_ERR = None try: import pysnow HAS_PYSNOW = True except ImportError: - pass + PYSNOW_IMP_ERR = traceback.format_exc() def run_module(): @@ -187,7 +189,7 @@ def run_module(): # check for pysnow if not HAS_PYSNOW: - module.fail_json(msg='pysnow module required') + module.fail_json(msg=missing_required_lib('pysnow'), exception=PYSNOW_IMP_ERR) params = module.params instance = params['instance'] diff --git a/lib/ansible/modules/packaging/language/maven_artifact.py b/lib/ansible/modules/packaging/language/maven_artifact.py index aadb9d73549..01662c736c7 100644 --- a/lib/ansible/modules/packaging/language/maven_artifact.py +++ b/lib/ansible/modules/packaging/language/maven_artifact.py @@ -161,20 +161,25 @@ import posixpath import shutil import io import tempfile +import traceback +LXML_ETREE_IMP_ERR = None try: from lxml import etree HAS_LXML_ETREE = True except ImportError: + LXML_ETREE_IMP_ERR = traceback.format_exc() HAS_LXML_ETREE = False +BOTO_IMP_ERR = None try: import boto3 HAS_BOTO = True except ImportError: + BOTO_IMP_ERR = traceback.format_exc() HAS_BOTO = False -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils.six.moves.urllib.parse import urlparse from ansible.module_utils.urls import fetch_url from ansible.module_utils._text import to_bytes, to_native, to_text @@ -463,7 +468,7 @@ def main(): ) if not HAS_LXML_ETREE: - module.fail_json(msg='module requires the lxml python library installed on the managed machine') + module.fail_json(msg=missing_required_lib('lxml'), exception=LXML_ETREE_IMP_ERR) repository_url = module.params["repository_url"] if not repository_url: @@ -476,7 +481,8 @@ def main(): local = parsed_url.scheme == "file" if parsed_url.scheme == 's3' and not HAS_BOTO: - module.fail_json(msg='boto3 required for this module, when using s3:// repository URLs') + module.fail_json(msg=missing_required_lib('boto3', reason='when using s3:// repository URLs'), + exception=BOTO_IMP_ERR) group_id = module.params["group_id"] artifact_id = module.params["artifact_id"] diff --git a/lib/ansible/modules/packaging/os/layman.py b/lib/ansible/modules/packaging/os/layman.py index 5466d957172..89f0b0b7081 100644 --- a/lib/ansible/modules/packaging/os/layman.py +++ b/lib/ansible/modules/packaging/os/layman.py @@ -80,17 +80,20 @@ EXAMPLES = ''' ''' import shutil +import traceback from os import path +LAYMAN_IMP_ERR = None try: from layman.api import LaymanAPI from layman.config import BareConfig HAS_LAYMAN_API = True except ImportError: + LAYMAN_IMP_ERR = traceback.format_exc() HAS_LAYMAN_API = False -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils.urls import fetch_url @@ -239,7 +242,7 @@ def main(): ) if not HAS_LAYMAN_API: - module.fail_json(msg='Layman is not installed') + module.fail_json(msg=missing_required_lib('Layman'), exception=LAYMAN_IMP_ERR) state, name, url = (module.params[key] for key in ['state', 'name', 'list_url']) diff --git a/lib/ansible/modules/remote_management/hpilo/hpilo_boot.py b/lib/ansible/modules/remote_management/hpilo/hpilo_boot.py index cb1a10933bc..6bc2815c163 100644 --- a/lib/ansible/modules/remote_management/hpilo/hpilo_boot.py +++ b/lib/ansible/modules/remote_management/hpilo/hpilo_boot.py @@ -103,15 +103,18 @@ RETURN = ''' ''' import time +import traceback import warnings +HPILO_IMP_ERR = None try: import hpilo HAS_HPILO = True except ImportError: + HPILO_IMP_ERR = traceback.format_exc() HAS_HPILO = False -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib # Suppress warnings from hpilo @@ -134,7 +137,7 @@ def main(): ) if not HAS_HPILO: - module.fail_json(msg='The hpilo python module is required') + module.fail_json(msg=missing_required_lib('python-hpilo'), exception=HPILO_IMP_ERR) host = module.params['host'] login = module.params['login'] diff --git a/lib/ansible/modules/remote_management/hpilo/hpilo_facts.py b/lib/ansible/modules/remote_management/hpilo/hpilo_facts.py index 70b0051c5ef..64c3f0227a9 100644 --- a/lib/ansible/modules/remote_management/hpilo/hpilo_facts.py +++ b/lib/ansible/modules/remote_management/hpilo/hpilo_facts.py @@ -120,15 +120,18 @@ hw_uuid: ''' import re +import traceback import warnings +HPILO_IMP_ERR = None try: import hpilo HAS_HPILO = True except ImportError: + HPILO_IMP_ERR = traceback.format_exc() HAS_HPILO = False -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib # Suppress warnings from hpilo @@ -161,7 +164,7 @@ def main(): ) if not HAS_HPILO: - module.fail_json(msg='The hpilo python module is required') + module.fail_json(msg=missing_required_lib('python-hpilo'), exception=HPILO_IMP_ERR) host = module.params['host'] login = module.params['login'] diff --git a/lib/ansible/modules/remote_management/imc/imc_rest.py b/lib/ansible/modules/remote_management/imc/imc_rest.py index b8440b322e3..455a0f2490d 100644 --- a/lib/ansible/modules/remote_management/imc/imc_rest.py +++ b/lib/ansible/modules/remote_management/imc/imc_rest.py @@ -262,20 +262,25 @@ import atexit import datetime import itertools import os +import traceback +LXML_ETREE_IMP_ERR = None try: import lxml.etree HAS_LXML_ETREE = True except ImportError: + LXML_ETREE_IMP_ERR = traceback.format_exc() HAS_LXML_ETREE = False +XMLJSON_COBRA_IMP_ERR = None try: from xmljson import cobra HAS_XMLJSON_COBRA = True except ImportError: + XMLJSON_COBRA_IMP_ERR = traceback.format_exc() HAS_XMLJSON_COBRA = False -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils.urls import fetch_url @@ -334,10 +339,10 @@ def main(): ) if not HAS_LXML_ETREE: - module.fail_json(msg='module requires the lxml Python library installed on the managed host') + module.fail_json(msg=missing_required_lib('lxml'), exception=LXML_ETREE_IMP_ERR) if not HAS_XMLJSON_COBRA: - module.fail_json(msg='module requires the xmljson (>= 0.1.8) Python library installed on the managed host') + module.fail_json(msg=missing_required_lib('xmljson >= 0.1.8'), exception=XMLJSON_COBRA_IMP_ERR) hostname = module.params['hostname'] username = module.params['username'] diff --git a/lib/ansible/modules/remote_management/ipmi/ipmi_boot.py b/lib/ansible/modules/remote_management/ipmi/ipmi_boot.py index 8cc8ffc7d0c..b2f1da051a8 100644 --- a/lib/ansible/modules/remote_management/ipmi/ipmi_boot.py +++ b/lib/ansible/modules/remote_management/ipmi/ipmi_boot.py @@ -110,12 +110,16 @@ EXAMPLES = ''' state: absent ''' +import traceback + +PYGHMI_IMP_ERR = None try: from pyghmi.ipmi import command except ImportError: + PYGHMI_IMP_ERR = traceback.format_exc() command = None -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib def main(): @@ -134,7 +138,7 @@ def main(): ) if command is None: - module.fail_json(msg='the python pyghmi module is required') + module.fail_json(msg=missing_required_lib('pyghmi'), exception=PYGHMI_IMP_ERR) name = module.params['name'] port = module.params['port'] diff --git a/lib/ansible/modules/remote_management/ipmi/ipmi_power.py b/lib/ansible/modules/remote_management/ipmi/ipmi_power.py index 8dea792ab81..40601b6e9f7 100644 --- a/lib/ansible/modules/remote_management/ipmi/ipmi_power.py +++ b/lib/ansible/modules/remote_management/ipmi/ipmi_power.py @@ -74,12 +74,16 @@ EXAMPLES = ''' state: on ''' +import traceback + +PYGHMI_IMP_ERR = None try: from pyghmi.ipmi import command except ImportError: + PYGHMI_IMP_ERR = traceback.format_exc() command = None -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib def main(): @@ -96,7 +100,7 @@ def main(): ) if command is None: - module.fail_json(msg='the python pyghmi module is required') + module.fail_json(msg=missing_required_lib('pyghmi'), exception=PYGHMI_IMP_ERR) name = module.params['name'] port = module.params['port'] diff --git a/lib/ansible/modules/remote_management/ucs/ucs_managed_objects.py b/lib/ansible/modules/remote_management/ucs/ucs_managed_objects.py index fead566c826..9f5ed4117a0 100644 --- a/lib/ansible/modules/remote_management/ucs/ucs_managed_objects.py +++ b/lib/ansible/modules/remote_management/ucs/ucs_managed_objects.py @@ -161,15 +161,19 @@ RETURN = r''' # ''' +import traceback + +IMPORT_IMP_ERR = None try: from importlib import import_module HAS_IMPORT_MODULE = True except Exception: + IMPORT_IMP_ERR = traceback.format_exc() HAS_IMPORT_MODULE = False from copy import deepcopy import json -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils.remote_management.ucs import UCSModule, ucs_argument_spec @@ -241,7 +245,7 @@ def main(): ) if not HAS_IMPORT_MODULE: - module.fail_json(msg='import_module is required for this module') + module.fail_json(msg=missing_required_lib('importlib'), exception=IMPORT_IMP_ERR) ucs = UCSModule(module) ucs.result['err'] = False diff --git a/lib/ansible/modules/source_control/github_issue.py b/lib/ansible/modules/source_control/github_issue.py index 5e3e33829a5..4ac47917e2a 100644 --- a/lib/ansible/modules/source_control/github_issue.py +++ b/lib/ansible/modules/source_control/github_issue.py @@ -66,14 +66,17 @@ EXAMPLES = ''' when: r.issue_status == 'open' ''' +import traceback +GITHUB_IMP_ERR = None try: import github3 HAS_GITHUB_PACKAGE = True except ImportError: + GITHUB_IMP_ERR = traceback.format_exc() HAS_GITHUB_PACKAGE = False -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib def main(): @@ -88,8 +91,8 @@ def main(): ) if not HAS_GITHUB_PACKAGE: - module.fail_json(msg="Missing required github3 module. (check docs or " - "install with: pip install github3.py==1.0.0a4)") + module.fail_json(msg=missing_required_lib('github3.py >= 1.0.0a4'), + exception=GITHUB_IMP_ERR) organization = module.params['organization'] repo = module.params['repo'] diff --git a/lib/ansible/modules/source_control/github_release.py b/lib/ansible/modules/source_control/github_release.py index 01796530722..132877d2900 100644 --- a/lib/ansible/modules/source_control/github_release.py +++ b/lib/ansible/modules/source_control/github_release.py @@ -127,14 +127,18 @@ latest_release: sample: 1.1.0 ''' +import traceback + +GITHUB_IMP_ERR = None try: import github3 HAS_GITHUB_API = True except ImportError: + GITHUB_IMP_ERR = traceback.format_exc() HAS_GITHUB_API = False -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils._text import to_native @@ -161,8 +165,8 @@ def main(): ) if not HAS_GITHUB_API: - module.fail_json(msg='Missing required github3 module (check docs or ' - 'install with: pip install github3.py==1.0.0a4)') + module.fail_json(msg=missing_required_lib('github3.py >= 1.0.0a3'), + exception=GITHUB_IMP_ERR) repo = module.params['repo'] user = module.params['user'] diff --git a/lib/ansible/modules/source_control/github_webhook.py b/lib/ansible/modules/source_control/github_webhook.py index 387abad897e..b87e4377f1a 100644 --- a/lib/ansible/modules/source_control/github_webhook.py +++ b/lib/ansible/modules/source_control/github_webhook.py @@ -135,13 +135,15 @@ hook_id: import traceback +GITHUB_IMP_ERR = None try: import github HAS_GITHUB = True except ImportError: + GITHUB_IMP_ERR = traceback.format_exc() HAS_GITHUB = False -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils._text import to_native @@ -219,7 +221,8 @@ def main(): ) if not HAS_GITHUB: - module.fail_json(msg="PyGithub required for this module") + module.fail_json(msg=missing_required_lib('PyGithub'), + exception=GITHUB_IMP_ERR) try: github_conn = github.Github( diff --git a/lib/ansible/modules/source_control/github_webhook_facts.py b/lib/ansible/modules/source_control/github_webhook_facts.py index 2afead90aff..920d349062a 100644 --- a/lib/ansible/modules/source_control/github_webhook_facts.py +++ b/lib/ansible/modules/source_control/github_webhook_facts.py @@ -86,13 +86,15 @@ hooks: import traceback +GITHUB_IMP_ERR = None try: import github HAS_GITHUB = True except ImportError: + GITHUB_IMP_ERR = traceback.format_exc() HAS_GITHUB = False -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils._text import to_native @@ -126,7 +128,8 @@ def main(): supports_check_mode=True) if not HAS_GITHUB: - module.fail_json(msg="PyGithub required for this module") + module.fail_json(msg=missing_required_lib('PyGithub'), + exception=GITHUB_IMP_ERR) try: github_conn = github.Github( diff --git a/lib/ansible/modules/system/dconf.py b/lib/ansible/modules/system/dconf.py index 1f266706de3..8183b07648d 100644 --- a/lib/ansible/modules/system/dconf.py +++ b/lib/ansible/modules/system/dconf.py @@ -119,14 +119,17 @@ EXAMPLES = """ import os +import traceback +PSUTIL_IMP_ERR = None try: import psutil psutil_found = True except ImportError: + PSUTIL_IMP_ERR = traceback.format_exc() psutil_found = False -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib class DBusWrapper(object): @@ -350,7 +353,7 @@ def main(): ) if not psutil_found: - module.fail_json(msg="Python module psutil is required on managed machine") + module.fail_json(msg=missing_required_lib("psutil"), exception=PSUTIL_IMP_ERR) # If present state was specified, value must be provided. if module.params['state'] == 'present' and module.params['value'] is None: diff --git a/lib/ansible/modules/system/seboolean.py b/lib/ansible/modules/system/seboolean.py index 748f61068a7..4b477e384e5 100644 --- a/lib/ansible/modules/system/seboolean.py +++ b/lib/ansible/modules/system/seboolean.py @@ -56,20 +56,25 @@ EXAMPLES = ''' ''' import os +import traceback +SELINUX_IMP_ERR = None try: import selinux HAVE_SELINUX = True except ImportError: + SELINUX_IMP_ERR = traceback.format_exc() HAVE_SELINUX = False +SEMANAGE_IMP_ERR = None try: import semanage HAVE_SEMANAGE = True except ImportError: + SEMANAGE_IMP_ERR = traceback.format_exc() HAVE_SEMANAGE = False -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils.six import binary_type from ansible.module_utils._text import to_bytes, to_text @@ -279,10 +284,10 @@ def main(): ) if not HAVE_SELINUX: - module.fail_json(msg="This module requires libselinux-python support") + module.fail_json(msg=missing_required_lib('libselinux-python'), exception=SELINUX_IMP_ERR) if not HAVE_SEMANAGE: - module.fail_json(msg="This module requires libsemanage-python support") + module.fail_json(msg=missing_required_lib('libsemanage-python'), exception=SEMANAGE_IMP_ERR) ignore_selinux_state = module.params['ignore_selinux_state'] diff --git a/lib/ansible/modules/system/sefcontext.py b/lib/ansible/modules/system/sefcontext.py index 47daa3d6b3d..e2f20543f5a 100644 --- a/lib/ansible/modules/system/sefcontext.py +++ b/lib/ansible/modules/system/sefcontext.py @@ -102,19 +102,25 @@ RETURN = r''' # Default return values ''' -from ansible.module_utils.basic import AnsibleModule +import traceback + +from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils._text import to_native +SELINUX_IMP_ERR = None try: import selinux HAVE_SELINUX = True except ImportError: + SELINUX_IMP_ERR = traceback.format_exc() HAVE_SELINUX = False +SEOBJECT_IMP_ERR = None try: import seobject HAVE_SEOBJECT = True except ImportError: + SEOBJECT_IMP_ERR = traceback.format_exc() HAVE_SEOBJECT = False # Add missing entries (backward compatible) @@ -257,10 +263,10 @@ def main(): supports_check_mode=True, ) if not HAVE_SELINUX: - module.fail_json(msg="This module requires libselinux-python") + module.fail_json(msg=missing_required_lib("libselinux-python"), exception=SELINUX_IMP_ERR) if not HAVE_SEOBJECT: - module.fail_json(msg="This module requires policycoreutils-python") + module.fail_json(msg=missing_required_lib("policycoreutils-python"), exception=SEOBJECT_IMP_ERR) ignore_selinux_state = module.params['ignore_selinux_state'] diff --git a/lib/ansible/modules/system/selinux.py b/lib/ansible/modules/system/selinux.py index 79f4ed30725..ce824a4bf7a 100644 --- a/lib/ansible/modules/system/selinux.py +++ b/lib/ansible/modules/system/selinux.py @@ -89,14 +89,17 @@ reboot_required: import os import re import tempfile +import traceback +SELINUX_IMP_ERR = None try: import selinux HAS_SELINUX = True except ImportError: + SELINUX_IMP_ERR = traceback.format_exc() HAS_SELINUX = False -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils.facts.utils import get_file_lines @@ -176,7 +179,7 @@ def main(): ) if not HAS_SELINUX: - module.fail_json(msg='libselinux-python required for this module') + module.fail_json(msg=missing_required_lib('libselinux-python'), exception=SELINUX_IMP_ERR) # global vars changed = False diff --git a/lib/ansible/modules/system/selinux_permissive.py b/lib/ansible/modules/system/selinux_permissive.py index d7f4a8bd123..f061d58b0d3 100644 --- a/lib/ansible/modules/system/selinux_permissive.py +++ b/lib/ansible/modules/system/selinux_permissive.py @@ -57,13 +57,14 @@ EXAMPLES = ''' import traceback HAVE_SEOBJECT = False +SEOBJECT_IMP_ERR = None try: import seobject HAVE_SEOBJECT = True except ImportError: - pass + SEOBJECT_IMP_ERR = traceback.format_exc() -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils._text import to_native @@ -86,7 +87,8 @@ def main(): no_reload = module.params['no_reload'] if not HAVE_SEOBJECT: - module.fail_json(changed=False, msg="policycoreutils-python required for this module") + module.fail_json(changed=False, msg=missing_required_lib("policycoreutils-python"), + exception=SEOBJECT_IMP_ERR) try: permissive_domains = seobject.permissiveRecords(store) diff --git a/lib/ansible/modules/system/seport.py b/lib/ansible/modules/system/seport.py index ccd20068251..f3101ed56fb 100644 --- a/lib/ansible/modules/system/seport.py +++ b/lib/ansible/modules/system/seport.py @@ -92,19 +92,23 @@ EXAMPLES = ''' import traceback +SELINUX_IMP_ERR = None try: import selinux HAVE_SELINUX = True except ImportError: + SELINUX_IMP_ERR = traceback.format_exc() HAVE_SELINUX = False +SEOBJECT_IMP_ERR = None try: import seobject HAVE_SEOBJECT = True except ImportError: + SEOBJECT_IMP_ERR = traceback.format_exc() HAVE_SEOBJECT = False -from ansible.module_utils.basic import AnsibleModule, HAVE_SELINUX +from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils._text import to_native @@ -261,10 +265,10 @@ def main(): ) if not HAVE_SELINUX: - module.fail_json(msg="This module requires libselinux-python") + module.fail_json(msg=missing_required_lib("libselinux-python"), exception=SELINUX_IMP_ERR) if not HAVE_SEOBJECT: - module.fail_json(msg="This module requires policycoreutils-python") + module.fail_json(msg=missing_required_lib("policycoreutils-python"), exception=SEOBJECT_IMP_ERR) ignore_selinux_state = module.params['ignore_selinux_state'] diff --git a/lib/ansible/modules/system/vdo.py b/lib/ansible/modules/system/vdo.py index 488a4c63576..d5d53dd56f8 100644 --- a/lib/ansible/modules/system/vdo.py +++ b/lib/ansible/modules/system/vdo.py @@ -290,13 +290,16 @@ EXAMPLES = r''' RETURN = r'''# ''' -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib import re +import traceback +YAML_IMP_ERR = None try: import yaml HAS_YAML = True except ImportError: + YAML_IMP_ERR = traceback.format_exc() HAS_YAML = False @@ -490,7 +493,7 @@ def run_module(): ) if not HAS_YAML: - module.fail_json(msg='PyYAML is required for this module.') + module.fail_json(msg=missing_required_lib('PyYAML'), exception=YAML_IMP_ERR) vdocmd = module.get_bin_path("vdo", required=True) if not vdocmd: