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
|
package hcapi2
import (
"context"
"strconv"
"sync"
"github.com/hetznercloud/hcloud-go/v2/hcloud"
)
// NetworkClient embeds the Hetzner Cloud Network client and provides some
// additional helper functions.
type NetworkClient interface {
NetworkClientBase
Names() []string
Name(int64) string
LabelKeys(string) []string
}
func NewNetworkClient(client NetworkClientBase) NetworkClient {
return &networkClient{
NetworkClientBase: client,
}
}
type networkClient struct {
NetworkClientBase
netsByID map[int64]*hcloud.Network
netsByName map[string]*hcloud.Network
once sync.Once
err error
}
// Name obtains the name of the network with id. If the name could not
// be fetched it returns the value id converted to a string.
func (c *networkClient) Name(id int64) string {
if err := c.init(); err != nil {
return strconv.FormatInt(id, 10)
}
net, ok := c.netsByID[id]
if !ok || net.Name == "" {
return strconv.FormatInt(id, 10)
}
return net.Name
}
// Names obtains a list of available networks. It returns nil if the
// network names could not be fetched or if there are no networks.
func (c *networkClient) Names() []string {
if err := c.init(); err != nil || len(c.netsByID) == 0 {
return nil
}
names := make([]string, len(c.netsByID))
i := 0
for _, net := range c.netsByID {
name := net.Name
if name == "" {
name = strconv.FormatInt(net.ID, 10)
}
names[i] = name
i++
}
return names
}
// LabelKeys returns a slice containing the keys of all labels assigned
// to the Network with the passed idOrName.
func (c *networkClient) LabelKeys(idOrName string) []string {
var net *hcloud.Network
if err := c.init(); err != nil || len(c.netsByID) == 0 {
return nil
}
if id, err := strconv.ParseInt(idOrName, 10, 64); err != nil {
net = c.netsByID[id]
}
if v, ok := c.netsByName[idOrName]; ok && net == nil {
net = v
}
if net == nil || len(net.Labels) == 0 {
return nil
}
return labelKeys(net.Labels)
}
func (c *networkClient) init() error {
c.once.Do(func() {
nets, err := c.All(context.Background())
if err != nil {
c.err = err
}
if c.err != nil || len(nets) == 0 {
return
}
c.netsByID = make(map[int64]*hcloud.Network, len(nets))
c.netsByName = make(map[string]*hcloud.Network, len(nets))
for _, net := range nets {
c.netsByID[net.ID] = net
c.netsByName[net.Name] = net
}
})
return c.err
}
|