package main import ( "context" "encoding/json" "fmt" "os" "time" "git.wntrmute.dev/kyle/mcias/client" "github.com/spf13/cobra" "github.com/spf13/viper" ) var ( dbUsername string dbToken string useStored bool databaseID string outputJSON bool ) var databaseCmd = &cobra.Command{ Use: "database", Short: "Manage database credentials", Long: `Commands for managing database credentials in the MCIAS system.`, } var getCredentialsCmd = &cobra.Command{ Use: "credentials", Short: "Get database credentials", Long: `Retrieve database credentials from the MCIAS system. This command requires authentication with a username and token. If database-id is provided, it returns credentials for that specific database. If database-id is not provided, it returns the first database the user has access to.`, Run: func(_ *cobra.Command, args []string) { getCredentials() }, } var listCredentialsCmd = &cobra.Command{ Use: "list", Short: "List all accessible database credentials", Long: `List all database credentials the user has access to. This command requires authentication with a username and token.`, Run: func(_ *cobra.Command, args []string) { listCredentials() }, } func init() { rootCmd.AddCommand(databaseCmd) databaseCmd.AddCommand(getCredentialsCmd) databaseCmd.AddCommand(listCredentialsCmd) // Flags for getCredentialsCmd getCredentialsCmd.Flags().StringVarP(&dbUsername, "username", "u", "", "Username for authentication") getCredentialsCmd.Flags().StringVarP(&dbToken, "token", "t", "", "Authentication token") getCredentialsCmd.Flags().BoolVarP(&useStored, "use-stored", "s", false, "Use stored token from previous login") getCredentialsCmd.Flags().StringVarP(&databaseID, "database-id", "d", "", "ID of the specific database to retrieve") getCredentialsCmd.Flags().BoolVarP(&outputJSON, "json", "j", false, "Output in JSON format") // Flags for listCredentialsCmd listCredentialsCmd.Flags().StringVarP(&dbUsername, "username", "u", "", "Username for authentication") listCredentialsCmd.Flags().StringVarP(&dbToken, "token", "t", "", "Authentication token") listCredentialsCmd.Flags().BoolVarP(&useStored, "use-stored", "s", false, "Use stored token from previous login") listCredentialsCmd.Flags().BoolVarP(&outputJSON, "json", "j", false, "Output in JSON format") // Make username required only if not using stored token getCredentialsCmd.MarkFlagsMutuallyExclusive("token", "use-stored") listCredentialsCmd.MarkFlagsMutuallyExclusive("token", "use-stored") } // createClient creates and configures a new MCIAS client func createClient() *client.Client { // If using stored token, load it from the token file if useStored { tokenInfo, err := loadToken() if err != nil { fmt.Fprintf(os.Stderr, "Error loading token: %v\n", err) os.Exit(1) } dbUsername = tokenInfo.Username dbToken = tokenInfo.Token } // Validate required parameters if dbUsername == "" { fmt.Fprintf(os.Stderr, "Error: username is required\n") os.Exit(1) } if dbToken == "" { fmt.Fprintf(os.Stderr, "Error: token is required (either provide --token or use --use-stored)\n") os.Exit(1) } serverAddr := viper.GetString("server") if serverAddr == "" { serverAddr = "http://localhost:8080" } // Create a new client with the appropriate options c := client.NewClient( client.WithBaseURL(serverAddr), client.WithUsername(dbUsername), client.WithToken(dbToken), ) return c } func getCredentials() { // Create a new client c := createClient() // Create a context with timeout ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() // Get database credentials creds, err := c.GetDatabaseCredentials(ctx, databaseID) if err != nil { fmt.Fprintf(os.Stderr, "Error retrieving database credentials: %v\n", err) os.Exit(1) } // Output in JSON format if requested if outputJSON { jsonData, err := json.MarshalIndent(creds, "", " ") if err != nil { fmt.Fprintf(os.Stderr, "Error formatting JSON: %v\n", err) os.Exit(1) } fmt.Println(string(jsonData)) return } // Output in human-readable format fmt.Println("Database Credentials:") fmt.Printf("Host: %s\n", creds.Host) fmt.Printf("Port: %d\n", creds.Port) fmt.Printf("Name: %s\n", creds.Name) fmt.Printf("User: %s\n", creds.User) fmt.Printf("Password: %s\n", creds.Password) } func listCredentials() { // Create a new client c := createClient() // Create a context with timeout ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() // Get all database credentials credsList, err := c.GetDatabaseCredentialsList(ctx) if err != nil { fmt.Fprintf(os.Stderr, "Error retrieving database credentials: %v\n", err) os.Exit(1) } // Output in JSON format if requested if outputJSON { jsonData, err := json.MarshalIndent(credsList, "", " ") if err != nil { fmt.Fprintf(os.Stderr, "Error formatting JSON: %v\n", err) os.Exit(1) } fmt.Println(string(jsonData)) return } // Output in human-readable format fmt.Printf("Found %d database(s):\n\n", len(credsList)) for i, creds := range credsList { fmt.Printf("Database #%d:\n", i+1) fmt.Printf(" Host: %s\n", creds.Host) fmt.Printf(" Port: %d\n", creds.Port) fmt.Printf(" Name: %s\n", creds.Name) fmt.Printf(" User: %s\n", creds.User) fmt.Printf(" Password: %s\n", creds.Password) fmt.Println() } }