VOL-1552 - inital stub
remove extra file
Change-Id: I9f5c93eefbde51c64a7c1b13244eca3a16de8a41
diff --git a/Gopkg.lock b/Gopkg.lock
index 42709c8..ddf7aad 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -27,6 +27,14 @@
[[projects]]
branch = "master"
+ digest = "1:c16f511247fb7dd5b3e8428bed24b9f74473f343b3fb7c14763b47f567feb8a5"
+ name = "github.com/bclicn/color"
+ packages = ["."]
+ pruneopts = "UT"
+ revision = "108f2023dc84f1f9e64f246fa3997993971b2706"
+
+[[projects]]
+ branch = "master"
digest = "1:0b0303f763128c8e8092843b9d85fdf03bb5bfa4145f1ebe77c12e835a871dc2"
name = "github.com/boljen/go-bitmap"
packages = ["."]
@@ -745,6 +753,7 @@
analyzer-name = "dep"
analyzer-version = 1
input-imports = [
+ "github.com/bclicn/color",
"github.com/boljen/go-bitmap",
"github.com/bsm/sarama-cluster",
"github.com/cevaris/ordered_map",
diff --git a/cli/main.go b/cli/main.go
new file mode 100644
index 0000000..a20fbf4
--- /dev/null
+++ b/cli/main.go
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package main
+
+import (
+ "flag"
+ "fmt"
+ "log"
+ "os/exec"
+
+ "github.com/opencord/voltha-go/cli/menu/mainmenu"
+ "google.golang.org/grpc"
+)
+
+func main() {
+
+ // disable input buffering
+ exec.Command("stty", "-F", "/dev/tty", "cbreak", "min", "1").Run()
+ // do not display entered characters on the screen
+ exec.Command("stty", "-F", "/dev/tty", "-echo").Run()
+ printHeader()
+
+ volthaAddress := flag.String("voltha_address", "localhost:6161", "IP/Hostname:Port for Voltha Core")
+ h := flag.Bool("h", false, "Print help")
+ help := flag.Bool("help", false, "Print help")
+ flag.Parse()
+ if *h || *help {
+ fmt.Println("cli -h(elp) print this message")
+ fmt.Println("cli -voltha_address=$VOLTHA_ADDRESS:PORT default localhost:6161")
+ return
+ }
+ conn, err := grpc.Dial(*volthaAddress, grpc.WithInsecure())
+ if err != nil {
+ log.Fatalf("did not connect: %s", err)
+ }
+ defer conn.Close()
+ fmt.Println("Connecting to " + *volthaAddress)
+
+ mainmenu.MainLoop(conn)
+}
+func printHeader() {
+ header :=
+ ` _ _ _ ___ _ ___
+__ _____| | |_| |_ __ _ / __| | |_ _|
+\ V / _ \ | _| ' \/ _' | | (__| |__ | |
+ \_/\___/_|\__|_||_\__,_| \___|____|___|
+`
+ fmt.Println(header)
+}
diff --git a/cli/menu/devicemenu/deviceMenu.go b/cli/menu/devicemenu/deviceMenu.go
new file mode 100644
index 0000000..a435f16
--- /dev/null
+++ b/cli/menu/devicemenu/deviceMenu.go
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package devicemenu
+
+import (
+ "fmt"
+
+ "github.com/bclicn/color"
+ "github.com/opencord/voltha-go/cli/util"
+ "google.golang.org/grpc"
+)
+
+/*
+Conn - the grpc connection to use for making calls to voltha core
+*/
+var (
+ Conn *grpc.ClientConn
+ DeviceId *string
+ InputPrompt *string
+ Commands *[]string
+)
+
+/*
+MainLoop - the loop which processes commands at the main level
+*/
+func MainLoop(conn *grpc.ClientConn, deviceId string) {
+
+ DeviceId = &deviceId
+ inputPrompt := fmt.Sprint("(" + color.LightRed("device "+deviceId) + ") ")
+ InputPrompt = &inputPrompt
+ funcTable := make(map[string]func(bool))
+ // inputPromptSize := len(inputPrompt)
+ Conn = conn
+ funcTable["quit"] = util.Exit
+ funcTable["exit"] = nil
+ funcTable["edit"] = doEdit
+ funcTable["history"] = doHistory
+ funcTable["img_dnld_request"] = doImgDnldRequest
+ funcTable["perf_config"] = doPerfConfig
+ funcTable["save"] = doSave
+ funcTable["eof"] = doEof
+ funcTable["images"] = doImages
+ funcTable["img_dnld_status"] = doImgDnldStatus
+ funcTable["ports"] = doPorts
+ funcTable["set"] = doSet
+ funcTable["img_activate"] = doImgActivate
+ funcTable["img_revert"] = doImgRevert
+ funcTable["py"] = doPy
+ funcTable["shell"] = doShell
+ funcTable["flows"] = doFlows
+ funcTable["img_dnld_canel"] = doImgDnldCancel
+ funcTable["list"] = doList
+ funcTable["shortcuts"] = doShortCuts
+ funcTable["help"] = doHelp
+ funcTable["img_dnld_list"] = doImgDnldList
+ funcTable["pause"] = doPause
+ funcTable["run"] = doRun
+ funcTable["show"] = doShow
+
+ commands := make([]string, len(funcTable))
+ i := 0
+ for key, _ := range funcTable {
+ commands[i] = key
+ i++
+ }
+ Commands = &commands
+
+ util.ProcessTable(funcTable, inputPrompt)
+
+}
diff --git a/cli/menu/devicemenu/edit.go b/cli/menu/devicemenu/edit.go
new file mode 100644
index 0000000..c5c1e8e
--- /dev/null
+++ b/cli/menu/devicemenu/edit.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package devicemenu
+
+import "fmt"
+
+func doEdit(enterPressed bool) {
+ fmt.Println("doEdit")
+}
diff --git a/cli/menu/devicemenu/eof.go b/cli/menu/devicemenu/eof.go
new file mode 100644
index 0000000..4d752fb
--- /dev/null
+++ b/cli/menu/devicemenu/eof.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package devicemenu
+
+import "fmt"
+
+func doEof(enterPressed bool) {
+ fmt.Println("doEof")
+}
diff --git a/cli/menu/devicemenu/flows.go b/cli/menu/devicemenu/flows.go
new file mode 100644
index 0000000..9a648b2
--- /dev/null
+++ b/cli/menu/devicemenu/flows.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package devicemenu
+
+import "fmt"
+
+func doFlows(enterPressed bool) {
+ fmt.Println("doFlows")
+}
diff --git a/cli/menu/devicemenu/help.go b/cli/menu/devicemenu/help.go
new file mode 100644
index 0000000..340817d
--- /dev/null
+++ b/cli/menu/devicemenu/help.go
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package devicemenu
+
+import (
+ "fmt"
+ "os"
+ "strings"
+
+ "github.com/opencord/voltha-go/cli/util"
+)
+
+func doHelp(enterPressed bool) {
+ input := ""
+ var b = make([]byte, 1)
+ inputPrompt := *InputPrompt + "help "
+ for {
+ os.Stdin.Read(b)
+ char := string(b)
+ if char == "\t" || char == "\n" || char == "?" {
+ if enterPressed {
+ baseHelp()
+ return
+ }
+
+ fmt.Println("")
+ ret, prompt := util.Test(input, *Commands)
+ if len(ret) == 1 {
+ input = ret[0]
+ if input == "quit" {
+ util.Exit(true)
+ } else if input == "exit" {
+ return
+ }
+
+ MainLoop(Conn, input)
+ return
+ } else if len(ret) == 0 {
+ input = ""
+ fmt.Print("Invalid Input \n" + inputPrompt)
+ } else {
+
+ fmt.Println(ret)
+ input = prompt
+ fmt.Print(prompt + inputPrompt)
+ }
+ } else if b[0] == 127 || char == "\b" {
+
+ sz := len(input)
+ if sz > 0 {
+ fmt.Print("\b \b")
+ input = input[:sz-1]
+ }
+ if !(strings.HasPrefix(input, "device")) {
+ return
+ }
+ } else {
+ fmt.Print(char)
+ input += char
+ }
+ }
+}
+func baseHelp() {
+ message := `
+Documented commands (type help <topic>):
+========================================
+edit help img_dnld_cancel img_revert ports set
+eof history img_dnld_list list py shell
+exit images img_dnld_request pause run shortcuts
+flows img_activate img_dnld_status perf_config save show
+
+Miscellaneous help topics:
+==========================
+load
+
+Undocumented commands:
+======================
+quit
+
+`
+ fmt.Println(message)
+}
diff --git a/cli/menu/devicemenu/history.go b/cli/menu/devicemenu/history.go
new file mode 100644
index 0000000..b4d2423
--- /dev/null
+++ b/cli/menu/devicemenu/history.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package devicemenu
+
+import "fmt"
+
+func doHistory(enterPressed bool) {
+ fmt.Println("doHistory")
+}
diff --git a/cli/menu/devicemenu/images.go b/cli/menu/devicemenu/images.go
new file mode 100644
index 0000000..dc2105e
--- /dev/null
+++ b/cli/menu/devicemenu/images.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package devicemenu
+
+import "fmt"
+
+func doImages(enterPressed bool) {
+ fmt.Println("doImages")
+}
diff --git a/cli/menu/devicemenu/img_activate.go b/cli/menu/devicemenu/img_activate.go
new file mode 100644
index 0000000..b615c1b
--- /dev/null
+++ b/cli/menu/devicemenu/img_activate.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package devicemenu
+
+import "fmt"
+
+func doImgActivate(enterPressed bool) {
+ fmt.Println("doImgActivate")
+}
diff --git a/cli/menu/devicemenu/img_dnld_cancel.go b/cli/menu/devicemenu/img_dnld_cancel.go
new file mode 100644
index 0000000..cc9881d
--- /dev/null
+++ b/cli/menu/devicemenu/img_dnld_cancel.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package devicemenu
+
+import "fmt"
+
+func doImgDnldCancel(enterPressed bool) {
+ fmt.Println("doImgDnldCancel")
+}
diff --git a/cli/menu/devicemenu/img_dnld_list.go b/cli/menu/devicemenu/img_dnld_list.go
new file mode 100644
index 0000000..ea6d31f
--- /dev/null
+++ b/cli/menu/devicemenu/img_dnld_list.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package devicemenu
+
+import "fmt"
+
+func doImgDnldList(enterPressed bool) {
+ fmt.Println("doImgDnldList")
+}
diff --git a/cli/menu/devicemenu/img_dnld_request.go b/cli/menu/devicemenu/img_dnld_request.go
new file mode 100644
index 0000000..1a0ee98
--- /dev/null
+++ b/cli/menu/devicemenu/img_dnld_request.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package devicemenu
+
+import "fmt"
+
+func doImgDnldRequest(enterPressed bool) {
+ fmt.Println("doImgDnldRequest")
+}
diff --git a/cli/menu/devicemenu/img_dnld_status.go b/cli/menu/devicemenu/img_dnld_status.go
new file mode 100644
index 0000000..2177996
--- /dev/null
+++ b/cli/menu/devicemenu/img_dnld_status.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package devicemenu
+
+import "fmt"
+
+func doImgDnldStatus(enterPressed bool) {
+ fmt.Println("doImgDnldStatus")
+}
diff --git a/cli/menu/devicemenu/img_revert.go b/cli/menu/devicemenu/img_revert.go
new file mode 100644
index 0000000..bac7b37
--- /dev/null
+++ b/cli/menu/devicemenu/img_revert.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package devicemenu
+
+import "fmt"
+
+func doImgRevert(enterPressed bool) {
+ fmt.Println("doImgRevert")
+}
diff --git a/cli/menu/devicemenu/list.go b/cli/menu/devicemenu/list.go
new file mode 100644
index 0000000..053fec9
--- /dev/null
+++ b/cli/menu/devicemenu/list.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package devicemenu
+
+import "fmt"
+
+func doList(enterPressed bool) {
+ fmt.Println("doList")
+}
diff --git a/cli/menu/devicemenu/pause.go b/cli/menu/devicemenu/pause.go
new file mode 100644
index 0000000..6fec137
--- /dev/null
+++ b/cli/menu/devicemenu/pause.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package devicemenu
+
+import "fmt"
+
+func doPause(enterPressed bool) {
+ fmt.Println("doPause")
+}
diff --git a/cli/menu/devicemenu/perf_config.go b/cli/menu/devicemenu/perf_config.go
new file mode 100644
index 0000000..bdc9ab4
--- /dev/null
+++ b/cli/menu/devicemenu/perf_config.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package devicemenu
+
+import "fmt"
+
+func doPerfConfig(enterPressed bool) {
+ fmt.Println("doPrefConfig")
+}
diff --git a/cli/menu/devicemenu/ports.go b/cli/menu/devicemenu/ports.go
new file mode 100644
index 0000000..4b1aefb
--- /dev/null
+++ b/cli/menu/devicemenu/ports.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package devicemenu
+
+import "fmt"
+
+func doPorts(enterPressed bool) {
+ fmt.Println("doPorts")
+}
diff --git a/cli/menu/devicemenu/py.go b/cli/menu/devicemenu/py.go
new file mode 100644
index 0000000..8a489fd
--- /dev/null
+++ b/cli/menu/devicemenu/py.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package devicemenu
+
+import "fmt"
+
+func doPy(enterPressed bool) {
+ fmt.Println("doPy")
+}
diff --git a/cli/menu/devicemenu/run.go b/cli/menu/devicemenu/run.go
new file mode 100644
index 0000000..081fddb
--- /dev/null
+++ b/cli/menu/devicemenu/run.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package devicemenu
+
+import "fmt"
+
+func doRun(enterPressed bool) {
+ fmt.Println("doRun")
+}
diff --git a/cli/menu/devicemenu/save.go b/cli/menu/devicemenu/save.go
new file mode 100644
index 0000000..ba4ef89
--- /dev/null
+++ b/cli/menu/devicemenu/save.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package devicemenu
+
+import "fmt"
+
+func doSave(enterPressed bool) {
+ fmt.Println("doSave")
+}
diff --git a/cli/menu/devicemenu/set.go b/cli/menu/devicemenu/set.go
new file mode 100644
index 0000000..c8d8a15
--- /dev/null
+++ b/cli/menu/devicemenu/set.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package devicemenu
+
+import "fmt"
+
+func doSet(enterPressed bool) {
+ fmt.Println("doSet")
+}
diff --git a/cli/menu/devicemenu/shell.go b/cli/menu/devicemenu/shell.go
new file mode 100644
index 0000000..cffbcbd
--- /dev/null
+++ b/cli/menu/devicemenu/shell.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package devicemenu
+
+import "fmt"
+
+func doShell(enterPressed bool) {
+ fmt.Println("doShell")
+}
diff --git a/cli/menu/devicemenu/shortcuts.go b/cli/menu/devicemenu/shortcuts.go
new file mode 100644
index 0000000..14596d0
--- /dev/null
+++ b/cli/menu/devicemenu/shortcuts.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package devicemenu
+
+import "fmt"
+
+func doShortCuts(enterPressed bool) {
+ fmt.Println("doShortCuts")
+}
diff --git a/cli/menu/devicemenu/show.go b/cli/menu/devicemenu/show.go
new file mode 100644
index 0000000..b9e22bd
--- /dev/null
+++ b/cli/menu/devicemenu/show.go
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package devicemenu
+
+import (
+ "context"
+ "fmt"
+ "strconv"
+
+ "github.com/opencord/voltha-go/cli/util"
+ "github.com/opencord/voltha-protos/go/common"
+ "github.com/opencord/voltha-protos/go/voltha"
+)
+
+func doShow(enterPressed bool) {
+ client := voltha.NewVolthaServiceClient(Conn)
+ fmt.Println(*DeviceId)
+ device, err := client.GetDevice(context.Background(), &common.ID{Id: *DeviceId})
+ if err != nil {
+ fmt.Println(err)
+ }
+ fields := []string{"field", "value"}
+ var rows []map[string]string
+
+ id := make(map[string]string)
+ id["field"] = "id"
+ id["value"] = device.Id
+ rows = append(rows, id)
+
+ Type := make(map[string]string)
+ Type["field"] = "type"
+ Type["value"] = device.Type
+ rows = append(rows, Type)
+
+ parentId := make(map[string]string)
+ parentId["field"] = "parent_id"
+ parentId["value"] = device.ParentId
+ rows = append(rows, parentId)
+
+ vlan := make(map[string]string)
+ vlan["field"] = "vlan"
+ vlan["value"] = strconv.FormatUint(uint64(device.Vlan), 10)
+ rows = append(rows, vlan)
+
+ adminState := make(map[string]string)
+ adminState["field"] = "admin_state"
+ adminState["value"] = strconv.FormatUint(uint64(device.AdminState), 10)
+ rows = append(rows, adminState)
+
+ proxyAddress := device.GetProxyAddress()
+ proxyDeviceId := make(map[string]string)
+ proxyDeviceId["field"] = "proxy_address.device_id"
+ proxyDeviceId["value"] = proxyAddress.DeviceId
+ rows = append(rows, proxyDeviceId)
+
+ proxyDeviceType := make(map[string]string)
+ proxyDeviceType["field"] = "proxy_address.device_type"
+ proxyDeviceType["value"] = proxyAddress.DeviceType
+ rows = append(rows, proxyDeviceType)
+
+ proxyChannelId := make(map[string]string)
+ proxyChannelId["field"] = "proxy_address.channel_id"
+ proxyChannelId["value"] = strconv.FormatUint(uint64(proxyAddress.ChannelId), 10)
+ rows = append(rows, proxyChannelId)
+
+ parentPortNumber := make(map[string]string)
+ parentPortNumber["field"] = "parent_port_no"
+ parentPortNumber["value"] = strconv.FormatUint(uint64(device.GetParentPortNo()), 10)
+ rows = append(rows, parentPortNumber)
+
+ output, _ := util.BuildTable(fields, rows)
+
+ fmt.Println(output)
+}
diff --git a/cli/menu/mainmenu/Makefile b/cli/menu/mainmenu/Makefile
new file mode 100644
index 0000000..fd522a5
--- /dev/null
+++ b/cli/menu/mainmenu/Makefile
@@ -0,0 +1,13 @@
+VOLTHA_PROTO_PATH := protos/voltha_protos
+VOLTHA_PROTO_FILES := $(wildcard protos/voltha_protos/*.proto)
+VOLTHA_PROTO_GO_FILES := $(foreach f,$(VOLTHA_PROTO_FILES),$(subst .proto,.pb.go,$(f)))
+VOLTHA_PROTO_DESC_FILES := $(foreach f,$(VOLTHA_PROTO_FILES),$(subst .proto,.desc,$(f)))
+
+voltha-api: $(VOLTHA_PROTO_GO_FILES)
+
+%.pb.go: %.proto
+ @protoc -I ${VOLTHA_PROTO_PATH} \
+ --go_out=plugins=grpc:${VOLTHA_PROTO_PATH} \
+ -I${GOPATH}/src \
+ -I${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
+ $<
diff --git a/cli/menu/mainmenu/alarmFilters.go b/cli/menu/mainmenu/alarmFilters.go
new file mode 100644
index 0000000..4a1b274
--- /dev/null
+++ b/cli/menu/mainmenu/alarmFilters.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doAlarmFilters(enterPressed bool) {
+ fmt.Print("input: alarm_filters>")
+}
diff --git a/cli/menu/mainmenu/arriveOnus.go b/cli/menu/mainmenu/arriveOnus.go
new file mode 100644
index 0000000..75e6263
--- /dev/null
+++ b/cli/menu/mainmenu/arriveOnus.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doArriveOnus(enterPressed bool) {
+ fmt.Print("input: arrive_onus>")
+}
diff --git a/cli/menu/mainmenu/cmdEnvironment.go b/cli/menu/mainmenu/cmdEnvironment.go
new file mode 100644
index 0000000..0342e87
--- /dev/null
+++ b/cli/menu/mainmenu/cmdEnvironment.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doCmdEnvironment(enterPressed bool) {
+ fmt.Println("input: doCmdEnvironment> ")
+}
diff --git a/cli/menu/mainmenu/delete.go b/cli/menu/mainmenu/delete.go
new file mode 100644
index 0000000..9b9f49b
--- /dev/null
+++ b/cli/menu/mainmenu/delete.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doDelete(enterPressed bool) {
+ fmt.Println("input: delete > ")
+}
diff --git a/cli/menu/mainmenu/deleteAllFlows.go b/cli/menu/mainmenu/deleteAllFlows.go
new file mode 100644
index 0000000..9888fa9
--- /dev/null
+++ b/cli/menu/mainmenu/deleteAllFlows.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doDeleteAllFlows(enterPressed bool) {
+ fmt.Print("input: delete_all_flows>")
+}
diff --git a/cli/menu/mainmenu/device.go b/cli/menu/mainmenu/device.go
new file mode 100644
index 0000000..45b35a9
--- /dev/null
+++ b/cli/menu/mainmenu/device.go
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import (
+ "context"
+ "fmt"
+ "os"
+ "strings"
+
+ "github.com/golang/protobuf/ptypes/empty"
+ "github.com/opencord/voltha-go/cli/menu/devicemenu"
+ "github.com/opencord/voltha-go/cli/util"
+ "github.com/opencord/voltha-protos/go/voltha"
+)
+
+func doDevice(enterPressed bool) {
+ fmt.Print(" ")
+ client := voltha.NewVolthaServiceClient(Conn)
+ devices, err := client.ListDevices(context.Background(), &empty.Empty{})
+ items := devices.GetItems()
+ if err != nil {
+ fmt.Println(err)
+ }
+ deviceIds := []string{"exit", "quit"}
+ for i := 0; i < len(items); i++ {
+ deviceIds = append(deviceIds, items[i].Id)
+ }
+ var b = make([]byte, 1)
+ input := ""
+
+ for {
+ os.Stdin.Read(b)
+ char := string(b)
+ if char == "\t" || char == "\n" || char == "?" {
+ fmt.Println("")
+ ret, prompt := util.Test(input, deviceIds)
+ if len(ret) == 1 {
+ input = ret[0]
+ if input == "quit" {
+ util.Exit(true)
+ } else if input == "exit" {
+ return
+ }
+
+ devicemenu.MainLoop(Conn, input)
+ return
+ } else if len(ret) == 0 {
+ input = ""
+ fmt.Print("Invalid Input \ninput:")
+ } else {
+
+ fmt.Println(ret)
+ input = prompt
+ fmt.Print("input: " + prompt)
+ }
+ } else if b[0] == 127 || char == "\b" {
+
+ sz := len(input)
+ if sz > 0 {
+ fmt.Print("\b \b")
+ input = input[:sz-1]
+ }
+ if !(strings.HasPrefix(input, "device")) {
+ return
+ }
+ } else {
+ fmt.Print(char)
+ input += char
+ }
+ }
+
+}
diff --git a/cli/menu/mainmenu/devices.go b/cli/menu/mainmenu/devices.go
new file mode 100644
index 0000000..f5ef716
--- /dev/null
+++ b/cli/menu/mainmenu/devices.go
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import (
+ "context"
+ "fmt"
+ "strconv"
+
+ "github.com/golang/protobuf/ptypes/empty"
+ "github.com/opencord/voltha-go/cli/util"
+ "github.com/opencord/voltha-protos/go/voltha"
+)
+
+/*
+ reason | proxy_address.device_id | proxy_address.onu_id | proxy_address.onu_session_id |
+*/
+func doDevices(enterPressed bool) {
+
+ client := voltha.NewVolthaServiceClient(Conn)
+ devices, err := client.ListDevices(context.Background(), &empty.Empty{})
+ if err != nil {
+ fmt.Println(err)
+ }
+ var rows []map[string]string
+ items := devices.GetItems()
+ var fields = []string{"id", "type", "root", "parent_id", "serial_number", "admin_state", "oper_status", "connect_status", "parent_port_no", "host_and_port", "reason",
+ "proxy_address.device_id", "proxy_address.onu_id", "proxy_address.onu_session_id"}
+
+ for i := 0; i < len(items); i++ {
+ //fmt.Println(items[i])
+ device := items[i]
+ row := make(map[string]string)
+ row["id"] = device.Id
+ row["type"] = device.Type
+ row["root"] = strconv.FormatBool(device.Root)
+ row["parent_id"] = device.ParentId
+ row["serial_number"] = device.SerialNumber
+ row["admin_state"] = device.AdminState.String()
+ row["oper_status"] = device.OperStatus.String()
+ row["connect_status"] = device.ConnectStatus.String()
+ row["parent_port_no"] = strconv.FormatUint(uint64(device.GetParentPortNo()), 10)
+ row["host_and_port"] = device.GetHostAndPort()
+ row["reason"] = device.Reason
+ proxyAddress := device.GetProxyAddress()
+ if proxyAddress != nil {
+ row["proxy_address.device_id"] = proxyAddress.DeviceId
+ row["proxy_address.onu_id"] = strconv.FormatUint(uint64(proxyAddress.OnuId), 10)
+ row["proxy_address.onu_session_id"] = strconv.FormatUint(uint64(proxyAddress.OnuSessionId), 10)
+ } else {
+ row["proxy_address.device_id"] = ""
+ row["proxy_address.onu_id"] = ""
+ row["proxy_address.onu_session_id"] = ""
+ }
+
+ rows = append(rows, row)
+ }
+ output, err := util.BuildTable(fields, rows)
+ if err != nil {
+ fmt.Println(err)
+ }
+ fmt.Print(output)
+
+}
diff --git a/cli/menu/mainmenu/disable.go b/cli/menu/mainmenu/disable.go
new file mode 100644
index 0000000..45d86af
--- /dev/null
+++ b/cli/menu/mainmenu/disable.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doDisable(enterPressed bool) {
+ fmt.Print("input: disable>")
+}
diff --git a/cli/menu/mainmenu/enable.go b/cli/menu/mainmenu/enable.go
new file mode 100644
index 0000000..3068c72
--- /dev/null
+++ b/cli/menu/mainmenu/enable.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doEnable(enterPressed bool) {
+ fmt.Print("input: enable>")
+}
diff --git a/cli/menu/mainmenu/health.go b/cli/menu/mainmenu/health.go
new file mode 100644
index 0000000..562ff9b
--- /dev/null
+++ b/cli/menu/mainmenu/health.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doHealth(enterPressed bool) {
+ fmt.Print("input: health>")
+}
diff --git a/cli/menu/mainmenu/injectEapolStart.go b/cli/menu/mainmenu/injectEapolStart.go
new file mode 100644
index 0000000..8015013
--- /dev/null
+++ b/cli/menu/mainmenu/injectEapolStart.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doInjectEapolStart(enterPressed bool) {
+ fmt.Print("input: inject_eapol_start>")
+}
diff --git a/cli/menu/mainmenu/installAllControllerBoundFlows.go b/cli/menu/mainmenu/installAllControllerBoundFlows.go
new file mode 100644
index 0000000..c994831
--- /dev/null
+++ b/cli/menu/mainmenu/installAllControllerBoundFlows.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doInstallAllControllerBoundFlows(enterPressed bool) {
+ fmt.Print("input: install_all_controller_bound_flows>")
+}
diff --git a/cli/menu/mainmenu/installAllSampleFlows.go b/cli/menu/mainmenu/installAllSampleFlows.go
new file mode 100644
index 0000000..a9d08e4
--- /dev/null
+++ b/cli/menu/mainmenu/installAllSampleFlows.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doInstallAllSampleFlows(enterPressed bool) {
+ fmt.Print("input: install_all_sample_flows>")
+}
diff --git a/cli/menu/mainmenu/installDhcpFlows.go b/cli/menu/mainmenu/installDhcpFlows.go
new file mode 100644
index 0000000..799867d
--- /dev/null
+++ b/cli/menu/mainmenu/installDhcpFlows.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doInstallDhcpFlows(enterPressed bool) {
+ fmt.Print("input: install_dhcp_flows>")
+}
diff --git a/cli/menu/mainmenu/installEapolFlow.go b/cli/menu/mainmenu/installEapolFlow.go
new file mode 100644
index 0000000..2a76bae
--- /dev/null
+++ b/cli/menu/mainmenu/installEapolFlow.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doInstallEapolFlow(enterPressed bool) {
+ fmt.Print("input: install_eapol_flow>")
+}
diff --git a/cli/menu/mainmenu/launch.go b/cli/menu/mainmenu/launch.go
new file mode 100644
index 0000000..818e5a4
--- /dev/null
+++ b/cli/menu/mainmenu/launch.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doLaunch(enterPressed bool) {
+ fmt.Print("input: launch")
+}
diff --git a/cli/menu/mainmenu/load.go b/cli/menu/mainmenu/load.go
new file mode 100644
index 0000000..20fd7c7
--- /dev/null
+++ b/cli/menu/mainmenu/load.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doLoad(enterPressed bool) {
+ fmt.Println("input: load>")
+}
diff --git a/cli/menu/mainmenu/log.go b/cli/menu/mainmenu/log.go
new file mode 100644
index 0000000..d94c4cf
--- /dev/null
+++ b/cli/menu/mainmenu/log.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doLog(enterPressed bool) {
+ fmt.Print("input: log>")
+}
diff --git a/cli/menu/mainmenu/logicalDevice.go b/cli/menu/mainmenu/logicalDevice.go
new file mode 100644
index 0000000..9e306ec
--- /dev/null
+++ b/cli/menu/mainmenu/logicalDevice.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doLogicalDevice(enterPressed bool) {
+ fmt.Print("input: logical_device>")
+}
diff --git a/cli/menu/mainmenu/logicalDevices.go b/cli/menu/mainmenu/logicalDevices.go
new file mode 100644
index 0000000..5d6f2fc
--- /dev/null
+++ b/cli/menu/mainmenu/logicalDevices.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doLogicalDevices(enterPressed bool) {
+ fmt.Print("input: logical_devices>")
+}
diff --git a/cli/menu/mainmenu/mainMenu.go b/cli/menu/mainmenu/mainMenu.go
new file mode 100644
index 0000000..3d57892
--- /dev/null
+++ b/cli/menu/mainmenu/mainMenu.go
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import (
+ "fmt"
+
+ "github.com/bclicn/color"
+ "github.com/opencord/voltha-go/cli/util"
+ "google.golang.org/grpc"
+)
+
+/*
+Conn - the grpc connection to use for making calls to voltha core
+*/
+var Conn *grpc.ClientConn
+
+/*
+MainLoop - the loop which processes commands at the main level
+*/
+func MainLoop(conn *grpc.ClientConn) {
+
+ inputPrompt := fmt.Sprint("(" + color.LightBlue("voltha") + ") ")
+ // inputPromptSize := len(inputPrompt)
+ Conn = conn
+ mainFuncTable := make(map[string]func(bool))
+ mainFuncTable["quit"] = util.Exit
+ mainFuncTable["exit"] = nil
+ mainFuncTable["cmdenvironment"] = doCmdEnvironment
+ mainFuncTable["load"] = doLoad
+ mainFuncTable["relative_load"] = doRelativeLoad
+ mainFuncTable["reset_history"] = doResetHistory
+ mainFuncTable["log"] = doLog
+ mainFuncTable["launch"] = doLaunch
+ mainFuncTable["restart"] = doRestart
+ mainFuncTable["devices"] = doDevices
+ mainFuncTable["device"] = doDevice
+ mainFuncTable["logical_devices"] = doLogicalDevices
+ mainFuncTable["logical_device"] = doLogicalDevice
+ mainFuncTable["omci"] = doOmci
+ mainFuncTable["pdb"] = doPdb
+ mainFuncTable["version"] = doVersion
+ mainFuncTable["health"] = doHealth
+ mainFuncTable["preprovison_olt"] = doPreprovisionOlt
+ mainFuncTable["enable"] = doEnable
+ mainFuncTable["reboot"] = doReboot
+ mainFuncTable["self_test"] = doSelfTest
+ mainFuncTable["delete"] = doDelete
+ mainFuncTable["disable"] = doDisable
+ mainFuncTable["test"] = doTest
+ mainFuncTable["alarm_filters"] = doAlarmFilters
+ mainFuncTable["arrive_onus"] = doArriveOnus
+ mainFuncTable["install_eapol_flow"] = doInstallEapolFlow
+ mainFuncTable["install_all_controller_bound_flows"] = doInstallAllControllerBoundFlows
+ mainFuncTable["install_all_sample_flows"] = doInstallAllSampleFlows
+ mainFuncTable["install_dhcp_flows"] = doInstallDhcpFlows
+ mainFuncTable["delete_all_flows"] = doDeleteAllFlows
+ mainFuncTable["send_simulated_upstream_eapol"] = doSendSimulatedUpstreamEapol
+ mainFuncTable["inject_eapol_start"] = doInjectEapolStart
+ util.ProcessTable(mainFuncTable, inputPrompt)
+}
diff --git a/cli/menu/mainmenu/omci.go b/cli/menu/mainmenu/omci.go
new file mode 100644
index 0000000..98d3328
--- /dev/null
+++ b/cli/menu/mainmenu/omci.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doOmci(enterPressed bool) {
+ fmt.Print("input: ocmi>")
+}
diff --git a/cli/menu/mainmenu/pdb.go b/cli/menu/mainmenu/pdb.go
new file mode 100644
index 0000000..32b9035
--- /dev/null
+++ b/cli/menu/mainmenu/pdb.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doPdb(enterPressed bool) {
+ fmt.Print("input: pdb>")
+}
diff --git a/cli/menu/mainmenu/preprovisionOlt.go b/cli/menu/mainmenu/preprovisionOlt.go
new file mode 100644
index 0000000..f185b14
--- /dev/null
+++ b/cli/menu/mainmenu/preprovisionOlt.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doPreprovisionOlt(enterPressed bool) {
+ fmt.Print("input preprovision_olt>")
+}
diff --git a/cli/menu/mainmenu/reboot.go b/cli/menu/mainmenu/reboot.go
new file mode 100644
index 0000000..a0a4b12
--- /dev/null
+++ b/cli/menu/mainmenu/reboot.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doReboot(enterPressed bool) {
+ fmt.Print("input: reboot>")
+}
diff --git a/cli/menu/mainmenu/relativeLoad.go b/cli/menu/mainmenu/relativeLoad.go
new file mode 100644
index 0000000..ab492b4
--- /dev/null
+++ b/cli/menu/mainmenu/relativeLoad.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doRelativeLoad(enterPressed bool) {
+ fmt.Print("input: relative_load>")
+}
diff --git a/cli/menu/mainmenu/resetHistory.go b/cli/menu/mainmenu/resetHistory.go
new file mode 100644
index 0000000..61187a5
--- /dev/null
+++ b/cli/menu/mainmenu/resetHistory.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doResetHistory(enterPressed bool) {
+ fmt.Print("input: reset_history>")
+}
diff --git a/cli/menu/mainmenu/restart.go b/cli/menu/mainmenu/restart.go
new file mode 100644
index 0000000..62ce7e1
--- /dev/null
+++ b/cli/menu/mainmenu/restart.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doRestart(enterPressed bool) {
+ fmt.Print("input: restart>")
+}
diff --git a/cli/menu/mainmenu/selfTest.go b/cli/menu/mainmenu/selfTest.go
new file mode 100644
index 0000000..f25e6fb
--- /dev/null
+++ b/cli/menu/mainmenu/selfTest.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doSelfTest(enterPressed bool) {
+ fmt.Print("input: self_test>")
+}
diff --git a/cli/menu/mainmenu/sendSimulatedUpstreamEapol.go b/cli/menu/mainmenu/sendSimulatedUpstreamEapol.go
new file mode 100644
index 0000000..c82b0df
--- /dev/null
+++ b/cli/menu/mainmenu/sendSimulatedUpstreamEapol.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doSendSimulatedUpstreamEapol(enterPressed bool) {
+ fmt.Print("input: send_simulated_upstream_eapol>")
+}
diff --git a/cli/menu/mainmenu/test.go b/cli/menu/mainmenu/test.go
new file mode 100644
index 0000000..96e3f0a
--- /dev/null
+++ b/cli/menu/mainmenu/test.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doTest(enterPressed bool) {
+ fmt.Print("input: test>")
+}
diff --git a/cli/menu/mainmenu/version.go b/cli/menu/mainmenu/version.go
new file mode 100644
index 0000000..7464c1b
--- /dev/null
+++ b/cli/menu/mainmenu/version.go
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package mainmenu
+
+import "fmt"
+
+func doVersion(enterPressed bool) {
+ fmt.Print("input: version>")
+}
diff --git a/cli/util/menuProcessor.go b/cli/util/menuProcessor.go
new file mode 100644
index 0000000..c9ba837
--- /dev/null
+++ b/cli/util/menuProcessor.go
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package util
+
+import (
+ "fmt"
+ "os"
+)
+
+/*
+ProcessTable parses table structure and executes functions
+*/
+func ProcessTable(functionTable map[string]func(bool), inputPrompt string) {
+ keys := []string{}
+ for k := range functionTable {
+ keys = append(keys, k)
+ }
+ var b = make([]byte, 1)
+ input := ""
+ fmt.Print(inputPrompt)
+ for {
+ os.Stdin.Read(b)
+ char := string(b)
+ if char == "\t" || char == "\n" || char == "?" {
+ fmt.Println("")
+ ret, prompt := Test(input, keys)
+ if len(ret) == 1 {
+ input = ret[0]
+ if input == "exit" {
+ return
+ }
+ if char == "\n" {
+ Route(input, functionTable, true)
+ } else {
+ Route(input, functionTable, false)
+ }
+ input = ""
+ fmt.Print(inputPrompt)
+ } else if len(ret) == 0 {
+ input = ""
+ fmt.Println("\nInvalid Input ")
+ fmt.Print(inputPrompt)
+ } else if len(ret) == 0 {
+ } else {
+
+ fmt.Println(ret)
+ input = prompt
+ fmt.Print(inputPrompt)
+ fmt.Print(prompt)
+ }
+ } else if char == " " {
+ _, ok := functionTable[input]
+ if ok {
+ Route(input, functionTable, false)
+ fmt.Print(inputPrompt)
+ input = ""
+ } else {
+ ret, prompt := Test(input, keys)
+ if len(ret) == 1 {
+ input = ret[0]
+ Route(input, functionTable, false)
+ input = ""
+ fmt.Print(inputPrompt)
+ } else if len(ret) == 0 {
+ input = ""
+ fmt.Println("\nInvalid Input ")
+ fmt.Print(inputPrompt)
+ } else {
+
+ fmt.Println(ret)
+ input = prompt
+ fmt.Print(inputPrompt + input)
+ }
+ }
+
+ } else if b[0] == 127 || char == "\b" {
+ sz := len(input)
+
+ if sz > 0 {
+ fmt.Print("\b \b")
+ input = input[:sz-1]
+ }
+ } else {
+ fmt.Print(char)
+ input += char
+ }
+ }
+}
diff --git a/cli/util/parseCmd.go b/cli/util/parseCmd.go
new file mode 100644
index 0000000..06ad8b8
--- /dev/null
+++ b/cli/util/parseCmd.go
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package util
+
+import (
+ "os"
+ "strings"
+)
+
+func Test(chars string, values []string) ([]string, string) {
+
+ var ret []string
+ for i := 0; i < len(values); i++ {
+ if strings.HasPrefix(values[i], chars) {
+ ret = append(ret, values[i])
+ }
+ }
+ if len(ret) == 0 {
+ return ret, ""
+ }
+ shortIndex := 0
+ if len(ret) > 1 {
+ for i := 0; i < len(ret); i++ {
+ if len(ret[i]) < len(ret[shortIndex]) {
+ shortIndex = i
+ }
+ }
+ }
+ for i := len(chars); i < len(ret[shortIndex]); i++ {
+ inAllWords := true
+ for j := 0; j < len(ret); j++ {
+ inAllWords = inAllWords && ret[j][i] == ret[shortIndex][i]
+ }
+ if inAllWords {
+ chars += string(ret[shortIndex][i])
+ } else {
+ return ret, chars
+ }
+
+ }
+
+ return ret, chars
+}
+
+func Route(command string, table map[string]func(bool), enterPressed bool) {
+ cmd := table[command]
+ cmd(enterPressed)
+
+}
+
+func Exit(notUsed bool) {
+ os.Exit(0)
+}
diff --git a/cli/util/tableGen.go b/cli/util/tableGen.go
new file mode 100644
index 0000000..3b07ef0
--- /dev/null
+++ b/cli/util/tableGen.go
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package util
+
+import (
+ "fmt"
+ "strings"
+)
+
+func BuildTable(keys []string, rows []map[string]string) (string, error) {
+ var returnString string
+ fieldSizes := make(map[string]int)
+
+ for i := 0; i < len(rows); i++ {
+ for key, value := range rows[i] {
+ currentSize := len(value)
+ if currentSize > fieldSizes[key] {
+ fieldSizes[key] = currentSize
+ }
+
+ }
+ }
+ for i := 0; i < len(keys); i++ {
+ currentSize := len(keys[i])
+ if currentSize > fieldSizes[keys[i]] {
+ fieldSizes[keys[i]] = currentSize
+ }
+ }
+ bottom := "+"
+
+ for i := 0; i < len(rows); i++ {
+ header := "|"
+ line := "|"
+ for j := 0; j < len(keys); j++ {
+ key := keys[j]
+ value := rows[i][key]
+ if i == 0 {
+ pad := 2 + fieldSizes[key] - len(key)
+ field := fmt.Sprintf("%s%s|", strings.Repeat(" ", pad), key)
+ spacer := fmt.Sprintf("%s+", strings.Repeat("-", fieldSizes[key]+2))
+ header = header + field
+ bottom = bottom + spacer
+ }
+ pad := 2 + fieldSizes[key] - len(value)
+ field := fmt.Sprintf("%s%s|", strings.Repeat(" ", pad), value)
+ line = line + field
+
+ }
+ if i == 0 {
+ returnString = bottom + "\n" + header + "\n" + bottom + "\n"
+ }
+
+ returnString = returnString + line + "\n"
+ }
+ returnString = returnString + bottom + "\n"
+
+ return returnString, nil
+
+}
diff --git a/vendor/github.com/bclicn/color/LICENSE b/vendor/github.com/bclicn/color/LICENSE
new file mode 100644
index 0000000..c22bc5f
--- /dev/null
+++ b/vendor/github.com/bclicn/color/LICENSE
@@ -0,0 +1,23 @@
+
+The MIT License (MIT)
+
+Copyright (c) 2016-2018 bcli
+
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/bclicn/color/README.md b/vendor/github.com/bclicn/color/README.md
new file mode 100644
index 0000000..1065950
--- /dev/null
+++ b/vendor/github.com/bclicn/color/README.md
@@ -0,0 +1,43 @@
+# GoLang Colorized Output
+
+GoLang colorized output library for Mac & Linux Shell, [中文版说明](README_CN.md)
+
+## Showcase
+![img](showcase.jpg)
+
+## Install
+
+1. __Make sure__ your've read [GoLang Official File Structure](https://golang.org/doc/code.html)
+2. Make sure you've set a correct GOPATH
+3. `$ go get github.com/bclicn/color`
+4. In your script, `import "github.com/bclicn/color"` then call `color.Test()`
+5. Use `fmt.Println("Hello" + color.Red("World"))` to assemble a colorized output
+6. API examples available in `color-test.go`
+
+## Quick (brainless) Usage
+
+1. Download `color.go`
+2. Modify its `package color` to `package main`
+3. Put your script under the same directory and write `fmt.Println(Red("I'm red !!!"))`
+4. Run `go run color.go yourScript.go`
+5. Or build by `go build color.go yourScript.go`
+
+## A simple test script
+
+ package main
+
+ import (
+ "fmt"
+ "github.com/bclicn/color"
+ )
+
+ func main(){
+ fmt.Println(color.Red("Red output"))
+ color.Test()
+ }
+
+## License
+
+[MIT](LICENSE)
+
+bcli, 2018-7-11
diff --git a/vendor/github.com/bclicn/color/README_CN.md b/vendor/github.com/bclicn/color/README_CN.md
new file mode 100644
index 0000000..25b447e
--- /dev/null
+++ b/vendor/github.com/bclicn/color/README_CN.md
@@ -0,0 +1,43 @@
+# GoLang 彩色输出
+
+用于Mac和Linux Shell的GoLang彩色文字输出, [English Version](README.md)
+
+## 效果展示
+![img](showcase.jpg)
+
+## 安装
+
+1. __确保__你已经读过 [GoLang官方文件结构](https://golang.org/doc/code.html)
+2. 确保你的GOPATH环境变量正确
+3. `go get github.com/bclicn/color`
+3. 在你的脚本中,`import "github.com/bclicn/color"` 然后调用 `color.Test()`查看全部效果
+5. 使用`fmt.Println("Hello" + color.Red("World"))`进行彩色输出
+4. API调用示例在`color-test.go`
+
+## 快速(无脑)使用
+
+1. 下载`color.go`
+2. 将其第一行的`package color`改为`package main`
+3. 把你的脚本放在同一个文件夹下,直接调用如`fmt.Println(Red("I'm red !!!"))`
+4. 运行`go run color.go yourScript.go`
+5. 你也可以直接`go build color.go yourScript.go`
+
+## 快速调用示例
+
+ package main
+
+ import (
+ "fmt"
+ "github.com/bclicn/color"
+ )
+
+ func main(){
+ fmt.Println(color.Red("Red output"))
+ color.Test()
+ }
+
+## License
+
+[MIT](LICENSE)
+
+bcli, 2018-7-11
diff --git a/vendor/github.com/bclicn/color/color-test.go b/vendor/github.com/bclicn/color/color-test.go
new file mode 100644
index 0000000..59e9b5b
--- /dev/null
+++ b/vendor/github.com/bclicn/color/color-test.go
@@ -0,0 +1,87 @@
+package color
+
+import (
+ "fmt"
+)
+
+// github.com/bclicn/color
+// colorized output for Mac & Linux terminal
+// version: 1.0.0
+// author: bcli, bclicn@gmail.com, 2016-11-4
+// see: http://misc.flogisoft.com/bash/tip_colors_and_formatting
+// usage:
+// For official code layout
+// $ go get github.com/bclicn/color
+// # in your project
+// import "github.com/bclicn/color"
+// func main() {
+// color.Test()
+// }
+
+func ColorTest() {
+
+ const HEAD = " "
+ const TAIL = " "
+
+ // regular
+ fmt.Println(HEAD + Black("black") + TAIL)
+ fmt.Println(HEAD + Red("red") + TAIL)
+ fmt.Println(HEAD + Green("green") + TAIL)
+ fmt.Println(HEAD + Yellow("yellow") + TAIL)
+ fmt.Println(HEAD + Blue("blue") + TAIL)
+ fmt.Println(HEAD + Purple("purple") + TAIL)
+ fmt.Println(HEAD + Cyan("cyan") + TAIL)
+ fmt.Println(HEAD + LightGray("light gray") + TAIL)
+ fmt.Println(HEAD + DarkGray("dark gray") + TAIL)
+ fmt.Println(HEAD + LightRed("light red") + TAIL)
+ fmt.Println(HEAD + LightGreen("light green") + TAIL)
+ fmt.Println(HEAD + LightYellow("light yellow") + TAIL)
+ fmt.Println(HEAD + LightBlue("light blue") + TAIL)
+ fmt.Println(HEAD + LightPurple("light purple") + TAIL)
+ fmt.Println(HEAD + LightCyan("light cyan") + TAIL)
+ fmt.Println(HEAD + White("white") + TAIL)
+
+ // bold
+ fmt.Println(HEAD + BBlack("bold black") + TAIL)
+ fmt.Println(HEAD + BRed("bold red") + TAIL)
+ fmt.Println(HEAD + BGreen("bold green") + TAIL)
+ fmt.Println(HEAD + BYellow("bold yellow") + TAIL)
+ fmt.Println(HEAD + BBlue("bold blue") + TAIL)
+ fmt.Println(HEAD + BPurple("bold purple") + TAIL)
+ fmt.Println(HEAD + BCyan("bold cyan") + TAIL)
+ fmt.Println(HEAD + BLightGray("bold light gray") + TAIL)
+ fmt.Println(HEAD + BDarkGray("bold dark gray") + TAIL)
+ fmt.Println(HEAD + BLightRed("bold light red") + TAIL)
+ fmt.Println(HEAD + BLightGreen("bold light green") + TAIL)
+ fmt.Println(HEAD + BLightYellow("bold light yellow") + TAIL)
+ fmt.Println(HEAD + BLightBlue("bold light blue") + TAIL)
+ fmt.Println(HEAD + BLightPurple("bold light purple") + TAIL)
+ fmt.Println(HEAD + BLightCyan("bold light cyan") + TAIL)
+ fmt.Println(HEAD + BWhite("bold white") + TAIL)
+
+ // background
+ fmt.Println(HEAD + GBlack("background black") + TAIL)
+ fmt.Println(HEAD + GRed("background red") + TAIL)
+ fmt.Println(HEAD + GGreen("background green") + TAIL)
+ fmt.Println(HEAD + GYellow("background yellow") + TAIL)
+ fmt.Println(HEAD + GBlue("background blue") + TAIL)
+ fmt.Println(HEAD + GPurple("background purple") + TAIL)
+ fmt.Println(HEAD + GCyan("background cyan") + TAIL)
+ fmt.Println(HEAD + GLightGray("background light gray") + TAIL)
+ fmt.Println(HEAD + GDarkGray("background dark gray") + TAIL)
+ fmt.Println(HEAD + GLightRed("background light red") + TAIL)
+ fmt.Println(HEAD + GLightGreen("background light green") + TAIL)
+ fmt.Println(HEAD + GLightYellow("background light yellow") + TAIL)
+ fmt.Println(HEAD + GLightBlue("background light blue") + TAIL)
+ fmt.Println(HEAD + GLightPurple("background light purple") + TAIL)
+ fmt.Println(HEAD + GLightCyan("background light cyan") + TAIL)
+ fmt.Println(HEAD + GWhite("background white") + TAIL)
+
+ // special
+ fmt.Println("A " + Bold("bold") + " text")
+ fmt.Println("This is a " + Dim("dimmed") + " text")
+ fmt.Println("Add a " + Underline("underline"))
+ fmt.Println("Use " + Invert("invert") + " to highlight your text")
+ fmt.Println("Your password is:" + Hide("myPass"))
+ fmt.Println("OMG I'm " + Blink("blinking") + " !!!") // blinking works only on mac
+}
diff --git a/vendor/github.com/bclicn/color/color.go b/vendor/github.com/bclicn/color/color.go
new file mode 100644
index 0000000..ce7fc83
--- /dev/null
+++ b/vendor/github.com/bclicn/color/color.go
@@ -0,0 +1,330 @@
+// github.com/bclicn/color
+// colorized output for Mac & Linux terminal
+// version: 1.0.0
+// author: bcli, bclicn@gmail.com, 2018-7-11
+// see: http://misc.flogisoft.com/bash/tip_colors_and_formatting
+// usage:
+// Official layout
+// $ go get github.com/bclicn/color
+// # in your project
+// import "github.com/bclicn/color"
+// func main() {
+// fmt.Println(color.Red("I'm red!"))
+// color.Test()
+// }
+
+package color
+
+import (
+ "strconv"
+)
+
+const (
+ // common
+ reset = "\033[0m" // auto reset the rest of text to default color
+ normal = 0
+ bold = 1 // increase this value if you want bolder text
+ // special
+ dim = 2
+ underline = 4
+ blink = 5
+ reverse = 7
+ hidden = 8
+ // color
+ black = 30 // default = 39
+ red = 31
+ green = 32
+ yellow = 33
+ blue = 34
+ purple = 35 // purple = magenta
+ cyan = 36
+ lightGray = 37
+ darkGray = 90
+ lightRed = 91
+ lightGreen = 92
+ lightYellow = 93
+ lightBlue = 94
+ lightPurple = 95
+ lightCyan = 96
+ white = 97
+)
+
+// you can use custom color code and font size by calling this function
+func Render(colorCode int, fontSize int, content string) string {
+ return "\033[" + strconv.Itoa(fontSize) + ";" + strconv.Itoa(colorCode) + "m" + content + reset
+}
+
+// black text (use this with caution since most geeks use dark console)
+func Black(txt string) string {
+ return Render(black, normal, txt)
+}
+
+// red text
+func Red(txt string) string {
+ return Render(red, normal, txt)
+}
+
+// green text
+func Green(txt string) string {
+ return Render(green, normal, txt)
+}
+
+// yellow text
+func Yellow(txt string) string {
+ return Render(yellow, normal, txt)
+}
+
+// blue text
+func Blue(txt string) string {
+ return Render(blue, normal, txt)
+}
+
+// purple text
+func Purple(txt string) string {
+ return Render(purple, normal, txt)
+}
+
+// cyan text
+func Cyan(txt string) string {
+ return Render(cyan, normal, txt)
+}
+
+// light gray text
+func LightGray(txt string) string {
+ return Render(lightGray, normal, txt)
+}
+
+// dark gray text
+func DarkGray(txt string) string {
+ return Render(darkGray, normal, txt)
+}
+
+// light red text
+func LightRed(txt string) string {
+ return Render(lightRed, normal, txt)
+}
+
+// light green text
+func LightGreen(txt string) string {
+ return Render(lightGreen, normal, txt)
+}
+
+// light yellow text
+func LightYellow(txt string) string {
+ return Render(lightYellow, normal, txt)
+}
+
+// light blue text
+func LightBlue(txt string) string {
+ return Render(lightBlue, normal, txt)
+}
+
+// light purple text
+func LightPurple(txt string) string {
+ return Render(lightPurple, normal, txt)
+}
+
+// light cyan text
+func LightCyan(txt string) string {
+ return Render(lightCyan, normal, txt)
+}
+
+// white text
+func White(txt string) string {
+ return Render(white, normal, txt)
+}
+
+// black text (use this with caution since most geeks use dark console)
+func BBlack(txt string) string {
+ return Render(black, bold, txt)
+}
+
+// bold red
+func BRed(txt string) string {
+ return Render(red, bold, txt)
+}
+
+// bold green
+func BGreen(txt string) string {
+ return Render(green, bold, txt)
+}
+
+// bold yellow
+func BYellow(txt string) string {
+ return Render(yellow, bold, txt)
+}
+
+// bold blue
+func BBlue(txt string) string {
+ return Render(blue, bold, txt)
+}
+
+// bold purple
+func BPurple(txt string) string {
+ return Render(purple, bold, txt)
+}
+
+// bold cyan
+func BCyan(txt string) string {
+ return Render(cyan, bold, txt)
+}
+
+// bold light gray
+func BLightGray(txt string) string {
+ return Render(lightGray, bold, txt)
+}
+
+// bold dark gray
+func BDarkGray(txt string) string {
+ return Render(darkGray, bold, txt)
+}
+
+// bold light red
+func BLightRed(txt string) string {
+ return Render(lightRed, bold, txt)
+}
+
+// bold light green
+func BLightGreen(txt string) string {
+ return Render(lightGreen, bold, txt)
+}
+
+// bold light yellow
+func BLightYellow(txt string) string {
+ return Render(lightYellow, bold, txt)
+}
+
+// bold light blue
+func BLightBlue(txt string) string {
+ return Render(lightBlue, bold, txt)
+}
+
+// bold light purple
+func BLightPurple(txt string) string {
+ return Render(lightPurple, bold, txt)
+}
+
+// bold light cyan
+func BLightCyan(txt string) string {
+ return Render(lightCyan, bold, txt)
+}
+
+// bold white
+func BWhite(txt string) string {
+ return Render(white, bold, txt)
+}
+
+// black background (use this with caution since most of geeks use dark console)
+func GBlack(txt string) string {
+ return Render(black+1, normal, txt)
+}
+
+// red background
+func GRed(txt string) string {
+ return Render(red+1, normal, txt)
+}
+
+// green background
+func GGreen(txt string) string {
+ return Render(green+1, normal, txt)
+}
+
+// yellow background
+func GYellow(txt string) string {
+ return Render(yellow+1, normal, txt)
+}
+
+// blue background
+func GBlue(txt string) string {
+ return Render(blue+1, normal, txt)
+}
+
+// purple background
+func GPurple(txt string) string {
+ return Render(purple+1, normal, txt)
+}
+
+// cyan background
+func GCyan(txt string) string {
+ return Render(cyan+1, normal, txt)
+}
+
+// light gray background
+func GLightGray(txt string) string {
+ return Render(lightGray+1, normal, txt)
+}
+
+// dark gray background
+func GDarkGray(txt string) string {
+ return Render(darkGray+1, normal, txt)
+}
+
+// light red background
+func GLightRed(txt string) string {
+ return Render(lightRed+1, normal, txt)
+}
+
+// light green background
+func GLightGreen(txt string) string {
+ return Render(lightGreen+1, normal, txt)
+}
+
+// light yellow background
+func GLightYellow(txt string) string {
+ return Render(lightYellow+1, normal, txt)
+}
+
+// blue background
+func GLightBlue(txt string) string {
+ return Render(lightBlue+1, normal, txt)
+}
+
+// light purple background
+func GLightPurple(txt string) string {
+ return Render(lightPurple+1, normal, txt)
+}
+
+// light cyan background
+func GLightCyan(txt string) string {
+ return Render(lightCyan+1, normal, txt)
+}
+
+// give text a white background
+func GWhite(txt string) string {
+ return Render(white+1, normal, txt)
+}
+
+// bold text
+func Bold(txt string) string {
+ return Render(bold, normal, txt)
+}
+
+// dimmed text
+func Dim(txt string) string {
+ return Render(dim, normal, txt)
+}
+
+// underlined text
+func Underline(txt string) string {
+ return Render(underline, 0, txt)
+}
+
+// make given text blink, not supported by all consoles
+func Blink(txt string) string {
+ return Render(blink, normal, txt)
+}
+
+// invert the color of text and its background
+func Invert(txt string) string {
+ return Render(reverse, normal, txt)
+}
+
+// hide given text, useful for password input
+func Hide(txt string) string {
+ return Render(hidden, normal, txt)
+}
+
+// test all functions
+func Test() {
+ ColorTest()
+}
diff --git a/vendor/github.com/bclicn/color/showcase.jpg b/vendor/github.com/bclicn/color/showcase.jpg
new file mode 100644
index 0000000..39f270c
--- /dev/null
+++ b/vendor/github.com/bclicn/color/showcase.jpg
Binary files differ