summaryrefslogtreecommitdiff
path: root/neutronclient/osc
diff options
context:
space:
mode:
authorNa <nazhu@cn.ibm.com>2016-07-12 02:50:06 -0500
committerAkihiro Motoki <amotoki@gmail.com>2017-10-26 14:10:42 +0900
commit33947da4b93c41248cb6c46c1f6e0a7bdcaaf9e9 (patch)
tree8ba1ed9a256abf657c214084975b7acb7c5fecff /neutronclient/osc
parent0907ccc4df68c71f1af71976819bff741829e434 (diff)
downloadpython-neutronclient-33947da4b93c41248cb6c46c1f6e0a7bdcaaf9e9.tar.gz
Dynamic routing CLIs OSC transition
Neutron is transitioning its CLI to OSC, should update dynamic routing CLIs to align with OSC plugin. Change-Id: Ic1a633ca103d9e97e28ddf23e0f528e0261ce497 Co-Authored-By: Ryan Tidwell <ryan@6tidwells.com> Co-Authored-By: Roey Chen <roeyc@vmware.com> Partially-Implements: blueprint bgp-spinout Partial-Bug: #1560003
Diffstat (limited to 'neutronclient/osc')
-rw-r--r--neutronclient/osc/v2/dynamic_routing/bgp_dragent.py99
-rw-r--r--neutronclient/osc/v2/dynamic_routing/bgp_peer.py188
-rw-r--r--neutronclient/osc/v2/dynamic_routing/bgp_speaker.py320
-rw-r--r--neutronclient/osc/v2/dynamic_routing/constants.py18
4 files changed, 625 insertions, 0 deletions
diff --git a/neutronclient/osc/v2/dynamic_routing/bgp_dragent.py b/neutronclient/osc/v2/dynamic_routing/bgp_dragent.py
new file mode 100644
index 0000000..f7f1e83
--- /dev/null
+++ b/neutronclient/osc/v2/dynamic_routing/bgp_dragent.py
@@ -0,0 +1,99 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+
+from osc_lib.command import command
+from osc_lib import utils
+
+from neutronclient._i18n import _
+from neutronclient.osc.v2.dynamic_routing import constants
+
+
+def _format_alive_state(item):
+ return ':-)' if item else 'XXX'
+
+
+_formatters = {
+ 'alive': _format_alive_state
+}
+
+
+def add_common_args(parser):
+ parser.add_argument('dragent_id',
+ metavar='<agent-id>',
+ help=_("ID of the dynamic routing agent"))
+ parser.add_argument('bgp_speaker',
+ metavar='<bgp-speaker>',
+ help=_("ID or name of the BGP speaker"))
+
+
+class AddBgpSpeakerToDRAgent(command.Command):
+ """Add a BGP speaker to a dynamic routing agent"""
+
+ def get_parser(self, prog_name):
+ parser = super(AddBgpSpeakerToDRAgent, self).get_parser(prog_name)
+ add_common_args(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ client = self.app.client_manager.neutronclient
+ speaker_id = client.find_resource(constants.BGP_SPEAKER,
+ parsed_args.bgp_speaker)['id']
+ client.add_bgp_speaker_to_dragent(
+ parsed_args.dragent_id, {'bgp_speaker_id': speaker_id})
+
+
+class RemoveBgpSpeakerFromDRAgent(command.Command):
+ """Removes a BGP speaker from a dynamic routing agent"""
+
+ def get_parser(self, prog_name):
+ parser = super(RemoveBgpSpeakerFromDRAgent, self).get_parser(
+ prog_name)
+ add_common_args(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ client = self.app.client_manager.neutronclient
+ speaker_id = client.find_resource(constants.BGP_SPEAKER,
+ parsed_args.bgp_speaker)['id']
+ client.remove_bgp_speaker_from_dragent(parsed_args.dragent_id,
+ speaker_id)
+
+
+class ListDRAgentsHostingBgpSpeaker(command.Lister):
+ """List dynamic routing agents hosting a BGP speaker"""
+
+ resource = 'agent'
+ list_columns = ['id', 'host', 'admin_state_up', 'alive']
+ unknown_parts_flag = False
+
+ def get_parser(self, prog_name):
+ parser = super(ListDRAgentsHostingBgpSpeaker,
+ self).get_parser(prog_name)
+ parser.add_argument('bgp_speaker',
+ metavar='<bgp-speaker>',
+ help=_("ID or name of the BGP speaker"))
+ return parser
+
+ def take_action(self, parsed_args):
+ search_opts = {}
+ client = self.app.client_manager.neutronclient
+ speaker_id = client.find_resource(constants.BGP_SPEAKER,
+ parsed_args.bgp_speaker)['id']
+ search_opts['bgp_speaker'] = speaker_id
+ data = client.list_dragents_hosting_bgp_speaker(**search_opts)
+ headers = ('ID', 'Host', 'State', 'Alive')
+ columns = ('id', 'host', 'admin_state_up', 'alive')
+ return (headers,
+ (utils.get_dict_properties(
+ s, columns, formatters=_formatters,
+ ) for s in data['agents']))
diff --git a/neutronclient/osc/v2/dynamic_routing/bgp_peer.py b/neutronclient/osc/v2/dynamic_routing/bgp_peer.py
new file mode 100644
index 0000000..c245ce2
--- /dev/null
+++ b/neutronclient/osc/v2/dynamic_routing/bgp_peer.py
@@ -0,0 +1,188 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+
+from osc_lib.command import command
+from osc_lib import utils
+
+from neutronclient._i18n import _
+from neutronclient.common import exceptions
+from neutronclient.common import utils as nc_utils
+from neutronclient.osc import utils as nc_osc_utils
+from neutronclient.osc.v2.dynamic_routing import constants
+
+
+def _get_attrs(client_manager, parsed_args):
+ attrs = {}
+
+ # Validate password
+ if 'auth_type' in parsed_args:
+ if parsed_args.auth_type != 'none':
+ if 'password' not in parsed_args or parsed_args.password is None:
+ raise exceptions.CommandError(_('Must provide password if '
+ 'auth-type is specified.'))
+ if (
+ parsed_args.auth_type == 'none' and
+ parsed_args.password is not None
+ ):
+ raise exceptions.CommandError(_('Must provide auth-type if '
+ 'password is specified.'))
+ attrs['auth_type'] = parsed_args.auth_type
+
+ if parsed_args.name is not None:
+ attrs['name'] = parsed_args.name
+ if 'remote_as' in parsed_args:
+ attrs['remote_as'] = parsed_args.remote_as
+ if 'peer_ip' in parsed_args:
+ attrs['peer_ip'] = parsed_args.peer_ip
+ if 'password' in parsed_args:
+ attrs['password'] = parsed_args.password
+
+ if 'project' in parsed_args and parsed_args.project is not None:
+ identity_client = client_manager.identity
+ project_id = nc_osc_utils.find_project(
+ identity_client,
+ parsed_args.project,
+ parsed_args.project_domain,
+ ).id
+ attrs['tenant_id'] = project_id
+ return attrs
+
+
+class CreateBgpPeer(command.ShowOne):
+ _description = _("Create a BGP peer")
+
+ def get_parser(self, prog_name):
+ parser = super(CreateBgpPeer, self).get_parser(prog_name)
+ parser.add_argument(
+ 'name',
+ metavar='<name>',
+ help=_("Name of the BGP peer to create"))
+ parser.add_argument(
+ '--peer-ip',
+ metavar='<peer-ip-address>',
+ required=True,
+ help=_("Peer IP address"))
+ parser.add_argument(
+ '--remote-as',
+ required=True,
+ metavar='<peer-remote-as>',
+ help=_("Peer AS number. (Integer in [%(min_val)s, %(max_val)s] "
+ "is allowed)") % {'min_val': constants.MIN_AS_NUM,
+ 'max_val': constants.MAX_AS_NUM})
+ parser.add_argument(
+ '--auth-type',
+ metavar='<peer-auth-type>',
+ choices=['none', 'md5'],
+ type=nc_utils.convert_to_lowercase,
+ default='none',
+ help=_("Authentication algorithm. Supported algorithms: "
+ "none (default), md5"))
+ parser.add_argument(
+ '--password',
+ metavar='<auth-password>',
+ help=_("Authentication password"))
+ nc_osc_utils.add_project_owner_option_to_parser(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ client = self.app.client_manager.neutronclient
+ attrs = _get_attrs(self.app.client_manager, parsed_args)
+ body = {constants.BGP_PEER: attrs}
+ obj = client.create_bgp_peer(body)[constants.BGP_PEER]
+ columns, display_columns = nc_osc_utils.get_columns(obj)
+ data = utils.get_dict_properties(obj, columns)
+ return display_columns, data
+
+
+class DeleteBgpPeer(command.Command):
+ _description = _("Delete a BGP peer")
+
+ def get_parser(self, prog_name):
+ parser = super(DeleteBgpPeer, self).get_parser(prog_name)
+ parser.add_argument(
+ 'bgp_peer',
+ metavar="<bgp-peer>",
+ help=_("BGP peer to delete (name or ID)")
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ client = self.app.client_manager.neutronclient
+ id = client.find_resource(constants.BGP_PEER,
+ parsed_args.bgp_peer)['id']
+ client.delete_bgp_peer(id)
+
+
+class ListBgpPeer(command.Lister):
+ _description = _("List BGP peers")
+
+ def take_action(self, parsed_args):
+ data = self.app.client_manager.neutronclient.list_bgp_peers()
+ headers = ('ID', 'Name', 'Peer IP', 'Remote AS')
+ columns = ('id', 'name', 'peer_ip', 'remote_as')
+ return (headers,
+ (utils.get_dict_properties(
+ s, columns,
+ ) for s in data[constants.BGP_PEERS]))
+
+
+class SetBgpPeer(command.Command):
+ _description = _("Update a BGP peer")
+ resource = constants.BGP_PEER
+
+ def get_parser(self, prog_name):
+ parser = super(SetBgpPeer, self).get_parser(prog_name)
+ parser.add_argument(
+ '--name',
+ help=_("Updated name of the BGP peer"))
+ parser.add_argument(
+ '--password',
+ metavar='<auth-password>',
+ help=_("Updated authentication password"))
+ parser.add_argument(
+ 'bgp_peer',
+ metavar="<bgp-peer>",
+ help=_("BGP peer to update (name or ID)")
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ client = self.app.client_manager.neutronclient
+ id = client.find_resource(constants.BGP_PEER,
+ parsed_args.bgp_peer)['id']
+ attrs = _get_attrs(self.app.client_manager, parsed_args)
+ body = {}
+ body[constants.BGP_PEER] = attrs
+ client.update_bgp_peer(id, body)
+
+
+class ShowBgpPeer(command.ShowOne):
+ _description = _("Show information for a BGP peer")
+
+ def get_parser(self, prog_name):
+ parser = super(ShowBgpPeer, self).get_parser(prog_name)
+ parser.add_argument(
+ 'bgp_peer',
+ metavar="<bgp-peer>",
+ help=_("BGP peer to display (name or ID)")
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ client = self.app.client_manager.neutronclient
+ id = client.find_resource(constants.BGP_PEER,
+ parsed_args.bgp_peer)['id']
+ obj = client.show_bgp_peer(id)[constants.BGP_PEER]
+ columns, display_columns = nc_osc_utils.get_columns(obj)
+ data = utils.get_dict_properties(obj, columns)
+ return display_columns, data
diff --git a/neutronclient/osc/v2/dynamic_routing/bgp_speaker.py b/neutronclient/osc/v2/dynamic_routing/bgp_speaker.py
new file mode 100644
index 0000000..bfe202f
--- /dev/null
+++ b/neutronclient/osc/v2/dynamic_routing/bgp_speaker.py
@@ -0,0 +1,320 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+
+from osc_lib.command import command
+from osc_lib import utils
+
+from neutronclient._i18n import _
+from neutronclient.osc import utils as nc_osc_utils
+from neutronclient.osc.v2.dynamic_routing import constants
+
+
+def _get_attrs(client_manager, parsed_args):
+ attrs = {}
+ if parsed_args.name is not None:
+ attrs['name'] = str(parsed_args.name)
+ if 'local_as' in parsed_args:
+ attrs['local_as'] = parsed_args.local_as
+ if 'ip_version' in parsed_args:
+ attrs['ip_version'] = parsed_args.ip_version
+ if parsed_args.advertise_tenant_networks:
+ attrs['advertise_tenant_networks'] = True
+ if parsed_args.no_advertise_tenant_networks:
+ attrs['advertise_tenant_networks'] = False
+ if parsed_args.advertise_floating_ip_host_routes:
+ attrs['advertise_floating_ip_host_routes'] = True
+ if parsed_args.no_advertise_floating_ip_host_routes:
+ attrs['advertise_floating_ip_host_routes'] = False
+
+ if 'project' in parsed_args and parsed_args.project is not None:
+ identity_client = client_manager.identity
+ project_id = nc_osc_utils.find_project(
+ identity_client,
+ parsed_args.project,
+ parsed_args.project_domain,
+ ).id
+ attrs['tenant_id'] = project_id
+ return attrs
+
+
+def add_common_arguments(parser):
+ parser.add_argument(
+ '--advertise-floating-ip-host-routes',
+ action='store_true',
+ help=_("Enable the advertisement of floating IP host routes "
+ "by the BGP speaker. (default)"))
+ parser.add_argument(
+ '--no-advertise-floating-ip-host-routes',
+ action='store_true',
+ help=_("Disable the advertisement of floating IP host routes "
+ "by the BGP speaker."))
+ parser.add_argument(
+ '--advertise-tenant-networks',
+ action='store_true',
+ help=_("Enable the advertisement of tenant network routes "
+ "by the BGP speaker. (default)"))
+ parser.add_argument(
+ '--no-advertise-tenant-networks',
+ action='store_true',
+ help=_("Disable the advertisement of tenant network routes "
+ "by the BGP speaker."))
+
+
+class AddNetworkToSpeaker(command.Command):
+ _description = _("Add a network to a BGP speaker")
+
+ def get_parser(self, prog_name):
+ parser = super(AddNetworkToSpeaker, self).get_parser(prog_name)
+ parser.add_argument(
+ 'bgp_speaker',
+ metavar='<bgp-speaker>',
+ help=_("BGP speaker (name or ID)"))
+ parser.add_argument(
+ 'network',
+ metavar='<network>',
+ help=_("Network to add (name or ID)"))
+ return parser
+
+ def take_action(self, parsed_args):
+ client = self.app.client_manager.neutronclient
+ speaker_id = client.find_resource(constants.BGP_SPEAKER,
+ parsed_args.bgp_speaker)['id']
+ net_id = client.find_resource('network',
+ parsed_args.network)['id']
+ client.add_network_to_bgp_speaker(speaker_id, {'network_id': net_id})
+
+
+class AddPeerToSpeaker(command.Command):
+ _description = _("Add a peer to a BGP speaker")
+
+ def get_parser(self, prog_name):
+ parser = super(AddPeerToSpeaker, self).get_parser(prog_name)
+ parser.add_argument(
+ 'bgp_speaker',
+ metavar='<bgp-speaker>',
+ help=_("BGP speaker (name or ID)"))
+ parser.add_argument(
+ 'bgp_peer',
+ metavar='<bgp-peer>',
+ help=_("BGP Peer to add (name or ID)"))
+ return parser
+
+ def take_action(self, parsed_args):
+ client = self.app.client_manager.neutronclient
+ speaker_id = client.find_resource(constants.BGP_SPEAKER,
+ parsed_args.bgp_speaker)['id']
+ peer_id = client.find_resource(constants.BGP_PEER,
+ parsed_args.bgp_peer)['id']
+ client.add_peer_to_bgp_speaker(speaker_id, {'bgp_peer_id': peer_id})
+
+
+class CreateBgpSpeaker(command.ShowOne):
+ _description = _("Create a BGP speaker")
+
+ def get_parser(self, prog_name):
+ parser = super(CreateBgpSpeaker, self).get_parser(prog_name)
+ parser.add_argument(
+ 'name',
+ metavar='<name>',
+ help=_("Name of the BGP speaker to create"))
+ parser.add_argument(
+ '--local-as',
+ metavar='<local-as>',
+ required=True,
+ help=_("Local AS number. (Integer in [%(min_val)s, %(max_val)s] "
+ "is allowed.)") % {'min_val': constants.MIN_AS_NUM,
+ 'max_val': constants.MAX_AS_NUM})
+ parser.add_argument(
+ '--ip-version',
+ type=int, choices=[4, 6],
+ default=4,
+ help=_("IP version for the BGP speaker (default is 4)"))
+ add_common_arguments(parser)
+ nc_osc_utils.add_project_owner_option_to_parser(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ client = self.app.client_manager.neutronclient
+ attrs = _get_attrs(self.app.client_manager, parsed_args)
+ body = {}
+ body[constants.BGP_SPEAKER] = attrs
+ obj = client.create_bgp_speaker(body)[constants.BGP_SPEAKER]
+ columns, display_columns = nc_osc_utils.get_columns(obj)
+ data = utils.get_dict_properties(obj, columns)
+ return display_columns, data
+
+
+class DeleteBgpSpeaker(command.Command):
+ _description = _("Delete a BGP speaker")
+
+ def get_parser(self, prog_name):
+ parser = super(DeleteBgpSpeaker, self).get_parser(prog_name)
+ parser.add_argument(
+ 'bgp_speaker',
+ metavar="<bgp-speaker>",
+ help=_("BGP speaker to delete (name or ID)")
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ client = self.app.client_manager.neutronclient
+ id = client.find_resource(constants.BGP_SPEAKER,
+ parsed_args.bgp_speaker)['id']
+ client.delete_bgp_speaker(id)
+
+
+class ListBgpSpeaker(command.Lister):
+ _description = _("List BGP speakers")
+
+ def get_parser(self, prog_name):
+ parser = super(ListBgpSpeaker, self).get_parser(prog_name)
+ parser.add_argument(
+ '--agent',
+ metavar='<agent-id>',
+ help=_("List BGP speakers hosted by an agent (ID only)"))
+ return parser
+
+ def take_action(self, parsed_args):
+ client = self.app.client_manager.neutronclient
+ if parsed_args.agent is not None:
+ data = client.list_bgp_speaker_on_dragent(parsed_args.agent_id)
+ else:
+ data = client.list_bgp_speakers()
+
+ headers = ('ID', 'Name', 'Local AS', 'IP Version')
+ columns = ('id', 'name', 'local_as', 'ip_version')
+ return (headers, (utils.get_dict_properties(s, columns)
+ for s in data[constants.BGP_SPEAKERS]))
+
+
+class ListRoutesAdvertisedBySpeaker(command.Lister):
+ _description = _("List routes advertised")
+
+ def get_parser(self, prog_name):
+ parser = super(ListRoutesAdvertisedBySpeaker,
+ self).get_parser(prog_name)
+ parser.add_argument(
+ 'bgp_speaker',
+ metavar='<bgp-speaker>',
+ help=_("BGP speaker (name or ID)"))
+ return parser
+
+ def take_action(self, parsed_args):
+ client = self.app.client_manager.neutronclient
+ speaker_id = client.find_resource(constants.BGP_SPEAKER,
+ parsed_args.bgp_speaker)['id']
+ data = client.list_route_advertised_from_bgp_speaker(speaker_id)
+ headers = ('ID', 'Destination', 'Nexthop')
+ columns = ('id', 'destination', 'next_hop')
+ return (headers, (utils.get_dict_properties(s, columns)
+ for s in data['advertised_routes']))
+
+
+class RemoveNetworkFromSpeaker(command.Command):
+ _description = _("Remove a network from a BGP speaker")
+
+ def get_parser(self, prog_name):
+ parser = super(RemoveNetworkFromSpeaker, self).get_parser(prog_name)
+ parser.add_argument(
+ 'bgp_speaker',
+ metavar='<bgp-speaker>',
+ help=_("BGP speaker (name or ID)"))
+ parser.add_argument(
+ 'network',
+ metavar='<network>',
+ help=_("Network to remove (name or ID)"))
+ return parser
+
+ def take_action(self, parsed_args):
+ client = self.app.client_manager.neutronclient
+ speaker_id = client.find_resource(constants.BGP_SPEAKER,
+ parsed_args.bgp_speaker)['id']
+ net_id = client.find_resource('network',
+ parsed_args.network)['id']
+ client.remove_network_from_bgp_speaker(speaker_id,
+ {'network_id': net_id})
+
+
+class RemovePeerFromSpeaker(command.Command):
+ _description = _("Remove a peer from a BGP speaker")
+
+ def get_parser(self, prog_name):
+ parser = super(RemovePeerFromSpeaker, self).get_parser(prog_name)
+ parser.add_argument(
+ 'bgp_speaker',
+ metavar='<bgp-speaker>',
+ help=_("BGP speaker (name or ID)"))
+ parser.add_argument(
+ 'bgp_peer',
+ metavar='<bgp-peer>',
+ help=_("BGP Peer to remove (name or ID)"))
+ return parser
+
+ def take_action(self, parsed_args):
+ client = self.app.client_manager.neutronclient
+ speaker_id = client.find_resource(constants.BGP_SPEAKER,
+ parsed_args.bgp_speaker)['id']
+ peer_id = client.find_resource(constants.BGP_PEER,
+ parsed_args.bgp_peer)['id']
+ client.remove_peer_from_bgp_speaker(speaker_id,
+ {'bgp_peer_id': peer_id})
+
+
+class SetBgpSpeaker(command.Command):
+ _description = _("Set BGP speaker properties")
+
+ resource = constants.BGP_SPEAKER
+
+ def get_parser(self, prog_name):
+ parser = super(SetBgpSpeaker, self).get_parser(prog_name)
+ parser.add_argument(
+ 'bgp_speaker',
+ metavar="<bgp-speaker>",
+ help=_("BGP speaker to update (name or ID)")
+ )
+ parser.add_argument(
+ '--name',
+ help=_("Name of the BGP speaker to update"))
+ add_common_arguments(parser)
+ return parser
+
+ def take_action(self, parsed_args):
+ client = self.app.client_manager.neutronclient
+ id = client.find_resource(constants.BGP_SPEAKER,
+ parsed_args.bgp_speaker)['id']
+ attrs = _get_attrs(self.app.client_manager, parsed_args)
+ body = {}
+ body[constants.BGP_SPEAKER] = attrs
+ client.update_bgp_speaker(id, body)
+
+
+class ShowBgpSpeaker(command.ShowOne):
+ _description = _("Show a BGP speaker")
+
+ def get_parser(self, prog_name):
+ parser = super(ShowBgpSpeaker, self).get_parser(prog_name)
+ parser.add_argument(
+ 'bgp_speaker',
+ metavar="<bgp-speaker>",
+ help=_("BGP speaker to display (name or ID)")
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ client = self.app.client_manager.neutronclient
+ id = client.find_resource(constants.BGP_SPEAKER,
+ parsed_args.bgp_speaker)['id']
+ obj = client.show_bgp_speaker(id)[constants.BGP_SPEAKER]
+ columns, display_columns = nc_osc_utils.get_columns(obj)
+ data = utils.get_dict_properties(obj, columns)
+ return display_columns, data
diff --git a/neutronclient/osc/v2/dynamic_routing/constants.py b/neutronclient/osc/v2/dynamic_routing/constants.py
new file mode 100644
index 0000000..0dd16b1
--- /dev/null
+++ b/neutronclient/osc/v2/dynamic_routing/constants.py
@@ -0,0 +1,18 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+BGP_SPEAKERS = 'bgp_speakers'
+BGP_SPEAKER = 'bgp_speaker'
+BGP_PEERS = 'bgp_peers'
+BGP_PEER = 'bgp_peer'
+MIN_AS_NUM = 1
+MAX_AS_NUM = 65535