From 7767401193fb4cfa90e2e06b4539e36f7ff22d35 Mon Sep 17 00:00:00 2001 From: stack72 Date: Fri, 11 Dec 2015 18:41:33 +0000 Subject: [PATCH] Initial Scaffolding of the AWS Network ACL Entry resource --- builtin/providers/aws/provider.go | 1 + .../aws/resource_aws_network_acl_rule.go | 177 ++++++++++++++++++ 2 files changed, 178 insertions(+) create mode 100644 builtin/providers/aws/resource_aws_network_acl_rule.go diff --git a/builtin/providers/aws/provider.go b/builtin/providers/aws/provider.go index 313f74b18a73..572daf4caa9e 100644 --- a/builtin/providers/aws/provider.go +++ b/builtin/providers/aws/provider.go @@ -229,6 +229,7 @@ func Provider() terraform.ResourceProvider { "aws_lb_cookie_stickiness_policy": resourceAwsLBCookieStickinessPolicy(), "aws_main_route_table_association": resourceAwsMainRouteTableAssociation(), "aws_network_acl": resourceAwsNetworkAcl(), + "aws_network_acl_rule": resourceAwsNetworkAclRule(), "aws_network_interface": resourceAwsNetworkInterface(), "aws_opsworks_stack": resourceAwsOpsworksStack(), "aws_opsworks_java_app_layer": resourceAwsOpsworksJavaAppLayer(), diff --git a/builtin/providers/aws/resource_aws_network_acl_rule.go b/builtin/providers/aws/resource_aws_network_acl_rule.go new file mode 100644 index 000000000000..0a0a629910e4 --- /dev/null +++ b/builtin/providers/aws/resource_aws_network_acl_rule.go @@ -0,0 +1,177 @@ +package aws + +import ( + "fmt" + "log" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceAwsNetworkAclRule() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsNetworkAclRuleCreate, + Read: resourceAwsNetworkAclRuleRead, + Delete: resourceAwsNetworkAclRuleDelete, + + Schema: map[string]*schema.Schema{ + "network_acl_id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "rule_number": &schema.Schema{ + Type: schema.TypeInt, + Required: true, + ForceNew: true, + }, + "egress": &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + ForceNew: true, + Default: false, + }, + "protocol": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "rule_action": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "cidr_block": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "from_port": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + }, + "to_port": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + }, + "icmp_type": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + }, + "icmp_code": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + }, + }, + } +} + +func resourceAwsNetworkAclRuleCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).ec2conn + params := &ec2.CreateNetworkAclEntryInput{ + NetworkAclId: aws.String(d.Get("network_acl_id").(string)), + Egress: aws.Bool(d.Get("egress").(bool)), + RuleNumber: aws.Int64(int64(d.Get("rule_number").(int))), + Protocol: aws.String(d.Get("protocol").(string)), + CidrBlock: aws.String(d.Get("cidr_block").(string)), + RuleAction: aws.String(d.Get("rule_action").(string)), + } + + _, fromOk := d.Get("from_port").(int) + _, toOk := d.Get("to_port").(int) + if fromOk && toOk { + params.PortRange = &ec2.PortRange{ + From: aws.Int64(int64(d.Get("from_port").(int))), + To: aws.Int64(int64(d.Get("to_port").(int))), + } + } + + _, icmpTypeOk := d.Get("icmp_type").(int) + _, icmpCodeOk := d.Get("icmp_code").(int) + if icmpTypeOk && icmpCodeOk { + params.IcmpTypeCode = &ec2.IcmpTypeCode{ + Type: aws.Int64(int64(d.Get("icmp_type").(int))), + Code: aws.Int64(int64(d.Get("icmp_code").(int))), + } + } + + log.Printf("[INFO] Creating Network Acl Rule: %d (%s)", d.Get("rule_number").(int), d.Get("egress").(bool)) + _, err := conn.CreateNetworkAclEntry(params) + if err != nil { + return fmt.Errorf("Error Creating Network Acl Rule: %s", err.Error()) + } + return resourceAwsNetworkAclRuleRead(d, meta) +} + +func findNetworkAclRule(d *schema.ResourceData, meta interface{}) (*ec2.NetworkAclEntry, error) { + conn := meta.(*AWSClient).ec2conn + + filters := make([]*ec2.Filter, 0, 2) + ruleNumberFilter := &ec2.Filter{ + Name: aws.String("entry.rule-number"), + Values: []*string{aws.String(fmt.Sprintf("%v", d.Get("rule_number").(int)))}, + } + filters = append(filters, ruleNumberFilter) + egressFilter := &ec2.Filter{ + Name: aws.String("entry.egress"), + Values: []*string{aws.String(fmt.Sprintf("%v", d.Get("egress").(bool)))}, + } + filters = append(filters, egressFilter) + params := &ec2.DescribeNetworkAclsInput{ + NetworkAclIds: []*string{aws.String(d.Get("network_acl_id").(string))}, + Filters: filters, + } + + log.Printf("[INFO] Describing Network Acl: %s", d.Get("network_acl_id").(string)) + resp, err := conn.DescribeNetworkAcls(params) + if err != nil { + return nil, fmt.Errorf("Error Finding Network Acl Rule %d: %s", d.Get("rule_number").(int), err.Error()) + } + + if resp == nil || len(resp.NetworkAcls) != 1 || resp.NetworkAcls[0] == nil { + return nil, fmt.Errorf( + "Expected to find one Network ACL, got: %#v", + resp.NetworkAcls) + } + networkAcl := resp.NetworkAcls[0] + if len(networkAcl.Entries) != 1 || networkAcl.Entries[0] == nil { + return nil, fmt.Errorf( + "Expected Network ACL to have a Network ACL Rule, got: %#v", + networkAcl.Entries) + + } + return networkAcl.Entries[0], nil + +} + +func resourceAwsNetworkAclRuleRead(d *schema.ResourceData, meta interface{}) error { + _, err := findNetworkAclRule(d, meta) + if err != nil { + return err + } + + return nil +} + +func resourceAwsNetworkAclRuleDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).ec2conn + + params := &ec2.DeleteNetworkAclEntryInput{ + NetworkAclId: aws.String(d.Get("network_acl_id").(string)), + RuleNumber: aws.Int64(int64(d.Get("rule_number").(int))), + Egress: aws.Bool(d.Get("egress").(bool)), + } + + log.Printf("[INFO] Deleting Network Acl Rule: %s", d.Id()) + _, err := conn.DeleteNetworkAclEntry(params) + if err != nil { + return fmt.Errorf("Error Deleting Network Acl Rule: %s", err.Error()) + } + + return nil +}