# 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的资源。

```python
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()方法返回一个该类的实体。 分析其初始化方法：

```python
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方法中有

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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://yeasy.gitbook.io/openstack_code_neutron/neutron/api/v2.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
