Skip to content

Commit

Permalink
use SSO name for config-profiles block
Browse files Browse the repository at this point in the history
Deal with users with multiple SSOConfig's and who use `config-profiles`
command.  We no longer will replace the previous config block in the
~/.aws/config file.
  • Loading branch information
synfinatic committed Jun 4, 2024
1 parent fb95df2 commit 83524fe
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 50 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

## [v1.16.0] - XXXX-XX-XX

### Changes

* `config-profiles` command now uses the name of the SSO for the block #696

### New Features

* Add credentials command #867
Expand Down
2 changes: 1 addition & 1 deletion cmd/aws-sso/config_profiles_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func (cc *ConfigProfilesCmd) Run(ctx *RunContext) error {
}

if action == url.ConfigProfilesUndef {
return fmt.Errorf("Please specify --open [clip|exec|open|granted-containers|open-url-in-container]")
return fmt.Errorf("%s", "please specify --open [clip|exec|open|granted-containers|open-url-in-container]")
}

urlAction, _ := url.NewAction(string(action))
Expand Down
7 changes: 4 additions & 3 deletions internal/awsconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func PrintAwsConfig(s *sso.Settings, action url.Action) error {
return err
}

f, err := utils.NewFileEdit(CONFIG_TEMPLATE, profiles)
f, err := utils.NewFileEdit(CONFIG_TEMPLATE, s.DefaultSSO, profiles)
if err != nil {
return err
}
Expand All @@ -71,13 +71,14 @@ func UpdateAwsConfig(s *sso.Settings, action url.Action, cfile string, diff, for
return err
}

f, err := utils.NewFileEdit(CONFIG_TEMPLATE, profiles)
f, err := utils.NewFileEdit(CONFIG_TEMPLATE, s.DefaultSSO, profiles)
if err != nil {
return err
}

oldConfig := AwsConfigFile(cfile)
return f.UpdateConfig(diff, force, oldConfig)
_, err = f.UpdateConfig(diff, force, oldConfig)
return err
}

// getProfileMap returns our validated sso.ProfileMap
Expand Down
10 changes: 6 additions & 4 deletions internal/helper/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,12 @@ func installConfigFile(path string, contents []byte) error {
"Executable": exec,
}

