Пример #1
0
    def _network_check_processes(self):
        """
        Check related configuration files
        :return: True if no warning
        """
        output(b('>>> Checking processes...\n'))
        warns = False
        cmd = "ps aux|grep neutron|grep python"
        result, err = \
            Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True).communicate()
        if err:
            return []

        for p in [
            'neutron-server',
            'neutron-dhcp-agent',
            'neutron-metadata-agent',
            'neutron-openvswitch-agent',
            'neutron-l3-agent',
            #'neutron-ns-metadata-proxy',
            ]:
            if p not in result:
                warn(r('%s service is not running\n' % p))
                warns = True

        if not warns:
            output(g('<<< Checking processes passed\n'))
            return True
        else:
            warn(r('<<< Checking processes has warnings\n'))
            return False
Пример #2
0
 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])
Пример #3
0
    def _load(self, test_content=None):
        if not test_content:  # test_content is null
            run_cmd = '%s exec %s ip a' % (self.ns_cmd, self.id)
            content, err = Popen(run_cmd, stdout=PIPE, stderr=PIPE,
                                 shell=True).communicate()
            if err:
                error("Failed to run %s, err=%s\n" % (run_cmd, err))
                return
        else:
            content = test_content

        lines = content.split('\n')
        intfs = {}  #  {'1':{'intf': eth0, 'ip': [ip1, ip2]}, 'mac': xxx }
        for l in lines:
            if not l:
                continue
            if not l.startswith(' '):  # one interface: 1: lo: xxxxx
                intf_line = l.split(':')
                if len(intf_line) < 2:
                    warn('Seems the interface line too short\n')
                    continue
                else:
                    id = intf_line[0].strip()
                    intf = intf_line[1].strip()
                    intfs[id] = {'intf': intf, 'ip': [], 'mac': '*'}
            else:  # some content line
                cons = l.split()
                if len(cons) < 2:
                    continue
                if cons[0] == 'inet':
                    intfs[id]['ip'].append(cons[1])
                elif cons[0] == 'link/ether':
                    intfs[id]['mac'] = cons[1]
        self.intfs = intfs
Пример #4
0
 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])
Пример #5
0
    def _load(self, test_content=None):
        if not test_content: # test_content is null
            run_cmd = '%s exec %s ip a' % (self.ns_cmd, self.id)
            content, err = Popen(run_cmd, stdout=PIPE, stderr=PIPE,
                                 shell=True).communicate()
            if err:
                error("Failed to run %s, err=%s\n" % (run_cmd, err))
                return
        else:
            content = test_content

        lines = content.split('\n')
        intfs = {}  #  {'1':{'intf': eth0, 'ip': [ip1, ip2]}, 'mac': xxx }
        for l in lines:
            if not l:
                continue
            if not l.startswith(' '):  # one interface: 1: lo: xxxxx
                intf_line = l.split(':')
                if len(intf_line) < 2:
                    warn('Seems the interface line too short\n')
                    continue
                else:
                    id = intf_line[0].strip()
                    intf = intf_line[1].strip()
                    intfs[id] = {'intf': intf, 'ip': [], 'mac': '*' }
            else:  # some content line
                cons = l.split()
                if len(cons) < 2:
                    continue
                if cons[0] == 'inet':
                    intfs[id]['ip'].append(cons[1])
                elif cons[0] == 'link/ether':
                    intfs[id]['mac'] = cons[1]
        self.intfs = intfs
Пример #6
0
 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
     output(color_str('## IP = %s, port = %s\n' % (ip, port_id), 'r'))
     br_port = find_br_ports(port_id)
     if not br_port:
         warn('No br port is found for ip=%s\n' % ip)
         return
     debug('The br port is %s\n' % br_port)
     rules_dic = self._query_port_rules(br_port)
     if rules_dic:
         output(color_str( _format_str_iptables_rule_ % (
             'PKTS', 'SOURCE', 'DESTINATION', 'PROT', 'OTHER'), 'b'))
         for r in rules_dic:
             if rules_dic[r]:
                 output('%s:\n' % r)
                 self._fmt_show_rules(rules_dic[r])
Пример #7
0
 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
Пример #8
0
 def route(self, id_pattern):
     """
     Show routes of a namespace whose id matched
     :param id_pattern: id pattern to match
     :return: N/A
     """
     ns_list = self.get_ids()
     if not ns_list:
         warn('No namespace exists\n')
         return
     for s in ns_list:
         if id_pattern in s:
             NameSpace(s).show_routes()
Пример #9
0
 def route(self, id_pattern):
     """
     Show routes of a namespace whose id matched
     :param id_pattern: id pattern to match
     :return: N/A
     """
     ns_list = self.get_ids()
     if not ns_list:
         warn('No namespace exists\n')
         return
     for s in ns_list:
         if id_pattern in s:
             NameSpace(s).show_routes()
