diff --git a/doc/source/reference/index.rst b/doc/source/reference/index.rst index 0489af46..6b91a87f 100644 --- a/doc/source/reference/index.rst +++ b/doc/source/reference/index.rst @@ -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/`` 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/`` 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/`` 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/`` 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/`` 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/`` 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//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//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//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//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//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-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-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-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-drinstances/`` -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. diff --git a/neutron_dynamic_routing/api/rpc/handlers/bgp_speaker_rpc.py b/neutron_dynamic_routing/api/rpc/handlers/bgp_speaker_rpc.py index 2f148102..108276c0 100644 --- a/neutron_dynamic_routing/api/rpc/handlers/bgp_speaker_rpc.py +++ b/neutron_dynamic_routing/api/rpc/handlers/bgp_speaker_rpc.py @@ -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): diff --git a/neutron_dynamic_routing/db/bgp_db.py b/neutron_dynamic_routing/db/bgp_db.py index c136f499..885d22d9 100644 --- a/neutron_dynamic_routing/db/bgp_db.py +++ b/neutron_dynamic_routing/db/bgp_db.py @@ -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): diff --git a/neutron_dynamic_routing/extensions/bgp.py b/neutron_dynamic_routing/extensions/bgp.py index 416b7b46..7b88995e 100644 --- a/neutron_dynamic_routing/extensions/bgp.py +++ b/neutron_dynamic_routing/extensions/bgp.py @@ -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) diff --git a/neutron_dynamic_routing/extensions/bgp_4byte_asn.py b/neutron_dynamic_routing/extensions/bgp_4byte_asn.py index a50cd315..ea33e38b 100644 --- a/neutron_dynamic_routing/extensions/bgp_4byte_asn.py +++ b/neutron_dynamic_routing/extensions/bgp_4byte_asn.py @@ -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 diff --git a/neutron_dynamic_routing/extensions/bgp_dragentscheduler.py b/neutron_dynamic_routing/extensions/bgp_dragentscheduler.py index 167e53b9..f5063123 100644 --- a/neutron_dynamic_routing/extensions/bgp_dragentscheduler.py +++ b/neutron_dynamic_routing/extensions/bgp_dragentscheduler.py @@ -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): diff --git a/neutron_dynamic_routing/services/bgp/bgp_plugin.py b/neutron_dynamic_routing/services/bgp/bgp_plugin.py index 20e56321..be325d4a 100644 --- a/neutron_dynamic_routing/services/bgp/bgp_plugin.py +++ b/neutron_dynamic_routing/services/bgp/bgp_plugin.py @@ -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.""" diff --git a/neutron_dynamic_routing/tests/unit/api/rpc/handlers/test_bgp_speaker_rpc.py b/neutron_dynamic_routing/tests/unit/api/rpc/handlers/test_bgp_speaker_rpc.py index 032742a4..ed335d0c 100644 --- a/neutron_dynamic_routing/tests/unit/api/rpc/handlers/test_bgp_speaker_rpc.py +++ b/neutron_dynamic_routing/tests/unit/api/rpc/handlers/test_bgp_speaker_rpc.py @@ -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): diff --git a/neutron_dynamic_routing/tests/unit/db/test_bgp_dragentscheduler_db.py b/neutron_dynamic_routing/tests/unit/db/test_bgp_dragentscheduler_db.py index 1a25b00e..371b4139 100644 --- a/neutron_dynamic_routing/tests/unit/db/test_bgp_dragentscheduler_db.py +++ b/neutron_dynamic_routing/tests/unit/db/test_bgp_dragentscheduler_db.py @@ -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() diff --git a/releasenotes/notes/rehome-dynamic-routing-apidef-d656e3273baac4e8.yaml b/releasenotes/notes/rehome-dynamic-routing-apidef-d656e3273baac4e8.yaml new file mode 100644 index 00000000..cd7428c0 --- /dev/null +++ b/releasenotes/notes/rehome-dynamic-routing-apidef-d656e3273baac4e8.yaml @@ -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``.