- restructured
- implementation of client and sysuser cli - backend for client, sysuser, domain and record - unified cli binary gva git-svn-id: file:///home/www/usr01/svn/gnuviechadmin/gnuviech.info/gnuviechadmin/trunk@226 a67ec6bc-e5d5-0310-a910-815c51eb3124
This commit is contained in:
parent
ee36146629
commit
926acaddfa
19 changed files with 1010 additions and 345 deletions
|
@ -20,62 +20,202 @@
|
|||
# Version: $Id$
|
||||
|
||||
import getopt, sys
|
||||
from gnuviechadmin.exceptions import GnuviechadminError
|
||||
|
||||
class CliCommand:
|
||||
"""Base class for command line interface."""
|
||||
def usage(self):
|
||||
"""This method should print usage information for the command."""
|
||||
"""Base class for command line interface. A specific
|
||||
implementation class must define the fields name, description and
|
||||
_optionmap.
|
||||
|
||||
|
||||
The field name is the name of the subcommand.
|
||||
|
||||
The field description is a short, one line description of the
|
||||
command.
|
||||
|
||||
The field _optionmap is a map which maps the subcommand names to
|
||||
lists of tuples. Each tuple consists of four elements. The first
|
||||
element is a list of command line arguments, short arguments start
|
||||
with dash, long arguments with a double dash. The second element
|
||||
is the name of the field in the data map of the command, it will
|
||||
directly be sent to the underlying entity. The third field is a
|
||||
description for the group of command line options in field
|
||||
one. The fourth field is True for mandatory fields and False
|
||||
otherwise.
|
||||
"""
|
||||
|
||||
def _usage(self):
|
||||
"""This method shows usage information. The implementation
|
||||
relies on the information in the fields name, description and
|
||||
_optionmap in the implementation classes."""
|
||||
print """GNUViechAdmin command line interface
|
||||
|
||||
Subcommand: %(command)s
|
||||
|
||||
%(description)s
|
||||
|
||||
Usage:
|
||||
|
||||
%(called)s %(command)s -h|--help
|
||||
|
||||
gives this usage information.
|
||||
|
||||
Common options:
|
||||
|
||||
%(option)s
|
||||
%(mandatory)s %(optiondesc)s
|
||||
""" % { 'called' : sys.argv[0],
|
||||
'command' : self.name,
|
||||
'description' : self.description,
|
||||
'option' : '-v, --verbose',
|
||||
'optiondesc' : 'verbose operation',
|
||||
'mandatory' : " "}
|
||||
for commandname in self._optionmap.keys():
|
||||
cmdl = "%(called)s %(command)s %(subcommand)s [-v|--verbose]" % {
|
||||
'called' : sys.argv[0],
|
||||
'command' : self.name,
|
||||
'subcommand' : commandname}
|
||||
desc = """
|
||||
%s
|
||||
""" % (self._optionmap[commandname][0])
|
||||
for (options, field, optiondesc, mandatory) in \
|
||||
self._optionmap[commandname][1]:
|
||||
cmd = " "
|
||||
pairs = []
|
||||
for option in options:
|
||||
if field:
|
||||
if option.startswith("--"):
|
||||
pairs.append("%s=<%s>" % (option, field))
|
||||
else:
|
||||
pairs.append("%s <%s>" % (option, field))
|
||||
else:
|
||||
pairs.append(option)
|
||||
if not mandatory:
|
||||
cmd = cmd + "["
|
||||
cmd = cmd + "|".join(pairs)
|
||||
if not mandatory:
|
||||
cmd = cmd + "]"
|
||||
descmap = {
|
||||
'option' : ", ".join(pairs),
|
||||
'optiondesc' : optiondesc,
|
||||
'mandatory' : ' '}
|
||||
if mandatory:
|
||||
descmap['mandatory'] = '*'
|
||||
desc = desc + """ %(option)s
|
||||
%(mandatory)s %(optiondesc)s
|
||||
""" % descmap
|
||||
if (len(cmdl) + len(cmd)) > 79:
|
||||
print cmdl
|
||||
cmdl = cmd
|
||||
else:
|
||||
cmdl = cmdl + cmd
|
||||
print cmdl
|
||||
print desc
|
||||
print "Mandatory options are marked with *"
|
||||
|
||||
def _subcommands(self):
|
||||
"""Convenience method for retrieving the subcommand names from
|
||||
the _optionmap field."""
|
||||
return self._optionmap.keys()
|
||||
|
||||
def _longopts(self, subcommand):
|
||||
"""This method retrieves available long options in a format
|
||||
valid for getopt.gnu_getopt(...) from the _optionmap field."""
|
||||
longopts = []
|
||||
for cur in [(option[0], option[1]) for option in \
|
||||
self._optionmap[subcommand][1]]:
|
||||
for command in cur[0]:
|
||||
if command.startswith("--"):
|
||||
if cur[1]:
|
||||
longopts.append(command[2:] + "=")
|
||||
else:
|
||||
longopts.append(command[2:])
|
||||
return longopts
|
||||
|
||||
def _shortopts(self, subcommand):
|
||||
"""This method retrieves available short options in a format
|
||||
valid for getopt.gnu_getopt(...) from the _optionmap field."""
|
||||
shortopts = ""
|
||||
for cur in [(option[0], option[1]) for option in \
|
||||
self._optionmap[subcommand][1]]:
|
||||
for command in cur[0]:
|
||||
if not command.startswith("--"):
|
||||
if cur[1]:
|
||||
shortopts = shortopts + command[1:] + ":"
|
||||
else:
|
||||
shortopts = shortopts + command[1:]
|
||||
return shortopts
|
||||
|
||||
def _checkrequired(self, subcommand):
|
||||
"""Checks whether the required fields of the given subcommand
|
||||
are set."""
|
||||
reqcheck = [True, []]
|
||||
for req in [option for option in \
|
||||
self._optionmap[subcommand][1] if option[3]]:
|
||||
if not req[1] in self._data:
|
||||
reqcheck[0] = False
|
||||
reqcheck[1].append(""" %s
|
||||
* %s""" % (", ".join(req[0]), req[2]))
|
||||
return reqcheck
|
||||
|
||||
def _handleoption(self, subcommand, o, a):
|
||||
"""Handles a command line option by assigning it to the
|
||||
matching key as defined in the _optionmap property of the
|
||||
implementation class."""
|
||||
optionmap = [(option[0], option[1]) for option in \
|
||||
self._optionmap[subcommand][1]]
|
||||
if optionmap:
|
||||
for (options, datakey) in optionmap:
|
||||
if o in options:
|
||||
self._data[datakey] = a
|
||||
|
||||
def _execute(self, subcommand):
|
||||
"""This method is called when the subcommand of the command is
|
||||
executed."""
|
||||
raise NotImplementedError
|
||||
|
||||
def shortopts(self):
|
||||
"""This method should return an option string for the short
|
||||
options for getopt.gnu_getopt(...)."""
|
||||
raise NotImplementedError
|
||||
|
||||
def longopts(self):
|
||||
"""This method should return a list of long options for
|
||||
getopt.gnu_getopt(...)."""
|
||||
raise NotImplementedError
|
||||
|
||||
def handleoption(self, option, argument):
|
||||
"""This method should handle each option known to the command."""
|
||||
raise NotImplementedError
|
||||
|
||||
def execute(self):
|
||||
"""This method is called when the command is executed."""
|
||||
raise NotImplementedError
|
||||
|
||||
def checkrequired(self):
|
||||
"""This methode is called after handling command line options
|
||||
and should check whether all required values were set."""
|
||||
raise NotImplementedError
|
||||
|
||||
def __parseopts(self, args):
|
||||
def _parseopts(self, subcommand, args):
|
||||
"""This method parses the options given on the command line."""
|
||||
longopts = ["help", "verbose"]
|
||||
longopts.extend(self.longopts())
|
||||
longopts.extend(self._longopts(subcommand))
|
||||
try:
|
||||
opts, args = getopt.gnu_getopt(
|
||||
args,
|
||||
"hv" + self.shortopts(),
|
||||
"hv" + self._shortopts(subcommand),
|
||||
longopts)
|
||||
except getopt.GetoptError:
|
||||
self.usage()
|
||||
self._usage()
|
||||
sys.exit(2)
|
||||
self.verbose = False
|
||||
self._verbose = False
|
||||
for o, a in opts:
|
||||
if o in ("-v", "--verbose"):
|
||||
self.verbose = True
|
||||
self._verbose = True
|
||||
if o in ("-h", "--help"):
|
||||
self.usage()
|
||||
self._usage()
|
||||
sys.exit()
|
||||
self.handleoption(o, a)
|
||||
self._handleoption(subcommand, o, a)
|
||||
|
||||
def __init__(self, args):
|
||||
"""This initializes the command with the given command line
|
||||
arguments and executes it."""
|
||||
self.__parseopts(args)
|
||||
if (self.checkrequired()):
|
||||
self.execute()
|
||||
self._data = {}
|
||||
if len(args) > 0:
|
||||
if args[0] in self._subcommands():
|
||||
self._parseopts(args[0], args[1:])
|
||||
reqcheck = self._checkrequired(args[0])
|
||||
if reqcheck[0]:
|
||||
try:
|
||||
self._execute(args[0])
|
||||
except GnuviechadminError, e:
|
||||
print e
|
||||
else:
|
||||
self._usage()
|
||||
print """
|
||||
the following required arguments are missing:
|
||||
"""
|
||||
print "\n".join(reqcheck[1])
|
||||
else:
|
||||
self._usage()
|
||||
print "invalid sub command"
|
||||
else:
|
||||
self.usage()
|
||||
self._usage()
|
||||
|
|
|
@ -20,91 +20,63 @@
|
|||
# Version: $Id$
|
||||
|
||||
import CliCommand, sys
|
||||
from gnuviechadmin import client
|
||||
|
||||
class ClientCli(CliCommand.CliCommand):
|
||||
"""Command line interface command for client creation."""
|
||||
def shortopts(self):
|
||||
return "f:l:a:z:c:e:p:o:t:m:x:"
|
||||
"""Command line interface command for client managament."""
|
||||
|
||||
def longopts(self):
|
||||
return ["firstname=", "lastname=", "address=", "zip=",
|
||||
"city=", "email=", "phone=", "address2=", "organisation=",
|
||||
"country=", "title=", "mobile=", "fax="]
|
||||
|
||||
def usage(self):
|
||||
print """Usage: %s client [-h|--help] [-v|--verbose]
|
||||
[-t <title>|--title=<title>]
|
||||
-f <firstname>|--firstname=<firstname> -l <lastname>|--lastname=<lastname>
|
||||
-a <address1>|--address=<address1> [--address2=<address2>]
|
||||
-z <zip>|--zip=<zip> -c <city>|--city=<city> [--country=<isocode>]
|
||||
[-o <organisation>|--organisation=<organisation>]
|
||||
-e <email>|--email=<email> -p <phone>|--phone=<phone>
|
||||
[-m <mobile>|--mobile=<mobile>] [-x <fax>|--fax=<fax>]
|
||||
|
||||
General options:
|
||||
-h, --help show this usage message and exit
|
||||
-v, --verbose verbose operation
|
||||
|
||||
Mandatory client data options:
|
||||
-f, --firstname firstname
|
||||
-l, --lastname lastname
|
||||
-a, --address street address
|
||||
-z, --zip zip or postal code
|
||||
-c, --city city or location
|
||||
-e, --email contact email address
|
||||
-p, --phone telephone number
|
||||
|
||||
Optional client data options:
|
||||
--address2 optional second line of the street address
|
||||
-o, --organisation option organisation
|
||||
--country country (defaults to de)
|
||||
-t, --title optional title
|
||||
-m, --mobile optional mobile number
|
||||
-x, --fax optional fax number
|
||||
""" % sys.argv[0]
|
||||
|
||||
def handleoption(self, o, a):
|
||||
if o in ("-f", "--firstname"):
|
||||
self.data["firstname"] = a
|
||||
elif o in ("-l", "--lastname"):
|
||||
self.data["lastname"] = a
|
||||
elif o in ("-a", "--address"):
|
||||
self.data["address1"] = a
|
||||
elif o in ("-z", "--zip"):
|
||||
self.data["zip"] = a
|
||||
elif o in ("-c", "--city"):
|
||||
self.data["city"] = a
|
||||
elif o == "--country":
|
||||
self.data["country"] = a
|
||||
elif o in ("-t", "--title"):
|
||||
self.data["title"] = a
|
||||
elif o in ("-m", "--mobile"):
|
||||
self.data["mobile"] = a
|
||||
elif o in ("-e", "--email"):
|
||||
self.data["email"] = a
|
||||
elif o in ("-o", "--organisation"):
|
||||
self.data["organisation"] = a
|
||||
elif o in ("-x", "--fax"):
|
||||
self.data["fax"] = a
|
||||
elif o in ("-p", "--phone"):
|
||||
self.data["phone"] = a
|
||||
|
||||
def checkrequired(self):
|
||||
required = ['firstname', 'lastname', 'address1', 'zip', 'city',
|
||||
'phone', 'email']
|
||||
if self.verbose:
|
||||
print self.data
|
||||
for req in required:
|
||||
if not req in self.data:
|
||||
return False
|
||||
return True
|
||||
|
||||
def execute(self):
|
||||
myclient = client.create(**self.data)
|
||||
if self.verbose:
|
||||
print myclient
|
||||
name = "client"
|
||||
description = "manage clients"
|
||||
_optionmap = {
|
||||
'create' : ("creates a new client",
|
||||
[(["-f", "--firstname"], "firstname",
|
||||
"the client's first name", True),
|
||||
(["-l", "--lastname"], "lastname",
|
||||
"the client's last name", True),
|
||||
(["-t", "--title"], "title",
|
||||
"the client's title", False),
|
||||
(["-a", "--address"], "address1",
|
||||
"the address of the client", True),
|
||||
(["--address2"], "address2",
|
||||
"second line of the client's address", False),
|
||||
(["-z", "--zip"], "zip",
|
||||
"the zipcode of the client's address", True),
|
||||
(["-c", "--city"], "city",
|
||||
"the city of the client's address", True),
|
||||
(["--country"], "country",
|
||||
"the client's country", False),
|
||||
(["-e", "--email"], "email",
|
||||
"the client's email address", True),
|
||||
(["-p", "--phone"], "phone",
|
||||
"the client's phone number", True),
|
||||
(["-m", "--mobile"], "mobile",
|
||||
"the client's mobile phone number", False),
|
||||
(["-x", "--fax"], "fax",
|
||||
"the client's fax number", False)]),
|
||||
'list' : ("lists existing clients",
|
||||
[]),
|
||||
'delete' : ("deletes the specified client if it has no dependent data",
|
||||
[(["-c", "--clientid"], "clientid",
|
||||
"the client id", True)])}
|
||||
|
||||
def _execute(self, subcommand):
|
||||
from gnuviechadmin.backend import client
|
||||
from gnuviechadmin import exceptions
|
||||
if subcommand == "create":
|
||||
try:
|
||||
myclient = client.ClientHandler(self._verbose).create(
|
||||
**self._data)
|
||||
if self._verbose:
|
||||
print myclient
|
||||
except exceptions.CreationFailedError, cfe:
|
||||
self._usage()
|
||||
print cfe
|
||||
sys.exit(2)
|
||||
elif subcommand == "list":
|
||||
clients = client.ClientHandler(self._verbose).fetchall()
|
||||
for client in clients:
|
||||
print client
|
||||
elif subcommand == "delete":
|
||||
client.ClientHandler(self._verbose).delete(self._data["clientid"])
|
||||
|
||||
def __init__(self, argv):
|
||||
self.data = {}
|
||||
CliCommand.CliCommand.__init__(self, argv)
|
||||
|
|
|
@ -1 +1,71 @@
|
|||
pass
|
||||
# -*- coding: UTF-8 -*-
|
||||
#
|
||||
# Copyright (C) 2007 by Jan Dittberner.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
# USA.
|
||||
#
|
||||
# Version: $Id$
|
||||
|
||||
import CliCommand, sys
|
||||
|
||||
class SysuserCli(CliCommand.CliCommand):
|
||||
"""Command line interface command for system user managament."""
|
||||
|
||||
name = "sysuser"
|
||||
description = "manage system users"
|
||||
_optionmap = {
|
||||
"create" : ("create a new system user with the given options.",
|
||||
[(["-n", "--username"], "username",
|
||||
"the system user name", False),
|
||||
(["-t", "--usertype"], "usertype",
|
||||
"the numeric user type", False),
|
||||
(["-h", "--home"], "home",
|
||||
"the home directory", False),
|
||||
(["-s", "--shell"], "shell",
|
||||
"true if the user should get shell access", False),
|
||||
(["-p", "--password"], "clearpass",
|
||||
"the password for the user", False),
|
||||
(["-c", "--clientid"], "clientid",
|
||||
"the client id", True)]),
|
||||
"list" : ("list existing system users.",
|
||||
[]),
|
||||
"delete" : ("delete a system user.",
|
||||
[(["-s", "--sysuserid"], "sysuserid",
|
||||
"the system user id", True)])}
|
||||
|
||||
def _execute(self, subcommand):
|
||||
from gnuviechadmin.backend import sysuser
|
||||
from gnuviechadmin import exceptions
|
||||
if subcommand == "create":
|
||||
try:
|
||||
mysysuser = sysuser.SysuserHandler(self._verbose).create(
|
||||
**self._data)
|
||||
if self._verbose:
|
||||
print mysysuser
|
||||
except exceptions.CreationFailedError, cfe:
|
||||
self._usage()
|
||||
print cfe
|
||||
sys.exit(2)
|
||||
elif subcommand == "list":
|
||||
sysusers = sysuser.SysuserHandler(self._verbose).fetchall()
|
||||
for su in sysusers:
|
||||
print su
|
||||
elif subcommand == "delete":
|
||||
sysuser.SysuserHandler(self._verbose).delete(
|
||||
self._data["sysuserid"])
|
||||
|
||||
def __init__(self, argv):
|
||||
CliCommand.CliCommand.__init__(self, argv)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue