
    Vh5                        d Z dZdZddlZ	 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 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zedk(  r e        yy# e$ r Y ow xY w)a  
module: waf_rule
short_description: Create and delete WAF Rules
version_added: 1.0.0
description:
  - Read the AWS documentation for WAF
    U(https://aws.amazon.com/documentation/waf/).
  - Prior to release 5.0.0 this module was called C(community.aws.aws_waf_rule).
    The usage did not change.

author:
  - Mike Mochan (@mmochan)
  - Will Thames (@willthames)

options:
  name:
    description: Name of the Web Application Firewall rule.
    required: true
    type: str
  metric_name:
    description:
      - A friendly name or description for the metrics for the rule.
      - The name can contain only alphanumeric characters (A-Z, a-z, 0-9); the name may not contain whitespace.
      - You can't change I(metric_name) after you create the rule.
      - Defaults to the same as I(name) with disallowed characters removed.
    type: str
  state:
    description: Whether the rule should be present or absent.
    choices: ['present', 'absent']
    default: present
    type: str
  conditions:
    description: >
      List of conditions used in the rule. M(community.aws.waf_condition) can be used to create new conditions.
    type: list
    elements: dict
    suboptions:
      type:
        required: true
        type: str
        choices: ['byte','geo','ip','size','sql','xss']
        description: The type of rule to match.
      negated:
        required: true
        type: bool
        description: Whether the condition should be negated.
      condition:
        required: true
        type: str
        description: The name of the condition.  The condition must already exist.
  purge_conditions:
    description:
      - Whether or not to remove conditions that are not passed when updating I(conditions).
    default: false
    type: bool
  waf_regional:
    description: Whether to use C(waf-regional) module.
    default: false
    required: false
    type: bool

extends_documentation_fragment:
  - amazon.aws.common.modules
  - amazon.aws.region.modules
  - amazon.aws.boto3
a  
- name: create WAF rule
  community.aws.waf_rule:
    name: my_waf_rule
    conditions:
      - name: my_regex_condition
        type: regex
        negated: false
      - name: my_geo_condition
        type: geo
        negated: false
      - name: my_byte_condition
        type: byte
        negated: true

- name: remove WAF rule
  community.aws.waf_rule:
    name: "my_waf_rule"
    state: absent
a=  
rule:
  description: WAF rule contents
  returned: always
  type: complex
  contains:
    metric_name:
      description: Metric name for the rule.
      returned: always
      type: str
      sample: ansibletest1234rule
    name:
      description: Friendly name for the rule.
      returned: always
      type: str
      sample: ansible-test-1234_rule
    predicates:
      description: List of conditions used in the rule.
      returned: always
      type: complex
      contains:
        data_id:
          description: ID of the condition.
          returned: always
          type: str
          sample: 8251acdb-526c-42a8-92bc-d3d13e584166
        negated:
          description: Whether the sense of the condition is negated.
          returned: always
          type: bool
          sample: false
        type:
          description: type of the condition.
          returned: always
          type: str
          sample: ByteMatch
    rule_id:
      description: ID of the WAF rule.
      returned: always
      type: str
      sample: 15de0cbc-9204-4e1f-90e6-69b2f415c261
    N)camel_dict_to_snake_dict)MATCH_LOOKUP)get_web_acl_with_backoff) list_regional_rules_with_backoff)#list_regional_web_acls_with_backoff)list_rules_with_backoff)list_web_acls_with_backoff)"run_func_with_change_token_backoff)AnsibleCommunityAWSModulec                 f    t        | |      D cg c]  }|d   |k(  s|d    }}|r|d   S y c c}w )NNameRuleIdr   )
list_rules)clientmodulenamedruless        j/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/aws/plugins/modules/waf_rule.pyget_rule_by_namer      sB    ",VV"<RQ&	T@QQx[RERQx  Ss   ..c                     	 | j                  |      d   S # t        j                  j                  t        j                  j                  f$ r}|j                  |d       Y d }~y d }~ww xY w)N)r   RulezCould not get WAF rulemsg)get_rulebotocore
exceptionsClientErrorBotoCoreErrorfail_json_aws)r   r   rule_ides       r   r   r      sa    >g.v66++X-@-@-N-NO >Q$<==>s    7A+A&&A+c                    | j                   j                  dk(  r	 t        |       S | j                   j                  dk(  r	 t        |       S y # t        j                  j
                  t        j                  j                  f$ r}|j                  |d       Y d }~y d }~ww xY w# t        j                  j
                  t        j                  j                  f$ r}|j                  |d       Y d }~y d }~ww xY w)NWAFCould not list WAF rulesr   WAFRegionalz!Could not list WAF Regional rules)		__class____name__r   r   r   r   r   r    r   r   r   r"   s      r   r   r      s      E)	D*622 
			"	"m	3	M3F;; 
4 ##//1D1D1R1RS 	D  (B CC	D
 ##//1D1D1R1RS 	M  (K LL	Ms/   
A  
B# 7B BB #7C7C22C7c                     	 t        |       S # t        j                  j                  t        j                  j                  f$ r}|j                  |d       Y d }~y d }~ww xY w)Nr%   r   )r   r   r   r   r   r    r)   s      r   list_regional_rulesr+      sY    @/77++X-@-@-N-NO @Q$>??@s   
 7A!AA!c           	         t        | ||      }|d   }t        d t        D              }t        d t        D              }t               }t        D ]  }dt        |   d   z   dz   }t               ||<   	 | j                  |      }	|	j	                         j
                  }
	  |
       t        |   d   dz      }D ]?  }|t        |   d   dz      |d<   t        |      ||   |d   <   t        |      ||   |d   <   A  |j                  d   D ]  }|||d      |d   <    t        d t        j                          D              }|d   D ]  }t        |      |||d         |d   <    t#               }t#               }|D ]p  }||   j!                         D ]X  \  }}|||   vr|j%                  d| d| d
       ||   |   d   |d<   |d   ||   vs?|j'                  t)        |             Z r |j                  d   rS|D ]N  }|j+                  ||   j-                         D cg c]   }||   |d      d   ||   vrt/        |      " c}       P t1        |xs |      }|||z   d}|r	 t3        | ||| j4                  d       |t        | ||      fS # t        t        j                  j                  f$ r t        | |      }
Y (w xY w# t        j                  j                  t        j                  j                  f$ r"}|j                  |d| d	
       Y d }~hd }~ww xY wc c}w # t        j                  j                  t        j                  j                  f$ r}|j                  |d
       Y d }~d }~ww xY w)Nr   c              3   4   K   | ]  }|t               f  y wNdict.0condition_types     r   	<genexpr>z'find_and_update_rule.<locals>.<genexpr>   s     [N7[   c              3   4   K   | ]  }|t               f  y wr.   r/   r1   s     r   r4   z'find_and_update_rule.<locals>.<genexpr>   s     Z>~tv6Zr5   list_methodsconditionsetzCould not list z conditionsr   IdDataIdr   
conditionstyper   c              3   0   K   | ]  \  }}|d    |f  yw)r>   N )r2   kvs      r   r4   z'find_and_update_rule.<locals>.<genexpr>   s     "Ufq!AfIq>"Us   
PredicatesTypez
Condition z	 of type z does not existdata_idpurge_conditionsr   UpdatesTwaitz Could not update rule conditions)r   r0   r   get_paginatorpaginatebuild_full_resultKeyErrorr   r   OperationNotPageableErrorgetattrr   r   r    r   paramsitemslist	fail_jsonappendformat_for_insertionextendvaluesformat_for_deletionboolr
   update_rule)r   r   r!   ruleexisting_conditionsdesired_conditionsall_conditionsr3   r8   	paginatorfuncpred_resultsr"   pred	conditionreverse_condition_types
insertions	deletionscondition_namechangedupdates                        r   find_and_update_rulerk      s
   FFG,D8nG[l[[Z\ZZVN& \<7AACG)-~&	+,,V4I%%'99D
	W6,~">~"NQT"TUL ! 	\D!,~">~"NQU"UVDN;STX;YN>*4<8=UVZ=[N>*4>:	\\& ]]<0 M	CL9V,-i.?@M #"U@R@R@T"UU,' 
	_w`
3If4EFG	RZH[\

 JI, C);N)K)Q)Q)S 	C%NI^N%CC  z.1A>JZZi%j k#1.#A.#QR[#\Ii #+>~+NN!!"6y"AB	CC }}'(1 	N &9%H%O%O%Q!%n5i	6JKFS-n=> (	2	 :*+GJ,BCF	L.vvvvGYGY`de HVVW555i (--GGH 	+ 66*D	+ ##//1D1D1R1RS 	W  /.9I(U VV	W< ##//1D1D1R1RS 	L  (J KK	LsH   2+JK	"%L%
*L* /KK	7L" LL"*7M>!M99M>c           	      Z    t        dt        | d   t        | d      d   | d               S )NINSERTnegatedr>   rE   NegatedrD   r<   Action	Predicate)r0   r   rd   s    r   rV   rV     s<    i(|If<M/Nv/V_hir_s
     c           	      F    t        dt        | d   | d   | d               S )NDELETErn   r>   rE   ro   rq   r/   rt   s    r   rY   rY     s/    y3)F:KT]^gThi ru   c                 V   t        | ||      d   }|D cg c]  }t        t        |             }}	 t        | |||d| j                         y c c}w # t
        j                  j                  t
        j                  j                  f$ r}|j                  |d       Y d }~y d }~ww xY w)NrC   rG   z Could not remove rule conditionsr   )
r   rY   r   r
   r[   r   r   r   r   r    )r   r   r!   r=   rd   updatesr"   s          r   remove_rule_conditionsrz     s    &&'2<@JYcdI"#;I#FGdGdH*66gZa;bdjdvdvw e ++X-@-@-N-NO HQ$FGGHs   AA 7B(B##B(c                 
   |j                   d   }t        | ||      }t               }|rt        | ||      S |j                   d   |d<   |j                   d   }|s$t	        j
                  dd|j                   d         }||d<   	 t        | ||| j                        d   }t        | |d
         S # t        j                  j                  t        j                  j                  f$ r}|j                  |d	       Y d }~_d }~ww xY w)Nr   r   metric_namez[^a-zA-Z0-9] 
MetricNamer   zCould not create ruler   r   )rQ   r   r0   rk   resubr
   create_ruler   r   r   r   r    )r   r   r   r!   rQ   r|   new_ruler"   s           r   ensure_rule_presentr     s    == Dvvt4GVF#FFG<<v.vmmM2&&"fmmF6KLK*|	A9&&&RXRdRdeflmH $FFHX4FGG ##//1D1D1R1RS 	A  (? @@	As   B. .7D%C==Dc                    g }	 | j                   j                  dk(  rt        |       }n$| j                   j                  dk(  rt        |       }D ]?  }	 t        | |d         }|d   D cg c]  }|d   	 c}v s,|j                  |d	          A |S # t        j
                  j                  t        j
                  j                  f$ r}|j                  |d       Y d }~d }~ww xY w# t        j
                  j                  t        j
                  j                  f$ r}|j                  |d       Y d }~d }~ww xY wc c}w )
Nr$   r&   zCould not list Web ACLsr   WebACLIdzCould not get Web ACL detailsRulesr   r   )r'   r(   r	   r   r   r   r   r   r    r   rU   )	r   r   r!   web_acls_in_useall_web_aclsr"   web_aclweb_acl_detailsr\   s	            r   find_rule_in_web_aclsr   1  s8   O?$$-5f=L&&-7>vFL   <	I6vwz?RSO /'2JK$tH~KK""?6#:;<  ++X-@-@-N-NO ?Q$=>>?
 ##//1D1D1R1RS 	I  (G HH	IKs6   A	B C**E7C'
C""C'*7D>!D99D>c                    t        | ||j                  d         }t        | ||      }|r6dj                  |      }|j	                  d|j                  d    d|        |r,t        | ||       	 dt        | |d|i| j                  d      fS d
i fS # t        j                  j                  t        j                  j                  f$ r }|j                  |d	       Y d }~d
i fS d }~ww xY w)Nr   z, zRule z is in use by Web ACL(s) r   Tr   rI   zCould not delete ruleF)r   rQ   r   joinrT   rz   r
   delete_ruler   r   r   r   r    )r   r   r!   in_use_web_aclsweb_acl_namesr"   s         r   ensure_rule_absentr   D  s   vvv}}V/DEG+FFGDO		/2uV]]6%:$;;TUbTcdevvw7	A;7 3V5G5Gd  
 "9 ##//1D1D1R1RS 	A  (? @@"9	As   0B 7C)	C$$C)c                     t        t        d      t               t        dddg      t        dd      t        d	d
      t        d	d
            } t        |       }|j                  j                  d      }|j                  d   sdnd}|j	                  |      }|dk(  rt        ||      \  }}nt        ||      \  }}|j                  |t        |             y )NT)requiredpresentabsent)defaultchoicesrS   r0   )r>   elementsrZ   F)r>   r   )r   r|   stater=   rF   waf_regional)argument_specr   r   wafzwaf-regional)ri   r\   )	r0   AnsibleAWSModulerQ   getr   r   r   	exit_jsonr   )r   r   r   resourcer   ri   resultss          r   mainr   U  s    4 F9y(.CDVf5659vu5M M:FMMg&E"MM.9u~H]]8$F	0@'/?'
W+CG+LMru   __main__) DOCUMENTATIONEXAMPLESRETURNr   r   ImportError0ansible.module_utils.common.dict_transformationsr   7ansible_collections.amazon.aws.plugins.module_utils.wafr   r   r   r   r   r	   r
   >ansible_collections.community.aws.plugins.module_utils.modulesr   r   r   r   r   r+   rk   rV   rY   rz   r   r   r   r   r(   r@   ru   r   <module>r      s   AF*)
V 
	 V P \ d g [ ^ f x>
M@B6JHH&&"N, zF y  		s   A8 8B ?B 