-1

Is it possible to accomplish something like this using json_query? I wasn't able to find anything after quite a bit of searching (neither with json_query nor with jmespath). Everything I was able to find assumed that the structure of the dict/json is known (i.e. the depth of the searched-for key is known).

Sample JSON input:

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

I would like to check whether a key Message is present with the value Server is already powered OFF. without assuming the depth of the key/structure of the JSON.

OL83
  • 3
  • 3
  • I don't really understand, you want to check if the message get this value: "Server is already powered OFF" without enter in it ? So if we consider your JSON as ONE message and you have a list of message, you can do this `@[?msg.error.error."@Message.ExtendedInfo"[0].Message == 'Server is already powered OFF.']` if we considert `@` as your current node – bosskay972 Jul 23 '19 at 08:24
  • 1
    @bosskay972 I was looking for a solution which doesn't contain any assumptions about the structure of the input (beyond _maybe_ that there is a top-level key called 'msg'). In the end I found an answer which doesn't use json_query, but which at least still sticks to built-in ansible filters/features (see my answer below). – OL83 Jul 23 '19 at 15:52

2 Answers2

-1

With custom filter_plugins

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

the task below

  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

gives

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

Details

Example of filter dict_flatten from dict_utils below

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('.') }}"

gives

"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
}
Vladimir Botka
  • 58,131
  • 4
  • 32
  • 63
-1

I was able to find the following answer on another site (thanks /u/boscopanda!):

- debug:
    var: js.msg
  when: (js | to_json).find('Server is already powered OFF') != -1
OL83
  • 3
  • 3
  • This does not comply with the conditions: "`to check whether a key Message is present with the value Server is already powered OFF`". – Vladimir Botka Aug 01 '19 at 05:34
  • You are correct @VladimirBotka. I should have phrased my original question slightly differently; that I am looking for a known value, and if necessary when looking for this known value, it's okay to assume the key is known as well. I will mark your answer as accepted. – OL83 Aug 05 '19 at 07:19