[libvirt] [test-API][PATCH] The patch covers all nwfilter api provided by libvirt.py. It includes define/undefine/list nwfilters and check them via checking ebtables rule. The following new files are added. cases/nwfilter.conf repos/nwfilter/__init__.py repos/nwfilter/nwfilter_check.py * Check the nwfilter via checking ebtales repos/nwfilter/nwfilter_define.py * Define the nwfilter using specified value repos/nwfilter/nwfilter_list.py * List all of the available network filters repos/nwfilter/nwfilter_undefine.py * Undefine the specified nwfilter repos/nwfilter/xmls/nwfilter.xml

Osier Yang jyang at redhat.com
Mon Mar 18 09:53:35 UTC 2013


On 2013年03月18日 14:54, hongming wrote:

Can you shorten the patch subject? And add the sentences in the commit
log instead?

> ---
>   cases/nwfilter.conf                 |   59 +++++++++++++++++
>   repos/nwfilter/nwfilter_check.py    |  120 +++++++++++++++++++++++++++++++++++
>   repos/nwfilter/nwfilter_define.py   |   54 ++++++++++++++++
>   repos/nwfilter/nwfilter_list.py     |   76 ++++++++++++++++++++++
>   repos/nwfilter/nwfilter_undefine.py |   43 +++++++++++++
>   repos/nwfilter/xmls/nwfilter.xml    |    3 +
>   6 files changed, 355 insertions(+), 0 deletions(-)
>   create mode 100644 cases/nwfilter.conf
>   create mode 100644 repos/nwfilter/__init__.py
>   create mode 100644 repos/nwfilter/nwfilter_check.py
>   create mode 100644 repos/nwfilter/nwfilter_define.py
>   create mode 100644 repos/nwfilter/nwfilter_list.py
>   create mode 100644 repos/nwfilter/nwfilter_undefine.py
>   create mode 100644 repos/nwfilter/xmls/nwfilter.xml
>
> diff --git a/cases/nwfilter.conf b/cases/nwfilter.conf
> new file mode 100644
> index 0000000..b394ee5
> --- /dev/null
> +++ b/cases/nwfilter.conf
> @@ -0,0 +1,59 @@
> +domain:install_linux_cdrom
> +    guestname
> +        $defaultname
> +    guestos
> +        $defaultos
> +    guestarch
> +        $defaultarch
> +    vcpu
> +        $defaultvcpu
> +    memory
> +        $defaultmem
> +    hddriver
> +        $defaulthd
> +    nicdriver
> +        $defaultnic
> +    imageformat
> +        qcow2
> +    macaddr
> +        54:52:00:4a:16:30
> +
> +nwfilter:nwfilter_list
> +
> +# chain -- ipv4, ipv6, arp .etc
> +# action -- mandatory; drop, accept, return
> +# direction -- mandatory; must either be in, out or inout
> +nwfilter:nwfilter_define
> +    nwfiltername
> +    	disallow-arp
> +    chain
> +    	arp
> +    action
> +    	drop
> +    direction
> +    	inout
> +
> +nwfilter:nwfilter_list
> +
> +nwfilter:nwfilter_check
> +    nwfiltername
> +	disallow-arp
> +    guestname
> +	$defaultname
> +
> +nwfilter:nwfilter_define
> +    nwfiltername
> +    	disallow-ipv6
> +    chain
> +    	ipv6
> +    action
> +    	drop
> +    direction
> +    	in
> +
> +nwfilter:nwfilter_undefine
> +    nwfiltername
> +	disallow-ipv6
> +
> +nwfilter:nwfilter_list
> +
> diff --git a/repos/nwfilter/__init__.py b/repos/nwfilter/__init__.py
> new file mode 100644
> index 0000000..e69de29
> diff --git a/repos/nwfilter/nwfilter_check.py b/repos/nwfilter/nwfilter_check.py
> new file mode 100644
> index 0000000..b2c7ece
> --- /dev/null
> +++ b/repos/nwfilter/nwfilter_check.py
> @@ -0,0 +1,120 @@
> +#!/usr/bin/env python
> +import time
> +import xml.dom.minidom
> +
> +from libvirt import libvirtError
> +from utils import utils
> +from xml.dom import minidom
> +
> +from src import sharedmod
> +
> +required_params = ('nwfiltername','guestname',)
> +optional_params = {}
> +
> +EBTABLES = "ebtables -t nat -L"
> +
> +def get_ebtables():
> +    """ Get the output of ebtables """
> +    (status, output) = utils.exec_cmd(EBTABLES,shell=True)
> +    logger.info("Execute command:" + EBTABLES)
> +    ebtables_list = []
> +
> +    if status:
> +        logger.error("Executing " + EBTABLES + " failed")
> +        logger.error(output)
> +        return False
> +    else:
> +        for i in range(len(output)):
> +            ebtables_list.append(output[i])
> +        logger.info("Get the output of ebtables list: %s" \
> +                    % ebtables_list)
> +
> +    return ebtables_list
> +
> +def check_ebtables(*args):
> +    """ Check the ebtables """
> +    (nwfiltername,conn)= args
> +    ebtables_list = get_ebtables()
> +
> +    #Get the filter' attribute value
> +    nwfilter_xml = conn.nwfilterLookupByName(nwfiltername).XMLDesc(0)
> +    nwfilter_parsedxml = minidom.parseString(nwfilter_xml)
> +    chain = nwfilter_parsedxml.getElementsByTagName("filter")[0].\
> +    getAttribute("chain")
> +    rule = nwfilter_parsedxml.getElementsByTagName("rule")[0]
> +    action = rule.getAttribute("action").upper()
> +    direction = rule.getAttribute("direction")
> +    logger.info("The nwfilter chain:%s ,action:%s ,direction:%s " %\
> +                    (chain,action,direction) )
> +    in_vnet_chain = "I-vnet0-" + chain
> +    out_vnet_chain = "O-vnet0-" + chain
> +
> +    if cmp(direction,"inout") == 0 :
> +        if len(ebtables_list) == 21 and in_vnet_chain in ebtables_list[-5]\
> +        and out_vnet_chain in ebtables_list[-2] \
> +        and action in ebtables_list[-1] \
> +        and action in ebtables_list[-4]:
> +            return True
> +        else:
> +            return False
> +    elif cmp(direction,"in") == 0:
> +        if len(ebtables_list) == 14 and out_vnet_chain in ebtables_list[-2]\
> +        and action in ebtables_list[-1]:
> +            return True
> +        else:
> +            return False
> +
> +    elif cmp(direction,"out") == 0:
> +        if len(ebtables_list) == 14 and in_vnet_chain in ebtables_list[-2] \
> +        and action in ebtables_list[-1]:
> +            return True
> +        else:
> +            return False
> +
> +def nwfilter_check(params):
> +    """Check the nwfilter via checking ebtales"""
> +    global logger
> +    logger = params['logger']
> +    nwfiltername = params['nwfiltername']
> +    guestname = params['guestname']
> +    domain_nwfilter_xml = ""
> +
> +    conn = sharedmod.libvirtobj['conn']
> +    domobj = conn.lookupByName(guestname)
> +
> +    try:
> +
> +        #Create the nwfilter's element and append it to domain xml
> +        domxml = domobj.XMLDesc(0)
> +        domain_parsedxml = minidom.parseString(domxml)
> +        domain_ifxml = domain_parsedxml.getElementsByTagName("interface")
> +        filterxml = domain_parsedxml.createElement("filterref")
> +        filterxml.setAttribute("filter", nwfiltername)
> +        domain_ifxml[0].appendChild(filterxml)
> +
> +        #Destroy the domain and redefine it with nwfilter
> +        domobj.destroy()
> +        time.sleep(5)
> +        domobj.undefine()
> +
> +        #Define the new domain with the nwfilter
> +        dom_nwfilter = conn.defineXML(domain_parsedxml.toxml())
> +        logger.debug("The xml of new defined domain with nwfilter %s" % \
> +                     dom_nwfilter.XMLDesc(0))
> +
> +        #Start the new defined domain
> +        dom_nwfilter.create()
> +        time.sleep(5)
> +
> +        if check_ebtables(nwfiltername,conn):
> +            logger.info("Successfully create nwfilter")
> +            return 0
> +        else:
> +            logger.error("Failed to create nwfilter")
> +            return 1
> +
> +    except libvirtError, e:
> +        logger.error("API error message: %s" % e.message)
> +        return 1
> +
> +    return 0
> \ No newline at end of file
> diff --git a/repos/nwfilter/nwfilter_define.py b/repos/nwfilter/nwfilter_define.py
> new file mode 100644
> index 0000000..e20fd2d
> --- /dev/null
> +++ b/repos/nwfilter/nwfilter_define.py
> @@ -0,0 +1,54 @@
> +#! /usr/bin/env python
> +
> +
> +
> +from libvirt import libvirtError
> +from src import sharedmod
> +
> +
> +required_params = ('nwfiltername','chain','action','direction')
> +optional_params = {'xml' : 'xmls/nwfilter.xml',}
> +
> +def nwfilter_define(params):
> +    """ Define network filters."""
> +    logger = params['logger']
> +    conn = sharedmod.libvirtobj['conn']
> +    xmlstr = params['xml']
> +    nwfiltername = params['nwfiltername']
> +    chain = params['chain']
> +    action = params['action']
> +    direction = params['direction']
> +
> +
> +    xmlstr = xmlstr.replace('NWFILTERNAME', nwfiltername)
> +    xmlstr = xmlstr.replace('CHAIN', chain)
> +    xmlstr = xmlstr.replace('ACTION', action)
> +    xmlstr = xmlstr.replace('DIRECTION', direction)
> +    try:
> +        logger.info("nwfiltername:%s chain:%s action:%s direction:%s" % \
> +                    (nwfiltername,chain,action,direction))
> +        logger.info("The nwfilter's xml is %s" % xmlstr)
> +
> +        #Define the nwfilter with given attribute value from nwfilter.conf"""
> +        conn.nwfilterDefineXML(xmlstr)
> +        nwfilterxml = conn.nwfilterLookupByName(nwfiltername).XMLDesc(0)
> +
> +        if nwfiltername in conn.listNWFilters():
> +            logger.info("The nwfilter list includes the defined nwfilter")
> +            if cmp(xmlstr,nwfilterxml):
> +                logger.info("Successfully define the nwfilter %s" % \
> +                            nwfiltername)
> +                return 0
> +            else:
> +                logger.error("Fail to define the nwfilter %s" % nwfiltername)
> +                return 1
> +        else:
> +            logger.error("Failed,nwfilter list doesn't include the defined \
> +            nwfilter")
> +            return 1
> +
> +    except libvirtError, e:
> +        logger.error("API error message: %s" % e.message)
> +        return 1
> +
> +    return 0
> \ No newline at end of file
> diff --git a/repos/nwfilter/nwfilter_list.py b/repos/nwfilter/nwfilter_list.py
> new file mode 100644
> index 0000000..056ee1f
> --- /dev/null
> +++ b/repos/nwfilter/nwfilter_list.py
> @@ -0,0 +1,76 @@
> +#!/usr/bin/env python
> +
> +from libvirt import libvirtError
> +from utils import utils
> +
> +from src import sharedmod
> +
> +required_params = ()
> +optional_params = {}
> +
> +NWFILTER_LIST_API_DIR = "ls /etc/libvirt/nwfilter"
> +
> +def get_nwfilterlist_dir():
> +    """ Get the nwfilter list from dir """
> +
> +    (status, output) = utils.exec_cmd(NWFILTER_LIST_API_DIR,shell=True)
> +    logger.info("Execute command:" + NWFILTER_LIST_API_DIR)
> +    nwfilter_list_api_dir = []
> +    if status:
> +        logger.error("Executing " + NWFILTER_LIST_API_DIR + " failed")
> +        logger.error(output)
> +        return False
> +    else:
> +        for i in range(len(output)):
> +            nwfilter_list_api_dir.append(output[i][:-4])
> +        logger.info("Get nwfilters name list under dir: %s" \
> +                    % nwfilter_list_api_dir)
> +        return nwfilter_list_api_dir
> +
> +def nwfilter_list(params):
> +    """ List all of the available network filters."""
> +    global logger
> +    logger = params['logger']
> +    conn = sharedmod.libvirtobj['conn']
> +
> +    try:
> +        #Get the nwfilter name list from API """
> +        nwfilter_namelist_api = conn.listNWFilters()
> +
> +        #Get the nwfilter object list
> +        nwfilter_list_api = conn.listAllNWFilters(0)
> +        logger.info("The connection URI %s" % \
> +                    nwfilter_list_api[0].connect().getURI())
> +
> +        #Get the number of nwfilters from API
> +        nwfilter_num = conn.numOfNWFilters()
> +
> +        nwfilter_list_dir = get_nwfilterlist_dir()
> +        if nwfilter_num == len(nwfilter_list_api) and \
> +        len(nwfilter_list_api) == len(nwfilter_list_dir) and \
> +        cmp(nwfilter_namelist_api,nwfilter_list_dir):
> +            logger.info("The number of available network filters is %s" % \
> +                    nwfilter_num)
> +        else:
> +            logger.error("Failed to get the nwfilters list")
> +            return 1
> +
> +        for nwfilter_item in nwfilter_list_api:
> +            if nwfilter_item.name()in nwfilter_list_dir and \
> +            nwfilter_item.name()in nwfilter_namelist_api:
> +                logger.info("The name is %s" % nwfilter_item.name())
> +            else:
> +                logger.error("Failed to get nwfilter's name.")
> +                return 1
> +            if cmp(str(nwfilter_item.UUID()),nwfilter_item.UUIDString()):
> +                logger.info("The UUID is %s" % nwfilter_item.UUIDString())
> +            else:
> +                logger.error("Failed to get nwfilter's uuid.")
> +                return 1
> +
> +
> +    except libvirtError, e:
> +        logger.error("API error message: %s" % e.message)
> +        return 1
> +
> +    return 0
> \ No newline at end of file
> diff --git a/repos/nwfilter/nwfilter_undefine.py b/repos/nwfilter/nwfilter_undefine.py
> new file mode 100644
> index 0000000..b9ea332
> --- /dev/null
> +++ b/repos/nwfilter/nwfilter_undefine.py
> @@ -0,0 +1,43 @@
> +#!/usr/bin/env python
> +
> +from libvirt import libvirtError
> +
> +from src import sharedmod
> +
> +required_params = ('nwfiltername',)
> +optional_params = {}
> +
> +def nwfilter_undefine(params):
> +    """Undefine the specified nwfilter"""
> +    logger = params['logger']
> +    nwfiltername = params['nwfiltername']
> +    conn = sharedmod.libvirtobj['conn']
> +
> +    try:
> +         nwfilter = conn.nwfilterLookupByName(nwfiltername)
> +         uuidstr = nwfilter.UUIDString()
> +         uuid = nwfilter.UUID()
> +         # Lookup by nwfilter's uuid string
> +         nwfilter_uuidstr = conn.nwfilterLookupByUUIDString(uuidstr)
> +         # Lookup by nwfilter's uuid
> +         nwfilter_uuid = conn.nwfilterLookupByUUID(uuid)
> +
> +         # Check if the nwfilter lookup by name/uuid/uuidstr is the same one
> +         if cmp(nwfilter,nwfilter_uuidstr) and cmp(nwfilter_uuidstr,\
> +                                                   nwfilter_uuid):
> +             # Undefine the nwfilter
> +             nwfilter.undefine()
> +             # Check if the nwfiler list includes the undefined nwfilter
> +             if nwfiltername not in conn.listNWFilters():
> +                 logger.info("Successfully undefine the nwfilter %s" % \
> +                         nwfiltername)
> +                 return 0
> +         else:
> +             logger.error("Failed to undefine the nwfilter %s" % nwfiltername)
> +             return 1
> +
> +    except libvirtError, e:
> +        logger.error("API error message: %s" % e.message)
> +        return 1
> +
> +    return 0
> diff --git a/repos/nwfilter/xmls/nwfilter.xml b/repos/nwfilter/xmls/nwfilter.xml
> new file mode 100644
> index 0000000..6d52d5d
> --- /dev/null
> +++ b/repos/nwfilter/xmls/nwfilter.xml
> @@ -0,0 +1,3 @@
> +<filter name='NWFILTERNAME' chain='CHAIN'>
> +<rule action='ACTION' direction='DIRECTION' priority='500'/>
> +</filter>




More information about the libvir-list mailing list