github.com/containers/podman/v2@v2.2.2-0.20210501105131-c1e07d070c4c/test/e2e/network_create_test.go (about) 1 package integration 2 3 import ( 4 "encoding/json" 5 "io/ioutil" 6 "net" 7 "os" 8 "strings" 9 10 cniversion "github.com/containernetworking/cni/pkg/version" 11 "github.com/containers/podman/v2/libpod/network" 12 . "github.com/containers/podman/v2/test/utils" 13 . "github.com/onsi/ginkgo" 14 . "github.com/onsi/gomega" 15 "github.com/pkg/errors" 16 ) 17 18 var ErrPluginNotFound = errors.New("plugin not found") 19 20 func findPluginByName(plugins interface{}, pluginType string) (interface{}, error) { 21 for _, p := range plugins.([]interface{}) { 22 r := p.(map[string]interface{}) 23 if pluginType == r["type"] { 24 return p, nil 25 } 26 } 27 return nil, errors.Wrap(ErrPluginNotFound, pluginType) 28 } 29 30 func genericPluginsToBridge(plugins interface{}, pluginType string) (network.HostLocalBridge, error) { 31 var bridge network.HostLocalBridge 32 generic, err := findPluginByName(plugins, pluginType) 33 if err != nil { 34 return bridge, err 35 } 36 b, err := json.Marshal(generic) 37 if err != nil { 38 return bridge, err 39 } 40 err = json.Unmarshal(b, &bridge) 41 return bridge, err 42 } 43 44 func genericPluginsToPortMap(plugins interface{}, pluginType string) (network.PortMapConfig, error) { 45 var portMap network.PortMapConfig 46 generic, err := findPluginByName(plugins, "portmap") 47 if err != nil { 48 return portMap, err 49 } 50 b, err := json.Marshal(generic) 51 if err != nil { 52 return portMap, err 53 } 54 err = json.Unmarshal(b, &portMap) 55 return portMap, err 56 } 57 58 func (p *PodmanTestIntegration) removeCNINetwork(name string) { 59 session := p.Podman([]string{"network", "rm", "-f", name}) 60 session.WaitWithDefaultTimeout() 61 Expect(session.ExitCode()).To(BeNumerically("<=", 1)) 62 } 63 64 func removeNetworkDevice(name string) { 65 session := SystemExec("ip", []string{"link", "delete", name}) 66 session.WaitWithDefaultTimeout() 67 } 68 69 var _ = Describe("Podman network create", func() { 70 var ( 71 tempdir string 72 err error 73 podmanTest *PodmanTestIntegration 74 ) 75 76 BeforeEach(func() { 77 SkipIfRootless("rootless CNI is tech preview in RHEL 8.3.1") 78 tempdir, err = CreateTempDirInTempDir() 79 if err != nil { 80 os.Exit(1) 81 } 82 podmanTest = PodmanTestCreate(tempdir) 83 podmanTest.Setup() 84 podmanTest.SeedImages() 85 }) 86 87 AfterEach(func() { 88 podmanTest.Cleanup() 89 f := CurrentGinkgoTestDescription() 90 processTestResult(f) 91 }) 92 93 It("podman network create with no input", func() { 94 var result network.NcList 95 96 nc := podmanTest.Podman([]string{"network", "create"}) 97 nc.WaitWithDefaultTimeout() 98 Expect(nc.ExitCode()).To(BeZero()) 99 100 fileContent, err := ioutil.ReadFile(nc.OutputToString()) 101 Expect(err).To(BeNil()) 102 err = json.Unmarshal(fileContent, &result) 103 Expect(err).To(BeNil()) 104 defer podmanTest.removeCNINetwork(result["name"].(string)) 105 Expect(result["cniVersion"]).To(Equal(cniversion.Current())) 106 Expect(strings.HasPrefix(result["name"].(string), "cni-podman")).To(BeTrue()) 107 108 bridgePlugin, err := genericPluginsToBridge(result["plugins"], "bridge") 109 Expect(err).To(BeNil()) 110 portMapPlugin, err := genericPluginsToPortMap(result["plugins"], "portmap") 111 Expect(err).To(BeNil()) 112 113 Expect(bridgePlugin.IPAM.Routes[0].Dest).To(Equal("0.0.0.0/0")) 114 Expect(bridgePlugin.IsGW).To(BeTrue()) 115 Expect(bridgePlugin.IPMasq).To(BeTrue()) 116 Expect(portMapPlugin.Capabilities["portMappings"]).To(BeTrue()) 117 118 }) 119 120 It("podman network create with name", func() { 121 var ( 122 results []network.NcList 123 ) 124 125 nc := podmanTest.Podman([]string{"network", "create", "newname"}) 126 nc.WaitWithDefaultTimeout() 127 Expect(nc.ExitCode()).To(BeZero()) 128 defer podmanTest.removeCNINetwork("newname") 129 130 inspect := podmanTest.Podman([]string{"network", "inspect", "newname"}) 131 inspect.WaitWithDefaultTimeout() 132 133 err := json.Unmarshal([]byte(inspect.OutputToString()), &results) 134 Expect(err).To(BeNil()) 135 result := results[0] 136 Expect(result["name"]).To(Equal("newname")) 137 138 }) 139 140 It("podman network create with name and subnet", func() { 141 var ( 142 results []network.NcList 143 ) 144 nc := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.12.0/24", "newnetwork"}) 145 nc.WaitWithDefaultTimeout() 146 Expect(nc.ExitCode()).To(BeZero()) 147 148 defer podmanTest.removeCNINetwork("newnetwork") 149 150 // Inspect the network configuration 151 inspect := podmanTest.Podman([]string{"network", "inspect", "newnetwork"}) 152 inspect.WaitWithDefaultTimeout() 153 154 // JSON the network configuration into something usable 155 err := json.Unmarshal([]byte(inspect.OutputToString()), &results) 156 Expect(err).To(BeNil()) 157 result := results[0] 158 Expect(result["name"]).To(Equal("newnetwork")) 159 160 // JSON the bridge info 161 bridgePlugin, err := genericPluginsToBridge(result["plugins"], "bridge") 162 Expect(err).To(BeNil()) 163 164 // Once a container executes a new network, the nic will be created. We should clean those up 165 // best we can 166 defer removeNetworkDevice(bridgePlugin.BrName) 167 168 try := podmanTest.Podman([]string{"run", "-it", "--rm", "--network", "newnetwork", ALPINE, "sh", "-c", "ip addr show eth0 | awk ' /inet / {print $2}'"}) 169 try.WaitWithDefaultTimeout() 170 171 _, subnet, err := net.ParseCIDR("10.11.12.0/24") 172 Expect(err).To(BeNil()) 173 // Note this is an IPv4 test only! 174 containerIP, _, err := net.ParseCIDR(try.OutputToString()) 175 Expect(err).To(BeNil()) 176 // Ensure that the IP the container got is within the subnet the user asked for 177 Expect(subnet.Contains(containerIP)).To(BeTrue()) 178 }) 179 180 It("podman network create with name and IPv6 subnet", func() { 181 SkipIfRootless("FIXME It needs the ip6tables modules loaded") 182 var ( 183 results []network.NcList 184 ) 185 nc := podmanTest.Podman([]string{"network", "create", "--subnet", "fd00:1:2:3:4::/64", "newIPv6network"}) 186 nc.WaitWithDefaultTimeout() 187 Expect(nc.ExitCode()).To(BeZero()) 188 189 defer podmanTest.removeCNINetwork("newIPv6network") 190 191 // Inspect the network configuration 192 inspect := podmanTest.Podman([]string{"network", "inspect", "newIPv6network"}) 193 inspect.WaitWithDefaultTimeout() 194 195 // JSON the network configuration into something usable 196 err := json.Unmarshal([]byte(inspect.OutputToString()), &results) 197 Expect(err).To(BeNil()) 198 result := results[0] 199 Expect(result["name"]).To(Equal("newIPv6network")) 200 201 // JSON the bridge info 202 bridgePlugin, err := genericPluginsToBridge(result["plugins"], "bridge") 203 Expect(err).To(BeNil()) 204 Expect(bridgePlugin.IPAM.Routes[0].Dest).To(Equal("::/0")) 205 206 // Once a container executes a new network, the nic will be created. We should clean those up 207 // best we can 208 defer removeNetworkDevice(bridgePlugin.BrName) 209 210 try := podmanTest.Podman([]string{"run", "-it", "--rm", "--network", "newIPv6network", ALPINE, "sh", "-c", "ip addr show eth0 | grep global | awk ' /inet6 / {print $2}'"}) 211 try.WaitWithDefaultTimeout() 212 213 _, subnet, err := net.ParseCIDR("fd00:1:2:3:4::/64") 214 Expect(err).To(BeNil()) 215 containerIP, _, err := net.ParseCIDR(try.OutputToString()) 216 Expect(err).To(BeNil()) 217 // Ensure that the IP the container got is within the subnet the user asked for 218 Expect(subnet.Contains(containerIP)).To(BeTrue()) 219 }) 220 221 It("podman network create with name and IPv6 flag (dual-stack)", func() { 222 SkipIfRootless("FIXME It needs the ip6tables modules loaded") 223 var ( 224 results []network.NcList 225 ) 226 nc := podmanTest.Podman([]string{"network", "create", "--subnet", "fd00:4:3:2:1::/64", "--ipv6", "newDualStacknetwork"}) 227 nc.WaitWithDefaultTimeout() 228 Expect(nc.ExitCode()).To(BeZero()) 229 230 defer podmanTest.removeCNINetwork("newDualStacknetwork") 231 232 // Inspect the network configuration 233 inspect := podmanTest.Podman([]string{"network", "inspect", "newDualStacknetwork"}) 234 inspect.WaitWithDefaultTimeout() 235 236 // JSON the network configuration into something usable 237 err := json.Unmarshal([]byte(inspect.OutputToString()), &results) 238 Expect(err).To(BeNil()) 239 result := results[0] 240 Expect(result["name"]).To(Equal("newDualStacknetwork")) 241 242 // JSON the bridge info 243 bridgePlugin, err := genericPluginsToBridge(result["plugins"], "bridge") 244 Expect(err).To(BeNil()) 245 Expect(bridgePlugin.IPAM.Routes[0].Dest).To(Equal("::/0")) 246 Expect(bridgePlugin.IPAM.Routes[1].Dest).To(Equal("0.0.0.0/0")) 247 248 // Once a container executes a new network, the nic will be created. We should clean those up 249 // best we can 250 defer removeNetworkDevice(bridgePlugin.BrName) 251 252 try := podmanTest.Podman([]string{"run", "-it", "--rm", "--network", "newDualStacknetwork", ALPINE, "sh", "-c", "ip addr show eth0 | grep global | awk ' /inet6 / {print $2}'"}) 253 try.WaitWithDefaultTimeout() 254 255 _, subnet, err := net.ParseCIDR("fd00:4:3:2:1::/64") 256 Expect(err).To(BeNil()) 257 containerIP, _, err := net.ParseCIDR(try.OutputToString()) 258 Expect(err).To(BeNil()) 259 // Ensure that the IP the container got is within the subnet the user asked for 260 Expect(subnet.Contains(containerIP)).To(BeTrue()) 261 // verify the container has an IPv4 address too (the IPv4 subnet is autogenerated) 262 try = podmanTest.Podman([]string{"run", "-it", "--rm", "--network", "newDualStacknetwork", ALPINE, "sh", "-c", "ip addr show eth0 | awk ' /inet / {print $2}'"}) 263 try.WaitWithDefaultTimeout() 264 containerIP, _, err = net.ParseCIDR(try.OutputToString()) 265 Expect(err).To(BeNil()) 266 Expect(containerIP.To4()).To(Not(BeNil())) 267 }) 268 269 It("podman network create with invalid subnet", func() { 270 nc := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.12.0/17000", "fail"}) 271 nc.WaitWithDefaultTimeout() 272 Expect(nc).To(ExitWithError()) 273 }) 274 275 It("podman network create with ipv4 subnet and ipv6 flag", func() { 276 nc := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.12.0/24", "--ipv6", "fail"}) 277 nc.WaitWithDefaultTimeout() 278 Expect(nc).To(ExitWithError()) 279 }) 280 281 It("podman network create with empty subnet and ipv6 flag", func() { 282 nc := podmanTest.Podman([]string{"network", "create", "--ipv6", "fail"}) 283 nc.WaitWithDefaultTimeout() 284 Expect(nc).To(ExitWithError()) 285 }) 286 287 It("podman network create with invalid IP", func() { 288 nc := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.0/17000", "fail"}) 289 nc.WaitWithDefaultTimeout() 290 Expect(nc).To(ExitWithError()) 291 }) 292 293 It("podman network create with invalid gateway for subnet", func() { 294 nc := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.12.0/24", "--gateway", "192.168.1.1", "fail"}) 295 nc.WaitWithDefaultTimeout() 296 Expect(nc).To(ExitWithError()) 297 }) 298 299 It("podman network create two networks with same name should fail", func() { 300 nc := podmanTest.Podman([]string{"network", "create", "samename"}) 301 nc.WaitWithDefaultTimeout() 302 Expect(nc.ExitCode()).To(BeZero()) 303 defer podmanTest.removeCNINetwork("samename") 304 305 ncFail := podmanTest.Podman([]string{"network", "create", "samename"}) 306 ncFail.WaitWithDefaultTimeout() 307 Expect(ncFail).To(ExitWithError()) 308 }) 309 310 It("podman network create two networks with same subnet should fail", func() { 311 nc := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.13.0/24", "subnet1"}) 312 nc.WaitWithDefaultTimeout() 313 Expect(nc.ExitCode()).To(BeZero()) 314 defer podmanTest.removeCNINetwork("subnet1") 315 316 ncFail := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.13.0/24", "subnet2"}) 317 ncFail.WaitWithDefaultTimeout() 318 Expect(ncFail).To(ExitWithError()) 319 }) 320 321 It("podman network create two IPv6 networks with same subnet should fail", func() { 322 SkipIfRootless("FIXME It needs the ip6tables modules loaded") 323 nc := podmanTest.Podman([]string{"network", "create", "--subnet", "fd00:4:4:4:4::/64", "--ipv6", "subnet1v6"}) 324 nc.WaitWithDefaultTimeout() 325 Expect(nc.ExitCode()).To(BeZero()) 326 defer podmanTest.removeCNINetwork("subnet1v6") 327 328 ncFail := podmanTest.Podman([]string{"network", "create", "--subnet", "fd00:4:4:4:4::/64", "--ipv6", "subnet2v6"}) 329 ncFail.WaitWithDefaultTimeout() 330 Expect(ncFail).To(ExitWithError()) 331 }) 332 333 It("podman network create with invalid network name", func() { 334 nc := podmanTest.Podman([]string{"network", "create", "foo "}) 335 nc.WaitWithDefaultTimeout() 336 Expect(nc).To(ExitWithError()) 337 }) 338 339 })