Merge "BGP Dynamic Routing: neutronclient changes"
This commit is contained in:
		
							
								
								
									
										0
									
								
								neutronclient/neutron/v2_0/bgp/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								neutronclient/neutron/v2_0/bgp/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										117
									
								
								neutronclient/neutron/v2_0/bgp/dragentscheduler.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								neutronclient/neutron/v2_0/bgp/dragentscheduler.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,117 @@ | ||||
| # Copyright 2016 Huawei Technologies India Pvt. Ltd. | ||||
| # All Rights Reserved. | ||||
| # | ||||
| #    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 __future__ import print_function | ||||
|  | ||||
| from neutronclient._i18n import _ | ||||
| from neutronclient.neutron import v2_0 as neutronV20 | ||||
| from neutronclient.neutron.v2_0.bgp import speaker as bgp_speaker | ||||
|  | ||||
|  | ||||
| def add_common_args(parser): | ||||
|     parser.add_argument('dragent_id', | ||||
|                         metavar='BGP_DRAGENT_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(neutronV20.NeutronCommand): | ||||
|     """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): | ||||
|         neutron_client = self.get_client() | ||||
|         _speaker_id = bgp_speaker.get_bgp_speaker_id(neutron_client, | ||||
|                                                      parsed_args.bgp_speaker) | ||||
|         neutron_client.add_bgp_speaker_to_dragent( | ||||
|             parsed_args.dragent_id, {'bgp_speaker_id': _speaker_id}) | ||||
|         print(_('Associated BGP speaker %s to the Dynamic Routing agent.') | ||||
|               % parsed_args.bgp_speaker, file=self.app.stdout) | ||||
|  | ||||
|  | ||||
| class RemoveBGPSpeakerFromDRAgent(neutronV20.NeutronCommand): | ||||
|     """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): | ||||
|         neutron_client = self.get_client() | ||||
|         _speaker_id = bgp_speaker.get_bgp_speaker_id(neutron_client, | ||||
|                                                      parsed_args.bgp_speaker) | ||||
|         neutron_client.remove_bgp_speaker_from_dragent(parsed_args.dragent_id, | ||||
|                                                        _speaker_id) | ||||
|         print(_('Disassociated BGP speaker %s from the ' | ||||
|                 'Dynamic Routing agent.') | ||||
|               % parsed_args.bgp_speaker, file=self.app.stdout) | ||||
|  | ||||
|  | ||||
| class ListBGPSpeakersOnDRAgent(neutronV20.ListCommand): | ||||
|     """List BGP speakers hosted by a Dynamic Routing agent.""" | ||||
|  | ||||
|     list_columns = ['id', 'name', 'local_as', 'ip_version'] | ||||
|     resource = 'bgp_speaker' | ||||
|  | ||||
|     def get_parser(self, prog_name): | ||||
|         parser = super(ListBGPSpeakersOnDRAgent, | ||||
|                        self).get_parser(prog_name) | ||||
|         parser.add_argument( | ||||
|             'dragent_id', | ||||
|             metavar='BGP_DRAGENT_ID', | ||||
|             help=_('ID of the Dynamic Routing agent.')) | ||||
|         return parser | ||||
|  | ||||
|     def call_server(self, neutron_client, search_opts, parsed_args): | ||||
|         data = neutron_client.list_bgp_speaker_on_dragent( | ||||
|             parsed_args.dragent_id, **search_opts) | ||||
|         return data | ||||
|  | ||||
|  | ||||
| class ListDRAgentsHostingBGPSpeaker(neutronV20.ListCommand): | ||||
|     """List Dynamic Routing agents hosting a BGP speaker.""" | ||||
|  | ||||
|     resource = 'agent' | ||||
|     _formatters = {} | ||||
|     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 extend_list(self, data, parsed_args): | ||||
|         for agent in data: | ||||
|             agent['alive'] = ":-)" if agent['alive'] else 'xxx' | ||||
|  | ||||
|     def call_server(self, neutron_client, search_opts, parsed_args): | ||||
|         _speaker_id = bgp_speaker.get_bgp_speaker_id(neutron_client, | ||||
|                                                      parsed_args.bgp_speaker) | ||||
|         search_opts['bgp_speaker'] = _speaker_id | ||||
|         data = neutron_client.list_dragents_hosting_bgp_speaker(**search_opts) | ||||
|         return data | ||||
							
								
								
									
										127
									
								
								neutronclient/neutron/v2_0/bgp/peer.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								neutronclient/neutron/v2_0/bgp/peer.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,127 @@ | ||||
