github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/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 protocolStrings(protocolIntegers map[string]int) map[int]string { 73 protocolStrings := make(map[int]string, len(protocolIntegers)) 74 for k, v := range protocolIntegers { 75 protocolStrings[v] = k 76 } 77 78 return protocolStrings 79 } 80 81 func protocolIntegers() map[string]int { 82 var protocolIntegers = make(map[string]int) 83 protocolIntegers = map[string]int{ 84 // defined at https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml 85 "ah": 51, 86 "esp": 50, 87 "udp": 17, 88 "tcp": 6, 89 "icmp": 1, 90 "all": -1, 91 "vrrp": 112, 92 } 93 return protocolIntegers 94 } 95 96 // expectedPortPair stores a pair of ports we expect to see together. 97 type expectedPortPair struct { 98 to_port int64 99 from_port int64 100 } 101 102 // validatePorts ensures the ports and protocol match expected 103 // values. 104 func validatePorts(to int64, from int64, expected expectedPortPair) bool { 105 if to != expected.to_port || from != expected.from_port { 106 return false 107 } 108 109 return true 110 } 111 112 // validateCIDRBlock ensures the passed CIDR block represents an implied 113 // network, and not an overly-specified IP address. 114 func validateCIDRBlock(cidr string) error { 115 _, ipnet, err := net.ParseCIDR(cidr) 116 if err != nil { 117 return err 118 } 119 if ipnet.String() != cidr { 120 return fmt.Errorf("%s is not a valid mask; did you mean %s?", cidr, ipnet) 121 } 122 123 return nil 124 }