Skip to content

Commit

Permalink
Add secretsmanager and s3 tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Julien Duchesne committed Jul 29, 2019
1 parent 6a27cff commit 7229ef1
Show file tree
Hide file tree
Showing 9 changed files with 193 additions and 53 deletions.
2 changes: 1 addition & 1 deletion cli/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import (
"gopkg.in/yaml.v2"

"github.com/coveooss/credentials-sync/credentials"
"github.com/coveooss/credentials-sync/targets"
"github.com/coveooss/credentials-sync/sync"
"github.com/coveooss/credentials-sync/targets"
log "github.com/sirupsen/logrus"

"github.com/spf13/cobra"
Expand Down
50 changes: 50 additions & 0 deletions credentials/helper_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package credentials

const (
testCredentialsAsMap = `{
"test": {
"type": "secret",
"description": "test-desc",
"secret": "my secret"
},
"test2": {
"type": "usernamepassword",
"description": "test2-desc",
"username": "my",
"password": "secret"
}
}`
testCredentialsAsList = `[
{
"id": "test",
"type": "secret",
"description": "test-desc",
"secret": "my secret"
},
{
"id": "test2",
"type": "usernamepassword",
"description": "test2-desc",
"username": "my",
"password": "secret"
}
]`
)

var testCredentials = []Credentials{
func() (creds *SecretTextCredentials) {
creds = NewSecretText()
creds.ID = "test"
creds.Secret = "my secret"
creds.Description = "test-desc"
return
}(),
func() (creds *UsernamePasswordCredentials) {
creds = NewUsernamePassword()
creds.ID = "test2"
creds.Username = "my"
creds.Password = "secret"
creds.Description = "test2-desc"
return
}(),
}
44 changes: 44 additions & 0 deletions credentials/source_s3_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,21 @@ package credentials

import (
"fmt"
"io/ioutil"
"strings"
"testing"

"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/s3/s3iface"

"github.com/stretchr/testify/assert"
)

const (
s3Bucket = "my-bucket"
s3Key = "a/key"
)

func TestS3SourceValidate(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -39,3 +49,37 @@ func TestS3SourceValidate(t *testing.T) {
})
}
}

type mockS3Client struct {
s3iface.S3API
t *testing.T
}

func (m *mockS3Client) GetObject(input *s3.GetObjectInput) (*s3.GetObjectOutput, error) {
assert.Equal(m.t, s3Bucket, *input.Bucket)
assert.Equal(m.t, s3Key, *input.Key)

return &s3.GetObjectOutput{Body: ioutil.NopCloser(strings.NewReader(`test_cred:
type: usernamepassword
description: a credential
username: user
password: pass`))}, nil
}

func TestGetCredentialsFromS3Source(t *testing.T) {
s3Source := &AWSS3Source{
Bucket: s3Bucket,
Key: s3Key,
client: &mockS3Client{t: t},
}

credentials, err := s3Source.Credentials()

expectedCred := NewUsernamePassword()
expectedCred.ID = "test_cred"
expectedCred.Description = "a credential"
expectedCred.Username = "user"
expectedCred.Password = "pass"
assert.Nil(t, err)
assert.Equal(t, []Credentials{expectedCred}, credentials)
}
86 changes: 86 additions & 0 deletions credentials/source_secretsmanager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,35 @@ package credentials

import (
"fmt"
"sort"
"testing"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/secretsmanager"
"github.com/aws/aws-sdk-go/service/secretsmanager/secretsmanageriface"

"github.com/stretchr/testify/assert"
)

const (
prefix = "the_prefix"
firstSecretName = "the_prefix/id1"
firstSecretARN = "arn:aws:secretsmanager:us-east-1:123456789012:secret:the_prefix/id1-123456"
secondSecretName = "the_prefix/id2"
secondSecretARN = "arn:aws:secretsmanager:us-east-1:123456789012:secret:the_prefix/id2-123456"
thirdSecretName = "id3"
thirdSecretARN = "arn:aws:secretsmanager:us-east-1:123456789012:secret:id3-123456"
)

var expectedSecretsManagerCredentials = func() []Credentials {
expectedCred := NewUsernamePassword()
expectedCred.ID = "test3"
expectedCred.Description = "a credential"
expectedCred.Username = "user"
expectedCred.Password = "pass"
return append(testCredentials, expectedCred)
}()

func TestSecretsManagerSourceValidate(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -44,3 +68,65 @@ func TestSecretsManagerSourceValidate(t *testing.T) {
})
}
}

type mockSecretsManagerClient struct {
secretsmanageriface.SecretsManagerAPI
t *testing.T
}

func (m *mockSecretsManagerClient) ListSecretsPages(input *secretsmanager.ListSecretsInput, theFunc func(*secretsmanager.ListSecretsOutput, bool) bool) error {
theFunc(&secretsmanager.ListSecretsOutput{SecretList: []*secretsmanager.SecretListEntry{
{
ARN: aws.String(firstSecretARN),
Name: aws.String(firstSecretName),
},
{
ARN: aws.String(secondSecretARN),
Name: aws.String(secondSecretName),
},
{
ARN: aws.String(thirdSecretARN),
Name: aws.String(thirdSecretName),
},
}}, true)
return nil
}

