diff --git a/plugins/modules/aci_rest.py b/plugins/modules/aci_rest.py
index 0e80a874d..851798235 100644
--- a/plugins/modules/aci_rest.py
+++ b/plugins/modules/aci_rest.py
@@ -390,11 +390,11 @@ def main():
elif rest_type == "xml" and HAS_LXML_ETREE:
if content and isinstance(content, dict) and HAS_XMLJSON_COBRA:
# Validate inline YAML/JSON
- payload = etree.tostring(cobra.etree(payload)[0])
+ payload = etree.tostring(cobra.etree(payload)[0], encoding="unicode")
elif payload and isinstance(payload, str):
try:
# Validate XML string
- payload = etree.tostring(etree.fromstring(payload))
+ payload = etree.tostring(etree.fromstring(payload), encoding="unicode")
except Exception as e:
module.fail_json(msg="Failed to parse provided XML payload: %s" % to_text(e), payload=payload)
diff --git a/tests/integration/targets/aci_rest/tasks/error_handling.yml b/tests/integration/targets/aci_rest/tasks/error_handling.yml
index c5c68a391..54922751e 100644
--- a/tests/integration/targets/aci_rest/tasks/error_handling.yml
+++ b/tests/integration/targets/aci_rest/tasks/error_handling.yml
@@ -189,3 +189,42 @@
- "'previous' not in error_on_invalid_object"
- "'sent' not in error_on_invalid_object"
- "'proposed' not in error_on_invalid_object"
+
+# Test case for certificate based error issue: https://github.com/CiscoDevNet/ansible-aci/issues/339
+# Original error was with ospfCtxPol but same behaviour detected for tenant creation thus simplifying the test case
+# Avoiding error: TypeError: must be str, not bytes
+- name: Add user certificate
+ cisco.aci.aci_aaa_user_certificate:
+ host: '{{ aci_hostname }}'
+ username: '{{ aci_username }}'
+ password: '{{ aci_password }}'
+ validate_certs: '{{ aci_validate_certs | default(false) }}'
+ use_ssl: '{{ aci_use_ssl | default(true) }}'
+ use_proxy: '{{ aci_use_proxy | default(true) }}'
+ output_level: '{{ aci_output_level | default("info") }}'
+ aaa_user: '{{ aci_username }}'
+ name: admin
+ certificate: "{{ lookup('file', 'pki/admin.crt') }}"
+ state: present
+ register: cm_add_cert
+
+- name: Create tenant
+ cisco.aci.aci_rest: &tenant
+ host: '{{ aci_hostname }}'
+ username: '{{ aci_username }}'
+ certificate_name: admin
+ private_key: "{{ lookup('file', 'pki/admin.key') }}"
+ validate_certs: '{{ aci_validate_certs | default(false) }}'
+ use_ssl: '{{ aci_use_ssl | default(true) }}'
+ use_proxy: '{{ aci_use_proxy | default(true) }}'
+ output_level: '{{ aci_output_level | default("info") }}'
+ path: /api/mo/uni.xml
+ method: post
+ content:
+
+
+- name: Delete tenant
+ cisco.aci.aci_rest:
+ <<: *tenant
+ content:
+
\ No newline at end of file
diff --git a/tests/integration/targets/aci_rest/tasks/pki/admin.crt b/tests/integration/targets/aci_rest/tasks/pki/admin.crt
new file mode 100644
index 000000000..cfac5531e
--- /dev/null
+++ b/tests/integration/targets/aci_rest/tasks/pki/admin.crt
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICODCCAaGgAwIBAgIJAIt8XMntue0VMA0GCSqGSIb3DQEBCwUAMDQxDjAMBgNV
+BAMMBUFkbWluMRUwEwYDVQQKDAxZb3VyIENvbXBhbnkxCzAJBgNVBAYTAlVTMCAX
+DTE4MDEwOTAwNTk0NFoYDzIxMTcxMjE2MDA1OTQ0WjA0MQ4wDAYDVQQDDAVBZG1p
+bjEVMBMGA1UECgwMWW91ciBDb21wYW55MQswCQYDVQQGEwJVUzCBnzANBgkqhkiG
+9w0BAQEFAAOBjQAwgYkCgYEAohG/7axtt7CbSaMP7r+2mhTKbNgh0Ww36C7Ta14i
+v+VmLyKkQHnXinKGhp6uy3Nug+15a+eIu7CrgpBVMQeCiWfsnwRocKcQJWIYDrWl
+XHxGQn31yYKR6mylE7Dcj3rMFybnyhezr5D8GcP85YRPmwG9H2hO/0Y1FUnWu9Iw
+AQkCAwEAAaNQME4wHQYDVR0OBBYEFD0jLXfpkrU/ChzRvfruRs/fy1VXMB8GA1Ud
+IwQYMBaAFD0jLXfpkrU/ChzRvfruRs/fy1VXMAwGA1UdEwQFMAMBAf8wDQYJKoZI
+hvcNAQELBQADgYEAOmvre+5tgZ0+F3DgsfxNQqLTrGiBgGCIymPkP/cBXXkNuJyl
+3ac7tArHQc7WEA4U2R2rZbEq8FC3UJJm4nUVtCPvEh3G9OhN2xwYev79yt6pIn/l
+KU0Td2OpVyo0eLqjoX5u2G90IBWzhyjFbo+CcKMrSVKj1YOdG0E3OuiJf00=
+-----END CERTIFICATE-----
diff --git a/tests/integration/targets/aci_rest/tasks/pki/admin.key b/tests/integration/targets/aci_rest/tasks/pki/admin.key
new file mode 100644
index 000000000..63bb00cc0
--- /dev/null
+++ b/tests/integration/targets/aci_rest/tasks/pki/admin.key
@@ -0,0 +1,16 @@
+-----BEGIN PRIVATE KEY-----
+MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKIRv+2sbbewm0mj
+D+6/tpoUymzYIdFsN+gu02teIr/lZi8ipEB514pyhoaerstzboPteWvniLuwq4KQ
+VTEHgoln7J8EaHCnECViGA61pVx8RkJ99cmCkepspROw3I96zBcm58oXs6+Q/BnD
+/OWET5sBvR9oTv9GNRVJ1rvSMAEJAgMBAAECgYByu3QO0qF9h7X3JEu0Ld4cKBnB
+giQ2uJC/et7KxIJ/LOvw9GopBthyt27KwG1ntBkJpkTuAaQHkyNns7vLkNB0S0IR
++owVFEcKYq9VCHTaiQU8TDp24gN+yPTrpRuH8YhDVq5SfVdVuTMgHVQdj4ya4VlF
+Gj+a7+ipxtGiLsVGrQJBAM7p0Fm0xmzi+tBOASUAcVrPLcteFIaTBFwfq16dm/ON
+00Khla8Et5kMBttTbqbukl8mxFjBEEBlhQqb6EdQQ0sCQQDIhHx1a9diG7y/4DQA
+4KvR3FCYwP8PBORlSamegzCo+P1OzxiEo0amX7yQMA5UyiP/kUsZrme2JBZgna8S
+p4R7AkEAr7rMhSOPUnMD6V4WgsJ5g1Jp5kqkzBaYoVUUSms5RASz4+cwJVCwTX91
+Y1jcpVIBZmaaY3a0wrx13ajEAa0dOQJBAIpjnb4wqpsEh7VpmJqOdSdGxb1XXfFQ
+sA0T1OQYqQnFppWwqrxIL+d9pZdiA1ITnNqyvUFBNETqDSOrUHwwb2cCQGArE+vu
+ffPUWQ0j+fiK+covFG8NL7H+26NSGB5+Xsn9uwOGLj7K/YT6CbBtr9hJiuWjM1Al
+0V4ltlTuu2mTMaw=
+-----END PRIVATE KEY-----