44 "context"
55 "fmt"
66
7+ "github.com/manifoldco/promptui"
78 "github.com/spf13/cobra"
89 "go.uber.org/zap"
910
@@ -26,13 +27,15 @@ func NewCreateOptions() *CreateOptions {
2627 },
2728 },
2829 },
30+ Output : cliutil .OutputJSON ,
2931 }
3032}
3133
3234// CreateOptions specify the Petition being created.
3335type CreateOptions struct {
3436 * indentv1.CreatePetitionRequest
3537 ResourceNames []string
38+ Interactive bool
3639 Output string
3740}
3841
@@ -56,9 +59,12 @@ func NewCmdCreate(f cliutil.Factory) *cobra.Command {
5659 },
5760 }
5861
59- // set petitioner
62+ // set petitioner and prompt for missing fields
6063 petitioner := f .CurrentUser (cmd .Context ())
6164 opts .Petition .Petitioners [0 ] = petitioner
65+ if len (opts .Petition .Reason ) < common .MinLenReason {
66+ opts .Petition .Reason = promptForReason (logger , opts )
67+ }
6268
6369 // create petition
6470 petition , err := client .CreatePetition (cmd .Context (), opts .CreatePetitionRequest )
@@ -70,28 +76,63 @@ func NewCmdCreate(f cliutil.Factory) *cobra.Command {
7076 // print output
7177 if opts .Output == "name" {
7278 fmt .Println (petition .Name )
79+ } else if opts .Output == cliutil .OutputJSON {
80+ f .OutputJSON (petition )
7381 }
7482 },
7583 }
7684
7785 flags := cmd .Flags ()
7886 flags .StringArrayVar (& opts .ResourceNames , "resources" , opts .ResourceNames , "names of resources being requested" )
79- flags .StringVar (& opts .Output , "output" , opts .Output , "format that should be output" )
87+ flags .BoolVar (& opts .Interactive , "interactive" , opts .Interactive , "whether to prompt for missing fields" )
88+ flags .StringVar (& opts .Output , "output" , opts .Output , "format that should be output (can be 'name' or 'json')" )
8089 flags .StringVar (& opts .Petition .Reason , "reason" , opts .Output , "reason Petition is being created" )
8190 return cmd
8291}
8392
84- func resolveResources (ctx context.Context , f cliutil.Factory , options * CreateOptions ) (resources []* auditv1.Resource ) {
93+ func resolveResources (ctx context.Context , f cliutil.Factory , opts * CreateOptions ) (resources []* auditv1.Resource ) {
94+ logger := f .Logger ()
95+
96+ // prompt for resource if interactive`
97+ if len (opts .ResourceNames ) == 0 {
98+ if ! opts .Interactive {
99+ logger .Fatal ("No resources specified and not interactive" )
100+ }
101+ resource := f .SelectResource (ctx , common .ViewRequestable )
102+ return []* auditv1.Resource {resource }
103+ }
104+
85105 client := f .API (ctx ).Resources ()
86- for _ , resourceName := range options .ResourceNames {
106+ for _ , resourceName := range opts .ResourceNames {
87107 resource , err := client .GetResource (ctx , & indentv1.GetResourceRequest {
88108 SpaceName : f .Config ().Space ,
89109 ResourceName : resourceName ,
90110 })
91111 if err != nil {
92- f . Logger () .Fatal ("Failed to resolve resource" , zap .Error (err ), zap .String ("resourceName" , resourceName ))
112+ logger .Fatal ("Failed to resolve resource" , zap .Error (err ), zap .String ("resourceName" , resourceName ))
93113 }
94114 resources = append (resources , resource )
95115 }
96116 return
97117}
118+
119+ func promptForReason (logger * zap.Logger , opts * CreateOptions ) string {
120+ if ! opts .Interactive {
121+ logger .Fatal ("Invalid reason specified and not interactive" , zap .String ("reason" , opts .Petition .Reason ))
122+ }
123+ prompt := & promptui.Prompt {
124+ Label : "Reason" ,
125+ Validate : func (s string ) error {
126+ if len (s ) < common .MinLenReason {
127+ return fmt .Errorf ("reason must be at least %d characters" , common .MinLenReason )
128+ }
129+ return nil
130+ },
131+ }
132+
133+ reason , err := prompt .Run ()
134+ if err != nil {
135+ logger .Fatal ("Failed to prompt for reason" , zap .Error (err ))
136+ }
137+ return reason
138+ }
0 commit comments