122 lines
3.1 KiB
Bash
Executable File
122 lines
3.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ROOT=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd)
|
|
env_file=${1:-}
|
|
|
|
if [[ -z "$env_file" || ! -f "$env_file" ]]; then
|
|
echo "Usage: $0 EDGE_ENV_FILE" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ "$(stat -c '%a' "$env_file")" != 600 ]]; then
|
|
echo "Edge environment must have mode 0600: $env_file" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ "$(stat -c '%u' "$env_file")" != "$(id -u)" ]]; then
|
|
echo "Edge environment must be owned by the current operator." >&2
|
|
exit 1
|
|
fi
|
|
|
|
read_value() {
|
|
local key=$1
|
|
|
|
awk -v key="$key" '
|
|
index($0, key "=") == 1 {
|
|
print substr($0, length(key) + 2)
|
|
found = 1
|
|
exit
|
|
}
|
|
END { if (!found) exit 1 }
|
|
' "$env_file"
|
|
}
|
|
|
|
require_value() {
|
|
local key=$1
|
|
local value
|
|
|
|
if ! value=$(read_value "$key") || [[ -z "$value" ]]; then
|
|
echo "$key is missing or empty in $env_file." >&2
|
|
exit 1
|
|
fi
|
|
|
|
printf '%s' "$value"
|
|
}
|
|
|
|
validate_hostname() {
|
|
local key=$1
|
|
local value=$2
|
|
|
|
if [[ ! "$value" =~ ^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)+$ ]]; then
|
|
echo "$key must be a lowercase ASCII DNS hostname." >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
validate_upstream() {
|
|
local key=$1
|
|
local value=$2
|
|
|
|
if [[ ! "$value" =~ ^[a-z0-9]([a-z0-9.-]*[a-z0-9])?:[0-9]+$ ]]; then
|
|
echo "$key must be a lowercase host and numeric port." >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
compose_project_name=$(require_value EDGE_COMPOSE_PROJECT_NAME)
|
|
public_edge_network=$(require_value PUBLIC_EDGE_NETWORK)
|
|
edge_bind_address=$(require_value EDGE_BIND_ADDRESS)
|
|
edge_http_port=$(require_value EDGE_HTTP_PORT)
|
|
edge_https_port=$(require_value EDGE_HTTPS_PORT)
|
|
primary_domain=$(require_value PRIMARY_DOMAIN)
|
|
primary_upstream=$(require_value PRIMARY_UPSTREAM)
|
|
test_domain=$(require_value TEST_DOMAIN)
|
|
test_upstream=$(require_value TEST_UPSTREAM)
|
|
|
|
[[ "$compose_project_name" =~ ^[a-zA-Z0-9_-]+$ ]] || {
|
|
echo "EDGE_COMPOSE_PROJECT_NAME contains unsupported characters." >&2
|
|
exit 1
|
|
}
|
|
[[ "$public_edge_network" =~ ^[a-zA-Z0-9_-]+$ ]] || {
|
|
echo "PUBLIC_EDGE_NETWORK contains unsupported characters." >&2
|
|
exit 1
|
|
}
|
|
[[ "$edge_bind_address" == "0.0.0.0" || "$edge_bind_address" == "127.0.0.1" ]] || {
|
|
echo "EDGE_BIND_ADDRESS must be 0.0.0.0 or 127.0.0.1." >&2
|
|
exit 1
|
|
}
|
|
for port_name in edge_http_port edge_https_port; do
|
|
port=${!port_name}
|
|
if [[ ! "$port" =~ ^[0-9]+$ ]] || ((port < 1 || port > 65535)); then
|
|
echo "${port_name^^} must be between 1 and 65535." >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
[[ "$edge_http_port" != "$edge_https_port" ]] || {
|
|
echo "EDGE_HTTP_PORT and EDGE_HTTPS_PORT must be different." >&2
|
|
exit 1
|
|
}
|
|
|
|
validate_hostname PRIMARY_DOMAIN "$primary_domain"
|
|
validate_hostname TEST_DOMAIN "$test_domain"
|
|
validate_upstream PRIMARY_UPSTREAM "$primary_upstream"
|
|
validate_upstream TEST_UPSTREAM "$test_upstream"
|
|
|
|
[[ "$primary_domain" != "$test_domain" ]] || {
|
|
echo "PRIMARY_DOMAIN and TEST_DOMAIN must be different." >&2
|
|
exit 1
|
|
}
|
|
[[ "$primary_upstream" != "$test_upstream" ]] || {
|
|
echo "PRIMARY_UPSTREAM and TEST_UPSTREAM must be different." >&2
|
|
exit 1
|
|
}
|
|
|
|
docker compose \
|
|
--project-directory "$ROOT" \
|
|
--env-file "$env_file" \
|
|
--file "$ROOT/compose.edge.yaml" \
|
|
config --quiet
|
|
|
|
echo "Public edge environment passed structural validation."
|