github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/aws/resource_aws_network_acl_rule_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  	"strconv"
     7  	"testing"
     8  
     9  	"github.com/aws/aws-sdk-go/aws"
    10  	"github.com/aws/aws-sdk-go/aws/awserr"
    11  	"github.com/aws/aws-sdk-go/service/ec2"
    12  	"github.com/hashicorp/terraform/helper/resource"
    13  	"github.com/hashicorp/terraform/terraform"
    14  )
    15  
    16  func TestAccAWSNetworkAclRule_basic(t *testing.T) {
    17  	var networkAcl ec2.NetworkAcl
    18  
    19  	resource.Test(t, resource.TestCase{
    20  		PreCheck:     func() { testAccPreCheck(t) },
    21  		Providers:    testAccProviders,
    22  		CheckDestroy: testAccCheckAWSNetworkAclRuleDestroy,
    23  		Steps: []resource.TestStep{
    24  			{
    25  				Config: testAccAWSNetworkAclRuleBasicConfig,
    26  				Check: resource.ComposeTestCheckFunc(
    27  					testAccCheckAWSNetworkAclRuleExists("aws_network_acl_rule.baz", &networkAcl),
    28  					testAccCheckAWSNetworkAclRuleExists("aws_network_acl_rule.qux", &networkAcl),
    29  					testAccCheckAWSNetworkAclRuleExists("aws_network_acl_rule.wibble", &networkAcl),
    30  				),
    31  			},
    32  		},
    33  	})
    34  }
    35  
    36  func TestAccAWSNetworkAclRule_missingParam(t *testing.T) {
    37  
    38  	resource.Test(t, resource.TestCase{
    39  		PreCheck:     func() { testAccPreCheck(t) },
    40  		Providers:    testAccProviders,
    41  		CheckDestroy: testAccCheckAWSNetworkAclRuleDestroy,
    42  		Steps: []resource.TestStep{
    43  			{
    44  				Config:      testAccAWSNetworkAclRuleMissingParam,
    45  				ExpectError: regexp.MustCompile("Either `cidr_block` or `ipv6_cidr_block` must be defined"),
    46  			},
    47  		},
    48  	})
    49  }
    50  
    51  func TestAccAWSNetworkAclRule_ipv6(t *testing.T) {
    52  	var networkAcl ec2.NetworkAcl
    53  
    54  	resource.Test(t, resource.TestCase{
    55  		PreCheck:     func() { testAccPreCheck(t) },
    56  		Providers:    testAccProviders,
    57  		CheckDestroy: testAccCheckAWSNetworkAclRuleDestroy,
    58  		Steps: []resource.TestStep{
    59  			{
    60  				Config: testAccAWSNetworkAclRuleIpv6Config,
    61  				Check: resource.ComposeTestCheckFunc(
    62  					testAccCheckAWSNetworkAclRuleExists("aws_network_acl_rule.baz", &networkAcl),
    63  				),
    64  			},
    65  		},
    66  	})
    67  }
    68  
    69  func TestAccAWSNetworkAclRule_allProtocol(t *testing.T) {
    70  
    71  	resource.Test(t, resource.TestCase{
    72  		PreCheck:     func() { testAccPreCheck(t) },
    73  		Providers:    testAccProviders,
    74  		CheckDestroy: testAccCheckAWSNetworkAclRuleDestroy,
    75  		Steps: []resource.TestStep{
    76  			{
    77  				Config:             testAccAWSNetworkAclRuleAllProtocolConfig,
    78  				ExpectNonEmptyPlan: false,
    79  			},
    80  			{
    81  				Config:             testAccAWSNetworkAclRuleAllProtocolConfigNoRealUpdate,
    82  				ExpectNonEmptyPlan: false,
    83  			},
    84  		},
    85  	})
    86  }
    87  
    88  func TestResourceAWSNetworkAclRule_validateICMPArgumentValue(t *testing.T) {
    89  	type testCases struct {
    90  		Value    string
    91  		ErrCount int
    92  	}
    93  
    94  	invalidCases := []testCases{
    95  		{
    96  			Value:    "",
    97  			ErrCount: 1,
    98  		},
    99  		{
   100  			Value:    "not-a-number",
   101  			ErrCount: 1,
   102  		},
   103  		{
   104  			Value:    "1.0",
   105  			ErrCount: 1,
   106  		},
   107  	}
   108  
   109  	for _, tc := range invalidCases {
   110  		_, errors := validateICMPArgumentValue(tc.Value, "icmp_type")
   111  		if len(errors) != tc.ErrCount {
   112  			t.Fatalf("Expected %q to trigger a validation error.", tc.Value)
   113  		}
   114  	}
   115  
   116  	validCases := []testCases{
   117  		{
   118  			Value:    "0",
   119  			ErrCount: 0,
   120  		},
   121  		{
   122  			Value:    "-1",
   123  			ErrCount: 0,
   124  		},
   125  		{
   126  			Value:    "1",
   127  			ErrCount: 0,
   128  		},
   129  	}
   130  
   131  	for _, tc := range validCases {
   132  		_, errors := validateICMPArgumentValue(tc.Value, "icmp_type")
   133  		if len(errors) != tc.ErrCount {
   134  			t.Fatalf("Expected %q not to trigger a validation error.", tc.Value)
   135  		}
   136  	}
   137  
   138  }
   139  
   140  func TestAccAWSNetworkAclRule_deleteRule(t *testing.T) {
   141  	var networkAcl ec2.NetworkAcl
   142  
   143  	resource.Test(t, resource.TestCase{
   144  		PreCheck:     func() { testAccPreCheck(t) },
   145  		Providers:    testAccProviders,
   146  		CheckDestroy: testAccCheckAWSNetworkAclRuleDestroy,
   147  		Steps: []resource.TestStep{
   148  			{
   149  				Config: testAccAWSNetworkAclRuleBasicConfig,
   150  				Check: resource.ComposeTestCheckFunc(
   151  					testAccCheckAWSNetworkAclRuleExists("aws_network_acl_rule.baz", &networkAcl),
   152  					testAccCheckAWSNetworkAclRuleDelete("aws_network_acl_rule.baz"),
   153  				),
   154  				ExpectNonEmptyPlan: true,
   155  			},
   156  		},
   157  	})
   158  }
   159  
   160  func testAccCheckAWSNetworkAclRuleDestroy(s *terraform.State) error {
   161  
   162  	for _, rs := range s.RootModule().Resources {
   163  		conn := testAccProvider.Meta().(*AWSClient).ec2conn
   164  		if rs.Type != "aws_network_acl_rule" {
   165  			continue
   166  		}
   167  
   168  		req := &ec2.DescribeNetworkAclsInput{
   169  			NetworkAclIds: []*string{aws.String(rs.Primary.ID)},
   170  		}
   171  		resp, err := conn.DescribeNetworkAcls(req)
   172  		if err == nil {
   173  			if len(resp.NetworkAcls) > 0 && *resp.NetworkAcls[0].NetworkAclId == rs.Primary.ID {
   174  				networkAcl := resp.NetworkAcls[0]
   175  				if networkAcl.Entries != nil {
   176  					return fmt.Errorf("Network ACL Entries still exist")
   177  				}
   178  			}
   179  		}
   180  
   181  		ec2err, ok := err.(awserr.Error)
   182  		if !ok {
   183  			return err
   184  		}
   185  		if ec2err.Code() != "InvalidNetworkAclID.NotFound" {
   186  			return err
   187  		}
   188  	}
   189  
   190  	return nil
   191  }
   192  
   193  func testAccCheckAWSNetworkAclRuleExists(n string, networkAcl *ec2.NetworkAcl) resource.TestCheckFunc {
   194  	return func(s *terraform.State) error {
   195  		conn := testAccProvider.Meta().(*AWSClient).ec2conn
   196  		rs, ok := s.RootModule().Resources[n]
   197  		if !ok {
   198  			return fmt.Errorf("Not found: %s", n)
   199  		}
   200  
   201  		if rs.Primary.ID == "" {
   202  			return fmt.Errorf("No Network ACL Rule Id is set")
   203  		}
   204  
   205  		req := &ec2.DescribeNetworkAclsInput{
   206  			NetworkAclIds: []*string{aws.String(rs.Primary.Attributes["network_acl_id"])},
   207  		}
   208  		resp, err := conn.DescribeNetworkAcls(req)
   209  		if err != nil {
   210  			return err
   211  		}
   212  		if len(resp.NetworkAcls) != 1 {
   213  			return fmt.Errorf("Network ACL not found")
   214  		}
   215  		egress, err := strconv.ParseBool(rs.Primary.Attributes["egress"])
   216  		if err != nil {
   217  			return err
   218  		}
   219  		ruleNo, err := strconv.ParseInt(rs.Primary.Attributes["rule_number"], 10, 64)
   220  		if err != nil {
   221  			return err
   222  		}
   223  		for _, e := range resp.NetworkAcls[0].Entries {
   224  			if *e.RuleNumber == ruleNo && *e.Egress == egress {
   225  				return nil
   226  			}
   227  		}
   228  		return fmt.Errorf("Entry not found: %s", resp.NetworkAcls[0])
   229  	}
   230  }
   231  
   232  func testAccCheckAWSNetworkAclRuleDelete(n string) resource.TestCheckFunc {
   233  	return func(s *terraform.State) error {
   234  		rs, ok := s.RootModule().Resources[n]
   235  		if !ok {
   236  			return fmt.Errorf("Not found: %s", n)
   237  		}
   238  
   239  		if rs.Primary.ID == "" {
   240  			return fmt.Errorf("No Network ACL Rule Id is set")
   241  		}
   242  
   243  		egress, err := strconv.ParseBool(rs.Primary.Attributes["egress"])
   244  		if err != nil {
   245  			return err
   246  		}
   247  		ruleNo, err := strconv.ParseInt(rs.Primary.Attributes["rule_number"], 10, 64)
   248  		if err != nil {
   249  			return err
   250  		}
   251  
   252  		conn := testAccProvider.Meta().(*AWSClient).ec2conn
   253  		_, err = conn.DeleteNetworkAclEntry(&ec2.DeleteNetworkAclEntryInput{
   254  			NetworkAclId: aws.String(rs.Primary.Attributes["network_acl_id"]),
   255  			RuleNumber:   aws.Int64(ruleNo),
   256  			Egress:       aws.Bool(egress),
   257  		})
   258  		if err != nil {
   259  			return fmt.Errorf("Error deleting Network ACL Rule (%s) in testAccCheckAWSNetworkAclRuleDelete: %s", rs.Primary.ID, err)
   260  		}
   261  
   262  		return nil
   263  	}
   264  }
   265  
   266  const testAccAWSNetworkAclRuleBasicConfig = `
   267  provider "aws" {
   268    region = "us-east-1"
   269  }
   270  resource "aws_vpc" "foo" {
   271  	cidr_block = "10.3.0.0/16"
   272  }
   273  resource "aws_network_acl" "bar" {
   274  	vpc_id = "${aws_vpc.foo.id}"
   275  }
   276  resource "aws_network_acl_rule" "baz" {
   277  	network_acl_id = "${aws_network_acl.bar.id}"
   278  	rule_number = 200
   279  	egress = false
   280  	protocol = "tcp"
   281  	rule_action = "allow"
   282  	cidr_block = "0.0.0.0/0"
   283  	from_port = 22
   284  	to_port = 22
   285  }
   286  resource "aws_network_acl_rule" "qux" {
   287  	network_acl_id = "${aws_network_acl.bar.id}"
   288  	rule_number = 300
   289  	protocol = "icmp"
   290  	rule_action = "allow"
   291  	cidr_block = "0.0.0.0/0"
   292  	icmp_type = 0
   293  	icmp_code = -1
   294  }
   295  resource "aws_network_acl_rule" "wibble" {
   296  	network_acl_id = "${aws_network_acl.bar.id}"
   297  	rule_number = 400
   298  	protocol = "icmp"
   299  	rule_action = "allow"
   300  	cidr_block = "0.0.0.0/0"
   301  	icmp_type = -1
   302  	icmp_code = -1
   303  }
   304  `
   305  
   306  const testAccAWSNetworkAclRuleMissingParam = `
   307  provider "aws" {
   308    region = "us-east-1"
   309  }
   310  resource "aws_vpc" "foo" {
   311  	cidr_block = "10.3.0.0/16"
   312  }
   313  resource "aws_network_acl" "bar" {
   314  	vpc_id = "${aws_vpc.foo.id}"
   315  }
   316  resource "aws_network_acl_rule" "baz" {
   317  	network_acl_id = "${aws_network_acl.bar.id}"
   318  	rule_number = 200
   319  	egress = false
   320  	protocol = "tcp"
   321  	rule_action = "allow"
   322  	from_port = 22
   323  	to_port = 22
   324  }
   325  `
   326  
   327  const testAccAWSNetworkAclRuleAllProtocolConfigNoRealUpdate = `
   328  resource "aws_vpc" "foo" {
   329  	cidr_block = "10.3.0.0/16"
   330  }
   331  resource "aws_network_acl" "bar" {
   332  	vpc_id = "${aws_vpc.foo.id}"
   333  }
   334  resource "aws_network_acl_rule" "baz" {
   335  	network_acl_id = "${aws_network_acl.bar.id}"
   336  	rule_number = 150
   337  	egress = false
   338  	protocol = "all"
   339  	rule_action = "allow"
   340  	cidr_block = "0.0.0.0/0"
   341  	from_port = 22
   342  	to_port = 22
   343  }
   344  `
   345  
   346  const testAccAWSNetworkAclRuleAllProtocolConfig = `
   347  resource "aws_vpc" "foo" {
   348  	cidr_block = "10.3.0.0/16"
   349  }
   350  resource "aws_network_acl" "bar" {
   351  	vpc_id = "${aws_vpc.foo.id}"
   352  }
   353  resource "aws_network_acl_rule" "baz" {
   354  	network_acl_id = "${aws_network_acl.bar.id}"
   355  	rule_number = 150
   356  	egress = false
   357  	protocol = "-1"
   358  	rule_action = "allow"
   359  	cidr_block = "0.0.0.0/0"
   360  	from_port = 22
   361  	to_port = 22
   362  }
   363  `
   364  
   365  const testAccAWSNetworkAclRuleIpv6Config = `
   366  resource "aws_vpc" "foo" {
   367  	cidr_block = "10.3.0.0/16"
   368  }
   369  resource "aws_network_acl" "bar" {
   370  	vpc_id = "${aws_vpc.foo.id}"
   371  }
   372  resource "aws_network_acl_rule" "baz" {
   373  	network_acl_id = "${aws_network_acl.bar.id}"
   374  	rule_number = 150
   375  	egress = false
   376  	protocol = "tcp"
   377  	rule_action = "allow"
   378  	ipv6_cidr_block = "::/0"
   379  	from_port = 22
   380  	to_port = 22
   381  }
   382  
   383  `