def set_fault(self): """ Set fault mode on this router """ if not self.cl.is_redundant(): logging.error("Set fault called on non-redundant router") return self.set_lock() logging.info("Router switched to fault mode") interfaces = [interface for interface in self.address.get_interfaces() if interface.is_public()] for interface in interfaces: CsHelper.execute("ifconfig %s down" % interface.get_device()) cmd = "%s -C %s" % (self.CONNTRACKD_BIN, self.CONNTRACKD_CONF) CsHelper.execute("%s -s" % cmd) CsHelper.service("ipsec", "stop") CsHelper.service("xl2tpd", "stop") CsHelper.service("dnsmasq", "stop") interfaces = [interface for interface in self.address.get_interfaces() if interface.needs_vrrp()] for interface in interfaces: CsPasswdSvc(interface.get_ip()).stop() CsPasswdSvc(interface.get_gateway()).stop() self.cl.set_fault_state() self.cl.save() self.release_lock() logging.info("Router switched to fault mode") interfaces = [interface for interface in self.address.get_interfaces() if interface.is_public()] CsHelper.reconfigure_interfaces(self.cl, interfaces)
def post_config_change(self, method): route = CsRoute() if method == "add": route.add_table(self.dev) route.add_route(self.dev, str(self.address["network"])) elif method == "delete": logging.warn("delete route not implemented") self.fw_router() self.fw_vpcrouter() # On deletion nw_type will no longer be known if self.get_type() in ('guest'): if self.config.is_vpc() or self.config.is_router(): CsDevice(self.dev, self.config).configure_rp() logging.error( "Not able to setup source-nat for a regular router yet") if self.config.has_dns() or self.config.is_dhcp(): dns = CsDnsmasq(self) dns.add_firewall_rules() if self.config.has_metadata(): app = CsApache(self) app.setup() cmdline = self.config.cmdline() # Start passwd server on non-redundant routers and on the master router of redundant pairs # CsRedundant will handle fail-over. if self.get_type() in ["guest"] and (not self.cl.is_redundant() or self.cl.is_master()): CsPasswdSvc(self.address['public_ip']).start() elif self.get_type() in ["guest"]: # Or else make sure it's stopped CsPasswdSvc(self.address['public_ip']).stop() if self.get_type() == "public" and self.config.is_vpc(): if self.address["source_nat"]: logging.info("Adding SourceNAT for interface %s to %s" % (self.dev, self.address['public_ip'])) self.fw.append([ "nat", "", "-A POSTROUTING -j SNAT -o %s --to-source %s" % (self.dev, self.address['public_ip']) ]) else: logging.info( "Not adding SourceNAT for interface %s to %s, because source_nat=False" % (self.dev, self.address['public_ip']))
def set_backup(self): """ Set the current router to backup """ if not self.cl.is_redundant(): logging.error("Set backup called on non-redundant router") return self.set_lock() logging.debug("Setting router to backup") dev = '' interfaces = [ interface for interface in self.address.get_interfaces() if interface.is_public() ] for interface in interfaces: if dev == interface.get_device(): continue logging.info("Bringing public interface %s down" % interface.get_device()) cmd2 = "ip link set %s down" % interface.get_device() CsHelper.execute(cmd2) dev = interface.get_device() cmd = "%s -C %s" % (self.CONNTRACKD_BIN, self.CONNTRACKD_CONF) CsHelper.execute("%s -d" % cmd) CsHelper.service("ipsec", "stop") CsHelper.service("xl2tpd", "stop") interfaces = [ interface for interface in self.address.get_interfaces() if interface.needs_vrrp() ] for interface in interfaces: CsPasswdSvc(interface.get_ip()).stop() CsPasswdSvc(interface.get_gateway()).stop() CsHelper.service("dnsmasq", "stop") self.cl.set_master_state(False) self.cl.save() self.release_lock() interfaces = [ interface for interface in self.address.get_interfaces() if interface.is_public() ] CsHelper.reconfigure_interfaces(self.cl, interfaces) logging.info("Router switched to backup mode")
def set_backup(self): """ Set the current router to backup """ if not self.cl.is_redundant(): logging.error("Set backup called on non-redundant router") return """ if not self.cl.is_master(): logging.error("Set backup called on node that is already backup") return """ self.set_lock() logging.debug("Setting router to backup") ads = [o for o in self.address.get_ips() if o.is_public()] dev = '' for o in ads: if dev == o.get_device(): continue logging.info("Bringing public interface %s down" % o.get_device()) cmd2 = "ip link set %s up" % o.get_device() CsHelper.execute(cmd2) dev = o.get_device() cmd = "%s -C %s" % (self.CONNTRACKD_BIN, self.CONNTRACKD_CONF) CsHelper.execute("%s -d" % cmd) CsHelper.service("ipsec", "stop") CsHelper.service("xl2tpd", "stop") ads = [o for o in self.address.get_ips() if o.needs_vrrp()] for o in ads: CsPasswdSvc(o.get_gateway()).stop() CsHelper.service("dnsmasq", "stop") # self._set_priority(self.CS_PRIO_DOWN) self.cl.set_master_state(False) self.cl.save() self.release_lock() logging.info("Router switched to backup mode")
def set_master(self): """ Set the current router to master """ if not self.cl.is_redundant(): logging.error("Set master called on non-redundant router") return """ if self.cl.is_master(): logging.error("Set master called on master node") return """ s = self.set_lock() logging.debug("Setting router to master") ads = [o for o in self.address.get_ips() if o.is_public()] for o in ads: # cmd2 = "ip link set %s up" % self.getDevice() CsHelper.execute("ifconfig %s down" % o.get_device()) CsHelper.execute("ifconfig %s up" % o.get_device()) CsHelper.execute("arping -I %s -A %s -c 1" % (o.get_device(), o.get_ip())) # FIXME Need to add in the default routes but I am unsure what the gateway is # ip route add default via $gw table Table_$dev proto static cmd = "%s -C %s" % (self.CONNTRACKD_BIN, self.CONNTRACKD_CONF) CsHelper.execute("%s -c" % cmd) CsHelper.execute("%s -f" % cmd) CsHelper.execute("%s -R" % cmd) CsHelper.execute("%s -B" % cmd) CsHelper.service("ipsec", "restart") CsHelper.service("xl2tpd", "restart") ads = [o for o in self.address.get_ips() if o.needs_vrrp()] for o in ads: pwdsvc = CsPasswdSvc(o.get_gateway()).restart() CsHelper.service("dnsmasq", "restart") self.cl.set_master_state(True) self.cl.save() logging.info("Router switched to master mode")
def post_config_change(self, method): route = CsRoute(self.dev) route.routeTable() route.add(self.address, method) self.fw_router() self.fw_vpcrouter() # On deletion nw_type will no longer be known if self.get_type() in ["guest"] and self.config.is_vpc(): CsDevice(self.dev, self.config).configure_rp() logging.error( "Not able to setup sourcenat for a regular router yet") dns = CsDnsmasq(self) dns.add_firewall_rules() app = CsApache(self) app.setup() # If redundant then this is dealt with by the master backup functions if self.get_type() in ["guest"] and not self.config.cl.is_redundant(): pwdsvc = CsPasswdSvc(self.address['public_ip']).start() if self.get_type() == "public" and self.config.is_vpc(): if self.address["source_nat"]: vpccidr = self.config.cmdline().get_vpccidr() self.fw.append([ "filter", "", "-A FORWARD -s %s ! -d %s -j ACCEPT" % (vpccidr, vpccidr) ]) self.fw.append([ "nat", "", "-A POSTROUTING -j SNAT -o %s --to-source %s" % (self.dev, self.address['public_ip']) ])
def set_master(self): """ Set the current router to master """ if not self.cl.is_redundant(): logging.error("Set master called on non-redundant router") return self.set_lock() logging.debug("Setting router to master") self.address.process() logging.info("added default routes") # ip route add default via $gw table Table_$dev proto static cmd = "%s -C %s" % (self.CONNTRACKD_BIN, self.CONNTRACKD_CONF) CsHelper.execute("%s -c" % cmd) CsHelper.execute("%s -f" % cmd) CsHelper.execute("%s -R" % cmd) CsHelper.execute("%s -B" % cmd) CsHelper.service("ipsec", "restart") CsHelper.service("xl2tpd", "restart") ads = [o for o in self.address.get_ips() if o.needs_vrrp()] for o in ads: CsPasswdSvc(o.get_gateway()).restart() CsHelper.service("dnsmasq", "restart") self.cl.set_master_state(True) self.cl.save() self.release_lock() logging.info("Router switched to master mode")
def set_master(self): """ Set the current router to master """ if not self.cl.is_redundant(): logging.error("Set master called on non-redundant router") return self.set_lock() logging.debug("Setting router to master") dev = '' interfaces = [interface for interface in self.address.get_interfaces() if interface.is_public()] route = CsRoute() for interface in interfaces: if dev == interface.get_device(): continue dev = interface.get_device() logging.info("Will proceed configuring device ==> %s" % dev) cmd = "ip link set %s up" % dev if CsDevice(dev, self.config).waitfordevice(): CsHelper.execute(cmd) logging.info("Bringing public interface %s up" % dev) try: gateway = interface.get_gateway() logging.info("Adding gateway ==> %s to device ==> %s" % (gateway, dev)) if dev == CsHelper.PUBLIC_INTERFACES[self.cl.get_type()]: route.add_defaultroute(gateway) except: logging.error("ERROR getting gateway from device %s" % dev) else: logging.error("Device %s was not ready could not bring it up" % dev) logging.debug("Configuring static routes") static_routes = CsStaticRoutes("staticroutes", self.config) static_routes.process() cmd = "%s -C %s" % (self.CONNTRACKD_BIN, self.CONNTRACKD_CONF) CsHelper.execute("%s -c" % cmd) CsHelper.execute("%s -f" % cmd) CsHelper.execute("%s -R" % cmd) CsHelper.execute("%s -B" % cmd) CsHelper.service("ipsec", "restart") CsHelper.service("xl2tpd", "restart") interfaces = [interface for interface in self.address.get_interfaces() if interface.needs_vrrp()] for interface in interfaces: # Listen on local ip address, as cloud-init uses the 'dhcp-server-identifier' address, # which unfortunately is not the gateway address. CsPasswdSvc(interface.get_ip()).start() CsHelper.service("dnsmasq", "restart") self.cl.set_master_state(True) self.cl.save() self.release_lock() interfaces = [interface for interface in self.address.get_interfaces() if interface.is_public()] CsHelper.reconfigure_interfaces(self.cl, interfaces) logging.info("Router switched to master mode")
def set_master(self): """ Set the current router to master """ if not self.cl.is_redundant(): logging.error("Set master called on non-redundant router") return self.set_lock() logging.debug("Setting router to master") ads = [o for o in self.address.get_ips() if o.is_public()] dev = '' route = CsRoute() for o in ads: if dev == o.get_device(): continue dev = o.get_device() logging.info("Will proceed configuring device ==> %s" % dev) cmd2 = "ip link set %s up" % dev if CsDevice(dev, self.config).waitfordevice(): CsHelper.execute(cmd2) logging.info("Bringing public interface %s up" % dev) try: gateway = o.get_gateway() logging.info("Adding gateway ==> %s to device ==> %s" % (gateway, dev)) route.add_defaultroute(gateway) except: logging.error("ERROR getting gateway from device %s" % dev) else: logging.error("Device %s was not ready could not bring it up" % dev) # ip route add default via $gw table Table_$dev proto static cmd = "%s -C %s" % (self.CONNTRACKD_BIN, self.CONNTRACKD_CONF) CsHelper.execute("%s -c" % cmd) CsHelper.execute("%s -f" % cmd) CsHelper.execute("%s -R" % cmd) CsHelper.execute("%s -B" % cmd) CsHelper.service("ipsec", "restart") CsHelper.service("xl2tpd", "restart") ads = [o for o in self.address.get_ips() if o.needs_vrrp()] for o in ads: CsPasswdSvc(o.get_gateway()).restart() CsHelper.service("dnsmasq", "restart") self.cl.set_master_state(True) self.cl.save() self.release_lock() logging.info("Router switched to master mode")
def post_config_change(self, method): route = CsRoute() if method == "add": route.add_table(self.dev) route.add_route(self.dev, str(self.address["network"])) elif method == "delete": logging.warn("delete route not implemented") self.fw_router() self.fw_vpcrouter() # On deletion nw_type will no longer be known if self.get_type() in ('guest'): if self.config.is_vpc() or self.config.is_router(): CsDevice(self.dev, self.config).configure_rp() logging.error( "Not able to setup source-nat for a regular router yet") if self.config.has_dns() or self.config.is_dhcp(): dns = CsDnsmasq(self) dns.add_firewall_rules() if self.config.has_metadata(): app = CsApache(self) app.setup() cmdline = self.config.cmdline() # If redundant then this is dealt with by the master backup functions if self.get_type() in ["guest"] and not cmdline.is_redundant(): pwdsvc = CsPasswdSvc(self.address['public_ip']).start() if self.get_type() == "public" and self.config.is_vpc(): if self.address["source_nat"]: vpccidr = cmdline.get_vpccidr() self.fw.append([ "filter", 3, "-A FORWARD -s %s ! -d %s -j ACCEPT" % (vpccidr, vpccidr) ]) self.fw.append([ "nat", "", "-A POSTROUTING -j SNAT -o %s --to-source %s" % (self.dev, self.address['public_ip']) ])
def set_fault(self): """ Set fault mode on this router """ if not self.cl.is_redundant(): logging.error("Set fault called on non-redundant router") return s = self.set_lock() logging.info("Router switched to fault mode") ads = [o for o in self.address.get_ips() if o.is_public()] for o in ads: CsHelper.execute("ifconfig %s down" % o.get_device()) cmd = "%s -C %s" % (self.CONNTRACKD_BIN, self.CONNTRACKD_CONF) CsHelper.execute("%s -s" % cmd) CsHelper.service("ipsec", "stop") CsHelper.service("xl2tpd", "stop") CsHelper.service("dnsmasq", "stop") ads = [o for o in self.address.get_ips() if o.needs_vrrp()] for o in ads: pwdsvc = CsPasswdSvc(o.get_gateway()).stop() self.cl.set_fault_state() self.cl.save() logging.info("Router switched to fault mode")
def post_config_change(self, method): route = CsRoute() tableName = "Table_" + self.dev if method == "add": if not self.config.is_vpc(): if self.get_type() in ["public"]: route.set_route( "table %s throw %s proto static" % (tableName, self.config.address().dbag['eth0'][0]['network'])) route.set_route( "table %s throw %s proto static" % (tableName, self.config.address().dbag['eth1'][0]['network'])) # add 'default via gateway' rule in the device specific routing table if "gateway" in self.address and self.address[ "gateway"] and self.address["gateway"] != "None": route.add_route(self.dev, self.address["gateway"]) if "network" in self.address and self.address["network"]: route.add_network_route(self.dev, str(self.address["network"])) if self.get_type() in ["public"]: CsRule(self.dev).addRule("from " + str(self.address["network"])) if self.config.is_vpc(): if self.get_type() in [ "public" ] and "gateway" in self.address and self.address[ "gateway"] and self.address["gateway"] != "None": route.add_route(self.dev, self.address["gateway"]) for inf, addresses in self.config.address().dbag.iteritems( ): if not inf.startswith("eth"): continue for address in addresses: if "nw_type" in address and address[ "nw_type"] == "guest": route.add_network_route( self.dev, str(address["network"])) route.add_network_route(self.dev, str(self.address["network"])) CsHelper.execute("sudo ip route flush cache") elif method == "delete": # treat the last IP to be dis-associated with interface as special case to clean up the routing rules if self.get_type() in [ "public" ] and (not self.config.is_vpc()) and (len(self.iplist) == 0): CsHelper.execute("sudo ip rule delete table " + tableName) CsHelper.execute("sudo ip route flush table " + tableName) CsHelper.execute("sudo ip route flush cache") CsRule(self.dev).delMark() self.fw_router() self.fw_vpcrouter() cmdline = self.config.cmdline() # On deletion nw_type will no longer be known if self.get_type() in ('guest'): if self.config.is_vpc() or self.config.is_router(): CsDevice(self.dev, self.config).configure_rp() logging.error( "Not able to setup source-nat for a regular router yet") if (self.config.has_dns() or self.config.is_dhcp()) and self.config.expose_dns(): logging.info("Making dns publicly available") dns = CsDnsmasq(self) dns.add_firewall_rules() else: logging.info("Not making dns publicly available") if self.config.has_metadata(): app = CsApache(self) app.setup() # If redundant then this is dealt with # by the primary backup functions if not cmdline.is_redundant(): if method == "add": CsPasswdSvc(self.address['public_ip']).start() elif method == "delete": CsPasswdSvc(self.address['public_ip']).stop() elif cmdline.is_primary(): if method == "add": CsPasswdSvc(self.get_gateway() + "," + self.address['public_ip']).start() elif method == "delete": CsPasswdSvc(self.get_gateway() + "," + self.address['public_ip']).stop() if self.get_type() == "public" and self.config.is_vpc( ) and method == "add": if self.address["source_nat"]: vpccidr = cmdline.get_vpccidr() self.fw.append([ "filter", 3, "-A FORWARD -s %s ! -d %s -j ACCEPT" % (vpccidr, vpccidr) ]) self.fw.append([ "nat", "", "-A POSTROUTING -j SNAT -o %s --to-source %s" % (self.dev, self.address['public_ip']) ])
def set_primary(self): """ Set the current router to primary """ if not self.cl.is_redundant(): logging.error("Set primary called on non-redundant router") return self.set_lock() logging.debug("Setting router to primary") dev = '' interfaces = [ interface for interface in self.address.get_interfaces() if interface.is_public() ] route = CsRoute() for interface in interfaces: if dev == interface.get_device(): continue dev = interface.get_device() logging.info("Will proceed configuring device ==> %s" % dev) cmd = "ip link set %s up" % dev if CsDevice(dev, self.config).waitfordevice(): CsHelper.execute(cmd) logging.info("Bringing public interface %s up" % dev) try: gateway = interface.get_gateway() logging.info("Adding gateway ==> %s to device ==> %s" % (gateway, dev)) if dev == CsHelper.PUBLIC_INTERFACES[self.cl.get_type()]: route.add_defaultroute(gateway) except Exception: logging.error("ERROR getting gateway from device %s" % dev) if dev == CsHelper.PUBLIC_INTERFACES[self.cl.get_type()]: try: self._add_ipv6_to_interface(interface, interface.get_ip6()) if interface.get_gateway6(): route.add_defaultroute_v6(interface.get_gateway6()) except Exception as e: logging.error( "ERROR adding IPv6, getting IPv6 gateway from device %s: %s" % (dev, e)) else: logging.error("Device %s was not ready could not bring it up" % dev) self._add_ipv6_guest_gateway() logging.debug("Configuring static routes") static_routes = CsStaticRoutes("staticroutes", self.config) static_routes.process() cmd = "%s -C %s" % (self.CONNTRACKD_BIN, self.CONNTRACKD_CONF) CsHelper.execute("%s -c" % cmd) CsHelper.execute("%s -f" % cmd) CsHelper.execute("%s -R" % cmd) CsHelper.execute("%s -B" % cmd) CsHelper.service("ipsec", "restart") CsHelper.service("xl2tpd", "restart") interfaces = [ interface for interface in self.address.get_interfaces() if interface.needs_vrrp() ] for interface in interfaces: if interface.is_added(): CsPasswdSvc(interface.get_gateway() + "," + interface.get_ip()).restart() CsHelper.service("dnsmasq", "restart") self.cl.set_primary_state(True) self.cl.save() self.release_lock() interfaces = [ interface for interface in self.address.get_interfaces() if interface.is_public() ] CsHelper.reconfigure_interfaces(self.cl, interfaces) public_devices = list( set([interface.get_device() for interface in interfaces])) if len(public_devices) > 1: # Handle specific failures when multiple public interfaces public_devices.sort() # Ensure the default route is added, or outgoing traffic from VMs with static NAT on # the subsequent interfaces will go from the wrong IP route = CsRoute() dev = '' for interface in interfaces: if dev == interface.get_device(): continue dev = interface.get_device() gateway = interface.get_gateway() if gateway: route.add_route(dev, gateway) # The first public interface has a static MAC address between VRs. Subsequent ones don't, # so an ARP announcement is needed on failover for device in public_devices[1:]: logging.info("Sending garp messages for IPs on %s" % device) for interface in interfaces: if interface.get_device() == device: CsHelper.execute("arping -I %s -U %s -c 1" % (device, interface.get_ip())) logging.info("Router switched to primary mode")