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/backup"
|
||||||
"github.com/alcionai/corso/cli/config"
|
"github.com/alcionai/corso/cli/config"
|
||||||
|
"github.com/alcionai/corso/cli/help"
|
||||||
"github.com/alcionai/corso/cli/print"
|
"github.com/alcionai/corso/cli/print"
|
||||||
"github.com/alcionai/corso/cli/repo"
|
"github.com/alcionai/corso/cli/repo"
|
||||||
"github.com/alcionai/corso/cli/restore"
|
"github.com/alcionai/corso/cli/restore"
|
||||||
@ -65,6 +66,7 @@ func BuildCommandTree(cmd *cobra.Command) {
|
|||||||
repo.AddCommands(cmd)
|
repo.AddCommands(cmd)
|
||||||
backup.AddCommands(cmd)
|
backup.AddCommands(cmd)
|
||||||
restore.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
|
// 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
|
// output to stdout the list of printable structs in a table
|
||||||
func outputTable(w io.Writer, ps []Printable) {
|
func outputTable(w io.Writer, ps []Printable) {
|
||||||
t := table.Table{
|
t := table.Table{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user