support for GENERATE, network instead of vlan

This commit is contained in:
ROTTLER Tamas 2023-09-21 03:11:06 +02:00
parent 9f29d721f5
commit 260ff97c0a

View File

@ -45,7 +45,7 @@ class Rev:
self.revzones[zone]['info'] += info self.revzones[zone]['info'] += info
#print(f"zoneinfo {zone} - {info}") #print(f"zoneinfo {zone} - {info}")
def ptr(self, zone, addr, name, vlan = "", noauto = False): def ptr(self, zone, addr, name, network = "", noauto = False, generate = False, comment = False):
self._check_zone(zone) self._check_zone(zone)
if not (ipbyte := re.match(r"(\d+)\.(\d+)\.(\d+)\.(\d+)", addr)): if not (ipbyte := re.match(r"(\d+)\.(\d+)\.(\d+)\.(\d+)", addr)):
raise RevInvalidAddress(f"invalid address: {addr} ({name} / rev zone: {zone})") raise RevInvalidAddress(f"invalid address: {addr} ({name} / rev zone: {zone})")
@ -60,8 +60,10 @@ class Rev:
'addr': addr, 'addr': addr,
'ptr': ptr, 'ptr': ptr,
'name': name, 'name': name,
'vlan': vlan, 'network': network,
'noauto': noauto 'noauto': noauto,
'generate': generate,
'comment': comment
} }
#print(f"{zone} {addr} {ptr}") #print(f"{zone} {addr} {ptr}")
@ -78,7 +80,7 @@ class Rev:
ptr = [] ptr = []
for ip in sorted(self.revzones[zone]['ptr']): for ip in sorted(self.revzones[zone]['ptr']):
rec = self.revzones[zone]['ptr'][ip] rec = self.revzones[zone]['ptr'][ip]
if rec['noauto']: if rec['noauto'] or rec['comment']:
continue; continue;
ptr.append(f"{rec['ptr']}\t\tIN PTR\t{rec['name']}") ptr.append(f"{rec['ptr']}\t\tIN PTR\t{rec['name']}")
return other + ptr return other + ptr
@ -87,17 +89,27 @@ class Rev:
self._check_zone(zone) self._check_zone(zone)
other = self.revzones[zone]['other'] other = self.revzones[zone]['other']
wiki = [f"^ {zone} - {self.revzones[zone]['info']} ^^^", wiki = [f"^ {zone} - {self.revzones[zone]['info']} ^^^",
f"^IP cím^név^vlan^"] f"^IP cím^név^hálózat^"]
last_addr = None last_addr = None
for ip in sorted(self.revzones[zone]['ptr']): for ip in sorted(self.revzones[zone]['ptr']):
rec = self.revzones[zone]['ptr'][ip] rec = self.revzones[zone]['ptr'][ip]
if last_addr and re.sub(r"(\d+)$", lambda r : str(int(r[1])+1), last_addr) != rec['addr']: if last_addr and re.sub(r"(\d+)$", lambda r : str(int(r[1])+1), last_addr) != rec['addr']:
wiki.append("| |||") wiki.append("| |||")
vlan = rec['vlan']
if rec['noauto']:
vlan = "**M** "+ vlan
wiki.append(f"|{rec['addr']}|{rec['name']}|{vlan}|")
last_addr = rec['addr'] last_addr = rec['addr']
if rec['generate']:
if rec['generate'] == 'first':
gen_first_name = rec['name']
gen_first_addr = rec['addr']
continue
elif rec['generate'] == 'middle':
continue
elif rec['generate'] == 'last':
rec['name'] = f"{gen_first_name}\\\\ ...\\\\ {rec['name']}"
rec['addr'] = f"{gen_first_addr}\\\\ ...\\\\ {rec['addr']}"
network = re.sub(r'(v\d+)', '**\\1**', rec['network'])
if rec['noauto']:
network = "**M** "+ network
wiki.append(f"|{rec['addr']}|{rec['name']}|{network}|")
return wiki return wiki
@ -105,7 +117,8 @@ def read_zone(zonefile, rev):
with open(zonefile, 'r') as f: with open(zonefile, 'r') as f:
origin = None origin = None
revzone = None revzone = None
vlan = "" network = ""
network_ptrs = False
while line := f.readline(): while line := f.readline():
if r := re.match(r"\s*\$ORIGIN\s*(\S*)", line): if r := re.match(r"\s*\$ORIGIN\s*(\S*)", line):
origin = r[1] origin = r[1]
@ -119,7 +132,20 @@ def read_zone(zonefile, rev):
exit(1) exit(1)
rev.add_zone(revzone) rev.add_zone(revzone)
elif r:= re.match(r"\s*;.*?\[vlan\]\s*(.*)", line): elif r:= re.match(r"\s*;.*?\[vlan\]\s*(.*)", line):
vlan = r[1] network = r[1]
network_ptrs = False
print(f"warning: legacy [vlan] in zone file {zonefile}")
elif r:= re.match(r"\s*;.*?\[net(work)?\]\s*(.*)", line):
prev_network = network
network = r[2]
if prev_network and not network_ptrs:
# no ptr records in previous network
if r:= re.match(r"[0-9./]+", network):
try:
rev.ptr(revzone, r[0], f"-", network=network, comment=True)
except:
pass
network_ptrs = False
if not revzone or not origin: if not revzone or not origin:
continue continue
if r := re.match(r"\s*([a-z0-9.-]+)\s+IN\s+A\s+([0-9.]+)(.*)", line, flags=re.I): if r := re.match(r"\s*([a-z0-9.-]+)\s+IN\s+A\s+([0-9.]+)(.*)", line, flags=re.I):
@ -127,7 +153,27 @@ def read_zone(zonefile, rev):
if re.search(r"\[no_autorev\]", extra): if re.search(r"\[no_autorev\]", extra):
continue continue
try: try:
rev.ptr(revzone, addr, f"{name}.{origin}", vlan=vlan) rev.ptr(revzone, addr, f"{name}.{origin}", network=network)
network_ptrs = True
except (RevDuplicateAddress, RevInvalidAddress) as e:
print(e, file=sys.stderr)
exit(1)
elif r := re.match(r"\s*\$GENERATE\s+(\d+)-(\d+)\s+([a-z0-9.$-]+)\s+A\s+([0-9.$]+)", line, flags=re.I):
begin, end, name_pattern, addr_pattern = int(r[1]), int(r[2]), r[3], r[4]
if begin < 0 or begin >= end or end > 255:
raise RevInvalidAddress(f"invalid generate range: {begin}-{end}")
for i in range(begin, end + 1):
name = re.sub(r"\$", str(i), name_pattern)
addr = re.sub(r"\$", str(i), addr_pattern)
if i == begin:
gen = 'first'
elif i == end:
gen = 'last'
else:
gen = 'middle'
try:
rev.ptr(revzone, addr, f"{name}.{origin}", network=network, generate=gen)
network_ptrs = True
except (RevDuplicateAddress, RevInvalidAddress) as e: except (RevDuplicateAddress, RevInvalidAddress) as e:
print(e, file=sys.stderr) print(e, file=sys.stderr)
exit(1) exit(1)