1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

Fixed imc_rest session logout (#1743) (#1868)

* 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:
patchback[bot] 2021-02-21 18:08:56 +01:00 committed by GitHub
parent 58317b37b3
commit aad2b2400e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 47 additions and 41 deletions

View 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).

View file

@ -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__':

View file

@ -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

View file

@ -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

View file

@ -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