Add PostgreSQL deployment tooling and release validation
This commit is contained in:
Executable
+146
@@ -0,0 +1,146 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(
|
||||
cd "$(dirname "${BASH_SOURCE[0]}")/.." &&
|
||||
pwd
|
||||
)"
|
||||
|
||||
cd "$ROOT"
|
||||
|
||||
echo "========================================"
|
||||
echo " managed-container release test suite"
|
||||
echo "========================================"
|
||||
|
||||
echo
|
||||
echo ">>> Entrypoint / shell structure"
|
||||
./tests/test-entrypoint-structure.sh
|
||||
|
||||
echo
|
||||
echo ">>> Python syntax"
|
||||
|
||||
while IFS= read -r -d '' file; do
|
||||
python3 -m py_compile "$file"
|
||||
done < <(
|
||||
find ocf \
|
||||
-type f \
|
||||
-name '*.py' \
|
||||
-print0
|
||||
)
|
||||
|
||||
echo "PYTHON_SYNTAX_OK=1"
|
||||
|
||||
echo
|
||||
echo ">>> Host helper shell syntax"
|
||||
|
||||
for file in postgres-host/*; do
|
||||
[[ -f "$file" ]] || continue
|
||||
|
||||
case "$file" in
|
||||
*.sh|*/postgres-ha-bootstrap)
|
||||
bash -n "$file"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo "HOST_HELPER_SYNTAX_OK=1"
|
||||
|
||||
echo
|
||||
echo ">>> Secret-content guard"
|
||||
|
||||
python3 - <<'PY_SECRET_GUARD'
|
||||
from pathlib import Path
|
||||
import re
|
||||
import sys
|
||||
|
||||
roots = [Path("quadlet"), Path("postgres-host")]
|
||||
|
||||
credential_key = re.compile(
|
||||
r'^[A-Z0-9_]*(?:PASSWORD|PASSWD|SECRET|TOKEN)[A-Z0-9_]*$'
|
||||
)
|
||||
|
||||
private_key = re.compile(
|
||||
r'-----BEGIN (?:OPENSSH|RSA|EC|DSA) PRIVATE KEY-----'
|
||||
)
|
||||
|
||||
errors = []
|
||||
|
||||
for root in roots:
|
||||
if not root.exists():
|
||||
continue
|
||||
|
||||
for path in root.rglob("*"):
|
||||
if not path.is_file():
|
||||
continue
|
||||
|
||||
try:
|
||||
text = path.read_text(errors="replace")
|
||||
except Exception as exc:
|
||||
errors.append(f"{path}: unable to read: {exc}")
|
||||
continue
|
||||
|
||||
if private_key.search(text):
|
||||
errors.append(f"{path}: contains private-key material")
|
||||
|
||||
for lineno, raw in enumerate(text.splitlines(), 1):
|
||||
line = raw.strip()
|
||||
|
||||
if not line or line.startswith("#"):
|
||||
continue
|
||||
|
||||
# Only inspect configuration-style assignments whose KEY itself
|
||||
# is uppercase and explicitly credential-related.
|
||||
m = re.match(
|
||||
r'^([A-Z][A-Z0-9_]*)\s*=\s*(.*)$',
|
||||
line
|
||||
)
|
||||
|
||||
if not m:
|
||||
continue
|
||||
|
||||
key, value = m.groups()
|
||||
|
||||
if not credential_key.match(key):
|
||||
continue
|
||||
|
||||
value = value.strip()
|
||||
|
||||
# Empty values are not embedded credentials.
|
||||
if not value:
|
||||
continue
|
||||
|
||||
# References, secret-file paths, templates and placeholders
|
||||
# are acceptable.
|
||||
safe_prefixes = (
|
||||
"$",
|
||||
"${",
|
||||
"/run/secrets/",
|
||||
"/etc/",
|
||||
"<",
|
||||
"CHANGE_ME",
|
||||
)
|
||||
|
||||
unquoted = value.strip("'\"")
|
||||
|
||||
if value.startswith(safe_prefixes) or unquoted.startswith(safe_prefixes):
|
||||
continue
|
||||
|
||||
errors.append(
|
||||
f"{path}:{lineno}: possible literal credential assignment: {key}=..."
|
||||
)
|
||||
|
||||
if errors:
|
||||
for error in errors:
|
||||
print(error, file=sys.stderr)
|
||||
|
||||
print(
|
||||
"ERROR: possible embedded credential material found",
|
||||
file=sys.stderr
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
print("SECRET_GUARD_OK=1")
|
||||
PY_SECRET_GUARD
|
||||
|
||||
echo
|
||||
echo "ALL_TESTS_PASS=1"
|
||||
Reference in New Issue
Block a user