From 6601acd49cac8576140d5f385b31bef9809310c3 Mon Sep 17 00:00:00 2001 From: David Dymko Date: Thu, 6 Feb 2020 11:28:03 -0500 Subject: [PATCH 1/2] lb - create --- load_balancer.go | 79 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 67 insertions(+), 12 deletions(-) diff --git a/load_balancer.go b/load_balancer.go index 279f6c5..f7eaf77 100644 --- a/load_balancer.go +++ b/load_balancer.go @@ -2,6 +2,7 @@ package govultr import ( "context" + "encoding/json" "net/http" "net/url" "strconv" @@ -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) (int, error) } // LoadBalancerHandler handles interaction with the server methods for the Vultr API @@ -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 @@ -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) (int, error) { + uri := "/v1/loadbalancer/create" + + //todo validate all of the + + 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 0, err + } + + + //todo clean up the err and res here + l.client.DoWithContext(ctx, req, nil) + + return 0, nil +} From 49ffeb34f844d5f2eddffbb6a58cab4444df4104 Mon Sep 17 00:00:00 2001 From: David Dymko Date: Thu, 13 Feb 2020 10:22:01 -0500 Subject: [PATCH 2/2] lb - create --- load_balancer.go | 34 ++++++++++++------------- load_balancer_test.go | 59 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 73 insertions(+), 20 deletions(-) diff --git a/load_balancer.go b/load_balancer.go index f7eaf77..9997ba2 100644 --- a/load_balancer.go +++ b/load_balancer.go @@ -25,7 +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) (int, 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 @@ -35,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 @@ -440,11 +440,9 @@ 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) (int, error) { +func (l *LoadBalancerHandler) Create(ctx context.Context, region int, genericInfo *GenericInfo, healthCheck *HealthCheck, rules []ForwardingRule) (*LoadBalancers, error) { uri := "/v1/loadbalancer/create" - //todo validate all of the - values := url.Values{ "DCID": {strconv.Itoa(region)}, } @@ -482,12 +480,14 @@ func (l *LoadBalancerHandler) Create(ctx context.Context, region int, genericInf req, err := l.client.NewRequest(ctx, http.MethodPost, uri, values) if err != nil { - return 0, err + return nil, err } + var lb LoadBalancers + err = l.client.DoWithContext(ctx, req, &lb) + if err != nil { + return nil, err + } - //todo clean up the err and res here - l.client.DoWithContext(ctx, req, nil) - - return 0, nil + return &lb, nil } diff --git a/load_balancer_test.go b/load_balancer_test.go index d8050cc..ae52425 100644 --- a/load_balancer_test.go +++ b/load_balancer_test.go @@ -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) { @@ -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", @@ -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) } -} \ No newline at end of file +} + +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) + } +}