skip to Main Content

I have a file "results.json"

It looks like this

{
    "applicationId" : "application",
    "scanId" : "scanId",
    "policyEvaluationResult" : {
      "alerts" : [ {
        "trigger" : {
          "policyId" : "pid1",
          "policyName" : "Security-High",
          "threatLevel" : 9,
          "policyViolationId" : "pvid1",
        },
        "trigger" : {
          "policyId" : "pid2",
          "policyName" : "Security-Low",
          "threatLevel" : 1,
          "policyViolationId" : "pvid2",
        },
        ...
        }]
    }
}

It has multiple "trigger" objects.

I’m trying to write a bash/shell script which checks this file using jq and if it sees that any of the "trigger" objects contain a threatLevel greater than or equal to a variable defined in GitLab CI/CD variables.

If so, it will echo out a failure message and return exit code 1, otherwise echo a success message and return exit code 0.

I don’t care about returning any actual values of JSON, I just care about a success/fail outcome.

I can’t seem to figure out how to do this.

Any ideas?

At pseudo level I’ve assumed it’s something around the idea of:

if (jq 'any(.threatLevel | contains (>=${THRESHOLD_VALUE}))') results.json; then
    echo 'failing pipeline'
    exit 1
else
    echo 'passing pipeline'
    exit 0
fi

Am I on the right tracks here?

2

Answers


  1. It has multiple "trigger" objects.

    This is not idiomatic JSON. Field names are supposed to be unique. Otherwise, JSON processors may collapse them into one, or fail in any another way, not providing you with the expected behavior.

    With jq, you could overcome this by having it read and evaluate its input in small pieces using the --stream flag, so "past duplicates" would have been processed before the next one would be read.

    if >/dev/null jq --argjson th ${THRESHOLD_VALUE} --stream -en '
      any(inputs | select(.[0][-1] == "threatLevel")[1]; . > $th)' results.json 
    then
        echo 'failing pipeline'
        exit 1
    else
        echo 'passing pipeline'
        exit 0
    fi
    
    Login or Signup to reply.
  2. The syntax of the contains filter is incorrect. You should use the comparison operator ">=" directly instead of "contains".

    Here’s a revised version:

    if jq '[.policyEvaluationResult.alerts[] | select(.trigger.threatLevel >= env.THRESHOLD_VALUE)] | length > 0' results.json >/dev/null; then
        echo 'failing pipeline'
        exit 1
    else
        echo 'passing pipeline'
        exit 0
    fi
    

    I hope this helps!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search