fix(deploy): select verified proxy subnet
This commit is contained in:
+65
-2
@@ -97,16 +97,79 @@ resolve_existing_web_proxy_subnet() {
|
||||
fi
|
||||
|
||||
local project_name="${COMPOSE_PROJECT_NAME:-$(basename "$PWD")}" network_name subnet
|
||||
local labelled_networks labelled_network_id labelled_project
|
||||
network_name="${project_name}_web_proxy"
|
||||
if ! docker network inspect "$network_name" >/dev/null 2>&1; then
|
||||
return 0
|
||||
# Compose projects may have been created from a differently named checkout.
|
||||
# A unique network carrying Compose's logical `web_proxy` label is the same
|
||||
# production fact even when its generated resource name differs.
|
||||
labelled_networks=""
|
||||
if [ -z "${COMPOSE_PROJECT_NAME:-}" ]; then
|
||||
labelled_networks="$(docker network ls --filter label=com.docker.compose.network=web_proxy -q 2>/dev/null || true)"
|
||||
fi
|
||||
if [ "$(printf '%s\n' "$labelled_networks" | sed '/^$/d' | wc -l | tr -d '[:space:]')" = "1" ]; then
|
||||
labelled_network_id="$(printf '%s\n' "$labelled_networks" | sed '/^$/d')"
|
||||
labelled_project="$(docker network inspect -f '{{index .Labels "com.docker.compose.project"}}' "$labelled_network_id" 2>/dev/null || true)"
|
||||
if [[ "$labelled_project" =~ ^[A-Za-z0-9][A-Za-z0-9_.-]*$ ]]; then
|
||||
export COMPOSE_PROJECT_NAME="$labelled_project"
|
||||
network_name="$labelled_network_id"
|
||||
else
|
||||
network_name=""
|
||||
fi
|
||||
else
|
||||
network_name=""
|
||||
fi
|
||||
fi
|
||||
|
||||
subnet="$(docker network inspect -f '{{range .IPAM.Config}}{{println .Subnet}}{{end}}' "$network_name" 2>/dev/null | head -n 1 | tr -d '[:space:]')"
|
||||
subnet=""
|
||||
if [ -n "$network_name" ]; then
|
||||
subnet="$(docker network inspect -f '{{range .IPAM.Config}}{{println .Subnet}}{{end}}' "$network_name" 2>/dev/null | head -n 1 | tr -d '[:space:]')"
|
||||
fi
|
||||
if [[ "$subnet" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}/([0-9]|[12][0-9]|3[0-2])$ ]]; then
|
||||
export WEB_PROXY_SUBNET="$subnet"
|
||||
echo "Reusing WEB_PROXY_SUBNET from the existing ${network_name} Docker network."
|
||||
return 0
|
||||
fi
|
||||
|
||||
# First creation of the isolated proxy network: use the documented default
|
||||
# only after proving it does not overlap any network currently on this host.
|
||||
local candidate="172.31.250.0/29" existing_output existing
|
||||
local candidate_start candidate_end existing_start existing_end
|
||||
local -a network_ids=()
|
||||
mapfile -t network_ids < <(docker network ls -q 2>/dev/null)
|
||||
if [ "${#network_ids[@]}" -eq 0 ]; then
|
||||
return 0
|
||||
fi
|
||||
if ! existing_output="$(docker network inspect -f '{{range .IPAM.Config}}{{println .Subnet}}{{end}}' "${network_ids[@]}" 2>/dev/null)"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
read -r candidate_start candidate_end < <(ipv4_cidr_bounds "$candidate") || return 0
|
||||
while IFS= read -r existing; do
|
||||
[[ "$existing" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}/([0-9]|[12][0-9]|3[0-2])$ ]] || continue
|
||||
read -r existing_start existing_end < <(ipv4_cidr_bounds "$existing") || continue
|
||||
if (( candidate_start <= existing_end && existing_start <= candidate_end )); then
|
||||
return 0
|
||||
fi
|
||||
done <<< "$existing_output"
|
||||
|
||||
export WEB_PROXY_SUBNET="$candidate"
|
||||
echo "Using non-overlapping WEB_PROXY_SUBNET ${candidate} after Docker network inventory."
|
||||
}
|
||||
|
||||
ipv4_cidr_bounds() {
|
||||
local cidr="$1" address prefix a b c d value ip size start
|
||||
address="${cidr%/*}"
|
||||
prefix="${cidr#*/}"
|
||||
IFS='.' read -r a b c d <<< "$address"
|
||||
for value in "$a" "$b" "$c" "$d"; do
|
||||
[[ "$value" =~ ^[0-9]{1,3}$ ]] && ((10#$value <= 255)) || return 1
|
||||
done
|
||||
[[ "$prefix" =~ ^[0-9]+$ ]] && ((10#$prefix <= 32)) || return 1
|
||||
ip=$(( (10#$a << 24) + (10#$b << 16) + (10#$c << 8) + 10#$d ))
|
||||
size=$(( 1 << (32 - 10#$prefix) ))
|
||||
start=$(( ip & ~(size - 1) ))
|
||||
printf '%s %s\n' "$start" "$((start + size - 1))"
|
||||
}
|
||||
|
||||
validate_deploy_config() {
|
||||
|
||||
Reference in New Issue
Block a user