diff --git a/octodns/cmds/compare.py b/octodns/cmds/compare.py index b05ca9c..7df23fd 100755 --- a/octodns/cmds/compare.py +++ b/octodns/cmds/compare.py @@ -11,19 +11,21 @@ from pprint import pprint from octodns.cmds.args import ArgumentParser from octodns.manager import Manager -parser = ArgumentParser(description=__doc__.split('\n')[1]) - -parser.add_argument('--config-file', required=True, - help='The Manager configuration file to use') -parser.add_argument('--a', nargs='+', required=True, - help='First source(s) to pull data from') -parser.add_argument('--b', nargs='+', required=True, - help='Second source(s) to pull data from') -parser.add_argument('--zone', default=None, required=True, - help='Zone to compare') - -args = parser.parse_args() - -manager = Manager(args.config_file) -changes = manager.compare(args.a, args.b, args.zone) -pprint(changes) + +def main(): + parser = ArgumentParser(description=__doc__.split('\n')[1]) + + parser.add_argument('--config-file', required=True, + help='The Manager configuration file to use') + parser.add_argument('--a', nargs='+', required=True, + help='First source(s) to pull data from') + parser.add_argument('--b', nargs='+', required=True, + help='Second source(s) to pull data from') + parser.add_argument('--zone', default=None, required=True, + help='Zone to compare') + + args = parser.parse_args() + + manager = Manager(args.config_file) + changes = manager.compare(args.a, args.b, args.zone) + pprint(changes) diff --git a/octodns/cmds/dump.py b/octodns/cmds/dump.py index b58a59d..bf8ff9d 100755 --- a/octodns/cmds/dump.py +++ b/octodns/cmds/dump.py @@ -9,17 +9,20 @@ from __future__ import absolute_import, division, print_function, \ from octodns.cmds.args import ArgumentParser from octodns.manager import Manager -parser = ArgumentParser(description=__doc__.split('\n')[1]) -parser.add_argument('--config-file', required=True, - help='The Manager configuration file to use') -parser.add_argument('--output-dir', required=True, - help='The directory into which the results will be ' - 'written (Note: will overwrite existing files)') -parser.add_argument('zone', help='Zone to dump') -parser.add_argument('source', nargs='+', help='Source(s) to pull data from') +def main(): + parser = ArgumentParser(description=__doc__.split('\n')[1]) -args = parser.parse_args() + parser.add_argument('--config-file', required=True, + help='The Manager configuration file to use') + parser.add_argument('--output-dir', required=True, + help='The directory into which the results will be ' + 'written (Note: will overwrite existing files)') + parser.add_argument('zone', help='Zone to dump') + parser.add_argument('source', nargs='+', + help='Source(s) to pull data from') -manager = Manager(args.config_file) -manager.dump(args.zone, args.output_dir, *args.source) + args = parser.parse_args() + + manager = Manager(args.config_file) + manager.dump(args.zone, args.output_dir, *args.source) diff --git a/octodns/cmds/report.py b/octodns/cmds/report.py index 062e5e7..52402fa 100755 --- a/octodns/cmds/report.py +++ b/octodns/cmds/report.py @@ -29,71 +29,72 @@ class AsyncResolver(Resolver): **kwargs) -parser = ArgumentParser(description=__doc__.split('\n')[1]) - -parser.add_argument('--config-file', required=True, - help='The Manager configuration file to use') -parser.add_argument('--zone', required=True, help='Zone to dump') -parser.add_argument('--source', required=True, default=[], action='append', - help='Source(s) to pull data from') -parser.add_argument('--num-workers', default=4, - help='Number of background workers') -parser.add_argument('--timeout', default=1, - help='Number seconds to wait for an answer') -parser.add_argument('server', nargs='+', help='Servers to query') - -args = parser.parse_args() - -manager = Manager(args.config_file) - -log = getLogger('report') - -try: - sources = [manager.providers[source] for source in args.source] -except KeyError as e: - raise Exception('Unknown source: {}'.format(e.args[0])) - -zone = Zone(args.zone, manager.configured_sub_zones(args.zone)) -for source in sources: - source.populate(zone) - -print('name,type,ttl,{},consistent'.format(','.join(args.server))) -resolvers = [] -ip_addr_re = re.compile(r'^[\d\.]+$') -for server in args.server: - resolver = AsyncResolver(configure=False, - num_workers=int(args.num_workers)) - if not ip_addr_re.match(server): - server = str(query(server, 'A')[0]) - log.info('server=%s', server) - resolver.nameservers = [server] - resolver.lifetime = int(args.timeout) - resolvers.append(resolver) - -queries = {} -for record in sorted(zone.records): - queries[record] = [r.query(record.fqdn, record._type) - for r in resolvers] - -for record, futures in sorted(queries.items(), key=lambda d: d[0]): - stdout.write(record.fqdn) - stdout.write(',') - stdout.write(record._type) - stdout.write(',') - stdout.write(str(record.ttl)) - compare = {} - for future in futures: +def main(): + parser = ArgumentParser(description=__doc__.split('\n')[1]) + + parser.add_argument('--config-file', required=True, + help='The Manager configuration file to use') + parser.add_argument('--zone', required=True, help='Zone to dump') + parser.add_argument('--source', required=True, default=[], action='append', + help='Source(s) to pull data from') + parser.add_argument('--num-workers', default=4, + help='Number of background workers') + parser.add_argument('--timeout', default=1, + help='Number seconds to wait for an answer') + parser.add_argument('server', nargs='+', help='Servers to query') + + args = parser.parse_args() + + manager = Manager(args.config_file) + + log = getLogger('report') + + try: + sources = [manager.providers[source] for source in args.source] + except KeyError as e: + raise Exception('Unknown source: {}'.format(e.args[0])) + + zone = Zone(args.zone, manager.configured_sub_zones(args.zone)) + for source in sources: + source.populate(zone) + + print('name,type,ttl,{},consistent'.format(','.join(args.server))) + resolvers = [] + ip_addr_re = re.compile(r'^[\d\.]+$') + for server in args.server: + resolver = AsyncResolver(configure=False, + num_workers=int(args.num_workers)) + if not ip_addr_re.match(server): + server = str(query(server, 'A')[0]) + log.info('server=%s', server) + resolver.nameservers = [server] + resolver.lifetime = int(args.timeout) + resolvers.append(resolver) + + queries = {} + for record in sorted(zone.records): + queries[record] = [r.query(record.fqdn, record._type) + for r in resolvers] + + for record, futures in sorted(queries.items(), key=lambda d: d[0]): + stdout.write(record.fqdn) stdout.write(',') - try: - answers = [str(r) for r in future.result()] - except (NoAnswer, NoNameservers): - answers = ['*no answer*'] - except NXDOMAIN: - answers = ['*does not exist*'] - except Timeout: - answers = ['*timeout*'] - stdout.write(' '.join(answers)) - # sorting to ignore order - answers = '*:*'.join(sorted(answers)).lower() - compare[answers] = True - stdout.write(',True\n' if len(compare) == 1 else ',False\n') + stdout.write(record._type) + stdout.write(',') + stdout.write(str(record.ttl)) + compare = {} + for future in futures: + stdout.write(',') + try: + answers = [str(r) for r in future.result()] + except (NoAnswer, NoNameservers): + answers = ['*no answer*'] + except NXDOMAIN: + answers = ['*does not exist*'] + except Timeout: + answers = ['*timeout*'] + stdout.write(' '.join(answers)) + # sorting to ignore order + answers = '*:*'.join(sorted(answers)).lower() + compare[answers] = True + stdout.write(',True\n' if len(compare) == 1 else ',False\n') diff --git a/octodns/cmds/sync.py b/octodns/cmds/sync.py index 5002743..8188a37 100755 --- a/octodns/cmds/sync.py +++ b/octodns/cmds/sync.py @@ -9,29 +9,31 @@ from __future__ import absolute_import, division, print_function, \ from octodns.cmds.args import ArgumentParser from octodns.manager import Manager -parser = ArgumentParser(description=__doc__.split('\n')[1]) -parser.add_argument('--config-file', required=True, - help='The Manager configuration file to use') -parser.add_argument('--doit', action='store_true', default=False, - help='Whether to take action or just show what would ' - 'change') -parser.add_argument('--force', action='store_true', default=False, - help='Acknowledge that significant changes are being made ' - 'and do them') +def main(): + parser = ArgumentParser(description=__doc__.split('\n')[1]) -parser.add_argument('zone', nargs='*', default=[], - help='Limit sync to the specified zone(s)') + parser.add_argument('--config-file', required=True, + help='The Manager configuration file to use') + parser.add_argument('--doit', action='store_true', default=False, + help='Whether to take action or just show what would ' + 'change') + parser.add_argument('--force', action='store_true', default=False, + help='Acknowledge that significant changes are being ' + 'made and do them') -# --sources isn't an option here b/c filtering sources out would be super -# dangerous since you could eaily end up with an empty zone and delete -# everything, or even just part of things when there are multiple sources + parser.add_argument('zone', nargs='*', default=[], + help='Limit sync to the specified zone(s)') -parser.add_argument('--target', default=[], action='append', - help='Limit sync to the specified target(s)') + # --sources isn't an option here b/c filtering sources out would be super + # dangerous since you could eaily end up with an empty zone and delete + # everything, or even just part of things when there are multiple sources -args = parser.parse_args() + parser.add_argument('--target', default=[], action='append', + help='Limit sync to the specified target(s)') -manager = Manager(args.config_file) -manager.sync(eligible_zones=args.zone, eligible_targets=args.target, - dry_run=not args.doit, force=args.force) + args = parser.parse_args() + + manager = Manager(args.config_file) + manager.sync(eligible_zones=args.zone, eligible_targets=args.target, + dry_run=not args.doit, force=args.force) diff --git a/octodns/cmds/validate.py b/octodns/cmds/validate.py index 576e96e..692576b 100755 --- a/octodns/cmds/validate.py +++ b/octodns/cmds/validate.py @@ -11,12 +11,14 @@ from logging import WARN from octodns.cmds.args import ArgumentParser from octodns.manager import Manager -parser = ArgumentParser(description=__doc__.split('\n')[1]) -parser.add_argument('--config-file', default='./config/production.yaml', - help='The Manager configuration file to use') +def main(): + parser = ArgumentParser(description=__doc__.split('\n')[1]) -args = parser.parse_args(WARN) + parser.add_argument('--config-file', default='./config/production.yaml', + help='The Manager configuration file to use') -manager = Manager(args.config_file) -manager.validate_configs() + args = parser.parse_args(WARN) + + manager = Manager(args.config_file) + manager.validate_configs() diff --git a/octodns/manager.py b/octodns/manager.py index 684ed07..86b7f24 100644 --- a/octodns/manager.py +++ b/octodns/manager.py @@ -53,6 +53,7 @@ class Manager(object): try: _class = provider_config.pop('class') except KeyError: + self.log.exception('Invalid provider class') raise Exception('Provider {} is missing class' .format(provider_name)) _class = self._get_provider_class(_class) @@ -65,6 +66,7 @@ class Manager(object): env_var = v[4:] v = environ[env_var] except KeyError: + self.log.exception('Invalid provider config') raise Exception('Incorrect provider config, ' 'missing env var {}' .format(env_var)) @@ -74,6 +76,7 @@ class Manager(object): try: self.providers[provider_name] = _class(provider_name, **kwargs) except TypeError: + self.log.exception('Invalid provider config') raise Exception('Incorrect provider config for {}' .format(provider_name)) @@ -102,14 +105,14 @@ class Manager(object): module_name, class_name = _class.rsplit('.', 1) module = import_module(module_name) except (ImportError, ValueError): - self.log.error('_get_provider_class: Unable to import module %s', - _class) + self.log.exception('_get_provider_class: Unable to import ' + 'module %s', _class) raise Exception('Unknown provider class: {}'.format(_class)) try: return getattr(module, class_name) except AttributeError: - self.log.error('_get_provider_class: Unable to get class %s from ' - 'module %s', class_name, module) + self.log.exception('_get_provider_class: Unable to get class %s ' + 'from module %s', class_name, module) raise Exception('Unknown provider class: {}'.format(_class)) def configured_sub_zones(self, zone_name): diff --git a/setup.py b/setup.py index f1c44c9..7dc56e9 100644 --- a/setup.py +++ b/setup.py @@ -17,8 +17,8 @@ cmds = ( ) cmds_dir = join(dirname(__file__), 'octodns', 'cmds') console_scripts = { - 'octodns-{name} = octodns.cmds.{name}'.format(name=filename[:-3]) - for filename in cmds + 'octodns-{name} = octodns.cmds.{name}:main'.format(name=name) + for name in cmds } setup(