自己动手写OpenStack的QoS功能(2)

本文地址:http://blog.csdn.net/spch2008/article/details/9281947


在/usr/share/pyshared/quantum/plugins/openvswitch/ 下创建新包extensions,然后将其连接到/usr/lib/python2.7/dist-packages/quantum/plugins/openvswitch下。

在extensions下创建ovsqos.py,同样需要进行软连接。具体可参见Quantum 数据库增加新表 

1. 首先,处理资源属性映射,其实就是对属性进行一些限制。  

def convert_to_unsigned_int_or_none(val):
    if val is None:
        return
    try:
        val = int(val)
        if val < 0:
            raise ValueError
    except (ValueError, TypeError):
        msg = _("'%s' must be a non negative integer.") % val
        raise qexception.InvalidInput(error_message=msg)
    return val


# Attribute Map
RESOURCE_ATTRIBUTE_MAP = {
    'ovsqoss': {
        'id': {'allow_post': False, 'allow_put': False,
               'is_visible': True,
               'primary_key': True},
        'name': {'allow_post': True, 'allow_put': True,
                 'is_visible': True, 'default': '',
                 'validate': {'type:string': None}},
        'rate': {'allow_post': True, 'allow_put': True,
                'is_visible': True, 'default': '0',
                'convert_to': convert_to_unsigned_int_or_none},
        'burst': {'allow_post': True, 'allow_put': True,
                'is_visible': True, 'default': '0',
                'convert_to': convert_to_unsigned_int_or_none},
        'tenant_id': {'allow_post': True, 'allow_put': False,
                      'required_by_policy': True,
                      'validate': {'type:string': None},
                      'is_visible': True},
    }
}
  convert_to_unsigned_int_or_none将属性值转换成整形。

  RESOURCE_ATTRIBUTE_MAP对属性进行制约; allow_put 是否允许用户进行修改,即update; allow_post是否通过用户传来数值进行填充,比如id,

  此值为false,如果用户提交过来的数据中有id值,则出错,也就是说id由系统进行分配,不由用户指定;is_visible该属性是否对用户可见,若为false,

  用户看不到该值。


2. 同理,qos是port的一个属性,对qos也进行一些限制

OVSQOS = 'ovsqoss'
EXTENDED_ATTRIBUTES_2_0 = {
    'ports': {OVSQOS: {'allow_post': True,
                               'allow_put': True,
                               'is_visible': True,
                               'default': attr.ATTR_NOT_SPECIFIED}}}

用户通过quantum port-list, port-update等命令对端口进行修改的时候,ovsqos这个属性是否可以修改,对用户可见等。


3. 最重要的一个类

   注意:类名必须与文件同名,且首字母大写。

