To_json not working in Ansible 2.19.0rc2

The to_json filter is not working to covert a string to json.
Eg.
Input: “msg”: “{‘Key’: ‘<null_index>’, ‘DeleteOnCompletion’: ‘false’, ‘InstanceID’: ‘DCIM_OSDConcreteJob:1’, ‘JobName’: ‘BootToNetworkISO’, ‘JobStatus’: ‘Failed’, ‘Message’: ‘Unable to locate the ISO image on the network share point.’, ‘MessageArguments’: None, ‘MessageID’: ‘OSD18’, ‘Name’: ‘BootToNetworkISO’, ‘Status’: ‘Failed’, ‘retval’: False, ‘file’: ‘/nfsshare/invalid.iso’}”

task:
- name: Set result_iso_invalid message
ansible.builtin.set_fact:
result_iso_invalid_msg: “{{ msg | to_json }}”

Actual result:
“ansible_facts”: {
“result_iso_invalid_msg”: “"{‘Key’: ‘<null_index>’, ‘DeleteOnCompletion’: ‘false’, ‘InstanceID’: ‘DCIM_OSDConcreteJob:1’, ‘JobName’: ‘BootToNetworkISO’, ‘JobStatus’: ‘Failed’, ‘Message’: ‘Unable to locate the ISO image on the network share point.’, ‘MessageArguments’: None, ‘MessageID’: ‘OSD18’, ‘Name’: ‘BootToNetworkISO’, ‘Status’: ‘Failed’, ‘retval’: False, ‘file’: ‘/nfsshare/invalid.iso’}"”
}

Expected result:
“result_iso_invalid_msg”: {
“DeleteOnCompletion”: “false”,
“InstanceID”: “DCIM_OSDConcreteJob:1”,
“JobName”: “BootToNetworkISO”,
“JobStatus”: “Failed”,
“Key”: “<null_index>”,
“Message”: “Unable to locate the ISO image on the network share point.”,
“MessageArguments”: “None”,
“MessageID”: “OSD18”,
“Name”: “BootToNetworkISO”,
“Status”: “Failed”,
“file”: “/nfsshare/invalid.iso”,
“retval”: false
}

Instead of to_json, when from_yaml is used, this works fine.

Has to_json been deprecated?

It sounds like the string is already JSON (in which case, you’d need to use from_json not to_json).

Can you share an example of specifically what was working before 2.19? The quotation marks in your example input are a little ambiguous to me (not valid json).

Hello @shertel,

Thank you for responding:
This is the set of tasks used:
- name: Boot to Network ISO with nfs share (iso_invalid)
idrac_os_deployment:
share_name: “{{nfs_share_name}}”
iso_image: “invalid.iso”
expose_duration: 5
ignore_errors: true
register: result_iso_invalid

- name: Set result_iso_invalid message
  ansible.builtin.set_fact:
    result_iso_invalid_msg: "{{ result_iso_invalid.msg | from_json }}"

The first task returns:
{
“changed”: false,
“invocation”: {
“module_args”: {
“ca_path”: null,
“expose_duration”: 5,
“idrac_ip”: “xx.xx.xx.xx”,
“idrac_password”: “VALUE_SPECIFIED_IN_NO_LOG_PARAMETER”,
“idrac_port”: 443,
“idrac_user”: “root”,
“iso_image”: “invalid.iso”,
“share_name”: “/nfsshare”,
“share_password”: null,
“share_user”: null,
“timeout”: 30,
“validate_certs”: false
}
},
“msg”: “{‘Key’: ‘<null_index>’, ‘DeleteOnCompletion’: ‘false’, ‘InstanceID’: ‘DCIM_OSDConcreteJob:1’, ‘JobName’: ‘BootToNetworkISO’, ‘JobStatus’: ‘Failed’, ‘Message’: ‘Unable to locate the ISO image on the network share point.’, ‘MessageArguments’: None, ‘MessageID’: ‘OSD18’, ‘Name’: ‘BootToNetworkISO’, ‘Status’: ‘Failed’, ‘retval’: False, ‘file’: ‘/nfsshare/invalid.iso’}”
}

The second task then returns:
{
“changed”: false,
“msg”: “Task failed: Finalization of task args for ‘ansible.builtin.set_fact’ failed: Error while resolving value for ‘result_iso_invalid_msg’: The filter plugin ‘ansible.builtin.from_json’ failed: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)”
}

In 2.18, the first task returned this:
{
“changed”: false,
“invocation”: {
“module_args”: {
“ca_path”: null,
“expose_duration”: 5,
“idrac_ip”: “xx.xx.xx.xx”,
“idrac_password”: “VALUE_SPECIFIED_IN_NO_LOG_PARAMETER”,
“idrac_port”: 443,
“idrac_user”: “root”,
“iso_image”: “invalid.iso”,
“share_name”: “/nfsshare”,
“share_password”: null,
“share_user”: null,
“timeout”: 30,
“validate_certs”: false
}
},
“msg”: {
“DeleteOnCompletion”: “false”,
“InstanceID”: “DCIM_OSDConcreteJob:1”,
“JobName”: “BootToNetworkISO”,
“JobStatus”: “Failed”,
“Key”: “<null_index>”,
“Message”: “Unable to locate the ISO image on the network share point.”,
“MessageArguments”: null,
“MessageID”: “OSD18”,
“Name”: “BootToNetworkISO”,
“Status”: “Failed”,
“file”: “/nfsshare/invalid.iso”,
“retval”: false
}
}

In 2.18, the msg returned was in dict form so the msg keys could be handled without using from_jsom/from_yaml.

Is this change expected?

It looks like msg should be a string: dellemc-openmanage-ansible-modules/plugins/modules/idrac_os_deployment.py at collections · dell/dellemc-openmanage-ansible-modules · GitHub. I wonder why it wasn’t before.

It might be a bug related to the module, not to_json. There’s an open issue here to validate compatibility with 2.19: Validate compatibility with ansible-core 2.19 · Issue #854 · dell/dellemc-openmanage-ansible-modules · GitHub.

@trisha-dell My mistake, I do see auto JSON conversion for string types. We may need to add a porting guide entry if there isn’t already one. I have brought it up internally.

I did some tests, ansible-core 2.19 converts msg to a string if AnsibleModule.fail_json() is called, while 2.18 does not do that. This also does not happen for AnsibleModule.exit_json(). (I’m not sure whether this happens in the module or in the controller code, but -vvv output already shows the stringified value for msg for the task.)