Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/lb-api' into lb-api
Browse files Browse the repository at this point in the history
  • Loading branch information
ddymko committed Feb 20, 2020
2 parents baef7d2 + f351e4d commit 3b44a32
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 23 deletions.
95 changes: 75 additions & 20 deletions load_balancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package govultr

import (
"context"
"encoding/json"
"net/http"
"net/url"
"strconv"
Expand All @@ -24,6 +25,7 @@ type LoadBalancerService interface {
CreateForwardingRule(ctx context.Context, ID int, rule *ForwardingRule) (*ForwardingRule, error)
GetFullConfig(ctx context.Context, ID int) (*LBConfig, error)
HasSSL(ctx context.Context, ID int) (*struct{ SSLInfo bool `json:"has_ssl"` }, error)
Create(ctx context.Context, region int, genericInfo *GenericInfo, healthCheck *HealthCheck, rules []ForwardingRule) (*LoadBalancers, error)
}

// LoadBalancerHandler handles interaction with the server methods for the Vultr API
Expand All @@ -33,14 +35,14 @@ type LoadBalancerHandler struct {

// LoadBalancers represent a basic structure of a load balancer
type LoadBalancers struct {
ID int `json:"SUBID"`
DateCreated string `json:"date_created"`
RegionID int `json:"DCID"`
Location string
Label string
Status string
IPV4 string `json:"main_ipv4"`
IPV6 string `json:"main_ipv6"`
ID int `json:"SUBID,omitempty"`
DateCreated string `json:"date_created,omitempty"`
RegionID int `json:"DCID,omitempty"`
Location string `json:"location,omitempty"`
Label string `json:"label,omitempty"`
Status string `json:"status,omitempty"`
IPV4 string `json:"main_ipv4,omitempty"`
IPV6 string `json:"main_ipv6,omitempty"`
}

// InstanceList represents instances that attached to your load balancer
Expand All @@ -50,25 +52,26 @@ type InstanceList struct {

// HealthCheck represents your health check configuration for your load balancer.
type HealthCheck struct {
Protocol string
Port int
Path string
CheckInterval int `json:"check_interval"`
ResponseTimeout int `json:"response_timeout"`
UnhealthyThreshold int `json:"unhealthy_threshold"`
HealthyThreshold int `json:"healthy_threshold"`
Protocol string `json:"protocol,omitempty"`
Port int `json:"port,omitempty"`
Path string `json:"path,omitempty"`
CheckInterval int `json:"check_interval,omitempty"`
ResponseTimeout int `json:"response_timeout,omitempty"`
UnhealthyThreshold int `json:"unhealthy_threshold,omitempty"`
HealthyThreshold int `json:"healthy_threshold,omitempty"`
}

// GenericInfo represents generic configuration of your load balancer
type GenericInfo struct {
BalancingAlgorithm string `json:"balancing_algorithm"`
SSLRedirect bool `json:"ssl_redirect"`
StickySessions CookieName `json:"sticky_sessions"`
BalancingAlgorithm string `json:"balancing_algorithm"`
SSLRedirect bool `json:"ssl_redirect"`
StickySessions *StickySessions `json:"sticky_sessions"`
}

// CookieName represents cookie for your load balancer
type CookieName struct {
CookieName string `json:"cookie_name"`
type StickySessions struct {
StickySessionsEnabled string `json:"sticky_sessions"`
CookieName string `json:"cookie_name"`
}

// ForwardingRules represent a list of forwarding rules
Expand Down Expand Up @@ -436,3 +439,55 @@ func (l *LoadBalancerHandler) HasSSL(ctx context.Context, ID int) (*struct{ SSLI

return ssl, nil
}

func (l *LoadBalancerHandler) Create(ctx context.Context, region int, genericInfo *GenericInfo, healthCheck *HealthCheck, rules []ForwardingRule) (*LoadBalancers, error) {
uri := "/v1/loadbalancer/create"

values := url.Values{
"DCID": {strconv.Itoa(region)},
}

// Check generic info struct
if genericInfo != nil {
if genericInfo.SSLRedirect == true {
values.Add("config_ssl_redirect", "true")
}

if genericInfo.BalancingAlgorithm != "" {
values.Add("algorithm", genericInfo.BalancingAlgorithm)
}

if genericInfo.StickySessions != nil {
if genericInfo.StickySessions.StickySessionsEnabled == "on" {
values.Add("sticky_sessions", genericInfo.StickySessions.StickySessionsEnabled)
values.Add("cookie_name", genericInfo.StickySessions.CookieName)
}
}
}

if healthCheck != nil {
t, _ := json.Marshal(healthCheck)
values.Add("health_check", string(t))
}

if rules != nil {
t, e := json.Marshal(rules)
if e != nil {
panic(e)
}
values.Add("forwarding_rules", string(t))
}

req, err := l.client.NewRequest(ctx, http.MethodPost, uri, values)
if err != nil {
return nil, err
}

var lb LoadBalancers
err = l.client.DoWithContext(ctx, req, &lb)
if err != nil {
return nil, err
}

return &lb, nil
}
59 changes: 56 additions & 3 deletions load_balancer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,9 @@ func TestLoadBalancerHandler_GetGenericInfo(t *testing.T) {
expected := &GenericInfo{
BalancingAlgorithm: "roundrobin",
SSLRedirect: false,
StickySessions: CookieName{CookieName: "test"},
StickySessions: &StickySessions{
CookieName: "test",
},
}

if !reflect.DeepEqual(info, expected) {
Expand Down Expand Up @@ -292,7 +294,7 @@ func TestLoadBalancerHandler_GetFullConfig(t *testing.T) {
GenericInfo: GenericInfo{
BalancingAlgorithm: "roundrobin",
SSLRedirect: true,
StickySessions: CookieName{CookieName: "cookiename"},
StickySessions: &StickySessions{CookieName: "cookiename"},
},
HealthCheck: HealthCheck{
Protocol: "http",
Expand Down Expand Up @@ -340,4 +342,55 @@ func TestLoadBalancerHandler_HasSSL(t *testing.T) {
if !reflect.DeepEqual(ssl, expected) {
t.Errorf("LoadBalancer.HasSSL returned %+v, expected %+v", ssl, expected)
}
}
}

func TestLoadBalancerHandler_Create(t *testing.T) {
setup()
defer teardown()

mux.HandleFunc("/v1/loadbalancer/create", func(writer http.ResponseWriter, request *http.Request) {
response := `{"SUBID": 1314840}`
fmt.Fprintf(writer, response)
})

info := GenericInfo{
BalancingAlgorithm: "roundrobin",
SSLRedirect: true,
StickySessions: &StickySessions{
StickySessionsEnabled: "on",
CookieName: "cookie",
},
}

health := HealthCheck{
Protocol: "http",
Port: 80,
Path: "/",
CheckInterval: 5,
ResponseTimeout: 5,
UnhealthyThreshold: 5,
HealthyThreshold: 5,
}

rules := []ForwardingRule{
{
FrontendProtocol: "http",
FrontendPort: 80,
BackendProtocol: "http",
BackendPort: 80,
},
}

lb, err := client.LoadBalancer.Create(ctx, 1, &info, &health, rules)
if err != nil {
t.Errorf("LoadBalancer.Create returned %+v", err)
}

expected := LoadBalancers{
ID: 1314840,
}

if !reflect.DeepEqual(lb, &expected) {
t.Errorf("LoadBalancer.Create returned %+v, expected %+v", lb, expected)
}
}

0 comments on commit 3b44a32

Please sign in to comment.