【问题标题】:Ansible: Looking for a known key with a known value at an arbitrary depth using json_query?Ansible:使用 json_query 在任意深度寻找具有已知值的已知键?
【发布时间】:2019-07-23 05:26:58
【问题描述】:

是否可以使用json_query 完成类似的操作?经过大量搜索后,我找不到任何东西(json_queryjmespath 都没有)。我能找到的所有东西都假设dict/json 的结构是已知的(即搜索键的深度是已知的)。

示例 JSON 输入:

{
  "changed": false,
  "msg": {
    "Data": {
      "Message": "returned status code doesn't match with the expected success code",
      "Status": "Failed",
      "StatusCode": 409
    },
    "Message": "none",
    "Status": "Failed",
    "StatusCode": 409,
    "error": {
      "error": {
        "@Message.ExtendedInfo": [
          {
            "Message": "Server is already powered OFF.",
            "MessageArgs": [

            ],
            "MessageArgs@odata.count": 0,
            "MessageId": "IDRAC.1.6.PSU502",
            "RelatedProperties": [

            ],
            "RelatedProperties@odata.count": 0,
            "Resolution": "No response action is required.",
            "Severity": "Informational"
          }
        ],
        "code": "Base.1.0.GeneralError",
        "message": "A general error has occurred. See ExtendedInfo for more information"
      }
    },
    "retval": true
  }
}

我想检查一个键 Message 是否存在值 Server is already power OFF. 而不假设 JSON 的键/结构的深度。

【问题讨论】:

  • 我不太明白,你想检查消息是否得到这个值:“服务器已关闭电源”而不输入?因此,如果我们将您的 JSON 视为一条消息并且您有一个消息列表,那么如果我们将 @ 视为您的当前节点,您可以这样做 @[?msg.error.error."@Message.ExtendedInfo"[0].Message == 'Server is already powered OFF.']
  • @bosskay972 我正在寻找一个不包含任何关于输入结构的假设的解决方案(除了 也许 有一个名为 'msg 的顶级键')。最后,我找到了一个不使用 json_query 的答案,但至少仍然坚持内置的 ansible 过滤器/功能(请参阅下面的答案)。

标签: ansible ansible-2.x jmespath json-query


【解决方案1】:

带有自定义filter_plugins

$ ls -1 filter_plugins/*.py
filter_plugins/dict_utils.py
filter_plugins/list_methods.py

下面的任务

  vars:
    my_key: Message
    my_value: Server is already powered OFF
  tasks:
    - debug:
        msg: "{{ item.key }}: {{ item.value is search(my_value)|
                                 ternary(my_value, 'NOT FOUND') }}"
      loop: "{{ input|dict_flatten|dict2items }}"
      when: item.key.split('.')|list_reverse|first == my_key

给予

"msg": "msg.Data.Message: NOT FOUND"
"msg": "msg.error.error.@Message.ExtendedInfo.0.Message: Server is already powered OFF"
"msg": "msg.Message: NOT FOUND"

详情

过滤器示例 dict_flatten 来自下面的dict_utils

vars:
dict4: {
      "a":{
        "r": 1,
        "s": 2,
        "t": 3
        },
      "b":{
        "u": 1,
        "v": {
            "x": 1,
            "y": 2,
            "z": [ 3, 4, 5 ]
          },
        "w": 3
        }
      }
tasks:
  - debug:
      var: dict4_flatten
    vars:
      dict4_flatten: "{{ dict4|dict_flatten('.') }}"

给予

"dict4_flatten": {
    "a.r": 1, 
    "a.s": 2, 
    "a.t": 3, 
    "b.u": 1, 
    "b.v.x": 1, 
    "b.v.y": 2, 
    "b.v.z.0": 3, 
    "b.v.z.1": 4, 
    "b.v.z.2": 5, 
    "b.w": 3
}

【讨论】:

    【解决方案2】:

    我能够在另一个网站上找到以下答案(感谢 /u/boscopanda!):

    - debug:
        var: js.msg
      when: (js | to_json).find('Server is already powered OFF') != -1
    

    【讨论】:

    • 这不符合条件:“to check whether a key Message is present with the value Server is already powered OFF”。
    • 你是对的@VladimirBotka。我应该对我原来的问题稍有不同的措辞;我正在寻找一个已知值,如果有必要在寻找这个已知值时,可以假设密钥也是已知的。我会将您的答案标记为已接受。
    猜你喜欢
    • 2021-01-18
    • 1970-01-01
    • 2018-12-18
    • 2011-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多