Yuvipanda has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/301058

Change subject: WIP replacement of modify-ldap-groups
......................................................................

WIP replacement of modify-ldap-groups

Change-Id: Ibc9e5bf28826804e90b9ae143bcdd4cf0020b11d
---
M modules/ldap/files/scripts/modify-ldap-group
1 file changed, 91 insertions(+), 132 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/operations/puppet 
refs/changes/58/301058/1

diff --git a/modules/ldap/files/scripts/modify-ldap-group 
b/modules/ldap/files/scripts/modify-ldap-group
index 6c7978d..9dd3c22 100755
--- a/modules/ldap/files/scripts/modify-ldap-group
+++ b/modules/ldap/files/scripts/modify-ldap-group
@@ -1,143 +1,102 @@
-#!/usr/bin/python
-
-#####################################################################
-### THIS FILE IS MANAGED BY PUPPET
-### puppet:///modules/ldap/scripts/modify-ldap-group
-#####################################################################
-
-import sys
-import grp
-import traceback
-import ldapsupportlib
-import copy
-from optparse import OptionParser
-
-try:
-    import ldap
-    import ldap.modlist
-except ImportError:
-    sys.stderr.write("Unable to import LDAP library.\n")
-    sys.exit(1)
+#!/usr/bin/python3
+"""
+Add / Remove users from LDAP group
+"""
+import ldap3
+import yaml
+import argparse
 
 
-def main():
-    parser = OptionParser(conflict_handler="resolve")
-    parser.set_usage('modify-ldap-group [options] <groupname> [--rename 
<newusergroup>]\nexample: modify-ldap-group --gid=501 wikidev')
+def get_members_list(conn, basedn, group, user):
+    """
+    Get list of members of the given group
+    """
+    conn.search(
+        'ou=groups,{base}'.format(base=basedn),
+        '(cn={group})'.format(group=group),
+        ldap3.SEARCH_SCOPE_WHOLE_SUBTREE,
+        attributes=['member']
+    )
+    return conn.response[0]['attributes']['member']
 
-    ldapSupportLib = ldapsupportlib.LDAPSupportLib()
-    ldapSupportLib.addParserOptions(parser, "scriptuser")
 
