
    =                        S r SSKJr  SSKJr  SSKJr  SSKrSSKJr  SSK	J
r
  SSK	Jr  SS	KJr  SS
KJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKr\R.                  " 5          " S S\R0                  5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      rS rS rS)S jrS r S*S jr!S+S jr"S+S jr#S r$  S,S  jr%S+S! jr&S+S" jr'S+S# jr(S$ r)S+S% jr*S+S& jr+S' r,    S-S( jr-g).z)Helper methods for importing record-sets.    )absolute_import)division)unicode_literalsN)encoding)	rdatatype)zone)record_types)	svcb_stub)apis)
exceptions)yamlc                       \ rS rSrSrSrg)Error(   z%Base exception for all import errors. N__name__
__module____qualname____firstlineno____doc____static_attributes__r       -lib/googlecloudsdk/api_lib/dns/import_util.pyr   r   (   s    -r   r   c                       \ rS rSrSrSrg)RecordsFileNotFound,   z)The specified records file was not found.r   Nr   r   r   r   r   r   ,   s    1r   r   c                       \ rS rSrSrSrg)RecordsFileIsADirectory0   z*The specified records file is a directory.r   Nr   r   r   r   r   r   0   s    2r   r   c                       \ rS rSrSrSrg)UnableToReadRecordsFile4   z;Unable to read record sets from the specified records file.r   Nr   r   r   r   r"   r"   4   s    Cr   r"   c                       \ rS rSrSrSrg)ConflictingRecordsFound8   zCConflicts found between records being imported and current records.r   Nr   r   r   r   r%   r%   8   s    Kr   r%   c           
          SR                  S SU R                  R                  U5      U R                  U R                  U R
                  U R                  U R                  4 5       5      $ )a\  Returns the translation of the given SOA rdata.

Args:
  rdata: Rdata, The data to be translated.
  origin: Name, The origin domain name.

Returns:
  str, The translation of the given SOA rdata which includes all the required
  SOA fields. Note that the primary NS name is left in a substitutable form
  because it is always provided by Cloud DNS.
 c              3   N   #    U  H  n[         R                  " U5      v   M     g 7fN)six	text_type).0xs     r   	<genexpr>"_SOATranslation.<locals>.<genexpr>I   s$      !1cmmA !s   #%{0})joinrnamederelativizeserialrefreshretryexpireminimumrdataorigins     r   _SOATranslationr=   <   s\     
 

++
"
"6
*
,,
--
++
,,
--! 
 r   c                     [         R                  " U 5      n U R                  S5      (       a  U R                  S5      (       a  U $ SR	                  U 5      $ )a  Returns the given text within quotes.

Args:
  text: str, The text to be escaped.

Returns:
  str, The given text within quotes. For further details on why this is
  necessary, please look at the TXT section at:
  https://cloud.google.com/dns/what-is-cloud-dns#supported_record_types.
"z"{0}")r   Decode
startswithendswithformat)texts    r   
QuotedTextrE   U   sC     
	$	__SdmmC00K>>$r   c                 "    U R                  USS9$ )zReturns the given rdata as text (formatted by its .to_text() method).

Args:
  rdata: Rdata, The data to be translated.
  origin: Name, The origin domain name.

Returns:
  str, The textual presentation form of the given rdata.
F)r<   
relativize)to_textr:   s     r   _NullTranslationrI   h   s     
f	77r   c                 B    U [         R                  :X  a  [        $ [        $ )zReturns the rdata translation function for a record type.

Args:
  rr_type: The record type

Returns:
  The record type's translation function.
)r   SOAr=   rI   )rr_types    r   GetRdataTranslationrM   u   s     		r   c                 H    U(       a  gX:X  a  U[         R                  :X  a  gg)a  Returns whether the given record should be filtered out.

Args:
  name: string, The name of the resord set we are considering
  rdtype: RDataType or string, type of Record we are considering approving.
  origin: Name, The origin domain of the zone we are considering
  replace_origin_ns: Bool, Whether origin NS records should be imported

Returns:
  True if the given record should be filtered out, false otherwise.
FT)r   NS)namerdtyper<   replace_origin_nss       r   _FilterOutRecordrS      s      ~&ILL0r   c                    UR                   [        R                  ;  a  g[        R                  " SU5      nUR                  5       nUR                  Ul        U R                  U5      R                  5       Ul	        UR                  Ul
        [        R                  " UR                   5      Ul        / nU H-  nUR                  [        UR                   5      " Xr5      5        M/     Xel        U$ )a  Returns the Cloud DNS ResourceRecordSet for the given zone file record.

Args:
  name: Name, Domain name of the zone record.
  rdset: Rdataset, The zone record object.
  origin: Name, The origin domain of the zone file.
  api_version: [str], the api version to use for creating the records.

Returns:
  The ResourceRecordSet equivalent for the given zone record, or None for
  unsupported record types.
Ndns)rQ   r	   SUPPORTED_TYPES	core_apisGetMessagesModuleResourceRecordSetkindr4   rH   rP   ttlr   typeappendrM   rrdatas)rP   rdsetr<   api_versionmessages
record_setrdatasr;   s           r   _RecordSetFromZoneRecordrd      s     \\555((<())+*OO*/%%f-557*/99*.%%ell3*/&e
MM%ell3EBC 	r   c                     [         R                  " XSS9n0 nUR                  5        H=  u  pV[        XVUR                  US9nU(       d  M#  XtUR
                  UR                  4'   M?     U$ )a!  Returns record-sets for the given domain imported from the given zone file.

Args:
  zone_file: file, The zone file with records for the given domain.
  domain: str, The domain for which record-sets should be obtained.
  api_version: [str], the api version to use for creating the records.

Returns:
  A (name, type) keyed dict of ResourceRecordSets that were obtained from the
  zone file. Note that only records of supported types are retrieved. Also,
  the primary NS field for SOA records is discarded since that is
  provided by Cloud DNS.
F)check_originr`   )r   	from_fileiterate_rdatasetsrd   r<   rP   r\   )	zone_filedomainr`   zone_contentsrecord_setsrP   r_   rb   s           r   RecordSetsFromZoneFilern      sh     ..G-+"446kd)])){DJz8B:??JOO45	 7
 
r   c                 X    U [         R                  ;   a  g[        R                  " U 5      $ )a  Converts string_type to an RdataType enum value if it is a standard type.

Only standard record types can be converted to a RdataType, all other types
will cause an exception. This method allow getting the standard enum type if
available without throwing an exception if an extended type is provided.

Args:
  string_type: [str] The record type as a string.

Returns:
  The record type as an RdataType enum or None if the type is not a standard
  DNS type.
N)r	   CLOUD_DNS_EXTENDED_TYPESr   	from_text)string_types    r   _ToStandardEnumTypeSafers      s&     L999			[	))r   c                    0 n[         R                  " SU5      n[        R                  " U 5      nU GH#  n[	        US   5      nU[
        R                  ;  a   U(       a  US   [
        R                  ;  a  MF  UR                  5       nUR                  Ul	        US   Ul
        US   Ul        US   Ul        SU;   a  US   Ul        O/SU;   a)  [        R                  " UR                   US   5      Ul        U[$        R&                  L a1  [(        R*                  " SSUR                  S	   S
S9UR                  S	'   XUR                  UR                  4'   GM&     U$ )a"  Returns record-sets read from the given yaml file.

Args:
  yaml_file: file, A yaml file with records.
  include_extended_records: [bool], If extended record should be included
    (otherwise they are silently skipped).
  api_version: [str], the api version to use for creating the records.

Returns:
  A (name, type) keyed dict of ResourceRecordSets that were obtained from the
  yaml file. Note that only records of supported types are retrieved. Also,
  the primary NS field for SOA records is discarded since that is
  provided by Cloud DNS.
rU   r\   rP   r[   r^   routingPolicyz\S+r1   r      )count)rW   rX   r   load_allrs   r	   rV   rp   rY   rZ   rP   r[   r\   r^   api_encodingPyValueToMessageRRSetRoutingPolicyru   r   rK   resub)		yaml_fileinclude_extended_recordsr`   rm   ra   yaml_record_setsyaml_record_set
rdata_typerb   s	            r   RecordSetsFromYamlFiler      sC   " +((<(]]9-)o()@AJ555$|'L'LL++-J ooJO%f-JO$U+JN%f-JOO#*95j	O	+!-!>!>

%
%
/
*"j
 Y]]" ffVUJ4F4Fq4I+,.j 7A*//235 *8 
r   c                    [         R                  " SU5      nUR                  5       nU R                  Ul        U R                  Ul        U R
                  Ul        U R                  Ul        [        U R                  5      Ul        U$ )zReturns a copy of the given record-set.

Args:
  record_set: ResourceRecordSet, Record-set to be copied.
  api_version: [str], the api version to use for creating the records.

Returns:
  Returns a copy of the given record-set.
rU   )	rW   rX   rY   rZ   rP   r\   r[   listr^   )rb   r`   ra   copys       r   _RecordSetCopyr     sg     ((<(		#	#	%$oo$)oo$)oo$)^^$(j(()$,	+r   c                     [        XS9nUR                  S   R                  U R                  S   R                  5       S   5      UR                  S'   X0:X  a  [	        X25      $ U$ )ai  Returns the replacement SOA record with restored primary NS name.

Args:
  current_record: ResourceRecordSet, Current record-set.
  record_to_be_imported: ResourceRecordSet, Record-set to be imported.
  api_version: [str], the api version to use for creating the records.

Returns:
  ResourceRecordSet, the replacement SOA record with restored primary NS name.
rg   r   )r   r^   rC   splitNextSOARecordSetcurrent_recordrecord_to_be_importedr`   replacements       r   _SOAReplacementr   )  sj     4N+&..q188Q%%'*,+a "K55r   c                 $    [        XS9nX0:X  a  gU$ )a  Returns a record-set containing rrdata to be imported.

Args:
  current_record: ResourceRecordSet, Current record-set.
  record_to_be_imported: ResourceRecordSet, Record-set to be imported.
  api_version: [str], the api version to use for creating the records.

Returns:
  ResourceRecordSet, a record-set containing rrdata to be imported.
  None, if rrdata to be imported is identical to current rrdata.
rg   N)r   r   s       r   _RDataReplacementr   ?  s     4N+"r   c                 B    U [         R                  :X  a  [        $ [        $ )a   Gets the RData replacement function for this type.

Args:
  rdtype: RDataType, the type for which to fetch a replacement function.

Returns:
  A function for replacing rdata of a record-set with rdata from another
  record-set with the same name and type.
)r   rK   r   r   )rQ   s    r   _GetRDataReplacementr   R  s     y}}	r   c                     [        XS9nU R                  S   R                  5       n[        [	        US   5      S-   S-  5      US'   SR                  U5      UR                  S'   U$ )a  Returns a new SOA record set with an incremented serial number.

Args:
  soa_record_set: ResourceRecordSet, Current SOA record-set.
  api_version: [str], the api version to use for creating the records.

Returns:
  A a new SOA record-set with an incremented serial number.
rg   r      rv   l        r(   )r   r^   r   strintr2   )soa_record_setr`   next_soa_record_setrdata_partss       r   r   r   a  si     '~O&&q)//1+KN+a/G<=+a.#&88K#8a 	r   c                 J   [        U R                  5      [        U R                  5      s=:H  =(       a    S:H  Os  =(       ab    [        U R                  S   R                  5      [
        R                  L =(       a)    [        U R                  S   U5      U R                  S   :H  $ )a  Returns True if the change only contains an SOA increment, False otherwise.

Args:
  change: Change, the change to be checked
  api_version: [str], the api version to use for creating the records.

Returns:
  True if the change only contains an SOA increment, False otherwise.
rv   r   )len	additions	deletionsrs   r\   r   rK   r   )changer`   s     r   IsOnlySOAIncrementr   s  s     f
3v'7'7#8
=
=A
= ?
!&"2"21"5":":
;y}}
L?
6++A.&(+1+;+;A+>?@r   c                 N    SR                  U R                  U R                  5      $ )Nz{0} {1})rC   rP   r\   )records    r   _NameAndTyper     s    			&++v{{	33r   c                 6   [         R                  " SU5      nUR                  5       n/ Ul        / Ul        [        U R                  5       5      n[        UR                  5       5      n	UR                  U	5      n
U(       dF  U
(       a?  [        SR                  [        U
5       Vs/ s H  n[        X   5      PM     sn5      5      eU
 H  nX   nX   n[        US   5      n[        UR                  UUU5      (       a  M8  [        U5      " XUS9nU(       d  MQ  UR                  R!                  U5        UR                  R!                  U5        M     U	R#                  U5       H   nUR                  R!                  X   5        M"     UR#                  U	5       H  nX   n[        US   5      nU[$        R&                  L aA  UR                  R!                  U5        UR                  R!                  [)        X5      5        Mi  U(       d  Mr  [        UR                  UUU5      (       a  M  UR                  R!                  U5        M     [+        Xu5      (       a  gUR                  R-                  [        S9  UR                  R-                  [        S9  U$ s  snf )a  Returns a change for importing the given record-sets.

Args:
  current: dict, (name, type) keyed dict of current record-sets.
  to_be_imported: dict, (name, type) keyed dict of record-sets to be imported.
  replace_all: bool, Whether the record-sets to be imported should replace the
    current record-sets.
  origin: string, the name of the apex zone ex. "foo.com"
  replace_origin_ns: bool, Whether origin NS records should be imported.
  api_version: [str], the api version to use for creating the records.

Raises:
  ConflictingRecordsFound: If conflicting records are found.

Returns:
  A Change that describes the actions required to import the given
  record-sets.
rU   z4The following records (name type) already exist: {0}rv   rg   N)key)rW   rX   Changer   r   setkeysintersectionr%   rC   sortedr   rs   rS   rP   r   r]   
differencer   rK   r   r   sort)currentto_be_importedreplace_allr<   rR   r`   ra   r   current_keyskeys_to_be_importedintersecting_keysr   r   r   rQ   r   s                   r   ComputeChanger     sS   0 ((<(??&&&W\\^$,N//12"//0CD	*
!>EE39:K3LM3LC\','3LM	OP P c\N*/$SV,FN//""-/ / )0
[Jk	/,  !++L9c
N/0 : $$%89c\N$SV,Fn-.~KL	-n.A.A.4.4.?A A n- : ,,L)L)	-K Ns   $Jr*   )F)v1)Fr   )FNFr   ).r   
__future__r   r   r   r|   apitools.base.pyr   ry   rU   r   r   googlecloudsdk.api_lib.dnsr	   r
   googlecloudsdk.api_lib.utilr   rW   googlecloudsdk.corer   r   googlecloudsdk.core.utilr+   registerr   r   r   r"   r%   r=   rE   rI   rM   rS   rd   rn   rs   r   r   r   r   r   r   r   r   r   r   r   r   <module>r      s     0 &  ' 	 5   3 0 9 * $ - 
 
   .J .2% 23e 3De DLe L2 &
8*<0*( 5:'+1h(,&$@ 4 $$)"Ir   