From ab1871872d547e01f78a8a6c7af96c6cf05f793d Mon Sep 17 00:00:00 2001 From: He Xiaoxi Date: Fri, 29 Sep 2017 10:13:44 +0800 Subject: [PATCH] Fix returned error code for network creation from 500 to 409 Signed-off-by: He Xiaoxi --- api/server/router/network/network_routes.go | 22 ++++++++- integration-cli/docker_api_network_test.go | 53 ++++++++++----------- 2 files changed, 46 insertions(+), 29 deletions(-) diff --git a/api/server/router/network/network_routes.go b/api/server/router/network/network_routes.go index ad3e74e6eb..b8a69fed00 100644 --- a/api/server/router/network/network_routes.go +++ b/api/server/router/network/network_routes.go @@ -100,6 +100,24 @@ func (e ambigousResultsError) Error() string { func (ambigousResultsError) InvalidParameter() {} +type conflictError struct { + cause error +} + +func (e conflictError) Error() string { + return e.cause.Error() +} + +func (e conflictError) Cause() error { + return e.cause +} + +func (e conflictError) Conflict() {} + +func nameConflict(name string) error { + return conflictError{libnetwork.NetworkNameError(name)} +} + func (n *networkRouter) getNetwork(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { if err := httputils.ParseForm(r); err != nil { return err @@ -225,7 +243,7 @@ func (n *networkRouter) postNetworkCreate(ctx context.Context, w http.ResponseWr } if nws, err := n.cluster.GetNetworksByName(create.Name); err == nil && len(nws) > 0 { - return libnetwork.NetworkNameError(create.Name) + return nameConflict(create.Name) } nw, err := n.backend.CreateNetwork(create) @@ -235,7 +253,7 @@ func (n *networkRouter) postNetworkCreate(ctx context.Context, w http.ResponseWr // check if user defined CheckDuplicate, if set true, return err // otherwise prepare a warning message if create.CheckDuplicate { - return libnetwork.NetworkNameError(create.Name) + return nameConflict(create.Name) } warning = libnetwork.NetworkNameError(create.Name).Error() } diff --git a/integration-cli/docker_api_network_test.go b/integration-cli/docker_api_network_test.go index 129ec7ea69..b6cd905f56 100644 --- a/integration-cli/docker_api_network_test.go +++ b/integration-cli/docker_api_network_test.go @@ -35,7 +35,7 @@ func (s *DockerSuite) TestAPINetworkCreateDelete(c *check.C) { CheckDuplicate: true, }, } - id := createNetwork(c, config, true) + id := createNetwork(c, config, http.StatusCreated) c.Assert(isNetworkAvailable(c, name), checker.Equals, true) // delete the network and make sure it is deleted @@ -60,14 +60,14 @@ func (s *DockerSuite) TestAPINetworkCreateCheckDuplicate(c *check.C) { } // Creating a new network first - createNetwork(c, configOnCheck, true) + createNetwork(c, configOnCheck, http.StatusCreated) c.Assert(isNetworkAvailable(c, name), checker.Equals, true) // Creating another network with same name and CheckDuplicate must fail - createNetwork(c, configOnCheck, false) + createNetwork(c, configOnCheck, http.StatusConflict) // Creating another network with same name and not CheckDuplicate must succeed - createNetwork(c, configNotCheck, true) + createNetwork(c, configNotCheck, http.StatusCreated) } func (s *DockerSuite) TestAPINetworkFilter(c *check.C) { @@ -114,7 +114,7 @@ func (s *DockerSuite) TestAPINetworkInspect(c *check.C) { Options: map[string]string{"foo": "bar", "opts": "dopts"}, }, } - id0 := createNetwork(c, config, true) + id0 := createNetwork(c, config, http.StatusCreated) c.Assert(isNetworkAvailable(c, "br0"), checker.Equals, true) nr = getNetworkResource(c, id0) @@ -137,7 +137,7 @@ func (s *DockerSuite) TestAPINetworkConnectDisconnect(c *check.C) { config := types.NetworkCreateRequest{ Name: name, } - id := createNetwork(c, config, true) + id := createNetwork(c, config, http.StatusCreated) nr := getNetworkResource(c, id) c.Assert(nr.Name, checker.Equals, name) c.Assert(nr.ID, checker.Equals, id) @@ -185,7 +185,7 @@ func (s *DockerSuite) TestAPINetworkIPAMMultipleBridgeNetworks(c *check.C) { IPAM: ipam0, }, } - id0 := createNetwork(c, config0, true) + id0 := createNetwork(c, config0, http.StatusCreated) c.Assert(isNetworkAvailable(c, "test0"), checker.Equals, true) ipam1 := &network.IPAM{ @@ -200,7 +200,7 @@ func (s *DockerSuite) TestAPINetworkIPAMMultipleBridgeNetworks(c *check.C) { IPAM: ipam1, }, } - createNetwork(c, config1, false) + createNetwork(c, config1, http.StatusForbidden) c.Assert(isNetworkAvailable(c, "test1"), checker.Equals, false) ipam2 := &network.IPAM{ @@ -215,20 +215,20 @@ func (s *DockerSuite) TestAPINetworkIPAMMultipleBridgeNetworks(c *check.C) { IPAM: ipam2, }, } - createNetwork(c, config2, true) + createNetwork(c, config2, http.StatusCreated) c.Assert(isNetworkAvailable(c, "test2"), checker.Equals, true) // remove test0 and retry to create test1 deleteNetwork(c, id0, true) - createNetwork(c, config1, true) + createNetwork(c, config1, http.StatusCreated) c.Assert(isNetworkAvailable(c, "test1"), checker.Equals, true) // for networks w/o ipam specified, docker will choose proper non-overlapping subnets - createNetwork(c, types.NetworkCreateRequest{Name: "test3"}, true) + createNetwork(c, types.NetworkCreateRequest{Name: "test3"}, http.StatusCreated) c.Assert(isNetworkAvailable(c, "test3"), checker.Equals, true) - createNetwork(c, types.NetworkCreateRequest{Name: "test4"}, true) + createNetwork(c, types.NetworkCreateRequest{Name: "test4"}, http.StatusCreated) c.Assert(isNetworkAvailable(c, "test4"), checker.Equals, true) - createNetwork(c, types.NetworkCreateRequest{Name: "test5"}, true) + createNetwork(c, types.NetworkCreateRequest{Name: "test5"}, http.StatusCreated) c.Assert(isNetworkAvailable(c, "test5"), checker.Equals, true) for i := 1; i < 6; i++ { @@ -251,9 +251,8 @@ func createDeletePredefinedNetwork(c *check.C, name string) { CheckDuplicate: true, }, } - shouldSucceed := false - createNetwork(c, config, shouldSucceed) - deleteNetwork(c, name, shouldSucceed) + createNetwork(c, config, http.StatusForbidden) + deleteNetwork(c, name, false) } func isNetworkAvailable(c *check.C, name string) bool { @@ -307,22 +306,22 @@ func getNetworkResource(c *check.C, id string) *types.NetworkResource { return &nr } -func createNetwork(c *check.C, config types.NetworkCreateRequest, shouldSucceed bool) string { +func createNetwork(c *check.C, config types.NetworkCreateRequest, expectedStatusCode int) string { resp, body, err := request.Post("/networks/create", request.JSONBody(config)) c.Assert(err, checker.IsNil) defer resp.Body.Close() - if !shouldSucceed { - c.Assert(resp.StatusCode, checker.Not(checker.Equals), http.StatusCreated) + + c.Assert(resp.StatusCode, checker.Equals, expectedStatusCode) + + if expectedStatusCode == http.StatusCreated { + var nr types.NetworkCreateResponse + err = json.NewDecoder(body).Decode(&nr) + c.Assert(err, checker.IsNil) + + return nr.ID + } else { return "" } - - c.Assert(resp.StatusCode, checker.Equals, http.StatusCreated) - - var nr types.NetworkCreateResponse - err = json.NewDecoder(body).Decode(&nr) - c.Assert(err, checker.IsNil) - - return nr.ID } func connectNetwork(c *check.C, nid, cid string) {