On 19.8.2015 10:57, Jan Cholasta wrote:
On 19.8.2015 10:47, thierry bordaz wrote:
On 08/19/2015 10:34 AM, Jan Cholasta wrote:
On 19.8.2015 09:39, thierry bordaz wrote:
Hi,
It worked like a charm.
I had a problem to commit it because of the VERSION stuff that changed.
Except that (changing VERSION), the fix looks good to me
thanks
thierry
On 08/18/2015 07:21 PM, Martin Basti wrote:
Thank you for the patch, I checked it, I just changed permission name
to have all first letters in uppercase as others.
Updated merged patch attached.
On 08/18/2015 05:34 PM, thierry bordaz wrote:
On 08/18/2015 04:13 PM, thierry bordaz wrote:
On 08/18/2015 04:04 PM, Martin Basti wrote:
On 08/18/2015 03:49 PM, thierry bordaz wrote:
On 08/18/2015 03:06 PM, Martin Basti wrote:
On 08/18/2015 11:32 AM, thierry bordaz wrote:
On 08/18/2015 10:02 AM, Martin Basti wrote:
On 08/18/2015 09:59 AM, thierry bordaz wrote:
On 08/18/2015 09:55 AM, Martin Basti wrote:
On 08/18/2015 09:50 AM, thierry bordaz wrote:
On 08/17/2015 08:33 PM, Martin Basti wrote:
Hello,
the 'user-stage' command replaces 'stageuser-add
--from-delete' command.
https://fedorahosted.org/freeipa/ticket/5041
Thierry can you check If I don't break everything, it works
for me, but the one never knows.
Honza can you please check the framework side? I use
self.api.Object.stageuser.add.* in user command, I'm not
sure if this is right way, but it works.
Patch attached. I created it in hurry, I'm expecting
NACK :D
Just question at the end: should I implement way Active
user -> stageuser? IMHO it would be implemented internally
by calling 'user-del --preserve' inside 'user-stage'.
Hi Martin,
There is a small failure with VERSION (edewata pushed his
patch first ;-) )
git apply -v
/tmp/freeipa-mbasti-0297-Add-user-stage-command.patch
Checking patch API.txt...
Checking patch VERSION...
error: while searching for:
# #
########################################################
IPA_API_VERSION_MAJOR=2
IPA_API_VERSION_MINOR=148
# Last change: ftweedal - add --out option to user-show
error: patch failed: VERSION:90
error: VERSION: patch does not apply
Checking patch ipalib/plugins/stageuser.py...
Checking patch ipalib/plugins/user.py...
There is many pending patches that may change VERSION number,
I will change it to right one before push.
Does code looks good for you?
Hi Martin,
Just a question, there is no additional permission. Did you
test being 'admin' ?
thanks
theirry
No I didn't,.
I preserver all permission, the original permissions should
work.
Martin
Hi Martin,
Running a test script, I have an issue with
ipa stageuser-add --first=t --last=b tb1
ipa: ERROR: an internal error has occurred
[Tue Aug 18 11:16:56.440658 2015] [wsgi:error] [pid 10486]
ipa: INFO: [jsonserver_kerb]
stage...@abc.idm.lab.eng.brq.redhat.com:
stageuser_add(u'tb1', givenname=u't', sn=u'b', cn=u't b',
displayname=u't b', initials=u'tb', gecos=u't b',
krbprincipalname=u't...@abc.idm.lab.eng.brq.redhat.com',
random=False, all=False, raw=False, version=u'2.149',
no_members=False): AttributeError
[Tue Aug 18 11:21:25.198021 2015] [wsgi:error] [pid 10485]
ipa: ERROR: non-public: AttributeError: 'DN' object has no
attribute 'setdefault'
[Tue Aug 18 11:21:25.198053 2015] [wsgi:error] [pid 10485]
Traceback (most recent call last):
[Tue Aug 18 11:21:25.198058 2015] [wsgi:error] [pid 10485]
File
"/usr/lib/python2.7/site-packages/ipaserver/rpcserver.py",
line 347, in wsgi_execute
[Tue Aug 18 11:21:25.198062 2015] [wsgi:error] [pid
10485] result = self.Command[name](*args, **options)
[Tue Aug 18 11:21:25.198066 2015] [wsgi:error] [pid 10485]
File "/usr/lib/python2.7/site-packages/ipalib/frontend.py",
line 443, in __call__
[Tue Aug 18 11:21:25.198070 2015] [wsgi:error] [pid
10485] ret = self.run(*args, **options)
[Tue Aug 18 11:21:25.198081 2015] [wsgi:error] [pid 10485]
File "/usr/lib/python2.7/site-packages/ipalib/frontend.py",
line 760, in run
[Tue Aug 18 11:21:25.198133 2015] [wsgi:error] [pid
10485] return self.execute(*args, **options)
[Tue Aug 18 11:21:25.198139 2015] [wsgi:error] [pid 10485]
File
"/usr/lib/python2.7/site-packages/ipalib/plugins/baseldap.py",
line 1227, in execute
[Tue Aug 18 11:21:25.198144 2015] [wsgi:error] [pid
10485] *keys, **options)
[Tue Aug 18 11:21:25.198147 2015] [wsgi:error] [pid 10485]
File
"/usr/lib/python2.7/site-packages/ipalib/plugins/stageuser.py",
line 373, in pre_callback
[Tue Aug 18 11:21:25.198151 2015] [wsgi:error] [pid
10485] attrs_list, *keys, **options)
[Tue Aug 18 11:21:25.198155 2015] [wsgi:error] [pid 10485]
File
"/usr/lib/python2.7/site-packages/ipalib/plugins/stageuser.py",
line 277, in set_default_values_pre_callback
[Tue Aug 18 11:21:25.198159 2015] [wsgi:error] [pid 10485]
entry_attrs.setdefault('description', [])
[Tue Aug 18 11:21:25.198163 2015] [wsgi:error] [pid 10485]
AttributeError: 'DN' object has no attribute 'setdefault'
[Tue Aug 18 11:21:25.199276 2015] [wsgi:error] [pid 10485]
ipa: INFO: [jsonserver_session]
stage...@abc.idm.lab.eng.brq.redhat.com:
stageuser_add(u'tb1', givenname=u't', sn=u'b', cn=u't b',
displayname=u't b', initials=u'tb', gecos=u't b',
krbprincipalname=u't...@abc.idm.lab.eng.brq.redhat.com',
random=False, all=False, raw=False, version=u'2.149',
no_members=False): AttributeError
The new set_default_values_pre_callback, can not use the
set_default function. It is not clear why. entry_attrs is one of
pre_callback parameter.
Should set_default_values_pre_callback be a subfonction of
pre_callback ?
thanks
thierry
Thank you,
updated patch attached.
So far, tests are ok.
Just one comment, the 'user-stage' command description is wrong,
as it moves an active user into the staged area
user-stage Move deleted user into
staged area
No, it's not doing that.
user-stage is replacement of stageuser-add --from-delete, it
doesn't work for active users.
The support to move active user to staged area is RFE, I did not
implemented it yet, and I dont know if this will fit IPA 4.2
timeframe
Ok. thanks.
Sure user-stage (active->stage) will not fit into IPA 4.2 timeframe.
Running the tests being admin, there is no problem.
I have a permission issue, when running as 'Stage administrator'.
The 'delete' entry being moved to 'stage' container, we need the a
special permission for it.
Hello,
I tested this new permission to grant 'Stage user administrator' to
do a 'user-stage'.
Is it ok to add it to your patch ?
thanks
thierry
[root@vm-141 ~]# ipa user-del ttest1 --preserve
---------------------
Deleted user "ttest1"
---------------------
[root@vm-141 ~]# ipa user-stage ttest1
ipa: ERROR: Insufficient access: Insufficient 'moddn' privilege to
move an entry to 'cn=staged
users,cn=accounts,cn=provisioning,dc=abc,dc=idm,dc=lab,dc=eng,dc=brq,dc=redhat,dc=com'.
[root@vm-141 ~]# klist
Ticket cache: KEYRING:persistent:0:krb_ccache_hw3P667
Default principal: stage...@abc.idm.lab.eng.brq.redhat.com
Valid starting Expires Service principal
08/18/2015 15:45:43 08/19/2015 15:45:42
ldap/vm-141.abc.idm.lab.eng.brq.redhat....@abc.idm.lab.eng.brq.redhat.com
08/18/2015 15:45:42 08/19/2015 15:45:42
krbtgt/abc.idm.lab.eng.brq.redhat....@abc.idm.lab.eng.brq.redhat.com
[root@vm-141 ~]# kinit admin
Password for ad...@abc.idm.lab.eng.brq.redhat.com:
[root@vm-141 ~]# ipa user-stage ttest1
----------------------------
Staged user account "ttest1"
----------------------------
[root@vm-141 ~]# ipa stageuser-find ttest1
--------------
1 user matched
--------------
User login: ttest1
First name: t
Last name: test1
Home directory: /home/ttest1
Login shell: /bin/sh
Email address: tte...@abc.idm.lab.eng.brq.redhat.com
UID: 1814000011
GID: 1814000011
Password: False
Kerberos keys available: False
----------------------------
Number of entries returned 1
----------------------------
NACK.
1) Use ADD+DEL instead of MODRDN as we agreed before:
<https://www.redhat.com/archives/freeipa-devel/2015-August/msg00148.html>.
Hi,
I have a slight preference doing MODRDN than ADD+DEL but I think it is
for corner case.
Before preserving a user, the user was active and could be updated. If
the user gets updated on a replica (e.g. change its phonenumer) but for
some reason the update is not immediately replicated, then a later
'user-del --preserve' + 'user-stage' will stage the user without the
updated phonenumber.
In addition, doing 2 ops rather than one costs more and is not atomic
(more complex to handle failure).
The same problem exists for stageuser_activate, and unless you want to
change it to use MODRDN as well, user_stage must use ADD+DEL.
This was already discussed quite thoroughly and we reached the decision
to use ADD+DEL, because it is consistent with the rest of the user code.
I don't see a point in discussing this further and rehashing what was
already said.
thank
thierry
2) You can't use the entry preparation code from stageuser-add in
user-stage - it is supposed to normalize user input, not already
normalized data from LDAP, and could lead to subtle and hard to track
errors.
Honza
I have updated Martin's patch with fixes for the above. See attachment.
--
Jan Cholasta
From 8caeda38d49aff277a16f6dea32cf7e534c54caa Mon Sep 17 00:00:00 2001
From: Martin Basti <mba...@redhat.com>
Date: Mon, 17 Aug 2015 20:11:21 +0200
Subject: [PATCH] Add user-stage command
This patch replaces 'stageuser-add --from-delete' with new command
user-stage.
Original way always required to specify first and last name, and
overall combination of options was hard to manage. The new command
requires only login of deleted user (user-del --preserve).
https://fedorahosted.org/freeipa/ticket/5041
---
API.txt | 10 ++++++++-
VERSION | 4 ++--
ipalib/plugins/stageuser.py | 44 +++++++-------------------------------
ipalib/plugins/user.py | 51 +++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 70 insertions(+), 39 deletions(-)
diff --git a/API.txt b/API.txt
index dd6bcc3..1944a6f 100644
--- a/API.txt
+++ b/API.txt
@@ -4211,7 +4211,7 @@ option: Str('displayname', attribute=True, autofill=True, cli_name='displayname'
option: Str('employeenumber', attribute=True, cli_name='employeenumber', multivalue=False, required=False)
option: Str('employeetype', attribute=True, cli_name='employeetype', multivalue=False, required=False)
option: Str('facsimiletelephonenumber', attribute=True, cli_name='fax', multivalue=True, required=False)
-option: Flag('from_delete?', autofill=True, cli_name='from_delete', default=False)
+option: DeprecatedParam('from_delete?', cli_name='from_delete', default=False)
option: Str('gecos', attribute=True, autofill=True, cli_name='gecos', multivalue=False, required=False)
option: Int('gidnumber', attribute=True, cli_name='gidnumber', minvalue=1, multivalue=False, required=False)
option: Str('givenname', attribute=True, cli_name='first', multivalue=False, required=True)
@@ -5371,6 +5371,14 @@ option: Str('version?', exclude='webui')
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: PrimaryKey('value', None, None)
+command: user_stage
+args: 1,2,3
+arg: Str('uid', attribute=True, cli_name='login', maxlength=255, multivalue=True, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?$', primary_key=True, query=True, required=True)
+option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('version?', exclude='webui')
+output: Output('result', <type 'dict'>, None)
+output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
+output: ListOfPrimaryKeys('value', None, None)
command: user_status
args: 1,4,4
arg: Str('uid', attribute=True, cli_name='login', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?$', primary_key=True, query=True, required=True)
diff --git a/VERSION b/VERSION
index 0ccfd09..e8387a1 100644
--- a/VERSION
+++ b/VERSION
@@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000
# #
########################################################
IPA_API_VERSION_MAJOR=2
-IPA_API_VERSION_MINOR=151
-# Last change: cheimes - Add flag to list all service and user vaults
+IPA_API_VERSION_MINOR=152
+# Last change: mbasti - add 'user-stage' command
diff --git a/ipalib/plugins/stageuser.py b/ipalib/plugins/stageuser.py
index 29739d5..f378853 100644
--- a/ipalib/plugins/stageuser.py
+++ b/ipalib/plugins/stageuser.py
@@ -23,7 +23,8 @@ import posixpath
import os
from copy import deepcopy
from ipalib import api, errors
-from ipalib import Flag, Int, Password, Str, Bool, StrEnum, DateTime
+from ipalib import (Flag, Int, Password, Str, Bool, StrEnum, DateTime,
+ DeprecatedParam)
from ipalib.plugable import Registry
from ipalib.plugins.baseldap import LDAPCreate, LDAPQuery, LDAPSearch, DN, entry_to_dict, pkey_to_value
from ipalib.plugins import baseldap
@@ -260,7 +261,7 @@ class stageuser_add(baseuser_add):
has_output_params = baseuser_add.has_output_params + stageuser_output_params
takes_options = LDAPCreate.takes_options + (
- Flag('from_delete?',
+ DeprecatedParam('from_delete?',
doc=_('Create Stage user in from a delete user'),
cli_name='from_delete',
default=False,
@@ -270,13 +271,12 @@ class stageuser_add(baseuser_add):
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
assert isinstance(dn, DN)
- if not options.get('from_delete'):
- # then givenname and sn are required attributes
- if 'givenname' not in entry_attrs:
- raise errors.RequirementError(name='givenname', error=_('givenname is required'))
+ # then givenname and sn are required attributes
+ if 'givenname' not in entry_attrs:
+ raise errors.RequirementError(name='givenname', error=_('givenname is required'))
- if 'sn' not in entry_attrs:
- raise errors.RequirementError(name='sn', error=_('sn is required'))
+ if 'sn' not in entry_attrs:
+ raise errors.RequirementError(name='sn', error=_('sn is required'))
# we don't want an user private group to be created for this user
# add NO_UPG_MAGIC description attribute to let the DS plugin know
@@ -367,34 +367,6 @@ class stageuser_add(baseuser_add):
return dn
- def execute(self, *keys, **options):
- '''
- A stage entry may be taken from the Delete container.
- In that case we rather do 'MODRDN' than 'ADD'.
- '''
- if options.get('from_delete'):
- ldap = self.obj.backend
-
- staging_dn = self.obj.get_dn(*keys, **options)
- delete_dn = DN(staging_dn[0], self.obj.delete_container_dn, api.env.basedn)
- new_dn = DN(staging_dn[0], self.obj.stage_container_dn, api.env.basedn)
- # Check that this value is a Active user
- try:
- entry_attrs = self._exc_wrapper(keys, options, ldap.get_entry)(delete_dn, ['dn'])
- except errors.NotFound:
- self.obj.handle_not_found(*keys)
-
- self._exc_wrapper(keys, options, ldap.move_entry)(
- delete_dn, new_dn)
- entry_attrs = entry_to_dict(entry_attrs, **options)
- entry_attrs['dn'] = new_dn
-
- if self.obj.primary_key and keys[-1] is not None:
- return dict(result=entry_attrs, value=keys[-1])
- return dict(result=entry_attrs, value=u'')
- else:
- return super(stageuser_add, self).execute(*keys, **options)
-
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
assert isinstance(dn, DN)
config = ldap.get_ipa_config()
diff --git a/ipalib/plugins/user.py b/ipalib/plugins/user.py
index 1d6073b..fb4e994 100644
--- a/ipalib/plugins/user.py
+++ b/ipalib/plugins/user.py
@@ -859,6 +859,57 @@ class user_undel(LDAPQuery):
value=pkey_to_value(keys[0], options),
)
+
+@register()
+class user_stage(LDAPMultiQuery):
+ __doc__ = _('Move deleted user into staged area')
+
+ has_output = output.standard_multi_delete
+ msg_summary = _('Staged user account "%(value)s"')
+
+ def execute(self, *keys, **options):
+ staged = []
+ failed = []
+
+ for key in keys[-1]:
+ single_keys = keys[:-1] + (key,)
+ multi_keys = keys[:-1] + ((key,),)
+
+ user = self.api.Command.user_show(*single_keys, all=True)['result']
+ new_options = {}
+ for param in self.api.Command.stageuser_add.options():
+ try:
+ value = user[param.name]
+ except KeyError:
+ continue
+ if param.multivalue and not isinstance(value, (list, tuple)):
+ value = [value]
+ elif not param.multivalue and isinstance(value, (list, tuple)):
+ value = value[0]
+ new_options[param.name] = value
+
+ try:
+ self.api.Command.stageuser_add(*single_keys, **new_options)
+ try:
+ self.api.Command.user_del(*multi_keys, preserve=False)
+ except errors.ExecutionError:
+ self.api.Command.stageuser_del(*multi_keys)
+ raise
+ except errors.ExecutionError:
+ if not options['continue']:
+ raise
+ failed.append(key)
+ else:
+ staged.append(key)
+
+ return dict(
+ result=dict(
+ failed=pkey_to_value(failed, options),
+ ),
+ value=pkey_to_value(staged, options),
+ )
+
+
@register()
class user_disable(LDAPQuery):
__doc__ = _('Disable a user account.')
--
2.4.3
--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code