diff --git a/cmd/podinfo/main.go b/cmd/podinfo/main.go index 08a6be627..f05a6de76 100644 --- a/cmd/podinfo/main.go +++ b/cmd/podinfo/main.go @@ -13,8 +13,8 @@ import ( "go.uber.org/zap" "go.uber.org/zap/zapcore" - "github.com/stefanprodan/podinfo/pkg/api" - "github.com/stefanprodan/podinfo/pkg/grpc" + "github.com/stefanprodan/podinfo/pkg/api/grpc" + "github.com/stefanprodan/podinfo/pkg/api/http" "github.com/stefanprodan/podinfo/pkg/signals" "github.com/stefanprodan/podinfo/pkg/version" go_grpc "google.golang.org/grpc" @@ -138,11 +138,13 @@ func main() { var grpcServer *go_grpc.Server if grpcCfg.Port > 0 { grpcSrv, _ := grpc.NewServer(&grpcCfg, logger) + //grpcinfoSrv, _ := grpc.NewInfoServer(&grpcCfg) + grpcServer = grpcSrv.ListenAndServe() } // load HTTP server config - var srvCfg api.Config + var srvCfg http.Config if err := viper.Unmarshal(&srvCfg); err != nil { logger.Panic("config unmarshal failed", zap.Error(err)) } @@ -155,7 +157,7 @@ func main() { ) // start HTTP server - srv, _ := api.NewServer(&srvCfg, logger) + srv, _ := http.NewServer(&srvCfg, logger) httpServer, httpsServer, healthy, ready := srv.ListenAndServe() // graceful shutdown diff --git a/pkg/api/grpc/echo.go b/pkg/api/grpc/echo.go new file mode 100644 index 000000000..2e850941f --- /dev/null +++ b/pkg/api/grpc/echo.go @@ -0,0 +1,20 @@ +package grpc + +import ( + "context" + + "github.com/stefanprodan/podinfo/pkg/api/grpc/echo" + "go.uber.org/zap" +) + +type echoServer struct { + echo.UnimplementedEchoServiceServer + config *Config + logger *zap.Logger +} + +func (s *echoServer) Echo (ctx context.Context, message *echo.Message) (*echo.Message, error){ + + s.logger.Info("Received message body from client:", zap.String("input body", message.Body)) + return &echo.Message {Body: message.Body}, nil +} diff --git a/pkg/api/grpc/echo/echo.pb.go b/pkg/api/grpc/echo/echo.pb.go new file mode 100644 index 000000000..b132476dc --- /dev/null +++ b/pkg/api/grpc/echo/echo.pb.go @@ -0,0 +1,146 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v4.24.3 +// source: echo/echo.proto + +package echo + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +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 Message struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Body string `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"` +} + +func (x *Message) Reset() { + *x = Message{} + if protoimpl.UnsafeEnabled { + mi := &file_echo_echo_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Message) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Message) ProtoMessage() {} + +func (x *Message) ProtoReflect() protoreflect.Message { + mi := &file_echo_echo_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Message.ProtoReflect.Descriptor instead. +func (*Message) Descriptor() ([]byte, []int) { + return file_echo_echo_proto_rawDescGZIP(), []int{0} +} + +func (x *Message) GetBody() string { + if x != nil { + return x.Body + } + return "" +} + +var File_echo_echo_proto protoreflect.FileDescriptor + +var file_echo_echo_proto_rawDesc = []byte{ + 0x0a, 0x0f, 0x65, 0x63, 0x68, 0x6f, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x04, 0x65, 0x63, 0x68, 0x6f, 0x22, 0x1d, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x32, 0x35, 0x0a, 0x0b, 0x45, 0x63, 0x68, 0x6f, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x45, 0x63, 0x68, 0x6f, 0x12, 0x0d, 0x2e, + 0x65, 0x63, 0x68, 0x6f, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x0d, 0x2e, 0x65, + 0x63, 0x68, 0x6f, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x42, 0x08, 0x5a, + 0x06, 0x2e, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_echo_echo_proto_rawDescOnce sync.Once + file_echo_echo_proto_rawDescData = file_echo_echo_proto_rawDesc +) + +func file_echo_echo_proto_rawDescGZIP() []byte { + file_echo_echo_proto_rawDescOnce.Do(func() { + file_echo_echo_proto_rawDescData = protoimpl.X.CompressGZIP(file_echo_echo_proto_rawDescData) + }) + return file_echo_echo_proto_rawDescData +} + +var file_echo_echo_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_echo_echo_proto_goTypes = []interface{}{ + (*Message)(nil), // 0: echo.Message +} +var file_echo_echo_proto_depIdxs = []int32{ + 0, // 0: echo.EchoService.Echo:input_type -> echo.Message + 0, // 1: echo.EchoService.Echo:output_type -> echo.Message + 1, // [1:2] is the sub-list for method output_type + 0, // [0:1] 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_echo_echo_proto_init() } +func file_echo_echo_proto_init() { + if File_echo_echo_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_echo_echo_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Message); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_echo_echo_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_echo_echo_proto_goTypes, + DependencyIndexes: file_echo_echo_proto_depIdxs, + MessageInfos: file_echo_echo_proto_msgTypes, + }.Build() + File_echo_echo_proto = out.File + file_echo_echo_proto_rawDesc = nil + file_echo_echo_proto_goTypes = nil + file_echo_echo_proto_depIdxs = nil +} diff --git a/pkg/api/grpc/echo/echo.proto b/pkg/api/grpc/echo/echo.proto new file mode 100644 index 000000000..efcefba1a --- /dev/null +++ b/pkg/api/grpc/echo/echo.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +option go_package = "./echo"; + +package echo; + +message Message { + string body = 1; +} + + +service EchoService { + rpc Echo(Message) returns (Message) {} +} \ No newline at end of file diff --git a/pkg/api/grpc/echo/echo_grpc.pb.go b/pkg/api/grpc/echo/echo_grpc.pb.go new file mode 100644 index 000000000..754d6d839 --- /dev/null +++ b/pkg/api/grpc/echo/echo_grpc.pb.go @@ -0,0 +1,109 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v4.24.3 +// source: echo/echo.proto + +package echo + +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.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + EchoService_Echo_FullMethodName = "/echo.EchoService/Echo" +) + +// EchoServiceClient is the client API for EchoService 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 EchoServiceClient interface { + Echo(ctx context.Context, in *Message, opts ...grpc.CallOption) (*Message, error) +} + +type echoServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewEchoServiceClient(cc grpc.ClientConnInterface) EchoServiceClient { + return &echoServiceClient{cc} +} + +func (c *echoServiceClient) Echo(ctx context.Context, in *Message, opts ...grpc.CallOption) (*Message, error) { + out := new(Message) + err := c.cc.Invoke(ctx, EchoService_Echo_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// EchoServiceServer is the server API for EchoService service. +// All implementations must embed UnimplementedEchoServiceServer +// for forward compatibility +type EchoServiceServer interface { + Echo(context.Context, *Message) (*Message, error) + mustEmbedUnimplementedEchoServiceServer() +} + +// UnimplementedEchoServiceServer must be embedded to have forward compatible implementations. +type UnimplementedEchoServiceServer struct { +} + +func (UnimplementedEchoServiceServer) Echo(context.Context, *Message) (*Message, error) { + return nil, status.Errorf(codes.Unimplemented, "method Echo not implemented") +} +func (UnimplementedEchoServiceServer) mustEmbedUnimplementedEchoServiceServer() {} + +// UnsafeEchoServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to EchoServiceServer will +// result in compilation errors. +type UnsafeEchoServiceServer interface { + mustEmbedUnimplementedEchoServiceServer() +} + +func RegisterEchoServiceServer(s grpc.ServiceRegistrar, srv EchoServiceServer) { + s.RegisterService(&EchoService_ServiceDesc, srv) +} + +func _EchoService_Echo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Message) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(EchoServiceServer).Echo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: EchoService_Echo_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(EchoServiceServer).Echo(ctx, req.(*Message)) + } + return interceptor(ctx, in, info, handler) +} + +// EchoService_ServiceDesc is the grpc.ServiceDesc for EchoService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var EchoService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "echo.EchoService", + HandlerType: (*EchoServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Echo", + Handler: _EchoService_Echo_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "echo/echo.proto", +} diff --git a/pkg/api/grpc/echo_test.go b/pkg/api/grpc/echo_test.go new file mode 100644 index 000000000..4f1812d85 --- /dev/null +++ b/pkg/api/grpc/echo_test.go @@ -0,0 +1,70 @@ +package grpc + +import ( + "context" + "log" + "net" + "regexp" + "testing" + + "github.com/stefanprodan/podinfo/pkg/api/grpc/echo" + "google.golang.org/grpc" + "google.golang.org/grpc/status" + "google.golang.org/grpc/test/bufconn" +) + +func TestGrpcEcho(t *testing.T) { + + // Server initialization + // bufconn => uses in-memory connection instead of system network I/O + lis := bufconn.Listen(1024*1024) + t.Cleanup(func() { + lis.Close() + }) + + s := NewMockGrpcServer() + srv := grpc.NewServer() + t.Cleanup(func() { + srv.Stop() + }) + + echo.RegisterEchoServiceServer(srv, &echoServer{config: s.config, logger: s.logger}) + + go func(){ + if err := srv.Serve(lis); err != nil { + log.Fatalf("srv.Serve %v", err) + } + }() + + // - Test + dialer := func(context.Context, string) (net.Conn, error){ + return lis.Dial() + } + + ctx := context.Background() + + conn, err := grpc.DialContext(ctx, "", grpc.WithContextDialer(dialer), grpc.WithInsecure()) + t.Cleanup(func() { + conn.Close() + }) + + if err != nil { + t.Fatalf("grpc.DialContext %v", err) + } + + client := echo.NewEchoServiceClient(conn) + res , err := client.Echo(context.Background(), &echo.Message{Body:"test123-test"}) + + // Check the status code is what we expect. + if _, ok := status.FromError(err); !ok { + t.Errorf("Echo returned type %T, want %T", err, status.Error) + } + + // Check the response body is what we expect. + expected := ".*body.*test123-test.*" + r := regexp.MustCompile(expected) + if !r.MatchString(res.String()) { + t.Fatalf("Returned unexpected body:\ngot \n%v \nwant \n%s", + res, expected) + } +} \ No newline at end of file diff --git a/pkg/api/grpc/mock_grpc.go b/pkg/api/grpc/mock_grpc.go new file mode 100644 index 000000000..f05827ed7 --- /dev/null +++ b/pkg/api/grpc/mock_grpc.go @@ -0,0 +1,31 @@ +package grpc + +import ( + "go.uber.org/zap" +) + + +func NewMockGrpcServer() *Server { + config := &Config{ + Port: 9999, + // ServerShutdownTimeout: 5 * time.Second, + // HttpServerTimeout: 30 * time.Second, + BackendURL: []string{}, + ConfigPath: "/config", + DataPath: "/data", + // HttpClientTimeout: 30 * time.Second, + UIColor: "blue", + UIPath: ".ui", + UIMessage: "Greetings", + Hostname: "localhost", + } + + logger, _ := zap.NewDevelopment() + + return &Server{ + //router: mux.NewRouter(), + logger: logger, + config: config, + //tracer: trace.NewNoopTracerProvider().Tracer("mock"), + } +} \ No newline at end of file diff --git a/pkg/api/grpc/panic.go b/pkg/api/grpc/panic.go new file mode 100644 index 000000000..b47b82aa2 --- /dev/null +++ b/pkg/api/grpc/panic.go @@ -0,0 +1,24 @@ +package grpc + +import ( + "context" + // "log" + "os" + + pb "github.com/stefanprodan/podinfo/pkg/api/grpc/panic" + "go.uber.org/zap" +) + +type PanicServer struct { + pb.UnimplementedPanicServiceServer + config *Config + logger *zap.Logger + +} + +func (s *PanicServer) Panic(ctx context.Context, req *pb.PanicRequest) (*pb.PanicResponse, error) { + s.logger.Info("Panic command received") + os.Exit(225) + return &pb.PanicResponse{}, nil +} + diff --git a/pkg/api/grpc/panic/panic.pb.go b/pkg/api/grpc/panic/panic.pb.go new file mode 100644 index 000000000..bfd104287 --- /dev/null +++ b/pkg/api/grpc/panic/panic.pb.go @@ -0,0 +1,189 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.6.1 +// source: panic.proto + +package panic + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +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 PanicRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *PanicRequest) Reset() { + *x = PanicRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_panic_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PanicRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PanicRequest) ProtoMessage() {} + +func (x *PanicRequest) ProtoReflect() protoreflect.Message { + mi := &file_panic_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PanicRequest.ProtoReflect.Descriptor instead. +func (*PanicRequest) Descriptor() ([]byte, []int) { + return file_panic_proto_rawDescGZIP(), []int{0} +} + +type PanicResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *PanicResponse) Reset() { + *x = PanicResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_panic_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PanicResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PanicResponse) ProtoMessage() {} + +func (x *PanicResponse) ProtoReflect() protoreflect.Message { + mi := &file_panic_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PanicResponse.ProtoReflect.Descriptor instead. +func (*PanicResponse) Descriptor() ([]byte, []int) { + return file_panic_proto_rawDescGZIP(), []int{1} +} + +var File_panic_proto protoreflect.FileDescriptor + +var file_panic_proto_rawDesc = []byte{ + 0x0a, 0x0b, 0x70, 0x61, 0x6e, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, + 0x61, 0x6e, 0x69, 0x63, 0x22, 0x0e, 0x0a, 0x0c, 0x50, 0x61, 0x6e, 0x69, 0x63, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x22, 0x0f, 0x0a, 0x0d, 0x50, 0x61, 0x6e, 0x69, 0x63, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x44, 0x0a, 0x0c, 0x50, 0x61, 0x6e, 0x69, 0x63, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x34, 0x0a, 0x05, 0x50, 0x61, 0x6e, 0x69, 0x63, 0x12, 0x13, + 0x2e, 0x70, 0x61, 0x6e, 0x69, 0x63, 0x2e, 0x50, 0x61, 0x6e, 0x69, 0x63, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x70, 0x61, 0x6e, 0x69, 0x63, 0x2e, 0x50, 0x61, 0x6e, 0x69, + 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x09, 0x5a, 0x07, 0x2e, + 0x2f, 0x70, 0x61, 0x6e, 0x69, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_panic_proto_rawDescOnce sync.Once + file_panic_proto_rawDescData = file_panic_proto_rawDesc +) + +func file_panic_proto_rawDescGZIP() []byte { + file_panic_proto_rawDescOnce.Do(func() { + file_panic_proto_rawDescData = protoimpl.X.CompressGZIP(file_panic_proto_rawDescData) + }) + return file_panic_proto_rawDescData +} + +var file_panic_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_panic_proto_goTypes = []interface{}{ + (*PanicRequest)(nil), // 0: panic.PanicRequest + (*PanicResponse)(nil), // 1: panic.PanicResponse +} +var file_panic_proto_depIdxs = []int32{ + 0, // 0: panic.PanicService.Panic:input_type -> panic.PanicRequest + 1, // 1: panic.PanicService.Panic:output_type -> panic.PanicResponse + 1, // [1:2] is the sub-list for method output_type + 0, // [0:1] 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_panic_proto_init() } +func file_panic_proto_init() { + if File_panic_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_panic_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PanicRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_panic_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PanicResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_panic_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_panic_proto_goTypes, + DependencyIndexes: file_panic_proto_depIdxs, + MessageInfos: file_panic_proto_msgTypes, + }.Build() + File_panic_proto = out.File + file_panic_proto_rawDesc = nil + file_panic_proto_goTypes = nil + file_panic_proto_depIdxs = nil +} diff --git a/pkg/api/grpc/panic/panic.proto b/pkg/api/grpc/panic/panic.proto new file mode 100644 index 000000000..995106d53 --- /dev/null +++ b/pkg/api/grpc/panic/panic.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +option go_package = "./panic"; + +package panic; + +// The greeting service definition. +service PanicService { + rpc Panic (PanicRequest) returns (PanicResponse) {} +} + +message PanicRequest { +} + +message PanicResponse { +} + diff --git a/pkg/api/grpc/panic/panic_grpc.pb.go b/pkg/api/grpc/panic/panic_grpc.pb.go new file mode 100644 index 000000000..dccf98b2e --- /dev/null +++ b/pkg/api/grpc/panic/panic_grpc.pb.go @@ -0,0 +1,105 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.6.1 +// source: panic.proto + +package panic + +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.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// PanicServiceClient is the client API for PanicService 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 PanicServiceClient interface { + Panic(ctx context.Context, in *PanicRequest, opts ...grpc.CallOption) (*PanicResponse, error) +} + +type panicServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewPanicServiceClient(cc grpc.ClientConnInterface) PanicServiceClient { + return &panicServiceClient{cc} +} + +func (c *panicServiceClient) Panic(ctx context.Context, in *PanicRequest, opts ...grpc.CallOption) (*PanicResponse, error) { + out := new(PanicResponse) + err := c.cc.Invoke(ctx, "/panic.PanicService/Panic", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// PanicServiceServer is the server API for PanicService service. +// All implementations must embed UnimplementedPanicServiceServer +// for forward compatibility +type PanicServiceServer interface { + Panic(context.Context, *PanicRequest) (*PanicResponse, error) + mustEmbedUnimplementedPanicServiceServer() +} + +// UnimplementedPanicServiceServer must be embedded to have forward compatible implementations. +type UnimplementedPanicServiceServer struct { +} + +func (UnimplementedPanicServiceServer) Panic(context.Context, *PanicRequest) (*PanicResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Panic not implemented") +} +func (UnimplementedPanicServiceServer) mustEmbedUnimplementedPanicServiceServer() {} + +// UnsafePanicServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to PanicServiceServer will +// result in compilation errors. +type UnsafePanicServiceServer interface { + mustEmbedUnimplementedPanicServiceServer() +} + +func RegisterPanicServiceServer(s grpc.ServiceRegistrar, srv PanicServiceServer) { + s.RegisterService(&PanicService_ServiceDesc, srv) +} + +func _PanicService_Panic_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PanicRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PanicServiceServer).Panic(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/panic.PanicService/Panic", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PanicServiceServer).Panic(ctx, req.(*PanicRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// PanicService_ServiceDesc is the grpc.ServiceDesc for PanicService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var PanicService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "panic.PanicService", + HandlerType: (*PanicServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Panic", + Handler: _PanicService_Panic_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "panic.proto", +} diff --git a/pkg/api/grpc/server.go b/pkg/api/grpc/server.go new file mode 100644 index 000000000..fd3283823 --- /dev/null +++ b/pkg/api/grpc/server.go @@ -0,0 +1,93 @@ +package grpc + +import ( + "fmt" + "net" + + "github.com/stefanprodan/podinfo/pkg/api/grpc/echo" + + "go.uber.org/zap" + "google.golang.org/grpc" + "google.golang.org/grpc/health" + "google.golang.org/grpc/health/grpc_health_v1" + "google.golang.org/grpc/reflection" + + "github.com/stefanprodan/podinfo/pkg/api/grpc/panic" + "github.com/stefanprodan/podinfo/pkg/api/grpc/version" +) + + +type Server struct { + logger *zap.Logger + config *Config +} + +type Config struct { + Port int `mapstructure:"grpc-port"` + ServiceName string `mapstructure:"grpc-service-name"` + + + BackendURL []string `mapstructure:"backend-url"` + UILogo string `mapstructure:"ui-logo"` + UIMessage string `mapstructure:"ui-message"` + UIColor string `mapstructure:"ui-color"` + UIPath string `mapstructure:"ui-path"` + DataPath string `mapstructure:"data-path"` + ConfigPath string `mapstructure:"config-path"` + CertPath string `mapstructure:"cert-path"` + Host string `mapstructure:"host"` + //Port string `mapstructure:"port"` + SecurePort string `mapstructure:"secure-port"` + PortMetrics int `mapstructure:"port-metrics"` + Hostname string `mapstructure:"hostname"` + H2C bool `mapstructure:"h2c"` + RandomDelay bool `mapstructure:"random-delay"` + RandomDelayUnit string `mapstructure:"random-delay-unit"` + RandomDelayMin int `mapstructure:"random-delay-min"` + RandomDelayMax int `mapstructure:"random-delay-max"` + RandomError bool `mapstructure:"random-error"` + Unhealthy bool `mapstructure:"unhealthy"` + Unready bool `mapstructure:"unready"` + JWTSecret string `mapstructure:"jwt-secret"` + CacheServer string `mapstructure:"cache-server"` + +} + +func NewServer(config *Config, logger *zap.Logger) (*Server, error) { + srv := &Server{ + logger: logger, + config: config, + } + + return srv, nil +} + + +func (s *Server) ListenAndServe() *grpc.Server { + listener, err := net.Listen("tcp", fmt.Sprintf(":%v", s.config.Port)) + if err != nil { + s.logger.Fatal("failed to listen", zap.Int("port", s.config.Port)) + } + + srv := grpc.NewServer() + server := health.NewServer() + + + // Register grpc apis for refection + echo.RegisterEchoServiceServer(srv, &echoServer{config: s.config, logger: s.logger}) + + version.RegisterVersionServiceServer(srv, &VersionServer{config: s.config, logger: s.logger}) + panic.RegisterPanicServiceServer(srv, &PanicServer{config: s.config, logger: s.logger}) + + reflection.Register(srv) + grpc_health_v1.RegisterHealthServer(srv, server) + server.SetServingStatus(s.config.ServiceName, grpc_health_v1.HealthCheckResponse_SERVING) + + go func() { + if err := srv.Serve(listener); err != nil { + s.logger.Fatal("failed to serve", zap.Error(err)) + } + }() + + return srv +} diff --git a/pkg/api/grpc/version.go b/pkg/api/grpc/version.go new file mode 100644 index 000000000..8291e2e6b --- /dev/null +++ b/pkg/api/grpc/version.go @@ -0,0 +1,21 @@ +package grpc + +import ( + "context" + + pb "github.com/stefanprodan/podinfo/pkg/api/grpc/version" + "github.com/stefanprodan/podinfo/pkg/version" + "go.uber.org/zap" +) + +type VersionServer struct { + pb.UnimplementedVersionServiceServer + config *Config + logger *zap.Logger + +} + +func (s *VersionServer) Version(ctx context.Context, req *pb.VersionRequest) (*pb.VersionResponse, error) { + return &pb.VersionResponse{Version: version.VERSION, Commit: version.REVISION}, nil +} + diff --git a/pkg/api/grpc/version/version.pb.go b/pkg/api/grpc/version/version.pb.go new file mode 100644 index 000000000..ee66cfab5 --- /dev/null +++ b/pkg/api/grpc/version/version.pb.go @@ -0,0 +1,211 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.6.1 +// source: version.proto + +package version + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +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 VersionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *VersionRequest) Reset() { + *x = VersionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_version_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VersionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VersionRequest) ProtoMessage() {} + +func (x *VersionRequest) ProtoReflect() protoreflect.Message { + mi := &file_version_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VersionRequest.ProtoReflect.Descriptor instead. +func (*VersionRequest) Descriptor() ([]byte, []int) { + return file_version_proto_rawDescGZIP(), []int{0} +} + +type VersionResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + Commit string `protobuf:"bytes,2,opt,name=commit,proto3" json:"commit,omitempty"` +} + +func (x *VersionResponse) Reset() { + *x = VersionResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_version_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VersionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VersionResponse) ProtoMessage() {} + +func (x *VersionResponse) ProtoReflect() protoreflect.Message { + mi := &file_version_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VersionResponse.ProtoReflect.Descriptor instead. +func (*VersionResponse) Descriptor() ([]byte, []int) { + return file_version_proto_rawDescGZIP(), []int{1} +} + +func (x *VersionResponse) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *VersionResponse) GetCommit() string { + if x != nil { + return x.Commit + } + return "" +} + +var File_version_proto protoreflect.FileDescriptor + +var file_version_proto_rawDesc = []byte{ + 0x0a, 0x0d, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x10, 0x0a, 0x0e, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x43, 0x0a, 0x0f, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x32, + 0x50, 0x0a, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0x3e, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x2e, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2e, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x42, 0x0b, 0x5a, 0x09, 0x2e, 0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_version_proto_rawDescOnce sync.Once + file_version_proto_rawDescData = file_version_proto_rawDesc +) + +func file_version_proto_rawDescGZIP() []byte { + file_version_proto_rawDescOnce.Do(func() { + file_version_proto_rawDescData = protoimpl.X.CompressGZIP(file_version_proto_rawDescData) + }) + return file_version_proto_rawDescData +} + +var file_version_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_version_proto_goTypes = []interface{}{ + (*VersionRequest)(nil), // 0: version.VersionRequest + (*VersionResponse)(nil), // 1: version.VersionResponse +} +var file_version_proto_depIdxs = []int32{ + 0, // 0: version.VersionService.Version:input_type -> version.VersionRequest + 1, // 1: version.VersionService.Version:output_type -> version.VersionResponse + 1, // [1:2] is the sub-list for method output_type + 0, // [0:1] 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_version_proto_init() } +func file_version_proto_init() { + if File_version_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_version_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VersionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_version_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VersionResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_version_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_version_proto_goTypes, + DependencyIndexes: file_version_proto_depIdxs, + MessageInfos: file_version_proto_msgTypes, + }.Build() + File_version_proto = out.File + file_version_proto_rawDesc = nil + file_version_proto_goTypes = nil + file_version_proto_depIdxs = nil +} diff --git a/pkg/api/grpc/version/version.proto b/pkg/api/grpc/version/version.proto new file mode 100644 index 000000000..7ea56b371 --- /dev/null +++ b/pkg/api/grpc/version/version.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +option go_package = "./version"; + +package version; + + +service VersionService { + rpc Version (VersionRequest) returns (VersionResponse) {} +} + + +message VersionRequest {} + +message VersionResponse { + string version = 1; + string commit = 2; +} diff --git a/pkg/api/grpc/version/version_grpc.pb.go b/pkg/api/grpc/version/version_grpc.pb.go new file mode 100644 index 000000000..ed4baff2b --- /dev/null +++ b/pkg/api/grpc/version/version_grpc.pb.go @@ -0,0 +1,105 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.6.1 +// source: version.proto + +package version + +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.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// VersionServiceClient is the client API for VersionService 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 VersionServiceClient interface { + Version(ctx context.Context, in *VersionRequest, opts ...grpc.CallOption) (*VersionResponse, error) +} + +type versionServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewVersionServiceClient(cc grpc.ClientConnInterface) VersionServiceClient { + return &versionServiceClient{cc} +} + +func (c *versionServiceClient) Version(ctx context.Context, in *VersionRequest, opts ...grpc.CallOption) (*VersionResponse, error) { + out := new(VersionResponse) + err := c.cc.Invoke(ctx, "/version.VersionService/Version", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// VersionServiceServer is the server API for VersionService service. +// All implementations must embed UnimplementedVersionServiceServer +// for forward compatibility +type VersionServiceServer interface { + Version(context.Context, *VersionRequest) (*VersionResponse, error) + mustEmbedUnimplementedVersionServiceServer() +} + +// UnimplementedVersionServiceServer must be embedded to have forward compatible implementations. +type UnimplementedVersionServiceServer struct { +} + +func (UnimplementedVersionServiceServer) Version(context.Context, *VersionRequest) (*VersionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Version not implemented") +} +func (UnimplementedVersionServiceServer) mustEmbedUnimplementedVersionServiceServer() {} + +// UnsafeVersionServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to VersionServiceServer will +// result in compilation errors. +type UnsafeVersionServiceServer interface { + mustEmbedUnimplementedVersionServiceServer() +} + +func RegisterVersionServiceServer(s grpc.ServiceRegistrar, srv VersionServiceServer) { + s.RegisterService(&VersionService_ServiceDesc, srv) +} + +func _VersionService_Version_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(VersionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VersionServiceServer).Version(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/version.VersionService/Version", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VersionServiceServer).Version(ctx, req.(*VersionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// VersionService_ServiceDesc is the grpc.ServiceDesc for VersionService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var VersionService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "version.VersionService", + HandlerType: (*VersionServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Version", + Handler: _VersionService_Version_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "version.proto", +} diff --git a/pkg/api/grpc/version_test.go b/pkg/api/grpc/version_test.go new file mode 100644 index 000000000..7cdbc21a3 --- /dev/null +++ b/pkg/api/grpc/version_test.go @@ -0,0 +1,72 @@ +package grpc + +import ( + "context" + "fmt" + "log" + "net" + "regexp" + "testing" + + "github.com/stefanprodan/podinfo/pkg/api/grpc/version" + v "github.com/stefanprodan/podinfo/pkg/version" + "google.golang.org/grpc" + "google.golang.org/grpc/status" + "google.golang.org/grpc/test/bufconn" +) + +func TestGrpcVersion(t *testing.T) { + + // Server initialization + // bufconn => uses in-memory connection instead of system network I/O + lis := bufconn.Listen(1024*1024) + t.Cleanup(func() { + lis.Close() + }) + + + srv := grpc.NewServer() + t.Cleanup(func() { + srv.Stop() + }) + + version.RegisterVersionServiceServer(srv, &VersionServer{}) + + go func(){ + if err := srv.Serve(lis); err != nil { + log.Fatalf("srv.Serve %v", err) + } + }() + + // - Test + dialer := func(context.Context, string) (net.Conn, error){ + return lis.Dial() + } + + ctx := context.Background() + + conn, err := grpc.DialContext(ctx, "", grpc.WithContextDialer(dialer), grpc.WithInsecure()) + t.Cleanup(func() { + conn.Close() + }) + + if err != nil { + t.Fatalf("grpc.DialContext %v", err) + } + + client := version.NewVersionServiceClient(conn) + res , err := client.Version(context.Background(), &version.VersionRequest{}) + + // Check the status code is what we expect. + if _, ok := status.FromError(err); !ok { + t.Errorf("Version returned type %T, want %T", err, status.Error) + } + + // Check the response body is what we expect. + expected := fmt.Sprintf(".*%s.*", v.VERSION) + r := regexp.MustCompile(expected) + if !r.MatchString(res.String()) { + t.Fatalf("Returned unexpected body:\ngot \n%v \nwant \n%s", + res, expected) + } +} \ No newline at end of file diff --git a/pkg/api/cache.go b/pkg/api/http/cache.go similarity index 99% rename from pkg/api/cache.go rename to pkg/api/http/cache.go index ac6787377..228e858dd 100644 --- a/pkg/api/cache.go +++ b/pkg/api/http/cache.go @@ -1,4 +1,4 @@ -package api +package http import ( "fmt" diff --git a/pkg/api/chunked.go b/pkg/api/http/chunked.go similarity index 98% rename from pkg/api/chunked.go rename to pkg/api/http/chunked.go index 0bf668e97..f8b7b69d2 100644 --- a/pkg/api/chunked.go +++ b/pkg/api/http/chunked.go @@ -1,4 +1,4 @@ -package api +package http import ( "math/rand" diff --git a/pkg/api/chunked_test.go b/pkg/api/http/chunked_test.go similarity index 98% rename from pkg/api/chunked_test.go rename to pkg/api/http/chunked_test.go index 090dd2fef..167b3b170 100644 --- a/pkg/api/chunked_test.go +++ b/pkg/api/http/chunked_test.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/configs.go b/pkg/api/http/configs.go similarity index 96% rename from pkg/api/configs.go rename to pkg/api/http/configs.go index 9b084153a..fb8bbebc5 100644 --- a/pkg/api/configs.go +++ b/pkg/api/http/configs.go @@ -1,4 +1,4 @@ -package api +package http import "net/http" diff --git a/pkg/api/delay.go b/pkg/api/http/delay.go similarity index 99% rename from pkg/api/delay.go rename to pkg/api/http/delay.go index 6655cf754..19893b053 100644 --- a/pkg/api/delay.go +++ b/pkg/api/http/delay.go @@ -1,4 +1,4 @@ -package api +package http import ( "math/rand" diff --git a/pkg/api/delay_test.go b/pkg/api/http/delay_test.go similarity index 98% rename from pkg/api/delay_test.go rename to pkg/api/http/delay_test.go index 88d5ab717..9309692da 100644 --- a/pkg/api/delay_test.go +++ b/pkg/api/http/delay_test.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/docs/docs.go b/pkg/api/http/docs/docs.go similarity index 100% rename from pkg/api/docs/docs.go rename to pkg/api/http/docs/docs.go diff --git a/pkg/api/docs/swagger.json b/pkg/api/http/docs/swagger.json similarity index 100% rename from pkg/api/docs/swagger.json rename to pkg/api/http/docs/swagger.json diff --git a/pkg/api/docs/swagger.yaml b/pkg/api/http/docs/swagger.yaml similarity index 100% rename from pkg/api/docs/swagger.yaml rename to pkg/api/http/docs/swagger.yaml diff --git a/pkg/api/echo.go b/pkg/api/http/echo.go similarity index 99% rename from pkg/api/echo.go rename to pkg/api/http/echo.go index 5bf7d8ff1..e2447ecff 100644 --- a/pkg/api/echo.go +++ b/pkg/api/http/echo.go @@ -1,4 +1,4 @@ -package api +package http import ( "bytes" diff --git a/pkg/api/echo_test.go b/pkg/api/http/echo_test.go similarity index 99% rename from pkg/api/echo_test.go rename to pkg/api/http/echo_test.go index 74e472a07..056e3b99a 100644 --- a/pkg/api/echo_test.go +++ b/pkg/api/http/echo_test.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/echows.go b/pkg/api/http/echows.go similarity index 99% rename from pkg/api/echows.go rename to pkg/api/http/echows.go index bcf693c3f..d92abcbd7 100644 --- a/pkg/api/echows.go +++ b/pkg/api/http/echows.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/env.go b/pkg/api/http/env.go similarity index 97% rename from pkg/api/env.go rename to pkg/api/http/env.go index c9951ccf0..e664bc375 100644 --- a/pkg/api/env.go +++ b/pkg/api/http/env.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/env_test.go b/pkg/api/http/env_test.go similarity index 98% rename from pkg/api/env_test.go rename to pkg/api/http/env_test.go index 0d53ce689..79c08bcff 100644 --- a/pkg/api/env_test.go +++ b/pkg/api/http/env_test.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/headers.go b/pkg/api/http/headers.go similarity index 97% rename from pkg/api/headers.go rename to pkg/api/http/headers.go index 2cc995a90..311108f56 100644 --- a/pkg/api/headers.go +++ b/pkg/api/http/headers.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/headers_test.go b/pkg/api/http/headers_test.go similarity index 98% rename from pkg/api/headers_test.go rename to pkg/api/http/headers_test.go index 8a7b37fc6..59cf8530a 100644 --- a/pkg/api/headers_test.go +++ b/pkg/api/http/headers_test.go @@ -1,4 +1,4 @@ -package api +package http import ( "fmt" diff --git a/pkg/api/health.go b/pkg/api/http/health.go similarity index 99% rename from pkg/api/health.go rename to pkg/api/http/health.go index 61742ec5c..a1631c4ae 100644 --- a/pkg/api/health.go +++ b/pkg/api/http/health.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/health_test.go b/pkg/api/http/health_test.go similarity index 98% rename from pkg/api/health_test.go rename to pkg/api/http/health_test.go index 646ff0518..d34625d4d 100644 --- a/pkg/api/health_test.go +++ b/pkg/api/http/health_test.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/http.go b/pkg/api/http/http.go similarity index 99% rename from pkg/api/http.go rename to pkg/api/http/http.go index 0061bb79e..360a525c2 100644 --- a/pkg/api/http.go +++ b/pkg/api/http/http.go @@ -1,4 +1,4 @@ -package api +package http import ( "bytes" diff --git a/pkg/api/index.go b/pkg/api/http/index.go similarity index 98% rename from pkg/api/index.go rename to pkg/api/http/index.go index a501dea82..158557628 100644 --- a/pkg/api/index.go +++ b/pkg/api/http/index.go @@ -1,4 +1,4 @@ -package api +package http import ( "html/template" diff --git a/pkg/api/info.go b/pkg/api/http/info.go similarity index 99% rename from pkg/api/info.go rename to pkg/api/http/info.go index 2cd4f4738..c4e82371f 100644 --- a/pkg/api/info.go +++ b/pkg/api/http/info.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/info_test.go b/pkg/api/http/info_test.go similarity index 98% rename from pkg/api/info_test.go rename to pkg/api/http/info_test.go index c076be91c..e1883da2d 100644 --- a/pkg/api/info_test.go +++ b/pkg/api/http/info_test.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/logging.go b/pkg/api/http/logging.go similarity index 97% rename from pkg/api/logging.go rename to pkg/api/http/logging.go index 47e5c2b54..c67b4123e 100644 --- a/pkg/api/logging.go +++ b/pkg/api/http/logging.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/metrics.go b/pkg/api/http/metrics.go similarity index 99% rename from pkg/api/metrics.go rename to pkg/api/http/metrics.go index c45c86fe6..f85ae41f8 100644 --- a/pkg/api/metrics.go +++ b/pkg/api/http/metrics.go @@ -1,4 +1,4 @@ -package api +package http import ( "bufio" diff --git a/pkg/api/mock.go b/pkg/api/http/mock.go similarity index 98% rename from pkg/api/mock.go rename to pkg/api/http/mock.go index 75629194f..244649c2b 100644 --- a/pkg/api/mock.go +++ b/pkg/api/http/mock.go @@ -1,4 +1,4 @@ -package api +package http import ( "time" diff --git a/pkg/api/panic.go b/pkg/api/http/panic.go similarity index 95% rename from pkg/api/panic.go rename to pkg/api/http/panic.go index 3ca5fc38e..fbf151db1 100644 --- a/pkg/api/panic.go +++ b/pkg/api/http/panic.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/server.go b/pkg/api/http/server.go similarity index 99% rename from pkg/api/server.go rename to pkg/api/http/server.go index b4224f45b..4eabe32d9 100644 --- a/pkg/api/server.go +++ b/pkg/api/http/server.go @@ -1,4 +1,4 @@ -package api +package http import ( "context" @@ -14,7 +14,7 @@ import ( "github.com/gomodule/redigo/redis" "github.com/gorilla/mux" "github.com/prometheus/client_golang/prometheus/promhttp" - _ "github.com/stefanprodan/podinfo/pkg/api/docs" + _ "github.com/stefanprodan/podinfo/pkg/api/http/docs" "github.com/stefanprodan/podinfo/pkg/fscache" httpSwagger "github.com/swaggo/http-swagger" "github.com/swaggo/swag" diff --git a/pkg/api/status.go b/pkg/api/http/status.go similarity index 98% rename from pkg/api/status.go rename to pkg/api/http/status.go index e9e33ae0c..1ccd4d045 100644 --- a/pkg/api/status.go +++ b/pkg/api/http/status.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/status_test.go b/pkg/api/http/status_test.go similarity index 97% rename from pkg/api/status_test.go rename to pkg/api/http/status_test.go index f85f2b2ca..3c8fda9b0 100644 --- a/pkg/api/status_test.go +++ b/pkg/api/http/status_test.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/store.go b/pkg/api/http/store.go similarity index 99% rename from pkg/api/store.go rename to pkg/api/http/store.go index a97db5e85..307fb8b21 100644 --- a/pkg/api/store.go +++ b/pkg/api/http/store.go @@ -1,4 +1,4 @@ -package api +package http import ( "crypto/sha1" diff --git a/pkg/api/token.go b/pkg/api/http/token.go similarity index 99% rename from pkg/api/token.go rename to pkg/api/http/token.go index c39186039..cb1cbb7fb 100644 --- a/pkg/api/token.go +++ b/pkg/api/http/token.go @@ -1,4 +1,4 @@ -package api +package http import ( "fmt" diff --git a/pkg/api/token_test.go b/pkg/api/http/token_test.go similarity index 98% rename from pkg/api/token_test.go rename to pkg/api/http/token_test.go index a82824b7c..f8d194ebc 100644 --- a/pkg/api/token_test.go +++ b/pkg/api/http/token_test.go @@ -1,4 +1,4 @@ -package api +package http import ( "encoding/json" diff --git a/pkg/api/tracer.go b/pkg/api/http/tracer.go similarity index 99% rename from pkg/api/tracer.go rename to pkg/api/http/tracer.go index ec7c208b7..8d9fbdae3 100644 --- a/pkg/api/tracer.go +++ b/pkg/api/http/tracer.go @@ -1,4 +1,4 @@ -package api +package http import ( "context" diff --git a/pkg/api/version.go b/pkg/api/http/version.go similarity index 97% rename from pkg/api/version.go rename to pkg/api/http/version.go index 037691e74..828234764 100644 --- a/pkg/api/version.go +++ b/pkg/api/http/version.go @@ -1,4 +1,4 @@ -package api +package http import ( "net/http" diff --git a/pkg/api/version_test.go b/pkg/api/http/version_test.go similarity index 98% rename from pkg/api/version_test.go rename to pkg/api/http/version_test.go index e7ee256e8..eba9fa71c 100644 --- a/pkg/api/version_test.go +++ b/pkg/api/http/version_test.go @@ -1,4 +1,4 @@ -package api +package http import ( "fmt" diff --git a/pkg/grpc/server.go b/pkg/grpc/server.go deleted file mode 100644 index 3de371f51..000000000 --- a/pkg/grpc/server.go +++ /dev/null @@ -1,52 +0,0 @@ -package grpc - -import ( - "fmt" - "net" - - "go.uber.org/zap" - "google.golang.org/grpc" - "google.golang.org/grpc/health" - "google.golang.org/grpc/health/grpc_health_v1" - "google.golang.org/grpc/reflection" -) - -type Server struct { - logger *zap.Logger - config *Config -} - -type Config struct { - Port int `mapstructure:"grpc-port"` - ServiceName string `mapstructure:"grpc-service-name"` -} - -func NewServer(config *Config, logger *zap.Logger) (*Server, error) { - srv := &Server{ - logger: logger, - config: config, - } - - return srv, nil -} - -func (s *Server) ListenAndServe() *grpc.Server { - listener, err := net.Listen("tcp", fmt.Sprintf(":%v", s.config.Port)) - if err != nil { - s.logger.Fatal("failed to listen", zap.Int("port", s.config.Port)) - } - - srv := grpc.NewServer() - server := health.NewServer() - reflection.Register(srv) - grpc_health_v1.RegisterHealthServer(srv, server) - server.SetServingStatus(s.config.ServiceName, grpc_health_v1.HealthCheckResponse_SERVING) - - go func() { - if err := srv.Serve(listener); err != nil { - s.logger.Fatal("failed to serve", zap.Error(err)) - } - }() - - return srv -}