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