Use bgp api-def from neutron-lib

As neutron-dynamic-routing is a Neutron stadium project the api-def
and the api-ref should be in neutron-lib.

Change-Id: Idccc69f025a0d1ec0453d13a7d81b94e3a15149d
Depends-On: https://review.opendev.org/c/openstack/neutron-lib/+/788322
This commit is contained in:
elajkat 2021-04-29 15:34:30 +02:00 committed by Lajos Katona
parent 7245c228c2
commit c021b106d9
10 changed files with 56 additions and 711 deletions

View File

@ -25,467 +25,5 @@
API
===
Introduction
------------
Neutron dynamic routing project adds the support for dynamic routing protocols
in neutron. Using the ReST interface, a cloud administrator can define routing
peers and advertise neutron routes outside the OpenStack domain.
.. note::
Currently, only the support for BGP dynamic routing protocol is available.
Data Model
----------
New data models are defined for supporting routing protocols. Below models are defined for
different protocols.
BGP
~~~
BGP Speaker
+++++++++++
* ``id``
The uuid of BGP Speaker.
* ``name``
The name of BGP Speaker.
* ``local_as``
The local AS value, ranges from 1 to 65535.
* ``ip_version``
The ip address version for BGP Speaker. 4 by default.
* ``peers``
The remote peer connection which supports BGP.
* ``networks``
The tenant networks connected to the BGP Speaker.
* ``advertise_floating_ip_host_routes``
Whether to enable or disable the advertisement of floating ip host routes by
the BGP Speaker. True by default.
* ``advertise_tenant_networks``
Whether to enable or disable the advertisement of tenant network routes by
the BGP Speaker. True by default.
BGP Peer
++++++++
* ``id``
The uuid of BGP peer.
* ``name``
The name of BGP peer.
* ``peer_ip``
The IP address of BGP peer.
* ``remote_as``
The remote AS value, ranges from 1 to 65535.
* ``auth_type``
The authentication algorithm. Supported algorithms: none and md5, none by
default.
* ``password``
The authentication password for the specified authentication type.
ReST Interface
--------------
Different ReST interface are exposed for realizing different dynamic protocol
functionality.
.. note::
Only an administrator have the access to the exposed API's.
BGP
~~~
BGP Speaker
+++++++++++
Create
''''''
Issue a ``POST`` request to ``/v2.0/bgp-speakers`` with following JSON-encoded
data to create a BGP Speaker: ::
{
"bgp_speaker":{
"ip_version":4,
"local_as":"1000",
"name":"bgp-speaker"
}
}
Response body:
{
"bgp_speaker":{
"peers":[
],
"name":"bgp-speaker",
"tenant_id":"34a6e17a48cf414ebc890367bf42266b",
"local_as":1000,
"advertise_tenant_networks":true,
"networks":[
],
"ip_version":4,
"advertise_floating_ip_host_routes":true,
"id":"5e08db80-db77-4b5c-a56d-dbca0b284f2c"
}
}
Return code: 201
List
''''
Issue a ``GET`` request to ``/v2.0/bgp-speakers`` to retrieve this list of available
BGP Speakers. ::
Response body:
{
"bgp_speakers":[
{
"peers":[
],
"name":"bgp-speaker-1",
"tenant_id":"34a6e17a48cf414ebc890367bf42266b",
"local_as":1001,
"advertise_tenant_networks":true,
"networks":[
],
"ip_version":4,
"advertise_floating_ip_host_routes":true,
"id":"5e08db80-db77-4b5c-a56d-dbca0b284f2c"
},
{
"peers":[
],
"name":"bgp-speaker",
"tenant_id":"34a6e17a48cf414ebc890367bf42266b",
"local_as":1000,
"advertise_tenant_networks":true,
"networks":[
],
"ip_version":4,
"advertise_floating_ip_host_routes":true,
"id":"b759b2a1-27f4-4a6b-bb61-f2c9a22c9902"
}
]
}
Return code: 200
Show
''''
Issue a ``GET`` request to ``/v2.0/bgp-speakers/<bgp-speaker-id>`` to retrieve the
detail about a specific BGP Speaker. ::
Response body:
{
"bgp_speaker":{
"peers":[
],
"name":"bgp-speaker",
"tenant_id":"34a6e17a48cf414ebc890367bf42266b",
"local_as":1000,
"advertise_tenant_networks":true,
"networks":[
],
"ip_version":4,
"advertise_floating_ip_host_routes":true,
"id":"b759b2a1-27f4-4a6b-bb61-f2c9a22c9902"
}
}
Return code: 200
Update
''''''
Issue ``PUT`` request to ``/v2.0/bgp-speakers/<bgp-speaker-id>`` to update a
specific BGP Speaker. Following attributes can be updated.
* ``name``
The name of BGP Speaker.
* ``advertise_floating_ip_host_routes``
Whether to enable or disable the advertisement of floating ip host routes by
the BGP Speaker. True by default.
* ``advertise_tenant_networks``
Whether to enable or disable the advertisement of tenant network routes by
the BGP Speaker. True by default.
Delete
''''''
Issue ``DELETE`` request to ``/v2.0/bgp-speakers/<bgp-speaker-id>`` to delete
a specific BGP Speaker. ::
No response body
Return code: 204
BGP Peer
++++++++
Create
''''''
Issue a ``POST`` request to ``/v2.0/bgp-peers`` with following JSON-encoded data
to create a BGP peer: ::
{
"bgp_peer":{
"auth_type":"none",
"remote_as":"1001",
"name":"bgp-peer",
"peer_ip":"10.0.0.3"
}
}
Response body:
{
"bgp_peer":{
"auth_type":"none",
"remote_as":"1001",
"name":"bgp-peer",
"tenant_id":"34a6e17a48cf414ebc890367bf42266b",
"peer_ip":"10.0.0.3",
"id":"a7193581-a31c-4ea5-8218-b3052758461f"
}
}
Return code: 201
List
''''
Issue a ``GET`` request to ``/v2.0/bgp-peers`` to retrieve the list of available
BGP peers. ::
Response body:
{
"bgp_peers":[
{
"auth_type":"none",
"remote_as":1001,
"name":"bgp-peer",
"tenant_id":"34a6e17a48cf414ebc890367bf42266b",
"peer_ip":"10.0.0.3",
"id":"a7193581-a31c-4ea5-8218-b3052758461f"
}
]
}
Return code: 200
Show
''''
Issue a ``GET`` request to ``/v2.0/bgp-peers/<bgp-peer-id>`` to retrieve the detail about a
specific BGP peer. ::
Response body:
{
"bgp_peer":{
"auth_type":"none",
"remote_as":1001,
"name":"bgp-peer",
"tenant_id":"34a6e17a48cf414ebc890367bf42266b",
"peer_ip":"10.0.0.3",
"id":"a7193581-a31c-4ea5-8218-b3052758461f"
}
}
Return code: 200
Update
''''''
Issue ``PUT`` request to ``/v2.0/bgp-peers/<bgp-peer-id>`` to update
a specific BGP peer. Following attributes can be updated.
* ``name``
The name of BGP peer.
* ``password``
The authentication password.
Delete
''''''
Issue ``DELETE`` request to ``/v2.0/bgp-peers/<bgp-peer-id>`` to delete
a specific BGP peer. ::
No response body
Return code: 204
BGP Speaker and Peer binding
++++++++++++++++++++++++++++
Add BGP Peer to a BGP Speaker
'''''''''''''''''''''''''''''
Issue a ``PUT`` request to ``/v2.0/bgp-speakers/<bgp-speaker-id>/add-bgp-peer``
to bind the BGP peer to the specified BGP Seaker with following JSON-encoded data: ::
{
"bgp_peer_id":"a7193581-a31c-4ea5-8218-b3052758461f"
}
Response body: ::
{
"bgp_peer_id":"a7193581-a31c-4ea5-8218-b3052758461f"
}
Return code: 200
Remove BGP Peer from a BGP Speaker
''''''''''''''''''''''''''''''''''
Issue a ``DELETE`` request with following data to ``/v2.0/bgp-speakers/<bgp-speaker-id>/remove-bgp-peer``
to unbind the BGP peer: ::
{
"bgp_peer_id":"a7193581-a31c-4ea5-8218-b3052758461f"
}
No response body
Return code: 200
BGP Speaker and Network binding
+++++++++++++++++++++++++++++++
Add Network to a BGP Speaker
''''''''''''''''''''''''''''
Issue a ``PUT`` request with following data to ``/v2.0/bgp-speakers/<bgp-speaker-id>/add_gateway_network``
to add a network to the specified BGP speaker: ::
{
"network_id":"f2269b61-6755-4174-8f64-5e318617b204"
}
Response body:
{
"network_id":"f2269b61-6755-4174-8f64-5e318617b204"
}
Return code: 200
Delete Network from a BGP Speaker
'''''''''''''''''''''''''''''''''
Issue a ``DELETE`` request with following data to ``/v2.0/bgp-speakers/<bgp-speaker-id>/remove_gateway_network``
to delete a network from a specified BGP speaker. ::
No response body
Return code: 200
BGP Speaker Advertised Routes
+++++++++++++++++++++++++++++
List routes advertised by a BGP Speaker
'''''''''''''''''''''''''''''''''''''''
Issue ``GET`` request to ```/v2.0/bgp-speakers/<bgp-speaker-id>/get_advertised_routes``
to list all routes advertised by the specified BGP Speaker. ::
Response body:
{
"advertised_routes":[
{
"cidr":"192.168.10.0/24",
"nexthop":"10.0.0.1"
}
]
}
Return code: 200
BGP Speaker and Dynamic Routing Agent interaction
+++++++++++++++++++++++++++++++++++++++++++++++++
Add BGP Speaker to a Dynamic Routing Agent
''''''''''''''''''''''''''''''''''''''''''
Issue a ``POST`` request to ``/v2.0/agents/<bgp-agent-id>/bgp-drinstances`` to
add a BGP Speaker to the specified dynamic routing agent. The following is
the request body: ::
{
"bgp_speaker_id": "5639072c-49eb-480a-9f11-953386589bc8"
}
No response body
Return code: 201
List BGP speakers hosted by a Dynamic Routing Agent
'''''''''''''''''''''''''''''''''''''''''''''''''''
Issue a ``GET`` request to ``/v2.0/agents/<bgp-dragent-id>/bgp-drinstances`` to
list all BGP Seakers hosted on the specified dynamic routing agent. ::
Response body:
{
"bgp_speakers":[
{
"peers":[
],
"name":"bgp-speaker",
"tenant_id":"34a6e17a48cf414ebc890367bf42266b",
"local_as":1000,
"advertise_tenant_networks":true,
"networks":[
],
"ip_version":4,
"advertise_floating_ip_host_routes":true,
"id":"b759b2a1-27f4-4a6b-bb61-f2c9a22c9902"
}
]
}
Return code: 200
List Dynamic Routing Agents hosting a specific BGP Speaker
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Issue a ``GET`` request to ``/v2.0/bgp-speakers/<bgp-speaker-id>/bgp-dragents``
to list all BGP dynamic agents which are hosting the specified BGP Speaker. ::
Response body:
{
"agents":[
{
"binary":"neutron-bgp-dragent",
"description":null,
"admin_state_up":true,
"heartbeat_timestamp":"2016-05-17 03:05:12",
"availability_zone":null,
"alive":true,
"topic":"bgp_dragent",
"host":"yangyubj-virtual-machine",
"agent_type":"BGP dynamic routing agent",
"resource_versions":{
},
"created_at":"2016-05-09 07:38:00",
"started_at":"2016-05-11 09:06:13",
"id":"af216618-29d3-4ee7-acab-725bdc90e614",
"configurations":{
"advertise_routes":0,
"bgp_peers":0,
"bgp_speakers":1
}
}
]
}
Return code: 200
Delete BGP Speaker from a Dynamic Routing Agent
'''''''''''''''''''''''''''''''''''''''''''''''
Issue a ``DELETE`` request to ``/v2.0/agents/<bgp-agent-id>/bgp-drinstances/<bgp-speaker-id>``
to delete the BGP Speaker hosted by the specified dynamic routing agent. ::
No response body
Return code: 204
Reference
---------
None
The reference of the OpenStack neutron-dynamic-routing API is found at
https://docs.openstack.org/api-ref/network/#bgp-dynamic-routing.

View File

@ -13,11 +13,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from neutron_lib.api.definitions import bgp as bgp_ext
from neutron_lib.plugins import directory
import oslo_messaging
from neutron_dynamic_routing.extensions import bgp as bgp_ext
class BgpSpeakerRpcCallback(object):
"""BgpDrAgent RPC callback in plugin implementations.
@ -37,7 +36,7 @@ class BgpSpeakerRpcCallback(object):
@property
def plugin(self):
if not hasattr(self, '_plugin'):
self._plugin = directory.get_plugin(bgp_ext.BGP_EXT_ALIAS)
self._plugin = directory.get_plugin(bgp_ext.ALIAS)
return self._plugin
def get_bgp_speaker_info(self, context, bgp_speaker_id):

View File

@ -26,6 +26,7 @@ from neutron.objects import subnet as subnet_obj
from neutron.objects import subnetpool as subnetpool_obj
from neutron.plugins.ml2 import models as ml2_models
from neutron_lib.api.definitions import bgp as bgp_ext
from neutron_lib.api import validators
from neutron_lib import constants as lib_consts
from neutron_lib.db import api as db_api
@ -43,7 +44,7 @@ from sqlalchemy.orm import aliased
from sqlalchemy.orm import exc as sa_exc
from neutron_dynamic_routing._i18n import _
from neutron_dynamic_routing.extensions import bgp as bgp_ext
from neutron_dynamic_routing.extensions import bgp
DEVICE_OWNER_ROUTER_GW = lib_consts.DEVICE_OWNER_ROUTER_GW
@ -208,7 +209,7 @@ class BgpDbMixin(object):
bgp_speaker_id,
network_id)
except oslo_db_exc.DBDuplicateEntry:
raise bgp_ext.BgpSpeakerNetworkBindingError(
raise bgp.BgpSpeakerNetworkBindingError(
network_id=network_id,
bgp_speaker_id=bgp_speaker_id)
return {'network_id': network_id}
@ -231,7 +232,7 @@ class BgpDbMixin(object):
auth_type = ri.get('auth_type')
password = ri.get('password')
if auth_type == 'md5' and not password:
raise bgp_ext.InvalidBgpPeerMd5Authentication()
raise bgp.InvalidBgpPeerMd5Authentication()
with db_api.CONTEXT_WRITER.using(context):
res_keys = ['tenant_id', 'name', 'remote_as', 'peer_ip',
@ -276,7 +277,7 @@ class BgpDbMixin(object):
bgp_peer_db = self._get_bgp_peer(context, bgp_peer_id)
if ((bp.get('password') is not None) and
(bgp_peer_db['auth_type'] == 'none')):
raise bgp_ext.BgpPeerNotAuthenticated(bgp_peer_id=bgp_peer_id)
raise bgp.BgpPeerNotAuthenticated(bgp_peer_id=bgp_peer_id)
bgp_peer_db.update(bp)
bgp_peer_dict = self._make_bgp_peer_dict(bgp_peer_db)
@ -287,7 +288,7 @@ class BgpDbMixin(object):
return model_query.get_by_id(context, BgpSpeaker,
bgp_speaker_id)
except sa_exc.NoResultFound:
raise bgp_ext.BgpSpeakerNotFound(id=bgp_speaker_id)
raise bgp.BgpSpeakerNotFound(id=bgp_speaker_id)
def _get_bgp_speaker_ids_by_router(self, context, router_id):
with db_api.CONTEXT_READER.using(context):
@ -340,13 +341,13 @@ class BgpDbMixin(object):
bgp_speaker = model_query.get_by_id(context, BgpSpeaker,
bgp_speaker_id)
except sa_exc.NoResultFound:
raise bgp_ext.BgpSpeakerNotFound(id=bgp_speaker_id)
raise bgp.BgpSpeakerNotFound(id=bgp_speaker_id)
try:
bgp_peer = model_query.get_by_id(context, BgpPeer,
bgp_peer_id)
except sa_exc.NoResultFound:
raise bgp_ext.BgpPeerNotFound(id=bgp_peer_id)
raise bgp.BgpPeerNotFound(id=bgp_peer_id)
peers = self._get_bgp_peers_by_bgp_speaker_binding(context,
bgp_speaker_id)
@ -358,7 +359,7 @@ class BgpDbMixin(object):
def _validate_peer_ips(self, bgp_speaker_id, current_peers, new_peer):
for peer in current_peers:
if peer.peer_ip == new_peer.peer_ip:
raise bgp_ext.DuplicateBgpPeerIpException(
raise bgp.DuplicateBgpPeerIpException(
bgp_peer_id=new_peer.id,
peer_ip=new_peer.peer_ip,
bgp_speaker_id=bgp_speaker_id)
@ -372,7 +373,7 @@ class BgpDbMixin(object):
bgp_speaker_id,
bgp_peer_id)
except sa_exc.NoResultFound:
raise bgp_ext.BgpSpeakerPeerNotAssociated(
raise bgp.BgpSpeakerPeerNotAssociated(
bgp_peer_id=bgp_peer_id,
bgp_speaker_id=bgp_speaker_id)
context.session.delete(binding)
@ -386,7 +387,7 @@ class BgpDbMixin(object):
bgp_speaker = model_query.get_by_id(context, BgpSpeaker,
bgp_speaker_id)
except sa_exc.NoResultFound:
raise bgp_ext.BgpSpeakerNotFound(id=bgp_speaker_id)
raise bgp.BgpSpeakerNotFound(id=bgp_speaker_id)
try:
network = model_query.get_by_id(context, models_v2.Network,
@ -410,7 +411,7 @@ class BgpDbMixin(object):
bgp_speaker_id,
network_id)
except sa_exc.NoResultFound:
raise bgp_ext.BgpSpeakerNetworkNotAssociated(
raise bgp.BgpSpeakerNetworkNotAssociated(
network_id=network_id,
bgp_speaker_id=bgp_speaker_id)
context.session.delete(binding)
@ -433,7 +434,7 @@ class BgpDbMixin(object):
try:
return model_query.get_by_id(context, BgpPeer, bgp_peer_id)
except sa_exc.NoResultFound:
raise bgp_ext.BgpPeerNotFound(id=bgp_peer_id)
raise bgp.BgpPeerNotFound(id=bgp_peer_id)
def _get_bgp_speaker_peer_binding(self, context,
bgp_speaker_id, bgp_peer_id):

View File

@ -14,107 +14,13 @@
# limitations under the License.
#
from neutron_lib.api import converters as n_conv
from neutron_lib.api import extensions
from neutron_lib.db import constants as db_const
from neutron_lib.api.definitions import bgp as bgp_api_def
from neutron_lib.api import extensions as api_ext
from neutron_lib import exceptions as n_exc
from neutron.api.v2 import resource_helper as rh
from neutron_dynamic_routing._i18n import _
from neutron_dynamic_routing.services.bgp.common import constants as bgp_consts
BGP_EXT_ALIAS = 'bgp'
BGP_SPEAKER_RESOURCE_NAME = 'bgp-speaker'
BGP_SPEAKER_BODY_KEY_NAME = 'bgp_speaker'
BGP_PEER_BODY_KEY_NAME = 'bgp_peer'
RESOURCE_ATTRIBUTE_MAP = {
BGP_SPEAKER_RESOURCE_NAME + 's': {
'id': {'allow_post': False, 'allow_put': False,
'validate': {'type:uuid': None},
'is_visible': True, 'primary_key': True},
'name': {'allow_post': True, 'allow_put': True,
'validate': {'type:string': db_const.NAME_FIELD_SIZE},
'is_visible': True, 'default': ''},
'local_as': {'allow_post': True, 'allow_put': False,
'validate': {'type:range': (bgp_consts.MIN_ASNUM,
bgp_consts.MAX_ASNUM)},
'is_visible': True, 'default': None,
'required_by_policy': False,
'enforce_policy': False},
'ip_version': {'allow_post': True, 'allow_put': False,
'validate': {'type:values': [4, 6]},
'is_visible': True, 'default': None,
'required_by_policy': False,
'enforce_policy': False},
'tenant_id': {'allow_post': True, 'allow_put': False,
'required_by_policy': False,
'validate': {
'type:string': db_const.PROJECT_ID_FIELD_SIZE},
'is_visible': True},
'peers': {'allow_post': False, 'allow_put': False,
'validate': {'type:uuid_list': None},
'is_visible': True, 'default': [],
'required_by_policy': False,
'enforce_policy': True},
'networks': {'allow_post': False, 'allow_put': False,
'validate': {'type:uuid_list': None},
'is_visible': True, 'default': [],
'required_by_policy': False,
'enforce_policy': True},
'advertise_floating_ip_host_routes': {
'allow_post': True,
'allow_put': True,
'convert_to': n_conv.convert_to_boolean,
'validate': {'type:boolean': None},
'is_visible': True, 'default': True,
'required_by_policy': False,
'enforce_policy': True},
'advertise_tenant_networks': {
'allow_post': True,
'allow_put': True,
'convert_to': n_conv.convert_to_boolean,
'validate': {'type:boolean': None},
'is_visible': True, 'default': True,
'required_by_policy': False,
'enforce_policy': True},
},
'bgp-peers': {
'id': {'allow_post': False, 'allow_put': False,
'validate': {'type:uuid': None},
'is_visible': True, 'primary_key': True},
'name': {'allow_post': True, 'allow_put': True,
'validate': {'type:string': db_const.NAME_FIELD_SIZE},
'is_visible': True, 'default': ''},
'peer_ip': {'allow_post': True, 'allow_put': False,
'required_by_policy': True,
'validate': {'type:ip_address': None},
'is_visible': True},
'remote_as': {'allow_post': True, 'allow_put': False,
'validate': {'type:range': (bgp_consts.MIN_ASNUM,
bgp_consts.MAX_ASNUM)},
'is_visible': True, 'default': None,
'required_by_policy': False,
'enforce_policy': False},
'auth_type': {'allow_post': True, 'allow_put': False,
'required_by_policy': True,
'validate': {'type:values':
bgp_consts.SUPPORTED_AUTH_TYPES},
'is_visible': True},
'password': {'allow_post': True, 'allow_put': True,
'required_by_policy': True,
'validate': {'type:string_or_none': None},
'is_visible': False,
'default': None},
'tenant_id': {'allow_post': True, 'allow_put': False,
'required_by_policy': False,
'validate': {
'type:string': db_const.PROJECT_ID_FIELD_SIZE},
'is_visible': True}
}
}
# Dynamic Routing Exceptions
@ -164,48 +70,16 @@ class NetworkNotBoundForIpVersion(NetworkNotBound):
"BgpSpeaker.")
class Bgp(extensions.ExtensionDescriptor):
@classmethod
def get_name(cls):
return "Neutron BGP Dynamic Routing Extension"
@classmethod
def get_alias(cls):
return BGP_EXT_ALIAS
@classmethod
def get_description(cls):
return("Discover and advertise routes for Neutron prefixes "
"dynamically via BGP")
@classmethod
def get_updated(cls):
return "2016-05-10T15:37:00-00:00"
class Bgp(api_ext.APIExtensionDescriptor):
api_definition = bgp_api_def
@classmethod
def get_resources(cls):
plural_mappings = rh.build_plural_mappings(
{}, RESOURCE_ATTRIBUTE_MAP)
action_map = {BGP_SPEAKER_RESOURCE_NAME:
{'add_bgp_peer': 'PUT',
'remove_bgp_peer': 'PUT',
'add_gateway_network': 'PUT',
'remove_gateway_network': 'PUT',
'get_advertised_routes': 'GET'}}
{}, bgp_api_def.RESOURCE_ATTRIBUTE_MAP)
exts = rh.build_resource_info(plural_mappings,
RESOURCE_ATTRIBUTE_MAP,
BGP_EXT_ALIAS,
action_map=action_map)
bgp_api_def.RESOURCE_ATTRIBUTE_MAP,
bgp_api_def.ALIAS,
action_map=bgp_api_def.ACTION_MAP)
return exts
def get_extended_resources(self, version):
if version == "2.0":
return RESOURCE_ATTRIBUTE_MAP
else:
return {}
def update_attributes_map(self, attributes):
super(Bgp, self).update_attributes_map(
attributes, extension_attrs_map=RESOURCE_ATTRIBUTE_MAP)

View File

@ -10,63 +10,12 @@
# License for the specific language governing permissions and limitations
# under the License.
from neutron_lib.api.definitions import bgp_4byte_asn as api_def
from neutron_lib.api import extensions as api_extensions
from neutron_dynamic_routing.extensions import bgp as bgp_ext
from neutron_dynamic_routing.services.bgp.common import constants as bgp_consts
BGP_4BYTE_ASN_EXT_ALIAS = 'bgp_4byte_asn'
RESOURCE_ATTRIBUTE_MAP = {
'bgp-speakers': {
'local_as': {'allow_post': True, 'allow_put': False,
'validate': {'type:range': (bgp_consts.MIN_ASNUM,
bgp_consts.MAX_4BYTE_ASNUM)},
'is_visible': True, 'default': None,
'required_by_policy': False,
'enforce_policy': False}
},
'bgp-peers': {
'remote_as': {'allow_post': True, 'allow_put': False,
'validate': {'type:range': (bgp_consts.MIN_ASNUM,
bgp_consts.MAX_4BYTE_ASNUM)},
'is_visible': True, 'default': None,
'required_by_policy': False,
'enforce_policy': False}
}
}
class Bgp_4byte_asn(api_extensions.ExtensionDescriptor):
class Bgp_4byte_asn(api_extensions.APIExtensionDescriptor):
"""Extension class supporting bgp 4-byte AS numbers.
"""
@classmethod
def get_name(cls):
return "BGP 4-byte AS numbers"
@classmethod
def get_alias(cls):
return BGP_4BYTE_ASN_EXT_ALIAS
@classmethod
def get_description(cls):
return "Support bgp 4-byte AS numbers"
@classmethod
def get_updated(cls):
return "2017-09-07T00:00:00-00:00"
@classmethod
def get_resources(cls):
return []
def get_extended_resources(self, version):
if version == "2.0":
return RESOURCE_ATTRIBUTE_MAP
else:
return {}
def get_required_extensions(self):
return [bgp_ext.BGP_EXT_ALIAS]
api_definition = api_def

View File

@ -18,6 +18,8 @@ import abc
from neutron.api import extensions
from neutron.api.v2 import resource
from neutron import wsgi
from neutron_lib.api.definitions import bgp as bgp_ext
from neutron_lib.api.definitions import bgp_dragentscheduler as api_def
from neutron_lib.api import extensions as api_extensions
from neutron_lib.api import faults
from neutron_lib import exceptions as n_exc
@ -27,17 +29,10 @@ from oslo_log import log as logging
import webob
from neutron_dynamic_routing._i18n import _, _LE
from neutron_dynamic_routing.extensions import bgp as bgp_ext
LOG = logging.getLogger(__name__)
BGP_DRAGENT_SCHEDULER_EXT_ALIAS = 'bgp_dragent_scheduler'
BGP_DRINSTANCE = 'bgp-drinstance'
BGP_DRINSTANCES = BGP_DRINSTANCE + 's'
BGP_DRAGENT = 'bgp-dragent'
BGP_DRAGENTS = BGP_DRAGENT + 's'
class DrAgentInvalid(agent_exc.AgentNotFound):
message = _("BgpDrAgent %(id)s is invalid or has been disabled.")
@ -61,7 +56,7 @@ class BgpSpeakerRescheduleError(n_exc.Conflict):
class BgpDrSchedulerController(wsgi.Controller):
"""Schedule BgpSpeaker for a BgpDrAgent"""
def get_plugin(self):
plugin = directory.get_plugin(bgp_ext.BGP_EXT_ALIAS)
plugin = directory.get_plugin(bgp_ext.ALIAS)
if not plugin:
LOG.error(_LE('No plugin for BGP routing registered'))
msg = _('The resource could not be found.')
@ -88,7 +83,7 @@ class BgpDrSchedulerController(wsgi.Controller):
class BgpDrAgentController(wsgi.Controller):
def get_plugin(self):
plugin = directory.get_plugin(bgp_ext.BGP_EXT_ALIAS)
plugin = directory.get_plugin(bgp_ext.ALIAS)
if not plugin:
LOG.error(_LE('No plugin for BGP routing registered'))
msg = _('The resource could not be found.')
@ -96,29 +91,16 @@ class BgpDrAgentController(wsgi.Controller):
return plugin
def index(self, request, **kwargs):
plugin = directory.get_plugin(bgp_ext.BGP_EXT_ALIAS)
plugin = directory.get_plugin(bgp_ext.ALIAS)
return plugin.list_dragent_hosting_bgp_speaker(
request.context, kwargs['bgp_speaker_id'])
class Bgp_dragentscheduler(api_extensions.ExtensionDescriptor):
class Bgp_dragentscheduler(api_extensions.APIExtensionDescriptor):
"""Extension class supporting Dynamic Routing scheduler.
"""
@classmethod
def get_name(cls):
return "BGP Dynamic Routing Agent Scheduler"
@classmethod
def get_alias(cls):
return BGP_DRAGENT_SCHEDULER_EXT_ALIAS
@classmethod
def get_description(cls):
return "Schedules BgpSpeakers on BgpDrAgent"
@classmethod
def get_updated(cls):
return "2015-07-30T10:00:00-00:00"
api_definition = api_def
@classmethod
def get_resources(cls):
@ -129,20 +111,17 @@ class Bgp_dragentscheduler(api_extensions.ExtensionDescriptor):
controller = resource.Resource(BgpDrSchedulerController(),
faults.FAULT_MAP)
exts.append(extensions.ResourceExtension(BGP_DRINSTANCES,
exts.append(extensions.ResourceExtension(api_def.BGP_DRINSTANCES,
controller, parent))
parent = dict(member_name="bgp_speaker",
collection_name="bgp-speakers")
controller = resource.Resource(BgpDrAgentController(),
faults.FAULT_MAP)
exts.append(extensions.ResourceExtension(BGP_DRAGENTS,
exts.append(extensions.ResourceExtension(api_def.BGP_DRAGENTS,
controller, parent))
return exts
def get_extended_resources(self, version):
return {}
class BgpDrSchedulerPluginBase(object, metaclass=abc.ABCMeta):
"""REST API to operate BGP dynamic routing agent scheduler.
@ -153,7 +132,7 @@ class BgpDrSchedulerPluginBase(object, metaclass=abc.ABCMeta):
return "Neutron BGP dynamic routing scheduler Plugin"
def get_plugin_type(self):
return bgp_ext.BGP_EXT_ALIAS
return bgp_ext.ALIAS
@abc.abstractmethod
def add_bgp_speaker_to_dragent(self, context, agent_id, speaker_id):

View File

@ -14,6 +14,9 @@
from netaddr import IPAddress
from neutron_lib.api.definitions import bgp as bgp_ext
from neutron_lib.api.definitions import bgp_4byte_asn
from neutron_lib.api.definitions import bgp_dragentscheduler as dras_ext
from neutron_lib.api.definitions import portbindings
from neutron_lib.callbacks import events
from neutron_lib.callbacks import registry
@ -31,12 +34,9 @@ from neutron_dynamic_routing.api.rpc.callbacks import resources as dr_resources
from neutron_dynamic_routing.api.rpc.handlers import bgp_speaker_rpc as bs_rpc
from neutron_dynamic_routing.db import bgp_db
from neutron_dynamic_routing.db import bgp_dragentscheduler_db
from neutron_dynamic_routing.extensions import bgp as bgp_ext
from neutron_dynamic_routing.extensions import bgp_4byte_asn
from neutron_dynamic_routing.extensions import bgp_dragentscheduler as dras_ext
from neutron_dynamic_routing.services.bgp.common import constants as bgp_consts
PLUGIN_NAME = bgp_ext.BGP_EXT_ALIAS + '_svc_plugin'
PLUGIN_NAME = bgp_ext.ALIAS + '_svc_plugin'
LOG = logging.getLogger(__name__)
@ -44,9 +44,9 @@ class BgpPlugin(service_base.ServicePluginBase,
bgp_db.BgpDbMixin,
bgp_dragentscheduler_db.BgpDrAgentSchedulerDbMixin):
supported_extension_aliases = [bgp_ext.BGP_EXT_ALIAS,
dras_ext.BGP_DRAGENT_SCHEDULER_EXT_ALIAS,
bgp_4byte_asn.BGP_4BYTE_ASN_EXT_ALIAS]
supported_extension_aliases = [bgp_ext.ALIAS,
dras_ext.ALIAS,
bgp_4byte_asn.ALIAS]
def __init__(self):
super(BgpPlugin, self).__init__()
@ -57,7 +57,7 @@ class BgpPlugin(service_base.ServicePluginBase,
self.add_periodic_dragent_status_check()
def get_plugin_type(self):
return bgp_ext.BGP_EXT_ALIAS
return bgp_ext.ALIAS
def get_plugin_description(self):
"""returns string description of the plugin."""

View File

@ -16,10 +16,10 @@
from unittest import mock
from neutron.tests import base
from neutron_lib.api.definitions import bgp as bgp_ext
from neutron_lib.plugins import directory
from neutron_dynamic_routing.api.rpc.handlers import bgp_speaker_rpc
from neutron_dynamic_routing.extensions import bgp as bgp_ext
class TestBgpSpeakerRpcCallback(base.BaseTestCase):
@ -27,7 +27,7 @@ class TestBgpSpeakerRpcCallback(base.BaseTestCase):
def setUp(self):
super(TestBgpSpeakerRpcCallback, self).setUp()
self.plugin = mock.Mock()
directory.add_plugin(bgp_ext.BGP_EXT_ALIAS, self.plugin)
directory.add_plugin(bgp_ext.ALIAS, self.plugin)
self.callback = bgp_speaker_rpc.BgpSpeakerRpcCallback()
def test_get_bgp_speaker_info(self):

View File

@ -12,6 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
from neutron_lib.api.definitions import bgp
from neutron_lib import context
from neutron_lib.plugins import directory
from oslo_config import cfg
@ -23,7 +24,6 @@ from neutron.tests.unit.extensions import test_agent
from neutron_dynamic_routing.db import bgp_db
from neutron_dynamic_routing.db import bgp_dragentscheduler_db as bgp_dras_db
from neutron_dynamic_routing.extensions import bgp
from neutron_dynamic_routing.extensions import bgp_dragentscheduler as bgp_dras_ext # noqa
from neutron_dynamic_routing.tests.common import helpers
from neutron_dynamic_routing.tests.unit.db import test_bgp_db
@ -190,12 +190,12 @@ class BgpDrPluginSchedulerTests(test_db_base_plugin.NeutronDbPluginV2TestCase,
plugin = ('neutron_dynamic_routing.tests.unit.db.'
'test_bgp_dragentscheduler_db.TestBgpDrSchedulerPlugin')
if not service_plugins:
service_plugins = {bgp.BGP_EXT_ALIAS:
service_plugins = {bgp.ALIAS:
'neutron_dynamic_routing.services.bgp.'
'bgp_plugin.BgpPlugin'}
ext_mgr = ext_mgr or BgpDrSchedulerTestExtensionManager()
super(BgpDrPluginSchedulerTests, self).setUp(
plugin=plugin, ext_mgr=ext_mgr, service_plugins=service_plugins)
self.bgp_plugin = directory.get_plugin(bgp.BGP_EXT_ALIAS)
self.bgp_plugin = directory.get_plugin(bgp.ALIAS)
self.context = context.get_admin_context()

View File

@ -0,0 +1,5 @@
---
features:
- The API definitions of ``neutron-dynamic-routing``, ``bgp``,
``bgp_4byte_asn`` and ``bgp_dragent_scheduler``, are now available
in ``neutron_lib.api.definitions``.