mirror of
https://github.com/fullstorydev/grpcurl.git
synced 2026-06-11 21:41:44 +03:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b9a11e9fea | ||
|
|
bc5cf811a0 | ||
|
|
fb49f049e6 | ||
|
|
cdb43b08fa | ||
|
|
56181ba330 | ||
|
|
46c38b351a | ||
|
|
a05d48d6dd | ||
|
|
fc63514da1 | ||
|
|
e14d9f769a | ||
|
|
239dde4a62 | ||
|
|
80e833a557 | ||
|
|
6fccd7757e |
@@ -9,22 +9,22 @@ shared_configs:
|
|||||||
# Use the latest 2.1 version of CircleCI pipeline process engine. See: https://circleci.com/docs/2.0/configuration-reference
|
# Use the latest 2.1 version of CircleCI pipeline process engine. See: https://circleci.com/docs/2.0/configuration-reference
|
||||||
version: 2.1
|
version: 2.1
|
||||||
jobs:
|
jobs:
|
||||||
build-1-19:
|
|
||||||
working_directory: ~/repo
|
|
||||||
docker:
|
|
||||||
- image: cimg/go:1.19
|
|
||||||
steps: *simple_job_steps
|
|
||||||
|
|
||||||
build-1-20:
|
|
||||||
working_directory: ~/repo
|
|
||||||
docker:
|
|
||||||
- image: cimg/go:1.20
|
|
||||||
steps: *simple_job_steps
|
|
||||||
|
|
||||||
build-1-21:
|
build-1-21:
|
||||||
working_directory: ~/repo
|
working_directory: ~/repo
|
||||||
docker:
|
docker:
|
||||||
- image: cimg/go:1.21
|
- image: cimg/go:1.21
|
||||||
|
steps: *simple_job_steps
|
||||||
|
|
||||||
|
build-1-22:
|
||||||
|
working_directory: ~/repo
|
||||||
|
docker:
|
||||||
|
- image: cimg/go:1.22
|
||||||
|
steps: *simple_job_steps
|
||||||
|
|
||||||
|
build-1-23:
|
||||||
|
working_directory: ~/repo
|
||||||
|
docker:
|
||||||
|
- image: cimg/go:1.23
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
- run:
|
- run:
|
||||||
@@ -32,18 +32,9 @@ jobs:
|
|||||||
command: |
|
command: |
|
||||||
make ci
|
make ci
|
||||||
|
|
||||||
# TODO: Need updates to some static analyzer tools to support 1.22. After those
|
|
||||||
# are updated, move the full linting from 1.21 to this latest release.
|
|
||||||
build-1-22:
|
|
||||||
working_directory: ~/repo
|
|
||||||
docker:
|
|
||||||
- image: cimg/go:1.22
|
|
||||||
steps: *simple_job_steps
|
|
||||||
|
|
||||||
workflows:
|
workflows:
|
||||||
pr-build-test:
|
pr-build-test:
|
||||||
jobs:
|
jobs:
|
||||||
- build-1-19
|
|
||||||
- build-1-20
|
|
||||||
- build-1-21
|
- build-1-21
|
||||||
- build-1-22
|
- build-1-22
|
||||||
|
- build-1-23
|
||||||
|
|||||||
@@ -8,14 +8,23 @@ builds:
|
|||||||
goarch:
|
goarch:
|
||||||
- amd64
|
- amd64
|
||||||
- 386
|
- 386
|
||||||
|
- arm
|
||||||
- arm64
|
- arm64
|
||||||
- s390x
|
- s390x
|
||||||
- ppc64le
|
- ppc64le
|
||||||
|
goarm:
|
||||||
|
- 5
|
||||||
|
- 6
|
||||||
|
- 7
|
||||||
ignore:
|
ignore:
|
||||||
- goos: darwin
|
- goos: darwin
|
||||||
goarch: 386
|
goarch: 386
|
||||||
- goos: windows
|
- goos: windows
|
||||||
goarch: arm64
|
goarch: arm64
|
||||||
|
- goos: darwin
|
||||||
|
goarch: arm
|
||||||
|
- goos: windows
|
||||||
|
goarch: arm
|
||||||
- goos: darwin
|
- goos: darwin
|
||||||
goarch: s390x
|
goarch: s390x
|
||||||
- goos: windows
|
- goos: windows
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM golang:1.21-alpine as builder
|
FROM golang:1.23-alpine as builder
|
||||||
MAINTAINER Fullstory Engineering
|
MAINTAINER Fullstory Engineering
|
||||||
|
|
||||||
# create non-privileged group and user
|
# create non-privileged group and user
|
||||||
|
|||||||
8
Makefile
8
Makefile
@@ -1,9 +1,7 @@
|
|||||||
dev_build_version=$(shell git describe --tags --always --dirty)
|
dev_build_version=$(shell git describe --tags --always --dirty)
|
||||||
|
|
||||||
export PATH := $(shell pwd)/.tmp/protoc/bin:$(PATH)
|
export PATH := $(shell pwd)/.tmp/protoc/bin:$(PATH)
|
||||||
|
|
||||||
export PROTOC_VERSION := 22.0
|
export PROTOC_VERSION := 22.0
|
||||||
|
|
||||||
# Disable CGO for improved compatibility across distros
|
# Disable CGO for improved compatibility across distros
|
||||||
export CGO_ENABLED=0
|
export CGO_ENABLED=0
|
||||||
|
|
||||||
@@ -44,7 +42,9 @@ docker:
|
|||||||
generate: .tmp/protoc/bin/protoc
|
generate: .tmp/protoc/bin/protoc
|
||||||
@go install google.golang.org/protobuf/cmd/protoc-gen-go@a709e31e5d12
|
@go install google.golang.org/protobuf/cmd/protoc-gen-go@a709e31e5d12
|
||||||
@go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1.0
|
@go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1.0
|
||||||
|
@go install github.com/jhump/protoreflect/desc/sourceinfo/cmd/protoc-gen-gosrcinfo@v1.14.1
|
||||||
go generate ./...
|
go generate ./...
|
||||||
|
go mod tidy
|
||||||
|
|
||||||
.PHONY: checkgenerate
|
.PHONY: checkgenerate
|
||||||
checkgenerate: generate
|
checkgenerate: generate
|
||||||
@@ -67,7 +67,7 @@ vet:
|
|||||||
|
|
||||||
.PHONY: staticcheck
|
.PHONY: staticcheck
|
||||||
staticcheck:
|
staticcheck:
|
||||||
@go install honnef.co/go/tools/cmd/staticcheck@v0.4.3
|
@go install honnef.co/go/tools/cmd/staticcheck@v0.5.1
|
||||||
staticcheck ./...
|
staticcheck ./...
|
||||||
|
|
||||||
.PHONY: ineffassign
|
.PHONY: ineffassign
|
||||||
@@ -77,7 +77,7 @@ ineffassign:
|
|||||||
|
|
||||||
.PHONY: predeclared
|
.PHONY: predeclared
|
||||||
predeclared:
|
predeclared:
|
||||||
@go install github.com/nishanths/predeclared@5f2f810c9ae6
|
@go install github.com/nishanths/predeclared@245576f9a85c
|
||||||
predeclared ./...
|
predeclared ./...
|
||||||
|
|
||||||
# Intentionally omitted from CI, but target here for ad-hoc reports.
|
# Intentionally omitted from CI, but target here for ad-hoc reports.
|
||||||
|
|||||||
14
README.md
14
README.md
@@ -145,6 +145,13 @@ grpcurl -d @ grpc.server.com:443 my.custom.server.Service/Method <<EOM
|
|||||||
}
|
}
|
||||||
EOM
|
EOM
|
||||||
```
|
```
|
||||||
|
### Adding Headers/Metadata to Request
|
||||||
|
Adding of headers / metadata to a rpc request is possible via the `-H name:value` command line option. Multiple headers can be added in a similar fashion.
|
||||||
|
Example :
|
||||||
|
```shell
|
||||||
|
grpcurl -H header1:value1 -H header2:value2 -d '{"id": 1234, "tags": ["foo","bar"]}' grpc.server.com:443 my.custom.server.Service/Method
|
||||||
|
```
|
||||||
|
For more usage guide, check out the help docs via `grpcurl -help`
|
||||||
|
|
||||||
### Listing Services
|
### Listing Services
|
||||||
To list all services exposed by a server, use the "list" verb. When using `.proto` source
|
To list all services exposed by a server, use the "list" verb. When using `.proto` source
|
||||||
@@ -159,6 +166,13 @@ grpcurl -protoset my-protos.bin list
|
|||||||
|
|
||||||
# Using proto sources
|
# Using proto sources
|
||||||
grpcurl -import-path ../protos -proto my-stuff.proto list
|
grpcurl -import-path ../protos -proto my-stuff.proto list
|
||||||
|
|
||||||
|
# Export proto files (use -proto-out-dir to specify the output directory)
|
||||||
|
grpcurl -plaintext -proto-out-dir "out_protos" "localhost:8787" describe my.custom.server.Service
|
||||||
|
|
||||||
|
# Export protoset file (use -protoset-out to specify the output file)
|
||||||
|
grpcurl -plaintext -protoset-out "out.protoset" "localhost:8787" describe my.custom.server.Service
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The "list" verb also lets you see all methods in a particular service:
|
The "list" verb also lets you see all methods in a particular service:
|
||||||
|
|||||||
@@ -151,6 +151,14 @@ var (
|
|||||||
file if this option is given. When invoking an RPC and this option is
|
file if this option is given. When invoking an RPC and this option is
|
||||||
given, the method being invoked and its transitive dependencies will be
|
given, the method being invoked and its transitive dependencies will be
|
||||||
included in the output file.`))
|
included in the output file.`))
|
||||||
|
protoOut = flags.String("proto-out-dir", "", prettify(`
|
||||||
|
The name of a directory where the generated .proto files will be written.
|
||||||
|
With the list and describe verbs, the listed or described elements and
|
||||||
|
their transitive dependencies will be written as .proto files in the
|
||||||
|
specified directory if this option is given. When invoking an RPC and
|
||||||
|
this option is given, the method being invoked and its transitive
|
||||||
|
dependencies will be included in the generated .proto files in the
|
||||||
|
output directory.`))
|
||||||
msgTemplate = flags.Bool("msg-template", false, prettify(`
|
msgTemplate = flags.Bool("msg-template", false, prettify(`
|
||||||
When describing messages, show a template of input data.`))
|
When describing messages, show a template of input data.`))
|
||||||
verbose = flags.Bool("v", false, prettify(`
|
verbose = flags.Bool("v", false, prettify(`
|
||||||
@@ -645,6 +653,9 @@ func main() {
|
|||||||
if err := writeProtoset(descSource, svcs...); err != nil {
|
if err := writeProtoset(descSource, svcs...); err != nil {
|
||||||
fail(err, "Failed to write protoset to %s", *protosetOut)
|
fail(err, "Failed to write protoset to %s", *protosetOut)
|
||||||
}
|
}
|
||||||
|
if err := writeProtos(descSource, svcs...); err != nil {
|
||||||
|
fail(err, "Failed to write protos to %s", *protoOut)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
methods, err := grpcurl.ListMethods(descSource, symbol)
|
methods, err := grpcurl.ListMethods(descSource, symbol)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -660,6 +671,9 @@ func main() {
|
|||||||
if err := writeProtoset(descSource, symbol); err != nil {
|
if err := writeProtoset(descSource, symbol); err != nil {
|
||||||
fail(err, "Failed to write protoset to %s", *protosetOut)
|
fail(err, "Failed to write protoset to %s", *protosetOut)
|
||||||
}
|
}
|
||||||
|
if err := writeProtos(descSource, symbol); err != nil {
|
||||||
|
fail(err, "Failed to write protos to %s", *protoOut)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if describe {
|
} else if describe {
|
||||||
@@ -764,6 +778,9 @@ func main() {
|
|||||||
if err := writeProtoset(descSource, symbols...); err != nil {
|
if err := writeProtoset(descSource, symbols...); err != nil {
|
||||||
fail(err, "Failed to write protoset to %s", *protosetOut)
|
fail(err, "Failed to write protoset to %s", *protosetOut)
|
||||||
}
|
}
|
||||||
|
if err := writeProtos(descSource, symbol); err != nil {
|
||||||
|
fail(err, "Failed to write protos to %s", *protoOut)
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Invoke an RPC
|
// Invoke an RPC
|
||||||
@@ -923,6 +940,13 @@ func writeProtoset(descSource grpcurl.DescriptorSource, symbols ...string) error
|
|||||||
return grpcurl.WriteProtoset(f, descSource, symbols...)
|
return grpcurl.WriteProtoset(f, descSource, symbols...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func writeProtos(descSource grpcurl.DescriptorSource, symbols ...string) error {
|
||||||
|
if *protoOut == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return grpcurl.WriteProtoFiles(*protoOut, descSource, symbols...)
|
||||||
|
}
|
||||||
|
|
||||||
type optionalBoolFlag struct {
|
type optionalBoolFlag struct {
|
||||||
set, val bool
|
set, val bool
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,13 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/golang/protobuf/proto" //lint:ignore SA1019 we have to import this because it appears in exported API
|
"github.com/golang/protobuf/proto" //lint:ignore SA1019 we have to import this because it appears in exported API
|
||||||
"github.com/jhump/protoreflect/desc"
|
"github.com/jhump/protoreflect/desc"
|
||||||
"github.com/jhump/protoreflect/desc/protoparse"
|
"github.com/jhump/protoreflect/desc/protoparse"
|
||||||
|
"github.com/jhump/protoreflect/desc/protoprint"
|
||||||
"github.com/jhump/protoreflect/dynamic"
|
"github.com/jhump/protoreflect/dynamic"
|
||||||
"github.com/jhump/protoreflect/grpcreflect"
|
"github.com/jhump/protoreflect/grpcreflect"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
@@ -258,19 +260,9 @@ func reflectionSupport(err error) error {
|
|||||||
// given output. The output will include descriptors for all files in which the
|
// given output. The output will include descriptors for all files in which the
|
||||||
// symbols are defined as well as their transitive dependencies.
|
// symbols are defined as well as their transitive dependencies.
|
||||||
func WriteProtoset(out io.Writer, descSource DescriptorSource, symbols ...string) error {
|
func WriteProtoset(out io.Writer, descSource DescriptorSource, symbols ...string) error {
|
||||||
// compute set of file descriptors
|
filenames, fds, err := getFileDescriptors(symbols, descSource)
|
||||||
filenames := make([]string, 0, len(symbols))
|
if err != nil {
|
||||||
fds := make(map[string]*desc.FileDescriptor, len(symbols))
|
return err
|
||||||
for _, sym := range symbols {
|
|
||||||
d, err := descSource.FindSymbol(sym)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to find descriptor for %q: %v", sym, err)
|
|
||||||
}
|
|
||||||
fd := d.GetFile()
|
|
||||||
if _, ok := fds[fd.GetName()]; !ok {
|
|
||||||
fds[fd.GetName()] = fd
|
|
||||||
filenames = append(filenames, fd.GetName())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// now expand that to include transitive dependencies in topologically sorted
|
// now expand that to include transitive dependencies in topologically sorted
|
||||||
// order (such that file always appears after its dependencies)
|
// order (such that file always appears after its dependencies)
|
||||||
@@ -302,3 +294,76 @@ func addFilesToSet(allFiles []*descriptorpb.FileDescriptorProto, expanded map[st
|
|||||||
}
|
}
|
||||||
return append(allFiles, fd.AsFileDescriptorProto())
|
return append(allFiles, fd.AsFileDescriptorProto())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WriteProtoFiles will use the given descriptor source to resolve all the given
|
||||||
|
// symbols and write proto files with their definitions to the given output directory.
|
||||||
|
func WriteProtoFiles(outProtoDirPath string, descSource DescriptorSource, symbols ...string) error {
|
||||||
|
filenames, fds, err := getFileDescriptors(symbols, descSource)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// now expand that to include transitive dependencies in topologically sorted
|
||||||
|
// order (such that file always appears after its dependencies)
|
||||||
|
expandedFiles := make(map[string]struct{}, len(fds))
|
||||||
|
allFileDescriptors := make([]*desc.FileDescriptor, 0, len(fds))
|
||||||
|
for _, filename := range filenames {
|
||||||
|
allFileDescriptors = addFilesToFileDescriptorList(allFileDescriptors, expandedFiles, fds[filename])
|
||||||
|
}
|
||||||
|
pr := protoprint.Printer{}
|
||||||
|
// now we can serialize to files
|
||||||
|
for i := range allFileDescriptors {
|
||||||
|
if err := writeProtoFile(outProtoDirPath, allFileDescriptors[i], &pr); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeProtoFile(outProtoDirPath string, fd *desc.FileDescriptor, pr *protoprint.Printer) error {
|
||||||
|
outFile := filepath.Join(outProtoDirPath, fd.GetFullyQualifiedName())
|
||||||
|
outDir := filepath.Dir(outFile)
|
||||||
|
if err := os.MkdirAll(outDir, 0777); err != nil {
|
||||||
|
return fmt.Errorf("failed to create directory %q: %w", outDir, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := os.Create(outFile)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to create proto file %q: %w", outFile, err)
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
if err := pr.PrintProtoFile(fd, f); err != nil {
|
||||||
|
return fmt.Errorf("failed to write proto file %q: %w", outFile, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getFileDescriptors(symbols []string, descSource DescriptorSource) ([]string, map[string]*desc.FileDescriptor, error) {
|
||||||
|
// compute set of file descriptors
|
||||||
|
filenames := make([]string, 0, len(symbols))
|
||||||
|
fds := make(map[string]*desc.FileDescriptor, len(symbols))
|
||||||
|
for _, sym := range symbols {
|
||||||
|
d, err := descSource.FindSymbol(sym)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("failed to find descriptor for %q: %v", sym, err)
|
||||||
|
}
|
||||||
|
fd := d.GetFile()
|
||||||
|
if _, ok := fds[fd.GetName()]; !ok {
|
||||||
|
fds[fd.GetName()] = fd
|
||||||
|
filenames = append(filenames, fd.GetName())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filenames, fds, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func addFilesToFileDescriptorList(allFiles []*desc.FileDescriptor, expanded map[string]struct{}, fd *desc.FileDescriptor) []*desc.FileDescriptor {
|
||||||
|
if _, ok := expanded[fd.GetName()]; ok {
|
||||||
|
// already seen this one
|
||||||
|
return allFiles
|
||||||
|
}
|
||||||
|
expanded[fd.GetName()] = struct{}{}
|
||||||
|
// add all dependencies first
|
||||||
|
for _, dep := range fd.GetDependencies() {
|
||||||
|
allFiles = addFilesToFileDescriptorList(allFiles, expanded, dep)
|
||||||
|
}
|
||||||
|
return append(allFiles, fd)
|
||||||
|
}
|
||||||
|
|||||||
6
go.mod
6
go.mod
@@ -1,12 +1,12 @@
|
|||||||
module github.com/fullstorydev/grpcurl
|
module github.com/fullstorydev/grpcurl
|
||||||
|
|
||||||
go 1.19
|
go 1.21
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/golang/protobuf v1.5.4
|
github.com/golang/protobuf v1.5.4
|
||||||
github.com/jhump/protoreflect v1.16.0
|
github.com/jhump/protoreflect v1.16.0
|
||||||
google.golang.org/grpc v1.61.0
|
google.golang.org/grpc v1.61.0
|
||||||
google.golang.org/protobuf v1.33.1-0.20240408130810-98873a205002
|
google.golang.org/protobuf v1.34.2
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
@@ -19,7 +19,7 @@ require (
|
|||||||
github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101 // indirect
|
github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101 // indirect
|
||||||
github.com/envoyproxy/go-control-plane v0.11.1 // indirect
|
github.com/envoyproxy/go-control-plane v0.11.1 // indirect
|
||||||
github.com/envoyproxy/protoc-gen-validate v1.0.2 // indirect
|
github.com/envoyproxy/protoc-gen-validate v1.0.2 // indirect
|
||||||
golang.org/x/net v0.22.0 // indirect
|
golang.org/x/net v0.23.0 // indirect
|
||||||
golang.org/x/oauth2 v0.14.0 // indirect
|
golang.org/x/oauth2 v0.14.0 // indirect
|
||||||
golang.org/x/sync v0.6.0 // indirect
|
golang.org/x/sync v0.6.0 // indirect
|
||||||
golang.org/x/sys v0.18.0 // indirect
|
golang.org/x/sys v0.18.0 // indirect
|
||||||
|
|||||||
14
go.sum
14
go.sum
@@ -18,6 +18,7 @@ github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWH
|
|||||||
github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101 h1:7To3pQ+pZo0i3dsWEbinPNFs5gPSBOsJtx3wTT94VBY=
|
github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101 h1:7To3pQ+pZo0i3dsWEbinPNFs5gPSBOsJtx3wTT94VBY=
|
||||||
github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.11.1 h1:wSUXTlLfiAQRWs2F+p+EKOY9rUyis1MyGqJ2DIk5HpM=
|
github.com/envoyproxy/go-control-plane v0.11.1 h1:wSUXTlLfiAQRWs2F+p+EKOY9rUyis1MyGqJ2DIk5HpM=
|
||||||
github.com/envoyproxy/go-control-plane v0.11.1/go.mod h1:uhMcXKCQMEJHiAb0w+YGefQLaTEw+YhGluxZkrTmD0g=
|
github.com/envoyproxy/go-control-plane v0.11.1/go.mod h1:uhMcXKCQMEJHiAb0w+YGefQLaTEw+YhGluxZkrTmD0g=
|
||||||
@@ -35,12 +36,16 @@ github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6
|
|||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
|
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
|
||||||
|
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/jhump/protoreflect v1.16.0 h1:54fZg+49widqXYQ0b+usAFHbMkBGR4PpXrsHc8+TBDg=
|
github.com/jhump/protoreflect v1.16.0 h1:54fZg+49widqXYQ0b+usAFHbMkBGR4PpXrsHc8+TBDg=
|
||||||
github.com/jhump/protoreflect v1.16.0/go.mod h1:oYPd7nPvcBw/5wlDfm/AVmU9zH9BgqGCI469pGxfj/8=
|
github.com/jhump/protoreflect v1.16.0/go.mod h1:oYPd7nPvcBw/5wlDfm/AVmU9zH9BgqGCI469pGxfj/8=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
@@ -56,8 +61,8 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn
|
|||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
|
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
|
||||||
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.14.0 h1:P0Vrf/2538nmC0H+pEQ3MNFRRnVR7RlqyVw+bvm26z0=
|
golang.org/x/oauth2 v0.14.0 h1:P0Vrf/2538nmC0H+pEQ3MNFRRnVR7RlqyVw+bvm26z0=
|
||||||
golang.org/x/oauth2 v0.14.0/go.mod h1:lAtNWgaWfL4cm7j2OV8TxGi9Qb7ECORx8DktCY74OwM=
|
golang.org/x/oauth2 v0.14.0/go.mod h1:lAtNWgaWfL4cm7j2OV8TxGi9Qb7ECORx8DktCY74OwM=
|
||||||
@@ -111,8 +116,9 @@ google.golang.org/grpc v1.61.0 h1:TOvOcuXn30kRao+gfcvsebNEa5iZIiLkisYEkf7R7o0=
|
|||||||
google.golang.org/grpc v1.61.0/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs=
|
google.golang.org/grpc v1.61.0/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs=
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
google.golang.org/protobuf v1.33.1-0.20240408130810-98873a205002 h1:V7Da7qt0MkY3noVANIMVBk28nOnijADeOR3i5Hcvpj4=
|
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||||
google.golang.org/protobuf v1.33.1-0.20240408130810-98873a205002/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
|||||||
18
grpcurl.go
18
grpcurl.go
@@ -28,6 +28,7 @@ import (
|
|||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
"google.golang.org/grpc/credentials/insecure"
|
"google.golang.org/grpc/credentials/insecure"
|
||||||
xdsCredentials "google.golang.org/grpc/credentials/xds"
|
xdsCredentials "google.golang.org/grpc/credentials/xds"
|
||||||
|
_ "google.golang.org/grpc/health" // import grpc/health to enable transparent client side checking
|
||||||
"google.golang.org/grpc/metadata"
|
"google.golang.org/grpc/metadata"
|
||||||
protov2 "google.golang.org/protobuf/proto"
|
protov2 "google.golang.org/protobuf/proto"
|
||||||
"google.golang.org/protobuf/types/descriptorpb"
|
"google.golang.org/protobuf/types/descriptorpb"
|
||||||
@@ -644,21 +645,6 @@ func BlockingDial(ctx context.Context, network, address string, creds credential
|
|||||||
writeResult: writeResult,
|
writeResult: writeResult,
|
||||||
}
|
}
|
||||||
|
|
||||||
dialer := func(ctx context.Context, address string) (net.Conn, error) {
|
|
||||||
// NB: We *could* handle the TLS handshake ourselves, in the custom
|
|
||||||
// dialer (instead of customizing both the dialer and the credentials).
|
|
||||||
// But that requires using insecure.NewCredentials() dial transport
|
|
||||||
// option (so that the gRPC library doesn't *also* try to do a
|
|
||||||
// handshake). And that would mean that the library would send the
|
|
||||||
// wrong ":scheme" metaheader to servers: it would send "http" instead
|
|
||||||
// of "https" because it is unaware that TLS is actually in use.
|
|
||||||
conn, err := (&net.Dialer{}).DialContext(ctx, network, address)
|
|
||||||
if err != nil {
|
|
||||||
writeResult(err)
|
|
||||||
}
|
|
||||||
return conn, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Even with grpc.FailOnNonTempDialError, this call will usually timeout in
|
// Even with grpc.FailOnNonTempDialError, this call will usually timeout in
|
||||||
// the face of TLS handshake errors. So we can't rely on grpc.WithBlock() to
|
// the face of TLS handshake errors. So we can't rely on grpc.WithBlock() to
|
||||||
// know when we're done. So we run it in a goroutine and then use result
|
// know when we're done. So we run it in a goroutine and then use result
|
||||||
@@ -669,7 +655,7 @@ func BlockingDial(ctx context.Context, network, address string, creds credential
|
|||||||
opts = append([]grpc.DialOption{grpc.FailOnNonTempDialError(true)}, opts...)
|
opts = append([]grpc.DialOption{grpc.FailOnNonTempDialError(true)}, opts...)
|
||||||
// But we don't want caller to be able to override these two, so we put
|
// But we don't want caller to be able to override these two, so we put
|
||||||
// them *after* the explicitly provided options.
|
// them *after* the explicitly provided options.
|
||||||
opts = append(opts, grpc.WithBlock(), grpc.WithContextDialer(dialer), grpc.WithTransportCredentials(creds))
|
opts = append(opts, grpc.WithBlock(), grpc.WithTransportCredentials(creds))
|
||||||
|
|
||||||
conn, err := grpc.DialContext(ctx, address, opts...)
|
conn, err := grpc.DialContext(ctx, address, opts...)
|
||||||
var res interface{}
|
var res interface{}
|
||||||
|
|||||||
Reference in New Issue
Block a user