2022-08-19 12:48:11 +00:00
|
|
|
#!/bin/bash
|
|
|
|
set -euo pipefail
|
|
|
|
|
|
|
|
# Usage:
|
|
|
|
#
|
|
|
|
# 1) Put this into your ~/.docker/config.json:
|
|
|
|
# { "credsStore": "vault" }
|
|
|
|
#
|
2022-08-19 13:13:10 +00:00
|
|
|
# 2) Optional: Create ~/.config/docker-credential-vault with an
|
2022-08-19 12:48:11 +00:00
|
|
|
# override for the $PREFIX variable which defaults to
|
|
|
|
# "secret/docker-credential" in case you want to store the
|
2022-08-19 13:13:10 +00:00
|
|
|
# credentials some place else. If you want the script to
|
|
|
|
# behave more verbose you can set NO_LOG=0 in order to enable
|
|
|
|
# logging all actions to STDERR
|
2022-08-19 12:48:11 +00:00
|
|
|
#
|
|
|
|
# 3) Ensure vault is installed and can access the path specified by
|
|
|
|
# $PREFIX/*
|
|
|
|
|
2022-08-19 13:13:10 +00:00
|
|
|
config="${HOME}/.config/docker-credential-vault"
|
|
|
|
req_cmds=(jq md5sum vault)
|
2022-08-19 12:48:11 +00:00
|
|
|
|
2022-08-19 13:13:10 +00:00
|
|
|
NO_LOG=1
|
2022-08-19 12:48:11 +00:00
|
|
|
PREFIX=secret/docker-credential
|
|
|
|
|
|
|
|
[[ -f $config ]] && source "${config}" || true
|
|
|
|
|
|
|
|
function check_command() {
|
|
|
|
command -v "${1}" >/dev/null || {
|
|
|
|
echo "Missing tool: ${1}" >&2
|
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function get() {
|
|
|
|
local hostname="$(cat -s)" # Missing newline at the end, read does not work
|
|
|
|
|
2022-08-19 13:13:10 +00:00
|
|
|
log "Retrieving credential for ${hostname} if exists..."
|
2022-08-19 12:48:11 +00:00
|
|
|
vault read -field=data -format=json "${PREFIX}/$(hash_hostname "${hostname}")"
|
|
|
|
}
|
|
|
|
|
2022-08-19 13:13:10 +00:00
|
|
|
function erase() {
|
|
|
|
local hostname="$(cat -s)" # Missing newline at the end, read does not work
|
|
|
|
|
|
|
|
log "Deleting credential for ${hostname} if exists..."
|
|
|
|
vault delete "${PREFIX}/$(hash_hostname "${hostname}")" >/dev/null
|
|
|
|
}
|
|
|
|
|
2022-08-19 12:48:11 +00:00
|
|
|
function hash_hostname() {
|
|
|
|
echo "$1" | md5sum | cut -d ' ' -f 1
|
|
|
|
}
|
|
|
|
|
2023-01-12 12:11:10 +00:00
|
|
|
function list() {
|
|
|
|
local creds="{}"
|
|
|
|
|
|
|
|
for key in $(vault list -format=json secret/docker-credential | jq -r '.[]'); do
|
|
|
|
creds="$(vault read -field=data -format=json "${PREFIX}/${key}" | jq -c "${creds} + {(.ServerURL): .Username}")"
|
|
|
|
done
|
|
|
|
|
|
|
|
echo "${creds}"
|
|
|
|
}
|
|
|
|
|
2022-08-19 13:13:10 +00:00
|
|
|
function log() {
|
2022-08-19 13:22:04 +00:00
|
|
|
[ $NO_LOG -eq 0 ] || return 0
|
2022-08-19 13:13:10 +00:00
|
|
|
echo "[$(date +%H:%M:%S)][docker-credential-vault] $@" >&2
|
|
|
|
}
|
|
|
|
|
2022-08-19 12:48:11 +00:00
|
|
|
function main() {
|
|
|
|
for cmd in "${req_cmds[@]}"; do
|
|
|
|
check_command "${cmd}"
|
|
|
|
done
|
|
|
|
|
2022-09-02 13:55:20 +00:00
|
|
|
case "${1:-}" in
|
2022-08-19 12:48:11 +00:00
|
|
|
get) get ;;
|
2022-08-19 13:13:10 +00:00
|
|
|
erase) erase ;;
|
2023-01-12 12:11:10 +00:00
|
|
|
list) list ;;
|
2022-08-19 12:48:11 +00:00
|
|
|
store) store ;;
|
|
|
|
*)
|
2022-09-02 13:55:20 +00:00
|
|
|
echo "$(basename $0): Supported are only: get, erase, store (called '${1:-}')" >&2
|
2022-08-19 12:48:11 +00:00
|
|
|
exit 1
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
}
|
|
|
|
|
|
|
|
function store() {
|
|
|
|
local json="$(cat -s)"
|
|
|
|
|
|
|
|
local hostname=$(echo "${json}" | jq -r '.ServerURL')
|
|
|
|
local username=$(echo "${json}" | jq -r '.Username')
|
|
|
|
local secret=$(echo "${json}" | jq -r '.Secret')
|
|
|
|
|
2022-08-19 13:13:10 +00:00
|
|
|
log "Updating credential for ${hostname}..."
|
2022-08-19 12:48:11 +00:00
|
|
|
vault write "${PREFIX}/$(hash_hostname "${hostname}")" \
|
|
|
|
"ServerURL=${hostname}" \
|
|
|
|
"Username=${username}" \
|
|
|
|
"Secret=${secret}"
|
|
|
|
}
|
|
|
|
|
|
|
|
main "$@"
|