dell / dellemc-openmanage-ansible-modules

Dell OpenManage Ansible Modules
GNU General Public License v3.0
340 stars 164 forks source link

[BUG]: dellemc.openmanage 8.2.0 ignores ```NO_PROXY``` #554

Closed sbeyermann closed 11 months ago

sbeyermann commented 1 year ago

Bug Description

In our environment we need to use a proxy to access public internet resources. Our Dell OpenManage Enterprise installation however can be reached directly and not via the proxy server. Therefore on our machines we have the http_proxy, HTTP_PROXY, https_proxy, HTTPS_PROXY, no_proxy and NO_PROXY environment variables defined. http_proxy, HTTP_PROXY, https_proxy and HTTPS_PROXY point to our proxy server while no_proxy and NO_PROXY contains proxy bypass exceptions for internal resources in the format .company.com

With dellemc.openmanage modules 8.0.0 and 8.1.0 this worked fine and our ansible host was able to communicate with our Dell OpenManage Enterprise installation. Unfortunately with dellemc.openmanage 8.2.0 we receive the following error message:

<urlopen error _ssl.c:975: The handshake operation timed out>

I did some troubleshooting and for me it looks like the ome.py in version 8.2.0 does a DNS lookup of the URL first and then connects to the IP address of the Dell OpenManage installation instead of the DNS FQDN. Therefore our proxy bypass exceptions do not match anymore and the dellemc.openmanage tries to contact our OME through our proxy which fails.

As a workaround I added the IP address of our OME installation to the NO_PROXY environment variable as well and afterwards dellemc.openmanage is able to contact OME again.

Component or Module Name

dellemc.openmanage.ome_device_info

Ansible Version

Ansible core 2.15.4

Python Version

Pyhton 3.11.2

iDRAC/OME/OME-M version

OME 3.10.2 dellemc.openmanage 8.2.0

Operating System

Debian 11

Playbook Used

- name: Retrieve basic managed device information from Dell Openmanage Enterprise
  dellemc.openmanage.ome_device_info:
    hostname: "{{ ome_server }}"
    username: "{{ domain_user ~ '@' ~ domain }}"
    password: "{{ domain_password }}"
    ca_path: "{{ ome_ca_path }}"
    validate_certs: "{{ ome_validate_certs }}"
    system_query_options:
      filter: "DeviceName eq '{{ inventory_hostname }}'"
  delegate_to: localhost
  register: update_firmware_ome_device_info

Logs

