github.com/rawahars/moby@v24.0.4+incompatible/libnetwork/driverapi/ipamdata.go (about)

     1  package driverapi
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"net"
     7  
     8  	"github.com/docker/docker/libnetwork/types"
     9  )
    10  
    11  // MarshalJSON encodes IPAMData into json message
    12  func (i *IPAMData) MarshalJSON() ([]byte, error) {
    13  	m := map[string]interface{}{}
    14  	m["AddressSpace"] = i.AddressSpace
    15  	if i.Pool != nil {
    16  		m["Pool"] = i.Pool.String()
    17  	}
    18  	if i.Gateway != nil {
    19  		m["Gateway"] = i.Gateway.String()
    20  	}
    21  	if i.AuxAddresses != nil {
    22  		am := make(map[string]string, len(i.AuxAddresses))
    23  		for k, v := range i.AuxAddresses {
    24  			am[k] = v.String()
    25  		}
    26  		m["AuxAddresses"] = am
    27  	}
    28  	return json.Marshal(m)
    29  }
    30  
    31  // UnmarshalJSON decodes a json message into IPAMData
    32  func (i *IPAMData) UnmarshalJSON(data []byte) error {
    33  	var (
    34  		m   map[string]interface{}
    35  		err error
    36  	)
    37  	if err := json.Unmarshal(data, &m); err != nil {
    38  		return err
    39  	}
    40  	i.AddressSpace = m["AddressSpace"].(string)
    41  	if v, ok := m["Pool"]; ok {
    42  		if i.Pool, err = types.ParseCIDR(v.(string)); err != nil {
    43  			return err
    44  		}
    45  	}
    46  	if v, ok := m["Gateway"]; ok {
    47  		if i.Gateway, err = types.ParseCIDR(v.(string)); err != nil {
    48  			return err
    49  		}
    50  	}
    51  	if v, ok := m["AuxAddresses"]; ok {
    52  		b, _ := json.Marshal(v)
    53  		var am map[string]string
    54  		if err = json.Unmarshal(b, &am); err != nil {
    55  			return err
    56  		}
    57  		i.AuxAddresses = make(map[string]*net.IPNet, len(am))
    58  		for k, v := range am {
    59  			if i.AuxAddresses[k], err = types.ParseCIDR(v); err != nil {
    60  				return err
    61  			}
    62  		}
    63  	}
    64  	return nil
    65  }
    66  
    67  // Validate checks whether the IPAMData structure contains congruent data
    68  func (i *IPAMData) Validate() error {
    69  	var isV6 bool
    70  	if i.Pool == nil {
    71  		return types.BadRequestErrorf("invalid pool")
    72  	}
    73  	if i.Gateway == nil {
    74  		return types.BadRequestErrorf("invalid gateway address")
    75  	}
    76  	isV6 = i.IsV6()
    77  	if isV6 && i.Gateway.IP.To4() != nil || !isV6 && i.Gateway.IP.To4() == nil {
    78  		return types.BadRequestErrorf("incongruent ip versions for pool and gateway")
    79  	}
    80  	for k, sip := range i.AuxAddresses {
    81  		if isV6 && sip.IP.To4() != nil || !isV6 && sip.IP.To4() == nil {
    82  			return types.BadRequestErrorf("incongruent ip versions for pool and secondary ip address %s", k)
    83  		}
    84  	}
    85  	if !i.Pool.Contains(i.Gateway.IP) {
    86  		return types.BadRequestErrorf("invalid gateway address (%s) does not belong to the pool (%s)", i.Gateway, i.Pool)
    87  	}
    88  	for k, sip := range i.AuxAddresses {
    89  		if !i.Pool.Contains(sip.IP) {
    90  			return types.BadRequestErrorf("invalid secondary address %s (%s) does not belong to the pool (%s)", k, i.Gateway, i.Pool)
    91  		}
    92  	}
    93  	return nil
    94  }
    95  
    96  // IsV6 returns whether this is an IPv6 IPAMData structure
    97  func (i *IPAMData) IsV6() bool {
    98  	return nil == i.Pool.IP.To4()
    99  }
   100  
   101  func (i *IPAMData) String() string {
   102  	return fmt.Sprintf("AddressSpace: %s\nPool: %v\nGateway: %v\nAddresses: %v", i.AddressSpace, i.Pool, i.Gateway, i.AuxAddresses)
   103  }