Getting Started with Provisioning

I’m now at the point, in this series of posts for ILM-newbies, where I can start to look at provisioning code.

I introduced the Metaverse Extension in this post, but to recap briefly: as far as ILM is concerned there is only one metaverse extension dll, which is run, in its entirity, against all types of metaverse object. For a project with more than, let’s say, four MAs you will find it easier to keep track of your code if you go for the MVRouter approach where you can split your project down into a seperate dll for each MA (remebering that this split is notional only – ILM still runs all the code against all objects).

The simplest provisioning code

If you haven’t already done so, create your extension project as covered in this post.

You can get started right away by adding some code to the Sub Provision. All you need, in this subroutine, is some code bracketed with the StartNewConnector and CommitNewConnector statements:

Dim csentry As CSEntry
Dim MA As ConnectedMA
MA = mventry.ConnectedMAs(MA_Name)
csentry = MA.Connectors.StartNewConnector("objecttype")
<..set name and attribute values of the new object>
csentry.CommitNewConnector()

This will create an object of type objecttype in the MA called MA_Name.

Setting the object name in a flat directory

If you’re provisioning to something like a database table, or a text file, or other system where the objects have a simple name, then all you need, to name the object, is to set the appropriate attribute:

csentry = MA.Connectors.StartNewConnector("record")
csentry("id").Value = mventry("StaffID").Value
<..set other attribute values>
csentry.CommitNewConnector()

Setting the object name in a relative directory

Relative (ie LDAP style) directories are a little more complicated, because the object name is the Distinguished Name, constructed from it’s relationship with a parent container. We have a little more coding to do in that case:

Dim dn as ReferenceValue
Dim rdn as String
'..Construct the dn from the cn and the OU
rdn = "CN=" & mventry("cn").Value
MA = mventry.ConnectedMAs(MA_Name)
dn = MA.EscapeDNComponent(rdn).Concat(OU_Name)
'..Create the cs object
csentry = MA.Connectors.StartNewConnector("user")
csentry.DN = dn
<..set other attribute values>
csentry.CommitNewConnector()

Note that the OU_Name you use here must be the fully distinguished name, eg: “CN=Users,DC=fabrikam,DC=com”.

Setting attribute values

Attribute values can either be set on the new object in the MVExtension, or by using flow rules. It doesn’t much matter which way you do it, as long as the attributes reach the connector space object before it’s exported.

Often you will want to set a few key attributes while creating the object and, this being the case, you must do it between the StartNewConnector and CommitNewConnector statements.

So, to put that another way, once a CS object exists you cannot modify its attributes in the MVExtension. The only way you can modify attributes, from that point on, is using flow rules.

To set an attribute value just use

csentry("attributeName").Value = ...

Disabled AD Account

In Active Directory the account will be created disabled unless a password is set. The following snippet sets the unicodePwd to some constant value, and then specifes that the account should be enabled (though the userAccountControl setting will be overridden by AD if your password is not strong enough to satisfiy its security settings).

Const ADS_UF_NORMAL_ACCOUNT As Integer = &H200
csentry("UnicodePwd").Values.Add(INITIAL_PASSWORD)
csentry("userAccountControl").IntegerValue = ADS_UF_NORMAL_ACCOUNT

For a list of the other userAccountControl settings see Example: Enabling or Disabling a User Account in Active Directory in the Developer’s Reference.

Code Examples

See this post for a simple, flexible outline for a Provisioning sub.

And also check out the Developer’s Reference for these examples:

Simple AD provisioning code: Example: Setting an Initial Password in Active Directory

Simple LDAP provisioning code: Example: Setting an Initial Password in Sun and Netscape Directory Servers

That should be enough to get you started…

Posts on xml lookup files and debugging will be coming as I have time to write them.

2 Replies to “Getting Started with Provisioning”

  1. again…great post! 🙂

    at what events does the Sub Provision get invoked? when an object is projected in metaverse OR when an attribute flow rule updates a metaverse object attribute value OR when a metaverse object is deleted OR all of these events?

    If it gets invoked at more than one events, how can one differentiate between actually what caused it to invoke? for example, consider two data sources (CDS1 & CDS2 with MA1 & MA2) both containing users data having different attributes and whose data needs to be “aggregated” in metaverse and then exported into third data source (CDS3 – destination). MA1, being the master and most authoritative data source, is configured to “join”, “project” & its attributes to be “imported” into the metaverse attributes. MA2 is only configured to “join” and its attributes to be “imported” into the metaverse attributes. So, in this scenario, MA1 can cause both objects to be created as well as updated in the metaverse, while MA2 can only cause objects to be updated in metaverse.

    If there is only one Sub Provision being invoked at both events (creation, updation), how can one identify which MA’s activity (and exactly which activity – projection or attribute flow) invoked the Sub Provision, via source code?

  2. The Provisioning code is invoked by any change to a metaverse object, including add, delete and attribute updates. It also runs both before an after a delete operation, which can lead to some unexpected errors if you weren’t prepared for it.

    The provisioning code can’t differentiate between types of updates – about all you can do, if you really must, is test for the MA that the change came from using the LastContributingMA property of the mventry.

    Good provisioning code design doesn’t rely on any sequence of events. It should be able to take the entire data set, sync it all in any order, and arrive at the same result. This is the “steady-state” pricipal of MIIS, and is really a very powerful thing.

Comments are closed.