diff --git a/api/server/router/network/network_routes.go b/api/server/router/network/network_routes.go index 0659ba61eb..28191ae412 100644 --- a/api/server/router/network/network_routes.go +++ b/api/server/router/network/network_routes.go @@ -13,6 +13,7 @@ import ( "github.com/docker/docker/daemon" "github.com/docker/docker/daemon/network" "github.com/docker/docker/pkg/parsers/filters" + "github.com/docker/docker/runconfig" "github.com/docker/libnetwork" ) @@ -85,6 +86,11 @@ func (n *networkRouter) postNetworkCreate(ctx context.Context, w http.ResponseWr return err } + if runconfig.IsPreDefinedNetwork(create.Name) { + return httputils.WriteJSON(w, http.StatusForbidden, + fmt.Sprintf("%s is a pre-defined network and cannot be created", create.Name)) + } + nw, err := n.daemon.GetNetwork(create.Name, daemon.NetworkByName) if _, ok := err.(libnetwork.ErrNoSuchNetwork); err != nil && !ok { return err @@ -161,6 +167,11 @@ func (n *networkRouter) deleteNetwork(ctx context.Context, w http.ResponseWriter return err } + if runconfig.IsPreDefinedNetwork(nw.Name()) { + return httputils.WriteJSON(w, http.StatusForbidden, + fmt.Sprintf("%s is a pre-defined network and cannot be removed", nw.Name())) + } + return nw.Delete() } diff --git a/integration-cli/docker_api_network_test.go b/integration-cli/docker_api_network_test.go index dc8e1b1b18..f76796b778 100644 --- a/integration-cli/docker_api_network_test.go +++ b/integration-cli/docker_api_network_test.go @@ -193,6 +193,23 @@ func (s *DockerSuite) TestApiNetworkIpamMultipleBridgeNetworks(c *check.C) { } } +func (s *DockerSuite) TestApiCreateDeletePredefinedNetworks(c *check.C) { + createDeletePredefinedNetwork(c, "bridge") + createDeletePredefinedNetwork(c, "none") + createDeletePredefinedNetwork(c, "host") +} + +func createDeletePredefinedNetwork(c *check.C, name string) { + // Create pre-defined network + config := types.NetworkCreate{ + Name: name, + CheckDuplicate: true, + } + shouldSucceed := false + createNetwork(c, config, shouldSucceed) + deleteNetwork(c, name, shouldSucceed) +} + func isNetworkAvailable(c *check.C, name string) bool { status, body, err := sockRequest("GET", "/networks", nil) c.Assert(status, checker.Equals, http.StatusOK) @@ -284,7 +301,6 @@ func deleteNetwork(c *check.C, id string, shouldSucceed bool) { status, _, err := sockRequest("DELETE", "/networks/"+id, nil) if !shouldSucceed { c.Assert(status, checker.Not(checker.Equals), http.StatusOK) - c.Assert(err, checker.NotNil) return } c.Assert(status, checker.Equals, http.StatusOK) diff --git a/runconfig/hostconfig_unix.go b/runconfig/hostconfig_unix.go index b952b172c2..fd0b988eb8 100644 --- a/runconfig/hostconfig_unix.go +++ b/runconfig/hostconfig_unix.go @@ -66,6 +66,12 @@ func (n NetworkMode) IsUserDefined() bool { return !n.IsDefault() && !n.IsBridge() && !n.IsHost() && !n.IsNone() && !n.IsContainer() } +// IsPreDefinedNetwork indicates if a network is predefined by the daemon +func IsPreDefinedNetwork(network string) bool { + n := NetworkMode(network) + return n.IsBridge() || n.IsHost() || n.IsNone() +} + //UserDefined indicates user-created network func (n NetworkMode) UserDefined() string { if n.IsUserDefined() { diff --git a/runconfig/hostconfig_windows.go b/runconfig/hostconfig_windows.go index 19c90bf72a..d21e082280 100644 --- a/runconfig/hostconfig_windows.go +++ b/runconfig/hostconfig_windows.go @@ -27,3 +27,8 @@ func MergeConfigs(config *Config, hostConfig *HostConfig) *ContainerConfigWrappe hostConfig, } } + +// IsPreDefinedNetwork indicates if a network is predefined by the daemon +func IsPreDefinedNetwork(network string) bool { + return false +}