From b36a85ac0454e67b7cd2da00bc3cfa5b26cd4aa8 Mon Sep 17 00:00:00 2001 From: kisfenyo Date: Mon, 5 Oct 2026 22:32:39 +0200 Subject: [PATCH] R-522: a disconnected tunnel is told on the dashboard row Since v0.292.0 (R-841) cloudflared's health check asks /ready, so a lost connection reads unhealthy; the cloudflared row now also carries the tag "Kivulrol nem erheto el" with a plain title, in hu+en. New parity case dashboard_tunnel_offline (born as a key). Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS --- controller/internal/i18n/locales/en.json | 2 + controller/internal/i18n/locales/hu.json | 2 + controller/internal/web/i18n_cases_a_test.go | 16 + controller/internal/web/inframeta_test.go | 27 + .../internal/web/templates/dashboard.html | 2 +- .../i18n_parity/dashboard_tunnel_offline.html | 594 ++++++++++++++++++ 6 files changed, 642 insertions(+), 1 deletion(-) create mode 100644 controller/internal/web/testdata/i18n_parity/dashboard_tunnel_offline.html diff --git a/controller/internal/i18n/locales/en.json b/controller/internal/i18n/locales/en.json index 728e7bf..e8ec504 100644 --- a/controller/internal/i18n/locales/en.json +++ b/controller/internal/i18n/locales/en.json @@ -904,6 +904,8 @@ "dashboard.telepites": "Install", "dashboard.telepitett_alkalmazasok": "Installed apps", "dashboard.url_nem_elerheto": "URL not reachable", + "dashboard.tunnel_offline": "Not reachable from outside", + "dashboard.tunnel_offline_title": "The secure internet connection is not connected now, so your apps cannot be reached from outside. Check the internet connection.", "dashboard.utolso_mentes": "Last backup:", "dashboard.vedett": "Protected", "dashboard.vezerlopult": "Dashboard", diff --git a/controller/internal/i18n/locales/hu.json b/controller/internal/i18n/locales/hu.json index 317fede..ac88841 100644 --- a/controller/internal/i18n/locales/hu.json +++ b/controller/internal/i18n/locales/hu.json @@ -899,6 +899,8 @@ "dashboard.telepites": "Telepítés", "dashboard.telepitett_alkalmazasok": "Telepített alkalmazások", "dashboard.url_nem_elerheto": "URL nem elérhető", + "dashboard.tunnel_offline": "Kívülről nem érhető el", + "dashboard.tunnel_offline_title": "A biztonságos internetkapcsolat most nem kapcsolódik, ezért az alkalmazásaid kívülről nem érhetők el. Ellenőrizd az internetkapcsolatot.", "dashboard.utolso_mentes": "Utolsó mentés:", "dashboard.vedett": "Védett", "dashboard.vezerlopult": "Vezérlőpult", diff --git a/controller/internal/web/i18n_cases_a_test.go b/controller/internal/web/i18n_cases_a_test.go index e6f45e8..e6f4915 100644 --- a/controller/internal/web/i18n_cases_a_test.go +++ b/controller/internal/web/i18n_cases_a_test.go @@ -67,6 +67,22 @@ func i18nCasesA() []i18nCase { d["Stacks"] = []stacks.Stack{} return d }}, + // R-522: a disconnected tunnel (cloudflared unhealthy) carries the „Kívülről nem érhető el" tag. Born as a + // key — its fixture was captured from this render, never from an unconverted template. + {"dashboard_tunnel_offline", "dashboard", func() map[string]interface{} { + d := i18nLayoutData("dashboard", "Vezérlőpult") + d["RunningCount"], d["StoppedCount"], d["TotalCount"] = 0, 0, 1 + d["SystemInfo"] = map[string]interface{}{"TotalMemMB": uint64(0)} + d["BackupEnabled"] = false + cf := i18nStack("cloudflared", "Cloudflared", stacks.StateUnhealthy, true) + cf.Protected = true + d["Stacks"] = []stacks.Stack{cf} + d["MissingStorage"] = map[string]string{} + d["NetworkStubs"] = map[string]string{} + d["NetworkWarnings"] = map[string]string{} + d["Subdomains"] = map[string]string{} + return d + }}, {"dashboard_diskcrit", "dashboard", func() map[string]interface{} { d := i18nLayoutData("dashboard", "Vezérlőpult") d["RunningCount"], d["StoppedCount"], d["TotalCount"] = 1, 0, 1 diff --git a/controller/internal/web/inframeta_test.go b/controller/internal/web/inframeta_test.go index 9fe4026..72bbffd 100644 --- a/controller/internal/web/inframeta_test.go +++ b/controller/internal/web/inframeta_test.go @@ -101,3 +101,30 @@ func TestInfraMetaFor_RegularAppIsNil(t *testing.T) { t.Error("filebrowser must be the Linked infra stack") } } + +// R-522: a disconnected tunnel (cloudflared's /ready health check failing → State unhealthy) is told +// on the dashboard row as „Kívülről nem érhető el", not left at a state the household reads as fine; +// a connected tunnel and an unhealthy OTHER infra stack carry no such tag. +func TestR522_TunnelOfflineTagOnlyForUnhealthyCloudflared(t *testing.T) { + data := infraPageData("dashboard") + html := renderBackupPage(t, "dashboard", data) + if strings.Contains(html, `data-tunnel-offline="true"`) { + t.Fatal("a connected tunnel must not carry the offline tag") + } + set := infraStacksTestSet() + set[0].State = stacks.StateUnhealthy // cloudflared + data["Stacks"] = set + html = renderBackupPage(t, "dashboard", data) + if !strings.Contains(html, `data-tunnel-offline="true"`) || !strings.Contains(html, "rhet") { + t.Fatal("an unhealthy cloudflared must carry the offline tag with its sentence") + } + if !strings.Contains(html, "Kívülről nem érhető el") { + t.Error("the tag text must be the Hungarian sentence") + } + set = infraStacksTestSet() + set[1].State = stacks.StateUnhealthy // traefik + data["Stacks"] = set + if strings.Contains(renderBackupPage(t, "dashboard", data), `data-tunnel-offline="true"`) { + t.Error("only cloudflared's state means the tunnel is down") + } +} diff --git a/controller/internal/web/templates/dashboard.html b/controller/internal/web/templates/dashboard.html index 8e2c963..7f592a4 100644 --- a/controller/internal/web/templates/dashboard.html +++ b/controller/internal/web/templates/dashboard.html @@ -192,7 +192,7 @@ {{if $.OOMKilled}}{{if index $.OOMKilled .Name}}{{T "dashboard.memoria_elfogyott"}}{{end}}{{end}} {{$ns := index $.NetworkStubs .Name}}{{if $ns}}{{T "dashboard.halozati_tarhely_hibas_az_alkalmazas"}}{{end}} {{$nw := index $.NetworkWarnings .Name}}{{if $nw}}{{T "dashboard.halozati_tarhely_nem_elerheto"}}{{end}} - {{if and .Deployed (routeUnpublished .State)}}{{T "dashboard.url_nem_elerheto"}}{{end}} + {{if and .Deployed (routeUnpublished .State)}}{{T "dashboard.url_nem_elerheto"}}{{end}}{{if and (eq .Name "cloudflared") (eq (printf "%s" .State) "unhealthy")}}{{T "dashboard.tunnel_offline"}}{{end}} {{if .Protected}} {{T "dashboard.vedett"}} diff --git a/controller/internal/web/testdata/i18n_parity/dashboard_tunnel_offline.html b/controller/internal/web/testdata/i18n_parity/dashboard_tunnel_offline.html new file mode 100644 index 0000000..bcb70e5 --- /dev/null +++ b/controller/internal/web/testdata/i18n_parity/dashboard_tunnel_offline.html @@ -0,0 +1,594 @@ + + + + + + + + Vezérlőpult — Felhom.eu + + + + + + + + +
+ + +
+ + +
+ + + + + + + + + + + + + + +
+

Lemezek állapota

+ +

Nincs adat

+ +
+ + + +

Telepített alkalmazások

+ +
+ + + + +
+ +
+ Cloudflare Tunnel + Biztonságos internetkapcsolat — a szerver portnyitás nélkül érhető el kívülről. +
+
+ + + Nem egészséges + + + + + + + URL nem elérhetőKívülről nem érhető el + + + Védett + + + + + + + +
+
+ + +
+ + + +
+ + + +