commands

package
v0.0.0-...-49e565d Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 3, 2015 License: Apache-2.0 Imports: 23 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	KeyBits      int
	Years        int
	Organization string
	Country      string
	Hosts        string
)

Command line args

View Source
var (
	Name           string
	ForceOverwrite bool
)

Command line args

View Source
var (
	SSHKey              string
	AdminCert           string
	CACert              string
	TLSCert             string
	TLSKey              string
	DataPath            string
	SSHListen           string
	HTTPListen          string
	NodeName            string
	ClusterName         string
	ClusterNodes        string
	Bootstrap           bool
	BootstrapExpect     int
	GossipBindAddr      string
	GossipBindPort      int
	GossipAdvertiseAddr string
	GossipAdvertisePort int
)

Command line args

View Source
var ClientCmd = &cobra.Command{
	Use:   "client [ssh://username@host:port]",
	Short: "client starts a terminal with the given kappa server",
	Long:  ``,
	Run: func(cmd *cobra.Command, args []string) {

		writer := log.NewConcurrentWriter(os.Stdout)
		logger := log.NewLogger(writer, "cli")

		err := InitializeClientConfig(logger)
		if err != nil {
			return
		}

		keyFile := viper.GetString("ClientKey")

		keyBytes, err := ioutil.ReadFile(keyFile)
		if err != nil {
			fmt.Println("Private key could not be read:", err.Error())
			fmt.Println(cmd.Help())
			return
		}

		privateKey, err := ssh.ParsePrivateKey(keyBytes)
		if err != nil {
			fmt.Println("Private key is invalid:", err.Error())
			fmt.Println(cmd.Help())
			return
		}

		if len(args) < 1 {
			fmt.Println("Missing server URL")
			fmt.Println(cmd.Help())
			return
		}

		u, err := url.Parse(args[0])
		if err != nil {
			fmt.Println("Error parsing host - expected format ssh://username@host:port : ", err.Error())
			fmt.Println(cmd.Help())
			return
		} else if u.User == nil {
			fmt.Println("Missing username - expected format: ssh://username@host:port")
			fmt.Println(cmd.Help())
			return
		} else if u.User.Username() == "" {
			fmt.Println("Missing username - expected format: ssh://username@host:port")
			fmt.Println(cmd.Help())
			return
		}

		config := &ssh.ClientConfig{
			User: u.User.Username(),
			Auth: []ssh.AuthMethod{
				ssh.PublicKeys(privateKey),
			},
		}

		client, err := ssh.Dial("tcp", u.Host, config)
		if err != nil {
			fmt.Println(err.Error())
			return
		}
		defer client.Close()

		channel, requests, err := client.OpenChannel("kappa-client", []byte{})
		go ssh.DiscardRequests(requests)

		// Read history
		var entries []string
		usr, err := user.Current()
		historyPath := path.Join(usr.HomeDir, ".kappa_history")
		historyBytes, err := ioutil.ReadFile(historyPath)
		if err == nil {
			tmpEntries := strings.Split(string(historyBytes), "\n")
			for _, e := range tmpEntries {
				if len(e) > 0 {
					entries = append(entries, e)
				}
			}
		}

		history := History{entries, make([]string, 0)}

		term := terminal.NewTerminal(os.Stdin, string(common.DefaultColorCodes.LightBlue)+"kappa > "+string(common.DefaultColorCodes.Reset))
		term.LoadInitialHistory(entries)

		oldState, err := terminal.MakeRaw(0)
		if err != nil {
			logger.Warn("Error making terminal raw: ", err.Error())
		}
		defer terminal.Restore(0, oldState)

		term.Write([]byte("\r\n"))
		for _, line := range common.ASCII {
			term.Write([]byte(line))
			term.Write([]byte("\r\n"))
		}

		term.Write([]byte("\r\n\n"))
		cli.GetMessage(term, common.DefaultColorCodes)
		term.Write([]byte("\n"))

		for {
			input, err := term.ReadLine()

			if err != nil {
				break
			}

			line := strings.TrimSpace(string(input))
			if len(line) > 0 {

				if line == "exit" || line == "quit" {
					break
				} else if line == "history" {
					for _, e := range history.oldEntries {
						term.Write([]byte(" " + e + "\r\n"))
					}
					for _, e := range history.newEntries {
						term.Write([]byte(" " + e + "\r\n"))
					}
					continue
				} else if strings.HasPrefix(line, "//") || strings.HasPrefix(line, "--") {

					term.Write(common.DefaultColorCodes.LightGrey)
					term.Write([]byte(line + "\r\n"))
					term.Write(common.DefaultColorCodes.Reset)
					continue
				}

				stmt, err := skl.ParseStatement(line)

				if err != nil {
					term.Write(common.DefaultColorCodes.LightRed)
					term.Write([]byte(" " + err.Error()))
					term.Write([]byte("\r\n"))
					term.Write(common.DefaultColorCodes.Reset)
					term.RemoveLastLine()
					continue
				}

				w := common.ResponseWriter{common.DefaultColorCodes, term}

				length := make([]byte, 4)
				xbinary.LittleEndian.PutInt32(length, 0, int32(len(line)))

				channel.Write(length)
				channel.Write([]byte(line))

				channel.Read(length)

				size, err := xbinary.LittleEndian.Int32(length, 0)
				data := make([]byte, int(size))
				channel.Read(data)

				w.Success(common.OK, stmt.String())

				history.Append(line + "\n")
			}
		}

		history.WriteToFile(historyPath)
		os.Stdout.Write(common.DefaultColorCodes.LightGreen)
		os.Stdout.Write([]byte("\r\n"))
		os.Stdout.Write([]byte(" Yo homes, smell you later!"))
		os.Stdout.Write([]byte("\r\n"))
		os.Stdout.Write(common.DefaultColorCodes.Reset)
	},
}

