From f71b8080cc9fb878642476af06507ef6e42e24ad Mon Sep 17 00:00:00 2001 From: Justin Riley Date: Fri, 21 Oct 2016 00:30:39 -0400 Subject: [PATCH] daemon: sync with opennebula on defined interval - Added --sync-interval option that defaults to 5 minutes --- onedns/cli.py | 25 ++++++++++++++++++++----- onedns/resolver.py | 4 ++-- onedns/server.py | 15 +++++++++++++++ onedns/tests/test_cli.py | 16 ++++++++++++++-- onedns/tests/test_dynamicresolver.py | 2 +- 5 files changed, 52 insertions(+), 10 deletions(-) diff --git a/onedns/cli.py b/onedns/cli.py index 5e284af..f1f3468 100644 --- a/onedns/cli.py +++ b/onedns/cli.py @@ -6,11 +6,12 @@ from onedns import logger def daemon(args, one_args, **kwargs): - testing = kwargs.get('testing', False) - vms = kwargs.get('vms') + test = kwargs.get('test', False) + test_vms = kwargs.get('test_vms') srv = server.OneDNS(args.domain, one_kwargs=one_args) - srv.sync(vms=vms) - srv.daemon(dns_port=args.dns_port, testing=testing) + srv.daemon(dns_port=args.dns_port, + sync_interval=args.sync_interval, + test=test, test_vms=test_vms) def shell(args, one_args, **kwargs): @@ -20,6 +21,17 @@ def shell(args, one_args, **kwargs): utils.shell(local_ns=ns) +def positive_int(value): + errmsg = "an integer greater than zero is required" + try: + ivalue = int(value) + except ValueError: + raise argparse.ArgumentTypeError(errmsg) + if ivalue <= 0: + raise argparse.ArgumentTypeError(errmsg) + return ivalue + + def get_parser(): parser = argparse.ArgumentParser( description='OneDNS - Dynamic DNS for OpenNebula') @@ -39,8 +51,11 @@ def get_parser(): daemon_parser = subparsers.add_parser('daemon') daemon_parser.set_defaults(func=daemon) daemon_parser.add_argument( - '--dns-port', required=False, default=53, type=int, + '--dns-port', required=False, default=53, type=positive_int, help="port for DNS server to listen on") + daemon_parser.add_argument( + '--sync-interval', required=False, default=5 * 60, type=positive_int, + help="time in seconds between ONE syncs") shell_parser = subparsers.add_parser('shell') shell_parser.set_defaults(func=shell) diff --git a/onedns/resolver.py b/onedns/resolver.py index 0540604..cc5fb99 100644 --- a/onedns/resolver.py +++ b/onedns/resolver.py @@ -99,10 +99,10 @@ class DynamicResolver(server.BaseResolver): srv.server.socket.close() def daemon(self, *args, **kwargs): - testing = kwargs.pop('testing', False) + test = kwargs.pop('test', False) if self._udp_server is None or not self._udp_server.isAlive(): self.start(*args, **kwargs) while self._udp_server.isAlive(): time.sleep(1) - if testing: + if test: break diff --git a/onedns/server.py b/onedns/server.py index 0a7771a..03fbaea 100644 --- a/onedns/server.py +++ b/onedns/server.py @@ -1,4 +1,5 @@ import re +import time from onedns import zone from onedns import resolver @@ -88,3 +89,17 @@ class OneDNS(resolver.DynamicResolver): except exception.DuplicateVMError as e: e.log(warn=True) self.load(z) + + def daemon(self, *args, **kwargs): + test = kwargs.pop('test', False) + test_vms = kwargs.pop('test_vms', None) + sync_interval = kwargs.pop('sync_interval', 5 * 60) + self.sync(vms=test_vms) + if self._udp_server is None or not self._udp_server.isAlive(): + self.start(*args, **kwargs) + time.sleep(sync_interval) + while self._udp_server.isAlive(): + self.sync(vms=test_vms) + time.sleep(sync_interval) + if test: + break diff --git a/onedns/tests/test_cli.py b/onedns/tests/test_cli.py index 95f7a8a..b78f0b5 100644 --- a/onedns/tests/test_cli.py +++ b/onedns/tests/test_cli.py @@ -13,12 +13,24 @@ def test_cli_help(): @mock.patch.object(cli, 'logger', mock.MagicMock()) def test_cli_subcmd_daemon(vms): - cli.main(args=['daemon'], testing=True, vms=vms) + cli.main(args='daemon --dns-port 9053 --sync-interval 1'.split(), + test=True, test_vms=vms) @mock.patch.dict('sys.modules', test_shell.IPY_MODULES) @mock.patch.object(cli, 'logger', mock.MagicMock()) def test_cli_subcmd_shell(): test_shell.IPY.embed.reset_mock() - cli.main(args=['shell'], testing=True) + cli.main(args=['shell'], test=True) test_shell.IPY.embed.assert_called_once() + + +def test_invalid_values(): + with pytest.raises(SystemExit): + cli.main(args='daemon --dns-port asdf'.split()) + with pytest.raises(SystemExit): + cli.main(args='daemon --dns-port 0'.split()) + with pytest.raises(SystemExit): + cli.main(args='daemon --sync-interval asdf'.split()) + with pytest.raises(SystemExit): + cli.main(args='daemon --sync-interval 0'.split()) diff --git a/onedns/tests/test_dynamicresolver.py b/onedns/tests/test_dynamicresolver.py index fc1a0c4..73b4235 100644 --- a/onedns/tests/test_dynamicresolver.py +++ b/onedns/tests/test_dynamicresolver.py @@ -36,7 +36,7 @@ def test_nxdomain(dns): def test_daemon(dns): dns.close() dns.daemon(dns_address=conftest.INTERFACE, dns_port=conftest.PORT, - tcp=True, testing=True) + tcp=True, test=True) @pytest.mark.parametrize("qname,qtype,output", conftest.TEST_LOOKUP_DATA)