github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/provider/ec2/subnet.go (about) 1 // Copyright 2017 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package ec2 5 6 import ( 7 "net" 8 "strings" 9 10 "gopkg.in/amz.v3/ec2" 11 ) 12 13 type SubnetMatcher interface { 14 Match(ec2.Subnet) bool 15 } 16 17 // CreateSubnetMatcher creates a SubnetMatcher that handles a particular method 18 // of comparison based on the content of the subnet query. If the query looks 19 // like a CIDR, then we will match subnets with the same CIDR. If it follows 20 // the syntax of a "subnet-XXXX" then we will match the Subnet ID. Everything 21 // else is just matched as a Name. 22 func CreateSubnetMatcher(subnetQuery string) SubnetMatcher { 23 logger.Debugf("searching for subnet matching placement directive %q", subnetQuery) 24 _, ipNet, err := net.ParseCIDR(subnetQuery) 25 if err == nil { 26 return &cidrSubnetMatcher{ 27 ipNet: ipNet, 28 CIDR: ipNet.String(), 29 } 30 } 31 if strings.HasPrefix(subnetQuery, "subnet-") { 32 return &subnetIDMatcher{ 33 subnetID: subnetQuery, 34 } 35 } 36 return &subnetNameMatcher{ 37 name: subnetQuery, 38 } 39 } 40 41 type cidrSubnetMatcher struct { 42 ipNet *net.IPNet 43 CIDR string 44 } 45 46 var _ SubnetMatcher = (*cidrSubnetMatcher)(nil) 47 48 func (sm *cidrSubnetMatcher) Match(subnet ec2.Subnet) bool { 49 _, existingIPNet, err := net.ParseCIDR(subnet.CIDRBlock) 50 if err != nil { 51 logger.Debugf("subnet %#v has invalid CIDRBlock", subnet) 52 return false 53 } 54 if sm.CIDR == existingIPNet.String() { 55 logger.Debugf("found subnet %q by matching subnet CIDR: %s", subnet.Id, sm.CIDR) 56 return true 57 } 58 return false 59 } 60 61 type subnetIDMatcher struct { 62 subnetID string 63 } 64 65 func (sm *subnetIDMatcher) Match(subnet ec2.Subnet) bool { 66 if subnet.Id == sm.subnetID { 67 logger.Debugf("found subnet %q by ID", subnet.Id) 68 return true 69 } 70 return false 71 } 72 73 type subnetNameMatcher struct { 74 name string 75 } 76 77 func (sm *subnetNameMatcher) Match(subnet ec2.Subnet) bool { 78 for _, tag := range subnet.Tags { 79 if tag.Key == "Name" && tag.Value == sm.name { 80 logger.Debugf("found subnet %q matching name %q", subnet.Id, sm.name) 81 return true 82 } 83 } 84 return false 85 }