json_query筛选器错误 - 模板字符串时的模板错误:预期的令牌','



我正在尝试使用json_query过滤器来解析所需的JSON数据。

可见剧本任务:

- name: Print items in option
ansible.builtin.debug:
msg: "{{ clust_opts | community.general.json_query('defaultReplicaSet.topology."dc1-indb-tst1:3306" | [].option['memberWeight']')' }}"

我也在我的剧本中尝试了以下操作-导致相同的错误:

- name: Print items in option
ansible.builtin.debug:
msg: "{{ clust_opts | community.general.json_query('defaultReplicaSet.topology.[?option == 'memberWeight']')' }}"

错误信息:

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解析来自:

{
"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"
}
]
}
}
}

最终目标是能够查找option字段中的数据并返回与之相关的value

因此,在我的示例中,我想找到特定系统的memberWeight并返回value

我正在查看dc1-indb-tst1:3306,特别是memberWeight,它应该返回50-但我得到了上述错误。

TL;DR;

一个正在工作的调试任务,在这个用例中应该是:

- ansible.builtin.debug:
msg: >-
{{
clust_opts | community.general.json_query('
defaultReplicaSet
.topology
."dc1-indb-tst1:3306"[?
option == `memberWeight`
].value | [0]
')
}}

给了:

ok: [localhost] => 
msg: '50'

您得到的错误是因为您忘记在JMESPath查询中转义单引号'

一个简化你自己的引号转义的想法是使用YAML折叠样式块符号:

- 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.

现在,对于您的JMESPath查询,您在它们中都有部分解决方案,因此,如果您将它们混合在一起,您将得到您所期望的。

稍加说明,map的属性是用点.表示法查询的。而数组的元素是通过方括号[]来查询的。

所以从你的第一次尝试来看,这部分是正确的:

defaultReplicaSet.topology."dc1-indb-tst1:3306"

在第二句中,这部分是正确的:

[?option == 'memberWeight']

你有

defaultReplicaSet
.topology
."dc1-indb-tst1:3306"[?
option == 'memberWeight'
]

给出整个对象:

[
{
"option": "memberWeight",
"value": "50",
"variable": "group_replication_member_weight"
}
]

现在您只需要查询该值,并返回它的第一个结果,因此添加:

.value | [0]

管道表达式是用来停止投影的,更多信息可以在相关文档中找到。

所以,你的查询结果是:

defaultReplicaSet
.topology
."dc1-indb-tst1:3306"[?
option == `memberWeight`
].value | [0]

请介意:我把单引号'换成了这里的反引号`,正如在关于json_query的Ansible文档的一个注释中提出的那样:

在上面的例子中,使用反引号引用字面量可以避免转义引号并保持可读性。

实际上,在JMESPath中,它们都表示字面量。这两者之间有一个细微的区别,单引号是一个文字表达式,而背包代表一个原始的文字字符串,但在手边的情况下,它的作用是一样的。

你的debug任务应该是:

- ansible.builtin.debug:
msg: >-
{{
clust_opts | community.general.json_query('
defaultReplicaSet
.topology
."dc1-indb-tst1:3306"[?
option == `memberWeight`
].value | [0]
')
}}

这将产生:

TASK [ansible.builtin.debug] *********************************************
ok: [localhost] => 
msg: '50'

最新更新