import argparse
import sys
-from typing import Any, Dict, List, Tuple, Type
+from enum import Enum
+from typing import Any, Dict, List, Optional, Tuple, Type
from knot_resolver_manager.cli.command import Command, CommandArgs, CompWords, register_command
from knot_resolver_manager.datamodel.cache_schema import CacheClearRPCSchema
from knot_resolver_manager.utils.requests import request
+class CacheOperations(Enum):
+ CLEAR = 0
+
+
@register_command
-class CacheClearCommand(Command):
+class CacheCommand(Command):
def __init__(self, namespace: argparse.Namespace) -> None:
super().__init__(namespace)
+ self.operation: Optional[CacheOperations] = namespace.operation if hasattr(namespace, "operation") else None
- config_dict: Dict[str, Any] = {"exact-name": namespace.exact_name}
-
+ # CLEAR operation
+ self.clear_dict: Dict[str, Any] = {}
+ if hasattr(namespace, "exact_name"):
+ self.clear_dict["exact-name"] = namespace.exact_name
if hasattr(namespace, "name"):
- config_dict["name"] = namespace.name
+ self.clear_dict["name"] = namespace.name
if hasattr(namespace, "rr_type"):
- config_dict["rr-type"] = namespace.rr_type
+ self.clear_dict["rr-type"] = namespace.rr_type
if hasattr(namespace, "chunk_size"):
- config_dict["chunk-size"] = namespace.chunk_size
-
- try:
- self.config = CacheClearRPCSchema(config_dict)
- except (AggregateDataValidationError, DataValidationError) as e:
- print(e, file=sys.stderr)
- sys.exit(1)
+ self.clear_dict["chunk-size"] = namespace.chunk_size
@staticmethod
def register_args_subparser(
subparser: "argparse._SubParsersAction[argparse.ArgumentParser]",
) -> Tuple[argparse.ArgumentParser, "Type[Command]"]:
- cache_clear = subparser.add_parser("cache-clear", help="Purge cache records matching specified criteria.")
- cache_clear.set_defaults(exact_name=False)
- cache_clear.add_argument(
+ cache_parser = subparser.add_parser("cache", help="Performs operations on the running resolver's cache.")
+
+ config_subparsers = cache_parser.add_subparsers(help="operation type")
+
+ # CLEAR operation
+ clear_subparser = config_subparsers.add_parser("clear", help="Purge cache records matching specified criteria.")
+ clear_subparser.set_defaults(operation=CacheOperations.CLEAR, exact_name=False)
+ clear_subparser.add_argument(
"--exact-name",
help="If set, only records with the same name are removed.",
action="store_true",
dest="exact_name",
)
- cache_clear.add_argument(
+ clear_subparser.add_argument(
"--rr-type",
help="Optional, you may additionally specify the type to remove, but that is only supported with '--exact-name' flag set.",
action="store",
type=str,
)
- cache_clear.add_argument(
+ clear_subparser.add_argument(
"--chunk-size",
help="Optional, the number of records to remove in one round; default: 100."
" The purpose is not to block the resolver for long. The resolver repeats the command after one millisecond until all matching data are cleared.",
type=int,
default=100,
)
- cache_clear.add_argument(
+ clear_subparser.add_argument(
"name",
type=str,
nargs="?",
default=None,
)
- return cache_clear, CacheClearCommand
+ return cache_parser, CacheCommand
@staticmethod
def completion(args: List[str], parser: argparse.ArgumentParser) -> CompWords:
return {}
def run(self, args: CommandArgs) -> None:
- body: str = DataFormat.JSON.dict_dump(self.config.get_unparsed_data())
- response = request(args.socket, "POST", "cache-clear", body)
+ if not self.operation:
+ args.subparser.print_help()
+ sys.exit()
+
+ if self.operation == CacheOperations.CLEAR:
+ try:
+ validated = CacheClearRPCSchema(self.clear_dict)
+ except (AggregateDataValidationError, DataValidationError) as e:
+ print(e, file=sys.stderr)
+ sys.exit(1)
+
+ body: str = DataFormat.JSON.dict_dump(validated.get_unparsed_data())
+ response = request(args.socket, "POST", "cache/clear", body)
if response.status != 200:
print(response, file=sys.stderr)
from knot_resolver_manager.constants import DEFAULT_MANAGER_CONFIG_FILE, PID_FILE_NAME, init_user_constants
from knot_resolver_manager.datamodel.cache_schema import CacheClearRPCSchema
from knot_resolver_manager.datamodel.config_schema import KresConfig, get_rundir_without_validation
-from knot_resolver_manager.datamodel.globals import (
- Context,
- set_global_validation_context,
-)
+from knot_resolver_manager.datamodel.globals import Context, set_global_validation_context
from knot_resolver_manager.datamodel.management_schema import ManagementSchema
from knot_resolver_manager.exceptions import CancelStartupExecInsteadException, KresManagerException
from knot_resolver_manager.kresd_controller import get_best_controller_implementation
web.get("/schema", self._handler_schema),
web.get("/schema/ui", self._handle_view_schema),
web.get("/metrics", self._handler_metrics),
- web.post("/cache-clear", self._handler_cache_clear),
+ web.post("/cache/clear", self._handler_cache_clear),
]
)