esxlib/service/service.go

121 lines
2.8 KiB
Go
Raw Normal View History

2023-06-24 19:57:08 +00:00
package service
import (
"context"
"fmt"
"net"
"os"
"esxlib/api/cloud"
"esxlib/esx"
"esxlib/pkg/utils"
"git.twelvetwelve.org/library/core/log"
"github.com/madflojo/testcerts"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
)
type CloudServer struct {
cloud.UnimplementedCloudServer
esx map[string]*esx.Client
config *Config
}
var authorizedTokens = map[string]string{}
func unaryInterceptor(ctx context.Context, req interface{}, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
// Auth is not enabled on the server
if len(authorizedTokens) == 0 {
return handler(ctx, req)
}
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
log.Debugf("no metadata\n")
return nil, status.Errorf(codes.Unauthenticated, "Unauthenticated access")
}
values := md["authorization"]
if len(values) == 0 {
log.Debugf("no authorization %+v\n", values)
return nil, status.Errorf(codes.Unauthenticated, "Unauthenticated access")
}
for _, v := range values {
if _, ok := authorizedTokens[v]; ok {
return handler(ctx, req)
}
}
log.Debugf("no authorization %+v\n", md)
return nil, status.Errorf(codes.Unauthenticated, "Unauthenticated access")
}
func Run(configFile string) error {
config := &Config{}
if err := utils.UnmarshalFromFile(configFile, config); err != nil {
return err
}
esxClients := make(map[string]*esx.Client)
for k := range config.Zones {
zone, _ := config.Zones[k]
client, err := esx.NewClientFromConfig(&zone)
if err != nil {
return err
}
esxClients[k] = client
}
lis, err := net.Listen("tcp", config.ListenAddress)
if err != nil {
panic(err)
}
// TLS: Generate TLS if not provided
if config.TLS.CertPath == "" && config.TLS.KeyPath == "" {
config.TLS.CertPath, config.TLS.KeyPath, err = testcerts.GenerateCertsToTempFile("/tmp/")
if err != nil {
return err
}
fmt.Printf("Creating credentials... %s:%s\n", config.TLS.CertPath, config.TLS.KeyPath)
defer os.Remove(config.TLS.CertPath)
defer os.Remove(config.TLS.KeyPath)
}
// generate local certs
creds, err := credentials.NewServerTLSFromFile(config.TLS.CertPath, config.TLS.KeyPath)
if err != nil {
log.Fatalf("Failed to setup TLS: %v\n", err)
}
var grpcServer *grpc.Server
if config.Token != "" {
fmt.Printf("Need token: %s\n", config.Token)
authorizedTokens[config.Token] = config.Token
grpcServer = grpc.NewServer(grpc.Creds(creds), grpc.UnaryInterceptor(unaryInterceptor))
} else {
grpcServer = grpc.NewServer(grpc.Creds(creds))
}
cloudServer := CloudServer{
esx: esxClients,
config: config,
}
cloud.RegisterCloudServer(grpcServer, &cloudServer)
log.Printf("server listening at %v\n", lis.Addr())
if err := grpcServer.Serve(lis); err != nil {
return err
}
return nil
}