github.com/argoproj/argo-cd/v3@v3.2.1/hack/snyk-report.sh (about)

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