From b25df2465640c206fc28f6e40d0ee9c3430e27b3 Mon Sep 17 00:00:00 2001
From: Florent Gluck <florent.gluck@hesge.ch>
Date: Tue, 30 Aug 2022 00:20:35 +0200
Subject: [PATCH] First usable version of nexush

---
 src/cmd/Command.go                            |  29 +++++
 src/{nexus-cli => }/cmd/go.mod                |   0
 src/{nexus-cli => }/cmdLogin/go.mod           |   0
 src/{nexus-cli => }/cmdLogin/login.go         |   4 +-
 src/{nexus-cli => }/cmdTemplate/go.mod        |   0
 src/{nexus-cli => }/cmdTemplate/helper.go     |   2 -
 .../cmdTemplate/templateCreate.go             |   0
 .../cmdTemplate/templateCreate.go.new         |   0
 .../cmdTemplate/templateDel.go                |   0
 .../cmdTemplate/templateList.go               |   0
 src/{nexus-cli => }/cmdUser/go.mod            |   0
 src/{nexus-cli => }/cmdUser/go.sum            |   0
 src/{nexus-cli => }/cmdUser/helper.go         |   1 -
 src/{nexus-cli => }/cmdUser/userAdd.go        |   0
 src/{nexus-cli => }/cmdUser/userDel.go        |   0
 src/{nexus-cli => }/cmdUser/userList.go       |   0
 src/{nexus-cli => }/cmdUser/userSetCaps.go    |   0
 src/{nexus-cli => }/cmdUser/userUpdatePwd.go  |   0
 src/{nexus-cli => }/cmdUser/userWhoami.go     |   0
 src/{nexus-cli => }/cmdVM/go.mod              |   0
 src/{nexus-cli => }/cmdVM/go.sum              |   0
 src/{nexus-cli => }/cmdVM/helper.go           |   2 -
 src/{nexus-cli => }/cmdVM/vmAttach.go         |   0
 src/{nexus-cli => }/cmdVM/vmCreate.go         |   0
 src/{nexus-cli => }/cmdVM/vmCred2pdf.go       |   0
 src/{nexus-cli => }/cmdVM/vmDel.go            |   0
 src/{nexus-cli => }/cmdVM/vmDelAccess.go      |   1 -
 src/{nexus-cli => }/cmdVM/vmEdit.go           |   1 -
 src/{nexus-cli => }/cmdVM/vmExportDir.go      |   0
 src/{nexus-cli => }/cmdVM/vmList.go           |   0
 src/{nexus-cli => }/cmdVM/vmListAttach.go     |   0
 src/{nexus-cli => }/cmdVM/vmListDel.go        |   0
 src/{nexus-cli => }/cmdVM/vmListEdit.go       |   0
 src/{nexus-cli => }/cmdVM/vmListEditAccess.go |   0
 src/{nexus-cli => }/cmdVM/vmListExportDir.go  |   0
 src/{nexus-cli => }/cmdVM/vmListStart.go      |   0
 src/{nexus-cli => }/cmdVM/vmListStop.go       |   0
 src/{nexus-cli => }/cmdVM/vmSetAccess.go      |   1 -
 src/{nexus-cli => }/cmdVM/vmShutdown.go       |   0
 src/{nexus-cli => }/cmdVM/vmStart.go          |   0
 src/{nexus-cli => }/cmdVM/vmStop.go           |   0
 src/nexus-cli/cmd/Command.go                  |   8 --
 src/nexus-cli/go.mod                          |  10 +-
 src/nexus-cli/nexus-cli.go                    |  14 +--
 src/nexush/go.mod                             |  30 ++++-
 src/nexush/go.sum                             |  28 +++++
 src/nexush/nexush.go                          | 111 +++++++++++++++++-
 47 files changed, 198 insertions(+), 44 deletions(-)
 create mode 100644 src/cmd/Command.go
 rename src/{nexus-cli => }/cmd/go.mod (100%)
 rename src/{nexus-cli => }/cmdLogin/go.mod (100%)
 rename src/{nexus-cli => }/cmdLogin/login.go (94%)
 rename src/{nexus-cli => }/cmdTemplate/go.mod (100%)
 rename src/{nexus-cli => }/cmdTemplate/helper.go (98%)
 rename src/{nexus-cli => }/cmdTemplate/templateCreate.go (100%)
 rename src/{nexus-cli => }/cmdTemplate/templateCreate.go.new (100%)
 rename src/{nexus-cli => }/cmdTemplate/templateDel.go (100%)
 rename src/{nexus-cli => }/cmdTemplate/templateList.go (100%)
 rename src/{nexus-cli => }/cmdUser/go.mod (100%)
 rename src/{nexus-cli => }/cmdUser/go.sum (100%)
 rename src/{nexus-cli => }/cmdUser/helper.go (99%)
 rename src/{nexus-cli => }/cmdUser/userAdd.go (100%)
 rename src/{nexus-cli => }/cmdUser/userDel.go (100%)
 rename src/{nexus-cli => }/cmdUser/userList.go (100%)
 rename src/{nexus-cli => }/cmdUser/userSetCaps.go (100%)
 rename src/{nexus-cli => }/cmdUser/userUpdatePwd.go (100%)
 rename src/{nexus-cli => }/cmdUser/userWhoami.go (100%)
 rename src/{nexus-cli => }/cmdVM/go.mod (100%)
 rename src/{nexus-cli => }/cmdVM/go.sum (100%)
 rename src/{nexus-cli => }/cmdVM/helper.go (98%)
 rename src/{nexus-cli => }/cmdVM/vmAttach.go (100%)
 rename src/{nexus-cli => }/cmdVM/vmCreate.go (100%)
 rename src/{nexus-cli => }/cmdVM/vmCred2pdf.go (100%)
 rename src/{nexus-cli => }/cmdVM/vmDel.go (100%)
 rename src/{nexus-cli => }/cmdVM/vmDelAccess.go (99%)
 rename src/{nexus-cli => }/cmdVM/vmEdit.go (99%)
 rename src/{nexus-cli => }/cmdVM/vmExportDir.go (100%)
 rename src/{nexus-cli => }/cmdVM/vmList.go (100%)
 rename src/{nexus-cli => }/cmdVM/vmListAttach.go (100%)
 rename src/{nexus-cli => }/cmdVM/vmListDel.go (100%)
 rename src/{nexus-cli => }/cmdVM/vmListEdit.go (100%)
 rename src/{nexus-cli => }/cmdVM/vmListEditAccess.go (100%)
 rename src/{nexus-cli => }/cmdVM/vmListExportDir.go (100%)
 rename src/{nexus-cli => }/cmdVM/vmListStart.go (100%)
 rename src/{nexus-cli => }/cmdVM/vmListStop.go (100%)
 rename src/{nexus-cli => }/cmdVM/vmSetAccess.go (99%)
 rename src/{nexus-cli => }/cmdVM/vmShutdown.go (100%)
 rename src/{nexus-cli => }/cmdVM/vmStart.go (100%)
 rename src/{nexus-cli => }/cmdVM/vmStop.go (100%)
 delete mode 100644 src/nexus-cli/cmd/Command.go

