Implement smart Magic DNS copy with automatic port detection

### Magic DNS Smart Copy Features:
- **PBS servers**: Automatically append `:8007` port when copying
- **PVE servers**: Automatically append `:8006` port when copying
- **Other machines**: Copy Magic DNS address without port (existing behavior)

### UI Improvements:
- PBS servers: Blue button with `:8007` port hint
- PVE servers: Orange button with `:8006` port hint
- Enhanced tooltips with service-specific port information
- Visual distinction between different server types

### PBS Backup Server Monitoring:
- Complete PBS API integration with authentication
- Real-time backup/restore task monitoring with detailed logs
- Namespace-separated backup visualization with color coding
- Datastore usage monitoring and status tracking
- Task history with success/failure status and error details

### Technical Implementation:
- Smart port detection via JavaScript `addSmartPort()` function
- Jinja2 template logic for conditional button styling
- PBS API endpoints for comprehensive backup monitoring
- Enhanced clipboard functionality with user feedback

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-09-14 10:48:47 +09:00
parent be3795c7bf
commit 7aa08682b8
4 changed files with 1888 additions and 18 deletions

View File

@@ -122,9 +122,20 @@
</div>
<div class="small text-success">
<i class="fas fa-link"></i> <code id="magicDns-{{ machine_data.id }}">{{ machine_data.machine_name or machine_data.hostname }}.headscale.local</code>
<button class="btn btn-sm btn-outline-secondary ms-1" onclick="copyToClipboard('{{ machine_data.machine_name or machine_data.hostname }}.headscale.local')" title="Magic DNS 주소 복사">
<i class="fas fa-copy"></i>
</button>
{% set machine_name = (machine_data.machine_name or machine_data.hostname).lower() %}
{% if 'pbs' in machine_name %}
<button class="btn btn-sm btn-outline-info ms-1" onclick="copyToClipboard('{{ machine_data.machine_name or machine_data.hostname }}.headscale.local')" title="Magic DNS 주소 복사 (PBS 서버 - 포트 8007 자동 추가)">
<i class="fas fa-copy"></i><small class="ms-1">:8007</small>
</button>
{% elif 'pve' in machine_name %}
<button class="btn btn-sm btn-outline-warning ms-1" onclick="copyToClipboard('{{ machine_data.machine_name or machine_data.hostname }}.headscale.local')" title="Magic DNS 주소 복사 (Proxmox VE - 포트 8006 자동 추가)">
<i class="fas fa-copy"></i><small class="ms-1">:8006</small>
</button>
{% else %}
<button class="btn btn-sm btn-outline-secondary ms-1" onclick="copyToClipboard('{{ machine_data.machine_name or machine_data.hostname }}.headscale.local')" title="Magic DNS 주소 복사">
<i class="fas fa-copy"></i>
</button>
{% endif %}
</div>
{% if machine_data.hostname != (machine_data.machine_name or machine_data.hostname) %}
<div class="small text-muted">
@@ -457,10 +468,37 @@ function deleteNode(nodeId, nodeName) {
});
}
// Magic DNS 주소 클립보드 복사 기능
// 스마트 포트 추가 기능
function addSmartPort(address) {
const lowerAddress = address.toLowerCase();
// PBS가 포함된 경우 :8007 포트 추가
if (lowerAddress.includes('pbs')) {
return address + ':8007';
}
// PVE가 포함된 경우 :8006 포트 추가
if (lowerAddress.includes('pve')) {
return address + ':8006';
}
// 기타 경우는 그대로 반환
return address;
}
// Magic DNS 주소 클립보드 복사 기능 (스마트 포트 지원)
function copyToClipboard(text) {
navigator.clipboard.writeText(text).then(() => {
showToast(`Magic DNS 주소가 복사되었습니다: ${text}`, 'success');
// 스마트 포트 추가 로직 적용
const enhancedText = addSmartPort(text);
navigator.clipboard.writeText(enhancedText).then(() => {
// 포트가 추가되었는지 확인하여 메시지 표시
if (enhancedText !== text) {
const port = enhancedText.split(':')[1];
showToast(`Magic DNS 주소가 복사되었습니다 (포트 ${port} 자동 추가): ${enhancedText}`, 'success');
} else {
showToast(`Magic DNS 주소가 복사되었습니다: ${enhancedText}`, 'success');
}
}).catch(err => {
console.error('복사 실패:', err);
showToast('복사에 실패했습니다.', 'danger');