github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/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 "github.com/aws/aws-sdk-go-v2/aws" 11 "github.com/aws/aws-sdk-go-v2/service/ec2/types" 12 "github.com/kr/pretty" 13 ) 14 15 type SubnetMatcher interface { 16 Match(types.Subnet) bool 17 } 18 19 // CreateSubnetMatcher creates a SubnetMatcher that handles a particular method 20 // of comparison based on the content of the subnet query. If the query looks 21 // like a CIDR, then we will match subnets with the same CIDR. If it follows 22 // the syntax of a "subnet-XXXX" then we will match the Subnet ID. Everything 23 // else is just matched as a Name. 24 func CreateSubnetMatcher(subnetQuery string) SubnetMatcher { 25 logger.Debugf("searching for subnet matching placement directive %q", subnetQuery) 26 _, ipNet, err := net.ParseCIDR(subnetQuery) 27 if err == nil { 28 return &cidrSubnetMatcher{ 29 ipNet: ipNet, 30 CIDR: ipNet.String(), 31 } 32 } 33 if strings.HasPrefix(subnetQuery, "subnet-") { 34 return &subnetIDMatcher{ 35 subnetID: subnetQuery, 36 } 37 } 38 return &subnetNameMatcher{ 39 name: subnetQuery, 40 } 41 } 42 43 type cidrSubnetMatcher struct { 44 ipNet *net.IPNet 45 CIDR string 46 } 47 48 var _ SubnetMatcher = (*cidrSubnetMatcher)(nil) 49 50 func (sm *cidrSubnetMatcher) Match(subnet types.Subnet) bool { 51 _, existingIPNet, err := net.ParseCIDR(aws.ToString(subnet.CidrBlock)) 52 if err != nil { 53 logger.Debugf("subnet %s has invalid CIDRBlock", pretty.Sprint(subnet)) 54 return false 55 } 56 if sm.CIDR == existingIPNet.String() { 57 logger.Debugf("found subnet %q by matching subnet CIDR: %s", aws.ToString(subnet.SubnetId), sm.CIDR) 58 return true 59 } 60 return false 61 } 62 63 type subnetIDMatcher struct { 64 subnetID string 65 } 66 67 func (sm *subnetIDMatcher) Match(subnet types.Subnet) bool { 68 if subnetID := aws.ToString(subnet.SubnetId); subnetID == sm.subnetID { 69 logger.Debugf("found subnet %q by ID", subnetID) 70 return true 71 } 72 return false 73 } 74 75 type subnetNameMatcher struct { 76 name string 77 } 78 79 func (sm *subnetNameMatcher) Match(subnet types.Subnet) bool { 80 for _, tag := range subnet.Tags { 81 if aws.ToString(tag.Key) == "Name" && aws.ToString(tag.Value) == sm.name { 82 logger.Debugf("found subnet %q matching name %q", aws.ToString(subnet.SubnetId), sm.name) 83 return true 84 } 85 } 86 return false 87 }