Skip to content
Snippets Groups Projects
Select Git revision
  • 5aa5c2303b2a132a17de81dddf6d2da087eab946
  • live_exam_os_ubuntu default protected
2 results

vmDelAccess.go

Blame
  • vmDelAccess.go 3.99 KiB
    package cmdVM
    
    import (
    	"encoding/csv"
    	"errors"
    	"io"
    	"net/mail"
    	u "nexus-client/utils"
    	g "nexus-libclient/globals"
    	"nexus-libclient/utils"
    	libclient "nexus-libclient/vm"
    	"os"
    )
    
    type DelAccess struct {
    	Name string
    }
    
    func (cmd *DelAccess) GetName() string {
    	return cmd.Name
    }
    
    func (cmd *DelAccess) GetDesc() []string {
    	return []string{
    		"Removes a user's VM access in one or more VMs.",
    		"If not the VM's owner: requires VM_SET_ACCESS user capability and VM_SET_ACCESS VM access capability."}
    }
    
    func (cmd *DelAccess) PrintUsage() {
    	for _, desc := range cmd.GetDesc() {
    		u.PrintlnErr(desc)
    	}
    	u.PrintlnErr("―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――")
    	u.PrintlnErr("USAGE: " + cmd.GetName() + " [ID ...] [regex ...] email")
    	u.PrintlnErr("       " + cmd.GetName() + " file.csv")
    	u.PrintlnErr("―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――")
    	const usage string = `file.csv   2-column CSV file specifying which VMs must have which VM access removed:
                   column1    VM ID
                   column2    email for which the VM Access must be removed`
    	u.PrintlnErr(usage)
    	printRegexUsageDetails()
    }
    
    func (cmd *DelAccess) Run(args []string) int {
    	argc := len(args)
    	if argc < 1 {
    		cmd.PrintUsage()
    		return 1
    	}
    
    	statusCode := 0
    
    	if argc == 1 {
    		// Single argument and it's a CSV file
    		csvFile := args[0]
    
    		file, err := os.Open(csvFile)
    		if err != nil {
    			u.PrintlnErr("Error: " + err.Error())
    			return 1
    		}
    		defer file.Close()
    		reader := csv.NewReader(file)
    		reader.Comma = g.CsvFieldSeparator // specify the column separator
    		reader.Comment = '#'               // lines starting with this symbol are to be ignored
    		line := 0
    		for {
    			line += 1
    			columns, err := reader.Read()
    			if err == io.EOF {
    				break
    			}
    			if err != nil {
    				u.PrintlnErr("FAILED reading " + err.Error())
    				statusCode = 1
    				continue
    			}
    
    			columnCount := len(columns)
    			if columnCount != 2 {
    				u.PrintlnErr("FAILED reading record on line ", line, ": expecting 2 columns")
    				statusCode = 1
    				continue
    			}
    
    			vmID := columns[0]
    
    			email := columns[1]
    			if !utils.IsEmail(email) {
    				u.PrintlnErr("FAILED reading record on line ", line, ": ", email, " is not a valid email")
    				statusCode = 1
    				continue
    			}
    
    			if err := libclient.VMDelAccess(vmID, vmID, email); err != nil {
    				u.PrintlnErr(err)
    				statusCode = 1
    			} else {
    				u.Println("Successfully removed VM access for " + email + " in VM \"" + vmID + "\"")
    			}
    		}
    	} else {
    		// Multiple arguments: not a CSV file
    
    		email, patterns, err := cmd.parseArgs(args)
    		if err != nil {
    			u.PrintlnErr(err)
    			return 1
    		}
    
    		vms, err := getFilteredVMs(libclient.GetEditAccessVMs, patterns)
    		if err != nil {
    			u.PrintlnErr(err)
    			return 1
    		}
    
    		if len(vms) == 0 {
    			u.PrintlnErr("Error: VM(s) not found.")
    			return 1
    		}
    
    		for _, vm := range vms {
    			if err := libclient.VMDelAccess(vm.ID.String(), vm.Name, email); err != nil {
    				u.PrintlnErr(err)
    				statusCode = 1
    			} else {
    				u.Println("Successfully removed VM access for " + email + " in VM \"" + vm.Name + "\"")
    			}
    		}
    	}
    
    	return statusCode
    }
    
    func (cmd *DelAccess) parseArgs(args []string) (string, []string, error) {
    	var patterns []string
    	emailFound := false
    	var email string
    
    	for _, arg := range args {
    		parsed, err := mail.ParseAddress(arg)
    		if err != nil {
    			// Not an email address, then must be a "pattern" (ID or regex)
    			patterns = append(patterns, arg)
    		} else {
    			// An email address was found
    			if emailFound {
    				return "", nil, errors.New("Only one email address must be specified")
    			}
    			email = parsed.Address
    			emailFound = true
    		}
    	}
    
    	if !emailFound {
    		return "", nil, errors.New("An email address must be specified")
    	}
    
    	return email, patterns, nil
    }