From 8f5cc5896c02cc9346fe67bf60a921b2e5234699 Mon Sep 17 00:00:00 2001 From: iyashnov Date: Thu, 5 Mar 2026 19:25:51 +0300 Subject: [PATCH 1/3] fix: changed rule type for dnsdist domain rule --- .../dns/clients/power_dnsdist_client.py | 42 ++++++------------- 1 file changed, 13 insertions(+), 29 deletions(-) diff --git a/app/ldap_protocol/dns/clients/power_dnsdist_client.py b/app/ldap_protocol/dns/clients/power_dnsdist_client.py index 4e869527b..1c7952aa2 100644 --- a/app/ldap_protocol/dns/clients/power_dnsdist_client.py +++ b/app/ldap_protocol/dns/clients/power_dnsdist_client.py @@ -160,18 +160,7 @@ def add_zone_rule(self, domain: str) -> None: """Add rule to redirect master zone DNS requests to auth server.""" command = f""" addAction( - QNameRule("*.{domain}"), - PoolAction("master") - ) - """ - self._send_command( - command, - expected=DNSdistCommandTypes.GENERIC, - ) - - command = f""" - addAction( - QNameRule("{domain}"), + QNameSuffixRule("{domain}"), PoolAction("master") ) """ @@ -186,24 +175,19 @@ def add_zone_rule(self, domain: str) -> None: def remove_zone_rule(self, domain: str) -> None: """Remove redirect rule from dnsdist.""" - rule_matches = [ - f"qname=={domain}", - f"qname==*.{domain}", - ] - for rule_match in rule_matches: - rules = self._get_all_rules() - if not rules.count: - DNSdistError( - "Failed to delete existing rule in dnsdist: Not Found", - ) + rules = self._get_all_rules() + if not rules.count: + DNSdistError( + "Failed to delete existing rule in dnsdist: Not Found", + ) - for rule in rules.rules: - if rule.match == rule_match: - command = f"rmRule({rule.id})" - self._send_command( - command, - expected=DNSdistCommandTypes.GENERIC, - ) + for rule in rules.rules: + if domain in rule.match: + command = f"rmRule({rule.id})" + self._send_command( + command, + expected=DNSdistCommandTypes.GENERIC, + ) self._persist_config() From 0fc97feffdae8aea08106ad87fe9f90fd519590c Mon Sep 17 00:00:00 2001 From: iyashnov Date: Fri, 6 Mar 2026 11:52:30 +0300 Subject: [PATCH 2/3] fix: enhance record name stripping and forwarders handling in BIND migration --- .../dns/bind_to_pdns_migration_use_case.py | 44 +++++++++++++++---- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/app/ldap_protocol/dns/bind_to_pdns_migration_use_case.py b/app/ldap_protocol/dns/bind_to_pdns_migration_use_case.py index 07824ac2a..66512ee1f 100644 --- a/app/ldap_protocol/dns/bind_to_pdns_migration_use_case.py +++ b/app/ldap_protocol/dns/bind_to_pdns_migration_use_case.py @@ -32,6 +32,19 @@ def __init__( self.pdns_manager = pdns_manager self.dns_settings = dns_settings + def _strip_record_name(self, record_name: str, zone_name: str) -> str: + """Strip trash from record name.""" + if ( + record_name.startswith(("\\032", "\\@", "\\\\")) + and record_name != "\\\\@" + ): + record_name = record_name.strip("\\").strip("\\032").strip("\\@") + elif record_name == "\\\\@": + record_name = zone_name + return ( + record_name if not record_name.startswith(".") else record_name[1:] + ) + def parse_bind_config_file( self, ) -> tuple[list[DNSMasterZoneDTO], list[DNSForwardZoneDTO]]: @@ -58,12 +71,24 @@ def parse_bind_config_file( ), ) elif "type forward" in line: - forward_zones.append( - DNSForwardZoneDTO( - id=zone_name, - name=zone_name, - ), + forward_zone = DNSForwardZoneDTO( + id=zone_name, + name=zone_name, ) + elif "forwarders" in line and forward_zone: + forwarders_part = line.split("forwarders")[1] + forwarders = [ + f + for f in forwarders_part.strip(";") + .strip(" ") + .strip("{") + .strip("}") + .strip(" ") + .split(";")[:-1] + ] + forward_zone.servers = forwarders + forward_zones.append(forward_zone) + forward_zone = None return master_zones, forward_zones @@ -94,7 +119,7 @@ def parse_zones_records( for name, ttl, rdata in zone_obj.iterate_rdatas(): try: - DNSRecordType(rdata.rdtype.name) + record_type = DNSRecordType(rdata.rdtype.name) except ValueError: logger.warning( f"Unsupported DNS record type {rdata.rdtype.name} in zone '{zone.name}'", # noqa: E501 @@ -103,8 +128,11 @@ def parse_zones_records( zone_rrsets.append( DNSRRSetDTO( - name=name.to_text(), - type=DNSRecordType(rdata.rdtype.name), + name=self._strip_record_name( + name.to_text(), + zone.name, + ), + type=record_type, records=[ DNSRecordDTO( content=rdata.to_text(), From 984c877ef57a0e9110ef4efa3f889c696d3d605d Mon Sep 17 00:00:00 2001 From: iyashnov Date: Fri, 6 Mar 2026 12:25:38 +0300 Subject: [PATCH 3/3] fix: improve record name stripping logic and handle DNSdist rule deletion more accurately --- .../dns/bind_to_pdns_migration_use_case.py | 12 ++++++------ .../dns/clients/power_dnsdist_client.py | 6 ++++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/app/ldap_protocol/dns/bind_to_pdns_migration_use_case.py b/app/ldap_protocol/dns/bind_to_pdns_migration_use_case.py index 66512ee1f..be208d12e 100644 --- a/app/ldap_protocol/dns/bind_to_pdns_migration_use_case.py +++ b/app/ldap_protocol/dns/bind_to_pdns_migration_use_case.py @@ -34,12 +34,12 @@ def __init__( def _strip_record_name(self, record_name: str, zone_name: str) -> str: """Strip trash from record name.""" - if ( - record_name.startswith(("\\032", "\\@", "\\\\")) - and record_name != "\\\\@" - ): - record_name = record_name.strip("\\").strip("\\032").strip("\\@") - elif record_name == "\\\\@": + logger.debug( + f"Stripping record name '{record_name}' for zone '{zone_name}'", + ) + if record_name.startswith(("\\032", "\\@")) and record_name != "\\@": + record_name = record_name.removeprefix("\\032").removeprefix("\\@") + elif record_name == "\\@": record_name = zone_name return ( record_name if not record_name.startswith(".") else record_name[1:] diff --git a/app/ldap_protocol/dns/clients/power_dnsdist_client.py b/app/ldap_protocol/dns/clients/power_dnsdist_client.py index 1c7952aa2..1e13899f4 100644 --- a/app/ldap_protocol/dns/clients/power_dnsdist_client.py +++ b/app/ldap_protocol/dns/clients/power_dnsdist_client.py @@ -177,12 +177,14 @@ def remove_zone_rule(self, domain: str) -> None: """Remove redirect rule from dnsdist.""" rules = self._get_all_rules() if not rules.count: - DNSdistError( + raise DNSdistError( "Failed to delete existing rule in dnsdist: Not Found", ) for rule in rules.rules: - if domain in rule.match: + rule_match = rule.match.split(" ")[-1] + domain_match = domain if domain.endswith(".") else f"{domain}." + if domain_match == rule_match: command = f"rmRule({rule.id})" self._send_command( command,