v2

优质
小牛编辑
122浏览
2023-12-01

v2

实现neutron api第2个版本的定义。 主要方法包括index、update、create、show和delete。

attributes.py

这里面定义了一系列的_validate_xxx方法,包括_validate_mac_address、_validate_ip_address、_validate_boolean等,对传入的参数进行格式检查。

base.py

定义了Controller类和create_resource方法。 后者根据传入参数声明一个Controller并用它初始化一个wsgi的资源。

def create_resource(collection, resource, plugin, params, allow_bulk=False,
                    member_actions=None, parent=None, allow_pagination=False,
                    allow_sorting=False):
    controller = Controller(plugin, collection, resource, params, allow_bulk,
                            member_actions=member_actions, parent=parent,
                            allow_pagination=allow_pagination,
                            allow_sorting=allow_sorting)

    return wsgi_resource.Resource(controller, FAULT_MAP)

Controller类负责对rest API调用的资源进行处理,将对资源的请求转化为对应的plugin中方法的调用。 成员包括一个对dhcp agent的notifier。

resource.py

主要定义了Request类和Resource方法。 Request类继承自wsgi.Request,代表一个资源请求。 Resource方法会根据传入的Controller构造一个resource对象。

resource_helper.py

包括build_plural_mappings和build_resource_info两个方法。 前者对所有的资源创建从其复数到单数形式的映射;后者为advanced services扩展创建API资源对象。

router.py

此处的router意味着是在wsgi框架下对请求的rest api进行调度的router,并非网络中的router。从外面api-paste.ini文件中,可以看到最终app指向的是

[app:neutronapiapp_v2_0]
paste.app_factory = neutron.api.v2.router:APIRouter.factory

该文件主要包括了APIRouter类,继承自wsgi.Router类,定义了factory方法。 其中factory()方法返回一个该类的实体。 分析其初始化方法:

def __init__(self, **local_config):
        mapper = routes_mapper.Mapper()
        plugin = manager.NeutronManager.get_plugin()
        ext_mgr = extensions.PluginAwareExtensionManager.get_instance()
        ext_mgr.extend_resources("2.0", attributes.RESOURCE_ATTRIBUTE_MAP)

        col_kwargs = dict(collection_actions=COLLECTION_ACTIONS,
                          member_actions=MEMBER_ACTIONS)

        def _map_resource(collection, resource, params, parent=None):
            allow_bulk = cfg.CONF.allow_bulk
            allow_pagination = cfg.CONF.allow_pagination
            allow_sorting = cfg.CONF.allow_sorting
            controller = base.create_resource(
                collection, resource, plugin, params, allow_bulk=allow_bulk,
                parent=parent, allow_pagination=allow_pagination,
                allow_sorting=allow_sorting)
            path_prefix = None
            if parent:
                path_prefix = "/%s/{%s_id}/%s" % (parent["collection_name"],
                                                  parent["member_name"],
                                                  collection)
            mapper_kwargs = dict(controller=controller,
                                 requirements=REQUIREMENTS,
                                 path_prefix=path_prefix,
                                 **col_kwargs)
            return mapper.collection(collection, resource,
                                     **mapper_kwargs)

        mapper.connect("index", "/", controller=Index(RESOURCES))
        for resource in RESOURCES:
            _map_resource(RESOURCES[resource], resource,
                          attributes.RESOURCE_ATTRIBUTE_MAP.get(
                              RESOURCES[resource], dict()))

        for resource in SUB_RESOURCES:
            _map_resource(SUB_RESOURCES[resource]["collection_name"], resource,
                          attributes.RESOURCE_ATTRIBUTE_MAP.get(
                              SUB_RESOURCES[resource]["collection_name"],
                              dict()),
                          SUB_RESOURCES[resource]["parent"])

        super(APIRouter, self).__init__(mapper)

首先初始化一个router的mapper;之后获取plugin,通过调用NeutronManger类(负责解析配置文件并读取其中的plugin信息);然后获取支持的扩展的资源管理者,并把默认的对网络、子网和端口的资源的操作添加到扩展的资源管理者类中。

接下来,绑定资源的请求到各个资源上。_map_resource方法中创建了对应的控制器和映射关系。控制器在base.py文件中,其中定义了index、show、create、delete和update方法。这些方法中会获取plugin的对应方法对请求进行处理。例如,在create方法中有

obj_creator = getattr(self._plugin, action)
...
obj = obj_creator(request.context, **kwargs)