def test_f5label(self): self.assertEqual(f5label("test test test"), "test test test") self.assertEqual(f5label("[dev]"), "dev") self.assertEqual(len(f5label(65 * "A")), 64) FORBIDDEN_CHARACTERS = "#&*<>?[\\]`\"" for forbidden_char in FORBIDDEN_CHARACTERS: self.assertEqual(f5label(forbidden_char), "")
def test_f5remark(self): self.assertEqual(f5remark("test test test"), "test test test") self.assertEqual(f5remark("\Programm Files"), "Programm Files") self.assertEqual(len(f5remark(65 * "A")), 64) FORBIDDEN_CHARACTERS = "\\\"" for forbidden_char in FORBIDDEN_CHARACTERS: self.assertEqual(f5label(forbidden_char), "")
def get_pool(pool, loadbalancer_ips, status): """Map Octavia Pool -> AS3 Pool object :param pool: octavia pool object :param loadbalancer_ips: already used loadbalancer_ips :param status: status manager instance :return: AS3 pool """ # Entities is a list of tuples, which each describe AS3 objects # which may reference each other but do not form a hierarchy. entities = [] lbaas_lb_method = pool.lb_algorithm.upper() lbmode = _set_lb_method(lbaas_lb_method, pool.members) service_args = { 'label': as3types.f5label(pool.name or pool.description), 'remark': as3types.f5remark(pool.description or pool.name), 'loadBalancingMode': lbmode, 'members': [], } enable_priority_group = any([member.backup for member in pool.members]) for member in pool.members: if not utils.pending_delete(member): if member.ip_address in loadbalancer_ips: LOG.warning("The member address %s of member %s (pool %s, LB %s) is already in use by another load balancer.", member.ip_address, member.id, member.pool.id, member.pool.load_balancer.id) if status: status.set_error(member) continue if member.ip_address == '0.0.0.0': LOG.warning("The member address 0.0.0.0 of member %s is prohibited.", member.id) if status: status.set_error(member) continue service_args['members'].append( m_member.get_member(member, enable_priority_group, pool.health_monitor)) # add custom member monitors if pool.health_monitor and (member.monitor_address or member.monitor_port): member_hm = m_monitor.get_monitor(pool.health_monitor, member.monitor_address or member.ip_address, member.monitor_port or member.protocol_port) entities.append((m_monitor.get_name(member.id), member_hm)) if pool.health_monitor and not utils.pending_delete( pool.health_monitor): monitor_name = m_monitor.get_name(pool.health_monitor.id) entities.append((monitor_name, m_monitor.get_monitor(pool.health_monitor))) service_args['monitors'] = [Pointer(use=monitor_name)] entities.append((get_name(pool.id), Pool(**service_args))) return entities
def get_endpoint_policy(l7policies): wrapper_name = ', '.join( [l7policy.name for l7policy in l7policies if l7policy.name]) wrapper_desc = ', '.join([ l7policy.description for l7policy in l7policies if l7policy.description ]) args = dict() args['label'] = as3types.f5label(wrapper_name or wrapper_desc) args['remark'] = as3types.f5remark(wrapper_desc or wrapper_name) args['rules'] = [ Endpoint_Policy_Rule( name=get_name(l7policy.id), label=as3types.f5label(l7policy.name or l7policy.description), remark=as3types.f5remark(l7policy.description or l7policy.name), conditions=[_get_condition(l7rule) for l7rule in l7policy.l7rules], actions=[_get_action(l7policy)]) for l7policy in l7policies ] args['strategy'] = 'first-match' return Endpoint_Policy(**args)
def get_ca_bundle(bundle, remark='', label=''): """AS3 Certificate Authority Bundle object. :param bundle: the CA certificate bundle as PEM encoded bytes :param remark: comment :param label: label :return: AS3 CA_Bundle """ service_args = { 'remark': as3types.f5remark(remark), 'label': as3types.f5label(label), 'bundle': bundle.decode('utf-8').replace('\r', '') } return CA_Bundle(**service_args)
def get_pool(pool): """Map Octavia Pool -> AS3 Pool object :param pool: octavia pool object :return: AS3 pool """ # Entities is a list of tuples, which each describe AS3 objects # which may reference each other but do not form a hierarchy. entities = [] lbaas_lb_method = pool.lb_algorithm.upper() lbmode = _set_lb_method(lbaas_lb_method, pool.members) service_args = { 'label': as3types.f5label(pool.name or pool.id), 'remark': as3types.f5remark(pool.description or pool.id), 'loadBalancingMode': lbmode, 'members': [], } for member in pool.members: # Ignore backup members, will be handled by service if not utils.pending_delete(member) and not member.backup: service_args['members'].append(m_member.get_member(member)) #if pool.health_monitor and not utils.pending_delete( # pool.health_monitor): # Workaround for Monitor deletion bug in AS3, dereference but remain HM if pool.health_monitor: hms = m_monitor.get_monitors(pool.health_monitor, pool.members) entities.extend(hms) # Part of the workaround if not utils.pending_delete(pool.health_monitor): service_args['monitors'] = [Pointer(use=name) for name, _ in hms] entities.append((get_name(pool.id), Pool(**service_args))) return entities
def get_service(listener, cert_manager, esd_repository): """ Map Octavia listener -> AS3 Service :param listener: Octavia listener :param cert_manager: cert_manager wrapper instance :return: AS3 Service + additional AS3 application objects """ # Entities is a list of tuples, which each describe AS3 objects # which may reference each other but do not form a hierarchy. entities = [] vip = listener.load_balancer.vip project_id = listener.load_balancer.project_id label = as3types.f5label(listener.name or listener.description) virtual_address = '{}/32'.format(vip.ip_address) service_args = { 'virtualPort': listener.protocol_port, 'persistenceMethods': [], 'iRules': [], 'policyEndpoint': [], 'label': label } # Custom virtual address settings if CONF.f5_agent.service_address_icmp_echo: service_address = as3.ServiceAddress( virtualAddress=virtual_address, icmpEcho=CONF.f5_agent.service_address_icmp_echo) entities.append( (m_app.get_name(listener.load_balancer.id), service_address)) service_args['virtualAddresses'] = [[ as3.Pointer(m_app.get_name(listener.load_balancer.id)), virtual_address ]] else: service_args['virtualAddresses'] = [virtual_address] # Determine service type if listener.protocol == const.PROTOCOL_TCP: service_args['_servicetype'] = CONF.f5_agent.tcp_service_type # UDP elif listener.protocol == const.PROTOCOL_UDP: service_args['_servicetype'] = const.SERVICE_UDP # HTTP elif listener.protocol == const.PROTOCOL_HTTP: service_args['_servicetype'] = const.SERVICE_HTTP # HTTPS (non-terminated, forward TCP traffic) elif listener.protocol == const.PROTOCOL_HTTPS: service_args['_servicetype'] = CONF.f5_agent.tcp_service_type # Proxy elif listener.protocol == const.PROTOCOL_PROXY: service_args['_servicetype'] = const.SERVICE_TCP name, irule = m_irule.get_proxy_irule() service_args['iRules'].append(name) entities.append((name, irule)) # Terminated HTTPS elif listener.protocol == const.PROTOCOL_TERMINATED_HTTPS: service_args['_servicetype'] = const.SERVICE_HTTPS service_args['serverTLS'] = m_tls.get_listener_name(listener.id) service_args['redirect80'] = False # Certificate Handling auth_name = None certificates = cert_manager.get_certificates(listener) if listener.client_ca_tls_certificate_id and listener.client_authentication != 'NONE': # Client Side Certificates try: auth_name, secret = cert_manager.load_secret( project_id, listener.client_ca_tls_certificate_id) entities.append((auth_name, m_cert.get_ca_bundle(secret, auth_name, auth_name))) except exceptions.CertificateRetrievalException as e: LOG.error("Error fetching certificate: %s", e) entities.append( (m_tls.get_listener_name(listener.id), m_tls.get_tls_server([cert['id'] for cert in certificates], auth_name, listener.client_authentication))) entities.extend([(cert['id'], cert['as3']) for cert in certificates]) if listener.connection_limit > 0: service_args['maxConnections'] = listener.connection_limit # Add default pool if listener.default_pool_id: pool = listener.default_pool if pool.provisioning_status != lib_consts.PENDING_DELETE: default_pool = m_pool.get_name(listener.default_pool_id) service_args['pool'] = default_pool # only consider Proxy pool, everything else is determined by listener type if pool.protocol == const.PROTOCOL_PROXY: name, irule = m_irule.get_proxy_irule() service_args['iRules'].append(name) entities.append((name, irule)) # Pool member certificate handling (TLS backends) if pool.tls_enabled and listener.protocol in \ [ const.PROTOCOL_PROXY, const.PROTOCOL_HTTP, const.PROTOCOL_TERMINATED_HTTPS ]: client_cert = None trust_ca = None crl_file = None service_args['clientTLS'] = m_tls.get_pool_name(pool.id) certificates = cert_manager.get_certificates(pool) if len(certificates) == 1: cert = certificates.pop() entities.append((cert['id'], cert['as3'])) client_cert = cert['id'] if pool.ca_tls_certificate_id: trust_ca, secret = cert_manager.load_secret( project_id, pool.ca_tls_certificate_id) entities.append( (trust_ca, m_cert.get_ca_bundle(secret, trust_ca, trust_ca))) if pool.crl_container_id: # TODO: CRL currently not supported pass entities.append((m_tls.get_pool_name(pool.id), m_tls.get_tls_client(trust_ca=trust_ca, client_cert=client_cert, crl_file=crl_file))) # Insert header irules if service_args['_servicetype'] in const.SERVICE_HTTP_TYPES: # HTTP profiles only for name, irule in m_irule.get_header_irules(listener.insert_headers): service_args['iRules'].append(name) entities.append((name, irule)) # session persistence if listener.default_pool_id and listener.default_pool.session_persistence: persistence = listener.default_pool.session_persistence lb_algorithm = listener.default_pool.lb_algorithm if service_args['_servicetype'] in const.SERVICE_HTTP_TYPES: # Add APP_COOKIE / HTTP_COOKIE persistance only in HTTP profiles if persistence.type == 'APP_COOKIE' and persistence.cookie_name: # generate iRule for cookie_name escaped_cookie = persistence.cookie_name escaped_cookie.replace("\"", "") irule_name, irule = m_irule.get_app_cookie_irule( escaped_cookie) entities.append((irule_name, irule)) # add iRule to universal persistance profile name, obj_persist = m_persist.get_app_cookie(escaped_cookie) service_args['persistenceMethods'] = [as3.Pointer(name)] entities.append((name, obj_persist)) if lb_algorithm == 'SOURCE_IP': service_args[ 'fallbackPersistenceMethod'] = 'source-address' elif persistence.type == 'HTTP_COOKIE': service_args['persistenceMethods'] = ['cookie'] if lb_algorithm == 'SOURCE_IP': service_args[ 'fallbackPersistenceMethod'] = 'source-address' if persistence.type == 'SOURCE_IP': if not persistence.persistence_timeout and not persistence.persistence_granularity: service_args['persistenceMethods'] = ['source-address'] else: name, obj_persist = m_persist.get_source_ip( persistence.persistence_timeout, persistence.persistence_granularity) service_args['persistenceMethods'] = [as3.Pointer(name)] entities.append((name, obj_persist)) # Map listener tags to ESDs for tag in listener.tags: # get ESD of same name esd = esd_repository.get_esd(tag) if esd is None: continue # enrich service with iRules and other things defined in ESD esd_entities = get_esd_entities(service_args['_servicetype'], esd) for entity_name in esd_entities: if entity_name == 'iRules': service_args['iRules'].extend(esd_entities['iRules']) else: service_args[entity_name] = esd_entities[entity_name] endpoint_policies = [] # Map special L7policies to ESDs # TODO: Remove this as soon as all customers have migrated their scripts. # Triggering ESDs via L7policies is considered deprecated. Tags should be used instead. See the code above. for policy in listener.l7policies: # get ESD of same name esd = esd_repository.get_esd(policy.name) # Add ESD or regular endpoint policy if esd: # enrich service with iRules and other things defined in ESD esd_entities = get_esd_entities(service_args['_servicetype'], esd) for entity_name in esd_entities: if entity_name == 'iRules': service_args['iRules'].extend(esd_entities['iRules']) else: service_args[entity_name] = esd_entities[entity_name] elif policy.provisioning_status != lib_consts.PENDING_DELETE: endpoint_policies.append(policy) # UDP listener won't support policies if endpoint_policies and not service_args[ '_servicetype'] == const.SERVICE_UDP: # add a regular endpoint policy policy_name = m_policy.get_wrapper_name(listener.id) # make endpoint policy object endpoint_policy = (policy_name, m_policy.get_endpoint_policy(endpoint_policies)) entities.append(endpoint_policy) # reference endpoint policy object in service service_args['policyEndpoint'].append(policy_name) # Ensure no duplicate iRules service_args['iRules'] = list(set(service_args['iRules'])) # fastL4 profile doesn't support iRules, fallback to TCP Profile when iRules detected if service_args['_servicetype'] == const.SERVICE_L4 and len( service_args['iRules']) > 0: service_args['_servicetype'] = const.SERVICE_TCP # add default profiles to supported listeners if CONF.f5_agent.profile_http and service_args[ '_servicetype'] in const.SERVICE_HTTP_TYPES: if 'profileHTTP' not in service_args: service_args['profileHTTP'] = as3.BigIP(CONF.f5_agent.profile_http) if CONF.f5_agent.profile_l4 and service_args[ '_servicetype'] == const.SERVICE_L4: if 'profileL4' not in service_args: service_args['profileL4'] = as3.BigIP(CONF.f5_agent.profile_l4) if CONF.f5_agent.profile_tcp and service_args[ '_servicetype'] in const.SERVICE_TCP_TYPES: if 'profileTCP' not in service_args: service_args['profileTCP'] = as3.BigIP(CONF.f5_agent.profile_tcp) if CONF.f5_agent.profile_udp and service_args[ '_servicetype'] == const.SERVICE_UDP: if 'profileUDP' not in service_args: service_args['profileUDP'] = as3.BigIP(CONF.f5_agent.profile_udp) # Use the virtual-server address as SNAT address if CONF.f5_agent.snat_virtual: service_args['snat'] = 'self' # create service object and fill in additional fields service = as3.Service(**service_args) # add service to entities and return entities.append((get_name(listener.id), service)) return entities
def get_monitor(health_monitor, target_address=None, target_port=None): args = dict() # Standard Octavia monitor types if health_monitor.type == 'HTTP': args['monitorType'] = 'http' elif health_monitor.type == 'HTTPS': args['monitorType'] = 'https' elif health_monitor.type == 'PING': args['monitorType'] = 'icmp' elif health_monitor.type == 'TCP': args['monitorType'] = 'tcp' args['send'] = '' args['receive'] = '' elif health_monitor.type == 'TLS-HELLO': args['monitorType'] = 'external' args['script'] = TLS_HELLO_CHECK args['receive'] = 'UP' elif health_monitor.type == 'UDP-CONNECT': args['monitorType'] = 'external' args['script'] = UDP_CHECK args['receive'] = 'UP' # F5 specific monitory types elif health_monitor.type == 'SIP': args['monitorType'] = 'sip' elif health_monitor.type == 'SMTP': args['monitorType'] = 'smtp' elif health_monitor.type == 'TCP-HALF_OPEN': args['monitorType'] = 'tcp-half-open' elif health_monitor.type == 'LDAP': args['monitorType'] = 'ldap' elif health_monitor.type == 'DNS': args['monitorType'] = 'dns' args['queryName'] = health_monitor.domain_name # No Health monitor type available else: return {} if health_monitor.type == 'HTTP' or health_monitor.type == 'HTTPS': http_version = '1.0' if health_monitor.http_version: http_version = health_monitor.http_version send = "{} {} HTTP/{}\\r\\n".format(health_monitor.http_method, health_monitor.url_path, http_version) if health_monitor.domain_name: send += "Host: {}\\r\\n\\r\\n".format(health_monitor.domain_name) else: send += "\\r\\n" args['send'] = send args['receive'] = _get_recv_text(health_monitor) if health_monitor.delay: args["interval"] = health_monitor.delay if health_monitor.timeout: timeout = (int(health_monitor.fall_threshold) * int(health_monitor.timeout)) args["timeout"] = timeout if health_monitor.rise_threshold: time_until_up = (int(health_monitor.rise_threshold) * int(health_monitor.timeout)) args["timeUntilUp"] = time_until_up if target_address: args["targetAddress"] = target_address if target_port: args["targetPort"] = target_port args['label'] = as3types.f5label(health_monitor.name or health_monitor.id) return Monitor(**args)
def get_monitor(health_monitor, target_address=None, target_port=None): args = dict() # Standard Octavia monitor types if health_monitor.type == 'HTTP': args['monitorType'] = 'http' elif health_monitor.type == 'HTTPS': args['monitorType'] = 'https' elif health_monitor.type == 'PING': args['monitorType'] = 'icmp' elif health_monitor.type == 'TCP': args['monitorType'] = 'tcp' args['send'] = '' args['receive'] = '' elif health_monitor.type == 'TLS-HELLO': args['monitorType'] = 'external' args['script'] = TLS_HELLO_CHECK args['receive'] = 'UP' elif health_monitor.type == 'UDP-CONNECT': args['monitorType'] = 'udp' args['receive'] = '' args['send'] = '' # F5 specific monitory types elif health_monitor.type == 'SIP': args['monitorType'] = 'sip' elif health_monitor.type == 'SMTP': args['monitorType'] = 'smtp' elif health_monitor.type == 'TCP-HALF_OPEN': args['monitorType'] = 'tcp-half-open' elif health_monitor.type == 'LDAP': args['monitorType'] = 'ldap' elif health_monitor.type == 'DNS': args['monitorType'] = 'dns' args['queryName'] = health_monitor.domain_name # No Health monitor type available else: return {} if health_monitor.type == 'HTTP' or health_monitor.type == 'HTTPS': http_version = '1.0' if health_monitor.http_version: http_version = health_monitor.http_version send = "{} {} HTTP/{}\\r\\n".format( health_monitor.http_method, health_monitor.url_path, http_version ) if health_monitor.domain_name: send += "Host: {}\\r\\n\\r\\n".format( health_monitor.domain_name) else: send += "\\r\\n" args['send'] = send args['receive'] = _get_recv_text(health_monitor) args["interval"] = health_monitor.delay timeout = int(health_monitor.fall_threshold) * int(health_monitor.delay) + 1 # respect BigIP LTM maximum health monitor timeout of 900 seconds args["timeout"] = min(timeout, 900) if target_address: args["targetAddress"] = target_address if target_port: args["targetPort"] = target_port if CONF.f5_agent.profile_healthmonitor_tls and health_monitor.type == 'HTTPS': args["clientTLS"] = as3.BigIP(CONF.f5_agent.profile_healthmonitor_tls) args['label'] = as3types.f5label(health_monitor.name or health_monitor.id) return as3.Monitor(**args)
def get_service(listener, cert_manager, esd_repository): """ Map Octavia listener -> AS3 Service :param listener: Octavia listener :param cert_manager: cert_manager wrapper instance :return: AS3 Service + additional AS3 application objects """ # Entities is a list of tuples, which each describe AS3 objects # which may reference each other but do not form a hierarchy. entities = [] vip = listener.load_balancer.vip project_id = listener.load_balancer.project_id label = as3types.f5label(listener.description or listener.id) service_args = { 'virtualPort': listener.protocol_port, 'virtualAddresses': [vip.ip_address], 'persistenceMethods': [], 'iRules': [], 'policyEndpoint': [], 'label': label } # Determine service type if listener.protocol == const.PROTOCOL_TCP: service_args['_servicetype'] = CONF.f5_agent.tcp_service_type # UDP elif listener.protocol == const.PROTOCOL_UDP: service_args['_servicetype'] = const.SERVICE_UDP # HTTP elif listener.protocol == const.PROTOCOL_HTTP: service_args['_servicetype'] = const.SERVICE_HTTP # HTTPS (non-terminated) elif listener.protocol == const.PROTOCOL_HTTPS: service_args['_servicetype'] = const.SERVICE_GENERIC # Proxy elif listener.protocol == const.PROTOCOL_PROXY: service_args['_servicetype'] = const.SERVICE_HTTP name, irule = m_irule.get_proxy_irule() service_args['iRules'].append(name) entities.append((name, irule)) # Terminated HTTPS elif listener.protocol == const.PROTOCOL_TERMINATED_HTTPS: service_args['_servicetype'] = const.SERVICE_HTTPS service_args['serverTLS'] = m_tls.get_listener_name(listener.id) service_args['redirect80'] = False # Certificate Handling auth_name = None certificates = cert_manager.get_certificates(listener) if listener.client_ca_tls_certificate_id and listener.client_authentication != 'NONE': # Client Side Certificates try: auth_name, secret = cert_manager.load_secret( project_id, listener.client_ca_tls_certificate_id) entities.append((auth_name, m_cert.get_ca_bundle(secret, auth_name, auth_name))) except exceptions.CertificateRetrievalException as e: LOG.error("Error fetching certificate: %s", e) entities.append( (m_tls.get_listener_name(listener.id), m_tls.get_tls_server([cert['id'] for cert in certificates], auth_name, listener.client_authentication))) entities.extend([(cert['id'], cert['as3']) for cert in certificates]) # add profile if CONF.f5_agent.profile_l4: service_args['profileL4'] = as3.BigIP(CONF.f5_agent.profile_l4) if CONF.f5_agent.profile_multiplex: service_args['profileMultiplex'] = as3.BigIP( CONF.f5_agent.profile_multiplex) if listener.connection_limit > 0: service_args['maxConnections'] = listener.connection_limit # Add default pool if listener.default_pool_id: pool = listener.default_pool if pool.provisioning_status != lib_consts.PENDING_DELETE: default_pool = m_pool.get_name(listener.default_pool_id) service_args['pool'] = default_pool # only consider Proxy pool, everything else is determined by listener type if pool.protocol == const.PROTOCOL_PROXY: name, irule = m_irule.get_proxy_irule() service_args['iRules'].append(name) entities.append((name, irule)) # Support of backup members (realized as fallback host via http_profile), pick the first one backup_members = [ member for member in pool.members if member.backup ] if backup_members: http_profile_name = m_member.get_name(backup_members[0].id) http_profile = as3.HTTP_Profile( fallbackRedirect=backup_members[0].ip_address) service_args['profileHTTP'] = as3.Pointer(http_profile_name) entities.append((http_profile_name, http_profile)) # Pool member certificate handling (TLS backends) if pool.tls_enabled: client_cert = None trust_ca = None crl_file = None service_args['clientTLS'] = m_tls.get_pool_name(pool.id) certificates = cert_manager.get_certificates(pool) if len(certificates) == 1: cert = certificates.pop() entities.append((cert['id'], cert['as3'])) client_cert = cert['id'] if pool.ca_tls_certificate_id: trust_ca, secret = cert_manager.load_secret( project_id, pool.ca_tls_certificate_id) entities.append( (trust_ca, m_cert.get_ca_bundle(secret, trust_ca, trust_ca))) if pool.crl_container_id: # TODO: CRL currently not supported pass entities.append((m_tls.get_pool_name(pool.id), m_tls.get_tls_client(trust_ca=trust_ca, client_cert=client_cert, crl_file=crl_file))) # Insert header irules for name, irule in m_irule.get_header_irules(listener.insert_headers): service_args['iRules'].append(name) entities.append((name, irule)) # session persistence if listener.default_pool_id and listener.default_pool.session_persistence: persistence = listener.default_pool.session_persistence lb_algorithm = listener.default_pool.lb_algorithm if persistence.type == 'APP_COOKIE': name, obj_persist = m_persist.get_app_cookie( persistence.cookie_name) service_args['persistenceMethods'] = [as3.Pointer(name)] entities.append((name, obj_persist)) if lb_algorithm == 'SOURCE_IP': service_args['fallbackPersistenceMethod'] = 'source-address' elif persistence.type == 'SOURCE_IP': if not persistence.persistence_timeout and not persistence.persistence_granularity: service_args['persistenceMethods'] = ['source-address'] else: name, obj_persist = m_persist.get_source_ip( persistence.persistence_timeout, persistence.persistence_granularity) service_args['persistenceMethods'] = [as3.Pointer(name)] entities.append((name, obj_persist)) elif persistence.type == 'HTTP_COOKIE': service_args['persistenceMethods'] = ['cookie'] if lb_algorithm == 'SOURCE_IP': service_args['fallbackPersistenceMethod'] = 'source-address' # Map listener tags to ESDs for tag in listener.tags: # get ESD of same name esd = esd_repository.get_esd(tag) if esd is None: continue # enrich service with iRules and other things defined in ESD esd_entities = get_esd_entities(service_args['_servicetype'], esd) for entity_name in esd_entities: if entity_name == 'iRules': service_args['iRules'].extend(esd_entities['iRules']) else: service_args[entity_name] = esd_entities[entity_name] # Map special L7policies to ESDs # TODO: Remove this as soon as all customers have migrated their scripts. # Triggering ESDs via L7policies is considered deprecated. Tags should be used instead. See the code above. for policy in listener.l7policies: # get ESD of same name esd = esd_repository.get_esd(policy.name) # Add ESD or regular endpoint policy if esd: # enrich service with iRules and other things defined in ESD esd_entities = get_esd_entities(service_args['_servicetype'], esd) for entity_name in esd_entities: if entity_name == 'iRules': service_args['iRules'].extend(esd_entities['iRules']) else: service_args[entity_name] = esd_entities[entity_name] elif policy.provisioning_status != lib_consts.PENDING_DELETE: # add a regular endpoint policy policy_name = m_policy.get_name(policy.id) # make endpoint policy object endpoint_policy = (policy_name, m_policy.get_endpoint_policy(policy)) entities.append(endpoint_policy) # reference endpoint policy object in service service_args['policyEndpoint'].append(policy_name) # Ensure no duplicate iRules service_args['iRules'] = list(set(service_args['iRules'])) # create service object and fill in additional fields service = as3.Service(**service_args) # add service to entities and return entities.append((get_name(listener.id), service)) return entities