Skip to content

jmespath

"JMESPath is a query language for JSON." - http://jmespath.org

Examples

Quotes matter

Something that is completely absent from the jmespath tutorial is that quotes matter. You have to quote strings with single quotes, which means you have to quote the python function call with double quotes.

>>> print(l)
[{"name": "foo-name", "age": "foo-age"}, {"name": "bar-name", "age": "bar-age"}]
>>> print(yaml.dump(l))
- age: foo-age
  name: foo-name
- age: bar-age
  name: bar-name

>>> jmespath.search("[?name == 'bar-name']", l)
[{'name': 'bar-name', 'age': 'bar-age'}]
>>> jmespath.search('[?name == "bar-name"]', l)
[]

However, you also need to use double-quotes to surround keys that have dots in them.

>>> l = [{"name": "foo-name", "the.age": "foo-the.age"}, {"name": "bar-name", "the.age": "bar-the.age"}]
>>> l[1]['the.age']
'bar-the.age'
>>> jmespath.search("[?'the.age' == 'bar-the.age']", l)
[]
>>> jmespath.search('[?"the.age" == "bar-the.age"]', l)
[]
>>> jmespath.search("[?\"the.age\" == 'bar-the.age']", l)
[{'name': 'bar-name', 'the.age': 'bar-the.age'}]

There are so many ways to silently fail here, it's really hard to trust jmespath to do the right thing. 😞

A regex to validate that you are only using double-quotes in python jmespath.search is /jmespath\.search\(('|\"\"\")/. See https://regex101.com/r/Jtars6/1

Grab some kubernetes fields and remap them to be less deep

kubectl get po --all-namespaces -o json |
jp "items[*].{name: metadata.name, namespace: metadata.namespace, imagePullSecrets: spec.imagePullSecrets[*].name}"

Or filter only to non-default namespace where imagePullSecrets is populated

kubectl get po --all-namespaces -o json |
jp "items[?metadata.namespace != 'default' && spec.imagePullSecrets != null].{name: metadata.name, namespace: metadata.namespace, imagePullSecrets: spec.imagePullSecrets[*].name}"