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 }