[enh] Use a common method to retrieve public IP address

This commit is contained in:
Jérôme Lebleu 2016-03-08 11:08:57 +01:00
parent 5f08eb06ae
commit 8aa64a0641
4 changed files with 48 additions and 46 deletions

View file

@ -1169,7 +1169,7 @@ dyndns:
full: --key
help: Public DNS key
-i:
full: --ip
full: --ipv4
help: IP address to send
-6:
full: --ipv6

View file

@ -82,10 +82,7 @@ def domain_add(auth, domain, dyndns=False):
from yunohost.hook import hook_callback
attr_dict = { 'objectClass' : ['mailDomain', 'top'] }
try:
ip = str(urlopen('https://ip.yunohost.org').read())
except IOError:
ip = "127.0.0.1"
now = datetime.datetime.now()
timestamp = str(now.year) + str(now.month) + str(now.day)
@ -232,20 +229,16 @@ def domain_dns_conf(domain, ttl=None):
ip4 = ip6 = None
# A/AAAA records
try:
ip4 = urlopen("https://ip.yunohost.org").read().strip()
except IOError:
raise MoulinetteError(errno.ENETUNREACH,
m18n.n('no_internet_connection'))
ip4 = get_public_ip()
result = (
"@ {ttl} IN A {ip4}\n"
"* {ttl} IN A {ip4}\n"
).format(ttl=ttl, ip4=ip4)
try:
ip6 = urlopen("http://ip6.yunohost.org").read().strip()
except IOError:
logger.debug('cannot retrieve IPv6', exc_info=1)
ip6 = get_public_ip(6)
except:
pass
else:
result += (
"@ {ttl} IN AAAA {ip6}\n"
@ -295,3 +288,17 @@ def domain_dns_conf(domain, ttl=None):
)
return result
def get_public_ip(protocol=4):
"""Retrieve the public IP address from ip.yunohost.org"""
if protocol not in [4, 6]:
raise ValueError("invalid protocol version")
try:
return urlopen("https://ip{protocol}.yunohost.org".format(
protocol=('' if protocol == 4 else 'v6')
)).read().strip()
except IOError:
logger.debug('cannot retrieve public IPv%d' % protocol, exc_info=1)
raise MoulinetteError(errno.ENETUNREACH,
m18n.n('no_internet_connection'))

View file

