121 lines
2.8 KiB
Go
121 lines
2.8 KiB
Go
package cli
|
|
|
|
import (
|
|
"bufio"
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
"syscall"
|
|
|
|
"github.com/spf13/cobra"
|
|
"golang.org/x/term"
|
|
|
|
"github.com/user/aevs/internal/config"
|
|
"github.com/user/aevs/internal/storage"
|
|
)
|
|
|
|
var configCmd = &cobra.Command{
|
|
Use: "config",
|
|
Short: "Configure storage credentials",
|
|
Long: `Interactive configuration of S3-compatible storage credentials.`,
|
|
RunE: runConfig,
|
|
}
|
|
|
|
func runConfig(cmd *cobra.Command, args []string) error {
|
|
reader := bufio.NewReader(os.Stdin)
|
|
|
|
fmt.Println()
|
|
fmt.Println("AEVS Configuration")
|
|
fmt.Println("==================")
|
|
fmt.Println()
|
|
|
|
// Storage type
|
|
storageType := promptWithDefault(reader, "Storage type", config.DefaultStorageType)
|
|
|
|
// Endpoint
|
|
endpoint := promptWithDefault(reader, "S3 Endpoint", config.DefaultEndpoint)
|
|
|
|
// Region
|
|
region := promptWithDefault(reader, "AWS Region", config.DefaultRegion)
|
|
|
|
// Bucket name
|
|
bucket := prompt(reader, "Bucket name")
|
|
if bucket == "" {
|
|
return fmt.Errorf("bucket name is required")
|
|
}
|
|
|
|
// Access key
|
|
accessKey := prompt(reader, "Access Key ID")
|
|
if accessKey == "" {
|
|
return fmt.Errorf("access key is required")
|
|
}
|
|
|
|
// Secret key (hidden)
|
|
fmt.Print("Secret Access Key: ")
|
|
secretKeyBytes, err := term.ReadPassword(int(syscall.Stdin))
|
|
fmt.Println()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to read secret key: %w", err)
|
|
}
|
|
secretKey := string(secretKeyBytes)
|
|
if secretKey == "" {
|
|
return fmt.Errorf("secret key is required")
|
|
}
|
|
|
|
// Create config
|
|
cfg := &config.GlobalConfig{
|
|
Storage: config.StorageConfig{
|
|
Type: storageType,
|
|
Endpoint: endpoint,
|
|
Region: region,
|
|
Bucket: bucket,
|
|
AccessKey: accessKey,
|
|
SecretKey: secretKey,
|
|
},
|
|
}
|
|
|
|
// Test connection
|
|
fmt.Println()
|
|
fmt.Println("Testing connection...")
|
|
|
|
s3Storage, err := storage.NewS3Storage(&cfg.Storage)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create storage client: %w", err)
|
|
}
|
|
|
|
ctx := context.Background()
|
|
if err := s3Storage.TestConnection(ctx); err != nil {
|
|
return fmt.Errorf("connection test failed: %w", err)
|
|
}
|
|
|
|
fmt.Printf("✓ Successfully connected to s3://%s\n", bucket)
|
|
fmt.Println()
|
|
|
|
// Save config
|
|
if err := config.SaveGlobalConfig(cfg); err != nil {
|
|
return fmt.Errorf("failed to save config: %w", err)
|
|
}
|
|
|
|
fmt.Printf("Config saved to %s\n", config.GlobalConfigPath())
|
|
return nil
|
|
}
|
|
|
|
// prompt reads a line from stdin
|
|
func prompt(reader *bufio.Reader, question string) string {
|
|
fmt.Printf("%s: ", question)
|
|
answer, _ := reader.ReadString('\n')
|
|
return strings.TrimSpace(answer)
|
|
}
|
|
|
|
// promptWithDefault reads a line from stdin with a default value
|
|
func promptWithDefault(reader *bufio.Reader, question, defaultValue string) string {
|
|
fmt.Printf("%s (%s): ", question, defaultValue)
|
|
answer, _ := reader.ReadString('\n')
|
|
answer = strings.TrimSpace(answer)
|
|
if answer == "" {
|
|
return defaultValue
|
|
}
|
|
return answer
|
|
}
|