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  }