searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

为Neutron添加新的Plugin

2023-11-06 03:00:58
72
0

neutron添加plugin和extensions


  neutron中plugin通常会绑定一个extension,用于实现资源的创建,controller的构建等。plugin分为core和service两种类型,core由openstack配置,主要为network、port、subnet、sbunetpool;我们构建通常为service_plugin。
  core_plugin在neutron/plugins/ml2中,service_plugin在neutron/services/** 中。
 

一. 为neutron添加plugin识别


  在neutron中,想要加载自己构建的service_plugin,有两种添加形式:
    1. 第一种是在neutron/plugins/common/constant.py中DEFAULT_SERVICE_PLUGINS添加自己构建的plugin名。
    2. 第二种是在/etc/neutron/neutron.conf种的service_plugin添加自己构建的plugin名。
  具体举例如下:
# Maps default service plugins entry points to their extension aliases
DEFAULT_SERVICE_PLUGINS = {
    'auto_allocate': 'auto-allocated-topology',
    'tag': 'tag',
    'timestamp': 'timestamp',
    'network_ip_availability': 'network-ip-availability',
    'flavors': 'flavors',
    'revisions': 'revisions',
    'peering':'peering',    #添加的plugin名
}
 

二. 在neutron中添加plugin定义


  这里主要是让neutron知道我们定义的名字是什么,同时定义plugin的resource_map。
这一部分的定义在/usr/local/lib/python3.10/dist-packages/neutron_lib/api/definitions/中,添加peering.py的定义文件。
# peering.py

from neutron_lib.api import converters
   
PEERING = 'peering'
SERVICE_PROFILES = 'service_profiles'
NEXT_PROVIDERS = 'next_providers'
PEERINGS = 'peerings'
ALIAS = 'peering'
NAME = 'Neutron Service Peerings'
DESCRIPTION = 'peering speification for Neutron advance services'
API_PREFIX = ''
UPDATED_TIMESTAMP = '2022-12-19T10:00:00-00:00'
RESOURCE_ATTRIBUTE_MAP = {
    'peerings' : {
        'id': {'allow_post': False, 'allow_put': False,
               'validate': {'type:uuid': None},
               'is_visible': True, 'primary_key': True},
        'name': {'allow_post': True, 'allow_put': True,
                 'default': '', 'is_visible': True},
        'description': {'allow_post': True, 'allow_put': True,
                        'default': '', 'is_visible': True},
        'tenant_id': {'allow_post': True, 'allow_put': False,
                      'is_visible': False, 'default': False},
        'accept_network_id': {'allow_post': True, 'allow_put': False,
                              'is_visible': True},
        'accept_network_name': {'allow_post': True, 'allow_put': False,
                                'is_visible': True, 'default': ''},
        'accept_tenant_id': {'allow_post': True, 'allow_put': False,
                             'is_visible': True},
        'request_network_id': {'allow_post': True, 'allow_put': False,
                               'is_visible': True},
        'request_network_name': {'allow_post': True, 'allow_put': False,
                                 'is_visible': True, 'default': ''},
        'request_tenant_id': {'allow_post': True, 'allow_put': False,
                              'is_visible': True},
        'network_type': {'allow_post': False, 'allow_put': False,
                         'is_visible': True},
        'physical_network': {'allow_post': False, 'allow_put': False,
                             'is_visible': True, 'default': ''},
        'segmentation_id': {'allow_post': False, 'allow_put': False,
                            'is_visible': True},
    }
}
SUB_RESOURCE_ATTRIBUTE_MAP = {}

ACTION_MAP = {}
REQUIRED_EXTENSIONS = {}
OPTIONAL_EXTENSIONS = {}
ACTION_STATUS = {}

 

三. 编写plugin文件


  plugin文件需要在/neutron/services/目录下新建plugin目录,这里的新建的目录为/peering。
在/peering目录下需要实现plugin文件和init文件,init文件可以为空,plugin文件实现如下:
#peering_plugin.py

from oslo_config import cfg
from oslo_log import log as logging
from oslo_serialization import jsonutils
from oslo_utils import uuidutils

from neutron.extensions import peering
from neutron_lib.plugins import directory


LOG = logging.getLogger(__name__)

class PeeringPlugin(peering.PeeringPluginBase):
    
    supported_extension_aliases = ['peering']

    def __init__(self):
        super(PeeringPlugin, self).__init__()
        LOG.info('init PeeringPlugin')
        #self.type_manager = directory.get_plugin('CORE').type_manager

    def get_plugin_description(self):
        return "peering plugin------------------------------"

    def get_plugin_type(cls):
        return 'peering'
     
    def _format_peering_dict_from_db(self):
        peering_resp_dict = {
            'id': '123',
            'name': "peering_test",
            'description': "peering test"
        }
        return peering_resp_dict

    def get_peerings(self,context,filters=None,fields=None):
        LOG.info("get_peerings")
        peering_resp = [self._format_peering_dict_from_db()]
        #return peering_resp
        return {}
         

    def get_peering(self,context,id,fields=None):
        LOG.info("get_peering")
        return self._format_peering_dict_from_db()

    def create_peering(self,context,peering):
        peering = peering['peering']
        peering_id = uuidutils-generate_uuid()
        peering['id'] = peering_id
        LOG.info("create_peering")
        return self._format_peering_dict_from_db()

    def update_peering(self,context,id,peering):
        LOG.info("update_peering")
        return self._format_peering_dict_from_db()

    def delete_peering(self,context,id):
        LOG.info("delete_peering")
        return
  1. PeeringPlugin继承了PeeringPluginBase类,该类定义了PeeringPlugin需要实现的基础的增删改查方法类型,基类在extension文件中定义。
 
  1. get_peerings方法不能直接return,返回空会导致api请求无资源,最少返回一个空的字典{}
 
  1. plugin的功能放在extension中实现,再通过supported_extension_aliases 绑定对应的extension。

 

四. 编写extension文件


  该文件主要实现了plugin的资源创建,以及定义了plugin的基类。实现如下:
 peering.py

import abc
import itertools
import re

from neutron_lib.api import extensions as api_extensions
from neutron_lib.api.definitions import peering as apidef
from neutron_lib.plugins import constants
from neutron_lib.plugins import directory
from neutron_lib.services import base as service_base
import six

from neutron.api import extensions
from neutron.api.v2 import base
from neutron.api.v2 import resource_helper

class Peering(api_extensions.APIExtensionDescriptor):
    
    api_definition = apidef    
    @classmethod
    def get_name(cls):
        return 'peering'

    @classmethod
    def get_alias(cls):
        return 'peering'

    @classmethod
    def get_description(cls):
        return 'The peering request extension.'

    @classmethod
    def get_namespace(cls):
        return '****://docs.openstack.org/ext/agent/api/v2.0'

    @classmethod
    def get_update(cls):
        return '2022-12-12T10:00:00:00-00:00'

    @classmethod
    def get_plugin_interface(cls):
        return PeeringPluginBase

    @classmethod
    def get_resources(cls):
        
        plural_mappings = resource_helper.build_plural_mappings(
                {},apidef.RESOURCE_ATTRIBUTE_MAP)
        resources = resource_helper.build_resource_info(
                plural_mappings,
                apidef.RESOURCE_ATTRIBUTE_MAP,
                'peering')
        return resources

@six.add_metaclass(abc.ABCMeta)
class PeeringPluginBase(service_base.ServicePluginBase):


    path_prefix = ''
    
    @classmethod
    def get_plugin_type(cls):
        return 'peering'

    def get_plugin_description(self):
        return 'Peering Service Plugin'

    @abc.abstractmethod
    def get_peerings(self,context,filters=None,fields=None):
        pass

    @abc.abstractmethod
    def get_peering(self,context,id,fields=None):
        pass
    
    @abc.abstractmethod
    def create_peering(self,context,peering):
        pass

    @abc.abstractmethod
    def update_peering(self,context,id,peering):
        pass

    @abc.abstractmethod
    def delete_peering(self,context,id):
        pass
  1. 实现资源创建和功能的类Peering继承自api_extensions.APIExtensionDescriptor实现了必要的方法,最重要的实现了get_resources方法,该方法创建mapping映射以及resource。
 
  1. PeeringPluginBase继承自service_base.ServicePluginBase,主要定义了一个plugin应该实现的类。

 

五. 为neutron添加plugin入口


  最后一部分,为peering添加plugin的入口,这样在api请求来的时候,controller知道从哪里去构建对象。该部分代码位于:/neutron/neutron.egg-info/entry_points.txt中,增加的代码如下:
# entry_points.txt

peering = neutron.services.peering.peering_plugin:PeeringPlugin

0条评论
0 / 1000
卢****锋
3文章数
0粉丝数
卢****锋
3 文章 | 0 粉丝
卢****锋
3文章数
0粉丝数
卢****锋
3 文章 | 0 粉丝
原创

为Neutron添加新的Plugin

2023-11-06 03:00:58
72
0

neutron添加plugin和extensions


  neutron中plugin通常会绑定一个extension,用于实现资源的创建,controller的构建等。plugin分为core和service两种类型,core由openstack配置,主要为network、port、subnet、sbunetpool;我们构建通常为service_plugin。
  core_plugin在neutron/plugins/ml2中,service_plugin在neutron/services/** 中。
 

一. 为neutron添加plugin识别


  在neutron中,想要加载自己构建的service_plugin,有两种添加形式:
    1. 第一种是在neutron/plugins/common/constant.py中DEFAULT_SERVICE_PLUGINS添加自己构建的plugin名。
    2. 第二种是在/etc/neutron/neutron.conf种的service_plugin添加自己构建的plugin名。
  具体举例如下:
# Maps default service plugins entry points to their extension aliases
DEFAULT_SERVICE_PLUGINS = {
    'auto_allocate': 'auto-allocated-topology',
    'tag': 'tag',
    'timestamp': 'timestamp',
    'network_ip_availability': 'network-ip-availability',
    'flavors': 'flavors',
    'revisions': 'revisions',
    'peering':'peering',    #添加的plugin名
}
 

二. 在neutron中添加plugin定义


  这里主要是让neutron知道我们定义的名字是什么,同时定义plugin的resource_map。
这一部分的定义在/usr/local/lib/python3.10/dist-packages/neutron_lib/api/definitions/中,添加peering.py的定义文件。
# peering.py

from neutron_lib.api import converters
   
PEERING = 'peering'
SERVICE_PROFILES = 'service_profiles'
NEXT_PROVIDERS = 'next_providers'
PEERINGS = 'peerings'
ALIAS = 'peering'
NAME = 'Neutron Service Peerings'
DESCRIPTION = 'peering speification for Neutron advance services'
API_PREFIX = ''
UPDATED_TIMESTAMP = '2022-12-19T10:00:00-00:00'
RESOURCE_ATTRIBUTE_MAP = {
    'peerings' : {
        'id': {'allow_post': False, 'allow_put': False,
               'validate': {'type:uuid': None},
               'is_visible': True, 'primary_key': True},
        'name': {'allow_post': True, 'allow_put': True,
                 'default': '', 'is_visible': True},
        'description': {'allow_post': True, 'allow_put': True,
                        'default': '', 'is_visible': True},
        'tenant_id': {'allow_post': True, 'allow_put': False,
                      'is_visible': False, 'default': False},
        'accept_network_id': {'allow_post': True, 'allow_put': False,
                              'is_visible': True},
        'accept_network_name': {'allow_post': True, 'allow_put': False,
                                'is_visible': True, 'default': ''},
        'accept_tenant_id': {'allow_post': True, 'allow_put': False,
                             'is_visible': True},
        'request_network_id': {'allow_post': True, 'allow_put': False,
                               'is_visible': True},
        'request_network_name': {'allow_post': True, 'allow_put': False,
                                 'is_visible': True, 'default': ''},
        'request_tenant_id': {'allow_post': True, 'allow_put': False,
                              'is_visible': True},
        'network_type': {'allow_post': False, 'allow_put': False,
                         'is_visible': True},
        'physical_network': {'allow_post': False, 'allow_put': False,
                             'is_visible': True, 'default': ''},
        'segmentation_id': {'allow_post': False, 'allow_put': False,
                            'is_visible': True},
    }
}
SUB_RESOURCE_ATTRIBUTE_MAP = {}

ACTION_MAP = {}
REQUIRED_EXTENSIONS = {}
OPTIONAL_EXTENSIONS = {}
ACTION_STATUS = {}

 

三. 编写plugin文件


  plugin文件需要在/neutron/services/目录下新建plugin目录,这里的新建的目录为/peering。
在/peering目录下需要实现plugin文件和init文件,init文件可以为空,plugin文件实现如下:
#peering_plugin.py

from oslo_config import cfg
from oslo_log import log as logging
from oslo_serialization import jsonutils
from oslo_utils import uuidutils

from neutron.extensions import peering
from neutron_lib.plugins import directory


LOG = logging.getLogger(__name__)

class PeeringPlugin(peering.PeeringPluginBase):
    
    supported_extension_aliases = ['peering']

    def __init__(self):
        super(PeeringPlugin, self).__init__()
        LOG.info('init PeeringPlugin')
        #self.type_manager = directory.get_plugin('CORE').type_manager

    def get_plugin_description(self):
        return "peering plugin------------------------------"

    def get_plugin_type(cls):
        return 'peering'
     
    def _format_peering_dict_from_db(self):
        peering_resp_dict = {
            'id': '123',
            'name': "peering_test",
            'description': "peering test"
        }
        return peering_resp_dict

    def get_peerings(self,context,filters=None,fields=None):
        LOG.info("get_peerings")
        peering_resp = [self._format_peering_dict_from_db()]
        #return peering_resp
        return {}
         

    def get_peering(self,context,id,fields=None):
        LOG.info("get_peering")
        return self._format_peering_dict_from_db()

    def create_peering(self,context,peering):
        peering = peering['peering']
        peering_id = uuidutils-generate_uuid()
        peering['id'] = peering_id
        LOG.info("create_peering")
        return self._format_peering_dict_from_db()

    def update_peering(self,context,id,peering):
        LOG.info("update_peering")
        return self._format_peering_dict_from_db()

    def delete_peering(self,context,id):
        LOG.info("delete_peering")
        return
  1. PeeringPlugin继承了PeeringPluginBase类,该类定义了PeeringPlugin需要实现的基础的增删改查方法类型,基类在extension文件中定义。
 
  1. get_peerings方法不能直接return,返回空会导致api请求无资源,最少返回一个空的字典{}
 
  1. plugin的功能放在extension中实现,再通过supported_extension_aliases 绑定对应的extension。

 

四. 编写extension文件


  该文件主要实现了plugin的资源创建,以及定义了plugin的基类。实现如下:
 peering.py

import abc
import itertools
import re

from neutron_lib.api import extensions as api_extensions
from neutron_lib.api.definitions import peering as apidef
from neutron_lib.plugins import constants
from neutron_lib.plugins import directory
from neutron_lib.services import base as service_base
import six

from neutron.api import extensions
from neutron.api.v2 import base
from neutron.api.v2 import resource_helper

class Peering(api_extensions.APIExtensionDescriptor):
    
    api_definition = apidef    
    @classmethod
    def get_name(cls):
        return 'peering'

    @classmethod
    def get_alias(cls):
        return 'peering'

    @classmethod
    def get_description(cls):
        return 'The peering request extension.'

    @classmethod
    def get_namespace(cls):
        return '****://docs.openstack.org/ext/agent/api/v2.0'

    @classmethod
    def get_update(cls):
        return '2022-12-12T10:00:00:00-00:00'

    @classmethod
    def get_plugin_interface(cls):
        return PeeringPluginBase

    @classmethod
    def get_resources(cls):
        
        plural_mappings = resource_helper.build_plural_mappings(
                {},apidef.RESOURCE_ATTRIBUTE_MAP)
        resources = resource_helper.build_resource_info(
                plural_mappings,
                apidef.RESOURCE_ATTRIBUTE_MAP,
                'peering')
        return resources

@six.add_metaclass(abc.ABCMeta)
class PeeringPluginBase(service_base.ServicePluginBase):


    path_prefix = ''
    
    @classmethod
    def get_plugin_type(cls):
        return 'peering'

    def get_plugin_description(self):
        return 'Peering Service Plugin'

    @abc.abstractmethod
    def get_peerings(self,context,filters=None,fields=None):
        pass

    @abc.abstractmethod
    def get_peering(self,context,id,fields=None):
        pass
    
    @abc.abstractmethod
    def create_peering(self,context,peering):
        pass

    @abc.abstractmethod
    def update_peering(self,context,id,peering):
        pass

    @abc.abstractmethod
    def delete_peering(self,context,id):
        pass
  1. 实现资源创建和功能的类Peering继承自api_extensions.APIExtensionDescriptor实现了必要的方法,最重要的实现了get_resources方法,该方法创建mapping映射以及resource。
 
  1. PeeringPluginBase继承自service_base.ServicePluginBase,主要定义了一个plugin应该实现的类。

 

五. 为neutron添加plugin入口


  最后一部分,为peering添加plugin的入口,这样在api请求来的时候,controller知道从哪里去构建对象。该部分代码位于:/neutron/neutron.egg-info/entry_points.txt中,增加的代码如下:
# entry_points.txt

peering = neutron.services.peering.peering_plugin:PeeringPlugin

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0