Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6a2db542c3 | ||
|
|
d49fa9ce90 |
@@ -20,19 +20,25 @@ class GrafanaClient:
|
|||||||
Initialize the Grafana client.
|
Initialize the Grafana client.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
server: dict with keys: ip, port, api_token, use_ssl
|
server: dict with keys: ip, port, api_token (or user+password), use_ssl
|
||||||
"""
|
"""
|
||||||
self.ip: str = server["ip"]
|
self.ip: str = server["ip"]
|
||||||
self.port: int = int(server["port"])
|
self.port: int = int(server["port"])
|
||||||
self.api_token: str = server["api_token"]
|
self.api_token: str = server.get("api_token", "")
|
||||||
|
self.user: str = server.get("user", "")
|
||||||
|
self.password: str = server.get("password", "")
|
||||||
self.use_ssl: bool = bool(server.get("use_ssl", False))
|
self.use_ssl: bool = bool(server.get("use_ssl", False))
|
||||||
|
|
||||||
scheme = "https" if self.use_ssl else "http"
|
scheme = "https" if self.use_ssl else "http"
|
||||||
self.base_url: str = f"{scheme}://{self.ip}:{self.port}"
|
self.base_url: str = f"{scheme}://{self.ip}:{self.port}"
|
||||||
self.headers: dict[str, str] = {
|
self.headers: dict[str, str] = {"Content-Type": "application/json"}
|
||||||
"Authorization": f"Bearer {self.api_token}",
|
self.auth: tuple[str, str] | None = None
|
||||||
"Content-Type": "application/json",
|
|
||||||
}
|
if self.api_token:
|
||||||
|
self.headers["Authorization"] = f"Bearer {self.api_token}"
|
||||||
|
elif self.user and self.password:
|
||||||
|
self.auth = (self.user, self.password)
|
||||||
|
|
||||||
self.timeout: int = 10
|
self.timeout: int = 10
|
||||||
|
|
||||||
def _get(self, path: str, params: dict | None = None) -> Any:
|
def _get(self, path: str, params: dict | None = None) -> Any:
|
||||||
@@ -42,7 +48,7 @@ class GrafanaClient:
|
|||||||
url = f"{self.base_url}{path}"
|
url = f"{self.base_url}{path}"
|
||||||
log.debug("Grafana GET %s", url)
|
log.debug("Grafana GET %s", url)
|
||||||
resp = requests.get(
|
resp = requests.get(
|
||||||
url, headers=self.headers, params=params, timeout=self.timeout
|
url, headers=self.headers, params=params, auth=self.auth, timeout=self.timeout
|
||||||
)
|
)
|
||||||
resp.raise_for_status()
|
resp.raise_for_status()
|
||||||
return resp.json()
|
return resp.json()
|
||||||
@@ -54,7 +60,7 @@ class GrafanaClient:
|
|||||||
url = f"{self.base_url}{path}"
|
url = f"{self.base_url}{path}"
|
||||||
log.debug("Grafana POST %s", url)
|
log.debug("Grafana POST %s", url)
|
||||||
resp = requests.post(
|
resp = requests.post(
|
||||||
url, headers=self.headers, json=json_data, timeout=self.timeout
|
url, headers=self.headers, json=json_data, auth=self.auth, timeout=self.timeout
|
||||||
)
|
)
|
||||||
resp.raise_for_status()
|
resp.raise_for_status()
|
||||||
return resp.json()
|
return resp.json()
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ FIELD_MAP = {
|
|||||||
"mssql": ["user", "password", "database"],
|
"mssql": ["user", "password", "database"],
|
||||||
"postgresql": ["user", "password", "database"],
|
"postgresql": ["user", "password", "database"],
|
||||||
"redis": ["password", "db_index", "use_ssl"],
|
"redis": ["password", "db_index", "use_ssl"],
|
||||||
"grafana": ["api_token", "use_ssl"],
|
"grafana": ["user", "password", "api_token", "use_ssl"],
|
||||||
"prometheus": ["use_ssl"],
|
"prometheus": ["use_ssl"],
|
||||||
"rdp": ["user", "password", "rdp_resolution", "rdp_quality", "rdp_clipboard", "rdp_drives", "rdp_printers"],
|
"rdp": ["user", "password", "rdp_resolution", "rdp_quality", "rdp_clipboard", "rdp_drives", "rdp_printers"],
|
||||||
"vnc": ["password"],
|
"vnc": ["password"],
|
||||||
|
|||||||
@@ -140,7 +140,10 @@ class GrafanaTab(ctk.CTkFrame):
|
|||||||
|
|
||||||
def _get_client(self) -> GrafanaClient:
|
def _get_client(self) -> GrafanaClient:
|
||||||
if self._client is None:
|
if self._client is None:
|
||||||
self._client = GrafanaClient(self._current_alias, self.store)
|
server = self.store.get_server(self._current_alias)
|
||||||
|
if not server:
|
||||||
|
raise ValueError(f"Server '{self._current_alias}' not found")
|
||||||
|
self._client = GrafanaClient(server)
|
||||||
return self._client
|
return self._client
|
||||||
|
|
||||||
# ── Table population ──
|
# ── Table population ──
|
||||||
@@ -194,10 +197,9 @@ class GrafanaTab(ctk.CTkFrame):
|
|||||||
if url:
|
if url:
|
||||||
try:
|
try:
|
||||||
client = self._get_client()
|
client = self._get_client()
|
||||||
full_url = client.get_dashboard_url(url)
|
full_url = f"{client.base_url}{url}"
|
||||||
webbrowser.open(full_url)
|
webbrowser.open(full_url)
|
||||||
except Exception:
|
except Exception:
|
||||||
# Fallback: just open relative URL
|
|
||||||
webbrowser.open(url)
|
webbrowser.open(url)
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|||||||
@@ -189,8 +189,10 @@ class PrometheusTab(ctk.CTkFrame):
|
|||||||
try:
|
try:
|
||||||
client = self._get_client()
|
client = self._get_client()
|
||||||
|
|
||||||
targets = client.get_targets()
|
targets_resp = client.targets()
|
||||||
alerts = client.get_alerts()
|
targets = targets_resp.get("data", {}).get("activeTargets", [])
|
||||||
|
alerts_resp = client.alerts()
|
||||||
|
alerts = alerts_resp.get("data", {}).get("alerts", [])
|
||||||
|
|
||||||
self.after(0, lambda: self._populate_targets(targets))
|
self.after(0, lambda: self._populate_targets(targets))
|
||||||
self.after(0, lambda: self._populate_alerts(alerts))
|
self.after(0, lambda: self._populate_alerts(alerts))
|
||||||
@@ -210,7 +212,10 @@ class PrometheusTab(ctk.CTkFrame):
|
|||||||
|
|
||||||
def _get_client(self) -> PrometheusClient:
|
def _get_client(self) -> PrometheusClient:
|
||||||
if self._client is None:
|
if self._client is None:
|
||||||
self._client = PrometheusClient(self._current_alias, self.store)
|
server = self.store.get_server(self._current_alias)
|
||||||
|
if not server:
|
||||||
|
raise ValueError(f"Server '{self._current_alias}' not found")
|
||||||
|
self._client = PrometheusClient(server)
|
||||||
return self._client
|
return self._client
|
||||||
|
|
||||||
# ── Table population ──
|
# ── Table population ──
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
13
tools/ssh.py
13
tools/ssh.py
@@ -1511,16 +1511,19 @@ def _grafana_request(server: dict, endpoint: str) -> dict:
|
|||||||
import requests
|
import requests
|
||||||
host = server["ip"]
|
host = server["ip"]
|
||||||
port = server.get("port", 3000)
|
port = server.get("port", 3000)
|
||||||
protocol = "https" if server.get("ssl", False) else "http"
|
protocol = "https" if server.get("use_ssl", server.get("ssl", False)) else "http"
|
||||||
base_url = server.get("base_url", f"{protocol}://{host}:{port}")
|
base_url = server.get("base_url", f"{protocol}://{host}:{port}")
|
||||||
api_key = server.get("api_key", server.get("password", ""))
|
api_token = server.get("api_token", server.get("api_key", ""))
|
||||||
|
|
||||||
headers = {}
|
headers = {}
|
||||||
if api_key:
|
auth = None
|
||||||
headers["Authorization"] = f"Bearer {api_key}"
|
if api_token:
|
||||||
|
headers["Authorization"] = f"Bearer {api_token}"
|
||||||
|
elif server.get("user") and server.get("password"):
|
||||||
|
auth = (server["user"], server["password"])
|
||||||
|
|
||||||
url = f"{base_url.rstrip('/')}/api/{endpoint.lstrip('/')}"
|
url = f"{base_url.rstrip('/')}/api/{endpoint.lstrip('/')}"
|
||||||
resp = requests.get(url, headers=headers, timeout=15, verify=server.get("ssl_verify", True))
|
resp = requests.get(url, headers=headers, auth=auth, timeout=15, verify=server.get("ssl_verify", True))
|
||||||
resp.raise_for_status()
|
resp.raise_for_status()
|
||||||
return resp.json()
|
return resp.json()
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"""Version info for ServerManager."""
|
"""Version info for ServerManager."""
|
||||||
|
|
||||||
__version__ = "1.9.39"
|
__version__ = "1.9.41"
|
||||||
__app_name__ = "ServerManager"
|
__app_name__ = "ServerManager"
|
||||||
__author__ = "aibot777"
|
__author__ = "aibot777"
|
||||||
__description__ = "Desktop GUI for managing remote servers"
|
__description__ = "Desktop GUI for managing remote servers"
|
||||||
|
|||||||
Reference in New Issue
Block a user