Refactored network model access into data abstraction layer.

Also changed the name to floating_ip.
This commit is contained in:
Vishvananda Ishaya
2010-08-23 13:55:16 -07:00
parent 44a796c998
commit e64136c381
4 changed files with 66 additions and 63 deletions

View File

@@ -25,9 +25,9 @@ import logging
import os
import sys
#TODO(joshua): there is concern that the user dnsmasq runs under will not
# have nova in the path. This should be verified and if it is
# not true the ugly line below can be removed
# TODO(joshua): there is concern that the user dnsmasq runs under will not
# have nova in the path. This should be verified and if it is
# not true the ugly line below can be removed
sys.path.append(os.path.abspath(os.path.join(__file__, "../../")))
from nova import flags
@@ -36,6 +36,7 @@ from nova import utils
from nova.network import linux_net
from nova.network import service
from nova import datastore # for redis_db flag
from nova.auth import manager # for auth flags
FLAGS = flags.FLAGS
@@ -43,16 +44,16 @@ FLAGS = flags.FLAGS
def add_lease(_mac, ip, _hostname, _interface):
"""Set the IP that was assigned by the DHCP server."""
if FLAGS.fake_rabbit:
logging.debug("leasing_ip")
logging.debug("leasing ip")
from nova import models
print models.FixedIp.count()
print models.Network.count()
print FLAGS.sql_connection
service.VlanNetworkService().lease_ip(ip)
service.VlanNetworkService().lease_fixed_ip(ip)
else:
rpc.cast("%s.%s" % (FLAGS.network_topic, FLAGS.node_name),
{"method": "lease_ip",
"args": {"fixed_ip_str": ip}})
{"method": "lease_fixed_ip",
"args": {"address": ip}})
def old_lease(_mac, _ip, _hostname, _interface):
@@ -63,12 +64,12 @@ def old_lease(_mac, _ip, _hostname, _interface):
def del_lease(_mac, ip, _hostname, _interface):
"""Called when a lease expires."""
if FLAGS.fake_rabbit:
logging.debug("releasing_ip")
service.VlanNetworkService().release_ip(ip)
logging.debug("releasing ip")
service.VlanNetworkService().release_fixed_ip(ip)
else:
rpc.cast("%s.%s" % (FLAGS.network_topic, FLAGS.node_name),
{"method": "release_ip",
"args": {"fixed_ip_str": ip}})
{"method": "release_fixed_ip",
"args": {"address": ip}})
def init_leases(interface):

View File

@@ -311,7 +311,7 @@ class CloudController(object):
def _get_address(self, context, public_ip):
# FIXME(vish) this should move into network.py
address = network_model.ElasticIp.lookup(public_ip)
address = network_model.FloatingIp.lookup(public_ip)
if address and (context.user.is_admin() or address['project_id'] == context.project.id):
return address
raise exception.NotFound("Address at ip %s not found" % public_ip)
@@ -459,7 +459,7 @@ class CloudController(object):
def format_addresses(self, context):
addresses = []
for address in network_model.ElasticIp.all():
for address in network_model.FloatingIp.all():
# TODO(vish): implement a by_project iterator for addresses
if (context.user.is_admin() or
address['project_id'] == context.project.id):
@@ -481,7 +481,7 @@ class CloudController(object):
def allocate_address(self, context, **kwargs):
network_topic = yield self._get_network_topic(context)
public_ip = yield rpc.call(network_topic,
{"method": "allocate_elastic_ip",
{"method": "allocate_floating_ip",
"args": {"user_id": context.user.id,
"project_id": context.project.id}})
defer.returnValue({'addressSet': [{'publicIp': public_ip}]})
@@ -492,8 +492,8 @@ class CloudController(object):
# NOTE(vish): Should we make sure this works?
network_topic = yield self._get_network_topic(context)
rpc.cast(network_topic,
{"method": "deallocate_elastic_ip",
"args": {"elastic_ip": public_ip}})
{"method": "deallocate_floating_ip",
"args": {"floating_ip": public_ip}})
defer.returnValue({'releaseResponse': ["Address released."]})
@rbac.allow('netadmin')
@@ -503,8 +503,8 @@ class CloudController(object):
address = self._get_address(context, public_ip)
network_topic = yield self._get_network_topic(context)
rpc.cast(network_topic,
{"method": "associate_elastic_ip",
"args": {"elastic_ip": address['address'],
{"method": "associate_floating_ip",
"args": {"floating_ip": address['address'],
"fixed_ip": instance['private_dns_name'],
"instance_id": instance['instance_id']}})
defer.returnValue({'associateResponse': ["Address associated."]})
@@ -515,8 +515,8 @@ class CloudController(object):
address = self._get_address(context, public_ip)
network_topic = yield self._get_network_topic(context)
rpc.cast(network_topic,
{"method": "disassociate_elastic_ip",
"args": {"elastic_ip": address['address']}})
{"method": "disassociate_floating_ip",
"args": {"floating_ip": address['address']}})
defer.returnValue({'disassociateResponse': ["Address disassociated."]})
@defer.inlineCallbacks
@@ -617,15 +617,15 @@ class CloudController(object):
logging.warning("Instance %s was not found during terminate"
% i)
continue
elastic_ip = network_model.get_public_ip_for_instance(i)
if elastic_ip:
logging.debug("Disassociating address %s" % elastic_ip)
floating_ip = network_model.get_public_ip_for_instance(i)
if floating_ip:
logging.debug("Disassociating address %s" % floating_ip)
# NOTE(vish): Right now we don't really care if the ip is
# disassociated. We may need to worry about
# checking this later. Perhaps in the scheduler?
rpc.cast(network_topic,
{"method": "disassociate_elastic_ip",
"args": {"elastic_ip": elastic_ip}})
{"method": "disassociate_floating_ip",
"args": {"floating_ip": floating_ip}})
fixed_ip = instance.get('private_dns_name', None)
if fixed_ip:

View File

@@ -278,12 +278,12 @@ class FixedIp(Base, NovaBase):
raise exception.NotFound("No model for ip str %s" % ip_str)
class ElasticIp(Base, NovaBase):
__tablename__ = 'elastic_ips'
class FloatingIp(Base, NovaBase):
__tablename__ = 'floating_ips'
id = Column(Integer, primary_key=True)
ip_str = Column(String(255), unique=True)
fixed_ip_id = Column(Integer, ForeignKey('fixed_ips.id'), nullable=True)
fixed_ip = relationship(FixedIp, backref=backref('elastic_ips'))
fixed_ip = relationship(FixedIp, backref=backref('floating_ips'))
project_id = Column(String(255)) #, ForeignKey('projects.id'), nullable=False)
node_name = Column(String(255)) #, ForeignKey('physical_node.id'))
@@ -305,7 +305,7 @@ class Network(Base, NovaBase):
kind = Column(String(255))
injected = Column(Boolean, default=False)
network_str = Column(String(255))
cidr = Column(String(255))
netmask = Column(String(255))
bridge = Column(String(255))
gateway = Column(String(255))

View File

@@ -21,8 +21,8 @@ Unit Tests for network code
import IPy
import os
import logging
import tempfile
from nova import db
from nova import exception
from nova import flags
from nova import models
@@ -30,7 +30,6 @@ from nova import test
from nova import utils
from nova.auth import manager
from nova.network import service
from nova.network.exception import NoMoreAddresses, NoMoreNetworks
FLAGS = flags.FLAGS
@@ -59,49 +58,52 @@ class NetworkTestCase(test.TrialTestCase):
name))
# create the necessary network data for the project
self.service.set_network_host(self.projects[i].id)
instance = models.Instance()
instance.mac_address = utils.generate_mac()
instance.hostname = 'fake'
instance.save()
self.instance_id = instance.id
instance_id = db.instance_create(None,
{'mac_address': utils.generate_mac()})
self.instance_id = instance_id
instance_id = db.instance_create(None,
{'mac_address': utils.generate_mac()})
self.instance2_id = instance_id
def tearDown(self): # pylint: disable=C0103
super(NetworkTestCase, self).tearDown()
# TODO(termie): this should really be instantiating clean datastores
# in between runs, one failure kills all the tests
db.instance_destroy(None, self.instance_id)
db.instance_destroy(None, self.instance2_id)
for project in self.projects:
self.manager.delete_project(project)
self.manager.delete_user(self.user)
def test_public_network_association(self):
"""Makes sure that we can allocaate a public ip"""
# FIXME better way of adding elastic ips
# TODO(vish): better way of adding floating ips
pubnet = IPy.IP(flags.FLAGS.public_range)
ip_str = str(pubnet[0])
try:
elastic_ip = models.ElasticIp.find_by_ip_str(ip_str)
floating_ip = models.FloatingIp.find_by_ip_str(ip_str)
except exception.NotFound:
elastic_ip = models.ElasticIp()
elastic_ip.ip_str = ip_str
elastic_ip.node_name = FLAGS.node_name
elastic_ip.save()
eaddress = self.service.allocate_elastic_ip(self.projects[0].id)
floating_ip = models.FloatingIp()
floating_ip.ip_str = ip_str
floating_ip.node_name = FLAGS.node_name
floating_ip.save()
eaddress = self.service.allocate_floating_ip(self.projects[0].id)
faddress = self.service.allocate_fixed_ip(self.projects[0].id,
self.instance_id)
self.assertEqual(eaddress, str(pubnet[0]))
self.service.associate_elastic_ip(eaddress, faddress)
self.service.associate_floating_ip(eaddress, faddress)
# FIXME datamodel abstraction
self.assertEqual(elastic_ip.fixed_ip.ip_str, faddress)
self.service.disassociate_elastic_ip(eaddress)
self.assertEqual(elastic_ip.fixed_ip, None)
self.service.deallocate_elastic_ip(eaddress)
self.assertEqual(floating_ip.fixed_ip.ip_str, faddress)
self.service.disassociate_floating_ip(eaddress)
self.assertEqual(floating_ip.fixed_ip, None)
self.service.deallocate_floating_ip(eaddress)
self.service.deallocate_fixed_ip(faddress)
def test_allocate_deallocate_fixed_ip(self):
"""Makes sure that we can allocate and deallocate a fixed ip"""
address = self.service.allocate_fixed_ip(self.projects[0].id,
self.instance_id)
net = service.get_network_for_project(self.projects[0].id)
net = db.project_get_network(None, self.projects[0].id)
self.assertTrue(is_allocated_in_project(address, self.projects[0].id))
issue_ip(address, net.bridge)
self.service.deallocate_fixed_ip(address)
@@ -117,10 +119,10 @@ class NetworkTestCase(test.TrialTestCase):
address = self.service.allocate_fixed_ip(self.projects[0].id,
self.instance_id)
address2 = self.service.allocate_fixed_ip(self.projects[1].id,
self.instance_id)
self.instance2_id)
net = service.get_network_for_project(self.projects[0].id)
net2 = service.get_network_for_project(self.projects[1].id)
net = db.project_get_network(None, self.projects[0].id)
net2 = db.project_get_network(None, self.projects[1].id)
self.assertTrue(is_allocated_in_project(address, self.projects[0].id))
self.assertTrue(is_allocated_in_project(address2, self.projects[1].id))
@@ -151,7 +153,7 @@ class NetworkTestCase(test.TrialTestCase):
address = self.service.allocate_fixed_ip(project_id, self.instance_id)
address2 = self.service.allocate_fixed_ip(project_id, self.instance_id)
address3 = self.service.allocate_fixed_ip(project_id, self.instance_id)
net = service.get_network_for_project(project_id)
net = db.project_get_network(None, project_id)
issue_ip(address, net.bridge)
issue_ip(address2, net.bridge)
issue_ip(address3, net.bridge)
@@ -167,7 +169,7 @@ class NetworkTestCase(test.TrialTestCase):
release_ip(address, net.bridge)
release_ip(address2, net.bridge)
release_ip(address3, net.bridge)
net = service.get_network_for_project(self.projects[0].id)
net = db.project_get_network(None, self.projects[0].id)
self.service.deallocate_fixed_ip(first)
def test_vpn_ip_and_port_looks_valid(self):
@@ -186,7 +188,7 @@ class NetworkTestCase(test.TrialTestCase):
self.service.set_network_host(project.id)
projects.append(project)
project = self.manager.create_project('boom' , self.user)
self.assertRaises(NoMoreNetworks,
self.assertRaises(db.NoMoreNetworks,
self.service.set_network_host,
project.id)
self.manager.delete_project(project)
@@ -198,7 +200,7 @@ class NetworkTestCase(test.TrialTestCase):
"""Makes sure that ip addresses that are deallocated get reused"""
address = self.service.allocate_fixed_ip(self.projects[0].id,
self.instance_id)
net = service.get_network_for_project(self.projects[0].id)
net = db.project_get_network(None, self.projects[0].id)
issue_ip(address, net.bridge)
self.service.deallocate_fixed_ip(address)
release_ip(address, net.bridge)
@@ -219,7 +221,7 @@ class NetworkTestCase(test.TrialTestCase):
There are ips reserved at the bottom and top of the range.
services (network, gateway, CloudPipe, broadcast)
"""
network = service.get_network_for_project(self.projects[0].id)
network = db.project_get_network(None, self.projects[0].id)
net_size = flags.FLAGS.network_size
total_ips = (available_ips(network) +
reserved_ips(network) +
@@ -229,7 +231,7 @@ class NetworkTestCase(test.TrialTestCase):
def test_too_many_addresses(self):
"""Test for a NoMoreAddresses exception when all fixed ips are used.
"""
network = service.get_network_for_project(self.projects[0].id)
network = db.project_get_network(None, self.projects[0].id)
# Number of availaible ips is len of the available list
@@ -242,7 +244,7 @@ class NetworkTestCase(test.TrialTestCase):
issue_ip(addresses[i],network.bridge)
self.assertEqual(available_ips(network), 0)
self.assertRaises(NoMoreAddresses,
self.assertRaises(db.NoMoreAddresses,
self.service.allocate_fixed_ip,
self.projects[0].id,
self.instance_id)
@@ -274,11 +276,11 @@ def reserved_ips(network):
def is_allocated_in_project(address, project_id):
"""Returns true if address is in specified project"""
fixed_ip = models.FixedIp.find_by_ip_str(address)
project_net = service.get_network_for_project(project_id)
fixed_ip = db.fixed_ip_get_by_address(None, address)
project_net = db.project_get_network(None, project_id)
# instance exists until release
logging.error('fixed_ip.instance: %s', fixed_ip.instance)
logging.error('project_net: %s', project_net)
logging.debug('fixed_ip.instance: %s', fixed_ip.instance)
logging.debug('project_net: %s', project_net)
return fixed_ip.instance is not None and fixed_ip.network == project_net