#!/usr/bin/python

## purpose: creates new spacewalk accounts for users in a specific LDAP
##          group, removes spacewalk accounts after deleting users from a
##          specific LDAP group
## copyright: B1 Systems GmbH <info@b1-systems.de>, 2011.
## license: GPLv3+, http://www.gnu.org/licenses/gpl-3.0.html
## author: Christian Berendt <berendt@b1-systems.de>, 2011.

import logging
import xmlrpclib
import ldap
import yaml
import sys

logging.basicConfig(
    filename = "/var/log/sw-ldap-user-sync.log",
    filemode = "a",
    format = "%(asctime)s [%(levelname)-8s] %(message)s",
    level = logging.DEBUG
)

settings = yaml.load(open("/etc/rhn/sw-ldap-user-sync.conf"))

try:
    directory = ldap.initialize(settings["directory"]["url"])
    directory.simple_bind_s(settings["directory"]["user"],
                        settings["directory"]["password"])
except Exception, e:
    logging.error("unable to connect to LDAP server: %s" % e)
    sys.exit(1)

try:
    spacewalk = xmlrpclib.Server(settings["spacewalk"]["url"], verbose=0)
    spacewalk_token = spacewalk.auth.login(settings["spacewalk"]["user"],
        settings["spacewalk"]["password"])
except Exception, e:
    logging.error("unable to connect to spacewalk server: %s" % e)
    sys.exit(1)

filter = '(objectclass=groupOfNames)'
attrs = ['member']

try:
    result = spacewalk.user.list_users(spacewalk_token)
except Exception, e:
    logging.error("unable to fetch user accounts from spacewalk server: %s" % e)
    sys.exit(1)

users = {}
for user in result:
    detail = spacewalk.user.getDetails(spacewalk_token, user.get('login'))
    if user.get('use_pam'):
        users[user.get('login')] = 1

try:
    (dn, data) = directory.search_s(settings["directory"]["group"], ldap.SCOPE_SUBTREE, filter, attrs)[0]
except Exception, e:
    logging.error("unable to fetch user entries from LDAP group: %s" % e)
    sys.exit(1)

for uid in data['member']:
    filter = "(objectclass=posixAccount)"
    attrs = ['givenName', 'sn', 'mail', 'uid']

    try:
        (userdn, userdata) = directory.search_s(uid, ldap.SCOPE_SUBTREE, filter, attrs)[0]
        if users.has_key(userdata["uid"][0]):
            del users[userdata["uid"][0]]
        else:
            logging.info("creating new user account for ldap user %s" % userdata["uid"][0])

            try:
                spacewalk.user.create(spacewalk_token, userdata["uid"][0], "",
                  userdata["givenName"][0], userdata["sn"][0], userdata["mail"][0], 1)
            except Exception, e:
                logging.error("unable to create new user account %s on spacewalk server: %s" % (userdata["uid"], e))
    except Exception, e:
        logging.error("unable to fetch user details for user %s from LDAP server: %s" % (uid, e))


for user in users.keys():
    logging.info("deleting user %s" % user)

    try:
        spacewalk.user.delete(spacewalk_token, user)
    except Exception, e:
        logging.error("unable to remove user account %s from spacewalk: %s"
                % (user, e))

directory.unbind()
spacewalk.auth.logout(spacewalk_token)

