✨ One-liner 的 CLI #3
							
								
								
									
										7
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								go.mod
									
									
									
									
									
								
							| @@ -11,6 +11,13 @@ require ( | ||||
| 	github.com/valyala/fasthttp v1.50.0 | ||||
| ) | ||||
|  | ||||
| require ( | ||||
| 	github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect | ||||
| 	github.com/russross/blackfriday/v2 v2.1.0 // indirect | ||||
| 	github.com/urfave/cli/v2 v2.26.0 // indirect | ||||
| 	github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect | ||||
| ) | ||||
|  | ||||
| require ( | ||||
| 	github.com/andybalholm/brotli v1.0.5 // indirect | ||||
| 	github.com/fsnotify/fsnotify v1.6.0 // indirect | ||||
|   | ||||
							
								
								
									
										8
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								go.sum
									
									
									
									
									
								
							| @@ -56,6 +56,8 @@ github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnht | ||||
| github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= | ||||
| github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= | ||||
| github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= | ||||
| github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= | ||||
| github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= | ||||
| github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||
| github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||
| github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= | ||||
| @@ -206,6 +208,8 @@ github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/f | ||||
| github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= | ||||
| github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A= | ||||
| github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= | ||||
| github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= | ||||
| github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= | ||||
| github.com/sagikazarmark/crypt v0.15.0/go.mod h1:5rwNNax6Mlk9sZ40AcyVtiEw24Z4J04cfSioF2COKmc= | ||||
| github.com/sagikazarmark/locafero v0.3.0 h1:zT7VEGWC2DTflmccN/5T1etyKvxSxpHsjb9cJvm4SvQ= | ||||
| github.com/sagikazarmark/locafero v0.3.0/go.mod h1:w+v7UsPNFwzF1cHuOajOOzoq4U7v/ig1mpRjqV+Bu1U= | ||||
| @@ -238,12 +242,16 @@ github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8 | ||||
| github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= | ||||
| github.com/tinylib/msgp v1.1.8 h1:FCXC1xanKO4I8plpHGH2P7koL/RzZs12l/+r7vakfm0= | ||||
| github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw= | ||||
| github.com/urfave/cli/v2 v2.26.0 h1:3f3AMg3HpThFNT4I++TKOejZO8yU55t3JnnSr4S4QEI= | ||||
| github.com/urfave/cli/v2 v2.26.0/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= | ||||
| github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= | ||||
| github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= | ||||
| github.com/valyala/fasthttp v1.50.0 h1:H7fweIlBm0rXLs2q0XbalvJ6r0CUPFWK3/bB4N13e9M= | ||||
| github.com/valyala/fasthttp v1.50.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA= | ||||
| github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= | ||||
| github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= | ||||
| github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= | ||||
| github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= | ||||
| github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||||
| github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||||
| github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||||
|   | ||||
							
								
								
									
										14
									
								
								pkg/administration/connectivity.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								pkg/administration/connectivity.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| package administration | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	roadsign "code.smartsheep.studio/goatworks/roadsign/pkg" | ||||
| 	"github.com/gofiber/fiber/v2" | ||||
| ) | ||||
|  | ||||
| func responseConnectivity(c *fiber.Ctx) error { | ||||
| 	return c. | ||||
| 		Status(fiber.StatusOK). | ||||
| 		SendString(fmt.Sprintf("Hello from RoadSign v%s", roadsign.AppVersion)) | ||||
| } | ||||
| @@ -35,6 +35,11 @@ func InitAdministration() *fiber.App { | ||||
| 		}, | ||||
| 	})) | ||||
|  | ||||
| 	cgi := app.Group("/cgi").Name("CGI") | ||||
| 	{ | ||||
| 		cgi.All("/connectivity", responseConnectivity) | ||||
| 	} | ||||
|  | ||||
| 	webhooks := app.Group("/webhooks").Name("WebHooks") | ||||
| 	{ | ||||
| 		webhooks.Put("/publish/:site/:upstream", doPublish) | ||||
|   | ||||
							
								
								
									
										88
									
								
								pkg/cmd/cli/conn/commands.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								pkg/cmd/cli/conn/commands.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | ||||
| package conn | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/rs/zerolog/log" | ||||
| 	"github.com/samber/lo" | ||||
| 	"github.com/spf13/viper" | ||||
| 	"github.com/urfave/cli/v2" | ||||
| ) | ||||
|  | ||||
| var CliCommands = []*cli.Command{ | ||||
| 	{ | ||||
| 		Name:        "list", | ||||
| 		Aliases:     []string{"ls"}, | ||||
| 		Description: "List all connected remote server", | ||||
| 		Action: func(ctx *cli.Context) error { | ||||
| 			var servers []CliConnection | ||||
| 			raw, _ := json.Marshal(viper.Get("servers")) | ||||
| 			_ = json.Unmarshal(raw, &servers) | ||||
|  | ||||
| 			log.Info().Msgf("There are %d server(s) connected in total.", len(servers)) | ||||
| 			for idx, server := range servers { | ||||
| 				log.Info().Msgf("%d. %s", idx+1, server.Url) | ||||
| 			} | ||||
|  | ||||
| 			return nil | ||||
| 		}, | ||||
| 	}, | ||||
| 	{ | ||||
| 		Name:        "connect", | ||||
| 		Aliases:     []string{"add"}, | ||||
| 		Description: "Connect and save configuration of remote server", | ||||
| 		ArgsUsage:   "<server url> <credential>", | ||||
| 		Action: func(ctx *cli.Context) error { | ||||
| 			if ctx.Args().Len() < 2 { | ||||
| 				return fmt.Errorf("must have more two arguments: <server url> <credential>") | ||||
| 			} | ||||
|  | ||||
| 			c := CliConnection{ | ||||
| 				Url:        ctx.Args().Get(0), | ||||
| 				Credential: ctx.Args().Get(1), | ||||
| 			} | ||||
|  | ||||
| 			if err := c.GetConnectivity(); err != nil { | ||||
| 				return fmt.Errorf("couldn't connect server: %s", err.Error()) | ||||
| 			} else { | ||||
| 				var servers []CliConnection | ||||
| 				raw, _ := json.Marshal(viper.Get("servers")) | ||||
| 				_ = json.Unmarshal(raw, &servers) | ||||
| 				viper.Set("servers", append(servers, c)) | ||||
|  | ||||
| 				if err := viper.WriteConfig(); err != nil { | ||||
| 					return err | ||||
| 				} else { | ||||
| 					log.Info().Msg("Successfully connected a new remote server, enter \"rds ls\" to get more info.") | ||||
| 					return nil | ||||
| 				} | ||||
| 			} | ||||
| 		}, | ||||
| 	}, | ||||
| 	{ | ||||
| 		Name:        "disconnect", | ||||
| 		Aliases:     []string{"remove"}, | ||||
| 		Description: "Remove a remote server configuration", | ||||
| 		ArgsUsage:   "<server url>", | ||||
| 		Action: func(ctx *cli.Context) error { | ||||
| 			if ctx.Args().Len() < 1 { | ||||
| 				return fmt.Errorf("must have more one arguments: <server url>") | ||||
| 			} | ||||
|  | ||||
| 			var servers []CliConnection | ||||
| 			raw, _ := json.Marshal(viper.Get("servers")) | ||||
| 			_ = json.Unmarshal(raw, &servers) | ||||
| 			viper.Set("servers", lo.Filter(servers, func(item CliConnection, idx int) bool { | ||||
| 				return item.Url != ctx.Args().Get(0) | ||||
| 			})) | ||||
|  | ||||
| 			if err := viper.WriteConfig(); err != nil { | ||||
| 				return err | ||||
| 			} else { | ||||
| 				log.Info().Msg("Successfully disconnected a remote server, enter \"rds ls\" to get more info.") | ||||
| 				return nil | ||||
| 			} | ||||
| 		}, | ||||
| 	}, | ||||
| } | ||||
							
								
								
									
										25
									
								
								pkg/cmd/cli/conn/connect.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								pkg/cmd/cli/conn/connect.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| package conn | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/gofiber/fiber/v2" | ||||
