Files
dns-manager/dns-zone-add

134 lines
5.1 KiB
Python
Executable File

#!/usr/bin/env python3
import argparse
import dns.rdataclass
import dns.rdataset
import dns.rdatatype
import dnsmgr
import sys
from time import sleep
def main():
preparser = argparse.ArgumentParser(add_help=False)
preparser.add_argument('-b', '--batch', action='store_true')
preargs, args = preparser.parse_known_args()
nargs = None if preargs.batch else '?'
parser = argparse.ArgumentParser(description='Add DNS zones.')
parser.add_argument('-b', '--batch', help='run in batch mode (no user input)', action='store_true')
parser.add_argument('-c', '--config', help='path to config file', default=dnsmgr.DEFAULT_CFGFILE)
parser.add_argument('-t', '--config-template', help='config file/template (overrides value set in ZONE_TEMPLATES config option)', default=None)
parser.add_argument('-z', '--zone-template', help='zone file/template (overrides value set in ZONE_TEMPLATES config option)', default=None)
parser.add_argument('zone', metavar='ZONE[@VIEWS]', nargs=nargs, help='DNS zone name and optional list of views (comma separated or asterisk to select all views)', default=None)
args = parser.parse_args()
try:
manager = dnsmgr.DNSManager(cfgfile=args.config)
except RuntimeError as e:
dnsmgr.printe(f'config: {e}')
sys.exit(100)
managed_views = sorted(manager.config.zones_config.keys())
try:
if args.zone is None:
name = dnsmgr.input_name()
rows = [[view] for view in managed_views]
index = dnsmgr.prettyselect(['View'], rows, prompt='Select view', also_valid=['*'])
views = managed_views if index == '*' else [managed_views[index]]
else:
(name, views) = dnsmgr.name_views_from_text(args.zone)
if views is None:
if len(managed_views) > 1:
raise RuntimeError('multiple managed views configured but none specified')
elif managed_views[0] != dnsmgr.NAMED_DEFAULT_VIEW:
raise RuntimeError('the default view is not managed')
views = managed_views
elif views == '*':
views = managed_views
else:
for view in views:
if view not in managed_views:
raise RuntimeError(f'managed view does not exist -- \'{view}\'')
existing_views = [zone.view for zone in filter(lambda zone: zone.origin == name and zone.view in views, manager.all_zones)]
if existing_views:
views = 'and '.join(existing_views)
raise RuntimeError(f'zone already exists in view {views}')
except RuntimeError as e:
dnsmgr.printe(e)
sys.exit(150)
except KeyboardInterrupt:
sys.exit(0)
if not args.batch:
for view in views:
origin = name.to_text(omit_final_dot=True)
print(f'View: {view}')
print(f'\033[32m+ {origin}\033[0m\n')
if not dnsmgr.input_yes_no():
sys.exit(0)
zones = []
for view in views:
origin = name.to_text(omit_final_dot=True)
if len(views) > 1 or view != dnsmgr.NAMED_DEFAULT_VIEW:
origin = f'{origin}@{view}'
print(f"Adding zone '{origin}'... ", end='')
try:
zone = manager.add_zone(name, view, args.config_template, args.zone_template)
manager.generate_config(view)
print('OK')
if manager.config.zones_config[view].catalog_zone:
zones.append(zone)
except RuntimeError as e:
dnsmgr.printe(e)
sys.exit(160)
try:
print('Reloading named... ', end='')
manager.named_reload()
print('OK')
except RuntimeError as e:
dnsmgr.printe(e)
sys.exit(170)
if zones:
sleep(2)
for zone in zones:
catalog_zone_name = manager.config.zones_config[zone.view].catalog_zone
try:
catalog_zones = manager.get_zones(catalog_zone_name, all_zones=True)
except RuntimeError as e:
raise RuntimeError(f'catalog zone of view \'{zone.view}\': {e}')
origin = zone.origin.to_text(omit_final_dot=True)
if len(zones) > 1 or zone.view != dnsmgr.NAMED_DEFAULT_VIEW:
origin = f'{origin}@{zone.view}'
for catalog_zone in catalog_zones:
rdata = dnsmgr.rdata_from_text(dns.rdatatype.PTR, zone.origin.to_text(), catalog_zone.origin)
rdataset = dns.rdataset.Rdataset(dns.rdataclass.IN, dns.rdatatype.PTR, ttl=3600)
rdataset.add(rdata)
rdname = dns.name.from_text(zone.nfz() + '.zones', catalog_zone.origin)
catalog_zone_origin = catalog_zone.origin.to_text(omit_final_dot=True)
if catalog_zone.view != dnsmgr.NAMED_DEFAULT_VIEW:
catalog_zone_origin += f'@{catalog_zone.view}'
try:
print(f'Adding zone \'{origin}\' to catalog zone \'{catalog_zone_origin}\'... ', end='')
manager.add_zone_record(catalog_zone, rdname, rdataset)
print('OK')
except RuntimeError as e:
dnsmgr.printe(e)
if __name__ == '__main__':
main()