はじめに
前回はLDAPの追加と取得を行いました。今回は、WriterとReaderを使用した追加と取得の方法をまとめます。
環境
- python:3.6.5
- ldap3:2.7
- イメージ:osixia/openldap
LDAP操作
Readerを使用したLDAPの読み込み
ldap3には色々な機能を持ったReaderクラスがあります。それを使用してLDAPの情報を取得します。Readerにはコネクションとオブジェクトとcn(検索パス)が必要になります。例は基本的に上から順に続きものとして記載しています。
オブジェクトの生成
オブジェクトはObjectDefクラスに対象のオブジェクト名とコネクションを渡して生成します。今回は、cnの値を取りたいためinetOrgPerson
を指定します。ouを取得したいときはorganizationalUnit
など取得したい対象を指定します。
from ldap3 import Server, Connection, ObjectDef, Reader
server = Server('localhost')
conn = Connection(server, 'cn=admin,dc=sample-ldap', password='LdapPass')
result = conn.bind()
# inetOrgPersonのオブジェクト生成
obj_cn_name = ObjectDef('inetOrgPerson', conn)
Readerの生成
先ほど生成したオブジェクトとコネクション、検索パスを与えてReaderを生成します。この時に与える検索パスにより、どの階層から情報を取得できるかを指定できます。ここではReaderの生成だけで検索していないので値は入っていません。
# リーダーの生成
data_reader = Reader(conn, obj_cn_name, 'ou=sample-unit,dc=sample-component,dc=sample-ldap')
LDAPの値の取得
LDAPの値の配下をリストで取得
リーダーのsearch()
を使用することでLDAP値のリストを取得することができます。
# ここで検索をする
data = data_reader.search()
# 全アイテムが取れる
print(data)
結果
[DN: cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-27T20:50:15.470086
cn: sample-name
objectClass: inetOrgPerson
sn: sample1
sample2
st: test2
, DN: cn=sample-name1,ou=sample-unit,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-27T20:50:15.478084
cn: sample-name1
objectClass: inetOrgPerson
sn: sample
]
結果を見るとReaderに指定したou=sample-unit,dc=sample-component,dc=sample-ldap
以下のcnが全て取得できていることがわかります。さらにそれぞれの属性値であるsnとstが取得できています。
属性による検索データの取得
search()
に属性の文字列を入れて属性値のあるデータを取得します。例ではstを与えており、LDAPの情報は先ほどと同じなのでcn: sample-nameが取れるはずです。
# 検索条件を指定する
data = data_reader.search('st')
print(data)
結果
DN: cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-27T20:50:15.470086
cn: sample-name
objectClass: inetOrgPerson
sn: sample1
sample2
st: test2
結果を見ると予想した通りsample-nameのcnが取れました。
json形式で取得する
リーダーのentry_to_json()
を使用することでLDAPの値をjson形式の文字列に変換して取得できる機能があります。
# json形式で取得できる
json_str = data[0].entry_to_json()
print(json_str)
print(type(json_str))
結果
{
"attributes": {
"st": [
"test2"
]
},
"dn": "cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap"
}
<class 'str'>
Dict形式で取得する
リーダーのentry_attributes_as_dict
を使用することでLDAPの値をDict形式に変換して取得できる機能があります。
ldap_dict = data[0].entry_attributes_as_dict
print(ldap_dict)
print(type(ldap_dict))
結果
{'st': ['test2']}
<class 'dict'>
cnをパスにしてcnを1つ取得する
cnを指定することでその1つのcnのみ情報を取得することができます。
# cnをパスにすれば一個だけとれる
data_reader = Reader(conn, obj_cn_name, 'cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap')
data = data_reader.search()
print(data)
結果
[DN: cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-27T21:16:17.284094
cn: sample-name
objectClass: inetOrgPerson
sn: sample1
sample2
st: test2
]
Writerを使用したLDAPの書き込み
ldap3には色々な機能を持ったWriterクラスを使用してLDAPの情報を書き込むことができます。WriterにはReaderを利用して生成することができます。
Writerの生成・書き込み
Writerのfrom_cursor()
にLDAPの値を取得したReaderを与えてWriterを生成します。
生成したWriterの変数に値を入れてcommit()
することで値を書き込みます。
from ldap3 import Server, Connection, ObjectDef, Reader, Writer
server = Server('localhost')
conn = Connection(server, 'cn=admin,dc=sample-ldap', password='LdapPass')
result = conn.bind()
# readerを使った取得
obj_cn_name = ObjectDef('inetOrgPerson', conn)
data_reader = Reader(conn, obj_cn_name, 'cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap')
data = data_reader.search()
# 更新前に表示する
print(data[0])
# writerに読み込ませる
data_writer = Writer.from_cursor(data_reader)
# writer経由で値を入れる
data_writer[0].sn = 'sample10'
data_writer[0].sn += 'sample20'
data_writer[0].st = 'test10'
# 変更結果の反映
data_writer.commit()
# 更新後に表示する
data_reader2 = Reader(conn, obj_cn_name, 'cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap')
data2 = data_reader2.search()
print(data2[0])
結果
DN: cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-27T21:36:03.493031
cn: sample-name
objectClass: inetOrgPerson
sn: sample1
sample2
st: test1
DN: cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-27T21:36:03.686030
cn: sample-name
objectClass: inetOrgPerson
sn: sample10
sample20
st: test10
指定したように値が変わっていることがわかります。
おわりに
LDAPのReaderとWriterを使用したLDAPの取得・変更・追加についてまとめました。ReaderとWriterを使用することでLDAPの扱い方が少し容易になった気がします。そのおかげでRDBの代わりにLDAPを使用するということが現実的になってきました。今回は極力簡単にするために構成を考えずにべたでソースを書いていきましたがもう少し工夫することでさらにソースが便利になるのではないかと思っています。