Example #1
0
func (*NetworkSuite) TestGenerateNetworkConfig(c *gc.C) {
	for _, test := range []struct {
		config *container.NetworkConfig
		net    string
		link   string
	}{{
		config: nil,
		net:    "veth",
		link:   "lxcbr0",
	}, {
		config: lxc.DefaultNetworkConfig(),
		net:    "veth",
		link:   "lxcbr0",
	}, {
		config: container.BridgeNetworkConfig("foo"),
		net:    "veth",
		link:   "foo",
	}, {
		config: container.PhysicalNetworkConfig("foo"),
		net:    "phys",
		link:   "foo",
	}} {
		config := lxc.GenerateNetworkConfig(test.config)
		c.Assert(config, jc.Contains, fmt.Sprintf("lxc.network.type = %s\n", test.net))
		c.Assert(config, jc.Contains, fmt.Sprintf("lxc.network.link = %s\n", test.link))
	}
}
Example #2
0
func (*NetworkSuite) TestGenerateNetworkConfig(c *gc.C) {
	dhcpNIC := network.InterfaceInfo{
		DeviceIndex:   0,
		MACAddress:    "aa:bb:cc:dd:ee:f0",
		InterfaceName: "eth0",
		// The following is not part of the LXC config, but cause the
		// generated cloud-init user-data to change accordingly.
		ConfigType: network.ConfigDHCP,
	}
	staticNIC := network.InterfaceInfo{
		DeviceIndex:    1,
		CIDR:           "0.1.2.0/20", // used to infer the subnet mask.
		MACAddress:     "aa:bb:cc:dd:ee:f1",
		InterfaceName:  "eth1",
		Address:        network.NewAddress("0.1.2.3"),
		GatewayAddress: network.NewAddress("0.1.2.1"),
		// The rest is passed to cloud-init.
		ConfigType: network.ConfigStatic,
		DNSServers: network.NewAddresses("ns1.invalid", "ns2.invalid"),
	}
	extraConfigNIC := network.InterfaceInfo{
		DeviceIndex:   2,
		MACAddress:    "aa:bb:cc:dd:ee:f2",
		InterfaceName: "eth2",
		VLANTag:       42,
		NoAutoStart:   true,
		// The rest is passed to cloud-init.
		ConfigType: network.ConfigManual,
		DNSServers: network.NewAddresses("ns1.invalid", "ns2.invalid"),
	}
	// Test /24 is used by default when the CIDR is invalid or empty.
	staticNICNoCIDR, staticNICBadCIDR := staticNIC, staticNIC
	staticNICNoCIDR.CIDR = ""
	staticNICBadCIDR.CIDR = "bad"
	// Test when NoAutoStart is true gateway is not added, even if there.
	staticNICNoAutoWithGW := staticNIC
	staticNICNoAutoWithGW.NoAutoStart = true

	var lastTestLog string
	allNICs := []network.InterfaceInfo{dhcpNIC, staticNIC, extraConfigNIC}
	for i, test := range []struct {
		about             string
		config            *container.NetworkConfig
		nics              []network.InterfaceInfo
		rendered          []string
		logContains       string
		logDoesNotContain string
	}{{
		about:  "empty config",
		config: nil,
		rendered: []string{
			"lxc.network.type = veth",
			"lxc.network.link = lxcbr0",
			"lxc.network.flags = up",
		},
		logContains:       `WARNING juju.container.lxc network type missing, using the default "bridge" config`,
		logDoesNotContain: `INFO juju.container.lxc setting MTU to 0 for LXC network interfaces`,
	}, {
		about:  "default config",
		config: lxc.DefaultNetworkConfig(),
		rendered: []string{
			"lxc.network.type = veth",
			"lxc.network.link = lxcbr0",
			"lxc.network.flags = up",
		},
		logDoesNotContain: `INFO juju.container.lxc setting MTU to 0 for LXC network interfaces`,
	}, {
		about:  "bridge config with MTU 1500, device foo, no NICs",
		config: container.BridgeNetworkConfig("foo", 1500, nil),
		rendered: []string{
			"lxc.network.type = veth",
			"lxc.network.link = foo",
			"lxc.network.flags = up",
			"lxc.network.mtu = 1500",
		},
	}, {
		about:  "phys config with MTU 9000, device foo, no NICs",
		config: container.PhysicalNetworkConfig("foo", 9000, nil),
		rendered: []string{
			"lxc.network.type = phys",
			"lxc.network.link = foo",
			"lxc.network.flags = up",
			"lxc.network.mtu = 9000",
		},
	}, {
		about:  "bridge config with MTU 8000, device foo, all NICs",
		config: container.BridgeNetworkConfig("foo", 8000, allNICs),
		nics:   allNICs,
		rendered: []string{
			"lxc.network.type = veth",
			"lxc.network.link = foo",
			"lxc.network.flags = up",
			"lxc.network.name = eth0",
			"lxc.network.hwaddr = aa:bb:cc:dd:ee:f0",

			"lxc.network.type = veth",
			"lxc.network.link = foo",
			"lxc.network.flags = up",
			"lxc.network.name = eth1",
			"lxc.network.hwaddr = aa:bb:cc:dd:ee:f1",
			"lxc.network.ipv4 = 0.1.2.3/20",

			"lxc.network.type = veth",
			"lxc.network.link = foo",
			"lxc.network.name = eth2",
			"lxc.network.hwaddr = aa:bb:cc:dd:ee:f2",
		},
	}, {
		about:  "bridge config with MTU 0, device foo, staticNICNoCIDR",
		config: container.BridgeNetworkConfig("foo", 0, []network.InterfaceInfo{staticNICNoCIDR}),
		nics:   []network.InterfaceInfo{staticNICNoCIDR},
		rendered: []string{
			"lxc.network.type = veth",
			"lxc.network.link = foo",
			"lxc.network.flags = up",
			"lxc.network.name = eth1",
			"lxc.network.hwaddr = aa:bb:cc:dd:ee:f1",
		},
		logDoesNotContain: `INFO juju.container.lxc setting MTU to 0 for all LXC network interfaces`,
	}, {
		about:  "bridge config with MTU 0, device foo, staticNICBadCIDR",
		config: container.BridgeNetworkConfig("foo", 0, []network.InterfaceInfo{staticNICBadCIDR}),
		nics:   []network.InterfaceInfo{staticNICBadCIDR},
		rendered: []string{
			"lxc.network.type = veth",
			"lxc.network.link = foo",
			"lxc.network.flags = up",
			"lxc.network.name = eth1",
			"lxc.network.hwaddr = aa:bb:cc:dd:ee:f1",
			"lxc.network.ipv4 = invalid CIDR address: bad",
		},
	}, {
		about:  "bridge config with MTU 0, device foo, staticNICNoAutoWithGW",
		config: container.BridgeNetworkConfig("foo", 0, []network.InterfaceInfo{staticNICNoAutoWithGW}),
		nics:   []network.InterfaceInfo{staticNICNoAutoWithGW},
		rendered: []string{
			"lxc.network.type = veth",
			"lxc.network.link = foo",
			"lxc.network.name = eth1",
			"lxc.network.hwaddr = aa:bb:cc:dd:ee:f1",
			"lxc.network.ipv4 = 0.1.2.3/20",
		},
	}} {
		c.Logf("test #%d: %s", i, test.about)
		config := lxc.GenerateNetworkConfig(test.config)
		// Parse the config to drop comments and empty lines. This is
		// needed to ensure the order of all settings match what we
		// expect to get rendered, as the order matters.
		var configLines []string
		for _, line := range strings.Split(config, "\n") {
			line = strings.TrimSpace(line)
			if line == "" || strings.HasPrefix(line, "#") {
				continue
			}
			configLines = append(configLines, line)
		}
		currentLog := strings.TrimPrefix(c.GetTestLog(), lastTestLog)
		c.Check(configLines, jc.DeepEquals, test.rendered)
		if test.logContains != "" {
			c.Check(currentLog, jc.Contains, test.logContains)
		}
		if test.logDoesNotContain != "" {
			c.Check(currentLog, gc.Not(jc.Contains), test.logDoesNotContain)
		}
		// TODO(dimitern) In a follow-up, test the generated user-data
		// honors the other settings.
		lastTestLog = c.GetTestLog()
	}
}