#!/bin/sh MD_URL="http://169.254.169.254/latest" OIFS="$IFS" TIMEOUT=10 CR=" " Usage() { cat < dump 'item' from the metadata service Special items: --block-device-mappings dump the block device mappings, space delimited --public-keys dump the public keys with no options given, metadata service will be crawled and dumped. This will not include user-data. EOF } error() { echo "$@" 1>&2; } fail() { [ $# -eq 0 ] || error "$@"; exit 1; } get_field_list() { local under="$1" x="" out="" found="" mdget "$under" out="$_RET" for x in $out; do case "$x" in */) get_field_list "${under:+${under}/}${x%/}" found="${found} $_RET";; *) found="${found} ${under:+$under/}$x";; esac done _RET="${found# }" } caturl() { curl --fail --silent --max-time "${TIMEOUT}" "$1" } mdget() { local u="$1" t1="" t2="" out="" case "$u" in user-data) :;; public-keys|public-keys/) out=$(caturl "$MD_URL/meta-data/$u") || fail "failed to get $MD_URL/meta-data/$u"; # output of public-keys is lines of 'X=keyname' # so we return a carriage return list of the tokens before = _RET="" IFS="$CR" for t1 in $out; do t1="${t1%%=*}" _RET="${_RET:+${_RET}${CR}}${t1%/}" done IFS="$OIFS" return ;; public-keys/*) t1=${u#public-keys/[0-9]} # t2 will now have 'public-keys/[0-9]' t2=${u%${t1}} # if t1 has a / (ie, u=public-keys/0=brickies/openssh-keys) # then set t1 to just "/openssh-keys". if not, set it to "" [ "${t1#*/}" = "${t1}" ] && t1="" || t1="/${t1#*/}" u="meta-data/${t2}${t1}" ;; *) u="meta-data/$u";; esac _RET=$(caturl "$MD_URL/$u") || fail "failed to get ${MD_URL}/$u" } special() { local out="" x="" t="" ret="" case "$1" in availability-zone) mdget "placement/availability-zone";; public-keys) mdget public-keys out="$_RET" IFS="$CR" for x in ${out}; do IFS="$OIFS" mdget \ "public-keys/${x}/openssh-key" && ret="${ret:+${ret}${CR}}${_RET}" done IFS="$OIFS" _RET="$ret" ;; block-device-mappings) mdget block-device-mapping out="$_RET" for x in ${out}; do mdget "block-device-mapping/$x" ret="${ret:+${ret} }${x}=$_RET"; done _RET="$ret" esac } fields="" while [ $# -ne 0 ]; do cur=${1}; next=${2}; case "$cur" in -h|--help) Usage ; exit 0;; --url=*) MD_URL=${cur#*=}; MD_URL=${MD_URL%/};; --url|-u) MD_URL="${next%/}"; shift;; --availability-zone|--public-keys|--block-device-mappings) fields="$fields special_${cur#--}";; --*) fields="$fields ${cur#--}";; esac shift; done fields="${fields# }" if [ -z "$fields" ]; then get_field_list "" fields="${_RET}" prefix=true else prefix=false fi for f in $fields; do case "$f" in special_*) special "${f#special_}";; *) mdget "$f";; esac ret=$? [ $ret -eq 0 ] || fail "failed to get $f" if $prefix; then if [ "${_RET#*${CR}}" != "${_RET}" ]; then _RET=$(echo "$_RET" | sed 's,^,|,g') _RET="${_RET#|}" fi echo "${f#special_}: $_RET" else echo "$_RET" fi done exit 0 # vi: ts=4 noexpandtab