summaryrefslogtreecommitdiffstats
path: root/ipalib
diff options
context:
space:
mode:
authorRob Crittenden <rcritten@redhat.com>2010-02-12 16:34:21 -0500
committerJason Gerard DeRose <jderose@redhat.com>2010-02-15 13:10:11 -0700
commit58746226d4b36bc40de91d4d1dd283e9faaff639 (patch)
tree11c4cd42b0285ff366c68274495cd1e9ee7fa7da /ipalib
parent99dcf9d4f97ac8bff112d6ccc36bb5b894fa5bcd (diff)
downloadfreeipa-58746226d4b36bc40de91d4d1dd283e9faaff639.tar.gz
freeipa-58746226d4b36bc40de91d4d1dd283e9faaff639.tar.xz
freeipa-58746226d4b36bc40de91d4d1dd283e9faaff639.zip
Use the Output tuple to determine the order of output
The attributes displayed is now dependant upon their definition in a Param. This enhances that, giving some level of control over how the result is displayed to the user. This also fixes displaying group membership, including failures of adding/removing entries. All tests pass now though there is still one problem. We need to return the dn as well. Once that is fixed we just need to comment out all the dn entries in the tests and they should once again pass.
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 83956e16d..beaf0ab51 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 b3980945b..d8c4b8058 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 ae7ec9454..0a1566e49 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 425ff977c..757e7155e 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 eeea7a6c4..964f8e5d9 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 55b3b70bb..3931d214a 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 0cc42a7a6..a04330cc8 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 7e9dd90ba..c459cfe09 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 7accca621..5a723b8c8 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 094a6d870..767bc1b35 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 ea89aa519..bf21e23c0 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 a5de17b3a..d7c795ba3 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 a39f5c004..afdbf6561 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 c06a9280f..00d64c7e4 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)