ClientCmd is the CLI command

View Source
var (
	ClientKey string
)

Command line args

View Source
var (
	ConfigPath string
)

Command line args

View Source
var InitCACmd = &cobra.Command{
	Use:   "init-ca",
	Short: "init-ca creates a new certificate authority",
	Long:  ``,
	Run: func(cmd *cobra.Command, args []string) {

		writer := log.NewConcurrentWriter(os.Stdout)
		logger := log.NewLogger(writer, "init-ca")

		err := InitializeConfig(writer)
		if err != nil {
			return
		}

		if err := auth.CreatePkiDirectories(logger, "."); err != nil {
			return
		}

		pki := path.Join(".", "pki")
		crtFile := path.Join(pki, "ca.crt")
		privFile := path.Join(pki, "private", "ca.key")

		if !viper.GetBool("ForceOverwrite") {
			var files []string
			for _, filename := range []string{privFile, crtFile} {
				if _, err := os.Stat(filename); err == nil {
					files = append(files, filename)
				}
			}

			if len(files) > 0 {
				var input string
				fmt.Println("This operation will overwrite these existing files:")
				for _, file := range files {
					fmt.Println("\t", file)
				}
				fmt.Print("Are you sure you want to overwrite these files (yN)? ")
				fmt.Scanln(&input)

				if !strings.Contains(strings.ToLower(input), "y") {
					fmt.Println("New certificate was not created.")
					return
				}
			}
		}

		privatekey, err := rsa.GenerateKey(rand.Reader, viper.GetInt("Bits"))
		if err != nil {
			logger.Warn("Error generating private key")
			return
		}

		cert, err := auth.CreateCertificateAuthority(logger, privatekey,
			viper.GetInt("Years"), viper.GetString("Organization"),
			viper.GetString("Country"), viper.GetString("Hosts"))
		if err != nil {
			logger.Warn("Error creating CA", "err", err.Error())
			return
		}

		auth.SaveCertificate(logger, cert, crtFile)

		auth.SavePrivateKey(logger, privatekey, privFile)

	},
}

InitCACmd is the kappa root command.

View Source
var KappaCmd = &cobra.Command{
	Use:   "kappa",
	Short: "Kappa is a NoSQL database centered around replicated logs and views.",
	Long:  ``,
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println(cmd.Help())
	},
}

KappaCmd is the root root command.

