Merge "Distributed locking support"

This commit is contained in:
Jenkins 2015-06-14 16:43:06 +00:00 committed by Gerrit Code Review
commit 85cec0c269
6 changed files with 250 additions and 181 deletions

View File

@ -18,3 +18,4 @@ oslo.log>=0.1.0 # Apache-2.0
oslo.serialization>=1.0.0 # Apache-2.0
oslo.utils>=1.1.0 # Apache-2.0
oslo.vmware>=0.9.0 # Apache-2.0
tooz>=0.13.1 # Apache-2.0

View File

@ -260,6 +260,8 @@ nsxv_opts = [
cfg.IntOpt('dhcp_lease_time',
default=86400,
help=_('DHCP default lease time.')),
cfg.StrOpt('locking_coordinator_url',
help=_('A URL to a locking mechanism coordinator')),
]
# Register the configuration options

View File

@ -0,0 +1,51 @@
# Copyright 2015 VMware, 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 oslo_concurrency import lockutils
from oslo_config import cfg
from oslo_log import log
from tooz import coordination
LOG = log.getLogger(__name__)
class LockManager:
_coordinator = None
_connect_string = cfg.CONF.nsxv.locking_coordinator_url
def __init__(self):
LOG.debug('LockManager initialized!')
@staticmethod
def get_lock(name, **kwargs):
if cfg.CONF.nsxv.locking_coordinator_url:
return LockManager._get_lock_distributed(name)
else:
return LockManager._get_lock_local(name, **kwargs)
@staticmethod
def _get_lock_local(name, **kwargs):
return lockutils.lock(name, **kwargs)
@staticmethod
def _get_lock_distributed(name):
if not LockManager._coordinator:
LOG.debug('Initialized coordinator with connect string %s',
LockManager._connect_string)
LockManager._coordinator = coordination.get_coordinator(
LockManager._connect_string, 'vmware-neutron-plugin')
LOG.debug('Retrieved lock for ', name)
return LockManager._coordinator.get_lock(name)

View File

