69 lines
2.1 KiB
Python
69 lines
2.1 KiB
Python
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
|
#
|
|
# SPDX-License-Identifier: MPL-2.0
|
|
#
|
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
|
#
|
|
# See the COPYRIGHT file distributed with this work for additional
|
|
# information regarding copyright ownership.
|
|
|
|
import abc
|
|
import os
|
|
import subprocess
|
|
|
|
|
|
class RNDCExecutor(abc.ABC):
|
|
"""
|
|
An interface which RNDC executors have to implement in order for the
|
|
`NamedInstance` class to be able to use them.
|
|
"""
|
|
|
|
@abc.abstractmethod
|
|
def call(self, ip: str, port: int, command: str) -> str:
|
|
"""
|
|
Send RNDC `command` to the `named` instance at `ip:port` and return the
|
|
server's response.
|
|
"""
|
|
|
|
|
|
class RNDCException(Exception):
|
|
"""
|
|
Raised by classes implementing the `RNDCExecutor` interface when sending an
|
|
RNDC command fails for any reason.
|
|
"""
|
|
|
|
|
|
class RNDCBinaryExecutor(RNDCExecutor):
|
|
"""
|
|
An `RNDCExecutor` which sends RNDC commands to servers using the `rndc`
|
|
binary.
|
|
"""
|
|
|
|
def __init__(self) -> None:
|
|
"""
|
|
This class needs the `RNDC` environment variable to be set to the path
|
|
to the `rndc` binary to use.
|
|
"""
|
|
rndc_path = os.environ.get("RNDC", "/bin/false")
|
|
rndc_conf = os.path.join("..", "_common", "rndc.conf")
|
|
self._base_cmdline = [rndc_path, "-c", rndc_conf]
|
|
|
|
def call(self, ip: str, port: int, command: str) -> str:
|
|
"""
|
|
Send RNDC `command` to the `named` instance at `ip:port` and return the
|
|
server's response.
|
|
"""
|
|
cmdline = self._base_cmdline[:]
|
|
cmdline.extend(["-s", ip])
|
|
cmdline.extend(["-p", str(port)])
|
|
cmdline.extend(command.split())
|
|
|
|
try:
|
|
return subprocess.check_output(
|
|
cmdline, stderr=subprocess.STDOUT, timeout=10, encoding="utf-8"
|
|
)
|
|
except subprocess.SubprocessError as exc:
|
|
msg = getattr(exc, "output", "RNDC exception occurred")
|
|
raise RNDCException(msg) from exc
|