dotcloud/docker

View on GitHub
libnetwork/driverapi/ipamdata.go

Summary

Maintainability
A
1 hr
Test Coverage
package driverapi

import (
    "encoding/json"
    "fmt"
    "net"

    "github.com/docker/docker/libnetwork/types"
)

// MarshalJSON encodes IPAMData into json message
func (i *IPAMData) MarshalJSON() ([]byte, error) {
    m := map[string]interface{}{}
    m["AddressSpace"] = i.AddressSpace
    if i.Pool != nil {
        m["Pool"] = i.Pool.String()
    }
    if i.Gateway != nil {
        m["Gateway"] = i.Gateway.String()
    }
    if i.AuxAddresses != nil {
        am := make(map[string]string, len(i.AuxAddresses))
        for k, v := range i.AuxAddresses {
            am[k] = v.String()
        }
        m["AuxAddresses"] = am
    }
    return json.Marshal(m)
}

// UnmarshalJSON decodes a json message into IPAMData
func (i *IPAMData) UnmarshalJSON(data []byte) error {
    var (
        m   map[string]interface{}
        err error
    )
    if err := json.Unmarshal(data, &m); err != nil {
        return err
    }
    i.AddressSpace = m["AddressSpace"].(string)
    if v, ok := m["Pool"]; ok {
        if i.Pool, err = types.ParseCIDR(v.(string)); err != nil {
            return err
        }
    }
    if v, ok := m["Gateway"]; ok {
        if i.Gateway, err = types.ParseCIDR(v.(string)); err != nil {
            return err
        }
    }
    if v, ok := m["AuxAddresses"]; ok {
        b, _ := json.Marshal(v)
        var am map[string]string
        if err = json.Unmarshal(b, &am); err != nil {
            return err
        }
        i.AuxAddresses = make(map[string]*net.IPNet, len(am))
        for k, v := range am {
            if i.AuxAddresses[k], err = types.ParseCIDR(v); err != nil {
                return err
            }
        }
    }
    return nil
}

// Validate checks whether the IPAMData structure contains congruent data
func (i *IPAMData) Validate() error {
    var isV6 bool
    if i.Pool == nil {
        return types.InvalidParameterErrorf("invalid pool")
    }
    if i.Gateway == nil {
        return types.InvalidParameterErrorf("invalid gateway address")
    }
    isV6 = i.IsV6()
    if isV6 && i.Gateway.IP.To4() != nil || !isV6 && i.Gateway.IP.To4() == nil {
        return types.InvalidParameterErrorf("incongruent ip versions for pool and gateway")
    }
    for k, sip := range i.AuxAddresses {
        if isV6 && sip.IP.To4() != nil || !isV6 && sip.IP.To4() == nil {
            return types.InvalidParameterErrorf("incongruent ip versions for pool and secondary ip address %s", k)
        }
    }
    if !i.Pool.Contains(i.Gateway.IP) {
        return types.InvalidParameterErrorf("invalid gateway address (%s) does not belong to the pool (%s)", i.Gateway, i.Pool)
    }
    for k, sip := range i.AuxAddresses {
        if !i.Pool.Contains(sip.IP) {
            return types.InvalidParameterErrorf("invalid secondary address %s (%s) does not belong to the pool (%s)", k, i.Gateway, i.Pool)
        }
    }
    return nil
}

// IsV6 returns whether this is an IPv6 IPAMData structure
func (i *IPAMData) IsV6() bool {
    return nil == i.Pool.IP.To4()
}

func (i *IPAMData) String() string {
    return fmt.Sprintf("AddressSpace: %s\nPool: %v\nGateway: %v\nAddresses: %v", i.AddressSpace, i.Pool, i.Gateway, i.AuxAddresses)
}