Skip to content

Instantly share code, notes, and snippets.

@kristiandrucker
Last active December 28, 2021 13:21
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kristiandrucker/d3a7c7b8e64f55ad4ebfa3634a96d5fe to your computer and use it in GitHub Desktop.
Save kristiandrucker/d3a7c7b8e64f55ad4ebfa3634a96d5fe to your computer and use it in GitHub Desktop.
package main
import (
"flag"
"google.golang.org/protobuf/reflect/protoreflect"
"io/ioutil"
"log"
"os"
"google.golang.org/genproto/googleapis/api/annotations"
"google.golang.org/genproto/googleapis/longrunning"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/descriptorpb"
)
func main() {
var filename string
flag.StringVar(&filename, "f", "", "file descriptor set to scrub")
flag.Parse()
if filename == "" {
flag.Usage()
os.Exit(1)
}
input, err := ioutil.ReadFile(filename)
if err != nil {
log.Fatal(err)
}
var fileDescriptorSet descriptorpb.FileDescriptorSet
if err := proto.Unmarshal(input, &fileDescriptorSet); err != nil {
log.Fatal(err)
}
for _, file := range fileDescriptorSet.GetFile() {
scrubFileImports(file)
scrubFileOptions(file)
for _, message := range file.GetMessageType() {
scrubResourceReferences(message)
}
for _, service := range file.GetService() {
scrubServiceOptions(service)
for _, method := range service.GetMethod() {
scrubMethodOptions(method)
}
}
}
output, err := proto.Marshal(&fileDescriptorSet)
if err != nil {
log.Fatal(err)
}
if err := ioutil.WriteFile(filename, output, 0o600); err != nil {
log.Fatal(err)
}
}
func scrubFileImports(message *descriptorpb.FileDescriptorProto) {
for i, dep := range message.GetDependency() {
switch dep {
case "google/api/client.proto",
"google/api/resource.proto",
"google/api/field_behavior.proto":
message.Dependency = append(message.Dependency[:i], message.Dependency[i+1:]...)
default:
continue
}
}
}
func scrubFileOptions(file *descriptorpb.FileDescriptorProto) {
if file.GetOptions() != nil {
scrubIfExists(file.GetOptions(), annotations.E_ResourceDefinition)
}
}
func scrubResourceReferences(message *descriptorpb.DescriptorProto) {
for _, field := range message.GetField() {
if field.GetOptions() != nil {
scrubIfExists(field.GetOptions(), annotations.E_Resource)
scrubIfExists(field.GetOptions(), annotations.E_ResourceReference)
scrubIfExists(field.GetOptions(), annotations.E_FieldBehavior)
}
}
for _, nestedMessage := range message.NestedType {
scrubResourceReferences(nestedMessage)
}
}
func scrubServiceOptions(service *descriptorpb.ServiceDescriptorProto) {
if service.GetOptions() != nil {
scrubIfExists(service.GetOptions(), annotations.E_DefaultHost)
}
}
func scrubMethodOptions(method *descriptorpb.MethodDescriptorProto) {
if method.GetOptions() != nil {
scrubIfExists(method.GetOptions(), annotations.E_MethodSignature)
scrubIfExists(method.GetOptions(), longrunning.E_OperationInfo)
}
}
func scrubIfExists(msg proto.Message, extensionType protoreflect.ExtensionType) {
if proto.HasExtension(msg, extensionType) {
proto.ClearExtension(msg, extensionType)
}
}
@long1eu
Copy link

long1eu commented Dec 27, 2021

Can you provide some instructions on how to use this?

@kristiandrucker
Copy link
Author

You can run it by running. By providing the -f argument you specify your generated API descriptor.

# go run scrubber.go -f api_descriptor.pb

@long1eu
Copy link

long1eu commented Dec 28, 2021

backend/cloud-run/scrubber.go:10:2: no required module provides package google.golang.org/genproto/googleapis/api/annotations: go.mod file not found in current directory or any parent directory; see 'go help modules'
backend/cloud-run/scrubber.go:11:2: no required module provides package google.golang.org/genproto/googleapis/longrunning: go.mod file not found in current directory or any parent directory; see 'go help modules'
backend/cloud-run/scrubber.go:12:2: no required module provides package google.golang.org/protobuf/proto: go.mod file not found in current directory or any parent directory; see 'go help modules'
backend/cloud-run/scrubber.go:5:2: no required module provides package google.golang.org/protobuf/reflect/protoreflect: go.mod file not found in current directory or any parent directory; see 'go help modules'
backend/cloud-run/scrubber.go:13:2: no required module provides package google.golang.org/protobuf/types/descriptorpb: go.mod file not found in current directory or any parent directory; see 'go help modules'

@kristiandrucker
Copy link
Author

Try running

go mod init scrubber
go mod tidy
go run ...

This should get all of the packages and run correctly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment