diff --git a/libnetwork/api/api.go b/libnetwork/api/api.go deleted file mode 100644 index 1ebb2781ee..0000000000 --- a/libnetwork/api/api.go +++ /dev/null @@ -1,973 +0,0 @@ -package api - -import ( - "encoding/json" - "fmt" - "io" - "net/http" - "strconv" - "strings" - - "github.com/docker/docker/libnetwork" - "github.com/docker/docker/libnetwork/netlabel" - "github.com/docker/docker/libnetwork/netutils" - "github.com/docker/docker/libnetwork/types" - "github.com/gorilla/mux" -) - -var ( - successResponse = responseStatus{Status: "Success", StatusCode: http.StatusOK} - createdResponse = responseStatus{Status: "Created", StatusCode: http.StatusCreated} - badQueryResponse = responseStatus{Status: "Unsupported query", StatusCode: http.StatusBadRequest} -) - -const ( - // Resource name regex - // Gorilla mux encloses the passed pattern with '^' and '$'. So we need to do some tricks - // to have mux eventually build a query regex which matches empty or word string (`^$|[\w]+`) - regex = "[a-zA-Z_0-9-]+" - qregx = "$|" + regex - // Router URL variable definition - nwNameQr = "{" + urlNwName + ":" + qregx + "}" - nwID = "{" + urlNwID + ":" + regex + "}" - nwPIDQr = "{" + urlNwPID + ":" + qregx + "}" - epNameQr = "{" + urlEpName + ":" + qregx + "}" - epID = "{" + urlEpID + ":" + regex + "}" - epPIDQr = "{" + urlEpPID + ":" + qregx + "}" - sbID = "{" + urlSbID + ":" + regex + "}" - sbPIDQr = "{" + urlSbPID + ":" + qregx + "}" - cnIDQr = "{" + urlCnID + ":" + qregx + "}" - cnPIDQr = "{" + urlCnPID + ":" + qregx + "}" - - // Internal URL variable name.They can be anything as - // long as they do not collide with query fields. - urlNwName = "network-name" - urlNwID = "network-id" - urlNwPID = "network-partial-id" - urlEpName = "endpoint-name" - urlEpID = "endpoint-id" - urlEpPID = "endpoint-partial-id" - urlSbID = "sandbox-id" - urlSbPID = "sandbox-partial-id" - urlCnID = "container-id" - urlCnPID = "container-partial-id" -) - -// NewHTTPHandler creates and initialize the HTTP handler to serve the requests for libnetwork -func NewHTTPHandler(c libnetwork.NetworkController) func(w http.ResponseWriter, req *http.Request) { - h := &httpHandler{c: c} - h.initRouter() - return h.handleRequest -} - -type responseStatus struct { - Status string - StatusCode int -} - -func (r *responseStatus) isOK() bool { - return r.StatusCode == http.StatusOK || r.StatusCode == http.StatusCreated -} - -type processor func(c libnetwork.NetworkController, vars map[string]string, body []byte) (interface{}, *responseStatus) - -type httpHandler struct { - c libnetwork.NetworkController - r *mux.Router -} - -func (h *httpHandler) handleRequest(w http.ResponseWriter, req *http.Request) { - // Make sure the service is there - if h.c == nil { - http.Error(w, "NetworkController is not available", http.StatusServiceUnavailable) - return - } - - // Get handler from router and execute it - h.r.ServeHTTP(w, req) -} - -func (h *httpHandler) initRouter() { - m := map[string][]struct { - url string - qrs []string - fct processor - }{ - "GET": { - // Order matters - {"/networks", []string{"name", nwNameQr}, procGetNetworks}, - {"/networks", []string{"partial-id", nwPIDQr}, procGetNetworks}, - {"/networks", nil, procGetNetworks}, - {"/networks/" + nwID, nil, procGetNetwork}, - {"/networks/" + nwID + "/endpoints", []string{"name", epNameQr}, procGetEndpoints}, - {"/networks/" + nwID + "/endpoints", []string{"partial-id", epPIDQr}, procGetEndpoints}, - {"/networks/" + nwID + "/endpoints", nil, procGetEndpoints}, - {"/networks/" + nwID + "/endpoints/" + epID, nil, procGetEndpoint}, - {"/services", []string{"network", nwNameQr}, procGetServices}, - {"/services", []string{"name", epNameQr}, procGetServices}, - {"/services", []string{"partial-id", epPIDQr}, procGetServices}, - {"/services", nil, procGetServices}, - {"/services/" + epID, nil, procGetService}, - {"/services/" + epID + "/backend", nil, procGetSandbox}, - {"/sandboxes", []string{"partial-container-id", cnPIDQr}, procGetSandboxes}, - {"/sandboxes", []string{"container-id", cnIDQr}, procGetSandboxes}, - {"/sandboxes", []string{"partial-id", sbPIDQr}, procGetSandboxes}, - {"/sandboxes", nil, procGetSandboxes}, - {"/sandboxes/" + sbID, nil, procGetSandbox}, - }, - "POST": { - {"/networks", nil, procCreateNetwork}, - {"/networks/" + nwID + "/endpoints", nil, procCreateEndpoint}, - {"/networks/" + nwID + "/endpoints/" + epID + "/sandboxes", nil, procJoinEndpoint}, - {"/services", nil, procPublishService}, - {"/services/" + epID + "/backend", nil, procAttachBackend}, - {"/sandboxes", nil, procCreateSandbox}, - }, - "DELETE": { - {"/networks/" + nwID, nil, procDeleteNetwork}, - {"/networks/" + nwID + "/endpoints/" + epID, nil, procDeleteEndpoint}, - {"/networks/" + nwID + "/endpoints/" + epID + "/sandboxes/" + sbID, nil, procLeaveEndpoint}, - {"/services/" + epID, nil, procUnpublishService}, - {"/services/" + epID + "/backend/" + sbID, nil, procDetachBackend}, - {"/sandboxes/" + sbID, nil, procDeleteSandbox}, - }, - } - - h.r = mux.NewRouter() - for method, routes := range m { - for _, route := range routes { - r := h.r.Path("/{.*}" + route.url).Methods(method).HandlerFunc(makeHandler(h.c, route.fct)) - if route.qrs != nil { - r.Queries(route.qrs...) - } - - r = h.r.Path(route.url).Methods(method).HandlerFunc(makeHandler(h.c, route.fct)) - if route.qrs != nil { - r.Queries(route.qrs...) - } - } - } -} - -func makeHandler(ctrl libnetwork.NetworkController, fct processor) http.HandlerFunc { - return func(w http.ResponseWriter, req *http.Request) { - var ( - body []byte - err error - ) - if req.Body != nil { - body, err = io.ReadAll(req.Body) - if err != nil { - http.Error(w, "Invalid body: "+err.Error(), http.StatusBadRequest) - return - } - } - - res, rsp := fct(ctrl, mux.Vars(req), body) - if !rsp.isOK() { - http.Error(w, rsp.Status, rsp.StatusCode) - return - } - if res != nil { - writeJSON(w, rsp.StatusCode, res) - } - } -} - -/***************** - Resource Builders -******************/ - -func buildNetworkResource(nw libnetwork.Network) *networkResource { - r := &networkResource{} - if nw != nil { - r.Name = nw.Name() - r.ID = nw.ID() - r.Type = nw.Type() - epl := nw.Endpoints() - r.Endpoints = make([]*endpointResource, 0, len(epl)) - for _, e := range epl { - epr := buildEndpointResource(e) - r.Endpoints = append(r.Endpoints, epr) - } - } - return r -} - -func buildEndpointResource(ep libnetwork.Endpoint) *endpointResource { - r := &endpointResource{} - if ep != nil { - r.Name = ep.Name() - r.ID = ep.ID() - r.Network = ep.Network() - } - return r -} - -func buildSandboxResource(sb libnetwork.Sandbox) *sandboxResource { - r := &sandboxResource{} - if sb != nil { - r.ID = sb.ID() - r.Key = sb.Key() - r.ContainerID = sb.ContainerID() - } - return r -} - -/**************** - Options Parsers -*****************/ - -func (sc *sandboxCreate) parseOptions() []libnetwork.SandboxOption { - var setFctList []libnetwork.SandboxOption - if sc.HostName != "" { - setFctList = append(setFctList, libnetwork.OptionHostname(sc.HostName)) - } - if sc.DomainName != "" { - setFctList = append(setFctList, libnetwork.OptionDomainname(sc.DomainName)) - } - if sc.HostsPath != "" { - setFctList = append(setFctList, libnetwork.OptionHostsPath(sc.HostsPath)) - } - if sc.ResolvConfPath != "" { - setFctList = append(setFctList, libnetwork.OptionResolvConfPath(sc.ResolvConfPath)) - } - if sc.UseDefaultSandbox { - setFctList = append(setFctList, libnetwork.OptionUseDefaultSandbox()) - } - if sc.UseExternalKey { - setFctList = append(setFctList, libnetwork.OptionUseExternalKey()) - } - if sc.DNS != nil { - for _, d := range sc.DNS { - setFctList = append(setFctList, libnetwork.OptionDNS(d)) - } - } - if sc.ExtraHosts != nil { - for _, e := range sc.ExtraHosts { - setFctList = append(setFctList, libnetwork.OptionExtraHost(e.Name, e.Address)) - } - } - if sc.ExposedPorts != nil { - setFctList = append(setFctList, libnetwork.OptionExposedPorts(sc.ExposedPorts)) - } - if sc.PortMapping != nil { - setFctList = append(setFctList, libnetwork.OptionPortMapping(sc.PortMapping)) - } - return setFctList -} - -/****************** - Process functions -*******************/ - -func processCreateDefaults(c libnetwork.NetworkController, nc *networkCreate) { - if nc.NetworkType == "" { - nc.NetworkType = c.Config().Daemon.DefaultDriver - } -} - -/*************************** - NetworkController interface -****************************/ -func procCreateNetwork(c libnetwork.NetworkController, vars map[string]string, body []byte) (interface{}, *responseStatus) { - var create networkCreate - - err := json.Unmarshal(body, &create) - if err != nil { - return nil, &responseStatus{Status: "Invalid body: " + err.Error(), StatusCode: http.StatusBadRequest} - } - processCreateDefaults(c, &create) - - options := []libnetwork.NetworkOption{} - if val, ok := create.NetworkOpts[netlabel.Internal]; ok { - internal, err := strconv.ParseBool(val) - if err != nil { - return nil, &responseStatus{Status: err.Error(), StatusCode: http.StatusBadRequest} - } - if internal { - options = append(options, libnetwork.NetworkOptionInternalNetwork()) - } - } - if val, ok := create.NetworkOpts[netlabel.EnableIPv6]; ok { - enableIPv6, err := strconv.ParseBool(val) - if err != nil { - return nil, &responseStatus{Status: err.Error(), StatusCode: http.StatusBadRequest} - } - options = append(options, libnetwork.NetworkOptionEnableIPv6(enableIPv6)) - } - if len(create.DriverOpts) > 0 { - options = append(options, libnetwork.NetworkOptionDriverOpts(create.DriverOpts)) - } - - if len(create.IPv4Conf) > 0 { - ipamV4Conf := &libnetwork.IpamConf{ - PreferredPool: create.IPv4Conf[0].PreferredPool, - SubPool: create.IPv4Conf[0].SubPool, - } - - options = append(options, libnetwork.NetworkOptionIpam("default", "", []*libnetwork.IpamConf{ipamV4Conf}, nil, nil)) - } - - nw, err := c.NewNetwork(create.NetworkType, create.Name, create.ID, options...) - if err != nil { - return nil, convertNetworkError(err) - } - - return nw.ID(), &createdResponse -} - -func procGetNetwork(c libnetwork.NetworkController, vars map[string]string, body []byte) (interface{}, *responseStatus) { - t, by := detectNetworkTarget(vars) - nw, errRsp := findNetwork(c, t, by) - if !errRsp.isOK() { - return nil, errRsp - } - return buildNetworkResource(nw), &successResponse -} - -func procGetNetworks(c libnetwork.NetworkController, vars map[string]string, body []byte) (interface{}, *responseStatus) { - var list []*networkResource - - // Look for query filters and validate - name, queryByName := vars[urlNwName] - shortID, queryByPid := vars[urlNwPID] - if queryByName && queryByPid { - return nil, &badQueryResponse - } - - if queryByName { - if nw, errRsp := findNetwork(c, name, byName); errRsp.isOK() { - list = append(list, buildNetworkResource(nw)) - } - } else if queryByPid { - // Return all the prefix-matching networks - l := func(nw libnetwork.Network) bool { - if strings.HasPrefix(nw.ID(), shortID) { - list = append(list, buildNetworkResource(nw)) - } - return false - } - c.WalkNetworks(l) - } else { - for _, nw := range c.Networks() { - list = append(list, buildNetworkResource(nw)) - } - } - - return list, &successResponse -} - -func procCreateSandbox(c libnetwork.NetworkController, vars map[string]string, body []byte) (interface{}, *responseStatus) { - var create sandboxCreate - - err := json.Unmarshal(body, &create) - if err != nil { - return "", &responseStatus{Status: "Invalid body: " + err.Error(), StatusCode: http.StatusBadRequest} - } - - sb, err := c.NewSandbox(create.ContainerID, create.parseOptions()...) - if err != nil { - return "", convertNetworkError(err) - } - - return sb.ID(), &createdResponse -} - -/****************** - Network interface -*******************/ -func procCreateEndpoint(c libnetwork.NetworkController, vars map[string]string, body []byte) (interface{}, *responseStatus) { - var ec endpointCreate - - err := json.Unmarshal(body, &ec) - if err != nil { - return "", &responseStatus{Status: "Invalid body: " + err.Error(), StatusCode: http.StatusBadRequest} - } - - nwT, nwBy := detectNetworkTarget(vars) - n, errRsp := findNetwork(c, nwT, nwBy) - if !errRsp.isOK() { - return "", errRsp - } - - var setFctList []libnetwork.EndpointOption - for _, str := range ec.MyAliases { - setFctList = append(setFctList, libnetwork.CreateOptionMyAlias(str)) - } - - ep, err := n.CreateEndpoint(ec.Name, setFctList...) - if err != nil { - return "", convertNetworkError(err) - } - - return ep.ID(), &createdResponse -} - -func procGetEndpoint(c libnetwork.NetworkController, vars map[string]string, body []byte) (interface{}, *responseStatus) { - nwT, nwBy := detectNetworkTarget(vars) - epT, epBy := detectEndpointTarget(vars) - - ep, errRsp := findEndpoint(c, nwT, epT, nwBy, epBy) - if !errRsp.isOK() { - return nil, errRsp - } - - return buildEndpointResource(ep), &successResponse -} - -func procGetEndpoints(c libnetwork.NetworkController, vars map[string]string, body []byte) (interface{}, *responseStatus) { - // Look for query filters and validate - name, queryByName := vars[urlEpName] - shortID, queryByPid := vars[urlEpPID] - if queryByName && queryByPid { - return nil, &badQueryResponse - } - - nwT, nwBy := detectNetworkTarget(vars) - nw, errRsp := findNetwork(c, nwT, nwBy) - if !errRsp.isOK() { - return nil, errRsp - } - - var list []*endpointResource - - // If query parameter is specified, return a filtered collection - if queryByName { - if ep, errRsp := findEndpoint(c, nwT, name, nwBy, byName); errRsp.isOK() { - list = append(list, buildEndpointResource(ep)) - } - } else if queryByPid { - // Return all the prefix-matching endpoints - l := func(ep libnetwork.Endpoint) bool { - if strings.HasPrefix(ep.ID(), shortID) { - list = append(list, buildEndpointResource(ep)) - } - return false - } - nw.WalkEndpoints(l) - } else { - for _, ep := range nw.Endpoints() { - epr := buildEndpointResource(ep) - list = append(list, epr) - } - } - - return list, &successResponse -} - -func procDeleteNetwork(c libnetwork.NetworkController, vars map[string]string, body []byte) (interface{}, *responseStatus) { - target, by := detectNetworkTarget(vars) - - nw, errRsp := findNetwork(c, target, by) - if !errRsp.isOK() { - return nil, errRsp - } - - err := nw.Delete() - if err != nil { - return nil, convertNetworkError(err) - } - - return nil, &successResponse -} - -/****************** - Endpoint interface -*******************/ -func procJoinEndpoint(c libnetwork.NetworkController, vars map[string]string, body []byte) (interface{}, *responseStatus) { - var ej endpointJoin - var setFctList []libnetwork.EndpointOption - err := json.Unmarshal(body, &ej) - if err != nil { - return nil, &responseStatus{Status: "Invalid body: " + err.Error(), StatusCode: http.StatusBadRequest} - } - - nwT, nwBy := detectNetworkTarget(vars) - epT, epBy := detectEndpointTarget(vars) - - ep, errRsp := findEndpoint(c, nwT, epT, nwBy, epBy) - if !errRsp.isOK() { - return nil, errRsp - } - - sb, errRsp := findSandbox(c, ej.SandboxID, byID) - if !errRsp.isOK() { - return nil, errRsp - } - - for _, str := range ej.Aliases { - name, alias, err := netutils.ParseAlias(str) - if err != nil { - return "", convertNetworkError(err) - } - setFctList = append(setFctList, libnetwork.CreateOptionAlias(name, alias)) - } - - err = ep.Join(sb, setFctList...) - if err != nil { - return nil, convertNetworkError(err) - } - return sb.Key(), &successResponse -} - -func procLeaveEndpoint(c libnetwork.NetworkController, vars map[string]string, body []byte) (interface{}, *responseStatus) { - nwT, nwBy := detectNetworkTarget(vars) - epT, epBy := detectEndpointTarget(vars) - - ep, errRsp := findEndpoint(c, nwT, epT, nwBy, epBy) - if !errRsp.isOK() { - return nil, errRsp - } - - sb, errRsp := findSandbox(c, vars[urlSbID], byID) - if !errRsp.isOK() { - return nil, errRsp - } - - err := ep.Leave(sb) - if err != nil { - return nil, convertNetworkError(err) - } - - return nil, &successResponse -} - -func procDeleteEndpoint(c libnetwork.NetworkController, vars map[string]string, body []byte) (interface{}, *responseStatus) { - nwT, nwBy := detectNetworkTarget(vars) - epT, epBy := detectEndpointTarget(vars) - - ep, errRsp := findEndpoint(c, nwT, epT, nwBy, epBy) - if !errRsp.isOK() { - return nil, errRsp - } - - err := ep.Delete(false) - if err != nil { - return nil, convertNetworkError(err) - } - - return nil, &successResponse -} - -/****************** - Service interface -*******************/ -func procGetServices(c libnetwork.NetworkController, vars map[string]string, body []byte) (interface{}, *responseStatus) { - // Look for query filters and validate - nwName, filterByNwName := vars[urlNwName] - svName, queryBySvName := vars[urlEpName] - shortID, queryBySvPID := vars[urlEpPID] - - if filterByNwName && queryBySvName || filterByNwName && queryBySvPID || queryBySvName && queryBySvPID { - return nil, &badQueryResponse - } - - var list []*endpointResource - - switch { - case filterByNwName: - // return all service present on the specified network - nw, errRsp := findNetwork(c, nwName, byName) - if !errRsp.isOK() { - return list, &successResponse - } - for _, ep := range nw.Endpoints() { - epr := buildEndpointResource(ep) - list = append(list, epr) - } - case queryBySvName: - // Look in each network for the service with the specified name - l := func(ep libnetwork.Endpoint) bool { - if ep.Name() == svName { - list = append(list, buildEndpointResource(ep)) - return true - } - return false - } - for _, nw := range c.Networks() { - nw.WalkEndpoints(l) - } - case queryBySvPID: - // Return all the prefix-matching services - l := func(ep libnetwork.Endpoint) bool { - if strings.HasPrefix(ep.ID(), shortID) { - list = append(list, buildEndpointResource(ep)) - } - return false - } - for _, nw := range c.Networks() { - nw.WalkEndpoints(l) - } - default: - for _, nw := range c.Networks() { - for _, ep := range nw.Endpoints() { - epr := buildEndpointResource(ep) - list = append(list, epr) - } - } - } - - return list, &successResponse -} - -func procGetService(c libnetwork.NetworkController, vars map[string]string, body []byte) (interface{}, *responseStatus) { - epT, epBy := detectEndpointTarget(vars) - sv, errRsp := findService(c, epT, epBy) - if !errRsp.isOK() { - return nil, endpointToService(errRsp) - } - return buildEndpointResource(sv), &successResponse -} - -func procPublishService(c libnetwork.NetworkController, vars map[string]string, body []byte) (interface{}, *responseStatus) { - var sp servicePublish - - err := json.Unmarshal(body, &sp) - if err != nil { - return "", &responseStatus{Status: "Invalid body: " + err.Error(), StatusCode: http.StatusBadRequest} - } - - n, errRsp := findNetwork(c, sp.Network, byName) - if !errRsp.isOK() { - return "", errRsp - } - - var setFctList []libnetwork.EndpointOption - for _, str := range sp.MyAliases { - setFctList = append(setFctList, libnetwork.CreateOptionMyAlias(str)) - } - - ep, err := n.CreateEndpoint(sp.Name, setFctList...) - if err != nil { - return "", endpointToService(convertNetworkError(err)) - } - - return ep.ID(), &createdResponse -} - -func procUnpublishService(c libnetwork.NetworkController, vars map[string]string, body []byte) (interface{}, *responseStatus) { - var sd serviceDelete - - if body != nil { - err := json.Unmarshal(body, &sd) - if err != nil { - return "", &responseStatus{Status: "Invalid body: " + err.Error(), StatusCode: http.StatusBadRequest} - } - } - - epT, epBy := detectEndpointTarget(vars) - sv, errRsp := findService(c, epT, epBy) - if !errRsp.isOK() { - return nil, errRsp - } - - if err := sv.Delete(sd.Force); err != nil { - return nil, endpointToService(convertNetworkError(err)) - } - return nil, &successResponse -} - -func procAttachBackend(c libnetwork.NetworkController, vars map[string]string, body []byte) (interface{}, *responseStatus) { - var bk endpointJoin - var setFctList []libnetwork.EndpointOption - err := json.Unmarshal(body, &bk) - if err != nil { - return nil, &responseStatus{Status: "Invalid body: " + err.Error(), StatusCode: http.StatusBadRequest} - } - - epT, epBy := detectEndpointTarget(vars) - sv, errRsp := findService(c, epT, epBy) - if !errRsp.isOK() { - return nil, errRsp - } - - sb, errRsp := findSandbox(c, bk.SandboxID, byID) - if !errRsp.isOK() { - return nil, errRsp - } - - for _, str := range bk.Aliases { - name, alias, err := netutils.ParseAlias(str) - if err != nil { - return "", convertNetworkError(err) - } - setFctList = append(setFctList, libnetwork.CreateOptionAlias(name, alias)) - } - - err = sv.Join(sb, setFctList...) - if err != nil { - return nil, convertNetworkError(err) - } - - return sb.Key(), &successResponse -} - -func procDetachBackend(c libnetwork.NetworkController, vars map[string]string, body []byte) (interface{}, *responseStatus) { - epT, epBy := detectEndpointTarget(vars) - sv, errRsp := findService(c, epT, epBy) - if !errRsp.isOK() { - return nil, errRsp - } - - sb, errRsp := findSandbox(c, vars[urlSbID], byID) - if !errRsp.isOK() { - return nil, errRsp - } - - err := sv.Leave(sb) - if err != nil { - return nil, convertNetworkError(err) - } - - return nil, &successResponse -} - -/****************** - Sandbox interface -*******************/ -func procGetSandbox(c libnetwork.NetworkController, vars map[string]string, body []byte) (interface{}, *responseStatus) { - if epT, ok := vars[urlEpID]; ok { - sv, errRsp := findService(c, epT, byID) - if !errRsp.isOK() { - return nil, endpointToService(errRsp) - } - return buildSandboxResource(sv.Info().Sandbox()), &successResponse - } - - sbT, by := detectSandboxTarget(vars) - sb, errRsp := findSandbox(c, sbT, by) - if !errRsp.isOK() { - return nil, errRsp - } - return buildSandboxResource(sb), &successResponse -} - -type cndFnMkr func(string) cndFn -type cndFn func(libnetwork.Sandbox) bool - -// list of (query type, condition function makers) couples -var cndMkrList = []struct { - identifier string - maker cndFnMkr -}{ - {urlSbPID, func(id string) cndFn { - return func(sb libnetwork.Sandbox) bool { return strings.HasPrefix(sb.ID(), id) } - }}, - {urlCnID, func(id string) cndFn { - return func(sb libnetwork.Sandbox) bool { return sb.ContainerID() == id } - }}, - {urlCnPID, func(id string) cndFn { - return func(sb libnetwork.Sandbox) bool { return strings.HasPrefix(sb.ContainerID(), id) } - }}, -} - -func getQueryCondition(vars map[string]string) func(libnetwork.Sandbox) bool { - for _, im := range cndMkrList { - if val, ok := vars[im.identifier]; ok { - return im.maker(val) - } - } - return func(sb libnetwork.Sandbox) bool { return true } -} - -func sandboxWalker(condition cndFn, list *[]*sandboxResource) libnetwork.SandboxWalker { - return func(sb libnetwork.Sandbox) bool { - if condition(sb) { - *list = append(*list, buildSandboxResource(sb)) - } - return false - } -} - -func procGetSandboxes(c libnetwork.NetworkController, vars map[string]string, body []byte) (interface{}, *responseStatus) { - var list []*sandboxResource - - cnd := getQueryCondition(vars) - c.WalkSandboxes(sandboxWalker(cnd, &list)) - - return list, &successResponse -} - -func procDeleteSandbox(c libnetwork.NetworkController, vars map[string]string, body []byte) (interface{}, *responseStatus) { - sbT, by := detectSandboxTarget(vars) - - sb, errRsp := findSandbox(c, sbT, by) - if !errRsp.isOK() { - return nil, errRsp - } - - err := sb.Delete() - if err != nil { - return nil, convertNetworkError(err) - } - - return nil, &successResponse -} - -/*********** - Utilities -************/ -const ( - byID = iota - byName -) - -func detectNetworkTarget(vars map[string]string) (string, int) { - if target, ok := vars[urlNwName]; ok { - return target, byName - } - if target, ok := vars[urlNwID]; ok { - return target, byID - } - // vars are populated from the URL, following cannot happen - panic("Missing URL variable parameter for network") -} - -func detectSandboxTarget(vars map[string]string) (string, int) { - if target, ok := vars[urlSbID]; ok { - return target, byID - } - // vars are populated from the URL, following cannot happen - panic("Missing URL variable parameter for sandbox") -} - -func detectEndpointTarget(vars map[string]string) (string, int) { - if target, ok := vars[urlEpName]; ok { - return target, byName - } - if target, ok := vars[urlEpID]; ok { - return target, byID - } - // vars are populated from the URL, following cannot happen - panic("Missing URL variable parameter for endpoint") -} - -func findNetwork(c libnetwork.NetworkController, s string, by int) (libnetwork.Network, *responseStatus) { - var ( - nw libnetwork.Network - err error - ) - switch by { - case byID: - nw, err = c.NetworkByID(s) - case byName: - if s == "" { - s = c.Config().Daemon.DefaultNetwork - } - nw, err = c.NetworkByName(s) - default: - panic(fmt.Sprintf("unexpected selector for network search: %d", by)) - } - if err != nil { - if _, ok := err.(types.NotFoundError); ok { - return nil, &responseStatus{Status: "Resource not found: Network", StatusCode: http.StatusNotFound} - } - return nil, &responseStatus{Status: err.Error(), StatusCode: http.StatusBadRequest} - } - return nw, &successResponse -} - -func findSandbox(c libnetwork.NetworkController, s string, by int) (libnetwork.Sandbox, *responseStatus) { - var ( - sb libnetwork.Sandbox - err error - ) - - switch by { - case byID: - sb, err = c.SandboxByID(s) - default: - panic(fmt.Sprintf("unexpected selector for sandbox search: %d", by)) - } - if err != nil { - if _, ok := err.(types.NotFoundError); ok { - return nil, &responseStatus{Status: "Resource not found: Sandbox", StatusCode: http.StatusNotFound} - } - return nil, &responseStatus{Status: err.Error(), StatusCode: http.StatusBadRequest} - } - return sb, &successResponse -} - -func findEndpoint(c libnetwork.NetworkController, ns, es string, nwBy, epBy int) (libnetwork.Endpoint, *responseStatus) { - nw, errRsp := findNetwork(c, ns, nwBy) - if !errRsp.isOK() { - return nil, errRsp - } - var ( - err error - ep libnetwork.Endpoint - ) - switch epBy { - case byID: - ep, err = nw.EndpointByID(es) - case byName: - ep, err = nw.EndpointByName(es) - default: - panic(fmt.Sprintf("unexpected selector for endpoint search: %d", epBy)) - } - if err != nil { - if _, ok := err.(types.NotFoundError); ok { - return nil, &responseStatus{Status: "Resource not found: Endpoint", StatusCode: http.StatusNotFound} - } - return nil, &responseStatus{Status: err.Error(), StatusCode: http.StatusBadRequest} - } - return ep, &successResponse -} - -func findService(c libnetwork.NetworkController, svs string, svBy int) (libnetwork.Endpoint, *responseStatus) { - for _, nw := range c.Networks() { - var ( - ep libnetwork.Endpoint - err error - ) - switch svBy { - case byID: - ep, err = nw.EndpointByID(svs) - case byName: - ep, err = nw.EndpointByName(svs) - default: - panic(fmt.Sprintf("unexpected selector for service search: %d", svBy)) - } - if err == nil { - return ep, &successResponse - } else if _, ok := err.(types.NotFoundError); !ok { - return nil, convertNetworkError(err) - } - } - return nil, &responseStatus{Status: "Service not found", StatusCode: http.StatusNotFound} -} - -func endpointToService(rsp *responseStatus) *responseStatus { - rsp.Status = strings.Replace(rsp.Status, "endpoint", "service", -1) - return rsp -} - -func convertNetworkError(err error) *responseStatus { - var code int - switch err.(type) { - case types.BadRequestError: - code = http.StatusBadRequest - case types.ForbiddenError: - code = http.StatusForbidden - case types.NotFoundError: - code = http.StatusNotFound - case types.TimeoutError: - code = http.StatusRequestTimeout - case types.NotImplementedError: - code = http.StatusNotImplemented - case types.NoServiceError: - code = http.StatusServiceUnavailable - case types.InternalError: - code = http.StatusInternalServerError - default: - code = http.StatusInternalServerError - } - return &responseStatus{Status: err.Error(), StatusCode: code} -} - -func writeJSON(w http.ResponseWriter, code int, v interface{}) error { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(code) - return json.NewEncoder(w).Encode(v) -} diff --git a/libnetwork/api/api_linux_test.go b/libnetwork/api/api_linux_test.go deleted file mode 100644 index 1d37d0aca8..0000000000 --- a/libnetwork/api/api_linux_test.go +++ /dev/null @@ -1,2404 +0,0 @@ -package api - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "io" - "net/http" - "os" - "regexp" - "runtime" - "testing" - - "github.com/docker/docker/libnetwork" - "github.com/docker/docker/libnetwork/datastore" - "github.com/docker/docker/libnetwork/drivers/bridge" - "github.com/docker/docker/libnetwork/netlabel" - "github.com/docker/docker/libnetwork/options" - "github.com/docker/docker/libnetwork/testutils" - "github.com/docker/docker/libnetwork/types" - "github.com/docker/docker/pkg/reexec" -) - -const ( - bridgeNetType = "bridge" -) - -func i2s(i interface{}) string { - s, ok := i.(string) - if !ok { - panic(fmt.Sprintf("Failed i2s for %v", i)) - } - return s -} - -func i2e(i interface{}) *endpointResource { - s, ok := i.(*endpointResource) - if !ok { - panic(fmt.Sprintf("Failed i2e for %v", i)) - } - return s -} - -func i2eL(i interface{}) []*endpointResource { - s, ok := i.([]*endpointResource) - if !ok { - panic(fmt.Sprintf("Failed i2eL for %v", i)) - } - return s -} - -func i2n(i interface{}) *networkResource { - s, ok := i.(*networkResource) - if !ok { - panic(fmt.Sprintf("Failed i2n for %v", i)) - } - return s -} - -func i2nL(i interface{}) []*networkResource { - s, ok := i.([]*networkResource) - if !ok { - panic(fmt.Sprintf("Failed i2nL for %v", i)) - } - return s -} - -func i2sb(i interface{}) *sandboxResource { - s, ok := i.(*sandboxResource) - if !ok { - panic(fmt.Sprintf("Failed i2sb for %v", i)) - } - return s -} - -func i2sbL(i interface{}) []*sandboxResource { - s, ok := i.([]*sandboxResource) - if !ok { - panic(fmt.Sprintf("Failed i2sbL for %v", i)) - } - return s -} - -func createTestNetwork(t *testing.T, network string) (libnetwork.NetworkController, libnetwork.Network) { - // Cleanup local datastore file - os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address) - - c, err := libnetwork.New() - if err != nil { - t.Fatal(err) - } - - netOption := options.Generic{ - netlabel.GenericData: options.Generic{ - "BridgeName": network, - }, - } - netGeneric := libnetwork.NetworkOptionGeneric(netOption) - nw, err := c.NewNetwork(bridgeNetType, network, "", netGeneric) - if err != nil { - t.Fatal(err) - } - - return c, nw -} - -func GetOpsMap(bridgeName, defaultMTU string) map[string]string { - if defaultMTU == "" { - return map[string]string{ - bridge.BridgeName: bridgeName, - } - } - return map[string]string{ - bridge.BridgeName: bridgeName, - netlabel.DriverMTU: defaultMTU, - } -} - -func getExposedPorts() []types.TransportPort { - return []types.TransportPort{ - {Proto: types.TCP, Port: uint16(5000)}, - {Proto: types.UDP, Port: uint16(400)}, - {Proto: types.TCP, Port: uint16(600)}, - } -} - -func getPortMapping() []types.PortBinding { - return []types.PortBinding{ - {Proto: types.TCP, Port: uint16(230), HostPort: uint16(23000)}, - {Proto: types.UDP, Port: uint16(200), HostPort: uint16(22000)}, - {Proto: types.TCP, Port: uint16(120), HostPort: uint16(12000)}, - } -} - -func TestMain(m *testing.M) { - if reexec.Init() { - return - } - os.Exit(m.Run()) -} - -func TestSandboxOptionParser(t *testing.T) { - hn := "host1" - dn := "docker.com" - hp := "/etc/hosts" - rc := "/etc/resolv.conf" - dnss := []string{"8.8.8.8", "172.28.34.5"} - ehs := []extraHost{{Name: "extra1", Address: "172.28.9.1"}, {Name: "extra2", Address: "172.28.9.2"}} - - sb := sandboxCreate{ - HostName: hn, - DomainName: dn, - HostsPath: hp, - ResolvConfPath: rc, - DNS: dnss, - ExtraHosts: ehs, - UseDefaultSandbox: true, - } - - if len(sb.parseOptions()) != 9 { - t.Fatal("Failed to generate all libnetwork.SandboxOption methods") - } -} - -func TestJson(t *testing.T) { - nc := networkCreate{NetworkType: bridgeNetType} - b, err := json.Marshal(nc) - if err != nil { - t.Fatal(err) - } - - var ncp networkCreate - err = json.Unmarshal(b, &ncp) - if err != nil { - t.Fatal(err) - } - - if nc.NetworkType != ncp.NetworkType { - t.Fatalf("Incorrect networkCreate after json encoding/deconding: %v", ncp) - } - - jl := endpointJoin{SandboxID: "abcdef456789"} - b, err = json.Marshal(jl) - if err != nil { - t.Fatal(err) - } - - var jld endpointJoin - err = json.Unmarshal(b, &jld) - if err != nil { - t.Fatal(err) - } - - if jl.SandboxID != jld.SandboxID { - t.Fatalf("Incorrect endpointJoin after json encoding/deconding: %v", jld) - } -} - -func TestCreateDeleteNetwork(t *testing.T) { - defer testutils.SetupTestOSContext(t)() - - // Cleanup local datastore file - os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address) - - c, err := libnetwork.New() - if err != nil { - t.Fatal(err) - } - defer c.Stop() - - badBody, err := json.Marshal("bad body") - if err != nil { - t.Fatal(err) - } - - vars := make(map[string]string) - _, errRsp := procCreateNetwork(c, nil, badBody) - if errRsp == &createdResponse { - t.Fatal("Expected to fail but succeeded") - } - if errRsp.StatusCode != http.StatusBadRequest { - t.Fatalf("Expected StatusBadRequest status code, got: %v", errRsp) - } - - incompleteBody, err := json.Marshal(networkCreate{}) - if err != nil { - t.Fatal(err) - } - - _, errRsp = procCreateNetwork(c, vars, incompleteBody) - if errRsp == &createdResponse { - t.Fatal("Expected to fail but succeeded") - } - if errRsp.StatusCode != http.StatusBadRequest { - t.Fatalf("Expected StatusBadRequest status code, got: %v", errRsp) - } - - dops := GetOpsMap("abc", "") - nops := map[string]string{} - nc := networkCreate{Name: "network_1", NetworkType: bridgeNetType, DriverOpts: dops, NetworkOpts: nops} - goodBody, err := json.Marshal(nc) - if err != nil { - t.Fatal(err) - } - - _, errRsp = procCreateNetwork(c, vars, goodBody) - if errRsp != &createdResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - - vars[urlNwName] = "" - _, errRsp = procDeleteNetwork(c, vars, nil) - if errRsp == &successResponse { - t.Fatal("Expected to fail but succeeded") - } - - vars[urlNwName] = "abc" - _, errRsp = procDeleteNetwork(c, vars, nil) - if errRsp == &successResponse { - t.Fatal("Expected to fail but succeeded") - } - - vars[urlNwName] = "network_1" - _, errRsp = procDeleteNetwork(c, vars, nil) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } -} - -func TestGetNetworksAndEndpoints(t *testing.T) { - defer testutils.SetupTestOSContext(t)() - - // Cleanup local datastore file - os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address) - - c, err := libnetwork.New() - if err != nil { - t.Fatal(err) - } - defer c.Stop() - - ops := GetOpsMap("api_test_nw", "") - nc := networkCreate{Name: "sh", NetworkType: bridgeNetType, DriverOpts: ops} - body, err := json.Marshal(nc) - if err != nil { - t.Fatal(err) - } - - vars := make(map[string]string) - inid, errRsp := procCreateNetwork(c, vars, body) - if errRsp != &createdResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - nid, ok := inid.(string) - if !ok { - t.FailNow() - } - - ec1 := endpointCreate{ - Name: "ep1", - } - b1, err := json.Marshal(ec1) - if err != nil { - t.Fatal(err) - } - ec2 := endpointCreate{Name: "ep2"} - b2, err := json.Marshal(ec2) - if err != nil { - t.Fatal(err) - } - - vars[urlNwName] = "sh" - vars[urlEpName] = "ep1" - ieid1, errRsp := procCreateEndpoint(c, vars, b1) - if errRsp != &createdResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - eid1 := i2s(ieid1) - vars[urlEpName] = "ep2" - ieid2, errRsp := procCreateEndpoint(c, vars, b2) - if errRsp != &createdResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - eid2 := i2s(ieid2) - - vars[urlNwName] = "" - vars[urlEpName] = "ep1" - _, errRsp = procGetEndpoint(c, vars, nil) - if errRsp == &successResponse { - t.Fatalf("Expected failure but succeeded: %v", errRsp) - } - if errRsp.StatusCode != http.StatusBadRequest { - t.Fatalf("Expected to fail with http.StatusBadRequest, but got: %d", errRsp.StatusCode) - } - - vars = make(map[string]string) - vars[urlNwName] = "sh" - vars[urlEpID] = "" - _, errRsp = procGetEndpoint(c, vars, nil) - if errRsp == &successResponse { - t.Fatalf("Expected failure but succeeded: %v", errRsp) - } - if errRsp.StatusCode != http.StatusBadRequest { - t.Fatalf("Expected to fail with http.StatusBadRequest, but got: %d", errRsp.StatusCode) - } - - vars = make(map[string]string) - vars[urlNwID] = "" - vars[urlEpID] = eid1 - _, errRsp = procGetEndpoint(c, vars, nil) - if errRsp == &successResponse { - t.Fatalf("Expected failure but succeeded: %v", errRsp) - } - if errRsp.StatusCode != http.StatusBadRequest { - t.Fatalf("Expected to fail with http.StatusBadRequest, but got: %d", errRsp.StatusCode) - } - - // nw by name and ep by id - vars[urlNwName] = "sh" - i1, errRsp := procGetEndpoint(c, vars, nil) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - // nw by name and ep by name - delete(vars, urlEpID) - vars[urlEpName] = "ep1" - i2, errRsp := procGetEndpoint(c, vars, nil) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - // nw by id and ep by name - delete(vars, urlNwName) - vars[urlNwID] = nid - i3, errRsp := procGetEndpoint(c, vars, nil) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - // nw by id and ep by id - delete(vars, urlEpName) - vars[urlEpID] = eid1 - i4, errRsp := procGetEndpoint(c, vars, nil) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - - id1 := i2e(i1).ID - if id1 != i2e(i2).ID || id1 != i2e(i3).ID || id1 != i2e(i4).ID { - t.Fatalf("Endpoints retrieved via different query parameters differ: %v, %v, %v, %v", i1, i2, i3, i4) - } - - vars[urlNwName] = "" - _, errRsp = procGetEndpoints(c, vars, nil) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } - - delete(vars, urlNwName) - vars[urlNwID] = "fakeID" - _, errRsp = procGetEndpoints(c, vars, nil) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } - - vars[urlNwID] = nid - _, errRsp = procGetEndpoints(c, vars, nil) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - - vars[urlNwName] = "sh" - iepList, errRsp := procGetEndpoints(c, vars, nil) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - epList := i2eL(iepList) - if len(epList) != 2 { - t.Fatalf("Did not return the expected number (2) of endpoint resources: %d", len(epList)) - } - if "sh" != epList[0].Network || "sh" != epList[1].Network { - t.Fatal("Did not find expected network name in endpoint resources") - } - - vars = make(map[string]string) - vars[urlNwName] = "" - _, errRsp = procGetNetwork(c, vars, nil) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } - vars[urlNwName] = "shhhhh" - _, errRsp = procGetNetwork(c, vars, nil) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } - vars[urlNwName] = "sh" - inr1, errRsp := procGetNetwork(c, vars, nil) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - nr1 := i2n(inr1) - - delete(vars, urlNwName) - vars[urlNwID] = "acacac" - _, errRsp = procGetNetwork(c, vars, nil) - if errRsp == &successResponse { - t.Fatalf("Expected failure. Got: %v", errRsp) - } - vars[urlNwID] = nid - inr2, errRsp := procGetNetwork(c, vars, nil) - if errRsp != &successResponse { - t.Fatalf("procgetNetworkByName() != procgetNetworkById(), %v vs %v", inr1, inr2) - } - nr2 := i2n(inr2) - if nr1.Name != nr2.Name || nr1.Type != nr2.Type || nr1.ID != nr2.ID || len(nr1.Endpoints) != len(nr2.Endpoints) { - t.Fatalf("Get by name and Get failure: %v", errRsp) - } - - if len(nr1.Endpoints) != 2 { - t.Fatalf("Did not find the expected number (2) of endpoint resources in the network resource: %d", len(nr1.Endpoints)) - } - for _, er := range nr1.Endpoints { - if er.ID != eid1 && er.ID != eid2 { - t.Fatalf("Did not find the expected endpoint resources in the network resource: %v", nr1.Endpoints) - } - } - - iList, errRsp := procGetNetworks(c, nil, nil) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - netList := i2nL(iList) - if len(netList) != 1 { - t.Fatal("Did not return the expected number of network resources") - } - if nid != netList[0].ID { - t.Fatalf("Did not find expected network %s: %v", nid, netList) - } - - _, errRsp = procDeleteNetwork(c, vars, nil) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } - - vars[urlEpName] = "ep1" - _, errRsp = procDeleteEndpoint(c, vars, nil) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - delete(vars, urlEpName) - iepList, errRsp = procGetEndpoints(c, vars, nil) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - epList = i2eL(iepList) - if len(epList) != 1 { - t.Fatalf("Did not return the expected number (1) of endpoint resources: %d", len(epList)) - } - - vars[urlEpName] = "ep2" - _, errRsp = procDeleteEndpoint(c, vars, nil) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - iepList, errRsp = procGetEndpoints(c, vars, nil) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - epList = i2eL(iepList) - if len(epList) != 0 { - t.Fatalf("Did not return the expected number (0) of endpoint resources: %d", len(epList)) - } - - _, errRsp = procDeleteNetwork(c, vars, nil) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - - iList, errRsp = procGetNetworks(c, nil, nil) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - netList = i2nL(iList) - if len(netList) != 0 { - t.Fatal("Did not return the expected number of network resources") - } -} - -func TestProcGetServices(t *testing.T) { - defer testutils.SetupTestOSContext(t)() - - // Cleanup local datastore file - os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address) - - c, err := libnetwork.New() - if err != nil { - t.Fatal(err) - } - defer c.Stop() - - // Create 2 networks - netName1 := "production" - netOption := options.Generic{ - netlabel.GenericData: options.Generic{ - "BridgeName": netName1, - }, - } - nw1, err := c.NewNetwork(bridgeNetType, netName1, "", libnetwork.NetworkOptionGeneric(netOption)) - if err != nil { - t.Fatal(err) - } - - netName2 := "workdev" - netOption = options.Generic{ - netlabel.GenericData: options.Generic{ - "BridgeName": netName2, - }, - } - nw2, err := c.NewNetwork(bridgeNetType, netName2, "", libnetwork.NetworkOptionGeneric(netOption)) - if err != nil { - t.Fatal(err) - } - - vars := make(map[string]string) - li, errRsp := procGetServices(c, vars, nil) - if !errRsp.isOK() { - t.Fatalf("Unexpected failure: %v", errRsp) - } - list := i2eL(li) - if len(list) != 0 { - t.Fatalf("Unexpected services in response: %v", list) - } - - // Add a couple of services on one network and one on the other network - ep11, err := nw1.CreateEndpoint("db-prod") - if err != nil { - t.Fatal(err) - } - ep12, err := nw1.CreateEndpoint("web-prod") - if err != nil { - t.Fatal(err) - } - ep21, err := nw2.CreateEndpoint("db-dev") - if err != nil { - t.Fatal(err) - } - - li, errRsp = procGetServices(c, vars, nil) - if !errRsp.isOK() { - t.Fatalf("Unexpected failure: %v", errRsp) - } - list = i2eL(li) - if len(list) != 3 { - t.Fatalf("Unexpected services in response: %v", list) - } - - // Filter by network - vars[urlNwName] = netName1 - li, errRsp = procGetServices(c, vars, nil) - if !errRsp.isOK() { - t.Fatalf("Unexpected failure: %v", errRsp) - } - list = i2eL(li) - if len(list) != 2 { - t.Fatalf("Unexpected services in response: %v", list) - } - - vars[urlNwName] = netName2 - li, errRsp = procGetServices(c, vars, nil) - if !errRsp.isOK() { - t.Fatalf("Unexpected failure: %v", errRsp) - } - list = i2eL(li) - if len(list) != 1 { - t.Fatalf("Unexpected services in response: %v", list) - } - - vars[urlNwName] = "unknown-network" - li, errRsp = procGetServices(c, vars, nil) - if !errRsp.isOK() { - t.Fatalf("Unexpected failure: %v", errRsp) - } - list = i2eL(li) - if len(list) != 0 { - t.Fatalf("Unexpected services in response: %v", list) - } - - // Query by name - delete(vars, urlNwName) - vars[urlEpName] = "db-prod" - li, errRsp = procGetServices(c, vars, nil) - if !errRsp.isOK() { - t.Fatalf("Unexpected failure: %v", errRsp) - } - list = i2eL(li) - if len(list) != 1 { - t.Fatalf("Unexpected services in response: %v", list) - } - - vars[urlEpName] = "no-service" - li, errRsp = procGetServices(c, vars, nil) - if !errRsp.isOK() { - t.Fatalf("Unexpected failure: %v", errRsp) - } - list = i2eL(li) - if len(list) != 0 { - t.Fatalf("Unexpected services in response: %v", list) - } - - // Query by id or partial id - delete(vars, urlEpName) - vars[urlEpPID] = ep12.ID() - li, errRsp = procGetServices(c, vars, nil) - if !errRsp.isOK() { - t.Fatalf("Unexpected failure: %v", errRsp) - } - list = i2eL(li) - if len(list) != 1 { - t.Fatalf("Unexpected services in response: %v", list) - } - if list[0].ID != ep12.ID() { - t.Fatalf("Unexpected element in response: %v", list) - } - - vars[urlEpPID] = "non-id" - li, errRsp = procGetServices(c, vars, nil) - if !errRsp.isOK() { - t.Fatalf("Unexpected failure: %v", errRsp) - } - list = i2eL(li) - if len(list) != 0 { - t.Fatalf("Unexpected services in response: %v", list) - } - - delete(vars, urlEpPID) - err = ep11.Delete(false) - if err != nil { - t.Fatal(err) - } - err = ep12.Delete(false) - if err != nil { - t.Fatal(err) - } - err = ep21.Delete(false) - if err != nil { - t.Fatal(err) - } - - li, errRsp = procGetServices(c, vars, nil) - if !errRsp.isOK() { - t.Fatalf("Unexpected failure: %v", errRsp) - } - list = i2eL(li) - if len(list) != 0 { - t.Fatalf("Unexpected services in response: %v", list) - } -} - -func TestProcGetService(t *testing.T) { - defer testutils.SetupTestOSContext(t)() - - c, nw := createTestNetwork(t, "network") - defer c.Stop() - ep1, err := nw.CreateEndpoint("db") - if err != nil { - t.Fatal(err) - } - ep2, err := nw.CreateEndpoint("web") - if err != nil { - t.Fatal(err) - } - - vars := map[string]string{urlEpID: ""} - _, errRsp := procGetService(c, vars, nil) - if errRsp.isOK() { - t.Fatal("Expected failure, but succeeded") - } - if errRsp.StatusCode != http.StatusBadRequest { - t.Fatalf("Expected %d, but got: %d", http.StatusBadRequest, errRsp.StatusCode) - } - - vars[urlEpID] = "unknown-service-id" - _, errRsp = procGetService(c, vars, nil) - if errRsp.isOK() { - t.Fatal("Expected failure, but succeeded") - } - if errRsp.StatusCode != http.StatusNotFound { - t.Fatalf("Expected %d, but got: %d. (%v)", http.StatusNotFound, errRsp.StatusCode, errRsp) - } - - vars[urlEpID] = ep1.ID() - si, errRsp := procGetService(c, vars, nil) - if !errRsp.isOK() { - t.Fatalf("Unexpected failure: %v", errRsp) - } - sv := i2e(si) - if sv.ID != ep1.ID() { - t.Fatalf("Unexpected service resource returned: %v", sv) - } - - vars[urlEpID] = ep2.ID() - si, errRsp = procGetService(c, vars, nil) - if !errRsp.isOK() { - t.Fatalf("Unexpected failure: %v", errRsp) - } - sv = i2e(si) - if sv.ID != ep2.ID() { - t.Fatalf("Unexpected service resource returned: %v", sv) - } -} - -func TestProcPublishUnpublishService(t *testing.T) { - defer testutils.SetupTestOSContext(t)() - - c, _ := createTestNetwork(t, "network") - defer c.Stop() - - vars := make(map[string]string) - - vbad, err := json.Marshal("bad service create data") - if err != nil { - t.Fatal(err) - } - _, errRsp := procPublishService(c, vars, vbad) - if errRsp == &createdResponse { - t.Fatal("Expected to fail but succeeded") - } - if errRsp.StatusCode != http.StatusBadRequest { - t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp) - } - - b, err := json.Marshal(servicePublish{Name: ""}) - if err != nil { - t.Fatal(err) - } - _, errRsp = procPublishService(c, vars, b) - if errRsp == &createdResponse { - t.Fatal("Expected to fail but succeeded") - } - if errRsp.StatusCode != http.StatusBadRequest { - t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp) - } - - b, err = json.Marshal(servicePublish{Name: "db"}) - if err != nil { - t.Fatal(err) - } - _, errRsp = procPublishService(c, vars, b) - if errRsp == &createdResponse { - t.Fatal("Expected to fail but succeeded") - } - if errRsp.StatusCode != http.StatusBadRequest { - t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp) - } - - b, err = json.Marshal(servicePublish{Name: "db", Network: "unknown-network"}) - if err != nil { - t.Fatal(err) - } - _, errRsp = procPublishService(c, vars, b) - if errRsp == &createdResponse { - t.Fatal("Expected to fail but succeeded") - } - if errRsp.StatusCode != http.StatusNotFound { - t.Fatalf("Expected %d. Got: %v", http.StatusNotFound, errRsp) - } - - b, err = json.Marshal(servicePublish{Name: "", Network: "network"}) - if err != nil { - t.Fatal(err) - } - _, errRsp = procPublishService(c, vars, b) - if errRsp == &createdResponse { - t.Fatal("Expected to fail but succeeded") - } - if errRsp.StatusCode != http.StatusBadRequest { - t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp) - } - - b, err = json.Marshal(servicePublish{Name: "db", Network: "network"}) - if err != nil { - t.Fatal(err) - } - _, errRsp = procPublishService(c, vars, b) - if errRsp != &createdResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - - sp := servicePublish{ - Name: "web", - Network: "network", - } - b, err = json.Marshal(sp) - if err != nil { - t.Fatal(err) - } - si, errRsp := procPublishService(c, vars, b) - if errRsp != &createdResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - sid := i2s(si) - - vars[urlEpID] = "" - _, errRsp = procUnpublishService(c, vars, nil) - if errRsp.isOK() { - t.Fatal("Expected failure but succeeded") - } - if errRsp.StatusCode != http.StatusBadRequest { - t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp) - } - - vars[urlEpID] = "unknown-service-id" - _, errRsp = procUnpublishService(c, vars, nil) - if errRsp.isOK() { - t.Fatal("Expected failure but succeeded") - } - if errRsp.StatusCode != http.StatusNotFound { - t.Fatalf("Expected %d. Got: %v", http.StatusNotFound, errRsp) - } - - vars[urlEpID] = sid - _, errRsp = procUnpublishService(c, vars, nil) - if !errRsp.isOK() { - t.Fatalf("Unexpected failure: %v", errRsp) - } - - _, errRsp = procGetService(c, vars, nil) - if errRsp.isOK() { - t.Fatal("Expected failure, but succeeded") - } - if errRsp.StatusCode != http.StatusNotFound { - t.Fatalf("Expected %d, but got: %d. (%v)", http.StatusNotFound, errRsp.StatusCode, errRsp) - } -} - -func TestAttachDetachBackend(t *testing.T) { - defer testutils.SetupTestOSContext(t)() - - c, nw := createTestNetwork(t, "network") - defer c.Stop() - ep1, err := nw.CreateEndpoint("db") - if err != nil { - t.Fatal(err) - } - - vars := make(map[string]string) - - vbad, err := json.Marshal("bad data") - if err != nil { - t.Fatal(err) - } - _, errRsp := procAttachBackend(c, vars, vbad) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } - - vars[urlEpName] = "endpoint" - bad, err := json.Marshal(endpointJoin{}) - if err != nil { - t.Fatal(err) - } - _, errRsp = procAttachBackend(c, vars, bad) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } - if errRsp.StatusCode != http.StatusNotFound { - t.Fatalf("Expected %d. Got: %v", http.StatusNotFound, errRsp) - } - - vars[urlEpID] = "db" - _, errRsp = procGetSandbox(c, vars, nil) - if errRsp.isOK() { - t.Fatalf("Expected failure. Got %v", errRsp) - } - if errRsp.StatusCode != http.StatusNotFound { - t.Fatalf("Expected %d. Got: %v", http.StatusNotFound, errRsp) - } - - vars[urlEpName] = "db" - _, errRsp = procAttachBackend(c, vars, bad) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } - if errRsp.StatusCode != http.StatusBadRequest { - t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp) - } - - cid := "abcdefghi" - sbox, err := c.NewSandbox(cid) - if err != nil { - t.Fatal(err) - } - sid := sbox.ID() - defer sbox.Delete() - - jl := endpointJoin{SandboxID: sid} - jlb, err := json.Marshal(jl) - if err != nil { - t.Fatal(err) - } - - _, errRsp = procAttachBackend(c, vars, jlb) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure, got: %v", errRsp) - } - - sli, errRsp := procGetSandboxes(c, vars, nil) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure, got: %v", errRsp) - } - sl := i2sbL(sli) - if len(sl) != 1 { - t.Fatalf("Did not find expected number of sandboxes attached to the service: %d", len(sl)) - } - if sl[0].ContainerID != cid { - t.Fatalf("Did not find expected sandbox attached to the service: %v", sl[0]) - } - - _, errRsp = procUnpublishService(c, vars, nil) - if errRsp.isOK() { - t.Fatal("Expected failure but succeeded") - } - if errRsp.StatusCode != http.StatusForbidden { - t.Fatalf("Expected %d. Got: %v", http.StatusForbidden, errRsp) - } - - vars[urlEpName] = "endpoint" - _, errRsp = procDetachBackend(c, vars, nil) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } - if errRsp.StatusCode != http.StatusNotFound { - t.Fatalf("Expected %d. Got: %v", http.StatusNotFound, errRsp) - } - - vars[urlEpName] = "db" - _, errRsp = procDetachBackend(c, vars, nil) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } - if errRsp.StatusCode != http.StatusBadRequest { - t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp) - } - - vars[urlSbID] = sid - _, errRsp = procDetachBackend(c, vars, nil) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure, got: %v", errRsp) - } - - delete(vars, urlEpID) - si, errRsp := procGetSandbox(c, vars, nil) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure, got: %v", errRsp) - } - sb := i2sb(si) - if sb.ContainerID != cid { - t.Fatalf("Did not find expected sandbox. Got %v", sb) - } - - err = ep1.Delete(false) - if err != nil { - t.Fatal(err) - } -} - -func TestDetectGetNetworksInvalidQueryComposition(t *testing.T) { - // Cleanup local datastore file - os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address) - - c, err := libnetwork.New() - if err != nil { - t.Fatal(err) - } - defer c.Stop() - - vars := map[string]string{urlNwName: "x", urlNwPID: "y"} - _, errRsp := procGetNetworks(c, vars, nil) - if errRsp.StatusCode != http.StatusBadRequest { - t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp) - } -} - -func TestDetectGetEndpointsInvalidQueryComposition(t *testing.T) { - defer testutils.SetupTestOSContext(t)() - - c, _ := createTestNetwork(t, "network") - defer c.Stop() - - vars := map[string]string{urlNwName: "network", urlEpName: "x", urlEpPID: "y"} - _, errRsp := procGetEndpoints(c, vars, nil) - if errRsp.StatusCode != http.StatusBadRequest { - t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp) - } -} - -func TestDetectGetServicesInvalidQueryComposition(t *testing.T) { - defer testutils.SetupTestOSContext(t)() - - c, _ := createTestNetwork(t, "network") - defer c.Stop() - - vars := map[string]string{urlNwName: "network", urlEpName: "x", urlEpPID: "y"} - _, errRsp := procGetServices(c, vars, nil) - if errRsp.StatusCode != http.StatusBadRequest { - t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp) - } -} - -func TestFindNetworkUtilPanic(t *testing.T) { - defer checkPanic(t) - findNetwork(nil, "", -1) -} - -func TestFindNetworkUtil(t *testing.T) { - defer testutils.SetupTestOSContext(t)() - - c, nw := createTestNetwork(t, "network") - defer c.Stop() - - nid := nw.ID() - - _, errRsp := findNetwork(c, "", byName) - if errRsp == &successResponse { - t.Fatal("Expected to fail but succeeded") - } - if errRsp.StatusCode != http.StatusBadRequest { - t.Fatalf("Expected %d, but got: %d", http.StatusBadRequest, errRsp.StatusCode) - } - - n, errRsp := findNetwork(c, nid, byID) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - if n == nil { - t.Fatal("Unexpected nil libnetwork.Network") - } - if nid != n.ID() { - t.Fatalf("Incorrect libnetwork.Network resource. It has different id: %v", n) - } - if "network" != n.Name() { - t.Fatalf("Incorrect libnetwork.Network resource. It has different name: %v", n) - } - - n, errRsp = findNetwork(c, "network", byName) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - if n == nil { - t.Fatal("Unexpected nil libnetwork.Network") - } - if nid != n.ID() { - t.Fatalf("Incorrect libnetwork.Network resource. It has different id: %v", n) - } - if "network" != n.Name() { - t.Fatalf("Incorrect libnetwork.Network resource. It has different name: %v", n) - } - - if err := n.Delete(); err != nil { - t.Fatalf("Failed to delete the network: %s", err.Error()) - } - - _, errRsp = findNetwork(c, nid, byID) - if errRsp == &successResponse { - t.Fatal("Expected to fail but succeeded") - } - if errRsp.StatusCode != http.StatusNotFound { - t.Fatalf("Expected %d, but got: %d", http.StatusNotFound, errRsp.StatusCode) - } - - _, errRsp = findNetwork(c, "network", byName) - if errRsp == &successResponse { - t.Fatal("Expected to fail but succeeded") - } - if errRsp.StatusCode != http.StatusNotFound { - t.Fatalf("Expected %d, but got: %d", http.StatusNotFound, errRsp.StatusCode) - } -} - -func TestCreateDeleteEndpoints(t *testing.T) { - defer testutils.SetupTestOSContext(t)() - - // Cleanup local datastore file - os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address) - - c, err := libnetwork.New() - if err != nil { - t.Fatal(err) - } - defer c.Stop() - - nc := networkCreate{Name: "firstNet", NetworkType: bridgeNetType} - body, err := json.Marshal(nc) - if err != nil { - t.Fatal(err) - } - - vars := make(map[string]string) - i, errRsp := procCreateNetwork(c, vars, body) - if errRsp != &createdResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - nid := i2s(i) - - vbad, err := json.Marshal("bad endpoint create data") - if err != nil { - t.Fatal(err) - } - - vars[urlNwName] = "firstNet" - _, errRsp = procCreateEndpoint(c, vars, vbad) - if errRsp == &createdResponse { - t.Fatal("Expected to fail but succeeded") - } - - b, err := json.Marshal(endpointCreate{Name: ""}) - if err != nil { - t.Fatal(err) - } - - vars[urlNwName] = "secondNet" - _, errRsp = procCreateEndpoint(c, vars, b) - if errRsp == &createdResponse { - t.Fatal("Expected to fail but succeeded") - } - - vars[urlNwName] = "firstNet" - _, errRsp = procCreateEndpoint(c, vars, b) - if errRsp == &successResponse { - t.Fatalf("Expected failure but succeeded: %v", errRsp) - } - - b, err = json.Marshal(endpointCreate{Name: "firstEp"}) - if err != nil { - t.Fatal(err) - } - - i, errRsp = procCreateEndpoint(c, vars, b) - if errRsp != &createdResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - eid := i2s(i) - - _, errRsp = findEndpoint(c, "myNet", "firstEp", byName, byName) - if errRsp == &successResponse { - t.Fatalf("Expected failure but succeeded: %v", errRsp) - } - - ep0, errRsp := findEndpoint(c, nid, "firstEp", byID, byName) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - - ep1, errRsp := findEndpoint(c, "firstNet", "firstEp", byName, byName) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - - ep2, errRsp := findEndpoint(c, nid, eid, byID, byID) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - - ep3, errRsp := findEndpoint(c, "firstNet", eid, byName, byID) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - - if ep0.ID() != ep1.ID() || ep0.ID() != ep2.ID() || ep0.ID() != ep3.ID() { - t.Fatalf("Different queries returned different endpoints: \nep0: %v\nep1: %v\nep2: %v\nep3: %v", ep0, ep1, ep2, ep3) - } - - vars = make(map[string]string) - vars[urlNwName] = "" - vars[urlEpName] = "ep1" - _, errRsp = procDeleteEndpoint(c, vars, nil) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } - - vars[urlNwName] = "firstNet" - vars[urlEpName] = "" - _, errRsp = procDeleteEndpoint(c, vars, nil) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } - - vars[urlEpName] = "ep2" - _, errRsp = procDeleteEndpoint(c, vars, nil) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } - - vars[urlEpName] = "firstEp" - _, errRsp = procDeleteEndpoint(c, vars, nil) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - - _, errRsp = findEndpoint(c, "firstNet", "firstEp", byName, byName) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } -} - -func TestJoinLeave(t *testing.T) { - if runtime.GOARCH == "arm64" { - t.Skip("This test fails on arm64 foor some reason... this need to be fixed") - } - defer testutils.SetupTestOSContext(t)() - - // Cleanup local datastore file - os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address) - - c, err := libnetwork.New() - if err != nil { - t.Fatal(err) - } - defer c.Stop() - - nb, err := json.Marshal(networkCreate{Name: "network", NetworkType: bridgeNetType}) - if err != nil { - t.Fatal(err) - } - vars := make(map[string]string) - _, errRsp := procCreateNetwork(c, vars, nb) - if errRsp != &createdResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - - eb, err := json.Marshal(endpointCreate{Name: "endpoint"}) - if err != nil { - t.Fatal(err) - } - vars[urlNwName] = "network" - _, errRsp = procCreateEndpoint(c, vars, eb) - if errRsp != &createdResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - - vbad, err := json.Marshal("bad data") - if err != nil { - t.Fatal(err) - } - _, errRsp = procJoinEndpoint(c, vars, vbad) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } - - vars[urlEpName] = "endpoint" - bad, err := json.Marshal(endpointJoin{}) - if err != nil { - t.Fatal(err) - } - _, errRsp = procJoinEndpoint(c, vars, bad) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } - - cid := "abcdefghi" - sb, err := c.NewSandbox(cid) - if err != nil { - t.Fatal(err) - } - defer sb.Delete() - - jl := endpointJoin{SandboxID: sb.ID()} - jlb, err := json.Marshal(jl) - if err != nil { - t.Fatal(err) - } - - vars = make(map[string]string) - vars[urlNwName] = "" - vars[urlEpName] = "" - _, errRsp = procJoinEndpoint(c, vars, jlb) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } - - vars[urlNwName] = "network" - vars[urlEpName] = "" - _, errRsp = procJoinEndpoint(c, vars, jlb) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } - - vars[urlEpName] = "epoint" - _, errRsp = procJoinEndpoint(c, vars, jlb) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } - - // bad labels - vars[urlEpName] = "endpoint" - key, errRsp := procJoinEndpoint(c, vars, jlb) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure, got: %v", errRsp) - } - - keyStr := i2s(key) - if keyStr == "" { - t.Fatal("Empty sandbox key") - } - _, errRsp = procDeleteEndpoint(c, vars, nil) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } - - vars[urlNwName] = "network2" - _, errRsp = procLeaveEndpoint(c, vars, vbad) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } - _, errRsp = procLeaveEndpoint(c, vars, bad) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } - _, errRsp = procLeaveEndpoint(c, vars, jlb) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } - vars = make(map[string]string) - vars[urlNwName] = "" - vars[urlEpName] = "" - _, errRsp = procLeaveEndpoint(c, vars, jlb) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } - vars[urlNwName] = "network" - vars[urlEpName] = "" - _, errRsp = procLeaveEndpoint(c, vars, jlb) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } - vars[urlEpName] = "2epoint" - _, errRsp = procLeaveEndpoint(c, vars, jlb) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } - vars[urlEpName] = "epoint" - vars[urlCnID] = "who" - _, errRsp = procLeaveEndpoint(c, vars, jlb) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } - - delete(vars, urlCnID) - vars[urlEpName] = "endpoint" - _, errRsp = procLeaveEndpoint(c, vars, jlb) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } - - vars[urlSbID] = sb.ID() - _, errRsp = procLeaveEndpoint(c, vars, jlb) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - - _, errRsp = procLeaveEndpoint(c, vars, jlb) - if errRsp == &successResponse { - t.Fatalf("Expected failure, got: %v", errRsp) - } - - _, errRsp = procDeleteEndpoint(c, vars, nil) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } -} - -func TestFindEndpointUtilPanic(t *testing.T) { - defer testutils.SetupTestOSContext(t)() - defer checkPanic(t) - c, nw := createTestNetwork(t, "network") - defer c.Stop() - - nid := nw.ID() - findEndpoint(c, nid, "", byID, -1) -} - -func TestFindServiceUtilPanic(t *testing.T) { - defer testutils.SetupTestOSContext(t)() - defer checkPanic(t) - c, _ := createTestNetwork(t, "network") - defer c.Stop() - - findService(c, "random_service", -1) -} - -func TestFindEndpointUtil(t *testing.T) { - defer testutils.SetupTestOSContext(t)() - - c, nw := createTestNetwork(t, "network") - defer c.Stop() - - nid := nw.ID() - - ep, err := nw.CreateEndpoint("secondEp", nil) - if err != nil { - t.Fatal(err) - } - eid := ep.ID() - - _, errRsp := findEndpoint(c, nid, "", byID, byName) - if errRsp == &successResponse { - t.Fatalf("Expected failure, but got: %v", errRsp) - } - if errRsp.StatusCode != http.StatusBadRequest { - t.Fatalf("Expected %d, but got: %d", http.StatusBadRequest, errRsp.StatusCode) - } - - ep0, errRsp := findEndpoint(c, nid, "secondEp", byID, byName) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - - ep1, errRsp := findEndpoint(c, "network", "secondEp", byName, byName) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - - ep2, errRsp := findEndpoint(c, nid, eid, byID, byID) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - - ep3, errRsp := findEndpoint(c, "network", eid, byName, byID) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - - ep4, errRsp := findService(c, "secondEp", byName) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - - ep5, errRsp := findService(c, eid, byID) - if errRsp != &successResponse { - t.Fatalf("Unexpected failure: %v", errRsp) - } - - if ep0.ID() != ep1.ID() || ep0.ID() != ep2.ID() || - ep0.ID() != ep3.ID() || ep0.ID() != ep4.ID() || ep0.ID() != ep5.ID() { - t.Fatal("Different queries returned different endpoints") - } - - ep.Delete(false) - - _, errRsp = findEndpoint(c, nid, "secondEp", byID, byName) - if errRsp == &successResponse { - t.Fatalf("Expected failure, but got: %v", errRsp) - } - if errRsp.StatusCode != http.StatusNotFound { - t.Fatalf("Expected %d, but got: %d", http.StatusNotFound, errRsp.StatusCode) - } - - _, errRsp = findEndpoint(c, "network", "secondEp", byName, byName) - if errRsp == &successResponse { - t.Fatalf("Expected failure, but got: %v", errRsp) - } - if errRsp.StatusCode != http.StatusNotFound { - t.Fatalf("Expected %d, but got: %d", http.StatusNotFound, errRsp.StatusCode) - } - - _, errRsp = findEndpoint(c, nid, eid, byID, byID) - if errRsp == &successResponse { - t.Fatalf("Expected failure, but got: %v", errRsp) - } - if errRsp.StatusCode != http.StatusNotFound { - t.Fatalf("Expected %d, but got: %d", http.StatusNotFound, errRsp.StatusCode) - } - - _, errRsp = findEndpoint(c, "network", eid, byName, byID) - if errRsp == &successResponse { - t.Fatalf("Expected failure, but got: %v", errRsp) - } - if errRsp.StatusCode != http.StatusNotFound { - t.Fatalf("Expected %d, but got: %d", http.StatusNotFound, errRsp.StatusCode) - } - - _, errRsp = findService(c, "secondEp", byName) - if errRsp == &successResponse { - t.Fatalf("Expected failure, but got: %v", errRsp) - } - if errRsp.StatusCode != http.StatusNotFound { - t.Fatalf("Expected %d, but got: %d", http.StatusNotFound, errRsp.StatusCode) - } - - _, errRsp = findService(c, eid, byID) - if errRsp == &successResponse { - t.Fatalf("Expected failure, but got: %v", errRsp) - } - if errRsp.StatusCode != http.StatusNotFound { - t.Fatalf("Expected %d, but got: %d", http.StatusNotFound, errRsp.StatusCode) - } -} - -func TestEndpointToService(t *testing.T) { - r := &responseStatus{Status: "this is one endpoint", StatusCode: http.StatusOK} - r = endpointToService(r) - if r.Status != "this is one service" { - t.Fatalf("endpointToService returned unexpected status string: %s", r.Status) - } - - r = &responseStatus{Status: "this is one network", StatusCode: http.StatusOK} - r = endpointToService(r) - if r.Status != "this is one network" { - t.Fatalf("endpointToService returned unexpected status string: %s", r.Status) - } -} - -func checkPanic(t *testing.T) { - if r := recover(); r != nil { - if _, ok := r.(runtime.Error); ok { - panic(r) - } - } else { - t.Fatal("Expected to panic, but succeeded") - } -} - -func TestDetectNetworkTargetPanic(t *testing.T) { - defer checkPanic(t) - vars := make(map[string]string) - detectNetworkTarget(vars) -} - -func TestDetectEndpointTargetPanic(t *testing.T) { - defer checkPanic(t) - vars := make(map[string]string) - detectEndpointTarget(vars) -} - -func TestResponseStatus(t *testing.T) { - list := []int{ - http.StatusBadGateway, - http.StatusBadRequest, - http.StatusConflict, - http.StatusContinue, - http.StatusExpectationFailed, - http.StatusForbidden, - http.StatusFound, - http.StatusGatewayTimeout, - http.StatusGone, - http.StatusHTTPVersionNotSupported, - http.StatusInternalServerError, - http.StatusLengthRequired, - http.StatusMethodNotAllowed, - http.StatusMovedPermanently, - http.StatusMultipleChoices, - http.StatusNoContent, - http.StatusNonAuthoritativeInfo, - http.StatusNotAcceptable, - http.StatusNotFound, - http.StatusNotModified, - http.StatusPartialContent, - http.StatusPaymentRequired, - http.StatusPreconditionFailed, - http.StatusProxyAuthRequired, - http.StatusRequestEntityTooLarge, - http.StatusRequestTimeout, - http.StatusRequestURITooLong, - http.StatusRequestedRangeNotSatisfiable, - http.StatusResetContent, - http.StatusServiceUnavailable, - http.StatusSwitchingProtocols, - http.StatusTemporaryRedirect, - http.StatusUnauthorized, - http.StatusUnsupportedMediaType, - http.StatusUseProxy, - } - for _, c := range list { - r := responseStatus{StatusCode: c} - if r.isOK() { - t.Fatalf("isOK() returned true for code% d", c) - } - } - - r := responseStatus{StatusCode: http.StatusOK} - if !r.isOK() { - t.Fatal("isOK() failed") - } - - r = responseStatus{StatusCode: http.StatusCreated} - if !r.isOK() { - t.Fatal("isOK() failed") - } -} - -// Local structs for end to end testing of api.go -type localReader struct { - data []byte - beBad bool -} - -func newLocalReader(data []byte) *localReader { - lr := &localReader{data: make([]byte, len(data))} - copy(lr.data, data) - return lr -} - -func (l *localReader) Read(p []byte) (n int, err error) { - if l.beBad { - return 0, errors.New("I am a bad reader") - } - if p == nil { - return -1, errors.New("nil buffer passed") - } - if l.data == nil || len(l.data) == 0 { - return 0, io.EOF - } - copy(p[:], l.data[:]) - return len(l.data), io.EOF -} - -type localResponseWriter struct { - body []byte - statusCode int -} - -func newWriter() *localResponseWriter { - return &localResponseWriter{} -} - -func (f *localResponseWriter) Header() http.Header { - return make(map[string][]string) -} - -func (f *localResponseWriter) Write(data []byte) (int, error) { - if data == nil { - return -1, errors.New("nil data passed") - } - - f.body = make([]byte, len(data)) - copy(f.body, data) - - return len(f.body), nil -} - -func (f *localResponseWriter) WriteHeader(c int) { - f.statusCode = c -} - -func testWriteJSON(t *testing.T, testCode int, testData interface{}) { - testDataMarshalled, err := json.Marshal(testData) - if err != nil { - t.Fatal(err) - } - - rsp := newWriter() - writeJSON(rsp, testCode, testData) - if rsp.statusCode != testCode { - t.Fatalf("writeJSON() failed to set the status code. Expected %d. Got %d", testCode, rsp.statusCode) - } - // writeJSON calls json.Encode and it appends '\n' to the result, - // while json.Marshal not - expected := append(testDataMarshalled, byte('\n')) - if !bytes.Equal(expected, rsp.body) { - t.Fatalf("writeJSON() failed to set the body. Expected %q. Got %q", expected, rsp.body) - } -} - -func TestWriteJSON(t *testing.T) { - testWriteJSON(t, 55, "test data as string") - testWriteJSON(t, 55, []byte("test data as bytes")) -} - -func TestHttpHandlerUninit(t *testing.T) { - defer testutils.SetupTestOSContext(t)() - - // Cleanup local datastore file - os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address) - - c, err := libnetwork.New() - if err != nil { - t.Fatal(err) - } - defer c.Stop() - - h := &httpHandler{c: c} - h.initRouter() - if h.r == nil { - t.Fatal("initRouter() did not initialize the router") - } - - rsp := newWriter() - req, err := http.NewRequest("GET", "/v1.19/networks", nil) - if err != nil { - t.Fatal(err) - } - - handleRequest := NewHTTPHandler(nil) - handleRequest(rsp, req) - if rsp.statusCode != http.StatusServiceUnavailable { - t.Fatalf("Expected (%d). Got (%d): %s", http.StatusServiceUnavailable, rsp.statusCode, rsp.body) - } - - handleRequest = NewHTTPHandler(c) - - handleRequest(rsp, req) - if rsp.statusCode != http.StatusOK { - t.Fatalf("Expected (%d). Got: (%d): %s", http.StatusOK, rsp.statusCode, rsp.body) - } - - var list []*networkResource - err = json.Unmarshal(rsp.body, &list) - if err != nil { - t.Fatal(err) - } - if len(list) != 0 { - t.Fatalf("Expected empty list. Got %v", list) - } - - n, err := c.NewNetwork(bridgeNetType, "didietro", "", nil) - if err != nil { - t.Fatal(err) - } - nwr := buildNetworkResource(n) - expected, err := json.Marshal([]*networkResource{nwr}) - if err != nil { - t.Fatal(err) - } - - handleRequest(rsp, req) - if rsp.statusCode != http.StatusOK { - t.Fatalf("Unexpected failure: (%d): %s", rsp.statusCode, rsp.body) - } - if len(rsp.body) == 0 { - t.Fatal("Empty list of networks") - } - if bytes.Equal(rsp.body, expected) { - t.Fatal("Incorrect list of networks in response's body") - } -} - -func TestHttpHandlerBadBody(t *testing.T) { - defer testutils.SetupTestOSContext(t)() - - rsp := newWriter() - - // Cleanup local datastore file - os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address) - - c, err := libnetwork.New() - if err != nil { - t.Fatal(err) - } - defer c.Stop() - handleRequest := NewHTTPHandler(c) - - req, err := http.NewRequest("POST", "/v1.19/networks", &localReader{beBad: true}) - if err != nil { - t.Fatal(err) - } - handleRequest(rsp, req) - if rsp.statusCode != http.StatusBadRequest { - t.Fatalf("Unexpected status code. Expected (%d). Got (%d): %s.", http.StatusBadRequest, rsp.statusCode, string(rsp.body)) - } - - body := []byte{} - lr := newLocalReader(body) - req, err = http.NewRequest("POST", "/v1.19/networks", lr) - if err != nil { - t.Fatal(err) - } - handleRequest(rsp, req) - if rsp.statusCode != http.StatusBadRequest { - t.Fatalf("Unexpected status code. Expected (%d). Got (%d): %s.", http.StatusBadRequest, rsp.statusCode, string(rsp.body)) - } -} - -func TestEndToEnd(t *testing.T) { - defer testutils.SetupTestOSContext(t)() - - rsp := newWriter() - - // Cleanup local datastore file - os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address) - - c, err := libnetwork.New() - if err != nil { - t.Fatal(err) - } - defer c.Stop() - - handleRequest := NewHTTPHandler(c) - - dops := GetOpsMap("cdef", "1460") - nops := map[string]string{} - - // Create network - nc := networkCreate{Name: "network-fiftyfive", NetworkType: bridgeNetType, DriverOpts: dops, NetworkOpts: nops} - body, err := json.Marshal(nc) - if err != nil { - t.Fatal(err) - } - lr := newLocalReader(body) - req, err := http.NewRequest("POST", "/v1.19/networks", lr) - if err != nil { - t.Fatal(err) - } - handleRequest(rsp, req) - if rsp.statusCode != http.StatusCreated { - t.Fatalf("Unexpected status code. Expected (%d). Got (%d): %s.", http.StatusCreated, rsp.statusCode, string(rsp.body)) - } - if len(rsp.body) == 0 { - t.Fatal("Empty response body") - } - - var nid string - err = json.Unmarshal(rsp.body, &nid) - if err != nil { - t.Fatal(err) - } - - // Query networks collection - req, err = http.NewRequest("GET", "/v1.19/networks?name=", nil) - if err != nil { - t.Fatal(err) - } - handleRequest(rsp, req) - if rsp.statusCode != http.StatusOK { - t.Fatalf("Expected StatusOK. Got (%d): %s", rsp.statusCode, rsp.body) - } - var list []*networkResource - err = json.Unmarshal(rsp.body, &list) - if err != nil { - t.Fatal(err) - } - if len(list) != 0 { - t.Fatalf("Expected empty list. Got %v", list) - } - - req, err = http.NewRequest("GET", "/v1.19/networks", nil) - if err != nil { - t.Fatal(err) - } - handleRequest(rsp, req) - if rsp.statusCode != http.StatusOK { - t.Fatalf("Expected StatusOK. Got (%d): %s", rsp.statusCode, rsp.body) - } - - b0 := make([]byte, len(rsp.body)) - copy(b0, rsp.body) - - req, err = http.NewRequest("GET", "/v1.19/networks?name=network-fiftyfive", nil) - if err != nil { - t.Fatal(err) - } - handleRequest(rsp, req) - if rsp.statusCode != http.StatusOK { - t.Fatalf("Expected StatusOK. Got (%d): %s", rsp.statusCode, rsp.body) - } - - if !bytes.Equal(b0, rsp.body) { - t.Fatal("Expected same body from GET /networks and GET /networks?name= when only network exist.") - } - - // Query network by name - req, err = http.NewRequest("GET", "/v1.19/networks?name=culo", nil) - if err != nil { - t.Fatal(err) - } - handleRequest(rsp, req) - if rsp.statusCode != http.StatusOK { - t.Fatalf("Expected StatusOK. Got (%d): %s", rsp.statusCode, rsp.body) - } - - err = json.Unmarshal(rsp.body, &list) - if err != nil { - t.Fatal(err) - } - if len(list) != 0 { - t.Fatalf("Expected empty list. Got %v", list) - } - - req, err = http.NewRequest("GET", "/v1.19/networks?name=network-fiftyfive", nil) - if err != nil { - t.Fatal(err) - } - handleRequest(rsp, req) - if rsp.statusCode != http.StatusOK { - t.Fatalf("Unexpected failure: (%d): %s", rsp.statusCode, rsp.body) - } - - err = json.Unmarshal(rsp.body, &list) - if err != nil { - t.Fatal(err) - } - if len(list) == 0 { - t.Fatal("Expected non empty list") - } - if list[0].Name != "network-fiftyfive" || nid != list[0].ID { - t.Fatalf("Incongruent resource found: %v", list[0]) - } - - // Query network by partial id - chars := []byte(nid) - partial := string(chars[0 : len(chars)/2]) - req, err = http.NewRequest("GET", "/v1.19/networks?partial-id="+partial, nil) - if err != nil { - t.Fatal(err) - } - handleRequest(rsp, req) - if rsp.statusCode != http.StatusOK { - t.Fatalf("Unexpected failure: (%d): %s", rsp.statusCode, rsp.body) - } - - err = json.Unmarshal(rsp.body, &list) - if err != nil { - t.Fatal(err) - } - if len(list) == 0 { - t.Fatal("Expected non empty list") - } - if list[0].Name != "network-fiftyfive" || nid != list[0].ID { - t.Fatalf("Incongruent resource found: %v", list[0]) - } - - // Get network by id - req, err = http.NewRequest("GET", "/v1.19/networks/"+nid, nil) - if err != nil { - t.Fatal(err) - } - handleRequest(rsp, req) - if rsp.statusCode != http.StatusOK { - t.Fatalf("Unexpected failure: (%d): %s", rsp.statusCode, rsp.body) - } - - var nwr networkResource - err = json.Unmarshal(rsp.body, &nwr) - if err != nil { - t.Fatal(err) - } - if nwr.Name != "network-fiftyfive" || nid != nwr.ID { - t.Fatalf("Incongruent resource found: %v", nwr) - } - - // Create endpoint - eb, err := json.Marshal(endpointCreate{Name: "ep-TwentyTwo"}) - if err != nil { - t.Fatal(err) - } - - lr = newLocalReader(eb) - req, err = http.NewRequest("POST", "/v1.19/networks/"+nid+"/endpoints", lr) - if err != nil { - t.Fatal(err) - } - handleRequest(rsp, req) - if rsp.statusCode != http.StatusCreated { - t.Fatalf("Unexpected status code. Expected (%d). Got (%d): %s.", http.StatusCreated, rsp.statusCode, string(rsp.body)) - } - if len(rsp.body) == 0 { - t.Fatal("Empty response body") - } - - var eid string - err = json.Unmarshal(rsp.body, &eid) - if err != nil { - t.Fatal(err) - } - - // Query endpoint(s) - req, err = http.NewRequest("GET", "/v1.19/networks/"+nid+"/endpoints", nil) - if err != nil { - t.Fatal(err) - } - handleRequest(rsp, req) - if rsp.statusCode != http.StatusOK { - t.Fatalf("Expected StatusOK. Got (%d): %s", rsp.statusCode, rsp.body) - } - - req, err = http.NewRequest("GET", "/v1.19/networks/"+nid+"/endpoints?name=bla", nil) - if err != nil { - t.Fatal(err) - } - handleRequest(rsp, req) - if rsp.statusCode != http.StatusOK { - t.Fatalf("Unexpected failure: (%d): %s", rsp.statusCode, rsp.body) - } - var epList []*endpointResource - err = json.Unmarshal(rsp.body, &epList) - if err != nil { - t.Fatal(err) - } - if len(epList) != 0 { - t.Fatalf("Expected empty list. Got %v", epList) - } - - // Query endpoint by name - req, err = http.NewRequest("GET", "/v1.19/networks/"+nid+"/endpoints?name=ep-TwentyTwo", nil) - if err != nil { - t.Fatal(err) - } - handleRequest(rsp, req) - if rsp.statusCode != http.StatusOK { - t.Fatalf("Unexpected failure: (%d): %s", rsp.statusCode, rsp.body) - } - - err = json.Unmarshal(rsp.body, &epList) - if err != nil { - t.Fatal(err) - } - if len(epList) == 0 { - t.Fatal("Empty response body") - } - if epList[0].Name != "ep-TwentyTwo" || eid != epList[0].ID { - t.Fatalf("Incongruent resource found: %v", epList[0]) - } - - // Query endpoint by partial id - chars = []byte(eid) - partial = string(chars[0 : len(chars)/2]) - req, err = http.NewRequest("GET", "/v1.19/networks/"+nid+"/endpoints?partial-id="+partial, nil) - if err != nil { - t.Fatal(err) - } - handleRequest(rsp, req) - if rsp.statusCode != http.StatusOK { - t.Fatalf("Unexpected failure: (%d): %s", rsp.statusCode, rsp.body) - } - - err = json.Unmarshal(rsp.body, &epList) - if err != nil { - t.Fatal(err) - } - if len(epList) == 0 { - t.Fatal("Empty response body") - } - if epList[0].Name != "ep-TwentyTwo" || eid != epList[0].ID { - t.Fatalf("Incongruent resource found: %v", epList[0]) - } - - // Get endpoint by id - req, err = http.NewRequest("GET", "/v1.19/networks/"+nid+"/endpoints/"+eid, nil) - if err != nil { - t.Fatal(err) - } - handleRequest(rsp, req) - if rsp.statusCode != http.StatusOK { - t.Fatalf("Unexpected failure: (%d): %s", rsp.statusCode, rsp.body) - } - - var epr endpointResource - err = json.Unmarshal(rsp.body, &epr) - if err != nil { - t.Fatal(err) - } - if epr.Name != "ep-TwentyTwo" || epr.ID != eid { - t.Fatalf("Incongruent resource found: %v", epr) - } - - // Store two container ids and one partial ids - cid1 := "container10010000000" - cid2 := "container20010000000" - chars = []byte(cid1) - cpid1 := string(chars[0 : len(chars)/2]) - - // Create sandboxes - sb1, err := json.Marshal(sandboxCreate{ - ContainerID: cid1, - PortMapping: getPortMapping(), - }) - if err != nil { - t.Fatal(err) - } - - lr = newLocalReader(sb1) - req, err = http.NewRequest("POST", "/v5.22/sandboxes", lr) - if err != nil { - t.Fatal(err) - } - handleRequest(rsp, req) - if rsp.statusCode != http.StatusCreated { - t.Fatalf("Unexpected status code. Expected (%d). Got (%d): %s.", http.StatusCreated, rsp.statusCode, string(rsp.body)) - } - if len(rsp.body) == 0 { - t.Fatal("Empty response body") - } - // Get sandbox id and partial id - var sid1 string - err = json.Unmarshal(rsp.body, &sid1) - if err != nil { - t.Fatal(err) - } - - sb2, err := json.Marshal(sandboxCreate{ - ContainerID: cid2, - ExposedPorts: getExposedPorts(), - }) - if err != nil { - t.Fatal(err) - } - - lr = newLocalReader(sb2) - req, err = http.NewRequest("POST", "/v5.22/sandboxes", lr) - if err != nil { - t.Fatal(err) - } - handleRequest(rsp, req) - if rsp.statusCode != http.StatusCreated { - t.Fatalf("Unexpected status code. Expected (%d). Got (%d): %s.", http.StatusCreated, rsp.statusCode, string(rsp.body)) - } - if len(rsp.body) == 0 { - t.Fatal("Empty response body") - } - // Get sandbox id and partial id - var sid2 string - err = json.Unmarshal(rsp.body, &sid2) - if err != nil { - t.Fatal(err) - } - chars = []byte(sid2) - spid2 := string(chars[0 : len(chars)/2]) - - // Query sandboxes - req, err = http.NewRequest("GET", "/sandboxes", nil) - if err != nil { - t.Fatal(err) - } - handleRequest(rsp, req) - if rsp.statusCode != http.StatusOK { - t.Fatalf("Expected StatusOK. Got (%d): %s", rsp.statusCode, rsp.body) - } - - var sbList []*sandboxResource - err = json.Unmarshal(rsp.body, &sbList) - if err != nil { - t.Fatal(err) - } - if len(sbList) != 2 { - t.Fatalf("Expected 2 elements in list. Got %v", sbList) - } - - // Get sandbox by id - req, err = http.NewRequest("GET", "/sandboxes/"+sid1, nil) - if err != nil { - t.Fatal(err) - } - handleRequest(rsp, req) - if rsp.statusCode != http.StatusOK { - t.Fatalf("Unexpected failure: (%d): %s", rsp.statusCode, rsp.body) - } - - var sbr sandboxResource - err = json.Unmarshal(rsp.body, &sbr) - if err != nil { - t.Fatal(err) - } - if sbr.ContainerID != cid1 { - t.Fatalf("Incongruent resource found: %v", sbr) - } - - // Query sandbox by partial sandbox id - req, err = http.NewRequest("GET", "/sandboxes?partial-id="+spid2, nil) - if err != nil { - t.Fatal(err) - } - handleRequest(rsp, req) - if rsp.statusCode != http.StatusOK { - t.Fatalf("Unexpected failure: (%d): %s", rsp.statusCode, rsp.body) - } - - err = json.Unmarshal(rsp.body, &sbList) - if err != nil { - t.Fatal(err) - } - if len(sbList) == 0 { - t.Fatal("Empty response body") - } - if sbList[0].ID != sid2 { - t.Fatalf("Incongruent resource found: %v", sbList[0]) - } - - // Query sandbox by container id - req, err = http.NewRequest("GET", "/sandboxes?container-id="+cid2, nil) - if err != nil { - t.Fatal(err) - } - handleRequest(rsp, req) - if rsp.statusCode != http.StatusOK { - t.Fatalf("Unexpected failure: (%d): %s", rsp.statusCode, rsp.body) - } - - err = json.Unmarshal(rsp.body, &sbList) - if err != nil { - t.Fatal(err) - } - if len(sbList) == 0 { - t.Fatal("Empty response body") - } - if sbList[0].ContainerID != cid2 { - t.Fatalf("Incongruent resource found: %v", sbList[0]) - } - - // Query sandbox by partial container id - req, err = http.NewRequest("GET", "/sandboxes?partial-container-id="+cpid1, nil) - if err != nil { - t.Fatal(err) - } - handleRequest(rsp, req) - if rsp.statusCode != http.StatusOK { - t.Fatalf("Unexpected failure: (%d): %s", rsp.statusCode, rsp.body) - } - - err = json.Unmarshal(rsp.body, &sbList) - if err != nil { - t.Fatal(err) - } - if len(sbList) == 0 { - t.Fatal("Empty response body") - } - if sbList[0].ContainerID != cid1 { - t.Fatalf("Incongruent resource found: %v", sbList[0]) - } -} - -func TestEndToEndErrorMessage(t *testing.T) { - defer testutils.SetupTestOSContext(t)() - - rsp := newWriter() - - // Cleanup local datastore file - os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address) - - c, err := libnetwork.New() - if err != nil { - t.Fatal(err) - } - defer c.Stop() - handleRequest := NewHTTPHandler(c) - - body := []byte{} - lr := newLocalReader(body) - req, err := http.NewRequest("POST", "/v1.19/networks", lr) - if err != nil { - t.Fatal(err) - } - handleRequest(rsp, req) - - if len(rsp.body) == 0 { - t.Fatal("Empty response body.") - } - empty := []byte("\"\"") - if bytes.Equal(empty, bytes.TrimSpace(rsp.body)) { - t.Fatal("Empty response error message.") - } -} - -type bre struct{} - -func (b *bre) Error() string { - return "I am a bad request error" -} -func (b *bre) BadRequest() {} - -type nfe struct{} - -func (n *nfe) Error() string { - return "I am a not found error" -} -func (n *nfe) NotFound() {} - -type forb struct{} - -func (f *forb) Error() string { - return "I am a bad request error" -} -func (f *forb) Forbidden() {} - -type notimpl struct{} - -func (nip *notimpl) Error() string { - return "I am a not implemented error" -} -func (nip *notimpl) NotImplemented() {} - -type inter struct{} - -func (it *inter) Error() string { - return "I am an internal error" -} -func (it *inter) Internal() {} - -type tout struct{} - -func (to *tout) Error() string { - return "I am a timeout error" -} -func (to *tout) Timeout() {} - -type noserv struct{} - -func (nos *noserv) Error() string { - return "I am a no service error" -} -func (nos *noserv) NoService() {} - -type notclassified struct{} - -func (noc *notclassified) Error() string { - return "I am a non classified error" -} - -func TestErrorConversion(t *testing.T) { - if convertNetworkError(new(bre)).StatusCode != http.StatusBadRequest { - t.Fatal("Failed to recognize BadRequest error") - } - - if convertNetworkError(new(nfe)).StatusCode != http.StatusNotFound { - t.Fatal("Failed to recognize NotFound error") - } - - if convertNetworkError(new(forb)).StatusCode != http.StatusForbidden { - t.Fatal("Failed to recognize Forbidden error") - } - - if convertNetworkError(new(notimpl)).StatusCode != http.StatusNotImplemented { - t.Fatal("Failed to recognize NotImplemented error") - } - - if convertNetworkError(new(inter)).StatusCode != http.StatusInternalServerError { - t.Fatal("Failed to recognize Internal error") - } - - if convertNetworkError(new(tout)).StatusCode != http.StatusRequestTimeout { - t.Fatal("Failed to recognize Timeout error") - } - - if convertNetworkError(new(noserv)).StatusCode != http.StatusServiceUnavailable { - t.Fatal("Failed to recognize No Service error") - } - - if convertNetworkError(new(notclassified)).StatusCode != http.StatusInternalServerError { - t.Fatal("Failed to recognize not classified error as Internal error") - } -} - -func TestFieldRegex(t *testing.T) { - pr := regexp.MustCompile(regex) - qr := regexp.MustCompile(`^` + qregx + `$`) // mux compiles it like this - - if pr.MatchString("") { - t.Fatal("Unexpected match") - } - if !qr.MatchString("") { - t.Fatal("Unexpected match failure") - } - - if pr.MatchString(":") { - t.Fatal("Unexpected match") - } - if qr.MatchString(":") { - t.Fatal("Unexpected match") - } - - if pr.MatchString(".") { - t.Fatal("Unexpected match") - } - if qr.MatchString(".") { - t.Fatal("Unexpected match") - } -} diff --git a/libnetwork/api/types.go b/libnetwork/api/types.go deleted file mode 100644 index 6552ae3667..0000000000 --- a/libnetwork/api/types.go +++ /dev/null @@ -1,96 +0,0 @@ -package api - -import "github.com/docker/docker/libnetwork/types" - -/*********** - Resources -************/ - -// networkResource is the body of the "get network" http response message -type networkResource struct { - Name string `json:"name"` - ID string `json:"id"` - Type string `json:"type"` - Endpoints []*endpointResource `json:"endpoints"` -} - -// endpointResource is the body of the "get endpoint" http response message -type endpointResource struct { - Name string `json:"name"` - ID string `json:"id"` - Network string `json:"network"` -} - -// sandboxResource is the body of "get service backend" response message -type sandboxResource struct { - ID string `json:"id"` - Key string `json:"key"` - ContainerID string `json:"container_id"` -} - -/*********** - Body types - ************/ - -type ipamConf struct { - PreferredPool string - SubPool string - Gateway string - AuxAddresses map[string]string -} - -// networkCreate is the expected body of the "create network" http request message -type networkCreate struct { - Name string `json:"name"` - ID string `json:"id"` - NetworkType string `json:"network_type"` - IPv4Conf []ipamConf `json:"ipv4_configuration"` - DriverOpts map[string]string `json:"driver_opts"` - NetworkOpts map[string]string `json:"network_opts"` -} - -// endpointCreate represents the body of the "create endpoint" http request message -type endpointCreate struct { - Name string `json:"name"` - MyAliases []string `json:"my_aliases"` -} - -// sandboxCreate is the expected body of the "create sandbox" http request message -type sandboxCreate struct { - ContainerID string `json:"container_id"` - HostName string `json:"host_name"` - DomainName string `json:"domain_name"` - HostsPath string `json:"hosts_path"` - ResolvConfPath string `json:"resolv_conf_path"` - DNS []string `json:"dns"` - ExtraHosts []extraHost `json:"extra_hosts"` - UseDefaultSandbox bool `json:"use_default_sandbox"` - UseExternalKey bool `json:"use_external_key"` - ExposedPorts []types.TransportPort `json:"exposed_ports"` - PortMapping []types.PortBinding `json:"port_mapping"` -} - -// endpointJoin represents the expected body of the "join endpoint" or "leave endpoint" http request messages -type endpointJoin struct { - SandboxID string `json:"sandbox_id"` - Aliases []string `json:"aliases"` -} - -// servicePublish represents the body of the "publish service" http request message -type servicePublish struct { - Name string `json:"name"` - MyAliases []string `json:"my_aliases"` - Network string `json:"network_name"` -} - -// serviceDelete represents the body of the "unpublish service" http request message -type serviceDelete struct { - Name string `json:"name"` - Force bool `json:"force"` -} - -// extraHost represents the extra host object -type extraHost struct { - Name string `json:"name"` - Address string `json:"address"` -}