Signed-off-by: Madhu Venugopal <madhu@docker.com>
| ... | ... |
@@ -13,6 +13,7 @@ import ( |
| 13 | 13 |
"github.com/docker/docker/daemon" |
| 14 | 14 |
"github.com/docker/docker/daemon/network" |
| 15 | 15 |
"github.com/docker/docker/pkg/parsers/filters" |
| 16 |
+ "github.com/docker/docker/runconfig" |
|
| 16 | 17 |
"github.com/docker/libnetwork" |
| 17 | 18 |
) |
| 18 | 19 |
|
| ... | ... |
@@ -85,6 +86,11 @@ func (n *networkRouter) postNetworkCreate(ctx context.Context, w http.ResponseWr |
| 85 | 85 |
return err |
| 86 | 86 |
} |
| 87 | 87 |
|
| 88 |
+ if runconfig.IsPreDefinedNetwork(create.Name) {
|
|
| 89 |
+ return httputils.WriteJSON(w, http.StatusForbidden, |
|
| 90 |
+ fmt.Sprintf("%s is a pre-defined network and cannot be created", create.Name))
|
|
| 91 |
+ } |
|
| 92 |
+ |
|
| 88 | 93 |
nw, err := n.daemon.GetNetwork(create.Name, daemon.NetworkByName) |
| 89 | 94 |
if _, ok := err.(libnetwork.ErrNoSuchNetwork); err != nil && !ok {
|
| 90 | 95 |
return err |
| ... | ... |
@@ -161,6 +167,11 @@ func (n *networkRouter) deleteNetwork(ctx context.Context, w http.ResponseWriter |
| 161 | 161 |
return err |
| 162 | 162 |
} |
| 163 | 163 |
|
| 164 |
+ if runconfig.IsPreDefinedNetwork(nw.Name()) {
|
|
| 165 |
+ return httputils.WriteJSON(w, http.StatusForbidden, |
|
| 166 |
+ fmt.Sprintf("%s is a pre-defined network and cannot be removed", nw.Name()))
|
|
| 167 |
+ } |
|
| 168 |
+ |
|
| 164 | 169 |
return nw.Delete() |
| 165 | 170 |
} |
| 166 | 171 |
|
| ... | ... |
@@ -193,6 +193,23 @@ func (s *DockerSuite) TestApiNetworkIpamMultipleBridgeNetworks(c *check.C) {
|
| 193 | 193 |
} |
| 194 | 194 |
} |
| 195 | 195 |
|
| 196 |
+func (s *DockerSuite) TestApiCreateDeletePredefinedNetworks(c *check.C) {
|
|
| 197 |
+ createDeletePredefinedNetwork(c, "bridge") |
|
| 198 |
+ createDeletePredefinedNetwork(c, "none") |
|
| 199 |
+ createDeletePredefinedNetwork(c, "host") |
|
| 200 |
+} |
|
| 201 |
+ |
|
| 202 |
+func createDeletePredefinedNetwork(c *check.C, name string) {
|
|
| 203 |
+ // Create pre-defined network |
|
| 204 |
+ config := types.NetworkCreate{
|
|
| 205 |
+ Name: name, |
|
| 206 |
+ CheckDuplicate: true, |
|
| 207 |
+ } |
|
| 208 |
+ shouldSucceed := false |
|
| 209 |
+ createNetwork(c, config, shouldSucceed) |
|
| 210 |
+ deleteNetwork(c, name, shouldSucceed) |
|
| 211 |
+} |
|
| 212 |
+ |
|
| 196 | 213 |
func isNetworkAvailable(c *check.C, name string) bool {
|
| 197 | 214 |
status, body, err := sockRequest("GET", "/networks", nil)
|
| 198 | 215 |
c.Assert(status, checker.Equals, http.StatusOK) |
| ... | ... |
@@ -284,7 +301,6 @@ func deleteNetwork(c *check.C, id string, shouldSucceed bool) {
|
| 284 | 284 |
status, _, err := sockRequest("DELETE", "/networks/"+id, nil)
|
| 285 | 285 |
if !shouldSucceed {
|
| 286 | 286 |
c.Assert(status, checker.Not(checker.Equals), http.StatusOK) |
| 287 |
- c.Assert(err, checker.NotNil) |
|
| 288 | 287 |
return |
| 289 | 288 |
} |
| 290 | 289 |
c.Assert(status, checker.Equals, http.StatusOK) |
| ... | ... |
@@ -66,6 +66,12 @@ func (n NetworkMode) IsUserDefined() bool {
|
| 66 | 66 |
return !n.IsDefault() && !n.IsBridge() && !n.IsHost() && !n.IsNone() && !n.IsContainer() |
| 67 | 67 |
} |
| 68 | 68 |
|
| 69 |
+// IsPreDefinedNetwork indicates if a network is predefined by the daemon |
|
| 70 |
+func IsPreDefinedNetwork(network string) bool {
|
|
| 71 |
+ n := NetworkMode(network) |
|
| 72 |
+ return n.IsBridge() || n.IsHost() || n.IsNone() |
|
| 73 |
+} |
|
| 74 |
+ |
|
| 69 | 75 |
//UserDefined indicates user-created network |
| 70 | 76 |
func (n NetworkMode) UserDefined() string {
|
| 71 | 77 |
if n.IsUserDefined() {
|