This commit is contained in:
ilkeral
2025-07-21 13:49:36 +03:00
commit 342f1314c7
57 changed files with 9297 additions and 0 deletions

View File

@ -0,0 +1,359 @@
{% extends 'ssh_manager/base.html' %}
{% block title %}Host Yönetimi - Hosting Yönetim Paneli{% endblock %}
{% block content %}
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
<h3 class="mb-1">Host Yönetimi</h3>
<small class="text-muted">SSH bağlantı bilgileri ve sunucu durumları</small>
</div>
<div class="d-flex gap-2">
<button class="btn btn-success" onclick="refreshAllHosts()">
<i class="bi bi-arrow-clockwise"></i> Tümünü Yenile
</button>
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#hostModal" onclick="resetHostForm()">
<i class="bi bi-plus-circle"></i> Yeni Host
</button>
</div>
</div>
<!-- Host Tablosu -->
<div class="table-responsive">
<table class="table table-dark table-striped">
<thead>
<tr>
<th>Host Adı</th>
<th>IP/Domain</th>
<th>Port</th>
<th>Kullanıcı</th>
<th>Durum</th>
<th>Disk Kullanımı</th>
<th>Son Kontrol</th>
<th class="actions">İşlemler</th>
</tr>
</thead>
<tbody>
{% for host in ssh_credentials %}
<tr>
<td>
<strong>{{ host.name }}</strong>
{% if host.is_default %}
<span class="badge bg-info ms-1">Varsayılan</span>
{% endif %}
</td>
<td>{{ host.hostname }}</td>
<td>{{ host.port }}</td>
<td>{{ host.username }}</td>
<td>
<span class="badge {% if host.connection_status == 'connected' %}bg-success{% elif host.connection_status == 'failed' %}bg-danger{% else %}bg-secondary{% endif %}">
{% if host.connection_status == 'connected' %}
<i class="bi bi-check-circle"></i> Bağlı
{% elif host.connection_status == 'failed' %}
<i class="bi bi-x-circle"></i> Hata
{% else %}
<i class="bi bi-question-circle"></i> Bilinmiyor
{% endif %}
</span>
</td>
<td>
{% if host.disk_usage %}
<div class="d-flex align-items-center">
<div class="progress me-2" style="width: 80px; height: 8px;">
<div class="progress-bar {% if host.disk_usage > 80 %}bg-danger{% elif host.disk_usage > 60 %}bg-warning{% else %}bg-success{% endif %}"
style="width: {{ host.disk_usage }}%"></div>
</div>
<small>{{ host.disk_usage }}%</small>
</div>
{% else %}
<span class="text-muted">-</span>
{% endif %}
</td>
<td>
{% if host.last_checked %}
<small class="text-muted">{{ host.last_checked|date:"d.m.Y H:i" }}</small>
{% else %}
<span class="text-muted">Hiçbir zaman</span>
{% endif %}
</td>
<td class="actions">
<i class="action-icon bi bi-arrow-clockwise" title="Bağlantı Testi" onclick="testConnection({{ host.id }})"></i>
<i class="action-icon edit bi bi-pencil" title="Düzenle" onclick="editHost({{ host.id }})"></i>
<i class="action-icon delete bi bi-trash" title="Sil" onclick="deleteHost({{ host.id }})"></i>
<i class="action-icon logs bi bi-list-ul" title="Loglar" onclick="viewHostLogs({{ host.id }})"></i>
</td>
</tr>
{% empty %}
<tr>
<td colspan="8" class="text-center text-muted py-4">
<i class="bi bi-server" style="font-size: 2rem;"></i>
<div class="mt-2">Henüz host tanımlanmamış</div>
<button class="btn btn-sm btn-outline-primary mt-2" data-bs-toggle="modal" data-bs-target="#hostModal" onclick="resetHostForm()">
İlk host'u ekle
</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- Host Ekleme/Düzenleme Modal -->
<div class="modal fade" id="hostModal" tabindex="-1" aria-labelledby="hostModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content">
<form id="hostForm">
<div class="modal-header">
<h5 class="modal-title" id="hostModalLabel">Yeni Host Ekle</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<input type="hidden" id="hostId" name="hostId">
<!-- Bağlantı Bilgileri -->
<div class="mb-4">
<h6 class="text-muted mb-3">
<i class="bi bi-server me-1"></i>Bağlantı Bilgileri
</h6>
<div class="row g-3">
<div class="col-md-6">
<label for="hostName" class="form-label">Host Adı *</label>
<input type="text" class="form-control" id="hostName" name="name" required placeholder="Sunucu adı">
</div>
<div class="col-md-6">
<label for="hostname" class="form-label">IP/Domain *</label>
<input type="text" class="form-control" id="hostname" name="hostname" required placeholder="192.168.1.100 veya example.com">
</div>
<div class="col-md-6">
<label for="port" class="form-label">Port</label>
<input type="number" class="form-control" id="port" name="port" value="22" min="1" max="65535">
</div>
<div class="col-md-6">
<label for="username" class="form-label">Kullanıcı Adı *</label>
<input type="text" class="form-control" id="username" name="username" required placeholder="root">
</div>
</div>
</div>
<!-- Kimlik Doğrulama -->
<div class="mb-4">
<h6 class="text-muted mb-3">
<i class="bi bi-key me-1"></i>Kimlik Doğrulama
</h6>
<div class="row g-3">
<div class="col-12">
<label for="password" class="form-label">Şifre</label>
<input type="password" class="form-control" id="password" name="password" placeholder="SSH şifresi">
<small class="text-muted">Güvenlik için şifre şifrelenmiş olarak saklanır</small>
</div>
<div class="col-12">
<label for="basePath" class="form-label">Temel Dizin</label>
<input type="text" class="form-control" id="basePath" name="base_path" placeholder="/var/www" value="/var/www">
<small class="text-muted">Projelerin bulunduğu ana dizin</small>
</div>
</div>
</div>
<!-- Ayarlar -->
<div class="mb-3">
<h6 class="text-muted mb-3">
<i class="bi bi-gear me-1"></i>Ayarlar
</h6>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="isDefault" name="is_default">
<label class="form-check-label" for="isDefault">
Varsayılan host olarak ayarla
</label>
<small class="form-text text-muted d-block">Yeni projeler için otomatik olarak bu host kullanılacak</small>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Kapat</button>
<button type="button" class="btn btn-info me-2" onclick="testHostConnection()">
<i class="bi bi-wifi"></i> Bağlantı Testi
</button>
<button type="submit" class="btn btn-primary">Kaydet</button>
</div>
</form>
</div>
</div>
</div>
<script>
// Host bağlantı testi
function testConnection(hostId) {
showToast('Bağlantı test ediliyor...', 'info');
fetch(`/test-host-connection/${hostId}/`, {
method: 'POST',
headers: {
'X-CSRFToken': getCookie('csrftoken'),
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
showToast(data.message, 'success');
setTimeout(() => location.reload(), 1000);
} else {
showToast(data.message, 'error');
}
})
.catch(error => {
showToast('Bağlantı testi sırasında hata oluştu', 'error');
});
}
// Tüm hostları yenile
function refreshAllHosts() {
showToast('Tüm hostlar kontrol ediliyor...', 'info');
fetch('/refresh-all-hosts/', {
method: 'POST',
headers: {
'X-CSRFToken': getCookie('csrftoken'),
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
showToast(data.message, 'success');
setTimeout(() => location.reload(), 2000);
} else {
showToast(data.message, 'error');
}
})
.catch(error => {
showToast('Host yenileme sırasında hata oluştu', 'error');
});
}
// Host formu sıfırla
function resetHostForm() {
document.getElementById('hostForm').reset();
document.getElementById('hostId').value = '';
document.getElementById('hostModalLabel').textContent = 'Yeni Host Ekle';
document.getElementById('port').value = '22';
document.getElementById('basePath').value = '/var/www';
}
// Host düzenle
function editHost(hostId) {
fetch(`/get-host-details/${hostId}/`)
.then(response => response.json())
.then(data => {
if (data.success) {
const host = data.host;
document.getElementById('hostId').value = host.id;
document.getElementById('hostName').value = host.name;
document.getElementById('hostname').value = host.hostname;
document.getElementById('port').value = host.port;
document.getElementById('username').value = host.username;
document.getElementById('basePath').value = host.base_path || '/var/www';
document.getElementById('isDefault').checked = host.is_default;
document.getElementById('hostModalLabel').textContent = 'Host Düzenle';
const modal = new bootstrap.Modal(document.getElementById('hostModal'));
modal.show();
} else {
showToast('Host bilgileri alınamadı', 'error');
}
})
.catch(error => {
showToast('Host bilgileri alınırken hata oluştu', 'error');
});
}
// Host sil
function deleteHost(hostId) {
if (confirm('Bu host\'u silmek istediğinizden emin misiniz? Bu işlem geri alınamaz.')) {
fetch(`/delete-host/${hostId}/`, {
method: 'DELETE',
headers: {
'X-CSRFToken': getCookie('csrftoken'),
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
showToast(data.message, 'success');
setTimeout(() => location.reload(), 1000);
} else {
showToast(data.message, 'error');
}
})
.catch(error => {
showToast('Host silme sırasında hata oluştu', 'error');
});
}
}
// Host logları görüntüle
function viewHostLogs(hostId) {
// Host spesifik logları göstermek için logs sayfasına yönlendir
window.location.href = `/islem-gecmisi/?host=${hostId}`;
}
// Modal içinde bağlantı testi
function testHostConnection() {
const formData = new FormData(document.getElementById('hostForm'));
showToast('Bağlantı test ediliyor...', 'info');
fetch('/test-host-connection-form/', {
method: 'POST',
headers: {
'X-CSRFToken': getCookie('csrftoken')
},
body: formData
})
.then(response => response.json())
.then(data => {
if (data.success) {
showToast(data.message, 'success');
} else {
showToast(data.message, 'error');
}
})
.catch(error => {
showToast('Bağlantı testi sırasında hata oluştu', 'error');
});
}
// Host form submit
document.getElementById('hostForm').addEventListener('submit', function(e) {
e.preventDefault();
const formData = new FormData(this);
const hostId = document.getElementById('hostId').value;
const url = hostId ? `/update-host/${hostId}/` : '/create-host/';
fetch(url, {
method: 'POST',
headers: {
'X-CSRFToken': getCookie('csrftoken')
},
body: formData
})
.then(response => response.json())
.then(data => {
if (data.success) {
showToast(data.message, 'success');
bootstrap.Modal.getInstance(document.getElementById('hostModal')).hide();
setTimeout(() => location.reload(), 1000);
} else {
showToast(data.message, 'error');
}
})
.catch(error => {
showToast('Host kaydederken hata oluştu', 'error');
});
});
</script>
{% endblock %}