feature/integracion-panel-restore-targets
This commit is contained in:
@@ -3,13 +3,14 @@
|
||||
from PySide6.QtWidgets import (
|
||||
QWidget, QVBoxLayout, QHBoxLayout, QGroupBox,
|
||||
QFormLayout, QLineEdit, QPushButton, QSpinBox,
|
||||
QCheckBox, QFileDialog, QMessageBox, QScrollArea
|
||||
QCheckBox, QFileDialog, QMessageBox, QScrollArea, QComboBox
|
||||
)
|
||||
from pathlib import Path
|
||||
|
||||
from ..utils.crypto import encrypt_password, decrypt_password
|
||||
from ..extract.seven_zip import SevenZipExtractor
|
||||
from ..sql.sql_manager import SQLServerManager
|
||||
from ..panel import panel_client
|
||||
|
||||
|
||||
class ConfigTab(QWidget):
|
||||
@@ -20,6 +21,7 @@ class ConfigTab(QWidget):
|
||||
super().__init__()
|
||||
self.engine = engine
|
||||
self.config = {}
|
||||
self._catalog_names: list[str] = []
|
||||
self._setup_ui()
|
||||
|
||||
def _setup_ui(self):
|
||||
@@ -118,7 +120,38 @@ class ConfigTab(QWidget):
|
||||
|
||||
sql_group.setLayout(sql_layout)
|
||||
layout.addWidget(sql_group)
|
||||
|
||||
|
||||
# Grupo: PANEL de Control (servidor de restauración activo)
|
||||
panel_group = QGroupBox("PANEL de Control")
|
||||
panel_layout = QFormLayout()
|
||||
|
||||
self.panel_url_input = QLineEdit()
|
||||
self.panel_url_input.setPlaceholderText("http://ip-del-panel:3000")
|
||||
panel_layout.addRow("URL del PANEL:", self.panel_url_input)
|
||||
|
||||
self.panel_token_input = QLineEdit()
|
||||
self.panel_token_input.setEchoMode(QLineEdit.EchoMode.Password)
|
||||
panel_layout.addRow("API Token:", self.panel_token_input)
|
||||
|
||||
self.panel_instance_combo = QComboBox()
|
||||
self.panel_instance_combo.setToolTip(
|
||||
"Nombre de este servidor en el panel. El CRA restaurará aquí lo que le "
|
||||
"corresponda y reenviará el resto por SFTP automáticamente."
|
||||
)
|
||||
self.refresh_instance_btn = QPushButton("Actualizar lista de servidores")
|
||||
self.refresh_instance_btn.clicked.connect(self._refresh_instance_combo)
|
||||
instance_row = QHBoxLayout()
|
||||
instance_row.addWidget(self.panel_instance_combo, stretch=1)
|
||||
instance_row.addWidget(self.refresh_instance_btn)
|
||||
panel_layout.addRow("Instancia (servidor):", instance_row)
|
||||
|
||||
test_panel_btn = QPushButton("🔌 Probar Conexión al PANEL")
|
||||
test_panel_btn.clicked.connect(self._test_panel_connection)
|
||||
panel_layout.addRow("", test_panel_btn)
|
||||
|
||||
panel_group.setLayout(panel_layout)
|
||||
layout.addWidget(panel_group)
|
||||
|
||||
# Grupo: Concurrencia
|
||||
concurrency_group = QGroupBox("Concurrencia")
|
||||
concurrency_layout = QFormLayout()
|
||||
@@ -269,7 +302,42 @@ class ConfigTab(QWidget):
|
||||
self.dry_run_checkbox.setChecked(features.get("dry_run_mode", False))
|
||||
self.auto_scan_checkbox.setChecked(features.get("auto_scan_enabled", True))
|
||||
self.scan_interval_spinbox.setValue(features.get("scan_interval_seconds", 30))
|
||||
|
||||
# PANEL de Control
|
||||
panel = config.get("panel", {})
|
||||
self.panel_url_input.setText(panel.get("api_url", ""))
|
||||
self.panel_token_input.setText(panel.get("api_token", ""))
|
||||
self._refresh_instance_combo()
|
||||
|
||||
def _refresh_instance_combo(self):
|
||||
"""Recarga los nombres de servidores desde el catálogo del panel."""
|
||||
current = self.panel_instance_combo.currentText().strip()
|
||||
saved_key = (self.config.get("panel", {}).get("instance_key") or "").strip()
|
||||
preserve = current or saved_key
|
||||
|
||||
api_url = self.panel_url_input.text().strip()
|
||||
api_token = self.panel_token_input.text().strip()
|
||||
|
||||
names: list[str] = []
|
||||
if api_url and api_token:
|
||||
names = panel_client.list_restore_target_names(api_url, api_token)
|
||||
|
||||
self._catalog_names = names
|
||||
|
||||
items = [""]
|
||||
for name in names:
|
||||
if name not in items:
|
||||
items.append(name)
|
||||
if preserve and preserve not in items:
|
||||
items.append(preserve)
|
||||
|
||||
self.panel_instance_combo.blockSignals(True)
|
||||
self.panel_instance_combo.clear()
|
||||
self.panel_instance_combo.addItems(items)
|
||||
idx = self.panel_instance_combo.findText(preserve)
|
||||
self.panel_instance_combo.setCurrentIndex(idx if idx >= 0 else 0)
|
||||
self.panel_instance_combo.blockSignals(False)
|
||||
|
||||
def _save_config(self):
|
||||
"""Guarda la configuración."""
|
||||
# Construir config
|
||||
@@ -307,9 +375,31 @@ class ConfigTab(QWidget):
|
||||
"dry_run_mode": self.dry_run_checkbox.isChecked(),
|
||||
"auto_scan_enabled": self.auto_scan_checkbox.isChecked(),
|
||||
"scan_interval_seconds": self.scan_interval_spinbox.value()
|
||||
},
|
||||
"panel": {
|
||||
"api_url": self.panel_url_input.text().strip(),
|
||||
"api_token": self.panel_token_input.text().strip(),
|
||||
"instance_key": self.panel_instance_combo.currentText().strip(),
|
||||
}
|
||||
}
|
||||
|
||||
panel_url = self.panel_url_input.text().strip()
|
||||
panel_token = self.panel_token_input.text().strip()
|
||||
instance_key = self.panel_instance_combo.currentText().strip()
|
||||
if panel_url and panel_token and not instance_key:
|
||||
QMessageBox.warning(
|
||||
self,
|
||||
"Advertencia",
|
||||
"Con panel configurado debe seleccionar la instancia (servidor).",
|
||||
)
|
||||
if panel_url and instance_key and self._catalog_names and instance_key not in self._catalog_names:
|
||||
QMessageBox.warning(
|
||||
self,
|
||||
"Advertencia",
|
||||
f'La instancia "{instance_key}" no está en el catálogo del panel. '
|
||||
"Verifique el nombre o cree el servidor en Servidores de Restauración.",
|
||||
)
|
||||
|
||||
# Cifrar password si no usa Windows Auth
|
||||
if not self.sql_windows_auth_checkbox.isChecked():
|
||||
password = self.sql_password_input.text()
|
||||
@@ -356,6 +446,25 @@ class ConfigTab(QWidget):
|
||||
"No se pudo auto-detectar 7-Zip. Por favor, selecciona manualmente."
|
||||
)
|
||||
|
||||
def _test_panel_connection(self):
|
||||
"""Prueba la conexión al PANEL y muestra el servidor de restauración activo."""
|
||||
api_url = self.panel_url_input.text().strip()
|
||||
api_token = self.panel_token_input.text().strip()
|
||||
|
||||
if not api_url:
|
||||
QMessageBox.warning(self, "Error", "Debe especificar la URL del PANEL.")
|
||||
return
|
||||
|
||||
success, info = panel_client.test_connection(api_url, api_token)
|
||||
|
||||
if success:
|
||||
self._refresh_instance_combo()
|
||||
QMessageBox.information(
|
||||
self, "Éxito", f"Conexión al PANEL exitosa.\n{info or ''}"
|
||||
)
|
||||
else:
|
||||
QMessageBox.critical(self, "Error", f"No se pudo conectar al PANEL:\n{info}")
|
||||
|
||||
def _on_auth_changed(self, checked: bool):
|
||||
"""Maneja el cambio en el tipo de autenticación."""
|
||||
self.sql_username_input.setEnabled(not checked)
|
||||
|
||||
@@ -4,7 +4,7 @@ from PySide6.QtWidgets import (
|
||||
QWidget, QVBoxLayout, QHBoxLayout, QTableWidget,
|
||||
QTableWidgetItem, QPushButton, QDialog, QFormLayout,
|
||||
QLineEdit, QTextEdit, QCheckBox, QDialogButtonBox,
|
||||
QMessageBox
|
||||
QMessageBox, QLabel
|
||||
)
|
||||
from PySide6.QtCore import Qt
|
||||
|
||||
|
||||
Reference in New Issue
Block a user