Example #1
0
 def write_hosts(self):
     file = CsFile("/etc/hosts")
     file.repopulate()
     for ip in self.hosts:
         file.add("%s\t%s" % (ip, self.hosts[ip]))
     if file.is_changed():
         file.commit()
         logging.info("Updated hosts file")
     else:
         logging.debug("Hosts file unchanged")
Example #2
0
 def write_hosts(self):
     file = CsFile("/etc/hosts")
     file.repopulate()
     for ip in self.hosts:
         file.add("%s\t%s" % (ip, self.hosts[ip]))
     file.commit()
     if file.is_changed():
         logging.info("Updated hosts file")
     else:
         logging.debug("Hosts file unchanged")
Example #3
0
class CsDhcp(CsDataBag):
    """ Manage dhcp entries """

    def process(self):
        self.hosts = {}
        self.changed = []
        self.devinfo = CsHelper.get_device_info()
        self.preseed()
        self.cloud = CsFile(DHCP_HOSTS)
        self.conf = CsFile(CLOUD_CONF)

        self.cloud.repopulate()

        for item in self.dbag:
            if item == "id":
                continue
            self.add(self.dbag[item])
        self.write_hosts()
        
        if self.cloud.is_changed():
            self.delete_leases()

        self.configure_server()

        self.conf.commit()
        self.cloud.commit()

        # We restart DNSMASQ every time the configure.py is called in order to avoid lease problems.
        if not self.cl.is_redundant() or self.cl.is_master():
            CsHelper.service("dnsmasq", "restart")

    def configure_server(self):
        # self.conf.addeq("dhcp-hostsfile=%s" % DHCP_HOSTS)
        for i in self.devinfo:
            if not i['dnsmasq']:
                continue
            device = i['dev']
            ip = i['ip'].split('/')[0]
            sline = "dhcp-range=interface:%s,set:interface" % (device)
            line = "dhcp-range=interface:%s,set:interface-%s,%s,static" % (device, device, ip)
            self.conf.search(sline, line)
            gn = CsGuestNetwork(device, self.config)
            sline = "dhcp-option=tag:interface-%s,15" % device
            line = "dhcp-option=tag:interface-%s,15,%s" % (device, gn.get_domain())
            self.conf.search(sline, line)
            # DNS search order
            if gn.get_dns() and device:
                sline = "dhcp-option=tag:interface-%s,6" % device
                dns_list = [x for x in gn.get_dns() if x is not None]
                line = "dhcp-option=tag:interface-%s,6,%s" % (device, ','.join(dns_list))
                self.conf.search(sline, line)
            # Gateway
            gateway = ''
            if self.config.is_vpc():
                gateway = gn.get_gateway()
            else:
                gateway = i['gateway']
            sline = "dhcp-option=tag:interface-%s,3," % device
            line = "dhcp-option=tag:interface-%s,3,%s" % (device, gateway)
            self.conf.search(sline, line)
            # Netmask
            netmask = ''
            if self.config.is_vpc():
                netmask = gn.get_netmask()
            else:
                netmask = self.config.address().get_guest_netmask()
            sline = "dhcp-option=tag:interface-%s,1," % device
            line = "dhcp-option=tag:interface-%s,1,%s" % (device, netmask)
            self.conf.search(sline, line)

    def delete_leases(self):
        try:
            open(LEASES, 'w').close()
        except IOError:
            return

    def preseed(self):
        self.add_host("127.0.0.1", "localhost")
        self.add_host("::1",     "localhost ip6-localhost ip6-loopback")
        self.add_host("ff02::1", "ip6-allnodes")
        self.add_host("ff02::2", "ip6-allrouters")
        if self.config.is_vpc():
            self.add_host("127.0.0.1", CsHelper.get_hostname())
        if self.config.is_router():
            self.add_host(self.config.address().get_guest_ip(), "%s data-server" % CsHelper.get_hostname())

    def write_hosts(self):
        file = CsFile("/etc/hosts")
        file.repopulate()
        for ip in self.hosts:
            file.add("%s\t%s" % (ip, self.hosts[ip]))
        if file.is_changed():
            file.commit()
            logging.info("Updated hosts file")
        else:
            logging.debug("Hosts file unchanged")

    def add(self, entry):
        self.add_host(entry['ipv4_adress'], entry['host_name'])
        self.cloud.add("%s,%s,%s,infinite" % (entry['mac_address'],
                                              entry['ipv4_adress'],
                                              entry['host_name']))
        i = IPAddress(entry['ipv4_adress'])
        # Calculate the device
        for v in self.devinfo:
            if i > v['network'].network and i < v['network'].broadcast:
                v['dnsmasq'] = True
                # Virtual Router
                v['gateway'] = entry['default_gateway']

    def add_host(self, ip, hosts):
        self.hosts[ip] = hosts
Example #4
0
class CsVrConfig(CsDataBag):
    def process(self):
        logging.debug("Processing CsVrConfig file ==> %s" % self.dbag)

        syslogserverlist = ""

        for item in self.dbag:
            if item == "id":
                continue

            if item == "source_nat_list":
                self._configure_firewall(self.dbag[item])

            if item == "syslog_server_list":
                syslogserverlist = self.dbag[item]

        self._configure_syslog(syslogserverlist)

    def _configure_firewall(self, sourcenatlist):
        firewall = self.config.get_fw()

        logging.debug("Processing source NAT list: %s" % sourcenatlist)
        for cidr in sourcenatlist.split(','):
            firewall.append([
                "filter", "",
                "-A SOURCE_NAT_LIST -o eth1 -s %s -j ACCEPT" % cidr
            ])

    def _configure_syslog(self, syslogserverlist):
        self.syslogconf = CsFile(RSYSLOG_IPTABLES_CONF)
        self.syslogconf.repopulate()

        logging.debug("Processing syslog server list: %s" % syslogserverlist)
        ips = filter(bool, syslogserverlist.split(','))
        if not ips:
            # no IP in the syslog server list; reset the config to default:
            self.syslogconf.append(
                "# no remote syslog servers so stop further processing")
            self.syslogconf.append("# this file is managed by CsVrConfig.py")
            self.syslogconf.append(
                ":msg, regex, \"^\[ *[0-9]*\.[0-9]*\] iptables denied: \" ~")
        else:
            # add IPs from the syslog server list to the config:
            self.syslogconf.append(
                "# forwarding IP tables syslog to %s and stop further processing"
                % syslogserverlist)
            self.syslogconf.append("# this file is managed by CsVrConfig.py")
            first = True
            for ip in ips:
                if first:
                    self.syslogconf.append(
                        ":msg, regex, \"^\[ *[0-9]*\.[0-9]*\] iptables denied: \" @@%s:514"
                        % ip)
                    first = False
                else:
                    self.syslogconf.append("& @@%s:514" % ip)

            self.syslogconf.append("& ~")

        changed = self.syslogconf.is_changed()
        self.syslogconf.commit()
        if changed:
            CsHelper.execute2("service rsyslog restart")
Example #5
0
class CsDhcp(CsDataBag):
    """ Manage dhcp entries """
    def process(self):
        self.hosts = {}
        self.changed = []
        self.devinfo = CsHelper.get_device_info()
        self.preseed()
        self.cloud = CsFile(DHCP_HOSTS)
        self.conf = CsFile(CLOUD_CONF)

        self.cloud.repopulate()

        for item in self.dbag:
            if item == "id":
                continue
            self.add(self.dbag[item])
        self.write_hosts()

        if self.cloud.is_changed():
            self.delete_leases()

        self.configure_server()

        self.conf.commit()
        self.cloud.commit()

        # We restart DNSMASQ every time the configure.py is called in order to avoid lease problems.
        if not self.cl.is_redundant() or self.cl.is_master():
            CsHelper.service("dnsmasq", "restart")

    def configure_server(self):
        # self.conf.addeq("dhcp-hostsfile=%s" % DHCP_HOSTS)
        for i in self.devinfo:
            if not i['dnsmasq']:
                continue
            device = i['dev']
            ip = i['ip'].split('/')[0]
            sline = "dhcp-range=interface:%s,set:interface" % (device)
            line = "dhcp-range=interface:%s,set:interface-%s,%s,static" % (
                device, device, ip)
            self.conf.search(sline, line)
            gn = CsGuestNetwork(device, self.config)
            sline = "dhcp-option=tag:interface-%s,15" % device
            line = "dhcp-option=tag:interface-%s,15,%s" % (device,
                                                           gn.get_domain())
            self.conf.search(sline, line)
            # DNS search order
            if gn.get_dns() and device:
                sline = "dhcp-option=tag:interface-%s,6" % device
                dns_list = [x for x in gn.get_dns() if x is not None]
                line = "dhcp-option=tag:interface-%s,6,%s" % (
                    device, ','.join(dns_list))
                self.conf.search(sline, line)
            # Gateway
            gateway = ''
            if self.config.is_vpc():
                gateway = gn.get_gateway()
            else:
                gateway = i['gateway']
            sline = "dhcp-option=tag:interface-%s,3," % device
            line = "dhcp-option=tag:interface-%s,3,%s" % (device, gateway)
            self.conf.search(sline, line)
            # Netmask
            netmask = ''
            if self.config.is_vpc():
                netmask = gn.get_netmask()
            else:
                netmask = self.config.address().get_guest_netmask()
            sline = "dhcp-option=tag:interface-%s,1," % device
            line = "dhcp-option=tag:interface-%s,1,%s" % (device, netmask)
            self.conf.search(sline, line)

    def delete_leases(self):
        try:
            open(LEASES, 'w').close()
        except IOError:
            return

    def preseed(self):
        self.add_host("127.0.0.1", "localhost")
        self.add_host("::1", "localhost ip6-localhost ip6-loopback")
        self.add_host("ff02::1", "ip6-allnodes")
        self.add_host("ff02::2", "ip6-allrouters")
        if self.config.is_vpc():
            self.add_host("127.0.0.1", CsHelper.get_hostname())
        if self.config.is_router():
            self.add_host(self.config.address().get_guest_ip(),
                          "%s data-server" % CsHelper.get_hostname())

    def write_hosts(self):
        file = CsFile("/etc/hosts")
        file.repopulate()
        for ip in self.hosts:
            file.add("%s\t%s" % (ip, self.hosts[ip]))
        if file.is_changed():
            file.commit()
            logging.info("Updated hosts file")
        else:
            logging.debug("Hosts file unchanged")

    def add(self, entry):
        self.add_host(entry['ipv4_adress'], entry['host_name'])
        self.cloud.add(
            "%s,%s,%s,infinite" %
            (entry['mac_address'], entry['ipv4_adress'], entry['host_name']))
        i = IPAddress(entry['ipv4_adress'])
        # Calculate the device
        for v in self.devinfo:
            if i > v['network'].network and i < v['network'].broadcast:
                v['dnsmasq'] = True
                # Virtual Router
                v['gateway'] = entry['default_gateway']

    def add_host(self, ip, hosts):
        self.hosts[ip] = hosts
