github.com/dinever/docker@v1.11.1/daemon/network.go (about)

     1  package daemon
     2  
     3  import (
     4  	"fmt"
     5  	"net"
     6  	"net/http"
     7  	"strings"
     8  
     9  	"github.com/docker/docker/errors"
    10  	"github.com/docker/docker/runconfig"
    11  	"github.com/docker/engine-api/types/network"
    12  	"github.com/docker/libnetwork"
    13  )
    14  
    15  // NetworkControllerEnabled checks if the networking stack is enabled.
    16  // This feature depends on OS primitives and it's disabled in systems like Windows.
    17  func (daemon *Daemon) NetworkControllerEnabled() bool {
    18  	return daemon.netController != nil
    19  }
    20  
    21  // FindNetwork function finds a network for a given string that can represent network name or id
    22  func (daemon *Daemon) FindNetwork(idName string) (libnetwork.Network, error) {
    23  	// Find by Name
    24  	n, err := daemon.GetNetworkByName(idName)
    25  	if err != nil && !isNoSuchNetworkError(err) {
    26  		return nil, err
    27  	}
    28  
    29  	if n != nil {
    30  		return n, nil
    31  	}
    32  
    33  	// Find by id
    34  	return daemon.GetNetworkByID(idName)
    35  }
    36  
    37  func isNoSuchNetworkError(err error) bool {
    38  	_, ok := err.(libnetwork.ErrNoSuchNetwork)
    39  	return ok
    40  }
    41  
    42  // GetNetworkByID function returns a network whose ID begins with the given prefix.
    43  // It fails with an error if no matching, or more than one matching, networks are found.
    44  func (daemon *Daemon) GetNetworkByID(partialID string) (libnetwork.Network, error) {
    45  	list := daemon.GetNetworksByID(partialID)
    46  
    47  	if len(list) == 0 {
    48  		return nil, libnetwork.ErrNoSuchNetwork(partialID)
    49  	}
    50  	if len(list) > 1 {
    51  		return nil, libnetwork.ErrInvalidID(partialID)
    52  	}
    53  	return list[0], nil
    54  }
    55  
    56  // GetNetworkByName function returns a network for a given network name.
    57  func (daemon *Daemon) GetNetworkByName(name string) (libnetwork.Network, error) {
    58  	c := daemon.netController
    59  	if name == "" {
    60  		name = c.Config().Daemon.DefaultNetwork
    61  	}
    62  	return c.NetworkByName(name)
    63  }
    64  
    65  // GetNetworksByID returns a list of networks whose ID partially matches zero or more networks
    66  func (daemon *Daemon) GetNetworksByID(partialID string) []libnetwork.Network {
    67  	c := daemon.netController
    68  	list := []libnetwork.Network{}
    69  	l := func(nw libnetwork.Network) bool {
    70  		if strings.HasPrefix(nw.ID(), partialID) {
    71  			list = append(list, nw)
    72  		}
    73  		return false
    74  	}
    75  	c.WalkNetworks(l)
    76  
    77  	return list
    78  }
    79  
    80  // GetAllNetworks returns a list containing all networks
    81  func (daemon *Daemon) GetAllNetworks() []libnetwork.Network {
    82  	c := daemon.netController
    83  	list := []libnetwork.Network{}
    84  	l := func(nw libnetwork.Network) bool {
    85  		list = append(list, nw)
    86  		return false
    87  	}
    88  	c.WalkNetworks(l)
    89  
    90  	return list
    91  }
    92  
    93  // CreateNetwork creates a network with the given name, driver and other optional parameters
    94  func (daemon *Daemon) CreateNetwork(name, driver string, ipam network.IPAM, netOption map[string]string, labels map[string]string, internal bool, enableIPv6 bool) (libnetwork.Network, error) {
    95  	c := daemon.netController
    96  	if driver == "" {
    97  		driver = c.Config().Daemon.DefaultDriver
    98  	}
    99  
   100  	v4Conf, v6Conf, err := getIpamConfig(ipam.Config)
   101  	if err != nil {
   102  		return nil, err
   103  	}
   104  
   105  	nwOptions := []libnetwork.NetworkOption{
   106  		libnetwork.NetworkOptionIpam(ipam.Driver, "", v4Conf, v6Conf, ipam.Options),
   107  		libnetwork.NetworkOptionEnableIPv6(enableIPv6),
   108  		libnetwork.NetworkOptionDriverOpts(netOption),
   109  		libnetwork.NetworkOptionLabels(labels),
   110  	}
   111  	if internal {
   112  		nwOptions = append(nwOptions, libnetwork.NetworkOptionInternalNetwork())
   113  	}
   114  	n, err := c.NewNetwork(driver, name, nwOptions...)
   115  	if err != nil {
   116  		return nil, err
   117  	}
   118  
   119  	daemon.LogNetworkEvent(n, "create")
   120  	return n, nil
   121  }
   122  
   123  func getIpamConfig(data []network.IPAMConfig) ([]*libnetwork.IpamConf, []*libnetwork.IpamConf, error) {
   124  	ipamV4Cfg := []*libnetwork.IpamConf{}
   125  	ipamV6Cfg := []*libnetwork.IpamConf{}
   126  	for _, d := range data {
   127  		iCfg := libnetwork.IpamConf{}
   128  		iCfg.PreferredPool = d.Subnet
   129  		iCfg.SubPool = d.IPRange
   130  		iCfg.Gateway = d.Gateway
   131  		iCfg.AuxAddresses = d.AuxAddress
   132  		ip, _, err := net.ParseCIDR(d.Subnet)
   133  		if err != nil {
   134  			return nil, nil, fmt.Errorf("Invalid subnet %s : %v", d.Subnet, err)
   135  		}
   136  		if ip.To4() != nil {
   137  			ipamV4Cfg = append(ipamV4Cfg, &iCfg)
   138  		} else {
   139  			ipamV6Cfg = append(ipamV6Cfg, &iCfg)
   140  		}
   141  	}
   142  	return ipamV4Cfg, ipamV6Cfg, nil
   143  }
   144  
   145  // ConnectContainerToNetwork connects the given container to the given
   146  // network. If either cannot be found, an err is returned. If the
   147  // network cannot be set up, an err is returned.
   148  func (daemon *Daemon) ConnectContainerToNetwork(containerName, networkName string, endpointConfig *network.EndpointSettings) error {
   149  	container, err := daemon.GetContainer(containerName)
   150  	if err != nil {
   151  		return err
   152  	}
   153  	return daemon.ConnectToNetwork(container, networkName, endpointConfig)
   154  }
   155  
   156  // DisconnectContainerFromNetwork disconnects the given container from
   157  // the given network. If either cannot be found, an err is returned.
   158  func (daemon *Daemon) DisconnectContainerFromNetwork(containerName string, network libnetwork.Network, force bool) error {
   159  	container, err := daemon.GetContainer(containerName)
   160  	if err != nil {
   161  		if force {
   162  			return daemon.ForceEndpointDelete(containerName, network)
   163  		}
   164  		return err
   165  	}
   166  	return daemon.DisconnectFromNetwork(container, network, force)
   167  }
   168  
   169  // GetNetworkDriverList returns the list of plugins drivers
   170  // registered for network.
   171  func (daemon *Daemon) GetNetworkDriverList() map[string]bool {
   172  	pluginList := make(map[string]bool)
   173  
   174  	if !daemon.NetworkControllerEnabled() {
   175  		return nil
   176  	}
   177  	c := daemon.netController
   178  	networks := c.Networks()
   179  
   180  	for _, network := range networks {
   181  		driver := network.Type()
   182  		pluginList[driver] = true
   183  	}
   184  
   185  	return pluginList
   186  }
   187  
   188  // DeleteNetwork destroys a network unless it's one of docker's predefined networks.
   189  func (daemon *Daemon) DeleteNetwork(networkID string) error {
   190  	nw, err := daemon.FindNetwork(networkID)
   191  	if err != nil {
   192  		return err
   193  	}
   194  
   195  	if runconfig.IsPreDefinedNetwork(nw.Name()) {
   196  		err := fmt.Errorf("%s is a pre-defined network and cannot be removed", nw.Name())
   197  		return errors.NewErrorWithStatusCode(err, http.StatusForbidden)
   198  	}
   199  
   200  	if err := nw.Delete(); err != nil {
   201  		return err
   202  	}
   203  	daemon.LogNetworkEvent(nw, "destroy")
   204  	return nil
   205  }