Example #1
0
    def _rr_line(self, section):
        """Process one line from the text format answer, authority, or
        additional data sections.
        """

        deleting = None
        # Name
        token = self.tok.get(want_leading = True)
        if not token.is_whitespace():
            self.last_name = mname.from_text(token.value, None)
        name = self.last_name
        token = self.tok.get()
        if not token.is_identifier():
            raise exception.SyntaxError
        # TTL
        try:
            ttl = int(token.value, 0)
            token = self.tok.get()
            if not token.is_identifier():
                raise exception.SyntaxError
        except exception.SyntaxError:
            raise exception.SyntaxError
        except:
            ttl = 0
        # Class
        try:
            rdclass = rdataclass.from_text(token.value)
            token = self.tok.get()
            if not token.is_identifier():
                raise exception.SyntaxError
            if rdclass == rdataclass.ANY or rdclass == rdataclass.NONE:
                deleting = rdclass
                rdclass = self.zone_rdclass
        except exception.SyntaxError:
            raise exception.SyntaxError
        except:
            rdclass = rdataclass.IN
        # Type
        rdtype = rdatatype.from_text(token.value)
        token = self.tok.get()
        if not token.is_eol_or_eof():
            self.tok.unget(token)
            rd = rdata.from_text(rdclass, rdtype, self.tok, None)
            covers = rd.covers()
        else:
            rd = None
            covers = rdatatype.NONE
        rrset = self.message.find_rrset(section, name,
                                        rdclass, rdtype, covers,
                                        deleting, True, self.updating)
        if not rd is None:
            rrset.add(rd, ttl)
Example #2
0
    def _rr_line(self, section):
        """Process one line from the text format answer, authority, or
        additional data sections.
        """

        deleting = None
        # Name
        token = self.tok.get(want_leading=True)
        if not token.is_whitespace():
            self.last_name = mname.from_text(token.value, None)
        name = self.last_name
        token = self.tok.get()
        if not token.is_identifier():
            raise exception.SyntaxError
        # TTL
        try:
            ttl = int(token.value, 0)
            token = self.tok.get()
            if not token.is_identifier():
                raise exception.SyntaxError
        except exception.SyntaxError:
            raise exception.SyntaxError
        except:
            ttl = 0
        # Class
        try:
            rdclass = rdataclass.from_text(token.value)
            token = self.tok.get()
            if not token.is_identifier():
                raise exception.SyntaxError
            if rdclass == rdataclass.ANY or rdclass == rdataclass.NONE:
                deleting = rdclass
                rdclass = self.zone_rdclass
        except exception.SyntaxError:
            raise exception.SyntaxError
        except:
            rdclass = rdataclass.IN
        # Type
        rdtype = rdatatype.from_text(token.value)
        token = self.tok.get()
        if not token.is_eol_or_eof():
            self.tok.unget(token)
            rd = rdata.from_text(rdclass, rdtype, self.tok, None)
            covers = rd.covers()
        else:
            rd = None
            covers = rdatatype.NONE
        rrset = self.message.find_rrset(section, name, rdclass, rdtype, covers,
                                        deleting, True, self.updating)
        if not rd is None:
            rrset.add(rd, ttl)
Example #3
0
def from_text_list(rdclass, rdtype, ttl, text_rdatas):
    """Create an rdataset with the specified class, type, and TTL, and with
    the specified list of rdatas in text format.

    @rtype: rdataset.Rdataset object
    """

    if isinstance(rdclass, (str, unicode)):
        rdclass = rdataclass.from_text(rdclass)
    if isinstance(rdtype, (str, unicode)):
        rdtype = rdatatype.from_text(rdtype)
    r = Rdataset(rdclass, rdtype)
    r.update_ttl(ttl)
    for t in text_rdatas:
        rd = rdata.from_text(r.rdclass, r.rdtype, t)
        r.add(rd)
    return r
