Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ require (
github.com/fatih/structs v1.1.0
github.com/goccy/go-yaml v1.19.2
github.com/guptarohit/asciigraph v0.9.0
github.com/hetznercloud/hcloud-go/v2 v2.38.0
github.com/hetznercloud/hcloud-go/v2 v2.38.1-0.20260424132332-275506f01f2b
github.com/jedib0t/go-pretty/v6 v6.7.10
github.com/spf13/cast v1.10.0
github.com/spf13/cobra v1.10.2
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/guptarohit/asciigraph v0.9.0 h1:MvCSRRVkT2XvU1IO6n92o7l7zqx1DiFaoszOUZQztbY=
github.com/guptarohit/asciigraph v0.9.0/go.mod h1:dYl5wwK4gNsnFf9Zp+l06rFiDZ5YtXM6x7SRWZ3KGag=
github.com/hetznercloud/hcloud-go/v2 v2.38.0 h1:bJL4O5Zd8iF+vDRzeAbmsMcxKhn/sf/HUtu2jl/bFl0=
github.com/hetznercloud/hcloud-go/v2 v2.38.0/go.mod h1:BHmbGdh59t0CazoUEFvbdp6PyV+gwnF0fl9D4Bdgqq0=
github.com/hetznercloud/hcloud-go/v2 v2.38.1-0.20260424132332-275506f01f2b h1:HFh1KoZ5dwXvBZbskDdPhlhiV/ELp0jd9fPc4OpyQVY=
github.com/hetznercloud/hcloud-go/v2 v2.38.1-0.20260424132332-275506f01f2b/go.mod h1:BHmbGdh59t0CazoUEFvbdp6PyV+gwnF0fl9D4Bdgqq0=
github.com/iancoleman/orderedmap v0.3.0 h1:5cbR2grmZR/DiVt+VJopEhtVs9YGInGIxAoMJn+Ichc=
github.com/iancoleman/orderedmap v0.3.0/go.mod h1:XuLcCUkdL5owUCQeF2Ue9uuw1EptkJDkXXS7VoV7XGE=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
Expand Down
6 changes: 6 additions & 0 deletions internal/cmd/loadbalancer/add_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ var AddServiceCmd = base.Cmd{
cmd.Flags().Duration("http-cookie-lifetime", 0, "Sticky Sessions: Lifetime of the cookie")
cmd.Flags().StringSlice("http-certificates", []string{}, "IDs or names of Certificates which should be attached to this Load Balancer")
cmd.Flags().Bool("http-redirect-http", false, "Redirect all traffic on port 80 to port 443 (true, false)")
cmd.Flags().Duration("http-timeout-idle", 0, "Idle timeout for HTTP connections (30s-300s)")

cmd.Flags().String("health-check-protocol", "", "The protocol the health check is performed over")
cmd.Flags().Int("health-check-port", 0, "The port the health check is performed over")
Expand Down Expand Up @@ -91,6 +92,7 @@ var AddServiceCmd = base.Cmd{
httpCookieName, _ := cmd.Flags().GetString("http-cookie-name")
httpCookieLifetime, _ := cmd.Flags().GetDuration("http-cookie-lifetime")
httpRedirect, _ := cmd.Flags().GetBool("http-redirect-http")
httpTimeoutIdle, _ := cmd.Flags().GetDuration("http-timeout-idle")

loadBalancer, _, err := s.Client().LoadBalancer().Get(s, idOrName)
if err != nil {
Expand Down Expand Up @@ -123,6 +125,10 @@ var AddServiceCmd = base.Cmd{
if httpCookieLifetime != 0 {
opts.HTTP.CookieLifetime = &httpCookieLifetime
}
if httpTimeoutIdle != 0 {
opts.HTTP.TimeoutIdle = &httpTimeoutIdle
}

for _, idOrName := range httpCertificates {
cert, _, err := s.Client().Certificate().Get(s, idOrName)
if err != nil {
Expand Down
3 changes: 2 additions & 1 deletion internal/cmd/loadbalancer/add_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func TestAddService(t *testing.T) {
HTTP: &hcloud.LoadBalancerAddServiceOptsHTTP{
StickySessions: hcloud.Ptr(false),
RedirectHTTP: hcloud.Ptr(false),
TimeoutIdle: hcloud.Ptr(60 * time.Second),
},
Proxyprotocol: hcloud.Ptr(false),
}).
Expand All @@ -39,7 +40,7 @@ func TestAddService(t *testing.T) {
WaitForActions(gomock.Any(), gomock.Any(), &hcloud.Action{ID: 123}).
Return(nil)

out, errOut, err := fx.Run(cmd, []string{"123", "--protocol", "http", "--listen-port", "80", "--destination-port", "8080"})
out, errOut, err := fx.Run(cmd, []string{"123", "--protocol", "http", "--listen-port", "80", "--destination-port", "8080", "--http-timeout-idle", "60s"})

expOut := "Service was added to Load Balancer 123\n"

Expand Down
1 change: 1 addition & 0 deletions internal/cmd/loadbalancer/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ var DescribeCmd = base.DescribeCmd[*hcloud.LoadBalancer]{
fmt.Fprintf(out, " Destination Port:\t%d\n", service.DestinationPort)
fmt.Fprintf(out, " Proxy Protocol:\t%s\n", util.YesNo(service.Proxyprotocol))
if service.Protocol != hcloud.LoadBalancerServiceProtocolTCP {
fmt.Fprintf(out, " Timeout Idle:\t%vs\n", service.HTTP.TimeoutIdle.Seconds())
fmt.Fprintf(out, " Sticky Sessions:\t%s\n", util.YesNo(service.HTTP.StickySessions))
if service.HTTP.StickySessions {
fmt.Fprintf(out, " Sticky Cookie Name:\t%s\n", service.HTTP.CookieName)
Expand Down
48 changes: 47 additions & 1 deletion internal/cmd/loadbalancer/describe_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,35 @@ func TestDescribe(t *testing.T) {
Algorithm: hcloud.LoadBalancerAlgorithm{
Type: hcloud.LoadBalancerAlgorithmTypeLeastConnections,
},
Services: []hcloud.LoadBalancerService{
{
Protocol: hcloud.LoadBalancerServiceProtocolHTTP,
ListenPort: 80,
DestinationPort: 8080,
Proxyprotocol: true,
HTTP: hcloud.LoadBalancerServiceHTTP{
TimeoutIdle: 60 * time.Second,
StickySessions: true,
CookieName: "my-cookie",
CookieLifetime: 5 * time.Minute,
RedirectHTTP: true,
},
HealthCheck: hcloud.LoadBalancerServiceHealthCheck{
Protocol: hcloud.LoadBalancerServiceProtocolHTTP,
Port: 8080,
Timeout: 10 * time.Second,
Interval: 15 * time.Second,
Retries: 3,
HTTP: &hcloud.LoadBalancerServiceHealthCheckHTTP{
Domain: "example.com",
Path: "/health",
Response: "OK",
StatusCodes: []string{"200", "201"},
TLS: true,
},
},
},
},
IncludedTraffic: 20 * util.Tebibyte,
IngoingTraffic: 10 * util.Tebibyte,
OutgoingTraffic: 10 * util.Tebibyte,
Expand Down Expand Up @@ -87,7 +116,24 @@ Load Balancer Type:
Max assigned Certificates: 10

Services:
No services
- Protocol: http
Listen Port: 80
Destination Port: 8080
Proxy Protocol: yes
Timeout Idle: 60s
Sticky Sessions: yes
Sticky Cookie Name: my-cookie
Sticky Cookie Lifetime: 300s
Health Check:
Protocol: http
Timeout: 10s
Interval: every 15s
Retries: 3
HTTP Domain: example.com
HTTP Path: /health
Response: OK
TLS: yes
Status Codes: [200 201]

Targets:
No targets
Expand Down
5 changes: 5 additions & 0 deletions internal/cmd/loadbalancer/update_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ var UpdateServiceCmd = base.Cmd{
cmd.Flags().String("http-cookie-name", "", "Sticky Sessions: Cookie Name which will be set")
cmd.Flags().Duration("http-cookie-lifetime", 0, "Sticky Sessions: Lifetime of the cookie")
cmd.Flags().StringSlice("http-certificates", []string{}, "IDs or names of Certificates which should be attached to this Load Balancer")
cmd.Flags().Duration("http-timeout-idle", 0, "Idle timeout for HTTP connections (30s-300s)")

cmd.Flags().String("health-check-protocol", "", "The protocol the health check is performed over")
cmd.Flags().Int("health-check-port", 0, "The port the health check is performed over")
Expand Down Expand Up @@ -103,6 +104,10 @@ var UpdateServiceCmd = base.Cmd{
cookieLifetime, _ := cmd.Flags().GetDuration("http-cookie-lifetime")
opts.HTTP.CookieLifetime = &cookieLifetime
}
if cmd.Flag("http-timeout-idle").Changed {
timeoutIdle, _ := cmd.Flags().GetDuration("http-timeout-idle")
opts.HTTP.TimeoutIdle = &timeoutIdle
}
if cmd.Flag("http-certificates").Changed {
certificates, _ := cmd.Flags().GetStringSlice("http-certificates")
for _, idOrName := range certificates {
Expand Down
2 changes: 2 additions & 0 deletions internal/cmd/loadbalancer/update_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func TestUpdateService(t *testing.T) {
CookieName: hcloud.Ptr("test"),
CookieLifetime: hcloud.Ptr(10 * time.Minute),
Certificates: []*hcloud.Certificate{{ID: 1}},
TimeoutIdle: hcloud.Ptr(60 * time.Second),
},
HealthCheck: &hcloud.LoadBalancerUpdateServiceOptsHealthCheck{
Protocol: hcloud.LoadBalancerServiceProtocolTCP,
Expand Down Expand Up @@ -69,6 +70,7 @@ func TestUpdateService(t *testing.T) {
"--http-cookie-name", "test",
"--http-cookie-lifetime", "10m",
"--http-certificates", "1",
"--http-timeout-idle", "60s",
"--health-check-protocol", "tcp",
"--health-check-port", "8080",
"--health-check-interval", "10s",
Expand Down
Loading