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:
@@ -112,6 +112,14 @@ class PicNgoDDNS(DDNSProvider):
|
||||
# Public interface
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def release(self, token: str) -> bool:
|
||||
"""DELETE /api/v1/registration — release the subdomain owned by token."""
|
||||
url = f'{self.api_base_url}/api/v1/registration'
|
||||
resp = requests.delete(url, json={'token': token},
|
||||
headers=self._headers(), timeout=self.TIMEOUT)
|
||||
self._raise_for_status(resp, 'release')
|
||||
return True
|
||||
|
||||
def register(self, name: str, ip: str) -> dict:
|
||||
"""POST /api/v1/register — register subdomain, returns token + subdomain."""
|
||||
url = f'{self.api_base_url}/api/v1/register'
|
||||
@@ -398,6 +406,18 @@ class DDNSManager(BaseServiceManager):
|
||||
if not ip:
|
||||
ip = _get_public_ip() or ''
|
||||
|
||||
# Release the old subdomain if the name is changing and we hold a token
|
||||
if self.config_manager is not None and hasattr(provider, 'release'):
|
||||
old_token = self._ddns_cfg().get('token', '')
|
||||
old_domain = self._identity().get('domain_name', '')
|
||||
old_name = old_domain.replace('.pic.ngo', '') if old_domain else ''
|
||||
if old_token and old_name and old_name != name:
|
||||
try:
|
||||
provider.release(old_token)
|
||||
logger.info("DDNS released old subdomain %r before registering %r", old_name, name)
|
||||
except Exception as exc:
|
||||
logger.warning("DDNS could not release old subdomain %r: %s", old_name, exc)
|
||||
|
||||
result = provider.register(name, ip)
|
||||
|
||||
if self.config_manager is not None:
|
||||
|
||||
Reference in New Issue
Block a user