Accountant: Inventar, where, Checkmk, Abrechnung
This commit is contained in:
1 parent
9f16148cde
commit
dd93277750
59 files changed
+7522
-113
No files matched your search
@@ -0,0 +1,136 @@
|
||||
package accountant
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"sultan/pkg/ledger"
|
||||
)
|
||||
|
||||
// whereLedger: zwei Payees; kunde.de zieht von webdocker07 nach webdocker11 um,
|
||||
// olat.kunde.de verschwindet, andere.de liegt auf dem zweiten Payee.
|
||||
func whereLedger(t *testing.T) (*ledger.Ledger, func(time.Time)) {
|
||||
t.Helper()
|
||||
l, err := ledger.Open(ctx, filepath.Join(t.TempDir(), "accountant.db"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(func() { l.Close() })
|
||||
now := time.Date(2026, 9, 1, 10, 0, 0, 0, time.UTC)
|
||||
setNow := func(at time.Time) { now = at }
|
||||
l.SetClock(func() time.Time { return now })
|
||||
for _, id := range []string{"webproxy11", "webproxy12"} {
|
||||
l.AddInvite(ctx, "tok-"+id, id, now.Add(time.Hour))
|
||||
if _, err := l.Enroll(ctx, "tok-"+id, ledger.Payee{Hostname: id + ".lan", PublicKey: "key-" + id}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
return l, setNow
|
||||
}
|
||||
|
||||
func save(t *testing.T, l *ledger.Ledger, payeeID string, rep Report) {
|
||||
t.Helper()
|
||||
if err := StoreReport(ctx, l, payeeID, rep); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func whereReport(node string, routes ...ReportRoute) Report {
|
||||
return Report{
|
||||
GeneratedAt: time.Now(),
|
||||
Tenants: []ReportTenant{{ID: "kunde", Name: "Kunde A"}, {ID: "andere", Name: "Andere GmbH"}},
|
||||
Nodes: []ReportNode{{ID: node, Tenant: "kunde", FQDN: node + ".lan.r25dc.de", Connected: true, OS: "Debian 13",
|
||||
DockerVersion: "29.8.2", NetBirdIP: "100.92.10.4"}},
|
||||
Routes: routes,
|
||||
}
|
||||
}
|
||||
|
||||
func route(tenant, node, router string, hosts ...string) ReportRoute {
|
||||
return ReportRoute{Tenant: tenant, Node: node, Router: router, Protocol: "http", Hosts: hosts, Workload: "kunde-a-" + router + "-1",
|
||||
Backend: "http://10.0.0.11:8081", BackendFQDN: node + ".lan.r25dc.de:8081", Active: true,
|
||||
ComposeDir: "/srv/kunde-a", ComposeProject: "kunde-a", State: "running", Health: "healthy"}
|
||||
}
|
||||
|
||||
func TestWhere(t *testing.T) {
|
||||
l, setNow := whereLedger(t)
|
||||
t1 := time.Date(2026, 9, 1, 10, 0, 0, 0, time.UTC)
|
||||
save(t, l, "webproxy11", whereReport("webdocker07", route("kunde", "webdocker07", "wp", "kunde.de"),
|
||||
route("kunde", "webdocker07", "olat", "olat.kunde.de")))
|
||||
andere := whereReport("n9", route("andere", "n9", "web", "andere.de"))
|
||||
save(t, l, "webproxy12", andere)
|
||||
|
||||
t2 := t1.Add(30 * 24 * time.Hour)
|
||||
setNow(t2)
|
||||
save(t, l, "webproxy11", whereReport("webdocker11", route("kunde", "webdocker11", "wp", "kunde.de", "www.kunde.de")))
|
||||
|
||||
res, err := Where(ctx, l, "kunde.de")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(res.Current) != 1 {
|
||||
t.Fatalf("aktuell: %+v", res.Current)
|
||||
}
|
||||
h := res.Current[0]
|
||||
if h.Payee != "webproxy11" || h.Route.Router != "wp" || h.TenantName != "Kunde A" || h.Node.FQDN != "webdocker11.lan.r25dc.de" ||
|
||||
h.Route.ComposeDir != "/srv/kunde-a" || !h.Since.Equal(t2) || !h.ReportAt.Equal(t2) {
|
||||
t.Errorf("Treffer: %+v", h)
|
||||
}
|
||||
if len(h.Previous) != 1 || h.Previous[0].Node != "webdocker07" || !h.Previous[0].Ended.Equal(t2) || !h.Previous[0].FirstSeen.Equal(t1) {
|
||||
t.Errorf("vorher: %+v", h.Previous)
|
||||
}
|
||||
// olat.kunde.de passt (Teiltreffer "kunde.de"), ist aber verschwunden.
|
||||
if len(res.Gone) != 1 || res.Gone[0].Router != "olat" || !res.Gone[0].Ended.Equal(t2) {
|
||||
t.Errorf("verschwunden: %+v", res.Gone)
|
||||
}
|
||||
|
||||
// Teiltreffer und Mandant.
|
||||
if r, _ := Where(ctx, l, "WWW.Kunde"); len(r.Current) != 1 {
|
||||
t.Errorf("Teiltreffer: %+v", r)
|
||||
}
|
||||
if r, _ := Where(ctx, l, "andere"); len(r.Current) != 1 || r.Current[0].Payee != "webproxy12" {
|
||||
t.Errorf("Mandant: %+v", r)
|
||||
}
|
||||
if r, _ := Where(ctx, l, "gibts-nicht.de"); len(r.Current)+len(r.Gone) != 0 {
|
||||
t.Errorf("kein Treffer erwartet: %+v", r)
|
||||
}
|
||||
if r, _ := Where(ctx, l, "_"); len(r.Current)+len(r.Gone) != 0 {
|
||||
t.Errorf("Platzhalter wirkt als Joker: %+v", r)
|
||||
}
|
||||
}
|
||||
|
||||
// Der Bericht geht über den Endpunkt in die Historie ein.
|
||||
func TestReport_RecordsHistory(t *testing.T) {
|
||||
a := start(t, "")
|
||||
key := enrolledPayee(t, a, "webproxy11")
|
||||
body, _ := json.Marshal(whereReport("webdocker11", route("kunde", "webdocker11", "wp", "kunde.de")))
|
||||
postReport(t, a, key, body)
|
||||
l, _ := ledger.Open(ctx, filepath.Join(a.DataDir(), "accountant.db"))
|
||||
defer l.Close()
|
||||
spans, err := l.RouteHistory(ctx, ledger.HistoryFilter{})
|
||||
if err != nil || len(spans) != 1 || spans[0].Payee != "webproxy11" || spans[0].BackendFQDN != "webdocker11.lan.r25dc.de:8081" {
|
||||
t.Errorf("Historie: %+v, %v", spans, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRoutes(t *testing.T) {
|
||||
l, _ := whereLedger(t)
|
||||
save(t, l, "webproxy11", whereReport("webdocker11", route("kunde", "webdocker11", "wp", "kunde.de"),
|
||||
route("kunde", "webdocker11", "olat", "olat.kunde.de")))
|
||||
save(t, l, "webproxy12", whereReport("n9", route("andere", "n9", "web", "andere.de")))
|
||||
|
||||
all, err := Routes(ctx, l, RoutesFilter{})
|
||||
if err != nil || len(all) != 3 {
|
||||
t.Fatalf("Routes = %+v, %v", all, err)
|
||||
}
|
||||
if all[0].Route.Hosts[0] != "andere.de" || all[2].Route.Hosts[0] != "olat.kunde.de" {
|
||||
t.Errorf("nicht nach Host sortiert: %v %v %v", all[0].Route.Hosts, all[1].Route.Hosts, all[2].Route.Hosts)
|
||||
}
|
||||
if r, _ := Routes(ctx, l, RoutesFilter{Tenant: "kunde"}); len(r) != 2 {
|
||||
t.Errorf("--tenant: %+v", r)
|
||||
}
|
||||
if r, _ := Routes(ctx, l, RoutesFilter{Payee: "webproxy12"}); len(r) != 1 || r[0].Since.IsZero() {
|
||||
t.Errorf("--payee: %+v", r)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user