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
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# 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
|
# L2 agent vif type
|
||||||
VIF_TYPE_DVS = 'dvs'
|
VIF_TYPE_DVS = 'dvs'
|
||||||
|
|
||||||
# NSXv3 L2 Gateway constants
|
|
||||||
BRIDGE_ENDPOINT = "BRIDGEENDPOINT"
|
|
||||||
|
|
||||||
# NSX service type
|
|
||||||
SERVICE_DHCP = "dhcp"
|
|
||||||
|
|
||||||
# NSXv3 CORE PLUGIN PATH
|
# NSXv3 CORE PLUGIN PATH
|
||||||
VMWARE_NSX_V3_PLUGIN_NAME = 'vmware_nsx.plugin.NsxV3Plugin'
|
VMWARE_NSX_V3_PLUGIN_NAME = 'vmware_nsx.plugin.NsxV3Plugin'
|
||||||
|
@ -18,25 +18,20 @@ import functools
|
|||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
import eventlet
|
import eventlet
|
||||||
|
import six
|
||||||
|
|
||||||
from neutron import version as n_version
|
from neutron import version as n_version
|
||||||
from neutron_lib.api import validators
|
from neutron_lib.api import validators
|
||||||
from neutron_lib import constants
|
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_context import context as common_context
|
||||||
from oslo_log import log
|
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__)
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
MAX_DISPLAY_NAME_LEN = 40
|
MAX_DISPLAY_NAME_LEN = 40
|
||||||
MAX_RESOURCE_TYPE_LEN = 20
|
|
||||||
MAX_TAG_LEN = 40
|
|
||||||
NEUTRON_VERSION = n_version.version_info.release_string()
|
NEUTRON_VERSION = n_version.version_info.release_string()
|
||||||
NSX_NEUTRON_PLUGIN = 'NSX Neutron plugin'
|
|
||||||
OS_NEUTRON_ID_SCOPE = 'os-neutron-id'
|
OS_NEUTRON_ID_SCOPE = 'os-neutron-id'
|
||||||
NSXV3_VERSION_1_1_0 = '1.1.0'
|
NSXV3_VERSION_1_1_0 = '1.1.0'
|
||||||
|
|
||||||
@ -111,137 +106,6 @@ def check_and_truncate(display_name):
|
|||||||
return display_name or ''
|
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):
|
def read_file(path):
|
||||||
try:
|
try:
|
||||||
with open(path) as file:
|
with open(path) as file:
|
||||||
|
@ -14,10 +14,12 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import six
|
||||||
|
from sqlalchemy.orm import exc
|
||||||
|
|
||||||
from oslo_db import exception as db_exc
|
from oslo_db import exception as db_exc
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
from oslo_utils import excutils
|
from oslo_utils import excutils
|
||||||
from sqlalchemy.orm import exc
|
|
||||||
|
|
||||||
import neutron.db.api as db
|
import neutron.db.api as db
|
||||||
|
|
||||||
@ -27,6 +29,20 @@ from vmware_nsx.db import nsx_models
|
|||||||
LOG = logging.getLogger(__name__)
|
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):
|
def get_network_bindings(session, network_id):
|
||||||
session = session or db.get_session()
|
session = session or db.get_session()
|
||||||
return (session.query(nsx_models.TzNetworkBinding).
|
return (session.query(nsx_models.TzNetworkBinding).
|
||||||
@ -247,6 +263,19 @@ def get_nsx_security_group_id(session, neutron_id):
|
|||||||
return None
|
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):
|
def _delete_by_neutron_id(session, model, neutron_id):
|
||||||
return session.query(model).filter_by(neutron_id=neutron_id).delete()
|
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))
|
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):
|
def get_sg_rule_mapping(session, rule_id):
|
||||||
rule_mapping = session.query(
|
rule_mapping = session.query(
|
||||||
nsx_models.NeutronNsxRuleMapping).filter_by(
|
nsx_models.NeutronNsxRuleMapping).filter_by(
|
||||||
neutron_id=rule_id).one()
|
neutron_id=rule_id).one()
|
||||||
return rule_mapping.nsx_id
|
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
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
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(
|
nsx_service_type_enum = sa.Enum(
|
||||||
|
@ -27,7 +27,7 @@ from sqlalchemy import sql
|
|||||||
from neutron.db import models_v2
|
from neutron.db import models_v2
|
||||||
from oslo_db.sqlalchemy import models
|
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):
|
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._i18n import _, _LE, _LW
|
||||||
from vmware_nsx.common import exceptions as nsx_exc
|
from vmware_nsx.common import exceptions as nsx_exc
|
||||||
from vmware_nsx.common import nsxv_constants
|
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.db import nsxv_models
|
||||||
from vmware_nsx.extensions import dhcp_mtu as ext_dhcp_mtu
|
from vmware_nsx.extensions import dhcp_mtu as ext_dhcp_mtu
|
||||||
from vmware_nsx.extensions import dns_search_domain as ext_dns_search_domain
|
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__)
|
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,
|
def add_nsxv_router_binding(session, router_id, vse_id, lswitch_id, status,
|
||||||
appliance_size=nsxv_constants.LARGE,
|
appliance_size=nsxv_constants.LARGE,
|
||||||
edge_type=nsxv_constants.SERVICE_EDGE,
|
edge_type=nsxv_constants.SERVICE_EDGE,
|
||||||
@ -117,7 +104,7 @@ def get_nsxv_router_bindings(session, filters=None,
|
|||||||
like_filters=None):
|
like_filters=None):
|
||||||
session = db.get_session()
|
session = db.get_session()
|
||||||
query = session.query(nsxv_models.NsxvRouterBinding)
|
query = session.query(nsxv_models.NsxvRouterBinding)
|
||||||
return _apply_filters_to_query(query, nsxv_models.NsxvRouterBinding,
|
return nsx_db._apply_filters_to_query(query, nsxv_models.NsxvRouterBinding,
|
||||||
filters, like_filters).all()
|
filters, like_filters).all()
|
||||||
|
|
||||||
|
|
||||||
@ -586,7 +573,7 @@ def get_nsxv_spoofguard_policy_network_mappings(session, filters=None,
|
|||||||
like_filters=None):
|
like_filters=None):
|
||||||
session = db.get_session()
|
session = db.get_session()
|
||||||
query = session.query(nsxv_models.NsxvSpoofGuardPolicyNetworkMapping)
|
query = session.query(nsxv_models.NsxvSpoofGuardPolicyNetworkMapping)
|
||||||
return _apply_filters_to_query(
|
return nsx_db._apply_filters_to_query(
|
||||||
query, nsxv_models.NsxvSpoofGuardPolicyNetworkMapping,
|
query, nsxv_models.NsxvSpoofGuardPolicyNetworkMapping,
|
||||||
filters, like_filters).all()
|
filters, like_filters).all()
|
||||||
|
|
||||||
|
@ -16,23 +16,17 @@
|
|||||||
from oslo_log import log
|
from oslo_log import log
|
||||||
|
|
||||||
from vmware_nsx._i18n import _, _LW
|
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 client
|
||||||
from vmware_nsx.nsxlib.v3 import cluster
|
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 exceptions
|
||||||
|
from vmware_nsx.nsxlib.v3 import nsx_constants
|
||||||
from vmware_nsx.nsxlib.v3 import security
|
from vmware_nsx.nsxlib.v3 import security
|
||||||
|
from vmware_nsx.nsxlib.v3 import utils
|
||||||
|
|
||||||
LOG = log.getLogger(__name__)
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
# Max amount of time to try a request
|
|
||||||
DEFAULT_MAX_ATTEMPTS = 3
|
|
||||||
|
|
||||||
|
class NsxLib(security.Security):
|
||||||
class NsxLib(dfw_api.DfwApi, security.Security):
|
|
||||||
|
|
||||||
MAX_ATTEMPTS = DEFAULT_MAX_ATTEMPTS
|
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
username=None,
|
username=None,
|
||||||
@ -45,9 +39,11 @@ class NsxLib(dfw_api.DfwApi, security.Security):
|
|||||||
http_read_timeout=None,
|
http_read_timeout=None,
|
||||||
conn_idle_timeout=None,
|
conn_idle_timeout=None,
|
||||||
http_provider=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(
|
self.cluster = cluster.NSXClusteredAPI(
|
||||||
username=username, password=password,
|
username=username, password=password,
|
||||||
retries=retries, insecure=insecure,
|
retries=retries, insecure=insecure,
|
||||||
@ -58,7 +54,9 @@ class NsxLib(dfw_api.DfwApi, security.Security):
|
|||||||
conn_idle_timeout=conn_idle_timeout,
|
conn_idle_timeout=conn_idle_timeout,
|
||||||
http_provider=http_provider)
|
http_provider=http_provider)
|
||||||
|
|
||||||
|
# create the Client
|
||||||
self.client = client.NSX3Client(self.cluster)
|
self.client = client.NSX3Client(self.cluster)
|
||||||
|
|
||||||
super(NsxLib, self).__init__()
|
super(NsxLib, self).__init__()
|
||||||
|
|
||||||
def get_version(self):
|
def get_version(self):
|
||||||
@ -70,7 +68,7 @@ class NsxLib(dfw_api.DfwApi, security.Security):
|
|||||||
resource = "edge-clusters/%s" % edge_cluster_uuid
|
resource = "edge-clusters/%s" % edge_cluster_uuid
|
||||||
return self.client.get(resource)
|
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):
|
def update_resource_with_retry(self, resource, payload):
|
||||||
revised_payload = self.client.get(resource)
|
revised_payload = self.client.get(resource)
|
||||||
for key_name in payload.keys():
|
for key_name in payload.keys():
|
||||||
@ -128,8 +126,7 @@ class NsxLib(dfw_api.DfwApi, security.Security):
|
|||||||
|
|
||||||
return self.client.create(resource, body)
|
return self.client.create(resource, body)
|
||||||
|
|
||||||
@utils.retry_upon_exception_nsxv3(exceptions.StaleRevision,
|
@utils.retry_upon_exception(exceptions.StaleRevision)
|
||||||
max_attempts=MAX_ATTEMPTS)
|
|
||||||
def delete_logical_switch(self, lswitch_id):
|
def delete_logical_switch(self, lswitch_id):
|
||||||
resource = 'logical-switches/%s?detach=true&cascade=true' % lswitch_id
|
resource = 'logical-switches/%s?detach=true&cascade=true' % lswitch_id
|
||||||
self.client.delete(resource)
|
self.client.delete(resource)
|
||||||
@ -138,8 +135,7 @@ class NsxLib(dfw_api.DfwApi, security.Security):
|
|||||||
resource = "logical-switches/%s" % logical_switch_id
|
resource = "logical-switches/%s" % logical_switch_id
|
||||||
return self.client.get(resource)
|
return self.client.get(resource)
|
||||||
|
|
||||||
@utils.retry_upon_exception_nsxv3(exceptions.StaleRevision,
|
@utils.retry_upon_exception(exceptions.StaleRevision)
|
||||||
max_attempts=MAX_ATTEMPTS)
|
|
||||||
def update_logical_switch(self, lswitch_id, name=None, admin_state=None,
|
def update_logical_switch(self, lswitch_id, name=None, admin_state=None,
|
||||||
tags=None):
|
tags=None):
|
||||||
resource = "logical-switches/%s" % lswitch_id
|
resource = "logical-switches/%s" % lswitch_id
|
||||||
@ -346,12 +342,12 @@ class NsxLib(dfw_api.DfwApi, security.Security):
|
|||||||
if len(matched_results) == 0:
|
if len(matched_results) == 0:
|
||||||
err_msg = (_("Could not find %(resource)s %(name)s") %
|
err_msg = (_("Could not find %(resource)s %(name)s") %
|
||||||
{'name': name_or_id, 'resource': resource})
|
{'name': name_or_id, 'resource': resource})
|
||||||
# XXX improve exception handling...
|
# TODO(asarfaty): improve exception handling...
|
||||||
raise exceptions.ManagerError(details=err_msg)
|
raise exceptions.ManagerError(details=err_msg)
|
||||||
elif len(matched_results) > 1:
|
elif len(matched_results) > 1:
|
||||||
err_msg = (_("Found multiple %(resource)s named %(name)s") %
|
err_msg = (_("Found multiple %(resource)s named %(name)s") %
|
||||||
{'name': name_or_id, 'resource': resource})
|
{'name': name_or_id, 'resource': resource})
|
||||||
# XXX improve exception handling...
|
# TODO(asarfaty): improve exception handling...
|
||||||
raise exceptions.ManagerError(details=err_msg)
|
raise exceptions.ManagerError(details=err_msg)
|
||||||
|
|
||||||
return matched_results[0].get('id')
|
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 neutron_lib import constants
|
||||||
from oslo_config import cfg
|
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):
|
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 oslo_log import log
|
||||||
|
|
||||||
from vmware_nsx._i18n import _, _LW
|
from vmware_nsx._i18n import _, _LW
|
||||||
from vmware_nsx.common import utils
|
|
||||||
from vmware_nsx.nsxlib import v3
|
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 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__)
|
LOG = log.getLogger(__name__)
|
||||||
@ -40,7 +40,7 @@ class NSGroupManager(object):
|
|||||||
are also of type NSGroups) to group the other NSGroups and associate it
|
are also of type NSGroups) to group the other NSGroups and associate it
|
||||||
with these rules.
|
with these rules.
|
||||||
In practice, one NSGroup (nested) can't contain all the other NSGroups, as
|
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
|
create several nested groups instead of just one, and we evenly distribute
|
||||||
NSGroups (security-groups) between them.
|
NSGroups (security-groups) between them.
|
||||||
By using an hashing function on the NSGroup uuid we determine in which
|
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.')
|
NESTED_GROUP_DESCRIPTION = ('OpenStack NSGroup. Do not delete.')
|
||||||
|
|
||||||
def __init__(self, size):
|
def __init__(self, size):
|
||||||
# XXX intergrate this in a better way..
|
# TODO(asarfaty): integrate this in a better way..
|
||||||
self.nsx = v3.NsxLib(
|
self.nsx = v3.NsxLib(
|
||||||
username=cfg.CONF.nsx_v3.nsx_api_user,
|
username=cfg.CONF.nsx_v3.nsx_api_user,
|
||||||
password=cfg.CONF.nsx_v3.nsx_api_password,
|
password=cfg.CONF.nsx_v3.nsx_api_password,
|
||||||
@ -84,7 +84,7 @@ class NSGroupManager(object):
|
|||||||
nested_groups = {
|
nested_groups = {
|
||||||
self._get_nested_group_index_from_name(nsgroup): nsgroup['id']
|
self._get_nested_group_index_from_name(nsgroup): nsgroup['id']
|
||||||
for nsgroup in self.nsx.list_nsgroups()
|
for nsgroup in self.nsx.list_nsgroups()
|
||||||
if utils.is_internal_resource(nsgroup)}
|
if nsxlib_utils.is_internal_resource(nsgroup)}
|
||||||
|
|
||||||
if nested_groups:
|
if nested_groups:
|
||||||
size = max(requested_size, max(nested_groups) + 1)
|
size = max(requested_size, max(nested_groups) + 1)
|
||||||
@ -115,7 +115,7 @@ class NSGroupManager(object):
|
|||||||
name_prefix = NSGroupManager.NESTED_GROUP_NAME
|
name_prefix = NSGroupManager.NESTED_GROUP_NAME
|
||||||
name = '%s %s' % (name_prefix, index + 1)
|
name = '%s %s' % (name_prefix, index + 1)
|
||||||
description = NSGroupManager.NESTED_GROUP_DESCRIPTION
|
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)
|
return self.nsx.create_nsgroup(name, description, tags)
|
||||||
|
|
||||||
def _hash_uuid(self, internal_id):
|
def _hash_uuid(self, internal_id):
|
||||||
@ -138,7 +138,7 @@ class NSGroupManager(object):
|
|||||||
LOG.debug("Adding NSGroup %s to nested group %s",
|
LOG.debug("Adding NSGroup %s to nested group %s",
|
||||||
nsgroup_id, group)
|
nsgroup_id, group)
|
||||||
self.nsx.add_nsgroup_members(group,
|
self.nsx.add_nsgroup_members(group,
|
||||||
firewall.NSGROUP,
|
consts.NSGROUP,
|
||||||
[nsgroup_id])
|
[nsgroup_id])
|
||||||
break
|
break
|
||||||
except exceptions.NSGroupIsFull:
|
except exceptions.NSGroupIsFull:
|
||||||
@ -153,7 +153,8 @@ class NSGroupManager(object):
|
|||||||
for group in self._suggest_nested_group(nsgroup_id):
|
for group in self._suggest_nested_group(nsgroup_id):
|
||||||
try:
|
try:
|
||||||
self.nsx.remove_nsgroup_member(
|
self.nsx.remove_nsgroup_member(
|
||||||
group, firewall.NSGROUP, nsgroup_id, verify=True)
|
group, consts.NSGROUP,
|
||||||
|
nsgroup_id, verify=True)
|
||||||
break
|
break
|
||||||
except exceptions.NSGroupMemberNotFound:
|
except exceptions.NSGroupMemberNotFound:
|
||||||
LOG.warning(_LW("NSGroup %(nsgroup)s was expected to be found "
|
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 oslo_config import cfg
|
||||||
|
|
||||||
from vmware_nsx._i18n import _
|
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 client
|
||||||
from vmware_nsx.nsxlib.v3 import exceptions
|
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(
|
SwitchingProfileTypeId = collections.namedtuple(
|
||||||
@ -285,13 +285,13 @@ class LogicalPort(AbstractRESTResource):
|
|||||||
attachment=attachment))
|
attachment=attachment))
|
||||||
return self._client.create(body=body)
|
return self._client.create(body=body)
|
||||||
|
|
||||||
@utils.retry_upon_exception_nsxv3(
|
@utils.retry_upon_exception(
|
||||||
exceptions.StaleRevision,
|
exceptions.StaleRevision,
|
||||||
max_attempts=cfg.CONF.nsx_v3.retries)
|
max_attempts=cfg.CONF.nsx_v3.retries)
|
||||||
def delete(self, lport_id):
|
def delete(self, lport_id):
|
||||||
return self._client.url_delete('%s?detach=true' % lport_id)
|
return self._client.url_delete('%s?detach=true' % lport_id)
|
||||||
|
|
||||||
@utils.retry_upon_exception_nsxv3(
|
@utils.retry_upon_exception(
|
||||||
exceptions.StaleRevision,
|
exceptions.StaleRevision,
|
||||||
max_attempts=cfg.CONF.nsx_v3.retries)
|
max_attempts=cfg.CONF.nsx_v3.retries)
|
||||||
def update(self, lport_id, vif_uuid,
|
def update(self, lport_id, vif_uuid,
|
||||||
@ -342,7 +342,7 @@ class LogicalRouter(AbstractRESTResource):
|
|||||||
def delete(self, lrouter_id):
|
def delete(self, lrouter_id):
|
||||||
return self._client.url_delete(lrouter_id)
|
return self._client.url_delete(lrouter_id)
|
||||||
|
|
||||||
@utils.retry_upon_exception_nsxv3(
|
@utils.retry_upon_exception(
|
||||||
exceptions.StaleRevision,
|
exceptions.StaleRevision,
|
||||||
max_attempts=cfg.CONF.nsx_v3.retries)
|
max_attempts=cfg.CONF.nsx_v3.retries)
|
||||||
def update(self, lrouter_id, *args, **kwargs):
|
def update(self, lrouter_id, *args, **kwargs):
|
||||||
@ -389,7 +389,7 @@ class LogicalRouterPort(AbstractRESTResource):
|
|||||||
|
|
||||||
return self._client.create(body=body)
|
return self._client.create(body=body)
|
||||||
|
|
||||||
@utils.retry_upon_exception_nsxv3(
|
@utils.retry_upon_exception(
|
||||||
exceptions.StaleRevision,
|
exceptions.StaleRevision,
|
||||||
max_attempts=cfg.CONF.nsx_v3.retries)
|
max_attempts=cfg.CONF.nsx_v3.retries)
|
||||||
def update(self, logical_port_id, **kwargs):
|
def update(self, logical_port_id, **kwargs):
|
||||||
@ -402,7 +402,7 @@ class LogicalRouterPort(AbstractRESTResource):
|
|||||||
# new revision_id
|
# new revision_id
|
||||||
return self._client.update(logical_port_id, body=logical_router_port)
|
return self._client.update(logical_port_id, body=logical_router_port)
|
||||||
|
|
||||||
@utils.retry_upon_exception_nsxv3(
|
@utils.retry_upon_exception(
|
||||||
exceptions.StaleRevision,
|
exceptions.StaleRevision,
|
||||||
max_attempts=cfg.CONF.nsx_v3.retries)
|
max_attempts=cfg.CONF.nsx_v3.retries)
|
||||||
def delete(self, logical_port_id):
|
def delete(self, logical_port_id):
|
||||||
@ -511,7 +511,7 @@ class LogicalDhcpServer(AbstractRESTResource):
|
|||||||
options, tags)
|
options, tags)
|
||||||
return self._client.create(body=body)
|
return self._client.create(body=body)
|
||||||
|
|
||||||
@utils.retry_upon_exception_nsxv3(
|
@utils.retry_upon_exception(
|
||||||
exceptions.StaleRevision,
|
exceptions.StaleRevision,
|
||||||
max_attempts=cfg.CONF.nsx_v3.retries)
|
max_attempts=cfg.CONF.nsx_v3.retries)
|
||||||
def update(self, uuid, dhcp_profile_id=None, server_ip=None, name=None,
|
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)
|
url = "%s/static-bindings/%s" % (server_uuid, binding_uuid)
|
||||||
return self._client.url_get(url)
|
return self._client.url_get(url)
|
||||||
|
|
||||||
@utils.retry_upon_exception_nsxv3(
|
@utils.retry_upon_exception(
|
||||||
exceptions.StaleRevision,
|
exceptions.StaleRevision,
|
||||||
max_attempts=cfg.CONF.nsx_v3.retries)
|
max_attempts=cfg.CONF.nsx_v3.retries)
|
||||||
def update_binding(self, server_uuid, binding_uuid, **kwargs):
|
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 oslo_log import log
|
||||||
|
|
||||||
from vmware_nsx._i18n import _, _LW
|
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 exceptions
|
||||||
|
from vmware_nsx.nsxlib.v3 import nsx_constants
|
||||||
|
from vmware_nsx.nsxlib.v3 import utils
|
||||||
|
|
||||||
LOG = log.getLogger(__name__)
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -15,34 +15,27 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
NSX-V3 Plugin security integration module
|
NSX-V3 Plugin security integration & Distributed Firewall module
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from neutron_lib import constants
|
from neutron_lib import constants
|
||||||
from oslo_config import cfg
|
|
||||||
from oslo_log import log
|
from oslo_log import log
|
||||||
from oslo_utils import excutils
|
from oslo_utils import excutils
|
||||||
|
|
||||||
from vmware_nsx._i18n import _LE
|
from vmware_nsx._i18n import _LE, _LW
|
||||||
from vmware_nsx.common import utils
|
from vmware_nsx.nsxlib.v3 import client as nsxclient
|
||||||
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.nsxlib.v3 import exceptions
|
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__)
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
DEFAULT_SECTION = 'OS Default Section for Neutron Security-Groups'
|
DEFAULT_SECTION = 'OS Default Section for Neutron Security-Groups'
|
||||||
DEFAULT_SECTION_TAG_NAME = 'neutron_default_dfw_section'
|
|
||||||
PORT_SG_SCOPE = 'os-security-group'
|
PORT_SG_SCOPE = 'os-security-group'
|
||||||
|
|
||||||
MAX_NSGROUPS_CRITERIA_TAGS = 10
|
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):
|
class Security(object):
|
||||||
|
|
||||||
def _get_l4_protocol_name(self, protocol_number):
|
def _get_l4_protocol_name(self, protocol_number):
|
||||||
@ -52,24 +45,26 @@ class Security(object):
|
|||||||
protocol_number)
|
protocol_number)
|
||||||
protocol_number = int(protocol_number)
|
protocol_number = int(protocol_number)
|
||||||
if protocol_number == 6:
|
if protocol_number == 6:
|
||||||
return firewall.TCP
|
return consts.TCP
|
||||||
elif protocol_number == 17:
|
elif protocol_number == 17:
|
||||||
return firewall.UDP
|
return consts.UDP
|
||||||
elif protocol_number == 1:
|
elif protocol_number == 1:
|
||||||
return firewall.ICMPV4
|
return consts.ICMPV4
|
||||||
else:
|
else:
|
||||||
return protocol_number
|
return protocol_number
|
||||||
|
|
||||||
def _get_direction(self, sg_rule):
|
def _get_direction(self, sg_rule):
|
||||||
return (
|
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):
|
def _decide_service(self, sg_rule):
|
||||||
l4_protocol = self._get_l4_protocol_name(sg_rule['protocol'])
|
l4_protocol = self._get_l4_protocol_name(sg_rule['protocol'])
|
||||||
direction = self._get_direction(sg_rule)
|
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
|
# If port_range_min is not specified then we assume all ports are
|
||||||
# matched, relying on neutron to perform validation.
|
# matched, relying on neutron to perform validation.
|
||||||
source_ports = []
|
source_ports = []
|
||||||
@ -82,20 +77,23 @@ class Security(object):
|
|||||||
else:
|
else:
|
||||||
destination_ports = ['%(port_range_min)s' % sg_rule]
|
destination_ports = ['%(port_range_min)s' % sg_rule]
|
||||||
|
|
||||||
if direction == firewall.OUT:
|
if direction == consts.OUT:
|
||||||
source_ports, destination_ports = destination_ports, []
|
source_ports, destination_ports = destination_ports, []
|
||||||
|
|
||||||
return self.get_nsservice(firewall.L4_PORT_SET_NSSERVICE,
|
return self.get_nsservice(
|
||||||
|
consts.L4_PORT_SET_NSSERVICE,
|
||||||
l4_protocol=l4_protocol,
|
l4_protocol=l4_protocol,
|
||||||
source_ports=source_ports,
|
source_ports=source_ports,
|
||||||
destination_ports=destination_ports)
|
destination_ports=destination_ports)
|
||||||
elif l4_protocol == firewall.ICMPV4:
|
elif l4_protocol == consts.ICMPV4:
|
||||||
return self.get_nsservice(firewall.ICMP_TYPE_NSSERVICE,
|
return self.get_nsservice(
|
||||||
|
consts.ICMP_TYPE_NSSERVICE,
|
||||||
protocol=l4_protocol,
|
protocol=l4_protocol,
|
||||||
icmp_type=sg_rule['port_range_min'],
|
icmp_type=sg_rule['port_range_min'],
|
||||||
icmp_code=sg_rule['port_range_max'])
|
icmp_code=sg_rule['port_range_max'])
|
||||||
elif l4_protocol is not None:
|
elif l4_protocol is not None:
|
||||||
return self.get_nsservice(firewall.IP_PROTOCOL_NSSERVICE,
|
return self.get_nsservice(
|
||||||
|
consts.IP_PROTOCOL_NSSERVICE,
|
||||||
protocol_number=l4_protocol)
|
protocol_number=l4_protocol)
|
||||||
|
|
||||||
def _get_fw_rule_from_sg_rule(self, sg_rule, nsgroup_id, rmt_nsgroup_id,
|
def _get_fw_rule_from_sg_rule(self, sg_rule, nsgroup_id, rmt_nsgroup_id,
|
||||||
@ -104,9 +102,9 @@ class Security(object):
|
|||||||
ip_protocol = sg_rule['ethertype'].upper()
|
ip_protocol = sg_rule['ethertype'].upper()
|
||||||
direction = self._get_direction(sg_rule)
|
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(
|
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)
|
ip_protocol)
|
||||||
else:
|
else:
|
||||||
local_ip_prefix = None
|
local_ip_prefix = None
|
||||||
@ -121,7 +119,7 @@ class Security(object):
|
|||||||
if rmt_nsgroup_id:
|
if rmt_nsgroup_id:
|
||||||
source = self.get_nsgroup_reference(rmt_nsgroup_id)
|
source = self.get_nsgroup_reference(rmt_nsgroup_id)
|
||||||
destination = local_ip_prefix or local_group
|
destination = local_ip_prefix or local_group
|
||||||
if direction == firewall.OUT:
|
if direction == consts.OUT:
|
||||||
source, destination = destination, source
|
source, destination = destination, source
|
||||||
|
|
||||||
service = self._decide_service(sg_rule)
|
service = self._decide_service(sg_rule)
|
||||||
@ -133,17 +131,15 @@ class Security(object):
|
|||||||
action, logged)
|
action, logged)
|
||||||
|
|
||||||
def create_firewall_rules(self, context, section_id, nsgroup_id,
|
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
|
# 1. translate rules
|
||||||
# 2. insert in section
|
# 2. insert in section
|
||||||
# 3. save mappings
|
# 3. return the rules
|
||||||
|
|
||||||
firewall_rules = []
|
firewall_rules = []
|
||||||
for sg_rule in security_group_rules:
|
for sg_rule in security_group_rules:
|
||||||
remote_nsgroup_id = self._get_remote_nsg_mapping(
|
remote_nsgroup_id = ruleid_2_remote_nsgroup_map[sg_rule['id']]
|
||||||
context, sg_rule, nsgroup_id)
|
|
||||||
|
|
||||||
fw_rule = self._get_fw_rule_from_sg_rule(
|
fw_rule = self._get_fw_rule_from_sg_rule(
|
||||||
sg_rule, nsgroup_id, remote_nsgroup_id,
|
sg_rule, nsgroup_id, remote_nsgroup_id,
|
||||||
logging_enabled, action)
|
logging_enabled, action)
|
||||||
@ -167,13 +163,13 @@ class Security(object):
|
|||||||
section_id, logging)
|
section_id, logging)
|
||||||
self.update_section(section_id, rules=rules)
|
self.update_section(section_id, rules=rules)
|
||||||
|
|
||||||
def update_security_group_on_backend(self, context, security_group):
|
def update_security_group_on_backend(self, context, security_group,
|
||||||
nsgroup_id, section_id = self.get_sg_mappings(context.session,
|
nsgroup_id, section_id,
|
||||||
security_group['id'])
|
log_sg_allowed_traffic):
|
||||||
name = self.get_nsgroup_name(security_group)
|
name = self.get_nsgroup_name(security_group)
|
||||||
description = security_group['description']
|
description = security_group['description']
|
||||||
logging = (cfg.CONF.nsx_v3.log_security_groups_allowed_traffic or
|
logging = (log_sg_allowed_traffic or
|
||||||
security_group[sg_logging.LOGGING])
|
security_group[consts.LOGGING])
|
||||||
rules = self._process_firewall_section_rules_logging_for_update(
|
rules = self._process_firewall_section_rules_logging_for_update(
|
||||||
section_id, logging)
|
section_id, logging)
|
||||||
self.update_nsgroup(nsgroup_id, name, description)
|
self.update_nsgroup(nsgroup_id, name, description)
|
||||||
@ -184,38 +180,6 @@ class Security(object):
|
|||||||
# for usability purposes.
|
# for usability purposes.
|
||||||
return '%(name)s - %(id)s' % security_group
|
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):
|
def get_lport_tags_for_security_groups(self, secgroups):
|
||||||
if len(secgroups) > MAX_NSGROUPS_CRITERIA_TAGS:
|
if len(secgroups) > MAX_NSGROUPS_CRITERIA_TAGS:
|
||||||
raise exceptions.NumberOfNsgroupCriteriaTagsReached(
|
raise exceptions.NumberOfNsgroupCriteriaTagsReached(
|
||||||
@ -232,30 +196,29 @@ class Security(object):
|
|||||||
original, updated):
|
original, updated):
|
||||||
added = set(updated) - set(original)
|
added = set(updated) - set(original)
|
||||||
removed = set(original) - set(updated)
|
removed = set(original) - set(updated)
|
||||||
for sg_id in added:
|
for nsgroup_id in added:
|
||||||
nsgroup_id, s = self.get_sg_mappings(context.session, sg_id)
|
|
||||||
try:
|
try:
|
||||||
self.add_nsgroup_members(
|
self.add_nsgroup_members(
|
||||||
nsgroup_id, firewall.LOGICAL_PORT, [lport_id])
|
nsgroup_id, consts.TARGET_TYPE_LOGICAL_PORT,
|
||||||
|
[lport_id])
|
||||||
except exceptions.NSGroupIsFull:
|
except exceptions.NSGroupIsFull:
|
||||||
for sg_id in added:
|
for nsgroup_id in added:
|
||||||
nsgroup_id, s = self.get_sg_mappings(
|
|
||||||
context.session, sg_id)
|
|
||||||
# NOTE(roeyc): If the port was not added to the nsgroup
|
# NOTE(roeyc): If the port was not added to the nsgroup
|
||||||
# yet, then this request will silently fail.
|
# yet, then this request will silently fail.
|
||||||
self.remove_nsgroup_member(
|
self.remove_nsgroup_member(
|
||||||
nsgroup_id, firewall.LOGICAL_PORT, lport_id)
|
nsgroup_id, consts.TARGET_TYPE_LOGICAL_PORT,
|
||||||
|
lport_id)
|
||||||
raise exceptions.SecurityGroupMaximumCapacityReached(
|
raise exceptions.SecurityGroupMaximumCapacityReached(
|
||||||
sg_id=sg_id)
|
sg_id=nsgroup_id)
|
||||||
except exceptions.ResourceNotFound:
|
except exceptions.ResourceNotFound:
|
||||||
with excutils.save_and_reraise_exception():
|
with excutils.save_and_reraise_exception():
|
||||||
LOG.error(_LE("NSGroup %s doesn't exists"), nsgroup_id)
|
LOG.error(_LE("NSGroup %s doesn't exists"), nsgroup_id)
|
||||||
for sg_id in removed:
|
for nsgroup_id in removed:
|
||||||
nsgroup_id, s = self.get_sg_mappings(context.session, sg_id)
|
|
||||||
self.remove_nsgroup_member(
|
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()
|
fw_sections = self.list_sections()
|
||||||
for section in fw_sections:
|
for section in fw_sections:
|
||||||
if section['display_name'] == name:
|
if section['display_name'] == name:
|
||||||
@ -266,23 +229,28 @@ class Security(object):
|
|||||||
name, description, nested_groups, tags)
|
name, description, nested_groups, tags)
|
||||||
|
|
||||||
block_rule = self.get_firewall_rule_dict(
|
block_rule = self.get_firewall_rule_dict(
|
||||||
'Block All', action=firewall.DROP,
|
'Block All', action=consts.FW_ACTION_DROP,
|
||||||
logged=cfg.CONF.nsx_v3.log_security_groups_blocked_traffic)
|
logged=log_sg_blocked_traffic)
|
||||||
# TODO(roeyc): Add additional rules to allow IPV6 NDP.
|
# TODO(roeyc): Add additional rules to allow IPV6 NDP.
|
||||||
dhcp_client = self.get_nsservice(firewall.L4_PORT_SET_NSSERVICE,
|
dhcp_client = self.get_nsservice(
|
||||||
l4_protocol=firewall.UDP,
|
consts.L4_PORT_SET_NSSERVICE,
|
||||||
|
l4_protocol=consts.UDP,
|
||||||
source_ports=[67],
|
source_ports=[67],
|
||||||
destination_ports=[68])
|
destination_ports=[68])
|
||||||
dhcp_client_rule_in = self.get_firewall_rule_dict(
|
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 = (
|
dhcp_server = (
|
||||||
self.get_nsservice(firewall.L4_PORT_SET_NSSERVICE,
|
self.get_nsservice(consts.L4_PORT_SET_NSSERVICE,
|
||||||
l4_protocol=firewall.UDP,
|
l4_protocol=consts.UDP,
|
||||||
source_ports=[68],
|
source_ports=[68],
|
||||||
destination_ports=[67]))
|
destination_ports=[67]))
|
||||||
dhcp_client_rule_out = self.get_firewall_rule_dict(
|
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'],
|
self.update_section(section['id'],
|
||||||
name, section['description'],
|
name, section['description'],
|
||||||
@ -291,3 +259,205 @@ class Security(object):
|
|||||||
dhcp_client_rule_in,
|
dhcp_client_rule_in,
|
||||||
block_rule])
|
block_rule])
|
||||||
return section['id']
|
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 config # noqa
|
||||||
from vmware_nsx.common import exceptions as nsx_exc
|
from vmware_nsx.common import exceptions as nsx_exc
|
||||||
from vmware_nsx.common import locking
|
from vmware_nsx.common import locking
|
||||||
from vmware_nsx.common import nsx_constants
|
|
||||||
from vmware_nsx.common import utils
|
from vmware_nsx.common import utils
|
||||||
from vmware_nsx.db import db as nsx_db
|
from vmware_nsx.db import db as nsx_db
|
||||||
from vmware_nsx.db import extended_security_group
|
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 providersecuritygroup as provider_sg
|
||||||
from vmware_nsx.extensions import securitygrouplogging as sg_logging
|
from vmware_nsx.extensions import securitygrouplogging as sg_logging
|
||||||
from vmware_nsx.nsxlib import v3 as nsxlib
|
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 exceptions as nsx_lib_exc
|
||||||
from vmware_nsx.nsxlib.v3 import native_dhcp
|
from vmware_nsx.nsxlib.v3 import native_dhcp
|
||||||
from vmware_nsx.nsxlib.v3 import ns_group_manager
|
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 resources as nsx_resources
|
||||||
from vmware_nsx.nsxlib.v3 import router
|
from vmware_nsx.nsxlib.v3 import router
|
||||||
from vmware_nsx.nsxlib.v3 import security
|
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.common import utils as qos_com_utils
|
||||||
from vmware_nsx.services.qos.nsx_v3 import utils as qos_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
|
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):
|
def _init_nsx_profiles(self):
|
||||||
LOG.debug("Initializing NSX v3 port spoofguard switching profile")
|
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 = None
|
||||||
self._psec_profile = self._init_port_security_profile()
|
self._psec_profile = self._init_port_security_profile()
|
||||||
if not self._psec_profile:
|
if not self._psec_profile:
|
||||||
@ -236,7 +237,8 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
|
|
||||||
LOG.debug("Initializing NSX v3 DHCP switching profile")
|
LOG.debug("Initializing NSX v3 DHCP switching profile")
|
||||||
try:
|
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 = None
|
||||||
self._dhcp_profile = self._init_dhcp_switching_profile()
|
self._dhcp_profile = self._init_dhcp_switching_profile()
|
||||||
except Exception:
|
except Exception:
|
||||||
@ -247,7 +249,8 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
if utils.is_nsx_version_1_1_0(self._nsx_version):
|
if utils.is_nsx_version_1_1_0(self._nsx_version):
|
||||||
LOG.debug("Initializing NSX v3 Mac Learning switching profile")
|
LOG.debug("Initializing NSX v3 Mac Learning switching profile")
|
||||||
try:
|
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 = None
|
||||||
self._mac_learning_profile = self._init_mac_learning_profile()
|
self._mac_learning_profile = self._init_mac_learning_profile()
|
||||||
# Only expose the extension if it is supported
|
# Only expose the extension if it is supported
|
||||||
@ -318,14 +321,15 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
"must be disabled") % dhcp_profile_uuid
|
"must be disabled") % dhcp_profile_uuid
|
||||||
raise n_exc.InvalidInput(error_message=msg)
|
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):
|
def _init_dhcp_switching_profile(self):
|
||||||
with locking.LockManager.get_lock('nsxv3_dhcp_profile_init'):
|
with locking.LockManager.get_lock('nsxv3_dhcp_profile_init'):
|
||||||
profile = self._get_dhcp_security_profile()
|
profile = self._get_dhcp_security_profile()
|
||||||
if not profile:
|
if not profile:
|
||||||
self._switching_profiles.create_dhcp_profile(
|
self._switching_profiles.create_dhcp_profile(
|
||||||
NSX_V3_DHCP_PROFILE_NAME, 'Neutron DHCP Security 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()
|
return self._get_dhcp_security_profile()
|
||||||
|
|
||||||
def _get_dhcp_security_profile(self):
|
def _get_dhcp_security_profile(self):
|
||||||
@ -345,7 +349,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
self._switching_profiles.create_mac_learning_profile(
|
self._switching_profiles.create_mac_learning_profile(
|
||||||
NSX_V3_MAC_LEARNING_PROFILE_NAME,
|
NSX_V3_MAC_LEARNING_PROFILE_NAME,
|
||||||
'Neutron MAC Learning Profile',
|
'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()
|
return self._get_mac_learning_profile()
|
||||||
|
|
||||||
def _get_mac_learning_profile(self):
|
def _get_mac_learning_profile(self):
|
||||||
@ -369,7 +373,8 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
NSX_V3_PSEC_PROFILE_NAME)
|
NSX_V3_PSEC_PROFILE_NAME)
|
||||||
return profile[0] if profile else None
|
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):
|
def _init_port_security_profile(self):
|
||||||
profile = self._get_port_security_profile()
|
profile = self._get_port_security_profile()
|
||||||
if profile:
|
if profile:
|
||||||
@ -384,7 +389,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
self._switching_profiles.create_spoofguard_profile(
|
self._switching_profiles.create_spoofguard_profile(
|
||||||
NSX_V3_PSEC_PROFILE_NAME, 'Neutron Port Security Profile',
|
NSX_V3_PSEC_PROFILE_NAME, 'Neutron Port Security Profile',
|
||||||
whitelist_ports=True, whitelist_switches=False,
|
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()
|
return self._get_port_security_profile()
|
||||||
|
|
||||||
def _process_security_group_logging(self):
|
def _process_security_group_logging(self):
|
||||||
@ -396,8 +401,8 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
sg_logging.LOGGING])
|
sg_logging.LOGGING])
|
||||||
for sg in [sg for sg in secgroups
|
for sg in [sg for sg in secgroups
|
||||||
if sg[sg_logging.LOGGING] is False]:
|
if sg[sg_logging.LOGGING] is False]:
|
||||||
_, section_id = self.nsxlib.get_sg_mappings(context.session,
|
nsgroup_id, section_id = nsx_db.get_sg_mappings(
|
||||||
sg['id'])
|
context.session, sg['id'])
|
||||||
try:
|
try:
|
||||||
self.nsxlib.set_firewall_rule_logging_for_section(
|
self.nsxlib.set_firewall_rule_logging_for_section(
|
||||||
section_id, logging=log_all_rules)
|
section_id, logging=log_all_rules)
|
||||||
@ -414,9 +419,10 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
cfg.CONF.nsx_v3.number_of_nested_groups)
|
cfg.CONF.nsx_v3.number_of_nested_groups)
|
||||||
section_description = ("This section is handled by OpenStack to "
|
section_description = ("This section is handled by OpenStack to "
|
||||||
"contain default rules on security-groups.")
|
"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,
|
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
|
return nsgroup_manager, section_id
|
||||||
|
|
||||||
def _init_dhcp_metadata(self):
|
def _init_dhcp_metadata(self):
|
||||||
@ -601,7 +607,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
# update the network name to indicate the neutron id too.
|
# update the network name to indicate the neutron id too.
|
||||||
net_name = utils.get_name_and_uuid(net_data['name'] or 'network',
|
net_name = utils.get_name_and_uuid(net_data['name'] or 'network',
|
||||||
neutron_net_id)
|
neutron_net_id)
|
||||||
tags = utils.build_v3_tags_payload(
|
tags = nsxlib_utils.build_v3_tags_payload(
|
||||||
net_data, resource_type='os-neutron-net-id',
|
net_data, resource_type='os-neutron-net-id',
|
||||||
project_name=context.tenant_name)
|
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:
|
if is_backend_network and cfg.CONF.nsx_v3.native_dhcp_metadata:
|
||||||
# Enable native metadata proxy for this network.
|
# 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',
|
net_data, resource_type='os-neutron-net-id',
|
||||||
project_name=context.tenant_name)
|
project_name=context.tenant_name)
|
||||||
name = utils.get_name_and_uuid('%s-%s' % (
|
name = utils.get_name_and_uuid('%s-%s' % (
|
||||||
@ -722,7 +728,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
md_port = self._port_client.create(
|
md_port = self._port_client.create(
|
||||||
nsx_net_id, cfg.CONF.nsx_v3.metadata_proxy_uuid,
|
nsx_net_id, cfg.CONF.nsx_v3.metadata_proxy_uuid,
|
||||||
tags=tags, name=name,
|
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 "
|
LOG.debug("Created MD-Proxy logical port %(port)s "
|
||||||
"for network %(network)s",
|
"for network %(network)s",
|
||||||
{'port': md_port['id'],
|
{'port': md_port['id'],
|
||||||
@ -923,7 +929,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
server_data = native_dhcp.build_dhcp_server_config(
|
server_data = native_dhcp.build_dhcp_server_config(
|
||||||
network, subnet, neutron_port, context.tenant_name)
|
network, subnet, neutron_port, context.tenant_name)
|
||||||
nsx_net_id = self._get_network_nsx_id(context, network['id'])
|
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',
|
neutron_port, resource_type='os-neutron-dport-id',
|
||||||
project_name=context.tenant_name)
|
project_name=context.tenant_name)
|
||||||
dhcp_server = None
|
dhcp_server = None
|
||||||
@ -935,7 +941,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
name = self._get_port_name(context, port_data)
|
name = self._get_port_name(context, port_data)
|
||||||
nsx_port = self._port_client.create(
|
nsx_port = self._port_client.create(
|
||||||
nsx_net_id, dhcp_server['id'], tags=tags, name=name,
|
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 "
|
LOG.debug("Created DHCP logical port %(port)s for "
|
||||||
"network %(network)s",
|
"network %(network)s",
|
||||||
{'port': nsx_port['id'], 'network': network['id']})
|
{'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.
|
# Add neutron_net_id -> dhcp_service_id mapping to the DB.
|
||||||
nsx_db.add_neutron_nsx_service_binding(
|
nsx_db.add_neutron_nsx_service_binding(
|
||||||
context.session, network['id'], neutron_port['id'],
|
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:
|
except db_exc.DBError:
|
||||||
with excutils.save_and_reraise_exception():
|
with excutils.save_and_reraise_exception():
|
||||||
LOG.error(_LE("Failed to create mapping for DHCP port %s,"
|
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
|
# First delete the DHCP port in this network. Then delete the
|
||||||
# corresponding LogicalDhcpServer for this network.
|
# corresponding LogicalDhcpServer for this network.
|
||||||
dhcp_service = nsx_db.get_nsx_service_binding(
|
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:
|
if not dhcp_service:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -1002,7 +1008,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
try:
|
try:
|
||||||
# Delete neutron_id -> dhcp_service_id mapping from the DB.
|
# Delete neutron_id -> dhcp_service_id mapping from the DB.
|
||||||
nsx_db.delete_neutron_nsx_service_binding(
|
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:
|
except db_exc.DBError:
|
||||||
with excutils.save_and_reraise_exception():
|
with excutils.save_and_reraise_exception():
|
||||||
LOG.error(_LE("Unable to delete DHCP server mapping for "
|
LOG.error(_LE("Unable to delete DHCP server mapping for "
|
||||||
@ -1105,7 +1111,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
if kwargs:
|
if kwargs:
|
||||||
dhcp_service = nsx_db.get_nsx_service_binding(
|
dhcp_service = nsx_db.get_nsx_service_binding(
|
||||||
context.session, orig_subnet['network_id'],
|
context.session, orig_subnet['network_id'],
|
||||||
nsx_constants.SERVICE_DHCP)
|
nsxlib_consts.SERVICE_DHCP)
|
||||||
if dhcp_service:
|
if dhcp_service:
|
||||||
try:
|
try:
|
||||||
self._dhcp_server.update(
|
self._dhcp_server.update(
|
||||||
@ -1256,13 +1262,13 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
resource_type = 'os-neutron-rport-id'
|
resource_type = 'os-neutron-rport-id'
|
||||||
else:
|
else:
|
||||||
resource_type = 'os-neutron-port-id'
|
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,
|
port_data, resource_type=resource_type,
|
||||||
project_name=context.tenant_name)
|
project_name=context.tenant_name)
|
||||||
resource_type = self._get_resource_type_for_device_id(
|
resource_type = self._get_resource_type_for_device_id(
|
||||||
device_owner, device_id)
|
device_owner, device_id)
|
||||||
if resource_type:
|
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 utils.is_nsx_version_1_1_0(self._nsx_version):
|
||||||
# If port has no security-groups then we don't need to add any
|
# 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
|
vif_uuid = False
|
||||||
else:
|
else:
|
||||||
# default attachment
|
# default attachment
|
||||||
attachment_type = nsx_constants.ATTACHMENT_VIF
|
attachment_type = nsxlib_consts.ATTACHMENT_VIF
|
||||||
vif_uuid = port_data['id']
|
vif_uuid = port_data['id']
|
||||||
|
|
||||||
profiles = []
|
profiles = []
|
||||||
@ -1423,7 +1429,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
if not utils.is_port_dhcp_configurable(port):
|
if not utils.is_port_dhcp_configurable(port):
|
||||||
return
|
return
|
||||||
dhcp_service = nsx_db.get_nsx_service_binding(
|
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:
|
if not dhcp_service:
|
||||||
return
|
return
|
||||||
for fixed_ip in self._filter_ipv4_dhcp_fixed_ips(
|
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.
|
# Locate the backend DHCP server for this DHCP port.
|
||||||
dhcp_service = nsx_db.get_nsx_service_binding(
|
dhcp_service = nsx_db.get_nsx_service_binding(
|
||||||
context.session, old_port['network_id'],
|
context.session, old_port['network_id'],
|
||||||
nsx_constants.SERVICE_DHCP)
|
nsxlib_consts.SERVICE_DHCP)
|
||||||
if dhcp_service:
|
if dhcp_service:
|
||||||
new_ip = ips_to_add[0][1]
|
new_ip = ips_to_add[0][1]
|
||||||
try:
|
try:
|
||||||
@ -1586,7 +1592,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
if ips_to_add:
|
if ips_to_add:
|
||||||
dhcp_service = nsx_db.get_nsx_service_binding(
|
dhcp_service = nsx_db.get_nsx_service_binding(
|
||||||
context.session, new_port['network_id'],
|
context.session, new_port['network_id'],
|
||||||
nsx_constants.SERVICE_DHCP)
|
nsxlib_consts.SERVICE_DHCP)
|
||||||
if dhcp_service:
|
if dhcp_service:
|
||||||
for (subnet_id, ip) in ips_to_add:
|
for (subnet_id, ip) in ips_to_add:
|
||||||
self._add_dhcp_binding_on_server(
|
self._add_dhcp_binding_on_server(
|
||||||
@ -1622,6 +1628,16 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
{'mac': mac, 'ip': ip, 'port': binding['port_id'],
|
{'mac': mac, 'ip': ip, 'port': binding['port_id'],
|
||||||
'server': binding['nsx_service_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):
|
def create_port(self, context, port, l2gw_port_check=False):
|
||||||
port_data = port['port']
|
port_data = port['port']
|
||||||
dhcp_opts = port_data.get(ext_edo.EXTRADHCPOPTS, [])
|
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):
|
if not utils.is_nsx_version_1_1_0(self._nsx_version):
|
||||||
try:
|
try:
|
||||||
self.nsxlib.update_lport_with_security_groups(
|
self._update_lport_with_security_groups(
|
||||||
context, lport['id'], [], sgids or [])
|
context, lport['id'], [], sgids or [])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
with excutils.save_and_reraise_exception(reraise=False):
|
with excutils.save_and_reraise_exception(reraise=False):
|
||||||
@ -1762,7 +1778,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
context.session, port_id)
|
context.session, port_id)
|
||||||
self._port_client.delete(nsx_port_id)
|
self._port_client.delete(nsx_port_id)
|
||||||
if not utils.is_nsx_version_1_1_0(self._nsx_version):
|
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,
|
context, nsx_port_id,
|
||||||
port.get(ext_sg.SECURITYGROUPS, []), [])
|
port.get(ext_sg.SECURITYGROUPS, []), [])
|
||||||
self.disassociate_floatingips(context, port_id)
|
self.disassociate_floatingips(context, port_id)
|
||||||
@ -1866,21 +1882,21 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
resource_type = self._get_resource_type_for_device_id(
|
resource_type = self._get_resource_type_for_device_id(
|
||||||
original_device_owner, updated_device_id)
|
original_device_owner, updated_device_id)
|
||||||
if resource_type:
|
if resource_type:
|
||||||
tags_update = utils.add_v3_tag(tags_update, resource_type,
|
tags_update = nsxlib_utils.add_v3_tag(
|
||||||
updated_device_id)
|
tags_update, resource_type, updated_device_id)
|
||||||
|
|
||||||
parent_vif_id, tag = self._get_data_from_binding_profile(
|
parent_vif_id, tag = self._get_data_from_binding_profile(
|
||||||
context, updated_port)
|
context, updated_port)
|
||||||
|
|
||||||
if updated_device_owner in (original_device_owner,
|
if updated_device_owner in (original_device_owner,
|
||||||
l3_db.DEVICE_OWNER_ROUTER_INTF,
|
l3_db.DEVICE_OWNER_ROUTER_INTF,
|
||||||
nsx_constants.BRIDGE_ENDPOINT):
|
nsxlib_consts.BRIDGE_ENDPOINT):
|
||||||
# no attachment change
|
# no attachment change
|
||||||
attachment_type = False
|
attachment_type = False
|
||||||
vif_uuid = False
|
vif_uuid = False
|
||||||
elif updated_device_owner:
|
elif updated_device_owner:
|
||||||
# default attachment
|
# default attachment
|
||||||
attachment_type = nsx_constants.ATTACHMENT_VIF
|
attachment_type = nsxlib_consts.ATTACHMENT_VIF
|
||||||
vif_uuid = updated_port['id']
|
vif_uuid = updated_port['id']
|
||||||
else:
|
else:
|
||||||
# no attachment
|
# no attachment
|
||||||
@ -1894,7 +1910,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
updated_port.get(ext_sg.SECURITYGROUPS, []) +
|
updated_port.get(ext_sg.SECURITYGROUPS, []) +
|
||||||
updated_port.get(provider_sg.PROVIDER_SECURITYGROUPS, []))
|
updated_port.get(provider_sg.PROVIDER_SECURITYGROUPS, []))
|
||||||
else:
|
else:
|
||||||
self.nsxlib.update_lport_with_security_groups(
|
self._update_lport_with_security_groups(
|
||||||
context, lport_id,
|
context, lport_id,
|
||||||
original_port.get(ext_sg.SECURITYGROUPS, []) +
|
original_port.get(ext_sg.SECURITYGROUPS, []) +
|
||||||
original_port.get(provider_sg.PROVIDER_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)
|
edge_cluster_uuid = self._get_edge_cluster(new_tier0_uuid)
|
||||||
self._routerlib.update_router_edge_cluster(
|
self._routerlib.update_router_edge_cluster(
|
||||||
nsx_router_id, edge_cluster_uuid)
|
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',
|
router, resource_type='os-neutron-rport',
|
||||||
project_name=context.tenant_name)
|
project_name=context.tenant_name)
|
||||||
self._routerlib.add_router_link_port(nsx_router_id, new_tier0_uuid,
|
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)
|
gw_info = self._extract_external_gw(context, router, is_extract=True)
|
||||||
router['router']['id'] = (router['router'].get('id') or
|
router['router']['id'] = (router['router'].get('id') or
|
||||||
uuidutils.generate_uuid())
|
uuidutils.generate_uuid())
|
||||||
tags = utils.build_v3_tags_payload(
|
tags = nsxlib_utils.build_v3_tags_payload(
|
||||||
router['router'], resource_type='os-neutron-router-id',
|
router['router'], resource_type='os-neutron-router-id',
|
||||||
project_name=context.tenant_name)
|
project_name=context.tenant_name)
|
||||||
result = self._router_client.create(
|
result = self._router_client.create(
|
||||||
@ -2522,7 +2538,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
context, router_id, network_id)
|
context, router_id, network_id)
|
||||||
display_name = utils.get_name_and_uuid(
|
display_name = utils.get_name_and_uuid(
|
||||||
subnet['name'] or 'subnet', subnet['id'])
|
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',
|
port, resource_type='os-neutron-rport-id',
|
||||||
project_name=context.tenant_name)
|
project_name=context.tenant_name)
|
||||||
tags.append({'scope': 'os-subnet-id', 'tag': subnet['id']})
|
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):
|
def _create_fw_section_for_secgroup(self, nsgroup, is_provider):
|
||||||
# NOTE(arosen): if a security group is provider we want to
|
# NOTE(arosen): if a security group is provider we want to
|
||||||
# insert our rules at the top.
|
# insert our rules at the top.
|
||||||
operation = (firewall.INSERT_TOP
|
operation = (nsxlib_consts.FW_INSERT_TOP
|
||||||
if is_provider
|
if is_provider
|
||||||
else firewall.INSERT_BEFORE)
|
else nsxlib_consts.FW_INSERT_BEFORE)
|
||||||
|
|
||||||
# security-group rules are located in a dedicated firewall section.
|
# security-group rules are located in a dedicated firewall section.
|
||||||
firewall_section = (
|
firewall_section = (
|
||||||
@ -2791,7 +2807,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
return firewall_section
|
return firewall_section
|
||||||
|
|
||||||
def _create_security_group_backend_resources(self, secgroup):
|
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',
|
secgroup, resource_type='os-neutron-secgr-id',
|
||||||
project_name=secgroup['tenant_id'])
|
project_name=secgroup['tenant_id'])
|
||||||
name = self.nsxlib.get_nsgroup_name(secgroup)
|
name = self.nsxlib.get_nsgroup_name(secgroup)
|
||||||
@ -2810,6 +2826,27 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
ns_group, secgroup.get(provider_sg.PROVIDER))
|
ns_group, secgroup.get(provider_sg.PROVIDER))
|
||||||
return ns_group, firewall_section
|
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):
|
def create_security_group(self, context, security_group, default_sg=False):
|
||||||
secgroup = security_group['security_group']
|
secgroup = security_group['security_group']
|
||||||
secgroup['id'] = secgroup.get('id') or uuidutils.generate_uuid()
|
secgroup['id'] = secgroup.get('id') or uuidutils.generate_uuid()
|
||||||
@ -2871,14 +2908,13 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
# translate and creates firewall rules.
|
# translate and creates firewall rules.
|
||||||
logging = (cfg.CONF.nsx_v3.log_security_groups_allowed_traffic
|
logging = (cfg.CONF.nsx_v3.log_security_groups_allowed_traffic
|
||||||
or secgroup.get(sg_logging.LOGGING, False))
|
or secgroup.get(sg_logging.LOGGING, False))
|
||||||
action = (firewall.DROP
|
action = (nsxlib_consts.FW_ACTION_DROP
|
||||||
if secgroup.get(provider_sg.PROVIDER)
|
if secgroup.get(provider_sg.PROVIDER)
|
||||||
else firewall.ALLOW)
|
else nsxlib_consts.FW_ACTION_ALLOW)
|
||||||
rules = self.nsxlib.create_firewall_rules(
|
rules = self._create_firewall_rules(
|
||||||
context, firewall_section['id'], ns_group['id'],
|
context, firewall_section['id'], ns_group['id'],
|
||||||
logging, action, sg_rules)
|
logging, action, sg_rules)
|
||||||
self.nsxlib.save_sg_rule_mappings(context.session,
|
self.save_security_group_rule_mappings(context, rules['rules'])
|
||||||
rules['rules'])
|
|
||||||
self.nsgroup_manager.add_nsgroup(ns_group['id'])
|
self.nsgroup_manager.add_nsgroup(ns_group['id'])
|
||||||
except nsx_lib_exc.ManagerError:
|
except nsx_lib_exc.ManagerError:
|
||||||
with excutils.save_and_reraise_exception():
|
with excutils.save_and_reraise_exception():
|
||||||
@ -2905,7 +2941,11 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
self._process_security_group_properties_update(
|
self._process_security_group_properties_update(
|
||||||
context, secgroup_res, security_group['security_group'])
|
context, secgroup_res, security_group['security_group'])
|
||||||
try:
|
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:
|
except nsx_lib_exc.ManagerError:
|
||||||
with excutils.save_and_reraise_exception():
|
with excutils.save_and_reraise_exception():
|
||||||
LOG.exception(_LE("Failed to update security-group %(name)s "
|
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):
|
def delete_security_group(self, context, id):
|
||||||
self._prevent_non_admin_delete_provider_sg(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)
|
context.session, id)
|
||||||
super(NsxV3Plugin, self).delete_security_group(context, id)
|
super(NsxV3Plugin, self).delete_security_group(context, id)
|
||||||
self.nsxlib.delete_section(section_id)
|
self.nsxlib.delete_section(section_id)
|
||||||
@ -2957,18 +2997,18 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
|
|
||||||
security_group = self.get_security_group(
|
security_group = self.get_security_group(
|
||||||
context, sg_id)
|
context, sg_id)
|
||||||
action = firewall.ALLOW
|
action = nsxlib_consts.FW_ACTION_ALLOW
|
||||||
if security_group.get(provider_sg.PROVIDER) is True:
|
if security_group.get(provider_sg.PROVIDER) is True:
|
||||||
# provider security groups are drop rules.
|
# provider security groups are drop rules.
|
||||||
action = firewall.DROP
|
action = nsxlib_consts.FW_ACTION_DROP
|
||||||
|
|
||||||
sg_id = rules_db[0]['security_group_id']
|
sg_id = rules_db[0]['security_group_id']
|
||||||
nsgroup_id, section_id = self.nsxlib.get_sg_mappings(context.session,
|
nsgroup_id, section_id = nsx_db.get_sg_mappings(context.session,
|
||||||
sg_id)
|
sg_id)
|
||||||
logging_enabled = (cfg.CONF.nsx_v3.log_security_groups_allowed_traffic
|
logging_enabled = (cfg.CONF.nsx_v3.log_security_groups_allowed_traffic
|
||||||
or self._is_security_group_logged(context, sg_id))
|
or self._is_security_group_logged(context, sg_id))
|
||||||
try:
|
try:
|
||||||
rules = self.nsxlib.create_firewall_rules(
|
rules = self._create_firewall_rules(
|
||||||
context, section_id, nsgroup_id,
|
context, section_id, nsgroup_id,
|
||||||
logging_enabled, action, rules_db)
|
logging_enabled, action, rules_db)
|
||||||
except nsx_lib_exc.ManagerError:
|
except nsx_lib_exc.ManagerError:
|
||||||
@ -2976,14 +3016,18 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
for rule in rules_db:
|
for rule in rules_db:
|
||||||
super(NsxV3Plugin, self).delete_security_group_rule(
|
super(NsxV3Plugin, self).delete_security_group_rule(
|
||||||
context, rule['id'])
|
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
|
return rules_db
|
||||||
|
|
||||||
def delete_security_group_rule(self, context, id):
|
def delete_security_group_rule(self, context, id):
|
||||||
rule_db = self._get_security_group_rule(context, id)
|
rule_db = self._get_security_group_rule(context, id)
|
||||||
sg_id = rule_db['security_group_id']
|
sg_id = rule_db['security_group_id']
|
||||||
self._prevent_non_admin_delete_provider_sg(context, sg_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)
|
fw_rule_id = nsx_db.get_sg_rule_mapping(context.session, id)
|
||||||
self.nsxlib.delete_rule(section_id, fw_rule_id)
|
self.nsxlib.delete_rule(section_id, fw_rule_id)
|
||||||
super(NsxV3Plugin, self).delete_security_group_rule(context, 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 neutron_lib import exceptions as n_exc
|
||||||
|
|
||||||
from vmware_nsx._i18n import _, _LE, _LI
|
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.common import utils as nsx_utils
|
||||||
from vmware_nsx.db import db as nsx_db
|
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 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__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -219,7 +220,7 @@ class NsxV3Driver(l2gateway_db.L2GatewayMixin):
|
|||||||
tenant_id = context.tenant_id
|
tenant_id = context.tenant_id
|
||||||
gw_connection['tenant_id'] = tenant_id
|
gw_connection['tenant_id'] = tenant_id
|
||||||
try:
|
try:
|
||||||
tags = nsx_utils.build_v3_tags_payload(
|
tags = nsxlib_utils.build_v3_tags_payload(
|
||||||
gw_connection, resource_type='os-neutron-l2gw-id',
|
gw_connection, resource_type='os-neutron-l2gw-id',
|
||||||
project_name=context.tenant_name)
|
project_name=context.tenant_name)
|
||||||
bridge_endpoint = self._core_plugin.nsxlib.create_bridge_endpoint(
|
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._i18n import _, _LE, _LW
|
||||||
from vmware_nsx.common import exceptions as nsx_exc
|
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.db import db as nsx_db
|
||||||
from vmware_nsx.nsxlib import v3 as nsxlib
|
from vmware_nsx.nsxlib import v3 as nsxlib
|
||||||
from vmware_nsx.nsxlib.v3 import exceptions as nsxlib_exc
|
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 resources as nsx_resources
|
||||||
|
from vmware_nsx.nsxlib.v3 import utils as nsxlib_utils
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -177,7 +177,7 @@ class NsxV3Driver(base_driver.TaasBaseDriver,
|
|||||||
tf.get('tap_service_id'))
|
tf.get('tap_service_id'))
|
||||||
src_port_id = tf.get('source_port')
|
src_port_id = tf.get('source_port')
|
||||||
dest_port_id = ts.get('port_id')
|
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',
|
tf, resource_type='os-neutron-mirror-id',
|
||||||
project_name=context._plugin_context.tenant_name)
|
project_name=context._plugin_context.tenant_name)
|
||||||
nsx_direction = self._convert_to_backend_direction(
|
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._i18n import _, _LW
|
||||||
from vmware_nsx.common import exceptions as nsx_exc
|
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.db import db as nsx_db
|
||||||
|
from vmware_nsx.nsxlib.v3 import utils
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
MAX_KBPS_MIN_VALUE = 1024
|
MAX_KBPS_MIN_VALUE = 1024
|
||||||
|
@ -20,9 +20,9 @@ from neutron_lib import constants as const
|
|||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
|
|
||||||
from vmware_nsx._i18n import _LE, _LI
|
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.common import utils as nsx_utils
|
||||||
from vmware_nsx.nsxlib.v3 import native_dhcp
|
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.nsxlib.v3 import resources
|
||||||
from vmware_nsx.shell.admin.plugins.common import constants
|
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 formatters
|
||||||
|
@ -19,10 +19,11 @@ from neutron_lib import constants as const
|
|||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
|
|
||||||
from vmware_nsx._i18n import _LE, _LI
|
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.common import utils as nsx_utils
|
||||||
from vmware_nsx.dhcp_meta import rpc as nsx_rpc
|
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 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 constants
|
||||||
from vmware_nsx.shell.admin.plugins.common import formatters
|
from vmware_nsx.shell.admin.plugins.common import formatters
|
||||||
from vmware_nsx.shell.admin.plugins.common import utils as admin_utils
|
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'])
|
lswitch_id = neutron_client.net_id_to_lswitch_id(network['id'])
|
||||||
if not lswitch_id:
|
if not lswitch_id:
|
||||||
continue
|
continue
|
||||||
tags = nsx_utils.build_v3_tags_payload(
|
tags = nsxlib_utils.build_v3_tags_payload(
|
||||||
network, resource_type='os-neutron-net-id',
|
network, resource_type='os-neutron-net-id',
|
||||||
project_name='admin')
|
project_name='admin')
|
||||||
name = nsx_utils.get_name_and_uuid('%s-%s' % (
|
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.admin.plugins.nsxv3.resources import utils as v3_utils
|
||||||
from vmware_nsx.shell import resources as shell
|
from vmware_nsx.shell import resources as shell
|
||||||
from vmware_nsx._i18n import _LE, _LW
|
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 security
|
||||||
|
from vmware_nsx.nsxlib.v3 import utils as nsxlib_utils
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
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)
|
lport_id = neutron_db.get_logical_port_id(port_id)
|
||||||
members.append(lport_id)
|
members.append(lport_id)
|
||||||
nsxlib.add_nsgroup_members(
|
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']:
|
for rule in secgroup['security_group_rules']:
|
||||||
rule_mapping = (context_.session.query(
|
rule_mapping = (context_.session.query(
|
||||||
@ -229,14 +230,14 @@ def fix_security_groups(resource, event, trigger, **kwargs):
|
|||||||
neutron_id=rule['id']).one())
|
neutron_id=rule['id']).one())
|
||||||
with context_.session.begin(subtransactions=True):
|
with context_.session.begin(subtransactions=True):
|
||||||
context_.session.delete(rule_mapping)
|
context_.session.delete(rule_mapping)
|
||||||
action = (firewall.DROP
|
action = (consts.FW_ACTION_DROP
|
||||||
if secgroup.get(provider_sg.PROVIDER)
|
if secgroup.get(provider_sg.PROVIDER)
|
||||||
else firewall.ALLOW)
|
else consts.FW_ACTION_ALLOW)
|
||||||
rules = nsxlib.create_firewall_rules(
|
rules = plugin._create_firewall_rules(
|
||||||
context_, fw_section['id'], nsgroup['id'],
|
context_, fw_section['id'], nsgroup['id'],
|
||||||
secgroup.get(sg_logging.LOGGING, False), action,
|
secgroup.get(sg_logging.LOGGING, False), action,
|
||||||
secgroup['security_group_rules'])
|
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
|
# Add nsgroup to a nested group
|
||||||
plugin.nsgroup_manager.add_nsgroup(nsgroup['id'])
|
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_id = neutron_db.get_lswitch_and_lport_id(port['id'])
|
||||||
lport = port_client.get(lport_id)
|
lport = port_client.get(lport_id)
|
||||||
criteria_tags = nsxlib.get_lport_tags_for_security_groups(secgroups)
|
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)
|
lport.get('tags', []), criteria_tags)
|
||||||
port_client._client.update(lport_id, body=lport)
|
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 neutron.db import db_base_plugin_v2
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
|
|
||||||
from vmware_nsx.common import nsx_constants
|
|
||||||
from vmware_nsx.db import db as nsx_db
|
from vmware_nsx.db import db as nsx_db
|
||||||
from vmware_nsx.nsxlib import v3
|
from vmware_nsx.nsxlib import v3
|
||||||
|
from vmware_nsx.nsxlib.v3 import nsx_constants
|
||||||
from vmware_nsx.plugins.nsx_v3 import plugin
|
from vmware_nsx.plugins.nsx_v3 import plugin
|
||||||
|
|
||||||
|
|
||||||
|
@ -150,4 +150,5 @@ class TestNSXv3ExtendedSGRule(test_nsxv3_plugin.NsxV3PluginTestCaseMixin,
|
|||||||
mock.ANY, # ns_group_id
|
mock.ANY, # ns_group_id
|
||||||
False, # logging
|
False, # logging
|
||||||
'ALLOW', # action
|
'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.extensions import securitygroup as ext_sg
|
||||||
from neutron.tests.unit.extensions import test_securitygroup as test_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 exceptions as nsxlib_exc
|
||||||
from vmware_nsx.nsxlib.v3 import ns_group_manager
|
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.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.nsx_v3 import test_plugin as test_nsxv3
|
||||||
from vmware_nsx.tests.unit.nsxlib.v3 import nsxlib_testcase
|
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
|
# The first nsgroup is associated with the default secgroup, which is
|
||||||
# not added to this port.
|
# not added to this port.
|
||||||
calls = [mock.call(NSG_IDS[1], firewall.LOGICAL_PORT, mock.ANY),
|
calls = [mock.call(NSG_IDS[1],
|
||||||
mock.call(NSG_IDS[2], firewall.LOGICAL_PORT, mock.ANY)]
|
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)
|
add_member_mock.assert_has_calls(calls, any_order=True)
|
||||||
|
|
||||||
@_mock_create_and_list_nsgroups
|
@_mock_create_and_list_nsgroups
|
||||||
@ -97,13 +99,16 @@ class TestSecurityGroupsNoDynamicCriteria(test_nsxv3.NsxV3PluginTestCaseMixin,
|
|||||||
super(TestSecurityGroupsNoDynamicCriteria,
|
super(TestSecurityGroupsNoDynamicCriteria,
|
||||||
self).test_update_port_with_multiple_security_groups()
|
self).test_update_port_with_multiple_security_groups()
|
||||||
|
|
||||||
calls = [mock.call(NSG_IDS[0], firewall.LOGICAL_PORT, mock.ANY),
|
calls = [mock.call(NSG_IDS[0],
|
||||||
mock.call(NSG_IDS[1], firewall.LOGICAL_PORT, mock.ANY),
|
consts.TARGET_TYPE_LOGICAL_PORT, mock.ANY),
|
||||||
mock.call(NSG_IDS[2], firewall.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)
|
add_member_mock.assert_has_calls(calls, any_order=True)
|
||||||
|
|
||||||
remove_member_mock.assert_called_with(
|
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_create_and_list_nsgroups
|
||||||
@mock.patch('vmware_nsx.nsxlib.v3.NsxLib.remove_nsgroup_member')
|
@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()
|
self).test_update_port_remove_security_group_empty_list()
|
||||||
|
|
||||||
add_member_mock.assert_called_with(
|
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(
|
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_create_and_list_nsgroups
|
||||||
@mock.patch('vmware_nsx.nsxlib.v3.NsxLib.add_nsgroup_members')
|
@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
|
# 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
|
# revert any changes in the NSGroups - It is required to remove the
|
||||||
# lport from any NSGroups which it was added to during that call.
|
# lport from any NSGroups which it was added to during that call.
|
||||||
calls = [mock.call(NSG_IDS[1], firewall.LOGICAL_PORT, mock.ANY),
|
calls = [mock.call(NSG_IDS[1],
|
||||||
mock.call(NSG_IDS[2], firewall.LOGICAL_PORT, mock.ANY)]
|
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)
|
remove_member_mock.assert_has_calls(calls, any_order=True)
|
||||||
|
|
||||||
def test_create_security_group_rule_icmpv6_legacy_protocol_name(self):
|
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
|
# There are 5 nested groups, the hash function will return 7, therefore
|
||||||
# we expect that the nsgroup will be placed in the 3rd group.
|
# we expect that the nsgroup will be placed in the 3rd group.
|
||||||
add_member_mock.assert_called_once_with(
|
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(
|
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_create_and_list_nsgroups
|
||||||
@mock.patch('vmware_nsx.nsxlib.v3.NsxLib.remove_nsgroup_member')
|
@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
|
# Trying to add nsgroup to the nested group at index 2 will raise
|
||||||
# NSGroupIsFull exception, we expect that the nsgroup will be added to
|
# NSGroupIsFull exception, we expect that the nsgroup will be added to
|
||||||
# the nested group at index 3.
|
# the nested group at index 3.
|
||||||
calls = [mock.call(NSG_IDS[2], firewall.NSGROUP, [nsgroup_id]),
|
calls = [mock.call(NSG_IDS[2],
|
||||||
mock.call(NSG_IDS[3], firewall.NSGROUP, [nsgroup_id])]
|
consts.NSGROUP, [nsgroup_id]),
|
||||||
|
mock.call(NSG_IDS[3],
|
||||||
|
consts.NSGROUP, [nsgroup_id])]
|
||||||
add_member_mock.assert_has_calls(calls)
|
add_member_mock.assert_has_calls(calls)
|
||||||
|
|
||||||
# Since the nsgroup was added to the nested group at index 3, it will
|
# 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.
|
# remove it from the group at index 3.
|
||||||
calls = [
|
calls = [
|
||||||
mock.call(
|
mock.call(
|
||||||
NSG_IDS[2], firewall.NSGROUP, nsgroup_id, verify=True),
|
NSG_IDS[2], consts.NSGROUP,
|
||||||
|
nsgroup_id, verify=True),
|
||||||
mock.call(
|
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)
|
remove_member_mock.assert_has_calls(calls)
|
||||||
|
|
||||||
@_mock_create_and_list_nsgroups
|
@_mock_create_and_list_nsgroups
|
||||||
@ -282,9 +294,10 @@ class TestNSGroupManager(nsxlib_testcase.NsxLibTestCase):
|
|||||||
size = 3
|
size = 3
|
||||||
cont_manager = ns_group_manager.NSGroupManager(size)
|
cont_manager = ns_group_manager.NSGroupManager(size)
|
||||||
# list_nsgroups will return nested group 1 and 3, but not group 2.
|
# list_nsgroups will return nested group 1 and 3, but not group 2.
|
||||||
with mock.patch.object(firewall,
|
# FIXME: Not sure what this mock does. no one calls this method now.
|
||||||
'list_nsgroups_mock') as list_nsgroups_mock:
|
#with mock.patch.object(vmware_nsx.nsxlib.v3.NsxLib.list_nsgroups,
|
||||||
list_nsgroups_mock = lambda: list_nsgroups_mock()[::2]
|
# 'list_nsgroups_mock') as list_nsgroups_mock:
|
||||||
|
# list_nsgroups_mock = lambda: list_nsgroups_mock()[::2]
|
||||||
# invoking the initialization process again, it should process
|
# invoking the initialization process again, it should process
|
||||||
# groups 1 and 3 and create group 2.
|
# groups 1 and 3 and create group 2.
|
||||||
cont_manager = ns_group_manager.NSGroupManager(size)
|
cont_manager = ns_group_manager.NSGroupManager(size)
|
||||||
|
@ -14,149 +14,4 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
|
||||||
from oslo_utils import uuidutils
|
|
||||||
|
|
||||||
PLUGIN_NAME = 'vmware_nsx.plugins.nsx_v3.plugin.NsxV3Plugin'
|
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 oslo_utils import uuidutils
|
||||||
|
|
||||||
from vmware_nsx.common import exceptions as nsx_exc
|
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.common import utils
|
||||||
from vmware_nsx.db import db as nsx_db
|
from vmware_nsx.db import db as nsx_db
|
||||||
from vmware_nsx.extensions import advancedserviceproviders as as_providers
|
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 resources as nsx_resources
|
||||||
|
from vmware_nsx.nsxlib.v3 import utils as nsxlib_utils
|
||||||
from vmware_nsx.tests.unit.nsx_v3 import test_plugin
|
from vmware_nsx.tests.unit.nsx_v3 import test_plugin
|
||||||
|
|
||||||
|
|
||||||
@ -456,7 +457,7 @@ class NsxNativeMetadataTestCase(test_plugin.NsxV3PluginTestCaseMixin):
|
|||||||
with self.network() as network:
|
with self.network() as network:
|
||||||
nsx_net_id = self.plugin._get_network_nsx_id(
|
nsx_net_id = self.plugin._get_network_nsx_id(
|
||||||
context.get_admin_context(), network['network']['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',
|
network['network'], resource_type='os-neutron-net-id',
|
||||||
project_name=None)
|
project_name=None)
|
||||||
name = utils.get_name_and_uuid('%s-%s' % (
|
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.plugins.nsx_v3 import plugin as nsx_plugin
|
||||||
from vmware_nsx.tests import unit as vmware
|
from vmware_nsx.tests import unit as vmware
|
||||||
from vmware_nsx.tests.unit.extensions import test_metadata
|
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
|
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_serialization import jsonutils
|
||||||
from oslo_utils import uuidutils
|
from oslo_utils import uuidutils
|
||||||
from vmware_nsx.common import nsx_constants
|
from vmware_nsx.nsxlib.v3 import nsx_constants
|
||||||
|
|
||||||
|
|
||||||
FAKE_NAME = "fake_name"
|
FAKE_NAME = "fake_name"
|
||||||
@ -135,7 +135,7 @@ class MockRequestSessionApi(object):
|
|||||||
|
|
||||||
def _build_response(self, url, content=None,
|
def _build_response(self, url, content=None,
|
||||||
status=requests.codes.ok, **kwargs):
|
status=requests.codes.ok, **kwargs):
|
||||||
if type(content) is list:
|
if isinstance(content, list):
|
||||||
content = {
|
content = {
|
||||||
'result_count': len(content),
|
'result_count': len(content),
|
||||||
'results': content
|
'results': content
|
@ -45,14 +45,14 @@ def _mock_nsxlib():
|
|||||||
def _return_id_key(*args, **kwargs):
|
def _return_id_key(*args, **kwargs):
|
||||||
return {'id': uuidutils.generate_uuid()}
|
return {'id': uuidutils.generate_uuid()}
|
||||||
|
|
||||||
# FIXME(arosen): this is duplicated in test_plugin
|
def _mock_add_rules_in_section(*args):
|
||||||
def _mock_create_firewall_rules(*args):
|
|
||||||
# NOTE(arosen): the code in the neutron plugin expects the
|
# NOTE(arosen): the code in the neutron plugin expects the
|
||||||
# neutron rule id as the display_name.
|
# neutron rule id as the display_name.
|
||||||
rules = args[5]
|
rules = args[0]
|
||||||
return {
|
return {
|
||||||
'rules': [
|
'rules': [
|
||||||
{'display_name': rule['id'], 'id': uuidutils.generate_uuid()}
|
{'display_name': rule['display_name'],
|
||||||
|
'id': uuidutils.generate_uuid()}
|
||||||
for rule in rules
|
for rule in rules
|
||||||
]}
|
]}
|
||||||
|
|
||||||
@ -70,15 +70,15 @@ def _mock_nsxlib():
|
|||||||
side_effect=_return_id_key).start()
|
side_effect=_return_id_key).start()
|
||||||
|
|
||||||
mock.patch(
|
mock.patch(
|
||||||
"vmware_nsx.nsxlib.v3.NsxLib._init_default_section",
|
"vmware_nsx.nsxlib.v3.NsxLib.init_default_section",
|
||||||
side_effect=_return_id_key).start()
|
side_effect=_return_id_key).start()
|
||||||
|
|
||||||
mock.patch(
|
mock.patch(
|
||||||
"vmware_nsx.nsxlib.v3.NsxLib.list_nsgroups").start()
|
"vmware_nsx.nsxlib.v3.NsxLib.list_nsgroups").start()
|
||||||
|
|
||||||
mock.patch(
|
mock.patch(
|
||||||
"vmware_nsx.nsxlib.v3.NsxLib.create_firewall_rules",
|
"vmware_nsx.nsxlib.v3.NsxLib.add_rules_in_section",
|
||||||
side_effect=_mock_create_firewall_rules).start()
|
side_effect=_mock_add_rules_in_section).start()
|
||||||
|
|
||||||
mock.patch(
|
mock.patch(
|
||||||
"vmware_nsx.nsxlib.v3.NsxLib.get_transport_zone_id_by_name_or_id",
|
"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 client
|
||||||
from vmware_nsx.nsxlib.v3 import exceptions as nsxlib_exc
|
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
|
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 client
|
||||||
from vmware_nsx.nsxlib.v3 import cluster
|
from vmware_nsx.nsxlib.v3 import cluster
|
||||||
from vmware_nsx.nsxlib.v3 import exceptions as nsxlib_exc
|
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
|
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 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 nsxlib_testcase
|
||||||
|
from vmware_nsx.tests.unit.nsxlib.v3 import test_constants as test_constants_v3
|
||||||
|
|
||||||
LOG = log.getLogger(__name__)
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -20,10 +20,10 @@ import mock
|
|||||||
from oslo_serialization import jsonutils
|
from oslo_serialization import jsonutils
|
||||||
|
|
||||||
from vmware_nsx.nsxlib.v3 import resources
|
from vmware_nsx.nsxlib.v3 import resources
|
||||||
from vmware_nsx.tests.unit.nsx_v3 import mocks
|
from vmware_nsx.tests.unit.nsxlib.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 nsxlib_testcase
|
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_client
|
||||||
|
from vmware_nsx.tests.unit.nsxlib.v3 import test_constants as test_constants_v3
|
||||||
|
|
||||||
|
|
||||||
CLIENT_PKG = test_client.CLIENT_PKG
|
CLIENT_PKG = test_client.CLIENT_PKG
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
import mock
|
import mock
|
||||||
from oslo_log import log
|
from oslo_log import log
|
||||||
|
|
||||||
from vmware_nsx.common import nsx_constants
|
from vmware_nsx.nsxlib.v3 import nsx_constants
|
||||||
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
|
from vmware_nsx.tests.unit.nsxlib.v3 import nsxlib_testcase
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,14 +13,16 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
from neutron.tests.unit.db import test_db_base_plugin_v2 as test_plugin
|
||||||
from neutron import version
|
from neutron import version
|
||||||
from neutron_lib import exceptions as n_exc
|
from neutron_lib import exceptions as n_exc
|
||||||
|
|
||||||
from vmware_nsx.common import utils
|
from vmware_nsx.nsxlib.v3 import utils
|
||||||
from vmware_nsx.tests.unit.nsx_v3 import test_plugin
|
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):
|
def test_build_v3_tags_payload(self):
|
||||||
result = utils.build_v3_tags_payload(
|
result = utils.build_v3_tags_payload(
|
@ -31,10 +31,10 @@ from neutron import context
|
|||||||
from neutron.tests import base
|
from neutron.tests import base
|
||||||
|
|
||||||
from neutron_lib import exceptions as n_exc
|
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.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.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')
|
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.services.qos import qos_plugin
|
||||||
from neutron.tests.unit.services.qos import base
|
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.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.services.qos.nsx_v3 import utils as qos_utils
|
||||||
from vmware_nsx.tests.unit.nsx_v3 import test_plugin
|
from vmware_nsx.tests.unit.nsx_v3 import test_plugin
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user