Skip to content
Snippets Groups Projects
Select Git revision
  • 7dc61c6e80907453cbab3324adfb61272c71f8a7
  • master default protected
2 results

pubmedApi.py

Blame
  • helper.go 5.76 KiB
    package cmdVM
    
    import (
        "fmt"
        "regexp"
        "errors"
        "strings"
        "encoding/json"
        "nexus-client/cmd"
        u "nexus-client/utils"
        g "nexus-client/globals"
        "github.com/google/uuid"
        "github.com/go-resty/resty/v2"
    )
    
    // Converts a VM structure into a pretty string.
    func (vm *VMNetworkSerialized)String() string {
        output, err := json.MarshalIndent(vm, "", "    ")
        if err != nil {
            return err.Error()
        }
        return string(output)
    }
    
    func printRegexUsage(c cmd.Command) {
        for _, desc := range c.GetDesc() {
            u.PrintlnErr(desc)
        }
        u.PrintlnErr("―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――")
        u.PrintlnErr("USAGE: ",c.GetName()," [ID ...] [regex ...]")
        u.PrintlnErr("―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――")
    }
    
    func printRegexUsageDetails() {
        u.PrintlnErr("The action only applies to VMs matching the specified IDs or regexes.")
        const usage string = `Any number of IDs or regexes can be specified.
    The regex only matches the VM's name and is case-insensitive.
    Regex examples:
    "."   -> matches any VMs
    "bla" -> matches any VMs containing "bla" in their name`
        u.PrintlnErr(usage)
    }
    
    // Prints a list of filtered VMs for a given route.
    // Return 0 if everything went well or 1 in case of failure.
    func printFilteredVMs(c cmd.Command, args []string, route string) int {
        if len(args) < 1 {
            c.PrintUsage()
            return 1
        }
    
        // Helper function to remove an element from a string array at a given index
        removeArgAtIndex := func (slice []string, index int) []string {
            return append(slice[:index], slice[index+1:]...)
        }
    
        // Check if a "-l" argument is specified
        foundLongOutputFlag := -1
        for idx, arg := range args {
            if arg == "-l" {
                foundLongOutputFlag = idx
            }
        }
    
        if foundLongOutputFlag >= 0 {
            removeArgAtIndex(args, foundLongOutputFlag)
        }
    
        vms, err := getFilteredVMs(route, args)
        if err != nil {
            u.PrintlnErr("Error: "+err.Error())
            return 1
        }
    
        if foundLongOutputFlag >= 0 {
            for _, vm := range vms {
                u.Println(vm.String())
            }
        } else {
            // Compute the length of the longest name and state (used for padding columns)
            nameLen := 0
            idLen := 0
            stateLen := 0
            for _, vm := range vms {
                l := len(vm.Name)
                if l > nameLen {
                    nameLen = l
                }
                idLen = len(vm.ID.String())  // ID is a UUID of constant length
                l = len(vm.State)
                if l > stateLen {
                    stateLen = l
                }
            }
    
            paddedFmt := fmt.Sprintf("%%-%ds | %%-%ds | %%-%ds\n",nameLen, idLen, stateLen)
    
            for _, vm := range vms {
                fmt.Printf(paddedFmt, vm.Name, vm.ID, vm.State)
            }
        }
    
        return 0
    }
    
    // Returns a list of filtered VMs for a given route.
    // Filters are based on patterns describing IDs or regexes.
    // Patterns can either be:
    // - any number of "VM IDs" (UUID)
    // - any number of "VM names"
    // - any combination of "VM IDs" and "VM names"
    // - any regular expression (it applies to the VM's name only)
    // Remark: the matching is case-insensitive
    // Regular expression examples:
    //   "."   -> matches everything
    //   "bla" -> matches any VM name containing "bla"
    func getFilteredVMs(route string, patterns []string) ([]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
    
        for _, pattern := range patterns {
            _, err := uuid.Parse(pattern)
            if err != nil {
                regexes = append(regexes, pattern)
            } else {
                ids = append(ids, pattern)
            }
        }
    
        resp, err := client.R().Get(host+route)
        if err != nil {
            return nil, err
        }
    
        vmsList := []VMNetworkSerialized{}
    
        if resp.IsSuccess() {
            vms, err := getVMs(resp)
            if err != nil {
                return nil, err
            }
    
            for _, vm := range vms {
                found := false
                for _, id := range ids {
                    if id == vm.ID.String() {
                        vmsList = append(vmsList, vm)
                        found = true
                        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("Error: "+resp.Status()+": "+resp.String())
        }
    }
    
    // Retrieves all VMs (no filtering).
    func getVMs(resp *resty.Response) ([]VMNetworkSerialized, error) {
        vms := []VMNetworkSerialized{}
        if err := json.Unmarshal(resp.Body(), &vms); err != nil {
            return nil, err
        }
        return vms, nil
    }
    
    // Retrieve a single VM.
    func getVM(resp *resty.Response) (*VMNetworkSerialized, error) {
        var vm *VMNetworkSerialized = &VMNetworkSerialized{}
        if err := json.Unmarshal(resp.Body(), vm); err != nil {
            return vm, err
        }
        return vm, nil
    }