123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- # Copyright (C) 2009 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 module holds classes representing modules, commands and
- parameters for use in bindctl"""
- import textwrap
- try:
- from collections import OrderedDict
- except ImportError:
- from bindctl.mycollections import OrderedDict
- # Define value type
- STRING_TYPE = "string"
- LIST_TYPE = "list"
- INT_TYPE = "int"
- MODULE_NODE_NAME = 'module'
- COMMAND_NODE_NAME = 'command'
- PARAM_NODE_NAME = 'param'
- # this is used to align the descriptions in help output
- CONST_BINDCTL_HELP_INDENT_WIDTH=12
- class ParamInfo:
- """One parameter of one command.
- Each command parameter has five attributes:
- parameter name, parameter type, parameter value,
- parameter description and paramter's spec(got from
- module spec file).
- """
- def __init__(self, name, desc = '', type = STRING_TYPE,
- optional = False, value = '', default_value = '',
- param_spec = None):
- self.name = name
- self.type = type
- self.value = value
- self.default_value = default_value
- self.desc = desc
- self.is_optional = optional
- self.param_spec = param_spec
-
- def __str__(self):
- return str("\t%s <type: %s> \t(%s)" % (self.name, self.type, self.desc))
- def get_basic_info(self):
- if self.is_optional:
- opt_str = "optional"
- else:
- opt_str = "mandatory"
- return "%s (%s, %s)" % (self.name, self.type, opt_str)
- def get_desc(self):
- return self.desc
- class CommandInfo:
- """One command which is provided by one bind10 module, it has zero
- or more parameters
- """
- def __init__(self, name, desc = ""):
- self.name = name
- self.desc = desc
- self.params = OrderedDict()
- # Set default parameter "help"
- self.add_param(ParamInfo("help",
- desc = "Get help for command.",
- optional = True))
-
- 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
-
- def has_param_with_name(self, param_name):
- """Returns true if the parameter with param_name exists"""
- return param_name in self.params
-
- def get_param_with_name(self, param_name):
- """Returns the ParamInfo with the given name. Raises a
- KeyError if it doesn't exist"""
- return self.params[param_name]
-
- def get_params(self):
- """Returns a list of all ParamInfo objects for this CommandInfo"""
- return list(self.params.values())
-
- def get_param_names(self):
- """Returns a list of the names of all parameters for this command"""
- return list(self.params.keys())
-
-
- def get_mandatory_param_names(self):
- """Returns a list of the names of all mandatory parameters for
- this command"""
- all_names = self.params.keys()
- return [name for name in all_names
- if not self.params[name].is_optional]
-
- def get_param_name_by_position(self, pos, param_count):
- """
- Find a proper parameter name for the position 'pos':
- If param_count is equal to the count of mandatory parameters of command,
- and there is some optional parameter, find the first mandatory parameter
- from the position 'pos' to the end. Else, return the name on position pos.
- (This function will be changed if bindctl command line syntax is changed
- in the future. )
- """
- if type(pos) != int:
- raise KeyError(str(pos) + " is not an integer")
- else:
- params = self.params.copy()
- del params['help']
- count = len(params)
- if (pos >= count):
- raise KeyError(str(pos) + " out of range")
- mandatory_count = len(self.get_mandatory_param_names())
- param_names = list(params.keys())
- if (param_count == mandatory_count) and (param_count < count):
- while pos < count:
- if not params[param_names[pos]].is_optional:
- return param_names[pos]
- pos += 1
-
- raise KeyError(str(pos) + "parameters have error")
- else:
- return param_names[pos]
- def command_help(self):
- """Prints the help info for this command to stdout"""
- print("Command ", self)
- print("\t\thelp (Get help for command)")
- params = self.params.copy()
- del params["help"]
- if len(params) == 0:
- print("This command has no parameters")
- return
- print("Parameters:")
- for info in params.values():
- print(" %s" % info.get_basic_info())
- description = info.get_desc()
- if description != "":
- print(textwrap.fill(description,
- initial_indent=" ",
- subsequent_indent=" ",
- width=70))
- class ModuleInfo:
- """Define the information of one module, include module name,
- module supporting commands.
- """
-
- def __init__(self, name, desc = ""):
- self.name = name
- self.desc = desc
- self.commands = OrderedDict()
- self.add_command(CommandInfo(name = "help",
- desc = "Get help for module."))
-
- 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
-
- def has_command_with_name(self, command_name):
- """Returns true if this module has a command with the given name."""
- return command_name in self.commands
-
- def get_command_with_name(self, command_name):
- """Returns the CommandInfo for the command with the given name.
- Raises a KeyError if not found"""
- return self.commands[command_name]
-
- def get_commands(self):
- """Returns a list of all CommandInfo objects for this module."""
- return list(self.commands.values())
-
- def get_command_names(self):
- """Returns a list of the names of all commands for this module."""
- return list(self.commands.keys())
- def module_help(self):
- """Prints the help info for this module to stdout"""
- print("Module " + str(self))
- print("Available commands:")
- for k in self.commands.values():
- n = k.get_name()
- if len(n) >= CONST_BINDCTL_HELP_INDENT_WIDTH:
- print(" %s" % n)
- print(textwrap.fill(k.get_desc(),
- initial_indent=" ",
- subsequent_indent=" " +
- " " * CONST_BINDCTL_HELP_INDENT_WIDTH,
- width=70))
- else:
- print(textwrap.fill("%s%s%s" %
- (k.get_name(),
- " "*(CONST_BINDCTL_HELP_INDENT_WIDTH - len(k.get_name())),
- k.get_desc()),
- initial_indent=" ",
- subsequent_indent=" " +
- " " * CONST_BINDCTL_HELP_INDENT_WIDTH,
- width=70))
-
- def command_help(self, command):
- """Prints the help info for the command with the given name.
- Raises KeyError if not found"""
- self.commands[command].command_help()
|