Blob Blame History Raw
From 015744e92e601036ddcd77bd2fbed966172cb759 Mon Sep 17 00:00:00 2001
From: Vishvananda Ishaya <vishvananda@gmail.com>
Date: Tue, 3 Apr 2012 11:30:57 -0700
Subject: [PATCH] Delete fixed_ips when network is deleted

 * adds failing test
 * adds exception that is raised when network is in use
 * fixes bug 754900

Change-Id: Ib95dc5927561b979b1eea237d4d6dc323483d4a5
---
 nova/db/sqlalchemy/api.py |   13 +++++++++++++
 nova/exception.py         |    4 ++++
 nova/tests/test_db_api.py |   19 +++++++++++++++++++
 3 files changed, 36 insertions(+), 0 deletions(-)

diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index f2c3062..03ac987 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -1898,8 +1898,21 @@ def network_create_safe(context, values):
 def network_delete_safe(context, network_id):
     session = get_session()
     with session.begin():
+        result = session.query(models.FixedIp).\
+                         filter_by(network_id=network_id).\
+                         filter_by(deleted=False).\
+                         filter_by(allocated=True).\
+                         all()
+        if result:
+            raise exception.NetworkInUse(network_id=network_id)
         network_ref = network_get(context, network_id=network_id,
                                   session=session)
+        session.query(models.FixedIp).\
+                filter_by(network_id=network_id).\
+                filter_by(deleted=False).\
+                update({'deleted': True,
+                        'updated_at': literal_column('updated_at'),
+                        'deleted_at': utils.utcnow()})
         session.delete(network_ref)
 
 
diff --git a/nova/exception.py b/nova/exception.py
index eb0bf38..da067b6 100644
--- a/nova/exception.py
+++ b/nova/exception.py
@@ -525,6 +525,10 @@ class StorageRepositoryNotFound(NotFound):
     message = _("Cannot find SR to read/write VDI.")
 
 
+class NetworkInUse(NovaException):
+    message = _("Network %(network_id)s is still in use.")
+
+
 class NetworkNotCreated(NovaException):
     message = _("%(req)s is required to create a network.")
 
diff --git a/nova/tests/test_db_api.py b/nova/tests/test_db_api.py
index 8b73580..28f3558 100644
--- a/nova/tests/test_db_api.py
+++ b/nova/tests/test_db_api.py
@@ -136,6 +136,25 @@ class DbApiTestCase(test.TestCase):
         db_network = db.network_get(ctxt, network.id)
         self.assertEqual(network.uuid, db_network.uuid)
 
+    def test_network_delete_safe(self):
+        ctxt = context.get_admin_context()
+        values = {'host': 'localhost', 'project_id': 'project1'}
+        network = db.network_create_safe(ctxt, values)
+        db_network = db.network_get(ctxt, network.id)
+        values = {'network_id': network['id'], 'address': 'fake1'}
+        address1 = db.fixed_ip_create(ctxt, values)
+        values = {'network_id': network['id'],
+                  'address': 'fake2',
+                  'allocated': True}
+        address2 = db.fixed_ip_create(ctxt, values)
+        self.assertRaises(exception.NetworkInUse,
+                          db.network_delete_safe, ctxt, network['id'])
+        db.fixed_ip_update(ctxt, address2, {'allocated': False})
+        network = db.network_delete_safe(ctxt, network['id'])
+        ctxt = ctxt.elevated(read_deleted='yes')
+        fixed_ip = db.fixed_ip_get_by_address(ctxt, address1)
+        self.assertTrue(fixed_ip['deleted'])
+
     def test_network_create_with_duplicate_vlan(self):
         ctxt = context.get_admin_context()
         values1 = {'host': 'localhost', 'project_id': 'project1', 'vlan': 1}