1# Licensed under the Apache License, Version 2.0 (the "License"); you may 2# not use this file except in compliance with the License. You may obtain 3# a copy of the License at 4# 5# http://www.apache.org/licenses/LICENSE-2.0 6# 7# Unless required by applicable law or agreed to in writing, software 8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10# License for the specific language governing permissions and limitations 11# under the License. 12# 13 14from osc_lib.command import command 15from osc_lib import utils 16from osc_lib.utils import columns as column_util 17 18from neutronclient._i18n import _ 19from neutronclient.osc import utils as nc_osc_utils 20from neutronclient.osc.v2.dynamic_routing import constants 21 22 23def _get_attrs(client_manager, parsed_args): 24 attrs = {} 25 if parsed_args.name is not None: 26 attrs['name'] = str(parsed_args.name) 27 if 'local_as' in parsed_args: 28 attrs['local_as'] = parsed_args.local_as 29 if 'ip_version' in parsed_args: 30 attrs['ip_version'] = parsed_args.ip_version 31 if parsed_args.advertise_tenant_networks: 32 attrs['advertise_tenant_networks'] = True 33 if parsed_args.no_advertise_tenant_networks: 34 attrs['advertise_tenant_networks'] = False 35 if parsed_args.advertise_floating_ip_host_routes: 36 attrs['advertise_floating_ip_host_routes'] = True 37 if parsed_args.no_advertise_floating_ip_host_routes: 38 attrs['advertise_floating_ip_host_routes'] = False 39 40 if 'project' in parsed_args and parsed_args.project is not None: 41 identity_client = client_manager.identity 42 project_id = nc_osc_utils.find_project( 43 identity_client, 44 parsed_args.project, 45 parsed_args.project_domain, 46 ).id 47 attrs['tenant_id'] = project_id 48 return attrs 49 50 51def add_common_arguments(parser): 52 parser.add_argument( 53 '--advertise-floating-ip-host-routes', 54 action='store_true', 55 help=_("Enable the advertisement of floating IP host routes " 56 "by the BGP speaker. (default)")) 57 parser.add_argument( 58 '--no-advertise-floating-ip-host-routes', 59 action='store_true', 60 help=_("Disable the advertisement of floating IP host routes " 61 "by the BGP speaker.")) 62 parser.add_argument( 63 '--advertise-tenant-networks', 64 action='store_true', 65 help=_("Enable the advertisement of tenant network routes " 66 "by the BGP speaker. (default)")) 67 parser.add_argument( 68 '--no-advertise-tenant-networks', 69 action='store_true', 70 help=_("Disable the advertisement of tenant network routes " 71 "by the BGP speaker.")) 72 73 74class AddNetworkToSpeaker(command.Command): 75 _description = _("Add a network to a BGP speaker") 76 77 def get_parser(self, prog_name): 78 parser = super(AddNetworkToSpeaker, self).get_parser(prog_name) 79 parser.add_argument( 80 'bgp_speaker', 81 metavar='<bgp-speaker>', 82 help=_("BGP speaker (name or ID)")) 83 parser.add_argument( 84 'network', 85 metavar='<network>', 86 help=_("Network to add (name or ID)")) 87 return parser 88 89 def take_action(self, parsed_args): 90 client = self.app.client_manager.neutronclient 91 speaker_id = client.find_resource(constants.BGP_SPEAKER, 92 parsed_args.bgp_speaker)['id'] 93 net_id = client.find_resource('network', 94 parsed_args.network)['id'] 95 client.add_network_to_bgp_speaker(speaker_id, {'network_id': net_id}) 96 97 98class AddPeerToSpeaker(command.Command): 99 _description = _("Add a peer to a BGP speaker") 100 101 def get_parser(self, prog_name): 102 parser = super(AddPeerToSpeaker, self).get_parser(prog_name) 103 parser.add_argument( 104 'bgp_speaker', 105 metavar='<bgp-speaker>', 106 help=_("BGP speaker (name or ID)")) 107 parser.add_argument( 108 'bgp_peer', 109 metavar='<bgp-peer>', 110 help=_("BGP Peer to add (name or ID)")) 111 return parser 112 113 def take_action(self, parsed_args): 114 client = self.app.client_manager.neutronclient 115 speaker_id = client.find_resource(constants.BGP_SPEAKER, 116 parsed_args.bgp_speaker)['id'] 117 peer_id = client.find_resource(constants.BGP_PEER, 118 parsed_args.bgp_peer)['id'] 119 client.add_peer_to_bgp_speaker(speaker_id, {'bgp_peer_id': peer_id}) 120 121 122class CreateBgpSpeaker(command.ShowOne): 123 _description = _("Create a BGP speaker") 124 125 def get_parser(self, prog_name): 126 parser = super(CreateBgpSpeaker, self).get_parser(prog_name) 127 parser.add_argument( 128 'name', 129 metavar='<name>', 130 help=_("Name of the BGP speaker to create")) 131 parser.add_argument( 132 '--local-as', 133 metavar='<local-as>', 134 required=True, 135 help=_("Local AS number. (Integer in [%(min_val)s, %(max_val)s] " 136 "is allowed.)") % {'min_val': constants.MIN_AS_NUM, 137 'max_val': constants.MAX_AS_NUM}) 138 parser.add_argument( 139 '--ip-version', 140 type=int, choices=[4, 6], 141 default=4, 142 help=_("IP version for the BGP speaker (default is 4)")) 143 add_common_arguments(parser) 144 nc_osc_utils.add_project_owner_option_to_parser(parser) 145 return parser 146 147 def take_action(self, parsed_args): 148 client = self.app.client_manager.neutronclient 149 attrs = _get_attrs(self.app.client_manager, parsed_args) 150 body = {} 151 body[constants.BGP_SPEAKER] = attrs 152 obj = client.create_bgp_speaker(body)[constants.BGP_SPEAKER] 153 columns, display_columns = column_util.get_columns(obj) 154 data = utils.get_dict_properties(obj, columns) 155 return display_columns, data 156 157 158class DeleteBgpSpeaker(command.Command): 159 _description = _("Delete a BGP speaker") 160 161 def get_parser(self, prog_name): 162 parser = super(DeleteBgpSpeaker, self).get_parser(prog_name) 163 parser.add_argument( 164 'bgp_speaker', 165 metavar="<bgp-speaker>", 166 help=_("BGP speaker to delete (name or ID)") 167 ) 168 return parser 169 170 def take_action(self, parsed_args): 171 client = self.app.client_manager.neutronclient 172 id = client.find_resource(constants.BGP_SPEAKER, 173 parsed_args.bgp_speaker)['id'] 174 client.delete_bgp_speaker(id) 175 176 177class ListBgpSpeaker(command.Lister): 178 _description = _("List BGP speakers") 179 180 def get_parser(self, prog_name): 181 parser = super(ListBgpSpeaker, self).get_parser(prog_name) 182 parser.add_argument( 183 '--agent', 184 metavar='<agent-id>', 185 help=_("List BGP speakers hosted by an agent (ID only)")) 186 return parser 187 188 def take_action(self, parsed_args): 189 client = self.app.client_manager.neutronclient 190 if parsed_args.agent is not None: 191 data = client.list_bgp_speaker_on_dragent(parsed_args.agent) 192 else: 193 data = client.list_bgp_speakers() 194 195 headers = ('ID', 'Name', 'Local AS', 'IP Version') 196 columns = ('id', 'name', 'local_as', 'ip_version') 197 return (headers, (utils.get_dict_properties(s, columns) 198 for s in data[constants.BGP_SPEAKERS])) 199 200 201class ListRoutesAdvertisedBySpeaker(command.Lister): 202 _description = _("List routes advertised") 203 204 def get_parser(self, prog_name): 205 parser = super(ListRoutesAdvertisedBySpeaker, 206 self).get_parser(prog_name) 207 parser.add_argument( 208 'bgp_speaker', 209 metavar='<bgp-speaker>', 210 help=_("BGP speaker (name or ID)")) 211 return parser 212 213 def take_action(self, parsed_args): 214 client = self.app.client_manager.neutronclient 215 speaker_id = client.find_resource(constants.BGP_SPEAKER, 216 parsed_args.bgp_speaker)['id'] 217 data = client.list_route_advertised_from_bgp_speaker(speaker_id) 218 headers = ('Destination', 'Nexthop') 219 columns = ('destination', 'next_hop') 220 return (headers, (utils.get_dict_properties(s, columns) 221 for s in data['advertised_routes'])) 222 223 224class RemoveNetworkFromSpeaker(command.Command): 225 _description = _("Remove a network from a BGP speaker") 226 227 def get_parser(self, prog_name): 228 parser = super(RemoveNetworkFromSpeaker, self).get_parser(prog_name) 229 parser.add_argument( 230 'bgp_speaker', 231 metavar='<bgp-speaker>', 232 help=_("BGP speaker (name or ID)")) 233 parser.add_argument( 234 'network', 235 metavar='<network>', 236 help=_("Network to remove (name or ID)")) 237 return parser 238 239 def take_action(self, parsed_args): 240 client = self.app.client_manager.neutronclient 241 speaker_id = client.find_resource(constants.BGP_SPEAKER, 242 parsed_args.bgp_speaker)['id'] 243 net_id = client.find_resource('network', 244 parsed_args.network)['id'] 245 client.remove_network_from_bgp_speaker(speaker_id, 246 {'network_id': net_id}) 247 248 249class RemovePeerFromSpeaker(command.Command): 250 _description = _("Remove a peer from a BGP speaker") 251 252 def get_parser(self, prog_name): 253 parser = super(RemovePeerFromSpeaker, self).get_parser(prog_name) 254 parser.add_argument( 255 'bgp_speaker', 256 metavar='<bgp-speaker>', 257 help=_("BGP speaker (name or ID)")) 258 parser.add_argument( 259 'bgp_peer', 260 metavar='<bgp-peer>', 261 help=_("BGP Peer to remove (name or ID)")) 262 return parser 263 264 def take_action(self, parsed_args): 265 client = self.app.client_manager.neutronclient 266 speaker_id = client.find_resource(constants.BGP_SPEAKER, 267 parsed_args.bgp_speaker)['id'] 268 peer_id = client.find_resource(constants.BGP_PEER, 269 parsed_args.bgp_peer)['id'] 270 client.remove_peer_from_bgp_speaker(speaker_id, 271 {'bgp_peer_id': peer_id}) 272 273 274class SetBgpSpeaker(command.Command): 275 _description = _("Set BGP speaker properties") 276 277 resource = constants.BGP_SPEAKER 278 279 def get_parser(self, prog_name): 280 parser = super(SetBgpSpeaker, self).get_parser(prog_name) 281 parser.add_argument( 282 'bgp_speaker', 283 metavar="<bgp-speaker>", 284 help=_("BGP speaker to update (name or ID)") 285 ) 286 parser.add_argument( 287 '--name', 288 help=_("New name for the BGP speaker")) 289 add_common_arguments(parser) 290 return parser 291 292 def take_action(self, parsed_args): 293 client = self.app.client_manager.neutronclient 294 id = client.find_resource(constants.BGP_SPEAKER, 295 parsed_args.bgp_speaker)['id'] 296 attrs = _get_attrs(self.app.client_manager, parsed_args) 297 body = {} 298 body[constants.BGP_SPEAKER] = attrs 299 client.update_bgp_speaker(id, body) 300 301 302class ShowBgpSpeaker(command.ShowOne): 303 _description = _("Show a BGP speaker") 304 305 def get_parser(self, prog_name): 306 parser = super(ShowBgpSpeaker, self).get_parser(prog_name) 307 parser.add_argument( 308 'bgp_speaker', 309 metavar="<bgp-speaker>", 310 help=_("BGP speaker to display (name or ID)") 311 ) 312 return parser 313 314 def take_action(self, parsed_args): 315 client = self.app.client_manager.neutronclient 316 id = client.find_resource(constants.BGP_SPEAKER, 317 parsed_args.bgp_speaker)['id'] 318 obj = client.show_bgp_speaker(id)[constants.BGP_SPEAKER] 319 columns, display_columns = column_util.get_columns(obj) 320 data = utils.get_dict_properties(obj, columns) 321 return display_columns, data 322