PythonでLDAP Persistent Search

Sat, Dec 19, 2015

OpenLDAP と仲間たち Advent Calendar 2015 19日目。

OpenLDAPにはsyncreplという同期機能がありますが、この仕組みを応用して(Persistent Search)持続検索を行うことができます。

Persistent SearchはLDAPサーバーに対する変更をリアルタイムに検知するので、これを応用するとLDAPのデータをRDBMSやNoSQL、クラウドストレージなどの異種DBと同期するエキセントリックな環境を構築できます。

今回はPython LDAPを使ってPersistent Searchをやってみます。

slapd.confに以下を設定

overlay syncprov

python-ldapとpyasn1をインストール

$ pip install python-ldap pyasn1

psearch.py:

#!/usr/bin/env python2
# -*- coding: utf-8 -*-

import sys
import ldap
import ldap.syncrepl
from ldap.syncrepl import SyncreplConsumer
from ldap.ldapobject import LDAPObject

URL='ldap://localhost:389/'
BASE_DN='dc=example,dc=com'
BIND_DN='cn=Manager,dc=example,dc=com'
BIND_PW='password'

class SyncreplPrint(LDAPObject,SyncreplConsumer):
    def __init__(self, *args, **kwargs):
        LDAPObject.__init__(self, *args, **kwargs)
        self.uuids = {}
    def syncrepl_entry(self, dn, attrs, uuid):
        if uuid in self.uuids:
            print "modify entry: ", dn
        else:
            self.uuids[uuid] = True
            print "add entry: ", dn

    def syncrepl_delete(self, uuids):
        for uuid in uuids:
            if uuid in self.uuids:
                del self.uuids[uuid]
                print "delete entry: ", uuid

def main():
    sync = SyncreplPrint(URL, trace_level=0)
    sync.simple_bind_s(BIND_DN, BIND_PW)
    msgid = sync.syncrepl_search(BASE_DN, ldap.SCOPE_SUBTREE, mode='refreshAndPersist')
    try:
        while sync.syncrepl_poll(all=1, msgid=msgid):
            pass
    except KeyboardInterrupt:
        pass

if __name__ == '__main__':
    main()

実行

$ python psearch.py

LDAPサーバーに対するADD,MODIFY,DELETEを検知できるようになりました。