Skip to content
Merged
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
12 changes: 12 additions & 0 deletions openstack/loadbalancer/v2/loadbalancers/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,5 +136,17 @@ Example to Failover a Load Balancers
if err != nil {
panic(err)
}

Example to Resize a Load Balancer (OVHcloud Octavia only)

lbID := "d67d56a6-4a86-4688-a282-f46444705c64"
resizeOpts := loadbalancers.ResizeOpts{
NewFlavorID: "bba40eb2-ee8c-11e9-81b4-2a2ae2dbcce4",
}

err := loadbalancers.Resize(context.TODO(), networkClient, lbID, resizeOpts).ExtractErr()
if err != nil {
panic(err)
}
*/
package loadbalancers
35 changes: 35 additions & 0 deletions openstack/loadbalancer/v2/loadbalancers/requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,3 +279,38 @@ func Failover(ctx context.Context, c *gophercloud.ServiceClient, id string) (r F
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
return
}

// ResizeOptsBuilder allows extensions to add additional parameters to the
// Resize request.
type ResizeOptsBuilder interface {
ToLoadBalancerResizeMap() (map[string]any, error)
}

// ResizeOpts is the common options struct used in this package's Resize
// operation.
type ResizeOpts struct {
// The ID of the flavor to resize the load balancer to.
NewFlavorID string `json:"new_flavor_id" required:"true"`
}

// ToLoadBalancerResizeMap builds a request body from ResizeOpts.
func (opts ResizeOpts) ToLoadBalancerResizeMap() (map[string]any, error) {
return gophercloud.BuildRequestBody(opts, "")
}

// Resize changes the flavor of a load balancer: Octavia fails it over onto
// amphorae of the new flavor. This call is not part of upstream Octavia; it
// is OVHcloud's downstream patch (upstream change 890215, spec "Load balancer
// resizing").
func Resize(ctx context.Context, c *gophercloud.ServiceClient, id string, opts ResizeOptsBuilder) (r ResizeResult) {
b, err := opts.ToLoadBalancerResizeMap()
if err != nil {
r.Err = err
return
}
resp, err := c.Put(ctx, resizeRootURL(c, id), b, nil, &gophercloud.RequestOpts{
OkCodes: []int{202},
})
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
return
}
6 changes: 6 additions & 0 deletions openstack/loadbalancer/v2/loadbalancers/results.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,3 +264,9 @@ type DeleteResult struct {
type FailoverResult struct {
gophercloud.ErrResult
}

// ResizeResult represents the result of a resize operation. Call its
// ExtractErr method to determine if the request succeeded or failed.
type ResizeResult struct {
gophercloud.ErrResult
}
11 changes: 11 additions & 0 deletions openstack/loadbalancer/v2/loadbalancers/testing/fixtures_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -633,3 +633,14 @@ func HandleLoadbalancerFailoverSuccessfully(t *testing.T, fakeServer th.FakeServ
w.WriteHeader(http.StatusAccepted)
})
}

// HandleLoadbalancerResizeSuccessfully sets up the test server to respond to a loadbalancer resize request.
func HandleLoadbalancerResizeSuccessfully(t *testing.T, fakeServer th.FakeServer) {
fakeServer.Mux.HandleFunc("/v2.0/lbaas/loadbalancers/36e08a3e-a78f-4b40-a229-1e7e23eee1ab/resize", func(w http.ResponseWriter, r *http.Request) {
th.TestMethod(t, r, "PUT")
th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
th.TestJSONRequest(t, r, `{"new_flavor_id": "bba40eb2-ee8c-11e9-81b4-2a2ae2dbcce4"}`)

w.WriteHeader(http.StatusAccepted)
})
}
18 changes: 18 additions & 0 deletions openstack/loadbalancer/v2/loadbalancers/testing/requests_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,3 +239,21 @@ func TestFailoverLoadbalancer(t *testing.T) {
res := loadbalancers.Failover(context.TODO(), fake.ServiceClient(fakeServer), "36e08a3e-a78f-4b40-a229-1e7e23eee1ab")
th.AssertNoErr(t, res.Err)
}

func TestResizeLoadbalancer(t *testing.T) {
fakeServer := th.SetupHTTP()
defer fakeServer.Teardown()
HandleLoadbalancerResizeSuccessfully(t, fakeServer)

res := loadbalancers.Resize(context.TODO(), fake.ServiceClient(fakeServer), "36e08a3e-a78f-4b40-a229-1e7e23eee1ab", loadbalancers.ResizeOpts{
NewFlavorID: "bba40eb2-ee8c-11e9-81b4-2a2ae2dbcce4",
})
th.AssertNoErr(t, res.Err)
}

func TestResizeLoadbalancerRequiresAFlavor(t *testing.T) {
res := loadbalancers.Resize(context.TODO(), nil, "36e08a3e-a78f-4b40-a229-1e7e23eee1ab", loadbalancers.ResizeOpts{})
if res.Err == nil {
t.Fatal("expected an error without new_flavor_id")
}
}
5 changes: 5 additions & 0 deletions openstack/loadbalancer/v2/loadbalancers/urls.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const (
statusPath = "status"
statisticsPath = "stats"
failoverPath = "failover"
resizePath = "resize"
)

func rootURL(c *gophercloud.ServiceClient) string {
Expand All @@ -29,3 +30,7 @@ func statisticsRootURL(c *gophercloud.ServiceClient, id string) string {
func failoverRootURL(c *gophercloud.ServiceClient, id string) string {
return c.ServiceURL(rootPath, resourcePath, id, failoverPath)
}

func resizeRootURL(c *gophercloud.ServiceClient, id string) string {
return c.ServiceURL(rootPath, resourcePath, id, resizePath)
}
Loading