Example #4
0
    def delete(self, name, *args):
        """Delete records.  The first argument is always a name.  The other
        arguments can be:

                - I{nothing}

                - rdataset...

                - rdata...

                - rdtype, [string...]"""

        if isinstance(name, (str, unicode)):
            name = name.from_text(name, None)
        if len(args) == 0:
            rrset = self.find_rrset(self.authority, name, rdataclass.ANY,
                                    rdatatype.ANY, rdatatype.NONE,
                                    rdatatype.ANY, True, True)
        elif isinstance(args[0], rdataset.Rdataset):
            for rds in args:
                for rd in rds:
                    self._add_rr(name, 0, rd, rdataclass.NONE)
        else:
            args = list(args)
            if isinstance(args[0], rdata.Rdata):
                for rd in args:
                    self._add_rr(name, 0, rd, rdataclass.NONE)
            else:
                rdtype = args.pop(0)
                if isinstance(rdtype, (str, unicode)):
                    rdtype = rdatatype.from_text(rdtype)
                if len(args) == 0:
                    rrset = self.find_rrset(self.authority, name,
                                            self.zone_rdclass, rdtype,
                                            rdatatype.NONE,
                                            rdataclass.ANY,
                                            True, True)
                else:
                    for s in args:
                        rd = rdata.from_text(self.zone_rdclass, rdtype, s,
                                                 self.origin)
                        self._add_rr(name, 0, rd, rdataclass.NONE)
Example #5
0
    def delete(self, name, *args):
        """Delete records.  The first argument is always a name.  The other
        arguments can be:

                - I{nothing}

                - rdataset...

                - rdata...

                - rdtype, [string...]"""

        if isinstance(name, (str, unicode)):
            name = name.from_text(name, None)
        if len(args) == 0:
            rrset = self.find_rrset(self.authority, name, rdataclass.ANY,
                                    rdatatype.ANY, rdatatype.NONE,
                                    rdatatype.ANY, True, True)
        elif isinstance(args[0], rdataset.Rdataset):
            for rds in args:
                for rd in rds:
                    self._add_rr(name, 0, rd, rdataclass.NONE)
        else:
            args = list(args)
            if isinstance(args[0], rdata.Rdata):
                for rd in args:
                    self._add_rr(name, 0, rd, rdataclass.NONE)
            else:
                rdtype = args.pop(0)
                if isinstance(rdtype, (str, unicode)):
                    rdtype = rdatatype.from_text(rdtype)
                if len(args) == 0:
                    rrset = self.find_rrset(self.authority, name,
                                            self.zone_rdclass, rdtype,
                                            rdatatype.NONE, rdataclass.ANY,
                                            True, True)
                else:
                    for s in args:
                        rd = rdata.from_text(self.zone_rdclass, rdtype, s,
                                             self.origin)
                        self._add_rr(name, 0, rd, rdataclass.NONE)
Example #6
0
    def _add(self, replace, section, name, *args):
        """Add records.  The first argument is the replace mode.  If
        false, RRs are added to an existing RRset; if true, the RRset
        is replaced with the specified contents.  The second
        argument is the section to add to.  The third argument
        is always a name.  The other arguments can be:

                - rdataset...

                - ttl, rdata...

                - ttl, rdtype, string..."""

        if isinstance(name, (str, unicode)):
            name = name.from_text(name, None)
        if isinstance(args[0], rdataset.Rdataset):
            for rds in args:
                if replace:
                    self.delete(name, rds.rdtype)
                for rd in rds:
                    self._add_rr(name, rds.ttl, rd, section=section)
        else:
            args = list(args)
            ttl = int(args.pop(0))
            if isinstance(args[0], rdata.Rdata):
                if replace:
                    self.delete(name, args[0].rdtype)
                for rd in args:
                    self._add_rr(name, ttl, rd, section=section)
            else:
                rdtype = args.pop(0)
                if isinstance(rdtype, str):
                    rdtype = rdatatype.from_text(rdtype)
                if replace:
                    self.delete(name, rdtype)
                for s in args:
                    rd = rdata.from_text(self.zone_rdclass, rdtype, s,
                                             self.origin)
                    self._add_rr(name, ttl, rd, section=section)
Example #7
0
    def _add(self, replace, section, name, *args):
        """Add records.  The first argument is the replace mode.  If
        false, RRs are added to an existing RRset; if true, the RRset
        is replaced with the specified contents.  The second
        argument is the section to add to.  The third argument
        is always a name.  The other arguments can be:

                - rdataset...

                - ttl, rdata...

                - ttl, rdtype, string..."""

        if isinstance(name, (str, unicode)):
            name = name.from_text(name, None)
        if isinstance(args[0], rdataset.Rdataset):
            for rds in args:
                if replace:
                    self.delete(name, rds.rdtype)
                for rd in rds:
                    self._add_rr(name, rds.ttl, rd, section=section)
        else:
            args = list(args)
            ttl = int(args.pop(0))
            if isinstance(args[0], rdata.Rdata):
                if replace:
                    self.delete(name, args[0].rdtype)
                for rd in args:
                    self._add_rr(name, ttl, rd, section=section)
            else:
                rdtype = args.pop(0)
                if isinstance(rdtype, str):
                    rdtype = rdatatype.from_text(rdtype)
                if replace:
                    self.delete(name, rdtype)
                for s in args:
                    rd = rdata.from_text(self.zone_rdclass, rdtype, s,
                                         self.origin)
                    self._add_rr(name, ttl, rd, section=section)
Example #8
0
    def _generate_line(self):
        # range lhs [ttl] [class] type rhs [ comment ]
        """Process one line containing the GENERATE statement from a DNS
        master file."""
        if self.current_origin is None:
            raise UnknownOrigin

        token = self.tok.get()
        # Range (required)
        try:
            start, stop, step = grange.from_text(token.value)
            token = self.tok.get()
            if not token.is_identifier():
                raise exception.SyntaxError
        except:
            raise exception.SyntaxError

        # lhs (required)
        try:
            lhs = token.value
            token = self.tok.get()
            if not token.is_identifier():
                raise exception.SyntaxError
        except:
            raise exception.SyntaxError

        # TTL
        try:
            ttl = ttl.from_text(token.value)
            token = self.tok.get()
            if not token.is_identifier():
                raise exception.SyntaxError
        except ttl.BadTTL:
            ttl = self.ttl
        # Class
        try:
            rdclass = rdataclass.from_text(token.value)
            token = self.tok.get()
            if not token.is_identifier():
                raise exception.SyntaxError
        except exception.SyntaxError:
            raise exception.SyntaxError
        except:
            rdclass = self.zone.rdclass
        if rdclass != self.zone.rdclass:
            raise exception.SyntaxError("RR class is not zone's class")
        # Type
        try:
            rdtype = rdatatype.from_text(token.value)
            token = self.tok.get()
            if not token.is_identifier():
                raise exception.SyntaxError
        except:
            raise exception.SyntaxError("unknown rdatatype '%s'" % token.value)

        # lhs (required)
        try:
            rhs = token.value
        except:
            raise exception.SyntaxError

        lmod, lsign, loffset, lwidth, lbase = self._parse_modify(lhs)
        rmod, rsign, roffset, rwidth, rbase = self._parse_modify(rhs)
        for i in range(start, stop + 1, step):
            # +1 because bind is inclusive and python is exclusive

            if lsign == '+':
                lindex = i + int(loffset)
            elif lsign == '-':
                lindex = i - int(loffset)

            if rsign == '-':
                rindex = i - int(roffset)
            elif rsign == '+':
                rindex = i + int(roffset)

            lzfindex = str(lindex).zfill(int(lwidth))
            rzfindex = str(rindex).zfill(int(rwidth))

            name = lhs.replace('$%s' % (lmod), lzfindex)
            rdata = rhs.replace('$%s' % (rmod), rzfindex)

            self.last_name = name.from_text(name, self.current_origin)
            name = self.last_name
            if not name.is_subdomain(self.zone.origin):
                self._eat_line()
                return
            if self.relativize:
                name = name.relativize(self.zone.origin)

            n = self.zone.nodes.get(name)
            if n is None:
                n = self.zone.node_factory()
                self.zone.nodes[name] = n
            try:
                rd = rdata.from_text(rdclass, rdtype, rdata,
                                     self.current_origin, False)
            except exception.SyntaxError:
                # Catch and reraise.
                (ty, va) = sys.exc_info()[:2]
                raise va
            except:
                # All exceptions that occur in the processing of rdata
                # are treated as syntax errors.  This is not strictly
                # correct, but it is correct almost all of the time.
                # We convert them to syntax errors so that we can emit
                # helpful filename:line info.
                (ty, va) = sys.exc_info()[:2]
                raise exception.SyntaxError("caught exception %s: %s" %
                                            (str(ty), str(va)))

            rd.choose_relativity(self.zone.origin, self.relativize)
            covers = rd.covers()
            rds = n.find_rdataset(rdclass, rdtype, covers, True)
            rds.add(rd, ttl)
Example #9
0
    def _rr_line(self):
        """Process one line from a DNS master file."""
        # Name
        if self.current_origin is None:
            raise UnknownOrigin
        token = self.tok.get(want_leading=True)
        if not token.is_whitespace():
            self.last_name = name.from_text(token.value, self.current_origin)
        else:
            token = self.tok.get()
            if token.is_eol_or_eof():
                # treat leading WS followed by EOL/EOF as if they were EOL/EOF.
                return
            self.tok.unget(token)
        name = self.last_name
        if not name.is_subdomain(self.zone.origin):
            self._eat_line()
            return
        if self.relativize:
            name = name.relativize(self.zone.origin)
        token = self.tok.get()
        if not token.is_identifier():
            raise exception.SyntaxError
        # TTL
        try:
            ttl = ttl.from_text(token.value)
            token = self.tok.get()
            if not token.is_identifier():
                raise exception.SyntaxError
        except ttl.BadTTL:
            ttl = self.ttl
        # Class
        try:
            rdclass = rdataclass.from_text(token.value)
            token = self.tok.get()
            if not token.is_identifier():
                raise exception.SyntaxError
        except exception.SyntaxError:
            raise exception.SyntaxError
        except:
            rdclass = self.zone.rdclass
        if rdclass != self.zone.rdclass:
            raise exception.SyntaxError("RR class is not zone's class")
        # Type
        try:
            rdtype = rdatatype.from_text(token.value)
        except:
            raise exception.SyntaxError("unknown rdatatype '%s'" % token.value)
        n = self.zone.nodes.get(name)
        if n is None:
            n = self.zone.node_factory()
            self.zone.nodes[name] = n
        try:
            rd = rdata.from_text(rdclass, rdtype, self.tok,
                                 self.current_origin, False)
        except exception.SyntaxError:
            # Catch and reraise.
            (ty, va) = sys.exc_info()[:2]
            raise va
        except:
            # All exceptions that occur in the processing of rdata
            # are treated as syntax errors.  This is not strictly
            # correct, but it is correct almost all of the time.
            # We convert them to syntax errors so that we can emit
            # helpful filename:line info.
            (ty, va) = sys.exc_info()[:2]
            raise exception.SyntaxError("caught exception %s: %s" %
                                        (str(ty), str(va)))

        rd.choose_relativity(self.zone.origin, self.relativize)
        covers = rd.covers()
        rds = n.find_rdataset(rdclass, rdtype, covers, True)
        rds.add(rd, ttl)
Example #10
0
    def _generate_line(self):
        # range lhs [ttl] [class] type rhs [ comment ]
        """Process one line containing the GENERATE statement from a DNS
        master file."""
        if self.current_origin is None:
            raise UnknownOrigin

        token = self.tok.get()
        # Range (required)
        try:
            start, stop, step = grange.from_text(token.value)
            token = self.tok.get()
            if not token.is_identifier():
                raise exception.SyntaxError
        except:
            raise exception.SyntaxError

        # lhs (required)
        try:
            lhs = token.value
            token = self.tok.get()
            if not token.is_identifier():
                raise exception.SyntaxError
        except:
            raise exception.SyntaxError

        # TTL
        try:
            ttl = ttl.from_text(token.value)
            token = self.tok.get()
            if not token.is_identifier():
                raise exception.SyntaxError
        except ttl.BadTTL:
            ttl = self.ttl
        # Class
        try:
            rdclass = rdataclass.from_text(token.value)
            token = self.tok.get()
            if not token.is_identifier():
                raise exception.SyntaxError
        except exception.SyntaxError:
            raise exception.SyntaxError
        except:
            rdclass = self.zone.rdclass
        if rdclass != self.zone.rdclass:
            raise exception.SyntaxError("RR class is not zone's class")
        # Type
        try:
            rdtype = rdatatype.from_text(token.value)
            token = self.tok.get()
            if not token.is_identifier():
                raise exception.SyntaxError
        except:
            raise exception.SyntaxError("unknown rdatatype '%s'" %
                    token.value)

        # lhs (required)
        try:
            rhs = token.value
        except:
            raise exception.SyntaxError


        lmod, lsign, loffset, lwidth, lbase = self._parse_modify(lhs)
        rmod, rsign, roffset, rwidth, rbase = self._parse_modify(rhs)
        for i in range(start, stop + 1, step):
            # +1 because bind is inclusive and python is exclusive

            if lsign == '+':
                lindex = i + int(loffset)
            elif lsign == '-':
                lindex = i - int(loffset)

            if rsign == '-':
                rindex = i - int(roffset)
            elif rsign == '+':
                rindex = i + int(roffset)

            lzfindex = str(lindex).zfill(int(lwidth))
            rzfindex = str(rindex).zfill(int(rwidth))


            name = lhs.replace('$%s' % (lmod), lzfindex)
            rdata = rhs.replace('$%s' % (rmod), rzfindex)

            self.last_name = name.from_text(name, self.current_origin)
            name = self.last_name
            if not name.is_subdomain(self.zone.origin):
                self._eat_line()
                return
            if self.relativize:
                name = name.relativize(self.zone.origin)

            n = self.zone.nodes.get(name)
            if n is None:
                n = self.zone.node_factory()
                self.zone.nodes[name] = n
            try:
                rd = rdata.from_text(rdclass, rdtype, rdata,
                                         self.current_origin, False)
            except exception.SyntaxError:
                # Catch and reraise.
                (ty, va) = sys.exc_info()[:2]
                raise va
            except:
                # All exceptions that occur in the processing of rdata
                # are treated as syntax errors.  This is not strictly
                # correct, but it is correct almost all of the time.
                # We convert them to syntax errors so that we can emit
                # helpful filename:line info.
                (ty, va) = sys.exc_info()[:2]
                raise exception.SyntaxError("caught exception %s: %s" %
                        (str(ty), str(va)))

            rd.choose_relativity(self.zone.origin, self.relativize)
            covers = rd.covers()
            rds = n.find_rdataset(rdclass, rdtype, covers, True)
            rds.add(rd, ttl)
Example #11
0
    def _rr_line(self):
        """Process one line from a DNS master file."""
        # Name
        if self.current_origin is None:
            raise UnknownOrigin
        token = self.tok.get(want_leading = True)
        if not token.is_whitespace():
            self.last_name = name.from_text(token.value, self.current_origin)
        else:
            token = self.tok.get()
            if token.is_eol_or_eof():
                # treat leading WS followed by EOL/EOF as if they were EOL/EOF.
                return
            self.tok.unget(token)
        name = self.last_name
        if not name.is_subdomain(self.zone.origin):
            self._eat_line()
            return
        if self.relativize:
            name = name.relativize(self.zone.origin)
        token = self.tok.get()
        if not token.is_identifier():
            raise exception.SyntaxError
        # TTL
        try:
            ttl = ttl.from_text(token.value)
            token = self.tok.get()
            if not token.is_identifier():
                raise exception.SyntaxError
        except ttl.BadTTL:
            ttl = self.ttl
        # Class
        try:
            rdclass = rdataclass.from_text(token.value)
            token = self.tok.get()
            if not token.is_identifier():
                raise exception.SyntaxError
        except exception.SyntaxError:
            raise exception.SyntaxError
        except:
            rdclass = self.zone.rdclass
        if rdclass != self.zone.rdclass:
            raise exception.SyntaxError("RR class is not zone's class")
        # Type
        try:
            rdtype = rdatatype.from_text(token.value)
        except:
            raise exception.SyntaxError("unknown rdatatype '%s'" % token.value)
        n = self.zone.nodes.get(name)
        if n is None:
            n = self.zone.node_factory()
            self.zone.nodes[name] = n
        try:
            rd = rdata.from_text(rdclass, rdtype, self.tok,
                                     self.current_origin, False)
        except exception.SyntaxError:
            # Catch and reraise.
            (ty, va) = sys.exc_info()[:2]
            raise va
        except:
            # All exceptions that occur in the processing of rdata
            # are treated as syntax errors.  This is not strictly
            # correct, but it is correct almost all of the time.
            # We convert them to syntax errors so that we can emit
            # helpful filename:line info.
            (ty, va) = sys.exc_info()[:2]
            raise exception.SyntaxError("caught exception %s: %s" % (str(ty), str(va)))

        rd.choose_relativity(self.zone.origin, self.relativize)
        covers = rd.covers()
        rds = n.find_rdataset(rdclass, rdtype, covers, True)
        rds.add(rd, ttl)