#!/usr/bin/env bash set -u set -o pipefail VERSION=0.4.1 SCRIPT_VERSION="image_scan.sh@${VERSION}" SCAN_URL="https://mw-receiver.yamory.io/image/scan/trivy" SCAN_RESULT_URL="https://mw-receiver.yamory.io/image/scan/result" IMAGE_WEB_URL="https://app.yamory.io/images/scan" findWhich() { WHICH="" if [ -x /bin/which ]; then WHICH=/bin/which elif [ -x /usr/bin/which ]; then WHICH=/usr/bin/which else if [ -x /bin/type ]; then WHICH="/bin/type -p" elif [ -x /usr/bin/type ]; then WHICH="/usr/bin/type -p" else WHICH="" fi fi } findGzip() { if [ -x /bin/gzip ]; then GZIP=/bin/gzip elif [ -x /usr/bin/gzip ]; then GZIP=/usr/bin/gzip elif [ -n "${WHICH}" -a -x "$("${WHICH}" gzip 2>/dev/null)" ]; then GZIP="$(${WHICH} gzip 2>/dev/null)" else GZIP="" fi } findCurl() { if [ -x /bin/curl ]; then CURL=/bin/curl elif [ -x /usr/bin/curl ]; then CURL=/usr/bin/curl elif [ -n "${WHICH}" -a -x "$(${WHICH} curl 2>/dev/null)" ]; then CURL="$(${WHICH} curl 2>/dev/null)" else CURL="" fi } findTrivy() { if [ -x ./trivy -a -f ./trivy ]; then TRIVY=./trivy elif [ -x /bin/trivy ]; then TRIVY=/bin/trivy elif [ -x /usr/bin/trivy ]; then TRIVY=/usr/bin/trivy elif [ -x /usr/local/bin/trivy ]; then TRIVY=/usr/local/bin/trivy elif [ -n "${WHICH}" -a -x "$(${WHICH} trivy 2>/dev/null)" ]; then TRIVY="$(${WHICH} trivy 2>/dev/null)" else TRIVY="" fi } int() { exit 130 # 128 + SIGINT } trap int INT if [ -z "${SCAN_URL}" ]; then echo "SCAN_URL is not specified." >&2 exit 1 fi if [ -z "${YAMORY_ACCESS_TOKEN}" ]; then echo "YAMORY_ACCESS_TOKEN is not specified." >&2 exit 1 fi if [ -z "${YAMORY_IMAGE_NAME}" ]; then echo "YAMORY_IMAGE_NAME is not specified." >&2 exit 1 fi findWhich if [ -z "${WHICH}" ]; then echo "which or type is not specified." >&2 exit 1 fi findGzip if [ -z "${GZIP}" ]; then echo "gzip is not specified." >&2 exit 1 fi findCurl if [ -z "${CURL}" ]; then echo "curl is not specified." >&2 exit 1 fi findTrivy if [ -z "${TRIVY}" ]; then echo "trivy is not specified." >&2 exit 1 fi echo -e "Scan start!!\nThis scan might take a few minutes...\n" TRIVY_OPTS="" if [ "${TRIVY_DEBUG:-""}" = "" ]; then TRIVY_OPTS="-q" fi TRIVY_RESPONSE=$("${TRIVY}" ${TRIVY_OPTS} image -f=json --list-all-pkgs --ignore-unfixed ${YAMORY_IMAGE_NAME}) if [ $? -ne 0 ]; then echo "trivy execution error." >&2 exit 1 fi RESP=$(echo ${TRIVY_RESPONSE} | "${GZIP}" -c | "${CURL}" -sSL --max-time 60 -w '%{http_code}\n' -X POST \ -H "X-YAMORY-API-KEY: ${YAMORY_ACCESS_TOKEN}" \ -F "trivyResult=@-" \ -F "requestParam={ \ \"token\": \"${YAMORY_ACCESS_TOKEN}\", \ \"cliVersion\": \"${VERSION}\", \ \"title\": \"${YAMORY_IMAGE_TITLE:-""}\", \ \"identifier\": \"${YAMORY_IMAGE_IDENTIFIER:-""}\", \ \"imageName\": \"${YAMORY_IMAGE_NAME}\", \ \"openSystem\": \"${YAMORY_OPEN_CONTAINER:-null}\",\ \"tagNames\": \"${YAMORY_IMAGE_TAGS:-""}\" \ };type=application/json" \ ${SCAN_URL} 2>/dev/null) RET=$? REQUEST_ID=${RESP/%???/} HTTP_RESPONSE=${RESP: -3} case ${RET} in 0) if [ ${HTTP_RESPONSE} -eq "200" ]; then SR_URL="${SCAN_RESULT_URL}/${REQUEST_ID}" MAX_COUNT=12 for CNT in $(seq 1 ${MAX_COUNT}); do sleep 5 SR_RESP=$("${CURL}" -sSL --max-time 60 -w '%{http_code}\n' -X GET "${SR_URL}" \ -H "content-type: text/plain" \ -H "X-YAMORY-API-KEY: ${YAMORY_ACCESS_TOKEN}" \ -H "X-CLI-VERSION: ${SCRIPT_VERSION}" 2>/dev/null) SR_RET=$? case ${SR_RET} in 0) SR_BODY=${SR_RESP/%???/} SR_HTTP_RESPONSE=${SR_RESP: -3} if [ ${SR_HTTP_RESPONSE} -eq "200" ]; then IMMEDIATE=$(echo "${SR_BODY}" | cut -d ',' -f 1) TOTAL=$(echo "${SR_BODY}" | cut -d ',' -f 2) LINK=$(echo "${SR_BODY}" | cut -d ',' -f 3) echo "Vulnerabilities (I: Immediate, T: Total)" echo "I:${IMMEDIATE}" echo "T:${TOTAL}" echo "" echo "Explore below after few minutes" echo "${IMAGE_WEB_URL}/${LINK}" break elif [ ${SR_HTTP_RESPONSE} -eq "204" ]; then if [ ${CNT} -eq ${MAX_COUNT} ]; then echo "Request is received." >&2 break else : # retry fi elif [ ${SR_HTTP_RESPONSE} -eq "400" ]; then if [ -z "${SR_BODY}" ]; then echo "Failed to scan. response=${SR_HTTP_RESPONSE}" >&2 else echo "Failed to scan. response=${SR_HTTP_RESPONSE}, message=${SR_BODY}" >&2 fi SR_RET=1 break else if [ -z "${SR_BODY}" ]; then echo "Failed to get scan result. response=${SR_HTTP_RESPONSE}" >&2 else echo "Failed to get scan result. response=${SR_HTTP_RESPONSE}, message=${SR_BODY}" >&2 fi SR_RET=1 break fi ;; 7) echo "Failed to connect to ${SR_URL}" >&2;break;; 28) echo "Request is received." >&2;break;; *) echo "cURL error. code=${SR_RET}" >&2;break;; esac done exit ${SR_RET} else echo "" if [ -z "${REQUEST_ID}" ]; then echo "Failed to scan. response=${HTTP_RESPONSE}" >&2 else echo "Failed to scan. response=${HTTP_RESPONSE}, message=${REQUEST_ID}" >&2 fi RET=1 fi ;; 7) echo "Failed to connect to ${SCAN_URL}" >&2;; 28) echo "Request is received." >&2;; *) echo "cURL error. code=${RET}" >&2;; esac exit ${RET}