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

  1. def create_resource(collection, resource, plugin, params, allow_bulk=False,
  2. member_actions=None, parent=None, allow_pagination=False,
  3. allow_sorting=False):
  4. controller = Controller(plugin, collection, resource, params, allow_bulk,
  5. member_actions=member_actions, parent=parent,
  6. allow_pagination=allow_pagination,
  7. allow_sorting=allow_sorting)
  8. 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指向的是

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

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

  1. def __init__(self, **local_config):
  2. mapper = routes_mapper.Mapper()
  3. plugin = manager.NeutronManager.get_plugin()
  4. ext_mgr = extensions.PluginAwareExtensionManager.get_instance()
  5. ext_mgr.extend_resources("2.0", attributes.RESOURCE_ATTRIBUTE_MAP)
  6. col_kwargs = dict(collection_actions=COLLECTION_ACTIONS,
  7. member_actions=MEMBER_ACTIONS)
  8. def _map_resource(collection, resource, params, parent=None):
  9. allow_bulk = cfg.CONF.allow_bulk
  10. allow_pagination = cfg.CONF.allow_pagination
  11. allow_sorting = cfg.CONF.allow_sorting
  12. controller = base.create_resource(
  13. collection, resource, plugin, params, allow_bulk=allow_bulk,
  14. parent=parent, allow_pagination=allow_pagination,
  15. allow_sorting=allow_sorting)
  16. path_prefix = None
  17. if parent:
  18. path_prefix = "/%s/{%s_id}/%s" % (parent['collection_name'],
  19. parent['member_name'],
  20. collection)
  21. mapper_kwargs = dict(controller=controller,
  22. requirements=REQUIREMENTS,
  23. path_prefix=path_prefix,
  24. **col_kwargs)
  25. return mapper.collection(collection, resource,
  26. **mapper_kwargs)
  27. mapper.connect('index', '/', controller=Index(RESOURCES))
  28. for resource in RESOURCES:
  29. _map_resource(RESOURCES[resource], resource,
  30. attributes.RESOURCE_ATTRIBUTE_MAP.get(
  31. RESOURCES[resource], dict()))
  32. for resource in SUB_RESOURCES:
  33. _map_resource(SUB_RESOURCES[resource]['collection_name'], resource,
  34. attributes.RESOURCE_ATTRIBUTE_MAP.get(
  35. SUB_RESOURCES[resource]['collection_name'],
  36. dict()),
  37. SUB_RESOURCES[resource]['parent'])
  38. super(APIRouter, self).__init__(mapper)

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

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

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