mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
automember rebuild nowait feature added
automember-rebuild uses asynchronous 389 task, and returned success even if the task didn't run. this patch fixes this issue adding a --nowait parameter to 'ipa automember-rebuild', defaulting to False, thus when the script runs without it, it waits for the 'nstaskexitcode' attribute, which means the task has finished. Old usage can be enabled using --nowait, and returns the DN of the task for further polling. New tests added also. https://fedorahosted.org/freeipa/ticket/4239 Reviewed-By: Petr Viktorin <pviktori@redhat.com>
This commit is contained in:
committed by
Petr Viktorin
parent
c58d6b2689
commit
8b91d9a6e8
7
API.txt
7
API.txt
@@ -201,12 +201,15 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
|
||||
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
|
||||
output: Output('value', <type 'unicode'>, None)
|
||||
command: automember_rebuild
|
||||
args: 0,4,3
|
||||
args: 0,7,3
|
||||
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
|
||||
option: Str('hosts*')
|
||||
option: Flag('no_wait?', autofill=True, default=False)
|
||||
option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
|
||||
option: StrEnum('type', cli_name='type', multivalue=False, required=False, values=(u'group', u'hostgroup'))
|
||||
option: Str('users*')
|
||||
option: Str('version?', exclude='webui')
|
||||
output: Output('result', <type 'bool'>, None)
|
||||
output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
|
||||
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
|
||||
output: Output('value', <type 'unicode'>, None)
|
||||
command: automember_remove_condition
|
||||
|
||||
4
VERSION
4
VERSION
@@ -89,5 +89,5 @@ IPA_DATA_VERSION=20100614120000
|
||||
# #
|
||||
########################################################
|
||||
IPA_API_VERSION_MAJOR=2
|
||||
IPA_API_VERSION_MINOR=81
|
||||
# Last change: amisnyov - user plugin extend
|
||||
IPA_API_VERSION_MINOR=82
|
||||
# Last change: amisnyov - automember nowait add
|
||||
|
||||
@@ -1530,6 +1530,22 @@ class DNSDataMismatch(ExecutionError):
|
||||
format = _('DNS check failed: Expected {%(expected)s} got {%(got)s}')
|
||||
|
||||
|
||||
class TaskTimeout(DatabaseError):
|
||||
"""
|
||||
**4213** Raised when an LDAP task times out
|
||||
|
||||
For example:
|
||||
|
||||
>>> raise TaskTimeout()
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
TaskTimeout: Automember LDAP task timeout, Task DN: ''
|
||||
"""
|
||||
|
||||
errno = 4213
|
||||
format = _("%(task)s LDAP task timeout, Task DN: '%(task_dn)s'")
|
||||
|
||||
|
||||
class CertificateError(ExecutionError):
|
||||
"""
|
||||
**4300** Base class for Certificate execution errors (*4300 - 4399*).
|
||||
|
||||
@@ -17,8 +17,11 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import uuid
|
||||
import time
|
||||
|
||||
import ldap as _ldap
|
||||
from ipalib import api, errors, Str, StrEnum, _, ngettext
|
||||
|
||||
from ipalib import api, errors, Str, StrEnum, DNParam, _, ngettext
|
||||
from ipalib.plugins.baseldap import *
|
||||
from ipalib.request import context
|
||||
from ipapython.dn import DN
|
||||
@@ -623,9 +626,21 @@ class automember_rebuild(Command):
|
||||
label=_('Hosts'),
|
||||
doc=_('Rebuild membership for specified hosts'),
|
||||
),
|
||||
Flag(
|
||||
'no_wait?',
|
||||
default=False,
|
||||
label=_('No wait'),
|
||||
doc=_("Don't wait for rebuilding membership"),
|
||||
),
|
||||
)
|
||||
has_output = output.standard_entry
|
||||
has_output_params = (
|
||||
DNParam(
|
||||
'dn',
|
||||
label=_('Task DN'),
|
||||
doc=_('DN of the started task'),
|
||||
),
|
||||
)
|
||||
has_output = output.standard_value
|
||||
msg_summary = _('Automember rebuild membership task completed')
|
||||
|
||||
def validate(self, **kw):
|
||||
"""
|
||||
@@ -693,20 +708,51 @@ class automember_rebuild(Command):
|
||||
else:
|
||||
search_filter = '(%s=*)' % obj.primary_key.name
|
||||
|
||||
task_dn = DN(
|
||||
('cn', cn),
|
||||
('cn', 'automember rebuild membership'),
|
||||
('cn', 'tasks'),
|
||||
('cn', 'config'))
|
||||
|
||||
entry = ldap.make_entry(
|
||||
DN(
|
||||
('cn', cn),
|
||||
('cn', 'automember rebuild membership'),
|
||||
('cn', 'tasks'),
|
||||
('cn', 'config'),
|
||||
),
|
||||
task_dn,
|
||||
objectclass=['top', 'extensibleObject'],
|
||||
cn=[cn],
|
||||
basedn=[basedn],
|
||||
filter=[search_filter],
|
||||
scope=['sub']
|
||||
)
|
||||
scope=['sub'],
|
||||
ttl=[3600])
|
||||
ldap.add_entry(entry)
|
||||
return dict(result=True, value=u'')
|
||||
|
||||
summary = _('Automember rebuild membership task started')
|
||||
result = {'dn': task_dn}
|
||||
|
||||
if not options.get('no_wait'):
|
||||
summary = _('Automember rebuild membership task completed')
|
||||
result = {}
|
||||
start_time = time.time()
|
||||
|
||||
while True:
|
||||
try:
|
||||
task = ldap.get_entry(task_dn)
|
||||
except errors.NotFound:
|
||||
break
|
||||
|
||||
if 'nstaskexitcode' in task:
|
||||
if str(task.single_value['nstaskexitcode']) == '0':
|
||||
summary=task.single_value['nstaskstatus']
|
||||
break
|
||||
else:
|
||||
raise errors.DatabaseError(
|
||||
desc=task.single_value['nstaskstatus'],
|
||||
info=_("Task DN = '%s'" % task_dn))
|
||||
time.sleep(1)
|
||||
if time.time() > (start_time + 60):
|
||||
raise errors.TaskTimeout(task=_('Automember'), task_dn=task_dn)
|
||||
|
||||
return dict(
|
||||
result=result,
|
||||
summary=unicode(summary),
|
||||
value=u'')
|
||||
|
||||
api.register(automember_rebuild)
|
||||
|
||||
@@ -24,7 +24,8 @@ Test the `ipalib/plugins/automember.py` module.
|
||||
from ipalib import api, errors
|
||||
from ipapython.dn import DN
|
||||
from ipatests.test_xmlrpc import objectclasses
|
||||
from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid
|
||||
from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid, \
|
||||
fuzzy_automember_dn, fuzzy_automember_message
|
||||
from ipatests.test_xmlrpc.test_user_plugin import get_user_result
|
||||
|
||||
|
||||
@@ -242,8 +243,20 @@ class test_automember(Declarative):
|
||||
command=('automember_rebuild', [], dict(type=u'hostgroup')),
|
||||
expected=dict(
|
||||
value=u'',
|
||||
summary=u'Automember rebuild membership task completed',
|
||||
result=True
|
||||
summary=fuzzy_automember_message,
|
||||
result=dict()
|
||||
),
|
||||
),
|
||||
|
||||
dict(
|
||||
desc='Rebuild membership for hostgroups asynchronously',
|
||||
command=('automember_rebuild', [], dict(type=u'hostgroup',no_wait=True)),
|
||||
expected=dict(
|
||||
value=u'',
|
||||
summary=u'Automember rebuild membership task started',
|
||||
result=dict(
|
||||
dn=fuzzy_automember_dn
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -349,8 +362,20 @@ class test_automember(Declarative):
|
||||
command=('automember_rebuild', [], dict(hosts=fqdn1)),
|
||||
expected=dict(
|
||||
value=u'',
|
||||
summary=u'Automember rebuild membership task completed',
|
||||
result=True
|
||||
summary=fuzzy_automember_message,
|
||||
result=dict()
|
||||
),
|
||||
),
|
||||
|
||||
dict(
|
||||
desc='Rebuild membership for host: %s asynchronously' % fqdn1,
|
||||
command=('automember_rebuild', [], dict(hosts=fqdn1, no_wait=True)),
|
||||
expected=dict(
|
||||
value=u'',
|
||||
summary=u'Automember rebuild membership task started',
|
||||
result=dict(
|
||||
dn=fuzzy_automember_dn
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -519,8 +544,20 @@ class test_automember(Declarative):
|
||||
command=('automember_rebuild', [], dict(type=u'group')),
|
||||
expected=dict(
|
||||
value=u'',
|
||||
summary=u'Automember rebuild membership task completed',
|
||||
result=True
|
||||
summary=fuzzy_automember_message,
|
||||
result=dict()
|
||||
),
|
||||
),
|
||||
|
||||
dict(
|
||||
desc='Rebuild membership for groups asynchronously',
|
||||
command=('automember_rebuild', [], dict(type=u'group', no_wait=True)),
|
||||
expected=dict(
|
||||
value=u'',
|
||||
summary=u'Automember rebuild membership task started',
|
||||
result=dict(
|
||||
dn=fuzzy_automember_dn
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -584,8 +621,20 @@ class test_automember(Declarative):
|
||||
command=('automember_rebuild', [], dict(users=user1)),
|
||||
expected=dict(
|
||||
value=u'',
|
||||
summary=u'Automember rebuild membership task completed',
|
||||
result=True
|
||||
summary=fuzzy_automember_message,
|
||||
result=dict()
|
||||
),
|
||||
),
|
||||
|
||||
dict(
|
||||
desc='Rebuild membership for user: %s asynchronously' % user1,
|
||||
command=('automember_rebuild', [], dict(users=user1, no_wait=True)),
|
||||
expected=dict(
|
||||
value=u'',
|
||||
summary=u'Automember rebuild membership task started',
|
||||
result=dict(
|
||||
dn=fuzzy_automember_dn
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
|
||||
@@ -38,6 +38,16 @@ uuid_re = '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'
|
||||
# Matches an ipauniqueid like u'784d85fd-eae7-11de-9d01-54520012478b'
|
||||
fuzzy_uuid = Fuzzy('^%s$' % uuid_re)
|
||||
|
||||
# Matches an automember task DN
|
||||
fuzzy_automember_dn = Fuzzy(
|
||||
'^cn=%s,cn=automember rebuild membership,cn=tasks,cn=config$' % uuid_re
|
||||
)
|
||||
|
||||
# Matches an automember task finish message
|
||||
fuzzy_automember_message = Fuzzy(
|
||||
'^Automember rebuild task finished\. Processed \(\d+\) entries\.$'
|
||||
)
|
||||
|
||||
# Matches trusted domain GUID, like u'463bf2be-3456-4a57-979e-120304f2a0eb'
|
||||
fuzzy_guid = fuzzy_uuid
|
||||
|
||||
|
||||
Reference in New Issue
Block a user