Skip to content

Commit f8269b5

Browse files
sync(cmd/access): pull from indent core (#6)
* sync(cmd/access): pull from indent core GitOrigin-RevId: e777d23c52da3b8d77432be71d5917d3c1ce8548 * update indent-go to v1.0.2 --------- Co-authored-by: Dan Gillespie <dan@indent.com>
1 parent 84dad55 commit f8269b5

File tree

9 files changed

+174
-918
lines changed

9 files changed

+174
-918
lines changed

cmd/access/cmd/auth/login.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ func NewCmdLogin(f cliutil.Factory) *cobra.Command {
2121
opts.OAuth = f.Config().Environment.OAuth
2222

2323
store := f.Store()
24-
if err := store.Login(cmd.Context(), opts); err != nil {
24+
if err := store.Login(opts); err != nil {
2525
logger.Fatal("Failed to login", zap.Error(err))
26-
} else if err = store.UpdateUserInfo(cmd.Context()); err != nil {
26+
} else if err = store.UpdateUserInfo(); err != nil {
2727
logger.Fatal("Failed to get userinfo", zap.Error(err))
2828
}
2929
logger.Info("Login successful")

cmd/access/cmd/new.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package cmd
2+
3+
import (
4+
"github.com/spf13/cobra"
5+
"go.uber.org/zap"
6+
7+
petitionscmd "go.indent.com/access/cmd/access/cmd/petitions"
8+
"go.indent.com/indent-go/pkg/cliutil"
9+
)
10+
11+
// NewCmdNew returns a command that interactively creates a Petition.
12+
func NewCmdNew(f cliutil.Factory) *cobra.Command {
13+
cmd := &cobra.Command{
14+
Use: "new",
15+
Short: "Request access",
16+
Long: "Interactively create a Petition to request access to a Resource",
17+
Run: func(cmd *cobra.Command, args []string) {
18+
logger := f.Logger()
19+
createCmd := petitionscmd.NewCmdCreate(f)
20+
createCmd.SetContext(cmd.Context())
21+
if err := createCmd.Flags().Set("interactive", "true"); err != nil {
22+
logger.Fatal("failed to set interactive flag", zap.Error(err))
23+
}
24+
createCmd.Run(createCmd, nil)
25+
},
26+
}
27+
return cmd
28+
}

cmd/access/cmd/petitions/create.go

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
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.
3335
type 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+
}

cmd/access/cmd/petitions/list.go

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,19 @@ import (
88
"go.indent.com/indent-go/pkg/cliutil"
99
)
1010

11-
const (
12-
numPetitionsList = 20
13-
)
11+
// NewListOptions returns a new ListOptions.
12+
func NewListOptions() *ListOptions {
13+
return &ListOptions{}
14+
}
15+
16+
// ListOptions are the options for listing Petitions.
17+
type ListOptions struct {
18+
Output string
19+
}
1420

1521
// NewCmdList returns a command allowing users to list Petitions.
1622
func NewCmdList(f cliutil.Factory) *cobra.Command {
23+
opts := NewListOptions()
1724
cmd := &cobra.Command{
1825
Use: "list",
1926
Short: "List Petitions",
@@ -29,15 +36,23 @@ func NewCmdList(f cliutil.Factory) *cobra.Command {
2936
logger.Fatal("Failed to list Petitions", zap.Error(err))
3037
}
3138

32-
for i, pet := range petitions.GetPetitions() {
33-
logger.Info("Petition", zap.Any("petition", pet))
39+
if opts.Output == cliutil.OutputJSON {
40+
f.OutputJSON(petitions)
41+
return
42+
}
3443

35-
if i > numPetitionsList {
36-
break
37-
}
44+
s, err := cliutil.NewSelect(petitions.GetPetitions())
45+
if err != nil {
46+
logger.Fatal("Failed to create select", zap.Error(err))
47+
} else if result, err := s.Run(); err != nil {
48+
logger.Fatal("Failed to run select", zap.Error(err))
49+
} else {
50+
f.OutputJSON(result)
3851
}
3952
},
4053
}
4154

55+
flags := cmd.Flags()
56+
flags.StringVar(&opts.Output, "output", opts.Output, "Output format (can be 'json')")
4257
return cmd
4358
}

cmd/access/cmd/resources/list.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package resources
2+
3+
import (
4+
"github.com/spf13/cobra"
5+
6+
"go.indent.com/indent-go/pkg/cliutil"
7+
)
8+
9+
// NewListOptions returns a new ListOptions.
10+
func NewListOptions() *ListOptions {
11+
return &ListOptions{}
12+
}
13+
14+
// ListOptions are the options for listing Resources.
15+
type ListOptions struct {
16+
View string
17+
Output string
18+
}
19+
20+
// NewCmdList returns a command allowing users to list Resources.
21+
func NewCmdList(f cliutil.Factory) *cobra.Command {
22+
opts := NewListOptions()
23+
cmd := &cobra.Command{
24+
Use: "list",
25+
Short: "List Resources",
26+
Long: `List and filter Resources`,
27+
Run: func(cmd *cobra.Command, args []string) {
28+
if opts.Output == "json" {
29+
resources := f.Resources(cmd.Context(), opts.View)
30+
f.OutputJSON(resources)
31+
return
32+
}
33+
34+
// show prompt to select resource
35+
resource := f.SelectResource(cmd.Context(), "")
36+
f.OutputJSON(resource)
37+
},
38+
}
39+
40+
flags := cmd.Flags()
41+
flags.StringVar(&opts.View, "view", opts.View, "View to show")
42+
flags.StringVar(&opts.Output, "output", opts.Output, "Output format (can be 'json')")
43+
return cmd
44+
}

cmd/access/cmd/resources/resources.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ func NewCmdResources(f cliutil.Factory) *cobra.Command {
1616
such as pulling.`,
1717
}
1818
cmd.AddCommand(NewCmdCreate(f))
19+
cmd.AddCommand(NewCmdList(f))
1920
cmd.AddCommand(NewCmdPull(f))
2021
return cmd
2122
}

cmd/access/cmd/root.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ func NewRoot() *cobra.Command {
1919
}
2020
f, config := cliutil.New(rootCmd)
2121
rootCmd.AddCommand(NewCmdInit(f))
22+
rootCmd.AddCommand(NewCmdNew(f))
2223
rootCmd.AddCommand(auth.NewCmdAuth(f))
2324
rootCmd.AddCommand(configcmd.NewCmdConfig(f))
2425
rootCmd.AddCommand(petitions.NewCmdPetitions(f))
@@ -27,6 +28,7 @@ func NewRoot() *cobra.Command {
2728
flags := rootCmd.PersistentFlags()
2829
flags.StringVar(&config.Space, "space", config.Space, "Space to perform operations in")
2930
flags.BoolVar(&config.Staging, "staging", config.Staging, "Use staging environment for request")
31+
flags.BoolVar(&config.Headless, "headless", config.Headless, "Run in headless mode (no browser login prompt)")
3032
f.Setup()
3133
return rootCmd
3234
}

go.mod

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,17 @@ module go.indent.com/access
33
go 1.20
44

55
require (
6+
github.com/manifoldco/promptui v0.9.0
67
github.com/spf13/cobra v1.7.0
78
github.com/spf13/viper v1.15.0
8-
go.indent.com/indent-go v1.0.1
9+
go.indent.com/indent-go v1.0.2
910
go.uber.org/zap v1.24.0
1011
)
1112

1213
require (
1314
cloud.google.com/go/compute v1.14.0 // indirect
1415
cloud.google.com/go/compute/metadata v0.2.3 // indirect
16+
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect
1517
github.com/fsnotify/fsnotify v1.6.0 // indirect
1618
github.com/go-logr/logr v1.2.3 // indirect
1719
github.com/golang/protobuf v1.5.2 // indirect
@@ -27,9 +29,11 @@ require (
2729
github.com/subosito/gotenv v1.4.2 // indirect
2830
go.uber.org/atomic v1.9.0 // indirect
2931
go.uber.org/multierr v1.8.0 // indirect
32+
golang.org/x/crypto v0.1.0 // indirect
3033
golang.org/x/net v0.4.0 // indirect
3134
golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 // indirect
3235
golang.org/x/sys v0.3.0 // indirect
36+
golang.org/x/term v0.3.0 // indirect
3337
golang.org/x/text v0.5.0 // indirect
3438
google.golang.org/appengine v1.6.7 // indirect
3539
google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef // indirect

0 commit comments

Comments
 (0)