Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

provider/aws: aws_network_acl_rule #4286

Merged
merged 3 commits into from
Dec 18, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions builtin/providers/aws/network_acl_entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,15 @@ func flattenNetworkAclEntries(list []*ec2.NetworkAclEntry) []map[string]interfac

}

func protocolStrings(protocolIntegers map[string]int) map[int]string {
protocolStrings := make(map[int]string, len(protocolIntegers))
for k, v := range protocolIntegers {
protocolStrings[v] = k
}

return protocolStrings
}

func protocolIntegers() map[string]int {
var protocolIntegers = make(map[string]int)
protocolIntegers = map[string]int{
Expand Down
1 change: 1 addition & 0 deletions builtin/providers/aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ func Provider() terraform.ResourceProvider {
"aws_main_route_table_association": resourceAwsMainRouteTableAssociation(),
"aws_nat_gateway": resourceAwsNatGateway(),
"aws_network_acl": resourceAwsNetworkAcl(),
"aws_network_acl_rule": resourceAwsNetworkAclRule(),
"aws_network_interface": resourceAwsNetworkInterface(),
"aws_opsworks_stack": resourceAwsOpsworksStack(),
"aws_opsworks_java_app_layer": resourceAwsOpsworksJavaAppLayer(),
Expand Down
142 changes: 73 additions & 69 deletions builtin/providers/aws/resource_aws_network_acl.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ func resourceAwsNetworkAcl() *schema.Resource {
Type: schema.TypeSet,
Required: false,
Optional: true,
Computed: false,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"from_port": &schema.Schema{
Expand Down Expand Up @@ -92,6 +93,7 @@ func resourceAwsNetworkAcl() *schema.Resource {
Type: schema.TypeSet,
Required: false,
Optional: true,
Computed: false,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"from_port": &schema.Schema{
Expand Down Expand Up @@ -316,87 +318,89 @@ func resourceAwsNetworkAclUpdate(d *schema.ResourceData, meta interface{}) error

func updateNetworkAclEntries(d *schema.ResourceData, entryType string, conn *ec2.EC2) error {

o, n := d.GetChange(entryType)

if o == nil {
o = new(schema.Set)
}
if n == nil {
n = new(schema.Set)
}

os := o.(*schema.Set)
ns := n.(*schema.Set)

toBeDeleted, err := expandNetworkAclEntries(os.Difference(ns).List(), entryType)
if err != nil {
return err
}
for _, remove := range toBeDeleted {
if d.HasChange(entryType) {
o, n := d.GetChange(entryType)

// AWS includes default rules with all network ACLs that can be
// neither modified nor destroyed. They have a custom rule
// number that is out of bounds for any other rule. If we
// encounter it, just continue. There's no work to be done.
if *remove.RuleNumber == 32767 {
continue
if o == nil {
o = new(schema.Set)
}
if n == nil {
n = new(schema.Set)
}

// Delete old Acl
_, err := conn.DeleteNetworkAclEntry(&ec2.DeleteNetworkAclEntryInput{
NetworkAclId: aws.String(d.Id()),
RuleNumber: remove.RuleNumber,
Egress: remove.Egress,
})
os := o.(*schema.Set)
ns := n.(*schema.Set)

toBeDeleted, err := expandNetworkAclEntries(os.Difference(ns).List(), entryType)
if err != nil {
return fmt.Errorf("Error deleting %s entry: %s", entryType, err)
return err
}
}

toBeCreated, err := expandNetworkAclEntries(ns.Difference(os).List(), entryType)
if err != nil {
return err
}
for _, add := range toBeCreated {
// Protocol -1 rules don't store ports in AWS. Thus, they'll always
// hash differently when being read out of the API. Force the user
// to set from_port and to_port to 0 for these rules, to keep the
// hashing consistent.
if *add.Protocol == "-1" {
to := *add.PortRange.To
from := *add.PortRange.From
expected := &expectedPortPair{
to_port: 0,
from_port: 0,
for _, remove := range toBeDeleted {

// AWS includes default rules with all network ACLs that can be
// neither modified nor destroyed. They have a custom rule
// number that is out of bounds for any other rule. If we
// encounter it, just continue. There's no work to be done.
if *remove.RuleNumber == 32767 {
continue
}
if ok := validatePorts(to, from, *expected); !ok {
return fmt.Errorf(
"to_port (%d) and from_port (%d) must both be 0 to use the the 'all' \"-1\" protocol!",
to, from)

// Delete old Acl
_, err := conn.DeleteNetworkAclEntry(&ec2.DeleteNetworkAclEntryInput{
NetworkAclId: aws.String(d.Id()),
RuleNumber: remove.RuleNumber,
Egress: remove.Egress,
})
if err != nil {
return fmt.Errorf("Error deleting %s entry: %s", entryType, err)
}
}

// AWS mutates the CIDR block into a network implied by the IP and
// mask provided. This results in hashing inconsistencies between
// the local config file and the state returned by the API. Error
// if the user provides a CIDR block with an inappropriate mask
if err := validateCIDRBlock(*add.CidrBlock); err != nil {
toBeCreated, err := expandNetworkAclEntries(ns.Difference(os).List(), entryType)
if err != nil {
return err
}
for _, add := range toBeCreated {
// Protocol -1 rules don't store ports in AWS. Thus, they'll always
// hash differently when being read out of the API. Force the user
// to set from_port and to_port to 0 for these rules, to keep the
// hashing consistent.
if *add.Protocol == "-1" {
to := *add.PortRange.To
from := *add.PortRange.From
expected := &expectedPortPair{
to_port: 0,
from_port: 0,
}
if ok := validatePorts(to, from, *expected); !ok {
return fmt.Errorf(
"to_port (%d) and from_port (%d) must both be 0 to use the the 'all' \"-1\" protocol!",
to, from)
}
}

// Add new Acl entry
_, connErr := conn.CreateNetworkAclEntry(&ec2.CreateNetworkAclEntryInput{
NetworkAclId: aws.String(d.Id()),
CidrBlock: add.CidrBlock,
Egress: add.Egress,
PortRange: add.PortRange,
Protocol: add.Protocol,
RuleAction: add.RuleAction,
RuleNumber: add.RuleNumber,
IcmpTypeCode: add.IcmpTypeCode,
})
if connErr != nil {
return fmt.Errorf("Error creating %s entry: %s", entryType, connErr)
// AWS mutates the CIDR block into a network implied by the IP and
// mask provided. This results in hashing inconsistencies between
// the local config file and the state returned by the API. Error
// if the user provides a CIDR block with an inappropriate mask
if err := validateCIDRBlock(*add.CidrBlock); err != nil {
return err
}

// Add new Acl entry
_, connErr := conn.CreateNetworkAclEntry(&ec2.CreateNetworkAclEntryInput{
NetworkAclId: aws.String(d.Id()),
CidrBlock: add.CidrBlock,
Egress: add.Egress,
PortRange: add.PortRange,
Protocol: add.Protocol,
RuleAction: add.RuleAction,
RuleNumber: add.RuleNumber,
IcmpTypeCode: add.IcmpTypeCode,
})
if connErr != nil {
return fmt.Errorf("Error creating %s entry: %s", entryType, connErr)
}
}
}
return nil
Expand Down
Loading