123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304 |
- #! /usr/bin/env bash
- # Copyright Materialize, Inc. and contributors. All rights reserved.
- #
- # Use of this software is governed by the Business Source License
- # included in the LICENSE file at the root of this repository.
- #
- # As of the Change Date specified in that file, in accordance with
- # the Business Source License, use of this software will be governed
- # by the Apache License, Version 2.0.
- #
- # shlib.bash — A shell utility library.
- # die [ARGS...]
- #
- # Outputs ARGS to stderr, then exits the script with a failing exit status.
- die() {
- echo "$@" >&2
- exit 1
- }
- # run PROGRAM [ARGS...]
- #
- # Runs PROGRAM, but informs the user first. Specifically, run outputs "PROGRAM
- # ARGS..." to stderr, then executes PROGRAM with the specified ARGS.
- run() {
- echo "\$ $*" >&2
- "$@"
- }
- # command_exists PROGRAM
- #
- # Returns successfully if PROGRAM exists in $PATH, or unsuccessfully otherwise.
- # Outputs nothing.
- command_exists() {
- hash "$1" 2>/dev/null
- }
- # version_compat MINIMUM ACTUAL
- # version_compat [VERSIONS...]
- #
- # Checks whether VERSIONS is in sorted order according to version comparison
- # rules. Typical usage is to provide exactly two versions, in which case the
- # function checks that ACTUAL is greater than or equal to MINIMUM.
- version_compat() {
- printf "%s\n" "$@" | sort --check=silent --version-sort
- }
- # git_empty_tree
- #
- # Outputs the 40-character SHA-1 hash of Git's empty tree object.
- git_empty_tree() {
- git hash-object -t tree /dev/null
- }
- # git_files [PATTERNS...]
- #
- # Lists the files known to Git that match the PATTERNS, with the following
- # differences from `git ls-files`:
- #
- # 1. files matched by a gitignore rule are excluded,
- # 2. deleted but unstaged files are excluded,
- # 3. symlinks are excluded.
- #
- git_files() {
- git diff --ignore-submodules=all --raw "$(git_empty_tree)" -- "$@" \
- | awk '$2 != 120000 {print $6}'
- }
- # try COMMAND [ARGS...]
- #
- # Runs COMMAND with the specified ARGS without aborting the script if the
- # command fails. See also try_last_failed and try_status_report.
- try() {
- ci_collapsed_heading "$@"
- # Try the command.
- if "$@"; then
- result=$?
- try_last_failed=false
- ((++ci_try_passed))
- else
- result=$?
- try_last_failed=true
- # The command failed. Tell Buildkite to uncollapse this log section, so
- # that the errors are immediately visible.
- in_ci && ci_uncollapse_current_section
- echo "^^^ 🚨 Failed: $*"
- fi
- ((++ci_try_total))
- }
- try_last_failed=false
- # try_last_failed
- #
- # Reports whether the last command executed with `try` succeeded or failed.
- try_last_failed() {
- $try_last_failed
- }
- # try_status_report
- #
- # Exits the script with a code that reflects whether all commands executed with
- # `try` were successful.
- try_status_report() {
- ci_uncollapsed_heading "Status report"
- echo "$ci_try_passed/$ci_try_total commands passed"
- if ((ci_try_passed != ci_try_total)); then
- exit 1
- fi
- }
- ci_unimportant_heading() {
- echo "~~~" "$@" >&2
- }
- ci_collapsed_heading() {
- echo "---" "$@" >&2
- }
- ci_uncollapsed_heading() {
- echo "+++" "$@" >&2
- }
- ci_uncollapse_current_section() {
- if in_ci; then
- echo "^^^ +++" >&2
- fi
- }
- ci_try_passed=0
- ci_try_total=0
- # read_list PREFIX
- #
- # Appends the environment variables `PREFIX_0`, `PREFIX_1`, ... `PREFIX_N` to
- # the `result` global variable, stopping when `PREFIX_N` is an empty string.
- read_list() {
- result=()
- local i=0
- local param="${1}_${i}"
- if [[ "${!1:-}" ]]; then
- echo "error: mzcompose command must be an array, not a string" >&2
- exit 1
- fi
- while [[ "${!param:-}" ]]; do
- result+=("${!param}")
- i=$((i+1))
- param="${1}_${i}"
- done
- [[ ${#result[@]} -gt 0 ]] || return 1
- }
- # mapfile_shim [array]
- #
- # A limited backport of the Bash 4.0 `mapfile` built-in. Reads lines from the
- # standard input into the indexed array variable ARRAY. If ARRAY is unspecified,
- # the variable MAPFILE is used instead. Other options of `mapfile` are not
- # supported.
- mapfile_shim() {
- local val
- val=()
- while IFS= read -r line; do
- val+=("$line")
- done
- declare -ag "${1:-MAPFILE}=($(printf "%q " "${val[@]}"))"
- }
- # arch_gcc
- #
- # Computes the host architecture using GCC nomenclature: x86_64 or aarch64.
- # Dies if the host architecture is unknown.
- arch_gcc() {
- local arch
- arch=$(uname -m)
- case "$arch" in
- x86_64|aarch64) echo "$arch" ;;
- arm64) echo aarch64 ;;
- *) die "unknown host architecture \"$arch\"" ;;
- esac
- }
- # arch_go [ARCH-GCC]
- #
- # Converts ARCH-GCC to Go nomenclature: amd64 or arm64. If ARCH-GCC is not
- # specified, uses the host architecture.
- arch_go() {
- local arch=${1:-$(arch_gcc)}
- case "$arch" in
- x86_64) echo amd64 ;;
- aarch64) echo arm64 ;;
- *) die "unknown host architecture \"$arch\"" ;;
- esac
- }
- # red [ARGS...]
- #
- # Prints the provided text in red.
- red() {
- echo -ne "\e[31m$*\e[0m"
- }
- # green [ARGS...]
- #
- # Prints the provided text in green.
- green() {
- echo -ne "\e[32m$*\e[0m"
- }
- # white [ARGS...]
- #
- # Prints the provided text in white.
- white() {
- echo -ne "\e[97m$*\e[0m"
- }
- # in_ci
- #
- # Returns 0 if in CI and 1 otherwise
- in_ci() {
- [ -z "${BUILDKITE-}" ] && return 1
- return 0
- }
- # is_truthy VAR
- #
- # Returns 0 if the parameter is not one of: 0, '', no, false; and 1 otherwise
- is_truthy() {
- if [[ "$1" == "0" || "$1" == "" || "$1" == "no" || "$1" == "false" ]]; then
- return 1
- fi
- return 0
- }
- # trufflehog_jq_filter_common
- #
- # Filters out secrets we expect in both checked in files and logs
- trufflehog_jq_filter_common() {
- jq -c '
- select(
- .Raw != "postgres://mz_system:materialize@materialized:5432" and
- .Raw != "postgres://materialize:materialize@materialized:6875" and
- .Raw != "postgres://mz_system:materialize@materialized:6877" and
- .Raw != "postgres://superuser_login:some_bogus_password@materialized2:6875" and
- .Raw != "jdbc:postgresql://127.0.0.1:26257/defaultdb?sslmode=disable" and
- .Raw != "postgres://any:user@materialized:6875" and
- .Raw != "https://materialize:sekurity@schema-registry:8081" and
- .Raw != "postgresql://postgres:postgres@postgres:5432" and
- .Raw != "postgres://postgres:postgres@postgres:5432" and
- .Raw != "sub-c-4377ab04-f100-11e3-bffd-02ee2ddab7fe" and
- .Raw != "jdbc:postgresql://localhost:6875/materialize" and
- .Raw != "postgres://yugabyte:yugabyte@yugabyte:5433" and
- .Raw != "postgres://materialize_user:materialize_pass@postgres.materialize.svc.cluster.local:5432" and
- .Raw != "jdbc:postgresql://%s:%s/materialize" and
- .Raw != "postgres://postgres:$MATERIALIZE_PROD_SANDBOX_RDS_PASSWORD@$MATERIALIZE_PROD_SANDBOX_RDS_HOSTNAME:5432" and
- .Raw != "http://user:pass@example.com" and
- .Raw != "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDDC5MP3v1BHOgI\n5SsmrW8mjxzQGOz0IlC5jp1muW/kpEoE9TG317TEnO5Uye6zZudkFCP8YGEiN3Mc\nFbTM7eX6PjAPdnGU7khuUt/20ZM+NX5kWZPrmPTh4WQaDCL7ah1LqzBaUAMaSXq8\niuy7LGJNF8wdx8L5BjDiGTTxZXOg0Haxknc7Mbiwc9z8eb7omvzQzsOwyqocrF2u\nz86TzX1jtHP48i5CxoRHKxE94De3tNxjT/Y3OZlS4QS7iekAOQ04DVV3GIHvRUXN\n2H8ayy4+yOdhHn6ER5Jn3lti1Q5XSrxkrYn7L1Vcj6IwZQhhF5vc+ovxOYb+8ert\nEo97tIkLAgMBAAECggEAQteHHRPKz9Mzs8Sxvo4GPv0hnzFDl0DhUE4PJCKdtYoV\n8dADq2DJiu3LAZS4cJPt7Y63bGitMRg2oyPPM8G9pD5Goy3wq9zjRqexKDlXUCTt\n/T7zofRny7c94m1RWb7ablGq/vBXt90BqnajvVtvDsN+iKAqccQM4ZdI3QdrEmt1\ncHex924itzG/mqbFTAfAmVj1ZsRnJp55Txy2gqq7jX00xDM8+H49SRvUu49N64LQ\n6BUWCgWCJePRtgjSHjboAzPqSkMdaTE/WDY2zgGF3Qfq4f6JCHKfm4QylCH4gYUU\n1Kf7ttmhu9NoZO+hczobKkxP9RtXfyTRH2bsJXy2HQKBgQDhHgavxk/ln5mdMGGw\nrQud2vF9n7UwFiysYxocIC5/CWD0GAhnawchjPypbW/7vKM5Z9zhW3eH1U9P13sa\n2xHfrU5BZ16rxoBbKNpcr7VeEbUBAsDoGV24xjoecp7rB2hZ+mGik5/5Ig1Rk1KH\ndcvYy2KSi1h4Sm+mXwimmA4VDQKBgQDdzW+5FPbdM2sUB2gLMQtn3ICjDSu6IQ+k\nd0p3WlTIT51RUsPXXKkk96O5anUbeB3syY8tSKPGggsaXaeL3o09yIamtERgCnn3\nd9IS+4VKPWQlFUICU1KrD+TO7IYIX04iXBuVE5ihv0q3mslhDotmX4kS38NtKEFF\njLjA2RvAdwKBgAFkIxxw+Ett+hALnX7vAtRd5wIku4TpjisejanA1Si50RyRDXQ+\nKBQf/+u4HmoK12Nibe4Cl7GCMvRGW59l3S1pr8MdtWsQVfi6Puc1usQzDdBMyQ5m\nIbsjlnZbtPm02QM9Vd8gVGvAtx5a77aglrrnPtuy+r/7jccUbURCSkv9AoGAH9m3\nWGmVRZBzqO2jWDATxjdY1ZE3nUPQHjrvG5KCKD2ehqYO72cj9uYEwcRyyp4GFhGf\nmM4cjo3wEDowrBoqSBv6kgfC5dO7TfkL1qP9sPp93gFeeD0E2wGuRrSaTqt46eA2\nKcMloNx6W0FD98cB55KCeY5eXtdwAA/EHBVRMeMCgYAd3n6PcL6rVXyE3+wRTKK4\n+zvx5sjTAnljr5ttbEnpZafzrYIfDpB8NNjexy83AeC0O13LvSHIFoTwP8sywJRO\nRxbPMjhEBdVZ5NxlxYer7yKN+h5OBJfrLswPku7y4vdFYK3x/lMuNQO61hb1VFHc\nT2BDTbF0QSlPxFsv18B9zg==\n-----END PRIVATE KEY-----\n" and
- .Raw != "postgres://materialize:materialize@environmentd:6875" and
- .Raw != "postgres://MATERIALIZE_USERNAME:APP_SPECIFIC_PASSWORD@MATERIALIZE_HOST:6875" and
- .Raw != "jdbc:postgresql://MATERIALIZE_HOST:6875/materialize" and
- .Raw != "postgres://user:password@host:6875" and
- .Raw != "postgres" and
- .Raw != "slt" and
- .Raw != "e6d5833015b170e23ae819e8c5d7eaedb472ca98" and
- .Raw != "postgresql://materialize:AbC123dEf@ep-cool-darkness-123456.us-east-2.aws.neon.tech:5432" and
- .Raw != "d3aa325086974cdfb3912f28e5a8c168"
- )'
- }
- # trufflehog_jq_filter_files
- #
- # Filters out secrets we expect only in checked in files
- trufflehog_jq_filter_files() {
- trufflehog_jq_filter_common | jq -c '
- select(
- .Raw != "ghp_9fK8sL3x7TqR1vEzYm2pDaN4WjXbQzUtV0aN"
- )'
- }
- # trufflehog_jq_filter_logs
- #
- # Filters out secrets we expect only in logs during CI runs
- trufflehog_jq_filter_logs() {
- trufflehog_jq_filter_common | jq -c '
- select(
- (.Raw | contains("mz_system:materialize") | not) and
- (.Raw | contains("jdbc:postgresql://postgres") | not) and
- (.Raw | contains("mz_analytics:materialize") | not) and
- (.Raw | contains("mz_support:materialize") | not) and
- (.Raw | contains("jdbc:mysql://mysql") | not) and
- (.Raw | contains("superuser_login:some_bogus_password") | not) and
- (.Raw | contains("postgres:postgres") | not) and
- (.Raw | contains("jdbc:postgresql://127.0.0") | not) and
- (.Raw | contains("jdbc:postgresql://cockroach") | not) and
- (.Raw | contains("materialize:materialize") | not) and
- (.Raw | contains("ExpirationReaper") | not) and
- (.Raw | contains("u1@example.com") | not) and
- .Raw != "[REDACTED]"
- )'
- }
|