From 3a28a3eae0b7491f419b5ccdcda66ae263a71831 Mon Sep 17 00:00:00 2001 From: Tine Date: Sun, 5 Jan 2025 21:48:17 +0100 Subject: [PATCH] feat(ingress.tjo.cloud): refactoring and healthcheck implementation --- devbox.json | 9 +- devbox.lock | 84 ++++++++++++++++ ingress.tjo.cloud/justfile | 2 +- ingress.tjo.cloud/root/etc/nginx/nginx.conf | 11 +++ ingress.tjo.cloud/root/usr/local/bin/dyndns | 95 +++++++++++-------- .../terraform/.terraform.lock.hcl | 3 + network.tjo.cloud/configs/common.yaml | 1 + 7 files changed, 162 insertions(+), 43 deletions(-) diff --git a/devbox.json b/devbox.json index e8d21df..55fa215 100644 --- a/devbox.json +++ b/devbox.json @@ -9,15 +9,14 @@ "tflint@latest", "age@latest", "tenv@latest", - "gomplate@latest" + "gomplate@latest", + "just@latest" ], "env": { "TFENV_AUTO_INSTALL": "true" }, "shell": { - "init_hook": [ - ], - "scripts": { - } + "init_hook": [], + "scripts": {} } } diff --git a/devbox.lock b/devbox.lock index 86bede5..1679237 100644 --- a/devbox.lock +++ b/devbox.lock @@ -145,6 +145,90 @@ } } }, + "just@latest": { + "last_modified": "2024-12-23T21:10:33Z", + "resolved": "github:NixOS/nixpkgs/de1864217bfa9b5845f465e771e0ecb48b30e02d#just", + "source": "devbox-search", + "version": "1.38.0", + "systems": { + "aarch64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/vsh8l0h4w2s2chhxnq3crggnqgajv8fr-just-1.38.0", + "default": true + }, + { + "name": "man", + "path": "/nix/store/4v2f2ilb558wldh4wl5iplhbqbwcs8x7-just-1.38.0-man", + "default": true + }, + { + "name": "doc", + "path": "/nix/store/ys7i8a3y8x0wpvpgjm1cg32vcmkvghaq-just-1.38.0-doc" + } + ], + "store_path": "/nix/store/vsh8l0h4w2s2chhxnq3crggnqgajv8fr-just-1.38.0" + }, + "aarch64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/v9c5rvb1f5351vnfqw1dwrqnyr0zmwkl-just-1.38.0", + "default": true + }, + { + "name": "man", + "path": "/nix/store/b402yzxcpdldqafh9lh1vz10pifyyrm1-just-1.38.0-man", + "default": true + }, + { + "name": "doc", + "path": "/nix/store/wdvhp7n1ll2r94bp1wq0nw9d7jsy9h5r-just-1.38.0-doc" + } + ], + "store_path": "/nix/store/v9c5rvb1f5351vnfqw1dwrqnyr0zmwkl-just-1.38.0" + }, + "x86_64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/nrwx6y35zjj83shb7vj6nxl5a7ll7jfq-just-1.38.0", + "default": true + }, + { + "name": "man", + "path": "/nix/store/g72x3fkmf25sa8gc3sh17wm2s14vk1zi-just-1.38.0-man", + "default": true + }, + { + "name": "doc", + "path": "/nix/store/1z00n6g7id3z5x4wgmxnpp0www1r9ah6-just-1.38.0-doc" + } + ], + "store_path": "/nix/store/nrwx6y35zjj83shb7vj6nxl5a7ll7jfq-just-1.38.0" + }, + "x86_64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/8gfn54vq7r96i0jpdgbz4084b4n5if61-just-1.38.0", + "default": true + }, + { + "name": "man", + "path": "/nix/store/kh82ps1zp22cv36l4w1r7pzv1rbzpmjz-just-1.38.0-man", + "default": true + }, + { + "name": "doc", + "path": "/nix/store/lxn266hlm8ngl6r0bkz9bdc2g5iskqby-just-1.38.0-doc" + } + ], + "store_path": "/nix/store/8gfn54vq7r96i0jpdgbz4084b4n5if61-just-1.38.0" + } + } + }, "kubectl@latest": { "last_modified": "2024-07-07T07:43:47Z", "resolved": "github:NixOS/nixpkgs/b60793b86201040d9dee019a05089a9150d08b5b#kubectl", diff --git a/ingress.tjo.cloud/justfile b/ingress.tjo.cloud/justfile index 786589c..349ce3b 100644 --- a/ingress.tjo.cloud/justfile +++ b/ingress.tjo.cloud/justfile @@ -78,4 +78,4 @@ update-blocked-list: echo "#!!DO NOT EDIT!! Generated by using just ingress-blocked-list command." > root/etc/nginx/partials/blocked.conf for ip in $IP_RANGES; do echo "deny $ip;" >> root/etc/nginx/partials/blocked.conf - done \ No newline at end of file + done diff --git a/ingress.tjo.cloud/root/etc/nginx/nginx.conf b/ingress.tjo.cloud/root/etc/nginx/nginx.conf index 92a1414..eea9f79 100644 --- a/ingress.tjo.cloud/root/etc/nginx/nginx.conf +++ b/ingress.tjo.cloud/root/etc/nginx/nginx.conf @@ -9,6 +9,17 @@ events { worker_connections 768; } +http { + server { + listen 0.0.0.0:1337; + listen [::]:1337; + + location /healthz { + return 200 "OK"; + } + } +} + stream { # Map of Host -> IP # We will route the traffic to this endpoints. diff --git a/ingress.tjo.cloud/root/usr/local/bin/dyndns b/ingress.tjo.cloud/root/usr/local/bin/dyndns index d56090e..c6613f5 100755 --- a/ingress.tjo.cloud/root/usr/local/bin/dyndns +++ b/ingress.tjo.cloud/root/usr/local/bin/dyndns @@ -31,7 +31,45 @@ test -z "${DNSIMPLE_ACCOUNT_ID}" && error "DNSIMPLE_ACCOUNT_ID not set!" test -z "${DOMAIN}" && error "DOMAIN not set!" test -z "${CLOUD_REGION}" && error "CLOUD_REGION not set!" -dns_list="$api_host/$DNSIMPLE_ACCOUNT_ID/zones/$DOMAIN/records" +base_zone_url="$api_host/$DNSIMPLE_ACCOUNT_ID/zones/$DOMAIN/records" + +dnsimple_list_record() { + curl -s -X GET \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $DNSIMPLE_TOKEN" \ + "$base_zone_url" +} + +dnsimple_create_record() { + local data="$1" + + curl -s -X POST \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $DNSIMPLE_TOKEN" \ + -d "$data" \ + "$base_zone_url" +} + +dnsimple_update_record() { + local record="$1" + local data="$2" + + curl -s -X PATCH \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $DNSIMPLE_TOKEN" \ + -d "$data" \ + "$base_zone_url/$record" &>/dev/null +} + +dnsimeple_delete_record() { + local record="$1" + + curl -s -X DELETE \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $DNSIMPLE_TOKEN" \ + "$base_zone_url/$record" &>/dev/null + +} configure_single() { # disable glob expansion @@ -52,10 +90,7 @@ configure_single() { record_data=$(echo "$record_data" | head -1) while IFS= read -r line; do - curl -s -X DELETE \ - -H "Content-Type: application/json" \ - -H "Authorization: Bearer $DNSIMPLE_TOKEN" \ - "$dns_list/$line" &>/dev/null + dnsimeple_delete_record "$line" done <<<"$record_id_to_delete" fi @@ -63,28 +98,17 @@ configure_single() { set +f data="{\"type\": \"$type\", \"name\": \"$domain\", \"content\": \"$ip\", \"ttl\": $record_ttl}" - url="$dns_list/$record_id" if [[ -z $record_id ]]; then - info "domain=$domain type=$type No record found. Creating record, sending data=$data to url=$url" + info "domain=$domain type=$type No record found. Creating record." - new_record=$(curl -s -X POST \ - -H "Content-Type: application/json" \ - -H "Authorization: Bearer $DNSIMPLE_TOKEN" \ - -d "$data" \ - "$url") - - record_data=$(echo "$new_record" | jq -r ".data") + record_data=$(dnsimple_create_record "$data" | jq -r ".data") fi if [[ "$ip" != "$record_data" ]]; then - info "domain=$domain type=$type Existing DNS record address ($record_data) doesn't match current IP ($ip), sending data=$data to url=$url" + info "domain=$domain type=$type Existing DNS record address ($record_data) doesn't match current IP ($ip)" - curl -s -X PATCH \ - -H "Content-Type: application/json" \ - -H "Authorization: Bearer $DNSIMPLE_TOKEN" \ - -d "$data" \ - "$url" &>/dev/null + dnsimple_update_record "$record_id" "$data" else info "domain=$domain type=$type Existing DNS record address ($record_data) did not need updating" fi @@ -106,31 +130,28 @@ configure_many() { set +f data="{\"type\": \"$type\", \"name\": \"$domain\", \"content\": \"$ip\", \"ttl\": $record_ttl}" - url="$dns_list/$record_id" + url="$base_zone_url/$record_id" if [[ -z $record_id ]]; then - info "domain=$domain type=$type No record found. Creating record, sending data=$data to url=$url" + info "domain=$domain type=$type No record found. Creating record." - new_record=$(curl -s -X POST \ - -H "Content-Type: application/json" \ - -H "Authorization: Bearer $DNSIMPLE_TOKEN" \ - -d "$data" \ - "$url") - - record_data=$(echo "$new_record" | jq -r ".data") + record_data=$(dnsimple_create_record "$data" | jq -r ".data") else - info "domain=$domain type=$type Existing DNS record address ($record_data) did not need updating" + info "domain=$domain type=$type Existing DNS record address ($record_data) did not need updating." fi } +healthcheck() { + local ip="$1" + + curl -s -f -o /dev/null "http://$ip" || error "Healthcheck failed" +} + while (true); do - domain_records=$(curl -s -X GET \ - -H "Content-Type: application/json" \ - -H "Authorization: Bearer $DNSIMPLE_TOKEN" \ - "$dns_list") + domain_records=$(dnsimple_list_record) for service in "${services[@]}"; do - info "Trying with $service..." + info "Discovering public IP with $service..." ipv4="$(curl -4 -s -f --connect-timeout 2 "$service" || echo "")" ipv6="$(curl -6 -s -f --connect-timeout 2 "$service" || echo "")" @@ -147,7 +168,7 @@ while (true); do else info "Found IPv4 address $ipv4" configure_single "$domain_records" "$CLOUD_REGION" "$ipv4" "A" - configure_many "$domain_records" "any" "$ipv4" "A" + configure_many "$domain_records" "any" "$ipv4" "A" fi if [[ -z $ipv6 ]]; then @@ -155,7 +176,7 @@ while (true); do else info "Found IPv6 address $ipv6" configure_single "$domain_records" "$CLOUD_REGION" "$ipv6" "AAAA" - configure_many "$domain_records" "any" "$ipv6" "AAAA" + configure_many "$domain_records" "any" "$ipv6" "AAAA" fi sleep "$sleep_interval" diff --git a/ingress.tjo.cloud/terraform/.terraform.lock.hcl b/ingress.tjo.cloud/terraform/.terraform.lock.hcl index 1c53f99..5e86393 100644 --- a/ingress.tjo.cloud/terraform/.terraform.lock.hcl +++ b/ingress.tjo.cloud/terraform/.terraform.lock.hcl @@ -6,6 +6,7 @@ provider "registry.opentofu.org/bpg/proxmox" { constraints = "0.61.1" hashes = [ "h1:6kz2Rdjc8+TVq2aUxEQXLOwbb9OdhJJei0L1fC4K2R4=", + "h1:SQSHTHj2ThcF08cON2gHYcnkS/XLmoF8E4cRIgpagtE=", "zh:27d8b589a2dc1e0a5b0f8ab299b9f3704a2f0b69799d1d4d8845c68056986d1f", "zh:46dfa6b33ddd7007a2144f38090457604eb56a59a303b37bb0ad1be5c84ddaca", "zh:47a1b14a759393c5ecc76f2feb950677c418c910b8c677fde0dd3e4675c41579", @@ -28,6 +29,7 @@ provider "registry.opentofu.org/goauthentik/authentik" { version = "2024.8.3" constraints = "2024.8.3" hashes = [ + "h1:8ZYjDZc+RMO9vFxOPXjc4PEZimV9gMKk1vxDPjc+TZQ=", "h1:NiXi1gn1BH2tk1MIqgl6hQotwVe8FN8RJqvE7ix+EWs=", "zh:1d2d165662d36dae0aacb478a6bae055546979dea58ee3762dd7d398b7f60e8c", "zh:3a118d3c123eab3e26c33821607d2f70f9e317d3d33289f9d615e4b6d353b877", @@ -51,6 +53,7 @@ provider "registry.opentofu.org/tailscale/tailscale" { constraints = "0.17.2" hashes = [ "h1:0bZpffptYi/bXOXEnFjUYD6UwaR4vqUdMULdeeBhz84=", + "h1:Hb7w+ibr6O6jvQSJbLAH0DI/r7sgnkxKLiAofAjEzpQ=", "zh:13d21db507bfb17018005c5c4f19314591a5734c76bcd51ab6e80984164c2a71", "zh:13dbb3d978aca16f66c49596e5a38d236264d10a66879dc0d06839aca9cdad3f", "zh:1589a8b006da14d60e3fcd55fbc465ccdce7a99e833b6a7455fbf81be59f07f3", diff --git a/network.tjo.cloud/configs/common.yaml b/network.tjo.cloud/configs/common.yaml index 91bf3ae..e0638e7 100644 --- a/network.tjo.cloud/configs/common.yaml +++ b/network.tjo.cloud/configs/common.yaml @@ -10,6 +10,7 @@ firewall: - 465 # ESMTP (implicit TLS) - 587 # ESMTP (explicit TLS => STARTTLS) - 993 # IMAP4 (implicit TLS) + - 1337 # HTTP ingress.tjo.cloud healthcheck - 4190 # MANAGE SIEVE bgp: