Reputation: 7467
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?
Upvotes: 20
Views: 4414
Reputation: 1679
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.
Upvotes: 1
Reputation: 471
jq will save you:
aws secretsmanager get-secret-value --secret-id todobackend/db/credentials-AP57K | jq -r '.SecretString|fromjson|.MYSQL_USER,.MYSQL_PASSWORD'
Upvotes: 4
Reputation: 993
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
Upvotes: -3