github.com/turtlemonvh/terraform@v0.6.9-0.20151204001754-8e40b6b855e8/builtin/providers/aws/network_acl_entry.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"net"
     6  	"strconv"
     7  
     8  	"github.com/aws/aws-sdk-go/aws"
     9  	"github.com/aws/aws-sdk-go/service/ec2"
    10  )
    11  
    12  func expandNetworkAclEntries(configured []interface{}, entryType string) ([]*ec2.NetworkAclEntry, error) {
    13  	entries := make([]*ec2.NetworkAclEntry, 0, len(configured))
    14  	for _, eRaw := range configured {
    15  		data := eRaw.(map[string]interface{})
    16  		protocol := data["protocol"].(string)
    17  		p, err := strconv.Atoi(protocol)
    18  		if err != nil {
    19  			var ok bool
    20  			p, ok = protocolIntegers()[protocol]
    21  			if !ok {
    22  				return nil, fmt.Errorf("Invalid Protocol %s for rule %#v", protocol, data)
    23  			}
    24  		}
    25  
    26  		e := &ec2.NetworkAclEntry{
    27  			Protocol: aws.String(strconv.Itoa(p)),
    28  			PortRange: &ec2.PortRange{
    29  				From: aws.Int64(int64(data["from_port"].(int))),
    30  				To:   aws.Int64(int64(data["to_port"].(int))),
    31  			},
    32  			Egress:     aws.Bool(entryType == "egress"),
    33  			RuleAction: aws.String(data["action"].(string)),
    34  			RuleNumber: aws.Int64(int64(data["rule_no"].(int))),
    35  			CidrBlock:  aws.String(data["cidr_block"].(string)),
    36  		}
    37  
    38  		// Specify additional required fields for ICMP
    39  		if p == 1 {
    40  			e.IcmpTypeCode = &ec2.IcmpTypeCode{}
    41  			if v, ok := data["icmp_code"]; ok {
    42  				e.IcmpTypeCode.Code = aws.Int64(int64(v.(int)))
    43  			}
    44  			if v, ok := data["icmp_type"]; ok {
    45  				e.IcmpTypeCode.Type = aws.Int64(int64(v.(int)))
    46  			}
    47  		}
    48  
    49  		entries = append(entries, e)
    50  	}
    51  	return entries, nil
    52  }
    53  
    54  func flattenNetworkAclEntries(list []*ec2.NetworkAclEntry) []map[string]interface{} {
    55  	entries := make([]map[string]interface{}, 0, len(list))
    56  
    57  	for _, entry := range list {
    58  		entries = append(entries, map[string]interface{}{
    59  			"from_port":  *entry.PortRange.From,
    60  			"to_port":    *entry.PortRange.To,
    61  			"action":     *entry.RuleAction,
    62  			"rule_no":    *entry.RuleNumber,
    63  			"protocol":   *entry.Protocol,
    64  			"cidr_block": *entry.CidrBlock,
    65  		})
    66  	}
    67  
    68  	return entries
    69  
    70  }
    71  
    72  func protocolIntegers() map[string]int {
    73  	var protocolIntegers = make(map[string]int)
    74  	protocolIntegers = map[string]int{
    75  		// defined at https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
    76  		"ah":   51,
    77  		"esp":  50,
    78  		"udp":  17,
    79  		"tcp":  6,
    80  		"icmp": 1,
    81  		"all":  -1,
    82  	}
    83  	return protocolIntegers
    84  }
    85  
    86  // expectedPortPair stores a pair of ports we expect to see together.
    87  type expectedPortPair struct {
    88  	to_port   int64
    89  	from_port int64
    90  }
    91  
    92  // validatePorts ensures the ports and protocol match expected
    93  // values.
    94  func validatePorts(to int64, from int64, expected expectedPortPair) bool {
    95  	if to != expected.to_port || from != expected.from_port {
    96  		return false
    97  	}
    98  
    99  	return true
   100  }
   101  
   102  // validateCIDRBlock ensures the passed CIDR block represents an implied
   103  // network, and not an overly-specified IP address.
   104  func validateCIDRBlock(cidr string) error {
   105  	_, ipnet, err := net.ParseCIDR(cidr)
   106  	if err != nil {
   107  		return err
   108  	}
   109  	if ipnet.String() != cidr {
   110  		return fmt.Errorf("%s is not a valid mask; did you mean %s?", cidr, ipnet)
   111  	}
   112  
   113  	return nil
   114  }