github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/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  		}
    36  
    37  		if v, ok := data["ipv6_cidr_block"]; ok {
    38  			e.Ipv6CidrBlock = aws.String(v.(string))
    39  		}
    40  
    41  		if v, ok := data["cidr_block"]; ok {
    42  			e.CidrBlock = aws.String(v.(string))
    43  		}
    44  
    45  		// Specify additional required fields for ICMP
    46  		if p == 1 {
    47  			e.IcmpTypeCode = &ec2.IcmpTypeCode{}
    48  			if v, ok := data["icmp_code"]; ok {
    49  				e.IcmpTypeCode.Code = aws.Int64(int64(v.(int)))
    50  			}
    51  			if v, ok := data["icmp_type"]; ok {
    52  				e.IcmpTypeCode.Type = aws.Int64(int64(v.(int)))
    53  			}
    54  		}
    55  
    56  		entries = append(entries, e)
    57  	}
    58  	return entries, nil
    59  }
    60  
    61  func flattenNetworkAclEntries(list []*ec2.NetworkAclEntry) []map[string]interface{} {
    62  	entries := make([]map[string]interface{}, 0, len(list))
    63  
    64  	for _, entry := range list {
    65  
    66  		newEntry := map[string]interface{}{
    67  			"from_port": *entry.PortRange.From,
    68  			"to_port":   *entry.PortRange.To,
    69  			"action":    *entry.RuleAction,
    70  			"rule_no":   *entry.RuleNumber,
    71  			"protocol":  *entry.Protocol,
    72  		}
    73  
    74  		if entry.CidrBlock != nil {
    75  			newEntry["cidr_block"] = *entry.CidrBlock
    76  		}
    77  
    78  		if entry.Ipv6CidrBlock != nil {
    79  			newEntry["ipv6_cidr_block"] = *entry.Ipv6CidrBlock
    80  		}
    81  
    82  		entries = append(entries, newEntry)
    83  	}
    84  
    85  	return entries
    86  
    87  }
    88  
    89  func protocolStrings(protocolIntegers map[string]int) map[int]string {
    90  	protocolStrings := make(map[int]string, len(protocolIntegers))
    91  	for k, v := range protocolIntegers {
    92  		protocolStrings[v] = k
    93  	}
    94  
    95  	return protocolStrings
    96  }
    97  
    98  func protocolIntegers() map[string]int {
    99  	var protocolIntegers = make(map[string]int)
   100  	protocolIntegers = map[string]int{
   101  		// defined at https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
   102  		"ah":   51,
   103  		"esp":  50,
   104  		"udp":  17,
   105  		"tcp":  6,
   106  		"icmp": 1,
   107  		"all":  -1,
   108  		"vrrp": 112,
   109  	}
   110  	return protocolIntegers
   111  }
   112  
   113  // expectedPortPair stores a pair of ports we expect to see together.
   114  type expectedPortPair struct {
   115  	to_port   int64
   116  	from_port int64
   117  }
   118  
   119  // validatePorts ensures the ports and protocol match expected
   120  // values.
   121  func validatePorts(to int64, from int64, expected expectedPortPair) bool {
   122  	if to != expected.to_port || from != expected.from_port {
   123  		return false
   124  	}
   125  
   126  	return true
   127  }
   128  
   129  // validateCIDRBlock ensures the passed CIDR block represents an implied
   130  // network, and not an overly-specified IP address.
   131  func validateCIDRBlock(cidr string) error {
   132  	_, ipnet, err := net.ParseCIDR(cidr)
   133  	if err != nil {
   134  		return err
   135  	}
   136  	if ipnet.String() != cidr {
   137  		return fmt.Errorf("%s is not a valid mask; did you mean %s?", cidr, ipnet)
   138  	}
   139  
   140  	return nil
   141  }