
    Vhs                     b   d dl Z d dlmZ 	 d dlmZ d dlmZ d dlmZ d dlm	Z	 d dlm
Z
 d dlmZ d d	lmZ d
dlmZ d
dlmZ d
dlmZ d
dlmZ d
dlmZ d
dlmZ d
dlmZ d
dlmZ d
dlmZ d
dlmZ d
dlmZ d
dlmZ d
dlmZ d
dlmZ d
dlmZ d
dlmZ d
dlmZ d
dlm Z  d
dlm!Z! d
dlm"Z" d
dlm#Z# d
d lm$Z$ d
d!lm%Z% d
d"lm&Z& d
d#l'm(Z( d
d$l)m*Z* d
d%l+m,Z, d
d&l+m-Z- d
d'l.m/Z/ d
d(l0m1Z1 d)e	e2ef   d*ee2   d+ee2   fd,Z3d-e	e2ef   d+e	e2ef   fd.Z4d-e	e2ef   d+e	e2ef   fd/Z5d-e	e2ef   d+e	e2ef   fd0Z6d1e
e	e2ef      d+e
e	e2ef      fd2Z7d1e
e	e2e2f      d+e
e	e2e2f      fd3Z8 G d4 d5      Z9 G d6 d7e9      Z: G d8 d9e9      Z;d:e	e2ef   d;e	e2ef   d+ee	e2ef      fd<Z<d=e
e	e2ef      d>e
e	e2ef      d+ee
e	e2ef      e
e	e2ef      e
e	e2ef      f   fd?Z=d@e(dAee
e	e2ef         d+e
e	e2ef      fdBZ> G dC dD      Z? G dE dF      Z@dGe
e	e2ef      dHe	e2ef   d+eAfdIZBdJe
e	e2ef      dKe
e	e2ef      d+eAfdLZCdMe	e2ef   dNe	e2ef   d+e	e2ef   fdOZDdPe
e	e2ef      dQe
e	e2ef      d+ee
e	e2ef      e
e	e2ef      e
e	e2ef      e
e2   f   fdRZE G dS dT      ZF G dU dV      ZGy# e$ r Y w xY w)W    N)deepcopy)BotoCoreError)ClientError)Any)Dict)List)Optional)Tuple   )%get_ec2_security_group_ids_from_names)AnsibleELBv2Error)add_listener_certificates)add_tags)convert_tg_name_to_arn)create_listener)create_load_balancer)create_rule)delete_listener)delete_load_balancer)delete_rule)describe_listeners)!describe_load_balancer_attributes)describe_rules)describe_tags)get_elb)modify_listener)modify_load_balancer_attributes)modify_rule)remove_tags)set_ip_address_type)set_rule_priorities)set_security_groups)set_subnets)AnsibleAWSModule)AWSRetry)ansible_dict_to_boto3_tag_list)boto3_tag_list_to_ansible_dict)scrub_none_parameters)
get_waiterconfig
parent_arnreturnc                 "   t        |       } | j                  dddi      }|ddik7  ry | j                  dg       }| ry t        |      dkD  ry |s|S |d   }|j                  dd        |j                  dd       }|ry |s|sy |s|S |s|S ||k7  ry |S )	NTargetGroupStickinessConfigEnabledFTargetGroupsr   r   WeightTargetGroupArn)r   poplen)r*   r+   
stickinesstarget_groupstarget_grouptarget_group_arns         i/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/amazon/aws/plugins/module_utils/elbv2.py_simple_forward_config_arnr:   5   s    fF9Iu;MNJi''JJ~r2M 
=A #LXt$#''(8$?  
 %%    actionc                     | j                  dd      dk7  r| S d| vr| S | j                  dd      }t        | d   |      }|s| S | j                         }|d= ||d<   |S )zx
    Drops a redundant ForwardConfig where TargetGroupARN has already been set.
    (So we can perform comparisons)
    Type forwardForwardConfigr2   N)getr:   copy)r<   r+   arn	newActions       r9   _prune_ForwardConfigrF   e   sy    
 zz&"*f$,d3J
$VO%<j
IC I/""%Ir;   c                 V   | d   dk7  r| S | d   j                  dd      sd| d   d<   | d   j                  dd      sd| d   d<   | d   j                  d	d      r| d   j                  d
d        | d   j                  dd      sd| d   d<   | d   j                  dd      sd| d   d<   | S )Nr>   authenticate-oidcAuthenticateOidcConfigScopeFopenidSessionTimeouti:	 UseExistingClientSecretClientSecretOnUnauthenticatedRequestauthenticateSessionCookieNameAWSELBAuthSessionCookie)rB   r3   r<   s    r9   _prune_secretrT   }   s    f~,,*+//?4<'(1*+//0@%H=C'()9:&'++,EuM'(,,^TB*+//0JERGU'()CD*+//0CUK@Y'()<=Mr;   c                 *    | d   dk7  r| S d| d   d<   | S )Nr>   rH   TrI   rM    rS   s    r9   #_append_use_existing_client_secretnrW      s*    f~,,BFF#$%>?Mr;   actionsc                     t        | d       S )Nc                 &    | j                  dd      S )NOrderr   rB   xs    r9   <lambda>z_sort_actions.<locals>.<lambda>   s    w): r;   keysortedrX   s    r9   _sort_actionsre      s    ':;;r;   c                     t        | d       S )Nc                     | j                  d      | j                  d      | j                  d      | j                  d      | j                  d      fS )NrI   FixedResponseConfigRedirectConfigr2   r>   r\   r]   s    r9   r_   z(_sort_listener_actions.<locals>.<lambda>   sH    EE*+EE'(EE"#EE"#EE&M
 r;   r`   rb   rd   s    r9   _sort_listener_actionsrj      s    
	 	r;   c                      e Zd ZdededdfdZdededdfdZdeddfd	Zdeddfd
Z	de
eef   fdZdee   fdZddZde
eef   fdZdee   ddfdZddZddZdefdZddZddZddZde
eef   fdZddZy)ElasticLoadBalancerV2
connectionmoduler,   Nc                    || _         || _        d| _        d| _        |j                  j                  d      | _        |j                  j                  d      | _        |  |j                  j                  d      | _        |j                  j                  d      | _	        |j                  j                  d      | _
        |j                  j                  d      | _        |j                  j                  d      | _        |j                  j                  d	      *t        |j                  j                  d	            | _        nd | _        |j                  j                  d
      | _        t!        ||| j                        | _        i | _        | j"                  G| j'                         | _        | j)                         | _        | j+                         | j"                  d	<   |j,                  | _        |j.                  | _        |j0                  | _        |j2                  | _        |j4                  | _        |j                  | _        y )NFschemenamesubnet_mappingssubnetsdeletion_protectionip_address_typewaittags
purge_tags)rm   rn   changednew_load_balancerparamsrB   rp   rq   rr   rs   rt   elb_ip_addr_typerv   r&   rw   rx   r   elbelb_attributesget_elb_attributesget_elb_ip_address_typeget_elb_tags
check_mode	exit_json	fail_jsonfail_json_awsfail_json_aws_errorselfrm   rn   s      r9   __init__zElasticLoadBalancerV2.__init__   s   $!&mm''1MM%%f-	%}}001BC}}((3#)==#4#45J#K  & 1 12C DMM%%f-	==V$06v}}7H7H7PQDIDI --++L9:vtyy9 88"&"9"9";D$($@$@$BD!#002DHHV ++))))#11#)#=#= mmr;   elb_arnip_typec                    | j                   syddd}||vry	 t        | j                  |j                  |            }|j                  |g       y# t        t
        f$ r%}| j                  j                  |       Y d}~yd}~ww xY w)
        Wait for load balancer to reach 'active' status

        :param elb_arn: The load balancer ARN
        :return:
        N"load_balancer_ip_address_type_ipv4'load_balancer_ip_address_type_dualstack)ipv4	dualstackLoadBalancerArns)rv   r)   rm   rB   r   r   rn   r   )r   r   r   waiter_nameswaiteres         r9   wait_for_ip_typez&ElasticLoadBalancerV2.wait_for_ip_type   s     yy 9B
 ,&	)1A1A'1JKFKK'K3{+ 	)KK%%a((	)s   8A B!BBc                     | j                   sy	 t        | j                  d      }|j                  |g       y# t        t        f$ r%}| j
                  j                  |       Y d}~yd}~ww xY w)r   Nload_balancer_availabler   rv   r)   rm   r   r   rn   r   r   r   r   r   s       r9   wait_for_statusz%ElasticLoadBalancerV2.wait_for_status   s^     yy	)1JKFKK'K3{+ 	)KK%%a((	)s   )9 A-A((A-c                     | j                   r+	 t        | j                  d      }|j                  |g       yy# t        t        f$ r%}| j
                  j                  |       Y d}~yd}~ww xY w)r   load_balancers_deletedr   Nr   r   s       r9   wait_for_deletionz'ElasticLoadBalancerV2.wait_for_deletion   sb     99-#DOO5MNgY7  ";/ -))!,,-s   )9 A-A((A-c                     t        t        | j                  | j                  d               }t	        d |j                         D              S )z@
        Get load balancer attributes

        :return:
        LoadBalancerArnc              3   J   K   | ]  \  }}|j                  d d      |f  yw)._N)replace).0kvs      r9   	<genexpr>z;ElasticLoadBalancerV2.get_elb_attributes.<locals>.<genexpr>  s$     PAQYYsC(!,Ps   !#)r'   r   rm   r}   dictitems)r   r~   s     r9   r   z(ElasticLoadBalancerV2.get_elb_attributes
  sB     8-dootxxHY?Z[

 P9M9M9OPPPr;   c                 :    | j                   j                  dd      S )zh
        Retrieve load balancer ip address type using describe_load_balancers

        :return:
        IpAddressTypeN)r}   rB   r   s    r9   r   z-ElasticLoadBalancerV2.get_elb_ip_address_type  s     xx||OT22r;   c                 .    | j                         | _        y)zF
        Update the elb_attributes parameter
        :return:
        N)r   r~   r   s    r9   update_elb_attributesz+ElasticLoadBalancerV2.update_elb_attributes!  s    
 #557r;   c                     	 t        | j                  | j                  d   g      d   d   }|S # t        $ r&}| j                  j                  |       Y d}~S d}~ww xY w)z:
        Get load balancer tags

        :return:
        r   )resource_arnsr   TagsN)r   rm   r}   r   rn   r   )r   elb_tagsr   s      r9   r   z"ElasticLoadBalancerV2.get_elb_tags(  sc    	)$T__TXXN_E`DabcdeflmH  ! 	)KK%%a((	)s   +/ 	AAAtags_to_deletec                     	 t        | j                  | j                  d   g|      | _        y# t        $ r%}| j
                  j                  |       Y d}~yd}~ww xY w)z3
        Delete elb tags

        :return:
        r   N)r   rm   r}   ry   r   rn   r   )r   r   r   s      r9   delete_tagsz!ElasticLoadBalancerV2.delete_tags5  sN    	)&tBS9T8UWefDL  	)KK%%a((	)s   *- 	AAAc                     	 t        | j                  | j                  d   g| j                        | _        y# t
        $ r%}| j                  j                  |       Y d}~yd}~ww xY w)z3
        Modify elb tags

        :return:
        r   N)r   rm   r}   rw   ry   r   rn   r   r   r   s     r9   modify_tagsz!ElasticLoadBalancerV2.modify_tagsA  sT    	)#DOOdhh?P6Q5RTXT]T]^DL  	)KK%%a((	)s   47 	A% A  A%c                    	 t        | j                  | j                  d         | _        | j                  r| j                  | j                  d          yy# t        $ r%}| j
                  j                  |       Y d}~Ud}~ww xY w)z-
        Delete elb
        :return:
        r   N)r   rm   r}   ry   r   rn   r   r   r   s     r9   deletezElasticLoadBalancerV2.deleteM  sp    	)/J[A\]DL <<""488,=#>?  ! 	)KK%%a((	)s   (A 	BA??Bc                    g }g }| j                   $| j                   D ]  }|j                  d|i        | j                  | j                  }| j                  d   D ]?  }d|d   i}|j	                  dg       D ]  }d|v s|d   |d<    n |j                  |       A t        d |D              t        d |D              k(  S )zy
        Compare user subnets with current ELB subnets

        :return: bool True if they match otherwise False
        SubnetIdAvailabilityZonesLoadBalancerAddressesAllocationIdc              3   N   K   | ]  }t        |j                                 y wN	frozensetr   r   mappings     r9   r   z8ElasticLoadBalancerV2.compare_subnets.<locals>.<genexpr>y  s     T'9W]]_-T   #%c              3   N   K   | ]  }t        |j                                 y wr   r   r   s     r9   r   z8ElasticLoadBalancerV2.compare_subnets.<locals>.<genexpr>y  s"      \
+2Igmmo&\
r   )rs   appendrr   r}   rB   set)r   subnet_mapping_id_listrr   subnetthis_mappingaddresss         r9   compare_subnetsz%ElasticLoadBalancerV2.compare_subnetsZ  s     "$ <<#,, =&&
F';<= +"22O hh23 	8F&z(:;L!::&=rB !W,3:>3JL0
 #)),7	8 T=STTX[ \
