Fixed defaultroute on VPC routers in CsRoute and CsAddress
Refactored CsRoute
diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py
index 1bd0949..d49c47a 100755
--- a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py
+++ b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py
@@ -96,14 +96,19 @@
         return None
 
     def process(self):
+        route = CsRoute()
+        found_defaultroute = False
+
         for dev in self.dbag:
             if dev == "id":
                 continue
             ip = CsIP(dev, self.config)
 
             for address in self.dbag[dev]:
-                if not address["nw_type"] == "control":
-                    CsRoute(dev).add(address)
+
+                gateway = str(address["gateway"])
+                network = str(address["network"])
+
                 ip.setAddress(address)
 
                 if ip.configured():
@@ -118,6 +123,16 @@
                     if CsDevice(dev, self.config).waitfordevice():
                         ip.configure()
 
+                if address["nw_type"] != "control":
+                    route.add_route(dev, network)
+
+                # once we start processing public ip's we need to verify there
+                # is a default route and add if needed
+                if address["nw_type"] == "public" and not found_defaultroute:
+                    if not route.defaultroute_exists():
+                        if route.add_defaultroute(gateway):
+                            found_defaultroute = True
+
 
 class CsInterface:
 
@@ -275,8 +290,8 @@
     def post_configure(self):
         """ The steps that must be done after a device is configured """
         if not self.get_type() in ["control"]:
-            route = CsRoute(self.dev)
-            route.routeTable()
+            route = CsRoute()
+            route.add_table(self.dev)
             CsRule(self.dev).addMark()
             self.check_is_up()
             self.set_mark()
@@ -467,9 +482,13 @@
         self.fw.append(["", "", "-A NETWORK_STATS -i eth2 ! -o eth0 -p tcp"])
 
     def post_config_change(self, method):
-        route = CsRoute(self.dev)
-        route.routeTable()
-        route.add(self.address, 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
diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsRoute.py b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsRoute.py
index 234d9b9..fd2d989 100755
--- a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsRoute.py
+++ b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsRoute.py
@@ -23,27 +23,33 @@
 
     """ Manage routes """
 
-    def __init__(self, dev):
-        self.dev = dev
-        self.tableNo = dev[3:]
-        self.table = "Table_%s" % (dev)
+    def __init__(self):
+        self.table_prefix = "Table_"
 
-    def routeTable(self):
-        str = "%s %s" % (self.tableNo, self.table)
+    def get_tablename(self, name):
+        return self.table_prefix + name
+
+    def add_table(self, devicename):
+        tablenumber = devicename[3:]
+        tablename = self.get_tablename(devicename)
+        str = "%s %s" % (tablenumber, tablename)
         filename = "/etc/iproute2/rt_tables"
         logging.info(
             "Adding route table: " + str + " to " + filename + " if not present ")
         CsHelper.addifmissing(filename, str)
 
-    def flush(self):
-        CsHelper.execute("ip route flush table %s" % (self.table))
+    def flush_table(self, tablename):
+        CsHelper.execute("ip route flush table %s" % (tablename))
         CsHelper.execute("ip route flush cache")
 
-    def add(self, address, method="add"):
-        # ip route show dev eth1 table Table_eth1 10.0.2.0/24
-        if(method == "add"):
-            cmd = "dev %s table %s %s" % (self.dev, self.table, address['network'])
-            self.set_route(cmd, method)
+    def add_route(self, dev, address):
+        """ Wrapper method that adds table name and device to route statement """
+        # ip route add dev eth1 table Table_eth1 10.0.2.0/24
+        table = self.get_tablename(dev)
+        logging.info("Adding route: dev " + dev + " table: " +
+                     table + " network: " + address + " if not present")
+        cmd = "dev %s table %s %s" % (dev, table, address)
+        self.set_route(cmd)
 
     def set_route(self, cmd, method="add"):
         """ Add a route if it is not already defined """
@@ -59,3 +65,30 @@
         else:
             return
         CsHelper.execute(cmd)
+
+    def add_defaultroute(self, gateway):
+        """  Add a default route
+        :param str gateway
+        :return: bool
+        """
+        if gateway is not None:
+            cmd = "default via " + gateway
+            logging.info("Adding default route")
+            self.set_route(cmd)
+            return True
+        else:
+            return False
+
+    def defaultroute_exists(self):
+        """ Return True if a default route is present
+        :return: bool
+        """
+        logging.info("Checking if default ipv4 route is present")
+        route_found = CsHelper.execute("ip -4 route list 0/0")
+
+        if len(route_found) > 0:
+            logging.info("Default route found: " + route_found[0])
+            return True
+        else:
+            logging.warn("No default route found!")
+            return False
diff --git a/systemvm/test/python/TestCsRoute.py b/systemvm/test/python/TestCsRoute.py
index dc464d5..6035258 100644
--- a/systemvm/test/python/TestCsRoute.py
+++ b/systemvm/test/python/TestCsRoute.py
@@ -26,8 +26,21 @@
         merge.DataBag.DPATH = "."
 
     def test_init(self):
-        csroute = CsRoute(["one", "two", "three", "four"])
-        self.assertTrue(csroute is not None)
+        csroute = CsRoute()
+        self.assertIsInstance(csroute, CsRoute)
+
+    def test_defaultroute_exists(self):
+        csroute = CsRoute()
+        self.assertFalse(csroute.defaultroute_exists())
+
+    def test_add_defaultroute(self):
+        csroute = CsRoute()
+        self.assertTrue(csroute.add_defaultroute("192.168.1.1"))
+
+    def test_get_tablename(self):
+        csroute = CsRoute()
+        name = "eth1"
+        self.assertEqual("Table_eth1", csroute.get_tablename(name))
 
 if __name__ == '__main__':
     unittest.main()