#!/usr/bin/env bash
# Prowler - the handy cloud security tool (copyright 2018) by Toni de la Fuente
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
# Generates JUnit XML reports which can be read by Jenkins or other CI tools
JUNIT_OUTPUT_DIRECTORY="junit-reports"
is_junit_output_enabled() {
if [[ " ${MODES[@]} " =~ " junit-xml " ]]; then
true
else
false
fi
}
xml_escape() {
sed 's/&/\&/g; s/\</g; s/>/\>/g; s/\"/\"/g; s/'"'"'/\'/g' <<< "$1"
}
prepare_junit_output() {
# Remove any JUnit output from previous runs
rm -rf "$JUNIT_OUTPUT_DIRECTORY"
mkdir "$JUNIT_OUTPUT_DIRECTORY"
echo ""
echo "$NOTICE Writing JUnit XML reports to $PROWLER_DIR/$JUNIT_OUTPUT_DIRECTORY $NORMAL"
}
prepare_junit_check_output() {
# JUnit test cases must be named uniquely, but each Prowler check can output many times due to multiple resources,
# therefore append an index value to the test case name to provide uniqueness, reset it to 1 before starting this check
JUNIT_CHECK_INDEX=1
# To match JUnit behaviour in Java, and ensure that an aborted execution does not leave a partially written and therefore invalid XML file,
# output a JUnit XML file per check
JUNIT_OUTPUT_FILE="$JUNIT_OUTPUT_DIRECTORY/TEST-$1.xml"
printf '%s\n' \
"" \
"" \
" " \
" " \
" " \
" " \
" " \
" " \
" " \
" " \
" " \
" " \
> "$JUNIT_OUTPUT_FILE"
JUNIT_CHECK_START_TIME=$(get_time_in_milliseconds)
}
finalise_junit_check_output() {
echo '' >> "$JUNIT_OUTPUT_FILE"
}
output_junit_success() {
output_junit_test_case "$1" "$(xml_escape "$1")"
}
output_junit_info() {
# Nothing to output for JUnit for this level of message, but reset the check timer for timing the next check
JUNIT_CHECK_START_TIME=$(get_time_in_milliseconds)
}
output_junit_failure() {
output_junit_test_case "$1" ""
}
get_junit_classname() {
# . naturally follows a Java package structure, so it is suitable as a package name
echo "$TITLE_ID"
}
output_junit_test_case() {
local time_now
local test_case_duration
time_now=$(get_time_in_milliseconds)
# JUnit test case time values are in seconds, so divide by 1000 using e-3 to convert from milliseconds without losing accuracy due to non-floating point arithmetic
test_case_duration=$(printf "%.3f" "$((time_now - JUNIT_CHECK_START_TIME))e-3")
printf '%s\n' \
" " \
" $2" \
" " >> "$JUNIT_OUTPUT_FILE"
# Reset the check timer for timing the next check
JUNIT_CHECK_START_TIME=$(get_time_in_milliseconds)
((JUNIT_CHECK_INDEX+=1))
}