85197a92d3
Since oslo.utils provide the ability to generate the uuid string, and some others use oslo.utils[0] too. For consistency, this ps replaces uuid.uuid4() with uuidutils.generate_uuid(). Change-Id: I0513d43e62ecec19a8df6fd62b5e8d2e1e2f4803
716 lines
30 KiB
Python
716 lines
30 KiB
Python
# Copyright 2017 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 abc
|
|
|
|
from oslo_log import log as logging
|
|
from oslo_utils import uuidutils
|
|
import six
|
|
|
|
from vmware_nsxlib._i18n import _
|
|
from vmware_nsxlib.v3 import exceptions
|
|
from vmware_nsxlib.v3 import policy_constants
|
|
from vmware_nsxlib.v3 import policy_defs
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
@six.add_metaclass(abc.ABCMeta)
|
|
class NsxPolicyResourceBase(object):
|
|
"""Abstract class for NSX policy resources
|
|
|
|
declaring the basic apis each policy resource should support,
|
|
and implement some common apis and utilities
|
|
"""
|
|
def __init__(self, policy_api):
|
|
self.policy_api = policy_api
|
|
|
|
@abc.abstractmethod
|
|
def list(self, *args, **kwargs):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def get(self, uuid, *args, **kwargs):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def delete(self, uuid, *args, **kwargs):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def create_or_overwrite(self, *args, **kwargs):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def update(self, uuid, *args, **kwargs):
|
|
pass
|
|
|
|
@staticmethod
|
|
def _init_obj_uuid(obj_uuid):
|
|
if not obj_uuid:
|
|
# generate a random id
|
|
obj_uuid = str(uuidutils.generate_uuid())
|
|
return obj_uuid
|
|
|
|
def _canonize_name(self, name):
|
|
# remove spaces and slashes from objects names
|
|
return name.replace(' ', '_').replace('/', '_')
|
|
|
|
def get_by_name(self, name, *args, **kwargs):
|
|
# Return first match by name
|
|
resources_list = self.list(*args, **kwargs)
|
|
for obj in resources_list:
|
|
if obj.get('display_name') == name:
|
|
return obj
|
|
|
|
def _get_realized_state(self, path):
|
|
try:
|
|
result = self.policy_api.get_by_path(path)
|
|
if result and result.get('state'):
|
|
return result['state']
|
|
except exceptions.BackendResourceNotFound:
|
|
# resource not deployed yet
|
|
LOG.warning("No realized state found for %s", path)
|
|
|
|
|
|
class NsxPolicyDomainApi(NsxPolicyResourceBase):
|
|
"""NSX Policy Domain."""
|
|
def create_or_overwrite(self, name, domain_id=None, description=None,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
domain_id = self._init_obj_uuid(domain_id)
|
|
domain_def = policy_defs.DomainDef(domain_id=domain_id,
|
|
name=name,
|
|
description=description,
|
|
tenant=tenant)
|
|
return self.policy_api.create_or_update(domain_def)
|
|
|
|
def delete(self, domain_id, tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
domain_def = policy_defs.DomainDef(domain_id, tenant=tenant)
|
|
self.policy_api.delete(domain_def)
|
|
|
|
def get(self, domain_id, tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
domain_def = policy_defs.DomainDef(domain_id, tenant=tenant)
|
|
return self.policy_api.get(domain_def)
|
|
|
|
def list(self, tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
domain_def = policy_defs.DomainDef(tenant=tenant)
|
|
return self.policy_api.list(domain_def)['results']
|
|
|
|
def update(self, domain_id, name=None, description=None,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
domain_def = policy_defs.DomainDef(domain_id=domain_id,
|
|
tenant=tenant)
|
|
domain_def.update_attributes_in_body(name=name,
|
|
description=description)
|
|
# update the backend
|
|
return self.policy_api.create_or_update(domain_def)
|
|
|
|
|
|
class NsxPolicyGroupApi(NsxPolicyResourceBase):
|
|
"""NSX Policy Group (under a Domain) with a single condition."""
|
|
def create_or_overwrite(
|
|
self, name, domain_id, group_id=None,
|
|
description=None,
|
|
cond_val=None,
|
|
cond_key=policy_constants.CONDITION_KEY_TAG,
|
|
cond_op=policy_constants.CONDITION_OP_EQUALS,
|
|
cond_member_type=policy_constants.CONDITION_MEMBER_PORT,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
"""Create a group with/without a condition.
|
|
|
|
Empty condition value will result a group with no condition.
|
|
"""
|
|
|
|
group_id = self._init_obj_uuid(group_id)
|
|
# Prepare the condition
|
|
if cond_val is not None:
|
|
condition = policy_defs.Condition(value=cond_val,
|
|
key=cond_key,
|
|
operator=cond_op,
|
|
member_type=cond_member_type)
|
|
conditions = [condition]
|
|
else:
|
|
conditions = []
|
|
group_def = policy_defs.GroupDef(domain_id=domain_id,
|
|
group_id=group_id,
|
|
name=name,
|
|
description=description,
|
|
conditions=conditions,
|
|
tenant=tenant)
|
|
return self.policy_api.create_or_update(group_def)
|
|
|
|
def delete(self, domain_id, group_id,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
group_def = policy_defs.GroupDef(domain_id=domain_id,
|
|
group_id=group_id,
|
|
tenant=tenant)
|
|
self.policy_api.delete(group_def)
|
|
|
|
def get(self, domain_id, group_id,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
group_def = policy_defs.GroupDef(domain_id=domain_id,
|
|
group_id=group_id,
|
|
tenant=tenant)
|
|
return self.policy_api.get(group_def)
|
|
|
|
def list(self, domain_id,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
"""List all the groups of a specific domain."""
|
|
group_def = policy_defs.GroupDef(domain_id=domain_id,
|
|
tenant=tenant)
|
|
return self.policy_api.list(group_def)['results']
|
|
|
|
def get_by_name(self, domain_id, name,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
"""Return first group matched by name of this domain"""
|
|
return super(NsxPolicyGroupApi, self).get_by_name(name, domain_id,
|
|
tenant=tenant)
|
|
|
|
def update(self, domain_id, group_id, name=None, description=None,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
"""Update the general data of the group.
|
|
|
|
Without changing the conditions
|
|
"""
|
|
group_def = policy_defs.GroupDef(domain_id=domain_id,
|
|
group_id=group_id,
|
|
tenant=tenant)
|
|
group_def.update_attributes_in_body(name=name,
|
|
description=description)
|
|
# update the backend
|
|
return self.policy_api.create_or_update(group_def)
|
|
|
|
def update_condition(
|
|
self, domain_id, group_id,
|
|
cond_val=None,
|
|
cond_key=policy_constants.CONDITION_KEY_TAG,
|
|
cond_op=policy_constants.CONDITION_OP_EQUALS,
|
|
cond_member_type=policy_constants.CONDITION_MEMBER_PORT,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
"""Update/Remove the condition of a group.
|
|
|
|
Empty condition value will result a group with no condition.
|
|
"""
|
|
group_def = policy_defs.GroupDef(domain_id=domain_id,
|
|
group_id=group_id,
|
|
tenant=tenant)
|
|
|
|
# Prepare the condition
|
|
if cond_val is not None:
|
|
condition = policy_defs.Condition(value=cond_val,
|
|
key=cond_key,
|
|
operator=cond_op,
|
|
member_type=cond_member_type)
|
|
conditions = [condition]
|
|
else:
|
|
conditions = []
|
|
# Get the current data, and update it with the new values
|
|
# We need to do that here because of the conditions data
|
|
group = self.get(domain_id, group_id, tenant=tenant)
|
|
group_def.update_attributes_in_body(body=group, conditions=conditions)
|
|
# update the backend
|
|
return self.policy_api.create_or_update(group_def)
|
|
|
|
def get_realized_state(self, domain_id, group_id, ep_id,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
group_def = policy_defs.GroupDef(domain_id=domain_id,
|
|
group_id=group_id,
|
|
tenant=tenant)
|
|
path = group_def.get_realized_state_path(ep_id)
|
|
return self._get_realized_state(path)
|
|
|
|
|
|
class NsxPolicyServiceBase(NsxPolicyResourceBase):
|
|
"""Base class for NSX Policy Service with a single entry.
|
|
|
|
Note the nsx-policy backend supports multiple service entries per service.
|
|
At this point this is not supported here.
|
|
"""
|
|
def delete(self, service_id,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
"""Delete the service with all its entries"""
|
|
service_def = policy_defs.ServiceDef(service_id=service_id,
|
|
tenant=tenant)
|
|
service = self.policy_api.get(service_def)
|
|
# first delete all the service entries
|
|
if 'service_entries' in service:
|
|
for entry in service['service_entries']:
|
|
entry_def = self.entry_def(
|
|
service_id=service_id,
|
|
service_entry_id=entry['id'],
|
|
tenant=tenant)
|
|
self.policy_api.delete(entry_def)
|
|
self.policy_api.delete(service_def)
|
|
|
|
def get(self, service_id,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
service_def = policy_defs.ServiceDef(service_id=service_id,
|
|
tenant=tenant)
|
|
return self.policy_api.get(service_def)
|
|
|
|
def list(self, tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
service_def = policy_defs.ServiceDef(tenant=tenant)
|
|
return self.policy_api.list(service_def)['results']
|
|
|
|
def get_realized_state(self, service_id, ep_id,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
service_def = policy_defs.ServiceDef(service_id=service_id,
|
|
tenant=tenant)
|
|
path = service_def.get_realized_state_path(ep_id)
|
|
return self._get_realized_state(path)
|
|
|
|
# TODO(asarfaty) currently service update doesn't work
|
|
def update(self, service_id, name=None, description=None,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT,
|
|
**kwargs):
|
|
# service name cannot contain spaces or slashes
|
|
if name:
|
|
name = self._canonize_name(name)
|
|
|
|
# Get the current data of service & its' service entry
|
|
service = self.get(service_id, tenant=tenant)
|
|
# update the relevant data service itself:
|
|
# TODO(asarfaty): currently updating the service itself doesn't work
|
|
if name is not None:
|
|
service['display_name'] = name
|
|
if description is not None:
|
|
service['description'] = description
|
|
|
|
if (service.get('service_entries') and
|
|
len(service['service_entries']) == 1):
|
|
# update the service entry body
|
|
self._update_service_entry(
|
|
service_id, service['service_entries'][0],
|
|
name=name, description=description, **kwargs)
|
|
else:
|
|
LOG.error("Cannot update service %s - expected 1 service "
|
|
"entry", service_id)
|
|
|
|
# update the backend
|
|
service_def = policy_defs.ServiceDef(service_id=service_id,
|
|
tenant=tenant)
|
|
service_def.body = service
|
|
self.policy_api.create_or_update(service_def)
|
|
# return the updated service
|
|
return self.get(service_id, tenant=tenant)
|
|
|
|
def get_by_name(self, name, *args, **kwargs):
|
|
# service name cannot contain spaces or slashes
|
|
name = self._canonize_name(name)
|
|
return super(NsxPolicyServiceBase, self).get_by_name(
|
|
name, *args, **kwargs)
|
|
|
|
@property
|
|
def entry_def(self):
|
|
pass
|
|
|
|
|
|
class NsxPolicyL4ServiceApi(NsxPolicyServiceBase):
|
|
"""NSX Policy Service with a single L4 service entry.
|
|
|
|
Note the nsx-policy backend supports multiple service entries per service.
|
|
At this point this is not supported here.
|
|
"""
|
|
@property
|
|
def entry_def(self):
|
|
return policy_defs.L4ServiceEntryDef
|
|
|
|
def create_or_overwrite(self, name, service_id=None, description=None,
|
|
protocol=policy_constants.TCP, dest_ports=None,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
service_id = self._init_obj_uuid(service_id)
|
|
# service name cannot contain spaces or slashes
|
|
name = self._canonize_name(name)
|
|
service_def = policy_defs.ServiceDef(service_id=service_id,
|
|
name=name,
|
|
description=description,
|
|
tenant=tenant)
|
|
# NOTE(asarfaty) We set the service entry display name (which is also
|
|
# used as the id) to be the same as the service name. In case we
|
|
# support multiple service entries, we need the name to be unique.
|
|
entry_def = policy_defs.L4ServiceEntryDef(
|
|
service_id=service_id,
|
|
name=name,
|
|
description=description,
|
|
protocol=protocol,
|
|
dest_ports=dest_ports,
|
|
tenant=tenant)
|
|
|
|
return self.policy_api.create_with_parent(service_def, entry_def)
|
|
|
|
def _update_service_entry(self, service_id, srv_entry,
|
|
name=None, description=None,
|
|
protocol=None, dest_ports=None,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
entry_id = srv_entry['id']
|
|
entry_def = policy_defs.L4ServiceEntryDef(service_id=service_id,
|
|
service_entry_id=entry_id,
|
|
tenant=tenant)
|
|
entry_def.update_attributes_in_body(body=srv_entry, name=name,
|
|
description=description,
|
|
protocol=protocol,
|
|
dest_ports=dest_ports)
|
|
|
|
|
|
class NsxPolicyIcmpServiceApi(NsxPolicyServiceBase):
|
|
"""NSX Policy Service with a single ICMP service entry.
|
|
|
|
Note the nsx-policy backend supports multiple service entries per service.
|
|
At this point this is not supported here.
|
|
"""
|
|
@property
|
|
def entry_def(self):
|
|
return policy_defs.IcmpServiceEntryDef
|
|
|
|
def create_or_overwrite(self, name, service_id=None, description=None,
|
|
version=4, icmp_type=None, icmp_code=None,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
service_id = self._init_obj_uuid(service_id)
|
|
# service name cannot contain spaces or slashes
|
|
name = self._canonize_name(name)
|
|
service_def = policy_defs.ServiceDef(service_id=service_id,
|
|
name=name,
|
|
description=description,
|
|
tenant=tenant)
|
|
# NOTE(asarfaty) We set the service entry display name (which is also
|
|
# used as the id) to be the same as the service name. In case we
|
|
# support multiple service entries, we need the name to be unique.
|
|
entry_def = policy_defs.IcmpServiceEntryDef(
|
|
service_id=service_id,
|
|
name=name,
|
|
description=description,
|
|
version=version,
|
|
icmp_type=icmp_type,
|
|
icmp_code=icmp_code,
|
|
tenant=tenant)
|
|
|
|
return self.policy_api.create_with_parent(service_def, entry_def)
|
|
|
|
def _update_service_entry(self, service_id, srv_entry,
|
|
name=None, description=None,
|
|
version=None, icmp_type=None, icmp_code=None,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
entry_id = srv_entry['id']
|
|
entry_def = policy_defs.IcmpServiceEntryDef(service_id=service_id,
|
|
service_entry_id=entry_id,
|
|
tenant=tenant)
|
|
entry_def.update_attributes_in_body(body=srv_entry, name=name,
|
|
description=description,
|
|
version=version,
|
|
icmp_type=icmp_type,
|
|
icmp_code=icmp_code)
|
|
|
|
|
|
class NsxPolicyCommunicationMapApi(NsxPolicyResourceBase):
|
|
"""NSX Policy CommunicationMap (Under a Domain)."""
|
|
def _get_last_seq_num(self, domain_id, map_id,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
# get the current entries, and choose the next unused sequence number
|
|
# between the entries under the same communication map
|
|
try:
|
|
com_map = self.get(domain_id, map_id, tenant=tenant)
|
|
com_entries = com_map.get('communication_entries')
|
|
except exceptions.ResourceNotFound:
|
|
return -1
|
|
if not com_entries:
|
|
return 0
|
|
seq_nums = [int(cm['sequence_number']) for cm in com_entries]
|
|
seq_nums.sort()
|
|
return seq_nums[-1]
|
|
|
|
def create_or_overwrite(self, name, domain_id, map_id=None,
|
|
description=None, precedence=0,
|
|
category=policy_constants.CATEGORY_DEFAULT,
|
|
sequence_number=None, service_ids=None,
|
|
action=policy_constants.ACTION_ALLOW,
|
|
source_groups=None, dest_groups=None,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
"""Create CommunicationMap & Entry.
|
|
|
|
source_groups/dest_groups should be a list of group ids belonging
|
|
to the domain.
|
|
NOTE: In multi-connection environment, it is recommended to execute
|
|
this call under lock to prevent race condition where two entries
|
|
end up with same sequence number.
|
|
"""
|
|
# Validate and convert inputs
|
|
if not service_ids:
|
|
# service-ids must be provided
|
|
err_msg = (_("Cannot create a communication map %(name)s without "
|
|
"services") % {'name': name})
|
|
raise exceptions.ManagerError(details=err_msg)
|
|
if map_id:
|
|
# get the next available sequence number
|
|
last_sequence = self._get_last_seq_num(domain_id, map_id,
|
|
tenant=tenant)
|
|
else:
|
|
map_id = self._init_obj_uuid(map_id)
|
|
last_sequence = -1
|
|
|
|
if not sequence_number:
|
|
if last_sequence < 0:
|
|
sequence_number = 1
|
|
else:
|
|
sequence_number = last_sequence + 1
|
|
|
|
# Build the communication entry. Since we currently support only one
|
|
# it will have the same id as its parent
|
|
entry_def = policy_defs.CommunicationMapEntryDef(
|
|
domain_id=domain_id,
|
|
map_id=map_id,
|
|
entry_id=map_id,
|
|
name=name,
|
|
description=description,
|
|
sequence_number=sequence_number,
|
|
source_groups=source_groups,
|
|
dest_groups=dest_groups,
|
|
service_ids=service_ids,
|
|
action=action,
|
|
tenant=tenant)
|
|
|
|
map_def = policy_defs.CommunicationMapDef(
|
|
domain_id=domain_id, map_id=map_id,
|
|
tenant=tenant, name=name, description=description,
|
|
precedence=precedence, category=category)
|
|
if last_sequence < 0:
|
|
# if communication map is absent, we need to create it
|
|
return self.policy_api.create_with_parent(map_def, entry_def)
|
|
|
|
# TODO(asarfaty) combine both calls together
|
|
self.policy_api.create_or_update(map_def)
|
|
self.policy_api.create_or_update(entry_def)
|
|
return self.get(domain_id, map_id, tenant=tenant)
|
|
|
|
def delete(self, domain_id, map_id,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
map_def = policy_defs.CommunicationMapDef(
|
|
domain_id=domain_id,
|
|
map_id=map_id,
|
|
tenant=tenant)
|
|
self.policy_api.delete(map_def)
|
|
|
|
def get(self, domain_id, map_id,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
map_def = policy_defs.CommunicationMapDef(
|
|
domain_id=domain_id,
|
|
map_id=map_id,
|
|
tenant=tenant)
|
|
return self.policy_api.get(map_def)
|
|
|
|
def get_by_name(self, domain_id, name,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
"""Return first communication map entry matched by name"""
|
|
return super(NsxPolicyCommunicationMapApi, self).get_by_name(
|
|
name, domain_id, tenant=tenant)
|
|
|
|
def list(self, domain_id,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
"""List all the map entries of a specific domain."""
|
|
map_def = policy_defs.CommunicationMapDef(
|
|
domain_id=domain_id,
|
|
tenant=tenant)
|
|
return self.policy_api.list(map_def)['results']
|
|
|
|
def update(self, domain_id, map_id, name=None, description=None,
|
|
sequence_number=None, service_ids=None, action=None,
|
|
source_groups=None, dest_groups=None, precedence=None,
|
|
category=None,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
# Get the current data of communication map & its' entry
|
|
comm_map = self.get(domain_id, map_id, tenant=tenant)
|
|
# update the communication map itself:
|
|
comm_def = policy_defs.CommunicationMapDef(
|
|
domain_id=domain_id, map_id=map_id, tenant=tenant)
|
|
if name is not None:
|
|
comm_map['display_name'] = name
|
|
if description is not None:
|
|
comm_map['description'] = description
|
|
if category is not None:
|
|
comm_map['category'] = category
|
|
if precedence is not None:
|
|
comm_map['precedence'] = precedence
|
|
|
|
if (comm_map.get('communication_entries') and
|
|
len(comm_map['communication_entries']) == 1):
|
|
# update the entry body
|
|
comm_entry = comm_map['communication_entries'][0]
|
|
entry_id = comm_entry['id']
|
|
entry_def = policy_defs.CommunicationMapEntryDef(
|
|
domain_id=domain_id, map_id=map_id, entry_id=entry_id,
|
|
tenant=tenant)
|
|
entry_def.update_attributes_in_body(
|
|
body=comm_entry, name=name,
|
|
description=description,
|
|
service_ids=service_ids,
|
|
source_groups=source_groups,
|
|
dest_groups=dest_groups,
|
|
sequence_number=sequence_number,
|
|
action=action)
|
|
else:
|
|
LOG.error("Cannot update communication map %s - expected 1 entry",
|
|
map_id)
|
|
|
|
comm_def.body = comm_map
|
|
self.policy_api.create_or_update(comm_def)
|
|
|
|
# re-read the map from the backend to return the current data
|
|
return self.get(domain_id, map_id, tenant=tenant)
|
|
|
|
def get_realized_state(self, domain_id, map_id, ep_id,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
map_def = policy_defs.CommunicationMapDef(map_id, domain_id,
|
|
tenant=tenant)
|
|
path = map_def.get_realized_state_path(ep_id)
|
|
return self._get_realized_state(path)
|
|
|
|
|
|
class NsxPolicyEnforcementPointApi(NsxPolicyResourceBase):
|
|
"""NSX Policy Enforcement Point."""
|
|
|
|
def create_or_overwrite(self, name, ep_id=None, description=None,
|
|
ip_address=None, username=None,
|
|
password=None, thumbprint=None,
|
|
edge_cluster_id=None, transport_zone_id=None,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
if not ip_address or not username or password is None:
|
|
err_msg = (_("Cannot create an enforcement point without "
|
|
"ip_address, username and password"))
|
|
raise exceptions.ManagerError(details=err_msg)
|
|
ep_id = self._init_obj_uuid(ep_id)
|
|
ep_def = policy_defs.EnforcementPointDef(
|
|
ep_id=ep_id,
|
|
name=name,
|
|
description=description,
|
|
ip_address=ip_address,
|
|
username=username,
|
|
password=password,
|
|
thumbprint=thumbprint,
|
|
edge_cluster_id=edge_cluster_id,
|
|
transport_zone_id=transport_zone_id,
|
|
tenant=tenant)
|
|
return self.policy_api.create_or_update(ep_def)
|
|
|
|
def delete(self, ep_id,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
ep_def = policy_defs.EnforcementPointDef(
|
|
ep_id=ep_id, tenant=tenant)
|
|
self.policy_api.delete(ep_def)
|
|
|
|
def get(self, ep_id,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
ep_def = policy_defs.EnforcementPointDef(
|
|
ep_id=ep_id, tenant=tenant)
|
|
return self.policy_api.get(ep_def)
|
|
|
|
def list(self, tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
ep_def = policy_defs.EnforcementPointDef(tenant=tenant)
|
|
return self.policy_api.list(ep_def)['results']
|
|
|
|
def update(self, ep_id, name=None, description=None,
|
|
ip_address=None, username=None,
|
|
password=None, thumbprint=None,
|
|
edge_cluster_id=None, transport_zone_id=None,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
"""Update the enforcement point.
|
|
|
|
username & password must be defined
|
|
"""
|
|
if not username or password is None:
|
|
# username/password must be provided
|
|
err_msg = (_("Cannot update an enforcement point without "
|
|
"username and password"))
|
|
raise exceptions.ManagerError(details=err_msg)
|
|
# Get the original body because ip & thumbprint are mandatory
|
|
body = self.get(ep_id)
|
|
ep_def = policy_defs.EnforcementPointDef(ep_id=ep_id, tenant=tenant)
|
|
ep_def.update_attributes_in_body(body=body,
|
|
name=name,
|
|
description=description,
|
|
ip_address=ip_address,
|
|
username=username,
|
|
password=password,
|
|
edge_cluster_id=edge_cluster_id,
|
|
transport_zone_id=transport_zone_id,
|
|
thumbprint=thumbprint)
|
|
# update the backend
|
|
return self.policy_api.create_or_update(ep_def)
|
|
|
|
def get_realized_state(self, ep_id,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
ep_def = policy_defs.EnforcementPointDef(ep_id=ep_id, tenant=tenant)
|
|
path = ep_def.get_realized_state_path()
|
|
return self._get_realized_state(path)
|
|
|
|
|
|
class NsxPolicyDeploymentMapApi(NsxPolicyResourceBase):
|
|
"""NSX Policy Deployment Map."""
|
|
|
|
def create_or_overwrite(self, name, map_id=None, description=None,
|
|
ep_id=None, domain_id=None,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
map_id = self._init_obj_uuid(map_id)
|
|
map_def = policy_defs.DeploymentMapDef(
|
|
map_id=map_id,
|
|
name=name,
|
|
description=description,
|
|
ep_id=ep_id,
|
|
domain_id=domain_id,
|
|
tenant=tenant)
|
|
return self.policy_api.create_or_update(map_def)
|
|
|
|
def delete(self, map_id, domain_id=None,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
if not domain_id:
|
|
# domain_id must be provided
|
|
err_msg = (_("Cannot delete deployment maps without a domain"))
|
|
raise exceptions.ManagerError(details=err_msg)
|
|
|
|
map_def = policy_defs.DeploymentMapDef(
|
|
map_id=map_id, domain_id=domain_id, tenant=tenant)
|
|
self.policy_api.delete(map_def)
|
|
|
|
def get(self, map_id, domain_id=None,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
if not domain_id:
|
|
# domain_id must be provided
|
|
err_msg = (_("Cannot get deployment maps without a domain"))
|
|
raise exceptions.ManagerError(details=err_msg)
|
|
map_def = policy_defs.DeploymentMapDef(
|
|
map_id=map_id, domain_id=domain_id, tenant=tenant)
|
|
return self.policy_api.get(map_def)
|
|
|
|
def list(self, domain_id=None,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
if not domain_id:
|
|
# domain_id must be provided
|
|
err_msg = (_("Cannot list deployment maps without a domain"))
|
|
raise exceptions.ManagerError(details=err_msg)
|
|
map_def = policy_defs.DeploymentMapDef(domain_id=domain_id,
|
|
tenant=tenant)
|
|
return self.policy_api.list(map_def)['results']
|
|
|
|
def update(self, map_id, name=None, description=None,
|
|
ep_id=None, domain_id=None,
|
|
tenant=policy_constants.POLICY_INFRA_TENANT):
|
|
map_def = policy_defs.DeploymentMapDef(
|
|
map_id=map_id, domain_id=domain_id, tenant=tenant)
|
|
map_def.update_attributes_in_body(name=name,
|
|
description=description,
|
|
ep_id=ep_id,
|
|
domain_id=domain_id)
|
|
# update the backend
|
|
return self.policy_api.create_or_update(map_def)
|