Allow AnsibleVaultEncryptedUnicode to pass through exec_jsonrpc (#48306)
* Allow AnsibleVaultEncryptedUnicode to pass through exec_jsonrpc * Add changelog
This commit is contained in:
parent
7f3e4910b0
commit
f05979932b
2 changed files with 33 additions and 15 deletions
4
changelogs/fragments/48306-ansible-connection-json
Normal file
4
changelogs/fragments/48306-ansible-connection-json
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
bugfixes:
|
||||
- Use custom JSON encoder in conneciton.py so that ansible objects (AnsibleVaultEncryptedUnicode, for example)
|
||||
can be sent to the persistent connection process
|
|
@ -33,9 +33,11 @@ import socket
|
|||
import struct
|
||||
import traceback
|
||||
import uuid
|
||||
from datetime import date, datetime
|
||||
|
||||
from functools import partial
|
||||
from ansible.module_utils._text import to_bytes, to_text
|
||||
from ansible.module_utils.common._collections_compat import Mapping
|
||||
from ansible.module_utils.six import iteritems
|
||||
from ansible.module_utils.six.moves import cPickle
|
||||
|
||||
|
@ -138,22 +140,8 @@ class Connection(object):
|
|||
'\nSee the socket_path issue catergory in Network Debug and Troubleshooting Guide')
|
||||
|
||||
try:
|
||||
data = json.dumps(req)
|
||||
data = json.dumps(req, cls=AnsibleJSONEncoder)
|
||||
except TypeError as exc:
|
||||
data = req.get('params')
|
||||
|
||||
if isinstance(data, dict):
|
||||
data = data.get('var_options', {})
|
||||
|
||||
for key, value in iteritems(data):
|
||||
try:
|
||||
dummy = json.dumps(value)
|
||||
except TypeError:
|
||||
raise ConnectionError(
|
||||
"Failed to encode some variables as JSON for communication with ansible-connection. "
|
||||
"Please open an issue and mention that the culprit is most likely '%s'" % key
|
||||
)
|
||||
|
||||
raise ConnectionError(
|
||||
"Failed to encode some variables as JSON for communication with ansible-connection. "
|
||||
"The original exception was: %s" % to_text(exc)
|
||||
|
@ -214,3 +202,29 @@ class Connection(object):
|
|||
sf.close()
|
||||
|
||||
return to_text(response, errors='surrogate_or_strict')
|
||||
|
||||
|
||||
# NOTE: This is a modified copy of the class in parsing.ajson to get around not
|
||||
# being able to import that directly, nor some of the type classes
|
||||
class AnsibleJSONEncoder(json.JSONEncoder):
|
||||
'''
|
||||
Simple encoder class to deal with JSON encoding of Ansible internal types
|
||||
'''
|
||||
|
||||
def default(self, o):
|
||||
if type(o).__name__ == 'AnsibleVaultEncryptedUnicode':
|
||||
# vault object
|
||||
value = {'__ansible_vault': to_text(o._ciphertext, errors='surrogate_or_strict', nonstring='strict')}
|
||||
elif type(o).__name__ == 'AnsibleUnsafe':
|
||||
# unsafe object
|
||||
value = {'__ansible_unsafe': to_text(o, errors='surrogate_or_strict', nonstring='strict')}
|
||||
elif isinstance(o, Mapping):
|
||||
# hostvars and other objects
|
||||
value = dict(o)
|
||||
elif isinstance(o, (date, datetime)):
|
||||
# date object
|
||||
value = o.isoformat()
|
||||
else:
|
||||
# use default encoder
|
||||
value = super(AnsibleJSONEncoder, self).default(o)
|
||||
return value
|
||||
|
|
Loading…
Reference in a new issue