add the corso env command for env var guidance (#591)
This commit is contained in:
parent
3ac05acf64
commit
91e5c3d90c
@ -8,6 +8,7 @@ import (
|
||||
|
||||
"github.com/alcionai/corso/cli/backup"
|
||||
"github.com/alcionai/corso/cli/config"
|
||||
"github.com/alcionai/corso/cli/help"
|
||||
"github.com/alcionai/corso/cli/print"
|
||||
"github.com/alcionai/corso/cli/repo"
|
||||
"github.com/alcionai/corso/cli/restore"
|
||||
@ -65,6 +66,7 @@ func BuildCommandTree(cmd *cobra.Command) {
|
||||
repo.AddCommands(cmd)
|
||||
backup.AddCommands(cmd)
|
||||
restore.AddCommands(cmd)
|
||||
help.AddCommands(cmd)
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
||||
100
src/cli/help/env.go
Normal file
100
src/cli/help/env.go
Normal file
@ -0,0 +1,100 @@
|
||||
package help
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
. "github.com/alcionai/corso/cli/print"
|
||||
)
|
||||
|
||||
// AddCommands attaches all `corso env * *` commands to the parent.
|
||||
func AddCommands(parent *cobra.Command) {
|
||||
parent.AddCommand(envCmd())
|
||||
}
|
||||
|
||||
// The env command: purely a help display.
|
||||
// `corso env [--help]`
|
||||
func envCmd() *cobra.Command {
|
||||
envCmd := &cobra.Command{
|
||||
Use: "env",
|
||||
Short: "env var guide",
|
||||
Long: `A guide to using environment variables in Corso.`,
|
||||
RunE: handleEnvCmd,
|
||||
Args: cobra.NoArgs,
|
||||
}
|
||||
envCmd.SetHelpFunc(envGuide)
|
||||
return envCmd
|
||||
}
|
||||
|
||||
// Handler for flat calls to `corso env`.
|
||||
// Produces the same output as `corso env --help`.
|
||||
func handleEnvCmd(cmd *cobra.Command, args []string) error {
|
||||
return cmd.Help()
|
||||
}
|
||||
|
||||
type envVar struct {
|
||||
category string
|
||||
name string
|
||||
description string
|
||||
}
|
||||
|
||||
// interface compliance check
|
||||
var _ Printable = &envVar{}
|
||||
|
||||
// no modifications needed, just passthrough.
|
||||
func (ev envVar) MinimumPrintable() any {
|
||||
return ev
|
||||
}
|
||||
|
||||
func (ev envVar) Headers() []string {
|
||||
return []string{ev.category, " "}
|
||||
}
|
||||
|
||||
func (ev envVar) Values() []string {
|
||||
return []string{ev.name, ev.description}
|
||||
}
|
||||
|
||||
// headers
|
||||
const (
|
||||
corso = "Corso"
|
||||
azure = "Azure AD App Credentials"
|
||||
aws = "AWS Credentials"
|
||||
)
|
||||
|
||||
var (
|
||||
corsoEVs = []envVar{
|
||||
{corso, "CORSO_PASSWORD", "Passphrase to protect repository encryption material." +
|
||||
"It is impossible to use the repository or recover any backups without this key."},
|
||||
}
|
||||
azureEVs = []envVar{
|
||||
{azure, "CLIENT_ID", "Client ID for your Azure AD application used to access your M365 tenant."},
|
||||
{azure, "CLIENT_SECRET", "Azure secret for your Azure AD application used to access your M365 tenant."},
|
||||
}
|
||||
awsEVs = []envVar{
|
||||
{aws, "AWS_ACCESS_KEY_ID", "AWS access key for an IAM user or role for accessing S3 bucket repository."},
|
||||
{aws, "AWS_SECRET_ACCESS_KEY", "Secret key associated with the access key."},
|
||||
{aws, "AWS_SESSION_TOKEN", "Session token required when using temporary credentials."},
|
||||
}
|
||||
)
|
||||
|
||||
func toPrintable(evs []envVar) []Printable {
|
||||
ps := []Printable{}
|
||||
for _, ev := range evs {
|
||||
ps = append(ps, ev)
|
||||
}
|
||||
return ps
|
||||
}
|
||||
|
||||
// envGuide outputs a help menu for setting env vars in Corso.
|
||||
func envGuide(cmd *cobra.Command, args []string) {
|
||||
ctx := cmd.Context()
|
||||
Info(ctx,
|
||||
"\n--- Environment Variable Guide ---\n",
|
||||
"As a best practice, Corso retrieves credentials and sensitive information from environment variables.\n ",
|
||||
"\n",
|
||||
)
|
||||
Table(ctx, toPrintable(corsoEVs))
|
||||
Info(ctx, "\n")
|
||||
Table(ctx, toPrintable(azureEVs))
|
||||
Info(ctx, "\n")
|
||||
Table(ctx, toPrintable(awsEVs))
|
||||
}
|
||||
36
src/cli/help/env_test.go
Normal file
36
src/cli/help/env_test.go
Normal file
@ -0,0 +1,36 @@
|
||||
package help
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/alcionai/corso/internal/tester"
|
||||
)
|
||||
|
||||
type EnvSuite struct {
|
||||
suite.Suite
|
||||
}
|
||||
|
||||
func TestEnvSuite(t *testing.T) {
|
||||
suite.Run(t, new(EnvSuite))
|
||||
}
|
||||
|
||||
func (suite *EnvSuite) TestAddEnvCommands() {
|
||||
t := suite.T()
|
||||
cmd := &cobra.Command{Use: "root"}
|
||||
|
||||
AddCommands(cmd)
|
||||
c := envCmd()
|
||||
require.NotNil(t, c)
|
||||
|
||||
cmds := cmd.Commands()
|
||||
require.Len(t, cmds, 1)
|
||||
|
||||
assert.Equal(t, "env", c.Use)
|
||||
assert.Equal(t, envCmd().Short, c.Short)
|
||||
tester.AreSameFunc(t, handleEnvCmd, c.RunE)
|
||||
}
|
||||
@ -155,6 +155,12 @@ func printAll(w io.Writer, ps []Printable) {
|
||||
// Tabular
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
||||
// Table writes the printables in a tabular format. Takes headers from
|
||||
// the 0th printable only.
|
||||
func Table(ctx context.Context, ps []Printable) {
|
||||
outputTable(getRootCmd(ctx).OutOrStdout(), ps)
|
||||
}
|
||||
|
||||
// output to stdout the list of printable structs in a table
|
||||
func outputTable(w io.Writer, ps []Printable) {
|
||||
t := table.Table{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user