· 6 years ago · May 05, 2019, 07:24 PM
1#!/bin/bash
2# this script can be used to retrieve secrets from kubernetes and put them into a file
3#
4[[ -n $DEBUG ]] && set -x
5
6# get directory of script
7DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
8
9require_application() {
10 if ! [ -x "$(command -v $1)" ]; then
11 echo "Error: $1 is not installed." >&2
12 exit 1
13 fi
14}
15
16require_applications() {
17 for command in $@
18 do
19 require_application $command
20 done
21}
22
23current_namespace() {
24 local cur_ctx
25 cur_ctx="$(current_context)"
26 ns="$(kubectl config view -o=jsonpath="{.contexts[?(@.name==\"${cur_ctx}\")].context.namespace}")"
27 if [[ -z "${ns}" ]]; then
28 echo "default"
29 else
30 echo "${ns}"
31 fi
32}
33
34current_context() {
35 kubectl config view -o=jsonpath='{.current-context}'
36}
37
38function trim {
39 echo $*
40}
41
42function die {
43 printf "%s\n" "$@" >&2
44 exit 1
45}
46
47NAMESPACE=$(current_namespace)
48
49# if current ns is 'default', make the default namespace be their username
50if [[ "$NAMESPACE" == "default" ]]; then
51 NAMESPACE=$(whoami)
52fi
53
54
55K8S_SVC_ACCOUNT=
56USE_ROOT_TOKEN=
57SECRET_NAME=
58SECRET_KEY=
59OUTPUT_DIRECTORY=
60
61while :; do
62 case $1 in
63 -h|-\?|--help)
64 echo "Usage: $0 [-n <namespace>] [-S <k8s svc account>] [-s <k8s secret name>] [-k <secret key>] [-o <output location>]"
65 echo ""
66 echo " options: "
67 echo " -n the k8s namespace (default: $NAMESPACE)"
68 echo " -S get the K8S service account token for the given kubernetes service account. implies -k 'token'"
69 echo " -s get the k8s secret w/ the given name"
70 echo " -k key within the secret to retrieve (single selection, otherwise gets all keys)"
71 echo " -o output directory."
72 echo ""
73 echo ""
74 echo " Get the kubernetes service account JWT for the auth-service service account"
75 echo " > ./get-k8s-secret.sh -S SVCACCOUNT > svcaccount.jwt"
76 echo ""
77 echo " Get the secret data in vault-client-tls and output it to tmp dir"
78 echo " > ./get-k8s-secret.sh -s MYSECRET -o tmp"
79 exit
80 ;;
81 -S)
82 if [ "$2" ]; then
83 K8S_SVC_ACCOUNT=$2
84 SECRET_KEY=token
85 shift
86 else
87 die "ERROR: -S requires a non-empty option argument"
88 fi
89 ;;
90 -s)
91 if [ "$2" ]; then
92 SECRET_NAME=$2
93 shift
94 else
95 die "ERROR: -s requires a non-empty option argument"
96 fi
97 ;;
98 -k)
99 if [ "$2" ]; then
100 SECRET_KEY=$2
101 shift
102 else
103 die "ERROR: -k requires a non-empty option argument"
104 fi
105 ;;
106 -n)
107 if [ "$2" ]; then
108 NAMESPACE=$2
109 shift
110 else
111 die "ERROR: -n requires a non-empty option argument"
112 fi
113 ;;
114 -o)
115 if [ "$2" ]; then
116 OUTPUT_DIRECTORY=$2
117 shift
118 else
119 die "ERROR: -o requires a non-empty option argument"
120 fi
121 ;;
122 --) # end of all options
123 shift
124 break
125 ;;
126 -?*)
127 die "ERROR: Unknown option: $1"
128 ;;
129 *)
130 break # default case: no more options, break out of loop
131 ;;
132 esac
133 shift
134done
135
136
137NON_OPTION_ARGS=$@
138
139set -eou pipefail
140require_applications base64 kubectl jq
141
142if [[ ! -z "${K8S_SVC_ACCOUNT}" ]]; then
143 echo "Locating secret for service account $K8S_SVC_ACCOUNT..." 1>&2
144 SECRET_NAME=$(kubectl get serviceaccount --namespace ${NAMESPACE} ${K8S_SVC_ACCOUNT} -o jsonpath="{.secrets[*]['name']}")
145fi
146
147
148if [[ ! -z "${SECRET_NAME}" ]]; then
149 SECRET_DATA_JSON=$(kubectl get secret --namespace ${NAMESPACE} ${SECRET_NAME} -o json)
150 for k in $(echo $SECRET_DATA_JSON | jq '.data' | jq -r 'keys[]' ); do
151 OUTPUT_FLAG="false"
152 if [[ ! -z "${SECRET_KEY}" ]]; then
153 if [[ "${SECRET_KEY}" == "${k}" ]]; then
154 OUTPUT_FLAG="true"
155 fi
156 else
157 OUTPUT_FLAG="true"
158 fi
159 if [[ "${OUTPUT_FLAG}" == "true" ]]; then
160 echo "Reading k8s secret ${NAMESPACE}:${SECRET_NAME}:${k} ... " 1>&2
161 if [[ ! -z "${OUTPUT_DIRECTORY}" ]]; then
162 mkdir -p $OUTPUT_DIRECTORY
163 echo $SECRET_DATA_JSON | jq -r '.data["'"${k}"'"]' | base64 --decode > ${OUTPUT_DIRECTORY}/${k}
164 else
165 echo $SECRET_DATA_JSON | jq -r '.data["'"${k}"'"]' | base64 --decode
166 echo
167 fi
168 fi
169 done
170else
171 die "you must ask for a secret. see usage"
172fi