Add domain search

This commit is contained in:
Matteo Bertucci
2021-01-14 17:29:14 +01:00
parent d44c8d0a71
commit ad68d13078
2 changed files with 99 additions and 14 deletions

View File

@ -1,11 +1,11 @@
import logging import logging
import threading import threading
from dataclasses import dataclass from dataclasses import dataclass
from typing import Tuple from typing import Tuple, List, Dict, NoReturn
import requests import requests
from cloudflare_ddns.constants import VERIFY_TOKEN from cloudflare_ddns.constants import VERIFY_TOKEN, LIST_ZONES, LIST_DNS, ACCEPTED_RECORDS
from cloudflare_ddns.utils import parse_duration, BearerAuth from cloudflare_ddns.utils import parse_duration, BearerAuth
log = logging.getLogger("ddns") log = logging.getLogger("ddns")
@ -15,21 +15,99 @@ log = logging.getLogger("ddns")
class Domain: class Domain:
domain: str domain: str
record_type: str record_type: str
zone: str
id: str
class ApplicationJob(threading.Thread): class ApplicationJob(threading.Thread):
def __init__(self, delay: str, token: str, raw_domains: Tuple[str], default_ipv6: bool): def __init__(self, raw_delay: str, token: str, raw_domains: Tuple[str], default_ipv6: bool):
super().__init__() super().__init__()
self.stop_signal = threading.Event() self.stop_signal = threading.Event()
self.delay = delay self.delay = None
self.domains: List[Domain] = []
self.found_domains: Dict[str, Domain] = {}
self.auth = BearerAuth(token) self.auth = BearerAuth(token)
self.raw_domains = raw_domains
self.default_ipv6 = default_ipv6 self.default_ipv6 = default_ipv6
self.raw_domains = raw_domains
self.raw_delay = raw_delay
def launch(self) -> None: def launch(self) -> None:
self.validate_arguments() self.validate_arguments()
log.debug("Starting job.")
self.start()
def run(self) -> None:
log.debug("Parsing domains.")
self.parse_domains()
log.debug(f"Using domains: {', '.join(f'{domain.record_type}:{domain.domain}' for domain in self.domains)}")
log.info("Starting app.")
self.update_records()
while not self.stop_signal.wait(self.delay):
self.update_records()
def update_records(self):
...
def parse_domains(self):
type_1 = "A" if not self.default_ipv6 else "AAAA"
type_2 = "A" if self.default_ipv6 else "AAAA"
for zone_json in requests.get(LIST_ZONES, auth=self.auth).json()["result"]:
for record_json in requests.get(
LIST_DNS.format(zone_identifier=zone_json["id"]),
auth=self.auth
).json()["result"]:
if record_json["type"] in ACCEPTED_RECORDS:
domain = Domain(
record_json["name"],
record_json["type"],
record_json["zone_id"],
record_json["id"]
)
self.found_domains[f'{record_json["name"]}-{record_json["type"]}'] = domain
log.debug(
f"Found domains: "
f"{', '.join(f'{domain.record_type}:{domain.domain}' for domain in self.found_domains.values())}"
)
for domain in self.raw_domains:
if ':' in domain:
type_, domain = domain.split(':', maxsplit=1)
if type_ not in ACCEPTED_RECORDS:
log.error(f"Invalid record type {type_}. Must be one of {', '.join(ACCEPTED_RECORDS)}.")
log.info(f"Exiting with code 65.")
exit(65)
if f"{domain}-{type_}" not in self.found_domains:
log.error(
f"Cannot find an {type_} record for the domain {domain} in your Cloudflare settings. "
f"Have you defined this record yet?"
)
log.info(f"Exiting with code 65.")
exit(65)
else:
if f"{domain}-{type_1}" in self.found_domains:
type_ = type_1
elif f"{domain}-{type_2}" in self.found_domains:
type_ = type_2
else:
log.error(
f"Cannot find the domain {domain} in your Cloudflare settings. "
f"Have you defined this record yet?"
)
log.info(f"Exiting with code 65.")
exit(65)
self.domains.append(self.found_domains[f"{domain}-{type_}"])
def validate_arguments(self): def validate_arguments(self):
failed = False failed = False
@ -39,11 +117,12 @@ class ApplicationJob(threading.Thread):
failed = True failed = True
try: try:
self.delay = parse_duration(self.delay) self.delay = parse_duration(self.raw_delay)
except ValueError as e: except ValueError as e:
log.error(f"Failed to parse delay: {e}") log.error(f"Failed to parse delay: {e}")
failed = True failed = True
if not failed:
try: try:
log.debug("Validating bearer token.") log.debug("Validating bearer token.")

View File

@ -5,3 +5,9 @@ DEFAULT_DELAY = "5 minutes"
BASE_ENDPOINT = "https://api.cloudflare.com/client/v4/" BASE_ENDPOINT = "https://api.cloudflare.com/client/v4/"
VERIFY_TOKEN = BASE_ENDPOINT + "user/tokens/verify" VERIFY_TOKEN = BASE_ENDPOINT + "user/tokens/verify"
LIST_ZONES = BASE_ENDPOINT + "zones"
LIST_DNS = BASE_ENDPOINT + "zones/{zone_identifier}/dns_records"
# Utilities
ACCEPTED_RECORDS = ('A', 'AAAA')