之前我们看过了core plugin, service plugin 还有resource extension。

resource extension的作用是定义新的资源。而我们说过还有两种extension: action extension 跟 request extension。这一章我们将写一个action extension。

action in RESTful

openstack中所有的网络服务都是RESTful风格的。但RESTful风格的URL有一个问题,如何表示动作。

像 network,tiger 这些单词都是名词,用在URL中以HTTP的POST/GET/DELETE/PUT来对应create get delete update没有任何问题。但有的时候我们需要在url中表示一些动词。比如,router是一个名词,但router中添加一个端口是一个动词。这时候我们有三种选择:

把增加端口变成update router的一个分支功能

这是一个好办法,但很多时候由于种种原因并不适用,比如这需要修改原来的update逻辑,需要修改原来的router数据结构,可能这个动作及其复杂,把它放入update不合适等等等等

把这个动作变成一个独立的资源

比如原来的url是api/v2/routers, 但现在我们用下面的URL表示这个动作

api/v2/routers/{router id}/add_router_interface

这个方法也很不错。事实上,neutron中大多数情况下都是用的这个方法。不过,如果这么做的话,动作变成了资源,那么就不用action extension而用resource extension了。所以这种方法不是我们这里要讨论的

用一个action资源来处理所有的动作

比如原来的url是api/v2/routers,现在我们用下面的url

api/v2/routers/action POST

既然是POST 那么肯定有body, body可能是

'{"add_router_interface":"some value"}'

这样就可以通过一个action url处理所有的动作请求了。这正是neutron action extension所做的事。

不过,奇妙的是,搜索遍了neutron的代码,没有看到一个功能是用这种extension来实现的。也许neutron正在努力用第二种方式替代第三种方式。

write action extension

虽然neutron中没有用这种extension,但它还是支持的。并且我们也很有必要了解这种extension,因为在neutron的启动加载过程中会尝试处理它,如果我们不了解,那么看到了这种代码会很懵

之前我们写过一个zoo plugin和zoo extension。并且实现了一个tiger资源。这里我们写一个action extension来为tiger增加一个动作:eat_wolf。

要实现action extension非常简单,只需要提供get_actions函数如下

from neutron.api import extensions
from neutron.api.v2 import attributes
from neutron.api.v2 import base
from neutron import manager
from neutron.api.v2 import resource_helper
from neutron.plugins.common import constants EXT_PREFIX = '/zoo'
RESOURCE_NAME = 'tiger'
COLLECTION_NAME = '%ss' % RESOURCE_NAME RESOURCE_ATTRIBUTE_MAP = {
'tiger': {
'id': {'allow_post': False, 'allow_put': False,
'validate': {'type:uuid': None},
'is_visible': True,
'primary_key': True},
'name': {'allow_post': True,
'allow_put': False,
'is_visible': True,
'default': ''},
# tenant_id is the user id used by keystone for authorisation
# It's good to use the following as it is and it is necessary
# for every extension
'tenant_id': {'allow_post': True, 'allow_put': False,
'required_by_policy': True,
'validate': {'type:string': None},
'is_visible': True} }
} class Zoo(extensions.ExtensionDescriptor):
# path_prefix = "zoo"
@classmethod
def get_name(cls):
return "zoo" @classmethod
def get_alias(cls):
return 'zoo' @classmethod
def get_description(cls):
return "zoo" @classmethod
def get_updated(cls):
return "2017-02-08T10:00:00-00:00" @classmethod
def get_resources(cls):
# This method registers the URL and the dictionary of
# attributes on the neutron-server.
exts = list()
plugin = manager.NeutronManager.get_service_plugins()['ZOO']
resource_name = RESOURCE_NAME
collection_name = COLLECTION_NAME
params = RESOURCE_ATTRIBUTE_MAP.get(resource_name)
controller = base.create_resource(collection_name, resource_name,
plugin, params, allow_bulk=False)
ex = extensions.ResourceExtension(collection_name, controller, path_prefix=EXT_PREFIX)
exts.append(ex)
return exts def get_actions(self):
eat_wolf_action = extensions.ActionExtension('tigers', 'eat_wolf', self._eat_wolf_handler)
return [eat_wolf_action] def _eat_wolf_handler(self, *args, **kwargs):
return 'The tiger eat a wolf'

我们这里贴出了所有的代码。但实际上只需要 get_action函数和 _eat_wolf_handler函数。实现了第一个函数就是action extension,第二个函数只是为了处理action的逻辑。重启neutron server后我们访问一下

