github.com/argoproj/argo-cd/v2@v2.10.9/hack/snyk-report.sh (about) 1 #!/usr/bin/env bash 2 3 set -e 4 set -o pipefail 5 6 npm install snyk snyk-to-html --location=global 7 8 # Choose the branch where docs changes will actually be written. 9 target_branch="$1" 10 if [ "$target_branch" != "" ]; then 11 git checkout "$target_branch" 12 fi 13 14 # In case the directory doesn't exist in the target branch. 15 mkdir -p docs/snyk 16 17 # Clear the docs directory in case we need to delete an old version. 18 rm -rf docs/snyk/* 19 20 cat > docs/snyk/index.md <<- EOM 21 # Snyk Scans 22 23 Every Sunday, Snyk scans are generated for Argo CD's \`master\` branch and the most recent patches of the three most 24 recent minor releases. 25 26 !!! note 27 For the most recent scans, view the [\`latest\` version of the docs](https://argo-cd.readthedocs.io/en/latest/snyk/). 28 You can return to your preferred version of the docs site using the dropdown selector at the top of the page. 29 30 ## Scans 31 EOM 32 33 argocd_dir=$(pwd) 34 temp_dir=$(mktemp -d) 35 cd "$temp_dir" 36 git clone https://github.com/argoproj/argo-cd.git 37 cd argo-cd 38 git checkout master 39 40 minor_version=$(git tag -l | sort -g | tail -n 1 | grep -Eo '[0-9]+\.[0-9]+') 41 patch_num=$(git tag -l | grep "v$minor_version." | grep -o "[a-z[:digit:]-]*$" | sort -g | tail -n 1) 42 version="v$minor_version.$patch_num" 43 versions="master " 44 45 version_count=3 46 # When the most recent version is still a release candidate, get reports for 4 versions (so the 3 most recent stable 47 # releases are included). 48 if [[ $patch_num == "0-rc"* ]]; then version_count=4; fi 49 50 for i in $(seq "$version_count"); do 51 if [ "$version" == "" ]; then break; fi 52 # Nightmare code to get the most recent patches of the three most recent minor versions. 53 versions+="$version " 54 minor_num=$(printf '%s' "$minor_version" | sed -E 's/[0-9]+\.//') 55 minor_num=$((minor_num-1)) 56 minor_version=$(printf '%s' "$minor_version" | sed -E "s/\.[0-9]+$/.$minor_num/g") 57 patch_num=$(git tag -l | grep "v$minor_version." | grep -o "[a-z[:digit:]-]*$" | sort -g | tail -n 1) 58 version="v$minor_version.$patch_num" 59 done 60 61 for version in $versions; do 62 printf '\n%s\n\n' "### $version" >> "$argocd_dir/docs/snyk/index.md" 63 64 mkdir -p "$argocd_dir/docs/snyk/$version" 65 66 git reset --hard # reset any pending changes to avoid checkout errors 67 git checkout "$version" 68 69 # Get the latest ignore rules. 70 cp "$argocd_dir/.snyk" .snyk 71 72 # || [ $? == 1 ] ignores errors due to vulnerabilities. 73 snyk test --all-projects --exclude=docs,site,ui-test --org=argoproj --policy-path=.snyk --sarif-file-output=/tmp/argocd-test.sarif --json-file-output=/tmp/argocd-test.json || [ $? == 1 ] 74 snyk-to-html -i /tmp/argocd-test.json -o "$argocd_dir/docs/snyk/$version/argocd-test.html" 75 { echo "| | Critical | High | Medium | Low |" 76 echo "|---:|:--------:|:----:|:------:|:---:|" 77 } >> "$argocd_dir/docs/snyk/index.md" 78 jq 'map( 79 { 80 # Collect all the vulnerabilities severities. Group by id to avoid double-counting. 81 severity: (.vulnerabilities | group_by(.id) | map(.[0])[].severity), 82 displayTargetFile: (.displayTargetFile) 83 } 84 ) 85 # Hack to make sure even if there are no vulnerabilities, a row is added to the table. 86 + [{displayTargetFile: "go.mod"}, {displayTargetFile: "ui/yarn.lock"}] 87 # Group by target file (e.g. go.mod) so we can see where the vulnerabilities are. 88 | group_by(.displayTargetFile) 89 | map( 90 "| [\(.[0].displayTargetFile)](\($version)/argocd-test.html) " 91 + "| \(map(select(.severity == "critical")) | length) " 92 + "| \(map(select(.severity == "high")) | length) " 93 + "| \(map(select(.severity == "medium")) | length) " 94 + "| \(map(select(.severity == "low")) | length) |") 95 | join("\n")' --arg version "$version" -r /tmp/argocd-test.json >> "$argocd_dir/docs/snyk/index.md" 96 97 98 images=$(grep 'image: ' manifests/install.yaml manifests/namespace-install.yaml manifests/ha/install.yaml | sed 's/.*image: //' | sort | uniq) 99 100 while IFS= read -r image; do 101 extra_args="" 102 if echo "$image" | grep "argocd"; then 103 # Pass the file arg only for the Argo CD image. The file arg also gives us access to sarif output. 104 extra_args="--file=Dockerfile --sarif-file-output=/tmp/${image//[\/:]/_}.sarif " 105 fi 106 107 set -x 108 # || [ $? == 1 ] ignores errors due to vulnerabilities. 109 snyk container test "$image" --org=argoproj "--json-file-output=/tmp/${image//[\/:]/_}.json" $extra_args || [ $? == 1 ] 110 set +x 111 112 snyk-to-html -i "/tmp/${image//[\/:]/_}.json" -o "$argocd_dir/docs/snyk/$version/${image//[\/:]/_}.html" 113 114 printf '%s' "| [${image/*\//}]($version/${image//[\/:]/_}.html) | " >> "$argocd_dir/docs/snyk/index.md" 115 116 # Add severity counts to index. 117 jq '[ 118 .vulnerabilities 119 # Group by ID to avoid double-counting. 120 | group_by(.id) 121 # Get the severity of the first vulnerability in the group (should be the same for every item in the group). 122 | map(.[0])[].severity 123 # Construct a summary using the counts of each severity level. 124 ] | "\(map(select(. == "critical")) | length) | \(map(select(. == "high")) | length) | \(map(select(. == "medium")) | length) | \(map(select(. == "low")) | length) |" 125 ' -r "/tmp/${image//[\/:]/_}.json" >> "$argocd_dir/docs/snyk/index.md" 126 done <<< "$images" 127 128 # || [ $? == 1 ] ignores errors due to vulnerabilities. 129 snyk iac test manifests/install.yaml --org=argoproj --policy-path=.snyk --sarif-file-output=/tmp/argocd-iac-install.sarif --json-file-output=/tmp/argocd-iac-install.json || [ $? == 1 ] 130 snyk-to-html -i /tmp/argocd-iac-install.json -o "$argocd_dir/docs/snyk/$version/argocd-iac-install.html" 131 echo "| [install.yaml]($version/argocd-iac-install.html) | - | - | - | - |" >> "$argocd_dir/docs/snyk/index.md" 132 133 # || [ $? == 1 ] ignores errors due to vulnerabilities. 134 snyk iac test manifests/namespace-install.yaml --org=argoproj --policy-path=.snyk --sarif-file-output=/tmp/argocd-iac-namespace-install.sarif --json-file-output=/tmp/argocd-iac-namespace-install.json || [ $? == 1 ] 135 snyk-to-html -i /tmp/argocd-iac-namespace-install.json -o "$argocd_dir/docs/snyk/$version/argocd-iac-namespace-install.html" 136 echo "| [namespace-install.yaml]($version/argocd-iac-namespace-install.html) | - | - | - | - |" >> "$argocd_dir/docs/snyk/index.md" 137 done 138 139 # clean up 140 cd "$argocd_dir" # Back to the main argo-cd clone. 141 rm -rf "$temp_dir" 142 143 # regex-escape the temp dir path 144 dir_r="${temp_dir//\//\\\/}" 145 146 # Make sed -i cross-platform: https://stackoverflow.com/a/51060063/684776 147 sedi=(-i) 148 case "$(uname)" in 149 Darwin*) sedi=(-i "") 150 esac 151 152 # remove temp dir path from Snyk output 153 sed "${sedi[@]}" "s/$dir_r//g" docs/snyk/*/*.html