Browse code

Merge pull request #35030 from tossmilestone/34459-fix-network-create-conflict-errcode

Fix returned error code for network creation from 500 to 409

Sebastiaan van Stijn authored on 2017/10/25 21:29:20
Showing 2 changed files
... ...
@@ -100,6 +100,24 @@ func (e ambigousResultsError) Error() string {
100 100
 
101 101
 func (ambigousResultsError) InvalidParameter() {}
102 102
 
103
+type conflictError struct {
104
+	cause error
105
+}
106
+
107
+func (e conflictError) Error() string {
108
+	return e.cause.Error()
109
+}
110
+
111
+func (e conflictError) Cause() error {
112
+	return e.cause
113
+}
114
+
115
+func (e conflictError) Conflict() {}
116
+
117
+func nameConflict(name string) error {
118
+	return conflictError{libnetwork.NetworkNameError(name)}
119
+}
120
+
103 121
 func (n *networkRouter) getNetwork(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
104 122
 	if err := httputils.ParseForm(r); err != nil {
105 123
 		return err
... ...
@@ -225,7 +243,7 @@ func (n *networkRouter) postNetworkCreate(ctx context.Context, w http.ResponseWr
225 225
 	}
226 226
 
227 227
 	if nws, err := n.cluster.GetNetworksByName(create.Name); err == nil && len(nws) > 0 {
228
-		return libnetwork.NetworkNameError(create.Name)
228
+		return nameConflict(create.Name)
229 229
 	}
230 230
 
231 231
 	nw, err := n.backend.CreateNetwork(create)
... ...
@@ -235,7 +253,7 @@ func (n *networkRouter) postNetworkCreate(ctx context.Context, w http.ResponseWr
235 235
 			// check if user defined CheckDuplicate, if set true, return err
236 236
 			// otherwise prepare a warning message
237 237
 			if create.CheckDuplicate {
238
-				return libnetwork.NetworkNameError(create.Name)
238
+				return nameConflict(create.Name)
239 239
 			}
240 240
 			warning = libnetwork.NetworkNameError(create.Name).Error()
241 241
 		}
... ...
@@ -35,7 +35,7 @@ func (s *DockerSuite) TestAPINetworkCreateDelete(c *check.C) {
35 35
 			CheckDuplicate: true,
36 36
 		},
37 37
 	}
38
-	id := createNetwork(c, config, true)
38
+	id := createNetwork(c, config, http.StatusCreated)
39 39
 	c.Assert(isNetworkAvailable(c, name), checker.Equals, true)
40 40
 
41 41
 	// delete the network and make sure it is deleted
... ...
@@ -60,14 +60,14 @@ func (s *DockerSuite) TestAPINetworkCreateCheckDuplicate(c *check.C) {
60 60
 	}
61 61
 
62 62
 	// Creating a new network first
63
-	createNetwork(c, configOnCheck, true)
63
+	createNetwork(c, configOnCheck, http.StatusCreated)
64 64
 	c.Assert(isNetworkAvailable(c, name), checker.Equals, true)
65 65
 
66 66
 	// Creating another network with same name and CheckDuplicate must fail
67
-	createNetwork(c, configOnCheck, false)
67
+	createNetwork(c, configOnCheck, http.StatusConflict)
68 68
 
69 69
 	// Creating another network with same name and not CheckDuplicate must succeed
70
-	createNetwork(c, configNotCheck, true)
70
+	createNetwork(c, configNotCheck, http.StatusCreated)
71 71
 }
72 72
 
73 73
 func (s *DockerSuite) TestAPINetworkFilter(c *check.C) {
... ...
@@ -116,7 +116,7 @@ func (s *DockerSuite) TestAPINetworkInspectUserDefinedNetwork(c *check.C) {
116 116
 			Options: map[string]string{"foo": "bar", "opts": "dopts"},
117 117
 		},
118 118
 	}
119
-	id0 := createNetwork(c, config, true)
119
+	id0 := createNetwork(c, config, http.StatusCreated)
120 120
 	c.Assert(isNetworkAvailable(c, "br0"), checker.Equals, true)
121 121
 
122 122
 	nr := getNetworkResource(c, id0)
... ...
@@ -139,7 +139,7 @@ func (s *DockerSuite) TestAPINetworkConnectDisconnect(c *check.C) {
139 139
 	config := types.NetworkCreateRequest{
140 140
 		Name: name,
141 141
 	}
142
-	id := createNetwork(c, config, true)
142
+	id := createNetwork(c, config, http.StatusCreated)
143 143
 	nr := getNetworkResource(c, id)
144 144
 	c.Assert(nr.Name, checker.Equals, name)
145 145
 	c.Assert(nr.ID, checker.Equals, id)
... ...
@@ -187,7 +187,7 @@ func (s *DockerSuite) TestAPINetworkIPAMMultipleBridgeNetworks(c *check.C) {
187 187
 			IPAM:   ipam0,
188 188
 		},
189 189
 	}
190
-	id0 := createNetwork(c, config0, true)
190
+	id0 := createNetwork(c, config0, http.StatusCreated)
191 191
 	c.Assert(isNetworkAvailable(c, "test0"), checker.Equals, true)
192 192
 
193 193
 	ipam1 := &network.IPAM{
... ...
@@ -202,7 +202,7 @@ func (s *DockerSuite) TestAPINetworkIPAMMultipleBridgeNetworks(c *check.C) {
202 202
 			IPAM:   ipam1,
203 203
 		},
204 204
 	}
205
-	createNetwork(c, config1, false)
205
+	createNetwork(c, config1, http.StatusForbidden)
206 206
 	c.Assert(isNetworkAvailable(c, "test1"), checker.Equals, false)
207 207
 
208 208
 	ipam2 := &network.IPAM{
... ...
@@ -217,20 +217,20 @@ func (s *DockerSuite) TestAPINetworkIPAMMultipleBridgeNetworks(c *check.C) {
217 217
 			IPAM:   ipam2,
218 218
 		},
219 219
 	}
220
-	createNetwork(c, config2, true)
220
+	createNetwork(c, config2, http.StatusCreated)
221 221
 	c.Assert(isNetworkAvailable(c, "test2"), checker.Equals, true)
222 222
 
223 223
 	// remove test0 and retry to create test1
224 224
 	deleteNetwork(c, id0, true)
225
-	createNetwork(c, config1, true)
225
+	createNetwork(c, config1, http.StatusCreated)
226 226
 	c.Assert(isNetworkAvailable(c, "test1"), checker.Equals, true)
227 227
 
228 228
 	// for networks w/o ipam specified, docker will choose proper non-overlapping subnets
229
-	createNetwork(c, types.NetworkCreateRequest{Name: "test3"}, true)
229
+	createNetwork(c, types.NetworkCreateRequest{Name: "test3"}, http.StatusCreated)
230 230
 	c.Assert(isNetworkAvailable(c, "test3"), checker.Equals, true)
231
-	createNetwork(c, types.NetworkCreateRequest{Name: "test4"}, true)
231
+	createNetwork(c, types.NetworkCreateRequest{Name: "test4"}, http.StatusCreated)
232 232
 	c.Assert(isNetworkAvailable(c, "test4"), checker.Equals, true)
233
-	createNetwork(c, types.NetworkCreateRequest{Name: "test5"}, true)
233
+	createNetwork(c, types.NetworkCreateRequest{Name: "test5"}, http.StatusCreated)
234 234
 	c.Assert(isNetworkAvailable(c, "test5"), checker.Equals, true)
235 235
 
236 236
 	for i := 1; i < 6; i++ {
... ...
@@ -253,9 +253,8 @@ func createDeletePredefinedNetwork(c *check.C, name string) {
253 253
 			CheckDuplicate: true,
254 254
 		},
255 255
 	}
256
-	shouldSucceed := false
257
-	createNetwork(c, config, shouldSucceed)
258
-	deleteNetwork(c, name, shouldSucceed)
256
+	createNetwork(c, config, http.StatusForbidden)
257
+	deleteNetwork(c, name, false)
259 258
 }
