Skip to content

Commit 874037a

Browse files
committed
sync(cmd/access): pull from indent core
GitOrigin-RevId: 945ecd7e32ab5e9f8d9dae3be32f76544c3faf5a
1 parent b2ce589 commit 874037a

File tree

4 files changed

+156
-2
lines changed

4 files changed

+156
-2
lines changed

cmd/access/cmd/root.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
configcmd "go.indent.com/access/cmd/access/cmd/config"
1010
"go.indent.com/access/cmd/access/cmd/petitions"
1111
"go.indent.com/access/cmd/access/cmd/resources"
12+
"go.indent.com/access/cmd/access/cmd/tokens"
1213
"go.indent.com/indent-go/pkg/cliutil"
1314
)
1415

@@ -25,12 +26,16 @@ func NewRoot(logger *zap.Logger) *cobra.Command {
2526
rootCmd.AddCommand(configcmd.NewCmdConfig(f))
2627
rootCmd.AddCommand(petitions.NewCmdPetitions(f))
2728
rootCmd.AddCommand(resources.NewCmdResources(f))
29+
rootCmd.AddCommand(tokens.NewCmdTokens(f))
2830

2931
flags := rootCmd.PersistentFlags()
3032
flags.StringVarP(&config.Space, "space", "s", config.Space, "Space to perform operations in")
3133
flags.BoolVar(&config.Staging, "staging", config.Staging, "Use staging environment for request")
3234
flags.BoolVarP(&config.Verbose, "verbose", "v", config.Verbose, "Include debug messages and additional context in logs")
3335
flags.BoolVar(&config.Headless, "headless", config.Headless, "Run in headless mode (no browser login prompt)")
34-
f.Setup()
36+
37+
rootCmd.PersistentPreRun = func(cmd *cobra.Command, args []string) {
38+
f.Setup()
39+
}
3540
return rootCmd
3641
}