Пример #10
0
    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
Пример #11
0
 def show(self, id_pattern):
     """
     Show the content of specific id or id_pattern
     :param id_pattern: id of namespace to show
     :return:
     """
     ns_list = self.get_ids()
     if not ns_list:
         warn('No namespace exists\n')
         return
     for s in ns_list:
         if id_pattern in s:
             NameSpace(s).show()
             return
Пример #12
0
 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))
Пример #13
0
 def _network_check_router_ns(self, ns_router):
     """
     Check the local router namespace on compute node
     :param ns_router:
     :return: list of the fip ns
     """
     output(b('### Checking router ns = %s\n' % ns_router))
     if not ns_router:
         return False
     intfs = NameSpace(ns_router).get_intfs()
     r_ports = []  # list of {'intf':eth0, 'ip':[]}
     for i in intfs:  # check each intf in this ns
         p = intfs[i]['intf']
         if p == 'lo':  # ignore the lo port
             continue
         elif not p.startswith('qr-'):  # no router port?
             warn(r('Invalid port %s in %s\n' % (p, ns_router)))
             return False
         else:
             output(b('### Checking port %s\n' % p))
             r_ports.append(p)
             if not intfs[i]['ip']:
                 warn(r('No ip with port %s in %s\n' % (p, ns_router)))
                 return False
             else:
                 for ip_m in intfs[i]['ip']:
                     ip, mask = ip_m.split('/')
                     if ipStrToNum(ip) != networkMask(ip_m) + 1:
                         warn(r('IP %s is not gw on port %s\n' % (ip_m,
                                                               ns_router)))
                         return False
     if not r_ports:
         warn(r('Cannot find router port in ns %s\n' % ns_router))
         return False
     return True
Пример #14
0
 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
Пример #15
0
 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))
Пример #16
0
 def do_dvr(self, arg):
     """
     Check the dvr rules
     dvr [check]
     dvr check compute
     dvr check net
     """
     args = arg.split()
     if len(args) > 2:  # only 1 is valid
         warn("Not correct parameters, use as:\n")
         warn("dvr [check]\n")
         warn("dvr check compute\n")
         warn("dvr check net\n")
         return
     if len(args) == 0:  # default cmd for ns
         args.insert(0, 'check')
     cmd = args[0]
     if not hasattr(self.dvr, '%s' % cmd):
         error('Unsupported cmd=%s\n' % cmd)
         return
     if cmd == 'check':
         if len(args) == 1:  # only check cmd is given
             debug('run self.dvr.%s()\n' % cmd)
             getattr(self.dvr, '%s' % cmd)()
         else:  # node parameter is given
             debug('run self.dvr.%s(%s)\n' % (cmd, args[1]))
             getattr(self.dvr, '%s' % cmd)(args[1])
Пример #17
0
 def show(self, id_pattern):
     """
     Show the content of specific id or id_pattern
     :param id_pattern: id of namespace to show
     :return:
     """
     ns_list = self.get_ids()
     if not ns_list:
         warn('No namespace exists\n')
         return
     for s in ns_list:
         if id_pattern in s:
             NameSpace(s).show()
             return
Пример #18
0
    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 %s not in %s\n" % (rule, c_name)))
            return False
        else:
            output(g('Passed\n'))
            return True
Пример #19
0
 def do_dvr(self, arg):
     """
     Check the dvr rules
     dvr [check]
     dvr check compute
     dvr check net
     """
     args = arg.split()
     if len(args) > 2:  # only 1 is valid
         warn("Not correct parameters, use as:\n")
         warn("dvr [check]\n")
         warn("dvr check compute\n")
         warn("dvr check net\n")
         return
     self.dvr = DVR()
     if len(args) == 0:  # default cmd for ns
         args.insert(0, 'check')
     cmd = args[0]
     if not hasattr(self.dvr, '%s' % cmd):
         error('Unsupported cmd=%s\n' % cmd)
         return
     if cmd == 'check':
         if len(args) == 1:  # only check cmd is given
             debug('run self.dvr.%s()\n' % cmd)
             getattr(self.dvr, '%s' % cmd)()
         else:  # node parameter is given
             debug('run self.dvr.%s(%s)\n' % (cmd, args[1]))
             getattr(self.dvr, '%s' % cmd)(args[1])
Пример #20
0
 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
