summaryrefslogtreecommitdiffstats
path: root/ipalib
diff options
context:
space:
mode:
authorRob Crittenden <rcritten@redhat.com>2010-10-27 12:07:53 -0400
committerRob Crittenden <rcritten@redhat.com>2010-10-28 17:47:20 -0400
commit3c795f3251bd0354d56e2b50042ee04cee7cd21f (patch)
tree2b52ddf89754c8375290343cdc51563c147346fd /ipalib
parent7486ead6c910d13ae4d7cbae6fae738ce2bf47eb (diff)
downloadfreeipa-3c795f3251bd0354d56e2b50042ee04cee7cd21f.tar.gz
freeipa-3c795f3251bd0354d56e2b50042ee04cee7cd21f.tar.xz
freeipa-3c795f3251bd0354d56e2b50042ee04cee7cd21f.zip
Return reason for failure when updating group membership fails.
We used to return a list of dns that failed to be added. We now return a list of tuples instead. The tuple looks like (dn, reason) where reason is the exception that was returned. Also made the label we use for failures to be singular instead of plural since we now print them out individually instead of as comma-separated. ticket 270
Diffstat (limited to 'ipalib')
-rw-r--r--ipalib/cli.py14
-rw-r--r--ipalib/frontend.py34
-rw-r--r--ipalib/plugins/baseldap.py26
-rw-r--r--ipalib/plugins/netgroup.py18
4 files changed, 56 insertions, 36 deletions
diff --git a/ipalib/cli.py b/ipalib/cli.py
index e8242bfd2..6d057ca93 100644
--- a/ipalib/cli.py
+++ b/ipalib/cli.py
@@ -274,7 +274,17 @@ class textui(backend.Backend):
self.print_indented(format % (attr, self.encode_binary(v)), indent)
else:
value = map(lambda v: self.encode_binary(v), value)
- text = ', '.join(value)
+ if len(value) > 0 and type(value[0]) in (list, tuple):
+ # This is where we print failed add/remove members
+ for l in value:
+ text = ': '.join(l)
+ self.print_indented(format % (attr, self.encode_binary(text)), indent)
+ return
+ else:
+ if len(value) > 0:
+ text = ', '.join(value)
+ else:
+ return
line_len = self.get_tty_width()
if line_len and text:
s_indent = '%s%s' % (
@@ -343,6 +353,8 @@ class textui(backend.Backend):
label = labels.get(key, key)
value = entry[key]
if isinstance(value, dict):
+ if frontend.entry_count(value) == 0:
+ continue
self.print_indented(format % (label, ''), indent)
self.print_entry(
value, order, labels, print_all, format,
diff --git a/ipalib/frontend.py b/ipalib/frontend.py
index 577c2fcc9..73680ef2f 100644
--- a/ipalib/frontend.py
+++ b/ipalib/frontend.py
@@ -46,6 +46,22 @@ def is_rule(obj):
return callable(obj) and getattr(obj, RULE_FLAG, False) is True
+def entry_count(entry):
+ """
+ Return the number of entries in an entry. This is primarly for the
+ failed output parameter so we don't print empty values.
+
+ We also use this to determine if a non-zero return value is needed.
+ """
+ num_entries = 0
+ for f in entry:
+ if type(entry[f]) is dict:
+ num_entries = num_entries + entry_count(entry[f])
+ else:
+ num_entries = num_entries + len(entry[f])
+
+ return num_entries
+
class HasParam(Plugin):
"""
@@ -844,22 +860,6 @@ class Command(HasParam):
continue
yield param
- def number_failed(self, failed):
- """
- Return the number of entries in the failed output parameter.
-
- This is used to determine whether the failed members should be
- displayed and what the return value should be.
- """
- num_failed = 0
- for f in failed:
- if type(failed[f]) is dict:
- num_failed = num_failed + self.number_failed(failed[f])
- else:
- num_failed = num_failed + len(failed[f])
-
- return num_failed
-
def output_for_cli(self, textui, output, *args, **options):
"""
Generic output method. Prints values the output argument according
@@ -899,7 +899,7 @@ class Command(HasParam):
if o.lower() == 'count' and result == 0:
rv = 1
elif o.lower() == 'failed':
- if self.number_failed(result) == 0:
+ if entry_count(result) == 0:
# Don't display an empty failed list
continue
else:
diff --git a/ipalib/plugins/baseldap.py b/ipalib/plugins/baseldap.py
index f764efbb7..f3aa09d3e 100644
--- a/ipalib/plugins/baseldap.py
+++ b/ipalib/plugins/baseldap.py
@@ -117,6 +117,12 @@ global_output_params = (
Str('externalhost?',
label=_('External host'),
),
+ Str('memberhost',
+ label=_('Failed hosts/hostgroups'),
+ ),
+ Str('memberuser',
+ label=_('Failed users/groups'),
+ ),
)
@@ -818,7 +824,7 @@ class LDAPModMember(LDAPQuery):
name = to_cli(ldap_obj_name)
doc = self.member_param_doc % ldap_obj.object_name_plural
yield List('%s?' % name, cli_name='%ss' % name, doc=doc,
- label=ldap_obj.object_name_plural)
+ label=ldap_obj.object_name)
def get_member_dns(self, **options):
dns = {}
@@ -835,8 +841,8 @@ class LDAPModMember(LDAPQuery):
ldap_obj = self.api.Object[ldap_obj_name]
try:
dns[attr][ldap_obj_name].append(ldap_obj.get_dn(name))
- except errors.PublicError:
- failed[attr][ldap_obj_name].append(name)
+ except errors.PublicError, e:
+ failed[attr][ldap_obj_name].append((name, unicode(e)))
return (dns, failed)
@@ -884,10 +890,11 @@ class LDAPAddMember(LDAPModMember):
continue
try:
ldap.add_entry_to_group(m_dn, dn, attr)
- except errors.PublicError:
+ except errors.PublicError, e:
ldap_obj = self.api.Object[ldap_obj_name]
- failed[attr][ldap_obj_name].append(
- ldap_obj.get_primary_key_from_dn(m_dn)
+ failed[attr][ldap_obj_name].append((
+ ldap_obj.get_primary_key_from_dn(m_dn),
+ unicode(e),)
)
else:
completed += 1
@@ -985,10 +992,11 @@ class LDAPRemoveMember(LDAPModMember):
continue
try:
ldap.remove_entry_from_group(m_dn, dn, attr)
- except errors.PublicError:
+ except errors.PublicError, e:
ldap_obj = self.api.Object[ldap_obj_name]
- failed[attr][ldap_obj_name].append(
- ldap_obj.get_primary_key_from_dn(m_dn)
+ failed[attr][ldap_obj_name].append((
+ ldap_obj.get_primary_key_from_dn(m_dn),
+ unicode(e),)
)
else:
completed += 1
diff --git a/ipalib/plugins/netgroup.py b/ipalib/plugins/netgroup.py
index 3b714213a..28647b963 100644
--- a/ipalib/plugins/netgroup.py
+++ b/ipalib/plugins/netgroup.py
@@ -156,13 +156,13 @@ class netgroup_add_member(LDAPAddMember):
external_hosts = entry_attrs_.get('externalhost', [])
failed_hosts = []
for host in failed['memberhost']['host']:
- host = host.lower()
- host_dn = self.api.Object['host'].get_dn(host)
- if host not in external_hosts and host_dn not in members:
- external_hosts.append(host)
+ hostname = host[0].lower()
+ host_dn = self.api.Object['host'].get_dn(hostname)
+ if hostname not in external_hosts and host_dn not in members:
+ external_hosts.append(hostname)
completed_external += 1
else:
- failed_hosts.append(host)
+ failed_hosts.append(hostname)
if completed_external:
try:
ldap.update_entry(dn, {'externalhost': external_hosts})
@@ -190,12 +190,12 @@ class netgroup_remove_member(LDAPRemoveMember):
failed_hosts = []
completed_external = 0
for host in failed['memberhost']['host']:
- host = host.lower()
- if host in external_hosts:
- external_hosts.remove(host)
+ hostname = host[0].lower()
+ if hostname in external_hosts:
+ external_hosts.remove(hostname)
completed_external += 1
else:
- failed_hosts.append(host)
+ failed_hosts.append(hostname)
if completed_external:
try:
ldap.update_entry(dn, {'externalhost': external_hosts})