OpenStack : Nova API 分析

来源:互联网 发布:sql日期时间格式转换 编辑:程序博客网 时间:2024/05/16 12:47

    Author: tianst  

     Note:本博客只是没事闲扯蛋,加深记忆,对读者产生错误的引导概不负责!谢谢! 欢迎指正错误之处,一定及时修改。


     Nova API 是Nova对外的接口,虚拟机的所有执行的动作都要经过API接口来执行,目前Nova 支持 Amazon EC2 API 和Openstack API 两种,实现的功能都是一样的。本节主要讲述Openstack  API(通常称为Nova API), 在OpenStack 中为dasboard 提供前端的Web Service服务。是基于WSGI 的 RESTful Web API

     在Juno版本的初期,共存着V2和V3两个版本的API,V2是对外发布的版本,已经使用很长时间了,由于API的特殊性,对兼容性要求比较高,所以API接口返回的数据结构,变量名称是不能修改的,导致一些bug没法直接在V2版本中修改,在这种情况下社区新增V3的版本,V3 不但修改了V2的一些bug,还对API plugin 的管理做了些优化,不幸的是V3在Icehouse版本中没能如期发布就夭折了,经过社区的激烈讨论,主要围绕向前的兼容型,你不能要求使用OpenStack的发行商升级之后要重写他们的管理软件,这对已经大规模部署的公司来说是灾难性的。经过在Icehouse社区大会的讨论,决定基V2和V3版本实现一个V2.1版本的API,V2.1架构和代码是基于V3的,但是向前兼容V2版本,用户可以通过代码中开关来决定是否返回V2版本格式的数据。在写本节内容的时候,社区对V2.1还没有达成一致的意见,还没合入一个patch,所以本节以V3版本为基础。

      目前V3 API 只支持JSON格式的数据,在2014的除夕夜我和社区的core们一起将XML的支持剔除掉了,主要原因有两个,一是Nova API对XML的解析做的不好,重新引入pecan改动太大,二是core们觉得没人用XML,JSON的格式更易用。所以Sean Dague 提出之后,很快得到Nova core们的认同。

      Nova API 是属于RESTful API的类型。使用python 语言的WSGI的架构,基于Python Paste来构建的。

      RESTful AP 是一个使用HTTP并遵循REST原则的Web服务。它从以下三个方面资源进行定义:

        1.直观简短的资源地址:URI,比如:http://example.com/resources/。

        2.传输的资源:Web服务接受与返回的互联网媒体类型,比如:JSONXML ,YAML 等。

        3.对资源的操作:Web服务在该资源上所支持的一系列请求方法(比如:POST,GET,PUT或DELETE)。

      在nova/etc/nova/目录下的 api-paste.ini配置文件是实现API的核心,WSGI、Python Paste这部分知识属于python的内容,这里不再此介绍

   [app:osapi_compute_app_v3]   paste.app_factory =nova.api.openstack.compute:APIRouterV3.factory

    从上面的配置项来看,API 的Route 的map工作都是APIRouterV3类有来完成。也就是构建资源与URL直接的映射关系,完成从接收到URL请求然后映射到具体的函数上执行的整个过程。V3 所有API 都在plugin 都在目录nova\api\openstack\compute\plugins\v3下面,在openstack中实现一个API 有两种情况,一是增加一个新的资源,二是扩展原有的某个资源的一个动作。 本章内容主要是聚焦在openstack的里面,很多关于高级python架构和应用的不想在此介绍,我们还是来实现一个API的例子来聚焦在openstack中吧。

    我们来一步一步的来实现一个API的例子,这个例子需要完成两个目标,一是实现一个新的资源,二是扩展原有的资源的动作,比如当在你的主机的hypervisor 加入你自己的标识,执行nova hypervisor-show 可以看到这台host的具体参数,但是你还希望在里面加入一个特定的参数,来标识这个host是你部署的。

    首先,请使用devstack部署好你的openstack 环境,在nova\api\openstack\compute\plugins\v3下面增加一个intel_openstack.py:

  1 from nova.api.openstack import extensions  2 from nova.api.openstack import wsgi  3  4  5 ALIAS = 'intel'  6  7 class IntelHypervisorController(wsgi.Controller):  8     @wsgi.extends  9     def detail(self, req, resp_obj): 10         hypervisors = list(resp_obj.obj['hypervisors']) 11         for hypervisor in hypervisors: 12             hypervisor["intel"] = "intel otc openstack team " 13 14 class IntelController(object): 15 16     @extensions.expected_errors(404) 17     def show(self, req, id): 18         result = {'intel_cup': 2, 19                 'intel_pci': 1, 20                 'intel_openstack': "ok"  } 21         return dict(intel=result) 22 23 24 class Intel(extensions.V3APIExtensionBase): 25     """intel openstack.""" 26     name = "intel" 27     alias = ALIAS 28     version = 1 29 30     def get_resources(self): 31         resources = [extensions.ResourceExtension(ALIAS, 32                      IntelController(), 33                      collection_actions={'detail': 'GET'})] 34         return resources 35 36     def get_controller_extensions(self): 37         hypersion_extension = extensions.ControllerExtension( 38             self, 'os-hypervisors', IntelHypervisorController()) 39         return [hypersion_extension]

要想让这个plugin 工作还需要在nova/setup.cfg中加入一个键值,让API初始化的时候加载你的plugin:

56 nova.api.v3.extensions =97     intel = nova.api.openstack.compute.plugins.v3.intel_openstack:Intel

   在/opt/stack/nova 下执行python setup.py egg_info 和 sudo python setup.py install 重新安装一下Nova的服务,由于我们只修改了Nova API, 所以只需重启一下nova-api 的服务是修改生效。

怎么验证新加的完成两个目标呢,一是获取hypervisor 信息时里面包含了“intel”这个键值,二是怎加一个新的资源,这个资源和一个特定的URL对应,当使用这个URL的时候就可以得到一个包含intel信息的字典。为了使用nova hypervisor-show的命令需要简单介绍一下Novaclient,它是一个python的脚本用来实现命令行和URL的对应,主要方便开发人员和维护人员使用。 如果要使用它,你需要在你的devstack目录下执行 source openrc admin 命令。Novaclient的源码在/opt/stack/python-novaclient 目录下,目前默认是对应V2版本的API, 如果使用V3版本的API 需要修改一下/opt/stack/python-novaclient/novaclient/shell.py配置项:

<span style="font-family:SimSun;font-size:18px;"><span style="font-size:14px;">  DEFAULT_OS_COMPUTE_API_VERSION= "3"</span></span>

现在就可以使用了: 在笔者的环境下:

 

       可以看在返回的结构中已经包含“intel”的键值了。上面实现一个对nova/api/openstack/compute/plugins/v3/hypervisors.py的detail 的action的扩展,其实就是在hypervisors 的detail函数返回的字典中再加入“intel”这个键值。这和在hypervisors 的detail函数加入这个值是一样的,Nova API 之所以推荐这么做,主要是为增加API的灵活性,如果一个不同的部署者可以根据不同的需求编写自己的APIplugin,在setup.cfg中灵活配置,也可以在nova/etc/policy.json中为不同API配置使用不同的权限。

    再来看看怎么验证新加的资源,由于只实现了show(), 这个函数对应于nova *-show命令,但是由于我们没有编写novaclient去实现用命令生成URL,所以无法直接使用命令行,先来看看“nova –debug flavor –show 1” 会去生成什么样的URL, 使用nova –debug flavor –show 1得到如下的细节:

<span style="font-family:SimSun;font-size:18px;"><span style="font-size:14px;">curl-i 'http://10.239.37.55:8774/v3/flavors/1' -X GET -H "X-Auth-Project-Id:demo" -H "User-Agent: python-novaclient" -H "Accept:application/json" -H "X-Auth-Token: MIIQQwYJKoZIhvcNAQcCoIIQNDCCEDACAQExCTAHBgUrDgMCGjCCDpkGCSqGSIb3DQEHAaCCDooEgg6GeyJhY2Nlc3MiOiB7InRva2VuIjogeyJpc3N1ZWRfYXQiOiAiMjAxNC0wNy0wOVQwNjowMzoxMC4xODM4N……….."</span></span>

   可以看出首先会先获得一个key,这个key是keystore服务生成,是openstack的安全机制,然后就是URL是 'http://10.239.37.55:8774/v3/flavors'这个是flavor的资源的URL,”/1”是指show()函数要传入的id参数,可以参照这个推断出新加的资源的URL 应该是'http://10.239.37.55:8774/v3/intel/1', 将nova flavor-show 1 的curl项复制一份,URL改成想要的即可得到下面的结果

 

 

    在V3版本的API中,每个plugin都需要一个继承了extensions.V3APIExtensionBase的类,并且实现两个函数get_resources() 和get_controller_extensions(),在API初始化的时候,后在nova.api.openstack.compute:APIRouterV3 基类会调用这两个函数完成资源某项动作和URL直接的映射关系。 当有HTTP请求,会根据URL的解析到某个函数。

    Nova api 中还有一些policy机制,来限制某些用户(例如非admin用户)的操作, 其实这些rules就是字符串的比较,更多详细的信息,请看nova/etc/nova/policy.json 文件。

关于WSGI 和python高级应用不在此介绍,读者Google之,这边只是记录怎样在openstack 中怎加一项修改,增加一个resource或是一个extension

0 0
原创粉丝点击