- Add all view templates (servers, auth, dashboard, admin, layouts, errors, terminal) - Fix SSH double decryption bug in SSHService - Fix router parameter type casting for strict_types - Add missing error views (401, 403, 404) - Add nginx manager with file editing - Add SSL certificates management - Add database manager with phpMyAdmin-like interface - Add sidebar server accordion
120 lines
5.9 KiB
PHP
Executable File
120 lines
5.9 KiB
PHP
Executable File
<?php $groups = $groups ?? []; ?>
|
|
|
|
<div class="page-header">
|
|
<h1 class="page-title">Add Server</h1>
|
|
<p class="page-subtitle">Register a new Linux server</p>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<form method="POST" action="/servers/create" class="form" id="serverForm">
|
|
<input type="hidden" name="_csrf_token" value="<?= $this->csrfToken() ?>">
|
|
|
|
<div class="form-section">
|
|
<h3><i class="fas fa-info-circle"></i> General Information</h3>
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="name">Server Name *</label>
|
|
<input type="text" id="name" name="name" class="form-input"
|
|
placeholder="e.g., Production Web Server" required>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="group_name">Group / Category</label>
|
|
<input type="text" id="group_name" name="group_name" class="form-input"
|
|
placeholder="e.g., Production, Staging"
|
|
list="groupList">
|
|
<datalist id="groupList">
|
|
<?php foreach ($groups as $group): ?>
|
|
<option value="<?= htmlspecialchars($group) ?>">
|
|
<?php endforeach; ?>
|
|
</datalist>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="description">Description</label>
|
|
<textarea id="description" name="description" class="form-input" rows="3"
|
|
placeholder="Optional description of the server"></textarea>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-section">
|
|
<h3><i class="fas fa-plug"></i> Connection Details</h3>
|
|
<div class="form-row form-row-3">
|
|
<div class="form-group">
|
|
<label for="ip_address">IP Address / Hostname *</label>
|
|
<input type="text" id="ip_address" name="ip_address" class="form-input"
|
|
placeholder="e.g., 192.168.1.100 or server.example.com" required>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="ssh_port">SSH Port *</label>
|
|
<input type="number" id="ssh_port" name="ssh_port" class="form-input"
|
|
value="22" min="1" max="65535" required>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="ssh_user">SSH User *</label>
|
|
<input type="text" id="ssh_user" name="ssh_user" class="form-input"
|
|
placeholder="e.g., root or admin" required>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-section">
|
|
<h3><i class="fas fa-key"></i> Authentication</h3>
|
|
<div class="auth-method-tabs">
|
|
<button type="button" class="tab active" data-method="password">Password</button>
|
|
<button type="button" class="tab" data-method="key">Private Key</button>
|
|
</div>
|
|
<div class="auth-method-content" id="passwordMethod">
|
|
<div class="form-group">
|
|
<label for="ssh_password">SSH Password</label>
|
|
<div class="input-group">
|
|
<input type="password" id="ssh_password" name="ssh_password" class="form-input"
|
|
placeholder="Leave blank if using key-based auth">
|
|
<button type="button" class="input-toggle-password" tabindex="-1">
|
|
<i class="fas fa-eye"></i>
|
|
</button>
|
|
</div>
|
|
<small class="form-hint">Credentials are encrypted with AES-256 before storage.</small>
|
|
</div>
|
|
</div>
|
|
<div class="auth-method-content" id="keyMethod" style="display: none;">
|
|
<div class="form-group">
|
|
<label for="ssh_key">SSH Private Key</label>
|
|
<textarea id="ssh_key" name="ssh_key" class="form-input font-mono" rows="6"
|
|
placeholder="Paste the private key content (RSA/Ed25519)"></textarea>
|
|
<small class="form-hint">Private key is encrypted before storage. Passphrase-protected keys supported.</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-section">
|
|
<div class="form-group">
|
|
<label class="checkbox-label">
|
|
<input type="checkbox" name="is_active" value="1" checked>
|
|
<span>Server active</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-actions">
|
|
<button type="submit" class="btn btn-primary">
|
|
<i class="fas fa-save"></i> Save Server
|
|
</button>
|
|
<a href="/servers" class="btn btn-secondary">Cancel</a>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
document.querySelectorAll('.auth-method-tabs .tab').forEach(tab => {
|
|
tab.addEventListener('click', function() {
|
|
document.querySelectorAll('.auth-method-tabs .tab').forEach(t => t.classList.remove('active'));
|
|
this.classList.add('active');
|
|
const method = this.dataset.method;
|
|
document.getElementById('passwordMethod').style.display = method === 'password' ? 'block' : 'none';
|
|
document.getElementById('keyMethod').style.display = method === 'key' ? 'block' : 'none';
|
|
});
|
|
});
|
|
</script>
|