diff --git a/hcloud/certificate.go b/hcloud/certificate.go index 1c1d9c7a..eca1db89 100644 --- a/hcloud/certificate.go +++ b/hcloud/certificate.go @@ -130,7 +130,10 @@ func (c *CertificateClient) GetByName(ctx context.Context, name string) (*Certif // retrieves a Certificate by its name. If the Certificate does not exist, nil is returned. func (c *CertificateClient) Get(ctx context.Context, idOrName string) (*Certificate, *Response, error) { if id, err := strconv.ParseInt(idOrName, 10, 64); err == nil { - return c.GetByID(ctx, id) + cert, res, err := c.GetByID(ctx, id) + if cert != nil || err != nil { + return cert, res, err + } } return c.GetByName(ctx, idOrName) } diff --git a/hcloud/certificate_test.go b/hcloud/certificate_test.go index 0bb2cdc2..a75c2171 100644 --- a/hcloud/certificate_test.go +++ b/hcloud/certificate_test.go @@ -239,6 +239,48 @@ func TestCertificateClientGetByName(t *testing.T) { }) } +func TestCertificateClientGetByNumericName(t *testing.T) { + env := newTestEnv() + defer env.Teardown() + + env.Mux.HandleFunc("/certificates/123", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusNotFound) + json.NewEncoder(w).Encode(schema.ErrorResponse{ + Error: schema.Error{ + Code: string(ErrorCodeNotFound), + }, + }) + }) + + env.Mux.HandleFunc("/certificates", func(w http.ResponseWriter, r *http.Request) { + if r.URL.RawQuery != "name=123" { + t.Fatal("missing name query") + } + json.NewEncoder(w).Encode(schema.CertificateListResponse{ + Certificates: []schema.Certificate{ + { + ID: 1, + Name: "123", + }, + }, + }) + }) + + ctx := context.Background() + + certficate, _, err := env.Client.Certificate.Get(ctx, "123") + if err != nil { + t.Fatal(err) + } + if certficate == nil { + t.Fatal("no certficate") + } + if certficate.ID != 1 { + t.Errorf("unexpected certficate ID: %v", certficate.ID) + } +} + func TestCertificateClientGetByNameNotFound(t *testing.T) { env := newTestEnv() defer env.Teardown() diff --git a/hcloud/firewall.go b/hcloud/firewall.go index a2219135..46d6e99e 100644 --- a/hcloud/firewall.go +++ b/hcloud/firewall.go @@ -128,7 +128,10 @@ func (c *FirewallClient) GetByName(ctx context.Context, name string) (*Firewall, // retrieves a Firewall by its name. If the Firewall does not exist, nil is returned. func (c *FirewallClient) Get(ctx context.Context, idOrName string) (*Firewall, *Response, error) { if id, err := strconv.ParseInt(idOrName, 10, 64); err == nil { - return c.GetByID(ctx, id) + fw, res, err := c.GetByID(ctx, id) + if fw != nil || err != nil { + return fw, res, err + } } return c.GetByName(ctx, idOrName) } diff --git a/hcloud/firewall_test.go b/hcloud/firewall_test.go index 61761b1e..7d35b95f 100644 --- a/hcloud/firewall_test.go +++ b/hcloud/firewall_test.go @@ -148,6 +148,48 @@ func TestFirewallClientGetByName(t *testing.T) { }) } +func TestFirewallClientGetByNumericName(t *testing.T) { + env := newTestEnv() + defer env.Teardown() + + env.Mux.HandleFunc("/firewalls/123", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusNotFound) + json.NewEncoder(w).Encode(schema.ErrorResponse{ + Error: schema.Error{ + Code: string(ErrorCodeNotFound), + }, + }) + }) + + env.Mux.HandleFunc("/firewalls", func(w http.ResponseWriter, r *http.Request) { + if r.URL.RawQuery != "name=123" { + t.Fatal("missing name query") + } + json.NewEncoder(w).Encode(schema.FirewallListResponse{ + Firewalls: []schema.Firewall{ + { + ID: 1, + Name: "123", + }, + }, + }) + }) + + ctx := context.Background() + + firewall, _, err := env.Client.Firewall.Get(ctx, "123") + if err != nil { + t.Fatal(err) + } + if firewall == nil { + t.Fatal("no firewall") + } + if firewall.ID != 1 { + t.Errorf("unexpected firewall ID: %v", firewall.ID) + } +} + func TestFirewallClientGetByNameNotFound(t *testing.T) { env := newTestEnv() defer env.Teardown() diff --git a/hcloud/floating_ip.go b/hcloud/floating_ip.go index 0e6962ab..11059d53 100644 --- a/hcloud/floating_ip.go +++ b/hcloud/floating_ip.go @@ -129,7 +129,10 @@ func (c *FloatingIPClient) GetByName(ctx context.Context, name string) (*Floatin // retrieves a Floating IP by its name. If the Floating IP does not exist, nil is returned. func (c *FloatingIPClient) Get(ctx context.Context, idOrName string) (*FloatingIP, *Response, error) { if id, err := strconv.ParseInt(idOrName, 10, 64); err == nil { - return c.GetByID(ctx, id) + ip, res, err := c.GetByID(ctx, id) + if ip != nil || err != nil { + return ip, res, err + } } return c.GetByName(ctx, idOrName) } diff --git a/hcloud/floating_ip_test.go b/hcloud/floating_ip_test.go index 4f6d1efe..d6b6ca6c 100644 --- a/hcloud/floating_ip_test.go +++ b/hcloud/floating_ip_test.go @@ -117,6 +117,50 @@ func TestFloatingIPClientGetByName(t *testing.T) { }) } +func TestFloatingIPClientGetByNumericName(t *testing.T) { + env := newTestEnv() + defer env.Teardown() + + env.Mux.HandleFunc("/floating_ips/123", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusNotFound) + json.NewEncoder(w).Encode(schema.ErrorResponse{ + Error: schema.Error{ + Code: string(ErrorCodeNotFound), + }, + }) + }) + + env.Mux.HandleFunc("/floating_ips", func(w http.ResponseWriter, r *http.Request) { + if r.URL.RawQuery != "name=123" { + t.Fatal("missing name query") + } + json.NewEncoder(w).Encode(schema.FloatingIPListResponse{ + FloatingIPs: []schema.FloatingIP{ + { + ID: 1, + Name: "123", + Type: "ipv4", + IP: "131.232.99.1", + }, + }, + }) + }) + + ctx := context.Background() + + floatingIP, _, err := env.Client.FloatingIP.Get(ctx, "123") + if err != nil { + t.Fatal(err) + } + if floatingIP == nil { + t.Fatal("no Floating IP") + } + if floatingIP.ID != 1 { + t.Errorf("unexpected Floating IP ID: %v", floatingIP.ID) + } +} + func TestFloatingIPClientGetByNameNotFound(t *testing.T) { env := newTestEnv() defer env.Teardown() diff --git a/hcloud/image.go b/hcloud/image.go index 185c38d4..3ee230cd 100644 --- a/hcloud/image.go +++ b/hcloud/image.go @@ -134,7 +134,10 @@ func (c *ImageClient) GetByNameAndArchitecture(ctx context.Context, name string, // Deprecated: Use [ImageClient.GetForArchitecture] instead. func (c *ImageClient) Get(ctx context.Context, idOrName string) (*Image, *Response, error) { if id, err := strconv.ParseInt(idOrName, 10, 64); err == nil { - return c.GetByID(ctx, id) + img, res, err := c.GetByID(ctx, id) + if img != nil { + return img, res, err + } } return c.GetByName(ctx, idOrName) } @@ -146,7 +149,10 @@ func (c *ImageClient) Get(ctx context.Context, idOrName string) (*Image, *Respon // check for this in your calling method. func (c *ImageClient) GetForArchitecture(ctx context.Context, idOrName string, architecture Architecture) (*Image, *Response, error) { if id, err := strconv.ParseInt(idOrName, 10, 64); err == nil { - return c.GetByID(ctx, id) + img, res, err := c.GetByID(ctx, id) + if img != nil || err != nil { + return img, res, err + } } return c.GetByNameAndArchitecture(ctx, idOrName, architecture) } diff --git a/hcloud/image_test.go b/hcloud/image_test.go index 31707baf..d9b1e42c 100644 --- a/hcloud/image_test.go +++ b/hcloud/image_test.go @@ -134,6 +134,47 @@ func TestImageClient(t *testing.T) { }) }) + t.Run("GetByNumericName", func(t *testing.T) { + env := newTestEnv() + defer env.Teardown() + + env.Mux.HandleFunc("/images/123", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusNotFound) + json.NewEncoder(w).Encode(schema.ErrorResponse{ + Error: schema.Error{ + Code: string(ErrorCodeNotFound), + }, + }) + }) + + env.Mux.HandleFunc("/images", func(w http.ResponseWriter, r *http.Request) { + if r.URL.RawQuery != "name=123" { + t.Fatal("missing name query") + } + json.NewEncoder(w).Encode(schema.ImageListResponse{ + Images: []schema.Image{ + { + ID: 1, + }, + }, + }) + }) + + ctx := context.Background() + + image, _, err := env.Client.Image.Get(ctx, "123") + if err != nil { + t.Fatal(err) + } + if image == nil { + t.Fatal("no image") + } + if image.ID != 1 { + t.Errorf("unexpected image ID: %v", image.ID) + } + }) + t.Run("GetByName (not found)", func(t *testing.T) { env := newTestEnv() defer env.Teardown() diff --git a/hcloud/iso.go b/hcloud/iso.go index 08f7072c..0c461939 100644 --- a/hcloud/iso.go +++ b/hcloud/iso.go @@ -71,7 +71,10 @@ func (c *ISOClient) GetByName(ctx context.Context, name string) (*ISO, *Response // Get retrieves an ISO by its ID if the input can be parsed as an integer, otherwise it retrieves an ISO by its name. func (c *ISOClient) Get(ctx context.Context, idOrName string) (*ISO, *Response, error) { if id, err := strconv.ParseInt(idOrName, 10, 64); err == nil { - return c.GetByID(ctx, id) + iso, res, err := c.GetByID(ctx, id) + if iso != nil || err != nil { + return iso, res, err + } } return c.GetByName(ctx, idOrName) } diff --git a/hcloud/iso_test.go b/hcloud/iso_test.go index 11fe9081..ced1fdff 100644 --- a/hcloud/iso_test.go +++ b/hcloud/iso_test.go @@ -134,6 +134,47 @@ func TestISOClient(t *testing.T) { }) }) + t.Run("GetByNumericName", func(t *testing.T) { + env := newTestEnv() + defer env.Teardown() + + env.Mux.HandleFunc("/isos/123", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusNotFound) + json.NewEncoder(w).Encode(schema.ErrorResponse{ + Error: schema.Error{ + Code: string(ErrorCodeNotFound), + }, + }) + }) + + env.Mux.HandleFunc("/isos", func(w http.ResponseWriter, r *http.Request) { + if r.URL.RawQuery != "name=123" { + t.Fatal("missing name query") + } + json.NewEncoder(w).Encode(schema.ISOListResponse{ + ISOs: []schema.ISO{ + { + ID: 1, + }, + }, + }) + }) + + ctx := context.Background() + + iso, _, err := env.Client.ISO.Get(ctx, "123") + if err != nil { + t.Fatal(err) + } + if iso == nil { + t.Fatal("no iso") + } + if iso.ID != 1 { + t.Errorf("unexpected iso ID: %v", iso.ID) + } + }) + t.Run("GetByName (not found)", func(t *testing.T) { env := newTestEnv() defer env.Teardown() diff --git a/hcloud/load_balancer.go b/hcloud/load_balancer.go index c634d160..c6829fce 100644 --- a/hcloud/load_balancer.go +++ b/hcloud/load_balancer.go @@ -275,7 +275,10 @@ func (c *LoadBalancerClient) GetByName(ctx context.Context, name string) (*LoadB // 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.ParseInt(idOrName, 10, 64); err == nil { - return c.GetByID(ctx, id) + lb, res, err := c.GetByID(ctx, id) + if lb != nil || err != nil { + return lb, res, err + } } return c.GetByName(ctx, idOrName) } diff --git a/hcloud/load_balancer_test.go b/hcloud/load_balancer_test.go index 2f18efe3..5b45717a 100644 --- a/hcloud/load_balancer_test.go +++ b/hcloud/load_balancer_test.go @@ -125,6 +125,48 @@ func TestLoadBalancerClientGetByName(t *testing.T) { }) } +func TestLoadBalancerClientGetByNumericName(t *testing.T) { + env := newTestEnv() + defer env.Teardown() + + env.Mux.HandleFunc("/load_balancers/123", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusNotFound) + json.NewEncoder(w).Encode(schema.ErrorResponse{ + Error: schema.Error{ + Code: string(ErrorCodeNotFound), + }, + }) + }) + + env.Mux.HandleFunc("/load_balancers", func(w http.ResponseWriter, r *http.Request) { + if r.URL.RawQuery != "name=123" { + t.Fatal("missing name query") + } + json.NewEncoder(w).Encode(schema.LoadBalancerListResponse{ + LoadBalancers: []schema.LoadBalancer{ + { + ID: 1, + Name: "123", + }, + }, + }) + }) + + ctx := context.Background() + + loadBalancer, _, err := env.Client.LoadBalancer.Get(ctx, "123") + if err != nil { + t.Fatal(err) + } + if loadBalancer == nil { + t.Fatal("no load balancer") + } + if loadBalancer.ID != 1 { + t.Errorf("unexpected load balancer ID: %v", loadBalancer.ID) + } +} + func TestLoadBalancerClientGetByNameNotFound(t *testing.T) { env := newTestEnv() defer env.Teardown() diff --git a/hcloud/network.go b/hcloud/network.go index 95e42cd8..2f2fae84 100644 --- a/hcloud/network.go +++ b/hcloud/network.go @@ -119,7 +119,10 @@ func (c *NetworkClient) GetByName(ctx context.Context, name string) (*Network, * // retrieves a network by its name. If the network does not exist, nil is returned. func (c *NetworkClient) Get(ctx context.Context, idOrName string) (*Network, *Response, error) { if id, err := strconv.ParseInt(idOrName, 10, 64); err == nil { - return c.GetByID(ctx, id) + n, res, err := c.GetByID(ctx, id) + if n != nil || err != nil { + return n, res, err + } } return c.GetByName(ctx, idOrName) } diff --git a/hcloud/network_test.go b/hcloud/network_test.go index 51f1fe8e..2c325c6e 100644 --- a/hcloud/network_test.go +++ b/hcloud/network_test.go @@ -116,6 +116,47 @@ func TestNetworkClientGetByName(t *testing.T) { }) } +func TestNetworkClientGetByNumericName(t *testing.T) { + env := newTestEnv() + defer env.Teardown() + + env.Mux.HandleFunc("/networks/123", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusNotFound) + json.NewEncoder(w).Encode(schema.ErrorResponse{ + Error: schema.Error{ + Code: string(ErrorCodeNotFound), + }, + }) + }) + + env.Mux.HandleFunc("/networks", func(w http.ResponseWriter, r *http.Request) { + if r.URL.RawQuery != "name=123" { + t.Fatal("missing name query") + } + json.NewEncoder(w).Encode(schema.NetworkListResponse{ + Networks: []schema.Network{ + { + ID: 1, + Name: "123", + }, + }, + }) + }) + ctx := context.Background() + + network, _, err := env.Client.Network.Get(ctx, "123") + if err != nil { + t.Fatal(err) + } + if network == nil { + t.Fatal("no network") + } + if network.ID != 1 { + t.Errorf("unexpected network ID: %v", network.ID) + } +} + func TestNetworkClientGetByNameNotFound(t *testing.T) { env := newTestEnv() defer env.Teardown() diff --git a/hcloud/placement_group.go b/hcloud/placement_group.go index 5ad3515e..ac347ae2 100644 --- a/hcloud/placement_group.go +++ b/hcloud/placement_group.go @@ -70,7 +70,10 @@ func (c *PlacementGroupClient) GetByName(ctx context.Context, name string) (*Pla // retrieves a PlacementGroup by its name. If the PlacementGroup does not exist, nil is returned. func (c *PlacementGroupClient) Get(ctx context.Context, idOrName string) (*PlacementGroup, *Response, error) { if id, err := strconv.ParseInt(idOrName, 10, 64); err == nil { - return c.GetByID(ctx, id) + pg, res, err := c.GetByID(ctx, id) + if pg != nil || err != nil { + return pg, res, err + } } return c.GetByName(ctx, idOrName) } diff --git a/hcloud/placement_group_test.go b/hcloud/placement_group_test.go index 0b37f49f..f4794c58 100644 --- a/hcloud/placement_group_test.go +++ b/hcloud/placement_group_test.go @@ -127,6 +127,62 @@ func TestPlacementGroupClientGetByName(t *testing.T) { }) } +func TestPlacementGroupClientGetByNumericName(t *testing.T) { + env := newTestEnv() + defer env.Teardown() + + const ( + id = 1 + name = "123" + ) + + env.Mux.HandleFunc("/placement_groups/123", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusNotFound) + json.NewEncoder(w).Encode(schema.ErrorResponse{ + Error: schema.Error{ + Code: string(ErrorCodeNotFound), + }, + }) + }) + + env.Mux.HandleFunc("/placement_groups", func(w http.ResponseWriter, r *http.Request) { + if r.URL.RawQuery != fmt.Sprintf("name=%s", name) { + t.Fatal("missing name query") + } + json.NewEncoder(w).Encode(schema.PlacementGroupListResponse{ + PlacementGroups: []schema.PlacementGroup{ + { + ID: id, + Name: name, + }, + }, + }) + }) + + checkError := func(t *testing.T, placementGroup *PlacementGroup, err error) { + if err != nil { + t.Fatal(err) + } + if placementGroup == nil { + t.Fatal("no placement group") + } + if placementGroup.ID != id { + t.Errorf("unexpected placement group ID: %v", placementGroup.ID) + } + if placementGroup.Name != name { + t.Errorf("unexpected placement group Name: %v", placementGroup.Name) + } + } + + ctx := context.Background() + + t.Run("called via Get", func(t *testing.T) { + placementGroup, _, err := env.Client.PlacementGroup.Get(ctx, name) + checkError(t, placementGroup, err) + }) +} + func TestPlacementGroupClientGetByNameNotFound(t *testing.T) { env := newTestEnv() defer env.Teardown() diff --git a/hcloud/primary_ip.go b/hcloud/primary_ip.go index 05c412ee..d8ed7750 100644 --- a/hcloud/primary_ip.go +++ b/hcloud/primary_ip.go @@ -209,7 +209,10 @@ func (c *PrimaryIPClient) GetByName(ctx context.Context, name string) (*PrimaryI // retrieves a Primary IP by its name. If the Primary IP does not exist, nil is returned. func (c *PrimaryIPClient) Get(ctx context.Context, idOrName string) (*PrimaryIP, *Response, error) { if id, err := strconv.ParseInt(idOrName, 10, 64); err == nil { - return c.GetByID(ctx, id) + ip, res, err := c.GetByID(ctx, id) + if ip != nil || err != nil { + return ip, res, err + } } return c.GetByName(ctx, idOrName) } diff --git a/hcloud/primary_ip_test.go b/hcloud/primary_ip_test.go index a61c8455..97299f6c 100644 --- a/hcloud/primary_ip_test.go +++ b/hcloud/primary_ip_test.go @@ -119,6 +119,47 @@ func TestPrimaryIPClient(t *testing.T) { }) }) + t.Run("GetByNumericName", func(t *testing.T) { + env := newTestEnv() + defer env.Teardown() + + env.Mux.HandleFunc("/primary_ips/123", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusNotFound) + json.NewEncoder(w).Encode(schema.ErrorResponse{ + Error: schema.Error{ + Code: string(ErrorCodeNotFound), + }, + }) + }) + + env.Mux.HandleFunc("/primary_ips", func(w http.ResponseWriter, r *http.Request) { + if r.URL.RawQuery != "name=123" { + t.Fatal("missing name query") + } + json.NewEncoder(w).Encode(schema.PrimaryIPListResult{ + PrimaryIPs: []schema.PrimaryIP{ + { + ID: 1, + }, + }, + }) + }) + + ctx := context.Background() + + primaryIP, _, err := env.Client.PrimaryIP.Get(ctx, "123") + if err != nil { + t.Fatal(err) + } + if primaryIP == nil { + t.Fatal("no primary_ip") + } + if primaryIP.ID != 1 { + t.Errorf("unexpected primary_ip ID: %v", primaryIP.ID) + } + }) + t.Run("GetByName (not found)", func(t *testing.T) { env := newTestEnv() defer env.Teardown() diff --git a/hcloud/server.go b/hcloud/server.go index d1514f5c..e74c3ea5 100644 --- a/hcloud/server.go +++ b/hcloud/server.go @@ -230,7 +230,10 @@ func (c *ServerClient) GetByName(ctx context.Context, name string) (*Server, *Re // retrieves a server by its name. If the server does not exist, nil is returned. func (c *ServerClient) Get(ctx context.Context, idOrName string) (*Server, *Response, error) { if id, err := strconv.ParseInt(idOrName, 10, 64); err == nil { - return c.GetByID(ctx, id) + srv, res, err := c.GetByID(ctx, id) + if srv != nil || err != nil { + return srv, res, err + } } return c.GetByName(ctx, idOrName) } diff --git a/hcloud/server_test.go b/hcloud/server_test.go index f1e4535a..5b5c1737 100644 --- a/hcloud/server_test.go +++ b/hcloud/server_test.go @@ -122,6 +122,47 @@ func TestServerClientGetByName(t *testing.T) { }) } +func TestServerClientGetByNumericName(t *testing.T) { + env := newTestEnv() + defer env.Teardown() + + env.Mux.HandleFunc("/servers/123", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusNotFound) + json.NewEncoder(w).Encode(schema.ErrorResponse{ + Error: schema.Error{ + Code: string(ErrorCodeNotFound), + }, + }) + }) + + env.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) { + if r.URL.RawQuery != "name=123" { + t.Fatal("missing name query") + } + json.NewEncoder(w).Encode(schema.ServerListResponse{ + Servers: []schema.Server{ + { + ID: 1, + Name: "123", + }, + }, + }) + }) + ctx := context.Background() + + server, _, err := env.Client.Server.Get(ctx, "123") + if err != nil { + t.Fatal(err) + } + if server == nil { + t.Fatal("no server") + } + if server.ID != 1 { + t.Errorf("unexpected server ID: %v", server.ID) + } +} + func TestServerClientGetByNameNotFound(t *testing.T) { env := newTestEnv() defer env.Teardown() diff --git a/hcloud/ssh_key.go b/hcloud/ssh_key.go index 45d4558f..0af48376 100644 --- a/hcloud/ssh_key.go +++ b/hcloud/ssh_key.go @@ -71,7 +71,10 @@ func (c *SSHKeyClient) GetByFingerprint(ctx context.Context, fingerprint string) // retrieves a SSH key by its name. If the SSH key does not exist, nil is returned. func (c *SSHKeyClient) Get(ctx context.Context, idOrName string) (*SSHKey, *Response, error) { if id, err := strconv.ParseInt(idOrName, 10, 64); err == nil { - return c.GetByID(ctx, id) + sshKey, res, err := c.GetByID(ctx, id) + if sshKey != nil || err != nil { + return sshKey, res, err + } } return c.GetByName(ctx, idOrName) } diff --git a/hcloud/ssh_key_test.go b/hcloud/ssh_key_test.go index abc0d1f5..896c2476 100644 --- a/hcloud/ssh_key_test.go +++ b/hcloud/ssh_key_test.go @@ -120,6 +120,48 @@ func TestSSHKeyClientGetByName(t *testing.T) { }) } +func TestSSHKeyClientGetByNumericName(t *testing.T) { + env := newTestEnv() + defer env.Teardown() + + env.Mux.HandleFunc("/ssh_keys/123", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusNotFound) + json.NewEncoder(w).Encode(schema.ErrorResponse{ + Error: schema.Error{ + Code: string(ErrorCodeNotFound), + }, + }) + }) + + env.Mux.HandleFunc("/ssh_keys", func(w http.ResponseWriter, r *http.Request) { + if r.URL.RawQuery != "name=123" { + t.Fatal("missing name query") + } + fmt.Fprint(w, `{ + "ssh_keys": [{ + "id": 1, + "name": "123", + "fingerprint": "b7:2f:30:a0:2f:6c:58:6c:21:04:58:61:ba:06:3b:2c", + "public_key": "ssh-rsa AAAjjk76kgf...Xt" + }] + }`) + }) + + ctx := context.Background() + + sshKey, _, err := env.Client.SSHKey.Get(ctx, "123") + if err != nil { + t.Fatalf("SSHKey.GetByID failed: %s", err) + } + if sshKey == nil { + t.Fatal("no SSH key") + } + if sshKey.ID != 1 { + t.Errorf("unexpected SSH key ID: %v", sshKey.ID) + } +} + func TestSSHKeyClientGetByNameNotFound(t *testing.T) { env := newTestEnv() defer env.Teardown() diff --git a/hcloud/volume.go b/hcloud/volume.go index 6fe9d5ab..bf54994b 100644 --- a/hcloud/volume.go +++ b/hcloud/volume.go @@ -89,7 +89,10 @@ func (c *VolumeClient) GetByName(ctx context.Context, name string) (*Volume, *Re // retrieves a volume by its name. If the volume does not exist, nil is returned. func (c *VolumeClient) Get(ctx context.Context, idOrName string) (*Volume, *Response, error) { if id, err := strconv.ParseInt(idOrName, 10, 64); err == nil { - return c.GetByID(ctx, id) + vol, res, err := c.GetByID(ctx, id) + if vol != nil || err != nil { + return vol, res, err + } } return c.GetByName(ctx, idOrName) } diff --git a/hcloud/volume_test.go b/hcloud/volume_test.go index de05b945..e997172e 100644 --- a/hcloud/volume_test.go +++ b/hcloud/volume_test.go @@ -157,6 +157,65 @@ func TestVolumeClientGetByName(t *testing.T) { }) } +func TestVolumeClientGetByNumericName(t *testing.T) { + env := newTestEnv() + defer env.Teardown() + + env.Mux.HandleFunc("/volumes/123", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusNotFound) + json.NewEncoder(w).Encode(schema.ErrorResponse{ + Error: schema.Error{ + Code: string(ErrorCodeNotFound), + }, + }) + }) + + env.Mux.HandleFunc("/volumes", func(w http.ResponseWriter, r *http.Request) { + if r.URL.RawQuery != "name=123" { + t.Fatal("missing name query") + } + fmt.Fprint(w, `{ + "volumes": [ + { + "id": 1, + "created": "2016-01-30T23:50:11+00:00", + "name": "123", + "status": "creating", + "server": null, + "location": { + "id": 1, + "name": "fsn1", + "description": "Falkenstein DC Park 1", + "country": "DE", + "city": "Falkenstein", + "latitude": 50.47612, + "longitude": 12.370071 + }, + "size": 42, + "linux_device":"/dev/disk/by-id/scsi-0HC_volume_1", + "protection": { + "delete": true + } + } + ] + }`) + }) + + ctx := context.Background() + + volume, _, err := env.Client.Volume.Get(ctx, "123") + if err != nil { + t.Fatal(err) + } + if volume == nil { + t.Fatal("no volume") + } + if volume.ID != 1 { + t.Errorf("unexpected volume ID: %v", volume.ID) + } +} + func TestVolumeClientGetByNameNotFound(t *testing.T) { env := newTestEnv() defer env.Teardown()