View Source
var NewCertCmd = &cobra.Command{
	Use:   "new-cert",
	Short: "new-cert creates a new certificate",
	Long:  ``,
	Run: func(cmd *cobra.Command, args []string) {

		writer := log.NewConcurrentWriter(os.Stdout)
		logger := log.NewLogger(writer, "new-cert")

		err := InitializeConfig(writer)
		if err != nil {
			return
		}

		if err := auth.CreatePkiDirectories(logger, "."); err != nil {
			return
		}

		pki := path.Join(".", "pki")
		reqFile := path.Join(pki, "reqs", viper.GetString("Name")+".req")
		privFile := path.Join(pki, "private", viper.GetString("Name")+".key")
		crtFile := path.Join(pki, "public", viper.GetString("Name")+".crt")

		if !viper.GetBool("ForceOverwrite") {
			var files []string
			for _, filename := range []string{reqFile, privFile, crtFile} {
				if _, err := os.Stat(filename); err == nil {
					files = append(files, filename)
				}
			}

			if len(files) > 0 {
				var input string
				fmt.Println("This operation will overwrite these existing files:")
				for _, file := range files {
					fmt.Println("\t", file)
				}
				fmt.Print("Are you sure you want to overwrite these files (yN)? ")
				fmt.Scanln(&input)

				if !strings.Contains(strings.ToLower(input), "y") {
					fmt.Println("New certificate was not created.")
					return
				}
			}
		}

		privatekey, err := rsa.GenerateKey(rand.Reader, viper.GetInt("Bits"))
		if err != nil {
			logger.Warn("Error generating private key")
			return
		}

		csr, req, err := auth.CreateCertificateRequest(logger, privatekey,
			viper.GetString("Name"), viper.GetString("Organization"),
			viper.GetString("Country"), viper.GetString("Hosts"))
		if err != nil {
			logger.Warn("Error creating CA", "err", err.Error())
			return
		}

		crt, err := auth.CreateCertificate(logger, csr, privatekey,
			viper.GetInt("Years"), viper.GetString("Hosts"))
		if err != nil {
			logger.Warn("Error creating certificate", "err", err.Error())
			return
		}

		auth.SaveCertificateRequest(logger, req, reqFile)

		auth.SavePrivateKey(logger, privatekey, privFile)

		auth.SaveCertificate(logger, crt, crtFile)
	},
}

NewCertCmd is the kappa root command.

View Source
var ServerCmd = &cobra.Command{
	Use:   "server",
	Short: "server starts the database server",
	Long:  ``,
	Run: func(cmd *cobra.Command, args []string) {

		writer := log.NewConcurrentWriter(os.Stderr)
		logger := log.NewLogger(writer, "kappa")

		err := InitializeConfig(writer)
		if err != nil {
			return
		}

		cfg := server.DatabaseConfig{
			LogOutput:             writer,
			NodeName:              viper.GetString("NodeName"),
			ClusterName:           viper.GetString("ClusterName"),
			ExistingNodes:         strings.Split(viper.GetString("ClusterNodes"), ","),
			Bootstrap:             viper.GetBool("Bootstrap"),
			BootstrapExpect:       viper.GetInt("BootstrapExpect"),
			AdminCertificateFile:  viper.GetString("AdminCert"),
			CACertificateFile:     viper.GetString("CACert"),
			DataPath:              viper.GetString("DataPath"),
			SSHBindAddress:        viper.GetString("SSHListen"),
			SSHPrivateKeyFile:     viper.GetString("SSHKey"),
			SSHConnectionDeadline: time.Second,
			GossipBindAddr:        viper.GetString("GossipBindAddr"),
			GossipBindPort:        viper.GetInt("GossipBindPort"),
			GossipAdvertiseAddr:   viper.GetString("GossipAdvertiseAddr"),
			GossipAdvertisePort:   viper.GetInt("GossipAdvertisePort"),
		}

		svr, err := server.NewServer(&cfg)
		if err != nil {
			logger.Error("Failed to start server:", "error", err)
			return
		}

		if err := svr.Start(); err != nil {
			svr.Stop()
			return
		}

		sig := make(chan os.Signal, 1)
		signal.Notify(sig, os.Interrupt, os.Kill)

		logger.Info("Ready to serve requests")

		<-sig

		signal.Stop(sig)
		close(sig)

		logger.Info("Shutting down servers.")

		svr.Stop()
	},
}

ServerCmd is the kappa root command.

Functions

func AddCommands

func AddCommands()

AddCommands add all of the subcommands to the main entry point.

func Execute

func Execute()

Execute is the main entry point into the server.

func InitializeCertAuthConfig

func InitializeCertAuthConfig(logger log.Logger) error

InitializeCertAuthConfig sets up the command line options for creating a CA

func InitializeClientConfig

func InitializeClientConfig(logger log.Logger) error

InitializeClientConfig sets up the config options for the database servers.

func InitializeConfig

func InitializeConfig(writer io.Writer) error

InitializeConfig reads the configuration file and sets up the application settings via Viper.

func InitializeMainConfig

func InitializeMainConfig(logger log.Logger) error

InitializeMainConfig sets up the config options for the kappa command

func InitializeNewCertConfig

func InitializeNewCertConfig(logger log.Logger) error

InitializeNewCertConfig sets up the command line options for creating a new certificate

func InitializeServerConfig

func InitializeServerConfig(logger log.Logger) error

InitializeServerConfig sets up the config options for the database servers.

Types

type History

type History struct {
	// contains filtered or unexported fields
}

func (*History) Append

func (h *History) Append(line string)

func (*History) WriteToFile

func (h *History) WriteToFile(filepath string) error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL