106 lines
2.3 KiB
Go
106 lines
2.3 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"crypto/rand"
|
|
"encoding/base64"
|
|
"errors"
|
|
"log"
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
|
|
"git.fossy.my.id/bagas/tunnel-please-controller/db/sqlc/repository"
|
|
"git.fossy.my.id/bagas/tunnel-please-controller/server"
|
|
"github.com/jackc/pgx/v5"
|
|
"github.com/joho/godotenv"
|
|
"github.com/lestrrat-go/httprc/v3"
|
|
"github.com/lestrrat-go/jwx/v3/jwk"
|
|
)
|
|
|
|
func main() {
|
|
if _, err := os.Stat(".env"); err == nil {
|
|
if err = godotenv.Load(".env"); err != nil {
|
|
log.Printf("Warning: Failed to load .env file: %s", err)
|
|
}
|
|
}
|
|
|
|
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
|
defer stop()
|
|
|
|
log.SetOutput(os.Stdout)
|
|
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
|
|
|
dbURL := os.Getenv("DATABASE_URL")
|
|
if dbURL == "" {
|
|
log.Fatal("DATABASE_URL is required")
|
|
}
|
|
|
|
controllerAddr := getenv("CONTROLLER_ADDR", ":8080")
|
|
apiAddr := getenv("API_ADDR", ":8081")
|
|
authToken := getenv("AUTH_TOKEN", "")
|
|
if authToken == "" {
|
|
authToken = generateAuthToken()
|
|
log.Printf("No AUTH_TOKEN provided. Generated token: %s", authToken)
|
|
}
|
|
|
|
connect, err := pgx.Connect(ctx, dbURL)
|
|
if err != nil {
|
|
panic(err)
|
|
return
|
|
}
|
|
defer func(connect *pgx.Conn, ctx context.Context) {
|
|
err = connect.Close(ctx)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}(connect, ctx)
|
|
|
|
repo := repository.New(connect)
|
|
client := httprc.NewClient()
|
|
jwkCache, err := jwk.NewCache(ctx, client)
|
|
if err != nil {
|
|
log.Printf("failed to initialize jwk cache : %s", err)
|
|
}
|
|
s := server.New(repo, authToken, jwkCache)
|
|
|
|
log.Printf("Listening controller on %s", controllerAddr)
|
|
log.Printf("Listening api on %s", apiAddr)
|
|
|
|
errCh := make(chan error, 2)
|
|
|
|
go func() {
|
|
if err = s.StartAPI(ctx, apiAddr); err != nil && !errors.Is(err, context.Canceled) {
|
|
errCh <- err
|
|
}
|
|
}()
|
|
|
|
go func() {
|
|
if err = s.StartController(ctx, controllerAddr); err != nil && !errors.Is(err, context.Canceled) {
|
|
errCh <- err
|
|
}
|
|
}()
|
|
|
|
select {
|
|
case <-ctx.Done():
|
|
log.Printf("shutting down: %v", ctx.Err())
|
|
case err = <-errCh:
|
|
log.Fatalf("server error: %v", err)
|
|
}
|
|
}
|
|
|
|
func getenv(key, def string) string {
|
|
if val := os.Getenv(key); val != "" {
|
|
return val
|
|
}
|
|
return def
|
|
}
|
|
|
|
func generateAuthToken() string {
|
|
buf := make([]byte, 32)
|
|
if _, err := rand.Read(buf); err != nil {
|
|
panic(err)
|
|
}
|
|
return base64.StdEncoding.EncodeToString(buf)
|
|
}
|