
    Vh2L                        d dl mZmZmZ eZdZdZdZd dl	Z	d dl
mZ d dlmZ dZ	 d dlZd dlZd dlZd dlZd dlZdZd d
lmZmZ d dlmZ  G d de      Z d Z!e"dk(  r e!        yy# e$ r  e	j2                         Zd	ZY Dw xY w)    )absolute_importdivisionprint_functiona  
module: nsupdate

short_description: Manage DNS records
description:
  - Create, update and remove DNS records using DDNS updates.
requirements:
  - dnspython
author: "Loic Blot (@nerzhul)"
extends_documentation_fragment:
  - community.general.attributes
attributes:
  check_mode:
    support: full
  diff_mode:
    support: none
options:
  state:
    description:
      - Manage DNS record.
    choices: ['present', 'absent']
    default: 'present'
    type: str
  server:
    description:
      - Apply DNS modification on this server, specified by IPv4 or IPv6 address.
    required: true
    type: str
  port:
    description:
      - Use this TCP port when connecting to O(server).
    default: 53
    type: int
  key_name:
    description:
      - Use TSIG key name to authenticate against DNS O(server).
    type: str
  key_secret:
    description:
      - Use TSIG key secret, associated with O(key_name), to authenticate against O(server).
    type: str
  key_algorithm:
    description:
      - Specify key algorithm used by O(key_secret).
    choices: ['HMAC-MD5.SIG-ALG.REG.INT', 'hmac-md5', 'hmac-sha1', 'hmac-sha224', 'hmac-sha256', 'hmac-sha384', 'hmac-sha512']
    default: 'hmac-md5'
    type: str
  zone:
    description:
      - DNS record will be modified on this O(zone).
      - When omitted DNS will be queried to attempt finding the correct zone.
    type: str
  record:
    description:
      - Sets the DNS record to modify. When zone is omitted this has to be absolute (ending with a dot).
    required: true
    type: str
  type:
    description:
      - Sets the record type.
    default: 'A'
    type: str
  ttl:
    description:
      - Sets the record TTL.
    default: 3600
    type: int
  value:
    description:
      - Sets the record value.
    type: list
    elements: str
  protocol:
    description:
      - Sets the transport protocol (TCP or UDP). TCP is the recommended and a more robust option.
    default: 'tcp'
    choices: ['tcp', 'udp']
    type: str
aI  
- name: Add or modify ansible.example.org A to 192.168.1.1"
  community.general.nsupdate:
    key_name: "nsupdate"
    key_secret: "+bFQtBCta7j2vWkjPkAFtgA=="
    server: "10.1.1.1"
    zone: "example.org"
    record: "ansible"
    value: "192.168.1.1"

- name: Add or modify ansible.example.org A to 192.168.1.1, 192.168.1.2 and 192.168.1.3"
  community.general.nsupdate:
    key_name: "nsupdate"
    key_secret: "+bFQtBCta7j2vWkjPkAFtgA=="
    server: "10.1.1.1"
    zone: "example.org"
    record: "ansible"
    value: ["192.168.1.1", "192.168.1.2", "192.168.1.3"]

- name: Remove puppet.example.org CNAME
  community.general.nsupdate:
    key_name: "nsupdate"
    key_secret: "+bFQtBCta7j2vWkjPkAFtgA=="
    server: "10.1.1.1"
    zone: "example.org"
    record: "puppet"
    type: "CNAME"
    state: absent

- name: Add 1.1.168.192.in-addr.arpa. PTR for ansible.example.org
  community.general.nsupdate:
    key_name: "nsupdate"
    key_secret: "+bFQtBCta7j2vWkjPkAFtgA=="
    server: "10.1.1.1"
    record: "1.1.168.192.in-addr.arpa."
    type: "PTR"
    value: "ansible.example.org."
    state: present

- name: Remove 1.1.168.192.in-addr.arpa. PTR
  community.general.nsupdate:
    key_name: "nsupdate"
    key_secret: "+bFQtBCta7j2vWkjPkAFtgA=="
    server: "10.1.1.1"
    record: "1.1.168.192.in-addr.arpa."
    type: "PTR"
    state: absent
a  
changed:
  description: If module has modified record.
  returned: success
  type: str
record:
  description: DNS record.
  returned: success
  type: str
  sample: 'ansible'
ttl:
  description: DNS record TTL.
  returned: success
  type: int
  sample: 86400
type:
  description: DNS record type.
  returned: success
  type: str
  sample: 'CNAME'
value:
  description: DNS record value(s).
  returned: success
  type: list
  sample: '192.168.1.1'
zone:
  description: DNS record zone.
  returned: success
  type: str
  sample: 'example.org.'
dns_rc:
  description: C(dnspython) return code.
  returned: always
  type: int
  sample: 4
dns_rc_str:
  description: C(dnspython) return code (string representation).
  returned: always
  type: str
  sample: 'REFUSED'
N)Error)errorTF)AnsibleModulemissing_required_lib)	to_nativec                   H    e Zd Zd Zd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zy)RecordManagerc                    || _         |j                  d   rB	 t        j                  j	                  |j                  d   |j                  d   i      | _        nd | _        |j                  d   dk(  rd| _
        n|j                  d   | _
        |j                  d	   G|j                  d
   d   dk7  r| j                   j                  d       | j                         | _        n;|j                  d	   | _        | j                  d   dk7  r| xj                  dz  c_        |j                  d
   d   dk7  r%|j                  d
   dz   | j                  z   | _        n|j                  d
   | _        | j                   j                  d   j                         dk(  r\| j                   j                  d   Ct        t!        | j"                  | j                   j                  d               | _        d| _        y | j                   j                  d   | _        d| _        y # t        $ r |j                  d       Y t        $ r)}|j                  dt        |      z         Y d }~d }~ww xY w)Nkey_name
key_secretzMissing key_secretmsgzTSIG key error: %skey_algorithmhmac-md5HMAC-MD5.SIG-ALG.REG.INTzonerecord.z4record must be absolute when omitting zone parametertypetxtvaluer   )moduleparamsdnstsigkeyring	from_textkeyring	TypeError	fail_jsonbinascii_errorr
   	algorithmlookup_zoner   fqdnlowerlistmap
txt_helperr   dns_rc)selfr   es      n/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/general/plugins/modules/nsupdate.py__init__zRecordManager.__init__   s
   ==$J"88MM*-v}}\/J:    DL==)Z77DN#]]?;DN== (}}X&r*c1%%*`%a((*DIf-DIyy}#		S 	=="2&#-h/#5		ADIh/DI;;f%++-64;;;M;Mg;V;bc$//4;;3E3Eg3NOPDJ  ++G4DJA  ;  %9 :! J  %9IaL%H IIJs   A H I(7I(?I##I(c                 J    |d   dk(  r
|d   dk(  r|S dj                  |      S )Nr   "r   z"{text}")text)format)r-   entrys     r/   r+   zRecordManager.txt_helper   s1    8s?uRyC/L  e ,,    c           	         t         j                  j                  | j                  j                  d         }	 t         j
                  j                  |t         j                  j                        }| j                  r'|j                  | j                  | j                         	 | j                  j                  d   dk(  rRt         j                  j                  || j                  j                  d   d| j                  j                  d         }nQt         j                  j                  || j                  j                  d   d| j                  j                  d         }j3                         t         j2                  j4                  t         j2                  j6                  fv rQ| j                  j%                  d| j                  j                  d   d| j                  j                  d   d       |j8                  D ]U  }|j:                  t         j                  j                  k(  s+|j                  |k(  s;|j                  j=                         c S  |j>                  D ]  }|j:                  t         j                  j                  k(  s+|jA                  |j                        d   t         j                  jB                  k(  se|j                  j=                         c S  	 |jE                         }# t         j                  j                   t         j                  j"                  f$ rJ}| j                  j%                  d	|j&                  j(                  d
t+        |             Y d }~d }~wt,        t         j.                  j0                  f$ rJ}| j                  j%                  d|j&                  j(                  d
t+        |             Y d }~d }~ww xY w# t         j                  jF                  $ r: | j                  j%                  d| j                  j                  d   z         Y Gw xY w)Nr   r!   r%   protocoltcpserver
   porttimeoutr=   TSIG update error (): r   DNS server error: (zZone lookup failure: 'z)' will not respond to queries regarding 'z'.r   z.Zone lookup of '%s' failed for unknown reason.)$r   namer    r   r   message