| # Copyright 2016 Huawei Technologies India Pvt. Ltd. | ||||
| # All Rights Reserved. | ||||
| # | ||||
| #    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 neutronclient._i18n import _ | ||||
| from neutronclient.common import exceptions | ||||
| from neutronclient.common import utils | ||||
| from neutronclient.common import validators | ||||
| from neutronclient.neutron import v2_0 as neutronv20 | ||||
|  | ||||
|  | ||||
| def get_bgp_peer_id(client, id_or_name): | ||||
|     return neutronv20.find_resourceid_by_name_or_id(client, | ||||
|                                                     'bgp_peer', | ||||
|                                                     id_or_name) | ||||
|  | ||||
|  | ||||
| def validate_peer_attributes(parsed_args): | ||||
|     # Validate AS number | ||||
|     validators.validate_int_range(parsed_args, 'remote_as', | ||||
|                                   neutronv20.bgp.speaker.MIN_AS_NUM, | ||||
|                                   neutronv20.bgp.speaker.MAX_AS_NUM) | ||||
|     # Validate password | ||||
|     if parsed_args.auth_type != 'none' and 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: | ||||
|         raise exceptions.CommandError(_('Must provide auth-type if password ' | ||||
|                                         'is specified.')) | ||||
|  | ||||
|  | ||||
| class ListPeers(neutronv20.ListCommand): | ||||
|     """List BGP peers.""" | ||||
|  | ||||
|     resource = 'bgp_peer' | ||||
|     list_columns = ['id', 'name', 'peer_ip', 'remote_as'] | ||||
|     pagination_support = True | ||||
|     sorting_support = True | ||||
|  | ||||
|  | ||||
| class ShowPeer(neutronv20.ShowCommand): | ||||
|     """Show information of a given BGP peer.""" | ||||
|  | ||||
|     resource = 'bgp_peer' | ||||
|  | ||||
|  | ||||
| class CreatePeer(neutronv20.CreateCommand): | ||||
|     """Create a BGP Peer.""" | ||||
|  | ||||
|     resource = 'bgp_peer' | ||||
|  | ||||
|     def add_known_arguments(self, parser): | ||||
|         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': neutronv20.bgp.speaker.MIN_AS_NUM, | ||||
|              'max_val': neutronv20.bgp.speaker.MAX_AS_NUM}) | ||||
|         parser.add_argument( | ||||
|             '--auth-type', | ||||
|             metavar='PEER_AUTH_TYPE', | ||||
|             choices=['none', 'md5'], | ||||
|             default='none', | ||||
|             type=utils.convert_to_lowercase, | ||||
|             help=_('Authentication algorithm. Supported algorithms: ' | ||||
|                    'none(default), md5')) | ||||
|         parser.add_argument( | ||||
|             '--password', | ||||
|             metavar='AUTH_PASSWORD', | ||||
|             help=_('Authentication password.')) | ||||
|  | ||||
|     def args2body(self, parsed_args): | ||||
|         body = {} | ||||
|         validate_peer_attributes(parsed_args) | ||||
|         neutronv20.update_dict(parsed_args, body, | ||||
|                                ['name', 'peer_ip', | ||||
|                                 'remote_as', 'auth_type', 'password']) | ||||
|         return {self.resource: body} | ||||
|  | ||||
|  | ||||
| class UpdatePeer(neutronv20.UpdateCommand): | ||||
|     """Update BGP Peer's information.""" | ||||
|  | ||||
|     resource = 'bgp_peer' | ||||
|  | ||||
|     def add_known_arguments(self, parser): | ||||
|         parser.add_argument( | ||||
|             '--name', | ||||
|             help=_('Updated name of the BGP peer.')) | ||||
|         parser.add_argument( | ||||
|             '--password', | ||||
|             metavar='AUTH_PASSWORD', | ||||
|             help=_('Updated authentication password.')) | ||||
|  | ||||
|     def args2body(self, parsed_args): | ||||
|         body = {} | ||||
|         neutronv20.update_dict(parsed_args, body, ['name', 'password']) | ||||
|         return {self.resource: body} | ||||
|  | ||||
|  | ||||
| class DeletePeer(neutronv20.DeleteCommand): | ||||
|     """Delete a BGP peer.""" | ||||
|  | ||||
|     resource = 'bgp_peer' | ||||
							
								
								
									
										277
									
								
								neutronclient/neutron/v2_0/bgp/speaker.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										277
									
								
								neutronclient/neutron/v2_0/bgp/speaker.py
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,277 @@ | ||||
| # Copyright 2016 Huawei Technologies India Pvt. Ltd. | ||||
| # All Rights Reserved. | ||||
| # | ||||
| #    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 __future__ import print_function | ||||
|  | ||||
| from neutronclient._i18n import _ | ||||
| from neutronclient.common import utils | ||||
| from neutronclient.common import validators | ||||
| from neutronclient.neutron import v2_0 as neutronv20 | ||||
| from neutronclient.neutron.v2_0.bgp import peer as bgp_peer | ||||
|  | ||||
| # Allowed BGP Autonomous number range | ||||
| MIN_AS_NUM = 1 | ||||
| MAX_AS_NUM = 65535 | ||||
|  | ||||
|  | ||||
| def get_network_id(client, id_or_name): | ||||
|     return neutronv20.find_resourceid_by_name_or_id(client, | ||||
|                                                     'network', | ||||
|                                                     id_or_name) | ||||
|  | ||||
|  | ||||
| def get_bgp_speaker_id(client, id_or_name): | ||||
|     return neutronv20.find_resourceid_by_name_or_id(client, | ||||
|                                                     'bgp_speaker', | ||||
|                                                     id_or_name) | ||||
|  | ||||
|  | ||||
| def validate_speaker_attributes(parsed_args): | ||||
|     # Validate AS number | ||||
|     validators.validate_int_range(parsed_args, 'local_as', | ||||
|                                   MIN_AS_NUM, MAX_AS_NUM) | ||||
|  | ||||
|  | ||||
| def add_common_arguments(parser): | ||||
|     utils.add_boolean_argument( | ||||
|         parser, '--advertise-floating-ip-host-routes', | ||||
|         help=_('Whether to enable or disable the advertisement ' | ||||
|                'of floating-ip host routes by the BGP speaker. ' | ||||
|                'By default floating ip host routes will be ' | ||||
|                'advertised by the BGP speaker.')) | ||||
|     utils.add_boolean_argument( | ||||
|         parser, '--advertise-tenant-networks', | ||||
|         help=_('Whether to enable or disable the advertisement ' | ||||
|                'of tenant network routes by the BGP speaker. ' | ||||
|                'By default tenant network routes will be ' | ||||
|                'advertised by the BGP speaker.')) | ||||
|  | ||||
|  | ||||
| def args2body_common_arguments(body, parsed_args): | ||||
|     neutronv20.update_dict(parsed_args, body, | ||||
|                            ['name', | ||||
|                             'advertise_floating_ip_host_routes', | ||||
|                             'advertise_tenant_networks']) | ||||
|  | ||||
|  | ||||
| class ListSpeakers(neutronv20.ListCommand): | ||||
|     """List BGP speakers.""" | ||||
|  | ||||
|     resource = 'bgp_speaker' | ||||
|     list_columns = ['id', 'name', 'local_as', 'ip_version'] | ||||
|     pagination_support = True | ||||
|     sorting_support = True | ||||
|  | ||||
|  | ||||
| class ShowSpeaker(neutronv20.ShowCommand): | ||||
|     """Show information of a given BGP speaker.""" | ||||
|  | ||||
|     resource = 'bgp_speaker' | ||||
|  | ||||
|  | ||||
| class CreateSpeaker(neutronv20.CreateCommand): | ||||
|     """Create a BGP Speaker.""" | ||||
|  | ||||
|     resource = 'bgp_speaker' | ||||
|  | ||||
|     def add_known_arguments(self, parser): | ||||
|         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': MIN_AS_NUM, | ||||
|                                       'max_val': 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) | ||||
|  | ||||
|     def args2body(self, parsed_args): | ||||
|         body = {} | ||||
|         validate_speaker_attributes(parsed_args) | ||||
|         body['local_as'] = parsed_args.local_as | ||||
|         body['ip_version'] = parsed_args.ip_version | ||||
|         args2body_common_arguments(body, parsed_args) | ||||
|         return {self.resource: body} | ||||
|  | ||||
|  | ||||
| class UpdateSpeaker(neutronv20.UpdateCommand): | ||||
|     """Update BGP Speaker's information.""" | ||||
|  | ||||
|     resource = 'bgp_speaker' | ||||
|  | ||||
|     def add_known_arguments(self, parser): | ||||
|         parser.add_argument( | ||||
|             '--name', | ||||
|             help=_('Name of the BGP speaker to update.')) | ||||
|         add_common_arguments(parser) | ||||
|  | ||||
|     def args2body(self, parsed_args): | ||||
|         body = {} | ||||
|         args2body_common_arguments(body, parsed_args) | ||||
|         return {self.resource: body} | ||||
|  | ||||
|  | ||||
| class DeleteSpeaker(neutronv20.DeleteCommand): | ||||
|     """Delete a BGP speaker.""" | ||||
|  | ||||
|     resource = 'bgp_speaker' | ||||
|  | ||||
|  | ||||
| class AddPeerToSpeaker(neutronv20.NeutronCommand): | ||||
|     """Add a peer to the 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=_('ID or name of the BGP speaker.')) | ||||
|         parser.add_argument( | ||||
|             'bgp_peer', | ||||
|             metavar='BGP_PEER', | ||||
|             help=_('ID or name of the BGP peer to add.')) | ||||
|         return parser | ||||
|  | ||||
|     def run(self, parsed_args): | ||||
|         neutron_client = self.get_client() | ||||
|         _speaker_id = get_bgp_speaker_id(neutron_client, | ||||
|                                          parsed_args.bgp_speaker) | ||||
|         _peer_id = bgp_peer.get_bgp_peer_id(neutron_client, | ||||
|                                             parsed_args.bgp_peer) | ||||
|         neutron_client.add_peer_to_bgp_speaker(_speaker_id, | ||||
|                                                {'bgp_peer_id': _peer_id}) | ||||
|         print(_('Added BGP peer %(peer)s to BGP speaker %(speaker)s.') % | ||||
|               {'peer': parsed_args.bgp_peer, | ||||
|                'speaker': parsed_args.bgp_speaker}, | ||||
|               file=self.app.stdout) | ||||
|  | ||||
|  | ||||
| class RemovePeerFromSpeaker(neutronv20.NeutronCommand): | ||||
|     """Remove a peer from the 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=_('ID or name of the BGP speaker.')) | ||||
|         parser.add_argument( | ||||
|             'bgp_peer', | ||||
|             metavar='BGP_PEER', | ||||
|             help=_('ID or name of the BGP peer to remove.')) | ||||
|         return parser | ||||
|  | ||||
|     def run(self, parsed_args): | ||||
|         neutron_client = self.get_client() | ||||
|         _speaker_id = get_bgp_speaker_id(neutron_client, | ||||
|                                          parsed_args.bgp_speaker) | ||||
|         _peer_id = bgp_peer.get_bgp_peer_id(neutron_client, | ||||
|                                             parsed_args.bgp_peer) | ||||
|         neutron_client.remove_peer_from_bgp_speaker(_speaker_id, | ||||
|                                                     {'bgp_peer_id': _peer_id}) | ||||
|         print(_('Removed BGP peer %(peer)s from BGP speaker %(speaker)s.') % | ||||
|               {'peer':  parsed_args.bgp_peer, | ||||
|                'speaker': parsed_args.bgp_speaker}, | ||||
|               file=self.app.stdout) | ||||
|  | ||||
|  | ||||
| class AddNetworkToSpeaker(neutronv20.NeutronCommand): | ||||
|     """Add a network to the 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=_('ID or name of the BGP speaker.')) | ||||
|         parser.add_argument( | ||||
|             'network', | ||||
|             metavar='NETWORK', | ||||
|             help=_('ID or name of the network to add.')) | ||||
|         return parser | ||||
|  | ||||
|     def run(self, parsed_args): | ||||
|         neutron_client = self.get_client() | ||||
|         _speaker_id = get_bgp_speaker_id(neutron_client, | ||||
|                                          parsed_args.bgp_speaker) | ||||
|         _net_id = get_network_id(neutron_client, | ||||
|                                  parsed_args.network) | ||||
|         neutron_client.add_network_to_bgp_speaker(_speaker_id, | ||||
|                                                   {'network_id': _net_id}) | ||||
|         print(_('Added network %(net)s to BGP speaker %(speaker)s.') % | ||||
|               {'net': parsed_args.network, 'speaker': parsed_args.bgp_speaker}, | ||||
|               file=self.app.stdout) | ||||
|  | ||||
|  | ||||
| class RemoveNetworkFromSpeaker(neutronv20.NeutronCommand): | ||||
|     """Remove a network from the 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=_('ID or name of the BGP speaker.')) | ||||
|         parser.add_argument( | ||||
|             'network', | ||||
|             metavar='NETWORK', | ||||
|             help=_('ID or name of the network to remove.')) | ||||
|         return parser | ||||
|  | ||||
|     def run(self, parsed_args): | ||||
|         neutron_client = self.get_client() | ||||
|         _speaker_id = get_bgp_speaker_id(neutron_client, | ||||
|                                          parsed_args.bgp_speaker) | ||||
|         _net_id = get_network_id(neutron_client, | ||||
|                                  parsed_args.network) | ||||
|         neutron_client.remove_network_from_bgp_speaker(_speaker_id, | ||||
|                                                        {'network_id': _net_id}) | ||||
|         print(_('Removed network %(net)s from BGP speaker %(speaker)s.') % | ||||
|               {'net': parsed_args.network, 'speaker': parsed_args.bgp_speaker}, | ||||
|               file=self.app.stdout) | ||||
|  | ||||
|  | ||||
| class ListRoutesAdvertisedBySpeaker(neutronv20.ListCommand): | ||||
|     """List routes advertised by a given BGP speaker.""" | ||||
|  | ||||
|     list_columns = ['id', 'destination', 'next_hop'] | ||||
|     resource = 'advertised_route' | ||||
|     pagination_support = True | ||||
|     sorting_support = True | ||||
|  | ||||
|     def get_parser(self, prog_name): | ||||
|         parser = super(ListRoutesAdvertisedBySpeaker, | ||||
|                        self).get_parser(prog_name) | ||||
|         parser.add_argument( | ||||
|             'bgp_speaker', | ||||
|             metavar='BGP_SPEAKER', | ||||
|             help=_('ID or name of the BGP speaker.')) | ||||
|         return parser | ||||
|  | ||||
|     def call_server(self, neutron_client, search_opts, parsed_args): | ||||
|         _speaker_id = get_bgp_speaker_id(neutron_client, | ||||
|                                          parsed_args.bgp_speaker) | ||||
|         data = neutron_client.list_route_advertised_from_bgp_speaker( | ||||
|             _speaker_id, **search_opts) | ||||
|         return data | ||||
| @@ -45,6 +45,9 @@ from neutronclient.neutron.v2_0 import agent | ||||
| from neutronclient.neutron.v2_0 import agentscheduler | ||||
| from neutronclient.neutron.v2_0 import auto_allocated_topology | ||||
| from neutronclient.neutron.v2_0 import availability_zone | ||||
| from neutronclient.neutron.v2_0.bgp import dragentscheduler as bgp_drsched | ||||
| from neutronclient.neutron.v2_0.bgp import peer as bgp_peer | ||||
| from neutronclient.neutron.v2_0.bgp import speaker as bgp_speaker | ||||
| from neutronclient.neutron.v2_0 import extension | ||||
| from neutronclient.neutron.v2_0.flavor import flavor | ||||
| from neutronclient.neutron.v2_0.flavor import flavor_profile | ||||
| @@ -395,6 +398,35 @@ COMMAND_V2 = { | ||||
|     'availability-zone-list': availability_zone.ListAvailabilityZone, | ||||
|     'auto-allocated-topology-show': ( | ||||
|         auto_allocated_topology.ShowAutoAllocatedTopology), | ||||
|     'bgp-dragent-speaker-add': ( | ||||
|         bgp_drsched.AddBGPSpeakerToDRAgent | ||||
|     ), | ||||
|     'bgp-dragent-speaker-remove': ( | ||||
|         bgp_drsched.RemoveBGPSpeakerFromDRAgent | ||||
|     ), | ||||
|     'bgp-speaker-list-on-dragent': ( | ||||
|         bgp_drsched.ListBGPSpeakersOnDRAgent | ||||
|     ), | ||||
|     'bgp-dragent-list-hosting-speaker': ( | ||||
|         bgp_drsched.ListDRAgentsHostingBGPSpeaker | ||||
|     ), | ||||
|     'bgp-speaker-list': bgp_speaker.ListSpeakers, | ||||
|     'bgp-speaker-advertiseroute-list': ( | ||||
|         bgp_speaker.ListRoutesAdvertisedBySpeaker | ||||
|     ), | ||||
|     'bgp-speaker-show': bgp_speaker.ShowSpeaker, | ||||
|     'bgp-speaker-create': bgp_speaker.CreateSpeaker, | ||||
|     'bgp-speaker-update': bgp_speaker.UpdateSpeaker, | ||||
|     'bgp-speaker-delete': bgp_speaker.DeleteSpeaker, | ||||
|     'bgp-speaker-peer-add': bgp_speaker.AddPeerToSpeaker, | ||||
|     'bgp-speaker-peer-remove': bgp_speaker.RemovePeerFromSpeaker, | ||||
|     'bgp-speaker-network-add': bgp_speaker.AddNetworkToSpeaker, | ||||
|     'bgp-speaker-network-remove': bgp_speaker.RemoveNetworkFromSpeaker, | ||||
|     'bgp-peer-list': bgp_peer.ListPeers, | ||||
|     'bgp-peer-show': bgp_peer.ShowPeer, | ||||
|     'bgp-peer-create': bgp_peer.CreatePeer, | ||||
|     'bgp-peer-update': bgp_peer.UpdatePeer, | ||||
|     'bgp-peer-delete': bgp_peer.DeletePeer, | ||||
| } | ||||
|  | ||||
| COMMANDS = {'2.0': COMMAND_V2} | ||||
|   | ||||
							
								
								
									
										0
									
								
								neutronclient/tests/unit/bgp/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								neutronclient/tests/unit/bgp/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										66
									
								
								neutronclient/tests/unit/bgp/test_cli20_dragentscheduler.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								neutronclient/tests/unit/bgp/test_cli20_dragentscheduler.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| # Copyright 2016 Huawei Technologies India Pvt. Ltd. | ||||
