There are quite a few differences in syntax and behavior compared to regular JS, so it can be expected that a lot of things that you think should work, will not work inside vRO.
- JS feature basically stop at ES5, but some features of ES5 aren’t even implemented.
- Not all of the API is available inside vRO, and some objects, methods or functions have been replaced with an equivalent (Console.log is equivalent to System.log in vRO)
- You can’t normally use external JS libraries such as axios, jQuery, lodash, etc.
If you want to use an external library inside VRO, there are a few things to consider, but these are the most important:
- The JS version that the library is/depends on.
- The APIs and JS features that the library depends on.
If not, then you can try a few things to try to get it to work inside vRO:
- Use a transpiler (and bundler if you need) (such as Babel+Webpack, SWC, Esbuild, to name just a few) to downgrade the source code of the library you want to use into an older version of JS into a single JS file.
- You might need to use polyfills if you use some browser or Node.js APIs because they will not work inside VRO even when transpiled and downgraded.
- Put the resulting JS code into the same vRO workflow/action that you want to use it in and use it directly (I don’t recommend this, as it can become a mess quite fast and is unreadable)
- Put the resulting JS code into a vRO resource element, then inside your vRO workflow/action , get the content of this resource element (it will be a string at this point) and use the
Functionconstructor to parse and evaluate the library code. It will then be available to use inside the rest of the workflow/action. (I recommend this method, since it is the least error prone, takes 1-3 lines of code only and is more readable)
- You could do the same thing, but additionally split the library code into as many smaller working modules/objects/functions as you want to have better performance and potentially work around vRO’s limitations when working with huge files.
This is what worked for me in general, but I can’t guarantee that it will work in all cases. Because of the bizarre nature of the Rhino engine and limitations of vRO, you could run into other problems or limitations and won’t be able to use the JS library that you want to use. For example, if your library code is too big, vRO will not be able to use it as it will run out of memory, or the workflow/action will crash, or it will just stop evaluating the library code midway and be useless.
There are 2 other ways to use external libraries inside vRO workflows/actions, but they don’t use the normal vRO engine. Just keep in mind that using this way, you cannot directly access all of the vRO APIs such as resource elements, plugins ,etc. So it has some limitations :
- Use the Node.js runtime of vRO instead of the default one (Rhino) to code your workflow/actions. You can use external and regular Node.js libraries such as lodash this way, without needing to transpile or bundle or downgrade it. (This is the best way to use external libraries, as they should work as you would expect normally in JS). There are 2 ways to do this and the documentation is quite useful in explaining in more details : https://docs.vmware.com/en/vRealize-Orchestrator/8.10/com.vmware.vrealize.orchestrator-using-client-guide.doc/GUID-13E3704E-A325-4CB1-AF57-45FEBDBBD159.html
- You can also setup an Node.js environment in vRO 8.8+ with all the required modules and dependencies. Follow this link for more info on how to create one: https://cloudblogger.co.in/2022/07/20/getting-started-vrealize-orchestrator-script-environments-cb10098
- You can code a microservice or something that uses all the JS libraries you would need and expose them as a REST API in some server hosted somewhere, then call these endpoints from your vRO workflow/action.(This requires the most effort and is not really recommended for simple scripting)
Credits to Olivier Fortier for this lucid explanation.