In this chapter, we are aiming at improving your programming skills. We will look at the following recipes:
JavaScript is the scripting language that Orchestrator is based on. Learning JavaScript makes for a much-improved workflow build. JavaScript is especially useful in the creation of actions.
There are some nice little things that help you a bit if you know about them.
When you are in a scriptable task, start typing something such as Server
. or define a variable of type VC:VirtualMachine (vmObject
) and then type vmObject
. Then press Ctrl and the spacebar. You will see a window that shows you all the properties and methods that go along with this object.
You can now start typing the attribute or method you want and see the list shrinking.
The following is a very short and quick reference for JavaScript. It is aimed at people who already know a programming language and just need to adapt to the syntax of JavaScript.
To learn JavaScript, you can have a look at http://www.w3schools.com/js/ .
Here is a list that shows the very basic things one needs to know about JavaScript:
;
).//
./*
and end with */
.myTest5
) and must start with a letter.+
, -
, *
, and /
.+
operator, for example, "a" + "b"
or stringVariable + " text to append"
.var variable name = new variable_type
; for example, var myString = new String();
.Check Chapter 5, Visual Programming, for JavaScript on decisions, loops, and logs and Chapter 9, Essential Plugins, and Chapter 10, Built-in Plugins, for more examples.
This is a small collection of some tricks and tips that are quite handy to know.
A typical situation that you may come across is this: you have a parameter that contains a string and you would like to know if this string contains another string.
For example, you have a parameter, myVM
that contains the string testVM.mylab.local.
You want to know if this VM is in the mylab
domain, and if the myLab
string is part of it. You can use the indexOf()
method of the type string
. The index functions return the position of the first occurrence. If the string is not part of the other string, the return value will be -1. Here's an example:
Var myVM = "testVM.mylab.local"; If ( myVM.indexOf("myLab") > 0) { //is part of mylab } else { //is NOT part of mylab }
Another common problem is that a user might enter MyLab
, myLab
, or MYLAB
instead of the myLab
you are expecting and checking for. Here is a simple way to solve this one. You just make everything capital and then check. So instead of the following code:
var myEntry = "MyLab"; var myTest = "myLab": if ( myEntry == myTest ) { // both are the same }
use the .toUpperCase()
method of the type string
:
If ( myEntry.toUpperCase() == myTest.toUpperCase() ) { // both are the same }
The same method applies, for example, to the hostnames or VM names. VM names or hostnames are mostly held in lowercase. Use the .toLowerCase()
method to do this.
It can happen that users enter "myLab "
or " myLab"
by mistake (an extra space at the beginning or end) and you can imagine how this can play havoc with an if
clause. Use the .trim()
method to solve this:
var dirtyString = " Hello World! "; var cleanString = dirtyString.trim();
You can use regular expressions with strings, which goes a long way, for example, with HTML mails.
Create an HTML mail body, such as a table that contain some places that you later want to exchange. Such a table could look like this:
<table border=1> <tr> <td>VM Name</td><td>{VM}</td> </tr><tr> <td>vCPU</td><td>{CPU}</td> </tr></table >
You then can store this as an attribute (or even better, as a resource) and when you need it, you replace it with the following:
mailContent=mailContent.replace(new RegExp("{VM}","g"),vmName); mailContent=mailContent.replace(new RegExp("{CPU}","g"),vCPU);
The result is a nice e-mail that is easily formatted. Please not, that we have to escape the {
in the regex.
instanceof
is used to determine if a variable is of a given type. This example shows how to use it. Also see the example action, getAvailableCPUFromCluster
.
If we have a vSphere cluster with HA configuration, it can be either configured as n+1 or with %. The exact mode is stored as follows:
HApolicy = clusterObject.configuration.dasConfig.admissionControlPolicy
Using an if
statement, we can determine which it is:
if (HApolicy instanceof VcClusterFailoverResourcesAdmissionControlPolicy) if (HApolicy instanceof VcClusterFailoverLevelAdmissionControlPolicy)
Just a few words on working with the Date
type in JavaScript. Working with Date
is easy if you understand how it works. Basically, it counts the milliseconds since January 1, 1970 (in 1970, UNIX was released). If you want to read or set the time, it's best to use the methods that are encapsulated with the type.
Values |
Read |
Write | |
Day of the week |
0-6 |
|
|
Day of the month |
1-31 |
|
|
Number of month |
0-11 |
|
|
Year |
Four digit year: for example, 1970 |
|
|
Milliseconds since 01.01.1970 |
- |
|
|
Seconds |
0-59 |
|
|
Minutes |
0-59 |
|
|
Hours |
0-23 |
|
|
Have a look at the full list of attributes on w3Schools: http://www.w3schools.com/jsref/jsref_obj_date.asp
It is also important to know that if you set a workflow attribute of the Date
type, it is null (it doesn't contain the current time or the time you started the workflow); however, if you set a date as a workflow in-parameter, you will automatically see the current date and time when you try to define it.
To initialize a Date
attribute, you can bind it to an action to do it for you. Create an action with an out-parameter of the Date
type and the following script:
var current = new Date(); return current;
This action will set an existing attribute to the current time when the action is invoked. Also see the example workflow, 06.04.03 Working with date attributes
, and the example action, setNow
.
To display the date, there isn't a nice way implemented in Orchestrator, so you have to go the long way:
date.getDate()+"."+date.getMonth()+"."+date.getFullYear()
This is a typical problem in workflows. You have a wait task or a user interaction that requires a timeout as Date
type. You can define the new end date with the following:
var endDate = new Date(); endDate.setMinutes(endDate.getMinutes() + minutes);
This will create a new endDate
that is minutes
in the future. The same can be done with all the gets and sets from the previous table. To add days, use 24 hours.