You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by bz...@apache.org on 2021/06/04 05:35:52 UTC

[apisix-dashboard] 01/01: feat: split cmd package code

This is an automated email from the ASF dual-hosted git repository.

bzp2010 pushed a commit to branch feat-split-cmd-pkg
in repository https://gitbox.apache.org/repos/asf/apisix-dashboard.git

commit dc73a17b9b9b39ec69bdcfc1dd4333396965ab92
Author: bzp2010 <ba...@iydhp.com>
AuthorDate: Fri Jun 4 13:35:31 2021 +0800

    feat: split cmd package code
---
 api/build.sh                              |   4 +-
 api/cmd/{manager/main.go => install.go}   |  24 ++++--
 api/cmd/{manager/main.go => remove.go}    |  22 +++--
 api/cmd/{managerapi.go => root.go}        | 137 ++++++------------------------
 api/cmd/service.go                        |   3 +-
 api/cmd/{manager/main.go => start.go}     |  22 +++--
 api/cmd/{manager/main.go => status.go}    |  22 +++--
 api/cmd/{manager/main_test.go => stop.go} |  56 +++++-------
 api/cmd/{manager/main.go => version.go}   |  31 +++++--
 api/go.mod                                |   7 +-
 api/go.sum                                |  28 +-----
 api/{cmd/manager => }/main.go             |   7 +-
 api/{cmd/manager => }/main_test.go        |   0
 13 files changed, 146 insertions(+), 217 deletions(-)

diff --git a/api/build.sh b/api/build.sh
index 6cd249a..f160111 100755
--- a/api/build.sh
+++ b/api/build.sh
@@ -24,7 +24,7 @@ GOLDFLAGS="-X github.com/apisix/manager-api/internal/utils.version=${VERSION} -X
 
 # Enter dry-run mode
 if [ "$1" == "--dry-run" ]; then
-    cd ./api && go run -ldflags "${GOLDFLAGS}" ./cmd/manager
+    cd ./api && go run -ldflags "${GOLDFLAGS}" ./main.go
     exit 0
 fi
 
@@ -42,7 +42,7 @@ if [[ ! -f "dag-to-lua-1.1/lib/dag-to-lua.lua" ]]; then
 fi
 
 # build
-cd ./api && go build -o ../output/manager-api -ldflags "${GOLDFLAGS}" ./cmd/manager && cd ..
+cd ./api && go build -o ../output/manager-api -ldflags "${GOLDFLAGS}" ./main.go && cd ..
 
 cp ./api/conf/schema.json ./output/conf/schema.json
 cp ./api/conf/conf.yaml ./output/conf/conf.yaml
diff --git a/api/cmd/manager/main.go b/api/cmd/install.go
similarity index 68%
copy from api/cmd/manager/main.go
copy to api/cmd/install.go
index b4f260a..5604ea7 100644
--- a/api/cmd/manager/main.go
+++ b/api/cmd/install.go
@@ -14,17 +14,27 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package main
+package cmd
 
 import (
 	"fmt"
-	"os"
 
-	"github.com/apisix/manager-api/cmd"
+	"github.com/spf13/cobra"
 )
 
