Stop using CommonDbMixin apis

Commit I5b804e09e630d88d551271d9731cc1f65c065259 changed/removed some of the
methods in CommonDbMixin.
As a result the way the plugins register the different extend-dict methods has changed,
and now uses a decorator.
Also those extend-dict callbacks are static methods which do not receive 'self', and
this caused some additional changes.

Change-Id: If99da0ea1e37792bd531ef92b0bbb880d2b05b8a
Depends-on: I5b804e09e630d88d551271d9731cc1f65c065259
changes/04/459204/9
Adit Sarfaty 6 years ago
parent 11d3da3ef5
commit 8548f110ac
  1. 7
      vmware_nsx/common/sync.py
  2. 44
      vmware_nsx/db/extended_security_group.py
  3. 10
      vmware_nsx/db/extended_security_group_rule.py
  4. 15
      vmware_nsx/db/maclearning.py
  5. 30
      vmware_nsx/db/networkgw_db.py
  6. 16
      vmware_nsx/db/nsxrouter.py
  7. 60
      vmware_nsx/db/qos_db.py
  8. 10
      vmware_nsx/db/vnic_index_db.py
  9. 5
      vmware_nsx/plugin.py
  10. 27
      vmware_nsx/plugins/dvs/plugin.py
  11. 14
      vmware_nsx/plugins/nsx_mh/plugin.py
  12. 87
      vmware_nsx/plugins/nsx_v/plugin.py
  13. 72
      vmware_nsx/plugins/nsx_v3/plugin.py
  14. 4
      vmware_nsx/shell/admin/plugins/nsxv/resources/securitygroups.py
  15. 10
      vmware_nsx/tests/unit/extensions/test_provider_security_groups.py
  16. 2
      vmware_nsx/tests/unit/nsx_v/test_plugin.py
  17. 40
      vmware_nsx/tests/unit/shell/test_admin_utils.py

@ -25,6 +25,7 @@ from oslo_service import loopingcall
from oslo_utils import timeutils
import six
from neutron.db import _model_query as model_query
from neutron.db import api as db_api
from neutron.db.models import external_net as external_net_db
from neutron.db.models import l3 as l3_db
@ -336,7 +337,7 @@ class NsxSynchronizer(object):
if not scan_missing:
filters['id'] = neutron_net_ids
networks = self._plugin._get_collection(
networks = model_query.get_collection(
ctx, models_v2.Network, self._plugin._make_network_dict,
filters=filters)
@ -416,7 +417,7 @@ class NsxSynchronizer(object):
# Fetch neutron routers from database
filters = ({} if scan_missing else
{'id': neutron_router_mappings.keys()})
routers = self._plugin._get_collection(
routers = model_query.get_collection(
ctx, l3_db.Router, self._plugin._make_router_dict,
filters=filters)
for router in routers:
@ -518,7 +519,7 @@ class NsxSynchronizer(object):
external_net_db.ExternalNetwork,
(models_v2.Network.id ==
external_net_db.ExternalNetwork.network_id))]
ports = self._plugin._get_collection(
ports = model_query.get_collection(
ctx, models_v2.Port, self._plugin._make_port_dict,
filters=filters)
for port in ports:

@ -22,8 +22,8 @@ from sqlalchemy import sql
from neutron.api.v2 import attributes
from neutron.common import utils as n_utils
from neutron.db import _resource_extend as resource_extend
from neutron.db import api as db_api
from neutron.db import db_base_plugin_v2
from neutron.db.models import securitygroup as securitygroups_db
from neutron.extensions import securitygroup as ext_sg
from neutron_lib.api import validators
@ -59,6 +59,7 @@ class NsxExtendedSecurityGroupProperties(model_base.BASEV2):
uselist=False, cascade='delete'))
@resource_extend.has_resource_extenders
class ExtendedSecurityGroupPropertiesMixin(object):
# NOTE(arosen): here we add a relationship so that from the ports model
@ -345,39 +346,34 @@ class ExtendedSecurityGroupPropertiesMixin(object):
sg_id):
raise sg_policy.PolicySecurityGroupDeleteNotAdmin(id=sg_id)
def _extend_security_group_with_properties(self, sg_res, sg_db):
@staticmethod
@resource_extend.extends([ext_sg.SECURITYGROUPS])
def _extend_security_group_with_properties(sg_res, sg_db):
if sg_db.ext_properties:
sg_res[sg_logging.LOGGING] = sg_db.ext_properties.logging
sg_res[provider_sg.PROVIDER] = sg_db.ext_properties.provider
sg_res[sg_policy.POLICY] = sg_db.ext_properties.policy
def _extend_port_dict_provider_security_group(self, port_res, port_db):
# NOTE(arosen): this method overrides the one in the base
# security group db class. The reason this is needed is because
# we are storing provider security groups in the same security
# groups db model. We need to do this here to remove the provider
# security groups and put those on the port resource as their
# own attribute.
# Security group bindings will be retrieved from the SQLAlchemy
# model. As they're loaded eagerly with ports because of the
# joined load they will not cause an extra query.
@staticmethod
@resource_extend.extends([attributes.PORTS])
def _extend_port_dict_provider_security_group(port_res, port_db):
# Add the provider sg list to the port.
# later we will remove those from the regular sg list
provider_groups = []
not_provider_groups = []
for sec_group_mapping in port_db.security_groups:
if sec_group_mapping.extended_grp.provider is True:
provider_groups.append(sec_group_mapping['security_group_id'])
else:
not_provider_groups.append(
sec_group_mapping['security_group_id'])
port_res[ext_sg.SECURITYGROUPS] = not_provider_groups
port_res[provider_sg.PROVIDER_SECURITYGROUPS] = provider_groups
return port_res
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
attributes.PORTS, ['_extend_port_dict_provider_security_group'])
@staticmethod
def _remove_provider_security_groups_from_list(port_res):
# Remove provider security groups from the list of regular security
# groups of the result port
if (ext_sg.SECURITYGROUPS not in port_res or
provider_sg.PROVIDER_SECURITYGROUPS not in port_res):
return
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
ext_sg.SECURITYGROUPS, ['_extend_security_group_with_properties'])
port_res[ext_sg.SECURITYGROUPS] = list(
set(port_res[ext_sg.SECURITYGROUPS]) -
set(port_res[provider_sg.PROVIDER_SECURITYGROUPS]))

@ -17,8 +17,8 @@ from neutron_lib.db import model_base
import sqlalchemy as sa
from sqlalchemy import orm
from neutron.db import _resource_extend as resource_extend
from neutron.db import api as db_api
from neutron.db import db_base_plugin_v2
from neutron.db.models import securitygroup
from neutron.extensions import securitygroup as ext_sg
from neutron_lib.api import validators
@ -52,6 +52,7 @@ class NsxExtendedSecurityGroupRuleProperties(model_base.BASEV2):
uselist=False, cascade='delete'))
@resource_extend.has_resource_extenders
class ExtendedSecurityGroupRuleMixin(object):
def _check_local_ip_prefix(self, context, rule):
@ -81,10 +82,9 @@ class ExtendedSecurityGroupRuleMixin(object):
rule_res[ext_local_ip.LOCAL_IP_PREFIX] = (
rule_req[ext_local_ip.LOCAL_IP_PREFIX])
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
ext_sg.SECURITYGROUPRULES, ['_extend_security_group_rule_with_params'])
def _extend_security_group_rule_with_params(self, sg_rule_res, sg_rule_db):
@staticmethod
@resource_extend.extends([ext_sg.SECURITYGROUPRULES])
def _extend_security_group_rule_with_params(sg_rule_res, sg_rule_db):
if sg_rule_db.ext_properties:
sg_rule_res[ext_local_ip.LOCAL_IP_PREFIX] = (
sg_rule_db.ext_properties.local_ip_prefix)

@ -16,9 +16,10 @@
from sqlalchemy.orm import exc
from neutron.api.v2 import attributes
from neutron.db import _model_query as model_query
from neutron.db import _resource_extend as resource_extend
from neutron.db import _utils as db_utils
from neutron.db import api as db_api
from neutron.db import db_base_plugin_v2
from oslo_log import log as logging
@ -28,6 +29,7 @@ from vmware_nsx.extensions import maclearning as mac
LOG = logging.getLogger(__name__)
@resource_extend.has_resource_extenders
class MacLearningDbMixin(object):
"""Mixin class for mac learning."""
@ -36,18 +38,17 @@ class MacLearningDbMixin(object):
mac.MAC_LEARNING: port[mac.MAC_LEARNING]}
return db_utils.resource_fields(res, fields)
def _extend_port_mac_learning_state(self, port_res, port_db):
@staticmethod
@resource_extend.extends([attributes.PORTS])
def _extend_port_mac_learning_state(port_res, port_db):
state = port_db.mac_learning_state
if state and state.mac_learning_enabled:
port_res[mac.MAC_LEARNING] = state.mac_learning_enabled
# Register dict extend functions for ports
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
attributes.PORTS, ['_extend_port_mac_learning_state'])
def _update_mac_learning_state(self, context, port_id, enabled):
try:
query = self._model_query(context, nsx_models.MacLearningState)
query = model_query.query_with_hooks(
context, nsx_models.MacLearningState)
state = query.filter(
nsx_models.MacLearningState.port_id == port_id).one()
state.update({mac.MAC_LEARNING: enabled})

@ -14,6 +14,7 @@
from sqlalchemy.orm import exc as sa_orm_exc
from neutron.db import _model_query as model_query
from neutron.db import _utils as db_utils
from neutron.db import api as db_api
from neutron.plugins.common import utils
@ -97,7 +98,8 @@ class NetworkGatewayMixin(networkgw.NetworkGatewayPluginBase):
def _get_network_gateway(self, context, gw_id):
try:
gw = self._get_by_id(context, nsx_models.NetworkGateway, gw_id)
gw = model_query.get_by_id(context, nsx_models.NetworkGateway,
gw_id)
except sa_orm_exc.NoResultFound:
raise GatewayNotFound(gateway_id=gw_id)
return gw
@ -172,9 +174,9 @@ class NetworkGatewayMixin(networkgw.NetworkGatewayPluginBase):
for k, v in six.iteritems(mapping_info):
if v and k != NETWORK_ID:
filters[k] = [v]
query = self._get_collection_query(context,
nsx_models.NetworkConnection,
filters)
query = model_query.get_collection_query(context,
nsx_models.NetworkConnection,
filters)
return query.one() if only_one else query.all()
def _unset_default_network_gateways(self, context):
@ -265,12 +267,12 @@ class NetworkGatewayMixin(networkgw.NetworkGatewayPluginBase):
page_reverse=False):
marker_obj = self._get_marker_obj(
context, 'network_gateway', limit, marker)
return self._get_collection(context, nsx_models.NetworkGateway,
self._make_network_gateway_dict,
filters=filters, fields=fields,
sorts=sorts, limit=limit,
marker_obj=marker_obj,
page_reverse=page_reverse)
return model_query.get_collection(context, nsx_models.NetworkGateway,
self._make_network_gateway_dict,
filters=filters, fields=fields,
sorts=sorts, limit=limit,
marker_obj=marker_obj,
page_reverse=page_reverse)
def connect_network(self, context, network_gateway_id,
network_mapping_info):
@ -396,14 +398,14 @@ class NetworkGatewayMixin(networkgw.NetworkGatewayPluginBase):
def _get_gateway_device(self, context, device_id):
try:
return self._get_by_id(context,
nsx_models.NetworkGatewayDevice,
device_id)
return model_query.get_by_id(context,
nsx_models.NetworkGatewayDevice,
device_id)
except sa_orm_exc.NoResultFound:
raise GatewayDeviceNotFound(device_id=device_id)
def _is_device_in_use(self, context, device_id):
query = self._get_collection_query(
query = model_query.get_collection_query(
context, nsx_models.NetworkGatewayDeviceReference,
{'id': [device_id]})
return query.first()

@ -13,25 +13,25 @@
# under the License.
#
from neutron.db import db_base_plugin_v2
from neutron.extensions import l3
from oslo_log import log as logging
from neutron.db import _resource_extend as resource_extend
from vmware_nsx.db import nsxv_models
LOG = logging.getLogger(__name__)
@resource_extend.has_resource_extenders
class NsxRouterMixin(object):
"""Mixin class to enable nsx router support."""
nsx_attributes = []
def _extend_nsx_router_dict(self, router_res, router_db):
@staticmethod
def _extend_nsx_router_dict(router_res, router_db, nsx_attributes):
nsx_attrs = router_db['nsx_attributes']
# Return False if nsx attributes are not definied for this
# neutron router
for attr in self.nsx_attributes:
for attr in nsx_attributes:
name = attr['name']
default = attr['default']
router_res[name] = (
@ -61,7 +61,3 @@ class NsxRouterMixin(object):
name, default)
LOG.debug("Nsx router extension successfully processed "
"for router:%s", router_db['id'])
# Register dict extend functions for ports
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
l3.ROUTERS, ['_extend_nsx_router_dict'])

@ -16,9 +16,10 @@
from sqlalchemy.orm import exc
from neutron.api.v2 import attributes as attr
from neutron.db import _model_query as model_query
from neutron.db import _resource_extend as resource_extend
from neutron.db import _utils as db_utils
from neutron.db import api as db_api
from neutron.db import db_base_plugin_v2
from neutron.db import models_v2
from oslo_log import log
@ -30,6 +31,7 @@ from vmware_nsx.extensions import qos_queue as qos
LOG = log.getLogger(__name__)
@resource_extend.has_resource_extenders
class QoSDbMixin(qos.QueuePluginBase):
"""Mixin class to add queues."""
@ -54,19 +56,20 @@ class QoSDbMixin(qos.QueuePluginBase):
def _get_qos_queue(self, context, queue_id):
try:
return self._get_by_id(context, nsx_models.QoSQueue, queue_id)
return model_query.get_by_id(context, nsx_models.QoSQueue,
queue_id)
except exc.NoResultFound:
raise qos.QueueNotFound(id=queue_id)
def get_qos_queues(self, context, filters=None, fields=None, sorts=None,
limit=None, marker=None, page_reverse=False):
marker_obj = self._get_marker_obj(context, 'qos_queue', limit, marker)
return self._get_collection(context, nsx_models.QoSQueue,
self._make_qos_queue_dict,
filters=filters, fields=fields,
sorts=sorts, limit=limit,
marker_obj=marker_obj,
page_reverse=page_reverse)
return model_query.get_collection(context, nsx_models.QoSQueue,
self._make_qos_queue_dict,
filters=filters, fields=fields,
sorts=sorts, limit=limit,
marker_obj=marker_obj,
page_reverse=page_reverse)
def delete_qos_queue(self, context, queue_id):
with db_api.context_manager.writer.using(context):
@ -83,12 +86,14 @@ class QoSDbMixin(qos.QueuePluginBase):
queue_id=queue_id))
def _get_port_queue_bindings(self, context, filters=None, fields=None):
return self._get_collection(context, nsx_models.PortQueueMapping,
self._make_port_queue_binding_dict,
filters=filters, fields=fields)
return model_query.get_collection(context,
nsx_models.PortQueueMapping,
self._make_port_queue_binding_dict,
filters=filters, fields=fields)
def _delete_port_queue_mapping(self, context, port_id):
query = self._model_query(context, nsx_models.PortQueueMapping)
query = model_query.query_with_hooks(context,
nsx_models.PortQueueMapping)
try:
binding = query.filter(
nsx_models.PortQueueMapping.port_id == port_id).one()
@ -110,9 +115,11 @@ class QoSDbMixin(qos.QueuePluginBase):
queue_id=queue_id))
def _get_network_queue_bindings(self, context, filters=None, fields=None):
return self._get_collection(context, nsx_models.NetworkQueueMapping,
self._make_network_queue_binding_dict,
filters=filters, fields=fields)
return model_query.get_collection(
context,
nsx_models.NetworkQueueMapping,
self._make_network_queue_binding_dict,
filters=filters, fields=fields)
def _delete_network_queue_mapping(self, context, network_id):
query = self._model_query(context, nsx_models.NetworkQueueMapping)
@ -121,24 +128,15 @@ class QoSDbMixin(qos.QueuePluginBase):
if binding:
context.session.delete(binding)
def _extend_dict_qos_queue(self, obj_res, obj_db):
@staticmethod
@resource_extend.extends([attr.NETWORKS])
@resource_extend.extends([attr.PORTS])
def _extend_dict_qos_queue(obj_res, obj_db):
queue_mapping = obj_db['qos_queue']
if queue_mapping:
obj_res[qos.QUEUE] = queue_mapping.get('queue_id')
return obj_res
def _extend_port_dict_qos_queue(self, port_res, port_db):
self._extend_dict_qos_queue(port_res, port_db)
def _extend_network_dict_qos_queue(self, network_res, network_db):
self._extend_dict_qos_queue(network_res, network_db)
# Register dict extend functions for networks and ports
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
attr.NETWORKS, ['_extend_network_dict_qos_queue'])
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
attr.PORTS, ['_extend_port_dict_qos_queue'])
def _make_qos_queue_dict(self, queue, fields=None):
res = {'id': queue['id'],
'name': queue.get('name'),
@ -203,9 +201,9 @@ class QoSDbMixin(qos.QueuePluginBase):
filters = {'device_id': [port.get('device_id')],
'network_id': [network['network_id'] for
network in networks_with_same_queue]}
query = self._model_query(context, models_v2.Port.id)
query = self._apply_filters_to_query(query, models_v2.Port,
filters)
query = model_query.query_with_hooks(context, models_v2.Port.id)
model_query.apply_filters(query, models_v2.Port,
filters, context)
ports_ids = [p[0] for p in query]
if ports_ids:
# shared queue already exists find the queue id

@ -16,7 +16,7 @@
from sqlalchemy.orm import exc
from neutron.api.v2 import attributes as attr
from neutron.db import db_base_plugin_v2
from neutron.db import _resource_extend as resource_extend
from oslo_db import exception as db_exc
from oslo_log import log as logging
@ -27,15 +27,15 @@ from vmware_nsx.extensions import vnicindex as vnicidx
LOG = logging.getLogger(__name__)
@resource_extend.has_resource_extenders
class VnicIndexDbMixin(object):
def _extend_port_vnic_index_binding(self, port_res, port_db):
@staticmethod
@resource_extend.extends([attr.PORTS])
def _extend_port_vnic_index_binding(port_res, port_db):
state = port_db.vnic_index
port_res[vnicidx.VNIC_INDEX] = state.index if state else None
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
attr.PORTS, ['_extend_port_vnic_index_binding'])
def _get_port_vnic_index(self, context, port_id):
"""Returns the vnic index for the given port.
If the port is not associated with any vnic then return None

@ -15,6 +15,11 @@
# under the License.
#
# Note: this import should be here in order to appear before NeutronDbPluginV2
# in each of the plugins. If not: security-group/-rule will not have all the
# relevant extend dict registries.
from neutron.db.models import securitygroup # noqa
from vmware_nsx.plugins.dvs import plugin as dvs
from vmware_nsx.plugins.nsx_mh import plugin as nsx_mh
from vmware_nsx.plugins.nsx_v import plugin as nsx_v

@ -15,12 +15,12 @@
import uuid
from neutron_lib import context as n_context
from oslo_log import log as logging
from oslo_utils import excutils
from neutron.api import extensions as neutron_extensions
from neutron.api.v2 import attributes as attr
from neutron.db import _resource_extend as resource_extend
from neutron.db import _utils as db_utils
from neutron.db import agentschedulers_db
from neutron.db import allowedaddresspairs_db as addr_pair_db
@ -62,6 +62,7 @@ from vmware_nsx.dvs import dvs_utils
LOG = logging.getLogger(__name__)
@resource_extend.has_resource_extenders
class NsxDvsV2(addr_pair_db.AllowedAddressPairsMixin,
agentschedulers_db.DhcpAgentSchedulerDbMixin,
db_base_plugin_v2.NeutronDbPluginV2,
@ -104,11 +105,9 @@ class NsxDvsV2(addr_pair_db.AllowedAddressPairsMixin,
self._dvs = dvs.SingleDvsManager()
self.setup_dhcpmeta_access()
# Register extend dict methods for port resources.
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
attr.PORTS, ['_ext_extend_port_dict'])
def _extend_port_dict_binding(self, portdb, result):
@staticmethod
@resource_extend.extends([attr.PORTS])
def _extend_port_dict_binding(result, portdb):
result[pbin.VIF_TYPE] = nsx_constants.VIF_TYPE_DVS
port_attr = portdb.get('nsx_port_attributes')
if port_attr:
@ -117,14 +116,8 @@ class NsxDvsV2(addr_pair_db.AllowedAddressPairsMixin,
result[pbin.VNIC_TYPE] = pbin.VNIC_NORMAL
result[pbin.VIF_DETAILS] = {
# TODO(rkukura): Replace with new VIF security details
pbin.CAP_PORT_FILTER:
'security-group' in self.supported_extension_aliases}
def _ext_extend_port_dict(self, result, portdb):
ctx = n_context.get_admin_context()
with db_api.context_manager.writer.using(ctx):
self._extend_port_dict_binding(portdb,
result)
# security-groups extension supported by this plugin
pbin.CAP_PORT_FILTER: True}
def _extend_network_dict_provider(self, context, network,
multiprovider=None, bindings=None):
@ -202,7 +195,7 @@ class NsxDvsV2(addr_pair_db.AllowedAddressPairsMixin,
net_db = self._get_network(context, new_net['id'])
net_db['vlan_transparent'] = trunk_mode
net_data['vlan_transparent'] = trunk_mode
self._apply_dict_extend_functions('networks', net_data, net_db)
resource_extend.apply_funcs('networks', net_data, net_db)
nsx_db.add_network_binding(
context.session, new_net['id'],
@ -223,7 +216,7 @@ class NsxDvsV2(addr_pair_db.AllowedAddressPairsMixin,
# this extra lookup is necessary to get the
# latest db model for the extension functions
net_model = self._get_network(context, net_data['id'])
self._apply_dict_extend_functions('networks', new_net, net_model)
resource_extend.apply_funcs('networks', new_net, net_model)
self.handle_network_dhcp_access(context, new_net,
action='create_network')
@ -397,7 +390,7 @@ class NsxDvsV2(addr_pair_db.AllowedAddressPairsMixin,
# this extra lookup is necessary to get the
# latest db model for the extension functions
port_model = self._get_port(context, port_data['id'])
self._apply_dict_extend_functions('ports', port_data, port_model)
resource_extend.apply_funcs('ports', port_data, port_model)
self.handle_port_dhcp_access(context, port_data, action='create_port')
return port_data

@ -32,6 +32,8 @@ import webob.exc
from neutron.api import extensions as neutron_extensions
from neutron.api.v2 import attributes as attr
from neutron.api.v2 import base
from neutron.db import _model_query as model_query
from neutron.db import _resource_extend as resource_extend
from neutron.db import _utils as db_utils
from neutron.db import agentschedulers_db
from neutron.db import allowedaddresspairs_db as addr_pair_db
@ -1005,7 +1007,7 @@ class NsxPluginV2(addr_pair_db.AllowedAddressPairsMixin,
# this extra lookup is necessary to get the
# latest db model for the extension functions
net_model = self._get_network(context, new_net['id'])
self._apply_dict_extend_functions('networks', new_net, net_model)
resource_extend.apply_funcs('networks', new_net, net_model)
self.handle_network_dhcp_access(context, new_net,
action='create_network')
return new_net
@ -1197,7 +1199,7 @@ class NsxPluginV2(addr_pair_db.AllowedAddressPairsMixin,
# this extra lookup is necessary to get the
# latest db model for the extension functions
port_model = self._get_port(context, neutron_port_id)
self._apply_dict_extend_functions('ports', port_data, port_model)
resource_extend.apply_funcs('ports', port_data, port_model)
self.handle_port_dhcp_access(context, port_data, action='create_port')
return port_data
@ -2155,7 +2157,7 @@ class NsxPluginV2(addr_pair_db.AllowedAddressPairsMixin,
LOG.error("Rolling back database changes for gateway device %s "
"because of an error in the NSX backend", device_id)
with db_api.context_manager.writer.using(context):
query = self._model_query(
query = model_query.query_with_hooks(
context, nsx_models.NetworkGatewayDevice).filter(
nsx_models.NetworkGatewayDevice.id == device_id)
if is_create:
@ -2191,7 +2193,7 @@ class NsxPluginV2(addr_pair_db.AllowedAddressPairsMixin,
# set NSX GW device in neutron database and update status
with db_api.context_manager.writer.using(context):
query = self._model_query(
query = model_query.query_with_hooks(
context, nsx_models.NetworkGatewayDevice).filter(
nsx_models.NetworkGatewayDevice.id == neutron_id)
query.update({'status': device_status,
@ -2230,7 +2232,7 @@ class NsxPluginV2(addr_pair_db.AllowedAddressPairsMixin,
nsx_id)
# update status
with db_api.context_manager.writer.using(context):
query = self._model_query(
query = model_query.query_with_hooks(
context, nsx_models.NetworkGatewayDevice).filter(
nsx_models.NetworkGatewayDevice.id == neutron_id)
query.update({'status': device_status},
@ -2265,7 +2267,7 @@ class NsxPluginV2(addr_pair_db.AllowedAddressPairsMixin,
# TODO(salv-orlando): Asynchronous sync for gateway device status
# Update status in database
with db_api.context_manager.writer.using(context):
query = self._model_query(
query = model_query.query_with_hooks(
context, nsx_models.NetworkGatewayDevice).filter(
nsx_models.NetworkGatewayDevice.id == device_id)
query.update({'status': device_status},

@ -38,6 +38,7 @@ from neutron.common import ipv6_utils
from neutron.common import rpc as n_rpc
from neutron.common import topics
from neutron.common import utils as n_utils
from neutron.db import _resource_extend as resource_extend
from neutron.db import _utils as db_utils
from neutron.db import address_scope_db
from neutron.db import agents_db
@ -136,6 +137,7 @@ ROUTER_SIZE = routersize.ROUTER_SIZE
VALID_EDGE_SIZES = routersize.VALID_EDGE_SIZES
@resource_extend.has_resource_extenders
class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
agents_db.AgentDbMixin,
db_base_plugin_v2.NeutronDbPluginV2,
@ -289,16 +291,6 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
# Bind QoS notifications
qos_driver.register(self)
# Register extend dict methods for network and port resources.
# Each extension driver that supports extend attribute for the resources
# can add those attribute to the result.
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
attr.NETWORKS, ['_ext_extend_network_dict'])
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
attr.PORTS, ['_ext_extend_port_dict'])
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
attr.SUBNETS, ['_ext_extend_subnet_dict'])
def init_complete(self, resource, event, trigger, **kwargs):
has_metadata_cfg = (
cfg.CONF.nsxv.nova_metadata_ips
@ -378,24 +370,34 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
# Bind FWaaS callbacks to the driver
self.fwaas_callbacks = fwaas_callbacks.NsxvFwaasCallbacks()
def _ext_extend_network_dict(self, result, netdb):
@staticmethod
@resource_extend.extends([attr.NETWORKS])
def _ext_extend_network_dict(result, netdb):
ctx = n_context.get_admin_context()
# get the core plugin as this is a static method with no 'self'
plugin = directory.get_plugin()
with db_api.context_manager.writer.using(ctx):
self._extension_manager.extend_network_dict(
plugin._extension_manager.extend_network_dict(
ctx.session, netdb, result)
def _ext_extend_port_dict(self, result, portdb):
@staticmethod
@resource_extend.extends([attr.PORTS])
def _ext_extend_port_dict(result, portdb):
ctx = n_context.get_admin_context()
# get the core plugin as this is a static method with no 'self'
plugin = directory.get_plugin()
with db_api.context_manager.writer.using(ctx):
self._extension_manager.extend_port_dict(
plugin._extension_manager.extend_port_dict(
ctx.session, portdb, result)
self._extend_port_dict_binding(portdb,
result)
def _ext_extend_subnet_dict(self, result, subnetdb):
@staticmethod
@resource_extend.extends([attr.SUBNETS])
def _ext_extend_subnet_dict(result, subnetdb):
ctx = n_context.get_admin_context()
# get the core plugin as this is a static method with no 'self'
plugin = directory.get_plugin()
with db_api.context_manager.writer.using(ctx):
self._extension_manager.extend_subnet_dict(
plugin._extension_manager.extend_subnet_dict(
ctx.session, subnetdb, result)
def _create_security_group_container(self):
@ -448,6 +450,13 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
r["distributed"] = False
r["router_type"] = router_type
@staticmethod
@resource_extend.extends([l3.ROUTERS])
def _extend_nsx_router_dict(router_res, router_db):
router_type_obj = rt_rtr.RouterType_mixin()
router_type_obj._extend_nsx_router_dict(
router_res, router_db, router_type_obj.nsx_attributes)
def _create_cluster_default_fw_section(self):
section_name = 'OS Cluster Security Group section'
@ -1229,7 +1238,7 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
# this extra lookup is necessary to get the
# latest db model for the extension functions
net_model = self._get_network(context, new_net['id'])
self._apply_dict_extend_functions('networks', new_net, net_model)
resource_extend.apply_funcs('networks', new_net, net_model)
return new_net
def _update_qos_on_created_network(self, context, net_data):
@ -1741,7 +1750,16 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
# this extra lookup is necessary to get the
# latest db model for the extension functions
port_model = self._get_port(context, port_data['id'])
self._apply_dict_extend_functions('ports', port_data, port_model)
resource_extend.apply_funcs('ports', port_data, port_model)
self._remove_provider_security_groups_from_list(port_data)
return port_data
def _make_port_dict(self, port, fields=None,
process_extensions=True):
port_data = super(NsxVPluginV2, self)._make_port_dict(
port, fields=fields,
process_extensions=process_extensions)
self._remove_provider_security_groups_from_list(port_data)
return port_data
def _get_port_subnet_mask(self, context, port):
@ -2190,7 +2208,9 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
self._delete_dhcp_static_binding(context, neutron_db_port)
def _extend_port_dict_binding(self, portdb, result):
@staticmethod
@resource_extend.extends([attr.PORTS])
def _extend_nsx_port_dict_binding(result, portdb):
result[pbin.VIF_TYPE] = nsx_constants.VIF_TYPE_DVS
port_attr = portdb.get('nsx_port_attributes')
if port_attr:
@ -2199,8 +2219,8 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
result[pbin.VNIC_TYPE] = pbin.VNIC_NORMAL
result[pbin.VIF_DETAILS] = {
# TODO(rkukura): Replace with new VIF security details
pbin.CAP_PORT_FILTER:
'security-group' in self.supported_extension_aliases}
# security-groups extension supported by this plugin
pbin.CAP_PORT_FILTER: True}
def delete_subnet(self, context, id):
subnet = self._get_subnet(context, id)
@ -2460,10 +2480,9 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
self._update_subnet_dhcp_status(subnet, context)
return subnet
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
attr.SUBNETS, ['_extend_subnet_dict_extended_attributes'])
def _extend_subnet_dict_extended_attributes(self, subnet_res, subnet_db):
@staticmethod
@resource_extend.extends([attr.SUBNETS])
def _extend_subnet_dict_extended_attributes(subnet_res, subnet_db):
subnet_attr = subnet_db.get('nsxv_subnet_attributes')
if subnet_attr:
subnet_res['dns_search_domain'] = subnet_attr.dns_search_domain
@ -3027,10 +3046,9 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
super(NsxVPluginV2, self).delete_router(context, id)
router_driver.delete_router(context, id)
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
attr.NETWORKS, ['_extend_availability_zone_hints'])
def _extend_availability_zone_hints(self, net_res, net_db):
@staticmethod
@resource_extend.extends([attr.NETWORKS])
def _extend_availability_zone_hints(net_res, net_db):
net_res[az_ext.AZ_HINTS] = az_ext.convert_az_string_to_list(
net_db[az_ext.AZ_HINTS])
@ -3078,12 +3096,11 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
if validators.is_attr_set(r.get('flavor_id')):
router_db.flavor_id = r['flavor_id']
def add_flavor_id(plugin, router_res, router_db):
@staticmethod
@resource_extend.extends([l3.ROUTERS])
def add_flavor_id(router_res, router_db):
router_res['flavor_id'] = router_db['flavor_id']
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
l3.ROUTERS, [add_flavor_id])
def get_router(self, context, id, fields=None):
router = super(NsxVPluginV2, self).get_router(context, id, fields)
if router.get("distributed") and 'router_type' in router:

@ -22,6 +22,7 @@ from neutron.api.rpc.handlers import metadata_rpc
from neutron.api.v2 import attributes
from neutron.common import rpc as n_rpc
from neutron.common import topics
from neutron.db import _resource_extend as resource_extend
from neutron.db import _utils as db_utils
from neutron.db import address_scope_db
from neutron.db import agents_db
@ -64,6 +65,7 @@ from neutron_lib.callbacks import resources
from neutron_lib import constants as const
from neutron_lib import context as q_context
from neutron_lib import exceptions as n_exc
from neutron_lib.plugins import directory
from neutron_lib.utils import helpers
from oslo_config import cfg
from oslo_db import exception as db_exc
@ -119,6 +121,7 @@ NSX_V3_EXCLUDED_PORT_NSGROUP_NAME = 'neutron_excluded_port_nsgroup'
# this needs to be above securitygroups_db.SecurityGroupDbMixin.
# FIXME(arosen): we can solve this inheritance order issue by just mixining in
# the classes into a new class to handle the order correctly.
@resource_extend.has_resource_extenders
class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
extended_security_group.ExtendedSecurityGroupPropertiesMixin,
addr_pair_db.AllowedAddressPairsMixin,
@ -242,17 +245,6 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
# Register NSXv3 trunk driver to support trunk extensions
self.trunk_driver = trunk_driver.NsxV3TrunkDriver.create(self)
# Register extend dict methods for network and port resources.
# Each extension driver that supports extend attribute for the resources
# can add those attribute to the result.
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
attributes.NETWORKS, ['_ext_extend_network_dict',
'_extend_availability_zone_hints'])
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
attributes.PORTS, ['_ext_extend_port_dict'])
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
attributes.SUBNETS, ['_ext_extend_subnet_dict'])
def init_availability_zones(self):
# availability zones are supported only with native dhcp
# if not - the default az will be loaded and used internally only
@ -320,7 +312,8 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
for az in self.get_azs_list():
az.translate_configured_names_to_uuids(self.nsxlib)
def _extend_port_dict_binding(self, context, port_data):
def _extend_nsx_port_dict_binding(self, context, port_data):
# Not using the register api for this because we need the context
port_data[pbin.VIF_TYPE] = pbin.VIF_TYPE_OVS
port_data[pbin.VNIC_TYPE] = pbin.VNIC_NORMAL
if 'network_id' in port_data:
@ -557,22 +550,34 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
return self.conn.consume_in_threads()
def _ext_extend_network_dict(self, result, netdb):
@staticmethod
@resource_extend.extends([attributes.NETWORKS])
def _ext_extend_network_dict(result, netdb):
ctx = q_context.get_admin_context()
# get the core plugin as this is a static method with no 'self'
plugin = directory.get_plugin()
with db_api.context_manager.writer.using(ctx):
self._extension_manager.extend_network_dict(
plugin._extension_manager.extend_network_dict(
ctx.session, netdb, result)
def _ext_extend_port_dict(self, result, portdb):
@staticmethod
@resource_extend.extends([attributes.PORTS])
def _ext_extend_port_dict(result, portdb):
ctx = q_context.get_admin_context()
# get the core plugin as this is a static method with no 'self'
plugin = directory.get_plugin()
with db_api.context_manager.writer.using(ctx):
self._extension_manager.extend_port_dict(
plugin._extension_manager.extend_port_dict(
ctx.session, portdb, result)
def _ext_extend_subnet_dict(self, result, subnetdb):
@staticmethod
@resource_extend.extends([attributes.SUBNETS])
def _ext_extend_subnet_dict(result, subnetdb):
ctx = q_context.get_admin_context()
# get the core plugin as this is a static method with no 'self'
plugin = directory.get_plugin()
with db_api.context_manager.writer.using(ctx):
self._extension_manager.extend_subnet_dict(
plugin._extension_manager.extend_subnet_dict(
ctx.session, subnetdb, result)
def _validate_provider_create(self, context, network_data, az):
@ -829,7 +834,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
# this extra lookup is necessary to get the
# latest db model for the extension functions
net_model = self._get_network(context, created_net['id'])
self._apply_dict_extend_functions('networks', created_net, net_model)
resource_extend.apply_funcs('networks', created_net, net_model)
if qos_consts.QOS_POLICY_ID in net_data:
# attach the policy to the network in neutron DB
@ -2041,7 +2046,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
# sgids is a set() so we need to | it in.
if provider_groups:
sgids = list(set(sgids) | set(provider_groups))
self._extend_port_dict_binding(context, port_data)
self._extend_nsx_port_dict_binding(context, port_data)
if validators.is_attr_set(port_data.get(mac_ext.MAC_LEARNING)):
if is_psec_on:
msg = _('Mac learning requires that port security be '
@ -2105,7 +2110,8 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
# this extra lookup is necessary to get the
# latest db model for the extension functions
port_model = self._get_port(context, port_data['id'])
self._apply_dict_extend_functions('ports', port_data, port_model)
resource_extend.apply_funcs('ports', port_data, port_model)
self._remove_provider_security_groups_from_list(port_data)
# Add Mac/IP binding to native DHCP server and neutron DB.
if cfg.CONF.nsx_v3.native_dhcp_metadata:
@ -2436,7 +2442,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
context, updated_port)
self._process_portbindings_create_and_update(
context, port['port'], updated_port)
self._extend_port_dict_binding(context, updated_port)
self._extend_nsx_port_dict_binding(context, updated_port)
mac_learning_state = updated_port.get(mac_ext.MAC_LEARNING)
if mac_learning_state is not None:
if port_security and mac_learning_state:
@ -2505,8 +2511,9 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
return updated_port
def _extend_get_port_dict_binding(self, context, port):
self._extend_port_dict_binding(context, port)
def _extend_get_port_dict_qos_and_binding(self, context, port):
# Not using the register api for this because we need the context
self._extend_nsx_port_dict_binding(context, port)
# add the qos policy id from the DB
if 'id' in port:
@ -2515,8 +2522,11 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
def get_port(self, context, id, fields=None):
port = super(NsxV3Plugin, self).get_port(context, id, fields=None)
self._extend_get_port_dict_binding(context, port)
if 'id' in port:
port_model = self._get_port(context, port['id'])
resource_extend.apply_funcs('ports', port, port_model)
self._extend_get_port_dict_qos_and_binding(context, port)
self._remove_provider_security_groups_from_list(port)
return db_utils.resource_fields(port, fields)
def get_ports(self, context, filters=None, fields=None,
@ -2530,7 +2540,11 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
limit, marker, page_reverse))
# Add port extensions
for port in ports:
self._extend_get_port_dict_binding(context, port)
if 'id' in port:
port_model = self._get_port(context, port['id'])
resource_extend.apply_funcs('ports', port, port_model)
self._extend_get_port_dict_qos_and_binding(context, port)
self._remove_provider_security_groups_from_list(port)
return (ports if not fields else
[db_utils.resource_fields(port, fields) for port in ports])
@ -3520,7 +3534,9 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
# Validate against the configured AZs
return self.validate_obj_azs(availability_zones)
def _extend_availability_zone_hints(self, net_res, net_db):
@staticmethod
@resource_extend.extends([attributes.NETWORKS])
def _extend_availability_zone_hints(net_res, net_db):
net_res[az_ext.AZ_HINTS] = az_ext.convert_az_string_to_list(
net_db[az_ext.AZ_HINTS])
if cfg.CONF.nsx_v3.native_dhcp_metadata:

@ -27,6 +27,7 @@ from oslo_log import log as logging
from vmware_nsx.common import utils as com_utils
from vmware_nsx.db import db as nsx_db
from vmware_nsx.db import extended_security_group as extended_secgroup
from vmware_nsx.db import extended_security_group_rule as extend_sg_rule
from vmware_nsx.db import nsx_models
from vmware_nsx.db import nsxv_db
from vmware_nsx.db import nsxv_models
@ -44,7 +45,8 @@ LOG = logging.getLogger(__name__)
class NeutronSecurityGroupDB(
utils.NeutronDbClient,
securitygroups_db.SecurityGroupDbMixin,
extended_secgroup.ExtendedSecurityGroupPropertiesMixin):
extended_secgroup.ExtendedSecurityGroupPropertiesMixin,
extend_sg_rule.ExtendedSecurityGroupRuleMixin):
def __init__(self):
super(NeutronSecurityGroupDB, self)

@ -37,7 +37,7 @@ PLUGIN_NAME = ('vmware_nsx.tests.unit.extensions.'
class ProviderSecurityGroupTestPlugin(
db_base_plugin_v2.NeutronDbPluginV2,
extended_security_group.ExtendedSecurityGroupPropertiesMixin,
securitygroups_db.SecurityGroupDbMixin):
securitygroups_db.SecurityGroupDbMixin):
supported_extension_aliases = ["security-group",
"provider-security-group"]
@ -97,6 +97,14 @@ class ProviderSecurityGroupTestPlugin(
context, port, original_port, updated_port)
return self.get_port(context, id)
def _make_port_dict(self, port, fields=None, process_extensions=True):
port_data = super(
ProviderSecurityGroupTestPlugin, self)._make_port_dict(
port, fields=fields,
process_extensions=process_extensions)
self._remove_provider_security_groups_from_list(port_data)
return port_data
def delete_security_group(self, context, id):
self._prevent_non_admin_delete_provider_sg(context, id)
super(ProviderSecurityGroupTestPlugin,

@ -5023,7 +5023,7 @@ class TestRouterFlavorTestCase(extension.ExtensionTestCase,
FLAVOR_PLUGIN = 'neutron.services.flavors.flavors_plugin.FlavorsPlugin'
def _mock_add_flavor_id(self, resource_type, router_res, router_db):
def _mock_add_flavor_id(dummy, router_res, router_db):
# this function is a registered callback so we can't mock it
# in a regular way.
# need to change behavior for this test suite only, since

@ -26,14 +26,14 @@ from neutron.common import config as neutron_config
from neutron.db import servicetype_db # noqa
from neutron.quota import resource_registry
from neutron.tests import base
from neutron.tests.unit.api import test_extensions
from neutron_lib.callbacks import registry
from vmware_nsx._i18n import _
from vmware_nsx.common import config # noqa
from vmware_nsx.db import nsxv_db
from vmware_nsx.dvs import dvs_utils
import vmware_nsx.shell.admin.plugins.nsxv.resources.utils as utils
from vmware_nsx.shell.admin.plugins.nsxv.resources import utils as nsxv_utils
from vmware_nsx.shell.admin.plugins.nsxv3.resources import utils as nsxv3_utils
from vmware_nsx.shell import resources
from vmware_nsx.tests import unit as vmware
from vmware_nsx.tests.unit.nsx_v import test_plugin as test_v_plugin
@ -137,8 +137,20 @@ class TestNsxvAdminUtils(AbstractTestAdminUtils,
'NsxVPluginWrapper.count_spawn_jobs',
return_value=0).start()
self._plugin = nsxv_utils.NsxVPluginWrapper()
mock_nm_get_plugin = mock.patch(
"neutron_lib.plugins.directory.get_plugin")
self.mock_nm_get_plugin = mock_nm_get_plugin.start()
self.mock_nm_get_plugin.return_value = self._plugin
# Create a router to make sure we have deployed an edge
self.create_router()
self.router = self.create_router()
def tearDown(self):
if self.router and self.router.get('id'):
edgeapi = nsxv_utils.NeutronDbClient()
self._plugin.delete_router(edgeapi.context, self.router['id'])
super(TestNsxvAdminUtils, self).tearDown()
def test_nsxv_resources(self):
self._test_resources(resources.nsxv_resources)
@ -149,26 +161,18 @@ class TestNsxvAdminUtils(AbstractTestAdminUtils,
self._test_resource('edges', 'nsx-update', **args)
def create_router(self):
# Global configuration to support router creation without messing up
# the plugin wrapper
cfg.CONF.set_override('track_quota_usage', False,
group='QUOTAS')
ext_mgr = test_v_plugin.TestL3ExtensionManager()
ext_api = test_extensions.setup_extensions_middleware(ext_mgr)
# Create an exclusive router (with an edge)
tenant_id = uuidutils.generate_uuid()
data = {'router': {'tenant_id': tenant_id}}
data['router']['name'] = 'dummy'
data['router']['admin_state_up'] = True
data['router']['router_type'] = 'exclusive'
router_req = self.new_create_request('routers', data, self.fmt)
res = router_req.get_response(ext_api)
r = self.deserialize(self.fmt, res)
return r
edgeapi = nsxv_utils.NeutronDbClient()
return self._plugin.create_router(edgeapi.context, data)
def get_edge_id(self):
edgeapi = utils.NeutronDbClient()
edgeapi = nsxv_utils.NeutronDbClient()
bindings = nsxv_db.get_nsxv_router_bindings(edgeapi.context.session)
for binding in bindings:
if binding.edge_id:
@ -251,6 +255,12 @@ class TestNsxv3AdminUtils(AbstractTestAdminUtils,
return_value=[{'id': uuidutils.generate_uuid()}])
super(TestNsxv3AdminUtils, self)._init_mock_plugin()
self._plugin = nsxv3_utils.NsxV3PluginWrapper()
mock_nm_get_plugin = mock.patch(
"neutron_lib.plugins.directory.get_plugin")
self.mock_nm_get_plugin = mock_nm_get_plugin.start()
self.mock_nm_get_plugin.return_value = self._plugin
def _get_plugin_name(self):
return 'nsxv3'

Loading…
Cancel
Save