Examples

2

Introducing: The LittleCMDB (a vCenter Orchestrator & WaveMaker Demo-Project)

It is a pleasure for me to write these lines as an introduction to a full series of articles, posted on vcoportal over the next couple of days:

Christian Strijbos (you remember his posts about WaveMaker and vs. LDAP a couple of weeks ago!?) put together a comprehensive project involving vCenter Orchestrator (and its SQL Plugin) and WaveMaker:

***…drumroll…***

The LittleCMDB

***…drumroll…***

Features

The LittleCMDB is a Workflow-driven Database Application which stores information of Virtual Machine configurations in a SQL database. The user can see the configuration via a web-based UI. It’s even possible to file a Request to change the configuration of a VM via the Web-Frontend, it will automatically processed and the settings of the VM will be adjusted.

In short, you can…:

  • Show the current Virtual Machine configuration in a Web-Frontend
  • Initialize the Database automatically
  • Refresh the Database when the configuration of a Virtual Machine changes
  • Let the users change the Virtual Machine configuration via a Web-Frontend

Architecture

LittleCMDB uses Orchestrator Workflows to implement the “business logic” of the application. For that it leverages the SQL-Plugin for vCO, so you don’t have to write a single line of SQL Statements.

There will be some backend Workflows which gather information from vCenter and store them into the Database.

The web-based frontend is built with VMware WaveMaker.

What you get:

We will publish a full guide how-to build the LittleCMDB from scratch, separated in different parts over the next couple of days (see the picture above also as a “Table of Content”).

We will also provide the Workflow Packages and the WaveMaker project to download.

Our main goal is to give you…

  • examples and “hands-on” guides to develop workflows in vCO
  • same for WaveMaker
  • an example how easy it is to create such a “CMDB application” using vCO Plugins
  • ideas to use vCO and WaveMaker for your own use-cases

So: Even if the downloadable workflows should  run quite out-of-the-box, do NOT use them for production!
The complete project is for educational purposes only.
(If you like the idea, and want something like that for your company, engage Christian for a project!  8-))

Now, get your vCO Lab ready and look forward to Part 1…

tomorrow in this Theater :mrgreen:!

Here we go:

Part 1:
http://www.vcoportal.de/2012/07/little-cmdb-part1/

Part 2:
http://www.vcoportal.de/2012/07/littlecmdb-an-orchestrator-and-wavemaker-project-part-2/

Part 3:
http://www.vcoportal.de/2012/07/little-cmdb-part3/

Part 4:
http://www.vcoportal.de/2012/07/little-cmdb-part4/

Part 5:
http://www.vcoportal.de/2012/07/littlecmdb-part-5/

Part 6:
http://www.vcoportal.de/2012/08/littlecmdb-an-orchestrator-and-wavemaker-project-part-6/

Part 7:
http://www.vcoportal.de/2012/08/littlecmdb-an-orchestrator-and-wavemaker-project-part-7/

0

Regular Expression-Objects in vCO Scripts

Recently there was a great discussion on the forums about how to match Workflow input parameters against a Regular Expression: http://communities.vmware.com/message/2064306 (make sure to read through the complete thread to get Christophe’s (www.vcoteam.info) examples!)

Create RegExp Objects

Regular Expressions are used in JavaScript as objects of type ‘RegExp’. You can create them explicitly via constructor new RegExp() or directly with /pattern/modifiers-syntax:

//using the constructor
//new RegExp(pattern, modifiers);
var ipPattern= new RegExp("^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})$");

//Or, to save a bit of typing, JavaScript provides a simpler syntax;
//var pattern = /pattern/modifiers;
var ipPattern= /^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})$/;

(you might remember that from the E4X-syntax for XML-handling: http://www.vcoportal.de/2011/03/xml-handling-the-e4x-way/)

Use RegExp Objects

var ipPattern= /^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})$/;
// as parameter for String-methods
var ip = "192.168.1.1";
var isValidIp = (ip.match(ipPattern) != null);
System.debug('Is the String ' + ip + ' a valid IP-address? ' + isValidIp);

ip = "192.168.1.678";
isValidIp = (ip.match(ipPattern) != null);
System.debug('Is the String ' + ip + ' a valid IP-address? ' + isValidIp);

//with the RegExp-object's own methods exec(), test()...
var validation = /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$/;
var creditCardNumber = "1234123412341234";
var isValidCreditCardNumber = validation.test(creditCardNumber); //returns a boolean
System.debug('isValidCreditCardNumber? :' + isValidCreditCardNumber);

(If you have a real world use case for the last example, let me know!  It’s on my todo-list next to an “How to integrate vCO with Paypal” article… :mrgreen:)

References

To feel the power of Regular Expressions (they even look very geeky  ;-)) visit:
http://www.w3schools.com/js/js_obj_regexp.asp
http://www.w3schools.com/jsref/jsref_obj_regexp.asp
http://www.regular-expressions.info/examples.html