| # All Rights Reserved | ||||
| # | ||||
| #    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. | ||||
| # | ||||
|  | ||||
| import sys | ||||
|  | ||||
| from neutronclient.neutron.v2_0.bgp import dragentscheduler as bgp_drsched | ||||
| from neutronclient.tests.unit import test_cli20 | ||||
| from neutronclient.tests.unit import test_cli20_agentschedulers as test_as | ||||
|  | ||||
|  | ||||
| BGP_DRAGENT_ID = 'bgp_dragent_id1' | ||||
| BGP_SPEAKER = 'bgp_speaker_id1' | ||||
|  | ||||
|  | ||||
| class CLITestV20DRAgentScheduler(test_as.CLITestV20AgentScheduler): | ||||
|  | ||||
|     def test_add_bgp_speaker_to_dragent(self): | ||||
|         resource = 'agent' | ||||
|         cmd = bgp_drsched.AddBGPSpeakerToDRAgent( | ||||
|             test_cli20.MyApp(sys.stdout), None) | ||||
|         args = (BGP_DRAGENT_ID, BGP_SPEAKER) | ||||
|         body = {'bgp_speaker_id': BGP_SPEAKER} | ||||
|         result = {'bgp_speaker_id': 'bgp_speaker_id', } | ||||
|         self._test_add_to_agent(resource, cmd, args, | ||||
|                                 self.client.BGP_DRINSTANCES, | ||||
|                                 body, result) | ||||
|  | ||||
|     def test_remove_bgp_speaker_from_dragent(self): | ||||
|         resource = 'agent' | ||||
|         cmd = bgp_drsched.RemoveBGPSpeakerFromDRAgent( | ||||
|             test_cli20.MyApp(sys.stdout), None) | ||||
|         args = (BGP_DRAGENT_ID, BGP_SPEAKER) | ||||
|         self._test_remove_from_agent(resource, cmd, args, | ||||
|                                      self.client.BGP_DRINSTANCES) | ||||
|  | ||||
|     def test_list_bgp_speakers_on_dragent(self): | ||||
|         resources = 'bgp_speakers' | ||||
|         cmd = bgp_drsched.ListBGPSpeakersOnDRAgent( | ||||
|             test_cli20.MyApp(sys.stdout), None) | ||||
|         path = ((self.client.agent_path + self.client.BGP_DRINSTANCES) % | ||||
|                 BGP_DRAGENT_ID) | ||||
|         self._test_list_resources(resources, cmd, base_args=[BGP_DRAGENT_ID], | ||||
|                                   path=path) | ||||
|  | ||||
|     def test_list_dragents_hosting_bgp_speaker(self): | ||||
|         resources = 'agent' | ||||
|         cmd = bgp_drsched.ListDRAgentsHostingBGPSpeaker( | ||||
|             test_cli20.MyApp(sys.stdout), None) | ||||
|         path = ((self.client.bgp_speaker_path + self.client.BGP_DRAGENTS) % | ||||
|                 BGP_DRAGENT_ID) | ||||
|         contents = {self.id_field: 'myid1', 'alive': True} | ||||
|         self._test_list_resources(resources, cmd, base_args=[BGP_DRAGENT_ID], | ||||
|                                   path=path, response_contents=contents) | ||||
							
								
								
									
										223
									
								
								neutronclient/tests/unit/bgp/test_cli20_peer.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										223
									
								
								neutronclient/tests/unit/bgp/test_cli20_peer.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,223 @@ | ||||
