[ILM 2007] Creating a provisioning code (Already object exists でエラーになっちゃうよ)
こんにちは、ぴろとでございます。先日、Provision された Person Object (娘) が、Pending Export 状態であった旨、お伝えしておりました。この度、無事なんのエラーもなく、Export and Check 処理が完了しました。これからが、大変な毎日が待っていると重々覚悟をしているのですが、まずはほっと胸をなでおろす今日この頃です。
今回の記事は Provisioning をテーマに書いてみたいと思います。
とある一家が家族が増えたことを契機に、家庭にある Family ドメインの ID 管理を自動化したいと思いつき、ILM 2007 FP1 を用いて ID 同期を行うつもりのようです。はてさて、どうなることやら…。
パパ 「うちにも家族が増えたし、ID 管理を容易化したいと思うんだが…」
ママ 「え?そんなに家族がいないし、手作業でやればいいじゃん」
パパ 「子どもだって、今後もっと増えるかもしれないし、3 人以上いたら管理が必要なんだよ」
ママ 「どうせ、パパが管理しているわけだし好きにすればいいじゃない?」
… こんなすったもんだがあったかなかったかは、また別の話になりますが、以下のシステム要件で行うようです。
- システム要件
・CSV ファイルに管理されている家族人員の内容を元に、Family ドメインに Person を追加・変更を行う必要がある。
・Family ドメインは既存ドメインのため、すでに Father と Mother の Person オブジェクトが存在している。
・Daughter は、生まれたばかりなので CSV ファイルに追記したばかり。
Provisining ルールにて、以下のようなコードを書いてみました。
Public Sub Provision(ByVal mventry As MVEntry) Implements IMVSynchronization.Provision
Dim targetContainer As String
Dim cnAttribute As String
Dim maName As String
Dim objectType As String
Select Case mventry.ObjectType.ToString
Case "person"
cnAttribute = "CN"
maName = "AD-MA" 'MAの名前を定義
targetContainer = ADUsersContainer
objectType = "user"
ProvisionObjectToActiveDirectory(mventry, cnAttribute, maName, targetContainer, objectType)
End Select
End Sub
Private Sub ProvisionObjectToActiveDirectory(ByVal mventry As MVEntry, ByVal cnAttribute As String, ByVal maName As String, ByVal targetContainer As String, ByVal objectType As String)
Dim coNNectedMA As ConnectedMA
Dim cnForObject As String
Dim rdn As String
Dim dn As ReferenceValue
Dim numConnectors As Integer
Dim csentry As CSEntry
Dim myConnector As CSEntry
Dim successful As Boolean = False
'----------- プロビジョニングコード ------------
'CN属性値のチェック
If Not mventry(cnAttribute).IsPresent Then
Throw New UnexpectedDataException("CN属性がありません")
End If
'接続するMAのオブジェクトを取得
coNNectedMA = mventry.ConnectedMAs(maName)
'メタバースエントリのCN属性値の取得
cnForObject = mventry(cnAttribute).Value.ToString()
Try
rdn = "CN=" & cnForObject
' OUを含めた完全なDN属性値を生成
dn = coNNectedMA.EscapeDNComponent(rdn).Concat(targetContainer)
numConnectors = coNNectedMA.Connectors.Count
If 0 = numConnectors Then
'CSエントリを新規作成
csentry = coNNectedMA.Connectors.StartNewConnector(objectType)
csentry.DN = dn
csentry.CommitNewConnector()
ElseIf 1 = numConnectors Then
'移動先のDN値をセット
myConnector = coNNectedMA.Connectors.ByIndex(0)
myConnector.DN = dn
Else
Throw New UnexpectedDataException("コネクタが複数です")
End If
successful = True
Catch ex As ObjectAlreadyExistsException
Throw New UnexpectedDataException("オブジェクトは既にあります")
Finally
End Try
End Sub
そして、オペレーションは、次の流れで実施を行いました。
1. CSV-MA にて、Full Import (Stage Only)
2. AD-MA にて、Full Import (Stage Only)
3. CSV-MA にて、Full Synch ….
おや、3. CSV-MA にて Full Synch の処理にて、エラーが発生しました。イベントログをみると、”オブジェクトは既にあります” です。 エラーとなったオブジェクトは、Father と Mother で、いとしき愛娘は、正常に Provisioning されています。「おとーさん、うまく同期されなかったよ」 と寝ている娘にささやくのでした。気を取り直して、デバッグすることにしました。すると、ComittNewConnector にて、エラーになっていることがわかりました。そこで、パパは気がつきました。「あれ? provisioning では新しいコネクタスペースオブジェクトを作成する処理だよなぁ。けど、AD-MA にはすでに Father オブジェクトはあるはず…」 そうです、ここでは、ObjectAlreadyExistsException は無視し、Join ルールにて、処理させるべきです。それに伴い、MV ルールを変更することにしました。
- 変更点
・Throw New UnexpectedDataException をコメントアウト
・Run Profile の実行順序を以下のように変更
1. CSV-MA の Full Import (Stage Only)
2. AD-MA の Full Import (Stage Only)
3. CSV-MA の Full Synch (注) コメントアウトされたため、エラーにならない)
4. AD-MA の Full SYnch (注) AD-MA のコネクタスペースオブジェクトと MV オブジェクトが Join
------
ちなみに、2. の処理を実施せずに、1. –> 3. の順番で同期を行うと、同期オブジェクトの DN 名に指定される OU が未 Import 状態のため、MissingParentObject Exception が発生します。
このシステムを管理しているパパはきっと娘に、「おとーさんは、ここにいるよ」とささやくに違いありません。
~ ぴろと@娘の名前はやっぱり”ななみ” ~