-    parser.add_option("-m", "--directorymanager", action="store_true", 
dest="directorymanager", help="Use the Directory Manager's credentials, rather 
than your own")
-    parser.add_option("--gid", action="store", dest="gidNumber", help="Set the 
group's gid")
-    parser.add_option("--rename", action="store_true", dest="rename", 
help="Rename the user")
-    parser.add_option("--addmembers", action="store", dest="addMembers", 
help="Add a comma separated list of users to this group")
-    parser.add_option("--deletemembers", action="store", dest="deleteMembers", 
help="Delete a comma separated list of users from this")
-    (options, args) = parser.parse_args()
+def add_member(conn, basedn, group, user):
+    """
+    Adds user to group as a mmeber
+    """
+    userdn = 'uid={user},ou=people,{base}'.format(
+        user=user,
+        base=basedn,
+    )
+    groupdn = 'cn={group},ou=groups,{base}'.format(
+        group=group,
+        base=basedn,
+    )
+    members = get_members_list(conn, basedn, group, user)
+    if userdn in members:
+        raise Exception("User already is member of given group")
+    members.append(userdn)
+    op = {
+        'member': [(ldap3.MODIFY_REPLACE, [members])]
+    }
+    return conn.modify(groupdn, op).result
 
-    if len(args) != 1:
-        if options.rename and len(args) != 2:
-            parser.error("modify-ldap-group expects exactly two arguments when 
using rename.")
-        elif not options.rename:
-            parser.error("modify-ldap-group expects exactly one argument, 
unless using --rename.")
 
-    ldapSupportLib.setBindInfoByOptions(options, parser)
+def remove_member(conn, basedn, group, user):
+    """
+    Remove user from group as a member
+    """
+    userdn = 'uid={user},ou=people,{base}'.format(
+        user=user,
+        base=basedn,
+    )
+    groupdn = 'cn={group},ou=groups,{base}'.format(
+        group=group,
+        base=basedn,
+    )
+    members = get_members_list(conn, basedn, group, user)
+    if userdn not in members:
+        raise Exception("User already is not a member of given group")
+    members.remove(userdn)
+    op = {
+        'member': [(ldap3.MODIFY_REPLACE, [members])]
+    }
+    return conn.modify(groupdn, op).result
 
-    base = ldapSupportLib.getBase()
 
-    ds = ldapSupportLib.connect()
+if __name__ == '__main__':
+    parser = argparse.ArgumentParser()
+    parser.add_argument(
+        'action',
+        help='Action to perform',
+        choices=['adduser', 'removeuser'],
+    )
+    parser.add_argument(
+        'group',
+        help='Name of group to modify',
+    )
+    parser.add_argument(
+        'user',
+        help='Name of user to add/remove'
+    )
+    parser.add_argument(
+        '--ldapconfig',
+        help='Path to LDAP connection config in YAML format',
+        default='/etc/ldap.scriptuser.yaml',
+    )
 
-    # w00t We're in!
-    try:
-        groupname = args[0]
-        PosixData = ds.search_s("ou=groups," + base, ldap.SCOPE_SUBTREE, 
"(&(objectclass=posixGroup)(cn=" + groupname + "))")
-        if not PosixData:
-            raise ldap.NO_SUCH_OBJECT()
-        dn = PosixData[0][0]
+    args = parser.parse_args()
 
-        if options.rename:
-            newgroupname = args[1]
+    with open(args.ldapconfig, encoding='utf-8') as f:
+        ldapconfig = yaml.safe_load(f)
 
-            # Rename the entry
-            newrdn = 'cn=' + newgroupname
-            ds.rename_s(dn, newrdn)
-        else:
-            PosixData = PosixData[0][1]
-            NewPosixData = copy.deepcopy(PosixData)
-            if options.gidNumber:
-                try:
-                    groupcheck = grp.getgrgid(options.gidNumber)
-                    raise ldap.TYPE_OR_VALUE_EXISTS()
-                except KeyError:
-                    NewPosixData['gidNumber'] = options.gidNumber
-            if options.addMembers:
-                raw_members = options.addMembers.split(',')
-                for raw_member in raw_members:
-                    try:
-                        user=ds.search_s("ou=people," + base, 
ldap.SCOPE_SUBTREE, "uid=%s" % raw_member, ("dn",))
-                        if len(user) == 0:
-                            sys.stderr.write(raw_member + " doesn't exist, and 
won't be added to the group.\n")
-                            return
-                        if len(user) > 1:
-                            sys.stderr.write(raw_member + " exist multiple 
times, this is so wrong, abandon all hope\n")
-                            return
-                    except Exception as e:
-                        sys.stderr.write("Failed to search user in LDAP. 
Error: %s\n" % str(e))
-                        raise e
-                    membertoadd = user[0][0]
-                    # member expects DNs
-                    if 'member' in NewPosixData.keys():
-                        if membertoadd in NewPosixData['member']:
-                            sys.stderr.write(raw_member + " is already a 
member of the group, skipping.\n")
-                        else:
-                            NewPosixData['member'].append(membertoadd)
-                    else:
-                        NewPosixData['member'] = [membertoadd]
-            elif options.deleteMembers:
-                raw_members = options.deleteMembers.split(',')
-                for raw_member in raw_members:
-                    membertoremove = 'uid=' + raw_member + ',ou=people,' + base
-                    if 'member' in NewPosixData.keys():
-                        if membertoremove in NewPosixData['member']:
-                            NewPosixData['member'].remove(membertoremove)
-                        else:
-                                    sys.stderr.write(raw_member + " isn't a 
member of the group, skipping.\n")
-                    else:
-                                    sys.stderr.write("This group contains no 
members.\n")
-
-            if PosixData == NewPosixData:
-                sys.stderr.write("No changes to make; exiting.\n")
-            else:
-                modlist = ldap.modlist.modifyModlist(PosixData, NewPosixData)
-                ds.modify_s(dn, modlist)
-    except ldap.UNWILLING_TO_PERFORM, msg:
-        sys.stderr.write("LDAP was unwilling to modify the group. Error was: 
%s\n" % msg[0]["info"])
-        ds.unbind()
-        sys.exit(1)
-    except ldap.NO_SUCH_OBJECT:
-        sys.stderr.write("The group you are trying to modify doesn't exist.\n")
-        ds.unbind()
-        sys.exit(1)
-    except ldap.TYPE_OR_VALUE_EXISTS:
-        sys.stderr.write("The gid given already exists.\n")
-        ds.unbind()
-        sys.exit(1)
-    except ldap.PROTOCOL_ERROR:
-        sys.stderr.write("There was an LDAP protocol error; see traceback.\n")
-        traceback.print_exc(file=sys.stderr)
-        ds.unbind()
-        sys.exit(1)
-    except Exception:
-        try:
-            sys.stderr.write("There was a general error, this is unexpected; 
see traceback.\n")
-            traceback.print_exc(file=sys.stderr)
-            ds.unbind()
-        except Exception:
-            sys.stderr.write("Also failed to unbind.\n")
-            traceback.print_exc(file=sys.stderr)
-        sys.exit(1)
-
-    ds.unbind()
-    sys.exit(0)
-
-if __name__ == "__main__":
-    main()
+    with ldap3.Connection([
+        ldap3.Server(s) for s in ldapconfig['servers']],
+        user=ldapconfig['user'],
+        auto_bind=True,
+        password=ldapconfig['password']
+    ) as conn:
+        if args.action == 'adduser':
+            print(add_member(conn, ldapconfig['basedn'], args.group, 
args.user))
+        elif args.action == 'removeuser':
+            print(remove_member(conn, ldapconfig['basedn'], args.group, 
args.user))
\ No newline at end of file

-- 
To view, visit https://gerrit.wikimedia.org/r/301058
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ibc9e5bf28826804e90b9ae143bcdd4cf0020b11d
Gerrit-PatchSet: 1
Gerrit-Project: operations/puppet
Gerrit-Branch: production
Gerrit-Owner: Yuvipanda <yuvipa...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to