U mfv@s~dZddlZddlZddlZddlZddlmZmZmZm Z m Z m Z m Z m Z mZmZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddl Zddl!m"Z"m#Z#m$Z$Gdddej%j&Z'Gddde'Z(Gd d d e'Z)Gd d d e'Z*Gd ddej%j&Z+Gdddej%j&Z,Gdddej%j&Z-Gdddej%j&Z.ej/j0e ej/j0e1ej/j0dddZ2Gdddej3j4Z5Gdddej6j7Z8ej9j9Gddde8Z:GdddZ;Gd d!d!e;ZZ>dej?j@d&e5dd'd&dd&f ee eej/j0eAfej?jBe1ee eAe1e1e ej/jCee1eeAfe5d( d)d*ZDdej?j@d&e5dd'd&dd&f eAe eej/j0eAfej?jBe1ee eAe1e1e ej/jCee1eeAfe5d( d+d,ZEdej?j@d&e5dd&d&dd&f ee eej/j0eAfej?jBe1ee eAe1e1e ej/jCee1eeAfe5d- d.d/ZFe5d&d&feee1e1e5d0d1d2ZGdS)3z DNS Zones.N) AnyCallableIterableIteratorListMutableMappingOptionalSetTupleUnion)DigestHashAlgorithm DigestScheme_digest_hashersc@seZdZdZdS)BadZonezThe DNS zone is malformed.N__name__ __module__ __qualname____doc__rr6/opt/hc_python/lib/python3.8/site-packages/dns/zone.pyr8src@seZdZdZdS)NoSOAz)The DNS zone has no SOA RR at its origin.Nrrrrrr<src@seZdZdZdS)NoNSz+The DNS zone has no NS RRset at its origin.Nrrrrrr@src@seZdZdZdS) UnknownOriginz!The DNS zone's origin is unknown.NrrrrrrDsrc@seZdZdZdS)UnsupportedDigestSchemez(The zone digest's scheme is unsupported.NrrrrrrHsrc@seZdZdZdS)UnsupportedDigestHashAlgorithmz(The zone digest's origin is unsupported.NrrrrrrLsrc@seZdZdZdS)NoDigestz/The DNS zone has no ZONEMD RRset at its origin.NrrrrrrPsrc@seZdZdZdS)DigestVerificationFailurez#The ZONEMD digest failed to verify.NrrrrrrTsr)nameorigin relativizereturncCsv|dkrtd|r:||s*td|rr||}n8z||}Wn tjjk rhtdYnX|sr|}|S)Nzno zone origin is definedz5name parameter must be a subdomain of the zone originzrelative name too long for zone)KeyError is_absoluteZ is_subdomainr Z derelativizednsrZ NameTooLong)rrr Zabs_namerrr_validate_nameXs  r%c @seZdZUdZejjZegejjfe d<e Z ege ej jejjffe d<dZeegdfe d<dZeegdfe d<d d d d gZejjd feeej jefejjedddZddZddZeej jefej jdddZddZddZddZddZ d d!Z!d"d#Z"d$d%Z#d&d'Z$d(d)Z%dleej jefeejjd+d,d-Z&dmeej jefeeejjd+d.d/Z'eej jefddd0d1Z(ej)j*d*feej jefeej)j+efeej)j+efeej,j-d2d3d4Z.ej)j*d*feej jefeej)j+efeej)j+efeeej,j-d2d5d6Z/ej)j*feej jefeej)j+efeej)j+efdd7d8d9Z0eej jefej,j-dd:d;d<Z1ej)j*feej jefeej)j+efeej)j+efej2j3d7d=d>Z4ej)j*feej jefeej)j+efeej)j+efeej2j3d7d?d@Z5ej)j6ej)j*feej)j+efeej)j+efe7e8ej jej,j-fdAdBdCZ9ej)j6ej)j*feej)j+efeej)j+efe7e8ej je:ej;jeeeeeeddFdGdHZ?doeeeeeeedIdJdKZ@ddLdMdNZAdpeejBjCejDj6jEjEdOdPdQZFeGjHfeIeGeJdRdSdTZKeGjHfeIeGejDj6jLjLdRdUdVZMdqeejDj6jLjLddWdXdYZNdZdLd[d\ZOdredZd]d^d_ZPe8eej jeeej jfdLd`daZQdbdcZRdddeZSdfdgZTdhdiZUdjdkZVdS)sZoneazA DNS zone. A ``Zone`` is a mapping from names to nodes. The zone object may be treated like a Python dictionary, e.g. ``zone[name]`` will retrieve the node associated with that name. The *name* may be a ``dns.name.Name object``, or it may be a string. In either case, if the name is relative it is treated as relative to the origin of the zone. node_factory map_factoryNWritableVersionwritable_version_factoryImmutableVersionimmutable_version_factoryrdclassrnodesr T)rr-r cCsf|dk rFt|tr tj|}nt|tjjs6td|sFtd||_||_ | |_ ||_ dS)aInitialize a zone object. *origin* is the origin of the zone. It may be a ``dns.name.Name``, a ``str``, or ``None``. If ``None``, then the zone's origin will be set by the first ``$ORIGIN`` line in a zone file. *rdclass*, an ``int``, the zone's rdata class; the default is class IN. *relativize*, a ``bool``, determine's whether domain names are relativized to the zone's origin. The default is ``True``. Nz2origin parameter must be convertible to a DNS namez)origin parameter must be an absolute name) isinstancestrr$r from_textName ValueErrorr#rr-r(r.r )selfrr-r rrr__init__s  z Zone.__init__cCs:t|tsdS|j|jks2|j|jks2|j|jkr6dSdS)zqTwo zones are equal if they have the same origin, class, and nodes. Returns a ``bool``. FT)r/r&r-rr.r4otherrrr__eq__s    z Zone.__eq__cCs || S)z>Are two zones not equal? Returns a ``bool``. )r8r6rrr__ne__sz Zone.__ne__rr!cCs@t|trtj|d}nt|tjjs0tdt||j|j S)Nz0name parameter must be convertible to a DNS name) r/r0r$rr1r2r"r%rr r4rrrrr%s  zZone._validate_namecCs||}|j|SNr%r.r4keyrrr __getitem__s zZone.__getitem__cCs||}||j|<dSr<r=)r4r?valuerrr __setitem__s zZone.__setitem__cCs||}|j|=dSr<r=r>rrr __delitem__s zZone.__delitem__cCs |jSr<)r.__iter__r4rrrrDsz Zone.__iter__cCs |jSr<r.keysrErrrrGsz Zone.keyscCs |jSr<)r.valuesrErrrrHsz Zone.valuescCs |jSr<r.itemsrErrrrJsz Zone.itemscCs||}|j|Sr<r%r.getr>rrrrLs zZone.getcCs||}||jkSr<r=r>rrr __contains__s zZone.__contains__F)rcreater!cCs<||}|j|}|dkr8|s&t|}||j|<|S)aNFind a node in the zone, possibly creating it. *name*: the name of the node to find. The value may be a ``dns.name.Name`` or a ``str``. If absolute, the name must be a subdomain of the zone's origin. If ``zone.relativize`` is ``True``, then the name will be relativized. *create*, a ``bool``. If true, the node will be created if it does not exist. Raises ``KeyError`` if the name is not known and create was not specified, or if the name was not a subdomain of the origin. Returns a ``dns.node.Node``. N)r%r.rLr"r'r4rrNnoderrr find_nodes   zZone.find_nodecCs.z|||}Wntk r(d}YnX|S)aGet a node in the zone, possibly creating it. This method is like ``find_node()``, except it returns None instead of raising an exception if the node does not exist and creation has not been requested. *name*: the name of the node to find. The value may be a ``dns.name.Name`` or a ``str``. If absolute, the name must be a subdomain of the zone's origin. If ``zone.relativize`` is ``True``, then the name will be relativized. *create*, a ``bool``. If true, the node will be created if it does not exist. Returns a ``dns.node.Node`` or ``None``. N)rQr"rOrrrget_nodes  z Zone.get_nodecCs ||}||jkr|j|=dS)akDelete the specified node if it exists. *name*: the name of the node to find. The value may be a ``dns.name.Name`` or a ``str``. If absolute, the name must be a subdomain of the zone's origin. If ``zone.relativize`` is ``True``, then the name will be relativized. It is not an error if the node does not exist. Nr=r;rrr delete_node s  zZone.delete_node)rrdtypecoversrNr!cCsD||}tjj|}tjj|}|||}||j|||S)aLook for an rdataset with the specified name and type in the zone, and return an rdataset encapsulating it. The rdataset returned is not a copy; changes to it will change the zone. KeyError is raised if the name or type are not found. *name*: the name of the node to find. The value may be a ``dns.name.Name`` or a ``str``. If absolute, the name must be a subdomain of the zone's origin. If ``zone.relativize`` is ``True``, then the name will be relativized. *rdtype*, a ``dns.rdatatype.RdataType`` or ``str``, the rdata type desired. *covers*, a ``dns.rdatatype.RdataType`` or ``str`` the covered type. Usually this value is ``dns.rdatatype.NONE``, but if the rdtype is ``dns.rdatatype.SIG`` or ``dns.rdatatype.RRSIG``, then the covers value will be the rdata type the SIG/RRSIG covers. The library treats the SIG and RRSIG types as if they were a family of types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA). This makes RRSIGs much easier to work with than if RRSIGs covering different rdata types were aggregated into a single RRSIG rdataset. *create*, a ``bool``. If true, the node will be created if it does not exist. Raises ``KeyError`` if the name is not known and create was not specified, or if the name was not a subdomain of the origin. Returns a ``dns.rdataset.Rdataset``. )r%r$ rdatatype RdataTypemakerQ find_rdatasetr-)r4rrTrUrNrPrrrrY/s )  zZone.find_rdatasetcCs2z|||||}Wntk r,d}YnX|S)a%Look for an rdataset with the specified name and type in the zone. This method is like ``find_rdataset()``, except it returns None instead of raising an exception if the rdataset does not exist and creation has not been requested. The rdataset returned is not a copy; changes to it will change the zone. *name*: the name of the node to find. The value may be a ``dns.name.Name`` or a ``str``. If absolute, the name must be a subdomain of the zone's origin. If ``zone.relativize`` is ``True``, then the name will be relativized. *rdtype*, a ``dns.rdatatype.RdataType`` or ``str``, the rdata type desired. *covers*, a ``dns.rdatatype.RdataType`` or ``str``, the covered type. Usually this value is ``dns.rdatatype.NONE``, but if the rdtype is ``dns.rdatatype.SIG`` or ``dns.rdatatype.RRSIG``, then the covers value will be the rdata type the SIG/RRSIG covers. The library treats the SIG and RRSIG types as if they were a family of types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA). This makes RRSIGs much easier to work with than if RRSIGs covering different rdata types were aggregated into a single RRSIG rdataset. *create*, a ``bool``. If true, the node will be created if it does not exist. Raises ``KeyError`` if the name is not known and create was not specified, or if the name was not a subdomain of the origin. Returns a ``dns.rdataset.Rdataset`` or ``None``. N)rYr")r4rrTrUrNrdatasetrrr get_rdataset^s * zZone.get_rdatasetrrTrUr!cCsb||}tjj|}tjj|}||}|dk r^||j||t|dkr^| |dS)aDelete the rdataset matching *rdtype* and *covers*, if it exists at the node specified by *name*. It is not an error if the node does not exist, or if there is no matching rdataset at the node. If the node has no rdatasets after the deletion, it will itself be deleted. *name*: the name of the node to find. The value may be a ``dns.name.Name`` or a ``str``. If absolute, the name must be a subdomain of the zone's origin. If ``zone.relativize`` is ``True``, then the name will be relativized. *rdtype*, a ``dns.rdatatype.RdataType`` or ``str``, the rdata type desired. *covers*, a ``dns.rdatatype.RdataType`` or ``str`` or ``None``, the covered type. Usually this value is ``dns.rdatatype.NONE``, but if the rdtype is ``dns.rdatatype.SIG`` or ``dns.rdatatype.RRSIG``, then the covers value will be the rdata type the SIG/RRSIG covers. The library treats the SIG and RRSIG types as if they were a family of types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA). This makes RRSIGs much easier to work with than if RRSIGs covering different rdata types were aggregated into a single RRSIG rdataset. Nr) r%r$rVrWrXrRdelete_rdatasetr-lenrSr4rrTrUrPrrrr]s   zZone.delete_rdataset)r replacementr!cCs.|j|jkrtd||d}||dS)aReplace an rdataset at name. It is not an error if there is no rdataset matching I{replacement}. Ownership of the *replacement* object is transferred to the zone; in other words, this method does not store a copy of *replacement* at the node, it stores *replacement* itself. If the node does not exist, it is created. *name*: the name of the node to find. The value may be a ``dns.name.Name`` or a ``str``. If absolute, the name must be a subdomain of the zone's origin. If ``zone.relativize`` is ``True``, then the name will be relativized. *replacement*, a ``dns.rdataset.Rdataset``, the replacement rdataset. z#replacement.rdclass != zone.rdclassTN)r-r3rQreplace_rdataset)r4rr`rPrrrras  zZone.replace_rdatasetcCs^||}tjj|}tjj|}|j||j||}tj ||j||}| ||S)aLook for an rdataset with the specified name and type in the zone, and return an RRset encapsulating it. This method is less efficient than the similar ``find_rdataset()`` because it creates an RRset instead of returning the matching rdataset. It may be more convenient for some uses since it returns an object which binds the owner name to the rdataset. This method may not be used to create new nodes or rdatasets; use ``find_rdataset`` instead. *name*: the name of the node to find. The value may be a ``dns.name.Name`` or a ``str``. If absolute, the name must be a subdomain of the zone's origin. If ``zone.relativize`` is ``True``, then the name will be relativized. *rdtype*, a ``dns.rdatatype.RdataType`` or ``str``, the rdata type desired. *covers*, a ``dns.rdatatype.RdataType`` or ``str``, the covered type. Usually this value is ``dns.rdatatype.NONE``, but if the rdtype is ``dns.rdatatype.SIG`` or ``dns.rdatatype.RRSIG``, then the covers value will be the rdata type the SIG/RRSIG covers. The library treats the SIG and RRSIG types as if they were a family of types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA). This makes RRSIGs much easier to work with than if RRSIGs covering different rdata types were aggregated into a single RRSIG rdataset. *create*, a ``bool``. If true, the node will be created if it does not exist. Raises ``KeyError`` if the name is not known and create was not specified, or if the name was not a subdomain of the origin. Returns a ``dns.rrset.RRset`` or ``None``. ) r%r$rVrWrXr.rYr-rrsetRRsetupdate)r4rrTrUZvnamerZrbrrr find_rrsets,  zZone.find_rrsetcCs0z||||}Wntk r*d}YnX|S)a.Look for an rdataset with the specified name and type in the zone, and return an RRset encapsulating it. This method is less efficient than the similar ``get_rdataset()`` because it creates an RRset instead of returning the matching rdataset. It may be more convenient for some uses since it returns an object which binds the owner name to the rdataset. This method may not be used to create new nodes or rdatasets; use ``get_rdataset()`` instead. *name*: the name of the node to find. The value may be a ``dns.name.Name`` or a ``str``. If absolute, the name must be a subdomain of the zone's origin. If ``zone.relativize`` is ``True``, then the name will be relativized. *rdtype*, a ``dns.rdataset.Rdataset`` or ``str``, the rdata type desired. *covers*, a ``dns.rdataset.Rdataset`` or ``str``, the covered type. Usually this value is ``dns.rdatatype.NONE``, but if the rdtype is ``dns.rdatatype.SIG`` or ``dns.rdatatype.RRSIG``, then the covers value will be the rdata type the SIG/RRSIG covers. The library treats the SIG and RRSIG types as if they were a family of types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA). This makes RRSIGs much easier to work with than if RRSIGs covering different rdata types were aggregated into a single RRSIG rdataset. *create*, a ``bool``. If true, the node will be created if it does not exist. Returns a ``dns.rrset.RRset`` or ``None``. N)rer")r4rrTrUrbrrr get_rrsets ( zZone.get_rrset)rTrUr!ccsftjj|}tjj|}|D]<\}}|D].}|tjjksT|j|kr0|j|kr0||fVq0q$dS)aReturn a generator which yields (name, rdataset) tuples for all rdatasets in the zone which have the specified *rdtype* and *covers*. If *rdtype* is ``dns.rdatatype.ANY``, the default, then all rdatasets will be matched. *rdtype*, a ``dns.rdataset.Rdataset`` or ``str``, the rdata type desired. *covers*, a ``dns.rdataset.Rdataset`` or ``str``, the covered type. Usually this value is ``dns.rdatatype.NONE``, but if the rdtype is ``dns.rdatatype.SIG`` or ``dns.rdatatype.RRSIG``, then the covers value will be the rdata type the SIG/RRSIG covers. The library treats the SIG and RRSIG types as if they were a family of types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA). This makes RRSIGs much easier to work with than if RRSIGs covering different rdata types were aggregated into a single RRSIG rdataset. N)r$rVrWrXrJANYrTrU)r4rTrUrrPrdsrrriterate_rdatasets0s zZone.iterate_rdatasetsccsttjj|}tjj|}|D]J\}}|D]<}|tjjksT|j|kr0|j|kr0|D]}||j|fVqXq0q$dS)aReturn a generator which yields (name, ttl, rdata) tuples for all rdatas in the zone which have the specified *rdtype* and *covers*. If *rdtype* is ``dns.rdatatype.ANY``, the default, then all rdatas will be matched. *rdtype*, a ``dns.rdataset.Rdataset`` or ``str``, the rdata type desired. *covers*, a ``dns.rdataset.Rdataset`` or ``str``, the covered type. Usually this value is ``dns.rdatatype.NONE``, but if the rdtype is ``dns.rdatatype.SIG`` or ``dns.rdatatype.RRSIG``, then the covers value will be the rdata type the SIG/RRSIG covers. The library treats the SIG and RRSIG types as if they were a family of types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA). This makes RRSIGs much easier to work with than if RRSIGs covering different rdata types were aggregated into a single RRSIG rdataset. N) r$rVrWrXrJrgrTrUttl)r4rTrUrrPrhrdatarrriterate_rdatasPs zZone.iterate_rdatas)fsortedr nl want_comments want_originr!c Cst|trt|d}n t|}|\}t|dd}|dkr@d}|dkrZtj|} d}n"t|trp||} n |} | }|r|j dk st d|j } | |} z| | | | Wn(tk r| | | |YnX|rt|} | n|} | D]l} || j | |j ||d} | |} z| | | | Wn*tk rx| | | |YnXqW5QRXdS)a=Write a zone to a file. *f*, a file or `str`. If *f* is a string, it is treated as the name of a file to open. *sorted*, a ``bool``. If True, the default, then the file will be written with the names sorted in DNSSEC order from least to greatest. Otherwise the names will be written in whatever order they happen to have in the zone's dictionary. *relativize*, a ``bool``. If True, the default, then domain names in the output will be relativized to the zone's origin if possible. *nl*, a ``str`` or None. The end of line string. If not ``None``, the output will use the platform's native end-of-line marker (i.e. LF on POSIX, CRLF on Windows). *want_comments*, a ``bool``. If ``True``, emit end-of-line comments as part of writing the file. If ``False``, the default, do not emit them. *want_origin*, a ``bool``. If ``True``, emit a $ORIGIN line at the start of the file. If ``False``, the default, do not emit one. wbencodingNzutf-8 z$ORIGIN )rr rp)r/r0open contextlib nullcontextgetattroslinesepencodedecoderAssertionErrorto_textwrite TypeErrorlistrGsort)r4rmrnr rorprqcmZfile_encZnl_blZl_bnamesnrrrto_fileqsT$               z Zone.to_file)rnr rorprqr!cCs0t}||||||||}||S)aReturn a zone's text as though it were written to a file. *sorted*, a ``bool``. If True, the default, then the file will be written with the names sorted in DNSSEC order from least to greatest. Otherwise the names will be written in whatever order they happen to have in the zone's dictionary. *relativize*, a ``bool``. If True, the default, then domain names in the output will be relativized to the zone's origin if possible. *nl*, a ``str`` or None. The end of line string. If not ``None``, the output will use the platform's native end-of-line marker (i.e. LF on POSIX, CRLF on Windows). *want_comments*, a ``bool``. If ``True``, emit end-of-line comments as part of writing the file. If ``False``, the default, do not emit them. *want_origin*, a ``bool``. If ``True``, emit a $ORIGIN line at the start of the output. If ``False``, the default, do not emit one. Returns a ``str``. )ioStringIOrgetvalueclose)r4rnr rorprqZ temp_bufferZ return_valuerrrr~s !z Zone.to_textr!cCsX|jrtjj}n|jdk st|j}||tjjdkrt j }|}t D]\}}|j }t |dddD]~} ||krtjj| j| jfkrqztd| j| j| j} fdd| D} t | D]*} tdt| } ||| | | qqzqV|S)NcSs |j|jfSr<)rTrU)rhrrr1z&Zone._compute_digest..)r?z!HHIcsg|]}|jqSr) to_digestabler).0rkrErr :sz(Zone._compute_digest..z!H)rrLrr SIMPLErr r$rrrr}rnrJrrVZONEMDrTrUstructpackr-rjr^rddigest)r4rrZhashinforZhasherrrPZ rrnamebufrZZrrfixedZrdatasrkZrrlenrrEr_compute_digests:     zZone._compute_digestcCs6|j}|||}tjjj|jtjj||||Sr<) rserialrr$rdtypesrgrr-rV)r4rrrrrrrcompute_digest@s   zZone.compute_digest)zonemdr!c Cs|r |g}n0|jdk st||jtjj}|dkr8t|}|D]@}z&||j|j }||j krhWdSWq@t k r~Yq@Xq@t dSr<) rr}r[r$rVrrrrrr Exceptionr)r4rdigestsrhrZcomputedrrr verify_digestKs  zZone.verify_digest TransactioncCst|dt|d|j|jS)NF)rVersionr.rrErrrreaderbsz Zone.readerr`r!cCst||}||Sr<)r_setup_version)r4r`rrrrwriteres z Zone.writercCs$|jrtjj}n|j}|j|j|fSr<)r r$rrr)r4 effectiverrrorigin_informationjs zZone.origin_informationcCs|jSr<)r-rErrr get_classtszZone.get_classcCsdSr<rr4rrrr _end_readyszZone._end_readcCsdSr<rrrrr _end_write|szZone._end_writecCs|j|_|jdkr||_dSr<)r.r)r4_versionrrrr_commit_versions zZone._commit_versioncCsdS)NrrrErrr_get_next_version_idszZone._get_next_version_id)F)F)TTNFF)TTNFF)N)N)F)Wrrrrr$rPNoder'r__annotations__dictr(rrr2r*rr, __slots__ rdataclassINr r0 RdataClassboolr5r8r9r%r@rBrCrDrGrHrJrLrMrQrRrSrVNONErWrZRdatasetrYr[r]rarbrcrerfrgrr riintrkZRdatarlrrr~r transactionrrrrr rr bytesrrrrrrrrrrrrrrrrr&xs4  $      3 4 '  8 0 " $ [ '   %   r&cs"eZdZdgZfddZZS) VersionedNodeidcstd|_dSNr)superr5rrE __class__rrr5s zVersionedNode.__init__)rrrrr5 __classcell__rrrrrsrcseZdZfddZejjdfejjejj ejj e ej j dfdd Z ejjdfejjejj ejj e eej j dfdd Zejjfejjejj ejj d d d d Zej j d d ddZe dddZZS)ImmutableVersionedNodecs,t|j|_tdd|jD|_dS)NcSsg|]}tj|qSr)r$rZZImmutableRdataset)rrhrrrrsz3ImmutableVersionedNode.__init__..)rr5rtuple rdatasets)r4rPrrrr5s  zImmutableVersionedNode.__init__F)r-rTrUrNr!cs|r tdt|||dSN immutableF)rrrYr4r-rTrUrNrrrrYsz$ImmutableVersionedNode.find_rdatasetcs|r tdt|||dSr)rrr[rrrrr[sz#ImmutableVersionedNode.get_rdatasetN)r-rTrUr!cCs tddSNrr)r4r-rTrUrrrr]sz&ImmutableVersionedNode.delete_rdatasetrcCs tddSrr)r4r`rrrrasz'ImmutableVersionedNode.replace_rdatasetrcCsdSNTrrErrr is_immutablesz#ImmutableVersionedNode.is_immutable)rrrr5r$rVrrrrWrrZrrYrr[r]rarrrrrrrs8   rc@seZdZdeeeeejj ej j feejj dddZ ejj ejj dddZ ejj eej j ddd Zejj ejjejjeejjd d d Zd dZddZdS)rN)zonerr.rcCs0||_||_|dk r||_n ||_||_dSr<)rrr.r(r)r4rrr.rrrrr5s  zVersion.__init__r:cCst||j|jjSr<)r%rrr r;rrrr%szVersion._validate_namecCs||}|j|Sr<rKr;rrrrRs zVersion.get_noder\cCs(||}|dkrdS||jj||Sr<)rRr[rr-r_rrrr[s zVersion.get_rdatasetcCs |jSr<rFrErrrrGsz Version.keyscCs |jSr<rIrErrrrJsz Version.items)NN)rrrr&rrrr$rr2rPrr5r%rRrVrWrZrr[rGrJrrrrrs"  rcseZdZdeedfdd Zejjej j dddZ ejjddd d Z ejjej jdd d d ZejjejjejjddddZZS)r)F)rr`cs<|}t|||s(|j|j|j|_t|_dSr<)rrr5r.rdrsetchanged)r4rr`rrrrr5s zWritableVersion.__init__r:cCs|||}|j|}|dks(||jkrt|j}t|drD|j|_|dk rZ|j |j||j|<|j ||S|SdS)Nr) r%r.rLrrr'hasattrrrextendadd)r4rrPnew_noderrr _maybe_cows      zWritableVersion._maybe_cowNcCs,||}||jkr(|j|=|j|dSr<)r%r.rrr;rrrrSs  zWritableVersion.delete_node)rrZr!cCs||}||dSr<)rra)r4rrZrPrrr put_rdatasets zWritableVersion.put_rdatasetr\cCs4||}||jj||t|dkr0|j|=dSr)rr]rr-r^r.r_rrrr]$s  zWritableVersion.delete_rdataset)F)rrrr&rr5r$rr2rPrrrSrZrrrVrWr]rrrrrr)s r)cs"eZdZedfdd ZZS)r+)rcsft|jd|j|_|j|_|jD]"}|j|}|r&t||j|<q&t j |jd|jj |_dSr) rr5rrrrr.rLrr$rDictr()r4rrrPrrrr52s  zImmutableVersion.__init__)rrrr)r5rrrrrr+0sr+cseZdZd!fdd ZeddZddZd d Zd d Zd dZ ddZ ddZ ddZ ddZ ddZddZddZddZdd ZZS)"rNFcs(|dk }t|||||_||_dSr<)rr5rmake_immutable)r4rr`rr read_onlyrrrr5IszTransaction.__init__cCs|jSr<)managerrErrrrOszTransaction.zonecCs6|jdkst|jj}|dkr"t}||j|j|_dSr<)rr}rr*r)rr`)r4factoryrrrrSs zTransaction._setup_versioncCs|j|||Sr<)rr[r4rrTrUrrr _get_rdatasetZszTransaction._get_rdatasetcCs|jr t|j||dSr<)rr}rr)r4rrZrrr _put_rdataset]s zTransaction._put_rdatasetcCs|jr t|j|dSr<)rr}rrSr;rrr _delete_nameas zTransaction._delete_namecCs|jr t|j|||dSr<)rr}rr]rrrr_delete_rdatasetes zTransaction._delete_rdatasetcCs|j|dk Sr<rrRr;rrr _name_existsiszTransaction._name_existscCs|jr dSt|jjdkSdS)NFr)rr^rrrErrr_changedlszTransaction._changedcCsz|jr|j|nb|rjt|jjdkrj|jrN|jj}|dkrBt }||j}n|j}|j |||jj n |j |dSr) rrrr^rrrrr,r+rrr)r4commitrrrrr_end_transactionrs zTransaction._end_transactioncCs|jjdkr||j_dSr<)rr)r4rrrr _set_origins zTransaction._set_originccs,|jD]\}}|D]}||fVqq dSr<)rrJ)r4rrPrZrrr_iterate_rdatasetsszTransaction._iterate_rdatasetscCs |jSr<)rrGrErrr_iterate_namesszTransaction._iterate_namescCs |j|Sr<rr;rrr _get_nodeszTransaction._get_nodecCsH|j\}}}|dkr>|jjdk r>|jj}|r:tjj}n|}|||fSr<)rrrrr$rr)r4absoluter rrrr_origin_informations zTransaction._origin_information)NF)rrrr5propertyrrrrrrrrrrrrrrrrrrrrHs  rTF) textrr-r zone_factoryfilename allow_includer idna_codecallow_directivesr!c  Cs|dkr d}||||d} | d\} tjj|||d} tjj| || || d} z | Wn tjjk rztjjYnXW5QRX|r| | S)Nzr T)r)rr) rr$ tokenizer TokenizerZzonefileReaderreadrrr)rrr-r rrrrrrrrtokrrrr _from_texts&  rc Cst|||||||||| S)aBuild a zone object from a zone file format string. *text*, a ``str``, the zone file format input. *origin*, a ``dns.name.Name``, a ``str``, or ``None``. The origin of the zone; if not specified, the first ``$ORIGIN`` statement in the zone file will determine the origin of the zone. *rdclass*, a ``dns.rdataclass.RdataClass``, the zone's rdata class; the default is class IN. *relativize*, a ``bool``, determine's whether domain names are relativized to the zone's origin. The default is ``True``. *zone_factory*, the zone factory to use or ``None``. If ``None``, then ``dns.zone.Zone`` will be used. The value may be any class or callable that returns a subclass of ``dns.zone.Zone``. *filename*, a ``str`` or ``None``, the filename to emit when describing where an error occurred; the default is ``''``. *allow_include*, a ``bool``. If ``True``, the default, then ``$INCLUDE`` directives are permitted. If ``False``, then encoutering a ``$INCLUDE`` will raise a ``SyntaxError`` exception. *check_origin*, a ``bool``. If ``True``, the default, then sanity checks of the origin node will be made by calling the zone's ``check_origin()`` method. *idna_codec*, a ``dns.name.IDNACodec``, specifies the IDNA encoder/decoder. If ``None``, the default IDNA 2003 encoder/decoder is used. *allow_directives*, a ``bool`` or an iterable of `str`. If ``True``, the default, then directives are permitted, and the *allow_include* parameter controls whether ``$INCLUDE`` is permitted. If ``False`` or an empty iterable, then no directive processing is done and any directive-like text will be treated as a regular owner name. If a non-empty iterable, then only the listed directives (including the ``$``) are allowed. Raises ``dns.zone.NoSOA`` if there is no SOA RRset. Raises ``dns.zone.NoNS`` if there is no NS RRset. Raises ``KeyError`` if there is no origin node. Returns a subclass of ``dns.zone.Zone``. )r) rrr-r rrrrrrrrrr1s<r1) rmrr-r rrrrrrr!c Csht|tr |dkr|}t|} n t|} | (}t|||||||||| W5QRSQRXdsdtdS)aRead a zone file and build a zone object. *f*, a file or ``str``. If *f* is a string, it is treated as the name of a file to open. *origin*, a ``dns.name.Name``, a ``str``, or ``None``. The origin of the zone; if not specified, the first ``$ORIGIN`` statement in the zone file will determine the origin of the zone. *rdclass*, an ``int``, the zone's rdata class; the default is class IN. *relativize*, a ``bool``, determine's whether domain names are relativized to the zone's origin. The default is ``True``. *zone_factory*, the zone factory to use or ``None``. If ``None``, then ``dns.zone.Zone`` will be used. The value may be any class or callable that returns a subclass of ``dns.zone.Zone``. *filename*, a ``str`` or ``None``, the filename to emit when describing where an error occurred; the default is ``''``. *allow_include*, a ``bool``. If ``True``, the default, then ``$INCLUDE`` directives are permitted. If ``False``, then encoutering a ``$INCLUDE`` will raise a ``SyntaxError`` exception. *check_origin*, a ``bool``. If ``True``, the default, then sanity checks of the origin node will be made by calling the zone's ``check_origin()`` method. *idna_codec*, a ``dns.name.IDNACodec``, specifies the IDNA encoder/decoder. If ``None``, the default IDNA 2003 encoder/decoder is used. *allow_directives*, a ``bool`` or an iterable of `str`. If ``True``, the default, then directives are permitted, and the *allow_include* parameter controls whether ``$INCLUDE`` is permitted. If ``False`` or an empty iterable, then no directive processing is done and any directive-like text will be treated as a regular owner name. If a non-empty iterable, then only the listed directives (including the ``$``) are allowed. Raises ``dns.zone.NoSOA`` if there is no SOA RRset. Raises ``dns.zone.NoNS`` if there is no NS RRset. Raises ``KeyError`` if there is no origin node. Returns a subclass of ``dns.zone.Zone``. NF)r/r0rurvrwrr}) rmrr-r rrrrrrrrrr from_files&=    r)xfrrr rr!c Csd}|D]}|dkrF|r |j}n |jdj}|jdj}||||d}|jD]`}|j|j} | sv|} | |j|j<| |j|j|j d} | |j |D]} | | qqLq|dkrt d|r||S)aNConvert the output of a zone transfer generator into a zone object. *xfr*, a generator of ``dns.message.Message`` objects, typically ``dns.query.xfr()``. *relativize*, a ``bool``, determine's whether domain names are relativized to the zone's origin. The default is ``True``. It is essential that the relativize setting matches the one specified to the generator. *check_origin*, a ``bool``. If ``True``, the default, then sanity checks of the origin node will be made by calling the zone's ``check_origin()`` method. Raises ``dns.zone.NoSOA`` if there is no SOA RRset. Raises ``dns.zone.NoNS`` if there is no NS RRset. Raises ``KeyError`` if there is no origin node. Raises ``ValueError`` if no messages are yielded by the generator. Returns a subclass of ``dns.zone.Zone``. NrrTzempty transfer)rZanswerrr-r.rLr'rYrTrUZ update_ttlrjrr3r) rrr rzrrr-rbZznodeZzrdsrdrrrfrom_xfres,     r)Hrrvrryrtypingrrrrrrrr r r Z dns.exceptionr$Z dns.grangeZ dns.immutableZdns.nameZdns.nodeZ dns.rdataZdns.rdataclassZ dns.rdatasetZ dns.rdatatypeZdns.rdtypes.ANY.SOAZdns.rdtypes.ANY.ZONEMDZ dns.rrsetZ dns.tokenizerZdns.transactionZdns.ttlZ dns.zonefileZ dns.zonetypesr r r exceptionZ DNSExceptionrrrrrrrrrr2rr%rZTransactionManagerr&rPrrrrrr)r+rrrr0rZ IDNACodecrr1rrrrrrs0    -)?X  ,  L  U