Refonte sauvegarde MariaDB NAS => VPS2
This commit is contained in:
12
.env
12
.env
@@ -58,15 +58,19 @@ ALERT_LOOKBACK_MINUTES=120
|
|||||||
# Logs
|
# Logs
|
||||||
LOGLEVEL=INFO
|
LOGLEVEL=INFO
|
||||||
|
|
||||||
# paramètres mail
|
# paramètres mail Synology MailPlus
|
||||||
SMTP_HOST=ssl0.ovh.net
|
SMTP_HOST=mail.mj91.fr
|
||||||
SMTP_PORT=465
|
SMTP_PORT=465
|
||||||
SMTP_SECURITY=SSL
|
SMTP_SECURITY=SSL
|
||||||
SMTP_USER=services@domo91.fr
|
|
||||||
SMTP_PASS=VHq3278YA#sGV*bh#mR
|
SMTP_USER=services
|
||||||
|
SMTP_PASS=NOUVEAU_MOT_DE_PASSE_SERVICES
|
||||||
|
|
||||||
MAIL_FROM=services@domo91.fr
|
MAIL_FROM=services@domo91.fr
|
||||||
MAIL_TO=robots@domo91.fr
|
MAIL_TO=robots@domo91.fr
|
||||||
|
|
||||||
MAIL_TO_SACLAY=robots@domo91.fr,nicolas.thibaut@bw-paris-saclay.com
|
MAIL_TO_SACLAY=robots@domo91.fr,nicolas.thibaut@bw-paris-saclay.com
|
||||||
MAIL_FROM_SACLAY="DOMO91 Saclay <services@domo91.fr>"
|
MAIL_FROM_SACLAY="DOMO91 Saclay <services@domo91.fr>"
|
||||||
|
|
||||||
MAIL_TO_MEUDON=robots@domo91.fr,chef@parismeudonermitage.com
|
MAIL_TO_MEUDON=robots@domo91.fr,chef@parismeudonermitage.com
|
||||||
MAIL_FROM_MEUDON="DOMO91 Meudon <services@domo91.fr>"
|
MAIL_FROM_MEUDON="DOMO91 Meudon <services@domo91.fr>"
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import mysql.connector
|
||||||
|
|
||||||
|
conn = mysql.connector.connect(
|
||||||
|
host="10.9.0.1",
|
||||||
|
port=3306,
|
||||||
|
user="Michel",
|
||||||
|
password="wuP^wu&6xjx61bh*kjS^",
|
||||||
|
database="Sondes"
|
||||||
|
)
|
||||||
|
|
||||||
|
print("Connexion MariaDB OK via WireGuard")
|
||||||
|
|
||||||
|
conn.close()
|
||||||
@@ -1,45 +1,115 @@
|
|||||||
#!/home/debian/Gestion_sondes/myenv/bin/python
|
#!/home/debian/Gestion_sondes/myenv/bin/python
|
||||||
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import smtplib
|
import smtplib
|
||||||
from email.mime.text import MIMEText
|
from email.mime.text import MIMEText
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
heure_actuelle = datetime.now().strftime("%H:%M")
|
BASE_DIR = Path('/home/debian/Gestion_sondes')
|
||||||
|
ENV_FILE = BASE_DIR / '.env'
|
||||||
|
|
||||||
|
|
||||||
|
def charger_env(path: Path) -> None:
|
||||||
|
"""Charge simplement les variables d'un fichier .env sans dépendance externe."""
|
||||||
|
if not path.exists():
|
||||||
|
return
|
||||||
|
|
||||||
|
with path.open('r', encoding='utf-8') as f:
|
||||||
|
for line in f:
|
||||||
|
line = line.strip()
|
||||||
|
if not line or line.startswith('#') or '=' not in line:
|
||||||
|
continue
|
||||||
|
|
||||||
|
key, value = line.split('=', 1)
|
||||||
|
key = key.strip()
|
||||||
|
value = value.strip().strip('"').strip("'")
|
||||||
|
os.environ.setdefault(key, value)
|
||||||
|
|
||||||
|
|
||||||
|
def lire_liste_mails(valeur: str) -> list[str]:
|
||||||
|
return [mail.strip() for mail in valeur.split(',') if mail.strip()]
|
||||||
|
|
||||||
|
|
||||||
|
charger_env(ENV_FILE)
|
||||||
|
|
||||||
|
SMTP_HOST = os.getenv('SMTP_HOST', 'mail.mj91.fr')
|
||||||
|
SMTP_PORT = int(os.getenv('SMTP_PORT', '465'))
|
||||||
|
SMTP_SECURITY = os.getenv('SMTP_SECURITY', 'SSL').upper()
|
||||||
|
SMTP_USER = os.getenv('SMTP_USER', 'services')
|
||||||
|
SMTP_PASS = os.getenv('SMTP_PASS', '')
|
||||||
|
MAIL_FROM = os.getenv('MAIL_FROM', 'services@domo91.fr')
|
||||||
|
MAIL_TO = lire_liste_mails(os.getenv('MAIL_TO', 'services@domo91.fr'))
|
||||||
|
|
||||||
|
heure_actuelle = datetime.now().strftime('%H:%M')
|
||||||
etat_services = []
|
etat_services = []
|
||||||
anomalies = []
|
anomalies = []
|
||||||
|
|
||||||
try:
|
try:
|
||||||
output = subprocess.check_output("sudo /usr/bin/supervisorctl status", shell=True, text=True)
|
output = subprocess.check_output(
|
||||||
|
'sudo /usr/bin/supervisorctl status',
|
||||||
|
shell=True,
|
||||||
|
text=True,
|
||||||
|
stderr=subprocess.STDOUT,
|
||||||
|
)
|
||||||
|
|
||||||
for line in output.splitlines():
|
for line in output.splitlines():
|
||||||
parts = line.split()
|
parts = line.split()
|
||||||
if len(parts) >= 2:
|
if len(parts) >= 2:
|
||||||
nom, statut = parts[0], parts[1]
|
nom, statut = parts[0], parts[1]
|
||||||
etat_services.append(f"{nom} ➤ {statut}")
|
etat_services.append(f'{nom} ➤ {statut}')
|
||||||
if statut != "RUNNING":
|
if statut != 'RUNNING':
|
||||||
anomalies.append(f"{nom} ➤ {statut}")
|
anomalies.append(f'{nom} ➤ {statut}')
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
etat_services.append("❌ Impossible d'exécuter supervisorctl")
|
etat_services.append("❌ Impossible d'exécuter supervisorctl")
|
||||||
anomalies.append(f"Erreur : {e}")
|
anomalies.append(f'Erreur : {e}')
|
||||||
|
|
||||||
# Déclenchement mail si anomalie ou à 07:00
|
# Déclenchement mail si anomalie ou rapport quotidien à 07:00
|
||||||
envoyer_mail = bool(anomalies) or heure_actuelle == "07:00"
|
envoyer_mail = bool(anomalies) or heure_actuelle == '07:00'
|
||||||
|
|
||||||
if envoyer_mail:
|
if envoyer_mail:
|
||||||
sujet = "⚠️ Alerte Supervisor" if anomalies else "✅ Rapport quotidien Supervisor"
|
sujet = "Rapport Supervisor - anomalie detectee" if anomalies else "Rapport quotidien Supervisor"
|
||||||
intro = "🛑 Les services suivants ne sont pas en RUNNING :" if anomalies else "✅ Tous les services supervisés sont en RUNNING."
|
intro = (
|
||||||
contenu = f"{intro}\n\n" + "\n".join(etat_services)
|
'🛑 Les services suivants ne sont pas en RUNNING :'
|
||||||
|
if anomalies
|
||||||
|
else '✅ Tous les services supervisés sont en RUNNING.'
|
||||||
|
)
|
||||||
|
|
||||||
msg = MIMEText(contenu)
|
contenu = (
|
||||||
msg["Subject"] = sujet
|
f'{intro}\n\n'
|
||||||
msg["From"] = "supervisor@domo91.fr"
|
f'Date contrôle : {datetime.now().strftime("%d/%m/%Y %H:%M:%S")}\n\n'
|
||||||
msg["To"] = "services@domo91.fr"
|
+ '\n'.join(etat_services)
|
||||||
|
)
|
||||||
|
|
||||||
|
msg = MIMEText(contenu, _charset='utf-8')
|
||||||
|
msg['Subject'] = sujet
|
||||||
|
msg['From'] = MAIL_FROM
|
||||||
|
msg['To'] = ', '.join(MAIL_TO)
|
||||||
|
|
||||||
|
if not SMTP_PASS:
|
||||||
|
print('Erreur envoi mail : SMTP_PASS est vide dans le fichier .env')
|
||||||
|
else:
|
||||||
try:
|
try:
|
||||||
with smtplib.SMTP_SSL("smtp.mail.ovh.net", 465) as server:
|
if SMTP_SECURITY == 'SSL':
|
||||||
server.login("services@domo91.fr", "VHq3278YA#sGV*bh#mR")
|
with smtplib.SMTP_SSL(SMTP_HOST, SMTP_PORT) as server:
|
||||||
server.sendmail(msg["From"], [msg["To"]], msg.as_string())
|
server.login(SMTP_USER, SMTP_PASS)
|
||||||
print("📧 Mail envoyé.")
|
server.send_message(msg)
|
||||||
|
elif SMTP_SECURITY == 'STARTTLS':
|
||||||
|
with smtplib.SMTP(SMTP_HOST, SMTP_PORT) as server:
|
||||||
|
server.ehlo()
|
||||||
|
server.starttls()
|
||||||
|
server.ehlo()
|
||||||
|
server.login(SMTP_USER, SMTP_PASS)
|
||||||
|
server.send_message(msg)
|
||||||
|
else:
|
||||||
|
with smtplib.SMTP(SMTP_HOST, SMTP_PORT) as server:
|
||||||
|
server.login(SMTP_USER, SMTP_PASS)
|
||||||
|
server.send_message(msg)
|
||||||
|
|
||||||
|
print('📧 Mail envoyé.')
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Erreur envoi mail : {e}")
|
print(f'Erreur envoi mail : {e}')
|
||||||
else:
|
else:
|
||||||
print("🕖 Aucun mail envoyé (tout est OK et ce n’est pas l’heure du rapport).")
|
print("🕖 Aucun mail envoyé (tout est OK et ce n’est pas l’heure du rapport).")
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# A mettre dans le dossier /home/debian/Gestion_sondes/scripts du VPS
|
||||||
|
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
import sys
|
||||||
|
|
||||||
|
BACKUP_DIR = Path("/home/debian/backup")
|
||||||
|
LOG_FILE = BACKUP_DIR / "check_backup_mysql.log"
|
||||||
|
|
||||||
|
MAX_AGE_HOURS = 30
|
||||||
|
MIN_SIZE_MB = 50
|
||||||
|
|
||||||
|
|
||||||
|
def log(message):
|
||||||
|
ligne = f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} - {message}"
|
||||||
|
print(ligne)
|
||||||
|
with LOG_FILE.open("a", encoding="utf-8") as f:
|
||||||
|
f.write(ligne + "\n")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if not BACKUP_DIR.exists():
|
||||||
|
log(f"❌ Dossier introuvable : {BACKUP_DIR}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
fichiers = sorted(
|
||||||
|
BACKUP_DIR.glob("mysql_backup_*.sql"),
|
||||||
|
key=lambda p: p.stat().st_mtime,
|
||||||
|
reverse=True
|
||||||
|
)
|
||||||
|
|
||||||
|
if not fichiers:
|
||||||
|
log("❌ Aucun fichier de sauvegarde trouvé")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
dernier = fichiers[0]
|
||||||
|
stat = dernier.stat()
|
||||||
|
|
||||||
|
date_modif = datetime.fromtimestamp(stat.st_mtime)
|
||||||
|
age = datetime.now() - date_modif
|
||||||
|
taille_mb = stat.st_size / 1024 / 1024
|
||||||
|
|
||||||
|
log(f"🔎 Dernière sauvegarde : {dernier.name}")
|
||||||
|
log(f"🔎 Date : {date_modif.strftime('%Y-%m-%d %H:%M:%S')}")
|
||||||
|
log(f"🔎 Taille : {taille_mb:.1f} Mo")
|
||||||
|
|
||||||
|
if age > timedelta(hours=MAX_AGE_HOURS):
|
||||||
|
log(f"❌ Sauvegarde trop ancienne : {age}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if taille_mb < MIN_SIZE_MB:
|
||||||
|
log(f"❌ Sauvegarde trop petite : {taille_mb:.1f} Mo")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
log("✅ Contrôle sauvegarde OK")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# A mettre dans le dossier /home/debian/Gestion_sondes/scripts du VPS
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
BACKUP_DIR="/home/debian/backup"
|
||||||
|
DATE=$(date +"%Y-%m-%d_%H-%M")
|
||||||
|
FICHIER="mysql_backup_${DATE}.sql"
|
||||||
|
|
||||||
|
mkdir -p "$BACKUP_DIR"
|
||||||
|
|
||||||
|
echo "🔷 Démarrage dump MySQL : $(date)"
|
||||||
|
echo "🔷 Destination locale : $BACKUP_DIR/$FICHIER"
|
||||||
|
|
||||||
|
mysqldump --all-databases > "$BACKUP_DIR/$FICHIER"
|
||||||
|
|
||||||
|
echo "✅ Dump OK : $BACKUP_DIR/$FICHIER"
|
||||||
|
|
||||||
|
python3 /home/debian/Gestion_sondes/scripts/check_backup_mysql.py
|
||||||
|
|
||||||
|
find "$BACKUP_DIR" -name "mysql_backup_*.sql" -type f -mtime +30 -delete
|
||||||
93
scripts/test_mail.py
Normal file
93
scripts/test_mail.py
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
import smtplib
|
||||||
|
from email.mime.text import MIMEText
|
||||||
|
from email.mime.multipart import MIMEMultipart
|
||||||
|
|
||||||
|
SMTP_SERVER = "mail.mj91.fr" # ou ton serveur SMTP Synology / OVH
|
||||||
|
SMTP_PORT = 587 # 587 avec STARTTLS, ou 465 en SSL
|
||||||
|
SMTP_USER = "services" # adresse expéditrice
|
||||||
|
SMTP_PASSWORD ="84Bf&c$$1Mx953s8!L2"
|
||||||
|
import smtplib
|
||||||
|
from email.mime.text import MIMEText
|
||||||
|
from email.mime.multipart import MIMEMultipart
|
||||||
|
|
||||||
|
FROM_EMAIL = "services@domo91.fr"
|
||||||
|
TO_EMAIL = "robots@domo91.fr"
|
||||||
|
|
||||||
|
msg = MIMEMultipart()
|
||||||
|
msg["From"] = FROM_EMAIL
|
||||||
|
msg["To"] = TO_EMAIL
|
||||||
|
msg["Subject"] = "Test mail depuis la VM"
|
||||||
|
|
||||||
|
body = """
|
||||||
|
Bonjour,
|
||||||
|
|
||||||
|
Ceci est un test d'envoi de mail depuis la VM en SSH.
|
||||||
|
|
||||||
|
Si tu reçois ce message, l'envoi SMTP fonctionne.
|
||||||
|
|
||||||
|
Michel
|
||||||
|
"""
|
||||||
|
|
||||||
|
msg.attach(MIMEText(body, "plain"))
|
||||||
|
|
||||||
|
try:
|
||||||
|
print("Connexion au serveur SMTP...")
|
||||||
|
server = smtplib.SMTP(SMTP_SERVER, SMTP_PORT, timeout=20)
|
||||||
|
server.set_debuglevel(1)
|
||||||
|
|
||||||
|
print("Démarrage TLS...")
|
||||||
|
server.starttls()
|
||||||
|
|
||||||
|
print("Authentification...")
|
||||||
|
server.login(SMTP_USER, SMTP_PASSWORD)
|
||||||
|
|
||||||
|
print("Envoi du message...")
|
||||||
|
server.sendmail(FROM_EMAIL, TO_EMAIL, msg.as_string())
|
||||||
|
|
||||||
|
server.quit()
|
||||||
|
print("✅ Mail envoyé avec succès")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print("❌ Erreur lors de l'envoi :")
|
||||||
|
print(e)
|
||||||
|
|
||||||
|
FROM_EMAIL = "services@domo91.fr"
|
||||||
|
TO_EMAIL = "robots@domo91.fr"
|
||||||
|
|
||||||
|
msg = MIMEMultipart()
|
||||||
|
msg["From"] = FROM_EMAIL
|
||||||
|
msg["To"] = TO_EMAIL
|
||||||
|
msg["Subject"] = "Test mail depuis la VM"
|
||||||
|
|
||||||
|
body = """
|
||||||
|
Bonjour,
|
||||||
|
|
||||||
|
Ceci est un test d'envoi de mail depuis la VM en SSH.
|
||||||
|
|
||||||
|
Si tu reçois ce message, l'envoi SMTP fonctionne.
|
||||||
|
|
||||||
|
Michel
|
||||||
|
"""
|
||||||
|
|
||||||
|
msg.attach(MIMEText(body, "plain"))
|
||||||
|
|
||||||
|
try:
|
||||||
|
print("Connexion au serveur SMTP...")
|
||||||
|
server = smtplib.SMTP(SMTP_SERVER, SMTP_PORT, timeout=20)
|
||||||
|
server.set_debuglevel(1)
|
||||||
|
|
||||||
|
print("Démarrage TLS...")
|
||||||
|
server.starttls()
|
||||||
|
|
||||||
|
print("Authentification...")
|
||||||
|
server.login(SMTP_USER, SMTP_PASSWORD)
|
||||||
|
|
||||||
|
print("Envoi du message...")
|
||||||
|
server.sendmail(FROM_EMAIL, TO_EMAIL, msg.as_string())
|
||||||
|
|
||||||
|
server.quit()
|
||||||
|
print("✅ Mail envoyé avec succès")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print("❌ Erreur lors de l'envoi :")
|
||||||
|
print(e)
|
||||||
Reference in New Issue
Block a user