25

I'm trying to save the contents of a configmap to a file on my local hard drive. Kubectl supports selecting with JSONPath but I can't find the expression I need to select just the file contents.

The configmap was created using the command

kubectl create configmap my-configmap --from-file=my.configmap.json=my.file.json

When I run

kubectl describe configmap my-configmap

I see the following output:

Name:         my-configmap 
Namespace:    default 
Labels:       <none> 
Annotations:  <none>

Data
==== 
my.file.json:
---- 
{
    "key": "value" 
} 
Events:  <none>

The furthest I've gotten so selecting only the file contents is this:

 kubectl get configmap my-configmap -o jsonpath="{.data}"

Which outputs

map[my.file.json:{
    "key": "value"
}]

The output that I want is

{
  "key": "value"
}

What is the last piece of the JSONPath puzzle?

PeterH
  • 801
  • 2
  • 7
  • 16

2 Answers2

38

There’s an open issue at the Kubernetes GitHub repo with a list of things that needs to be fixed in regards to kubectl (and JSONpath), one of them are issue 16707 jsonpath template output should be json.

Edit:

How about this:

kubectl get cm my-configmap -o jsonpath='{.data.my\.file\.json}'

I just realized i had answered another question related (kind of) to this one. The above command should output what you had in mind!

mikejoh
  • 1,377
  • 11
  • 18
  • 1
    It works, but how would one do if the config map contains more than one key and one wishes to download all the files without knowing the keys in advance? – stackoverflowed Apr 07 '20 at 11:56
2

If you have the ability to use jq, then you can use the following approach to e.g. "list" all config maps by selector, and extract the files:

readarray -d $'\0' -t a < <(kubectl get cm -l grafana=dashboards -o json | jq -cj '.items[] | . as $cm | .data | to_entries[] | [ ($cm.metadata.name + "-" + .key), .value ][]+"\u0000"') ; count=0; while [ $count -lt ${#a[@]} ]; do echo "${a[$((count + 1))]}" > ${a[$count]}; count=$(( $count + 2)); done

This uses kubectl (using -l for a label selector) to get all configmaps. Next it pipes them through jq, creating key value pairs with a null byte termination (the key also contains the name of the configmap, this way I ensured that duplicate file names are not an issue). Then it reads this into a bash array, iterating over the array in steps of 2. Creating files with the content.

This also works file config map values that contain newlines.

ctron
  • 538
  • 3
  • 13