github.com/i0n/terraform@v0.4.3-0.20150506151324-010a39a58ec1/builtin/providers/aws/resource_aws_security_group_rule_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"testing"
     7  
     8  	"github.com/awslabs/aws-sdk-go/aws"
     9  	"github.com/awslabs/aws-sdk-go/service/ec2"
    10  	"github.com/hashicorp/terraform/helper/resource"
    11  	"github.com/hashicorp/terraform/terraform"
    12  )
    13  
    14  func TestIpPermissionIDHash(t *testing.T) {
    15  	simple := &ec2.IPPermission{
    16  		IPProtocol: aws.String("tcp"),
    17  		FromPort:   aws.Long(int64(80)),
    18  		ToPort:     aws.Long(int64(8000)),
    19  		IPRanges: []*ec2.IPRange{
    20  			&ec2.IPRange{
    21  				CIDRIP: aws.String("10.0.0.0/8"),
    22  			},
    23  		},
    24  	}
    25  
    26  	egress := &ec2.IPPermission{
    27  		IPProtocol: aws.String("tcp"),
    28  		FromPort:   aws.Long(int64(80)),
    29  		ToPort:     aws.Long(int64(8000)),
    30  		IPRanges: []*ec2.IPRange{
    31  			&ec2.IPRange{
    32  				CIDRIP: aws.String("10.0.0.0/8"),
    33  			},
    34  		},
    35  	}
    36  
    37  	egress_all := &ec2.IPPermission{
    38  		IPProtocol: aws.String("-1"),
    39  		IPRanges: []*ec2.IPRange{
    40  			&ec2.IPRange{
    41  				CIDRIP: aws.String("10.0.0.0/8"),
    42  			},
    43  		},
    44  	}
    45  
    46  	// hardcoded hashes, to detect future change
    47  	cases := []struct {
    48  		Input  *ec2.IPPermission
    49  		Type   string
    50  		Output string
    51  	}{
    52  		{simple, "ingress", "sg-82613597"},
    53  		{egress, "egress", "sg-363054720"},
    54  		{egress_all, "egress", "sg-857124156"},
    55  	}
    56  
    57  	for _, tc := range cases {
    58  		actual := ipPermissionIDHash(tc.Type, tc.Input)
    59  		if actual != tc.Output {
    60  			t.Fatalf("input: %s - %#v\noutput: %s", tc.Type, tc.Input, actual)
    61  		}
    62  	}
    63  }
    64  
    65  func TestAccAWSSecurityGroupRule_Ingress(t *testing.T) {
    66  	var group ec2.SecurityGroup
    67  
    68  	testRuleCount := func(*terraform.State) error {
    69  		if len(group.IPPermissions) != 1 {
    70  			return fmt.Errorf("Wrong Security Group rule count, expected %d, got %d",
    71  				1, len(group.IPPermissions))
    72  		}
    73  
    74  		rule := group.IPPermissions[0]
    75  		if *rule.FromPort != int64(80) {
    76  			return fmt.Errorf("Wrong Security Group port setting, expected %d, got %d",
    77  				80, int(*rule.FromPort))
    78  		}
    79  
    80  		return nil
    81  	}
    82  
    83  	resource.Test(t, resource.TestCase{
    84  		PreCheck:     func() { testAccPreCheck(t) },
    85  		Providers:    testAccProviders,
    86  		CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy,
    87  		Steps: []resource.TestStep{
    88  			resource.TestStep{
    89  				Config: testAccAWSSecurityGroupRuleIngressConfig,
    90  				Check: resource.ComposeTestCheckFunc(
    91  					testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group),
    92  					testAccCheckAWSSecurityGroupRuleAttributes(&group, "ingress"),
    93  					resource.TestCheckResourceAttr(
    94  						"aws_security_group_rule.ingress_1", "from_port", "80"),
    95  					testRuleCount,
    96  				),
    97  			},
    98  		},
    99  	})
   100  }
   101  
   102  func TestAccAWSSecurityGroupRule_IngressClassic(t *testing.T) {
   103  	var group ec2.SecurityGroup
   104  
   105  	testRuleCount := func(*terraform.State) error {
   106  		if len(group.IPPermissions) != 1 {
   107  			return fmt.Errorf("Wrong Security Group rule count, expected %d, got %d",
   108  				1, len(group.IPPermissions))
   109  		}
   110  
   111  		rule := group.IPPermissions[0]
   112  		if *rule.FromPort != int64(80) {
   113  			return fmt.Errorf("Wrong Security Group port setting, expected %d, got %d",
   114  				80, int(*rule.FromPort))
   115  		}
   116  
   117  		return nil
   118  	}
   119  
   120  	resource.Test(t, resource.TestCase{
   121  		PreCheck:     func() { testAccPreCheck(t) },
   122  		Providers:    testAccProviders,
   123  		CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy,
   124  		Steps: []resource.TestStep{
   125  			resource.TestStep{
   126  				Config: testAccAWSSecurityGroupRuleIngressClassicConfig,
   127  				Check: resource.ComposeTestCheckFunc(
   128  					testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group),
   129  					testAccCheckAWSSecurityGroupRuleAttributes(&group, "ingress"),
   130  					resource.TestCheckResourceAttr(
   131  						"aws_security_group_rule.ingress_1", "from_port", "80"),
   132  					testRuleCount,
   133  				),
   134  			},
   135  		},
   136  	})
   137  }
   138  
   139  func TestAccAWSSecurityGroupRule_MultiIngress(t *testing.T) {
   140  	var group ec2.SecurityGroup
   141  
   142  	testMultiRuleCount := func(*terraform.State) error {
   143  		if len(group.IPPermissions) != 3 {
   144  			return fmt.Errorf("Wrong Security Group rule count, expected %d, got %d",
   145  				3, len(group.IPPermissions))
   146  		}
   147  
   148  		var rule *ec2.IPPermission
   149  		for _, r := range group.IPPermissions {
   150  			if *r.FromPort == int64(80) {
   151  				rule = r
   152  			}
   153  		}
   154  
   155  		if *rule.ToPort != int64(8000) {
   156  			return fmt.Errorf("Wrong Security Group port 2 setting, expected %d, got %d",
   157  				8000, int(*rule.ToPort))
   158  		}
   159  
   160  		return nil
   161  	}
   162  
   163  	resource.Test(t, resource.TestCase{
   164  		PreCheck:     func() { testAccPreCheck(t) },
   165  		Providers:    testAccProviders,
   166  		CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy,
   167  		Steps: []resource.TestStep{
   168  			resource.TestStep{
   169  				Config: testAccAWSSecurityGroupRuleConfigMultiIngress,
   170  				Check: resource.ComposeTestCheckFunc(
   171  					testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group),
   172  					testMultiRuleCount,
   173  				),
   174  			},
   175  		},
   176  	})
   177  }
   178  
   179  func TestAccAWSSecurityGroupRule_Egress(t *testing.T) {
   180  	var group ec2.SecurityGroup
   181  
   182  	resource.Test(t, resource.TestCase{
   183  		PreCheck:     func() { testAccPreCheck(t) },
   184  		Providers:    testAccProviders,
   185  		CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy,
   186  		Steps: []resource.TestStep{
   187  			resource.TestStep{
   188  				Config: testAccAWSSecurityGroupRuleEgressConfig,
   189  				Check: resource.ComposeTestCheckFunc(
   190  					testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group),
   191  					testAccCheckAWSSecurityGroupRuleAttributes(&group, "egress"),
   192  				),
   193  			},
   194  		},
   195  	})
   196  }
   197  
   198  func testAccCheckAWSSecurityGroupRuleDestroy(s *terraform.State) error {
   199  	conn := testAccProvider.Meta().(*AWSClient).ec2conn
   200  
   201  	for _, rs := range s.RootModule().Resources {
   202  		if rs.Type != "aws_security_group" {
   203  			continue
   204  		}
   205  
   206  		// Retrieve our group
   207  		req := &ec2.DescribeSecurityGroupsInput{
   208  			GroupIDs: []*string{aws.String(rs.Primary.ID)},
   209  		}
   210  		resp, err := conn.DescribeSecurityGroups(req)
   211  		if err == nil {
   212  			if len(resp.SecurityGroups) > 0 && *resp.SecurityGroups[0].GroupID == rs.Primary.ID {
   213  				return fmt.Errorf("Security Group (%s) still exists.", rs.Primary.ID)
   214  			}
   215  
   216  			return nil
   217  		}
   218  
   219  		ec2err, ok := err.(aws.APIError)
   220  		if !ok {
   221  			return err
   222  		}
   223  		// Confirm error code is what we want
   224  		if ec2err.Code != "InvalidGroup.NotFound" {
   225  			return err
   226  		}
   227  	}
   228  
   229  	return nil
   230  }
   231  
   232  func testAccCheckAWSSecurityGroupRuleExists(n string, group *ec2.SecurityGroup) 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 Security Group is set")
   241  		}
   242  
   243  		conn := testAccProvider.Meta().(*AWSClient).ec2conn
   244  		req := &ec2.DescribeSecurityGroupsInput{
   245  			GroupIDs: []*string{aws.String(rs.Primary.ID)},
   246  		}
   247  		resp, err := conn.DescribeSecurityGroups(req)
   248  		if err != nil {
   249  			return err
   250  		}
   251  
   252  		if len(resp.SecurityGroups) > 0 && *resp.SecurityGroups[0].GroupID == rs.Primary.ID {
   253  			*group = *resp.SecurityGroups[0]
   254  			return nil
   255  		}
   256  
   257  		return fmt.Errorf("Security Group not found")
   258  	}
   259  }
   260  
   261  func testAccCheckAWSSecurityGroupRuleAttributes(group *ec2.SecurityGroup, ruleType string) resource.TestCheckFunc {
   262  	return func(s *terraform.State) error {
   263  		p := &ec2.IPPermission{
   264  			FromPort:   aws.Long(80),
   265  			ToPort:     aws.Long(8000),
   266  			IPProtocol: aws.String("tcp"),
   267  			IPRanges:   []*ec2.IPRange{&ec2.IPRange{CIDRIP: aws.String("10.0.0.0/8")}},
   268  		}
   269  		var rules []*ec2.IPPermission
   270  		if ruleType == "ingress" {
   271  			rules = group.IPPermissions
   272  		} else {
   273  			rules = group.IPPermissionsEgress
   274  		}
   275  
   276  		if len(rules) == 0 {
   277  			return fmt.Errorf("No IPPerms")
   278  		}
   279  
   280  		// Compare our ingress
   281  		if !reflect.DeepEqual(rules[0], p) {
   282  			return fmt.Errorf(
   283  				"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   284  				rules[0],
   285  				p)
   286  		}
   287  
   288  		return nil
   289  	}
   290  }
   291  
   292  const testAccAWSSecurityGroupRuleIngressConfig = `
   293  resource "aws_security_group" "web" {
   294    name = "terraform_acceptance_test_example"
   295    description = "Used in the terraform acceptance tests"
   296  
   297          tags {
   298                  Name = "tf-acc-test"
   299          }
   300  }
   301  
   302  resource "aws_security_group_rule" "ingress_1" {
   303    type = "ingress"
   304    protocol = "tcp"
   305    from_port = 80
   306    to_port = 8000
   307    cidr_blocks = ["10.0.0.0/8"]
   308  
   309    security_group_id = "${aws_security_group.web.id}"
   310  }
   311  `
   312  
   313  const testAccAWSSecurityGroupRuleIngressClassicConfig = `
   314  provider "aws" {
   315          region = "us-east-1"
   316  }
   317  
   318  resource "aws_security_group" "web" {
   319    name = "terraform_acceptance_test_example"
   320    description = "Used in the terraform acceptance tests"
   321  
   322          tags {
   323                  Name = "tf-acc-test"
   324          }
   325  }
   326  
   327  resource "aws_security_group_rule" "ingress_1" {
   328    type = "ingress"
   329    protocol = "tcp"
   330    from_port = 80
   331    to_port = 8000
   332    cidr_blocks = ["10.0.0.0/8"]
   333  
   334    security_group_id = "${aws_security_group.web.id}"
   335  }
   336  `
   337  
   338  const testAccAWSSecurityGroupRuleEgressConfig = `
   339  resource "aws_security_group" "web" {
   340    name = "terraform_acceptance_test_example"
   341    description = "Used in the terraform acceptance tests"
   342  
   343          tags {
   344                  Name = "tf-acc-test"
   345          }
   346  }
   347  
   348  resource "aws_security_group_rule" "egress_1" {
   349    type = "egress"
   350    protocol = "tcp"
   351    from_port = 80
   352    to_port = 8000
   353    cidr_blocks = ["10.0.0.0/8"]
   354  
   355    security_group_id = "${aws_security_group.web.id}"
   356  }
   357  `
   358  
   359  const testAccAWSSecurityGroupRuleConfigMultiIngress = `
   360  resource "aws_security_group" "web" {
   361    name = "terraform_acceptance_test_example_2"
   362    description = "Used in the terraform acceptance tests"
   363  }
   364  
   365  resource "aws_security_group" "worker" {
   366    name = "terraform_acceptance_test_example_worker"
   367    description = "Used in the terraform acceptance tests"
   368  }
   369  
   370  
   371  resource "aws_security_group_rule" "ingress_1" {
   372    type = "ingress"
   373    protocol = "tcp"
   374    from_port = 22
   375    to_port = 22
   376    cidr_blocks = ["10.0.0.0/8"]
   377  
   378    security_group_id = "${aws_security_group.web.id}"
   379          source_security_group_id = "${aws_security_group.worker.id}"
   380  }
   381  
   382  resource "aws_security_group_rule" "ingress_2" {
   383    type = "ingress"
   384    protocol = "tcp"
   385    from_port = 80
   386    to_port = 8000
   387          self = true
   388  
   389    security_group_id = "${aws_security_group.web.id}"
   390  }
   391  `