diff --git a/atlas/service/doctype/ipv6_router_server/ipv6_router_server.py b/atlas/service/doctype/ipv6_router_server/ipv6_router_server.py index 4db0d62ee..40da70fb6 100644 --- a/atlas/service/doctype/ipv6_router_server/ipv6_router_server.py +++ b/atlas/service/doctype/ipv6_router_server/ipv6_router_server.py @@ -3,6 +3,7 @@ from __future__ import annotations +import ipaddress from contextlib import contextmanager from typing import TYPE_CHECKING, Any @@ -128,6 +129,9 @@ def archive(self) -> None: router.save(ignore_permissions=True) if pool: pool.gateway = None + # A direct provider pool hands out its whole prefix. + if pool.source == "Provider": + pool.allocation_prefix_length = ipaddress.ip_network(pool.prefix, strict=False).prefixlen pool.save(ignore_permissions=True) frappe.msgprint(_("IPv6 Router Server {0} is archived.").format(self.name)) diff --git a/atlas/service/doctype/ipv6_router_server/test_ipv6_router_server.py b/atlas/service/doctype/ipv6_router_server/test_ipv6_router_server.py index c062526a5..3c1a0d0e7 100644 --- a/atlas/service/doctype/ipv6_router_server/test_ipv6_router_server.py +++ b/atlas/service/doctype/ipv6_router_server/test_ipv6_router_server.py @@ -145,3 +145,19 @@ def test_archive_queues_the_pool_detach_instead_of_running_it(self) -> None: pool.queue_reconcile.assert_called_once_with() pool.reconcile.assert_not_called() self.assertEqual(router.status, "Archived") + + def test_archive_returns_a_provider_pool_to_one_allocation(self) -> None: + pool = MagicMock(source="Provider", prefix="2001:db8::/80", allocation_prefix_length=128) + router = MagicMock(status="Failed", virtual_machine=None, pool=pool) + with ( + patch.object(router_module, "_validate_system_manager"), + patch.object(router_module, "ipv6_router_lifecycle_lock", return_value=nullcontext()), + patch.object(router_module.frappe, "get_doc", return_value=router), + patch.object(router_module.frappe.db, "exists", return_value=False), + patch.object(router_module.frappe, "msgprint"), + ): + IPv6RouterServer.archive(SimpleNamespace(doctype="IPv6 Router Server", name="ipv6-router-001")) + + self.assertIsNone(pool.gateway) + self.assertEqual(pool.allocation_prefix_length, 80) + pool.save.assert_called_once_with(ignore_permissions=True)