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 }