Skip to content
Snippets Groups Projects

OP#7546 Icinga Check für ablaufende Gitlab tokens https://projects.iml.unibe.ch/work_packages/7546

+ 237
0
 
#!/bin/bash
 
# ======================================================================
 
#
 
# Check Gitlab tokens
 
#
 
# requirements:
 
# - inc/rest-api-client.sh
 
# - curl
 
#
 
# ----------------------------------------------------------------------
 
# 2024-10-25 v0.0 <axel.hahn@iml.unibe.ch>
 
# ======================================================================
 
 
 
cd "$( dirname "$0" )" || exit
 
 
. "$( dirname $0 )/inc_pluginfunctions" || exit 1
 
 
export self_APPVERSION=0.1
 
 
GITLAB_API='https://gitlab.example.com/api/v4'
 
GITLAB_TOKEN='glpat-12345678'
 
 
GITLAB_API='https://git-repo.iml.unibe.ch/api/v4'
 
GITLAB_TOKEN='glpat-4Lh6j_aJv7b6zVsRxyXF'
 
 
GITLAB_CONFIG=/etc/icinga2/gitlab.cfg
 
REST_CLIENT="$( dirname $0 )/../inc/rest-api-client.sh"
 
 
typeset -i iSince=395
 
typeset -i iTokenCount
 
typeset -i iTokensFound
 
NL="
 
"
 
 
typeset -i iWarnLimit=300
 
typeset -i iCriticalLimit=200
 
 
typeset -i iCountWarn=0
 
typeset -i iCountCritical=0
 
output=""
 
 
# ----------------------------------------------------------------------
 
# functions
 
# ----------------------------------------------------------------------
 
 
 
function showHelp(){
 
local _self; _self=$(basename $0)
 
cat <<EOF
 
$( ph.showImlHelpHeader )
 
 
Check gitlab tokens and warn if a token expires soon.
 
 
This check fetches the gitlbab tokens created in the last $iSince days
 
from the Gitlab API. It skips
 
 
- personal access tokens of users
 
- revoked tokens
 
 
SYNTAX:
 
$_self [-w WARN_LIMIT] [-c CRITICAL_LIMIT]
 
 
OPTIONS:
 
 
-h or --help show this help.
 
 
-w VALUE warning level (default: $iWarnLimit)
 
-c VALUE critical level (default: $iCriticalLimit)
 
 
-g FILE path to GITLAB_CONFIG; default: $GITLAB_CONFIG
 
-r FILE path to REST_CLIENT; default: $REST_CLIENT
 
 
-s DAYS Number of days for max age of token; default: $iSince
 
 
PARAMETERS:
 
 
None.
 
 
EXAMPLE:
 
$(basename $0) -w 28 -c 7
 
 
EOF
 
}
 
 
# Ffetch data from gitlab api with page requests
 
# param string url
 
# param string output file
 
# param int optional: number of items per page; default: 100
 
function _getPagesToFile(){
 
local url="$1"
 
local outfile="$2"
 
local iPerPage=${3:-100}
 
local page=0
 
 
test -f "${outfile}" && rm "${outfile}"
 
 
grep -q "?" <<< "$url" || url="${url}?"
 
while true; do
 
(( page++ ))
 
 
pageUrl="$url&per_page=${iPerPage}&page=${page}"
 
# echo "Request: $pageUrl"
 
 
http.makeRequest "$pageUrl"
 
if ! http.isOk > /dev/null; then
 
echo "ERROR: Request failed: $pageUrl"
 
http.getResponseHeader
 
http.getResponse
 
exit 1
 
fi
 
 
# if response is "[]" then we are done
 
if ! http.getResponse | grep -q "^\[\]$"; then
 
http.getResponse >> "${outfile}"
 
else
 
break
 
fi
 
 
done
 
}
 
 
function getKey(){
 
echo "$1" | jq -r ".$2" | grep -v "null"
 
}
 
 
# ----------------------------------------------------------------------
 
# MAIN
 
# ----------------------------------------------------------------------
 
 
# --- check param -h
 
case "$1" in
 