diff --git a/src/cmd/Command.go b/src/cmd/Command.go
new file mode 100644
index 0000000..9a5fa08
--- /dev/null
+++ b/src/cmd/Command.go
@@ -0,0 +1,29 @@
+package cmd
+
+import (
+	"strings"
+	u "nexus-client/utils"
+)
+
+type Command interface {
+	GetName() string
+	GetDesc() []string
+	PrintUsage()
+	Run(args []string) int   // Returns 0 if the Command was successful.
+}
+
+func Help(commands []Command, indent string) {
+	padding := 20
+	for _, cmd := range commands {
+		u.PrintlnErr("―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――")
+		cmdStr := indent+cmd.GetName()
+		u.PrintErr(cmdStr)
+		pad := strings.Repeat(" ", padding-len(cmd.GetName()))
+		for i, desc := range cmd.GetDesc() {
+			if i > 0 {
+				u.PrintErr(strings.Repeat(" ", len(cmdStr)))
+			}
+			u.PrintlnErr(pad+desc)
+		}
+	}
+}
diff --git a/src/nexus-cli/cmd/go.mod b/src/cmd/go.mod
similarity index 100%
rename from src/nexus-cli/cmd/go.mod
rename to src/cmd/go.mod
diff --git a/src/nexus-cli/cmdLogin/go.mod b/src/cmdLogin/go.mod
similarity index 100%
rename from src/nexus-cli/cmdLogin/go.mod
rename to src/cmdLogin/go.mod
diff --git a/src/nexus-cli/cmdLogin/login.go b/src/cmdLogin/login.go
similarity index 94%
rename from src/nexus-cli/cmdLogin/login.go
rename to src/cmdLogin/login.go
index 788a95b..9556f28 100644
--- a/src/nexus-cli/cmdLogin/login.go
+++ b/src/cmdLogin/login.go
@@ -39,7 +39,7 @@ func (cmd *Login)Run(args []string) int {
 
 	email := args[0]
 	pwd := args[1]
-	token, err := login(email, pwd)
+	token, err := GetToken(email, pwd)
 	if err != nil {
 		u.PrintlnErr("Error: "+err.Error())
 		return 1
@@ -54,7 +54,7 @@ func (cmd *Login)Run(args []string) int {
 // curl -X POST http://localhost:8000/login -H 'Content-Type: application/json' -d '{"email": "johndoe@nexus.org", "pwd":"pipomolo"}'
 // Returns a jwt token if authentication was successful:
 // {"token":"<jwt token>"}
-func login(user string, pwd string) (string, error) {
+func GetToken(user string, pwd string) (string, error) {
 	client := g.GetInstance().Client
 	host := g.GetInstance().Host
 
diff --git a/src/nexus-cli/cmdTemplate/go.mod b/src/cmdTemplate/go.mod
similarity index 100%
rename from src/nexus-cli/cmdTemplate/go.mod
rename to src/cmdTemplate/go.mod
diff --git a/src/nexus-cli/cmdTemplate/helper.go b/src/cmdTemplate/helper.go
similarity index 98%
rename from src/nexus-cli/cmdTemplate/helper.go
rename to src/cmdTemplate/helper.go
index 5931674..2a66de5 100644
--- a/src/nexus-cli/cmdTemplate/helper.go
+++ b/src/cmdTemplate/helper.go
@@ -40,7 +40,6 @@ func printUsage(c cmd.Command, action string) {
 	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
 "."   -> matches any templates
 "bla" -> matches any templates containing "bla"`
 	u.PrintlnErr(usage)
@@ -76,7 +75,6 @@ func printFilteredTemplates(c cmd.Command, args []string, route string) int {
 // - any regular expression (it applies to the template's name only)
 // Remark: the matching is case-insensitive
 // Regular expression examples:
-//   ""    -> matches everything
 //   "."   -> matches everything
 //   "bla" -> matches any template name containing "bla"
 func getFilteredTemplates(route string, patterns []string) ([]Template, error) {
diff --git a/src/nexus-cli/cmdTemplate/templateCreate.go b/src/cmdTemplate/templateCreate.go
similarity index 100%
rename from src/nexus-cli/cmdTemplate/templateCreate.go
rename to src/cmdTemplate/templateCreate.go
diff --git a/src/nexus-cli/cmdTemplate/templateCreate.go.new b/src/cmdTemplate/templateCreate.go.new
similarity index 100%
rename from src/nexus-cli/cmdTemplate/templateCreate.go.new
rename to src/cmdTemplate/templateCreate.go.new
diff --git a/src/nexus-cli/cmdTemplate/templateDel.go b/src/cmdTemplate/templateDel.go
similarity index 100%
rename from src/nexus-cli/cmdTemplate/templateDel.go
rename to src/cmdTemplate/templateDel.go
diff --git a/src/nexus-cli/cmdTemplate/templateList.go b/src/cmdTemplate/templateList.go
similarity index 100%
rename from src/nexus-cli/cmdTemplate/templateList.go
rename to src/cmdTemplate/templateList.go
diff --git a/src/nexus-cli/cmdUser/go.mod b/src/cmdUser/go.mod
similarity index 100%
rename from src/nexus-cli/cmdUser/go.mod
rename to src/cmdUser/go.mod
diff --git a/src/nexus-cli/cmdUser/go.sum b/src/cmdUser/go.sum
similarity index 100%
rename from src/nexus-cli/cmdUser/go.sum
rename to src/cmdUser/go.sum
diff --git a/src/nexus-cli/cmdUser/helper.go b/src/cmdUser/helper.go
similarity index 99%
rename from src/nexus-cli/cmdUser/helper.go
rename to src/cmdUser/helper.go
index 3302f4e..4db03d4 100644
--- a/src/nexus-cli/cmdUser/helper.go
+++ b/src/cmdUser/helper.go
@@ -45,7 +45,6 @@ func printRegexUsageDetails() {
 Any number of regexes can be specified.
 The regex matches the user email, first name and last name and is case-insensitive.
 Regex examples:
-""    -> matches any users
 "."   -> matches any users
 "bla" -> matches any users containing "bla"`
 	u.PrintlnErr(usage)
diff --git a/src/nexus-cli/cmdUser/userAdd.go b/src/cmdUser/userAdd.go
similarity index 100%
rename from src/nexus-cli/cmdUser/userAdd.go
rename to src/cmdUser/userAdd.go
diff --git a/src/nexus-cli/cmdUser/userDel.go b/src/cmdUser/userDel.go
similarity index 100%
rename from src/nexus-cli/cmdUser/userDel.go
rename to src/cmdUser/userDel.go
diff --git a/src/nexus-cli/cmdUser/userList.go b/src/cmdUser/userList.go
similarity index 100%
rename from src/nexus-cli/cmdUser/userList.go
rename to src/cmdUser/userList.go
diff --git a/src/nexus-cli/cmdUser/userSetCaps.go b/src/cmdUser/userSetCaps.go
similarity index 100%
rename from src/nexus-cli/cmdUser/userSetCaps.go
rename to src/cmdUser/userSetCaps.go
diff --git a/src/nexus-cli/cmdUser/userUpdatePwd.go b/src/cmdUser/userUpdatePwd.go
similarity index 100%
rename from src/nexus-cli/cmdUser/userUpdatePwd.go
rename to src/cmdUser/userUpdatePwd.go
diff --git a/src/nexus-cli/cmdUser/userWhoami.go b/src/cmdUser/userWhoami.go
similarity index 100%
rename from src/nexus-cli/cmdUser/userWhoami.go
rename to src/cmdUser/userWhoami.go
diff --git a/src/nexus-cli/cmdVM/go.mod b/src/cmdVM/go.mod
similarity index 100%
rename from src/nexus-cli/cmdVM/go.mod
rename to src/cmdVM/go.mod
diff --git a/src/nexus-cli/cmdVM/go.sum b/src/cmdVM/go.sum
similarity index 100%
rename from src/nexus-cli/cmdVM/go.sum
rename to src/cmdVM/go.sum
diff --git a/src/nexus-cli/cmdVM/helper.go b/src/cmdVM/helper.go
similarity index 98%
rename from src/nexus-cli/cmdVM/helper.go
rename to src/cmdVM/helper.go
index 55d0d4f..d8018c6 100644
--- a/src/nexus-cli/cmdVM/helper.go
+++ b/src/cmdVM/helper.go
@@ -64,7 +64,6 @@ func printRegexUsageDetails() {
 	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
 "."   -> matches any VMs
 "bla" -> matches any VMs containing "bla" in their name`
 	u.PrintlnErr(usage)
@@ -121,7 +120,6 @@ func printFilteredVMs(c cmd.Command, args []string, route string) int {
 // - any regular expression (it applies to the VM's name only)
 // Remark: the matching is case-insensitive
 // Regular expression examples:
-//   ""    -> matches everything
 //   "."   -> matches everything
 //   "bla" -> matches any VM name containing "bla"
 func getFilteredVMs(route string, patterns []string) ([]VM, error) {
diff --git a/src/nexus-cli/cmdVM/vmAttach.go b/src/cmdVM/vmAttach.go
similarity index 100%
rename from src/nexus-cli/cmdVM/vmAttach.go
rename to src/cmdVM/vmAttach.go
diff --git a/src/nexus-cli/cmdVM/vmCreate.go b/src/cmdVM/vmCreate.go
similarity index 100%
rename from src/nexus-cli/cmdVM/vmCreate.go
rename to src/cmdVM/vmCreate.go
diff --git a/src/nexus-cli/cmdVM/vmCred2pdf.go b/src/cmdVM/vmCred2pdf.go
similarity index 100%
rename from src/nexus-cli/cmdVM/vmCred2pdf.go
rename to src/cmdVM/vmCred2pdf.go
diff --git a/src/nexus-cli/cmdVM/vmDel.go b/src/cmdVM/vmDel.go
similarity index 100%
rename from src/nexus-cli/cmdVM/vmDel.go
rename to src/cmdVM/vmDel.go
diff --git a/src/nexus-cli/cmdVM/vmDelAccess.go b/src/cmdVM/vmDelAccess.go
similarity index 99%
rename from src/nexus-cli/cmdVM/vmDelAccess.go
rename to src/cmdVM/vmDelAccess.go
index ab5e89f..ecb44e5 100644
--- a/src/nexus-cli/cmdVM/vmDelAccess.go
+++ b/src/cmdVM/vmDelAccess.go
@@ -34,7 +34,6 @@ func (cmd *DelAccess)PrintUsage() {
 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
 "."   -> matches any VMs
 "bla" -> matches any VMs containing "bla" in their name`
 	u.PrintlnErr(usage)
diff --git a/src/nexus-cli/cmdVM/vmEdit.go b/src/cmdVM/vmEdit.go
similarity index 99%
rename from src/nexus-cli/cmdVM/vmEdit.go
rename to src/cmdVM/vmEdit.go
index c78b299..0cfa98b 100644
--- a/src/nexus-cli/cmdVM/vmEdit.go
+++ b/src/cmdVM/vmEdit.go
@@ -38,7 +38,6 @@ func (cmd *Edit)PrintUsage() {
 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
 "."   -> matches any VMs
 "bla" -> matches any VMs containing "bla" in their name
 VM parameters that can be edited are the following:
diff --git a/src/nexus-cli/cmdVM/vmExportDir.go b/src/cmdVM/vmExportDir.go
similarity index 100%
rename from src/nexus-cli/cmdVM/vmExportDir.go
rename to src/cmdVM/vmExportDir.go
diff --git a/src/nexus-cli/cmdVM/vmList.go b/src/cmdVM/vmList.go
similarity index 100%
rename from src/nexus-cli/cmdVM/vmList.go
rename to src/cmdVM/vmList.go
diff --git a/src/nexus-cli/cmdVM/vmListAttach.go b/src/cmdVM/vmListAttach.go
similarity index 100%
rename from src/nexus-cli/cmdVM/vmListAttach.go
rename to src/cmdVM/vmListAttach.go
diff --git a/src/nexus-cli/cmdVM/vmListDel.go b/src/cmdVM/vmListDel.go
similarity index 100%
rename from src/nexus-cli/cmdVM/vmListDel.go
rename to src/cmdVM/vmListDel.go
diff --git a/src/nexus-cli/cmdVM/vmListEdit.go b/src/cmdVM/vmListEdit.go
similarity index 100%
rename from src/nexus-cli/cmdVM/vmListEdit.go
rename to src/cmdVM/vmListEdit.go
diff --git a/src/nexus-cli/cmdVM/vmListEditAccess.go b/src/cmdVM/vmListEditAccess.go
similarity index 100%
rename from src/nexus-cli/cmdVM/vmListEditAccess.go
rename to src/cmdVM/vmListEditAccess.go
diff --git a/src/nexus-cli/cmdVM/vmListExportDir.go b/src/cmdVM/vmListExportDir.go
similarity index 100%
rename from src/nexus-cli/cmdVM/vmListExportDir.go
rename to src/cmdVM/vmListExportDir.go
diff --git a/src/nexus-cli/cmdVM/vmListStart.go b/src/cmdVM/vmListStart.go
similarity index 100%
rename from src/nexus-cli/cmdVM/vmListStart.go
rename to src/cmdVM/vmListStart.go
diff --git a/src/nexus-cli/cmdVM/vmListStop.go b/src/cmdVM/vmListStop.go
similarity index 100%
rename from src/nexus-cli/cmdVM/vmListStop.go
rename to src/cmdVM/vmListStop.go
diff --git a/src/nexus-cli/cmdVM/vmSetAccess.go b/src/cmdVM/vmSetAccess.go
similarity index 99%
rename from src/nexus-cli/cmdVM/vmSetAccess.go
rename to src/cmdVM/vmSetAccess.go
index d098f93..7596912 100644
--- a/src/nexus-cli/cmdVM/vmSetAccess.go
+++ b/src/cmdVM/vmSetAccess.go
@@ -31,7 +31,6 @@ Only VMs matching the specified IDs or regexes will have their VM access set.
 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
 "."   -> matches any VMs
 "bla" -> matches any VMs containing "bla" in their name`
 	u.PrintlnErr(usage)
diff --git a/src/nexus-cli/cmdVM/vmShutdown.go b/src/cmdVM/vmShutdown.go
similarity index 100%
rename from src/nexus-cli/cmdVM/vmShutdown.go
rename to src/cmdVM/vmShutdown.go
diff --git a/src/nexus-cli/cmdVM/vmStart.go b/src/cmdVM/vmStart.go
similarity index 100%
rename from src/nexus-cli/cmdVM/vmStart.go
rename to src/cmdVM/vmStart.go
diff --git a/src/nexus-cli/cmdVM/vmStop.go b/src/cmdVM/vmStop.go
similarity index 100%
rename from src/nexus-cli/cmdVM/vmStop.go
rename to src/cmdVM/vmStop.go
diff --git a/src/nexus-cli/cmd/Command.go b/src/nexus-cli/cmd/Command.go
deleted file mode 100644
index 261bef7..0000000
--- a/src/nexus-cli/cmd/Command.go
+++ /dev/null
@@ -1,8 +0,0 @@
-package cmd
-
-type Command interface {
-	GetName() string
-	GetDesc() []string
-	PrintUsage()
-	Run(args []string) int   // Returns 0 if the Command was successful.
-}
diff --git a/src/nexus-cli/go.mod b/src/nexus-cli/go.mod
index cb1cc41..54db3c3 100644
--- a/src/nexus-cli/go.mod
+++ b/src/nexus-cli/go.mod
@@ -2,19 +2,19 @@ module nexus-cli
 
 go 1.18
 
-replace nexus-client/cmd => ./cmd
+replace nexus-client/cmd => ../cmd
 
 replace nexus-client/globals => ../globals
 
 replace nexus-client/utils => ../utils
 
-replace nexus-client/cmdLogin => ./cmdLogin
+replace nexus-client/cmdLogin => ../cmdLogin
 
-replace nexus-client/cmdUser => ./cmdUser
+replace nexus-client/cmdUser => ../cmdUser
 
-replace nexus-client/cmdVM => ./cmdVM
+replace nexus-client/cmdVM => ../cmdVM
 
-replace nexus-client/cmdTemplate => ./cmdTemplate
+replace nexus-client/cmdTemplate => ../cmdTemplate
 
 require (
 	github.com/go-resty/resty/v2 v2.7.0
diff --git a/src/nexus-cli/nexus-cli.go b/src/nexus-cli/nexus-cli.go
index 082c04a..e72c2bc 100644
--- a/src/nexus-cli/nexus-cli.go
+++ b/src/nexus-cli/nexus-cli.go
@@ -90,19 +90,7 @@ func main() {
 		u.PrintlnErr("All commands besides login read the access token from the env. variable \"NEXUS_TOKEN\".")
 		u.PrintlnErr("To obtain an access token, use the \"login\" command.")
 		u.PrintlnErr("List of supported Commands:")
-		padding := 20
-		for _, cmd := range cmdList {
-			u.PrintlnErr("")
-			cmdStr := "    "+cmd.GetName()
-			u.PrintErr(cmdStr)
-			pad := strings.Repeat(" ", padding-len(cmd.GetName()))
-			for i, desc := range cmd.GetDesc() {
-				if i > 0 {
-					u.PrintErr(strings.Repeat(" ", len(cmdStr)))
-				}
-				u.PrintlnErr(pad+desc)
-			}
-		}
+		cmd.Help(cmdList, "    ")
 		os.Exit(1)
 	}
 
diff --git a/src/nexush/go.mod b/src/nexush/go.mod
index 772762a..2f094ab 100644
--- a/src/nexush/go.mod
+++ b/src/nexush/go.mod
@@ -6,10 +6,32 @@ replace nexus-client/globals => ../globals
 
 replace nexus-client/utils => ../utils
 
-require github.com/go-resty/resty/v2 v2.7.0
+replace nexus-client/cmd => ../cmd
+
+replace nexus-client/cmdLogin => ../cmdLogin
+
+replace nexus-client/cmdTemplate => ../cmdTemplate
+
+replace nexus-client/cmdUser => ../cmdUser
+
+replace nexus-client/cmdVM => ../cmdVM
+
+require (
+	github.com/go-resty/resty/v2 v2.7.0
+	golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1
+	nexus-client/cmdLogin v0.0.0-00010101000000-000000000000
+	nexus-client/globals v0.0.0-00010101000000-000000000000
+	nexus-client/utils v0.0.0-00010101000000-000000000000
+)
 
 require (
-	golang.org/x/net v0.0.0-20211029224645-99673261e6eb // indirect
-	nexus-client/globals v0.0.0-00010101000000-000000000000 // indirect
-	nexus-client/utils v0.0.0-00010101000000-000000000000 // indirect
+	github.com/go-pdf/fpdf v0.6.0 // indirect
+	github.com/google/uuid v1.3.0 // indirect
+	golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect
+	golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect
+	golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 // indirect
+	nexus-client/cmd v0.0.0-00010101000000-000000000000 // indirect
+	nexus-client/cmdTemplate v0.0.0-00010101000000-000000000000 // indirect
+	nexus-client/cmdUser v0.0.0-00010101000000-000000000000 // indirect
+	nexus-client/cmdVM v0.0.0-00010101000000-000000000000 // indirect
 )
diff --git a/src/nexush/go.sum b/src/nexush/go.sum
index a5c1a24..10b3946 100644
--- a/src/nexush/go.sum
+++ b/src/nexush/go.sum
@@ -1,9 +1,37 @@
+github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
+github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/go-pdf/fpdf v0.6.0 h1:MlgtGIfsdMEEQJr2le6b/HNr1ZlQwxyWr77r2aj2U/8=
+github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M=
 github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
 github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
+github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
+github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
+github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY=
+github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=
+github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w=
+github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY=
+golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
+golang.org/x/image v0.0.0-20210607152325-775e3b0c77b9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
 golang.org/x/net v0.0.0-20211029224645-99673261e6eb h1:pirldcYWx7rx7kE5r+9WsOXPXK0+WH5+uZ7uPmJ44uM=
 golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c=
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
diff --git a/src/nexush/nexush.go b/src/nexush/nexush.go
index 6e6f02e..5753ef7 100644
--- a/src/nexush/nexush.go
+++ b/src/nexush/nexush.go
@@ -2,15 +2,57 @@ package main
 
 import (
 	"os"
+	"fmt"
+	"bufio"
 	"path"
 	"strings"
+	"syscall"
+	"golang.org/x/term"
 	u "nexus-client/utils"
 	g "nexus-client/globals"
-	// "nexus-client/cmd"
-	// "nexus-client/cmdLogin"
+	"nexus-client/cmd"	
+	"nexus-client/cmdLogin"
+	"nexus-client/cmdUser"
+	"nexus-client/cmdVM"
+	"nexus-client/cmdTemplate"
 	"github.com/go-resty/resty/v2"
 )
 
+var cmdList = []cmd.Command {
+	&cmdUser.Whoami{"whoami"},
+	&cmdUser.UpdatePwd{"passwd"},
+	&cmdUser.List{"userlist"},
+	&cmdUser.Add{"useradd"},
+	&cmdUser.Del{"userdel"},
+	&cmdUser.SetCaps{"usersetcaps"},
+
+	&cmdVM.List{"vmlist"},
+	&cmdVM.ListStart{"vmliststart"},
+	&cmdVM.ListAttach{"vmlistattach"},
+	&cmdVM.ListStop{"vmliststop"},
+	&cmdVM.ListEdit{"vmlistedit"},
+	&cmdVM.ListEditAccess{"vmlisteditaccess"},
+	&cmdVM.ListDel{"vmlistdel"},
+	&cmdVM.ListExportDir{"vmlistexportdir"},
+
+	&cmdVM.Cred2pdf{"vmcred2pdf"},
+
+	&cmdVM.Start{"vmstart"},
+	&cmdVM.Stop{"vmstop"},
+	&cmdVM.Shutdown{"vmshutdown"},
+	&cmdVM.Attach{"vmattach"},
+	&cmdVM.Create{"vmcreate"},
+	&cmdVM.Edit{"vmedit"},
+	&cmdVM.Del{"vmdel"},
+	&cmdVM.SetAccess{"vmsetaccess"},
+	&cmdVM.DelAccess{"vmdelaccess"},
+	&cmdVM.ExportDir{"vmexportdir"},
+
+	&cmdTemplate.List{"tpllist"},
+	&cmdTemplate.Create{"tplcreate"},
+	&cmdTemplate.Del{"tpldel"},
+}
+
 func main() {
 	server, found := os.LookupEnv(g.ENV_NEXUS_SERVER)
 	if !found {
@@ -50,5 +92,66 @@ func main() {
 		os.Exit(1)
 	}
 
-	os.Exit(1)
-}
\ No newline at end of file
+	email := os.Args[1]
+	fmt.Printf(email+"'s password: ")
+	bytePwd, err := term.ReadPassword(int(syscall.Stdin))
+    if err != nil {
+		u.PrintlnErr(err.Error())
+        os.Exit(1)
+    }
+	pwd := string(bytePwd)
+
+	token, err := cmdLogin.GetToken(email, pwd)
+	u.Println("")
+	if err != nil {
+		u.PrintlnErr("Error: "+err.Error())
+		os.Exit(1)
+	}
+
+	shell(token)
+
+	os.Exit(0)
+}
+
+func shell(token string) {
+	u.Println(`Welcome to nexush, the nexus shell.
+Type: "help" for help on commands
+      "quit" to quit the shell`)
+
+	client := g.GetInstance().Client
+
+	quit := false
+	for !quit {
+		fmt.Printf("nexush> ")
+		var reader = bufio.NewReader(os.Stdin)
+		line, _ := reader.ReadString('\n')
+		line = strings.TrimSpace(line)
+		args := strings.Split(line, " ")
+	
+		valid := false
+		switch {
+		case line == "quit":
+			quit = true
+		case line == "help":
+			cmd.Help(cmdList, "")
+		case line == "":
+			
+		default:
+			c := args[0]
+			for _, cmd := range cmdList {
+				if c == cmd.GetName() {
+					valid = true
+					client.SetHeader("Content-Type", "application/json")
+					client.SetHeader("Authorization", "Bearer "+token)
+					cmd.Run(args[1:])
+					break
+				}
+			}
+			if !valid {
+				u.Println(c+": unknown command")
+			}	
+		}
+	}
+
+	os.Exit(0)
+}
-- 
GitLab