Commit f64a1962 authored by Jelte Jansen's avatar Jelte Jansen
Browse files

improve internal help documentation for config commands

while i was at it, improved printing/indentation of help data to make output more readable


git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac384@4150 e5f2f494-b856-4b98-b285-d166d9295462
parent 25530c6c
......@@ -388,9 +388,19 @@ class BindCmdInterpreter(Cmd):
def do_help(self, name):
print(CONST_BINDCTL_HELP)
for k in self.modules.keys():
print("\t", self.modules[k])
for k in self.modules.values():
n = k.get_name()
if len(n) >= 8:
print("\t%s" % n)
print(textwrap.fill(k.get_desc(),
initial_indent="\t\t",
subsequent_indent="\t\t",
width=70))
else:
print(textwrap.fill("%s\t%s" % (k.get_name(), k.get_desc()),
initial_indent="\t",
subsequent_indent="\t\t",
width=70))
def onecmd(self, line):
if line == 'EOF' or line.lower() == "quit":
......@@ -540,14 +550,16 @@ class BindCmdInterpreter(Cmd):
if cmd.params['identifier'].startswith("/"):
identifier = cmd.params['identifier']
else:
if cmd.params['identifier'].startswith('['):
identifier = identifier[:-1]
identifier += cmd.params['identifier']
# Check if the module is known; for unknown modules
# we currently deny setting preferences, as we have
# no way yet to determine if they are ok.
module_name = identifier.split('/')[1]
if self.config_data is None or \
not self.config_data.have_specification(module_name):
if module_name != "" and (self.config_data is None or \
not self.config_data.have_specification(module_name)):
print("Error: Module '" + module_name + "' unknown or not running")
return
......@@ -630,16 +642,24 @@ class BindCmdInterpreter(Cmd):
def go(self, identifier):
'''Handles the config go command, change the 'current' location
within the configuration tree'''
# this is just to see if it exists
self.config_data.get_value(identifier)
# some sanitizing
identifier = identifier.replace("//", "/")
if not identifier.startswith("/"):
identifier = "/" + identifier
if identifier.endswith("/"):
identifier = identifier[:-1]
self.location = identifier
within the configuration tree. '..' will be interpreted as
'up one level'.'''
id_parts = isc.cc.data.split_identifier(identifier)
new_location = ""
for id_part in id_parts:
if (id_part == ".."):
# go 'up' one level
new_location, a, b = new_location.rpartition("/")
else:
new_location += "/" + id_part
# check if exists, if not, revert and error
v = self.config_data.find_spec_part(new_location)
if v is None:
print("Error: " + identifier + " not found")
return
self.location = new_location
def apply_cmd(self, cmd):
'''Handles a general module command'''
......
......@@ -33,58 +33,60 @@ isc.util.process.rename()
# number, and the overall BIND 10 version number (set in configure.ac).
VERSION = "bindctl 20101201 (BIND 10 @PACKAGE_VERSION@)"
DEFAULT_IDENTIFIER_DESC = "The identifier specifiec the config item. Child elements are separated with the '/' character. List indices can be specified with '[i]', where i is an integer specifying the index, starting with 0. Examples: 'Boss/start_auth', 'Recurse/listen_on[0]/address'. If no identifier is given, shows the item at the current location."
def prepare_config_commands(tool):
'''Prepare fixed commands for local configuration editing'''
module = ModuleInfo(name = CONFIG_MODULE_NAME, desc = "Configuration commands")
cmd = CommandInfo(name = "show", desc = "Show configuration")
param = ParamInfo(name = "argument", type = "string", optional=True)
param = ParamInfo(name = "argument", type = "string", optional=True, desc = "If you specify the argument 'all' (before the identifier), recursively shows all child elements for the given identifier")
cmd.add_param(param)
param = ParamInfo(name = "identifier", type = "string", optional=True)
param = ParamInfo(name = "identifier", type = "string", optional=True, desc = DEFAULT_IDENTIFIER_DESC)
cmd.add_param(param)
module.add_command(cmd)
cmd = CommandInfo(name = "show_json", desc = "Show full configuration in JSON format")
param = ParamInfo(name = "identifier", type = "string", optional=True)
param = ParamInfo(name = "identifier", type = "string", optional=True, desc = DEFAULT_IDENTIFIER_DESC)
cmd.add_param(param)
module.add_command(cmd)
cmd = CommandInfo(name = "add", desc = "Add an entry to configuration list. If no value is given, a default value is added.")
param = ParamInfo(name = "identifier", type = "string", optional=True)
param = ParamInfo(name = "identifier", type = "string", optional=True, desc = DEFAULT_IDENTIFIER_DESC)
cmd.add_param(param)
param = ParamInfo(name = "value", type = "string", optional=True)
param = ParamInfo(name = "value", type = "string", optional=True, desc = "Specifies a value to add to the list. It must be in correct JSON format and complete.")
cmd.add_param(param)
module.add_command(cmd)
cmd = CommandInfo(name = "remove", desc = "Remove entry from configuration list")
param = ParamInfo(name = "identifier", type = "string", optional=True)
param = ParamInfo(name = "identifier", type = "string", optional=True, desc = DEFAULT_IDENTIFIER_DESC)
cmd.add_param(param)
param = ParamInfo(name = "value", type = "string", optional=True)
param = ParamInfo(name = "value", type = "string", optional=True, desc = "Specifies a value to remove from the list. It must be in correct JSON format and complete.")
cmd.add_param(param)
module.add_command(cmd)
cmd = CommandInfo(name = "set", desc = "Set a configuration value")
param = ParamInfo(name = "identifier", type = "string", optional=True)
param = ParamInfo(name = "identifier", type = "string", optional=True, desc = DEFAULT_IDENTIFIER_DESC)
cmd.add_param(param)
param = ParamInfo(name = "value", type = "string", optional=False)
param = ParamInfo(name = "value", type = "string", optional=False, desc = "Specifies a value to set. It must be in correct JSON format and complete.")
cmd.add_param(param)
module.add_command(cmd)
cmd = CommandInfo(name = "unset", desc = "Unset a configuration value")
param = ParamInfo(name = "identifier", type = "string", optional=False)
cmd = CommandInfo(name = "unset", desc = "Unset a configuration value (i.e. revert to the default, if any)")
param = ParamInfo(name = "identifier", type = "string", optional=False, desc = DEFAULT_IDENTIFIER_DESC)
cmd.add_param(param)
module.add_command(cmd)
cmd = CommandInfo(name = "diff", desc = "Show all local changes")
cmd = CommandInfo(name = "diff", desc = "Show all local changes that have not been committed")
module.add_command(cmd)
cmd = CommandInfo(name = "revert", desc = "Revert all local changes")
module.add_command(cmd)
cmd = CommandInfo(name = "commit", desc = "Commit all local changes")
cmd = CommandInfo(name = "commit", desc = "Commit all local changes.")
module.add_command(cmd)
cmd = CommandInfo(name = "go", desc = "Go to a specific configuration part")
param = ParamInfo(name = "identifier", type="string", optional=False)
param = ParamInfo(name = "identifier", type="string", optional=False, desc = DEFAULT_IDENTIFIER_DESC)
cmd.add_param(param)
module.add_command(cmd)
......
......@@ -16,6 +16,8 @@
"""This module holds classes representing modules, commands and
parameters for use in bindctl"""
import textwrap
try:
from collections import OrderedDict
except ImportError:
......@@ -52,6 +54,12 @@ class ParamInfo:
def __str__(self):
return str("\t%s <type: %s> \t(%s)" % (self.name, self.type, self.desc))
def get_name(self):
return "%s <type: %s>" % (self.name, self.type)
def get_desc(self):
return self.desc
class CommandInfo:
"""One command which is provided by one bind10 module, it has zero
or more parameters
......@@ -68,8 +76,13 @@ class CommandInfo:
def __str__(self):
return str("%s \t(%s)" % (self.name, self.desc))
def get_name(self):
return self.name
def get_desc(self):
return self.desc;
def add_param(self, paraminfo):
"""Add a ParamInfo object to this CommandInfo"""
self.params[paraminfo.name] = paraminfo
......@@ -144,22 +157,30 @@ class CommandInfo:
del params["help"]
if len(params) == 0:
print("\tNo parameters for the command")
print("No parameters for the command")
return
print("\n\tMandatory parameters:")
print("\nMandatory parameters:")
mandatory_infos = []
for info in params.values():
if not info.is_optional:
print("\t", info)
print("\t%s" % info.get_name())
print(textwrap.fill(info.get_desc(),
initial_indent="\t\t",
subsequent_indent="\t\t",
width=50))
mandatory_infos.append(info)
optional_infos = [info for info in params.values()
if info not in mandatory_infos]
if len(optional_infos) > 0:
print("\n\tOptional parameters:")
print("\nOptional parameters:")
for info in optional_infos:
print("\t", info)
print("\t%s" % info.get_name())
print(textwrap.fill(info.get_desc(),
initial_indent="\t\t",
subsequent_indent="\t\t",
width=50))
class ModuleInfo:
......@@ -176,7 +197,13 @@ class ModuleInfo:
def __str__(self):
return str("%s \t%s" % (self.name, self.desc))
def get_name(self):
return self.name
def get_desc(self):
return self.desc
def add_command(self, command_info):
"""Add a CommandInfo to this ModuleInfo."""
self.commands[command_info.name] = command_info
......@@ -201,8 +228,19 @@ class ModuleInfo:
def module_help(self):
"""Prints the help info for this module to stdout"""
print("Module ", self, "\nAvailable commands:")
for k in self.commands.keys():
print("\t", self.commands[k])
for k in self.commands.values():
n = k.get_name()
if len(n) >= 8:
print("\t%s" % n)
print(textwrap.fill(k.get_desc(),
initial_indent="\t\t",
subsequent_indent="\t\t",
width=70))
else:
print(textwrap.fill("%s\t%s" % (k.get_name(), k.get_desc()),
initial_indent="\t",
subsequent_indent="\t\t",
width=70))
def command_help(self, command):
"""Prints the help info for the command with the given name.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment