167 lines
4.2 KiB
Go
167 lines
4.2 KiB
Go
package hetzner
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.stinnesbeck.com/go/log"
|
|
"github.com/hetznercloud/hcloud-go/hcloud"
|
|
)
|
|
|
|
func connect() *hcloud.Client {
|
|
token := os.Getenv("HCLOUD_API_TOKEN")
|
|
if token == "" {
|
|
log.PrintError("please specify HCLOUD_API_TOKEN")
|
|
os.Exit(1)
|
|
}
|
|
return hcloud.NewClient(hcloud.WithToken(token))
|
|
}
|
|
|
|
func GetNewSuffix(servers []*hcloud.Server) (int, error) {
|
|
// cop out if there are no servers yet
|
|
if len(servers) == 0 {
|
|
return 1, nil
|
|
}
|
|
|
|
// variable to hold highest number
|
|
var highestNumber int
|
|
|
|
// loop through all servers
|
|
for i := range servers {
|
|
serverNameSlice := strings.Split(servers[i].Name, "-")
|
|
suffix, err := strconv.Atoi(serverNameSlice[len(serverNameSlice)-1])
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
// compare our current number agains the highest yet
|
|
if suffix > highestNumber {
|
|
highestNumber = suffix
|
|
}
|
|
}
|
|
// return one number higher than highest number
|
|
return highestNumber + 1, nil
|
|
}
|
|
|
|
// ListJynxServers lists all servers managed by Jynx hosted on Hetzner Cloud
|
|
func ListJynxServers(prefix string) ([]*hcloud.Server, error) {
|
|
// connect to the hcloud API
|
|
client := connect()
|
|
|
|
// get all servers
|
|
servers, err := client.Server.All(context.Background())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// create object that holds all servers managed by Jynx
|
|
var jynxServers []*hcloud.Server
|
|
|
|
// loop through servers and filter out managed servers
|
|
for _, server := range servers {
|
|
if strings.HasPrefix(server.Name, prefix) {
|
|
jynxServers = append(jynxServers, server)
|
|
}
|
|
}
|
|
|
|
// return managed servers
|
|
return jynxServers, nil
|
|
}
|
|
|
|
func CheckServerDeletions(servers []*hcloud.Server) error {
|
|
interval := os.Getenv("SCALER_POLL_INTERVAL")
|
|
if interval == "" {
|
|
interval = "5"
|
|
}
|
|
|
|
pollIntervalSeconds, err := strconv.Atoi(interval)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if pollIntervalSeconds < 60 {
|
|
pollIntervalSeconds = 60
|
|
}
|
|
|
|
if pollIntervalSeconds > 3600 {
|
|
pollIntervalSeconds %= 3600
|
|
}
|
|
|
|
for _, server := range servers {
|
|
safeInterval := time.Duration(3600-pollIntervalSeconds) * time.Second
|
|
optimalDeleteTime := server.Created.Add(safeInterval).Local()
|
|
log.PrintDebug(server.Name, "optimal delete time:", optimalDeleteTime)
|
|
if time.Now().Local().Before(optimalDeleteTime) {
|
|
continue
|
|
}
|
|
|
|
// optimal delete time has passed, delete the server
|
|
if err := DeleteServer(server); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func DeleteServer(server *hcloud.Server) error {
|
|
client := connect()
|
|
log.PrintInfo("Deleting", server.Name)
|
|
result, response, err := client.Server.DeleteWithResult(context.Background(), server)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
log.PrintWarning(result.Action.Status)
|
|
log.PrintWarning(response.StatusCode)
|
|
return nil
|
|
}
|
|
func CreateServers(servers []string) error {
|
|
// connect to hcloud API
|
|
client := connect()
|
|
|
|
// read in some environment variables
|
|
woodpeckerHost := os.Getenv("WOODPECKER_HOSTNAME")
|
|
agentSecret := os.Getenv("WOODPECKER_AGENT_SECRET")
|
|
|
|
// loop through each server
|
|
for _, server := range servers {
|
|
// create unique AgentCMD for cloud init
|
|
AgentCMD := fmt.Sprintf("docker run -d -v /var/run/docker.sock:/var/run/docker.sock -e WOODPECKER_GRPC_SECURE=false -e WOODPECKER_SERVER=%s -e WOODPECKER_AGENT_SECRET=%s -e WOODPECKER_MAX_PROCS=%d -e WOODPECKER_HOSTNAME=%s woodpeckerci/woodpecker-agent", woodpeckerHost, agentSecret, 1, server)
|
|
|
|
userdata := fmt.Sprintf("#cloud-config\nruncmd:\n - %s", AgentCMD)
|
|
labels := make(map[string]string)
|
|
labels["created_by"] = "jynx"
|
|
labels["created"] = fmt.Sprintf("%d", time.Now().Unix())
|
|
|
|
var sshkeys []*hcloud.SSHKey
|
|
|
|
sshkeys, err := getSSHKeys("stefan", "nils")
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
serverOpts := hcloud.ServerCreateOpts{
|
|
Name: server,
|
|
StartAfterCreate: hcloud.Ptr(true),
|
|
SSHKeys: sshkeys,
|
|
Image: &hcloud.Image{Name: "docker-ce"},
|
|
ServerType: &hcloud.ServerType{Name: "cax11"},
|
|
Location: &hcloud.Location{Name: "fsn1"},
|
|
UserData: userdata,
|
|
PublicNet: &hcloud.ServerCreatePublicNet{EnableIPv4: true},
|
|
Labels: labels,
|
|
}
|
|
_, _, err = client.Server.Create(context.Background(), serverOpts)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|