-
Notifications
You must be signed in to change notification settings - Fork 4
/
httokensh
executable file
·172 lines (151 loc) · 4.03 KB
/
httokensh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#!/bin/bash
#
# Run htgettoken and then start a shell command and keep the access
# token updated for as long as the command runs. See httokensh(1).
#
# Written by Dave Dykstra August 2023
usage()
{
echo "Usage: httokensh [-h] [htgettokenoptions] -- [command]"
echo
echo "Runs htgettoken with given options, starts the command, and runs"
echo "htgettoken again in the background as needed to renew the token"
echo "until the command exits."
echo
echo "Options:"
echo " -h, --help show this help message and exit"
echo
echo "command defaults to \$SHELL"
exit 1
} >&2
if [ $# = 0 ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
usage
fi
HTGETOKENARGS=()
COMMANDARGS=()
GOTSEP=false
MINSECS=60
GOTVERBOSE=false
GOTOUTFILE=false
GOTVTFILE=false
GOTVTTTL=false
for ARG; do
if $GOTSEP; then
COMMANDARGS+=("$ARG")
elif [ "$ARG" = "--" ]; then
GOTSEP=true
else
HTGETTOKENARGS+=("$ARG")
case "$ARG" in
--minsecs=*)
MINSECS="${ARG/--minsecs=/}"
;;
-v|--verbose)
GOTVERBOSE=true
;;
-o|--outfile=*)
GOTOUTFILE=true
;;
--vaulttokenfile=*)
GOTVTFILE=true
;;
--vaulttokenttl=*|--vaulttokenminttl=*)
GOTVTTTL=true
;;
esac
fi
done
if ! $GOTSEP; then
echo "No -- separator given" >&2
usage
fi
if [ ${#HTGETTOKENARGS[@]} = 0 ]; then
echo "No htgettoken options given" >&2
usage
fi
if [ ${#COMMANDARGS[@]} = 0 ]; then
COMMANDARGS=("$SHELL")
fi
if [ -z "$BEARER_TOKEN_FILE" ] && ! $GOTOUTFILE; then
BTFILE="bt_u$(id -u).sh-$$"
if [ -n "$XDG_RUNTIME_DIR" ]; then
BEARER_TOKEN_FILE=$XDG_RUNTIME_DIR/$BTFILE
else
BEARER_TOKEN_FILE=/tmp/$BTFILE
fi
export BEARER_TOKEN_FILE
fi
if ! $GOTVTFILE; then
ARGHASH="$(echo "${HTGETTOKENARGS[@]}"|md5sum -)"
ARGHASH="${ARGHASH%% *}"
VTFILE="/tmp/vt_u$(id -u).sh-$ARGHASH"
HTGETTOKENARGS+=("--vaulttokenfile=$VTFILE")
fi
if ! $GOTVTTTL; then
HTGETTOKENARGS+=("--vaulttokenminttl=6d")
fi
gettoken()
{
htgettoken "${HTGETTOKENARGS[@]}"
RETVAL="$?"
if [ $RETVAL != 0 ]; then
echo "htgettoken failed, $1" >&2
exit $RETVAL
fi
TOKENJSON="$(htdecodetoken)"
RETVAL="$?"
if [ $RETVAL != 0 ]; then
echo "htdecodetoken failed, $1" >&2
exit $RETVAL
fi
EXP="$(echo $TOKENJSON|jq .exp)"
NOW="$(date +%s)"
let SLEEPSECS="$EXP - $MINSECS - $NOW + 2"
if [ "$SLEEPSECS" -lt $2 ]; then
echo "Calculated renewal time of $SLEEPSECS seconds is less than $2, $1"
exit 1
fi
}
# The first time it is possible to get a cached token that is barely
# beyond the minsecs, so reduce the minimum to just 1 second
gettoken "not running command" 1
# make sure the logged info is verbose for easier diagnosis
if ! $GOTVERBOSE; then
HTGETTOKENARGS+=("-v")
fi
# prevent attempts to get new vault token in background
HTGETTOKENARGS+=("--nooidc" "--nokerberos" "--nossh")
# enable job control so background processes get their own process group
set -m
echo "Renewal log is at \$BEARER_TOKEN_FILE.log"
{
# keep a copy of $PPID because it will change to 1 if parent dies
PARENTPID=$PPID
echo htgettoken args are "${HTGETTOKENARGS[@]}"
while true; do
date
echo "Renewal scheduled in $SLEEPSECS seconds"
sleep $SLEEPSECS
date
if kill -0 $PARENTPID; then
gettoken "exiting" 60
else
echo "Parent process $PARENTPID not running, exiting"
exit 0
fi
done
} >$BEARER_TOKEN_FILE.log 2>&1 &
BACKGROUND_PID=$!
cleanup()
{
if kill -- -$BACKGROUND_PID 2>/dev/null; then
wait 2>/dev/null
rm -f $BEARER_TOKEN_FILE $BEARER_TOKEN_FILE.log
else
echo >&2
echo "Renewal background process failed, see $BEARER_TOKEN_FILE.log" >&2
exit 1
fi
}
trap cleanup 0
"${COMMANDARGS[@]}"