-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Start hacking on AWS credentials file compatible mode
Signed-off-by: Noah Stride <noah.stride@goteleport.com>
- Loading branch information
1 parent
9d2957c
commit c148711
Showing
5 changed files
with
191 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package internal | ||
|
||
import ( | ||
"fmt" | ||
"log/slog" | ||
"os" | ||
|
||
"gopkg.in/ini.v1" | ||
) | ||
|
||
type AWSCredentialsFileConfig struct { | ||
Path string | ||
ProfileName string | ||
Force bool | ||
ReplaceFile bool | ||
} | ||
|
||
type AWSCredentialsFileProfile struct { | ||
AWSAccessKeyID string | ||
AWSSecretAccessKey string | ||
AWSSessionToken string | ||
} | ||
|
||
func (p AWSCredentialsFileProfile) Validate() error { | ||
// TODO: Validate | ||
return nil | ||
} | ||
|
||
// UpsertAWSCredentialsFileProfile writes the provided AWS credentials profile to the AWS credentials file. | ||
// See https://docs.aws.amazon.com/cli/v1/userguide/cli-configure-files.html | ||
func UpsertAWSCredentialsFileProfile( | ||
log *slog.Logger, | ||
cfg AWSCredentialsFileConfig, | ||
p AWSCredentialsFileProfile, | ||
) error { | ||
if err := p.Validate(); err != nil { | ||
return fmt.Errorf("validating aws credentials file profile: %w", err) | ||
} | ||
|
||
f, err := ini.Load(cfg.Path) | ||
if err != nil { | ||
if !os.IsNotExist(err) { | ||
if !cfg.Force { | ||
log.Error( | ||
"When loading the existing AWS credentials file, an error occurred. Use --force to ignore errors and attempt to overwrite.", | ||
"error", err, | ||
"path", cfg.Path, | ||
) | ||
return fmt.Errorf("loading existing aws credentials file: %w", err) | ||
} | ||
log.Warn( | ||
"When loading the existing AWS credentials file, an error occurred. As --force is set, the file will be overwritten.", | ||
"error", err, | ||
"path", cfg.Path, | ||
) | ||
} | ||
f = ini.Empty() | ||
} | ||
|
||
sectionName := "default" | ||
if cfg.ProfileName != "" { | ||
sectionName = cfg.ProfileName | ||
} | ||
sec := f.Section(sectionName) | ||
|
||
sec.Key("aws_secret_access_key").SetValue(p.AWSSecretAccessKey) | ||
sec.Key("aws_access_key_id").SetValue(p.AWSAccessKeyID) | ||
sec.Key("aws_session_token").SetValue(p.AWSSessionToken) | ||
|
||
if err := f.SaveTo(cfg.Path); err != nil { | ||
return fmt.Errorf("saving aws credentials file: %w", err) | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package internal | ||
|
||
import ( | ||
"log/slog" | ||
"os" | ||
"path/filepath" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestAWSCredentialsFile_Write(t *testing.T) { | ||
// TODO: Add more cases: | ||
// - If file exists, but is a bad ini and Force moe | ||
// - Replace mode | ||
tmp := t.TempDir() | ||
configPath := filepath.Join(tmp, "config") | ||
log := slog.Default() | ||
|
||
err := UpsertAWSCredentialsFileProfile( | ||
log, | ||
AWSCredentialsFileConfig{ | ||
Path: configPath, | ||
}, | ||
AWSCredentialsFileProfile{ | ||
AWSAccessKeyID: "1234567890", | ||
AWSSecretAccessKey: "abcdefgh", | ||
AWSSessionToken: "ijklmnop", | ||
}, | ||
) | ||
require.NoError(t, err) | ||
|
||
got, err := os.ReadFile(configPath) | ||
require.NoError(t, err) | ||
|
||
require.Equal(t, `[default] | ||
aws_secret_access_key = abcdefgh | ||
aws_access_key_id = 1234567890 | ||
aws_session_token = ijklmnop | ||
`, string(got)) | ||
|
||
t.Run("bad file", func(t *testing.T) { | ||
tmp := t.TempDir() | ||
configPath := filepath.Join(tmp, "config") | ||
require.NoError(t, os.WriteFile(configPath, []byte("bad ini"), 0600)) | ||
err := UpsertAWSCredentialsFileProfile( | ||
log, | ||
AWSCredentialsFileConfig{ | ||
Path: configPath, | ||
Force: true, | ||
}, | ||
AWSCredentialsFileProfile{ | ||
AWSAccessKeyID: "1234567890", | ||
AWSSecretAccessKey: "abcdefgh", | ||
AWSSessionToken: "ijklmnop", | ||
}, | ||
) | ||
require.NoError(t, err) | ||
|
||
got, err := os.ReadFile(configPath) | ||
require.NoError(t, err) | ||
|
||
require.Equal(t, `[default] | ||
aws_secret_access_key = abcdefgh | ||
aws_access_key_id = 1234567890 | ||
aws_session_token = ijklmnop | ||
`, string(got)) | ||
}) | ||
} |