diff --git a/README.md b/README.md index e0bd622bf9464eb75da0ff371f946ba3f35243f3..de96a67dddf1937395dabdf83225293e862aa10f 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ List of supported Commands: vmdelaccess Delete a user's VM access in one or more VMs (regex matching). tpllist List available templates (regex matching). tplcreate Create a template, either from an existing VM or from a .qcow file. - tpldel Delete one or more templates. + tpldel Delete one or more templates (regex matching). ``` When attached to a VM's desktop (`vmattach` command), ctrl+F12 toggles between fullscreen/non-fullscreen modes. @@ -293,6 +293,11 @@ Delete template `8ae56a30-3195-4aea-960d-abb45c47f99e`: nexus-client tpldel 8ae56a30-3195-4aea-960d-abb45c47f99e ``` +Delete all templates matching the "test" pattern: +``` +nexus-client tpldel test +``` + ## nexus-client-exam ### Compiling nexus-client-exam diff --git a/src/client_cli/cmdTemplate/helper.go b/src/client_cli/cmdTemplate/helper.go index 9fbd514eaa88b4f33fd45a6ffd6120d0ff28baf7..394f685d0596b9a3f622e2f7f62aefb14bafd99a 100644 --- a/src/client_cli/cmdTemplate/helper.go +++ b/src/client_cli/cmdTemplate/helper.go @@ -1,8 +1,9 @@ package cmdTemplate import ( - "strings" + "errors" "regexp" + "strings" "encoding/json" "nexus-client/cmd" u "nexus-client/utils" @@ -30,11 +31,11 @@ func (tpl *Template)String() string { return string(output) } -func printUsage(c cmd.Command) { +func printUsage(c cmd.Command, action string) { u.PrintlnErr(c.GetDesc()) u.PrintlnErr("Usage: ",c.GetName()," [ID ...] [regex ...]") - const usage string = `Only templates matching the specified IDs or regexes will be listed. -Any number of IDs or regexes can be specified. + u.PrintlnErr("Only templates matching the specified IDs or regexes will be "+action+".") + const usage string = `Any number of IDs or regexes can be specified. The regex only matches the templates's name and is case-insensitive. Regex examples: "" -> matches any templates @@ -43,6 +44,27 @@ Regex examples: u.PrintlnErr(usage) } +// Prints a list of filtered templates for a given route. +// Return 0 if everything went well or 1 in case of failure. +func printFilteredTemplates(c cmd.Command, args []string, route string) int { + if len(args) == 0 { + c.PrintUsage() + return 1 + } + + templates, err := getFilteredTemplates(route, args) + if err != nil { + u.PrintlnErr("Error: "+err.Error()) + return 1 + } + + for _, template := range templates { + u.Println(template.Name+" | "+template.ID.String()+" | "+template.Access) + } + + return 0 +} + // Returns a list of filtered templates for a given route. // Filters are based on patterns describing IDs or regexes. // Patterns can either be: @@ -55,10 +77,9 @@ Regex examples: // "" -> matches everything // "." -> matches everything // "bla" -> matches any template name containing "bla" -func printFilteredTemplates(c cmd.Command, patterns []string, route string) int { +func getFilteredTemplates(route string, patterns []string) ([]Template, error) { if len(patterns) < 1 { - c.PrintUsage() - return 1 + return nil, errors.New("At least one ID or regex must be specified") } client := g.GetInstance().Client @@ -78,22 +99,22 @@ func printFilteredTemplates(c cmd.Command, patterns []string, route string) int resp, err := client.R().Get(host+route) if err != nil { - u.PrintlnErr("Error: "+err.Error()) - return 1 + return nil, err } + templatesList := []Template{} + if resp.IsSuccess() { templates, err := getTemplates(resp) if err != nil { - u.PrintlnErr("Error: "+err.Error()) - return 1 + return nil, err } for _, template := range templates { found := false for _, id := range ids { if id == template.ID.String() { - u.Println(template.String()) + templatesList = append(templatesList, template) found = true break } @@ -104,22 +125,22 @@ func printFilteredTemplates(c cmd.Command, patterns []string, route string) int for _, regex := range regexes { match, err := regexp.MatchString(strings.ToLower(regex), strings.ToLower(template.Name)) if err != nil { - u.PrintlnErr("Error matching \""+regex+"\": "+err.Error()) + return nil, errors.New("Error matching \""+regex+"\": "+err.Error()) } else { if match { - u.Println(template.String()) + templatesList = append(templatesList, template) break } } } } - return 0 + return templatesList, nil } else { - u.PrintlnErr("Error: "+resp.Status()+": "+resp.String()) - return 1 + return nil, errors.New("Error: "+resp.Status()+": "+resp.String()) } } +// Retrieves all templates (no filtering). func getTemplates(resp *resty.Response) ([]Template, error) { templates := []Template{} if err := json.Unmarshal(resp.Body(), &templates); err != nil { diff --git a/src/client_cli/cmdTemplate/templateDel.go b/src/client_cli/cmdTemplate/templateDel.go index 9f1713bf8d985862955789959e98defb1a1fdbb7..0c70aa877c90bd1e5f67ad0e282c7a3b169a1ab4 100644 --- a/src/client_cli/cmdTemplate/templateDel.go +++ b/src/client_cli/cmdTemplate/templateDel.go @@ -14,12 +14,11 @@ func (cmd *Del)GetName() string { } func (cmd *Del)GetDesc() string { - return "Delete one or more templates." + return "Delete one or more templates (regex matching)." } func (cmd *Del)PrintUsage() { - u.PrintlnErr(cmd.GetDesc()) - u.PrintlnErr("Usage: "+cmd.Name+" id [id ...]") + printUsage(cmd, "deleted") } func (cmd *Del)Run(args []string) int { @@ -32,23 +31,35 @@ func (cmd *Del)Run(args []string) int { return 1 } + templates, err := getFilteredTemplates("/templates", args) + if err != nil { + u.PrintlnErr(err.Error()) + return 1 + } + + if len(templates) == 0 { + u.PrintlnErr("No templates to delete!") + return 1 + } + statusCode := 0 - // Iterates through each template to delete - for i:= range(args) { - id := args[i] - resp, err := client.R().Delete(host+"/templates/"+id) + for _, template := range(templates) { + uuid := template.ID.String() + resp, err := client.R().Delete(host+"/templates/"+uuid) if err != nil { - u.PrintlnErr("Error: "+err.Error()) + u.PrintlnErr("Failed deleting template \""+template.Name+"\" | "+uuid+" : "+err.Error()) statusCode = 1 } else { if resp.IsSuccess() { - u.Println("Template "+id+" deleted.") + u.Println("Deleted template \""+template.Name+"\" | "+uuid) } else { - u.PrintlnErr("Error: "+resp.Status()+": "+resp.String()) + u.PrintlnErr("Failed deleting template \""+template.Name+"\" | "+uuid+" : "+resp.Status()+": "+resp.String()) statusCode = 1 } } + } + return statusCode } diff --git a/src/client_cli/cmdTemplate/templateList.go b/src/client_cli/cmdTemplate/templateList.go index 49c3916d60cd569f38fa8c1849bac9d77526f57b..5e621045bc8f5dfb4b1cc7d25379404b6f4ae5df 100644 --- a/src/client_cli/cmdTemplate/templateList.go +++ b/src/client_cli/cmdTemplate/templateList.go @@ -13,7 +13,7 @@ func (cmd *List)GetDesc() string { } func (cmd *List)PrintUsage() { - printUsage(cmd) + printUsage(cmd, "listed") } func (cmd *List)Run(args []string) int { diff --git a/src/client_cli/cmdVM/helper.go b/src/client_cli/cmdVM/helper.go index bce68e1540a5dc9d5ba438b2fad511319a2dd4ec..c62a4140843ce4ab1e27480405ec2de1635e80ca 100644 --- a/src/client_cli/cmdVM/helper.go +++ b/src/client_cli/cmdVM/helper.go @@ -196,4 +196,13 @@ func getVMs(resp *resty.Response) ([]VM, error) { return nil, err } return vms, nil +} + +// Retrieve a single VM. +func getVM(resp *resty.Response) (*VM, error) { + var vm *VM = &VM{} + if err := json.Unmarshal(resp.Body(), vm); err != nil { + return vm, err + } + return vm, nil } \ No newline at end of file diff --git a/src/client_cli/cmdVM/vmCreate.go b/src/client_cli/cmdVM/vmCreate.go index e7fe682ef4aa96ad3a2426bb780ed6153a4f24a3..3bcbc8e863c5a7c677e9a6614a00e20f7c4dd1c9 100644 --- a/src/client_cli/cmdVM/vmCreate.go +++ b/src/client_cli/cmdVM/vmCreate.go @@ -97,7 +97,12 @@ func (cmd *Create)Run(args []string) int { statusCode = 1 } else { if resp.IsSuccess() { - u.Println("Created VM \""+vmArgs.Name+"\"") + vm, err := getVM(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 diff --git a/src/client_cli/cmdVM/vmDel.go b/src/client_cli/cmdVM/vmDel.go index 5feb37cec6bcf19e615b3ab7a0c14ca29e554ed7..f1b893f286e0236e811d6c7aff9f2c1888733a87 100644 --- a/src/client_cli/cmdVM/vmDel.go +++ b/src/client_cli/cmdVM/vmDel.go @@ -48,13 +48,13 @@ func (cmd *Del)Run(args []string) int { uuid := vm.ID.String() resp, err := client.R().Delete(host+"/vms/"+uuid) if err != nil { - u.PrintlnErr("Failed deleting VM \""+vm.Name+"\" ("+uuid+"): "+err.Error()) + u.PrintlnErr("Failed deleting VM \""+vm.Name+"\" | "+uuid+" : "+err.Error()) statusCode = 1 } else { if resp.IsSuccess() { - u.Println("Deleted VM \""+vm.Name+"\" ("+uuid+")") + u.Println("Deleted VM \""+vm.Name+"\" | "+uuid) } else { - u.PrintlnErr("Failed deleting VM \""+vm.Name+"\" ("+uuid+"): "+resp.Status()+": "+resp.String()) + u.PrintlnErr("Failed deleting VM \""+vm.Name+"\" | "+uuid+" : "+resp.Status()+": "+resp.String()) statusCode = 1 } } diff --git a/src/client_cli/cmdVM/vmDelAccess.go b/src/client_cli/cmdVM/vmDelAccess.go index 8e33cf0eaee1c014ce568e1d2eb4bdb08a9b0e82..01163151ca6715d1c5b2423b6b561f7a07e5c279 100644 --- a/src/client_cli/cmdVM/vmDelAccess.go +++ b/src/client_cli/cmdVM/vmDelAccess.go @@ -69,13 +69,13 @@ func (cmd *DelAccess)Run(args []string) int { uuid := vm.ID.String() resp, err := client.R().Delete(host+"/vms/"+uuid+"/access/"+email) if err != nil { - u.PrintlnErr("Failed removing VM access for "+email+" in VM \""+vm.Name+"\" ("+uuid+"): "+err.Error()) + u.PrintlnErr("Failed removing VM access for "+email+" in VM \""+vm.Name+"\" | "+uuid+" : "+err.Error()) statusCode = 1 } else { if resp.IsSuccess() { - u.Println("Removed VM access for "+email+" in VM \""+vm.Name+"\" ("+uuid+")") + u.Println("Removed VM access for "+email+" in VM \""+vm.Name+"\" | "+uuid) } else { - u.PrintlnErr("Failed removing VM access for "+email+" in VM \""+vm.Name+"\" ("+uuid+"): "+resp.Status()+": "+resp.String()) + u.PrintlnErr("Failed removing VM access for "+email+" in VM \""+vm.Name+"\" | "+uuid+" : "+resp.Status()+": "+resp.String()) statusCode = 1 } } diff --git a/src/client_cli/cmdVM/vmEdit.go b/src/client_cli/cmdVM/vmEdit.go index 2da538380ff9e04f370a018a4f4832db14f6bcc2..007fd464b37e47d7b3687a6be6ce58cbd84d94cc 100644 --- a/src/client_cli/cmdVM/vmEdit.go +++ b/src/client_cli/cmdVM/vmEdit.go @@ -82,13 +82,13 @@ func (cmd *Edit)Run(args []string) int { uuid := vm.ID.String() resp, err := client.R().SetBody(vmParams).Put(host+"/vms/"+uuid) if err != nil { - u.PrintlnErr("Failed editing VM \""+vm.Name+"\" ("+uuid+"): "+err.Error()) + u.PrintlnErr("Failed editing VM \""+vm.Name+"\" | "+uuid+" : "+err.Error()) statusCode = 1 } else { if resp.IsSuccess() { - u.Println("Edited VM \""+vm.Name+"\" ("+uuid+")") + u.Println("Edited VM \""+vm.Name+"\" | "+uuid) } else { - u.PrintlnErr("Failed editing VM \""+vm.Name+"\" ("+uuid+"): "+resp.Status()+": "+resp.String()) + u.PrintlnErr("Failed editing VM \""+vm.Name+"\" | "+uuid+" : "+resp.Status()+": "+resp.String()) statusCode = 1 } } diff --git a/src/client_cli/cmdVM/vmSetAccess.go b/src/client_cli/cmdVM/vmSetAccess.go index 58d0d5762b4ad10c58df2ff0f6f152018177c4f0..08159bec143fc118a4363cf31f460bf8174525b0 100644 --- a/src/client_cli/cmdVM/vmSetAccess.go +++ b/src/client_cli/cmdVM/vmSetAccess.go @@ -75,13 +75,13 @@ func (cmd *SetAccess)Run(args []string) int { uuid := vm.ID.String() resp, err := client.R().SetBody(userUpdatedAccessArgs).Put(host+"/vms/"+uuid+"/access/"+email) if err != nil { - u.PrintlnErr("Failed removing VM access for "+email+" in VM \""+vm.Name+"\" ("+uuid+"): "+err.Error()) + u.PrintlnErr("Failed removing VM access for "+email+" in VM \""+vm.Name+"\" | "+uuid+" : "+err.Error()) statusCode = 1 } else { if resp.IsSuccess() { - u.Println("Removed VM access for "+email+" in VM \""+vm.Name+"\" ("+uuid+")") + u.Println("Removed VM access for "+email+" in VM \""+vm.Name+"\" | "+uuid) } else { - u.PrintlnErr("Failed removing VM access for "+email+" in VM \""+vm.Name+"\" ("+uuid+"): "+resp.Status()+": "+resp.String()) + u.PrintlnErr("Failed removing VM access for "+email+" in VM \""+vm.Name+"\" | "+uuid+" : "+resp.Status()+": "+resp.String()) statusCode = 1 } } diff --git a/src/client_cli/cmdVM/vmStart.go b/src/client_cli/cmdVM/vmStart.go index cea4e972aa00e02c19c5869aeaed1ce16399910a..3ed02d2e82ad7718a293a63755f6e67d670f24b4 100644 --- a/src/client_cli/cmdVM/vmStart.go +++ b/src/client_cli/cmdVM/vmStart.go @@ -48,13 +48,13 @@ func (cmd *Start)Run(args []string) int { uuid := vm.ID.String() resp, err := client.R().Put(host+"/vms/"+uuid+"/start") if err != nil { - u.PrintlnErr("Failed starting VM \""+vm.Name+"\" ("+uuid+"): "+err.Error()) + u.PrintlnErr("Failed starting VM \""+vm.Name+"\" | "+uuid+" : "+err.Error()) statusCode = 1 } else { if resp.IsSuccess() { - u.Println("Started VM \""+vm.Name+"\" ("+uuid+")") + u.Println("Started VM \""+vm.Name+"\" | "+uuid) } else { - u.PrintlnErr("Failed starting VM \""+vm.Name+"\" ("+uuid+"): "+resp.Status()+": "+resp.String()) + u.PrintlnErr("Failed starting VM \""+vm.Name+"\" | "+uuid+" : "+resp.Status()+": "+resp.String()) statusCode = 1 } } diff --git a/src/client_cli/cmdVM/vmStop.go b/src/client_cli/cmdVM/vmStop.go index b1b8bdce248ec02b1f139cf4dd3dd52ff1c7b137..73180e1076201fdd0cec97353d9acd110ebf496d 100644 --- a/src/client_cli/cmdVM/vmStop.go +++ b/src/client_cli/cmdVM/vmStop.go @@ -48,13 +48,13 @@ func (cmd *Stop)Run(args []string) int { uuid := vm.ID.String() resp, err := client.R().Put(host+"/vms/"+uuid+"/stop") if err != nil { - u.PrintlnErr("Failed stopping VM \""+vm.Name+"\" ("+uuid+"): "+err.Error()) + u.PrintlnErr("Failed stopping VM \""+vm.Name+"\" | "+uuid+" : "+err.Error()) statusCode = 1 } else { if resp.IsSuccess() { - u.Println("Stopped VM \""+vm.Name+"\" ("+uuid+")") + u.Println("Stopped VM \""+vm.Name+"\" | "+uuid) } else { - u.PrintlnErr("Failed stopping VM \""+vm.Name+"\" ("+uuid+"): "+resp.Status()+": "+resp.String()) + u.PrintlnErr("Failed stopping VM \""+vm.Name+"\" | "+uuid+" : "+resp.Status()+": "+resp.String()) statusCode = 1 } }