def _add_snat_port_info_to_router(self, router, internal_ports): # Add snat port information to the router snat_port_list = router.get(l3_constants.SNAT_ROUTER_INTF_KEY, []) if not snat_port_list and internal_ports: # Get values from internal port port = internal_ports[0] fixed_ip = port['fixed_ips'][0] snat_subnet = port['subnets'][0] port_ip = fixed_ip['ip_address'] # Pick an ip address which is not the same as port_ip snat_ip = str(netaddr.IPAddress(port_ip) + 5) # Add the info to router as the first snat port # in the list of snat ports prefixlen = netaddr.IPNetwork(snat_subnet['cidr']).prefixlen router[l3_constants.SNAT_ROUTER_INTF_KEY] = [ {'subnets': [ {'cidr': snat_subnet['cidr'], 'gateway_ip': snat_subnet['gateway_ip'], 'id': fixed_ip['subnet_id']}], 'network_id': port['network_id'], 'device_owner': l3_constants.DEVICE_OWNER_ROUTER_SNAT, 'mac_address': 'fa:16:3e:80:8d:89', 'fixed_ips': [{'subnet_id': fixed_ip['subnet_id'], 'ip_address': snat_ip, 'prefixlen': prefixlen}], 'id': framework._uuid(), 'device_id': framework._uuid()} ]
def _add_snat_port_info_to_router(self, router, internal_ports): # Add snat port information to the router snat_port_list = router.get(l3_constants.SNAT_ROUTER_INTF_KEY, []) if not snat_port_list and internal_ports: router[l3_constants.SNAT_ROUTER_INTF_KEY] = [] for port in internal_ports: # Get values from internal port fixed_ip = port["fixed_ips"][0] snat_subnet = port["subnets"][0] port_ip = fixed_ip["ip_address"] # Pick an ip address which is not the same as port_ip snat_ip = str(netaddr.IPAddress(port_ip) + 5) # Add the info to router as the first snat port # in the list of snat ports prefixlen = netaddr.IPNetwork(snat_subnet["cidr"]).prefixlen snat_router_port = { "subnets": [ { "cidr": snat_subnet["cidr"], "gateway_ip": snat_subnet["gateway_ip"], "id": fixed_ip["subnet_id"], } ], "network_id": port["network_id"], "device_owner": l3_constants.DEVICE_OWNER_ROUTER_SNAT, "mac_address": "fa:16:3e:80:8d:89", "fixed_ips": [{"subnet_id": fixed_ip["subnet_id"], "ip_address": snat_ip, "prefixlen": prefixlen}], "id": framework._uuid(), "device_id": framework._uuid(), } # Get the address scope if there is any if "address_scopes" in port: snat_router_port["address_scopes"] = port["address_scopes"] router[l3_constants.SNAT_ROUTER_INTF_KEY].append(snat_router_port)
def _add_fip_agent_gw_port_info_to_router(self, router, external_gw_port): # Add fip agent gateway port information to the router_info fip_gw_port_list = router.get( l3_constants.FLOATINGIP_AGENT_INTF_KEY, []) if not fip_gw_port_list and external_gw_port: # Get values from external gateway port fixed_ip = external_gw_port['fixed_ips'][0] float_subnet = external_gw_port['subnets'][0] port_ip = fixed_ip['ip_address'] # Pick an ip address which is not the same as port_ip fip_gw_port_ip = str(netaddr.IPAddress(port_ip) + 5) # Add floatingip agent gateway port info to router prefixlen = netaddr.IPNetwork(float_subnet['cidr']).prefixlen router[l3_constants.FLOATINGIP_AGENT_INTF_KEY] = [ {'subnets': [ {'cidr': float_subnet['cidr'], 'gateway_ip': float_subnet['gateway_ip'], 'id': fixed_ip['subnet_id']}], 'network_id': external_gw_port['network_id'], 'device_owner': l3_constants.DEVICE_OWNER_AGENT_GW, 'mac_address': 'fa:16:3e:80:8d:89', portbindings.HOST_ID: self.agent.conf.host, 'fixed_ips': [{'subnet_id': fixed_ip['subnet_id'], 'ip_address': fip_gw_port_ip, 'prefixlen': prefixlen}], 'id': framework._uuid(), 'device_id': framework._uuid()} ]
def _add_fip_agent_gw_port_info_to_router(self, router, external_gw_port): # Add fip agent gateway port information to the router_info fip_gw_port_list = router.get(l3_constants.FLOATINGIP_AGENT_INTF_KEY, []) if not fip_gw_port_list and external_gw_port: # Get values from external gateway port fixed_ip = external_gw_port["fixed_ips"][0] float_subnet = external_gw_port["subnets"][0] port_ip = fixed_ip["ip_address"] # Pick an ip address which is not the same as port_ip fip_gw_port_ip = str(netaddr.IPAddress(port_ip) + 5) # Add floatingip agent gateway port info to router prefixlen = netaddr.IPNetwork(float_subnet["cidr"]).prefixlen router[l3_constants.FLOATINGIP_AGENT_INTF_KEY] = [ { "subnets": [ { "cidr": float_subnet["cidr"], "gateway_ip": float_subnet["gateway_ip"], "id": fixed_ip["subnet_id"], } ], "network_id": external_gw_port["network_id"], "device_owner": l3_constants.DEVICE_OWNER_AGENT_GW, "mac_address": "fa:16:3e:80:8d:89", portbindings.HOST_ID: self.agent.conf.host, "fixed_ips": [ {"subnet_id": fixed_ip["subnet_id"], "ip_address": fip_gw_port_ip, "prefixlen": prefixlen} ], "id": framework._uuid(), "device_id": framework._uuid(), } ]
def test_keepalived_configuration(self): router_info = self.generate_router_info(enable_ha=True) router = self.manage_router(self.agent, router_info) expected = self.get_expected_keepalive_configuration(router) self.assertEqual(expected, router.keepalived_manager.get_conf_on_disk()) # Add a new FIP and change the GW IP address router.router = copy.deepcopy(router.router) existing_fip = "19.4.4.2" new_fip = "19.4.4.3" self._add_fip(router, new_fip) subnet_id = framework._uuid() fixed_ips = [{"ip_address": "19.4.4.10", "prefixlen": 24, "subnet_id": subnet_id}] subnets = [{"id": subnet_id, "cidr": "19.4.4.0/24", "gateway_ip": "19.4.4.5"}] router.router["gw_port"]["subnets"] = subnets router.router["gw_port"]["fixed_ips"] = fixed_ips router.process(self.agent) # Get the updated configuration and assert that both FIPs are in, # and that the GW IP address was updated. new_config = router.keepalived_manager.config.get_config_str() old_gw = "0.0.0.0/0 via 19.4.4.1" new_gw = "0.0.0.0/0 via 19.4.4.5" old_external_device_ip = "19.4.4.4" new_external_device_ip = "19.4.4.10" self.assertIn(existing_fip, new_config) self.assertIn(new_fip, new_config) self.assertNotIn(old_gw, new_config) self.assertIn(new_gw, new_config) external_port = router.get_ex_gw_port() external_device_name = router.get_external_device_name(external_port["id"]) self.assertNotIn("%s/24 dev %s" % (old_external_device_ip, external_device_name), new_config) self.assertIn("%s/24 dev %s" % (new_external_device_ip, external_device_name), new_config)
def _test_periodic_sync_routers_task(self, routers_to_keep, routers_deleted, routers_deleted_during_resync): ns_names_to_retrieve = set() deleted_routers_info = [] for r in routers_to_keep: ri = self.manage_router(self.agent, r) ns_names_to_retrieve.add(ri.ns_name) for r in routers_deleted + routers_deleted_during_resync: ri = self.manage_router(self.agent, r) deleted_routers_info.append(ri) ns_names_to_retrieve.add(ri.ns_name) mocked_get_router_ids = self.mock_plugin_api.get_router_ids mocked_get_router_ids.return_value = [r['id'] for r in routers_to_keep + routers_deleted_during_resync] mocked_get_routers = self.mock_plugin_api.get_routers mocked_get_routers.return_value = (routers_to_keep + routers_deleted_during_resync) # clear agent router_info as it will be after restart self.agent.router_info = {} # Synchronize the agent with the plug-in with mock.patch.object(namespace_manager.NamespaceManager, 'list_all', return_value=ns_names_to_retrieve): self.agent.periodic_sync_routers_task(self.agent.context) # Mock the plugin RPC API so a known external network id is returned # when the router updates are processed by the agent external_network_id = framework._uuid() self.mock_plugin_api.get_external_network_id.return_value = ( external_network_id) # Plug external_gateway_info in the routers that are not going to be # deleted by the agent when it processes the updates. Otherwise, # _process_router_if_compatible in the agent fails for r in routers_to_keep: r['external_gateway_info'] = {'network_id': external_network_id} # while sync updates are still in the queue, higher priority # router_deleted events may be added there as well for r in routers_deleted_during_resync: self.agent.router_deleted(self.agent.context, r['id']) # make sure all events are processed while not self.agent._queue._queue.empty(): self.agent._process_router_update() for r in routers_to_keep: self.assertIn(r['id'], self.agent.router_info) self.assertTrue(self._namespace_exists(namespaces.NS_PREFIX + r['id'])) for ri in deleted_routers_info: self.assertNotIn(ri.router_id, self.agent.router_info) self._assert_router_does_not_exist(ri)
def test_keepalived_configuration(self): router_info = self.generate_router_info(enable_ha=True) router = self.manage_router(self.agent, router_info) expected = self.get_expected_keepalive_configuration(router) self.assertEqual(expected, router.keepalived_manager.get_conf_on_disk()) # Add a new FIP and change the GW IP address router.router = copy.deepcopy(router.router) existing_fip = '19.4.4.2' new_fip = '19.4.4.3' self._add_fip(router, new_fip) subnet_id = framework._uuid() fixed_ips = [{ 'ip_address': '19.4.4.10', 'prefixlen': 24, 'subnet_id': subnet_id }] subnets = [{ 'id': subnet_id, 'cidr': '19.4.4.0/24', 'gateway_ip': '19.4.4.5' }] router.router['gw_port']['subnets'] = subnets router.router['gw_port']['fixed_ips'] = fixed_ips router.process() # Get the updated configuration and assert that both FIPs are in, # and that the GW IP address was updated. new_config = router.keepalived_manager.config.get_config_str() old_gw = '0.0.0.0/0 via 19.4.4.1' new_gw = '0.0.0.0/0 via 19.4.4.5' old_external_device_ip = '19.4.4.4' new_external_device_ip = '19.4.4.10' self.assertIn(existing_fip, new_config) self.assertIn(new_fip, new_config) self.assertNotIn(old_gw, new_config) self.assertIn(new_gw, new_config) external_port = router.get_ex_gw_port() external_device_name = router.get_external_device_name( external_port['id']) self.assertNotIn( '%s/24 dev %s' % (old_external_device_ip, external_device_name), new_config) self.assertIn( '%s/24 dev %s' % (new_external_device_ip, external_device_name), new_config)
def _add_fip_agent_gw_port_info_to_router(self, router, external_gw_port): # Add fip agent gateway port information to the router_info fip_gw_port_list = router.get(n_const.FLOATINGIP_AGENT_INTF_KEY, []) if not fip_gw_port_list and external_gw_port: # Get values from external gateway port fixed_ip = external_gw_port['fixed_ips'][0] float_subnet = external_gw_port['subnets'][0] port_ip = fixed_ip['ip_address'] # Pick an ip address which is not the same as port_ip fip_gw_port_ip = str(netaddr.IPAddress(port_ip) + 5) # Add floatingip agent gateway port info to router prefixlen = netaddr.IPNetwork(float_subnet['cidr']).prefixlen router[n_const.FLOATINGIP_AGENT_INTF_KEY] = [{ 'subnets': [{ 'cidr': float_subnet['cidr'], 'gateway_ip': float_subnet['gateway_ip'], 'id': fixed_ip['subnet_id'] }], 'network_id': external_gw_port['network_id'], 'device_owner': l3_constants.DEVICE_OWNER_AGENT_GW, 'mac_address': 'fa:16:3e:80:8d:89', portbindings.HOST_ID: self.agent.conf.host, 'fixed_ips': [{ 'subnet_id': fixed_ip['subnet_id'], 'ip_address': fip_gw_port_ip, 'prefixlen': prefixlen }], 'id': framework._uuid(), 'device_id': framework._uuid() }]
def _add_snat_port_info_to_router(self, router, internal_ports): # Add snat port information to the router snat_port_list = router.get(l3_constants.SNAT_ROUTER_INTF_KEY, []) if not snat_port_list and internal_ports: # Get values from internal port port = internal_ports[0] fixed_ip = port['fixed_ips'][0] snat_subnet = port['subnets'][0] port_ip = fixed_ip['ip_address'] # Pick an ip address which is not the same as port_ip snat_ip = str(netaddr.IPAddress(port_ip) + 5) # Add the info to router as the first snat port # in the list of snat ports prefixlen = netaddr.IPNetwork(snat_subnet['cidr']).prefixlen router[l3_constants.SNAT_ROUTER_INTF_KEY] = [{ 'subnets': [{ 'cidr': snat_subnet['cidr'], 'gateway_ip': snat_subnet['gateway_ip'], 'id': fixed_ip['subnet_id'] }], 'network_id': port['network_id'], 'device_owner': l3_constants.DEVICE_OWNER_ROUTER_SNAT, 'mac_address': 'fa:16:3e:80:8d:89', 'fixed_ips': [{ 'subnet_id': fixed_ip['subnet_id'], 'ip_address': snat_ip, 'prefixlen': prefixlen }], 'id': framework._uuid(), 'device_id': framework._uuid() }]
def test_keepalived_configuration(self): router_info = self.generate_router_info(enable_ha=True) router = self.manage_router(self.agent, router_info) expected = self.get_expected_keepalive_configuration(router) self.assertEqual(expected, router.keepalived_manager.get_conf_on_disk()) # Add a new FIP and change the GW IP address router.router = copy.deepcopy(router.router) existing_fip = '19.4.4.2' new_fip = '19.4.4.3' self._add_fip(router, new_fip) subnet_id = framework._uuid() fixed_ips = [{'ip_address': '19.4.4.10', 'prefixlen': 24, 'subnet_id': subnet_id}] subnets = [{'id': subnet_id, 'cidr': '19.4.4.0/24', 'gateway_ip': '19.4.4.5'}] router.router['gw_port']['subnets'] = subnets router.router['gw_port']['fixed_ips'] = fixed_ips router.process(self.agent) # Get the updated configuration and assert that both FIPs are in, # and that the GW IP address was updated. new_config = router.keepalived_manager.config.get_config_str() old_gw = '0.0.0.0/0 via 19.4.4.1' new_gw = '0.0.0.0/0 via 19.4.4.5' old_external_device_ip = '19.4.4.4' new_external_device_ip = '19.4.4.10' self.assertIn(existing_fip, new_config) self.assertIn(new_fip, new_config) self.assertNotIn(old_gw, new_config) self.assertIn(new_gw, new_config) external_port = router.get_ex_gw_port() external_device_name = router.get_external_device_name( external_port['id']) self.assertNotIn('%s/24 dev %s' % (old_external_device_ip, external_device_name), new_config) self.assertIn('%s/24 dev %s' % (new_external_device_ip, external_device_name), new_config)
def test_dvr_router_fips_stale_gw_port(self): self.agent.conf.agent_mode = 'dvr' # Create the router with external net dvr_router_kwargs = {'ip_address': '19.4.4.3', 'subnet_cidr': '19.4.4.0/24', 'gateway_ip': '19.4.4.1', 'gateway_mac': 'ca:fe:de:ab:cd:ef'} router_info = self.generate_dvr_router_info(**dvr_router_kwargs) external_gw_port = router_info['gw_port'] ext_net_id = router_info['_floatingips'][0]['floating_network_id'] self.mock_plugin_api.get_external_network_id.return_value(ext_net_id) # Create the fip namespace up front stale_fip_ns = dvr_fip_ns.FipNamespace(ext_net_id, self.agent.conf, self.agent.driver, self.agent.use_ipv6) stale_fip_ns.create() # Add a stale fg port to the namespace fixed_ip = external_gw_port['fixed_ips'][0] float_subnet = external_gw_port['subnets'][0] fip_gw_port_ip = str(netaddr.IPAddress(fixed_ip['ip_address']) + 10) prefixlen = netaddr.IPNetwork(float_subnet['cidr']).prefixlen stale_agent_gw_port = { 'subnets': [{'cidr': float_subnet['cidr'], 'gateway_ip': float_subnet['gateway_ip'], 'id': fixed_ip['subnet_id']}], 'network_id': external_gw_port['network_id'], 'device_owner': l3_constants.DEVICE_OWNER_AGENT_GW, 'mac_address': 'fa:16:3e:80:8f:89', portbindings.HOST_ID: self.agent.conf.host, 'fixed_ips': [{'subnet_id': fixed_ip['subnet_id'], 'ip_address': fip_gw_port_ip, 'prefixlen': prefixlen}], 'id': framework._uuid(), 'device_id': framework._uuid()} stale_fip_ns.create_gateway_port(stale_agent_gw_port) stale_dev_exists = self.device_exists_with_ips_and_mac( stale_agent_gw_port, stale_fip_ns.get_ext_device_name, stale_fip_ns.get_name()) self.assertTrue(stale_dev_exists) # Create the router, this shouldn't allow the duplicate port to stay router = self.manage_router(self.agent, router_info) # Assert the device no longer exists stale_dev_exists = self.device_exists_with_ips_and_mac( stale_agent_gw_port, stale_fip_ns.get_ext_device_name, stale_fip_ns.get_name()) self.assertFalse(stale_dev_exists) # Validate things are looking good and clean up self._validate_fips_for_external_network( router, router.fip_ns.get_name()) ext_gateway_port = router_info['gw_port'] self._delete_router(self.agent, router.router_id) self._assert_fip_namespace_deleted(ext_gateway_port)
def test_dvr_router_fips_stale_gw_port(self): self.agent.conf.agent_mode = 'dvr' # Create the router with external net dvr_router_kwargs = { 'ip_address': '19.4.4.3', 'subnet_cidr': '19.4.4.0/24', 'gateway_ip': '19.4.4.1', 'gateway_mac': 'ca:fe:de:ab:cd:ef' } router_info = self.generate_dvr_router_info(**dvr_router_kwargs) external_gw_port = router_info['gw_port'] ext_net_id = router_info['_floatingips'][0]['floating_network_id'] self.mock_plugin_api.get_external_network_id.return_value(ext_net_id) # Create the fip namespace up front stale_fip_ns = dvr_fip_ns.FipNamespace(ext_net_id, self.agent.conf, self.agent.driver, self.agent.use_ipv6) stale_fip_ns.create() # Add a stale fg port to the namespace fixed_ip = external_gw_port['fixed_ips'][0] float_subnet = external_gw_port['subnets'][0] fip_gw_port_ip = str(netaddr.IPAddress(fixed_ip['ip_address']) + 10) prefixlen = netaddr.IPNetwork(float_subnet['cidr']).prefixlen stale_agent_gw_port = { 'subnets': [{ 'cidr': float_subnet['cidr'], 'gateway_ip': float_subnet['gateway_ip'], 'id': fixed_ip['subnet_id'] }], 'network_id': external_gw_port['network_id'], 'device_owner': lib_constants.DEVICE_OWNER_AGENT_GW, 'mac_address': 'fa:16:3e:80:8f:89', portbindings.HOST_ID: self.agent.conf.host, 'fixed_ips': [{ 'subnet_id': fixed_ip['subnet_id'], 'ip_address': fip_gw_port_ip, 'prefixlen': prefixlen }], 'id': framework._uuid(), 'device_id': framework._uuid() } stale_fip_ns.create_gateway_port(stale_agent_gw_port) stale_dev_exists = self.device_exists_with_ips_and_mac( stale_agent_gw_port, stale_fip_ns.get_ext_device_name, stale_fip_ns.get_name()) self.assertTrue(stale_dev_exists) # Create the router, this shouldn't allow the duplicate port to stay router = self.manage_router(self.agent, router_info) # Assert the device no longer exists stale_dev_exists = self.device_exists_with_ips_and_mac( stale_agent_gw_port, stale_fip_ns.get_ext_device_name, stale_fip_ns.get_name()) self.assertFalse(stale_dev_exists) # Validate things are looking good and clean up self._validate_fips_for_external_network(router, router.fip_ns.get_name()) ext_gateway_port = router_info['gw_port'] self._delete_router(self.agent, router.router_id) self._assert_fip_namespace_deleted(ext_gateway_port)