Example #6
0
class CsDhcp(CsDataBag):
    """ Manage dhcp entries """

    def process(self):
        self.hosts = {}
        self.changed = []
        self.devinfo = CsHelper.get_device_info()
        self.preseed()
        self.dhcp_hosts = CsFile(DHCP_HOSTS)
        self.dhcp_opts = CsFile(DHCP_OPTS)
        self.conf = CsFile(CLOUD_CONF)
        self.dhcp_leases = CsFile(LEASES)

        self.dhcp_hosts.repopulate()
        self.dhcp_opts.repopulate()

        for item in self.dbag:
            if item == "id":
                continue
            if not self.dbag[item]['remove']:
                self.add(self.dbag[item])

        self.configure_server()

        restart_dnsmasq = False
        need_delete_leases = False

        if self.conf.commit():
            restart_dnsmasq = True
            need_delete_leases = True

        if self.dhcp_hosts.commit():
            need_delete_leases = True

        if self.dhcp_leases.commit():
            need_delete_leases = True

        self.dhcp_opts.commit()

        if need_delete_leases:
            self.delete_leases()
        self.write_hosts()

        if not self.cl.is_redundant() or self.cl.is_primary():
            if restart_dnsmasq:
                CsHelper.service("dnsmasq", "restart")
            else:
                CsHelper.start_if_stopped("dnsmasq")
                CsHelper.service("dnsmasq", "reload")

    def configure_server(self):
        # self.conf.addeq("dhcp-hostsfile=%s" % DHCP_HOSTS)
        idx = 0
        listen_address = ["127.0.0.1"]
        for i in self.devinfo:
            if not i['dnsmasq']:
                continue
            device = i['dev']
            ip = i['ip'].split('/')[0]
            gn = CsGuestNetwork(device, self.config)
            # Gateway
            gateway = ''
            if self.config.is_vpc():
                gateway = gn.get_gateway()
            else:
                gateway = i['gateway']
            sline = "dhcp-range=set:interface-%s-%s" % (device, idx)
            if self.cl.is_redundant():
                line = "dhcp-range=set:interface-%s-%s,%s,static" % (device, idx, gateway)
            else:
                line = "dhcp-range=set:interface-%s-%s,%s,static" % (device, idx, ip)
            self.conf.search(sline, line)
            sline = "dhcp-option=tag:interface-%s-%s,15" % (device, idx)
            line = "dhcp-option=tag:interface-%s-%s,15,%s" % (device, idx, gn.get_domain())
            self.conf.search(sline, line)
            # DNS search order
            if gn.get_dns() and device:
                sline = "dhcp-option=tag:interface-%s-%s,6" % (device, idx)
                dns_list = [x for x in gn.get_dns() if x]
                line = "dhcp-option=tag:interface-%s-%s,6,%s" % (device, idx, ','.join(dns_list))
                self.conf.search(sline, line)
            if gateway != '0.0.0.0':
                sline = "dhcp-option=tag:interface-%s-%s,3," % (device, idx)
                line = "dhcp-option=tag:interface-%s-%s,3,%s" % (device, idx, gateway)
                self.conf.search(sline, line)
            # Netmask
            netmask = ''
            if self.config.is_vpc():
                netmask = gn.get_netmask()
            else:
                netmask = str(i['network'].netmask)
            sline = "dhcp-option=tag:interface-%s-%s,1," % (device, idx)
            line = "dhcp-option=tag:interface-%s-%s,1,%s" % (device, idx, netmask)
            self.conf.search(sline, line)
            # Listen Address
            if self.cl.is_redundant():
                listen_address.append(gateway)
            else:
                listen_address.append(ip)
            # Add localized "data-server" records in /etc/hosts for VPC routers
            if self.config.is_vpc():
                self.add_host(gateway, "%s data-server" % CsHelper.get_hostname())
            idx += 1

        # Listen Address
        sline = "listen-address="
        line = "listen-address=%s" % (','.join(listen_address))
        self.conf.search(sline, line)

    def delete_leases(self):
        macs_dhcphosts = []
        try:
            logging.info("Attempting to delete entries from dnsmasq.leases file for VMs which are not on dhcphosts file")
            for host in open(DHCP_HOSTS):
                macs_dhcphosts.append(host.split(',')[0])

            removed = 0
            for leaseline in open(LEASES):
                lease = leaseline.split(' ')
                mac = lease[1]
                ip = lease[2]
                if mac not in macs_dhcphosts:
                    cmd = "dhcp_release $(ip route get %s | grep eth | head -1 | awk '{print $3}') %s %s" % (ip, ip, mac)
                    logging.info(cmd)
                    CsHelper.execute(cmd)
                    removed = removed + 1
                    self.del_host(ip)
            logging.info("Deleted %s entries from dnsmasq.leases file" % str(removed))
        except Exception as e:
            logging.error("Caught error while trying to delete entries from dnsmasq.leases file: %s" % e)

    def preseed(self):
        self.add_host("127.0.0.1", "localhost")
        self.add_host("127.0.1.1", "%s" % CsHelper.get_hostname())
        self.add_host("::1", "localhost ip6-localhost ip6-loopback")
        self.add_host("ff02::1", "ip6-allnodes")
        self.add_host("ff02::2", "ip6-allrouters")
        if self.config.is_router() or self.config.is_dhcp():
            self.add_host(self.config.address().get_guest_ip(), "%s data-server" % CsHelper.get_hostname())

    def write_hosts(self):
        file = CsFile("/etc/hosts")
        file.repopulate()
        for ip in self.hosts:
            file.add("%s\t%s" % (ip, self.hosts[ip]))
        if file.is_changed():
            file.commit()
            logging.info("Updated hosts file")
        else:
            logging.debug("Hosts file unchanged")

    def add(self, entry):
        self.add_host(entry['ipv4_address'], entry['host_name'])
        # Lease time set to "infinite" since we properly control all DHCP/DNS config via CloudStack.
        # Infinite time helps avoid some edge cases which could cause DHCPNAK being sent to VMs since
        # (RHEL) system lose routes when they receive DHCPNAK.
        # When VM is expunged, its active lease and DHCP/DNS config is properly removed from related files in VR,
        # so the infinite duration of lease does not cause any issues or garbage.
        lease = 'infinite'

        if entry['default_entry']:
            self.dhcp_hosts.add("%s,%s,%s,%s" % (entry['mac_address'],
                                                 entry['ipv4_address'],
                                                 entry['host_name'],
                                                 lease))
            self.dhcp_leases.search(entry['mac_address'], "0 %s %s %s *" % (entry['mac_address'],
                                                                            entry['ipv4_address'],
                                                                            entry['host_name']))
        else:
            tag = entry['ipv4_address'].replace(".", "_")
            self.dhcp_hosts.add("%s,set:%s,%s,%s,%s" % (entry['mac_address'],
                                                        tag,
                                                        entry['ipv4_address'],
                                                        entry['host_name'],
                                                        lease))
            self.dhcp_opts.add("%s,%s" % (tag, 3))
            self.dhcp_opts.add("%s,%s" % (tag, 6))
            self.dhcp_opts.add("%s,%s" % (tag, 15))
            self.dhcp_leases.search(entry['mac_address'], "0 %s %s %s *" % (entry['mac_address'],
                                                                            entry['ipv4_address'],
                                                                            entry['host_name']))

        i = IPAddress(entry['ipv4_address'])
        # Calculate the device
        for v in self.devinfo:
            if i > v['network'].network and i < v['network'].broadcast:
                v['dnsmasq'] = True
                # Virtual Router
                v['gateway'] = entry['default_gateway']

    def add_host(self, ip, hosts):
        self.hosts[ip] = hosts

    def del_host(self, ip):
        if ip in self.hosts:
            self.hosts.pop(ip)
