Josh's networking refactor, modified to work with projects
This commit is contained in:
@@ -28,6 +28,7 @@ import json
|
||||
import logging
|
||||
import os
|
||||
import sqlite3
|
||||
import time
|
||||
|
||||
from nova import vendor
|
||||
import redis
|
||||
@@ -77,10 +78,11 @@ class RedisModel(object):
|
||||
def set_default_state(self):
|
||||
self.state = {'state' : 'pending'}
|
||||
self.state[self.object_type+"_id"] = self.object_id
|
||||
self.state["create_time"] = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())
|
||||
|
||||
@property
|
||||
def __redis_key(self):
|
||||
""" Magic string for instance keys """
|
||||
""" Magic string for keys """
|
||||
return '%s:%s' % (self.object_type, self.object_id)
|
||||
|
||||
def __repr__(self):
|
||||
|
||||
@@ -60,7 +60,7 @@ class CloudController(object):
|
||||
"""
|
||||
def __init__(self):
|
||||
self.instdir = model.InstanceDirectory()
|
||||
self.network = network.NetworkController()
|
||||
self.network = network.PublicNetworkController()
|
||||
self.setup()
|
||||
|
||||
@property
|
||||
@@ -254,21 +254,10 @@ class CloudController(object):
|
||||
res.addCallback(_format_result)
|
||||
return res
|
||||
|
||||
def _convert_address(self, network_address):
|
||||
# FIXME(vish): this should go away when network.py stores info properly
|
||||
address = {}
|
||||
address['public_ip'] == network_address[u'address']
|
||||
address['user_id'] == network_address[u'user_id']
|
||||
address['project_id'] == network_address.get(u'project_id', address['user_id'])
|
||||
address['instance_id'] == network_address.get(u'instance_id', None)
|
||||
return address
|
||||
|
||||
def _get_address(self, context, public_ip):
|
||||
# right now all addresses are allocated locally
|
||||
# FIXME(vish) this should move into network.py
|
||||
for network_address in self.network.describe_addresses():
|
||||
if network_address[u'address'] == public_ip:
|
||||
address = self._convert_address(network_address)
|
||||
for address in self.network.hosts:
|
||||
if address['address'] == public_ip:
|
||||
if context.user.is_admin() or address['project_id'] == context.project.id:
|
||||
return address
|
||||
raise exception.NotFound("Address at ip %s not found" % public_ip)
|
||||
@@ -398,14 +387,12 @@ class CloudController(object):
|
||||
def format_addresses(self, context):
|
||||
addresses = []
|
||||
# TODO(vish): move authorization checking into network.py
|
||||
for network_address in self.network.describe_addresses(type=network.PublicNetwork):
|
||||
for address in self.network.hosts:
|
||||
#logging.debug(address_record)
|
||||
address = self._convert_address(network_address)
|
||||
address_rv = {
|
||||
'public_ip': address['public_ip'],
|
||||
'public_ip': address['address'],
|
||||
'instance_id' : address.get('instance_id', 'free')
|
||||
}
|
||||
# FIXME: add another field for user id
|
||||
if context.user.is_admin():
|
||||
address_rv['instance_id'] = "%s (%s, %s)" % (
|
||||
address['instance_id'],
|
||||
@@ -417,17 +404,17 @@ class CloudController(object):
|
||||
return {'addressesSet': addresses}
|
||||
|
||||
def allocate_address(self, context, **kwargs):
|
||||
(address,network_name) = self.network.allocate_address(
|
||||
context.user.id, context.project_id, type=network.PublicNetwork)
|
||||
address = self.network.allocate_ip(
|
||||
context.user.id, context.project.id, 'public')
|
||||
return defer.succeed({'addressSet': [{'publicIp' : address}]})
|
||||
|
||||
def release_address(self, context, public_ip, **kwargs):
|
||||
address = self._get_address(public_ip)
|
||||
self.network.deallocate_ip(public_ip)
|
||||
return defer.succeed({'releaseResponse': ["Address released."]})
|
||||
|
||||
def associate_address(self, context, instance_id, **kwargs):
|
||||
instance = self._get_instance(context, instance_id)
|
||||
rv = self.network.associate_address(
|
||||
self.network.associate_address(
|
||||
kwargs['public_ip'],
|
||||
instance['private_dns_name'],
|
||||
instance_id)
|
||||
@@ -435,7 +422,7 @@ class CloudController(object):
|
||||
|
||||
def disassociate_address(self, context, public_ip, **kwargs):
|
||||
address = self._get_address(public_ip)
|
||||
rv = self.network.disassociate_address(public_ip)
|
||||
self.network.disassociate_address(public_ip)
|
||||
# TODO - Strip the IP from the instance
|
||||
return defer.succeed({'disassociateResponse': ["Address disassociated."]})
|
||||
|
||||
@@ -466,14 +453,10 @@ class CloudController(object):
|
||||
inst['project_id'] = context.project.id
|
||||
inst['mac_address'] = utils.generate_mac()
|
||||
inst['ami_launch_index'] = num
|
||||
address, _netname = self.network.allocate_address(
|
||||
user_id=inst['user_id'],
|
||||
project_id=inst['project_id'],
|
||||
mac=inst['mac_address'])
|
||||
network = self.network.get_users_network(str(context.user.id))
|
||||
inst['network_str'] = json.dumps(network.to_dict())
|
||||
inst['bridge_name'] = network.bridge_name
|
||||
address = network.allocate_ip(
|
||||
inst['user_id'], inst['project_id'], mac=inst['mac_address'])
|
||||
inst['private_dns_name'] = str(address)
|
||||
inst['bridge_name'] = network.BridgedNetwork.get_network_for_project(inst['user_id'], inst['project_id'])['bridge_name']
|
||||
# TODO: allocate expresses on the router node
|
||||
inst.save()
|
||||
rpc.cast(FLAGS.compute_topic,
|
||||
@@ -502,7 +485,7 @@ class CloudController(object):
|
||||
if instance.get('private_dns_name', None):
|
||||
logging.debug("Deallocating address %s" % instance.get('private_dns_name', None))
|
||||
try:
|
||||
self.network.deallocate_address(instance.get('private_dns_name', None))
|
||||
self.network.deallocate_ip(instance.get('private_dns_name', None))
|
||||
except Exception, _err:
|
||||
pass
|
||||
if instance.get('node_name', 'unassigned') != 'unassigned': #It's also internal default
|
||||
|
||||
@@ -23,11 +23,17 @@ from nova import flags
|
||||
from nova import test
|
||||
from nova.compute import network
|
||||
from nova.auth import users
|
||||
from nova import utils
|
||||
|
||||
|
||||
class NetworkTestCase(test.TrialTestCase):
|
||||
def setUp(self):
|
||||
super(NetworkTestCase, self).setUp()
|
||||
self.flags(fake_libvirt=True,
|
||||
fake_storage=True,
|
||||
fake_network=True,
|
||||
network_size=32,
|
||||
redis_db=8)
|
||||
logging.getLogger().setLevel(logging.DEBUG)
|
||||
self.manager = users.UserManager.instance()
|
||||
try:
|
||||
@@ -37,7 +43,7 @@ class NetworkTestCase(test.TrialTestCase):
|
||||
name = 'project%s' % i
|
||||
if not self.manager.get_project(name):
|
||||
self.manager.create_project(name, 'netuser', name)
|
||||
self.network = network.NetworkController(netsize=16)
|
||||
self.network = network.PublicNetworkController()
|
||||
|
||||
def tearDown(self):
|
||||
super(NetworkTestCase, self).tearDown()
|
||||
@@ -46,70 +52,69 @@ class NetworkTestCase(test.TrialTestCase):
|
||||
self.manager.delete_project(name)
|
||||
self.manager.delete_user('netuser')
|
||||
|
||||
def test_network_serialization(self):
|
||||
net1 = network.Network(vlan=100, network="192.168.100.0/24", conn=None)
|
||||
address = net1.allocate_ip("netuser", "project0", "01:24:55:36:f2:a0")
|
||||
net_json = str(net1)
|
||||
net2 = network.Network.from_json(net_json)
|
||||
self.assertEqual(net_json, str(net2))
|
||||
self.assertTrue(IPy.IP(address) in net2.network)
|
||||
def test_public_network_allocation(self):
|
||||
pubnet = IPy.IP(flags.FLAGS.public_range)
|
||||
address = self.network.allocate_ip("netuser", "project0", "public")
|
||||
self.assertTrue(IPy.IP(address) in pubnet)
|
||||
self.assertTrue(IPy.IP(address) in self.network.network)
|
||||
|
||||
def test_allocate_deallocate_address(self):
|
||||
(address, net_name) = self.network.allocate_address("netuser",
|
||||
"project0", "01:24:55:36:f2:a0")
|
||||
def test_allocate_deallocate_ip(self):
|
||||
address = network.allocate_ip(
|
||||
"netuser", "project0", utils.generate_mac())
|
||||
logging.debug("Was allocated %s" % (address))
|
||||
self.assertEqual(True, address in self._get_project_addresses("project0"))
|
||||
rv = self.network.deallocate_address(address)
|
||||
rv = network.deallocate_ip(address)
|
||||
self.assertEqual(False, address in self._get_project_addresses("project0"))
|
||||
|
||||
def test_range_allocation(self):
|
||||
(address, net_name) = self.network.allocate_address("netuser",
|
||||
"project0", "01:24:55:36:f2:a0")
|
||||
(secondaddress, net_name) = self.network.allocate_address("netuser",
|
||||
"project1", "01:24:55:36:f2:a0")
|
||||
self.assertEqual(True, address in self._get_project_addresses("project0"))
|
||||
address = network.allocate_ip(
|
||||
"netuser", "project0", utils.generate_mac())
|
||||
secondaddress = network.allocate_ip(
|
||||
"netuser", "project1", utils.generate_mac())
|
||||
self.assertEqual(True,
|
||||
address in self._get_project_addresses("project0"))
|
||||
self.assertEqual(True,
|
||||
secondaddress in self._get_project_addresses("project1"))
|
||||
self.assertEqual(False, address in self._get_project_addresses("project1"))
|
||||
rv = self.network.deallocate_address(address)
|
||||
rv = network.deallocate_ip(address)
|
||||
self.assertEqual(False, address in self._get_project_addresses("project0"))
|
||||
rv = self.network.deallocate_address(secondaddress)
|
||||
rv = network.deallocate_ip(secondaddress)
|
||||
self.assertEqual(False,
|
||||
secondaddress in self._get_project_addresses("project1"))
|
||||
|
||||
def test_subnet_edge(self):
|
||||
(secondaddress, net_name) = self.network.allocate_address("netuser", "project0")
|
||||
secondaddress = network.allocate_ip("netuser", "project0",
|
||||
utils.generate_mac())
|
||||
for project in range(1,5):
|
||||
project_id = "project%s" % (project)
|
||||
(address, net_name) = self.network.allocate_address("netuser",
|
||||
project_id, "01:24:55:36:f2:a0")
|
||||
(address2, net_name) = self.network.allocate_address("netuser",
|
||||
project_id, "01:24:55:36:f2:a0")
|
||||
(address3, net_name) = self.network.allocate_address("netuser",
|
||||
project_id, "01:24:55:36:f2:a0")
|
||||
address = network.allocate_ip(
|
||||
"netuser", project_id, utils.generate_mac())
|
||||
address2 = network.allocate_ip(
|
||||
"netuser", project_id, utils.generate_mac())
|
||||
address3 = network.allocate_ip(
|
||||
"netuser", project_id, utils.generate_mac())
|
||||
self.assertEqual(False,
|
||||
address in self._get_project_addresses("project0"))
|
||||
self.assertEqual(False,
|
||||
address2 in self._get_project_addresses("project0"))
|
||||
self.assertEqual(False,
|
||||
address3 in self._get_project_addresses("project0"))
|
||||
rv = self.network.deallocate_address(address)
|
||||
rv = self.network.deallocate_address(address2)
|
||||
rv = self.network.deallocate_address(address3)
|
||||
rv = self.network.deallocate_address(secondaddress)
|
||||
rv = network.deallocate_ip(address)
|
||||
rv = network.deallocate_ip(address2)
|
||||
rv = network.deallocate_ip(address3)
|
||||
rv = network.deallocate_ip(secondaddress)
|
||||
|
||||
def test_too_many_projects(self):
|
||||
for i in range(0, 30):
|
||||
name = 'toomany-project%s' % i
|
||||
self.manager.create_project(name, 'netuser', name)
|
||||
(address, net_name) = self.network.allocate_address("netuser",
|
||||
name, "01:24:55:36:f2:a0")
|
||||
address = network.allocate_ip(
|
||||
"netuser", name, utils.generate_mac())
|
||||
rv = network.deallocate_ip(address)
|
||||
self.manager.delete_project(name)
|
||||
|
||||
def _get_project_addresses(self, project_id):
|
||||
rv = self.network.describe_addresses()
|
||||
project_addresses = []
|
||||
for item in rv:
|
||||
if item['project_id'] == project_id:
|
||||
project_addresses.append(item['address'])
|
||||
for addr in network.get_project_network(project_id).list_addresses():
|
||||
project_addresses.append(addr)
|
||||
return project_addresses
|
||||
|
||||
Reference in New Issue
Block a user