26707bdbe7
We have git to track authorship, so let's not pad source files with it as well. A hacking check has been added for this. The value is N322. Change-Id: Iab0b64d417e0bb41a6b455e2ac377deee64ec3ee
184 lines
7.5 KiB
Python
184 lines
7.5 KiB
Python
# Copyright (c) 2014 Cisco Systems Inc.
|
|
# 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 apicapi import apic_mapper
|
|
|
|
from neutron.db import db_base_plugin_v2
|
|
from neutron.db import extraroute_db
|
|
from neutron.db import l3_dvr_db
|
|
from neutron.openstack.common import excutils
|
|
from neutron.plugins.common import constants
|
|
|
|
from neutron.plugins.ml2.drivers.cisco.apic import mechanism_apic
|
|
|
|
|
|
class ApicL3ServicePlugin(db_base_plugin_v2.NeutronDbPluginV2,
|
|
l3_dvr_db.L3_NAT_with_dvr_db_mixin,
|
|
extraroute_db.ExtraRoute_db_mixin):
|
|
supported_extension_aliases = ["router", "ext-gw-mode", "extraroute"]
|
|
|
|
def __init__(self):
|
|
super(ApicL3ServicePlugin, self).__init__()
|
|
self.manager = mechanism_apic.APICMechanismDriver.get_apic_manager()
|
|
self.name_mapper = self.manager.apic_mapper
|
|
self.synchronizer = None
|
|
self.manager.ensure_infra_created_on_apic()
|
|
self.manager.ensure_bgp_pod_policy_created_on_apic()
|
|
|
|
def _map_names(self, context,
|
|
tenant_id, router_id, net_id, subnet_id):
|
|
context._plugin = self
|
|
with apic_mapper.mapper_context(context) as ctx:
|
|
atenant_id = tenant_id and self.name_mapper.tenant(ctx, tenant_id)
|
|
arouter_id = router_id and self.name_mapper.router(ctx, router_id)
|
|
anet_id = net_id and self.name_mapper.network(ctx, net_id)
|
|
asubnet_id = subnet_id and self.name_mapper.subnet(ctx, subnet_id)
|
|
return atenant_id, arouter_id, anet_id, asubnet_id
|
|
|
|
@staticmethod
|
|
def get_plugin_type():
|
|
return constants.L3_ROUTER_NAT
|
|
|
|
@staticmethod
|
|
def get_plugin_description():
|
|
"""Returns string description of the plugin."""
|
|
return _("L3 Router Service Plugin for basic L3 using the APIC")
|
|
|
|
def sync_init(f):
|
|
def inner(inst, *args, **kwargs):
|
|
if not inst.synchronizer:
|
|
inst.synchronizer = (
|
|
mechanism_apic.APICMechanismDriver.
|
|
get_router_synchronizer(inst))
|
|
inst.synchronizer.sync_router()
|
|
return f(inst, *args, **kwargs)
|
|
return inner
|
|
|
|
def add_router_interface_postcommit(self, context, router_id,
|
|
interface_info):
|
|
# Update router's state first
|
|
router = self.get_router(context, router_id)
|
|
self.update_router_postcommit(context, router)
|
|
|
|
# Add router interface
|
|
if 'subnet_id' in interface_info:
|
|
subnet = self.get_subnet(context, interface_info['subnet_id'])
|
|
network_id = subnet['network_id']
|
|
tenant_id = subnet['tenant_id']
|
|
else:
|
|
port = self.get_port(context, interface_info['port_id'])
|
|
network_id = port['network_id']
|
|
tenant_id = port['tenant_id']
|
|
|
|
# Map openstack IDs to APIC IDs
|
|
atenant_id, arouter_id, anetwork_id, _ = self._map_names(
|
|
context, tenant_id, router_id, network_id, None)
|
|
|
|
# Program APIC
|
|
self.manager.add_router_interface(atenant_id, arouter_id,
|
|
anetwork_id)
|
|
|
|
def remove_router_interface_precommit(self, context, router_id,
|
|
interface_info):
|
|
if 'subnet_id' in interface_info:
|
|
subnet = self.get_subnet(context, interface_info['subnet_id'])
|
|
network_id = subnet['network_id']
|
|
tenant_id = subnet['tenant_id']
|
|
else:
|
|
port = self.get_port(context, interface_info['port_id'])
|
|
network_id = port['network_id']
|
|
tenant_id = port['tenant_id']
|
|
|
|
# Map openstack IDs to APIC IDs
|
|
atenant_id, arouter_id, anetwork_id, _ = self._map_names(
|
|
context, tenant_id, router_id, network_id, None)
|
|
|
|
# Program APIC
|
|
self.manager.remove_router_interface(atenant_id, arouter_id,
|
|
anetwork_id)
|
|
|
|
def delete_router_precommit(self, context, router_id):
|
|
context._plugin = self
|
|
with apic_mapper.mapper_context(context) as ctx:
|
|
arouter_id = router_id and self.name_mapper.router(ctx, router_id)
|
|
self.manager.delete_router(arouter_id)
|
|
|
|
def update_router_postcommit(self, context, router):
|
|
context._plugin = self
|
|
with apic_mapper.mapper_context(context) as ctx:
|
|
arouter_id = router['id'] and self.name_mapper.router(ctx,
|
|
router['id'])
|
|
with self.manager.apic.transaction() as trs:
|
|
self.manager.create_router(arouter_id, transaction=trs)
|
|
if router['admin_state_up']:
|
|
self.manager.enable_router(arouter_id, transaction=trs)
|
|
else:
|
|
self.manager.disable_router(arouter_id, transaction=trs)
|
|
|
|
# Router API
|
|
|
|
@sync_init
|
|
def create_router(self, *args, **kwargs):
|
|
return super(ApicL3ServicePlugin, self).create_router(*args, **kwargs)
|
|
|
|
@sync_init
|
|
def update_router(self, context, id, router):
|
|
result = super(ApicL3ServicePlugin, self).update_router(context,
|
|
id, router)
|
|
self.update_router_postcommit(context, result)
|
|
return result
|
|
|
|
@sync_init
|
|
def get_router(self, *args, **kwargs):
|
|
return super(ApicL3ServicePlugin, self).get_router(*args, **kwargs)
|
|
|
|
@sync_init
|
|
def get_routers(self, *args, **kwargs):
|
|
return super(ApicL3ServicePlugin, self).get_routers(*args, **kwargs)
|
|
|
|
@sync_init
|
|
def get_routers_count(self, *args, **kwargs):
|
|
return super(ApicL3ServicePlugin, self).get_routers_count(*args,
|
|
**kwargs)
|
|
|
|
def delete_router(self, context, router_id):
|
|
self.delete_router_precommit(context, router_id)
|
|
result = super(ApicL3ServicePlugin, self).delete_router(context,
|
|
router_id)
|
|
return result
|
|
|
|
# Router Interface API
|
|
|
|
@sync_init
|
|
def add_router_interface(self, context, router_id, interface_info):
|
|
# Create interface in parent
|
|
result = super(ApicL3ServicePlugin, self).add_router_interface(
|
|
context, router_id, interface_info)
|
|
try:
|
|
self.add_router_interface_postcommit(context, router_id,
|
|
interface_info)
|
|
except Exception:
|
|
with excutils.save_and_reraise_exception():
|
|
# Rollback db operation
|
|
super(ApicL3ServicePlugin, self).remove_router_interface(
|
|
context, router_id, interface_info)
|
|
return result
|
|
|
|
def remove_router_interface(self, context, router_id, interface_info):
|
|
self.remove_router_interface_precommit(context, router_id,
|
|
interface_info)
|
|
return super(ApicL3ServicePlugin, self).remove_router_interface(
|
|
context, router_id, interface_info)
|