\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/DatabaseBackupMasterv8/templates/ |
|
B-Con CMD Config cPanel C-Rdp D-Log Info Jump Mass Ransom Symlink vHost Zone-H |
| Current File : /var/www/html/yedekledb24/DatabaseBackupMasterv8/templates/backup_jobs.html |
{% extends "base.html" %}
{% block content %}
<div class="container-fluid">
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">Yedekleme Görevleri</h1>
<div class="btn-toolbar mb-2 mb-md-0">
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addBackupJobModal">
<i class="fas fa-plus"></i> Yedekleme Görevi Ekle
</button>
</div>
</div>
<!-- Backup Jobs Table -->
<div class="card">
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover align-middle">
<thead>
<tr>
<th>Durum</th>
<th>Adı</th>
<th>Veritabanı</th>
<th>VT Tipi</th>
<th>Depolama</th>
<th>Depolama Tipi</th>
<th>Zamanlama</th>
<th>Son Çalışma</th>
<th>İşlemler</th>
</tr>
</thead>
<tbody>
{% for job in backup_jobs %}
<tr>
<td>
{% if job.enabled %}
<span class="badge bg-success">Etkin</span>
{% else %}
<span class="badge bg-danger">Devre Dışı</span>
{% endif %}
</td>
<td>{{ job.name }}</td>
<td>
{% for db in db_connections %}
{% if db.id == job.database_id %}
{{ db.name }}
{% endif %}
{% endfor %}
</td>
<td>
{% for db in db_connections %}
{% if db.id == job.database_id %}
{% if db.db_type == 'mysql' %}
<span class="badge bg-primary">
<i class="fa-brands fa-mysql me-1"></i>MySQL
</span>
{% elif db.db_type == 'mariadb' %}
<span class="badge bg-info">
<i class="fa-solid fa-server me-1"></i>MariaDB
</span>
{% elif db.db_type == 'postgresql' %}
<span class="badge bg-success">
<i class="fa-solid fa-database me-1"></i>PostgreSQL
</span>
{% endif %}
{% endif %}
{% endfor %}
</td>
<td>
{% for storage in storage_targets %}
{% if storage.id == job.storage_id %}
{{ storage.name }}
{% endif %}
{% endfor %}
</td>
<td>
{% for storage in storage_targets %}
{% if storage.id == job.storage_id %}
{% if storage.storage_type == 'smb' %}
<span class="badge bg-primary">
<i class="fas fa-share-alt me-1"></i>SMB/CIFS
</span>
{% elif storage.storage_type == 'nfs' %}
<span class="badge bg-info">
<i class="fas fa-network-wired me-1"></i>NFS
</span>
{% elif storage.storage_type == 'ftp' %}
<span class="badge bg-success">
<i class="fas fa-upload me-1"></i>FTP
</span>
{% endif %}
{% endif %}
{% endfor %}
</td>
<td>
<span class="badge bg-info">{{ job.schedule_type|capitalize }}</span>
<small>{{ job.schedule_value }}</small>
</td>
<td>
{% if job.last_run %}
{{ job.last_run.strftime('%Y-%m-%d %H:%M:%S') }}
{% else %}
Hiç Çalışmadı
{% endif %}
</td>
<td>
<div class="btn-group" role="group">
<form action="{{ url_for('run_backup_job', job_id=job.id) }}" method="post">
{{ csrf_form.csrf_token }}
<button type="submit" class="btn btn-sm btn-outline-primary me-1">
<i class="fas fa-play"></i> Şimdi Çalıştır
</button>
</form>
<form action="{{ url_for('toggle_backup_job', job_id=job.id) }}" method="post">
{{ csrf_form.csrf_token }}
<button type="submit" class="btn btn-sm btn-outline-{% if job.enabled %}warning{% else %}success{% endif %} me-1">
<i class="fas {% if job.enabled %}fa-pause{% else %}fa-play{% endif %}"></i>
{% if job.enabled %}Devre Dışı Bırak{% else %}Etkinleştir{% endif %}
</button>
</form>
<a href="{{ url_for('edit_backup_job', job_id=job.id) }}" class="btn btn-sm btn-outline-secondary me-1">
<i class="fas fa-edit"></i> Düzenle
</a>
<button type="button" class="btn btn-sm btn-outline-danger"
data-bs-toggle="modal" data-bs-target="#deleteModal{{ job.id }}">
<i class="fas fa-trash"></i> Sil
</button>
</div>
<!-- Delete Confirmation Modal -->
<div class="modal fade" id="deleteModal{{ job.id }}" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Silme İşlemini Onayla</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<strong>{{ job.name }}</strong> adlı yedekleme görevini silmek istediğinizden emin misiniz?
Bu işlem geri alınamaz.
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">İptal</button>
<form action="{{ url_for('delete_backup_job', job_id=job.id) }}" method="post">
{{ csrf_form.csrf_token }}
<button type="submit" class="btn btn-danger">Sil</button>
</form>
</div>
</div>
</div>
</div>
</td>
</tr>
{% endfor %}
{% if not backup_jobs %}
<tr>
<td colspan="9" class="text-center">Yedekleme görevi bulunamadı</td>
</tr>
{% endif %}
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- Add Backup Job Modal -->
<div class="modal fade" id="addBackupJobModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Yedekleme Görevi Ekle</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form method="post" action="{{ url_for('add_backup_job') }}">
<div class="modal-body">
{{ form.csrf_token }}
<div class="mb-3">
<label for="name" class="form-label">{{ form.name.label }}</label>
{{ form.name(class="form-control", placeholder="örn., Günlük MySQL Yedekleme") }}
</div>
<div class="mb-3">
<label for="database_id" class="form-label">{{ form.database_id.label }}</label>
{% if db_connections %}
<select name="database_id" id="database_id" class="form-select">
{% for db in db_connections %}
<option value="{{ db.id }}" data-db-type="{{ db.db_type }}">
{{ db.name }}
</option>
{% endfor %}
</select>
{% else %}
<select class="form-select" disabled>
<option>Kullanılabilir veritabanı bağlantısı yok</option>
</select>
<div class="form-text text-danger">
Önce bir veritabanı bağlantısı eklemeniz gerekiyor.
<a href="{{ url_for('databases') }}">Buradan ekleyin</a>
</div>
{% endif %}
</div>
<div class="mb-3">
<label for="storage_id" class="form-label">{{ form.storage_id.label }}</label>
{% if storage_targets %}
{{ form.storage_id(class="form-select") }}
{% else %}
<select class="form-select" disabled>
<option>Kullanılabilir depolama hedefi yok</option>
</select>
<div class="form-text text-danger">
Önce bir depolama hedefi eklemeniz gerekiyor.
<a href="{{ url_for('storage') }}">Buradan ekleyin</a>
</div>
{% endif %}
</div>
<div class="mb-3">
<label for="schedule_type" class="form-label">{{ form.schedule_type.label }}</label>
{{ form.schedule_type(class="form-select", id="scheduleType") }}
</div>
<div class="mb-3">
<label for="schedule_value" class="form-label">{{ form.schedule_value.label }}</label>
{{ form.schedule_value(class="form-control", id="scheduleValue") }}
<div class="form-text" id="scheduleHelp">
Günlük için: SS:DD (örn., 23:00)<br>
Haftalık için: gün:SS:DD (örn., pzt:23:00)<br>
Aylık için: gün:SS:DD (örn., 1:23:00)<br>
Özel için: standart cron ifadesi
</div>
</div>
<div class="mb-3">
<label for="retention_days" class="form-label">{{ form.retention_days.label }}</label>
{{ form.retention_days(class="form-control", value=30) }}
</div>
<div class="mb-3 form-check">
{{ form.enabled(class="form-check-input", checked=true) }}
<label class="form-check-label" for="enabled">{{ form.enabled.label }}</label>
</div>
<h5 class="mt-4 mb-2">Sıkıştırma Seçenekleri <span class="badge bg-info">Opsiyonel</span></h5>
<div class="alert alert-info">
<i class="fas fa-info-circle"></i> Yedeklerin sıkıştırılması disk alanından tasarruf sağlar ve transfer hızını artırır.
</div>
<div class="mb-3 form-check">
{{ form.compress_backup(class="form-check-input", id="compress_backup") }}
<label class="form-check-label" for="compress_backup">{{ form.compress_backup.label }}</label>
<div class="form-text">Yedekleri sıkıştırmak, yedekleme dosyalarının boyutunu önemli ölçüde küçültür.</div>
</div>
<div id="compression_options">
<div class="mb-3">
<label for="compression_type" class="form-label">{{ form.compression_type.label }}</label>
{{ form.compression_type(class="form-select", id="compression_type") }}
<div class="form-text">ZIP daha yaygın uyumludur, GZIP daha iyi sıkıştırma sağlar.</div>
</div>
</div>
<h5 class="mt-4 mb-2">Yedekleme Yöntemi</h5>
<div class="alert alert-info">
<i class="fas fa-info-circle"></i> Tam yedekleme tüm veritabanını kaydeder. Artırımlı yedekleme ise sadece değişen verileri saklar ve önceki tam yedeğe bağlıdır. Fark yedekleme, en son tam yedekten sonra tüm değişiklikleri içerir.
</div>
<div class="mb-3">
<label for="backup_method" class="form-label">{{ form.backup_method.label }}</label>
<select class="form-select" id="backup_method" name="backup_method">
<option value="full">Tam Yedekleme (Full Backup)</option>
<option value="incremental" class="mysql-only" style="display:none;">Artırımlı Yedekleme (Incremental Backup)</option>
<option value="differential" class="mysql-only" style="display:none;">Fark Yedekleme (Differential Backup)</option>
</select>
<div class="form-text">
<span class="badge bg-info">Not:</span> Artırımlı yedekleme şu anda sadece MySQL/MariaDB (XtraBackup/MariaBackup) için desteklenmektedir. PostgreSQL için sadece tam yedekleme kullanılır.
</div>
</div>
<div id="xtrabackup_options" style="display: none;">
<div class="mb-3">
<label for="xtrabackup_options" class="form-label">{{ form.xtrabackup_options.label }}</label>
{{ form.xtrabackup_options(class="form-control", placeholder="--compress=lz4 --compress-threads=4") }}
<div class="form-text">Percona XtraBackup/MariaBackup için ekstra komut satırı parametreleri. (İsteğe bağlı)</div>
</div>
</div>
<h5 class="mt-4 mb-2">Şifreleme Seçenekleri <span class="badge bg-info">Opsiyonel</span></h5>
<div class="alert alert-info">
<i class="fas fa-info-circle"></i> Şifreleme özelliği isteğe bağlıdır. Hassas veritabanı yedeklerinizi ek güvenlik katmanıyla korumak istiyorsanız etkinleştirebilirsiniz.
</div>
<div class="mb-3 form-check">
{{ form.encrypt_backup(class="form-check-input", id="encrypt_backup") }}
<label class="form-check-label" for="encrypt_backup">{{ form.encrypt_backup.label }}</label>
<div class="form-text">Yedekleri şifrelemek güvenliği artırır ancak geri yükleme sırasında şifre gerektirir.</div>
</div>
<div id="encryption_options" style="display: none;">
<div class="mb-3">
<label for="encryption_type" class="form-label">{{ form.encryption_type.label }}</label>
{{ form.encryption_type(class="form-select", id="encryption_type") }}
</div>
<div id="symmetric_options" style="display: none;">
<div class="mb-3">
<label for="encryption_passphrase" class="form-label">{{ form.encryption_passphrase.label }}</label>
{{ form.encryption_passphrase(class="form-control", placeholder="Güçlü bir şifre girin") }}
<div class="form-text">En az 8 karakter uzunluğunda, harfler, rakamlar ve özel karakterler içeren güçlü bir şifre kullanın.</div>
</div>
</div>
<div id="asymmetric_options" style="display: none;">
<div class="mb-3">
<label for="encryption_key_id" class="form-label">{{ form.encryption_key_id.label }}</label>
{{ form.encryption_key_id(class="form-select") }}
<div class="form-text">
{% if form.encryption_key_id.choices|length <= 1 %}
Asimetrik şifreleme için kullanılabilir GPG anahtarı bulunamadı.
<a href="{{ url_for('settings') }}">Ayarlar sayfasından</a> anahtar ekleyebilirsiniz.
{% endif %}
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">İptal</button>
<button type="submit" class="btn btn-primary"
{% if not db_connections or not storage_targets %}disabled{% endif %}>
Yedekleme Görevi Ekle
</button>
</div>
</form>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
// Zamanlama yardım metnini seçime göre güncelle
document.addEventListener('DOMContentLoaded', function() {
const scheduleTypeSelect = document.getElementById('scheduleType');
const scheduleValueInput = document.getElementById('scheduleValue');
if (scheduleTypeSelect && scheduleValueInput) {
scheduleTypeSelect.addEventListener('change', function() {
const scheduleType = this.value;
switch (scheduleType) {
case 'daily':
scheduleValueInput.placeholder = "23:00";
scheduleValueInput.value = "23:00";
break;
case 'weekly':
scheduleValueInput.placeholder = "pzt:23:00";
scheduleValueInput.value = "pzt:23:00";
break;
case 'monthly':
scheduleValueInput.placeholder = "1:23:00";
scheduleValueInput.value = "1:23:00";
break;
case 'custom':
scheduleValueInput.placeholder = "0 23 * * *";
scheduleValueInput.value = "0 23 * * *";
break;
}
});
// İlk değeri ayarlamak için change olayını tetikle
scheduleTypeSelect.dispatchEvent(new Event('change'));
}
// Sıkıştırma seçenekleri için
const compressCheckbox = document.getElementById('compress_backup');
const compressionOptions = document.getElementById('compression_options');
const compressionTypeSelect = document.getElementById('compression_type');
if (compressCheckbox && compressionOptions && compressionTypeSelect) {
// Sıkıştırma kutusu işaretlendiğinde seçenekleri göster/gizle
compressCheckbox.addEventListener('change', function() {
if (this.checked) {
compressionOptions.style.display = 'block';
} else {
compressionOptions.style.display = 'none';
}
});
// İlk yükleme için sıkıştırma durumunu kontrol et
if (compressCheckbox.checked) {
compressionOptions.style.display = 'block';
} else {
compressionOptions.style.display = 'none';
}
}
// Şifreleme seçenekleri için
const encryptCheckbox = document.getElementById('encrypt_backup');
const encryptionOptions = document.getElementById('encryption_options');
const encryptionTypeSelect = document.getElementById('encryption_type');
const symmetricOptions = document.getElementById('symmetric_options');
const asymmetricOptions = document.getElementById('asymmetric_options');
if (encryptCheckbox && encryptionOptions && encryptionTypeSelect) {
// Şifreleme kutusu işaretlendiğinde seçenekleri göster/gizle
encryptCheckbox.addEventListener('change', function() {
if (this.checked) {
encryptionOptions.style.display = 'block';
// Şifreleme tipi seçimini tetikle
encryptionTypeSelect.dispatchEvent(new Event('change'));
} else {
encryptionOptions.style.display = 'none';
}
});
// Şifreleme tipine göre ilgili seçenekleri göster/gizle
encryptionTypeSelect.addEventListener('change', function() {
const encryptionType = this.value;
if (encryptionType === 'symmetric') {
symmetricOptions.style.display = 'block';
asymmetricOptions.style.display = 'none';
} else if (encryptionType === 'asymmetric') {
symmetricOptions.style.display = 'none';
asymmetricOptions.style.display = 'block';
} else {
symmetricOptions.style.display = 'none';
asymmetricOptions.style.display = 'none';
}
});
// İlk yükleme için şifreleme durumunu kontrol et
if (encryptCheckbox.checked) {
encryptionOptions.style.display = 'block';
encryptionTypeSelect.dispatchEvent(new Event('change'));
}
}
// Yedekleme yöntemi seçenekleri için
const backupMethodSelect = document.getElementById('backup_method');
const xtrabackupOptions = document.getElementById('xtrabackup_options');
const dbIdSelect = document.getElementById('database_id');
// Veritabanı tipi ve yedekleme metodu kombinasyonuna göre seçenekleri güncelle
function updateBackupMethodOptions() {
if (!backupMethodSelect || !xtrabackupOptions || !dbIdSelect) {
return;
}
const backupMethod = backupMethodSelect.value;
const selectedDbOption = dbIdSelect.options[dbIdSelect.selectedIndex];
const dbType = selectedDbOption ? selectedDbOption.getAttribute('data-db-type') : '';
// Artırımlı yedekleme seçeneklerini göster/gizle
const mysqlOnlyOptions = document.querySelectorAll('.mysql-only');
if (dbType === 'mysql' || dbType === 'mariadb') {
// MySQL/MariaDB için artırımlı yedekleme seçeneklerini göster
mysqlOnlyOptions.forEach(option => {
option.style.display = '';
});
// XtraBackup sadece incremental/differential ve MySQL/MariaDB için gösterilsin
if (backupMethod === 'incremental' || backupMethod === 'differential') {
xtrabackupOptions.style.display = 'block';
} else {
xtrabackupOptions.style.display = 'none';
}
} else {
// PostgreSQL için artırımlı yedekleme seçeneklerini gizle
mysqlOnlyOptions.forEach(option => {
option.style.display = 'none';
});
// PostgreSQL için sadece "full" seçeneği olmalı
backupMethodSelect.value = 'full';
// XtraBackup seçeneklerini gizle
xtrabackupOptions.style.display = 'none';
}
}
// Yedekleme metodu veya veritabanı değişince güncelle
if (backupMethodSelect) {
backupMethodSelect.addEventListener('change', updateBackupMethodOptions);
}
if (dbIdSelect) {
dbIdSelect.addEventListener('change', updateBackupMethodOptions);
}
// İlk yükleme için yedekleme metodunu kontrol et
updateBackupMethodOptions();
});
</script>
{% endblock %}