281 lines
8.4 KiB
Go
281 lines
8.4 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/UpCloudLtd/upcloud-go-api/upcloud"
|
|
"github.com/UpCloudLtd/upcloud-go-api/upcloud/request"
|
|
"github.com/UpCloudLtd/upcloud-go-api/upcloud/service"
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
func NewStoreConfig(dataPath string) (*StoreConfig, error) {
|
|
// Create config structure
|
|
storeConfig := &StoreConfig{}
|
|
|
|
// Open config file
|
|
file, err := os.Open(dataPath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer file.Close()
|
|
|
|
// Init new YAML decode
|
|
d := yaml.NewDecoder(file)
|
|
|
|
// Start YAML decoding from file
|
|
if err := d.Decode(&storeConfig); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return storeConfig, nil
|
|
}
|
|
|
|
func loadStoreConfig(dataCfgPath string) (*StoreConfig, error) {
|
|
// datacfg := &DataConfig{}
|
|
storecfg, err := NewStoreConfig(dataCfgPath)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
return storecfg, err
|
|
}
|
|
return storecfg, nil
|
|
}
|
|
|
|
func getStorageDevices(srv ServerConfig) []request.CreateServerStorageDevice {
|
|
var storageDevices []request.CreateServerStorageDevice
|
|
for _,storage := range srv.StorageDevices {
|
|
storageDevices = append(storageDevices,request.CreateServerStorageDevice{
|
|
Action : storage.Action,
|
|
Title : storage.Title,
|
|
Storage : storage.Storage,
|
|
Size : storage.Size,
|
|
Tier : storage.Tier,
|
|
})
|
|
}
|
|
return storageDevices
|
|
}
|
|
func deleteStorage(s *service.Service, uuid string) error {
|
|
fmt.Println("Getting storage")
|
|
storages, err := s.GetStorages(&request.GetStoragesRequest{
|
|
Access: upcloud.StorageAccessPrivate,
|
|
})
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Unable to get storages: %#v\n", err)
|
|
return err
|
|
}
|
|
fmt.Printf("Retrieved %d storages\n", len(storages.Storages))
|
|
if len(storages.Storages) > 0 {
|
|
for _, storage := range storages.Storages {
|
|
if storage.UUID == uuid {
|
|
fmt.Printf("Deleting storage %s", storage.UUID)
|
|
err := errors.New("Dummy")
|
|
for i := 0; err != nil && i < 5; i++ {
|
|
fmt.Printf("%d: Deleting %s (%s)\n", i, storage.Title, storage.UUID)
|
|
err = s.DeleteStorage(&request.DeleteStorageRequest{
|
|
UUID: storage.UUID,
|
|
})
|
|
}
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Unable to delete storage: %#v (%s)\n", err, err.Error())
|
|
return err
|
|
}
|
|
|
|
fmt.Printf("Successfully deleted %s (%s)\n", storage.Title, storage.UUID)
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
func modifyStorage(s *service.Service, storecfg *StoreConfig) error {
|
|
if len(storecfg.Uuid) == 0 {
|
|
fmt.Printf("Unable to get storages uuid from data file \n")
|
|
return nil
|
|
}
|
|
for _, item := range storecfg.Servers {
|
|
s.StopServer(&request.StopServerRequest{
|
|
UUID: item,
|
|
StopType: request.ServerStopTypeHard,
|
|
})
|
|
}
|
|
fmt.Println("Getting storage")
|
|
storages, err := s.GetStorages(&request.GetStoragesRequest{
|
|
Access: upcloud.StorageAccessPrivate,
|
|
})
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Unable to get storages: %#v\n", err)
|
|
return err
|
|
}
|
|
fmt.Printf("Retrieved %d storages\n", len(storages.Storages))
|
|
|
|
if len(storages.Storages) > 0 {
|
|
for _, storage := range storages.Storages {
|
|
if storage.UUID == storecfg.Uuid {
|
|
fmt.Printf("Modify storage %s (%s)\n",storage.Title, storage.UUID)
|
|
err := errors.New("Dummy")
|
|
for i := 0; err != nil && i < 5; i++ {
|
|
fmt.Printf("%d: Modify %s (%s)\n", i, storage.Title, storage.UUID)
|
|
_, err = s.ModifyStorage(&request.ModifyStorageRequest{
|
|
UUID: storecfg.Uuid,
|
|
// Title: datacfg.Title,
|
|
Size: storecfg.Size,
|
|
// BackupRule *upcloud.BackupRule `json:"backup_rule,omitempty"`
|
|
})
|
|
}
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Unable to modify storage: %#v (%s)\n", err, err.Error())
|
|
// return err
|
|
}
|
|
fmt.Printf("Successfully modified %s (%s)\n", storage.Title, storage.UUID)
|
|
}
|
|
}
|
|
}
|
|
for _, item := range storecfg.Servers {
|
|
s.StartServer(&request.StartServerRequest{
|
|
UUID: item,
|
|
// StopType: request.ServerStopTypeHard,
|
|
})
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func fixStorageDevices(s *service.Service,srvrCfg ServerConfig, serverDetails *upcloud.ServerDetails, targetSize string) {
|
|
if len(serverDetails.StorageDevices) == 0 {
|
|
return
|
|
}
|
|
err := errors.New("Dummy")
|
|
// fmt.Fprintf(os.Stderr, "%#v: %#v\n", serverDetails.StorageDevices, srvrCfg)
|
|
for i, storage := range serverDetails.StorageDevices {
|
|
store_size := 0
|
|
switch targetSize {
|
|
case "size":
|
|
store_size = srvrCfg.StorageDevices[i].Size
|
|
case "part0":
|
|
s := strings.Split(srvrCfg.StorageDevices[i].PartSizes, ",")
|
|
store_size, err = strconv.Atoi(s[0])
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Unable to get partsize 0 to create image storage for %s: %#v (%s)\n", storage.Title, err, err.Error())
|
|
return
|
|
}
|
|
case "part1":
|
|
s := strings.Split(srvrCfg.StorageDevices[i].PartSizes, ",")
|
|
store_size, err = strconv.Atoi(s[1])
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Unable to get partsize 1 to create image storage for %s: %#v (%s)\n", storage.Title, err, err.Error())
|
|
return
|
|
}
|
|
case "final":
|
|
store_size = srvrCfg.StorageDevices[i].FinalSize
|
|
}
|
|
if store_size == 0 {
|
|
fmt.Printf("No targetSize found [size|final] for %s (%s) %dGB == %dGB\n",storage.Title, storage.UUID, storage.Size, store_size)
|
|
continue
|
|
}
|
|
if store_size== storage.Size {
|
|
fmt.Printf("%s (%s) %dGB == %dGB\n",storage.Title, storage.UUID, storage.Size, store_size)
|
|
continue
|
|
}
|
|
fmt.Printf("FixStorage %s (%s) %dGB to %dGB\n",storage.Title, storage.UUID, storage.Size, store_size)
|
|
if serverDetails.Server.State != upcloud.ServerStateStopped {
|
|
err = stopOneServer(s, serverDetails.Server)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Unable to stop server %#v: %#v\n", serverDetails.Server.UUID, err)
|
|
continue
|
|
}
|
|
}
|
|
_, err = s.ModifyStorage(&request.ModifyStorageRequest{
|
|
UUID: storage.UUID,
|
|
// Title: srvrCfg.StorageDevices[i].Title,
|
|
Size: store_size,
|
|
// BackupRule *upcloud.BackupRule `json:"backup_rule,omitempty"`
|
|
})
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Unable to modify storage: %#v (%s)\n", err, err.Error())
|
|
} else {
|
|
fmt.Printf("Successfully modified %s (%s) to %dGB\n", storage.Title, storage.UUID, store_size)
|
|
}
|
|
}
|
|
info,err := s.GetServerDetails(&request.GetServerDetailsRequest{
|
|
UUID: serverDetails.UUID,
|
|
})
|
|
if info.Server.State != upcloud.ServerStateStarted {
|
|
startOneServer(s, serverDetails.Server)
|
|
}
|
|
}
|
|
|
|
func createStorageImage(s *service.Service, target_uuid string, title string) error {
|
|
info,err := s.TemplatizeStorage(&request.TemplatizeStorageRequest{
|
|
UUID: target_uuid,
|
|
Title: strings.Trim(title, "\""),
|
|
})
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Unable to create image storage: %#v (%s)\n", err, err.Error())
|
|
} else {
|
|
fmt.Printf("Successfully created %s (%s)\n", title, target_uuid)
|
|
}
|
|
s.WaitForStorageState(&request.WaitForStorageStateRequest{
|
|
UUID: target_uuid,
|
|
DesiredState: "online",
|
|
Timeout: 1 * time.Minute,
|
|
})
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Failed to wait for storage to reach desired online state: %#v", err)
|
|
return err
|
|
}
|
|
enc := json.NewEncoder(os.Stdout)
|
|
enc.Encode(info)
|
|
return nil
|
|
}
|
|
func listStorages(s *service.Service, dataCfg *DataConfig, target string) error {
|
|
storages, err := s.GetStorages(&request.GetStoragesRequest{
|
|
Access: upcloud.StorageAccessPrivate,
|
|
})
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Unable to get storages: %#v\n", err)
|
|
return err
|
|
}
|
|
servers, _ := s.GetServers()
|
|
fmt.Printf("Scanning over %d storages and %d servers \n", len(storages.Storages), len(servers.Servers))
|
|
if len(storages.Storages) > 0 {
|
|
for _, storage := range storages.Storages {
|
|
storage_out := fmt.Sprintf("title: \"%s\", id: %s, size: %d, plan: %s, state: %s, zone: %s, type: %s",
|
|
storage.Title, storage.UUID, storage.Size, storage.PartOfPlan, storage.State, storage.Zone, storage.Type)
|
|
is_attached := false
|
|
for _, server := range servers.Servers {
|
|
isInGroup := false
|
|
for _, srv := range dataCfg.Servers {
|
|
if server.Hostname == srv.Hostname {
|
|
isInGroup = true
|
|
break
|
|
}
|
|
}
|
|
info,err := s.GetServerDetails(&request.GetServerDetailsRequest{
|
|
UUID: server.UUID,
|
|
})
|
|
if err == nil {
|
|
for _, srv_storage := range info.StorageDevices {
|
|
if srv_storage.UUID == storage.UUID {
|
|
is_attached=true
|
|
if isInGroup {
|
|
fmt.Printf("%s, attached: \"%s\", id: %s\n", storage_out, server.Title, server.UUID)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ! is_attached {
|
|
fmt.Printf("%s, attached: none\n", storage_out)
|
|
}
|
|
if target != "" && storage.UUID == target {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
} |