firewall.enabled (default true) is a cluster setting, applied live: the leader sends a Firewall message to every agent when it registers and when the setting or firewall_networks changes, and the agent (root) takes llmgw's nft table out or installs it. A control plane writes the state to /var/lib/llmgw/firewall.json, which llmgw-firewall-sync.path applies as root with `llmgw firewall sync`; server init and server add install the units, `llmgw firewall sync --install` on one set up before. node add and server add put no firewall on a machine while the setting is off. `llmgw wipe` removes llmgw from a machine after listing what goes and asking for its name: units, engines' processes, the nft table, /etc/llmgw, /var/lib/llmgw, the agent's state, the sudo grant, the CA from the trust store, keepalived's configuration when llmgw wrote it, and the users. --models, --store (Patroni member, etcd, or the local database) and --all take more. The console has it under Do. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
58 lines
1.7 KiB
Go
58 lines
1.7 KiB
Go
package agent
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"log/slog"
|
|
"strings"
|
|
"testing"
|
|
|
|
llmgwv1 "gitea.mynodes.xyz/ilker/llmgw/api/gen/llmgw/v1"
|
|
)
|
|
|
|
// fakeShell answers the firewall package's scripts and records what was
|
|
// installed or removed.
|
|
type fakeShell struct {
|
|
present bool
|
|
installed string
|
|
deleted bool
|
|
}
|
|
|
|
func (f *fakeShell) Run(_ context.Context, script string, stdin []byte) ([]byte, error) {
|
|
switch {
|
|
case strings.HasPrefix(script, "ip -o route get 10.0.0.140"):
|
|
return []byte("10.0.0.140 dev eth0 src 10.0.0.141 uid 0\n2: eth0 inet 10.0.0.141/24 brd 10.0.0.255 scope global eth0\n"), nil
|
|
case strings.HasPrefix(script, "sudo -n /usr/sbin/nft list table"):
|
|
if f.present {
|
|
return nil, nil
|
|
}
|
|
return nil, errors.New("no table")
|
|
case strings.Contains(script, "nft delete table") && !strings.Contains(script, "cat > "):
|
|
f.deleted, f.present = true, false
|
|
return nil, nil
|
|
case strings.HasPrefix(script, "sudo cat "):
|
|
return nil, nil
|
|
default:
|
|
f.installed, f.present = string(stdin), true
|
|
return []byte("changed\n"), nil
|
|
}
|
|
}
|
|
|
|
func TestANodeKeepsOrDropsItsFirewallAsTheClusterSays(t *testing.T) {
|
|
sh := &fakeShell{}
|
|
a := &Agent{log: slog.New(slog.DiscardHandler), fwRunner: sh, serverList: []string{"https://10.0.0.140:7443"}}
|
|
|
|
a.applyFirewall(&llmgwv1.Firewall{Enabled: true, Networks: []string{"192.168.5.0/24", "10.9.9.9"},
|
|
EnginePortsFrom: 20000, EnginePortsTo: 20999})
|
|
for _, want := range []string{"10.0.0.0/24", "192.168.5.0/24", "10.9.9.9/32", "20000-20999", "9100"} {
|
|
if !strings.Contains(sh.installed, want) {
|
|
t.Errorf("the rules lack %s:\n%s", want, sh.installed)
|
|
}
|
|
}
|
|
|
|
a.applyFirewall(&llmgwv1.Firewall{Enabled: false})
|
|
if !sh.deleted {
|
|
t.Error("turned off, the table stayed")
|
|
}
|
|
}
|