Итак, у нас на работе много vlan, часто приятно видеть, какие диапазоны IP-адресов связаны с указанным vlan. У нас есть хорошо развитый API для отображения информации о нашей сети, поэтому я написал небольшой скрипт для извлечения этой информации.
Единственная проблема заключается в том, что для доступа к API нам требуется токен не старше X часов. Таким образом, скрипт должен проверить этот токен и при необходимости обновить его перед запуском команды.
API не является общедоступным, но данные ответа выглядят так:
Запрос
v1/networks/?vlan=119
Ответ
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"id": 13,
"excluded_ranges": [],
"created_at": "2019-10-16T14:57:55.932564+02:00",
"updated_at": "2019-10-23T12:23:30.914823+02:00",
"network": "yyy.xxx.2.64/27",
"description": "core-3",
"vlan": 119,
"dns_delegated": false,
"category": "so",
"location": "",
"frozen": false,
"reserved": 3
},
{
"id": 1110,
"excluded_ranges": [],
"created_at": "2019-10-16T14:57:55.932564+02:00",
"updated_at": "2019-10-10T12:44:18.912178+02:00",
"network": "xxx:yyy:zzz:540::/64",
"description": "core-3",
"vlan": 119,
"dns_delegated": false,
"category": "",
"location": "",
"frozen": false,
"reserved": 3
}
]
}
Код используется как ./ulan.sh 119
с ответом
yyy.xxx.2.64/27 core-3
xxx:yyy:zzz:540::/64 core-3
Код работает по назначению, проходит шеллчек и форматируется с использованием shfmt -l -w -i 4 ulan.sh
. Тем не менее, я чувствую, что еще многое предстоит улучшить.
Полный код
#!/bin/bash
#
# Author: N3buchadnezzar
#
# License: GPLv3+
# Set PATH
PATH=/bin:/usr/bin
export PATH
# Usage
usage="Usage: ulan <vlan>"
# Check arguments
if [ -z "$1" ]; then
echo >&2 "$usage"
exit 1
fi
# Help
if [ "$1" == "-h" ] || [ "$1" == "--help" ]; then
echo "$usage"
cat <<EOF
List ip-range and description associated with the uio drifted vlan
Options:
-h, --help Show this help message
EOF
exit 0
fi
MREG_TOKEN_PATH="$HOME/.mreg-cli_auth_token"
MREG_VERSION="1"
MREG_API="https://mreg.uio.no/api"
function create_mreg_token {
echo "Connecting to https://mreg.uio.no"
printf "Username: " >&2
read -r USER
printf 'Password for %s:' "$USER"
trap 'stty echo' INT EXIT
stty -echo
read -r MYPASS
printf "\n"
token_object=$(
curl -X POST -H "Content-Type: application/json" \
--data "{\"username\":\"$USER\",\"password\":\"$MYPASS\"}" \
"${MREG_API}/token-auth/"
)
token=$(echo "$token_object" | jq -r '.token')
echo -n "$USER¤$token" >"$MREG_TOKEN_PATH"
}
function check_vlan {
if [ $# -eq 0 ]; then
echo "No arguments supplied"
exit 1
fi
vlan="$1"
if [ ! -f "$MREG_TOKEN_PATH" ]; then
touch "$MREG_TOKEN_PATH"
fi
mreg_token=$(cut -d "¤" -f2 "$MREG_TOKEN_PATH")
mreg_query="${MREG_API}/v${MREG_VERSION}/networks/?vlan=$vlan"
mreg_response_http_code=$(
curl \
--write-out "%{http_code}" --silent --output /dev/null \
-s -H "Authorization: Token ${mreg_token}" \
"${mreg_query}"
)
if [ "$mreg_response_http_code" -ne 200 ]; then
echo "Invalid mreg token! Creating.."
create_mreg_token
mreg_token=$(cut -d "¤" -f2 "$MREG_TOKEN_PATH")
fi
mreg_response=$(curl -s -H "Authorization: Token ${mreg_token}" "$mreg_query")
result=$(echo "$mreg_response" | jq -c .results)
for row in $(echo "${result}" | jq -r '.[] | @base64'); do
_jq() {
echo "${row}" | base64 --decode | jq -r "${1}"
}
echo "$(_jq '.network') $(_jq '.description')"
done | column -t
}
check_vlan "$1"