Python_scripts/7_LOGEPROJ/restaure_sauvegarde.py

243 lines
7.6 KiB
Python

#!/usr/bin/env python3
import argparse
import pathlib
import subprocess
import os
import psycopg2
from pathlib import Path
from sqlalchemy.engine import URL
from sqlalchemy import create_engine
import paramiko
import datetime
def etablit_connexion_SFTP(p_hote, p_port, p_utilisateur, p_motdepasse):
connexion_ssh = paramiko.SSHClient()
connexion_ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
connexion_ssh.connect(p_hote, p_port, p_utilisateur, p_motdepasse)
return connexion_ssh.open_sftp()
def creer_chaine_connexion(p_utilisateur, p_pass, p_serveur, p_port,p_base):
# return f"postgresql://{p_utilisateur}@{p_serveur}:{p_port}"
url_geo = URL.create('postgresql+psycopg2',
username = p_utilisateur,
password = p_pass,
host = p_serveur,
port = p_port,
database = p_base,
)
return create_engine(url_geo)
def creer_base_de_donnee(p_base_a_creer, p_base_connexion, p_chaine_connexion):
requete_SQL = f'CREATE DATABASE "{p_base_a_creer}" WITH OWNER logeproj'
commande = [
"psql",
f"{p_chaine_connexion}/{p_base_connexion}",
"-c",
f"{requete_SQL}",
]
commande_run = subprocess.run(commande)
code_retour = commande_run.returncode
if code_retour != 0:
return False
else:
return True
def supprimer_base_de_donnee(p_base_a_supprimer, p_base_connexion, p_chaine_connexion):
requete_SQL = f'DROP DATABASE "{p_base_a_supprimer}"'
commande = [
"psql",
f"{p_chaine_connexion}/{p_base_connexion}",
"-c",
f"{requete_SQL}",
]
commande_run = subprocess.run(commande)
code_retour = commande_run.returncode
if code_retour != 0:
return False
else:
return True
def lister_bases_de_donnees(p_connexion):
tableau_bases = []
requete_SQL = "SELECT datname FROM pg_database WHERE datistemplate = false;"
curseur = p_connexion
curseur.execute(requete_SQL)
for enregistrement in curseur:
tableau_bases.append(enregistrement[0])
return tableau_bases
def restaurer_sauvegarde(
p_chemin_sauvegarde, p_base, p_base_connexion, p_chaine_de_connexion
):
# connexion = psycopg2.connect(p_chaine_de_connexion)
connexion = p_chaine_de_connexion
if p_base in lister_bases_de_donnees(connexion):
supprimer_base_de_donnee(p_base, p_base_connexion, p_chaine_de_connexion)
creer_base_de_donnee(p_base, p_base_connexion, p_chaine_de_connexion)
connexion.close()
commande = [
"pg_restore",
"-d",
f"{p_chaine_de_connexion}/{p_base}",
p_chemin_sauvegarde,
]
commande_run = subprocess.run(commande)
code_retour = commande_run.returncode
if code_retour != 0:
return False
else:
return True
def restaurer_toutes_sauvegardes(
p_chemin_sauvegarde, p_base_de_connexion, p_chaine_connexion
):
repertoire_des_sauvegardes = pathlib.Path(p_chemin_sauvegarde)
for sauvegarde in repertoire_des_sauvegardes.glob("*-logeproj-centrale.custom"):
sauvegarde.resolve()
chemin = str(sauvegarde)
fichier = sauvegarde.name
fichier_split = fichier.split("-")
base = f"{fichier_split[0]}-logeproj-test"
restaurer_sauvegarde(chemin, base, p_base_de_connexion, p_chaine_connexion)
def cherche_chemin_rep_sauvegardes_du_jour(p_connexion_sftp, p_rep_racine, p_date, p_format=None):
liste_rep_backups_du_jour = []
date_backup = "1900-01-01"
rep_split = ["1900", "01", "01"]
p_connexion_sftp.chdir("/"+p_rep_racine)
for rep in p_connexion_sftp.listdir():
rep_split = rep.split("-")
if len(rep_split) < 3 : continue
if p_format is not None and rep.find(p_format) == -1: continue
date_backup = f"{rep_split[0]}-{rep_split[1]}-{rep_split[2]}"
if date_backup == p_date.strftime("%Y-%m-%d"):
liste_rep_backups_du_jour.append(rep)
nombre_de_rep = len(liste_rep_backups_du_jour)
if nombre_de_rep > 1:
print(
f"Le serveur de sauvegarde dispose de plusieurs répertoires de sauvegardes datés du {p_date.strftime('%d/%m/%Y')} :"
)
for indice in range(0, nombre_de_rep):
numero_rep = indice + 1
print(f"- {numero_rep} : {liste_rep_backups_du_jour[indice]}")
choix = int(
input(
"Entrer le numéro du répertoire dont vous souhaitez télécharger les sauvegardes : "
)
)
rep_sauvegarde_du_jour = liste_rep_backups_du_jour[choix - 1]
else:
rep_sauvegarde_du_jour = liste_rep_backups_du_jour[0]
chemin_sauvegardes_du_jour = f"/{p_rep_racine}/{rep_sauvegarde_du_jour}"
return chemin_sauvegardes_du_jour
def telecharge_un_fichier(
p_chemin_fichier_distant, p_chemin_fichier_local, p_connexionSFTP
):
print(
f"- Téléchargement de {p_chemin_fichier_distant} dans {p_chemin_fichier_local}"
)
p_connexionSFTP.get(p_chemin_fichier_distant, p_chemin_fichier_local)
def clos_connexion_SFTP(p_connexion_SFTP):
p_connexion_SFTP.close()
def main():
aujourdhui = datetime.date.today()
chemin_rep_local_sauvegarde = "./"
sftp_hote = "ftpmdv.myriadev.fr"
sftp_port = "22060"
sftp_utilisateur = "cen-isere"
sftp_mot_de_passe = "gaic4Ao'Do1O"
sftp_rep_racine_sauvegardes = 'cen-isere'
repertoire_sauvegardes = "/cen-isere"
serveur_postgresql = "91.134.194.221"
port_postgresql = "5432"
utilisateur_postgresql = "cen_admin"
mot_de_passe_postgresql = "#CEN38\@venir"
base_de_connexion = "logeproj"
# Si le mot de passe de postgre est stocké dans une variable d'environnement, plus
# besoin de le fournir par la suite
os.environ["PGPASSWORD"] = mot_de_passe_postgresql
parser = argparse.ArgumentParser()
parser.add_argument(
"-b", "--base",
required=False,
help="nom de la base à restaurer (si non fourni, le script restaure toutes les bases",
)
arguments = parser.parse_args()
arguments.base = 'logeproj'
connexion_sftp = etablit_connexion_SFTP(
sftp_hote, sftp_port, sftp_utilisateur, sftp_mot_de_passe
)
chemin_rep_sauvegardes_du_jour = cherche_chemin_rep_sauvegardes_du_jour(
connexion_sftp, sftp_rep_racine_sauvegardes, aujourdhui,'gz'
)
# Télécharger la base fournie en argument au format custom
chemin_sauvegarde_distante = chemin_rep_sauvegardes_du_jour
chemin_sauvegarde_locale = (
f"{chemin_rep_local_sauvegarde}"+chemin_rep_sauvegardes_du_jour.rsplit('/',1)[-1]
)
telecharge_un_fichier(
chemin_sauvegarde_distante, chemin_sauvegarde_locale, connexion_sftp
)
clos_connexion_SFTP(connexion_sftp)
chaine_de_connexion = creer_chaine_connexion(
utilisateur_postgresql,mot_de_passe_postgresql, serveur_postgresql, port_postgresql,base_de_connexion
)
if arguments.base is None:
# Restaurer toutes les sauvegardes
print(f'Restauration de toutes les sauvegardes')
restaurer_toutes_sauvegardes(
repertoire_sauvegardes, base_de_connexion, chaine_de_connexion
)
else:
# Restaurer la base fournie en argument
base=f'{arguments.base}'
print(f'Restauration de {base}')
fichier_sauvegarde = chemin_sauvegarde_locale
path_sauvegarde = pathlib.Path(fichier_sauvegarde)
restaurer_sauvegarde(
p_chemin_sauvegarde = path_sauvegarde,
p_base = base,
p_base_connexion = base_de_connexion,
p_chaine_de_connexion = chaine_de_connexion,
)
if __name__ == "__main__":
main()