260 259
 
261 260
 func isNetworkAvailable(c *check.C, name string) bool {
... ...
@@ -316,22 +315,22 @@ func getNetworkResource(c *check.C, id string) *types.NetworkResource {
316 316
 	return &nr
317 317
 }
318 318
 
319
-func createNetwork(c *check.C, config types.NetworkCreateRequest, shouldSucceed bool) string {
319
+func createNetwork(c *check.C, config types.NetworkCreateRequest, expectedStatusCode int) string {
320 320
 	resp, body, err := request.Post("/networks/create", request.JSONBody(config))
321 321
 	c.Assert(err, checker.IsNil)
322 322
 	defer resp.Body.Close()
323
-	if !shouldSucceed {
324
-		c.Assert(resp.StatusCode, checker.Not(checker.Equals), http.StatusCreated)
325
-		return ""
326
-	}
327 323
 
328
-	c.Assert(resp.StatusCode, checker.Equals, http.StatusCreated)
324
+	c.Assert(resp.StatusCode, checker.Equals, expectedStatusCode)
329 325
 
330
-	var nr types.NetworkCreateResponse
331
-	err = json.NewDecoder(body).Decode(&nr)
332
-	c.Assert(err, checker.IsNil)
326
+	if expectedStatusCode == http.StatusCreated {
327
+		var nr types.NetworkCreateResponse
328
+		err = json.NewDecoder(body).Decode(&nr)
329
+		c.Assert(err, checker.IsNil)
333 330
 
334
-	return nr.ID
331
+		return nr.ID
332
+	} else {
333
+		return ""
334
+	}
335 335
 }
336 336
 
337 337
 func connectNetwork(c *check.C, nid, cid string) {