Rajaram/Santhosh | Deallocated Ips are deleted after a configurable number of days

This commit is contained in:
Rajaram Mallya
2011-07-19 12:13:59 +05:30
parent fac27cc498
commit 749f920fd7
4 changed files with 105 additions and 22 deletions

View File

@@ -134,6 +134,12 @@ def find_all_blocks_with_deallocated_ips():
filter(_ip_address().marked_for_deallocation == True)
def delete_deallocated_ips(deallocated_by, **kwargs):
return delete_all(find_all_by(_ip_address(), **kwargs).\
filter_by(marked_for_deallocation=True).\
filter(_ip_address().deallocated_at <= deallocated_by))
def _ip_nat():
return session.models()["ip_nat_relation"]

View File

@@ -0,0 +1,34 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2011 OpenStack LLC.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from sqlalchemy.schema import (Column, MetaData, Table)
from melange.ipam import models
from melange.db.migrate_repo.schema import (
Boolean, DateTime, Integer, String, Text, create_tables, drop_tables)
import datetime
def upgrade(migrate_engine):
meta = MetaData()
meta.bind = migrate_engine
Column('deallocated_at', DateTime()).create(\
Table('ip_addresses', meta))
def downgrade(migrate_engine):
meta = MetaData()
meta.bind = migrate_engine
Table('ip_addresses', meta).columns["deallocated_at"].drop()

View File

@@ -22,6 +22,7 @@ import netaddr
from netaddr.strategy.ipv6 import ipv6_verbose
from netaddr import IPNetwork, IPAddress
from datetime import timedelta
from melange.common.exception import MelangeError
from melange.db import api as db_api
from melange.common import utils
@@ -335,8 +336,12 @@ class IpBlock(ModelBase):
ip_address.deallocate()
def delete_deallocated_ips(self):
db_api.delete_all(IpAddress.find_all(ip_block_id=self.id,
marked_for_deallocation=True))
db_api.delete_deallocated_ips(
deallocated_by=self._deallocated_by_date(), ip_block_id=self.id)
def _deallocated_by_date(self):
days_to_keep_ips = Config.get('keep_deallocated_ips_for_days', 2)
return utils.utcnow() - timedelta(days=days_to_keep_ips)
def subnet(self, cidr, network_id=None, tenant_id=None):
network_id = network_id or self.network_id
@@ -437,10 +442,11 @@ class IpAddress(ModelBase):
for local_address in ip_addresses])
def deallocate(self):
return self.update(marked_for_deallocation=True)
return self.update(marked_for_deallocation=True,
deallocated_at=utils.utcnow())
def restore(self):
self.update(marked_for_deallocation=False)
self.update(marked_for_deallocation=False, deallocated_at=None)
def inside_globals(self, **kwargs):
return db_api.find_inside_globals_for(self.id, **kwargs)

View File

