🎉 Initial Commit
Some checks failed
release-nightly / build-docker (push) Has been cancelled

This commit is contained in:
2024-07-14 20:25:30 +08:00
commit 466b240e95
41 changed files with 4312 additions and 0 deletions

45
pkg/internal/grpc/auth.go Normal file
View File

@@ -0,0 +1,45 @@
package grpc
import (
"context"
"fmt"
"git.solsynth.dev/hydrogen/dealer/pkg/internal/directory"
"git.solsynth.dev/hydrogen/dealer/pkg/proto"
"time"
)
func (v *Server) Authenticate(ctx context.Context, request *proto.AuthRequest) (*proto.AuthReply, error) {
instance := directory.GetServiceInstanceByType(directory.ServiceTypeAuthProvider)
if instance == nil {
return &proto.AuthReply{}, fmt.Errorf("no available service %s found", directory.ServiceTypeAuthProvider)
}
conn, err := instance.GetGrpcConn()
if err != nil {
return nil, fmt.Errorf("service is down: %v", err)
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
out, err := proto.NewAuthClient(conn).Authenticate(ctx, request)
return out, err
}
func (v *Server) EnsurePermGranted(ctx context.Context, request *proto.CheckPermRequest) (*proto.CheckPermReply, error) {
instance := directory.GetServiceInstanceByType(directory.ServiceTypeAuthProvider)
if instance == nil {
return &proto.CheckPermReply{}, fmt.Errorf("no available service %s found", directory.ServiceTypeAuthProvider)
}
conn, err := instance.GetGrpcConn()
if err != nil {
return nil, fmt.Errorf("service is down: %v", err)
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
out, err := proto.NewAuthClient(conn).EnsurePermGranted(ctx, request)
return out, err
}

View File

@@ -0,0 +1,26 @@
package grpc
import (
"context"
health "google.golang.org/grpc/health/grpc_health_v1"
"time"
)
func (v *Server) Check(ctx context.Context, request *health.HealthCheckRequest) (*health.HealthCheckResponse, error) {
return &health.HealthCheckResponse{
Status: health.HealthCheckResponse_SERVING,
}, nil
}
func (v *Server) Watch(request *health.HealthCheckRequest, server health.Health_WatchServer) error {
for {
if server.Send(&health.HealthCheckResponse{
Status: health.HealthCheckResponse_SERVING,
}) != nil {
break
}
time.Sleep(1000 * time.Millisecond)
}
return nil
}

View File

@@ -0,0 +1,43 @@
package grpc
import (
"git.solsynth.dev/hydrogen/dealer/pkg/proto"
"net"
"google.golang.org/grpc/reflection"
"github.com/spf13/viper"
"google.golang.org/grpc"
health "google.golang.org/grpc/health/grpc_health_v1"
)
type Server struct {
proto.UnimplementedServiceDirectoryServer
proto.UnimplementedAuthServer
srv *grpc.Server
}
func NewServer() *Server {
server := &Server{
srv: grpc.NewServer(),
}
proto.RegisterServiceDirectoryServer(server.srv, &Server{})
proto.RegisterAuthServer(server.srv, &Server{})
health.RegisterHealthServer(server.srv, &Server{})
reflection.Register(server.srv)
return server
}
func (v *Server) Listen() error {
listener, err := net.Listen("tcp", viper.GetString("grpc_bind"))
if err != nil {
return err
}
return v.srv.Serve(listener)
}

View File

@@ -0,0 +1,70 @@
package grpc
import (
"context"
"fmt"
"git.solsynth.dev/hydrogen/dealer/pkg/internal/directory"
"git.solsynth.dev/hydrogen/dealer/pkg/proto"
"github.com/samber/lo"
)
func warpServiceInstanceToInfo(in *directory.ServiceInstance) *proto.ServiceInfo {
return &proto.ServiceInfo{
Id: in.ID,
Type: in.Type,
Label: in.Label,
GrpcAddr: in.GrpcAddr,
HttpAddr: in.HttpAddr,
}
}
func (v *Server) GetService(ctx context.Context, request *proto.GetServiceRequest) (*proto.GetServiceResponse, error) {
if request.Id != nil {
out := directory.GetServiceInstance(request.GetId())
return &proto.GetServiceResponse{
Data: warpServiceInstanceToInfo(out),
}, nil
}
if request.Type != nil {
out := directory.GetServiceInstanceByType(request.GetType())
return &proto.GetServiceResponse{
Data: warpServiceInstanceToInfo(out),
}, nil
}
return nil, fmt.Errorf("no filter condition is provided")
}
func (v *Server) ListService(ctx context.Context, request *proto.ListServiceRequest) (*proto.ListServiceResponse, error) {
var out []*directory.ServiceInstance
if request.Type != nil {
out = directory.ListServiceInstanceByType(request.GetType())
} else {
out = directory.ListServiceInstance()
}
return &proto.ListServiceResponse{
Data: lo.Map(out, func(item *directory.ServiceInstance, index int) *proto.ServiceInfo {
return warpServiceInstanceToInfo(item)
}),
}, nil
}
func (v *Server) AddService(ctx context.Context, info *proto.ServiceInfo) (*proto.AddServiceResponse, error) {
in := &directory.ServiceInstance{
ID: info.GetId(),
Type: info.GetType(),
Label: info.GetLabel(),
GrpcAddr: info.GetGrpcAddr(),
HttpAddr: info.HttpAddr,
}
directory.AddServiceInstance(in)
return &proto.AddServiceResponse{
IsSuccess: true,
}, nil
}
func (v *Server) RemoveService(ctx context.Context, request *proto.RemoveServiceRequest) (*proto.RemoveServiceResponse, error) {
directory.RemoveServiceInstance(request.GetId())
return &proto.RemoveServiceResponse{
IsSuccess: true,
}, nil
}