diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2e55df8..d76f410 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest env: GO_VERSION: stable - GOLANGCI_LINT_VERSION: v1.63.4 + GOLANGCI_LINT_VERSION: v2.1.2 CGO_ENABLED: 0 steps: diff --git a/.golangci.yml b/.golangci.yml index f49e476..1e624ef 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,84 +1,84 @@ -run: - timeout: 2m - -linters-settings: - govet: - enable-all: true - disable: - - fieldalignment - gocyclo: - min-complexity: 16 - goconst: - min-len: 3 - min-occurrences: 3 - misspell: - locale: US - funlen: - lines: -1 - statements: 40 - gofumpt: - extra-rules: true - depguard: - rules: - main: - deny: - - pkg: "github.com/instana/testify" - desc: not allowed - - pkg: "github.com/pkg/errors" - desc: Should be replaced by standard lib errors package - godox: - keywords: - - FIXME - gocritic: - enabled-tags: - - diagnostic - - style - - performance - disabled-checks: - - sloppyReassign - - rangeValCopy - - octalLiteral - - paramTypeCombine # already handle by gofumpt.extra-rules - settings: - hugeParam: - sizeThreshold: 100 - forbidigo: - forbid: - - '^print(ln)?$' - - '^panic$' - - '^spew\.Print(f|ln)?$' - - '^spew\.Dump$' - +version: "2" linters: - enable-all: true + default: all disable: - - rowserrcheck # not relevant (SQL) - - sqlclosecheck # not relevant (SQL) - - cyclop # duplicate of gocyclo + - cyclop - dupl + - err113 - exhaustive - exhaustruct - - exportloopref - forbidigo - gochecknoglobals - gochecknoinits - - err113 - - mnd - gosec - lll + - mnd - nilnil - nlreturn - paralleltest - prealloc + - rowserrcheck + - sqlclosecheck - testpackage - tparallel - varnamelen - wrapcheck - wsl - + settings: + depguard: + rules: + main: + deny: + - pkg: github.com/instana/testify + desc: not allowed + - pkg: github.com/pkg/errors + desc: Should be replaced by standard lib errors package + forbidigo: + forbid: + - pattern: ^print(ln)?$ + - pattern: ^panic$ + - pattern: ^spew\.Print(f|ln)?$ + - pattern: ^spew\.Dump$ + funlen: + lines: -1 + statements: 40 + goconst: + min-len: 3 + min-occurrences: 3 + gocritic: + disabled-checks: + - sloppyReassign + - rangeValCopy + - octalLiteral + - paramTypeCombine + enabled-tags: + - diagnostic + - style + - performance + settings: + hugeParam: + sizeThreshold: 100 + gocyclo: + min-complexity: 16 + godox: + keywords: + - FIXME + govet: + disable: + - fieldalignment + enable-all: true + misspell: + locale: US + exclusions: + presets: + - comments issues: - exclude-use-default: false max-issues-per-linter: 0 max-same-issues: 0 - exclude: - - 'package-comments: should have a package comment' +formatters: + enable: + - gci + - gofumpt + settings: + gofumpt: + extra-rules: true diff --git a/Makefile b/Makefile index 30cf594..d97a95b 100644 --- a/Makefile +++ b/Makefile @@ -15,3 +15,6 @@ check: image: docker build -t $(IMAGE_NAME) . + +protoc: + protoc --proto_path . ./grpc.proto --go-grpc_out=./ --go_out=./ diff --git a/README.md b/README.md index 72d714d..420df48 100644 --- a/README.md +++ b/README.md @@ -59,45 +59,82 @@ Heath check. ## Examples ```console -$ docker run -d -P --name iamfoo traefik/whoami +$ docker run -d -p 8080:80 --name iamfoo traefik/whoami -$ docker inspect --format '{{ .NetworkSettings.Ports }}' iamfoo -map[80/tcp:[{0.0.0.0 32769}]] - -$ curl "http://0.0.0.0:32769" -Hostname : 6e0030e67d6a -IP : 127.0.0.1 -IP : ::1 -IP : 172.17.0.27 -IP : fe80::42:acff:fe11:1b +$ curl http://localhost:8080 +Hostname: 9c9c93da54b5 +IP: 127.0.0.1 +IP: ::1 +IP: 172.17.0.2 +RemoteAddr: 172.17.0.1:41040 GET / HTTP/1.1 -Host: 0.0.0.0:32769 -User-Agent: curl/7.35.0 +Host: localhost:8080 +User-Agent: curl/8.5.0 Accept: */* ``` ```console # updates health check status -$ curl -X POST -d '500' http://localhost:80/health +$ curl -X POST -d '500' http://localhost:8080/health # calls the health check -$ curl -v http://localhost:80/health -* Trying ::1:80... -* TCP_NODELAY set -* Connected to localhost (::1) port 80 (#0) +$ curl -v http://localhost:8080/health +* Host localhost:8080 was resolved. +* IPv6: ::1 +* IPv4: 127.0.0.1 +* Trying [::1]:8080... +* Connected to localhost (::1) port 8080 > GET /health HTTP/1.1 -> Host: localhost:80 -> User-Agent: curl/7.65.3 +> Host: localhost:8080 +> User-Agent: curl/8.5.0 > Accept: */* > -* Mark bundle as not supporting multiuse < HTTP/1.1 500 Internal Server Error -< Date: Mon, 16 Sep 2019 22:52:40 GMT +< Date: Fri, 18 Apr 2025 13:36:02 GMT < Content-Length: 0 ``` ```console -docker run -d -P -v ./certs:/certs --name iamfoo traefik/whoami --cert /certs/example.cert --key /certs/example.key +$ openssl req -newkey rsa:4096 \ + -x509 \ + -sha256 \ + -days 3650 \ + -nodes \ + -out ./certs/example.crt \ + -keyout ./certs/example.key + +$ docker run -d -p 8080:80 -v ./certs:/certs --name iamfoo traefik/whoami --cert /certs/example.crt --key /certs/example.key + +$ curl https://localhost:8080 -k --cert certs/example.crt --key certs/example.key +Hostname: 25bc0df47b95 +IP: 127.0.0.1 +IP: ::1 +IP: 172.17.0.2 +RemoteAddr: 172.17.0.1:50278 +Certificate[0] Subject: CN=traefik.io,O=TraefikLabs,L=Lyon,ST=France,C=FR +GET / HTTP/1.1 +Host: localhost:8080 +User-Agent: curl/8.5.0 +Accept: */* +``` + +```console +$ docker run -d -p 8080:80 --name iamfoo traefik/whoami + +$ grpcurl -plaintext -proto grpc.proto localhost:8080 whoami.Whoami/Whoami +{ + "hostname": "5a45e21984b4", + "iface": [ + "127.0.0.1", + "::1", + "172.17.0.2" + ] +} + +$ grpcurl -plaintext -proto grpc.proto localhost:8080 whoami.Whoami/Bench +{ + "data": 1 +} ``` ```yml @@ -110,4 +147,4 @@ services: # It tells whoami to start listening on 2001 instead of 80 - --port=2001 - --name=iamfoo -``` +``` \ No newline at end of file diff --git a/app.go b/app.go index 0849b03..c2f0512 100644 --- a/app.go +++ b/app.go @@ -1,6 +1,7 @@ package main import ( + "context" "crypto/tls" "crypto/x509" "encoding/json" @@ -17,6 +18,10 @@ import ( "time" "github.com/gorilla/websocket" + grpcWhoami "github.com/traefik/whoami/grpc" + "golang.org/x/net/http2" + "golang.org/x/net/http2/h2c" + "google.golang.org/grpc" ) // Units. @@ -78,16 +83,22 @@ func main() { mux.Handle("/health", handle(healthHandler, verbose)) mux.Handle("/", handle(whoamiHandler, verbose)) + serverGRPC := grpc.NewServer() + grpcWhoami.RegisterWhoamiServer(serverGRPC, whoamiServer{}) + mux.Handle("/whoami.Whoami/", serverGRPC) + + h := handle(mux.ServeHTTP, verbose) + if cert == "" || key == "" { log.Printf("Starting up on port %s", port) - log.Fatal(http.ListenAndServe(":"+port, mux)) + log.Fatal(http.ListenAndServe(":"+port, h2c.NewHandler(h, &http2.Server{}))) } server := &http.Server{ Addr: ":" + port, TLSConfig: &tls.Config{ClientAuth: tls.RequestClientCert}, - Handler: mux, + Handler: h, } if ca != "" { @@ -344,3 +355,38 @@ func getIPs() []string { return ips } + +type whoamiServer struct { + grpcWhoami.UnimplementedWhoamiServer +} + +func (g whoamiServer) Bench(_ context.Context, _ *grpcWhoami.BenchRequest) (*grpcWhoami.BenchReply, error) { + return &grpcWhoami.BenchReply{Data: 1}, nil +} + +func (g whoamiServer) Whoami(_ context.Context, _ *grpcWhoami.WhoamiRequest) (*grpcWhoami.WhoamiReply, error) { + reply := &grpcWhoami.WhoamiReply{} + if name != "" { + reply.Name = name + } + + reply.Hostname, _ = os.Hostname() + + ifaces, _ := net.Interfaces() + for _, i := range ifaces { + addrs, _ := i.Addrs() + // handle err + for _, addr := range addrs { + var ip net.IP + switch v := addr.(type) { + case *net.IPNet: + ip = v.IP + case *net.IPAddr: + ip = v.IP + } + reply.Iface = append(reply.Iface, ip.String()) + } + } + + return reply, nil +} diff --git a/go.mod b/go.mod index 681d1fd..b17efda 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,16 @@ module github.com/traefik/whoami -go 1.23 +go 1.24 -require github.com/gorilla/websocket v1.5.3 +require ( + github.com/gorilla/websocket v1.5.3 + golang.org/x/net v0.34.0 + google.golang.org/grpc v1.71.1 + google.golang.org/protobuf v1.36.6 +) + +require ( + golang.org/x/sys v0.29.0 // indirect + golang.org/x/text v0.21.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect +) diff --git a/go.sum b/go.sum index 25a9fc4..d3c6f46 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,36 @@ +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +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.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= +go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= +go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= +go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= +go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= +go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= +go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= +go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= +go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= +go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50= +google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI= +google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= diff --git a/grpc.proto b/grpc.proto new file mode 100644 index 0000000..05764c6 --- /dev/null +++ b/grpc.proto @@ -0,0 +1,26 @@ +syntax = "proto3"; + +package whoami; + +option go_package = "./grpc"; + +service Whoami { + rpc Whoami (WhoamiRequest) returns (WhoamiReply) {} + rpc Bench(BenchRequest) returns (BenchReply) {} +} + +message WhoamiRequest {} + +message WhoamiReply { + string name = 1; + string hostname = 2; + repeated string iface = 3; +} + +// The empty request message +message BenchRequest {} + +// The response message containing simple data +message BenchReply { + int32 data = 1; +} \ No newline at end of file diff --git a/grpc/grpc.pb.go b/grpc/grpc.pb.go new file mode 100644 index 0000000..83af2e6 --- /dev/null +++ b/grpc/grpc.pb.go @@ -0,0 +1,274 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.6 +// protoc v3.21.12 +// source: grpc.proto + +package grpc + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type WhoamiRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *WhoamiRequest) Reset() { + *x = WhoamiRequest{} + mi := &file_grpc_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *WhoamiRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WhoamiRequest) ProtoMessage() {} + +func (x *WhoamiRequest) ProtoReflect() protoreflect.Message { + mi := &file_grpc_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WhoamiRequest.ProtoReflect.Descriptor instead. +func (*WhoamiRequest) Descriptor() ([]byte, []int) { + return file_grpc_proto_rawDescGZIP(), []int{0} +} + +type WhoamiReply struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Hostname string `protobuf:"bytes,2,opt,name=hostname,proto3" json:"hostname,omitempty"` + Iface []string `protobuf:"bytes,3,rep,name=iface,proto3" json:"iface,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *WhoamiReply) Reset() { + *x = WhoamiReply{} + mi := &file_grpc_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *WhoamiReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WhoamiReply) ProtoMessage() {} + +func (x *WhoamiReply) ProtoReflect() protoreflect.Message { + mi := &file_grpc_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WhoamiReply.ProtoReflect.Descriptor instead. +func (*WhoamiReply) Descriptor() ([]byte, []int) { + return file_grpc_proto_rawDescGZIP(), []int{1} +} + +func (x *WhoamiReply) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *WhoamiReply) GetHostname() string { + if x != nil { + return x.Hostname + } + return "" +} + +func (x *WhoamiReply) GetIface() []string { + if x != nil { + return x.Iface + } + return nil +} + +// The empty request message +type BenchRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BenchRequest) Reset() { + *x = BenchRequest{} + mi := &file_grpc_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BenchRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BenchRequest) ProtoMessage() {} + +func (x *BenchRequest) ProtoReflect() protoreflect.Message { + mi := &file_grpc_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BenchRequest.ProtoReflect.Descriptor instead. +func (*BenchRequest) Descriptor() ([]byte, []int) { + return file_grpc_proto_rawDescGZIP(), []int{2} +} + +// The response message containing simple data +type BenchReply struct { + state protoimpl.MessageState `protogen:"open.v1"` + Data int32 `protobuf:"varint,1,opt,name=data,proto3" json:"data,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BenchReply) Reset() { + *x = BenchReply{} + mi := &file_grpc_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BenchReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BenchReply) ProtoMessage() {} + +func (x *BenchReply) ProtoReflect() protoreflect.Message { + mi := &file_grpc_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BenchReply.ProtoReflect.Descriptor instead. +func (*BenchReply) Descriptor() ([]byte, []int) { + return file_grpc_proto_rawDescGZIP(), []int{3} +} + +func (x *BenchReply) GetData() int32 { + if x != nil { + return x.Data + } + return 0 +} + +var File_grpc_proto protoreflect.FileDescriptor + +const file_grpc_proto_rawDesc = "" + + "\n" + + "\n" + + "grpc.proto\x12\x06whoami\"\x0f\n" + + "\rWhoamiRequest\"S\n" + + "\vWhoamiReply\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x1a\n" + + "\bhostname\x18\x02 \x01(\tR\bhostname\x12\x14\n" + + "\x05iface\x18\x03 \x03(\tR\x05iface\"\x0e\n" + + "\fBenchRequest\" \n" + + "\n" + + "BenchReply\x12\x12\n" + + "\x04data\x18\x01 \x01(\x05R\x04data2u\n" + + "\x06Whoami\x126\n" + + "\x06Whoami\x12\x15.whoami.WhoamiRequest\x1a\x13.whoami.WhoamiReply\"\x00\x123\n" + + "\x05Bench\x12\x14.whoami.BenchRequest\x1a\x12.whoami.BenchReply\"\x00B\bZ\x06./grpcb\x06proto3" + +var ( + file_grpc_proto_rawDescOnce sync.Once + file_grpc_proto_rawDescData []byte +) + +func file_grpc_proto_rawDescGZIP() []byte { + file_grpc_proto_rawDescOnce.Do(func() { + file_grpc_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_grpc_proto_rawDesc), len(file_grpc_proto_rawDesc))) + }) + return file_grpc_proto_rawDescData +} + +var file_grpc_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_grpc_proto_goTypes = []any{ + (*WhoamiRequest)(nil), // 0: whoami.WhoamiRequest + (*WhoamiReply)(nil), // 1: whoami.WhoamiReply + (*BenchRequest)(nil), // 2: whoami.BenchRequest + (*BenchReply)(nil), // 3: whoami.BenchReply +} +var file_grpc_proto_depIdxs = []int32{ + 0, // 0: whoami.Whoami.Whoami:input_type -> whoami.WhoamiRequest + 2, // 1: whoami.Whoami.Bench:input_type -> whoami.BenchRequest + 1, // 2: whoami.Whoami.Whoami:output_type -> whoami.WhoamiReply + 3, // 3: whoami.Whoami.Bench:output_type -> whoami.BenchReply + 2, // [2:4] is the sub-list for method output_type + 0, // [0:2] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_grpc_proto_init() } +func file_grpc_proto_init() { + if File_grpc_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_grpc_proto_rawDesc), len(file_grpc_proto_rawDesc)), + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_grpc_proto_goTypes, + DependencyIndexes: file_grpc_proto_depIdxs, + MessageInfos: file_grpc_proto_msgTypes, + }.Build() + File_grpc_proto = out.File + file_grpc_proto_goTypes = nil + file_grpc_proto_depIdxs = nil +} diff --git a/grpc/grpc_grpc.pb.go b/grpc/grpc_grpc.pb.go new file mode 100644 index 0000000..14c1964 --- /dev/null +++ b/grpc/grpc_grpc.pb.go @@ -0,0 +1,159 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc v3.21.12 +// source: grpc.proto + +package grpc + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + Whoami_Whoami_FullMethodName = "/whoami.Whoami/Whoami" + Whoami_Bench_FullMethodName = "/whoami.Whoami/Bench" +) + +// WhoamiClient is the client API for Whoami service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type WhoamiClient interface { + Whoami(ctx context.Context, in *WhoamiRequest, opts ...grpc.CallOption) (*WhoamiReply, error) + Bench(ctx context.Context, in *BenchRequest, opts ...grpc.CallOption) (*BenchReply, error) +} + +type whoamiClient struct { + cc grpc.ClientConnInterface +} + +func NewWhoamiClient(cc grpc.ClientConnInterface) WhoamiClient { + return &whoamiClient{cc} +} + +func (c *whoamiClient) Whoami(ctx context.Context, in *WhoamiRequest, opts ...grpc.CallOption) (*WhoamiReply, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(WhoamiReply) + err := c.cc.Invoke(ctx, Whoami_Whoami_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *whoamiClient) Bench(ctx context.Context, in *BenchRequest, opts ...grpc.CallOption) (*BenchReply, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(BenchReply) + err := c.cc.Invoke(ctx, Whoami_Bench_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// WhoamiServer is the server API for Whoami service. +// All implementations must embed UnimplementedWhoamiServer +// for forward compatibility. +type WhoamiServer interface { + Whoami(context.Context, *WhoamiRequest) (*WhoamiReply, error) + Bench(context.Context, *BenchRequest) (*BenchReply, error) + mustEmbedUnimplementedWhoamiServer() +} + +// UnimplementedWhoamiServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedWhoamiServer struct{} + +func (UnimplementedWhoamiServer) Whoami(context.Context, *WhoamiRequest) (*WhoamiReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method Whoami not implemented") +} +func (UnimplementedWhoamiServer) Bench(context.Context, *BenchRequest) (*BenchReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method Bench not implemented") +} +func (UnimplementedWhoamiServer) mustEmbedUnimplementedWhoamiServer() {} +func (UnimplementedWhoamiServer) testEmbeddedByValue() {} + +// UnsafeWhoamiServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to WhoamiServer will +// result in compilation errors. +type UnsafeWhoamiServer interface { + mustEmbedUnimplementedWhoamiServer() +} + +func RegisterWhoamiServer(s grpc.ServiceRegistrar, srv WhoamiServer) { + // If the following call pancis, it indicates UnimplementedWhoamiServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&Whoami_ServiceDesc, srv) +} + +func _Whoami_Whoami_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(WhoamiRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WhoamiServer).Whoami(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Whoami_Whoami_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WhoamiServer).Whoami(ctx, req.(*WhoamiRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Whoami_Bench_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BenchRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WhoamiServer).Bench(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Whoami_Bench_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WhoamiServer).Bench(ctx, req.(*BenchRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// Whoami_ServiceDesc is the grpc.ServiceDesc for Whoami service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Whoami_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "whoami.Whoami", + HandlerType: (*WhoamiServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Whoami", + Handler: _Whoami_Whoami_Handler, + }, + { + MethodName: "Bench", + Handler: _Whoami_Bench_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "grpc.proto", +}