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
|
package hcapi2
import (
"context"
"strconv"
"sync"
"github.com/hetznercloud/hcloud-go/v2/hcloud"
)
type ServerClient interface {
ServerClientBase
ServerName(id int64) string
Names() []string
LabelKeys(idOrName string) []string
}
func NewServerClient(client *hcloud.ServerClient) ServerClient {
return &serverClient{
ServerClientBase: client,
}
}
// ServerClient embeds the Hetzner Cloud Server client and provides some
// additional helper functions.
type serverClient struct {
ServerClientBase
ServerTypes *hcloud.ServerTypeClient
srvByID map[int64]*hcloud.Server
srvByName map[string]*hcloud.Server
once sync.Once
err error
}
// ServerName obtains the name of the server with id. If the name could not
// be fetched it returns the value id converted to a string.
func (c *serverClient) ServerName(id int64) string {
if err := c.init(); err != nil {
return strconv.FormatInt(id, 10)
}
srv, ok := c.srvByID[id]
if !ok || srv.Name == "" {
return strconv.FormatInt(id, 10)
}
return srv.Name
}
// Names obtains a list of available servers. It returns nil if the
// server names could not be fetched or if there are no servers.
func (c *serverClient) Names() []string {
if err := c.init(); err != nil || len(c.srvByID) == 0 {
return nil
}
names := make([]string, len(c.srvByID))
i := 0
for _, srv := range c.srvByID {
name := srv.Name
if name == "" {
name = strconv.FormatInt(srv.ID, 10)
}
names[i] = name
i++
}
return names
}
// LabelKeys returns a slice containing the keys of all labels assigned
// to the Server with the passed idOrName.
func (c *serverClient) LabelKeys(idOrName string) []string {
var srv *hcloud.Server
if err := c.init(); err != nil || len(c.srvByID) == 0 {
return nil
}
// Try to get server by ID.
if id, err := strconv.ParseInt(idOrName, 10, 64); err != nil {
srv = c.srvByID[id]
}
// If the above failed idOrName might contain a server name. If srv is not
// nil at this point and we found something in the map, someone gave their
// server a name containing the ID of another server.
if v, ok := c.srvByName[idOrName]; ok && srv == nil {
srv = v
}
if srv == nil || len(srv.Labels) == 0 {
return nil
}
return labelKeys(srv.Labels)
}
// ServerTypeNames returns a slice of all available server types.
func (c *serverClient) ServerTypeNames() []string {
sts, err := c.ServerTypes.All(context.Background())
if err != nil || len(sts) == 0 {
return nil
}
names := make([]string, len(sts))
for i, st := range sts {
names[i] = st.Name
}
return names
}
func (c *serverClient) init() error {
c.once.Do(func() {
srvs, err := c.All(context.Background())
if err != nil {
c.err = err
}
if c.err != nil || len(srvs) == 0 {
return
}
c.srvByID = make(map[int64]*hcloud.Server, len(srvs))
c.srvByName = make(map[string]*hcloud.Server, len(srvs))
for _, srv := range srvs {
c.srvByID[srv.ID] = srv
c.srvByName[srv.Name] = srv
}
})
return c.err
}
|