@@ -16,7 +16,7 @@
# under the License.
from melange.tests import unit
from melange.tests import BaseTest
from datetime import datetime
from datetime import datetime, timedelta
from melange.ipam import models
from melange.db import session
from melange.tests.unit import StubConfig, StubTime
@@ -124,7 +124,7 @@ class TestIpv6AddressGeneratorFactory(BaseTest):
def test_loads_ipv6_generator_factory_from_config_file(self):
args = dict(tenant_id="1", mac_address="00:11:22:33:44:55")
with(StubConfig(ipv6_generator=self.mock_generatore_name)):
with StubConfig(ipv6_generator=self.mock_generatore_name):
ip_generator = models.ipv6_address_generator_factory("fe::/64",
**args)
@@ -145,7 +145,7 @@ class TestIpv6AddressGeneratorFactory(BaseTest):
models.ipv6_address_generator_factory, "fe::/64")
def test_does_not_raise_error_if_generator_does_not_require_params(self):
with(StubConfig(ipv6_generator=self.mock_generatore_name)):
with StubConfig(ipv6_generator=self.mock_generatore_name):
ip_generator = models.ipv6_address_generator_factory("fe::/64")
self.assertIsNotNone(ip_generator)
@@ -436,7 +436,7 @@ class TestIpBlock(BaseTest):
block = IpV6IpBlockFactory(cidr="ff::/120")
MockIpV6Generator.ip_list = ["ff::0001", "ff::0002"]
with(StubConfig(ipv6_generator=self.mock_generator_name)):
with StubConfig(ipv6_generator=self.mock_generator_name):
ip = block.allocate_ip()
self.assertEqual(ip.address, "00ff:0000:0000:0000:0000:0000:0000:0001")
@@ -446,7 +446,7 @@ class TestIpBlock(BaseTest):
MockIpV6Generator.ip_list = ["ff::0001", "ff::0002"]
IpAddressFactory(address="ff::0001", ip_block_id=block.id)
with(StubConfig(ipv6_generator=self.mock_generator_name)):
with StubConfig(ipv6_generator=self.mock_generator_name):
ip = block.allocate_ip()
self.assertEqual(ip.address, "00ff:0000:0000:0000:0000:0000:0000:0002")
@@ -584,32 +584,64 @@ class TestIpBlock(BaseTest):
self.assertModelsEqual(ip_block.subnets(), [subnet1, subnet2])
def test_delete_all_deallocated_addresses(self):
def test_delete_all_deallocated_ips_after_default_of_two_days(self):
ip_block1 = PrivateIpBlockFactory(cidr="10.0.1.1/29")
ip_block2 = PrivateIpBlockFactory(cidr="10.0.1.1/29")
current_time = datetime(2050, 1, 1)
two_days_before = current_time - timedelta(days=2)
ip1 = ip_block1.allocate_ip()
ip2 = ip_block2.allocate_ip()
ip1.deallocate()
ip2.deallocate()
with StubTime(time=two_days_before):
ip1.deallocate()
ip2.deallocate()
IpBlock.delete_all_deallocated_ips()
with StubTime(time=current_time):
IpBlock.delete_all_deallocated_ips()
self.assertEqual(IpAddress.find_all(
ip_block_id=ip_block1.id).all(), [])
self.assertEqual(IpAddress.find_all(
ip_block_id=ip_block2.id).all(), [])
def test_delete_deallocated_addresses(self):
def test_delete_deallocated_ips_after_default_of_two_days(self):
ip_block = PrivateIpBlockFactory(cidr="10.0.1.1/29")
current_time = datetime(2050, 1, 1)
two_days_before = current_time - timedelta(days=2)
ip1 = ip_block.allocate_ip()
ip2 = ip_block.allocate_ip()
ip3 = ip_block.allocate_ip()
with StubTime(time=two_days_before):
ip1.deallocate()
ip3.deallocate()
with StubTime(time=current_time):
ip_block.delete_deallocated_ips()
existing_ips = IpAddress.find_all(ip_block_id=ip_block.id).all()
self.assertModelsEqual(existing_ips, [ip2])
def test_delete_deallocated_ips_after_configured_no_of_days(self):
ip_block = PrivateIpBlockFactory(cidr="10.0.1.1/29")
ip1 = ip_block.allocate_ip()
ip2 = ip_block.allocate_ip()
ip3 = ip_block.allocate_ip()
ip1.deallocate()
ip3.deallocate()
ip4 = ip_block.allocate_ip()
current_time = datetime(2050, 1, 1)
one_day_before = current_time - timedelta(days=1)
two_days_before = current_time - timedelta(days=2)
with StubTime(time=two_days_before):
ip1.deallocate()
ip3.deallocate()
with StubTime(time=one_day_before):
ip4.deallocate()
with StubTime(time=current_time):
ip2.deallocate()
ip_block.delete_deallocated_ips()
existing_ips = IpAddress.find_all(ip_block_id=ip_block.id).all()
self.assertModelsEqual(existing_ips, [ip2])
with StubConfig(keep_deallocated_ips_for_days=1):
with StubTime(time=current_time):
ip_block.delete_deallocated_ips()
self.assertEqual(ip_block.addresses().all(), [ip2])
def test_is_full_flag_reset_when_addresses_are_deleted(self):
ip_block = PrivateIpBlockFactory(cidr="10.0.0.0/32")
@@ -794,11 +826,15 @@ class TestIpAddress(BaseTest):
def test_deallocate(self):
ip_block = PrivateIpBlockFactory(cidr="10.0.0.1/8")
ip_address = ip_block.allocate_ip()
current_time = datetime(2050, 1, 1)
ip_address.deallocate()
with StubTime(time=current_time):
ip_address.deallocate()
self.assertNotEqual(IpAddress.find(ip_address.id), None)
self.assertTrue(IpAddress.find(ip_address.id).marked_for_deallocation)
self.assertTrue(IpAddress.find(ip_address.id).deallocated_at,
current_time)
def test_restore(self):
ip_block = PrivateIpBlockFactory(cidr="10.0.0.1/29")
@@ -808,6 +844,7 @@ class TestIpAddress(BaseTest):
ip_address.restore()
self.assertFalse(ip_address.marked_for_deallocation)
self.assertIsNone(ip_address.deallocated_at)
def test_ip_block(self):
ip_block = PrivateIpBlockFactory()
@@ -837,7 +874,7 @@ class TestIpAddress(BaseTest):
ip_address = block.allocate_ip()
with(StubConfig(nameserver="ns.example.com")):
with StubConfig(nameserver="ns.example.com"):
data = ip_address.data_with_network_info()
self.assertEqual(data['broadcast_address'], "10.0.0.255")
@@ -1126,7 +1163,7 @@ class TestNetwork(BaseTest):
def test_find_or_create_when_no_ip_blocks_for_given_network_exist(self):
noise_ip_block = PublicIpBlockFactory(network_id=9999)
with(StubConfig(default_cidr="10.10.10.0/24")):
with StubConfig(default_cidr="10.10.10.0/24"):
network = Network.find_or_create_by(id='1', tenant_id='123')
self.assertEqual(network.id, '1')