6E\
 Y
 
 	
r;   c                 p    t        | j                  | j                  d   | j                         d| _        y)zP
        Modify elb subnets to match module parameters
        :return:
        r   )SubnetsTN)r#   rm   r}   rs   ry   r   s    r9   modify_subnetsz$ElasticLoadBalancerV2.modify_subnets}  s)    
 	DOOTXX.?%@$,,Wr;   c                     t        | j                  | j                  | j                  j                  j	                  d            | _        | j                         | j
                  d<   y)z:
        Update the elb from AWS
        :return:
        rq   rw   N)r   rm   rn   r{   rB   r}   r   r   s    r9   updatezElasticLoadBalancerV2.update  sI     4??DKK9K9K9O9OPV9WX,,.r;   c                     |y| j                   |k(  ryt        | j                  | j                  d   |       d| _        | j                  | j                  d   |       y)z=
        Modify ELB ip address type
        :return:
        Nr   T)r|   r    rm   r}   ry   r   )r   ip_addr_types     r9   modify_ip_address_typez,ElasticLoadBalancerV2.modify_ip_address_type  sY    
   L0DOOTXX6G-H,Wdhh'89<Hr;   c                 .   t               }| j                  |d<   | j                  |d<   | j                  | j                  |d<   | j                  | j                  |d<   | j
                  | j
                  |d<   | j                  r| j                  |d<   |S )NNamer>   r   r   SubnetMappingsr   )r   rq   typer|   rs   rr   rw   )r   r{   s     r9   _elb_create_paramsz(ElasticLoadBalancerV2._elb_create_params  s    vv   ,&*&;&;F?#<<# $F9+'+';';F#$99!YYF6N r;   c                     | j                         }|j                  d      }t        | j                  |fi |d   | _        d| _        d| _        | j                  | j                  d          y)z9
        Create a load balancer
        :return:
        r   r   Tr   N)r   r3   r   rm   r}   ry   rz   r   )r   r{   rq   s      r9   
create_elbz ElasticLoadBalancerV2.create_elb  sc     ((*zz&!'HHK!%TXX&789r;   r,   N)__name__
__module____qualname__r   r$   r   strr   r   r   r   r   r	   r   r   r   r   r   r   r   boolr   r   r   r   r   r   rV   r;   r9   rl   rl      s     $3  $0@  $T  $D) )c )d )0)s )t )"- - -QDcN Q3# 38d38n 
)$s) 
) 
)
)@!
 !
