#!/bin/sh
# @(#)$KimmoSuominen: .cfg/home/bin/share/ec2meta,v 1.9 2022/05/02 09:27:42 kim Exp $
#
# Get EC2 metadata
#
# 20150506  Kimmo Suominen
#

PATH=/bin:/usr/bin
export PATH

BASE=http://169.254.169.254/latest
TOKEN_LIFETIME=180

PROG="${0##*/}"

umask 077

get_meta()
{
    local i
    case "${1}" in
    '')
	# unfortunately no trailing slashes as of 2015-05-06
	for i in $(imds_request)
	do
	    case "${i}" in
	    dynamic|meta-data)
		# these are known to have stuff under them
		echo "${i}/"
		;;
	    *)
		echo "${i}"
		;;
	    esac
	done
	;;
    user-data)
	local dir
	dir=$(mktemp -dq "${TMPDIR:-/tmp}/${PROG}.XXXXXXXXXX") || exit ${?}
	imds_request "${1}" > "${dir}/original.gz"
	gunzip -q "${dir}/original.gz" \
	&& cat "${dir}/original" \
	|| cat "${dir}/original.gz"
	rm -rf "${dir}"
	;;
    *)
	imds_request "${1}"
	;;
    esac
}

get_token()
{
    curl -fs -X PUT \
	-H "X-aws-ec2-metadata-token-ttl-seconds: ${TOKEN_LIFETIME}" \
	"${BASE}/api/token"
}

imds_request()
{
    curl -fs -H "X-aws-ec2-metadata-token: ${TOKEN}" "${BASE}/${1:-}"
}

meta_print()
{
    local i lines value
    for i in $(get_meta "${1}")
    do
	case "${1}${i}" in
	*/)
	    meta_print "${1}${i}"
	    ;;
	*=*)
	    meta_print "${1}${i%%=*}/"
	    ;;
	*)
	    value=$(get_meta "${1}${i}")
	    case ${?} in
	    22)
		# not found or other 4xx or higher status
		;;
	    *)
		lines=$(echo "${value}" | wc -l)
		# zero cannot happen
		case "${lines}" in
		1)
		    echo "${1}${i}: ${value}"
		    ;;
		*)
		    multiline "${1}${i}" "${value}"
		    ;;
		esac
		;;
	    esac
	    ;;
	esac
    done
}

multiline()
{
    echo "${1}:"
    # prepend two spaces
    echo "${2}" | sed -e 's/^/  /'
}

TOKEN=$(get_token)
exit_code=${?}
case "${TOKEN}" in
'')
    exit ${exit_code}
    ;;
esac

case "${1}" in
*/|'')
    get_meta "${1}" >/dev/null && meta_print "${1}"
    ;;
*)
    # force a newline
    value=$(get_meta "${1}")
    exit_code=${?}
    case "${value}" in
    '')
	;;
    *)
	echo "${value}"
	;;
    esac
    exit ${exit_code}
    ;;
esac
