Parse raw string as object using JMESPath
Asked Answered
P

3

20

I have an object that I am parsing using JMESPath where the value of a property is a JSON object encoded as a string. I want to be able to parse that string property as a JSON Object and work with it using JMESPath only (I'm aware I could parse the value using a JSON encoder).

Here is the object:

{
    "ARN": "arn:aws:secretsmanager:us-east-1:xxxxx:secret:todobackend/db/credentials-AP57Kn",
    "Name": "todobackend/db/credentials",
    "VersionId": "c95fae54-e7b4-4c7f-80d6-2c5649f86570",
    "SecretString": "{\"MYSQL_USER\":\"todobackend\",\"MYSQL_PASSWORD\":\"password\"}",
    "VersionStages": [
        "AWSCURRENT"
    ],
    "CreatedDate": 1523276277.046
}

So I want to parse the SecretString property as a JSON object.

Any ideas on whether or not this is possible?

Ptisan answered 14/4, 2018 at 4:9 Comment(3)
I'm afraid JMESPath cannot do that. Literal Expressions are available, but they don't help in your case. You need to request this feature at github.Laodicea
todobackend lol ... why is it always a ToDo app?Myriammyriameter
@Ptisan : Did you got any workaround for this issue ? I am also facing the same issue and don't want to use jqVelmaveloce
C
4

jq will save you:

aws secretsmanager get-secret-value --secret-id todobackend/db/credentials-AP57K | jq -r '.SecretString|fromjson|.MYSQL_USER,.MYSQL_PASSWORD'
Chuu answered 17/1, 2020 at 20:41 Comment(0)
T
1

The correct answer per OP's request to do this strictly in JMESPath is to use to_array():

array to_array(any $arg)

  array - Returns the passed in value.
  number/string/object/boolean - Returns a one element array containing the passed in argument.

The linked page gives examples, but to illustrate what you're looking for:

to_array(SecretString)[0].MYSQL_USER
# => `todobackend`

to_array(SecretString)[0].MYSQL_PASSWORD
# => `password`

For anyone who wants to use this with Azure CLI's JMESPath --query functionality, at least as of version 2.33.1 in May 2022, to_array() does not work as documented and this is a bug in their implementation. Instead of returning an array containing an object, it will return an array containing a string of the node value, without parsing it.

Tachometer answered 16/5, 2022 at 17:30 Comment(1)
This also does not work with the AWS CLI --query optionRevel
B
-3

If you use JMESPath only you can try to do it with your hand with this request:

merge(@,{SecretString: {MYSQL_USER: 'todobackend', MYSQL_PASSWORD: 'password'}})

it's work well. But if you can do it in other language include jmespath like js you can do it this way:

let jsonString = JSON.stringify(JSON.parse("{\"MYSQL_USER\":\"todobackend\",\"MYSQL_PASSWORD\":\"password\"}")).split('"').join("'").replace("{'","{").split(",'").join(",").split("':").join(":");
let mainObject = {
   "ARN": "arn:aws:secretsmanager:us-east-1:xxxxx:secret:todobackend/db/credentials-AP57Kn",
   "Name": "todobackend/db/credentials",
   "VersionId": "c95fae54-e7b4-4c7f-80d6-2c5649f86570",
   "SecretString": "{\"MYSQL_USER\":\"todobackend\",\"MYSQL_PASSWORD\":\"password\"}",
   "VersionStages": [
       "AWSCURRENT"
   ],
   "CreatedDate": 1523276277.046
}
var data = jmespath.search(mainObject, `merge(@,{SecretString:${jsonString}})`)

the split/join permit that the code could be used for another string like this

Bale answered 26/7, 2019 at 8:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.