| # Copyright 2016 Huawei Technologies India Pvt. Ltd. | ||||
| # All Rights Reserved | ||||
| # | ||||
| #    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. | ||||
| # | ||||
|  | ||||
| import sys | ||||
|  | ||||
| from neutronclient.common import exceptions | ||||
| from neutronclient.neutron.v2_0.bgp import peer as bgp_peer | ||||
| from neutronclient.neutron.v2_0.bgp import speaker as bgp_speaker | ||||
| from neutronclient.tests.unit import test_cli20 | ||||
|  | ||||
|  | ||||
| class CLITestV20BGPPeerJSON(test_cli20.CLITestV20Base): | ||||
|  | ||||
|     non_admin_status_resources = ['bgp_peer'] | ||||
|  | ||||
|     def test_create_bgp_peer_with_mandatory_params(self): | ||||
|         # Create BGP peer with mandatory params. | ||||
|         resource = 'bgp_peer' | ||||
|         cmd = bgp_peer.CreatePeer(test_cli20.MyApp(sys.stdout), | ||||
|                                   None) | ||||
|         name = 'my-name' | ||||
|         my_id = 'my-id' | ||||
|         peerip = '1.1.1.1' | ||||
|         remote_asnum = '1' | ||||
|         args = [name, | ||||
|                 '--peer-ip', peerip, | ||||
|                 '--remote-as', remote_asnum, ] | ||||
|         position_names = ['name', 'peer_ip', 'remote_as', | ||||
|                           'auth_type'] | ||||
|         position_values = [name, peerip, remote_asnum, 'none'] | ||||
|         self._test_create_resource(resource, cmd, name, my_id, args, | ||||
|                                    position_names, position_values) | ||||
|  | ||||
|     def test_create_bgp_peer_with_all_params(self): | ||||
|         # Create BGP peer with all params. | ||||
|         resource = 'bgp_peer' | ||||
|         cmd = bgp_peer.CreatePeer(test_cli20.MyApp(sys.stdout), | ||||
|                                   None) | ||||
|         name = 'my-name' | ||||
|         my_id = 'my-id' | ||||
|         peerip = '1.1.1.1' | ||||
|         remote_asnum = '65535' | ||||
|         authType = 'md5' | ||||
|         password = 'abc' | ||||
|         args = [name, | ||||
|                 '--peer-ip', peerip, | ||||
|                 '--remote-as', remote_asnum, | ||||
|                 '--auth-type', authType, | ||||
|                 '--password', password] | ||||
|         position_names = ['name', 'peer_ip', 'remote_as', | ||||
|                           'auth_type', 'password'] | ||||
|         position_values = [name, peerip, remote_asnum, authType, password] | ||||
|         self._test_create_resource(resource, cmd, name, my_id, args, | ||||
|                                    position_names, position_values) | ||||
|  | ||||
|     def test_create_bgp_peer_with_invalid_min_remote_asnum(self): | ||||
|         # Create BGP peer with invalid minimum remote-asnum. | ||||
|         resource = 'bgp_peer' | ||||
|         cmd = bgp_peer.CreatePeer(test_cli20.MyApp(sys.stdout), | ||||
|                                   None) | ||||
|         name = 'my-name' | ||||
|         my_id = 'my-id' | ||||
|         peerip = '1.1.1.1' | ||||
|         remote_asnum = '0' | ||||
|         args = [name, | ||||
|                 '--peer-ip', peerip, | ||||
|                 '--remote-as', remote_asnum, ] | ||||
|         position_names = ['name', 'peer_ip', 'remote_as', ] | ||||
|         position_values = [name, peerip, remote_asnum, ] | ||||
|         exc = self.assertRaises(exceptions.CommandError, | ||||
|                                 self._test_create_resource, | ||||
|                                 resource, cmd, name, my_id, args, | ||||
|                                 position_names, position_values) | ||||
|         self.assertEqual('remote-as "0" should be an integer [%s:%s].' % | ||||
|                          (bgp_speaker.MIN_AS_NUM, bgp_speaker.MAX_AS_NUM), | ||||
|                          str(exc)) | ||||
|  | ||||
|     def test_create_bgp_peer_with_invalid_max_remote_asnum(self): | ||||
|         # Create BGP peer with invalid maximum remote-asnum. | ||||
|         resource = 'bgp_peer' | ||||
|         cmd = bgp_peer.CreatePeer(test_cli20.MyApp(sys.stdout), | ||||
|                                   None) | ||||
|         name = 'my-name' | ||||
|         my_id = 'my-id' | ||||
|         peerip = '1.1.1.1' | ||||
|         remote_asnum = '65536' | ||||
|         args = [name, | ||||
|                 '--peer-ip', peerip, | ||||
|                 '--remote-as', remote_asnum, ] | ||||
|         position_names = ['name', 'peer_ip', 'remote_as', | ||||
|                           'auth_type', 'password'] | ||||
|         position_values = [name, peerip, remote_asnum, 'none', ''] | ||||
|         exc = self.assertRaises(exceptions.CommandError, | ||||
|                                 self._test_create_resource, | ||||
|                                 resource, cmd, name, my_id, args, | ||||
|                                 position_names, position_values) | ||||
|         self.assertEqual('remote-as "65536" should be an integer [%s:%s].' % | ||||
|                          (bgp_speaker.MIN_AS_NUM, bgp_speaker.MAX_AS_NUM), | ||||
|                          str(exc)) | ||||
|  | ||||
|     def test_create_authenticated_bgp_peer_without_authtype(self): | ||||
|         # Create authenticated BGP peer without auth-type. | ||||
|         resource = 'bgp_peer' | ||||
|         cmd = bgp_peer.CreatePeer(test_cli20.MyApp(sys.stdout), | ||||
|                                   None) | ||||
|         name = 'my-name' | ||||
|         my_id = 'my-id' | ||||
|         peerip = '1.1.1.1' | ||||
|         remote_asnum = '2048' | ||||
|         password = 'abc' | ||||
|         args = [name, | ||||
|                 '--peer-ip', peerip, | ||||
|                 '--remote-as', remote_asnum, | ||||
|                 '--password', password] | ||||
|         position_names = ['name', 'peer_ip', 'remote_as', 'password'] | ||||
|         position_values = [name, peerip, remote_asnum, password] | ||||
|         exc = self.assertRaises(exceptions.CommandError, | ||||
|                                 self._test_create_resource, | ||||
|                                 resource, cmd, name, my_id, args, | ||||
|                                 position_names, position_values) | ||||
|         self.assertEqual('Must provide auth-type if password is specified.', | ||||
|                          str(exc)) | ||||
|  | ||||
|     def test_create_authenticated_bgp_peer_without_password(self): | ||||
|         # Create authenticated BGP peer without password. | ||||
|         resource = 'bgp_peer' | ||||
|         cmd = bgp_peer.CreatePeer(test_cli20.MyApp(sys.stdout), | ||||
|                                   None) | ||||
|         name = 'my-name' | ||||
|         my_id = 'my-id' | ||||
|         peerip = '1.1.1.1' | ||||
|         remote_asnum = '2048' | ||||
|         authType = 'md5' | ||||
|         args = [name, | ||||
|                 '--peer-ip', peerip, | ||||
|                 '--remote-as', remote_asnum, | ||||
|                 '--auth-type', authType] | ||||
|         position_names = ['name', 'peer_ip', 'remote_as', 'auth-type'] | ||||
|         position_values = [name, peerip, remote_asnum, authType] | ||||
|         exc = self.assertRaises(exceptions.CommandError, | ||||
|                                 self._test_create_resource, | ||||
|                                 resource, cmd, name, my_id, args, | ||||
|                                 position_names, position_values) | ||||
|         self.assertEqual('Must provide password if auth-type is specified.', | ||||
|                          str(exc)) | ||||
|  | ||||
|     def test_update_bgp_peer(self): | ||||
|         # Update BGP peer: | ||||
|         # myid --advertise-tenant-networks True | ||||
|         #      --advertise-floating-ip-host-routes False | ||||
|         resource = 'bgp_peer' | ||||
|         cmd = bgp_peer.UpdatePeer(test_cli20.MyApp(sys.stdout), | ||||
|                                   None) | ||||
|         self._test_update_resource(resource, cmd, 'myid', | ||||
|                                    ['myid', '--name', 'new-name', | ||||
|                                     '--password', 'abc'], | ||||
|                                    {'name': 'new-name', 'password': 'abc'}) | ||||
|  | ||||
|     def test_update_bgp_peer_exception(self): | ||||
|         # Update BGP peer: myid. | ||||
|         resource = 'bgp_peer' | ||||
|         cmd = bgp_peer.UpdatePeer(test_cli20.MyApp(sys.stdout), | ||||
|                                   None) | ||||
|         self.assertRaises(exceptions.CommandError, | ||||
|                           self._test_update_resource, | ||||
|                           resource, cmd, 'myid', ['myid'], {}) | ||||
|  | ||||
|     def test_list_bgp_peer(self): | ||||
|         # List all BGP peers. | ||||
|         resources = "bgp_peers" | ||||
|         cmd = bgp_peer.ListPeers(test_cli20.MyApp(sys.stdout), | ||||
|                                  None) | ||||
|         self._test_list_resources(resources, cmd, True) | ||||
|  | ||||
|     # TODO(Vikram): Add test_list_bgp_peer_pagination | ||||
|  | ||||
|     def test_list_bgp_peer_sort(self): | ||||
|         # sorted list: bgp-peer-list --sort-key name --sort-key id | ||||
|         #                            --sort-key asc --sort-key desc | ||||
|         resources = "bgp_peers" | ||||
|         cmd = bgp_peer.ListPeers(test_cli20.MyApp(sys.stdout), | ||||
|                                  None) | ||||
|         self._test_list_resources(resources, cmd, | ||||
|                                   sort_key=["name", "id"], | ||||
|                                   sort_dir=["asc", "desc"]) | ||||
|  | ||||
|     def test_list_bgp_peer_limit(self): | ||||
|         # size (1000) limited list: bgp-peer-list -P. | ||||
|         resources = "bgp_peers" | ||||
|         cmd = bgp_peer.ListPeers(test_cli20.MyApp(sys.stdout), | ||||
|                                  None) | ||||
|         self._test_list_resources(resources, cmd, page_size=1000) | ||||
|  | ||||
|     def test_show_bgp_peer(self): | ||||
|         # Show BGP peer: --fields id --fields name myid. | ||||
|         resource = 'bgp_peer' | ||||
|         cmd = bgp_peer.ShowPeer(test_cli20.MyApp(sys.stdout), | ||||
|                                 None) | ||||
|         args = ['--fields', 'id', '--fields', 'name', self.test_id] | ||||
|         self._test_show_resource(resource, cmd, self.test_id, args, | ||||
|                                  ['id', 'name']) | ||||
|  | ||||
|     def test_delete_bgp_peer(self): | ||||
|         # Delete BGP peer: bgp_peer_id. | ||||
|         resource = 'bgp_peer' | ||||
|         cmd = bgp_peer.DeletePeer(test_cli20.MyApp(sys.stdout), | ||||
|                                   None) | ||||
|         myid = 'myid' | ||||
|         args = [myid] | ||||
|         self._test_delete_resource(resource, cmd, myid, args) | ||||
							
								
								
									
										267
									
								
								neutronclient/tests/unit/bgp/test_cli20_speaker.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										267
									
								
								neutronclient/tests/unit/bgp/test_cli20_speaker.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,267 @@ | ||||
