fix(infra): improve hetzner client error handling and naming

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-03-29 15:21:02 +00:00
parent 1f0372e15b
commit 21df4909b0
4 changed files with 32 additions and 17 deletions

View file

@ -7,8 +7,8 @@ import (
"time"
"forge.lthn.ai/core/cli/pkg/cli"
coreerr "forge.lthn.ai/core/go-log"
"forge.lthn.ai/core/go-infra"
coreerr "forge.lthn.ai/core/go-log"
)
var lbCmd = &cli.Command{
@ -74,7 +74,7 @@ func runLBStatus(cmd *cli.Command, args []string) error {
cli.Print("\n Services:\n")
for _, s := range lb.Services {
cli.Print(" %s :%d -> :%d proxy_protocol=%v\n",
s.Protocol, s.ListenPort, s.DestinationPort, s.Proxyprotocol)
s.Protocol, s.ListenPort, s.DestinationPort, s.ProxyProtocol)
}
}

View file

@ -6,8 +6,8 @@ import (
"time"
"forge.lthn.ai/core/cli/pkg/cli"
coreerr "forge.lthn.ai/core/go-log"
"forge.lthn.ai/core/go-infra"
coreerr "forge.lthn.ai/core/go-log"
)
var setupCmd = &cli.Command{
@ -190,7 +190,7 @@ func stepLoadBalancer(ctx context.Context, cfg *infra.Config) error {
Protocol: l.Protocol,
ListenPort: l.Frontend,
DestinationPort: l.Backend,
Proxyprotocol: l.ProxyProtocol,
ProxyProtocol: l.ProxyProtocol,
HealthCheck: &infra.HCloudLBHealthCheck{
Protocol: cfg.LoadBalancer.Health.Protocol,
Port: l.Backend,

View file

@ -1,11 +1,11 @@
package infra
import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"
"strings"
coreerr "forge.lthn.ai/core/go-log"
)
@ -108,7 +108,7 @@ type HCloudLBService struct {
Protocol string `json:"protocol"`
ListenPort int `json:"listen_port"`
DestinationPort int `json:"destination_port"`
Proxyprotocol bool `json:"proxyprotocol"`
ProxyProtocol bool `json:"proxyprotocol"`
HTTP *HCloudLBHTTP `json:"http,omitempty"`
HealthCheck *HCloudLBHealthCheck `json:"health_check,omitempty"`
}
@ -231,36 +231,48 @@ func (c *HCloudClient) DeleteLoadBalancer(ctx context.Context, id int) error {
// CreateSnapshot creates a server snapshot.
func (c *HCloudClient) CreateSnapshot(ctx context.Context, serverID int, description string) error {
body, _ := json.Marshal(map[string]string{
body, err := json.Marshal(map[string]string{
"description": description,
"type": "snapshot",
})
if err != nil {
return coreerr.E("HCloudClient.CreateSnapshot", "marshal request", err)
}
return c.post(ctx, fmt.Sprintf("/servers/%d/actions/create_image", serverID), body, nil)
}
func (c *HCloudClient) get(ctx context.Context, path string, result any) error {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, c.baseURL+path, nil)
if err != nil {
return err
return coreerr.E("HCloudClient.get", "build request", err)
}
return c.do(req, result)
if err := c.do(req, result); err != nil {
return coreerr.E("HCloudClient.get", "execute request", err)
}
return nil
}
func (c *HCloudClient) post(ctx context.Context, path string, body []byte, result any) error {
req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.baseURL+path, strings.NewReader(string(body)))
req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.baseURL+path, bytes.NewReader(body))
if err != nil {
return err
return coreerr.E("HCloudClient.post", "build request", err)
}
req.Header.Set("Content-Type", "application/json")
return c.do(req, result)
if err := c.do(req, result); err != nil {
return coreerr.E("HCloudClient.post", "execute request", err)
}
return nil
}
func (c *HCloudClient) delete(ctx context.Context, path string) error {
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, c.baseURL+path, nil)
if err != nil {
return err
return coreerr.E("HCloudClient.delete", "build request", err)
}
return c.do(req, nil)
if err := c.do(req, nil); err != nil {
return coreerr.E("HCloudClient.delete", "execute request", err)
}
return nil
}
func (c *HCloudClient) do(req *http.Request, result any) error {
@ -334,7 +346,10 @@ func (c *HRobotClient) GetServer(ctx context.Context, ip string) (*HRobotServer,
func (c *HRobotClient) get(ctx context.Context, path string, result any) error {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, c.baseURL+path, nil)
if err != nil {
return err
return coreerr.E("HRobotClient.get", "build request", err)
}
return c.api.Do(req, result)
if err := c.api.Do(req, result); err != nil {
return coreerr.E("HRobotClient.get", "execute request", err)
}
return nil
}

View file

@ -441,7 +441,7 @@ func TestHCloudLoadBalancer_JSON_Good(t *testing.T) {
assert.Equal(t, "round_robin", lb.Algorithm.Type)
require.Len(t, lb.Services, 1)
assert.Equal(t, 443, lb.Services[0].ListenPort)
assert.True(t, lb.Services[0].Proxyprotocol)
assert.True(t, lb.Services[0].ProxyProtocol)
require.Len(t, lb.Targets, 1)
assert.Equal(t, "ip", lb.Targets[0].Type)
assert.Equal(t, "10.0.0.1", lb.Targets[0].IP.IP)