summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nova/network/l3.py10
-rw-r--r--nova/network/manager.py23
-rw-r--r--nova/tests/network/test_manager.py201
3 files changed, 229 insertions, 5 deletions
diff --git a/nova/network/l3.py b/nova/network/l3.py
index 9ca6b6a43..7511f7ba4 100644
--- a/nova/network/l3.py
+++ b/nova/network/l3.py
@@ -79,7 +79,13 @@ class LinuxNetL3(L3Driver):
if self.initialized:
return
LOG.debug("Initializing linux_net L3 driver")
- linux_net.init_host()
+ fixed_range = kwargs.get('fixed_range', False)
+ networks = kwargs.get('networks', None)
+ if not fixed_range and networks is not None:
+ for network in networks:
+ self.initialize_network(network['cidr'])
+ else:
+ linux_net.init_host()
linux_net.ensure_metadata_ip()
linux_net.metadata_forward()
self.initialized = True
@@ -88,7 +94,7 @@ class LinuxNetL3(L3Driver):
return self.initialized
def initialize_network(self, cidr):
- linux_net.add_snat_rule(cidr)
+ linux_net.init_host(cidr)
def initialize_gateway(self, network_ref):
mac_address = utils.generate_mac_address()
diff --git a/nova/network/manager.py b/nova/network/manager.py
index 482744a8b..f1a3c45d2 100644
--- a/nova/network/manager.py
+++ b/nova/network/manager.py
@@ -106,9 +106,12 @@ network_opts = [
cfg.IntOpt('network_size',
default=256,
help='Number of addresses in each private subnet'),
+ # TODO(mathrock): Deprecate in Grizzly, remove in Havana
cfg.StrOpt('fixed_range',
default='10.0.0.0/8',
- help='Fixed IP address block'),
+ help='DEPRECATED - Fixed IP address block.'
+ 'If set to an empty string, the subnet range(s) will be '
+ 'automatically determined and configured.'),
cfg.StrOpt('fixed_range_v6',
default='fd00::/48',
help='Fixed IPv6 address block'),
@@ -1559,7 +1562,12 @@ class FlatDHCPManager(RPCAllocateFixedIP, floating_ips.FloatingIP,
"""Do any initialization that needs to be run if this is a
standalone service.
"""
- self.l3driver.initialize()
+ if not CONF.fixed_range:
+ ctxt = context.get_admin_context()
+ networks = self.db.network_get_all_by_host(ctxt, self.host)
+ self.l3driver.initialize(fixed_range=False, networks=networks)
+ else:
+ self.l3driver.initialize(fixed_range=CONF.fixed_range)
super(FlatDHCPManager, self).init_host()
self.init_host_floating_ips()
@@ -1567,6 +1575,8 @@ class FlatDHCPManager(RPCAllocateFixedIP, floating_ips.FloatingIP,
"""Sets up network on this host."""
network['dhcp_server'] = self._get_dhcp_ip(context, network)
+ if not CONF.fixed_range:
+ self.l3driver.initialize_network(network.get('cidr'))
self.l3driver.initialize_gateway(network)
if not CONF.fake_network:
@@ -1630,7 +1640,12 @@ class VlanManager(RPCAllocateFixedIP, floating_ips.FloatingIP, NetworkManager):
standalone service.
"""
- self.l3driver.initialize()
+ if not CONF.fixed_range:
+ ctxt = context.get_admin_context()
+ networks = self.db.network_get_all_by_host(ctxt, self.host)
+ self.l3driver.initialize(fixed_range=False, networks=networks)
+ else:
+ self.l3driver.initialize(fixed_range=CONF.fixed_range)
NetworkManager.init_host(self)
self.init_host_floating_ips()
@@ -1773,6 +1788,8 @@ class VlanManager(RPCAllocateFixedIP, floating_ips.FloatingIP, NetworkManager):
address = network['vpn_public_address']
network['dhcp_server'] = self._get_dhcp_ip(context, network)
+ if not CONF.fixed_range:
+ self.l3driver.initialize_network(network.get('cidr'))
self.l3driver.initialize_gateway(network)
# NOTE(vish): only ensure this forward if the address hasn't been set
diff --git a/nova/tests/network/test_manager.py b/nova/tests/network/test_manager.py
index 92b8e1d91..6121ae8ac 100644
--- a/nova/tests/network/test_manager.py
+++ b/nova/tests/network/test_manager.py
@@ -1601,6 +1601,207 @@ class CommonNetworkTestCase(test.TestCase):
self.assertRaises(exception.NetworkNotFound,
manager.disassociate_network, fake_context, uuid)
+ def _test_init_host_static_fixed_range(self, net_manager):
+ self.flags(fake_network=True,
+ fixed_range='10.0.0.0/22',
+ routing_source_ip='192.168.0.1',
+ metadata_host='192.168.0.1',
+ public_interface='eth1',
+ dmz_cidr=['10.0.3.0/24'])
+ binary_name = linux_net.get_binary_name()
+
+ # Stub out calls we don't want to really run
+ self.stubs.Set(linux_net.iptables_manager, '_apply', lambda: None)
+ self.stubs.Set(floating_ips.FloatingIP, 'init_host_floating_ips',
+ lambda *args: None)
+
+ # Call the network manager init code to configure the fixed_range
+ net_manager.init_host()
+
+ # Get the iptables rules that got created
+ current_lines = []
+ new_lines = linux_net.iptables_manager._modify_rules(current_lines,
+ linux_net.iptables_manager.ipv4['nat'],
+ table_name='nat')
+
+ # The expected rules that should be configured based on the fixed_range
+ expected_lines = ['[0:0] -A %s-snat -s %s -j SNAT --to-source %s -o %s'
+ % (binary_name, CONF.fixed_range,
+ CONF.routing_source_ip,
+ CONF.public_interface),
+ '[0:0] -A %s-POSTROUTING -s %s -d %s/32 -j ACCEPT'
+ % (binary_name, CONF.fixed_range,
+ CONF.metadata_host),
+ '[0:0] -A %s-POSTROUTING -s %s -d %s -j ACCEPT'
+ % (binary_name, CONF.fixed_range, CONF.dmz_cidr[0]),
+ '[0:0] -A %s-POSTROUTING -s %s -d %s -m conntrack ! '
+ '--ctstate DNAT -j ACCEPT' % (binary_name,
+ CONF.fixed_range,
+ CONF.fixed_range)]
+
+ # Finally, compare the expected rules against the actual ones
+ for line in expected_lines:
+ self.assertTrue(line in new_lines)
+
+ def _test_init_host_dynamic_fixed_range(self, net_manager):
+ self.flags(fake_network=True,
+ fixed_range='',
+ routing_source_ip='172.16.0.1',
+ metadata_host='172.16.0.1',
+ public_interface='eth1',
+ dmz_cidr=['10.0.3.0/24'])
+ binary_name = linux_net.get_binary_name()
+
+ # Stub out calls we don't want to really run, mock the db
+ self.stubs.Set(linux_net.iptables_manager, '_apply', lambda: None)
+ self.stubs.Set(floating_ips.FloatingIP, 'init_host_floating_ips',
+ lambda *args: None)
+ self.stubs.Set(net_manager.l3driver, 'initialize_gateway',
+ lambda *args: None)
+ self.mox.StubOutWithMock(db, 'network_get_all_by_host')
+ db.network_get_all_by_host(mox.IgnoreArg(),
+ mox.IgnoreArg()).MultipleTimes().AndReturn(networks)
+ self.mox.ReplayAll()
+
+ # Call the network manager init code to configure the fixed_range
+ net_manager.init_host()
+
+ # Get the iptables rules that got created
+ current_lines = []
+ new_lines = linux_net.iptables_manager._modify_rules(current_lines,
+ linux_net.iptables_manager.ipv4['nat'],
+ table_name='nat')
+
+ # The expected rules that should be configured based on the fixed_range
+ expected_lines = ['[0:0] -A %s-snat -s %s -j SNAT --to-source %s -o %s'
+ % (binary_name, networks[0]['cidr'],
+ CONF.routing_source_ip,
+ CONF.public_interface),
+ '[0:0] -A %s-POSTROUTING -s %s -d %s/32 -j ACCEPT'
+ % (binary_name, networks[0]['cidr'],
+ CONF.metadata_host),
+ '[0:0] -A %s-POSTROUTING -s %s -d %s -j ACCEPT'
+ % (binary_name, networks[0]['cidr'],
+ CONF.dmz_cidr[0]),
+ '[0:0] -A %s-POSTROUTING -s %s -d %s -m conntrack ! '
+ '--ctstate DNAT -j ACCEPT' % (binary_name,
+ networks[0]['cidr'],
+ networks[0]['cidr']),
+ '[0:0] -A %s-snat -s %s -j SNAT --to-source %s -o %s'
+ % (binary_name, networks[1]['cidr'],
+ CONF.routing_source_ip,
+ CONF.public_interface),
+ '[0:0] -A %s-POSTROUTING -s %s -d %s/32 -j ACCEPT'
+ % (binary_name, networks[1]['cidr'],
+ CONF.metadata_host),
+ '[0:0] -A %s-POSTROUTING -s %s -d %s -j ACCEPT'
+ % (binary_name, networks[1]['cidr'],
+ CONF.dmz_cidr[0]),
+ '[0:0] -A %s-POSTROUTING -s %s -d %s -m conntrack ! '
+ '--ctstate DNAT -j ACCEPT' % (binary_name,
+ networks[1]['cidr'],
+ networks[1]['cidr'])]
+
+ # Compare the expected rules against the actual ones
+ for line in expected_lines:
+ self.assertTrue(line in new_lines)
+
+ # Add an additional network and ensure the rules get configured
+ new_network = {'id': 2,
+ 'uuid': 'cccccccc-cccc-cccc-cccc-cccccccc',
+ 'label': 'test2',
+ 'injected': False,
+ 'multi_host': False,
+ 'cidr': '192.168.2.0/24',
+ 'cidr_v6': '2001:dba::/64',
+ 'gateway_v6': '2001:dba::1',
+ 'netmask_v6': '64',
+ 'netmask': '255.255.255.0',
+ 'bridge': 'fa1',
+ 'bridge_interface': 'fake_fa1',
+ 'gateway': '192.168.2.1',
+ 'broadcast': '192.168.2.255',
+ 'dns1': '192.168.2.1',
+ 'dns2': '192.168.2.2',
+ 'vlan': None,
+ 'host': HOST,
+ 'project_id': 'fake_project',
+ 'vpn_public_address': '192.168.2.2',
+ 'vpn_public_port': '22',
+ 'vpn_private_address': '10.0.0.2'}
+
+ # Call the network manager init code to configure the fixed_range
+ ctxt = context.get_admin_context()
+ net_manager._setup_network_on_host(ctxt, new_network)
+
+ # Get the new iptables rules that got created from adding a new network
+ current_lines = []
+ new_lines = linux_net.iptables_manager._modify_rules(current_lines,
+ linux_net.iptables_manager.ipv4['nat'],
+ table_name='nat')
+
+ # Add the new expected rules to the old ones
+ expected_lines += ['[0:0] -A %s-snat -s %s -j SNAT --to-source %s -o '
+ '%s' % (binary_name, new_network['cidr'],
+ CONF.routing_source_ip,
+ CONF.public_interface),
+ '[0:0] -A %s-POSTROUTING -s %s -d %s/32 -j ACCEPT'
+ % (binary_name, new_network['cidr'],
+ CONF.metadata_host),
+ '[0:0] -A %s-POSTROUTING -s %s -d %s -j ACCEPT'
+ % (binary_name, new_network['cidr'],
+ CONF.dmz_cidr[0]),
+ '[0:0] -A %s-POSTROUTING -s %s -d %s -m conntrack '
+ '! --ctstate DNAT -j ACCEPT' % (binary_name,
+ new_network['cidr'],
+ new_network['cidr'])]
+
+ # Compare the expected rules (with new network) against the actual ones
+ for line in expected_lines:
+ self.assertTrue(line in new_lines)
+
+ def test_flatdhcpmanager_static_fixed_range(self):
+ """Test FlatDHCPManager NAT rules for fixed_range."""
+ # Set the network manager
+ self.network = network_manager.FlatDHCPManager(host=HOST)
+ self.network.db = db
+
+ # Test existing behavior:
+ # CONF.fixed_range is set, NAT based on CONF.fixed_range
+ self._test_init_host_static_fixed_range(self.network)
+
+ def test_flatdhcpmanager_dynamic_fixed_range(self):
+ """Test FlatDHCPManager NAT rules for fixed_range."""
+ # Set the network manager
+ self.network = network_manager.FlatDHCPManager(host=HOST)
+ self.network.db = db
+
+ # Test new behavior:
+ # CONF.fixed_range is not set, defaults to None
+ # Determine networks to NAT based on lookup
+ self._test_init_host_dynamic_fixed_range(self.network)
+
+ def test_vlanmanager_static_fixed_range(self):
+ """Test VlanManager NAT rules for fixed_range."""
+ # Set the network manager
+ self.network = network_manager.VlanManager(host=HOST)
+ self.network.db = db
+
+ # Test existing behavior:
+ # CONF.fixed_range is set, NAT based on CONF.fixed_range
+ self._test_init_host_static_fixed_range(self.network)
+
+ def test_vlanmanager_dynamic_fixed_range(self):
+ """Test VlanManager NAT rules for fixed_range."""
+ # Set the network manager
+ self.network = network_manager.VlanManager(host=HOST)
+ self.network.db = db
+
+ # Test new behavior:
+ # CONF.fixed_range is not set, defaults to None
+ # Determine networks to NAT based on lookup
+ self._test_init_host_dynamic_fixed_range(self.network)
+
class TestRPCFixedManager(network_manager.RPCAllocateFixedIP,
network_manager.NetworkManager):