1
0
Fork 0

refactor: move http api to a new transport layer

This commit is contained in:
Arthur K. 2026-01-23 09:56:01 +03:00
parent 476c4b056f
commit 0448f66ab2
Signed by: wzray
GPG key ID: B97F30FDC4636357
41 changed files with 822 additions and 390 deletions

View file

@ -8,22 +8,23 @@ import (
"strings"
"sync"
"git.wzray.com/homelab/hivemind/internal/app"
"git.wzray.com/homelab/hivemind/internal/config"
"git.wzray.com/homelab/hivemind/internal/state"
"git.wzray.com/homelab/hivemind/internal/transport"
"git.wzray.com/homelab/hivemind/internal/transport/dns"
"git.wzray.com/homelab/hivemind/internal/types"
"git.wzray.com/homelab/hivemind/internal/web/client"
"github.com/rs/zerolog/log"
)
const hostsDir = "/etc/hosts.d/"
type Role struct {
state *state.RuntimeState
state *app.State
config config.DnsConfig
group sync.WaitGroup
}
func New(state *state.RuntimeState, config config.DnsConfig) *Role {
func New(state *app.State, config config.DnsConfig) *Role {
r := &Role{
state: state,
config: config,
@ -32,28 +33,6 @@ func New(state *state.RuntimeState, config config.DnsConfig) *Role {
return r
}
func (r *Role) updateDnsmasq(filename string, data []byte) error {
if err := os.WriteFile(filename, data, 0644); err != nil {
return fmt.Errorf("write endpoint file %q: %w", filename, err)
}
if err := r.reload(); err != nil {
return fmt.Errorf("reload dnsmasq: %w", err)
}
return nil
}
func parseState(state types.HostState) (string, []byte) {
var builder strings.Builder
for _, d := range state.Domains {
builder.WriteString(fmt.Sprintf("%s %s\n", state.Address, d))
}
return hostsDir + state.Hostname, []byte(builder.String())
}
func (r *Role) OnStartup(ctx context.Context) error {
r.group.Go(func() {
r.syncFromRegistry()
@ -74,15 +53,46 @@ func (r *Role) OnStartup(ctx context.Context) error {
return nil
}
func (r *Role) OnShutdown() error {
r.group.Wait()
return nil
}
func (r *Role) RegisterHandlers(rg transport.Registrator) {
dns.Register(rg, r)
}
func (r *Role) Callback(state types.HostState) (bool, error) {
filename, data := parseState(state)
if err := r.updateDnsmasq(filename, data); err != nil {
return false, err
}
return true, nil
}
func (r *Role) updateDnsmasq(filename string, data []byte) error {
if err := os.WriteFile(filename, data, 0644); err != nil {
return fmt.Errorf("write endpoint file %q: %w", filename, err)
}
if err := r.reload(); err != nil {
return fmt.Errorf("reload dnsmasq: %w", err)
}
return nil
}
func (r *Role) syncFromRegistry() {
for _, n := range r.state.Registry.ByRole(types.HostRole) {
state, err := client.Get[types.HostState](n.Endpoint, types.PathHostDns)
state, err := r.state.Clients.Host.Dns(n.Endpoint)
if err != nil {
log.Warn().Str("name", n.Hostname).Err(err).Msg("unable to get host config")
continue
}
filename, data := parseState(*state)
filename, data := parseState(state)
if err := r.updateDnsmasq(filename, data); err != nil {
log.Warn().Str("name", n.Hostname).Err(err).Msg("unable to update dnsmasq")
continue
@ -90,11 +100,6 @@ func (r *Role) syncFromRegistry() {
}
}
func (r *Role) OnShutdown() error {
r.group.Wait()
return nil
}
func (r *Role) reload() error {
var err error
@ -107,16 +112,12 @@ func (r *Role) reload() error {
return err
}
func (r *Role) onCallback(state types.HostState) (bool, error) {
filename, data := parseState(state)
func parseState(state types.HostState) (string, []byte) {
var builder strings.Builder
if err := r.updateDnsmasq(filename, data); err != nil {
return false, err
for _, d := range state.Domains {
builder.WriteString(fmt.Sprintf("%s %s\n", state.Address, d))
}
return true, nil
}
func (r *Role) RegisterHandlers(rg types.Registrator) {
rg.Register(types.PostEndpoint(types.PathDnsCallback, r.onCallback))
return hostsDir + state.Hostname, []byte(builder.String())
}