#!/usr/bin/python3 import os import datetime import requests import json import yaml import argparse def create_snapshot(domain, apikey, message='Snapshot from GLD-updater'): url = 'https://api.gandi.net/v5/livedns/domains/%s/snapshots' % domain headers = {} headers['authorization'] = "Apikey %s" % apikey headers['Content-Type'] = "application/json" data = {} data['name'] = message r = requests.post(url, headers=headers, data=json.dumps(data)) if r.status_code != 201: raise Exception("Snapshot creation failed (error %d)" % r.status_code) else: print(r.json()['message']) def backup_records(domain, apikey, dest_path): url = 'https://api.gandi.net/v5/livedns/domains/%s/records' % domain headers = {} headers['authorization'] = "Apikey %s" % apikey r = requests.get(url, headers=headers) if r.status_code != 200: raise Exception("Can't get current DNS records (error %d)" % r.status_code) full_dir = os.path.join(dest_path,domain) os.makedirs(full_dir, exist_ok=True) os.chdir(full_dir) filename = datetime.datetime.now().strftime('%Y%m%d-%H%M') + ".json" backup_file = open(filename,"w") backup_file.write(r.text) backup_file.close() print('Current config saved in %s/%s' % (full_dir, filename)) def update_dns_zone(domain, apikey, config_data): # must provide json data as required by the PUT records endpoint url = 'https://api.gandi.net/v5/livedns/domains/%s/records' % domain headers = {} headers['authorization'] = "Apikey %s" % apikey headers['Content-Type'] = "application/json" data = config_data r = requests.put(url, headers=headers, data=data) if r.status_code != 201: raise Exception("Zone replacement failed (error %d)" % r.status_code) else: print(r.json()['message']) def parse_config_file(config_file): yaml_file = open(config_file, 'r') yaml_content = yaml.load(yaml_file, Loader=yaml.FullLoader) for key in yaml_content: domain = key zone_json = json.dumps(yaml_content[key]) yield domain, zone_json def parse_backup(backup_file): pass def main(): parser = argparse.ArgumentParser() parser.add_argument("-c", "--config-file", help="Zones records in YAML format") parser.add_argument("-k", "--api-key", help="Gandi API key") parser.add_argument("-d", "--backup-dir", help="Directory where the backups will be located (the same folder as the script per default)", default="BACKUPS") parser.add_argument("--no-snapshot", help="Don't create a snapshot of the current zones", action="store_true") parser.add_argument("--no-backup", help="Don't create a local backup of the current zones", action="store_true") args = parser.parse_args() if args.config_file is None: print("No config file provided, check --help.") exit(1) if args.api_key is None: print("No API key provided, check --help.") exit(1) apikey = args.api_key backup_dir = os.path.join(os.getcwd(),args.backup_dir) for domain, zone in parse_config_file(args.config_file): if not args.no_snapshot: create_snapshot(domain,apikey) if not args.no_backup: backup_records(domain,apikey,backup_dir) update_dns_zone(domain,apikey,zone) if __name__ == '__main__': main() print('ALL DONE')