def record_device_delete(aDict): """Function docstring for record_device_delete TBD Args: - a_id (optional) - id/0 - ptr_id (optional) - id/0 - a_domain_id (optional required) - ptr_domain_id (optional required) Output: """ ret = {'A': 0, 'PTR': 0} with DB() as db: for tp in ['a', 'ptr']: domain_id = aDict.get('%s_domain_id' % tp) id = str(aDict.get('%s_id' % tp, '0')) if domain_id and id != '0': db.do( "SELECT foreign_id, server, node FROM domains LEFT JOIN domain_servers ON domains.server_id = domain_servers.id WHERE domains.id = '%s'" % (domain_id)) infra = db.get_row() args = {'id': id, 'domain_id': infra['foreign_id']} ret[tp.upper()] = node_call(infra['node'], infra['server'], 'record_delete', args)['deleted'] return ret
def record_list(aDict): """Function docstring for record_list TBD Args: - type (optional) - domain_id (required), <B>use cached one</B> Output: """ args = aDict with DB() as db: if aDict.get('domain_id'): db.do( "SELECT foreign_id, server, node FROM domain_servers LEFT JOIN domains ON domains.server_id = domain_servers.id WHERE domains.id = %s" % aDict['domain_id']) infra = db.get_row() args['domain_id'] = infra['foreign_id'] else: # Strictly internal use - this one fetch all records for consistency check id = aDict.pop('server_id', '0') db.do("SELECT server, node FROM domain_servers WHERE id = %s" % id) infra = db.get_row() ret = node_call(infra['node'], infra['server'], 'record_list', args) ret['domain_id'] = aDict.get('domain_id', 0) return ret
def domain_delete(aDict): """Function docstring for domain_delete. Args: - id (required) - transfer (optional) Output: """ if aDict['id'] != aDict.get('transfer') and int(aDict['id']) > 0: with DB() as db: db.do( "SELECT foreign_id, server, node FROM domain_servers LEFT JOIN domains ON domains.server_id = domain_servers.id WHERE domains.id = %s" % aDict['id']) infra = db.get_row() ret = node_call(infra['node'], infra['server'], 'domain_delete', {'id': infra['foreign_id']}) ret['devices'] = db.do( "UPDATE devices SET a_id = 0, a_dom_id = %s WHERE a_dom_id = %s" % (aDict.get('transfer', 0), aDict['id'])) ret['cache'] = db.do("DELETE FROM domains WHERE id = %s" % (aDict['id'])) else: ret = {'devices': 0, 'cache': 0, 'records': 0} return ret
def leases(aDict): """Function docstring for leases TBD Args: - type (required) Output: """ return node_call(SC['dhcp']['node'],SC['dhcp']['type'],'leases',aDict)
def update_server(aDict): """Function docstring for update_server TBD Args: - entries (required). entries is a list of dict objects containing hostname, mac, ip etc Output: """ return node_call(SC['dhcp']['node'],SC['dhcp']['type'],'update_server',aDict)
def domain_list(aDict): """Function docstring for domain_list. Args: - filter (optional) - dict (optional) - sync (optional) - exclude (optional) Output: - filter:forward/reverse """ ret = {} with DB() as db: if aDict.get('sync') == 'true': org = {} db.do("SELECT id, server, node FROM domain_servers") servers = db.get_rows() for server in servers: org[server['id']] = node_call(server['node'], server['server'], 'domain_list')['domains'] ret.update({'sync': {'added': [], 'deleted': []}}) db.do("SELECT domains.* FROM domains") cache = db.get_dict('foreign_id') for srv, domains in org.iteritems(): for dom in domains: if not cache.pop(dom['id'], None): ret['sync']['added'].append(dom) # Add forward here db.insert_dict( 'domains', { 'name': dom['name'], 'server_id': srv, 'foreign_id': dom['id'] }, "ON DUPLICATE KEY UPDATE name = '%s'" % dom['name']) for id, dom in cache.iteritems(): ret['sync']['deleted'].append(dom) db.do("DELETE FROM domains WHERE id = '%s'" % id) filter = [] if aDict.get('filter'): filter.append("name %s LIKE '%%arpa'" % ('' if aDict.get('filter') == 'reverse' else "NOT")) if aDict.get('exclude'): db.do("SELECT server_id FROM domains WHERE id = '%s'" % (aDict.get('exclude'))) filter.append('server_id = %s' % (db.get_val('server_id'))) filter.append("domains.id <> '%s'" % aDict.get('exclude')) ret['xist'] = db.do( "SELECT domains.*, server FROM domains LEFT JOIN domain_servers ON domains.server_id = domain_servers.id WHERE %s ORDER BY name" % ('TRUE' if len(filter) == 0 else " AND ".join(filter))) ret['domains'] = db.get_rows( ) if not aDict.get('dict') else db.get_dict(aDict.get('dict')) return ret
def domain_info(aDict): """Function docstring for domain_info TBD Args: - id (required) - type (required) - master (required) - name (required) - server_id (optional) Output: """ ret = {'id': aDict['id']} args = aDict with DB() as db: if args['id'] == 'new' and not (args.get('op') == 'update'): db.do("SELECT id, server, node FROM domain_servers") ret['servers'] = db.get_rows() ret['data'] = { 'id': 'new', 'name': 'new-name', 'master': 'ip-of-master', 'type': 'MASTER', 'notified_serial': 0 } else: if args['id'] == 'new': db.do( "SELECT id, 'new' AS foreign_id, server, node FROM domain_servers WHERE id = %s" % args.pop('server_id', '0')) else: db.do( "SELECT domain_servers.id, foreign_id, server, node FROM domain_servers LEFT JOIN domains ON domains.server_id = domain_servers.id WHERE domains.id = %s" % args['id']) ret['infra'] = db.get_row() args['id'] = ret['infra'].pop('foreign_id', None) ret.update( node_call(ret['infra']['node'], ret['infra']['server'], 'domain_info', args)) if str(ret.get('insert', 0)) == '1': ret['cache'] = db.insert_dict( 'domains', { 'name': args['name'], 'server_id': ret['infra']['id'], 'foreign_id': ret['data']['id'] }) ret['id'] = db.get_last_id() return ret
def dedup(aDict): """Function docstring for dedup. TBD Args: Output: """ ret = {} with DB() as db: db.do("SELECT server, node FROM domain_servers") servers = db.get_rows() for infra in servers: res = node_call(infra['node'], infra['server'], 'dedup') ret["%s_%s" % (infra['node'], infra['server'])] = res['removed'] return ret
def record_device_create(aDict): """Function docstring for record_device_create TBD Args: - device_id (required) - ip (required) - type (required) - domain_id (required) - fqdn (required) Output: """ ret = {} args = {'op': 'update', 'id': 'new', 'type': aDict['type'].upper()} if args['type'] == 'A': args['name'] = aDict['fqdn'] args['content'] = aDict['ip'] elif args['type'] == 'PTR': def GL_ip2ptr(addr): octets = addr.split('.') octets.reverse() octets.append("in-addr.arpa") return ".".join(octets) args['name'] = GL_ip2ptr(aDict['ip']) args['content'] = aDict['fqdn'] with DB() as db: db.do( "SELECT foreign_id, server, node FROM domain_servers LEFT JOIN domains ON domains.server_id = domain_servers.id WHERE domains.id = %s" % aDict['domain_id']) infra = db.get_row() args['domain_id'] = infra['foreign_id'] ret['record'] = node_call(infra['node'], infra['server'], 'record_info', args) opres = str(ret['record'].get('update')) == "1" or str( ret['record'].get('insert')) == "1" if opres and (args['type'] in ['A', 'PTR']): ret['device'] = {'id': aDict['device_id']} ret['device']['update'] = db.do( "UPDATE devices SET %s_id = '%s' WHERE id = '%s'" % (aDict['type'].lower(), ret['record']['data']['id'], aDict['device_id'])) return ret
def record_delete(aDict): """Function docstring for record_delete TBD Args: - id (required) - domain_id (required) Output: """ args = aDict with DB() as db: db.do( "SELECT foreign_id, server, node FROM domain_servers LEFT JOIN domains ON domains.server_id = domain_servers.id WHERE domains.id = %s" % args['domain_id']) infra = db.get_row() args['domain_id'] = infra['foreign_id'] ret = node_call(infra['node'], infra['server'], 'record_delete', args) return ret
def top(aDict): """Function docstring for top TBD Args: - count (optional) Output: """ ret = {'top': {}, 'who': {}} args = {'count': aDict.get('count', 20)} with DB() as db: db.do( "SELECT server, node FROM domain_servers LEFT JOIN domains ON domains.server_id = domain_servers.id" ) servers = db.get_rows() for infra in servers: res = node_call(infra['node'], infra['server'], 'top', args) ret['top']["%s_%s" % (infra['node'], infra['server'])] = res['top'] ret['who']["%s_%s" % (infra['node'], infra['server'])] = res['who'] return ret
def record_info(aDict): """Function docstring for record_info TBD Args: - id (required) - domain_id (required) - name (optional) - content (optional) - type (optional) Output: """ ret = {} args = aDict domain_id = aDict['domain_id'] with DB() as db: if aDict['id'] == 'new' and not (aDict.get('op') == 'update'): ret['data'] = { 'id': 'new', 'domain_id': domain_id, 'name': 'key', 'content': 'value', 'type': 'type-of-record', 'ttl': '3600', 'foreign_id': 'NA' } else: db.do( "SELECT foreign_id, server, node FROM domain_servers LEFT JOIN domains ON domains.server_id = domain_servers.id WHERE domains.id = %s" % domain_id) infra = db.get_row() args['domain_id'] = infra['foreign_id'] ret = node_call(infra['node'], infra['server'], 'record_info', args) ret['data']['domain_id'] = domain_id return ret
def record_device_update(aDict): """Function docstring for record_device_update. Tries to update DNS server with new info and fetch A and PTR id if they exist... (None, A, A + PTR) "Tricky" part is when device MOVED from one domain to another AND this means server change, then we need to do delete first on old server. If IP address changed. Args: - id (required) id/new - ip (required) - hostname (required) - a_domain_id (required) - a_id (required) - id/0/new - ptr_id (required) - id/0/new Output: """ ret = { 'A': { 'xist': 0 }, 'PTR': { 'xist': 0 }, 'device': { 'xist': 0 }, 'server': {} } aDict['a_domain_id'] = int(aDict['a_domain_id']) data = {} def GL_ip2ptr(addr): octets = addr.split('.') octets.reverse() octets.append("in-addr.arpa") return ".".join(octets) with DB() as db: domains = {'name': {}, 'foreign_id': {}} db.do( "SELECT domains.id AS domain_id, server_id, foreign_id, name, server, node FROM domains LEFT JOIN domain_servers ON domains.server_id = domain_servers.id" ) domains['id'] = db.get_dict('domain_id') for dom in domains['id'].values(): domains['name'][dom['name']] = dom domains['foreign_id'][dom['foreign_id']] = dom ret['device']['xist'] = db.do( "SELECT hostname, a_dom_id AS a_domain_id, INET_NTOA(ip) AS ip FROM devices WHERE id = '%s'" % (aDict['id'])) if not aDict['id'] == 'new' else 0 device = db.get_row() if ret['device']['xist'] > 0 else None # # A record: check if valid domain, then if not a_id == 'new' make sure we didn't move server otherwise delete record and set a_id to new # a_id = 'new' if str(aDict['a_id']) == '0' else aDict['a_id'] infra = domains['id'].get(aDict['a_domain_id'], None) if not infra: return ret if a_id != 'new' and device: old = domains['id'].get(device['a_domain_id'], None) if old['server_id'] != infra['server_id']: ret['server']['A'] = node_call(old['node'], old['server'], 'record_delete', {'id': a_id}) a_id = 'new' else: ret['server']['A'] = 'remain' fqdn = "%s.%s" % (aDict['hostname'], infra['name']) data['A'] = { 'server': infra['server'], 'node': infra['node'], 'args': { 'type': 'A', 'id': a_id, 'domain_id': infra['foreign_id'], 'content': aDict['ip'], 'name': fqdn } } # # PTR record: check if valid domain, then if not a_id == 'new' make sure we didn't move server otherwise delete record and set ptr_id to new # ptr_id = 'new' if str(aDict['ptr_id']) == '0' else aDict['ptr_id'] ptr = GL_ip2ptr(aDict['ip']) arpa = ptr.partition('.')[2] infra = domains['name'].get(arpa, None) if infra and fqdn: if ptr_id != 'new' and device: old_ptr = GL_ip2ptr(device['ip']) old_arpa = ptr.partition('.')[2] old = domains['name'].get(old_arpa, None) if old['server_id'] != infra['server_id']: ret['server']['PTR'] = node_call(old['node'], old['server'], 'record_delete', {'id': ptr_id}) ptr_id = 'new' else: ret['server']['PTR'] = 'remain' data['PTR'] = { 'server': infra['server'], 'node': infra['node'], 'args': { 'type': 'PTR', 'id': ptr_id, 'domain_id': infra['foreign_id'], 'content': fqdn, 'name': ptr } } for type, infra in data.iteritems(): if infra['server']: infra['args']['op'] = 'update' res = node_call(infra['node'], infra['server'], 'record_info', infra['args']) ret[type]['record_id'] = res['data']['id'] ret[type]['domain_id'] = domains['foreign_id'].get( res['data']['domain_id'], {'domain_id': 0})['domain_id'] ret[type]['xist'] = res['xist'] ret[type]['update'] = res.get('update', 0) ret[type]['insert'] = res.get('insert', 0) return ret