diff --git a/src/client/cmdMisc/ls.go b/src/client/cmdMisc/ls.go index ebcc84e55d0ef433de4ac18650c895e1dac2814a..e3a5e30916afe44cd0dfb6ee6cd8450dfdda19e2 100644 --- a/src/client/cmdMisc/ls.go +++ b/src/client/cmdMisc/ls.go @@ -14,7 +14,7 @@ func (cmd *Ls) GetName() string { } func (cmd *Ls) GetDesc() []string { - return []string{"List files in the specified dir or in the current dir if no argument is specified."} + return []string{"Lists files in the specified dir or in the current dir if no argument is specified."} } func (cmd *Ls) PrintUsage() { @@ -24,7 +24,6 @@ func (cmd *Ls) PrintUsage() { u.PrintlnErr("―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――") u.PrintlnErr("USAGE: ", cmd.GetName(), " [dir]") u.PrintlnErr("―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――") - u.PrintlnErr("List files in the specified dir or in the current dir if no argument is specified.") } func (cmd *Ls) Run(args []string) int { diff --git a/src/client/cmdUser/userList.go b/src/client/cmdUser/userList.go index 17f2648da79e17aef468a1b4e5bf3cf356235a2c..81150c91409504a8dd7e95f40f149aeb34a15df2 100644 --- a/src/client/cmdUser/userList.go +++ b/src/client/cmdUser/userList.go @@ -2,7 +2,6 @@ package cmdUser import ( "fmt" - "nexus-client/cmd" u "nexus-client/utils" "nexus-common/params" libclient "nexus-libclient/user" @@ -124,15 +123,6 @@ func (cmd *List) Run(args []string) int { return 0 } -func printRegexUsage(c cmd.Command) { - for _, desc := range c.GetDesc() { - u.PrintlnErr(desc) - } - u.PrintlnErr("―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――") - u.PrintlnErr("USAGE: ", c.GetName(), " [regex ...]") - u.PrintlnErr("―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――") -} - func printRegexUsageDetails() { const usage string = `Only users matching the specified regexes will be listed. Any number of regexes can be specified. diff --git a/src/client/cmdUser/userSetCaps.go b/src/client/cmdUser/userSetCaps.go index 6e3ddec91dc940783a67659e978168bac47f4517..adfa2edd05deb9aa4f71946a44f2387a7c78be20 100644 --- a/src/client/cmdUser/userSetCaps.go +++ b/src/client/cmdUser/userSetCaps.go @@ -106,7 +106,7 @@ func (cmd *SetCaps) Run(args []string) int { continue } - userCaps := ¶ms.UserSetCaps{make(map[string]int)} + userCaps := ¶ms.UserSetCaps{Caps: make(map[string]int)} capsStr := strings.TrimSpace(columns[1]) if len(capsStr) > 0 { @@ -134,7 +134,7 @@ func (cmd *SetCaps) Run(args []string) int { // Argument is an email address email := args[0] - userCaps := ¶ms.UserSetCaps{make(map[string]int)} + userCaps := ¶ms.UserSetCaps{Caps: make(map[string]int)} for _, cap := range args[1:] { userCaps.Caps[cap] = 1 } diff --git a/src/client/cmdVM/helper.go b/src/client/cmdVM/helper.go index 9259f42dccf1ef15243c9b39cb4a5e894d08ef59..27149c74892827f6289a4f3b85790bfd8e52859e 100644 --- a/src/client/cmdVM/helper.go +++ b/src/client/cmdVM/helper.go @@ -47,7 +47,7 @@ Regex examples: // "bla" -> matches any VM name containing "bla" 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") + return nil, errors.New("at least one ID or regex must be specified") } var ids []string @@ -110,7 +110,7 @@ func getFilteredVMs(filteredVMsFunc GetVMs, patterns []string) ([]vm.VMNetworkSe // "bla" -> matches any VM name containing "bla" func getFilteredVMCredentials(patterns []string) ([]vm.VMAttachCredentialsSerialized, error) { if len(patterns) < 1 { - return nil, errors.New("At least one ID or regex must be specified") + return nil, errors.New("at least one ID or regex must be specified") } var ids []string diff --git a/src/client/cmdVM/vmAddAccess.go b/src/client/cmdVM/vmAddAccess.go index ec290e443bf49ae12866a3458b3d8c2ca794f07c..1bd100c9859f896579e75541340c7cf70c20f5ea 100644 --- a/src/client/cmdVM/vmAddAccess.go +++ b/src/client/cmdVM/vmAddAccess.go @@ -114,7 +114,7 @@ func (cmd *AddAccess) Run(args []string) int { continue } - vmAccessCaps := ¶ms.VMAddAccess{make(caps.Capabilities)} + vmAccessCaps := ¶ms.VMAddAccess{Access: make(caps.Capabilities)} capsStr := strings.TrimSpace(columns[2]) if len(capsStr) > 0 { @@ -151,7 +151,7 @@ func (cmd *AddAccess) Run(args []string) int { return 1 } - vmAccessCaps := ¶ms.VMAddAccess{make(caps.Capabilities)} + vmAccessCaps := ¶ms.VMAddAccess{Access: make(caps.Capabilities)} for _, cap := range capabilities { vmAccessCaps.Access[cap] = 1 } @@ -194,7 +194,7 @@ func (cmd *AddAccess) parseArgs(args []string) (string, []string, []string, erro } if !emailFound { - return "", nil, nil, errors.New("An email address must be specified") + return "", nil, nil, errors.New("an email address must be specified") } return email, capabilities, patterns, nil diff --git a/src/client/cmdVM/vmAttachFromPwd.go b/src/client/cmdVM/vmAttachFromPwd.go index 1bbf3f4726c6b418fe7181aef39020986c476d49..89245d4fdb7fec30488e2702e90c7acb4afe9a03 100644 --- a/src/client/cmdVM/vmAttachFromPwd.go +++ b/src/client/cmdVM/vmAttachFromPwd.go @@ -2,7 +2,6 @@ package cmdVM import ( "nexus-client/exec" - e "nexus-client/exec" u "nexus-client/utils" "nexus-common/params" "nexus-common/vm" @@ -57,7 +56,7 @@ func (cmd *AttachFromPwd) Run(args []string) int { return 1 } else { go func(creds vm.VMSpiceCredentialsSerialized) { - _, err := e.RunRemoteViewer(hostname, cert, creds.Name, creds.SpicePort, creds.SpicePwd, true) + _, err := exec.RunRemoteViewer(hostname, cert, creds.Name, creds.SpicePort, creds.SpicePwd, true) if err != nil { u.PrintlnErr("Failed executing remote-viewer: " + err.Error()) } diff --git a/src/client/cmdVM/vmDelAccess.go b/src/client/cmdVM/vmDelAccess.go index 7d16a31c81ee86d91140a2ca9101e058633386e8..2e6d2e324059c22d678018dcf847b79c00de8ee5 100644 --- a/src/client/cmdVM/vmDelAccess.go +++ b/src/client/cmdVM/vmDelAccess.go @@ -145,7 +145,7 @@ func (cmd *DelAccess) parseArgs(args []string) (string, []string, error) { } else { // An email address was found if emailFound { - return "", nil, errors.New("Only one email address must be specified") + return "", nil, errors.New("only one email address must be specified") } email = parsed.Address emailFound = true @@ -153,7 +153,7 @@ func (cmd *DelAccess) parseArgs(args []string) (string, []string, error) { } if !emailFound { - return "", nil, errors.New("An email address must be specified") + return "", nil, errors.New("an email address must be specified") } return email, patterns, nil diff --git a/src/client/cmdVM/vmEdit.go b/src/client/cmdVM/vmEdit.go index 9cc00938994df74f13232a04819a9ad21da37fe2..d4d3352d551fdba58b7c7a1cbcd0780e1ddef434 100644 --- a/src/client/cmdVM/vmEdit.go +++ b/src/client/cmdVM/vmEdit.go @@ -121,7 +121,7 @@ func (cmd *Edit) parseArgs(args []string) (*params.VMEdit, []string, error) { if s != "" { cpus, err := strconv.Atoi(s) if err != nil || cpus < 1 { - return nil, nil, errors.New("Error: invalid number of CPU(s)!") + return nil, nil, errors.New("error: invalid number of CPU(s)") } vmParams.Cpus = cpus atLeastOneArg = true @@ -131,7 +131,7 @@ func (cmd *Edit) parseArgs(args []string) (*params.VMEdit, []string, error) { if s != "" { ram, err := strconv.Atoi(s) if err != nil || ram < 1 { - return nil, nil, errors.New("Error: invalid amount of RAM!") + return nil, nil, errors.New("error: invalid amount of RAM") } vmParams.Ram = ram atLeastOneArg = true diff --git a/src/client/cmdVM/vmList.go b/src/client/cmdVM/vmList.go index e9312f658caafc11714d8f9eb73143a5682a7492..379c090aebd2202bf9c0658a1dd990bb97d1225b 100644 --- a/src/client/cmdVM/vmList.go +++ b/src/client/cmdVM/vmList.go @@ -33,12 +33,12 @@ func (cmd *List) PrintUsage() { } func (cmd *List) Run(args []string) int { - return cmd.printFilteredVMs(args, "/vms") + return cmd.printFilteredVMs(args) } // Prints a list of filtered VMs for a given route. // Return 0 if everything went well or 1 in case of failure. -func (cmd *List) printFilteredVMs(args []string, route string) int { +func (cmd *List) printFilteredVMs(args []string) int { if len(args) < 1 { cmd.PrintUsage() return 1 diff --git a/src/client/cmdVM/vmStartWithCreds.go b/src/client/cmdVM/vmStartWithCreds.go index b583fdaad4679fcf71a597361845abe7e0647f21..8b693a80bec86e712dda41dfaede1b3022397057 100644 --- a/src/client/cmdVM/vmStartWithCreds.go +++ b/src/client/cmdVM/vmStartWithCreds.go @@ -47,7 +47,7 @@ func (cmd *StartWithCreds) parseCSVFile(csvFile string) ([]string, []string, err } count := len(vmIDs) if len(pwds) != count { - return nil, nil, errors.New("Invalid CSV file: all columns must have the same number of entries!") + return nil, nil, errors.New("invalid CSV file: all columns must have the same number of entries") } return vmIDs, pwds, nil } diff --git a/src/client/cmdVersion/version.go b/src/client/cmdVersion/version.go index 758be04213d76e91874d6d3d32e171b3f627e1c1..29677e653c179cabef7542872077ce6d81c9074b 100644 --- a/src/client/cmdVersion/version.go +++ b/src/client/cmdVersion/version.go @@ -15,8 +15,7 @@ func (cmd *Version) GetName() string { } func (cmd *Version) GetDesc() []string { - return []string{ - "Display nexus server and client's versions."} + return []string{"Display nexus server and client's versions."} } func (cmd *Version) PrintUsage() { diff --git a/src/client/go.mod b/src/client/go.mod index e11566dbb2826ea926cf8cf1e924e59cf60aceff..4e105cb3ea930e72fec55b28422a00c8eedfb291 100644 --- a/src/client/go.mod +++ b/src/client/go.mod @@ -9,7 +9,7 @@ replace nexus-libclient => ../libclient require ( fyne.io/fyne/v2 v2.5.2 github.com/go-pdf/fpdf v0.9.0 - github.com/go-playground/validator/v10 v10.23.0 + github.com/go-playground/validator/v10 v10.23.0 // indirect github.com/go-resty/resty/v2 v2.16.2 github.com/google/uuid v1.6.0 github.com/peterh/liner v1.2.2 diff --git a/src/client/nexus-cli/nexus-cli.go b/src/client/nexus-cli/nexus-cli.go index 8b4bca9657d5f0c85e7533dbc0383512542db803..fe66f9fefbe3b776f64a92e34836fb7bf7b3a242 100644 --- a/src/client/nexus-cli/nexus-cli.go +++ b/src/client/nexus-cli/nexus-cli.go @@ -23,53 +23,53 @@ import ( ) var cmdList = []cmd.Command{ - &cmdMisc.HelpHeader{"!═════╡ GENERAL commands ╞═════════════════════════════════════════════════════════════════"}, + &cmdMisc.HelpHeader{Name: "!═════╡ GENERAL commands ╞═════════════════════════════════════════════════════════════════"}, // Commands in this block are specific to nexus-cli - &cmdLogin.Login{"login"}, + &cmdLogin.Login{Name: "login"}, // End of nexus-cli specific commands - &cmdToken.Refresh{"refresh"}, - &cmdVersion.Version{"version"}, - - &cmdMisc.HelpHeader{"!═════╡ USER commands ╞═════════════════════════════════════════════════════════════════"}, - &cmdUser.Whoami{"whoami"}, - &cmdUser.UpdatePwd{"passwd"}, - &cmdUser.List{"userlist"}, - &cmdUser.Add{"usercreate"}, - &cmdUser.Del{"userdel"}, - &cmdUser.ResetPwd{"userresetpwd"}, - &cmdUser.SetCaps{"usersetcaps"}, - &cmdUser.Unlock{"userunlock"}, - - &cmdMisc.HelpHeader{"!═════╡ TEMPLATE commands ╞═════════════════════════════════════════════════════════════════"}, - &cmdTemplate.Create{"tplcreate"}, - &cmdTemplate.Del{"tpldel"}, - &cmdTemplate.Edit{"tpledit"}, - &cmdTemplate.ExportDisk{"tplexportdisk"}, - &cmdTemplate.List{"tpllist"}, - // &cmdTemplate.ListSingle{"tpllistsingle"}, // for testing the route only - - &cmdMisc.HelpHeader{"!═════╡ VM commands ╞═════════════════════════════════════════════════════════════════"}, - &cmdVM.AddAccess{"vmaddaccess"}, - &cmdVM.AttachAsync{"vmattach"}, - // &cmdVM.AttachAsyncSingle{"vmattachsingle"}, // for testing the route only - // &cmdVM.AttachFromPwd{"vmattachfrompwd"}, // for testing the route only - &cmdVM.Create{"vmcreate"}, - &cmdVM.Creds2pdf{"vmcreds2pdf"}, - &cmdVM.Creds2csv{"vmcreds2csv"}, - &cmdVM.Del{"vmdel"}, - &cmdVM.DelAccess{"vmdelaccess"}, - &cmdVM.Edit{"vmedit"}, - &cmdVM.ExportDir{"vmexportdir"}, - &cmdVM.ImportDir{"vmimportdir"}, - &cmdVM.Stop{"vmkill"}, - &cmdVM.List{"vmlist"}, - // &cmdVM.ListSingle{"vmlistsingle"}, // for testing the route only - &cmdVM.Reboot{"vmreboot"}, - &cmdVM.Shutdown{"vmshutdown"}, - &cmdVM.Start{"vmstart"}, - &cmdVM.StartAttach{"vmstartattach"}, - &cmdVM.StartWithCreds{"vmstartwithcreds"}, + &cmdToken.Refresh{Name: "refresh"}, + &cmdVersion.Version{Name: "version"}, + + &cmdMisc.HelpHeader{Name: "!═════╡ USER commands ╞═════════════════════════════════════════════════════════════════"}, + &cmdUser.Whoami{Name: "whoami"}, + &cmdUser.UpdatePwd{Name: "passwd"}, + &cmdUser.List{Name: "userlist"}, + &cmdUser.Add{Name: "usercreate"}, + &cmdUser.Del{Name: "userdel"}, + &cmdUser.ResetPwd{Name: "userresetpwd"}, + &cmdUser.SetCaps{Name: "usersetcaps"}, + &cmdUser.Unlock{Name: "userunlock"}, + + &cmdMisc.HelpHeader{Name: "!═════╡ TEMPLATE commands ╞═════════════════════════════════════════════════════════════════"}, + &cmdTemplate.Create{Name: "tplcreate"}, + &cmdTemplate.Del{Name: "tpldel"}, + &cmdTemplate.Edit{Name: "tpledit"}, + &cmdTemplate.ExportDisk{Name: "tplexportdisk"}, + &cmdTemplate.List{Name: "tpllist"}, + // &cmdTemplate.ListSingle{Name: "tpllistsingle"}, // for testing the route only + + &cmdMisc.HelpHeader{Name: "!═════╡ VM commands ╞═════════════════════════════════════════════════════════════════"}, + &cmdVM.AddAccess{Name: "vmaddaccess"}, + &cmdVM.AttachAsync{Name: "vmattach"}, + // &cmdVM.AttachAsyncSingle{Name: "vmattachsingle"}, // for testing the route only + // &cmdVM.AttachFromPwd{Name: "vmattachfrompwd"}, // for testing the route only + &cmdVM.Create{Name: "vmcreate"}, + &cmdVM.Creds2pdf{Name: "vmcreds2pdf"}, + &cmdVM.Creds2csv{Name: "vmcreds2csv"}, + &cmdVM.Del{Name: "vmdel"}, + &cmdVM.DelAccess{Name: "vmdelaccess"}, + &cmdVM.Edit{Name: "vmedit"}, + &cmdVM.ExportDir{Name: "vmexportdir"}, + &cmdVM.ImportDir{Name: "vmimportdir"}, + &cmdVM.Stop{Name: "vmkill"}, + &cmdVM.List{Name: "vmlist"}, + // &cmdVM.ListSingle{Name: "vmlistsingle"}, // for testing the route only + &cmdVM.Reboot{Name: "vmreboot"}, + &cmdVM.Shutdown{Name: "vmshutdown"}, + &cmdVM.Start{Name: "vmstart"}, + &cmdVM.StartAttach{Name: "vmstartattach"}, + &cmdVM.StartWithCreds{Name: "vmstartwithcreds"}, } func run() int { diff --git a/src/client/nexush/nexush.go b/src/client/nexush/nexush.go index c37a8b97a544aeb068eca4c66efa4a065f4fa3c4..ee4a51a9804364ed913d3e6919f7943b93649922 100644 --- a/src/client/nexush/nexush.go +++ b/src/client/nexush/nexush.go @@ -30,53 +30,53 @@ import ( ) var cmdList = []cmd.Command{ - &cmdMisc.HelpHeader{"!═════╡ GENERAL commands ╞═════════════════════════════════════════════════════════════════"}, + &cmdMisc.HelpHeader{Name: "!═════╡ GENERAL commands ╞═════════════════════════════════════════════════════════════════"}, // Commands in this block are specific to nexush: - &cmdMisc.Ls{"ls"}, + &cmdMisc.Ls{Name: "ls"}, // End of nexush specific commands - &cmdToken.Refresh{"refresh"}, - &cmdVersion.Version{"version"}, - - &cmdMisc.HelpHeader{"!═════╡ USER commands ╞═════════════════════════════════════════════════════════════════"}, - &cmdUser.Whoami{"whoami"}, - &cmdUser.UpdatePwd{"passwd"}, - &cmdUser.List{"userlist"}, - &cmdUser.Add{"usercreate"}, - &cmdUser.Del{"userdel"}, - &cmdUser.ResetPwd{"userresetpwd"}, - &cmdUser.SetCaps{"usersetcaps"}, - &cmdUser.Unlock{"userunlock"}, - - &cmdMisc.HelpHeader{"!═════╡ TEMPLATE commands ╞═════════════════════════════════════════════════════════════════"}, - &cmdTemplate.Create{"tplcreate"}, - &cmdTemplate.Del{"tpldel"}, - &cmdTemplate.Edit{"tpledit"}, - &cmdTemplate.ExportDisk{"tplexportdisk"}, - &cmdTemplate.List{"tpllist"}, - // &cmdTemplate.ListSingle{"tpllistsingle"}, // for testing the route only - - &cmdMisc.HelpHeader{"!═════╡ VM commands ╞═════════════════════════════════════════════════════════════════"}, - &cmdVM.AddAccess{"vmaddaccess"}, - &cmdVM.AttachAsync{"vmattach"}, - // &cmdVM.AttachAsyncSingle{"vmattachsingle"}, // for testing the route only - // &cmdVM.AttachFromPwd{"vmattachfrompwd"}, // for testing the route only - &cmdVM.Create{"vmcreate"}, - &cmdVM.Creds2pdf{"vmcreds2pdf"}, - &cmdVM.Creds2csv{"vmcreds2csv"}, - &cmdVM.Del{"vmdel"}, - &cmdVM.DelAccess{"vmdelaccess"}, - &cmdVM.Edit{"vmedit"}, - &cmdVM.ExportDir{"vmexportdir"}, - &cmdVM.ImportDir{"vmimportdir"}, - &cmdVM.Stop{"vmkill"}, - &cmdVM.List{"vmlist"}, - // &cmdVM.ListSingle{"vmlistsingle"}, // for testing the route only - &cmdVM.Reboot{"vmreboot"}, - &cmdVM.Shutdown{"vmshutdown"}, - &cmdVM.Start{"vmstart"}, - &cmdVM.StartAttach{"vmstartattach"}, - &cmdVM.StartWithCreds{"vmstartwithcreds"}, + &cmdToken.Refresh{Name: "refresh"}, + &cmdVersion.Version{Name: "version"}, + + &cmdMisc.HelpHeader{Name: "!═════╡ USER commands ╞═════════════════════════════════════════════════════════════════"}, + &cmdUser.Whoami{Name: "whoami"}, + &cmdUser.UpdatePwd{Name: "passwd"}, + &cmdUser.List{Name: "userlist"}, + &cmdUser.Add{Name: "usercreate"}, + &cmdUser.Del{Name: "userdel"}, + &cmdUser.ResetPwd{Name: "userresetpwd"}, + &cmdUser.SetCaps{Name: "usersetcaps"}, + &cmdUser.Unlock{Name: "userunlock"}, + + &cmdMisc.HelpHeader{Name: "!═════╡ TEMPLATE commands ╞═════════════════════════════════════════════════════════════════"}, + &cmdTemplate.Create{Name: "tplcreate"}, + &cmdTemplate.Del{Name: "tpldel"}, + &cmdTemplate.Edit{Name: "tpledit"}, + &cmdTemplate.ExportDisk{Name: "tplexportdisk"}, + &cmdTemplate.List{Name: "tpllist"}, + // &cmdTemplate.ListSingle{Name: "tpllistsingle"}, // for testing the route only + + &cmdMisc.HelpHeader{Name: "!═════╡ VM commands ╞═════════════════════════════════════════════════════════════════"}, + &cmdVM.AddAccess{Name: "vmaddaccess"}, + &cmdVM.AttachAsync{Name: "vmattach"}, + // &cmdVM.AttachAsyncSingle{Name: "vmattachsingle"}, // for testing the route only + // &cmdVM.AttachFromPwd{Name: "vmattachfrompwd"}, // for testing the route only + &cmdVM.Create{Name: "vmcreate"}, + &cmdVM.Creds2pdf{Name: "vmcreds2pdf"}, + &cmdVM.Creds2csv{Name: "vmcreds2csv"}, + &cmdVM.Del{Name: "vmdel"}, + &cmdVM.DelAccess{Name: "vmdelaccess"}, + &cmdVM.Edit{Name: "vmedit"}, + &cmdVM.ExportDir{Name: "vmexportdir"}, + &cmdVM.ImportDir{Name: "vmimportdir"}, + &cmdVM.Stop{Name: "vmkill"}, + &cmdVM.List{Name: "vmlist"}, + // &cmdVM.ListSingle{Name: "vmlistsingle"}, // for testing the route only + &cmdVM.Reboot{Name: "vmreboot"}, + &cmdVM.Shutdown{Name: "vmshutdown"}, + &cmdVM.Start{Name: "vmstart"}, + &cmdVM.StartAttach{Name: "vmstartattach"}, + &cmdVM.StartWithCreds{Name: "vmstartwithcreds"}, } var prompt *liner.State = nil @@ -162,7 +162,7 @@ func run() int { // Obtains password from cmd line. email := os.Args[1] - fmt.Printf(email + "'s password: ") + fmt.Printf("%s", email+"'s password: ") bytePwd, err := term.ReadPassword(int(syscall.Stdin)) if err != nil { u.PrintlnErr(err) diff --git a/src/common/caps/caps.go b/src/common/caps/caps.go index 77628ca17b55ae0cc09af130f0456ec52fd2d6fe..e8e13fe52269efb5334a401301d23caac748b20f 100644 --- a/src/common/caps/caps.go +++ b/src/common/caps/caps.go @@ -9,45 +9,45 @@ type Capabilities map[string]int const ( CAP_USER_CREATE string = "USER_CREATE" - CAP_USER_DESTROY = "USER_DESTROY" - CAP_USER_SET_CAPS = "USER_SET_CAPS" - CAP_USER_UNLOCK = "USER_UNLOCK" - CAP_USER_RESETPWD = "USER_RESETPWD" - CAP_USER_LIST = "USER_LIST" - - CAP_VM_LIST = "VM_LIST" - CAP_VM_LIST_ANY = "VM_LIST_ANY" - CAP_VM_ATTACH = "VM_ATTACH" - CAP_VM_ATTACH_ANY = "VM_ATTACH_ANY" - CAP_VM_START = "VM_START" - CAP_VM_START_ANY = "VM_START_ANY" - CAP_VM_STOP = "VM_STOP" - CAP_VM_STOP_ANY = "VM_STOP_ANY" - CAP_VM_REBOOT = "VM_REBOOT" - CAP_VM_REBOOT_ANY = "VM_REBOOT_ANY" - CAP_VM_CREATE = "VM_CREATE" - CAP_VM_DESTROY = "VM_DESTROY" - CAP_VM_DESTROY_ANY = "VM_DESTROY_ANY" - CAP_VM_EDIT = "VM_EDIT" - CAP_VM_EDIT_ANY = "VM_EDIT_ANY" - CAP_VM_SET_ACCESS = "VM_SET_ACCESS" - CAP_VM_SET_ACCESS_ANY = "VM_SET_ACCESS_ANY" - CAP_VM_READFS = "VM_READFS" - CAP_VM_READFS_ANY = "VM_READFS_ANY" - CAP_VM_WRITEFS = "VM_WRITEFS" - CAP_VM_WRITEFS_ANY = "VM_WRITEFS_ANY" - - CAP_EXAM_ATTACH = "EXAM_ATTACH" - - CAP_TPL_CREATE = "TPL_CREATE" - CAP_TPL_EDIT = "TPL_EDIT" - CAP_TPL_EDIT_ANY = "TPL_EDIT_ANY" - CAP_TPL_LIST = "TPL_LIST" - CAP_TPL_LIST_ANY = "TPL_LIST_ANY" - CAP_TPL_DESTROY = "TPL_DESTROY" - CAP_TPL_DESTROY_ANY = "TPL_DESTROY_ANY" - CAP_TPL_READFS = "TPL_READFS" - CAP_TPL_READFS_ANY = "TPL_READFS_ANY" + CAP_USER_DESTROY string = "USER_DESTROY" + CAP_USER_SET_CAPS string = "USER_SET_CAPS" + CAP_USER_UNLOCK string = "USER_UNLOCK" + CAP_USER_RESETPWD string = "USER_RESETPWD" + CAP_USER_LIST string = "USER_LIST" + + CAP_VM_LIST string = "VM_LIST" + CAP_VM_LIST_ANY string = "VM_LIST_ANY" + CAP_VM_ATTACH string = "VM_ATTACH" + CAP_VM_ATTACH_ANY string = "VM_ATTACH_ANY" + CAP_VM_START string = "VM_START" + CAP_VM_START_ANY string = "VM_START_ANY" + CAP_VM_STOP string = "VM_STOP" + CAP_VM_STOP_ANY string = "VM_STOP_ANY" + CAP_VM_REBOOT string = "VM_REBOOT" + CAP_VM_REBOOT_ANY string = "VM_REBOOT_ANY" + CAP_VM_CREATE string = "VM_CREATE" + CAP_VM_DESTROY string = "VM_DESTROY" + CAP_VM_DESTROY_ANY string = "VM_DESTROY_ANY" + CAP_VM_EDIT string = "VM_EDIT" + CAP_VM_EDIT_ANY string = "VM_EDIT_ANY" + CAP_VM_SET_ACCESS string = "VM_SET_ACCESS" + CAP_VM_SET_ACCESS_ANY string = "VM_SET_ACCESS_ANY" + CAP_VM_READFS string = "VM_READFS" + CAP_VM_READFS_ANY string = "VM_READFS_ANY" + CAP_VM_WRITEFS string = "VM_WRITEFS" + CAP_VM_WRITEFS_ANY string = "VM_WRITEFS_ANY" + + CAP_EXAM_ATTACH string = "EXAM_ATTACH" + + CAP_TPL_CREATE string = "TPL_CREATE" + CAP_TPL_EDIT string = "TPL_EDIT" + CAP_TPL_EDIT_ANY string = "TPL_EDIT_ANY" + CAP_TPL_LIST string = "TPL_LIST" + CAP_TPL_LIST_ANY string = "TPL_LIST_ANY" + CAP_TPL_DESTROY string = "TPL_DESTROY" + CAP_TPL_DESTROY_ANY string = "TPL_DESTROY_ANY" + CAP_TPL_READFS string = "TPL_READFS" + CAP_TPL_READFS_ANY string = "TPL_READFS_ANY" ) // Capabilities stored in the user config @@ -113,7 +113,7 @@ func IsVMAccessCapValid(cap string) bool { // Validates all user capabilities. func ValidateUserCaps(caps Capabilities) error { - for cap, _ := range caps { + for cap := range caps { if !IsUserCapValid(cap) { return errors.New("Invalid capability: " + cap) } @@ -123,7 +123,7 @@ func ValidateUserCaps(caps Capabilities) error { // Validates all VM access capabilities. func ValidateVMAccessCaps(caps Capabilities) error { - for cap, _ := range caps { + for cap := range caps { if !IsVMAccessCapValid(cap) { return errors.New("Invalid capability: " + cap) } @@ -133,7 +133,7 @@ func ValidateVMAccessCaps(caps Capabilities) error { func GetUserCapsNames() []string { caps := []string{} - for key, _ := range userCaps { + for key := range userCaps { caps = append(caps, key) } @@ -147,7 +147,7 @@ func GetUserCapsNames() []string { func GetVMAccessCapsNames() []string { caps := []string{} - for key, _ := range vmAccessCaps { + for key := range vmAccessCaps { caps = append(caps, key) } diff --git a/src/common/params/vms.go b/src/common/params/vms.go index e25c9764539e5cc673655692c622b4854a17b891..52ebc93efef44df5734361f48b8288efd0e4d2fc 100644 --- a/src/common/params/vms.go +++ b/src/common/params/vms.go @@ -11,8 +11,8 @@ type VMCreate struct { Name string `json:"name" validate:"required,min=1,max=256"` Cpus int `json:"cpus" validate:"required,gte=1,lte=32"` Ram int `json:"ram" validate:"required,gte=128,lte=32768"` - Nic vm.NicType `json:"nic" validate:"required` - UsbDevs []string `json:"usbDevs" validate:"required` + Nic vm.NicType `json:"nic"` + UsbDevs []string `json:"usbDevs"` TemplateID uuid.UUID `json:"templateID" validate:"required"` } @@ -28,8 +28,8 @@ type VMEdit struct { Name string `json:"name" validate:"required,min=1,max=256"` Cpus int `json:"cpus" validate:"required,gte=1,lte=32"` Ram int `json:"ram" validate:"required,gte=128,lte=32768"` - Nic vm.NicType `json:"nic" validate:"required` - UsbDevs []string `json:"usbDevs" validate:"required` + Nic vm.NicType `json:"nic"` + UsbDevs []string `json:"usbDevs"` } type VMAddAccess struct { diff --git a/src/libclient/go.mod b/src/libclient/go.mod index 14915045c7c5d748b5efc1087ea1361c28d6c10a..c70650134288db7317bc630162112b449fd69d52 100644 --- a/src/libclient/go.mod +++ b/src/libclient/go.mod @@ -6,4 +6,9 @@ replace nexus-common => ../common require nexus-common v0.0.0-00010101000000-000000000000 -require github.com/google/uuid v1.6.0 // indirect +require golang.org/x/net v0.27.0 // indirect + +require ( + github.com/go-resty/resty/v2 v2.16.2 + github.com/google/uuid v1.6.0 // indirect +) diff --git a/src/libclient/go.sum b/src/libclient/go.sum index 7790d7c3e03900e267f0aade3acce649895b2246..5060da736650c97cec6eb978d30c4256168b46a3 100644 --- a/src/libclient/go.sum +++ b/src/libclient/go.sum @@ -1,2 +1,6 @@ +github.com/go-resty/resty/v2 v2.16.2 h1:CpRqTjIzq/rweXUt9+GxzzQdlkqMdt8Lm/fuK/CAbAg= +github.com/go-resty/resty/v2 v2.16.2/go.mod h1:0fHAoK7JoBy/Ch36N8VFeMsK7xQOHhvWaC3iOktwmIU= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= diff --git a/src/server/exec/QemuImg.go b/src/server/exec/QemuImg.go index e9c222ad38b23a851926d90b28bf697d846f35db..90f3794e1271fa0ed43ac4a16a249d803bf418f8 100644 --- a/src/server/exec/QemuImg.go +++ b/src/server/exec/QemuImg.go @@ -25,12 +25,12 @@ func CheckQemuImg() error { lines := strings.Split(out, "\n") fields := strings.Split(lines[0], " ") if len(fields) < 3 { - return errors.New("Failed extracting " + conf.Tools.QemuImg + " version number!") + return errors.New("failed extracting " + conf.Tools.QemuImg + " version number") } v := fields[2] majorVersionNumber, err := strconv.Atoi(string(v[0])) if err != nil { - return errors.New("Failed extracting " + conf.Tools.QemuImg + " version number: " + err.Error()) + return errors.New("failed extracting " + conf.Tools.QemuImg + " version number: " + err.Error()) } if majorVersionNumber < qemuimgBinaryMinVersion { return errors.New(conf.Tools.QemuImg + " " + strconv.Itoa(qemuimgBinaryMinVersion) + ".0.0 or newer is required. Found version " + v + ".") @@ -45,7 +45,7 @@ func QemuImgCreate(templateDiskFile, vmDiskFile string) error { if err != nil { output := fmt.Sprintf("[%s]", stdoutStderr) log.Error("Failed creating VM disk image: " + output) - return errors.New("Failed creating VM disk image") + return errors.New("failed creating VM disk image") } return nil } @@ -57,7 +57,7 @@ func QemuImgRebase(overlayFile string) error { if err != nil { output := fmt.Sprintf("[%s]", stdoutStderr) log.Error("Failed rebasing template disk from VM: " + ": " + output) - return errors.New("Failed rebasing template disk from VM") + return errors.New("failed rebasing template disk from VM") } return nil } diff --git a/src/server/exec/QemuSystem.go b/src/server/exec/QemuSystem.go index 40dde35e1528b33cc1b87a2b5cc4bc29de5ffa65..a76c4a854e3d7b0e55f4b34bf23b1d1db681731c 100644 --- a/src/server/exec/QemuSystem.go +++ b/src/server/exec/QemuSystem.go @@ -46,7 +46,7 @@ func NewQemuSystem(qgaSock string, cpus, ram int, nic string, usbDevs []string, if nic == "user" { addr, err := utils.RandMacAddress() if err != nil { - return nil, errors.New("Failed executing VM: MAC address generation error") + return nil, errors.New("failed executing VM: MAC address generation error") } nicArgs = "user,mac=" + addr + ",model=virtio-net-pci" } @@ -71,7 +71,7 @@ func NewQemuSystem(qgaSock string, cpus, ram int, nic string, usbDevs []string, filter.WriteString("-1:-1:-1:-1:0") // Generate QEMU's arguments for the USB devices - for i, _ := range usbDevs { + for i := range usbDevs { idx := strconv.Itoa(i + 1) usb = append(usb, "-chardev", "spicevmc,name=usbredir,id=usbredir"+idx) usb = append(usb, "-device", "usb-redir,filter="+filter.String()+",chardev=usbredir"+idx) diff --git a/src/server/users/user.go b/src/server/users/user.go index 557112713fc4b14a0c6ea62cd1d6ae20f0cd6e9d..a8f182df7391377729763a3e68984b68b482bdda 100644 --- a/src/server/users/user.go +++ b/src/server/users/user.go @@ -34,7 +34,7 @@ func (user *User) HasCapability(capability string) bool { func (user *User) GetVMAccessCapabilities() []string { caps := []string{} - for key, _ := range user.Caps { + for key := range user.Caps { caps = append(caps, key) } return caps diff --git a/src/server/vms/template.go b/src/server/vms/template.go index ba083570e1d4b72460c715eab6b0479870569930..234dc6cf36a557b540a39d0a575a32813e7c4ae5 100644 --- a/src/server/vms/template.go +++ b/src/server/vms/template.go @@ -35,13 +35,13 @@ func NewTemplateFromVM(name, owner, access string, vm *VM) (*Template, error) { if vm.IsRunning() { vm.mutex.Unlock() - return nil, errors.New("Failed creating template: VM must be stopped") + return nil, errors.New("failed creating template: VM must be stopped") } // Marks VM as "busy", meaning its disk file is being accessed for a possibly long time. if vm.IsDiskBusy() { vm.mutex.Unlock() - return nil, errors.New("Failed creating template: VM disk is in use (busy)") + return nil, errors.New("failed creating template: VM disk is in use (busy)") } vm.DiskBusy = true @@ -131,7 +131,7 @@ func NewTemplateFromQCOW(name, owner, access, qcowFile string) (*Template, error // Concurrency: safe func ValidateTemplateAccess(access string) error { if access != templatePrivate && access != templatePublic { - return errors.New("Wrong template access type") + return errors.New("wrong template access type") } return nil } @@ -169,7 +169,7 @@ func newTemplate(name, owner, access string) (*Template, error) { return nil, err } - template := &Template{template.TemplateSerialized{id, name, owner, access, time.Now()}} + template := &Template{template.TemplateSerialized{ID: id, Name: name, Owner: owner, Access: access, CreationTime: time.Now()}} if err := template.validate(); err != nil { return nil, errors.New("Failed validating template: " + err.Error()) diff --git a/src/server/vms/templates.go b/src/server/vms/templates.go index 61cc4ba24ad8fdd3686aa45ce282666d04793760..8227293d63d9ba13f94aac4d74001a4193dbf846 100644 --- a/src/server/vms/templates.go +++ b/src/server/vms/templates.go @@ -126,7 +126,7 @@ func (templates *Templates) DeleteTemplate(tplID uuid.UUID, vms *VMs) error { template, exists := templates.m[id] if exists { if vms.IsTemplateUsed(id) { - return errors.New("Failed: template still used by one or more VMs") + return errors.New("failed: template still used by one or more VMs") } // Removes the template's files (and directory). if err := template.delete(); err != nil { @@ -137,7 +137,7 @@ func (templates *Templates) DeleteTemplate(tplID uuid.UUID, vms *VMs) error { return nil } - return errors.New("Failed: template not found") + return errors.New("failed: template not found") } // Adds a template, create its on-disk directory and config file. diff --git a/src/server/vms/vm.go b/src/server/vms/vm.go index e76ac00785d3c0a52d6692aeb59a11abbf0034c0..b42acca20902a7150eddaa29b38267c18a7f1d3e 100644 --- a/src/server/vms/vm.go +++ b/src/server/vms/vm.go @@ -39,8 +39,6 @@ type ( AttachPwd string // Password required to attach to this VM StartTime time.Time } - - endOfExecCallback func(vm *VM) ) const ( @@ -235,7 +233,7 @@ func (vm *VM) validate() error { for email, accessCaps := range vm.v.Access { _, err := mail.ParseAddress(email) if err != nil { - return errors.New("Invalid email") + return errors.New("invalid email") } if err := caps.ValidateVMAccessCaps(accessCaps); err != nil { return err @@ -350,11 +348,11 @@ func validateUsbDevs(devs []string) error { for _, dev := range devs { ids := strings.Split(dev, ":") // Extracts vendorID (vid) and productID (pid) if len(ids) != 2 { // expect exactly two values: vid and pid - return errors.New("Invalid USB device syntax") + return errors.New("invalid USB device syntax") } vid, pid := ids[0], ids[1] if !isUsbId(vid) || !isUsbId(pid) { - return errors.New("Invalid USB vendor/product ID") + return errors.New("invalid USB vendor/product ID") } } return nil diff --git a/src/server/vms/vms.go b/src/server/vms/vms.go index 52ba1811540aff110ba872ea636349429d546af5..edb1a7060c2b3f594aafa0584de36dac7ad14b1f 100644 --- a/src/server/vms/vms.go +++ b/src/server/vms/vms.go @@ -56,7 +56,7 @@ func GetVMsInstance() *VMs { func InitVMs() error { vmsDir := conf.VMsDir vms = &VMs{m: make(map[string]*VM), pwdToVM: make(map[string]uuid.UUID), mutexPwdToVM: new(sync.Mutex), dir: vmsDir, rwlock: new(sync.RWMutex), mutexUsedPorts: new(sync.Mutex), usedRAM: 0} - for i, _ := range vms.usedPorts { + for i := range vms.usedPorts { vms.usedPorts[i] = false } vms.usedPorts[conf.Core.APIDefaultPort] = true @@ -194,11 +194,11 @@ func (vms *VMs) DeleteVM(vmID uuid.UUID) error { defer vm.mutex.Unlock() if vm.IsRunning() { - return errors.New("Failed deleting VM: VM must be stopped") + return errors.New("failed deleting VM: VM must be stopped") } if vm.IsDiskBusy() { - return errors.New("Failed deleting VM: disk in use (busy)") + return errors.New("failed deleting VM: disk in use (busy)") } // Deletes the VM's files (and directories). @@ -432,7 +432,7 @@ func (vms *VMs) allocateSpiceRandomPort() (int, error) { for { if !isFreePortLeft() { - return -1, errors.New("No free port left") + return -1, errors.New("no free port left") } port := utils.Rand(minPort, maxPort) if !vms.usedPorts[port] { @@ -482,7 +482,7 @@ func (vms *VMs) allocateAttachPwd(attachPwd string, vmID uuid.UUID) error { _, exists := vms.pwdToVM[attachPwd] if exists { - return errors.New("vms.allocateAttachPwd: password already reserved!") + return errors.New("vms.allocateAttachPwd: password already reserved") } vms.pwdToVM[attachPwd] = vmID return nil @@ -511,7 +511,7 @@ func (vms *VMs) KillVM(vmID uuid.UUID) error { defer vm.mutex.Unlock() if !vm.IsRunning() { - return errors.New("Failed killing VM: VM must be running") + return errors.New("failed killing VM: VM must be running") } // Sends a SIGINT signal to terminate the QEMU process. @@ -540,7 +540,7 @@ func (vms *VMs) ShutdownVM(vmID uuid.UUID) error { defer vm.mutex.Unlock() if !vm.IsRunning() { - return errors.New("Shutdown failed: VM must be running") + return errors.New("shutdown failed: VM must be running") } // Function that gracefully shutdowns a running VM. @@ -589,7 +589,7 @@ func (vms *VMs) RebootVM(vmID uuid.UUID) error { defer vm.mutex.Unlock() if !vm.IsRunning() { - return errors.New("Reboot failed: VM must be running") + return errors.New("reboot failed: VM must be running") } // Function that reboots a running VM. @@ -714,7 +714,7 @@ func (vms *VMs) SetVMAccess(vmID uuid.UUID, user *users.User, destUserEmail stri userCaps := vm.v.Access[user.Email] _, exists := userCaps[caps.CAP_VM_SET_ACCESS] if !exists { - return errors.New("Insufficient capability") + return errors.New("insufficient capability") } } } @@ -753,7 +753,7 @@ func (vms *VMs) DeleteVMAccess(vmID uuid.UUID, user *users.User, destUserEmail s userCaps := vm.v.Access[user.Email] _, exists := userCaps[caps.CAP_VM_SET_ACCESS] if !exists { - return errors.New("Insufficient capability") + return errors.New("insufficient capability") } } }