cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Working with Velocity Template Language in ITSM Ticketing

Working with Velocity Template Language in ITSM Ticketing

Overview

With disconnected systems, a common practice for handling write operations is to leverage an information technology service management (ITSM) system to handle the manual fulfillment tasks which would otherwise be collected within IdentityNow itself. Essentially, an integration can be deployed to generate service tickets directly into systems such as ServiceNow, Jira Service Desk, Cherwell, etc.

The use of such an integration allows for a great degree of flexibility and customization within the ticket's message body itself. IdentityNow allows you to dynamically inject portions of the provisioning plan into the API payload which ultimately gets sent to the ITSM system. We leverage a subset of Velocity Template Language to accomplish this, and this guide details some of the special variables which can be used to customize tickets. Additionally, examples of complicated use cases are provided to assist you in crafting your own custom ticket descriptions. 

Keywords and Variables

The below keywords can be used to reference particular aspects of the provisioning plan object which is fed into the integration's Velocity evaluator. As with all Velocity variables, these keywords must start with a dollar ($) sign:

  • $plan – The overall provisioning plan generated; this is usually used as a top-level object reference for one of the below variables.
  • $plan.arguments – The list of attributes and values generated by the system during plan generation; within the identity request XML document, these will be the entries listed under the <Plan><Attributes> node.
  • $plan.requests – An array list of account requests generated by the system during plan generation; within the identity request XML document, these will be the <AccountRequest> entries listed under the <Plan> node; there will be one entry for each linked account for that user, which is typically just one for IdentityNow.
  • $plan.request(<i>).resource - The target application of the provisioning plan. This will normally be the name of the source within IdentityNow which the integration is serving.
  • $plan.request(<i>).operation - The provisioning plan operation (i.e., Create, Modify, Disable, Delete) for the specific source account. 
  • $plan.request(<i>).items – An array list of attributes and values provided as part of the account create/enable/modify/disable profile for that account; within the identity request XML document, these will be the <AttributeRequest> entries listed under the <Plan><AccountRequest> node.
  • $plan.request(<i>).items(<j>).name – This is the name of the attribute within the referenced attribute request (e.g., email, displayName, groups, etc.)
  • $plan.request(<i>).items(<j>).Operation – This is the action being taken on the attribute within the referenced attribute request (i.e., Add, Remove, Set)
  • $plan.request(<i>).items(<j>).value – This is the value which the attribute within the referenced attribute request should be set to during an Add or Set operation.
  • $plan.request.id – This is the nativeIdentity value of the user for which the account request has been initiated.
  • $plan.arguments.<name> – This will return the value of the plan argument identified by <name>

Leveraging Keywords within Velocity Template Language

Note the usage of (<i>) and (<j>) in the documentation above for both the request and items array lists. This is an indication that these objects can be multi-valued and thus any particular reference to them must have some knowledge of which item in the list is desired. However, SailPoint's implementation of the Velocity Engine only has a stateless reference to the provisioning plan -- it is passed through the evaluator only once without any sort of variable pre-calculation, so index notation such as `$items[1]` or `$request[0]` will not evaluate.

Therefore, the proper way to build the desired verbiage in your Velocity script is to construct it dynamically while iterating through the objects. Consider the following example:

#foreach($request in $plan.requests)
  $!{request.operation} account '${request.id}' on ${request.resource}
  #if($request.items)
    Additional Details:
    #foreach($item in $request.items)
      $!{item.Operation} attribute '${item.name}' with value: ${item.value}
    #end
  #end
#end

The Velocity Engine will run through the provisioning plan and output all of the text elements in order as it's iterating through the list of requests and items. The above code would result in something similar to:

Create account 'test.user' on System A
Additional Details:
Add attribute 'name' with value: Test User
Add attribute 'email' with value: test.user@test.com
Add attribute 'location' with value: Austin

Sometimes, it is necessary to get some detailed information about the provisioning event from the plan's attributes in order to know what type of text to render as output. For example, you maybe have a need to output one type of message if the account request is a Create, and another type of message if the account request is a Disable. Consider the following desired requirement:

If the target application is called Application A, generate the below message:

"This access has been approved in SailPoint. Please install the local client for <user's display name> (Employee ID = <user's employeeID>). Please forward this ticket to the Application A team."

Otherwise, generate the below message:

"This access has been approved in SailPoint. Please Create an account in <target application name> with the following attributes and entitlement/s for <user's display name> (Employee ID = <user's employee ID>):
displayName = Test User
email = test.user@test.com
location = Austin"

Here, the goal is to output one message body if the target application is "Application A," but output a different message body if it is any other application. The appropriate way to construct your Velocity Template Language code to achieve this result would be:

#foreach($request in $plan.requests)
  #set($appName = $request.resource)
#end
#if($appName == 'Application A')
  This access has been approved in SailPoint. Please install the local client for $!plan.arguments.displayName (Employee ID = $!plan.arguments.employeeID).\nPlease forward this ticket to the $appName team.
#{else}
  This access has been approved in SailPoint. Please $!plan.arguments.acctOperation an account in $appName with the following attributes and entitlement/s for $!plan.arguments.displayName (Employee ID = $!plan.arguments.employeeID):\n
  #foreach($request in $plan.requests)
    #if($request.items)
      #foreach($item in $request.items)
        $item.name = $item.value\n
      #end
    #end
  #end
#end

As you can see above, we are able to iterate through the plan as many times as needed, set temporary variables, and then use those temporary variables to drive the final text to generate.

Version history
Revision #:
5 of 5
Last update:
‎Oct 12, 2021 03:10 PM
Updated by:
 
Contributors