nsxlib refactor: config + neutron deps
1. new config class was added to allow all the classes to use the same object 2. removing dependencies of the neutron project in nsxlib code & tests Change-Id: I15ace2ab60c1e4307d7076426c48ecc7a242e792
This commit is contained in:
parent
701de5c48f
commit
34f3ee275e
@ -19,6 +19,7 @@ from vmware_nsx._i18n import _, _LW
|
||||
from vmware_nsx.nsxlib.v3 import client
|
||||
from vmware_nsx.nsxlib.v3 import cluster
|
||||
from vmware_nsx.nsxlib.v3 import exceptions
|
||||
from vmware_nsx.nsxlib.v3 import native_dhcp
|
||||
from vmware_nsx.nsxlib.v3 import nsx_constants
|
||||
from vmware_nsx.nsxlib.v3 import security
|
||||
from vmware_nsx.nsxlib.v3 import utils
|
||||
@ -28,60 +29,43 @@ LOG = log.getLogger(__name__)
|
||||
|
||||
class NsxLib(object):
|
||||
|
||||
def __init__(self,
|
||||
username=None,
|
||||
password=None,
|
||||
retries=None,
|
||||
insecure=None,
|
||||
ca_file=None,
|
||||
concurrent_connections=None,
|
||||
http_timeout=None,
|
||||
http_read_timeout=None,
|
||||
conn_idle_timeout=None,
|
||||
http_provider=None,
|
||||
max_attempts=0,
|
||||
nsx_api_managers=None):
|
||||
def __init__(self, nsxlib_config):
|
||||
|
||||
self.max_attempts = max_attempts
|
||||
self.nsxlib_config = nsxlib_config
|
||||
|
||||
# create the Cluster
|
||||
self.cluster = cluster.NSXClusteredAPI(
|
||||
username=username, password=password,
|
||||
retries=retries, insecure=insecure,
|
||||
ca_file=ca_file,
|
||||
concurrent_connections=concurrent_connections,
|
||||
http_timeout=http_timeout,
|
||||
http_read_timeout=http_read_timeout,
|
||||
conn_idle_timeout=conn_idle_timeout,
|
||||
http_provider=http_provider,
|
||||
nsx_api_managers=nsx_api_managers)
|
||||
self.cluster = cluster.NSXClusteredAPI(nsxlib_config)
|
||||
|
||||
# create the Client
|
||||
self.client = client.NSX3Client(
|
||||
self.cluster,
|
||||
max_attempts=max_attempts)
|
||||
max_attempts=nsxlib_config.max_attempts)
|
||||
|
||||
# init the api object
|
||||
self.general_apis = utils.NsxLibApiBase(
|
||||
self.client, nsxlib_config)
|
||||
self.port_mirror = NsxLibPortMirror(
|
||||
self.client, self.max_attempts)
|
||||
self.client, nsxlib_config)
|
||||
self.bridge_endpoint = NsxLibBridgeEndpoint(
|
||||
self.client, self.max_attempts)
|
||||
self.client, nsxlib_config)
|
||||
self.logical_switch = NsxLibLogicalSwitch(
|
||||
self.client, self.max_attempts)
|
||||
self.client, nsxlib_config)
|
||||
self.logical_router = NsxLibLogicalRouter(
|
||||
self.client, self.max_attempts)
|
||||
self.client, nsxlib_config)
|
||||
self.qos_switching_profile = NsxLibQosSwitchingProfile(
|
||||
self.client, self.max_attempts)
|
||||
self.client, nsxlib_config)
|
||||
self.edge_cluster = NsxLibEdgeCluster(
|
||||
self.client, self.max_attempts)
|
||||
self.client, nsxlib_config)
|
||||
self.bridge_cluster = NsxLibBridgeCluster(
|
||||
self.client, self.max_attempts)
|
||||
self.client, nsxlib_config)
|
||||
self.transport_zone = NsxLibTransportZone(
|
||||
self.client, self.max_attempts)
|
||||
self.client, nsxlib_config)
|
||||
self.firewall_section = security.NsxLibFirewallSection(
|
||||
self.client, self.max_attempts)
|
||||
self.client, nsxlib_config)
|
||||
self.ns_group = security.NsxLibNsGroup(
|
||||
self.client, self.max_attempts, self.firewall_section)
|
||||
self.client, nsxlib_config, self.firewall_section)
|
||||
self.native_dhcp = native_dhcp.NsxLibNativeDhcp(
|
||||
self.client, nsxlib_config)
|
||||
|
||||
super(NsxLib, self).__init__()
|
||||
|
||||
@ -90,6 +74,19 @@ class NsxLib(object):
|
||||
version = node.get('node_version')
|
||||
return version
|
||||
|
||||
def build_v3_api_version_tag(self):
|
||||
return self.general_apis.build_v3_api_version_tag()
|
||||
|
||||
def is_internal_resource(self, nsx_resource):
|
||||
return self.general_apis.is_internal_resource(nsx_resource)
|
||||
|
||||
def build_v3_tags_payload(self, resource, resource_type, project_name):
|
||||
return self.general_apis.build_v3_tags_payload(
|
||||
resource, resource_type, project_name)
|
||||
|
||||
def reinitialize_cluster(self, resource, event, trigger, **kwargs):
|
||||
self.cluster.reinit_cluster()
|
||||
|
||||
|
||||
class NsxLibPortMirror(utils.NsxLibApiBase):
|
||||
|
||||
@ -182,8 +179,9 @@ class NsxLibLogicalSwitch(utils.NsxLibApiBase):
|
||||
|
||||
def delete(self, lswitch_id):
|
||||
#Using internal method so we can access max_attempts in the decorator
|
||||
@utils.retry_upon_exception(exceptions.StaleRevision,
|
||||
max_attempts=self.max_attempts)
|
||||
@utils.retry_upon_exception(
|
||||
exceptions.StaleRevision,
|
||||
max_attempts=self.nsxlib_config.max_attempts)
|
||||
def _do_delete():
|
||||
resource = ('logical-switches/%s?detach=true&cascade=true' %
|
||||
lswitch_id)
|
||||
@ -197,8 +195,9 @@ class NsxLibLogicalSwitch(utils.NsxLibApiBase):
|
||||
|
||||
def update(self, lswitch_id, name=None, admin_state=None, tags=None):
|
||||
#Using internal method so we can access max_attempts in the decorator
|
||||
@utils.retry_upon_exception(exceptions.StaleRevision,
|
||||
max_attempts=self.max_attempts)
|
||||
@utils.retry_upon_exception(
|
||||
exceptions.StaleRevision,
|
||||
max_attempts=self.nsxlib_config.max_attempts)
|
||||
def _do_update():
|
||||
resource = "logical-switches/%s" % lswitch_id
|
||||
lswitch = self.get(lswitch_id)
|
||||
@ -234,7 +233,7 @@ class NsxLibQosSwitchingProfile(utils.NsxLibApiBase):
|
||||
def _enable_shaping_in_args(self, body, burst_size=None,
|
||||
peak_bandwidth=None, average_bandwidth=None):
|
||||
for shaper in body["shaper_configuration"]:
|
||||
# Neutron currently supports only shaping of Egress traffic
|
||||
# We currently supports only shaping of Egress traffic
|
||||
if shaper["resource_type"] == "EgressRateShaper":
|
||||
shaper["enabled"] = True
|
||||
if burst_size:
|
||||
@ -249,7 +248,7 @@ class NsxLibQosSwitchingProfile(utils.NsxLibApiBase):
|
||||
|
||||
def _disable_shaping_in_args(self, body):
|
||||
for shaper in body["shaper_configuration"]:
|
||||
# Neutron currently supports only shaping of Egress traffic
|
||||
# We currently supports only shaping of Egress traffic
|
||||
if shaper["resource_type"] == "EgressRateShaper":
|
||||
shaper["enabled"] = False
|
||||
shaper["burst_size_bytes"] = 0
|
||||
|
@ -26,9 +26,6 @@ import six.moves.urllib.parse as urlparse
|
||||
|
||||
from eventlet import greenpool
|
||||
from eventlet import pools
|
||||
from neutron.callbacks import events
|
||||
from neutron.callbacks import registry
|
||||
from neutron.callbacks import resources
|
||||
from oslo_log import log
|
||||
from oslo_service import loopingcall
|
||||
from requests import adapters
|
||||
@ -121,13 +118,14 @@ class NSXRequestsHTTPProvider(AbstractHTTPProvider):
|
||||
manager=endpoint.provider.url, operation=msg)
|
||||
|
||||
def new_connection(self, cluster_api, provider):
|
||||
session = TimeoutSession(cluster_api.http_timeout,
|
||||
cluster_api.http_read_timeout)
|
||||
config = cluster_api.nsxlib_config
|
||||
session = TimeoutSession(config.http_timeout,
|
||||
config.http_read_timeout)
|
||||
session.auth = (provider.username, provider.password)
|
||||
# NSX v3 doesn't use redirects
|
||||
session.max_redirects = 0
|
||||
|
||||
session.verify = not cluster_api.insecure
|
||||
session.verify = not config.insecure
|
||||
if session.verify and provider.ca_file:
|
||||
# verify using the said ca bundle path
|
||||
session.verify = provider.ca_file
|
||||
@ -135,7 +133,7 @@ class NSXRequestsHTTPProvider(AbstractHTTPProvider):
|
||||
# we are pooling with eventlet in the cluster class
|
||||
adapter = adapters.HTTPAdapter(
|
||||
pool_connections=1, pool_maxsize=1,
|
||||
max_retries=cluster_api.retries,
|
||||
max_retries=config.retries,
|
||||
pool_block=False)
|
||||
session.mount('http://', adapter)
|
||||
session.mount('https://', adapter)
|
||||
@ -258,10 +256,10 @@ class ClusteredAPI(object):
|
||||
|
||||
_init_cluster()
|
||||
|
||||
# reinitialize upon fork for api workers to ensure each
|
||||
# process has its own keepalive loops + state
|
||||
registry.subscribe(
|
||||
_init_cluster, resources.PROCESS, events.AFTER_INIT)
|
||||
# keep this internal method for reinitialize upon fork
|
||||
# for api workers to ensure each process has its own keepalive
|
||||
# loops + state
|
||||
self._reinit_cluster = _init_cluster
|
||||
|
||||
def _init_endpoints(self, providers,
|
||||
min_conns_per_pool, max_conns_per_pool):
|
||||
@ -450,40 +448,17 @@ class NSXClusteredAPI(ClusteredAPI):
|
||||
NSX v3 cluster.
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
username=None,
|
||||
password=None,
|
||||
retries=None,
|
||||
insecure=None,
|
||||
ca_file=None,
|
||||
concurrent_connections=None,
|
||||
http_timeout=None,
|
||||
http_read_timeout=None,
|
||||
conn_idle_timeout=None,
|
||||
http_provider=None,
|
||||
nsx_api_managers=None):
|
||||
def __init__(self, nsxlib_config):
|
||||
self.nsxlib_config = nsxlib_config
|
||||
|
||||
# username, password & ca_file may be lists, in order to support
|
||||
# different credentials per nsx manager
|
||||
self._username = username
|
||||
self._password = password
|
||||
self._ca_file = ca_file
|
||||
|
||||
self.retries = retries
|
||||
self.insecure = insecure
|
||||
self.conns_per_pool = concurrent_connections
|
||||
self.http_timeout = http_timeout
|
||||
self.http_read_timeout = http_read_timeout
|
||||
self.conn_idle_timeout = conn_idle_timeout
|
||||
self.nsx_api_managers = nsx_api_managers
|
||||
|
||||
self._http_provider = http_provider or NSXRequestsHTTPProvider()
|
||||
self._http_provider = (nsxlib_config.http_provider or
|
||||
NSXRequestsHTTPProvider())
|
||||
|
||||
super(NSXClusteredAPI, self).__init__(
|
||||
self._build_conf_providers(),
|
||||
self._http_provider,
|
||||
max_conns_per_pool=self.conns_per_pool,
|
||||
keepalive_interval=self.conn_idle_timeout)
|
||||
max_conns_per_pool=self.nsxlib_config.concurrent_connections,
|
||||
keepalive_interval=self.nsxlib_config.conn_idle_timeout)
|
||||
|
||||
LOG.debug("Created NSX clustered API with '%s' "
|
||||
"provider", self._http_provider.provider_id)
|
||||
@ -496,7 +471,7 @@ class NSXClusteredAPI(ClusteredAPI):
|
||||
uri if uri.startswith('http') else
|
||||
"%s://%s" % (self._http_provider.default_scheme, uri))
|
||||
|
||||
conf_urls = self.nsx_api_managers[:]
|
||||
conf_urls = self.nsxlib_config.nsx_api_managers[:]
|
||||
urls = []
|
||||
providers = []
|
||||
provider_index = -1
|
||||
@ -512,27 +487,7 @@ class NSXClusteredAPI(ClusteredAPI):
|
||||
Provider(
|
||||
conf_url.netloc,
|
||||
urlparse.urlunparse(conf_url),
|
||||
self.username(provider_index),
|
||||
self.password(provider_index),
|
||||
self.ca_file(provider_index)))
|
||||
self.nsxlib_config.username(provider_index),
|
||||
self.nsxlib_config.password(provider_index),
|
||||
self.nsxlib_config.ca_file(provider_index)))
|
||||
return providers
|
||||
|
||||
def _attribute_by_index(self, scalar_or_list, index):
|
||||
if isinstance(scalar_or_list, list):
|
||||
if not len(scalar_or_list):
|
||||
return None
|
||||
if len(scalar_or_list) > index:
|
||||
return scalar_or_list[index]
|
||||
# if not long enough - use the first one as default
|
||||
return scalar_or_list[0]
|
||||
# this is a scalar
|
||||
return scalar_or_list
|
||||
|
||||
def username(self, index):
|
||||
return self._attribute_by_index(self._username, index)
|
||||
|
||||
def password(self, index):
|
||||
return self._attribute_by_index(self._password, index)
|
||||
|
||||
def ca_file(self, index):
|
||||
return self._attribute_by_index(self._ca_file, index)
|
||||
|
123
vmware_nsx/nsxlib/v3/config.py
Normal file
123
vmware_nsx/nsxlib/v3/config.py
Normal file
@ -0,0 +1,123 @@
|
||||
# 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.
|
||||
|
||||
|
||||
class NsxLibConfig(object):
|
||||
"""Class holding all the configuration parameters used by the nsxlib code.
|
||||
|
||||
:param nsx_api_managers: List of IP addresses of the NSX managers.
|
||||
Each IP address should be of the form:
|
||||
[<scheme>://]<ip_adress>[:<port>]
|
||||
If scheme is not provided https is used.
|
||||
If port is not provided port 80 is used for http
|
||||
and port 443 for https.
|
||||
:param username: User name for the NSX manager
|
||||
:param password: Password for the NSX manager
|
||||
:param insecure: If true, the NSX Manager server certificate is not
|
||||
verified. If false the CA bundle specified via "ca_file"
|
||||
will be used or if unsest the default system root CAs
|
||||
will be used.
|
||||
:param ca_file: Specify a CA bundle file to use in verifying the NSX
|
||||
Manager server certificate. This option is ignored if
|
||||
"insecure" is set to True. If "insecure" is set to
|
||||
False and ca_file is unset, the system root CAs will
|
||||
be used to verify the server certificate.
|
||||
|
||||
:param concurrent_connections: Maximum concurrent connections to each NSX
|
||||
manager.
|
||||
:param retries: Maximum number of times to retry a HTTP connection.
|
||||
:param http_timeout: The time in seconds before aborting a HTTP connection
|
||||
to a NSX manager.
|
||||
:param http_read_timeout: The time in seconds before aborting a HTTP read
|
||||
response from a NSX manager.
|
||||
:param conn_idle_timeout: The amount of time in seconds to wait before
|
||||
ensuring connectivity to the NSX manager if no
|
||||
manager connection has been used.
|
||||
:param http_provider: HTTPProvider object, or None.
|
||||
|
||||
:param max_attempts: Maximum number of times to retry API requests upon
|
||||
stale revision errors.
|
||||
|
||||
:param plugin_scope: The default scope for the v3 api-version tag
|
||||
:param plugin_tag: The value for the v3 api-version tag
|
||||
:param plugin_ver: The version of the plugin used as the 'os-api-version'
|
||||
tag value in the v3 api-version tag
|
||||
:param dns_nameservers: List of nameservers to configure for the DHCP
|
||||
binding entries. These will be used if there are
|
||||
no nameservers defined on the subnet.
|
||||
:param dns_domain: Domain to use for building the hostnames.
|
||||
:param dhcp_profile_uuid: The UUID of the NSX DHCP Profile that will be
|
||||
used to enable native DHCP service.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
nsx_api_managers=None,
|
||||
username=None,
|
||||
password=None,
|
||||
insecure=True,
|
||||
ca_file=None,
|
||||
concurrent_connections=10,
|
||||
retries=3,
|
||||
http_timeout=10,
|
||||
http_read_timeout=180,
|
||||
conn_idle_timeout=10,
|
||||
http_provider=None,
|
||||
max_attempts=10,
|
||||
plugin_scope=None,
|
||||
plugin_tag=None,
|
||||
plugin_ver=None,
|
||||
dns_nameservers=None,
|
||||
dns_domain='openstacklocal',
|
||||
dhcp_profile_uuid=None):
|
||||
|
||||
self.nsx_api_managers = nsx_api_managers
|
||||
self._username = username
|
||||
self._password = password
|
||||
self._ca_file = ca_file
|
||||
self.insecure = insecure
|
||||
self.concurrent_connections = concurrent_connections
|
||||
self.retries = retries
|
||||
self.http_timeout = http_timeout
|
||||
self.http_read_timeout = http_read_timeout
|
||||
self.conn_idle_timeout = conn_idle_timeout
|
||||
self.http_provider = http_provider
|
||||
self.max_attempts = max_attempts
|
||||
self.plugin_scope = plugin_scope
|
||||
self.plugin_tag = plugin_tag
|
||||
self.plugin_ver = plugin_ver
|
||||
self.dns_nameservers = dns_nameservers or []
|
||||
self.dns_domain = dns_domain
|
||||
self.dhcp_profile_uuid = dhcp_profile_uuid
|
||||
|
||||
def _attribute_by_index(self, scalar_or_list, index):
|
||||
if isinstance(scalar_or_list, list):
|
||||
if not len(scalar_or_list):
|
||||
return None
|
||||
if len(scalar_or_list) > index:
|
||||
return scalar_or_list[index]
|
||||
# if not long enough - use the first one as default
|
||||
return scalar_or_list[0]
|
||||
# this is a scalar
|
||||
return scalar_or_list
|
||||
|
||||
def username(self, index):
|
||||
return self._attribute_by_index(self._username, index)
|
||||
|
||||
def password(self, index):
|
||||
return self._attribute_by_index(self._password, index)
|
||||
|
||||
def ca_file(self, index):
|
||||
return self._attribute_by_index(self._ca_file, index)
|
@ -20,46 +20,45 @@ from neutron_lib import constants
|
||||
from vmware_nsx.nsxlib.v3 import utils
|
||||
|
||||
|
||||
def build_dhcp_server_config(network, subnet, port, project_name,
|
||||
nameservers, dhcp_profile_uuid, dns_domain):
|
||||
# Prepare the configuration for a new logical DHCP server.
|
||||
server_ip = "%s/%u" % (port['fixed_ips'][0]['ip_address'],
|
||||
netaddr.IPNetwork(subnet['cidr']).prefixlen)
|
||||
dns_nameservers = subnet['dns_nameservers']
|
||||
if not dns_nameservers or not validators.is_attr_set(dns_nameservers):
|
||||
dns_nameservers = nameservers
|
||||
gateway_ip = subnet['gateway_ip']
|
||||
if not validators.is_attr_set(gateway_ip):
|
||||
gateway_ip = None
|
||||
class NsxLibNativeDhcp(utils.NsxLibApiBase):
|
||||
|
||||
# The following code is based on _generate_opts_per_subnet() in
|
||||
# neutron/agent/linux/dhcp.py. It prepares DHCP options for a subnet.
|
||||
def build_server_config(self, network, subnet, port, tags):
|
||||
# Prepare the configuration for a new logical DHCP server.
|
||||
server_ip = "%s/%u" % (port['fixed_ips'][0]['ip_address'],
|
||||
netaddr.IPNetwork(subnet['cidr']).prefixlen)
|
||||
dns_nameservers = subnet['dns_nameservers']
|
||||
if not dns_nameservers or not validators.is_attr_set(dns_nameservers):
|
||||
dns_nameservers = self.nsxlib_config.dns_nameservers
|
||||
gateway_ip = subnet['gateway_ip']
|
||||
if not validators.is_attr_set(gateway_ip):
|
||||
gateway_ip = None
|
||||
|
||||
# Add route for directly connected network.
|
||||
host_routes = [{'network': subnet['cidr'], 'next_hop': '0.0.0.0'}]
|
||||
# Copy routes from subnet host_routes attribute.
|
||||
for hr in subnet['host_routes']:
|
||||
if hr['destination'] == constants.IPv4_ANY:
|
||||
if not gateway_ip:
|
||||
gateway_ip = hr['nexthop']
|
||||
else:
|
||||
host_routes.append({'network': hr['destination'],
|
||||
'next_hop': hr['nexthop']})
|
||||
# If gateway_ip is defined, add default route via this gateway.
|
||||
if gateway_ip:
|
||||
host_routes.append({'network': constants.IPv4_ANY,
|
||||
'next_hop': gateway_ip})
|
||||
# The following code is based on _generate_opts_per_subnet() in
|
||||
# neutron/agent/linux/dhcp.py. It prepares DHCP options for a subnet.
|
||||
|
||||
options = {'option121': {'static_routes': host_routes}}
|
||||
name = utils.get_name_and_uuid(network['name'] or 'dhcpserver',
|
||||
network['id'])
|
||||
tags = utils.build_v3_tags_payload(
|
||||
network, resource_type='os-neutron-net-id', project_name=project_name)
|
||||
return {'name': name,
|
||||
'dhcp_profile_id': dhcp_profile_uuid,
|
||||
'server_ip': server_ip,
|
||||
'dns_nameservers': dns_nameservers,
|
||||
'domain_name': dns_domain,
|
||||
'gateway_ip': gateway_ip,
|
||||
'options': options,
|
||||
'tags': tags}
|
||||
# Add route for directly connected network.
|
||||
host_routes = [{'network': subnet['cidr'], 'next_hop': '0.0.0.0'}]
|
||||
# Copy routes from subnet host_routes attribute.
|
||||
for hr in subnet['host_routes']:
|
||||
if hr['destination'] == constants.IPv4_ANY:
|
||||
if not gateway_ip:
|
||||
gateway_ip = hr['nexthop']
|
||||
else:
|
||||
host_routes.append({'network': hr['destination'],
|
||||
'next_hop': hr['nexthop']})
|
||||
# If gateway_ip is defined, add default route via this gateway.
|
||||
if gateway_ip:
|
||||
host_routes.append({'network': constants.IPv4_ANY,
|
||||
'next_hop': gateway_ip})
|
||||
|
||||
options = {'option121': {'static_routes': host_routes}}
|
||||
name = utils.get_name_and_uuid(network['name'] or 'dhcpserver',
|
||||
network['id'])
|
||||
return {'name': name,
|
||||
'dhcp_profile_id': self.nsxlib_config.dhcp_profile_uuid,
|
||||
'server_ip': server_ip,
|
||||
'dns_nameservers': dns_nameservers,
|
||||
'domain_name': self.nsxlib_config.dns_domain,
|
||||
'gateway_ip': gateway_ip,
|
||||
'options': options,
|
||||
'tags': tags}
|
||||
|
@ -22,7 +22,6 @@ from oslo_log import log
|
||||
from vmware_nsx._i18n import _, _LW
|
||||
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__)
|
||||
@ -69,7 +68,7 @@ class NSGroupManager(object):
|
||||
nested_groups = {
|
||||
self._get_nested_group_index_from_name(nsgroup): nsgroup['id']
|
||||
for nsgroup in self.nsxlib_nsgroup.list()
|
||||
if nsxlib_utils.is_internal_resource(nsgroup)}
|
||||
if self.nsxlib_nsgroup.is_internal_resource(nsgroup)}
|
||||
|
||||
if nested_groups:
|
||||
size = max(requested_size, max(nested_groups) + 1)
|
||||
@ -100,7 +99,7 @@ class NSGroupManager(object):
|
||||
name_prefix = NSGroupManager.NESTED_GROUP_NAME
|
||||
name = '%s %s' % (name_prefix, index + 1)
|
||||
description = NSGroupManager.NESTED_GROUP_DESCRIPTION
|
||||
tags = nsxlib_utils.build_v3_api_version_tag()
|
||||
tags = self.nsxlib_nsgroup.build_v3_api_version_tag()
|
||||
return self.nsxlib_nsgroup.create(name, description, tags)
|
||||
|
||||
def _hash_uuid(self, internal_id):
|
||||
|
@ -30,7 +30,6 @@ from vmware_nsx.nsxlib.v3 import utils
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
DEFAULT_SECTION = 'OS Default Section for Neutron Security-Groups'
|
||||
PORT_SG_SCOPE = 'os-security-group'
|
||||
MAX_NSGROUPS_CRITERIA_TAGS = 10
|
||||
|
||||
@ -168,7 +167,7 @@ class NsxLibNsGroup(utils.NsxLibApiBase):
|
||||
#Using internal method so we can access max_attempts in the decorator
|
||||
@utils.retry_upon_exception(
|
||||
exceptions.StaleRevision,
|
||||
max_attempts=self.max_attempts)
|
||||
max_attempts=self.nsxlib_config.max_attempts)
|
||||
def _do_update():
|
||||
nsgroup = self.read(nsgroup_id)
|
||||
if display_name is not None:
|
||||
@ -196,7 +195,7 @@ class NsxLibNsGroup(utils.NsxLibApiBase):
|
||||
#Using internal method so we can access max_attempts in the decorator
|
||||
@utils.retry_upon_exception(
|
||||
exceptions.StaleRevision,
|
||||
max_attempts=self.max_attempts)
|
||||
max_attempts=self.nsxlib_config.max_attempts)
|
||||
def _do_update():
|
||||
members_update = 'ns-groups/%s?action=%s' % (nsgroup_id, action)
|
||||
return self.client.create(members_update, members)
|
||||
@ -342,7 +341,7 @@ class NsxLibFirewallSection(utils.NsxLibApiBase):
|
||||
#Using internal method so we can access max_attempts in the decorator
|
||||
@utils.retry_upon_exception(
|
||||
exceptions.StaleRevision,
|
||||
max_attempts=self.max_attempts)
|
||||
max_attempts=self.nsxlib_config.max_attempts)
|
||||
def _do_update():
|
||||
resource = 'firewall/sections/%s' % section_id
|
||||
section = self.read(section_id)
|
||||
@ -494,7 +493,7 @@ class NsxLibFirewallSection(utils.NsxLibApiBase):
|
||||
if section['display_name'] == name:
|
||||
break
|
||||
else:
|
||||
tags = utils.build_v3_api_version_tag()
|
||||
tags = self.build_v3_api_version_tag()
|
||||
section = self.create_empty(
|
||||
name, description, nested_groups, tags)
|
||||
|
||||
|
@ -15,7 +15,6 @@
|
||||
|
||||
import retrying
|
||||
|
||||
from neutron import version as n_version
|
||||
from neutron_lib import exceptions
|
||||
from oslo_log import log
|
||||
|
||||
@ -26,33 +25,9 @@ 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'
|
||||
DEFAULT_MAX_ATTEMPTS = 10
|
||||
|
||||
|
||||
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:
|
||||
@ -63,31 +38,6 @@ def _validate_resource_type_length(resource_type):
|
||||
'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]})
|
||||
@ -174,15 +124,15 @@ def get_name_and_uuid(name, uuid, tag=None, maxlen=80):
|
||||
|
||||
class NsxLibApiBase(object):
|
||||
"""Base class for nsxlib api """
|
||||
def __init__(self, client, max_attempts):
|
||||
def __init__(self, client, nsxlib_config):
|
||||
self.client = client
|
||||
self.max_attempts = max_attempts
|
||||
self.nsxlib_config = nsxlib_config
|
||||
super(NsxLibApiBase, self).__init__()
|
||||
|
||||
def _update_resource_with_retry(self, resource, payload):
|
||||
#Using internal method so we can access max_attempts in the decorator
|
||||
@retry_upon_exception(nsxlib_exceptions.StaleRevision,
|
||||
max_attempts=self.max_attempts)
|
||||
max_attempts=self.nsxlib_config.max_attempts)
|
||||
def do_update():
|
||||
revised_payload = self.client.get(resource)
|
||||
for key_name in payload.keys():
|
||||
@ -215,3 +165,47 @@ class NsxLibApiBase(object):
|
||||
raise exceptions.ManagerError(details=err_msg)
|
||||
|
||||
return matched_results[0].get('id')
|
||||
|
||||
def build_v3_api_version_tag(self,):
|
||||
"""
|
||||
Some resources are created on the manager that do not have a
|
||||
corresponding plugin resource.
|
||||
"""
|
||||
return [{'scope': self.nsxlib_config.plugin_scope,
|
||||
'tag': self.nsxlib_config.plugin_tag},
|
||||
{'scope': "os-api-version",
|
||||
'tag': self.nsxlib_config.plugin_ver}]
|
||||
|
||||
def is_internal_resource(self, 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'] == self.nsxlib_config.plugin_scope:
|
||||
return tag['tag'] == self.nsxlib_config.plugin_tag
|
||||
return False
|
||||
|
||||
def build_v3_tags_payload(self, resource, resource_type, project_name):
|
||||
"""
|
||||
Construct the tags payload that will be pushed to NSX-v3
|
||||
Add <resource_type>:<resource-id>, os-project-id:<project-id>,
|
||||
os-project-name:<project_name> os-api-version:<plugin-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 = self.nsxlib_config.plugin_tag
|
||||
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': self.nsxlib_config.plugin_ver}]
|
||||
|
@ -84,7 +84,6 @@ from vmware_nsx.extensions import maclearning as mac_ext
|
||||
from vmware_nsx.extensions import providersecuritygroup as provider_sg
|
||||
from vmware_nsx.extensions import securitygrouplogging as sg_logging
|
||||
from vmware_nsx.nsxlib.v3 import exceptions as nsx_lib_exc
|
||||
from vmware_nsx.nsxlib.v3 import native_dhcp
|
||||
from vmware_nsx.nsxlib.v3 import ns_group_manager
|
||||
from vmware_nsx.nsxlib.v3 import nsx_constants as nsxlib_consts
|
||||
from vmware_nsx.nsxlib.v3 import resources as nsx_resources
|
||||
@ -102,6 +101,7 @@ NSX_V3_PSEC_PROFILE_NAME = 'neutron_port_spoof_guard_profile'
|
||||
NSX_V3_NO_PSEC_PROFILE_NAME = 'nsx-default-spoof-guard-vif-profile'
|
||||
NSX_V3_DHCP_PROFILE_NAME = 'neutron_port_dhcp_profile'
|
||||
NSX_V3_MAC_LEARNING_PROFILE_NAME = 'neutron_port_mac_learning_profile'
|
||||
NSX_V3_FW_DEFAULT_SECTION = 'OS Default Section for Neutron Security-Groups'
|
||||
|
||||
|
||||
# NOTE(asarfaty): the order of inheritance here is important. in order for the
|
||||
@ -166,6 +166,11 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
LOG.info(_LI("Starting NsxV3Plugin"))
|
||||
|
||||
self.nsxlib = v3_utils.get_nsxlib_wrapper()
|
||||
# reinitialize the cluster upon fork for api workers to ensure each
|
||||
# process has its own keepalive loops + state
|
||||
registry.subscribe(
|
||||
self.nsxlib.reinitialize_cluster,
|
||||
resources.PROCESS, events.AFTER_INIT)
|
||||
|
||||
self._nsx_version = self.nsxlib.get_version()
|
||||
LOG.info(_LI("NSX Version: %s"), self._nsx_version)
|
||||
@ -318,7 +323,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
if not profile:
|
||||
self._switching_profiles.create_dhcp_profile(
|
||||
NSX_V3_DHCP_PROFILE_NAME, 'Neutron DHCP Security Profile',
|
||||
tags=nsxlib_utils.build_v3_api_version_tag())
|
||||
tags=self.nsxlib.build_v3_api_version_tag())
|
||||
return self._get_dhcp_security_profile()
|
||||
|
||||
def _get_dhcp_security_profile(self):
|
||||
@ -338,7 +343,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
self._switching_profiles.create_mac_learning_profile(
|
||||
NSX_V3_MAC_LEARNING_PROFILE_NAME,
|
||||
'Neutron MAC Learning Profile',
|
||||
tags=nsxlib_utils.build_v3_api_version_tag())
|
||||
tags=self.nsxlib.build_v3_api_version_tag())
|
||||
return self._get_mac_learning_profile()
|
||||
|
||||
def _get_mac_learning_profile(self):
|
||||
@ -378,7 +383,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
self._switching_profiles.create_spoofguard_profile(
|
||||
NSX_V3_PSEC_PROFILE_NAME, 'Neutron Port Security Profile',
|
||||
whitelist_ports=True, whitelist_switches=False,
|
||||
tags=nsxlib_utils.build_v3_api_version_tag())
|
||||
tags=self.nsxlib.build_v3_api_version_tag())
|
||||
return self._get_port_security_profile()
|
||||
|
||||
def _process_security_group_logging(self):
|
||||
@ -409,7 +414,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
section_description = ("This section is handled by OpenStack to "
|
||||
"contain default rules on security-groups.")
|
||||
section_id = self.nsxlib.firewall_section.init_default(
|
||||
security.DEFAULT_SECTION, section_description,
|
||||
NSX_V3_FW_DEFAULT_SECTION, section_description,
|
||||
nsgroup_manager.nested_groups.values(),
|
||||
cfg.CONF.nsx_v3.log_security_groups_blocked_traffic)
|
||||
return nsgroup_manager, section_id
|
||||
@ -596,7 +601,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
# update the network name to indicate the neutron id too.
|
||||
net_name = utils.get_name_and_uuid(net_data['name'] or 'network',
|
||||
neutron_net_id)
|
||||
tags = nsxlib_utils.build_v3_tags_payload(
|
||||
tags = self.nsxlib.build_v3_tags_payload(
|
||||
net_data, resource_type='os-neutron-net-id',
|
||||
project_name=context.tenant_name)
|
||||
|
||||
@ -708,7 +713,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
|
||||
if is_backend_network and cfg.CONF.nsx_v3.native_dhcp_metadata:
|
||||
# Enable native metadata proxy for this network.
|
||||
tags = nsxlib_utils.build_v3_tags_payload(
|
||||
tags = self.nsxlib.build_v3_tags_payload(
|
||||
net_data, resource_type='os-neutron-net-id',
|
||||
project_name=context.tenant_name)
|
||||
name = utils.get_name_and_uuid('%s-%s' % (
|
||||
@ -915,13 +920,13 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
}
|
||||
neutron_port = super(NsxV3Plugin, self).create_port(
|
||||
context, {'port': port_data})
|
||||
server_data = native_dhcp.build_dhcp_server_config(
|
||||
network, subnet, neutron_port, context.tenant_name,
|
||||
cfg.CONF.nsx_v3.nameservers,
|
||||
cfg.CONF.nsx_v3.dhcp_profile_uuid,
|
||||
cfg.CONF.nsx_v3.dns_domain)
|
||||
net_tags = self.nsxlib.build_v3_tags_payload(
|
||||
network, resource_type='os-neutron-net-id',
|
||||
project_name=context.tenant_name)
|
||||
server_data = self.nsxlib.native_dhcp.build_server_config(
|
||||
network, subnet, neutron_port, net_tags)
|
||||
nsx_net_id = self._get_network_nsx_id(context, network['id'])
|
||||
tags = nsxlib_utils.build_v3_tags_payload(
|
||||
port_tags = self.nsxlib.build_v3_tags_payload(
|
||||
neutron_port, resource_type='os-neutron-dport-id',
|
||||
project_name=context.tenant_name)
|
||||
dhcp_server = None
|
||||
@ -932,7 +937,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
{'server': dhcp_server['id'], 'network': network['id']})
|
||||
name = self._get_port_name(context, port_data)
|
||||
nsx_port = self._port_client.create(
|
||||
nsx_net_id, dhcp_server['id'], tags=tags, name=name,
|
||||
nsx_net_id, dhcp_server['id'], tags=port_tags, name=name,
|
||||
attachment_type=nsxlib_consts.ATTACHMENT_DHCP)
|
||||
LOG.debug("Created DHCP logical port %(port)s for "
|
||||
"network %(network)s",
|
||||
@ -1254,7 +1259,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
resource_type = 'os-neutron-rport-id'
|
||||
else:
|
||||
resource_type = 'os-neutron-port-id'
|
||||
tags = nsxlib_utils.build_v3_tags_payload(
|
||||
tags = self.nsxlib.build_v3_tags_payload(
|
||||
port_data, resource_type=resource_type,
|
||||
project_name=context.tenant_name)
|
||||
resource_type = self._get_resource_type_for_device_id(
|
||||
@ -2244,7 +2249,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
edge_cluster_uuid = self._get_edge_cluster(new_tier0_uuid)
|
||||
self._routerlib.update_router_edge_cluster(
|
||||
nsx_router_id, edge_cluster_uuid)
|
||||
tags = nsxlib_utils.build_v3_tags_payload(
|
||||
tags = self.nsxlib.build_v3_tags_payload(
|
||||
router, resource_type='os-neutron-rport',
|
||||
project_name=context.tenant_name)
|
||||
self._routerlib.add_router_link_port(nsx_router_id, new_tier0_uuid,
|
||||
@ -2264,7 +2269,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
gw_info = self._extract_external_gw(context, router, is_extract=True)
|
||||
router['router']['id'] = (router['router'].get('id') or
|
||||
uuidutils.generate_uuid())
|
||||
tags = nsxlib_utils.build_v3_tags_payload(
|
||||
tags = self.nsxlib.build_v3_tags_payload(
|
||||
router['router'], resource_type='os-neutron-router-id',
|
||||
project_name=context.tenant_name)
|
||||
result = self._router_client.create(
|
||||
@ -2530,7 +2535,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
context, router_id, network_id)
|
||||
display_name = utils.get_name_and_uuid(
|
||||
subnet['name'] or 'subnet', subnet['id'])
|
||||
tags = nsxlib_utils.build_v3_tags_payload(
|
||||
tags = self.nsxlib.build_v3_tags_payload(
|
||||
port, resource_type='os-neutron-rport-id',
|
||||
project_name=context.tenant_name)
|
||||
tags.append({'scope': 'os-subnet-id', 'tag': subnet['id']})
|
||||
@ -2799,7 +2804,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
return firewall_section
|
||||
|
||||
def _create_security_group_backend_resources(self, secgroup):
|
||||
tags = nsxlib_utils.build_v3_tags_payload(
|
||||
tags = self.nsxlib.build_v3_tags_payload(
|
||||
secgroup, resource_type='os-neutron-secgr-id',
|
||||
project_name=secgroup['tenant_id'])
|
||||
name = self.nsxlib.ns_group.get_name(secgroup)
|
||||
|
@ -14,11 +14,18 @@
|
||||
# under the License.
|
||||
from oslo_config import cfg
|
||||
|
||||
from neutron import version as n_version
|
||||
|
||||
from vmware_nsx.nsxlib import v3
|
||||
from vmware_nsx.nsxlib.v3 import config
|
||||
|
||||
|
||||
NSX_NEUTRON_PLUGIN = 'NSX Neutron plugin'
|
||||
OS_NEUTRON_ID_SCOPE = 'os-neutron-id'
|
||||
|
||||
|
||||
def get_nsxlib_wrapper():
|
||||
return v3.NsxLib(
|
||||
nsxlib_config = config.NsxLibConfig(
|
||||
username=cfg.CONF.nsx_v3.nsx_api_user,
|
||||
password=cfg.CONF.nsx_v3.nsx_api_password,
|
||||
retries=cfg.CONF.nsx_v3.http_retries,
|
||||
@ -30,4 +37,11 @@ def get_nsxlib_wrapper():
|
||||
conn_idle_timeout=cfg.CONF.nsx_v3.conn_idle_timeout,
|
||||
http_provider=None,
|
||||
max_attempts=cfg.CONF.nsx_v3.retries,
|
||||
nsx_api_managers=cfg.CONF.nsx_v3.nsx_api_managers)
|
||||
nsx_api_managers=cfg.CONF.nsx_v3.nsx_api_managers,
|
||||
plugin_scope=OS_NEUTRON_ID_SCOPE,
|
||||
plugin_tag=NSX_NEUTRON_PLUGIN,
|
||||
plugin_ver=n_version.version_info.release_string(),
|
||||
dns_nameservers=cfg.CONF.nsx_v3.nameservers,
|
||||
dns_domain=cfg.CONF.nsx_v3.dns_domain,
|
||||
dhcp_profile_uuid=cfg.CONF.nsx_v3.dhcp_profile_uuid)
|
||||
return v3.NsxLib(nsxlib_config)
|
||||
|
@ -38,7 +38,6 @@ from vmware_nsx.common import utils as nsx_utils
|
||||
from vmware_nsx.db import db as nsx_db
|
||||
from vmware_nsx.nsxlib.v3 import exceptions as nsxlib_exc
|
||||
from vmware_nsx.nsxlib.v3 import nsx_constants
|
||||
from vmware_nsx.nsxlib.v3 import utils as nsxlib_utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@ -220,7 +219,7 @@ class NsxV3Driver(l2gateway_db.L2GatewayMixin):
|
||||
tenant_id = context.tenant_id
|
||||
gw_connection['tenant_id'] = tenant_id
|
||||
try:
|
||||
tags = nsxlib_utils.build_v3_tags_payload(
|
||||
tags = self._core_plugin.nsxlib.build_v3_tags_payload(
|
||||
gw_connection, resource_type='os-neutron-l2gw-id',
|
||||
project_name=context.tenant_name)
|
||||
bridge_endpoint = self._core_plugin.nsxlib.bridge_endpoint.create(
|
||||
|
@ -31,7 +31,6 @@ from vmware_nsx.db import db as nsx_db
|
||||
from vmware_nsx.nsxlib import v3 as nsxlib
|
||||
from vmware_nsx.nsxlib.v3 import exceptions as nsxlib_exc
|
||||
from vmware_nsx.nsxlib.v3 import resources as nsx_resources
|
||||
from vmware_nsx.nsxlib.v3 import utils as nsxlib_utils
|
||||
from vmware_nsx.plugins.nsx_v3 import utils as v3_utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
@ -178,7 +177,8 @@ class NsxV3Driver(base_driver.TaasBaseDriver,
|
||||
tf.get('tap_service_id'))
|
||||
src_port_id = tf.get('source_port')
|
||||
dest_port_id = ts.get('port_id')
|
||||
tags = nsxlib_utils.build_v3_tags_payload(
|
||||
nsxlib = v3_utils.get_nsxlib_wrapper()
|
||||
tags = nsxlib.build_v3_tags_payload(
|
||||
tf, resource_type='os-neutron-mirror-id',
|
||||
project_name=context._plugin_context.tenant_name)
|
||||
nsx_direction = self._convert_to_backend_direction(
|
||||
|
@ -26,7 +26,6 @@ from oslo_log import log as logging
|
||||
from vmware_nsx._i18n import _, _LW
|
||||
from vmware_nsx.common import exceptions as nsx_exc
|
||||
from vmware_nsx.db import db as nsx_db
|
||||
from vmware_nsx.nsxlib.v3 import utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
MAX_KBPS_MIN_VALUE = 1024
|
||||
@ -90,7 +89,7 @@ class QosNotificationsHandler(object):
|
||||
|
||||
def _get_tags(self, context, policy):
|
||||
policy_dict = {'id': policy.id, 'tenant_id': policy.tenant_id}
|
||||
return utils.build_v3_tags_payload(
|
||||
return self._nsxlib_qos.build_v3_tags_payload(
|
||||
policy_dict, resource_type='os-neutron-qos-id',
|
||||
project_name=context.tenant_name)
|
||||
|
||||
|
@ -21,7 +21,6 @@ from oslo_config import cfg
|
||||
|
||||
from vmware_nsx._i18n import _LE, _LI
|
||||
from vmware_nsx.common import utils as nsx_utils
|
||||
from vmware_nsx.nsxlib.v3 import native_dhcp
|
||||
from vmware_nsx.nsxlib.v3 import nsx_constants
|
||||
from vmware_nsx.nsxlib.v3 import resources
|
||||
from vmware_nsx.shell.admin.plugins.common import constants
|
||||
@ -48,7 +47,8 @@ def list_dhcp_bindings(resource, event, trigger, **kwargs):
|
||||
def nsx_update_dhcp_bindings(resource, event, trigger, **kwargs):
|
||||
"""Resync DHCP bindings for NSXv3 CrossHairs."""
|
||||
|
||||
nsx_version = utils.get_connected_nsxlib().get_version()
|
||||
nsxlib = utils.get_connected_nsxlib()
|
||||
nsx_version = nsxlib.get_version()
|
||||
if not nsx_utils.is_nsx_version_1_1_0(nsx_version):
|
||||
LOG.info(_LI("This utility is not available for NSX version %s"),
|
||||
nsx_version)
|
||||
@ -88,11 +88,11 @@ def nsx_update_dhcp_bindings(resource, event, trigger, **kwargs):
|
||||
# and update the attachment type to DHCP on the corresponding
|
||||
# logical port of the Neutron DHCP port.
|
||||
network = neutron_client.get_network(port['network_id'])
|
||||
server_data = native_dhcp.build_dhcp_server_config(
|
||||
network, subnet, port, 'admin',
|
||||
cfg.CONF.nsx_v3.nameservers,
|
||||
cfg.CONF.nsx_v3.dhcp_profile_uuid,
|
||||
cfg.CONF.nsx_v3.dns_domain)
|
||||
net_tags = nsxlib.build_v3_tags_payload(
|
||||
network, resource_type='os-neutron-net-id',
|
||||
project_name='admin')
|
||||
server_data = nsxlib.native_dhcp.build_server_config(
|
||||
network, subnet, port, net_tags)
|
||||
dhcp_server = dhcp_server_resource.create(**server_data)
|
||||
LOG.info(_LI("Created logical DHCP server %(server)s for "
|
||||
"network %(network)s"),
|
||||
|
@ -23,7 +23,6 @@ from vmware_nsx.common import utils as nsx_utils
|
||||
from vmware_nsx.dhcp_meta import rpc as nsx_rpc
|
||||
from vmware_nsx.nsxlib.v3 import nsx_constants
|
||||
from vmware_nsx.nsxlib.v3 import resources
|
||||
from vmware_nsx.nsxlib.v3 import utils as nsxlib_utils
|
||||
from vmware_nsx.shell.admin.plugins.common import constants
|
||||
from vmware_nsx.shell.admin.plugins.common import formatters
|
||||
from vmware_nsx.shell.admin.plugins.common import utils as admin_utils
|
||||
@ -105,7 +104,7 @@ def nsx_update_metadata_proxy(resource, event, trigger, **kwargs):
|
||||
lswitch_id = neutron_client.net_id_to_lswitch_id(network['id'])
|
||||
if not lswitch_id:
|
||||
continue
|
||||
tags = nsxlib_utils.build_v3_tags_payload(
|
||||
tags = utils.get_connected_nsxlib().build_v3_tags_payload(
|
||||
network, resource_type='os-neutron-net-id',
|
||||
project_name='admin')
|
||||
name = nsx_utils.get_name_and_uuid('%s-%s' % (
|
||||
|
@ -30,7 +30,6 @@ from vmware_nsx.db import db as nsx_db
|
||||
from vmware_nsx.extensions import advancedserviceproviders as as_providers
|
||||
from vmware_nsx.nsxlib.v3 import nsx_constants
|
||||
from vmware_nsx.nsxlib.v3 import resources as nsx_resources
|
||||
from vmware_nsx.nsxlib.v3 import utils as nsxlib_utils
|
||||
from vmware_nsx.tests.unit.nsx_v3 import test_plugin
|
||||
|
||||
|
||||
@ -457,7 +456,7 @@ class NsxNativeMetadataTestCase(test_plugin.NsxV3PluginTestCaseMixin):
|
||||
with self.network() as network:
|
||||
nsx_net_id = self.plugin._get_network_nsx_id(
|
||||
context.get_admin_context(), network['network']['id'])
|
||||
tags = nsxlib_utils.build_v3_tags_payload(
|
||||
tags = self.plugin.nsxlib.build_v3_tags_payload(
|
||||
network['network'], resource_type='os-neutron-net-id',
|
||||
project_name=None)
|
||||
name = utils.get_name_and_uuid('%s-%s' % (
|
||||
|
@ -20,9 +20,10 @@ import unittest
|
||||
from oslo_utils import uuidutils
|
||||
from requests import exceptions as requests_exceptions
|
||||
|
||||
from vmware_nsx.nsxlib import v3
|
||||
from vmware_nsx.nsxlib.v3 import client as nsx_client
|
||||
from vmware_nsx.nsxlib.v3 import cluster as nsx_cluster
|
||||
from vmware_nsx.plugins.nsx_v3 import utils as v3_utils
|
||||
from vmware_nsx.nsxlib.v3 import config
|
||||
|
||||
NSX_USER = 'admin'
|
||||
NSX_PASSWORD = 'default'
|
||||
@ -35,6 +36,10 @@ NSX_HTTP_READ_TIMEOUT = 180
|
||||
NSX_CONCURENT_CONN = 10
|
||||
NSX_CONN_IDLE_TIME = 10
|
||||
|
||||
PLUGIN_SCOPE = "plugin scope"
|
||||
PLUGIN_TAG = "plugin tag"
|
||||
PLUGIN_VER = "plugin ver"
|
||||
|
||||
|
||||
def _mock_nsxlib():
|
||||
def _return_id_key(*args, **kwargs):
|
||||
@ -84,13 +89,32 @@ def _mock_nsxlib():
|
||||
return_value='1.1.0').start()
|
||||
|
||||
|
||||
def get_default_nsxlib_config():
|
||||
return config.NsxLibConfig(
|
||||
username=NSX_USER,
|
||||
password=NSX_PASSWORD,
|
||||
retries=NSX_HTTP_RETRIES,
|
||||
insecure=NSX_INSECURE,
|
||||
ca_file=NSX_CERT,
|
||||
concurrent_connections=NSX_CONCURENT_CONN,
|
||||
http_timeout=NSX_HTTP_TIMEOUT,
|
||||
http_read_timeout=NSX_HTTP_READ_TIMEOUT,
|
||||
conn_idle_timeout=NSX_CONN_IDLE_TIME,
|
||||
http_provider=None,
|
||||
nsx_api_managers=[],
|
||||
plugin_scope=PLUGIN_SCOPE,
|
||||
plugin_tag=PLUGIN_TAG,
|
||||
plugin_ver=PLUGIN_VER)
|
||||
|
||||
|
||||
class NsxLibTestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self, *args, **kwargs):
|
||||
super(NsxLibTestCase, self).setUp()
|
||||
_mock_nsxlib()
|
||||
|
||||
self.nsxlib = v3_utils.get_nsxlib_wrapper()
|
||||
nsxlib_config = get_default_nsxlib_config()
|
||||
self.nsxlib = v3.NsxLib(nsxlib_config)
|
||||
|
||||
# print diffs when assert comparisons fail
|
||||
self.maxDiff = None
|
||||
@ -135,7 +159,8 @@ class NsxClientTestCase(NsxLibTestCase):
|
||||
http_read_timeout=None,
|
||||
conn_idle_timeout=None,
|
||||
nsx_api_managers=None):
|
||||
super(NsxClientTestCase.MockNSXClusteredAPI, self).__init__(
|
||||
|
||||
nsxlib_config = config.NsxLibConfig(
|
||||
username=username or NSX_USER,
|
||||
password=password or NSX_PASSWORD,
|
||||
retries=retries or NSX_HTTP_RETRIES,
|
||||
@ -148,7 +173,13 @@ class NsxClientTestCase(NsxLibTestCase):
|
||||
conn_idle_timeout=conn_idle_timeout or NSX_CONN_IDLE_TIME,
|
||||
http_provider=NsxClientTestCase.MockHTTPProvider(
|
||||
session_response=session_response),
|
||||
nsx_api_managers=nsx_api_managers or [NSX_MANAGER])
|
||||
nsx_api_managers=nsx_api_managers or [NSX_MANAGER],
|
||||
plugin_scope=PLUGIN_SCOPE,
|
||||
plugin_tag=PLUGIN_TAG,
|
||||
plugin_ver=PLUGIN_VER)
|
||||
|
||||
super(NsxClientTestCase.MockNSXClusteredAPI, self).__init__(
|
||||
nsxlib_config)
|
||||
self._record = mock.Mock()
|
||||
|
||||
def record_call(self, request, **kwargs):
|
||||
@ -279,16 +310,10 @@ class NsxClientTestCase(NsxLibTestCase):
|
||||
mock_provider.default_scheme = 'https'
|
||||
mock_provider.validate_connection = validate_conn_func
|
||||
|
||||
return nsx_cluster.NSXClusteredAPI(
|
||||
username=NSX_USER,
|
||||
password=NSX_PASSWORD,
|
||||
retries=NSX_HTTP_RETRIES,
|
||||
insecure=NSX_INSECURE,
|
||||
ca_file=NSX_CERT,
|
||||
concurrent_connections=(concurrent_connections or
|
||||
NSX_CONCURENT_CONN),
|
||||
http_timeout=NSX_HTTP_TIMEOUT,
|
||||
http_read_timeout=NSX_HTTP_READ_TIMEOUT,
|
||||
conn_idle_timeout=NSX_CONN_IDLE_TIME,
|
||||
http_provider=mock_provider,
|
||||
nsx_api_managers=conf_managers)
|
||||
nsxlib_config = get_default_nsxlib_config()
|
||||
if concurrent_connections:
|
||||
nsxlib_config.concurrent_connections = concurrent_connections
|
||||
nsxlib_config.http_provider = mock_provider
|
||||
nsxlib_config.nsx_api_managers = conf_managers
|
||||
|
||||
return nsx_cluster.NSXClusteredAPI(nsxlib_config)
|
||||
|
@ -38,13 +38,14 @@ class RequestsHTTPProviderTestCase(unittest.TestCase):
|
||||
|
||||
def test_new_connection(self):
|
||||
mock_api = mock.Mock()
|
||||
mock_api._username = 'nsxuser'
|
||||
mock_api._password = 'nsxpassword'
|
||||
mock_api.retries = 100
|
||||
mock_api.insecure = True
|
||||
mock_api._ca_file = None
|
||||
mock_api.http_timeout = 99
|
||||
mock_api.conn_idle_timeout = 39
|
||||
mock_api.nsxlib_config = mock.Mock()
|
||||
mock_api.nsxlib_config.username = 'nsxuser'
|
||||
mock_api.nsxlib_config.password = 'nsxpassword'
|
||||
mock_api.nsxlib_config.retries = 100
|
||||
mock_api.nsxlib_config.insecure = True
|
||||
mock_api.nsxlib_config.ca_file = None
|
||||
mock_api.nsxlib_config.http_timeout = 99
|
||||
mock_api.nsxlib_config.conn_idle_timeout = 39
|
||||
provider = cluster.NSXRequestsHTTPProvider()
|
||||
session = provider.new_connection(
|
||||
mock_api, cluster.Provider('9.8.7.6', 'https://9.8.7.6',
|
||||
@ -196,3 +197,8 @@ class ClusteredAPITestCase(nsxlib_testcase.NsxClientTestCase):
|
||||
|
||||
eps[0]._state = cluster.EndpointState.UP
|
||||
self.assertEqual(_get_schedule(4), [eps[0], eps[2], eps[0], eps[2]])
|
||||
|
||||
def test_reinitialize_cluster(self):
|
||||
api = self.mock_nsx_clustered_api()
|
||||
# just make sure this api is defined, and does not crash
|
||||
api._reinit_cluster()
|
||||
|
@ -52,7 +52,7 @@ class NsxLibQosTestCase(nsxlib_testcase.NsxClientTestCase):
|
||||
body["description"] = description
|
||||
|
||||
for shaper in body["shaper_configuration"]:
|
||||
# Neutron currently support only shaping of Egress traffic
|
||||
# We currently support only shaping of Egress traffic
|
||||
if shaper["resource_type"] == "EgressRateShaper":
|
||||
shaper["enabled"] = shaping_enabled
|
||||
if burst_size:
|
||||
|
@ -93,7 +93,7 @@ class TestSwitchingProfileTestCase(nsxlib_testcase.NsxClientTestCase):
|
||||
mocked_resource = self._mocked_switching_profile()
|
||||
|
||||
mocked_resource.create_spoofguard_profile(
|
||||
'neutron-spoof', 'spoofguard-for-neutron',
|
||||
'plugin-spoof', 'spoofguard-for-plugin',
|
||||
whitelist_ports=True, tags=tags)
|
||||
|
||||
test_client.assert_json_call(
|
||||
@ -101,8 +101,8 @@ class TestSwitchingProfileTestCase(nsxlib_testcase.NsxClientTestCase):
|
||||
'https://1.2.3.4/api/v1/switching-profiles',
|
||||
data=jsonutils.dumps({
|
||||
'resource_type': profile_types.SPOOF_GUARD,
|
||||
'display_name': 'neutron-spoof',
|
||||
'description': 'spoofguard-for-neutron',
|
||||
'display_name': 'plugin-spoof',
|
||||
'description': 'spoofguard-for-plugin',
|
||||
'white_list_providers': ['LPORT_BINDINGS'],
|
||||
'tags': tags
|
||||
}, sort_keys=True))
|
||||
@ -123,7 +123,7 @@ class TestSwitchingProfileTestCase(nsxlib_testcase.NsxClientTestCase):
|
||||
mocked_resource = self._mocked_switching_profile()
|
||||
|
||||
mocked_resource.create_dhcp_profile(
|
||||
'neutron-dhcp', 'dhcp-for-neutron',
|
||||
'plugin-dhcp', 'dhcp-for-plugin',
|
||||
tags=tags)
|
||||
|
||||
test_client.assert_json_call(
|
||||
@ -135,8 +135,8 @@ class TestSwitchingProfileTestCase(nsxlib_testcase.NsxClientTestCase):
|
||||
'white_list': []
|
||||
},
|
||||
'resource_type': profile_types.SWITCH_SECURITY,
|
||||
'display_name': 'neutron-dhcp',
|
||||
'description': 'dhcp-for-neutron',
|
||||
'display_name': 'plugin-dhcp',
|
||||
'description': 'dhcp-for-plugin',
|
||||
'tags': tags,
|
||||
'dhcp_filter': {
|
||||
'client_block_enabled': True,
|
||||
@ -168,7 +168,7 @@ class TestSwitchingProfileTestCase(nsxlib_testcase.NsxClientTestCase):
|
||||
mocked_resource = self._mocked_switching_profile()
|
||||
|
||||
mocked_resource.create_mac_learning_profile(
|
||||
'neutron-mac-learning', 'mac-learning-for-neutron',
|
||||
'plugin-mac-learning', 'mac-learning-for-plugin',
|
||||
tags=tags)
|
||||
|
||||
test_client.assert_json_call(
|
||||
@ -179,8 +179,8 @@ class TestSwitchingProfileTestCase(nsxlib_testcase.NsxClientTestCase):
|
||||
'enabled': True,
|
||||
},
|
||||
'resource_type': profile_types.MAC_LEARNING,
|
||||
'display_name': 'neutron-mac-learning',
|
||||
'description': 'mac-learning-for-neutron',
|
||||
'display_name': 'plugin-mac-learning',
|
||||
'description': 'mac-learning-for-plugin',
|
||||
'tags': tags,
|
||||
'source_mac_change_allowed': True,
|
||||
}, sort_keys=True))
|
||||
|
@ -13,71 +13,69 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from neutron.tests.unit.db import test_db_base_plugin_v2 as test_plugin
|
||||
from neutron import version
|
||||
from neutron_lib import exceptions as n_exc
|
||||
|
||||
from vmware_nsx.nsxlib.v3 import utils
|
||||
from vmware_nsx.tests.unit.nsxlib.v3 import nsxlib_testcase
|
||||
|
||||
|
||||
class TestNsxV3Utils(test_plugin.NeutronDbPluginV2TestCase,
|
||||
nsxlib_testcase.NsxClientTestCase):
|
||||
class TestNsxV3Utils(nsxlib_testcase.NsxClientTestCase):
|
||||
|
||||
def test_build_v3_tags_payload(self):
|
||||
result = utils.build_v3_tags_payload(
|
||||
result = self.nsxlib.build_v3_tags_payload(
|
||||
{'id': 'fake_id',
|
||||
'tenant_id': 'fake_tenant_id'},
|
||||
resource_type='os-neutron-net-id',
|
||||
resource_type='os-net-id',
|
||||
project_name='fake_tenant_name')
|
||||
expected = [{'scope': 'os-neutron-net-id', 'tag': 'fake_id'},
|
||||
expected = [{'scope': 'os-net-id', 'tag': 'fake_id'},
|
||||
{'scope': 'os-project-id', 'tag': 'fake_tenant_id'},
|
||||
{'scope': 'os-project-name', 'tag': 'fake_tenant_name'},
|
||||
{'scope': 'os-api-version',
|
||||
'tag': version.version_info.release_string()}]
|
||||
'tag': nsxlib_testcase.PLUGIN_VER}]
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
def test_build_v3_tags_payload_internal(self):
|
||||
result = utils.build_v3_tags_payload(
|
||||
result = self.nsxlib.build_v3_tags_payload(
|
||||
{'id': 'fake_id',
|
||||
'tenant_id': 'fake_tenant_id'},
|
||||
resource_type='os-neutron-net-id',
|
||||
resource_type='os-net-id',
|
||||
project_name=None)
|
||||
expected = [{'scope': 'os-neutron-net-id', 'tag': 'fake_id'},
|
||||
expected = [{'scope': 'os-net-id', 'tag': 'fake_id'},
|
||||
{'scope': 'os-project-id', 'tag': 'fake_tenant_id'},
|
||||
{'scope': 'os-project-name', 'tag': 'NSX Neutron plugin'},
|
||||
{'scope': 'os-project-name',
|
||||
'tag': nsxlib_testcase.PLUGIN_TAG},
|
||||
{'scope': 'os-api-version',
|
||||
'tag': version.version_info.release_string()}]
|
||||
'tag': nsxlib_testcase.PLUGIN_VER}]
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
def test_build_v3_tags_payload_invalid_length(self):
|
||||
self.assertRaises(n_exc.InvalidInput,
|
||||
utils.build_v3_tags_payload,
|
||||
self.nsxlib.build_v3_tags_payload,
|
||||
{'id': 'fake_id',
|
||||
'tenant_id': 'fake_tenant_id'},
|
||||
resource_type='os-neutron-maldini-rocks-id',
|
||||
resource_type='os-longer-maldini-rocks-id',
|
||||
project_name='fake')
|
||||
|
||||
def test_build_v3_api_version_tag(self):
|
||||
result = utils.build_v3_api_version_tag()
|
||||
expected = [{'scope': 'os-neutron-id',
|
||||
'tag': 'NSX Neutron plugin'},
|
||||
result = self.nsxlib.build_v3_api_version_tag()
|
||||
expected = [{'scope': nsxlib_testcase.PLUGIN_SCOPE,
|
||||
'tag': nsxlib_testcase.PLUGIN_TAG},
|
||||
{'scope': 'os-api-version',
|
||||
'tag': version.version_info.release_string()}]
|
||||
'tag': nsxlib_testcase.PLUGIN_VER}]
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
def test_is_internal_resource(self):
|
||||
project_tag = utils.build_v3_tags_payload(
|
||||
project_tag = self.nsxlib.build_v3_tags_payload(
|
||||
{'id': 'fake_id',
|
||||
'tenant_id': 'fake_tenant_id'},
|
||||
resource_type='os-neutron-net-id',
|
||||
resource_type='os-net-id',
|
||||
project_name=None)
|
||||
internal_tag = utils.build_v3_api_version_tag()
|
||||
internal_tag = self.nsxlib.build_v3_api_version_tag()
|
||||
|
||||
expect_false = utils.is_internal_resource({'tags': project_tag})
|
||||
expect_false = self.nsxlib.is_internal_resource({'tags': project_tag})
|
||||
self.assertFalse(expect_false)
|
||||
|
||||
expect_true = utils.is_internal_resource({'tags': internal_tag})
|
||||
expect_true = self.nsxlib.is_internal_resource({'tags': internal_tag})
|
||||
self.assertTrue(expect_true)
|
||||
|
||||
def test_get_name_and_uuid(self):
|
||||
@ -93,16 +91,16 @@ class TestNsxV3Utils(test_plugin.NeutronDbPluginV2TestCase,
|
||||
self.assertEqual(expected, short_name)
|
||||
|
||||
def test_build_v3_tags_max_length_payload(self):
|
||||
result = utils.build_v3_tags_payload(
|
||||
result = self.nsxlib.build_v3_tags_payload(
|
||||
{'id': 'X' * 255,
|
||||
'tenant_id': 'X' * 255},
|
||||
resource_type='os-neutron-net-id',
|
||||
resource_type='os-net-id',
|
||||
project_name='X' * 255)
|
||||
expected = [{'scope': 'os-neutron-net-id', 'tag': 'X' * 40},
|
||||
expected = [{'scope': 'os-net-id', 'tag': 'X' * 40},
|
||||
{'scope': 'os-project-id', 'tag': 'X' * 40},
|
||||
{'scope': 'os-project-name', 'tag': 'X' * 40},
|
||||
{'scope': 'os-api-version',
|
||||
'tag': version.version_info.release_string()}]
|
||||
'tag': nsxlib_testcase.PLUGIN_VER}]
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
def test_add_v3_tag(self):
|
||||
@ -123,59 +121,59 @@ class TestNsxV3Utils(test_plugin.NeutronDbPluginV2TestCase,
|
||||
'fake-tag')
|
||||
|
||||
def test_update_v3_tags_addition(self):
|
||||
tags = [{'scope': 'os-neutron-net-id', 'tag': 'X' * 40},
|
||||
tags = [{'scope': 'os-net-id', 'tag': 'X' * 40},
|
||||
{'scope': 'os-project-id', 'tag': 'Y' * 40},
|
||||
{'scope': 'os-project-name', 'tag': 'Z' * 40},
|
||||
{'scope': 'os-api-version',
|
||||
'tag': version.version_info.release_string()}]
|
||||
'tag': nsxlib_testcase.PLUGIN_VER}]
|
||||
resources = [{'scope': 'os-instance-uuid',
|
||||
'tag': 'A' * 40}]
|
||||
tags = utils.update_v3_tags(tags, resources)
|
||||
expected = [{'scope': 'os-neutron-net-id', 'tag': 'X' * 40},
|
||||
expected = [{'scope': 'os-net-id', 'tag': 'X' * 40},
|
||||
{'scope': 'os-project-id', 'tag': 'Y' * 40},
|
||||
{'scope': 'os-project-name', 'tag': 'Z' * 40},
|
||||
{'scope': 'os-api-version',
|
||||
'tag': version.version_info.release_string()},
|
||||
'tag': nsxlib_testcase.PLUGIN_VER},
|
||||
{'scope': 'os-instance-uuid',
|
||||
'tag': 'A' * 40}]
|
||||
self.assertEqual(sorted(expected, key=lambda x: x.get('tag')),
|
||||
sorted(tags, key=lambda x: x.get('tag')))
|
||||
|
||||
def test_update_v3_tags_removal(self):
|
||||
tags = [{'scope': 'os-neutron-net-id', 'tag': 'X' * 40},
|
||||
tags = [{'scope': 'os-net-id', 'tag': 'X' * 40},
|
||||
{'scope': 'os-project-id', 'tag': 'Y' * 40},
|
||||
{'scope': 'os-project-name', 'tag': 'Z' * 40},
|
||||
{'scope': 'os-api-version',
|
||||
'tag': version.version_info.release_string()}]
|
||||
resources = [{'scope': 'os-neutron-net-id',
|
||||
'tag': nsxlib_testcase.PLUGIN_VER}]
|
||||
resources = [{'scope': 'os-net-id',
|
||||
'tag': ''}]
|
||||
tags = utils.update_v3_tags(tags, resources)
|
||||
expected = [{'scope': 'os-project-id', 'tag': 'Y' * 40},
|
||||
{'scope': 'os-project-name', 'tag': 'Z' * 40},
|
||||
{'scope': 'os-api-version',
|
||||
'tag': version.version_info.release_string()}]
|
||||
'tag': nsxlib_testcase.PLUGIN_VER}]
|
||||
self.assertEqual(sorted(expected, key=lambda x: x.get('tag')),
|
||||
sorted(tags, key=lambda x: x.get('tag')))
|
||||
|
||||
def test_update_v3_tags_update(self):
|
||||
tags = [{'scope': 'os-neutron-net-id', 'tag': 'X' * 40},
|
||||
tags = [{'scope': 'os-net-id', 'tag': 'X' * 40},
|
||||
{'scope': 'os-project-id', 'tag': 'Y' * 40},
|
||||
{'scope': 'os-project-name', 'tag': 'Z' * 40},
|
||||
{'scope': 'os-api-version',
|
||||
'tag': version.version_info.release_string()}]
|
||||
'tag': nsxlib_testcase.PLUGIN_VER}]
|
||||
resources = [{'scope': 'os-project-id',
|
||||
'tag': 'A' * 40}]
|
||||
tags = utils.update_v3_tags(tags, resources)
|
||||
expected = [{'scope': 'os-neutron-net-id', 'tag': 'X' * 40},
|
||||
expected = [{'scope': 'os-net-id', 'tag': 'X' * 40},
|
||||
{'scope': 'os-project-id', 'tag': 'A' * 40},
|
||||
{'scope': 'os-project-name', 'tag': 'Z' * 40},
|
||||
{'scope': 'os-api-version',
|
||||
'tag': version.version_info.release_string()}]
|
||||
'tag': nsxlib_testcase.PLUGIN_VER}]
|
||||
self.assertEqual(sorted(expected, key=lambda x: x.get('tag')),
|
||||
sorted(tags, key=lambda x: x.get('tag')))
|
||||
|
||||
def test_update_v3_tags_repetitive_scopes(self):
|
||||
tags = [{'scope': 'os-neutron-net-id', 'tag': 'X' * 40},
|
||||
tags = [{'scope': 'os-net-id', 'tag': 'X' * 40},
|
||||
{'scope': 'os-project-id', 'tag': 'Y' * 40},
|
||||
{'scope': 'os-project-name', 'tag': 'Z' * 40},
|
||||
{'scope': 'os-security-group', 'tag': 'SG1'},
|
||||
@ -183,7 +181,7 @@ class TestNsxV3Utils(test_plugin.NeutronDbPluginV2TestCase,
|
||||
tags_update = [{'scope': 'os-security-group', 'tag': 'SG3'},
|
||||
{'scope': 'os-security-group', 'tag': 'SG4'}]
|
||||
tags = utils.update_v3_tags(tags, tags_update)
|
||||
expected = [{'scope': 'os-neutron-net-id', 'tag': 'X' * 40},
|
||||
expected = [{'scope': 'os-net-id', 'tag': 'X' * 40},
|
||||
{'scope': 'os-project-id', 'tag': 'Y' * 40},
|
||||
{'scope': 'os-project-name', 'tag': 'Z' * 40},
|
||||
{'scope': 'os-security-group', 'tag': 'SG3'},
|
||||
@ -192,14 +190,14 @@ class TestNsxV3Utils(test_plugin.NeutronDbPluginV2TestCase,
|
||||
sorted(tags, key=lambda x: x.get('tag')))
|
||||
|
||||
def test_update_v3_tags_repetitive_scopes_remove(self):
|
||||
tags = [{'scope': 'os-neutron-net-id', 'tag': 'X' * 40},
|
||||
tags = [{'scope': 'os-net-id', 'tag': 'X' * 40},
|
||||
{'scope': 'os-project-id', 'tag': 'Y' * 40},
|
||||
{'scope': 'os-project-name', 'tag': 'Z' * 40},
|
||||
{'scope': 'os-security-group', 'tag': 'SG1'},
|
||||
{'scope': 'os-security-group', 'tag': 'SG2'}]
|
||||
tags_update = [{'scope': 'os-security-group', 'tag': None}]
|
||||
tags = utils.update_v3_tags(tags, tags_update)
|
||||
expected = [{'scope': 'os-neutron-net-id', 'tag': 'X' * 40},
|
||||
expected = [{'scope': 'os-net-id', 'tag': 'X' * 40},
|
||||
{'scope': 'os-project-id', 'tag': 'Y' * 40},
|
||||
{'scope': 'os-project-name', 'tag': 'Z' * 40}]
|
||||
self.assertEqual(sorted(expected, key=lambda x: x.get('tag')),
|
||||
|
@ -25,7 +25,7 @@ from neutron.services.qos import qos_plugin
|
||||
from neutron.tests.unit.services.qos import base
|
||||
|
||||
from vmware_nsx.db import db as nsx_db
|
||||
from vmware_nsx.nsxlib.v3 import utils
|
||||
from vmware_nsx.plugins.nsx_v3 import utils as v3_utils
|
||||
from vmware_nsx.services.qos.nsx_v3 import utils as qos_utils
|
||||
from vmware_nsx.tests.unit.nsx_v3 import test_plugin
|
||||
|
||||
@ -85,6 +85,8 @@ class TestQosNsxV3Notification(base.BaseQosTestCase,
|
||||
|
||||
self.peak_bw_multiplier = cfg.CONF.NSX.qos_peak_bw_multiplier
|
||||
|
||||
self.nsxlib = v3_utils.get_nsxlib_wrapper()
|
||||
|
||||
@mock.patch(
|
||||
'neutron.objects.rbac_db.RbacNeutronDbObjectMixin'
|
||||
'.create_rbac_policy')
|
||||
@ -100,7 +102,7 @@ class TestQosNsxV3Notification(base.BaseQosTestCase,
|
||||
with mock.patch('neutron.objects.qos.policy.QosPolicy.create'):
|
||||
policy = self.qos_plugin.create_policy(self.ctxt,
|
||||
self.policy_data)
|
||||
expected_tags = utils.build_v3_tags_payload(
|
||||
expected_tags = self.nsxlib.build_v3_tags_payload(
|
||||
policy,
|
||||
resource_type='os-neutron-qos-id',
|
||||
project_name=self.ctxt.tenant_name)
|
||||
@ -129,7 +131,7 @@ class TestQosNsxV3Notification(base.BaseQosTestCase,
|
||||
self.ctxt, self.policy.id, {'policy': fields})
|
||||
# verify that the profile was updated with the correct data
|
||||
self.policy_data["policy"]["id"] = self.policy.id
|
||||
expected_tags = utils.build_v3_tags_payload(
|
||||
expected_tags = self.nsxlib.build_v3_tags_payload(
|
||||
self.policy_data["policy"],
|
||||
resource_type='os-neutron-qos-id',
|
||||
project_name=self.ctxt.tenant_name)
|
||||
|
Loading…
Reference in New Issue
Block a user