Beispiel #1
0
    def _test_external_gateway_action(self, action):
        router_id = _uuid()
        ri = l3_agent.RouterInfo(router_id, self.conf.root_helper,
                                 self.conf.use_namespaces, None)
        agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
        internal_cidrs = ['100.0.1.0/24', '200.74.0.0/16']
        ex_gw_port = {
            'fixed_ips': [{
                'ip_address': '20.0.0.30',
                'subnet_id': _uuid()
            }],
            'subnet': {
                'gateway_ip': '20.0.0.1'
            },
            'id': _uuid(),
            'network_id': _uuid(),
            'mac_address': 'ca:fe:de:ad:be:ef',
            'ip_cidr': '20.0.0.30/24'
        }
        interface_name = agent.get_external_device_name(ex_gw_port['id'])

        if action == 'add':
            self.device_exists.return_value = False
            ri.router = mock.Mock()
            ri.router.get.return_value = [{
                'floating_ip_address': '192.168.1.34'
            }]
            agent.external_gateway_added(ri, ex_gw_port, interface_name,
                                         internal_cidrs)
            self.assertEqual(self.mock_driver.plug.call_count, 1)
            self.assertEqual(self.mock_driver.init_l3.call_count, 1)
            self.send_arp.assert_called_once_with(ri, interface_name,
                                                  '20.0.0.30')
            kwargs = {
                'preserve_ips': ['192.168.1.34/32'],
                'namespace': 'qrouter-' + router_id
            }
            self.mock_driver.init_l3.assert_called_with(
                interface_name, ['20.0.0.30/24'], **kwargs)

        elif action == 'remove':
            self.device_exists.return_value = True
            agent.external_gateway_removed(ri, ex_gw_port, interface_name,
                                           internal_cidrs)
            self.assertEqual(self.mock_driver.unplug.call_count, 1)
        else:
            raise Exception("Invalid action %s" % action)
Beispiel #2
0
 def test_router_removed(self):
     self.plugin_api.get_external_network_id.return_value = None
     mock.patch(
         'neutron.agent.linux.iptables_manager.IptablesManager').start()
     router_id = _uuid()
     ri = l3_agent.RouterInfo(router_id, self.conf.root_helper,
                              self.conf.use_namespaces, None)
     ri.router = {
         'id': _uuid(),
         'admin_state_up': True,
         'routes': [],
         'external_gateway_info': {}}
     device = mock.Mock()
     self.agent.router_info = {router_id: ri}
     self.agent.devices = [device]
     self.agent._router_removed(router_id)
     device.destroy_router.assert_called_once_with(router_id)
Beispiel #3
0
 def test_router_info_create_with_router(self):
     id = _uuid()
     ex_gw_port = {'id': _uuid(),
                   'network_id': _uuid(),
                   'fixed_ips': [{'ip_address': '19.4.4.4',
                                  'subnet_id': _uuid()}],
                   'subnet': {'cidr': '19.4.4.0/24',
                              'gateway_ip': '19.4.4.1'}}
     router = {
         'id': _uuid(),
         'enable_snat': True,
         'routes': [],
         'gw_port': ex_gw_port}
     ri = l3_agent.RouterInfo(id, self.conf.root_helper,
                              self.conf.use_namespaces, router)
     self.assertTrue(ri.ns_name().endswith(id))
     self.assertEqual(ri.router, router)
Beispiel #4
0
    def _test_external_gateway_action(self, action):
        router_id = _uuid()
        ri = l3_agent.RouterInfo(router_id, self.conf.root_helper,
                                 self.conf.use_namespaces, None)
        agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
        internal_cidrs = ['100.0.1.0/24', '200.74.0.0/16']
        ex_gw_port = {
            'fixed_ips': [{
                'ip_address': '20.0.0.30',
                'subnet_id': _uuid()
            }],
            'subnet': {
                'gateway_ip': '20.0.0.1'
            },
            'id': _uuid(),
            'network_id': _uuid(),
            'mac_address': 'ca:fe:de:ad:be:ef',
            'ip_cidr': '20.0.0.30/24'
        }
        interface_name = agent.get_external_device_name(ex_gw_port['id'])

        if action == 'add':
            self.device_exists.return_value = False
            agent.external_gateway_added(ri, ex_gw_port, interface_name,
                                         internal_cidrs)
            self.assertEqual(self.mock_driver.plug.call_count, 1)
            self.assertEqual(self.mock_driver.init_l3.call_count, 1)
            arping_cmd = [
                'arping', '-A', '-U', '-I', interface_name, '-c',
                self.conf.send_arp_for_ha, '20.0.0.30'
            ]
            if self.conf.use_namespaces:
                self.mock_ip.netns.execute.assert_any_call(
                    arping_cmd, check_exit_code=True)
            else:
                self.utils_exec.assert_any_call(
                    check_exit_code=True, root_helper=self.conf.root_helper)

        elif action == 'remove':
            self.device_exists.return_value = True
            agent.external_gateway_removed(ri, ex_gw_port, interface_name,
                                           internal_cidrs)
            self.assertEqual(self.mock_driver.unplug.call_count, 1)
        else:
            raise Exception("Invalid action %s" % action)
