mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Add missing managing hosts filtering options
Host object has a virtual attribute "managing" containing all hosts
it manages (governed by managedBy attribute). This patch also adds
standard membership filtering options:
--man-hosts=HOSTS: Only hosts managing _all_ HOSTS are returned
--not-man-hosts=HOSTS: Only hosts which do not manage _any_ host
in HOSTS are returned
https://fedorahosted.org/freeipa/ticket/1675
This commit is contained in:
committed by
Endi S. Dewata
parent
4277253b83
commit
0b9279a30a
4
API.txt
4
API.txt
@@ -1697,7 +1697,7 @@ output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
|
||||
output: Output('result', <type 'bool'>, None)
|
||||
output: Output('value', <type 'unicode'>, None)
|
||||
command: host_find
|
||||
args: 1,29,4
|
||||
args: 1,31,4
|
||||
arg: Str('criteria?', noextrawhitespace=False)
|
||||
option: Str('fqdn', attribute=True, autofill=False, cli_name='hostname', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9][a-zA-Z0-9-\\.]{0,254}$', pattern_errmsg='may only include letters, numbers, and -', primary_key=True, query=True, required=False)
|
||||
option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, query=True, required=False)
|
||||
@@ -1728,6 +1728,8 @@ option: Str('enroll_by_user*', cli_name='enroll_by_users', csv=True)
|
||||
option: Str('not_enroll_by_user*', cli_name='not_enroll_by_users', csv=True)
|
||||
option: Str('man_by_host*', cli_name='man_by_hosts', csv=True)
|
||||
option: Str('not_man_by_host*', cli_name='not_man_by_hosts', csv=True)
|
||||
option: Str('man_host*', cli_name='man_hosts', csv=True)
|
||||
option: Str('not_man_host*', cli_name='not_man_hosts', csv=True)
|
||||
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
|
||||
output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list of LDAP entries', domain='ipa', localedir=None))
|
||||
output: Output('count', <type 'int'>, None)
|
||||
|
||||
2
VERSION
2
VERSION
@@ -79,4 +79,4 @@ IPA_DATA_VERSION=20100614120000
|
||||
# #
|
||||
########################################################
|
||||
IPA_API_VERSION_MAJOR=2
|
||||
IPA_API_VERSION_MINOR=22
|
||||
IPA_API_VERSION_MINOR=23
|
||||
|
||||
@@ -1595,6 +1595,31 @@ class LDAPSearch(BaseLDAPCommand, crud.Search):
|
||||
for arg in super(crud.Search, self).get_args():
|
||||
yield arg
|
||||
|
||||
def get_member_options(self, attr):
|
||||
for ldap_obj_name in self.obj.attribute_members[attr]:
|
||||
ldap_obj = self.api.Object[ldap_obj_name]
|
||||
relationship = self.obj.relationships.get(
|
||||
attr, ['member', '', 'no_']
|
||||
)
|
||||
doc = self.member_param_incl_doc % (
|
||||
self.obj.object_name_plural, relationship[0].lower(),
|
||||
ldap_obj.object_name_plural
|
||||
)
|
||||
name = '%s%s' % (relationship[1], to_cli(ldap_obj_name))
|
||||
yield Str(
|
||||
'%s*' % name, cli_name='%ss' % name, doc=doc,
|
||||
label=ldap_obj.object_name, csv=True
|
||||
)
|
||||
doc = self.member_param_excl_doc % (
|
||||
self.obj.object_name_plural, relationship[0].lower(),
|
||||
ldap_obj.object_name_plural
|
||||
)
|
||||
name = '%s%s' % (relationship[2], to_cli(ldap_obj_name))
|
||||
yield Str(
|
||||
'%s*' % name, cli_name='%ss' % name, doc=doc,
|
||||
label=ldap_obj.object_name, csv=True
|
||||
)
|
||||
|
||||
def get_options(self):
|
||||
for option in super(LDAPSearch, self).get_options():
|
||||
yield option
|
||||
@@ -1602,29 +1627,8 @@ class LDAPSearch(BaseLDAPCommand, crud.Search):
|
||||
'no_output' not in self.obj.primary_key.flags:
|
||||
yield gen_pkey_only_option(self.obj.primary_key.cli_name)
|
||||
for attr in self.member_attributes:
|
||||
for ldap_obj_name in self.obj.attribute_members[attr]:
|
||||
ldap_obj = self.api.Object[ldap_obj_name]
|
||||
relationship = self.obj.relationships.get(
|
||||
attr, ['member', '', 'no_']
|
||||
)
|
||||
doc = self.member_param_incl_doc % (
|
||||
self.obj.object_name_plural, relationship[0].lower(),
|
||||
ldap_obj.object_name_plural
|
||||
)
|
||||
name = '%s%s' % (relationship[1], to_cli(ldap_obj_name))
|
||||
yield Str(
|
||||
'%s*' % name, cli_name='%ss' % name, doc=doc,
|
||||
label=ldap_obj.object_name, csv=True
|
||||
)
|
||||
doc = self.member_param_excl_doc % (
|
||||
self.obj.object_name_plural, relationship[0].lower(),
|
||||
ldap_obj.object_name_plural
|
||||
)
|
||||
name = '%s%s' % (relationship[2], to_cli(ldap_obj_name))
|
||||
yield Str(
|
||||
'%s*' % name, cli_name='%ss' % name, doc=doc,
|
||||
label=ldap_obj.object_name, csv=True
|
||||
)
|
||||
for option in self.get_member_options(attr):
|
||||
yield option
|
||||
|
||||
def get_member_filter(self, ldap, **options):
|
||||
filter = ''
|
||||
|
||||
@@ -33,6 +33,7 @@ from ipalib.plugins.dns import dns_container_exists, _record_types
|
||||
from ipalib.plugins.dns import add_forward_record
|
||||
from ipalib import _, ngettext
|
||||
from ipalib import x509
|
||||
from ipalib.dn import *
|
||||
from ipapython.ipautil import ipa_generate_password, CheckedIPAddress
|
||||
from ipalib.request import context
|
||||
import base64
|
||||
@@ -733,10 +734,56 @@ class host_find(LDAPSearch):
|
||||
)
|
||||
member_attributes = ['memberof', 'enrolledby', 'managedby']
|
||||
|
||||
def get_options(self):
|
||||
for option in super(host_find, self).get_options():
|
||||
yield option
|
||||
# "managing" membership has to be added and processed separately
|
||||
for option in self.get_member_options('managing'):
|
||||
yield option
|
||||
|
||||
def pre_callback(self, ldap, filter, attrs_list, base_dn, scope, *args, **options):
|
||||
if 'locality' in attrs_list:
|
||||
attrs_list.remove('locality')
|
||||
attrs_list.append('l')
|
||||
if 'man_host' in options or 'not_man_host' in options:
|
||||
hosts = []
|
||||
if options.get('man_host') is not None:
|
||||
for pkey in options.get('man_host', []):
|
||||
dn = self.obj.get_dn(pkey)
|
||||
try:
|
||||
(dn, entry_attrs) = ldap.get_entry(dn, ['managedby'])
|
||||
except errors.NotFound:
|
||||
self.obj.handle_not_found(pkey)
|
||||
hosts.append(set(entry_attrs.get('managedby', '')))
|
||||
hosts = list(reduce(lambda s1, s2: s1 & s2, hosts))
|
||||
|
||||
if not hosts:
|
||||
# There is no host managing _all_ hosts in --man-hosts
|
||||
filter = ldap.combine_filters(
|
||||
(filter, '(objectclass=disabled)'), ldap.MATCH_ALL
|
||||
)
|
||||
|
||||
not_hosts = []
|
||||
if options.get('not_man_host') is not None:
|
||||
for pkey in options.get('not_man_host', []):
|
||||
dn = self.obj.get_dn(pkey)
|
||||
try:
|
||||
(dn, entry_attrs) = ldap.get_entry(dn, ['managedby'])
|
||||
except errors.NotFound:
|
||||
self.obj.handle_not_found(pkey)
|
||||
not_hosts += entry_attrs.get('managedby', [])
|
||||
not_hosts = list(set(not_hosts))
|
||||
|
||||
for target_hosts, filter_op in ((hosts, ldap.MATCH_ANY),
|
||||
(not_hosts, ldap.MATCH_NONE)):
|
||||
hosts_avas = [DN(host)[0][0] for host in target_hosts]
|
||||
hosts_filters = [ldap.make_filter_from_attr(ava.attr, ava.value) for ava in hosts_avas]
|
||||
hosts_filter = ldap.combine_filters(hosts_filters, filter_op)
|
||||
|
||||
filter = ldap.combine_filters(
|
||||
(filter, hosts_filter), ldap.MATCH_ALL
|
||||
)
|
||||
|
||||
return (filter.replace('locality', 'l'), base_dn, scope)
|
||||
|
||||
def post_callback(self, ldap, entries, truncated, *args, **options):
|
||||
|
||||
@@ -390,6 +390,39 @@ class test_host(Declarative):
|
||||
),
|
||||
),
|
||||
|
||||
dict(
|
||||
desc='Search for hosts with --man-hosts and --not-man-hosts',
|
||||
command=('host_find', [], {'man_host' : fqdn3, 'not_man_host' : fqdn1}),
|
||||
expected=dict(
|
||||
count=1,
|
||||
truncated=False,
|
||||
summary=u'1 host matched',
|
||||
result=[
|
||||
dict(
|
||||
dn=lambda x: DN(x) == dn3,
|
||||
fqdn=[fqdn3],
|
||||
description=[u'Test host 2'],
|
||||
l=[u'Undisclosed location 2'],
|
||||
krbprincipalname=[u'host/%s@%s' % (fqdn3, api.env.realm)],
|
||||
has_keytab=False,
|
||||
has_password=False,
|
||||
managedby_host=[u'%s' % fqdn3, u'%s' % fqdn1],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
dict(
|
||||
desc='Try to search for hosts with --man-hosts',
|
||||
command=('host_find', [], {'man_host' : [fqdn3,fqdn4]}),
|
||||
expected=dict(
|
||||
count=0,
|
||||
truncated=False,
|
||||
summary=u'0 hosts matched',
|
||||
result=[],
|
||||
),
|
||||
),
|
||||
|
||||
dict(
|
||||
desc='Remove managedby_host %r from %r' % (fqdn1, fqdn3),
|
||||
command=('host_remove_managedby', [fqdn3],
|
||||
|
||||
Reference in New Issue
Block a user