mirror of
https://github.com/prometheus/prometheus.git
synced 2024-12-28 15:09:39 -08:00
b6955bf1ca
Signed-off-by: Lukas Kämmerling <lukas.kaemmerling@hetzner-cloud.de>
934 lines
30 KiB
Go
934 lines
30 KiB
Go
package hcloud
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net"
|
|
"net/url"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/hetznercloud/hcloud-go/hcloud/schema"
|
|
)
|
|
|
|
// LoadBalancer represents a Load Balancer in the Hetzner Cloud.
|
|
type LoadBalancer struct {
|
|
ID int
|
|
Name string
|
|
PublicNet LoadBalancerPublicNet
|
|
PrivateNet []LoadBalancerPrivateNet
|
|
Location *Location
|
|
LoadBalancerType *LoadBalancerType
|
|
Algorithm LoadBalancerAlgorithm
|
|
Services []LoadBalancerService
|
|
Targets []LoadBalancerTarget
|
|
Protection LoadBalancerProtection
|
|
Labels map[string]string
|
|
Created time.Time
|
|
IncludedTraffic uint64
|
|
OutgoingTraffic uint64
|
|
IngoingTraffic uint64
|
|
}
|
|
|
|
// LoadBalancerPublicNet represents a Load Balancer's public network.
|
|
type LoadBalancerPublicNet struct {
|
|
Enabled bool
|
|
IPv4 LoadBalancerPublicNetIPv4
|
|
IPv6 LoadBalancerPublicNetIPv6
|
|
}
|
|
|
|
// LoadBalancerPublicNetIPv4 represents a Load Balancer's public IPv4 address.
|
|
type LoadBalancerPublicNetIPv4 struct {
|
|
IP net.IP
|
|
}
|
|
|
|
// LoadBalancerPublicNetIPv6 represents a Load Balancer's public IPv6 address.
|
|
type LoadBalancerPublicNetIPv6 struct {
|
|
IP net.IP
|
|
}
|
|
|
|
// LoadBalancerPrivateNet represents a Load Balancer's private network.
|
|
type LoadBalancerPrivateNet struct {
|
|
Network *Network
|
|
IP net.IP
|
|
}
|
|
|
|
// LoadBalancerService represents a Load Balancer service.
|
|
type LoadBalancerService struct {
|
|
Protocol LoadBalancerServiceProtocol
|
|
ListenPort int
|
|
DestinationPort int
|
|
Proxyprotocol bool
|
|
HTTP LoadBalancerServiceHTTP
|
|
HealthCheck LoadBalancerServiceHealthCheck
|
|
}
|
|
|
|
// LoadBalancerServiceHTTP stores configuration for a service using the HTTP protocol.
|
|
type LoadBalancerServiceHTTP struct {
|
|
CookieName string
|
|
CookieLifetime time.Duration
|
|
Certificates []*Certificate
|
|
RedirectHTTP bool
|
|
StickySessions bool
|
|
}
|
|
|
|
// LoadBalancerServiceHealthCheck stores configuration for a service health check.
|
|
type LoadBalancerServiceHealthCheck struct {
|
|
Protocol LoadBalancerServiceProtocol
|
|
Port int
|
|
Interval time.Duration
|
|
Timeout time.Duration
|
|
Retries int
|
|
HTTP *LoadBalancerServiceHealthCheckHTTP
|
|
}
|
|
|
|
// LoadBalancerServiceHealthCheckHTTP stores configuration for a service health check
|
|
// using the HTTP protocol.
|
|
type LoadBalancerServiceHealthCheckHTTP struct {
|
|
Domain string
|
|
Path string
|
|
Response string
|
|
StatusCodes []string
|
|
TLS bool
|
|
}
|
|
|
|
// LoadBalancerAlgorithmType specifies the algorithm type a Load Balancer
|
|
// uses for distributing requests.
|
|
type LoadBalancerAlgorithmType string
|
|
|
|
const (
|
|
// LoadBalancerAlgorithmTypeRoundRobin is an algorithm which distributes
|
|
// requests to targets in a round robin fashion.
|
|
LoadBalancerAlgorithmTypeRoundRobin LoadBalancerAlgorithmType = "round_robin"
|
|
// LoadBalancerAlgorithmTypeLeastConnections is an algorithm which distributes
|
|
// requests to targets with the least number of connections.
|
|
LoadBalancerAlgorithmTypeLeastConnections LoadBalancerAlgorithmType = "least_connections"
|
|
)
|
|
|
|
// LoadBalancerAlgorithm configures the algorithm a Load Balancer uses
|
|
// for distributing requests.
|
|
type LoadBalancerAlgorithm struct {
|
|
Type LoadBalancerAlgorithmType
|
|
}
|
|
|
|
// LoadBalancerTargetType specifies the type of a Load Balancer target.
|
|
type LoadBalancerTargetType string
|
|
|
|
const (
|
|
// LoadBalancerTargetTypeServer is a target type which points to a specific
|
|
// server.
|
|
LoadBalancerTargetTypeServer LoadBalancerTargetType = "server"
|
|
|
|
// LoadBalancerTargetTypeLabelSelector is a target type which selects the
|
|
// servers a Load Balancer points to using labels assigned to the servers.
|
|
LoadBalancerTargetTypeLabelSelector LoadBalancerTargetType = "label_selector"
|
|
|
|
// LoadBalancerTargetTypeIP is a target type which points to an IP.
|
|
LoadBalancerTargetTypeIP LoadBalancerTargetType = "ip"
|
|
)
|
|
|
|
// LoadBalancerServiceProtocol specifies the protocol of a Load Balancer service.
|
|
type LoadBalancerServiceProtocol string
|
|
|
|
const (
|
|
// LoadBalancerServiceProtocolTCP specifies a TCP service.
|
|
LoadBalancerServiceProtocolTCP LoadBalancerServiceProtocol = "tcp"
|
|
// LoadBalancerServiceProtocolHTTP specifies an HTTP service.
|
|
LoadBalancerServiceProtocolHTTP LoadBalancerServiceProtocol = "http"
|
|
// LoadBalancerServiceProtocolHTTPS specifies an HTTPS service.
|
|
LoadBalancerServiceProtocolHTTPS LoadBalancerServiceProtocol = "https"
|
|
)
|
|
|
|
// LoadBalancerTarget represents a Load Balancer target.
|
|
type LoadBalancerTarget struct {
|
|
Type LoadBalancerTargetType
|
|
Server *LoadBalancerTargetServer
|
|
LabelSelector *LoadBalancerTargetLabelSelector
|
|
IP *LoadBalancerTargetIP
|
|
HealthStatus []LoadBalancerTargetHealthStatus
|
|
Targets []LoadBalancerTarget
|
|
UsePrivateIP bool
|
|
}
|
|
|
|
// LoadBalancerTargetServer configures a Load Balancer target
|
|
// pointing at a specific server.
|
|
type LoadBalancerTargetServer struct {
|
|
Server *Server
|
|
}
|
|
|
|
// LoadBalancerTargetLabelSelector configures a Load Balancer target pointing
|
|
// at the servers matching the selector. This includes the target pointing at
|
|
// nothing, if no servers match the Selector.
|
|
type LoadBalancerTargetLabelSelector struct {
|
|
Selector string
|
|
}
|
|
|
|
// LoadBalancerTargetIP configures a Load Balancer target pointing to a Hetzner
|
|
// Online IP address.
|
|
type LoadBalancerTargetIP struct {
|
|
IP string
|
|
}
|
|
|
|
// LoadBalancerTargetHealthStatusStatus describes a target's health status.
|
|
type LoadBalancerTargetHealthStatusStatus string
|
|
|
|
const (
|
|
// LoadBalancerTargetHealthStatusStatusUnknown denotes that the health status is unknown.
|
|
LoadBalancerTargetHealthStatusStatusUnknown LoadBalancerTargetHealthStatusStatus = "unknown"
|
|
// LoadBalancerTargetHealthStatusStatusHealthy denotes a healthy target.
|
|
LoadBalancerTargetHealthStatusStatusHealthy LoadBalancerTargetHealthStatusStatus = "healthy"
|
|
// LoadBalancerTargetHealthStatusStatusUnhealthy denotes an unhealthy target.
|
|
LoadBalancerTargetHealthStatusStatusUnhealthy LoadBalancerTargetHealthStatusStatus = "unhealthy"
|
|
)
|
|
|
|
// LoadBalancerTargetHealthStatus describes a target's health for a specific service.
|
|
type LoadBalancerTargetHealthStatus struct {
|
|
ListenPort int
|
|
Status LoadBalancerTargetHealthStatusStatus
|
|
}
|
|
|
|
// LoadBalancerProtection represents the protection level of a Load Balancer.
|
|
type LoadBalancerProtection struct {
|
|
Delete bool
|
|
}
|
|
|
|
// LoadBalancerClient is a client for the Load Balancers API.
|
|
type LoadBalancerClient struct {
|
|
client *Client
|
|
}
|
|
|
|
// GetByID retrieves a Load Balancer by its ID. If the Load Balancer does not exist, nil is returned.
|
|
func (c *LoadBalancerClient) GetByID(ctx context.Context, id int) (*LoadBalancer, *Response, error) {
|
|
req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("/load_balancers/%d", id), nil)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var body schema.LoadBalancerGetResponse
|
|
resp, err := c.client.Do(req, &body)
|
|
if err != nil {
|
|
if IsError(err, ErrorCodeNotFound) {
|
|
return nil, resp, nil
|
|
}
|
|
return nil, nil, err
|
|
}
|
|
return LoadBalancerFromSchema(body.LoadBalancer), resp, nil
|
|
}
|
|
|
|
// GetByName retrieves a Load Balancer by its name. If the Load Balancer does not exist, nil is returned.
|
|
func (c *LoadBalancerClient) GetByName(ctx context.Context, name string) (*LoadBalancer, *Response, error) {
|
|
if name == "" {
|
|
return nil, nil, nil
|
|
}
|
|
LoadBalancer, response, err := c.List(ctx, LoadBalancerListOpts{Name: name})
|
|
if len(LoadBalancer) == 0 {
|
|
return nil, response, err
|
|
}
|
|
return LoadBalancer[0], response, err
|
|
}
|
|
|
|
// Get retrieves a Load Balancer by its ID if the input can be parsed as an integer, otherwise it
|
|
// retrieves a Load Balancer by its name. If the Load Balancer does not exist, nil is returned.
|
|
func (c *LoadBalancerClient) Get(ctx context.Context, idOrName string) (*LoadBalancer, *Response, error) {
|
|
if id, err := strconv.Atoi(idOrName); err == nil {
|
|
return c.GetByID(ctx, int(id))
|
|
}
|
|
return c.GetByName(ctx, idOrName)
|
|
}
|
|
|
|
// LoadBalancerListOpts specifies options for listing Load Balancers.
|
|
type LoadBalancerListOpts struct {
|
|
ListOpts
|
|
Name string
|
|
}
|
|
|
|
func (l LoadBalancerListOpts) values() url.Values {
|
|
vals := l.ListOpts.values()
|
|
if l.Name != "" {
|
|
vals.Add("name", l.Name)
|
|
}
|
|
return vals
|
|
}
|
|
|
|
// List returns a list of Load Balancers for a specific page.
|
|
//
|
|
// Please note that filters specified in opts are not taken into account
|
|
// when their value corresponds to their zero value or when they are empty.
|
|
func (c *LoadBalancerClient) List(ctx context.Context, opts LoadBalancerListOpts) ([]*LoadBalancer, *Response, error) {
|
|
path := "/load_balancers?" + opts.values().Encode()
|
|
req, err := c.client.NewRequest(ctx, "GET", path, nil)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var body schema.LoadBalancerListResponse
|
|
resp, err := c.client.Do(req, &body)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
LoadBalancers := make([]*LoadBalancer, 0, len(body.LoadBalancers))
|
|
for _, s := range body.LoadBalancers {
|
|
LoadBalancers = append(LoadBalancers, LoadBalancerFromSchema(s))
|
|
}
|
|
return LoadBalancers, resp, nil
|
|
}
|
|
|
|
// All returns all Load Balancers.
|
|
func (c *LoadBalancerClient) All(ctx context.Context) ([]*LoadBalancer, error) {
|
|
allLoadBalancer := []*LoadBalancer{}
|
|
|
|
opts := LoadBalancerListOpts{}
|
|
opts.PerPage = 50
|
|
|
|
_, err := c.client.all(func(page int) (*Response, error) {
|
|
opts.Page = page
|
|
LoadBalancer, resp, err := c.List(ctx, opts)
|
|
if err != nil {
|
|
return resp, err
|
|
}
|
|
allLoadBalancer = append(allLoadBalancer, LoadBalancer...)
|
|
return resp, nil
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return allLoadBalancer, nil
|
|
}
|
|
|
|
// AllWithOpts returns all Load Balancers for the given options.
|
|
func (c *LoadBalancerClient) AllWithOpts(ctx context.Context, opts LoadBalancerListOpts) ([]*LoadBalancer, error) {
|
|
var allLoadBalancers []*LoadBalancer
|
|
|
|
_, err := c.client.all(func(page int) (*Response, error) {
|
|
opts.Page = page
|
|
LoadBalancers, resp, err := c.List(ctx, opts)
|
|
if err != nil {
|
|
return resp, err
|
|
}
|
|
allLoadBalancers = append(allLoadBalancers, LoadBalancers...)
|
|
return resp, nil
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return allLoadBalancers, nil
|
|
}
|
|
|
|
// LoadBalancerUpdateOpts specifies options for updating a Load Balancer.
|
|
type LoadBalancerUpdateOpts struct {
|
|
Name string
|
|
Labels map[string]string
|
|
}
|
|
|
|
// Update updates a Load Balancer.
|
|
func (c *LoadBalancerClient) Update(ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerUpdateOpts) (*LoadBalancer, *Response, error) {
|
|
reqBody := schema.LoadBalancerUpdateRequest{}
|
|
if opts.Name != "" {
|
|
reqBody.Name = &opts.Name
|
|
}
|
|
if opts.Labels != nil {
|
|
reqBody.Labels = &opts.Labels
|
|
}
|
|
reqBodyData, err := json.Marshal(reqBody)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
path := fmt.Sprintf("/load_balancers/%d", loadBalancer.ID)
|
|
req, err := c.client.NewRequest(ctx, "PUT", path, bytes.NewReader(reqBodyData))
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
respBody := schema.LoadBalancerUpdateResponse{}
|
|
resp, err := c.client.Do(req, &respBody)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
return LoadBalancerFromSchema(respBody.LoadBalancer), resp, nil
|
|
}
|
|
|
|
// LoadBalancerCreateOpts specifies options for creating a new Load Balancer.
|
|
type LoadBalancerCreateOpts struct {
|
|
Name string
|
|
LoadBalancerType *LoadBalancerType
|
|
Algorithm *LoadBalancerAlgorithm
|
|
Location *Location
|
|
NetworkZone NetworkZone
|
|
Labels map[string]string
|
|
Targets []LoadBalancerCreateOptsTarget
|
|
Services []LoadBalancerCreateOptsService
|
|
PublicInterface *bool
|
|
Network *Network
|
|
}
|
|
|
|
// LoadBalancerCreateOptsTarget holds options for specifying a target
|
|
// when creating a new Load Balancer.
|
|
type LoadBalancerCreateOptsTarget struct {
|
|
Type LoadBalancerTargetType
|
|
Server LoadBalancerCreateOptsTargetServer
|
|
LabelSelector LoadBalancerCreateOptsTargetLabelSelector
|
|
IP LoadBalancerCreateOptsTargetIP
|
|
UsePrivateIP *bool
|
|
}
|
|
|
|
// LoadBalancerCreateOptsTargetServer holds options for specifying a server target
|
|
// when creating a new Load Balancer.
|
|
type LoadBalancerCreateOptsTargetServer struct {
|
|
Server *Server
|
|
}
|
|
|
|
// LoadBalancerCreateOptsTargetLabelSelector holds options for specifying a label selector target
|
|
// when creating a new Load Balancer.
|
|
type LoadBalancerCreateOptsTargetLabelSelector struct {
|
|
Selector string
|
|
}
|
|
|
|
// LoadBalancerCreateOptsTargetIP holds options for specifying an IP target
|
|
// when creating a new Load Balancer.
|
|
type LoadBalancerCreateOptsTargetIP struct {
|
|
IP string
|
|
}
|
|
|
|
// LoadBalancerCreateOptsService holds options for specifying a service
|
|
// when creating a new Load Balancer.
|
|
type LoadBalancerCreateOptsService struct {
|
|
Protocol LoadBalancerServiceProtocol
|
|
ListenPort *int
|
|
DestinationPort *int
|
|
Proxyprotocol *bool
|
|
HTTP *LoadBalancerCreateOptsServiceHTTP
|
|
HealthCheck *LoadBalancerCreateOptsServiceHealthCheck
|
|
}
|
|
|
|
// LoadBalancerCreateOptsServiceHTTP holds options for specifying an HTTP service
|
|
// when creating a new Load Balancer.
|
|
type LoadBalancerCreateOptsServiceHTTP struct {
|
|
CookieName *string
|
|
CookieLifetime *time.Duration
|
|
Certificates []*Certificate
|
|
RedirectHTTP *bool
|
|
StickySessions *bool
|
|
}
|
|
|
|
// LoadBalancerCreateOptsServiceHealthCheck holds options for specifying a service
|
|
// health check when creating a new Load Balancer.
|
|
type LoadBalancerCreateOptsServiceHealthCheck struct {
|
|
Protocol LoadBalancerServiceProtocol
|
|
Port *int
|
|
Interval *time.Duration
|
|
Timeout *time.Duration
|
|
Retries *int
|
|
HTTP *LoadBalancerCreateOptsServiceHealthCheckHTTP
|
|
}
|
|
|
|
// LoadBalancerCreateOptsServiceHealthCheckHTTP holds options for specifying a service
|
|
// HTTP health check when creating a new Load Balancer.
|
|
type LoadBalancerCreateOptsServiceHealthCheckHTTP struct {
|
|
Domain *string
|
|
Path *string
|
|
Response *string
|
|
StatusCodes []string
|
|
TLS *bool
|
|
}
|
|
|
|
// LoadBalancerCreateResult is the result of a create Load Balancer call.
|
|
type LoadBalancerCreateResult struct {
|
|
LoadBalancer *LoadBalancer
|
|
Action *Action
|
|
}
|
|
|
|
// Create creates a new Load Balancer.
|
|
func (c *LoadBalancerClient) Create(ctx context.Context, opts LoadBalancerCreateOpts) (LoadBalancerCreateResult, *Response, error) {
|
|
reqBody := loadBalancerCreateOptsToSchema(opts)
|
|
reqBodyData, err := json.Marshal(reqBody)
|
|
|
|
if err != nil {
|
|
return LoadBalancerCreateResult{}, nil, err
|
|
}
|
|
req, err := c.client.NewRequest(ctx, "POST", "/load_balancers", bytes.NewReader(reqBodyData))
|
|
if err != nil {
|
|
return LoadBalancerCreateResult{}, nil, err
|
|
}
|
|
|
|
respBody := schema.LoadBalancerCreateResponse{}
|
|
resp, err := c.client.Do(req, &respBody)
|
|
if err != nil {
|
|
return LoadBalancerCreateResult{}, resp, err
|
|
}
|
|
return LoadBalancerCreateResult{
|
|
LoadBalancer: LoadBalancerFromSchema(respBody.LoadBalancer),
|
|
Action: ActionFromSchema(respBody.Action),
|
|
}, resp, nil
|
|
}
|
|
|
|
// Delete deletes a Load Balancer.
|
|
func (c *LoadBalancerClient) Delete(ctx context.Context, loadBalancer *LoadBalancer) (*Response, error) {
|
|
req, err := c.client.NewRequest(ctx, "DELETE", fmt.Sprintf("/load_balancers/%d", loadBalancer.ID), nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return c.client.Do(req, nil)
|
|
}
|
|
|
|
func (c *LoadBalancerClient) addTarget(ctx context.Context, loadBalancer *LoadBalancer, reqBody schema.LoadBalancerActionAddTargetRequest) (*Action, *Response, error) {
|
|
reqBodyData, err := json.Marshal(reqBody)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
path := fmt.Sprintf("/load_balancers/%d/actions/add_target", loadBalancer.ID)
|
|
req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData))
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var respBody schema.LoadBalancerActionAddTargetResponse
|
|
resp, err := c.client.Do(req, &respBody)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
return ActionFromSchema(respBody.Action), resp, nil
|
|
}
|
|
|
|
func (c *LoadBalancerClient) removeTarget(ctx context.Context, loadBalancer *LoadBalancer, reqBody schema.LoadBalancerActionRemoveTargetRequest) (*Action, *Response, error) {
|
|
reqBodyData, err := json.Marshal(reqBody)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
path := fmt.Sprintf("/load_balancers/%d/actions/remove_target", loadBalancer.ID)
|
|
req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData))
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var respBody schema.LoadBalancerActionRemoveTargetResponse
|
|
resp, err := c.client.Do(req, &respBody)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
return ActionFromSchema(respBody.Action), resp, nil
|
|
}
|
|
|
|
// LoadBalancerAddServerTargetOpts specifies options for adding a server target
|
|
// to a Load Balancer.
|
|
type LoadBalancerAddServerTargetOpts struct {
|
|
Server *Server
|
|
UsePrivateIP *bool
|
|
}
|
|
|
|
// AddServerTarget adds a server target to a Load Balancer.
|
|
func (c *LoadBalancerClient) AddServerTarget(ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerAddServerTargetOpts) (*Action, *Response, error) {
|
|
reqBody := schema.LoadBalancerActionAddTargetRequest{
|
|
Type: string(LoadBalancerTargetTypeServer),
|
|
Server: &schema.LoadBalancerActionAddTargetRequestServer{
|
|
ID: opts.Server.ID,
|
|
},
|
|
UsePrivateIP: opts.UsePrivateIP,
|
|
}
|
|
return c.addTarget(ctx, loadBalancer, reqBody)
|
|
}
|
|
|
|
// RemoveServerTarget removes a server target from a Load Balancer.
|
|
func (c *LoadBalancerClient) RemoveServerTarget(ctx context.Context, loadBalancer *LoadBalancer, server *Server) (*Action, *Response, error) {
|
|
reqBody := schema.LoadBalancerActionRemoveTargetRequest{
|
|
Type: string(LoadBalancerTargetTypeServer),
|
|
Server: &schema.LoadBalancerActionRemoveTargetRequestServer{
|
|
ID: server.ID,
|
|
},
|
|
}
|
|
return c.removeTarget(ctx, loadBalancer, reqBody)
|
|
}
|
|
|
|
// LoadBalancerAddLabelSelectorTargetOpts specifies options for adding a label selector target
|
|
// to a Load Balancer.
|
|
type LoadBalancerAddLabelSelectorTargetOpts struct {
|
|
Selector string
|
|
UsePrivateIP *bool
|
|
}
|
|
|
|
// AddLabelSelectorTarget adds a label selector target to a Load Balancer.
|
|
func (c *LoadBalancerClient) AddLabelSelectorTarget(ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerAddLabelSelectorTargetOpts) (*Action, *Response, error) {
|
|
reqBody := schema.LoadBalancerActionAddTargetRequest{
|
|
Type: string(LoadBalancerTargetTypeLabelSelector),
|
|
LabelSelector: &schema.LoadBalancerActionAddTargetRequestLabelSelector{
|
|
Selector: opts.Selector,
|
|
},
|
|
UsePrivateIP: opts.UsePrivateIP,
|
|
}
|
|
return c.addTarget(ctx, loadBalancer, reqBody)
|
|
}
|
|
|
|
// RemoveLabelSelectorTarget removes a label selector target from a Load Balancer.
|
|
func (c *LoadBalancerClient) RemoveLabelSelectorTarget(ctx context.Context, loadBalancer *LoadBalancer, labelSelector string) (*Action, *Response, error) {
|
|
reqBody := schema.LoadBalancerActionRemoveTargetRequest{
|
|
Type: string(LoadBalancerTargetTypeLabelSelector),
|
|
LabelSelector: &schema.LoadBalancerActionRemoveTargetRequestLabelSelector{
|
|
Selector: labelSelector,
|
|
},
|
|
}
|
|
return c.removeTarget(ctx, loadBalancer, reqBody)
|
|
}
|
|
|
|
// LoadBalancerAddIPTargetOpts specifies options for adding an IP target to a
|
|
// Load Balancer.
|
|
type LoadBalancerAddIPTargetOpts struct {
|
|
IP net.IP
|
|
}
|
|
|
|
// AddIPTarget adds an IP target to a Load Balancer.
|
|
func (c *LoadBalancerClient) AddIPTarget(ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerAddIPTargetOpts) (*Action, *Response, error) {
|
|
reqBody := schema.LoadBalancerActionAddTargetRequest{
|
|
Type: string(LoadBalancerTargetTypeIP),
|
|
IP: &schema.LoadBalancerActionAddTargetRequestIP{IP: opts.IP.String()},
|
|
}
|
|
return c.addTarget(ctx, loadBalancer, reqBody)
|
|
}
|
|
|
|
// RemoveIPTarget removes an IP target from a Load Balancer.
|
|
func (c *LoadBalancerClient) RemoveIPTarget(ctx context.Context, loadBalancer *LoadBalancer, ip net.IP) (*Action, *Response, error) {
|
|
reqBody := schema.LoadBalancerActionRemoveTargetRequest{
|
|
Type: string(LoadBalancerTargetTypeIP),
|
|
IP: &schema.LoadBalancerActionRemoveTargetRequestIP{
|
|
IP: ip.String(),
|
|
},
|
|
}
|
|
return c.removeTarget(ctx, loadBalancer, reqBody)
|
|
}
|
|
|
|
// LoadBalancerAddServiceOpts specifies options for adding a service to a Load Balancer.
|
|
type LoadBalancerAddServiceOpts struct {
|
|
Protocol LoadBalancerServiceProtocol
|
|
ListenPort *int
|
|
DestinationPort *int
|
|
Proxyprotocol *bool
|
|
HTTP *LoadBalancerAddServiceOptsHTTP
|
|
HealthCheck *LoadBalancerAddServiceOptsHealthCheck
|
|
}
|
|
|
|
// LoadBalancerAddServiceOptsHTTP holds options for specifying an HTTP service
|
|
// when adding a service to a Load Balancer.
|
|
type LoadBalancerAddServiceOptsHTTP struct {
|
|
CookieName *string
|
|
CookieLifetime *time.Duration
|
|
Certificates []*Certificate
|
|
RedirectHTTP *bool
|
|
StickySessions *bool
|
|
}
|
|
|
|
// LoadBalancerAddServiceOptsHealthCheck holds options for specifying an health check
|
|
// when adding a service to a Load Balancer.
|
|
type LoadBalancerAddServiceOptsHealthCheck struct {
|
|
Protocol LoadBalancerServiceProtocol
|
|
Port *int
|
|
Interval *time.Duration
|
|
Timeout *time.Duration
|
|
Retries *int
|
|
HTTP *LoadBalancerAddServiceOptsHealthCheckHTTP
|
|
}
|
|
|
|
// LoadBalancerAddServiceOptsHealthCheckHTTP holds options for specifying an
|
|
// HTTP health check when adding a service to a Load Balancer.
|
|
type LoadBalancerAddServiceOptsHealthCheckHTTP struct {
|
|
Domain *string
|
|
Path *string
|
|
Response *string
|
|
StatusCodes []string
|
|
TLS *bool
|
|
}
|
|
|
|
// AddService adds a service to a Load Balancer.
|
|
func (c *LoadBalancerClient) AddService(ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerAddServiceOpts) (*Action, *Response, error) {
|
|
reqBody := loadBalancerAddServiceOptsToSchema(opts)
|
|
reqBodyData, err := json.Marshal(reqBody)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
path := fmt.Sprintf("/load_balancers/%d/actions/add_service", loadBalancer.ID)
|
|
req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData))
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var respBody schema.LoadBalancerActionAddServiceResponse
|
|
resp, err := c.client.Do(req, &respBody)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
return ActionFromSchema(respBody.Action), resp, nil
|
|
}
|
|
|
|
// LoadBalancerUpdateServiceOpts specifies options for updating a service.
|
|
type LoadBalancerUpdateServiceOpts struct {
|
|
Protocol LoadBalancerServiceProtocol
|
|
DestinationPort *int
|
|
Proxyprotocol *bool
|
|
HTTP *LoadBalancerUpdateServiceOptsHTTP
|
|
HealthCheck *LoadBalancerUpdateServiceOptsHealthCheck
|
|
}
|
|
|
|
// LoadBalancerUpdateServiceOptsHTTP specifies options for updating an HTTP(S) service.
|
|
type LoadBalancerUpdateServiceOptsHTTP struct {
|
|
CookieName *string
|
|
CookieLifetime *time.Duration
|
|
Certificates []*Certificate
|
|
RedirectHTTP *bool
|
|
StickySessions *bool
|
|
}
|
|
|
|
// LoadBalancerUpdateServiceOptsHealthCheck specifies options for updating
|
|
// a service's health check.
|
|
type LoadBalancerUpdateServiceOptsHealthCheck struct {
|
|
Protocol LoadBalancerServiceProtocol
|
|
Port *int
|
|
Interval *time.Duration
|
|
Timeout *time.Duration
|
|
Retries *int
|
|
HTTP *LoadBalancerUpdateServiceOptsHealthCheckHTTP
|
|
}
|
|
|
|
// LoadBalancerUpdateServiceOptsHealthCheckHTTP specifies options for updating
|
|
// the HTTP-specific settings of a service's health check.
|
|
type LoadBalancerUpdateServiceOptsHealthCheckHTTP struct {
|
|
Domain *string
|
|
Path *string
|
|
Response *string
|
|
StatusCodes []string
|
|
TLS *bool
|
|
}
|
|
|
|
// UpdateService updates a Load Balancer service.
|
|
func (c *LoadBalancerClient) UpdateService(ctx context.Context, loadBalancer *LoadBalancer, listenPort int, opts LoadBalancerUpdateServiceOpts) (*Action, *Response, error) {
|
|
reqBody := loadBalancerUpdateServiceOptsToSchema(opts)
|
|
reqBody.ListenPort = listenPort
|
|
reqBodyData, err := json.Marshal(reqBody)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
path := fmt.Sprintf("/load_balancers/%d/actions/update_service", loadBalancer.ID)
|
|
req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData))
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var respBody schema.LoadBalancerActionUpdateServiceResponse
|
|
resp, err := c.client.Do(req, &respBody)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
return ActionFromSchema(respBody.Action), resp, nil
|
|
}
|
|
|
|
// DeleteService deletes a Load Balancer service.
|
|
func (c *LoadBalancerClient) DeleteService(ctx context.Context, loadBalancer *LoadBalancer, listenPort int) (*Action, *Response, error) {
|
|
reqBody := schema.LoadBalancerDeleteServiceRequest{
|
|
ListenPort: listenPort,
|
|
}
|
|
reqBodyData, err := json.Marshal(reqBody)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
path := fmt.Sprintf("/load_balancers/%d/actions/delete_service", loadBalancer.ID)
|
|
req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData))
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
var respBody schema.LoadBalancerDeleteServiceResponse
|
|
resp, err := c.client.Do(req, &respBody)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
return ActionFromSchema(respBody.Action), resp, nil
|
|
}
|
|
|
|
// LoadBalancerChangeProtectionOpts specifies options for changing the resource protection level of a Load Balancer.
|
|
type LoadBalancerChangeProtectionOpts struct {
|
|
Delete *bool
|
|
}
|
|
|
|
// ChangeProtection changes the resource protection level of a Load Balancer.
|
|
func (c *LoadBalancerClient) ChangeProtection(ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerChangeProtectionOpts) (*Action, *Response, error) {
|
|
reqBody := schema.LoadBalancerActionChangeProtectionRequest{
|
|
Delete: opts.Delete,
|
|
}
|
|
reqBodyData, err := json.Marshal(reqBody)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
path := fmt.Sprintf("/load_balancers/%d/actions/change_protection", loadBalancer.ID)
|
|
req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData))
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
respBody := schema.LoadBalancerActionChangeProtectionResponse{}
|
|
resp, err := c.client.Do(req, &respBody)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
return ActionFromSchema(respBody.Action), resp, err
|
|
}
|
|
|
|
// LoadBalancerChangeAlgorithmOpts specifies options for changing the algorithm of a Load Balancer.
|
|
type LoadBalancerChangeAlgorithmOpts struct {
|
|
Type LoadBalancerAlgorithmType
|
|
}
|
|
|
|
// ChangeAlgorithm changes the algorithm of a Load Balancer.
|
|
func (c *LoadBalancerClient) ChangeAlgorithm(ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerChangeAlgorithmOpts) (*Action, *Response, error) {
|
|
reqBody := schema.LoadBalancerActionChangeAlgorithmRequest{
|
|
Type: string(opts.Type),
|
|
}
|
|
reqBodyData, err := json.Marshal(reqBody)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
path := fmt.Sprintf("/load_balancers/%d/actions/change_algorithm", loadBalancer.ID)
|
|
req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData))
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
respBody := schema.LoadBalancerActionChangeAlgorithmResponse{}
|
|
resp, err := c.client.Do(req, &respBody)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
return ActionFromSchema(respBody.Action), resp, err
|
|
}
|
|
|
|
// LoadBalancerAttachToNetworkOpts specifies options for attaching a Load Balancer to a network.
|
|
type LoadBalancerAttachToNetworkOpts struct {
|
|
Network *Network
|
|
IP net.IP
|
|
}
|
|
|
|
// AttachToNetwork attaches a Load Balancer to a network.
|
|
func (c *LoadBalancerClient) AttachToNetwork(ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerAttachToNetworkOpts) (*Action, *Response, error) {
|
|
reqBody := schema.LoadBalancerActionAttachToNetworkRequest{
|
|
Network: opts.Network.ID,
|
|
}
|
|
if opts.IP != nil {
|
|
reqBody.IP = String(opts.IP.String())
|
|
}
|
|
reqBodyData, err := json.Marshal(reqBody)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
path := fmt.Sprintf("/load_balancers/%d/actions/attach_to_network", loadBalancer.ID)
|
|
req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData))
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
respBody := schema.LoadBalancerActionAttachToNetworkResponse{}
|
|
resp, err := c.client.Do(req, &respBody)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
return ActionFromSchema(respBody.Action), resp, err
|
|
}
|
|
|
|
// LoadBalancerDetachFromNetworkOpts specifies options for detaching a Load Balancer from a network.
|
|
type LoadBalancerDetachFromNetworkOpts struct {
|
|
Network *Network
|
|
}
|
|
|
|
// DetachFromNetwork detaches a Load Balancer from a network.
|
|
func (c *LoadBalancerClient) DetachFromNetwork(ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerDetachFromNetworkOpts) (*Action, *Response, error) {
|
|
reqBody := schema.LoadBalancerActionDetachFromNetworkRequest{
|
|
Network: opts.Network.ID,
|
|
}
|
|
reqBodyData, err := json.Marshal(reqBody)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
path := fmt.Sprintf("/load_balancers/%d/actions/detach_from_network", loadBalancer.ID)
|
|
req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData))
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
respBody := schema.LoadBalancerActionDetachFromNetworkResponse{}
|
|
resp, err := c.client.Do(req, &respBody)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
return ActionFromSchema(respBody.Action), resp, err
|
|
}
|
|
|
|
// EnablePublicInterface enables the Load Balancer's public network interface.
|
|
func (c *LoadBalancerClient) EnablePublicInterface(ctx context.Context, loadBalancer *LoadBalancer) (*Action, *Response, error) {
|
|
path := fmt.Sprintf("/load_balancers/%d/actions/enable_public_interface", loadBalancer.ID)
|
|
req, err := c.client.NewRequest(ctx, "POST", path, nil)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
respBody := schema.LoadBalancerActionEnablePublicInterfaceResponse{}
|
|
resp, err := c.client.Do(req, &respBody)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
return ActionFromSchema(respBody.Action), resp, err
|
|
}
|
|
|
|
// DisablePublicInterface disables the Load Balancer's public network interface.
|
|
func (c *LoadBalancerClient) DisablePublicInterface(ctx context.Context, loadBalancer *LoadBalancer) (*Action, *Response, error) {
|
|
path := fmt.Sprintf("/load_balancers/%d/actions/disable_public_interface", loadBalancer.ID)
|
|
req, err := c.client.NewRequest(ctx, "POST", path, nil)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
respBody := schema.LoadBalancerActionDisablePublicInterfaceResponse{}
|
|
resp, err := c.client.Do(req, &respBody)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
return ActionFromSchema(respBody.Action), resp, err
|
|
}
|
|
|
|
// LoadBalancerChangeTypeOpts specifies options for changing a Load Balancer's type.
|
|
type LoadBalancerChangeTypeOpts struct {
|
|
LoadBalancerType *LoadBalancerType // new Load Balancer type
|
|
}
|
|
|
|
// ChangeType changes a Load Balancer's type.
|
|
func (c *LoadBalancerClient) ChangeType(ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerChangeTypeOpts) (*Action, *Response, error) {
|
|
reqBody := schema.LoadBalancerActionChangeTypeRequest{}
|
|
if opts.LoadBalancerType.ID != 0 {
|
|
reqBody.LoadBalancerType = opts.LoadBalancerType.ID
|
|
} else {
|
|
reqBody.LoadBalancerType = opts.LoadBalancerType.Name
|
|
}
|
|
reqBodyData, err := json.Marshal(reqBody)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
path := fmt.Sprintf("/load_balancers/%d/actions/change_type", loadBalancer.ID)
|
|
req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData))
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
respBody := schema.LoadBalancerActionChangeTypeResponse{}
|
|
resp, err := c.client.Do(req, &respBody)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
return ActionFromSchema(respBody.Action), resp, nil
|
|
}
|