github.com/nsqio/nsq@v1.3.0/apps/nsqadmin/main.go (about)

     1  package main
     2  
     3  import (
     4  	"flag"
     5  	"fmt"
     6  	"os"
     7  	"path/filepath"
     8  	"sync"
     9  	"syscall"
    10  
    11  	"github.com/BurntSushi/toml"
    12  	"github.com/judwhite/go-svc"
    13  	"github.com/mreiferson/go-options"
    14  	"github.com/nsqio/nsq/internal/app"
    15  	"github.com/nsqio/nsq/internal/lg"
    16  	"github.com/nsqio/nsq/internal/version"
    17  	"github.com/nsqio/nsq/nsqadmin"
    18  )
    19  
    20  func nsqadminFlagSet(opts *nsqadmin.Options) *flag.FlagSet {
    21  	flagSet := flag.NewFlagSet("nsqadmin", flag.ExitOnError)
    22  
    23  	flagSet.String("config", "", "path to config file")
    24  	flagSet.Bool("version", false, "print version string")
    25  
    26  	logLevel := opts.LogLevel
    27  	flagSet.Var(&logLevel, "log-level", "set log verbosity: debug, info, warn, error, or fatal")
    28  	flagSet.String("log-prefix", "[nsqadmin] ", "log message prefix")
    29  	flagSet.Bool("verbose", false, "[deprecated] has no effect, use --log-level")
    30  
    31  	flagSet.String("http-address", opts.HTTPAddress, "<addr>:<port> to listen on for HTTP clients")
    32  	flagSet.String("base-path", opts.BasePath, "URL base path")
    33  	flagSet.String("dev-static-dir", opts.DevStaticDir, "(development use only)")
    34  
    35  	flagSet.String("graphite-url", opts.GraphiteURL, "graphite HTTP address")
    36  	flagSet.Bool("proxy-graphite", false, "proxy HTTP requests to graphite")
    37  
    38  	flagSet.String("statsd-counter-format", opts.StatsdCounterFormat, "The counter stats key formatting applied by the implementation of statsd. If no formatting is desired, set this to an empty string.")
    39  	flagSet.String("statsd-gauge-format", opts.StatsdGaugeFormat, "The gauge stats key formatting applied by the implementation of statsd. If no formatting is desired, set this to an empty string.")
    40  	flagSet.String("statsd-prefix", opts.StatsdPrefix, "prefix used for keys sent to statsd (%s for host replacement, must match nsqd)")
    41  	flagSet.Duration("statsd-interval", opts.StatsdInterval, "time interval nsqd is configured to push to statsd (must match nsqd)")
    42  
    43  	flagSet.String("notification-http-endpoint", "", "HTTP endpoint (fully qualified) to which POST notifications of admin actions will be sent")
    44  
    45  	flagSet.Duration("http-client-connect-timeout", opts.HTTPClientConnectTimeout, "timeout for HTTP connect")
    46  	flagSet.Duration("http-client-request-timeout", opts.HTTPClientRequestTimeout, "timeout for HTTP request")
    47  
    48  	flagSet.Bool("http-client-tls-insecure-skip-verify", false, "configure the HTTP client to skip verification of TLS certificates")
    49  	flagSet.String("http-client-tls-root-ca-file", "", "path to CA file for the HTTP client")
    50  	flagSet.String("http-client-tls-cert", "", "path to certificate file for the HTTP client")
    51  	flagSet.String("http-client-tls-key", "", "path to key file for the HTTP client")
    52  
    53  	flagSet.String("allow-config-from-cidr", opts.AllowConfigFromCIDR, "A CIDR from which to allow HTTP requests to the /config endpoint")
    54  	flagSet.String("acl-http-header", opts.ACLHTTPHeader, "HTTP header to check for authenticated admin users")
    55  
    56  	nsqlookupdHTTPAddresses := app.StringArray{}
    57  	flagSet.Var(&nsqlookupdHTTPAddresses, "lookupd-http-address", "lookupd HTTP address (may be given multiple times)")
    58  	nsqdHTTPAddresses := app.StringArray{}
    59  	flagSet.Var(&nsqdHTTPAddresses, "nsqd-http-address", "nsqd HTTP address (may be given multiple times)")
    60  	adminUsers := app.StringArray{}
    61  	flagSet.Var(&adminUsers, "admin-user", "admin user (may be given multiple times; if specified, only these users will be able to perform privileged actions; acl-http-header is used to determine the authenticated user)")
    62  
    63  	return flagSet
    64  }
    65  
    66  type program struct {
    67  	once     sync.Once
    68  	nsqadmin *nsqadmin.NSQAdmin
    69  }
    70  
    71  func main() {
    72  	prg := &program{}
    73  	if err := svc.Run(prg, syscall.SIGINT, syscall.SIGTERM); err != nil {
    74  		logFatal("%s", err)
    75  	}
    76  }
    77  
    78  func (p *program) Init(env svc.Environment) error {
    79  	if env.IsWindowsService() {
    80  		dir := filepath.Dir(os.Args[0])
    81  		return os.Chdir(dir)
    82  	}
    83  	return nil
    84  }
    85  
    86  func (p *program) Start() error {
    87  	opts := nsqadmin.NewOptions()
    88  
    89  	flagSet := nsqadminFlagSet(opts)
    90  	flagSet.Parse(os.Args[1:])
    91  
    92  	if flagSet.Lookup("version").Value.(flag.Getter).Get().(bool) {
    93  		fmt.Println(version.String("nsqadmin"))
    94  		os.Exit(0)
    95  	}
    96  
    97  	var cfg config
    98  	configFile := flagSet.Lookup("config").Value.String()
    99  	if configFile != "" {
   100  		_, err := toml.DecodeFile(configFile, &cfg)
   101  		if err != nil {
   102  			logFatal("failed to load config file %s - %s", configFile, err)
   103  		}
   104  	}
   105  	cfg.Validate()
   106  
   107  	options.Resolve(opts, flagSet, cfg)
   108  	nsqadmin, err := nsqadmin.New(opts)
   109  	if err != nil {
   110  		logFatal("failed to instantiate nsqadmin - %s", err)
   111  	}
   112  	p.nsqadmin = nsqadmin
   113  
   114  	go func() {
   115  		err := p.nsqadmin.Main()
   116  		if err != nil {
   117  			p.Stop()
   118  			os.Exit(1)
   119  		}
   120  	}()
   121  
   122  	return nil
   123  }
   124  
   125  func (p *program) Stop() error {
   126  	p.once.Do(func() {
   127  		p.nsqadmin.Exit()
   128  	})
   129  	return nil
   130  }
   131  
   132  func logFatal(f string, args ...interface{}) {
   133  	lg.LogFatal("[nsqadmin] ", f, args...)
   134  }