[management,proxy,client] Add L4 capabilities (TLS/TCP/UDP) (#5530)

This commit is contained in:
Viktor Liu
2026-03-14 01:36:44 +08:00
committed by GitHub
parent fe9b844511
commit 3e6baea405
90 changed files with 9611 additions and 1397 deletions

View File

@@ -152,7 +152,7 @@ func (c *Client) printClients(data map[string]any) {
return
}
_, _ = fmt.Fprintf(c.out, "%-38s %-12s %-40s %s\n", "ACCOUNT ID", "AGE", "DOMAINS", "HAS CLIENT")
_, _ = fmt.Fprintf(c.out, "%-38s %-12s %-40s %s\n", "ACCOUNT ID", "AGE", "SERVICES", "HAS CLIENT")
_, _ = fmt.Fprintln(c.out, strings.Repeat("-", 110))
for _, item := range clients {
@@ -166,7 +166,7 @@ func (c *Client) printClientRow(item any) {
return
}
domains := c.extractDomains(client)
services := c.extractServiceKeys(client)
hasClient := "no"
if hc, ok := client["has_client"].(bool); ok && hc {
hasClient = "yes"
@@ -175,20 +175,20 @@ func (c *Client) printClientRow(item any) {
_, _ = fmt.Fprintf(c.out, "%-38s %-12v %s %s\n",
client["account_id"],
client["age"],
domains,
services,
hasClient,
)
}
func (c *Client) extractDomains(client map[string]any) string {
d, ok := client["domains"].([]any)
func (c *Client) extractServiceKeys(client map[string]any) string {
d, ok := client["service_keys"].([]any)
if !ok || len(d) == 0 {
return "-"
}
parts := make([]string, len(d))
for i, domain := range d {
parts[i] = fmt.Sprint(domain)
for i, key := range d {
parts[i] = fmt.Sprint(key)
}
return strings.Join(parts, ", ")
}

View File

@@ -189,7 +189,7 @@ type indexData struct {
Version string
Uptime string
ClientCount int
TotalDomains int
TotalServices int
CertsTotal int
CertsReady int
CertsPending int
@@ -202,7 +202,7 @@ type indexData struct {
type clientData struct {
AccountID string
Domains string
Services string
Age string
Status string
}
@@ -211,9 +211,9 @@ func (h *Handler) handleIndex(w http.ResponseWriter, _ *http.Request, wantJSON b
clients := h.provider.ListClientsForDebug()
sortedIDs := sortedAccountIDs(clients)
totalDomains := 0
totalServices := 0
for _, info := range clients {
totalDomains += info.DomainCount
totalServices += info.ServiceCount
}
var certsTotal, certsReady, certsPending, certsFailed int
@@ -234,24 +234,24 @@ func (h *Handler) handleIndex(w http.ResponseWriter, _ *http.Request, wantJSON b
for _, id := range sortedIDs {
info := clients[id]
clientsJSON = append(clientsJSON, map[string]interface{}{
"account_id": info.AccountID,
"domain_count": info.DomainCount,
"domains": info.Domains,
"has_client": info.HasClient,
"created_at": info.CreatedAt,
"age": time.Since(info.CreatedAt).Round(time.Second).String(),
"account_id": info.AccountID,
"service_count": info.ServiceCount,
"service_keys": info.ServiceKeys,
"has_client": info.HasClient,
"created_at": info.CreatedAt,
"age": time.Since(info.CreatedAt).Round(time.Second).String(),
})
}
resp := map[string]interface{}{
"version": version.NetbirdVersion(),
"uptime": time.Since(h.startTime).Round(time.Second).String(),
"client_count": len(clients),
"total_domains": totalDomains,
"certs_total": certsTotal,
"certs_ready": certsReady,
"certs_pending": certsPending,
"certs_failed": certsFailed,
"clients": clientsJSON,
"version": version.NetbirdVersion(),
"uptime": time.Since(h.startTime).Round(time.Second).String(),
"client_count": len(clients),
"total_services": totalServices,
"certs_total": certsTotal,
"certs_ready": certsReady,
"certs_pending": certsPending,
"certs_failed": certsFailed,
"clients": clientsJSON,
}
if len(certsPendingDomains) > 0 {
resp["certs_pending_domains"] = certsPendingDomains
@@ -278,7 +278,7 @@ func (h *Handler) handleIndex(w http.ResponseWriter, _ *http.Request, wantJSON b
Version: version.NetbirdVersion(),
Uptime: time.Since(h.startTime).Round(time.Second).String(),
ClientCount: len(clients),
TotalDomains: totalDomains,
TotalServices: totalServices,
CertsTotal: certsTotal,
CertsReady: certsReady,
CertsPending: certsPending,
@@ -291,9 +291,9 @@ func (h *Handler) handleIndex(w http.ResponseWriter, _ *http.Request, wantJSON b
for _, id := range sortedIDs {
info := clients[id]
domains := info.Domains.SafeString()
if domains == "" {
domains = "-"
services := strings.Join(info.ServiceKeys, ", ")
if services == "" {
services = "-"
}
status := "No client"
if info.HasClient {
@@ -301,7 +301,7 @@ func (h *Handler) handleIndex(w http.ResponseWriter, _ *http.Request, wantJSON b
}
data.Clients = append(data.Clients, clientData{
AccountID: string(info.AccountID),
Domains: domains,
Services: services,
Age: time.Since(info.CreatedAt).Round(time.Second).String(),
Status: status,
})
@@ -324,12 +324,12 @@ func (h *Handler) handleListClients(w http.ResponseWriter, _ *http.Request, want
for _, id := range sortedIDs {
info := clients[id]
clientsJSON = append(clientsJSON, map[string]interface{}{
"account_id": info.AccountID,
"domain_count": info.DomainCount,
"domains": info.Domains,
"has_client": info.HasClient,
"created_at": info.CreatedAt,
"age": time.Since(info.CreatedAt).Round(time.Second).String(),
"account_id": info.AccountID,
"service_count": info.ServiceCount,
"service_keys": info.ServiceKeys,
"has_client": info.HasClient,
"created_at": info.CreatedAt,
"age": time.Since(info.CreatedAt).Round(time.Second).String(),
})
}
h.writeJSON(w, map[string]interface{}{
@@ -347,9 +347,9 @@ func (h *Handler) handleListClients(w http.ResponseWriter, _ *http.Request, want
for _, id := range sortedIDs {
info := clients[id]
domains := info.Domains.SafeString()
if domains == "" {
domains = "-"
services := strings.Join(info.ServiceKeys, ", ")
if services == "" {
services = "-"
}
status := "No client"
if info.HasClient {
@@ -357,7 +357,7 @@ func (h *Handler) handleListClients(w http.ResponseWriter, _ *http.Request, want
}
data.Clients = append(data.Clients, clientData{
AccountID: string(info.AccountID),
Domains: domains,
Services: services,
Age: time.Since(info.CreatedAt).Round(time.Second).String(),
Status: status,
})

View File

@@ -12,14 +12,14 @@
<table>
<tr>
<th>Account ID</th>
<th>Domains</th>
<th>Services</th>
<th>Age</th>
<th>Status</th>
</tr>
{{range .Clients}}
<tr>
<td><a href="/debug/clients/{{.AccountID}}/tools">{{.AccountID}}</a></td>
<td>{{.Domains}}</td>
<td>{{.Services}}</td>
<td>{{.Age}}</td>
<td>{{.Status}}</td>
</tr>

View File

@@ -27,19 +27,19 @@
<ul>{{range .CertsFailedDomains}}<li>{{.Domain}}: {{.Error}}</li>{{end}}</ul>
</details>
{{end}}
<h2>Clients ({{.ClientCount}}) | Domains ({{.TotalDomains}})</h2>
<h2>Clients ({{.ClientCount}}) | Services ({{.TotalServices}})</h2>
{{if .Clients}}
<table>
<tr>
<th>Account ID</th>
<th>Domains</th>
<th>Services</th>
<th>Age</th>
<th>Status</th>
</tr>
{{range .Clients}}
<tr>
<td><a href="/debug/clients/{{.AccountID}}/tools">{{.AccountID}}</a></td>
<td>{{.Domains}}</td>
<td>{{.Services}}</td>
<td>{{.Age}}</td>
<td>{{.Status}}</td>
</tr>