@ -17,7 +17,6 @@ import six
import uuid
import netaddr
from oslo_concurrency import lockutils
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import excutils
@ -56,6 +55,7 @@ from neutron.plugins.vmware.extensions import (
from vmware_nsx.neutron.plugins import vmware
from vmware_nsx.neutron.plugins.vmware.common import config # noqa
from vmware_nsx.neutron.plugins.vmware.common import exceptions as nsx_exc
from vmware_nsx.neutron.plugins.vmware.common import locking
from vmware_nsx.neutron.plugins.vmware.common import utils as c_utils
from vmware_nsx.neutron.plugins.vmware.dbexts import (
routertype as rt_rtr)
@ -453,8 +453,8 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
return self._ensure_default_security_group(context, tenant_id)
def _add_member_to_security_group(self, sg_id, vnic_id):
with lockutils.lock(str(sg_id),
lock_file_prefix='neutron-security-ops'):
with locking.LockManager.get_lock(
str(sg_id), lock_file_prefix='neutron-security-ops'):
try:
h, c = self.nsx_v.vcns.add_member_to_security_group(
sg_id, vnic_id)
@ -480,8 +480,8 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
self._add_member_to_security_group(nsx_sg_id, vnic_id)
def _remove_member_from_security_group(self, sg_id, vnic_id):
with lockutils.lock(str(sg_id),
lock_file_prefix='neutron-security-ops'):
with locking.LockManager.get_lock(
str(sg_id), lock_file_prefix='neutron-security-ops'):
try:
h, c = self.nsx_v.vcns.remove_member_from_security_group(
sg_id, vnic_id)
@ -1026,9 +1026,8 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
err_msg = _("No support for DHCP for IPv6")
raise n_exc.InvalidInput(error_message=err_msg)
with lockutils.lock('nsx-edge-pool',
lock_file_prefix='edge-bind-',
external=True):
with locking.LockManager.get_lock(
'nsx-edge-pool', lock_file_prefix='edge-bind-', external=True):
s = super(NsxVPluginV2, self).create_subnet(context, subnet)
if s['enable_dhcp']:
try:
@ -1052,19 +1051,21 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
self.edge_manager.update_dhcp_edge_bindings(context, network_id)
return subnet
@lockutils.synchronized('vmware', 'neutron-dhcp-')
def _get_conflict_network_ids_by_overlapping(self, context, subnets):
conflict_network_ids = []
subnet_ids = [subnet['id'] for subnet in subnets]
conflict_set = netaddr.IPSet([subnet['cidr'] for subnet in subnets])
subnets_qry = context.session.query(models_v2.Subnet).all()
subnets_all = [subnet for subnet in subnets_qry
if subnet['id'] not in subnet_ids]
for subnet in subnets_all:
cidr_set = netaddr.IPSet([subnet['cidr']])
if cidr_set & conflict_set:
conflict_network_ids.append(subnet['network_id'])
return conflict_network_ids
with locking.LockManager.get_lock(
'vmware', lock_file_prefix='neutron-dhcp-'):
conflict_network_ids = []
subnet_ids = [subnet['id'] for subnet in subnets]
conflict_set = netaddr.IPSet(
[subnet['cidr'] for subnet in subnets])
subnets_qry = context.session.query(models_v2.Subnet).all()
subnets_all = [subnet for subnet in subnets_qry
if subnet['id'] not in subnet_ids]
for subnet in subnets_all:
cidr_set = netaddr.IPSet([subnet['cidr']])
if cidr_set & conflict_set:
conflict_network_ids.append(subnet['network_id'])
return conflict_network_ids
def _get_conflicting_networks_for_subnet(self, context, subnet):
network_id = subnet['network_id']

View File

@ -13,7 +13,6 @@
# under the License.
import netaddr
from oslo_concurrency import lockutils
from oslo_config import cfg
from neutron.api.v2 import attributes as attr
@ -22,6 +21,7 @@ from neutron.db import models_v2
from neutron.plugins.vmware.dbexts import nsxv_models
from oslo_log import log as logging
from vmware_nsx.neutron.plugins.vmware.common import exceptions as nsx_exc
from vmware_nsx.neutron.plugins.vmware.common import locking
from vmware_nsx.neutron.plugins.vmware.dbexts import nsxv_db
from vmware_nsx.neutron.plugins.vmware.plugins import nsx_v
from vmware_nsx.neutron.plugins.vmware.plugins.nsx_v_drivers import (
@ -51,9 +51,9 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
return super(nsx_v.NsxVPluginV2, self.plugin).update_router(
context, router_id, router)
else:
with lockutils.lock(str(edge_id),
lock_file_prefix=NSXV_ROUTER_RECONFIG,
external=True):
with locking.LockManager.get_lock(
str(edge_id), lock_file_prefix=NSXV_ROUTER_RECONFIG,
external=True):
gw_info = self.plugin._extract_external_gw(
context, router, is_extract=True)
super(nsx_v.NsxVPluginV2, self.plugin).update_router(
@ -206,9 +206,9 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
context, router_id, router_db.admin_state_up)
new_edge_id = edge_utils.get_router_edge_id(context,
router_id)
with lockutils.lock(str(new_edge_id),
lock_file_prefix=NSXV_ROUTER_RECONFIG,
external=True):
with locking.LockManager.get_lock(
str(new_edge_id),
lock_file_prefix=NSXV_ROUTER_RECONFIG, external=True):
self._add_router_services_on_available_edge(context,
router_id)
router_ids = self.edge_manager.get_routers_on_same_edge(
@ -446,40 +446,42 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
optional_router_ids.append(router['id'])
return optional_router_ids, conflict_router_ids
@lockutils.synchronized("router", "bind-", external=True)
def _bind_router_on_available_edge(self, context, router_id, admin_state):
conflict_network_ids, conflict_router_ids, intf_num = (
self._get_conflict_network_and_router_ids_by_intf(context,
router_id))
conflict_network_ids_by_ext_net = (
self._get_conflict_network_ids_by_ext_net(context, router_id))
conflict_network_ids.extend(conflict_network_ids_by_ext_net)
optional_router_ids, new_conflict_router_ids = (
self._get_available_and_conflicting_ids(context, router_id))
conflict_router_ids.extend(new_conflict_router_ids)
conflict_router_ids = list(set(conflict_router_ids))
with locking.LockManager.get_lock("router", lock_file_prefix="bind-",
external=True):
conflict_network_ids, conflict_router_ids, intf_num = (
self._get_conflict_network_and_router_ids_by_intf(context,
router_id))
conflict_network_ids_by_ext_net = (
self._get_conflict_network_ids_by_ext_net(context, router_id))
conflict_network_ids.extend(conflict_network_ids_by_ext_net)
optional_router_ids, new_conflict_router_ids = (
self._get_available_and_conflicting_ids(context, router_id))
conflict_router_ids.extend(new_conflict_router_ids)
conflict_router_ids = list(set(conflict_router_ids))
new = self.edge_manager.bind_router_on_available_edge(
context, router_id, optional_router_ids,
conflict_router_ids, conflict_network_ids, intf_num)
# configure metadata service on the router.
metadata_proxy_handler = self.plugin.metadata_proxy_handler
if metadata_proxy_handler and new:
metadata_proxy_handler.configure_router_edge(router_id)
edge_id = edge_utils.get_router_edge_id(context, router_id)
with lockutils.lock(str(edge_id),
lock_file_prefix=NSXV_ROUTER_RECONFIG,
external=True):
# add all internal interfaces of the router on edge
intf_net_ids = (
self.plugin._get_internal_network_ids_by_router(context,
router_id))
for network_id in intf_net_ids:
address_groups = self.plugin._get_address_groups(
context, router_id, network_id)
edge_utils.update_internal_interface(
self.nsx_v, context, router_id, network_id,
address_groups, admin_state)
new = self.edge_manager.bind_router_on_available_edge(
context, router_id, optional_router_ids,
conflict_router_ids, conflict_network_ids, intf_num)
# configure metadata service on the router.
metadata_proxy_handler = self.plugin.metadata_proxy_handler
if metadata_proxy_handler and new:
metadata_proxy_handler.configure_router_edge(router_id)
edge_id = edge_utils.get_router_edge_id(context, router_id)
with locking.LockManager.get_lock(
str(edge_id),
lock_file_prefix=NSXV_ROUTER_RECONFIG,
external=True):
# add all internal interfaces of the router on edge
intf_net_ids = (
self.plugin._get_internal_network_ids_by_router(context,
router_id))
for network_id in intf_net_ids:
address_groups = self.plugin._get_address_groups(
context, router_id, network_id)
edge_utils.update_internal_interface(
self.nsx_v, context, router_id, network_id,
address_groups, admin_state)
def _unbind_router_on_edge(self, context, router_id):
self.edge_manager.unbind_router_on_edge(context, router_id)
@ -527,9 +529,10 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
# UPDATE gw info only if the router has been attached to an edge
else:
is_migrated = False
with lockutils.lock(str(edge_id),
lock_file_prefix=NSXV_ROUTER_RECONFIG,
external=True):
with locking.LockManager.get_lock(
str(edge_id),
lock_file_prefix=NSXV_ROUTER_RECONFIG,
external=True):
router_ids = self.edge_manager.get_routers_on_same_edge(
context, router_id)
org_ext_net_id = (router.gw_port_id and
@ -605,9 +608,10 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
self._bind_router_on_available_edge(
context, router_id, router.admin_state_up)
edge_id = edge_utils.get_router_edge_id(context, router_id)
with lockutils.lock(str(edge_id),
lock_file_prefix=NSXV_ROUTER_RECONFIG,
external=True):
with locking.LockManager.get_lock(
str(edge_id),
lock_file_prefix=NSXV_ROUTER_RECONFIG,
external=True):
self._add_router_services_on_available_edge(context,
router_id)
@ -617,9 +621,10 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
router_db = self.plugin._get_router(context, router_id)
if edge_id:
is_migrated = False
with lockutils.lock(str(edge_id),
lock_file_prefix=NSXV_ROUTER_RECONFIG,
external=True):
with locking.LockManager.get_lock(
str(edge_id),
lock_file_prefix=NSXV_ROUTER_RECONFIG,
external=True):
router_ids = self.edge_manager.get_routers_on_same_edge(
context, router_id)
info = super(nsx_v.NsxVPluginV2,
@ -677,9 +682,10 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
self._bind_router_on_available_edge(
context, router_id, router_db.admin_state_up)
edge_id = edge_utils.get_router_edge_id(context, router_id)
with lockutils.lock(str(edge_id),
lock_file_prefix=NSXV_ROUTER_RECONFIG,
external=True):
with locking.LockManager.get_lock(
str(edge_id),
lock_file_prefix=NSXV_ROUTER_RECONFIG,
external=True):
self._add_router_services_on_available_edge(context,
router_id)
else:
@ -689,18 +695,20 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
self._bind_router_on_available_edge(
context, router_id, router_db.admin_state_up)
edge_id = edge_utils.get_router_edge_id(context, router_id)
with lockutils.lock(str(edge_id),
lock_file_prefix=NSXV_ROUTER_RECONFIG,
external=True):
with locking.LockManager.get_lock(
str(edge_id),
lock_file_prefix=NSXV_ROUTER_RECONFIG,
external=True):
self._add_router_services_on_available_edge(context,
router_id)
return info
def remove_router_interface(self, context, router_id, interface_info):
edge_id = edge_utils.get_router_edge_id(context, router_id)
with lockutils.lock(str(edge_id),
lock_file_prefix=NSXV_ROUTER_RECONFIG,
external=True):
with locking.LockManager.get_lock(
str(edge_id),
lock_file_prefix=NSXV_ROUTER_RECONFIG,
external=True):
info = super(
nsx_v.NsxVPluginV2, self.plugin).remove_router_interface(
context, router_id, interface_info)
@ -730,9 +738,10 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
def _update_edge_router(self, context, router_id):
edge_id = edge_utils.get_router_edge_id(context, router_id)
with lockutils.lock(str(edge_id),
lock_file_prefix=NSXV_ROUTER_RECONFIG,
external=True):
with locking.LockManager.get_lock(
str(edge_id),
lock_file_prefix=NSXV_ROUTER_RECONFIG,
external=True):
router_ids = self.edge_manager.get_routers_on_same_edge(
context, router_id)
if router_ids:

View File

@ -18,7 +18,6 @@ import random
from sqlalchemy import exc as db_base_exc
import time
from oslo_concurrency import lockutils
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import excutils
@ -31,6 +30,7 @@ from neutron import context as q_context
from neutron.extensions import l3
from neutron.plugins.common import constants as plugin_const
from vmware_nsx.neutron.plugins.vmware.common import locking
from vmware_nsx.neutron.plugins.vmware.common import nsxv_constants
from vmware_nsx.neutron.plugins.vmware.dbexts import db as nsx_db
from vmware_nsx.neutron.plugins.vmware.dbexts import nsxv_db
@ -446,9 +446,8 @@ class EdgeManager(object):
task.wait(task_const.TaskState.RESULT)
return
with lockutils.lock('nsx-edge-request',
lock_file_prefix='get-',
external=True):
with locking.LockManager.get_lock(
'nsx-edge-request', lock_file_prefix='get-', external=True):
self._clean_all_error_edge_bindings(context)
available_router_binding = self._get_available_router_binding(
context, appliance_size=appliance_size, edge_type=edge_type)
@ -534,9 +533,8 @@ class EdgeManager(object):
router_id, binding['edge_id'], jobdata=jobdata, dist=dist)
return
with lockutils.lock('nsx-edge-request',
lock_file_prefix='get-',
external=True):
with locking.LockManager.get_lock(
'nsx-edge-request', lock_file_prefix='get-', external=True):
self._clean_all_error_edge_bindings(context)
backup_router_bindings = self._get_backup_edge_bindings(
context, appliance_size=binding['appliance_size'],
@ -726,9 +724,8 @@ class EdgeManager(object):
def allocate_new_dhcp_edge(self, context, network_id, resource_id):
self._allocate_dhcp_edge_appliance(context, resource_id)
with lockutils.lock('nsx-edge-pool',
lock_file_prefix='edge-bind-',
external=True):
with locking.LockManager.get_lock(
'nsx-edge-pool', lock_file_prefix='edge-bind-', external=True):
new_edge = nsxv_db.get_nsxv_router_binding(context.session,
resource_id)
nsxv_db.allocate_edge_vnic_with_tunnel_index(
@ -750,17 +747,17 @@ class EdgeManager(object):
allocate_new_edge = False
# case 1: update a subnet to an existing dhcp edge
if dhcp_edge_binding:
with lockutils.lock('nsx-edge-pool',
lock_file_prefix='edge-bind-',
external=True):
with locking.LockManager.get_lock(
'nsx-edge-pool', lock_file_prefix='edge-bind-',
external=True):
edge_id = dhcp_edge_binding['edge_id']
(conflict_edge_ids,
available_edge_ids) = self._get_used_edges(context, subnet)
LOG.debug('The available edges %s, the conflict edges %s',
available_edge_ids, conflict_edge_ids)
with lockutils.lock(str(edge_id),
lock_file_prefix='nsxv-dhcp-config-',
external=True):
with locking.LockManager.get_lock(
str(edge_id), lock_file_prefix='nsxv-dhcp-config-',
external=True):
# Delete the existing vnic interface if there is
# and overlapping subnet
if edge_id in conflict_edge_ids:
@ -781,9 +778,9 @@ class EdgeManager(object):
allocate_new_edge = True
# case 2: attach the subnet to a new edge and update vnic
else:
with lockutils.lock('nsx-edge-pool',
lock_file_prefix='edge-bind-',
external=True):
with locking.LockManager.get_lock(
'nsx-edge-pool', lock_file_prefix='edge-bind-',
external=True):
(conflict_edge_ids,
available_edge_ids) = self._get_used_edges(context, subnet)
LOG.debug('The available edges %s, the conflict edges %s',
@ -821,9 +818,9 @@ class EdgeManager(object):
LOG.debug('Update the dhcp service for %s on vnic %d tunnel %d',
edge_id, vnic_index, tunnel_index)
try:
with lockutils.lock(str(edge_id),
lock_file_prefix='nsxv-dhcp-config-',
external=True):
with locking.LockManager.get_lock(
str(edge_id), lock_file_prefix='nsxv-dhcp-config-',
external=True):
self._update_dhcp_internal_interface(
context, edge_id, vnic_index, tunnel_index, network_id,
address_groups)
@ -863,9 +860,9 @@ class EdgeManager(object):
edge_id,
network_id)
try:
with lockutils.lock(str(edge_id),
lock_file_prefix='nsxv-dhcp-config-',
external=True):
with locking.LockManager.get_lock(
str(edge_id), lock_file_prefix='nsxv-dhcp-config-',
external=True):
self._delete_dhcp_internal_interface(context, edge_id,
vnic_index,
tunnel_index,
@ -889,13 +886,13 @@ class EdgeManager(object):
resource_id)
if dhcp_edge_binding:
with lockutils.lock('nsx-edge-pool',
lock_file_prefix='edge-bind-',
external=True):
with locking.LockManager.get_lock(
'nsx-edge-pool', lock_file_prefix='edge-bind-',
external=True):
edge_id = dhcp_edge_binding['edge_id']
with lockutils.lock(str(edge_id),
lock_file_prefix='nsxv-dhcp-config-',
external=True):
with locking.LockManager.get_lock(
str(edge_id), lock_file_prefix='nsxv-dhcp-config-',
external=True):
self.remove_network_from_dhcp_edge(context, network_id,
edge_id)
@ -1034,7 +1031,6 @@ class EdgeManager(object):
else:
return []
@lockutils.synchronized("edge-router", "bind-", external=True)
def bind_router_on_available_edge(
self, context, target_router_id,
optional_router_ids, conflict_router_ids,
@ -1042,88 +1038,97 @@ class EdgeManager(object):
"""Bind logical router on an available edge.
Return True if the logical router is bound to a new edge.
"""
optional_edge_ids = []
conflict_edge_ids = []
for router_id in optional_router_ids:
binding = nsxv_db.get_nsxv_router_binding(
context.session, router_id)
if (binding and binding.status == plugin_const.ACTIVE and
binding.edge_id not in optional_edge_ids):
optional_edge_ids.append(binding.edge_id)
with locking.LockManager.get_lock(
"edge-router", lock_file_prefix="bind-", external=True):
optional_edge_ids = []
conflict_edge_ids = []
for router_id in optional_router_ids:
binding = nsxv_db.get_nsxv_router_binding(
context.session, router_id)
if (binding and binding.status == plugin_const.ACTIVE and
binding.edge_id not in optional_edge_ids):
optional_edge_ids.append(binding.edge_id)
for router_id in conflict_router_ids:
binding = nsxv_db.get_nsxv_router_binding(
context.session, router_id)
if binding and binding.edge_id not in conflict_edge_ids:
conflict_edge_ids.append(binding.edge_id)
optional_edge_ids = list(
set(optional_edge_ids) - set(conflict_edge_ids))
for router_id in conflict_router_ids:
binding = nsxv_db.get_nsxv_router_binding(
context.session, router_id)
if binding and binding.edge_id not in conflict_edge_ids:
conflict_edge_ids.append(binding.edge_id)
optional_edge_ids = list(
set(optional_edge_ids) - set(conflict_edge_ids))
max_net_number = 0
available_edge_id = None
for edge_id in optional_edge_ids:
edge_vnic_bindings = nsxv_db.get_edge_vnic_bindings_by_edge(
context.session, edge_id)
# one vnic is used to provide external access.
net_number = vcns_const.MAX_VNIC_NUM - len(edge_vnic_bindings) - 1
if net_number > max_net_number and net_number >= network_number:
net_ids = [vnic_binding.network_id
for vnic_binding in edge_vnic_bindings]
if not (set(conflict_network_ids) & set(net_ids)):
max_net_number = net_number
available_edge_id = edge_id
else:
# TODO(yangyu): Remove conflict_network_ids
LOG.exception(_LE("Failed to query conflict_router_ids"))
if available_edge_id:
edge_binding = nsxv_db.get_nsxv_router_bindings_by_edge(
context.session, available_edge_id)[0]
nsxv_db.add_nsxv_router_binding(
context.session, target_router_id,
edge_binding.edge_id, None,
edge_binding.status,
edge_binding.appliance_size,
edge_binding.edge_type)
else:
router_name = ('shared' + '-' + _uuid())[:vcns_const.EDGE_NAME_LEN]
self._allocate_edge_appliance(
context, target_router_id, router_name,
appliance_size=vcns_const.SERVICE_SIZE_MAPPING['router'])
return True
max_net_number = 0
available_edge_id = None
for edge_id in optional_edge_ids:
edge_vnic_bindings = nsxv_db.get_edge_vnic_bindings_by_edge(
context.session, edge_id)
# one vnic is used to provide external access.
net_number = (
vcns_const.MAX_VNIC_NUM - len(edge_vnic_bindings) - 1)
if (net_number > max_net_number
and net_number >= network_number):
net_ids = [vnic_binding.network_id
for vnic_binding in edge_vnic_bindings]
if not (set(conflict_network_ids) & set(net_ids)):
max_net_number = net_number
available_edge_id = edge_id
else:
# TODO(yangyu): Remove conflict_network_ids
LOG.exception(
_LE("Failed to query conflict_router_ids"))
if available_edge_id:
edge_binding = nsxv_db.get_nsxv_router_bindings_by_edge(
context.session, available_edge_id)[0]
nsxv_db.add_nsxv_router_binding(
context.session, target_router_id,
edge_binding.edge_id, None,
edge_binding.status,
edge_binding.appliance_size,
edge_binding.edge_type)
else:
router_name = ('shared' + '-' + _uuid())[
:vcns_const.EDGE_NAME_LEN]
self._allocate_edge_appliance(
context, target_router_id, router_name,
appliance_size=vcns_const.SERVICE_SIZE_MAPPING['router'])
return True
@lockutils.synchronized("edge-router", "bind-", external=True)
def unbind_router_on_edge(self, context, router_id):
"""Unbind a logical router from edge.
Return True if no logical router bound to the edge.
"""
# free edge if no other routers bound to the edge
router_ids = self.get_routers_on_same_edge(context, router_id)
if router_ids == [router_id]:
self._free_edge_appliance(context, router_id)
return True
else:
nsxv_db.delete_nsxv_router_binding(context.session, router_id)
with locking.LockManager.get_lock(
"edge-router", lock_file_prefix="bind-", external=True):
# free edge if no other routers bound to the edge
router_ids = self.get_routers_on_same_edge(context, router_id)
if router_ids == [router_id]:
self._free_edge_appliance(context, router_id)
return True
else:
nsxv_db.delete_nsxv_router_binding(context.session, router_id)
@lockutils.synchronized("edge-router", "bind-", external=True)
def is_router_conflict_on_edge(self, context, router_id,
conflict_router_ids,
conflict_network_ids,
intf_num=0):
router_ids = self.get_routers_on_same_edge(context, router_id)
if set(router_ids) & set(conflict_router_ids):
return True
router_binding = nsxv_db.get_nsxv_router_binding(context.session,
router_id)
edge_vnic_bindings = nsxv_db.get_edge_vnic_bindings_by_edge(
context.session, router_binding.edge_id)
if vcns_const.MAX_VNIC_NUM - len(edge_vnic_bindings) - 1 < intf_num:
LOG.debug("There isn't available edge vnic for the router: %s",
router_id)
return True
for binding in edge_vnic_bindings:
if binding.network_id in conflict_network_ids:
with locking.LockManager.get_lock(
"edge-router", lock_file_prefix="bind-", external=True):
router_ids = self.get_routers_on_same_edge(context, router_id)
if set(router_ids) & set(conflict_router_ids):
return True
return False
router_binding = nsxv_db.get_nsxv_router_binding(context.session,
router_id)
edge_vnic_bindings = nsxv_db.get_edge_vnic_bindings_by_edge(
context.session, router_binding.edge_id)
if (vcns_const.MAX_VNIC_NUM - len(edge_vnic_bindings
) - 1 < intf_num):
LOG.debug("There isn't available edge vnic for the router: %s",
router_id)
return True
for binding in edge_vnic_bindings:
if binding.network_id in conflict_network_ids:
return True
return False
def create_lrouter(nsxv_manager, context, lrouter, lswitch=None, dist=False):