File: location.go

package info (click to toggle)
golang-github-hetznercloud-hcloud-go 2.4.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,072 kB
  • sloc: sh: 5; makefile: 2
file content (132 lines) | stat: -rw-r--r-- 3,632 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package hcloud

import (
	"context"
	"fmt"
	"net/url"
	"strconv"

	"github.com/hetznercloud/hcloud-go/v2/hcloud/schema"
)

// Location represents a location in the Hetzner Cloud.
type Location struct {
	ID          int64
	Name        string
	Description string
	Country     string
	City        string
	Latitude    float64
	Longitude   float64
	NetworkZone NetworkZone
}

// LocationClient is a client for the location API.
type LocationClient struct {
	client *Client
}

// GetByID retrieves a location by its ID. If the location does not exist, nil is returned.
func (c *LocationClient) GetByID(ctx context.Context, id int64) (*Location, *Response, error) {
	req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("/locations/%d", id), nil)
	if err != nil {
		return nil, nil, err
	}

	var body schema.LocationGetResponse
	resp, err := c.client.Do(req, &body)
	if err != nil {
		if IsError(err, ErrorCodeNotFound) {
			return nil, resp, nil
		}
		return nil, resp, err
	}
	return LocationFromSchema(body.Location), resp, nil
}

// GetByName retrieves an location by its name. If the location does not exist, nil is returned.
func (c *LocationClient) GetByName(ctx context.Context, name string) (*Location, *Response, error) {
	if name == "" {
		return nil, nil, nil
	}
	locations, response, err := c.List(ctx, LocationListOpts{Name: name})
	if len(locations) == 0 {
		return nil, response, err
	}
	return locations[0], response, err
}

// Get retrieves a location by its ID if the input can be parsed as an integer, otherwise it
// retrieves a location by its name. If the location does not exist, nil is returned.
func (c *LocationClient) Get(ctx context.Context, idOrName string) (*Location, *Response, error) {
	if id, err := strconv.ParseInt(idOrName, 10, 64); err == nil {
		return c.GetByID(ctx, id)
	}
	return c.GetByName(ctx, idOrName)
}

// LocationListOpts specifies options for listing location.
type LocationListOpts struct {
	ListOpts
	Name string
	Sort []string
}

func (l LocationListOpts) values() url.Values {
	vals := l.ListOpts.Values()
	if l.Name != "" {
		vals.Add("name", l.Name)
	}
	for _, sort := range l.Sort {
		vals.Add("sort", sort)
	}
	return vals
}

// List returns a list of locations for a specific page.
//
// Please note that filters specified in opts are not taken into account
// when their value corresponds to their zero value or when they are empty.
func (c *LocationClient) List(ctx context.Context, opts LocationListOpts) ([]*Location, *Response, error) {
	path := "/locations?" + opts.values().Encode()
	req, err := c.client.NewRequest(ctx, "GET", path, nil)
	if err != nil {
		return nil, nil, err
	}

	var body schema.LocationListResponse
	resp, err := c.client.Do(req, &body)
	if err != nil {
		return nil, nil, err
	}
	locations := make([]*Location, 0, len(body.Locations))
	for _, i := range body.Locations {
		locations = append(locations, LocationFromSchema(i))
	}
	return locations, resp, nil
}

// All returns all locations.
func (c *LocationClient) All(ctx context.Context) ([]*Location, error) {
	return c.AllWithOpts(ctx, LocationListOpts{ListOpts: ListOpts{PerPage: 50}})
}

// AllWithOpts returns all locations for the given options.
func (c *LocationClient) AllWithOpts(ctx context.Context, opts LocationListOpts) ([]*Location, error) {
	allLocations := []*Location{}

	err := c.client.all(func(page int) (*Response, error) {
		opts.Page = page
		locations, resp, err := c.List(ctx, opts)
		if err != nil {
			return resp, err
		}
		allLocations = append(allLocations, locations...)
		return resp, nil
	})
	if err != nil {
		return nil, err
	}

	return allLocations, nil
}