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.
|
||||
required: true
|
||||
aliases: [ host, ip ]
|
||||
type: str
|
||||
username:
|
||||
description:
|
||||
- Username used to login to the switch.
|
||||
default: admin
|
||||
aliases: [ user ]
|
||||
type: str
|
||||
password:
|
||||
description:
|
||||
- The password to use for authentication.
|
||||
default: password
|
||||
type: str
|
||||
path:
|
||||
description:
|
||||
- Name of the absolute path of the filename that includes the body
|
||||
of the http request being sent to the Cisco IMC REST API.
|
||||
- Parameter C(path) is mutual exclusive with parameter C(content).
|
||||
aliases: [ 'src', 'config_file' ]
|
||||
type: path
|
||||
content:
|
||||
description:
|
||||
- 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,
|
||||
the Cisco IMC output is subsequently merged.
|
||||
- Parameter C(content) is mutual exclusive with parameter C(path).
|
||||
type: str
|
||||
protocol:
|
||||
description:
|
||||
- Connection protocol to use.
|
||||
default: https
|
||||
choices: [ http, https ]
|
||||
type: str
|
||||
timeout:
|
||||
description:
|
||||
- The socket level timeout in seconds.
|
||||
|
@ -61,6 +67,7 @@ options:
|
|||
If this C(timeout) is reached, the module will fail with a
|
||||
C(Connection failure) indicating that C(The read operation timed out).
|
||||
default: 60
|
||||
type: int
|
||||
validate_certs:
|
||||
description:
|
||||
- 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"/>
|
||||
'''
|
||||
|
||||
import atexit
|
||||
import datetime
|
||||
import itertools
|
||||
import os
|
||||
import traceback
|
||||
from functools import partial
|
||||
|
||||
LXML_ETREE_IMP_ERR = None
|
||||
try:
|
||||
|
@ -317,7 +324,6 @@ def merge(one, two):
|
|||
|
||||
|
||||
def main():
|
||||
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
hostname=dict(type='str', required=True, aliases=['host', 'ip']),
|
||||
|
@ -374,53 +380,54 @@ def main():
|
|||
result.update(imc_response(module, resp.read()))
|
||||
|
||||
# Store cookie for future requests
|
||||
cookie = ''
|
||||
try:
|
||||
cookie = result['aaaLogin']['attributes']['outCookie']
|
||||
except Exception:
|
||||
module.fail_json(msg='Could not find cookie in output', **result)
|
||||
|
||||
# If we would not log out properly, we run out of sessions quickly
|
||||
atexit.register(logout, module, url, cookie, timeout)
|
||||
try:
|
||||
# Prepare request data
|
||||
if content:
|
||||
rawdata = content
|
||||
elif file_exists:
|
||||
with open(path, 'r') as config_object:
|
||||
rawdata = config_object.read()
|
||||
|
||||
# Prepare request data
|
||||
if content:
|
||||
rawdata = content
|
||||
elif file_exists:
|
||||
with open(path, 'r') as config_object:
|
||||
rawdata = config_object.read()
|
||||
# Wrap the XML documents in a <root> element
|
||||
xmldata = lxml.etree.fromstring('<root>%s</root>' % rawdata.replace('\n', ''))
|
||||
|
||||
# Wrap the XML documents in a <root> element
|
||||
xmldata = lxml.etree.fromstring('<root>%s</root>' % rawdata.replace('\n', ''))
|
||||
# Handle each XML document separately in the same session
|
||||
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
|
||||
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)
|
||||
# Perform actual request
|
||||
resp, info = fetch_url(module, url, data=data, method='POST', timeout=timeout)
|
||||
if resp is None or info['status'] != 200:
|
||||
result['elapsed'] = (datetime.datetime.utcnow() - start).seconds
|
||||
module.fail_json(msg='Task failed with error %(status)s: %(msg)s' % info, **result)
|
||||
|
||||
# Perform actual request
|
||||
resp, info = fetch_url(module, url, data=data, method='POST', timeout=timeout)
|
||||
if resp is None or info['status'] != 200:
|
||||
result['elapsed'] = (datetime.datetime.utcnow() - start).seconds
|
||||
module.fail_json(msg='Task failed with error %(status)s: %(msg)s' % info, **result)
|
||||
# Merge results with previous results
|
||||
rawoutput = resp.read()
|
||||
result = merge(result, imc_response(module, rawoutput, rawinput=data))
|
||||
result['response'] = info['msg']
|
||||
result['status'] = info['status']
|
||||
|
||||
# Merge results with previous results
|
||||
rawoutput = resp.read()
|
||||
result = merge(result, imc_response(module, rawoutput, rawinput=data))
|
||||
result['response'] = info['msg']
|
||||
result['status'] = info['status']
|
||||
# Check for any changes
|
||||
# NOTE: Unfortunately IMC API always report status as 'modified'
|
||||
xmloutput = lxml.etree.fromstring(rawoutput)
|
||||
results = xmloutput.xpath('/configConfMo/outConfig/*/@status')
|
||||
result['changed'] = ('modified' in results)
|
||||
|
||||
# Check for any changes
|
||||
# NOTE: Unfortunately IMC API always report status as 'modified'
|
||||
xmloutput = lxml.etree.fromstring(rawoutput)
|
||||
results = xmloutput.xpath('/configConfMo/outConfig/*/@status')
|
||||
result['changed'] = ('modified' in results)
|
||||
|
||||
# Report success
|
||||
result['elapsed'] = (datetime.datetime.utcnow() - start).seconds
|
||||
module.exit_json(**result)
|
||||
# Report success
|
||||
result['elapsed'] = (datetime.datetime.utcnow() - start).seconds
|
||||
module.exit_json(**result)
|
||||
finally:
|
||||
logout(module, url, cookie, timeout)
|
||||
|
||||
|
||||
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_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/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_nodes.py validate-modules:doc-missing-type
|
||||
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_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/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_nodes.py validate-modules:doc-missing-type
|
||||
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_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/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_nodes.py validate-modules:doc-missing-type
|
||||
plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules:doc-choices-do-not-match-spec
|
||||
|
|
Loading…
Reference in a new issue