#!/usr/bin/env python3 # -*- encoding: UTF8 -*- # author: Pascal Gollor (https://gitbucket.pgollor.de) from INWX.Domrobot import ApiClient from configuration import get_account_data import argparse from getIPaddress import getPublicIP def errorCheck(ret): if (ret['code'] != 1000): raise RuntimeError('[ERROR] Code: ' + str(ret['code']) + ' Message: ' + ret['msg']) # end if return ret # end errorCheck def updateRecord(mode, username, password, domain, sub, record_type, ttl, content=None, config_section="live", verbose=False): debug_mode = False api_url = ApiClient.API_LIVE_URL if (config_section == "ote"): debug_mode = True api_url = ApiClient.API_OTE_URL api_client = ApiClient(api_url=api_url, debug_mode=debug_mode) ret = errorCheck(api_client.login(username, password)) if (verbose): print("login:", ret) # check domain ret = errorCheck(api_client.call_api(api_method='nameserver.list', method_params={'domain': domain})) if (verbose): print('list:', ret) if (ret['resData']['count'] == 0): raise RuntimeError("You are not user of this domain.") # looking if subdomain exists ret = errorCheck(api_client.call_api(api_method='nameserver.info', method_params={'domain': domain})) records = ret['resData']['record'] if (mode == "delete" or mode == "update"): recordFound = False for r in records: if (r['name'] == domain and r['type'] == record_type): recordFound = True if (verbose): print('entry:', r) # delete entry if (mode == "delete"): # if content is not none: delete only entry with given content. if (content != None and r['content'] != content): continue ret = errorCheck(api_client.call_api(api_method='nameserver.deleteRecord', method_params={'id': r['id']})) if (verbose): print('delete:', ret) # update entry elif (mode == "update"): ret = errorCheck(api_client.call_api(api_method='nameserver.updateRecord', method_params={'id': r['id'], 'type': record_type, 'content': content, 'ttl': ttl})) if (verbose): print('update:', ret) # end if # end if # end for if (mode == "delete" and not recordFound): raise RuntimeError('can not delete entry.') # end if if (mode == "create" or (mode == "update" and not recordFound)): ret = errorCheck(api_client.call_api(api_method='nameserver.createRecord', method_params={'domain': domain, 'name': sub, 'type': record_type, 'content': content, 'ttl': ttl})) if (verbose): print('create:', ret) # end if api_client.logout() # end updateRecord def main(args): # do some checks if (args.mode != 'delete' and not args.public_ip and not args.content): raise ValueError("Missing content for domain entry.") # end if # split domain domain = args.domain h = domain.split('.') if (len(h) < 3): raise ValueError("invalid subdomain") sub = h[0] for i in range(1, len(h)-2): sub += '.' + h[i] domain = h[-2] + '.' + h[-1] if (args.debug): print(args) # get config and login username, password, shared_secret = get_account_data(True, config_file=args.config_file, config_section=args.config_section) # use puplic ip as content content= args.content if (args.public_ip and (args.mode == 'create' or args.mode == 'update')): if (args.record_type != 'A' and args.record_type != 'AAAA'): raise RuntimeError('Record type have to be A or AAAA') content = getPublicIP(ipv4=(args.record_type=='A')) # end if updateRecord( mode=args.mode, username=username, password=password, domain=domain, sub=sub, content=content, record_type=args.record_type, ttl=args.ttl, config_section=args.config_section, verbose=args.verbose ) # end main if __name__ == '__main__': parser = argparse.ArgumentParser(description='inwx subdomain update') parser.add_argument('domain', metavar='domain', help='full domain like subdomain.example.com') parser.add_argument('content', metavar='content', nargs='?', default=None, help='ip or string to fill/update into subdomain domain entry') parser.add_argument('-r', '--record-type', metavar='type', required=True, choices=['A', 'AAAA', 'TXT', 'CNAME', 'TLSA'], help='record type (A, AAAA, TXT, CNAME, TLSA)') parser.add_argument('-m', '--mode', metavar='mode', required=True, choices=['create', 'update', 'delete'], help='operation mode (create, update, delete)\nupdate:update all existing records if one exists, or create if not existing\ndelete: delete existing record with given content, or delete all records if no content is given') parser.add_argument('-p', '--public-ip', action='store_true', required=False, help='insert public ip. Use -r A for ip4 an -r AAAA for ipv6') parser.add_argument('-c', '--config_file', metavar='path', default='./conf.cfg', help='path to configuration file') parser.add_argument('-t', '--ttl', default=3600, type=int, help='TTL (time to live) of the nameserver record in seconds (default 3600)') parser.add_argument('-s', '--config_section', metavar='section', default='live', choices=['live', 'ote'], help='configuration section (live, ote) default: live') parser.add_argument('-v', '--verbose', action='store_true', help='verbose') parser.add_argument('-d', '--debug', action='store_true', help='debug') args = parser.parse_args() if (args.debug): main(args) else: try: main(args) except (NameError, RuntimeError, ValueError) as e: print(e.args[0]) # end try # end if # end if