Skip to content
Snippets Groups Projects

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

1 file
+ 237
0
Compare changes
  • Side-by-side
  • Inline
+ 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