diff --git a/cf-ddns.sh b/cf-ddns.sh index 148289d..afc6e48 100644 --- a/cf-ddns.sh +++ b/cf-ddns.sh @@ -16,7 +16,7 @@ source "$ENV_FILE" : "${CF_PROXIED:=false}" : "${CF_TTL:=120}" -# --- Derive zone/record from system hostname --- +# --- Names from system --- CF_RECORD_NAME="$(hostname -f 2>/dev/null || true)" CF_SHORT_NAME="$(hostname -s 2>/dev/null || true)" CF_ZONE_NAME="$(hostname -d 2>/dev/null || true)" @@ -24,26 +24,39 @@ CF_ZONE_NAME="$(hostname -d 2>/dev/null || true)" [[ -n "$CF_RECORD_NAME" ]] || fail "hostname -s returned empty" [[ -n "$CF_ZONE_NAME" ]] || fail "hostname -d returned empty (set a DNS/search domain)" +# --- short_host(): derive short alias used for the CNAME --- +short_host() { + local short_hostname part1 part2 part3 part4 num_parts second_initial transformed_hostname + short_hostname="$(hostname -s)" + IFS="-" read -r part1 part2 part3 part4 <<< "$short_hostname" + num_parts=$(awk -F'-' '{print NF}' <<< "$short_hostname") + if [ "$num_parts" -eq 4 ]; then + second_initial=${part2:0:1} # kept in case you want it later + transformed_hostname="${part2}-${part4}" + else + transformed_hostname="$short_hostname" + fi + echo "$transformed_hostname" +} + +SHORT_ALIAS="$(short_host)" +SHORT_ALIAS_FQDN="${SHORT_ALIAS}.${CF_ZONE_NAME}" + # Safe filename for state safe_name="$(echo "$CF_RECORD_NAME" | tr '/:' '__')" LAST_IP_FILE="${STATE_DIR}/last_ipv4_${safe_name}" - mkdir -p "$STATE_DIR" # --- Detect local IPv4 on default route interface --- detect_ip() { local iface ip - - # Prefer ip-route default; fallback to ip route get iface="$(ip route show default 2>/dev/null | awk '/default/ {print $5; exit}')" - if [[ -z "$iface" ]]; then + if [[ -z "${iface}" ]]; then iface="$(ip -4 route get 1.1.1.1 2>/dev/null | awk '{for (i=1;i<=NF;i++) if ($i=="dev") {print $(i+1); exit}}')" fi [[ -n "$iface" ]] || fail "Could not detect default route interface" - ip="$(ip -4 addr show dev "$iface" | awk '/inet / {print $2}' | cut -d/ -f1 | head -n1)" [[ -n "$ip" ]] || fail "No IPv4 found on default interface '$iface'" - echo "$ip" } @@ -65,13 +78,13 @@ zone_id="$(curl -fsS "${hdr[@]}" "${API}/zones?${zone_q}" \ | sed -n 's/.*"id":"\([^"]*\)".*"name":"'"$CF_ZONE_NAME"'".*/\1/p' | head -n1)" [[ -n "$zone_id" ]] || fail "Could not find Zone ID for ${CF_ZONE_NAME}" -# 2) Lookup existing A record by name +# 2) Lookup existing A record by FQDN rec_q="type=A&name=$(urlenc "$CF_RECORD_NAME")" record_json="$(curl -fsS "${hdr[@]}" "${API}/zones/${zone_id}/dns_records?${rec_q}")" record_id="$(echo "$record_json" | sed -n 's/.*"id":"\([^"]*\)".*"name":"'"$CF_RECORD_NAME"'".*"type":"A".*/\1/p' | head -n1)" -# 3) Create payload + create/update -json_payload() { +# 3) A record payload + create/update +json_payload_a() { cat < ${current_ip}" curl -fsS -X POST "${hdr[@]}" \ - --data "$(json_payload)" \ + --data "$(json_payload_a)" \ "${API}/zones/${zone_id}/dns_records" >/dev/null - log "Created." + log "A record created." else log "Updating A ${CF_RECORD_NAME} -> ${current_ip}" curl -fsS -X PUT "${hdr[@]}" \ - --data "$(json_payload)" \ + --data "$(json_payload_a)" \ "${API}/zones/${zone_id}/dns_records/${record_id}" >/dev/null - log "Updated." + log "A record updated." fi -echo "$current_ip" > "$LAST_IP_FILE" \ No newline at end of file +# 4) Create/Update CNAME: SHORT_ALIAS -> CF_RECORD_NAME +if [[ "$SHORT_ALIAS_FQDN" == "$CF_RECORD_NAME" ]]; then + log "SHORT_ALIAS equals CF_RECORD_NAME; skipping CNAME to avoid name conflict." +else + cname_q="type=CNAME&name=$(urlenc "$SHORT_ALIAS_FQDN")" + cname_json="$(curl -fsS "${hdr[@]}" "${API}/zones/${zone_id}/dns_records?${cname_q}")" + cname_id="$(echo "$cname_json" | sed -n 's/.*"id":"\([^"]*\)".*"name":"'"$SHORT_ALIAS_FQDN"'".*"type":"CNAME".*/\1/p' | head -n1)" + json_payload_cname() { + cat < ${CF_RECORD_NAME}" + curl -fsS -X POST "${hdr[@]}" \ + --data "$(json_payload_cname)" \ + "${API}/zones/${zone_id}/dns_records" >/dev/null + log "CNAME created." + else + log "Updating CNAME ${SHORT_ALIAS_FQDN} -> ${CF_RECORD_NAME}" + curl -fsS -X PUT "${hdr[@]}" \ + --data "$(json_payload_cname)" \ + "${API}/zones/${zone_id}/dns_records/${cname_id}" >/dev/null + log "CNAME updated." + fi +fi + +echo "$current_ip" > "$LAST_IP_FILE"