From c452575b77802615068d1ad4fa32872d085973e1 Mon Sep 17 00:00:00 2001 From: waazaa-fr Date: Mon, 11 Nov 2024 19:06:04 +0100 Subject: [PATCH] gestion par config.yml pour multiples updates --- Dockerfile | 5 +- root/app/ddns-myaddr.py | 116 +++++++++++++++++++++++++++------------- root/start/start.sh | 7 +++ 3 files changed, 90 insertions(+), 38 deletions(-) diff --git a/Dockerfile b/Dockerfile index 41640b1..1f04de4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,15 +1,18 @@ FROM alpine:3.20.0 ENV TZ=Europe/Paris +ENV DDNS_MYADDR_NO_UPDATE_LIMIT=30 ENV DDNS_MYADDR_IP_VERSION="ipv4" ENV DDNS_MYADDR_KEY=xxxxx RUN apk update && apk add --no-cache tzdata curl wget python3 py3-pip RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone RUN mkdir -m 0777 -p /root/.config/pip && echo "[global]" > /root/.config/pip/pip.conf && echo "break-system-packages = true" >> /root/.config/pip/pip.conf -RUN pip install requests +RUN pip install requests pyyaml COPY ./root / RUN chmod a+x /start/*.sh +VOLUME /config + CMD ["/start/start.sh"] \ No newline at end of file diff --git a/root/app/ddns-myaddr.py b/root/app/ddns-myaddr.py index f27ed34..2d8a8c8 100644 --- a/root/app/ddns-myaddr.py +++ b/root/app/ddns-myaddr.py @@ -1,53 +1,95 @@ import requests import time import os +import threading import logging +import yaml from datetime import datetime, timedelta logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') -# Variables -ip_version = os.getenv('DDNS_MYADDR_IP_VERSION') # 'ipv4' ou 'ipv6' -key = os.getenv('DDNS_MYADDR_KEY') # Récupère clé -check_interval = 15 * 60 # Intervalle de vérification de 15 minutes -no_update_limit = timedelta(days=30) # Limite de 30 jours +log_lock = threading.Lock() # Création d'un verrou pour les logs -def get_public_ip(): - if ip_version == 'ipv6': - response = requests.get('https://api64.ipify.org') # Appel pour IPv6 - else: - response = requests.get('https://api.ipify.org') # Appel pour IPv4 - return response.text.strip() +# Charge le fichier de configuration +def load_config(file_path='/config/config.yml'): + with open(file_path, 'r') as file: + return yaml.safe_load(file) -def update_ip(ip): - url = 'https://myaddr.tools/update' - data = {'ip': ip, 'key': key} - response = requests.post(url, data=data) +def get_public_ip(version): + if version == 'ipv4': + return requests.get('https://api.ipify.org').text.strip() + elif version == 'ipv6': + return requests.get('https://api64.ipify.org').text.strip() + return None + +def update_ip(api_key, ip): + url = 'https://myaddr.tools/update' + data = {'ip': ip, 'key': api_key} + response = requests.post(url, data=data) return response.text -if __name__ == '__main__': - try: - last_ip = None - last_update_time = datetime.now() +def process_configuration(name, config): + last_ipv4 = None + last_ipv6 = None + last_update_ipv4_time = datetime.now() - timedelta(days=config['NO_UPDATE_LIMIT']) + last_update_ipv6_time = datetime.now() - timedelta(days=config['NO_UPDATE_LIMIT']) + api_key = config['KEY'] + while True: + current_time = datetime.now() - while True: - public_ip = get_public_ip() - current_time = datetime.now() + # Traitement de l'IPv4 + ipv4_action = config['IPv4'] + if ipv4_action == 'auto': + public_ipv4 = get_public_ip('ipv4') + if public_ipv4 != last_ipv4 and public_ipv4: + result = update_ip(api_key, public_ipv4) + with log_lock: # Utiliser le verrou pour synchroniser les logs + logging.info(f"{name} - IPv4 updated : {public_ipv4}, Response : {result}") + last_ipv4 = public_ipv4 + last_update_ipv4_time = current_time + elif ipv4_action != 'none': # Privé une IPv4 + if ipv4_action != last_ipv4 and current_time - last_update_ipv4_time > timedelta(days=config['NO_UPDATE_LIMIT']): + result = update_ip(api_key, ipv4_action) + with log_lock: # Utiliser le verrou pour synchroniser les logs + logging.info(f"{name} - IPv4 set to : {ipv4_action}, Response : {result}") + last_ipv4 = ipv4_action + last_update_ipv4_time = current_time - if public_ip != last_ip: # Vérifie si l'IP a changé - result = update_ip(public_ip) - logging.info(f"IP mise à jour : {public_ip}, Réponse : {result}") - last_ip = public_ip # Met à jour l'IP - last_update_time = current_time # Réinitialise le temps - elif current_time - last_update_time > no_update_limit: # Vérifie si 1 mois sans mise à jour - result = update_ip(public_ip) - logging.info(f"Aucune mise à jour depuis un mois, IP envoyée : {public_ip}, Réponse : {result}") - last_update_time = current_time # Réinitialise le temps - - else: - logging.info(f"Aucune mise à jour, l'IP reste la même : {public_ip}") + # Traitement de l'IPv6 + ipv6_action = config['IPv6'] + if ipv6_action == 'auto': + public_ipv6 = get_public_ip('ipv6') + if public_ipv6 != last_ipv6 and public_ipv6: + result = update_ip(api_key, public_ipv6) + with log_lock: # Utiliser le verrou pour synchroniser les logs + logging.info(f"{name} - IPv6 updated : {public_ipv6}, Response : {result}") + last_ipv6 = public_ipv6 + last_update_ipv6_time = current_time + elif ipv6_action != 'none': # Privé une IPv6 + if ipv6_action != last_ipv6 and current_time - last_update_ipv6_time > timedelta(days=config['NO_UPDATE_LIMIT']): + result = update_ip(api_key, ipv6_action) + with log_lock: # Utiliser le verrou pour synchroniser les logs + logging.info(f"{name} - IPv6 set to : {ipv6_action}, Response : {result}") + last_ipv6 = ipv6_action + last_update_ipv6_time = current_time - time.sleep(check_interval) # Pause de 15 minutes - + time.sleep(15 * 60) # Vérifie tous les 15 minutes + +if __name__ == '__main__': + configurations = load_config() + + threads = [] + try: + for config_name, config in configurations.items(): + thread = threading.Thread(target=process_configuration, args=(config_name, config)) + thread.start() + threads.append(thread) + + for thread in threads: + thread.join() except KeyboardInterrupt: - logging.info("Arrêt en cours...") \ No newline at end of file + logging.info("Arrêt du script en cours...") + # Optionnel : tu peux ajouter une logique pour arrêter les threads proprement si nécessaire. + for thread in threads: + thread.join(timeout=1) # Attendre un peu pour que les threads finissent + logging.info("Script arrêté.") \ No newline at end of file diff --git a/root/start/start.sh b/root/start/start.sh index 6872740..229239c 100644 --- a/root/start/start.sh +++ b/root/start/start.sh @@ -1,4 +1,11 @@ #!/usr/bin/env ash set -e +config_file="/config/config.yml" + +if [[ ! -f $config_file ]]; then + echo "Error : $config_file not found." + exit 1 +fi + python3 /app/ddns-myaddr.py \ No newline at end of file