F/IDcN (:r;   rl   c                   r     e Zd Zdedededdf fdZdeeef   f fdZde	fdZ
dd	Zde	fd
ZddZ xZS )ApplicationLoadBalancerrm   connection_ec2rn   r,   Nc                    t         |   ||       || _        d| _        |j                  j                  d      O	   t        j                         t              |j                  j                  d      | j                        | _	        n |j                  j                  d      | _	        |j                  j                  d      | _        |j                  j                  d      | _        |j                  j                  d      | _        |j                  j                  d      | _        |j                  j                  d	      | _        |j                  j                  d
      | _        |j                  j                  d      | _        |j                  j                  d      | _        |j                  j                  d      | _        |j                  j                  d      | _        | j8                  &| j8                  d   dk7  r| j                  d       yyy# t        $ r9}| j                  t        |      t        j                                Y d}~d}~wt        t         f$ r}| j#                  |       Y d}~d}~ww xY w)\

        :param connection: boto3 connection
        :param module: Ansible module
        applicationsecurity_groupsN)msg	exceptionaccess_logs_enabledaccess_logs_s3_bucketaccess_logs_s3_prefixidle_timeouthttp2http_desync_mitigation_modehttp_drop_invalid_header_fields(http_x_amzn_tls_version_and_cipher_suitehttp_xff_client_portwaf_fail_openr>   zfThe load balancer type you are trying to manage is not application. Try elb_network_lb module instead.r   )superr   r   r   r{   rB   r%   jittered_backoffr   r   
ValueErrorr   r   	traceback
format_excr   r   r   r   r   r   r   r   r   r   r   r   r   r}   )r   rm   r   rn   r   	__class__s        r9   r   z ApplicationLoadBalancer.__init__  s    	V,, "	==./;&'i'Bx'@'@'BCh'iMM%%&78$:M:M($ $*==#4#45F#GD #)==#4#45J#K %+]]%6%67N%O"%+]]%6%67N%O""MM--n=]]&&w/
+1==+<+<=Z+[(/5}}/@/@Ab/c,8>8I8IJt8u5$*MM$5$56L$M!#]]..?88DHHV$4$ENN|   %F#  M3q6Y5I5I5KLL!;/ &""1%%&s$   AH 	J&.IJ,JJc                 x    t         |          }| j                  | j                  |d<   | j                  |d<   |S )NSecurityGroupsScheme)r   r   r   rp   r   r{   r   s     r9   r   z*ApplicationLoadBalancer._elb_create_params  s@    +-+'+';';F#$;;xr;   c                 	   g }| j                   ht        | j                         j                         | j                  d   k7  r5|j	                  dt        | j                         j                         d       | j
                  :| j
                  | j                  d   k7  r|j	                  d| j
                  d       | j                  :| j                  | j                  d   k7  r|j	                  d| j                  d       | j                  ht        | j                        j                         | j                  d   k7  r5|j	                  d	t        | j                        j                         d       | j                  Lt        | j                        | j                  d
   k7  r'|j	                  dt        | j                        d       | j                  ht        | j                        j                         | j                  d   k7  r5|j	                  dt        | j                        j                         d       | j                  ht        | j                        j                         | j                  d   k7  r5|j	                  dt        | j                        j                         d       | j                  ht        | j                        j                         | j                  d   k7  r5|j	                  dt        | j                        j                         d       | j                  ht        | j                        j                         | j                  d   k7  r5|j	                  dt        | j                        j                         d       | j                  ht        | j                        j                         | j                  d   k7  r5|j	                  dt        | j                        j                         d       | j                  ht        | j                        j                         | j                  d   k7  r5|j	                  dt        | j                        j                         d       | S )z~
        Compare user attributes with current ELB attributes
        :return: bool True if they match otherwise False
        access_logs_s3_enabledaccess_logs.s3.enabledKeyValuer   access_logs.s3.bucketr   access_logs.s3.prefixdeletion_protection_enableddeletion_protection.enabledidle_timeout_timeout_secondsidle_timeout.timeout_secondsrouting_http2_enabledrouting.http2.enabled#routing_http_desync_mitigation_mode#routing.http.desync_mitigation_mode/routing_http_drop_invalid_header_fields_enabled/routing.http.drop_invalid_header_fields.enabled8routing_http_x_amzn_tls_version_and_cipher_suite_enabled8routing.http.x_amzn_tls_version_and_cipher_suite.enabled$routing_http_xff_client_port_enabled$routing.http.xff_client_port.enabledwaf_fail_open_enabledwaf.fail_open.enabled)r   r   lowerr~   r   r   r   rt   r   r   r   r   r   r   r   )r   update_attributess     r9   compare_elb_attributesz.ApplicationLoadBalancer.compare_elb_attributes  s    $$0D,,-3359L9LMe9ff$$-EPSTXTlTlPmPsPsPu%vw&&2**d.A.ABY.ZZ$$-DtOiOi%jk&&2**d.A.ABY.ZZ$$-DtOiOi%jk$$0D,,-3359L9LMj9kk$$5DD\D\@]@c@c@ef )D%%&$*=*=>\*]]$$-KVYZ^ZkZkVl%mn::!c$**o&;&;&=ATATUlAm&m$$-DsSWS]S]OdOdOf%gh,,8D445;;=""#HIJ $$=DLlLlHmHsHsHuv 00<D889??A""#TUV $$L !E!EFLLN 99EDAABHHJ""#]^_ $$U !N!NOUUW %%1D--.446$:M:MNt:uu$$>TMfMfIgImImIop *D&&'--/43F3FG^3__$$-DsSWSeSeOfOlOlOn%op$$$r;   c                 
   g }| j                   ht        | j                         j                         | j                  d   k7  r5|j	                  dt        | j                         j                         d       | j
                  :| j
                  | j                  d   k7  r|j	                  d| j
                  d       | j                  :| j                  | j                  d   k7  r|j	                  d| j                  d       | j                  ht        | j                        j                         | j                  d	   k7  r5|j	                  d
t        | j                        j                         d       | j                  Lt        | j                        | j                  d   k7  r'|j	                  dt        | j                        d       | j                  ht        | j                        j                         | j                  d   k7  r5|j	                  dt        | j                        j                         d       | j                  ht        | j                        j                         | j                  d   k7  r5|j	                  dt        | j                        j                         d       | j                  ht        | j                        j                         | j                  d   k7  r5|j	                  dt        | j                        j                         d       | j                  ht        | j                        j                         | j                  d   k7  r5|j	                  dt        | j                        j                         d       | j                  ht        | j                        j                         | j                  d   k7  r5|j	                  dt        | j                        j                         d       | j                  ht        | j                        j                         | j                  d   k7  r5|j	                  dt        | j                        j                         d       |r-	 t        | j                   | j"                  d   |       d| _        yy# t&        $ rJ}| j(                  r#t+        | j                   | j"                  d          | j-                  |       Y d}~yd}~ww xY w)zQ
        Update Application ELB attributes if required

        :return:
        Nr  r  r  r   r
  r   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   T)r   r   r  r~   r   r   r   rt   r   r   r   r   r   r   r   r   rm   r}   ry   r   rz   r   r   r   r  r   s      r9   modify_elb_attributesz-ApplicationLoadBalancer.modify_elb_attributesB  sT     $$0D,,-3359L9LMe9ff$$-EPSTXTlTlPmPsPsPu%vw&&2**d.A.ABY.ZZ$$-DtOiOi%jk&&2**d.A.ABY.ZZ$$-DtOiOi%jk$$0D,,-3359L9LMj9kk$$5DD\D\@]@c@c@ef )D%%&$*=*=>\*]]$$-KVYZ^ZkZkVl%mn::!c$**o&;&;&=ATATUlAm&m$$-DsSWS]S]OdOdOf%gh,,8D445;;=""#HIJ $$=DLlLlHmHsHsHuv 00<D889??A""#TUV $$L !E!EFLLN 99EDAABHHJ""#]^_ $$U !N!NOUUW %%1D--.446$:M:MNt:uu$$>TMfMfIgImImIop *D&&'--/43F3FG^3__$$-DsSWSeSeOfOlOlOn%op&/J[A\^op#  % &))($((CT:UV""1%%	&s   
