github.com/flavio/docker@v0.1.3-0.20170117145210-f63d1a6eec47/api/server/router/network/network_routes.go (about)

     1  package network
     2  
     3  import (
     4  	"encoding/json"
     5  	"net/http"
     6  
     7  	"golang.org/x/net/context"
     8  
     9  	"github.com/docker/docker/api/server/httputils"
    10  	"github.com/docker/docker/api/types"
    11  	"github.com/docker/docker/api/types/filters"
    12  	"github.com/docker/docker/api/types/network"
    13  	"github.com/docker/libnetwork"
    14  	"github.com/docker/libnetwork/networkdb"
    15  )
    16  
    17  var (
    18  	// acceptedNetworkFilters is a list of acceptable filters
    19  	acceptedNetworkFilters = map[string]bool{
    20  		"driver": true,
    21  		"type":   true,
    22  		"name":   true,
    23  		"id":     true,
    24  		"label":  true,
    25  	}
    26  )
    27  
    28  func (n *networkRouter) getNetworksList(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
    29  	if err := httputils.ParseForm(r); err != nil {
    30  		return err
    31  	}
    32  
    33  	filter := r.Form.Get("filters")
    34  	netFilters, err := filters.FromParam(filter)
    35  	if err != nil {
    36  		return err
    37  	}
    38  
    39  	if err := netFilters.Validate(acceptedNetworkFilters); err != nil {
    40  		return err
    41  	}
    42  
    43  	list := []types.NetworkResource{}
    44  
    45  	if nr, err := n.cluster.GetNetworks(); err == nil {
    46  		list = append(list, nr...)
    47  	}
    48  
    49  	// Combine the network list returned by Docker daemon if it is not already
    50  	// returned by the cluster manager
    51  SKIP:
    52  	for _, nw := range n.backend.GetNetworks() {
    53  		for _, nl := range list {
    54  			if nl.ID == nw.ID() {
    55  				continue SKIP
    56  			}
    57  		}
    58  		list = append(list, *n.buildNetworkResource(nw))
    59  	}
    60  
    61  	list, err = filterNetworks(list, netFilters)
    62  	if err != nil {
    63  		return err
    64  	}
    65  	return httputils.WriteJSON(w, http.StatusOK, list)
    66  }
    67  
    68  func (n *networkRouter) getNetwork(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
    69  	if err := httputils.ParseForm(r); err != nil {
    70  		return err
    71  	}
    72  
    73  	nw, err := n.backend.FindNetwork(vars["id"])
    74  	if err != nil {
    75  		if nr, err := n.cluster.GetNetwork(vars["id"]); err == nil {
    76  			return httputils.WriteJSON(w, http.StatusOK, nr)
    77  		}
    78  		return err
    79  	}
    80  	return httputils.WriteJSON(w, http.StatusOK, n.buildNetworkResource(nw))
    81  }
    82  
    83  func (n *networkRouter) postNetworkCreate(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
    84  	var create types.NetworkCreateRequest
    85  
    86  	if err := httputils.ParseForm(r); err != nil {
    87  		return err
    88  	}
    89  
    90  	if err := httputils.CheckForJSON(r); err != nil {
    91  		return err
    92  	}
    93  
    94  	if err := json.NewDecoder(r.Body).Decode(&create); err != nil {
    95  		return err
    96  	}
    97  
    98  	if nws, err := n.cluster.GetNetworksByName(create.Name); err == nil && len(nws) > 0 {
    99  		return libnetwork.NetworkNameError(create.Name)
   100  	}
   101  
   102  	nw, err := n.backend.CreateNetwork(create)
   103  	if err != nil {
   104  		if _, ok := err.(libnetwork.ManagerRedirectError); !ok {
   105  			return err
   106  		}
   107  		id, err := n.cluster.CreateNetwork(create)
   108  		if err != nil {
   109  			return err
   110  		}
   111  		nw = &types.NetworkCreateResponse{ID: id}
   112  	}
   113  
   114  	return httputils.WriteJSON(w, http.StatusCreated, nw)
   115  }
   116  
   117  func (n *networkRouter) postNetworkConnect(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
   118  	var connect types.NetworkConnect
   119  	if err := httputils.ParseForm(r); err != nil {
   120  		return err
   121  	}
   122  
   123  	if err := httputils.CheckForJSON(r); err != nil {
   124  		return err
   125  	}
   126  
   127  	if err := json.NewDecoder(r.Body).Decode(&connect); err != nil {
   128  		return err
   129  	}
   130  
   131  	return n.backend.ConnectContainerToNetwork(connect.Container, vars["id"], connect.EndpointConfig)
   132  }
   133  
   134  func (n *networkRouter) postNetworkDisconnect(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
   135  	var disconnect types.NetworkDisconnect
   136  	if err := httputils.ParseForm(r); err != nil {
   137  		return err
   138  	}
   139  
   140  	if err := httputils.CheckForJSON(r); err != nil {
   141  		return err
   142  	}
   143  
   144  	if err := json.NewDecoder(r.Body).Decode(&disconnect); err != nil {
   145  		return err
   146  	}
   147  
   148  	return n.backend.DisconnectContainerFromNetwork(disconnect.Container, vars["id"], disconnect.Force)
   149  }
   150  
   151  func (n *networkRouter) deleteNetwork(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
   152  	if err := httputils.ParseForm(r); err != nil {
   153  		return err
   154  	}
   155  	if _, err := n.cluster.GetNetwork(vars["id"]); err == nil {
   156  		if err = n.cluster.RemoveNetwork(vars["id"]); err != nil {
   157  			return err
   158  		}
   159  		w.WriteHeader(http.StatusNoContent)
   160  		return nil
   161  	}
   162  	if err := n.backend.DeleteNetwork(vars["id"]); err != nil {
   163  		return err
   164  	}
   165  	w.WriteHeader(http.StatusNoContent)
   166  	return nil
   167  }
   168  
   169  func (n *networkRouter) buildNetworkResource(nw libnetwork.Network) *types.NetworkResource {
   170  	r := &types.NetworkResource{}
   171  	if nw == nil {
   172  		return r
   173  	}
   174  
   175  	info := nw.Info()
   176  	r.Name = nw.Name()
   177  	r.ID = nw.ID()
   178  	r.Created = info.Created()
   179  	r.Scope = info.Scope()
   180  	if n.cluster.IsManager() {
   181  		if _, err := n.cluster.GetNetwork(nw.Name()); err == nil {
   182  			r.Scope = "swarm"
   183  		}
   184  	} else if info.Dynamic() {
   185  		r.Scope = "swarm"
   186  	}
   187  	r.Driver = nw.Type()
   188  	r.EnableIPv6 = info.IPv6Enabled()
   189  	r.Internal = info.Internal()
   190  	r.Attachable = info.Attachable()
   191  	r.Options = info.DriverOptions()
   192  	r.Containers = make(map[string]types.EndpointResource)
   193  	buildIpamResources(r, info)
   194  	r.Labels = info.Labels()
   195  
   196  	peers := info.Peers()
   197  	if len(peers) != 0 {
   198  		r.Peers = buildPeerInfoResources(peers)
   199  	}
   200  
   201  	epl := nw.Endpoints()
   202  	for _, e := range epl {
   203  		ei := e.Info()
   204  		if ei == nil {
   205  			continue
   206  		}
   207  		sb := ei.Sandbox()
   208  		tmpID := e.ID()
   209  		key := "ep-" + tmpID
   210  		if sb != nil {
   211  			key = sb.ContainerID()
   212  		}
   213  
   214  		r.Containers[key] = buildEndpointResource(tmpID, e.Name(), ei)
   215  	}
   216  	return r
   217  }
   218  
   219  func buildPeerInfoResources(peers []networkdb.PeerInfo) []network.PeerInfo {
   220  	peerInfo := make([]network.PeerInfo, 0, len(peers))
   221  	for _, peer := range peers {
   222  		peerInfo = append(peerInfo, network.PeerInfo{
   223  			Name: peer.Name,
   224  			IP:   peer.IP,
   225  		})
   226  	}
   227  	return peerInfo
   228  }
   229  
   230  func buildIpamResources(r *types.NetworkResource, nwInfo libnetwork.NetworkInfo) {
   231  	id, opts, ipv4conf, ipv6conf := nwInfo.IpamConfig()
   232  
   233  	ipv4Info, ipv6Info := nwInfo.IpamInfo()
   234  
   235  	r.IPAM.Driver = id
   236  
   237  	r.IPAM.Options = opts
   238  
   239  	r.IPAM.Config = []network.IPAMConfig{}
   240  	for _, ip4 := range ipv4conf {
   241  		if ip4.PreferredPool == "" {
   242  			continue
   243  		}
   244  		iData := network.IPAMConfig{}
   245  		iData.Subnet = ip4.PreferredPool
   246  		iData.IPRange = ip4.SubPool
   247  		iData.Gateway = ip4.Gateway
   248  		iData.AuxAddress = ip4.AuxAddresses
   249  		r.IPAM.Config = append(r.IPAM.Config, iData)
   250  	}
   251  
   252  	if len(r.IPAM.Config) == 0 {
   253  		for _, ip4Info := range ipv4Info {
   254  			iData := network.IPAMConfig{}
   255  			iData.Subnet = ip4Info.IPAMData.Pool.String()
   256  			iData.Gateway = ip4Info.IPAMData.Gateway.IP.String()
   257  			r.IPAM.Config = append(r.IPAM.Config, iData)
   258  		}
   259  	}
   260  
   261  	hasIpv6Conf := false
   262  	for _, ip6 := range ipv6conf {
   263  		if ip6.PreferredPool == "" {
   264  			continue
   265  		}
   266  		hasIpv6Conf = true
   267  		iData := network.IPAMConfig{}
   268  		iData.Subnet = ip6.PreferredPool
   269  		iData.IPRange = ip6.SubPool
   270  		iData.Gateway = ip6.Gateway
   271  		iData.AuxAddress = ip6.AuxAddresses
   272  		r.IPAM.Config = append(r.IPAM.Config, iData)
   273  	}
   274  
   275  	if !hasIpv6Conf {
   276  		for _, ip6Info := range ipv6Info {
   277  			iData := network.IPAMConfig{}
   278  			iData.Subnet = ip6Info.IPAMData.Pool.String()
   279  			iData.Gateway = ip6Info.IPAMData.Gateway.String()
   280  			r.IPAM.Config = append(r.IPAM.Config, iData)
   281  		}
   282  	}
   283  }
   284  
   285  func buildEndpointResource(id string, name string, info libnetwork.EndpointInfo) types.EndpointResource {
   286  	er := types.EndpointResource{}
   287  
   288  	er.EndpointID = id
   289  	er.Name = name
   290  	ei := info
   291  	if ei == nil {
   292  		return er
   293  	}
   294  
   295  	if iface := ei.Iface(); iface != nil {
   296  		if mac := iface.MacAddress(); mac != nil {
   297  			er.MacAddress = mac.String()
   298  		}
   299  		if ip := iface.Address(); ip != nil && len(ip.IP) > 0 {
   300  			er.IPv4Address = ip.String()
   301  		}
   302  
   303  		if ipv6 := iface.AddressIPv6(); ipv6 != nil && len(ipv6.IP) > 0 {
   304  			er.IPv6Address = ipv6.String()
   305  		}
   306  	}
   307  	return er
   308  }
   309  
   310  func (n *networkRouter) postNetworksPrune(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
   311  	if err := httputils.ParseForm(r); err != nil {
   312  		return err
   313  	}
   314  
   315  	pruneFilters, err := filters.FromParam(r.Form.Get("filters"))
   316  	if err != nil {
   317  		return err
   318  	}
   319  
   320  	pruneReport, err := n.backend.NetworksPrune(pruneFilters)
   321  	if err != nil {
   322  		return err
   323  	}
   324  	return httputils.WriteJSON(w, http.StatusOK, pruneReport)
   325  }