From e2c3a2fcdc8600ee9b81cb5a9488cf0443f154b7 Mon Sep 17 00:00:00 2001 From: Evan Pratten Date: Mon, 22 Apr 2024 11:41:46 -0400 Subject: [PATCH] Add API token param for cron --- scripts/cfddns | 79 +++++++++++++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 30 deletions(-) diff --git a/scripts/cfddns b/scripts/cfddns index 9b116cc..c48fd92 100755 --- a/scripts/cfddns +++ b/scripts/cfddns @@ -130,6 +130,7 @@ def main() -> int: help="Print actions instead of performing them", action="store_true", ) + ap.add_argument("--api-token", help="Cloudflare API token") ap.add_argument( "-v", "--verbose", help="Enable verbose logging", action="store_true" ) @@ -142,7 +143,7 @@ def main() -> int: ) # Read env vars needed for the Cloudflare API - cf_api_token = read_secret("api-token") + cf_api_token = args.api_token or read_secret("api-token") if not cf_api_token: logger.error( "Failed to read the Cloudflare API token. Either set $CFDDNS_API_TOKEN or use ewp-secrets" @@ -170,7 +171,7 @@ def main() -> int: # Print the IPs we found logger.info(f"Our IPv4 address is {ipv4}") logger.info(f"Our IPv6 address is {ipv6}") - + # Look up the contents of the zone zone_contents_response = requests.get( f"https://api.cloudflare.com/client/v4/zones/{args.zone_id}/dns_records", @@ -189,18 +190,24 @@ def main() -> int: logger.error("Failed to get the zone contents") print(zone_contents) return 1 - + # Clear all non-matching A and AAAA records on the base zone has_correct_ipv4_record = False has_correct_ipv6_record = False apex_name = None for record in zone_contents["result"]: if record["name"] == args.base_zone and record["type"] in ["A", "AAAA"]: - logger.info(f"Found existing {record['type']} record for {record['name']}. Value: {record['content']}") - + logger.info( + f"Found existing {record['type']} record for {record['name']}. Value: {record['content']}" + ) + # If this doesn't match the corresponding IP, delete it - if (record["type"] == "A" and record["content"] != str(ipv4)) or (record["type"] == "AAAA" and record["content"] != str(ipv6)): - logger.info(f"Deleting stale record {record['id']} ({record['content']})") + if (record["type"] == "A" and record["content"] != str(ipv4)) or ( + record["type"] == "AAAA" and record["content"] != str(ipv6) + ): + logger.info( + f"Deleting stale record {record['id']} ({record['content']})" + ) if not args.dry_run: delete_response = requests.delete( f"https://api.cloudflare.com/client/v4/zones/{args.zone_id}/dns_records/{record['id']}", @@ -214,24 +221,24 @@ def main() -> int: except Exception as e: logger.error(delete_response.json()) raise e - + # Mark the record as OK if it is ok - else: + else: if record["type"] == "A": has_correct_ipv4_record = True elif record["type"] == "AAAA": has_correct_ipv6_record = True - + # Keep track of the apex if not apex_name: apex_name = record["zone_name"] - + # Figure out *when* we are now = datetime.now().isoformat() - + # If the base name is the apex, switch it to @ base_name = args.base_zone if args.base_zone != apex_name else "@" - + # Write new A and AAAA records (if needed) to the base zone if ipv4 and not has_correct_ipv4_record: logger.info(f"Creating new A record for {base_name} with value {ipv4}") @@ -248,7 +255,7 @@ def main() -> int: "content": str(ipv4), "ttl": 60, "proxied": False, - "comment": f"Auto-generated by cfddns on {now}" + "comment": f"Auto-generated by cfddns on {now}", }, ) try: @@ -271,7 +278,7 @@ def main() -> int: "content": str(ipv6), "ttl": 60, "proxied": False, - "comment": f"Auto-generated by cfddns on {now}" + "comment": f"Auto-generated by cfddns on {now}", }, ) try: @@ -279,22 +286,26 @@ def main() -> int: except Exception as e: logger.error(create_response.json()) raise e - + # If we should be creating subdomains, do so if not args.no_ipv4_subzone and ipv4: # Look for an existing record already_exists = False for record in zone_contents["result"]: if record["name"] == f"ipv4.{args.base_zone}" and record["type"] == "A": - logger.info(f"Found existing A record for {record['name']}. Value: {record['content']}") - + logger.info( + f"Found existing A record for {record['name']}. Value: {record['content']}" + ) + # If the record matches, we're done if record["content"] == str(ipv4): already_exists = True break - + # Otherwise, delete it - logger.info(f"Deleting stale record {record['id']} ({record['content']})") + logger.info( + f"Deleting stale record {record['id']} ({record['content']})" + ) if not args.dry_run: delete_response = requests.delete( f"https://api.cloudflare.com/client/v4/zones/{args.zone_id}/dns_records/{record['id']}", @@ -308,10 +319,12 @@ def main() -> int: except Exception as e: logger.error(delete_response.json()) raise e - + # If the record doesn't exist, create it if not already_exists: - logger.info(f"Creating new A record for ipv4.{args.base_zone} with value {ipv4}") + logger.info( + f"Creating new A record for ipv4.{args.base_zone} with value {ipv4}" + ) if not args.dry_run: create_response = requests.post( f"https://api.cloudflare.com/client/v4/zones/{args.zone_id}/dns_records", @@ -325,7 +338,7 @@ def main() -> int: "content": str(ipv4), "ttl": 60, "proxied": False, - "comment": f"Auto-generated by cfddns on {now}" + "comment": f"Auto-generated by cfddns on {now}", }, ) try: @@ -338,15 +351,19 @@ def main() -> int: already_exists = False for record in zone_contents["result"]: if record["name"] == f"ipv6.{args.base_zone}" and record["type"] == "AAAA": - logger.info(f"Found existing AAAA record for {record['name']}. Value: {record['content']}") - + logger.info( + f"Found existing AAAA record for {record['name']}. Value: {record['content']}" + ) + # If the record matches, we're done if record["content"] == str(ipv6): already_exists = True break - + # Otherwise, delete it - logger.info(f"Deleting stale record {record['id']} ({record['content']})") + logger.info( + f"Deleting stale record {record['id']} ({record['content']})" + ) if not args.dry_run: delete_response = requests.delete( f"https://api.cloudflare.com/client/v4/zones/{args.zone_id}/dns_records/{record['id']}", @@ -360,10 +377,12 @@ def main() -> int: except Exception as e: logger.error(delete_response.json()) raise e - + # If the record doesn't exist, create it if not already_exists: - logger.info(f"Creating new AAAA record for ipv6.{args.base_zone} with value {ipv6}") + logger.info( + f"Creating new AAAA record for ipv6.{args.base_zone} with value {ipv6}" + ) if not args.dry_run: create_response = requests.post( f"https://api.cloudflare.com/client/v4/zones/{args.zone_id}/dns_records", @@ -377,7 +396,7 @@ def main() -> int: "content": str(ipv6), "ttl": 60, "proxied": False, - "comment": f"Auto-generated by cfddns on {now}" + "comment": f"Auto-generated by cfddns on {now}", }, ) try: