
When actual NSX versiono has been determined, we need to revisit to move the load balancer feature support to the correct version. We put this feature under NSX 2.0 for now. Change-Id: I5f6dea097442593ceeb5248625def108b18a9596
248 lines
9.5 KiB
Python
248 lines
9.5 KiB
Python
# Copyright 2016 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.
|
|
|
|
import abc
|
|
import six
|
|
|
|
from distutils import version
|
|
from oslo_log import log
|
|
|
|
from vmware_nsxlib._i18n import _
|
|
from vmware_nsxlib.v3 import client
|
|
from vmware_nsxlib.v3 import cluster
|
|
from vmware_nsxlib.v3 import core_resources
|
|
from vmware_nsxlib.v3 import exceptions
|
|
from vmware_nsxlib.v3 import load_balancer
|
|
from vmware_nsxlib.v3 import native_dhcp
|
|
from vmware_nsxlib.v3 import nsx_constants
|
|
from vmware_nsxlib.v3 import policy_defs
|
|
from vmware_nsxlib.v3 import policy_resources
|
|
from vmware_nsxlib.v3 import resources
|
|
from vmware_nsxlib.v3 import security
|
|
from vmware_nsxlib.v3 import utils
|
|
|
|
LOG = log.getLogger(__name__)
|
|
|
|
|
|
@six.add_metaclass(abc.ABCMeta)
|
|
class NsxLibBase(object):
|
|
def __init__(self, nsxlib_config):
|
|
|
|
self.set_config(nsxlib_config)
|
|
|
|
# create the Cluster
|
|
self.cluster = cluster.NSXClusteredAPI(self.nsxlib_config)
|
|
|
|
# create the Client
|
|
self.client = client.NSX3Client(
|
|
self.cluster,
|
|
nsx_api_managers=self.nsxlib_config.nsx_api_managers,
|
|
max_attempts=self.nsxlib_config.max_attempts,
|
|
url_path_base=self.client_url_prefix)
|
|
|
|
self.general_apis = utils.NsxLibApiBase(
|
|
self.client, self.nsxlib_config)
|
|
|
|
self.init_api()
|
|
|
|
super(NsxLibBase, self).__init__()
|
|
|
|
self.nsx_version = None
|
|
|
|
def set_config(self, nsxlib_config):
|
|
"""Set config user provided and extend it according to application"""
|
|
self.nsxlib_config = nsxlib_config
|
|
self.nsxlib_config.extend(keepalive_section=self.keepalive_section,
|
|
url_base=self.client_url_prefix)
|
|
|
|
@abc.abstractproperty
|
|
def client_url_prefix(self):
|
|
pass
|
|
|
|
@abc.abstractproperty
|
|
def keepalive_section(self):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def init_api(self):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def feature_supported(self, feature):
|
|
pass
|
|
|
|
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()
|
|
|
|
def subscribe(self, callback, event):
|
|
self.cluster.subscribe(callback, event)
|
|
|
|
# TODO(abhiraut): Revisit this method to generate complex boolean
|
|
# queries to search resources.
|
|
def search_by_tags(self, tags, resource_type=None):
|
|
"""Return the list of resources searched based on tags.
|
|
|
|
Currently the query only supports AND boolean operator.
|
|
:param tags: List of dictionaries containing tags. Each
|
|
NSX tag dictionary is of the form:
|
|
{'scope': <scope_key>, 'tag': <tag_value>}
|
|
:param resource_type: Optional string parameter to limit the
|
|
scope of the search to the given ResourceType.
|
|
"""
|
|
if not tags:
|
|
reason = _("Missing required argument 'tags'")
|
|
raise exceptions.NsxSearchInvalidQuery(reason=reason)
|
|
# Query will return nothing if the same scope is repeated.
|
|
query_tags = self._build_query(tags)
|
|
query = 'resource_type:%s' % resource_type if resource_type else None
|
|
if query:
|
|
query += " AND %s" % query_tags
|
|
else:
|
|
query = query_tags
|
|
url = "search?query=%s" % query
|
|
return self.client.url_get(url)
|
|
|
|
def _build_query(self, tags):
|
|
try:
|
|
return " AND ".join(['tags.scope:%(scope)s AND '
|
|
'tags.tag:%(tag)s' % item for item in tags])
|
|
except KeyError as e:
|
|
reason = _('Missing key:%s in tags') % str(e)
|
|
raise exceptions.NsxSearchInvalidQuery(reason=reason)
|
|
|
|
|
|
class NsxLib(NsxLibBase):
|
|
|
|
def init_api(self):
|
|
self.port_mirror = core_resources.NsxLibPortMirror(
|
|
self.client, self.nsxlib_config, nsxlib=self)
|
|
self.bridge_endpoint = core_resources.NsxLibBridgeEndpoint(
|
|
self.client, self.nsxlib_config, nsxlib=self)
|
|
self.logical_switch = core_resources.NsxLibLogicalSwitch(
|
|
self.client, self.nsxlib_config, nsxlib=self)
|
|
self.logical_router = core_resources.NsxLibLogicalRouter(
|
|
self.client, self.nsxlib_config, nsxlib=self)
|
|
self.switching_profile = core_resources.NsxLibSwitchingProfile(
|
|
self.client, self.nsxlib_config, nsxlib=self)
|
|
self.qos_switching_profile = core_resources.NsxLibQosSwitchingProfile(
|
|
self.client, self.nsxlib_config, nsxlib=self)
|
|
self.edge_cluster = core_resources.NsxLibEdgeCluster(
|
|
self.client, self.nsxlib_config, nsxlib=self)
|
|
self.bridge_cluster = core_resources.NsxLibBridgeCluster(
|
|
self.client, self.nsxlib_config, nsxlib=self)
|
|
self.transport_zone = core_resources.NsxLibTransportZone(
|
|
self.client, self.nsxlib_config, nsxlib=self)
|
|
self.native_dhcp_profile = core_resources.NsxLibDhcpProfile(
|
|
self.client, self.nsxlib_config, nsxlib=self)
|
|
self.native_md_proxy = core_resources.NsxLibMetadataProxy(
|
|
self.client, self.nsxlib_config, nsxlib=self)
|
|
self.firewall_section = security.NsxLibFirewallSection(
|
|
self.client, self.nsxlib_config)
|
|
self.ns_group = security.NsxLibNsGroup(
|
|
self.client, self.nsxlib_config, self.firewall_section)
|
|
self.native_dhcp = native_dhcp.NsxLibNativeDhcp(
|
|
self.client, self.nsxlib_config)
|
|
self.ip_block_subnet = core_resources.NsxLibIpBlockSubnet(
|
|
self.client, self.nsxlib_config, nsxlib=self)
|
|
self.ip_block = core_resources.NsxLibIpBlock(
|
|
self.client, self.nsxlib_config, nsxlib=self)
|
|
self.ip_set = security.NsxLibIPSet(
|
|
self.client, self.nsxlib_config)
|
|
self.logical_port = resources.LogicalPort(
|
|
self.client, self.nsxlib_config)
|
|
self.logical_router_port = resources.LogicalRouterPort(
|
|
self.client, self.nsxlib_config)
|
|
self.dhcp_server = resources.LogicalDhcpServer(
|
|
self.client, self.nsxlib_config)
|
|
self.ip_pool = resources.IpPool(
|
|
self.client, self.nsxlib_config)
|
|
self.load_balancer = load_balancer.LoadBalancer(
|
|
self.client, self.nsxlib_config)
|
|
|
|
@property
|
|
def keepalive_section(self):
|
|
return 'transport-zones'
|
|
|
|
def get_version(self):
|
|
if self.nsx_version:
|
|
return self.nsx_version
|
|
|
|
node = self.client.get("node")
|
|
self.nsx_version = node.get('node_version')
|
|
return self.nsx_version
|
|
|
|
def feature_supported(self, feature):
|
|
if (version.LooseVersion(self.get_version()) >=
|
|
version.LooseVersion(nsx_constants.NSX_VERSION_2_0_0)):
|
|
# Features available since 2.0
|
|
# TODO(tongl) Load balancer is supported in the next version
|
|
# after 2.0. Move load balancer feature to NSX version 2.x
|
|
# when the actual version of NSX has been decided.
|
|
if (feature == nsx_constants.FEATURE_EXCLUDE_PORT_BY_TAG or
|
|
feature == nsx_constants.FEATURE_ROUTER_FIREWALL or
|
|
feature == nsx_constants.FEATURE_LOAD_BALANCER):
|
|
return True
|
|
|
|
if (version.LooseVersion(self.get_version()) >=
|
|
version.LooseVersion(nsx_constants.NSX_VERSION_1_1_0)):
|
|
# Features available since 1.1
|
|
if (feature == nsx_constants.FEATURE_MAC_LEARNING or
|
|
feature == nsx_constants.FEATURE_DYNAMIC_CRITERIA):
|
|
return True
|
|
|
|
return False
|
|
|
|
@property
|
|
def client_url_prefix(self):
|
|
return client.NSX3Client.NSX_V1_API_PREFIX
|
|
|
|
|
|
class NsxPolicyLib(NsxLibBase):
|
|
|
|
def init_api(self):
|
|
self.policy_api = policy_defs.NsxPolicyApi(self.client)
|
|
self.domain = policy_resources.NsxPolicyDomainApi(self.policy_api)
|
|
self.group = policy_resources.NsxPolicyGroupApi(self.policy_api)
|
|
self.service = policy_resources.NsxPolicyL4ServiceApi(self.policy_api)
|
|
self.comm_profile = policy_resources.NsxPolicyCommunicationProfileApi(
|
|
self.policy_api)
|
|
self.comm_map = policy_resources.NsxPolicyCommunicationMapApi(
|
|
self.policy_api)
|
|
self.enforcement_point = policy_resources.NsxPolicyEnforcementPointApi(
|
|
self.policy_api)
|
|
self.deployment_map = policy_resources.NsxPolicyDeploymentMapApi(
|
|
self.policy_api)
|
|
|
|
@property
|
|
def keepalive_section(self):
|
|
return 'infra'
|
|
|
|
def feature_supported(self, feature):
|
|
return (feature == nsx_constants.FEATURE_NSX_POLICY)
|
|
|
|
@property
|
|
def client_url_prefix(self):
|
|
return client.NSX3Client.NSX_POLICY_V1_API_PREFIX
|