はじめに
前回と前々回はLDAPの追加と取得を行いました。今回は、削除やデータ移動、名前の変更など他の機能をまとめます。
名前の変更
コネクションのみ使用した名前の変更
cnのみ変更したい場合はConnectionのmodify_dn()
を使用して変更できます。変更前のdnと変更後のcnを指定することでcnのみ変更することができます。以下の例は前々回でまとめたのでConnectionの接続は端折っています。
# 更新前に表示する
obj_cn_name = ObjectDef('inetOrgPerson', conn)
data_reader = Reader(conn, obj_cn_name, 'ou=sample-unit,dc=sample-component,dc=sample-ldap')
print(data_reader.search())
print('=======================')
# modify_dnに移動対象のdnと変更後のcnを指定する
conn.modify_dn('cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap', 'cn=sample-rename')
# 更新後に表示する
data_reader2 = Reader(conn, obj_cn_name, 'ou=sample-unit,dc=sample-component,dc=sample-ldap')
print(data_reader2.search())
結果
[DN: cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-29T19:24:03.368406
cn: sample-name
objectClass: inetOrgPerson
sn: sample
]
=======================
[DN: cn=sample-rename,ou=sample-unit,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-29T19:24:03.448482
cn: sample-rename
objectClass: inetOrgPerson
sn: sample
]
変更前後のLDAPの値を見るとcnがsample-nameからsample-renameに変更されていることがわかります。また、中の値もそのまま移動されていることがわかります。
Writerを使用した名前の変更
Writerを使用した名前の変更はWriterのentry_rename()
を使用して変更できます。Connectionと異なり、Writer読み込み時に変更前のパスを指定してentry_rename()
には変更後の名前をフルパスで与えます。
# 更新前に表示する
obj_cn_name = ObjectDef('inetOrgPerson', conn)
data_reader = Reader(conn, obj_cn_name, 'ou=sample-unit,dc=sample-component,dc=sample-ldap')
print(data_reader.search())
print('=======================')
# 移動対象をWriterに読み込ませる
data_reader = Reader(conn, obj_cn_name, 'cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap')
data_reader.search()
data_writer = Writer.from_cursor(data_reader)
# 変更後のパスをフルで指定
data_writer[0].entry_rename('cn=sample-rename,ou=sample-unit,dc=sample-component,dc=sample-ldap')
# 変更結果の反映
data_writer.commit()
# 更新後に表示する
data_reader2 = Reader(conn, obj_cn_name, 'ou=sample-unit,dc=sample-component,dc=sample-ldap')
print(data_reader2.search())
結果
[DN: cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-29T19:40:09.898199
cn: sample-name
objectClass: inetOrgPerson
sn: sample
]
=======================
[DN: cn=sample-rename,ou=sample-unit,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-29T19:40:10.017186
cn: sample-rename
objectClass: inetOrgPerson
sn: sample
]
変更前後のLDAPの値を見るとConnectionの変更と同様に、cnがsample-nameからsample-renameに変更されて中の値もそのまま移動されていることがわかります。
エンティティの移動
コネクションのみ使用したエンティティの移動
エンティティを他のパスに移動させたい場合も上と同様Connectionのmodify_dn()
を使用して変更できます。移動対象のdnと変更後のcn、変更後のdnを指定することでエンティティを移動させることができます。以下の例は前々回でまとめたのでConnectionの接続は端折っています。
from ldap3 import Server, Connection, ObjectDef, Reader, Writer
server = Server('localhost')
conn = Connection(server, 'cn=admin,dc=sample-ldap', password='LdapPass')
conn.bind()
# 更新前に表示する
obj_cn_name = ObjectDef('inetOrgPerson', conn)
data_reader = Reader(conn, obj_cn_name, 'dc=sample-component,dc=sample-ldap')
print(data_reader.search())
print('=======================')
# 移動する
conn.modify_dn('cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap', 'cn=sample-name', new_superior='ou=sample-unit-move,dc=sample-component,dc=sample-ldap')
# 更新後に表示する
data_reader2 = Reader(conn, obj_cn_name, 'dc=sample-component,dc=sample-ldap')
print(data_reader2.search())
結果
[DN: cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-29T20:01:02.190680
cn: sample-name
objectClass: inetOrgPerson
sn: test
st: sample
, DN: cn=sample-name2,ou=sample-unit,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-29T20:01:02.194679
cn: sample-name2
objectClass: inetOrgPerson
sn: test
st: sample
]
=======================
[DN: cn=sample-name,ou=sample-unit-move,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-29T20:01:02.233686
cn: sample-name
objectClass: inetOrgPerson
sn: test
st: sample
, DN: cn=sample-name2,ou=sample-unit,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-29T20:01:02.236675
cn: sample-name2
objectClass: inetOrgPerson
sn: test
st: sample
]
cnがsample-nameのouがsample-unitからsample-unit-moveに移動していることが分かります。さらに先ほどと同様に中の属性も一緒に移動されています。
Writerを使用したエンティティの移動
Writerを使用したエンティティの移動はWriterのentry_move()
を使用して変更できます。entry_rename()
と同じ使い方で、Writer読み込み時に変更前のパスを指定してentry_move()
には変更後のパスをフルパスで与えます。ここでは、移動後のエンティティの名前はパスに入れてはいけないこと、存在しないパスには移動できないことに気をつけてください。
# 更新前に表示する
obj_cn_name = ObjectDef('inetOrgPerson', conn)
data_reader = Reader(conn, obj_cn_name, 'dc=sample-component,dc=sample-ldap')
print(data_reader.search())
print('=======================')
# 移動対象をWriterに読み込ませる
data_reader = Reader(conn, obj_cn_name, 'cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap')
data_reader.search()
data_writer = Writer.from_cursor(data_reader)
# 値を移動する
data_writer[0].entry_move('cn=sample-name,ou=sample-unit-move,dc=sample-component,dc=sample-ldap')
# 変更結果の反映
data_writer.commit()
# 更新後に表示する
data_reader2 = Reader(conn, obj_cn_name, 'dc=sample-component,dc=sample-ldap')
print(data_reader2.search())
結果
[DN: cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-29T20:08:33.946805
cn: sample-name
objectClass: inetOrgPerson
sn: test
st: sample
, DN: cn=sample-name2,ou=sample-unit,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-29T20:08:33.952774
cn: sample-name2
objectClass: inetOrgPerson
sn: test
st: sample
]
=======================
[DN: cn=sample-name,ou=sample-unit-move,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-29T20:08:34.045188
cn: sample-name
objectClass: inetOrgPerson
sn: test
st: sample
, DN: cn=sample-name2,ou=sample-unit,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-29T20:08:34.051225
cn: sample-name2
objectClass: inetOrgPerson
sn: test
st: sample
]
cnがsample-nameのouがsample-unitからsample-unit-moveに移動していることが分かります。さらに先ほどと同様に中の属性も一緒に移動されています。
削除
コネクションのみ使用した削除
エンティティを削除したい場合はConnectionのdelete()
を使用します。この関数にdnを指定すると削除できます。以下の例は前々回でまとめたのでConnectionの接続は端折っています。
# 削除前に表示する
conn.search('ou=sample-unit,dc=sample-component,dc=sample-ldap', '(objectclass=inetOrgPerson)')
print(conn.entries)
print('=======================')
# パスを指定して削除
ou_result = conn.delete('cn=sample-name2,ou=sample-unit,dc=sample-component,dc=sample-ldap')
print(ou_result)
# 削除後に表示する
conn.search('ou=sample-unit,dc=sample-component,dc=sample-ldap', '(objectclass=inetOrgPerson)')
print(conn.entries)
結果
[DN: cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-29T20:19:59.281937
, DN: cn=sample-name2,ou=sample-unit,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-29T20:19:59.281937
]
=======================
True
[DN: cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-29T20:19:59.322233
]
削除後にsample2のcnが消えていることがわかります。
取得と合わせることで全削除もできます。
conn.search('dc=sample-component,dc=sample-ldap', '(objectclass=inetOrgPerson)')
for entry in conn.entries:
del_result = conn.delete(entry.entry_dn)
print(del_result)
Writerを使用した削除
エンティティを削除したい場合はWriterのentry_delete()
を使用します。今までのWriterを使用した操作と同様にWriterを生成した後にエンティティのentry_delete()
を呼ぶだけです。以下の例は前々回でまとめたのでConnectionの接続は端折っています。
# 更新前に表示する
obj_cn_name = ObjectDef('inetOrgPerson', conn)
data_reader = Reader(conn, obj_cn_name, 'ou=sample-unit,dc=sample-component,dc=sample-ldap')
print(data_reader.search())
print('=======================')
# 移動対象をWriterに読み込ませる
data_reader = Reader(conn, obj_cn_name, 'cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap')
data_reader.search()
data_writer = Writer.from_cursor(data_reader)
# 値を削除する
data_writer[0].entry_delete()
data_writer.commit()
# 更新後に表示する
data_reader2 = Reader(conn, obj_cn_name, 'ou=sample-unit,dc=sample-component,dc=sample-ldap')
print(data_reader2.search())
結果
[DN: cn=sample-name,ou=sample-unit,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-29T20:30:26.155112
cn: sample-name
objectClass: inetOrgPerson
sn: test
st: sample
, DN: cn=sample-name2,ou=sample-unit,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-29T20:30:26.160111
cn: sample-name2
objectClass: inetOrgPerson
sn: test
st: sample
]
=======================
[DN: cn=sample-name2,ou=sample-unit,dc=sample-component,dc=sample-ldap - STATUS: Read - READ TIME: 2020-03-29T20:30:26.264725
cn: sample-name2
objectClass: inetOrgPerson
sn: test
st: sample
]
削除後の結果を見るとsample-nameのcnがなくなっていることがわかります。
これも検索条件を変えると全削除ができます
# 上位のパスをWriterに読み込ませる
data_reader = Reader(conn, obj_cn_name, 'dc=sample-component,dc=sample-ldap')
data_reader.search()
data_writer = Writer.from_cursor(data_reader)
# 値をすべて削除する
for data_entity in data_writer:
data_entity.entry_delete()
おわりに
LDAPを操作する上で必要な追加・検索・削除・変更をまとめることができました。さらにRDBには無い移動であったり名前の変更であったりとディレクトリ操作特有のものも出てきました。このように似たようにデータを保存する機能を持っていたとしてもRDBとLDAPは明確に違う点があるためうまく使い分けるとより便利になるのではないかと思いました。