Example #1
0
    def test_connect(self):
        self.make_mock_vpc()

        # With a test VPC created, we now test our own functions

        con = vpc.connect_to_region("ap-southeast-2")
        d = vpc.get_vpc_overview(con, self.new_vpc.id, "ap-southeast-2")

        self.assertEqual(
            sorted([
                'subnets', 'route_tables', 'instance_by_id', 'instances',
                'zones', 'vpc'
            ]), sorted(d.keys()))

        self.assertEqual(self.new_vpc.id, d['vpc'].id)
        self.assertTrue(self.new_subnet_a.id in [s.id for s in d['subnets']])
        self.assertTrue(self.new_subnet_b.id in [s.id for s in d['subnets']])
        self.assertTrue(len(d['zones']) == 3)
        self.assertTrue(len(d['route_tables']) == 1)
        self.assertTrue(len(d['instance_by_id'].keys()) == 2)
        self.assertTrue(d['instance_by_id'][self.i1.id].id == self.i1.id)
        self.assertTrue(d['instance_by_id'][self.i2.id].id == self.i2.id)

        self.assertTrue(
            vpc.find_instance_and_eni_by_ip(d, self.i1ip)[0].id == self.i1.id)
        self.assertTrue(
            vpc.find_instance_and_eni_by_ip(d, self.i2ip)[0].id == self.i2.id)
Example #2
0
    def _prepare_mock_env(self):
        self.make_mock_vpc()

        con = vpc.connect_to_region("ap-southeast-2")

        d = vpc.get_vpc_overview(con, self.new_vpc.id, "ap-southeast-2")

        i1, eni1 = vpc.find_instance_and_eni_by_ip(d, self.i1ip)
        i2, eni2 = vpc.find_instance_and_eni_by_ip(d, self.i2ip)

        rt_id = d['route_tables'][0].id

        return con, d, i1, eni1, i2, eni2, rt_id
Example #3
0
    def test_connect(self):
        self.make_mock_vpc()

        # With a test VPC created, we now test our own functions

        # In the mocked test the meta data won't contain the info we need (vpc
        # and region name), because the emulated EC2 instance isn't in any
        # region or vpc.
        meta = vpc.get_ec2_meta_data()
        self.assertTrue(meta == {})

        self.assertRaises(VpcRouteSetError, vpc.connect_to_region, "blah")

        con = vpc.connect_to_region("ap-southeast-2")

        # Error when specifying non-existent VPC
        self.assertRaises(VpcRouteSetError, vpc.get_vpc_overview, con,
                          "non-existent-vpc", "ap-southeast-2")

        # Get the default: First VPC if no VPC is specified
        d = vpc.get_vpc_overview(con, None, "ap-southeast-2")
        self.assertEqual(d['vpc'].id, "vpc-be745e76")

        # Get specified VPC
        d = vpc.get_vpc_overview(con, self.new_vpc.id, "ap-southeast-2")
        self.assertEqual(d['vpc'].id, "vpc-be745e76")

        self.assertEqual(
            sorted([
                'subnets', 'route_tables', 'instance_by_id',
                'ip_subnet_lookup', 'instances', 'rt_subnet_lookup', 'zones',
                'vpc'
            ]), sorted(d.keys()))

        self.assertEqual(self.new_vpc.id, d['vpc'].id)
        self.assertTrue(self.new_subnet_a.id in [s.id for s in d['subnets']])
        self.assertTrue(self.new_subnet_b.id in [s.id for s in d['subnets']])
        self.assertTrue(len(d['zones']) == 3)
        self.assertTrue(len(d['route_tables']) == 1)
        self.assertTrue(len(d['instance_by_id'].keys()) == 2)
        self.assertTrue(d['instance_by_id'][self.i1.id].id == self.i1.id)
        self.assertTrue(d['instance_by_id'][self.i2.id].id == self.i2.id)

        self.assertRaises(VpcRouteSetError, vpc.find_instance_and_eni_by_ip, d,
                          "9.9.9.9")  # Non existent IP
        self.assertTrue(
            vpc.find_instance_and_eni_by_ip(d, self.i1ip)[0].id == self.i1.id)
        self.assertTrue(
            vpc.find_instance_and_eni_by_ip(d, self.i2ip)[0].id == self.i2.id)
