google-nomulus/release/schema-verifier/verify_deployed_sql_schema.sh
Weimin Yu d03cd5bb76 Verify schema using Cloud Build (#1627)
* Add tool to compare  golden and actual schema
2022-05-16 16:10:09 -04:00

92 lines
3.6 KiB
Bash
Executable file

#!/bin/bash
# Copyright 2022 The Nomulus Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# This script compares the actual schema in a Cloud SQL database with the golden
# schema in the corresponding release. It detects schema changes made outside
# the normal deployment process, e.g., those made during a troubleshooting
# session that were not cleaned up.
#
# Mounted volumes and required files in them:
# - /secrets/cloud_sql_credential.json: Cloud SQL proxy credential
# - /secrets/schema_deployer_credential.dec the schema_deployer user's
# database login credential.
# - /schema/schema.jar: the jar with the golden schema.
set -e
read -r cloud_sql_instance db_user db_password \
<<<$(cat /secrets/schema_deployer_credential.dec | awk '{print $1, $2, $3}')
# Unpack the golden schema from schema.jar
unzip -p /schema/schema.jar sql/schema/nomulus.golden.sql \
> /schema/nomulus.golden.sql
echo "$(date): Connecting to ${cloud_sql_instance}."
# Set up connection to the Cloud SQL instance.
# For now we use Cloud SQL Proxy to set up a SSL tunnel to the Cloud SQL
# instance. This has two drawbacks:
# - It starts a background process, which is an anti-pattern in Docker.
# - The main job needs to wait for a while for the proxy to come up.
# We will research for a better long-term solution.
#
# Other options considered:
# - Connect using Socket Factory in this script.
# * Drawback: need to manage version and transitive dependencies
# of the postgres-socket-factory jar.
# - Create a self-contained Java application that connects using socket factory
# * Drawback: Seems an overkill
trap "pkill cloud_sql_proxy" EXIT
cloud_sql_proxy -instances="${cloud_sql_instance}"=tcp:5432 \
--credential_file=/secrets/cloud_sql_credential.json &
set +e
# Wait for cloud_sql_proxy to start:
# first sleep 1 second for the process to launch, then loop until port is ready
# or the proxy process dies.
sleep 1
while ! netstat -an | grep ':5432 ' && pgrep cloud_sql_proxy; do sleep 1; done
if ! pgrep cloud_sql_proxy; then
echo "Cloud SQL Proxy failed to set up connection."
exit 1
fi
# Download the actual sql schema
PGPASSWORD=${db_password} pg_dump -h localhost -U "${db_user}" \
-f /schema/nomulus.actual.sql --schema-only --no-owner --no-privileges \
--exclude-table flyway_schema_history \
postgres
raw_diff=$(diff /schema/nomulus.golden.sql /schema/nomulus.actual.sql)
# Clean up the raw_diff:
# - Remove diff locations (e.g. "5,6c5,6): grep "^[<>]"
# - Remove leading bracket for easier grepping later: sed -e "s/^[<>]\s//g"
# - Remove comments and blank lines: grep -v -E "^--|^$"
# - Remove patterns in allowed_diffs.txt, which are custom Cloud SQL configs we
# cannot emulate in the golden schema.
effective_diff=$(echo "${raw_diff}" \
| grep "^[<>]" | sed -e "s/^[<>]\s//g" \
| grep -v -E "^--|^$" \
| grep -v -f /allowed_diffs.txt )
if [[ ${effective_diff} == "" ]]
then
echo "Golden and actual schemas match."
exit 0
else
echo "Golden and actual schemas do not match. Diff is:"
echo "${raw_diff}"
exit 1
fi