class IPtables(object): """ represent a iptables object, which can handle the table rules """ def __init__(self, ns=None): self.valid_tables = ['raw', 'nat', 'filter', 'mangle', 'security'] self.tables = {} self.nss = NameSpaces() self.ns = ns for tb in self.valid_tables: self.tables[tb] = IPtable(tb, ns) self._load(ns=self.ns) def get_valid_tables(self): return self.valid_tables def _load(self, table=None, chain=None, ns=None): ''' Load the rules from system. If given table name, then only load that table. :param table: which table to load, None for all :param chain: which chain to load, None for all :param ns: which ns to load, None for root :return: ''' _ns = ns or self.ns if table in self.valid_tables: self.tables[table].load(chain, _ns) else: for tb in self.valid_tables: self.tables[tb].load(chain, _ns) def show(self, table='filter', chain=None, ns=None): ''' Show the content. :param table: which table to show, None for all :param chain: which chain to show, None for all. :return: ''' debug("Show table=%s, chain=%s, ns=%s\n" % (table, chain, ns)) #self._load(table, chain, ns) if table in self.valid_tables: self.tables[table].show(chain) def vm(self, ip): ''' list vm related rules :param ip: vm ip :return: ''' debug("Try to show vm rules, ip=%s\n" % ip) port_id = get_port_id_from_ip(ip) debug('The port id is %s\n' % port_id) if not port_id: warn('No port id is found for ip=%s\n' % ip) return br_port = find_br_ports(port_id) if not br_port: warn('No br port is found for ip=%s\n' % ip) return output(r('## IP = %s, port = %s\n' % (ip, br_port))) rules_dic = self._query_port_rules(br_port) if rules_dic: output(b( _format_str_iptables_rule_ % ( 'PKTS', 'IN', 'SOURCE', 'OUT', 'DESTINATION', 'PROT', 'TARGET', 'OTHER'))) for rule in rules_dic: output(b('%s:\n' % rule)) self._fmt_show_rules(rules_dic[rule]) def has_rule(self, table='filter', chain='INPUT', rule_dic=None, ns=None): """ Whether the table/chain has the rule :param table: :param chain: :param rule_dic: :param ns: :return: """ t = self.get_table(table) if not t: return False else: return t.has_rule(chain, rule_dic) pass def get_table(self, table='filter'): ''' Get some table handler of this ipt instance. :param table: :return: the table instance, None if failed ''' return self.tables.get(table, None) def get_chain(self, table='filter', chain='INPUT'): ''' Get some table handler of this ipt instance. :param table: :return: the table instance, None if failed ''' tb = self.tables.get(table, None) if tb: return tb.get_chain(chain) def _get_rules(self, table='filter', chain='INPUT', ns=None): ''' Get the rule list of a given chain :param table: :param chain: :return: [{},{}] ''' ch = self.get_chain(table, chain) if ch: return ch._get_rules() else: return None def _query_port_rules(self, br_port): """ Return the dict of the related security rules on a given port. { 'NAME':[iptables rules], } will load rules first """ results = {} if br_port.startswith('qvo'): # vm port debug('qvo should be vm port\n') #self._load(table='filter') chain_tag = br_port[3:13] i_rules = self._get_rules(chain='neutron-openvswi-i' + chain_tag) out = self._get_rules(chain='neutron-openvswi-o' + chain_tag) filter = self._get_rules(chain='neutron-openvswi-s' + chain_tag) if i_rules: results['IN'] = i_rules if out: results['OUT'] = out if filter: results['SRC_FILTER'] = filter else: # maybe at Network Node debug('Should be network function port\n') ns = self.nss.get_intf_by_name(br_port) if not ns: warn("port %s not in namespaces\n" % br_port) else: output('ns=%s\n' % ns) self._load(table='nat', ns=ns) if br_port.startswith('tap'): # dhcp return None elif br_port.startswith('qr-') or br_port.startswith('qg-'): pre = self._get_rules(table='nat', chain='neutron-l3-agent-PREROUTING') out = self._get_rules(table='nat', chain='neutron-l3-agent-OUTPUT') float_snat = self._get_rules(table='nat', chain='neutron-l3-agent-float-snat') snat = self._get_rules(table='nat', chain='neutron-l3-agent-snat') if pre: results['PRE'] = pre if out: results['OUT'] = out if float_snat: results['FLOAT'] = float_snat if snat: results['SNAT'] = snat return results def _fmt_show_rules(self, rule_list): """ Possible columns: num pkts bytes target prot opt in out source destination flags """ for r in rule_list: r.show()
class DVR(object): """ DVR configuration """ def __init__(self, node='compute'): """ :param node: on computer node or network node """ self.node = node self.br_int = Bridge('br-int') self.nss = NameSpaces() def check(self, _node=None): node = _node or self.node if node in 'compute': output(b('# Checking DVR on compute node\n')) self._check_compute_node() elif node in 'network': output(b('# Checking DVR on network node\n')) self._check_network_node() else: error('Unknown node type=%s, compute or network?\n' % node) def _check_chain_rule_num(self, table, c_name, num): """ Check if the chain has given number of rules. :param table: :param c_name: :param num: :return: """ output(b('Checking chain rule number: %s...' % c_name)) c = table.get_chain(c_name) if len(c.get_rules()) != num: warn(r("Wrong rule number in chain %s\n" % c_name)) return False else: output(g('Passed\n')) return True def _check_chain_has_rule(self, table, c_name, rule): """ :param rule: :return: True or False """ output(b('Checking chain rules: %s...' % c_name)) c = table.get_chain(c_name) if not c.has_rule(rule): warn(r("Defined rule not in %s\n" % c_name)) return False else: output(g('Passed\n')) return True def _check_compute_node_nat_rules(self, qr_intfs, rfp_intfs, nat, ns_fip): """ Check three chains rules match with each other :param nat: the nat table :param ns_fip: :return: True or False """ c_name = 'neutron-l3-agent-PREROUTING' rule = { 'in': 'qr-+', 'source': '*', 'out': '*', 'destination': '169.254.169.254', 'target': 'REDIRECT', 'prot': 'tcp', 'flags': 'tcp dpt:80 redir ports 9697' } if not self._check_chain_has_rule(nat, c_name, rule): return False ips_qr = [ item for sublist in map(lambda x: x['ip'], qr_intfs) for item in sublist ] ips_rfp = [ item for sublist in map(lambda x: x['ip'], rfp_intfs) for item in sublist ] for intf in rfp_intfs: c_name = 'neutron-l3-agent-PREROUTING' for ip_m in intf['ip'][1:]: # check each floating ip dip = ip_m.split('/')[0] # real floating ip for destination if not ipInNetworks(dip, ips_rfp): warn(r('dip %s not in rfp ports %s\n' % (dip, ips_rfp))) return False rule = nat.get_rule(c_name, {'destination': dip}) sip = rule.get_flags().split(':')[1] if not ipInNetworks(sip, ips_qr): warn(r('sip %s not in qr port %s\n' % (sip, ips_qr))) return False rule_expect = { 'in': '*', 'source': '*', 'out': '*', 'destination': dip, 'target': 'DNAT', 'prot': '*', 'flags': 'to:' + sip } if not rule.is_match(rule_expect): warn(r('rule not matched in %s\n' % (c_name))) return False if not self._check_chain_has_rule( nat, 'neutron-l3-agent-OUTPUT', rule_expect): return False else: output( g('DNAT for incomping: %s --> %s passed\n' % (dip, sip))) rule_expect = { 'in': '*', 'source': sip, 'out': '*', 'destination': '*', 'target': 'SNAT', 'prot': '*', 'flags': 'to:' + dip } if not self._check_chain_has_rule( nat, 'neutron-l3-agent-float-snat', rule_expect): return False else: output( g('SNAT for outgoing: %s --> %s passed\n' % (sip, dip))) return True def _check_compute_node_nat_table(self, ns_q, ns_fip): """ Check the snat rules in the given ns :param ns_q: :param ns_fip: :return: """ ipt = IPtables(ns_q) nat = ipt.get_table(table='nat') chains = [ 'neutron-postrouting-bottom', 'neutron-l3-agent-OUTPUT', 'POSTROUTING', 'neutron-l3-agent-PREROUTING', 'PREROUTING', 'neutron-l3-agent-float-snat', 'OUTPUT', 'INPUT', 'neutron-l3-agent-POSTROUTING', 'neutron-l3-agent-snat', ] for c_name in chains: c = nat.get_chain(c_name) if not c: warn(r("Not found chain %s\n" % c_name)) return False if c.get_policy() != 'ACCEPT': warn(r("Chain %s's policy is not ACCEPT\n" % c.name)) for c_name in [ 'neutron-postrouting-bottom', 'OUTPUT', 'neutron-l3-agent-snat' ]: if not self._check_chain_rule_num(nat, c_name, 1): return False c_name = 'neutron-postrouting-bottom' rule = { 'in': '*', 'source': '*', 'out': '*', 'destination': '*', 'target': 'neutron-l3-agent-snat', 'prot': '*' } if not self._check_chain_has_rule(nat, c_name, rule): return False c_name = 'PREROUTING' rule = { 'in': '*', 'source': '*', 'out': '*', 'destination': '*', 'target': 'neutron-l3-agent-PREROUTING', 'prot': '*' } if not self._check_chain_has_rule(nat, c_name, rule): return False c_name = 'OUTPUT' rule = { 'in': '*', 'source': '*', 'out': '*', 'destination': '*', 'target': 'neutron-l3-agent-OUTPUT', 'prot': '*' } if not self._check_chain_has_rule(nat, c_name, rule): return False c_name = 'POSTROUTING' rule = { 'in': '*', 'source': '*', 'out': '*', 'destination': '*', 'target': 'neutron-l3-agent-POSTROUTING', 'prot': '*' } if not self._check_chain_has_rule(nat, c_name, rule): return False rule = { 'in': '*', 'source': '*', 'out': '*', 'destination': '*', 'target': 'neutron-postrouting-bottom', 'prot': '*' } if not self._check_chain_has_rule(nat, c_name, rule): return False c_name = 'neutron-l3-agent-POSTROUTING' rfp_intfs = NameSpace(ns_q).find_intfs('rfp-') for intf in rfp_intfs: rule = { 'in': '!' + intf['intf'], 'source': '*', 'out': '!' + intf['intf'], 'destination': '*', 'target': 'ACCEPT', 'prot': '*', 'flags': '! ctstate DNAT' } if not self._check_chain_has_rule(nat, c_name, rule): return False qr_intfs = NameSpace(ns_q).find_intfs('qr-') if not self._check_compute_node_nat_rules(qr_intfs, rfp_intfs, nat, ns_fip): return False return True def _check_compute_node_snat_ns(self, ns_router): """ Check the local router namespace on compute node :param ns_router: :return: list of the fip ns """ if not ns_router: return self.nss.show(ns_router) intfs = NameSpace(ns_router).get_intfs() rfp_ports = [] # list of {'intf':eth0, 'ip':[]} for i in intfs: # check each intf in this ns p = intfs[i]['intf'] if p.startswith('rfp-'): # rfp port in q connect to fpr in fip rfp_ports.append(p) output(b('### Checking rfp port %s\n' % p)) if len(intfs[i]['ip']) < 2: warn(r('Missing ips for port %s\n' % p)) continue else: output( g('Found associated floating ips : %s\n' % ', '.join(intfs[i]['ip'][1:]))) ns_fip = self.nss.get_intf_by_name('fpr-' + intfs[i]['intf'][4:]) if not ns_fip: warn(r('Cannot find fip ns for %s\n' % q)) return self._check_compute_node_fip_ns(intfs[i], ns_fip) self._check_compute_node_nat_table(ns_router, ns_fip) if not rfp_ports: warn(r('Cannot find rfp port in ns %s\n' % ns_router)) elif len(rfp_ports) > 1: warn(r('More than 1 rfp ports in ns %s\n' % ns_router)) def _check_compute_node_fip_ns(self, rfp_port, ns_fip): """ Check a fip namespace on compute node :param rfp_port: :return: """ q = 'fpr-' + rfp_port['intf'][4:] output(b('### Checking associated fpr port %s\n' % q)) self.nss.show(ns_fip) output(b('### Check related fip_ns=%s\n' % ns_fip)) fpr_port = NameSpace(ns_fip).get_intf_by_name(q) if not fpr_port: warn(r('Cannot find fpr_port in fip ns %s\n' % ns_fip)) return a_ip, a_mask = rfp_port['ip'][0].split('/') b_ip, b_mask = fpr_port['ip'][0].split('/') if networkMask(a_ip, a_mask) != networkMask(b_ip, b_mask): warn( r('Different subnets for %s and %s\n' % (rfp_port['ip'][0], fpr_port['ip'][0]))) return else: output(g('Bridging in the same subnet\n')) fg_port = NameSpace(ns_fip).find_intf('fg-') if not fg_port: warn('Cannot find fg_port in fip ns %s\n' % ns_fip) return if fg_port['intf'] in Bridge('br-ex').get_ports(): output(g('fg port is attached to br-ex\n')) else: warn(g('fg port is NOT attached to br-ex\n')) return for float_ip in rfp_port['ip'][1:]: ip = float_ip.split('/')[0] if ipInNetwork(ip, fg_port['ip'][0]): output(g('floating ip %s match fg subnet\n' % ip)) else: warn(r('floating ip %s No match the fg subnet' % ip)) def _check_compute_node(self): """ Check the qrouter-*** fip-*** spaces in the compute node. :return: """ checked_ns = [] for port in self.br_int.get_ports(): if port.startswith('qr-'): # qrouter port output(b('## Checking router port = %s\n' % port)) nsrouter = self.nss.get_intf_by_name(port) if nsrouter in checked_ns: output(g('Checking passed already\n')) continue else: checked_ns.append(nsrouter) # the names of the ns checked self._check_compute_node_snat_ns(nsrouter) pass pass def _check_network_node(self): """ Check the qrouter-*** fip-*** snat-*** spaces in the network node. :return: """ pass
class IPtables(object): """ represent a iptables object, which can handle the table rules """ def __init__(self, ns=None): self.valid_tables = ['raw', 'nat', 'filter', 'mangle', 'security'] self.tables = {} self.nss = NameSpaces() self.ns = ns for tb in self.valid_tables: self.tables[tb] = IPtable(tb, ns) self._load(ns=self.ns) def get_valid_tables(self): return self.valid_tables def _load(self, table=None, chain=None, ns=None): ''' Load the rules from system. If given table name, then only load that table. :param table: which table to load, None for all :param chain: which chain to load, None for all :param ns: which ns to load, None for root :return: ''' _ns = ns or self.ns if table in self.valid_tables: self.tables[table].load(chain, _ns) else: for tb in self.valid_tables: self.tables[tb].load(chain, _ns) def show(self, table='filter', chain=None, ns=None): ''' Show the content. :param table: which table to show, None for all :param chain: which chain to show, None for all. :return: ''' debug("Show table=%s, chain=%s, ns=%s\n" % (table, chain, ns)) #self._load(table, chain, ns) if table in self.valid_tables: self.tables[table].show(chain) def vm(self, ip): ''' list vm related rules :param ip: vm ip :return: ''' debug("Try to show vm rules, ip=%s\n" % ip) port_id = get_port_id_from_ip(ip) debug('The port id is %s\n' % port_id) if not port_id: warn('No port id is found for ip=%s\n' % ip) return br_port = find_br_ports(port_id) if not br_port: warn('No br port is found for ip=%s\n' % ip) return output(r('## IP = %s, port = %s\n' % (ip, br_port))) rules_dic = self._query_port_rules(br_port) if rules_dic: output( b(_format_str_iptables_rule_ % ('PKTS', 'IN', 'SOURCE', 'OUT', 'DESTINATION', 'PROT', 'TARGET', 'OTHER'))) for rule in rules_dic: output(b('%s:\n' % rule)) self._fmt_show_rules(rules_dic[rule]) def has_rule(self, table='filter', chain='INPUT', rule_dic=None, ns=None): """ Whether the table/chain has the rule :param table: :param chain: :param rule_dic: :param ns: :return: """ t = self.get_table(table) if not t: return False else: return t.has_rule(chain, rule_dic) pass def get_table(self, table='filter'): ''' Get some table handler of this ipt instance. :param table: :return: the table instance, None if failed ''' return self.tables.get(table, None) def get_chain(self, table='filter', chain='INPUT'): ''' Get some table handler of this ipt instance. :param table: :return: the table instance, None if failed ''' tb = self.tables.get(table, None) if tb: return tb.get_chain(chain) def _get_rules(self, table='filter', chain='INPUT', ns=None): ''' Get the rule list of a given chain :param table: :param chain: :return: [{},{}] ''' ch = self.get_chain(table, chain) if ch: return ch._get_rules() else: return None def _query_port_rules(self, br_port): """ Return the dict of the related security rules on a given port. { 'NAME':[iptables rules], } will load rules first """ results = {} if br_port.startswith('qvo'): # vm port debug('qvo should be vm port\n') #self._load(table='filter') chain_tag = br_port[3:13] i_rules = self._get_rules(chain='neutron-openvswi-i' + chain_tag) out = self._get_rules(chain='neutron-openvswi-o' + chain_tag) filter = self._get_rules(chain='neutron-openvswi-s' + chain_tag) if i_rules: results['IN'] = i_rules if out: results['OUT'] = out if filter: results['SRC_FILTER'] = filter else: # maybe at Network Node debug('Should be network function port\n') ns = self.nss.get_intf_by_name(br_port) if not ns: warn("port %s not in namespaces\n" % br_port) else: output('ns=%s\n' % ns) self._load(table='nat', ns=ns) if br_port.startswith('tap'): # dhcp return None elif br_port.startswith('qr-') or br_port.startswith('qg-'): pre = self._get_rules(table='nat', chain='neutron-l3-agent-PREROUTING') out = self._get_rules(table='nat', chain='neutron-l3-agent-OUTPUT') float_snat = self._get_rules( table='nat', chain='neutron-l3-agent-float-snat') snat = self._get_rules(table='nat', chain='neutron-l3-agent-snat') if pre: results['PRE'] = pre if out: results['OUT'] = out if float_snat: results['FLOAT'] = float_snat if snat: results['SNAT'] = snat return results def _fmt_show_rules(self, rule_list): """ Possible columns: num pkts bytes target prot opt in out source destination flags """ for r in rule_list: r.show()
class DVR(object): """ DVR configuration """ def __init__(self, node='compute'): """ :param node: on computer node or network node """ self.node = node self.br_int = Bridge('br-int') self.nss = NameSpaces() def check(self, _node=None): node = _node or self.node if node in 'compute': output(b('# Checking DVR on compute node\n')) self._check_compute_node() elif node in 'network': output(b('# Checking DVR on network node\n')) self._check_network_node() else: error('Unknown node type=%s, compute or network?\n' % node) def _check_chain_rule_num(self, table, c_name, num): """ Check if the chain has given number of rules. :param table: :param c_name: :param num: :return: """ output(b('Checking chain rule number: %s...' % c_name)) c = table.get_chain(c_name) if len(c.get_rules()) != num: warn(r("Wrong rule number in chain %s\n" % c_name)) return False else: output(g('Passed\n')) return True def _check_chain_has_rule(self, table, c_name, rule): """ :param rule: :return: True or False """ output(b('Checking chain rules: %s...' % c_name)) c = table.get_chain(c_name) if not c.has_rule(rule): warn(r("Defined rule not in %s\n" % c_name)) return False else: output(g('Passed\n')) return True def _check_compute_node_nat_rules(self, qr_intfs, rfp_intfs, nat, ns_fip): """ Check three chains rules match with each other :param nat: the nat table :param ns_fip: :return: True or False """ c_name = 'neutron-l3-agent-PREROUTING' rule = {'in': 'qr-+', 'source': '*', 'out': '*', 'destination': '169.254.169.254', 'target': 'REDIRECT', 'prot': 'tcp', 'flags': 'tcp dpt:80 redir ports 9697'} if not self._check_chain_has_rule(nat, c_name, rule): return False ips_qr = [item for sublist in map(lambda x: x['ip'], qr_intfs) for item in sublist] ips_rfp = [item for sublist in map(lambda x: x['ip'], rfp_intfs) for item in sublist] for intf in rfp_intfs: c_name = 'neutron-l3-agent-PREROUTING' for ip_m in intf['ip'][1:]: # check each floating ip dip = ip_m.split('/')[0] # real floating ip for destination if not ipInNetworks(dip, ips_rfp): warn(r('dip %s not in rfp ports %s\n' % (dip, ips_rfp))) return False rule = nat.get_rule(c_name, {'destination': dip}) sip = rule.get_flags().split(':')[1] if not ipInNetworks(sip, ips_qr): warn(r('sip %s not in qr port %s\n' % (sip, ips_qr))) return False rule_expect = {'in': '*', 'source': '*', 'out': '*', 'destination': dip, 'target': 'DNAT', 'prot': '*', 'flags': 'to:'+sip} if not rule.is_match(rule_expect): warn(r('rule not matched in %s\n' % (c_name))) return False if not self._check_chain_has_rule(nat, 'neutron-l3-agent-OUTPUT', rule_expect): return False else: output(g('DNAT for incomping: %s --> %s passed\n' % (dip, sip))) rule_expect = {'in': '*', 'source': sip, 'out': '*', 'destination': '*', 'target': 'SNAT', 'prot': '*', 'flags': 'to:'+dip} if not self._check_chain_has_rule( nat, 'neutron-l3-agent-float-snat', rule_expect): return False else: output(g('SNAT for outgoing: %s --> %s passed\n' % (sip, dip))) return True def _check_compute_node_nat_table(self, ns_q, ns_fip): """ Check the snat rules in the given ns :param ns_q: :param ns_fip: :return: """ ipt = IPtables(ns_q) nat = ipt.get_table(table='nat') chains = [ 'neutron-postrouting-bottom', 'neutron-l3-agent-OUTPUT', 'POSTROUTING', 'neutron-l3-agent-PREROUTING', 'PREROUTING', 'neutron-l3-agent-float-snat', 'OUTPUT', 'INPUT', 'neutron-l3-agent-POSTROUTING', 'neutron-l3-agent-snat', ] for c_name in chains: c = nat.get_chain(c_name) if not c: warn(r("Not found chain %s\n" % c_name)) return False if c.get_policy() != 'ACCEPT': warn(r("Chain %s's policy is not ACCEPT\n" % c.name)) for c_name in ['neutron-postrouting-bottom', 'OUTPUT', 'neutron-l3-agent-snat']: if not self._check_chain_rule_num(nat, c_name, 1): return False c_name = 'neutron-postrouting-bottom' rule = {'in': '*', 'source': '*', 'out': '*', 'destination': '*', 'target': 'neutron-l3-agent-snat', 'prot': '*'} if not self._check_chain_has_rule(nat, c_name, rule): return False c_name = 'PREROUTING' rule = {'in': '*', 'source': '*', 'out': '*', 'destination': '*', 'target': 'neutron-l3-agent-PREROUTING', 'prot': '*'} if not self._check_chain_has_rule(nat, c_name, rule): return False c_name = 'OUTPUT' rule = {'in': '*', 'source': '*', 'out': '*', 'destination': '*', 'target': 'neutron-l3-agent-OUTPUT', 'prot': '*'} if not self._check_chain_has_rule(nat, c_name, rule): return False c_name = 'POSTROUTING' rule = {'in': '*', 'source': '*', 'out': '*', 'destination': '*', 'target': 'neutron-l3-agent-POSTROUTING', 'prot': '*'} if not self._check_chain_has_rule(nat, c_name, rule): return False rule = {'in': '*', 'source': '*', 'out': '*', 'destination': '*', 'target': 'neutron-postrouting-bottom', 'prot': '*'} if not self._check_chain_has_rule(nat, c_name, rule): return False c_name = 'neutron-l3-agent-POSTROUTING' rfp_intfs = NameSpace(ns_q).find_intfs('rfp-') for intf in rfp_intfs: rule = {'in': '!'+intf['intf'], 'source': '*', 'out': '!'+intf['intf'], 'destination': '*', 'target': 'ACCEPT', 'prot': '*', 'flags': '! ctstate DNAT'} if not self._check_chain_has_rule(nat, c_name, rule): return False qr_intfs = NameSpace(ns_q).find_intfs('qr-') if not self._check_compute_node_nat_rules(qr_intfs, rfp_intfs, nat, ns_fip): return False return True def _check_compute_node_snat_ns(self, ns_router): """ Check the local router namespace on compute node :param ns_router: :return: list of the fip ns """ if not ns_router: return self.nss.show(ns_router) intfs = NameSpace(ns_router).get_intfs() rfp_ports = [] # list of {'intf':eth0, 'ip':[]} for i in intfs: # check each intf in this ns p = intfs[i]['intf'] if p.startswith('rfp-'): # rfp port in q connect to fpr in fip rfp_ports.append(p) output(b('### Checking rfp port %s\n' % p)) if len(intfs[i]['ip']) < 2: warn(r('Missing ips for port %s\n' % p)) continue else: output(g('Found associated floating ips : %s\n' % ', '.join(intfs[i]['ip'][1:]))) ns_fip = self.nss.get_intf_by_name('fpr-'+intfs[i]['intf'][4:]) if not ns_fip: warn(r('Cannot find fip ns for %s\n' % q)) return self._check_compute_node_fip_ns(intfs[i], ns_fip) self._check_compute_node_nat_table(ns_router, ns_fip) if not rfp_ports: warn(r('Cannot find rfp port in ns %s\n' % ns_router)) elif len(rfp_ports) > 1: warn(r('More than 1 rfp ports in ns %s\n' % ns_router)) def _check_compute_node_fip_ns(self, rfp_port, ns_fip): """ Check a fip namespace on compute node :param rfp_port: :return: """ q = 'fpr-'+rfp_port['intf'][4:] output(b('### Checking associated fpr port %s\n' % q)) self.nss.show(ns_fip) output(b('### Check related fip_ns=%s\n' % ns_fip)) fpr_port = NameSpace(ns_fip).get_intf_by_name(q) if not fpr_port: warn(r('Cannot find fpr_port in fip ns %s\n' % ns_fip)) return a_ip, a_mask = rfp_port['ip'][0].split('/') b_ip, b_mask = fpr_port['ip'][0].split('/') if networkMask(a_ip, a_mask) != networkMask(b_ip, b_mask): warn(r('Different subnets for %s and %s\n' % (rfp_port['ip'][0], fpr_port['ip'][0]))) return else: output(g('Bridging in the same subnet\n')) fg_port = NameSpace(ns_fip).find_intf('fg-') if not fg_port: warn('Cannot find fg_port in fip ns %s\n' % ns_fip) return if fg_port['intf'] in Bridge('br-ex').get_ports(): output(g('fg port is attached to br-ex\n')) else: warn(g('fg port is NOT attached to br-ex\n')) return for float_ip in rfp_port['ip'][1:]: ip = float_ip.split('/')[0] if ipInNetwork(ip, fg_port['ip'][0]): output(g('floating ip %s match fg subnet\n' % ip)) else: warn(r('floating ip %s No match the fg subnet' % ip)) def _check_compute_node(self): """ Check the qrouter-*** fip-*** spaces in the compute node. :return: """ checked_ns = [] for port in self.br_int.get_ports(): if port.startswith('qr-'): # qrouter port output(b('## Checking router port = %s\n' % port)) nsrouter = self.nss.get_intf_by_name(port) if nsrouter in checked_ns: output(g('Checking passed already\n')) continue else: checked_ns.append(nsrouter) # the names of the ns checked self._check_compute_node_snat_ns(nsrouter) pass pass def _check_network_node(self): """ Check the qrouter-*** fip-*** snat-*** spaces in the network node. :return: """ pass