diff options
author | Paul Holzinger <pholzing@redhat.com> | 2021-12-10 15:22:09 +0100 |
---|---|---|
committer | Paul Holzinger <pholzing@redhat.com> | 2021-12-14 15:23:39 +0100 |
commit | 535818414c2a6bdcf6434e36c33775ea1a43f1cf (patch) | |
tree | bc7130eb922b7d2918527f13c3155506af4444f1 /pkg/specgen/namespaces_test.go | |
parent | d072167fe2f75db9648bf1be4181b42e9b7db9a4 (diff) | |
download | podman-535818414c2a6bdcf6434e36c33775ea1a43f1cf.tar.gz podman-535818414c2a6bdcf6434e36c33775ea1a43f1cf.tar.bz2 podman-535818414c2a6bdcf6434e36c33775ea1a43f1cf.zip |
support advanced network configuration via cli
Rework the --network parse logic to support multiple networks with
specific network configuration settings.
--network can now be set multiple times. For bridge network mode the
following options have been added:
- **alias=name**: Add network-scoped alias for the container.
- **ip=IPv4**: Specify a static ipv4 address for this container.
- **ip=IPv6**: Specify a static ipv6 address for this container.
- **mac=MAC**: Specify a static mac address address for this container.
- **interface_name**: Specify a name for the created network interface inside the container.
So now you can set --network bridge:ip=10.88.0.10,mac=44:33:22:11:00:99
for the default bridge network as well as for network names.
This is better than using --ip because we can set the ip per network
without any confusion which network the ip address should be assigned
to.
The --ip, --mac-address and --network-alias options are still supported
but --ip or --mac-address can only be set when only one network is set.
This limitation already existed previously.
The ability to specify a custom network interface name is new
Fixes #11534
Signed-off-by: Paul Holzinger <pholzing@redhat.com>
Diffstat (limited to 'pkg/specgen/namespaces_test.go')
-rw-r--r-- | pkg/specgen/namespaces_test.go | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/pkg/specgen/namespaces_test.go b/pkg/specgen/namespaces_test.go new file mode 100644 index 000000000..4f69e6b98 --- /dev/null +++ b/pkg/specgen/namespaces_test.go @@ -0,0 +1,265 @@ +package specgen + +import ( + "net" + "testing" + + "github.com/containers/podman/v3/libpod/network/types" + "github.com/containers/podman/v3/pkg/rootless" + "github.com/stretchr/testify/assert" +) + +func parsMacNoErr(mac string) types.HardwareAddr { + m, _ := net.ParseMAC(mac) + return types.HardwareAddr(m) +} + +func TestParseNetworkFlag(t *testing.T) { + // root and rootless have different defaults + defaultNetName := "default" + defaultNetworks := map[string]types.PerNetworkOptions{ + defaultNetName: {}, + } + defaultNsMode := Namespace{NSMode: Bridge} + if rootless.IsRootless() { + defaultNsMode = Namespace{NSMode: Slirp} + defaultNetworks = map[string]types.PerNetworkOptions{} + } + + tests := []struct { + name string + args []string + nsmode Namespace + networks map[string]types.PerNetworkOptions + options map[string][]string + err string + }{ + { + name: "empty input", + args: nil, + nsmode: defaultNsMode, + networks: defaultNetworks, + }, + { + name: "empty string as input", + args: []string{}, + nsmode: defaultNsMode, + networks: defaultNetworks, + }, + { + name: "default mode", + args: []string{"default"}, + nsmode: defaultNsMode, + networks: defaultNetworks, + }, + { + name: "private mode", + args: []string{"private"}, + nsmode: defaultNsMode, + networks: defaultNetworks, + }, + { + name: "bridge mode", + args: []string{"bridge"}, + nsmode: Namespace{NSMode: Bridge}, + networks: map[string]types.PerNetworkOptions{ + defaultNetName: {}, + }, + }, + { + name: "slirp4netns mode", + args: []string{"slirp4netns"}, + nsmode: Namespace{NSMode: Slirp}, + networks: map[string]types.PerNetworkOptions{}, + }, + { + name: "from pod mode", + args: []string{"pod"}, + nsmode: Namespace{NSMode: FromPod}, + networks: map[string]types.PerNetworkOptions{}, + }, + { + name: "no network mode", + args: []string{"none"}, + nsmode: Namespace{NSMode: NoNetwork}, + networks: map[string]types.PerNetworkOptions{}, + }, + { + name: "container mode", + args: []string{"container:abc"}, + nsmode: Namespace{NSMode: FromContainer, Value: "abc"}, + networks: map[string]types.PerNetworkOptions{}, + }, + { + name: "ns path mode", + args: []string{"ns:/path"}, + nsmode: Namespace{NSMode: Path, Value: "/path"}, + networks: map[string]types.PerNetworkOptions{}, + }, + { + name: "slirp4netns mode with options", + args: []string{"slirp4netns:cidr=10.0.0.0/24"}, + nsmode: Namespace{NSMode: Slirp}, + networks: map[string]types.PerNetworkOptions{}, + options: map[string][]string{ + "slirp4netns": {"cidr=10.0.0.0/24"}, + }, + }, + { + name: "bridge mode with options 1", + args: []string{"bridge:ip=10.0.0.1,mac=11:22:33:44:55:66"}, + nsmode: Namespace{NSMode: Bridge}, + networks: map[string]types.PerNetworkOptions{ + defaultNetName: { + StaticIPs: []net.IP{net.ParseIP("10.0.0.1")}, + StaticMAC: parsMacNoErr("11:22:33:44:55:66"), + }, + }, + }, + { + name: "bridge mode with options 2", + args: []string{"bridge:ip=10.0.0.1,ip=10.0.0.5"}, + nsmode: Namespace{NSMode: Bridge}, + networks: map[string]types.PerNetworkOptions{ + defaultNetName: { + StaticIPs: []net.IP{net.ParseIP("10.0.0.1"), net.ParseIP("10.0.0.5")}, + }, + }, + }, + { + name: "bridge mode with ip6 option", + args: []string{"bridge:ip6=fd10::"}, + nsmode: Namespace{NSMode: Bridge}, + networks: map[string]types.PerNetworkOptions{ + defaultNetName: { + StaticIPs: []net.IP{net.ParseIP("fd10::")}, + }, + }, + }, + { + name: "bridge mode with alias option", + args: []string{"bridge:alias=myname,alias=myname2"}, + nsmode: Namespace{NSMode: Bridge}, + networks: map[string]types.PerNetworkOptions{ + defaultNetName: { + Aliases: []string{"myname", "myname2"}, + }, + }, + }, + { + name: "bridge mode with alias option", + args: []string{"bridge:alias=myname,alias=myname2"}, + nsmode: Namespace{NSMode: Bridge}, + networks: map[string]types.PerNetworkOptions{ + defaultNetName: { + Aliases: []string{"myname", "myname2"}, + }, + }, + }, + { + name: "bridge mode with interface option", + args: []string{"bridge:interface_name=eth123"}, + nsmode: Namespace{NSMode: Bridge}, + networks: map[string]types.PerNetworkOptions{ + defaultNetName: { + InterfaceName: "eth123", + }, + }, + }, + { + name: "bridge mode with invalid option", + args: []string{"bridge:abc=123"}, + nsmode: Namespace{NSMode: Bridge}, + err: "unknown bridge network option: abc", + }, + { + name: "bridge mode with invalid ip", + args: []string{"bridge:ip=10..1"}, + nsmode: Namespace{NSMode: Bridge}, + err: "invalid ip address \"10..1\"", + }, + { + name: "bridge mode with invalid mac", + args: []string{"bridge:mac=123"}, + nsmode: Namespace{NSMode: Bridge}, + err: "address 123: invalid MAC address", + }, + { + name: "network name", + args: []string{"someName"}, + nsmode: Namespace{NSMode: Bridge}, + networks: map[string]types.PerNetworkOptions{ + "someName": {}, + }, + }, + { + name: "network name with options", + args: []string{"someName:ip=10.0.0.1"}, + nsmode: Namespace{NSMode: Bridge}, + networks: map[string]types.PerNetworkOptions{ + "someName": {StaticIPs: []net.IP{net.ParseIP("10.0.0.1")}}, + }, + }, + { + name: "multiple networks", + args: []string{"someName", "net2"}, + nsmode: Namespace{NSMode: Bridge}, + networks: map[string]types.PerNetworkOptions{ + "someName": {}, + "net2": {}, + }, + }, + { + name: "multiple networks with options", + args: []string{"someName:ip=10.0.0.1", "net2:ip=10.10.0.1"}, + nsmode: Namespace{NSMode: Bridge}, + networks: map[string]types.PerNetworkOptions{ + "someName": {StaticIPs: []net.IP{net.ParseIP("10.0.0.1")}}, + "net2": {StaticIPs: []net.IP{net.ParseIP("10.10.0.1")}}, + }, + }, + { + name: "multiple networks with bridge mode first should map to default net", + args: []string{"bridge", "net2"}, + nsmode: Namespace{NSMode: Bridge}, + networks: map[string]types.PerNetworkOptions{ + defaultNetName: {}, + "net2": {}, + }, + }, + { + name: "conflicting network modes should error", + args: []string{"bridge", "host"}, + nsmode: Namespace{NSMode: Bridge}, + err: "can only set extra network names, selected mode host conflicts with bridge: invalid argument", + }, + { + name: "multiple networks empty name should error", + args: []string{"someName", ""}, + nsmode: Namespace{NSMode: Bridge}, + err: "network name cannot be empty: invalid argument", + }, + { + name: "multiple networks on invalid mode should error", + args: []string{"host", "net2"}, + nsmode: Namespace{NSMode: Host}, + err: "cannot set multiple networks without bridge network mode, selected mode host: invalid argument", + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + got, got1, got2, err := ParseNetworkFlag(tt.args) + if tt.err != "" { + assert.EqualError(t, err, tt.err, tt.name) + } else { + assert.NoError(t, err, tt.name) + } + + assert.Equal(t, tt.nsmode, got, tt.name) + assert.Equal(t, tt.networks, got1, tt.name) + assert.Equal(t, tt.options, got2, tt.name) + }) + } +} |