I'm trying to monitor my Jenkins instances by using the Jenkins CLI. Most important are security warnings like given in the Jenkins Security Advisories. Those are shown in the GUI in the upper right corner by red and orange warning symbols:
I can use the CLI to list all my plugins and possible updates for these:
java -jar ./jenkins-cli.jar <host> -auth <token> list-plugins | grep -E '\([0-9].[0-9].*\)'
This returns a three columned list like
docker-commons | Docker Commons Plugin | 1.20 (1.21) |
where 1.20 tells me the currently installed version and (1.21) tells me the currently available version.
But still I could not find a CLI-call to tell whether a listed plugin has a known vulnerability. This information seems only to be available in the GUI?
I found the solution on https://community.jenkins.io/t/jenkins-plugins-security-warnings/2266/2.
It seems there's no native call to get those information. But one can curl the latest information from https://updates.jenkins.io/update-center.actual.json.
Then you probably need to code the rest of it yourself. You find the security alerts in the warnings part of the json. In each warning you find a subsection "versions" where lastVersion probably means the last affected version by this warning. By using the (hopefully well-kept) pattern you can compare your used version to the latestVersion.
I'm currently trying to build a usable bash-script for this task and will update my answer later on when I have finished the script but since I'm not a bash scripting guy this might take a while.
Edit: I got it working. Maybe it's helpful for anyone else, but as I said, I'm not the bash-scripting guy.
#!/bin/bash
DELIMITER=";"
#Getting all information from the Jenkins Update Center
items=$(curl -qLs https://updates.jenkins.io/update-center.actual.json)
#Getting installed plugins from Jenkins
results=$(java -jar jenkins-cli.jar -s <host> -auth <token> list-plugins)
#and writing it to an array.
readarray -t plugins <<<"$results"
for i in "${!plugins[@]}"; do
#keep format (with whitespaces):
#matrix-project Matrix Project Plugin 772.v494f19991984 (785.v06b_7f47b_c631)
formattedLine=$(echo "${plugins[$i]}");
#replace 2 or more whitespaces by the delimiter.
#matrix-project;Matrix Project Plugin;772.v494f19991984 (785.v06b_7f47b_c631)
replacedWhitespaces=$(echo "$formattedLine" | sed "s/ \{2,\}/$DELIMITER/g")
#split result into an array
#[0]matrix-project
#[1]Matrix Project Plugin
#[2]772.v494f19991984 (785.v06b_7f47b_c631)
IFS="$DELIMITER" read -r -a parts <<< "$replacedWhitespaces"
#check whether there is an update available or not
#<=> if there is a () separated by a whitespace or not
if [[ "${parts[2]}" =~ \ |\' ]]
then
IFS=' ' read -r -a subparts <<< "${parts[2]}";
parts[2]=$(echo "${subparts[0]}")
parts[3]=$(echo "${subparts[1]}")
else
parts[3]=""
fi
echo "name: ${parts[0]}"
echo "description: ${parts[1]}"
echo "Used Version: ${parts[2]}"
echo "Latest Version: ${parts[3]}"
echo "Vulnerabilities:"
#find vulnerabilities to this plugin:
vulnerabilities=$(echo "$items" | ./jq-win64 -c -r --arg pluginName "${parts[0]}" '.warnings[] | select(.name==$pluginName)')
#separate vulnerabilities
IFS=$'\n' res=($vulnerabilities)
#get the relevant content from each vulnerability
for r in "${!res[@]}"; do
lastVersion=$(echo "${res[$r]}" | ./jq-win64 -r -c '.versions[0]|.lastVersion')
id=$(echo "${res[$r]}" | ./jq-win64 -r -c '.|.id')
message=$(echo "${res[$r]}" | ./jq-win64 -r -c '.|.message')
url=$(echo "${res[$r]}" | ./jq-win64 -r -c '.|.url')
echo "* <=$lastVersion: $id - $message ($url)";
done;
echo "------------------------------------------------------------"
done