Example #4
0
    def test_handle_spec(self):
        self.make_mock_vpc()

        # Need to take a peek inside the VPC so we can properly evaluate the
        # output later on
        con = vpc.connect_to_region("ap-southeast-2")
        d = vpc.get_vpc_overview(con, self.new_vpc.id, "ap-southeast-2")
        route_spec = {u"10.2.0.0/16": [self.i1ip]}
        d['cluster_node_subnets'] = \
                        vpc.make_cluster_node_subnet_list(d, route_spec)
        i, eni = vpc.find_instance_and_eni_by_ip(d, self.i1ip)

        rt_id = d['route_tables'][0].id

        con.associate_route_table(route_table_id=rt_id,
                                  subnet_id=self.new_subnet_a.id)
        con.associate_route_table(route_table_id=rt_id,
                                  subnet_id=self.new_subnet_b.id)

        # Test handle_spec
        vid = self.new_vpc.id
        self.lc.clear()
        vpc.handle_spec("ap-southeast-2", vid, route_spec, [], [])
        self.lc.check(
            ('root', 'DEBUG', 'Handle route spec'),
            ('root', 'DEBUG', "Connecting to AWS region 'ap-southeast-2'"),
            ('root', 'DEBUG', "Retrieving information for VPC '%s'" % vid),
            ('root', 'DEBUG', 'Route spec processing. No failed IPs.'),
            ('root', 'INFO',
             "--- adding route in RT '%s' 10.2.0.0/16 -> %s (%s, %s)" %
             (rt_id, self.i1ip, self.i1.id, eni.id)))

        # mock the get_instance_private_ip_from_route() function in vpc. Reason
        # being: The boto mocking library (moto) doesn't handle ENIs in routes
        # correctly. Therefore, a match against the information we get from the
        # routes will never work. So, we provide a wrapper, which fills the
        # instance's ENI information into the route. This means that this
        # function now will always match. It's good for testing the 'match'
        # part of the code.
        old_func = vpc.get_instance_private_ip_from_route

        def my_get_instance_private_ip_from_route(instance, route):
            route.interface_id = instance.interfaces[0].id
            return old_func(instance, route)

        vpc.get_instance_private_ip_from_route = \
                                my_get_instance_private_ip_from_route
        self.lc.clear()
        vpc.handle_spec("ap-southeast-2", vid, route_spec, [], [])

        vpc.get_instance_private_ip_from_route = old_func

        self.lc.check(
            ('root', 'DEBUG', 'Handle route spec'),
            ('root', 'DEBUG', "Connecting to AWS region 'ap-southeast-2'"),
            ('root', 'DEBUG', "Retrieving information for VPC '%s'" % vid),
            ('root', 'DEBUG', 'Route spec processing. No failed IPs.'),
            ('root', 'INFO',
             "--- route exists already in RT '%s': 10.2.0.0/16 -> "
             "%s (%s, %s)" % (rt_id, self.i1ip, self.i1.id, eni.id)))
Example #5
0
    def test_process_route_spec_config(self):
        self.make_mock_vpc()

        con = vpc.connect_to_region("ap-southeast-2")

        d = vpc.get_vpc_overview(con, self.new_vpc.id, "ap-southeast-2")

        i1, eni1 = vpc.find_instance_and_eni_by_ip(d, self.i1ip)
        i2, eni2 = vpc.find_instance_and_eni_by_ip(d, self.i2ip)

        rt_id = d['route_tables'][0].id

        route_spec = {u"10.1.0.0/16": [self.i1ip, self.i2ip]}

        # Process a simple route spec, a route should have been added
        self.lc.clear()
        vpc.process_route_spec_config(con, d, route_spec, [])
        # One of the hosts is randomly chosen. We seeded the random number
        # generator at in this module, so we know that it will choose the
        # second host in this case.
        self.lc.check(
            ('root', 'DEBUG', 'Route spec processing. No failed IPs.'),
            ('root', 'INFO', "--- adding route in RT '%s' "
             "10.1.0.0/16 -> %s (%s, %s)" %
             (rt_id, self.i2ip, i2.id, eni2.id)))

        # One of the two IPs failed, switch over
        d = vpc.get_vpc_overview(con, self.new_vpc.id, "ap-southeast-2")
        self.lc.clear()
        vpc.process_route_spec_config(con, d, route_spec, [self.i1ip])
        self.lc.check(
            ('root', 'DEBUG',
             'Route spec processing. Failed IPs: %s' % self.i1ip),
            ('root', 'INFO',
             "--- updating existing route in RT '%s' 10.1.0.0/16 -> "
             "%s (%s, %s) (old IP: None, reason: old IP failed or not "
             "eligible anymore)" % (rt_id, self.i2ip, i2.id, eni2.id)))

        # Now all IPs for a route have failed
        d = vpc.get_vpc_overview(con, self.new_vpc.id, "ap-southeast-2")
        self.lc.clear()
        vpc.process_route_spec_config(con, d, route_spec,
                                      [self.i1ip, self.i2ip])
        self.lc.check(
            ('root', 'DEBUG', 'Route spec processing. Failed IPs: %s,%s' %
             (self.i1ip, self.i2ip)),
            ('root', 'WARNING',
             '--- cannot find available target for route update 10.1.0.0/16! '
             'Nothing I can do...'))

        # Add new route, remove old one
        route_spec = {u"10.2.0.0/16": [self.i1ip]}

        d = vpc.get_vpc_overview(con, self.new_vpc.id, "ap-southeast-2")
        self.lc.clear()
        vpc.process_route_spec_config(con, d, route_spec, [])
        self.lc.check(
            ('root', 'DEBUG', 'Route spec processing. No failed IPs.'),
            ('root', 'INFO', "--- route not in spec, deleting in RT '%s': "
             "10.1.0.0/16 -> ... (%s, (unknown))" % (rt_id, i2.id)),
            ('root', 'INFO', "--- adding route in RT '%s' "
             "10.2.0.0/16 -> %s (%s, %s)" %
             (rt_id, self.i1ip, i1.id, eni1.id)))