Automate Directory Sync in vRO 7.4

I took quite a break from blogging this past year – and now that it’s VMworld 2018 again, I figured I’d contribute some useful vRO content as it’s always my biggest gripe when I’m there!

One of the big gaps that has been in vRA 7.x has been that you cannot perform a synchronization of your identity sources in a programmatic way. Since the transition from PSC/SSO lookups to vIDM, this is a pretty big feature to miss when you want to automate management of your users and groups.

Thankfully, a new API is available in vRA 7.4+ that is exposed by both the REST API, as well as the CAFE plugin making it easy to embed in your workflows.

It’s staggering to me that VMware didn’t include a pretty basic workflow to go along with this, but that’s OK. Here’s one for you that you can extend however you want! Given it’s relative simplicity, this is probably a good candidate for a vRO Action.

NOTE: This API only works for vRA 7.4 or higher!

First, you’ll need a couple of inputs:
cafeHost (Type: vCACCAFE:VCACHost) – the tenant where the identity source exists.
identitySource (Type: string) – the name of the identity source. The actual domain is extracted in the code.

Once you have those, bind them to a new Scriptable Task and put in the following code:

// Use tenant to create a connection to the Identity Store service.
var service = cafeHost.createAuthenticationClient().getAuthenticationIdentityStoreClientService()
var store = service.getIdentityStore(cafeHost.tenant,identitySource)
var domain = store.domain

// What's the current status of the identity source?
var status = service.getIdentityStoreStatus(cafeHost.tenant,domain).getSyncStatus().getStatus().value()
if(status !== "RUNNING") {
  // The source is currently not performing a sync, so begin one!
  try {
    service.syncIdentityStore(cafeHost.tenant,domain)
    System.debug("Sync of "+domain+" has started.")
  } catch(e) {
    throw("Failed at sync start: "+e)
  }

  // Poll the sync operation to completion, whether it succeeds or fails.
  var retries = 36
  for(i=0; i<retries; i++) {
    try {
      var status = service.getIdentityStoreStatus(cafeHost.tenant,domain).getSyncStatus().getStatus().value()
      if(status == "RUNNING") {
        System.debug("\tSync of domain "+domain+" is currently in progress...checking again in 10 seconds.")
  System.sleep(10000)
  i++
      } else {
        System.debug("Sync status of "+domain+" is now: "+status)
  break
      }
    } catch(e) {
      throw("Unable to query status: "+e)
    }
  }
}

A useful aside to this code: in case you ever need to know what possible values exist for any .value() method in the CAFE plugin, you can just output the .values() to the log, and it will return a list.

For this particular operation, these are your options: COMPLETED, FAILED, RUNNING, UNDEFINED

I’ve not run into a Undefined situation before, but these values should help you in extending or mapping out your logic for the workflow. My retries logic is pretty simple and easily modified. Find out what works in your environment and adjust it accordingly!

As an Action, I think the best case would be to use the code above, and once completed return a boolean on whether the synchronization process successfully completed, and you can error handle from there.

I hope to be bringing more stuff forward for the rest of the year! Happy orchestrating!

 

Leave a Reply