TASK [update_firmware : Retrieve basic managed device information from Dell Openmanage Enterprise] ***************************************************************************************************************************************
task path: /scripts/ansible/roles/update_firmware/tasks/main.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 `"&& mkdir "` echo /root/.ansible/tmp/ansible-tmp-1694755665.3208275-79-183326375421279 `" && echo ansible-tmp-1694755665.3208275-79-183326375421279="` echo /root/.ansible/tmp/ansible-tmp-1694755665.3208275-79-183326375421279 `" ) && sleep 0'
Using module file /opt/ansible_venv/lib/python3.11/site-packages/ansible_collections/dellemc/openmanage/plugins/modules/ome_device_info.py
<localhost> PUT /root/.ansible/tmp/ansible-local-6101xabs_a/tmpu4iof2tu TO /root/.ansible/tmp/ansible-tmp-1694755665.3208275-79-183326375421279/AnsiballZ_ome_device_info.py
<localhost> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp-1694755665.3208275-79-183326375421279/ /root/.ansible/tmp/ansible-tmp-1694755665.3208275-79-183326375421279/AnsiballZ_ome_device_info.py && sleep 0'
<localhost> EXEC /bin/sh -c '/opt/ansible_venv/bin/python3 /root/.ansible/tmp/ansible-tmp-1694755665.3208275-79-183326375421279/AnsiballZ_ome_device_info.py && sleep 0'
<localhost> EXEC /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-tmp-1694755665.3208275-79-183326375421279/ > /dev/null 2>&1 && sleep 0'
The full traceback is:
  File "/tmp/ansible_dellemc.openmanage.ome_device_info_payload_ktgztv2v/ansible_dellemc.openmanage.ome_device_info_payload.zip/ansible_collections/dellemc/openmanage/plugins/modules/ome_device_info.py", line 389, in main
  File "/tmp/ansible_dellemc.openmanage.ome_device_info_payload_ktgztv2v/ansible_dellemc.openmanage.ome_device_info_payload.zip/ansible_collections/dellemc/openmanage/plugins/module_utils/ome.py", line 206, in __enter__
    resp = self.invoke_request('POST', path, data=payload)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/ansible_dellemc.openmanage.ome_device_info_payload_ktgztv2v/ansible_dellemc.openmanage.ome_device_info_payload.zip/ansible_collections/dellemc/openmanage/plugins/module_utils/ome.py", line 196, in invoke_request
    raise err
  File "/tmp/ansible_dellemc.openmanage.ome_device_info_payload_ktgztv2v/ansible_dellemc.openmanage.ome_device_info_payload.zip/ansible_collections/dellemc/openmanage/plugins/module_utils/ome.py", line 193, in invoke_request
    resp = open_url(url, data=data, **url_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/ansible_dellemc.openmanage.ome_device_info_payload_ktgztv2v/ansible_dellemc.openmanage.ome_device_info_payload.zip/ansible/module_utils/urls.py", line 1669, in open_url
    return Request().open(method, url, data=data, headers=headers, use_proxy=use_proxy,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/ansible_dellemc.openmanage.ome_device_info_payload_ktgztv2v/ansible_dellemc.openmanage.ome_device_info_payload.zip/ansible/module_utils/urls.py", line 1561, in open
    r = urllib_request.urlopen(request, None, timeout)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/urllib/request.py", line 216, in urlopen
    return opener.open(url, data, timeout)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/urllib/request.py", line 519, in open
    response = self._open(req, data)
               ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/urllib/request.py", line 536, in _open
    result = self._call_chain(self.handle_open, protocol, protocol +
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/urllib/request.py", line 496, in _call_chain
    result = func(*args)
             ^^^^^^^^^^^
  File "/tmp/ansible_dellemc.openmanage.ome_device_info_payload_ktgztv2v/ansible_dellemc.openmanage.ome_device_info_payload.zip/ansible/module_utils/urls.py", line 605, in https_open
    return self.do_open(self._build_https_connection, req)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/urllib/request.py", line 1351, in do_open
    raise URLError(err)
fatal: [somehost.company.com -> localhost]: FAILED! => changed=false
  failed_when_result: true
  invocation:
    module_args:
      ca_path: /usr/local/share/ca-certificates/OUR-CA.crt
      fact_subset: basic_inventory
      hostname: ome.company.com
      password: VALUE_SPECIFIED_IN_NO_LOG_PARAMETER
      port: 443
      system_query_options:
        device_id: null
        device_service_tag: null
        filter: DeviceName eq 'somehost.company.com'
        inventory_type: null
      timeout: 30
      username: admin@company.com
      validate_certs: false
  msg: '<urlopen error _ssl.c:975: The handshake operation timed out>'

Steps to Reproduce

Expected Behavior

Connections to the domain name of the OME installation will honor proxy bypass exceptions and be created directly (as in dellemc.openmanage 8.0.0 or 8.1.0

Actual Behavior

dellemc.openmanage 8.2.0 tries to access the OME system through proxy because IP addresses proxy bypass exceptions are not set in no_proxy or NO_PROXY environment variables

Screenshots

No response

Additional Information

No response

anupamaloke commented 1 year ago

@sbeyermann, thanks for submitting the issue. We are analyzing this one and accordingly pick it up for a fix in future release.

sachin-apa commented 1 year ago

@sbeyermann Can you please help me verifying a changes. Please replace the code in ome.py from line 106 - 114 with the below code.

host_ipaddress = ipaddress.ip_address(self.hostname)
if host_ipaddress.version == 6:
    self.hostname = "[{0}]".format(self.hostname)

Attached the file for a reference. ome.zip

sbeyermann commented 1 year ago

@sachin-apa Thank you for picking up this issue. I replaced the original dellemc.openmanage 8.2.0's ome.py with the file you provided. Unfortunately this results in the following error:

The full traceback is:
  File "/tmp/ansible_dellemc.openmanage.ome_device_info_payload_68lqup6r/ansible_dellemc.openmanage.ome_device_info_payload.zip/ansible_collections/dellemc/openmanage/plugins/modules/ome_device_info.py", line 389, in main
  File "/tmp/ansible_dellemc.openmanage.ome_device_info_payload_68lqup6r/ansible_dellemc.openmanage.ome_device_info_payload.zip/ansible_collections/dellemc/openmanage/plugins/module_utils/ome.py", line 107, in __init__
    host_ipaddress = ipaddress.ip_address(self.hostname)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/ipaddress.py", line 54, in ip_address
    raise ValueError(f'{address!r} does not appear to be an IPv4 or IPv6 address')
fatal: [somehost.company.com -> localhost]: FAILED! => changed=false
  invocation:
    module_args:
      ca_path: /etc/ssl/certs/ca-certificates.crt
      fact_subset: basic_inventory
      hostname: ome.company.com
      password: VALUE_SPECIFIED_IN_NO_LOG_PARAMETER
      port: 443
      system_query_options:
        device_id: null
        device_service_tag: null
        filter: DeviceName eq 'somehost.company.com'
        inventory_type: null
      timeout: 30
      username: admin@company.com
      validate_certs: false
  msg: '''ome.company.com'' does not appear to be an IPv4 or IPv6 address'