github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/test/e2e/network_create_test.go (about) 1 package integration 2 3 import ( 4 "encoding/json" 5 "net" 6 "os" 7 8 "github.com/containers/common/libnetwork/types" 9 . "github.com/hanks177/podman/v4/test/utils" 10 "github.com/containers/storage/pkg/stringid" 11 . "github.com/onsi/ginkgo" 12 . "github.com/onsi/gomega" 13 . "github.com/onsi/gomega/gexec" 14 ) 15 16 func removeNetworkDevice(name string) { 17 session := SystemExec("ip", []string{"link", "delete", name}) 18 session.WaitWithDefaultTimeout() 19 } 20 21 var _ = Describe("Podman network create", func() { 22 var ( 23 tempdir string 24 err error 25 podmanTest *PodmanTestIntegration 26 ) 27 28 BeforeEach(func() { 29 tempdir, err = CreateTempDirInTempDir() 30 if err != nil { 31 os.Exit(1) 32 } 33 podmanTest = PodmanTestCreate(tempdir) 34 podmanTest.Setup() 35 }) 36 37 AfterEach(func() { 38 podmanTest.Cleanup() 39 f := CurrentGinkgoTestDescription() 40 processTestResult(f) 41 }) 42 43 It("podman network create with name and subnet", func() { 44 netName := "subnet-" + stringid.GenerateNonCryptoID() 45 nc := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.12.0/24", "--ip-range", "10.11.12.0/26", netName}) 46 nc.WaitWithDefaultTimeout() 47 defer podmanTest.removeNetwork(netName) 48 Expect(nc).Should(Exit(0)) 49 50 // Inspect the network configuration 51 inspect := podmanTest.Podman([]string{"network", "inspect", netName}) 52 inspect.WaitWithDefaultTimeout() 53 Expect(inspect).Should(Exit(0)) 54 55 // JSON the network configuration into something usable 56 var results []types.Network 57 err := json.Unmarshal([]byte(inspect.OutputToString()), &results) 58 Expect(err).To(BeNil()) 59 Expect(results).To(HaveLen(1)) 60 result := results[0] 61 Expect(result).To(HaveField("Name", netName)) 62 Expect(result.Subnets).To(HaveLen(1)) 63 Expect(result.Subnets[0].Subnet.String()).To(Equal("10.11.12.0/24")) 64 Expect(result.Subnets[0].Gateway.String()).To(Equal("10.11.12.1")) 65 Expect(result.Subnets[0].LeaseRange).ToNot(BeNil()) 66 Expect(result.Subnets[0].LeaseRange.StartIP.String()).To(Equal("10.11.12.1")) 67 Expect(result.Subnets[0].LeaseRange.EndIP.String()).To(Equal("10.11.12.63")) 68 69 // Once a container executes a new network, the nic will be created. We should clean those up 70 // best we can 71 defer removeNetworkDevice(result.NetworkInterface) 72 73 try := podmanTest.Podman([]string{"run", "-it", "--rm", "--network", netName, ALPINE, "sh", "-c", "ip addr show eth0 | awk ' /inet / {print $2}'"}) 74 try.WaitWithDefaultTimeout() 75 Expect(try).To(Exit(0)) 76 77 _, subnet, err := net.ParseCIDR("10.11.12.0/24") 78 Expect(err).To(BeNil()) 79 // Note this is an IPv4 test only! 80 containerIP, _, err := net.ParseCIDR(try.OutputToString()) 81 Expect(err).To(BeNil()) 82 // Ensure that the IP the container got is within the subnet the user asked for 83 Expect(subnet.Contains(containerIP)).To(BeTrue()) 84 }) 85 86 It("podman network create with name and IPv6 subnet", func() { 87 netName := "ipv6-" + stringid.GenerateNonCryptoID() 88 nc := podmanTest.Podman([]string{"network", "create", "--subnet", "fd00:1:2:3:4::/64", netName}) 89 nc.WaitWithDefaultTimeout() 90 defer podmanTest.removeNetwork(netName) 91 Expect(nc).Should(Exit(0)) 92 93 // Inspect the network configuration 94 inspect := podmanTest.Podman([]string{"network", "inspect", netName}) 95 inspect.WaitWithDefaultTimeout() 96 Expect(inspect).Should(Exit(0)) 97 98 // JSON the network configuration into something usable 99 var results []types.Network 100 err := json.Unmarshal([]byte(inspect.OutputToString()), &results) 101 Expect(err).To(BeNil()) 102 Expect(results).To(HaveLen(1)) 103 result := results[0] 104 Expect(result).To(HaveField("Name", netName)) 105 Expect(result.Subnets).To(HaveLen(1)) 106 Expect(result.Subnets[0].Gateway.String()).To(Equal("fd00:1:2:3::1")) 107 Expect(result.Subnets[0].Subnet.String()).To(Equal("fd00:1:2:3::/64")) 108 109 // Once a container executes a new network, the nic will be created. We should clean those up 110 // best we can 111 defer removeNetworkDevice(result.NetworkInterface) 112 113 try := podmanTest.Podman([]string{"run", "-it", "--rm", "--network", netName, ALPINE, "sh", "-c", "ip addr show eth0 | grep global | awk ' /inet6 / {print $2}'"}) 114 try.WaitWithDefaultTimeout() 115 Expect(try).To(Exit(0)) 116 117 _, subnet, err := net.ParseCIDR("fd00:1:2:3:4::/64") 118 Expect(err).To(BeNil()) 119 containerIP, _, err := net.ParseCIDR(try.OutputToString()) 120 Expect(err).To(BeNil()) 121 // Ensure that the IP the container got is within the subnet the user asked for 122 Expect(subnet.Contains(containerIP)).To(BeTrue()) 123 }) 124 125 It("podman network create with name and IPv6 flag (dual-stack)", func() { 126 netName := "dual-" + stringid.GenerateNonCryptoID() 127 nc := podmanTest.Podman([]string{"network", "create", "--subnet", "fd00:4:3:2::/64", "--ipv6", netName}) 128 nc.WaitWithDefaultTimeout() 129 defer podmanTest.removeNetwork(netName) 130 Expect(nc).Should(Exit(0)) 131 132 // Inspect the network configuration 133 inspect := podmanTest.Podman([]string{"network", "inspect", netName}) 134 inspect.WaitWithDefaultTimeout() 135 Expect(inspect).Should(Exit(0)) 136 137 // JSON the network configuration into something usable 138 var results []types.Network 139 err := json.Unmarshal([]byte(inspect.OutputToString()), &results) 140 Expect(err).To(BeNil()) 141 Expect(results).To(HaveLen(1)) 142 result := results[0] 143 Expect(result).To(HaveField("Name", netName)) 144 Expect(result.Subnets).To(HaveLen(2)) 145 Expect(result.Subnets[0].Subnet.IP).ToNot(BeNil()) 146 Expect(result.Subnets[1].Subnet.IP).ToNot(BeNil()) 147 148 _, subnet11, err := net.ParseCIDR(result.Subnets[0].Subnet.String()) 149 Expect(err).To(BeNil()) 150 _, subnet12, err := net.ParseCIDR(result.Subnets[1].Subnet.String()) 151 Expect(err).To(BeNil()) 152 153 // Once a container executes a new network, the nic will be created. We should clean those up 154 // best we can 155 defer removeNetworkDevice(result.NetworkInterface) 156 157 // create a second network to check the auto assigned ipv4 subnet does not overlap 158 // https://github.com/containers/podman/issues/11032 159 netName2 := "dual-" + stringid.GenerateNonCryptoID() 160 nc = podmanTest.Podman([]string{"network", "create", "--subnet", "fd00:10:3:2::/64", "--ipv6", netName2}) 161 nc.WaitWithDefaultTimeout() 162 defer podmanTest.removeNetwork(netName2) 163 Expect(nc).Should(Exit(0)) 164 165 // Inspect the network configuration 166 inspect = podmanTest.Podman([]string{"network", "inspect", netName2}) 167 inspect.WaitWithDefaultTimeout() 168 Expect(inspect).Should(Exit(0)) 169 170 // JSON the network configuration into something usable 171 err = json.Unmarshal([]byte(inspect.OutputToString()), &results) 172 Expect(err).To(BeNil()) 173 Expect(results).To(HaveLen(1)) 174 result = results[0] 175 Expect(result).To(HaveField("Name", netName2)) 176 Expect(result.Subnets).To(HaveLen(2)) 177 Expect(result.Subnets[0].Subnet.IP).ToNot(BeNil()) 178 Expect(result.Subnets[1].Subnet.IP).ToNot(BeNil()) 179 180 _, subnet21, err := net.ParseCIDR(result.Subnets[0].Subnet.String()) 181 Expect(err).To(BeNil()) 182 _, subnet22, err := net.ParseCIDR(result.Subnets[1].Subnet.String()) 183 Expect(err).To(BeNil()) 184 185 // check that the subnets do not overlap 186 Expect(subnet11.Contains(subnet21.IP)).To(BeFalse()) 187 Expect(subnet12.Contains(subnet22.IP)).To(BeFalse()) 188 189 try := podmanTest.Podman([]string{"run", "-it", "--rm", "--network", netName, ALPINE, "sh", "-c", "ip addr show eth0 | grep global | awk ' /inet6 / {print $2}'"}) 190 try.WaitWithDefaultTimeout() 191 192 _, subnet, err := net.ParseCIDR("fd00:4:3:2:1::/64") 193 Expect(err).To(BeNil()) 194 containerIP, _, err := net.ParseCIDR(try.OutputToString()) 195 Expect(err).To(BeNil()) 196 // Ensure that the IP the container got is within the subnet the user asked for 197 Expect(subnet.Contains(containerIP)).To(BeTrue()) 198 // verify the container has an IPv4 address too (the IPv4 subnet is autogenerated) 199 try = podmanTest.Podman([]string{"run", "-it", "--rm", "--network", netName, ALPINE, "sh", "-c", "ip addr show eth0 | awk ' /inet / {print $2}'"}) 200 try.WaitWithDefaultTimeout() 201 containerIP, _, err = net.ParseCIDR(try.OutputToString()) 202 Expect(err).To(BeNil()) 203 Expect(containerIP.To4()).To(Not(BeNil())) 204 }) 205 206 It("podman network create with invalid subnet", func() { 207 nc := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.12.0/17000", stringid.GenerateNonCryptoID()}) 208 nc.WaitWithDefaultTimeout() 209 Expect(nc).To(ExitWithError()) 210 }) 211 212 It("podman network create with ipv4 subnet and ipv6 flag", func() { 213 name := stringid.GenerateNonCryptoID() 214 nc := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.12.0/24", "--ipv6", name}) 215 nc.WaitWithDefaultTimeout() 216 Expect(nc).To(Exit(0)) 217 defer podmanTest.removeNetwork(name) 218 219 nc = podmanTest.Podman([]string{"network", "inspect", name}) 220 nc.WaitWithDefaultTimeout() 221 Expect(nc).To(Exit(0)) 222 Expect(nc.OutputToString()).To(ContainSubstring(`::/64`)) 223 Expect(nc.OutputToString()).To(ContainSubstring(`10.11.12.0/24`)) 224 }) 225 226 It("podman network create with empty subnet and ipv6 flag", func() { 227 name := stringid.GenerateNonCryptoID() 228 nc := podmanTest.Podman([]string{"network", "create", "--ipv6", name}) 229 nc.WaitWithDefaultTimeout() 230 Expect(nc).To(Exit(0)) 231 defer podmanTest.removeNetwork(name) 232 233 nc = podmanTest.Podman([]string{"network", "inspect", name}) 234 nc.WaitWithDefaultTimeout() 235 Expect(nc).To(Exit(0)) 236 Expect(nc.OutputToString()).To(ContainSubstring(`::/64`)) 237 Expect(nc.OutputToString()).To(ContainSubstring(`.0/24`)) 238 }) 239 240 It("podman network create with invalid IP", func() { 241 nc := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.0/17000", stringid.GenerateNonCryptoID()}) 242 nc.WaitWithDefaultTimeout() 243 Expect(nc).To(ExitWithError()) 244 }) 245 246 It("podman network create with invalid gateway for subnet", func() { 247 nc := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.12.0/24", "--gateway", "192.168.1.1", stringid.GenerateNonCryptoID()}) 248 nc.WaitWithDefaultTimeout() 249 Expect(nc).To(ExitWithError()) 250 }) 251 252 It("podman network create two networks with same name should fail", func() { 253 netName := "same-" + stringid.GenerateNonCryptoID() 254 nc := podmanTest.Podman([]string{"network", "create", netName}) 255 nc.WaitWithDefaultTimeout() 256 defer podmanTest.removeNetwork(netName) 257 Expect(nc).Should(Exit(0)) 258 259 ncFail := podmanTest.Podman([]string{"network", "create", netName}) 260 ncFail.WaitWithDefaultTimeout() 261 Expect(ncFail).To(ExitWithError()) 262 }) 263 264 It("podman network create two networks with same subnet should fail", func() { 265 netName1 := "sub1-" + stringid.GenerateNonCryptoID() 266 nc := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.13.0/24", netName1}) 267 nc.WaitWithDefaultTimeout() 268 defer podmanTest.removeNetwork(netName1) 269 Expect(nc).Should(Exit(0)) 270 271 netName2 := "sub2-" + stringid.GenerateNonCryptoID() 272 ncFail := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.13.0/24", netName2}) 273 ncFail.WaitWithDefaultTimeout() 274 defer podmanTest.removeNetwork(netName2) 275 Expect(ncFail).To(ExitWithError()) 276 }) 277 278 It("podman network create two IPv6 networks with same subnet should fail", func() { 279 netName1 := "subipv61-" + stringid.GenerateNonCryptoID() 280 nc := podmanTest.Podman([]string{"network", "create", "--subnet", "fd00:4:4:4:4::/64", "--ipv6", netName1}) 281 nc.WaitWithDefaultTimeout() 282 defer podmanTest.removeNetwork(netName1) 283 Expect(nc).Should(Exit(0)) 284 285 netName2 := "subipv62-" + stringid.GenerateNonCryptoID() 286 ncFail := podmanTest.Podman([]string{"network", "create", "--subnet", "fd00:4:4:4:4::/64", "--ipv6", netName2}) 287 ncFail.WaitWithDefaultTimeout() 288 defer podmanTest.removeNetwork(netName2) 289 Expect(ncFail).To(ExitWithError()) 290 }) 291 292 It("podman network create with invalid network name", func() { 293 nc := podmanTest.Podman([]string{"network", "create", "foo "}) 294 nc.WaitWithDefaultTimeout() 295 Expect(nc).To(ExitWithError()) 296 }) 297 298 It("podman network create with mtu option", func() { 299 net := "mtu-test" + stringid.GenerateNonCryptoID() 300 nc := podmanTest.Podman([]string{"network", "create", "--opt", "mtu=9000", net}) 301 nc.WaitWithDefaultTimeout() 302 defer podmanTest.removeNetwork(net) 303 Expect(nc).Should(Exit(0)) 304 305 nc = podmanTest.Podman([]string{"network", "inspect", net}) 306 nc.WaitWithDefaultTimeout() 307 Expect(nc).Should(Exit(0)) 308 Expect(nc.OutputToString()).To(ContainSubstring(`"mtu": "9000"`)) 309 }) 310 311 It("podman network create with vlan option", func() { 312 net := "vlan-test" + stringid.GenerateNonCryptoID() 313 nc := podmanTest.Podman([]string{"network", "create", "--opt", "vlan=9", net}) 314 nc.WaitWithDefaultTimeout() 315 defer podmanTest.removeNetwork(net) 316 Expect(nc).Should(Exit(0)) 317 318 nc = podmanTest.Podman([]string{"network", "inspect", net}) 319 nc.WaitWithDefaultTimeout() 320 Expect(nc).Should(Exit(0)) 321 Expect(nc.OutputToString()).To(ContainSubstring(`"vlan": "9"`)) 322 }) 323 324 It("podman network create with invalid option", func() { 325 net := "invalid-test" + stringid.GenerateNonCryptoID() 326 nc := podmanTest.Podman([]string{"network", "create", "--opt", "foo=bar", net}) 327 nc.WaitWithDefaultTimeout() 328 defer podmanTest.removeNetwork(net) 329 Expect(nc).To(ExitWithError()) 330 }) 331 332 It("podman CNI network create with internal should not have dnsname", func() { 333 SkipIfNetavark(podmanTest) 334 net := "internal-test" + stringid.GenerateNonCryptoID() 335 nc := podmanTest.Podman([]string{"network", "create", "--internal", net}) 336 nc.WaitWithDefaultTimeout() 337 defer podmanTest.removeNetwork(net) 338 Expect(nc).Should(Exit(0)) 339 // Not performing this check on remote tests because it is a logrus error which does 340 // not come back via stderr on the remote client. 341 if !IsRemote() { 342 Expect(nc.ErrorToString()).To(ContainSubstring("dnsname and internal networks are incompatible")) 343 } 344 nc = podmanTest.Podman([]string{"network", "inspect", net}) 345 nc.WaitWithDefaultTimeout() 346 Expect(nc).Should(Exit(0)) 347 Expect(nc.OutputToString()).ToNot(ContainSubstring("dnsname")) 348 }) 349 350 It("podman Netavark network create with internal should have dnsname", func() { 351 SkipIfCNI(podmanTest) 352 net := "internal-test" + stringid.GenerateNonCryptoID() 353 nc := podmanTest.Podman([]string{"network", "create", "--internal", net}) 354 nc.WaitWithDefaultTimeout() 355 defer podmanTest.removeNetwork(net) 356 Expect(nc).Should(Exit(0)) 357 // Not performing this check on remote tests because it is a logrus error which does 358 // not come back via stderr on the remote client. 359 if !IsRemote() { 360 Expect(nc.ErrorToString()).To(BeEmpty()) 361 } 362 nc = podmanTest.Podman([]string{"network", "inspect", net}) 363 nc.WaitWithDefaultTimeout() 364 Expect(nc).Should(Exit(0)) 365 Expect(nc.OutputToString()).To(ContainSubstring(`"dns_enabled": true`)) 366 }) 367 368 It("podman network create with invalid name", func() { 369 for _, name := range []string{"none", "host", "bridge", "private", "slirp4netns", "container", "ns"} { 370 nc := podmanTest.Podman([]string{"network", "create", name}) 371 nc.WaitWithDefaultTimeout() 372 Expect(nc).To(Exit(125)) 373 Expect(nc.ErrorToString()).To(ContainSubstring("cannot create network with name %q because it conflicts with a valid network mode", name)) 374 } 375 }) 376 377 It("podman network create with multiple subnets", func() { 378 name := "subnets-" + stringid.GenerateNonCryptoID() 379 subnet1 := "10.10.0.0/24" 380 subnet2 := "10.10.1.0/24" 381 nc := podmanTest.Podman([]string{"network", "create", "--subnet", subnet1, "--subnet", subnet2, name}) 382 nc.WaitWithDefaultTimeout() 383 defer podmanTest.removeNetwork(name) 384 Expect(nc).To(Exit(0)) 385 Expect(nc.OutputToString()).To(Equal(name)) 386 387 inspect := podmanTest.Podman([]string{"network", "inspect", name}) 388 inspect.WaitWithDefaultTimeout() 389 Expect(inspect).To(Exit(0)) 390 Expect(inspect.OutputToString()).To(ContainSubstring(`"subnet": "` + subnet1)) 391 Expect(inspect.OutputToString()).To(ContainSubstring(`"subnet": "` + subnet2)) 392 Expect(inspect.OutputToString()).To(ContainSubstring(`"ipv6_enabled": false`)) 393 }) 394 395 It("podman network create with multiple subnets dual stack", func() { 396 name := "subnets-" + stringid.GenerateNonCryptoID() 397 subnet1 := "10.10.2.0/24" 398 subnet2 := "fd52:2a5a:747e:3acd::/64" 399 nc := podmanTest.Podman([]string{"network", "create", "--subnet", subnet1, "--subnet", subnet2, name}) 400 nc.WaitWithDefaultTimeout() 401 defer podmanTest.removeNetwork(name) 402 Expect(nc).To(Exit(0)) 403 Expect(nc.OutputToString()).To(Equal(name)) 404 405 inspect := podmanTest.Podman([]string{"network", "inspect", name}) 406 inspect.WaitWithDefaultTimeout() 407 Expect(inspect).To(Exit(0)) 408 Expect(inspect.OutputToString()).To(ContainSubstring(`"subnet": "` + subnet1)) 409 Expect(inspect.OutputToString()).To(ContainSubstring(`"subnet": "` + subnet2)) 410 Expect(inspect.OutputToString()).To(ContainSubstring(`"ipv6_enabled": true`)) 411 }) 412 413 It("podman network create with multiple subnets dual stack with gateway and range", func() { 414 name := "subnets-" + stringid.GenerateNonCryptoID() 415 subnet1 := "10.10.3.0/24" 416 gw1 := "10.10.3.10" 417 range1 := "10.10.3.0/26" 418 subnet2 := "fd52:2a5a:747e:3ace::/64" 419 gw2 := "fd52:2a5a:747e:3ace::10" 420 nc := podmanTest.Podman([]string{"network", "create", "--subnet", subnet1, "--gateway", gw1, "--ip-range", range1, "--subnet", subnet2, "--gateway", gw2, name}) 421 nc.WaitWithDefaultTimeout() 422 defer podmanTest.removeNetwork(name) 423 Expect(nc).To(Exit(0)) 424 Expect(nc.OutputToString()).To(Equal(name)) 425 426 inspect := podmanTest.Podman([]string{"network", "inspect", name}) 427 inspect.WaitWithDefaultTimeout() 428 Expect(inspect).To(Exit(0)) 429 Expect(inspect.OutputToString()).To(ContainSubstring(`"subnet": "` + subnet1)) 430 Expect(inspect.OutputToString()).To(ContainSubstring(`"gateway": "` + gw1)) 431 Expect(inspect.OutputToString()).To(ContainSubstring(`"start_ip": "10.10.3.1",`)) 432 Expect(inspect.OutputToString()).To(ContainSubstring(`"end_ip": "10.10.3.63"`)) 433 Expect(inspect.OutputToString()).To(ContainSubstring(`"subnet": "` + subnet2)) 434 Expect(inspect.OutputToString()).To(ContainSubstring(`"gateway": "` + gw2)) 435 Expect(inspect.OutputToString()).To(ContainSubstring(`"ipv6_enabled": true`)) 436 }) 437 438 It("podman network create invalid options with multiple subnets", func() { 439 name := "subnets-" + stringid.GenerateNonCryptoID() 440 subnet1 := "10.10.3.0/24" 441 gw1 := "10.10.3.10" 442 gw2 := "fd52:2a5a:747e:3acf::10" 443 nc := podmanTest.Podman([]string{"network", "create", "--subnet", subnet1, "--gateway", gw1, "--gateway", gw2, name}) 444 nc.WaitWithDefaultTimeout() 445 Expect(nc).To(Exit(125)) 446 Expect(nc.ErrorToString()).To(Equal("Error: cannot set more gateways than subnets")) 447 448 range1 := "10.10.3.0/26" 449 range2 := "10.10.3.0/28" 450 nc = podmanTest.Podman([]string{"network", "create", "--subnet", subnet1, "--ip-range", range1, "--ip-range", range2, name}) 451 nc.WaitWithDefaultTimeout() 452 Expect(nc).To(Exit(125)) 453 Expect(nc.ErrorToString()).To(Equal("Error: cannot set more ranges than subnets")) 454 }) 455 })