Enhance loginHarborHub.sh with improved credential management and usage examples

This commit is contained in:
Luca Frosini 2025-03-12 10:00:32 +01:00
parent 56b62463a4
commit 48ad68b5cd
1 changed files with 268 additions and 6 deletions

View File

@ -1,13 +1,275 @@
#!/bin/bash
# Script to authenticate with Harbor Registry
# Manages credentials in a JSON file and facilitates Docker CLI access
# Configuration file is stored in ~/.harbor.json
# Examples:
# # Authenticate using stored credentials or prompt if none exist
# loginHarborHub.sh
# # Save credentials without performing login
# loginHarborHub.sh -d
# # Save credentials and perform login
# loginHarborHub.sh -d -l
# # Authenticate with a different registry
# loginHarborHub.sh -r docker.io
# # Authenticate with explicit parameters
# loginHarborHub.sh -u username -p my_token
# # Save credentials for a specific registry
# loginHarborHub.sh -d -r docker.io -u username -p my_token
# # Save credentials for a specific registry prompting them
# loginHarborHub.sh -d -r docker.io
# # Configuration file format:
# [
# {
# "registry_url": "hub.dev.d4science.org",
# "username": "myusername",
# "access_token": "mytoken" # accept plain or base64 encoded
# }
# ]
CONFIG_FILE="$HOME/.harbor.json"
# Default values
REGISTRY_URL="hub.dev.d4science.org"
#USERNAME="alfredo.oliviero"
echo "to obtain Harbor username and CLI secret:"
echo "https://hub.dev.d4science.org/ -> user profile -> CLI secret"
USERNAME=""
ACCESS_TOKEN=""
ENCODE_TOKEN=true
DUMP_CREDENTIALS=false
read -p "username:" USERNAME
ARK_REGISTRY_URL=""
ARG_USERNAME=""
ARG_ACCESS_TOKEN=""
echo ""
# Function to display help
show_help() {
echo "Usage: $(basename $0) [options]"
echo ""
echo "Options:"
echo " -h Show this help message"
echo " -r Specify a different registry URL"
echo " -u Specify the username"
echo " -p Specify the CLI secret (access token)"
echo " -d Save credentials without performing login"
echo " -f credentials files (default ~/.harbor.json)"
echo " -l Perform login after saving credentials (requires -d) (default: false)"
echo " -t Don't encode the token in base64 when saving"
echo ""
echo "Examples:"
echo " # Authenticate using stored credentials or prompt if none exist"
echo " $(basename $0)"
echo ""
echo " # Save credentials without performing login"
echo " $(basename $0) -d"
echo ""
echo " # Save credentials on custom file, and perform login. will prompt for credentials"
echo " $(basename $0) -d -l -f aaa.json"
echo ""
echo " # Authenticate with a different registry"
echo " $(basename $0) -r docker.io"
echo ""
echo " # Authenticate with explicit parameters"
echo " $(basename $0) -u username -p my_token"
echo ""
echo " # Save credentials for a specific registry"
echo " $(basename $0) -d -r docker.io -u username -p my_token"
echo ""
echo " # Save credentials for a specific registry prompting them"
echo " $(basename $0) -d -r docker.io"
}
read -s -p "CLI secret:" ACCESS_TOKEN
LOGIN_AFTER_SAVE=false
# Parse optional parameters
while getopts "r:u:p:dthlf:" opt; do
case $opt in
r)
ARK_REGISTRY_URL=$OPTARG
;;
u)
ARG_USERNAME=$OPTARG
;;
p)
ARG_ACCESS_TOKEN=$OPTARG
;;
d)
DUMP_CREDENTIALS=true
;;
t)
ENCODE_TOKEN=false
;;
l)
LOGIN_AFTER_SAVE=true
;;
f)
CONFIG_FILE=$OPTARG
;;
h)
show_help
exit 0
;;
\?)
echo "Invalid option: -$OPTARG" >&2
show_help
exit 1
;;
esac
done
# Function to read credentials from config file
read_credentials() {
local registry_url=$1
if [ -f "$CONFIG_FILE" ]; then
# Ensure file is valid JSON
if jq empty "$CONFIG_FILE" 2>/dev/null; then
local credentials=$(jq -r --arg url "$registry_url" '.[] | select(.registry_url == $url)' "$CONFIG_FILE")
local username_from_file=$(echo "$credentials" | jq -r '.username')
local token_from_file=$(echo "$credentials" | jq -r '.access_token')
# Only use values if they are not null or empty
if [ "$username_from_file" != "null" ] && [ -n "$username_from_file" ]; then
USERNAME="$username_from_file"
fi
if [ "$token_from_file" != "null" ] && [ -n "$token_from_file" ]; then
# Try to decode, if it fails, use as is
ACCESS_TOKEN=$(echo "$token_from_file" | base64 --decode 2>/dev/null || echo "$token_from_file")
fi
else
echo "Warning: Config file exists but is not valid JSON"
fi
fi
}
# Function to write credentials to config file
write_credentials() {
local registry_url=$1
local username=$2
local access_token=$3
echo "Saving credentials for $registry_url..."
echo " Username: $username"
echo " Token: [HIDDEN]"
mkdir -p "$(dirname "$CONFIG_FILE")"
if [ "$ENCODE_TOKEN" = true ]; then
access_token=$(
echo "$access_token" | base64
)
fi
local new_entry=$(jq -n --arg url "$registry_url" --arg user "$username" --arg token "$access_token" \
'{registry_url: $url, username: $user, access_token: $token}')
if [ -f "$CONFIG_FILE" ] && [ -s "$CONFIG_FILE" ]; then
if jq empty "$CONFIG_FILE" 2>/dev/null; then
jq --argjson new_entry "$new_entry" 'map(select(.registry_url != $new_entry.registry_url)) + [$new_entry]' "$CONFIG_FILE" >"$CONFIG_FILE.tmp"
mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
else
echo "[$new_entry]" >"$CONFIG_FILE"
fi
else
echo "[$new_entry]" >"$CONFIG_FILE"
fi
}
# Function to prompt for confirmation or change
prompt_for_change() {
local var_name=$1
local var_value=$2
local var_prompt=$3
if [ -z "$var_value" ]; then
read -p "$var_prompt: " new_value
if [ -n "$new_value" ]; then
eval "$var_name=\"\$new_value\""
fi
else
read -p "$var_prompt [$var_value]: " new_value
if [ -n "$new_value" ]; then
eval "$var_name=\"\$new_value\""
fi
fi
}
# Dump credentials if -d option is provided
if [ "$DUMP_CREDENTIALS" = true ]; then
# Read any existing credentials first
if [ -z "$ARK_REGISTRY_URL" ]; then
prompt_for_change "REGISTRY_URL" "$REGISTRY_URL" "Registry URL"
else
echo "Registry URL: $ARK_REGISTRY_URL"
REGISTRY_URL="$ARK_REGISTRY_URL"
fi
read_credentials "$REGISTRY_URL"
if [ -z "$ARG_USERNAME" ]; then
prompt_for_change "USERNAME" "$USERNAME" "Username"
else
echo "Username: $ARG_USERNAME"
USERNAME="$ARG_USERNAME"
fi
if [ -z "$ARG_ACCESS_TOKEN" ]; then
echo "https://$REGISTRY_URL/ -> user profile -> CLI secret"
read -s -p "CLI secret: " ACCESS_TOKEN
echo ""
else
echo "CLI secret: [****]"
ACCESS_TOKEN=$ARG_ACCESS_TOKEN
fi
write_credentials "$REGISTRY_URL" "$USERNAME" "$ACCESS_TOKEN"
echo "Credentials saved to $CONFIG_FILE"
if [ "$LOGIN_AFTER_SAVE" != true ]; then
exit 0
fi
fi
# If a different registry URL is specified, use it
if [ -n "$ARK_REGISTRY_URL" ]; then
REGISTRY_URL="$ARK_REGISTRY_URL"
fi
# If username is specified, use it
if [ -n "$ARG_USERNAME" ]; then
USERNAME="$ARG_USERNAME"
fi
# If token is specified, use it
if [ -n "$ARG_ACCESS_TOKEN" ]; then
ACCESS_TOKEN="$ARG_ACCESS_TOKEN"
fi
# Read credentials from config file if not provided as parameters
read_credentials "$REGISTRY_URL"
# Ask for username only if not provided as parameter or in config file
if [ -z "$USERNAME" ]; then
echo "To obtain Harbor username and CLI secret:"
echo "https://$REGISTRY_URL/ -> user profile -> CLI secret"
read -p "Username: " USERNAME
fi
# Ask for CLI secret only if not provided as parameter or in config file
if [ -z "$ACCESS_TOKEN" ]; then
read -s -p "CLI secret: " ACCESS_TOKEN
echo ""
fi
# Perform Docker login with credentials
echo "$ACCESS_TOKEN" | docker login $REGISTRY_URL -u $USERNAME --password-stdin
unset ACCESS_TOKEN