96 lines
1.9 KiB
Go
96 lines
1.9 KiB
Go
package host
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
|
|
"git.wzray.com/homelab/hivemind/internal/config"
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
type TraefikListener interface {
|
|
OnTraefikUpdate(traefikResponse)
|
|
}
|
|
|
|
type TraefikGateway struct {
|
|
client *http.Client
|
|
server *http.Server
|
|
listener TraefikListener
|
|
address url.URL
|
|
domain string
|
|
}
|
|
|
|
func NewTraefikGateway(cfg config.HostConfig, listener TraefikListener) *TraefikGateway {
|
|
mux := http.NewServeMux()
|
|
gw := &TraefikGateway{
|
|
client: &http.Client{},
|
|
|
|
server: &http.Server{
|
|
Addr: cfg.ListenAddress,
|
|
Handler: mux,
|
|
},
|
|
listener: listener,
|
|
address: url.URL{
|
|
Scheme: "http",
|
|
Host: cfg.LocalAddress,
|
|
},
|
|
domain: cfg.Domain,
|
|
}
|
|
|
|
mux.HandleFunc("/callback", gw.onCallback)
|
|
return gw
|
|
}
|
|
|
|
func (g *TraefikGateway) Listen() error {
|
|
return g.server.ListenAndServe()
|
|
}
|
|
|
|
func (g *TraefikGateway) Shutdown(ctx context.Context) error {
|
|
return g.server.Shutdown(ctx)
|
|
}
|
|
|
|
func (g *TraefikGateway) GetRawData() (*traefikResponse, error) {
|
|
var raw TraefikRawResponse
|
|
|
|
url := g.address
|
|
url.Path = "/api/rawdata"
|
|
|
|
req := http.Request{
|
|
Method: http.MethodGet,
|
|
URL: &url,
|
|
}
|
|
|
|
req.Host = g.domain
|
|
|
|
r, err := g.client.Do(&req)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("make request: %w", err)
|
|
}
|
|
defer r.Body.Close()
|
|
|
|
if err := json.NewDecoder(r.Body).Decode(&raw); err != nil {
|
|
return nil, fmt.Errorf("unmarshal body: %w", err)
|
|
}
|
|
|
|
out := parseTraefikResponse(raw)
|
|
return &out, nil
|
|
}
|
|
|
|
func (g *TraefikGateway) onCallback(w http.ResponseWriter, req *http.Request) {
|
|
var raw TraefikRawResponse
|
|
if err := json.NewDecoder(req.Body).Decode(&raw); err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
log.Err(err).Msg("unable to decode traefik callback data")
|
|
return
|
|
}
|
|
|
|
resp := parseTraefikResponse(raw)
|
|
if g.listener != nil {
|
|
g.listener.OnTraefikUpdate(resp)
|
|
}
|
|
|
|
w.Write([]byte("OK"))
|
|
}
|