To become a Wizard, read following books (and :-)### grow a beard):
http://www.amazon.com/exec/obidos/ASIN/0596520689
http://www.amazon.com/exec/obidos/ASIN/0596528124/

And, as final pro-tips for the use of String.search(regexp):

  • It returns a number with the position of the first match (there is a mistake in the vCO API Explorer!), and
  • -1 is not false in JavaScript!!!
4

Using Onyx to speed-up Workflow development

In the VMTN Community Forums for Orchestrator recently one question came up:

“…how to use orchestrator to change the Video Card Setting of a VM to “Auto-detect settings” the next time the VM reboots?” (read the full thread here: http://communities.vmware.com/message/2040860#2040860)

That is a typical task for a workflow developer: Automate something you can easily click in vSphere Client, but it maybe hard to figure out, how to automate it.

ONYX to the rescue!

See this video how to get to the solution in less than 15 minutes  :-D… (You can download the resulting workflow below, but that shouldn’t be necessary anymore 😛 !)

It’s a quick shot screencast, so no audio….

If you like the style, drop me a comment, and I will create more videos (with explanations  😎 ) in future!

Change VM Video Settings Workflow
Change VM Video Settings Workflow
Change-VM-settings-to-auto-detect-video-memory.workflow
2.1 KiB
Details...
4

The Philosopher’s Stone of vCO: Workflow Reflection

Don’t fear anything, it’s not necessary to live in a barrel to understand this topic! You just have to go a bit beyond the obvious…

In computer science, reflection is the process by which a computer program can observe (do type introspection) and modify its own structure and behavior at runtime.says Wikipedia.

The Orchestrator also provides a kind of reflection for workflows: Using the keyword “workflow” in a JavaScript Element a workflow can access its current runtime state. This article explains the basic understanding about Workflows and WorkflowToken, script examples and common use-cases for that.

The Basics

An important conecpt of vCO is to create a so called Workflow Token for every single time a workflow gets executed. Only so it’s possible to keep track of multiple in-parallel runs of the same workflow, what’s absolutely possible. (Currently supported in vCO 4.2: 150 concurrent running workflows).

In the vCO Smart Client you can see all the workflow token (=past executions) in the Workflow library, as leafs under the workflow itself:

If you are familiar with object-oriented programming, consider the Workflow as a class (description), the WorkflowToken is an actual instance of this class.

When you select a workflow token in the tree, you can see its details in the main window, most important:

  • the state (e.g. running, failed, completed, waiting)
  • the current vlaues of the workflow attributes
  • the log output (done via System.log() or System.debug())
  • (if there is one:) the error message at the bottom of the Variables-Tab

<Additional Technical Background>: All information about the state of a workflow token is stored in vCO’s database (the state, the attributes, the current element,…). So it’s possible for vCO to continue the workflow even after a crash of the server (Checkpointing).
For a quick & (really!) dirty ( & completly unsupported!) monitoring you could do SQL-cram against the vCO database like that:

ALTER trigger [dbo].[monitor] on [dbo].[VMO_WorkflowToken]
AFTER UPDATE
AS
SET NOCOUNT ON
IF EXISTS ( SELECT * FROM Inserted I WHERE I.globalState = 'failed')
BEGIN
/* ***DEMO ONLY:** */ Insert into dbo.fails VALUES ('adsf'); # send a mail, wake somebody up...
END

</Additional Technical Background>

How to…

Back to topic: You can also access the runtime information about the current workflow execution “from inside”, by using the keyword “workflow” (small-caps, remember: JavaScript is case-sensitive!) in a scriptable element.
This keyword returns an object of type WorkflowToken.  This object now represents the current instance of the workflow. This object provides some attributes, see the script below for examples…

Important: If you want to access the Workflow-object (the (class/description/definition), you have to use the rootWorkflow-Attribute of the WorkflowToken (eg. “var theWorkflow = workflow.rootWorkflow”; theWorkflow will be of type Workflow). (Yeah, that’s what I meant with “beyond the obvious”)

The following script examples shows all that stuff: First we get some information about the current instance (you got it, the WorkflowToken). Starting in line 10 we access the Workflow, the last part from line 23 uses the WorkflowToken again.

//get the current workflow token /"instance"
 var token = workflow;
 System.debug(token);

//get some details about the current workflow token/execution/instance
 System.debug("startDate: " + token.startDate);
 System.debug("businessState: " + token.businessState);

//get the Workflow-"Class" of the current token
 var rootWorkflow = workflow.rootWorkflow;
 System.debug(rootWorkflow);

// get "declaraction": Array of Input Parameters of the workflow in general
 var inParams = rootWorkflow.inParameters;
 System.debug("inParams: " + inParams);
 //loop through array and print out details for each parameter
 for (var i in inParams) {
 loopParam = inParams[i];
 //print out in type:::name:::description
 System.debug(loopParam.type + ":::"+ loopParam.name + ":::" + loopParam.description);
 }

// get the current token's inParameters (they include the values, and are returned as Properties
 //(key : values tuples)
 var curInParams = token.getInputParameters();
 System.debug("curInParams: " + curInParams);
 //crawl through the Properties
 var keys = curInParams.keys;
 for (var i in keys) {
 var curKey = keys[i];
 //print out properties in format key :::: value
 var curValue = curInParams.get(curKey)
 System.debug(curKey + " :::: " + curValue );
 }

All that happens just in the script, there are no workflow attributes bound to this scriptable element. The Workflow you can download below has one INPUT Parameter, just to see something in the logs :-). It’s not used anywhere.

The script produces output like this:

Use-Cases

Now, what to use all that stuff for?

  • Obviously, if you need some of the information, like the startDate, later in the workflow
  • If your workflow has an User Interaction element, you can send an URL to answer it via email (there is a complete example in Library / Mail)
  • It’s possible to change the User context the workflow runs, using the changeCredential()-Method
  • If you are working with the Business State field of workflow elements, you eventually want to read this in script.

Not really related to the “Reflection”, but useful anyway:
The same objects are used when you access past workflow tokens not of the current workflow, but of other workflows. This can be used for instance to create Healthcheck Workflows which monitor the vCO Server for failed or canceled workflow runs (a much cleaner & more reliable ( & supported) way to replace the SQL-cram mentioned above!).
Insider Tip
: See the Actions provided by the module “com.vmware.web.webview” for a lot of useful scripts! They have many more use-cases than only within webviews…

Now, finally:

Download the example!

It should just run out of the box…

Workflow Reflection example
Workflow Reflection example
WorkflowReflection.workflow
1.8 KiB
Details...
3

Quick one: Trace out object attributes in JavaScript

I just strumbled (once again) over some scripting objects in vCenter Orchestrator where the documentation in the API Explorer is, eeeh, just missing. So I had to figure out the attributes of the object manually. To do this, you can leverage the JavaScripts’s characteristic that objects are represented as enumerations of their attributes.

So it’s possible to loop through all the attributes even if you don’t know their identifier (yet). Following example in Javascript does exactly that, to trace out all attributes of a VM-Object (Type: VcVirtualMachine) and its Datastores. (you can download the full example below)

The script

//print out properties of a VM-object

//loop through all properties (leverage Javascript's
// "object is an associative array" characteristic)
for (var i in vm) { (//vm is an input parameter of Type VcVirtualMachine
	//we have to catch some 'not defined' errors if object has
	//an attribute of type "dynamic property")
	try {
	//print out in form "propertyname:::value"
		System.debug(i + ":::" + vm[i]);
	} catch (ex) {
		//just ignore error and continue with next iteration(=property)
		continue;
	}
}

//other example: For a datastore
System.debug("================================");
System.debug("====NOW FOR THE DATASTORE===");
System.debug("================================");
var vmsDatastores = vm.datastore;
System.debug("VM's Datastore(-object): " + vmsDatastores);
//vm.datastore return an ARRAY OF DATASTORES itself, so we have
//wrap it in another loop
for (var k in vmsDatastores) {
	var curDatastore = vmsDatastores[k];
	System.debug("******** NEXT DATASTORE: *****");
	System.debug("curDatastore: " + curDatastore);

//same loop as above for each datastore
//play it again, Sam!
for (var j in curDatastore) {
	try{
		System.debug(j + ":::" + curDatastore[j]);
	} catch (ex) {
		continue;
	}
}
//end same loop as above 🙂

} //end loop through Datastore-Array

The results

The output looks like this:

To interpret the results, an example line of the output:

[2012-03-06 09:45:23.844] [D] resourcePool:::DynamicWrapper (Instance) : \\
    [VcResourcePool]-[class com.vmware.vmo.plugin.vi4.model.VimResourcePool] \\
    -- VALUE : ResourcePool<resgroup-98>

The first part resourcePool is the name of the attribute.
After the ::: separator you get the object type [VcResourcePool] of this attribute, the providing class in the vCenter-Plugin of vCO,
and finally after the separator you get the value of the attribute, in this case it’s with ResourcePool<resgroup-98> a Moref (Managed Object Reference) to the resource pool the VM is located in.

Now you can use the .-Operator in JavaScript to access the attributes, as in line 21 in the script where we do the cram again for all Datastores the VM is related to.

Only caveat: Just from the System.debug()-Output it’s NOT possible to see if an attribute is just a single object or an Array!
(read carefully the example again: vm.datastore (line 21) returns and Array of VcDatastores, but you cannot see this just from the output of line 22)

Conclusion:

Always have the vSphere API Reference open in background when working with vCenter objects in vCO!

Download the example:

Workflow: Trace Out Object Properties
Workflow: Trace Out Object Properties
trace out object properties.workflow
2.3 KiB
Details...
Page 7 of 9« First...56789