Beispiel #5
0
    def _test_arping(self, namespace):
        if not namespace:
            self.conf.set_override('use_namespaces', False)

        router_id = _uuid()
        ri = l3_agent.RouterInfo(router_id, self.conf.root_helper,
                                 self.conf.use_namespaces, None)
        agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
        floating_ip = '20.0.0.101'
        interface_name = agent.get_external_device_name(router_id)
        agent._arping(ri, interface_name, floating_ip)

        arping_cmd = [
            'arping', '-A', '-I', interface_name, '-c',
            self.conf.send_arp_for_ha, floating_ip
        ]
        self.mock_ip.netns.execute.assert_any_call(arping_cmd,
                                                   check_exit_code=True)
Beispiel #6
0
 def test_process_router_interface_removed(self):
     agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
     router = self._prepare_router_data(num_internal_ports=2)
     ri = l3_agent.RouterInfo(router['id'], self.conf.root_helper,
                              self.conf.use_namespaces, router=router)
     # Process with NAT
     agent.process_router(ri)
     orig_nat_rules = ri.iptables_manager.ipv4['nat'].rules[:]
     # Add an interface and reprocess
     del router[l3_constants.INTERFACE_KEY][1]
     # Reassign the router object to RouterInfo
     ri.router = router
     agent.process_router(ri)
     # For some reason set logic does not work well with
     # IpTablesRule instances
     nat_rules_delta = [r for r in orig_nat_rules
                        if r not in ri.iptables_manager.ipv4['nat'].rules]
     self.assertEqual(len(nat_rules_delta), 1)
     self._verify_snat_rules(nat_rules_delta, router, negate=True)
Beispiel #7
0
 def test_process_router_snat_enabled(self):
     agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
     router = self._prepare_router_data(enable_snat=False)
     ri = l3_agent.RouterInfo(router['id'], self.conf.root_helper,
                              self.conf.use_namespaces, router=router)
     # Process without NAT
     agent.process_router(ri)
     orig_nat_rules = ri.iptables_manager.ipv4['nat'].rules[:]
     # Reprocess with NAT
     router['enable_snat'] = True
     # Reassign the router object to RouterInfo
     ri.router = router
     agent.process_router(ri)
     # For some reason set logic does not work well with
     # IpTablesRule instances
     nat_rules_delta = [r for r in ri.iptables_manager.ipv4['nat'].rules
                        if r not in orig_nat_rules]
     self.assertEqual(len(nat_rules_delta), 2)
     self._verify_snat_rules(nat_rules_delta, router)
Beispiel #8
0
 def test_process_router_interface_added(self):
     agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
     router = self._prepare_router_data()
     ri = l3_agent.RouterInfo(router['id'],
                              self.conf.root_helper,
                              self.conf.use_namespaces,
                              router=router)
     agent.external_gateway_added = mock.Mock()
     # Process with NAT
     agent.process_router(ri)
     orig_nat_rules = ri.iptables_manager.ipv4['nat'].rules[:]
     # Add an interface and reprocess
     router[l3_constants.INTERFACE_KEY].append({
         'id':
         _uuid(),
         'network_id':
         _uuid(),
         'admin_state_up':
         True,
         'fixed_ips': [{
             'ip_address': '35.4.1.4',
             'subnet_id': _uuid()
         }],
         'mac_address':
         'ca:fe:de:ad:be:ef',
         'subnet': {
             'cidr': '35.4.1.0/24',
             'gateway_ip': '35.4.1.1'
         }
     })
     # Reassign the router object to RouterInfo
     ri.router = router
     agent.process_router(ri)
     # For some reason set logic does not work well with
     # IpTablesRule instances
     nat_rules_delta = [
         r for r in ri.iptables_manager.ipv4['nat'].rules
         if r not in orig_nat_rules
     ]
     self.assertEqual(len(nat_rules_delta), 1)
     self._verify_snat_rules(nat_rules_delta, router)
     self.send_arp.assert_called_once()