func (m *mockSecretsManagerClient) GetSecretValue(input *secretsmanager.GetSecretValueInput) (*secretsmanager.GetSecretValueOutput, error) {
if *input.SecretId == firstSecretARN {
return &secretsmanager.GetSecretValueOutput{SecretString: aws.String(testCredentialsAsMap)}, nil
} else if *input.SecretId == secondSecretARN {
return &secretsmanager.GetSecretValueOutput{SecretString: aws.String(`test3:
type: usernamepassword
description: a credential
username: user
password: pass`)}, nil
}
return nil, fmt.Errorf("Only first and second are valid")
}

func TestGetCredentialsFromSecretsManagerSourceWithPrefix(t *testing.T) {
secretsManagerSource := &AWSSecretsManagerSource{
SecretPrefix: prefix,
client: &mockSecretsManagerClient{t: t},
}

credentials, err := secretsManagerSource.Credentials()
sort.Slice(credentials, func(i, j int) bool { return credentials[i].GetID() < credentials[j].GetID() })

assert.Nil(t, err)
assert.Equal(t, expectedSecretsManagerCredentials, credentials)
}

func TestGetCredentialsFromSecretsManagerSourceWithID(t *testing.T) {
secretsManagerSource := &AWSSecretsManagerSource{
SecretID: firstSecretARN,
client: &mockSecretsManagerClient{t: t},
}

credentials, err := secretsManagerSource.Credentials()
sort.Slice(credentials, func(i, j int) bool { return credentials[i].GetID() < credentials[j].GetID() })

assert.Nil(t, err)
assert.Equal(t, testCredentials, credentials)
}
1 change: 1 addition & 0 deletions credentials/sources.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type SourcesConfiguration struct {
credentialsList []Credentials
}

// SourceCollection represents a collection of sources from which credentials can be fetched
type SourceCollection interface {
AllSources() []Source
Credentials() ([]Credentials, error)
Expand Down
52 changes: 4 additions & 48 deletions credentials/sources_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,6 @@ import (
"github.com/stretchr/testify/assert"
)

var testCredentials = []Credentials{
func() (creds *SecretTextCredentials) {
creds = NewSecretText()
creds.ID = "test"
creds.Secret = "my secret"
creds.Description = "test-desc"
return
}(),
func() (creds *UsernamePasswordCredentials) {
creds = NewUsernamePassword()
creds.ID = "test2"
creds.Username = "my"
creds.Password = "secret"
creds.Description = "test2-desc"
return
}(),
}

func TestSourcesConfigWithLocalSource(t *testing.T) {
tempDir, err := ioutil.TempDir("", "")
if err != nil {
Expand Down Expand Up @@ -65,40 +47,14 @@ func TestGetCredentialsFromBytes(t *testing.T) {
wantErr: false,
},
{
name: "List",
bytes: []byte(`[
{
"id": "test",
"type": "secret",
"description": "test-desc",
"secret": "my secret"
},
{
"id": "test2",
"type": "usernamepassword",
"description": "test2-desc",
"username": "my",
"password": "secret"
}
]`),
name: "List",
bytes: []byte(testCredentialsAsList),
result: testCredentials,
wantErr: false,
},
{
name: "Map",
bytes: []byte(`{
"test": {
"type": "secret",
"description": "test-desc",
"secret": "my secret"
},
"test2": {
"type": "usernamepassword",
"description": "test2-desc",
"username": "my",
"password": "secret"
}
}`),
name: "Map",
bytes: []byte(testCredentialsAsMap),
result: testCredentials,
wantErr: false,
},
Expand Down
2 changes: 2 additions & 0 deletions sync/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ func NewConfiguration() *Configuration {
}
}

// SetSources sets the source configuration on synchronization configuration
func (config *Configuration) SetSources(sources credentials.SourceCollection) {
config.Sources = sources
}

// SetTargets sets the target configuration on synchronization configuration
func (config *Configuration) SetTargets(targets targets.TargetCollection) {
config.Targets = targets
}
Expand Down
1 change: 1 addition & 0 deletions targets/targets.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ func HasCredential(target Target, id string) bool {
return false
}

// TargetCollection represents a collection of targets to which credentials can be synced
type TargetCollection interface {
AllTargets() []Target
ValidateConfiguration() error
Expand Down
8 changes: 4 additions & 4 deletions targets/targets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func TestConfigValidateConfiguration(t *testing.T) {
{
name: "valid target",
targets: []*JenkinsTarget{
&JenkinsTarget{
{
Base: Base{Name: "test"},
URL: "https://test.com",
},
Expand All @@ -32,7 +32,7 @@ func TestConfigValidateConfiguration(t *testing.T) {
{
name: "no name",
targets: []*JenkinsTarget{
&JenkinsTarget{
{
Base: Base{Name: ""},
URL: "https://test.com",
},
Expand All @@ -42,7 +42,7 @@ func TestConfigValidateConfiguration(t *testing.T) {
{
name: "two actions for unsynced credentials",
targets: []*JenkinsTarget{
&JenkinsTarget{
{
Base: Base{Name: "test", DeleteUnsynced: true, TagUnsynced: true},
URL: "https://test.com",
},
Expand All @@ -52,7 +52,7 @@ func TestConfigValidateConfiguration(t *testing.T) {
{
name: "bad url (validated by Jenkins)",
targets: []*JenkinsTarget{
&JenkinsTarget{
{
Base: Base{Name: "test"},
URL: "bad",
},
Expand Down

0 comments on commit 7229ef1

Please sign in to comment.