package internal import ( "context" "errors" "fmt" "net" "github.com/hetznercloud/hcloud-go/hcloud" log "github.com/sirupsen/logrus" ) func GetSpeakableNodes(cfg *Config) ([]string, error) { client := hcloud.NewClient(hcloud.WithToken(cfg.HcloudToken)) server, _, err := client.Server.List(context.TODO(), hcloud.ServerListOpts{ ListOpts: hcloud.ListOpts{ LabelSelector: cfg.LabelSelector, }}) if err != nil { return nil, errors.New(fmt.Sprintf("Error listing Hetzner Nodes: %s", err.Error())) } ips := make([]string, len(server)) if server != nil { for i, instance := range server { log.WithFields(log.Fields{ "Caller": "GetSpeakableNodes", }).Info(fmt.Sprintf("Found IP: %s", instance.PrivateNet[0].IP.String())) ips[i] = instance.PrivateNet[0].IP.String() } } else { return nil, errors.New(fmt.Sprintf("No Nodes found with label selector: %s", cfg.LabelSelector)) } return ips, nil } func GetNodeID(cfg *Config, ip string) (hcloud.Server, error) { // get can only be done via name or id: https://pkg.go.dev/github.com/hetznercloud/hcloud-go/v2/hcloud#ServerClient.Get // we can iterate over all nodes and select the one that matches the IP we know from speaker: https://pkg.go.dev/github.com/hetznercloud/hcloud-go/v2/hcloud#ServerClient.List client := hcloud.NewClient(hcloud.WithToken(cfg.HcloudToken)) serverList, _, err := client.Server.List(context.TODO(), hcloud.ServerListOpts{ ListOpts: hcloud.ListOpts{ Page: 1, PerPage: 100, }, Status: []hcloud.ServerStatus{hcloud.ServerStatusRunning}, }) if err != nil { return hcloud.Server{}, errors.New(fmt.Sprintf("Could not get Server List from Hetzner: %s", err.Error())) } for _, server := range serverList { log.WithFields(log.Fields{ "Caller": "GetNodeID", }).Info(fmt.Sprintf("Checking Node %d for announcing IP", server.ID)) if server.PublicNet.IPv4.IP.Equal(net.ParseIP(ip)) { log.WithFields(log.Fields{ "Caller": "GetNodeID", }).Info(fmt.Sprintf("Match on Node %d", server.ID)) return *server, nil } for _, network := range server.PrivateNet { if network.IP.Equal(net.ParseIP(ip)) { log.WithFields(log.Fields{ "Caller": "GetNodeID", }).Info(fmt.Sprintf("Match on Node %d", server.ID)) return *server, nil } } } return hcloud.Server{}, errors.New(fmt.Sprintf("Could not find correct server")) } func AttachFloatingIpToNode(cfg *Config, server hcloud.Server) error { // get floating ip by name. name can be set to config https://github.com/hetznercloud/hcloud-go/blob/v2.3.0/hcloud/floating_ip.go#L117 client := hcloud.NewClient(hcloud.WithToken(cfg.HcloudToken)) floatingIP, _, err := client.FloatingIP.GetByName(context.TODO(), cfg.FloatingIPName) if err != nil { return errors.New(fmt.Sprintf("Could not find Floating IP by name: %s", err.Error())) } if floatingIP.Server.ID == server.ID { log.WithFields(log.Fields{ "Caller": "AttachFloatingIpToNode", }).Info(fmt.Sprintf("Floating IP %s already assigned to Node %s", cfg.FloatingIPName, server.Name)) return nil } _, _, err = client.FloatingIP.Assign(context.TODO(), floatingIP, &server) if err != nil { log.WithFields(log.Fields{ "Caller": "AttachFloatingIpToNode", }).Error(fmt.Sprintf("Error response while attaching floating ip: %s", err.Error())) } log.WithFields(log.Fields{ "Caller": "AttachFloatingIpToNode", }).Info(fmt.Sprintf("Attached floating ip %s to node %s", cfg.FloatingIPName, server.Name)) return err }