| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 | // Copyright 2015 go-dockerclient authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package dockerimport (	"bytes"	"encoding/json"	"errors"	"fmt"	"net/http")// ErrNetworkAlreadyExists is the error returned by CreateNetwork when the// network already exists.var ErrNetworkAlreadyExists = errors.New("network already exists")// Network represents a network.//// See https://goo.gl/6GugX3 for more details.type Network struct {	Name       string	ID         string `json:"Id"`	Scope      string	Driver     string	IPAM       IPAMOptions	Containers map[string]Endpoint	Options    map[string]string	Internal   bool	EnableIPv6 bool `json:"EnableIPv6"`}// Endpoint contains network resources allocated and used for a container in a network//// See https://goo.gl/6GugX3 for more details.type Endpoint struct {	Name        string	ID          string `json:"EndpointID"`	MacAddress  string	IPv4Address string	IPv6Address string}// ListNetworks returns all networks.//// See https://goo.gl/6GugX3 for more details.func (c *Client) ListNetworks() ([]Network, error) {	resp, err := c.do("GET", "/networks", doOptions{})	if err != nil {		return nil, err	}	defer resp.Body.Close()	var networks []Network	if err := json.NewDecoder(resp.Body).Decode(&networks); err != nil {		return nil, err	}	return networks, nil}// NetworkFilterOpts is an aggregation of key=value that Docker// uses to filter networkstype NetworkFilterOpts map[string]map[string]bool// FilteredListNetworks returns all networks with the filters applied//// See goo.gl/zd2mx4 for more details.func (c *Client) FilteredListNetworks(opts NetworkFilterOpts) ([]Network, error) {	params := bytes.NewBuffer(nil)	if err := json.NewEncoder(params).Encode(&opts); err != nil {		return nil, err	}	path := "/networks?filters=" + params.String()	resp, err := c.do("GET", path, doOptions{})	if err != nil {		return nil, err	}	defer resp.Body.Close()	var networks []Network	if err := json.NewDecoder(resp.Body).Decode(&networks); err != nil {		return nil, err	}	return networks, nil}// NetworkInfo returns information about a network by its ID.//// See https://goo.gl/6GugX3 for more details.func (c *Client) NetworkInfo(id string) (*Network, error) {	path := "/networks/" + id	resp, err := c.do("GET", path, doOptions{})	if err != nil {		if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound {			return nil, &NoSuchNetwork{ID: id}		}		return nil, err	}	defer resp.Body.Close()	var network Network	if err := json.NewDecoder(resp.Body).Decode(&network); err != nil {		return nil, err	}	return &network, nil}// CreateNetworkOptions specify parameters to the CreateNetwork function and// (for now) is the expected body of the "create network" http request message//// See https://goo.gl/6GugX3 for more details.type CreateNetworkOptions struct {	Name           string                 `json:"Name"`	CheckDuplicate bool                   `json:"CheckDuplicate"`	Driver         string                 `json:"Driver"`	IPAM           IPAMOptions            `json:"IPAM"`	Options        map[string]interface{} `json:"Options"`	Internal       bool                   `json:"Internal"`	EnableIPv6     bool                   `json:"EnableIPv6"`}// IPAMOptions controls IP Address Management when creating a network//// See https://goo.gl/T8kRVH for more details.type IPAMOptions struct {	Driver string       `json:"Driver"`	Config []IPAMConfig `json:"Config"`}// IPAMConfig represents IPAM configurations//// See https://goo.gl/T8kRVH for more details.type IPAMConfig struct {	Subnet     string            `json:",omitempty"`	IPRange    string            `json:",omitempty"`	Gateway    string            `json:",omitempty"`	AuxAddress map[string]string `json:"AuxiliaryAddresses,omitempty"`}// CreateNetwork creates a new network, returning the network instance,// or an error in case of failure.//// See https://goo.gl/6GugX3 for more details.func (c *Client) CreateNetwork(opts CreateNetworkOptions) (*Network, error) {	resp, err := c.do(		"POST",		"/networks/create",		doOptions{			data: opts,		},	)	if err != nil {		if e, ok := err.(*Error); ok && e.Status == http.StatusConflict {			return nil, ErrNetworkAlreadyExists		}		return nil, err	}	defer resp.Body.Close()	type createNetworkResponse struct {		ID string	}	var (		network Network		cnr     createNetworkResponse	)	if err := json.NewDecoder(resp.Body).Decode(&cnr); err != nil {		return nil, err	}	network.Name = opts.Name	network.ID = cnr.ID	network.Driver = opts.Driver	return &network, nil}// RemoveNetwork removes a network or returns an error in case of failure.//// See https://goo.gl/6GugX3 for more details.func (c *Client) RemoveNetwork(id string) error {	resp, err := c.do("DELETE", "/networks/"+id, doOptions{})	if err != nil {		if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound {			return &NoSuchNetwork{ID: id}		}		return err	}	resp.Body.Close()	return nil}// NetworkConnectionOptions specify parameters to the ConnectNetwork and// DisconnectNetwork function.//// See https://goo.gl/RV7BJU for more details.type NetworkConnectionOptions struct {	Container string	// EndpointConfig is only applicable to the ConnectNetwork call	EndpointConfig *EndpointConfig `json:"EndpointConfig,omitempty"`	// Force is only applicable to the DisconnectNetwork call	Force bool}// EndpointConfig stores network endpoint details//// See https://goo.gl/RV7BJU for more details.type EndpointConfig struct {	IPAMConfig *EndpointIPAMConfig	Links      []string	Aliases    []string}// EndpointIPAMConfig represents IPAM configurations for an// endpoint//// See https://goo.gl/RV7BJU for more details.type EndpointIPAMConfig struct {	IPv4Address string `json:",omitempty"`	IPv6Address string `json:",omitempty"`}// ConnectNetwork adds a container to a network or returns an error in case of// failure.//// See https://goo.gl/6GugX3 for more details.func (c *Client) ConnectNetwork(id string, opts NetworkConnectionOptions) error {	resp, err := c.do("POST", "/networks/"+id+"/connect", doOptions{data: opts})	if err != nil {		if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound {			return &NoSuchNetworkOrContainer{NetworkID: id, ContainerID: opts.Container}		}		return err	}	resp.Body.Close()	return nil}// DisconnectNetwork removes a container from a network or returns an error in// case of failure.//// See https://goo.gl/6GugX3 for more details.func (c *Client) DisconnectNetwork(id string, opts NetworkConnectionOptions) error {	resp, err := c.do("POST", "/networks/"+id+"/disconnect", doOptions{data: opts})	if err != nil {		if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound {			return &NoSuchNetworkOrContainer{NetworkID: id, ContainerID: opts.Container}		}		return err	}	resp.Body.Close()	return nil}// NoSuchNetwork is the error returned when a given network does not exist.type NoSuchNetwork struct {	ID string}func (err *NoSuchNetwork) Error() string {	return fmt.Sprintf("No such network: %s", err.ID)}// NoSuchNetworkOrContainer is the error returned when a given network or// container does not exist.type NoSuchNetworkOrContainer struct {	NetworkID   string	ContainerID string}func (err *NoSuchNetworkOrContainer) Error() string {	return fmt.Sprintf("No such network (%s) or container (%s)", err.NetworkID, err.ContainerID)}
 |