def on_deleted(path): """Invoked when a network rule is deleted.""" # Edge case, if the directory where the rules are kept gets removed, # abort if path == rulemgr.path: _LOGGER.critical('Network rules directory was removed: %r', path) utils.sys_exit(1) # The rule is the filename rule_file = os.path.basename(path) _LOGGER.info('Removing %r', rule_file) chain_rule = rulemgr.get_rule(rule_file) if chain_rule is not None: chain, rule = chain_rule iptables.delete_rule(rule, chain=chain) if isinstance(rule, fw.PassThroughRule): if passthrough[rule.src_ip] == 1: # Remove the IPs from the passthrough set passthrough.pop(rule.src_ip) _LOGGER.info('Removing passthrough %r', rule.src_ip) iptables.rm_ip_set(iptables.SET_PASSTHROUGHS, rule.src_ip) iptables.flush_pt_conntrack_table(rule.src_ip) else: passthrough[rule.src_ip] -= 1 elif isinstance(rule, (fw.SNATRule, fw.DNATRule)): if rule.proto == 'udp': iptables.flush_conntrack_table( src_ip=rule.src_ip, src_port=rule.src_port, dst_ip=rule.dst_ip, dst_port=rule.dst_port, ) else: _LOGGER.warning('Ignoring unparseable file %r', rule_file)
def on_created(path): """Invoked when a network rule is created.""" rule_file = os.path.basename(path) _LOGGER.info('adding %r', rule_file) # The rule is the filename chain_rule = rulemgr.get_rule(rule_file) if chain_rule is not None: chain, rule = chain_rule iptables.add_rule(rule, chain=chain) if isinstance(rule, fw.PassThroughRule): passthrough[rule.src_ip] = ( passthrough.setdefault(rule.src_ip, 0) + 1 ) _LOGGER.info('Adding passthrough %r', rule.src_ip) iptables.add_ip_set(iptables.SET_PASSTHROUGHS, rule.src_ip) iptables.flush_pt_conntrack_table(rule.src_ip) elif isinstance(rule, (fw.SNATRule, fw.DNATRule)): if rule.proto == 'udp': iptables.flush_conntrack_table( src_ip=rule.src_ip, src_port=rule.src_port, dst_ip=rule.dst_ip, dst_port=rule.dst_port, ) else: _LOGGER.warning('Ignoring unparseable rule %r', rule_file)
def _cleanup_network(tm_env, app, network_client): """Cleanup the network part of a container. """ # Generate a unique name for the app unique_name = appmgr.app_unique_name(app) try: app_network = network_client.get(unique_name) except services.ResourceServiceError: _LOGGER.warning('network never allocated') return if app_network is None: _LOGGER.info('Network resource already freed') return # Unconfigure passthrough if hasattr(app, 'passthrough'): _LOGGER.info('Deleting passthrough for: %r', app.passthrough) # Resolve all the hosts # FIXME: There is no guarantie the hosts will resolve to # the same IPs as they did during creation. ips = set([socket.gethostbyname(host) for host in app.passthrough]) for ip in ips: tm_env.rules.unlink_rule( rule=firewall.PassThroughRule(src_ip=ip, dst_ip=app_network['vip']), owner=unique_name, ) for endpoint in app.endpoints: tm_env.rules.unlink_rule( rule=firewall.DNATRule(proto=endpoint.proto, orig_ip=app.host_ip, orig_port=endpoint.real_port, new_ip=app_network['vip'], new_port=endpoint.port), owner=unique_name, ) # See if this was an "infra" endpoint and if so remove it # from the whitelist set. if getattr(endpoint, 'type', None) == 'infra': _LOGGER.debug('removing %s:%s from infra services set', app_network['vip'], endpoint.port) iptables.rm_ip_set( iptables.SET_INFRA_SVC, '{ip},{proto}:{port}'.format( ip=app_network['vip'], proto=endpoint.proto, port=endpoint.port, )) _cleanup_ports(tm_env, unique_name, app_network['vip'], app.ephemeral_ports.tcp, 'tcp') _cleanup_ports(tm_env, unique_name, app_network['vip'], app.ephemeral_ports.udp, 'udp') # Terminate any entries in the conntrack table iptables.flush_conntrack_table(app_network['vip']) # Cleanup network resources network_client.delete(unique_name)