curl -g -i -X POST http://liberty-controller01:9696/v2.0/tigers/40/action -H "Content-Type: application/json" -H "Accept: application/json" -H "X-Auth-Token: $token" -d '{"eat_wolf": "0730d3b8-9f1a-47e4-8d8b-365aef954160"}'
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 20
X-Openstack-Request-Id: req-d28c6e78-d8da-49fe-8fe8-deaac591a076
Date: Thu, 09 Feb 2017 09:58:36 GMT The tiger eat a wolf

OK, 上面就是我们的action extension了

how to read openstack code: action extension的更多相关文章

  1. how to read openstack code: request extension

    We have learned resource extension and action extension. This post we will write a request extension ...

  2. how to read openstack code: Core plugin and resource extension

    本章我们将写一个自己的core plugin 和一个resource extension来加深理解.(阅读本文的前提是你已经理解了restful以及stevedore等内容) 什么是 core plu ...

  3. how to read openstack code: loading process

    之前我们了解了neutron的结构,plugin 和 extension等信息.这一章我们看一下neutron如何加载这些plugin和extension.也就是neutron的启动过程.本文涉及的代 ...

  4. how to read openstack code: service plugin

    We have learned core plugin, service plugin and extension in last post. Now let`s review: Core Plugi ...

  5. how to read openstack code: Neutron architecture

    今天这一章节非常重要.我们知道neutron是一个非常复杂的系统,由很多组件构成.研究这样一个复杂的系统,正确的顺序应该是现在宏观上对其整体结构有所了解,然后再由针对性的对其组件进行深入了解.本章要做 ...

  6. how to read openstack code

    本文的目的不是介绍openstack.我们这里假设你已经知道了openstack是什么,能够做什么.所以目的是介绍如何阅读openstack的代码.通过读代码来进一步学习openstack. 转载要求 ...

  7. iOS - Action Extension

    上一篇<iOS开发 之 Share Extension>介绍了分享扩展的开发与使用,本篇主要还是讲述在系统分享菜单中最底下一栏的功能扩展:Action Extension,该扩展跟Shar ...

  8. action extension添加图标

    最近在做ios的action extension,这里记录一下添加图标的方法. 在Action Extension的target里面的Build Settings,里面的Asset Catalog C ...

  9. how to read openstack code : routes

    When coding a web system, you have to think about an important problem, how to map urls to logic. Op ...

随机推荐

  1. 作为一个iOS Developer 为什么我不用Swift?

    1.开始 在去年这个时候接手了一个iOS项目,项目主用Swift语言进行开发,对于部分第三方Objective C开源库则使用bridge的方式进行调用 当时项目的规模大概是不超过15个页面,功能也比 ...

  2. Android中单选框RadioButton的基本用法

    总结一下设置图标的三种方式: (1)button属性:主要用于图标大小要求不高,间隔要求也不高的场合. (2)background属性:主要用于能够以较大空间显示图标的场合. (3)drawableL ...

  3. vue 组件名和方法名 重名了,报function错误

    vue 组件名和方法名 重名了,报function错误

  4. android 解密工具

    androguard. 这个是python写的 安装: pip install androguard

  5. ES6 export default 和 export 的区别

    export default 和 export 区别: 1.export与export default均可用于导出常量.函数.文件.模块等 2.你可以在其它文件或模块中通过import+(常量 | 函 ...

  6. C++构造函数(复制构造函数)、析构函数

    注:若类中没有显示的写如下函数,编译会自动生成:默认复制构造函数.默认赋值构造函数(浅拷贝).默认=运算符重载函数(浅拷贝).析构函数: 1.默认构造函数(默认值)构造函数的作用:初始化对象的数据成员 ...

  7. source 1.7 中不支持 lambda 表达式(请使用 -source 8 或更高版本以启用 lambda 表达式)

    from:http://blog.csdn.net/qwdafedv/article/details/54691740 https://www.youtube.com/watch?v=oXxijdf8 ...

  8. luogu 3004 宝箱

    题目游戏的加强版,建议先去A掉(双倍经验),数据范围比较大,所以我们不能想原来那样开二维数组来储存,所以我们必须压维,现在我们重新定义状态,一维数组dp[i]表示以i开头的最优拿法. 做法:枚举每一种 ...

  9. OpenJudge-百练-2755

    这道题用递归写的话还是很好写的,我们设递归函数的名称为Ways(w,k) . 它的含义就是,w的大小,取k个物品,有多少种方式. 我们可以知道递归的边界条件就是当w的大小为0的时候,我们的方法数只有一 ...

  10. zabbix 3.4安装

    一.server安装 [root@zabbix ~]# cat /etc/redhat-release CentOS Linux release (Core) [root@zabbix ~]# una ...