From 948d927eb9e16f85813c8d9073d4476268b29fe1 Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Fri, 8 Jan 2021 22:19:23 -0800 Subject: [PATCH] Cleanup command running a bit --- cmd/root.go | 104 ++++++++++++++++++++++++------------------------ system/const.go | 2 +- 2 files changed, 54 insertions(+), 52 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index ef7d8c8..d1e26a0 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -21,6 +21,7 @@ import ( "github.com/spf13/cobra" "golang.org/x/crypto/acme" "golang.org/x/crypto/acme/autocert" + log2 "log" "net/http" "os" "path" @@ -29,39 +30,51 @@ import ( ) var ( - profiler = "" - configPath = config.DefaultLocation - debug = false - useAutomaticTls = false - tlsHostname = "" - showVersion = false - ignoreCertificateErrors = false + configPath = config.DefaultLocation + debug = false ) -var root = &cobra.Command{ +var rootCommand = &cobra.Command{ Use: "wings", - Short: "The wings of the pterodactyl game management panel", - Long: ``, + Short: "Runs the API server allowing programatic control of game servers for Pterodactyl Panel.", PreRun: func(cmd *cobra.Command, args []string) { - if useAutomaticTls && len(tlsHostname) == 0 { - fmt.Println("A TLS hostname must be provided when running wings with automatic TLS, e.g.:\n\n ./wings --auto-tls --tls-hostname my.example.com") - os.Exit(1) + if tls, _ := cmd.Flags().GetBool("auto-tls"); tls { + if host, _ := cmd.Flags().GetString("tls-hostname"); host == "" { + fmt.Println("A TLS hostname must be provided when running wings with automatic TLS, e.g.:\n\n ./wings --auto-tls --tls-hostname my.example.com") + os.Exit(1) + } } }, Run: rootCmdRun, } -func init() { - root.PersistentFlags().BoolVar(&showVersion, "version", false, "show the version and exit") - root.PersistentFlags().StringVar(&configPath, "config", config.DefaultLocation, "set the location for the configuration file") - root.PersistentFlags().BoolVar(&debug, "debug", false, "pass in order to run wings in debug mode") - root.PersistentFlags().StringVar(&profiler, "profiler", "", "the profiler to run for this instance") - root.PersistentFlags().BoolVar(&useAutomaticTls, "auto-tls", false, "pass in order to have wings generate and manage it's own SSL certificates using Let's Encrypt") - root.PersistentFlags().StringVar(&tlsHostname, "tls-hostname", "", "required with --auto-tls, the FQDN for the generated SSL certificate") - root.PersistentFlags().BoolVar(&ignoreCertificateErrors, "ignore-certificate-errors", false, "if passed any SSL certificate errors will be ignored by wings") +var versionCommand = &cobra.Command{ + Use: "version", + Short: "Prints the current executable version and exits.", + Run: func(cmd *cobra.Command, _ []string) { + fmt.Printf("wings v%s\nCopyright © 2018 - 2021 Dane Everitt & Contributors\n", system.Version) + }, +} - root.AddCommand(configureCmd) - root.AddCommand(diagnosticsCmd) +func Execute() { + if err := rootCommand.Execute(); err != nil { + log2.Fatalf("failed to execute command: %s", err) + } +} + +func init() { + rootCommand.PersistentFlags().StringVar(&configPath, "config", config.DefaultLocation, "set the location for the configuration file") + rootCommand.PersistentFlags().BoolVar(&debug, "debug", false, "pass in order to run wings in debug mode") + + // Flags specifically used when running the API. + rootCommand.Flags().String("profiler", "", "the profiler to run for this instance") + rootCommand.Flags().Bool("auto-tls", false, "pass in order to have wings generate and manage it's own SSL certificates using Let's Encrypt") + rootCommand.Flags().String("tls-hostname", "", "required with --auto-tls, the FQDN for the generated SSL certificate") + rootCommand.Flags().Bool("ignore-certificate-errors", false, "ignore certificate verification errors when executing API calls") + + rootCommand.AddCommand(versionCommand) + rootCommand.AddCommand(configureCmd) + rootCommand.AddCommand(diagnosticsCmd) } // Get the configuration path based on the arguments provided. @@ -85,13 +98,8 @@ func readConfiguration() (*config.Configuration, error) { return config.ReadConfiguration(p) } -func rootCmdRun(*cobra.Command, []string) { - if showVersion { - fmt.Println(system.Version) - os.Exit(0) - } - - switch profiler { +func rootCmdRun(cmd *cobra.Command, _ []string) { + switch cmd.Flag("profiler").Value.String() { case "cpu": defer profile.Start(profile.CPUProfile).Stop() case "mem": @@ -117,7 +125,6 @@ func rootCmdRun(*cobra.Command, []string) { if errors.Is(err, os.ErrNotExist) { exitWithConfigurationNotice() } - panic(err) } } @@ -141,7 +148,7 @@ func rootCmdRun(*cobra.Command, []string) { log.Debug("running in debug mode") } - if ignoreCertificateErrors { + if ok, _ := cmd.Flags().GetBool("ignore-certificate-errors"); ok { log.Warn("running with --ignore-certificate-errors: TLS certificate host chains and name will not be verified") http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{ InsecureSkipVerify: true, @@ -280,9 +287,15 @@ func rootCmdRun(*cobra.Command, []string) { log.WithField("error", err).Error("failed to create backup directory") } + autotls, _ := cmd.Flags().GetBool("auto-tls") + tlshostname, _ := cmd.Flags().GetString("tls-hostname") + if autotls && tlshostname == "" { + autotls = false + } + log.WithFields(log.Fields{ "use_ssl": c.Api.Ssl.Enabled, - "use_auto_tls": useAutomaticTls && len(tlsHostname) > 0, + "use_auto_tls": autotls, "host_address": c.Api.Host, "host_port": c.Api.Port, }).Info("configuring internal webserver") @@ -293,7 +306,6 @@ func rootCmdRun(*cobra.Command, []string) { s := &http.Server{ Addr: fmt.Sprintf("%s:%d", c.Api.Host, c.Api.Port), Handler: r, - TLSConfig: &tls.Config{ NextProtos: []string{"h2", "http/1.1"}, // @see https://blog.cloudflare.com/exposing-go-on-the-internet @@ -313,14 +325,14 @@ func rootCmdRun(*cobra.Command, []string) { } // Check if the server should run with TLS but using autocert. - if useAutomaticTls && len(tlsHostname) > 0 { + if autotls { m := autocert.Manager{ Prompt: autocert.AcceptTOS, Cache: autocert.DirCache(path.Join(c.System.RootDirectory, "/.tls-cache")), - HostPolicy: autocert.HostWhitelist(tlsHostname), + HostPolicy: autocert.HostWhitelist(tlshostname), } - log.WithField("hostname", tlsHostname). + log.WithField("hostname", tlshostname). Info("webserver is now listening with auto-TLS enabled; certificates will be automatically generated by Let's Encrypt") // Hook autocert into the main http server. @@ -336,7 +348,7 @@ func rootCmdRun(*cobra.Command, []string) { // Start the main http server with TLS using autocert. if err := s.ListenAndServeTLS("", ""); err != nil { - log.WithFields(log.Fields{"auto_tls": true, "tls_hostname": tlsHostname, "error": err}). + log.WithFields(log.Fields{"auto_tls": true, "tls_hostname": tlshostname, "error": err}). Fatal("failed to configure HTTP server using auto-tls") } @@ -364,11 +376,6 @@ func rootCmdRun(*cobra.Command, []string) { } } -// Execute calls cobra to handle cli commands -func Execute() error { - return root.Execute() -} - // Configures the global logger for Zap so that we can call it from any location // in the code without having to pass around a logger instance. func configureLogging(logDir string, debug bool) error { @@ -379,20 +386,15 @@ func configureLogging(logDir string, debug bool) error { p := filepath.Join(logDir, "/wings.log") w, err := logrotate.NewFile(p) if err != nil { - panic(errors.WithMessage(err, "failed to open process log file")) + return err } + log.SetLevel(log.InfoLevel) if debug { log.SetLevel(log.DebugLevel) - } else { - log.SetLevel(log.InfoLevel) } - log.SetHandler(multi.New( - cli.Default, - cli.New(w.File, false), - )) - + log.SetHandler(multi.New(cli.Default, cli.New(w.File, false))) log.WithField("path", p).Info("writing log files to disk") return nil diff --git a/system/const.go b/system/const.go index 21fe42b..87d87fb 100644 --- a/system/const.go +++ b/system/const.go @@ -2,5 +2,5 @@ package system var ( // The current version of this software. - Version = "v0.0.1" + Version = "0.0.1" )