+R7 7	T
 A TT
c                 b    t        | j                  d         t        | j                        k7  ryy)z
        Compare user security groups with current ELB security groups

        :return: bool True if they match otherwise False
        r  FT)r   r}   r   r   s    r9   compare_security_groupsz/ApplicationLoadBalancer.compare_security_groups  s,     txx()*c$2F2F.GGr;   c                 n    t        | j                  | j                  d   | j                         d| _        y)zX
        Modify elb security groups to match module parameters
        :return:
        r   TN)r"   rm   r}   r   ry   r   s    r9   modify_security_groupsz.ApplicationLoadBalancer.modify_security_groups  s+    
 	DOOTXX6G-H$J^J^_r;   r   )r   r   r   r   r$   r   r   r   r   r   r  r!  r#  r%  __classcell__r   s   @r9   r   r     sb    %3 % %EU %Z^ %NDcN O% O%bY&v	 	r;   r   c                   X     e Zd Zdedededdf fdZdeeef   f fdZd
dZ	d	 Z
 xZS )NetworkLoadBalancerrm   r   rn   r,   Nc                     t         |   ||       || _        d| _        |j                  j                  d      | _        | j                  &| j                  d   dk7  r| j                  d       yyy)r   networkcross_zone_load_balancingNr>   zfThe load balancer type you are trying to manage is not network. Try elb_application_lb module instead.r   )	r   r   r   r   r{   rB   r,  r}   r   )r   rm   r   rn   r   s       r9   r   zNetworkLoadBalancer.__init__  st     	V,, 	)/):):;V)W&88DHHV$4	$ANN|   %Br;   c                 B    t         |          }| j                  |d<   |S )Nr  )r   r   rp   r  s     r9   r   z&NetworkLoadBalancer._elb_create_params  s#    +-;;xr;   c                    g }| j                   ht        | j                         j                         | j                  d   k7  r5|j	                  dt        | j                         j                         d       | j
                  ht        | j
                        j                         | j                  d   k7  r5|j	                  dt        | j
                        j                         d       |r-	 t        | j                  | j                  d   |       d| _	        yy# t        $ rK}| j                  r$t        | j                  | j                  d   	       | j                  |       Y d}~yd}~ww xY w)
zM
        Update Network ELB attributes if required

        :return:
        N!load_balancing_cross_zone_enabledz!load_balancing.cross_zone.enabledr  r  r  r   T)r   )r,  r   r  r~   r   rt   r   rm   r}   ry   r   rz   r   r   r   s      r9   r!  z)NetworkLoadBalancer.modify_elb_attributes  s?     **6D22399;t?R?RSv?ww$$;c$JhJhFiFoFoFqr $$0D,,-3359L9LMj9kk$$5DD\D\@]@c@c@ef &/J[A\^op#  % &))($((SdJef""1%%	&s   .+D 	E/$AE**E/c                 (    | j                  d       y)zf
        Modify elb subnets to match module parameters (unsupported for NLB)
        :return:
        zLModifying subnets and elastic IPs is not supported for Network Load Balancerr   N)r   r   s    r9   r   z"NetworkLoadBalancer.modify_subnets  s     	ijr;   r   )r   r   r   r   r$   r   r   r   r   r!  r   r&  r'  s   @r9   r)  r)    sF    3  EU Z^ &DcN  &Dkr;   r)  current_listenernew_listenerc                    i }| d   }|d   }||k7  r||d<   |dv r| j                  d      }|j                  d      }|rt        | |xr ||k7  f      r||d<   |j                  d      }| j                  d      }|r/t        | |xr |d   d   |d   d   k7  f      rd|d   d   ig|d<   | j                  d      }	|j                  d      }
|
rD|	r=t        |	      t        |
      k(  r&t        d |	D              }|t        |
      k7  r|
|d<   n|
|d<   |j                  d	      }|r8|d
k(  r3| j                  d	      }| d   d
k7  s| d   d
k(  r|r|d   |d   k7  r||d	<   |S )a  
    Compare two listeners. We do not check the port as the function is expecting that
    the two listeners are passed with the same port value.

    :param current_listener: The current listener attributes as stored into AWS
    :param new_listener: The listener as defined into module parameters
    :return: A dict containing the resulting update to perform on the current listener
    Protocol)HTTPSTLS	SslPolicyCertificatesr   CertificateArnDefaultActionsc              3   x   K   | ],  }|j                         D ci c]  \  }}|d v r|| c}} . yc c}}w w))rI   rh   ri   r2   r>   N)r   )r   r^   r   r   s       r9   r   z$_compare_listener.<locals>.<genexpr>'  sL      < 	 !"	1tu qD<s   :4:
AlpnPolicyr6  )rB   anyr4   rj   )r1  r2  modified_listenercurrent_protocolnew_protocolcurrent_ssl_policynew_ssl_policynew_certificatescurrent_certificatescurrent_default_actionsnew_default_actionscurrent_actions_sortednew_alpn_policycurrent_alpn_policys                 r9   _compare_listenerrJ    s     (
3
+L<'(4*% ''-11+>%))+6c##%7%`<NR`<`a
 .<k* (++N;/33NC(($ g(+,<=AQRSATUeAff!
 3CDTUVDWXhDi1j0kn-
 /223CD&**+;<"s+B'CsK^G_'_%; < 1< &" &)?@S)TT6I!"23 3F./ #&&|4O<50.22<@J'50Z(E1(,?,BoVWFX,X.=l+r;   current_listenersnew_listenersc                 @   g }g }t        |      }| D ]  t        fdt        |      D        d      }|dk(  r|j                  d          ;|j	                  |      }t        |      }|s[|j                  d   d   d       |j                  |        |||fS )aj  
    This function groups listeners.
    - listeners to add: any new listener from module parameters not present of the current listeners stored in AWS resource.
    - listeners to delete: any listener currently stored in AWS resource and not present of the module parameters.
    - listeners to modify: any listener present in both list but with different properties.
    The listener key is the Port value.

    :param current_listeners: The current listeners stored into AWS.
    :param new_listeners: The listeners as defined into module parameters.
    :return: A dict containing 3 lists of listeners groups.
    c              3   R   K   | ]  \  }}t        |d          d    k(  s|   yw)PortN)int)r   ilistenerr1  s      r9   r   z#_group_listeners.<locals>.<genexpr>X  s-     s;1hXfEUAVZjkqZrArQss   ''ListenerArnrO  )rO  rT  )r   next	enumerater   r3   rJ  r   )	rK  rL  listeners_to_modifylisteners_to_deletelisteners_to_addidx
m_listenerr>  r1  s	           @r9   _group_listenersr\  C  s     . . :s),<"=suw
 "9&&'7'FG%))#.
-.>
K$$.>v.FWghuWv%wx&&'89:  02EEEr;   rn   	listenersc                    g }|s|S i }|D ]s  }t        |      }t        |d      }d|v r	|d   g|d<   |d   D ]3  }|j                  dd       }|s||vrt        | ||      ||<   ||   |d<   5 |j	                  |       u |S )NF)descend_into_listsr<  r:  TargetGroupNamer2   )r   r(   r3   r   r   )	rm   rn   r]  updated_listenerstarget_group_mappingitemrR  r<   tg_names	            r9   _prepare_listenersre  i  s        +D>(eL8#&.|&<%=H\" /0 	IFjj!2D9G"664J:W]_f4g(1+?+H'(	I 	  *+  r;   c                       e Zd ZdedededdfdZddZdede	e   fd	Z
deeeeef      eeeef      eeeef      f   fd
Zy)ELBListenersrm   rn   r   r,   Nc                     || _         || _        || _        t        |||j                  j                  d            | _        | j                          |j                  j                  d      | _        d| _	        y )Nr]  purge_listenersF)
rm   rn   r   re  r{   rB   r]  r   ri  ry   )r   rm   rn   r   s       r9   r   zELBListeners.__init__  s_    $+J@Q@QR]@^_%}}001BCr;   c                 P    t        | j                  | j                        | _        y)zD
        Update the listeners for the ELB

        :return:
        )load_balancer_arnN)r   rm   r   rK  r   s    r9   r   zELBListeners.update  s     "4DOOW[WcWc!dr;   listener_portc                 L    d }| j                   D ]  }|d   |k(  s|d   } |S  |S )NrO  rT  )rK  )r   rl  listener_arnrR  s       r9   #get_listener_arn_from_listener_portz0ELBListeners.get_listener_arn_from_listener_port  sD    .. 	H=0'6		 r;   c                     t        | j                  | j                        \  }}}||z   D ]  }|j                  dd        | j                  r|ng }|||fS )zThis function call the _group_listeners method and update the listeners
        to delete depending on the value set on `purge_listeners` parameter.
        RulesN)r\  rK  r]  r3   ri  )r   rY  rW  rX  rR  s        r9   compare_listenerszELBListeners.compare_listeners  sq     FV""DNNF
B-/B
 )+>> 	(HLL$'	( 6:5I5I1r!46IIIr;   r   )r   r   r   r   r$   r   r   r   rP  r	   ro  r
   r   r   rr  rV   r;   r9   rg  rg    s    3 0@ 3 SW e RU J5d38n)=tDcN?SUYZ^_bdg_gZhUi)i#j Jr;   rg  c            
       V    e Zd Zdededeeef   deddf
dZdefdZdd	Z	dd
Z
ddZy)ELBListenerrm   rn   rR  r   r,   Nc                 <    || _         || _        || _        || _        y)zm

        :param connection:
        :param module:
        :param listener:
        :param elb_arn:
        N)rm   rn   rR  r   )r   rm   rn   rR  r   s        r9   r   zELBListener.__init__  s      % r;   c                 d    t        | j                  | j                  fi | j                  d   d   S )Nr   rT  )r   rm   r   rR  r   s    r9   r   zELBListener.create_listener  s+    tNNqQR_``r;   c                     | j                   j                  dg       }g g }}t        |      dkD  r|d   |dd  }}|g| j                   d<   | j                         }|D ]  }t	        | j
                  ||g        y )Nr8  r   r   )rn  certificates)rR  rB   r4   r   r   rm   )r   listener_certificatesfirst_certificateother_certsrn  certs         r9   addzELBListener.add  s     $ 1 1." E)+R;$%)-B1-EG\]^]_G`{->,?DMM.)++- 	gD%dooL`d_ef	gr;   c                 ~    | j                   j                  d      }t        | j                  fd|i| j                    y )NrT  rn  )rR  r3   r   rm   )r   rn  s     r9   modifyzELBListener.modify  s0    }}((7TlTdmmTr;   c                 D    t        | j                  | j                         y r   )r   rm   rR  r   s    r9   r   zELBListener.delete  s    7r;   r   )r   r   r   r   r$   r   r   r   r   r}  r  r   rV   r;   r9   rt  rt    sW    3 0@ DQTVYQYN eh mq a agU8r;   rt  current_conditions	conditionc                    d}d}t        |      }|D ]  }||v st        ||   d         ||   d<     d|v rt        |d         |d<   | D ]|  }|d   |d   k7  r|j                  d      r1|j                  d      r t        |d   d         |d   d   k(  sMd} |S |j                  d      r2t        |d   d         |d   d   k(  s~|d   d   |d   d   k(  sd} |S |j                  d	      r t        |d	   d         |d	   d   k(  sd} |S |j                  d
      r2|j                  d
      r!t        |d
   d         |d
   d   k(  sd} |S |j                  d      r|d   d   |d   d   k(  s-d} |S |j                  d      r!t        |d   d         |d   d   k(  s_d} |S t        |d         |d   k(  szd} |S  |S )a  This function checks if the condition is part of the list of current condition

    Parameters:
    current_conditions: The list of conditions
    condition: The condition we are trying to find into the list

    Returns:
    True if the condition is part of the list, False if not.
    F)HostHeaderConfigHttpHeaderConfigHttpRequestMethodConfigSourceIpConfigPathPatternConfigValuesFieldr  Tr  HttpHeaderNamer  r  QueryStringConfigr  )r   rc   rB   )r  r  condition_foundcompare_keyss_conditionra   current_conditions          r9   _check_rule_conditionr    s    OL 9%K L+)/C0@0J)KKX&L ; &{8'< =H/ .W%W)==   !34I[9\'(:;HEF+VhJijrJss"&L K ""#56();<XFG;WiKjksKtt%&89:JK123CDE #'< ; ""#<=()BCHMN89(CD #'. ' ""#67KOOL_<`'(;<XFG;WjKkltKuu"&   ""#67 !45h?;ObCcdlCmm"&  ""#34'(89(CDTdHefnHoo"& 	 %h/0K4II"Oa.` r;   current_actionsnew_actionsc                 ^   t        |       t        |      k7  ryt        |       }t        t        |            }|D cg c]  }t        |       }}|D cg c]  }t	        |       }}|D cg c]  }t        |       c}|D cg c]  }t        |       c}k(  S c c}w c c}w c c}w c c}w )a  This function compares current_actions with new_actions.
    Bfore to the comparison, the function will set the default values for some attributes of the new actions
    as these are not part of the module parameters.

    Parameters:
    current_actions: The current AWS rule actions
    new_actions: The rule actions from module parameters.

    Returns:
    True if the current_actions and new_actions are equal, False if not.
    F)r4   re   r   rW   rT   rF   )r  r  rG  new_actions_sortedrQ  new_current_actions_sortednew_actions_sorted_no_secrets          r9   _compare_rule_actionsr  &  s     ?s;// +?;&x'<=Rh!iQ"Ea"H!i!i>P#QM!$4#Q #Q-GH #H)EM$%QM   "j#QH Ms   BB ,B%B*current_rulenew_rulec                     i }t        | d         t        |d         k7  r|d   |d<   t        | d   |d         }|s|d   |d<   |d   D cg c]  }t        | d   |      r| }}|r||d<   |S c c}w )a&  This function compares rule_a with rule_b and returns differences
    between the two rules as a dictionnary

    Parameters:
    current_rule: The current listener rule stored in AWS.
    new_rule: The new listener rule.

    Returns:
    A dictionnary containing the modified attributes.
    PriorityActions
Conditions)rP  r  r  )r  r  modified_ruleactions_matchcmodified_conditionss         r9   _compare_ruler  D  s     M <
#$HZ,@(AA$,Z$8j! *,y*A8ICVWM#+I#6i  L)1F|T`Gacd1e  &9l#s   A/ A/current_rulesrulesc                    g }g }t        |      }g }t        |       }g }|r|j                  d      }|j                  dd      r&d}	|D ]  }
t        ||
      }|s|j	                  |
       d}	 na|s)t        |j                               dgk(  sGt        |
d         |d<   |d   |d<   |j                  |       d}	|j	                  |
        n |	r|j                  |       |r|D ]  }d}|D ]  }
|d   t        |
d         k(  sd}|j	                  |
       t        ||
      }|r|t        |d         |d<   |d   |d<   |
d   |d<   |
d   |d<   |j                  dg       D ]-  }|j                  d	i       j                  d
d      s&d|d	   d<   / |j                  |        n |r|j                  dd      r|j                  |d           ||||fS )a%  This function compares listener rules from AWS with module provided listener rules and a matrix with the
    following:
        - Rules to add: a rule is added when it is part of the module parameters and not currently stored on AWS
        - Rules to set priority: Any rule with unchanged attributes but with a different priority value
        - Rules to modify: Any rule on which one the following attribute has changed 'Actions', 'Conditions'
        - Rules to delete: Any rule currently stored on AWS and not defined in module parameters.

    Parameters:
    current_rules: The current listener rules stored in AWS.
    rules: The new listener rules.

    Returns:
    A tuple with a list of rules to add, a list of rules to set priority, a list of rules to modify and a list of rules to delete
    r   	IsDefaultFTr  RuleArnr  r  rI   rN   rM   )
r   r3   rB   r  removelistkeysrP  r   r   )r  r  rules_to_modifyrules_to_deleterules_to_addrules_to_set_priority_current_rulesremaining_rulesr  to_keepr  r  current_rule_passed_to_moduler<   s                 r9   _group_rulesr  e  sB   $ OOE?L m,NO
%))!,K/$ 	H),AM  ##H-m&8&8&:!;
|!K,/0D,Ej)+7	+Bi(%,,];##H-!	" ""<01 4 ( <(-%$ 	HJ'3x
/C+DD04-##H- -lH E 03L4L0MM*-/;I/FM),/7	/BM),2:<2HM,/"/"3"3Ir"B `!::&>CGGX]^Z_F#;<=VW` $**=9!	& -\5E5EkSX5Y""<	#:;-<0 .PPr;   c                       e Zd Zdededee   deeeef      ddf
dZ	deeeef      deeeef      fd	Z
deeeeef      eeeef      eeeef      ee   f   fd
Zy)ELBListenerRulesrm   rn   rn  listener_rulesr,   Nc                     || _         || _        | j                  |      | _        d| _        || _        t        | j                   |      | _        y )NF)rT  )rm   rn   _ensure_rules_action_has_arnr  ry   rn  r   r  )r   rm   rn   rn  r  s        r9   r   zELBListenerRules.__init__  sF     %66~F
(+DOOVr;   r  c                     g }|D ]c  }g }|d   D ]A  }d|v r*t        | j                  | j                  |d         |d<   |d= |j                  |       C ||d<   |j                  |       e |S )aI  
        If a rule Action has been passed with a Target Group Name instead of ARN, lookup the ARN and
        replace the name.

        :param rules: a list of rule dicts
        :return: the same list of dicts ensuring that each rule Actions dict has TargetGroupArn key. If a TargetGroupName key exists, it is removed.
        r  r`  r2   )r   rm   rn   r   )r   r  fixed_rulesrulefixed_actionsr<   s         r9   r  z-ELBListenerRules._ensure_rules_action_has_arn  s      
	%DMy/ -$./Ef=N6O0F+, 01$$V,- ,DOt$
	% r;   c                 >   t        | j                  | j                        \  }}}}|D ]d  }|j                  dg       D ]-  }|j                  di       j                  dd      s&d|d   d<   / | j                  |d<   t        |d         |d<   f |D ]  }|d=  ||||fS )a-  This function creates the rule matrix (to add, to set priority, to modify, to delete)
        and prepare them to be ready for AWS API call.

        Returns:
        A tuple with a list of rules to add, a list of rules to set priority, a list of rules to modify and a list of rules to delete
        r  rI   rM   FrT  r  )r  r  r  rB   rn  rP  )r   r  r  r  r  r  r<   s          r9   compare_ruleszELBListenerRules.compare_rules  s     Q]

Q
M+_o ! 	5D((9b1 X::6;??@Y[`aRWF345NOX #'"3"3D"4
#34D	5 $ 	!DZ 	! 2O_TTr;   )r   r   r   r   r$   r	   r   r   r   r   r  r
   r  rV   r;   r9   r  r    s    WW !W sm	W
 T#s(^,W 
W$tCH~2F 4PTUXZ]U]P^K_ 0U	tDcN#T$sCx.%94S#X;OQUVYQZZ	[Ur;   r  c            
           e Zd ZddZdeeef   ddfdZdeeef   ddfdZdeddfdZ	d	e
eeef      ddfd
Zde
eeef      de
eeef      de
eeef      de
e   def
dZy)ELBListenerRuler,   Nc                      || _         || _        y r   )rm   rn   r   s      r9   r   zELBListenerRule.__init__  s    $r;   r  c                     |j                  d      }|j                  d      }|j                  d      }|j                  d      }|j                  dd      }t        | j                  |||||       y)z:
        Create a listener rule

        :return:
        rT  r  r  r  r   N)rn  
conditionsrX   rw   priority)r3   r   rm   )r   r  rn  r  r  rX   rw   s          r9   createzELBListenerRule.create   sj     xx.XXl+
88J'((9%xx%OO%!	
r;   c                 V    |j                  d      }t        | j                  fd|i| y)z:
        Modify a listener rule

        :return:
        r  rule_arnN)r3   r   rm   )r   r  r  s      r9   r  zELBListenerRule.modify  s(     88I&DOO?h?$?r;   r  c                 0    t        | j                  |       y)z:
        Delete a listener rule

        :return:
        N)r   rm   )r   r  s     r9   r   zELBListenerRule.delete  s     	DOOX.r;   r  c           	      h    t        | j                  |D cg c]  }|d   |d   d c}       yc c}w )zO
        Sets the priorities of the specified rules.

        :return:
        r  r  )r  r  N)r!   rm   )r   r  r  s      r9   r!   z#ELBListenerRule.set_rule_priorities%  s3     	OOejk]a$y/tJGWXk	
ks   /
rules_to_creater  r  r  c                    d}|r| j                  |       d}| j                  j                  d   r|D ]  }| j                  |       d} |D ]  }| j	                  |       d} |D ]  }| j                  |       d} |S )NFTpurge_rules)r!   rn   r{   r   r  r  )r   r  r  r  r  ry   rD   r  s           r9   process_ruleszELBListenerRule.process_rules/  s      $$%:;G;;m,& C  $ 	DKKG	 $ 	DKKG	 r;   r   )r   r   r   r   r   r   r   r  r  r   r   r!   r   r  rV   r;   r9   r  r    s    
4S> 
d 
(@4S> @d @/s /t /
d38n)= 
$ 
d38n-  $DcN3 d38n-	
 c 
r;   r  )Hr   rC   r   botocore.exceptionsr   r   ImportErrortypingr   r   r   r	   r
   ec2r   	elb_utilsr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   modulesr$   retriesr%   taggingr&   r'   transformationr(   waitersr)   r   r:   rF   rT   rW   re   rj   rl   r   r)  rJ  r\  re  rg  rt  r   r  r  r  r  r  r  rV   r;   r9   <module>r     s    	1/      6 ( 0  - & + " & + " ) 8 % $  & 6 " " * * * " %  3 3 1 ,tCH~ ,8C= ,U]^aUb ,`c3h DcN 0$sCx. T#s(^ 0S#X 4S> <4S#X/ <Dc3h4H <
Dc3h$8 
T$sCx.=Q 
N: N:bn3 nbCk/ CkLIS#X Id3PS8n IYabfgjlogobpYq IX#FDcN+#F<@c3h<P#F
4S#Xd38n!5tDcN7KKL#FL(5=d4S>>R5S	$sCx.<'J 'JT$8 $8NKd4S>.B KtTWY\T\~ Kbf K\4S#X+? dSWX[]`X`SaNb gk <S#X $sCx. TRUWZRZ^ BMQS#X'MQ04T#s(^0DMQ
4S#Xd38n!5tDcN7KTRUYVWMQ`CU CULI I_'  		s   J% %J.-J.