之前我们看过了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表示这个动作

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

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

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

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

  1. api/v2/routers/action POST

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

  1. '{"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函数如下

  1. from neutron.api import extensions
  2. from neutron.api.v2 import attributes
  3. from neutron.api.v2 import base
  4. from neutron import manager
  5. from neutron.api.v2 import resource_helper
  6. from neutron.plugins.common import constants
  7. EXT_PREFIX = '/zoo'
  8. RESOURCE_NAME = 'tiger'
  9. COLLECTION_NAME = '%ss' % RESOURCE_NAME
  10. RESOURCE_ATTRIBUTE_MAP = {
  11. 'tiger': {
  12. 'id': {'allow_post': False, 'allow_put': False,
  13. 'validate': {'type:uuid': None},
  14. 'is_visible': True,
  15. 'primary_key': True},
  16. 'name': {'allow_post': True,
  17. 'allow_put': False,
  18. 'is_visible': True,
  19. 'default': ''},
  20. # tenant_id is the user id used by keystone for authorisation
  21. # It's good to use the following as it is and it is necessary
  22. # for every extension
  23. 'tenant_id': {'allow_post': True, 'allow_put': False,
  24. 'required_by_policy': True,
  25. 'validate': {'type:string': None},
  26. 'is_visible': True}
  27. }
  28. }
  29. class Zoo(extensions.ExtensionDescriptor):
  30. # path_prefix = "zoo"
  31. @classmethod
  32. def get_name(cls):
  33. return "zoo"
  34. @classmethod
  35. def get_alias(cls):
  36. return 'zoo'
  37. @classmethod
  38. def get_description(cls):
  39. return "zoo"
  40. @classmethod
  41. def get_updated(cls):
  42. return "2017-02-08T10:00:00-00:00"
  43. @classmethod
  44. def get_resources(cls):
  45. # This method registers the URL and the dictionary of
  46. # attributes on the neutron-server.
  47. exts = list()
  48. plugin = manager.NeutronManager.get_service_plugins()['ZOO']
  49. resource_name = RESOURCE_NAME
  50. collection_name = COLLECTION_NAME
  51. params = RESOURCE_ATTRIBUTE_MAP.get(resource_name)
  52. controller = base.create_resource(collection_name, resource_name,
  53. plugin, params, allow_bulk=False)
  54. ex = extensions.ResourceExtension(collection_name, controller, path_prefix=EXT_PREFIX)
  55. exts.append(ex)
  56. return exts
  57. def get_actions(self):
  58. eat_wolf_action = extensions.ActionExtension('tigers', 'eat_wolf', self._eat_wolf_handler)
  59. return [eat_wolf_action]
  60. def _eat_wolf_handler(self, *args, **kwargs):
  61. return 'The tiger eat a wolf'

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

  1. 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"}'
  2. HTTP/1.1 200 OK
  3. Content-Type: text/html; charset=UTF-8
  4. Content-Length: 20
  5. X-Openstack-Request-Id: req-d28c6e78-d8da-49fe-8fe8-deaac591a076
  6. Date: Thu, 09 Feb 2017 09:58:36 GMT
  7. 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. 手把手教你免费把网站IP换成1.1.1.1/1.0.0.1

    近日,Cloudflare官方发文,与APNIC官方合作打算用IP1.1.1.1推出速度更快.私密性更强的DNS Cloudflare 运行全球规模最大.速度最快的网络之一. APNIC 是一个非营利 ...

  2. java生成随机字符

    1.生成的字符串每个位置都有可能是str中的一个字母或数字,需要导入的包是import java.util.Random; //length用户要求产生字符串的长度 public static Str ...

  3. vue.js中的表单radio,select,textarea的v-model属性的用法

    只要是表单元素,其值已经不会再用value来定义了,但是placeholder还是可以用来设置默认值. section1--input:type="text" type=" ...

  4. Intel CPU参数查询网站

    链接:https://ark.intel.com/#@Processors

  5. CreateProcess相关

    CreateProcess不创建窗口执行: https://blog.csdn.net/rongwenbin/article/details/24422041 CreateProcess返回值: 执行 ...

  6. Ubuntu 和 centos7 服务的启动

    Ubuntu 下: /etc/init.d/nginx  start | stop | reload Centos7下: service nginx start | stop | reload

  7. CSS3---渲染属性

    1.计数器 CSS3计数器( CSS Counters )可以允许我们使用css对页面中的任意元素进行计数,实现类似于有序列表的功能.与有序列表相比,它的突出特性在于可以对任意元素计数,同时实现个性化 ...

  8. 【HDU 6008】Worried School(模拟)

    Problem Description You may already know that how the World Finals slots are distributed in EC sub-r ...

  9. python基础——5(元组、字典、集合)

    上节复习: # 数字类型 # int:py3|py2  long:py2 # float: 3.14 # complex(5, 4) => 5 + 4j num = 12345678901234 ...

  10. 了解DOM

    DOM是为了方便处理层次型文档(如XML.HTML)的一种技术.DOM还提供了一套API,使开发人员可以用面向对象的方式来处理这些文档.对于XML文档来说,有专门的处理XML文档是XML  DOM,一 ...