<commit_before>import logging
import copy

from uuid import uuid1
from vlcp.server.module import Module,depend,api,callAPI
from vlcp.event.runnable import RoutineContainer
from vlcp.utils.networkmodel import *
from vlcp.utils.dataobject import watch_context,set_new,dump,ReferenceObject,WeakReferenceObject
from vlcp.utils.ethernet import ip4_addr
from vlcp.utils.netutils import format_network_cidr,check_ip_address, parse_ip4_network, ip_in_network

import vlcp.service.kvdb.objectdb as objectdb

logger = logging.getLogger("vrouterapi")


@depend(objectdb.ObjectDB)
class VRouterApi(Module):
    def __init__(self,server):
        super(VRouterApi,self).__init__(server)

        self.app_routine = RoutineContainer(self.scheduler)
        self.app_routine.main = self.main
        self.routines.append(self.app_routine)
        self._reqid = 0

        self.createAPI(api(self.createvirtualrouter,self.app_routine),
                       api(self.createvirtualrouters,self.app_routine),
                       api(self.updatevirtualrouter,self.app_routine),
                       api(self.updatevirtualrouters,self.app_routine),
                       api(self.deletevirtualrouter,self.app_routine),
                       api(self.deletevirtualrouters,self.app_routine),
                       api(self.listvirtualrouters,self.app_routine),
                       api(self.addrouterinterface,self.app_routine),
                       api(self.addrouterinterfaces,self.app_routine),
                       api(self.removerouterinterface,self.app_routine),
                       api(self.removerouterinterfaces,self.app_routine),
                       api(self.listrouterinterfaces,self.app_routine))
    def main(self):
        logger.info(" viperflow VRouterApi running --")
        
        if False:
            yield 
    def _dumpkeys(self,keys):
        self._reqid += 1
        reqid = ('virtualrouter',self._reqid)

        for m in callAPI(self.app_routine,'objectdb','mget',{'keys':keys,'requestid':reqid}):
            yield m

        retobjs = self.app_routine.retvalue

        with watch_context(keys,retobjs,reqid,self.app_routine):
            self.app_routine.retvalue = [dump(v) for v in retobjs]

    def _getkeys(self,keys):
        self._reqid += 1
        reqid = ('virtualrouter',self._reqid)
        for m in callAPI(self.app_routine,'objectdb','mget',{'keys':keys,'requestid':reqid}):
            yield m
        with watch_context(keys,self.app_routine.retvalue,reqid,self.app_routine):
            pass

    def createvirtualrouter(self,id=None,**kwargs):
        "create virtual router "
        if not id:
            id = str(uuid1())

        router = {"id":id}
        router.update(kwargs)

        for m in self.createvirtualrouters([router]):
            yield m

    def createvirtualrouters(self,routers):
        "create virutal routers"
        idset = set()
        newrouters = []
        for router in routers:
            router = copy.deepcopy(router)
            if "id" not in router:
                router["id"] = str(uuid1())
            else:
                if router["id"] in idset:
                    raise ValueError("id repeat " + router['id'])
                else:
                    idset.add(router['id'])

            newrouters.append(router)
        
        routerkeys = [VRouter.default_key(r['id']) for r in newrouters]
        dvrouterinfokeys = [DVRouterInfo.default_key(r['id']) for r in newrouters]
        routersetkey = [VRouterSet.default_key()]

        routerobjects = [self._createvirtualrouter(**r) for r in newrouters ]
        dvrouterinfoobjects = [DVRouterInfo.create_instance(r['id']) for r in newrouters ]

        def createrouterdb(keys,values):
            routerset = values[0]

            for i in range(0,len(routerkeys)):
                values[i+1] = set_new(values[i+1],routerobjects[i])
                values[i+1+len(routerkeys)] = set_new(values[i+1+len(routerkeys)],dvrouterinfoobjects[i])
                routerset.set.dataset().add(routerobjects[i].create_weakreference())

            return keys,values
        try:
            for m in callAPI(self.app_routine,"objectdb","transact",
                             {"keys":routersetkey+routerkeys+dvrouterinfokeys,"updater":createrouterdb}):
                yield m
        except:
            raise
        else:
            for m in self._dumpkeys(routerkeys):
                yield m

    def _createvirtualrouter(self,id,**kwargs):

        router = VRouter.create_instance(id)

        # {'routers':[{"ip_prefix":cidr,"nexthop":ip}]}
        if 'routes' in kwargs:
            for r in kwargs['routes']:
                ip_prefix = r.get('ip_prefix')
                nexthop = r.get('nexthop')

                if ip_prefix and nexthop:

                    # ip_prefix must be cidr
                    # nexthop must be ip_address
                    ip_prefix = format_network_cidr(ip_prefix)
                    nexthop = check_ip_address(nexthop)
                    # when create virtual route , there no interface in it
                    # add static route
                    router.routes.append((ip_prefix,nexthop))
                else:
                    raise ValueError("routers format error " + r)

        for k,v in kwargs.items():
            if k != "routes":
                setattr(router,k,v)

        return router

    def updatevirtualrouter(self,id,**kwargs):
        "update virtual router"
        if not id:
            raise ValueError(" must special id")
        router = {"id":id}
        router.update(kwargs)

        for m in self.updatevirtualrouters([router]):
            yield m

    def updatevirtualrouters(self,routers):
        "update virtual routers"
        idset = set()
        for router in routers:
            if 'id' not in router:
                raise ValueError(" must special id")
            else:
                if router['id'] in idset:
                    raise ValueError(" id repeat " + router['id'])
                else:
                    idset.add(router['id'])

            # if routers updating ,, check format
            if 'routes' in router:
                for r in router['routes']:
                    ip_prefix = r.get('ip_prefix')
                    nexthop = r.get('nexthop')

                    if ip_prefix and nexthop:
                        ip_prefix = format_network_cidr(ip_prefix)
                        nexthop = check_ip_address(nexthop)<commit_msg>修改 vrouter 静态路由表的格式，方便操作！<commit_after>import logging
