Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions cmd/nerdctl/network/network_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func createCommand() *cobra.Command {
cmd.Flags().String("ip-range", "", `Allocate container ip from a sub-range`)
cmd.Flags().StringArray("label", nil, "Set metadata for a network")
cmd.Flags().Bool("ipv6", false, "Enable IPv6 networking")
cmd.Flags().Bool("internal", false, "Restrict external access to the network")
return cmd
}

Expand Down Expand Up @@ -100,6 +101,10 @@ func createAction(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
internal, err := cmd.Flags().GetBool("internal")
if err != nil {
return err
}

return network.Create(types.NetworkCreateOptions{
GOptions: globalOptions,
Expand All @@ -113,5 +118,6 @@ func createAction(cmd *cobra.Command, args []string) error {
IPRange: ipRangeStr,
Labels: labels,
IPv6: ipv6,
Internal: internal,
}, cmd.OutOrStdout())
}
48 changes: 48 additions & 0 deletions cmd/nerdctl/network/network_create_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package network

import (
"encoding/json"
"fmt"
"net"
"strings"
Expand Down Expand Up @@ -107,6 +108,53 @@ func TestNetworkCreate(t *testing.T) {
}
},
},
{
Description: "internal enabled",
Setup: func(data test.Data, helpers test.Helpers) {
helpers.Ensure("network", "create", "--internal", data.Identifier())
netw := nerdtest.InspectNetwork(helpers, data.Identifier())
assert.Equal(t, len(netw.IPAM.Config), 1)
data.Labels().Set("subnet", netw.IPAM.Config[0].Subnet)
},
Cleanup: func(data test.Data, helpers test.Helpers) {
helpers.Anyhow("network", "rm", data.Identifier())
},
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
return helpers.Command("run", "--rm", "--net", data.Identifier(), testutil.CommonImage, "ip", "route")
},
Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
return &test.Expected{
ExitCode: 0,
Output: func(stdout string, t tig.T) {
assert.Assert(t, strings.Contains(stdout, data.Labels().Get("subnet")))
assert.Assert(t, !strings.Contains(stdout, "default "))
if nerdtest.IsDocker() {
return
}
nativeNet := nerdtest.InspectNetworkNative(helpers, data.Identifier())
var cni struct {
Plugins []struct {
Type string `json:"type"`
IsGW bool `json:"isGateway"`
IPMasq bool `json:"ipMasq"`
} `json:"plugins"`
}
_ = json.Unmarshal(nativeNet.CNI, &cni)
// bridge plugin assertions and no portmap
foundBridge := false
for _, p := range cni.Plugins {
assert.Assert(t, p.Type != "portmap")
if p.Type == "bridge" {
foundBridge = true
assert.Assert(t, !p.IsGW)
assert.Assert(t, !p.IPMasq)
}
}
assert.Assert(t, foundBridge)
},
}
},
},
}

testCase.Run(t)
Expand Down
3 changes: 2 additions & 1 deletion docs/command-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -1169,8 +1169,9 @@ Flags:
- :whale: `--ip-range`: Allocate container ip from a sub-range
- :whale: `--label`: Set metadata on a network
- :whale: `--ipv6`: Enable IPv6. Should be used with a valid subnet.
- :whale: `--internal`: Restrict external access to the network.

Unimplemented `docker network create` flags: `--attachable`, `--aux-address`, `--config-from`, `--config-only`, `--ingress`, `--internal`, `--scope`
Unimplemented `docker network create` flags: `--attachable`, `--aux-address`, `--config-from`, `--config-only`, `--ingress`, `--scope`

### :whale: nerdctl network ls

Expand Down
1 change: 1 addition & 0 deletions pkg/api/types/network_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type NetworkCreateOptions struct {
IPRange string
Labels []string
IPv6 bool
Internal bool
}

