mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-09-01 22:45:18 +00:00
[1843] add a builtin command set for execute
moved exception catching around a bit, so the set does not get completed if one of its steps fails
This commit is contained in:
@@ -8,7 +8,7 @@ EXTRA_DIST = $(man_MANS) bindctl.xml
|
|||||||
noinst_SCRIPTS = run_bindctl.sh
|
noinst_SCRIPTS = run_bindctl.sh
|
||||||
|
|
||||||
python_PYTHON = __init__.py bindcmd.py cmdparse.py exception.py moduleinfo.py \
|
python_PYTHON = __init__.py bindcmd.py cmdparse.py exception.py moduleinfo.py \
|
||||||
mycollections.py
|
mycollections.py command_sets.py
|
||||||
pythondir = $(pyexecdir)/bindctl
|
pythondir = $(pyexecdir)/bindctl
|
||||||
|
|
||||||
bindctldir = $(pkgdatadir)
|
bindctldir = $(pkgdatadir)
|
||||||
|
@@ -23,6 +23,7 @@ from cmd import Cmd
|
|||||||
from bindctl.exception import *
|
from bindctl.exception import *
|
||||||
from bindctl.moduleinfo import *
|
from bindctl.moduleinfo import *
|
||||||
from bindctl.cmdparse import BindCmdParse
|
from bindctl.cmdparse import BindCmdParse
|
||||||
|
import command_sets
|
||||||
from xml.dom import minidom
|
from xml.dom import minidom
|
||||||
import isc
|
import isc
|
||||||
import isc.cc.data
|
import isc.cc.data
|
||||||
@@ -410,18 +411,8 @@ class BindCmdInterpreter(Cmd):
|
|||||||
if cmd.command == "help" or ("help" in cmd.params.keys()):
|
if cmd.command == "help" or ("help" in cmd.params.keys()):
|
||||||
self._handle_help(cmd)
|
self._handle_help(cmd)
|
||||||
elif cmd.module == CONFIG_MODULE_NAME:
|
elif cmd.module == CONFIG_MODULE_NAME:
|
||||||
try:
|
self.apply_config_cmd(cmd)
|
||||||
self.apply_config_cmd(cmd)
|
|
||||||
except isc.cc.data.DataTypeError as dte:
|
|
||||||
print("Error: " + str(dte))
|
|
||||||
except isc.cc.data.DataNotFoundError as dnfe:
|
|
||||||
print("Error: " + str(dnfe))
|
|
||||||
except isc.cc.data.DataAlreadyPresentError as dape:
|
|
||||||
print("Error: " + str(dape))
|
|
||||||
except KeyError as ke:
|
|
||||||
print("Error: missing " + str(ke))
|
|
||||||
elif cmd.module == EXECUTE_MODULE_NAME:
|
elif cmd.module == EXECUTE_MODULE_NAME:
|
||||||
# TODO: catch errors
|
|
||||||
self.apply_execute_cmd(cmd)
|
self.apply_execute_cmd(cmd)
|
||||||
else:
|
else:
|
||||||
self.apply_cmd(cmd)
|
self.apply_cmd(cmd)
|
||||||
@@ -581,6 +572,14 @@ class BindCmdInterpreter(Cmd):
|
|||||||
self._print_correct_usage(err)
|
self._print_correct_usage(err)
|
||||||
except isc.cc.data.DataTypeError as err:
|
except isc.cc.data.DataTypeError as err:
|
||||||
print("Error! ", err)
|
print("Error! ", err)
|
||||||
|
except isc.cc.data.DataTypeError as dte:
|
||||||
|
print("Error: " + str(dte))
|
||||||
|
except isc.cc.data.DataNotFoundError as dnfe:
|
||||||
|
print("Error: " + str(dnfe))
|
||||||
|
except isc.cc.data.DataAlreadyPresentError as dape:
|
||||||
|
print("Error: " + str(dape))
|
||||||
|
except KeyError as ke:
|
||||||
|
print("Error: missing " + str(ke))
|
||||||
|
|
||||||
def _print_correct_usage(self, ept):
|
def _print_correct_usage(self, ept):
|
||||||
if isinstance(ept, CmdUnknownModuleSyntaxError):
|
if isinstance(ept, CmdUnknownModuleSyntaxError):
|
||||||
@@ -737,14 +736,38 @@ class BindCmdInterpreter(Cmd):
|
|||||||
'''Handles the 'execute' command, which executes a number of
|
'''Handles the 'execute' command, which executes a number of
|
||||||
(preset) statements. Currently only 'file' commands are supported,
|
(preset) statements. Currently only 'file' commands are supported,
|
||||||
e.g. 'execute file <file>'.'''
|
e.g. 'execute file <file>'.'''
|
||||||
try:
|
if command.command == 'file':
|
||||||
command_file = open(command.params['filename'])
|
try:
|
||||||
self.apply_commands_from_file(command_file)
|
command_file = open(command.params['filename'])
|
||||||
except IOError as ioe:
|
# copy them into a list for consistency with the built-in
|
||||||
print("Error: " + str(ioe))
|
# sets of commands
|
||||||
|
commands = []
|
||||||
|
for line in command_file:
|
||||||
|
commands.append(line)
|
||||||
|
command_file.close()
|
||||||
|
except IOError as ioe:
|
||||||
|
print("Error: " + str(ioe))
|
||||||
|
return
|
||||||
|
elif command.command == 'init_authoritative_server':
|
||||||
|
commands = command_sets.init_auth_server
|
||||||
|
else:
|
||||||
|
# Should not be reachable; parser should've caught this
|
||||||
|
raise Exception("Unknown execute command type " + command.command)
|
||||||
|
|
||||||
def apply_commands_from_file(self, command_file):
|
# We have our set of commands now, depending on whether 'show' was
|
||||||
'''Applies the configuration commands from the given opened file.
|
# specified, show or execute them
|
||||||
|
if 'show' in command.params and command.params['show'] == 'show':
|
||||||
|
self.__show_execute_commands(commands)
|
||||||
|
else:
|
||||||
|
self.__apply_execute_commands(commands)
|
||||||
|
|
||||||
|
def __show_execute_commands(self, commands):
|
||||||
|
'''Prints the command list without executing them'''
|
||||||
|
for line in commands:
|
||||||
|
print(line.strip())
|
||||||
|
|
||||||
|
def __apply_execute_commands(self, commands):
|
||||||
|
'''Applies the configuration commands from the given iterator.
|
||||||
This is the method that catches, comments, echo statements, and
|
This is the method that catches, comments, echo statements, and
|
||||||
other directives. All commands not filtered by this method are
|
other directives. All commands not filtered by this method are
|
||||||
interpreted as if they are directly entered in an active session.
|
interpreted as if they are directly entered in an active session.
|
||||||
@@ -759,7 +782,7 @@ class BindCmdInterpreter(Cmd):
|
|||||||
'''
|
'''
|
||||||
verbose = False
|
verbose = False
|
||||||
try:
|
try:
|
||||||
for line in command_file:
|
for line in commands:
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
if verbose:
|
if verbose:
|
||||||
print(line)
|
print(line)
|
||||||
@@ -781,7 +804,10 @@ class BindCmdInterpreter(Cmd):
|
|||||||
except isc.config.ModuleCCSessionError as mcse:
|
except isc.config.ModuleCCSessionError as mcse:
|
||||||
print(str(mcse))
|
print(str(mcse))
|
||||||
except (IOError, http.client.HTTPException,
|
except (IOError, http.client.HTTPException,
|
||||||
BindCtlException, isc.cc.data.DataTypeError) as err:
|
BindCtlException, isc.cc.data.DataTypeError,
|
||||||
|
isc.cc.data.DataNotFoundError,
|
||||||
|
isc.cc.data.DataAlreadyPresentError,
|
||||||
|
KeyError) as err:
|
||||||
print('Error: ', err)
|
print('Error: ', err)
|
||||||
|
|
||||||
def apply_cmd(self, cmd):
|
def apply_cmd(self, cmd):
|
||||||
|
@@ -103,13 +103,33 @@ def prepare_config_commands(tool):
|
|||||||
|
|
||||||
tool.add_module_info(module)
|
tool.add_module_info(module)
|
||||||
|
|
||||||
|
def prepare_execute_commands(tool):
|
||||||
|
# common parameter
|
||||||
|
param_show = ParamInfo(name="show", type="string", optional=True,
|
||||||
|
desc="Show the list of commands without executing them")
|
||||||
|
|
||||||
|
# The command module
|
||||||
module = ModuleInfo(name=EXECUTE_MODULE_NAME,
|
module = ModuleInfo(name=EXECUTE_MODULE_NAME,
|
||||||
desc="Execute a given set of commands")
|
desc="Execute a given set of commands")
|
||||||
|
|
||||||
|
# Command to execute a file
|
||||||
cmd = CommandInfo(name="file", desc="Read commands from file")
|
cmd = CommandInfo(name="file", desc="Read commands from file")
|
||||||
param = ParamInfo(name="filename", type="string", optional=False,
|
param = ParamInfo(name="filename", type="string", optional=False,
|
||||||
desc="File to read the set of commands from.")
|
desc="File to read the set of commands from.")
|
||||||
cmd.add_param(param)
|
cmd.add_param(param)
|
||||||
|
cmd.add_param(param_show)
|
||||||
module.add_command(cmd)
|
module.add_command(cmd)
|
||||||
|
|
||||||
|
cmd = CommandInfo(name="init_authoritative_server", desc=
|
||||||
|
"Configure and run a basic Authoritative server, with default "
|
||||||
|
"SQLite3 backend, and xfrin and xfrout functionality")
|
||||||
|
cmd.add_param(param_show)
|
||||||
|
cmd.add_param(ParamInfo(name="show", type="string", optional=True,
|
||||||
|
desc="Show the list of commands without executing them"))
|
||||||
|
module.add_command(cmd)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
tool.add_module_info(module)
|
tool.add_module_info(module)
|
||||||
|
|
||||||
def check_port(option, opt_str, value, parser):
|
def check_port(option, opt_str, value, parser):
|
||||||
@@ -155,5 +175,6 @@ if __name__ == '__main__':
|
|||||||
tool = BindCmdInterpreter(server_addr, pem_file=options.cert_chain,
|
tool = BindCmdInterpreter(server_addr, pem_file=options.cert_chain,
|
||||||
csv_file_dir=options.csv_file_dir)
|
csv_file_dir=options.csv_file_dir)
|
||||||
prepare_config_commands(tool)
|
prepare_config_commands(tool)
|
||||||
|
prepare_execute_commands(tool)
|
||||||
result = tool.run()
|
result = tool.run()
|
||||||
sys.exit(result)
|
sys.exit(result)
|
||||||
|
40
src/bin/bindctl/command_sets.py
Normal file
40
src/bin/bindctl/command_sets.py
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Copyright (C) 2012 Internet Systems Consortium.
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and distribute this software 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 INTERNET SYSTEMS CONSORTIUM
|
||||||
|
# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
||||||
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||||
|
# INTERNET SYSTEMS CONSORTIUM 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.
|
||||||
|
|
||||||
|
# This file provides a built-in set of 'execute' commands, for common
|
||||||
|
# functions, such as adding an initial auth server
|
||||||
|
# These sets must have an associated CommandInfo defined in
|
||||||
|
# bindctl_main.py.in, in prepare_execute_commands
|
||||||
|
|
||||||
|
init_auth_server = [
|
||||||
|
'!echo adding Authoritative server component',
|
||||||
|
'config add /Boss/components b10-auth',
|
||||||
|
'config set /Boss/components/b10-auth/kind needed',
|
||||||
|
'config set /Boss/components/b10-auth/special auth',
|
||||||
|
'!echo adding Xfrin component',
|
||||||
|
'config add /Boss/components b10-xfrin',
|
||||||
|
'config set /Boss/components/b10-xfrin/address Xfrin',
|
||||||
|
'config set /Boss/components/b10-xfrin/kind dispensable',
|
||||||
|
'!echo adding Xfrout component',
|
||||||
|
'config add /Boss/components b10-xfrout',
|
||||||
|
'config set /Boss/components/b10-xfrout/address Xfrout',
|
||||||
|
'config set /Boss/components/b10-xfrout/kind dispensable',
|
||||||
|
'!echo adding Zone Manager component',
|
||||||
|
'config add /Boss/components b10-zonemgr',
|
||||||
|
'config set /Boss/components/b10-zonemgr/address Zonemgr',
|
||||||
|
'config set /Boss/components/b10-zonemgr/kind dispensable',
|
||||||
|
'!echo Components added. Please enter "config commit" to finalize initial'+
|
||||||
|
' setup and run the components.'
|
||||||
|
]
|
Reference in New Issue
Block a user