if fe, err = utils.NewFileEdit(string(contents), args); err != nil {
if fe, err = utils.NewFileEdit(string(contents), "", args); err != nil {
return err
}

if err = fe.UpdateConfig(false, false, path); err != nil {
_, err = fe.UpdateConfig(false, false, path)
if err != nil {
return err
}

Expand All @@ -194,11 +195,12 @@ func uninstallConfigFile(path string, contents []byte) error {
var err error
var fe *utils.FileEdit

if fe, err = utils.NewFileEdit("", ""); err != nil {
if fe, err = utils.NewFileEdit("", "", ""); err != nil {
return nil
}

if err = fe.UpdateConfig(false, false, path); err != nil {
_, err = fe.UpdateConfig(false, false, path)
if err != nil {
log.Warnf("unable to remove config: %s", err.Error())
}

Expand Down
32 changes: 20 additions & 12 deletions internal/utils/fileedit.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ import (
)

const (
CONFIG_PREFIX = "# BEGIN_AWS_SSO_CLI"
CONFIG_SUFFIX = "# END_AWS_SSO_CLI"
FILE_TEMPLATE = "%s\n%s\n%s\n"
DEFAULT_SSO_NAME = "Default" // DefaultSSO per cmd/aws-sso/main.go
CONFIG_PREFIX = "# BEGIN_AWS_SSO_CLI"
CONFIG_SUFFIX = "# END_AWS_SSO_CLI"
FILE_TEMPLATE = "%s\n%s\n%s\n"
)

type FileEdit struct {
Expand All @@ -62,11 +63,17 @@ func GenerateSource(fileTemplate string, vars interface{}) ([]byte, error) {
return buf.Bytes(), nil
}

func NewFileEdit(fileTemplate string, vars interface{}) (*FileEdit, error) {
func NewFileEdit(fileTemplate, ssoName string, vars interface{}) (*FileEdit, error) {
var t string

if fileTemplate != "" {
t = fmt.Sprintf(FILE_TEMPLATE, CONFIG_PREFIX, fileTemplate, CONFIG_SUFFIX)
prefix := CONFIG_PREFIX
suffix := CONFIG_SUFFIX
if ssoName != "" && ssoName != DEFAULT_SSO_NAME {
prefix = fmt.Sprintf("%s_%s", CONFIG_PREFIX, ssoName)
suffix = fmt.Sprintf("%s_%s", CONFIG_SUFFIX, ssoName)
}
t = fmt.Sprintf(FILE_TEMPLATE, prefix, fileTemplate, suffix)
}
templ, err := template.New("template").Parse(t)
if err != nil {
Expand All @@ -84,16 +91,17 @@ func NewFileEdit(fileTemplate string, vars interface{}) (*FileEdit, error) {
var diffWriter io.Writer = os.Stdout

// UpdateConfig does all the heavy lifting of updating (or creating) the file
// and optionally providing a diff for user to approve/view
func (f *FileEdit) UpdateConfig(printDiff, force bool, configFile string) error {
// and optionally providing a diff for user to approve/view. Returns true if
// changes were made, false if no changes were made, or an error if something happened
func (f *FileEdit) UpdateConfig(printDiff, force bool, configFile string) (bool, error) {
inputBytes, err := os.ReadFile(configFile)
if err != nil {
inputBytes = []byte{}
}

outputBytes, err := f.GenerateNewFile(configFile)
if err != nil {
return err
return false, err
}

newFile := fmt.Sprintf("%s.new", configFile)
Expand All @@ -103,22 +111,22 @@ func (f *FileEdit) UpdateConfig(printDiff, force bool, configFile string) error
if len(diff) == 0 {
// do nothing if there is no diff
log.Infof("no changes made to %s", configFile)
return nil
return false, nil
}

if !force {
approved, err := prompt(configFile, diff)
if err != nil {
return err
return false, err
}
if !approved {
return nil
return false, nil
}
} else if printDiff {
fmt.Fprintf(diffWriter, "%s", diff)
}

return os.WriteFile(configFile, outputBytes, 0600)
return true, os.WriteFile(configFile, outputBytes, 0600)
}

// GenerateNewFile generates the contents of a new config file
Expand Down
84 changes: 54 additions & 30 deletions internal/utils/fileedit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,47 +24,51 @@ import (
"os"
"testing"

"github.com/sirupsen/logrus"
"github.com/sirupsen/logrus/hooks/test"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestFileEditInvalid(t *testing.T) {
// invalid template
_, err := NewFileEdit("{{ .Test", "", map[string]string{})
assert.Error(t, err)
}

func TestFileEdit(t *testing.T) {
var err error
var fe *FileEdit
var output bytes.Buffer
diffWriter = &output
defer func() { diffWriter = os.Stdout }()

var template = "{{ .Test }}"
var vars = map[string]string{
"Test": "foo",
}

_, err = NewFileEdit("{{ .Test", vars)
assert.Error(t, err)

fe, err = NewFileEdit(template, vars)
var template = "{{ .Test }}"
fe, err = NewFileEdit(template, "test", vars)
assert.NoError(t, err)

tfile, err := os.CreateTemp("", "")
assert.NoError(t, err)
defer os.Remove(tfile.Name())
err = fe.UpdateConfig(true, true, tfile.Name())
changed, err := fe.UpdateConfig(true, true, tfile.Name())
assert.NoError(t, err)
assert.True(t, changed)
assert.NotEmpty(t, output)
tfile.Close()

prefix := fmt.Sprintf("%s_%s", CONFIG_PREFIX, "test")
suffix := fmt.Sprintf("%s_%s", CONFIG_SUFFIX, "test")
fBytes, err := os.ReadFile(tfile.Name())
assert.NoError(t, err)
assert.Equal(t, []byte(
fmt.Sprintf(FILE_TEMPLATE, CONFIG_PREFIX, "foo", CONFIG_SUFFIX)), fBytes)
assert.Equal(t, []byte(fmt.Sprintf(FILE_TEMPLATE, prefix, "foo", suffix)), fBytes)

// create the base path
badfile := "./this/doesnt/exist"
err = fe.UpdateConfig(false, true, badfile)
changed, err = fe.UpdateConfig(false, true, badfile)
assert.NoError(t, err)
assert.True(t, changed)
defer os.Remove(badfile)

// can't treat a file like a directory though :)
Expand All @@ -75,31 +79,24 @@ func TestFileEdit(t *testing.T) {
_ = os.Chmod(baddir, 0777)
os.Remove(baddir)
}()
err = fe.UpdateConfig(false, true, fmt.Sprintf("%s/foo", baddir))
_, err = fe.UpdateConfig(false, true, fmt.Sprintf("%s/foo", baddir))
assert.Error(t, err)

// can't create this path
err = fe.UpdateConfig(false, true, "/cant/write/to/root/filesystem")
_, err = fe.UpdateConfig(false, true, "/cant/write/to/root/filesystem")
assert.Error(t, err)

// setup logger for testing
logger, hook := test.NewNullLogger()
logger.SetLevel(logrus.DebugLevel)
oldLogger := GetLogger()
SetLogger(logger)
defer SetLogger(oldLogger)

// check the empty diff code path
tfile2, err := os.Open(tfile.Name())
assert.NoError(t, err)
err = fe.UpdateConfig(false, true, tfile2.Name())
changed, err = fe.UpdateConfig(false, true, tfile2.Name())
assert.NoError(t, err)
assert.Contains(t, hook.LastEntry().Message, "no changes made to")
assert.True(t, changed)

// can't eval template
fe, err = NewFileEdit("{{ .Test }}", []string{})
fe, err = NewFileEdit("{{ .Test }}", "test", []string{})
assert.NoError(t, err)
err = fe.UpdateConfig(false, true, tfile.Name())
_, err = fe.UpdateConfig(false, true, tfile.Name())
assert.Error(t, err)
}

Expand Down Expand Up @@ -128,7 +125,7 @@ func TestGenerateNewFile(t *testing.T) {
var vars = map[string]string{
"Test": "foo",
}
fe, _ := NewFileEdit(template, vars)
fe, _ := NewFileEdit(template, "", vars)
_, err := fe.GenerateNewFile("/this/directory/really/should/not/exist")
assert.Error(t, err)
}
Expand All @@ -145,6 +142,32 @@ func promptError(a, b string) (bool, error) {
return false, fmt.Errorf("an error")
}

func TestDefaultFileEdit(t *testing.T) {
var output bytes.Buffer
diffWriter = &output
defer func() { diffWriter = os.Stdout }()

var vars = map[string]string{
"Test": "foo",
}
var template = "{{ .Test }}"
fe, err := NewFileEdit(template, "Default", vars)
assert.NoError(t, err)

tfile, err := os.CreateTemp("", "")
assert.NoError(t, err)
defer os.Remove(tfile.Name())
changed, err := fe.UpdateConfig(true, true, tfile.Name())
assert.NoError(t, err)
assert.True(t, changed)
assert.NotEmpty(t, output)
tfile.Close()

fBytes, err := os.ReadFile(tfile.Name())
assert.NoError(t, err)
assert.Equal(t, []byte(fmt.Sprintf(FILE_TEMPLATE, CONFIG_PREFIX, "foo", CONFIG_SUFFIX)), fBytes)
}

func TestPrompter(t *testing.T) {
var err error
var fe *FileEdit
Expand All @@ -154,10 +177,10 @@ func TestPrompter(t *testing.T) {
"Test": "foo",
}

_, err = NewFileEdit("{{ .Test", vars)
_, err = NewFileEdit("{{ .Test", "", vars)
assert.Error(t, err)

fe, err = NewFileEdit(template, vars)
fe, err = NewFileEdit(template, "", vars)
assert.NoError(t, err)

oldP := prompt
Expand All @@ -168,19 +191,20 @@ func TestPrompter(t *testing.T) {
defer os.Remove(tfile.Name())
tfile.Close()
prompt = promptNo
err = fe.UpdateConfig(false, false, tfile.Name())
changed, err := fe.UpdateConfig(false, false, tfile.Name())
assert.NoError(t, err)
assert.False(t, changed)

fBytes, err := os.ReadFile(tfile.Name())
assert.NoError(t, err)
assert.Empty(t, fBytes)

prompt = promptError
err = fe.UpdateConfig(false, false, tfile.Name())
_, err = fe.UpdateConfig(false, false, tfile.Name())
assert.Error(t, err)

prompt = promptYes
err = fe.UpdateConfig(false, false, tfile.Name())
_, err = fe.UpdateConfig(false, false, tfile.Name())
assert.NoError(t, err)

fBytes, err = os.ReadFile(tfile.Name())
Expand Down

0 comments on commit 83524fe

Please sign in to comment.