-
Notifications
You must be signed in to change notification settings - Fork 4
/
bash-functions
172 lines (154 loc) · 5.49 KB
/
bash-functions
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
# shellcheck disable=SC2119,SC2120
#
# Bash functions for chcreds
#
# This file should be sourced from your ~/.bashrc file like:
# . ~/projects/openstack-bash-creds-helper/bash-functions
#
# Andy Botting <[email protected]>
# Jacob Aharon <[email protected]>
CHCRED_FILE="${CHCRED_FILE:-$HOME/.chcred}"
KEYSTONE_AUTH_VERSION="v3"
function creds() {
export OS_PROJECT_DOMAIN_NAME=Default
export OS_USER_DOMAIN_NAME=Default
export OS_IDENTITY_API_VERSION=3
export OS_AUTH_TYPE=password
if [ -f "$CHCRED_FILE" ]; then
cred=$(cat "$CHCRED_FILE")
export OS_CRED=${cred%.openrc}
# shellcheck source=openstack_creds
. <(pass "$cred")
else
chcreds
fi
}
function chcreds() {
if builtin type -P fzf &> /dev/null; then
# Using fzf (if installed) for cred chooser
rmcreds && openstack_creds "$1" && creds
else
# Regular choice list
tput smcup && tput cup 0 0 && rmcreds && \
openstack_creds "$1" && creds && tput rmcup
fi
}
function creds_token() {
if [ -f "$CHCRED_FILE" ]; then
cred=$(cat "$CHCRED_FILE")
export OS_CRED=${cred%.openrc}
if result=$(__get_token "$(pass "$cred")"); then
token_envs=$result
else
return 1
fi
# shellcheck source=/dev/null
. <(echo "$token_envs")
else
chcreds_token
fi
}
function __get_token(){
original_envs=$(echo "$@" | awk '{print $2}')
chcreds_totp="false"
cmd=""
for env_var in $original_envs
do
# add single qoutes around the variables values
# otherwise special chars (like ")") in the password will bork out the script
escaped_env=$(awk -F= '{print $1"=\x27"$2"\x27"}' <<< "$env_var")
cmd+="${escaped_env} "
# if CHCREDS_MFA_TOTP_PASS is true, we need to get the totp
if [[ $env_var == *"CHCREDS_MFA_TOTP_PASS=true"* ]]; then
chcreds_totp="true"
echo "Enter your TOTP code: " > /dev/stderr
read -r totp_code
cmd+="TOTP_CODE=${totp_code} "
fi
# parse OS_AUTH_URL and add version number if it is missing
if [[ $env_var == *"OS_AUTH_URL"* ]]; then
auth_url=$(awk -F= '/OS_AUTH_URL/{print $2}' <<< "$env_var")
# conform the url to not end with '/' if it already have the version number, for easier parsing
if [[ $auth_url == *"/${KEYSTONE_AUTH_VERSION}/" ]]; then
auth_url=${auth_url%?}
fi
if [[ $auth_url != *"/${KEYSTONE_AUTH_VERSION}" ]]; then
if [[ $auth_url == *"/" ]]; then
auth_url=${auth_url}"${KEYSTONE_AUTH_VERSION}"
else
auth_url=${auth_url}"/${KEYSTONE_AUTH_VERSION}"
fi
fi
auth_url=${auth_url}"/auth/tokens"
fi
done
# Just password is the default
methods_data="\\\"methods\\\": [\\\"password\\\"],"
password_data="\\\"password\\\": {
\\\"user\\\": {
\\\"name\\\": \\\"\${OS_USERNAME}\\\",
\\\"domain\\\": { \\\"name\\\": \\\"\${OS_USER_DOMAIN_NAME}\\\" },
\\\"password\\\": \\\"\${OS_PASSWORD}\\\"
}
},"
totp_data="\\\"totp\\\": {}"
# Set the curl request for the token (password only / password and totp)
if [[ "${chcreds_totp}" == "true" ]]; then
methods_data="\\\"methods\\\": [\\\"password\\\",\\\"totp\\\"],"
totp_data="\\\"totp\\\": {
\\\"user\\\": {
\\\"name\\\": \\\"\${OS_USERNAME}\\\",
\\\"domain\\\": { \\\"name\\\": \\\"\${OS_USER_DOMAIN_NAME}\\\" },
\\\"passcode\\\": \\\"\${TOTP_CODE}\\\"
}
}"
fi
curl_data="\"
{ \\\"auth\\\": {
\\\"identity\\\": {
${methods_data}
${password_data}
${totp_data}
}
}
}\""
cmd+="; curl -i --silent -X POST -H \"Content-Type: application/json\" -d ${curl_data} \"${auth_url}\""
if result=$(bash -c "${cmd}"); then
if ! x_subject_token=$(echo "${result}" | grep -i "x-subject-token: " ); then
echo "$result" > /dev/stderr
return 1
else
token=$(awk -v RS='\r\n' '{printf $2}' <<< "$x_subject_token")
fi
else
echo "Curl failed!" > /dev/stderr
return 1
fi
token_envs=$(grep -v -w -e "CHCREDS_MFA_TOTP_PASS" -e "OS_USERNAME" -e "OS_PASSWORD" -e "OS_USER_DOMAIN_NAME"<<< "$@")
token_envs+=" export OS_AUTH_TYPE=token export OS_TOKEN=${token}"
echo "$token_envs"
}
function chcreds_token() {
if builtin type -P fzf &> /dev/null; then
# Using fzf (if installed) for cred chooser
rmcreds && openstack_creds "$1" && creds_token
else
# Regular choice list
tput smcup && tput cup 0 0 && rmcreds && \
openstack_creds "$1" && creds_token && tput rmcup
fi
}
function rmcreds() {
for v in $(env | grep -E '^(OS|CHCREDS)_' | sed 's/=.*//'); do
unset "$v"
done
}
function prcreds {
env | awk -F'[=_]' '/^(OS|CHCREDS)_/ {if ($2 == "PASSWORD" || $2 == "TOKEN") print "OS_"$2"=******" ;else print $0}'
}
# Function useful for adding to your bash prompt
function os_creds {
[ -z "$OS_CRED" ] || echo " $OS_CRED"
}
# vim:syntax=sh