| # Copyright 2016 Huawei Technologies India Pvt. Ltd. | ||||
| # All Rights Reserved | ||||
| # | ||||
| #    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. | ||||
| # | ||||
|  | ||||
| import sys | ||||
|  | ||||
| from mox3 import mox | ||||
|  | ||||
| from neutronclient.common import exceptions | ||||
| from neutronclient.neutron.v2_0.bgp import speaker as bgp_speaker | ||||
| from neutronclient.tests.unit import test_cli20 | ||||
|  | ||||
|  | ||||
| class CLITestV20BGPSpeakerJSON(test_cli20.CLITestV20Base): | ||||
|  | ||||
|     non_admin_status_resources = ['bgp_speaker'] | ||||
|  | ||||
|     def test_create_bgp_speaker_with_minimal_options(self): | ||||
|         # Create BGP Speaker with mandatory params. | ||||
|         resource = 'bgp_speaker' | ||||
|         cmd = bgp_speaker.CreateSpeaker(test_cli20.MyApp(sys.stdout), | ||||
|                                         None) | ||||
|         name = 'my-name' | ||||
|         my_id = 'my-id' | ||||
|         local_asnum = '1' | ||||
|         args = [name, '--local-as', local_asnum, ] | ||||
|         position_names = ['name', 'local_as', 'ip_version'] | ||||
|         position_values = [name, local_asnum, 4] | ||||
|         self._test_create_resource(resource, cmd, name, my_id, args, | ||||
|                                    position_names, position_values) | ||||
|  | ||||
|     def test_create_ipv4_bgp_speaker_with_all_params(self): | ||||
|         # Create BGP Speaker with all params. | ||||
|         resource = 'bgp_speaker' | ||||
|         cmd = bgp_speaker.CreateSpeaker(test_cli20.MyApp(sys.stdout), | ||||
|                                         None) | ||||
|         name = 'my-name' | ||||
|         my_id = 'my-id' | ||||
|         local_asnum = '1' | ||||
|         args = [name, | ||||
|                 '--local-as', local_asnum, | ||||
|                 '--ip-version', '4', | ||||
|                 '--advertise-floating-ip-host-routes', 'True', | ||||
|                 '--advertise-tenant-networks', 'True'] | ||||
|         position_names = ['name', 'local_as', 'ip_version', | ||||
|                           'advertise_floating_ip_host_routes', | ||||
|                           'advertise_tenant_networks'] | ||||
|         position_values = [name, local_asnum, 4, 'True', 'True'] | ||||
|         self._test_create_resource(resource, cmd, name, my_id, args, | ||||
|                                    position_names, position_values) | ||||
|  | ||||
|     def test_create_ipv6_bgp_speaker_with_all_params(self): | ||||
|         # Create BGP Speaker with all params. | ||||
|         resource = 'bgp_speaker' | ||||
|         cmd = bgp_speaker.CreateSpeaker(test_cli20.MyApp(sys.stdout), | ||||
|                                         None) | ||||
|         name = 'my-name' | ||||
|         my_id = 'my-id' | ||||
|         local_asnum = '65535' | ||||
|         args = [name, | ||||
|                 '--local-as', local_asnum, | ||||
|                 '--ip-version', '6', | ||||
|                 '--advertise-floating-ip-host-routes', 'True', | ||||
|                 '--advertise-tenant-networks', 'True'] | ||||
|         position_names = ['name', 'local_as', 'ip_version', | ||||
|                           'advertise_floating_ip_host_routes', | ||||
|                           'advertise_tenant_networks'] | ||||
|         position_values = [name, local_asnum, 6, 'True', 'True'] | ||||
|         self._test_create_resource(resource, cmd, name, my_id, args, | ||||
|                                    position_names, position_values) | ||||
|  | ||||
|     def test_create_bgp_speaker_with_invalid_min_local_asnum(self): | ||||
|         # Create BGP Speaker with invalid minimum local-asnum. | ||||
|         resource = 'bgp_speaker' | ||||
|         cmd = bgp_speaker.CreateSpeaker(test_cli20.MyApp(sys.stdout), | ||||
|                                         None) | ||||
|         name = 'my-name' | ||||
|         my_id = 'my-id' | ||||
|         local_asnum = '0' | ||||
|         args = [name, | ||||
|                 '--local-as', local_asnum] | ||||
|         position_names = ['name', 'local_as'] | ||||
|         position_values = [name, local_asnum] | ||||
|         exc = self.assertRaises(exceptions.CommandError, | ||||
|                                 self._test_create_resource, | ||||
|                                 resource, cmd, name, my_id, args, | ||||
|                                 position_names, position_values) | ||||
|         self.assertEqual('local-as "0" should be an integer [%s:%s].' % | ||||
|                          (bgp_speaker.MIN_AS_NUM, bgp_speaker.MAX_AS_NUM), | ||||
|                          str(exc)) | ||||
|  | ||||
|     def test_create_bgp_speaker_with_invalid_max_local_asnum(self): | ||||
|         # Create BGP Speaker with invalid maximum local-asnum. | ||||
|         resource = 'bgp_speaker' | ||||
|         cmd = bgp_speaker.CreateSpeaker(test_cli20.MyApp(sys.stdout), | ||||
|                                         None) | ||||
|         name = 'my-name' | ||||
|         my_id = 'my-id' | ||||
|         local_asnum = '65536' | ||||
|         args = [name, | ||||
|                 '--local-as', local_asnum] | ||||
|         position_names = ['name', 'local_as', ] | ||||
|         position_values = [name, local_asnum, ] | ||||
|         exc = self.assertRaises(exceptions.CommandError, | ||||
|                                 self._test_create_resource, | ||||
|                                 resource, cmd, name, my_id, args, | ||||
|                                 position_names, position_values) | ||||
|         self.assertEqual('local-as "65536" should be an integer [%s:%s].' % | ||||
|                          (bgp_speaker.MIN_AS_NUM, bgp_speaker.MAX_AS_NUM), | ||||
|                          str(exc)) | ||||
|  | ||||
|     def test_update_bgp_speaker(self): | ||||
|         # Update BGP Speaker: | ||||
|         # myid --advertise-tenant-networks True | ||||
|         #      --advertise-floating-ip-host-routes False | ||||
|         resource = 'bgp_speaker' | ||||
|         cmd = bgp_speaker.UpdateSpeaker(test_cli20.MyApp(sys.stdout), | ||||
|                                         None) | ||||
|         self._test_update_resource(resource, cmd, 'myid', | ||||
|                                    ['myid', | ||||
|                                     '--name', 'new-name', | ||||
|                                     '--advertise-tenant-networks', 'True', | ||||
|                                     '--advertise-floating-ip-host-routes', | ||||
|                                     'False'], | ||||
|                                    {'name': 'new-name', | ||||
|                                     'advertise_tenant_networks': 'True', | ||||
|                                     'advertise_floating_ip_host_routes': | ||||
|                                     'False'}) | ||||
|  | ||||
|     def test_update_bgp_speaker_exception(self): | ||||
|         # Update BGP Speaker: myid. | ||||
|         resource = 'bgp_speaker' | ||||
|         cmd = bgp_speaker.UpdateSpeaker(test_cli20.MyApp(sys.stdout), | ||||
|                                         None) | ||||
|         self.assertRaises(exceptions.CommandError, | ||||
|                           self._test_update_resource, | ||||
|                           resource, cmd, 'myid', ['myid'], {}) | ||||
|  | ||||
|     def test_list_bgp_speaker(self): | ||||
|         # List all BGP Speakers. | ||||
|         resources = "bgp_speakers" | ||||
|         cmd = bgp_speaker.ListSpeakers(test_cli20.MyApp(sys.stdout), | ||||
|                                        None) | ||||
|         self._test_list_resources(resources, cmd, True) | ||||
|  | ||||
|     def test_list_bgp_speaker_pagination(self): | ||||
|         # List all BGP Speakers with pagination support. | ||||
|         cmd = bgp_speaker.ListSpeakers(test_cli20.MyApp(sys.stdout), | ||||
|                                        None) | ||||
|         self.mox.StubOutWithMock(bgp_speaker.ListSpeakers, | ||||
|                                  "extend_list") | ||||
|         bgp_speaker.ListSpeakers.extend_list(mox.IsA(list), | ||||
|                                              mox.IgnoreArg()) | ||||
|         self._test_list_resources_with_pagination("bgp_speakers", | ||||
|                                                   cmd) | ||||
|         self.mox.VerifyAll() | ||||
|         self.mox.UnsetStubs() | ||||
|  | ||||
|     def test_list_bgp_speaker_sort(self): | ||||
|         # sorted list: bgp-speaker-list --sort-key name --sort-key id | ||||
|         #                               --sort-key asc --sort-key desc | ||||
|         resources = "bgp_speakers" | ||||
|         cmd = bgp_speaker.ListSpeakers(test_cli20.MyApp(sys.stdout), | ||||
|                                        None) | ||||
|         self._test_list_resources(resources, cmd, | ||||
|                                   sort_key=["name", "id"], | ||||
|                                   sort_dir=["asc", "desc"]) | ||||
|  | ||||
|     def test_list_bgp_speaker_limit(self): | ||||
|         # size (1000) limited list: bgp-speaker-list -P. | ||||
|         resources = "bgp_speakers" | ||||
|         cmd = bgp_speaker.ListSpeakers(test_cli20.MyApp(sys.stdout), | ||||
|                                        None) | ||||
|         self._test_list_resources(resources, cmd, page_size=1000) | ||||
|  | ||||
|     def test_show_bgp_speaker(self): | ||||
|         # Show BGP Speaker: --fields id --fields name myid. | ||||
|         resource = 'bgp_speaker' | ||||
|         cmd = bgp_speaker.ShowSpeaker(test_cli20.MyApp(sys.stdout), | ||||
|                                       None) | ||||
|         args = ['--fields', 'id', '--fields', 'name', self.test_id] | ||||
|         self._test_show_resource(resource, cmd, self.test_id, args, | ||||
|                                  ['id', 'name']) | ||||
|  | ||||
|     def test_delete_bgp_speaker(self): | ||||
|         # Delete BGP Speaker: bgp_speaker_id. | ||||
|         resource = 'bgp_speaker' | ||||
|         cmd = bgp_speaker.DeleteSpeaker(test_cli20.MyApp(sys.stdout), | ||||
|                                         None) | ||||
|         myid = 'myid' | ||||
|         args = [myid] | ||||
|         self._test_delete_resource(resource, cmd, myid, args) | ||||
|  | ||||
|     def _test_add_remove_peer(self, action, cmd, args): | ||||
|         """Add or Remove BGP Peer to/from a BGP Speaker.""" | ||||
|         resource = 'bgp_speaker' | ||||
|         subcmd = '%s_bgp_peer' % action | ||||
|         body = {'bgp_peer_id': 'peerid'} | ||||
|         if action == 'add': | ||||
|             retval = {'bgp_peer': 'peerid'} | ||||
|         else: | ||||
|             retval = None | ||||
|         self._test_update_resource_action(resource, cmd, 'myid', | ||||
|                                           subcmd, args, body, retval) | ||||
|  | ||||
|     def test_add_peer_to_bgp_speaker(self): | ||||
|         # Add peer to BGP speaker: myid peer_id=peerid | ||||
|         cmd = bgp_speaker.AddPeerToSpeaker(test_cli20.MyApp(sys.stdout), | ||||
|                                            None) | ||||
|         args = ['myid', 'peerid'] | ||||
|         self._test_add_remove_peer('add', cmd, args) | ||||
|  | ||||
|     def test_remove_peer_from_bgp_speaker(self): | ||||
|         # Remove peer from BGP speaker: myid peer_id=peerid | ||||
|         cmd = bgp_speaker.RemovePeerFromSpeaker(test_cli20.MyApp(sys.stdout), | ||||
|                                                 None) | ||||
|         args = ['myid', 'peerid'] | ||||
|         self._test_add_remove_peer('remove', cmd, args) | ||||
|  | ||||
|     def _test_add_remove_network(self, action, cmd, args): | ||||
|         # Add or Remove network to/from a BGP Speaker. | ||||
|         resource = 'bgp_speaker' | ||||
|         subcmd = '%s_gateway_network' % action | ||||
|         body = {'network_id': 'netid'} | ||||
|         if action == 'add': | ||||
|             retval = {'network': 'netid'} | ||||
|         else: | ||||
|             retval = None | ||||
|         self._test_update_resource_action(resource, cmd, 'myid', | ||||
|                                           subcmd, args, body, retval) | ||||
|  | ||||
|     def test_add_network_to_bgp_speaker(self): | ||||
|         # Add peer to BGP speaker: myid network_id=netid | ||||
|         cmd = bgp_speaker.AddNetworkToSpeaker(test_cli20.MyApp(sys.stdout), | ||||
|                                               None) | ||||
|         args = ['myid', 'netid'] | ||||
|         self._test_add_remove_network('add', cmd, args) | ||||
|  | ||||
|     def test_remove_network_from_bgp_speaker(self): | ||||
|         # Remove network from BGP speaker: myid network_id=netid | ||||
|         cmd = bgp_speaker.RemoveNetworkFromSpeaker( | ||||
|             test_cli20.MyApp(sys.stdout), None) | ||||
|         args = ['myid', 'netid'] | ||||
|         self._test_add_remove_network('remove', cmd, args) | ||||
|  | ||||
|     def test_list_routes_advertised_by_a_bgp_speaker(self): | ||||
|         # Retrieve advertised route list | ||||
|         resources = 'advertised_routes' | ||||
|         cmd = bgp_speaker.ListRoutesAdvertisedBySpeaker( | ||||
|             test_cli20.MyApp(sys.stdout), None) | ||||
|         bs_id = 'bgp_speaker_id1' | ||||
|         path = ((self.client.bgp_speaker_path + '/get_advertised_routes') % | ||||
|                 bs_id) | ||||
|         self._test_list_resources(resources, cmd, base_args=[bs_id], | ||||
|                                   path=path) | ||||
| @@ -404,6 +404,14 @@ class Client(ClientBase): | ||||
|     flavor_profile_binding_path = flavor_path + service_profile_path | ||||
|     availability_zones_path = "/availability_zones" | ||||
|     auto_allocated_topology_path = "/auto-allocated-topology/%s" | ||||
|     BGP_DRINSTANCES = "/bgp-drinstances" | ||||
|     BGP_DRINSTANCE = "/bgp-drinstance/%s" | ||||
|     BGP_DRAGENTS = "/bgp-dragents" | ||||
|     BGP_DRAGENT = "/bgp-dragents/%s" | ||||
|     bgp_speakers_path = "/bgp-speakers" | ||||
|     bgp_speaker_path = "/bgp-speakers/%s" | ||||
|     bgp_peers_path = "/bgp-peers" | ||||
|     bgp_peer_path = "/bgp-peers/%s" | ||||
|  | ||||
|     # API has no way to report plurals, so we have to hard code them | ||||
|     EXTED_PLURALS = {'routers': 'router', | ||||
| @@ -441,6 +449,8 @@ class Client(ClientBase): | ||||
|                      'bandwidth_limit_rules': 'bandwidth_limit_rule', | ||||
|                      'rule_types': 'rule_type', | ||||
|                      'flavors': 'flavor', | ||||
|                      'bgp_speakers': 'bgp_speaker', | ||||
|                      'bgp_peers': 'bgp_peer', | ||||
|                      } | ||||
|  | ||||
|     @APIParamsCall | ||||
| @@ -1340,6 +1350,30 @@ class Client(ClientBase): | ||||
|         return self.post((self.agent_path + self.L3_ROUTERS) % l3_agent, | ||||
|                          body=body) | ||||
|  | ||||
|     @APIParamsCall | ||||
|     def list_dragents_hosting_bgp_speaker(self, bgp_speaker, **_params): | ||||
|         """Fetches a list of Dynamic Routing agents hosting a BGP speaker.""" | ||||
|         return self.get((self.bgp_speaker_path + self.BGP_DRAGENTS) | ||||
|                         % bgp_speaker, params=_params) | ||||
|  | ||||
|     @APIParamsCall | ||||
|     def add_bgp_speaker_to_dragent(self, bgp_dragent, body): | ||||
|         """Adds a BGP speaker to Dynamic Routing agent.""" | ||||
|         return self.post((self.agent_path + self.BGP_DRINSTANCES) | ||||
|                          % bgp_dragent, body=body) | ||||
|  | ||||
|     @APIParamsCall | ||||
|     def remove_bgp_speaker_from_dragent(self, bgp_dragent, bgpspeaker_id): | ||||
|         """Removes a BGP speaker from Dynamic Routing agent.""" | ||||
|         return self.delete((self.agent_path + self.BGP_DRINSTANCES + "/%s") | ||||
|                            % (bgp_dragent, bgpspeaker_id)) | ||||
|  | ||||
|     @APIParamsCall | ||||
|     def list_bgp_speaker_on_dragent(self, bgp_dragent, **_params): | ||||
|         """Fetches a list of BGP speakers hosted by Dynamic Routing agent.""" | ||||
|         return self.get((self.agent_path + self.BGP_DRINSTANCES) | ||||
|                         % bgp_dragent, params=_params) | ||||
|  | ||||
|     @APIParamsCall | ||||
|     def list_firewall_rules(self, retrieve_all=True, **_params): | ||||
|         """Fetches a list of all firewall rules for a tenant.""" | ||||
| @@ -1695,6 +1729,89 @@ class Client(ClientBase): | ||||
|             self.auto_allocated_topology_path % tenant_id, | ||||
|             params=_params) | ||||
|  | ||||
|     @APIParamsCall | ||||
|     def list_bgp_speakers(self, retrieve_all=True, **_params): | ||||
|         """Fetches a list of all BGP speakers for a tenant.""" | ||||
|         return self.list('bgp_speakers', self.bgp_speakers_path, retrieve_all, | ||||
|                          **_params) | ||||
|  | ||||
|     @APIParamsCall | ||||
|     def show_bgp_speaker(self, bgp_speaker_id, **_params): | ||||
|         """Fetches information of a certain BGP speaker.""" | ||||
|         return self.get(self.bgp_speaker_path % (bgp_speaker_id), | ||||
|                         params=_params) | ||||
|  | ||||
|     @APIParamsCall | ||||
|     def create_bgp_speaker(self, body=None): | ||||
|         """Creates a new BGP speaker.""" | ||||
|         return self.post(self.bgp_speakers_path, body=body) | ||||
|  | ||||
|     @APIParamsCall | ||||
|     def update_bgp_speaker(self, bgp_speaker_id, body=None): | ||||
|         """Update a BGP speaker.""" | ||||
|         return self.put(self.bgp_speaker_path % bgp_speaker_id, body=body) | ||||
|  | ||||
|     @APIParamsCall | ||||
|     def delete_bgp_speaker(self, speaker_id): | ||||
|         """Deletes the specified BGP speaker.""" | ||||
|         return self.delete(self.bgp_speaker_path % (speaker_id)) | ||||
|  | ||||
|     @APIParamsCall | ||||
|     def add_peer_to_bgp_speaker(self, speaker_id, body=None): | ||||
|         """Adds a peer to BGP speaker.""" | ||||
|         return self.put((self.bgp_speaker_path % speaker_id) + | ||||
|                         "/add_bgp_peer", body=body) | ||||
|  | ||||
|     @APIParamsCall | ||||
|     def remove_peer_from_bgp_speaker(self, speaker_id, body=None): | ||||
|         """Removes a peer from BGP speaker.""" | ||||
|         return self.put((self.bgp_speaker_path % speaker_id) + | ||||
|                         "/remove_bgp_peer", body=body) | ||||
|  | ||||
|     @APIParamsCall | ||||
|     def add_network_to_bgp_speaker(self, speaker_id, body=None): | ||||
|         """Adds a network to BGP speaker.""" | ||||
|         return self.put((self.bgp_speaker_path % speaker_id) + | ||||
|                         "/add_gateway_network", body=body) | ||||
|  | ||||
|     @APIParamsCall | ||||
|     def remove_network_from_bgp_speaker(self, speaker_id, body=None): | ||||
|         """Removes a network from BGP speaker.""" | ||||
|         return self.put((self.bgp_speaker_path % speaker_id) + | ||||
|                         "/remove_gateway_network", body=body) | ||||
|  | ||||
|     @APIParamsCall | ||||
|     def list_route_advertised_from_bgp_speaker(self, speaker_id, **_params): | ||||
|         """Fetches a list of all routes advertised by BGP speaker.""" | ||||
|         return self.get((self.bgp_speaker_path % speaker_id) + | ||||
|                         "/get_advertised_routes", params=_params) | ||||
|  | ||||
|     @APIParamsCall | ||||
|     def list_bgp_peers(self, **_params): | ||||
|         """Fetches a list of all BGP peers.""" | ||||
|         return self.get(self.bgp_peers_path, params=_params) | ||||
|  | ||||
|     @APIParamsCall | ||||
|     def show_bgp_peer(self, peer_id, **_params): | ||||
|         """Fetches information of a certain BGP peer.""" | ||||
|         return self.get(self.bgp_peer_path % peer_id, | ||||
|                         params=_params) | ||||
|  | ||||
|     @APIParamsCall | ||||
|     def create_bgp_peer(self, body=None): | ||||
|         """Create a new BGP peer.""" | ||||
|         return self.post(self.bgp_peers_path, body=body) | ||||
|  | ||||
|     @APIParamsCall | ||||
|     def update_bgp_peer(self, bgp_peer_id, body=None): | ||||
|         """Update a BGP peer.""" | ||||
|         return self.put(self.bgp_peer_path % bgp_peer_id, body=body) | ||||
|  | ||||
|     @APIParamsCall | ||||
|     def delete_bgp_peer(self, peer_id): | ||||
|         """Deletes the specified BGP peer.""" | ||||
|         return self.delete(self.bgp_peer_path % peer_id) | ||||
|  | ||||
|     def __init__(self, **kwargs): | ||||
|         """Initialize a new client for the Neutron v2.0 API.""" | ||||
|         super(Client, self).__init__(**kwargs) | ||||
|   | ||||
| @@ -0,0 +1,5 @@ | ||||
| --- | ||||
| features: | ||||
|   - | | ||||
|     CLI support for the BGP dynamic routing functionality will help | ||||
|     advertising neutron fixed-ips and dvr host routes via BGP. | ||||
		Reference in New Issue
	
	Block a user
	 Jenkins
					Jenkins