Kubernetes: 快速展開 Secrets 的資料 (jq)



前言

日常查找 config 時,不時都要去 pipe secret 到 base64 -d 去解碼,像是

1
2
kubectl get secret -n default my-secret \
    -ojsonpath='{.data.config.password}' | base64 -d

如果是輸入帳密等,例如 minio,操作起來就有點麻煩。
剛好常用 jq 來幫助 Kubernetes 的 parsing,也一起記錄。



說明

function 直接處理

直接宣告這個 function,

1
2
3
expand-secrets () {
    cat - | jq -r '.data | to_entries | map(if .value | type == "string" then .value |= @base64d else . end) | map("\(.key): \(.value)") | .[]'
}

之後就可以直接 pipe | 來使用:

1
kubectl get secret -n default my-secret -ojson | expand-secrets

由於裡面會把所有 .data 底下的 key-value pair 都展開,所以一口氣就可以拿到全部解碼後的字串。

像這樣

1
2
3
4
kubectl -n minio get secret connetion-info -o json | expand-secrets
DEMO_ENDPOINT: http://minio.minio:9000
DEMO_SECRET_ID: my-access-key
DEMO_SECRET_KEY: my-secret-key

詳細說明

縮排一下,方便識別:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
expand-secrets () {
    cat - \
        | jq -r '
            .data 
                | to_entries 
                | map(if .value | type == "string" then .value |= @base64d else . end) 
                | map("\(.key): \(.value)") 
                | .[]
        '
}
  • cat -:在 function 裡面讀取 stdin 的資料;
    這是為了讓 function 可以用 pipe | 操作,比較方便。

jq 中的

  1. to_entries:將資料轉換成 key-value pair,例如
1
{ "password": "123" }

會變成

1
2
3
4
5
6
[
  {
    "key": "password",
    "value": "123"
  }
]

這是因為想要把該 secret 中所有的 key 都遍歷一遍,然後才能分別 base64 decode。

  1. map(if .value | type == "string" then .value |= @base64d else . end)
    這是判斷如果 value 欄位的值是字串的話,就用 base64 decode 處理。

  2. map("\(.key): \(.value)")
    key value pair 轉回成 key: value 的格式。
    跳脫括號這部分 \(.key) 稱為 jq interpolation,可以參考
    用 Github CLI - gh 來查找 action,並且 rerun 這篇的範例用法。

  3. .[]:最後把 Array 裡的元素全部取出;如果有 \n 換行符號,印出時會自動換行。




REF

  1. https://stackoverflow.com/questions/40910296/decoding-json-and-a-base64-encoded-value-in-a-shell-script
  2. https://stackoverflow.com/questions/20181467/how-to-map-an-object-to-arrays-so-it-can-be-converted-to-csv

主題 StackJimmy 設計