Added tests. Updated CLIConfig to pass tests.

This commit is contained in:
Christopher Gerber 2016-02-04 14:56:22 -06:00
parent f1ae2a2b5a
commit 6c3e0daf24
2 changed files with 146 additions and 12 deletions

View File

@ -14,6 +14,7 @@ import (
)
type CLIConfig struct {
ProfileName string
SourceProfile string
AssumeRoleInput *sts.AssumeRoleInput
@ -26,18 +27,19 @@ type CLIConfig struct {
// Return a new CLIConfig with stored profile settings
func NewFromProfile(name string) (*CLIConfig, error) {
c := &CLIConfig{}
c.AssumeRoleInput = new(sts.AssumeRoleInput)
err := c.Prepare(name)
if err != nil {
return nil, err
}
arn := aws.String(c.profileCfg.Key("role_arn").Value())
sessName, err := c.getSessionName(aws.String(c.profileCfg.Key("role_session_name").Value()))
sessName, err := c.getSessionName(c.profileCfg.Key("role_session_name").Value())
if err != nil {
return nil, err
}
c.AssumeRoleInput = &sts.AssumeRoleInput{
RoleSessionName: sessName,
RoleArn: arn,
c.AssumeRoleInput.RoleSessionName = aws.String(sessName)
arn := c.profileCfg.Key("role_arn").Value()
if arn != "" {
c.AssumeRoleInput.RoleArn = aws.String(arn)
}
id := c.profileCfg.Key("external_id").Value()
if id != "" {
@ -51,8 +53,13 @@ func NewFromProfile(name string) (*CLIConfig, error) {
return c, nil
}
// Return AWS Credentials using current profile. Must supply source config
// Return AWS Credentials using current profile. Must supply source config.
func (c *CLIConfig) CredentialsFromProfile(conf *aws.Config) (*credentials.Credentials, error) {
// If the profile name is equal to the source profile, there is no role to assume so return
// the source credentials as they were captured.
if c.ProfileName == c.SourceProfile {
return c.SourceCredentials, nil
}
srcCfg := aws.NewConfig().Copy(conf).WithCredentials(c.SourceCredentials)
svc := sts.New(session.New(), srcCfg)
res, err := svc.AssumeRole(c.AssumeRoleInput)
@ -69,13 +76,14 @@ func (c *CLIConfig) CredentialsFromProfile(conf *aws.Config) (*credentials.Crede
// Sets params in the struct based on the file section
func (c *CLIConfig) Prepare(name string) error {
var err error
c.profileCfg, err = configFromName(name)
c.ProfileName = name
c.profileCfg, err = configFromName(c.ProfileName)
if err != nil {
return err
}
c.SourceProfile = c.profileCfg.Key("source_profile").Value()
if c.SourceProfile == "" {
c.SourceProfile = name
c.SourceProfile = c.ProfileName
}
c.profileCred, err = credsFromName(c.SourceProfile)
if err != nil {
@ -84,13 +92,14 @@ func (c *CLIConfig) Prepare(name string) error {
return nil
}
func (c *CLIConfig) getSessionName(rawName *string) (*string, error) {
if rawName != nil {
func (c *CLIConfig) getSessionName(rawName string) (string, error) {
if rawName == "" {
name := "packer-"
host, err := os.Hostname()
if err != nil {
return nil, err
return name, err
}
return aws.String(fmt.Sprintf("packer-%s", host)), nil
return fmt.Sprintf("%s%s", name, host), nil
} else {
return rawName, nil
}

View File

@ -0,0 +1,125 @@
package common
import (
"io/ioutil"
"os"
"path"
"testing"
"github.com/aws/aws-sdk-go/aws"
)
func init() {
os.Setenv("AWS_ACCESS_KEY_ID", "")
os.Setenv("AWS_ACCESS_KEY", "")
os.Setenv("AWS_SECRET_ACCESS_KEY", "")
os.Setenv("AWS_SECRET_KEY", "")
os.Setenv("AWS_CONFIG_FILE", "")
os.Setenv("AWS_SHARED_CREDENTIALS_FILE", "")
}
func testCLIConfig() *CLIConfig {
return &CLIConfig{}
}
func TestCLIConfigNewFromProfile(t *testing.T) {
tmpDir := mockConfig(t)
c, err := NewFromProfile("testing2")
if err != nil {
t.Error(err)
}
if c.AssumeRoleInput.RoleArn != nil {
t.Errorf("RoleArn should be nil. Instead %p", c.AssumeRoleInput.RoleArn)
}
if c.AssumeRoleInput.ExternalId != nil {
t.Errorf("ExternalId should be nil. Instead %p", c.AssumeRoleInput.ExternalId)
}
mockConfigClose(t, tmpDir)
}
func TestAssumeRole(t *testing.T) {
tmpDir := mockConfig(t)
c, err := NewFromProfile("testing1")
if err != nil {
t.Error(err)
}
// Role
e := "arn:aws:iam::123456789011:role/rolename"
a := *c.AssumeRoleInput.RoleArn
if e != a {
t.Errorf("RoleArn value should be %s. Instead %s", e, a)
}
// Session
a = *c.AssumeRoleInput.RoleSessionName
e = "testsession"
if e != a {
t.Errorf("RoleSessionName value should be %s. Instead %s", e, a)
}
config := aws.NewConfig()
_, err = c.CredentialsFromProfile(config)
if err == nil {
t.Error("Should have errored")
}
mockConfigClose(t, tmpDir)
}
func mockConfig(t *testing.T) string {
dir, err := ioutil.TempDir("", "packer-test")
if err != nil {
t.Error(err)
}
cfgFile := path.Join(dir, "config")
os.Setenv("AWS_CONFIG_FILE", cfgFile)
crdFile := path.Join(dir, "credentials")
os.Setenv("AWS_SHARED_CREDENTIALS_FILE", crdFile)
f, err := os.Create(cfgFile)
if err != nil {
t.Error(err)
}
cfg := []byte(`[profile testing1]
region=us-west-2
source_profile=testingcredentials
role_arn = arn:aws:iam::123456789011:role/rolename
role_session_name = testsession
[profile testing2]
region=us-west-2
`)
_, err = f.Write(cfg)
if err != nil {
t.Error(err)
}
g, err := os.Create(crdFile)
if err != nil {
t.Error(err)
}
crd := []byte(`[testingcredentials]
aws_access_key_id = foo
aws_secret_access_key = bar
[testing2]
aws_access_key_id = baz
aws_secret_access_key = qux
`)
_, err = g.Write(crd)
if err != nil {
t.Error(err)
}
return dir
}
func mockConfigClose(t *testing.T, dir string) {
err := os.RemoveAll(dir)
if err != nil {
t.Error(err)
}
}