cmd/access/cmd/tokens/create.go

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
package tokens
2+
3+
import (
4+
"context"
5+
"strconv"
6+
7+
"github.com/spf13/cobra"
8+
"go.uber.org/zap"
9+
10+
indentv1 "go.indent.com/indent-go/api/indent/v1"
11+
"go.indent.com/indent-go/pkg/cliutil"
12+
"go.indent.com/indent-go/pkg/common"
13+
)
14+
15+
const (
16+
// defaultServiceAccount is the default service account to use when creating tokens.
17+
defaultServiceAccount = "access-cli-default-service-account"
18+
19+
// defaultServiceAccountDisplayName is the default service account display name to use when creating tokens.
20+
defaultServiceAccountDisplayName = "Default Service Account"
21+
22+
// defaultExpiryDays is the default number of days until a token expires.
23+
defaultExpiryDays = 25
24+
)
25+
26+
// NewCreateOptions returns a CreateOptions with the defaults set.
27+
func NewCreateOptions() *CreateOptions {
28+
return &CreateOptions{
29+
CreateTokenRequest: new(indentv1.CreateTokenRequest),
30+
}
31+
}
32+
33+
// CreateOptions defines how a token is created.
34+
type CreateOptions struct {
35+
*indentv1.CreateTokenRequest
36+
37+
// CreateAccessToken indicates that an access token should be created.
38+
CreateAccessToken bool
39+
}
40+
41+
// NewCmdCreate returns a command that creates tokens.
42+
func NewCmdCreate(f cliutil.Factory) *cobra.Command {
43+
opts := NewCreateOptions()
44+
cmd := &cobra.Command{
45+
Use: "create [service_account]",
46+
Short: "Creates new refresh tokens",
47+
Long: `Creates new refresh tokens for a service account`,
48+
Run: func(cmd *cobra.Command, args []string) {
49+
logger := f.Logger()
50+
client := f.API(cmd.Context()).Accounts()
51+
52+
opts.ServiceAccountId = serviceAccountID(cmd.Context(), logger, f, client, args)
53+
logger = logger.With(zap.Uint64("serviceAccountID", opts.ServiceAccountId))
54+
55+
logger.Debug("Creating token")
56+
opts.SpaceName = f.Config().Space
57+
token, err := client.CreateToken(cmd.Context(), opts.CreateTokenRequest)
58+
if err != nil {
59+
logger.Fatal("Failed to create token", zap.Error(err))
60+
}
61+
62+
logger = logger.With(zap.String("refreshToken", token.GetRefreshToken()))
63+
logger.Info("Refresh token created")
64+
65+
if opts.CreateAccessToken {
66+
logger.Debug("Creating access token")
67+
tokenClient := f.API(cmd.Context()).Tokens()
68+
accessToken, err := tokenClient.ExchangeToken(cmd.Context(), &indentv1.ExchangeTokenRequest{
69+
RefreshToken: token.GetRefreshToken(),
70+
})
71+
if err != nil {
72+
logger.Fatal("Failed to create access token", zap.Error(err))
73+
}
74+
75+
logger = logger.With(zap.String("accessToken", accessToken.GetAccessToken()))
76+
logger.Info("Access token created")
77+
}
78+
},
79+
}
80+
81+
flags := cmd.Flags()
82+
flags.Uint64Var(&opts.ExpiryDays, "expiry-days", defaultExpiryDays, "Number of days until token expires")
83+
flags.BoolVar(&opts.CreateAccessToken, "access-token", false, "Create an access token also")
84+
return cmd
85+
}
86+
87+
func serviceAccountID(ctx context.Context, logger *zap.Logger, f cliutil.Factory, client indentv1.AccountAPIClient,
88+
args []string) (svcAccountID uint64) {
89+
var err error
90+
if len(args) != 0 {
91+
if svcAccountID, err = strconv.ParseUint(args[0], common.Base10, common.BitSize64); err != nil {
92+
logger.Fatal("Failed to parse service account ID", zap.Error(err))
93+
}
94+
}
95+
96+
// if service account is specified, use it
97+
if svcAccountID != 0 {
98+
return svcAccountID
99+
}
100+
101+
// use default service account if none specified
102+
logger.Debug("Looking up default service account")
103+
space := f.Config().Space
104+
var resp *indentv1.ListServiceAccountsResponse
105+
if resp, err = client.ListServicesAccounts(ctx, &indentv1.ListServiceAccountsRequest{
106+
SpaceName: space,
107+
}); err != nil {
108+
logger.Fatal("Failed to list service accounts", zap.Error(err))
109+
}
110+
111+
for _, serviceAccount := range resp.GetAccounts() {
112+
meta := serviceAccount.GetMeta()
113+
if meta.GetSpace() == space && meta.GetName() == defaultServiceAccount {
114+
return serviceAccount.GetServiceAccountId()
115+
}
116+
}
117+
118+
logger.Debug("Creating default service account")
119+
var svcAcct *indentv1.ServiceAccount
120+
if svcAcct, err = client.CreateServiceAccount(ctx, &indentv1.CreateServiceAccountRequest{
121+
SpaceName: space,
122+
Name: defaultServiceAccount,
123+
DisplayName: defaultServiceAccountDisplayName,
124+
}); err != nil {
125+
logger.Fatal("Failed to create default service account", zap.Error(err))
126+
}
127+
svcAccountID = svcAcct.GetServiceAccountId()
128+
logger.Debug("Default service account created", zap.Uint64("svcAccountID", svcAccountID))
129+
return svcAccountID
130+
}

cmd/access/cmd/tokens/tokens.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Package tokens is a command to manage tokens.
2+
package tokens
3+
4+
import (
5+
"github.com/spf13/cobra"
6+
7+
"go.indent.com/indent-go/pkg/cliutil"
8+
)
9+
10+
// NewCmdTokens returns a set of commands used to manage tokens.
11+
func NewCmdTokens(f cliutil.Factory) *cobra.Command {
12+
cmd := &cobra.Command{
13+
Use: "tokens",
14+
Aliases: []string{"t"},
15+
Short: "Manage tokens",
16+
}
17+
cmd.AddCommand(NewCmdCreate(f))
18+
return cmd
19+
}

cmd/access/logger.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66
)
77

88
func newLogger() *zap.Logger {
9-
cfg := zap.NewProductionConfig()
9+
cfg := zap.NewDevelopmentConfig()
1010
cfg.DisableCaller = true
1111
cfg.DisableStacktrace = true
1212
cfg.Encoding = "console"

0 commit comments

Comments
 (0)