github.com/bendemaree/terraform@v0.5.4-0.20150613200311-f50d97d6eee6/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.Long(int64(data["from_port"].(int))),
    30  				To:   aws.Long(int64(data["to_port"].(int))),
    31  			},
    32  			Egress:     aws.Boolean((entryType == "egress")),
    33  			RuleAction: aws.String(data["action"].(string)),
    34  			RuleNumber: aws.Long(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.Long(int64(v.(int)))
    43  			}
    44  			if v, ok := data["icmp_type"]; ok {
    45  				e.ICMPTypeCode.Type = aws.Long(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  		"udp":  17,
    76  		"tcp":  6,
    77  		"icmp": 1,
    78  		"all":  -1,
    79  	}
    80  	return protocolIntegers
    81  }
    82  
    83  // expectedPortPair stores a pair of ports we expect to see together.
    84  type expectedPortPair struct {
    85  	to_port   int64
    86  	from_port int64
    87  }
    88  
    89  // validatePorts ensures the ports and protocol match expected
    90  // values.
    91  func validatePorts(to int64, from int64, expected expectedPortPair) bool {
    92  	if to != expected.to_port || from != expected.from_port {
    93  		return false
    94  	}
    95  
    96  	return true
    97  }
    98  
    99  // validateCIDRBlock ensures the passed CIDR block represents an implied
   100  // network, and not an overly-specified IP address.
   101  func validateCIDRBlock(cidr string) error {
   102  	_, ipnet, err := net.ParseCIDR(cidr)
   103  	if err != nil {
   104  		return err
   105  	}
   106  	if ipnet.String() != cidr {
   107  		return fmt.Errorf("%s is not a valid mask; did you mean %s?", cidr, ipnet)
   108  	}
   109  
   110  	return nil
   111  }