Beispiel #9
0
    def _test_routes_updated(self, namespace=True):
        if not namespace:
            self.conf.set_override('use_namespaces', False)
        agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
        router_id = _uuid()

        ri = l3_agent.RouterInfo(router_id, self.conf.root_helper,
                                 self.conf.use_namespaces,
                                 None)
        ri.router = {}

        fake_old_routes = []
        fake_new_routes = [{'destination': "110.100.31.0/24",
                            'nexthop': "10.100.10.30"},
                           {'destination': "110.100.30.0/24",
                            'nexthop': "10.100.10.30"}]
        ri.routes = fake_old_routes
        ri.router['routes'] = fake_new_routes
        agent.routes_updated(ri)

        expected = [['ip', 'route', 'replace', 'to', '110.100.30.0/24',
                    'via', '10.100.10.30'],
                    ['ip', 'route', 'replace', 'to', '110.100.31.0/24',
                    'via', '10.100.10.30']]

        self._check_agent_method_called(agent, expected, namespace)

        fake_new_routes = [{'destination': "110.100.30.0/24",
                            'nexthop': "10.100.10.30"}]
        ri.router['routes'] = fake_new_routes
        agent.routes_updated(ri)
        expected = [['ip', 'route', 'delete', 'to', '110.100.31.0/24',
                    'via', '10.100.10.30']]

        self._check_agent_method_called(agent, expected, namespace)
        fake_new_routes = []
        ri.router['routes'] = fake_new_routes
        agent.routes_updated(ri)

        expected = [['ip', 'route', 'delete', 'to', '110.100.30.0/24',
                    'via', '10.100.10.30']]
        self._check_agent_method_called(agent, expected, namespace)
Beispiel #10
0
    def _test_internal_network_action(self, action):
        port_id = _uuid()
        router_id = _uuid()
        network_id = _uuid()
        ri = l3_agent.RouterInfo(router_id, self.conf.root_helper,
                                 self.conf.use_namespaces, None)
        agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
        cidr = '99.0.1.9/24'
        mac = 'ca:fe:de:ad:be:ef'

        if action == 'add':
            self.device_exists.return_value = False
            agent.internal_network_added(ri, network_id, port_id, cidr, mac)
            self.assertEqual(self.mock_driver.plug.call_count, 1)
            self.assertEqual(self.mock_driver.init_l3.call_count, 1)
        elif action == 'remove':
            self.device_exists.return_value = True
            agent.internal_network_removed(ri, port_id, cidr)
            self.assertEqual(self.mock_driver.unplug.call_count, 1)
        else:
            raise Exception("Invalid action %s" % action)
Beispiel #11
0
    def _test_routing_table_update(self, namespace):
        if not namespace:
            self.conf.set_override('use_namespaces', False)

        router_id = _uuid()
        ri = l3_agent.RouterInfo(router_id, self.conf.root_helper,
                                 self.conf.use_namespaces, None)
        agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)

        fake_route1 = {'destination': '135.207.0.0/16', 'nexthop': '1.2.3.4'}
        fake_route2 = {
            'destination': '135.207.111.111/32',
            'nexthop': '1.2.3.4'
        }

        agent._update_routing_table(ri, 'replace', fake_route1)
        expected = [[
            'ip', 'route', 'replace', 'to', '135.207.0.0/16', 'via', '1.2.3.4'
        ]]
        self._check_agent_method_called(agent, expected, namespace)

        agent._update_routing_table(ri, 'delete', fake_route1)
        expected = [[
            'ip', 'route', 'delete', 'to', '135.207.0.0/16', 'via', '1.2.3.4'
        ]]
        self._check_agent_method_called(agent, expected, namespace)

        agent._update_routing_table(ri, 'replace', fake_route2)
        expected = [[
            'ip', 'route', 'replace', 'to', '135.207.111.111/32', 'via',
            '1.2.3.4'
        ]]
        self._check_agent_method_called(agent, expected, namespace)

        agent._update_routing_table(ri, 'delete', fake_route2)
        expected = [[
            'ip', 'route', 'delete', 'to', '135.207.111.111/32', 'via',
            '1.2.3.4'
        ]]
        self._check_agent_method_called(agent, expected, namespace)
Beispiel #12
0
    def _prepare_router_data(self, enable_snat=None):
        router_id = _uuid()
        ex_gw_port = {'id': _uuid(),
                      'network_id': _uuid(),
                      'fixed_ips': [{'ip_address': '172.24.4.2',
                                     'subnet_id': _uuid()}],
                      'subnet': {'cidr': '172.24.4.0/24',
                                 'gateway_ip': '172.24.4.1'},
                      'ip_cidr': '172.24.4.226/28'}
        int_ports = []

        router = {
            'id': router_id,
            l3_constants.INTERFACE_KEY: int_ports,
            'routes': [],
            'gw_port': ex_gw_port}
        if enable_snat is not None:
            router['enable_snat'] = enable_snat

        ri = l3_agent.RouterInfo(router['id'], self.conf.root_helper,
                                 self.conf.use_namespaces, router=router)
        return ri
Beispiel #13
0
    def test_process_router(self):
        agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
        agent.process_router_floating_ips = mock.Mock()
        router = self._prepare_router_data()
        fake_floatingips1 = {'floatingips': [
            {'id': _uuid(),
             'floating_ip_address': '8.8.8.8',
             'fixed_ip_address': '7.7.7.7',
             'port_id': _uuid()}]}
        ri = l3_agent.RouterInfo(router['id'], self.conf.root_helper,
                                 self.conf.use_namespaces, router=router)
        agent.process_router(ri)
        ex_gw_port = agent._get_ex_gw_port(ri)
        agent.process_router_floating_ips.assert_called_with(ri, ex_gw_port)
        agent.process_router_floating_ips.reset_mock()

        # remap floating IP to a new fixed ip
        fake_floatingips2 = copy.deepcopy(fake_floatingips1)
        fake_floatingips2['floatingips'][0]['fixed_ip_address'] = '7.7.7.8'

        router[l3_constants.FLOATINGIP_KEY] = fake_floatingips2['floatingips']
        agent.process_router(ri)
        ex_gw_port = agent._get_ex_gw_port(ri)
        agent.process_router_floating_ips.assert_called_with(ri, ex_gw_port)
        agent.process_router_floating_ips.reset_mock()

        # remove just the floating ips
        del router[l3_constants.FLOATINGIP_KEY]
        agent.process_router(ri)
        ex_gw_port = agent._get_ex_gw_port(ri)
        agent.process_router_floating_ips.assert_called_with(ri, ex_gw_port)
        agent.process_router_floating_ips.reset_mock()

        # now no ports so state is torn down
        del router[l3_constants.INTERFACE_KEY]
        del router['gw_port']
        agent.process_router(ri)
        self.send_arp.assert_called_once()
        self.assertFalse(agent.process_router_floating_ips.called)
Beispiel #14
0
    def test_handle_router_snat_rules_add_rules(self):
        agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
        ri = l3_agent.RouterInfo(_uuid(), self.conf.root_helper,
                                 self.conf.use_namespaces, None)
        ex_gw_port = {'fixed_ips': [{'ip_address': '192.168.1.4'}]}
        internal_cidrs = ['10.0.0.0/24']
        agent._handle_router_snat_rules(ri, ex_gw_port, internal_cidrs,
                                        "iface", "add_rules")

        nat_rules = map(str, ri.iptables_manager.ipv4['nat'].rules)
        wrap_name = ri.iptables_manager.wrap_name

        jump_float_rule = "-A %s-snat -j %s-float-snat" % (wrap_name,
                                                           wrap_name)
        internal_net_rule = ("-A %s-snat -s %s -j SNAT --to-source %s") % (
            wrap_name, internal_cidrs[0],
            ex_gw_port['fixed_ips'][0]['ip_address'])

        self.assertIn(jump_float_rule, nat_rules)

        self.assertIn(internal_net_rule, nat_rules)
        self.assertThat(nat_rules.index(jump_float_rule),
                        matchers.LessThan(nat_rules.index(internal_net_rule)))
