modified: pyproject.toml
Fix paths after restructuring renamed: netbox_dns_bridge/management/commands/export-dns-zone.py -> netbox_dns_bridge/management/commands/dns-export-zone.py renamed: netbox_dns_bridge/management/commands/export-all-dns-zones.py -> netbox_dns_bridge/management/commands/dns-export-zones.py Unify command naming scheme new file: netbox_dns_bridge/migrations/0001_initial.py Adds the missing migration. Since the plugin was renamed this is also an opportunity to merge all changes into a single migration. renamed: netbox_dns_bridge/service/transfer/catalog_zone_manager.py -> netbox_dns_bridge/catalog_zone_manager.py renamed: netbox_dns_bridge/service/transfer/dns_server.py -> netbox_dns_bridge/dns_server.py new file: netbox_dns_bridge/management/commands/dns-settings.py modified: netbox_dns_bridge/management/commands/dns-transfer-endpoint.py renamed: netbox_dns_bridge/service/transfer/request_handler.py -> netbox_dns_bridge/request_handler.py deleted: netbox_dns_bridge/service/transfer/__init__.py Another restructure to simplify code re-use. New command dns-settings added to allow setting of catalog zone serial. This will be needed to migrate from previous versions.
This commit is contained in:
1 parent
5f48472ba4
commit
f713719543
10 files changed
+106
-16
No files matched your search
+10
-6
@@ -16,7 +16,7 @@ from netbox_dns_bridge.models import IntegerKeyValueSetting, CatalogZoneMemberId
|
|||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
from base64 import b32encode
|
from base64 import b32encode
|
||||||
|
|
||||||
logger = logging.getLogger("dns-transfer-endpoint")
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
_LOCK = threading.Lock()
|
_LOCK = threading.Lock()
|
||||||
_SERIAL_MAX = 0xFFFFFFFF
|
_SERIAL_MAX = 0xFFFFFFFF
|
||||||
@@ -47,18 +47,22 @@ def _init_serial() -> None:
|
|||||||
f"Catalog zone SOA serial number was not set in the database. Set to {_SERIAL_OBJ.value}"
|
f"Catalog zone SOA serial number was not set in the database. Set to {_SERIAL_OBJ.value}"
|
||||||
)
|
)
|
||||||
|
|
||||||
def _increment_serial() -> None:
|
def _set_serial(new_serial: int) -> bool:
|
||||||
global _SERIAL_OBJ
|
global _SERIAL_OBJ
|
||||||
|
|
||||||
if 0 < _SERIAL_OBJ.value < _SERIAL_MAX:
|
if (0 < new_serial < _SERIAL_MAX):
|
||||||
_SERIAL_OBJ.value += 1
|
_SERIAL_OBJ.value = new_serial
|
||||||
_SERIAL_OBJ.save()
|
_SERIAL_OBJ.save()
|
||||||
|
return True
|
||||||
else:
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _increment_serial() -> None:
|
||||||
|
if not _set_serial( _SERIAL_OBJ.value + 1 ):
|
||||||
logger.warning(
|
logger.warning(
|
||||||
f"Failed to incremenet catalog serial {_SERIAL_OBJ.value}. Will overflow serial back to 1"
|
f"Failed to incremenet catalog serial {_SERIAL_OBJ.value}. Will overflow serial back to 1"
|
||||||
)
|
)
|
||||||
_SERIAL_OBJ.value = 1
|
_set_serial(1)
|
||||||
_SERIAL_OBJ.save()
|
|
||||||
logger.debug(
|
logger.debug(
|
||||||
f"Catalog zone SOA serial number incremented to {_SERIAL_OBJ.value}"
|
f"Catalog zone SOA serial number incremented to {_SERIAL_OBJ.value}"
|
||||||
)
|
)
|
||||||
@@ -2,7 +2,7 @@ import logging
|
|||||||
import socketserver
|
import socketserver
|
||||||
import socket
|
import socket
|
||||||
|
|
||||||
logger = logging.getLogger("dns-transfer-endpoint")
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class DNSAddressMixin:
|
class DNSAddressMixin:
|
||||||
def _resolve_address(self, server_address, socktype, proto):
|
def _resolve_address(self, server_address, socktype, proto):
|
||||||
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,47 @@
|
|||||||
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
|
from netbox_dns_bridge.models import IntegerKeyValueSetting
|
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = "Get or set integer key-value settings"
|
||||||
|
|
||||||
|
def add_arguments(self, parser):
|
||||||
|
parser.add_argument("action", choices=["get", "set", "list"], help="Action to perform")
|
||||||
|
parser.add_argument("key", nargs="?", help="Setting key")
|
||||||
|
parser.add_argument("value", nargs="?", type=int, help="Value to set (required for 'set')")
|
||||||
|
|
||||||
|
def handle(self, *args, **options):
|
||||||
|
action = options["action"]
|
||||||
|
key = options.get("key")
|
||||||
|
value = options.get("value")
|
||||||
|
|
||||||
|
if action == "list":
|
||||||
|
settings = IntegerKeyValueSetting.objects.all()
|
||||||
|
if not settings.exists():
|
||||||
|
self.stdout.write("No settings found.")
|
||||||
|
return
|
||||||
|
for setting in settings:
|
||||||
|
self.stdout.write(str(setting))
|
||||||
|
|
||||||
|
elif action == "get":
|
||||||
|
if not key:
|
||||||
|
raise CommandError("A key is required for GET")
|
||||||
|
try:
|
||||||
|
setting = IntegerKeyValueSetting.objects.get(key=key)
|
||||||
|
self.stdout.write(f"{setting.key}: {setting.value}")
|
||||||
|
except IntegerKeyValueSetting.DoesNotExist:
|
||||||
|
raise CommandError(f"No setting was found for {key}")
|
||||||
|
|
||||||
|
elif action == "set":
|
||||||
|
if not key:
|
||||||
|
raise CommandError("A setting is required for SET command")
|
||||||
|
if value is None:
|
||||||
|
raise CommandError("A value is required for SET command")
|
||||||
|
try:
|
||||||
|
setting = IntegerKeyValueSetting.objects.get(key=key)
|
||||||
|
old_value = setting.value
|
||||||
|
setting.value = value
|
||||||
|
setting.save()
|
||||||
|
self.stdout.write(f"Updated {key} from {old_value} to {value}")
|
||||||
|
except IntegerKeyValueSetting.DoesNotExist:
|
||||||
|
raise CommandError(f"No setting found for {key}")
|
||||||
@@ -14,11 +14,12 @@ import dns.renderer
|
|||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from netbox_dns.models import View
|
from netbox_dns.models import View
|
||||||
from netbox_dns_bridge.service.endpoint.request_handler import UDPRequestHandler, TCPRequestHandler
|
from netbox_dns_bridge.request_handler import UDPRequestHandler, TCPRequestHandler
|
||||||
from netbox_dns_bridge.service.endpoint.dns_server import UDPDNSServer, TCPDNSServer
|
from netbox_dns_bridge.dns_server import UDPDNSServer, TCPDNSServer
|
||||||
from netbox_dns_bridge.service.endpoint import catalog_zone_manager as catzm
|
from netbox_dns_bridge import catalog_zone_manager as catzm
|
||||||
|
from netbox_dns_bridge.models import IntegerKeyValueSetting
|
||||||
|
|
||||||
logger = logging.getLogger("dns-transfer-endpoint")
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = "Run a minimal AXFR DNS server using data from NetBox DNS plugin"
|
help = "Run a minimal AXFR DNS server using data from NetBox DNS plugin"
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
# Generated by Django 5.2.9 on 2026-04-08 11:29
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('netbox_dns', '0030_dnsseckeytemplate_comments_dnsseckeytemplate_owner_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='IntegerKeyValueSetting',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
|
||||||
|
('key', models.CharField(max_length=64)),
|
||||||
|
('value', models.IntegerField()),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'default_permissions': (),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='CatalogZoneMemberIdentifier',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
|
||||||
|
('name', models.CharField(max_length=26, unique=True)),
|
||||||
|
('zone', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='catz_identifier', to='netbox_dns.zone')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'ordering': ('name',),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
+3
-3
@@ -13,9 +13,9 @@ import dns.exception
|
|||||||
import dns.renderer
|
import dns.renderer
|
||||||
from netbox_dns.models import Zone, Record
|
from netbox_dns.models import Zone, Record
|
||||||
from netbox_dns.choices import ZoneStatusChoices, RecordStatusChoices
|
from netbox_dns.choices import ZoneStatusChoices, RecordStatusChoices
|
||||||
from . import catalog_zone_manager as catzm
|
from netbox_dns_bridge import catalog_zone_manager as catzm
|
||||||
|
|
||||||
logger = logging.getLogger("dns-transfer-endpoint")
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class DNSBaseRequestHandler(socketserver.BaseRequestHandler):
|
class DNSBaseRequestHandler(socketserver.BaseRequestHandler):
|
||||||
@@ -131,7 +131,7 @@ class DNSBaseRequestHandler(socketserver.BaseRequestHandler):
|
|||||||
keyname=query.keyname,
|
keyname=query.keyname,
|
||||||
tsig_error=tsig_error,
|
tsig_error=tsig_error,
|
||||||
)
|
)
|
||||||
self.denyRequest(query)
|
self._denyRequest(query)
|
||||||
|
|
||||||
def _send_response(self, data) -> None:
|
def _send_response(self, data) -> None:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
Whitespace-only changes.
+2
-2
@@ -20,10 +20,10 @@ dependencies = [
|
|||||||
[tool.setuptools]
|
[tool.setuptools]
|
||||||
include-package-data = true
|
include-package-data = true
|
||||||
zip-safe = false
|
zip-safe = false
|
||||||
package-dir = { "" = "netbox_dns_bridge" }
|
package-dir = { "" = "." }
|
||||||
|
|
||||||
[tool.setuptools.packages.find]
|
[tool.setuptools.packages.find]
|
||||||
where = ["netbox_dns_bridge"]
|
where = ["."]
|
||||||
|
|
||||||
[tool.setuptools.dynamic]
|
[tool.setuptools.dynamic]
|
||||||
version = { attr = "netbox_dns_bridge.__version__" }
|
version = { attr = "netbox_dns_bridge.__version__" }
|
||||||
|
|||||||
Reference in new issue
Block a user