github.com/someshkoli/terratest@v0.41.1/modules/aws/vpc_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  	"github.com/stretchr/testify/require"
     9  
    10  	"github.com/aws/aws-sdk-go/aws"
    11  	"github.com/aws/aws-sdk-go/service/ec2"
    12  )
    13  
    14  func TestGetDefaultVpc(t *testing.T) {
    15  	t.Parallel()
    16  
    17  	region := GetRandomStableRegion(t, nil, nil)
    18  	vpc := GetDefaultVpc(t, region)
    19  
    20  	assert.NotEmpty(t, vpc.Name)
    21  	assert.True(t, len(vpc.Subnets) > 0)
    22  	assert.Regexp(t, "^vpc-[[:alnum:]]+$", vpc.Id)
    23  }
    24  
    25  func TestGetVpcById(t *testing.T) {
    26  	t.Parallel()
    27  
    28  	region := GetRandomStableRegion(t, nil, nil)
    29  	vpc := createVpc(t, region)
    30  	defer deleteVpc(t, *vpc.VpcId, region)
    31  
    32  	vpcTest := GetVpcById(t, *vpc.VpcId, region)
    33  	assert.Equal(t, *vpc.VpcId, vpcTest.Id)
    34  }
    35  
    36  func TestGetVpcsE(t *testing.T) {
    37  	t.Parallel()
    38  
    39  	region := GetRandomStableRegion(t, nil, nil)
    40  	azs := GetAvailabilityZones(t, region)
    41  
    42  	isDefaultFilterName := "isDefault"
    43  	isDefaultFilterValue := "true"
    44  
    45  	defaultVpcFilter := ec2.Filter{Name: &isDefaultFilterName, Values: []*string{&isDefaultFilterValue}}
    46  	vpcs, _ := GetVpcsE(t, []*ec2.Filter{&defaultVpcFilter}, region)
    47  
    48  	require.Equal(t, len(vpcs), 1)
    49  	assert.NotEmpty(t, vpcs[0].Name)
    50  
    51  	// the default VPC has by default one subnet per availability zone
    52  	// https://docs.aws.amazon.com/vpc/latest/userguide/default-vpc.html
    53  	assert.True(t, len(vpcs[0].Subnets) >= len(azs))
    54  }
    55  
    56  func TestGetFirstTwoOctets(t *testing.T) {
    57  	t.Parallel()
    58  
    59  	firstTwo := GetFirstTwoOctets("10.100.0.0/28")
    60  	if firstTwo != "10.100" {
    61  		t.Errorf("Received: %s, Expected: 10.100", firstTwo)
    62  	}
    63  }
    64  
    65  func TestIsPublicSubnet(t *testing.T) {
    66  	t.Parallel()
    67  
    68  	region := GetRandomStableRegion(t, nil, nil)
    69  	vpc := createVpc(t, region)
    70  	defer deleteVpc(t, *vpc.VpcId, region)
    71  
    72  	routeTable := createRouteTable(t, *vpc.VpcId, region)
    73  	subnet := createSubnet(t, *vpc.VpcId, *routeTable.RouteTableId, region)
    74  	assert.False(t, IsPublicSubnet(t, *subnet.SubnetId, region))
    75  
    76  	createPublicRoute(t, *vpc.VpcId, *routeTable.RouteTableId, region)
    77  	assert.True(t, IsPublicSubnet(t, *subnet.SubnetId, region))
    78  }
    79  
    80  func TestGetDefaultSubnetIDsForVpc(t *testing.T) {
    81  	t.Parallel()
    82  
    83  	region := GetRandomStableRegion(t, nil, nil)
    84  	defaultVpcBeforeSubnetCreation := GetDefaultVpc(t, region)
    85  
    86  	// Creates a subnet in the default VPC with deferred deletion
    87  	// and fetches vpc object again
    88  	subnetName := fmt.Sprintf("%s-subnet", t.Name())
    89  	subnet := createPrivateSubnetInDefaultVpc(t, defaultVpcBeforeSubnetCreation.Id, subnetName, region)
    90  	defer deleteSubnet(t, *subnet.SubnetId, region)
    91  	defaultVpc := GetDefaultVpc(t, region)
    92  
    93  	defaultSubnetIDs := GetDefaultSubnetIDsForVpc(t, *defaultVpc)
    94  	assert.NotEmpty(t, defaultSubnetIDs)
    95  	// Checks that the amount of default subnets is smaller than
    96  	// total number of subnets in default vpc
    97  	assert.True(t, len(defaultSubnetIDs) < len(defaultVpc.Subnets))
    98  
    99  	availabilityZones := []string{}
   100  	for _, id := range defaultSubnetIDs {
   101  		// check if the recently created subnet does not come up here
   102  		assert.NotEqual(t, id, subnet.SubnetId)
   103  		// default subnets are by default public
   104  		// https://docs.aws.amazon.com/vpc/latest/userguide/default-vpc.html
   105  		assert.True(t, IsPublicSubnet(t, id, region))
   106  		for _, subnet := range defaultVpc.Subnets {
   107  			if id == subnet.Id {
   108  				availabilityZones = append(availabilityZones, subnet.AvailabilityZone)
   109  			}
   110  		}
   111  	}
   112  	// only one default subnet is allowed per AZ
   113  	uniqueAZs := map[string]bool{}
   114  	for _, az := range availabilityZones {
   115  		uniqueAZs[az] = true
   116  	}
   117  	assert.Equal(t, len(defaultSubnetIDs), len(uniqueAZs))
   118  }
   119  
   120  func TestGetTagsForVpc(t *testing.T) {
   121  	t.Parallel()
   122  
   123  	region := GetRandomStableRegion(t, nil, nil)
   124  	vpc := createVpc(t, region)
   125  	defer deleteVpc(t, *vpc.VpcId, region)
   126  
   127  	noTags := GetTagsForVpc(t, *vpc.VpcId, region)
   128  	assert.True(t, len(vpc.Tags) == 0)
   129  	assert.True(t, len(noTags) == 0)
   130  
   131  	testTags := make(map[string]string)
   132  	testTags["TagKey1"] = "TagValue1"
   133  	testTags["TagKey2"] = "TagValue2"
   134  
   135  	AddTagsToResource(t, region, *vpc.VpcId, testTags)
   136  	vpcWithTags := GetVpcById(t, *vpc.VpcId, region)
   137  	tags := GetTagsForVpc(t, *vpc.VpcId, region)
   138  
   139  	assert.True(t, len(vpcWithTags.Tags) == len(testTags))
   140  	assert.True(t, len(tags) == len(testTags))
   141  }
   142  
   143  func TestGetTagsForSubnet(t *testing.T) {
   144  	t.Parallel()
   145  
   146  	region := GetRandomStableRegion(t, nil, nil)
   147  	vpc := createVpc(t, region)
   148  	defer deleteVpc(t, *vpc.VpcId, region)
   149  
   150  	routeTable := createRouteTable(t, *vpc.VpcId, region)
   151  	subnet := createSubnet(t, *vpc.VpcId, *routeTable.RouteTableId, region)
   152  
   153  	noTags := GetTagsForSubnet(t, *subnet.SubnetId, region)
   154  	assert.True(t, len(subnet.Tags) == 0)
   155  	assert.True(t, len(noTags) == 0)
   156  
   157  	testTags := make(map[string]string)
   158  	testTags["TagKey1"] = "TagValue1"
   159  	testTags["TagKey2"] = "TagValue2"
   160  
   161  	AddTagsToResource(t, region, *subnet.SubnetId, testTags)
   162  
   163  	subnetWithTags := GetSubnetsForVpc(t, *vpc.VpcId, region)[0]
   164  	tags := GetTagsForSubnet(t, *subnet.SubnetId, region)
   165  
   166  	assert.True(t, len(subnetWithTags.Tags) == len(testTags))
   167  	assert.True(t, len(tags) == len(testTags))
   168  	assert.True(t, testTags["TagKey1"] == "TagValue1")
   169  	assert.True(t, testTags["TagKey2"] == "TagValue2")
   170  }
   171  
   172  func createPublicRoute(t *testing.T, vpcId string, routeTableId string, region string) {
   173  	ec2Client := NewEc2Client(t, region)
   174  
   175  	createIGWOut, igerr := ec2Client.CreateInternetGateway(&ec2.CreateInternetGatewayInput{})
   176  	require.NoError(t, igerr)
   177  
   178  	_, aigerr := ec2Client.AttachInternetGateway(&ec2.AttachInternetGatewayInput{
   179  		InternetGatewayId: createIGWOut.InternetGateway.InternetGatewayId,
   180  		VpcId:             aws.String(vpcId),
   181  	})
   182  	require.NoError(t, aigerr)
   183  
   184  	_, err := ec2Client.CreateRoute(&ec2.CreateRouteInput{
   185  		RouteTableId:         aws.String(routeTableId),
   186  		DestinationCidrBlock: aws.String("0.0.0.0/0"),
   187  		GatewayId:            createIGWOut.InternetGateway.InternetGatewayId,
   188  	})
   189  
   190  	require.NoError(t, err)
   191  }
   192  
   193  func createRouteTable(t *testing.T, vpcId string, region string) ec2.RouteTable {
   194  	ec2Client := NewEc2Client(t, region)
   195  
   196  	createRouteTableOutput, err := ec2Client.CreateRouteTable(&ec2.CreateRouteTableInput{
   197  		VpcId: aws.String(vpcId),
   198  	})
   199  
   200  	require.NoError(t, err)
   201  	return *createRouteTableOutput.RouteTable
   202  }
   203  
   204  func createSubnet(t *testing.T, vpcId string, routeTableId string, region string) ec2.Subnet {
   205  	ec2Client := NewEc2Client(t, region)
   206  
   207  	createSubnetOutput, err := ec2Client.CreateSubnet(&ec2.CreateSubnetInput{
   208  		CidrBlock: aws.String("10.10.1.0/24"),
   209  		VpcId:     aws.String(vpcId),
   210  	})
   211  	require.NoError(t, err)
   212  
   213  	_, err = ec2Client.AssociateRouteTable(&ec2.AssociateRouteTableInput{
   214  		RouteTableId: aws.String(routeTableId),
   215  		SubnetId:     aws.String(*createSubnetOutput.Subnet.SubnetId),
   216  	})
   217  	require.NoError(t, err)
   218  
   219  	return *createSubnetOutput.Subnet
   220  }
   221  
   222  func createPrivateSubnetInDefaultVpc(t *testing.T, vpcId string, subnetName string, region string) ec2.Subnet {
   223  	ec2Client := NewEc2Client(t, region)
   224  
   225  	createSubnetOutput, err := ec2Client.CreateSubnet(&ec2.CreateSubnetInput{
   226  		CidrBlock: aws.String("172.31.172.0/24"),
   227  		VpcId:     aws.String(vpcId),
   228  		TagSpecifications: []*ec2.TagSpecification{
   229  			{
   230  				ResourceType: aws.String("subnet"),
   231  				Tags: []*ec2.Tag{
   232  					{
   233  						Key:   aws.String("Name"),
   234  						Value: aws.String(subnetName),
   235  					},
   236  				},
   237  			},
   238  		},
   239  	})
   240  	require.NoError(t, err)
   241  
   242  	return *createSubnetOutput.Subnet
   243  }
   244  
   245  func deleteSubnet(t *testing.T, subnetId string, region string) {
   246  	ec2Client := NewEc2Client(t, region)
   247  
   248  	_, err := ec2Client.DeleteSubnet(&ec2.DeleteSubnetInput{
   249  		SubnetId: aws.String(subnetId),
   250  	})
   251  	require.NoError(t, err)
   252  }
   253  
   254  func createVpc(t *testing.T, region string) ec2.Vpc {
   255  	ec2Client := NewEc2Client(t, region)
   256  
   257  	createVpcOutput, err := ec2Client.CreateVpc(&ec2.CreateVpcInput{
   258  		CidrBlock: aws.String("10.10.0.0/16"),
   259  	})
   260  
   261  	require.NoError(t, err)
   262  	return *createVpcOutput.Vpc
   263  }
   264  
   265  func deleteRouteTables(t *testing.T, vpcId string, region string) {
   266  	ec2Client := NewEc2Client(t, region)
   267  
   268  	vpcIDFilterName := "vpc-id"
   269  	vpcIDFilter := ec2.Filter{Name: &vpcIDFilterName, Values: []*string{&vpcId}}
   270  
   271  	// "You can't delete the main route table."
   272  	mainRTFilterName := "association.main"
   273  	mainRTFilterValue := "false"
   274  	notMainRTFilter := ec2.Filter{Name: &mainRTFilterName, Values: []*string{&mainRTFilterValue}}
   275  
   276  	filters := []*ec2.Filter{&vpcIDFilter, &notMainRTFilter}
   277  
   278  	rtOutput, err := ec2Client.DescribeRouteTables(&ec2.DescribeRouteTablesInput{Filters: filters})
   279  	require.NoError(t, err)
   280  
   281  	for _, rt := range rtOutput.RouteTables {
   282  
   283  		// "You must disassociate the route table from any subnets before you can delete it."
   284  		for _, assoc := range rt.Associations {
   285  			_, disassocErr := ec2Client.DisassociateRouteTable(&ec2.DisassociateRouteTableInput{
   286  				AssociationId: assoc.RouteTableAssociationId,
   287  			})
   288  			require.NoError(t, disassocErr)
   289  		}
   290  
   291  		_, err := ec2Client.DeleteRouteTable(&ec2.DeleteRouteTableInput{
   292  			RouteTableId: rt.RouteTableId,
   293  		})
   294  		require.NoError(t, err)
   295  	}
   296  }
   297  
   298  func deleteSubnets(t *testing.T, vpcId string, region string) {
   299  	ec2Client := NewEc2Client(t, region)
   300  	vpcIDFilterName := "vpc-id"
   301  	vpcIDFilter := ec2.Filter{Name: &vpcIDFilterName, Values: []*string{&vpcId}}
   302  
   303  	subnetsOutput, err := ec2Client.DescribeSubnets(&ec2.DescribeSubnetsInput{Filters: []*ec2.Filter{&vpcIDFilter}})
   304  	require.NoError(t, err)
   305  
   306  	for _, subnet := range subnetsOutput.Subnets {
   307  		_, err := ec2Client.DeleteSubnet(&ec2.DeleteSubnetInput{
   308  			SubnetId: subnet.SubnetId,
   309  		})
   310  		require.NoError(t, err)
   311  	}
   312  }
   313  
   314  func deleteInternetGateways(t *testing.T, vpcId string, region string) {
   315  	ec2Client := NewEc2Client(t, region)
   316  	vpcIDFilterName := "attachment.vpc-id"
   317  	vpcIDFilter := ec2.Filter{Name: &vpcIDFilterName, Values: []*string{&vpcId}}
   318  
   319  	igwOutput, err := ec2Client.DescribeInternetGateways(&ec2.DescribeInternetGatewaysInput{Filters: []*ec2.Filter{&vpcIDFilter}})
   320  	require.NoError(t, err)
   321  
   322  	for _, igw := range igwOutput.InternetGateways {
   323  
   324  		_, detachErr := ec2Client.DetachInternetGateway(&ec2.DetachInternetGatewayInput{
   325  			InternetGatewayId: igw.InternetGatewayId,
   326  			VpcId:             aws.String(vpcId),
   327  		})
   328  		require.NoError(t, detachErr)
   329  
   330  		_, err := ec2Client.DeleteInternetGateway(&ec2.DeleteInternetGatewayInput{
   331  			InternetGatewayId: igw.InternetGatewayId,
   332  		})
   333  		require.NoError(t, err)
   334  	}
   335  }
   336  
   337  func deleteVpc(t *testing.T, vpcId string, region string) {
   338  	ec2Client := NewEc2Client(t, region)
   339  
   340  	deleteRouteTables(t, vpcId, region)
   341  	deleteSubnets(t, vpcId, region)
   342  	deleteInternetGateways(t, vpcId, region)
   343  
   344  	_, err := ec2Client.DeleteVpc(&ec2.DeleteVpcInput{
   345  		VpcId: aws.String(vpcId),
   346  	})
   347  	require.NoError(t, err)
   348  }