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 }