Example #7
0
class CsDhcp(CsDataBag):
    """ Manage dhcp entries """
    def process(self):
        self.hosts = {}
        self.changed = []
        self.devinfo = CsHelper.get_device_info()
        self.preseed()
        self.cloud = CsFile(DHCP_HOSTS)
        self.dhcp_opts = CsFile(DHCP_OPTS)
        self.conf = CsFile(CLOUD_CONF)

        self.cloud.repopulate()
        self.dhcp_opts.repopulate()

        for item in self.dbag:
            if item == "id":
                continue
            self.add(self.dbag[item])
            if self.dbag[item]['default_gateway'] == "0.0.0.0":
                self.add_dhcp_opts(self.dbag[item])

        self.write_hosts()

        if self.cloud.is_changed():
            self.delete_leases()

        self.configure_server()

        self.conf.commit()
        self.cloud.commit()
        self.dhcp_opts.commit()

        # We restart DNSMASQ every time the configure.py is called in order to avoid lease problems.
        # But only do that on the master or else VMs will get leases from the backup resulting in
        # Cloud-init to get the passwd and other meta-data from the backup as well.
        if not self.cl.is_redundant() or self.cl.is_master():
            CsHelper.execute2("service dnsmasq restart")

    def configure_server(self):
        # self.conf.addeq("dhcp-hostsfile=%s" % DHCP_HOSTS)
        idx = 0
        for i in self.devinfo:
            if not i['dnsmasq']:
                continue
            device = i['dev']
            # Listen only on the interfaces we configure VMs on
            sline = "interface=%s" % (device)
            line = "interface=%s" % (device)
            self.conf.search(sline, line)
            # Ip address
            ip = i['ip'].split('/')[0]
            sline = "dhcp-range=interface:%s,set:interface-%s-%s" % (
                device, device, idx)
            line = "dhcp-range=interface:%s,set:interface-%s-%s,%s,static" % (
                device, device, idx, ip)
            self.conf.search(sline, line)
            gn = CsGuestNetwork(device, self.config)
            sline = "dhcp-option=tag:interface-%s-%s,15" % (device, idx)
            line = "dhcp-option=tag:interface-%s-%s,15,%s" % (device, idx,
                                                              gn.get_domain())
            self.conf.search(sline, line)
            # DNS search order
            if gn.get_dns() and device:
                sline = "dhcp-option=tag:interface-%s-%s,6" % (device, idx)
                dns_list = [x for x in gn.get_dns() if x is not None]
                line = "dhcp-option=tag:interface-%s-%s,6,%s" % (
                    device, idx, ','.join(dns_list))
                self.conf.search(sline, line)
            # Gateway
            gateway = ''
            if self.config.is_vpc():
                gateway = gn.get_gateway()
            else:
                gateway = i['gateway']
            if gateway != '0.0.0.0':
                sline = "dhcp-option=tag:interface-%s-%s,3," % (device, idx)
                line = "dhcp-option=tag:interface-%s-%s,3,%s" % (device, idx,
                                                                 gateway)
                self.conf.search(sline, line)
            # Netmask
            netmask = ''
            if self.config.is_vpc():
                netmask = gn.get_netmask()
            else:
                netmask = self.config.address().get_guest_netmask()
            sline = "dhcp-option=tag:interface-%s-%s,1," % (device, idx)
            line = "dhcp-option=tag:interface-%s-%s,1,%s" % (device, idx,
                                                             netmask)
            self.conf.search(sline, line)
            idx += 1

    def delete_leases(self):
        try:
            open(LEASES, 'w').close()
        except IOError:
            return

    def preseed(self):
        self.add_host("127.0.0.1", "localhost %s" % CsHelper.get_hostname())
        self.add_host("::1", "localhost ip6-localhost ip6-loopback")
        self.add_host("ff02::1", "ip6-allnodes")
        self.add_host("ff02::2", "ip6-allrouters")
        if self.config.is_router():
            self.add_host(self.config.address().get_guest_ip(),
                          "%s data-server" % CsHelper.get_hostname())

    def write_hosts(self):
        file = CsFile("/etc/hosts")
        file.repopulate()
        for ip in self.hosts:
            file.add("%s\t%s" % (ip, self.hosts[ip]))
        if file.is_changed():
            file.commit()
            logging.info("Updated hosts file")
        else:
            logging.debug("Hosts file unchanged")

    def add(self, entry):
        self.add_host(entry['ipv4_adress'], entry['host_name'])
        tag = "set:" + str(entry['ipv4_adress']).replace(".", "_")
        self.cloud.add("%s,%s,%s,%s,infinite" %
                       (entry['mac_address'], tag, entry['ipv4_adress'],
                        entry['host_name']))
        i = IPAddress(entry['ipv4_adress'])
        # Calculate the device
        for v in self.devinfo:
            if i > v['network'].network and i < v['network'].broadcast:
                v['dnsmasq'] = True
                # Virtual Router
                v['gateway'] = entry['default_gateway']

    def add_dhcp_opts(self, entry):
        # This means we won't serve these DHCP options for hosts with this tag
        tag = str(entry['ipv4_adress']).replace(".", "_")
        self.dhcp_opts.add("%s,%s" % (tag, 3))
        self.dhcp_opts.add("%s,%s" % (tag, 6))
        self.dhcp_opts.add("%s,%s" % (tag, 15))

    def add_host(self, ip, hosts):
        self.hosts[ip] = hosts
