您的位置:首页 > 其它

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

2015-08-02 16:20 615 查看
输入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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: