Added the possibility to set TTL
This commit is contained in:
parent
bb06c0c886
commit
cb39d99618
1 changed files with 44 additions and 28 deletions
64
gandyndns.py
64
gandyndns.py
|
|
@ -2,8 +2,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# @author: polarolouis
|
||||
|
||||
import requests
|
||||
import argparse
|
||||
import requests
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="A script which connect to Gandi.net API to change IP associated to a DNS record")
|
||||
|
|
@ -18,6 +18,8 @@ parser.add_argument("--destination", metavar="DESTINATION", default="public_ip",
|
|||
help="The destination to point the subdomain to. Might be an IP, for instance 10.0.0.1, might be a subdomain, for instance @. Default: public_ip, which retrieves the machine public ip")
|
||||
parser.add_argument("--type", metavar="TYPE", default='A',
|
||||
help="The type of DNS record to create. Default: A", choices=['A', 'CNAME'])
|
||||
parser.add_argument("--ttl", metavar="TTL", default=10800,
|
||||
help="The Time To Live in seconds. This is the number of seconds the record must be stored in cache. Default value is 10800s (3hrs).", type=int)
|
||||
args = parser.parse_args()
|
||||
print(args)
|
||||
|
||||
|
|
@ -25,20 +27,21 @@ verbose = args.verbose
|
|||
domain = args.domain
|
||||
apikey = args.apikey
|
||||
subdomain = args.subdomain
|
||||
type = args.type
|
||||
record_type = args.type
|
||||
ttl = args.ttl
|
||||
destination = args.destination
|
||||
|
||||
domain_record_string = f"DNS {type} record for {subdomain}.{domain}"
|
||||
domain_record_string = f"DNS {record_type} record for {subdomain}.{domain}"
|
||||
|
||||
domain_record_string_lenght = len(domain_record_string)
|
||||
|
||||
apiUrl = f"https://api.gandi.net/v5/livedns/domains/{domain}/records/{subdomain}/{type}"
|
||||
api_url = f"https://api.gandi.net/v5/livedns/domains/{domain}/records/{subdomain}/{record_type}"
|
||||
|
||||
headers = {"Authorization": f"Apikey {apikey}",
|
||||
'User-Agent': 'Mozilla/5.0', "Content-Type": "application/json"}
|
||||
|
||||
|
||||
def retrieve_public_IP():
|
||||
def retrieve_public_ip():
|
||||
"""Retrieves the public IP by connecting to ipinfo.io API
|
||||
|
||||
Returns:
|
||||
|
|
@ -50,54 +53,67 @@ def retrieve_public_IP():
|
|||
return data['ip']
|
||||
|
||||
|
||||
def retrieve_dns_IP(apiUrl, headers):
|
||||
def retrieve_dns_ip(api_url, headers):
|
||||
"""Retrieves the IP in the DNS record using the domain, rrset_name (for instance subdomain like www etc) and rrset_type (the DNS record type A, CNAME ...).
|
||||
|
||||
The function uses requests library and connect to Gandi.net API
|
||||
|
||||
Returns:
|
||||
retrievedDnsIp (str): string of the IP address in the DNS record"""
|
||||
retrieved_dns_ip (str): string of the IP address in the DNS record"""
|
||||
if verbose:
|
||||
print("Retrieving the DNS IP")
|
||||
response = requests.get(apiUrl, headers=headers)
|
||||
response = requests.get(api_url, headers=headers)
|
||||
|
||||
responseJson = response.json() # IPs are stored in a list as string
|
||||
response_json = response.json() # IPs are stored in a list as string
|
||||
try:
|
||||
retrievedDnsIp = responseJson['rrset_values'][0]
|
||||
retrieved_dns_ip = response_json['rrset_values'][0]
|
||||
retrieved_ttl = response_json['rrset_ttl']
|
||||
except KeyError as key_error:
|
||||
print(
|
||||
f"{key_error} means the record doesn't exist, we'll return an empty string instead")
|
||||
retrievedDnsIp = ""
|
||||
return retrievedDnsIp
|
||||
retrieved_dns_ip = ""
|
||||
return retrieved_dns_ip, retrieved_ttl
|
||||
|
||||
|
||||
def update_dns_IP(apiUrl, headers):
|
||||
"""Updates the IP in the DNS record using the IP provided (acquired by retrieve_public_IP) if it is different from the DNS IP"""
|
||||
def update_dns_ip(api_url, headers):
|
||||
"""Updates the IP in the DNS record using the IP provided (acquired by retrieve_public_ip) if it is different from the DNS IP"""
|
||||
if destination == "public_ip":
|
||||
publicIP = retrieve_public_IP()
|
||||
publicIP = retrieve_public_ip()
|
||||
else:
|
||||
publicIP = destination
|
||||
dnsIP = retrieve_dns_IP(apiUrl, headers)
|
||||
dnsIP, dns_ttl = retrieve_dns_ip(api_url, headers)
|
||||
if verbose:
|
||||
print(f"Public IP is : {publicIP}")
|
||||
if dnsIP:
|
||||
print(f"DNS IP is : {dnsIP}")
|
||||
else:
|
||||
print("The subdomain doesn't exist, no DNS IP associated")
|
||||
if not publicIP == dnsIP:
|
||||
if verbose:
|
||||
print("IPs do not match, setting DNS IP")
|
||||
data = {
|
||||
"rrset_values": [publicIP]
|
||||
}
|
||||
print(f"DNS TTL is {dns_ttl}")
|
||||
if publicIP != dnsIP or dns_ttl != ttl:
|
||||
|
||||
data = dict()
|
||||
|
||||
data["rrset_values"] = [publicIP]
|
||||
print(f"{domain_record_string : <{domain_record_string_lenght}} | Old IP : {dnsIP} replaced -> by New IP : {publicIP}")
|
||||
response = requests.put(url=apiUrl, headers=headers, json=data)
|
||||
|
||||
if dns_ttl != ttl:
|
||||
data["rrset_ttl"] = ttl
|
||||
if verbose:
|
||||
print(f"TTL are differents. DNS TTL {dns_ttl} where wanted TTL is {ttl}")
|
||||
|
||||
if verbose:
|
||||
print(f"The data to be sent is : {data}")
|
||||
response = requests.put(url=api_url, headers=headers, json=data)
|
||||
if verbose:
|
||||
print(f"Request exited with status code : {response.status_code}")
|
||||
else:
|
||||
if publicIP == dnsIP:
|
||||
print(
|
||||
f"{domain_record_string : <{domain_record_string_lenght}} | {'IPs are the same.':<17}")
|
||||
if dns_ttl == ttl:
|
||||
print(
|
||||
f"{domain_record_string : <{domain_record_string_lenght}} | {'TTL are the same':<17}")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
update_dns_IP(apiUrl, headers)
|
||||
update_dns_ip(api_url, headers)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue