feat: release old pic.ngo subdomain when cell name changes
Unit Tests / test (push) Successful in 15m45s
Unit Tests / test (push) Successful in 15m45s
Adds DELETE /api/v1/registration to the DDNS server (token-authenticated, owner-only) and PicNgoDDNS.release() on the client. DDNSManager.register() now automatically releases the old subdomain before claiming the new one, so stale names are freed for others to use. Release failures are logged as warnings and do not block the new registration. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -352,6 +352,60 @@ class TestRegister(unittest.TestCase):
|
||||
mock_ip.assert_not_called()
|
||||
mock_provider.register.assert_called_once_with('alpha', '1.2.3.4')
|
||||
|
||||
def test_register_releases_old_name_when_changing(self):
|
||||
cm = _make_config_manager(ddns_cfg={'provider': 'pic_ngo', 'token': 'old_tok'})
|
||||
cm.get_identity.return_value = {'domain_name': 'oldname.pic.ngo'}
|
||||
mgr = DDNSManager(config_manager=cm)
|
||||
|
||||
mock_provider = MagicMock()
|
||||
mock_provider.register.return_value = {'token': 'new_tok', 'subdomain': 'newname.pic.ngo'}
|
||||
mgr.get_provider = MagicMock(return_value=mock_provider)
|
||||
|
||||
mgr.register('newname', '1.2.3.4')
|
||||
|
||||
mock_provider.release.assert_called_once_with('old_tok')
|
||||
mock_provider.register.assert_called_once_with('newname', '1.2.3.4')
|
||||
|
||||
def test_register_skips_release_when_name_unchanged(self):
|
||||
cm = _make_config_manager(ddns_cfg={'provider': 'pic_ngo', 'token': 'tok'})
|
||||
cm.get_identity.return_value = {'domain_name': 'alpha.pic.ngo'}
|
||||
mgr = DDNSManager(config_manager=cm)
|
||||
|
||||
mock_provider = MagicMock()
|
||||
mock_provider.register.return_value = {'token': 'tok2', 'subdomain': 'alpha.pic.ngo'}
|
||||
mgr.get_provider = MagicMock(return_value=mock_provider)
|
||||
|
||||
mgr.register('alpha', '1.2.3.4')
|
||||
|
||||
mock_provider.release.assert_not_called()
|
||||
|
||||
def test_register_skips_release_when_no_old_token(self):
|
||||
cm = _make_config_manager(ddns_cfg={'provider': 'pic_ngo'})
|
||||
cm.get_identity.return_value = {'domain_name': 'oldname.pic.ngo'}
|
||||
mgr = DDNSManager(config_manager=cm)
|
||||
|
||||
mock_provider = MagicMock()
|
||||
mock_provider.register.return_value = {'token': 'new_tok', 'subdomain': 'newname.pic.ngo'}
|
||||
mgr.get_provider = MagicMock(return_value=mock_provider)
|
||||
|
||||
mgr.register('newname', '1.2.3.4')
|
||||
|
||||
mock_provider.release.assert_not_called()
|
||||
|
||||
def test_register_continues_if_release_fails(self):
|
||||
cm = _make_config_manager(ddns_cfg={'provider': 'pic_ngo', 'token': 'old_tok'})
|
||||
cm.get_identity.return_value = {'domain_name': 'oldname.pic.ngo'}
|
||||
mgr = DDNSManager(config_manager=cm)
|
||||
|
||||
mock_provider = MagicMock()
|
||||
mock_provider.release.side_effect = DDNSError("server down")
|
||||
mock_provider.register.return_value = {'token': 'new_tok', 'subdomain': 'newname.pic.ngo'}
|
||||
mgr.get_provider = MagicMock(return_value=mock_provider)
|
||||
|
||||
result = mgr.register('newname', '1.2.3.4')
|
||||
self.assertEqual(result['token'], 'new_tok')
|
||||
mock_provider.register.assert_called_once()
|
||||
|
||||
def test_register_raises_when_no_provider(self):
|
||||
cm = _make_config_manager()
|
||||
mgr = DDNSManager(config_manager=cm)
|
||||
|
||||
Reference in New Issue
Block a user