nsxlib refactor - add hierarchy to the nsxlib apis
Separating the nsxlib apis into sub classed like firewall, nsgroup, logical router, in order to make the api simpler Change-Id: If67fae83515bd9e72aba116a78bb6afce1fe1ab9
This commit is contained in:
parent
40e5810d1d
commit
701de5c48f
@ -26,7 +26,7 @@ from vmware_nsx.nsxlib.v3 import utils
|
|||||||
LOG = log.getLogger(__name__)
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class NsxLib(security.Security):
|
class NsxLib(object):
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
username=None,
|
username=None,
|
||||||
@ -61,6 +61,28 @@ class NsxLib(security.Security):
|
|||||||
self.cluster,
|
self.cluster,
|
||||||
max_attempts=max_attempts)
|
max_attempts=max_attempts)
|
||||||
|
|
||||||
|
# init the api object
|
||||||
|
self.port_mirror = NsxLibPortMirror(
|
||||||
|
self.client, self.max_attempts)
|
||||||
|
self.bridge_endpoint = NsxLibBridgeEndpoint(
|
||||||
|
self.client, self.max_attempts)
|
||||||
|
self.logical_switch = NsxLibLogicalSwitch(
|
||||||
|
self.client, self.max_attempts)
|
||||||
|
self.logical_router = NsxLibLogicalRouter(
|
||||||
|
self.client, self.max_attempts)
|
||||||
|
self.qos_switching_profile = NsxLibQosSwitchingProfile(
|
||||||
|
self.client, self.max_attempts)
|
||||||
|
self.edge_cluster = NsxLibEdgeCluster(
|
||||||
|
self.client, self.max_attempts)
|
||||||
|
self.bridge_cluster = NsxLibBridgeCluster(
|
||||||
|
self.client, self.max_attempts)
|
||||||
|
self.transport_zone = NsxLibTransportZone(
|
||||||
|
self.client, self.max_attempts)
|
||||||
|
self.firewall_section = security.NsxLibFirewallSection(
|
||||||
|
self.client, self.max_attempts)
|
||||||
|
self.ns_group = security.NsxLibNsGroup(
|
||||||
|
self.client, self.max_attempts, self.firewall_section)
|
||||||
|
|
||||||
super(NsxLib, self).__init__()
|
super(NsxLib, self).__init__()
|
||||||
|
|
||||||
def get_version(self):
|
def get_version(self):
|
||||||
@ -68,51 +90,74 @@ class NsxLib(security.Security):
|
|||||||
version = node.get('node_version')
|
version = node.get('node_version')
|
||||||
return version
|
return version
|
||||||
|
|
||||||
def get_edge_cluster(self, edge_cluster_uuid):
|
|
||||||
resource = "edge-clusters/%s" % edge_cluster_uuid
|
|
||||||
return self.client.get(resource)
|
|
||||||
|
|
||||||
def update_resource_with_retry(self, resource, payload):
|
class NsxLibPortMirror(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)
|
|
||||||
def _do_update():
|
|
||||||
revised_payload = self.client.get(resource)
|
|
||||||
for key_name in payload.keys():
|
|
||||||
revised_payload[key_name] = payload[key_name]
|
|
||||||
return self.client.update(resource, revised_payload)
|
|
||||||
|
|
||||||
return _do_update()
|
def create_session(self, source_ports, dest_ports, direction,
|
||||||
|
description, name, tags):
|
||||||
|
"""Create a PortMirror Session on the backend.
|
||||||
|
|
||||||
def delete_resource_by_values(self, resource,
|
:param source_ports: List of UUIDs of the ports whose traffic is to be
|
||||||
skip_not_found=True, **kwargs):
|
mirrored.
|
||||||
resources_get = self.client.get(resource)
|
:param dest_ports: List of UUIDs of the ports where the mirrored
|
||||||
matched_num = 0
|
traffic is to be sent.
|
||||||
for res in resources_get['results']:
|
:param direction: String representing the direction of traffic to be
|
||||||
if utils.dict_match(kwargs, res):
|
mirrored. [INGRESS, EGRESS, BIDIRECTIONAL]
|
||||||
LOG.debug("Deleting %s from resource %s", res, resource)
|
:param description: String representing the description of the session.
|
||||||
delete_resource = resource + "/" + str(res['id'])
|
:param name: String representing the name of the session.
|
||||||
self.client.delete(delete_resource)
|
:param tags: nsx backend specific tags.
|
||||||
matched_num = matched_num + 1
|
"""
|
||||||
if matched_num == 0:
|
|
||||||
if skip_not_found:
|
|
||||||
LOG.warning(_LW("No resource in %(res)s matched for values: "
|
|
||||||
"%(values)s"), {'res': resource,
|
|
||||||
'values': kwargs})
|
|
||||||
else:
|
|
||||||
err_msg = (_("No resource in %(res)s matched for values: "
|
|
||||||
"%(values)s") % {'res': resource,
|
|
||||||
'values': kwargs})
|
|
||||||
raise exceptions.ResourceNotFound(
|
|
||||||
manager=self.cluster.nsx_api_managers,
|
|
||||||
operation=err_msg)
|
|
||||||
elif matched_num > 1:
|
|
||||||
LOG.warning(_LW("%(num)s resources in %(res)s matched for values: "
|
|
||||||
"%(values)s"), {'num': matched_num,
|
|
||||||
'res': resource,
|
|
||||||
'values': kwargs})
|
|
||||||
|
|
||||||
def create_logical_switch(self, display_name, transport_zone_id, tags,
|
resource = 'mirror-sessions'
|
||||||
|
body = {'direction': direction,
|
||||||
|
'tags': tags,
|
||||||
|
'display_name': name,
|
||||||
|
'description': description,
|
||||||
|
'mirror_sources': source_ports,
|
||||||
|
'mirror_destination': dest_ports}
|
||||||
|
return self.client.create(resource, body)
|
||||||
|
|
||||||
|
def delete_session(self, mirror_session_id):
|
||||||
|
"""Delete a PortMirror session on the backend.
|
||||||
|
|
||||||
|
:param mirror_session_id: string representing the UUID of the port
|
||||||
|
mirror session to be deleted.
|
||||||
|
"""
|
||||||
|
resource = 'mirror-sessions/%s' % mirror_session_id
|
||||||
|
self.client.delete(resource)
|
||||||
|
|
||||||
|
|
||||||
|
class NsxLibBridgeEndpoint(utils.NsxLibApiBase):
|
||||||
|
|
||||||
|
def create(self, device_name, seg_id, tags):
|
||||||
|
"""Create a bridge endpoint on the backend.
|
||||||
|
|
||||||
|
Create a bridge endpoint resource on a bridge cluster for the L2
|
||||||
|
gateway network connection.
|
||||||
|
:param device_name: device_name actually refers to the bridge cluster's
|
||||||
|
UUID.
|
||||||
|
:param seg_id: integer representing the VLAN segmentation ID.
|
||||||
|
:param tags: nsx backend specific tags.
|
||||||
|
"""
|
||||||
|
resource = 'bridge-endpoints'
|
||||||
|
body = {'bridge_cluster_id': device_name,
|
||||||
|
'tags': tags,
|
||||||
|
'vlan': seg_id}
|
||||||
|
return self.client.create(resource, body)
|
||||||
|
|
||||||
|
def delete(self, bridge_endpoint_id):
|
||||||
|
"""Delete a bridge endpoint on the backend.
|
||||||
|
|
||||||
|
:param bridge_endpoint_id: string representing the UUID of the bridge
|
||||||
|
endpoint to be deleted.
|
||||||
|
"""
|
||||||
|
resource = 'bridge-endpoints/%s' % bridge_endpoint_id
|
||||||
|
self.client.delete(resource)
|
||||||
|
|
||||||
|
|
||||||
|
class NsxLibLogicalSwitch(utils.NsxLibApiBase):
|
||||||
|
|
||||||
|
def create(self, display_name, transport_zone_id, tags,
|
||||||
replication_mode=nsx_constants.MTEP,
|
replication_mode=nsx_constants.MTEP,
|
||||||
admin_state=True, vlan_id=None):
|
admin_state=True, vlan_id=None):
|
||||||
# TODO(salv-orlando): Validate Replication mode and admin_state
|
# TODO(salv-orlando): Validate Replication mode and admin_state
|
||||||
@ -135,7 +180,7 @@ class NsxLib(security.Security):
|
|||||||
|
|
||||||
return self.client.create(resource, body)
|
return self.client.create(resource, body)
|
||||||
|
|
||||||
def delete_logical_switch(self, lswitch_id):
|
def delete(self, lswitch_id):
|
||||||
#Using internal method so we can access max_attempts in the decorator
|
#Using internal method so we can access max_attempts in the decorator
|
||||||
@utils.retry_upon_exception(exceptions.StaleRevision,
|
@utils.retry_upon_exception(exceptions.StaleRevision,
|
||||||
max_attempts=self.max_attempts)
|
max_attempts=self.max_attempts)
|
||||||
@ -146,18 +191,17 @@ class NsxLib(security.Security):
|
|||||||
|
|
||||||
_do_delete()
|
_do_delete()
|
||||||
|
|
||||||
def get_logical_switch(self, logical_switch_id):
|
def get(self, logical_switch_id):
|
||||||
resource = "logical-switches/%s" % logical_switch_id
|
resource = "logical-switches/%s" % logical_switch_id
|
||||||
return self.client.get(resource)
|
return self.client.get(resource)
|
||||||
|
|
||||||
def update_logical_switch(self, lswitch_id, name=None, admin_state=None,
|
def update(self, lswitch_id, name=None, admin_state=None, tags=None):
|
||||||
tags=None):
|
|
||||||
#Using internal method so we can access max_attempts in the decorator
|
#Using internal method so we can access max_attempts in the decorator
|
||||||
@utils.retry_upon_exception(exceptions.StaleRevision,
|
@utils.retry_upon_exception(exceptions.StaleRevision,
|
||||||
max_attempts=self.max_attempts)
|
max_attempts=self.max_attempts)
|
||||||
def _do_update():
|
def _do_update():
|
||||||
resource = "logical-switches/%s" % lswitch_id
|
resource = "logical-switches/%s" % lswitch_id
|
||||||
lswitch = self.get_logical_switch(lswitch_id)
|
lswitch = self.get(lswitch_id)
|
||||||
if name is not None:
|
if name is not None:
|
||||||
lswitch['display_name'] = name
|
lswitch['display_name'] = name
|
||||||
if admin_state is not None:
|
if admin_state is not None:
|
||||||
@ -171,70 +215,16 @@ class NsxLib(security.Security):
|
|||||||
|
|
||||||
return _do_update()
|
return _do_update()
|
||||||
|
|
||||||
def add_nat_rule(self, logical_router_id, action, translated_network,
|
|
||||||
source_net=None, dest_net=None,
|
|
||||||
enabled=True, rule_priority=None):
|
|
||||||
resource = 'logical-routers/%s/nat/rules' % logical_router_id
|
|
||||||
body = {'action': action,
|
|
||||||
'enabled': enabled,
|
|
||||||
'translated_network': translated_network}
|
|
||||||
if source_net:
|
|
||||||
body['match_source_network'] = source_net
|
|
||||||
if dest_net:
|
|
||||||
body['match_destination_network'] = dest_net
|
|
||||||
if rule_priority:
|
|
||||||
body['rule_priority'] = rule_priority
|
|
||||||
return self.client.create(resource, body)
|
|
||||||
|
|
||||||
def add_static_route(self, logical_router_id, dest_cidr, nexthop):
|
class NsxLibQosSwitchingProfile(utils.NsxLibApiBase):
|
||||||
resource = ('logical-routers/%s/routing/static-routes' %
|
|
||||||
logical_router_id)
|
|
||||||
body = {}
|
|
||||||
if dest_cidr:
|
|
||||||
body['network'] = dest_cidr
|
|
||||||
if nexthop:
|
|
||||||
body['next_hops'] = [{"ip_address": nexthop}]
|
|
||||||
return self.client.create(resource, body)
|
|
||||||
|
|
||||||
def delete_static_route(self, logical_router_id, static_route_id):
|
def _build_args(self, tags, name=None, description=None):
|
||||||
resource = 'logical-routers/%s/routing/static-routes/%s' % (
|
|
||||||
logical_router_id, static_route_id)
|
|
||||||
self.client.delete(resource)
|
|
||||||
|
|
||||||
def delete_static_route_by_values(self, logical_router_id,
|
|
||||||
dest_cidr=None, nexthop=None):
|
|
||||||
resource = ('logical-routers/%s/routing/static-routes' %
|
|
||||||
logical_router_id)
|
|
||||||
kwargs = {}
|
|
||||||
if dest_cidr:
|
|
||||||
kwargs['network'] = dest_cidr
|
|
||||||
if nexthop:
|
|
||||||
kwargs['next_hops'] = [{"ip_address": nexthop}]
|
|
||||||
return self.delete_resource_by_values(resource, **kwargs)
|
|
||||||
|
|
||||||
def delete_nat_rule(self, logical_router_id, nat_rule_id):
|
|
||||||
resource = 'logical-routers/%s/nat/rules/%s' % (logical_router_id,
|
|
||||||
nat_rule_id)
|
|
||||||
self.client.delete(resource)
|
|
||||||
|
|
||||||
def delete_nat_rule_by_values(self, logical_router_id, **kwargs):
|
|
||||||
resource = 'logical-routers/%s/nat/rules' % logical_router_id
|
|
||||||
return self.delete_resource_by_values(resource, **kwargs)
|
|
||||||
|
|
||||||
def update_logical_router_advertisement(self, logical_router_id, **kwargs):
|
|
||||||
resource = ('logical-routers/%s/routing/advertisement' %
|
|
||||||
logical_router_id)
|
|
||||||
return self.update_resource_with_retry(resource, kwargs)
|
|
||||||
|
|
||||||
def _build_qos_switching_profile_args(self, tags, name=None,
|
|
||||||
description=None):
|
|
||||||
body = {"resource_type": "QosSwitchingProfile",
|
body = {"resource_type": "QosSwitchingProfile",
|
||||||
"tags": tags}
|
"tags": tags}
|
||||||
return self._update_qos_switching_profile_args(
|
return self._update_args(
|
||||||
body, name=name, description=description)
|
body, name=name, description=description)
|
||||||
|
|
||||||
def _update_qos_switching_profile_args(self, body, name=None,
|
def _update_args(self, body, name=None, description=None):
|
||||||
description=None):
|
|
||||||
if name:
|
if name:
|
||||||
body["display_name"] = name
|
body["display_name"] = name
|
||||||
if description:
|
if description:
|
||||||
@ -277,24 +267,20 @@ class NsxLib(security.Security):
|
|||||||
|
|
||||||
return body
|
return body
|
||||||
|
|
||||||
def create_qos_switching_profile(self, tags, name=None,
|
def create(self, tags, name=None, description=None):
|
||||||
description=None):
|
|
||||||
resource = 'switching-profiles'
|
resource = 'switching-profiles'
|
||||||
body = self._build_qos_switching_profile_args(tags, name,
|
body = self._build_args(tags, name, description)
|
||||||
description)
|
|
||||||
return self.client.create(resource, body)
|
return self.client.create(resource, body)
|
||||||
|
|
||||||
def update_qos_switching_profile(self, profile_id, tags, name=None,
|
def update(self, profile_id, tags, name=None, description=None):
|
||||||
description=None):
|
|
||||||
resource = 'switching-profiles/%s' % profile_id
|
resource = 'switching-profiles/%s' % profile_id
|
||||||
# get the current configuration
|
# get the current configuration
|
||||||
body = self.get_qos_switching_profile(profile_id)
|
body = self.get(profile_id)
|
||||||
# update the relevant fields
|
# update the relevant fields
|
||||||
body = self._update_qos_switching_profile_args(body, name,
|
body = self._update_args(body, name, description)
|
||||||
description)
|
return self._update_resource_with_retry(resource, body)
|
||||||
return self.update_resource_with_retry(resource, body)
|
|
||||||
|
|
||||||
def update_qos_switching_profile_shaping(self, profile_id,
|
def update_shaping(self, profile_id,
|
||||||
shaping_enabled=False,
|
shaping_enabled=False,
|
||||||
burst_size=None,
|
burst_size=None,
|
||||||
peak_bandwidth=None,
|
peak_bandwidth=None,
|
||||||
@ -302,7 +288,7 @@ class NsxLib(security.Security):
|
|||||||
qos_marking=None, dscp=None):
|
qos_marking=None, dscp=None):
|
||||||
resource = 'switching-profiles/%s' % profile_id
|
resource = 'switching-profiles/%s' % profile_id
|
||||||
# get the current configuration
|
# get the current configuration
|
||||||
body = self.get_qos_switching_profile(profile_id)
|
body = self.get(profile_id)
|
||||||
# update the relevant fields
|
# update the relevant fields
|
||||||
if shaping_enabled:
|
if shaping_enabled:
|
||||||
body = self._enable_shaping_in_args(
|
body = self._enable_shaping_in_args(
|
||||||
@ -312,77 +298,103 @@ class NsxLib(security.Security):
|
|||||||
else:
|
else:
|
||||||
body = self._disable_shaping_in_args(body)
|
body = self._disable_shaping_in_args(body)
|
||||||
body = self._update_dscp_in_args(body, qos_marking, dscp)
|
body = self._update_dscp_in_args(body, qos_marking, dscp)
|
||||||
return self.update_resource_with_retry(resource, body)
|
return self._update_resource_with_retry(resource, body)
|
||||||
|
|
||||||
def get_qos_switching_profile(self, profile_id):
|
def get(self, profile_id):
|
||||||
resource = 'switching-profiles/%s' % profile_id
|
resource = 'switching-profiles/%s' % profile_id
|
||||||
return self.client.get(resource)
|
return self.client.get(resource)
|
||||||
|
|
||||||
def delete_qos_switching_profile(self, profile_id):
|
def delete(self, profile_id):
|
||||||
resource = 'switching-profiles/%s' % profile_id
|
resource = 'switching-profiles/%s' % profile_id
|
||||||
self.client.delete(resource)
|
self.client.delete(resource)
|
||||||
|
|
||||||
def create_bridge_endpoint(self, device_name, seg_id, tags):
|
|
||||||
"""Create a bridge endpoint on the backend.
|
|
||||||
|
|
||||||
Create a bridge endpoint resource on a bridge cluster for the L2
|
class NsxLibLogicalRouter(utils.NsxLibApiBase):
|
||||||
gateway network connection.
|
|
||||||
:param device_name: device_name actually refers to the bridge cluster's
|
def _delete_resource_by_values(self, resource,
|
||||||
UUID.
|
skip_not_found=True, **kwargs):
|
||||||
:param seg_id: integer representing the VLAN segmentation ID.
|
resources_get = self.client.get(resource)
|
||||||
:param tags: nsx backend specific tags.
|
matched_num = 0
|
||||||
"""
|
for res in resources_get['results']:
|
||||||
resource = 'bridge-endpoints'
|
if utils.dict_match(kwargs, res):
|
||||||
body = {'bridge_cluster_id': device_name,
|
LOG.debug("Deleting %s from resource %s", res, resource)
|
||||||
'tags': tags,
|
delete_resource = resource + "/" + str(res['id'])
|
||||||
'vlan': seg_id}
|
self.client.delete(delete_resource)
|
||||||
|
matched_num = matched_num + 1
|
||||||
|
if matched_num == 0:
|
||||||
|
if skip_not_found:
|
||||||
|
LOG.warning(_LW("No resource in %(res)s matched for values: "
|
||||||
|
"%(values)s"), {'res': resource,
|
||||||
|
'values': kwargs})
|
||||||
|
else:
|
||||||
|
err_msg = (_("No resource in %(res)s matched for values: "
|
||||||
|
"%(values)s") % {'res': resource,
|
||||||
|
'values': kwargs})
|
||||||
|
raise exceptions.ResourceNotFound(
|
||||||
|
manager=self.cluster.nsx_api_managers,
|
||||||
|
operation=err_msg)
|
||||||
|
elif matched_num > 1:
|
||||||
|
LOG.warning(_LW("%(num)s resources in %(res)s matched for values: "
|
||||||
|
"%(values)s"), {'num': matched_num,
|
||||||
|
'res': resource,
|
||||||
|
'values': kwargs})
|
||||||
|
|
||||||
|
def add_nat_rule(self, logical_router_id, action, translated_network,
|
||||||
|
source_net=None, dest_net=None,
|
||||||
|
enabled=True, rule_priority=None):
|
||||||
|
resource = 'logical-routers/%s/nat/rules' % logical_router_id
|
||||||
|
body = {'action': action,
|
||||||
|
'enabled': enabled,
|
||||||
|
'translated_network': translated_network}
|
||||||
|
if source_net:
|
||||||
|
body['match_source_network'] = source_net
|
||||||
|
if dest_net:
|
||||||
|
body['match_destination_network'] = dest_net
|
||||||
|
if rule_priority:
|
||||||
|
body['rule_priority'] = rule_priority
|
||||||
return self.client.create(resource, body)
|
return self.client.create(resource, body)
|
||||||
|
|
||||||
def delete_bridge_endpoint(self, bridge_endpoint_id):
|
def add_static_route(self, logical_router_id, dest_cidr, nexthop):
|
||||||
"""Delete a bridge endpoint on the backend.
|
resource = ('logical-routers/%s/routing/static-routes' %
|
||||||
|
logical_router_id)
|
||||||
|
body = {}
|
||||||
|
if dest_cidr:
|
||||||
|
body['network'] = dest_cidr
|
||||||
|
if nexthop:
|
||||||
|
body['next_hops'] = [{"ip_address": nexthop}]
|
||||||
|
return self.client.create(resource, body)
|
||||||
|
|
||||||
:param bridge_endpoint_id: string representing the UUID of the bridge
|
def delete_static_route(self, logical_router_id, static_route_id):
|
||||||
endpoint to be deleted.
|
resource = 'logical-routers/%s/routing/static-routes/%s' % (
|
||||||
"""
|
logical_router_id, static_route_id)
|
||||||
resource = 'bridge-endpoints/%s' % bridge_endpoint_id
|
|
||||||
self.client.delete(resource)
|
self.client.delete(resource)
|
||||||
|
|
||||||
def _get_resource_by_name_or_id(self, name_or_id, resource):
|
def delete_static_route_by_values(self, logical_router_id,
|
||||||
all_results = self.client.get(resource)['results']
|
dest_cidr=None, nexthop=None):
|
||||||
matched_results = []
|
resource = ('logical-routers/%s/routing/static-routes' %
|
||||||
for rs in all_results:
|
logical_router_id)
|
||||||
if rs.get('id') == name_or_id:
|
kwargs = {}
|
||||||
# Matched by id - must be unique
|
if dest_cidr:
|
||||||
return name_or_id
|
kwargs['network'] = dest_cidr
|
||||||
|
if nexthop:
|
||||||
|
kwargs['next_hops'] = [{"ip_address": nexthop}]
|
||||||
|
return self._delete_resource_by_values(resource, **kwargs)
|
||||||
|
|
||||||
if rs.get('display_name') == name_or_id:
|
def delete_nat_rule(self, logical_router_id, nat_rule_id):
|
||||||
# Matched by name - add to the list to verify it is unique
|
resource = 'logical-routers/%s/nat/rules/%s' % (logical_router_id,
|
||||||
matched_results.append(rs)
|
nat_rule_id)
|
||||||
|
self.client.delete(resource)
|
||||||
|
|
||||||
if len(matched_results) == 0:
|
def delete_nat_rule_by_values(self, logical_router_id, **kwargs):
|
||||||
err_msg = (_("Could not find %(resource)s %(name)s") %
|
resource = 'logical-routers/%s/nat/rules' % logical_router_id
|
||||||
{'name': name_or_id, 'resource': resource})
|
return self._delete_resource_by_values(resource, **kwargs)
|
||||||
# TODO(asarfaty): improve exception handling...
|
|
||||||
raise exceptions.ManagerError(details=err_msg)
|
|
||||||
elif len(matched_results) > 1:
|
|
||||||
err_msg = (_("Found multiple %(resource)s named %(name)s") %
|
|
||||||
{'name': name_or_id, 'resource': resource})
|
|
||||||
# TODO(asarfaty): improve exception handling...
|
|
||||||
raise exceptions.ManagerError(details=err_msg)
|
|
||||||
|
|
||||||
return matched_results[0].get('id')
|
def update_advertisement(self, logical_router_id, **kwargs):
|
||||||
|
resource = ('logical-routers/%s/routing/advertisement' %
|
||||||
|
logical_router_id)
|
||||||
|
return self._update_resource_with_retry(resource, kwargs)
|
||||||
|
|
||||||
def get_transport_zone_id_by_name_or_id(self, name_or_id):
|
def get_id_by_name_or_id(self, name_or_id):
|
||||||
"""Get a transport zone by it's display name or uuid
|
|
||||||
|
|
||||||
Return the transport zone data, or raise an exception if not found or
|
|
||||||
not unique
|
|
||||||
"""
|
|
||||||
|
|
||||||
return self._get_resource_by_name_or_id(name_or_id,
|
|
||||||
'transport-zones')
|
|
||||||
|
|
||||||
def get_logical_router_id_by_name_or_id(self, name_or_id):
|
|
||||||
"""Get a logical router by it's display name or uuid
|
"""Get a logical router by it's display name or uuid
|
||||||
|
|
||||||
Return the logical router data, or raise an exception if not found or
|
Return the logical router data, or raise an exception if not found or
|
||||||
@ -392,7 +404,30 @@ class NsxLib(security.Security):
|
|||||||
return self._get_resource_by_name_or_id(name_or_id,
|
return self._get_resource_by_name_or_id(name_or_id,
|
||||||
'logical-routers')
|
'logical-routers')
|
||||||
|
|
||||||
def get_bridge_cluster_id_by_name_or_id(self, name_or_id):
|
|
||||||
|
class NsxLibEdgeCluster(utils.NsxLibApiBase):
|
||||||
|
|
||||||
|
def get(self, edge_cluster_uuid):
|
||||||
|
resource = "edge-clusters/%s" % edge_cluster_uuid
|
||||||
|
return self.client.get(resource)
|
||||||
|
|
||||||
|
|
||||||
|
class NsxLibTransportZone(utils.NsxLibApiBase):
|
||||||
|
|
||||||
|
def get_id_by_name_or_id(self, name_or_id):
|
||||||
|
"""Get a transport zone by it's display name or uuid
|
||||||
|
|
||||||
|
Return the transport zone data, or raise an exception if not found or
|
||||||
|
not unique
|
||||||
|
"""
|
||||||
|
|
||||||
|
return self._get_resource_by_name_or_id(name_or_id,
|
||||||
|
'transport-zones')
|
||||||
|
|
||||||
|
|
||||||
|
class NsxLibBridgeCluster(utils.NsxLibApiBase):
|
||||||
|
|
||||||
|
def get_id_by_name_or_id(self, name_or_id):
|
||||||
"""Get a bridge cluster by it's display name or uuid
|
"""Get a bridge cluster by it's display name or uuid
|
||||||
|
|
||||||
Return the bridge cluster data, or raise an exception if not found or
|
Return the bridge cluster data, or raise an exception if not found or
|
||||||
@ -401,36 +436,3 @@ class NsxLib(security.Security):
|
|||||||
|
|
||||||
return self._get_resource_by_name_or_id(name_or_id,
|
return self._get_resource_by_name_or_id(name_or_id,
|
||||||
'bridge-clusters')
|
'bridge-clusters')
|
||||||
|
|
||||||
def create_port_mirror_session(self, source_ports, dest_ports, direction,
|
|
||||||
description, name, tags):
|
|
||||||
"""Create a PortMirror Session on the backend.
|
|
||||||
|
|
||||||
:param source_ports: List of UUIDs of the ports whose traffic is to be
|
|
||||||
mirrored.
|
|
||||||
:param dest_ports: List of UUIDs of the ports where the mirrored
|
|
||||||
traffic is to be sent.
|
|
||||||
:param direction: String representing the direction of traffic to be
|
|
||||||
mirrored. [INGRESS, EGRESS, BIDIRECTIONAL]
|
|
||||||
:param description: String representing the description of the session.
|
|
||||||
:param name: String representing the name of the session.
|
|
||||||
:param tags: nsx backend specific tags.
|
|
||||||
"""
|
|
||||||
|
|
||||||
resource = 'mirror-sessions'
|
|
||||||
body = {'direction': direction,
|
|
||||||
'tags': tags,
|
|
||||||
'display_name': name,
|
|
||||||
'description': description,
|
|
||||||
'mirror_sources': source_ports,
|
|
||||||
'mirror_destination': dest_ports}
|
|
||||||
return self.client.create(resource, body)
|
|
||||||
|
|
||||||
def delete_port_mirror_session(self, mirror_session_id):
|
|
||||||
"""Delete a PortMirror session on the backend.
|
|
||||||
|
|
||||||
:param mirror_session_id: string representing the UUID of the port
|
|
||||||
mirror session to be deleted.
|
|
||||||
"""
|
|
||||||
resource = 'mirror-sessions/%s' % mirror_session_id
|
|
||||||
self.client.delete(resource)
|
|
||||||
|
@ -50,7 +50,7 @@ class NSGroupManager(object):
|
|||||||
NESTED_GROUP_DESCRIPTION = ('OpenStack NSGroup. Do not delete.')
|
NESTED_GROUP_DESCRIPTION = ('OpenStack NSGroup. Do not delete.')
|
||||||
|
|
||||||
def __init__(self, nsxlib, size):
|
def __init__(self, nsxlib, size):
|
||||||
self.nsx = nsxlib
|
self.nsxlib_nsgroup = nsxlib.ns_group
|
||||||
self._nested_groups = self._init_nested_groups(size)
|
self._nested_groups = self._init_nested_groups(size)
|
||||||
self._size = len(self._nested_groups)
|
self._size = len(self._nested_groups)
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ class NSGroupManager(object):
|
|||||||
size = requested_size
|
size = requested_size
|
||||||
nested_groups = {
|
nested_groups = {
|
||||||
self._get_nested_group_index_from_name(nsgroup): nsgroup['id']
|
self._get_nested_group_index_from_name(nsgroup): nsgroup['id']
|
||||||
for nsgroup in self.nsx.list_nsgroups()
|
for nsgroup in self.nsxlib_nsgroup.list()
|
||||||
if nsxlib_utils.is_internal_resource(nsgroup)}
|
if nsxlib_utils.is_internal_resource(nsgroup)}
|
||||||
|
|
||||||
if nested_groups:
|
if nested_groups:
|
||||||
@ -101,7 +101,7 @@ class NSGroupManager(object):
|
|||||||
name = '%s %s' % (name_prefix, index + 1)
|
name = '%s %s' % (name_prefix, index + 1)
|
||||||
description = NSGroupManager.NESTED_GROUP_DESCRIPTION
|
description = NSGroupManager.NESTED_GROUP_DESCRIPTION
|
||||||
tags = nsxlib_utils.build_v3_api_version_tag()
|
tags = nsxlib_utils.build_v3_api_version_tag()
|
||||||
return self.nsx.create_nsgroup(name, description, tags)
|
return self.nsxlib_nsgroup.create(name, description, tags)
|
||||||
|
|
||||||
def _hash_uuid(self, internal_id):
|
def _hash_uuid(self, internal_id):
|
||||||
return hash(uuid.UUID(internal_id))
|
return hash(uuid.UUID(internal_id))
|
||||||
@ -122,9 +122,8 @@ class NSGroupManager(object):
|
|||||||
try:
|
try:
|
||||||
LOG.debug("Adding NSGroup %s to nested group %s",
|
LOG.debug("Adding NSGroup %s to nested group %s",
|
||||||
nsgroup_id, group)
|
nsgroup_id, group)
|
||||||
self.nsx.add_nsgroup_members(group,
|
self.nsxlib_nsgroup.add_members(
|
||||||
consts.NSGROUP,
|
group, consts.NSGROUP, [nsgroup_id])
|
||||||
[nsgroup_id])
|
|
||||||
break
|
break
|
||||||
except exceptions.NSGroupIsFull:
|
except exceptions.NSGroupIsFull:
|
||||||
LOG.debug("Nested group %(group_id)s is full, trying the "
|
LOG.debug("Nested group %(group_id)s is full, trying the "
|
||||||
@ -137,7 +136,7 @@ class NSGroupManager(object):
|
|||||||
def remove_nsgroup(self, nsgroup_id):
|
def remove_nsgroup(self, nsgroup_id):
|
||||||
for group in self._suggest_nested_group(nsgroup_id):
|
for group in self._suggest_nested_group(nsgroup_id):
|
||||||
try:
|
try:
|
||||||
self.nsx.remove_nsgroup_member(
|
self.nsxlib_nsgroup.remove_member(
|
||||||
group, consts.NSGROUP,
|
group, consts.NSGROUP,
|
||||||
nsgroup_id, verify=True)
|
nsgroup_id, verify=True)
|
||||||
break
|
break
|
||||||
|
@ -60,7 +60,7 @@ class RouterLib(object):
|
|||||||
err_msg = _("Failed to get edge cluster uuid from tier0 "
|
err_msg = _("Failed to get edge cluster uuid from tier0 "
|
||||||
"router %s at the backend") % lrouter
|
"router %s at the backend") % lrouter
|
||||||
else:
|
else:
|
||||||
edge_cluster = self.nsxlib.get_edge_cluster(edge_cluster_uuid)
|
edge_cluster = self.nsxlib.edge_cluster.get(edge_cluster_uuid)
|
||||||
member_index_list = [member['member_index']
|
member_index_list = [member['member_index']
|
||||||
for member in edge_cluster['members']]
|
for member in edge_cluster['members']]
|
||||||
if len(member_index_list) < MIN_EDGE_NODE_NUM:
|
if len(member_index_list) < MIN_EDGE_NODE_NUM:
|
||||||
@ -116,7 +116,7 @@ class RouterLib(object):
|
|||||||
advertise_route_connected,
|
advertise_route_connected,
|
||||||
advertise_route_static=False,
|
advertise_route_static=False,
|
||||||
enabled=True):
|
enabled=True):
|
||||||
return self.nsxlib.update_logical_router_advertisement(
|
return self.nsxlib.logical_router.update_advertisement(
|
||||||
logical_router_id,
|
logical_router_id,
|
||||||
advertise_nat_routes=advertise_route_nat,
|
advertise_nat_routes=advertise_route_nat,
|
||||||
advertise_nsx_connected_routes=advertise_route_connected,
|
advertise_nsx_connected_routes=advertise_route_connected,
|
||||||
@ -124,11 +124,13 @@ class RouterLib(object):
|
|||||||
enabled=enabled)
|
enabled=enabled)
|
||||||
|
|
||||||
def delete_gw_snat_rule(self, logical_router_id, gw_ip):
|
def delete_gw_snat_rule(self, logical_router_id, gw_ip):
|
||||||
return self.nsxlib.delete_nat_rule_by_values(logical_router_id,
|
return self.nsxlib.logical_router.delete_nat_rule_by_values(
|
||||||
|
logical_router_id,
|
||||||
translated_network=gw_ip)
|
translated_network=gw_ip)
|
||||||
|
|
||||||
def add_gw_snat_rule(self, logical_router_id, gw_ip):
|
def add_gw_snat_rule(self, logical_router_id, gw_ip):
|
||||||
return self.nsxlib.add_nat_rule(logical_router_id, action="SNAT",
|
return self.nsxlib.logical_router.add_nat_rule(
|
||||||
|
logical_router_id, action="SNAT",
|
||||||
translated_network=gw_ip,
|
translated_network=gw_ip,
|
||||||
rule_priority=GW_NAT_PRI)
|
rule_priority=GW_NAT_PRI)
|
||||||
|
|
||||||
@ -157,31 +159,36 @@ class RouterLib(object):
|
|||||||
port['id'], subnets=address_groups)
|
port['id'], subnets=address_groups)
|
||||||
|
|
||||||
def add_fip_nat_rules(self, logical_router_id, ext_ip, int_ip):
|
def add_fip_nat_rules(self, logical_router_id, ext_ip, int_ip):
|
||||||
self.nsxlib.add_nat_rule(logical_router_id, action="SNAT",
|
self.nsxlib.logical_router.add_nat_rule(
|
||||||
|
logical_router_id, action="SNAT",
|
||||||
translated_network=ext_ip,
|
translated_network=ext_ip,
|
||||||
source_net=int_ip,
|
source_net=int_ip,
|
||||||
rule_priority=FIP_NAT_PRI)
|
rule_priority=FIP_NAT_PRI)
|
||||||
self.nsxlib.add_nat_rule(logical_router_id, action="DNAT",
|
self.nsxlib.logical_router.add_nat_rule(
|
||||||
|
logical_router_id, action="DNAT",
|
||||||
translated_network=int_ip,
|
translated_network=int_ip,
|
||||||
dest_net=ext_ip,
|
dest_net=ext_ip,
|
||||||
rule_priority=FIP_NAT_PRI)
|
rule_priority=FIP_NAT_PRI)
|
||||||
|
|
||||||
def delete_fip_nat_rules(self, logical_router_id, ext_ip, int_ip):
|
def delete_fip_nat_rules(self, logical_router_id, ext_ip, int_ip):
|
||||||
self.nsxlib.delete_nat_rule_by_values(logical_router_id,
|
self.nsxlib.logical_router.delete_nat_rule_by_values(
|
||||||
|
logical_router_id,
|
||||||
action="SNAT",
|
action="SNAT",
|
||||||
translated_network=ext_ip,
|
translated_network=ext_ip,
|
||||||
match_source_network=int_ip)
|
match_source_network=int_ip)
|
||||||
self.nsxlib.delete_nat_rule_by_values(logical_router_id,
|
self.nsxlib.logical_router.delete_nat_rule_by_values(
|
||||||
|
logical_router_id,
|
||||||
action="DNAT",
|
action="DNAT",
|
||||||
translated_network=int_ip,
|
translated_network=int_ip,
|
||||||
match_destination_network=ext_ip)
|
match_destination_network=ext_ip)
|
||||||
|
|
||||||
def add_static_routes(self, nsx_router_id, route):
|
def add_static_routes(self, nsx_router_id, route):
|
||||||
return self.nsxlib.add_static_route(nsx_router_id,
|
return self.nsxlib.logical_router.add_static_route(
|
||||||
|
nsx_router_id,
|
||||||
route['destination'],
|
route['destination'],
|
||||||
route['nexthop'])
|
route['nexthop'])
|
||||||
|
|
||||||
def delete_static_routes(self, nsx_router_id, route):
|
def delete_static_routes(self, nsx_router_id, route):
|
||||||
return self.nsxlib.delete_static_route_by_values(
|
return self.nsxlib.logical_router.delete_static_route_by_values(
|
||||||
nsx_router_id, dest_cidr=route['destination'],
|
nsx_router_id, dest_cidr=route['destination'],
|
||||||
nexthop=route['nexthop'])
|
nexthop=route['nexthop'])
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
NSX-V3 Plugin security integration & Distributed Firewall module
|
NSX-V3 Plugin security & Distributed Firewall integration module
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from neutron_lib import constants
|
from neutron_lib import constants
|
||||||
@ -35,151 +35,31 @@ PORT_SG_SCOPE = 'os-security-group'
|
|||||||
MAX_NSGROUPS_CRITERIA_TAGS = 10
|
MAX_NSGROUPS_CRITERIA_TAGS = 10
|
||||||
|
|
||||||
|
|
||||||
class Security(object):
|
class NsxLibNsGroup(utils.NsxLibApiBase):
|
||||||
|
|
||||||
def _get_l4_protocol_name(self, protocol_number):
|
def __init__(self, client, max_attempts, firewall_section_handler):
|
||||||
if protocol_number is None:
|
self.firewall_section = firewall_section_handler
|
||||||
return
|
super(NsxLibNsGroup, self).__init__(client, max_attempts)
|
||||||
protocol_number = constants.IP_PROTOCOL_MAP.get(protocol_number,
|
|
||||||
protocol_number)
|
|
||||||
protocol_number = int(protocol_number)
|
|
||||||
if protocol_number == 6:
|
|
||||||
return consts.TCP
|
|
||||||
elif protocol_number == 17:
|
|
||||||
return consts.UDP
|
|
||||||
elif protocol_number == 1:
|
|
||||||
return consts.ICMPV4
|
|
||||||
else:
|
|
||||||
return protocol_number
|
|
||||||
|
|
||||||
def _get_direction(self, sg_rule):
|
def update_on_backend(self, context, security_group,
|
||||||
return (
|
|
||||||
consts.IN if sg_rule['direction'] == 'ingress'
|
|
||||||
else consts.OUT
|
|
||||||
)
|
|
||||||
|
|
||||||
def _decide_service(self, sg_rule):
|
|
||||||
l4_protocol = self._get_l4_protocol_name(sg_rule['protocol'])
|
|
||||||
direction = self._get_direction(sg_rule)
|
|
||||||
|
|
||||||
if l4_protocol in [consts.TCP,
|
|
||||||
consts.UDP]:
|
|
||||||
# If port_range_min is not specified then we assume all ports are
|
|
||||||
# matched, relying on neutron to perform validation.
|
|
||||||
source_ports = []
|
|
||||||
if sg_rule['port_range_min'] is None:
|
|
||||||
destination_ports = []
|
|
||||||
elif sg_rule['port_range_min'] != sg_rule['port_range_max']:
|
|
||||||
# NSX API requires a non-empty range (e.g - '22-23')
|
|
||||||
destination_ports = ['%(port_range_min)s-%(port_range_max)s'
|
|
||||||
% sg_rule]
|
|
||||||
else:
|
|
||||||
destination_ports = ['%(port_range_min)s' % sg_rule]
|
|
||||||
|
|
||||||
if direction == consts.OUT:
|
|
||||||
source_ports, destination_ports = destination_ports, []
|
|
||||||
|
|
||||||
return self.get_nsservice(
|
|
||||||
consts.L4_PORT_SET_NSSERVICE,
|
|
||||||
l4_protocol=l4_protocol,
|
|
||||||
source_ports=source_ports,
|
|
||||||
destination_ports=destination_ports)
|
|
||||||
elif l4_protocol == consts.ICMPV4:
|
|
||||||
return self.get_nsservice(
|
|
||||||
consts.ICMP_TYPE_NSSERVICE,
|
|
||||||
protocol=l4_protocol,
|
|
||||||
icmp_type=sg_rule['port_range_min'],
|
|
||||||
icmp_code=sg_rule['port_range_max'])
|
|
||||||
elif l4_protocol is not None:
|
|
||||||
return self.get_nsservice(
|
|
||||||
consts.IP_PROTOCOL_NSSERVICE,
|
|
||||||
protocol_number=l4_protocol)
|
|
||||||
|
|
||||||
def _get_fw_rule_from_sg_rule(self, sg_rule, nsgroup_id, rmt_nsgroup_id,
|
|
||||||
logged, action):
|
|
||||||
# IPV4 or IPV6
|
|
||||||
ip_protocol = sg_rule['ethertype'].upper()
|
|
||||||
direction = self._get_direction(sg_rule)
|
|
||||||
|
|
||||||
if sg_rule.get(consts.LOCAL_IP_PREFIX):
|
|
||||||
local_ip_prefix = self.get_ip_cidr_reference(
|
|
||||||
sg_rule[consts.LOCAL_IP_PREFIX],
|
|
||||||
ip_protocol)
|
|
||||||
else:
|
|
||||||
local_ip_prefix = None
|
|
||||||
|
|
||||||
source = None
|
|
||||||
local_group = self.get_nsgroup_reference(nsgroup_id)
|
|
||||||
if sg_rule['remote_ip_prefix'] is not None:
|
|
||||||
source = self.get_ip_cidr_reference(
|
|
||||||
sg_rule['remote_ip_prefix'], ip_protocol)
|
|
||||||
destination = local_ip_prefix or local_group
|
|
||||||
else:
|
|
||||||
if rmt_nsgroup_id:
|
|
||||||
source = self.get_nsgroup_reference(rmt_nsgroup_id)
|
|
||||||
destination = local_ip_prefix or local_group
|
|
||||||
if direction == consts.OUT:
|
|
||||||
source, destination = destination, source
|
|
||||||
|
|
||||||
service = self._decide_service(sg_rule)
|
|
||||||
name = sg_rule['id']
|
|
||||||
|
|
||||||
return self.get_firewall_rule_dict(name, source,
|
|
||||||
destination, direction,
|
|
||||||
ip_protocol, service,
|
|
||||||
action, logged)
|
|
||||||
|
|
||||||
def create_firewall_rules(self, context, section_id, nsgroup_id,
|
|
||||||
logging_enabled, action, security_group_rules,
|
|
||||||
ruleid_2_remote_nsgroup_map):
|
|
||||||
|
|
||||||
# 1. translate rules
|
|
||||||
# 2. insert in section
|
|
||||||
# 3. return the rules
|
|
||||||
firewall_rules = []
|
|
||||||
for sg_rule in security_group_rules:
|
|
||||||
remote_nsgroup_id = ruleid_2_remote_nsgroup_map[sg_rule['id']]
|
|
||||||
fw_rule = self._get_fw_rule_from_sg_rule(
|
|
||||||
sg_rule, nsgroup_id, remote_nsgroup_id,
|
|
||||||
logging_enabled, action)
|
|
||||||
|
|
||||||
firewall_rules.append(fw_rule)
|
|
||||||
|
|
||||||
return self.add_rules_in_section(firewall_rules, section_id)
|
|
||||||
|
|
||||||
def _process_firewall_section_rules_logging_for_update(self, section_id,
|
|
||||||
logging_enabled):
|
|
||||||
rules = self.get_section_rules(section_id).get('results', [])
|
|
||||||
update_rules = False
|
|
||||||
for rule in rules:
|
|
||||||
if rule['logged'] != logging_enabled:
|
|
||||||
rule['logged'] = logging_enabled
|
|
||||||
update_rules = True
|
|
||||||
return rules if update_rules else None
|
|
||||||
|
|
||||||
def set_firewall_rule_logging_for_section(self, section_id, logging):
|
|
||||||
rules = self._process_firewall_section_rules_logging_for_update(
|
|
||||||
section_id, logging)
|
|
||||||
self.update_section(section_id, rules=rules)
|
|
||||||
|
|
||||||
def update_security_group_on_backend(self, context, security_group,
|
|
||||||
nsgroup_id, section_id,
|
nsgroup_id, section_id,
|
||||||
log_sg_allowed_traffic):
|
log_sg_allowed_traffic):
|
||||||
name = self.get_nsgroup_name(security_group)
|
name = self.get_name(security_group)
|
||||||
description = security_group['description']
|
description = security_group['description']
|
||||||
logging = (log_sg_allowed_traffic or
|
logging = (log_sg_allowed_traffic or
|
||||||
security_group[consts.LOGGING])
|
security_group[consts.LOGGING])
|
||||||
rules = self._process_firewall_section_rules_logging_for_update(
|
rules = self.firewall_section._process_rules_logging_for_update(
|
||||||
section_id, logging)
|
section_id, logging)
|
||||||
self.update_nsgroup(nsgroup_id, name, description)
|
self.update(nsgroup_id, name, description)
|
||||||
self.update_section(section_id, name, description, rules=rules)
|
self.firewall_section.update(section_id, name, description,
|
||||||
|
rules=rules)
|
||||||
|
|
||||||
def get_nsgroup_name(self, security_group):
|
def get_name(self, security_group):
|
||||||
# NOTE(roeyc): We add the security-group id to the NSGroup name,
|
# NOTE(roeyc): We add the security-group id to the NSGroup name,
|
||||||
# for usability purposes.
|
# for usability purposes.
|
||||||
return '%(name)s - %(id)s' % security_group
|
return '%(name)s - %(id)s' % security_group
|
||||||
|
|
||||||
def get_lport_tags_for_security_groups(self, secgroups):
|
def get_lport_tags(self, secgroups):
|
||||||
if len(secgroups) > MAX_NSGROUPS_CRITERIA_TAGS:
|
if len(secgroups) > MAX_NSGROUPS_CRITERIA_TAGS:
|
||||||
raise exceptions.NumberOfNsgroupCriteriaTagsReached(
|
raise exceptions.NumberOfNsgroupCriteriaTagsReached(
|
||||||
max_num=MAX_NSGROUPS_CRITERIA_TAGS)
|
max_num=MAX_NSGROUPS_CRITERIA_TAGS)
|
||||||
@ -191,20 +71,19 @@ class Security(object):
|
|||||||
tags = [{'scope': PORT_SG_SCOPE, 'tag': None}]
|
tags = [{'scope': PORT_SG_SCOPE, 'tag': None}]
|
||||||
return tags
|
return tags
|
||||||
|
|
||||||
def update_lport_with_security_groups(self, context, lport_id,
|
def update_lport(self, context, lport_id, original, updated):
|
||||||
original, updated):
|
|
||||||
added = set(updated) - set(original)
|
added = set(updated) - set(original)
|
||||||
removed = set(original) - set(updated)
|
removed = set(original) - set(updated)
|
||||||
for nsgroup_id in added:
|
for nsgroup_id in added:
|
||||||
try:
|
try:
|
||||||
self.add_nsgroup_members(
|
self.add_members(
|
||||||
nsgroup_id, consts.TARGET_TYPE_LOGICAL_PORT,
|
nsgroup_id, consts.TARGET_TYPE_LOGICAL_PORT,
|
||||||
[lport_id])
|
[lport_id])
|
||||||
except exceptions.NSGroupIsFull:
|
except exceptions.NSGroupIsFull:
|
||||||
for nsgroup_id in added:
|
for nsgroup_id in added:
|
||||||
# NOTE(roeyc): If the port was not added to the nsgroup
|
# NOTE(roeyc): If the port was not added to the nsgroup
|
||||||
# yet, then this request will silently fail.
|
# yet, then this request will silently fail.
|
||||||
self.remove_nsgroup_member(
|
self.remove_member(
|
||||||
nsgroup_id, consts.TARGET_TYPE_LOGICAL_PORT,
|
nsgroup_id, consts.TARGET_TYPE_LOGICAL_PORT,
|
||||||
lport_id)
|
lport_id)
|
||||||
raise exceptions.SecurityGroupMaximumCapacityReached(
|
raise exceptions.SecurityGroupMaximumCapacityReached(
|
||||||
@ -213,7 +92,7 @@ class Security(object):
|
|||||||
with excutils.save_and_reraise_exception():
|
with excutils.save_and_reraise_exception():
|
||||||
LOG.error(_LE("NSGroup %s doesn't exists"), nsgroup_id)
|
LOG.error(_LE("NSGroup %s doesn't exists"), nsgroup_id)
|
||||||
for nsgroup_id in removed:
|
for nsgroup_id in removed:
|
||||||
self.remove_nsgroup_member(
|
self.remove_member(
|
||||||
nsgroup_id, consts.TARGET_TYPE_LOGICAL_PORT, lport_id)
|
nsgroup_id, consts.TARGET_TYPE_LOGICAL_PORT, lport_id)
|
||||||
|
|
||||||
def init_default_section(self, name, description, nested_groups,
|
def init_default_section(self, name, description, nested_groups,
|
||||||
@ -264,14 +143,13 @@ class Security(object):
|
|||||||
service.update(properties)
|
service.update(properties)
|
||||||
return {'service': service}
|
return {'service': service}
|
||||||
|
|
||||||
def get_nsgroup_port_tag_expression(self, scope, tag):
|
def get_port_tag_expression(self, scope, tag):
|
||||||
return {
|
return {'resource_type': consts.NSGROUP_TAG_EXP,
|
||||||
'resource_type': consts.NSGROUP_TAG_EXP,
|
|
||||||
'target_type': consts.TARGET_TYPE_LOGICAL_PORT,
|
'target_type': consts.TARGET_TYPE_LOGICAL_PORT,
|
||||||
'scope': scope,
|
'scope': scope,
|
||||||
'tag': tag}
|
'tag': tag}
|
||||||
|
|
||||||
def create_nsgroup(self, display_name, description, tags,
|
def create(self, display_name, description, tags,
|
||||||
membership_criteria=None):
|
membership_criteria=None):
|
||||||
body = {'display_name': display_name,
|
body = {'display_name': display_name,
|
||||||
'description': description,
|
'description': description,
|
||||||
@ -281,18 +159,18 @@ class Security(object):
|
|||||||
body.update({'membership_criteria': [membership_criteria]})
|
body.update({'membership_criteria': [membership_criteria]})
|
||||||
return self.client.create('ns-groups', body)
|
return self.client.create('ns-groups', body)
|
||||||
|
|
||||||
def list_nsgroups(self):
|
def list(self):
|
||||||
return self.client.get(
|
return self.client.get(
|
||||||
'ns-groups?populate_references=false').get('results', [])
|
'ns-groups?populate_references=false').get('results', [])
|
||||||
|
|
||||||
def update_nsgroup(self, nsgroup_id, display_name=None, description=None,
|
def update(self, nsgroup_id, display_name=None, description=None,
|
||||||
membership_criteria=None, members=None):
|
membership_criteria=None, members=None):
|
||||||
#Using internal method so we can access max_attempts in the decorator
|
#Using internal method so we can access max_attempts in the decorator
|
||||||
@utils.retry_upon_exception(
|
@utils.retry_upon_exception(
|
||||||
exceptions.StaleRevision,
|
exceptions.StaleRevision,
|
||||||
max_attempts=self.max_attempts)
|
max_attempts=self.max_attempts)
|
||||||
def _do_update():
|
def _do_update():
|
||||||
nsgroup = self.read_nsgroup(nsgroup_id)
|
nsgroup = self.read(nsgroup_id)
|
||||||
if display_name is not None:
|
if display_name is not None:
|
||||||
nsgroup['display_name'] = display_name
|
nsgroup['display_name'] = display_name
|
||||||
if description is not None:
|
if description is not None:
|
||||||
@ -306,7 +184,7 @@ class Security(object):
|
|||||||
|
|
||||||
return _do_update()
|
return _do_update()
|
||||||
|
|
||||||
def get_nsgroup_member_expression(self, target_type, target_id):
|
def get_member_expression(self, target_type, target_id):
|
||||||
return {
|
return {
|
||||||
'resource_type': consts.NSGROUP_SIMPLE_EXP,
|
'resource_type': consts.NSGROUP_SIMPLE_EXP,
|
||||||
'target_property': 'id',
|
'target_property': 'id',
|
||||||
@ -314,7 +192,7 @@ class Security(object):
|
|||||||
'op': consts.EQUALS,
|
'op': consts.EQUALS,
|
||||||
'value': target_id}
|
'value': target_id}
|
||||||
|
|
||||||
def _update_nsgroup_with_members(self, nsgroup_id, members, action):
|
def _update_with_members(self, nsgroup_id, members, action):
|
||||||
#Using internal method so we can access max_attempts in the decorator
|
#Using internal method so we can access max_attempts in the decorator
|
||||||
@utils.retry_upon_exception(
|
@utils.retry_upon_exception(
|
||||||
exceptions.StaleRevision,
|
exceptions.StaleRevision,
|
||||||
@ -325,15 +203,15 @@ class Security(object):
|
|||||||
|
|
||||||
return _do_update()
|
return _do_update()
|
||||||
|
|
||||||
def add_nsgroup_members(self, nsgroup_id, target_type, target_ids):
|
def add_members(self, nsgroup_id, target_type, target_ids):
|
||||||
members = []
|
members = []
|
||||||
for target_id in target_ids:
|
for target_id in target_ids:
|
||||||
member_expr = self.get_nsgroup_member_expression(
|
member_expr = self.get_member_expression(
|
||||||
target_type, target_id)
|
target_type, target_id)
|
||||||
members.append(member_expr)
|
members.append(member_expr)
|
||||||
members = {'members': members}
|
members = {'members': members}
|
||||||
try:
|
try:
|
||||||
return self._update_nsgroup_with_members(
|
return self._update_with_members(
|
||||||
nsgroup_id, members, consts.NSGROUP_ADD_MEMBERS)
|
nsgroup_id, members, consts.NSGROUP_ADD_MEMBERS)
|
||||||
except (exceptions.StaleRevision, exceptions.ResourceNotFound):
|
except (exceptions.StaleRevision, exceptions.ResourceNotFound):
|
||||||
raise
|
raise
|
||||||
@ -348,24 +226,24 @@ class Security(object):
|
|||||||
|
|
||||||
raise exceptions.NSGroupIsFull(nsgroup_id=nsgroup_id)
|
raise exceptions.NSGroupIsFull(nsgroup_id=nsgroup_id)
|
||||||
|
|
||||||
def remove_nsgroup_member(self, nsgroup_id, target_type,
|
def remove_member(self, nsgroup_id, target_type,
|
||||||
target_id, verify=False):
|
target_id, verify=False):
|
||||||
member_expr = self.get_nsgroup_member_expression(
|
member_expr = self.get_member_expression(
|
||||||
target_type, target_id)
|
target_type, target_id)
|
||||||
members = {'members': [member_expr]}
|
members = {'members': [member_expr]}
|
||||||
try:
|
try:
|
||||||
return self._update_nsgroup_with_members(
|
return self._update_with_members(
|
||||||
nsgroup_id, members, consts.NSGROUP_REMOVE_MEMBERS)
|
nsgroup_id, members, consts.NSGROUP_REMOVE_MEMBERS)
|
||||||
except exceptions.ManagerError:
|
except exceptions.ManagerError:
|
||||||
if verify:
|
if verify:
|
||||||
raise exceptions.NSGroupMemberNotFound(member_id=target_id,
|
raise exceptions.NSGroupMemberNotFound(member_id=target_id,
|
||||||
nsgroup_id=nsgroup_id)
|
nsgroup_id=nsgroup_id)
|
||||||
|
|
||||||
def read_nsgroup(self, nsgroup_id):
|
def read(self, nsgroup_id):
|
||||||
return self.client.get(
|
return self.client.get(
|
||||||
'ns-groups/%s?populate_references=true' % nsgroup_id)
|
'ns-groups/%s?populate_references=true' % nsgroup_id)
|
||||||
|
|
||||||
def delete_nsgroup(self, nsgroup_id):
|
def delete(self, nsgroup_id):
|
||||||
try:
|
try:
|
||||||
return self.client.delete(
|
return self.client.delete(
|
||||||
'ns-groups/%s?force=true' % nsgroup_id)
|
'ns-groups/%s?force=true' % nsgroup_id)
|
||||||
@ -374,7 +252,72 @@ class Security(object):
|
|||||||
LOG.debug("NSGroup %s does not exists for delete request.",
|
LOG.debug("NSGroup %s does not exists for delete request.",
|
||||||
nsgroup_id)
|
nsgroup_id)
|
||||||
|
|
||||||
def _build_section(self, display_name, description, applied_tos, tags):
|
|
||||||
|
class NsxLibFirewallSection(utils.NsxLibApiBase):
|
||||||
|
|
||||||
|
def _get_direction(self, sg_rule):
|
||||||
|
return (
|
||||||
|
consts.IN if sg_rule['direction'] == 'ingress'
|
||||||
|
else consts.OUT
|
||||||
|
)
|
||||||
|
|
||||||
|
def _get_l4_protocol_name(self, protocol_number):
|
||||||
|
if protocol_number is None:
|
||||||
|
return
|
||||||
|
protocol_number = constants.IP_PROTOCOL_MAP.get(protocol_number,
|
||||||
|
protocol_number)
|
||||||
|
protocol_number = int(protocol_number)
|
||||||
|
if protocol_number == 6:
|
||||||
|
return consts.TCP
|
||||||
|
elif protocol_number == 17:
|
||||||
|
return consts.UDP
|
||||||
|
elif protocol_number == 1:
|
||||||
|
return consts.ICMPV4
|
||||||
|
else:
|
||||||
|
return protocol_number
|
||||||
|
|
||||||
|
def get_nsservice(self, resource_type, **properties):
|
||||||
|
service = {'resource_type': resource_type}
|
||||||
|
service.update(properties)
|
||||||
|
return {'service': service}
|
||||||
|
|
||||||
|
def _decide_service(self, sg_rule):
|
||||||
|
l4_protocol = self._get_l4_protocol_name(sg_rule['protocol'])
|
||||||
|
direction = self._get_direction(sg_rule)
|
||||||
|
|
||||||
|
if l4_protocol in [consts.TCP, consts.UDP]:
|
||||||
|
# If port_range_min is not specified then we assume all ports are
|
||||||
|
# matched, relying on neutron to perform validation.
|
||||||
|
source_ports = []
|
||||||
|
if sg_rule['port_range_min'] is None:
|
||||||
|
destination_ports = []
|
||||||
|
elif sg_rule['port_range_min'] != sg_rule['port_range_max']:
|
||||||
|
# NSX API requires a non-empty range (e.g - '22-23')
|
||||||
|
destination_ports = ['%(port_range_min)s-%(port_range_max)s'
|
||||||
|
% sg_rule]
|
||||||
|
else:
|
||||||
|
destination_ports = ['%(port_range_min)s' % sg_rule]
|
||||||
|
|
||||||
|
if direction == consts.OUT:
|
||||||
|
source_ports, destination_ports = destination_ports, []
|
||||||
|
|
||||||
|
return self.get_nsservice(
|
||||||
|
consts.L4_PORT_SET_NSSERVICE,
|
||||||
|
l4_protocol=l4_protocol,
|
||||||
|
source_ports=source_ports,
|
||||||
|
destination_ports=destination_ports)
|
||||||
|
elif l4_protocol == consts.ICMPV4:
|
||||||
|
return self.get_nsservice(
|
||||||
|
consts.ICMP_TYPE_NSSERVICE,
|
||||||
|
protocol=l4_protocol,
|
||||||
|
icmp_type=sg_rule['port_range_min'],
|
||||||
|
icmp_code=sg_rule['port_range_max'])
|
||||||
|
elif l4_protocol is not None:
|
||||||
|
return self.get_nsservice(
|
||||||
|
consts.IP_PROTOCOL_NSSERVICE,
|
||||||
|
protocol_number=l4_protocol)
|
||||||
|
|
||||||
|
def _build(self, display_name, description, applied_tos, tags):
|
||||||
return {'display_name': display_name,
|
return {'display_name': display_name,
|
||||||
'description': description,
|
'description': description,
|
||||||
'stateful': True,
|
'stateful': True,
|
||||||
@ -383,18 +326,18 @@ class Security(object):
|
|||||||
for t_id in applied_tos],
|
for t_id in applied_tos],
|
||||||
'tags': tags}
|
'tags': tags}
|
||||||
|
|
||||||
def create_empty_section(self, display_name, description,
|
def create_empty(self, display_name, description,
|
||||||
applied_tos, tags,
|
applied_tos, tags,
|
||||||
operation=consts.FW_INSERT_BOTTOM,
|
operation=consts.FW_INSERT_BOTTOM,
|
||||||
other_section=None):
|
other_section=None):
|
||||||
resource = 'firewall/sections?operation=%s' % operation
|
resource = 'firewall/sections?operation=%s' % operation
|
||||||
body = self._build_section(display_name, description,
|
body = self._build(display_name, description,
|
||||||
applied_tos, tags)
|
applied_tos, tags)
|
||||||
if other_section:
|
if other_section:
|
||||||
resource += '&id=%s' % other_section
|
resource += '&id=%s' % other_section
|
||||||
return self.client.create(resource, body)
|
return self.client.create(resource, body)
|
||||||
|
|
||||||
def update_section(self, section_id, display_name=None, description=None,
|
def update(self, section_id, display_name=None, description=None,
|
||||||
applied_tos=None, rules=None):
|
applied_tos=None, rules=None):
|
||||||
#Using internal method so we can access max_attempts in the decorator
|
#Using internal method so we can access max_attempts in the decorator
|
||||||
@utils.retry_upon_exception(
|
@utils.retry_upon_exception(
|
||||||
@ -402,7 +345,7 @@ class Security(object):
|
|||||||
max_attempts=self.max_attempts)
|
max_attempts=self.max_attempts)
|
||||||
def _do_update():
|
def _do_update():
|
||||||
resource = 'firewall/sections/%s' % section_id
|
resource = 'firewall/sections/%s' % section_id
|
||||||
section = self.read_section(section_id)
|
section = self.read(section_id)
|
||||||
|
|
||||||
if rules is not None:
|
if rules is not None:
|
||||||
resource += '?action=update_with_rules'
|
resource += '?action=update_with_rules'
|
||||||
@ -422,15 +365,15 @@ class Security(object):
|
|||||||
|
|
||||||
return _do_update()
|
return _do_update()
|
||||||
|
|
||||||
def read_section(self, section_id):
|
def read(self, section_id):
|
||||||
resource = 'firewall/sections/%s' % section_id
|
resource = 'firewall/sections/%s' % section_id
|
||||||
return self.client.get(resource)
|
return self.client.get(resource)
|
||||||
|
|
||||||
def list_sections(self):
|
def list(self):
|
||||||
resource = 'firewall/sections'
|
resource = 'firewall/sections'
|
||||||
return self.client.get(resource).get('results', [])
|
return self.client.get(resource).get('results', [])
|
||||||
|
|
||||||
def delete_section(self, section_id):
|
def delete(self, section_id):
|
||||||
resource = 'firewall/sections/%s?cascade=true' % section_id
|
resource = 'firewall/sections/%s?cascade=true' % section_id
|
||||||
return self.client.delete(resource)
|
return self.client.delete(resource)
|
||||||
|
|
||||||
@ -445,7 +388,7 @@ class Security(object):
|
|||||||
return {'target_id': ip_cidr_block,
|
return {'target_id': ip_cidr_block,
|
||||||
'target_type': target_type}
|
'target_type': target_type}
|
||||||
|
|
||||||
def get_firewall_rule_dict(
|
def get_rule_dict(
|
||||||
self, display_name, source=None,
|
self, display_name, source=None,
|
||||||
destination=None,
|
destination=None,
|
||||||
direction=consts.IN_OUT,
|
direction=consts.IN_OUT,
|
||||||
@ -461,12 +404,12 @@ class Security(object):
|
|||||||
'action': action,
|
'action': action,
|
||||||
'logged': logged}
|
'logged': logged}
|
||||||
|
|
||||||
def add_rule_in_section(self, rule, section_id):
|
def add_rule(self, rule, section_id):
|
||||||
resource = 'firewall/sections/%s/rules' % section_id
|
resource = 'firewall/sections/%s/rules' % section_id
|
||||||
params = '?operation=insert_bottom'
|
params = '?operation=insert_bottom'
|
||||||
return self.client.create(resource + params, rule)
|
return self.client.create(resource + params, rule)
|
||||||
|
|
||||||
def add_rules_in_section(self, rules, section_id):
|
def add_rules(self, rules, section_id):
|
||||||
resource = 'firewall/sections/%s/rules' % section_id
|
resource = 'firewall/sections/%s/rules' % section_id
|
||||||
params = '?action=create_multiple&operation=insert_bottom'
|
params = '?action=create_multiple&operation=insert_bottom'
|
||||||
return self.client.create(resource + params, {'rules': rules})
|
return self.client.create(resource + params, {'rules': rules})
|
||||||
@ -475,6 +418,113 @@ class Security(object):
|
|||||||
resource = 'firewall/sections/%s/rules/%s' % (section_id, rule_id)
|
resource = 'firewall/sections/%s/rules/%s' % (section_id, rule_id)
|
||||||
return self.client.delete(resource)
|
return self.client.delete(resource)
|
||||||
|
|
||||||
def get_section_rules(self, section_id):
|
def get_rules(self, section_id):
|
||||||
resource = 'firewall/sections/%s/rules' % section_id
|
resource = 'firewall/sections/%s/rules' % section_id
|
||||||
return self.client.get(resource)
|
return self.client.get(resource)
|
||||||
|
|
||||||
|
def _get_fw_rule_from_sg_rule(self, sg_rule, nsgroup_id, rmt_nsgroup_id,
|
||||||
|
logged, action):
|
||||||
|
# IPV4 or IPV6
|
||||||
|
ip_protocol = sg_rule['ethertype'].upper()
|
||||||
|
direction = self._get_direction(sg_rule)
|
||||||
|
|
||||||
|
if sg_rule.get(consts.LOCAL_IP_PREFIX):
|
||||||
|
local_ip_prefix = self.get_ip_cidr_reference(
|
||||||
|
sg_rule[consts.LOCAL_IP_PREFIX],
|
||||||
|
ip_protocol)
|
||||||
|
else:
|
||||||
|
local_ip_prefix = None
|
||||||
|
|
||||||
|
source = None
|
||||||
|
local_group = self.get_nsgroup_reference(nsgroup_id)
|
||||||
|
if sg_rule['remote_ip_prefix'] is not None:
|
||||||
|
source = self.get_ip_cidr_reference(
|
||||||
|
sg_rule['remote_ip_prefix'], ip_protocol)
|
||||||
|
destination = local_ip_prefix or local_group
|
||||||
|
else:
|
||||||
|
if rmt_nsgroup_id:
|
||||||
|
source = self.get_nsgroup_reference(rmt_nsgroup_id)
|
||||||
|
destination = local_ip_prefix or local_group
|
||||||
|
if direction == consts.OUT:
|
||||||
|
source, destination = destination, source
|
||||||
|
|
||||||
|
service = self._decide_service(sg_rule)
|
||||||
|
name = sg_rule['id']
|
||||||
|
|
||||||
|
return self.get_rule_dict(name, source,
|
||||||
|
destination, direction,
|
||||||
|
ip_protocol, service,
|
||||||
|
action, logged)
|
||||||
|
|
||||||
|
def create_rules(self, context, section_id, nsgroup_id,
|
||||||
|
logging_enabled, action, security_group_rules,
|
||||||
|
ruleid_2_remote_nsgroup_map):
|
||||||
|
# 1. translate rules
|
||||||
|
# 2. insert in section
|
||||||
|
# 3. return the rules
|
||||||
|
firewall_rules = []
|
||||||
|
for sg_rule in security_group_rules:
|
||||||
|
remote_nsgroup_id = ruleid_2_remote_nsgroup_map[sg_rule['id']]
|
||||||
|
fw_rule = self._get_fw_rule_from_sg_rule(
|
||||||
|
sg_rule, nsgroup_id, remote_nsgroup_id,
|
||||||
|
logging_enabled, action)
|
||||||
|
|
||||||
|
firewall_rules.append(fw_rule)
|
||||||
|
|
||||||
|
return self.add_rules(firewall_rules, section_id)
|
||||||
|
|
||||||
|
def set_rule_logging(self, section_id, logging):
|
||||||
|
rules = self._process_rules_logging_for_update(
|
||||||
|
section_id, logging)
|
||||||
|
self.update(section_id, rules=rules)
|
||||||
|
|
||||||
|
def _process_rules_logging_for_update(self, section_id, logging_enabled):
|
||||||
|
rules = self.get_rules(section_id).get('results', [])
|
||||||
|
update_rules = False
|
||||||
|
for rule in rules:
|
||||||
|
if rule['logged'] != logging_enabled:
|
||||||
|
rule['logged'] = logging_enabled
|
||||||
|
update_rules = True
|
||||||
|
return rules if update_rules else None
|
||||||
|
|
||||||
|
def init_default(self, name, description, nested_groups,
|
||||||
|
log_sg_blocked_traffic):
|
||||||
|
fw_sections = self.list()
|
||||||
|
for section in fw_sections:
|
||||||
|
if section['display_name'] == name:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
tags = utils.build_v3_api_version_tag()
|
||||||
|
section = self.create_empty(
|
||||||
|
name, description, nested_groups, tags)
|
||||||
|
|
||||||
|
block_rule = self.get_rule_dict(
|
||||||
|
'Block All', action=consts.FW_ACTION_DROP,
|
||||||
|
logged=log_sg_blocked_traffic)
|
||||||
|
# TODO(roeyc): Add additional rules to allow IPV6 NDP.
|
||||||
|
dhcp_client = self.get_nsservice(
|
||||||
|
consts.L4_PORT_SET_NSSERVICE,
|
||||||
|
l4_protocol=consts.UDP,
|
||||||
|
source_ports=[67],
|
||||||
|
destination_ports=[68])
|
||||||
|
dhcp_client_rule_in = self.get_rule_dict(
|
||||||
|
'DHCP Reply', direction=consts.IN,
|
||||||
|
service=dhcp_client)
|
||||||
|
|
||||||
|
dhcp_server = (
|
||||||
|
self.get_nsservice(
|
||||||
|
consts.L4_PORT_SET_NSSERVICE,
|
||||||
|
l4_protocol=consts.UDP,
|
||||||
|
source_ports=[68],
|
||||||
|
destination_ports=[67]))
|
||||||
|
dhcp_client_rule_out = self.get_rule_dict(
|
||||||
|
'DHCP Request', direction=consts.OUT,
|
||||||
|
service=dhcp_server)
|
||||||
|
|
||||||
|
self.update(section['id'],
|
||||||
|
name, section['description'],
|
||||||
|
applied_tos=nested_groups,
|
||||||
|
rules=[dhcp_client_rule_out,
|
||||||
|
dhcp_client_rule_in,
|
||||||
|
block_rule])
|
||||||
|
return section['id']
|
||||||
|
@ -20,6 +20,7 @@ from neutron_lib import exceptions
|
|||||||
from oslo_log import log
|
from oslo_log import log
|
||||||
|
|
||||||
from vmware_nsx._i18n import _
|
from vmware_nsx._i18n import _
|
||||||
|
from vmware_nsx.nsxlib.v3 import exceptions as nsxlib_exceptions
|
||||||
|
|
||||||
LOG = log.getLogger(__name__)
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
@ -169,3 +170,48 @@ def get_name_and_uuid(name, uuid, tag=None, maxlen=80):
|
|||||||
return name[:maxlen] + '_' + tag + short_uuid
|
return name[:maxlen] + '_' + tag + short_uuid
|
||||||
else:
|
else:
|
||||||
return name[:maxlen] + short_uuid
|
return name[:maxlen] + short_uuid
|
||||||
|
|
||||||
|
|
||||||
|
class NsxLibApiBase(object):
|
||||||
|
"""Base class for nsxlib api """
|
||||||
|
def __init__(self, client, max_attempts):
|
||||||
|
self.client = client
|
||||||
|
self.max_attempts = max_attempts
|
||||||
|
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)
|
||||||
|
def do_update():
|
||||||
|
revised_payload = self.client.get(resource)
|
||||||
|
for key_name in payload.keys():
|
||||||
|
revised_payload[key_name] = payload[key_name]
|
||||||
|
return self.client.update(resource, revised_payload)
|
||||||
|
|
||||||
|
return do_update()
|
||||||
|
|
||||||
|
def _get_resource_by_name_or_id(self, name_or_id, resource):
|
||||||
|
all_results = self.client.get(resource)['results']
|
||||||
|
matched_results = []
|
||||||
|
for rs in all_results:
|
||||||
|
if rs.get('id') == name_or_id:
|
||||||
|
# Matched by id - must be unique
|
||||||
|
return name_or_id
|
||||||
|
|
||||||
|
if rs.get('display_name') == name_or_id:
|
||||||
|
# Matched by name - add to the list to verify it is unique
|
||||||
|
matched_results.append(rs)
|
||||||
|
|
||||||
|
if len(matched_results) == 0:
|
||||||
|
err_msg = (_("Could not find %(resource)s %(name)s") %
|
||||||
|
{'name': name_or_id, 'resource': resource})
|
||||||
|
# XXX improve exception handling...
|
||||||
|
raise exceptions.ManagerError(details=err_msg)
|
||||||
|
elif len(matched_results) > 1:
|
||||||
|
err_msg = (_("Found multiple %(resource)s named %(name)s") %
|
||||||
|
{'name': name_or_id, 'resource': resource})
|
||||||
|
# XXX improve exception handling...
|
||||||
|
raise exceptions.ManagerError(details=err_msg)
|
||||||
|
|
||||||
|
return matched_results[0].get('id')
|
||||||
|
@ -256,21 +256,21 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
# default VLAN transport zone name / uuid
|
# default VLAN transport zone name / uuid
|
||||||
self._default_vlan_tz_uuid = None
|
self._default_vlan_tz_uuid = None
|
||||||
if cfg.CONF.nsx_v3.default_vlan_tz:
|
if cfg.CONF.nsx_v3.default_vlan_tz:
|
||||||
tz_id = self.nsxlib.get_transport_zone_id_by_name_or_id(
|
tz_id = self.nsxlib.transport_zone.get_id_by_name_or_id(
|
||||||
cfg.CONF.nsx_v3.default_vlan_tz)
|
cfg.CONF.nsx_v3.default_vlan_tz)
|
||||||
self._default_vlan_tz_uuid = tz_id
|
self._default_vlan_tz_uuid = tz_id
|
||||||
|
|
||||||
# default overlay transport zone name / uuid
|
# default overlay transport zone name / uuid
|
||||||
self._default_overlay_tz_uuid = None
|
self._default_overlay_tz_uuid = None
|
||||||
if cfg.CONF.nsx_v3.default_overlay_tz:
|
if cfg.CONF.nsx_v3.default_overlay_tz:
|
||||||
tz_id = self.nsxlib.get_transport_zone_id_by_name_or_id(
|
tz_id = self.nsxlib.transport_zone.get_id_by_name_or_id(
|
||||||
cfg.CONF.nsx_v3.default_overlay_tz)
|
cfg.CONF.nsx_v3.default_overlay_tz)
|
||||||
self._default_overlay_tz_uuid = tz_id
|
self._default_overlay_tz_uuid = tz_id
|
||||||
|
|
||||||
# default tier0 router
|
# default tier0 router
|
||||||
self._default_tier0_router = None
|
self._default_tier0_router = None
|
||||||
if cfg.CONF.nsx_v3.default_tier0_router:
|
if cfg.CONF.nsx_v3.default_tier0_router:
|
||||||
rtr_id = self.nsxlib.get_logical_router_id_by_name_or_id(
|
rtr_id = self.nsxlib.logical_router.get_id_by_name_or_id(
|
||||||
cfg.CONF.nsx_v3.default_tier0_router)
|
cfg.CONF.nsx_v3.default_tier0_router)
|
||||||
self._default_tier0_router = rtr_id
|
self._default_tier0_router = rtr_id
|
||||||
|
|
||||||
@ -393,7 +393,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
nsgroup_id, section_id = nsx_db.get_sg_mappings(
|
nsgroup_id, section_id = nsx_db.get_sg_mappings(
|
||||||
context.session, sg['id'])
|
context.session, sg['id'])
|
||||||
try:
|
try:
|
||||||
self.nsxlib.set_firewall_rule_logging_for_section(
|
self.nsxlib.firewall_section.set_rule_logging(
|
||||||
section_id, logging=log_all_rules)
|
section_id, logging=log_all_rules)
|
||||||
except nsx_lib_exc.ManagerError:
|
except nsx_lib_exc.ManagerError:
|
||||||
with excutils.save_and_reraise_exception():
|
with excutils.save_and_reraise_exception():
|
||||||
@ -408,7 +408,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
self.nsxlib, cfg.CONF.nsx_v3.number_of_nested_groups)
|
self.nsxlib, cfg.CONF.nsx_v3.number_of_nested_groups)
|
||||||
section_description = ("This section is handled by OpenStack to "
|
section_description = ("This section is handled by OpenStack to "
|
||||||
"contain default rules on security-groups.")
|
"contain default rules on security-groups.")
|
||||||
section_id = self.nsxlib.init_default_section(
|
section_id = self.nsxlib.firewall_section.init_default(
|
||||||
security.DEFAULT_SECTION, section_description,
|
security.DEFAULT_SECTION, section_description,
|
||||||
nsgroup_manager.nested_groups.values(),
|
nsgroup_manager.nested_groups.values(),
|
||||||
cfg.CONF.nsx_v3.log_security_groups_blocked_traffic)
|
cfg.CONF.nsx_v3.log_security_groups_blocked_traffic)
|
||||||
@ -610,7 +610,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
'tags': tags,
|
'tags': tags,
|
||||||
'admin_state': admin_state,
|
'admin_state': admin_state,
|
||||||
'vlan_id': vlan_id})
|
'vlan_id': vlan_id})
|
||||||
nsx_result = self.nsxlib.create_logical_switch(
|
nsx_result = self.nsxlib.logical_switch.create(
|
||||||
net_name, physical_net, tags,
|
net_name, physical_net, tags,
|
||||||
admin_state=admin_state,
|
admin_state=admin_state,
|
||||||
vlan_id=vlan_id)
|
vlan_id=vlan_id)
|
||||||
@ -728,7 +728,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
LOG.exception(_LE('Failed to create network %s'),
|
LOG.exception(_LE('Failed to create network %s'),
|
||||||
created_net['id'])
|
created_net['id'])
|
||||||
if net_type != utils.NetworkTypes.L3_EXT:
|
if net_type != utils.NetworkTypes.L3_EXT:
|
||||||
self.nsxlib.delete_logical_switch(created_net['id'])
|
self.nsxlib.logical_switch.delete(created_net['id'])
|
||||||
|
|
||||||
# this extra lookup is necessary to get the
|
# this extra lookup is necessary to get the
|
||||||
# latest db model for the extension functions
|
# latest db model for the extension functions
|
||||||
@ -810,7 +810,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
# TODO(salv-orlando): Handle backend failure, possibly without
|
# TODO(salv-orlando): Handle backend failure, possibly without
|
||||||
# requiring us to un-delete the DB object. For instance, ignore
|
# requiring us to un-delete the DB object. For instance, ignore
|
||||||
# failures occurring if logical switch is not found
|
# failures occurring if logical switch is not found
|
||||||
self.nsxlib.delete_logical_switch(nsx_net_id)
|
self.nsxlib.logical_switch.delete(nsx_net_id)
|
||||||
else:
|
else:
|
||||||
# TODO(berlin): delete subnets public announce on the network
|
# TODO(berlin): delete subnets public announce on the network
|
||||||
pass
|
pass
|
||||||
@ -850,7 +850,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
try:
|
try:
|
||||||
# get the nsx switch id from the DB mapping
|
# get the nsx switch id from the DB mapping
|
||||||
nsx_id = self._get_network_nsx_id(context, id)
|
nsx_id = self._get_network_nsx_id(context, id)
|
||||||
self.nsxlib.update_logical_switch(
|
self.nsxlib.logical_switch.update(
|
||||||
nsx_id,
|
nsx_id,
|
||||||
name=utils.get_name_and_uuid(net_data['name'] or 'network',
|
name=utils.get_name_and_uuid(net_data['name'] or 'network',
|
||||||
id),
|
id),
|
||||||
@ -1232,7 +1232,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
def _get_qos_profile_id(self, context, policy_id):
|
def _get_qos_profile_id(self, context, policy_id):
|
||||||
switch_profile_id = nsx_db.get_switch_profile_by_qos_policy(
|
switch_profile_id = nsx_db.get_switch_profile_by_qos_policy(
|
||||||
context.session, policy_id)
|
context.session, policy_id)
|
||||||
qos_profile = self.nsxlib.get_qos_switching_profile(switch_profile_id)
|
qos_profile = self.nsxlib.qos_switching_profile.get(switch_profile_id)
|
||||||
if qos_profile:
|
if qos_profile:
|
||||||
profile_ids = self._switching_profiles.build_switch_profile_ids(
|
profile_ids = self._switching_profiles.build_switch_profile_ids(
|
||||||
self._switching_profiles, qos_profile)
|
self._switching_profiles, qos_profile)
|
||||||
@ -1266,7 +1266,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
# If port has no security-groups then we don't need to add any
|
# If port has no security-groups then we don't need to add any
|
||||||
# security criteria tag.
|
# security criteria tag.
|
||||||
if port_data[ext_sg.SECURITYGROUPS]:
|
if port_data[ext_sg.SECURITYGROUPS]:
|
||||||
tags += self.nsxlib.get_lport_tags_for_security_groups(
|
tags += self.nsxlib.ns_group.get_lport_tags(
|
||||||
port_data[ext_sg.SECURITYGROUPS] +
|
port_data[ext_sg.SECURITYGROUPS] +
|
||||||
port_data[provider_sg.PROVIDER_SECURITYGROUPS])
|
port_data[provider_sg.PROVIDER_SECURITYGROUPS])
|
||||||
|
|
||||||
@ -1627,7 +1627,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
original)
|
original)
|
||||||
nsx_updated = nsx_db.get_nsx_security_group_ids(context.session,
|
nsx_updated = nsx_db.get_nsx_security_group_ids(context.session,
|
||||||
updated)
|
updated)
|
||||||
self.nsxlib.update_lport_with_security_groups(
|
self.nsxlib.ns_group.update_lport(
|
||||||
context, lport_id, nsx_origial, nsx_updated)
|
context, lport_id, nsx_origial, nsx_updated)
|
||||||
|
|
||||||
def create_port(self, context, port, l2gw_port_check=False):
|
def create_port(self, context, port, l2gw_port_check=False):
|
||||||
@ -1898,7 +1898,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
name = self._get_port_name(context, updated_port)
|
name = self._get_port_name(context, updated_port)
|
||||||
|
|
||||||
if utils.is_nsx_version_1_1_0(self._nsx_version):
|
if utils.is_nsx_version_1_1_0(self._nsx_version):
|
||||||
tags_update += self.nsxlib.get_lport_tags_for_security_groups(
|
tags_update += self.nsxlib.ns_group.get_lport_tags(
|
||||||
updated_port.get(ext_sg.SECURITYGROUPS, []) +
|
updated_port.get(ext_sg.SECURITYGROUPS, []) +
|
||||||
updated_port.get(provider_sg.PROVIDER_SECURITYGROUPS, []))
|
updated_port.get(provider_sg.PROVIDER_SECURITYGROUPS, []))
|
||||||
else:
|
else:
|
||||||
@ -2791,7 +2791,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
|
|
||||||
# security-group rules are located in a dedicated firewall section.
|
# security-group rules are located in a dedicated firewall section.
|
||||||
firewall_section = (
|
firewall_section = (
|
||||||
self.nsxlib.create_empty_section(
|
self.nsxlib.firewall_section.create_empty(
|
||||||
nsgroup.get('display_name'), nsgroup.get('description'),
|
nsgroup.get('display_name'), nsgroup.get('description'),
|
||||||
[nsgroup.get('id')], nsgroup.get('tags'),
|
[nsgroup.get('id')], nsgroup.get('tags'),
|
||||||
operation=operation,
|
operation=operation,
|
||||||
@ -2802,16 +2802,16 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
tags = nsxlib_utils.build_v3_tags_payload(
|
tags = nsxlib_utils.build_v3_tags_payload(
|
||||||
secgroup, resource_type='os-neutron-secgr-id',
|
secgroup, resource_type='os-neutron-secgr-id',
|
||||||
project_name=secgroup['tenant_id'])
|
project_name=secgroup['tenant_id'])
|
||||||
name = self.nsxlib.get_nsgroup_name(secgroup)
|
name = self.nsxlib.ns_group.get_name(secgroup)
|
||||||
|
|
||||||
if utils.is_nsx_version_1_1_0(self._nsx_version):
|
if utils.is_nsx_version_1_1_0(self._nsx_version):
|
||||||
tag_expression = (
|
tag_expression = (
|
||||||
self.nsxlib.get_nsgroup_port_tag_expression(
|
self.nsxlib.ns_group.get_port_tag_expression(
|
||||||
security.PORT_SG_SCOPE, secgroup['id']))
|
security.PORT_SG_SCOPE, secgroup['id']))
|
||||||
else:
|
else:
|
||||||
tag_expression = None
|
tag_expression = None
|
||||||
|
|
||||||
ns_group = self.nsxlib.create_nsgroup(
|
ns_group = self.nsxlib.ns_group.create(
|
||||||
name, secgroup['description'], tags, tag_expression)
|
name, secgroup['description'], tags, tag_expression)
|
||||||
# security-group rules are located in a dedicated firewall section.
|
# security-group rules are located in a dedicated firewall section.
|
||||||
firewall_section = self._create_fw_section_for_secgroup(
|
firewall_section = self._create_fw_section_for_secgroup(
|
||||||
@ -2834,7 +2834,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
context.session, remote_group_id)
|
context.session, remote_group_id)
|
||||||
ruleid_2_remote_nsgroup_map[sg_rule['id']] = remote_nsgroup_id
|
ruleid_2_remote_nsgroup_map[sg_rule['id']] = remote_nsgroup_id
|
||||||
|
|
||||||
return self.nsxlib.create_firewall_rules(
|
return self.nsxlib.firewall_section.create_rules(
|
||||||
context, section_id, nsgroup_id,
|
context, section_id, nsgroup_id,
|
||||||
logging_enabled, action, sg_rules,
|
logging_enabled, action, sg_rules,
|
||||||
ruleid_2_remote_nsgroup_map)
|
ruleid_2_remote_nsgroup_map)
|
||||||
@ -2880,7 +2880,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
LOG.exception(_LE("Unable to create security-group on the "
|
LOG.exception(_LE("Unable to create security-group on the "
|
||||||
"backend."))
|
"backend."))
|
||||||
if ns_group:
|
if ns_group:
|
||||||
self.nsxlib.delete_nsgroup(ns_group['id'])
|
self.nsxlib.ns_group.delete(ns_group['id'])
|
||||||
except Exception:
|
except Exception:
|
||||||
with excutils.save_and_reraise_exception():
|
with excutils.save_and_reraise_exception():
|
||||||
section_id = firewall_section.get('id')
|
section_id = firewall_section.get('id')
|
||||||
@ -2890,9 +2890,9 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
"section %s, ns-group %s.",
|
"section %s, ns-group %s.",
|
||||||
section_id, nsgroup_id)
|
section_id, nsgroup_id)
|
||||||
if nsgroup_id:
|
if nsgroup_id:
|
||||||
self.nsxlib.delete_nsgroup(nsgroup_id)
|
self.nsxlib.ns_group.delete(nsgroup_id)
|
||||||
if section_id:
|
if section_id:
|
||||||
self.nsxlib.delete_section(section_id)
|
self.nsxlib.firewall_section.delete(section_id)
|
||||||
try:
|
try:
|
||||||
sg_rules = secgroup_db['security_group_rules']
|
sg_rules = secgroup_db['security_group_rules']
|
||||||
# skip if there are no rules in group. i.e provider case
|
# skip if there are no rules in group. i.e provider case
|
||||||
@ -2918,8 +2918,8 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
context = context.elevated()
|
context = context.elevated()
|
||||||
super(NsxV3Plugin, self).delete_security_group(
|
super(NsxV3Plugin, self).delete_security_group(
|
||||||
context, secgroup_db['id'])
|
context, secgroup_db['id'])
|
||||||
self.nsxlib.delete_nsgroup(ns_group['id'])
|
self.nsxlib.ns_group.delete(ns_group['id'])
|
||||||
self.nsxlib.delete_section(firewall_section['id'])
|
self.nsxlib.firewall_section.delete(firewall_section['id'])
|
||||||
|
|
||||||
return secgroup_db
|
return secgroup_db
|
||||||
|
|
||||||
@ -2935,7 +2935,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
try:
|
try:
|
||||||
nsgroup_id, section_id = nsx_db.get_sg_mappings(
|
nsgroup_id, section_id = nsx_db.get_sg_mappings(
|
||||||
context.session, id)
|
context.session, id)
|
||||||
self.nsxlib.update_security_group_on_backend(
|
self.nsxlib.ns_group.update_on_backend(
|
||||||
context, secgroup_res, nsgroup_id, section_id,
|
context, secgroup_res, nsgroup_id, section_id,
|
||||||
cfg.CONF.nsx_v3.log_security_groups_allowed_traffic)
|
cfg.CONF.nsx_v3.log_security_groups_allowed_traffic)
|
||||||
except nsx_lib_exc.ManagerError:
|
except nsx_lib_exc.ManagerError:
|
||||||
@ -2953,8 +2953,8 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
nsgroup_id, section_id = nsx_db.get_sg_mappings(
|
nsgroup_id, section_id = nsx_db.get_sg_mappings(
|
||||||
context.session, id)
|
context.session, id)
|
||||||
super(NsxV3Plugin, self).delete_security_group(context, id)
|
super(NsxV3Plugin, self).delete_security_group(context, id)
|
||||||
self.nsxlib.delete_section(section_id)
|
self.nsxlib.firewall_section.delete(section_id)
|
||||||
self.nsxlib.delete_nsgroup(nsgroup_id)
|
self.nsxlib.ns_group.delete(nsgroup_id)
|
||||||
self.nsgroup_manager.remove_nsgroup(nsgroup_id)
|
self.nsgroup_manager.remove_nsgroup(nsgroup_id)
|
||||||
|
|
||||||
def create_security_group_rule(self, context, security_group_rule):
|
def create_security_group_rule(self, context, security_group_rule):
|
||||||
@ -3017,7 +3017,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
self._prevent_non_admin_delete_provider_sg(context, sg_id)
|
self._prevent_non_admin_delete_provider_sg(context, sg_id)
|
||||||
nsgroup_id, section_id = nsx_db.get_sg_mappings(context.session, sg_id)
|
nsgroup_id, section_id = nsx_db.get_sg_mappings(context.session, sg_id)
|
||||||
fw_rule_id = nsx_db.get_sg_rule_mapping(context.session, id)
|
fw_rule_id = nsx_db.get_sg_rule_mapping(context.session, id)
|
||||||
self.nsxlib.delete_rule(section_id, fw_rule_id)
|
self.nsxlib.firewall_section.delete_rule(section_id, fw_rule_id)
|
||||||
super(NsxV3Plugin, self).delete_security_group_rule(context, id)
|
super(NsxV3Plugin, self).delete_security_group_rule(context, id)
|
||||||
|
|
||||||
def save_security_group_rule_mappings(self, context, firewall_rules):
|
def save_security_group_rule_mappings(self, context, firewall_rules):
|
||||||
|
@ -85,7 +85,7 @@ class NsxV3Driver(l2gateway_db.L2GatewayMixin):
|
|||||||
admin_ctx = context.get_admin_context()
|
admin_ctx = context.get_admin_context()
|
||||||
|
|
||||||
def_l2gw_uuid = (
|
def_l2gw_uuid = (
|
||||||
self._core_plugin.nsxlib.get_bridge_cluster_id_by_name_or_id(
|
self._core_plugin.nsxlib.bridge_cluster.get_id_by_name_or_id(
|
||||||
def_l2gw_name))
|
def_l2gw_name))
|
||||||
|
|
||||||
# Optimistically create the default L2 gateway in neutron DB
|
# Optimistically create the default L2 gateway in neutron DB
|
||||||
@ -223,7 +223,7 @@ class NsxV3Driver(l2gateway_db.L2GatewayMixin):
|
|||||||
tags = nsxlib_utils.build_v3_tags_payload(
|
tags = nsxlib_utils.build_v3_tags_payload(
|
||||||
gw_connection, resource_type='os-neutron-l2gw-id',
|
gw_connection, resource_type='os-neutron-l2gw-id',
|
||||||
project_name=context.tenant_name)
|
project_name=context.tenant_name)
|
||||||
bridge_endpoint = self._core_plugin.nsxlib.create_bridge_endpoint(
|
bridge_endpoint = self._core_plugin.nsxlib.bridge_endpoint.create(
|
||||||
device_name=device_name,
|
device_name=device_name,
|
||||||
seg_id=seg_id,
|
seg_id=seg_id,
|
||||||
tags=tags)
|
tags=tags)
|
||||||
@ -258,7 +258,7 @@ class NsxV3Driver(l2gateway_db.L2GatewayMixin):
|
|||||||
n_exc.NeutronException):
|
n_exc.NeutronException):
|
||||||
LOG.exception(_LE("Unable to create L2 gateway port, "
|
LOG.exception(_LE("Unable to create L2 gateway port, "
|
||||||
"rolling back changes on neutron"))
|
"rolling back changes on neutron"))
|
||||||
self._core_plugin.nsxlib.delete_bridge_endpoint(
|
self._core_plugin.nsxlib.bridge_endpoint.delete(
|
||||||
bridge_endpoint['id'])
|
bridge_endpoint['id'])
|
||||||
raise l2gw_exc.L2GatewayServiceDriverError(
|
raise l2gw_exc.L2GatewayServiceDriverError(
|
||||||
method='create_l2_gateway_connection_postcommit')
|
method='create_l2_gateway_connection_postcommit')
|
||||||
@ -273,7 +273,7 @@ class NsxV3Driver(l2gateway_db.L2GatewayMixin):
|
|||||||
with excutils.save_and_reraise_exception():
|
with excutils.save_and_reraise_exception():
|
||||||
LOG.exception(_LE("Unable to add L2 gateway connection "
|
LOG.exception(_LE("Unable to add L2 gateway connection "
|
||||||
"mappings, rolling back changes on neutron"))
|
"mappings, rolling back changes on neutron"))
|
||||||
self._core_plugin.nsxlib.delete_bridge_endpoint(
|
self._core_plugin.nsxlib.bridge_endpoint.delete(
|
||||||
bridge_endpoint['id'])
|
bridge_endpoint['id'])
|
||||||
super(NsxV3Driver,
|
super(NsxV3Driver,
|
||||||
self).delete_l2_gateway_connection(
|
self).delete_l2_gateway_connection(
|
||||||
@ -298,7 +298,7 @@ class NsxV3Driver(l2gateway_db.L2GatewayMixin):
|
|||||||
port_id=conn_mapping.get('port_id'),
|
port_id=conn_mapping.get('port_id'),
|
||||||
l2gw_port_check=False)
|
l2gw_port_check=False)
|
||||||
try:
|
try:
|
||||||
self._core_plugin.nsxlib.delete_bridge_endpoint(bridge_endpoint_id)
|
self._core_plugin.nsxlib.bridge_endpoint.delete(bridge_endpoint_id)
|
||||||
except nsxlib_exc.ManagerError as e:
|
except nsxlib_exc.ManagerError as e:
|
||||||
LOG.exception(_LE("Unable to delete bridge endpoint %(id)s on the "
|
LOG.exception(_LE("Unable to delete bridge endpoint %(id)s on the "
|
||||||
"backend due to exc: %(exc)s"),
|
"backend due to exc: %(exc)s"),
|
||||||
|
@ -281,7 +281,7 @@ class NsxV3Driver(base_driver.TaasBaseDriver,
|
|||||||
# Create port mirror session on the backend
|
# Create port mirror session on the backend
|
||||||
try:
|
try:
|
||||||
nsxlib = v3_utils.get_nsxlib_wrapper()
|
nsxlib = v3_utils.get_nsxlib_wrapper()
|
||||||
pm_session = nsxlib.create_port_mirror_session(
|
pm_session = nsxlib.port_mirror.create_session(
|
||||||
source_ports=nsx_src_ports,
|
source_ports=nsx_src_ports,
|
||||||
dest_ports=nsx_dest_ports,
|
dest_ports=nsx_dest_ports,
|
||||||
direction=direction,
|
direction=direction,
|
||||||
@ -307,8 +307,7 @@ class NsxV3Driver(base_driver.TaasBaseDriver,
|
|||||||
LOG.error(_LE("Unable to create port mirror session db "
|
LOG.error(_LE("Unable to create port mirror session db "
|
||||||
"mappings for tap flow %s. Rolling back "
|
"mappings for tap flow %s. Rolling back "
|
||||||
"changes in Neutron."), tf['id'])
|
"changes in Neutron."), tf['id'])
|
||||||
nsxlib.delete_port_mirror_session(
|
nsxlib.port_mirror.delete_session(pm_session['id'])
|
||||||
pm_session['id'])
|
|
||||||
|
|
||||||
def delete_tap_flow_precommit(self, context):
|
def delete_tap_flow_precommit(self, context):
|
||||||
pass
|
pass
|
||||||
@ -369,7 +368,7 @@ class NsxV3Driver(base_driver.TaasBaseDriver,
|
|||||||
def _delete_local_span(self, context, pm_session_id):
|
def _delete_local_span(self, context, pm_session_id):
|
||||||
# Delete port mirroring session on the backend
|
# Delete port mirroring session on the backend
|
||||||
try:
|
try:
|
||||||
nsxlib.delete_port_mirror_session(pm_session_id)
|
nsxlib.port_mirror.delete_session(pm_session_id)
|
||||||
except nsxlib_exc.ManagerError:
|
except nsxlib_exc.ManagerError:
|
||||||
with excutils.save_and_reraise_exception():
|
with excutils.save_and_reraise_exception():
|
||||||
LOG.error(_LE("Unable to delete port mirror session %s "
|
LOG.error(_LE("Unable to delete port mirror session %s "
|
||||||
|
@ -84,6 +84,10 @@ class QosNotificationsHandler(object):
|
|||||||
def _core_plugin(self):
|
def _core_plugin(self):
|
||||||
return manager.NeutronManager.get_plugin()
|
return manager.NeutronManager.get_plugin()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _nsxlib_qos(self):
|
||||||
|
return self._core_plugin.nsxlib.qos_switching_profile
|
||||||
|
|
||||||
def _get_tags(self, context, policy):
|
def _get_tags(self, context, policy):
|
||||||
policy_dict = {'id': policy.id, 'tenant_id': policy.tenant_id}
|
policy_dict = {'id': policy.id, 'tenant_id': policy.tenant_id}
|
||||||
return utils.build_v3_tags_payload(
|
return utils.build_v3_tags_payload(
|
||||||
@ -93,7 +97,7 @@ class QosNotificationsHandler(object):
|
|||||||
def create_policy(self, context, policy):
|
def create_policy(self, context, policy):
|
||||||
policy_id = policy.id
|
policy_id = policy.id
|
||||||
tags = self._get_tags(context, policy)
|
tags = self._get_tags(context, policy)
|
||||||
result = self._core_plugin.nsxlib.create_qos_switching_profile(
|
result = self._nsxlib_qos.create(
|
||||||
tags=tags, name=policy.name,
|
tags=tags, name=policy.name,
|
||||||
description=policy.description)
|
description=policy.description)
|
||||||
if not result or not validators.is_attr_set(result.get('id')):
|
if not result or not validators.is_attr_set(result.get('id')):
|
||||||
@ -109,13 +113,13 @@ class QosNotificationsHandler(object):
|
|||||||
def delete_policy(self, context, policy_id):
|
def delete_policy(self, context, policy_id):
|
||||||
profile_id = nsx_db.get_switch_profile_by_qos_policy(
|
profile_id = nsx_db.get_switch_profile_by_qos_policy(
|
||||||
context.session, policy_id)
|
context.session, policy_id)
|
||||||
self._core_plugin.nsxlib.delete_qos_switching_profile(profile_id)
|
self._nsxlib_qos.delete(profile_id)
|
||||||
|
|
||||||
def update_policy(self, context, policy_id, policy):
|
def update_policy(self, context, policy_id, policy):
|
||||||
profile_id = nsx_db.get_switch_profile_by_qos_policy(
|
profile_id = nsx_db.get_switch_profile_by_qos_policy(
|
||||||
context.session, policy_id)
|
context.session, policy_id)
|
||||||
tags = self._get_tags(context, policy)
|
tags = self._get_tags(context, policy)
|
||||||
self._core_plugin.nsxlib.update_qos_switching_profile(
|
self._nsxlib_qos.update(
|
||||||
profile_id,
|
profile_id,
|
||||||
tags=tags,
|
tags=tags,
|
||||||
name=policy.name,
|
name=policy.name,
|
||||||
@ -185,7 +189,7 @@ class QosNotificationsHandler(object):
|
|||||||
average_bw) = self._get_bw_values_from_rule(bw_rule)
|
average_bw) = self._get_bw_values_from_rule(bw_rule)
|
||||||
|
|
||||||
qos_marking, dscp = self._get_dscp_values_from_rule(dscp_rule)
|
qos_marking, dscp = self._get_dscp_values_from_rule(dscp_rule)
|
||||||
self._core_plugin.nsxlib.update_qos_switching_profile_shaping(
|
self._nsxlib_qos.update_shaping(
|
||||||
profile_id,
|
profile_id,
|
||||||
shaping_enabled=shaping_enabled,
|
shaping_enabled=shaping_enabled,
|
||||||
burst_size=burst_size,
|
burst_size=burst_size,
|
||||||
|
@ -54,7 +54,7 @@ def list_missing_networks(resource, event, trigger, **kwargs):
|
|||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
admin_utils.get_connected_nsxlib().get_logical_switch(nsx_id)
|
admin_utils.get_connected_nsxlib().logical_switch.get(nsx_id)
|
||||||
except nsx_exc.ResourceNotFound:
|
except nsx_exc.ResourceNotFound:
|
||||||
networks.append({'name': net['name'],
|
networks.append({'name': net['name'],
|
||||||
'neutron_id': neutron_id,
|
'neutron_id': neutron_id,
|
||||||
|
@ -128,7 +128,7 @@ def list_security_groups_mappings(resource, event, trigger, **kwargs):
|
|||||||
@admin_utils.list_handler(constants.FIREWALL_SECTIONS)
|
@admin_utils.list_handler(constants.FIREWALL_SECTIONS)
|
||||||
@admin_utils.output_header
|
@admin_utils.output_header
|
||||||
def nsx_list_dfw_sections(resource, event, trigger, **kwargs):
|
def nsx_list_dfw_sections(resource, event, trigger, **kwargs):
|
||||||
fw_sections = nsxlib.list_sections()
|
fw_sections = nsxlib.firewall_section.list()
|
||||||
_log_info(constants.FIREWALL_SECTIONS, fw_sections)
|
_log_info(constants.FIREWALL_SECTIONS, fw_sections)
|
||||||
return bool(fw_sections)
|
return bool(fw_sections)
|
||||||
|
|
||||||
@ -136,13 +136,13 @@ def nsx_list_dfw_sections(resource, event, trigger, **kwargs):
|
|||||||
@admin_utils.list_handler(constants.FIREWALL_NSX_GROUPS)
|
@admin_utils.list_handler(constants.FIREWALL_NSX_GROUPS)
|
||||||
@admin_utils.output_header
|
@admin_utils.output_header
|
||||||
def nsx_list_security_groups(resource, event, trigger, **kwargs):
|
def nsx_list_security_groups(resource, event, trigger, **kwargs):
|
||||||
nsx_secgroups = nsxlib.list_nsgroups()
|
nsx_secgroups = nsxlib.ns_group.list()
|
||||||
_log_info(constants.FIREWALL_NSX_GROUPS, nsx_secgroups)
|
_log_info(constants.FIREWALL_NSX_GROUPS, nsx_secgroups)
|
||||||
return bool(nsx_secgroups)
|
return bool(nsx_secgroups)
|
||||||
|
|
||||||
|
|
||||||
def _find_missing_security_groups():
|
def _find_missing_security_groups():
|
||||||
nsx_secgroups = nsxlib.list_nsgroups()
|
nsx_secgroups = nsxlib.ns_group.list()
|
||||||
sg_mappings = neutron_sg.get_security_groups_mappings()
|
sg_mappings = neutron_sg.get_security_groups_mappings()
|
||||||
missing_secgroups = {}
|
missing_secgroups = {}
|
||||||
for sg_db in sg_mappings:
|
for sg_db in sg_mappings:
|
||||||
@ -171,7 +171,7 @@ def list_missing_security_groups(resource, event, trigger, **kwargs):
|
|||||||
|
|
||||||
|
|
||||||
def _find_missing_sections():
|
def _find_missing_sections():
|
||||||
fw_sections = nsxlib.list_sections()
|
fw_sections = nsxlib.firewall_section.list()
|
||||||
sg_mappings = neutron_sg.get_security_groups_mappings()
|
sg_mappings = neutron_sg.get_security_groups_mappings()
|
||||||
missing_sections = {}
|
missing_sections = {}
|
||||||
for sg_db in sg_mappings:
|
for sg_db in sg_mappings:
|
||||||
@ -206,8 +206,8 @@ def fix_security_groups(resource, event, trigger, **kwargs):
|
|||||||
|
|
||||||
for sg_id, sg in inconsistent_secgroups.items():
|
for sg_id, sg in inconsistent_secgroups.items():
|
||||||
secgroup = plugin.get_security_group(context_, sg_id)
|
secgroup = plugin.get_security_group(context_, sg_id)
|
||||||
nsxlib.delete_section(sg['section-id'])
|
nsxlib.firewall_section.delete(sg['section-id'])
|
||||||
nsxlib.delete_nsgroup(sg['nsx-securitygroup-id'])
|
nsxlib.ns_group.delete(sg['nsx-securitygroup-id'])
|
||||||
neutron_sg.delete_security_group_section_mapping(sg_id)
|
neutron_sg.delete_security_group_section_mapping(sg_id)
|
||||||
neutron_sg.delete_security_group_backend_mapping(sg_id)
|
neutron_sg.delete_security_group_backend_mapping(sg_id)
|
||||||
nsgroup, fw_section = (
|
nsgroup, fw_section = (
|
||||||
@ -221,7 +221,7 @@ def fix_security_groups(resource, event, trigger, **kwargs):
|
|||||||
for port_id in neutron_db.get_ports_in_security_group(sg_id):
|
for port_id in neutron_db.get_ports_in_security_group(sg_id):
|
||||||
lport_id = neutron_db.get_logical_port_id(port_id)
|
lport_id = neutron_db.get_logical_port_id(port_id)
|
||||||
members.append(lport_id)
|
members.append(lport_id)
|
||||||
nsxlib.add_nsgroup_members(
|
nsxlib.ns_group.add_members(
|
||||||
nsgroup['id'], consts.TARGET_TYPE_LOGICAL_PORT, members)
|
nsgroup['id'], consts.TARGET_TYPE_LOGICAL_PORT, members)
|
||||||
|
|
||||||
for rule in secgroup['security_group_rules']:
|
for rule in secgroup['security_group_rules']:
|
||||||
@ -252,7 +252,7 @@ def _update_ports_dynamic_criteria_tags():
|
|||||||
|
|
||||||
_, lport_id = neutron_db.get_lswitch_and_lport_id(port['id'])
|
_, lport_id = neutron_db.get_lswitch_and_lport_id(port['id'])
|
||||||
lport = port_client.get(lport_id)
|
lport = port_client.get(lport_id)
|
||||||
criteria_tags = nsxlib.get_lport_tags_for_security_groups(secgroups)
|
criteria_tags = nsxlib.ns_group.get_lport_tags(secgroups)
|
||||||
lport['tags'] = nsxlib_utils.update_v3_tags(
|
lport['tags'] = nsxlib_utils.update_v3_tags(
|
||||||
lport.get('tags', []), criteria_tags)
|
lport.get('tags', []), criteria_tags)
|
||||||
port_client._client.update(lport_id, body=lport)
|
port_client._client.update(lport_id, body=lport)
|
||||||
@ -262,12 +262,12 @@ def _update_security_group_dynamic_criteria():
|
|||||||
secgroups = neutron_sg.get_security_groups()
|
secgroups = neutron_sg.get_security_groups()
|
||||||
for sg in secgroups:
|
for sg in secgroups:
|
||||||
nsgroup_id = neutron_sg.get_nsgroup_id(sg['id'])
|
nsgroup_id = neutron_sg.get_nsgroup_id(sg['id'])
|
||||||
membership_criteria = nsxlib.get_nsgroup_port_tag_expression(
|
membership_criteria = nsxlib.ns_group.get_port_tag_expression(
|
||||||
security.PORT_SG_SCOPE, sg['id'])
|
security.PORT_SG_SCOPE, sg['id'])
|
||||||
try:
|
try:
|
||||||
# We want to add the dynamic criteria and remove all direct members
|
# We want to add the dynamic criteria and remove all direct members
|
||||||
# they will be added by the manager using the new criteria.
|
# they will be added by the manager using the new criteria.
|
||||||
nsxlib.update_nsgroup(nsgroup_id,
|
nsxlib.ns_group.update(nsgroup_id,
|
||||||
membership_criteria=membership_criteria,
|
membership_criteria=membership_criteria,
|
||||||
members=[])
|
members=[])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -137,7 +137,7 @@ class TestNSXv3ExtendedSGRule(test_nsxv3_plugin.NsxV3PluginTestCaseMixin,
|
|||||||
'description': ''}]
|
'description': ''}]
|
||||||
|
|
||||||
with mock.patch(
|
with mock.patch(
|
||||||
"vmware_nsx.nsxlib.v3.NsxLib.create_firewall_rules",
|
"vmware_nsx.nsxlib.v3.security.NsxLibFirewallSection.create_rules",
|
||||||
side_effect=test_nsxv3_plugin._mock_create_firewall_rules,
|
side_effect=test_nsxv3_plugin._mock_create_firewall_rules,
|
||||||
) as mock_rule:
|
) as mock_rule:
|
||||||
|
|
||||||
|
@ -46,11 +46,11 @@ def _mock_create_and_list_nsgroups(test_method):
|
|||||||
|
|
||||||
def wrap(*args, **kwargs):
|
def wrap(*args, **kwargs):
|
||||||
with mock.patch(
|
with mock.patch(
|
||||||
'vmware_nsx.nsxlib.v3.NsxLib.create_nsgroup'
|
'vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.create'
|
||||||
) as create_nsgroup_mock:
|
) as create_nsgroup_mock:
|
||||||
create_nsgroup_mock.side_effect = _create_nsgroup_mock
|
create_nsgroup_mock.side_effect = _create_nsgroup_mock
|
||||||
with mock.patch(
|
with mock.patch(
|
||||||
"vmware_nsx.nsxlib.v3.NsxLib.list_nsgroups"
|
"vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.list"
|
||||||
) as list_nsgroups_mock:
|
) as list_nsgroups_mock:
|
||||||
list_nsgroups_mock.side_effect = lambda: nsgroups
|
list_nsgroups_mock.side_effect = lambda: nsgroups
|
||||||
test_method(*args, **kwargs)
|
test_method(*args, **kwargs)
|
||||||
@ -74,8 +74,8 @@ class TestSecurityGroupsNoDynamicCriteria(test_nsxv3.NsxV3PluginTestCaseMixin,
|
|||||||
self._patchers.append(mock_nsx_version)
|
self._patchers.append(mock_nsx_version)
|
||||||
|
|
||||||
@_mock_create_and_list_nsgroups
|
@_mock_create_and_list_nsgroups
|
||||||
@mock.patch('vmware_nsx.nsxlib.v3.NsxLib.remove_nsgroup_member')
|
@mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.remove_member')
|
||||||
@mock.patch('vmware_nsx.nsxlib.v3.NsxLib.add_nsgroup_members')
|
@mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.add_members')
|
||||||
def test_create_port_with_multiple_security_groups(self,
|
def test_create_port_with_multiple_security_groups(self,
|
||||||
add_member_mock,
|
add_member_mock,
|
||||||
remove_member_mock):
|
remove_member_mock):
|
||||||
@ -91,8 +91,8 @@ class TestSecurityGroupsNoDynamicCriteria(test_nsxv3.NsxV3PluginTestCaseMixin,
|
|||||||
add_member_mock.assert_has_calls(calls, any_order=True)
|
add_member_mock.assert_has_calls(calls, any_order=True)
|
||||||
|
|
||||||
@_mock_create_and_list_nsgroups
|
@_mock_create_and_list_nsgroups
|
||||||
@mock.patch('vmware_nsx.nsxlib.v3.NsxLib.remove_nsgroup_member')
|
@mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.remove_member')
|
||||||
@mock.patch('vmware_nsx.nsxlib.v3.NsxLib.add_nsgroup_members')
|
@mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.add_members')
|
||||||
def test_update_port_with_multiple_security_groups(self,
|
def test_update_port_with_multiple_security_groups(self,
|
||||||
add_member_mock,
|
add_member_mock,
|
||||||
remove_member_mock):
|
remove_member_mock):
|
||||||
@ -111,8 +111,8 @@ class TestSecurityGroupsNoDynamicCriteria(test_nsxv3.NsxV3PluginTestCaseMixin,
|
|||||||
NSG_IDS[0], consts.TARGET_TYPE_LOGICAL_PORT, mock.ANY)
|
NSG_IDS[0], consts.TARGET_TYPE_LOGICAL_PORT, mock.ANY)
|
||||||
|
|
||||||
@_mock_create_and_list_nsgroups
|
@_mock_create_and_list_nsgroups
|
||||||
@mock.patch('vmware_nsx.nsxlib.v3.NsxLib.remove_nsgroup_member')
|
@mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.remove_member')
|
||||||
@mock.patch('vmware_nsx.nsxlib.v3.NsxLib.add_nsgroup_members')
|
@mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.add_members')
|
||||||
def test_update_port_remove_security_group_empty_list(self,
|
def test_update_port_remove_security_group_empty_list(self,
|
||||||
add_member_mock,
|
add_member_mock,
|
||||||
remove_member_mock):
|
remove_member_mock):
|
||||||
@ -125,7 +125,7 @@ class TestSecurityGroupsNoDynamicCriteria(test_nsxv3.NsxV3PluginTestCaseMixin,
|
|||||||
NSG_IDS[1], consts.TARGET_TYPE_LOGICAL_PORT, mock.ANY)
|
NSG_IDS[1], consts.TARGET_TYPE_LOGICAL_PORT, mock.ANY)
|
||||||
|
|
||||||
@_mock_create_and_list_nsgroups
|
@_mock_create_and_list_nsgroups
|
||||||
@mock.patch('vmware_nsx.nsxlib.v3.NsxLib.add_nsgroup_members')
|
@mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.add_members')
|
||||||
def test_create_port_with_full_security_group(self, add_member_mock):
|
def test_create_port_with_full_security_group(self, add_member_mock):
|
||||||
|
|
||||||
def _add_member_mock(nsgroup, target_type, target_id):
|
def _add_member_mock(nsgroup, target_type, target_id):
|
||||||
@ -143,8 +143,8 @@ class TestSecurityGroupsNoDynamicCriteria(test_nsxv3.NsxV3PluginTestCaseMixin,
|
|||||||
res_body['NeutronError']['type'])
|
res_body['NeutronError']['type'])
|
||||||
|
|
||||||
@_mock_create_and_list_nsgroups
|
@_mock_create_and_list_nsgroups
|
||||||
@mock.patch('vmware_nsx.nsxlib.v3.NsxLib.remove_nsgroup_member')
|
@mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.remove_member')
|
||||||
@mock.patch('vmware_nsx.nsxlib.v3.NsxLib.add_nsgroup_members')
|
@mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.add_members')
|
||||||
def test_update_port_with_full_security_group(self,
|
def test_update_port_with_full_security_group(self,
|
||||||
add_member_mock,
|
add_member_mock,
|
||||||
remove_member_mock):
|
remove_member_mock):
|
||||||
@ -214,8 +214,8 @@ class TestNSGroupManager(nsxlib_testcase.NsxLibTestCase):
|
|||||||
nested_groups)
|
nested_groups)
|
||||||
|
|
||||||
@_mock_create_and_list_nsgroups
|
@_mock_create_and_list_nsgroups
|
||||||
@mock.patch('vmware_nsx.nsxlib.v3.NsxLib.remove_nsgroup_member')
|
@mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.remove_member')
|
||||||
@mock.patch('vmware_nsx.nsxlib.v3.NsxLib.add_nsgroup_members')
|
@mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.add_members')
|
||||||
def test_add_and_remove_nsgroups(self,
|
def test_add_and_remove_nsgroups(self,
|
||||||
add_member_mock,
|
add_member_mock,
|
||||||
remove_member_mock):
|
remove_member_mock):
|
||||||
@ -239,8 +239,8 @@ class TestNSGroupManager(nsxlib_testcase.NsxLibTestCase):
|
|||||||
verify=True)
|
verify=True)
|
||||||
|
|
||||||
@_mock_create_and_list_nsgroups
|
@_mock_create_and_list_nsgroups
|
||||||
@mock.patch('vmware_nsx.nsxlib.v3.NsxLib.remove_nsgroup_member')
|
@mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.remove_member')
|
||||||
@mock.patch('vmware_nsx.nsxlib.v3.NsxLib.add_nsgroup_members')
|
@mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.add_members')
|
||||||
def test_when_nested_group_is_full(self,
|
def test_when_nested_group_is_full(self,
|
||||||
add_member_mock,
|
add_member_mock,
|
||||||
remove_member_mock):
|
remove_member_mock):
|
||||||
@ -287,8 +287,8 @@ class TestNSGroupManager(nsxlib_testcase.NsxLibTestCase):
|
|||||||
remove_member_mock.assert_has_calls(calls)
|
remove_member_mock.assert_has_calls(calls)
|
||||||
|
|
||||||
@_mock_create_and_list_nsgroups
|
@_mock_create_and_list_nsgroups
|
||||||
@mock.patch('vmware_nsx.nsxlib.v3.NsxLib.remove_nsgroup_member')
|
@mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.remove_member')
|
||||||
@mock.patch('vmware_nsx.nsxlib.v3.NsxLib.add_nsgroup_members')
|
@mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.add_members')
|
||||||
def initialize_with_absent_nested_groups(self,
|
def initialize_with_absent_nested_groups(self,
|
||||||
add_member_mock,
|
add_member_mock,
|
||||||
remove_member_mock):
|
remove_member_mock):
|
||||||
|
@ -107,15 +107,15 @@ def _mock_nsx_backend_calls():
|
|||||||
side_effect=_return_id_key).start()
|
side_effect=_return_id_key).start()
|
||||||
|
|
||||||
mock.patch(
|
mock.patch(
|
||||||
"vmware_nsx.nsxlib.v3.NsxLib.get_bridge_cluster_id_by_name_or_id",
|
"vmware_nsx.nsxlib.v3.NsxLibBridgeCluster.get_id_by_name_or_id",
|
||||||
return_value=uuidutils.generate_uuid()).start()
|
return_value=uuidutils.generate_uuid()).start()
|
||||||
|
|
||||||
mock.patch(
|
mock.patch(
|
||||||
"vmware_nsx.nsxlib.v3.NsxLib.create_bridge_endpoint",
|
"vmware_nsx.nsxlib.v3.NsxLibBridgeEndpoint.create",
|
||||||
side_effect=_return_id_key).start()
|
side_effect=_return_id_key).start()
|
||||||
|
|
||||||
mock.patch(
|
mock.patch(
|
||||||
"vmware_nsx.nsxlib.v3.NsxLib.create_logical_switch",
|
"vmware_nsx.nsxlib.v3.NsxLibLogicalSwitch.create",
|
||||||
side_effect=_return_id_key).start()
|
side_effect=_return_id_key).start()
|
||||||
|
|
||||||
mock.patch(
|
mock.patch(
|
||||||
|
@ -56,27 +56,27 @@ def _mock_nsxlib():
|
|||||||
".validate_connection").start()
|
".validate_connection").start()
|
||||||
|
|
||||||
mock.patch(
|
mock.patch(
|
||||||
"vmware_nsx.nsxlib.v3.NsxLib.create_nsgroup",
|
"vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.create",
|
||||||
side_effect=_return_id_key
|
side_effect=_return_id_key
|
||||||
).start()
|
).start()
|
||||||
|
|
||||||
mock.patch(
|
mock.patch(
|
||||||
"vmware_nsx.nsxlib.v3.NsxLib.create_empty_section",
|
"vmware_nsx.nsxlib.v3.security.NsxLibFirewallSection.create_empty",
|
||||||
side_effect=_return_id_key).start()
|
side_effect=_return_id_key).start()
|
||||||
|
|
||||||
mock.patch(
|
mock.patch(
|
||||||
"vmware_nsx.nsxlib.v3.NsxLib.init_default_section",
|
"vmware_nsx.nsxlib.v3.security.NsxLibFirewallSection.init_default",
|
||||||
side_effect=_return_id_key).start()
|
side_effect=_return_id_key).start()
|
||||||
|
|
||||||
mock.patch(
|
mock.patch(
|
||||||
"vmware_nsx.nsxlib.v3.NsxLib.list_nsgroups").start()
|
"vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.list").start()
|
||||||
|
|
||||||
mock.patch(
|
mock.patch(
|
||||||
"vmware_nsx.nsxlib.v3.NsxLib.add_rules_in_section",
|
"vmware_nsx.nsxlib.v3.security.NsxLibFirewallSection.add_rules",
|
||||||
side_effect=_mock_add_rules_in_section).start()
|
side_effect=_mock_add_rules_in_section).start()
|
||||||
|
|
||||||
mock.patch(
|
mock.patch(
|
||||||
"vmware_nsx.nsxlib.v3.NsxLib.get_transport_zone_id_by_name_or_id",
|
"vmware_nsx.nsxlib.v3.NsxLibTransportZone.get_id_by_name_or_id",
|
||||||
side_effect=_return_id_key).start()
|
side_effect=_return_id_key).start()
|
||||||
|
|
||||||
mock.patch(
|
mock.patch(
|
||||||
|
@ -32,7 +32,8 @@ class NsxLibQosTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||||||
"tags": []
|
"tags": []
|
||||||
}
|
}
|
||||||
if qos_marking:
|
if qos_marking:
|
||||||
body = self.nsxlib._update_dscp_in_args(body, qos_marking, dscp)
|
body = self.nsxlib.qos_switching_profile._update_dscp_in_args(
|
||||||
|
body, qos_marking, dscp)
|
||||||
|
|
||||||
body["display_name"] = test_constants_v3.FAKE_NAME
|
body["display_name"] = test_constants_v3.FAKE_NAME
|
||||||
body["description"] = description
|
body["description"] = description
|
||||||
@ -63,7 +64,7 @@ class NsxLibQosTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||||||
break
|
break
|
||||||
|
|
||||||
if qos_marking:
|
if qos_marking:
|
||||||
body = self.nsxlib._update_dscp_in_args(
|
body = self.nsxlib.qos_switching_profile._update_dscp_in_args(
|
||||||
body, qos_marking, dscp)
|
body, qos_marking, dscp)
|
||||||
|
|
||||||
return body
|
return body
|
||||||
@ -74,7 +75,7 @@ class NsxLibQosTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
with mock.patch.object(self.nsxlib.client, 'create') as create:
|
with mock.patch.object(self.nsxlib.client, 'create') as create:
|
||||||
self.nsxlib.create_qos_switching_profile(
|
self.nsxlib.qos_switching_profile.create(
|
||||||
tags=[],
|
tags=[],
|
||||||
name=test_constants_v3.FAKE_NAME,
|
name=test_constants_v3.FAKE_NAME,
|
||||||
description=test_constants_v3.FAKE_NAME)
|
description=test_constants_v3.FAKE_NAME)
|
||||||
@ -92,7 +93,7 @@ class NsxLibQosTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||||||
with mock.patch.object(self.nsxlib.client, 'update') as update:
|
with mock.patch.object(self.nsxlib.client, 'update') as update:
|
||||||
|
|
||||||
# update the description of the profile
|
# update the description of the profile
|
||||||
self.nsxlib.update_qos_switching_profile(
|
self.nsxlib.qos_switching_profile.update(
|
||||||
test_constants_v3.FAKE_QOS_PROFILE['id'],
|
test_constants_v3.FAKE_QOS_PROFILE['id'],
|
||||||
tags=[],
|
tags=[],
|
||||||
description=new_description)
|
description=new_description)
|
||||||
@ -117,7 +118,7 @@ class NsxLibQosTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||||||
return_value=original_profile):
|
return_value=original_profile):
|
||||||
with mock.patch.object(self.nsxlib.client, 'update') as update:
|
with mock.patch.object(self.nsxlib.client, 'update') as update:
|
||||||
# update the bw shaping of the profile
|
# update the bw shaping of the profile
|
||||||
self.nsxlib.update_qos_switching_profile_shaping(
|
self.nsxlib.qos_switching_profile.update_shaping(
|
||||||
test_constants_v3.FAKE_QOS_PROFILE['id'],
|
test_constants_v3.FAKE_QOS_PROFILE['id'],
|
||||||
shaping_enabled=True,
|
shaping_enabled=True,
|
||||||
burst_size=burst_size,
|
burst_size=burst_size,
|
||||||
@ -155,7 +156,7 @@ class NsxLibQosTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||||||
return_value=original_profile):
|
return_value=original_profile):
|
||||||
with mock.patch.object(self.nsxlib.client, 'update') as update:
|
with mock.patch.object(self.nsxlib.client, 'update') as update:
|
||||||
# update the bw shaping of the profile
|
# update the bw shaping of the profile
|
||||||
self.nsxlib.update_qos_switching_profile_shaping(
|
self.nsxlib.qos_switching_profile.update_shaping(
|
||||||
test_constants_v3.FAKE_QOS_PROFILE['id'],
|
test_constants_v3.FAKE_QOS_PROFILE['id'],
|
||||||
shaping_enabled=False, qos_marking="trusted")
|
shaping_enabled=False, qos_marking="trusted")
|
||||||
|
|
||||||
@ -169,7 +170,7 @@ class NsxLibQosTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||||||
Test deleting qos-switching-profile
|
Test deleting qos-switching-profile
|
||||||
"""
|
"""
|
||||||
with mock.patch.object(self.nsxlib.client, 'delete') as delete:
|
with mock.patch.object(self.nsxlib.client, 'delete') as delete:
|
||||||
self.nsxlib.delete_qos_switching_profile(
|
self.nsxlib.qos_switching_profile.delete(
|
||||||
test_constants_v3.FAKE_QOS_PROFILE['id'])
|
test_constants_v3.FAKE_QOS_PROFILE['id'])
|
||||||
delete.assert_called_with(
|
delete.assert_called_with(
|
||||||
'switching-profiles/%s'
|
'switching-profiles/%s'
|
||||||
|
@ -47,7 +47,7 @@ class NsxLibSwitchTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
with mock.patch.object(self.nsxlib.client, 'create') as create:
|
with mock.patch.object(self.nsxlib.client, 'create') as create:
|
||||||
self.nsxlib.create_logical_switch(
|
self.nsxlib.logical_switch.create(
|
||||||
nsx_v3_mocks.FAKE_NAME, NsxLibSwitchTestCase._tz_id, [])
|
nsx_v3_mocks.FAKE_NAME, NsxLibSwitchTestCase._tz_id, [])
|
||||||
create.assert_called_with('logical-switches', self._create_body())
|
create.assert_called_with('logical-switches', self._create_body())
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ class NsxLibSwitchTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
with mock.patch.object(self.nsxlib.client, 'create') as create:
|
with mock.patch.object(self.nsxlib.client, 'create') as create:
|
||||||
self.nsxlib.create_logical_switch(
|
self.nsxlib.logical_switch.create(
|
||||||
nsx_v3_mocks.FAKE_NAME, NsxLibSwitchTestCase._tz_id,
|
nsx_v3_mocks.FAKE_NAME, NsxLibSwitchTestCase._tz_id,
|
||||||
[], admin_state=False)
|
[], admin_state=False)
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ class NsxLibSwitchTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
with mock.patch.object(self.nsxlib.client, 'create') as create:
|
with mock.patch.object(self.nsxlib.client, 'create') as create:
|
||||||
self.nsxlib.create_logical_switch(
|
self.nsxlib.logical_switch.create(
|
||||||
nsx_v3_mocks.FAKE_NAME, NsxLibSwitchTestCase._tz_id,
|
nsx_v3_mocks.FAKE_NAME, NsxLibSwitchTestCase._tz_id,
|
||||||
[], vlan_id='123')
|
[], vlan_id='123')
|
||||||
|
|
||||||
@ -87,7 +87,7 @@ class NsxLibSwitchTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||||||
|
|
||||||
with mock.patch.object(self.nsxlib.client, 'delete') as delete:
|
with mock.patch.object(self.nsxlib.client, 'delete') as delete:
|
||||||
fake_switch = nsx_v3_mocks.make_fake_switch()
|
fake_switch = nsx_v3_mocks.make_fake_switch()
|
||||||
self.nsxlib.delete_logical_switch(fake_switch['id'])
|
self.nsxlib.logical_switch.delete(fake_switch['id'])
|
||||||
delete.assert_called_with(
|
delete.assert_called_with(
|
||||||
'logical-switches/%s'
|
'logical-switches/%s'
|
||||||
'?detach=true&cascade=true' % fake_switch['id'])
|
'?detach=true&cascade=true' % fake_switch['id'])
|
||||||
|
@ -86,7 +86,7 @@ class TestNsxV3L2GatewayDriver(test_l2gw_db.L2GWTestCase,
|
|||||||
mock.MagicMock())
|
mock.MagicMock())
|
||||||
l2gws = self.driver._get_l2_gateways(self.context)
|
l2gws = self.driver._get_l2_gateways(self.context)
|
||||||
def_bridge_cluster_id = (
|
def_bridge_cluster_id = (
|
||||||
self.nsxlib.get_bridge_cluster_id_by_name_or_id(
|
self.nsxlib.bridge_cluster.get_id_by_name_or_id(
|
||||||
def_bridge_cluster_name))
|
def_bridge_cluster_name))
|
||||||
def_l2gw = None
|
def_l2gw = None
|
||||||
for l2gw in l2gws:
|
for l2gw in l2gws:
|
||||||
|
@ -92,7 +92,7 @@ class TestQosNsxV3Notification(base.BaseQosTestCase,
|
|||||||
def test_policy_create_profile(self, fake_db_add, fake_rbac_create):
|
def test_policy_create_profile(self, fake_db_add, fake_rbac_create):
|
||||||
# test the switch profile creation when a QoS policy is created
|
# test the switch profile creation when a QoS policy is created
|
||||||
with mock.patch(
|
with mock.patch(
|
||||||
'vmware_nsx.nsxlib.v3.NsxLib.create_qos_switching_profile',
|
'vmware_nsx.nsxlib.v3.NsxLibQosSwitchingProfile.create',
|
||||||
return_value=self.fake_profile
|
return_value=self.fake_profile
|
||||||
) as create_profile:
|
) as create_profile:
|
||||||
with mock.patch('neutron.objects.qos.policy.QosPolicy.get_object',
|
with mock.patch('neutron.objects.qos.policy.QosPolicy.get_object',
|
||||||
@ -120,7 +120,7 @@ class TestQosNsxV3Notification(base.BaseQosTestCase,
|
|||||||
fields = base_object.get_updatable_fields(
|
fields = base_object.get_updatable_fields(
|
||||||
policy_object.QosPolicy, self.policy_data['policy'])
|
policy_object.QosPolicy, self.policy_data['policy'])
|
||||||
with mock.patch(
|
with mock.patch(
|
||||||
'vmware_nsx.nsxlib.v3.NsxLib.update_qos_switching_profile'
|
'vmware_nsx.nsxlib.v3.NsxLibQosSwitchingProfile.update'
|
||||||
) as update_profile:
|
) as update_profile:
|
||||||
with mock.patch('neutron.objects.qos.policy.QosPolicy.get_object',
|
with mock.patch('neutron.objects.qos.policy.QosPolicy.get_object',
|
||||||
return_value=self.policy):
|
return_value=self.policy):
|
||||||
@ -151,8 +151,7 @@ class TestQosNsxV3Notification(base.BaseQosTestCase,
|
|||||||
with mock.patch('neutron.objects.qos.policy.QosPolicy.get_object',
|
with mock.patch('neutron.objects.qos.policy.QosPolicy.get_object',
|
||||||
return_value=_policy):
|
return_value=_policy):
|
||||||
with mock.patch(
|
with mock.patch(
|
||||||
'vmware_nsx.nsxlib.v3.NsxLib.'
|
'vmware_nsx.nsxlib.v3.NsxLibQosSwitchingProfile.update_shaping'
|
||||||
'update_qos_switching_profile_shaping'
|
|
||||||
) as update_profile:
|
) as update_profile:
|
||||||
with mock.patch('neutron.objects.db.api.update_object',
|
with mock.patch('neutron.objects.db.api.update_object',
|
||||||
return_value=self.rule_data):
|
return_value=self.rule_data):
|
||||||
@ -194,8 +193,7 @@ class TestQosNsxV3Notification(base.BaseQosTestCase,
|
|||||||
with mock.patch('neutron.objects.qos.policy.QosPolicy.get_object',
|
with mock.patch('neutron.objects.qos.policy.QosPolicy.get_object',
|
||||||
return_value=_policy):
|
return_value=_policy):
|
||||||
with mock.patch(
|
with mock.patch(
|
||||||
'vmware_nsx.nsxlib.v3.NsxLib.'
|
'vmware_nsx.nsxlib.v3.NsxLibQosSwitchingProfile.update_shaping'
|
||||||
'update_qos_switching_profile_shaping'
|
|
||||||
) as update_profile:
|
) as update_profile:
|
||||||
with mock.patch('neutron.objects.db.api.update_object',
|
with mock.patch('neutron.objects.db.api.update_object',
|
||||||
return_value=rule_data):
|
return_value=rule_data):
|
||||||
@ -227,8 +225,7 @@ class TestQosNsxV3Notification(base.BaseQosTestCase,
|
|||||||
with mock.patch('neutron.objects.qos.policy.QosPolicy.get_object',
|
with mock.patch('neutron.objects.qos.policy.QosPolicy.get_object',
|
||||||
return_value=_policy):
|
return_value=_policy):
|
||||||
with mock.patch(
|
with mock.patch(
|
||||||
'vmware_nsx.nsxlib.v3.NsxLib.'
|
'vmware_nsx.nsxlib.v3.NsxLibQosSwitchingProfile.update_shaping'
|
||||||
'update_qos_switching_profile_shaping'
|
|
||||||
) as update_profile:
|
) as update_profile:
|
||||||
with mock.patch('neutron.objects.db.api.'
|
with mock.patch('neutron.objects.db.api.'
|
||||||
'update_object', return_value=self.dscp_rule_data):
|
'update_object', return_value=self.dscp_rule_data):
|
||||||
@ -260,8 +257,7 @@ class TestQosNsxV3Notification(base.BaseQosTestCase,
|
|||||||
with mock.patch('neutron.objects.qos.policy.QosPolicy.get_object',
|
with mock.patch('neutron.objects.qos.policy.QosPolicy.get_object',
|
||||||
return_value=_policy):
|
return_value=_policy):
|
||||||
with mock.patch(
|
with mock.patch(
|
||||||
"vmware_nsx.nsxlib.v3.NsxLib."
|
"vmware_nsx.nsxlib.v3.NsxLibQosSwitchingProfile.update_shaping"
|
||||||
"update_qos_switching_profile_shaping"
|
|
||||||
) as update_profile:
|
) as update_profile:
|
||||||
setattr(_policy, "rules", [self.rule])
|
setattr(_policy, "rules", [self.rule])
|
||||||
self.qos_plugin.delete_policy_bandwidth_limit_rule(
|
self.qos_plugin.delete_policy_bandwidth_limit_rule(
|
||||||
@ -281,7 +277,7 @@ class TestQosNsxV3Notification(base.BaseQosTestCase,
|
|||||||
def test_policy_delete_profile(self, *mocks):
|
def test_policy_delete_profile(self, *mocks):
|
||||||
# test the switch profile deletion when a QoS policy is deleted
|
# test the switch profile deletion when a QoS policy is deleted
|
||||||
with mock.patch(
|
with mock.patch(
|
||||||
'vmware_nsx.nsxlib.v3.NsxLib.delete_qos_switching_profile',
|
'vmware_nsx.nsxlib.v3.NsxLibQosSwitchingProfile.delete',
|
||||||
return_value=self.fake_profile
|
return_value=self.fake_profile
|
||||||
) as delete_profile:
|
) as delete_profile:
|
||||||
self.qos_plugin.delete_policy(self.ctxt, self.policy.id)
|
self.qos_plugin.delete_policy(self.ctxt, self.policy.id)
|
||||||
|
Loading…
Reference in New Issue
Block a user