#!/usr/bin/python2

import sys
import os
import subprocess
import optparse
import time

class DNSData(object):
    '''
    Dumps DNS Data into a hosts file.
    '''
    def __init__(self, opts):
        self.opts = opts
        self.ips = set()

    def _get_hosts(self):
        '''
        Run the host command on all the addrs...
        No, run nmap...
        No, parse the leases file and then run host on all of the leases
        '''
        hosts = {}
        leases_fn = '/var/lib/misc/dnsmasq.leases'
        for line in open(leases_fn, 'r').readlines():
            self.ips.add(line.split()[2])
        for ip in self.ips:
            h_cmd = ['host', ip]
            out = subprocess.Popen(h_cmd,
                    stdout=subprocess.PIPE).communicate()[0]
            if out.count('not found'):
                self.ips.remove(ip)
                continue
            hosts[out.split()[-1][:-1]] = ip

        return hosts

    def _get_static(self):
        '''
        Parses the dnsmasq configuration and adds all static hosts files to the
        exported hosts file
        '''
        static_lines = []
        addn_hosts = []
        dnsc = '/etc/dnsmasq.conf'
        for line in open(dnsc, 'r').readlines():
            if line.startswith('addn-hosts='):
                addn_hosts.append(line.split('=')[1].strip())
        for addn in addn_hosts:
            if not os.path.isfile(addn):
                continue
            for line in open(addn, 'r').readlines():
                if line.startswith('#'):
                    continue
                static_lines.append(line)
        return static_lines


    def gen_file(self):
        '''
        Generates the string used in the hosts file
        '''
        hosts = self._get_hosts()
        static = self._get_static()
        hfile = ['## Begin Generated Hosts ##\n']
        for host in hosts:
            line = hosts[host] + '\t\t' + host
            hfile.append(line + '\n')

        hfile.append('#  Begin Static Hosts  #\n')

        for host in static:
            hfile.append(host)

        hfile.append('#  End Static Hosts  #\n')
        hfile.append('## End Generated Hosts ##\n')

        return hfile

    def save_hosts(self, hfile):
        '''
        Save the hosts file.
        '''
        if not os.path.isdir(os.path.dirname(self.opts['location'])):
            os.makedirs(os.path.dirname(self.opts['location']))
        open(self.opts['location'], 'w+').writelines(hfile)


    def start_rsync(self):
        '''
        Start the rsync daemon
        '''
        c_path = '/var/tmp/host-sync.conf'
        conf = ['[hosts]\n',
                'path = ' + os.path.dirname(self.opts['location'])  + '\n'
                'read only = yes\n']
        open(c_path, 'w+').writelines(conf)
        r_cmd = 'rsync --daemon --config=/var/tmp/host-sync.conf --port=9426'
        subprocess.call(r_cmd, shell=True)

    def run_daemon(self):
        '''
        Start dnsdump running as a daemon.. Ok, I don't have the pid fork stuff
        in here, run this in the background!
        '''
        self.start_rsync()
        while True:
            self.save_hosts(data.gen_file())
            time.sleep(600)


def datacenter():
    '''
    Returns the datacenter number
    '''
    d_cmd = "ip a | grep 172 | grep brd | awk '{print $2}' | cut -d. -f2"
    return subprocess.Popen(d_cmd,
            shell=True,
            stdout=subprocess.PIPE).communicate()[0][0]

def detect_networks():
    '''
    Parse all of the dnsmasq configuration files
    '''
    dnsc = '/etc/dnsmasq.conf'
    nets = set()
    conf_files = set()
    for line in open(dnsc, 'r').readlines():
        if line.startswith('domain='):
            dom = line.split(',')
            if dom.__len__() > 1:
                nets.add(dom[1])
        elif line.startswith('conf-dir='):
            cdir = line.split('=')[1].strip()
            if os.path.isdir(cdir):
                for fn_ in os.listdir(cdir):
                    if fn_.endswith('.conf'):
                        conf_files.add(os.path.join(cdir, fn_))
    for cfn in conf_files:
        if not os.path.isfile(cfn):
            continue
        for line in open(cfn, 'r').readlines():
            if line.startswith('domain='):
                dom = line.split(',')
                if dom.__len__() > 1:
                    nets.add(dom[1].strip())
    return nets


def parse():
    '''
    Parse the command line arguments
    '''
    parser = optparse.OptionParser()

    parser.add_option('-n',
            '--networks',
            default='',
            dest='networks',
            help='A comma delimited list of ip/mask networks')

    parser.add_option('-l',
            '--location',
            default='/var/tmp/dnsdump/hosts',
            dest='location',
            help='The local location to store the geneared hosts file')

    parser.add_option('-d',
            '--no-detect',
            default=False,
            dest='no_detect',
            action='store_true',
            help='Pass this flag if you wish to disable network'\
            + 'autodetection and just use the networks passed on the command'\
            + 'line.')

    options, args = parser.parse_args()

    opts = {}

    opts['networks'] = set()

    if options.networks:
        opts['networks'].update(options.networks.split(':'))
    else:
        options.no_detect = False
    if not options.no_detect:
        opts['networks'].update(detect_networks())

#    if not options.networks:
#        dc_ = datacenter()
#        networks = '172.DC0.1.0/24:172.DC0.2.0/24:172.DC1.0.0/24:172.DC1.1.0/24:10.DC0.0.0/24:10.DC0.1.0/24:172.DC2.0.0/16:172.DC3.0.0/16:10.DC3.0.0/16:172.DC4.0.0/16'
#        options.networks = networks.replace('DC', dc_)

    opts['location'] = options.location

    return opts

if __name__ == '__main__':
    opts = parse()
    data = DNSData(opts)
    data.run_daemon()
