U
    î¤ùdx1  ã                   @   sÊ   d Z ddlZddlZddlmZmZmZ ddlZddl	Zddl
ZddlZddlZddlZddlZejjhZejjejjejjhZdd„ ZejG dd„ dejƒƒZG dd	„ d	ƒZejjG d
d„ deƒƒZdS )z)DNS nodes.  A node is a set of rdatasets.é    N)ÚAnyÚDictÚOptionalc                 C   s   || kp|t jjko|| kS ©N)ÚdnsÚ	rdatatypeZRRSIG)ZrdtypesÚrdtypeÚcovers© r
   ú,/tmp/pip-unpacked-wheel-pk5slln3/dns/node.pyÚ_matches_type_or_its_signature,   s    r   c                   @   sR   e Zd ZdZdZdZdZeej	j
ej	j
d dœdd„ƒZeejjd dœd	d
„ƒZdS )ÚNodeKindzRdatasets in nodesr   é   é   )r   r	   Úreturnc                 C   s.   t t||ƒrtjS t t||ƒr$tjS tjS d S r   )r   Ú_cname_typesr   ÚCNAMEÚ_neutral_typesÚNEUTRALÚREGULAR)Úclsr   r	   r
   r
   r   Úclassify8   s
    zNodeKind.classify)Úrdatasetr   c                 C   s   |   |j|j¡S r   )r   r   r	   )r   r   r
   r
   r   Úclassify_rdatasetC   s    zNodeKind.classify_rdatasetN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   Úclassmethodr   r   Ú	RdataTyper   r   ÚRdatasetr   r
   r
   r
   r   r   0   s    þ
r   c                   @   s(  e Zd ZdZdgZdd„ Zejje	e
ef e
dœdd„Zdd	„ Zd
d„ Zdd„ Zdd„ Zdd„ Zdd„ Zejjdfejjejjejjeejjdœdd„Zejjdfejjejjejjeeejj dœdd„Zejjfejjejjejjddœdd„Zejjddœdd „Ze d!œd"d#„Z!ed!œd$d%„Z"dS )&ÚNodeaÖ  A Node is a set of rdatasets.

    A node is either a CNAME node or an "other data" node.  A CNAME
    node contains only CNAME, KEY, NSEC, and NSEC3 rdatasets along with their
    covering RRSIG rdatasets.  An "other data" node contains any
    rdataset other than a CNAME or RRSIG(CNAME) rdataset.  When
    changes are made to a node, the CNAME or "other data" state is
    always consistent with the update, i.e. the most recent change
    wins.  For example, if you have a node which contains a CNAME
    rdataset, and then add an MX rdataset to it, then the CNAME
    rdataset will be deleted.  Likewise if you have a node containing
    an MX rdataset and add a CNAME rdataset, the MX rdataset will be
    deleted.
    Ú	rdatasetsc                 C   s
   g | _ d S r   ©r"   ©Úselfr
   r
   r   Ú__init__[   s    zNode.__init__)ÚnameÚkwr   c                 K   sN   t  ¡ }| jD ].}t|ƒdkr| |j|f|Ž¡ | d¡ q| ¡ dd… S )a"  Convert a node to text format.

        Each rdataset at the node is printed.  Any keyword arguments
        to this method are passed on to the rdataset's to_text() method.

        *name*, a ``dns.name.Name``, the owner name of the
        rdatasets.

        Returns a ``str``.

        r   Ú
Néÿÿÿÿ)ÚioÚStringIOr"   ÚlenÚwriteÚto_textÚgetvalue)r%   r'   r(   ÚsÚrdsr
   r
   r   r/   _   s    
zNode.to_textc                 C   s   dt t| ƒƒ d S )Nz
<DNS node ú>)ÚstrÚidr$   r
   r
   r   Ú__repr__s   s    zNode.__repr__c                 C   s<   | j D ]}||j kr dS q|j D ]}|| j kr" dS q"dS )NFTr#   )r%   ÚotherÚrdr
   r
   r   Ú__eq__v   s    



zNode.__eq__c                 C   s   |   |¡ S r   )r9   )r%   r7   r
   r
   r   Ú__ne__‚   s    zNode.__ne__c                 C   s
   t | jƒS r   )r-   r"   r$   r
   r
   r   Ú__len__…   s    zNode.__len__c                 C   s
   t | jƒS r   )Úiterr"   r$   r
   r
   r   Ú__iter__ˆ   s    zNode.__iter__c                 C   sb   t | jƒdkrRt |¡}|tjkr6dd„ | jD ƒ| _n|tjkrRdd„ | jD ƒ| _| j |¡ dS )a†  Append rdataset to the node with special handling for CNAME and
        other data conditions.

        Specifically, if the rdataset being appended has ``NodeKind.CNAME``,
        then all rdatasets other than KEY, NSEC, NSEC3, and their covering
        RRSIGs are deleted.  If the rdataset being appended has
        ``NodeKind.REGULAR`` then CNAME and RRSIG(CNAME) are deleted.
        r   c                 S   s    g | ]}t  |¡t jkr|‘qS r
   )r   r   r   ©Ú.0r2   r
   r
   r   Ú
<listcomp>˜   s   þz)Node._append_rdataset.<locals>.<listcomp>c                 S   s    g | ]}t  |¡t jkr|‘qS r
   )r   r   r   r>   r
   r
   r   r@   ž   s   þN)r-   r"   r   r   r   r   Úappend©r%   r   Úkindr
   r
   r   Ú_append_rdataset‹   s    


þ

þzNode._append_rdatasetF©Úrdclassr   r	   Úcreater   c                 C   sH   | j D ]}| |||¡r|  S q|s*t‚tj |||¡}|  |¡ |S )a*  Find an rdataset matching the specified properties in the
        current node.

        *rdclass*, a ``dns.rdataclass.RdataClass``, the class of the rdataset.

        *rdtype*, a ``dns.rdatatype.RdataType``, the type of the rdataset.

        *covers*, a ``dns.rdatatype.RdataType``, 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, create the rdataset if it is not found.

        Raises ``KeyError`` if an rdataset of the desired type and class does
        not exist and *create* is not ``True``.

        Returns a ``dns.rdataset.Rdataset``.
        )r"   ÚmatchÚKeyErrorr   r   r    rD   ©r%   rF   r   r	   rG   r2   r
   r
   r   Úfind_rdataset§   s     


zNode.find_rdatasetc                 C   s2   z|   ||||¡}W n tk
r,   d}Y nX |S )aç  Get an rdataset matching the specified properties in the
        current node.

        None is returned if an rdataset of the specified type and
        class does not exist and *create* is not ``True``.

        *rdclass*, an ``int``, the class of the rdataset.

        *rdtype*, an ``int``, the type of the rdataset.

        *covers*, an ``int``, 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, create the rdataset if it is not found.

        Returns a ``dns.rdataset.Rdataset`` or ``None``.
        N)rK   rI   rJ   r
   r
   r   Úget_rdatasetÐ   s
    
zNode.get_rdatasetN©rF   r   r	   r   c                 C   s&   |   |||¡}|dk	r"| j |¡ dS )aD  Delete the rdataset matching the specified properties in the
        current node.

        If a matching rdataset does not exist, it is not an error.

        *rdclass*, an ``int``, the class of the rdataset.

        *rdtype*, an ``int``, the type of the rdataset.

        *covers*, an ``int``, the covered type.
        N)rL   r"   Úremove)r%   rF   r   r	   r2   r
   r
   r   Údelete_rdatasetõ   s    zNode.delete_rdataset©Úreplacementr   c                 C   sN   t |tjjƒstdƒ‚t |tjjƒr,| ¡ }|  |j	|j
|j¡ |  |¡ dS )aÅ  Replace an rdataset.

        It is not an error if there is no rdataset matching *replacement*.

        Ownership of the *replacement* object is transferred to the node;
        in other words, this method does not store a copy of *replacement*
        at the node, it stores *replacement* itself.

        *replacement*, a ``dns.rdataset.Rdataset``.

        Raises ``ValueError`` if *replacement* is not a
        ``dns.rdataset.Rdataset``.
        zreplacement is not an rdatasetN)Ú
isinstancer   r   r    Ú
ValueErrorZrrsetZRRsetZto_rdatasetrO   rF   r   r	   rD   ©r%   rQ   r
   r
   r   Úreplace_rdataset  s      ÿzNode.replace_rdataset©r   c                 C   s4   | j D ]&}t |j|j¡}|tjkr|  S qtjS )aT  Classify a node.

        A node which contains a CNAME or RRSIG(CNAME) is a
        ``NodeKind.CNAME`` node.

        A node which contains only "neutral" types, i.e. types allowed to
        co-exist with a CNAME, is a ``NodeKind.NEUTRAL`` node.  The neutral
        types are NSEC, NSEC3, KEY, and their associated RRSIGS.  An empty node
        is also considered neutral.

        A node which contains some rdataset which is not a CNAME, RRSIG(CNAME),
        or a neutral type is a a ``NodeKind.REGULAR`` node.  Regular nodes are
        also commonly referred to as "other data".
        )r"   r   r   r   r	   r   rB   r
   r
   r   r   %  s
    


zNode.classifyc                 C   s   dS )NFr
   r$   r
   r
   r   Úis_immutable:  s    zNode.is_immutable)#r   r   r   r   Ú	__slots__r&   r   r'   ÚNamer   r4   r   r/   r6   r9   r:   r;   r=   rD   r   ÚNONEÚ
rdataclassÚ
RdataClassr   Úboolr   r    rK   r   rL   rO   rU   r   r   rW   r
   r
   r
   r   r!   H   sL    ûú-û
ú)üûr!   c                       sÒ   e Zd Z‡ fdd„Zejjdfejjejj	ejj	e
ejjdœ‡ fdd„Zejjdfejjejj	ejj	e
eejj dœ‡ fdd„Zejjfejjejj	ejj	d	d
œdd„Zejjd	dœdd„Ze
dœdd„Z‡  ZS )ÚImmutableNodec                    s$   t ƒ  ¡  tdd„ |jD ƒƒ| _d S )Nc                 S   s   g | ]}t j |¡‘qS r
   )r   r   ZImmutableRdatasetr>   r
   r
   r   r@   C  s     z*ImmutableNode.__init__.<locals>.<listcomp>)Úsuperr&   Útupler"   )r%   Únode©Ú	__class__r
   r   r&   @  s    
ÿzImmutableNode.__init__FrE   c                    s   |rt dƒ‚tƒ  |||d¡S ©NÚ	immutableF)Ú	TypeErrorr_   rK   ©r%   rF   r   r	   rG   rb   r
   r   rK   F  s    zImmutableNode.find_rdatasetc                    s   |rt dƒ‚tƒ  |||d¡S rd   )rf   r_   rL   rg   rb   r
   r   rL   Q  s    zImmutableNode.get_rdatasetNrM   c                 C   s   t dƒ‚d S ©Nre   ©rf   )r%   rF   r   r	   r
   r
   r   rO   \  s    zImmutableNode.delete_rdatasetrP   c                 C   s   t dƒ‚d S rh   ri   rT   r
   r
   r   rU   d  s    zImmutableNode.replace_rdatasetrV   c                 C   s   dS )NTr
   r$   r
   r
   r   rW   g  s    zImmutableNode.is_immutable)r   r   r   r&   r   r   rZ   r[   r\   r   r]   r   r    rK   r   rL   rO   rU   rW   Ú__classcell__r
   r
   rb   r   r^   >  s8   
ûúû
úüûr^   )r   Úenumr+   Útypingr   r   r   Zdns.immutabler   Zdns.nameZdns.rdataclassZdns.rdatasetZdns.rdatatypeZdns.rendererZ	dns.rrsetr   r   r   ZNSECZNSEC3ZKEYr   r   ÚuniqueÚEnumr   r!   re   r^   r
   r
   r
   r   Ú<module>   s.   ÿý w