From 54180d6bb5ffaa95f8ac341c97fd7ef2305fe234 Mon Sep 17 00:00:00 2001 From: Nikolai R Kristiansen Date: Thu, 5 Jan 2017 00:29:16 +0100 Subject: [PATCH] refactor sync cmds --- mdb/management/commands/dhcp-sync.py | 50 ++++++++-------- mdb/management/commands/zone-sync.py | 90 +++++++++++++++------------- 2 files changed, 73 insertions(+), 67 deletions(-) diff --git a/mdb/management/commands/dhcp-sync.py b/mdb/management/commands/dhcp-sync.py index 026012b..3c987a3 100644 --- a/mdb/management/commands/dhcp-sync.py +++ b/mdb/management/commands/dhcp-sync.py @@ -5,7 +5,6 @@ import sys from difflib import context_diff from django.core.management.base import BaseCommand from django.core.mail import mail_admins -from optparse import make_option try: from subprocess import getstatusoutput except ImportError: @@ -18,23 +17,22 @@ class Command(BaseCommand): args = '--output [--force] [--restart]' help = 'Generates the DHCP configuration' - option_list = BaseCommand.option_list + ( - make_option('--output', - action='store', - dest='output', - default=None, - help='Path to dhcpd.conf, defaults to stdout'), - make_option('--force', - action='store_true', - dest='force', - default=False, - help='Write configuration even if serial is unchanged.'), - make_option('--restart', - action='store_true', - dest='restart', - default=False, - help='Restart dhcp3-server if serial is changed'), - ) + def add_arguments(self, parser): + parser.add_argument('--output', + action='store', + dest='output', + default=None, + help='Path to dhcpd.conf, defaults to stdout'), + parser.add_argument('--force', + action='store_true', + dest='force', + default=False, + help='Write configuration even if serial is unchanged.'), + parser.add_argument('--restart', + action='store_true', + dest='restart', + default=False, + help='Restart dhcp3-server if serial is changed'), def handle(self, *args, **options): output = options['output'] if options['output'] else sys.stdout @@ -67,13 +65,7 @@ class Command(BaseCommand): with open(output, 'w') as f: f.write(new) - # calculate diff - diff = "\n".join(context_diff( - a=old.splitlines(), - b=new.splitlines(), - fromfile=str(config.active_serial), - tofile=str(config.serial), - lineterm='')) + diff = self.calculate_diff(config, new, old) print(diff) @@ -104,3 +96,11 @@ class Command(BaseCommand): message=message, html_message='
%s
' % message) sys.exit(0) + + def calculate_diff(self, config, new, old): + return "\n".join(context_diff( + a=old.splitlines(), + b=new.splitlines(), + fromfile=str(config.active_serial), + tofile=str(config.serial), + lineterm='')) diff --git a/mdb/management/commands/zone-sync.py b/mdb/management/commands/zone-sync.py index dab7212..ab222de 100644 --- a/mdb/management/commands/zone-sync.py +++ b/mdb/management/commands/zone-sync.py @@ -6,7 +6,6 @@ from itertools import chain from difflib import context_diff from django.core.management.base import BaseCommand from django.core.mail import mail_admins -from optparse import make_option try: from subprocess import getstatusoutput except ImportError: @@ -19,19 +18,6 @@ class Command(BaseCommand): args = '[--force] [--debug]' help = 'Generates the bind configuration' - option_list = BaseCommand.option_list + ( - make_option('--debug', - action='store_true', - dest='debug', - default=False, - help='Debug mode. Writes to /tmp and does not reload.'), - make_option('--force', - action='store_true', - dest='force', - default=False, - help='Write zone files even if serial is unchanged.'), - ) - rndc_bin = "/usr/sbin/rndc" reload_command = "%s reload" % rndc_bin freeze_command = "%s freeze" % rndc_bin @@ -40,32 +26,35 @@ class Command(BaseCommand): checkzone_bin = "/usr/sbin/named-checkzone" checkzone_dir = "/tmp/mdb-checkzone" debug = False + force = False debug_dir = '/tmp/mdb-debug' changes = {} + def add_arguments(self, parser): + parser.add_argument('--debug', + action='store_true', + dest='debug', + default=False, + help='Debug mode. Writes to /tmp and does not reload.') + parser.add_argument('--force', + action='store_true', + dest='force', + default=False, + help='Write zone files even if serial is unchanged.') + def handle(self, *args, **options): - self.debug = debug = options['debug'] - force = options['force'] + self.debug = options['debug'] + self.force = options['force'] # do the binaries exist? - for f in (self.checkzone_bin, self.rndc_bin): - if not os.path.isfile(f) and not debug: - print("ERROR: no such file %s, exiting..." % f) - if not debug: - sys.exit(1) + self.validate_binaries_exist() # create directories if needed os.path.isdir(self.checkzone_dir) or os.mkdir(self.checkzone_dir) - debug and (os.path.isdir(self.debug_dir) or os.mkdir(self.debug_dir)) + self.debug and (os.path.isdir(self.debug_dir) or os.mkdir(self.debug_dir)) # update zones with new serials - for zone in chain(Domain.objects.all(), - Ip4Subnet.objects.all(), - Ip6Subnet.objects.all()): - if zone.domain_serial == zone.domain_active_serial and not force: - continue - if self.update_zone(zone): - self.changes[zone.domain_name]['success'] = True + self.update_zone_serials() # join errors, diffs and zone names errors = "\n\n\n".join( @@ -75,7 +64,7 @@ class Command(BaseCommand): zones = ", ".join(self.changes.keys()) # reload and send email with changes - if self.changes and not debug: + if self.changes and not self.debug: sys.stdout.write("reloading zones... ") for command in self.commands_in_order: status, output = getstatusoutput(command) @@ -102,9 +91,25 @@ class Command(BaseCommand): html_message='
%s
' % message) sys.exit(0) + def update_zone_serials(self): + for zone in chain(Domain.objects.all(), + Ip4Subnet.objects.all(), + Ip6Subnet.objects.all()): + if zone.domain_serial == zone.domain_active_serial and not self.force: + continue + + if self.update_zone(zone): + self.changes[zone.domain_name]['success'] = True + + def validate_binaries_exist(self): + for f in (self.checkzone_bin, self.rndc_bin): + if not os.path.isfile(f) and not self.debug: + print("ERROR: no such file %s, exiting..." % f) + if not self.debug: + sys.exit(1) + def update_zone(self, zone): - zonetype = getattr(zone._meta, 'verbose_name', None) \ - or zone._meta.model_name + zonetype = getattr(zone._meta, 'verbose_name', None) or zone._meta.model_name self.changes[zone.domain_name] = { 'old_serial': zone.domain_active_serial, @@ -130,14 +135,7 @@ class Command(BaseCommand): except IOError: old = '' - # calculate diff - diff = "\n".join(context_diff( - a=old.splitlines(), - b=new.splitlines(), - fromfile=str(zone.domain_active_serial) + '-' + zone.domain_name, - tofile=str(zone.domain_serial) + '-' + zone.domain_name, - lineterm='')) - self.changes[zone.domain_name]['diff'] = diff + self.changes[zone.domain_name]['diff'] = self.calculate_diff(new, old, zone) # validate with zonecheck sys.stdout.write("\t- validating... ") @@ -146,6 +144,7 @@ class Command(BaseCommand): sys.stdout.write("fail\n") self.changes[zone.domain_name]['errors'] = output return False + sys.stdout.write("ok\n") # write to zone file @@ -170,10 +169,17 @@ class Command(BaseCommand): self.changes[zone.domain_name]['success'] = True return True + def calculate_diff(self, new, old, zone): + return "\n".join(context_diff( + a=old.splitlines(), + b=new.splitlines(), + fromfile=str(zone.domain_active_serial) + '-' + zone.domain_name, + tofile=str(zone.domain_serial) + '-' + zone.domain_name, + lineterm='')) + def check_zone(self, zone, contents): zonefile = self.checkzone_dir + '/' + zone.domain_name with open(zonefile, 'w') as f: f.write(contents) - return getstatusoutput("%s %s %s" % ( - self.checkzone_bin, zone.domain_name, zonefile)) + return getstatusoutput("%s %s %s" % (self.checkzone_bin, zone.domain_name, zonefile))