Example #8
0
    def configure_ipsec(self, obj):
        leftpeer = obj['local_public_ip']
        rightpeer = obj['peer_gateway_ip']
        peerlist = obj['peer_guest_cidr_list'].replace(' ', '')
        vpnconffile = "%s/ipsec.vpn-%s.conf" % (self.VPNCONFDIR, rightpeer)
        vpnsecretsfile = "%s/ipsec.vpn-%s.secrets" % (self.VPNCONFDIR,
                                                      rightpeer)
        ikepolicy = obj['ike_policy'].replace(';', '-')
        esppolicy = obj['esp_policy'].replace(';', '-')
        splitconnections = obj[
            'split_connections'] if 'split_connections' in obj else False
        ikeversion = obj['ike_version'] if 'ike_version' in obj and obj[
            'ike_version'].lower() in ('ike', 'ikev1', 'ikev2') else 'ike'

        peerlistarr = peerlist.split(',')
        if splitconnections:
            logging.debug('Splitting rightsubnets %s' % peerlistarr)
            peerlist = peerlistarr[0]

        if rightpeer in self.confips:
            self.confips.remove(rightpeer)
        file = CsFile(vpnconffile)
        file.repopulate(
        )  # This avoids issues when switching off split_connections or removing subnets with split_connections == true
        file.add("#conn for vpn-%s" % rightpeer, 0)
        file.search("conn ", "conn vpn-%s" % rightpeer)
        file.addeq(" left=%s" % leftpeer)
        file.addeq(" leftsubnet=%s" % obj['local_guest_cidr'])
        file.addeq(" right=%s" % rightpeer)
        file.addeq(" rightsubnet=%s" % peerlist)
        file.addeq(" type=tunnel")
        file.addeq(" authby=secret")
        file.addeq(" keyexchange=%s" % ikeversion)
        file.addeq(" ike=%s" % ikepolicy)
        file.addeq(" ikelifetime=%s" %
                   self.convert_sec_to_h(obj['ike_lifetime']))
        file.addeq(" esp=%s" % esppolicy)
        file.addeq(" lifetime=%s" % self.convert_sec_to_h(obj['esp_lifetime']))
        file.addeq(" keyingtries=2")
        file.addeq(" auto=route")
        if 'encap' not in obj:
            obj['encap'] = False
        file.addeq(" forceencaps=%s" % CsHelper.bool_to_yn(obj['encap']))
        if obj['dpd']:
            file.addeq(" dpddelay=30")
            file.addeq(" dpdtimeout=120")
            file.addeq(" dpdaction=restart")
        if splitconnections and peerlistarr.count > 1:
            logging.debug('Splitting connections for rightsubnets %s' %
                          peerlistarr)
            for peeridx in range(1, len(peerlistarr)):
                logging.debug('Adding split connection -%d for subnet %s' %
                              (peeridx + 1, peerlistarr[peeridx]))
                file.append('')
                file.search('conn vpn-.*-%d' % (peeridx + 1),
                            "conn vpn-%s-%d" % (rightpeer, peeridx + 1))
                file.append(' also=vpn-%s' % rightpeer)
                file.append(' rightsubnet=%s' % peerlistarr[peeridx])
        secret = CsFile(vpnsecretsfile)
        secret.search(
            "%s " % leftpeer,
            "%s %s : PSK \"%s\"" % (leftpeer, rightpeer, obj['ipsec_psk']))
        if secret.is_changed() or file.is_changed():
            secret.commit()
            file.commit()
            logging.info("Configured vpn %s %s", leftpeer, rightpeer)
            CsHelper.execute("ipsec rereadsecrets")

        # This will load the new config
        CsHelper.execute("ipsec reload")
        os.chmod(vpnsecretsfile, 0400)

        for i in xrange(3):
            done = True
            for peeridx in range(0, len(peerlistarr)):
                # Check for the proper connection and subnet
                conn = rightpeer if not splitconnections else rightpeer if peeridx == 0 else '%s-%d' % (
                    rightpeer, peeridx + 1)
                result = CsHelper.execute('ipsec status vpn-%s | grep "%s"' %
                                          (conn, peerlistarr[peeridx]))
                # If any of the peers hasn't yet finished, continue the outer loop
                if len(result) == 0:
                    done = False
            if done:
                break
            time.sleep(1)

        # With 'auto=route', connections are established on an attempt to
        # communicate over the S2S VPN. This uses ping to initialize the connection.
        for peer in peerlistarr:
            octets = peer.split('/', 1)[0].split('.')
            octets[3] = str((int(octets[3]) + 1))
            ipinsubnet = '.'.join(octets)
            CsHelper.execute("timeout 5 ping -c 3 %s" % ipinsubnet)