@ -35,6 +35,8 @@ import subprocess
from moulinette.core import MoulinetteError
from moulinette.utils.log import getActionLogger
from yunohost.domain import get_public_ip
logger = getActionLogger('yunohost.dyndns')
@ -112,7 +114,8 @@ def dyndns_subscribe(subscribe_host="dyndns.yunohost.org", domain=None, key=None
dyndns_installcron()
def dyndns_update(dyn_host="dynhost.yunohost.org", domain=None, key=None, ip=None, ipv6=None):
def dyndns_update(dyn_host="dynhost.yunohost.org", domain=None, key=None,
ipv4=None, ipv6=None):
"""
Update IP on DynDNS platform
@ -120,7 +123,7 @@ def dyndns_update(dyn_host="dynhost.yunohost.org", domain=None, key=None, ip=Non
domain -- Full domain to subscribe with
dyn_host -- Dynette DNS server to inform
key -- Public DNS key
ip -- IP address to send
ipv4 -- IP address to send
ipv6 -- IPv6 address to send
"""
@ -129,13 +132,8 @@ def dyndns_update(dyn_host="dynhost.yunohost.org", domain=None, key=None, ip=Non
domain = f.readline().rstrip()
# IPv4
if ip is None:
try:
new_ip = requests.get('https://ip.yunohost.org').text
except requests.ConnectionError:
raise MoulinetteError(errno.ENETUNREACH, m18n.n('no_internet_connection'))
else:
new_ip = ip
if ipv4 is None:
ipv4 = get_public_ip()
try:
with open('/etc/yunohost/dyndns/old_ip', 'r') as f:
@ -145,7 +143,6 @@ def dyndns_update(dyn_host="dynhost.yunohost.org", domain=None, key=None, ip=Non
# IPv6
if ipv6 is None:
new_ipv6 = None
try:
ip_route_out = subprocess.check_output(
['ip', 'route', 'get', '2000::']).split('\n')
@ -153,7 +150,7 @@ def dyndns_update(dyn_host="dynhost.yunohost.org", domain=None, key=None, ip=Non
if len(ip_route_out) > 0:
route = IPRouteLine(ip_route_out[0])
if not route.unreachable:
new_ipv6 = route.src_addr
ipv6 = route.src_addr
except (OSError, ValueError) as e:
# Unlikely case "ip route" does not return status 0
@ -161,11 +158,8 @@ def dyndns_update(dyn_host="dynhost.yunohost.org", domain=None, key=None, ip=Non
raise MoulinetteError(errno.EBADMSG,
"ip route cmd error : {}".format(e))
if new_ipv6 is None:
logger.warning(m18n.n('no_ipv6_connectivity'))
else:
new_ipv6 = ipv6
if ipv6 is None:
logger.info(m18n.n('no_ipv6_connectivity'))
try:
with open('/etc/yunohost/dyndns/old_ipv6', 'r') as f:
@ -173,7 +167,7 @@ def dyndns_update(dyn_host="dynhost.yunohost.org", domain=None, key=None, ip=Non
except IOError:
old_ipv6 = '0000:0000:0000:0000:0000:0000:0000:0000'
if old_ip != new_ip or old_ipv6 != new_ipv6:
if old_ip != ipv4 or old_ipv6 != ipv6:
host = domain.split('.')[1:]
host = '.'.join(host)
lines = [
@ -191,21 +185,21 @@ def dyndns_update(dyn_host="dynhost.yunohost.org", domain=None, key=None, ip=Non
'update delete vjud.%s. AAAA' % domain,
'update delete _xmpp-client._tcp.%s. SRV' % domain,
'update delete _xmpp-server._tcp.%s. SRV' % domain,
'update add %s. 1800 A %s' % (domain, new_ip),
'update add %s. 1800 A %s' % (domain, ipv4),
'update add %s. 14400 MX 5 %s.' % (domain, domain),
'update add %s. 14400 TXT "v=spf1 a mx -all"' % domain,
'update add pubsub.%s. 1800 A %s' % (domain, new_ip),
'update add muc.%s. 1800 A %s' % (domain, new_ip),
'update add vjud.%s. 1800 A %s' % (domain, new_ip),
'update add pubsub.%s. 1800 A %s' % (domain, ipv4),
'update add muc.%s. 1800 A %s' % (domain, ipv4),
'update add vjud.%s. 1800 A %s' % (domain, ipv4),
'update add _xmpp-client._tcp.%s. 14400 SRV 0 5 5222 %s.' % (domain, domain),
'update add _xmpp-server._tcp.%s. 14400 SRV 0 5 5269 %s.' % (domain, domain)
]
if new_ipv6 is not None:
if ipv6 is not None:
lines += [
'update add %s. 1800 AAAA %s' % (domain, new_ipv6),
'update add pubsub.%s. 1800 AAAA %s' % (domain, new_ipv6),
'update add muc.%s. 1800 AAAA %s' % (domain, new_ipv6),
'update add vjud.%s. 1800 AAAA %s' % (domain, new_ipv6),
'update add %s. 1800 AAAA %s' % (domain, ipv6),
'update add pubsub.%s. 1800 AAAA %s' % (domain, ipv6),
'update add muc.%s. 1800 AAAA %s' % (domain, ipv6),
'update add vjud.%s. 1800 AAAA %s' % (domain, ipv6),
]
lines += [
'show',
@ -222,10 +216,10 @@ def dyndns_update(dyn_host="dynhost.yunohost.org", domain=None, key=None, ip=Non
if os.system('/usr/bin/nsupdate -k %s /etc/yunohost/dyndns/zone' % private_key_file) == 0:
logger.success(m18n.n('dyndns_ip_updated'))
with open('/etc/yunohost/dyndns/old_ip', 'w') as f:
f.write(new_ip)
if new_ipv6 is not None:
f.write(ipv4)
if ipv6 is not None:
with open('/etc/yunohost/dyndns/old_ipv6', 'w') as f:
f.write(new_ipv6)
f.write(ipv6)
else:
os.system('rm -f /etc/yunohost/dyndns/old_ip')
os.system('rm -f /etc/yunohost/dyndns/old_ipv6')

View file

@ -35,12 +35,13 @@ import errno
import os
import dns.resolver
import cPickle as pickle
from urllib import urlopen
from datetime import datetime, timedelta
from moulinette.core import MoulinetteError
from moulinette.utils.log import getActionLogger
from yunohost.domain import get_public_ip
logger = getActionLogger('yunohost.monitor')
glances_uri = 'http://127.0.0.1:61209'
@ -210,9 +211,9 @@ def monitor_network(units=None, human_readable=False):
logger.debug('interface name %s was not found', iname)
elif u == 'infos':
try:
p_ip = str(urlopen('https://ip.yunohost.org').read())
p_ipv4 = get_public_ip()
except:
p_ip = 'unknown'
p_ipv4 = 'unknown'
l_ip = 'unknown'
for name, addrs in devices.items():
@ -231,7 +232,7 @@ def monitor_network(units=None, human_readable=False):
proto, gateway = addr.popitem()
result[u] = {
'public_ip': p_ip,
'public_ip': p_ipv4,
'local_ip': l_ip,
'gateway': gateway,
}