From d8cbcc4e5c84ed6e0b7356c9d045e1ba094a58c8 Mon Sep 17 00:00:00 2001 From: Brennan Lamey <66885902+brennanjl@users.noreply.github.com> Date: Thu, 30 Nov 2023 11:20:48 -0600 Subject: [PATCH] added url parsing util since stdlib is very finnicky when managing grpc, http, and unix --- cmd/internal/display/format.go | 3 +- cmd/kwil-admin/cmds/common/rpc.go | 9 +- cmd/kwil-admin/cmds/validators/join-status.go | 4 +- cmd/kwil-admin/cmds/validators/list.go | 5 +- cmd/kwild/server/build.go | 28 ++--- core/adminclient/client.go | 13 +- core/client/client.go | 5 - core/rpc/client/admin/grpc/client.go | 19 +-- core/rpc/client/error.go | 28 ++++- core/utils/url/errors.go | 7 ++ core/utils/url/url.go | 119 ++++++++++++++++++ core/utils/url/url_test.go | 79 ++++++++++++ internal/_admin/admin.go | 74 ----------- internal/_admin/opts.go | 20 --- internal/_admin/tls.go | 26 ---- internal/services/grpc/admin/v0/service.go | 3 +- test/driver/client_driver.go | 12 +- 17 files changed, 281 insertions(+), 173 deletions(-) create mode 100644 core/utils/url/errors.go create mode 100644 core/utils/url/url.go create mode 100644 core/utils/url/url_test.go delete mode 100644 internal/_admin/admin.go delete mode 100644 internal/_admin/opts.go delete mode 100644 internal/_admin/tls.go diff --git a/cmd/internal/display/format.go b/cmd/internal/display/format.go index 5856dfd4c..a0fee10df 100644 --- a/cmd/internal/display/format.go +++ b/cmd/internal/display/format.go @@ -21,8 +21,9 @@ func BindOutputFormatFlag(cmd *cobra.Command) { // BindSilenceFlag binds the silence flag to the passed command. // If bound, the command will silence logs. // If true, display commands will not print to stdout or stderr. +// The flag will be bound to all subcommands of the given command. func BindSilenceFlag(cmd *cobra.Command) { - cmd.Flags().BoolP("silence", "S", false, "Silence logs") + cmd.PersistentFlags().BoolP("silence", "S", false, "Silence logs") } // ShouldSilence returns the value of the silence flag diff --git a/cmd/kwil-admin/cmds/common/rpc.go b/cmd/kwil-admin/cmds/common/rpc.go index 6b1680ade..47c5b7fca 100644 --- a/cmd/kwil-admin/cmds/common/rpc.go +++ b/cmd/kwil-admin/cmds/common/rpc.go @@ -15,12 +15,13 @@ import ( // 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.Flags().StringP("rpcserver", "s", "127.0.0.1:50151", "admin RPC server address (either unix or tcp) [default: unix:///tmp/kwil_admin.sock]") + cmd.PersistentFlags().StringP("rpcserver", "s", "unix:///tmp/kwil_admin.sock", "admin RPC server address (either unix or tcp) [default: unix:///tmp/kwil_admin.sock]") - cmd.Flags().String("authrpc-cert", "", "kwild's TLS certificate") - cmd.Flags().String("tlskey", "auth.key", "kwil-admin's TLS key file to establish a mTLS (authenticated) connection [default: auth.key]") - cmd.Flags().String("tlscert", "auth.cert", "kwil-admin's TLS certificate file for server to authenticate us [default: auth.cert]") + cmd.PersistentFlags().String("authrpc-cert", "", "kwild's TLS certificate") + cmd.PersistentFlags().String("tlskey", "auth.key", "kwil-admin's TLS key file to establish a mTLS (authenticated) connection [default: auth.key]") + cmd.PersistentFlags().String("tlscert", "auth.cert", "kwil-admin's TLS certificate file for server to authenticate us [default: auth.cert]") } // GetRPCServerFlag returns the RPC flag from the given command. diff --git a/cmd/kwil-admin/cmds/validators/join-status.go b/cmd/kwil-admin/cmds/validators/join-status.go index 58c70c977..9e6f432a4 100644 --- a/cmd/kwil-admin/cmds/validators/join-status.go +++ b/cmd/kwil-admin/cmds/validators/join-status.go @@ -10,7 +10,7 @@ import ( "github.com/kwilteam/kwil-db/cmd/internal/display" "github.com/kwilteam/kwil-db/cmd/kwil-admin/cmds/common" - "github.com/kwilteam/kwil-db/core/client" + "github.com/kwilteam/kwil-db/core/rpc/client" "github.com/kwilteam/kwil-db/internal/validators" "github.com/spf13/cobra" ) @@ -44,7 +44,7 @@ func joinStatusCmd() *cobra.Command { data, err := clt.JoinStatus(ctx, pubkeyBts) if err != nil { if errors.Is(err, client.ErrNotFound) { - return errors.New("no active join request for that validator") + return display.PrintErr(cmd, errors.New("no active join request for that validator")) } return err } diff --git a/cmd/kwil-admin/cmds/validators/list.go b/cmd/kwil-admin/cmds/validators/list.go index d0aa334cf..ee3b44f3f 100644 --- a/cmd/kwil-admin/cmds/validators/list.go +++ b/cmd/kwil-admin/cmds/validators/list.go @@ -72,7 +72,10 @@ func (r *respValSets) MarshalText() ([]byte, error) { var msg bytes.Buffer msg.WriteString("Current validator set:\n") for i, v := range r.Data { - msg.WriteString(fmt.Sprintf("% 3d. %s\n", i, v)) + msg.WriteString(fmt.Sprintf("% 3d. %s", i, v)) + if i != len(r.Data)-1 { + msg.WriteString("\n") + } } return msg.Bytes(), nil diff --git a/cmd/kwild/server/build.go b/cmd/kwild/server/build.go index ff82b4d59..c15656c06 100644 --- a/cmd/kwild/server/build.go +++ b/cmd/kwild/server/build.go @@ -7,10 +7,8 @@ import ( "errors" "fmt" "net" - "net/url" "os" "path/filepath" - "strings" "syscall" "time" @@ -46,6 +44,7 @@ import ( functionpb "github.com/kwilteam/kwil-db/core/rpc/protobuf/function/v0" txpb "github.com/kwilteam/kwil-db/core/rpc/protobuf/tx/v1" "github.com/kwilteam/kwil-db/core/rpc/transport" + "github.com/kwilteam/kwil-db/core/utils/url" abciTypes "github.com/cometbft/cometbft/abci/types" cmtEd "github.com/cometbft/cometbft/crypto/ed25519" @@ -417,25 +416,18 @@ func buildHealthSvc(d *coreDependencies) *healthsvc.Server { } func buildAdminService(d *coreDependencies, closer *closeFuncs, admsvc admpb.AdminServiceServer, txsvc txpb.TxServiceServer) *kwilgrpc.Server { - addr := d.cfg.AppCfg.AdminListenAddress - // if listen address does not have unix:// or tcp:// prefix, assume tcp:// - if !strings.HasPrefix(d.cfg.AppCfg.AdminListenAddress, "unix://") && !strings.HasPrefix(d.cfg.AppCfg.AdminListenAddress, "tcp://") { - addr = "tcp://" + addr - } - - // parse AdminListenAddress to see if it is tcp or unix - u, err := url.Parse(addr) + u, err := url.ParseURL(d.cfg.AppCfg.AdminListenAddress) if err != nil { - failBuild(err, "failed to build grpc server") + failBuild(err, "failed to build admin service") } switch u.Scheme { default: - failBuild(err, "unknown admin service protocol "+u.Scheme) - case "tcp": + failBuild(err, "unknown admin service protocol "+u.Scheme.String()) + case url.TCP: // if tcp, we need to set up TLS - lis, err := net.Listen("tcp", ":"+u.Port()) + lis, err := net.Listen("tcp", fmt.Sprintf(":%d", u.Port)) if err != nil { failBuild(err, "failed to build grpc server") } @@ -487,9 +479,9 @@ func buildAdminService(d *coreDependencies, closer *closeFuncs, admsvc admpb.Adm grpc_health_v1.RegisterHealthServer(grpcServer, buildHealthSvc(d)) return grpcServer - case "unix": + case url.UNIX: // if unix, we need to set up unix socket - err = os.MkdirAll(filepath.Dir(u.Path), 0755) // ensure parent dir exists + err = os.MkdirAll(filepath.Dir(u.Target), 0755) // ensure parent dir exists if err != nil { failBuild(err, "failed to build grpc server") } @@ -499,11 +491,11 @@ func buildAdminService(d *coreDependencies, closer *closeFuncs, admsvc admpb.Adm // suggested approach here (not sure about this for obvious reasons): // https://gist.github.com/hakobe/6f70d69b8c5243117787fd488ae7fbf2 - err = syscall.Unlink(u.Path) + err = syscall.Unlink(u.Target) if err != nil && !os.IsNotExist(err) { failBuild(err, "failed to build grpc server") } - lis, err := net.Listen("unix", u.Path) + lis, err := net.Listen("unix", u.Target) if err != nil { failBuild(err, "failed to build grpc server") } diff --git a/core/adminclient/client.go b/core/adminclient/client.go index a0c529237..4049451b5 100644 --- a/core/adminclient/client.go +++ b/core/adminclient/client.go @@ -6,8 +6,8 @@ package adminclient import ( "context" "crypto/tls" + "fmt" "net" - "net/url" "github.com/kwilteam/kwil-db/core/log" admingrpc "github.com/kwilteam/kwil-db/core/rpc/client/admin/grpc" @@ -15,6 +15,7 @@ import ( "github.com/kwilteam/kwil-db/core/rpc/transport" "github.com/kwilteam/kwil-db/core/types" adminTypes "github.com/kwilteam/kwil-db/core/types/admin" + "github.com/kwilteam/kwil-db/core/utils/url" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/insecure" @@ -82,7 +83,7 @@ func New(ctx context.Context, target string, opts ...AdminClientOpt) (*AdminClie log: log.NewNoOp(), } - parsedTarget, err := url.Parse(target) + parsedTarget, err := url.ParseURL(target) if err != nil { return nil, err } @@ -94,7 +95,7 @@ func New(ctx context.Context, target string, opts ...AdminClientOpt) (*AdminClie dialOpts := []grpc.DialOption{} switch parsedTarget.Scheme { - case "tcp", "": // default to grpc + case url.TCP: // default to grpc if c.kwildCertFile != "" || c.clientKeyFile != "" || c.clientCertFile != "" { // tcp + tls @@ -108,14 +109,16 @@ func New(ctx context.Context, target string, opts ...AdminClientOpt) (*AdminClie // tcp + no tls dialOpts = append(dialOpts, grpc.WithTransportCredentials(insecure.NewCredentials())) } - case "unix": + case url.UNIX: dialOpts = append(dialOpts, grpc.WithContextDialer(func(ctx context.Context, s string) (net.Conn, error) { return net.Dial("unix", s) }), grpc.WithTransportCredentials(insecure.NewCredentials())) + default: + return nil, fmt.Errorf("unknown scheme %q", parsedTarget.Scheme) } // we dial a normal grpc connection, and then wrap it with the services - conn, err := grpc.DialContext(ctx, target, dialOpts...) + conn, err := grpc.DialContext(ctx, parsedTarget.Target, dialOpts...) if err != nil { return nil, err } diff --git a/core/client/client.go b/core/client/client.go index e6f44b5b1..67129eec0 100644 --- a/core/client/client.go +++ b/core/client/client.go @@ -6,7 +6,6 @@ import ( "context" "encoding/base64" "encoding/json" - "errors" "fmt" "math/big" "net/url" @@ -39,10 +38,6 @@ type TxClient interface { EstimateCost(ctx context.Context, tx *transactions.Transaction) (*big.Int, error) } -var ( - ErrNotFound = errors.New("not found") -) - // Client is a Kwil client that can interact with the main public Kwil RPC. type Client struct { txClient TxClient diff --git a/core/rpc/client/admin/grpc/client.go b/core/rpc/client/admin/grpc/client.go index 7db805726..ae273a368 100644 --- a/core/rpc/client/admin/grpc/client.go +++ b/core/rpc/client/admin/grpc/client.go @@ -5,6 +5,7 @@ import ( "context" "time" + "github.com/kwilteam/kwil-db/core/rpc/client" admpb "github.com/kwilteam/kwil-db/core/rpc/protobuf/admin/v0" "github.com/kwilteam/kwil-db/core/types" adminTypes "github.com/kwilteam/kwil-db/core/types/admin" @@ -26,7 +27,7 @@ func NewAdminClient(conn *grpc.ClientConn) *GrpcAdminClient { func (c *GrpcAdminClient) Version(ctx context.Context) (string, error) { resp, err := c.client.Version(ctx, &admpb.VersionRequest{}) if err != nil { - return "", err + return "", client.ConvertGRPCErr(err) } return resp.VersionString, nil } @@ -47,7 +48,7 @@ func convertNodeInfo(ni *admpb.NodeInfo) *adminTypes.NodeInfo { func (c *GrpcAdminClient) Status(ctx context.Context) (*adminTypes.Status, error) { resp, err := c.client.Status(ctx, &admpb.StatusRequest{}) if err != nil { - return nil, err + return nil, client.ConvertGRPCErr(err) } return &adminTypes.Status{ Node: convertNodeInfo(resp.Node), @@ -68,7 +69,7 @@ func (c *GrpcAdminClient) Status(ctx context.Context) (*adminTypes.Status, error func (c *GrpcAdminClient) Peers(ctx context.Context) ([]*adminTypes.PeerInfo, error) { resp, err := c.client.Peers(ctx, &admpb.PeersRequest{}) if err != nil { - return nil, err + return nil, client.ConvertGRPCErr(err) } peers := make([]*adminTypes.PeerInfo, len(resp.Peers)) for i, pbPeer := range resp.Peers { @@ -86,7 +87,7 @@ func (c *GrpcAdminClient) Peers(ctx context.Context) ([]*adminTypes.PeerInfo, er func (c *GrpcAdminClient) Approve(ctx context.Context, publicKey []byte) ([]byte, error) { resp, err := c.client.Approve(ctx, &admpb.ApproveRequest{Pubkey: publicKey}) if err != nil { - return nil, err + return nil, client.ConvertGRPCErr(err) } return resp.TxHash, nil } @@ -96,7 +97,7 @@ func (c *GrpcAdminClient) Approve(ctx context.Context, publicKey []byte) ([]byte func (c *GrpcAdminClient) Join(ctx context.Context) ([]byte, error) { resp, err := c.client.Join(ctx, &admpb.JoinRequest{}) if err != nil { - return nil, err + return nil, client.ConvertGRPCErr(err) } return resp.TxHash, nil } @@ -106,7 +107,7 @@ func (c *GrpcAdminClient) Join(ctx context.Context) ([]byte, error) { func (c *GrpcAdminClient) Leave(ctx context.Context) ([]byte, error) { resp, err := c.client.Leave(ctx, &admpb.LeaveRequest{}) if err != nil { - return nil, err + return nil, client.ConvertGRPCErr(err) } return resp.TxHash, nil } @@ -116,7 +117,7 @@ func (c *GrpcAdminClient) Leave(ctx context.Context) ([]byte, error) { func (c *GrpcAdminClient) Remove(ctx context.Context, publicKey []byte) ([]byte, error) { resp, err := c.client.Remove(ctx, &admpb.RemoveRequest{Pubkey: publicKey}) if err != nil { - return nil, err + return nil, client.ConvertGRPCErr(err) } return resp.TxHash, nil } @@ -125,7 +126,7 @@ func (c *GrpcAdminClient) Remove(ctx context.Context, publicKey []byte) ([]byte, func (c *GrpcAdminClient) JoinStatus(ctx context.Context, pubkey []byte) (*types.JoinRequest, error) { resp, err := c.client.JoinStatus(ctx, &admpb.JoinStatusRequest{Pubkey: pubkey}) if err != nil { - return nil, err + return nil, client.ConvertGRPCErr(err) } total := len(resp.ApprovedValidators) + len(resp.PendingValidators) @@ -151,7 +152,7 @@ func (c *GrpcAdminClient) JoinStatus(ctx context.Context, pubkey []byte) (*types func (c *GrpcAdminClient) ListValidators(ctx context.Context) ([]*types.Validator, error) { resp, err := c.client.ListValidators(ctx, &admpb.ListValidatorsRequest{}) if err != nil { - return nil, err + return nil, client.ConvertGRPCErr(err) } validators := make([]*types.Validator, len(resp.Validators)) for i, v := range resp.Validators { diff --git a/core/rpc/client/error.go b/core/rpc/client/error.go index 72ee6ea9b..553f55eca 100644 --- a/core/rpc/client/error.go +++ b/core/rpc/client/error.go @@ -1,10 +1,36 @@ package client -import "errors" +import ( + "errors" + "fmt" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) var ( ErrInvalidSignature = errors.New("invalid signature") // ErrUnauthorized is returned when the client is not authenticated // It is the equivalent of http status code 401 ErrUnauthorized = errors.New("unauthorized") + ErrNotFound = errors.New("not found") ) + +// convertErr will convert the error to a known type, if possible. +// It is expected that the error is from a gRPC call. +func ConvertGRPCErr(err error) error { + statusError, ok := status.FromError(err) + if !ok { + return fmt.Errorf("unrecognized error: %w", err) + } + + switch statusError.Code() { + case codes.OK: + // this should never happen? + return fmt.Errorf("unexpected OK status code returned error") + case codes.NotFound: + return ErrNotFound + } + + return fmt.Errorf("%v (%d)", statusError.Message(), statusError.Code()) +} diff --git a/core/utils/url/errors.go b/core/utils/url/errors.go new file mode 100644 index 000000000..98e374f5d --- /dev/null +++ b/core/utils/url/errors.go @@ -0,0 +1,7 @@ +package url + +import "errors" + +var ( + ErrUnknownScheme = errors.New("unknown scheme") +) diff --git a/core/utils/url/url.go b/core/utils/url/url.go new file mode 100644 index 000000000..1cf3c0ebc --- /dev/null +++ b/core/utils/url/url.go @@ -0,0 +1,119 @@ +// package url provides url fuctionalities to provide consistent +// parsing for Kwil clients. +package url + +import ( + "fmt" + "net/url" + "strconv" + "strings" +) + +// URL is a parsed URL. +type URL struct { + // Original is the original URL string. + Original string + // Scheme is the protocol scheme, such as http or tcp. + Scheme Scheme + // Target is either the host, host:port, or unix socket path. + Target string + // Port is the port number, or 0 if not specified. + Port int +} + +// Scheme is a protocol scheme, such as http or tcp. +type Scheme string + +func (s Scheme) valid() bool { + switch s { + case HTTP, HTTPS, TCP, UNIX: + return true + default: + return false + } +} + +func (s Scheme) String() string { + return string(s) +} + +const ( + HTTP Scheme = "http" + HTTPS Scheme = "https" + TCP Scheme = "tcp" + UNIX Scheme = "unix" +) + +// ParseURL parses a URL string into a URL struct. +// URLs can be of the form: +// - http://localhost:8080 +// - tcp://localhost:8080 +// - localhost:8080 +// - localhost +// - unix:///var/run/kwil.sock +// If the URL does not have a scheme, it is assumed to be a tcp address. +func ParseURL(u string) (*URL, error) { + original := u + // if the url does not have a scheme, assume it's a tcp address + hasScheme, err := hasScheme(u) + if err != nil { + return nil, err + } + if !hasScheme { + u = "tcp://" + u + } + + parsed, err := url.Parse(u) + if err != nil { + return nil, err + } + + scheme := Scheme(parsed.Scheme) + if !scheme.valid() { // I don't think this can error, but just in case + return nil, fmt.Errorf("%w: %s", ErrUnknownScheme, scheme) + } + + var target string + switch scheme { + case UNIX: + target = parsed.Path + default: + target = parsed.Host + } + + portString := parsed.Port() + if portString == "" { + portString = "0" + } + port, err := strconv.ParseInt(portString, 10, 32) + if err != nil { + return nil, err + } + + return &URL{ + Original: original, + Scheme: scheme, + Target: target, + Port: int(port), + }, nil +} + +// hasScheme returns true if the url has a known scheme. +func hasScheme(u string) (bool, error) { + parsed, err := url.Parse(u) + if err != nil { + return false, err + } + + switch parsed.Scheme { + case "tcp", "unix", "http", "https": + return true, nil + default: + // see if it can be split by :// + split := strings.Split(u, "://") + if len(split) == 2 { + return false, fmt.Errorf("%w: %s", ErrUnknownScheme, parsed.Scheme) + } + return false, nil + } +} diff --git a/core/utils/url/url_test.go b/core/utils/url/url_test.go new file mode 100644 index 000000000..b6c6233c2 --- /dev/null +++ b/core/utils/url/url_test.go @@ -0,0 +1,79 @@ +package url_test + +import ( + "testing" + + "github.com/kwilteam/kwil-db/core/utils/url" + "gotest.tools/assert" +) + +func TestParseURL(t *testing.T) { + tests := []struct { + name string + url string + want *url.URL + wantErr error + }{ + { + name: "http", + url: "http://localhost:8080", + want: &url.URL{ + Original: "http://localhost:8080", + Scheme: url.HTTP, + Target: "localhost:8080", + Port: 8080, + }, + }, + { + name: "https, no port", + url: "https://localhost", + want: &url.URL{ + Original: "https://localhost", + Scheme: url.HTTPS, + Target: "localhost", + }, + }, + { + name: "tcp", + url: "tcp://localhost:8080", + want: &url.URL{ + Original: "tcp://localhost:8080", + Scheme: url.TCP, + Target: "localhost:8080", + Port: 8080, + }, + }, + { + name: "no scheme", + url: "localhost:8080", + want: &url.URL{ + Original: "localhost:8080", + Scheme: url.TCP, + Target: "localhost:8080", + Port: 8080, + }, + }, + { + name: "unknown scheme", + url: "foo://localhost:8080", + wantErr: url.ErrUnknownScheme, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := url.ParseURL(tt.url) + if tt.wantErr != nil { + if err == nil { + t.Errorf("ParseURL() error = %v, wantErr %v", err, tt.wantErr) + } + return + } + if err != nil { + t.Errorf("ParseURL() error = %v, wantErr %v", err, tt.wantErr) + return + } + + assert.Equal(t, *got, *tt.want) + }) + } +} diff --git a/internal/_admin/admin.go b/internal/_admin/admin.go deleted file mode 100644 index f91e13c14..000000000 --- a/internal/_admin/admin.go +++ /dev/null @@ -1,74 +0,0 @@ -// Package admin provides a client for communicating with an authenticated -// administrative gRPC service on a running kwild instance. This is presently to -// be used by kwil-admin, but it could be made part of our public API, perhaps -// in the client (SDK) package, once fleshed out a little more. -package admin - -import ( - "context" - - "github.com/kwilteam/kwil-db/core/client" - "github.com/kwilteam/kwil-db/core/crypto/auth" - "github.com/kwilteam/kwil-db/core/log" - admClient "github.com/kwilteam/kwil-db/core/rpc/client/admin" - types "github.com/kwilteam/kwil-db/core/types/admin" - - "go.uber.org/zap" -) - -// Client is performs node administrative actions via the authenticated gRPC -// service on a running kwild node. -type Client struct { - *client.Client - client *admClient.AdminClient - signer auth.Signer // for use in methods that require signing a transaction with a Kwil account - logger log.Logger -} - -// New creates a new admin TCP client. TLS is required so the kwild TLS certificate -// is required. Authentication is done at the protocol level (mTLS), so our own -// key pair is also required. The server must have our client certificate loaded -// in it's own tls.Config.ClientCAs. This client keypair can be thought of as a -// preshared key (like a password or token), but handled automatically by the -// TLS handshake, thus requiring no application level logic such as transmitting -// a pass/token with each request. -func New(ctx context.Context, host string, kwildCertFile, clientKeyFile, clientCertFile string, opts ...ClientOpt) (c *Client, err error) { - c = &Client{ - logger: log.NewNoOp(), - } - - for _, opt := range opts { - opt(c) - } - - c.Client, err = client.Dial(ctx, host, client.WithLogger(c.logger), client.WithSigner(c.signer)) - - tlsConfig, err := newAuthenticatedTLSConfig(kwildCertFile, clientCertFile, clientKeyFile) - if err != nil { - return nil, err - } - c.client, err = admClient.New(host, tlsConfig) - if err != nil { - return nil, err - } - - c.logger = *c.logger.Named("admin").With(zap.String("host", host)) - - return c, nil -} - -func (c *Client) Close() error { - return c.client.Close() -} - -func (c *Client) Version(ctx context.Context) (string, error) { - return c.client.Version(ctx) -} - -func (c *Client) Status(ctx context.Context) (*types.Status, error) { - return c.client.Status(ctx) -} - -func (c *Client) Peers(ctx context.Context) ([]*types.PeerInfo, error) { - return c.client.Peers(ctx) -} diff --git a/internal/_admin/opts.go b/internal/_admin/opts.go deleted file mode 100644 index 5271d0bd5..000000000 --- a/internal/_admin/opts.go +++ /dev/null @@ -1,20 +0,0 @@ -package admin - -import ( - "github.com/kwilteam/kwil-db/core/crypto/auth" - "github.com/kwilteam/kwil-db/core/log" -) - -type ClientOpt func(*Client) - -func WithLogger(logger log.Logger) ClientOpt { - return func(c *Client) { - c.logger = logger - } -} - -func WithSigner(signer auth.Signer) ClientOpt { - return func(c *Client) { - c.signer = signer - } -} diff --git a/internal/_admin/tls.go b/internal/_admin/tls.go deleted file mode 100644 index 19d3bb13e..000000000 --- a/internal/_admin/tls.go +++ /dev/null @@ -1,26 +0,0 @@ -package admin - -import ( - "crypto/tls" - - "github.com/kwilteam/kwil-db/core/rpc/transport" -) - -// newAuthenticatedTLSConfig creates a new tls.Config for an -// mutually-authenticated TLS (mTLS) client. In addition to the server's -// certificate file, the client's own key pair is required to support protocol -// level client authentication. -func newAuthenticatedTLSConfig(kwildCertFile, clientCertFile, clientKeyFile string) (*tls.Config, error) { - cfg, err := transport.NewClientTLSConfigFromFile(kwildCertFile) - if err != nil { - return nil, err - } - - authCert, err := tls.LoadX509KeyPair(clientCertFile, clientKeyFile) - if err != nil { - return nil, err - } - cfg.Certificates = append(cfg.Certificates, authCert) - - return cfg, nil -} diff --git a/internal/services/grpc/admin/v0/service.go b/internal/services/grpc/admin/v0/service.go index 5af01ef4b..c9374227e 100644 --- a/internal/services/grpc/admin/v0/service.go +++ b/internal/services/grpc/admin/v0/service.go @@ -74,8 +74,9 @@ func NewService(blockchain BlockchainTransactor, node NodeApplication, validator s := &Service{ blockchain: blockchain, nodeApp: node, - log: log.NewNoOp(), + validators: validators, signer: signer, + log: log.NewNoOp(), } for _, opt := range opts { diff --git a/test/driver/client_driver.go b/test/driver/client_driver.go index 5a2714fd9..9dad2a740 100644 --- a/test/driver/client_driver.go +++ b/test/driver/client_driver.go @@ -142,25 +142,25 @@ func (d *KwildClientDriver) Call(ctx context.Context, dbid, action string, input } func (k *KwildClientDriver) ValidatorJoinStatus(ctx context.Context, pubKey []byte) (*types.JoinRequest, error) { - panic("TODO: Implement") + return k.adminClient.JoinStatus(ctx, pubKey) } func (k *KwildClientDriver) ValidatorNodeApprove(ctx context.Context, joinerPubKey []byte) ([]byte, error) { - panic("TODO: Implement") + return k.adminClient.Approve(ctx, joinerPubKey) } func (k *KwildClientDriver) ValidatorNodeJoin(ctx context.Context) ([]byte, error) { - panic("TODO: Implement") + return k.adminClient.Join(ctx) } func (k *KwildClientDriver) ValidatorNodeLeave(ctx context.Context) ([]byte, error) { - panic("TODO: Implement") + return k.adminClient.Leave(ctx) } func (k *KwildClientDriver) ValidatorNodeRemove(ctx context.Context, target []byte) ([]byte, error) { - panic("TODO: Implement") + return k.adminClient.Remove(ctx, target) } func (k *KwildClientDriver) ValidatorsList(ctx context.Context) ([]*types.Validator, error) { - panic("TODO: Implement") + return k.adminClient.ListValidators(ctx) }