前两篇文章讨论了怎么写一个 Neutron 的插件。但是最基本的插件只包括 Network, Port,和 Subnet 三种资源。如果需要引入新的资源,比如一个二层的 gateway 的话,就需要在插件的基础上再写一个 extension, 也就是扩展。

Neutron 已经预定义了很多扩展,可以参看 neutron/extensions 下面的文件,我在这里就不一一列举了。如果正好有一种是你需要的,那直接拿过来用就好了。如果需要自己从头搭起的话,可以现在 自己的 plugin 文件夹下面创建一个 extensions 文件夹,然后在这个文件夹下面创建两个文件: __init__.py 和 myextension.py:

- neutron/

  - plugins/

    - myplugin/

      - __init__.py

      - plugin.py

      - extensions/

        - __init__.py

        - myextension.py

__init__.py 是空的就行了。在 myextension.py 中需要定义两个东西:一个叫RESOURCE_ATTRIBUTE_MAP 的词典和一个叫 Myextension 的类。RESOURCE_ATTRIBUTE_MAP里面放的就是你的这个新扩展的属性,例如:

RESOURCE_ATTRIBUTE_MAP = {
'myextensions': {
'id': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'name': {'allow_post': True, 'allow_put': True,
'is_visible': True},
'tenant_id': {'allow_post': True, 'allow_put': False,
'validate': {'type:string': None},
'required_by_policy': True,
'is_visible': True}
}
}

需要注意的是在词典中,第一层的 key ‘myextensions’ 就是文件名 ’myextension‘ 加上一个 ‘s'。第二层的 keys ’id‘, ’name‘, ’tenant_id‘ 就是这个扩展的三个属性。第三层的 keys 在 neutron/api/v2/attributes.py 中有比较详细的解释,我把它搬到这里来了:

# The following is a short reference for understanding attribute info:
# default: default value of the attribute (if missing, the attribute
# becomes mandatory.
# allow_post: the attribute can be used on POST requests.
# allow_put: the attribute can be used on PUT requests.
# validate: specifies rules for validating data in the attribute.
# convert_to: transformation to apply to the value before it is returned
# is_visible: the attribute is returned in GET responses.
# required_by_policy: the attribute is required by the policy engine and
# should therefore be filled by the API layer even if not present in
# request body.
# enforce_policy: the attribute is actively part of the policy enforcing
# mechanism, ie: there might be rules which refer to this attribute.

定义新类的时候需要注意一点,这个类的名字与包含这个类的文件名的唯一区别必须是一个首字母大写,另一个首字母小写。也就是说把MyExtension当做类的名字可能就会导致出错。具体原因可以参考 neutron/api/extensions.py 中 ExtensionManager 的_load_all_extensions_from_path 方法的实现。Myextension 这个类可以继承 neutron/api/extensions.py 这个文件中的一个类:ExtensionDescriptor,也可以自己定义。下面给出一个继承了该类的定义:

from neutron.api import extensions
from neutron import manager
from neutron.api.v2 import base
class Myextension(extensions.ExtensionDescriptor):
# The name of this class should be the same as the file name
# The first letter must be changed from lower case to upper case
# There are a couple of methods and their properties defined in the
# parent class of this class, ExtensionDescriptor you can check them @classmethod
def get_name(cls):
# You can coin a name for this extension
return "My Extension" @classmethod
def get_alias(cls):
# This alias will be used by your core_plugin class to load
# the extension
return "my-extensions" @classmethod
def get_description(cls):
# A small description about this extension
return "An extension defined by myself. Haha!" @classmethod
def get_namespace(cls):
# The XML namespace for this extension
return "http://docs.openstack.org/ext/myextension/api/v1.0" @classmethod
def get_updated(cls):
# Specify when was this extension last updated,
# good for management when there are changes in the design
return "2014-08-07T00:00:00-00:00" @classmethod
def get_resources(cls):
# This method registers the URL and the dictionary of
# attributes on the neutron-server.
exts = []
plugin = manager.NeutronManager.get_plugin()
resource_name = 'myextension'
collection_name = '%ss' % resource_name
params = RESOURCE_ATTRIBUTE_MAP.get(collection_name, dict())
controller = base.create_resource(collection_name, resource_name,
plugin, params, allow_bulk=False)
ex = extensions.ResourceExtension(collection_name, controller)
exts.append(ex)
return exts

到这一步为止,这个 myextension.py 文件基本就算是大功告成了,接下来需要去配置 /etc/neutron/neutron.conf 文件,告诉 Neutron 去哪里找到这个扩展。那么在该文件的[DEFAULT]下面,我们可以找到一个选项叫做api_extensions_path,并且把刚刚创建的 extensions 文件夹的位置赋给它,例如:

api_extensions_path = /usr/lib/python2.7/dist-packages/neutron/plugins/myplugin/extensions

然后在自己的 MyPlugin 类的定义中还要加一句话,告诉 Neutron 我的插件支持这个扩展。需要注意的是这里的方括号中的名字应该与上面 get_alias() 方法获得的名字一致。