-func main() {
-	if err := cmd.NewManagerAPICommand().Execute(); err != nil {
-		fmt.Fprintln(os.Stderr, err.Error())
-	}
+var service *Service
+
+var installCmd = &cobra.Command{
+	Use:   "install",
+	Short: "re-install Apache APISIX Dashboard service",
+	RunE: func(cmd *cobra.Command, args []string) error {
+		serviceState.installService = true
+		status, err := service.manageService()
+		fmt.Println(status)
+		return err
+	},
+}
+
+func init() {
+	rootCmd.AddCommand(installCmd)
 }
diff --git a/api/cmd/manager/main.go b/api/cmd/remove.go
similarity index 69%
copy from api/cmd/manager/main.go
copy to api/cmd/remove.go
index b4f260a..4391370 100644
--- a/api/cmd/manager/main.go
+++ b/api/cmd/remove.go
@@ -14,17 +14,25 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package main
+package cmd
 
 import (
 	"fmt"
-	"os"
 
-	"github.com/apisix/manager-api/cmd"
+	"github.com/spf13/cobra"
 )
 
-func main() {
-	if err := cmd.NewManagerAPICommand().Execute(); err != nil {
-		fmt.Fprintln(os.Stderr, err.Error())
-	}
+var removeCmd = &cobra.Command{
+	Use:   "remove",
+	Short: "remove Apache APISIX Dashboard service",
+	RunE: func(cmd *cobra.Command, args []string) error {
+		serviceState.removeService = true
+		status, err := service.manageService()
+		fmt.Println(status)
+		return err
+	},
+}
+
+func init() {
+	rootCmd.AddCommand(removeCmd)
 }
diff --git a/api/cmd/managerapi.go b/api/cmd/root.go
similarity index 64%
rename from api/cmd/managerapi.go
rename to api/cmd/root.go
index a3543b1..bd89146 100644
--- a/api/cmd/managerapi.go
+++ b/api/cmd/root.go
@@ -42,30 +42,19 @@ import (
 )
 
 var (
-	showVersion bool
-	Version     string
-	GitHash     string
-	service     *Service
+	configFile string
 )
 
-func printInfo() {
-	fmt.Fprint(os.Stdout, "The manager-api is running successfully!\n\n")
-	printVersion()
-	fmt.Fprintf(os.Stdout, "%-8s: %s:%d\n", "Listen", conf.ServerHost, conf.ServerPort)
-	if conf.SSLCert != "" && conf.SSLKey != "" {
-		fmt.Fprintf(os.Stdout, "%-8s: %s:%d\n", "HTTPS Listen", conf.SSLHost, conf.SSLPort)
-	}
-	fmt.Fprintf(os.Stdout, "%-8s: %s\n", "Loglevel", conf.ErrorLogLevel)
-	fmt.Fprintf(os.Stdout, "%-8s: %s\n\n", "Logfile", conf.ErrorLogPath)
-}
-
-func printVersion() {
-	fmt.Fprintf(os.Stdout, "%-8s: %s\n", "Version", Version)
-	fmt.Fprintf(os.Stdout, "%-8s: %s\n", "GitHash", GitHash)
+var rootCmd = &cobra.Command{
+	Use:   "manager-api [flags]",
+	Short: "Apache APISIX Manager API",
+	RunE: func(cmd *cobra.Command, args []string) error {
+		err := manageAPI()
+		return err
+	},
 }
 
-// NewManagerAPICommand creates the manager-api command.
-func NewManagerAPICommand() *cobra.Command {
+func init() {
 	cobra.OnInitialize(func() {
 		var err error
 		service, err = createService()
@@ -74,25 +63,14 @@ func NewManagerAPICommand() *cobra.Command {
 		}
 	})
 
-	cmd := &cobra.Command{
-		Use:   "manager-api [flags]",
-		Short: "APISIX Manager API",
-		RunE: func(cmd *cobra.Command, args []string) error {
-			GitHash, Version = utils.GetHashAndVersion()
-			if showVersion {
-				printVersion()
-				os.Exit(0)
-			}
-			err := manageAPI()
-			return err
-		},
-	}
-
-	cmd.PersistentFlags().StringVarP(&conf.WorkDir, "work-dir", "p", ".", "current work directory")
-	cmd.PersistentFlags().BoolVarP(&showVersion, "version", "v", false, "show manager-api version")
+	rootCmd.PersistentFlags().StringVarP(&configFile, "config", "c", "./conf/conf.yml", "config file")
+	rootCmd.PersistentFlags().StringVarP(&conf.WorkDir, "work-dir", "p", ".", "current work directory")
+}
 
-	cmd.AddCommand(newStartCommand(), newInstallCommand(), newStatusCommand(), newStopCommand(), newRemoveCommand())
-	return cmd
+func Execute() {
+	if err := rootCmd.Execute(); err != nil {
+		_, _ = fmt.Fprintln(os.Stderr, err.Error())
+	}
 }
 
 func manageAPI() error {
@@ -211,80 +189,13 @@ func shutdownServer(server *http.Server) {
 	}
 }
 
-func newStartCommand() *cobra.Command {
-	cmd := &cobra.Command{
-		Use:   "start",
-		Short: "start Apache APISIX Dashboard service",
-		RunE: func(cmd *cobra.Command, args []string) error {
-			serviceState.startService = true
-			status, err := service.manageService()
-			fmt.Println(status)
-			return err
-		},
-	}
-	return cmd
-}
-
-func newInstallCommand() *cobra.Command {
-	cmd := &cobra.Command{
-		Use:   "install",
-		Short: "re-install Apache APISIX Dashboard service",
-		RunE: func(cmd *cobra.Command, args []string) error {
-			serviceState.installService = true
-			status, err := service.manageService()
-			fmt.Println(status)
-			return err
-		},
-	}
-	return cmd
-}
-
-func newStatusCommand() *cobra.Command {
-	cmd := &cobra.Command{
-		Use:   "status",
-		Short: "inspect the status of Apache APISIX Dashboard service",
-		RunE: func(cmd *cobra.Command, args []string) error {
-			serviceState.status = true
-			status, err := service.manageService()
-			fmt.Println(status)
-			return err
-		},
-	}
-	return cmd
-}
-
-func newStopCommand() *cobra.Command {
-	cmd := &cobra.Command{
-		Use:   "stop",
-		Short: "stop Apache APISIX Dashboard service/program",
-		Run: func(cmd *cobra.Command, args []string) {
-			pid, err := utils.ReadPID(conf.PIDPath)
-			if err != nil {
-				if syscall.ENOENT.Error() != err.Error() {
-					fmt.Fprintf(os.Stderr, "failed to get manager-api pid: %s\n", err)
-				} else {
-					fmt.Fprintf(os.Stderr, "pid path %s not found, is manager-api running?\n", conf.PIDPath)
-				}
-				return
-			}
-			if err := syscall.Kill(pid, syscall.SIGINT); err != nil {
-				fmt.Fprintf(os.Stderr, "failed to kill manager-api: %s", err)
-			}
-		},
-	}
-	return cmd
-}
-
-func newRemoveCommand() *cobra.Command {
-	cmd := &cobra.Command{
-		Use:   "remove",
-		Short: "remove Apache APISIX Dashboard service",
-		RunE: func(cmd *cobra.Command, args []string) error {
-			serviceState.removeService = true
-			status, err := service.manageService()
-			fmt.Println(status)
-			return err
-		},
+func printInfo() {
+	fmt.Fprint(os.Stdout, "The manager-api is running successfully!\n\n")
+	printVersion()
+	fmt.Fprintf(os.Stdout, "%-8s: %s:%d\n", "Listen", conf.ServerHost, conf.ServerPort)
+	if conf.SSLCert != "" && conf.SSLKey != "" {
+		fmt.Fprintf(os.Stdout, "%-8s: %s:%d\n", "HTTPS Listen", conf.SSLHost, conf.SSLPort)
 	}
-	return cmd
+	fmt.Fprintf(os.Stdout, "%-8s: %s\n", "Loglevel", conf.ErrorLogLevel)
+	fmt.Fprintf(os.Stdout, "%-8s: %s\n\n", "Logfile", conf.ErrorLogPath)
 }
diff --git a/api/cmd/service.go b/api/cmd/service.go
index d02d2b2..af187e3 100644
--- a/api/cmd/service.go
+++ b/api/cmd/service.go
@@ -20,8 +20,9 @@ import (
 	"os"
 	"runtime"
 
-	"github.com/apisix/manager-api/internal/conf"
 	"github.com/takama/daemon"
+
+	"github.com/apisix/manager-api/internal/conf"
 )
 
 type Service struct {
diff --git a/api/cmd/manager/main.go b/api/cmd/start.go
similarity index 70%
copy from api/cmd/manager/main.go
copy to api/cmd/start.go
index b4f260a..7bae655 100644
--- a/api/cmd/manager/main.go
+++ b/api/cmd/start.go
@@ -14,17 +14,25 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package main
+package cmd
 
 import (
 	"fmt"
-	"os"
 
-	"github.com/apisix/manager-api/cmd"
+	"github.com/spf13/cobra"
 )
 
-func main() {
-	if err := cmd.NewManagerAPICommand().Execute(); err != nil {
-		fmt.Fprintln(os.Stderr, err.Error())
-	}
+var startCmd = &cobra.Command{
+	Use:   "start",
+	Short: "start Apache APISIX Dashboard service",
+	RunE: func(cmd *cobra.Command, args []string) error {
+		serviceState.startService = true
+		status, err := service.manageService()
+		fmt.Println(status)
+		return err
+	},
+}
+
+func init()  {
+	rootCmd.AddCommand(startCmd)
 }
diff --git a/api/cmd/manager/main.go b/api/cmd/status.go
similarity index 69%
copy from api/cmd/manager/main.go
copy to api/cmd/status.go
index b4f260a..7d64613 100644
--- a/api/cmd/manager/main.go
+++ b/api/cmd/status.go
@@ -14,17 +14,25 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package main
+package cmd
 
 import (
 	"fmt"
-	"os"
 
-	"github.com/apisix/manager-api/cmd"
+	"github.com/spf13/cobra"
 )
 
-func main() {
-	if err := cmd.NewManagerAPICommand().Execute(); err != nil {
-		fmt.Fprintln(os.Stderr, err.Error())
-	}
+var statusCmd = &cobra.Command{
+	Use:   "status",
+	Short: "inspect the status of Apache APISIX Dashboard service",
+	RunE: func(cmd *cobra.Command, args []string) error {
+		serviceState.status = true
+		status, err := service.manageService()
+		fmt.Println(status)
+		return err
+	},
+}
+
+func init() {
+	rootCmd.AddCommand(statusCmd)
 }
diff --git a/api/cmd/manager/main_test.go b/api/cmd/stop.go
similarity index 55%
copy from api/cmd/manager/main_test.go
copy to api/cmd/stop.go
index f891490..25df52d 100644
--- a/api/cmd/manager/main_test.go
+++ b/api/cmd/stop.go
@@ -14,43 +14,31 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package main
+package cmd
 
 import (
-	"os"
-	"os/signal"
-	"strings"
-	"syscall"
-	"testing"
+	"github.com/spf13/cobra"
 )
 
-func TestMainWrapper(t *testing.T) {
-	if os.Getenv("ENV") == "test" {
-		t.Skip("skipping build binary when execute unit test")
-	}
-
-	var (
-		args []string
-	)
-	for _, arg := range os.Args {
-		switch {
-		case strings.HasPrefix(arg, "-test"):
-		default:
-			args = append(args, arg)
+var stopCmd = &cobra.Command{
+	Use:   "stop",
+	Short: "stop Apache APISIX Dashboard service/program",
+	Run: func(cmd *cobra.Command, args []string) {
+		/*pid, err := utils.ReadPID(conf.PIDPath)
+		if err != nil {
+			if syscall.ENOENT.Error() != err.Error() {
+				fmt.Fprintf(os.Stderr, "failed to get manager-api pid: %s\n", err)
+			} else {
+				fmt.Fprintf(os.Stderr, "pid path %s not found, is manager-api running?\n", conf.PIDPath)
+			}
+			return
 		}
-	}
-	waitCh := make(chan int, 1)
-	os.Args = args
-	go func() {
-		main()
-		close(waitCh)
-	}()
-	signalCh := make(chan os.Signal, 1)
-	signal.Notify(signalCh, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGHUP)
-	select {
-	case <-signalCh:
-		return
-	case <-waitCh:
-		return
-	}
+		if err := syscall.Kill(pid, syscall.SIGINT); err != nil {
+			fmt.Fprintf(os.Stderr, "failed to kill manager-api: %s", err)
+		}*/
+	},
+}
+
+func init() {
+	rootCmd.AddCommand(stopCmd)
 }
diff --git a/api/cmd/manager/main.go b/api/cmd/version.go
similarity index 61%
copy from api/cmd/manager/main.go
copy to api/cmd/version.go
index b4f260a..1e12456 100644
--- a/api/cmd/manager/main.go
+++ b/api/cmd/version.go
@@ -14,17 +14,36 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package main
+package cmd
 
 import (
 	"fmt"
 	"os"
 
-	"github.com/apisix/manager-api/cmd"
+	"github.com/spf13/cobra"
+
+	"github.com/apisix/manager-api/internal/utils"
+)
+
+var (
+	Version string
+	GitHash string
 )
 
-func main() {
-	if err := cmd.NewManagerAPICommand().Execute(); err != nil {
-		fmt.Fprintln(os.Stderr, err.Error())
-	}
+var versionCmd = &cobra.Command{
+	Use:   "version",
+	Short: "show manager-api version",
+	Run: func(cmd *cobra.Command, args []string) {
+		printVersion()
+	},
+}
+
+func init() {
+	rootCmd.AddCommand(versionCmd)
+}
+
+func printVersion() {
+	GitHash, Version = utils.GetHashAndVersion()
+	fmt.Fprintf(os.Stdout, "%-8s: %s\n", "Version", Version)
+	fmt.Fprintf(os.Stdout, "%-8s: %s\n", "GitHash", GitHash)
 }
diff --git a/api/go.mod b/api/go.mod
index 62ea026..2091bd3 100644
--- a/api/go.mod
+++ b/api/go.mod
@@ -1,13 +1,13 @@
 module github.com/apisix/manager-api
 
-go 1.13
+go 1.16
 
 replace google.golang.org/grpc => google.golang.org/grpc v1.26.0
 
 replace github.com/coreos/bbolt => go.etcd.io/bbolt v1.3.5
 
 require (
-	github.com/coreos/bbolt v0.0.0-00010101000000-000000000000 // indirect
+	github.com/coreos/bbolt v1.3.2 // indirect
 	github.com/coreos/etcd v3.3.25+incompatible // indirect
 	github.com/coreos/go-semver v0.3.0 // indirect
 	github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf // indirect
@@ -17,12 +17,12 @@ require (
 	github.com/evanphx/json-patch/v5 v5.1.0
 	github.com/getkin/kin-openapi v0.33.0
 	github.com/gin-contrib/pprof v1.3.0
-	github.com/gin-contrib/sessions v0.0.3
 	github.com/gin-contrib/static v0.0.0-20200916080430-d45d9a37d28e
 	github.com/gin-gonic/gin v1.6.3
 	github.com/gogo/protobuf v1.3.2 // indirect
 	github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
 	github.com/google/uuid v1.1.2 // indirect
+	github.com/gorilla/websocket v1.4.2 // indirect
 	github.com/grpc-ecosystem/go-grpc-middleware v1.2.2 // indirect
 	github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
 	github.com/jonboulle/clockwork v0.2.2 // indirect
@@ -33,6 +33,7 @@ require (
 	github.com/sirupsen/logrus v1.7.0 // indirect
 	github.com/sony/sonyflake v1.0.0
 	github.com/spf13/cobra v0.0.3
+	github.com/spf13/pflag v1.0.3 // indirect
 	github.com/stretchr/testify v1.6.1
 	github.com/takama/daemon v1.0.0
 	github.com/tidwall/gjson v1.6.7
diff --git a/api/go.sum b/api/go.sum
index cdf98d0..1580eef 100644
--- a/api/go.sum
+++ b/api/go.sum
@@ -28,9 +28,6 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce
 github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
 github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
 github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
-github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff/go.mod h1:+RTT1BOk5P97fT2CiHkbFQwkK3mjsFAP6zCYV2aXtjw=
-github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
-github.com/bradleypeabody/gorilla-sessions-memcache v0.0.0-20181103040241-659414f458e1/go.mod h1:dkChI7Tbtx7H1Tj7TqGSZMOeGpMP5gLHtjroHd4agiI=
 github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
 github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
@@ -85,8 +82,6 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME
 github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
 github.com/gin-contrib/pprof v1.3.0 h1:G9eK6HnbkSqDZBYbzG4wrjCsA4e+cvYAHUZw6W+W9K0=
 github.com/gin-contrib/pprof v1.3.0/go.mod h1:waMjT1H9b179t3CxuG1cV3DHpga6ybizwfBaM5OXaB0=
-github.com/gin-contrib/sessions v0.0.3 h1:PoBXki+44XdJdlgDqDrY5nDVe3Wk7wDV/UCOuLP6fBI=
-github.com/gin-contrib/sessions v0.0.3/go.mod h1:8C/J6cad3Il1mWYYgtw0w+hqasmpvy25mPkXdOgeB9I=
 github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
 github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
 github.com/gin-contrib/static v0.0.0-20200916080430-d45d9a37d28e h1:8bZpGwoPxkaivQPrAbWl+7zjjUcbFUnYp7yQcx2r2N0=
@@ -95,7 +90,6 @@ github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmC
 github.com/gin-gonic/gin v1.6.2/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
 github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
 github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
-github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
 github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
@@ -146,7 +140,6 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
 github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
 github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
-github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@@ -162,17 +155,12 @@ github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
 github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
-github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
 github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
 github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
 github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
-github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
-github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
-github.com/gorilla/sessions v1.1.1/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w=
-github.com/gorilla/sessions v1.1.3 h1:uXoZdcdA5XdXF3QzuSlheVRUvjl+1rKY7zBXL68L9RU=
-github.com/gorilla/sessions v1.1.3/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w=
-github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c h1:Lh2aW+HnU2Nbe1gqD9SOJLJxW1jBMmQOktN2acDyJk8=
 github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
+github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
+github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
 github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
 github.com/grpc-ecosystem/go-grpc-middleware v1.2.2 h1:FlFbCRLd5Jr4iYXZufAvgWN6Ao0JrI5chLINnUXDDr0=
 github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI=
@@ -221,7 +209,6 @@ github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/
 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
 github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
 github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
-github.com/kidstuff/mongostore v0.0.0-20181113001930-e650cd85ee4b/go.mod h1:g2nVr8KZVXJSS97Jo8pJ0jgq29P6H7dG0oplUA86MQw=
 github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
@@ -250,7 +237,6 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky
 github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
 github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
-github.com/memcachier/mc v2.0.1+incompatible/go.mod h1:7bkvFE61leUBvXz+yxsOnGBQSZpBSPIMUQSmmSHvuXc=
 github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
 github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
 github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
@@ -330,7 +316,6 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx
 github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
 github.com/prometheus/procfs v0.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULUx4=
 github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
-github.com/quasoft/memstore v0.0.0-20180925164028-84a050167438/go.mod h1:wTPjTepVu7uJBYgZ0SdWHQlIas582j6cn2jgk4DDdlg=
 github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
 github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
 github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
@@ -342,7 +327,6 @@ github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0
 github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
 github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
 github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
-github.com/shiningrush/droplet v0.2.4 h1:OW4Pp+dXs9O61QKTiYSRWCdQeOyzO1n9h+i2PDJ5DK0=
 github.com/shiningrush/droplet v0.2.4/go.mod h1:akW2vIeamvMD6zj6wIBfzYn6StGXBxwlW3gA+hcHu5M=
 github.com/shiningrush/droplet v0.2.6-0.20210127040147-53817015cd1b h1:kAS+hyJuHUm/lAN4xbKY4/QHbRse95lcjxcIZwSJEvM=
 github.com/shiningrush/droplet v0.2.6-0.20210127040147-53817015cd1b/go.mod h1:akW2vIeamvMD6zj6wIBfzYn6StGXBxwlW3gA+hcHu5M=
@@ -363,8 +347,9 @@ github.com/sony/sonyflake v1.0.0 h1:MpU6Ro7tfXwgn2l5eluf9xQvQJDROTBImNCfRXn/YeM=
 github.com/sony/sonyflake v1.0.0/go.mod h1:Jv3cfhf/UFtolOTTRd3q4Nl6ENqM+KfyZ5PseKfZGF4=
 github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8=
 github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
-github.com/spf13/pflag v1.0.1 h1:aCvUg6QPl3ibpQUxyLkrEkCHtPqYJL4x9AuhqVqFis4=
 github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
+github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
 github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
 github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
@@ -406,7 +391,6 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/gopher-lua v0.0.0-20200816102855-ee81675732da h1:NimzV1aGyq29m5ukMK0AMWEhFaL/lrEOaephfuoiARg=
 github.com/yuin/gopher-lua v0.0.0-20200816102855-ee81675732da/go.mod h1:E1AXubJBdNmFERAOucpDIxNzeGfLzg0mYh+UfMWdChA=
-go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=
 go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
 go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0=
 go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
@@ -452,7 +436,6 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl
 golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
 golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
 golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
-golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b h1:GgiSbuUyC0BlbUmHQBgFqu32eiRR/CEYdjOjOd4zE6Y=
 golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
@@ -475,7 +458,6 @@ golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLL
 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
 golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
-golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
 golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
@@ -521,7 +503,6 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211 h1:9UQO31fZ+0aKQOFldThf7BKPMJTiBfWycGh/u3UoO88=
 golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@@ -541,7 +522,6 @@ golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtn
 golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa h1:5E4dL8+NgFOgjwbTKz+OOEGGhP+ectTmF842l6KjupQ=
 golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20210106214847-113979e3529a h1:CB3a9Nez8M13wwlr/E2YtwoU+qYHKfC+JrDa45RXXoQ=
diff --git a/api/cmd/manager/main.go b/api/main.go
similarity index 88%
rename from api/cmd/manager/main.go
rename to api/main.go
index b4f260a..6fc7013 100644
--- a/api/cmd/manager/main.go
+++ b/api/main.go
@@ -17,14 +17,9 @@
 package main
 
 import (
-	"fmt"
-	"os"
-
 	"github.com/apisix/manager-api/cmd"
 )
 
 func main() {
-	if err := cmd.NewManagerAPICommand().Execute(); err != nil {
-		fmt.Fprintln(os.Stderr, err.Error())
-	}
+	cmd.Execute()
 }
diff --git a/api/cmd/manager/main_test.go b/api/main_test.go
similarity index 100%
rename from api/cmd/manager/main_test.go
rename to api/main_test.go