add the corso env command for env var guidance (#591)

This commit is contained in:
Keepers 2022-08-18 13:09:25 -06:00 committed by GitHub
parent 3ac05acf64
commit 91e5c3d90c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 144 additions and 0 deletions

View File

@ -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
View 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
View 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)
}

View File

@ -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{