175 lines
4.2 KiB
Go
175 lines
4.2 KiB
Go
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
|
|
}
|
|
|
|
func NewService(config *Config) (*CloudServer, error) {
|
|
esxClients := make(map[string]*esx.Client)
|
|
|
|
for k := range config.Zones {
|
|
zone, _ := config.Zones[k]
|
|
|
|
client, err := esx.NewClientFromConfig(&zone)
|
|
if err != nil {
|
|
return nil, 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,
|
|
}
|
|
|
|
return cloudServer, nil
|
|
}
|