feat: sdk migration in progress

This commit is contained in:
allanice001
2025-11-02 13:19:30 +00:00
commit 0d10d42442
492 changed files with 71067 additions and 0 deletions

83
cmd/encryption.go Normal file
View File

@@ -0,0 +1,83 @@
package cmd
import (
"crypto/rand"
"encoding/base64"
"fmt"
"io"
"github.com/glueops/autoglue/internal/app"
"github.com/glueops/autoglue/internal/models"
"github.com/spf13/cobra"
)
var rotateMasterCmd = &cobra.Command{
Use: "rotate-master",
Short: "Generate and activate a new master encryption key",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
rt := app.NewRuntime()
db := rt.DB
key := make([]byte, 32)
if _, err := io.ReadFull(rand.Reader, key); err != nil {
return fmt.Errorf("generating random key: %w", err)
}
encoded := base64.StdEncoding.EncodeToString(key)
if err := db.Model(&models.MasterKey{}).
Where("is_active = ?", true).
Update("is_active", false).Error; err != nil {
return fmt.Errorf("deactivating previous key: %w", err)
}
if err := db.Create(&models.MasterKey{
Key: encoded,
IsActive: true,
}).Error; err != nil {
return fmt.Errorf("creating new master key: %w", err)
}
fmt.Println("Master key rotated successfully")
return nil
},
}
var createMasterCmd = &cobra.Command{
Use: "create-master",
Short: "Generate and activate a new master encryption key",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
rt := app.NewRuntime()
db := rt.DB
key := make([]byte, 32)
if _, err := io.ReadFull(rand.Reader, key); err != nil {
return fmt.Errorf("generating random key: %w", err)
}
encoded := base64.StdEncoding.EncodeToString(key)
if err := db.Create(&models.MasterKey{
Key: encoded,
IsActive: true,
}).Error; err != nil {
return fmt.Errorf("creating master key: %w", err)
}
fmt.Println("Master key created successfully")
return nil
},
}
var encryptCmd = &cobra.Command{
Use: "encrypt",
Short: "Manage autoglue encryption keys",
Long: "Manage autoglue master encryption keys used for securing data.",
}
func init() {
encryptCmd.AddCommand(rotateMasterCmd)
encryptCmd.AddCommand(createMasterCmd)
rootCmd.AddCommand(encryptCmd)
}

81
cmd/keys_generate.go Normal file
View File

@@ -0,0 +1,81 @@
package cmd
import (
"fmt"
"time"
"github.com/glueops/autoglue/internal/app"
"github.com/glueops/autoglue/internal/keys"
"github.com/spf13/cobra"
)
var (
alg string
rsaBits int
kidFlag string
nbfStr string
expStr string
)
var keysCmd = &cobra.Command{
Use: "keys",
Short: "Manage JWT signing keys",
}
var keysGenCmd = &cobra.Command{
Use: "generate",
Short: "Generate and store a new signing key",
RunE: func(_ *cobra.Command, _ []string) error {
rt := app.NewRuntime()
var nbfPtr, expPtr *time.Time
if nbfStr != "" {
t, err := time.Parse(time.RFC3339, nbfStr)
if err != nil {
return err
}
nbfPtr = &t
}
if expStr != "" {
t, err := time.Parse(time.RFC3339, expStr)
if err != nil {
return err
}
expPtr = &t
}
rec, err := keys.GenerateAndStore(rt.DB, rt.Cfg.JWTPrivateEncKey, keys.GenOpts{
Alg: alg,
Bits: rsaBits,
KID: kidFlag,
NBF: nbfPtr,
EXP: expPtr,
})
if err != nil {
return err
}
fmt.Printf("created signing key\n")
fmt.Printf(" kid: %s\n", rec.Kid)
fmt.Printf(" alg: %s\n", rec.Alg)
fmt.Printf(" active: %v\n", rec.IsActive)
if rec.NotBefore != nil {
fmt.Printf(" nbf: %s\n", rec.NotBefore.Format(time.RFC3339))
}
if rec.ExpiresAt != nil {
fmt.Printf(" exp: %s\n", rec.ExpiresAt.Format(time.RFC3339))
}
return nil
},
}
func init() {
rootCmd.AddCommand(keysCmd)
keysCmd.AddCommand(keysGenCmd)
keysGenCmd.Flags().StringVarP(&alg, "alg", "a", "EdDSA", "Signing alg: EdDSA|RS256|RS384|RS512")
keysGenCmd.Flags().IntVarP(&rsaBits, "bits", "b", 3072, "RSA key size (when alg is RS*)")
keysGenCmd.Flags().StringVarP(&kidFlag, "kid", "k", "", "Key ID (optional; auto if empty)")
keysGenCmd.Flags().StringVarP(&nbfStr, "nbf", "n", "", "Not Before (RFC3339)")
keysGenCmd.Flags().StringVarP(&expStr, "exp", "e", "", "Expires At (RFC3339)")
}

33
cmd/root.go Normal file
View File

@@ -0,0 +1,33 @@
package cmd
import (
"log"
"github.com/spf13/cobra"
)
var rootCmd = &cobra.Command{
Use: "autoglue",
Short: "Autoglue Kubernetes Cluster Management",
Long: "autoglue is used to manage the lifecycle of kubernetes clusters on GlueOps supported cloud providers",
Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 {
err := serveCmd.RunE(cmd, args)
if err != nil {
log.Fatal(err)
}
} else {
_ = cmd.Help()
}
},
}
func Execute() {
if err := rootCmd.Execute(); err != nil {
log.Fatal(err)
}
}
func init() {
cobra.OnInitialize()
}

94
cmd/serve.go Normal file
View File

@@ -0,0 +1,94 @@
package cmd
import (
"context"
"errors"
"fmt"
"log"
"net/http"
"os"
"os/signal"
"strings"
"syscall"
"time"
"github.com/glueops/autoglue/internal/api"
"github.com/glueops/autoglue/internal/app"
"github.com/glueops/autoglue/internal/auth"
"github.com/glueops/autoglue/internal/config"
"github.com/spf13/cobra"
)
var serveCmd = &cobra.Command{
Use: "serve",
Short: "Start API server",
RunE: func(_ *cobra.Command, _ []string) error {
rt := app.NewRuntime()
cfg, err := config.Load()
if err != nil {
return err
}
_ = auth.Refresh(rt.DB, rt.Cfg.JWTPrivateEncKey)
go func() {
t := time.NewTicker(60 * time.Second)
defer t.Stop()
for range t.C {
_ = auth.Refresh(rt.DB, rt.Cfg.JWTPrivateEncKey)
}
}()
r := api.NewRouter(rt.DB)
addr := fmt.Sprintf("%s:%s", cfg.Host, cfg.Port)
srv := &http.Server{
Addr: addr,
Handler: TimeoutExceptUpgrades(r, 60*time.Second, "request timed out"), // global safety
ReadTimeout: 15 * time.Second,
WriteTimeout: 60 * time.Second,
IdleTimeout: 120 * time.Second,
}
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
go func() {
fmt.Printf("🚀 API running on http://%s (ui.dev=%v)\n", addr, cfg.UIDev)
if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
log.Fatalf("server error: %v", err)
}
}()
<-ctx.Done()
fmt.Println("\n⏳ Shutting down...")
shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
return srv.Shutdown(shutdownCtx)
},
}
func init() {
rootCmd.AddCommand(serveCmd)
}
func TimeoutExceptUpgrades(next http.Handler, d time.Duration, msg string) http.Handler {
timeout := http.TimeoutHandler(next, d, msg)
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// If this is an upgrade (e.g., websocket), don't wrap.
if isUpgrade(r) {
next.ServeHTTP(w, r)
return
}
timeout.ServeHTTP(w, r)
})
}
func isUpgrade(r *http.Request) bool {
// Connection: Upgrade, Upgrade: websocket
if strings.Contains(strings.ToLower(r.Header.Get("Connection")), "upgrade") {
return true
}
return false
}

20
cmd/version.go Normal file
View File

@@ -0,0 +1,20 @@
package cmd
import (
"fmt"
"github.com/glueops/autoglue/internal/version"
"github.com/spf13/cobra"
)
var versionCmd = &cobra.Command{
Use: "version",
Short: "Show version information",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println(version.Info())
},
}
func init() {
rootCmd.AddCommand(versionCmd)
}