Upclapi/servers.go
2021-08-28 14:45:05 +01:00

306 lines
9.3 KiB
Go

package main
import (
"errors"
"fmt"
// "log"
"os"
"time"
// "strings"
"encoding/json"
"github.com/UpCloudLtd/upcloud-go-api/upcloud"
"github.com/UpCloudLtd/upcloud-go-api/upcloud/request"
"github.com/UpCloudLtd/upcloud-go-api/upcloud/service"
// "gocloud.dev/server"
// "gocloud.dev/server"
// "github.com/davecgh/go-spew/spew"
)
func createServer(s *service.Service, datacfg *DataConfig,sshkeys request.SSHKeySlice) error {
fmt.Println("Creating servers ...")
//fmt.Fprintf(os.Stdout, "%#v\n",sshkeys)
//fmt.Printf("%+v\n",datacfg) // Print with Variable Name
// fmt.Printf("Created server: %#v\n", details)
servers, _ := s.GetServers()
for _,srv := range datacfg.Servers {
alreadyExists := false
for _, server := range servers.Servers {
if server.Hostname == srv.Hostname {
alreadyExists = true
break
}
}
// Networking: setNetworkInterfaces(datacfg),
title := fmt.Sprintf("%s %s", srv.Hostname, srv.Title)
if alreadyExists {
fmt.Fprintf(os.Stderr, "Already exists server: %s\n", title)
continue
}
fmt.Printf("server: %s\n", title)
var srv_sshkeys request.SSHKeySlice
if len(srv_sshkeys) == 0 && len(sshkeys) > 0 {
srv_sshkeys = sshkeys
} else {
srv_sshkeys = srv.LoginUser.SSHKeys
}
details, err := s.CreateServer(&request.CreateServerRequest{
Hostname: srv.Hostname,
Title: title, // fmt.Sprintf("example-cli-server-%04d", rand.Int31n(1000)),
Zone: srv.Zone,
Plan: srv.Plan,
Metadata: srv.Metadata,
TimeZone: srv.TimeZone,
StorageDevices: getStorageDevices(srv),
Networking: &request.CreateServerNetworking{
Interfaces: getNetworkInterfaces(srv),
},
LoginUser: &request.LoginUser{
SSHKeys: srv_sshkeys,
},
UserData: srv.UserData,
})
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to create server: %#v\n", err)
return err
}
// spew.Println(details)
if len(details.UUID) == 0 {
fmt.Fprintf(os.Stderr, "UUID missing")
return errors.New("UUID too short")
}
details, err = s.WaitForServerState(&request.WaitForServerStateRequest{
UUID: details.UUID,
DesiredState: upcloud.ServerStateStarted,
Timeout: 1 * time.Minute,
})
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to wait for server: %#v", err)
return err
}
fmt.Printf("Created server: %#v\n", details)
fixStorageDevices(s,srv,details,"size")
addTagsToId(s,details.UUID,srv.Tags)
}
return nil
}
func modifyServer(s *service.Service,srvrCfg ServerConfig, serverDetails *upcloud.ServerDetails, targetPlan string) error {
title := fmt.Sprintf("%s %s", serverDetails.Hostname, serverDetails.Title)
fmt.Printf("Modify server %s ...\n",title)
if serverDetails.Plan == targetPlan {
fmt.Printf("%s == %s\n",serverDetails.Plan, targetPlan)
return nil
}
if serverDetails.State != upcloud.ServerStateStopped {
err := stopOneServer(s, serverDetails.Server)
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to stop server %#v: %#v\n", serverDetails.UUID, err)
return err
}
}
details,err := s.WaitForServerState(&request.WaitForServerStateRequest{
UUID: serverDetails.UUID,
DesiredState: upcloud.ServerStateStopped,
Timeout: 1 * time.Minute,
})
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to wait for server: %#v", err)
return err
}
fmt.Fprintf(os.Stderr, "Modify server after to: %s\n", targetPlan)
details, err = s.ModifyServer(&request.ModifyServerRequest{
UUID: serverDetails.UUID,
Plan: targetPlan,
})
fmt.Printf("Modify server done: %#v %#v\n", details, err)
// if err != nil {
// } else {
// fmt.Fprintf(os.Stderr, "Failed to modify server: %#v", err)
// // return err
// }
fmt.Fprintf(os.Stderr, "Start server after modify: %s\n", title)
info,err := s.GetServerDetails(&request.GetServerDetailsRequest{
UUID: serverDetails.UUID,
})
if info.State != upcloud.ServerStateStarted {
err = startOneServer(s, info.Server)
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to start server %#v: %#v\n", serverDetails.UUID, err)
return err
}
}
return nil
}
func waitForState(s *service.Service, server upcloud.Server, desiredState string) error {
_, err := s.WaitForServerState(&request.WaitForServerStateRequest{
UUID: server.UUID,
DesiredState: desiredState,
Timeout: 1 * time.Minute,
})
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to wait for server to reach desired state: %#v", err)
return err
}
return nil
}
func startOneServer(s *service.Service, server upcloud.Server) error {
fmt.Printf("Starting %s (%s) ... \n", server.Hostname, server.UUID)
if server.State == upcloud.ServerStateStopped {
fmt.Printf("Server %s (%s) is stopped. Starting\n", server.Title, server.UUID)
}
_, err := s.StartServer(&request.StartServerRequest{
UUID: server.UUID,
// StopType: request.ServerStopTypeHard,
})
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to start server: %#v\n", err)
return err
}
err = waitForState(s,server,upcloud.ServerStateStarted)
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to start state server: %#v\n", err)
return err
}
fmt.Printf("Successfully started %s (%s)\n", server.Title, server.UUID)
return nil
}
func restarOneServer(s *service.Service, server upcloud.Server) error {
fmt.Printf("Restarting %s (%s) ... \n", server.Hostname, server.UUID)
_, err := s.RestartServer(&request.RestartServerRequest{
UUID: server.UUID,
StopType: request.ServerStopTypeHard,
})
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to restart server: %#v\n", err)
return err
}
err = waitForState(s,server,upcloud.ServerStateStarted)
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to restart state server: %#v\n", err)
return err
}
fmt.Printf("Successfully restarted %s (%s)\n", server.Title, server.UUID)
return nil
}
func stopOneServer(s *service.Service, server upcloud.Server) error {
fmt.Printf("Stopping %s (%s) ... \n", server.Hostname, server.UUID)
if server.State != upcloud.ServerStateStopped {
// fmt.Printf("Server %s (%s) is not stopped. Stopping\n", server.Title, server.UUID)
_, err := s.StopServer(&request.StopServerRequest{
UUID: server.UUID,
StopType: request.ServerStopTypeHard,
})
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to stop server: %#v\n", err)
return err
}
err = waitForState(s,server,upcloud.ServerStateStopped)
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to stop state server: %#v\n", err)
return err
}
fmt.Printf("Successfully stopped %s (%s)\n", server.Title, server.UUID)
}
return nil
}
func deleteOneServer(s *service.Service, server upcloud.Server, keepStorage string) error {
err := stopOneServer(s,server)
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to stop server: %#v\n", err)
return err
}
if keepStorage != "keep" {
fmt.Printf("Deleting %s (%s) with storage\n", server.Title, server.UUID)
err = s.DeleteServerAndStorages(&request.DeleteServerAndStoragesRequest{
UUID: server.UUID,
})
} else {
fmt.Printf("Deleting %s (%s) keep storage\n", server.Title, server.UUID)
err = s.DeleteServer(&request.DeleteServerRequest{
UUID: server.UUID,
})
}
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to delete server: %#v\n", err)
return err
}
fmt.Printf("Successfully deleted %s (%s)\n", server.Title, server.UUID)
return nil
}
func detailsOneServer(s *service.Service, server upcloud.Server, dataprices DataPrices) error {
info,err := s.GetServerDetails(&request.GetServerDetailsRequest{
UUID: server.UUID,
})
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to get details from server %#v: %#v\n", server.UUID, err)
return err
}
// price,err_price:= priceResource(s,server.Zone,fmt.Sprintf("server_plan_%s",server.Plan))
price,err_price:= dataPriceResource(s,dataprices,server.Zone,fmt.Sprintf("server_plan_%s",server.Plan))
if err_price != nil {
fmt.Fprintf(os.Stderr, "Unable to get price info from server %#v: %#v\n", server.UUID, err_price)
return err
}
info_server := &InfoServer{info: *info, price: *price}
// c, err := json.Marshal(info_server)
// if err != nil {
// fmt.Println("error:", err)
// }
// os.Stdout.Write(c)
enc := json.NewEncoder(os.Stdout)
enc.Encode(info_server)
// enc.Encode(price)
/*
i,_ := json.Marshal(info)
p,_ := json.Marshal(price)
fmt.Printf("info %s \n", i)
fmt.Printf("price %s \n", p)
jsonData := []byte(`{"pric": "Value"}`)
// info_server := &v{info: fmt.Sprintf("%s",i) , price: fmt.Sprintf("%s",p)}
info_server := InfoServerPrice{info: "HOLA", price: "$$$" }
// v := struct {
// info upcloud.ServerDetails `json:"upcloud.ServerDetails"`
// price upcloud.Price `json:"upcloud.Price"`
// }{}
fmt.Printf("InfoServer %#v\n", info_server)
enc := json.NewEncoder(os.Stdout)
enc.Encode(info_server)
// b,err_un := json.Marshal(info_server) // json.Marshal(info_server)
// if err_un != nil {
// fmt.Fprintf(os.Stderr, "Unable to marshall: %#v\n", err_un)
// return err_un
// }
// os.Stdout.Write(b)
type ColorGroup struct {
ID int
Name string
Colors []string
}
group := ColorGroup{
ID: 1,
Name: "Reds",
Colors: []string{"Crimson", "Red", "Ruby", "Maroon"},
}
c, err := json.Marshal(group)
if err != nil {
fmt.Println("error:", err)
}
os.Stdout.Write(c)
// err_en := enc.Encode(info_server)
// if err_en != nil {
// fmt.Fprintf(os.Stderr, "Unable to encode info_server: %#v\n", err_en)
// return err_en
// }
// fmt.Printf("InfoServer %#v\n", info)
*/
return nil
}