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:
parent
7245c228c2
commit
c021b106d9
@ -25,467 +25,5 @@
|
|||||||
API
|
API
|
||||||
===
|
===
|
||||||
|
|
||||||
Introduction
|
The reference of the OpenStack neutron-dynamic-routing API is found at
|
||||||
------------
|
https://docs.openstack.org/api-ref/network/#bgp-dynamic-routing.
|
||||||
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
|
|
||||||
|
@ -13,11 +13,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
from neutron_lib.api.definitions import bgp as bgp_ext
|
||||||
from neutron_lib.plugins import directory
|
from neutron_lib.plugins import directory
|
||||||
import oslo_messaging
|
import oslo_messaging
|
||||||
|
|
||||||
from neutron_dynamic_routing.extensions import bgp as bgp_ext
|
|
||||||
|
|
||||||
|
|
||||||
class BgpSpeakerRpcCallback(object):
|
class BgpSpeakerRpcCallback(object):
|
||||||
"""BgpDrAgent RPC callback in plugin implementations.
|
"""BgpDrAgent RPC callback in plugin implementations.
|
||||||
@ -37,7 +36,7 @@ class BgpSpeakerRpcCallback(object):
|
|||||||
@property
|
@property
|
||||||
def plugin(self):
|
def plugin(self):
|
||||||
if not hasattr(self, '_plugin'):
|
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
|
return self._plugin
|
||||||
|
|
||||||
def get_bgp_speaker_info(self, context, bgp_speaker_id):
|
def get_bgp_speaker_info(self, context, bgp_speaker_id):
|
||||||
|
@ -26,6 +26,7 @@ from neutron.objects import subnet as subnet_obj
|
|||||||
from neutron.objects import subnetpool as subnetpool_obj
|
from neutron.objects import subnetpool as subnetpool_obj
|
||||||
from neutron.plugins.ml2 import models as ml2_models
|
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.api import validators
|
||||||
from neutron_lib import constants as lib_consts
|
from neutron_lib import constants as lib_consts
|
||||||
from neutron_lib.db import api as db_api
|
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 sqlalchemy.orm import exc as sa_exc
|
||||||
|
|
||||||
from neutron_dynamic_routing._i18n import _
|
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
|
DEVICE_OWNER_ROUTER_GW = lib_consts.DEVICE_OWNER_ROUTER_GW
|
||||||
@ -208,7 +209,7 @@ class BgpDbMixin(object):
|
|||||||
bgp_speaker_id,
|
bgp_speaker_id,
|
||||||
network_id)
|
network_id)
|
||||||
except oslo_db_exc.DBDuplicateEntry:
|
except oslo_db_exc.DBDuplicateEntry:
|
||||||
raise bgp_ext.BgpSpeakerNetworkBindingError(
|
raise bgp.BgpSpeakerNetworkBindingError(
|
||||||
network_id=network_id,
|
network_id=network_id,
|
||||||
bgp_speaker_id=bgp_speaker_id)
|
bgp_speaker_id=bgp_speaker_id)
|
||||||
return {'network_id': network_id}
|
return {'network_id': network_id}
|
||||||
@ -231,7 +232,7 @@ class BgpDbMixin(object):
|
|||||||
auth_type = ri.get('auth_type')
|
auth_type = ri.get('auth_type')
|
||||||
password = ri.get('password')
|
password = ri.get('password')
|
||||||
if auth_type == 'md5' and not password:
|
if auth_type == 'md5' and not password:
|
||||||
raise bgp_ext.InvalidBgpPeerMd5Authentication()
|
raise bgp.InvalidBgpPeerMd5Authentication()
|
||||||
|
|
||||||
with db_api.CONTEXT_WRITER.using(context):
|
with db_api.CONTEXT_WRITER.using(context):
|
||||||
res_keys = ['tenant_id', 'name', 'remote_as', 'peer_ip',
|
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)
|
bgp_peer_db = self._get_bgp_peer(context, bgp_peer_id)
|
||||||
if ((bp.get('password') is not None) and
|
if ((bp.get('password') is not None) and
|
||||||
(bgp_peer_db['auth_type'] == 'none')):
|
(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_db.update(bp)
|
||||||
|
|
||||||
bgp_peer_dict = self._make_bgp_peer_dict(bgp_peer_db)
|
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,
|
return model_query.get_by_id(context, BgpSpeaker,
|
||||||
bgp_speaker_id)
|
bgp_speaker_id)
|
||||||
except sa_exc.NoResultFound:
|
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):
|
def _get_bgp_speaker_ids_by_router(self, context, router_id):
|
||||||
with db_api.CONTEXT_READER.using(context):
|
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 = model_query.get_by_id(context, BgpSpeaker,
|
||||||
bgp_speaker_id)
|
bgp_speaker_id)
|
||||||
except sa_exc.NoResultFound:
|
except sa_exc.NoResultFound:
|
||||||
raise bgp_ext.BgpSpeakerNotFound(id=bgp_speaker_id)
|
raise bgp.BgpSpeakerNotFound(id=bgp_speaker_id)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
bgp_peer = model_query.get_by_id(context, BgpPeer,
|
bgp_peer = model_query.get_by_id(context, BgpPeer,
|
||||||
bgp_peer_id)
|
bgp_peer_id)
|
||||||
except sa_exc.NoResultFound:
|
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,
|
peers = self._get_bgp_peers_by_bgp_speaker_binding(context,
|
||||||
bgp_speaker_id)
|
bgp_speaker_id)
|
||||||
@ -358,7 +359,7 @@ class BgpDbMixin(object):
|
|||||||
def _validate_peer_ips(self, bgp_speaker_id, current_peers, new_peer):
|
def _validate_peer_ips(self, bgp_speaker_id, current_peers, new_peer):
|
||||||
for peer in current_peers:
|
for peer in current_peers:
|
||||||
if peer.peer_ip == new_peer.peer_ip:
|
if peer.peer_ip == new_peer.peer_ip:
|
||||||
raise bgp_ext.DuplicateBgpPeerIpException(
|
raise bgp.DuplicateBgpPeerIpException(
|
||||||
bgp_peer_id=new_peer.id,
|
bgp_peer_id=new_peer.id,
|
||||||
peer_ip=new_peer.peer_ip,
|
peer_ip=new_peer.peer_ip,
|
||||||
bgp_speaker_id=bgp_speaker_id)
|
bgp_speaker_id=bgp_speaker_id)
|
||||||
@ -372,7 +373,7 @@ class BgpDbMixin(object):
|
|||||||
bgp_speaker_id,
|
bgp_speaker_id,
|
||||||
bgp_peer_id)
|
bgp_peer_id)
|
||||||
except sa_exc.NoResultFound:
|
except sa_exc.NoResultFound:
|
||||||
raise bgp_ext.BgpSpeakerPeerNotAssociated(
|
raise bgp.BgpSpeakerPeerNotAssociated(
|
||||||
bgp_peer_id=bgp_peer_id,
|
bgp_peer_id=bgp_peer_id,
|
||||||
bgp_speaker_id=bgp_speaker_id)
|
bgp_speaker_id=bgp_speaker_id)
|
||||||
context.session.delete(binding)
|
context.session.delete(binding)
|
||||||
@ -386,7 +387,7 @@ class BgpDbMixin(object):
|
|||||||
bgp_speaker = model_query.get_by_id(context, BgpSpeaker,
|
bgp_speaker = model_query.get_by_id(context, BgpSpeaker,
|
||||||
bgp_speaker_id)
|
bgp_speaker_id)
|
||||||
except sa_exc.NoResultFound:
|
except sa_exc.NoResultFound:
|
||||||
raise bgp_ext.BgpSpeakerNotFound(id=bgp_speaker_id)
|
raise bgp.BgpSpeakerNotFound(id=bgp_speaker_id)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
network = model_query.get_by_id(context, models_v2.Network,
|
network = model_query.get_by_id(context, models_v2.Network,
|
||||||
@ -410,7 +411,7 @@ class BgpDbMixin(object):
|
|||||||
bgp_speaker_id,
|
bgp_speaker_id,
|
||||||
network_id)
|
network_id)
|
||||||
except sa_exc.NoResultFound:
|
except sa_exc.NoResultFound:
|
||||||
raise bgp_ext.BgpSpeakerNetworkNotAssociated(
|
raise bgp.BgpSpeakerNetworkNotAssociated(
|
||||||
network_id=network_id,
|
network_id=network_id,
|
||||||
bgp_speaker_id=bgp_speaker_id)
|
bgp_speaker_id=bgp_speaker_id)
|
||||||
context.session.delete(binding)
|
context.session.delete(binding)
|
||||||
@ -433,7 +434,7 @@ class BgpDbMixin(object):
|
|||||||
try:
|
try:
|
||||||
return model_query.get_by_id(context, BgpPeer, bgp_peer_id)
|
return model_query.get_by_id(context, BgpPeer, bgp_peer_id)
|
||||||
except sa_exc.NoResultFound:
|
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,
|
def _get_bgp_speaker_peer_binding(self, context,
|
||||||
bgp_speaker_id, bgp_peer_id):
|
bgp_speaker_id, bgp_peer_id):
|
||||||
|
@ -14,107 +14,13 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
from neutron_lib.api import converters as n_conv
|
from neutron_lib.api.definitions import bgp as bgp_api_def
|
||||||
from neutron_lib.api import extensions
|
from neutron_lib.api import extensions as api_ext
|
||||||
from neutron_lib.db import constants as db_const
|
|
||||||
from neutron_lib import exceptions as n_exc
|
from neutron_lib import exceptions as n_exc
|
||||||
|
|
||||||
from neutron.api.v2 import resource_helper as rh
|
from neutron.api.v2 import resource_helper as rh
|
||||||
|
|
||||||
from neutron_dynamic_routing._i18n import _
|
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
|
# Dynamic Routing Exceptions
|
||||||
@ -164,48 +70,16 @@ class NetworkNotBoundForIpVersion(NetworkNotBound):
|
|||||||
"BgpSpeaker.")
|
"BgpSpeaker.")
|
||||||
|
|
||||||
|
|
||||||
class Bgp(extensions.ExtensionDescriptor):
|
class Bgp(api_ext.APIExtensionDescriptor):
|
||||||
|
api_definition = bgp_api_def
|
||||||
@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"
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_resources(cls):
|
def get_resources(cls):
|
||||||
plural_mappings = rh.build_plural_mappings(
|
plural_mappings = rh.build_plural_mappings(
|
||||||
{}, RESOURCE_ATTRIBUTE_MAP)
|
{}, bgp_api_def.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'}}
|
|
||||||
exts = rh.build_resource_info(plural_mappings,
|
exts = rh.build_resource_info(plural_mappings,
|
||||||
RESOURCE_ATTRIBUTE_MAP,
|
bgp_api_def.RESOURCE_ATTRIBUTE_MAP,
|
||||||
BGP_EXT_ALIAS,
|
bgp_api_def.ALIAS,
|
||||||
action_map=action_map)
|
action_map=bgp_api_def.ACTION_MAP)
|
||||||
|
|
||||||
return exts
|
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)
|
|
||||||
|
@ -10,63 +10,12 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# 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_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
|
|
||||||
|
|
||||||
|
class Bgp_4byte_asn(api_extensions.APIExtensionDescriptor):
|
||||||
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):
|
|
||||||
"""Extension class supporting bgp 4-byte AS numbers.
|
"""Extension class supporting bgp 4-byte AS numbers.
|
||||||
"""
|
"""
|
||||||
@classmethod
|
|
||||||
def get_name(cls):
|
|
||||||
return "BGP 4-byte AS numbers"
|
|
||||||
|
|
||||||
@classmethod
|
api_definition = api_def
|
||||||
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]
|
|
||||||
|
@ -18,6 +18,8 @@ import abc
|
|||||||
from neutron.api import extensions
|
from neutron.api import extensions
|
||||||
from neutron.api.v2 import resource
|
from neutron.api.v2 import resource
|
||||||
from neutron import wsgi
|
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 extensions as api_extensions
|
||||||
from neutron_lib.api import faults
|
from neutron_lib.api import faults
|
||||||
from neutron_lib import exceptions as n_exc
|
from neutron_lib import exceptions as n_exc
|
||||||
@ -27,17 +29,10 @@ from oslo_log import log as logging
|
|||||||
import webob
|
import webob
|
||||||
|
|
||||||
from neutron_dynamic_routing._i18n import _, _LE
|
from neutron_dynamic_routing._i18n import _, _LE
|
||||||
from neutron_dynamic_routing.extensions import bgp as bgp_ext
|
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
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):
|
class DrAgentInvalid(agent_exc.AgentNotFound):
|
||||||
message = _("BgpDrAgent %(id)s is invalid or has been disabled.")
|
message = _("BgpDrAgent %(id)s is invalid or has been disabled.")
|
||||||
@ -61,7 +56,7 @@ class BgpSpeakerRescheduleError(n_exc.Conflict):
|
|||||||
class BgpDrSchedulerController(wsgi.Controller):
|
class BgpDrSchedulerController(wsgi.Controller):
|
||||||
"""Schedule BgpSpeaker for a BgpDrAgent"""
|
"""Schedule BgpSpeaker for a BgpDrAgent"""
|
||||||
def get_plugin(self):
|
def get_plugin(self):
|
||||||
plugin = directory.get_plugin(bgp_ext.BGP_EXT_ALIAS)
|
plugin = directory.get_plugin(bgp_ext.ALIAS)
|
||||||
if not plugin:
|
if not plugin:
|
||||||
LOG.error(_LE('No plugin for BGP routing registered'))
|
LOG.error(_LE('No plugin for BGP routing registered'))
|
||||||
msg = _('The resource could not be found.')
|
msg = _('The resource could not be found.')
|
||||||
@ -88,7 +83,7 @@ class BgpDrSchedulerController(wsgi.Controller):
|
|||||||
|
|
||||||
class BgpDrAgentController(wsgi.Controller):
|
class BgpDrAgentController(wsgi.Controller):
|
||||||
def get_plugin(self):
|
def get_plugin(self):
|
||||||
plugin = directory.get_plugin(bgp_ext.BGP_EXT_ALIAS)
|
plugin = directory.get_plugin(bgp_ext.ALIAS)
|
||||||
if not plugin:
|
if not plugin:
|
||||||
LOG.error(_LE('No plugin for BGP routing registered'))
|
LOG.error(_LE('No plugin for BGP routing registered'))
|
||||||
msg = _('The resource could not be found.')
|
msg = _('The resource could not be found.')
|
||||||
@ -96,29 +91,16 @@ class BgpDrAgentController(wsgi.Controller):
|
|||||||
return plugin
|
return plugin
|
||||||
|
|
||||||
def index(self, request, **kwargs):
|
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(
|
return plugin.list_dragent_hosting_bgp_speaker(
|
||||||
request.context, kwargs['bgp_speaker_id'])
|
request.context, kwargs['bgp_speaker_id'])
|
||||||
|
|
||||||
|
|
||||||
class Bgp_dragentscheduler(api_extensions.ExtensionDescriptor):
|
class Bgp_dragentscheduler(api_extensions.APIExtensionDescriptor):
|
||||||
"""Extension class supporting Dynamic Routing scheduler.
|
"""Extension class supporting Dynamic Routing scheduler.
|
||||||
"""
|
"""
|
||||||
@classmethod
|
|
||||||
def get_name(cls):
|
|
||||||
return "BGP Dynamic Routing Agent Scheduler"
|
|
||||||
|
|
||||||
@classmethod
|
api_definition = api_def
|
||||||
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"
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_resources(cls):
|
def get_resources(cls):
|
||||||
@ -129,20 +111,17 @@ class Bgp_dragentscheduler(api_extensions.ExtensionDescriptor):
|
|||||||
|
|
||||||
controller = resource.Resource(BgpDrSchedulerController(),
|
controller = resource.Resource(BgpDrSchedulerController(),
|
||||||
faults.FAULT_MAP)
|
faults.FAULT_MAP)
|
||||||
exts.append(extensions.ResourceExtension(BGP_DRINSTANCES,
|
exts.append(extensions.ResourceExtension(api_def.BGP_DRINSTANCES,
|
||||||
controller, parent))
|
controller, parent))
|
||||||
|
|
||||||
parent = dict(member_name="bgp_speaker",
|
parent = dict(member_name="bgp_speaker",
|
||||||
collection_name="bgp-speakers")
|
collection_name="bgp-speakers")
|
||||||
controller = resource.Resource(BgpDrAgentController(),
|
controller = resource.Resource(BgpDrAgentController(),
|
||||||
faults.FAULT_MAP)
|
faults.FAULT_MAP)
|
||||||
exts.append(extensions.ResourceExtension(BGP_DRAGENTS,
|
exts.append(extensions.ResourceExtension(api_def.BGP_DRAGENTS,
|
||||||
controller, parent))
|
controller, parent))
|
||||||
return exts
|
return exts
|
||||||
|
|
||||||
def get_extended_resources(self, version):
|
|
||||||
return {}
|
|
||||||
|
|
||||||
|
|
||||||
class BgpDrSchedulerPluginBase(object, metaclass=abc.ABCMeta):
|
class BgpDrSchedulerPluginBase(object, metaclass=abc.ABCMeta):
|
||||||
"""REST API to operate BGP dynamic routing agent scheduler.
|
"""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"
|
return "Neutron BGP dynamic routing scheduler Plugin"
|
||||||
|
|
||||||
def get_plugin_type(self):
|
def get_plugin_type(self):
|
||||||
return bgp_ext.BGP_EXT_ALIAS
|
return bgp_ext.ALIAS
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def add_bgp_speaker_to_dragent(self, context, agent_id, speaker_id):
|
def add_bgp_speaker_to_dragent(self, context, agent_id, speaker_id):
|
||||||
|
@ -14,6 +14,9 @@
|
|||||||
|
|
||||||
from netaddr import IPAddress
|
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.api.definitions import portbindings
|
||||||
from neutron_lib.callbacks import events
|
from neutron_lib.callbacks import events
|
||||||
from neutron_lib.callbacks import registry
|
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.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_db
|
||||||
from neutron_dynamic_routing.db import bgp_dragentscheduler_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
|
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__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@ -44,9 +44,9 @@ class BgpPlugin(service_base.ServicePluginBase,
|
|||||||
bgp_db.BgpDbMixin,
|
bgp_db.BgpDbMixin,
|
||||||
bgp_dragentscheduler_db.BgpDrAgentSchedulerDbMixin):
|
bgp_dragentscheduler_db.BgpDrAgentSchedulerDbMixin):
|
||||||
|
|
||||||
supported_extension_aliases = [bgp_ext.BGP_EXT_ALIAS,
|
supported_extension_aliases = [bgp_ext.ALIAS,
|
||||||
dras_ext.BGP_DRAGENT_SCHEDULER_EXT_ALIAS,
|
dras_ext.ALIAS,
|
||||||
bgp_4byte_asn.BGP_4BYTE_ASN_EXT_ALIAS]
|
bgp_4byte_asn.ALIAS]
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(BgpPlugin, self).__init__()
|
super(BgpPlugin, self).__init__()
|
||||||
@ -57,7 +57,7 @@ class BgpPlugin(service_base.ServicePluginBase,
|
|||||||
self.add_periodic_dragent_status_check()
|
self.add_periodic_dragent_status_check()
|
||||||
|
|
||||||
def get_plugin_type(self):
|
def get_plugin_type(self):
|
||||||
return bgp_ext.BGP_EXT_ALIAS
|
return bgp_ext.ALIAS
|
||||||
|
|
||||||
def get_plugin_description(self):
|
def get_plugin_description(self):
|
||||||
"""returns string description of the plugin."""
|
"""returns string description of the plugin."""
|
||||||
|
@ -16,10 +16,10 @@
|
|||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
from neutron.tests import base
|
from neutron.tests import base
|
||||||
|
from neutron_lib.api.definitions import bgp as bgp_ext
|
||||||
from neutron_lib.plugins import directory
|
from neutron_lib.plugins import directory
|
||||||
|
|
||||||
from neutron_dynamic_routing.api.rpc.handlers import bgp_speaker_rpc
|
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):
|
class TestBgpSpeakerRpcCallback(base.BaseTestCase):
|
||||||
@ -27,7 +27,7 @@ class TestBgpSpeakerRpcCallback(base.BaseTestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestBgpSpeakerRpcCallback, self).setUp()
|
super(TestBgpSpeakerRpcCallback, self).setUp()
|
||||||
self.plugin = mock.Mock()
|
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()
|
self.callback = bgp_speaker_rpc.BgpSpeakerRpcCallback()
|
||||||
|
|
||||||
def test_get_bgp_speaker_info(self):
|
def test_get_bgp_speaker_info(self):
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
from neutron_lib.api.definitions import bgp
|
||||||
from neutron_lib import context
|
from neutron_lib import context
|
||||||
from neutron_lib.plugins import directory
|
from neutron_lib.plugins import directory
|
||||||
from oslo_config import cfg
|
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_db
|
||||||
from neutron_dynamic_routing.db import bgp_dragentscheduler_db as bgp_dras_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.extensions import bgp_dragentscheduler as bgp_dras_ext # noqa
|
||||||
from neutron_dynamic_routing.tests.common import helpers
|
from neutron_dynamic_routing.tests.common import helpers
|
||||||
from neutron_dynamic_routing.tests.unit.db import test_bgp_db
|
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.'
|
plugin = ('neutron_dynamic_routing.tests.unit.db.'
|
||||||
'test_bgp_dragentscheduler_db.TestBgpDrSchedulerPlugin')
|
'test_bgp_dragentscheduler_db.TestBgpDrSchedulerPlugin')
|
||||||
if not service_plugins:
|
if not service_plugins:
|
||||||
service_plugins = {bgp.BGP_EXT_ALIAS:
|
service_plugins = {bgp.ALIAS:
|
||||||
'neutron_dynamic_routing.services.bgp.'
|
'neutron_dynamic_routing.services.bgp.'
|
||||||
'bgp_plugin.BgpPlugin'}
|
'bgp_plugin.BgpPlugin'}
|
||||||
|
|
||||||
ext_mgr = ext_mgr or BgpDrSchedulerTestExtensionManager()
|
ext_mgr = ext_mgr or BgpDrSchedulerTestExtensionManager()
|
||||||
super(BgpDrPluginSchedulerTests, self).setUp(
|
super(BgpDrPluginSchedulerTests, self).setUp(
|
||||||
plugin=plugin, ext_mgr=ext_mgr, service_plugins=service_plugins)
|
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()
|
self.context = context.get_admin_context()
|
||||||
|
@ -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``.
|
Loading…
Reference in New Issue
Block a user