add feature for subdomain records
This commit is contained in:
parent
c7fc059404
commit
f455014fd5
2 changed files with 52 additions and 19 deletions
|
@ -52,6 +52,7 @@ optional arguments:
|
||||||
-H , --fqdn Host's FQDN (Default: hostname -f)
|
-H , --fqdn Host's FQDN (Default: hostname -f)
|
||||||
--api-prefix API key publicprefix
|
--api-prefix API key publicprefix
|
||||||
--api-secret API key secret
|
--api-secret API key secret
|
||||||
|
-S, --subdomain Create/Update subdomain A/AAAA record (Default: False)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Ideas / To-do
|
## Ideas / To-do
|
||||||
|
|
|
@ -2,8 +2,12 @@
|
||||||
|
|
||||||
# Author: Lázaro Blanc
|
# Author: Lázaro Blanc
|
||||||
# GitHub: https://github.com/lazaroblanc
|
# GitHub: https://github.com/lazaroblanc
|
||||||
|
# Forked by: Jason Deroubaix
|
||||||
|
# GitHub: https://github.com/Jason954/IONOS-DynDNS
|
||||||
|
|
||||||
# Usage example: ./ionos_dyndns.py --A --AAAA --api-prefix <api_prefix> --api-secret <api_secret>
|
# Usage example: ./ionos_dyndns.py --A --AAAA --api-prefix <api_prefix> --api-secret <api_secret>
|
||||||
|
|
||||||
|
|
||||||
import subprocess # Getting IPv6 address from systools instead of via web API
|
import subprocess # Getting IPv6 address from systools instead of via web API
|
||||||
import re # Just regex stuff
|
import re # Just regex stuff
|
||||||
import requests # Talk to the API
|
import requests # Talk to the API
|
||||||
|
@ -17,7 +21,7 @@ logging.basicConfig(stream=sys.stdout, format="%(asctime)s %(message)s", datefmt
|
||||||
def parse_cmdline_args():
|
def parse_cmdline_args():
|
||||||
argparser = ArgumentParser(
|
argparser = ArgumentParser(
|
||||||
description="Create and update DNS records for this host using IONOS' API to use as a sort of DynDNS (for example via a cronjob).",
|
description="Create and update DNS records for this host using IONOS' API to use as a sort of DynDNS (for example via a cronjob).",
|
||||||
epilog="Author: Lázaro Blanc\nGitHub: https://github.com/lazaroblanc",
|
epilog="Author: Lázaro Blanc\nGitHub: https://github.com/lazaroblanc, `\nForked: Jason Deroubaix",
|
||||||
formatter_class=RawDescriptionHelpFormatter
|
formatter_class=RawDescriptionHelpFormatter
|
||||||
)
|
)
|
||||||
argparser.add_argument(
|
argparser.add_argument(
|
||||||
|
@ -43,21 +47,21 @@ def parse_cmdline_args():
|
||||||
)
|
)
|
||||||
argparser.add_argument(
|
argparser.add_argument(
|
||||||
"-H", "--fqdn",
|
"-H", "--fqdn",
|
||||||
default=subprocess.getoutput(f"hostname -f"),
|
default=subprocess.getoutput("hostname -f"),
|
||||||
action="store",
|
action="store",
|
||||||
metavar="",
|
metavar="",
|
||||||
help="Host's FQDN (Default: hostname -f)"
|
help="Host's FQDN (Default: hostname -f)"
|
||||||
)
|
)
|
||||||
argparser.add_argument(
|
argparser.add_argument(
|
||||||
"--api-prefix",
|
"--api-prefix",
|
||||||
required=True,
|
required=False,
|
||||||
action="store",
|
action="store",
|
||||||
metavar="",
|
metavar="",
|
||||||
help="API key publicprefix"
|
help="API key publicprefix"
|
||||||
)
|
)
|
||||||
argparser.add_argument(
|
argparser.add_argument(
|
||||||
"--api-secret",
|
"--api-secret",
|
||||||
required=True,
|
required=False,
|
||||||
action="store",
|
action="store",
|
||||||
metavar="",
|
metavar="",
|
||||||
help="API key secret"
|
help="API key secret"
|
||||||
|
@ -69,6 +73,20 @@ def parse_cmdline_args():
|
||||||
const=True,
|
const=True,
|
||||||
help="Check subdomain (Default: false)"
|
help="Check subdomain (Default: false)"
|
||||||
)
|
)
|
||||||
|
argparser.add_argument(
|
||||||
|
"--api-prefix-file",
|
||||||
|
required=False,
|
||||||
|
action="store",
|
||||||
|
metavar="",
|
||||||
|
help="Path to the file containing the API key publicprefix, WARNING OVERWRITES --api-prefix"
|
||||||
|
)
|
||||||
|
argparser.add_argument(
|
||||||
|
"--api-secret-file",
|
||||||
|
required=False,
|
||||||
|
action="store",
|
||||||
|
metavar="",
|
||||||
|
help="Path to the file containing the API key secret, WARNING OVERWRITES --api-secret"
|
||||||
|
)
|
||||||
|
|
||||||
args = argparser.parse_args()
|
args = argparser.parse_args()
|
||||||
|
|
||||||
|
@ -85,6 +103,21 @@ fqdn = args.fqdn.lower()
|
||||||
api_url = "https://api.hosting.ionos.com/dns/v1/zones"
|
api_url = "https://api.hosting.ionos.com/dns/v1/zones"
|
||||||
api_key_publicprefix = args.api_prefix
|
api_key_publicprefix = args.api_prefix
|
||||||
api_key_secret = args.api_secret
|
api_key_secret = args.api_secret
|
||||||
|
|
||||||
|
if args.api_prefix_file:
|
||||||
|
with open(args.api_prefix_file, "r") as file:
|
||||||
|
api_key_publicprefix = file.read().strip()
|
||||||
|
|
||||||
|
if args.api_secret_file:
|
||||||
|
with open(args.api_secret_file, "r") as file:
|
||||||
|
api_key_secret = file.read().strip()
|
||||||
|
|
||||||
|
# check if the API key and secret are set
|
||||||
|
if not api_key_publicprefix or not api_key_secret:
|
||||||
|
logging.error("API key and secret are required")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
api_headers = {
|
api_headers = {
|
||||||
"accept": "application/json",
|
"accept": "application/json",
|
||||||
"X-API-Key": f"{api_key_publicprefix}.{api_key_secret}"
|
"X-API-Key": f"{api_key_publicprefix}.{api_key_secret}"
|
||||||
|
@ -98,13 +131,6 @@ def main():
|
||||||
zone = get_zone(domain)
|
zone = get_zone(domain)
|
||||||
all_records = get_all_records_for_fqdn(zone["id"], fqdn, args.subdomain)
|
all_records = get_all_records_for_fqdn(zone["id"], fqdn, args.subdomain)
|
||||||
|
|
||||||
# iterate each records
|
|
||||||
for records in all_records:
|
|
||||||
# logging.info(f"Record: {records['name']} {records['type']} {records['content']} {records['ttl']}")
|
|
||||||
print(f"Record: {records['name']} {records['type']} {records['content']} {records['ttl']}")
|
|
||||||
print(all_records)
|
|
||||||
exit(-1)
|
|
||||||
|
|
||||||
records_to_create = []
|
records_to_create = []
|
||||||
records_to_update = []
|
records_to_update = []
|
||||||
|
|
||||||
|
@ -113,16 +139,22 @@ def main():
|
||||||
ipv4_address = get_ipv4_address()
|
ipv4_address = get_ipv4_address()
|
||||||
logging.info("Public IPv4: " + ipv4_address)
|
logging.info("Public IPv4: " + ipv4_address)
|
||||||
records_filtered = filter_records_by_type(all_records, "A")
|
records_filtered = filter_records_by_type(all_records, "A")
|
||||||
if records_filtered:
|
if not records_filtered:
|
||||||
if filter_records_by_type(all_records, "A")[0]["content"] == ipv4_address:
|
|
||||||
logging.info("A record is up-to-date")
|
|
||||||
else:
|
|
||||||
logging.info("A record is outdated")
|
|
||||||
records_to_update.append(
|
|
||||||
new_record(fqdn, "A", ipv4_address, 60))
|
|
||||||
else:
|
|
||||||
logging.info("No A record found")
|
logging.info("No A record found")
|
||||||
records_to_create.append(new_record(fqdn, "A", ipv4_address, 60))
|
records_to_create.append(new_record(fqdn, "A", ipv4_address, 60))
|
||||||
|
if args.subdomain:
|
||||||
|
logging.info("No Subdomain A record found")
|
||||||
|
records_to_create.append(new_record("*."+fqdn, "A", ipv4_address, 60))
|
||||||
|
else:
|
||||||
|
for record in records_filtered:
|
||||||
|
log_prefix = "Subdomain " if "*" in record["name"] else ""
|
||||||
|
if record["content"] == ipv4_address:
|
||||||
|
logging.info(f"{log_prefix}A record is up-to-date")
|
||||||
|
else:
|
||||||
|
record_name = "*." + fqdn if "*" in record["name"] else fqdn
|
||||||
|
logging.info(f"{log_prefix}A record is outdated")
|
||||||
|
records_to_update.append(new_record(record_name, "A", ipv4_address, 60))
|
||||||
|
|
||||||
|
|
||||||
# Good god this is ugly. I hate myself for writing this. This really needs refactoring...
|
# Good god this is ugly. I hate myself for writing this. This really needs refactoring...
|
||||||
if args.AAAA:
|
if args.AAAA:
|
||||||
|
|
Loading…
Reference in a new issue