суббота, 21 марта 2015 г.

Keystone. Synchronize users from AD to OpenLDAP [python script]

With OpenStack i need to sync users from corporate Microsoft Active Directory to OpenLDAP managed by Keystone.

As input i have list of user DNs. Script syncs only particular user parameters, such as

  • objectclass
  • mail
  • cn
  • givenName
  • sn
  • uid
  • userPassword
  • carLicense

These parameters a minimum enough for Keystone.

Usage:
1) Make sure you have "python-ldap" installed
2) Prepare "users" file with list of DNs in source AD

CN=user1,OU=USERS,DC=EXAMPLE,DC=com
CN=user2,OU=OTHER,OU=USERS,DC=EXAMPLE,DC=com

3) Start script below
./sync_users.py --users_file users \
                --src_ldap_uri ldap://192.168.0.11:389 \
                --src_ldap_user 'DOMAIN\administrator' \
                --src_ldap_pass 'xxx' \
                --dst_ldap_uri 'ldap://10.0.0.11' \
                --dst_ldap_user 'cn=admin,dc=domain,dc=tld' \
                --dst_ldap_pass xxx \
                --dst_ldap_tree 'ou=Users,dc=domain,dc=tld'

#!/usr/bin/python
import ldap
import ldap.modlist as modlist
import argparse
 
 
parser = argparse.ArgumentParser()
parser.add_argument('--users_file', default='users')
parser.add_argument('--src_ldap_uri', required=True)
parser.add_argument('--src_ldap_user', required=True)
parser.add_argument('--src_ldap_pass', required=True)
parser.add_argument('--dst_ldap_uri', required=True)
parser.add_argument('--dst_ldap_user', required=True)
parser.add_argument('--dst_ldap_pass', required=True)
parser.add_argument('--dst_ldap_tree', required=True)
args = parser.parse_args()
 
 
USERS_FILE = args.users_file
SRC_LDAP_URI = args.src_ldap_uri
SRC_LDAP_USER = args.src_ldap_user
SRC_LDAP_PASS = args.src_ldap_pass
DST_LDAP_URI = args.dst_ldap_uri
DST_LDAP_USER = args.dst_ldap_user
DST_LDAP_PASS = args.dst_ldap_pass
DST_LDAP_USER_TREE = args.dst_ldap_tree
 
 
def prepare_attrs(src_attrs):
    attrs = {}
    attrs['objectclass'= ['top','inetOrgPerson','organizationalPerson','person']
    attrs['mail'= src_attrs["mail"]
    attrs['cn'=  src_attrs["cn"]
    attrs['givenName'= src_attrs["givenName"]
    attrs['sn'= src_attrs["sAMAccountName"]
    attrs['uid'= src_attrs["sAMAccountName"]
    attrs['userPassword'= '{SASL}%s' % src_attrs["mail"]
    attrs['carLicense'= 'TRUE'
    return attrs
 
src_ldap = ldap.initialize(SRC_LDAP_URI)
src_ldap.simple_bind_s(SRC_LDAP_USER, SRC_LDAP_PASS)
 
 
dst_ldap = ldap.initialize(DST_LDAP_URI)
dst_ldap.simple_bind_s(DST_LDAP_USER, DST_LDAP_PASS)
 
 
with open(USERS_FILE) as f:
    users_to_sync = f.read().splitlines()
 
 
for user_dn in users_to_sync:
    user_cn = user_dn.split(',')[0]
    user_tree = user_dn.split(','1)[1]
    user = src_ldap.search_s(user_tree, ldap.SCOPE_ONELEVEL, user_cn)
    if user:
        dn = "cn=%s,%s" % (user_cn, DST_LDAP_USER_TREE)
        ldif = modlist.addModlist(prepare_attrs(user[0][1]))
        try:
            dst_ldap.add_s(dn,ldif)
            print "Synced user %s" % user[0][0]
        except ldap.ALREADY_EXISTS:
            print "User %s already exists" % user[0][0]
 
 
src_ldap.unbind_s()
dst_ldap.unbind_s()

Комментариев нет:

Отправить комментарий