mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
* Fixed imc_rest session logout
* Update plugins/modules/remote_management/imc/imc_rest.py
Co-authored-by: Felix Fontein <felix@fontein.de>
* Update changelogs/fragments/1735-imc-sessions.yml
Co-authored-by: Felix Fontein <felix@fontein.de>
* Trying with try/finally
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit fdb66d5567
)
Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
This commit is contained in:
parent
58317b37b3
commit
aad2b2400e
5 changed files with 47 additions and 41 deletions
2
changelogs/fragments/1735-imc-sessions.yml
Normal file
2
changelogs/fragments/1735-imc-sessions.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
bugfixes:
|
||||||
|
- imc_rest - explicitly logging out instead of registering the call in ```atexit``` (https://github.com/ansible-collections/community.general/issues/1735).
|
|
@ -27,21 +27,25 @@ options:
|
||||||
- IP Address or hostname of Cisco IMC, resolvable by Ansible control host.
|
- IP Address or hostname of Cisco IMC, resolvable by Ansible control host.
|
||||||
required: true
|
required: true
|
||||||
aliases: [ host, ip ]
|
aliases: [ host, ip ]
|
||||||
|
type: str
|
||||||
username:
|
username:
|
||||||
description:
|
description:
|
||||||
- Username used to login to the switch.
|
- Username used to login to the switch.
|
||||||
default: admin
|
default: admin
|
||||||
aliases: [ user ]
|
aliases: [ user ]
|
||||||
|
type: str
|
||||||
password:
|
password:
|
||||||
description:
|
description:
|
||||||
- The password to use for authentication.
|
- The password to use for authentication.
|
||||||
default: password
|
default: password
|
||||||
|
type: str
|
||||||
path:
|
path:
|
||||||
description:
|
description:
|
||||||
- Name of the absolute path of the filename that includes the body
|
- Name of the absolute path of the filename that includes the body
|
||||||
of the http request being sent to the Cisco IMC REST API.
|
of the http request being sent to the Cisco IMC REST API.
|
||||||
- Parameter C(path) is mutual exclusive with parameter C(content).
|
- Parameter C(path) is mutual exclusive with parameter C(content).
|
||||||
aliases: [ 'src', 'config_file' ]
|
aliases: [ 'src', 'config_file' ]
|
||||||
|
type: path
|
||||||
content:
|
content:
|
||||||
description:
|
description:
|
||||||
- When used instead of C(path), sets the content of the API requests directly.
|
- When used instead of C(path), sets the content of the API requests directly.
|
||||||
|
@ -49,11 +53,13 @@ options:
|
||||||
- You can collate multiple IMC XML fragments and they will be processed sequentially in a single stream,
|
- You can collate multiple IMC XML fragments and they will be processed sequentially in a single stream,
|
||||||
the Cisco IMC output is subsequently merged.
|
the Cisco IMC output is subsequently merged.
|
||||||
- Parameter C(content) is mutual exclusive with parameter C(path).
|
- Parameter C(content) is mutual exclusive with parameter C(path).
|
||||||
|
type: str
|
||||||
protocol:
|
protocol:
|
||||||
description:
|
description:
|
||||||
- Connection protocol to use.
|
- Connection protocol to use.
|
||||||
default: https
|
default: https
|
||||||
choices: [ http, https ]
|
choices: [ http, https ]
|
||||||
|
type: str
|
||||||
timeout:
|
timeout:
|
||||||
description:
|
description:
|
||||||
- The socket level timeout in seconds.
|
- The socket level timeout in seconds.
|
||||||
|
@ -61,6 +67,7 @@ options:
|
||||||
If this C(timeout) is reached, the module will fail with a
|
If this C(timeout) is reached, the module will fail with a
|
||||||
C(Connection failure) indicating that C(The read operation timed out).
|
C(Connection failure) indicating that C(The read operation timed out).
|
||||||
default: 60
|
default: 60
|
||||||
|
type: int
|
||||||
validate_certs:
|
validate_certs:
|
||||||
description:
|
description:
|
||||||
- If C(no), SSL certificates will not be validated.
|
- If C(no), SSL certificates will not be validated.
|
||||||
|
@ -253,11 +260,11 @@ output:
|
||||||
errorDescr="XML PARSING ERROR: Element 'computeRackUnit', attribute 'admin_Power': The attribute 'admin_Power' is not allowed.\n"/>
|
errorDescr="XML PARSING ERROR: Element 'computeRackUnit', attribute 'admin_Power': The attribute 'admin_Power' is not allowed.\n"/>
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import atexit
|
|
||||||
import datetime
|
import datetime
|
||||||
import itertools
|
import itertools
|
||||||
import os
|
import os
|
||||||
import traceback
|
import traceback
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
LXML_ETREE_IMP_ERR = None
|
LXML_ETREE_IMP_ERR = None
|
||||||
try:
|
try:
|
||||||
|
@ -317,7 +324,6 @@ def merge(one, two):
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
module = AnsibleModule(
|
module = AnsibleModule(
|
||||||
argument_spec=dict(
|
argument_spec=dict(
|
||||||
hostname=dict(type='str', required=True, aliases=['host', 'ip']),
|
hostname=dict(type='str', required=True, aliases=['host', 'ip']),
|
||||||
|
@ -374,53 +380,54 @@ def main():
|
||||||
result.update(imc_response(module, resp.read()))
|
result.update(imc_response(module, resp.read()))
|
||||||
|
|
||||||
# Store cookie for future requests
|
# Store cookie for future requests
|
||||||
|
cookie = ''
|
||||||
try:
|
try:
|
||||||
cookie = result['aaaLogin']['attributes']['outCookie']
|
cookie = result['aaaLogin']['attributes']['outCookie']
|
||||||
except Exception:
|
except Exception:
|
||||||
module.fail_json(msg='Could not find cookie in output', **result)
|
module.fail_json(msg='Could not find cookie in output', **result)
|
||||||
|
|
||||||
# If we would not log out properly, we run out of sessions quickly
|
try:
|
||||||
atexit.register(logout, module, url, cookie, timeout)
|
# Prepare request data
|
||||||
|
if content:
|
||||||
|
rawdata = content
|
||||||
|
elif file_exists:
|
||||||
|
with open(path, 'r') as config_object:
|
||||||
|
rawdata = config_object.read()
|
||||||
|
|
||||||
# Prepare request data
|
# Wrap the XML documents in a <root> element
|
||||||
if content:
|
xmldata = lxml.etree.fromstring('<root>%s</root>' % rawdata.replace('\n', ''))
|
||||||
rawdata = content
|
|
||||||
elif file_exists:
|
|
||||||
with open(path, 'r') as config_object:
|
|
||||||
rawdata = config_object.read()
|
|
||||||
|
|
||||||
# Wrap the XML documents in a <root> element
|
# Handle each XML document separately in the same session
|
||||||
xmldata = lxml.etree.fromstring('<root>%s</root>' % rawdata.replace('\n', ''))
|
for xmldoc in list(xmldata):
|
||||||
|
if xmldoc.tag is lxml.etree.Comment:
|
||||||
|
continue
|
||||||
|
# Add cookie to XML
|
||||||
|
xmldoc.set('cookie', cookie)
|
||||||
|
data = lxml.etree.tostring(xmldoc)
|
||||||
|
|
||||||
# Handle each XML document separately in the same session
|
# Perform actual request
|
||||||
for xmldoc in list(xmldata):
|
resp, info = fetch_url(module, url, data=data, method='POST', timeout=timeout)
|
||||||
if xmldoc.tag is lxml.etree.Comment:
|
if resp is None or info['status'] != 200:
|
||||||
continue
|
result['elapsed'] = (datetime.datetime.utcnow() - start).seconds
|
||||||
# Add cookie to XML
|
module.fail_json(msg='Task failed with error %(status)s: %(msg)s' % info, **result)
|
||||||
xmldoc.set('cookie', cookie)
|
|
||||||
data = lxml.etree.tostring(xmldoc)
|
|
||||||
|
|
||||||
# Perform actual request
|
# Merge results with previous results
|
||||||
resp, info = fetch_url(module, url, data=data, method='POST', timeout=timeout)
|
rawoutput = resp.read()
|
||||||
if resp is None or info['status'] != 200:
|
result = merge(result, imc_response(module, rawoutput, rawinput=data))
|
||||||
result['elapsed'] = (datetime.datetime.utcnow() - start).seconds
|
result['response'] = info['msg']
|
||||||
module.fail_json(msg='Task failed with error %(status)s: %(msg)s' % info, **result)
|
result['status'] = info['status']
|
||||||
|
|
||||||
# Merge results with previous results
|
# Check for any changes
|
||||||
rawoutput = resp.read()
|
# NOTE: Unfortunately IMC API always report status as 'modified'
|
||||||
result = merge(result, imc_response(module, rawoutput, rawinput=data))
|
xmloutput = lxml.etree.fromstring(rawoutput)
|
||||||
result['response'] = info['msg']
|
results = xmloutput.xpath('/configConfMo/outConfig/*/@status')
|
||||||
result['status'] = info['status']
|
result['changed'] = ('modified' in results)
|
||||||
|
|
||||||
# Check for any changes
|
# Report success
|
||||||
# NOTE: Unfortunately IMC API always report status as 'modified'
|
result['elapsed'] = (datetime.datetime.utcnow() - start).seconds
|
||||||
xmloutput = lxml.etree.fromstring(rawoutput)
|
module.exit_json(**result)
|
||||||
results = xmloutput.xpath('/configConfMo/outConfig/*/@status')
|
finally:
|
||||||
result['changed'] = ('modified' in results)
|
logout(module, url, cookie, timeout)
|
||||||
|
|
||||||
# Report success
|
|
||||||
result['elapsed'] = (datetime.datetime.utcnow() - start).seconds
|
|
||||||
module.exit_json(**result)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -331,7 +331,6 @@ plugins/modules/remote_management/foreman/katello.py yamllint:unparsable-with-li
|
||||||
plugins/modules/remote_management/hpilo/hpilo_boot.py validate-modules:parameter-type-not-in-doc
|
plugins/modules/remote_management/hpilo/hpilo_boot.py validate-modules:parameter-type-not-in-doc
|
||||||
plugins/modules/remote_management/hpilo/hpilo_info.py validate-modules:parameter-type-not-in-doc
|
plugins/modules/remote_management/hpilo/hpilo_info.py validate-modules:parameter-type-not-in-doc
|
||||||
plugins/modules/remote_management/hpilo/hponcfg.py validate-modules:parameter-type-not-in-doc
|
plugins/modules/remote_management/hpilo/hponcfg.py validate-modules:parameter-type-not-in-doc
|
||||||
plugins/modules/remote_management/imc/imc_rest.py validate-modules:parameter-type-not-in-doc
|
|
||||||
plugins/modules/remote_management/lxca/lxca_cmms.py validate-modules:doc-missing-type
|
plugins/modules/remote_management/lxca/lxca_cmms.py validate-modules:doc-missing-type
|
||||||
plugins/modules/remote_management/lxca/lxca_nodes.py validate-modules:doc-missing-type
|
plugins/modules/remote_management/lxca/lxca_nodes.py validate-modules:doc-missing-type
|
||||||
plugins/modules/remote_management/manageiq/manageiq_alert_profiles.py validate-modules:parameter-list-no-elements
|
plugins/modules/remote_management/manageiq/manageiq_alert_profiles.py validate-modules:parameter-list-no-elements
|
||||||
|
|
|
@ -319,7 +319,6 @@ plugins/modules/remote_management/foreman/katello.py yamllint:unparsable-with-li
|
||||||
plugins/modules/remote_management/hpilo/hpilo_boot.py validate-modules:parameter-type-not-in-doc
|
plugins/modules/remote_management/hpilo/hpilo_boot.py validate-modules:parameter-type-not-in-doc
|
||||||
plugins/modules/remote_management/hpilo/hpilo_info.py validate-modules:parameter-type-not-in-doc
|
plugins/modules/remote_management/hpilo/hpilo_info.py validate-modules:parameter-type-not-in-doc
|
||||||
plugins/modules/remote_management/hpilo/hponcfg.py validate-modules:parameter-type-not-in-doc
|
plugins/modules/remote_management/hpilo/hponcfg.py validate-modules:parameter-type-not-in-doc
|
||||||
plugins/modules/remote_management/imc/imc_rest.py validate-modules:parameter-type-not-in-doc
|
|
||||||
plugins/modules/remote_management/lxca/lxca_cmms.py validate-modules:doc-missing-type
|
plugins/modules/remote_management/lxca/lxca_cmms.py validate-modules:doc-missing-type
|
||||||
plugins/modules/remote_management/lxca/lxca_nodes.py validate-modules:doc-missing-type
|
plugins/modules/remote_management/lxca/lxca_nodes.py validate-modules:doc-missing-type
|
||||||
plugins/modules/remote_management/manageiq/manageiq_alert_profiles.py validate-modules:parameter-list-no-elements
|
plugins/modules/remote_management/manageiq/manageiq_alert_profiles.py validate-modules:parameter-list-no-elements
|
||||||
|
|
|
@ -308,7 +308,6 @@ plugins/modules/remote_management/foreman/katello.py validate-modules:missing-ma
|
||||||
plugins/modules/remote_management/hpilo/hpilo_boot.py validate-modules:parameter-type-not-in-doc
|
plugins/modules/remote_management/hpilo/hpilo_boot.py validate-modules:parameter-type-not-in-doc
|
||||||
plugins/modules/remote_management/hpilo/hpilo_info.py validate-modules:parameter-type-not-in-doc
|
plugins/modules/remote_management/hpilo/hpilo_info.py validate-modules:parameter-type-not-in-doc
|
||||||
plugins/modules/remote_management/hpilo/hponcfg.py validate-modules:parameter-type-not-in-doc
|
plugins/modules/remote_management/hpilo/hponcfg.py validate-modules:parameter-type-not-in-doc
|
||||||
plugins/modules/remote_management/imc/imc_rest.py validate-modules:parameter-type-not-in-doc
|
|
||||||
plugins/modules/remote_management/lxca/lxca_cmms.py validate-modules:doc-missing-type
|
plugins/modules/remote_management/lxca/lxca_cmms.py validate-modules:doc-missing-type
|
||||||
plugins/modules/remote_management/lxca/lxca_nodes.py validate-modules:doc-missing-type
|
plugins/modules/remote_management/lxca/lxca_nodes.py validate-modules:doc-missing-type
|
||||||
plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules:doc-choices-do-not-match-spec
|
plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules:doc-choices-do-not-match-spec
|
||||||
|
|
Loading…
Reference in a new issue