class Ovsqos(object):

    @classmethod
    def get_name(cls):
        return "ovsqos"

    @classmethod
    def get_alias(cls):
        return "ovsqos"

    @classmethod
    def get_description(cls):
        return "OVS QoS extension."

    @classmethod
    def get_namespace(cls):
        return "http://blog.csdn.net/spch2008"

    @classmethod
    def get_updated(cls):
        return "2013-06-05T10:00:00-00:00"

    @classmethod
    def get_resources(cls):
        """ Returns Ext Resources """
        exts = []
        plugin = manager.QuantumManager.get_plugin()
        resource_name = 'ovsqos'
        collection_name = resource_name.replace('_', '-') + "s"
        params = RESOURCE_ATTRIBUTE_MAP.get(resource_name + "s", 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

    def get_extended_resources(self, version):
        if version == "2.0":
            return EXTENDED_ATTRIBUTES_2_0
        else:
            return {}

  • get_extended_resources取得扩展属性,然后实际上报告给了(quantum\api\v2\router.py)中的APIRouter的

                 __init__的ext_mgr.extend_resources("2.0",  attributes.RESOURCE_ATTRIBUTE_MAP)

  • get_resources 取得资源,用于后续创建路由条目
  • get_alias返回一个别名,这个名字很重要。需要在ovs_quantum_plguin.py的OVSQuantumPluginV2属性_supported_extension_aliases

             加入该别名            

supported_extension_aliases = ["provider", "router", "ovsqos"]

4. quantum\extensions\extensions.py文件的最末尾

     def get_extensions_path() 用于取得扩展功能文件,原代码必须使用绝对路径,但是配置文档中给的是相对路径,不一致。

     遂将其改为相对路径,代码如下:   

def get_extensions_path():
    #spch
    paths = ':'.join(quantum.extensions.__path__)
    
    #get the prefix path
    prefix = "/".join(quantum.__path__[0].split("/")[:-1])
      
    if cfg.CONF.api_extensions_path:
        #split the api_extensions_path by ":"
        ext_paths = cfg.CONF.api_extensions_path.split(":")
        #add prefix for each path
        for i in range(len(ext_paths)):
            ext_paths[i] = prefix + ext_paths[i]
        
        ext_paths.append(paths)
        paths = ":".join(ext_paths)
    
    return paths

5. 将扩展功能写入配置文件中,使得OpenStack系统可以加载qos功能

    quantum.conf 中: 

api_extensions_path = /quantum/plugins/openvswitch/extensions

 完整代码如下:

'''
Created on 2013-6-5

@author: spch2008
'''


from abc import abstractmethod
from quantum.api.v2 import attributes as attr
from quantum.api.v2 import base
from quantum.extensions import extensions
from quantum.common import exceptions as qexception
from quantum import manager
import logging

LOG = logging.getLogger(__name__)


def convert_to_unsigned_int_or_none(val):
    if val is None:
        return
    try:
        val = int(val)
        if val < 0:
            raise ValueError
    except (ValueError, TypeError):
        msg = _("'%s' must be a non negative integer.") % val
        raise qexception.InvalidInput(error_message=msg)
    return val


# Attribute Map
RESOURCE_ATTRIBUTE_MAP = {
    'ovsqoss': {
        'id': {'allow_post': False, 'allow_put': False,
               'is_visible': True,
               'primary_key': True},
        'name': {'allow_post': True, 'allow_put': True,
                 'is_visible': True, 'default': '',
                 'validate': {'type:string': None}},
        'rate': {'allow_post': True, 'allow_put': True,
                'is_visible': True, 'default': '0',
                'convert_to': convert_to_unsigned_int_or_none},
        'burst': {'allow_post': True, 'allow_put': True,
                'is_visible': True, 'default': '0',
                'convert_to': convert_to_unsigned_int_or_none},
        'tenant_id': {'allow_post': True, 'allow_put': False,
                      'required_by_policy': True,
                      'validate': {'type:string': None},
                      'is_visible': True},
    }
}

OVSQOS = 'ovsqoss'
EXTENDED_ATTRIBUTES_2_0 = {
    'ports': {OVSQOS: {'allow_post': True,
                               'allow_put': True,
                               'is_visible': True,
                               'default': attr.ATTR_NOT_SPECIFIED}}}


class Ovsqos(object):

    @classmethod
    def get_name(cls):
        return "ovsqos"

    @classmethod
    def get_alias(cls):
        return "ovsqos"

    @classmethod
    def get_description(cls):
        return "OVS QoS extension."

    @classmethod
    def get_namespace(cls):
        return "http://blog.csdn.net/spch2008"

    @classmethod
    def get_updated(cls):
        return "2013-06-05T10:00:00-00:00"

    @classmethod
    def get_resources(cls):
        """ Returns Ext Resources """
        exts = []
        plugin = manager.QuantumManager.get_plugin()
        resource_name = 'ovsqos'
        collection_name = resource_name.replace('_', '-') + "s"
        params = RESOURCE_ATTRIBUTE_MAP.get(resource_name + "s", 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

    def get_extended_resources(self, version):
        if version == "2.0":
            return EXTENDED_ATTRIBUTES_2_0
        else:
            return {}

class OVSPluginBase(object):
    @abstractmethod
    def create_ovsqos(self, context, ovsqos):
        pass

    @abstractmethod
    def get_ovsqoss(self, context, filters, fields):
        pass

    @abstractmethod
    def get_ovsqos(self, context, rule_id, fields):
        pass

    @abstractmethod
    def delete_ovsqos(self, context, rule_id):
        pass

    @abstractmethod
    def update_ovsqos(self, context, rule_id, ovsqos):
        pass




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值