Anna Khmelnitsky bf31413c73 Avoid version API call for policy lib
Policy API does not expose version yet
In addition, this solves client cert generation issue (no
backend connection is yet available when certificate generation
flow is invoked, so get_version will fail on init)

Change-Id: Ibb1ea9b64bb92f3cae488db41da6bec849ce042e
2017-06-05 09:51:43 -07:00

245 lines
9.1 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)
self.bridge_endpoint = core_resources.NsxLibBridgeEndpoint(
self.client, self.nsxlib_config)
self.logical_switch = core_resources.NsxLibLogicalSwitch(
self.client, self.nsxlib_config)
self.logical_router = core_resources.NsxLibLogicalRouter(
self.client, self.nsxlib_config)
self.switching_profile = core_resources.NsxLibSwitchingProfile(
self.client, self.nsxlib_config)
self.qos_switching_profile = core_resources.NsxLibQosSwitchingProfile(
self.client, self.nsxlib_config)
self.edge_cluster = core_resources.NsxLibEdgeCluster(
self.client, self.nsxlib_config)
self.bridge_cluster = core_resources.NsxLibBridgeCluster(
self.client, self.nsxlib_config)
self.transport_zone = core_resources.NsxLibTransportZone(
self.client, self.nsxlib_config)
self.native_dhcp_profile = core_resources.NsxLibDhcpProfile(
self.client, self.nsxlib_config)
self.native_md_proxy = core_resources.NsxLibMetadataProxy(
self.client, self.nsxlib_config)
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)
self.ip_block = core_resources.NsxLibIpBlock(
self.client, self.nsxlib_config)
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
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