I am trying to use the json_query
filter to parse the desired JSON data.
Ansible playbook task:
- name: Print items in option
ansible.builtin.debug:
msg: "{{ clust_opts | community.general.json_query('defaultReplicaSet.topology.\"dc1-indb-tst1:3306\" | [].option['memberWeight']')' }}"
I have also tried the following in my playbook - which resulted in the same error:
- name: Print items in option
ansible.builtin.debug:
msg: "{{ clust_opts | community.general.json_query('defaultReplicaSet.topology.[?option == 'memberWeight']')' }}"
The error message:
TASK [Print items in option] **************************************************************************************************
fatal: [dc1-indb-tst1]: FAILED! => {"msg": "template error while templating string: expected token ',', got 'memberWeight'. String: {{ clust_opts | json_query('defaultReplicaSet.topology.[?option == 'memberWeight']')' }}"}
JSON to parse data from:
{
"clusterName": "idb_test",
"defaultReplicaSet": {
"globalOptions": [
{
"option": "groupName",
"value": "8f9e6040-F10s-11ec-b244-005056a4645c",
"variable": "group_replication_group_name"
},
{
"option": "memberSslMode",
"value": "REQUIRED",
"variable": "group_replication_ssl_mode"
},
{
"option": "disableClone",
"value": false
}
],
"tags": {
"dc1-indb-tst1:3306": [],
"dc1-indb-tst2:3306": [],
"dc1-indb-tst3:3306": [],
"global": []
},
"topology": {
"dc1-indb-tst1:3306": [
{
"option": "autoRejoinTries",
"value": "3",
"variable": "group_replication_autorejoin_tries"
},
{
"option": "consistency",
"value": "EVENTUAL",
"variable": "group_replication_consistency"
},
{
"option": "exitStateAction",
"value": "READ_ONLY",
"variable": "group_replication_exit_state_action"
},
{
"option": "expelTimeout",
"value": "5",
"variable": "group_replication_member_expel_timeout"
},
{
"option": "groupSeeds",
"value": "dc1-indb-tst2:33061,dc1-indb-tst3:33061",
"variable": "group_replication_group_seeds"
},
{
"option": "ipAllowlist",
"value": "AUTOMATIC",
"variable": "group_replication_ip_allowlist"
},
{
"option": "ipWhitelist",
"value": "AUTOMATIC",
"variable": "group_replication_ip_whitelist"
},
{
"option": "localAddress",
"value": "dc1-indb-tst1:33061",
"variable": "group_replication_local_address"
},
{
"option": "memberWeight",
"value": "50",
"variable": "group_replication_member_weight"
},
{
"value": "WRITESET",
"variable": "binlog_transaction_dependency_tracking"
},
{
"value": "LOGICAL_CLOCK",
"variable": "replica_parallel_type"
},
{
"value": "4",
"variable": "replica_parallel_workers"
},
{
"value": "ON",
"variable": "replica_preserve_commit_order"
},
{
"value": "XXHASH64",
"variable": "transaction_write_set_extraction"
}
],
"dc1-indb-tst2:3306": [
{
"option": "autoRejoinTries",
"value": "3",
"variable": "group_replication_autorejoin_tries"
},
{
"option": "consistency",
"value": "EVENTUAL",
"variable": "group_replication_consistency"
},
{
"option": "exitStateAction",
"value": "READ_ONLY",
"variable": "group_replication_exit_state_action"
},
{
"option": "expelTimeout",
"value": "5",
"variable": "group_replication_member_expel_timeout"
},
{
"option": "groupSeeds",
"value": "dc1-indb-tst1:33061,dc1-indb-tst3:33061",
"variable": "group_replication_group_seeds"
},
{
"option": "ipAllowlist",
"value": "AUTOMATIC",
"variable": "group_replication_ip_allowlist"
},
{
"option": "ipWhitelist",
"value": "AUTOMATIC",
"variable": "group_replication_ip_whitelist"
},
{
"option": "localAddress",
"value": "dc1-indb-tst2:33061",
"variable": "group_replication_local_address"
},
{
"option": "memberWeight",
"value": "50",
"variable": "group_replication_member_weight"
},
{
"value": "WRITESET",
"variable": "binlog_transaction_dependency_tracking"
},
{
"value": "LOGICAL_CLOCK",
"variable": "replica_parallel_type"
},
{
"value": "4",
"variable": "replica_parallel_workers"
},
{
"value": "ON",
"variable": "replica_preserve_commit_order"
},
{
"value": "XXHASH64",
"variable": "transaction_write_set_extraction"
}
],
"dc1-indb-tst3:3306": [
{
"option": "autoRejoinTries",
"value": "3",
"variable": "group_replication_autorejoin_tries"
},
{
"option": "consistency",
"value": "EVENTUAL",
"variable": "group_replication_consistency"
},
{
"option": "exitStateAction",
"value": "READ_ONLY",
"variable": "group_replication_exit_state_action"
},
{
"option": "expelTimeout",
"value": "5",
"variable": "group_replication_member_expel_timeout"
},
{
"option": "groupSeeds",
"value": "dc1-indb-tst1:33061,dc1-indb-tst2:33061",
"variable": "group_replication_group_seeds"
},
{
"option": "ipAllowlist",
"value": "AUTOMATIC",
"variable": "group_replication_ip_allowlist"
},
{
"option": "ipWhitelist",
"value": "AUTOMATIC",
"variable": "group_replication_ip_whitelist"
},
{
"option": "localAddress",
"value": "dc1-indb-tst3:33061",
"variable": "group_replication_local_address"
},
{
"option": "memberWeight",
"value": "50",
"variable": "group_replication_member_weight"
},
{
"value": "WRITESET",
"variable": "binlog_transaction_dependency_tracking"
},
{
"value": "LOGICAL_CLOCK",
"variable": "replica_parallel_type"
},
{
"value": "4",
"variable": "replica_parallel_workers"
},
{
"value": "ON",
"variable": "replica_preserve_commit_order"
},
{
"value": "XXHASH64",
"variable": "transaction_write_set_extraction"
}
]
}
}
}
The end goal is to be able to look for the data in the option
fields and return the value
associated with it.
So, in my example I want to find the memberWeight
for a specific system and return the value
.
I am looking at dc1-indb-tst1:3306
, specifically, for memberWeight
which should return 50
- but I am getting the above error instead.
A working debug task, in this use case would be:
- ansible.builtin.debug:
msg: >-
{{
clust_opts | community.general.json_query('
defaultReplicaSet
.topology
."dc1-indb-tst1:3306"[?
option == `memberWeight`
].value | [0]
')
}}
Which gives:
ok: [localhost] =>
msg: '50'
The error you are getting is because you forgot to escape the single quote '
in your JMESPath query.
An idea to ease your own life with quote escaping would be to use the YAML folded style block notation:
- ansible.builtin.debug:
msg: >-
I don't have to escape single (')
nor double (") quote in this string,
it is delimited only by the fact that it is further indented
than the block where the folded block starts.
Now, for your JMESPath query, you have part of the solution in both of them so, if you mix them both, you get nearly what you expect.
A little word of explanation, properties of map are queried with the dot .
notation. While elements of an array are queried via the square bracket notation []
.
So from your first attempts, this part is correct:
defaultReplicaSet.topology."dc1-indb-tst1:3306"
And in the second one, this part is correct:
[?option == 'memberWeight']
Together you have
defaultReplicaSet
.topology
."dc1-indb-tst1:3306"[?
option == 'memberWeight'
]
Which gives you the whole object:
[
{
"option": "memberWeight",
"value": "50",
"variable": "group_replication_member_weight"
}
]
Now you just need to query the value, and return the first result of it, so adding:
.value | [0]
The pipe expression is there to stop the projection, more on that can be found in the relevant documentation.
So, your query ends up being:
defaultReplicaSet
.topology
."dc1-indb-tst1:3306"[?
option == `memberWeight`
].value | [0]
Please mind: I swapped single quote '
for backticks here `
, as proposed in one of the notes of the Ansible documentation regarding json_query
:
In the example above, quoting literals using backticks avoids escaping quotes and maintains readability.
Indeed, in JMESPath, they both represent literals. There is a slight difference between the two, where the single quote is a literal expression and the backpacks represent a raw literal string, but in the case at hand, is will act the same.
And your debug
task should be:
- ansible.builtin.debug:
msg: >-
{{
clust_opts | community.general.json_query('
defaultReplicaSet
.topology
."dc1-indb-tst1:3306"[?
option == `memberWeight`
].value | [0]
')
}}
Which will yield:
TASK [ansible.builtin.debug] *********************************************
ok: [localhost] =>
msg: '50'