From af983acdf1e8f7fcdc73ed0a2d565097c0d652c5 Mon Sep 17 00:00:00 2001 From: Florent <florent.gluck@hesge.ch> Date: Mon, 23 Dec 2024 15:49:57 +0100 Subject: [PATCH] libclient: ongoing work on VM code --- src/client/cmdTemplate/templateDel.go | 1 - src/client/cmdVM/helper.go | 161 +++++------------- src/client/cmdVM/vmAddAccess.go | 3 +- src/client/cmdVM/vmAttachAsyncSingle.go | 31 +--- src/client/cmdVM/vmCreate.go | 23 +-- src/client/cmdVM/vmDel.go | 28 +-- src/client/cmdVM/vmDelAccess.go | 3 +- src/client/cmdVM/vmEdit.go | 3 +- src/client/cmdVM/vmExportDir.go | 5 +- src/client/cmdVM/vmImportDir.go | 6 +- src/client/cmdVM/vmList.go | 3 +- src/client/cmdVM/vmListSingle.go | 32 +--- src/client/cmdVM/vmReboot.go | 27 +-- src/client/cmdVM/vmShutdown.go | 3 +- src/client/cmdVM/vmStart.go | 3 +- src/client/cmdVM/vmStartAttach.go | 3 +- src/client/cmdVM/vmStop.go | 27 +-- src/libclient/go.mod | 4 + .../template/{helper.go => deserializer.go} | 0 .../user/{helper.go => deserializer.go} | 0 src/libclient/vm/deserializer.go | 51 ++++++ src/libclient/vm/vmAttach.go | 27 +++ src/libclient/vm/vmAttachCredentials.go | 27 +++ src/libclient/vm/vmCreate.go | 28 +++ src/libclient/vm/vmDel.go | 21 +++ src/libclient/vm/vmGet.go | 100 +++++++++++ src/libclient/vm/vmReboot.go | 21 +++ src/libclient/vm/vmStop.go | 21 +++ 28 files changed, 414 insertions(+), 248 deletions(-) rename src/libclient/template/{helper.go => deserializer.go} (100%) rename src/libclient/user/{helper.go => deserializer.go} (100%) create mode 100644 src/libclient/vm/deserializer.go create mode 100644 src/libclient/vm/vmAttach.go create mode 100644 src/libclient/vm/vmAttachCredentials.go create mode 100644 src/libclient/vm/vmCreate.go create mode 100644 src/libclient/vm/vmDel.go create mode 100644 src/libclient/vm/vmGet.go create mode 100644 src/libclient/vm/vmReboot.go create mode 100644 src/libclient/vm/vmStop.go diff --git a/src/client/cmdTemplate/templateDel.go b/src/client/cmdTemplate/templateDel.go index feb619d..b6522fe 100644 --- a/src/client/cmdTemplate/templateDel.go +++ b/src/client/cmdTemplate/templateDel.go @@ -37,7 +37,6 @@ func (cmd *Del) Run(args []string) int { } tplID := args[0] - err := libclient.TemplateDel(tplID) if err != nil { u.PrintlnErr(err) diff --git a/src/client/cmdVM/helper.go b/src/client/cmdVM/helper.go index 5ffd553..a20df13 100644 --- a/src/client/cmdVM/helper.go +++ b/src/client/cmdVM/helper.go @@ -1,20 +1,19 @@ package cmdVM import ( - "encoding/json" "errors" "nexus-client/cmd" u "nexus-client/utils" "nexus-common/vm" - g "nexus-libclient/globals" + libclient "nexus-libclient/vm" "regexp" "strings" - "github.com/go-playground/validator/v10" - "github.com/go-resty/resty/v2" "github.com/google/uuid" ) +type GetVMs func() ([]vm.VMNetworkSerialized, error) + func printRegexUsage(c cmd.Command) { for _, desc := range c.GetDesc() { u.PrintlnErr(desc) @@ -34,7 +33,7 @@ Regex examples: u.PrintlnErr(usage) } -// Returns a list of filtered VMs for a given route. +// Returns a list of filtered VMs based on a regex. // Filters are based on patterns describing IDs or regexes. // Patterns can either be: // - any number of "VM IDs" (UUID) @@ -46,14 +45,11 @@ Regex examples: // // "." -> matches everything // "bla" -> matches any VM name containing "bla" -func getFilteredVMs(route string, patterns []string) ([]vm.VMNetworkSerialized, error) { +func getFilteredVMs(filteredVMsFunc GetVMs, patterns []string) ([]vm.VMNetworkSerialized, error) { if len(patterns) < 1 { return nil, errors.New("At least one ID or regex must be specified") } - client := g.GetInstance().Client - host := g.GetInstance().Host - var ids []string var regexes []string @@ -66,47 +62,38 @@ func getFilteredVMs(route string, patterns []string) ([]vm.VMNetworkSerialized, } } - resp, err := client.R().Get(host + route) + vms, err := filteredVMsFunc() if err != nil { return nil, err } - vmsList := []vm.VMNetworkSerialized{} + filteredVMs := []vm.VMNetworkSerialized{} - if resp.IsSuccess() { - vms, err := deserializeVMs(resp) - if err != nil { - return nil, err + for _, vm := range vms { + found := false + for _, id := range ids { + if id == vm.ID.String() { + filteredVMs = append(filteredVMs, vm) + found = true + break + } } - - for _, vm := range vms { - found := false - for _, id := range ids { - if id == vm.ID.String() { - vmsList = append(vmsList, vm) - found = true + if found { + continue + } + for _, regex := range regexes { + match, err := regexp.MatchString(strings.ToLower(regex), strings.ToLower(vm.Name)) + if err != nil { + return nil, errors.New("Error matching \"" + regex + "\": " + err.Error()) + } else { + if match { + filteredVMs = append(filteredVMs, vm) break } } - if found { - continue - } - for _, regex := range regexes { - match, err := regexp.MatchString(strings.ToLower(regex), strings.ToLower(vm.Name)) - if err != nil { - return nil, errors.New("Error matching \"" + regex + "\": " + err.Error()) - } else { - if match { - vmsList = append(vmsList, vm) - break - } - } - } } - return vmsList, nil - } else { - return nil, errors.New(resp.Status() + ": " + resp.String()) } + return filteredVMs, nil } // Returns a list of filtered VM credentials for a given route. @@ -126,9 +113,6 @@ func getFilteredVMCredentials(route string, patterns []string) ([]vm.VMAttachCre return nil, errors.New("At least one ID or regex must be specified") } - client := g.GetInstance().Client - host := g.GetInstance().Host - var ids []string var regexes []string @@ -141,87 +125,36 @@ func getFilteredVMCredentials(route string, patterns []string) ([]vm.VMAttachCre } } - resp, err := client.R().Get(host + route) + vmAttachCreds, err := libclient.GetVMAttachCredentials() if err != nil { return nil, err } - vmsList := []vm.VMAttachCredentialsSerialized{} + filteredVMAttachCreds := []vm.VMAttachCredentialsSerialized{} - if resp.IsSuccess() { - vms, err := deserializeVMsCredentials(resp) - if err != nil { - return nil, err + for _, vm := range vmAttachCreds { + found := false + for _, id := range ids { + if id == vm.ID.String() { + filteredVMAttachCreds = append(filteredVMAttachCreds, vm) + found = true + break + } } - - for _, vm := range vms { - found := false - for _, id := range ids { - if id == vm.ID.String() { - vmsList = append(vmsList, vm) - found = true + if found { + continue + } + for _, regex := range regexes { + match, err := regexp.MatchString(strings.ToLower(regex), strings.ToLower(vm.Name)) + if err != nil { + return nil, errors.New("Error matching \"" + regex + "\": " + err.Error()) + } else { + if match { + filteredVMAttachCreds = append(filteredVMAttachCreds, vm) break } } - if found { - continue - } - for _, regex := range regexes { - match, err := regexp.MatchString(strings.ToLower(regex), strings.ToLower(vm.Name)) - if err != nil { - return nil, errors.New("Error matching \"" + regex + "\": " + err.Error()) - } else { - if match { - vmsList = append(vmsList, vm) - break - } - } - } } - return vmsList, nil - } else { - return nil, errors.New(resp.Status() + ": " + resp.String()) - } -} - -// Deserialize a list of VMs from an http response. -func deserializeVMs(resp *resty.Response) ([]vm.VMNetworkSerialized, error) { - vms := []vm.VMNetworkSerialized{} - if err := json.Unmarshal(resp.Body(), &vms); err != nil { - return nil, err - } - return vms, nil -} - -// Deserialize a single VM from an http response. -func deserializeVM(resp *resty.Response) (*vm.VMNetworkSerialized, error) { - var vm *vm.VMNetworkSerialized = &vm.VMNetworkSerialized{} - if err := json.Unmarshal(resp.Body(), vm); err != nil { - return vm, err - } - if err := validator.New(validator.WithRequiredStructEnabled()).Struct(vm); err != nil { - return nil, err - } - return vm, nil -} - -// Deserialize a list of VM credentials from an http response. -func deserializeVMsCredentials(resp *resty.Response) ([]vm.VMAttachCredentialsSerialized, error) { - vmsCreds := []vm.VMAttachCredentialsSerialized{} - if err := json.Unmarshal(resp.Body(), &vmsCreds); err != nil { - return nil, err - } - return vmsCreds, nil -} - -// Deserialize a VM credentials from an http response. -func deserializeVMCredentials(resp *resty.Response) (*vm.VMAttachCredentialsSerialized, error) { - var vmCreds vm.VMAttachCredentialsSerialized - if err := json.Unmarshal(resp.Body(), &vmCreds); err != nil { - return nil, err - } - if err := validator.New(validator.WithRequiredStructEnabled()).Struct(vmCreds); err != nil { - return nil, err } - return &vmCreds, nil + return filteredVMAttachCreds, nil } diff --git a/src/client/cmdVM/vmAddAccess.go b/src/client/cmdVM/vmAddAccess.go index d53c59d..f5a9f13 100644 --- a/src/client/cmdVM/vmAddAccess.go +++ b/src/client/cmdVM/vmAddAccess.go @@ -9,6 +9,7 @@ import ( "nexus-common/caps" "nexus-common/params" g "nexus-libclient/globals" + libclient "nexus-libclient/vm" "os" "strings" ) @@ -138,7 +139,7 @@ func (cmd *AddAccess) Run(args []string) int { return 1 } - vms, err := getFilteredVMs("/vms/editaccess", patterns) + vms, err := getFilteredVMs(libclient.GetEditAccessVMs, patterns) if err != nil { u.PrintlnErr(err.Error()) return 1 diff --git a/src/client/cmdVM/vmAttachAsyncSingle.go b/src/client/cmdVM/vmAttachAsyncSingle.go index f088d1e..0f2a5f2 100644 --- a/src/client/cmdVM/vmAttachAsyncSingle.go +++ b/src/client/cmdVM/vmAttachAsyncSingle.go @@ -4,7 +4,7 @@ import ( "nexus-client/exec" u "nexus-client/utils" "nexus-common/vm" - g "nexus-libclient/globals" + libclient "nexus-libclient/vm" ) type AttachAsyncSingle struct { @@ -42,31 +42,18 @@ func (cmd *AttachAsyncSingle) Run(args []string) int { return 1 } - client := g.GetInstance().Client - host := g.GetInstance().Host - vmID := args[0] - resp, err := client.R().Get(host + "/vms/" + vmID + "/attach") + + creds, err := libclient.VMAttach(vmID) if err != nil { u.PrintlnErr("Failed retrieving VM credentials for VM \"" + vmID + "\": " + err.Error()) return 1 - } else { - if resp.IsSuccess() { - creds, err := deserializeVMCredentials(resp) - if err != nil { - u.PrintlnErr("Failed retrieving server's response: " + err.Error()) - return 1 - } - statusCode, err := AttachToVMs([]vm.VMAttachCredentialsSerialized{*creds}, false) - if err != nil { - u.PrintlnErr(err) - } - return statusCode - } else { - u.PrintlnErr("Failed retrieving VM credentials for VM \"" + vmID + "\": " + resp.Status() + ": " + resp.String()) - return 1 - } } - return 0 + statusCode, err := AttachToVMs([]vm.VMAttachCredentialsSerialized{*creds}, false) + if err != nil { + u.PrintlnErr(err) + return 1 + } + return statusCode } diff --git a/src/client/cmdVM/vmCreate.go b/src/client/cmdVM/vmCreate.go index 38198dc..073a453 100644 --- a/src/client/cmdVM/vmCreate.go +++ b/src/client/cmdVM/vmCreate.go @@ -5,7 +5,7 @@ import ( u "nexus-client/utils" "nexus-common/params" "nexus-common/vm" - g "nexus-libclient/globals" + libclient "nexus-libclient/vm" "strconv" "github.com/google/uuid" @@ -49,9 +49,6 @@ file.csv 1-column CSV file defining the students names. } func (cmd *Create) Run(args []string) int { - client := g.GetInstance().Client - host := g.GetInstance().Host - argc := len(args) if argc < 6 || argc > 7 { cmd.PrintUsage() @@ -103,7 +100,7 @@ func (cmd *Create) Run(args []string) int { // if csvFile == "" -> we must create count VMs // otherwise -> we parse the CSV to know how many VMs to create - vmArgs := ¶ms.VMCreate{ + vmArgs := params.VMCreate{ Name: name, Cpus: ncpus, Ram: ram, @@ -125,22 +122,12 @@ func (cmd *Create) Run(args []string) int { vmArgs.Name = name + " " + csvEntries[i-1] } - resp, err := client.R().SetBody(vmArgs).Post(host + "/vms") + vm, err := libclient.VMCreate(vmArgs) if err != nil { - u.PrintlnErr("Failed creating VM \"" + vmArgs.Name + "\": " + err.Error()) + u.PrintlnErr(err) statusCode = 1 } else { - if resp.IsSuccess() { - vm, err := deserializeVM(resp) - if err != nil { - u.PrintlnErr("Failed retrieving server's response: " + err.Error()) - statusCode = 1 - } - u.Println("Created VM \"" + vm.Name + "\" | " + vm.ID.String()) - } else { - u.PrintlnErr("Failed creating VM \"" + vmArgs.Name + "\": " + resp.Status() + ": " + resp.String()) - statusCode = 1 - } + u.Println("Created VM \"" + vm.Name + "\" | " + vm.ID.String()) } } diff --git a/src/client/cmdVM/vmDel.go b/src/client/cmdVM/vmDel.go index 5251c0f..68caed1 100644 --- a/src/client/cmdVM/vmDel.go +++ b/src/client/cmdVM/vmDel.go @@ -2,7 +2,7 @@ package cmdVM import ( u "nexus-client/utils" - g "nexus-libclient/globals" + libclient "nexus-libclient/vm" ) type Del struct { @@ -25,16 +25,13 @@ func (cmd *Del) PrintUsage() { } func (cmd *Del) Run(args []string) int { - client := g.GetInstance().Client - host := g.GetInstance().Host - argc := len(args) if argc < 1 { cmd.PrintUsage() return 1 } - vms, err := getFilteredVMs("/vms/del", args) + vms, err := getFilteredVMs(libclient.GetDelVMs, args) if err != nil { u.PrintlnErr(err.Error()) return 1 @@ -45,24 +42,15 @@ func (cmd *Del) Run(args []string) int { return 1 } - statusCode := 0 - for _, vm := range vms { - uuid := vm.ID.String() - resp, err := client.R().Delete(host + "/vms/" + uuid) + + err := libclient.VMDel(vm.ID.String()) if err != nil { - u.PrintlnErr("Failed deleting VM \"" + vm.Name + "\": " + err.Error()) - statusCode = 1 - } else { - if resp.IsSuccess() { - u.Println("Deleted VM \"" + vm.Name + "\"") - } else { - u.PrintlnErr("Failed deleting VM \"" + vm.Name + "\": " + resp.Status() + ": " + resp.String()) - statusCode = 1 - } + u.PrintlnErr(err) + return 1 } - + u.Println("Deleted VM \"" + vm.Name + "\"") } - return statusCode + return 0 } diff --git a/src/client/cmdVM/vmDelAccess.go b/src/client/cmdVM/vmDelAccess.go index c830076..ee61f45 100644 --- a/src/client/cmdVM/vmDelAccess.go +++ b/src/client/cmdVM/vmDelAccess.go @@ -7,6 +7,7 @@ import ( "net/mail" u "nexus-client/utils" g "nexus-libclient/globals" + libclient "nexus-libclient/vm" "os" ) @@ -106,7 +107,7 @@ func (cmd *DelAccess) Run(args []string) int { return 1 } - vms, err := getFilteredVMs("/vms/editaccess", patterns) + vms, err := getFilteredVMs(libclient.GetEditAccessVMs, patterns) if err != nil { u.PrintlnErr(err.Error()) return 1 diff --git a/src/client/cmdVM/vmEdit.go b/src/client/cmdVM/vmEdit.go index 0a1cf1a..13055fb 100644 --- a/src/client/cmdVM/vmEdit.go +++ b/src/client/cmdVM/vmEdit.go @@ -6,6 +6,7 @@ import ( "nexus-common/params" "nexus-common/vm" g "nexus-libclient/globals" + libclient "nexus-libclient/vm" "strconv" "strings" ) @@ -65,7 +66,7 @@ func (cmd *Edit) Run(args []string) int { return 1 } - vms, err := getFilteredVMs("/vms/edit", patterns) + vms, err := getFilteredVMs(libclient.GetEditVMs, patterns) if err != nil { u.PrintlnErr(err.Error()) return 1 diff --git a/src/client/cmdVM/vmExportDir.go b/src/client/cmdVM/vmExportDir.go index 61b5521..cb3f456 100644 --- a/src/client/cmdVM/vmExportDir.go +++ b/src/client/cmdVM/vmExportDir.go @@ -4,6 +4,7 @@ import ( u "nexus-client/utils" "nexus-common/params" g "nexus-libclient/globals" + libclient "nexus-libclient/vm" ) type ExportDir struct { @@ -46,9 +47,9 @@ func (cmd *ExportDir) Run(args []string) int { dir := args[argc-1] - vms, err := getFilteredVMs("/vms/exportdir", args[:argc-1]) + vms, err := getFilteredVMs(libclient.GetExportDirVMs, args[:argc-1]) if err != nil { - u.PrintlnErr("Error: " + err.Error()) + u.PrintlnErr(err.Error()) return 1 } diff --git a/src/client/cmdVM/vmImportDir.go b/src/client/cmdVM/vmImportDir.go index 3e04a94..659fa4f 100644 --- a/src/client/cmdVM/vmImportDir.go +++ b/src/client/cmdVM/vmImportDir.go @@ -3,6 +3,8 @@ package cmdVM import ( u "nexus-client/utils" g "nexus-libclient/globals" + libclient "nexus-libclient/vm" + "os" ) @@ -48,9 +50,9 @@ func (cmd *ImportDir) Run(args []string) int { vmDir := args[argc-1] localDir := args[argc-2] - vms, err := getFilteredVMs("/vms/importfiles", args[:argc-2]) + vms, err := getFilteredVMs(libclient.GetImportFileVMs, args[:argc-2]) if err != nil { - u.PrintlnErr("Error: " + err.Error()) + u.PrintlnErr(err.Error()) return 1 } diff --git a/src/client/cmdVM/vmList.go b/src/client/cmdVM/vmList.go index ec0a7c3..a2fa9de 100644 --- a/src/client/cmdVM/vmList.go +++ b/src/client/cmdVM/vmList.go @@ -3,6 +3,7 @@ package cmdVM import ( "fmt" u "nexus-client/utils" + libclient "nexus-libclient/vm" ) type List struct { @@ -54,7 +55,7 @@ func (cmd *List) printFilteredVMs(args []string, route string) int { args = u.RemoveArgAtIndex(args, foundLongOutputFlag) } - vms, err := getFilteredVMs(route, args) + vms, err := getFilteredVMs(libclient.GetListVMs, args) if err != nil { u.PrintlnErr("Error: " + err.Error()) return 1 diff --git a/src/client/cmdVM/vmListSingle.go b/src/client/cmdVM/vmListSingle.go index f8f35d5..be8ef4b 100644 --- a/src/client/cmdVM/vmListSingle.go +++ b/src/client/cmdVM/vmListSingle.go @@ -2,7 +2,7 @@ package cmdVM import ( u "nexus-client/utils" - g "nexus-libclient/globals" + libclient "nexus-libclient/vm" ) type ListSingle struct { @@ -29,9 +29,6 @@ func (cmd *ListSingle) PrintUsage() { } func (cmd *ListSingle) Run(args []string) int { - client := g.GetInstance().Client - host := g.GetInstance().Host - argc := len(args) if argc < 1 { cmd.PrintUsage() @@ -39,28 +36,17 @@ func (cmd *ListSingle) Run(args []string) int { } vmID := args[0] - resp, err := client.R().Get(host + "/vms/" + vmID) + vm, err := libclient.GetListableVM(vmID) if err != nil { - u.PrintlnErr("Failed retrieving VM \"" + vmID + "\": " + err.Error()) + u.PrintlnErr(err) return 1 - } else { - if resp.IsSuccess() { - vm, err := deserializeVM(resp) - if err != nil { - u.PrintlnErr("Failed retrieving server's response: " + err.Error()) - return 1 - } - str, err := vm.String() - if err != nil { - u.PrintlnErr("Failed decoding VM " + vm.ID.String() + " to string. Skipped.") - } else { - u.Println(str) - } - } else { - u.PrintlnErr("Failed retrieving VM \"" + vmID + "\": " + resp.Status() + ": " + resp.String()) - return 1 - } } + vmStr, err := vm.String() + if err != nil { + u.PrintlnErr(err) + return 1 + } + u.Println(vmStr) return 0 } diff --git a/src/client/cmdVM/vmReboot.go b/src/client/cmdVM/vmReboot.go index 6faee71..e62c57d 100644 --- a/src/client/cmdVM/vmReboot.go +++ b/src/client/cmdVM/vmReboot.go @@ -1,8 +1,9 @@ package cmdVM import ( + libclient "nexus-libclient/vm" + u "nexus-client/utils" - g "nexus-libclient/globals" ) type Reboot struct { @@ -25,16 +26,13 @@ func (cmd *Reboot) PrintUsage() { } func (cmd *Reboot) Run(args []string) int { - client := g.GetInstance().Client - host := g.GetInstance().Host - argc := len(args) if argc < 1 { cmd.PrintUsage() return 1 } - vms, err := getFilteredVMs("/vms/reboot", args) + vms, err := getFilteredVMs(libclient.GetRebootVMs, args) if err != nil { u.PrintlnErr(err.Error()) return 1 @@ -45,24 +43,15 @@ func (cmd *Reboot) Run(args []string) int { return 1 } - statusCode := 0 - for _, vm := range vms { - uuid := vm.ID.String() - resp, err := client.R().Put(host + "/vms/" + uuid + "/reboot") + err := libclient.VMReboot(vm.ID.String()) if err != nil { - u.PrintlnErr("Reboot failed for VM \"" + vm.Name + "\": " + err.Error()) - statusCode = 1 - } else { - if resp.IsSuccess() { - u.Println("Sent reboot message to VM \"" + vm.Name + "\"") - } else { - u.PrintlnErr("Reboot failed for VM \"" + vm.Name + "\": " + resp.Status() + ": " + resp.String()) - statusCode = 1 - } + u.PrintlnErr(err) + return 1 } + u.Println("Sent reboot message to VM \"" + vm.Name + "\"") } - return statusCode + return 0 } diff --git a/src/client/cmdVM/vmShutdown.go b/src/client/cmdVM/vmShutdown.go index e7108cb..da07af9 100644 --- a/src/client/cmdVM/vmShutdown.go +++ b/src/client/cmdVM/vmShutdown.go @@ -3,6 +3,7 @@ package cmdVM import ( u "nexus-client/utils" g "nexus-libclient/globals" + libclient "nexus-libclient/vm" ) type Shutdown struct { @@ -34,7 +35,7 @@ func (cmd *Shutdown) Run(args []string) int { return 1 } - vms, err := getFilteredVMs("/vms/stop", args) + vms, err := getFilteredVMs(libclient.GetStopVMs, args) if err != nil { u.PrintlnErr(err.Error()) return 1 diff --git a/src/client/cmdVM/vmStart.go b/src/client/cmdVM/vmStart.go index f556b3a..bf11948 100644 --- a/src/client/cmdVM/vmStart.go +++ b/src/client/cmdVM/vmStart.go @@ -3,6 +3,7 @@ package cmdVM import ( u "nexus-client/utils" g "nexus-libclient/globals" + libclient "nexus-libclient/vm" ) type Start struct { @@ -34,7 +35,7 @@ func (cmd *Start) Run(args []string) int { return 1 } - vms, err := getFilteredVMs("/vms/start", args) + vms, err := getFilteredVMs(libclient.GetStartVMs, args) if err != nil { u.PrintlnErr(err.Error()) return 1 diff --git a/src/client/cmdVM/vmStartAttach.go b/src/client/cmdVM/vmStartAttach.go index b684f06..49b9a87 100644 --- a/src/client/cmdVM/vmStartAttach.go +++ b/src/client/cmdVM/vmStartAttach.go @@ -4,6 +4,7 @@ import ( "nexus-client/exec" u "nexus-client/utils" g "nexus-libclient/globals" + libclient "nexus-libclient/vm" ) type StartAttach struct { @@ -41,7 +42,7 @@ func (cmd *StartAttach) Run(args []string) int { return 1 } - vms, err := getFilteredVMs("/vms/start", args) + vms, err := getFilteredVMs(libclient.GetStartVMs, args) if err != nil { u.PrintlnErr(err.Error()) return 1 diff --git a/src/client/cmdVM/vmStop.go b/src/client/cmdVM/vmStop.go index 01d441c..22f86d7 100644 --- a/src/client/cmdVM/vmStop.go +++ b/src/client/cmdVM/vmStop.go @@ -2,7 +2,7 @@ package cmdVM import ( u "nexus-client/utils" - g "nexus-libclient/globals" + libclient "nexus-libclient/vm" ) type Stop struct { @@ -25,16 +25,13 @@ func (cmd *Stop) PrintUsage() { } func (cmd *Stop) Run(args []string) int { - client := g.GetInstance().Client - host := g.GetInstance().Host - argc := len(args) if argc < 1 { cmd.PrintUsage() return 1 } - vms, err := getFilteredVMs("/vms/stop", args) + vms, err := getFilteredVMs(libclient.GetStopVMs, args) if err != nil { u.PrintlnErr(err.Error()) return 1 @@ -45,24 +42,14 @@ func (cmd *Stop) Run(args []string) int { return 1 } - statusCode := 0 - for _, vm := range vms { - uuid := vm.ID.String() - resp, err := client.R().Put(host + "/vms/" + uuid + "/stop") + err := libclient.VMStop(vm.ID.String()) if err != nil { - u.PrintlnErr("Failed stopping VM \"" + vm.Name + "\": " + err.Error()) - statusCode = 1 - } else { - if resp.IsSuccess() { - u.Println("Stopped VM \"" + vm.Name + "\"") - } else { - u.PrintlnErr("Failed stopping VM \"" + vm.Name + "\": " + resp.Status() + ": " + resp.String()) - statusCode = 1 - } + u.PrintlnErr(err) + return 1 } - + u.Println("Stopped VM \"" + vm.Name + "\"") } - return statusCode + return 0 } diff --git a/src/libclient/go.mod b/src/libclient/go.mod index b1824ae..1491504 100644 --- a/src/libclient/go.mod +++ b/src/libclient/go.mod @@ -3,3 +3,7 @@ module nexus-libclient go 1.22.0 replace nexus-common => ../common + +require nexus-common v0.0.0-00010101000000-000000000000 + +require github.com/google/uuid v1.6.0 // indirect diff --git a/src/libclient/template/helper.go b/src/libclient/template/deserializer.go similarity index 100% rename from src/libclient/template/helper.go rename to src/libclient/template/deserializer.go diff --git a/src/libclient/user/helper.go b/src/libclient/user/deserializer.go similarity index 100% rename from src/libclient/user/helper.go rename to src/libclient/user/deserializer.go diff --git a/src/libclient/vm/deserializer.go b/src/libclient/vm/deserializer.go new file mode 100644 index 0000000..36ac137 --- /dev/null +++ b/src/libclient/vm/deserializer.go @@ -0,0 +1,51 @@ +package vm + +import ( + "encoding/json" + "nexus-common/vm" + + "github.com/go-playground/validator/v10" + "github.com/go-resty/resty/v2" +) + +// Deserialize a list of VMs from an http response. +func deserializeVMs(resp *resty.Response) ([]vm.VMNetworkSerialized, error) { + vms := []vm.VMNetworkSerialized{} + if err := json.Unmarshal(resp.Body(), &vms); err != nil { + return nil, err + } + return vms, nil +} + +// Deserialize a single VM from an http response. +func deserializeVM(resp *resty.Response) (*vm.VMNetworkSerialized, error) { + vm := vm.VMNetworkSerialized{} + if err := json.Unmarshal(resp.Body(), &vm); err != nil { + return nil, err + } + if err := validator.New(validator.WithRequiredStructEnabled()).Struct(vm); err != nil { + return nil, err + } + return &vm, nil +} + +// Deserialize a list of VM credentials from an http response. +func deserializeVMsCredentials(resp *resty.Response) ([]vm.VMAttachCredentialsSerialized, error) { + vmsCreds := []vm.VMAttachCredentialsSerialized{} + if err := json.Unmarshal(resp.Body(), &vmsCreds); err != nil { + return nil, err + } + return vmsCreds, nil +} + +// Deserialize a VM credentials from an http response. +func deserializeVMCredentials(resp *resty.Response) (*vm.VMAttachCredentialsSerialized, error) { + var vmCreds vm.VMAttachCredentialsSerialized + if err := json.Unmarshal(resp.Body(), &vmCreds); err != nil { + return nil, err + } + if err := validator.New(validator.WithRequiredStructEnabled()).Struct(vmCreds); err != nil { + return nil, err + } + return &vmCreds, nil +} diff --git a/src/libclient/vm/vmAttach.go b/src/libclient/vm/vmAttach.go new file mode 100644 index 0000000..113fb68 --- /dev/null +++ b/src/libclient/vm/vmAttach.go @@ -0,0 +1,27 @@ +package vm + +import ( + "nexus-common/vm" + g "nexus-libclient/globals" + "nexus-libclient/response" +) + +func VMAttach(vmID string) (*vm.VMAttachCredentialsSerialized, error) { + client := g.GetInstance().Client + host := g.GetInstance().Host + + resp, err := client.R().Get(host + "/vms/" + vmID + "/attach") + if err != nil { + return nil, err + } + + if resp.IsSuccess() { + vmCreds, err := deserializeVMCredentials(resp) + if err != nil { + return nil, err + } + return vmCreds, nil + } else { + return nil, response.ErrorToMsg(resp) + } +} diff --git a/src/libclient/vm/vmAttachCredentials.go b/src/libclient/vm/vmAttachCredentials.go new file mode 100644 index 0000000..4458656 --- /dev/null +++ b/src/libclient/vm/vmAttachCredentials.go @@ -0,0 +1,27 @@ +package vm + +import ( + "nexus-common/vm" + g "nexus-libclient/globals" + "nexus-libclient/response" +) + +func GetVMAttachCredentials() ([]vm.VMAttachCredentialsSerialized, error) { + client := g.GetInstance().Client + host := g.GetInstance().Host + + resp, err := client.R().Get(host + "/vms/attach") + if err != nil { + return nil, err + } + + if resp.IsSuccess() { + vmCreds, err := deserializeVMsCredentials(resp) + if err != nil { + return nil, err + } + return vmCreds, nil + } else { + return nil, response.ErrorToMsg(resp) + } +} diff --git a/src/libclient/vm/vmCreate.go b/src/libclient/vm/vmCreate.go new file mode 100644 index 0000000..d9ebf4f --- /dev/null +++ b/src/libclient/vm/vmCreate.go @@ -0,0 +1,28 @@ +package vm + +import ( + "encoding/json" + "nexus-common/params" + "nexus-common/vm" + g "nexus-libclient/globals" + "nexus-libclient/response" +) + +func VMCreate(p params.VMCreate) (*vm.VMNetworkSerialized, error) { + client := g.GetInstance().Client + host := g.GetInstance().Host + + resp, err := client.R().SetBody(p).Post(host + "/vms") + if err != nil { + return nil, err + } + if resp.IsSuccess() { + var vm vm.VMNetworkSerialized + if err := json.Unmarshal(resp.Body(), &vm); err != nil { + return nil, err + } + return &vm, nil + } else { + return nil, response.ErrorToMsg(resp) + } +} diff --git a/src/libclient/vm/vmDel.go b/src/libclient/vm/vmDel.go new file mode 100644 index 0000000..086b4f7 --- /dev/null +++ b/src/libclient/vm/vmDel.go @@ -0,0 +1,21 @@ +package vm + +import ( + g "nexus-libclient/globals" + "nexus-libclient/response" +) + +func VMDel(vmID string) error { + client := g.GetInstance().Client + host := g.GetInstance().Host + + resp, err := client.R().Delete(host + "/vms/" + vmID) + if err != nil { + return err + } + if resp.IsSuccess() { + return nil + } else { + return response.ErrorToMsg(resp) + } +} diff --git a/src/libclient/vm/vmGet.go b/src/libclient/vm/vmGet.go new file mode 100644 index 0000000..2b2eaf3 --- /dev/null +++ b/src/libclient/vm/vmGet.go @@ -0,0 +1,100 @@ +package vm + +import ( + "nexus-common/vm" + g "nexus-libclient/globals" + "nexus-libclient/response" +) + +const ( + attachVMs = "/vms/attach" + delVMs = "/vms/del" + editVMs = "/vms/edit" + editaccessVMs = "/vms/editaccess" + exportdirVMs = "/vms/exportdir" + importfileVMs = "/vms/importfiles" + listVMs = "/vms" + rebootVMs = "/vms/reboot" + startVMs = "/vms/start" + stopVMs = "/vms/stop" +) + +func GetAttachVMs() ([]vm.VMNetworkSerialized, error) { + return getFilteredVMs(attachVMs) +} + +func GetDelVMs() ([]vm.VMNetworkSerialized, error) { + return getFilteredVMs(delVMs) +} + +func GetEditAccessVMs() ([]vm.VMNetworkSerialized, error) { + return getFilteredVMs(editaccessVMs) +} + +func GetEditVMs() ([]vm.VMNetworkSerialized, error) { + return getFilteredVMs(editVMs) +} + +func GetExportDirVMs() ([]vm.VMNetworkSerialized, error) { + return getFilteredVMs(exportdirVMs) +} + +func GetImportFileVMs() ([]vm.VMNetworkSerialized, error) { + return getFilteredVMs(importfileVMs) +} + +func GetListVMs() ([]vm.VMNetworkSerialized, error) { + return getFilteredVMs(listVMs) +} + +func GetRebootVMs() ([]vm.VMNetworkSerialized, error) { + return getFilteredVMs(rebootVMs) +} + +func GetStartVMs() ([]vm.VMNetworkSerialized, error) { + return getFilteredVMs(startVMs) +} + +func GetStopVMs() ([]vm.VMNetworkSerialized, error) { + return getFilteredVMs(stopVMs) +} + +func getFilteredVMs(route string) ([]vm.VMNetworkSerialized, error) { + client := g.GetInstance().Client + host := g.GetInstance().Host + + resp, err := client.R().Get(host + route) + if err != nil { + return nil, err + } + + if resp.IsSuccess() { + templates, err := deserializeVMs(resp) + if err != nil { + return nil, err + } + return templates, nil + } else { + return nil, response.ErrorToMsg(resp) + } +} + +func GetListableVM(uuid string) (*vm.VMNetworkSerialized, error) { + client := g.GetInstance().Client + host := g.GetInstance().Host + + resp, err := client.R().Get(host + "/vms/" + uuid) + if err != nil { + return nil, err + } + + if resp.IsSuccess() { + template, err := deserializeVM(resp) + if err != nil { + return nil, err + } + return template, nil + } else { + return nil, response.ErrorToMsg(resp) + } +} diff --git a/src/libclient/vm/vmReboot.go b/src/libclient/vm/vmReboot.go new file mode 100644 index 0000000..adb1d7e --- /dev/null +++ b/src/libclient/vm/vmReboot.go @@ -0,0 +1,21 @@ +package vm + +import ( + g "nexus-libclient/globals" + "nexus-libclient/response" +) + +func VMReboot(vmID string) error { + client := g.GetInstance().Client + host := g.GetInstance().Host + + resp, err := client.R().Put(host + "/vms/" + vmID + "/reboot") + if err != nil { + return err + } + if resp.IsSuccess() { + return nil + } else { + return response.ErrorToMsg(resp) + } +} diff --git a/src/libclient/vm/vmStop.go b/src/libclient/vm/vmStop.go new file mode 100644 index 0000000..9c735c5 --- /dev/null +++ b/src/libclient/vm/vmStop.go @@ -0,0 +1,21 @@ +package vm + +import ( + g "nexus-libclient/globals" + "nexus-libclient/response" +) + +func VMStop(vmID string) error { + client := g.GetInstance().Client + host := g.GetInstance().Host + + resp, err := client.R().Put(host + "/vms/" + vmID + "/stop") + if err != nil { + return err + } + if resp.IsSuccess() { + return nil + } else { + return response.ErrorToMsg(resp) + } +} -- GitLab