|
#!/usr/bin/env sh |
|
set -e -o pipefail |
|
trap 'echo "On $action failed with $?"' ERR |
|
|
|
action=setup |
|
quiet=false |
|
verbose=false |
|
debug=false |
|
site="${ACP_SITE:-}" |
|
ffbase=~/AppData/Roaming/Mozilla/Firefox |
|
acptoken= |
|
cookies= |
|
ffprofile= |
|
if [ -f "$ffbase/profiles.ini" ] ; then |
|
ffprofile="$(sed -nre 's/^Default=Profiles\/(.*)\r?$/\1/p' "$ffbase/profiles.ini"|head -1)" |
|
if [ -f "$ffbase/Profiles/$ffprofile/cookies.sqlite" ] ; then |
|
cookies="$ffbase/Profiles/$ffprofile/cookies.sqlite" |
|
else |
|
ffprofile= |
|
fi |
|
fi |
|
|
|
progname="${ACP2KUBECONFIG:-${0##*/}}" |
|
usage="Usage: ${progname} [-qvD] [--quiet] [--verbose] [--debug] [-s|--site <host>] [-c|--cookies <cookies-sqlite-path] [[-t|--token] <token>]" |
|
|
|
if ! O=`getopt -l quiet,verbose,debug,site:,cookies:,token:,help -n "${0##*/}" -- qvDs:c:t:h "$@"` ; then |
|
echo "$usage" |
|
exit 1 |
|
fi |
|
eval set -- "$O" |
|
while true; do |
|
case "$1" in |
|
-v|--verbose) |
|
verbose=true;quiet=false;shift;; |
|
-q|--quiet) |
|
quiet=true;verbose=false;shift;; |
|
-D|--debug) |
|
debug=true;shift;; |
|
-s|--site) |
|
site="$2";shift 2;; |
|
-c|--cookies) |
|
cookies="$2";shift 2;; |
|
-t|--token) |
|
acptoken="$2";shift 2;; |
|
-h|--help) |
|
echo "$usage" |
|
echo "Options:" |
|
echo " -q, --quiet Be quiet$($quiet && echo " (default)")" |
|
echo " -v, --verbose Be verbose$($verbose && echo " (default)")" |
|
echo " -d, --debug Be very verbose" |
|
echo " -s, --site <host> Host of alauda console$(test -n "$site" && echo " (default: $site)" || echo " (required)")" |
|
echo " -c, --cookies <file> Path of cookies.sqlite file in Firefox profile$(test -n "$cookies" && echo " (autodetected profile $ffprofile)")" |
|
echo " -t, --token <token> Override token (use instead of --cookies)" |
|
exit 1;; |
|
--) |
|
shift; break;; |
|
*) |
|
echo getopt error;echo "$usage";exit 1;; |
|
esac |
|
done |
|
|
|
if [ "$#" == "1" ] && [ -z "$acptoken" ] ; then |
|
acptoken="$1" |
|
shift |
|
fi |
|
|
|
if [ "$#" != "0" ] ; then |
|
echo "getopt error: Leftover arguments: $*" |
|
echo "$usage" |
|
exit 1 |
|
fi |
|
|
|
if [ -z "$site" ] ; then |
|
echo "Either pass --site with host of Alauda ACP or set ACP_SITE globally." |
|
echo "$usage" |
|
exit 1 |
|
fi |
|
|
|
if [ -z "$cookies" ] && [ -z "$acptoken" ] ; then |
|
echo "$(test -z "$ffprofile" && echo "Unable to autodetect ff profile. ")Either pass --cookies with path to cookies.sqlite or --token." |
|
echo "$usage" |
|
exit 1 |
|
fi |
|
|
|
#echo -e "quiet=$quiet\nverbose=$verbose\ndebug=$debug\nsite=$site\nffprofile=$ffprofile\ncookies=$cookies\nacptoken=$acptoken" |
|
#exit |
|
|
|
if [ -z "$acptoken" ] ; then |
|
#if ! [ -f "$cookies" ] ; then |
|
# echo "FATAL: Unable to find file $cookies" |
|
# exit 1 |
|
#fi |
|
acptoken="$(sqlite3 -ifexists -readonly -batch "$cookies" "select value from moz_cookies where host='$site' and name='cpaas_id_token'" \ |
|
| jq -n '[inputs][0]? // ""|split(" ")[1]? // ("FATAL: Unable to detect acptoken.\n"|halt_error)' -r)" |
|
fi |
|
#kubeuser=c-common |
|
kubeuser="$(yq -r --arg site "$site" '"FATAL: Incorrect ~/.kube/config file.\n" as $e|(.clusters|map(select(.cluster.server|startswith("https://\($site)")))[0]? // ($e|halt_error)|.name) as $cluster|(.contexts[]|select(.context.cluster==$cluster)|.context+{context:.name}) as {$context,$user}|.users[]|select(.name==$user)|if .user.token then $user else $e|halt_error end' ~/.kube/config)" |
|
kubetoken="$(yq -r --arg kubeuser "$kubeuser" '.users|map(select(.name==$kubeuser).user.token)[0]? // ("FATAL: Incorrect ~/.kube/config file.\n"|halt_error)' ~/.kube/config)" |
|
|
|
#echo -e "acptoken=$acptoken\nkubeuser=$kubeuser\nkubetoken=$kubetoken" |
|
#exit |
|
|
|
action=check |
|
if [ "$acptoken" == "$kubetoken" ] ; then |
|
action=skip |
|
$verbose && echo "Already up to date." |
|
else |
|
action='prepare patch' |
|
$verbose && echo "Will patch..." |
|
sed -e "s/${kubetoken//./\\.}/$acptoken/" ~/.kube/config > ~/.kube/config.new |
|
action='verify patch' |
|
yq -s --arg kubeuser "$kubeuser" --arg kubetoken "$kubetoken" --arg acptoken "$acptoken" ' |
|
if type=="array" and length==2 then ( |
|
. as [$old,$new]| |
|
if $new|(type!="object" or (has("users")|not) or (.users|type)!="array") then "FATAL: New config has invalid format.\n"|halt_error |
|
elif $old|(type!="object" or (has("users")|not) or (.users|type)!="array") then "FATAL: Old config has invalid format.\n"|halt_error |
|
else . end| |
|
($old.users|to_entries|map(select(.value.name==$kubeuser))[0].key) as $i| |
|
if $new.users[$i]?.name?!=$kubeuser then "FATAL: New config has invalid $i user ref.\n"|halt_error |
|
elif $new.users[$i].user.token!=$acptoken then "FATAL: New config has invalid $i user token.\n"|halt_error |
|
elif $old.users[$i].user.token!=$kubetoken then "FATAL: Old config has invalid $i user token.\n"|halt_error |
|
else empty end |
|
) else "FATAL: Input error\n"|halt_error end' ~/.kube/config ~/.kube/config.new |
|
$debug && diff -su ~/.kube/config ~/.kube/config.new || true |
|
action='diff patch' |
|
commentchanges="$(diff -awNU0 ~/.kube/config ~/.kube/config.new|grep -cEe '^-\s*#')"||true |
|
changes="$(diff -awNU0 ~/.kube/config ~/.kube/config.new|grep -vEe '^-\s*#'|grep -cEe '^[+-]\s')"||true |
|
action='check patch' |
|
warn=false |
|
fail=false |
|
skip=false |
|
if [ $commentchanges -gt 0 ] ; then echo "WARN: Will remove $commentchanges comment lines" ; warn=true ; fi |
|
if [ $changes -ge 10 ] ; then echo "WARN: Too much changes$($debug && echo ": $changes")" ; fail=true |
|
elif [ $changes -gt 2 ] ; then echo "WARN: More changes than expecpected$($debug && echo ": $changes")" ; fail=true |
|
elif [ $changes -lt 1 ] ; then echo "WARN: Seems there are no changes" ; skip=true |
|
elif [ $changes -lt 2 ] ; then echo "WARN: Incorrect number of changes$($debug && echo ": $changes != 2")" ; fail=true |
|
elif $debug ; then echo "Correct: $changes == 2" |
|
fi |
|
if $skip ; then |
|
action='skip patch' |
|
true |
|
elif $fail ; then |
|
action='fail patch' |
|
echo If sure: |
|
echo mv -f ~/.kube/config.new ~/.kube/config |
|
elif $warn ; then |
|
action='warn patch' |
|
mv -i ~/.kube/config.new ~/.kube/config |
|
$debug && echo mv-res=$? |
|
else |
|
action='apply patch' |
|
mv -f ~/.kube/config.new ~/.kube/config |
|
$debug && echo mv-res=$? |
|
fi |
|
fi |
|
action=inspect |
|
if $quiet ; then |
|
true |
|
elif $verbose ; then |
|
yq '.users[].user.token? // empty|gsub("_";"/")|gsub("-";"+")|split(".")[1]|@base64d|fromjson |
|
|(.exp,.iat)|=(. as $in|try todate catch $in)|if .roles then .roles|=join(",") end |
|
|del(.sub,.c_hash,.at_hash,.nonce,.aud)|if .email_verified?==true then del(.email_verified) end |
|
|if .ext?.is_admin?==false and (.ext? // {}|keys)==["conn_id","is_admin"] then del(.ext) end' ~/.kube/config |
|
else |
|
#saveCP=`chcp.com 2>&1|sed -nre 's/^.*: (\S+)\r?$/\1/p'` |
|
#chcp.com 65001 &> /dev/null |
|
#yq -r -b '.users[].user.token? // empty|gsub("_";"/")|gsub("-";"+")|split(".")[1]|@base64d|fromjson |
|
# |(.exp,.iat)|=todate|"Token for \(.name) (\(.email)) as \(.iss),\nsince \(.iat) till \(.exp)"' ~/.kube/config |
|
#test -z "$saveCP" || chcp.com "$saveCP" &> /dev/null |
|
PYTHONUTF8=1 yq -y '.users[].user.token? // empty|gsub("_";"/")|gsub("-";"+")|split(".")[1]|@base64d|fromjson |
|
|(.exp,.iat)|=todate|{user:"\u0022\(.name)\u0022 <\(.email)>",target:.iss,since:.iat,till:.exp}' ~/.kube/config |
|
fi |