@@ -6,13 +6,13 @@ import (
66 "fmt"
77 "strings"
88
9- "github.com/AlecAivazis/survey/v2"
109 "github.com/apppackio/apppack/bridge"
1110 "github.com/apppackio/apppack/ui"
1211 "github.com/aws/aws-sdk-go-v2/aws"
1312 "github.com/aws/aws-sdk-go-v2/service/cloudformation/types"
1413 "github.com/aws/aws-sdk-go-v2/service/rds"
1514 rdstypes "github.com/aws/aws-sdk-go-v2/service/rds/types"
15+ "github.com/charmbracelet/huh"
1616 "github.com/sirupsen/logrus"
1717 "github.com/spf13/pflag"
1818)
@@ -275,12 +275,8 @@ func (a *DatabaseStack) UpdateFromFlags(flags *pflag.FlagSet) error {
275275}
276276
277277func (a * DatabaseStack ) AskQuestions (cfg aws.Config ) error {
278- var questions []* ui.QuestionExtra
279-
280278 var err error
281279
282- var aurora bool
283-
284280 if a .Stack == nil {
285281 err = AskForCluster (
286282 cfg ,
@@ -292,39 +288,19 @@ func (a *DatabaseStack) AskQuestions(cfg aws.Config) error {
292288 return err
293289 }
294290
295- questions = append (questions , []* ui.QuestionExtra {
296- {
297- Verbose : "What engine should this Database use?" ,
298- HelpText : "" ,
299- Question : & survey.Question {
300- Name : "Engine" ,
301- Prompt : & survey.Select {
302- Message : "Type" ,
303- Options : []string {"postgres" , "mysql" },
304- FilterMessage : "" ,
305- Default : "postgres" ,
306- },
307- Validate : survey .Required ,
308- },
309- },
310- {
311- Verbose : "Should this Database use the Aurora engine variant?" ,
312- HelpText : "Aurora provides many benefits over the standard engines, but is not available on very small instance sizes. For more info see https://aws.amazon.com/rds/aurora/." ,
313- WriteTo : & ui.BooleanOptionProxy {Value : & aurora },
314- Question : & survey.Question {
315- Prompt : & survey.Select {
316- Message : "Aurora" ,
317- Options : []string {"yes" , "no" },
318- FilterMessage : "" ,
319- Default : ui .BooleanAsYesNo (aurora ),
320- },
321- Validate : survey .Required ,
322- },
323- },
324- }... )
325- if err = ui .AskQuestions (questions , a .Parameters ); err != nil {
291+ // Engine prompt
292+ engineForm , enginePtr := DatabaseEngineForm (a .Parameters .Engine )
293+ if err = engineForm .Run (); err != nil {
294+ return err
295+ }
296+ a .Parameters .Engine = * enginePtr
297+
298+ // Aurora prompt
299+ auroraForm , auroraPtr := DatabaseAuroraForm (false )
300+ if err = auroraForm .Run (); err != nil {
326301 return err
327302 }
303+ aurora := ui .YesNoToBool (* auroraPtr )
328304
329305 ui .StartSpinner ()
330306
@@ -342,8 +318,6 @@ func (a *DatabaseStack) AskQuestions(cfg aws.Config) error {
342318 if err != nil {
343319 return err
344320 }
345-
346- questions = []* ui.QuestionExtra {}
347321 }
348322
349323 ui .StartSpinner ()
@@ -356,40 +330,123 @@ func (a *DatabaseStack) AskQuestions(cfg aws.Config) error {
356330
357331 ui .Spinner .Stop ()
358332 ui .Spinner .Suffix = ""
359- questions = append (questions , []* ui.QuestionExtra {
360- {
361- Verbose : "What instance class should be used for this Database?" ,
362- HelpText : "Enter the Database instance class. For more info see https://aws.amazon.com/rds/pricing/." ,
363- Question : & survey.Question {
364- Name : "InstanceClass" ,
365- Prompt : & survey.Select {
366- Message : "Instance Class" ,
367- Options : instanceClasses ,
368- FilterMessage : "" ,
369- Default : a .Parameters .InstanceClass ,
370- },
371- Validate : survey .Required ,
372- },
373- },
374- {
375- Verbose : "Should this Database be setup in multiple availability zones?" ,
376- HelpText : "Multiple availability zones (AZs) provide more resilience in the case of an AZ outage, " +
377- "but double the cost at AWS. In the case of Aurora databases, enabling multiple availability zones will give you access to a read-replica." +
378- "For more info see https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.MultiAZ.html." ,
379- WriteTo : & ui.BooleanOptionProxy {Value : & a .Parameters .MultiAZ },
380- Question : & survey.Question {
381- Prompt : & survey.Select {
382- Message : "Multi AZ" ,
383- Options : []string {"yes" , "no" },
384- FilterMessage : "" ,
385- Default : ui .BooleanAsYesNo (a .Parameters .MultiAZ ),
386- },
387- Validate : survey .Required ,
388- },
389- },
390- }... )
391-
392- return ui .AskQuestions (questions , a .Parameters )
333+
334+ // Instance class prompt
335+ instanceClassForm , instanceClassPtr := DatabaseInstanceClassForm (instanceClasses , a .Parameters .InstanceClass )
336+ if err = instanceClassForm .Run (); err != nil {
337+ return err
338+ }
339+ a .Parameters .InstanceClass = * instanceClassPtr
340+
341+ // Multi-AZ prompt
342+ multiAZForm , multiAZPtr := DatabaseMultiAZForm (a .Parameters .MultiAZ )
343+ if err = multiAZForm .Run (); err != nil {
344+ return err
345+ }
346+ a .Parameters .MultiAZ = ui .YesNoToBool (* multiAZPtr )
347+
348+ return nil
349+ }
350+
351+ // DatabaseEngineForm builds the interactive form for selecting the database engine.
352+ // Returns the form and a pointer to the selected engine value.
353+ func DatabaseEngineForm (defaultEngine string ) (* huh.Form , * string ) {
354+ if defaultEngine == "" {
355+ defaultEngine = "postgres"
356+ }
357+ selected := defaultEngine
358+
359+ options := []huh.Option [string ]{
360+ huh .NewOption ("postgres" , "postgres" ),
361+ huh .NewOption ("mysql" , "mysql" ),
362+ }
363+ if defaultEngine == "mysql" {
364+ options [1 ] = options [1 ].Selected (true )
365+ } else {
366+ options [0 ] = options [0 ].Selected (true )
367+ }
368+
369+ form := huh .NewForm (
370+ huh .NewGroup (
371+ huh .NewNote ().
372+ Title ("What engine should this Database use?" ),
373+ huh .NewSelect [string ]().
374+ Title ("Type" ).
375+ Options (options ... ).
376+ Value (& selected ),
377+ ),
378+ )
379+
380+ return form , & selected
381+ }
382+
383+ // DatabaseAuroraForm builds the interactive form for selecting Aurora mode.
384+ // Returns the form and a pointer to the selected "yes"/"no" value.
385+ func DatabaseAuroraForm (defaultAurora bool ) (* huh.Form , * string ) {
386+ selected := ui .BooleanAsYesNo (defaultAurora )
387+
388+ form := huh .NewForm (
389+ huh .NewGroup (
390+ huh .NewNote ().
391+ Title ("Should this Database use the Aurora engine variant?" ).
392+ Description ("Aurora provides many benefits over the standard engines, but is not available on very small\n instance sizes. For more info see https://aws.amazon.com/rds/aurora/." ),
393+ huh .NewSelect [string ]().
394+ Title ("Aurora" ).
395+ Options (ui .YesNoOptions (defaultAurora )... ).
396+ Value (& selected ),
397+ ),
398+ )
399+
400+ return form , & selected
401+ }
402+
403+ // DatabaseInstanceClassForm builds the interactive form for selecting a database instance class.
404+ // Returns the form and a pointer to the selected instance class.
405+ func DatabaseInstanceClassForm (instanceClasses []string , defaultClass string ) (* huh.Form , * string ) {
406+ selected := defaultClass
407+
408+ options := make ([]huh.Option [string ], len (instanceClasses ))
409+ for i , c := range instanceClasses {
410+ opt := huh .NewOption (c , c )
411+ if c == defaultClass {
412+ opt = opt .Selected (true )
413+ }
414+ options [i ] = opt
415+ }
416+
417+ form := huh .NewForm (
418+ huh .NewGroup (
419+ huh .NewNote ().
420+ Title ("What instance class should be used for this Database?" ).
421+ Description ("Enter the Database instance class. For more info see https://aws.amazon.com/rds/pricing/." ),
422+ huh .NewSelect [string ]().
423+ Title ("Instance Class" ).
424+ Options (options ... ).
425+ Value (& selected ),
426+ ),
427+ )
428+
429+ return form , & selected
430+ }
431+
432+ // DatabaseMultiAZForm builds the interactive form for selecting multi-AZ mode.
433+ // Returns the form and a pointer to the selected "yes"/"no" value.
434+ func DatabaseMultiAZForm (defaultMultiAZ bool ) (* huh.Form , * string ) {
435+ selected := ui .BooleanAsYesNo (defaultMultiAZ )
436+
437+ form := huh .NewForm (
438+ huh .NewGroup (
439+ huh .NewNote ().
440+ Title ("Should this Database be setup in multiple availability zones?" ).
441+ Description ("Multiple availability zones (AZs) provide more resilience in the case of an AZ outage,\n but double the cost at AWS. In the case of Aurora databases, enabling multiple availability\n zones will give you access to a read-replica. For more info see\n https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.MultiAZ.html." ),
442+ huh .NewSelect [string ]().
443+ Title ("Multi AZ" ).
444+ Options (ui .YesNoOptions (defaultMultiAZ )... ).
445+ Value (& selected ),
446+ ),
447+ )
448+
449+ return form , & selected
393450}
394451
395452func (* DatabaseStack ) StackName (name * string ) * string {
0 commit comments