make_query	rdatatypeSOAr!   use_tsigr%   queryr:   udptsig
PeerBadKeyPeerBadSignaturer#   	__class____name__r
   socket_error	exceptionTimeoutrcodeSERVFAILREFUSEDanswerrdtypeto_text	authorityfullcompareNAMERELN_SUBDOMAINparentNoParent)r-   rC   rI   lookupr.   rrs         r/   r&   zRecordManager.lookup_zone  s   xx!!$++"4"4X">?KK**41B1BCE||t||t~~No;;%%j1U: YY]]5$++2D2DX2NXZaealalasastza{]|F YY]]5$++2D2DX2NXZaealalasastza{]|F
 ||~#))"4"4cii6G6G!HH%%KK&&x0$++2D2DX2N+P% Q mm -99 1 11bggo77??,,-
 && -99 1 11d6F6Frww6OPQ6RVYV^V^VqVq6q77??,,-{{}7  HH'')B)BC o%%!++J^J^`ijk`l*m%nn #--"7"78 o%%!++J^J^`ijk`l*m%nno" 88$$ %%*\`d`k`k`r`rs{`|*}%~s8   $B?K= +O, =7O)4?M99&O)?O$$O),AQQc           	      l   d }	 | j                   j                  d   dk(  rSt        j                  j	                  || j                   j                  d   d| j                   j                  d         }|S t        j                  j                  || j                   j                  d   d| j                   j                  d         }	 |S # t        j                  j                  t        j                  j                  f$ rJ}| j                   j                  d|j                  j                  dt        |      	       Y d }~|S d }~wt        t        j                  j                  f$ rJ}| j                   j                  d
|j                  j                  dt        |      	       Y d }~|S d }~ww xY w)Nr9   r:   r;   r<   r=   r>   r@   rA   r   rB   )r   r   r   rI   r:   rJ   rK   rL   rM   r#   rN   rO   r
   rP   rQ   rR   )r-   updateresponser.   s       r/   __do_updatezRecordManager.__do_update#  s^   	k{{!!*-699==1C1CH1MWY`d`k`k`r`rsy`z={  99==1C1CH1MWY`d`k`k`r`rsy`z={
 	 ##SXX%>%>? 	kKK!!akkFZFZ\efg\h&i!jj  cmm334 	kKK!!akkFZFZ\efg\h&i!jj	ks+   A-C 3AC 7F3>?E&F3)?F..F3c                    ddd}| j                         }|dv r| j                  j                  r| j                  j                  d       |dk(  r7| j	                         | _        | j
                  dk7  rNd| j
                  z  |d<   n;|d	k(  r6| j                         | _        | j
                  dk7  rd
| j
                  z  |d<   | j
                  dk7  rd|d<   |S d|d<   |S d|d<   |S )NFchangedfailed)r      Trf   r   z$Failed to create DNS record (rc: %d)r   rh   z$Failed to update DNS record (rc: %d)rg   rf   )record_existsr   
check_mode	exit_jsoncreate_recordr,   modify_record)r-   resultexistss      r/   create_or_update_recordz%RecordManager.create_or_update_record0  s    "e4##%V{{%%%%d%3{"002;;!#$JT[[$XF5M1"002;;!#$JT[[$XF5M{{a#'x   %)y!
  !&F9r6   c                    t         j                  j                  | j                  | j                  | j
                        }| j                  D ]\  }	 |j                  | j                  j                  d   | j                  j                  d   | j                  j                  d   |       ^ | j                  |      }t         j                  j                   j#                  |      S # t        $ r | j                  j                  d       Y t         j                  j                  $ r | j                  j                  d       Y w xY w)Nr!   keyalgorithmr   ttlr   value needed when state=presentr   Invalid/malformed value)r   ra   Updater   r!   r%   r   addr   r   AttributeErrorr#   rQ   SyntaxError_RecordManager__do_updaterD   MessagerS   )r-   ra   r5   rb   s       r/   rm   zRecordManager.create_recordL  s
   ""499dllQUQ_Q_"`ZZ 		EEE

4;;--h7;;--e4;;--f5 "		E ##F+{{""((22 " M%%*K%L==,, E%%*C%DEs   AC&&%E8EEc           	      	   t         j                  j                  | j                  | j                  | j
                        }| j                  j                  d   j                         dk(  rt         j                  j                  | j                  j                  d   | j                  j                  d         }| j                  r'|j                  | j                  | j
                         	 | j                  j                  d   dk(  rRt         j                  j                  || j                  j                  d   d	| j                  j                  d
         }nQt         j                  j                  || j                  j                  d   d	| j                  j                  d
         }j2                  r|j2                  d   n|j4                  d   }|j6                  D cg c]/  }|j9                         | j:                  vs |j9                         1 }}n@|j=                  | j                  j                  d   | j                  j                  d          | j:                  D ]\  }	 |j?                  | j                  j                  d   | j                  j                  d   | j                  j                  d   |       ^ | j                  j                  d   j                         dk(  rHD ]C  }|j=                  | j                  j                  d   | j                  j                  d   |       E | jE                  |      }	t         j                  jF                  jI                  |	      S # t         j                  j                   t         j                  j"                  f$ rJ}| j                  j%                  d|j&                  j(                  dt+        |             Y d }~Bd }~wt,        t         j.                  j0                  f$ rJ}| j                  j%                  d|j&                  j(                  dt+        |             Y d }~d }~ww xY wc c}w # t@        $ r  | j                  j%                  d       Y 't         j.                  jB                  $ r  | j                  j%                  d       Y bw xY w)Nrs   r   NSr   r8   r9   r:   r;   r<   r=   r>   r@   rA   r   rB   r   ru   rv   rw   )%r   ra   rx   r   r!   r%   r   r   upperrD   rE   rH   rI   r:   rJ   rK   rL   rM   r#   rN   rO   r
   rP   rQ   rR   rV   rY   itemsrX   r   deletery   rz   r{   r|   r}   rS   )
r-   ra   rI   r^   r.   lookup_resultnentries_to_remover5   rb   s
             r/   rn   zRecordManager.modify_record\  s   ""499dllQUQ_Q_"`;;f%++-5 KK**4;;+=+=h+GI[I[\bIcdE||t||t~~No;;%%j1U: YY]]5$++2D2DX2NXZaealalasastza{]|F YY]]5$++2D2DX2NXZaealalasastza{]|F 17FMM!,6CSCSTUCVM6C6I6I kQYY[`d`j`jMj k kMM$++,,X68J8J68RSZZ 		EEE

4;;--h7;;--e4;;--f5 "		E ;;f%++-5* _dkk00:DKK<N<Nv<VX]^_ ##F+{{""((227 HH'')B)BC o%%!++J^J^`ijk`l*m%nn #--"7"78 o%%!++J^J^`ijk`l*m%nno !l " M%%*K%L==,, E%%*C%DEsJ   .B?M3 %!Q"Q",AQ'37Q*?O//&Q?QQ'%S8S
Sc                 v   ddd}| j                         dk(  r|S | j                  j                  r| j                  j                  d       t        j
                  j                  | j                  | j                  | j                        }|j                  | j                  j                  d   | j                  j                  d          | j                  |      }t        j                  j                  j                  |      | _        | j                   dk7  rd|d	<   d
| j                   z  |d<   |S d|d<   |S )NFre   r   Tri   rs   r   r   rg   z Failed to delete record (rc: %d)r   rf   )rj   r   rk   rl   r   ra   rx   r   r!   r%   r   r   r|   rD   r}   rS   r,   )r-   ro   ra   rb   s       r/   remove_recordzRecordManager.remove_record  s   "e41$M ;;!!KK!!$!/""499dllQUQ_Q_"`dkk((2DKK4F4Fv4NO##F+kk))//9;;!#F8>LF5M  !%F9r6   c                    t         j                  j                  | j                  | j                  | j
                        }	 |j                  | j                  j                  d   | j                  j                  d          | j                  |      }t         j                  j                   j#                  |      | _        | j$                  dk(  r| j                  j                  d   dk(  ry	| j&                  D ]D  }	 |j                  | j                  j                  d   | j                  j                  d   |       F | j                  |      }t         j                  j                   j#                  |      | _        | j$                  dk(  r| j/                         ryy	yy# t         j                  j                  $ r?}| j                  j                  dj                  t        |                   Y d }~wd }~ww xY w# t(        $ r  | j                  j                  d
       Y 0t         j*                  j,                  $ r  | j                  j                  d       Y kw xY w)Nrs   r   r   zRecord error: {0}r   r   stateabsent   rv   rw   rh   )r   ra   rx   r   r!   r%   presentr   r   rF   UnknownRdatatyper#   r4   r
   r|   rD   r}   rS   r,   r   rz   rQ   r{   ttl_changed)r-   ra   r.   rb   r5   s        r/   rj   zRecordManager.record_exists  s   ""499dllQUQ_Q_"`	PNN4;;--h79K9KF9ST ##F+kk))//9;;!{{!!'*h6 IINN4;;#5#5h#?ASASTZA[]bcI ''/H++--33H=DK{{a##%3 }}-- 	PKK!!&9&@&@1&N!OO	P & QKK)).O)P}}00 IKK)).G)HIs2   A F" =AH"G>?4G99G>%I%)8I%$I%c           	         t         j                  j                  | j                  | j                  j
                  d         }| j                  r'|j                  | j                  | j                         	 | j                  j
                  d   dk(  rRt         j                  j                  || j                  j
                  d   d| j                  j
                  d         }nQt         j                  j                  || j                  j
                  d   d| j                  j
                  d         }j-                         t         j,                  j.                  k7  r| j                  j                  d       |j0                  r|j0                  d   j2                  n|j4                  d   j2                  }|| j                  j
                  d   k7  S # t         j                  j                  t         j                  j                  f$ rJ}| j                  j                  d	|j                   j"                  d
t%        |             Y d }~d }~wt&        t         j(                  j*                  f$ rJ}| j                  j                  d|j                   j"                  d
t%        |             Y d }~d }~ww xY w)Nr   r8   r9   r:   r;   r<   r=   r>   r@   rA   r   rB   z1Failed to lookup TTL of existing matching record.r   ru   )r   rD   rE   r'   r   r   r!   rH   r%   rI   r:   rJ   rK   rL   rM   r#   rN   rO   r
   rP   rQ   rR   rS   NOERRORrV   ru   rY   )r-   rI   r^   r.   current_ttls        r/   r   zRecordManager.ttl_changed  s   &&tyy$++2D2DV2LM<<NN4<<4>>NJ	k{{!!*-6udkk.@.@.JTV]a]h]h]o]opv]wxudkk.@.@.JTV]a]h]h]o]opv]wx <<>SYY...KK!!&Y!Z.4mmfmmA&**AQAQRSATAXAXdkk00777 ##SXX%>%>? 	kKK!!akkFZFZ\efg\h&i!jjcmm334 	kKK!!akkFZFZ\efg\h&i!jj	ks%   6B?G 7K?I&K8?J==KN)rO   
__module____qualname__r0   r+   r&   r|   rq   rm   rn   r   rj   r    r6   r/   r   r      s8    (T-
B83 -3^0>8r6   r   c                  *   g d} t        t        t        ddddgd      t        dd      t        dd	d
      t        dd      t        ddd      t        dd| d      t        dd d      t        dd      t        ddd      t        ddd
      t        dd dd      t        ddddgd            d      }t        s |j                  t	        d      t
               t        |j                  d         dk(  r|j                  d       t        |      }i }|j                  d   dk(  r|j                         }n"|j                  d   dk(  r|j                         }|j                  |d<   t        j                  j                  |j                        |d<   |d   r |j                  d#i | y t        |j                  |j                  d   |j                  d    |j                  d!   |j                   "      |d<    |j"                  d#i | y )$N)r   r   z	hmac-sha1zhmac-sha224zhmac-sha256zhmac-sha384zhmac-sha512Fr   r   str)requireddefaultchoicesr   T)r   r   5   int)r   r   r   )r   r   no_logr   Ai  r)   )r   r   r   elementsr:   rJ   )r   r;   r=   r   r   r   r   r   r   ru   r   r9   )argument_specsupports_check_mode	dnspython)r   rQ   r   r   zrecord cannot be empty.r   r   r,   
dns_rc_strrg   r   ru   )r   r   r   ru   r   r   )r   dictHAVE_DNSPYTHONr#   r	   DNSPYTHON_IMP_ERRlenr   r   r   rq   r,   r   rS   rX   r   r   rl   )	tsig_algsr   r   ro   s       r/   mainr     s   >I y9hBW^cdE2ubu=5u5UtDz9[`aud?E2uc>eT>t&5Q5%%V[\
 !F$ 1+>J[\
6=="#q(676"FF}}W)%%'	w	9	,//1}}F899,,V]];F<h"6"V[['-}}X'>%+]]6%:$*MM%$8&,ll	4x 	"6"r6   __main__)#
__future__r   r   r   r   __metaclass__DOCUMENTATIONEXAMPLESRETURN	tracebackbinasciir   r$   socketr   rP   r   
dns.updater   	dns.querydns.tsigkeyringdns.messagedns.resolverr   ImportError
format_excansible.module_utils.basicr   r	   +ansible.module_utils.common.text.convertersr
   objectr   r   rO   r   r6   r/   <module>r      s    A @N`/b(
T  , ( 
N
 K AD8F D8N.#b zF A
  ,	,,.Ns   A& &B B