| ) | ||||
|  | ||||
| type CliConnection struct { | ||||
| 	Url        string `json:"url"` | ||||
| 	Credential string `json:"credential"` | ||||
| } | ||||
|  | ||||
| func (v CliConnection) GetConnectivity() error { | ||||
| 	client := fiber.Get(v.Url + "/cgi/connectivity") | ||||
| 	client.BasicAuth("RoadSign CLI", v.Credential) | ||||
|  | ||||
| 	if status, _, err := client.String(); len(err) > 0 { | ||||
| 		return fmt.Errorf("couldn't connect to server: %q", err) | ||||
| 	} else if status != 200 { | ||||
| 		return fmt.Errorf("server rejected request, may cause by invalid credential") | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										46
									
								
								pkg/cmd/cli/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								pkg/cmd/cli/main.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"os" | ||||
|  | ||||
| 	roadsign "code.smartsheep.studio/goatworks/roadsign/pkg" | ||||
| 	"code.smartsheep.studio/goatworks/roadsign/pkg/cmd/cli/conn" | ||||
| 	"github.com/rs/zerolog" | ||||
| 	"github.com/rs/zerolog/log" | ||||
| 	"github.com/spf13/viper" | ||||
| 	"github.com/urfave/cli/v2" | ||||
| ) | ||||
|  | ||||
| func init() { | ||||
| 	zerolog.TimeFieldFormat = zerolog.TimeFormatUnix | ||||
| 	log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stdout}) | ||||
| } | ||||
|  | ||||
| func main() { | ||||
| 	// Configure settings | ||||
| 	viper.AddConfigPath("$HOME") | ||||
| 	viper.SetConfigName(".roadsignrc") | ||||
| 	viper.SetConfigType("yaml") | ||||
|  | ||||
| 	// Load settings | ||||
| 	if err := viper.ReadInConfig(); err != nil { | ||||
| 		if _, ok := err.(viper.ConfigFileNotFoundError); ok { | ||||
| 			viper.SafeWriteConfig() | ||||
| 			viper.ReadInConfig() | ||||
| 		} else { | ||||
| 			log.Panic().Err(err).Msg("An error occurred when loading settings.") | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Configure CLI | ||||
| 	app := &cli.App{ | ||||
| 		Name:     "RoadSign CLI", | ||||
| 		Version:  roadsign.AppVersion, | ||||
| 		Commands: append([]*cli.Command{}, conn.CliCommands...), | ||||
| 	} | ||||
|  | ||||
| 	// Run CLI | ||||
| 	if err := app.Run(os.Args); err != nil { | ||||
| 		log.Fatal().Err(err).Msg("An error occurred when running cli.") | ||||
| 	} | ||||
| } | ||||
| @@ -1,5 +1,5 @@ | ||||
| package roadsign | ||||
|  | ||||
| const ( | ||||
| 	AppVersion = "1.0.0" | ||||
| 	AppVersion = "1.2.0" | ||||
| ) | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| debug: | ||||
|     print_routes: false | ||||
| hypertext: | ||||
|     administration_ports: [] | ||||
|     administration_ports: [":81"] | ||||
|     administration_secured_ports: [] | ||||
|     certificate: | ||||
|         administration_key: ./cert.key | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| debug: | ||||
|     print_routes: false | ||||
| hypertext: | ||||
|     administration_ports: [] | ||||
|     administration_ports: [":81"] | ||||
|     administration_secured_ports: [] | ||||
|     certificate: | ||||
|         administration_key: ./cert.key | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| debug: | ||||
|     print_routes: false | ||||
| hypertext: | ||||
|     administration_ports: [] | ||||
|     administration_ports: [":81"] | ||||
|     administration_secured_ports: [] | ||||
|     certificate: | ||||
|         administration_key: ./cert.key | ||||
|   | ||||
		Reference in New Issue
	
	Block a user