github.com/jrperritt/terraform@v0.1.1-0.20170525065507-96f391dafc38/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 tags { 273 Name = "testAccAWSNetworkAclRuleBasicConfig" 274 } 275 } 276 resource "aws_network_acl" "bar" { 277 vpc_id = "${aws_vpc.foo.id}" 278 } 279 resource "aws_network_acl_rule" "baz" { 280 network_acl_id = "${aws_network_acl.bar.id}" 281 rule_number = 200 282 egress = false 283 protocol = "tcp" 284 rule_action = "allow" 285 cidr_block = "0.0.0.0/0" 286 from_port = 22 287 to_port = 22 288 } 289 resource "aws_network_acl_rule" "qux" { 290 network_acl_id = "${aws_network_acl.bar.id}" 291 rule_number = 300 292 protocol = "icmp" 293 rule_action = "allow" 294 cidr_block = "0.0.0.0/0" 295 icmp_type = 0 296 icmp_code = -1 297 } 298 resource "aws_network_acl_rule" "wibble" { 299 network_acl_id = "${aws_network_acl.bar.id}" 300 rule_number = 400 301 protocol = "icmp" 302 rule_action = "allow" 303 cidr_block = "0.0.0.0/0" 304 icmp_type = -1 305 icmp_code = -1 306 } 307 ` 308 309 const testAccAWSNetworkAclRuleMissingParam = ` 310 provider "aws" { 311 region = "us-east-1" 312 } 313 resource "aws_vpc" "foo" { 314 cidr_block = "10.3.0.0/16" 315 tags { 316 Name = "testAccAWSNetworkAclRuleMissingParam" 317 } 318 } 319 resource "aws_network_acl" "bar" { 320 vpc_id = "${aws_vpc.foo.id}" 321 } 322 resource "aws_network_acl_rule" "baz" { 323 network_acl_id = "${aws_network_acl.bar.id}" 324 rule_number = 200 325 egress = false 326 protocol = "tcp" 327 rule_action = "allow" 328 from_port = 22 329 to_port = 22 330 } 331 ` 332 333 const testAccAWSNetworkAclRuleAllProtocolConfigNoRealUpdate = ` 334 resource "aws_vpc" "foo" { 335 cidr_block = "10.3.0.0/16" 336 tags { 337 Name = "testAccAWSNetworkAclRuleAllProtocolConfigNoRealUpdate" 338 } 339 } 340 resource "aws_network_acl" "bar" { 341 vpc_id = "${aws_vpc.foo.id}" 342 } 343 resource "aws_network_acl_rule" "baz" { 344 network_acl_id = "${aws_network_acl.bar.id}" 345 rule_number = 150 346 egress = false 347 protocol = "all" 348 rule_action = "allow" 349 cidr_block = "0.0.0.0/0" 350 from_port = 22 351 to_port = 22 352 } 353 ` 354 355 const testAccAWSNetworkAclRuleAllProtocolConfig = ` 356 resource "aws_vpc" "foo" { 357 cidr_block = "10.3.0.0/16" 358 tags { 359 Name = "testAccAWSNetworkAclRuleAllProtocolConfig" 360 } 361 } 362 resource "aws_network_acl" "bar" { 363 vpc_id = "${aws_vpc.foo.id}" 364 } 365 resource "aws_network_acl_rule" "baz" { 366 network_acl_id = "${aws_network_acl.bar.id}" 367 rule_number = 150 368 egress = false 369 protocol = "-1" 370 rule_action = "allow" 371 cidr_block = "0.0.0.0/0" 372 from_port = 22 373 to_port = 22 374 } 375 ` 376 377 const testAccAWSNetworkAclRuleIpv6Config = ` 378 resource "aws_vpc" "foo" { 379 cidr_block = "10.3.0.0/16" 380 tags { 381 Name = "testAccAWSNetworkAclRuleIpv6Config" 382 } 383 } 384 resource "aws_network_acl" "bar" { 385 vpc_id = "${aws_vpc.foo.id}" 386 } 387 resource "aws_network_acl_rule" "baz" { 388 network_acl_id = "${aws_network_acl.bar.id}" 389 rule_number = 150 390 egress = false 391 protocol = "tcp" 392 rule_action = "allow" 393 ipv6_cidr_block = "::/0" 394 from_port = 22 395 to_port = 22 396 } 397 398 `