Skip to content

Commit

Permalink
restore validators and admin commands
Browse files Browse the repository at this point in the history
  • Loading branch information
jchappelow committed Dec 11, 2024
1 parent 58b3dc4 commit 8548a20
Show file tree
Hide file tree
Showing 31 changed files with 369 additions and 159 deletions.
25 changes: 0 additions & 25 deletions _previous/cmd/kwil-admin/cmds/node/cmd.go

This file was deleted.

2 changes: 1 addition & 1 deletion app/node/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func buildServer(ctx context.Context, d *coreDependencies) *server {
// key because it is used to sign transactions and provide an Identity for
// account information (nonce and balance).
txSigner := &auth.EthPersonalSigner{Key: *d.privKey.(*crypto.Secp256k1PrivateKey)}
jsonAdminSvc := adminsvc.NewService(db, node, bp, nil, txSigner, d.cfg,
jsonAdminSvc := adminsvc.NewService(db, node, bp, vs, nil, txSigner, d.cfg,
d.genesisCfg.ChainID, adminServerLogger)
jsonRPCAdminServer = buildJRPCAdminServer(d)
jsonRPCAdminServer.RegisterSvc(jsonAdminSvc)
Expand Down
5 changes: 4 additions & 1 deletion app/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import (
"github.com/kwilteam/kwil-db/app/key"
"github.com/kwilteam/kwil-db/app/node"
"github.com/kwilteam/kwil-db/app/node/conf"
"github.com/kwilteam/kwil-db/app/rpc"
"github.com/kwilteam/kwil-db/app/setup"
"github.com/kwilteam/kwil-db/app/shared/bind"
"github.com/kwilteam/kwil-db/app/validator"
"github.com/kwilteam/kwil-db/version"

"github.com/spf13/cobra"
Expand Down Expand Up @@ -53,7 +55,8 @@ func RootCmd() *cobra.Command {
// There is a virtual "node" command grouping, but no actual "node" command yet.
cmd.AddCommand(node.StartCmd())
cmd.AddCommand(node.PrintConfigCmd())

cmd.AddCommand(rpc.NewAdminCmd())
cmd.AddCommand(validator.NewValidatorsCmd())
cmd.AddCommand(setup.SetupCmd())
cmd.AddCommand(key.KeyCmd())

Expand Down
163 changes: 163 additions & 0 deletions app/rpc/admin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package rpc

import (
"context"
"errors"
"fmt"
"os"
"path/filepath"

adminclient "github.com/kwilteam/kwil-db/node/admin"
"github.com/spf13/cobra"
)

const (
kwildRootTODO = "~/.kwild"
adminCertName = "admin.cert"
)

// BindRPCFlags binds the RPC flags to the given command.
// This includes an rpcserver flag, and the TLS flags.
// These flags can be used to create an admin service client.
// The flags will be bound to all subcommands of the given command.
func BindRPCFlags(cmd *cobra.Command) {
cmd.PersistentFlags().StringP("rpcserver", "s", "/tmp/kwild.socket", "admin RPC server address (either unix or tcp)")

cmd.PersistentFlags().String("authrpc-cert", "", "kwild's TLS certificate, required for HTTPS server")
cmd.PersistentFlags().String("pass", "", "admin server password (alternative to mTLS with tlskey/tlscert). May be set in ~/.kwil-admin/rpc-admin-pass instead.")
cmd.PersistentFlags().String("tlskey", "auth.key", "kwil-admin's TLS key file to establish a mTLS (authenticated) connection")
cmd.PersistentFlags().String("tlscert", "auth.cert", "kwil-admin's TLS certificate file for server to authenticate us")
}

// GetRPCServerFlag returns the RPC flag from the given command.
func GetRPCServerFlag(cmd *cobra.Command) (string, error) {
return cmd.Flags().GetString("rpcserver")
}

// AdminSvcClient will return an admin service client based on the flags.
// The flags should be bound using the BindRPCFlags function.
func AdminSvcClient(ctx context.Context, cmd *cobra.Command) (*adminclient.AdminClient, error) {
adminOpts := []adminclient.Opt{}

rpcServer, err := GetRPCServerFlag(cmd)
if err != nil {
return nil, err
}

// get the tls files
// if one is specified, all must be specified
// if none are specified, then we do not use tls
if cmd.Flags().Changed("authrpc-cert") || cmd.Flags().Changed("tlskey") || cmd.Flags().Changed("tlscert") {
kwildTLSCertFile, clientTLSKeyFile, clientTLSCertFile, err := getTLSFlags(cmd)
if err != nil {
return nil, err
}

adminOpts = append(adminOpts, adminclient.WithTLS(kwildTLSCertFile, clientTLSKeyFile, clientTLSCertFile))
}

if pass, err := cmd.Flags().GetString("pass"); err != nil {
return nil, err
} else if pass != "" {
adminOpts = append(adminOpts, adminclient.WithPass(pass))
}

return adminclient.NewClient(ctx, rpcServer, adminOpts...)
}

// getTLSFlags returns the TLS flags from the given command.
func getTLSFlags(cmd *cobra.Command) (kwildTLSCertFile, clientTLSKeyFile, clientTLSCertFile string, err error) {
kwildTLSCertFile, err = cmd.Flags().GetString("authrpc-cert")
if err != nil {
return "", "", "", err
}

clientTLSKeyFile, err = cmd.Flags().GetString("tlskey")
if err != nil {
return "", "", "", err
}

clientTLSCertFile, err = cmd.Flags().GetString("tlscert")
if err != nil {
return "", "", "", err
}

cert := nodeCert{
KwildTLSCertFile: kwildTLSCertFile,
ClientTLSKeyFile: clientTLSKeyFile,
ClientTLSCertFile: clientTLSCertFile,
}

return cert.tlsFiles()
}

// nodeCert is the struct that holds the TLS certificate and key files for
// kwil-admin to use when connecting to the remote node.
type nodeCert struct {
KwildTLSCertFile string
ClientTLSKeyFile string // default: auth.key
ClientTLSCertFile string // default: auth.cert
}

// tlsFiles loads the remote nodes TLS certificate, which the client uses to
// authenticate the server during the connection handshake, and our TLS key
// pair, which allows the server to authenticate the client. The server's TLS
// certificate would be obtained from the node machine and specified with the
// --authrpc-cert flag, this will search for it in known paths. The client key
// pair (ours) should first be generated with the `node gen-auth-key` command.
func (nc *nodeCert) tlsFiles() (nodeCert, ourKey, ourCert string, err error) {
// Look for kwild's TLS certificate in:
// 1. any path provided via --authrpc-cert
// 2. ~/.kwil-admin/kwild.cert
// 3. ~/.kwild/rpc.cert
nodeCert = nc.KwildTLSCertFile
if nodeCert != "" { // --authrpc-cert
nodeCert = fullPath(nodeCert)
} else { // search the two fallback paths
nodeCert = filepath.Join(kwildRootTODO, adminCertName)
}
if nodeCert == "" || !fileExists(nodeCert) {
err = fmt.Errorf("kwild cert file not found, checked %v", nodeCert)
return
}
ourKey, ourCert = fullPath(nc.ClientTLSKeyFile), fullPath(nc.ClientTLSCertFile)
if ourKey == "" || ourCert == "" {
err = errors.New("our TLS key/cert not found")
return // leave the existence check until we load the files
}

return
}

// fullPath gets the full path to a file, searching in the following order:
// 1. the path itself, if it is absolute
// 2. the current directory
// 3. ~/.kwild
func fullPath(path string) string {
// If an absolute path is specified, do nothing.
if filepath.IsAbs(path) {
return path
}

// First check relative to the current directory.
fullPath, err := filepath.Abs(path)
if err != nil {
return ""
}
if fileExists(fullPath) {
return fullPath
}

// Check for the file name in root dir
fullPath = filepath.Join(kwildRootTODO, path)
if fileExists(fullPath) {
return fullPath
}

return ""
}

func fileExists(path string) bool {
_, err := os.Stat(path)
return err == nil
}
30 changes: 30 additions & 0 deletions app/rpc/cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package rpc

import (
"github.com/spf13/cobra"

"github.com/kwilteam/kwil-db/app/shared/display"
)

const adminExplain = "The `admin` command is used to get information about a running Kwil node."

func NewAdminCmd() *cobra.Command {
adminCmd := &cobra.Command{
Use: "admin",
Short: "commands for admin RPCs",
Long: adminExplain,
}

adminCmd.AddCommand(
dumpCfgCmd(),
versionCmd(),
statusCmd(),
peersCmd(),
genAuthKeyCmd(),
)

BindRPCFlags(adminCmd)
display.BindOutputFormatFlag(adminCmd)

return adminCmd
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package node
package rpc

import (
"context"
"encoding/json"

"github.com/kwilteam/kwil-db/cmd/common/display"
"github.com/kwilteam/kwil-db/cmd/kwil-admin/cmds/common"
"github.com/pelletier/go-toml/v2"
"github.com/kwilteam/kwil-db/app/shared/display"
"github.com/kwilteam/kwil-db/config"

"github.com/spf13/cobra"
)

Expand All @@ -25,7 +25,7 @@ func dumpCfgCmd() *cobra.Command {
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, _ []string) error {
ctx := context.Background()
client, err := common.GetAdminSvcClient(ctx, cmd)
client, err := AdminSvcClient(ctx, cmd)
if err != nil {
return display.PrintErr(cmd, err)
}
Expand All @@ -35,31 +35,38 @@ func dumpCfgCmd() *cobra.Command {
return display.PrintErr(cmd, err)
}

cfg := make(map[string]interface{})
err = json.Unmarshal(bts, &cfg)
var cfg config.Config
err = cfg.FromTOML(bts)
if err != nil {
return display.PrintErr(cmd, err)
}

return display.PrintCmd(cmd, &cfgMsg{cfg: cfg})
return display.PrintCmd(cmd, &cfgMsg{toml: bts, cfg: &cfg})
},
}

common.BindRPCFlags(cmd)
BindRPCFlags(cmd)

return cmd
}

type cfgMsg struct {
cfg map[string]interface{}
toml []byte
cfg *config.Config
}

var _ display.MsgFormatter = (*cfgMsg)(nil)

func (c *cfgMsg) MarshalJSON() ([]byte, error) {
return json.Marshal(c.cfg)
return json.Marshal(struct {
OK bool `json:"ok"`
TOML string `json:"toml"`
}{
OK: true,
TOML: string(c.toml),
})
}

func (c *cfgMsg) MarshalText() ([]byte, error) {
return toml.Marshal(c.cfg)
return c.cfg.ToTOML()
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package node
package rpc

import (
"fmt"
"os"
"path/filepath"

"github.com/kwilteam/kwil-db/cmd/common/display"
"github.com/kwilteam/kwil-db/cmd/kwil-admin/cmds/common"
"github.com/kwilteam/kwil-db/app/shared/bind"
"github.com/kwilteam/kwil-db/app/shared/display"
"github.com/kwilteam/kwil-db/core/rpc/transport"
"github.com/spf13/cobra"
)
Expand All @@ -31,7 +31,7 @@ func genAuthKeyCmd() *cobra.Command {
Example: genAuthKeyExample,
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, _ []string) error {
rootDir := common.DefaultKwilAdminRoot()
rootDir, _ := bind.RootDir(cmd)

if !filepath.IsAbs(keyFile) {
keyFile = filepath.Join(rootDir, keyFile)
Expand Down Expand Up @@ -63,8 +63,3 @@ func genAuthKeyCmd() *cobra.Command {

return cmd
}

func fileExists(path string) bool {
_, err := os.Stat(path)
return !os.IsNotExist(err)
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package node
package rpc

import (
"context"
"encoding/json"

"github.com/kwilteam/kwil-db/cmd/common/display"
"github.com/kwilteam/kwil-db/cmd/kwil-admin/cmds/common"
"github.com/kwilteam/kwil-db/app/shared/display"
types "github.com/kwilteam/kwil-db/core/types/admin"
"github.com/spf13/cobra"
)
Expand All @@ -26,7 +25,7 @@ func peersCmd() *cobra.Command {
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, _ []string) error {
ctx := context.Background()
client, err := common.GetAdminSvcClient(ctx, cmd)
client, err := AdminSvcClient(ctx, cmd)
if err != nil {
return display.PrintErr(cmd, err)
}
Expand All @@ -40,7 +39,7 @@ func peersCmd() *cobra.Command {
},
}

common.BindRPCFlags(cmd)
BindRPCFlags(cmd)

return cmd
}
Expand Down
Loading

0 comments on commit 8548a20

Please sign in to comment.