diff options
Diffstat (limited to 'ipalib')
-rw-r--r-- | ipalib/__init__.py | 20 | ||||
-rw-r--r-- | ipalib/cli.py | 13 | ||||
-rw-r--r-- | ipalib/frontend.py | 29 | ||||
-rw-r--r-- | ipalib/output.py | 50 | ||||
-rw-r--r-- | ipalib/plugins/baseldap.py | 12 | ||||
-rw-r--r-- | ipalib/plugins/cert.py | 68 | ||||
-rw-r--r-- | ipalib/plugins/group.py | 32 | ||||
-rw-r--r-- | ipalib/plugins/host.py | 28 | ||||
-rw-r--r-- | ipalib/plugins/hostgroup.py | 18 | ||||
-rw-r--r-- | ipalib/plugins/netgroup.py | 25 | ||||
-rw-r--r-- | ipalib/plugins/rolegroup.py | 22 | ||||
-rw-r--r-- | ipalib/plugins/service.py | 4 | ||||
-rw-r--r-- | ipalib/plugins/taskgroup.py | 18 | ||||
-rw-r--r-- | ipalib/plugins/user.py | 14 |
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) |