From 41bf7dd319966e3fa0182b88b0869ab13b52092e Mon Sep 17 00:00:00 2001 From: Michael Johnson Date: Mon, 16 Jan 2023 22:40:24 +0000 Subject: Workaround issue with dnspython >= 2.3.0 The dnspython module >= 2.3.0 now validates the opcodes used when building DNS messages. This breaks Designate because designate is using an "unassigned"[1] opcode 14 for command/control messages inside the backend agents framework. This patch adds a workaround to override the dnspython opcode enum to include opcode 14. This will give us time to either remove the agent framework via deprecation or to change the agent framework protocol to not rely on unassigned opcode values. [1] https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-5 Partial-Bug: #2002950 Change-Id: If10443b2e361aa1b467fb64124ad3c82540bcddd --- designate/agent/handler.py | 4 ++ designate/backend/agent.py | 4 ++ designate/backend/private_codes.py | 54 +++++++++++++++++++++- designate/tests/unit/agent/test_handler.py | 5 ++ ...ound-unassigned-opcode-14-d5e1c759db58bb10.yaml | 7 +++ 5 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/Workaround-unassigned-opcode-14-d5e1c759db58bb10.yaml diff --git a/designate/agent/handler.py b/designate/agent/handler.py index 7f45a1e6..638831c8 100644 --- a/designate/agent/handler.py +++ b/designate/agent/handler.py @@ -56,6 +56,10 @@ class RequestHandler(object): backend_driver = cfg.CONF['service:agent'].backend_driver self.backend = agent_backend.get_backend(backend_driver, self) + # TODO(johnsom) Remove this after the agents framework is removed or + # the protocol has been updated to not use an unassigned opcode(14). + dns.opcode.Opcode = pcodes.OpcodeWith14 + def __call__(self, request): """ :param request: DNS Request Message diff --git a/designate/backend/agent.py b/designate/backend/agent.py index ec44e276..d4675ec4 100644 --- a/designate/backend/agent.py +++ b/designate/backend/agent.py @@ -59,6 +59,10 @@ class AgentPoolBackend(base.Backend): self.max_retries = CONF['service:worker'].poll_max_retries # FIXME: the agent retries creating zones without any interval + # TODO(johnsom) Remove this after the agents framework is removed or + # the protocol has been updated to not use an unassigned opcode(14). + dns.opcode.Opcode = private_codes.OpcodeWith14 + def create_zone(self, context, zone): LOG.debug('Create Zone') response = self._make_and_send_dns_message( diff --git a/designate/backend/private_codes.py b/designate/backend/private_codes.py index e971da3f..42769fac 100644 --- a/designate/backend/private_codes.py +++ b/designate/backend/private_codes.py @@ -13,7 +13,7 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. - +import dns """ backend.private_codes @@ -33,3 +33,55 @@ SUCCESS = 65280 FAILURE = 65281 CREATE = 65282 DELETE = 65283 + +# TODO(johnsom) Remove this after the agents framework is removed or the +# protocol has been updated to not use an unassigned opcode(14). +# +# This is an Opcode Enum class that includes the unassigned[1][2] +# opcode 14 used in the Designate agent framework until the agent framework +# can be removed or fixed. +# [1] https://www.rfc-editor.org/rfc/rfc6895.html#section-2.2 +# [2] https://www.iana.org/assignments/dns-parameters/ \ +# dns-parameters.xhtml#dns-parameters-5 +# +# Based on dns.opcode.Opcode: +# +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license +# Copyright (C) 2001-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + +class OpcodeWith14(dns.enum.IntEnum): + #: Query + QUERY = 0 + #: Inverse Query (historical) + IQUERY = 1 + #: Server Status (unspecified and unimplemented anywhere) + STATUS = 2 + #: Notify + NOTIFY = 4 + #: Dynamic Update + UPDATE = 5 + + # Unassigned, but used by Designate for command/control in the agents + UNASSIGNED14 = 14 + + @classmethod + def _maximum(cls): + return 15 + + @classmethod + def _unknown_exception_class(cls): + return dns.opcode.UnknownOpcode diff --git a/designate/tests/unit/agent/test_handler.py b/designate/tests/unit/agent/test_handler.py index 97d3796a..643277f8 100644 --- a/designate/tests/unit/agent/test_handler.py +++ b/designate/tests/unit/agent/test_handler.py @@ -21,6 +21,7 @@ import dns.resolver import designate from designate.agent import handler +from designate.backend import private_codes import designate.tests @@ -35,6 +36,10 @@ class AgentRequestHandlerTest(designate.tests.TestCase): self.handler = handler.RequestHandler() self.addr = ['0.0.0.0', 5558] + # TODO(johnsom) Remove this after the agents framework is removed or + # the protocol has been updated to not use an unassigned opcode(14). + dns.opcode.Opcode = private_codes.OpcodeWith14 + def test_init(self): self.CONF.set_override('masters', ['192.168.0.1', '192.168.0.2'], 'service:agent') diff --git a/releasenotes/notes/Workaround-unassigned-opcode-14-d5e1c759db58bb10.yaml b/releasenotes/notes/Workaround-unassigned-opcode-14-d5e1c759db58bb10.yaml new file mode 100644 index 00000000..f24e3ba0 --- /dev/null +++ b/releasenotes/notes/Workaround-unassigned-opcode-14-d5e1c759db58bb10.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + Workaround the use of an unassigned opcode(14) by Designate that fails + validation when used with dnspython >= 2.3.0. + + `LP#2002950 `__ \ No newline at end of file -- cgit v1.2.1