initial WIP
This commit is contained in:
parent
a197b0f03b
commit
36848a5095
5 changed files with 1053 additions and 0 deletions
127
scaler/grpcproxy.go
Normal file
127
scaler/grpcproxy.go
Normal file
|
@ -0,0 +1,127 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
|
||||
"github.com/mwitkow/grpc-proxy/proxy"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"google.golang.org/grpc/metadata"
|
||||
)
|
||||
|
||||
var director proxy.StreamDirector
|
||||
|
||||
func main() {
|
||||
// director = func(ctx context.Context, fullMethodName string) (context.Context, *grpc.ClientConn, error) {
|
||||
// // Make sure we never forward internal services.
|
||||
// if strings.HasPrefix(fullMethodName, "/com.example.internal.") {
|
||||
// return nil, nil, status.Errorf(codes.Unimplemented, "Unknown method")
|
||||
// }
|
||||
// md, ok := metadata.FromIncomingContext(ctx)
|
||||
// // Copy the inbound metadata explicitly.
|
||||
// outCtx := metadata.NewOutgoingContext(ctx, md.Copy())
|
||||
// if ok {
|
||||
// // Decide on which backend to dial
|
||||
// if val, exists := md[":authority"]; exists && val[0] == "staging.api.example.com" {
|
||||
// // Make sure we use DialContext so the dialing can be cancelled/time out together with the context.
|
||||
// conn, err := grpc.DialContext(ctx, "api-service.staging.svc.local")
|
||||
// return outCtx, conn, err
|
||||
// } else if val, exists := md[":authority"]; exists && val[0] == "api.example.com" {
|
||||
// conn, err := grpc.DialContext(ctx, "api-service.prod.svc.local")
|
||||
// return outCtx, conn, err
|
||||
// }
|
||||
// }
|
||||
// return nil, nil, status.Errorf(codes.Unimplemented, "Unknown method")
|
||||
// }
|
||||
|
||||
// director.
|
||||
fmt.Println(test())
|
||||
}
|
||||
|
||||
func test() error {
|
||||
socketPath := "/state/home/projects/workbench/26-headscale-tailnets/headscale.sock"
|
||||
|
||||
// // Connect to Unix socket
|
||||
// dst, err := grpc.Dial(
|
||||
// "unix://"+socketPath,
|
||||
// grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||
// )
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// defer dst.Close()
|
||||
|
||||
// Connect to TCP address instead of socket
|
||||
dst, err := grpc.Dial(
|
||||
"localhost:8081",
|
||||
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer dst.Close()
|
||||
|
||||
// Create proxy with director
|
||||
director := func(ctx context.Context, fullMethodName string) (context.Context, *grpc.ClientConn, error) {
|
||||
log.Printf("Director called for method: %s", fullMethodName)
|
||||
|
||||
// Extract incoming metadata/headers
|
||||
md, ok := metadata.FromIncomingContext(ctx)
|
||||
if ok {
|
||||
log.Printf("Forwarding headers: %v", md)
|
||||
|
||||
// Extract the intended host from :authority header
|
||||
if authority := md.Get(":authority"); len(authority) > 0 {
|
||||
log.Printf("Intended host: %s", authority[0])
|
||||
}
|
||||
|
||||
// Also check for host header (HTTP/1.1 style)
|
||||
if host := md.Get("host"); len(host) > 0 {
|
||||
log.Printf("Host header: %s", host[0])
|
||||
}
|
||||
|
||||
// Forward headers to outgoing context
|
||||
ctx = metadata.NewOutgoingContext(ctx, md)
|
||||
}
|
||||
|
||||
return ctx, dst, nil
|
||||
}
|
||||
|
||||
// Create gRPC server with proxy handler
|
||||
server := grpc.NewServer(
|
||||
grpc.CustomCodec(proxy.Codec()),
|
||||
grpc.UnknownServiceHandler(proxy.TransparentHandler(director)),
|
||||
)
|
||||
|
||||
// Listen on TCP
|
||||
lis, err := net.Listen("tcp", ":8090")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("gRPC proxy listening on :8090, forwarding to %s", socketPath)
|
||||
return server.Serve(lis)
|
||||
}
|
||||
|
||||
// func test2() error {
|
||||
// dst, err := grpc.Dial("example.com")
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// proxy := proxy.NewProxy(dst)
|
||||
|
||||
// grpc.Dia
|
||||
|
||||
// ip, err := net.ListenIP("tcp", "127.0.0.1")
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// proxy.Serve(ip)
|
||||
|
||||
// return nil
|
||||
|
||||
// }
|
152
scaler/main.go
Normal file
152
scaler/main.go
Normal file
|
@ -0,0 +1,152 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/netip"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/juanfont/headscale/hscontrol"
|
||||
"github.com/juanfont/headscale/hscontrol/types"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
fmt.Println("starting headscale")
|
||||
// go func() {
|
||||
fmt.Println(test(ctx))
|
||||
// }()
|
||||
|
||||
return
|
||||
startTime := time.Now()
|
||||
for {
|
||||
if time.Now().Sub(startTime) > 4*time.Second {
|
||||
fmt.Println("stopping headscale")
|
||||
cancel()
|
||||
|
||||
time.Sleep(2 * time.Second)
|
||||
break
|
||||
}
|
||||
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
func test(ctx context.Context) error {
|
||||
configPath := "orig-headscale.yaml"
|
||||
// viper.SetConfigFile(configPath)
|
||||
types.LoadConfig(configPath, true)
|
||||
|
||||
ncfg, err := types.LoadServerConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("%+v\n", ncfg)
|
||||
|
||||
return nil
|
||||
// dump config
|
||||
cfg, err := configHS()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// b, err := yaml.Marshal(cfg)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
// if err := os.WriteFile("config.yaml", b, 0666); err != nil {
|
||||
// return err
|
||||
// }
|
||||
return startHS(ctx, cfg)
|
||||
}
|
||||
|
||||
func configHS() (types.Config, error) {
|
||||
ipv4prefix, err := netip.ParsePrefix("100.64.0.0/10")
|
||||
if err != nil {
|
||||
return types.Config{}, err
|
||||
}
|
||||
|
||||
ipv6prefix, err := netip.ParsePrefix("fd7a:115c:a1e0::/48")
|
||||
if err != nil {
|
||||
return types.Config{}, err
|
||||
}
|
||||
|
||||
derpURL, err := url.Parse("https://controlplane.tailscale.com/derpmap/default")
|
||||
if err != nil {
|
||||
return types.Config{}, err
|
||||
}
|
||||
|
||||
cfg := types.Config{
|
||||
Addr: "127.0.0.1:8080", // listen_addr
|
||||
GRPCAddr: "127.0.0.1:8081",
|
||||
MetricsAddr: "127.0.0.1:8082",
|
||||
GRPCAllowInsecure: true,
|
||||
Log: types.LogConfig{
|
||||
Format: "text",
|
||||
// Level: zerolog.InfoLevel,
|
||||
Level: zerolog.TraceLevel,
|
||||
},
|
||||
Policy: types.PolicyConfig{
|
||||
Mode: types.PolicyMode("file"),
|
||||
},
|
||||
PrefixV4: &ipv4prefix,
|
||||
PrefixV6: &ipv6prefix,
|
||||
|
||||
EphemeralNodeInactivityTimeout: 30 * time.Minute,
|
||||
|
||||
DisableUpdateCheck: true,
|
||||
|
||||
NoisePrivateKeyPath: "noise.key",
|
||||
|
||||
Database: types.DatabaseConfig{
|
||||
Type: "sqlite3",
|
||||
Sqlite: types.SqliteConfig{
|
||||
Path: "db.sqlite",
|
||||
WriteAheadLog: true,
|
||||
},
|
||||
},
|
||||
|
||||
DERP: types.DERPConfig{
|
||||
AutoUpdate: true,
|
||||
ServerPrivateKeyPath: "depr_server_private.key",
|
||||
UpdateFrequency: 24 * time.Hour,
|
||||
URLs: []url.URL{*derpURL},
|
||||
},
|
||||
DNSConfig: types.DNSConfig{
|
||||
BaseDomain: "tailnet.fricloud.dk",
|
||||
MagicDNS: true,
|
||||
},
|
||||
|
||||
Tuning: types.Tuning{
|
||||
NotifierSendTimeout: 1 * time.Second,
|
||||
BatchChangeDelay: 1 * time.Second,
|
||||
},
|
||||
|
||||
UnixSocket: "headscale.sock",
|
||||
UnixSocketPermission: 0700,
|
||||
|
||||
// cli things
|
||||
CLI: types.CLIConfig{
|
||||
Address: "",
|
||||
// APIKey: "lol",
|
||||
Timeout: 2 * time.Second,
|
||||
Insecure: true,
|
||||
},
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func startHS(ctx context.Context, cfg types.Config) error {
|
||||
hs, err := hscontrol.NewHeadscale(&cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return hs.Serve(ctx)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue