# Copyright 2014 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 oslo_log import log as logging from vmware_nsx.plugins.nsx_v.vshield import nsxv_edge_cfg_obj LOG = logging.getLogger(__name__) class NsxvLoadbalancer(nsxv_edge_cfg_obj.NsxvEdgeCfgObj): SERVICE_NAME = 'loadbalancer' def __init__( self, enabled=True, enable_service_insertion=False, acceleration_enabled=False): super(NsxvLoadbalancer, self).__init__() self.payload = { 'enabled': enabled, 'enableServiceInsertion': enable_service_insertion, 'accelerationEnabled': acceleration_enabled} self.virtual_servers = {} def get_service_name(self): return self.SERVICE_NAME def add_virtual_server(self, virtual_server): self.virtual_servers[virtual_server.payload['name']] = virtual_server def del_virtual_server(self, name): self.virtual_servers.pop(name, None) def serializable_payload(self): virt_servers = [] app_profiles = [] app_rules = [] pools = [] monitors = [] virt_id = 1 app_prof_id = 1 app_rule_id = 1 pool_id = 1 monitor_id = 1 member_id = 1 for virtual_server in self.virtual_servers.values(): s_virt = virtual_server.payload.copy() s_virt['virtualServerId'] = 'virtualServer-%d' % virt_id virt_id += 1 # Setup app profile s_app_prof = virtual_server.app_profile.payload.copy() s_app_prof['applicationProfileId'] = ('applicationProfile-%d' % app_prof_id) app_profiles.append(s_app_prof) app_prof_id += 1 # Bind virtual server to app profile s_virt['applicationProfileId'] = s_app_prof['applicationProfileId'] # Setup app rules if virtual_server.app_rules.values(): s_virt['applicationRuleId'] = [] for app_rule in virtual_server.app_rules.values(): s_app_rule = app_rule.payload.copy() s_app_rule['applicationRuleId'] = ('applicationRule-%d' % app_rule_id) app_rule_id += 1 # Add to LB object, bind to virtual server app_rules.append(s_app_rule) s_virt['applicationRuleId'].append( s_app_rule['applicationRuleId']) # Setup pools s_pool = virtual_server.default_pool.payload.copy() s_pool['poolId'] = 'pool-%d' % pool_id pool_id += 1 pools.append(s_pool) # Add pool members s_pool['member'] = [] for member in virtual_server.default_pool.members.values(): s_m = member.payload.copy() s_m['memberId'] = 'member-%d' % member_id member_id += 1 s_pool['member'].append(s_m) # Bind pool to virtual server s_virt['defaultPoolId'] = s_pool['poolId'] s_pool['monitorId'] = [] # Add monitors for monitor in virtual_server.default_pool.monitors.values(): s_mon = monitor.payload.copy() s_mon['monitorId'] = 'monitor-%d' % monitor_id monitor_id += 1 s_pool['monitorId'].append(s_mon['monitorId']) monitors.append(s_mon) virt_servers.append(s_virt) payload = self.payload.copy() payload['applicationProfile'] = app_profiles if app_rules: payload['applicationRule'] = app_rules payload['monitor'] = monitors payload['pool'] = pools payload['virtualServer'] = virt_servers payload['featureType'] = 'loadbalancer_4.0' return payload @staticmethod def get_loadbalancer(vcns_obj, edge_id): edge_lb = nsxv_edge_cfg_obj.NsxvEdgeCfgObj.get_object( vcns_obj, edge_id, '%s/config' % NsxvLoadbalancer.SERVICE_NAME) lb_obj = NsxvLoadbalancer( edge_lb['enabled'], edge_lb['enableServiceInsertion'], edge_lb['accelerationEnabled']) # Construct loadbalancer objects for virt_srvr in edge_lb['virtualServer']: v_s = NsxvLBVirtualServer( virt_srvr['name'], virt_srvr['ipAddress'], virt_srvr['port'], virt_srvr['protocol'], virt_srvr['enabled'], virt_srvr['accelerationEnabled'], virt_srvr['connectionLimit']) # Find application profile objects, attach to virtual server for app_prof in edge_lb['applicationProfile']: if (virt_srvr['applicationProfileId'] == app_prof['applicationProfileId']): a_p = NsxvLBAppProfile( app_prof['name'], app_prof['serverSslEnabled'], app_prof['sslPassthrough'], app_prof['template'], app_prof['insertXForwardedFor']) if app_prof.get('persistence'): a_p.set_persistence( True, app_prof['persistence']['method'], app_prof['persistence'].get('cookieName'), app_prof['persistence'].get('cookieMode'), app_prof['persistence'].get('expire')) v_s.set_app_profile(a_p) # Find default pool, attach to virtual server for pool in edge_lb['pool']: if virt_srvr['defaultPoolId'] == pool['poolId']: p = NsxvLBPool( pool['name'], pool['algorithm'], pool['transparent']) # Add pool members to pool for member in pool['member']: m = NsxvLBPoolMember( member['name'], member['ipAddress'], member['port'], member['monitorPort'], member['condition'], member['weight'], member['minConn'], member['maxConn']) p.add_member(m) # Add monitors to pool for mon in edge_lb['monitor']: if mon['monitorId'] in pool['monitorId']: m = NsxvLBMonitor( mon['name'], mon['interval'], mon['maxRetries'], mon['method'], mon['timeout'], mon['type'], mon['url']) p.add_monitor(m) v_s.set_default_pool(p) # Add application rules to virtual server for rule in edge_lb['applicationRule']: if rule['applicationRuleId'] in virt_srvr['applicationRuleId']: r = NsxvLBAppRule( rule['name'], rule['script']) v_s.add_app_rule(r) lb_obj.add_virtual_server(v_s) return lb_obj class NsxvLBAppProfile(object): def __init__( self, name, server_ssl_enabled=False, ssl_pass_through=False, template='TCP', insert_xff=False, client_ssl_cert=None, persist=False, persist_method='cookie', persist_cookie_name='JSESSIONID', persist_cookie_mode='insert', persist_expire=30): self.payload = { 'name': name, 'serverSslEnabled': server_ssl_enabled, 'sslPassthrough': ssl_pass_through, 'template': template, 'insertXForwardedFor': insert_xff} if persist: self.payload['persistence'] = { 'method': persist_method, 'expire': persist_expire } if persist_cookie_mode == 'cookie': self.payload['persistence']['cookieMode'] = persist_cookie_mode self.payload['persistence']['cookieName'] = persist_cookie_name if client_ssl_cert: self.payload['clientSsl'] = { 'clientAuth': 'ignore', 'serviceCertificate': [client_ssl_cert] } def set_persistence( self, persist=False, persist_method='cookie', persist_cookie_name='JSESSIONID', persist_cookie_mode='insert', persist_expire=30): if persist: self.payload['persistence'] = { 'method': persist_method, 'expire': persist_expire } if persist_cookie_mode == 'cookie': self.payload['persistence']['cookieMode'] = persist_cookie_mode self.payload['persistence']['cookieName'] = persist_cookie_name else: self.payload.pop('persistence', None) class NsxvLBAppRule(object): def __init__(self, name, script): self.payload = { 'name': name, 'script': script} class NsxvLBVirtualServer(object): def __init__( self, name, ip_address, port=80, protocol='HTTP', enabled=True, acceleration_enabled=False, connection_limit=0, enable_service_insertion=False): self.payload = { 'name': name, 'ipAddress': ip_address, 'port': port, 'protocol': protocol, 'enabled': enabled, 'accelerationEnabled': acceleration_enabled, 'connectionLimit': connection_limit, 'enableServiceInsertion': enable_service_insertion} self.app_rules = {} self.app_profile = None self.default_pool = None def add_app_rule(self, app_rule): self.app_rules[app_rule.payload['name']] = app_rule def del_app_rule(self, name): self.app_rules.pop(name, None) def set_default_pool(self, pool): self.default_pool = pool def set_app_profile(self, app_profile): self.app_profile = app_profile class NsxvLBMonitor(object): def __init__( self, name, interval=10, max_retries=3, method='GET', timeout=15, mon_type='http', url='/'): self.payload = { 'name': name, 'interval': interval, 'maxRetries': max_retries, 'method': method, 'timeout': timeout, 'type': mon_type, 'url': url} class NsxvLBPoolMember(object): def __init__( self, name, ip_address, port, monitor_port=None, condition='enabled', weight=1, min_conn=0, max_conn=0): self.payload = { 'name': name, 'ipAddress': ip_address, 'port': port, 'monitorPort': monitor_port, 'condition': condition, 'weight': weight, 'minConn': min_conn, 'maxConn': max_conn} class NsxvLBPool(object): def __init__( self, name, algorithm='round-robin', transparent=False): self.payload = { 'name': name, 'algorithm': algorithm, 'transparent': transparent} self.members = {} self.monitors = {} def add_member(self, member): self.members[member.payload['name']] = member def del_member(self, name): self.members.pop(name, None) def add_monitor(self, monitor): self.monitors[monitor.payload['name']] = monitor def del_monitor(self, name): self.monitors.pop(name, None)