Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
rrset.py286 linesDownload Raw Back to dns
1# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license2 3# Copyright (C) 2003-2017 Nominum, Inc.4#5# Permission to use, copy, modify, and distribute this software and its6# documentation for any purpose with or without fee is hereby granted,7# provided that the above copyright notice and this permission notice8# appear in all copies.9#10# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES11# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF12# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR13# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES14# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN15# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT16# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.17 18"""DNS RRsets (an RRset is a named rdataset)"""19 20from typing import Any, Collection, Dict, Optional, Union, cast21 22import dns.name23import dns.rdataclass24import dns.rdataset25import dns.renderer26 27 28class RRset(dns.rdataset.Rdataset):29    """A DNS RRset (named rdataset).30 31    RRset inherits from Rdataset, and RRsets can be treated as32    Rdatasets in most cases.  There are, however, a few notable33    exceptions.  RRsets have different to_wire() and to_text() method34    arguments, reflecting the fact that RRsets always have an owner35    name.36    """37 38    __slots__ = ["name", "deleting"]39 40    def __init__(41        self,42        name: dns.name.Name,43        rdclass: dns.rdataclass.RdataClass,44        rdtype: dns.rdatatype.RdataType,45        covers: dns.rdatatype.RdataType = dns.rdatatype.NONE,46        deleting: Optional[dns.rdataclass.RdataClass] = None,47    ):48        """Create a new RRset."""49 50        super().__init__(rdclass, rdtype, covers)51        self.name = name52        self.deleting = deleting53 54    def _clone(self):55        obj = super()._clone()56        obj.name = self.name57        obj.deleting = self.deleting58        return obj59 60    def __repr__(self):61        if self.covers == 0:62            ctext = ""63        else:64            ctext = "(" + dns.rdatatype.to_text(self.covers) + ")"65        if self.deleting is not None:66            dtext = " delete=" + dns.rdataclass.to_text(self.deleting)67        else:68            dtext = ""69        return (70            "<DNS "71            + str(self.name)72            + " "73            + dns.rdataclass.to_text(self.rdclass)74            + " "75            + dns.rdatatype.to_text(self.rdtype)76            + ctext77            + dtext78            + " RRset: "79            + self._rdata_repr()80            + ">"81        )82 83    def __str__(self):84        return self.to_text()85 86    def __eq__(self, other):87        if isinstance(other, RRset):88            if self.name != other.name:89                return False90        elif not isinstance(other, dns.rdataset.Rdataset):91            return False92        return super().__eq__(other)93 94    def match(self, *args: Any, **kwargs: Any) -> bool:  # type: ignore[override]95        """Does this rrset match the specified attributes?96 97        Behaves as :py:func:`full_match()` if the first argument is a98        ``dns.name.Name``, and as :py:func:`dns.rdataset.Rdataset.match()`99        otherwise.100 101        (This behavior fixes a design mistake where the signature of this102        method became incompatible with that of its superclass.  The fix103        makes RRsets matchable as Rdatasets while preserving backwards104        compatibility.)105        """106        if isinstance(args[0], dns.name.Name):107            return self.full_match(*args, **kwargs)  # type: ignore[arg-type]108        else:109            return super().match(*args, **kwargs)  # type: ignore[arg-type]110 111    def full_match(112        self,113        name: dns.name.Name,114        rdclass: dns.rdataclass.RdataClass,115        rdtype: dns.rdatatype.RdataType,116        covers: dns.rdatatype.RdataType,117        deleting: Optional[dns.rdataclass.RdataClass] = None,118    ) -> bool:119        """Returns ``True`` if this rrset matches the specified name, class,120        type, covers, and deletion state.121        """122        if not super().match(rdclass, rdtype, covers):123            return False124        if self.name != name or self.deleting != deleting:125            return False126        return True127 128    # pylint: disable=arguments-differ129 130    def to_text(  # type: ignore[override]131        self,132        origin: Optional[dns.name.Name] = None,133        relativize: bool = True,134        **kw: Dict[str, Any],135    ) -> str:136        """Convert the RRset into DNS zone file format.137 138        See ``dns.name.Name.choose_relativity`` for more information139        on how *origin* and *relativize* determine the way names140        are emitted.141 142        Any additional keyword arguments are passed on to the rdata143        ``to_text()`` method.144 145        *origin*, a ``dns.name.Name`` or ``None``, the origin for relative146        names.147 148        *relativize*, a ``bool``.  If ``True``, names will be relativized149        to *origin*.150        """151 152        return super().to_text(153            self.name, origin, relativize, self.deleting, **kw  # type: ignore154        )155 156    def to_wire(  # type: ignore[override]157        self,158        file: Any,159        compress: Optional[dns.name.CompressType] = None,  # type: ignore160        origin: Optional[dns.name.Name] = None,161        **kw: Dict[str, Any],162    ) -> int:163        """Convert the RRset to wire format.164 165        All keyword arguments are passed to ``dns.rdataset.to_wire()``; see166        that function for details.167 168        Returns an ``int``, the number of records emitted.169        """170 171        return super().to_wire(172            self.name, file, compress, origin, self.deleting, **kw  # type:ignore173        )174 175    # pylint: enable=arguments-differ176 177    def to_rdataset(self) -> dns.rdataset.Rdataset:178        """Convert an RRset into an Rdataset.179 180        Returns a ``dns.rdataset.Rdataset``.181        """182        return dns.rdataset.from_rdata_list(self.ttl, list(self))183 184 185def from_text_list(186    name: Union[dns.name.Name, str],187    ttl: int,188    rdclass: Union[dns.rdataclass.RdataClass, str],189    rdtype: Union[dns.rdatatype.RdataType, str],190    text_rdatas: Collection[str],191    idna_codec: Optional[dns.name.IDNACodec] = None,192    origin: Optional[dns.name.Name] = None,193    relativize: bool = True,194    relativize_to: Optional[dns.name.Name] = None,195) -> RRset:196    """Create an RRset with the specified name, TTL, class, and type, and with197    the specified list of rdatas in text format.198 199    *idna_codec*, a ``dns.name.IDNACodec``, specifies the IDNA200    encoder/decoder to use; if ``None``, the default IDNA 2003201    encoder/decoder is used.202 203    *origin*, a ``dns.name.Name`` (or ``None``), the204    origin to use for relative names.205 206    *relativize*, a ``bool``.  If true, name will be relativized.207 208    *relativize_to*, a ``dns.name.Name`` (or ``None``), the origin to use209    when relativizing names.  If not set, the *origin* value will be used.210 211    Returns a ``dns.rrset.RRset`` object.212    """213 214    if isinstance(name, str):215        name = dns.name.from_text(name, None, idna_codec=idna_codec)216    rdclass = dns.rdataclass.RdataClass.make(rdclass)217    rdtype = dns.rdatatype.RdataType.make(rdtype)218    r = RRset(name, rdclass, rdtype)219    r.update_ttl(ttl)220    for t in text_rdatas:221        rd = dns.rdata.from_text(222            r.rdclass, r.rdtype, t, origin, relativize, relativize_to, idna_codec223        )224        r.add(rd)225    return r226 227 228def from_text(229    name: Union[dns.name.Name, str],230    ttl: int,231    rdclass: Union[dns.rdataclass.RdataClass, str],232    rdtype: Union[dns.rdatatype.RdataType, str],233    *text_rdatas: Any,234) -> RRset:235    """Create an RRset with the specified name, TTL, class, and type and with236    the specified rdatas in text format.237 238    Returns a ``dns.rrset.RRset`` object.239    """240 241    return from_text_list(242        name, ttl, rdclass, rdtype, cast(Collection[str], text_rdatas)243    )244 245 246def from_rdata_list(247    name: Union[dns.name.Name, str],248    ttl: int,249    rdatas: Collection[dns.rdata.Rdata],250    idna_codec: Optional[dns.name.IDNACodec] = None,251) -> RRset:252    """Create an RRset with the specified name and TTL, and with253    the specified list of rdata objects.254 255    *idna_codec*, a ``dns.name.IDNACodec``, specifies the IDNA256    encoder/decoder to use; if ``None``, the default IDNA 2003257    encoder/decoder is used.258 259    Returns a ``dns.rrset.RRset`` object.260 261    """262 263    if isinstance(name, str):264        name = dns.name.from_text(name, None, idna_codec=idna_codec)265 266    if len(rdatas) == 0:267        raise ValueError("rdata list must not be empty")268    r = None269    for rd in rdatas:270        if r is None:271            r = RRset(name, rd.rdclass, rd.rdtype)272            r.update_ttl(ttl)273        r.add(rd)274    assert r is not None275    return r276 277 278def from_rdata(name: Union[dns.name.Name, str], ttl: int, *rdatas: Any) -> RRset:279    """Create an RRset with the specified name and TTL, and with280    the specified rdata objects.281 282    Returns a ``dns.rrset.RRset`` object.283    """284 285    return from_rdata_list(name, ttl, cast(Collection[dns.rdata.Rdata], rdatas))286 
codekingpro/portable-devtools · Team Ai