summaryrefslogtreecommitdiffstats
path: root/ipalib
diff options
context:
space:
mode:
Diffstat (limited to 'ipalib')
-rw-r--r--ipalib/__init__.py20
-rw-r--r--ipalib/cli.py13
-rw-r--r--ipalib/frontend.py29
-rw-r--r--ipalib/output.py50
-rw-r--r--ipalib/plugins/baseldap.py12
-rw-r--r--ipalib/plugins/cert.py68
-rw-r--r--ipalib/plugins/group.py32
-rw-r--r--ipalib/plugins/host.py28
-rw-r--r--ipalib/plugins/hostgroup.py18
-rw-r--r--ipalib/plugins/netgroup.py25
-rw-r--r--ipalib/plugins/rolegroup.py22
-rw-r--r--ipalib/plugins/service.py4
-rw-r--r--ipalib/plugins/taskgroup.py18
-rw-r--r--ipalib/plugins/user.py14
14 files changed, 277 insertions, 76 deletions
diff --git a/ipalib/__init__.py b/ipalib/__init__.py
index 83956e16..beaf0ab5 100644
--- a/ipalib/__init__.py
+++ b/ipalib/__init__.py
@@ -584,9 +584,9 @@ For example, say we setup a command like this:
...
... def execute(self, key, **options):
... items = dict(
-... fruit='apple',
-... pet='dog',
-... city='Berlin',
+... fruit=u'apple',
+... pet=u'dog',
+... city=u'Berlin',
... )
... if key in items:
... return dict(result=items[key])
@@ -627,9 +627,9 @@ through the ``ipa`` script basically will do the following:
-----------
show-items:
-----------
- city = 'Berlin'
- fruit = 'apple'
- pet = 'dog'
+ city = u'Berlin'
+ fruit = u'apple'
+ pet = u'dog'
-------
3 items
-------
@@ -641,9 +641,9 @@ Similarly, calling it with ``reverse=True`` would result in the following:
-----------
show-items:
-----------
- pet = 'dog'
- fruit = 'apple'
- city = 'Berlin'
+ pet = u'dog'
+ fruit = u'apple'
+ city = u'Berlin'
--------------------------
3 items (in reverse order)
--------------------------
@@ -652,7 +652,7 @@ Lastly, providing a ``key`` would result in the following:
>>> result = api.Command.show_items(u'city')
>>> api.Command.show_items.output_for_cli(textui, result, 'city', reverse=False)
-city = 'Berlin'
+city = u'Berlin'
See the `ipalib.cli.textui` plugin for a description of its methods.
diff --git a/ipalib/cli.py b/ipalib/cli.py
index b3980945..d8c4b805 100644
--- a/ipalib/cli.py
+++ b/ipalib/cli.py
@@ -144,7 +144,6 @@ class textui(backend.Backend):
Convert a binary value to base64. We know a value is binary
if it is a python str type, otherwise it is a plain string.
"""
- assert isinstance(value, basestring)
if type(value) is str:
return base64.b64encode(value)
else:
@@ -231,15 +230,15 @@ class textui(backend.Backend):
>>> items = [
... ('in_server', True),
- ... ('mode', 'production'),
+ ... ('mode', u'production'),
... ]
>>> ui = textui()
>>> ui.print_keyval(items)
in_server = True
- mode = 'production'
+ mode = u'production'
>>> ui.print_keyval(items, indent=0)
in_server = True
- mode = 'production'
+ mode = u'production'
Also see `textui.print_indented`.
"""
@@ -354,7 +353,11 @@ class textui(backend.Backend):
if isinstance(value, (list, tuple)):
value = map(lambda v: self.encode_binary(v), value)
value = ', '.join(value)
- self.print_indented(format % (label, value), indent)
+ if isinstance(value, dict):
+ self.print_indented(format % (label, ''), indent)
+ self.print_entry(value, params, indent=indent+1)
+ else:
+ self.print_indented(format % (label, value), indent)
def print_dashed(self, string, above=True, below=True, indent=0, dash='-'):
diff --git a/ipalib/frontend.py b/ipalib/frontend.py
index ae7ec945..0a1566e4 100644
--- a/ipalib/frontend.py
+++ b/ipalib/frontend.py
@@ -824,16 +824,27 @@ class Command(HasParam):
result = output.get('result')
summary = output.get('summary')
- if (summary and isinstance(result, (list, tuple, dict)) and result):
- textui.print_name(self.name)
-
- if isinstance(result, (tuple, list)):
- textui.print_entries(result, self.output_params)
- elif isinstance(result, dict):
- textui.print_entry(result, self.output_params)
+ for o in self.output:
+ if 'no_display' in self.output[o].flags:
+ continue
+ result = output[o]
+
+ if isinstance(result, (tuple, list)):
+ textui.print_entries(result, self.output_params)
+ elif isinstance(result, dict):
+ textui.print_entry(result, self.output_params)
+ elif isinstance(result, unicode):
+ if o == 'summary':
+ textui.print_summary(result)
+ else:
+ textui.print_indented(result)
+ elif isinstance(result, bool):
+ # the Delete commands return a boolean indicating
+ # success or failure. Ignore these.
+ pass
+ elif isinstance(result, int):
+ textui.print_count(result, '%s %%d' % self.output[o].doc)
- if isinstance(summary, unicode):
- textui.print_summary(summary)
class LocalOrRemote(Command):
diff --git a/ipalib/output.py b/ipalib/output.py
index 425ff977..757e7155 100644
--- a/ipalib/output.py
+++ b/ipalib/output.py
@@ -29,18 +29,55 @@ from plugable import ReadOnly, lock
class Output(ReadOnly):
"""
Simple description of a member in the return value ``dict``.
+
+ This class controls both the type of object being returned by
+ a command as well as how the output will be displayed.
+
+ For example, this class defines two return results: an entry
+ and a value.
+
+ >>> from ipalib import crud, output
+ >>> class user(crud.Update):
+ ...
+ ... has_output = (
+ ... output.Entry('result'),
+ ... output.value,
+ ... )
+
+ The order of the values in has_output controls the order of output.
+ If you have values that you don't want to be printed then add
+ ``'no_display'`` to flags.
+
+ The difference between ``'no_dipslay`` and ``'no_output'`` is
+ that ``'no_output`` will prevent a Param value from being returned
+ at all. ``'no_display'`` will cause the API to return a value, it
+ simply won't be displayed to the user. This is so some things may
+ be returned that while not interesting to us, but may be to others.
+
+ >>> from ipalib import crud, output
+ >>> myvalue = output.Output('myvalue', unicode,
+ ... 'Do not print this value', flags=['no_display'],
+ ... )
+ >>> class user(crud.Update):
+ ...
+ ... has_output = (
+ ... output.Entry('result'),
+ ... myvalue,
+ ... )
"""
type = None
validate = None
doc = None
+ flags = []
- def __init__(self, name, type=None, doc=None):
+ def __init__(self, name, type=None, doc=None, flags=[]):
self.name = name
if type is not None:
self.type = type
if doc is not None:
self.doc = doc
+ self.flags = flags
lock(self)
def __repr__(self):
@@ -77,28 +114,29 @@ summary = Output('summary', (unicode, NoneType),
)
value = Output('value', unicode,
- "The primary_key value of the entry, e.g. 'jdoe' for a user"
+ "The primary_key value of the entry, e.g. 'jdoe' for a user",
+ flags=['no_display'],
)
-standard = (result, summary)
+standard = (summary, result)
standard_entry = (
+ summary,
Entry('result'),
value,
- summary,
)
standard_list_of_entries = (
+ summary,
ListOfEntries('result'),
Output('count', int, 'Number of entries returned'),
Output('truncated', bool, 'True if not all results were returned'),
- summary,
)
standard_delete = (
+ summary,
Output('result', bool, 'True means the operation was successful'),
value,
- summary,
)
standard_value = standard_delete
diff --git a/ipalib/plugins/baseldap.py b/ipalib/plugins/baseldap.py
index eeea7a6c..964f8e5d 100644
--- a/ipalib/plugins/baseldap.py
+++ b/ipalib/plugins/baseldap.py
@@ -102,7 +102,7 @@ class LDAPObject(Object):
for ldap_obj_name in self.attribute_members[attr]:
ldap_obj = self.api.Object[ldap_obj_name]
if member.find(ldap_obj.container_dn) > 0:
- new_attr = '%s %s' % (attr, ldap_obj.object_name)
+ new_attr = '%s_%s' % (attr, ldap_obj.object_name)
entry_attrs.setdefault(new_attr, []).append(
ldap_obj.get_primary_key_from_dn(member)
)
@@ -521,14 +521,14 @@ class LDAPAddMember(LDAPModMember):
has_output = (
output.Entry('result'),
- output.Output('completed',
- type=int,
- doc='Number of members added',
- ),
output.Output('failed',
type=dict,
doc='Members that could not be added',
),
+ output.Output('completed',
+ type=int,
+ doc='Number of members added',
+ ),
)
@@ -557,7 +557,7 @@ class LDAPAddMember(LDAPModMember):
else:
completed += 1
- (dn, entry_attrs) = ldap.get_entry(dn, member_dns.keys())
+ (dn, entry_attrs) = ldap.get_entry(dn, member_dns.keys()+self.obj.default_attributes)
(completed, dn) = self.post_callback(
ldap, completed, failed, dn, entry_attrs, *keys, **options
diff --git a/ipalib/plugins/cert.py b/ipalib/plugins/cert.py
index 55b3b70b..3931d214 100644
--- a/ipalib/plugins/cert.py
+++ b/ipalib/plugins/cert.py
@@ -35,12 +35,12 @@ from ipalib.plugins.virtual import *
from ipalib.plugins.service import split_principal
import base64
from ipalib.request import context
-from ipapython import dnsclient
from pyasn1.error import PyAsn1Error
import logging
import traceback
from ipalib.request import ugettext as _
from ipalib.request import context
+from ipalib.output import Output
def get_serial(certificate):
"""
@@ -184,6 +184,25 @@ class cert_request(VirtualCommand):
default=False,
autofill=True
),
+ Str('certificate?',
+ label='Certificate',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
+ Str('subject?',
+ label='Subject',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
+ Str('serial_number?',
+ label='Serial number',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
+ )
+
+ has_output = (
+ Output('result',
+ type=dict,
+ doc='Dictionary mapping variable name to value',
+ ),
)
def execute(self, csr, **kw):
@@ -268,7 +287,11 @@ class cert_request(VirtualCommand):
serial = get_serial(base64.b64encode(service['usercertificate'][0]))
# revoke the certificate and remove it from the service
# entry before proceeding
- api.Command['cert_revoke'](unicode(serial), revocation_reason=4)
+ try:
+ api.Command['cert_revoke'](unicode(serial), revocation_reason=4)
+ except errors.NotImplementedError:
+ # some CA's might not implement revoke
+ pass
api.Command['service_mod'](principal, usercertificate=None)
# Request the certificate
@@ -299,7 +322,18 @@ class cert_status(VirtualCommand):
Check status of a certificate signing request.
"""
- takes_args = ('request_id')
+ takes_args = (
+ Str('request_id',
+ label='Request id',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
+ )
+ takes_options = (
+ Str('cert_request_status?',
+ label='Request status',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
+ )
operation = "certificate status"
@@ -318,7 +352,19 @@ class cert_get(VirtualCommand):
"""
takes_args = (Str('serial_number',
+ label='Serial number',
doc='serial number in decimal or if prefixed with 0x in hexadecimal'))
+ takes_options = (
+ Str('certificate?',
+ label='Certificate',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
+ Str('subject?',
+ label='Subject',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
+ )
+
operation="retrieve certificate"
def execute(self, serial_number):
@@ -337,6 +383,12 @@ class cert_revoke(VirtualCommand):
takes_args = (Str('serial_number',
doc='serial number in decimal or if prefixed with 0x in hexadecimal'))
+ takes_options = (
+ Flag('revoked?',
+ label='Revoked',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
+ )
operation = "revoke certificate"
# FIXME: The default is 0. Is this really an Int param?
@@ -366,6 +418,16 @@ class cert_remove_hold(VirtualCommand):
takes_args = (Str('serial_number',
doc='serial number in decimal or if prefixed with 0x in hexadecimal'))
+ takes_options = (
+ Flag('unrevoked?',
+ label='Unrevoked',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
+ Str('error_string?',
+ label='Error',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
+ )
operation = "certificate remove hold"
def execute(self, serial_number, **kw):
diff --git a/ipalib/plugins/group.py b/ipalib/plugins/group.py
index 0cc42a7a..a04330cc 100644
--- a/ipalib/plugins/group.py
+++ b/ipalib/plugins/group.py
@@ -43,12 +43,12 @@ class group(LDAPObject):
attribute_names = {
'cn': 'name',
'gidnumber': 'group id',
- 'member user': 'member users',
- 'member group': 'member groups',
- 'memberof group': 'member of groups',
- 'memberof netgroup': 'member of netgroups',
- 'memberof rolegroup': 'member of rolegroup',
- 'memberof taskgroup': 'member of taskgroup',
+ 'member_user': 'member users',
+ 'member_group': 'member groups',
+ 'memberof_group': 'member of groups',
+ 'memberof_netgroup': 'member of netgroups',
+ 'memberof_rolegroup': 'member of rolegroup',
+ 'memberof_taskgroup': 'member of taskgroup',
}
attribute_members = {
'member': ['user', 'group'],
@@ -74,6 +74,26 @@ class group(LDAPObject):
label='GID',
doc='GID (use this option to set it manually)',
),
+ Str('member_group?',
+ label='Member Groups',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
+ Str('member_user?',
+ label='Member Users',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
+ Str('member?',
+ label='Failed Members',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
+ Str('user?',
+ label='Users',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
+ Str('group?',
+ label='Groups',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
)
api.register(group)
diff --git a/ipalib/plugins/host.py b/ipalib/plugins/host.py
index 7e9dd90b..c459cfe0 100644
--- a/ipalib/plugins/host.py
+++ b/ipalib/plugins/host.py
@@ -54,8 +54,8 @@ class host(LDAPObject):
object_class = ['ipaobject', 'nshost', 'ipahost', 'pkiuser', 'ipaservice']
# object_class_config = 'ipahostobjectclasses'
default_attributes = [
- 'fqdn', 'description', 'l', 'nshostlocation',
- 'nshardwareplatform', 'nsosversion', 'usercertificate',
+ 'fqdn', 'description', 'l', 'nshostlocation', 'krbprincipalname',
+ 'nshardwareplatform', 'nsosversion', 'usercertificate', 'memberof',
]
uuid_attribute = 'ipauniqueid'
attribute_names = {
@@ -70,9 +70,9 @@ class host(LDAPObject):
'enrolledby user': 'enrolled by',
'krbprincipalname': 'kerberos principal',
'ipauniqueid': 'unique identifier',
- 'memberof hostgroup': 'member of hostgroups',
- 'memberof netgroup': 'member of netgroups',
- 'memberof rolegroup': 'member of rolegroups',
+ 'memberof_hostgroup': 'member of hostgroups',
+ 'memberof_netgroup': 'member of netgroups',
+ 'memberof_rolegroup': 'member of rolegroups',
}
attribute_members = {
'enrolledby': ['user'],
@@ -93,7 +93,7 @@ class host(LDAPObject):
label='Description',
doc='Description of the host',
),
- Str('locality?',
+ Str('l?',
cli_name='locality',
label='Locality',
doc='Locality of the host (Baltimore, MD)',
@@ -122,6 +122,22 @@ class host(LDAPObject):
cli_name='certificate',
doc='base-64 encoded server certificate',
),
+ Str('krbprincipalname?',
+ label='Principal Name',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
+ Str('memberof_hostgroup?',
+ label='Member of Host Groups',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
+ Str('memberof_netgroup?',
+ label='Member Net Groups',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
+ Str('memberof_rolegroup?',
+ label='Member of Role Groups',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
)
def get_dn(self, *keys, **options):
diff --git a/ipalib/plugins/hostgroup.py b/ipalib/plugins/hostgroup.py
index 7accca62..5a723b8c 100644
--- a/ipalib/plugins/hostgroup.py
+++ b/ipalib/plugins/hostgroup.py
@@ -37,9 +37,9 @@ class hostgroup(LDAPObject):
uuid_attribute = 'ipauniqueid'
attribute_names = {
'cn': 'names',
- 'member host': 'member hosts',
- 'member hostgroup': 'member hostgroups',
- 'memberof hostgroup': 'member of hostgroup',
+ 'member_host': 'member hosts',
+ 'member_hostgroup': 'member hostgroups',
+ 'memberof_hostgroup': 'member of hostgroup',
}
attribute_members = {
'member': ['host', 'hostgroup'],
@@ -61,6 +61,18 @@ class hostgroup(LDAPObject):
label='Description',
doc='A description of this group',
),
+ Str('member_host?',
+ label='Member Hosts',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
+ Str('member_hostgroup?',
+ label='Member Host Groups',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
+ Str('memberof_hostgroup?',
+ label='Member of Hostgroups',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
)
api.register(hostgroup)
diff --git a/ipalib/plugins/netgroup.py b/ipalib/plugins/netgroup.py
index 094a6d87..767bc1b3 100644
--- a/ipalib/plugins/netgroup.py
+++ b/ipalib/plugins/netgroup.py
@@ -34,22 +34,21 @@ class netgroup(LDAPObject):
object_name = 'netgroup'
object_name_plural = 'netgroups'
object_class = ['ipaobject', 'ipaassociation', 'ipanisnetgroup']
- default_attributes = ['cn', 'description', 'member', 'memberof']
+ default_attributes = ['cn', 'description', 'member', 'memberof', 'externalhost']
uuid_attribute = 'ipauniqueid'
attribute_names = {
'cn': 'name',
- 'member user': 'member users',
- 'member group': 'member groups',
- 'member host': 'member hosts',
- 'member hostgroup': 'member hostgroups',
- 'member netgroup': 'member netgroups',
- 'memberof netgroup': 'member of netgroups',
- 'externalhost': 'external hosts',
+ 'member_user': 'member users',
+ 'member_group': 'member groups',
+ 'member_host': 'member hosts',
+ 'member_hostgroup': 'member hostgroups',
+ 'member_netgroup': 'member netgroups',
+ 'memberof_netgroup': 'member of netgroups',
+ 'externalhost': 'externalhost',
}
attribute_members = {
'member': ['user', 'group', 'host', 'hostgroup', 'netgroup'],
'memberof': ['netgroup'],
- 'externalhost': [],
}
label = _('Net Groups')
@@ -72,6 +71,14 @@ class netgroup(LDAPObject):
label='NIS domain name',
doc='NIS domain name',
),
+ Str('member_host?',
+ label='Member Host',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
+ Str('externalhost?',
+ label='External Host',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
)
def get_dn(self, *keys, **kwargs):
diff --git a/ipalib/plugins/rolegroup.py b/ipalib/plugins/rolegroup.py
index ea89aa51..bf21e23c 100644
--- a/ipalib/plugins/rolegroup.py
+++ b/ipalib/plugins/rolegroup.py
@@ -36,11 +36,11 @@ class rolegroup(LDAPObject):
default_attributes = ['cn', 'description', 'member', 'memberof']
attribute_names = {
'cn': 'name',
- 'member user': 'member users',
- 'member group': 'member groups',
- 'member host': 'member hosts',
- 'member hostgroup': 'member hostgroups',
- 'memberof taskgroup': 'member of taskgroup',
+ 'member_user': 'member users',
+ 'member_group': 'member groups',
+ 'member_host': 'member hosts',
+ 'member_hostgroup': 'member hostgroups',
+ 'memberof_taskgroup': 'member of taskgroup',
}
attribute_members = {
'member': ['user', 'group', 'host', 'hostgroup'],
@@ -62,6 +62,18 @@ class rolegroup(LDAPObject):
label='Description',
doc='A description of this rolegroup',
),
+ Str('member_group?',
+ label='Member Groups',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
+ Str('member_user?',
+ label='Member Users',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
+ Str('memberof_taskgroup?',
+ label='Member of Task Groups',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
)
api.register(rolegroup)
diff --git a/ipalib/plugins/service.py b/ipalib/plugins/service.py
index a5de17b3..d7c795ba 100644
--- a/ipalib/plugins/service.py
+++ b/ipalib/plugins/service.py
@@ -123,12 +123,14 @@ class service(LDAPObject):
takes_params = (
Str('krbprincipalname', validate_principal,
+ label='Principal',
cli_name='principal',
doc='service principal',
primary_key=True,
normalizer=lambda value: normalize_principal(value),
),
Bytes('usercertificate?', validate_certificate,
+ label='Certificate',
cli_name='certificate',
doc='base-64 encoded server certificate',
),
@@ -141,6 +143,7 @@ class service_add(LDAPCreate):
"""
Add new service.
"""
+ msg_summary = _('Added service "%(value)s"')
member_attributes = ['managedby']
takes_options = (
Flag('force',
@@ -187,6 +190,7 @@ class service_del(LDAPDelete):
"""
Delete an existing service.
"""
+ msg_summary = _('Deleted service "%(value)s"')
member_attributes = ['managedby']
def pre_callback(self, ldap, dn, *keys, **options):
if self.api.env.enable_ra:
diff --git a/ipalib/plugins/taskgroup.py b/ipalib/plugins/taskgroup.py
index a39f5c00..afdbf656 100644
--- a/ipalib/plugins/taskgroup.py
+++ b/ipalib/plugins/taskgroup.py
@@ -37,9 +37,9 @@ class taskgroup(LDAPObject):
default_attributes = ['cn', 'description', 'member', 'memberof']
attribute_names = {
'cn': 'name',
- 'member user': 'member users',
- 'member group': 'member groups',
- 'member rolegroup': 'member rolegroups',
+ 'member_user': 'member users',
+ 'member_group': 'member groups',
+ 'member_rolegroup': 'member rolegroups',
# FIXME: 'memberof ???': 'member of ???'
}
attribute_members = {
@@ -62,6 +62,18 @@ class taskgroup(LDAPObject):
label='Description',
doc='taskgroup description',
),
+ Str('member_group?',
+ label='Member Groups',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
+ Str('member_user?',
+ label='Member Users',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
+ Str('member_rolegroup?',
+ label='Member Role Groups',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
)
api.register(taskgroup)
diff --git a/ipalib/plugins/user.py b/ipalib/plugins/user.py
index c06a9280..00d64c7e 100644
--- a/ipalib/plugins/user.py
+++ b/ipalib/plugins/user.py
@@ -38,7 +38,7 @@ class user(LDAPObject):
object_class_config = 'ipauserobjectclasses'
default_attributes = [
'uid', 'givenname', 'sn', 'homedirectory', 'loginshell', 'ou',
- 'telephonenumber', 'title',
+ 'telephonenumber', 'title', 'memberof',
]
uuid_attribute = 'ipauniqueid'
attribute_names = {
@@ -53,10 +53,10 @@ class user(LDAPObject):
'krbpasswordexpiration': 'password expiration',
'uidnumber': 'uid number',
'gidnumber': 'gid number',
- 'memberof group': 'member of groups',
- 'memberof netgroup': 'member of netgroups',
- 'memberof rolegroup': 'member of rolegroups',
- 'memberof taskgroup': 'member of taskgroups',
+ 'memberof_group': 'member of groups',
+ 'memberof_netgroup': 'member of netgroups',
+ 'memberof_rolegroup': 'member of rolegroups',
+ 'memberof_taskgroup': 'member of taskgroups',
'ipauniqueid': 'unique identifier'
}
attribute_order = [
@@ -128,6 +128,10 @@ class user(LDAPObject):
cli_name='street',
label='Street address',
),
+ Str('memberof_group?',
+ label='Groups',
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
)
api.register(user)