forked from phensley/docker-dns-rest
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdocker_dnsrest
executable file
·125 lines (98 loc) · 3.85 KB
/
docker_dnsrest
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#!/usr/bin/env python
# dnsrest - restful dns service for associating domain names with docker containers
# python 3 compatibility
from __future__ import print_function
from future import standard_library
from functools import reduce
standard_library.install_aliases()
from builtins import map
from builtins import str
from builtins import object
# monkey patch
from gevent import monkey
monkey.patch_all(thread=False)
# core
import argparse
import os
import signal
import sys
from urllib.parse import urlparse
# local
from dnsrest.logger import init_logger, log
from dnsrest.monitor import DockerMonitor
from dnsrest.namesrv import DnsServer
from dnsrest.registry import Registry
from dnsrest.restapi import StaticApi, ContainerApi, DebugApi
# libs
import docker
import falcon
import gevent
from gevent.wsgi import WSGIServer
# Default variables
PROCESS = 'dnsrest'
DOCKER_SOCK = 'unix:///var/run/docker.sock'
DOCKER_VERSION = '1.14'
DNS_BINDADDR = '0.0.0.0:%s' % os.getenv('DNS_PORT', "53")
DNS_RESOLVER = ['8.8.8.8']
REST_BINDADDR = '0.0.0.0:%s' % os.getenv('API_PORT', "80")
EPILOG = '<tbd>'
def check(args):
url = urlparse(args.docker)
if url.scheme in ('unix', 'unix+http'):
# check if the socket file exists
if not os.path.exists(url.path):
log.error('unix socket %r does not exist', url.path)
sys.exit(1)
def parse_args():
docker_url = os.getenv('DOCKER_HOST', DOCKER_SOCK)
dns_bind_addr = os.getenv('DNS_BIND_ADDR', DNS_BINDADDR)
dns_rest_addr = os.getenv('DNS_REST_ADDR', REST_BINDADDR)
dns_no_resolv = os.getenv('DNS_NO_RESOLV', False)
dns_resolver = os.getenv('DNS_RESOLVER', DNS_RESOLVER)
parser = argparse.ArgumentParser(PROCESS, epilog=EPILOG,
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('--docker', default=docker_url,
help='Url to docker TCP/UNIX socket')
parser.add_argument('--dns-bind', default=dns_bind_addr,
help='Bind address for DNS server')
parser.add_argument('--rest-bind', default=dns_rest_addr,
help='Bind address for REST API server')
parser.add_argument('--domain', default=None,
help='Base domain name for registered services')
parser.add_argument('--resolver', default=dns_resolver, nargs='*',
help='Servers for recursive DNS resolution')
parser.add_argument('--no-recursion', default=dns_no_resolv,
action='store_const', const=1, help='Disables recursive DNS queries')
parser.add_argument('--verbose', action='store_const', const=1,
help='Be more verbose')
parser.add_argument('-q', '--quiet', action='store_const', const=0,
help='Quiet mode')
return parser.parse_args()
def stop(*servers):
for svr in servers:
if svr.started:
svr.stop()
sys.exit(signal.SIGINT)
def main():
args = parse_args()
check(args)
init_logger(process=PROCESS, quiet=args.quiet, verbose=args.verbose)
resolver = () if args.no_recursion else args.resolver
log.info("Starting with args %s", args)
registry = Registry(args.domain)
app = falcon.API()
app.add_route('/container/{label}/{arg}', ContainerApi(registry))
app.add_route('/domain/{domain}', StaticApi(registry))
app.add_route('/debug', DebugApi(registry))
api = WSGIServer(args.rest_bind, app)
dns = DnsServer(args.dns_bind, registry, resolver)
api.start()
dns.start()
for signum in (signal.SIGTERM, signal.SIGINT):
gevent.signal(signum, stop, api, dns)
client = docker.Client(args.docker, version=DOCKER_VERSION)
monitor = DockerMonitor(client, registry, args.domain)
monitor.bootstrap()
gevent.wait([gevent.spawn(monitor.run)])
if __name__ == '__main__':
main()