diff --git a/resource_compute_vpn_tunnel.go b/resource_compute_vpn_tunnel.go index d797c6d0..2788dda8 100644 --- a/resource_compute_vpn_tunnel.go +++ b/resource_compute_vpn_tunnel.go @@ -1,8 +1,10 @@ package google import ( + "bytes" "fmt" "log" + "net" "github.com/hashicorp/terraform/helper/schema" @@ -35,9 +37,10 @@ func resourceComputeVpnTunnel() *schema.Resource { ForceNew: true, }, "peer_ip": &schema.Schema{ - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validatePeerAddr, }, "shared_secret": &schema.Schema{ Type: schema.TypeString, @@ -177,3 +180,89 @@ func resourceComputeVpnTunnelDelete(d *schema.ResourceData, meta interface{}) er return nil } + +// validatePeerAddr returns false if a tunnel's peer_ip property +// is invalid. Currently, only addresses that collide with RFC +// 5735 (https://tools.ietf.org/html/rfc5735) fail validation. +func validatePeerAddr(i interface{}, val string) ([]string, []error) { + ip := net.ParseIP(i.(string)) + if ip == nil { + return nil, []error{fmt.Errorf("could not parse %q to IP address", val)} + } + for _, test := range invalidPeerAddrs { + if bytes.Compare(ip, test.from) >= 0 && bytes.Compare(ip, test.to) <= 0 { + return nil, []error{fmt.Errorf("address is invalid (is between %q and %q, conflicting with RFC5735)", test.from, test.to)} + } + } + return nil, nil +} + +// invalidPeerAddrs is a collection of IP addres ranges that represent +// a conflict with RFC 5735 (https://tools.ietf.org/html/rfc5735#page-3). +// CIDR range notations in the RFC were converted to a (from, to) pair +// for easy checking with bytes.Compare. +var invalidPeerAddrs = []struct { + from net.IP + to net.IP +}{ + { + from: net.ParseIP("0.0.0.0"), + to: net.ParseIP("0.255.255.255"), + }, + { + from: net.ParseIP("10.0.0.0"), + to: net.ParseIP("10.255.255.255"), + }, + { + from: net.ParseIP("127.0.0.0"), + to: net.ParseIP("127.255.255.255"), + }, + { + from: net.ParseIP("169.254.0.0"), + to: net.ParseIP("169.254.255.255"), + }, + { + from: net.ParseIP("172.16.0.0"), + to: net.ParseIP("172.31.255.255"), + }, + { + from: net.ParseIP("192.0.0.0"), + to: net.ParseIP("192.0.0.255"), + }, + { + from: net.ParseIP("192.0.2.0"), + to: net.ParseIP("192.0.2.255"), + }, + { + from: net.ParseIP("192.88.99.0"), + to: net.ParseIP("192.88.99.255"), + }, + { + from: net.ParseIP("192.168.0.0"), + to: net.ParseIP("192.168.255.255"), + }, + { + from: net.ParseIP("198.18.0.0"), + to: net.ParseIP("198.19.255.255"), + }, + { + from: net.ParseIP("198.51.100.0"), + to: net.ParseIP("198.51.100.255"), + }, + { + from: net.ParseIP("203.0.113.0"), + to: net.ParseIP("203.0.113.255"), + }, + { + from: net.ParseIP("224.0.0.0"), + to: net.ParseIP("239.255.255.255"), + }, + { + from: net.ParseIP("240.0.0.0"), + to: net.ParseIP("255.255.255.255"), + }, + { + from: net.ParseIP("255.255.255.255"), + to: net.ParseIP("255.255.255.255"), + }, +}