def test_add_new_route(self): con, d, i1, eni1, i2, eni2, rt_id = self._prepare_mock_env() self.lc.clear() vpc._add_new_route("10.9.0.0/16", self.i1ip, d, con, rt_id) self.lc.check(('root', 'INFO', "--- adding route in RT '%s' " "10.9.0.0/16 -> %s (%s, %s)" % (rt_id, self.i1ip, i1.id, eni1.id))) self.lc.clear() vpc._add_new_route("10.9.0.0/16", "99.99.99.99", d, con, rt_id) self.lc.check( ('root', 'ERROR', "*** failed to add route in RT '%s' " "10.9.0.0/16 -> 99.99.99.99 (Could not find instance/eni " "for '99.99.99.99' in VPC '%s'.)" % (rt_id, self.new_vpc.id)))
def test_update_route(self): con, d, i1, eni1, i2, eni2, rt_id = self._prepare_mock_env() route_spec = {"10.9.0.0/16": [self.i1ip]} d['cluster_node_subnets'] = \ vpc.make_cluster_node_subnet_list(d, route_spec) vpc._add_new_route("10.9.0.0/16", self.i1ip, d, con, rt_id) self.lc.clear() route_spec = {"10.9.0.0/16": [self.i2ip]} d['cluster_node_subnets'] = \ vpc.make_cluster_node_subnet_list(d, route_spec) vpc._update_route("10.9.0.0/16", self.i2ip, self.i1ip, d, con, rt_id, "foobar") self.lc.check( ('root', 'INFO', "--- updating existing route in RT '%s' " "10.9.0.0/16 -> %s (%s, %s) " "(old IP: %s, reason: foobar)" % (rt_id, self.i2ip, i2.id, eni2.id, self.i1ip))) self.lc.clear() vpc._update_route("10.9.0.0/16", "9.9.9.9", self.i2ip, d, con, rt_id, "foobar") self.lc.check( ('root', 'ERROR', "*** failed to update route in RT '%s' " "10.9.0.0/16 -> %s (Could not find instance/eni " "for '9.9.9.9' in VPC '%s'.)" % (rt_id, self.i2ip, self.new_vpc.id))) # Trying to update a non-existent route self.lc.clear() vpc._update_route("10.9.9.9/16", self.i1ip, self.i2ip, d, con, rt_id, "foobar") self.lc.check( ('root', 'INFO', "--- updating existing route in RT '%s' 10.9.9.9/16 -> %s " "(%s, %s) (old IP: %s, reason: foobar)" % (rt_id, self.i1ip, i1.id, eni1.id, self.i2ip)), ('root', 'ERROR', "*** failed to update route in RT '%s' 10.9.9.9/16 -> %s " "(replace_route failed: u'%s~10.9.9.9/16')" % (rt_id, self.i2ip, rt_id)))
def test_get_host_for_route(self): con, d, i1, eni1, i2, eni2, rt_id = self._prepare_mock_env() vpc._add_new_route("10.9.0.0/16", self.i1ip, d, con, rt_id) rt = d['route_tables'][0] self.assertEqual(rt.id, rt_id) route = rt.routes[0] # Moto doesn't maintain intance or interface ID in the routes # correctly, so need to set this one manually route.instance_id = i1.id route.interface_id = eni1.id # Find correct host for route (the passed in cidr is only used for # logging) self.assertEqual((i1.id, self.i1ip, eni1.id), vpc._get_host_for_route(d, route, rt, "cidr-log")) # Look for broken route without an instance id route.instance_id = None self.lc.clear() self.assertEqual(('(unknown)', None, '(unknown)'), vpc._get_host_for_route(d, route, rt, "cidr-log")) self.lc.check( ('root', 'INFO', "--- obsoleted route in RT '%s' cidr-log -> " "... (doesn't point to instance anymore)" % rt_id)) # Look for broken route with instance id for non-existent instance route.instance_id = "blah" self.lc.clear() self.assertEqual(('(unknown)', None, '(unknown)'), vpc._get_host_for_route(d, route, rt, "cidr-log")) self.lc.check(('root', 'INFO', "--- instance in route in RT '%s' can't be found: " "cidr-log -> ... (instance 'blah')" % rt_id))
def test_update_existing_routes(self): con, d, i1, eni1, i2, eni2, rt_id = self._prepare_mock_env() vpc._add_new_route("10.0.0.0/16", self.i1ip, d, con, rt_id) route_spec = {u"10.0.0.0/16": [self.i1ip]} routes_in_rts = {} # Test that a protected route doesn't get updated self.lc.clear() CURRENT_STATE.ignore_routes = ["10.0.0.0/8"] vpc._update_existing_routes(route_spec, [], [], d, con, routes_in_rts) self.assertTrue(rt_id in CURRENT_STATE.vpc_state['route_tables']) self.assertTrue( "10.0.0.0/16" in CURRENT_STATE.vpc_state['route_tables'][rt_id]) self.assertTrue("Ignored: Protected CIDR" in CURRENT_STATE. vpc_state['route_tables'][rt_id]["10.0.0.0/16"]) self.lc.check() # Now we un-protect the route and try again. Moto doesn't manage the # instance or interface ID in routes, so this will fail, because the # route doesn't look like it's pointing to an instance CURRENT_STATE.ignore_routes = [] vpc._update_existing_routes(route_spec, [], [], d, con, routes_in_rts) self.assertTrue("Ignored: Not a route to an instance" in CURRENT_STATE. vpc_state['route_tables'][rt_id]["10.0.0.0/16"]) self.lc.check() # Now we manually set the instance and eni id in the route, so that the # test can proceed. rt = d['route_tables'][0] self.assertEqual(rt.id, rt_id) route = rt.routes[0] # Moto doesn't maintain intance or interface ID in the routes # correctly, so need to set this one manually. This time the route spec # won't contain eligible hosts. route.instance_id = i1.id route.interface_id = eni1.id self.lc.clear() route_spec = {u"10.0.0.0/16": []} vpc._update_existing_routes(route_spec, [], [], d, con, routes_in_rts) self.lc.check( ('root', 'INFO', "--- route not in spec, deleting in RT '%s': 10.0.0.0/16 -> " "... (%s, %s)" % (rt_id, i1.id, eni1.id))) # Get a refresh, since deleting via Boto interface doesn't update the # cached vpc-info d = vpc.get_vpc_overview(con, self.new_vpc.id, "ap-southeast-2") # There shouldn't be any routes left now rt = d['route_tables'][0] self.assertFalse(rt.routes) # Now try again, but with proper route spec. First we need to create # the route again and manually... vpc._add_new_route("10.0.0.0/16", self.i1ip, d, con, rt_id) # ... and update our cached vpc info d = vpc.get_vpc_overview(con, self.new_vpc.id, "ap-southeast-2") rt = d['route_tables'][0] route = rt.routes[0] route.instance_id = i1.id route.interface_id = eni1.id route_spec = {u"10.0.0.0/16": [self.i2ip]} # Only IP for spec is in failed IPs, can't do anything self.lc.clear() vpc._update_existing_routes(route_spec, [self.i2ip], [], d, con, routes_in_rts) self.lc.check(('root', 'WARNING', '--- cannot find available target for route update ' '10.0.0.0/16! Nothing I can do...')) # Now with available IPs self.lc.clear() vpc._update_existing_routes(route_spec, [], [], d, con, routes_in_rts) self.lc.check( ('root', 'INFO', "--- updating existing route in RT '%s' 10.0.0.0/16 -> " "%s (%s, %s) (old IP: %s, reason: old IP failed/questionable " "or not eligible anymore)" % (rt_id, self.i2ip, i2.id, eni2.id, self.i1ip))) # Now with same route spec again d = vpc.get_vpc_overview(con, self.new_vpc.id, "ap-southeast-2") rt = d['route_tables'][0] route = rt.routes[0] route.instance_id = i2.id route.interface_id = eni2.id self.lc.clear() routes_in_rts = {} vpc._update_existing_routes(route_spec, [], [], d, con, routes_in_rts) self.lc.check(('root', 'INFO', "--- route exists already in RT '%s': 10.0.0.0/16 -> " "%s (%s, %s)" % (rt_id, self.i2ip, i2.id, eni2.id)))