- Ability to interact with grpc apis without needing to consult any documentation.
- Ability to customize behaviour for a specific use case if needed.
- Ability to create custom binary for a specific teams grpc services.
- No config: grpctl should be able to have no config/paperwork for the user to use the tool.
- Server reflection: can be used like grpcurl, but would support tab completion.
- grpcurl
- Universal, doesn't allow to build custom cli.
- protoc-gen-cobra
- Works for a lot of usecases, but adding code generators have an overhead.
- gWhisper
- supports tab completion, doesn't support creating a custom cli.
grpctl
should be a package that allows an engineer to create a custom cli for their teams gRPC API's.
It should use as much information that is possible from the protodescriptor.FileDescriptor
that is possible. This protoreflect.FileDescriptor
can come from the generated go grpc code.
This approach means that there is no need to manually compile .proto
files to get the protodescriptor.FileDescriptor
.
The conversion of protodescriptor.FileDescriptor
to cobra command would look like this:
- protoreflect.ServiceDescriptor -> top level command (eg
fooctl FooAPI
) - protoreflect.MethodDescriptor -> second level command (eg
fooctl FooAPI ListBar
) - protoreflect.MessageDescriptor -> flags (eg
fooctl FooAPI ListBar --field1="string"
)
Example of how a new grpctl cli should be created:
// Example call: billingctl -H="Authorization: Bearer $(gcloud auth application-default print-access-token)" CloudBilling ListBillingAccounts
func main() {
cmd := &cobra.Command{
Use: "billingctl",
Short: "an example cli tool for the gcp billing api",
}
err := grpctl.BuildCommand(cmd,
grpctl.WithFileDescriptors( // This specifies that we want to
billing.File_google_cloud_billing_v1_cloud_billing_proto,
billing.File_google_cloud_billing_v1_cloud_catalog_proto,
),
)
if err != nil {
log.Print(err)
}
if err := grpctl.RunCommand(cmd, context.Background()); err != nil {
log.Print(err)
}
}
grpctl.WithFileDescriptors
allows you to specify the proto descriptors from the generated go code, and in this specific example these FileDescriptors are found here which are generated from the proto source here.