Skip to content
Snippets Groups Projects
Commit 515de85a authored by Hahn Axel (hahn)'s avatar Hahn Axel (hahn)
Browse files

set version 1.0 for check_gitlab_token

parent ef34e1e9
No related branches found
No related tags found
1 merge request!278OP#7546 Icinga Check für ablaufende Gitlab tokens https://projects.iml.unibe.ch/work_packages/7546
#!/bin/bash
# ======================================================================
#
# Check Gitlab tokens
# Check Gitlab tokens of groups and projects.
# It warns if tokens expire soon.
#
# requirements:
# - inc/rest-api-client.sh
# - curl
#
# ----------------------------------------------------------------------
# 2024-10-25 v0.0 <axel.hahn@iml.unibe.ch>
# 2024-10-29 v1.0 <axel.hahn@iml.unibe.ch>
# ======================================================================
cd "$( dirname "$0" )" || exit
. "$( dirname $0 )/inc_pluginfunctions" || exit 1
export self_APPVERSION=0.1
export self_APPVERSION=1.0
GITLAB_API='https://gitlab.example.com/api/v4'
GITLAB_TOKEN='glpat-12345678'
......@@ -24,6 +24,11 @@ GITLAB_TOKEN='glpat-12345678'
GITLAB_CONFIG=/etc/icinga2/gitlab.cfg
REST_CLIENT="$( dirname $0 )/../inc/rest-api-client.sh"
projectUrls=
OUT_TOKENS=/tmp/gitlab-tokens__$USER.json
OUT_USERS=/tmp/gitlab-users__$USER.json
typeset -i iSince=395
typeset -i iTokenCount
typeset -i iTokensFound
......@@ -35,19 +40,20 @@ typeset -i iCriticalLimit=10
typeset -i iCountWarn=0
typeset -i iCountCritical=0
output=""
# ----------------------------------------------------------------------
# functions
# ----------------------------------------------------------------------
# Show help
function showHelp(){
local _self; _self=$(basename $0)
cat <<EOF
$( ph.showImlHelpHeader )
Check gitlab tokens and warn if a token expires soon.
Check gitlab tokens and warn if tokens expire soon.
This check fetches the gitlbab tokens created in the last $iSince days
from the Gitlab API. It skips
......@@ -55,8 +61,11 @@ from the Gitlab API. It skips
- personal access tokens of users
- revoked tokens
The script can run several seconds depending on count of tokens, projects
and users. Maybe you want to call it with a longer interval.
SYNTAX:
$_self [-w WARN_LIMIT] [-c CRITICAL_LIMIT]
$_self [OPTIONS]
OPTIONS:
......@@ -74,13 +83,22 @@ PARAMETERS:
None.
EXAMPLE:
$(basename $0) -w 28 -c 7
EXAMPLES:
$_self -w 28 -c 7
Set other warning and critical level
$_self -g ./gitlab.cfg
Set a custom gitlab config file
$_self -r /opt/bash-api-client/bash-api-client.sh
Set a custom gitlab config file
EOF
}
# Ffetch data from gitlab api with page requests
# Fetch data from gitlab api with multiple page requests
#
# param string url
# param string output file
# param int optional: number of items per page; default: 100
......@@ -104,7 +122,7 @@ function _getPagesToFile(){
echo "ERROR: Request failed: $pageUrl"
http.getResponseHeader
http.getResponse
exit 1
ph.abort
fi
# if response is "[]" then we are done
......@@ -117,8 +135,45 @@ function _getPagesToFile(){
done
}
# Get web link of a project to see its tokens
#
# global string projectUrls string to cache project name + link
#
# param string username eg. projects_14_bot_nnnnnn
# return string
function getWeblink(){
local myusername="$1"
sType=$( cut -f 1 -d "_" <<< "$myusername" )s
# sType is one of users|projects
sId2=$( cut -f 2 -d "_" <<< "$myusername" )
local data
local myurl
if ! grep -q "^/$sType/$sId2:" <<< "$projectUrls" ; then
http.makeRequest "/$sType/$sId2"
if ! http.isOk > /dev/null; then
echo "ERROR: Request /$sType/$sId2 failed: $pageUrl"
http.getResponseHeader
http.getResponse
ph.abort
fi
data="$( http.getResponse )"
myname=$( getKey "$data" "name" )
myurl=$( getKey "$data" "web_url" )
if [ -n "$myurl" ]; then
projectUrls+="/$sType/$sId2:$myname <$myurl/-/settings/access_tokens>$NL"
fi
fi
grep "^/$sType/$sId2:" <<< "$projectUrls" | cut -f 2- -d ":"
}
# Get a single value from json
# param string json data
# param string key
# return string
function getKey(){
echo "$1" | jq -r ".$2" | grep -v "null"
jq -r ".$2" <<< "$1" | grep -v "null"
}
# ----------------------------------------------------------------------
......@@ -156,26 +211,23 @@ 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
# get all tokens
# see https://docs.gitlab.com/ee/api/personal_access_tokens.html
_getPagesToFile "/personal_access_tokens/?revoked=false&created_after=${startdate}" "$OUT_TOKENS"
# get all users
# see https://docs.gitlab.com/ee/api/users.html
_getPagesToFile "/users?exclude_humans=true&exclude_external=true&exclude_internal=true&created_after=${startdate}&search=_bot_" "$OUT_USERS"
# 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
iTokenCount=$( jq ".[].id " < "$OUT_TOKENS" | wc -l )
iTokensFound=0
for i in $( seq 1 $iTokenCount )
do
# get nth token
entry="$( cat /tmp/gitlab-tokens.json | jq ".[$i]" )"
entry="$( jq ".[$i]" < "$OUT_TOKENS")"
# hide non active tokens
if [ "$( getKey "$entry" "active" )" = "false" ]; then
......@@ -190,7 +242,7 @@ do
# 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 '"') "
myusername="$( jq ".[] | select(.id == $sUserid)" < "$OUT_USERS" | jq ".username" | cut -f 1-3 -d "_" | tr -d '"') "
if ! grep -q "_[0-9]*_bot" <<< "$myusername" ; then
continue
fi
......@@ -215,12 +267,9 @@ do
fi
fi
# url of owning group (is that useful?)
sType=$( cut -f 1 -d "_" <<< "$myusername" )s
sId2=$( cut -f 2 -d "_" <<< "$myusername" )
myurl="$GITLAB_API/$sType/$sId2"
myproject="$( getWeblink "$myusername" )"
output+="$sExpire $sStatus $sName $myusername $myurl${NL}"
output+="$sExpire $sStatus $sName - $myproject${NL}"
done
......@@ -236,4 +285,10 @@ ph.status "$iTokensFound Gitlab Tokens (max $iSince days old) .. critical: $iCou
echo
echo "$output"
rm -f /tmp/gitlab-tokens.json /tmp/gitlab-users.json
\ No newline at end of file
# cleanup
rm -f "$OUT_TOKENS" "$OUT_USERS"
ph.exit
# ----------------------------------------------------------------------
......@@ -4,12 +4,36 @@
**check_gitlab_tokens** checks all newer tokens of projects and groups if they expire soon. You can set a warning and a critical level in days.
Gitlab has an api requrest `/personal_access_tokens` but it doesn't have the information about the project or usergroup where it is defined.
This check executes additional requests to show it and offers the url to the web linkinterface.
The check returns
* unknown - the http request to gitlab api failed
* critical - min. 1 token is expiring soon
* warning - min. 1 token reached the warning level (and no criritical token was found)
* ok - api request was successful; no critical or warning token was found.
## Requirements
* curl
* Bash REST API client<br>A set of class like functions with a http. prefix. <br>Docs: <https://os-docs.iml.unibe.ch/bash-rest-api-client/>
Extract or Git pull the Bash REST API client somewhere in your filesystem. eg. /opt/bash-api-client/. With the parameter `-r <FILE>` you point to the file `rest-api-client.sh`.
Extract or Git pull the Bash REST API client somewhere in your filesystem. eg. /opt/bash-api-client/. With the parameter `-r <FILE>` you point to the file `rest-api-client.sh`.
## Configuration
The script needs to connect to the Gitlab API.
You need to create a token in a admin group to read all tokens of all projects.
Put 2 bash variabbles into `/etc/icinga2/gitlab.cfg`:
```shell
GITLAB_API='https://gitlab.example.com/api/v4'
GITLAB_TOKEN='glpat-1234567890'
```
You can use another filename for this configuration - but then you need the parameter `-g <FILE>`to reference it.
## Syntax
......@@ -18,7 +42,7 @@ Extract or Git pull the Bash REST API client somewhere in your filesystem. eg. /
______________________________________________________________________
CHECK_GITLAB_TOKENS
v0.1
v1.0
(c) Institute for Medical Education - University of Bern
Licence: GNU GPL 3
......@@ -26,7 +50,7 @@ Licence: GNU GPL 3
https://os-docs.iml.unibe.ch/icinga-checks/Checks/check_gitlab_tokens.html
______________________________________________________________________
Check gitlab tokens and warn if a token expires soon.
Check gitlab tokens and warn if tokens expire soon.
This check fetches the gitlbab tokens created in the last 395 days
from the Gitlab API. It skips
......@@ -34,8 +58,11 @@ from the Gitlab API. It skips
- personal access tokens of users
- revoked tokens
The script can run several seconds depending on count of tokens, projects
and users. Maybe you want to call it with a longer interval.
SYNTAX:
check_gitlab_tokens [-w WARN_LIMIT] [-c CRITICAL_LIMIT]
check_gitlab_tokens [OPTIONS]
OPTIONS:
......@@ -53,30 +80,36 @@ PARAMETERS:
None.
EXAMPLE:
check_gitlab_tokens -w 28 -c 7
EXAMPLES:
```
check_gitlab_tokens -w 28 -c 7
Set other warning and critical level
### Parameters
check_gitlab_tokens -g ./gitlab.cfg
Set a custom gitlab config file
Add directories to check.
Set a directory that is writable for world or prepared to be accessible for the icinga user.
check_gitlab_tokens -r /opt/bash-api-client/bash-api-client.sh
Set a custom gitlab config file
## Configuration
The script needs to connect to the Gitlab API.
You need to create a token in a admin group to read all tokens of all projects.
```
Put 2 bash variabbles into `/etc/icinga2/gitlab.cfg`:
## Example
```shell
GITLAB_API='https://gitlab.example.com/api/v4'
GITLAB_TOKEN='glpat-1234567890'
```
The execution of `check_gitlab_tokens` returns
You can use another filename for this configuration - but then you need the parameter `-g <FILE>`to reference it.
* a status line with found tokens total, count of warning and critical
* one line per token with
* date of expiration
* status; one of OK, warning, critical based on number of days before expiring
* name of thwe token
* name of the project or group
* web link to the token page of the project or group
## Example
```text
OK: 16 Gitlab Tokens (max 395 days old) .. critical: 0 (10 days) .. warnings: 0 (30 days)
`check_gitlab_tokens -r /opt/rest-api-client/rest-api-client.sh`
2025-01-17 OK changelog - demoproject <https://gitlab.example.com/test/demoproject/-/settings/access_tokens>
2025-01-23 OK read_repo - demoproject <https://gitlab.example.com/test/demoproject/-/settings/access_tokens>
2025-03-14 OK api_token - admin <https://gitlab.example.com/admin/sysadminstuff/-/settings/access_tokens>
...
```
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment