def iter_changed_datastream(self): if not config.datastream.enable_dnszone: return from noc.dns.models.dnszone import DNSZone if self.fqdn: # Touch forward zone fz = DNSZone.get_zone(self.fqdn) if fz: for ds, id in fz.iter_changed_datastream(): yield ds, id # Touch reverse zone rz = DNSZone.get_zone(self.address) if rz: for ds, id in rz.iter_changed_datastream(): yield ds, id
def iter_changed_datastream(self, changed_fields=None): if config.datastream.enable_address: yield "address", self.id if config.datastream.enable_dnszone: from noc.dns.models.dnszone import DNSZone if self.fqdn: # Touch forward zone fz = DNSZone.get_zone(self.fqdn) if fz: for ds, id in fz.iter_changed_datastream(changed_fields=changed_fields): yield ds, id # Touch reverse zone rz = DNSZone.get_zone(self.address) if rz: for ds, id in rz.iter_changed_datastream(changed_fields=changed_fields): yield ds, id
def iter_changed_datastream(self, changed_fields=None): if not config.datastream.enable_dnszone: return from noc.dns.models.dnszone import DNSZone if self.action == "D": zone = DNSZone.get_reverse_for_address(self.from_address) if zone: yield "dnszone", zone.id
def dns_zone(self, zone, zone_profile, dry_run=False, clean=False): z = DNSZone.get_by_name(zone) if z: self.print("Using existing zone '%s'" % zone) else: self.print("Creating zone '%s'" % zone) z = DNSZone(name=zone, profile=zone_profile) clean = False # Nothing to clean if z.profile.id != zone_profile.id: self.print("Setting profile to '%s'" % zone_profile.name) z.profile = zone_profile # Apply changes if dry_run: z.clean() # Set type else: z.save() # Clean zone when necessary if clean: self.print("Cleaning zone") for rr in DNSZoneRecord.objects.filter(zone=z): self.print("Removing %s %s" % (rr.type, rr.name)) if not dry_run: rr.delete() return z
def import_zone(self, path, zone_profile, address_profile, dry_run=False, force=False, clean=False): self.print("Loading zone file '%s'" % path) self.print("Parsing zone file using BIND parser") with open(path) as f: rrs = self.iter_bind_zone_rr(f) try: soa = next(rrs) except StopIteration: raise CommandError("Unable to parse zone file from %s" % path) zone = self.from_idna(soa.zone) z = DNSZone.get_by_name(zone) if z: self.print("Using existing zone '%s'" % zone) else: self.print("Creating zone '%s'" % zone) z = DNSZone(name=zone, profile=zone_profile) clean = False # Nothing to clean if z.profile.id != zone_profile.id: self.print("Setting profile to '%s'" % zone_profile.name) z.profile = zone_profile # Apply changes if dry_run: z.clean() # Set type else: z.save() # Clean zone when necessary if clean: self.print("Cleaning zone") for rr in DNSZoneRecord.objects.filter(zone=z): self.print("Removing %s %s" % (rr.type, rr.name)) if not dry_run: rr.delete() # Populate zone vrf = VRF.get_global() zz = zone + "." lz = len(zz) if z.is_forward: zp = None elif z.is_reverse_ipv4: # Calculate prefix for reverse zone zp = ".".join(reversed(zone[:-13].split("."))) + "." elif z.is_reverse_ipv6: raise CommandError("IPv6 reverse import is not implemented") else: raise CommandError("Unknown zone type") for rr in rrs: name = rr.name if name.endswith(zz): name = name[:-lz] if name.endswith("."): name = name[:-1] # rr = None # Skip zone NS if rr.type == "NS" and not name: continue if rr.type in ("A", "AAAA"): self.create_address( zone, vrf, rr.rdata, "%s.%s" % (name, zone) if name else zone, address_profile, dry_run=dry_run, force=force, ) elif rr.type == "PTR": if "." in name: address = zp + ".".join(reversed(name.split("."))) else: address = zp + name self.create_address(zone, vrf, address, rr.rdata, address_profile, dry_run=dry_run, force=force) else: zrr = DNSZoneRecord( zone=z, name=name, type=rr.type, ttl=rr.ttl, priority=rr.priority, content=rr.rdata, ) self.print("Creating %s %s" % (rr.type, rr.name)) if not dry_run: zrr.save()
def import_zone(self, path, options): is_test = bool(options["test"]) self.info("Loading zone file '%s'" % path) with open(path) as f: data = f.read() self.info("Parsing zone file using BIND parser") zone, rrs = self.parse_bind_zone(data) if not zone or not rrs: raise CommandError("Unable to parse zone file") # Find profile profile = self.get_profile(options) # Get or create zone to_clean = bool(options["clean"]) try: z = DNSZone.objects.get(name=zone) self.info("Using existing zone '%s'" % z) except DNSZone.DoesNotExist: self.info("Creating zone '%s'" % zone) z = DNSZone(name=zone, profile=profile) to_clean = False # Nothing to clean yet if z.profile != profile: self.info("Setting profile to '%s'" % profile) z.profile = profile if not is_test: z.save() # Clean zone when necessary if to_clean and z.id: self.info("Cleaning zone") for rr in z.dnszonerecord_set.all(): self.info("Removing %s %s" % (rr.type, rr.name)) if not is_test: rr.delete() # Populate zone vrf = VRF.get_global() zz = zone + "." lz = len(zz) if zone.endswith(".in-addr.arpa"): # Calculate prefix for reverse zone zp = zone[:-13].split(".") zp.reverse() zp = ".".join(zp) + "." else: # @todo: IPv6 reverse zp = None for name, t, value, ttl, priority in rrs: # print name, t, value if name.endswith(zz): name = name[:-lz] if name.endswith("."): name = name[:-1] rr = None if (t == "SOA") or (t == "NS" and not name): continue if t in ("A", "AAAA"): afi = "4" if t == "A" else "6" self.create_address( zone, vrf, afi, value, "%s.%s" % (name, zone) if name else zone, is_test) elif t == "PTR": if not zp: raise CommandError("IPv6 reverse zone import is still not supported") address = zp + name afi = "6" if ":" in address else "4" self.create_address(zone, vrf, afi, address, value, is_test) else: rr = DNSZoneRecord( zone=z, name=name, type=t, ttl=ttl, priority=priority, content=value ) if rr: self.info("Creating %s %s" % (rr.type, rr.name)) if not is_test: rr.save()