\x89PNG\r\n\x1a\n\x00\x00\x00\x0DIHDR\x00\x00\x00\x01\x00 \x00\x00\x01\x08\x06\x00\x00\x00\x1F\x15\xC4\x89\x00\x00\x00 \x0AIDATx\x9Ccb\x00\x00\x00\x06\x00\x03\x1A\x05\x9D\x00\x00 \x00\x00IEND\xAE\x42\x60\x82
| Path : /var/www/html/yedekledb24/DatabaseBackupMasterv4/ |
|
B-Con CMD Config cPanel C-Rdp D-Log Info Jump Mass Ransom Symlink vHost Zone-H |
| Current File : /var/www/html/yedekledb24/DatabaseBackupMasterv4/restore_database_fixed.py |
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
yedekleDB24 için veritabanı geri yükleme scripti.
Bu script, yedeklenmiş veritabanını orijinal konumuna geri yükler.
"""
import os
import sys
import logging
import tempfile
import subprocess
from datetime import datetime
from flask import current_app, request
from models import BackupLog, db
# GPG şifreleme için destek
try:
from encryption_utils import decrypt_file
encryption_support = True
except ImportError:
logging.warning("GPG decryption support not available - encryption_utils.py not found")
encryption_support = False
# Logging yapılandırması
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
def restore_postgresql_database(db_conn, backup_file):
"""
PostgreSQL veritabanını geri yükler.
Args:
db_conn (dict): Veritabanı bağlantı bilgileri (host, port, username, password, database)
backup_file (str): Yedek dosyasının yolu
Returns:
bool: Başarılı ise True, değilse False
"""
try:
# Determine pg_restore command based on PostgreSQL version
pg_restore_cmd_base = "pg_restore"
# If a specific PostgreSQL version is configured, use the version-specific pg_restore
if 'pg_version' in db_conn and db_conn['pg_version']:
version_specific_cmd = f"/usr/lib/postgresql/{db_conn['pg_version']}/bin/pg_restore"
# Check if this version exists
if os.path.exists(version_specific_cmd):
pg_restore_cmd_base = version_specific_cmd
logger.info(f"PostgreSQL {db_conn['pg_version']} spesifik pg_restore kullanılıyor: {pg_restore_cmd_base}")
else:
logger.warning(f"PostgreSQL {db_conn['pg_version']} pg_restore komutu bulunamadı: {version_specific_cmd}, varsayılana dönülüyor")
# PostgreSQL geri yükleme komutu
pg_restore_cmd = [
pg_restore_cmd_base,
'--clean', # Varolan nesneleri temizle
'--if-exists', # Varolan nesneleri düşürme hatalarını görmezden gel
'--no-owner', # Nesnelerin sahipliğini atla
'--no-privileges', # Ayrıcalık atamalarını atla
'-h', db_conn['host'],
'-p', str(db_conn['port']),
'-U', db_conn['username'],
'-d', db_conn['database'],
backup_file
]
# PGPASSWORD çevre değişkeni ayarla
env = os.environ.copy()
env['PGPASSWORD'] = db_conn['password']
# Komutu çalıştır
logger.info(f"PostgreSQL veritabanı geri yükleniyor: {db_conn['database']}")
process = subprocess.Popen(
pg_restore_cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=env
)
stdout, stderr = process.communicate()
# Sonucu kontrol et
if process.returncode != 0:
error_msg = stderr.decode()
logger.error(f"Veritabanı geri yükleme hatası: {error_msg}")
# Check for version compatibility errors
if "server version" in error_msg and "client version" in error_msg:
logger.error("PostgreSQL sürüm uyumsuzluğu tespit edildi. Lütfen doğru PostgreSQL sürümünü ayarlayın.")
return False
logger.info(f"Veritabanı başarıyla geri yüklendi: {db_conn['database']}")
return True
except Exception as e:
logger.error(f"Veritabanı geri yükleme hatası: {str(e)}")
return False
def restore_mysql_database(db_conn, backup_file):
"""
MySQL/MariaDB veritabanını geri yükler.
Args:
db_conn (dict): Veritabanı bağlantı bilgileri (host, port, username, password, database)
backup_file (str): Yedek dosyasının yolu
Returns:
bool: Başarılı ise True, değilse False
"""
try:
# MySQL geri yükleme komutu
mysql_cmd = [
'mysql',
'--host=' + db_conn['host'],
'--port=' + str(db_conn['port']),
'--user=' + db_conn['username'],
'--password=' + db_conn['password'],
db_conn['database']
]
# Komutu çalıştır
logger.info(f"MySQL veritabanı geri yükleniyor: {db_conn['database']}")
with open(backup_file, 'rb') as f:
process = subprocess.Popen(
mysql_cmd,
stdin=f,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
stdout, stderr = process.communicate()
# Sonucu kontrol et
if process.returncode != 0:
logger.error(f"Veritabanı geri yükleme hatası: {stderr.decode()}")
return False
logger.info(f"Veritabanı başarıyla geri yüklendi: {db_conn['database']}")
return True
except Exception as e:
logger.error(f"Veritabanı geri yükleme hatası: {str(e)}")
return False
def restore_from_backup(log_id, passphrase=None):
"""
Bir yedekten veritabanını geri yükler.
Args:
log_id (int): Yedekleme kaydının ID'si
passphrase (str, optional): Şifreli yedekler için şifre
Returns:
dict: İşlem sonucu (success: bool, message: str)
"""
try:
# Yedek kaydını bul
backup_log = BackupLog.query.get(log_id)
if not backup_log:
return {
'success': False,
'message': f'Yedek kaydı bulunamadı (ID: {log_id})'
}
# İlgili yedekleme işini ve veritabanı bağlantısını al
backup_job = backup_log.job
db_conn = backup_job.database
# Yedek dosyasının var olup olmadığını kontrol et
if not backup_log.backup_file:
return {
'success': False,
'message': 'Yedek dosyası bulunamadı'
}
# Yedek dosyasını kontrol et
backup_file = backup_log.backup_file
if not os.path.exists(backup_file):
return {
'success': False,
'message': f'Yedek dosyası bulunamadı: {backup_file}'
}
# Veritabanı bağlantı bilgilerini hazırla
db_connection = {
'host': db_conn.host,
'port': db_conn.port,
'username': db_conn.username,
'password': db_conn.password,
'database': db_conn.database,
'db_type': db_conn.db_type
}
# PostgreSQL için sürüm bilgisini ekle
if db_conn.db_type == 'postgresql' and hasattr(db_conn, 'pg_version') and db_conn.pg_version:
db_connection['pg_version'] = db_conn.pg_version
# Şifrelenmiş yedekleri kontrol et
is_encrypted = False
temp_decrypted_file = None
# GPG şifreleme için destek kontrolü
try:
from encryption_utils import decrypt_file
encryption_support = True
except ImportError:
logger.warning("GPG encryption support not available - encryption_utils.py not found")
encryption_support = False
# Şifrelenmiş yedekleri işle
if encryption_support and backup_file.endswith('.gpg'):
is_encrypted = True
logger.info(f"Şifrelenmiş yedek dosyası algılandı: {backup_file}")
# Şifreleme türünü belirle (logdan)
if hasattr(backup_log, 'encrypted') and backup_log.encrypted:
encryption_type = backup_log.encryption_type
# Şifreleme türüne göre çözme
try:
# Geçici dosya oluştur
temp_decrypted_file = tempfile.mktemp(suffix='_decrypted')
if encryption_type == 'symmetric':
# Kullanıcıdan gelen şifreyi kullan
# Şifre yoksa kontrol et
if not passphrase:
return {
'success': False,
'message': 'Şifreli yedek dosyası için şifre gerekli',
'needs_passphrase': True
}
temp_decrypted_file = decrypt_file(backup_file, temp_decrypted_file, passphrase)
elif encryption_type == 'asymmetric':
# GPG anahtarı ile çöz
# Not: Bu durumda kullanıcının anahtarın private key'ine erişimi olmalı
# Şifreleme anahtarı kullanıcının GPG anahtar zincirinde olmalı
temp_decrypted_file = decrypt_file(backup_file, temp_decrypted_file)
else:
return {
'success': False,
'message': f'Desteklenmeyen şifreleme türü: {encryption_type}'
}
if temp_decrypted_file:
logger.info(f"Yedek dosyasının şifresi başarıyla çözüldü: {temp_decrypted_file}")
backup_file = temp_decrypted_file
else:
return {
'success': False,
'message': 'Dosya şifresi çözülemedi. Şifre doğru mu?'
}
except Exception as e:
logger.error(f"Dosya şifresini çözme hatası: {str(e)}")
return {
'success': False,
'message': f'Dosya şifresini çözme hatası: {str(e)}'
}
else:
# Basit şifre çözme yöntemi (eski yedekler için)
try:
# Kullanıcıdan gelen şifreyi kullan
# Şifre yoksa kontrol et
if not passphrase:
return {
'success': False,
'message': 'Şifreli yedek dosyası için şifre gerekli',
'needs_passphrase': True
}
temp_decrypted_file = tempfile.mktemp(suffix='_decrypted')
temp_decrypted_file = decrypt_file(backup_file, temp_decrypted_file, passphrase)
if temp_decrypted_file:
logger.info(f"Yedek dosyasının şifresi başarıyla çözüldü: {temp_decrypted_file}")
backup_file = temp_decrypted_file
else:
return {
'success': False,
'message': 'Dosya şifresi çözülemedi. Şifre doğru mu?'
}
except Exception as e:
logger.error(f"Dosya şifresini çözme hatası: {str(e)}")
return {
'success': False,
'message': f'Dosya şifresini çözme hatası: {str(e)}'
}
try:
# Veritabanı tipine göre geri yükleme işlemini gerçekleştir
if db_conn.db_type == 'postgresql':
success = restore_postgresql_database(db_connection, backup_file)
elif db_conn.db_type in ('mysql', 'mariadb'):
success = restore_mysql_database(db_connection, backup_file)
else:
return {
'success': False,
'message': f'Desteklenmeyen veritabanı tipi: {db_conn.db_type}'
}
# Geçici dosya temizliği
if temp_decrypted_file and os.path.exists(temp_decrypted_file):
try:
os.remove(temp_decrypted_file)
except:
pass
return {
'success': success,
'message': f'Veritabanı {"başarıyla geri yüklendi" if success else "geri yükleme başarısız oldu"}: {db_conn.name}'
}
except Exception as e:
# Geçici dosya temizliği
if temp_decrypted_file and os.path.exists(temp_decrypted_file):
try:
os.remove(temp_decrypted_file)
except:
pass
raise e
except Exception as e:
logger.error(f"Geri yükleme hatası: {str(e)}")
return {
'success': False,
'message': f'Geri yükleme hatası: {str(e)}'
}
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Kullanım: python restore_database.py <log_id>")
sys.exit(1)
log_id = int(sys.argv[1])
result = restore_from_backup(log_id)
if result['success']:
print(result['message'])
sys.exit(0)
else:
print(f"Hata: {result['message']}")
sys.exit(1)