def __init__(self, conf, router): self.conf = conf self.id = router['id'] self.router = router # TODO(cbrandily): deduplicate ns_name generation in metering/l3 self.ns_name = NS_PREFIX + self.id self.iptables_manager = None self.snat_iptables_manager = None if self.router['distributed']: # If distributed routers then we need to apply the # metering agent label rules in the snat namespace as well. snat_ns_name = dvr_snat_ns.SnatNamespace.get_snat_ns_name(self.id) # Check for namespace existence before we assign the # snat_iptables_manager if ip_lib.network_namespace_exists(snat_ns_name): self.snat_iptables_manager = iptables_manager.IptablesManager( namespace=snat_ns_name, binary_name=WRAP_NAME, state_less=True, use_ipv6=ipv6_utils.is_enabled_and_bind_by_default()) # Check of namespace existence before we assign the iptables_manager # NOTE(Swami): If distributed routers, all external traffic on a # compute node will flow through the rfp interface in the router # namespace. if ip_lib.network_namespace_exists(self.ns_name): self.iptables_manager = iptables_manager.IptablesManager( namespace=self.ns_name, binary_name=WRAP_NAME, state_less=True, use_ipv6=ipv6_utils.is_enabled_and_bind_by_default()) self.metering_labels = {}
def __init__(self, conf, router): self.conf = conf self.id = router['id'] self.router = router # TODO(cbrandily): deduplicate ns_name generation in metering/l3 self.ns_name = NS_PREFIX + self.id self.iptables_manager = None self.snat_iptables_manager = None if self.router['distributed']: # If distributed routers then we need to apply the # metering agent label rules in the snat namespace as well. snat_ns_name = dvr_snat_ns.SnatNamespace.get_snat_ns_name( self.id) # Check for namespace existence before we assign the # snat_iptables_manager if ip_lib.network_namespace_exists(snat_ns_name): self.snat_iptables_manager = iptables_manager.IptablesManager( namespace=snat_ns_name, binary_name=WRAP_NAME, state_less=True, use_ipv6=ipv6_utils.is_enabled_and_bind_by_default()) # Check of namespace existence before we assign the iptables_manager # NOTE(Swami): If distributed routers, all external traffic on a # compute node will flow through the rfp interface in the router # namespace. if ip_lib.network_namespace_exists(self.ns_name): self.iptables_manager = iptables_manager.IptablesManager( namespace=self.ns_name, binary_name=WRAP_NAME, state_less=True, use_ipv6=ipv6_utils.is_enabled_and_bind_by_default()) self.metering_labels = {}
def _check_rtr_2_fip_connect(self): """Checks if the rtr to fip connect exists, if not sets to false.""" fip_ns_name = self.fip_ns.get_name() if ip_lib.network_namespace_exists(fip_ns_name): fip_2_rtr_name = self.fip_ns.get_int_device_name(self.router_id) if not ip_lib.device_exists(fip_2_rtr_name, namespace=fip_ns_name): self.rtr_fip_connect = False
def destroy(self): if (ip_lib.network_namespace_exists(self.ip_dev.namespace) or self.ip_dev.namespace is None): try: self.ip_dev.link.delete() except RuntimeError: pass
def _check_rtr_2_fip_connect(self): """Checks if the rtr to fip connect exists, if not sets to false.""" fip_ns_name = self.fip_ns.get_name() if ip_lib.network_namespace_exists(fip_ns_name): fip_2_rtr_name = self.fip_ns.get_int_device_name(self.router_id) if not ip_lib.device_exists(fip_2_rtr_name, namespace=fip_ns_name): self.rtr_fip_connect = False
def destroy(self): if (ip_lib.network_namespace_exists(self.ip_dev.namespace) or self.ip_dev.namespace is None): try: self.ip_dev.link.delete() except RuntimeError: pass
def netns_read_requires_helper(): nsname = "netnsreadtest-" + uuidutils.generate_uuid() ip_lib.create_network_namespace(nsname) try: # read without root_helper. if exists, not required. exists = ip_lib.network_namespace_exists(nsname) finally: ip_lib.delete_network_namespace(nsname) return not exists
def netns_read_requires_helper(): nsname = "netnsreadtest-" + uuidutils.generate_uuid() ip_lib.create_network_namespace(nsname) try: # read without root_helper. if exists, not required. exists = ip_lib.network_namespace_exists(nsname) finally: ip_lib.delete_network_namespace(nsname) return not exists
def _add_interface_route_to_fip_ns(self, router_port): rtr_2_fip_ip, fip_2_rtr_name = self.get_rtr_fip_ip_and_interface_name() fip_ns_name = self.fip_ns.get_name() if ip_lib.network_namespace_exists(fip_ns_name): device = ip_lib.IPDevice(fip_2_rtr_name, namespace=fip_ns_name) if not device.exists(): return for subnet in router_port['subnets']: rtr_port_cidr = subnet['cidr'] device.route.add_route(rtr_port_cidr, str(rtr_2_fip_ip))
def _add_interface_route_to_fip_ns(self, router_port): rtr_2_fip_ip, fip_2_rtr_name = self.get_rtr_fip_ip_and_interface_name() fip_ns_name = self.fip_ns.get_name() if ip_lib.network_namespace_exists(fip_ns_name): device = ip_lib.IPDevice(fip_2_rtr_name, namespace=fip_ns_name) if not device.exists(): return for subnet in router_port['subnets']: rtr_port_cidr = subnet['cidr'] device.route.add_route(rtr_port_cidr, str(rtr_2_fip_ip))
def create_iptables_managers(self): """Creates iptables managers if the are not already created Returns True if any manager is created """ created = False if self.router['distributed'] and self.snat_iptables_manager is None: # If distributed routers then we need to apply the # metering agent label rules in the snat namespace as well. snat_ns_name = dvr_snat_ns.SnatNamespace.get_snat_ns_name(self.id) # Check for namespace existence before we assign the # snat_iptables_manager if ip_lib.network_namespace_exists(snat_ns_name): self.snat_iptables_manager = iptables_manager.IptablesManager( namespace=snat_ns_name, binary_name=WRAP_NAME, state_less=True, use_ipv6=netutils.is_ipv6_enabled()) created = True if self.iptables_manager is None: # Check of namespace existence before we assign the # iptables_manager # NOTE(Swami): If distributed routers, all external traffic on a # compute node will flow through the rfp interface in the router # namespace. if ip_lib.network_namespace_exists(self.ns_name): self.iptables_manager = iptables_manager.IptablesManager( namespace=self.ns_name, binary_name=WRAP_NAME, state_less=True, use_ipv6=netutils.is_ipv6_enabled()) created = True return created
def delete_probe(self, port_id): port = dhcp.DictModel(self.client.show_port(port_id)['port']) namespace = self._get_namespace(port) if ip_lib.network_namespace_exists(namespace): self.driver.unplug(self.driver.get_device_name(port), namespace=namespace) try: ip_lib.delete_network_namespace(namespace) except Exception: LOG.warning('Failed to delete namespace %s', namespace) else: self.driver.unplug(self.driver.get_device_name(port)) self.client.delete_port(port.id)
def delete_probe(self, port_id): port = dhcp.DictModel(self.client.show_port(port_id)['port']) namespace = self._get_namespace(port) if ip_lib.network_namespace_exists(namespace): self.driver.unplug(self.driver.get_device_name(port), namespace=namespace) try: ip_lib.delete_network_namespace(namespace) except Exception: LOG.warning('Failed to delete namespace %s', namespace) else: self.driver.unplug(self.driver.get_device_name(port)) self.client.delete_port(port.id)
def delete_probe(self, port_id): port = dhcp.DictModel(self.client.show_port(port_id)['port']) network = self._get_network(port.network_id) bridge = None if network.external: bridge = self.conf.external_network_bridge namespace = self._get_namespace(port) if ip_lib.network_namespace_exists(namespace): self.driver.unplug(self.driver.get_device_name(port), bridge=bridge, namespace=namespace) try: ip_lib.delete_network_namespace(namespace) except Exception: LOG.warning('Failed to delete namespace %s', namespace) else: self.driver.unplug(self.driver.get_device_name(port), bridge=bridge) self.client.delete_port(port.id)
def assert_dhcp_namespace(self, namespace, dhcp_enabled): self.assertEqual(dhcp_enabled, ip_lib.network_namespace_exists(namespace))
def _apply_synchronized(self): """Apply the current in-memory set of iptables rules. This will create a diff between the rules from the previous runs and replace them with the current set of rules. This happens atomically, thanks to iptables-restore. Returns a list of the changes that were sent to iptables-save. """ s = [('iptables', self.ipv4)] if self.use_ipv6: s += [('ip6tables', self.ipv6)] all_commands = [] # variable to keep track all commands for return val for cmd, tables in s: args = ['%s-save' % (cmd, )] if self.namespace: args = ['ip', 'netns', 'exec', self.namespace] + args try: save_output = self.execute(args, run_as_root=True) except RuntimeError: # We could be racing with a cron job deleting namespaces. # It is useless to try to apply iptables rules over and # over again in a endless loop if the namespace does not # exist. with excutils.save_and_reraise_exception() as ctx: if (self.namespace and not ip_lib.network_namespace_exists( self.namespace)): ctx.reraise = False LOG.error( "Namespace %s was deleted during IPTables " "operations.", self.namespace) return [] all_lines = save_output.split('\n') commands = [] # Traverse tables in sorted order for predictable dump output for table_name in sorted(tables): table = tables[table_name] # isolate the lines of the table we are modifying start, end = self._find_table(all_lines, table_name) old_rules = all_lines[start:end] # generate the new table state we want new_rules = self._modify_rules(old_rules, table, table_name) # generate the iptables commands to get between the old state # and the new state changes = _generate_path_between_rules(old_rules, new_rules) if changes: # if there are changes to the table, we put on the header # and footer that iptables-save needs commands += (['# Generated by iptables_manager'] + ['*%s' % table_name] + changes + ['COMMIT', '# Completed by iptables_manager']) if not commands: continue all_commands += commands # always end with a new line commands.append('') args = ['%s-restore' % (cmd, ), '-n'] if self.namespace: args = ['ip', 'netns', 'exec', self.namespace] + args err = self._run_restore(args, commands) if err: self._log_restore_err(err, commands) raise err LOG.debug( "IPTablesManager.apply completed with success. %d iptables " "commands were issued", len(all_commands)) return all_commands
def assert_namespace_exists(self, ns_name): common_utils.wait_until_true(lambda: ip_lib.network_namespace_exists( ns_name, try_is_ready=True))
def _namespace_exists(self, namespace): return ip_lib.network_namespace_exists(namespace)
def test_network_namespace_exists_ns_exists_try_is_ready(self): self.assertTrue( ip_lib.network_namespace_exists(self.namespace, try_is_ready=True))
def _assert_namespace_exists(self, ns_name): common_utils.wait_until_true( lambda: ip_lib.network_namespace_exists(ns_name))
def test_network_namespace_exists_ns_doesnt_exists(self): self.assertFalse(ip_lib.network_namespace_exists('another_ns'))
def _namespace_exists(self, namespace): return ip_lib.network_namespace_exists(namespace)
def test_network_namespace_exists_ns_doesnt_exists(self): self.assertFalse(ip_lib.network_namespace_exists('another_ns'))
def test_network_namespace_exists_ns_exists(self): self.assertTrue(ip_lib.network_namespace_exists(self.namespace))
def _assert_namespace_exists(self, ns_name): common_utils.wait_until_true( lambda: ip_lib.network_namespace_exists(ns_name))
def assert_dhcp_namespace(self, namespace, dhcp_enabled): self.assertEqual(dhcp_enabled, ip_lib.network_namespace_exists(namespace))
def test_network_namespace_exists_ns_doesnt_exists_try_is_ready(self): self.assertFalse(ip_lib.network_namespace_exists('another_ns', try_is_ready=True))
def test_network_namespace_exists_ns_exists(self): self.assertTrue(ip_lib.network_namespace_exists(self.namespace))
def assert_namespace_exists(self, ns_name): common_utils.wait_until_true( lambda: ip_lib.network_namespace_exists(ns_name, try_is_ready=True))
def test_network_namespace_exists_ns_doesnt_exists(self): for use_helper_for_ns_read in (True, False): cfg.CONF.set_override('use_helper_for_ns_read', use_helper_for_ns_read, 'AGENT') self.assertFalse(ip_lib.network_namespace_exists('another_ns'))
def _apply_synchronized(self): """Apply the current in-memory set of iptables rules. This will create a diff between the rules from the previous runs and replace them with the current set of rules. This happens atomically, thanks to iptables-restore. Returns a list of the changes that were sent to iptables-save. """ s = [('iptables', self.ipv4)] if self.use_ipv6: s += [('ip6tables', self.ipv6)] all_commands = [] # variable to keep track all commands for return val for cmd, tables in s: args = ['%s-save' % (cmd,)] if self.namespace: args = ['ip', 'netns', 'exec', self.namespace] + args try: save_output = self.execute(args, run_as_root=True) except RuntimeError: # We could be racing with a cron job deleting namespaces. # It is useless to try to apply iptables rules over and # over again in a endless loop if the namespace does not # exist. with excutils.save_and_reraise_exception() as ctx: if (self.namespace and not ip_lib.network_namespace_exists(self.namespace)): ctx.reraise = False LOG.error("Namespace %s was deleted during IPTables " "operations.", self.namespace) return [] all_lines = save_output.split('\n') commands = [] # Traverse tables in sorted order for predictable dump output for table_name in sorted(tables): table = tables[table_name] # isolate the lines of the table we are modifying start, end = self._find_table(all_lines, table_name) old_rules = all_lines[start:end] # generate the new table state we want new_rules = self._modify_rules(old_rules, table, table_name) # generate the iptables commands to get between the old state # and the new state changes = _generate_path_between_rules(old_rules, new_rules) if changes: # if there are changes to the table, we put on the header # and footer that iptables-save needs commands += (['# Generated by iptables_manager'] + ['*%s' % table_name] + changes + ['COMMIT', '# Completed by iptables_manager']) if not commands: continue all_commands += commands # always end with a new line commands.append('') args = ['%s-restore' % (cmd,), '-n'] if self.namespace: args = ['ip', 'netns', 'exec', self.namespace] + args err = self._run_restore(args, commands) if err: self._log_restore_err(err, commands) raise err LOG.debug("IPTablesManager.apply completed with success. %d iptables " "commands were issued", len(all_commands)) return all_commands
def test_network_namespace_exists_ns_doesnt_exists_try_is_ready(self): self.assertFalse( ip_lib.network_namespace_exists('another_ns', try_is_ready=True))
def test_network_namespace_exists_ns_exists_try_is_ready(self): self.assertTrue(ip_lib.network_namespace_exists(self.namespace, try_is_ready=True))