\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 csarite.com
KUJUNTI.ID MINISH3LL
Path : /var/www/html/yedekledb24/DatabaseBackupMasterv6/
(S)h3ll Cr3at0r :
F!le Upl0ad :

B-Con CMD Config cPanel C-Rdp D-Log Info Jump Mass Ransom Symlink vHost Zone-H

Current File : /var/www/html/yedekledb24/DatabaseBackupMasterv6/restore_database.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)

© KUJUNTI.ID