func (manager *IPManager) Update(key string, value string) error {
	return manager.client.Put(key, []byte(value), nil)
}
Update updates the value of existed key in the db
package ipstore
import (
	"math/big"
	"net"
	"time"
	"github.com/docker/libkv/store"
	"github.com/docker/libkv/store/boltdb"
	"github.com/pkg/errors"
)
const (
	MaxMask = 30
	IPPrefix = "1"
)
type IPManager struct {
	client      store.Store
	subnet      net.IPNet
	lastKnownIP net.IP
}
type Config struct {
	DB                string
	PersistConnection bool
	Bucket            string
	ConnectionTimeout time.Duration
}
type IPAllocator interface {
	GetAvailableIP(string) (string, error)
	Get(string) (string, error)
	Assign(string, string) error
	Update(string, string) error
	Release(string) error
	ReleaseByID(string) (string, error)
	Exists(string) (bool, error)
	SetLastKnownIP(net.IP)
	Close()
}
func NewIPAllocator(options *Config, subnet net.IPNet) (IPAllocator, error) {
	config := &store.Config{
		PersistConnection: options.PersistConnection,
		ConnectionTimeout: options.ConnectionTimeout,
		Bucket:            options.Bucket,
	}
	client, err := boltdb.New([]string{options.DB}, config)
	if err != nil {
		return nil, err
	}
	return &IPManager{
		client:      client,
		subnet:      subnet,
		lastKnownIP: subnet.IP.Mask(subnet.Mask),
	}, nil
}
func (manager *IPManager) SetLastKnownIP(ip net.IP) {
	manager.lastKnownIP = ip
}
func (manager *IPManager) GetAvailableIP(id string) (string, error) {
	var err error
	nextIP := manager.lastKnownIP
	for {
		nextIP, err = NextIP(nextIP, manager.subnet)
		if err != nil {
			return "", err
		}
		err = manager.Assign(nextIP.String(), id)
		if err != nil && err != store.ErrKeyExists {
			return "", errors.Wrapf(err, "ipstore get ip: failed to assign ip in ipam")
		} else if err == store.ErrKeyExists {
		} else {
			manager.lastKnownIP = nextIP
			return nextIP.String(), nil
		}
		if nextIP.Equal(manager.lastKnownIP) {
			return "", errors.New("getAvailableIP ipstore: failed to find available ip addresses in the subnet")
		}
	}
}
func (manager *IPManager) Get(ip string) (string, error) {
	kvPair, err := manager.client.Get(ip)
	if err != nil && err != store.ErrKeyNotFound {
		return "", errors.Wrapf(err, "get ipstore: failed to get %v from db", kvPair)
	}
	if err == store.ErrKeyNotFound {
		return "", nil
	}
	return string(kvPair.Value), nil
}
func (manager *IPManager) Assign(ip string, id string) error {
	ok, err := manager.Exists(ip)
	if err != nil {
		return errors.Wrapf(err, "assign ipstore: query the db failed, err: %v", err)
	}
	if ok {
		return store.ErrKeyExists
	}
	if id != "" {
		ok, err := manager.UniqueID(id)
		if err != nil {
			return errors.Wrapf(err, "assign ipstore: check id unique failed, id: %s", id)
		}
		if !ok {
			return errors.Errorf("assign ipstore: id already exists, id: %s", id)
		}
	}
	err = manager.client.Put(ip, []byte(id), nil)
	if err != nil {
		return errors.Wrapf(err, "assign ipstore: failed to put the key/value into the db: %s -> %s", ip, id)
	}
	manager.lastKnownIP = net.ParseIP(ip)
	return nil
}
func (manager *IPManager) Release(ip string) error {
	ok, err := manager.Exists(ip)
	if err != nil {
		return errors.Wrap(err, "release ipstore: failed to query the db")
	}
	if !ok {
		return errors.Errorf("release ipstore: ip does not existed in the db: %s", ip)
	}
	err = manager.client.Delete(ip)
	if err != nil {
		return errors.Wrap(err, "release ipstore: failed to delete the key in the db")
	}
	manager.lastKnownIP = net.ParseIP(ip)
	return nil
}
func (manager *IPManager) ReleaseByID(id string) (string, error) {
	kvPairs, err := manager.client.List(IPPrefix)
	if err == store.ErrKeyNotFound {
		return "", errors.Errorf("release ipstore: no ip associated with the id: %s", id)
	}
	if err != nil {
		return "", errors.Wrapf(err, "release ipstore: failed to list the key-value pairs in db")
	}
	var ipDeleted string
	for _, kvPair := range kvPairs {
		if string(kvPair.Value) == id {
			err = manager.Release(kvPair.Key)
			if err != nil {
				return "", err
			}
			ipDeleted = kvPair.Key
			return ipDeleted, nil
		}
	}
	return "", errors.Errorf("release ipstore: no ip address associated with the given id: %s", id)
}
func (manager *IPManager) UniqueID(id string) (bool, error) {
	kvPairs, err := manager.client.List(IPPrefix)
	if err == store.ErrKeyNotFound {
		return true, nil
	}
	if err != nil {
		return false, errors.Wrapf(err, "ipstore: failed to list the key-value pairs in db")
	}
	for _, kvPair := range kvPairs {
		if string(kvPair.Value) == id {
			return false, errors.Errorf("ipstore: id already exists")
		}
	}
	return true, nil
}