diff --git a/changelogs/fragments/iosxr_netconf_config_commit_fix.yaml b/changelogs/fragments/iosxr_netconf_config_commit_fix.yaml new file mode 100644 index 00000000000..429f3c5c595 --- /dev/null +++ b/changelogs/fragments/iosxr_netconf_config_commit_fix.yaml @@ -0,0 +1,2 @@ +bugfixes: +- Confirmed commit fails with TypeError in IOS XR netconf plugin (https://github.com/ansible-collections/cisco.iosxr/issues/74) diff --git a/lib/ansible/plugins/netconf/__init__.py b/lib/ansible/plugins/netconf/__init__.py index b181f37696a..529cc260675 100644 --- a/lib/ansible/plugins/netconf/__init__.py +++ b/lib/ansible/plugins/netconf/__init__.py @@ -24,7 +24,7 @@ from functools import wraps from ansible.errors import AnsibleError from ansible.plugins import AnsiblePlugin -from ansible.module_utils._text import to_native +from ansible.module_utils._text import to_native, to_text from ansible.module_utils.basic import missing_required_lib try: @@ -269,6 +269,7 @@ class NetconfBase(AnsiblePlugin): and set a token on the ongoing confirmed commit :return: Returns xml string containing the RPC response received from remote host """ + timeout = to_text(timeout, errors='surrogate_or_strict') resp = self.m.commit(confirmed=confirmed, timeout=timeout, persist=persist) return resp.data_xml if hasattr(resp, 'data_xml') else resp.xml diff --git a/lib/ansible/plugins/netconf/iosxr.py b/lib/ansible/plugins/netconf/iosxr.py index 228c5828ab1..2bcbfbf8eea 100644 --- a/lib/ansible/plugins/netconf/iosxr.py +++ b/lib/ansible/plugins/netconf/iosxr.py @@ -42,7 +42,7 @@ import json import re import collections -from ansible.module_utils._text import to_native +from ansible.module_utils._text import to_native, to_text from ansible.module_utils.network.common.netconf import remove_namespaces from ansible.module_utils.network.iosxr.iosxr import build_xml, etree_find from ansible.errors import AnsibleConnectionFailure @@ -181,6 +181,8 @@ class Netconf(NetconfBase): raise Exception(to_xml(exc.xml)) def commit(self, confirmed=False, timeout=None, persist=None, remove_ns=False): + timeout = to_text(timeout, errors='surrogate_or_strict') + try: resp = self.m.commit(confirmed=confirmed, timeout=timeout, persist=persist) if remove_ns: diff --git a/test/integration/targets/netconf_config/tests/iosxr/basic.yaml b/test/integration/targets/netconf_config/tests/iosxr/basic.yaml index c2cd38974de..47af1306ec1 100644 --- a/test/integration/targets/netconf_config/tests/iosxr/basic.yaml +++ b/test/integration/targets/netconf_config/tests/iosxr/basic.yaml @@ -11,4 +11,24 @@ that: - "'backup_path' in result" +- name: test confirm commit + netconf_config: + target: "candidate" + error_option: "rollback-on-error" + commit: yes + confirm: 10 + default_operation: "merge" + content: | + + + true + + + register: result + ignore_errors: True + +- assert: + that: + - "'failed' not in result" + - debug: msg="END netconf_config iosxr/basic.yaml on connection={{ ansible_connection }}"