github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/core/description/subnet.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package description
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"github.com/juju/schema"
     9  )
    10  
    11  type subnets struct {
    12  	Version  int       `yaml:"version"`
    13  	Subnets_ []*subnet `yaml:"subnets"`
    14  }
    15  
    16  type subnet struct {
    17  	ProviderId_ string `yaml:"provider-id,omitempty"`
    18  	CIDR_       string `yaml:"cidr"`
    19  	VLANTag_    int    `yaml:"vlan-tag"`
    20  
    21  	AvailabilityZone_ string `yaml:"availability-zone"`
    22  	SpaceName_        string `yaml:"space-name"`
    23  
    24  	// These will be deprecated once the address allocation strategy for
    25  	// EC2 is changed. They are unused already on MAAS.
    26  	AllocatableIPHigh_ string `yaml:"allocatable-ip-high,omitempty"`
    27  	AllocatableIPLow_  string `yaml:"allocatable-ip-low,omitempty"`
    28  }
    29  
    30  // SubnetArgs is an argument struct used to create a
    31  // new internal subnet type that supports the Subnet interface.
    32  type SubnetArgs struct {
    33  	ProviderId       string
    34  	CIDR             string
    35  	VLANTag          int
    36  	AvailabilityZone string
    37  	SpaceName        string
    38  
    39  	// These will be deprecated once the address allocation strategy for
    40  	// EC2 is changed. They are unused already on MAAS.
    41  	AllocatableIPHigh string
    42  	AllocatableIPLow  string
    43  }
    44  
    45  func newSubnet(args SubnetArgs) *subnet {
    46  	return &subnet{
    47  		ProviderId_:        string(args.ProviderId),
    48  		SpaceName_:         args.SpaceName,
    49  		CIDR_:              args.CIDR,
    50  		VLANTag_:           args.VLANTag,
    51  		AvailabilityZone_:  args.AvailabilityZone,
    52  		AllocatableIPHigh_: args.AllocatableIPHigh,
    53  		AllocatableIPLow_:  args.AllocatableIPLow,
    54  	}
    55  }
    56  
    57  // ProviderId implements Subnet.
    58  func (s *subnet) ProviderId() string {
    59  	return s.ProviderId_
    60  }
    61  
    62  // SpaceName implements Subnet.
    63  func (s *subnet) SpaceName() string {
    64  	return s.SpaceName_
    65  }
    66  
    67  // CIDR implements Subnet.
    68  func (s *subnet) CIDR() string {
    69  	return s.CIDR_
    70  }
    71  
    72  // VLANTag implements Subnet.
    73  func (s *subnet) VLANTag() int {
    74  	return s.VLANTag_
    75  }
    76  
    77  // AvailabilityZone implements Subnet.
    78  func (s *subnet) AvailabilityZone() string {
    79  	return s.AvailabilityZone_
    80  }
    81  
    82  // AllocatableIPHigh implements Subnet.
    83  func (s *subnet) AllocatableIPHigh() string {
    84  	return s.AllocatableIPHigh_
    85  }
    86  
    87  // AllocatableIPLow implements Subnet.
    88  func (s *subnet) AllocatableIPLow() string {
    89  	return s.AllocatableIPLow_
    90  }
    91  
    92  func importSubnets(source map[string]interface{}) ([]*subnet, error) {
    93  	checker := versionedChecker("subnets")
    94  	coerced, err := checker.Coerce(source, nil)
    95  	if err != nil {
    96  		return nil, errors.Annotatef(err, "subnets version schema check failed")
    97  	}
    98  	valid := coerced.(map[string]interface{})
    99  
   100  	version := int(valid["version"].(int64))
   101  	importFunc, ok := subnetDeserializationFuncs[version]
   102  	if !ok {
   103  		return nil, errors.NotValidf("version %d", version)
   104  	}
   105  	sourceList := valid["subnets"].([]interface{})
   106  	return importSubnetList(sourceList, importFunc)
   107  }
   108  
   109  func importSubnetList(sourceList []interface{}, importFunc subnetDeserializationFunc) ([]*subnet, error) {
   110  	result := make([]*subnet, 0, len(sourceList))
   111  	for i, value := range sourceList {
   112  		source, ok := value.(map[string]interface{})
   113  		if !ok {
   114  			return nil, errors.Errorf("unexpected value for subnet %d, %T", i, value)
   115  		}
   116  		subnet, err := importFunc(source)
   117  		if err != nil {
   118  			return nil, errors.Annotatef(err, "subnet %d", i)
   119  		}
   120  		result = append(result, subnet)
   121  	}
   122  	return result, nil
   123  }
   124  
   125  type subnetDeserializationFunc func(map[string]interface{}) (*subnet, error)
   126  
   127  var subnetDeserializationFuncs = map[int]subnetDeserializationFunc{
   128  	1: importSubnetV1,
   129  }
   130  
   131  func importSubnetV1(source map[string]interface{}) (*subnet, error) {
   132  	fields := schema.Fields{
   133  		"cidr":                schema.String(),
   134  		"provider-id":         schema.String(),
   135  		"vlan-tag":            schema.Int(),
   136  		"space-name":          schema.String(),
   137  		"availability-zone":   schema.String(),
   138  		"allocatable-ip-high": schema.String(),
   139  		"allocatable-ip-low":  schema.String(),
   140  	}
   141  
   142  	defaults := schema.Defaults{
   143  		"provider-id":         "",
   144  		"allocatable-ip-high": "",
   145  		"allocatable-ip-low":  "",
   146  	}
   147  	checker := schema.FieldMap(fields, defaults)
   148  
   149  	coerced, err := checker.Coerce(source, nil)
   150  	if err != nil {
   151  		return nil, errors.Annotatef(err, "subnet v1 schema check failed")
   152  	}
   153  	valid := coerced.(map[string]interface{})
   154  
   155  	// From here we know that the map returned from the schema coercion
   156  	// contains fields of the right type.
   157  	return &subnet{
   158  		CIDR_:              valid["cidr"].(string),
   159  		ProviderId_:        valid["provider-id"].(string),
   160  		VLANTag_:           int(valid["vlan-tag"].(int64)),
   161  		SpaceName_:         valid["space-name"].(string),
   162  		AvailabilityZone_:  valid["availability-zone"].(string),
   163  		AllocatableIPHigh_: valid["allocatable-ip-high"].(string),
   164  		AllocatableIPLow_:  valid["allocatable-ip-low"].(string),
   165  	}, nil
   166  }