class MyPlugin(db_base_plugin_v2.NeutronDbPluginV2):
  ...
  supported_extension_aliases = ['my-extensions']
  
  def __init__(self):
    ...
  ...

最后重启一下 neutron server, “service neutron-server restart”, 如果看到 /var/log/neutron/server.log 里面有 Loaded extension: my-extensions 的字样就说明成功了。

在接下来的一些文章中,我会继续讨论一下如何实现一个扩展的不同操作,如何在 CLI 中加入对自定义扩展的命令支持等内容。

怎样写 OpenStack Neutron 的 Extension (一)的更多相关文章

  1. 怎样写 OpenStack Neutron 的 Extension (四)

    上文说到需要在 /neutronclient/v2_0/myextension/extension.py 中分别定义五个 class:List/Show/Create/Delete/UpdateExt ...

  2. 怎样写 OpenStack Neutron 的 Extension (三)

    通过上几章的介绍,我们现在的 myplugin 文件夹看上去应该是这样的: - neutron/ - plugins/ - myplugin/ - __init__.py - plugin.py - ...

  3. 怎样写 OpenStack Neutron 的 Extension (二)

    接着之前一篇文章,再来谈谈 Extension 的具体实现问题.我使用的是本地数据库加远程API调用的方法,所以先要定义一下数据库中 myextension 如何存储.首先,我们可以在自己的 plug ...

  4. 怎样写 OpenStack Neutron 的 Plugin (二)

    其实上一篇博文中的内容已经涵盖了大部分写Neutron插件的技术问题,这里主要还遗留了一些有关插件的具体实现的问题. 首先,Neutron对最基本的三个资源:Network, Port 和 Subne ...

  5. 怎样写 OpenStack Neutron 的 Plugin (一)

    鉴于不知道Neutron的人也不会看这篇文章,而知道的人也不用我再啰嗦Neutron是什么东西,我决定跳过Neutron简介,直接爆料. 首先要介绍一下我的开发环境.我没有使用DevStack,而是直 ...

  6. OpenStack Neutron 之 Load Balance

    OpenStack Neutron 之 Load Balance 负载均衡(Load Balance)是 OpenStack Neutron 支持的功能之一.负载均衡能够将网络请求分发到多个实际处理请 ...

  7. how to read openstack code: action extension

    之前我们看过了core plugin, service plugin 还有resource extension. resource extension的作用是定义新的资源.而我们说过还有两种exten ...

  8. [转]OpenStack Neutron运行机制解析概要

    转载自:http://panpei.net.cn/2013/12/04/openstack-neutron-mechanism-introduce/ 自从开学以来,玩OpenStack也已经3个月了, ...

  9. [转]OpenStack Neutron解析

    1.为什么还需要linux bridge的部署方式? 2.哪一个网桥起着交换机的作用? 3.neutron如何实现私有网络的隔离 =================================== ...

随机推荐

  1. linux配置文件的一些调优

    Linux中所有东西都是文件,一个socket就对应着一个文件描述符,因此系统配置的最大打开文件数以及单个进程能够打开的最大文件数就决定了socket的数目上限:但是linux是有文件句柄限制的,而且 ...

  2. oracle-删除归档日志

    rman target user/password; DELETE ARCHIVELOG ALL COMPLETED BEFORE 'SYSDATE-7';

  3. hibernate一对多映射实现

    Junit4方法详解 setUpBeforeClass()类初始化前调用 tearDownAfterClass()类初始化后调用 setUp()在测试方法前调用 tearDown()在测试方法后调用 ...

  4. Golang 实现简单的滚动读取文本更新

    这个小程序要实现的效果,简单地说,就是将目标文件的内容读取输出到终端,并且目标文件并不是静态的,而是随时会添加新的内容.我们的目标就是一旦目标文件添加了新的内容,就把它读取出来并且显示到终端上. 实现 ...

  5. shell script 学习笔记-----if,for,while,case语句

    1.if内的判断条件为逻辑运算: 2.if内的判断条件为目录是否存在,文件是否存在,下图先检验目录/home/monster是否存在,然后再检测/home/monster中的file.txt文件是否存 ...

  6. 【读书笔记《Android游戏编程之从零开始》】5.Android 游戏开发常用的系统控件(ProgressBar、Seekbar)

    3.7 ProgressBar ProgressBar类官方文档地址:http://developer.android.com/reference/android/widget/ProgressBar ...

  7. hdu-5920 Ugly Problem(贪心+高精度)

    题目链接: Ugly Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Other ...

  8. 网页中插入FLASH(swf文件),并且让Flash不遮挡HTML元素

    一:网页中插入flash代码如下:  当然里面的很多属性可以去掉,根据具体的需求而定.  我们在网页中经常遇到播放flash,要正常播放flash就要用到OBJECT和EMBED这两个标签.鉴于火狐及 ...

  9. npm install时报错 npm ERR!Windows_NT 6.1.7601

    解决办法:先设置代理为空 npm config set proxy null, 然后再npm install cnpm -g --registry=https://registry.npm.taoba ...

  10. AS3声音录音

    MicRecorder, a tiny microphone library http://www.bytearray.org/?p=1858