+ Automated configuration baseline auditing, Active Directory role isolation checks (e.g. verifying Domain Controllers do not co-locate IIS or Remote Desktop), and fleet hardening standards require an active enterprise license with the best_practices capability enabled.
+
+
+ 💡 This capability is inactive by default. You can define rules in src/hub/best_practice_rules.py and activate it in the Licensing Portal at any time.
+
+
+
+
+
+
+
+
+ """
+ bp_kpi_value = "INACTIVE"
+ bp_kpi_sub = "Requires 'best_practices' license capability"
+ bp_kpi_badge = 'LOCKED'
+
+ # Build rows for Tab 1 (Forwarders), Tab 2 (Server Roles), and Tab 3 (Telemetry)
+ client_rows = []
+ server_roles_rows = []
+ telemetry_rows = []
+
+ for node in clients_data:
+ cid = node["client_id"]
+ host = node["hostname"]
+ ost = node["os_type"]
+ os_name = node["os_name"]
+ is_srv = node["is_server"]
+ roles = node["server_roles"]
+ info = node["client_info"]
+ fp = node["cert_fingerprint"]
+ st = node["status"]
+ first = node["first_seen"]
+ last = node["last_seen"]
+ cver = node["client_version"]
+ up_st = node["update_status"]
+ cpu_p = node["cpu_percent"]
+ mem_p = node["memory_percent"]
+ disk_p = node["disk_percent_free"]
esc_cid = html.escape(str(cid))
esc_host = html.escape(str(host))
@@ -273,23 +467,108 @@ class WebUIRenderer:
else:
ver_display = f'v{html.escape(cver)}'
- # Operating System & Server Classification Badge
- if ost == "windows_server" or is_server:
- role_cnt_badge = f'{len(roles)} Roles' if roles else ''
- os_badge_html = f'🏢 WIN SERVER{role_cnt_badge}'
- elif "win" in ost.lower():
+ # OS classification badge & display name
+ ost_lower = ost.lower()
+ if "server" in ost_lower or is_srv:
+ if "windows" in ost_lower or "win" in ost_lower:
+ filter_cat = "windows_server"
+ role_cnt_badge = f'{len(roles)} Roles' if roles else ''
+ os_badge_html = f'🏢 WIN SERVER{role_cnt_badge}'
+ os_badge_full = '🏢 WINDOWS SERVER'
+ os_display_name = html.escape(os_name or "Windows Server")
+ else:
+ filter_cat = "linux"
+ os_badge_html = f'🐧 LINUX'
+ os_badge_full = '🐧 LINUX SERVER'
+ os_display_name = html.escape(os_name or "Linux Node")
+ elif "windows" in ost_lower or "win" in ost_lower:
+ filter_cat = "windows_client"
os_badge_html = f'🖥️ WINDOWS'
- elif "linux" in ost.lower():
+ os_badge_full = '🖥️ WINDOWS CLIENT'
+ os_display_name = html.escape(os_name or "Windows Workstation")
+ elif "linux" in ost_lower:
+ filter_cat = "linux"
os_badge_html = f'🐧 LINUX'
+ os_badge_full = '🐧 LINUX'
+ os_display_name = html.escape(os_name or "Linux Node")
else:
+ filter_cat = "other"
os_badge_html = f'{esc_ost.upper()}'
+ os_badge_full = f'{html.escape(ost.upper())}'
+ os_display_name = html.escape(os_name or ost)
+ edition_str = html.escape(str(info.get("edition") or ""))
+ build_str = html.escape(str(info.get("build") or ""))
+ arch_str = html.escape(str(info.get("architecture") or ""))
+ specs_sub = f"{edition_str} • Build {build_str} • {arch_str}".strip(" •") if (edition_str or build_str or arch_str) else ""
+
+ # Roles badges
+ role_badges = []
+ if roles:
+ for r in roles:
+ esc_r = html.escape(str(r))
+ r_lower = str(r).lower()
+ if "active directory" in r_lower or "domain" in r_lower:
+ role_badges.append(f'🌐 {esc_r}')
+ elif "dns" in r_lower:
+ role_badges.append(f'📡 {esc_r}')
+ elif "dhcp" in r_lower:
+ role_badges.append(f'📶 {esc_r}')
+ elif "web server" in r_lower or "iis" in r_lower or "nginx" in r_lower or "apache" in r_lower:
+ role_badges.append(f'🌍 {esc_r}')
+ elif "hyper-v" in r_lower or "kvm" in r_lower or "qemu" in r_lower:
+ role_badges.append(f'⚡ {esc_r}')
+ elif "remote desktop" in r_lower or "terminal" in r_lower or "ssh" in r_lower:
+ role_badges.append(f'🖥️ {esc_r}')
+ elif "file" in r_lower or "storage" in r_lower or "samba" in r_lower or "nfs" in r_lower:
+ role_badges.append(f'📁 {esc_r}')
+ elif "print" in r_lower or "cups" in r_lower:
+ role_badges.append(f'🖨️ {esc_r}')
+ else:
+ role_badges.append(f'⚙️ {esc_r}')
+ roles_cell_html = "".join(role_badges)
+ else:
+ roles_cell_html = 'Workstation / Member Node (0 Roles)'
+
+ # Hardware specs & telemetry
+ ip_list = info.get("ip_addresses") or []
+ ip_str = ", ".join(ip_list[:2]) if ip_list else "Local"
+ mem_tot = info.get("memory_total_mb")
+ mem_tot_str = f"{round(mem_tot / 1024, 1)} GB" if mem_tot else ""
+ cpu_cnt = info.get("cpu_count")
+ cpu_cnt_str = f"{cpu_cnt} Cores • " if cpu_cnt else ""
+
+ cpu_bar_col = "#34d399" if cpu_p < 75 else ("#fbbf24" if cpu_p < 90 else "#f87171")
+ mem_bar_col = "#34d399" if mem_p < 75 else ("#fbbf24" if mem_p < 90 else "#f87171")
+ disk_bar_col = "#34d399" if disk_p >= 20 else ("#fbbf24" if disk_p >= 10 else "#f87171")
+
+ # Best Practice node compliance result
+ if is_bp_licensed and bp_evaluation and "fleet_results" in bp_evaluation:
+ node_eval = bp_evaluation["fleet_results"].get(cid) or bp_evaluation["fleet_results"].get(host)
+ if node_eval:
+ n_checks = node_eval.get("checks", [])
+ n_fails = sum(1 for c in n_checks if c.get("status") == "FAIL")
+ n_warns = sum(1 for c in n_checks if c.get("status") == "WARN")
+ n_passes = sum(1 for c in n_checks if c.get("status") == "PASS")
+ if n_fails > 0:
+ bp_node_badge = f'❌ {n_fails} FAIL'
+ elif n_warns > 0:
+ bp_node_badge = f'⚠️ {n_warns} WARN'
+ else:
+ bp_node_badge = f'✅ {n_passes} PASS'
+ else:
+ bp_node_badge = '✅ HEALTHY'
+ else:
+ bp_node_badge = '🔒 Locked'
+
+ # Builtin indicator
if fp == "LOCAL-HOST-BUILTIN":
esc_st = "LOCAL HUB HOST"
badge_cls = "badge-active"
fp_display = '⚡ Built-in Log Collector'
btn_action = 'Integrated (0 Seats)'
btn_del = ''
+ host_tag = '⚡ LOCAL HUB'
else:
fp_display = f"{esc_fp[:16]}..."
btn_action = (
@@ -298,11 +577,15 @@ class WebUIRenderer:
f''
)
btn_del = f''
+ host_tag = ''
+ safe_info_json = html.escape(json.dumps(node, indent=2))
+
+ # 1. Forwarders Row (Tab 1)
client_rows.append(f"""
{esc_st.upper()}
-
{esc_host}
+
{esc_host}{host_tag}
{esc_cid}
{os_badge_html}
{ver_display}
@@ -316,9 +599,81 @@ class WebUIRenderer:
""")
- clients_html = "".join(client_rows) if client_rows else '