// NetworkInspectOptions specifies options for `nerdctl network inspect`.
Expand Down
4 changes: 2 additions & 2 deletions pkg/netutil/netutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,11 +306,11 @@ func (e *CNIEnv) CreateNetwork(opts types.NetworkCreateOptions) (*NetworkConfig,
if _, ok := netMap[opts.Name]; ok {
return nil, errdefs.ErrAlreadyExists
}
ipam, err := e.generateIPAM(opts.IPAMDriver, opts.Subnets, opts.Gateway, opts.IPRange, opts.IPAMOptions, opts.IPv6)
ipam, err := e.generateIPAM(opts.IPAMDriver, opts.Subnets, opts.Gateway, opts.IPRange, opts.IPAMOptions, opts.IPv6, opts.Internal)
if err != nil {
return nil, err
}
plugins, err := e.generateCNIPlugins(opts.Driver, opts.Name, ipam, opts.Options, opts.IPv6)
plugins, err := e.generateCNIPlugins(opts.Driver, opts.Name, ipam, opts.Options, opts.IPv6, opts.Internal)
if err != nil {
return nil, err
}
Expand Down
24 changes: 17 additions & 7 deletions pkg/netutil/netutil_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func (n *NetworkConfig) clean() error {
return nil
}

func (e *CNIEnv) generateCNIPlugins(driver string, name string, ipam map[string]interface{}, opts map[string]string, ipv6 bool) ([]CNIPlugin, error) {
func (e *CNIEnv) generateCNIPlugins(driver string, name string, ipam map[string]interface{}, opts map[string]string, ipv6 bool, internal bool) ([]CNIPlugin, error) {
var (
plugins []CNIPlugin
err error
Expand Down Expand Up @@ -123,13 +123,21 @@ func (e *CNIEnv) generateCNIPlugins(driver string, name string, ipam map[string]
}
bridge.MTU = mtu
bridge.IPAM = ipam
bridge.IsGW = true
bridge.IPMasq = iPMasq
bridge.IsGW = !internal
if internal {
bridge.IPMasq = false
} else {
bridge.IPMasq = iPMasq
}
bridge.HairpinMode = true
if ipv6 {
bridge.Capabilities["ips"] = true
}
plugins = []CNIPlugin{bridge, newPortMapPlugin(), newFirewallPlugin(), newTuningPlugin()}
if internal {
plugins = []CNIPlugin{bridge, newFirewallPlugin(), newTuningPlugin()}
} else {
plugins = []CNIPlugin{bridge, newPortMapPlugin(), newFirewallPlugin(), newTuningPlugin()}
}
if name != DefaultNetworkName {
firewallPath := filepath.Join(e.Path, "firewall")
ok, err := firewallPluginGEQ110(firewallPath)
Expand Down Expand Up @@ -186,13 +194,15 @@ func (e *CNIEnv) generateCNIPlugins(driver string, name string, ipam map[string]
return plugins, nil
}

func (e *CNIEnv) generateIPAM(driver string, subnets []string, gatewayStr, ipRangeStr string, opts map[string]string, ipv6 bool) (map[string]interface{}, error) {
func (e *CNIEnv) generateIPAM(driver string, subnets []string, gatewayStr, ipRangeStr string, opts map[string]string, ipv6 bool, internal bool) (map[string]interface{}, error) {
var ipamConfig interface{}
switch driver {
case "default", "host-local":
ipamConf := newHostLocalIPAMConfig()
ipamConf.Routes = []IPAMRoute{
{Dst: "0.0.0.0/0"},
if !internal {
ipamConf.Routes = []IPAMRoute{
{Dst: "0.0.0.0/0"},
}
}
ranges, findIPv4, err := e.parseIPAMRanges(subnets, gatewayStr, ipRangeStr, ipv6)
if err != nil {
Expand Down
6 changes: 3 additions & 3 deletions pkg/netutil/netutil_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const (

// When creating non-default network without passing in `--subnet` option,
// nerdctl assigns subnet address for the creation starting from `StartingCIDR`
// This prevents subnet address overlapping with `DefaultCIDR` used by the default networkß
// This prevents subnet address overlapping with `DefaultCIDR` used by the default network
StartingCIDR = "10.4.1.0/24"
)

Expand Down Expand Up @@ -58,7 +58,7 @@ func (n *NetworkConfig) clean() error {
return nil
}

func (e *CNIEnv) generateCNIPlugins(driver string, name string, ipam map[string]interface{}, opts map[string]string, ipv6 bool) ([]CNIPlugin, error) {
func (e *CNIEnv) generateCNIPlugins(driver string, name string, ipam map[string]interface{}, opts map[string]string, ipv6 bool, internal bool) ([]CNIPlugin, error) {
var plugins []CNIPlugin
switch driver {
case "nat":
Expand All @@ -71,7 +71,7 @@ func (e *CNIEnv) generateCNIPlugins(driver string, name string, ipam map[string]
return plugins, nil
}

func (e *CNIEnv) generateIPAM(driver string, subnets []string, gatewayStr, ipRangeStr string, opts map[string]string, ipv6 bool) (map[string]interface{}, error) {
func (e *CNIEnv) generateIPAM(driver string, subnets []string, gatewayStr, ipRangeStr string, opts map[string]string, ipv6 bool, internal bool) (map[string]interface{}, error) {
switch driver {
case "default":
default:
Expand Down
13 changes: 13 additions & 0 deletions pkg/testutil/nerdtest/utilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,19 @@ func InspectNetwork(helpers test.Helpers, name string) dockercompat.Network {
return res
}

func InspectNetworkNative(helpers test.Helpers, name string) native.Network {
helpers.T().Helper()
var res native.Network
cmd := helpers.Command("network", "inspect", "--mode", "native", name)
cmd.Run(&test.Expected{
Output: expect.JSON([]native.Network{}, func(dc []native.Network, t tig.T) {
assert.Equal(t, 1, len(dc), "Unexpectedly got multiple results")
res = dc[0]
}),
})
return res
}

func InspectImage(helpers test.Helpers, name string) dockercompat.Image {
helpers.T().Helper()
var res dockercompat.Image
Expand Down