怎样写 OpenStack Neutron 的 Extension (一)

前两篇文章讨论了怎么写一个 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 extensionsfrom neutron import managerfrom 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 (一)

时间: 2024-10-13 17:05:13

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

怎样写 OpenStack Neutron 的 Extension (四)

上文说到需要在 /neutronclient/v2_0/myextension/extension.py 中分别定义五个 class:List/Show/Create/Delete/UpdateExtension.具体形式如下: import argparse import logging from neutronclient.neutron import v2_0 as neutronV20 from neutronclient.openstack.common.gettextutils im

怎样写 OpenStack Neutron 的 Extension (三)

通过上几章的介绍,我们现在的 myplugin 文件夹看上去应该是这样的: - neutron/ - plugins/ - myplugin/ - __init__.py - plugin.py - extensions/ - __init__.py - myextension.py - db/ - __init__.py - db.py - models.py 我们的plugin.py看上去应该是类似这样的: from neutron import neutron_plugin_base_v2

怎样写 OpenStack Neutron 的 Extension (二)

接着之前一篇文章,再来谈谈 Extension 的具体实现问题.我使用的是本地数据库加远程API调用的方法,所以先要定义一下数据库中 myextension 如何存储.首先,我们可以在自己的 plugin 根目录下新建一个 db 文件夹,以及三个文件: - neutron/ - plugins/ - myplugin/ - __init__.py - plugin.py - extensions/ - db/ - __init__.py - db.py - models.py db.py 用来存

怎样写 OpenStack Neutron 的 Plugin (二)

其实上一篇博文中的内容已经涵盖了大部分写Neutron插件的技术问题,这里主要还遗留了一些有关插件的具体实现的问题. 首先,Neutron对最基本的三个资源:Network, Port 和 Subnet 的基本调用都已经定义好了API接口.如果你的插件也需要用到这些资源,最好直接实现它们的接口.API接口的定义可以再 neutron/neutron_plugin_base_v2.py 这个文件中找到,其中每个参数的作用也有比较详细的介绍.对于用不着的资源,直接放任不管就好了,最多下次不小心调用了

怎样写 OpenStack Neutron 的 Plugin (一)

鉴于不知道Neutron的人也不会看这篇文章,而知道的人也不用我再啰嗦Neutron是什么东西,我决定跳过Neutron简介,直接爆料. 首先要介绍一下我的开发环境.我没有使用DevStack,而是直接在电脑上安装了三个Virtual Box,然后根据OpenStack的Ubuntu 安装指南部署了一个环境:一个控制节点,一个网络节点和一个计算节点.接下来我会直接在控制节点上修改 <your path>/neutron/ 下面的文件,然后通过重启neutron 的各个service来更新我的修

如何区分 OpenStack Neutron Extension 和 Plugin

Neutron 里面的 extension 和 plugin 是非常相似的两个概念,我花了好久才貌似搞懂了两者的区别,还不一定完全正确. 在OpenStack 的官网wiki中,可以找到它们两个的定义: Plugin: Neutron exposes a logical API to define network connectivity between devices from other OpenStack services (e.g., vNICs from Nova VMs). The

OpenStack Neutron 之 Load Balance

OpenStack Neutron 之 Load Balance 负载均衡(Load Balance)是 OpenStack Neutron 支持的功能之一.负载均衡能够将网络请求分发到多个实际处理请求的虚机上,这样能有效处理高流量的网络请求,负载均衡在现实中有很多使用场景.本文将基于 Neutron 所提供的负载均衡,介绍其基本概念.实现过程,并验证其功能. Neutron Load Balance 简介 负载均衡(Load Balance)其实早在 OpenStack 的 Grizzly 版

带着问题了解Openstack Neutron安全组

本文是由最近一个Openstack Neutron安全组的问题所触发而写.希望之后借此机会深入探讨一下iptables和netfilter相关用法.原理等. 本节先看看网络问题的解决思路以及Openstack Neutron安全组,之后再开篇细讲背后的网络内核netfilter. 问题简述 公司系统部同事为业务部门创建lvs服务时,Linux Director与Real Server间无法进行正常的通讯,Real Server是由Hulk平台创建的openstack虚拟机. 网络问题排查,按照"

openstack neutron L3 HA

作者:Liping Mao  发表于:2014-08-20 版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 最近Assaf Muller写了一篇关于Neutron L3 HA的文章很不错. 建议看原文,地址如下: http://assafmuller.wordpress.com/category/ml2/ 大致翻译如下: L3 Agent Low Availability(L3 agent的低可用性) 目前,在Openstack中,你只能用多个网络节点达到