#!/usr/bin/env bash # NWSID="yourmail@example.com" OIDC_TOKEN_URL="https://id.nws.netways.de/realms/nws/protocol/openid-connect/token" OS_AUTH_URL="https://cloud.netways.de:5000/v3/" OID_OPENSTACK_CLIENT="openstack" OIDC_ISSUER_URL="https://id.nws.netways.de/realms/nws" get_local_python() { local_python_bin=$(which python3) if [ "$?" -ne "0" ] then local_python_bin=$(which python2) if [ "$?" -ne "0" ] then local_python_bin=$(which python) if [ "$?" -ne "0" ] then echo "Error: Python was not found. Please install python and the openstack commandline client before continuing." return 1 fi fi fi } source_cache() { if [ -e ~/.cache/nwsid.cache ] then source ~/.cache/nwsid.cache echo "Cache loaded" return 0 else return 1 fi } update_cache() { if [ -w ~/.cache/nwsid.cache ]; then cache_updated=false if [ ! -z ${TOKEN_RESPONSE+x} ] && [[ ${TOKEN_RESPONSE} != Invalid* ]]; then echo "export OS_ACCESS_TOKEN=$TOKEN_RESPONSE" > ~/.cache/nwsid.cache cache_updated=true elif [ ! -z ${OS_ACCESS_TOKEN+x} ] && [[ ${OS_ACCESS_TOKEN} != Invalid* ]]; then echo "export OS_ACCESS_TOKEN=$OS_ACCESS_TOKEN" > ~/.cache/nwsid.cache cache_updated=true fi if $cache_updated; then echo "export OS_AUTH_TYPE=$OS_AUTH_TYPE" >> ~/.cache/nwsid.cache echo "export OS_AUTH_URL=$OS_AUTH_URL" >> ~/.cache/nwsid.cache echo "export OS_IDENTITY_PROVIDER=$OS_IDENTITY_PROVIDER" >> ~/.cache/nwsid.cache echo "export OS_PROTOCOL=$OS_PROTOCOL" >> ~/.cache/nwsid.cache echo "export OS_PROJECT_DOMAIN_NAME=$OS_PROJECT_DOMAIN_NAME" >> ~/.cache/nwsid.cache echo "export OS_IDENTITY_API_VERSION=$OS_IDENTITY_API_VERSION" >> ~/.cache/nwsid.cache echo "export OS_PROJECT_NAME=$OS_PROJECT_NAME" >> ~/.cache/nwsid.cache fi fi } enable_cache() { if [ -w ~/.cache/nwsid.cache ] then echo "Cache was already enabled!" else touch ~/.cache/nwsid.cache chmod 0600 ~/.cache/nwsid.cache echo "Cache is now enabled!" fi update_cache } disable_cache() { if [ -w ~/.cache/nwsid.cache ] then rm ~/.cache/nwsid.cache echo "Cache disabled" fi } set_openstack_environment() { which kubelogin >/dev/null if [ "$?" -ne "0" ] then echo "Warning: kubelogin not found. Fallback to CLI. Only Password and OTP Authentication is supported!" echo "Please enter your NWS-ID e-mail address (default: ${NWSID}): " read -r KC_USER if [ -z "$KC_USER" ] then KC_USER=${NWSID} fi echo "Please enter your NWS-ID password for user $KC_USER: " read -sr KC_PASSWORD_INPUT echo "Please enter your TOTP code (optional): " read -r KC_TOTP_INPUT TOKEN_RESPONSE=$(get_nws_id_token_by_curl) else TOKEN_RESPONSE=$(get_nws_id_token_by_kubelogin) fi if [ ! "x${TOKEN_RESPONSE}" = "x" ] && [[ ${TOKEN_RESPONSE} != Invalid* ]]; then export OS_ACCESS_TOKEN=$TOKEN_RESPONSE else echo "Authentication error: $TOKEN_RESPONSE" return 1 fi update_cache set_project } get_nws_id_token_by_curl() { curl -s -X POST ${OIDC_TOKEN_URL} -H "Content-Type: application/x-www-form-urlencoded" --data-urlencode "username=${KC_USER}" --data-urlencode "password=${KC_PASSWORD_INPUT}" --data-urlencode "scope=openid profile" --data-urlencode "grant_type=password" --data-urlencode "client_id=${OID_OPENSTACK_CLIENT}" --data-urlencode "totp=${KC_TOTP_INPUT}" | $local_python_bin -c "import sys,json; response=json.load(sys.stdin); result=response['error_description'] if 'error' in response else response['access_token']; print(result);" } get_nws_id_token_by_kubelogin() { #response=$(kubelogin get-token --authentication-timeout-sec 2 --oidc-issuer-url=${OIDC_ISSUER_URL} --oidc-client-id=${OID_OPENSTACK_CLIENT}) kubelogin get-token --oidc-issuer-url=${OIDC_ISSUER_URL} --oidc-client-id=${OID_OPENSTACK_CLIENT} | $local_python_bin -c "import sys,json; response=json.load(sys.stdin); result=response['status']['token']; print(result);" } set_project() { echo -e "\nTesting authentication and fetching project list ..." export OS_AUTH_TYPE=v3oidcaccesstoken export OS_AUTH_URL export OS_IDENTITY_PROVIDER=nws-id export OS_PROTOCOL=openid export OS_PROJECT_DOMAIN_NAME=Default export OS_IDENTITY_API_VERSION=3 unset OS_PROJECT_NAME OPENSTACK_PROJECTS=$(openstack federation project list --sort-column Name --sort-ascending -f value -c Name | tr '\n' ' ') if [ -z "$OPENSTACK_PROJECTS" ] then echo -e "\nSomething went wrong during the attempt to get the project list. Please ensure that you are member of at least one project." echo "Also make sure your openstack commandline client is up-to-date." return 1 fi if [ $(wc -w <<< "$OPENSTACK_PROJECTS") -gt "1" ] then echo -e "\nPlease select one of your OpenStack projects.\n" PS3="Enter a number: " select os_project in $(echo $OPENSTACK_PROJECTS) do echo "Selected project: $os_project" break; done export OS_PROJECT_NAME=$os_project else export OS_PROJECT_NAME=$OPENSTACK_PROJECTS echo "Selected project: $OPENSTACK_PROJECTS" fi update_cache } show_menu() { PS3="Enter a number: " select option in "switch project" "re-authenticate" "enable cache" "disable cache" "exit" do echo "Selected option: $option" case $REPLY in 1) set_project; break ;; 2) set_openstack_environment; break ;; 3) enable_cache; break ;; 4) disable_cache; break ;; 5) echo "Exiting"; break ;; esac done } get_local_python if [ "$?" -eq "1" ] then echo "Error: Python was not found. Please install python and the openstack commandline client before continuing." return 1 fi which curl >/dev/null if [ "$?" -ne "0" ] then echo "Error: curl not found. Please install curl before continuing." return 1 fi source_cache if [ ! -z ${OS_ACCESS_TOKEN} ] then exp=$(echo -n "$OS_ACCESS_TOKEN"| cut -d '.' -f 2 | base64 -d 2>/dev/null | sed -E 's/.*"exp":([0-9]+),.*/\1/') if [ $(date +%s) -ge $exp ]; then echo "Access token is expired. Please authenticate again." set_openstack_environment else if [ -n ${OS_PROJECT_NAME} ]; then echo "Active project: $OS_PROJECT_NAME" fi show_menu fi else set_openstack_environment fi