import copy

from uuid import uuid1
from vlcp.server.module import Module,depend,api,callAPI
from vlcp.event.runnable import RoutineContainer
from vlcp.utils.networkmodel import *
from vlcp.utils.dataobject import watch_context,set_new,dump,ReferenceObject,WeakReferenceObject
from vlcp.utils.ethernet import ip4_addr
from vlcp.utils.netutils import format_network_cidr,check_ip_address, parse_ip4_network, ip_in_network

import vlcp.service.kvdb.objectdb as objectdb

logger = logging.getLogger("vrouterapi")


@depend(objectdb.ObjectDB)
class VRouterApi(Module):
    def __init__(self,server):
        super(VRouterApi,self).__init__(server)

        self.app_routine = RoutineContainer(self.scheduler)
        self.app_routine.main = self.main
        self.routines.append(self.app_routine)
        self._reqid = 0

        self.createAPI(api(self.createvirtualrouter,self.app_routine),
                       api(self.createvirtualrouters,self.app_routine),
                       api(self.updatevirtualrouter,self.app_routine),
                       api(self.updatevirtualrouters,self.app_routine),
                       api(self.deletevirtualrouter,self.app_routine),
                       api(self.deletevirtualrouters,self.app_routine),
                       api(self.listvirtualrouters,self.app_routine),
                       api(self.addrouterinterface,self.app_routine),
                       api(self.addrouterinterfaces,self.app_routine),
                       api(self.removerouterinterface,self.app_routine),
                       api(self.removerouterinterfaces,self.app_routine),
                       api(self.listrouterinterfaces,self.app_routine))
    def main(self):
        logger.info(" viperflow VRouterApi running --")
        
        if False:
            yield 
    def _dumpkeys(self,keys):
        self._reqid += 1
        reqid = ('virtualrouter',self._reqid)

        for m in callAPI(self.app_routine,'objectdb','mget',{'keys':keys,'requestid':reqid}):
            yield m

        retobjs = self.app_routine.retvalue

        with watch_context(keys,retobjs,reqid,self.app_routine):
            self.app_routine.retvalue = [dump(v) for v in retobjs]

    def _getkeys(self,keys):
        self._reqid += 1
        reqid = ('virtualrouter',self._reqid)
        for m in callAPI(self.app_routine,'objectdb','mget',{'keys':keys,'requestid':reqid}):
            yield m
        with watch_context(keys,self.app_routine.retvalue,reqid,self.app_routine):
            pass

    def createvirtualrouter(self,id=None,**kwargs):
        "create virtual router "
        if not id:
            id = str(uuid1())

        router = {"id":id}
        router.update(kwargs)

        for m in self.createvirtualrouters([router]):
            yield m

    def createvirtualrouters(self,routers):
        "create virutal routers"
        idset = set()
        newrouters = []
        for router in routers:
            router = copy.deepcopy(router)
            if "id" not in router:
                router["id"] = str(uuid1())
            else:
                if router["id"] in idset:
                    raise ValueError("id repeat " + router['id'])
                else:
                    idset.add(router['id'])

            newrouters.append(router)
        
        routerkeys = [VRouter.default_key(r['id']) for r in newrouters]
        dvrouterinfokeys = [DVRouterInfo.default_key(r['id']) for r in newrouters]
        routersetkey = [VRouterSet.default_key()]

        routerobjects = [self._createvirtualrouter(**r) for r in newrouters ]
        dvrouterinfoobjects = [DVRouterInfo.create_instance(r['id']) for r in newrouters ]

        def createrouterdb(keys,values):
            routerset = values[0]

            for i in range(0,len(routerkeys)):
                values[i+1] = set_new(values[i+1],routerobjects[i])
                values[i+1+len(routerkeys)] = set_new(values[i+1+len(routerkeys)],dvrouterinfoobjects[i])
                routerset.set.dataset().add(routerobjects[i].create_weakreference())

            return keys,values
        try:
            for m in callAPI(self.app_routine,"objectdb","transact",
                             {"keys":routersetkey+routerkeys+dvrouterinfokeys,"updater":createrouterdb}):
                yield m
        except:
            raise
        else:
            for m in self._dumpkeys(routerkeys):
                yield m

    def _createvirtualrouter(self,id,**kwargs):

        router = VRouter.create_instance(id)

        # [(prefix, nexthop),(prefix, nexthop)]
        if 'routes' in kwargs:
            for e in kwargs['routes']:
                ip_prefix = e[0]
                nexthop = e[1]

                if ip_prefix and nexthop:
                    ip_prefix = format_network_cidr(ip_prefix)
                    nexthop = check_ip_address(nexthop)
                    router.routes.append((ip_prefix,nexthop))
                else:
                    raise ValueError(" routes format error " + e)

        for k,v in kwargs.items():
            if k != "routes":
                setattr(router,k,v)

        return router

    def updatevirtualrouter(self,id,**kwargs):
        "update virtual router"
        if not id:
            raise ValueError(" must special id")
        router = {"id":id}
        router.update(kwargs)

        for m in self.updatevirtualrouters([router]):
            yield m

    def updatevirtualrouters(self,routers):
        "update virtual routers"
        idset = set()
        for router in routers:
            if 'id' not in router:
                raise ValueError(" must special id")
            else:
                if router['id'] in idset:
                    raise ValueError(" id repeat " + router['id'])
                else:
                    idset.add(router['id'])

            # if routers updating ,, check format
            if 'routes' in router:
                for r in router['routes']:
                    ip_prefix = r[0]
                    nexthop = r[1]

                    if ip_prefix and nexthop:
                        ip_prefix = parse_ip4_network(ip_prefix)
                        nexthop = check_ip_address(nexthop)
{'fraction_non_alphanumeric': 0.09985108550826867, 'fraction_numerical': 0.0025864095932283094, 'mean_word_length': 1.9896907216494846, 'pattern_counts': {'":': 12, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7367202', 'n_tokens_mistral': 3736, 'n_tokens_neox': 3615, 'n_words': 708}