#!/usr/bin/env python import os # miscellaneous operating system interfaces import sys # system paramteters from ddns_common import parms from ddns_common import file_suffix from ddns_common import get_ddns_key # initialize template/dictionary variables mappings = parms('ddns_config.yaml') key_name = 'cloud.ddns' key_value = get_ddns_key() text = "#!/bin/sh\n" text += "source ./openrc.sh\n" text += "python ddns.py\n" text += "nsupdate -y %s:%s -v %s\n" % (key_name, key_value, 'A_records') for net in mappings.value('ip_ranges'): filename = "PTR_%s" % file_suffix(net) text += "nsupdate -y %s:%s -v %s\n" % (key_name, key_value, filename) text += "rm A_records PTR_*" f = open('ddns.sh', 'w') f.write(text) f.close()
def revzone_filename(net): return "reverse.cloudzone.%s" % file_suffix(net)
def main(): # Authenticate Credentials try: creds = get_nova_creds() except: print 'Please set OpenStack credentials, e.g. type source openrc.sh, and try again' sys.exit() # Retrieve the Nova client nova = novaclient.Client(**creds) # get template/dictionary variables mappings = parms('ddns_config.yaml') domain_name = mappings.value('domain_name') dns_name = mappings.value('dns_shortname') + "." + domain_name # initialize content for forward and reverse nsupdate files content_A_rec = content("server " + dns_name + "\n") content_PTR = {} for net in mappings.value('ip_ranges'): revzone = reverse_dns_zone(net) text = "server %s\n" % dns_name text += "zone %s\n" % revzone content_PTR[net] = content(text) # load the previous server list from a file if os.path.isfile('ddns_instance_state.pckl'): f = open('ddns_instance_state.pckl') prev_servers = pickle.load(f) f.close() else: prev_servers = [] # create a current list of servers and IPs that are valid for DNS updates curr_servers = {} for server in nova.servers.list(search_opts={'all_tenants': 1}): if server.status != 'ACTIVE': print "INFO: Server name %s has state %s" % (server.name, server.status) elif not valid_hostname(server.name): print "WARNING: Server name %s is not a valid hostname" % server.name elif (server.name in prev_servers) and (server.networks.values() != prev_servers[server.name]): print "WARNING: Server %s/%s is a duplicate of Server %s/%s" % (server.name, server.networks.values()[0], server.name, prev_servers[server.name][0]) elif server.name in curr_servers.keys(): # keys refers to the server names print "WARNING: Server %s/%s is a duplicate of Server %s/%s" % (server.name, server.networks.values(), server.name, curr_servers[server.name][0]) else: curr_servers[server.name] = server.networks.values() # delete servers in the previous list but not in the current list for server_name in prev_servers: if not server_name in curr_servers: # get saved ip_address ip_addresses = prev_servers[server_name] # create long hostname server_name += '.' + domain_name # update forward zone content content_A_rec.append( "update delete " + server_name + " A\n") # update reverse zone content for ip in ip_addresses[0]: rev_net, rev_dns = get_reverse_net_dns(ip, mappings.value('ip_ranges')) content_PTR[rev_net].append( "update delete " + rev_dns + " 600 IN PTR " + server_name + ".\n") # Add new servers, e.g. those in the current list but not the previous one for server_name in curr_servers: if not server_name in prev_servers: # get the ip addresses, assume there is only one network, e.g. "nebula" ip_addresses = curr_servers[server_name] # create long hostname server_name += "." + domain_name # update forward zone content with address of the last ip address forward_ip = ip_addresses[0][-1] content_A_rec.append( "update add " + server_name + " 600 A " + forward_ip + "\n") # update reverse zone content for ip in ip_addresses[0]: rev_net, rev_dns = get_reverse_net_dns(ip, mappings.value('ip_ranges')) content_PTR[rev_net].append( "update add " + rev_dns + " 600 IN PTR " + server_name + ".\n") # write content content_A_rec.write('A_records') for net in mappings.value('ip_ranges'): filename = "PTR_%s" % file_suffix(net) content_PTR[net].write(filename) # dump current server list to a file f = open('ddns_instance_state.pckl', 'w') pickle.dump(curr_servers, f) f.close()
def main(): # Authenticate Credentials try: creds = get_nova_creds() except: print 'Please set OpenStack credentials, e.g. type source openrc.sh, and try again' sys.exit() # Retrieve the Nova client nova = novaclient.Client(**creds) # get template/dictionary variables mappings = parms('ddns_config.yaml') domain_name = mappings.value('domain_name') dns_name = mappings.value('dns_shortname') + "." + domain_name # initialize content for forward and reverse nsupdate files content_A_rec = content("server " + dns_name + "\n") content_PTR = {} for net in mappings.value('ip_ranges'): revzone = reverse_dns_zone(net) text = "server %s\n" % dns_name text += "zone %s\n" % revzone content_PTR[net] = content(text) # load the previous server list from a file if os.path.isfile('ddns_instance_state.pckl'): f = open('ddns_instance_state.pckl') prev_servers = pickle.load(f) f.close() else: prev_servers = [] # create a current list of servers and IPs that are valid for DNS updates curr_servers = {} for server in nova.servers.list(search_opts={'all_tenants': 1}): if server.status != 'ACTIVE': print "INFO: Server name %s has state %s" % (server.name, server.status) elif not valid_hostname(server.name): print "WARNING: Server name %s is not a valid hostname" % server.name elif (server.name in prev_servers) and (server.networks.values() != prev_servers[server.name]): print "WARNING: Server %s/%s is a duplicate of Server %s/%s" % ( server.name, server.networks.values()[0], server.name, prev_servers[server.name][0]) elif server.name in curr_servers.keys( ): # keys refers to the server names print "WARNING: Server %s/%s is a duplicate of Server %s/%s" % ( server.name, server.networks.values(), server.name, curr_servers[server.name][0]) else: curr_servers[server.name] = server.networks.values() # delete servers in the previous list but not in the current list for server_name in prev_servers: if not server_name in curr_servers: # get saved ip_address ip_addresses = prev_servers[server_name] # create long hostname server_name += '.' + domain_name # update forward zone content content_A_rec.append("update delete " + server_name + " A\n") # update reverse zone content for ip in ip_addresses[0]: rev_net, rev_dns = get_reverse_net_dns( ip, mappings.value('ip_ranges')) content_PTR[rev_net].append("update delete " + rev_dns + " 600 IN PTR " + server_name + ".\n") # Add new servers, e.g. those in the current list but not the previous one for server_name in curr_servers: if not server_name in prev_servers: # get the ip addresses, assume there is only one network, e.g. "nebula" ip_addresses = curr_servers[server_name] # create long hostname server_name += "." + domain_name # update forward zone content with address of the last ip address forward_ip = ip_addresses[0][-1] content_A_rec.append("update add " + server_name + " 600 A " + forward_ip + "\n") # update reverse zone content for ip in ip_addresses[0]: rev_net, rev_dns = get_reverse_net_dns( ip, mappings.value('ip_ranges')) content_PTR[rev_net].append("update add " + rev_dns + " 600 IN PTR " + server_name + ".\n") # write content content_A_rec.write('A_records') for net in mappings.value('ip_ranges'): filename = "PTR_%s" % file_suffix(net) content_PTR[net].write(filename) # dump current server list to a file f = open('ddns_instance_state.pckl', 'w') pickle.dump(curr_servers, f) f.close()