docs: instructions for interacting with the private gRPC server locally

This commit is contained in:
Daniel Upton 2022-06-15 16:35:17 +01:00 committed by Dan Upton
parent 414bb7e34e
commit 8d39e1fd7e
2 changed files with 93 additions and 1 deletions

View File

@ -33,6 +33,24 @@ The main entrypoint to RPC routing is `handleConn` in [agent/consul/rpc.go].
[agent/consul/rpc.go]: https://github.com/hashicorp/consul/blob/main/agent/consul/rpc.go
### Development
Multiplexing several protocols over a single server port helps to reduce our
network requirements, but also makes interacting with Consul using local
development tools such as [grpcurl] difficult.
[grpcurl]: https://github.com/fullstorydev/grpcurl
You can get a "plain" TCP connection to the gRPC server using this proxy script:
```
$ go run tools/private-grpc-proxy/main.go localhost:8300
Proxying connections to Consul's private gRPC server
Use this address: 127.0.0.1:64077
```
Pass the returned proxy address to your tool of choice.
## RPC Endpoints
This section is a work in progress, it will eventually cover topics like:
@ -51,4 +69,3 @@ Routing RPC request to Consul servers and for connection pooling.
- [agent/router](https://github.com/hashicorp/consul/tree/main/agent/router)
- [agent/pool](https://github.com/hashicorp/consul/tree/main/agent/pool)

View File

@ -0,0 +1,75 @@
package main
import (
"fmt"
"io"
"net"
"os"
)
// gRPC byte prefix (see RPCGRPC in agent/pool/conn.go).
const bytePrefix byte = 8
func main() {
if len(os.Args) != 2 {
log("usage: %s host:port", os.Args[0])
os.Exit(1)
}
serverAddr := os.Args[1]
lis, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
log("failed to start listener: %v", err)
os.Exit(1)
}
defer lis.Close()
fmt.Println("Proxying connections to Consul's private gRPC server")
fmt.Printf("Use this address: %s\n", lis.Addr())
for {
conn, err := lis.Accept()
if err != nil {
log("failed to accept connection: %v", err)
continue
}
go func(conn net.Conn) {
if err := handleClient(serverAddr, conn); err != nil {
log(err.Error())
}
}(conn)
}
}
func handleClient(serverAddr string, clientConn net.Conn) error {
defer clientConn.Close()
serverConn, err := net.Dial("tcp", serverAddr)
if err != nil {
return fmt.Errorf("failed to dial server connection: %w", err)
}
defer serverConn.Close()
if _, err := serverConn.Write([]byte{bytePrefix}); err != nil {
return fmt.Errorf("failed to write byte prefix: %v", err)
}
errCh := make(chan error, 1)
go func() {
_, err := io.Copy(serverConn, clientConn)
errCh <- err
}()
go func() {
_, err := io.Copy(clientConn, serverConn)
errCh <- err
}()
return <-errCh
}
func log(message string, args ...interface{}) {
fmt.Fprintf(os.Stderr, message+"\n", args...)
}