docs: instructions for interacting with the private gRPC server locally
This commit is contained in:
parent
414bb7e34e
commit
8d39e1fd7e
|
@ -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)
|
||||
|
||||
|
|
|
@ -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...)
|
||||
}
|
Loading…
Reference in New Issue