nsxlib refactor continue
- separate nsxlib/v3 constants and utils from the common ones - separate the nsxlib/v3 tests - update the nsxlib tests to cover create_firewall_rules - remove all of the DB calls from the nsxlib/v3 - merge security & dfw_api classes To be done in future patches: - Avoid using the nsx configuration values directly - Improve nsxlib interface (as Aaron suggested in If2fe1e014b78703ff0a9cdff1e4e8d45f3a4a16d) Change-Id: I43257f557ce1e98b4f64b8157d723cc84ea58c2b
This commit is contained in:
parent
a3b17e2441
commit
a7b5bfafcc
@ -13,52 +13,8 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
# Admin statuses
|
||||
ADMIN_STATE_UP = "UP"
|
||||
ADMIN_STATE_DOWN = "DOWN"
|
||||
|
||||
ADMIN_STATUSES = [ADMIN_STATE_UP, ADMIN_STATE_DOWN]
|
||||
|
||||
# Port attachment types
|
||||
ATTACHMENT_VIF = "VIF"
|
||||
ATTACHMENT_LR = "LOGICALROUTER"
|
||||
ATTACHMENT_DHCP = "DHCP_SERVICE"
|
||||
ATTACHMENT_MDPROXY = "METADATA_PROXY"
|
||||
ATTACHMENT_CIF = "CIF"
|
||||
CIF_RESOURCE_TYPE = "CifAttachmentContext"
|
||||
|
||||
ATTACHMENT_TYPES = [ATTACHMENT_VIF, ATTACHMENT_LR]
|
||||
|
||||
# Replication modes
|
||||
MTEP = "MTEP"
|
||||
SOURCE = "SOURCE"
|
||||
|
||||
REPLICATION_MODES = [MTEP, SOURCE]
|
||||
|
||||
# Router type
|
||||
ROUTER_TYPE_TIER0 = "TIER0"
|
||||
ROUTER_TYPE_TIER1 = "TIER1"
|
||||
|
||||
ROUTER_TYPES = [ROUTER_TYPE_TIER0, ROUTER_TYPE_TIER1]
|
||||
|
||||
LROUTERPORT_UPLINK = "LogicalRouterUplinkPort"
|
||||
LROUTERPORT_DOWNLINK = "LogicalRouterDownLinkPort"
|
||||
LROUTERPORT_LINKONTIER0 = "LogicalRouterLinkPortOnTIER0"
|
||||
LROUTERPORT_LINKONTIER1 = "LogicalRouterLinkPortOnTIER1"
|
||||
|
||||
LROUTER_TYPES = [LROUTERPORT_UPLINK,
|
||||
LROUTERPORT_DOWNLINK,
|
||||
LROUTERPORT_LINKONTIER0,
|
||||
LROUTERPORT_LINKONTIER1]
|
||||
|
||||
# L2 agent vif type
|
||||
VIF_TYPE_DVS = 'dvs'
|
||||
|
||||
# NSXv3 L2 Gateway constants
|
||||
BRIDGE_ENDPOINT = "BRIDGEENDPOINT"
|
||||
|
||||
# NSX service type
|
||||
SERVICE_DHCP = "dhcp"
|
||||
|
||||
# NSXv3 CORE PLUGIN PATH
|
||||
VMWARE_NSX_V3_PLUGIN_NAME = 'vmware_nsx.plugin.NsxV3Plugin'
|
||||
|
@ -18,25 +18,20 @@ import functools
|
||||
import hashlib
|
||||
|
||||
import eventlet
|
||||
import six
|
||||
|
||||
from neutron import version as n_version
|
||||
from neutron_lib.api import validators
|
||||
from neutron_lib import constants
|
||||
from neutron_lib import exceptions
|
||||
from oslo_config import cfg
|
||||
from oslo_context import context as common_context
|
||||
from oslo_log import log
|
||||
import retrying
|
||||
import six
|
||||
|
||||
from vmware_nsx._i18n import _, _LE
|
||||
from vmware_nsx._i18n import _LE
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
MAX_DISPLAY_NAME_LEN = 40
|
||||
MAX_RESOURCE_TYPE_LEN = 20
|
||||
MAX_TAG_LEN = 40
|
||||
NEUTRON_VERSION = n_version.version_info.release_string()
|
||||
NSX_NEUTRON_PLUGIN = 'NSX Neutron plugin'
|
||||
OS_NEUTRON_ID_SCOPE = 'os-neutron-id'
|
||||
NSXV3_VERSION_1_1_0 = '1.1.0'
|
||||
|
||||
@ -111,137 +106,6 @@ def check_and_truncate(display_name):
|
||||
return display_name or ''
|
||||
|
||||
|
||||
def is_internal_resource(nsx_resource):
|
||||
"""
|
||||
Indicates whether the passed nsx-resource is owned by the plugin for
|
||||
internal use.
|
||||
"""
|
||||
for tag in nsx_resource.get('tags', []):
|
||||
if tag['scope'] == OS_NEUTRON_ID_SCOPE:
|
||||
return tag['tag'] == NSX_NEUTRON_PLUGIN
|
||||
return False
|
||||
|
||||
|
||||
def build_v3_api_version_tag():
|
||||
"""
|
||||
Some resources are created on the manager that do not have a corresponding
|
||||
Neutron resource.
|
||||
"""
|
||||
return [{'scope': OS_NEUTRON_ID_SCOPE,
|
||||
'tag': NSX_NEUTRON_PLUGIN},
|
||||
{'scope': "os-api-version",
|
||||
'tag': n_version.version_info.release_string()}]
|
||||
|
||||
|
||||
def _validate_resource_type_length(resource_type):
|
||||
# Add in a validation to ensure that we catch this at build time
|
||||
if len(resource_type) > MAX_RESOURCE_TYPE_LEN:
|
||||
raise exceptions.InvalidInput(
|
||||
error_message=(_('Resource type cannot exceed %(max_len)s '
|
||||
'characters: %(resource_type)s') %
|
||||
{'max_len': MAX_RESOURCE_TYPE_LEN,
|
||||
'resource_type': resource_type}))
|
||||
|
||||
|
||||
def build_v3_tags_payload(resource, resource_type, project_name):
|
||||
"""
|
||||
Construct the tags payload that will be pushed to NSX-v3
|
||||
Add <resource_type>:<resource-id>, os-project-id:<tenant-id>,
|
||||
os-project-name:<project_name> os-api-version:<neutron-api-version>
|
||||
"""
|
||||
_validate_resource_type_length(resource_type)
|
||||
# There may be cases when the plugin creates the port, for example DHCP
|
||||
if not project_name:
|
||||
project_name = 'NSX Neutron plugin'
|
||||
tenant_id = resource.get('tenant_id', '')
|
||||
# If tenant_id is present in resource and set to None, explicitly set
|
||||
# the tenant_id in tags as ''.
|
||||
if tenant_id is None:
|
||||
tenant_id = ''
|
||||
return [{'scope': resource_type,
|
||||
'tag': resource.get('id', '')[:MAX_TAG_LEN]},
|
||||
{'scope': 'os-project-id',
|
||||
'tag': tenant_id[:MAX_TAG_LEN]},
|
||||
{'scope': 'os-project-name',
|
||||
'tag': project_name[:MAX_TAG_LEN]},
|
||||
{'scope': 'os-api-version',
|
||||
'tag': n_version.version_info.release_string()[:MAX_TAG_LEN]}]
|
||||
|
||||
|
||||
def add_v3_tag(tags, resource_type, tag):
|
||||
_validate_resource_type_length(resource_type)
|
||||
tags.append({'scope': resource_type, 'tag': tag[:MAX_TAG_LEN]})
|
||||
return tags
|
||||
|
||||
|
||||
def update_v3_tags(current_tags, tags_update):
|
||||
current_scopes = set([tag['scope'] for tag in current_tags])
|
||||
updated_scopes = set([tag['scope'] for tag in tags_update])
|
||||
|
||||
tags = [{'scope': tag['scope'], 'tag': tag['tag']}
|
||||
for tag in (current_tags + tags_update)
|
||||
if tag['scope'] in (current_scopes ^ updated_scopes)]
|
||||
|
||||
modified_scopes = current_scopes & updated_scopes
|
||||
for tag in tags_update:
|
||||
if tag['scope'] in modified_scopes:
|
||||
# If the tag value is empty or None, then remove the tag completely
|
||||
if tag['tag']:
|
||||
tag['tag'] = tag['tag'][:MAX_TAG_LEN]
|
||||
tags.append(tag)
|
||||
|
||||
return tags
|
||||
|
||||
|
||||
def retry_upon_exception_nsxv3(exc, delay=500, max_delay=2000,
|
||||
max_attempts=cfg.CONF.nsx_v3.retries):
|
||||
return retrying.retry(retry_on_exception=lambda e: isinstance(e, exc),
|
||||
wait_exponential_multiplier=delay,
|
||||
wait_exponential_max=max_delay,
|
||||
stop_max_attempt_number=max_attempts)
|
||||
|
||||
|
||||
def list_match(list1, list2):
|
||||
# Check if list1 and list2 have identical elements, but relaxed on
|
||||
# dict elements where list1's dict element can be a subset of list2's
|
||||
# corresponding element.
|
||||
if (not isinstance(list1, list) or
|
||||
not isinstance(list2, list) or
|
||||
len(list1) != len(list2)):
|
||||
return False
|
||||
list1 = sorted(list1)
|
||||
list2 = sorted(list2)
|
||||
for (v1, v2) in zip(list1, list2):
|
||||
if isinstance(v1, dict):
|
||||
if not dict_match(v1, v2):
|
||||
return False
|
||||
elif isinstance(v1, list):
|
||||
if not list_match(v1, v2):
|
||||
return False
|
||||
elif v1 != v2:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def dict_match(dict1, dict2):
|
||||
# Check if dict1 is a subset of dict2.
|
||||
if not isinstance(dict1, dict) or not isinstance(dict2, dict):
|
||||
return False
|
||||
for k1, v1 in dict1.items():
|
||||
if k1 not in dict2:
|
||||
return False
|
||||
v2 = dict2[k1]
|
||||
if isinstance(v1, dict):
|
||||
if not dict_match(v1, v2):
|
||||
return False
|
||||
elif isinstance(v1, list):
|
||||
if not list_match(v1, v2):
|
||||
return False
|
||||
elif v1 != v2:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def read_file(path):
|
||||
try:
|
||||
with open(path) as file:
|
||||
|
@ -14,10 +14,12 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import six
|
||||
from sqlalchemy.orm import exc
|
||||
|
||||
from oslo_db import exception as db_exc
|
||||
from oslo_log import log as logging
|
||||
from oslo_utils import excutils
|
||||
from sqlalchemy.orm import exc
|
||||
|
||||
import neutron.db.api as db
|
||||
|
||||
@ -27,6 +29,20 @@ from vmware_nsx.db import nsx_models
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _apply_filters_to_query(query, model, filters, like_filters=None):
|
||||
if filters:
|
||||
for key, value in six.iteritems(filters):
|
||||
column = getattr(model, key, None)
|
||||
if column:
|
||||
query = query.filter(column.in_(value))
|
||||
if like_filters:
|
||||
for key, search_term in six.iteritems(like_filters):
|
||||
column = getattr(model, key, None)
|
||||
if column:
|
||||
query = query.filter(column.like(search_term))
|
||||
return query
|
||||
|
||||
|
||||
def get_network_bindings(session, network_id):
|
||||
session = session or db.get_session()
|
||||
return (session.query(nsx_models.TzNetworkBinding).
|
||||
@ -247,6 +263,19 @@ def get_nsx_security_group_id(session, neutron_id):
|
||||
return None
|
||||
|
||||
|
||||
def get_nsx_security_group_ids(session, neutron_ids):
|
||||
"""Return list of ids of a security groups in the NSX backend.
|
||||
"""
|
||||
filters = {'neutron_id': neutron_ids}
|
||||
like_filters = None
|
||||
query = session.query(nsx_models.NeutronNsxSecurityGroupMapping)
|
||||
mappings = _apply_filters_to_query(
|
||||
query, nsx_models.NeutronNsxSecurityGroupMapping,
|
||||
filters, like_filters).all()
|
||||
return [mapping['nsx_id'] for mapping in mappings
|
||||
if mapping['nsx_id'] is not None]
|
||||
|
||||
|
||||
def _delete_by_neutron_id(session, model, neutron_id):
|
||||
return session.query(model).filter_by(neutron_id=neutron_id).delete()
|
||||
|
||||
@ -361,8 +390,26 @@ def save_sg_mappings(session, sg_id, nsgroup_id, section_id):
|
||||
nsx_id=nsgroup_id))
|
||||
|
||||
|
||||
def get_sg_mappings(session, sg_id):
|
||||
nsgroup_mapping = session.query(
|
||||
nsx_models.NeutronNsxSecurityGroupMapping
|
||||
).filter_by(neutron_id=sg_id).one()
|
||||
section_mapping = session.query(
|
||||
nsx_models.NeutronNsxFirewallSectionMapping
|
||||
).filter_by(neutron_id=sg_id).one()
|
||||
return nsgroup_mapping.nsx_id, section_mapping.nsx_id
|
||||
|
||||
|
||||
def get_sg_rule_mapping(session, rule_id):
|
||||
rule_mapping = session.query(
|
||||
nsx_models.NeutronNsxRuleMapping).filter_by(
|
||||
neutron_id=rule_id).one()
|
||||
return rule_mapping.nsx_id
|
||||
|
||||
|
||||
def save_sg_rule_mappings(session, rules):
|
||||
with session.begin(subtransactions=True):
|
||||
for neutron_id, nsx_id in rules:
|
||||
mapping = nsx_models.NeutronNsxRuleMapping(
|
||||
neutron_id=neutron_id, nsx_id=nsx_id)
|
||||
session.add(mapping)
|
||||
|
@ -27,7 +27,7 @@ down_revision = 'c288bb6a7252'
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
from vmware_nsx.common import nsx_constants
|
||||
from vmware_nsx.nsxlib.v3 import nsx_constants
|
||||
|
||||
|
||||
nsx_service_type_enum = sa.Enum(
|
||||
|
@ -27,7 +27,7 @@ from sqlalchemy import sql
|
||||
from neutron.db import models_v2
|
||||
from oslo_db.sqlalchemy import models
|
||||
|
||||
from vmware_nsx.common import nsx_constants
|
||||
from vmware_nsx.nsxlib.v3 import nsx_constants
|
||||
|
||||
|
||||
class TzNetworkBinding(model_base.BASEV2, models.TimestampMixin):
|
||||
|
@ -29,6 +29,7 @@ from sqlalchemy.sql import expression as expr
|
||||
from vmware_nsx._i18n import _, _LE, _LW
|
||||
from vmware_nsx.common import exceptions as nsx_exc
|
||||
from vmware_nsx.common import nsxv_constants
|
||||
from vmware_nsx.db import db as nsx_db
|
||||
from vmware_nsx.db import nsxv_models
|
||||
from vmware_nsx.extensions import dhcp_mtu as ext_dhcp_mtu
|
||||
from vmware_nsx.extensions import dns_search_domain as ext_dns_search_domain
|
||||
@ -38,20 +39,6 @@ NsxvEdgeDhcpStaticBinding = nsxv_models.NsxvEdgeDhcpStaticBinding
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _apply_filters_to_query(query, model, filters, like_filters=None):
|
||||
if filters:
|
||||
for key, value in six.iteritems(filters):
|
||||
column = getattr(model, key, None)
|
||||
if column:
|
||||
query = query.filter(column.in_(value))
|
||||
if like_filters:
|
||||
for key, search_term in six.iteritems(like_filters):
|
||||
column = getattr(model, key, None)
|
||||
if column:
|
||||
query = query.filter(column.like(search_term))
|
||||
return query
|
||||
|
||||
|
||||
def add_nsxv_router_binding(session, router_id, vse_id, lswitch_id, status,
|
||||
appliance_size=nsxv_constants.LARGE,
|
||||
edge_type=nsxv_constants.SERVICE_EDGE,
|
||||
@ -117,8 +104,8 @@ def get_nsxv_router_bindings(session, filters=None,
|
||||
like_filters=None):
|
||||
session = db.get_session()
|
||||
query = session.query(nsxv_models.NsxvRouterBinding)
|
||||
return _apply_filters_to_query(query, nsxv_models.NsxvRouterBinding,
|
||||
filters, like_filters).all()
|
||||
return nsx_db._apply_filters_to_query(query, nsxv_models.NsxvRouterBinding,
|
||||
filters, like_filters).all()
|
||||
|
||||
|
||||
def update_nsxv_router_binding(session, router_id, **kwargs):
|
||||
@ -586,7 +573,7 @@ def get_nsxv_spoofguard_policy_network_mappings(session, filters=None,
|
||||
like_filters=None):
|
||||
session = db.get_session()
|
||||
query = session.query(nsxv_models.NsxvSpoofGuardPolicyNetworkMapping)
|
||||
return _apply_filters_to_query(
|
||||
return nsx_db._apply_filters_to_query(
|
||||
query, nsxv_models.NsxvSpoofGuardPolicyNetworkMapping,
|
||||
filters, like_filters).all()
|
||||
|
||||
|
@ -16,23 +16,17 @@
|
||||
from oslo_log import log
|
||||
|
||||
from vmware_nsx._i18n import _, _LW
|
||||
from vmware_nsx.common import nsx_constants
|
||||
from vmware_nsx.common import utils
|
||||
from vmware_nsx.nsxlib.v3 import client
|
||||
from vmware_nsx.nsxlib.v3 import cluster
|
||||
from vmware_nsx.nsxlib.v3 import dfw_api
|
||||
from vmware_nsx.nsxlib.v3 import exceptions
|
||||
from vmware_nsx.nsxlib.v3 import nsx_constants
|
||||
from vmware_nsx.nsxlib.v3 import security
|
||||
from vmware_nsx.nsxlib.v3 import utils
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
# Max amount of time to try a request
|
||||
DEFAULT_MAX_ATTEMPTS = 3
|
||||
|
||||
|
||||
class NsxLib(dfw_api.DfwApi, security.Security):
|
||||
|
||||
MAX_ATTEMPTS = DEFAULT_MAX_ATTEMPTS
|
||||
class NsxLib(security.Security):
|
||||
|
||||
def __init__(self,
|
||||
username=None,
|
||||
@ -45,9 +39,11 @@ class NsxLib(dfw_api.DfwApi, security.Security):
|
||||
http_read_timeout=None,
|
||||
conn_idle_timeout=None,
|
||||
http_provider=None,
|
||||
max_attempts=DEFAULT_MAX_ATTEMPTS):
|
||||
max_attempts=0):
|
||||
|
||||
self.max_attempts = max_attempts
|
||||
# TODO(asarfaty): use max_attempts instead of cfg value
|
||||
|
||||
# create the Cluster
|
||||
self.cluster = cluster.NSXClusteredAPI(
|
||||
username=username, password=password,
|
||||
retries=retries, insecure=insecure,
|
||||
@ -58,7 +54,9 @@ class NsxLib(dfw_api.DfwApi, security.Security):
|
||||
conn_idle_timeout=conn_idle_timeout,
|
||||
http_provider=http_provider)
|
||||
|
||||
# create the Client
|
||||
self.client = client.NSX3Client(self.cluster)
|
||||
|
||||
super(NsxLib, self).__init__()
|
||||
|
||||
def get_version(self):
|
||||
@ -70,7 +68,7 @@ class NsxLib(dfw_api.DfwApi, security.Security):
|
||||
resource = "edge-clusters/%s" % edge_cluster_uuid
|
||||
return self.client.get(resource)
|
||||
|
||||
@utils.retry_upon_exception_nsxv3(exceptions.StaleRevision)
|
||||
@utils.retry_upon_exception(exceptions.StaleRevision)
|
||||
def update_resource_with_retry(self, resource, payload):
|
||||
revised_payload = self.client.get(resource)
|
||||
for key_name in payload.keys():
|
||||
@ -128,8 +126,7 @@ class NsxLib(dfw_api.DfwApi, security.Security):
|
||||
|
||||
return self.client.create(resource, body)
|
||||
|
||||
@utils.retry_upon_exception_nsxv3(exceptions.StaleRevision,
|
||||
max_attempts=MAX_ATTEMPTS)
|
||||
@utils.retry_upon_exception(exceptions.StaleRevision)
|
||||
def delete_logical_switch(self, lswitch_id):
|
||||
resource = 'logical-switches/%s?detach=true&cascade=true' % lswitch_id
|
||||
self.client.delete(resource)
|
||||
@ -138,8 +135,7 @@ class NsxLib(dfw_api.DfwApi, security.Security):
|
||||
resource = "logical-switches/%s" % logical_switch_id
|
||||
return self.client.get(resource)
|
||||
|
||||
@utils.retry_upon_exception_nsxv3(exceptions.StaleRevision,
|
||||
max_attempts=MAX_ATTEMPTS)
|
||||
@utils.retry_upon_exception(exceptions.StaleRevision)
|
||||
def update_logical_switch(self, lswitch_id, name=None, admin_state=None,
|
||||
tags=None):
|
||||
resource = "logical-switches/%s" % lswitch_id
|
||||
@ -346,12 +342,12 @@ class NsxLib(dfw_api.DfwApi, security.Security):
|
||||
if len(matched_results) == 0:
|
||||
err_msg = (_("Could not find %(resource)s %(name)s") %
|
||||
{'name': name_or_id, 'resource': resource})
|
||||
# XXX improve exception handling...
|
||||
# TODO(asarfaty): improve exception handling...
|
||||
raise exceptions.ManagerError(details=err_msg)
|
||||
elif len(matched_results) > 1:
|
||||
err_msg = (_("Found multiple %(resource)s named %(name)s") %
|
||||
{'name': name_or_id, 'resource': resource})
|
||||
# XXX improve exception handling...
|
||||
# TODO(asarfaty): improve exception handling...
|
||||
raise exceptions.ManagerError(details=err_msg)
|
||||
|
||||
return matched_results[0].get('id')
|
||||
|
@ -1,269 +0,0 @@
|
||||
# Copyright 2015 OpenStack Foundation
|
||||
# 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.
|
||||
|
||||
|
||||
"""
|
||||
NSX-V3 Distributed Firewall
|
||||
"""
|
||||
from oslo_log import log
|
||||
|
||||
from vmware_nsx._i18n import _LW
|
||||
from vmware_nsx.common import utils
|
||||
from vmware_nsx.nsxlib.v3 import client as nsxclient
|
||||
from vmware_nsx.nsxlib.v3 import exceptions
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
# firewall section types
|
||||
LAYER3 = 'LAYER3'
|
||||
|
||||
INSERT_BEFORE = 'insert_before'
|
||||
INSERT_BOTTOM = 'insert_bottom'
|
||||
INSERT_TOP = 'insert_top'
|
||||
|
||||
# firewall rule actions
|
||||
ALLOW = 'ALLOW'
|
||||
DROP = 'DROP'
|
||||
REJECT = 'REJECT'
|
||||
|
||||
# filtering operators and expressions
|
||||
EQUALS = 'EQUALS'
|
||||
NSGROUP_SIMPLE_EXPRESSION = 'NSGroupSimpleExpression'
|
||||
NSGROUP_TAG_EXPRESSION = 'NSGroupTagExpression'
|
||||
|
||||
# nsgroup members update actions
|
||||
ADD_MEMBERS = 'ADD_MEMBERS'
|
||||
REMOVE_MEMBERS = 'REMOVE_MEMBERS'
|
||||
|
||||
NSGROUP = 'NSGroup'
|
||||
LOGICAL_SWITCH = 'LogicalSwitch'
|
||||
LOGICAL_PORT = 'LogicalPort'
|
||||
IPV4ADDRESS = 'IPv4Address'
|
||||
IPV6ADDRESS = 'IPv6Address'
|
||||
|
||||
IN = 'IN'
|
||||
OUT = 'OUT'
|
||||
IN_OUT = 'IN_OUT'
|
||||
|
||||
# NSServices resource types
|
||||
L4_PORT_SET_NSSERVICE = 'L4PortSetNSService'
|
||||
ICMP_TYPE_NSSERVICE = 'ICMPTypeNSService'
|
||||
IP_PROTOCOL_NSSERVICE = 'IPProtocolNSService'
|
||||
|
||||
TCP = 'TCP'
|
||||
UDP = 'UDP'
|
||||
ICMPV4 = 'ICMPv4'
|
||||
ICMPV6 = 'ICMPv6'
|
||||
|
||||
IPV4 = 'IPV4'
|
||||
IPV6 = 'IPV6'
|
||||
IPV4_IPV6 = 'IPV4_IPV6'
|
||||
|
||||
|
||||
class DfwApi(object):
|
||||
|
||||
def get_nsservice(self, resource_type, **properties):
|
||||
service = {'resource_type': resource_type}
|
||||
service.update(properties)
|
||||
return {'service': service}
|
||||
|
||||
def get_nsgroup_port_tag_expression(self, scope, tag):
|
||||
return {'resource_type': NSGROUP_TAG_EXPRESSION,
|
||||
'target_type': LOGICAL_PORT,
|
||||
'scope': scope,
|
||||
'tag': tag}
|
||||
|
||||
def create_nsgroup(self, display_name, description, tags,
|
||||
membership_criteria=None):
|
||||
body = {'display_name': display_name,
|
||||
'description': description,
|
||||
'tags': tags,
|
||||
'members': []}
|
||||
if membership_criteria:
|
||||
body.update({'membership_criteria': [membership_criteria]})
|
||||
return self.client.create('ns-groups', body)
|
||||
|
||||
def list_nsgroups(self):
|
||||
return self.client.get(
|
||||
'ns-groups?populate_references=false').get('results', [])
|
||||
|
||||
@utils.retry_upon_exception_nsxv3(exceptions.StaleRevision)
|
||||
def update_nsgroup(self, nsgroup_id, display_name=None, description=None,
|
||||
membership_criteria=None, members=None):
|
||||
nsgroup = self.read_nsgroup(nsgroup_id)
|
||||
if display_name is not None:
|
||||
nsgroup['display_name'] = display_name
|
||||
if description is not None:
|
||||
nsgroup['description'] = description
|
||||
if members is not None:
|
||||
nsgroup['members'] = members
|
||||
if membership_criteria is not None:
|
||||
nsgroup['membership_criteria'] = [membership_criteria]
|
||||
return self.client.update(
|
||||
'ns-groups/%s' % nsgroup_id, nsgroup)
|
||||
|
||||
def get_nsgroup_member_expression(self, target_type, target_id):
|
||||
return {'resource_type': NSGROUP_SIMPLE_EXPRESSION,
|
||||
'target_property': 'id',
|
||||
'target_type': target_type,
|
||||
'op': EQUALS,
|
||||
'value': target_id}
|
||||
|
||||
@utils.retry_upon_exception_nsxv3(exceptions.ManagerError)
|
||||
def _update_nsgroup_with_members(self, nsgroup_id, members, action):
|
||||
members_update = 'ns-groups/%s?action=%s' % (nsgroup_id, action)
|
||||
return self.client.create(members_update, members)
|
||||
|
||||
def add_nsgroup_members(self, nsgroup_id, target_type, target_ids):
|
||||
members = []
|
||||
for target_id in target_ids:
|
||||
member_expr = self.get_nsgroup_member_expression(
|
||||
target_type, target_id)
|
||||
members.append(member_expr)
|
||||
members = {'members': members}
|
||||
try:
|
||||
return self._update_nsgroup_with_members(
|
||||
nsgroup_id, members, ADD_MEMBERS)
|
||||
except (exceptions.StaleRevision, exceptions.ResourceNotFound):
|
||||
raise
|
||||
except exceptions.ManagerError:
|
||||
# REVISIT(roeyc): A ManagerError might have been raised for a
|
||||
# different reason, e.g - NSGroup does not exists.
|
||||
LOG.warning(_LW("Failed to add %(target_type)s resources "
|
||||
"(%(target_ids))s to NSGroup %(nsgroup_id)s"),
|
||||
{'target_type': target_type,
|
||||
'target_ids': target_ids,
|
||||
'nsgroup_id': nsgroup_id})
|
||||
|
||||
raise exceptions.NSGroupIsFull(nsgroup_id=nsgroup_id)
|
||||
|
||||
def remove_nsgroup_member(self, nsgroup_id, target_type,
|
||||
target_id, verify=False):
|
||||
member_expr = self.get_nsgroup_member_expression(
|
||||
target_type, target_id)
|
||||
members = {'members': [member_expr]}
|
||||
try:
|
||||
return self._update_nsgroup_with_members(
|
||||
nsgroup_id, members, REMOVE_MEMBERS)
|
||||
except exceptions.ManagerError:
|
||||
if verify:
|
||||
raise exceptions.NSGroupMemberNotFound(member_id=target_id,
|
||||
nsgroup_id=nsgroup_id)
|
||||
|
||||
def read_nsgroup(self, nsgroup_id):
|
||||
return self.client.get(
|
||||
'ns-groups/%s?populate_references=true' % nsgroup_id)
|
||||
|
||||
def delete_nsgroup(self, nsgroup_id):
|
||||
try:
|
||||
return self.client.delete(
|
||||
'ns-groups/%s?force=true' % nsgroup_id)
|
||||
# FIXME(roeyc): Should only except NotFound error.
|
||||
except Exception:
|
||||
LOG.debug("NSGroup %s does not exists for delete request.",
|
||||
nsgroup_id)
|
||||
|
||||
def _build_section(self, display_name, description, applied_tos, tags):
|
||||
return {'display_name': display_name,
|
||||
'description': description,
|
||||
'stateful': True,
|
||||
'section_type': LAYER3,
|
||||
'applied_tos': [self.get_nsgroup_reference(t_id)
|
||||
for t_id in applied_tos],
|
||||
'tags': tags}
|
||||
|
||||
def create_empty_section(self, display_name, description, applied_tos,
|
||||
tags, operation=INSERT_BOTTOM,
|
||||
other_section=None):
|
||||
resource = 'firewall/sections?operation=%s' % operation
|
||||
body = self._build_section(display_name, description,
|
||||
applied_tos, tags)
|
||||
if other_section:
|
||||
resource += '&id=%s' % other_section
|
||||
return self.client.create(resource, body)
|
||||
|
||||
@utils.retry_upon_exception_nsxv3(exceptions.StaleRevision)
|
||||
def update_section(self, section_id, display_name=None, description=None,
|
||||
applied_tos=None, rules=None):
|
||||
resource = 'firewall/sections/%s' % section_id
|
||||
section = self.read_section(section_id)
|
||||
|
||||
if rules is not None:
|
||||
resource += '?action=update_with_rules'
|
||||
section.update({'rules': rules})
|
||||
if display_name is not None:
|
||||
section['display_name'] = display_name
|
||||
if description is not None:
|
||||
section['description'] = description
|
||||
if applied_tos is not None:
|
||||
section['applied_tos'] = [self.get_nsgroup_reference(nsg_id)
|
||||
for nsg_id in applied_tos]
|
||||
if rules is not None:
|
||||
return nsxclient.create_resource(resource, section)
|
||||
elif any(p is not None for p in (display_name, description,
|
||||
applied_tos)):
|
||||
return self.client.update(resource, section)
|
||||
|
||||
def read_section(self, section_id):
|
||||
resource = 'firewall/sections/%s' % section_id
|
||||
return self.client.get(resource)
|
||||
|
||||
def list_sections(self):
|
||||
resource = 'firewall/sections'
|
||||
return self.client.get(resource).get('results', [])
|
||||
|
||||
def delete_section(self, section_id):
|
||||
resource = 'firewall/sections/%s?cascade=true' % section_id
|
||||
return self.client.delete(resource)
|
||||
|
||||
def get_nsgroup_reference(self, nsgroup_id):
|
||||
return {'target_id': nsgroup_id,
|
||||
'target_type': NSGROUP}
|
||||
|
||||
def get_ip_cidr_reference(self, ip_cidr_block, ip_protocol):
|
||||
target_type = IPV4ADDRESS if ip_protocol == IPV4 else IPV6ADDRESS
|
||||
return {'target_id': ip_cidr_block,
|
||||
'target_type': target_type}
|
||||
|
||||
def get_firewall_rule_dict(self, display_name, source=None,
|
||||
destination=None,
|
||||
direction=IN_OUT, ip_protocol=IPV4_IPV6,
|
||||
service=None, action=ALLOW, logged=False):
|
||||
return {'display_name': display_name,
|
||||
'sources': [source] if source else [],
|
||||
'destinations': [destination] if destination else [],
|
||||
'direction': direction,
|
||||
'ip_protocol': ip_protocol,
|
||||
'services': [service] if service else [],
|
||||
'action': action,
|
||||
'logged': logged}
|
||||
|
||||
def add_rule_in_section(self, rule, section_id):
|
||||
resource = 'firewall/sections/%s/rules' % section_id
|
||||
params = '?operation=insert_bottom'
|
||||
return self.client.create(resource + params, rule)
|
||||
|
||||
def add_rules_in_section(self, rules, section_id):
|
||||
resource = 'firewall/sections/%s/rules' % section_id
|
||||
params = '?action=create_multiple&operation=insert_bottom'
|
||||
return self.client.create(resource + params, {'rules': rules})
|
||||
|
||||
def delete_rule(self, section_id, rule_id):
|
||||
resource = 'firewall/sections/%s/rules/%s' % (section_id, rule_id)
|
||||
return self.client.delete(resource)
|
||||
|
||||
def get_section_rules(self, section_id):
|
||||
resource = 'firewall/sections/%s/rules' % section_id
|
||||
return self.client.get(resource)
|
@ -18,7 +18,7 @@ from neutron_lib.api import validators
|
||||
from neutron_lib import constants
|
||||
from oslo_config import cfg
|
||||
|
||||
from vmware_nsx.common import utils
|
||||
from vmware_nsx.nsxlib.v3 import utils
|
||||
|
||||
|
||||
def build_dhcp_server_config(network, subnet, port, project_name):
|
||||
|
@ -21,10 +21,10 @@ from oslo_config import cfg
|
||||
from oslo_log import log
|
||||
|
||||
from vmware_nsx._i18n import _, _LW
|
||||
from vmware_nsx.common import utils
|
||||
from vmware_nsx.nsxlib import v3
|
||||
from vmware_nsx.nsxlib.v3 import dfw_api as firewall
|
||||
from vmware_nsx.nsxlib.v3 import exceptions
|
||||
from vmware_nsx.nsxlib.v3 import nsx_constants as consts
|
||||
from vmware_nsx.nsxlib.v3 import utils as nsxlib_utils
|
||||
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
@ -40,7 +40,7 @@ class NSGroupManager(object):
|
||||
are also of type NSGroups) to group the other NSGroups and associate it
|
||||
with these rules.
|
||||
In practice, one NSGroup (nested) can't contain all the other NSGroups, as
|
||||
it has strict size limit. To overcome the limited space challange, we
|
||||
it has strict size limit. To overcome the limited space challenge, we
|
||||
create several nested groups instead of just one, and we evenly distribute
|
||||
NSGroups (security-groups) between them.
|
||||
By using an hashing function on the NSGroup uuid we determine in which
|
||||
@ -52,7 +52,7 @@ class NSGroupManager(object):
|
||||
NESTED_GROUP_DESCRIPTION = ('OpenStack NSGroup. Do not delete.')
|
||||
|
||||
def __init__(self, size):
|
||||
# XXX intergrate this in a better way..
|
||||
# TODO(asarfaty): integrate this in a better way..
|
||||
self.nsx = v3.NsxLib(
|
||||
username=cfg.CONF.nsx_v3.nsx_api_user,
|
||||
password=cfg.CONF.nsx_v3.nsx_api_password,
|
||||
@ -84,7 +84,7 @@ class NSGroupManager(object):
|
||||
nested_groups = {
|
||||
self._get_nested_group_index_from_name(nsgroup): nsgroup['id']
|
||||
for nsgroup in self.nsx.list_nsgroups()
|
||||
if utils.is_internal_resource(nsgroup)}
|
||||
if nsxlib_utils.is_internal_resource(nsgroup)}
|
||||
|
||||
if nested_groups:
|
||||
size = max(requested_size, max(nested_groups) + 1)
|
||||
@ -115,7 +115,7 @@ class NSGroupManager(object):
|
||||
name_prefix = NSGroupManager.NESTED_GROUP_NAME
|
||||
name = '%s %s' % (name_prefix, index + 1)
|
||||
description = NSGroupManager.NESTED_GROUP_DESCRIPTION
|
||||
tags = utils.build_v3_api_version_tag()
|
||||
tags = nsxlib_utils.build_v3_api_version_tag()
|
||||
return self.nsx.create_nsgroup(name, description, tags)
|
||||
|
||||
def _hash_uuid(self, internal_id):
|
||||
@ -138,7 +138,7 @@ class NSGroupManager(object):
|
||||
LOG.debug("Adding NSGroup %s to nested group %s",
|
||||
nsgroup_id, group)
|
||||
self.nsx.add_nsgroup_members(group,
|
||||
firewall.NSGROUP,
|
||||
consts.NSGROUP,
|
||||
[nsgroup_id])
|
||||
break
|
||||
except exceptions.NSGroupIsFull:
|
||||
@ -153,7 +153,8 @@ class NSGroupManager(object):
|
||||
for group in self._suggest_nested_group(nsgroup_id):
|
||||
try:
|
||||
self.nsx.remove_nsgroup_member(
|
||||
group, firewall.NSGROUP, nsgroup_id, verify=True)
|
||||
group, consts.NSGROUP,
|
||||
nsgroup_id, verify=True)
|
||||
break
|
||||
except exceptions.NSGroupMemberNotFound:
|
||||
LOG.warning(_LW("NSGroup %(nsgroup)s was expected to be found "
|
||||
|
96
vmware_nsx/nsxlib/v3/nsx_constants.py
Normal file
96
vmware_nsx/nsxlib/v3/nsx_constants.py
Normal file
@ -0,0 +1,96 @@
|
||||
# Copyright 2016 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.
|
||||
|
||||
# Admin statuses
|
||||
ADMIN_STATE_UP = "UP"
|
||||
ADMIN_STATE_DOWN = "DOWN"
|
||||
|
||||
# Replication modes
|
||||
MTEP = "MTEP"
|
||||
|
||||
# Port attachment types
|
||||
ATTACHMENT_VIF = "VIF"
|
||||
ATTACHMENT_CIF = "CIF"
|
||||
ATTACHMENT_LR = "LOGICALROUTER"
|
||||
ATTACHMENT_DHCP = "DHCP_SERVICE"
|
||||
ATTACHMENT_MDPROXY = "METADATA_PROXY"
|
||||
|
||||
CIF_RESOURCE_TYPE = "CifAttachmentContext"
|
||||
|
||||
# NSXv3 L2 Gateway constants
|
||||
BRIDGE_ENDPOINT = "BRIDGEENDPOINT"
|
||||
|
||||
# Router type
|
||||
ROUTER_TYPE_TIER0 = "TIER0"
|
||||
ROUTER_TYPE_TIER1 = "TIER1"
|
||||
|
||||
LROUTERPORT_UPLINK = "LogicalRouterUplinkPort"
|
||||
LROUTERPORT_DOWNLINK = "LogicalRouterDownLinkPort"
|
||||
LROUTERPORT_LINKONTIER0 = "LogicalRouterLinkPortOnTIER0"
|
||||
LROUTERPORT_LINKONTIER1 = "LogicalRouterLinkPortOnTIER1"
|
||||
|
||||
# NSX service type
|
||||
SERVICE_DHCP = "dhcp"
|
||||
|
||||
# NSX-V3 Distributed Firewall constants
|
||||
NSGROUP = 'NSGroup'
|
||||
NSGROUP_SIMPLE_EXP = 'NSGroupSimpleExpression'
|
||||
NSGROUP_TAG_EXP = 'NSGroupTagExpression'
|
||||
|
||||
# Firewall rule position
|
||||
FW_INSERT_BEFORE = 'insert_before'
|
||||
FW_INSERT_BOTTOM = 'insert_bottom'
|
||||
FW_INSERT_TOP = 'insert_top'
|
||||
|
||||
# firewall rule actions
|
||||
FW_ACTION_ALLOW = 'ALLOW'
|
||||
FW_ACTION_DROP = 'DROP'
|
||||
FW_ACTION_REJECT = 'REJECT'
|
||||
|
||||
# nsgroup members update actions
|
||||
NSGROUP_ADD_MEMBERS = 'ADD_MEMBERS'
|
||||
NSGROUP_REMOVE_MEMBERS = 'REMOVE_MEMBERS'
|
||||
|
||||
# NSServices resource types
|
||||
L4_PORT_SET_NSSERVICE = 'L4PortSetNSService'
|
||||
ICMP_TYPE_NSSERVICE = 'ICMPTypeNSService'
|
||||
IP_PROTOCOL_NSSERVICE = 'IPProtocolNSService'
|
||||
|
||||
# firewall section types
|
||||
FW_SECTION_LAYER3 = 'LAYER3'
|
||||
|
||||
TARGET_TYPE_LOGICAL_SWITCH = 'LogicalSwitch'
|
||||
TARGET_TYPE_LOGICAL_PORT = 'LogicalPort'
|
||||
TARGET_TYPE_IPV4ADDRESS = 'IPv4Address'
|
||||
TARGET_TYPE_IPV6ADDRESS = 'IPv6Address'
|
||||
|
||||
# filtering operators and expressions
|
||||
EQUALS = 'EQUALS'
|
||||
|
||||
IN = 'IN'
|
||||
OUT = 'OUT'
|
||||
IN_OUT = 'IN_OUT'
|
||||
|
||||
TCP = 'TCP'
|
||||
UDP = 'UDP'
|
||||
ICMPV4 = 'ICMPv4'
|
||||
ICMPV6 = 'ICMPv6'
|
||||
IPV4 = 'IPV4'
|
||||
IPV6 = 'IPV6'
|
||||
IPV4_IPV6 = 'IPV4_IPV6'
|
||||
|
||||
LOCAL_IP_PREFIX = 'local_ip_prefix'
|
||||
|
||||
LOGGING = 'logging'
|
@ -20,10 +20,10 @@ import six
|
||||
from oslo_config import cfg
|
||||
|
||||
from vmware_nsx._i18n import _
|
||||
from vmware_nsx.common import nsx_constants
|
||||
from vmware_nsx.common import utils
|
||||
from vmware_nsx.nsxlib.v3 import client
|
||||
from vmware_nsx.nsxlib.v3 import exceptions
|
||||
from vmware_nsx.nsxlib.v3 import nsx_constants
|
||||
from vmware_nsx.nsxlib.v3 import utils
|
||||
|
||||
|
||||
SwitchingProfileTypeId = collections.namedtuple(
|
||||
@ -285,13 +285,13 @@ class LogicalPort(AbstractRESTResource):
|
||||
attachment=attachment))
|
||||
return self._client.create(body=body)
|
||||
|
||||
@utils.retry_upon_exception_nsxv3(
|
||||
@utils.retry_upon_exception(
|
||||
exceptions.StaleRevision,
|
||||
max_attempts=cfg.CONF.nsx_v3.retries)
|
||||
def delete(self, lport_id):
|
||||
return self._client.url_delete('%s?detach=true' % lport_id)
|
||||
|
||||
@utils.retry_upon_exception_nsxv3(
|
||||
@utils.retry_upon_exception(
|
||||
exceptions.StaleRevision,
|
||||
max_attempts=cfg.CONF.nsx_v3.retries)
|
||||
def update(self, lport_id, vif_uuid,
|
||||
@ -342,7 +342,7 @@ class LogicalRouter(AbstractRESTResource):
|
||||
def delete(self, lrouter_id):
|
||||
return self._client.url_delete(lrouter_id)
|
||||
|
||||
@utils.retry_upon_exception_nsxv3(
|
||||
@utils.retry_upon_exception(
|
||||
exceptions.StaleRevision,
|
||||
max_attempts=cfg.CONF.nsx_v3.retries)
|
||||
def update(self, lrouter_id, *args, **kwargs):
|
||||
@ -389,7 +389,7 @@ class LogicalRouterPort(AbstractRESTResource):
|
||||
|
||||
return self._client.create(body=body)
|
||||
|
||||
@utils.retry_upon_exception_nsxv3(
|
||||
@utils.retry_upon_exception(
|
||||
exceptions.StaleRevision,
|
||||
max_attempts=cfg.CONF.nsx_v3.retries)
|
||||
def update(self, logical_port_id, **kwargs):
|
||||
@ -402,7 +402,7 @@ class LogicalRouterPort(AbstractRESTResource):
|
||||
# new revision_id
|
||||
return self._client.update(logical_port_id, body=logical_router_port)
|
||||
|
||||
@utils.retry_upon_exception_nsxv3(
|
||||
@utils.retry_upon_exception(
|
||||
exceptions.StaleRevision,
|
||||
max_attempts=cfg.CONF.nsx_v3.retries)
|
||||
def delete(self, logical_port_id):
|
||||
@ -511,7 +511,7 @@ class LogicalDhcpServer(AbstractRESTResource):
|
||||
options, tags)
|
||||
return self._client.create(body=body)
|
||||
|
||||
@utils.retry_upon_exception_nsxv3(
|
||||
@utils.retry_upon_exception(
|
||||
exceptions.StaleRevision,
|
||||
max_attempts=cfg.CONF.nsx_v3.retries)
|
||||
def update(self, uuid, dhcp_profile_id=None, server_ip=None, name=None,
|
||||
@ -539,7 +539,7 @@ class LogicalDhcpServer(AbstractRESTResource):
|
||||
url = "%s/static-bindings/%s" % (server_uuid, binding_uuid)
|
||||
return self._client.url_get(url)
|
||||
|
||||
@utils.retry_upon_exception_nsxv3(
|
||||
@utils.retry_upon_exception(
|
||||
exceptions.StaleRevision,
|
||||
max_attempts=cfg.CONF.nsx_v3.retries)
|
||||
def update_binding(self, server_uuid, binding_uuid, **kwargs):
|
||||
|
@ -22,9 +22,9 @@ from neutron_lib import exceptions as n_exc
|
||||
from oslo_log import log
|
||||
|
||||
from vmware_nsx._i18n import _, _LW
|
||||
from vmware_nsx.common import nsx_constants
|
||||
from vmware_nsx.common import utils
|
||||
from vmware_nsx.nsxlib.v3 import exceptions
|
||||
from vmware_nsx.nsxlib.v3 import nsx_constants
|
||||
from vmware_nsx.nsxlib.v3 import utils
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
@ -15,34 +15,27 @@
|
||||
# under the License.
|
||||
|
||||
"""
|
||||
NSX-V3 Plugin security integration module
|
||||
NSX-V3 Plugin security integration & Distributed Firewall module
|
||||
"""
|
||||
|
||||
from neutron_lib import constants
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log
|
||||
from oslo_utils import excutils
|
||||
|
||||
from vmware_nsx._i18n import _LE
|
||||
from vmware_nsx.common import utils
|
||||
from vmware_nsx.db import nsx_models
|
||||
from vmware_nsx.extensions import secgroup_rule_local_ip_prefix
|
||||
from vmware_nsx.extensions import securitygrouplogging as sg_logging
|
||||
from vmware_nsx.nsxlib.v3 import dfw_api as firewall
|
||||
from vmware_nsx._i18n import _LE, _LW
|
||||
from vmware_nsx.nsxlib.v3 import client as nsxclient
|
||||
from vmware_nsx.nsxlib.v3 import exceptions
|
||||
from vmware_nsx.nsxlib.v3 import nsx_constants as consts
|
||||
from vmware_nsx.nsxlib.v3 import utils
|
||||
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
DEFAULT_SECTION = 'OS Default Section for Neutron Security-Groups'
|
||||
DEFAULT_SECTION_TAG_NAME = 'neutron_default_dfw_section'
|
||||
PORT_SG_SCOPE = 'os-security-group'
|
||||
|
||||
MAX_NSGROUPS_CRITERIA_TAGS = 10
|
||||
|
||||
|
||||
# XXX this method should be refactored to pull the common stuff out to
|
||||
# a security_group utils file.
|
||||
class Security(object):
|
||||
|
||||
def _get_l4_protocol_name(self, protocol_number):
|
||||
@ -52,24 +45,26 @@ class Security(object):
|
||||
protocol_number)
|
||||
protocol_number = int(protocol_number)
|
||||
if protocol_number == 6:
|
||||
return firewall.TCP
|
||||
return consts.TCP
|
||||
elif protocol_number == 17:
|
||||
return firewall.UDP
|
||||
return consts.UDP
|
||||
elif protocol_number == 1:
|
||||
return firewall.ICMPV4
|
||||
return consts.ICMPV4
|
||||
else:
|
||||
return protocol_number
|
||||
|
||||
def _get_direction(self, sg_rule):
|
||||
return (
|
||||
firewall.IN if sg_rule['direction'] == 'ingress' else firewall.OUT
|
||||
consts.IN if sg_rule['direction'] == 'ingress'
|
||||
else consts.OUT
|
||||
)
|
||||
|
||||
def _decide_service(self, sg_rule):
|
||||
l4_protocol = self._get_l4_protocol_name(sg_rule['protocol'])
|
||||
direction = self._get_direction(sg_rule)
|
||||
|
||||
if l4_protocol in [firewall.TCP, firewall.UDP]:
|
||||
if l4_protocol in [consts.TCP,
|
||||
consts.UDP]:
|
||||
# If port_range_min is not specified then we assume all ports are
|
||||
# matched, relying on neutron to perform validation.
|
||||
source_ports = []
|
||||
@ -82,21 +77,24 @@ class Security(object):
|
||||
else:
|
||||
destination_ports = ['%(port_range_min)s' % sg_rule]
|
||||
|
||||
if direction == firewall.OUT:
|
||||
if direction == consts.OUT:
|
||||
source_ports, destination_ports = destination_ports, []
|
||||
|
||||
return self.get_nsservice(firewall.L4_PORT_SET_NSSERVICE,
|
||||
l4_protocol=l4_protocol,
|
||||
source_ports=source_ports,
|
||||
destination_ports=destination_ports)
|
||||
elif l4_protocol == firewall.ICMPV4:
|
||||
return self.get_nsservice(firewall.ICMP_TYPE_NSSERVICE,
|
||||
protocol=l4_protocol,
|
||||
icmp_type=sg_rule['port_range_min'],
|
||||
icmp_code=sg_rule['port_range_max'])
|
||||
return self.get_nsservice(
|
||||
consts.L4_PORT_SET_NSSERVICE,
|
||||
l4_protocol=l4_protocol,
|
||||
source_ports=source_ports,
|
||||
destination_ports=destination_ports)
|
||||
elif l4_protocol == consts.ICMPV4:
|
||||
return self.get_nsservice(
|
||||
consts.ICMP_TYPE_NSSERVICE,
|
||||
protocol=l4_protocol,
|
||||
icmp_type=sg_rule['port_range_min'],
|
||||
icmp_code=sg_rule['port_range_max'])
|
||||
elif l4_protocol is not None:
|
||||
return self.get_nsservice(firewall.IP_PROTOCOL_NSSERVICE,
|
||||
protocol_number=l4_protocol)
|
||||
return self.get_nsservice(
|
||||
consts.IP_PROTOCOL_NSSERVICE,
|
||||
protocol_number=l4_protocol)
|
||||
|
||||
def _get_fw_rule_from_sg_rule(self, sg_rule, nsgroup_id, rmt_nsgroup_id,
|
||||
logged, action):
|
||||
@ -104,9 +102,9 @@ class Security(object):
|
||||
ip_protocol = sg_rule['ethertype'].upper()
|
||||
direction = self._get_direction(sg_rule)
|
||||
|
||||
if sg_rule.get(secgroup_rule_local_ip_prefix.LOCAL_IP_PREFIX):
|
||||
if sg_rule.get(consts.LOCAL_IP_PREFIX):
|
||||
local_ip_prefix = self.get_ip_cidr_reference(
|
||||
sg_rule[secgroup_rule_local_ip_prefix.LOCAL_IP_PREFIX],
|
||||
sg_rule[consts.LOCAL_IP_PREFIX],
|
||||
ip_protocol)
|
||||
else:
|
||||
local_ip_prefix = None
|
||||
@ -121,7 +119,7 @@ class Security(object):
|
||||
if rmt_nsgroup_id:
|
||||
source = self.get_nsgroup_reference(rmt_nsgroup_id)
|
||||
destination = local_ip_prefix or local_group
|
||||
if direction == firewall.OUT:
|
||||
if direction == consts.OUT:
|
||||
source, destination = destination, source
|
||||
|
||||
service = self._decide_service(sg_rule)
|
||||
@ -133,17 +131,15 @@ class Security(object):
|
||||
action, logged)
|
||||
|
||||
def create_firewall_rules(self, context, section_id, nsgroup_id,
|
||||
logging_enabled, action, security_group_rules):
|
||||
logging_enabled, action, security_group_rules,
|
||||
ruleid_2_remote_nsgroup_map):
|
||||
|
||||
# 1. translate rules
|
||||
# 2. insert in section
|
||||
# 3. save mappings
|
||||
|
||||
# 3. return the rules
|
||||
firewall_rules = []
|
||||
for sg_rule in security_group_rules:
|
||||
remote_nsgroup_id = self._get_remote_nsg_mapping(
|
||||
context, sg_rule, nsgroup_id)
|
||||
|
||||
remote_nsgroup_id = ruleid_2_remote_nsgroup_map[sg_rule['id']]
|
||||
fw_rule = self._get_fw_rule_from_sg_rule(
|
||||
sg_rule, nsgroup_id, remote_nsgroup_id,
|
||||
logging_enabled, action)
|
||||
@ -167,13 +163,13 @@ class Security(object):
|
||||
section_id, logging)
|
||||
self.update_section(section_id, rules=rules)
|
||||
|
||||
def update_security_group_on_backend(self, context, security_group):
|
||||
nsgroup_id, section_id = self.get_sg_mappings(context.session,
|
||||
security_group['id'])
|
||||
def update_security_group_on_backend(self, context, security_group,
|
||||
nsgroup_id, section_id,
|
||||
log_sg_allowed_traffic):
|
||||
name = self.get_nsgroup_name(security_group)
|
||||
description = security_group['description']
|
||||
logging = (cfg.CONF.nsx_v3.log_security_groups_allowed_traffic or
|
||||
security_group[sg_logging.LOGGING])
|
||||
logging = (log_sg_allowed_traffic or
|
||||
security_group[consts.LOGGING])
|
||||
rules = self._process_firewall_section_rules_logging_for_update(
|
||||
section_id, logging)
|
||||
self.update_nsgroup(nsgroup_id, name, description)
|
||||
@ -184,38 +180,6 @@ class Security(object):
|
||||
# for usability purposes.
|
||||
return '%(name)s - %(id)s' % security_group
|
||||
|
||||
# XXX remove db calls from nsxlib
|
||||
def save_sg_rule_mappings(self, session, firewall_rules):
|
||||
# REVISIT(roeyc): This method should take care db access only.
|
||||
rules = [(rule['display_name'], rule['id']) for rule in firewall_rules]
|
||||
with session.begin(subtransactions=True):
|
||||
for neutron_id, nsx_id in rules:
|
||||
mapping = nsx_models.NeutronNsxRuleMapping(
|
||||
neutron_id=neutron_id, nsx_id=nsx_id)
|
||||
session.add(mapping)
|
||||
return mapping
|
||||
|
||||
# XXX db calls should not be here...
|
||||
def get_sg_mappings(self, session, sg_id):
|
||||
nsgroup_mapping = session.query(
|
||||
nsx_models.NeutronNsxSecurityGroupMapping
|
||||
).filter_by(neutron_id=sg_id).one()
|
||||
section_mapping = session.query(
|
||||
nsx_models.NeutronNsxFirewallSectionMapping
|
||||
).filter_by(neutron_id=sg_id).one()
|
||||
return nsgroup_mapping.nsx_id, section_mapping.nsx_id
|
||||
|
||||
def _get_remote_nsg_mapping(self, context, sg_rule, nsgroup_id):
|
||||
remote_nsgroup_id = None
|
||||
remote_group_id = sg_rule.get('remote_group_id')
|
||||
# skip unnecessary db access when possible
|
||||
if remote_group_id == sg_rule['security_group_id']:
|
||||
remote_nsgroup_id = nsgroup_id
|
||||
elif remote_group_id:
|
||||
remote_nsgroup_id, s = self.get_sg_mappings(context.session,
|
||||
remote_group_id)
|
||||
return remote_nsgroup_id
|
||||
|
||||
def get_lport_tags_for_security_groups(self, secgroups):
|
||||
if len(secgroups) > MAX_NSGROUPS_CRITERIA_TAGS:
|
||||
raise exceptions.NumberOfNsgroupCriteriaTagsReached(
|
||||
@ -232,30 +196,29 @@ class Security(object):
|
||||
original, updated):
|
||||
added = set(updated) - set(original)
|
||||
removed = set(original) - set(updated)
|
||||
for sg_id in added:
|
||||
nsgroup_id, s = self.get_sg_mappings(context.session, sg_id)
|
||||
for nsgroup_id in added:
|
||||
try:
|
||||
self.add_nsgroup_members(
|
||||
nsgroup_id, firewall.LOGICAL_PORT, [lport_id])
|
||||
nsgroup_id, consts.TARGET_TYPE_LOGICAL_PORT,
|
||||
[lport_id])
|
||||
except exceptions.NSGroupIsFull:
|
||||
for sg_id in added:
|
||||
nsgroup_id, s = self.get_sg_mappings(
|
||||
context.session, sg_id)
|
||||
for nsgroup_id in added:
|
||||
# NOTE(roeyc): If the port was not added to the nsgroup
|
||||
# yet, then this request will silently fail.
|
||||
self.remove_nsgroup_member(
|
||||
nsgroup_id, firewall.LOGICAL_PORT, lport_id)
|
||||
nsgroup_id, consts.TARGET_TYPE_LOGICAL_PORT,
|
||||
lport_id)
|
||||
raise exceptions.SecurityGroupMaximumCapacityReached(
|
||||
sg_id=sg_id)
|
||||
sg_id=nsgroup_id)
|
||||
except exceptions.ResourceNotFound:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error(_LE("NSGroup %s doesn't exists"), nsgroup_id)
|
||||
for sg_id in removed:
|
||||
nsgroup_id, s = self.get_sg_mappings(context.session, sg_id)
|
||||
for nsgroup_id in removed:
|
||||
self.remove_nsgroup_member(
|
||||
nsgroup_id, firewall.LOGICAL_PORT, lport_id)
|
||||
nsgroup_id, consts.TARGET_TYPE_LOGICAL_PORT, lport_id)
|
||||
|
||||
def _init_default_section(self, name, description, nested_groups):
|
||||
def init_default_section(self, name, description, nested_groups,
|
||||
log_sg_blocked_traffic):
|
||||
fw_sections = self.list_sections()
|
||||
for section in fw_sections:
|
||||
if section['display_name'] == name:
|
||||
@ -266,23 +229,28 @@ class Security(object):
|
||||
name, description, nested_groups, tags)
|
||||
|
||||
block_rule = self.get_firewall_rule_dict(
|
||||
'Block All', action=firewall.DROP,
|
||||
logged=cfg.CONF.nsx_v3.log_security_groups_blocked_traffic)
|
||||
'Block All', action=consts.FW_ACTION_DROP,
|
||||
logged=log_sg_blocked_traffic)
|
||||
# TODO(roeyc): Add additional rules to allow IPV6 NDP.
|
||||
dhcp_client = self.get_nsservice(firewall.L4_PORT_SET_NSSERVICE,
|
||||
l4_protocol=firewall.UDP,
|
||||
source_ports=[67],
|
||||
destination_ports=[68])
|
||||
dhcp_client = self.get_nsservice(
|
||||
consts.L4_PORT_SET_NSSERVICE,
|
||||
l4_protocol=consts.UDP,
|
||||
source_ports=[67],
|
||||
destination_ports=[68])
|
||||
dhcp_client_rule_in = self.get_firewall_rule_dict(
|
||||
'DHCP Reply', direction=firewall.IN, service=dhcp_client)
|
||||
'DHCP Reply',
|
||||
direction=consts.IN,
|
||||
service=dhcp_client)
|
||||
|
||||
dhcp_server = (
|
||||
self.get_nsservice(firewall.L4_PORT_SET_NSSERVICE,
|
||||
l4_protocol=firewall.UDP,
|
||||
self.get_nsservice(consts.L4_PORT_SET_NSSERVICE,
|
||||
l4_protocol=consts.UDP,
|
||||
source_ports=[68],
|
||||
destination_ports=[67]))
|
||||
dhcp_client_rule_out = self.get_firewall_rule_dict(
|
||||
'DHCP Request', direction=firewall.OUT, service=dhcp_server)
|
||||
'DHCP Request',
|
||||
direction=consts.OUT,
|
||||
service=dhcp_server)
|
||||
|
||||
self.update_section(section['id'],
|
||||
name, section['description'],
|
||||
@ -291,3 +259,205 @@ class Security(object):
|
||||
dhcp_client_rule_in,
|
||||
block_rule])
|
||||
return section['id']
|
||||
|
||||
def get_nsservice(self, resource_type, **properties):
|
||||
service = {'resource_type': resource_type}
|
||||
service.update(properties)
|
||||
return {'service': service}
|
||||
|
||||
def get_nsgroup_port_tag_expression(self, scope, tag):
|
||||
return {
|
||||
'resource_type': consts.NSGROUP_TAG_EXP,
|
||||
'target_type': consts.TARGET_TYPE_LOGICAL_PORT,
|
||||
'scope': scope,
|
||||
'tag': tag}
|
||||
|
||||
def create_nsgroup(self, display_name, description, tags,
|
||||
membership_criteria=None):
|
||||
body = {'display_name': display_name,
|
||||
'description': description,
|
||||
'tags': tags,
|
||||
'members': []}
|
||||
if membership_criteria:
|
||||
body.update({'membership_criteria': [membership_criteria]})
|
||||
return self.client.create('ns-groups', body)
|
||||
|
||||
def list_nsgroups(self):
|
||||
return self.client.get(
|
||||
'ns-groups?populate_references=false').get('results', [])
|
||||
|
||||
@utils.retry_upon_exception(exceptions.StaleRevision)
|
||||
def update_nsgroup(self, nsgroup_id, display_name=None, description=None,
|
||||
membership_criteria=None, members=None):
|
||||
nsgroup = self.read_nsgroup(nsgroup_id)
|
||||
if display_name is not None:
|
||||
nsgroup['display_name'] = display_name
|
||||
if description is not None:
|
||||
nsgroup['description'] = description
|
||||
if members is not None:
|
||||
nsgroup['members'] = members
|
||||
if membership_criteria is not None:
|
||||
nsgroup['membership_criteria'] = [membership_criteria]
|
||||
return self.client.update(
|
||||
'ns-groups/%s' % nsgroup_id, nsgroup)
|
||||
|
||||
def get_nsgroup_member_expression(self, target_type, target_id):
|
||||
return {
|
||||
'resource_type': consts.NSGROUP_SIMPLE_EXP,
|
||||
'target_property': 'id',
|
||||
'target_type': target_type,
|
||||
'op': consts.EQUALS,
|
||||
'value': target_id}
|
||||
|
||||
@utils.retry_upon_exception(exceptions.ManagerError)
|
||||
def _update_nsgroup_with_members(self, nsgroup_id, members, action):
|
||||
members_update = 'ns-groups/%s?action=%s' % (nsgroup_id, action)
|
||||
return self.client.create(members_update, members)
|
||||
|
||||
def add_nsgroup_members(self, nsgroup_id, target_type, target_ids):
|
||||
members = []
|
||||
for target_id in target_ids:
|
||||
member_expr = self.get_nsgroup_member_expression(
|
||||
target_type, target_id)
|
||||
members.append(member_expr)
|
||||
members = {'members': members}
|
||||
try:
|
||||
return self._update_nsgroup_with_members(
|
||||
nsgroup_id, members, consts.NSGROUP_ADD_MEMBERS)
|
||||
except (exceptions.StaleRevision, exceptions.ResourceNotFound):
|
||||
raise
|
||||
except exceptions.ManagerError:
|
||||
# REVISIT(roeyc): A ManagerError might have been raised for a
|
||||
# different reason, e.g - NSGroup does not exists.
|
||||
LOG.warning(_LW("Failed to add %(target_type)s resources "
|
||||
"(%(target_ids))s to NSGroup %(nsgroup_id)s"),
|
||||
{'target_type': target_type,
|
||||
'target_ids': target_ids,
|
||||
'nsgroup_id': nsgroup_id})
|
||||
|
||||
raise exceptions.NSGroupIsFull(nsgroup_id=nsgroup_id)
|
||||
|
||||
def remove_nsgroup_member(self, nsgroup_id, target_type,
|
||||
target_id, verify=False):
|
||||
member_expr = self.get_nsgroup_member_expression(
|
||||
target_type, target_id)
|
||||
members = {'members': [member_expr]}
|
||||
try:
|
||||
return self._update_nsgroup_with_members(
|
||||
nsgroup_id, members, consts.NSGROUP_REMOVE_MEMBERS)
|
||||
except exceptions.ManagerError:
|
||||
if verify:
|
||||
raise exceptions.NSGroupMemberNotFound(member_id=target_id,
|
||||
nsgroup_id=nsgroup_id)
|
||||
|
||||
def read_nsgroup(self, nsgroup_id):
|
||||
return self.client.get(
|
||||
'ns-groups/%s?populate_references=true' % nsgroup_id)
|
||||
|
||||
def delete_nsgroup(self, nsgroup_id):
|
||||
try:
|
||||
return self.client.delete(
|
||||
'ns-groups/%s?force=true' % nsgroup_id)
|
||||
# FIXME(roeyc): Should only except NotFound error.
|
||||
except Exception:
|
||||
LOG.debug("NSGroup %s does not exists for delete request.",
|
||||
nsgroup_id)
|
||||
|
||||
def _build_section(self, display_name, description, applied_tos, tags):
|
||||
return {'display_name': display_name,
|
||||
'description': description,
|
||||
'stateful': True,
|
||||
'section_type': consts.FW_SECTION_LAYER3,
|
||||
'applied_tos': [self.get_nsgroup_reference(t_id)
|
||||
for t_id in applied_tos],
|
||||
'tags': tags}
|
||||
|
||||
def create_empty_section(self, display_name, description,
|
||||
applied_tos, tags,
|
||||
operation=consts.FW_INSERT_BOTTOM,
|
||||
other_section=None):
|
||||
resource = 'firewall/sections?operation=%s' % operation
|
||||
body = self._build_section(display_name, description,
|
||||
applied_tos, tags)
|
||||
if other_section:
|
||||
resource += '&id=%s' % other_section
|
||||
return self.client.create(resource, body)
|
||||
|
||||
@utils.retry_upon_exception(exceptions.StaleRevision)
|
||||
def update_section(self, section_id, display_name=None, description=None,
|
||||
applied_tos=None, rules=None):
|
||||
resource = 'firewall/sections/%s' % section_id
|
||||
section = self.read_section(section_id)
|
||||
|
||||
if rules is not None:
|
||||
resource += '?action=update_with_rules'
|
||||
section.update({'rules': rules})
|
||||
if display_name is not None:
|
||||
section['display_name'] = display_name
|
||||
if description is not None:
|
||||
section['description'] = description
|
||||
if applied_tos is not None:
|
||||
section['applied_tos'] = [self.get_nsgroup_reference(nsg_id)
|
||||
for nsg_id in applied_tos]
|
||||
if rules is not None:
|
||||
return nsxclient.create_resource(resource, section)
|
||||
elif any(p is not None for p in (display_name, description,
|
||||
applied_tos)):
|
||||
return self.client.update(resource, section)
|
||||
|
||||
def read_section(self, section_id):
|
||||
resource = 'firewall/sections/%s' % section_id
|
||||
return self.client.get(resource)
|
||||
|
||||
def list_sections(self):
|
||||
resource = 'firewall/sections'
|
||||
return self.client.get(resource).get('results', [])
|
||||
|
||||
def delete_section(self, section_id):
|
||||
resource = 'firewall/sections/%s?cascade=true' % section_id
|
||||
return self.client.delete(resource)
|
||||
|
||||
def get_nsgroup_reference(self, nsgroup_id):
|
||||
return {'target_id': nsgroup_id,
|
||||
'target_type': consts.NSGROUP}
|
||||
|
||||
def get_ip_cidr_reference(self, ip_cidr_block, ip_protocol):
|
||||
target_type = (consts.TARGET_TYPE_IPV4ADDRESS
|
||||
if ip_protocol == consts.IPV4
|
||||
else consts.TARGET_TYPE_IPV6ADDRESS)
|
||||
return {'target_id': ip_cidr_block,
|
||||
'target_type': target_type}
|
||||
|
||||
def get_firewall_rule_dict(
|
||||
self, display_name, source=None,
|
||||
destination=None,
|
||||
direction=consts.IN_OUT,
|
||||
ip_protocol=consts.IPV4_IPV6,
|
||||
service=None, action=consts.FW_ACTION_ALLOW,
|
||||
logged=False):
|
||||
return {'display_name': display_name,
|
||||
'sources': [source] if source else [],
|
||||
'destinations': [destination] if destination else [],
|
||||
'direction': direction,
|
||||
'ip_protocol': ip_protocol,
|
||||
'services': [service] if service else [],
|
||||
'action': action,
|
||||
'logged': logged}
|
||||
|
||||
def add_rule_in_section(self, rule, section_id):
|
||||
resource = 'firewall/sections/%s/rules' % section_id
|
||||
params = '?operation=insert_bottom'
|
||||
return self.client.create(resource + params, rule)
|
||||
|
||||
def add_rules_in_section(self, rules, section_id):
|
||||
resource = 'firewall/sections/%s/rules' % section_id
|
||||
params = '?action=create_multiple&operation=insert_bottom'
|
||||
return self.client.create(resource + params, {'rules': rules})
|
||||
|
||||
def delete_rule(self, section_id, rule_id):
|
||||
resource = 'firewall/sections/%s/rules/%s' % (section_id, rule_id)
|
||||
return self.client.delete(resource)
|
||||
|
||||
def get_section_rules(self, section_id):
|
||||
resource = 'firewall/sections/%s/rules' % section_id
|
||||
return self.client.get(resource)
|
||||
|
171
vmware_nsx/nsxlib/v3/utils.py
Normal file
171
vmware_nsx/nsxlib/v3/utils.py
Normal file
@ -0,0 +1,171 @@
|
||||
# Copyright 2016 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.
|
||||
|
||||
import retrying
|
||||
|
||||
from neutron import version as n_version
|
||||
from neutron_lib import exceptions
|
||||
from oslo_log import log
|
||||
|
||||
from vmware_nsx._i18n import _
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
MAX_RESOURCE_TYPE_LEN = 20
|
||||
MAX_TAG_LEN = 40
|
||||
NSX_NEUTRON_PLUGIN = 'NSX Neutron plugin'
|
||||
OS_NEUTRON_ID_SCOPE = 'os-neutron-id'
|
||||
|
||||
|
||||
def is_internal_resource(nsx_resource):
|
||||
"""
|
||||
Indicates whether the passed nsx-resource is owned by the plugin for
|
||||
internal use.
|
||||
"""
|
||||
for tag in nsx_resource.get('tags', []):
|
||||
if tag['scope'] == OS_NEUTRON_ID_SCOPE:
|
||||
return tag['tag'] == NSX_NEUTRON_PLUGIN
|
||||
return False
|
||||
|
||||
|
||||
def build_v3_api_version_tag():
|
||||
"""
|
||||
Some resources are created on the manager that do not have a corresponding
|
||||
Neutron resource.
|
||||
"""
|
||||
return [{'scope': OS_NEUTRON_ID_SCOPE,
|
||||
'tag': NSX_NEUTRON_PLUGIN},
|
||||
{'scope': "os-api-version",
|
||||
'tag': n_version.version_info.release_string()}]
|
||||
|
||||
|
||||
def _validate_resource_type_length(resource_type):
|
||||
# Add in a validation to ensure that we catch this at build time
|
||||
if len(resource_type) > MAX_RESOURCE_TYPE_LEN:
|
||||
raise exceptions.InvalidInput(
|
||||
error_message=(_('Resource type cannot exceed %(max_len)s '
|
||||
'characters: %(resource_type)s') %
|
||||
{'max_len': MAX_RESOURCE_TYPE_LEN,
|
||||
'resource_type': resource_type}))
|
||||
|
||||
|
||||
def build_v3_tags_payload(resource, resource_type, project_name):
|
||||
"""
|
||||
Construct the tags payload that will be pushed to NSX-v3
|
||||
Add <resource_type>:<resource-id>, os-project-id:<tenant-id>,
|
||||
os-project-name:<project_name> os-api-version:<neutron-api-version>
|
||||
"""
|
||||
_validate_resource_type_length(resource_type)
|
||||
# There may be cases when the plugin creates the port, for example DHCP
|
||||
if not project_name:
|
||||
project_name = NSX_NEUTRON_PLUGIN
|
||||
tenant_id = resource.get('tenant_id', '')
|
||||
# If tenant_id is present in resource and set to None, explicitly set
|
||||
# the tenant_id in tags as ''.
|
||||
if tenant_id is None:
|
||||
tenant_id = ''
|
||||
return [{'scope': resource_type,
|
||||
'tag': resource.get('id', '')[:MAX_TAG_LEN]},
|
||||
{'scope': 'os-project-id',
|
||||
'tag': tenant_id[:MAX_TAG_LEN]},
|
||||
{'scope': 'os-project-name',
|
||||
'tag': project_name[:MAX_TAG_LEN]},
|
||||
{'scope': 'os-api-version',
|
||||
'tag': n_version.version_info.release_string()[:MAX_TAG_LEN]}]
|
||||
|
||||
|
||||
def add_v3_tag(tags, resource_type, tag):
|
||||
_validate_resource_type_length(resource_type)
|
||||
tags.append({'scope': resource_type, 'tag': tag[:MAX_TAG_LEN]})
|
||||
return tags
|
||||
|
||||
|
||||
def update_v3_tags(current_tags, tags_update):
|
||||
current_scopes = set([tag['scope'] for tag in current_tags])
|
||||
updated_scopes = set([tag['scope'] for tag in tags_update])
|
||||
|
||||
tags = [{'scope': tag['scope'], 'tag': tag['tag']}
|
||||
for tag in (current_tags + tags_update)
|
||||
if tag['scope'] in (current_scopes ^ updated_scopes)]
|
||||
|
||||
modified_scopes = current_scopes & updated_scopes
|
||||
for tag in tags_update:
|
||||
if tag['scope'] in modified_scopes:
|
||||
# If the tag value is empty or None, then remove the tag completely
|
||||
if tag['tag']:
|
||||
tag['tag'] = tag['tag'][:MAX_TAG_LEN]
|
||||
tags.append(tag)
|
||||
|
||||
return tags
|
||||
|
||||
|
||||
#Todo(asarfaty): figure out a way to use an NsxLib class variable in the
|
||||
#retry decorator instead of the configuration/constant one
|
||||
def retry_upon_exception(exc, delay=500, max_delay=2000, max_attempts=10):
|
||||
return retrying.retry(retry_on_exception=lambda e: isinstance(e, exc),
|
||||
wait_exponential_multiplier=delay,
|
||||
wait_exponential_max=max_delay,
|
||||
stop_max_attempt_number=max_attempts)
|
||||
|
||||
|
||||
def list_match(list1, list2):
|
||||
# Check if list1 and list2 have identical elements, but relaxed on
|
||||
# dict elements where list1's dict element can be a subset of list2's
|
||||
# corresponding element.
|
||||
if (not isinstance(list1, list) or
|
||||
not isinstance(list2, list) or
|
||||
len(list1) != len(list2)):
|
||||
return False
|
||||
list1 = sorted(list1)
|
||||
list2 = sorted(list2)
|
||||
for (v1, v2) in zip(list1, list2):
|
||||
if isinstance(v1, dict):
|
||||
if not dict_match(v1, v2):
|
||||
return False
|
||||
elif isinstance(v1, list):
|
||||
if not list_match(v1, v2):
|
||||
return False
|
||||
elif v1 != v2:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def dict_match(dict1, dict2):
|
||||
# Check if dict1 is a subset of dict2.
|
||||
if not isinstance(dict1, dict) or not isinstance(dict2, dict):
|
||||
return False
|
||||
for k1, v1 in dict1.items():
|
||||
if k1 not in dict2:
|
||||
return False
|
||||
v2 = dict2[k1]
|
||||
if isinstance(v1, dict):
|
||||
if not dict_match(v1, v2):
|
||||
return False
|
||||
elif isinstance(v1, list):
|
||||
if not list_match(v1, v2):
|
||||
return False
|
||||
elif v1 != v2:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def get_name_and_uuid(name, uuid, tag=None, maxlen=80):
|
||||
short_uuid = '_' + uuid[:5] + '...' + uuid[-5:]
|
||||
maxlen = maxlen - len(short_uuid)
|
||||
if tag:
|
||||
maxlen = maxlen - len(tag) - 1
|
||||
return name[:maxlen] + '_' + tag + short_uuid
|
||||
else:
|
||||
return name[:maxlen] + short_uuid
|
@ -73,7 +73,6 @@ from vmware_nsx.api_replay import utils as api_replay_utils
|
||||
from vmware_nsx.common import config # noqa
|
||||
from vmware_nsx.common import exceptions as nsx_exc
|
||||
from vmware_nsx.common import locking
|
||||
from vmware_nsx.common import nsx_constants
|
||||
from vmware_nsx.common import utils
|
||||
from vmware_nsx.db import db as nsx_db
|
||||
from vmware_nsx.db import extended_security_group
|
||||
@ -85,13 +84,14 @@ from vmware_nsx.extensions import maclearning as mac_ext
|
||||
from vmware_nsx.extensions import providersecuritygroup as provider_sg
|
||||
from vmware_nsx.extensions import securitygrouplogging as sg_logging
|
||||
from vmware_nsx.nsxlib import v3 as nsxlib
|
||||
from vmware_nsx.nsxlib.v3 import dfw_api as firewall
|
||||
from vmware_nsx.nsxlib.v3 import exceptions as nsx_lib_exc
|
||||
from vmware_nsx.nsxlib.v3 import native_dhcp
|
||||
from vmware_nsx.nsxlib.v3 import ns_group_manager
|
||||
from vmware_nsx.nsxlib.v3 import nsx_constants as nsxlib_consts
|
||||
from vmware_nsx.nsxlib.v3 import resources as nsx_resources
|
||||
from vmware_nsx.nsxlib.v3 import router
|
||||
from vmware_nsx.nsxlib.v3 import security
|
||||
from vmware_nsx.nsxlib.v3 import utils as nsxlib_utils
|
||||
from vmware_nsx.services.qos.common import utils as qos_com_utils
|
||||
from vmware_nsx.services.qos.nsx_v3 import utils as qos_utils
|
||||
from vmware_nsx.services.trunk.nsx_v3 import driver as trunk_driver
|
||||
@ -221,7 +221,8 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
|
||||
def _init_nsx_profiles(self):
|
||||
LOG.debug("Initializing NSX v3 port spoofguard switching profile")
|
||||
# XXX improve logic to avoid requiring setting this to none.
|
||||
# TODO(asarfaty): improve logic to avoid requiring setting
|
||||
# this to none.
|
||||
self._psec_profile = None
|
||||
self._psec_profile = self._init_port_security_profile()
|
||||
if not self._psec_profile:
|
||||
@ -236,7 +237,8 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
|
||||
LOG.debug("Initializing NSX v3 DHCP switching profile")
|
||||
try:
|
||||
# XXX improve logic to avoid requiring setting this to none.
|
||||
# TODO(asarfaty): improve logic to avoid requiring setting
|
||||
# this to none.
|
||||
self._dhcp_profile = None
|
||||
self._dhcp_profile = self._init_dhcp_switching_profile()
|
||||
except Exception:
|
||||
@ -247,7 +249,8 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
if utils.is_nsx_version_1_1_0(self._nsx_version):
|
||||
LOG.debug("Initializing NSX v3 Mac Learning switching profile")
|
||||
try:
|
||||
# XXX improve logic to avoid requiring setting this to none.
|
||||
# TODO(asarfaty): improve logic to avoid requiring setting
|
||||
# this to none.
|
||||
self._mac_learning_profile = None
|
||||
self._mac_learning_profile = self._init_mac_learning_profile()
|
||||
# Only expose the extension if it is supported
|
||||
@ -318,14 +321,15 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
"must be disabled") % dhcp_profile_uuid
|
||||
raise n_exc.InvalidInput(error_message=msg)
|
||||
|
||||
@utils.retry_upon_exception_nsxv3(Exception)
|
||||
@nsxlib_utils.retry_upon_exception(
|
||||
Exception, max_attempts=cfg.CONF.nsx_v3.retries)
|
||||
def _init_dhcp_switching_profile(self):
|
||||
with locking.LockManager.get_lock('nsxv3_dhcp_profile_init'):
|
||||
profile = self._get_dhcp_security_profile()
|
||||
if not profile:
|
||||
self._switching_profiles.create_dhcp_profile(
|
||||
NSX_V3_DHCP_PROFILE_NAME, 'Neutron DHCP Security Profile',
|
||||
tags=utils.build_v3_api_version_tag())
|
||||
tags=nsxlib_utils.build_v3_api_version_tag())
|
||||
return self._get_dhcp_security_profile()
|
||||
|
||||
def _get_dhcp_security_profile(self):
|
||||
@ -345,7 +349,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
self._switching_profiles.create_mac_learning_profile(
|
||||
NSX_V3_MAC_LEARNING_PROFILE_NAME,
|
||||
'Neutron MAC Learning Profile',
|
||||
tags=utils.build_v3_api_version_tag())
|
||||
tags=nsxlib_utils.build_v3_api_version_tag())
|
||||
return self._get_mac_learning_profile()
|
||||
|
||||
def _get_mac_learning_profile(self):
|
||||
@ -369,7 +373,8 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
NSX_V3_PSEC_PROFILE_NAME)
|
||||
return profile[0] if profile else None
|
||||
|
||||
@utils.retry_upon_exception_nsxv3(Exception)
|
||||
@nsxlib_utils.retry_upon_exception(
|
||||
Exception, max_attempts=cfg.CONF.nsx_v3.retries)
|
||||
def _init_port_security_profile(self):
|
||||
profile = self._get_port_security_profile()
|
||||
if profile:
|
||||
@ -384,7 +389,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
self._switching_profiles.create_spoofguard_profile(
|
||||
NSX_V3_PSEC_PROFILE_NAME, 'Neutron Port Security Profile',
|
||||
whitelist_ports=True, whitelist_switches=False,
|
||||
tags=utils.build_v3_api_version_tag())
|
||||
tags=nsxlib_utils.build_v3_api_version_tag())
|
||||
return self._get_port_security_profile()
|
||||
|
||||
def _process_security_group_logging(self):
|
||||
@ -396,8 +401,8 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
sg_logging.LOGGING])
|
||||
for sg in [sg for sg in secgroups
|
||||
if sg[sg_logging.LOGGING] is False]:
|
||||
_, section_id = self.nsxlib.get_sg_mappings(context.session,
|
||||
sg['id'])
|
||||
nsgroup_id, section_id = nsx_db.get_sg_mappings(
|
||||
context.session, sg['id'])
|
||||
try:
|
||||
self.nsxlib.set_firewall_rule_logging_for_section(
|
||||
section_id, logging=log_all_rules)
|
||||
@ -414,9 +419,10 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
cfg.CONF.nsx_v3.number_of_nested_groups)
|
||||
section_description = ("This section is handled by OpenStack to "
|
||||
"contain default rules on security-groups.")
|
||||
section_id = self.nsxlib._init_default_section(
|
||||
section_id = self.nsxlib.init_default_section(
|
||||
security.DEFAULT_SECTION, section_description,
|
||||
nsgroup_manager.nested_groups.values())
|
||||
nsgroup_manager.nested_groups.values(),
|
||||
cfg.CONF.nsx_v3.log_security_groups_blocked_traffic)
|
||||
return nsgroup_manager, section_id
|
||||
|
||||
def _init_dhcp_metadata(self):
|
||||
@ -601,7 +607,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
# update the network name to indicate the neutron id too.
|
||||
net_name = utils.get_name_and_uuid(net_data['name'] or 'network',
|
||||
neutron_net_id)
|
||||
tags = utils.build_v3_tags_payload(
|
||||
tags = nsxlib_utils.build_v3_tags_payload(
|
||||
net_data, resource_type='os-neutron-net-id',
|
||||
project_name=context.tenant_name)
|
||||
|
||||
@ -713,7 +719,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
|
||||
if is_backend_network and cfg.CONF.nsx_v3.native_dhcp_metadata:
|
||||
# Enable native metadata proxy for this network.
|
||||
tags = utils.build_v3_tags_payload(
|
||||
tags = nsxlib_utils.build_v3_tags_payload(
|
||||
net_data, resource_type='os-neutron-net-id',
|
||||
project_name=context.tenant_name)
|
||||
name = utils.get_name_and_uuid('%s-%s' % (
|
||||
@ -722,7 +728,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
md_port = self._port_client.create(
|
||||
nsx_net_id, cfg.CONF.nsx_v3.metadata_proxy_uuid,
|
||||
tags=tags, name=name,
|
||||
attachment_type=nsx_constants.ATTACHMENT_MDPROXY)
|
||||
attachment_type=nsxlib_consts.ATTACHMENT_MDPROXY)
|
||||
LOG.debug("Created MD-Proxy logical port %(port)s "
|
||||
"for network %(network)s",
|
||||
{'port': md_port['id'],
|
||||
@ -923,7 +929,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
server_data = native_dhcp.build_dhcp_server_config(
|
||||
network, subnet, neutron_port, context.tenant_name)
|
||||
nsx_net_id = self._get_network_nsx_id(context, network['id'])
|
||||
tags = utils.build_v3_tags_payload(
|
||||
tags = nsxlib_utils.build_v3_tags_payload(
|
||||
neutron_port, resource_type='os-neutron-dport-id',
|
||||
project_name=context.tenant_name)
|
||||
dhcp_server = None
|
||||
@ -935,7 +941,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
name = self._get_port_name(context, port_data)
|
||||
nsx_port = self._port_client.create(
|
||||
nsx_net_id, dhcp_server['id'], tags=tags, name=name,
|
||||
attachment_type=nsx_constants.ATTACHMENT_DHCP)
|
||||
attachment_type=nsxlib_consts.ATTACHMENT_DHCP)
|
||||
LOG.debug("Created DHCP logical port %(port)s for "
|
||||
"network %(network)s",
|
||||
{'port': nsx_port['id'], 'network': network['id']})
|
||||
@ -956,7 +962,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
# Add neutron_net_id -> dhcp_service_id mapping to the DB.
|
||||
nsx_db.add_neutron_nsx_service_binding(
|
||||
context.session, network['id'], neutron_port['id'],
|
||||
nsx_constants.SERVICE_DHCP, dhcp_server['id'])
|
||||
nsxlib_consts.SERVICE_DHCP, dhcp_server['id'])
|
||||
except db_exc.DBError:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error(_LE("Failed to create mapping for DHCP port %s,"
|
||||
@ -970,7 +976,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
# First delete the DHCP port in this network. Then delete the
|
||||
# corresponding LogicalDhcpServer for this network.
|
||||
dhcp_service = nsx_db.get_nsx_service_binding(
|
||||
context.session, network_id, nsx_constants.SERVICE_DHCP)
|
||||
context.session, network_id, nsxlib_consts.SERVICE_DHCP)
|
||||
if not dhcp_service:
|
||||
return
|
||||
|
||||
@ -1002,7 +1008,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
try:
|
||||
# Delete neutron_id -> dhcp_service_id mapping from the DB.
|
||||
nsx_db.delete_neutron_nsx_service_binding(
|
||||
context.session, network_id, nsx_constants.SERVICE_DHCP)
|
||||
context.session, network_id, nsxlib_consts.SERVICE_DHCP)
|
||||
except db_exc.DBError:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error(_LE("Unable to delete DHCP server mapping for "
|
||||
@ -1105,7 +1111,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
if kwargs:
|
||||
dhcp_service = nsx_db.get_nsx_service_binding(
|
||||
context.session, orig_subnet['network_id'],
|
||||
nsx_constants.SERVICE_DHCP)
|
||||
nsxlib_consts.SERVICE_DHCP)
|
||||
if dhcp_service:
|
||||
try:
|
||||
self._dhcp_server.update(
|
||||
@ -1256,13 +1262,13 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
resource_type = 'os-neutron-rport-id'
|
||||
else:
|
||||
resource_type = 'os-neutron-port-id'
|
||||
tags = utils.build_v3_tags_payload(
|
||||
tags = nsxlib_utils.build_v3_tags_payload(
|
||||
port_data, resource_type=resource_type,
|
||||
project_name=context.tenant_name)
|
||||
resource_type = self._get_resource_type_for_device_id(
|
||||
device_owner, device_id)
|
||||
if resource_type:
|
||||
tags = utils.add_v3_tag(tags, resource_type, device_id)
|
||||
tags = nsxlib_utils.add_v3_tag(tags, resource_type, device_id)
|
||||
|
||||
if utils.is_nsx_version_1_1_0(self._nsx_version):
|
||||
# If port has no security-groups then we don't need to add any
|
||||
@ -1293,7 +1299,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
vif_uuid = False
|
||||
else:
|
||||
# default attachment
|
||||
attachment_type = nsx_constants.ATTACHMENT_VIF
|
||||
attachment_type = nsxlib_consts.ATTACHMENT_VIF
|
||||
vif_uuid = port_data['id']
|
||||
|
||||
profiles = []
|
||||
@ -1423,7 +1429,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
if not utils.is_port_dhcp_configurable(port):
|
||||
return
|
||||
dhcp_service = nsx_db.get_nsx_service_binding(
|
||||
context.session, port['network_id'], nsx_constants.SERVICE_DHCP)
|
||||
context.session, port['network_id'], nsxlib_consts.SERVICE_DHCP)
|
||||
if not dhcp_service:
|
||||
return
|
||||
for fixed_ip in self._filter_ipv4_dhcp_fixed_ips(
|
||||
@ -1542,7 +1548,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
# Locate the backend DHCP server for this DHCP port.
|
||||
dhcp_service = nsx_db.get_nsx_service_binding(
|
||||
context.session, old_port['network_id'],
|
||||
nsx_constants.SERVICE_DHCP)
|
||||
nsxlib_consts.SERVICE_DHCP)
|
||||
if dhcp_service:
|
||||
new_ip = ips_to_add[0][1]
|
||||
try:
|
||||
@ -1586,7 +1592,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
if ips_to_add:
|
||||
dhcp_service = nsx_db.get_nsx_service_binding(
|
||||
context.session, new_port['network_id'],
|
||||
nsx_constants.SERVICE_DHCP)
|
||||
nsxlib_consts.SERVICE_DHCP)
|
||||
if dhcp_service:
|
||||
for (subnet_id, ip) in ips_to_add:
|
||||
self._add_dhcp_binding_on_server(
|
||||
@ -1622,6 +1628,16 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
{'mac': mac, 'ip': ip, 'port': binding['port_id'],
|
||||
'server': binding['nsx_service_id']})
|
||||
|
||||
def _update_lport_with_security_groups(self, context, lport_id,
|
||||
original, updated):
|
||||
# translate the neutron sg ids to nsx ids, and call nsxlib
|
||||
nsx_origial = nsx_db.get_nsx_security_group_ids(context.session,
|
||||
original)
|
||||
nsx_updated = nsx_db.get_nsx_security_group_ids(context.session,
|
||||
updated)
|
||||
self.nsxlib.update_lport_with_security_groups(
|
||||
context, lport_id, nsx_origial, nsx_updated)
|
||||
|
||||
def create_port(self, context, port, l2gw_port_check=False):
|
||||
port_data = port['port']
|
||||
dhcp_opts = port_data.get(ext_edo.EXTRADHCPOPTS, [])
|
||||
@ -1686,7 +1702,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
|
||||
if not utils.is_nsx_version_1_1_0(self._nsx_version):
|
||||
try:
|
||||
self.nsxlib.update_lport_with_security_groups(
|
||||
self._update_lport_with_security_groups(
|
||||
context, lport['id'], [], sgids or [])
|
||||
except Exception as e:
|
||||
with excutils.save_and_reraise_exception(reraise=False):
|
||||
@ -1762,7 +1778,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
context.session, port_id)
|
||||
self._port_client.delete(nsx_port_id)
|
||||
if not utils.is_nsx_version_1_1_0(self._nsx_version):
|
||||
self.nsxlib.update_lport_with_security_groups(
|
||||
self._update_lport_with_security_groups(
|
||||
context, nsx_port_id,
|
||||
port.get(ext_sg.SECURITYGROUPS, []), [])
|
||||
self.disassociate_floatingips(context, port_id)
|
||||
@ -1866,21 +1882,21 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
resource_type = self._get_resource_type_for_device_id(
|
||||
original_device_owner, updated_device_id)
|
||||
if resource_type:
|
||||
tags_update = utils.add_v3_tag(tags_update, resource_type,
|
||||
updated_device_id)
|
||||
tags_update = nsxlib_utils.add_v3_tag(
|
||||
tags_update, resource_type, updated_device_id)
|
||||
|
||||
parent_vif_id, tag = self._get_data_from_binding_profile(
|
||||
context, updated_port)
|
||||
|
||||
if updated_device_owner in (original_device_owner,
|
||||
l3_db.DEVICE_OWNER_ROUTER_INTF,
|
||||
nsx_constants.BRIDGE_ENDPOINT):
|
||||
nsxlib_consts.BRIDGE_ENDPOINT):
|
||||
# no attachment change
|
||||
attachment_type = False
|
||||
vif_uuid = False
|
||||
elif updated_device_owner:
|
||||
# default attachment
|
||||
attachment_type = nsx_constants.ATTACHMENT_VIF
|
||||
attachment_type = nsxlib_consts.ATTACHMENT_VIF
|
||||
vif_uuid = updated_port['id']
|
||||
else:
|
||||
# no attachment
|
||||
@ -1894,7 +1910,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
updated_port.get(ext_sg.SECURITYGROUPS, []) +
|
||||
updated_port.get(provider_sg.PROVIDER_SECURITYGROUPS, []))
|
||||
else:
|
||||
self.nsxlib.update_lport_with_security_groups(
|
||||
self._update_lport_with_security_groups(
|
||||
context, lport_id,
|
||||
original_port.get(ext_sg.SECURITYGROUPS, []) +
|
||||
original_port.get(provider_sg.PROVIDER_SECURITYGROUPS, []),
|
||||
@ -2236,7 +2252,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
edge_cluster_uuid = self._get_edge_cluster(new_tier0_uuid)
|
||||
self._routerlib.update_router_edge_cluster(
|
||||
nsx_router_id, edge_cluster_uuid)
|
||||
tags = utils.build_v3_tags_payload(
|
||||
tags = nsxlib_utils.build_v3_tags_payload(
|
||||
router, resource_type='os-neutron-rport',
|
||||
project_name=context.tenant_name)
|
||||
self._routerlib.add_router_link_port(nsx_router_id, new_tier0_uuid,
|
||||
@ -2256,7 +2272,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
gw_info = self._extract_external_gw(context, router, is_extract=True)
|
||||
router['router']['id'] = (router['router'].get('id') or
|
||||
uuidutils.generate_uuid())
|
||||
tags = utils.build_v3_tags_payload(
|
||||
tags = nsxlib_utils.build_v3_tags_payload(
|
||||
router['router'], resource_type='os-neutron-router-id',
|
||||
project_name=context.tenant_name)
|
||||
result = self._router_client.create(
|
||||
@ -2522,7 +2538,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
context, router_id, network_id)
|
||||
display_name = utils.get_name_and_uuid(
|
||||
subnet['name'] or 'subnet', subnet['id'])
|
||||
tags = utils.build_v3_tags_payload(
|
||||
tags = nsxlib_utils.build_v3_tags_payload(
|
||||
port, resource_type='os-neutron-rport-id',
|
||||
project_name=context.tenant_name)
|
||||
tags.append({'scope': 'os-subnet-id', 'tag': subnet['id']})
|
||||
@ -2777,9 +2793,9 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
def _create_fw_section_for_secgroup(self, nsgroup, is_provider):
|
||||
# NOTE(arosen): if a security group is provider we want to
|
||||
# insert our rules at the top.
|
||||
operation = (firewall.INSERT_TOP
|
||||
operation = (nsxlib_consts.FW_INSERT_TOP
|
||||
if is_provider
|
||||
else firewall.INSERT_BEFORE)
|
||||
else nsxlib_consts.FW_INSERT_BEFORE)
|
||||
|
||||
# security-group rules are located in a dedicated firewall section.
|
||||
firewall_section = (
|
||||
@ -2791,7 +2807,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
return firewall_section
|
||||
|
||||
def _create_security_group_backend_resources(self, secgroup):
|
||||
tags = utils.build_v3_tags_payload(
|
||||
tags = nsxlib_utils.build_v3_tags_payload(
|
||||
secgroup, resource_type='os-neutron-secgr-id',
|
||||
project_name=secgroup['tenant_id'])
|
||||
name = self.nsxlib.get_nsgroup_name(secgroup)
|
||||
@ -2810,6 +2826,27 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
ns_group, secgroup.get(provider_sg.PROVIDER))
|
||||
return ns_group, firewall_section
|
||||
|
||||
def _create_firewall_rules(self, context, section_id, nsgroup_id,
|
||||
logging_enabled, action, sg_rules):
|
||||
# since the nsxlib does not have access to the nsx db,
|
||||
# we need to provide a mapping for the remote nsgroup ids.
|
||||
ruleid_2_remote_nsgroup_map = {}
|
||||
for sg_rule in sg_rules:
|
||||
remote_nsgroup_id = None
|
||||
remote_group_id = sg_rule.get('remote_group_id')
|
||||
# skip unnecessary db access when possible
|
||||
if remote_group_id == sg_rule['security_group_id']:
|
||||
remote_nsgroup_id = nsgroup_id
|
||||
elif remote_group_id:
|
||||
remote_nsgroup_id = nsx_db.get_nsx_security_group_id(
|
||||
context.session, remote_group_id)
|
||||
ruleid_2_remote_nsgroup_map[sg_rule['id']] = remote_nsgroup_id
|
||||
|
||||
return self.nsxlib.create_firewall_rules(
|
||||
context, section_id, nsgroup_id,
|
||||
logging_enabled, action, sg_rules,
|
||||
ruleid_2_remote_nsgroup_map)
|
||||
|
||||
def create_security_group(self, context, security_group, default_sg=False):
|
||||
secgroup = security_group['security_group']
|
||||
secgroup['id'] = secgroup.get('id') or uuidutils.generate_uuid()
|
||||
@ -2871,14 +2908,13 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
# translate and creates firewall rules.
|
||||
logging = (cfg.CONF.nsx_v3.log_security_groups_allowed_traffic
|
||||
or secgroup.get(sg_logging.LOGGING, False))
|
||||
action = (firewall.DROP
|
||||
action = (nsxlib_consts.FW_ACTION_DROP
|
||||
if secgroup.get(provider_sg.PROVIDER)
|
||||
else firewall.ALLOW)
|
||||
rules = self.nsxlib.create_firewall_rules(
|
||||
else nsxlib_consts.FW_ACTION_ALLOW)
|
||||
rules = self._create_firewall_rules(
|
||||
context, firewall_section['id'], ns_group['id'],
|
||||
logging, action, sg_rules)
|
||||
self.nsxlib.save_sg_rule_mappings(context.session,
|
||||
rules['rules'])
|
||||
self.save_security_group_rule_mappings(context, rules['rules'])
|
||||
self.nsgroup_manager.add_nsgroup(ns_group['id'])
|
||||
except nsx_lib_exc.ManagerError:
|
||||
with excutils.save_and_reraise_exception():
|
||||
@ -2905,7 +2941,11 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
self._process_security_group_properties_update(
|
||||
context, secgroup_res, security_group['security_group'])
|
||||
try:
|
||||
self.nsxlib.update_security_group_on_backend(context, secgroup_res)
|
||||
nsgroup_id, section_id = nsx_db.get_sg_mappings(
|
||||
context.session, id)
|
||||
self.nsxlib.update_security_group_on_backend(
|
||||
context, secgroup_res, nsgroup_id, section_id,
|
||||
cfg.CONF.nsx_v3.log_security_groups_allowed_traffic)
|
||||
except nsx_lib_exc.ManagerError:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_LE("Failed to update security-group %(name)s "
|
||||
@ -2918,7 +2958,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
|
||||
def delete_security_group(self, context, id):
|
||||
self._prevent_non_admin_delete_provider_sg(context, id)
|
||||
nsgroup_id, section_id = self.nsxlib.get_sg_mappings(
|
||||
nsgroup_id, section_id = nsx_db.get_sg_mappings(
|
||||
context.session, id)
|
||||
super(NsxV3Plugin, self).delete_security_group(context, id)
|
||||
self.nsxlib.delete_section(section_id)
|
||||
@ -2957,18 +2997,18 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
|
||||
security_group = self.get_security_group(
|
||||
context, sg_id)
|
||||
action = firewall.ALLOW
|
||||
action = nsxlib_consts.FW_ACTION_ALLOW
|
||||
if security_group.get(provider_sg.PROVIDER) is True:
|
||||
# provider security groups are drop rules.
|
||||
action = firewall.DROP
|
||||
action = nsxlib_consts.FW_ACTION_DROP
|
||||
|
||||
sg_id = rules_db[0]['security_group_id']
|
||||
nsgroup_id, section_id = self.nsxlib.get_sg_mappings(context.session,
|
||||
sg_id)
|
||||
nsgroup_id, section_id = nsx_db.get_sg_mappings(context.session,
|
||||
sg_id)
|
||||
logging_enabled = (cfg.CONF.nsx_v3.log_security_groups_allowed_traffic
|
||||
or self._is_security_group_logged(context, sg_id))
|
||||
try:
|
||||
rules = self.nsxlib.create_firewall_rules(
|
||||
rules = self._create_firewall_rules(
|
||||
context, section_id, nsgroup_id,
|
||||
logging_enabled, action, rules_db)
|
||||
except nsx_lib_exc.ManagerError:
|
||||
@ -2976,14 +3016,18 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
for rule in rules_db:
|
||||
super(NsxV3Plugin, self).delete_security_group_rule(
|
||||
context, rule['id'])
|
||||
self.nsxlib.save_sg_rule_mappings(context.session, rules['rules'])
|
||||
self.save_security_group_rule_mappings(context, rules['rules'])
|
||||
return rules_db
|
||||
|
||||
def delete_security_group_rule(self, context, id):
|
||||
rule_db = self._get_security_group_rule(context, id)
|
||||
sg_id = rule_db['security_group_id']
|
||||
self._prevent_non_admin_delete_provider_sg(context, sg_id)
|
||||
_, section_id = self.nsxlib.get_sg_mappings(context.session, sg_id)
|
||||
nsgroup_id, section_id = nsx_db.get_sg_mappings(context.session, sg_id)
|
||||
fw_rule_id = nsx_db.get_sg_rule_mapping(context.session, id)
|
||||
self.nsxlib.delete_rule(section_id, fw_rule_id)
|
||||
super(NsxV3Plugin, self).delete_security_group_rule(context, id)
|
||||
|
||||
def save_security_group_rule_mappings(self, context, firewall_rules):
|
||||
rules = [(rule['display_name'], rule['id']) for rule in firewall_rules]
|
||||
nsx_db.save_sg_rule_mappings(context.session, rules)
|
||||
|
@ -34,10 +34,11 @@ from neutron_lib import constants
|
||||
from neutron_lib import exceptions as n_exc
|
||||
|
||||
from vmware_nsx._i18n import _, _LE, _LI
|
||||
from vmware_nsx.common import nsx_constants
|
||||
from vmware_nsx.common import utils as nsx_utils
|
||||
from vmware_nsx.db import db as nsx_db
|
||||
from vmware_nsx.nsxlib.v3 import exceptions as nsxlib_exc
|
||||
from vmware_nsx.nsxlib.v3 import nsx_constants
|
||||
from vmware_nsx.nsxlib.v3 import utils as nsxlib_utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@ -219,7 +220,7 @@ class NsxV3Driver(l2gateway_db.L2GatewayMixin):
|
||||
tenant_id = context.tenant_id
|
||||
gw_connection['tenant_id'] = tenant_id
|
||||
try:
|
||||
tags = nsx_utils.build_v3_tags_payload(
|
||||
tags = nsxlib_utils.build_v3_tags_payload(
|
||||
gw_connection, resource_type='os-neutron-l2gw-id',
|
||||
project_name=context.tenant_name)
|
||||
bridge_endpoint = self._core_plugin.nsxlib.create_bridge_endpoint(
|
||||
|
@ -27,11 +27,11 @@ from oslo_utils import excutils
|
||||
|
||||
from vmware_nsx._i18n import _, _LE, _LW
|
||||
from vmware_nsx.common import exceptions as nsx_exc
|
||||
from vmware_nsx.common import utils as nsx_utils
|
||||
from vmware_nsx.db import db as nsx_db
|
||||
from vmware_nsx.nsxlib import v3 as nsxlib
|
||||
from vmware_nsx.nsxlib.v3 import exceptions as nsxlib_exc
|
||||
from vmware_nsx.nsxlib.v3 import resources as nsx_resources
|
||||
from vmware_nsx.nsxlib.v3 import utils as nsxlib_utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@ -177,7 +177,7 @@ class NsxV3Driver(base_driver.TaasBaseDriver,
|
||||
tf.get('tap_service_id'))
|
||||
src_port_id = tf.get('source_port')
|
||||
dest_port_id = ts.get('port_id')
|
||||
tags = nsx_utils.build_v3_tags_payload(
|
||||
tags = nsxlib_utils.build_v3_tags_payload(
|
||||
tf, resource_type='os-neutron-mirror-id',
|
||||
project_name=context._plugin_context.tenant_name)
|
||||
nsx_direction = self._convert_to_backend_direction(
|
||||
|
@ -25,8 +25,8 @@ from oslo_log import log as logging
|
||||
|
||||
from vmware_nsx._i18n import _, _LW
|
||||
from vmware_nsx.common import exceptions as nsx_exc
|
||||
from vmware_nsx.common import utils
|
||||
from vmware_nsx.db import db as nsx_db
|
||||
from vmware_nsx.nsxlib.v3 import utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
MAX_KBPS_MIN_VALUE = 1024
|
||||
|
@ -20,9 +20,9 @@ from neutron_lib import constants as const
|
||||
from oslo_config import cfg
|
||||
|
||||
from vmware_nsx._i18n import _LE, _LI
|
||||
from vmware_nsx.common import nsx_constants
|
||||
from vmware_nsx.common import utils as nsx_utils
|
||||
from vmware_nsx.nsxlib.v3 import native_dhcp
|
||||
from vmware_nsx.nsxlib.v3 import nsx_constants
|
||||
from vmware_nsx.nsxlib.v3 import resources
|
||||
from vmware_nsx.shell.admin.plugins.common import constants
|
||||
from vmware_nsx.shell.admin.plugins.common import formatters
|
||||
|
@ -19,10 +19,11 @@ from neutron_lib import constants as const
|
||||
from oslo_config import cfg
|
||||
|
||||
from vmware_nsx._i18n import _LE, _LI
|
||||
from vmware_nsx.common import nsx_constants
|
||||
from vmware_nsx.common import utils as nsx_utils
|
||||
from vmware_nsx.dhcp_meta import rpc as nsx_rpc
|
||||
from vmware_nsx.nsxlib.v3 import nsx_constants
|
||||
from vmware_nsx.nsxlib.v3 import resources
|
||||
from vmware_nsx.nsxlib.v3 import utils as nsxlib_utils
|
||||
from vmware_nsx.shell.admin.plugins.common import constants
|
||||
from vmware_nsx.shell.admin.plugins.common import formatters
|
||||
from vmware_nsx.shell.admin.plugins.common import utils as admin_utils
|
||||
@ -104,7 +105,7 @@ def nsx_update_metadata_proxy(resource, event, trigger, **kwargs):
|
||||
lswitch_id = neutron_client.net_id_to_lswitch_id(network['id'])
|
||||
if not lswitch_id:
|
||||
continue
|
||||
tags = nsx_utils.build_v3_tags_payload(
|
||||
tags = nsxlib_utils.build_v3_tags_payload(
|
||||
network, resource_type='os-neutron-net-id',
|
||||
project_name='admin')
|
||||
name = nsx_utils.get_name_and_uuid('%s-%s' % (
|
||||
|
@ -32,8 +32,9 @@ from vmware_nsx.shell.admin.plugins.nsxv3.resources import ports
|
||||
from vmware_nsx.shell.admin.plugins.nsxv3.resources import utils as v3_utils
|
||||
from vmware_nsx.shell import resources as shell
|
||||
from vmware_nsx._i18n import _LE, _LW
|
||||
from vmware_nsx.nsxlib.v3 import dfw_api as firewall
|
||||
from vmware_nsx.nsxlib.v3 import nsx_constants as consts
|
||||
from vmware_nsx.nsxlib.v3 import security
|
||||
from vmware_nsx.nsxlib.v3 import utils as nsxlib_utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@ -221,7 +222,7 @@ def fix_security_groups(resource, event, trigger, **kwargs):
|
||||
lport_id = neutron_db.get_logical_port_id(port_id)
|
||||
members.append(lport_id)
|
||||
nsxlib.add_nsgroup_members(
|
||||
nsgroup['id'], firewall.LOGICAL_PORT, members)
|
||||
nsgroup['id'], consts.TARGET_TYPE_LOGICAL_PORT, members)
|
||||
|
||||
for rule in secgroup['security_group_rules']:
|
||||
rule_mapping = (context_.session.query(
|
||||
@ -229,14 +230,14 @@ def fix_security_groups(resource, event, trigger, **kwargs):
|
||||
neutron_id=rule['id']).one())
|
||||
with context_.session.begin(subtransactions=True):
|
||||
context_.session.delete(rule_mapping)
|
||||
action = (firewall.DROP
|
||||
action = (consts.FW_ACTION_DROP
|
||||
if secgroup.get(provider_sg.PROVIDER)
|
||||
else firewall.ALLOW)
|
||||
rules = nsxlib.create_firewall_rules(
|
||||
else consts.FW_ACTION_ALLOW)
|
||||
rules = plugin._create_firewall_rules(
|
||||
context_, fw_section['id'], nsgroup['id'],
|
||||
secgroup.get(sg_logging.LOGGING, False), action,
|
||||
secgroup['security_group_rules'])
|
||||
nsxlib.save_sg_rule_mappings(context_.session, rules['rules'])
|
||||
plugin.save_security_group_rule_mappings(context_, rules['rules'])
|
||||
# Add nsgroup to a nested group
|
||||
plugin.nsgroup_manager.add_nsgroup(nsgroup['id'])
|
||||
|
||||
@ -252,7 +253,7 @@ def _update_ports_dynamic_criteria_tags():
|
||||
_, lport_id = neutron_db.get_lswitch_and_lport_id(port['id'])
|
||||
lport = port_client.get(lport_id)
|
||||
criteria_tags = nsxlib.get_lport_tags_for_security_groups(secgroups)
|
||||
lport['tags'] = utils.update_v3_tags(
|
||||
lport['tags'] = nsxlib_utils.update_v3_tags(
|
||||
lport.get('tags', []), criteria_tags)
|
||||
port_client._client.update(lport_id, body=lport)
|
||||
|
||||
|
@ -17,9 +17,9 @@ from neutron import context
|
||||
from neutron.db import db_base_plugin_v2
|
||||
from oslo_config import cfg
|
||||
|
||||
from vmware_nsx.common import nsx_constants
|
||||
from vmware_nsx.db import db as nsx_db
|
||||
from vmware_nsx.nsxlib import v3
|
||||
from vmware_nsx.nsxlib.v3 import nsx_constants
|
||||
from vmware_nsx.plugins.nsx_v3 import plugin
|
||||
|
||||
|
||||
|
@ -150,4 +150,5 @@ class TestNSXv3ExtendedSGRule(test_nsxv3_plugin.NsxV3PluginTestCaseMixin,
|
||||
mock.ANY, # ns_group_id
|
||||
False, # logging
|
||||
'ALLOW', # action
|
||||
sg_rules) # sg_rules
|
||||
sg_rules, # sg_rules
|
||||
mock.ANY) # ruleid_2_remote_nsgroup_map
|
||||
|
@ -17,9 +17,9 @@ import mock
|
||||
from neutron.extensions import securitygroup as ext_sg
|
||||
from neutron.tests.unit.extensions import test_securitygroup as test_ext_sg
|
||||
|
||||
from vmware_nsx.nsxlib.v3 import dfw_api as firewall
|
||||
from vmware_nsx.nsxlib.v3 import exceptions as nsxlib_exc
|
||||
from vmware_nsx.nsxlib.v3 import ns_group_manager
|
||||
from vmware_nsx.nsxlib.v3 import nsx_constants as consts
|
||||
from vmware_nsx.plugins.nsx_v3 import plugin as nsx_plugin
|
||||
from vmware_nsx.tests.unit.nsx_v3 import test_plugin as test_nsxv3
|
||||
from vmware_nsx.tests.unit.nsxlib.v3 import nsxlib_testcase
|
||||
@ -84,8 +84,10 @@ class TestSecurityGroupsNoDynamicCriteria(test_nsxv3.NsxV3PluginTestCaseMixin,
|
||||
|
||||
# The first nsgroup is associated with the default secgroup, which is
|
||||
# not added to this port.
|
||||
calls = [mock.call(NSG_IDS[1], firewall.LOGICAL_PORT, mock.ANY),
|
||||
mock.call(NSG_IDS[2], firewall.LOGICAL_PORT, mock.ANY)]
|
||||
calls = [mock.call(NSG_IDS[1],
|
||||
consts.TARGET_TYPE_LOGICAL_PORT, mock.ANY),
|
||||
mock.call(NSG_IDS[2],
|
||||
consts.TARGET_TYPE_LOGICAL_PORT, mock.ANY)]
|
||||
add_member_mock.assert_has_calls(calls, any_order=True)
|
||||
|
||||
@_mock_create_and_list_nsgroups
|
||||
@ -97,13 +99,16 @@ class TestSecurityGroupsNoDynamicCriteria(test_nsxv3.NsxV3PluginTestCaseMixin,
|
||||
super(TestSecurityGroupsNoDynamicCriteria,
|
||||
self).test_update_port_with_multiple_security_groups()
|
||||
|
||||
calls = [mock.call(NSG_IDS[0], firewall.LOGICAL_PORT, mock.ANY),
|
||||
mock.call(NSG_IDS[1], firewall.LOGICAL_PORT, mock.ANY),
|
||||
mock.call(NSG_IDS[2], firewall.LOGICAL_PORT, mock.ANY)]
|
||||
calls = [mock.call(NSG_IDS[0],
|
||||
consts.TARGET_TYPE_LOGICAL_PORT, mock.ANY),
|
||||
mock.call(NSG_IDS[1],
|
||||
consts.TARGET_TYPE_LOGICAL_PORT, mock.ANY),
|
||||
mock.call(NSG_IDS[2],
|
||||
consts.TARGET_TYPE_LOGICAL_PORT, mock.ANY)]
|
||||
add_member_mock.assert_has_calls(calls, any_order=True)
|
||||
|
||||
remove_member_mock.assert_called_with(
|
||||
NSG_IDS[0], firewall.LOGICAL_PORT, mock.ANY)
|
||||
NSG_IDS[0], consts.TARGET_TYPE_LOGICAL_PORT, mock.ANY)
|
||||
|
||||
@_mock_create_and_list_nsgroups
|
||||
@mock.patch('vmware_nsx.nsxlib.v3.NsxLib.remove_nsgroup_member')
|
||||
@ -115,9 +120,9 @@ class TestSecurityGroupsNoDynamicCriteria(test_nsxv3.NsxV3PluginTestCaseMixin,
|
||||
self).test_update_port_remove_security_group_empty_list()
|
||||
|
||||
add_member_mock.assert_called_with(
|
||||
NSG_IDS[1], firewall.LOGICAL_PORT, mock.ANY)
|
||||
NSG_IDS[1], consts.TARGET_TYPE_LOGICAL_PORT, mock.ANY)
|
||||
remove_member_mock.assert_called_with(
|
||||
NSG_IDS[1], firewall.LOGICAL_PORT, mock.ANY)
|
||||
NSG_IDS[1], consts.TARGET_TYPE_LOGICAL_PORT, mock.ANY)
|
||||
|
||||
@_mock_create_and_list_nsgroups
|
||||
@mock.patch('vmware_nsx.nsxlib.v3.NsxLib.add_nsgroup_members')
|
||||
@ -166,8 +171,10 @@ class TestSecurityGroupsNoDynamicCriteria(test_nsxv3.NsxV3PluginTestCaseMixin,
|
||||
# Because the update has failed we excpect that the plugin will try to
|
||||
# revert any changes in the NSGroups - It is required to remove the
|
||||
# lport from any NSGroups which it was added to during that call.
|
||||
calls = [mock.call(NSG_IDS[1], firewall.LOGICAL_PORT, mock.ANY),
|
||||
mock.call(NSG_IDS[2], firewall.LOGICAL_PORT, mock.ANY)]
|
||||
calls = [mock.call(NSG_IDS[1],
|
||||
consts.TARGET_TYPE_LOGICAL_PORT, mock.ANY),
|
||||
mock.call(NSG_IDS[2],
|
||||
consts.TARGET_TYPE_LOGICAL_PORT, mock.ANY)]
|
||||
remove_member_mock.assert_has_calls(calls, any_order=True)
|
||||
|
||||
def test_create_security_group_rule_icmpv6_legacy_protocol_name(self):
|
||||
@ -225,9 +232,10 @@ class TestNSGroupManager(nsxlib_testcase.NsxLibTestCase):
|
||||
# There are 5 nested groups, the hash function will return 7, therefore
|
||||
# we expect that the nsgroup will be placed in the 3rd group.
|
||||
add_member_mock.assert_called_once_with(
|
||||
NSG_IDS[2], firewall.NSGROUP, [nsgroup_id])
|
||||
NSG_IDS[2], consts.NSGROUP, [nsgroup_id])
|
||||
remove_member_mock.assert_called_once_with(
|
||||
NSG_IDS[2], firewall.NSGROUP, nsgroup_id, verify=True)
|
||||
NSG_IDS[2], consts.NSGROUP, nsgroup_id,
|
||||
verify=True)
|
||||
|
||||
@_mock_create_and_list_nsgroups
|
||||
@mock.patch('vmware_nsx.nsxlib.v3.NsxLib.remove_nsgroup_member')
|
||||
@ -259,8 +267,10 @@ class TestNSGroupManager(nsxlib_testcase.NsxLibTestCase):
|
||||
# Trying to add nsgroup to the nested group at index 2 will raise
|
||||
# NSGroupIsFull exception, we expect that the nsgroup will be added to
|
||||
# the nested group at index 3.
|
||||
calls = [mock.call(NSG_IDS[2], firewall.NSGROUP, [nsgroup_id]),
|
||||
mock.call(NSG_IDS[3], firewall.NSGROUP, [nsgroup_id])]
|
||||
calls = [mock.call(NSG_IDS[2],
|
||||
consts.NSGROUP, [nsgroup_id]),
|
||||
mock.call(NSG_IDS[3],
|
||||
consts.NSGROUP, [nsgroup_id])]
|
||||
add_member_mock.assert_has_calls(calls)
|
||||
|
||||
# Since the nsgroup was added to the nested group at index 3, it will
|
||||
@ -268,9 +278,11 @@ class TestNSGroupManager(nsxlib_testcase.NsxLibTestCase):
|
||||
# remove it from the group at index 3.
|
||||
calls = [
|
||||
mock.call(
|
||||
NSG_IDS[2], firewall.NSGROUP, nsgroup_id, verify=True),
|
||||
NSG_IDS[2], consts.NSGROUP,
|
||||
nsgroup_id, verify=True),
|
||||
mock.call(
|
||||
NSG_IDS[3], firewall.NSGROUP, nsgroup_id, verify=True)]
|
||||
NSG_IDS[3], consts.NSGROUP,
|
||||
nsgroup_id, verify=True)]
|
||||
remove_member_mock.assert_has_calls(calls)
|
||||
|
||||
@_mock_create_and_list_nsgroups
|
||||
@ -282,16 +294,17 @@ class TestNSGroupManager(nsxlib_testcase.NsxLibTestCase):
|
||||
size = 3
|
||||
cont_manager = ns_group_manager.NSGroupManager(size)
|
||||
# list_nsgroups will return nested group 1 and 3, but not group 2.
|
||||
with mock.patch.object(firewall,
|
||||
'list_nsgroups_mock') as list_nsgroups_mock:
|
||||
list_nsgroups_mock = lambda: list_nsgroups_mock()[::2]
|
||||
# invoking the initialization process again, it should process
|
||||
# groups 1 and 3 and create group 2.
|
||||
cont_manager = ns_group_manager.NSGroupManager(size)
|
||||
self.assertEqual({1: NSG_IDS[0],
|
||||
2: NSG_IDS[3],
|
||||
3: NSG_IDS[2]},
|
||||
cont_manager.nested_groups)
|
||||
# FIXME: Not sure what this mock does. no one calls this method now.
|
||||
#with mock.patch.object(vmware_nsx.nsxlib.v3.NsxLib.list_nsgroups,
|
||||
# 'list_nsgroups_mock') as list_nsgroups_mock:
|
||||
# list_nsgroups_mock = lambda: list_nsgroups_mock()[::2]
|
||||
# invoking the initialization process again, it should process
|
||||
# groups 1 and 3 and create group 2.
|
||||
cont_manager = ns_group_manager.NSGroupManager(size)
|
||||
self.assertEqual({1: NSG_IDS[0],
|
||||
2: NSG_IDS[3],
|
||||
3: NSG_IDS[2]},
|
||||
cont_manager.nested_groups)
|
||||
|
||||
@_mock_create_and_list_nsgroups
|
||||
def test_suggest_nested_group(self):
|
||||
|
@ -14,149 +14,4 @@
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
PLUGIN_NAME = 'vmware_nsx.plugins.nsx_v3.plugin.NsxV3Plugin'
|
||||
FAKE_NAME = "fake_name"
|
||||
FAKE_SWITCH_UUID = uuidutils.generate_uuid()
|
||||
|
||||
FAKE_PORT_UUID = uuidutils.generate_uuid()
|
||||
FAKE_PORT = {
|
||||
"id": FAKE_PORT_UUID,
|
||||
"display_name": FAKE_NAME,
|
||||
"resource_type": "LogicalPort",
|
||||
"address_bindings": [],
|
||||
"logical_switch_id": FAKE_SWITCH_UUID,
|
||||
"admin_state": "UP",
|
||||
"attachment": {
|
||||
"id": "9ca8d413-f7bf-4276-b4c9-62f42516bdb2",
|
||||
"attachment_type": "VIF"
|
||||
},
|
||||
"switching_profile_ids": [
|
||||
{
|
||||
"value": "64814784-7896-3901-9741-badeff705639",
|
||||
"key": "IpDiscoverySwitchingProfile"
|
||||
},
|
||||
{
|
||||
"value": "fad98876-d7ff-11e4-b9d6-1681e6b88ec1",
|
||||
"key": "SpoofGuardSwitchingProfile"
|
||||
},
|
||||
{
|
||||
"value": "93b4b7e8-f116-415d-a50c-3364611b5d09",
|
||||
"key": "PortMirroringSwitchingProfile"
|
||||
},
|
||||
{
|
||||
"value": "fbc4fb17-83d9-4b53-a286-ccdf04301888",
|
||||
"key": "SwitchSecuritySwitchingProfile"
|
||||
},
|
||||
{
|
||||
"value": "f313290b-eba8-4262-bd93-fab5026e9495",
|
||||
"key": "QosSwitchingProfile"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
FAKE_CONTAINER_PORT = {
|
||||
"id": FAKE_PORT_UUID,
|
||||
"display_name": FAKE_NAME,
|
||||
"resource_type": "LogicalPort",
|
||||
"address_bindings": [
|
||||
{
|
||||
"ip_address": "192.168.1.110",
|
||||
"mac_address": "aa:bb:cc:dd:ee:ff"
|
||||
}
|
||||
],
|
||||
"logical_switch_id": FAKE_SWITCH_UUID,
|
||||
"admin_state": "UP",
|
||||
"attachment": {
|
||||
"id": "9ca8d413-f7bf-4276-b4c9-62f42516bdb2",
|
||||
"attachment_type": "CIF",
|
||||
"context": {
|
||||
"vlan_tag": 122,
|
||||
"container_host_vif_id": "c6f817a0-4e36-421e-98a6-8a2faed880bc",
|
||||
"key_values": [],
|
||||
"resource_type": "CifAttachmentContext",
|
||||
}
|
||||
},
|
||||
"switching_profile_ids": [
|
||||
{
|
||||
"value": "64814784-7896-3901-9741-badeff705639",
|
||||
"key": "IpDiscoverySwitchingProfile"
|
||||
},
|
||||
{
|
||||
"value": "fad98876-d7ff-11e4-b9d6-1681e6b88ec1",
|
||||
"key": "SpoofGuardSwitchingProfile"
|
||||
},
|
||||
{
|
||||
"value": "93b4b7e8-f116-415d-a50c-3364611b5d09",
|
||||
"key": "PortMirroringSwitchingProfile"
|
||||
},
|
||||
{
|
||||
"value": "fbc4fb17-83d9-4b53-a286-ccdf04301888",
|
||||
"key": "SwitchSecuritySwitchingProfile"
|
||||
},
|
||||
{
|
||||
"value": "f313290b-eba8-4262-bd93-fab5026e9495",
|
||||
"key": "QosSwitchingProfile"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
FAKE_QOS_PROFILE = {
|
||||
"resource_type": "QosSwitchingProfile",
|
||||
"id": uuidutils.generate_uuid(),
|
||||
"display_name": FAKE_NAME,
|
||||
"system_defined": False,
|
||||
"dscp": {
|
||||
"priority": 25,
|
||||
"mode": "UNTRUSTED"
|
||||
},
|
||||
"tags": [],
|
||||
"description": FAKE_NAME,
|
||||
"class_of_service": 0,
|
||||
"shaper_configuration": [
|
||||
{
|
||||
"resource_type": "IngressRateShaper",
|
||||
"enabled": False,
|
||||
"peak_bandwidth_mbps": 0,
|
||||
"burst_size_bytes": 0,
|
||||
"average_bandwidth_mbps": 0
|
||||
},
|
||||
{
|
||||
"resource_type": "IngressBroadcastRateShaper",
|
||||
"enabled": False,
|
||||
"peak_bandwidth_kbps": 0,
|
||||
"average_bandwidth_kbps": 0,
|
||||
"burst_size_bytes": 0
|
||||
},
|
||||
{
|
||||
"resource_type": "EgressRateShaper",
|
||||
"enabled": False,
|
||||
"peak_bandwidth_mbps": 0,
|
||||
"burst_size_bytes": 0,
|
||||
"average_bandwidth_mbps": 0
|
||||
}
|
||||
],
|
||||
"_last_modified_user": "admin",
|
||||
"_last_modified_time": 1438383180608,
|
||||
"_create_time": 1438383180608,
|
||||
"_create_user": "admin",
|
||||
"_revision": 0
|
||||
}
|
||||
|
||||
FAKE_ROUTER_UUID = uuidutils.generate_uuid()
|
||||
FAKE_ROUTER = {
|
||||
"resource_type": "LogicalRouter",
|
||||
"revision": 0,
|
||||
"id": FAKE_ROUTER_UUID,
|
||||
"display_name": FAKE_NAME
|
||||
}
|
||||
|
||||
FAKE_ROUTER_PORT_UUID = uuidutils.generate_uuid()
|
||||
FAKE_ROUTER_PORT = {
|
||||
"resource_type": "LogicalRouterLinkPort",
|
||||
"revision": 0,
|
||||
"id": FAKE_ROUTER_PORT_UUID,
|
||||
"display_name": FAKE_NAME,
|
||||
"logical_router_id": FAKE_ROUTER_UUID
|
||||
}
|
||||
|
@ -25,11 +25,12 @@ from oslo_config import cfg
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from vmware_nsx.common import exceptions as nsx_exc
|
||||
from vmware_nsx.common import nsx_constants
|
||||
from vmware_nsx.common import utils
|
||||
from vmware_nsx.db import db as nsx_db
|
||||
from vmware_nsx.extensions import advancedserviceproviders as as_providers
|
||||
from vmware_nsx.nsxlib.v3 import nsx_constants
|
||||
from vmware_nsx.nsxlib.v3 import resources as nsx_resources
|
||||
from vmware_nsx.nsxlib.v3 import utils as nsxlib_utils
|
||||
from vmware_nsx.tests.unit.nsx_v3 import test_plugin
|
||||
|
||||
|
||||
@ -456,7 +457,7 @@ class NsxNativeMetadataTestCase(test_plugin.NsxV3PluginTestCaseMixin):
|
||||
with self.network() as network:
|
||||
nsx_net_id = self.plugin._get_network_nsx_id(
|
||||
context.get_admin_context(), network['network']['id'])
|
||||
tags = utils.build_v3_tags_payload(
|
||||
tags = nsxlib_utils.build_v3_tags_payload(
|
||||
network['network'], resource_type='os-neutron-net-id',
|
||||
project_name=None)
|
||||
name = utils.get_name_and_uuid('%s-%s' % (
|
||||
|
@ -47,7 +47,7 @@ from vmware_nsx.common import utils
|
||||
from vmware_nsx.plugins.nsx_v3 import plugin as nsx_plugin
|
||||
from vmware_nsx.tests import unit as vmware
|
||||
from vmware_nsx.tests.unit.extensions import test_metadata
|
||||
from vmware_nsx.tests.unit.nsx_v3 import mocks as nsx_v3_mocks
|
||||
from vmware_nsx.tests.unit.nsxlib.v3 import mocks as nsx_v3_mocks
|
||||
from vmware_nsx.tests.unit.nsxlib.v3 import nsxlib_testcase
|
||||
|
||||
|
||||
|
@ -17,7 +17,7 @@ import six.moves.urllib.parse as urlparse
|
||||
|
||||
from oslo_serialization import jsonutils
|
||||
from oslo_utils import uuidutils
|
||||
from vmware_nsx.common import nsx_constants
|
||||
from vmware_nsx.nsxlib.v3 import nsx_constants
|
||||
|
||||
|
||||
FAKE_NAME = "fake_name"
|
||||
@ -135,7 +135,7 @@ class MockRequestSessionApi(object):
|
||||
|
||||
def _build_response(self, url, content=None,
|
||||
status=requests.codes.ok, **kwargs):
|
||||
if type(content) is list:
|
||||
if isinstance(content, list):
|
||||
content = {
|
||||
'result_count': len(content),
|
||||
'results': content
|
@ -45,14 +45,14 @@ def _mock_nsxlib():
|
||||
def _return_id_key(*args, **kwargs):
|
||||
return {'id': uuidutils.generate_uuid()}
|
||||
|
||||
# FIXME(arosen): this is duplicated in test_plugin
|
||||
def _mock_create_firewall_rules(*args):
|
||||
def _mock_add_rules_in_section(*args):
|
||||
# NOTE(arosen): the code in the neutron plugin expects the
|
||||
# neutron rule id as the display_name.
|
||||
rules = args[5]
|
||||
rules = args[0]
|
||||
return {
|
||||
'rules': [
|
||||
{'display_name': rule['id'], 'id': uuidutils.generate_uuid()}
|
||||
{'display_name': rule['display_name'],
|
||||
'id': uuidutils.generate_uuid()}
|
||||
for rule in rules
|
||||
]}
|
||||
|
||||
@ -70,15 +70,15 @@ def _mock_nsxlib():
|
||||
side_effect=_return_id_key).start()
|
||||
|
||||
mock.patch(
|
||||
"vmware_nsx.nsxlib.v3.NsxLib._init_default_section",
|
||||
"vmware_nsx.nsxlib.v3.NsxLib.init_default_section",
|
||||
side_effect=_return_id_key).start()
|
||||
|
||||
mock.patch(
|
||||
"vmware_nsx.nsxlib.v3.NsxLib.list_nsgroups").start()
|
||||
|
||||
mock.patch(
|
||||
"vmware_nsx.nsxlib.v3.NsxLib.create_firewall_rules",
|
||||
side_effect=_mock_create_firewall_rules).start()
|
||||
"vmware_nsx.nsxlib.v3.NsxLib.add_rules_in_section",
|
||||
side_effect=_mock_add_rules_in_section).start()
|
||||
|
||||
mock.patch(
|
||||
"vmware_nsx.nsxlib.v3.NsxLib.get_transport_zone_id_by_name_or_id",
|
||||
|
@ -20,7 +20,7 @@ from oslo_serialization import jsonutils
|
||||
|
||||
from vmware_nsx.nsxlib.v3 import client
|
||||
from vmware_nsx.nsxlib.v3 import exceptions as nsxlib_exc
|
||||
from vmware_nsx.tests.unit.nsx_v3 import mocks
|
||||
from vmware_nsx.tests.unit.nsxlib.v3 import mocks
|
||||
from vmware_nsx.tests.unit.nsxlib.v3 import nsxlib_testcase
|
||||
|
||||
|
||||
|
@ -23,7 +23,7 @@ from requests import exceptions as requests_exceptions
|
||||
from vmware_nsx.nsxlib.v3 import client
|
||||
from vmware_nsx.nsxlib.v3 import cluster
|
||||
from vmware_nsx.nsxlib.v3 import exceptions as nsxlib_exc
|
||||
from vmware_nsx.tests.unit.nsx_v3 import mocks
|
||||
from vmware_nsx.tests.unit.nsxlib.v3 import mocks
|
||||
from vmware_nsx.tests.unit.nsxlib.v3 import nsxlib_testcase
|
||||
|
||||
|
||||
|
162
vmware_nsx/tests/unit/nsxlib/v3/test_constants.py
Normal file
162
vmware_nsx/tests/unit/nsxlib/v3/test_constants.py
Normal file
@ -0,0 +1,162 @@
|
||||
# Copyright (c) 2016 VMware, Inc.
|
||||
#
|
||||
# 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_utils import uuidutils
|
||||
|
||||
FAKE_NAME = "fake_name"
|
||||
FAKE_SWITCH_UUID = uuidutils.generate_uuid()
|
||||
|
||||
FAKE_PORT_UUID = uuidutils.generate_uuid()
|
||||
FAKE_PORT = {
|
||||
"id": FAKE_PORT_UUID,
|
||||
"display_name": FAKE_NAME,
|
||||
"resource_type": "LogicalPort",
|
||||
"address_bindings": [],
|
||||
"logical_switch_id": FAKE_SWITCH_UUID,
|
||||
"admin_state": "UP",
|
||||
"attachment": {
|
||||
"id": "9ca8d413-f7bf-4276-b4c9-62f42516bdb2",
|
||||
"attachment_type": "VIF"
|
||||
},
|
||||
"switching_profile_ids": [
|
||||
{
|
||||
"value": "64814784-7896-3901-9741-badeff705639",
|
||||
"key": "IpDiscoverySwitchingProfile"
|
||||
},
|
||||
{
|
||||
"value": "fad98876-d7ff-11e4-b9d6-1681e6b88ec1",
|
||||
"key": "SpoofGuardSwitchingProfile"
|
||||
},
|
||||
{
|
||||
"value": "93b4b7e8-f116-415d-a50c-3364611b5d09",
|
||||
"key": "PortMirroringSwitchingProfile"
|
||||
},
|
||||
{
|
||||
"value": "fbc4fb17-83d9-4b53-a286-ccdf04301888",
|
||||
"key": "SwitchSecuritySwitchingProfile"
|
||||
},
|
||||
{
|
||||
"value": "f313290b-eba8-4262-bd93-fab5026e9495",
|
||||
"key": "QosSwitchingProfile"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
FAKE_CONTAINER_PORT = {
|
||||
"id": FAKE_PORT_UUID,
|
||||
"display_name": FAKE_NAME,
|
||||
"resource_type": "LogicalPort",
|
||||
"address_bindings": [
|
||||
{
|
||||
"ip_address": "192.168.1.110",
|
||||
"mac_address": "aa:bb:cc:dd:ee:ff"
|
||||
}
|
||||
],
|
||||
"logical_switch_id": FAKE_SWITCH_UUID,
|
||||
"admin_state": "UP",
|
||||
"attachment": {
|
||||
"id": "9ca8d413-f7bf-4276-b4c9-62f42516bdb2",
|
||||
"attachment_type": "CIF",
|
||||
"context": {
|
||||
"vlan_tag": 122,
|
||||
"container_host_vif_id": "c6f817a0-4e36-421e-98a6-8a2faed880bc",
|
||||
"key_values": [],
|
||||
"resource_type": "CifAttachmentContext",
|
||||
}
|
||||
},
|
||||
"switching_profile_ids": [
|
||||
{
|
||||
"value": "64814784-7896-3901-9741-badeff705639",
|
||||
"key": "IpDiscoverySwitchingProfile"
|
||||
},
|
||||
{
|
||||
"value": "fad98876-d7ff-11e4-b9d6-1681e6b88ec1",
|
||||
"key": "SpoofGuardSwitchingProfile"
|
||||
},
|
||||
{
|
||||
"value": "93b4b7e8-f116-415d-a50c-3364611b5d09",
|
||||
"key": "PortMirroringSwitchingProfile"
|
||||
},
|
||||
{
|
||||
"value": "fbc4fb17-83d9-4b53-a286-ccdf04301888",
|
||||
"key": "SwitchSecuritySwitchingProfile"
|
||||
},
|
||||
{
|
||||
"value": "f313290b-eba8-4262-bd93-fab5026e9495",
|
||||
"key": "QosSwitchingProfile"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
FAKE_ROUTER_UUID = uuidutils.generate_uuid()
|
||||
FAKE_ROUTER = {
|
||||
"resource_type": "LogicalRouter",
|
||||
"revision": 0,
|
||||
"id": FAKE_ROUTER_UUID,
|
||||
"display_name": FAKE_NAME
|
||||
}
|
||||
|
||||
FAKE_ROUTER_PORT_UUID = uuidutils.generate_uuid()
|
||||
FAKE_ROUTER_PORT = {
|
||||
"resource_type": "LogicalRouterLinkPort",
|
||||
"revision": 0,
|
||||
"id": FAKE_ROUTER_PORT_UUID,
|
||||
"display_name": FAKE_NAME,
|
||||
"logical_router_id": FAKE_ROUTER_UUID
|
||||
}
|
||||
|
||||
FAKE_QOS_PROFILE = {
|
||||
"resource_type": "QosSwitchingProfile",
|
||||
"id": uuidutils.generate_uuid(),
|
||||
"display_name": FAKE_NAME,
|
||||
"system_defined": False,
|
||||
"dscp": {
|
||||
"priority": 25,
|
||||
"mode": "UNTRUSTED"
|
||||
},
|
||||
"tags": [],
|
||||
"description": FAKE_NAME,
|
||||
"class_of_service": 0,
|
||||
"shaper_configuration": [
|
||||
{
|
||||
"resource_type": "IngressRateShaper",
|
||||
"enabled": False,
|
||||
"peak_bandwidth_mbps": 0,
|
||||
"burst_size_bytes": 0,
|
||||
"average_bandwidth_mbps": 0
|
||||
},
|
||||
{
|
||||
"resource_type": "IngressBroadcastRateShaper",
|
||||
"enabled": False,
|
||||
"peak_bandwidth_kbps": 0,
|
||||
"average_bandwidth_kbps": 0,
|
||||
"burst_size_bytes": 0
|
||||
},
|
||||
{
|
||||
"resource_type": "EgressRateShaper",
|
||||
"enabled": False,
|
||||
"peak_bandwidth_mbps": 0,
|
||||
"burst_size_bytes": 0,
|
||||
"average_bandwidth_mbps": 0
|
||||
}
|
||||
],
|
||||
"_last_modified_user": "admin",
|
||||
"_last_modified_time": 1438383180608,
|
||||
"_create_time": 1438383180608,
|
||||
"_create_user": "admin",
|
||||
"_revision": 0
|
||||
}
|
@ -17,8 +17,8 @@ import mock
|
||||
|
||||
from oslo_log import log
|
||||
|
||||
from vmware_nsx.tests.unit.nsx_v3 import test_constants as test_constants_v3
|
||||
from vmware_nsx.tests.unit.nsxlib.v3 import nsxlib_testcase
|
||||
from vmware_nsx.tests.unit.nsxlib.v3 import test_constants as test_constants_v3
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
@ -20,10 +20,10 @@ import mock
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
from vmware_nsx.nsxlib.v3 import resources
|
||||
from vmware_nsx.tests.unit.nsx_v3 import mocks
|
||||
from vmware_nsx.tests.unit.nsx_v3 import test_constants as test_constants_v3
|
||||
from vmware_nsx.tests.unit.nsxlib.v3 import mocks
|
||||
from vmware_nsx.tests.unit.nsxlib.v3 import nsxlib_testcase
|
||||
from vmware_nsx.tests.unit.nsxlib.v3 import test_client
|
||||
from vmware_nsx.tests.unit.nsxlib.v3 import test_constants as test_constants_v3
|
||||
|
||||
|
||||
CLIENT_PKG = test_client.CLIENT_PKG
|
||||
|
@ -17,8 +17,8 @@
|
||||
import mock
|
||||
from oslo_log import log
|
||||
|
||||
from vmware_nsx.common import nsx_constants
|
||||
from vmware_nsx.tests.unit.nsx_v3 import mocks as nsx_v3_mocks
|
||||
from vmware_nsx.nsxlib.v3 import nsx_constants
|
||||
from vmware_nsx.tests.unit.nsxlib.v3 import mocks as nsx_v3_mocks
|
||||
from vmware_nsx.tests.unit.nsxlib.v3 import nsxlib_testcase
|
||||
|
||||
|
||||
|
@ -13,14 +13,16 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from neutron.tests.unit.db import test_db_base_plugin_v2 as test_plugin
|
||||
from neutron import version
|
||||
from neutron_lib import exceptions as n_exc
|
||||
|
||||
from vmware_nsx.common import utils
|
||||
from vmware_nsx.tests.unit.nsx_v3 import test_plugin
|
||||
from vmware_nsx.nsxlib.v3 import utils
|
||||
from vmware_nsx.tests.unit.nsxlib.v3 import nsxlib_testcase
|
||||
|
||||
|
||||
class TestNsxV3Utils(test_plugin.NsxV3PluginTestCaseMixin):
|
||||
class TestNsxV3Utils(test_plugin.NeutronDbPluginV2TestCase,
|
||||
nsxlib_testcase.NsxClientTestCase):
|
||||
|
||||
def test_build_v3_tags_payload(self):
|
||||
result = utils.build_v3_tags_payload(
|
@ -31,10 +31,10 @@ from neutron import context
|
||||
from neutron.tests import base
|
||||
|
||||
from neutron_lib import exceptions as n_exc
|
||||
from vmware_nsx.common import nsx_constants
|
||||
from vmware_nsx.nsxlib.v3 import nsx_constants
|
||||
from vmware_nsx.services.l2gateway.nsx_v3 import driver as nsx_v3_driver
|
||||
from vmware_nsx.tests.unit.nsx_v3 import mocks as nsx_v3_mocks
|
||||
from vmware_nsx.tests.unit.nsx_v3 import test_plugin as test_nsx_v3_plugin
|
||||
from vmware_nsx.tests.unit.nsxlib.v3 import mocks as nsx_v3_mocks
|
||||
|
||||
|
||||
NSX_V3_PLUGIN_CLASS = ('vmware_nsx.plugins.nsx_v3.plugin.NsxV3Plugin')
|
||||
|
@ -24,8 +24,8 @@ from neutron.objects.qos import rule as rule_object
|
||||
from neutron.services.qos import qos_plugin
|
||||
from neutron.tests.unit.services.qos import base
|
||||
|
||||
from vmware_nsx.common import utils
|
||||
from vmware_nsx.db import db as nsx_db
|
||||
from vmware_nsx.nsxlib.v3 import utils
|
||||
from vmware_nsx.services.qos.nsx_v3 import utils as qos_utils
|
||||
from vmware_nsx.tests.unit.nsx_v3 import test_plugin
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user