This is an automated email from the git hooks/post-receive script.
firstyear pushed a commit to branch master
in repository lib389.
commit 9b421b0b551547300c41167e48362e9833dd054e
Author: William Brown <firstyear(a)redhat.com>
Date: Fri Feb 10 15:48:33 2017 +1000
Ticket 49126 - DIT management tool
Bug Description: This adds a tool allowing us to manage items in the DIT of
an LDAP server.
Fix Description: This tool is able to manage users, groups, ous and posixgroups.
Additionally, the functionality for schema management was ported into the dsconf
tool.
https://fedorahosted.org/389/ticket/49126
Author: wibrown
Review by: mreynolds (Thanks!)
---
cli/dsconf | 2 +
cli/{dsconf => dsidm} | 61 +++++++++----------
lib389/__init__.py | 6 +-
lib389/cli_conf/schema.py | 44 ++++++++++++++
lib389/cli_idm/__init__.py | 114 +++++++++++++++++++++++++++++++++++
lib389/cli_idm/group.py | 79 ++++++++++++++++++++++++
lib389/cli_idm/organisationalunit.py | 79 ++++++++++++++++++++++++
lib389/cli_idm/posixgroup.py | 80 ++++++++++++++++++++++++
lib389/cli_idm/user.py | 79 ++++++++++++++++++++++++
9 files changed, 507 insertions(+), 37 deletions(-)
diff --git a/cli/dsconf b/cli/dsconf
index bbb4fba..c74698d 100755
--- a/cli/dsconf
+++ b/cli/dsconf
@@ -19,6 +19,7 @@ logging.basicConfig(format='%(message)s')
from lib389 import DirSrv
from lib389.cli_conf import backend as cli_backend
from lib389.cli_conf import plugin as cli_plugin
+from lib389.cli_conf import schema as cli_schema
from lib389.cli_conf import lint as cli_lint
from lib389.cli_base import disconnect_instance, connect_instance
@@ -57,6 +58,7 @@ if __name__ == '__main__':
subparsers = parser.add_subparsers(help="resources to act upon")
cli_backend.create_parser(subparsers)
+ cli_schema.create_parser(subparsers)
cli_lint.create_parser(subparsers)
cli_plugin.create_parser(subparsers)
diff --git a/cli/dsconf b/cli/dsidm
similarity index 59%
copy from cli/dsconf
copy to cli/dsidm
index bbb4fba..64f10ed 100755
--- a/cli/dsconf
+++ b/cli/dsidm
@@ -1,54 +1,50 @@
#!/usr/bin/python3
# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2016 Red Hat, Inc.
+# Copyright (C) 2016, William Brown <william at blackhats.net.au>
# All rights reserved.
#
# License: GPL (version 3 or any later version).
# See LICENSE for details.
# --- END COPYRIGHT BLOCK ---
+import ldap
import argparse
+# import argcomplete
import logging
-import ldap
-import sys
-# This has to happen before we import DirSrv else it tramples our config ... :(
-logging.basicConfig(format='%(message)s')
+from lib389.cli_idm import organisationalunit as cli_ou
+from lib389.cli_idm import group as cli_group
+from lib389.cli_idm import posixgroup as cli_posixgroup
+from lib389.cli_idm import user as cli_user
-from lib389 import DirSrv
-from lib389.cli_conf import backend as cli_backend
-from lib389.cli_conf import plugin as cli_plugin
-from lib389.cli_conf import lint as cli_lint
-from lib389.cli_base import disconnect_instance, connect_instance
+from lib389.cli_base import connect_instance, disconnect_instance
-log = logging.getLogger("dsconf")
+logging.basicConfig()
+log = logging.getLogger("dsidm")
if __name__ == '__main__':
defbase = ldap.get_option(ldap.OPT_DEFBASE)
parser = argparse.ArgumentParser()
- # Build the base ldap options, this keeps in unified.
-
- # Can we get default options for these from .rc file?
-
+ # First, add the LDAP options
parser.add_argument('-D', '--binddn',
help="The account to bind as for executing operations",
- default='cn=Directory Manager',
+ default=None,
)
parser.add_argument('-H', '--ldapurl',
help="The LDAP url to connect to, IE ldap://mai.example.com:389",
- default='ldap://localhost',
- )
- parser.add_argument('-b', '--basedn',
- help="The basedn for this operation.",
default=None,
)
parser.add_argument('-Z', '--starttls',
help="Connect with StartTLS",
default=False, action='store_true'
)
+ parser.add_argument('-b', '--basedn',
+ help="Basedn (root naming context) of the instance to manage",
+ default=defbase
+ )
parser.add_argument('-v', '--verbose',
help="Display verbose operation tracing during command execution",
action='store_true', default=False
@@ -56,31 +52,28 @@ if __name__ == '__main__':
subparsers = parser.add_subparsers(help="resources to act upon")
- cli_backend.create_parser(subparsers)
- cli_lint.create_parser(subparsers)
- cli_plugin.create_parser(subparsers)
+ # Call all the other cli modules to register their bits
+ cli_ou.create_parser(subparsers)
+ cli_group.create_parser(subparsers)
+ cli_posixgroup.create_parser(subparsers)
+ cli_user.create_parser(subparsers)
+
+ # argcomplete.autocomplete(parser)
args = parser.parse_args()
if args.verbose:
log.setLevel(logging.DEBUG)
else:
- # We aren't verbose, so fix our formatter up to be more minimal ...
log.setLevel(logging.INFO)
- log.debug("The 389 Directory Server Configuration Tool")
+ log.debug("The 389 Directory Server Identity Manager")
# Leave this comment here: UofA let me take this code with me provided
# I gave attribution. -- wibrown
log.debug("Inspired by works of: ITS, The University of Adelaide")
log.debug("Called with: %s", args)
- # Assert we have a resources to work on.
- if not hasattr(args, 'func'):
- log.error("No resource provided to act upon")
- log.error("USAGE: dsadm [options] <resource> <action> [action
options]")
- sys.exit(1)
-
# Connect
inst = None
if args.verbose:
@@ -92,10 +85,10 @@ if __name__ == '__main__':
args.func(inst, args.basedn, log, args)
except Exception as e:
log.debug(e, exc_info=True)
- log.error("Error: %s" % e)
+ log.error("Error: %s" % e.message)
disconnect_instance(inst)
- # Done!
- log.debug("dsconf is brought to you by the letter H and the number 25.")
+
+ log.debug("dsidm is brought to you by the letter E and the number 26.")
diff --git a/lib389/__init__.py b/lib389/__init__.py
index bb3fe26..008fb11 100644
--- a/lib389/__init__.py
+++ b/lib389/__init__.py
@@ -522,6 +522,9 @@ class DirSrv(SimpleLDAPObject, object):
self.creation_suffix = args.get(SER_CREATION_SUFFIX, DEFAULT_SUFFIX)
# These settings are only needed on a local connection.
if self.isLocal:
+ # For compatibility keep self.inst but should be removed
+ self.inst = self.serverid
+
self.userid = args.get(SER_USER_ID)
if not self.userid:
if os.getuid() == 0:
@@ -546,9 +549,6 @@ class DirSrv(SimpleLDAPObject, object):
# self.errlog = os.path.join(self.prefix,
# "var/log/dirsrv/slapd-%s/errors" %
self.serverid)
- # For compatibility keep self.inst but should be removed
- self.inst = self.serverid
-
# additional settings
self.suffixes = {}
self.agmt = {}
diff --git a/lib389/cli_conf/schema.py b/lib389/cli_conf/schema.py
new file mode 100644
index 0000000..c2427c4
--- /dev/null
+++ b/lib389/cli_conf/schema.py
@@ -0,0 +1,44 @@
+#!/usr/bin/python3
+
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2016, William Brown <william at blackhats.net.au>
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+import argparse
+
+from lib389.cli_base import _get_arg
+
+def list_attributetype(inst, basedn, log, args):
+ for attributetype in inst.schema.get_attributetypes():
+ print(attributetype)
+
+def query_attributetype(inst, basedn, log, args):
+ # Need the query type
+ attr = _get_arg( args.attr , msg="Enter attribute to query" )
+ attributetype, must, may = inst.schema.query_attributetype(attr)
+ print(attributetype)
+ print("")
+ print("MUST")
+ for oc in must:
+ print(oc)
+ print("")
+ print("MAY")
+ for oc in may:
+ print(oc)
+
+def create_parser(subparsers):
+ schema_parser = subparsers.add_parser('schema', help='Query and
manipulate schema')
+
+ subcommands = schema_parser.add_subparsers(help='schema')
+
+ list_attributetype_parser = subcommands.add_parser('list_attributetype',
help='List avaliable attribute types on this system')
+ list_attributetype_parser.set_defaults(func=list_attributetype)
+
+ query_attributetype_parser = subcommands.add_parser('query_attributetype',
help='Query an attribute to determine object classes that may or must take it')
+ query_attributetype_parser.set_defaults(func=query_attributetype)
+ query_attributetype_parser.add_argument('attr', nargs='?',
help='Attribute type to query')
+
diff --git a/lib389/cli_idm/__init__.py b/lib389/cli_idm/__init__.py
new file mode 100644
index 0000000..39cd01d
--- /dev/null
+++ b/lib389/cli_idm/__init__.py
@@ -0,0 +1,114 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2016, William Brown <william at blackhats.net.au>
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+from getpass import getpass
+from lib389 import DirSrv
+from lib389.properties import SER_LDAP_URL, SER_ROOT_DN, SER_ROOT_PW
+
+
+def _get_arg(args, msg=None):
+ if args is not None and len(args) > 0:
+ if type(args) is list:
+ return args[0]
+ else:
+ return args
+ else:
+ return raw_input("%s : " % msg)
+
+def _get_args(args, kws):
+ kwargs = {}
+ while len(kws) > 0:
+ kw, msg, priv = kws.pop(0)
+
+ if args is not None and len(args) > 0:
+ kwargs[kw] = args.pop(0)
+ else:
+ if priv:
+ kwargs[kw] = getpass("%s : " % msg)
+ else:
+ kwargs[kw] = raw_input("%s : " % msg)
+ return kwargs
+
+# This is really similar to get_args, but generates from the MUST_ATTRIBUTES array
+def _get_attributes(args, attrs):
+ kwargs = {}
+ for attr in attrs:
+ if args is not None and len(args) > 0:
+ kwargs[attr] = args.pop(0)
+ else:
+ if attr.lower() == 'userpassword':
+ kwargs[attr] = getpass("Enter value for %s : " % attr)
+ else:
+ kwargs[attr] = raw_input("Enter value for %s : " % attr)
+ return kwargs
+
+
+def _warn(data, msg=None):
+ if msg is not None:
+ print("%s :" % msg)
+ if 'Yes I am sure' != raw_input("Type 'Yes I am sure' to
continue: "):
+ raise Exception("Not sure if want")
+ return data
+
+def connect_instance(ldapurl, binddn, verbose, starttls):
+ dsargs = {
+ SER_LDAP_URL: ldapurl,
+ SER_ROOT_DN: binddn
+ }
+ ds = DirSrv(verbose=verbose)
+ ds.allocate(dsargs)
+ if not ds.can_autobind() and binddn is not None:
+ dsargs[SER_ROOT_PW] = getpass("Enter password for %s on %s : " %
(binddn, ldapurl))
+ elif binddn is None:
+ raise Exception("Must provide a binddn to connect with")
+ ds.allocate(dsargs)
+ ds.open(starttls=starttls)
+ print("")
+ return ds
+
+def disconnect_instance(inst):
+ if inst is not None:
+ inst.close()
+
+def _generic_list(inst, basedn, log, manager_class, **kwargs):
+ mc = manager_class(inst, basedn)
+ ol = mc.list()
+ if len(ol) == 0:
+ print("No objects to display")
+ elif len(ol) > 0:
+ # We might sort this in the future
+ for o in ol:
+ o_str = o.__unicode__()
+ print(o_str)
+
+# Display these entries better!
+def _generic_get(inst, basedn, log, manager_class, selector):
+ mc = manager_class(inst, basedn)
+ o = mc.get(selector)
+ o_str = o.__unicode__()
+ print(o_str)
+
+def _generic_get_dn(inst, basedn, log, manager_class, dn):
+ mc = manager_class(inst, basedn)
+ o = mc.get(dn=dn)
+ o_str = o.__unicode__()
+ print(o_str)
+
+def _generic_create(inst, basedn, log, manager_class, kwargs):
+ mc = manager_class(inst, basedn)
+ o = mc.create(properties=kwargs)
+ o_str = o.__unicode__()
+ print('Sucessfully created %s' % o_str)
+
+def _generic_delete(inst, basedn, log, object_class, dn):
+ # Load the oc direct
+ o = object_class(inst, dn)
+ o.delete()
+ print('Sucessfully deleted %s' % dn)
+
+# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/lib389/cli_idm/group.py b/lib389/cli_idm/group.py
new file mode 100644
index 0000000..d41205f
--- /dev/null
+++ b/lib389/cli_idm/group.py
@@ -0,0 +1,79 @@
+#!/usr/bin/python3
+
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2016, William Brown <william at blackhats.net.au>
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+import argparse
+from lib389.idm.group import Group, Groups
+
+from lib389.cli_base import (
+ _generic_list,
+ _generic_get,
+ _generic_get_dn,
+ _generic_create,
+ _generic_delete,
+ _get_arg,
+ _get_args,
+ _get_attributes,
+ _warn,
+ )
+
+SINGULAR = Group
+MANY = Groups
+RDN = 'cn'
+
+# These are a generic specification, try not to tamper with them
+
+def list(inst, basedn, log, args):
+ _generic_list(inst, basedn, log.getChild('_generic_list'), MANY)
+
+def get(inst, basedn, log, args):
+ rdn = _get_arg( args.selector, msg="Enter %s to retrieve" % RDN)
+ _generic_get(inst, basedn, log.getChild('_generic_get'), MANY, rdn)
+
+def get_dn(inst, basedn, log, args):
+ dn = lambda args: _get_arg( args.dn, msg="Enter dn to retrieve")
+ _generic_get_dn(inst, basedn, log.getChild('_generic_get_dn'), MANY, dn)
+
+def create(inst, basedn, log, args):
+ kwargs = _get_attributes(args, MUST_ATTRIBUTES)
+ _generic_create(inst, basedn, log.getChild('_generic_create'), MANY, kwargs)
+
+def delete(inst, basedn, log, args):
+ dn = _get_arg( args, msg="Enter dn to delete")
+ _warn(dn, msg="Deleting %s %s" % (SINGULAR.__name__, dn))
+ _generic_delete(inst, basedn, log.getChild('_generic_delete'), SINGULAR, dn)
+
+def create_parser(subparsers):
+ group_parser = subparsers.add_parser('group', help='Manage groups')
+
+ subcommands = group_parser.add_subparsers(help='action')
+
+ list_parser = subcommands.add_parser('list', help='list')
+ list_parser.set_defaults(func=list)
+
+ get_parser = subcommands.add_parser('get', help='get')
+ get_parser.set_defaults(func=get)
+ get_parser.add_argument('selector', nargs='?', help='The term to
search for')
+
+ get_dn_parser = subcommands.add_parser('get_dn', help='get_dn')
+ get_dn_parser.set_defaults(func=get_dn)
+ get_dn_parser.add_argument('dn', nargs='?', help='The dn to
get')
+
+ create_parser = subcommands.add_parser('create', help='create')
+ create_parser.set_defaults(func=create)
+ create_parser.add_argument('extra', nargs=argparse.REMAINDER,
+ help='A create may take one or more extra arguments. This parameter
provides them'
+ )
+
+ delete_parser = subcommands.add_parser('delete', help='deletes the
object')
+ delete_parser.set_defaults(func=delete)
+ delete_parser.add_argument('dn', nargs='?', help='The dn to
delete')
+
+
+# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/lib389/cli_idm/organisationalunit.py b/lib389/cli_idm/organisationalunit.py
new file mode 100644
index 0000000..bcc2232
--- /dev/null
+++ b/lib389/cli_idm/organisationalunit.py
@@ -0,0 +1,79 @@
+#!/usr/bin/python3
+
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2016, William Brown <william at blackhats.net.au>
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+import argparse
+from lib389.idm.organisationalunit import OrganisationalUnit, OrganisationalUnits
+
+from lib389.cli_base import (
+ _generic_list,
+ _generic_get,
+ _generic_get_dn,
+ _generic_create,
+ _generic_delete,
+ _get_arg,
+ _get_args,
+ _get_attributes,
+ _warn,
+ )
+
+SINGULAR = OrganisationalUnit
+MANY = OrganisationalUnits
+RDN = 'ou'
+
+# These are a generic specification, try not to tamper with them
+
+def list(inst, basedn, log, args):
+ _generic_list(inst, basedn, log.getChild('_generic_list'), MANY)
+
+def get(inst, basedn, log, args):
+ rdn = _get_arg( args.selector, msg="Enter %s to retrieve" % RDN)
+ _generic_get(inst, basedn, log.getChild('_generic_get'), MANY, rdn)
+
+def get_dn(inst, basedn, log, args):
+ dn = lambda args: _get_arg( args.dn, msg="Enter dn to retrieve")
+ _generic_get_dn(inst, basedn, log.getChild('_generic_get_dn'), MANY, dn)
+
+def create(inst, basedn, log, args):
+ kwargs = _get_attributes(args, MUST_ATTRIBUTES)
+ _generic_create(inst, basedn, log.getChild('_generic_create'), MANY, kwargs)
+
+def delete(inst, basedn, log, args):
+ dn = _get_arg( args, msg="Enter dn to delete")
+ _warn(dn, msg="Deleting %s %s" % (SINGULAR.__name__, dn))
+ _generic_delete(inst, basedn, log.getChild('_generic_delete'), SINGULAR, dn)
+
+def create_parser(subparsers):
+ ou_parser = subparsers.add_parser('organisationalunit', help='Manage
organisational units')
+
+ subcommands = ou_parser.add_subparsers(help='action')
+
+ list_parser = subcommands.add_parser('list', help='list')
+ list_parser.set_defaults(func=list)
+
+ get_parser = subcommands.add_parser('get', help='get')
+ get_parser.set_defaults(func=get)
+ get_parser.add_argument('selector', nargs='?', help='The term to
search for')
+
+ get_dn_parser = subcommands.add_parser('get_dn', help='get_dn')
+ get_dn_parser.set_defaults(func=get_dn)
+ get_dn_parser.add_argument('dn', nargs='?', help='The dn to
get')
+
+ create_parser = subcommands.add_parser('create', help='create')
+ create_parser.set_defaults(func=create)
+ create_parser.add_argument('extra', nargs=argparse.REMAINDER,
+ help='A create may take one or more extra arguments. This parameter
provides them'
+ )
+
+ delete_parser = subcommands.add_parser('delete', help='deletes the
object')
+ delete_parser.set_defaults(func=delete)
+ delete_parser.add_argument('dn', nargs='?', help='The dn to
delete')
+
+
+# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/lib389/cli_idm/posixgroup.py b/lib389/cli_idm/posixgroup.py
new file mode 100644
index 0000000..5c9331a
--- /dev/null
+++ b/lib389/cli_idm/posixgroup.py
@@ -0,0 +1,80 @@
+#!/usr/bin/python3
+
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2016, William Brown <william at blackhats.net.au>
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+import argparse
+from lib389.idm.posixgroup import PosixGroup, PosixGroups, MUST_ATTRIBUTES
+
+from lib389.cli_base import (
+ _generic_list,
+ _generic_get,
+ _generic_get_dn,
+ _generic_create,
+ _generic_delete,
+ _get_arg,
+ _get_args,
+ _get_attributes,
+ _warn,
+ )
+
+
+SINGULAR = PosixGroup
+MANY = PosixGroups
+RDN = 'cn'
+
+# These are a generic specification, try not to tamper with them
+
+def list(inst, basedn, log, args):
+ _generic_list(inst, basedn, log.getChild('_generic_list'), MANY)
+
+def get(inst, basedn, log, args):
+ rdn = _get_arg( args.selector, msg="Enter %s to retrieve" % RDN)
+ _generic_get(inst, basedn, log.getChild('_generic_get'), MANY, rdn)
+
+def get_dn(inst, basedn, log, args):
+ dn = lambda args: _get_arg( args.dn, msg="Enter dn to retrieve")
+ _generic_get_dn(inst, basedn, log.getChild('_generic_get_dn'), MANY, dn)
+
+def create(inst, basedn, log, args):
+ kwargs = _get_attributes(args.extra, MUST_ATTRIBUTES)
+ _generic_create(inst, basedn, log.getChild('_generic_create'), MANY, kwargs)
+
+def delete(inst, basedn, log, args):
+ dn = _get_arg( args, msg="Enter dn to delete")
+ _warn(dn, msg="Deleting %s %s" % (SINGULAR.__name__, dn))
+ _generic_delete(inst, basedn, log.getChild('_generic_delete'), SINGULAR, dn)
+
+def create_parser(subparsers):
+ posixgroup_parser = subparsers.add_parser('posixgroup', help='Manage
posix groups')
+
+ subcommands = posixgroup_parser.add_subparsers(help='action')
+
+ list_parser = subcommands.add_parser('list', help='list')
+ list_parser.set_defaults(func=list)
+
+ get_parser = subcommands.add_parser('get', help='get')
+ get_parser.set_defaults(func=get)
+ get_parser.add_argument('selector', nargs='?', help='The term to
search for')
+
+ get_dn_parser = subcommands.add_parser('get_dn', help='get_dn')
+ get_dn_parser.set_defaults(func=get_dn)
+ get_dn_parser.add_argument('dn', nargs='?', help='The dn to
get')
+
+ create_parser = subcommands.add_parser('create', help='create')
+ create_parser.set_defaults(func=create)
+ create_parser.add_argument('extra', nargs=argparse.REMAINDER,
+ help='A create may take one or more extra arguments. This parameter
provides them'
+ )
+
+ delete_parser = subcommands.add_parser('delete', help='deletes the
object')
+ delete_parser.set_defaults(func=delete)
+ delete_parser.add_argument('dn', nargs='?', help='The dn to
delete')
+
+
+# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/lib389/cli_idm/user.py b/lib389/cli_idm/user.py
new file mode 100644
index 0000000..07e4853
--- /dev/null
+++ b/lib389/cli_idm/user.py
@@ -0,0 +1,79 @@
+#!/usr/bin/python3
+
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2016, William Brown <william at blackhats.net.au>
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+import argparse
+from lib389.idm.user import UserAccount, UserAccounts
+
+from lib389.cli_base import (
+ _generic_list,
+ _generic_get,
+ _generic_get_dn,
+ _generic_create,
+ _generic_delete,
+ _get_arg,
+ _get_args,
+ _get_attributes,
+ _warn,
+ )
+
+SINGULAR = UserAccount
+MANY = UserAccounts
+RDN = 'uid'
+
+# These are a generic specification, try not to tamper with them
+
+def list(inst, basedn, log, args):
+ _generic_list(inst, basedn, log.getChild('_generic_list'), MANY)
+
+def get(inst, basedn, log, args):
+ rdn = _get_arg( args.selector, msg="Enter %s to retrieve" % RDN)
+ _generic_get(inst, basedn, log.getChild('_generic_get'), MANY, rdn)
+
+def get_dn(inst, basedn, log, args):
+ dn = lambda args: _get_arg( args.dn, msg="Enter dn to retrieve")
+ _generic_get_dn(inst, basedn, log.getChild('_generic_get_dn'), MANY, dn)
+
+def create(inst, basedn, log, args):
+ kwargs = _get_attributes(args, MUST_ATTRIBUTES)
+ _generic_create(inst, basedn, log.getChild('_generic_create'), MANY, kwargs)
+
+def delete(inst, basedn, log, args):
+ dn = _get_arg( args, msg="Enter dn to delete")
+ _warn(dn, msg="Deleting %s %s" % (SINGULAR.__name__, dn))
+ _generic_delete(inst, basedn, log.getChild('_generic_delete'), SINGULAR, dn)
+
+def create_parser(subparsers):
+ user_parser = subparsers.add_parser('user', help='Manage posix
users')
+
+ subcommands = user_parser.add_subparsers(help='action')
+
+ list_parser = subcommands.add_parser('list', help='list')
+ list_parser.set_defaults(func=list)
+
+ get_parser = subcommands.add_parser('get', help='get')
+ get_parser.set_defaults(func=get)
+ get_parser.add_argument('selector', nargs='?', help='The term to
search for')
+
+ get_dn_parser = subcommands.add_parser('get_dn', help='get_dn')
+ get_dn_parser.set_defaults(func=get_dn)
+ get_dn_parser.add_argument('dn', nargs='?', help='The dn to
get')
+
+ create_parser = subcommands.add_parser('create', help='create')
+ create_parser.set_defaults(func=create)
+ create_parser.add_argument('extra', nargs=argparse.REMAINDER,
+ help='A create may take one or more extra arguments. This parameter
provides them'
+ )
+
+ delete_parser = subcommands.add_parser('delete', help='deletes the
object')
+ delete_parser.set_defaults(func=delete)
+ delete_parser.add_argument('dn', nargs='?', help='The dn to
delete')
+
+
+# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.