diff --git a/vmware_nsx/plugins/nsx_v/vshield/vcns_driver.py b/vmware_nsx/plugins/nsx_v/vshield/vcns_driver.py index efb2d9b9d9..64d5a25537 100644 --- a/vmware_nsx/plugins/nsx_v/vshield/vcns_driver.py +++ b/vmware_nsx/plugins/nsx_v/vshield/vcns_driver.py @@ -23,7 +23,6 @@ from vmware_nsx.plugins.nsx_v.vshield import edge_appliance_driver from vmware_nsx.plugins.nsx_v.vshield import edge_firewall_driver from vmware_nsx.plugins.nsx_v.vshield.tasks import tasks from vmware_nsx.plugins.nsx_v.vshield import vcns -from vmware_nsx.services.lbaas.nsx_v.v1 import edge_loadbalancer_driver from vmware_nsx.services.lbaas.nsx_v.v2 import ( edge_loadbalancer_driver_v2 as lbaas_v2) @@ -31,7 +30,6 @@ LOG = logging.getLogger(__name__) class VcnsDriver(edge_appliance_driver.EdgeApplianceDriver, - edge_loadbalancer_driver.EdgeLbDriver, lbaas_v2.EdgeLoadbalancerDriverV2, edge_firewall_driver.EdgeFirewallDriver): diff --git a/vmware_nsx/services/lbaas/nsx_v/v1/__init__.py b/vmware_nsx/services/lbaas/nsx_v/v1/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/vmware_nsx/services/lbaas/nsx_v/v1/edge_loadbalancer_driver.py b/vmware_nsx/services/lbaas/nsx_v/v1/edge_loadbalancer_driver.py deleted file mode 100644 index 38d43a27b9..0000000000 --- a/vmware_nsx/services/lbaas/nsx_v/v1/edge_loadbalancer_driver.py +++ /dev/null @@ -1,627 +0,0 @@ -# Copyright 2015 VMware, Inc. -# All Rights Reserved -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from neutron import manager -from neutron.plugins.common import constants -from neutron_lib import exceptions as n_exc -from oslo_log import log as logging -from oslo_utils import excutils - -from vmware_nsx._i18n import _, _LE -from vmware_nsx.common import locking -from vmware_nsx.plugins.nsx_v.vshield.common import exceptions as nsxv_exc -from vmware_nsx.services.lbaas.nsx_v import lbaas_common as lb_common -from vmware_nsx.services.lbaas.nsx_v import lbaas_const as lb_const - -LOG = logging.getLogger(__name__) - - -def convert_lbaas_pool(lbaas_pool): - """ - Transform OpenStack pool dict to NSXv pool dict. - """ - edge_pool = { - 'name': 'pool_' + lbaas_pool['id'], - 'description': lbaas_pool.get('description', - lbaas_pool.get('name')), - 'algorithm': lb_const.BALANCE_MAP.get( - lbaas_pool.get('lb_method'), 'round-robin'), - 'transparent': False - } - return edge_pool - - -def convert_lbaas_app_profile(name, sess_persist, protocol): - """ - Create app profile dict for lbaas VIP. - - Neutron-lbaas VIP objects breaks into an application profile object, and - a virtual server object in NSXv. - """ - vcns_app_profile = { - 'insertXForwardedFor': False, - 'name': name, - 'serverSslEnabled': False, - 'sslPassthrough': False, - 'template': protocol, - } - # Since SSL Termination is not supported right now, so just use - # sslPassthrough method if the protocol is HTTPS. - if protocol == lb_const.LB_PROTOCOL_HTTPS: - vcns_app_profile['sslPassthrough'] = True - - if sess_persist: - persist_type = sess_persist.get('type') - if persist_type: - # If protocol is not HTTP, only source_ip is supported - if (protocol != lb_const.LB_PROTOCOL_HTTP and - persist_type != lb_const.LB_SESSION_PERSISTENCE_SOURCE_IP): - msg = (_('Invalid %(protocol)s persistence method: %(type)s') % - {'protocol': protocol, - 'type': persist_type}) - raise n_exc.BadRequest(resource='edge-lbaas', msg=msg) - persistence = { - 'method': - lb_const.SESSION_PERSISTENCE_METHOD_MAP.get(persist_type)} - if persist_type in lb_const.SESSION_PERSISTENCE_COOKIE_MAP: - persistence.update({ - 'cookieName': sess_persist.get('cookie_name', - 'default_cookie_name'), - 'cookieMode': - lb_const.SESSION_PERSISTENCE_COOKIE_MAP[persist_type]}) - - vcns_app_profile['persistence'] = persistence - return vcns_app_profile - - -def convert_lbaas_vip(vip, app_profile_id, pool_mapping): - """ - Transform OpenStack VIP dict to NSXv virtual server dict. - """ - pool_id = pool_mapping['edge_pool_id'] - return { - 'name': 'vip_' + vip['id'], - 'description': vip['description'], - 'ipAddress': vip['address'], - 'protocol': vip.get('protocol'), - 'port': vip['protocol_port'], - 'connectionLimit': max(0, vip.get('connection_limit')), - 'defaultPoolId': pool_id, - 'applicationProfileId': app_profile_id} - - -def convert_lbaas_member(member): - """ - Transform OpenStack pool member dict to NSXv pool member dict. - """ - return { - 'ipAddress': member['address'], - 'weight': member['weight'], - 'port': member['protocol_port'], - 'monitorPort': member['protocol_port'], - 'name': lb_common.get_member_id(member['id']), - 'condition': 'enabled' if member['admin_state_up'] else 'disabled'} - - -def convert_lbaas_monitor(monitor): - """ - Transform OpenStack health monitor dict to NSXv health monitor dict. - """ - mon = { - 'type': lb_const.HEALTH_MONITOR_MAP.get(monitor['type'], 'icmp'), - 'interval': monitor['delay'], - 'timeout': monitor['timeout'], - 'maxRetries': monitor['max_retries'], - 'name': monitor['id']} - - if monitor.get('http_method'): - mon['method'] = monitor['http_method'] - - if monitor.get('url_path'): - mon['url'] = monitor['url_path'] - return mon - - -class EdgeLbDriver(object): - def __init__(self): - super(EdgeLbDriver, self).__init__() - LOG.debug('Initializing Edge loadbalancer') - # self.vcns is initialized by subclass - self.vcns = None - self._fw_section_id = None - self._lb_plugin = None - self._lbv1_driver_prop = None - - def _get_lb_plugin(self): - if not self._lb_plugin: - loaded_plugins = manager.NeutronManager.get_service_plugins() - self._lb_plugin = loaded_plugins[constants.LOADBALANCER] - return self._lb_plugin - - @property - def lbv1_driver(self): - if not self._lbv1_driver_prop: - plugin = self._get_lb_plugin() - self._lbv1_driver_prop = plugin.drivers['vmwareedge'] - - return self._lbv1_driver_prop - - def _get_lbaas_fw_section_id(self): - if not self._fw_section_id: - self._fw_section_id = lb_common.get_lbaas_fw_section_id(self.vcns) - return self._fw_section_id - - def _get_pool_member_ips(self, context, pool_id, operation, address): - plugin = self._get_lb_plugin() - members = plugin.get_members( - context, - filters={'pool_id': [pool_id]}, - fields=['address']) - member_ips = {member['address'] for member in members} - if operation == 'add': - member_ips.add(address) - elif operation == 'del' and address in member_ips: - member_ips.remove(address) - - return list(member_ips) - - def create_pool(self, context, pool): - LOG.debug('Creating pool %s', pool) - edge_id = lb_common.get_lbaas_edge_id_for_subnet( - context, self.callbacks.plugin, pool['subnet_id'], - pool['tenant_id']) - - if edge_id is None: - self.lbv1_driver.pool_failed(context, pool) - msg = _( - 'No suitable Edge found for subnet %s') % pool['subnet_id'] - raise n_exc.BadRequest(resource='edge-lbaas', msg=msg) - - # If Edge appliance is used for the 1st time for LB, - # enable LB acceleration - if not self.is_edge_in_use(context, - edge_id): - lb_common.enable_edge_acceleration(self.vcns, edge_id) - - edge_pool = convert_lbaas_pool(pool) - try: - with locking.LockManager.get_lock(edge_id): - h = self.vcns.create_pool(edge_id, edge_pool)[0] - edge_pool_id = lb_common.extract_resource_id(h['location']) - self.lbv1_driver.create_pool_successful( - context, pool, edge_id, edge_pool_id) - - except nsxv_exc.VcnsApiException: - with excutils.save_and_reraise_exception(): - self.lbv1_driver.pool_failed(context, pool) - LOG.error(_LE('Failed to create pool %s'), pool['id']) - - def update_pool(self, context, old_pool, pool, pool_mapping): - LOG.debug('Updating pool %s to %s', old_pool, pool) - edge_pool = convert_lbaas_pool(pool) - try: - with locking.LockManager.get_lock(pool_mapping['edge_id']): - curr_pool = self.vcns.get_pool(pool_mapping['edge_id'], - pool_mapping['edge_pool_id'])[1] - curr_pool.update(edge_pool) - self.vcns.update_pool(pool_mapping['edge_id'], - pool_mapping['edge_pool_id'], - curr_pool) - self.lbv1_driver.pool_successful(context, pool) - - except nsxv_exc.VcnsApiException: - with excutils.save_and_reraise_exception(): - self.lbv1_driver.pool_failed(context, pool) - LOG.error(_LE('Failed to update pool %s'), pool['id']) - - def delete_pool(self, context, pool, pool_mapping): - LOG.debug('Deleting pool %s', pool) - - if pool_mapping: - try: - with locking.LockManager.get_lock(pool_mapping['edge_id']): - self.vcns.delete_pool(pool_mapping['edge_id'], - pool_mapping['edge_pool_id']) - except nsxv_exc.VcnsApiException: - LOG.error(_LE('Failed to delete pool %s'), pool['id']) - else: - LOG.error(_LE('No mapping found for pool %s'), pool['id']) - - self.lbv1_driver.delete_pool_successful(context, pool) - - def create_vip(self, context, vip, pool_mapping): - LOG.debug('Create VIP %s', vip) - - app_profile = convert_lbaas_app_profile( - vip['id'], vip.get('session_persistence', {}), - vip.get('protocol')) - - if not pool_mapping: - msg = _('Pool %s in not mapped to any Edge appliance') % ( - vip['pool_id']) - raise n_exc.BadRequest(resource='edge-lbaas', msg=msg) - edge_id = pool_mapping['edge_id'] - - try: - with locking.LockManager.get_lock(edge_id): - h = (self.vcns.create_app_profile(edge_id, app_profile))[0] - app_profile_id = lb_common.extract_resource_id(h['location']) - except nsxv_exc.VcnsApiException: - with excutils.save_and_reraise_exception(): - self.lbv1_driver.vip_failed(context, vip) - LOG.error(_LE('Failed to create app profile on edge: %s'), - edge_id) - - edge_vip = convert_lbaas_vip(vip, app_profile_id, pool_mapping) - try: - lb_common.add_vip_as_secondary_ip(self.vcns, edge_id, - vip['address']) - with locking.LockManager.get_lock(edge_id): - h = self.vcns.create_vip(edge_id, edge_vip)[0] - edge_vip_id = lb_common.extract_resource_id(h['location']) - edge_fw_rule_id = lb_common.add_vip_fw_rule(self.vcns, - edge_id, vip['id'], - vip['address']) - self.lbv1_driver.create_vip_successful( - context, vip, edge_id, app_profile_id, edge_vip_id, - edge_fw_rule_id) - - except nsxv_exc.VcnsApiException: - with excutils.save_and_reraise_exception(): - self.lbv1_driver.vip_failed(context, vip) - LOG.error(_LE('Failed to create vip on Edge: %s'), edge_id) - with locking.LockManager.get_lock(edge_id): - self.vcns.delete_app_profile(edge_id, app_profile_id) - - def update_vip(self, context, old_vip, vip, pool_mapping, vip_mapping): - LOG.debug('Updating VIP %s to %s', old_vip, vip) - - edge_id = vip_mapping['edge_id'] - edge_vip_id = vip_mapping['edge_vse_id'] - app_profile_id = vip_mapping['edge_app_profile_id'] - app_profile = convert_lbaas_app_profile( - vip['name'], vip.get('session_persistence', {}), - vip.get('protocol')) - try: - with locking.LockManager.get_lock(edge_id): - self.vcns.update_app_profile(edge_id, app_profile_id, - app_profile) - except nsxv_exc.VcnsApiException: - with excutils.save_and_reraise_exception(): - self.lbv1_driver.vip_failed(context, vip) - LOG.error(_LE('Failed to update app profile on edge: %s'), - edge_id) - - edge_vip = convert_lbaas_vip(vip, app_profile_id, pool_mapping) - try: - with locking.LockManager.get_lock(edge_id): - self.vcns.update_vip(edge_id, edge_vip_id, edge_vip) - self.lbv1_driver.vip_successful(context, vip) - except nsxv_exc.VcnsApiException: - with excutils.save_and_reraise_exception(): - self.lbv1_driver.vip_failed(context, vip) - LOG.error(_LE('Failed to update vip on edge: %s'), edge_id) - - def delete_vip(self, context, vip, vip_mapping): - LOG.debug('Deleting VIP %s', vip) - - if not vip_mapping: - LOG.error(_LE('No mapping found for vip %s'), vip['id']) - else: - edge_id = vip_mapping['edge_id'] - edge_vse_id = vip_mapping['edge_vse_id'] - app_profile_id = vip_mapping['edge_app_profile_id'] - - try: - with locking.LockManager.get_lock(edge_id): - self.vcns.delete_vip(edge_id, edge_vse_id) - except Exception as e: - LOG.error(_LE('Failed to delete VIP from edge %(edge)s. ' - 'Exception is %(exc)s'), - {'edge': edge_id, 'exc': e}) - try: - lb_common.del_vip_as_secondary_ip(self.vcns, edge_id, - vip['address']) - except Exception as e: - LOG.error(_LE('Failed to delete secondary IP from edge ' - '%(edge)s. Exception is %(exc)s'), - {'edge': edge_id, 'exc': e}) - try: - lb_common.del_vip_fw_rule(self.vcns, edge_id, - vip_mapping['edge_fw_rule_id']) - except Exception as e: - LOG.error(_LE('Failed to delete VIP FW rule from edge ' - '%(edge)s. Exception is %(exc)s'), - {'edge': edge_id, 'exc': e}) - try: - with locking.LockManager.get_lock(edge_id): - self.vcns.delete_app_profile(edge_id, app_profile_id) - except Exception as e: - LOG.error(_LE('Failed to delete app profile from edge ' - '%(edge)s. Exception is %(exc)s'), - {'edge': edge_id, 'exc': e}) - - self.lbv1_driver.delete_vip_successful(context, vip) - - def create_member(self, context, member, pool_mapping): - LOG.debug('Creating member %s', member) - - with locking.LockManager.get_lock(pool_mapping['edge_id']): - edge_pool = self.vcns.get_pool(pool_mapping['edge_id'], - pool_mapping['edge_pool_id'])[1] - edge_member = convert_lbaas_member(member) - - if edge_pool['member']: - edge_pool['member'].append(edge_member) - else: - edge_pool['member'] = [edge_member] - - try: - self.vcns.update_pool( - pool_mapping['edge_id'], - pool_mapping['edge_pool_id'], - edge_pool) - - member_ips = self._get_pool_member_ips( - context, member['pool_id'], 'add', member['address']) - lb_common.update_pool_fw_rule( - self.vcns, member['pool_id'], pool_mapping['edge_id'], - self._get_lbaas_fw_section_id(), member_ips) - - self.lbv1_driver.member_successful(context, member) - - except nsxv_exc.VcnsApiException: - with excutils.save_and_reraise_exception(): - self.lbv1_driver.member_failed(context, member) - LOG.error(_LE('Failed to create member on edge: %s'), - pool_mapping['edge_id']) - - def update_member(self, context, old_member, member, pool_mapping): - LOG.debug('Updating member %s to %s', old_member, member) - - with locking.LockManager.get_lock(pool_mapping['edge_id']): - edge_pool = self.vcns.get_pool(pool_mapping['edge_id'], - pool_mapping['edge_pool_id'])[1] - - edge_member = convert_lbaas_member(member) - for i, m in enumerate(edge_pool['member']): - if m['name'] == lb_common.get_member_id(member['id']): - edge_pool['member'][i] = edge_member - break - - try: - self.vcns.update_pool(pool_mapping['edge_id'], - pool_mapping['edge_pool_id'], - edge_pool) - self.lbv1_driver.member_successful(context, member) - except nsxv_exc.VcnsApiException: - with excutils.save_and_reraise_exception(): - self.lbv1_driver.member_failed(context, member) - LOG.error(_LE('Failed to update member on edge: %s'), - pool_mapping['edge_id']) - - def delete_member(self, context, member, pool_mapping): - LOG.debug('Deleting member %s', member) - - if pool_mapping: - with locking.LockManager.get_lock(pool_mapping['edge_id']): - edge_pool = self.vcns.get_pool( - pool_mapping['edge_id'], - pool_mapping['edge_pool_id'])[1] - - for i, m in enumerate(edge_pool['member']): - if m['name'] == lb_common.get_member_id(member['id']): - edge_pool['member'].pop(i) - break - - try: - self.vcns.update_pool(pool_mapping['edge_id'], - pool_mapping['edge_pool_id'], - edge_pool) - member_ips = self._get_pool_member_ips( - context, member['pool_id'], 'del', member['address']) - lb_common.update_pool_fw_rule( - self.vcns, member['pool_id'], pool_mapping['edge_id'], - self._get_lbaas_fw_section_id(), member_ips) - - except nsxv_exc.VcnsApiException: - with excutils.save_and_reraise_exception(): - self.lbv1_driver.member_failed(context, member) - LOG.error(_LE('Failed to update member on edge: %s'), - pool_mapping['edge_id']) - - lb_plugin = self._get_lb_plugin() - lb_plugin._delete_db_member(context, member['id']) - - def create_pool_health_monitor(self, context, health_monitor, pool_id, - pool_mapping, mon_mappings): - LOG.debug('Create HM %s', health_monitor) - - edge_mon_id = None - with locking.LockManager.get_lock(pool_mapping['edge_id']): - # 1st, we find if we already have a pool with the same monitor, on - # the same Edge appliance. - # If there is no pool on this Edge which is already associated with - # this monitor, create this monitor on Edge - if mon_mappings: - edge_mon_id = mon_mappings['edge_monitor_id'] - else: - edge_monitor = convert_lbaas_monitor(health_monitor) - try: - h = self.vcns.create_health_monitor( - pool_mapping['edge_id'], edge_monitor)[0] - edge_mon_id = lb_common.extract_resource_id(h['location']) - - except nsxv_exc.VcnsApiException: - self.lbv1_driver.pool_health_monitor_failed(context, - health_monitor, - pool_id) - with excutils.save_and_reraise_exception(): - LOG.error( - _LE('Failed to associate monitor on edge: %s'), - pool_mapping['edge_id']) - - try: - # Associate monitor with Edge pool - edge_pool = self.vcns.get_pool(pool_mapping['edge_id'], - pool_mapping['edge_pool_id'])[1] - if edge_pool['monitorId']: - edge_pool['monitorId'].append(edge_mon_id) - else: - edge_pool['monitorId'] = [edge_mon_id] - - self.vcns.update_pool(pool_mapping['edge_id'], - pool_mapping['edge_pool_id'], - edge_pool) - - except nsxv_exc.VcnsApiException: - with excutils.save_and_reraise_exception(): - self.lbv1_driver.pool_health_monitor_failed(context, - health_monitor, - pool_id) - LOG.error( - _LE('Failed to associate monitor on edge: %s'), - pool_mapping['edge_id']) - - self.lbv1_driver.create_pool_health_monitor_successful( - context, health_monitor, pool_id, pool_mapping['edge_id'], - edge_mon_id) - - def update_pool_health_monitor(self, context, old_health_monitor, - health_monitor, pool_id, mon_mapping): - LOG.debug('Update HM %s to %s', old_health_monitor, health_monitor) - - edge_monitor = convert_lbaas_monitor(health_monitor) - - try: - with locking.LockManager.get_lock(mon_mapping['edge_id']): - self.vcns.update_health_monitor( - mon_mapping['edge_id'], - mon_mapping['edge_monitor_id'], - edge_monitor) - - except nsxv_exc.VcnsApiException: - with excutils.save_and_reraise_exception(): - self.lbv1_driver.pool_health_monitor_failed(context, - health_monitor, - pool_id) - LOG.error( - _LE('Failed to update monitor on edge: %s'), - mon_mapping['edge_id']) - - self.lbv1_driver.pool_health_monitor_successful(context, - health_monitor, - pool_id) - - def delete_pool_health_monitor(self, context, health_monitor, pool_id, - pool_mapping, mon_mapping): - LOG.debug('Deleting HM %s', health_monitor) - - edge_id = pool_mapping['edge_id'] - if not mon_mapping: - return - - with locking.LockManager.get_lock(pool_mapping['edge_id']): - edge_pool = self.vcns.get_pool(edge_id, - pool_mapping['edge_pool_id'])[1] - edge_pool['monitorId'].remove(mon_mapping['edge_monitor_id']) - - try: - self.vcns.update_pool(edge_id, - pool_mapping['edge_pool_id'], - edge_pool) - except nsxv_exc.VcnsApiException: - with excutils.save_and_reraise_exception(): - self.lbv1_driver.pool_health_monitor_failed(context, - health_monitor, - pool_id) - LOG.error( - _LE('Failed to delete monitor mapping on edge: %s'), - mon_mapping['edge_id']) - - # If this monitor is not used on this edge anymore, delete it - if not edge_pool['monitorId']: - try: - self.vcns.delete_health_monitor( - mon_mapping['edge_id'], - mon_mapping['edge_monitor_id']) - except nsxv_exc.VcnsApiException: - with excutils.save_and_reraise_exception(): - self.lbv1_driver.pool_health_monitor_failed( - context, health_monitor, pool_id) - LOG.error( - _LE('Failed to delete monitor on edge: %s'), - mon_mapping['edge_id']) - - self.lbv1_driver.delete_pool_health_monitor_successful( - context, health_monitor, pool_id, mon_mapping) - - def stats(self, context, pool_id, pool_mapping): - LOG.debug('Retrieving stats for pool %s', pool_id) - - try: - lb_stats = self.vcns.get_loadbalancer_statistics( - pool_mapping['edge_id']) - - except nsxv_exc.VcnsApiException: - with excutils.save_and_reraise_exception(): - LOG.error( - _LE('Failed to read load balancer statistics, edge: %s'), - pool_mapping['edge_id']) - - pools_stats = lb_stats[1].get('pool', []) - plugin = self._get_lb_plugin() - members = plugin.get_members( - context, - filters={'pool_id': [pool_id]}, - fields=['id', 'status']) - member_map = {m['id']: m['status'] for m in members} - - for pool_stats in pools_stats: - if pool_stats['poolId'] == pool_mapping['edge_pool_id']: - stats = {'bytes_in': pool_stats.get('bytesIn', 0), - 'bytes_out': pool_stats.get('bytesOut', 0), - 'active_connections': - pool_stats.get('curSessions', 0), - 'total_connections': - pool_stats.get('totalSessions', 0)} - - member_stats = {} - for member in pool_stats.get('member', []): - member_id = member['name'][len(lb_common.MEMBER_ID_PFX):] - if member_map[member_id] != 'ERROR': - member_stats[member_id] = { - 'status': ('INACTIVE' - if member['status'] == 'DOWN' - else 'ACTIVE')} - - stats['members'] = member_stats - return stats - - return {'bytes_in': 0, - 'bytes_out': 0, - 'active_connections': 0, - 'total_connections': 0} - - def is_edge_in_use(self, context, edge_id): - return self.lbv1_driver.is_edge_in_use(context, edge_id) - - def is_subnet_in_use(self, context, subnet_id): - plugin = self._get_lb_plugin() - if plugin: - pools = plugin.get_pools(context, - filters={'subnet_id': [subnet_id]}) - if pools: - return True diff --git a/vmware_nsx/tests/unit/nsx_v/test_edge_loadbalancer_driver.py b/vmware_nsx/tests/unit/nsx_v/test_edge_loadbalancer_driver.py deleted file mode 100644 index 56377151c9..0000000000 --- a/vmware_nsx/tests/unit/nsx_v/test_edge_loadbalancer_driver.py +++ /dev/null @@ -1,543 +0,0 @@ -# Copyright 2015 VMware, Inc. -# All Rights Reserved -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import mock - -from neutron import context -from neutron.tests import base - -from vmware_nsx.plugins.nsx_v.vshield import vcns_driver -from vmware_nsx.services.lbaas.nsx_v import lbaas_common as lb_common - -EDGE_PROVIDER = ('LOADBALANCER:vmwareedge:neutron.services.' - 'loadbalancer.drivers.vmware.edge_driver.' - 'EdgeLoadbalancerDriver:default') - -HEALTHMON_ID = 'cb297614-66c9-4048-8838-7e87231569ae' -POOL_ID = 'b3dfb476-6fdf-4ddd-b6bd-e86ae78dc30b' -TENANT_ID = 'f9135d3a908842bd8d785816c2c90d36' -SUBNET_ID = 'c8924d77-ff57-406f-a13c-a8c5def01fc9' -VIP_ID = 'f6393b95-34b0-4299-9001-cbc21e32bf03' -VIP_PORT_ID = '49c547e3-6775-42ea-a607-91e8f1a07432' -MEMBER_ID = '90dacafd-9c11-4af7-9d89-234e2d1fedb1' - -EDGE_ID = 'edge-x' -EDGE_POOL_ID = '111' -EDGE_VSE_ID = '222' -APP_PROFILE_ID = '333' -EDGE_MON_ID = '444' -EDGE_FW_RULE_ID = '555' - - -def lbaas_pool_maker(**kwargs): - lbaas_dict = { - 'status': 'PENDING_CREATE', - 'lb_method': 'ROUND_ROBIN', - 'protocol': 'HTTP', - 'description': '', - 'health_monitors': [], - 'members': [], - 'status_description': None, - 'id': POOL_ID, - 'vip_id': None, - 'name': 'testpool', - 'admin_state_up': True, - 'subnet_id': SUBNET_ID, - 'tenant_id': TENANT_ID, - 'health_monitors_status': [], - 'provider': 'vmwareedge'} - - lbaas_dict.update(kwargs) - return lbaas_dict - - -def lbaas_vip_maker(**kwargs): - lbaas_vip = { - 'status': 'PENDING_CREATE', - 'protocol': 'HTTP', - 'description': '', - 'address': '10.0.0.8', - 'protocol_port': 555, - 'port_id': VIP_PORT_ID, - 'id': VIP_ID, - 'status_description': None, - 'name': 'testvip1', - 'admin_state_up': True, - 'subnet_id': SUBNET_ID, - 'tenant_id': TENANT_ID, - 'connection_limit': -1, - 'pool_id': POOL_ID, - 'session_persistence': {'type': 'SOURCE_IP'}} - - lbaas_vip.update(kwargs) - return lbaas_vip - - -def lbaas_member_maker(**kwargs): - lbaas_member = { - 'admin_state_up': True, - 'status': 'PENDING_CREATE', - 'status_description': None, - 'weight': 5, - 'address': '10.0.0.4', - 'tenant_id': TENANT_ID, - 'protocol_port': 555, - 'id': MEMBER_ID, - 'pool_id': POOL_ID} - - lbaas_member.update(kwargs) - return lbaas_member - - -def lbaas_hmon_maker(**kwargs): - hmon = { - 'admin_state_up': True, - 'tenant_id': TENANT_ID, - 'delay': 5, - 'max_retries': 5, - 'timeout': 5, - 'pools': [{'status': 'PENDING_CREATE', 'status_description': None, - 'pool_id': POOL_ID}], - 'type': 'PING', - 'id': HEALTHMON_ID} - hmon.update(kwargs) - return hmon - - -class TestEdgeLbDriver(base.BaseTestCase): - def setUp(self): - super(TestEdgeLbDriver, self).setUp() - self.context = context.get_admin_context() - callbacks = mock.Mock() - callbacks.plugin = mock.Mock() - self.edge_driver = vcns_driver.VcnsDriver(callbacks) - self.edge_driver._lbv1_driver_prop = mock.Mock() - self._temp_get_lbaas_edge_id_for_subnet = ( - lb_common.get_lbaas_edge_id_for_subnet) - self._temp_update_pool_fw_rule = lb_common.update_pool_fw_rule - self._temp_add_vip_as_secondary_ip = lb_common.add_vip_as_secondary_ip - self._temp_add_vip_fw_rule = lb_common.add_vip_fw_rule - self._temp_del_vip_as_secondary_ip = lb_common.del_vip_as_secondary_ip - self._temp_del_vip_fw_rule = lb_common.del_vip_fw_rule - lb_common.get_lbaas_edge_id_for_subnet = mock.Mock() - lb_common.update_pool_fw_rule = mock.Mock() - lb_common.add_vip_as_secondary_ip = mock.Mock() - lb_common.add_vip_fw_rule = mock.Mock() - lb_common.del_vip_as_secondary_ip = mock.Mock() - lb_common.del_vip_fw_rule = mock.Mock() - - def tearDown(self): - super(TestEdgeLbDriver, self).tearDown() - lb_common.get_lbaas_edge_id_for_subnet = ( - self._temp_get_lbaas_edge_id_for_subnet) - lb_common.update_pool_fw_rule = self._temp_update_pool_fw_rule - lb_common.add_vip_as_secondary_ip = self._temp_add_vip_as_secondary_ip - lb_common.add_vip_fw_rule = self._temp_add_vip_fw_rule - lb_common.del_vip_as_secondary_ip = self._temp_del_vip_as_secondary_ip - lb_common.del_vip_fw_rule = self._temp_del_vip_fw_rule - - def _mock_edge_driver(self, attr): - return mock.patch.object(self.edge_driver, attr) - - def _mock_edge_driver_vcns(self, attr): - return mock.patch.object(self.edge_driver.vcns, attr) - - def _mock_edge_lbv1_driver(self, attr): - return mock.patch.object(self.edge_driver.lbv1_driver, attr) - - def test_create_pool(self): - lbaas_pool = lbaas_pool_maker() - - edge_pool = { - 'transparent': False, 'name': 'pool_' + POOL_ID, - 'algorithm': 'round-robin', 'description': ''} - - with self._mock_edge_lbv1_driver( - 'create_pool_successful') as create_pool_successful, \ - self._mock_edge_driver_vcns('create_pool') as create_pool: - - lb_common.get_lbaas_edge_id_for_subnet.return_value = EDGE_ID - create_pool.return_value = ({'location': 'x/' + EDGE_POOL_ID}, - None) - - self.edge_driver.create_pool(self.context, lbaas_pool) - create_pool.assert_called_with(EDGE_ID, edge_pool) - create_pool_successful.assert_called_with( - self.context, lbaas_pool, EDGE_ID, EDGE_POOL_ID) - - def test_update_pool(self): - from_pool = lbaas_pool_maker(status='ACTIVE') - to_pool = lbaas_pool_maker(status='PENDING_UPDATE', - lb_method='LEAST_CONNECTIONS') - - edge_pool = { - 'transparent': False, 'name': 'pool_' + POOL_ID, - 'algorithm': 'leastconn', 'description': ''} - - pool_mapping = {'edge_id': EDGE_ID, 'edge_pool_id': EDGE_POOL_ID} - with self._mock_edge_lbv1_driver('pool_successful') as pool_successful,\ - self._mock_edge_driver_vcns('get_pool') as get_pool, \ - self._mock_edge_driver_vcns('update_pool') as update_pool: - - get_pool.return_value = (None, {}) - self.edge_driver.update_pool( - self.context, from_pool, to_pool, pool_mapping) - update_pool.assert_called_with(EDGE_ID, EDGE_POOL_ID, edge_pool) - pool_successful.assert_called_with(self.context, to_pool) - - def test_delete_pool(self): - lbaas_pool = lbaas_pool_maker() - - pool_mapping = {'edge_id': EDGE_ID, 'edge_pool_id': EDGE_POOL_ID} - - with self._mock_edge_driver_vcns('delete_pool'),\ - self._mock_edge_lbv1_driver( - 'delete_pool_successful') as mock_delete_successful: - - self.edge_driver.delete_pool( - self.context, lbaas_pool, pool_mapping) - mock_delete_successful.assert_called_with(self.context, lbaas_pool) - - def test_create_vip(self): - lbaas_vip = lbaas_vip_maker() - edge_app_prof = { - 'name': VIP_ID, 'insertXForwardedFor': False, - 'serverSslEnabled': False, 'template': 'HTTP', - 'sslPassthrough': False, 'persistence': {'method': 'sourceip'}} - edge_vip = { - 'protocol': 'HTTP', 'name': 'vip_' + VIP_ID, 'connectionLimit': 0, - 'defaultPoolId': EDGE_POOL_ID, 'ipAddress': '10.0.0.8', - 'port': 555, 'applicationProfileId': APP_PROFILE_ID, - 'description': ''} - - pool_mapping = {'edge_id': EDGE_ID, 'edge_pool_id': EDGE_POOL_ID} - - with self._mock_edge_driver_vcns( - 'create_app_profile') as mock_create_app_profile,\ - self._mock_edge_driver_vcns('create_vip') as mock_create_vip,\ - self._mock_edge_lbv1_driver( - 'create_vip_successful') as mock_vip_successful: - - mock_create_app_profile.return_value = ( - {'location': 'x/' + APP_PROFILE_ID}, None) - mock_create_vip.return_value = ( - {'location': 'x/' + EDGE_VSE_ID}, None) - lb_common.add_vip_fw_rule.return_value = EDGE_FW_RULE_ID - - self.edge_driver.create_vip(self.context, lbaas_vip, pool_mapping) - mock_create_app_profile.assert_called_with(EDGE_ID, edge_app_prof) - lb_common.add_vip_fw_rule.assert_called_with( - self.edge_driver.vcns, EDGE_ID, VIP_ID, '10.0.0.8') - mock_create_vip.assert_called_with(EDGE_ID, edge_vip) - mock_vip_successful.assert_called_with( - self.context, lbaas_vip, EDGE_ID, APP_PROFILE_ID, EDGE_VSE_ID, - EDGE_FW_RULE_ID) - - def test_update_vip(self): - vip_from = lbaas_vip_maker(status='ACTIVE') - vip_to = lbaas_vip_maker(status='PENDING_UPDATE', - session_persistence={'type': 'HTTP_COOKIE'}) - edge_app_prof = { - 'name': 'testvip1', 'insertXForwardedFor': False, - 'serverSslEnabled': False, 'template': 'HTTP', - 'sslPassthrough': False, - 'persistence': {'cookieName': 'default_cookie_name', - 'method': 'cookie', 'cookieMode': 'insert'}} - edge_vip = { - 'protocol': 'HTTP', 'name': 'vip_' + VIP_ID, 'connectionLimit': 0, - 'defaultPoolId': EDGE_POOL_ID, 'ipAddress': '10.0.0.8', - 'port': 555, 'applicationProfileId': '333', 'description': ''} - - pool_mapping = {'edge_pool_id': '111'} - vip_mapping = {'edge_id': EDGE_ID, 'edge_vse_id': EDGE_VSE_ID, - 'edge_app_profile_id': APP_PROFILE_ID} - - with self._mock_edge_driver_vcns('update_vip') as mock_upd_vip,\ - self._mock_edge_driver_vcns( - 'update_app_profile') as mock_upd_app_prof,\ - self._mock_edge_lbv1_driver( - 'vip_successful') as mock_vip_successful: - - self.edge_driver.update_vip(self.context, vip_from, vip_to, - pool_mapping, vip_mapping) - - mock_upd_app_prof.assert_called_with(EDGE_ID, APP_PROFILE_ID, - edge_app_prof) - mock_upd_vip.assert_called_with(EDGE_ID, EDGE_VSE_ID, edge_vip) - mock_vip_successful.assert_called_with(self.context, vip_to) - - def test_delete_vip(self): - lbaas_vip = lbaas_vip_maker(status='PENDING_DELETE') - vip_mapping = {'edge_id': EDGE_ID, 'edge_vse_id': EDGE_VSE_ID, - 'edge_app_profile_id': APP_PROFILE_ID, - 'edge_fw_rule_id': EDGE_FW_RULE_ID} - - with self._mock_edge_driver_vcns( - 'delete_app_profile') as mock_del_app_profile,\ - self._mock_edge_driver_vcns('delete_vip') as mock_del_vip,\ - self._mock_edge_lbv1_driver( - 'delete_vip_successful') as mock_del_successful: - - self.edge_driver.delete_vip(self.context, lbaas_vip, vip_mapping) - mock_del_app_profile.assert_called_with(EDGE_ID, APP_PROFILE_ID) - mock_del_vip.assert_called_with(EDGE_ID, EDGE_VSE_ID) - lb_common.del_vip_fw_rule.assert_called_with( - self.edge_driver.vcns, EDGE_ID, EDGE_FW_RULE_ID) - mock_del_successful.assert_called_with(self.context, lbaas_vip) - - def test_create_member(self): - lbaas_member = lbaas_member_maker() - edge_pool = { - 'monitorId': [], 'name': POOL_ID, 'applicationRuleId': [], - 'member': [], 'poolId': 'pool-1', 'algorithm': 'round-robin', - 'transparent': False} - edge_member = { - 'condition': 'enabled', 'ipAddress': '10.0.0.4', 'port': 555, - 'weight': 5, 'name': 'member-' + MEMBER_ID} - - pool_mapping = {'edge_id': EDGE_ID, 'edge_pool_id': EDGE_POOL_ID} - - with self._mock_edge_driver_vcns('update_pool'),\ - self._mock_edge_driver_vcns('get_pool') as mock_get_pool,\ - self._mock_edge_driver( - '_get_pool_member_ips') as mock_get_ips, \ - self._mock_edge_driver( - '_get_lbaas_fw_section_id') as mock_fw_sect, \ - self._mock_edge_lbv1_driver( - 'member_successful') as mock_member_successful: - - mock_get_pool.return_value = (None, edge_pool) - mock_get_ips.return_value = ['10.0.0.4'] - mock_fw_sect.return_value = 10010 - self.edge_driver.create_member(self.context, lbaas_member, - pool_mapping) - edge_pool['member'].append(edge_member) - mock_member_successful.assert_called_with(self.context, - lbaas_member) - - def test_update_member(self): - member_from = lbaas_member_maker(status='ACTIVE') - member_to = lbaas_member_maker(status='PENDING_UPDATE', weight=10) - edge_pool = { - 'monitorId': [], 'name': POOL_ID, 'applicationRuleId': [], - 'member': [ - {'condition': 'enabled', 'ipAddress': '10.0.0.4', 'port': 555, - 'weight': 5, 'name': 'member-' + MEMBER_ID}], - 'poolId': 'pool-1', 'algorithm': 'round-robin', - 'transparent': False} - - pool_mapping = {'edge_id': EDGE_ID, 'edge_pool_id': EDGE_POOL_ID} - - with self._mock_edge_driver_vcns('get_pool') as mock_get_pool,\ - self._mock_edge_driver_vcns( - 'update_pool') as mock_update_pool,\ - self._mock_edge_lbv1_driver( - 'member_successful') as mock_member_successful: - - mock_get_pool.return_value = (None, edge_pool) - self.edge_driver.update_member(self.context, member_from, - member_to, pool_mapping) - edge_pool['member'][0]['weight'] = 6 - mock_update_pool.assert_called_with(EDGE_ID, EDGE_POOL_ID, - edge_pool) - mock_member_successful.assert_called_with(self.context, member_to) - - def test_delete_member(self): - def _del_member(context, member_id): - self.assertEqual(context, self.context) - self.assertEqual(member_id, MEMBER_ID) - - lbaas_member = lbaas_member_maker(status='PENDING_DELETE') - edge_pool = { - 'monitorId': [], 'name': POOL_ID, 'applicationRuleId': [], - 'member': [ - {'condition': 'enabled', 'ipAddress': '10.0.0.4', 'port': 555, - 'weight': 5, 'name': 'member-' + MEMBER_ID}], - 'poolId': 'pool-1', 'algorithm': 'round-robin', - 'transparent': False} - - pool_mapping = {'edge_id': EDGE_ID, 'edge_pool_id': EDGE_POOL_ID} - mock_lb_plugin = mock.Mock() - mock_lb_plugin._delete_db_member = _del_member - - with self._mock_edge_driver('_get_lb_plugin') as mock_get_lb_plugin,\ - self._mock_edge_driver_vcns('get_pool') as mock_get_pool,\ - self._mock_edge_driver( - '_get_lbaas_fw_section_id') as mock_fw_sect, \ - self._mock_edge_driver_vcns( - 'update_pool') as mock_update_pool: - - mock_get_pool.return_value = (None, edge_pool) - self.edge_driver.delete_member(self.context, lbaas_member, - pool_mapping) - mock_fw_sect.return_value = 10010 - mock_get_lb_plugin.return_value = mock_lb_plugin - edge_pool['member'] = [] - mock_update_pool.assert_called_with(EDGE_ID, EDGE_POOL_ID, - edge_pool) - - def test_create_pool_health_monitor(self): - hmon = lbaas_hmon_maker() - edge_hm = {'maxRetries': 5, 'interval': 5, 'type': 'icmp', - 'name': HEALTHMON_ID, 'timeout': 5} - edge_pool = {'monitorId': [], 'name': POOL_ID, - 'applicationRuleId': [], 'member': [], - 'poolId': 'pool-1', 'algorithm': 'round-robin', - 'transparent': False} - - pool_mapping = {'edge_id': EDGE_ID, 'edge_pool_id': EDGE_POOL_ID} - - with self._mock_edge_driver_vcns('update_pool') as mock_update_pool,\ - self._mock_edge_driver_vcns('get_pool') as mock_get_pool,\ - self._mock_edge_driver_vcns( - 'create_health_monitor') as mock_create_mon,\ - self._mock_edge_lbv1_driver( - 'create_pool_health_monitor_successful') as ( - mock_create_successful): - - mock_create_mon.return_value = ({'location': 'x/' + HEALTHMON_ID}, - None) - mock_get_pool.return_value = (None, edge_pool) - self.edge_driver.create_pool_health_monitor( - self.context, hmon, POOL_ID, pool_mapping, None) - mock_create_mon.assert_called_with(EDGE_ID, edge_hm) - edge_pool['monitorId'].append(HEALTHMON_ID) - mock_update_pool.assert_called_with(EDGE_ID, EDGE_POOL_ID, - edge_pool) - mock_create_successful.assert_called_with( - self.context, hmon, POOL_ID, EDGE_ID, HEALTHMON_ID) - - def test_update_pool_health_monitor(self): - from_hmon = lbaas_hmon_maker(status='ACTIVE') - to_hmon = lbaas_hmon_maker(status='PENDING_UPDATE', - max_retries=10) - edge_hmon = {'maxRetries': 10, 'interval': 5, 'type': 'icmp', - 'name': HEALTHMON_ID, 'timeout': 5} - - mon_mapping = {'edge_id': EDGE_ID, 'edge_monitor_id': EDGE_MON_ID} - - with self._mock_edge_driver_vcns( - 'update_health_monitor') as mock_update_mon,\ - self._mock_edge_lbv1_driver( - 'pool_health_monitor_successful') as mock_hmon_successful: - - self.edge_driver.update_pool_health_monitor( - self.context, from_hmon, to_hmon, POOL_ID, mon_mapping) - - mock_update_mon.assert_called_with(EDGE_ID, EDGE_MON_ID, edge_hmon) - mock_hmon_successful.assert_called_with(self.context, to_hmon, - POOL_ID,) - - def test_delete_pool_health_monitor(self): - hmon = lbaas_hmon_maker(status='PENDING_DELETE') - edge_pool = {'monitorId': [EDGE_MON_ID], 'name': POOL_ID, - 'applicationRuleId': [], 'member': [], - 'poolId': 'pool-1', 'algorithm': 'round-robin', - 'transparent': False} - - pool_mapping = {'edge_id': EDGE_ID, 'edge_pool_id': EDGE_POOL_ID} - mon_mapping = {'edge_id': EDGE_ID, 'edge_monitor_id': EDGE_MON_ID} - - with self._mock_edge_driver_vcns('update_pool') as mock_update_pool,\ - self._mock_edge_driver_vcns('get_pool') as mock_get_pool,\ - self._mock_edge_driver_vcns( - 'delete_health_monitor') as mock_del_mon,\ - self._mock_edge_lbv1_driver( - 'delete_pool_health_monitor_successful') as ( - mock_del_successful): - - mock_get_pool.return_value = (None, edge_pool) - self.edge_driver.delete_pool_health_monitor( - self.context, hmon, POOL_ID, pool_mapping, mon_mapping) - - edge_pool['monitorId'] = [] - mock_update_pool.assert_called_with(EDGE_ID, EDGE_POOL_ID, - edge_pool) - mock_del_mon.assert_called_with(EDGE_ID, EDGE_MON_ID) - mock_del_successful.assert_called_with(self.context, hmon, POOL_ID, - mon_mapping) - - def test_stats(self): - pool_mapping = {'edge_id': EDGE_ID, 'edge_pool_id': EDGE_POOL_ID} - pool_stats = ( - { - 'status': '200', - 'content-location': '', - 'transfer-encoding': 'chunked', - 'expires': 'Thu, 01 Jan 1970 00:00:00 GMT', - 'server': '', - 'cache-control': 'private, no-cache', - 'date': 'Thu, 30 Jul 2015 08:59:27 GMT', - 'content-type': 'application/json'}, - { - 'timeStamp': 1427358733, - 'virtualServer': [ - {'name': 'MdSrv', - 'virtualServerId': 'virtualServer-1', - 'bytesIn': 0, - 'bytesOut': 0, - 'totalSessions': 0, - 'ipAddress': '169.254.128.2', - 'curSessions': 0}], - 'pool': [ - {'status': 'UP', - 'totalSessions': 10000, - 'rateMax': 0, - 'name': 'MDSrvPool', - 'bytesOut': 100000, - 'rateLimit': 0, - 'member': [ - {'status': 'UP', - 'name': 'member-xxx-xxx-xxx-xxx', - 'bytesOut': 0, - 'memberId': 'member-1', - 'totalSessions': 20000, - 'ipAddress': '192.168.55.101', - 'httpReqRateMax': 0, - 'curSessions': 0, - 'bytesIn': 0}, - {'status': 'UP', - 'name': 'member-yyy-yyy-yyy-yyy', - 'bytesOut': 0, - 'memberId': 'member-2', - 'totalSessions': 20000, - 'ipAddress': '192.168.55.102', - 'httpReqRateMax': 0, - 'curSessions': 0, - 'bytesIn': 0}], - 'poolId': EDGE_POOL_ID, - 'maxSessions': 10000, - 'httpReqRateMax': 0, - 'curSessions': 5000, - 'bytesIn': 1000000}]}) - expected_stats = {'active_connections': 5000, - 'bytes_in': 1000000, - 'bytes_out': 100000, - 'total_connections': 10000, - 'members': {'xxx-xxx-xxx-xxx': {'status': 'ACTIVE'}}} - - members = [{'id': 'xxx-xxx-xxx-xxx', 'status': 'ACTIVE'}, - {'id': 'yyy-yyy-yyy-yyy', 'status': 'ERROR'}] - mock_lb_plugin = mock.Mock() - with mock.patch.object(self.edge_driver.vcns, - 'get_loadbalancer_statistics', - return_value=pool_stats), \ - mock.patch.object(self.edge_driver, - '_get_lb_plugin', - return_value=mock_lb_plugin), \ - mock.patch.object(mock_lb_plugin, 'get_members', - return_value=members): - stats = self.edge_driver.stats(self.context, POOL_ID, pool_mapping) - self.assertEqual(stats, expected_stats)