"--help"|"-h")
 
showHelp
 
exit 0
 
;;
 
*)
 
esac
 
 
REST_CLIENT=$( ph.getValueWithParam $REST_CLIENT r "$@")
 
GITLAB_CONFIG=$( ph.getValueWithParam $GITLAB_CONFIG g "$@")
 
 
# --- check requirements
 
ph.require curl
 
. "${GITLAB_CONFIG}" || exit 1
 
. "${REST_CLIENT}" || exit 1
 
http.help >/dev/null || exit 1
 
 
 
iWarnLimit=$( ph.getValueWithParam $iWarnLimit w "$@")
 
iCriticalLimit=$( ph.getValueWithParam $iCriticalLimit c "$@")
 
iSince=$( ph.getValueWithParam $iSince s "$@")
 
 
http.init
 
http.addHeader "PRIVATE-TOKEN: $GITLAB_TOKEN"
 
http.setBaseUrl "$GITLAB_API"
 
 
startdate="$( date +%Y-%m-%dT00:00:00Z --date "$iSince days ago")"
 
sDateWarn="$( date +%Y%m%d --date "${iWarnLimit} days" )"
 
sDateCritical="$( date +%Y%m%d --date "${iCriticalLimit} days" )"
 
 
url="/personal_access_tokens/?revoked=false&created_after=${startdate}"
 
_getPagesToFile "$url" "/tmp/gitlab-tokens.json"
 
_getPagesToFile "/users" /tmp/gitlab-users.json
 
 
 
# IDs / Einträge zählen:
 
iTokenCount=$( cat /tmp/gitlab-tokens.json | jq ".[].id " | wc -l )
 
# echo "Found Tokens since $startdate: $iTokenCount"
 
 
 
# echo "Warn when expiring before: ${sDateWarn} ... critical before: ${sDateCritical}"
 
# loop over tokens
 
 
iTokensFound=0
 
 
for i in $( seq 1 $iTokenCount )
 
do
 
 
# get nth token
 
entry="$( cat /tmp/gitlab-tokens.json | jq ".[$i]" )"
 
 
# hide non active tokens
 
if [ "$( getKey "$entry" "active" )" = "false" ]; then
 
continue
 
fi
 
 
# hide tokens without name
 
sName=$( getKey "$entry" "name" )
 
if [ -z "$sName" ]; then
 
continue
 
fi
 
 
# hide tokens referencing a username that doesn't contain "_[number]_bot_"
 
sUserid=$( getKey "$entry" "user_id" )
 
myusername="$( cat /tmp/gitlab-users.json | jq ".[] | select(.id == $sUserid)" | jq ".username" | cut -f 1-3 -d "_" | tr -d '"') "
 
if ! grep -q "_[0-9]*_bot" <<< "$myusername" ; then
 
continue
 
fi
 
 
iTokensFound+=1
 
 
# check expiration
 
sExpire=$( getKey "$entry" "expires_at" )
 
 
# remove "-" from date to get an integer
 
sExpire2=${sExpire//\-}
 
 
 
sStatus="OK "
 
if [ "$sExpire2" -le "$sDateWarn" ]; then
 
if [ "$sExpire2" -le "$sDateCritical" ]; then
 
iCountCritical+=1
 
sStatus="Critical"
 
else
 
iCountWarn+=1
 
sStatus="Warning "
 
fi
 
fi
 
 
output+="$sExpire $sStatus $sName $myusername${NL}"
 
 
done
 
 
if [ $iCountCritical -gt 0 ]; then
 
ph.setStatus "critical"
 
elif [ $iCountWarn -gt 0 ]; then
 
ph.setStatus "warning"
 
else
 
ph.setStatus "ok"
 
fi
 
 
ph.status "$iTokensFound Gitlab Tokens (max $iSince days old) .. critical: $iCountCritical ($iCriticalLimit days) .. warnings: $iCountWarn ($iWarnLimit days)"
 
echo
 
 
echo "$output"
 
rm -f /tmp/gitlab-tokens.json /tmp/gitlab-users.json
 
\ No newline at end of file
Loading