关于neutron router-update在server端执行流程

输入neutron router-update 参数执行后,neutron-server收到neutronclient发来的http请求后,根据路由映射选择相应的controller下的函数。

1.neutron/api/v2/base.py(493)update():所有的关于update操作都将在这处理

  def update(self, request, id, body=None, **kwargs):        
        """Updates the specified entity's attributes."""
           parent_id = kwargs.get(self._parent_id_name)
           try:
                payload = body.copy()#body是请求部分,在这里body里包含了传过来的路由信息
           except AttributeError:
                msg = _("Invalid format: %s") % request.body
                raise exceptions.BadRequest(resource='body', msg=msg)
           payload['id'] = id#id是路由器的id
           self._notifier.info(request.context,
           self._resource + '.update.start', payload)
           body = Controller.prepare_request_body(request.context, body, False,
                                                self._resource, self._attr_info,
                                                allow_bulk=self._allow_bulk)#路由信息
           action = self._plugin_handlers[self.UPDATE]
           # Load object to check authz
           # but pass only attributes in the original body and required
           # by the policy engine to the policy 'brain'
           field_list = [name for (name, value) in self._attr_info.iteritems()
                       if (value.get('required_by_policy') or
                           value.get('primary_key') or
                           'default' not in value)] #field_list是orig_obj

     policy.init()
            orig_obj = self._item(request, id, field_list=field_list,
                                  parent_id=parent_id)
            orig_object_copy = copy.copy(orig_obj)
            orig_obj.update(body[self._resource])
           # Ensure policy engine is initialized
           policy.init()orig_obj[const.ATTRIBUTES_TO_UPDATE] = body[self._resource].keys()
   try:
            policy.enforce(request.context,
                            action,
                            orig_obj)
           except exceptions.PolicyNotAuthorized:

                with excutils.save_and_reraise_exception() as ctxt:
                    # If a tenant is modifying it's own object, it's safe to return
                    # a 403. Otherwise, pretend that it doesn't exist to avoid
                    # giving away information.
                    if request.context.tenant_id != orig_obj['tenant_id']:
                           ctxt.reraise = False
                 msg = _('The resource could not be found.')
                 raise webob.exc.HTTPNotFound(msg)

          obj_updater = getattr(self._plugin, action)#bound method L3RouterPlugin.update_router of <neutron.services.l3_router.l3_router_plugin.L3RouterPlugin,实际执行 #update操作的都是class L3RouterPlugin及其父类相应函数
          kwargs = {self._resource: body}

          if parent_id:
              kwargs[self._parent_id_name] = parent_id
          obj = obj_updater(request.context, id, **kwargs)#开始更新,跳转到neutron/db/extraroute_db.py(66)update_router()
          result = {self._resource: self._view(request.context, obj)}
          notifier_method = self._resource + '.update.end'
          self._notifier.info(request.context, notifier_method, result)
          self._send_dhcp_notification(request.context,
                                      result,
                                     notifier_method)
          self._send_nova_notification(action, orig_object_copy, result)
          return result 



2.neutron/db/extraroute_db.py(66)update_router():处理uodate-router的入口

 def update_router(self, context, id, router):

r = router['router'] #r类型为字典,存储路由表信息

with context.session.begin(subtransactions=True):

 #check if route exists and have permission to access

#检查路由器是否存在并且是否有操作的权限

router_db = self._get_router(context, id)#/跳转到neutron/neutron/db/l3_db.py(120)_get_router()

if 'routes' in r:

self._update_extra_routes(context, router_db, r['routes'])

routes = self._get_extra_routes_by_router_id(context, id)

router_updated = super(ExtraRoute_dbonly_mixin, self).update_router(context, id, router)

router_updated['routes'] = routes

return router_updated

118     def _update_extra_routes(self, context, router, routes):
119         self._validate_routes(context, router['id'],
120                               routes)   
121         old_routes, routes_dict = self._get_extra_routes_dict_by_router_id(
122             context, router['id'])      
123                                         
124         '''                             
125             old_routes:existed routes,is a list,like:
126             [{'nexthop': u'10.0.0.3', 'destination': u'10.0.0.0/24'}, {'nexthop': u'192.168.100.3', 'destination': u'192.168.100.0/24'}]
127             routes:new routes to update,is a list,like:
128             [{u'destination': u'10.0.0.0/24', u'nexthop': u'10.0.0.2'}, {u'destination': u'192.168.100.0/24', u'nexthop': u'192.168.100.2'}]   
129         '''                             
130         added, removed = utils.diff_list_of_dict(old_routes,
131                                                  routes)
132                                         
133         '''                             
134             utils.diff_list_of_dict(old_routes, routes)
135             old_routes and routes change to set type,find new routes to add:added,find routes to delete:removed
136             added,removed both are list,like:
137             [{u'nexthop': u'10.0.0.2', u'destination': u'10.0.0.0/24'}, {u'nexthop': u'192.168.100.2', u'destination': u'192.168.100.0/24'}]
138         '''                             
139                                         
140         LOG.debug(_('Added routes are %s'), added)
141         for route in added:             
142             router_routes = RouterRoute(
143                 router_id=router['id'], 
144                 destination=route['destination'],
145                 nexthop=route['nexthop'])
146             context.session.add(router_routes)
147                                         
148         LOG.debug(_('Removed routes are %s'), removed)
149         for route in removed:           
150             context.session.delete(     
151                 routes_dict[(route['destination'], route['nexthop'])])


3./neutron/neutron/db/l3_db.py(120)_get_router():

 def    _get_router(self, context, router_id):
          try:
                 router = self._get_by_id(context, Router, router_id)#跳转到neutron/db/common_db_mixin.py(123)_get_by_id(),类型neutron.db.l3_db.Router
          except exc.NoResultFound:
                 raise l3.RouterNotFound(router_id=router_id)
          return router

4.neutron/db/common_db_mixin.py(123)_get_by_id():

 def   _get_by_id(self, context, model, id):
        query = self._model_query(context, model)
        return query.filter(model.id == id).one()


def _model_query(self, context, model):                                                                                                        
query = context.session.query(model)
  # define basic filter condition for model query
  # NOTE(jkoelker) non-admin queries are scoped to their tenant_id
# NOTE(salvatore-orlando): unless the model allows for shared objects
  query_filter = None

if not context.is_admin and hasattr(model, 'tenant_id'):
               if hasattr(model, 'shared'):
                    query_filter = ((model.tenant_id == context.tenant_id) |
                                    (model.shared == sql.true()))
                else:
                    query_filter = (model.tenant_id == context.tenant_id)
            # Execute query hooks registered from mixins and plugins
            for _name, hooks in self._model_query_hooks.get(model,
                                                            {}).iteritems():
                query_hook = hooks.get('query')
                if isinstance(query_hook, basestring):
                    query_hook = getattr(self, query_hook, None)
                if query_hook:
                    query = query_hook(context, model, query)
         
                filter_hook = hooks.get('filter')
                if isinstance(filter_hook, basestring):
                    filter_hook = getattr(self, filter_hook, None)
                if filter_hook:
                    query_filter = filter_hook(context, model, query_filter)
         
            # NOTE(salvatore-orlando): 'if query_filter' will try to evaluate the
            # condition, raising an exception
            if query_filter is not None:
                query = query.filter(query_filter)
            return query


你可能感兴趣的:(关于neutron router-update在server端执行流程)