Esempio n. 1
0
// Configure the connector to connect to the server over ssl. Parses the
// connection string, and sets up the correct function to dial the server
// based on the ssl options passed in.
func (self *SSLDBConnector) Configure(opts options.ToolOptions) error {

	// create the addresses to be used to connect
	connectionAddrs := util.CreateConnectionAddrs(opts.Host, opts.Port)

	var err error
	self.ctx, err = setupCtx(opts)
	if err != nil {
		return fmt.Errorf("setupCtx: %v", err)
	}

	// create the dialer func that will be used to connect
	dialer := func(addr *mgo.ServerAddr) (net.Conn, error) {
		conn, err := openssl.Dial("tcp", addr.String(), self.ctx, 0)
		self.dialError = err
		return conn, err
	}

	// set up the dial info
	self.dialInfo = &mgo.DialInfo{
		Addrs:      connectionAddrs,
		Timeout:    DefaultSSLDialTimeout,
		DialServer: dialer,

		Username:  opts.Auth.Username,
		Password:  opts.Auth.Password,
		Source:    opts.Auth.Source,
		Mechanism: opts.Auth.Mechanism,
	}

	return nil

}
Esempio n. 2
0
// Configure the db connector. Parses the connection string and sets up
// the dial info with the default dial timeout.
func (self *KerberosDBConnector) Configure(opts options.ToolOptions) error {

	// create the addresses to be used to connect
	connectionAddrs := util.CreateConnectionAddrs(opts.Host, opts.Port)

	// set up the dial info
	self.dialInfo = &mgo.DialInfo{
		Addrs:          connectionAddrs,
		Timeout:        KERBEROS_DIAL_TIMEOUT,
		Direct:         opts.Direct,
		ReplicaSetName: opts.ReplicaSetName,

		// Kerberos principal
		Username: opts.Auth.Username,
		// Note: Password is only used on Windows. SASL doesn't allow you to specify
		// a password, so this field is ignored on Linux and OSX. Run the kinit
		// command to get a ticket first.
		Password: opts.Auth.Password,
		// This should always be '$external', but legacy tools still allow you to
		// specify a source DB
		Source:      opts.Auth.Source,
		Service:     opts.Kerberos.Service,
		ServiceHost: opts.Kerberos.ServiceHost,
		Mechanism:   KERBEROS_AUTHENTICATION_MECHANISM,
	}

	return nil
}
Esempio n. 3
0
// Configure sets up the db connector using the options in opts. It parses the
// connection string and then sets up the dial information using the default
// dial timeout.
func (self *VanillaDBConnector) Configure(opts options.ToolOptions) error {
	// create the addresses to be used to connect
	connectionAddrs := util.CreateConnectionAddrs(opts.Host, opts.Port)

	// set up the dial info
	self.dialInfo = &mgo.DialInfo{
		Addrs:          connectionAddrs,
		Timeout:        DefaultDialTimeout,
		Direct:         opts.Direct,
		ReplicaSetName: opts.ReplicaSetName,
		Username:       opts.Auth.Username,
		Password:       opts.Auth.Password,
		Source:         opts.GetAuthenticationDatabase(),
		Mechanism:      opts.Auth.Mechanism,
	}
	return nil
}
Esempio n. 4
0
// Configure the connector to connect to the server over ssl. Parses the
// connection string, and sets up the correct function to dial the server
// based on the ssl options passed in.
func (self *SSLDBConnector) Configure(opts options.ToolOptions) error {

	// create the addresses to be used to connect
	connectionAddrs := util.CreateConnectionAddrs(opts.Host, opts.Port)

	var err error
	self.ctx, err = setupCtx(opts)
	if err != nil {
		return fmt.Errorf("openssl configuration: %v", err)
	}

	var flags openssl.DialFlags
	flags = 0
	if opts.SSLAllowInvalidCert || opts.SSLAllowInvalidHost || opts.SSLCAFile == "" {
		flags = openssl.InsecureSkipHostVerification
	}
	// create the dialer func that will be used to connect
	dialer := func(addr *mgo.ServerAddr) (net.Conn, error) {
		conn, err := openssl.Dial("tcp", addr.String(), self.ctx, flags)
		self.dialError = err
		return conn, err
	}

	timeout := time.Duration(opts.Timeout) * time.Second

	// set up the dial info
	self.dialInfo = &mgo.DialInfo{
		Addrs:          connectionAddrs,
		Timeout:        timeout,
		Direct:         opts.Direct,
		ReplicaSetName: opts.ReplicaSetName,
		DialServer:     dialer,
		Username:       opts.Auth.Username,
		Password:       opts.Auth.Password,
		Source:         opts.GetAuthenticationDatabase(),
		Mechanism:      opts.Auth.Mechanism,
	}

	return nil

}
Esempio n. 5
0
// Configure the db connector. Parses the connection string and sets up
// the dial info with the default dial timeout.
func (self *KerberosDBConnector) Configure(opts options.ToolOptions) error {

	// create the addresses to be used to connect
	connectionAddrs := util.CreateConnectionAddrs(opts.Host, opts.Port)

	// set up the dial info
	self.dialInfo = &mgo.DialInfo{
		Addrs:   connectionAddrs,
		Timeout: KERBEROS_DIAL_TIMEOUT,
		Direct:  opts.Direct,

		Username: opts.Auth.Username,
		// This should always be '$external', but legacy tools require this
		Source:      opts.Auth.Source,
		Service:     opts.Kerberos.Service,
		ServiceHost: opts.Kerberos.ServiceHost,
		Mechanism:   KERBEROS_AUTHENTICATION_MECHANISM,
	}

	return nil
}
Esempio n. 6
0
func main() {
	// initialize command-line opts
	opts := options.New(
		"mongostat",
		mongostat.Usage,
		options.EnabledOptions{Connection: true, Auth: true, Namespace: false})
	opts.UseReadOnlyHostDescription()

	// add mongostat-specific options
	statOpts := &mongostat.StatOptions{}
	opts.AddOptions(statOpts)

	interactiveOption := opts.FindOptionByLongName("interactive")
	if _, available := stat_consumer.FormatterConstructors["interactive"]; !available {
		// make --interactive inaccessible
		interactiveOption.LongName = ""
		interactiveOption.ShortName = 0
	}

	args, err := opts.Parse()
	if err != nil {
		log.Logvf(log.Always, "error parsing command line options: %v", err)
		log.Logvf(log.Always, "try 'mongostat --help' for more information")
		os.Exit(util.ExitBadOptions)
	}

	log.SetVerbosity(opts.Verbosity)
	signals.Handle()

	sleepInterval := 1
	if len(args) > 0 {
		if len(args) != 1 {
			log.Logvf(log.Always, "too many positional arguments: %v", args)
			log.Logvf(log.Always, "try 'mongostat --help' for more information")
			os.Exit(util.ExitBadOptions)
		}
		sleepInterval, err = strconv.Atoi(args[0])
		if err != nil {
			log.Logvf(log.Always, "invalid sleep interval: %v", args[0])
			os.Exit(util.ExitBadOptions)
		}
		if sleepInterval < 1 {
			log.Logvf(log.Always, "sleep interval must be at least 1 second")
			os.Exit(util.ExitBadOptions)
		}
	}

	// print help, if specified
	if opts.PrintHelp(false) {
		return
	}

	// print version, if specified
	if opts.PrintVersion() {
		return
	}

	if opts.Auth.Username != "" && opts.Auth.Source == "" && !opts.Auth.RequiresExternalDB() {
		log.Logvf(log.Always, "--authenticationDatabase is required when authenticating against a non $external database")
		os.Exit(util.ExitBadOptions)
	}

	if statOpts.Interactive && statOpts.Json {
		log.Logvf(log.Always, "cannot use output formats --json and --interactive together")
		os.Exit(util.ExitBadOptions)
	}

	if statOpts.Deprecated && !statOpts.Json {
		log.Logvf(log.Always, "--useDeprecatedJsonKeys can only be used when --json is also specified")
		os.Exit(util.ExitBadOptions)
	}

	if statOpts.Columns != "" && statOpts.AppendColumns != "" {
		log.Logvf(log.Always, "-O cannot be used if -o is also specified")
		os.Exit(util.ExitBadOptions)
	}

	if statOpts.HumanReadable != "true" && statOpts.HumanReadable != "false" {
		log.Logvf(log.Always, "--humanReadable must be set to either 'true' or 'false'")
		os.Exit(util.ExitBadOptions)
	}

	// we have to check this here, otherwise the user will be prompted
	// for a password for each discovered node
	if opts.Auth.ShouldAskForPassword() {
		opts.Auth.Password = password.Prompt()
	}

	var factory stat_consumer.FormatterConstructor
	if statOpts.Json {
		factory = stat_consumer.FormatterConstructors["json"]
	} else if statOpts.Interactive {
		factory = stat_consumer.FormatterConstructors["interactive"]
	} else {
		factory = stat_consumer.FormatterConstructors[""]
	}
	formatter := factory(statOpts.RowCount, !statOpts.NoHeaders)

	cliFlags := 0
	if statOpts.Columns == "" {
		cliFlags = line.FlagAlways
		if statOpts.Discover {
			cliFlags |= line.FlagDiscover
			cliFlags |= line.FlagHosts
		}
		if statOpts.All {
			cliFlags |= line.FlagAll
		}
		if strings.Contains(opts.Host, ",") {
			cliFlags |= line.FlagHosts
		}
	}

	var customHeaders []string
	if statOpts.Columns != "" {
		customHeaders = optionCustomHeaders(statOpts.Columns)
	} else if statOpts.AppendColumns != "" {
		customHeaders = optionCustomHeaders(statOpts.AppendColumns)
	}

	var keyNames map[string]string
	if statOpts.Deprecated {
		keyNames = line.DeprecatedKeyMap()
	} else if statOpts.Columns == "" {
		keyNames = line.DefaultKeyMap()
	} else {
		keyNames = optionKeyNames(statOpts.Columns)
	}
	if statOpts.AppendColumns != "" {
		addKN := optionKeyNames(statOpts.AppendColumns)
		for k, v := range addKN {
			keyNames[k] = v
		}
	}

	readerConfig := &status.ReaderConfig{
		HumanReadable: statOpts.HumanReadable == "true",
	}
	if statOpts.Json {
		readerConfig.TimeFormat = "15:04:05"
	}

	consumer := stat_consumer.NewStatConsumer(cliFlags, customHeaders,
		keyNames, readerConfig, formatter, os.Stdout)
	seedHosts := util.CreateConnectionAddrs(opts.Host, opts.Port)
	var cluster mongostat.ClusterMonitor
	if statOpts.Discover || len(seedHosts) > 1 {
		cluster = &mongostat.AsyncClusterMonitor{
			ReportChan:    make(chan *status.ServerStatus),
			ErrorChan:     make(chan *status.NodeError),
			LastStatLines: map[string]*line.StatLine{},
			Consumer:      consumer,
		}
	} else {
		cluster = &mongostat.SyncClusterMonitor{
			ReportChan: make(chan *status.ServerStatus),
			ErrorChan:  make(chan *status.NodeError),
			Consumer:   consumer,
		}
	}

	var discoverChan chan string
	if statOpts.Discover {
		discoverChan = make(chan string, 128)
	}

	opts.Direct = true
	_, setName := util.ParseConnectionString(opts.Host)
	opts.ReplicaSetName = setName
	stat := &mongostat.MongoStat{
		Options:       opts,
		StatOptions:   statOpts,
		Nodes:         map[string]*mongostat.NodeMonitor{},
		Discovered:    discoverChan,
		SleepInterval: time.Duration(sleepInterval) * time.Second,
		Cluster:       cluster,
	}

	for _, v := range seedHosts {
		stat.AddNewNode(v)
	}

	// kick it off
	err = stat.Run()
	if err != nil {
		log.Logvf(log.Always, "Failed: %v", err)
		os.Exit(util.ExitError)
	}
}
Esempio n. 7
0
func main() {
	go signals.Handle()
	// initialize command-line opts
	opts := options.New(
		"mongostat",
		mongostat.Usage,
		options.EnabledOptions{Connection: true, Auth: true, Namespace: false})

	// add mongostat-specific options
	statOpts := &mongostat.StatOptions{}
	opts.AddOptions(statOpts)

	args, err := opts.Parse()
	if err != nil {
		log.Logf(log.Always, "error parsing command line options: %v", err)
		log.Logf(log.Always, "try 'mongostat --help' for more information")
		os.Exit(util.ExitBadOptions)
	}

	log.SetVerbosity(opts.Verbosity)

	sleepInterval := 1
	if len(args) > 0 {
		if len(args) != 1 {
			log.Logf(log.Always, "too many positional arguments: %v", args)
			log.Logf(log.Always, "try 'mongostat --help' for more information")
			os.Exit(util.ExitBadOptions)
		}
		sleepInterval, err = strconv.Atoi(args[0])
		if err != nil {
			log.Logf(log.Always, "invalid sleep interval: %v", args[0])
			os.Exit(util.ExitBadOptions)
		}
		if sleepInterval < 1 {
			log.Logf(log.Always, "sleep interval must be at least 1 second")
			os.Exit(util.ExitBadOptions)
		}
	}

	// print help, if specified
	if opts.PrintHelp(false) {
		return
	}

	// print version, if specified
	if opts.PrintVersion() {
		return
	}

	if opts.Auth.Username != "" && opts.Auth.Source == "" && !opts.Auth.RequiresExternalDB() {
		log.Logf(log.Always, "--authenticationDatabase is required when authenticating against a non $external database")
		os.Exit(util.ExitBadOptions)
	}

	// we have to check this here, otherwise the user will be prompted
	// for a password for each discovered node
	if opts.Auth.ShouldAskForPassword() {
		opts.Auth.Password = password.Prompt()
	}

	var formatter mongostat.LineFormatter
	if statOpts.Json {
		formatter = &mongostat.JSONLineFormatter{}
	} else {
		formatter = &mongostat.GridLineFormatter{
			IncludeHeader:  !statOpts.NoHeaders,
			HeaderInterval: 10,
			Writer:         &text.GridWriter{ColumnPadding: 1},
		}
	}

	seedHosts := util.CreateConnectionAddrs(opts.Host, opts.Port)
	var cluster mongostat.ClusterMonitor
	if statOpts.Discover || len(seedHosts) > 1 {
		cluster = &mongostat.AsyncClusterMonitor{
			ReportChan:    make(chan mongostat.StatLine),
			LastStatLines: map[string]*mongostat.StatLine{},
			Formatter:     formatter,
		}
	} else {
		cluster = &mongostat.SyncClusterMonitor{
			ReportChan: make(chan mongostat.StatLine),
			Formatter:  formatter,
		}
	}

	var discoverChan chan string
	if statOpts.Discover {
		discoverChan = make(chan string, 128)
	}

	opts.Direct = true
	_, setName := util.ParseConnectionString(opts.Host)
	opts.ReplicaSetName = setName
	stat := &mongostat.MongoStat{
		Options:       opts,
		StatOptions:   statOpts,
		Nodes:         map[string]*mongostat.NodeMonitor{},
		Discovered:    discoverChan,
		SleepInterval: time.Duration(sleepInterval) * time.Second,
		Cluster:       cluster,
	}

	for _, v := range seedHosts {
		stat.AddNewNode(v)
	}

	// kick it off
	err = stat.Run()
	if err != nil {
		log.Logf(log.Always, "Failed: %v", err)
		os.Exit(util.ExitError)
	}
}