2021-12-28 03:01:00 -03:00
|
|
|
# coding: utf-8
|
|
|
|
import traceback
|
|
|
|
import asyncio
|
|
|
|
import time
|
|
|
|
import os
|
|
|
|
from async_dns.core import types, Address
|
|
|
|
from async_dns.resolver import DNSClient
|
|
|
|
|
|
|
|
from sqlalchemy.future import select
|
|
|
|
|
|
|
|
from .model import db, update_mx, update_a, FQDN, MXRecord, ARecord, IPV4Addr, Direccion, Destinatario
|
|
|
|
from .registro import log
|
|
|
|
|
|
|
|
if not os.environ.get('DNS_RELAY'):
|
|
|
|
dns_relay = '192.168.0.1'
|
|
|
|
else:
|
|
|
|
dns_relay = os.environ.get('DNS_RELAY')
|
|
|
|
|
|
|
|
async def updateDNS():
|
|
|
|
pendientes = 0
|
2022-01-21 01:21:44 -03:00
|
|
|
destinos = 0
|
2021-12-28 03:01:00 -03:00
|
|
|
# await log.debug('Updatedns')
|
2022-12-13 17:42:48 -03:00
|
|
|
missingFQDN = []
|
|
|
|
|
2021-12-28 03:01:00 -03:00
|
|
|
try:
|
|
|
|
rdestino = await db.execute(select(Destinatario).join(Direccion).join(FQDN).where(Destinatario.enviado==0).distinct(FQDN.id))
|
|
|
|
for destinatario in rdestino.scalars():
|
|
|
|
result = await db.execute(select(Direccion).where(Direccion.id==destinatario.direccionid))
|
|
|
|
dbemail = result.scalar_one_or_none()
|
2022-01-21 01:21:44 -03:00
|
|
|
destinos += 1
|
2021-12-28 03:01:00 -03:00
|
|
|
|
|
|
|
tieneMXValido = False
|
|
|
|
valido = int(time.time())
|
|
|
|
|
2022-01-21 01:21:44 -03:00
|
|
|
retries = 3
|
2022-01-21 01:39:56 -03:00
|
|
|
while tieneMXValido is False and retries > 0:
|
2022-01-21 01:21:44 -03:00
|
|
|
retries -= 1
|
|
|
|
dbmx = await db.execute(select(MXRecord).where(MXRecord.fqdnid==dbemail.dominioid))
|
|
|
|
for mx_record in dbmx.scalars():
|
|
|
|
if mx_record.validohasta > valido:
|
|
|
|
tieneMXValido = True
|
|
|
|
break
|
|
|
|
|
2022-01-21 01:39:56 -03:00
|
|
|
if tieneMXValido is False:
|
2022-01-21 01:41:31 -03:00
|
|
|
await servidores_correo(dbemail.dominioid)
|
2022-01-21 01:21:44 -03:00
|
|
|
|
|
|
|
if retries <= 0:
|
|
|
|
await log.error('Error al actualizar los servidores MX de {}'.format(dbemail.direccion))
|
|
|
|
pendientes += 1
|
2022-12-13 17:42:48 -03:00
|
|
|
destinatario.intentos += 1
|
2022-12-13 17:46:24 -03:00
|
|
|
if destinatario.intentos > 10:
|
|
|
|
destinatario.enviado = 2
|
2022-12-13 17:42:48 -03:00
|
|
|
await db.commit()
|
2021-12-28 03:01:00 -03:00
|
|
|
|
|
|
|
except:
|
|
|
|
await log.error('Traceback {}'.format(traceback.format_exc()))
|
|
|
|
|
2022-01-21 01:21:44 -03:00
|
|
|
if destinos>0 and pendientes == 0:
|
|
|
|
await log.info('Todos los servidores MX estan disponibles para enviar los correos')
|
|
|
|
elif destinos>0 and pendientes>0:
|
|
|
|
await log.info('Algunos servidores MX no pudieron resolverse')
|
2021-12-28 03:01:00 -03:00
|
|
|
|
2022-01-21 01:21:44 -03:00
|
|
|
if destinos > pendientes:
|
|
|
|
return True #hay correos que mandar
|
|
|
|
else:
|
|
|
|
return False #nada que hacer
|
2021-12-28 03:01:00 -03:00
|
|
|
|
|
|
|
async def servidores_correo(dominioid):
|
|
|
|
|
|
|
|
try:
|
|
|
|
result = await db.execute(select(FQDN).where(FQDN.id==dominioid))
|
|
|
|
dominio = result.scalar_one_or_none()
|
|
|
|
servidores = await resolver(types.MX, dominio.fqdn)
|
|
|
|
except:
|
|
|
|
# await log.error('Traceback {}'.format(traceback.format_exc()))
|
2022-01-21 01:21:44 -03:00
|
|
|
await log.error("No se pudo resolver los servidores de correo de '{}'".format(dominio.fqdn))
|
|
|
|
return False
|
2021-12-28 03:01:00 -03:00
|
|
|
|
|
|
|
await log.info("Actualizando los servidores de correo de: {}".format(dominio.fqdn))
|
|
|
|
|
|
|
|
for host in servidores:
|
|
|
|
typename = host.data.type_name
|
|
|
|
prioridad, fqdn = host.data.data
|
|
|
|
|
2022-01-21 01:21:44 -03:00
|
|
|
tiempo = int(time.time())+10 #add the 10, because of the sleep delay
|
2021-12-28 03:01:00 -03:00
|
|
|
validohasta = tiempo
|
|
|
|
|
|
|
|
try:
|
|
|
|
direcciones = await resolver(types.A, fqdn)
|
|
|
|
except:
|
|
|
|
# await log.error('Traceback {}'.format(traceback.format_exc()))
|
|
|
|
# await log.debug("No se pudo resolver la dirección A => {}".format(fqdn))
|
|
|
|
continue
|
|
|
|
|
|
|
|
dbmx = await update_mx(dominio.id, fqdn, prioridad)
|
|
|
|
|
|
|
|
# await log.debug("Servidor {}: '{}' prioridad {} validohasta: {}".format(typename, fqdn, prioridad, dbmx.validohasta))
|
|
|
|
for direccion in direcciones:
|
|
|
|
if direccion.qtype == types.A:
|
|
|
|
ttl = direccion.ttl + tiempo
|
|
|
|
typename = direccion.data.type_name
|
|
|
|
ipv4 = direccion.data.data
|
|
|
|
|
|
|
|
if ttl > validohasta:
|
|
|
|
validohasta = ttl
|
|
|
|
|
|
|
|
await update_a(dbmx.fqdnmxid, ipv4, ttl)
|
|
|
|
|
|
|
|
# await log.debug("Dirección {}: '{}' TTL {} (time:{}, ttl:{})".format(typename, ipv4, ttl, tiempo, direccion.ttl))
|
|
|
|
|
|
|
|
dbmx.validohasta = validohasta
|
|
|
|
await db.commit()
|
2022-01-21 01:21:44 -03:00
|
|
|
return True
|
2021-12-28 03:01:00 -03:00
|
|
|
# await log.debug("Servidor {}: '{}' prioridad {} validohasta: {}".format(typename, fqdn, prioridad, dbmx.validohasta))
|
|
|
|
|
|
|
|
async def resolver(tipo=types.A, fqdn='ilab.cl'):
|
|
|
|
client = DNSClient()
|
|
|
|
retry = 10
|
|
|
|
while retry > 0:
|
|
|
|
try:
|
|
|
|
return await client.query(fqdn, tipo, Address.parse(dns_relay))
|
|
|
|
# for valor in res:
|
|
|
|
# await log.debug('valor => {}'.format(valor))
|
|
|
|
# typename = valor.data.type_name
|
|
|
|
# if tipo == types.A:
|
|
|
|
# fqdn = valor.data.data
|
|
|
|
# await log.debug('data => {}'.format(fqdn))
|
|
|
|
# else:
|
|
|
|
# await log.debug('data => {}'.format(valor.data))
|
2022-01-21 01:21:44 -03:00
|
|
|
# prioridad, fqdn = valor.data.data
|
|
|
|
# return res
|
2021-12-28 03:01:00 -03:00
|
|
|
except asyncio.exceptions.TimeoutError:
|
|
|
|
retry = retry - 1
|
2022-01-21 01:21:44 -03:00
|
|
|
log.warning(u'Quedan {} intentos'.format(retry))
|
2021-12-28 03:01:00 -03:00
|
|
|
continue
|
|
|
|
|
|
|
|
raise asyncio.exceptions.TimeoutError('Intentos excedidos')
|