From 701de5c48ffcfb6045f1bc20f63e50da61c7e461 Mon Sep 17 00:00:00 2001 From: Adit Sarfaty Date: Mon, 19 Sep 2016 13:10:41 +0300 Subject: [PATCH] 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 --- vmware_nsx/nsxlib/v3/__init__.py | 426 +++++++++--------- vmware_nsx/nsxlib/v3/ns_group_manager.py | 13 +- vmware_nsx/nsxlib/v3/router.py | 61 +-- vmware_nsx/nsxlib/v3/security.py | 410 +++++++++-------- vmware_nsx/nsxlib/v3/utils.py | 46 ++ vmware_nsx/plugins/nsx_v3/plugin.py | 54 +-- .../services/l2gateway/nsx_v3/driver.py | 10 +- .../services/neutron_taas/nsx_v3/driver.py | 7 +- vmware_nsx/services/qos/nsx_v3/utils.py | 12 +- .../admin/plugins/nsxv3/resources/networks.py | 2 +- .../plugins/nsxv3/resources/securitygroups.py | 24 +- .../test_secgroup_rule_local_ip_prefix.py | 2 +- .../unit/extensions/test_securitygroup.py | 34 +- vmware_nsx/tests/unit/nsx_v3/test_plugin.py | 6 +- .../tests/unit/nsxlib/v3/nsxlib_testcase.py | 12 +- .../nsxlib/v3/test_qos_switching_profile.py | 15 +- .../tests/unit/nsxlib/v3/test_switch.py | 8 +- .../services/l2gateway/test_nsxv3_driver.py | 2 +- .../services/qos/test_nsxv3_notification.py | 18 +- 19 files changed, 633 insertions(+), 529 deletions(-) diff --git a/vmware_nsx/nsxlib/v3/__init__.py b/vmware_nsx/nsxlib/v3/__init__.py index cdabe49be9..bda2fd1490 100644 --- a/vmware_nsx/nsxlib/v3/__init__.py +++ b/vmware_nsx/nsxlib/v3/__init__.py @@ -26,7 +26,7 @@ from vmware_nsx.nsxlib.v3 import utils LOG = log.getLogger(__name__) -class NsxLib(security.Security): +class NsxLib(object): def __init__(self, username=None, @@ -61,6 +61,28 @@ class NsxLib(security.Security): self.cluster, 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__() def get_version(self): @@ -68,53 +90,76 @@ class NsxLib(security.Security): version = node.get('node_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): - #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) +class NsxLibPortMirror(utils.NsxLibApiBase): - 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, - skip_not_found=True, **kwargs): - resources_get = self.client.get(resource) - matched_num = 0 - for res in resources_get['results']: - if utils.dict_match(kwargs, res): - LOG.debug("Deleting %s from resource %s", res, resource) - delete_resource = resource + "/" + str(res['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}) + :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. + """ - def create_logical_switch(self, display_name, transport_zone_id, tags, - replication_mode=nsx_constants.MTEP, - admin_state=True, vlan_id=None): + 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, + admin_state=True, vlan_id=None): # TODO(salv-orlando): Validate Replication mode and admin_state # NOTE: These checks might be moved to the API client library if one # that performs such checks in the client is available @@ -135,7 +180,7 @@ class NsxLib(security.Security): 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 @utils.retry_upon_exception(exceptions.StaleRevision, max_attempts=self.max_attempts) @@ -146,18 +191,17 @@ class NsxLib(security.Security): _do_delete() - def get_logical_switch(self, logical_switch_id): + def get(self, logical_switch_id): resource = "logical-switches/%s" % logical_switch_id return self.client.get(resource) - def update_logical_switch(self, lswitch_id, name=None, admin_state=None, - tags=None): + def update(self, lswitch_id, name=None, admin_state=None, tags=None): #Using internal method so we can access max_attempts in the decorator @utils.retry_upon_exception(exceptions.StaleRevision, max_attempts=self.max_attempts) def _do_update(): resource = "logical-switches/%s" % lswitch_id - lswitch = self.get_logical_switch(lswitch_id) + lswitch = self.get(lswitch_id) if name is not None: lswitch['display_name'] = name if admin_state is not None: @@ -171,70 +215,16 @@ class NsxLib(security.Security): 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): - 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) +class NsxLibQosSwitchingProfile(utils.NsxLibApiBase): - def delete_static_route(self, logical_router_id, static_route_id): - 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): + def _build_args(self, tags, name=None, description=None): body = {"resource_type": "QosSwitchingProfile", "tags": tags} - return self._update_qos_switching_profile_args( + return self._update_args( body, name=name, description=description) - def _update_qos_switching_profile_args(self, body, name=None, - description=None): + def _update_args(self, body, name=None, description=None): if name: body["display_name"] = name if description: @@ -277,32 +267,28 @@ class NsxLib(security.Security): return body - def create_qos_switching_profile(self, tags, name=None, - description=None): + def create(self, tags, name=None, description=None): resource = 'switching-profiles' - body = self._build_qos_switching_profile_args(tags, name, - description) + body = self._build_args(tags, name, description) return self.client.create(resource, body) - def update_qos_switching_profile(self, profile_id, tags, name=None, - description=None): + def update(self, profile_id, tags, name=None, description=None): resource = 'switching-profiles/%s' % profile_id # get the current configuration - body = self.get_qos_switching_profile(profile_id) + body = self.get(profile_id) # update the relevant fields - body = self._update_qos_switching_profile_args(body, name, - description) - return self.update_resource_with_retry(resource, body) + body = self._update_args(body, name, description) + return self._update_resource_with_retry(resource, body) - def update_qos_switching_profile_shaping(self, profile_id, - shaping_enabled=False, - burst_size=None, - peak_bandwidth=None, - average_bandwidth=None, - qos_marking=None, dscp=None): + def update_shaping(self, profile_id, + shaping_enabled=False, + burst_size=None, + peak_bandwidth=None, + average_bandwidth=None, + qos_marking=None, dscp=None): resource = 'switching-profiles/%s' % profile_id # get the current configuration - body = self.get_qos_switching_profile(profile_id) + body = self.get(profile_id) # update the relevant fields if shaping_enabled: body = self._enable_shaping_in_args( @@ -312,77 +298,103 @@ class NsxLib(security.Security): else: body = self._disable_shaping_in_args(body) 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 return self.client.get(resource) - def delete_qos_switching_profile(self, profile_id): + def delete(self, profile_id): resource = 'switching-profiles/%s' % profile_id 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 - 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} +class NsxLibLogicalRouter(utils.NsxLibApiBase): + + def _delete_resource_by_values(self, resource, + skip_not_found=True, **kwargs): + resources_get = self.client.get(resource) + matched_num = 0 + for res in resources_get['results']: + if utils.dict_match(kwargs, res): + LOG.debug("Deleting %s from resource %s", res, resource) + delete_resource = resource + "/" + str(res['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) - def delete_bridge_endpoint(self, bridge_endpoint_id): - """Delete a bridge endpoint on the backend. + def add_static_route(self, logical_router_id, dest_cidr, nexthop): + 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 - endpoint to be deleted. - """ - resource = 'bridge-endpoints/%s' % bridge_endpoint_id + def delete_static_route(self, logical_router_id, static_route_id): + resource = 'logical-routers/%s/routing/static-routes/%s' % ( + logical_router_id, static_route_id) self.client.delete(resource) - 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 + 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) - if rs.get('display_name') == name_or_id: - # Matched by name - add to the list to verify it is unique - matched_results.append(rs) + 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) - if len(matched_results) == 0: - err_msg = (_("Could not find %(resource)s %(name)s") % - {'name': name_or_id, 'resource': resource}) - # 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) + 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) - 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): - """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): + def get_id_by_name_or_id(self, name_or_id): """Get a logical router by it's display name or uuid 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, '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 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, '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) diff --git a/vmware_nsx/nsxlib/v3/ns_group_manager.py b/vmware_nsx/nsxlib/v3/ns_group_manager.py index 39c90260ef..9f416f3275 100644 --- a/vmware_nsx/nsxlib/v3/ns_group_manager.py +++ b/vmware_nsx/nsxlib/v3/ns_group_manager.py @@ -50,7 +50,7 @@ class NSGroupManager(object): NESTED_GROUP_DESCRIPTION = ('OpenStack NSGroup. Do not delete.') def __init__(self, nsxlib, size): - self.nsx = nsxlib + self.nsxlib_nsgroup = nsxlib.ns_group self._nested_groups = self._init_nested_groups(size) self._size = len(self._nested_groups) @@ -68,7 +68,7 @@ class NSGroupManager(object): size = requested_size nested_groups = { 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 nested_groups: @@ -101,7 +101,7 @@ class NSGroupManager(object): name = '%s %s' % (name_prefix, index + 1) description = NSGroupManager.NESTED_GROUP_DESCRIPTION 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): return hash(uuid.UUID(internal_id)) @@ -122,9 +122,8 @@ class NSGroupManager(object): try: LOG.debug("Adding NSGroup %s to nested group %s", nsgroup_id, group) - self.nsx.add_nsgroup_members(group, - consts.NSGROUP, - [nsgroup_id]) + self.nsxlib_nsgroup.add_members( + group, consts.NSGROUP, [nsgroup_id]) break except exceptions.NSGroupIsFull: LOG.debug("Nested group %(group_id)s is full, trying the " @@ -137,7 +136,7 @@ class NSGroupManager(object): def remove_nsgroup(self, nsgroup_id): for group in self._suggest_nested_group(nsgroup_id): try: - self.nsx.remove_nsgroup_member( + self.nsxlib_nsgroup.remove_member( group, consts.NSGROUP, nsgroup_id, verify=True) break diff --git a/vmware_nsx/nsxlib/v3/router.py b/vmware_nsx/nsxlib/v3/router.py index d77ee021b8..b4f5edc2e5 100644 --- a/vmware_nsx/nsxlib/v3/router.py +++ b/vmware_nsx/nsxlib/v3/router.py @@ -60,7 +60,7 @@ class RouterLib(object): err_msg = _("Failed to get edge cluster uuid from tier0 " "router %s at the backend") % lrouter 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'] for member in edge_cluster['members']] if len(member_index_list) < MIN_EDGE_NODE_NUM: @@ -116,7 +116,7 @@ class RouterLib(object): advertise_route_connected, advertise_route_static=False, enabled=True): - return self.nsxlib.update_logical_router_advertisement( + return self.nsxlib.logical_router.update_advertisement( logical_router_id, advertise_nat_routes=advertise_route_nat, advertise_nsx_connected_routes=advertise_route_connected, @@ -124,13 +124,15 @@ class RouterLib(object): enabled=enabled) def delete_gw_snat_rule(self, logical_router_id, gw_ip): - return self.nsxlib.delete_nat_rule_by_values(logical_router_id, - translated_network=gw_ip) + return self.nsxlib.logical_router.delete_nat_rule_by_values( + logical_router_id, + translated_network=gw_ip) def add_gw_snat_rule(self, logical_router_id, gw_ip): - return self.nsxlib.add_nat_rule(logical_router_id, action="SNAT", - translated_network=gw_ip, - rule_priority=GW_NAT_PRI) + return self.nsxlib.logical_router.add_nat_rule( + logical_router_id, action="SNAT", + translated_network=gw_ip, + rule_priority=GW_NAT_PRI) def update_router_edge_cluster(self, nsx_router_id, edge_cluster_uuid): return self._router_client.update(nsx_router_id, @@ -157,31 +159,36 @@ class RouterLib(object): port['id'], subnets=address_groups) def add_fip_nat_rules(self, logical_router_id, ext_ip, int_ip): - self.nsxlib.add_nat_rule(logical_router_id, action="SNAT", - translated_network=ext_ip, - source_net=int_ip, - rule_priority=FIP_NAT_PRI) - self.nsxlib.add_nat_rule(logical_router_id, action="DNAT", - translated_network=int_ip, - dest_net=ext_ip, - rule_priority=FIP_NAT_PRI) + self.nsxlib.logical_router.add_nat_rule( + logical_router_id, action="SNAT", + translated_network=ext_ip, + source_net=int_ip, + rule_priority=FIP_NAT_PRI) + self.nsxlib.logical_router.add_nat_rule( + logical_router_id, action="DNAT", + translated_network=int_ip, + dest_net=ext_ip, + rule_priority=FIP_NAT_PRI) def delete_fip_nat_rules(self, logical_router_id, ext_ip, int_ip): - self.nsxlib.delete_nat_rule_by_values(logical_router_id, - action="SNAT", - translated_network=ext_ip, - match_source_network=int_ip) - self.nsxlib.delete_nat_rule_by_values(logical_router_id, - action="DNAT", - translated_network=int_ip, - match_destination_network=ext_ip) + self.nsxlib.logical_router.delete_nat_rule_by_values( + logical_router_id, + action="SNAT", + translated_network=ext_ip, + match_source_network=int_ip) + self.nsxlib.logical_router.delete_nat_rule_by_values( + logical_router_id, + action="DNAT", + translated_network=int_ip, + match_destination_network=ext_ip) def add_static_routes(self, nsx_router_id, route): - return self.nsxlib.add_static_route(nsx_router_id, - route['destination'], - route['nexthop']) + return self.nsxlib.logical_router.add_static_route( + nsx_router_id, + route['destination'], + route['nexthop']) 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'], nexthop=route['nexthop']) diff --git a/vmware_nsx/nsxlib/v3/security.py b/vmware_nsx/nsxlib/v3/security.py index cfbf0fb6c0..c54fd2f2e6 100644 --- a/vmware_nsx/nsxlib/v3/security.py +++ b/vmware_nsx/nsxlib/v3/security.py @@ -15,7 +15,7 @@ # under the License. """ -NSX-V3 Plugin security integration & Distributed Firewall module +NSX-V3 Plugin security & Distributed Firewall integration module """ from neutron_lib import constants @@ -35,151 +35,31 @@ PORT_SG_SCOPE = 'os-security-group' MAX_NSGROUPS_CRITERIA_TAGS = 10 -class Security(object): +class NsxLibNsGroup(utils.NsxLibApiBase): - 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 __init__(self, client, max_attempts, firewall_section_handler): + self.firewall_section = firewall_section_handler + super(NsxLibNsGroup, self).__init__(client, max_attempts) - def _get_direction(self, sg_rule): - 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, - log_sg_allowed_traffic): - name = self.get_nsgroup_name(security_group) + def update_on_backend(self, context, security_group, + nsgroup_id, section_id, + log_sg_allowed_traffic): + name = self.get_name(security_group) description = security_group['description'] logging = (log_sg_allowed_traffic or 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) - self.update_nsgroup(nsgroup_id, name, description) - self.update_section(section_id, name, description, rules=rules) + self.update(nsgroup_id, name, description) + 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, # for usability purposes. 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: raise exceptions.NumberOfNsgroupCriteriaTagsReached( max_num=MAX_NSGROUPS_CRITERIA_TAGS) @@ -191,20 +71,19 @@ class Security(object): tags = [{'scope': PORT_SG_SCOPE, 'tag': None}] return tags - def update_lport_with_security_groups(self, context, lport_id, - original, updated): + def update_lport(self, context, lport_id, original, updated): added = set(updated) - set(original) removed = set(original) - set(updated) for nsgroup_id in added: try: - self.add_nsgroup_members( + self.add_members( nsgroup_id, consts.TARGET_TYPE_LOGICAL_PORT, [lport_id]) except exceptions.NSGroupIsFull: for nsgroup_id in added: # NOTE(roeyc): If the port was not added to the nsgroup # yet, then this request will silently fail. - self.remove_nsgroup_member( + self.remove_member( nsgroup_id, consts.TARGET_TYPE_LOGICAL_PORT, lport_id) raise exceptions.SecurityGroupMaximumCapacityReached( @@ -213,7 +92,7 @@ class Security(object): with excutils.save_and_reraise_exception(): LOG.error(_LE("NSGroup %s doesn't exists"), nsgroup_id) for nsgroup_id in removed: - self.remove_nsgroup_member( + self.remove_member( nsgroup_id, consts.TARGET_TYPE_LOGICAL_PORT, lport_id) def init_default_section(self, name, description, nested_groups, @@ -264,15 +143,14 @@ class Security(object): service.update(properties) return {'service': service} - def get_nsgroup_port_tag_expression(self, scope, tag): - return { - 'resource_type': consts.NSGROUP_TAG_EXP, - 'target_type': consts.TARGET_TYPE_LOGICAL_PORT, - 'scope': scope, - 'tag': tag} + def get_port_tag_expression(self, scope, tag): + return {'resource_type': consts.NSGROUP_TAG_EXP, + 'target_type': consts.TARGET_TYPE_LOGICAL_PORT, + 'scope': scope, + 'tag': tag} - def create_nsgroup(self, display_name, description, tags, - membership_criteria=None): + def create(self, display_name, description, tags, + membership_criteria=None): body = {'display_name': display_name, 'description': description, 'tags': tags, @@ -281,18 +159,18 @@ class Security(object): body.update({'membership_criteria': [membership_criteria]}) return self.client.create('ns-groups', body) - def list_nsgroups(self): + def list(self): return self.client.get( 'ns-groups?populate_references=false').get('results', []) - def update_nsgroup(self, nsgroup_id, display_name=None, description=None, - membership_criteria=None, members=None): + def update(self, nsgroup_id, display_name=None, description=None, + membership_criteria=None, members=None): #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(): - nsgroup = self.read_nsgroup(nsgroup_id) + nsgroup = self.read(nsgroup_id) if display_name is not None: nsgroup['display_name'] = display_name if description is not None: @@ -306,7 +184,7 @@ class Security(object): return _do_update() - def get_nsgroup_member_expression(self, target_type, target_id): + def get_member_expression(self, target_type, target_id): return { 'resource_type': consts.NSGROUP_SIMPLE_EXP, 'target_property': 'id', @@ -314,7 +192,7 @@ class Security(object): 'op': consts.EQUALS, '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 @utils.retry_upon_exception( exceptions.StaleRevision, @@ -325,15 +203,15 @@ class Security(object): 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 = [] for target_id in target_ids: - member_expr = self.get_nsgroup_member_expression( + member_expr = self.get_member_expression( target_type, target_id) members.append(member_expr) members = {'members': members} try: - return self._update_nsgroup_with_members( + return self._update_with_members( nsgroup_id, members, consts.NSGROUP_ADD_MEMBERS) except (exceptions.StaleRevision, exceptions.ResourceNotFound): raise @@ -348,24 +226,24 @@ class Security(object): raise exceptions.NSGroupIsFull(nsgroup_id=nsgroup_id) - def remove_nsgroup_member(self, nsgroup_id, target_type, - target_id, verify=False): - member_expr = self.get_nsgroup_member_expression( + def remove_member(self, nsgroup_id, target_type, + target_id, verify=False): + member_expr = self.get_member_expression( target_type, target_id) members = {'members': [member_expr]} try: - return self._update_nsgroup_with_members( + return self._update_with_members( nsgroup_id, members, consts.NSGROUP_REMOVE_MEMBERS) except exceptions.ManagerError: if verify: raise exceptions.NSGroupMemberNotFound(member_id=target_id, nsgroup_id=nsgroup_id) - def read_nsgroup(self, nsgroup_id): + def read(self, nsgroup_id): return self.client.get( 'ns-groups/%s?populate_references=true' % nsgroup_id) - def delete_nsgroup(self, nsgroup_id): + def delete(self, nsgroup_id): try: return self.client.delete( 'ns-groups/%s?force=true' % nsgroup_id) @@ -374,7 +252,72 @@ class Security(object): LOG.debug("NSGroup %s does not exists for delete request.", 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, 'description': description, 'stateful': True, @@ -383,26 +326,26 @@ class Security(object): for t_id in applied_tos], 'tags': tags} - def create_empty_section(self, display_name, description, - applied_tos, tags, - operation=consts.FW_INSERT_BOTTOM, - other_section=None): + def create_empty(self, display_name, description, + applied_tos, tags, + operation=consts.FW_INSERT_BOTTOM, + other_section=None): resource = 'firewall/sections?operation=%s' % operation - body = self._build_section(display_name, description, - applied_tos, tags) + body = self._build(display_name, description, + applied_tos, tags) if other_section: resource += '&id=%s' % other_section return self.client.create(resource, body) - def update_section(self, section_id, display_name=None, description=None, - applied_tos=None, rules=None): + def update(self, section_id, display_name=None, description=None, + applied_tos=None, rules=None): #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(): resource = 'firewall/sections/%s' % section_id - section = self.read_section(section_id) + section = self.read(section_id) if rules is not None: resource += '?action=update_with_rules' @@ -422,15 +365,15 @@ class Security(object): return _do_update() - def read_section(self, section_id): + def read(self, section_id): resource = 'firewall/sections/%s' % section_id return self.client.get(resource) - def list_sections(self): + def list(self): resource = 'firewall/sections' 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 return self.client.delete(resource) @@ -445,7 +388,7 @@ class Security(object): return {'target_id': ip_cidr_block, 'target_type': target_type} - def get_firewall_rule_dict( + def get_rule_dict( self, display_name, source=None, destination=None, direction=consts.IN_OUT, @@ -461,12 +404,12 @@ class Security(object): 'action': action, '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 params = '?operation=insert_bottom' 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 params = '?action=create_multiple&operation=insert_bottom' 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) 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 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'] diff --git a/vmware_nsx/nsxlib/v3/utils.py b/vmware_nsx/nsxlib/v3/utils.py index 6433af0aa5..81139ca290 100644 --- a/vmware_nsx/nsxlib/v3/utils.py +++ b/vmware_nsx/nsxlib/v3/utils.py @@ -20,6 +20,7 @@ from neutron_lib import exceptions from oslo_log import log from vmware_nsx._i18n import _ +from vmware_nsx.nsxlib.v3 import exceptions as nsxlib_exceptions 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 else: 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') diff --git a/vmware_nsx/plugins/nsx_v3/plugin.py b/vmware_nsx/plugins/nsx_v3/plugin.py index fb80d62619..5277e8c1c9 100644 --- a/vmware_nsx/plugins/nsx_v3/plugin.py +++ b/vmware_nsx/plugins/nsx_v3/plugin.py @@ -256,21 +256,21 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, # default VLAN transport zone name / uuid self._default_vlan_tz_uuid = None 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) self._default_vlan_tz_uuid = tz_id # default overlay transport zone name / uuid self._default_overlay_tz_uuid = None 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) self._default_overlay_tz_uuid = tz_id # default tier0 router self._default_tier0_router = None 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) self._default_tier0_router = rtr_id @@ -393,7 +393,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, nsgroup_id, section_id = nsx_db.get_sg_mappings( context.session, sg['id']) try: - self.nsxlib.set_firewall_rule_logging_for_section( + self.nsxlib.firewall_section.set_rule_logging( section_id, logging=log_all_rules) except nsx_lib_exc.ManagerError: 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) section_description = ("This section is handled by OpenStack to " "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, nsgroup_manager.nested_groups.values(), cfg.CONF.nsx_v3.log_security_groups_blocked_traffic) @@ -610,7 +610,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, 'tags': tags, 'admin_state': admin_state, 'vlan_id': vlan_id}) - nsx_result = self.nsxlib.create_logical_switch( + nsx_result = self.nsxlib.logical_switch.create( net_name, physical_net, tags, admin_state=admin_state, vlan_id=vlan_id) @@ -728,7 +728,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, LOG.exception(_LE('Failed to create network %s'), created_net['id']) 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 # latest db model for the extension functions @@ -810,7 +810,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, # TODO(salv-orlando): Handle backend failure, possibly without # requiring us to un-delete the DB object. For instance, ignore # 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: # TODO(berlin): delete subnets public announce on the network pass @@ -850,7 +850,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, try: # get the nsx switch id from the DB mapping nsx_id = self._get_network_nsx_id(context, id) - self.nsxlib.update_logical_switch( + self.nsxlib.logical_switch.update( nsx_id, name=utils.get_name_and_uuid(net_data['name'] or 'network', id), @@ -1232,7 +1232,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, def _get_qos_profile_id(self, context, policy_id): switch_profile_id = nsx_db.get_switch_profile_by_qos_policy( 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: profile_ids = self._switching_profiles.build_switch_profile_ids( 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 # security criteria tag. 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[provider_sg.PROVIDER_SECURITYGROUPS]) @@ -1627,7 +1627,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, original) nsx_updated = nsx_db.get_nsx_security_group_ids(context.session, updated) - self.nsxlib.update_lport_with_security_groups( + self.nsxlib.ns_group.update_lport( context, lport_id, nsx_origial, nsx_updated) 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) 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(provider_sg.PROVIDER_SECURITYGROUPS, [])) else: @@ -2791,7 +2791,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, # security-group rules are located in a dedicated firewall section. firewall_section = ( - self.nsxlib.create_empty_section( + self.nsxlib.firewall_section.create_empty( nsgroup.get('display_name'), nsgroup.get('description'), [nsgroup.get('id')], nsgroup.get('tags'), operation=operation, @@ -2802,16 +2802,16 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, tags = nsxlib_utils.build_v3_tags_payload( secgroup, resource_type='os-neutron-secgr-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): tag_expression = ( - self.nsxlib.get_nsgroup_port_tag_expression( + self.nsxlib.ns_group.get_port_tag_expression( security.PORT_SG_SCOPE, secgroup['id'])) else: tag_expression = None - ns_group = self.nsxlib.create_nsgroup( + ns_group = self.nsxlib.ns_group.create( name, secgroup['description'], tags, tag_expression) # security-group rules are located in a dedicated firewall section. firewall_section = self._create_fw_section_for_secgroup( @@ -2834,7 +2834,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, context.session, remote_group_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, logging_enabled, action, sg_rules, ruleid_2_remote_nsgroup_map) @@ -2880,7 +2880,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, LOG.exception(_LE("Unable to create security-group on the " "backend.")) if ns_group: - self.nsxlib.delete_nsgroup(ns_group['id']) + self.nsxlib.ns_group.delete(ns_group['id']) except Exception: with excutils.save_and_reraise_exception(): section_id = firewall_section.get('id') @@ -2890,9 +2890,9 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, "section %s, ns-group %s.", section_id, nsgroup_id) if nsgroup_id: - self.nsxlib.delete_nsgroup(nsgroup_id) + self.nsxlib.ns_group.delete(nsgroup_id) if section_id: - self.nsxlib.delete_section(section_id) + self.nsxlib.firewall_section.delete(section_id) try: sg_rules = secgroup_db['security_group_rules'] # skip if there are no rules in group. i.e provider case @@ -2918,8 +2918,8 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, context = context.elevated() super(NsxV3Plugin, self).delete_security_group( context, secgroup_db['id']) - self.nsxlib.delete_nsgroup(ns_group['id']) - self.nsxlib.delete_section(firewall_section['id']) + self.nsxlib.ns_group.delete(ns_group['id']) + self.nsxlib.firewall_section.delete(firewall_section['id']) return secgroup_db @@ -2935,7 +2935,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, try: nsgroup_id, section_id = nsx_db.get_sg_mappings( context.session, id) - self.nsxlib.update_security_group_on_backend( + self.nsxlib.ns_group.update_on_backend( context, secgroup_res, nsgroup_id, section_id, cfg.CONF.nsx_v3.log_security_groups_allowed_traffic) except nsx_lib_exc.ManagerError: @@ -2953,8 +2953,8 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, nsgroup_id, section_id = nsx_db.get_sg_mappings( context.session, id) super(NsxV3Plugin, self).delete_security_group(context, id) - self.nsxlib.delete_section(section_id) - self.nsxlib.delete_nsgroup(nsgroup_id) + self.nsxlib.firewall_section.delete(section_id) + self.nsxlib.ns_group.delete(nsgroup_id) self.nsgroup_manager.remove_nsgroup(nsgroup_id) 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) 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) - 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) def save_security_group_rule_mappings(self, context, firewall_rules): diff --git a/vmware_nsx/services/l2gateway/nsx_v3/driver.py b/vmware_nsx/services/l2gateway/nsx_v3/driver.py index a67cd9673c..384d806536 100644 --- a/vmware_nsx/services/l2gateway/nsx_v3/driver.py +++ b/vmware_nsx/services/l2gateway/nsx_v3/driver.py @@ -85,7 +85,7 @@ class NsxV3Driver(l2gateway_db.L2GatewayMixin): admin_ctx = context.get_admin_context() 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)) # 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( gw_connection, resource_type='os-neutron-l2gw-id', 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, seg_id=seg_id, tags=tags) @@ -258,7 +258,7 @@ class NsxV3Driver(l2gateway_db.L2GatewayMixin): n_exc.NeutronException): LOG.exception(_LE("Unable to create L2 gateway port, " "rolling back changes on neutron")) - self._core_plugin.nsxlib.delete_bridge_endpoint( + self._core_plugin.nsxlib.bridge_endpoint.delete( bridge_endpoint['id']) raise l2gw_exc.L2GatewayServiceDriverError( method='create_l2_gateway_connection_postcommit') @@ -273,7 +273,7 @@ class NsxV3Driver(l2gateway_db.L2GatewayMixin): with excutils.save_and_reraise_exception(): LOG.exception(_LE("Unable to add L2 gateway connection " "mappings, rolling back changes on neutron")) - self._core_plugin.nsxlib.delete_bridge_endpoint( + self._core_plugin.nsxlib.bridge_endpoint.delete( bridge_endpoint['id']) super(NsxV3Driver, self).delete_l2_gateway_connection( @@ -298,7 +298,7 @@ class NsxV3Driver(l2gateway_db.L2GatewayMixin): port_id=conn_mapping.get('port_id'), l2gw_port_check=False) 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: LOG.exception(_LE("Unable to delete bridge endpoint %(id)s on the " "backend due to exc: %(exc)s"), diff --git a/vmware_nsx/services/neutron_taas/nsx_v3/driver.py b/vmware_nsx/services/neutron_taas/nsx_v3/driver.py index 11b482f1c2..8fda3e1bf4 100644 --- a/vmware_nsx/services/neutron_taas/nsx_v3/driver.py +++ b/vmware_nsx/services/neutron_taas/nsx_v3/driver.py @@ -281,7 +281,7 @@ class NsxV3Driver(base_driver.TaasBaseDriver, # Create port mirror session on the backend try: 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, dest_ports=nsx_dest_ports, direction=direction, @@ -307,8 +307,7 @@ class NsxV3Driver(base_driver.TaasBaseDriver, LOG.error(_LE("Unable to create port mirror session db " "mappings for tap flow %s. Rolling back " "changes in Neutron."), tf['id']) - nsxlib.delete_port_mirror_session( - pm_session['id']) + nsxlib.port_mirror.delete_session(pm_session['id']) def delete_tap_flow_precommit(self, context): pass @@ -369,7 +368,7 @@ class NsxV3Driver(base_driver.TaasBaseDriver, def _delete_local_span(self, context, pm_session_id): # Delete port mirroring session on the backend try: - nsxlib.delete_port_mirror_session(pm_session_id) + nsxlib.port_mirror.delete_session(pm_session_id) except nsxlib_exc.ManagerError: with excutils.save_and_reraise_exception(): LOG.error(_LE("Unable to delete port mirror session %s " diff --git a/vmware_nsx/services/qos/nsx_v3/utils.py b/vmware_nsx/services/qos/nsx_v3/utils.py index 238cfb3414..69c7072c99 100644 --- a/vmware_nsx/services/qos/nsx_v3/utils.py +++ b/vmware_nsx/services/qos/nsx_v3/utils.py @@ -84,6 +84,10 @@ class QosNotificationsHandler(object): def _core_plugin(self): return manager.NeutronManager.get_plugin() + @property + def _nsxlib_qos(self): + return self._core_plugin.nsxlib.qos_switching_profile + def _get_tags(self, context, policy): policy_dict = {'id': policy.id, 'tenant_id': policy.tenant_id} return utils.build_v3_tags_payload( @@ -93,7 +97,7 @@ class QosNotificationsHandler(object): def create_policy(self, context, policy): policy_id = policy.id 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, description=policy.description) 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): profile_id = nsx_db.get_switch_profile_by_qos_policy( 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): profile_id = nsx_db.get_switch_profile_by_qos_policy( context.session, policy_id) tags = self._get_tags(context, policy) - self._core_plugin.nsxlib.update_qos_switching_profile( + self._nsxlib_qos.update( profile_id, tags=tags, name=policy.name, @@ -185,7 +189,7 @@ class QosNotificationsHandler(object): average_bw) = self._get_bw_values_from_rule(bw_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, shaping_enabled=shaping_enabled, burst_size=burst_size, diff --git a/vmware_nsx/shell/admin/plugins/nsxv3/resources/networks.py b/vmware_nsx/shell/admin/plugins/nsxv3/resources/networks.py index 1eab554a9e..e7796a5399 100644 --- a/vmware_nsx/shell/admin/plugins/nsxv3/resources/networks.py +++ b/vmware_nsx/shell/admin/plugins/nsxv3/resources/networks.py @@ -54,7 +54,7 @@ def list_missing_networks(resource, event, trigger, **kwargs): pass else: 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: networks.append({'name': net['name'], 'neutron_id': neutron_id, diff --git a/vmware_nsx/shell/admin/plugins/nsxv3/resources/securitygroups.py b/vmware_nsx/shell/admin/plugins/nsxv3/resources/securitygroups.py index 6ea990e221..83e1f186e5 100644 --- a/vmware_nsx/shell/admin/plugins/nsxv3/resources/securitygroups.py +++ b/vmware_nsx/shell/admin/plugins/nsxv3/resources/securitygroups.py @@ -128,7 +128,7 @@ def list_security_groups_mappings(resource, event, trigger, **kwargs): @admin_utils.list_handler(constants.FIREWALL_SECTIONS) @admin_utils.output_header 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) 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.output_header 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) return bool(nsx_secgroups) def _find_missing_security_groups(): - nsx_secgroups = nsxlib.list_nsgroups() + nsx_secgroups = nsxlib.ns_group.list() sg_mappings = neutron_sg.get_security_groups_mappings() missing_secgroups = {} for sg_db in sg_mappings: @@ -171,7 +171,7 @@ def list_missing_security_groups(resource, event, trigger, **kwargs): def _find_missing_sections(): - fw_sections = nsxlib.list_sections() + fw_sections = nsxlib.firewall_section.list() sg_mappings = neutron_sg.get_security_groups_mappings() missing_sections = {} 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(): secgroup = plugin.get_security_group(context_, sg_id) - nsxlib.delete_section(sg['section-id']) - nsxlib.delete_nsgroup(sg['nsx-securitygroup-id']) + nsxlib.firewall_section.delete(sg['section-id']) + nsxlib.ns_group.delete(sg['nsx-securitygroup-id']) neutron_sg.delete_security_group_section_mapping(sg_id) neutron_sg.delete_security_group_backend_mapping(sg_id) 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): lport_id = neutron_db.get_logical_port_id(port_id) members.append(lport_id) - nsxlib.add_nsgroup_members( + nsxlib.ns_group.add_members( nsgroup['id'], consts.TARGET_TYPE_LOGICAL_PORT, members) 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 = 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.get('tags', []), criteria_tags) port_client._client.update(lport_id, body=lport) @@ -262,14 +262,14 @@ def _update_security_group_dynamic_criteria(): secgroups = neutron_sg.get_security_groups() for sg in secgroups: 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']) try: # We want to add the dynamic criteria and remove all direct members # they will be added by the manager using the new criteria. - nsxlib.update_nsgroup(nsgroup_id, - membership_criteria=membership_criteria, - members=[]) + nsxlib.ns_group.update(nsgroup_id, + membership_criteria=membership_criteria, + members=[]) except Exception as e: LOG.warning(_LW("Failed to update membership criteria for nsgroup " "%(nsgroup_id)s, request to backend returned " diff --git a/vmware_nsx/tests/unit/extensions/test_secgroup_rule_local_ip_prefix.py b/vmware_nsx/tests/unit/extensions/test_secgroup_rule_local_ip_prefix.py index f3ee8c17c1..b4dcaac933 100644 --- a/vmware_nsx/tests/unit/extensions/test_secgroup_rule_local_ip_prefix.py +++ b/vmware_nsx/tests/unit/extensions/test_secgroup_rule_local_ip_prefix.py @@ -137,7 +137,7 @@ class TestNSXv3ExtendedSGRule(test_nsxv3_plugin.NsxV3PluginTestCaseMixin, 'description': ''}] 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, ) as mock_rule: diff --git a/vmware_nsx/tests/unit/extensions/test_securitygroup.py b/vmware_nsx/tests/unit/extensions/test_securitygroup.py index b0eddd19c5..0a8d1fa951 100644 --- a/vmware_nsx/tests/unit/extensions/test_securitygroup.py +++ b/vmware_nsx/tests/unit/extensions/test_securitygroup.py @@ -46,11 +46,11 @@ def _mock_create_and_list_nsgroups(test_method): def wrap(*args, **kwargs): with mock.patch( - 'vmware_nsx.nsxlib.v3.NsxLib.create_nsgroup' + 'vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.create' ) as create_nsgroup_mock: create_nsgroup_mock.side_effect = _create_nsgroup_mock with mock.patch( - "vmware_nsx.nsxlib.v3.NsxLib.list_nsgroups" + "vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.list" ) as list_nsgroups_mock: list_nsgroups_mock.side_effect = lambda: nsgroups test_method(*args, **kwargs) @@ -74,8 +74,8 @@ class TestSecurityGroupsNoDynamicCriteria(test_nsxv3.NsxV3PluginTestCaseMixin, self._patchers.append(mock_nsx_version) @_mock_create_and_list_nsgroups - @mock.patch('vmware_nsx.nsxlib.v3.NsxLib.remove_nsgroup_member') - @mock.patch('vmware_nsx.nsxlib.v3.NsxLib.add_nsgroup_members') + @mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.remove_member') + @mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.add_members') def test_create_port_with_multiple_security_groups(self, add_member_mock, remove_member_mock): @@ -91,8 +91,8 @@ class TestSecurityGroupsNoDynamicCriteria(test_nsxv3.NsxV3PluginTestCaseMixin, add_member_mock.assert_has_calls(calls, any_order=True) @_mock_create_and_list_nsgroups - @mock.patch('vmware_nsx.nsxlib.v3.NsxLib.remove_nsgroup_member') - @mock.patch('vmware_nsx.nsxlib.v3.NsxLib.add_nsgroup_members') + @mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.remove_member') + @mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.add_members') def test_update_port_with_multiple_security_groups(self, add_member_mock, remove_member_mock): @@ -111,8 +111,8 @@ class TestSecurityGroupsNoDynamicCriteria(test_nsxv3.NsxV3PluginTestCaseMixin, NSG_IDS[0], consts.TARGET_TYPE_LOGICAL_PORT, mock.ANY) @_mock_create_and_list_nsgroups - @mock.patch('vmware_nsx.nsxlib.v3.NsxLib.remove_nsgroup_member') - @mock.patch('vmware_nsx.nsxlib.v3.NsxLib.add_nsgroup_members') + @mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.remove_member') + @mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.add_members') def test_update_port_remove_security_group_empty_list(self, add_member_mock, remove_member_mock): @@ -125,7 +125,7 @@ class TestSecurityGroupsNoDynamicCriteria(test_nsxv3.NsxV3PluginTestCaseMixin, NSG_IDS[1], consts.TARGET_TYPE_LOGICAL_PORT, mock.ANY) @_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 _add_member_mock(nsgroup, target_type, target_id): @@ -143,8 +143,8 @@ class TestSecurityGroupsNoDynamicCriteria(test_nsxv3.NsxV3PluginTestCaseMixin, res_body['NeutronError']['type']) @_mock_create_and_list_nsgroups - @mock.patch('vmware_nsx.nsxlib.v3.NsxLib.remove_nsgroup_member') - @mock.patch('vmware_nsx.nsxlib.v3.NsxLib.add_nsgroup_members') + @mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.remove_member') + @mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.add_members') def test_update_port_with_full_security_group(self, add_member_mock, remove_member_mock): @@ -214,8 +214,8 @@ class TestNSGroupManager(nsxlib_testcase.NsxLibTestCase): nested_groups) @_mock_create_and_list_nsgroups - @mock.patch('vmware_nsx.nsxlib.v3.NsxLib.remove_nsgroup_member') - @mock.patch('vmware_nsx.nsxlib.v3.NsxLib.add_nsgroup_members') + @mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.remove_member') + @mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.add_members') def test_add_and_remove_nsgroups(self, add_member_mock, remove_member_mock): @@ -239,8 +239,8 @@ class TestNSGroupManager(nsxlib_testcase.NsxLibTestCase): verify=True) @_mock_create_and_list_nsgroups - @mock.patch('vmware_nsx.nsxlib.v3.NsxLib.remove_nsgroup_member') - @mock.patch('vmware_nsx.nsxlib.v3.NsxLib.add_nsgroup_members') + @mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.remove_member') + @mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.add_members') def test_when_nested_group_is_full(self, add_member_mock, remove_member_mock): @@ -287,8 +287,8 @@ class TestNSGroupManager(nsxlib_testcase.NsxLibTestCase): remove_member_mock.assert_has_calls(calls) @_mock_create_and_list_nsgroups - @mock.patch('vmware_nsx.nsxlib.v3.NsxLib.remove_nsgroup_member') - @mock.patch('vmware_nsx.nsxlib.v3.NsxLib.add_nsgroup_members') + @mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.remove_member') + @mock.patch('vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.add_members') def initialize_with_absent_nested_groups(self, add_member_mock, remove_member_mock): diff --git a/vmware_nsx/tests/unit/nsx_v3/test_plugin.py b/vmware_nsx/tests/unit/nsx_v3/test_plugin.py index e136919ed2..91573ef6a1 100644 --- a/vmware_nsx/tests/unit/nsx_v3/test_plugin.py +++ b/vmware_nsx/tests/unit/nsx_v3/test_plugin.py @@ -107,15 +107,15 @@ def _mock_nsx_backend_calls(): side_effect=_return_id_key).start() 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() mock.patch( - "vmware_nsx.nsxlib.v3.NsxLib.create_bridge_endpoint", + "vmware_nsx.nsxlib.v3.NsxLibBridgeEndpoint.create", side_effect=_return_id_key).start() mock.patch( - "vmware_nsx.nsxlib.v3.NsxLib.create_logical_switch", + "vmware_nsx.nsxlib.v3.NsxLibLogicalSwitch.create", side_effect=_return_id_key).start() mock.patch( diff --git a/vmware_nsx/tests/unit/nsxlib/v3/nsxlib_testcase.py b/vmware_nsx/tests/unit/nsxlib/v3/nsxlib_testcase.py index a8ab44a9bd..1238bad4c7 100644 --- a/vmware_nsx/tests/unit/nsxlib/v3/nsxlib_testcase.py +++ b/vmware_nsx/tests/unit/nsxlib/v3/nsxlib_testcase.py @@ -56,27 +56,27 @@ def _mock_nsxlib(): ".validate_connection").start() mock.patch( - "vmware_nsx.nsxlib.v3.NsxLib.create_nsgroup", + "vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.create", side_effect=_return_id_key ).start() mock.patch( - "vmware_nsx.nsxlib.v3.NsxLib.create_empty_section", + "vmware_nsx.nsxlib.v3.security.NsxLibFirewallSection.create_empty", side_effect=_return_id_key).start() mock.patch( - "vmware_nsx.nsxlib.v3.NsxLib.init_default_section", + "vmware_nsx.nsxlib.v3.security.NsxLibFirewallSection.init_default", side_effect=_return_id_key).start() mock.patch( - "vmware_nsx.nsxlib.v3.NsxLib.list_nsgroups").start() + "vmware_nsx.nsxlib.v3.security.NsxLibNsGroup.list").start() 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() 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() mock.patch( diff --git a/vmware_nsx/tests/unit/nsxlib/v3/test_qos_switching_profile.py b/vmware_nsx/tests/unit/nsxlib/v3/test_qos_switching_profile.py index b5e56f1e2f..4d49dcae13 100644 --- a/vmware_nsx/tests/unit/nsxlib/v3/test_qos_switching_profile.py +++ b/vmware_nsx/tests/unit/nsxlib/v3/test_qos_switching_profile.py @@ -32,7 +32,8 @@ class NsxLibQosTestCase(nsxlib_testcase.NsxClientTestCase): "tags": [] } 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["description"] = description @@ -63,7 +64,7 @@ class NsxLibQosTestCase(nsxlib_testcase.NsxClientTestCase): break if qos_marking: - body = self.nsxlib._update_dscp_in_args( + body = self.nsxlib.qos_switching_profile._update_dscp_in_args( body, qos_marking, dscp) return body @@ -74,7 +75,7 @@ class NsxLibQosTestCase(nsxlib_testcase.NsxClientTestCase): """ with mock.patch.object(self.nsxlib.client, 'create') as create: - self.nsxlib.create_qos_switching_profile( + self.nsxlib.qos_switching_profile.create( tags=[], name=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: # 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'], tags=[], description=new_description) @@ -117,7 +118,7 @@ class NsxLibQosTestCase(nsxlib_testcase.NsxClientTestCase): return_value=original_profile): with mock.patch.object(self.nsxlib.client, 'update') as update: # 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'], shaping_enabled=True, burst_size=burst_size, @@ -155,7 +156,7 @@ class NsxLibQosTestCase(nsxlib_testcase.NsxClientTestCase): return_value=original_profile): with mock.patch.object(self.nsxlib.client, 'update') as update: # 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'], shaping_enabled=False, qos_marking="trusted") @@ -169,7 +170,7 @@ class NsxLibQosTestCase(nsxlib_testcase.NsxClientTestCase): Test deleting qos-switching-profile """ 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']) delete.assert_called_with( 'switching-profiles/%s' diff --git a/vmware_nsx/tests/unit/nsxlib/v3/test_switch.py b/vmware_nsx/tests/unit/nsxlib/v3/test_switch.py index 4e6cfebc00..b43843014d 100644 --- a/vmware_nsx/tests/unit/nsxlib/v3/test_switch.py +++ b/vmware_nsx/tests/unit/nsxlib/v3/test_switch.py @@ -47,7 +47,7 @@ class NsxLibSwitchTestCase(nsxlib_testcase.NsxClientTestCase): """ 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, []) 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: - self.nsxlib.create_logical_switch( + self.nsxlib.logical_switch.create( nsx_v3_mocks.FAKE_NAME, NsxLibSwitchTestCase._tz_id, [], admin_state=False) @@ -72,7 +72,7 @@ class NsxLibSwitchTestCase(nsxlib_testcase.NsxClientTestCase): """ 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, [], vlan_id='123') @@ -87,7 +87,7 @@ class NsxLibSwitchTestCase(nsxlib_testcase.NsxClientTestCase): with mock.patch.object(self.nsxlib.client, 'delete') as delete: 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( 'logical-switches/%s' '?detach=true&cascade=true' % fake_switch['id']) diff --git a/vmware_nsx/tests/unit/services/l2gateway/test_nsxv3_driver.py b/vmware_nsx/tests/unit/services/l2gateway/test_nsxv3_driver.py index ddd5a97814..da4bc8876f 100644 --- a/vmware_nsx/tests/unit/services/l2gateway/test_nsxv3_driver.py +++ b/vmware_nsx/tests/unit/services/l2gateway/test_nsxv3_driver.py @@ -86,7 +86,7 @@ class TestNsxV3L2GatewayDriver(test_l2gw_db.L2GWTestCase, mock.MagicMock()) l2gws = self.driver._get_l2_gateways(self.context) 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_l2gw = None for l2gw in l2gws: diff --git a/vmware_nsx/tests/unit/services/qos/test_nsxv3_notification.py b/vmware_nsx/tests/unit/services/qos/test_nsxv3_notification.py index a4b65ec2f7..9bc16c4fa7 100644 --- a/vmware_nsx/tests/unit/services/qos/test_nsxv3_notification.py +++ b/vmware_nsx/tests/unit/services/qos/test_nsxv3_notification.py @@ -92,7 +92,7 @@ class TestQosNsxV3Notification(base.BaseQosTestCase, def test_policy_create_profile(self, fake_db_add, fake_rbac_create): # test the switch profile creation when a QoS policy is created with mock.patch( - 'vmware_nsx.nsxlib.v3.NsxLib.create_qos_switching_profile', + 'vmware_nsx.nsxlib.v3.NsxLibQosSwitchingProfile.create', return_value=self.fake_profile ) as create_profile: with mock.patch('neutron.objects.qos.policy.QosPolicy.get_object', @@ -120,7 +120,7 @@ class TestQosNsxV3Notification(base.BaseQosTestCase, fields = base_object.get_updatable_fields( policy_object.QosPolicy, self.policy_data['policy']) with mock.patch( - 'vmware_nsx.nsxlib.v3.NsxLib.update_qos_switching_profile' + 'vmware_nsx.nsxlib.v3.NsxLibQosSwitchingProfile.update' ) as update_profile: with mock.patch('neutron.objects.qos.policy.QosPolicy.get_object', return_value=self.policy): @@ -151,8 +151,7 @@ class TestQosNsxV3Notification(base.BaseQosTestCase, with mock.patch('neutron.objects.qos.policy.QosPolicy.get_object', return_value=_policy): with mock.patch( - 'vmware_nsx.nsxlib.v3.NsxLib.' - 'update_qos_switching_profile_shaping' + 'vmware_nsx.nsxlib.v3.NsxLibQosSwitchingProfile.update_shaping' ) as update_profile: with mock.patch('neutron.objects.db.api.update_object', return_value=self.rule_data): @@ -194,8 +193,7 @@ class TestQosNsxV3Notification(base.BaseQosTestCase, with mock.patch('neutron.objects.qos.policy.QosPolicy.get_object', return_value=_policy): with mock.patch( - 'vmware_nsx.nsxlib.v3.NsxLib.' - 'update_qos_switching_profile_shaping' + 'vmware_nsx.nsxlib.v3.NsxLibQosSwitchingProfile.update_shaping' ) as update_profile: with mock.patch('neutron.objects.db.api.update_object', return_value=rule_data): @@ -227,8 +225,7 @@ class TestQosNsxV3Notification(base.BaseQosTestCase, with mock.patch('neutron.objects.qos.policy.QosPolicy.get_object', return_value=_policy): with mock.patch( - 'vmware_nsx.nsxlib.v3.NsxLib.' - 'update_qos_switching_profile_shaping' + 'vmware_nsx.nsxlib.v3.NsxLibQosSwitchingProfile.update_shaping' ) as update_profile: with mock.patch('neutron.objects.db.api.' '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', return_value=_policy): with mock.patch( - "vmware_nsx.nsxlib.v3.NsxLib." - "update_qos_switching_profile_shaping" + "vmware_nsx.nsxlib.v3.NsxLibQosSwitchingProfile.update_shaping" ) as update_profile: setattr(_policy, "rules", [self.rule]) self.qos_plugin.delete_policy_bandwidth_limit_rule( @@ -281,7 +277,7 @@ class TestQosNsxV3Notification(base.BaseQosTestCase, def test_policy_delete_profile(self, *mocks): # test the switch profile deletion when a QoS policy is deleted with mock.patch( - 'vmware_nsx.nsxlib.v3.NsxLib.delete_qos_switching_profile', + 'vmware_nsx.nsxlib.v3.NsxLibQosSwitchingProfile.delete', return_value=self.fake_profile ) as delete_profile: self.qos_plugin.delete_policy(self.ctxt, self.policy.id)