Beispiel #15
0
    def test_process_router_floatingip_disabled(self):
        agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
        with mock.patch.object(
                agent.plugin_rpc,
                'update_floatingip_statuses') as mock_update_fip_status:
            fip_id = _uuid()
            router = self._prepare_router_data(num_internal_ports=1)
            router[l3_constants.FLOATINGIP_KEY] = [{
                'id':
                fip_id,
                'floating_ip_address':
                '8.8.8.8',
                'fixed_ip_address':
                '7.7.7.7',
                'port_id':
                router[l3_constants.INTERFACE_KEY][0]['id']
            }]

            ri = l3_agent.RouterInfo(router['id'],
                                     self.conf.root_helper,
                                     self.conf.use_namespaces,
                                     router=router)
            agent.external_gateway_added = mock.Mock()
            agent.process_router(ri)
            # Assess the call for putting the floating IP up was performed
            mock_update_fip_status.assert_called_once_with(
                mock.ANY, ri.router_id,
                {fip_id: l3_constants.FLOATINGIP_STATUS_ACTIVE})
            mock_update_fip_status.reset_mock()
            # Process the router again, this time without floating IPs
            router[l3_constants.FLOATINGIP_KEY] = []
            ri.router = router
            agent.process_router(ri)
            # Assess the call for putting the floating IP up was performed
            mock_update_fip_status.assert_called_once_with(
                mock.ANY, ri.router_id,
                {fip_id: l3_constants.FLOATINGIP_STATUS_DOWN})
Beispiel #16
0
    def test_process_router_internal_network_added_unexpected_error(self):
        agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
        router = self._prepare_router_data()
        ri = l3_agent.RouterInfo(router['id'], self.conf.root_helper,
                                 self.conf.use_namespaces, router=router)
        with mock.patch.object(
                l3_agent.L3NATAgent,
                'internal_network_added') as internal_network_added:
            # raise RuntimeError to simulate that an unexpected exception
            # occurrs
            internal_network_added.side_effect = RuntimeError
            self.assertRaises(RuntimeError, agent.process_router, ri)
            self.assertNotIn(
                router[l3_constants.INTERFACE_KEY][0], ri.internal_ports)

            # The unexpected exception has been fixed manually
            internal_network_added.side_effect = None

            # _sync_routers_task finds out that _rpc_loop failed to process the
            # router last time, it will retry in the next run.
            agent.process_router(ri)
            # We were able to add the port to ri.internal_ports
            self.assertIn(
                router[l3_constants.INTERFACE_KEY][0], ri.internal_ports)
Beispiel #17
0
    def test_spawn_metadata_proxy(self):
        router_id = _uuid()
        metadata_port = 8080
        ip_class_path = 'neutron.agent.linux.ip_lib.IPWrapper'

        cfg.CONF.set_override('metadata_port', metadata_port)
        cfg.CONF.set_override('log_file', 'test.log')
        cfg.CONF.set_override('debug', True)

        router_info = l3_agent.RouterInfo(
            router_id, cfg.CONF.root_helper, cfg.CONF.use_namespaces, None
        )

        self.external_process_p.stop()
        try:
            with mock.patch(ip_class_path) as ip_mock:
                self.agent._spawn_metadata_proxy(router_info)
                ip_mock.assert_has_calls([
                    mock.call(
                        'sudo',
                        'qrouter-' + router_id
                    ),
                    mock.call().netns.execute([
                        'neutron-ns-metadata-proxy',
                        mock.ANY,
                        mock.ANY,
                        '--router_id=%s' % router_id,
                        mock.ANY,
                        '--metadata_port=%s' % metadata_port,
                        '--debug',
                        '--log-file=neutron-ns-metadata-proxy-%s.log' %
                        router_id
                    ])
                ])
        finally:
            self.external_process_p.start()
Beispiel #18
0
    def test_router_info_create(self):
        id = _uuid()
        ri = l3_agent.RouterInfo(id, self.conf.root_helper,
                                 self.conf.use_namespaces, None)

        self.assertTrue(ri.ns_name().endswith(id))
Beispiel #19
0
 def _router_added(self, router_id, router):
     LOG.debug(_("_router_added: %s"), router_id)
     ri = l3_agent.RouterInfo(router_id, self.root_helper,
                              self.conf.use_namespaces, router)
     self.router_info[router_id] = ri
     super(vArmourL3NATAgent, self).process_router_add(ri)
Beispiel #20
0
 def _prepare_router_data(self, use_namespaces):
     router = {'id': str(uuid.uuid4()), 'tenant_id': str(uuid.uuid4())}
     return l3_agent.RouterInfo(router['id'], self.conf.root_helper,
                                use_namespaces, router=router)
 def _prepare_router_data(self):
     router = {'id': str(uuid.uuid4()), 'tenant_id': str(uuid.uuid4())}
     ns = "ns-" + router['id']
     return l3_agent.RouterInfo(router['id'], self.conf.root_helper,
                                router=router, ns_name=ns)