Skip to content

Commit

Permalink
fix: error when updating IPv6 Primary IP
Browse files Browse the repository at this point in the history
The API returns a CIDR range in the `ip` field for ipv6 primary IPs. This
caused the `PrimaryIPClient.Update` call to fail, because the response
was parsed as a `net.IP`, but should have been parsed using `net.ParseNetwork`.

The required logic was already implemented in the `PrimaryIPFromSchema`
function, but not used for the update call.

With this commit, the struct `hcloud.PrimaryIPUpdateResult` is removed,
because using it to parse the response causes the error and it was never
returned from any of our methods, so consumers should not be using it.

This error was originally found in hcloud-cli, and caused following error
message:

    ➜  ~ hcloud primary-ip update --auto-delete=false test-ip
    hcloud: updating Primary IP test-ip failed: invalid IP address: 2001:db8::/64
  • Loading branch information
apricote committed Nov 10, 2022
1 parent 55dafa9 commit 532d840
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 12 deletions.
10 changes: 2 additions & 8 deletions hcloud/primary_ip.go
Expand Up @@ -90,12 +90,6 @@ type PrimaryIPUpdateOpts struct {
Name string `json:"name,omitempty"`
}

// PrimaryIPUpdateResult defines the response
// when updating a Primary IP.
type PrimaryIPUpdateResult struct {
PrimaryIP PrimaryIP `json:"primary_ip"`
}

// PrimaryIPAssignOpts defines the request to
// assign a Primary IP to an assignee (usually a server).
type PrimaryIPAssignOpts struct {
Expand Down Expand Up @@ -311,12 +305,12 @@ func (c *PrimaryIPClient) Update(ctx context.Context, primaryIP *PrimaryIP, reqB
return nil, nil, err
}

respBody := PrimaryIPUpdateResult{}
var respBody schema.PrimaryIPUpdateResult
resp, err := c.client.Do(req, &respBody)
if err != nil {
return nil, resp, err
}
return &respBody.PrimaryIP, resp, nil
return PrimaryIPFromSchema(respBody.PrimaryIP), resp, nil
}

// Assign a Primary IP to a resource
Expand Down
12 changes: 8 additions & 4 deletions hcloud/primary_ip_test.go
Expand Up @@ -3,6 +3,7 @@ package hcloud
import (
"context"
"encoding/json"
"net"
"net/http"
"testing"

Expand Down Expand Up @@ -333,8 +334,8 @@ func TestPrimaryIPClient(t *testing.T) {
t.Log(cmp.Diff(expectedReqBody, reqBody))
t.Error("unexpected request body")
}
json.NewEncoder(w).Encode(PrimaryIPUpdateResult{
PrimaryIP: PrimaryIP{ID: 1},
json.NewEncoder(w).Encode(schema.PrimaryIPUpdateResult{
PrimaryIP: schema.PrimaryIP{ID: 1, IP: "2001:db8::/64"},
})
})

Expand All @@ -347,11 +348,14 @@ func TestPrimaryIPClient(t *testing.T) {
Labels: &labels,
}

primaryIP := PrimaryIP{ID: 1}
primaryIP := PrimaryIP{ID: 1, IP: net.ParseIP("2001:db8::")}
result, resp, err := env.Client.PrimaryIP.Update(ctx, &primaryIP, opts)
assert.NoError(t, err)
assert.NotNil(t, resp, "no response returned")
assert.Equal(t, *result, primaryIP, "no primary IP returned")
if result.ID != 1 {
t.Errorf("unexpected Primary IP ID: %v", result.ID)
}
assert.Equal(t, primaryIP.IP, result.IP, "parsed the wrong IP")
})
t.Run("Assign", func(t *testing.T) {
env := newTestEnv()
Expand Down
6 changes: 6 additions & 0 deletions hcloud/schema/primary_ip.go
Expand Up @@ -47,3 +47,9 @@ type PrimaryIPGetResult struct {
type PrimaryIPListResult struct {
PrimaryIPs []PrimaryIP `json:"primary_ips"`
}

// PrimaryIPUpdateResult defines the response
// when updating a Primary IP.
type PrimaryIPUpdateResult struct {
PrimaryIP PrimaryIP `json:"primary_ip"`
}

0 comments on commit 532d840

Please sign in to comment.