diff --git a/src/client_cli/cmdVM/vmCreate.go b/src/client_cli/cmdVM/vmCreate.go index 3bcbc8e863c5a7c677e9a6614a00e20f7c4dd1c9..bd463f2b30f80d2dadddfd51648ec758fd718ab9 100644 --- a/src/client_cli/cmdVM/vmCreate.go +++ b/src/client_cli/cmdVM/vmCreate.go @@ -1,7 +1,10 @@ package cmdVM import ( + "os" + "errors" "strconv" + "encoding/csv" u "nexus-client/utils" g "nexus-client/globals" ) @@ -20,15 +23,17 @@ func (cmd *Create)GetDesc() string { func (cmd *Create)PrintUsage() { u.PrintlnErr(cmd.GetDesc()) - u.PrintlnErr("Usage: "+cmd.Name+" name cpus ram nic template [count]") + u.PrintlnErr("Usage: "+cmd.Name+" name cpus ram nic template [count | file.csv]") const usage string = `name name of the VM -cpus number of CPUs, between 1 and 16 -ram amount of RAM in MB, between 512 and 32768 -nic network interface, either "none" or "user" -template ID of the template to VM will be based on -count number of VMs to create (if not specified, one is created) - if specified and > 1, name is postfixed with [n] - where n ranges from 1..count` +cpus Number of CPUs, between 1 and 16. +ram Amount of RAM in MB, between 512 and 32768. +nic Network interface, either "none" or "user". +template ID of the template to VM will be based on. +count Number of VMs to create (if not specified, one is created). + If specified and > 1, the VM name is postfixed with [n], + where n ranges from 1..count. +file.csv Single-column CSV file defining the students names. + Each VM name is postfixed with each entry in the CSV file.` u.PrintlnErr(usage) } @@ -56,18 +61,33 @@ func (cmd *Create)Run(args []string) int { nic := args[3] template := args[4] count := 1 + var csvEntries []string = nil + + // If there is a 6th argument, checks whether it's a number or a CSV file. if argc == 6 { count, err = strconv.Atoi(args[5]) if err != nil { - u.PrintlnErr("Invalid count") - return 1 - } - if count < 1 { - u.PrintlnErr("count must be > 0") - return 1 + // It's not a number, so we assume it's a CSV file. + // Checks if the file exists. + file := args[5] + csvEntries, err = cmd.getCSVColumn(file, 0) + if err != nil { + u.PrintlnErr(err.Error()) + return 1 + } + count = len(csvEntries) + } else { + if count < 1 { + u.PrintlnErr("count must be > 0") + return 1 + } } } + // At this point: + // if csvFile == "" -> we must create count VMs + // otherwise -> we parse the CSV to know how many VMs to create + type VMArgs struct { Name string Cpus int @@ -87,8 +107,12 @@ func (cmd *Create)Run(args []string) int { statusCode := 0 for i := 1; i <= count; i++ { - if count > 1 { - vmArgs.Name = name+" ["+strconv.Itoa(i)+"]" + if csvEntries == nil { + if count > 1 { + vmArgs.Name = name+" ["+strconv.Itoa(i)+"]" + } + } else { + vmArgs.Name = name+" ["+csvEntries[i-1]+"]" } resp, err := client.R().SetBody(vmArgs).Post(host+"/vms") @@ -112,3 +136,22 @@ func (cmd *Create)Run(args []string) int { return statusCode } + +func (cmd *Create)getCSVColumn(csvFile string, column int) ([]string, error) { + file, err := os.Open(csvFile) + if err != nil { + return nil, errors.New("Failed opening \""+csvFile+"\"") + } + reader := csv.NewReader(file) + records, err := reader.ReadAll() + if err != nil { + return nil, errors.New("\""+csvFile+"\": "+err.Error()) + } + + var entries []string + for _, col := range(records) { + entries = append(entries, col[column]) + } + + return entries, nil +} \ No newline at end of file