docs/drivers/amazonec2/amazonec2_test.go

424 lines
11 KiB
Go

package amazonec2
import (
"testing"
"errors"
"reflect"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/docker/machine/commands/commandstest"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
const (
testSSHPort = int64(22)
testDockerPort = int64(2376)
testSwarmPort = int64(3376)
)
var (
securityGroup = &ec2.SecurityGroup{
GroupName: aws.String("test-group"),
GroupId: aws.String("12345"),
VpcId: aws.String("12345"),
}
)
func TestConfigureSecurityGroupPermissionsEmpty(t *testing.T) {
driver := NewTestDriver()
perms := driver.configureSecurityGroupPermissions(securityGroup)
assert.Len(t, perms, 2)
}
func TestConfigureSecurityGroupPermissionsSshOnly(t *testing.T) {
driver := NewTestDriver()
group := securityGroup
group.IpPermissions = []*ec2.IpPermission{
{
IpProtocol: aws.String("tcp"),
FromPort: aws.Int64(int64(testSSHPort)),
ToPort: aws.Int64(int64(testSSHPort)),
},
}
perms := driver.configureSecurityGroupPermissions(group)
assert.Len(t, perms, 1)
assert.Equal(t, testDockerPort, *perms[0].FromPort)
}
func TestConfigureSecurityGroupPermissionsDockerOnly(t *testing.T) {
driver := NewTestDriver()
group := securityGroup
group.IpPermissions = []*ec2.IpPermission{
{
IpProtocol: aws.String("tcp"),
FromPort: aws.Int64((testDockerPort)),
ToPort: aws.Int64((testDockerPort)),
},
}
perms := driver.configureSecurityGroupPermissions(group)
assert.Len(t, perms, 1)
assert.Equal(t, testSSHPort, *perms[0].FromPort)
}
func TestConfigureSecurityGroupPermissionsDockerAndSsh(t *testing.T) {
driver := NewTestDriver()
group := securityGroup
group.IpPermissions = []*ec2.IpPermission{
{
IpProtocol: aws.String("tcp"),
FromPort: aws.Int64(testSSHPort),
ToPort: aws.Int64(testSSHPort),
},
{
IpProtocol: aws.String("tcp"),
FromPort: aws.Int64(testDockerPort),
ToPort: aws.Int64(testDockerPort),
},
}
perms := driver.configureSecurityGroupPermissions(group)
assert.Empty(t, perms)
}
func TestConfigureSecurityGroupPermissionsWithSwarm(t *testing.T) {
driver := NewTestDriver()
driver.SwarmMaster = true
group := securityGroup
group.IpPermissions = []*ec2.IpPermission{
{
IpProtocol: aws.String("tcp"),
FromPort: aws.Int64(testSSHPort),
ToPort: aws.Int64(testSSHPort),
},
{
IpProtocol: aws.String("tcp"),
FromPort: aws.Int64(testDockerPort),
ToPort: aws.Int64(testDockerPort),
},
}
perms := driver.configureSecurityGroupPermissions(group)
assert.Len(t, perms, 1)
assert.Equal(t, testSwarmPort, *perms[0].FromPort)
}
func TestValidateAwsRegionValid(t *testing.T) {
regions := []string{"eu-west-1", "eu-central-1"}
for _, region := range regions {
validatedRegion, err := validateAwsRegion(region)
assert.NoError(t, err)
assert.Equal(t, region, validatedRegion)
}
}
func TestValidateAwsRegionInvalid(t *testing.T) {
regions := []string{"eu-west-2", "eu-central-2"}
for _, region := range regions {
_, err := validateAwsRegion(region)
assert.EqualError(t, err, "Invalid region specified")
}
}
func TestFindDefaultVPC(t *testing.T) {
driver := NewDriver("machineFoo", "path")
driver.clientFactory = func() Ec2Client { return &fakeEC2WithLogin{} }
vpc, err := driver.getDefaultVPCId()
assert.Equal(t, "vpc-9999", vpc)
assert.NoError(t, err)
}
func TestDefaultVPCIsMissing(t *testing.T) {
driver := NewDriver("machineFoo", "path")
driver.clientFactory = func() Ec2Client {
return &fakeEC2WithDescribe{
output: &ec2.DescribeAccountAttributesOutput{
AccountAttributes: []*ec2.AccountAttribute{},
},
}
}
vpc, err := driver.getDefaultVPCId()
assert.EqualError(t, err, "No default-vpc attribute")
assert.Empty(t, vpc)
}
func TestDescribeAccountAttributeFails(t *testing.T) {
driver := NewDriver("machineFoo", "path")
driver.clientFactory = func() Ec2Client {
return &fakeEC2WithDescribe{
err: errors.New("Not Found"),
}
}
vpc, err := driver.getDefaultVPCId()
assert.EqualError(t, err, "Not Found")
assert.Empty(t, vpc)
}
func TestAccessKeyIsMandatory(t *testing.T) {
driver := NewTestDriver()
driver.awsCredentials = &cliCredentials{}
options := &commandstest.FakeFlagger{
Data: map[string]interface{}{
"name": "test",
"amazonec2-region": "us-east-1",
"amazonec2-zone": "e",
},
}
err := driver.SetConfigFromFlags(options)
assert.Equal(t, err, errorMissingAccessKeyOption)
}
func TestAccessKeyIsMandatoryEvenIfSecretKeyIsPassed(t *testing.T) {
driver := NewTestDriver()
driver.awsCredentials = &cliCredentials{}
options := &commandstest.FakeFlagger{
Data: map[string]interface{}{
"name": "test",
"amazonec2-secret-key": "123",
"amazonec2-region": "us-east-1",
"amazonec2-zone": "e",
},
}
err := driver.SetConfigFromFlags(options)
assert.Equal(t, err, errorMissingAccessKeyOption)
}
func TestSecretKeyIsMandatory(t *testing.T) {
driver := NewTestDriver()
driver.awsCredentials = &cliCredentials{}
options := &commandstest.FakeFlagger{
Data: map[string]interface{}{
"name": "test",
"amazonec2-access-key": "foobar",
"amazonec2-region": "us-east-1",
"amazonec2-zone": "e",
},
}
err := driver.SetConfigFromFlags(options)
assert.Equal(t, err, errorMissingSecretKeyOption)
}
func TestLoadingFromCredentialsWorked(t *testing.T) {
driver := NewCustomTestDriver(&fakeEC2WithLogin{})
driver.awsCredentials = &fileCredentials{}
options := &commandstest.FakeFlagger{
Data: map[string]interface{}{
"name": "test",
"amazonec2-region": "us-east-1",
"amazonec2-zone": "e",
},
}
err := driver.SetConfigFromFlags(options)
assert.NoError(t, err)
assert.Equal(t, "access", driver.AccessKey)
assert.Equal(t, "secret", driver.SecretKey)
assert.Equal(t, "token", driver.SessionToken)
}
func TestPassingBothCLIArgWorked(t *testing.T) {
driver := NewCustomTestDriver(&fakeEC2WithLogin{})
driver.awsCredentials = &cliCredentials{}
options := &commandstest.FakeFlagger{
Data: map[string]interface{}{
"name": "test",
"amazonec2-access-key": "foobar",
"amazonec2-secret-key": "123",
"amazonec2-region": "us-east-1",
"amazonec2-zone": "e",
},
}
err := driver.SetConfigFromFlags(options)
assert.NoError(t, err)
assert.Equal(t, "foobar", driver.AccessKey)
assert.Equal(t, "123", driver.SecretKey)
}
var values = []string{
"bob",
"jake",
"jill",
}
var pointerSliceTests = []struct {
input []string
expected []*string
}{
{[]string{}, []*string{}},
{[]string{values[1]}, []*string{&values[1]}},
{[]string{values[0], values[2], values[2]}, []*string{&values[0], &values[2], &values[2]}},
}
func TestMakePointerSlice(t *testing.T) {
for _, tt := range pointerSliceTests {
actual := makePointerSlice(tt.input)
assert.Equal(t, tt.expected, actual)
}
}
var securityGroupNameTests = []struct {
groupName string
groupNames []string
expected []string
}{
{groupName: "bob", expected: []string{"bob"}},
{groupNames: []string{"bill"}, expected: []string{"bill"}},
{groupName: "bob", groupNames: []string{"bill"}, expected: []string{"bob", "bill"}},
}
func TestMergeSecurityGroupName(t *testing.T) {
for _, tt := range securityGroupNameTests {
d := Driver{SecurityGroupName: tt.groupName, SecurityGroupNames: tt.groupNames}
assert.Equal(t, tt.expected, d.securityGroupNames())
}
}
var securityGroupIdTests = []struct {
groupId string
groupIds []string
expected []string
}{
{groupId: "id", expected: []string{"id"}},
{groupIds: []string{"id"}, expected: []string{"id"}},
{groupId: "id1", groupIds: []string{"id2"}, expected: []string{"id1", "id2"}},
}
func TestMergeSecurityGroupId(t *testing.T) {
for _, tt := range securityGroupIdTests {
d := Driver{SecurityGroupId: tt.groupId, SecurityGroupIds: tt.groupIds}
assert.Equal(t, tt.expected, d.securityGroupIds())
}
}
func matchGroupLookup(expected []string) interface{} {
return func(input *ec2.DescribeSecurityGroupsInput) bool {
actual := []string{}
for _, filter := range input.Filters {
if *filter.Name == "group-name" {
for _, groupName := range filter.Values {
actual = append(actual, *groupName)
}
}
}
return reflect.DeepEqual(expected, actual)
}
}
func ipPermission(port int64) *ec2.IpPermission {
return &ec2.IpPermission{
FromPort: aws.Int64(port),
ToPort: aws.Int64(port),
IpProtocol: aws.String("tcp"),
IpRanges: []*ec2.IpRange{{CidrIp: aws.String(ipRange)}},
}
}
func TestConfigureSecurityGroupsEmpty(t *testing.T) {
recorder := fakeEC2SecurityGroupTestRecorder{}
driver := NewCustomTestDriver(&recorder)
err := driver.configureSecurityGroups([]string{})
assert.Nil(t, err)
recorder.AssertExpectations(t)
}
func TestConfigureSecurityGroupsMixed(t *testing.T) {
groups := []string{"existingGroup", "newGroup"}
recorder := fakeEC2SecurityGroupTestRecorder{}
// First, a check is made for which groups already exist.
initialLookupResult := ec2.DescribeSecurityGroupsOutput{SecurityGroups: []*ec2.SecurityGroup{
{
GroupName: aws.String("existingGroup"),
GroupId: aws.String("existingGroupId"),
IpPermissions: []*ec2.IpPermission{ipPermission(testSSHPort)},
},
}}
recorder.On("DescribeSecurityGroups", mock.MatchedBy(matchGroupLookup(groups))).Return(
&initialLookupResult, nil)
// An ingress permission is added to the existing group.
recorder.On("AuthorizeSecurityGroupIngress", &ec2.AuthorizeSecurityGroupIngressInput{
GroupId: aws.String("existingGroupId"),
IpPermissions: []*ec2.IpPermission{ipPermission(testDockerPort)},
}).Return(
&ec2.AuthorizeSecurityGroupIngressOutput{}, nil)
// The new security group is created.
recorder.On("CreateSecurityGroup", &ec2.CreateSecurityGroupInput{
GroupName: aws.String("newGroup"),
Description: aws.String("Docker Machine"),
VpcId: aws.String(""),
}).Return(
&ec2.CreateSecurityGroupOutput{GroupId: aws.String("newGroupId")}, nil)
// Ensuring the new security group exists.
postCreateLookupResult := ec2.DescribeSecurityGroupsOutput{SecurityGroups: []*ec2.SecurityGroup{
{
GroupName: aws.String("newGroup"),
GroupId: aws.String("newGroupId"),
},
}}
recorder.On("DescribeSecurityGroups",
&ec2.DescribeSecurityGroupsInput{GroupIds: []*string{aws.String("newGroupId")}}).Return(
&postCreateLookupResult, nil)
// Permissions are added to the new security group.
recorder.On("AuthorizeSecurityGroupIngress", &ec2.AuthorizeSecurityGroupIngressInput{
GroupId: aws.String("newGroupId"),
IpPermissions: []*ec2.IpPermission{ipPermission(testSSHPort), ipPermission(testDockerPort)},
}).Return(
&ec2.AuthorizeSecurityGroupIngressOutput{}, nil)
driver := NewCustomTestDriver(&recorder)
err := driver.configureSecurityGroups(groups)
assert.Nil(t, err)
recorder.AssertExpectations(t)
}
func TestConfigureSecurityGroupsErrLookupExist(t *testing.T) {
groups := []string{"group"}
recorder := fakeEC2SecurityGroupTestRecorder{}
lookupExistErr := errors.New("lookup failed")
recorder.On("DescribeSecurityGroups", mock.MatchedBy(matchGroupLookup(groups))).Return(
nil, lookupExistErr)
driver := NewCustomTestDriver(&recorder)
err := driver.configureSecurityGroups(groups)
assert.Exactly(t, lookupExistErr, err)
recorder.AssertExpectations(t)
}