Example #9
0
class CsDhcp(CsDataBag):
    """ Manage dhcp entries """

    def process(self):
        self.hosts = {}
        self.changed = []
        self.devinfo = CsHelper.get_device_info()
        self.preseed()
        self.cloud = CsFile(DHCP_HOSTS)
        self.dhcp_opts = CsFile(DHCP_OPTS)
        self.conf = CsFile(CLOUD_CONF)

        self.cloud.repopulate()
        self.dhcp_opts.repopulate()

        for item in self.dbag:
            if item == "id":
                continue
            self.add(self.dbag[item])
        self.write_hosts()

        self.configure_server()

        restart_dnsmasq = False

        if self.conf.commit():
            restart_dnsmasq = True

        if self.cloud.commit():
            restart_dnsmasq = True

        self.dhcp_opts.commit()

        if restart_dnsmasq:
            self.delete_leases()

        if not self.cl.is_redundant() or self.cl.is_master():
            if restart_dnsmasq:
                CsHelper.service("dnsmasq", "restart")
            else:
                CsHelper.start_if_stopped("dnsmasq")
                CsHelper.service("dnsmasq", "reload")

    def configure_server(self):
        # self.conf.addeq("dhcp-hostsfile=%s" % DHCP_HOSTS)
        idx = 0
        for i in self.devinfo:
            if not i['dnsmasq']:
                continue
            device = i['dev']
            ip = i['ip'].split('/')[0]
            sline = "dhcp-range=set:interface-%s-%s" % (device, idx)
            line = "dhcp-range=set:interface-%s-%s,%s,static" % (device, idx, ip)
            self.conf.search(sline, line)
            gn = CsGuestNetwork(device, self.config)
            sline = "dhcp-option=tag:interface-%s-%s,15" % (device, idx)
            line = "dhcp-option=tag:interface-%s-%s,15,%s" % (device, idx, gn.get_domain())
            self.conf.search(sline, line)
            # DNS search order
            if gn.get_dns() and device:
                sline = "dhcp-option=tag:interface-%s-%s,6" % (device, idx)
                dns_list = [x for x in gn.get_dns() if x]
                line = "dhcp-option=tag:interface-%s-%s,6,%s" % (device, idx, ','.join(dns_list))
                self.conf.search(sline, line)
            # Gateway
            gateway = ''
            if self.config.is_vpc():
                gateway = gn.get_gateway()
            else:
                gateway = i['gateway']
            if gateway != '0.0.0.0':
                sline = "dhcp-option=tag:interface-%s-%s,3," % (device, idx)
                line = "dhcp-option=tag:interface-%s-%s,3,%s" % (device, idx, gateway)
                self.conf.search(sline, line)
            # Netmask
            netmask = ''
            if self.config.is_vpc():
                netmask = gn.get_netmask()
            else:
                netmask = self.config.address().get_guest_netmask()
            sline = "dhcp-option=tag:interface-%s-%s,1," % (device, idx)
            line = "dhcp-option=tag:interface-%s-%s,1,%s" % (device, idx, netmask)
            self.conf.search(sline, line)
            idx += 1

    def delete_leases(self):
        try:
            open(LEASES, 'w').close()
        except IOError:
            return

    def preseed(self):
        self.add_host("127.0.0.1", "localhost %s" % CsHelper.get_hostname())
        self.add_host("::1", "localhost ip6-localhost ip6-loopback")
        self.add_host("ff02::1", "ip6-allnodes")
        self.add_host("ff02::2", "ip6-allrouters")
        if self.config.is_router():
            self.add_host(self.config.address().get_guest_ip(), "%s data-server" % CsHelper.get_hostname())

    def write_hosts(self):
        file = CsFile("/etc/hosts")
        file.repopulate()
        for ip in self.hosts:
            file.add("%s\t%s" % (ip, self.hosts[ip]))
        if file.is_changed():
            file.commit()
            logging.info("Updated hosts file")
        else:
            logging.debug("Hosts file unchanged")

    def add(self, entry):
        self.add_host(entry['ipv4_address'], entry['host_name'])
        # lease time boils down to once a month
        # with a splay of 60 hours to prevent storms
        lease = randint(700, 760)

        if entry['default_entry']:
            self.cloud.add("%s,%s,%s,%sh" % (entry['mac_address'],
                                             entry['ipv4_address'],
                                             entry['host_name'],
                                             lease))
        else:
            tag = entry['ipv4_address'].replace(".", "_")
            self.cloud.add("%s,set:%s,%s,%s,%sh" % (entry['mac_address'],
                                                    tag,
                                                    entry['ipv4_address'],
                                                    entry['host_name'],
                                                    lease))
            self.dhcp_opts.add("%s,%s" % (tag, 3))
            self.dhcp_opts.add("%s,%s" % (tag, 6))
            self.dhcp_opts.add("%s,%s" % (tag, 15))

        i = IPAddress(entry['ipv4_address'])
        # Calculate the device
        for v in self.devinfo:
            if i > v['network'].network and i < v['network'].broadcast:
                v['dnsmasq'] = True
                # Virtual Router
                v['gateway'] = entry['default_gateway']

    def add_host(self, ip, hosts):
        self.hosts[ip] = hosts