Пример #21
0
 def _check_chain_rule_num(self, table, c_name, num):
     """
     Check if the chain has given number of rules.
     :param table: table object
     :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
Пример #22
0
    def list(self):
        """
        List existing namespaces in the system
        :return:
        """
        ns_list = self.get_ids()
        if not ns_list:
            warn('No namespace exists\n')
            return

        output(color_str('%d namespaces:\n ' % len(ns_list), 'b'))
        ns_list_valid = filter(lambda x: not NameSpace(x).is_empty(), ns_list)
        ns_list_empty = filter(lambda x: NameSpace(x).is_empty(), ns_list)
        if ns_list_valid:
            output(color_str('%s\n' % '\t'.join(ns_list), 'b'))
        if ns_list_empty:
            output('%s\n' % '\t'.join(ns_list))
Пример #23
0
    def list(self):
        """
        List existing namespaces in the system
        :return:
        """
        ns_list = self.get_ids()
        if not ns_list:
            warn('No namespace exists\n')
            return

        output(color_str('%d namespaces:\n ' % len(ns_list), 'b'))
        ns_list_valid = filter(lambda x: not NameSpace(x).is_empty(), ns_list)
        ns_list_empty = filter(lambda x: NameSpace(x).is_empty(), ns_list)
        if ns_list_valid:
            output(color_str('%s\n' % '\t'.join(ns_list), 'b'))
        if ns_list_empty:
            output('%s\n' % '\t'.join(ns_list))
Пример #24
0
 def __init__(self):
     config.init(sys.argv[1:])
     try:
         self.keystone = ksclient.Client(auth_url=cfg.CONF.OS.auth_url,
                                tenant_name=cfg.CONF.OS.tenant_name,
                                username=cfg.CONF.OS.username,
                                password=cfg.CONF.OS.password)
         self.token = self.keystone.auth_token
         neutron_endpoint_url = self.keystone.service_catalog.url_for(
             service_type='network')
         self.neutron = neutronclient.Client(endpoint_url=neutron_endpoint_url,
                                         token=self.token)
     except AuthorizationFailure:
         warn("OpenStack Authorization Failed\n")
         self.neutron = None
     except Unauthorized:
         warn("No valid OpenStack authentication information is found\n")
         self.neutron = None
Пример #25
0
 def check(self, _node=None):
     guess = 'compute'
     for ns_id in NameSpaces().get_ids():
         if ns_id.startswith('snat-'):  # only network has snat-*
             guess = 'network'
             break
     if not _node:
         output(b('# No node type given, guessing...%s node\n' % guess))
     else:  # given _node, will check if match
         if _node not in guess:
             warn(r('# Given node type=%s not match the server\n' % _node))
             guess = _node
     node = guess
     if node in 'compute':
         return self._compute_node_check()
     elif node in 'network':
         return self._network_node_check()
     else:
         error('Unknown node type=%s, compute or network?\n' % node)
Пример #26
0
 def __init__(self):
     config.init(sys.argv[1:])
     try:
         self.keystone = ksclient.Client(
             auth_url=cfg.CONF.OS.auth_url,
             tenant_name=cfg.CONF.OS.tenant_name,
             username=cfg.CONF.OS.username,
             password=cfg.CONF.OS.password)
         self.token = self.keystone.auth_token
         neutron_endpoint_url = self.keystone.service_catalog.url_for(
             service_type='network')
         self.neutron = neutronclient.Client(
             endpoint_url=neutron_endpoint_url, token=self.token)
     except AuthorizationFailure:
         warn("OpenStack Authorization Failed\n")
         self.neutron = None
     except Unauthorized:
         warn("No valid OpenStack authentication information is found\n")
         self.neutron = None
Пример #27
0
 def _search_ns(self, pattern):
     """
     Find a namespace which have the pattern
     :param pattern: pattern to search
     :return: The id of the matched ns
     """
     ns_list = self.get_ids()
     if not ns_list:
         return None
     for ns in ns_list:  # qrouter-03266ec4-a03b-41b2-897b-c18ae3279933
         run_cmd = '%s exec %s ip addr | grep %s' % (self.ns_cmd, ns,
                                                     pattern)
         result, err = Popen(run_cmd, stdout=PIPE, stderr=PIPE,
                             shell=True) .communicate()
         if err:
             warn("Failed to run %s, err=%s\n" % (run_cmd, err))
             continue
         if result:
             return ns
     return None
Пример #28
0
 def _search_ns(self, pattern):
     """
     Find a namespace which have the pattern
     :param pattern: pattern to search
     :return: The id of the matched ns
     """
     ns_list = self.get_ids()
     if not ns_list:
         return None
     for ns in ns_list:  # qrouter-03266ec4-a03b-41b2-897b-c18ae3279933
         run_cmd = '%s exec %s ip addr | grep %s' % (self.ns_cmd, ns,
                                                     pattern)
         result, err = Popen(run_cmd, stdout=PIPE, stderr=PIPE,
                             shell=True).communicate()
         if err:
             warn("Failed to run %s, err=%s\n" % (run_cmd, err))
             continue
         if result:
             return ns
     return None
Пример #29
0
 def _compute_node_check(self):
     """
     Check the qrouter-***  fip-*** spaces in the compute node.
     :return:
     """
     output(b('=== Checking DVR on compute node ===\n'))
     flag = True
     if not self._compute_check_config_files():
         flag = False
     output('\n')
     if not self._compute_check_bridges():
         flag = False
     output('\n')
     if not self._compute_check_vports():
         flag = False
     if flag:
         output(g('=== PASSED Checking DVR on compute node ===\n'))
     else:
         warn(r('=== FAILED Checking DVR on compute node ===\n'))
     return flag
Пример #30
0
 def do_ipt(self, arg):
     """
     Show the iptables rules, e.g.,
     ipt vm vm1,vm2
     ipt show nat,raw,filter [INPUT]
     ipt check nat,raw,filter
     """
     args = arg.split()
     if len(args) < 1 or len(args) > 3:  # only 1-3 is valid
         warn("Not correct parameters, use as:\n")
         warn("ipt vm vm_ip\n")
         warn("ipt show|check [filter] [INPUT]\n")
         return
     cmd = args[0]
     if not hasattr(self.ipt, '%s' % cmd):
         error('Unsupported cmd=%s\n' % cmd)
         return
     if cmd == 'vm':
         if len(args) == 1:
             error('No vm ip is given\n')
             return
         else:
             for vm_ip in args[1:]:
                 debug('run self.ipt.%s(%s)\n' % (cmd, vm_ip))
                 getattr(self.ipt, '%s' % cmd)(vm_ip)
     elif cmd in ['check', 'show']:
         ns = None
         if args[-1] in NameSpaces().get_ids():
             ns = args.pop()
         if len(args) == 1:  # show
             debug('run self.ipt.%s(ns=%s)\n' % (cmd, ns))
             getattr(self.ipt, '%s' % cmd)(ns=ns)
             return
         elif len(args) == 2:  # filter|INPUT
             if args[1] in self.ipt.get_valid_tables():  # filter
                 debug('run self.ipt.%s(table=%s,ns=%s)\n' %
                       (cmd, args[1], ns))
                 getattr(self.ipt, '%s' % cmd)(table=args[1], ns=ns)
             else:  # INPUT
                 debug('run self.ipt.%s(chain=%s, ns=%s)\n' %
                       (cmd, args[1], ns))
                 getattr(self.ipt, '%s' % cmd)(chain=args[1], ns=ns)
         elif len(args) == 3:
             if args[1] in self.ipt.get_valid_tables():  # filter INPUT
                 debug('run self.ipt.%s(table=%s, chain=%s, ns=%s\n)' %
                       (cmd, args[1], args[2], ns))
                 getattr(self.ipt, '%s' % cmd)(table=args[1],
                                               chain=args[2],
                                               ns=ns)
             else:
                 warn("Unknown table, table=%s\n" % args[1])
Пример #31
0
 def do_ipt(self, arg):
     """
     Show the iptables rules, e.g.,
     ipt vm vm1,vm2
     ipt show nat,raw,filter [INPUT]
     ipt check nat,raw,filter
     """
     args = arg.split()
     if len(args) < 1 or len(args) > 3:  # only 1-3 is valid
         warn("Not correct parameters, use as:\n")
         warn("ipt vm vm_ip\n")
         warn("ipt show|check [filter] [INPUT]\n")
         return
     self.ipt = IPtables()
     cmd = args[0]
     if not hasattr(self.ipt, '%s' % cmd):
         error('Unsupported cmd=%s\n' % cmd)
         return
     if cmd == 'vm':
         if len(args) == 1:
             error('No vm ip is given\n')
             return
         else:
             for vm_ip in args[1:]:
                 debug('run self.ipt.%s(%s)\n' % (cmd, vm_ip))
                 getattr(self.ipt, '%s' % cmd)(vm_ip)
     elif cmd in ['check', 'show']:
         ns = None
         if args[-1] in NameSpaces().get_ids():
             ns = args.pop()
         if len(args) == 1:  # show
             debug('run self.ipt.%s(ns=%s)\n' % (cmd, ns))
             getattr(self.ipt, '%s' % cmd)(ns=ns)
             return
         elif len(args) == 2:  # filter|INPUT
             if args[1] in self.ipt.get_valid_tables():  # filter
                 debug('run self.ipt.%s(table=%s,ns=%s)\n' % (cmd,
                                                              args[1], ns))
                 getattr(self.ipt, '%s' % cmd)(table=args[1], ns=ns)
             else:  # INPUT
                 debug('run self.ipt.%s(chain=%s, ns=%s)\n'
                       % (cmd, args[1], ns))
                 getattr(self.ipt, '%s' % cmd)(chain=args[1], ns=ns)
         elif len(args) == 3:
             if args[1] in self.ipt.get_valid_tables():  # filter INPUT
                 debug('run self.ipt.%s(table=%s, chain=%s, ns=%s\n)'
                       % (cmd, args[1], args[2], ns))
                 getattr(self.ipt, '%s' % cmd)(table=args[1],
                                               chain=args[2], ns=ns)
             else:
                 warn("Unknown table, table=%s\n" % args[1])
Пример #32
0
 def _compute_check_vports(self):
     """
     Check the vport related information and rules
     :return:
     """
     checked_ns = []
     output(b('>>> Checking vports ...\n'))
     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_ns_by_port(port)
             if nsrouter in checked_ns:
                 output(g('Checking passed already\n'))
                 continue
             else:
                 checked_ns.append(nsrouter)  # the names of the ns checked
                 if not self._compute_check_router_ns(nsrouter):
                     warn(r('<<< Checking vports failed\n'))
                     return False
     output(b('<<< Checking vports passed\n'))
     return True
Пример #33
0
def fileHasLine(file, line):
    """
    Test if the file content has the line, will ignore the space among it
    :param file:
    :param line:
    :return:
    """
    try:
        f = open(file, "r")
    except IOError:
        warn(r("Cannot open file", file))
        return False
    line = line.replace(" ", "")
    while True:
        lines = f.readlines(1000)
        lines = map(lambda x: x.strip("\n").replace(" ", ""), lines)
        if not lines:
            break
        for _line in lines:
            if _line == line:
                return True
    return False
Пример #34
0
 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))
Пример #35
0
    def _compute_check_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 incoming: %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
Пример #36
0
 def __init__(self):
     config.init(sys.argv[1:])
     username = os.getenv('OS_USERNAME') or cfg.CONF.OS.username or None
     password = os.getenv('OS_PASSWORD') or cfg.CONF.OS.password or None
     tenant_name = \
         os.getenv('OS_TENANT_NAME') or cfg.CONF.OS.tenant_name or None
     auth_url = os.getenv('OS_AUTH_URL') or cfg.CONF.OS.auth_url or None
     try:
         self.keystone = ksclient.Client(auth_url=auth_url,
                                         tenant_name=tenant_name,
                                         username=username,
                                         password=password)
         self.token = self.keystone.auth_token
         neutron_endpoint_url = self.keystone.service_catalog.url_for(
             service_type='network')
         self.neutron = neutronclient.Client(
             endpoint_url=neutron_endpoint_url, token=self.token)
     except AuthorizationFailure:
         warn("OpenStack auth not loaded\n")
         self.neutron = None
     except Unauthorized:
         warn("No valid OpenStack auth info is found\n")
         self.neutron = None
Пример #37
0
 def _compute_check_fip_ns(self, rfp_port, ns_fip):
     """
     Check a fip namespace on compute node
     :param rfp_port:
     :return: True or False
     """
     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 False
     if networkMask(rfp_port['ip'][0]) != networkMask(fpr_port['ip'][0]):
         warn(r('Different subnets for %s and %s\n'
              % (rfp_port['ip'][0], fpr_port['ip'][0])))
         return False
     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 False
     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 False
     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))
             return False
     return True
Пример #38
0
 def _network_check_vports(self):
     """
     Check the vport related information and rules
     :return:
     """
     checked_ns = []
     output(b('>>> Checking vports ...\n'))
     qr_ports, dhcp_ports, sg_ports = [], [], []
     qr_ports_ips = []
     br_ports = self.br_int.get_ports()
     for port in br_ports:
         if port.startswith('qr-'):  # qrouter port
             qr_ports.append(port)
         elif port.startswith('tap'):  # qrouter port
             dhcp_ports.append(port)
         elif port.startswith('sg-'):  # qrouter port
             sg_ports.append(port)
     if not qr_ports:
         output('# no qrouter port found\n')
     if not dhcp_ports:
         output('# no dhcp port found\n')
     if not sg_ports:
         output('# no sg port found\n')
     for port in qr_ports:
         output(b('## Checking router port = %s\n' % port))
         ns_router = self.nss.get_ns_by_port(port)
         if ns_router in checked_ns:
             output(g('Checking passed already\n'))
         else:
             checked_ns.append(ns_router)  # the names of the ns checked
             if not self._network_check_router_ns(ns_router):
                 warn(r('<<< Checking vports failed\n'))
                 return False
         qr_ports_ips.extend(NameSpace(ns_router).get_ip_of_intf(
             port))
     for port in dhcp_ports:
         output(b('## Checking dhcp port = %s\n' % port))
         ns_dhcp = self.nss.get_ns_by_port(port)
         if ns_dhcp in checked_ns:
             output(g('Checking passed already\n'))
         else:
             checked_ns.append(ns_dhcp)  # the names of the ns checked
             if not self._network_check_dhcp_ns(ns_dhcp):
                 warn(r('<<< Checking vports failed\n'))
                 return False
     for port in sg_ports:  # snat port
         output(b('## Checking sg port = %s\n' % port))
         ns_snat = self.nss.get_ns_by_port(port)
         if ns_snat in checked_ns:
             output(g('Checking passed already\n'))
         else:
             checked_ns.append(ns_snat)  # the names of the ns checked
             if not self._network_check_snat_ns(ns_snat, qr_ports_ips):
                 warn(r('<<< Checking vports failed\n'))
                 return False
     output(g('<<< Checking vports passed\n'))
     return True
Пример #39
0
 def do_ns(self, arg):
     """
     Show the network namespace content, e.g.,
     ns list
     ns show id_prefix
     ns find pattern
     """
     args = arg.split()
     if len(args) > 2:  # only 1-2 is valid
         warn("Not correct parameters, use as:\n")
         warn("ns [list]\n")
         warn("ns show id_prefix (lo intf is ignored)\n")
         warn("ns find pattern\n")
         return
     self.nss = NameSpaces()
     if len(args) == 0:  # default cmd for ns
         args.insert(0, 'list')
     cmd = args[0]
     if not hasattr(self.nss, '%s' % cmd):
         error('Unsupported cmd=%s\n' % cmd)
         return
     if cmd in ['list', 'clean']:
         if len(args) != 1:
             error('No param should be given\n')
             return
         else:
             debug('run self.nss.%s()\n' % cmd)
             getattr(self.nss, '%s' % cmd)()
     elif cmd in ['show', 'find', 'route']:
         if len(args) == 2:  #
             debug('run self.nss.%s(%s)\n' % (cmd, args[1]))
             getattr(self.nss, '%s' % cmd)(args[1])
         else:
             warn("Invalid param number, no reach here, %s\n" % arg)
             return
     else:
         error("Unknown cmd, cmd= %s\n" % arg)
Пример #40
0
 def do_ns(self, arg):
     """
     Show the network namespace content, e.g.,
     ns list
     ns show id_prefix
     ns find pattern
     """
     args = arg.split()
     if len(args) > 2:  # only 1-2 is valid
         warn("Not correct parameters, use as:\n")
         warn("ns [list]\n")
         warn("ns show id_prefix (lo intf is ignored)\n")
         warn("ns find pattern\n")
         return
     if len(args) == 0:  # default cmd for ns
         args.insert(0, 'list')
     cmd = args[0]
     if not hasattr(self.nss, '%s' % cmd):
         error('Unsupported cmd=%s\n' % cmd)
         return
     if cmd == 'list':
         if len(args) != 1:
             error('No param should be given\n')
             return
         else:
             debug('run self.nss.%s(...)\n' % cmd)
             getattr(self.nss, '%s' % cmd)()
     elif cmd in ['show', 'find', 'route']:
         if len(args) == 2:  #
             debug('run self.nss.%s(%s)\n' % (cmd, args[1]))
             getattr(self.nss, '%s' % cmd)(args[1])
         else:
             warn("Invalid param number, no reach here, %s\n" % arg)
             return
     else:
         error("Unknown cmd, cmd= %s\n" % arg)
Пример #41
0
 def __init__(self):
     config.init(sys.argv[1:])
     username = os.getenv('OS_USERNAME') or cfg.CONF.OS.username or None
     password = os.getenv('OS_PASSWORD') or cfg.CONF.OS.password or None
     tenant_name = \
         os.getenv('OS_TENANT_NAME') or cfg.CONF.OS.tenant_name or None
     auth_url = os.getenv('OS_AUTH_URL') or cfg.CONF.OS.auth_url or None
     try:
         self.keystone = ksclient.Client(auth_url=auth_url,
                                         tenant_name=tenant_name,
                                         username=username,
                                         password=password)
         self.token = self.keystone.auth_token
         neutron_endpoint_url = self.keystone.service_catalog.url_for(
             service_type='network')
         self.neutron = neutronclient.Client(
             endpoint_url=neutron_endpoint_url,
             token=self.token)
     except AuthorizationFailure:
         warn("OpenStack auth not loaded\n")
         self.neutron = None
     except Unauthorized:
         warn("No valid OpenStack auth info is found\n")
         self.neutron = None
Пример #42
0
 def do_ns(self, arg):
     """
     Show the network namespace content, e.g.,
     ns list
     ns show id_prefix
     ns find pattern
     """
     args = arg.split()
     if len(args) > 2:  # only 1-2 is valid
         warn("Not correct parameters, use as:\n")
         warn("ns [list]\n")
         warn("ns show id_prefix (lo intf is ignored)\n")
         warn("ns find pattern\n")
         return
     if len(args) == 0:  # default cmd for ns
         args.insert(0, "list")
     cmd = args[0]
     if not hasattr(self.nss, "%s" % cmd):
         error("Unsupported cmd=%s\n" % cmd)
         return
     if cmd == "list":
         if len(args) != 1:
             error("No param should be given\n")
             return
         else:
             debug("run self.nss.%s(...)\n" % cmd)
             getattr(self.nss, "%s" % cmd)()
     elif cmd in ["show", "find", "route"]:
         if len(args) == 2:  #
             debug("run self.nss.%s(%s)\n" % (cmd, args[1]))
             getattr(self.nss, "%s" % cmd)(args[1])
         else:
             warn("Invalid param number, no reach here, %s\n" % arg)
             return
     else:
         error("Unknown cmd, cmd= %s\n" % arg)
Пример #43
0
    def _network_check_snat_ns(self, ns_snat, qr_ports_ips):
        """
        Check the local router namespace on compute node
        :param ns_snat:
        :return: list of the fip ns
        """
        output(b('### Checking snat ns = %s\n' % ns_snat))
        if not ns_snat:
            return False
        intfs = NameSpace(ns_snat).get_intfs()
        sg_ports, qg_ports = [], []
        sg_ports_ips = []
        for i in intfs:  # check each intf in this ns
            p = intfs[i]['intf']
            if p == 'lo':  # ignore the lo port
                continue
            elif p.startswith('sg-'):  # no router port?
                sg_ports.append(p)
                sg_ports_ips.extend(intfs[i]['ip'])
            elif p.startswith('qg-'):  # no router port?
                qg_ports.append(p)

        if set(map(lambda x: networkMask(x), sg_ports_ips)) != \
                set(map(lambda x: networkMask(x), qr_ports_ips)):
            warn(r('qrouter ports not matched with sg ports\n'))
            return False

        if not sg_ports:
            warn(r('Cannot find sg port in ns %s\n' % ns_snat))
            return False
        if not qg_ports:
            warn(r('Cannot find qg port in ns %s\n' % ns_snat))
            return False
        if not self._network_check_nat_table(ns_snat):
            warn(r('Checking snat ns %s nat table failed\n' % ns_snat))
            return False
        return True
Пример #44
0
    def _network_check_nat_table(self, ns_snat):
        ipt = IPtables(ns_snat)
        nat = ipt.get_table(table='nat')
        qg_intfs = NameSpace(ns_snat).find_intfs('qg-')
        chains = [
            'PREROUTING',
            'INPUT',
            'OUTPUT',
            'POSTROUTING',
            'neutron-l3-agent-OUTPUT',
            'neutron-l3-agent-PREROUTING',
            'neutron-l3-agent-POSTROUTING',
            'neutron-l3-agent-float-snat',
            'neutron-l3-agent-snat',
            'neutron-postrouting-bottom',
        ]
        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 ['PREROUTING', 'neutron-postrouting-bottom',
                       'OUTPUT']:
            if not self._check_chain_rule_num(nat, c_name, 1):
                warn(r("Chain %s's size mismatch\n" % c_name))
                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):
            warn(r("Chain %s's rule failed\n" % c_name))
            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):
            warn(r("Chain %s's rule failed\n" % c_name))
            return False
        rule = {'in': '*', 'source': '*', 'out': '*', 'destination': '*',
                'target': 'neutron-postrouting-bottom', 'prot': '*'}
        if not self._check_chain_has_rule(nat, c_name, rule):
            warn(r("Chain %s's rule failed\n" % c_name))
            return False

        c_name = 'neutron-l3-agent-POSTROUTING'
        for intf in qg_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):
                warn(r("Chain %s's rule failed\n" % c_name))
                return False

        c_name = 'neutron-l3-agent-snat'
        for intf in qg_intfs:
            for ip_m in intf['ip']:
                ip = ip_m.split('/')[0]
                rule = {'in': '*', 'source': '*', 'out': intf['intf'],
                        'destination': '*', 'target': 'SNAT', 'prot': '*',
                        'flags': 'to:'+ip}
                if not self._check_chain_has_rule(nat, c_name, rule):
                    warn(r("Chain %s's rule failed\n" % c_name))
                    return False
                rule = {'in': '*', 'source': '*', 'out': '*',
                        'destination': '*', 'target': 'SNAT', 'prot': '*'}
                if not self._check_chain_has_rule(nat, c_name, rule):
                    warn(r("Chain %s's rule failed\n" % c_name))
                    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):
            warn(r("Chain %s's rule failed\n" % c_name))
            return False

        return True
Пример #45
0
 def _network_check_dhcp_ns(self, ns_dhcp):
     """
     Check the local router namespace on compute node
     :param ns_router:
     :return: list of the fip ns
     """
     output(b('### Checking dhcp ns = %s...' % ns_dhcp))
     if not ns_dhcp or not ns_dhcp.startswith('qdhcp-'):
         warn(r('Given dhcp ns %s name is invalid\n' % ns_dhcp))
         return False
     warns = False
     intfs = NameSpace(ns_dhcp).get_intfs()
     dhcp_ports = []  # list of {'intf':eth0, 'ip':[]}
     for i in intfs:  # check each intf in this ns
         p = intfs[i]['intf']
         if p == 'lo':  # ignore the lo port
             continue
         elif not p.startswith('tap'):  # no router port?
             warn(r('Invalid port dhcp %s in %s\n' % (p, ns_dhcp)))
             return False
         else:
             dhcp_ports.append(p)
             if not intfs[i]['ip']:
                 warn(r('No ip with dhcp port %s in %s\n' % (p, ns_dhcp)))
                 return False
             for ip_m in intfs[i]['ip']:
                 if ip_m.startswith('169.254'):
                     continue
                 ip, mask = ip_m.split('/')
                 intf = intfs[i]['intf']
                 #  we do not checking the process here is because
                 # subprocess.Popen can only get one line of each process,
                 #  while dnsmasq process is of several lines.
                 cmd = 'grep %s /var/lib/neutron/dhcp/%s/interface'\
                       % (intf, ns_dhcp[6:])
                 result, err = \
                     Popen(cmd, stdout=PIPE, stderr=PIPE,
                           shell=True).communicate()
                 if err:
                     warn(r(err))
                     return False
                 if not result:
                     warn(r('Not found dhcp intf %s in cfg\n' % intf))
                     return False
                 cmd = 'grep %s /var/lib/neutron/dhcp/%s/host'\
                       % (ip, ns_dhcp[6:])
                 result, err = \
                     Popen(cmd, stdout=PIPE, stderr=PIPE,
                           shell=True).communicate()
                 if err:
                     warn(r(err))
                     return False
                 if not result:
                     warn(r('Not found dhcp server addr %s in cfg\n' %
                            ip))
                     return False
     if not dhcp_ports:
         warn(r('Cannot find dhcp port in ns %s\n' % ns_dhcp))
         return False
     output(g('Passed\n'))
     return True
Пример #46
0
    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
Пример #47
0
    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
Пример #48
0
    def _network_check_bridges(self):
        """
        Check the bridge information
        :return:
        """
        output(b('>>> Checking bridges...\n'))
        bridges = get_all_bridges()
        names = bridges.keys()
        brvlans = [e for e in names
                  if e not in ['br-int', 'br-ex', 'br-tun']]
        if not brvlans:
            warn(r('No vlan bridge is found\n'))
            return False
        brvlan = brvlans[0]
        output(b('# Existing bridges are %s\n' % ', '.join(names)))
        # check br-int
        if 'br-int' not in names:
            warn(r('No integration bridge is found\n'))
            return False
        else:
            br = Bridge('br-int')
            if not br.has_port('int-'+brvlan) and not br.has_port('patch-tun'):
                if not br.has_port('int-'+brvlan):
                    warn(r('port %s not found in br-int\n' % 'int-'+brvlan))
                if not br.has_port('patch-tun'):
                    warn(r('port %s not found in br-int\n' % 'patch-tun'))
                return False

        # check br-ex
        if 'br-ex' not in names:
            warn(r('No external bridge is found\n'))
            return False
        else:
            br = Bridge('br-ex')
            if not br.has_port_start_with('qg-'):
                warn(r('No qg port found in br-ex\n'))

        if 'br-tun' not in names:
            warn(r('No tunnel bridge is found\n'))
            return False
        else:
            br = Bridge('br-tun')
            if not br.has_port('patch-int'):
                warn(r('port %s not found in br-tun\n' % 'patch-int'))
                return False

        br = Bridge(brvlan)
        if not br.has_port('phy-'+brvlan):
            warn(r('port %s not found in %s\n' % ('phy-'+brvlan, brvlan)))

        output(b('# Vlan bridge is at %s\n' % ', '.join(names)))
        output(g('<<< Checking bridges passed\n'))
        return True