Nova API的实现——V2 API上添加新资源

为Nova添加新的API,或者对现有API进行扩展是件相对容易的事情,我们并不需要去过多关注一个HTTP请求是如何路由到新增的资源及其操作上,需要做的仅仅是遵循一些固定的规则与步骤。
首先看如何在v2 API中添加新的资源。
一 添加新资源与对应的Controller
对核心资源,需要在nova/api/openstack/compute目录下添加新文件,对于扩展资源则是nova/api/openstack/compute/contrib目录。
通常我们遇到的情况也仅仅是新增一个扩展资源,所以这里以现有的扩展资源keypairs为例进行说明。nova/api/openstack/compute/contrib/keypairs.py
定义该扩展资源对应的Controller,继承于所扩展核心资源的Controller,这里的keypairs是对核心资源的扩展
class Controller(servers.Controller):
                .......
     #Controller中的action,需要添加@wsgi.extends修饰
    @wsgi.extends
    def show(self, req, resp_obj, id):
        context = req.environ['nova.context']
        if soft_authorize(context):
            self._show(req, resp_obj)
    @wsgi.extends
    def detail(self, req, resp_obj):
        context = req.environ['nova.context']
        if 'servers' in resp_obj.obj and soft_authorize(context):
            resp_obj.attach(xml=ServersKeyNameTemplate())
            servers = resp_obj.obj['servers']
            self._add_key_name(req, servers)
#定义扩展资源对应的类,继承于ExtensionDescriptor,类名与文件名相同,只是首字母需大写
class Keypairs(extensions.ExtensionDescriptor):
    """Keypair Support."""
    #实现v2 API扩展资源必须定义4个变量name、alias、namespace、updated
    #alias必须保证唯一
    name = "Keypairs"
    alias = "os-keypairs"
    namespace = "http://docs.openstack.org/compute/ext/keypairs/api/v1.1";
    updated = "2011-08-08T00:00:00Z"
    #重载get_resources()创建新资源
    def get_resources(self):
        resources = []
        res = extensions.ResourceExtension(
                'os-keypairs',
                KeypairController())
        resources.append(res)
        return resources
     #对于扩展资源,需要重载get_controller_extensions(),并需要一个新的Controller,且该Controller继承于所扩展的核心资源的Controller
    def get_controller_extensions(self):
        controller = Controller(self.ext_mgr)
        extension = extensions.ControllerExtension(self, 'servers', controller)
        return [extension]
如果新的扩展资源除了扩展核心资源之外,还定义了新的独立资源,则需要定义自己专属的Controller,比如KeypairController,并实现一些基本的CRUD操作,比如index、show、create、delete等。

二 修改核心资源的代码
新增一个扩展资源后,通常需要修改核心资源的实现去处理扩展资源引入的参数。比如新增扩展资源keypairs之后,核心资源servers的create操作需要添加如下处理:
    # optional openstack extensions:
    key_name = None
    if self.ext_mgr.is_loaded('os-keypairs'):
        key_name = server_dict.get('key_name')
往往需要修改核心资源代码扩展资源才能够工作,这也是v2 API框架缺点之一。

三 当前V2 API存在的问题如下:
The development of the Nova v3 API will give us the opportunity to rework the extension framework. The current framework suffers from:
1 extension specific code required to exist in core code for specific extensions to work
eg nova/api/openstack/compute/servers.py:Controller:create where there are hard coded references to parameters specific to extensions to pass kwargs to the server create call
2 issues around efficiency with extensions each doing their own db lookup loops
3 Can’t have CamelCase class names for extension classes due to extension loading mechanism
第一个问题主要指当前的extension机制中,增加一个contrib后,往往需要在所谓的“core code”中添加必要的参数处理来将extension中引入的参数传入到内部的API中。需要注意的是这里的core code指的是nova.api.openstack.compute.*,即仅仅指的是API层次中核心资源相关的API Handlers,并非指的是各个Module内部的API/RPCAPI->Manager->Driver的代码层次结构中的代码。
第二个问题,在上文的bugs链接中已经描述的比较清楚,以servers为例,问题主要是指在GET等方法中,各个extension的处理逻辑中往往需要往返回的server信息中追加extension相关的信息,如disk_config扩展需要追加存储在DB中的disk config相关的信息等,故在各个extension中均会分别进行数据库查询操作,从而导致性能问题。
不过从目前HAVANA的代码来看,此问题已经通过一种方法缓解了,但从commit来看,和V3 API并不属于同一系列的提交。以servers为例,此问题现在的解决办法是,在core API处理时,就将可能需要从db中读取出来的servers相关的信息全部一次性读取出来并放入Cache中的Instance对象,在各个extension处理时只需要从Cache中取出所需的属性即可。在core API中一次性读出的信息除了instances表中一些extension添加的字段外,还会读出关联的instance_metadata、instance_system_metadata等多个表的信息。具体可参考nova.db.sqlalchemy.api:instance_get等相关的方法实现。
第三个问题是关于扩展资源的命名,v2 API中不能使用骆驼命名法,比如对于扩展资源Server Group,v2中命名为
Class Server_groups(extensions.ExtensionsDescriptor):
而v3中为
Class ServerGroups(extensions.V3APIExtensionBase):
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值