VMware VSA Deepdive – Part 6 – Eventing So Hard Right Now

I sure have done a lot of blogging about how to power off a VM lately, don’t you think?

One more time, but this time it’s the best version of them all.

I’m Eventing SO HARD right now

I figured this out while investigating something related to VSA and connecting the dots. Here’s how it went down.

In my setup, we have the VSA Clustering Service running on a separate VM at the remote location to handle quorum. One problem that pops up about once a month is the ongoing struggle of Windows patching. The VMs patch, and reboot as you would expect. This throws an alarm on the vCenter Datacenter object that the cluster service is offline. The other issue is that it doesn’t clear itself once the box comes back up. I wanted to find a way to clear this automatically, so that my monitoring guys didn’t lose their minds when hundreds of these appeared at 2AM.

If you look at the settings for the Alarm in question, you’ll see that it uses Events rather than Conditions for these alerts. I hadn’t dug too hard into how these worked before, so time to get dirty.

The default VSA Cluster Service Alarm.
The default VSA Cluster Service Alarm.

I realized then that the alarms in question were bubbling up from VSA Manager to vCenter using AMQP, and based on prior experience I knew that WSCLI would show events when I used startListener – so I started to do some more testing.

Running wscli [cluster IP] startListener from the command-line, I verified it was listening, and then rebooted the VSA cluster service machine in my lab. And then something neat happened – the listener showed an event called MemberOfflineEvent fire. I then waited for the node to come back online and sure enough, I saw MemberOnlineEvent fire.

After adding the trigger of MemberOnlineEvent to the alarm, and having it set the status back to normal I performed another test. Sure enough, the alarm came up, and a couple of minutes later, it disappeared when the service came back online. Problem solved!

It begs the question – why wasn’t this built in to the standard alarm? I wish I knew. But at the very least, I can correct this one.

I started thinking about this newfound trick and wondered – could it apply elsewhere with the VSA solution? I know that custom alarms are created for each NFS datastore used by the VSA, and custom alarms for the VSA machines too. What could we do with those?

The default VSA VM offline alarm settings.
The default VSA VM offline alarm settings.

This may look familiar! You can make similar changes to this alarm and it will clear things up automatically there too. So what about datastores?

The default VSA Datastore Alarm.
The default VSA Datastore Offline Alarm.

OK, the event is a little different, but otherwise pretty straightforward. We just need to find the corresponding event that indicates all is well again.

Below is the list of alarms created by the VSA Manager during an installation, by object context and name.
Datacenter – VSA Cluster Service Offline
Datacenter – VSA Storage Cluster Offline
Virtual Machine – VSA Member Offline
Datastore – VSA Storage Entity Offline
Datastore – VSA Storage Entity Degraded

All of these only have alarms for triggering, but none are set up by default to clear themselves. After using WSCLI and lots of testing, here are the settings I feel make the most sense to give the best idea of what is actually happening. This list only shows what would be added to the existing alarm to automatically clear it out.

Alarm: VSA Cluster Service Offline, VSA Member Offline
Event: MemberOnlineEvent
Status: Green

This clears up most of the alarms very easily. The datastore alarms are a little more interesting – you can actually have both the Offline and Degraded alarms fired during an outage, which isn’t necessarily helpful. The below changes will ensure only one is showing at a time.

Alarm: VSA Storage Entity Offline
Event: StorageEntityDegradedEvent
Status: Green

Alarm: VSA Storage Entity Degraded
Event: StorageEntityOnlineEvent
Status: Green

With the above changes, the datastore will go from green, to yellow, to red, and back up the list in the proper order.

Eureka Moment

This is fun and all, but this entry is actually about how to Power Off a VSA VM isn’t it?
Once I had figured out the connection between the events sent to vCenter from VSA Manager, I remembered something from my many adventures in WSCLI regarding the shutdownSvaServer command:

This operation sends an SvaEnterMaintenanceModeEvent management event
when the node is marked for entering maintenance mode, and a
SvaShutdownEvent when the VSA service is ready to shut down.

I hope this is helping you catch on to where this is going.
Let’s do an experiment in our VSA Cluster – create a custom alarm on one of the VSA VMs like so:

Creating a custom Maintenance Mode Alarm.
Creating a custom Maintenance Mode Alarm.
Setting custom Maintenance Mode Alarm event values.
Setting custom Maintenance Mode Alarm event values.
Setting custom Maintenance Mode Alarm action values.
Setting custom Maintenance Mode Alarm action values.

This alarm object will Power Off the VSA VM automatically when the shutdownSvaServer argument is sent through WSCLI. It’s truly a beautiful thing!

The alarm works!
The alarm works!

And for those wanting to see what it looks like in the standard client:

05-alarm-maintenance-shutdown-client

There it is! It seems really simple in hindsight, but then again we did start out just trying to power off a VM.
NOTE: Disable HA before shutting the VSA down. If you don’t, your VSA will get restarted automatically. Obviously, once you are done patching and all of that, re-enable it!

This process is pretty easy to update for a single datacenter manually.

Next time, we’ll make a workflow that will go through every datacenter object and update all of the alarms.

Thanks for reading! The VSA onion continues to peel…

VMware VSA Deepdive – Part 5 – Use SOAP!

Fake Edit: It has been a while! It’s been lots of great weather, people visits, and then VMworld happened. Time to get back on track!

In the last post about the VSA, we leveraged the SSH plugin in VCO to send the necessary command to the host that would force the VM to power off, as we can’t do it from vCenter. There are pros and cons to that approach, though.

First of all, not particularly great from a security perspective – you have to have SSH open and the service started to make that happen. Depending on your environment, this may not be seen as a good thing.

You’re also using the root credentials to accomplish the feat. You could use another one, but that’s a whole lot of work just to set that whole thing up in preparation for this scenario. You’d have to take into account rolling the root password and how you could work that into the workflow and managing it over time.

And finally, related to the above–this process isn’t going to pop up in a log very easily since you’re bypassing the API *AND* vCenter.

So, given these faults I needed to find another way to proceed. To be fair this process also required root to the host so it wasn’t that much better, but it would at least show up in host logging. The answer?

SOAP. The yardstick of all APIs.
SOAP. The yardstick of all APIs.

Yep. I was desperate. But if it helps me to automate working with 1500+ hosts, it’s WORTH IT.

I want you to hit me as hard as you can

I haven’t had to make SOAP requests to anything in ages, so I was pretty rusty. Thankfully VCO to the rescue again with a built-in SOAP plugin.
First things first. Make a new Workflow and define two input Parameters – one for the ESXi host, and the VSA VM you wish to power down.

Inputs for the SOAP workflow.
Inputs for the SOAP workflow.

For your attributes, define the following as type String:

  • inputHostWSDLUri – this is to specify the WSDL URI used to talk to the ESXi host.
  • inputHostPreferredEndpoint – this is for talking to the API endpoint.
  • inputHostName – this is just to hold a string value of the ESXi host for later.

The rest of the attributes in the workflow can simply be bound as you add the other workflows that come with VCO.

Preparing the SOAP Host entry

One thing to keep in mind – when adding an ESXi host as a SOAP Host, it sets some values automatically that do not allow this to complete as expected. The first problem is the SOAP Endpoint and the SOAP WSDL URI. Both of these, when enumerated by the SOAP plugin point to https://localhost which makes sense for when the ESX host is doing calls to itself, but not for VCO to reach out to it remotely. The first order of business is to fix these values.

Create a Scriptable Task element in your schema, and bind the input Parameter inputHost to it. Bind the 3 attributes you defined above for output. Then, input the code found below.

Setting up the WSDL and Endpoint URI.
Setting up the WSDL and Endpoint URI.

This code is pretty straightforward. It is simply replacing the values with the correct ones to perform remote SOAP calls.

Next up, drop a copy of the Add a SOAP Host workflow into your schema. Bind the inputHostName and inputHostWSDLUri values to the name and wsdlUri parameters, and bind the rest to new attributes/values as you desire.

Binding new attributes to the Add a SOAP Host Workflow.
Binding new attributes to the Add a SOAP Host Workflow.

You’ll need to provide things such as the username/password to the host, timeout values and other values, all of which can be static values, or linked to a Configuration Element.

For the OUT parameter of this workflow element, bind it to a new attribute named soapHost so we can use it later.

Modify the SOAP Host

Before you proceed, you need to update the new SOAP Host with the new value of inputHostPreferredEndpoint.
Drop a copy of the Update a SOAP Host with an endpoint URL workflow into the schema.
Simply bind the attributes soapHost and inputHostPreferredEndpoint to their respective input parameters, and bind soapHost to the output parameter, so that it completes.

Using SOAP to find the VSA and shut it down

Add a Scriptable Task to your schema. On the inputs, bind the soapHost, inputVM, username, and password attributes.

Below is the code you can copy/paste, with comments as needed.

// get the initial operation you want to go for from the SOAP host specified.
var operation = soapHost.getOperation("RetrieveServiceContent");
// Once you have the SOAP Operation, create the request object for it
var request = operation.createSOAPRequest();

// set Parameters and their attributes.
request.setInParameter("_this", "ServiceInstance"); // creating the input Parameter itself
request.addInParameterAttribute("_this", "type", "ServiceInstance");

// make the request, save as response variable
var response = operation.invoke(request);

// retrieved values to be passed on down the line
var searchIndex = response.getOutParameter("returnval.searchIndex")
var rootFolder = response.getOutParameter("returnval.rootFolder")
var sessionMgr = response.getOutParameter("returnval.sessionManager")

// get Login Session to add to future headers.
var hostLoginOp = soapHost.getOperation("Login")
// create Login request
var loginReq = hostLoginOp.createSOAPRequest()
loginReq.setInParameter("_this", sessionMgr) // using value from initial query
loginReq.addInParameterAttribute("_this", "type", "SessionManager")
loginReq.setInParameter("userName", inputUser)
loginReq.setInParameter("password", inputPassword)
var loginResp = hostLoginOp.invoke(loginReq)
var sessionKey = loginResp.getOutParameter("returnval.key")

// find the VSA VM on the host.
var vmoperation = soapHost.getOperation("FindChild")
System.log("VM Search Operation is: "+vmoperation.name)
var vmreq = vmoperation.createSOAPRequest()
// define parameters
vmreq.setInParameter("_this", "ha-searchindex") // get the SearchIndex
vmreq.addInParameterAttribute("_this", "type", "SearchIndex")
vmreq.setInParameter("entity", "ha-folder-vm") // representing the root VM Folder
vmreq.setInParameter("name", inputVM.name) // your search criteria

// send request, get the response in a variable
var vmresp = vmoperation.invoke(vmreq)
// assign moref to variable
var vmMoRef = vmresp.getOutParameter("returnval")
// this log shows the output value
System.log("MoREF of VM ["+inputVM.name+"] on ["+soapHost.name+"]: "+vmMoRef )

// now that you have the MoRef of the VSA VM, you can kick off the Power Off task with a decision/parameter.
var pwroffOp = soapHost.getOperation("PowerOffVM_Task") // get the Power Off operation
var pwroffOpReq = pwroffOp.createSOAPRequest() // create the Power Off request
// define parameters
pwroffOpReq.setInParameter("_this", vmMoRef) // assign the MoRef of the VM to power off
pwroffOpReq.addInParameterAttribute("_this", "type", "VirtualMachine")
// shut off the VM by executing the request.
var offresp = pwroffOp.invoke(pwroffOpReq)

And there you have it. If you direct connect to the ESXi host when you run this workflow, you will see a task for powering off the VM appear and you are good to go.

One thing I prefer to do at the end of this workflow is to drop in the Remove a SOAP Host workflow and bind appropriately so that my host list doesn’t get too large, but this is obviously optional.

A final note on SSL Certificates

If you run this as it is out of the gate, you will probably get a pop-up regarding whether to trust the SSL certificate of the host.
Of course in a perfect world, all of your certificates are trusted top to bottom and are maintained. But anyone who has tried to do this at scale has struggled and probably doesn’t bother. In order to bypass this, you’ll need to make a few adjustments and duplicate the stock workflows so you can make changes to them.

In the VCO workflow list, go down to Library -> SOAP -> Configuration and right-click Manage SSL Certificates.
Choose Duplicate Workflow.
Duplicate SSL Workflow
Save your copy of the workflow wherever you like. You may want to change the name a bit to reflect that it isn’t the standard workflow.

Now, you can edit the workflow and make a minor adjustment. Here is the workflow by default.

The default Manage SSL Certificates workflow schema.
The default Manage SSL Certificates workflow schema.

You’ll notice the Accept SSL certificate schema element. Simply click it and delete it from the schema.

The "custom" Manage SSL Certificates workflow schema.
The “custom” Manage SSL Certificates workflow schema.

Finally, click on the General tab of your workflow, and look for an attribute named installCertificates. Inside of the value, input the text Install. The workflow element Install certificate does a simple check to see if the attribute is requesting to install, and continues from there.

Updating the new Manage SSL Certificates attributes.
Updating the new Manage SSL Certificates attributes.

As a final step, you will want to duplicate the Add a SOAP Host workflow, and replace the Manage SSL Certificates element with this new one you have created.
Ensure that the two attributes are rebound to the values the old one were using.

Re-adding the workflow bindings for SSL Certificates.
Re-adding the workflow bindings for SSL Certificates.

With these changes, you can Add a SOAP Host and not get stopped for SSL verification.

Of course, this isn’t really a best practice, but it gets the job done.

Next up, the final and maybe the most elegant solution for working with the VSA VM Power Off situation.

VMware VSA Deepdive – Part 4 – Shutting Down VSA (SSH Edition)

The first way I elected to try and forcibly shut down the VSA VM was to do everything through the ESXi command line via SSH. ESXCLI itself is not implemented in VCO directly, so this will require some good old fashioned text parsing with AWK.

Enabling SSH on the host through a VCO Action

Unfortunately out of the box, there is no workflow/action that manages ESXi services, so I needed to roll my own.
Below is the Action setup and script code I used to check for the SSH service and start it up, given an input of type VC:HostSystem.
Create the Action, and name it startSSHService. There is no return value necessary on this Action.
Setting up the SSH Service Action

// get the list of services
var hostServices = inputHost.configManager.serviceSystem.serviceInfo.service
var sshService = null
// loop the services, find the SSH service.
for each(svc in hostServices) {
  if(svc.key == "TSM-SSH") {
    sshService = svc
    System.log("Found SSH Service on host ["+inputHost.name+"]")
    break
  }
}
if(sshService == null) {
  throw "Couldn't find SSH service on ["+inputHost.name+"]!"
}

// Enable the service
try {
  inputHost.configManager.serviceSystem.startService(sshService.key)
} catch(err) {
  System.log("ERROR--Couldn't start SSH service. Error Text: "+err)
}
// the end

So, once you have SSH started on your ESXi host, you can send commands through VCO to do what you need.

SSH Service Check Action

For a more robust workflow, you will probably want an Action that will check to see if the service is running, and return a boolean value. That way you can build in a little bit more into the flow.
The setup for the ‘check’ Action is the same, with the exception of the return value being a boolean.

Setting up the Check SSH Action.
Setting up the Check SSH Action.

The code is similar as well, just doing a simple check at the end.

var hostservices = inputHost.config.service.service
var sshSvc = null
for each(svc in hostservices) {
  // System.log("Service: "+svc.label+", Status is: "+svc.running)
  if(svc.label == "SSH") {
    sshSvc = svc
    break
  }
}

// check status, return true/false
if(sshSvc.running == true) {
  return true
} else {
  return false
}

Where’s my Burrit–VSA?

Before you power off the VSA VM you’ll want to make sure to vMotion your other guests to another node, or have a foolproof way of finding the VSA appliance on your host. Another Action to the rescue! Given an input ESXi host, this Action will query the VMs running on the host and check its tags out to see if it matches a specific value found on all VSA appliances. Note that these Tags are actually in the vCenter database, and not the Inventory Service Tags in the vSphere Web Client.

For purposes of this post, I’ll name the action getVSAonHost.

Setting up the VSA finder Action.
Setting up the VSA finder Action.
// for when you absolutely, positively need to make sure it's a VSA.
var vsaKey = "SYSTEM/COM.VMWARE.VIM.SVA"
// check the VMs on the host for the tag through a loop
for each(vm in inputHost.vm) {
  if(vm.tag) {
    for each(tag in vm.tag) {
      if(tag.key == vsaKey) {
        return vm
        break
      }
    }
  }
}

So now, you know you have the VM in question. You can then pass the VirtualMachine’s name property to your SSH command later.

Making a SSHandwich

With the ESXi host and the VSA VM in hand, you can execute the built in Run SSH Command workflow to do the final step.

Here’s the SSH command to send, which will find the VSA VM ID and power it off in one line, no questions asked:

VMID=$(vim-cmd vmsvc/getallvms | grep -i <VSA Name> | awk '{ print $1 }') && vim-cmd vmsvc/power.off $VMID

Begin by creating a new workflow, and create a single input parameter named inputHost, of type VC:HostSystem.
Then create three attributes in the General tab, naming them sshCommandhostSystemName and vmVSAName, all of type string.
Finally, create another attribute called vsaAppliance of type VC:VirtualMachine for use with the Action.

Next, drop your getVSAonHost Action into the schema, and bind the actionResult to vsaAppliance as seen below.

Binding Actions to the getVSAonHost Action.
Binding Actions to the getVSAonHost Action.

Next, drop a Scriptable Task into the Schema and bind inputHost and vsaAppliance on the IN tab. On the OUT tab, bind the attributes of hostSystemName and vmVSAName. We are effectively going to write a small blurb of code that hands off the name properties of the input objects to the output attributes for use later, along with creating the SSH command string.

Binding values to the Scriptable Task.
Binding values to the Scriptable Task.

In the Scripting Tab, we’ll use a few simple lines of code to perform the handoff of values.

// assign values to output attributes
hostSystemName = inputHost.name
vmVSAName = vsaAppliance.name
// create SSH command string using the input values
sshCommand = "VMID=$(vim-cmd vmsvc/getallvms | grep -i "+vmVSAName+" | awk \'{ print $1 }\') && vim-cmd vmsvc/power.off $VMID"

Finally, drop a copy of the Run SSH Command workflow into the schema. There are a lot of inputs here, so you will have to do some more complicated bindings. You can either force them to be input each time the workflow is run, set a static value, or bind to existing attributes.

Here’s what it looks like by default.

Setup for the SSH Workflow.
Setup for the SSH Workflow.

How you approach this part is largely up to you, but here is how I did it for this example.

The updated SSH Workflow Setup.
The updated SSH Workflow Setup.

You’ll notice for the username/password I set a static value for root and set passwordAuthentication to Yes, and changed the initial hostNameOrIP and cmd values to the attributes we created earlier. For the outputs, I created new local attributes to show the results.

Run the workflow and you should see that VSA go down!

As an aside, if HA is enabled in your VSA HA Cluster object, it will immediately attempt to restart the machine – so make sure you add in the capability to disable HA into your parent workflows first so that this doesn’t end up being a problem.

Sweet Reprieve

It’s a bit crazy the amount of effort it takes to work around a disabled method, but it does work. I don’t think it’s particularly great, and if you’re the only one who cares about the systems and don’t have audits, this may be enough.

But for my purposes this was just the first step of the journey. I did not end up actually using this way to do things, but figured it may be a good exercise to document the process.

The next post will take it in a different direction altogether, and a little bit closer to an API based solution that can also be audited.

VSA Deepdive Part 3 - Enter the Orchestrator!

VMware VSA Deepdive – Part 3 – Enter the Orchestrator

Previously we setup your VSA Home lab, and beefed up our knowledge of WSCLI.
There may have also been some general complaints  about the limitations of the VSA solution from a management perspective.

Now, it’s time to bring things together with an unlikely savior.

(Just kidding, it’s VCO to the rescue as always.)

What do you mean?

VCO being the general swiss-army knife tool it is, you probably already know it has virtually unlimited possibilities.
So how can VCO and VSA coming together make magic happen? There’s no native plugin!

Factoid 1: WSCLI is a Java JAR, and is portable code that can run directly from JRE.
Factoid 2: VCO runs Tomcat for its server software, which is executed using JRE.

For me, reading this excellent post on the VCOTeam blog was like a Eureka! moment. Surely if I can find where JRE is installed on the VCO Appliance, I can execute WSCLI commands in a programmatic way, right?

I feel like the answer is Yes?

Nailed it.  Here’s what you need to set this up.

Orchestrator Appliance Setup

First, you need to allow VCO the ability to create local processes (ie. execute local code).

To do this, SSH into the VCO Appliance as root.
Then, using VI as your text editor, type this in the SSH prompt:
vi /etc/vco/app-server/vmo/conf/vmo.properties

Once in the file, press I to enter Insert Mode, so you can add/edit content to the file.
Add this line anywhere in the file:
com.vmware.js.allow-local-process=true

Once added, press ESC, then type :wq to save changes and exit.

NOTE: Once you have made this change, a reboot of the appliance is needed.

Next up, Since SSH is enabled by default on the VCO Appliance, that means SCP is also enabled.
Using your favorite SCP Client, login to your appliance and upload WSCLI.jar to a folder of your choosing.
For purposes of this post we will put it in the folder /var/run/vco.

Now that you have the files there, the next thing to do is find the path to the JRE.
Thankfully, it’s extremely easy to find – simply type which java at the SSH prompt.

Finding the JRE on the VCO Appliance.
Finding the JRE on the VCO Appliance.

Next, you need to edit your js-io-rights.conf to allow VCO to read and execute content from both folders.

To edit the file, start by typing vi /etc/vco/app-server/js-io-rights.conf
Pressto change to Insert Mode.  You can now edit the file appropriately.
Here is what my js-io-rights.conf file looks like, in case you want to do a comparison.

04-js-io-conf-perms

My changes are specifically these to grant read/execute access:
+rwx /var/run/vco
+rx /usr/java/jre-vmware/bin

Once you have these lines in your file, press ESC to leave Insert Mode. Then type :wq and press Enter to write your changes and quit VI.

So, now you have the path to your JRE, and your WSCLI, and your permissions to the necessary folders. Let’s conduct a quick test!

Run this from the SSH prompt: /usr/java/jre-vmware/bin/java -jar /var/run/vco/WSCLI.jar

WSCLI running in VCO!
WSCLI running in VCO!

BOOM!

Create your Configuration Elements for WSCLI

Configuration Elements are your friend for using this tool. Since the path of JRE and your WSCLI upload shouldn’t really change, why not make it a global variable? That’s what a Configuration Element is essentially for.

In the VCO Client, change to Design View if you aren’t already there. Then, go to the Configuration Elements Tab.

The VCO Configurations Tab.
The VCO Configurations Tab.

Create a new Folder (or not), and create a new Element, as I have done in the above screenshot.
Once you have created it, you will go straight into the menu to customize the element.
Our goal here is to define two attributes: the path to JRE, and the path to WSCLI.jar.
Simply create two attributes, and populate them with the paths you have found earlier.
These paths are CASE-sensitive!

The WSCLI Configuration Element.
The WSCLI Configuration Element.

Save and Close your changes.

Using the Configuration Element in a Workflow

This one is almost TOO easy, and you’ll immediately see the value of Configuration Elements.

Create a new Workflow, and add two Attributes to it.  Once you have done so, you’ll see a small icon similar to Configuration Elements.

07-empty-attributes

Click the small arrow highlighted above for the pathWSCLI attribute, and you will get a dialog window to find your Configuration Element.

Available ConfigurationElements are listed in this window.
Available ConfigurationElements are listed in this window.

You’ll find your previously created ConfigurationElement, and you can bind the attribute in your workflow to it, and use it however you want in the Workflow!

Running WSCLI in a Workflow

The VCO Command Class.
The VCO Command Class.

The final step is using the Command class in VCO. This class is meant to perform the local execution of code and return the output. So if you run a command like ls -l you’ll get a list of files in a directory. But obviously it’s better when you can run WSCLI in a workflow.

In the Schema of the workflow, drop a Scriptable Task in, and bind the attributes you created to it.
To execute WSCLI commands from the appliance you will be using the Command Scripting Class, which is detailed below.

Not much there, but that’s OK! If you’re this far, I suspect you’re thinking of use cases for this, of which there are many!

Follow the below code snippet as an example.  Note that the pathJRE and pathWSCLI bits are the attributes you defined earlier.

// define command line to execute
var cmdString = pathJRE+" -jar "+pathWSCLI+" help shutdownSvaServer"
// create a new command object with your command string
var myCommand = new Command(cmdString)
// execute the command
myCommand.execute(true)
// show the output
System.log(myCommand.output)

At this point, you should see the results of WSCLI in the Logging tab.

WSCLI - now in VCO!
WSCLI – now in VCO!

You can now execute WSCLI in your workflows, but that is just part of the ongoing puzzle. As we know already, WSCLI can’t actually power down the VSA node. How do we tackle that when we’re denied that ability in vCenter?

In the next few posts, I’ll detail the various ways I was able to accomplish this, each with their pros and cons. In the meantime, I’ll leave you to create a few Actions or Workflows to add WSCLI functionality!

VSA Deepdive Part 2 - WSCLI

VMware VSA Deepdive – Part 2 – WSCLI

Previously in the series, we got the homelab version of VMware VSA up and running.

You may not know it yet, but it’s pretty important to become BEST FRIENDS with the WSCLI tool set–the only way to interact with the VSA systems from the command line and see what is actually happening behind the scenes. The VSA Manager gives you a heads up mostly–the rest is with this toolset.

There are occasional mutters about WSCLI on the internet if you search. I’d like this to be the definitive guide to it from a practical perspective.

WHAT IT DOES

WSCLI is a Java .jar file that comes installed with the VSA Manager plugin. You’ll find it in the install directory under subfolder \TOOLS. It comes with a simple .BAT file that finds the JRE’s current location and calls it along with the -jar parameter. A bonus that I have found–this being Java, the tool is essentially cross-platform so you can copy the JAR to other systems and run them from wherever. This is critical to know about later on, in my opinion.

WSCLI gives you the ability to do what is available in the VSA Manager vSphere plugin except the ability to upgrade from 5.1 to 5.5.
WSCLI output is far more verbose and can actually be useful in ways that are not obvious. When VSA Manager fails to do what you want it to (and it will), there is almost always a KB article with a how-to guide on fixing it with WSCLI.  Examples such as replacing a failed cluster node, or getting specific replication data or status are all must haves for a VSA Administrator.

SEND HELP

The first command argument for WSCLI you need to know is help. While it sounds obvious as to why, but this provides a wealth of information that becomes really interesting later. Keep the items emphasized below in the back of your mind for later to see how.
Let’s look at the shutdownSvaServer help info for an example of the help documentation.

Command usage:
shutdownSvaServer [<boolean:maintenance-mode=false>]
Parameters:
maintenance - whether the node should enter maintenance mode on restart, defaults to false
Prepares the node for a shutdown.
This command does not actually perform a shutdown of this node's VSA service or of its virtual machine. Instead, any test coverage data being collected is saved, all open files are synced, whether the node should enter maintenance mode on restart is persisted, and the ZooKeeper configuration is updated if the node will be entering maintenance mode, but the actual shutdown is not performed. The caller should arrange to power off the node on receiving the SvaShutdownEvent. Calls to this method are not counted when determining whether this node should be placed in maintenance mode because it appears to be in a continuous cycle of reboots.
This operation sends an SvaEnterMaintenanceModeEvent management event when the node is marked for entering maintenance mode, and a SvaShutdownEvent when theVSA service is ready to shut down.

Pretty verbose and unusally direct on the process, if you ask me! But notice how misleading it is – it just stops processes.  You have to power off the thing yourself.
Not a problem right?  Why wouldn’t I be able to power off a VM?

Wait, what? Y U NO POWER OFF?!!1
Wait, what? Y U NO POWER OFF?!!1

In the vCenter database, once the VSA VM is created, it is modified extensively and disables most methods entirely. So even good old Administrator@vsphere.local can’t do anything about this. This is the biggest obstacle to automation and management of the system, since it has to be powered off before you can put the host into Maintenance Mode.

And before you ask – VUM’s option to power off the VSA VM doesn’t fly here either!

There are a number of ways to tackle this which will be discussed later.

YOU MIGHT WANT TO JUST LISTEN

The second command argument for WSCLI you need to know is startListener. This launches a daemon that will show events happening in real-time, such as a cluster takeover, replication progress updated every minute or so, and entering/exiting maintenance mode. VSA Manager, assuming it shows anything useful, only updates every 30-40 seconds in the vSphere Client.

So, to build on the shutdownSvaServer command above, you could open a second command window, run wscli <cluster IP> startListener to see what’s happening within the cluster in real time. Then run the command wscli <vsa node IP> shutdownSvaServer and see the SvaShutdownEvent fire in the first window within a second or two. You can reboot the node and watch the carnage in your listener! You’ll see everything from the failover, to the reconnection, the sync, and completion.

THE COMMAND STRUCTURE

The commands are divided into 3 categories: SVA (Storage Virtual Appliance), SAS (Shared Access Storage), and VCS (VSA Cluster Service).

SVA commands are specific to the individual storage node and not the cluster in general.  Pings, version checks, and entering/exiting maintenance mode are the main uses in this context.

SAS commands are specific to the cluster, and is the most commonly used set.  Getting all of the UUID values, parameters, and querying synch state are the main uses in this context.

VCS commands are specific to the standalone cluster service.  In a two-node cluster, the quorum is handled by this service, and is installed on the vCenter Server when VSA Manager is installed. You can download the cluster service for Windows or even as a Linux package, and put it on a separate machine entirely if you want.  It is fairly rare to use any commands in here except to query status and maybe restart the service if the replicas aren’t coming up in a failover scenario.

WHAT IT ISN’T

The HELP documentation of the WSCLI package is pretty good, even if you have to do a good bit of copy/pasting from the command window to get anything useful.

But the verbosity of it, such as showing absolutely everything as UUIDs is infuriating sometimes.  Expect to be filtering all data based on the management IPs.  This isn’t PowerCLI grade goodness, unfortunately.

(MORE) GENERAL GRIPES

No real monitoring capability. In my experience, there are no real proactive warnings that something bad has happened, other than a few stock alarms in vCenter that happen and then don’t clear themselves out when the condition changes. It’s the boy who cried wolf, and you tend to ignore most of the issues as time goes on. But when things break, they break real good. And then you have to hope you don’t screw up typing in specific commands to save the day in WSCLI.

Protip to VMware – let the admins decide who can/can not Power Off their VSA VMs. It’s what roles were designed for!
(As an aside, I secretly love to give my TAM grief about this product.)

Because this is a software RAID over ethernet solution, one thing to keep in mind is that the health of the underlying hardware is far more critical. Any major problem I have had with the product has been with bad hardware, primarily the disks themselves, or the controller and stripes. Make sure that you have that under control and address right away, or you’ll pay for it.

Upgrades require complete cluster outages. This is the really unacceptable one from my perspective – but I suppose the product was geared more to SMB shops that close at some point and can take the downtime. I’m in one of the biggest shops out there, and it simply doesn’t work that way.

But in quandaries like this, you have to get creative and dig deep. So that’s what I did.

In the next few posts, less theory and complaints – more workflows and scripts, surprising finds and interesting workarounds to manage VSA at hundreds of sites.

 

VSA Deep Dive - The Lab

VMware VSA DeepDive – Part 1 – Building the lab

My deep dive into how the VMware VSA works was really brought on by necessity.

On the surface, it sounded like a great solution – and to be fair it does work quite well overall. It acts as a RAID-1 of local storage over Ethernet which is a life saver for cost-conscious companies or the SMB space. And it is really designed as a fire and forget solution – if you don’t plan on patching your hosts or really making any changes to things ever.

Up front, your investment seems like a good choice – in some cases it may have been the only one. (I’ll let you figure out where I sit on this.)
But as a virtualization admin or engineer, you will have to update it, patch it, and do maintenance at some point. For one location, it’s easy.

For hundreds of locations, it gets a lot more interesting.

The Lab Requirements

In short, you need a minimum of 2 ESXi hosts running 5.1 or higher, a Windows vCenter 5.1+ installation, and some local disks. For my home lab setup, I’m just building nested ESXi with a single thin provisioned 100gb disk per host – that’s enough to get you going for building this out.

Keep in mind, I’m setting these nested instances up in VMware Workstation!

You will need 4 vmnics on each host – 2 bridged or on the same network as vCenter, and 2 host-only for the VSA replication portgroups. The vmnics must be in this order by default:

  • vmnic0 – Bridged
  • vmnic1 – Host-Only
  • vmnic2 – Bridged
  • vmnic3 – Host-Only

If you are asking “why?” at this point, don’t worry – it will all make sense. I’m a professional.

Once you have vCenter running in Windows, you will need to install the VSA Manager plugin. It is Windows-only, and must be installed on vCenter itself, hence the earlier requirement.
The only gotcha is to make sure that the account you are logged in as on vCenter has admin privileges to both the box, and vCenter inventory.
Other than that, it’s pretty much a next-next-next type of deal.

Add your 2 ESXi hosts to a new datacenter object, and you are almost ready to get started.

Team Make It Fit

By default, the VSA will do a check on the host hardware to see if your RAID controller is on the HCL. For obvious reasons using Nested ESXi isn’t going to work exactly as planned.

The solution is simple – just disable the auditing of the host during installation entirely!
On the vCenter Server, go into the VSA Manager config folder and find the ‘dev.properties’ file, typically it’s found here:

  • C:\Program Files\VMware\Infrastructure\tomcat\webapps\VSAManager\WEB-INF\classes\dev.properties

In this text file you’ll see a number of tweaks you can perform to suit your lab. The value we care about though, is this:

# Other operations
host.audit=true
vm.rollback=true
vm.config=true
test.on=false

Simply change the value for host.audit to false, save the file and restart the vCenter Management Webservices service on the server. Then restart your vSphere Client. When you run the wizard next time, you should only get a warning, and not a fatal error about how totally unsupported you are. It’s a shame we can’t say the same back to it, at least until September, 2018.

Click the datacenter object and you should see a tab called VSA Manager. All operations are done from this menu – it doesn’t exist in any other context. You’ll get a certificate warning, even if you have a signed internal certificate installed for vCenter – so just accept it. This is only the first crack in the armor!

The installation should be pretty straightforward. You’ll need to specify a cluster IP, and a cluster SERVICE IP since you’re running 2 nodes.
When you installed VSA Manager, the clustering service was installed on vCenter, so just point the SERVICE IP to your vCenter server.

  • On a remote / ROBO deployment, you can run the clustering service on another VM – there is an available clustering service installer in the VMware portal for Linux or Windows.

The cluster IP itself can be whatever you want as long as its on the same network as vCenter, or the Cluster Service in the remote location.

In about 15 minutes, you should hopefully have a functional VSA installation ready to rumble for your lab to tinker with and destroy!

A completed VSA Lab setup.
A completed VSA Lab setup.

And destroy it, we shall.

Introducing: My SDDC 2015

First things first. When you’re in this line of work, and especially for engineer or higher levels, you have to have a lab. It’s pretty easy to get one going, especially if you have a garage where you can put your baremetal boxes, with your own Catalyst switches, and all that fun stuff.

Living in a 500 square foot Seattle condo poses some interesting challenges when it comes to a lab. I have a spouse, 3 cats, and like many people, a gaming habit. Given my space constraints, I had to go small and practical.

So, here’s what I roll–what I call SDDC 2015. I used this for preparing for my VCAP5-DCA exam and it worked just fine.


The Case

The case.
The case.

I don’t think I could be much happier with a case than this one, the Lian-Li PC-V359WX. For $170 at the time of purchase, it seemed steep, but I wouldn’t change anything. It’s hard to find now, but I can’t find really anything to fault on it. It’s a two-story box, with Plexiglass on top letting you peek inside to see your motherboard and all the goods. You can even go SLI/CrossFire if you have adequate power, but I haven’t needed that.  Yet.

This case fit the dimensions of my current TV stand perfectly (although, a bit tight!) and the reviews were glowing. I have been a fan of Lian Li cases for a while now, but never bothered to really look at them because of cost. This time, it was spare no expense!


The Build

Intel Xeon E3-1230v3
Intel Xeon E3-1230v3

The brains of the outfit – an Intel Xeon E1230v3.

I wanted a real CPU to handle this lab – again, I had to pack as much punch as I could in one chassis without blowing my budget. This CPU is fantastic from a price/performance perspective. 8 Cores, VT-d, all the bells and whistles, and it runs quiet and cool.

 

 

The ASRock Z97M.
The ASRock Z97M.

The motherboard as also important in terms of feature set. I didn’t want a piece of junk Realtek NIC running my VMs, much less on my network. But, I’ve got a size constraint and that narrowed the list down to just a few candidates, and I decided to go with the ASRock Z97M. This one is great – it has HCL-supported Intel NICs, so for nested virtualization purposes, less drama with building custom ISOs. Add in 32GB of DDR3-1600 memory from Crucial, and that’s plenty of room to run things!

 


The Drives

SSD – Crucial MX100 512GB, another coming soon!
HDD – 2x Hitachi 2TB 64MB Cache – RAID1

The drives are really the biggest item on the list in terms of quality of life. SSDs make a lab so much more bearable to work with it’s crazy – don’t skimp here is my recommendation. You just thin provision on the SSD for speed and you’re set. The Hitachi HDDs are just there because I had them from my old build, and the other 5 went into my home brew NAS, which performs quite a bit of extra duty.


The Software

When I call this “SDDC 2015” it’s really more of a joke – this lab runs Windows 7 Professional running Workstation 9, which I got for free after passing my VCP5. Some edits to Virtual Networks later, and I now have nested ESXi 5.1, 5.5, and soon 6.0 hosts. Some additional nested VSAN instances, VCO, along with the usual AD and DNS servers.

And when I’m done, my wife knows how to startup Netflix and Plex. This is more important than you realize!


The NAS

Such compact, wow
Such compact, wow

It’s really not a lab until you have something that can serve up blocks!

Once again, I went with Lian Li’s cases in Mini-ITX. This guy is the Lian-Li PC-Q25B and it is amazing. The motherboard is an ASUS H87, with an Intel G3220 CPU. The setup is really overkill for what it does, but I have put it to work as a media server, and my wife makes sure it’s always working!

The OS is FreeNAS 9.1.2 to a USB stick, and I have 5 Hitachi 2TB 64MB disks in there as a RAID-Z2 (essentially RAID-6). So far, it works pretty well and reliably.


 

I’m not sure I will refresh this lab any time soon, so it’s got to last. Maybe if I get a garage I can get myself a used ASA and a stack of 3750X switches.

But, until then – I’ll fire up Crypt of the NecroDancer. I love this lab!

 

Learning vCO – Beginner Actions, World 1-2

Previously, I went over a very simple example of creating a VCO Action from top to bottom. Combining two input strings into one is quite the thrill ride, but let’s see if we can’t do some expanding and exploration of what we can do with Actions.

Suffice to say, Actions can be as simple or as complicated as you require. In this post, we’ll build a more complicated Action for a more specific use case. There’s a little JavaScript in here, but don’t worry – it will be well commented and should be easy to understand.

The Case

A pretty common issue as environments get larger is managing to keep VMware Tools up to speed. A simple Action you could create would dig into a VM and tell you whether it is current or not – and you could integrate that into a larger workflow that could mount up the VMware Tools and initiate an upgrade during a maintenance window.

The Action

From the Actions tab in VCO, go to your module and right-click, choosing to Add Actions.
Let’s name it something obvious…

02-action-name

There are a number of ways to approach the creation of this Action, but let’s say that our input parameter inputVM will be the VM itself (that is, type VC:VirtualMachine) and the return type will be a boolean, indicating whether the VMware Tools are up to date or not.

03-action-parameters

With the ins and outs defined, it’s time to write out the code. If you’re inexperienced with JavaScript or the vSphere API in general, prepare to meet your new best friend, the API Explorer. It is accessible within any scripting window, or from the main client menu under the Tools option.

Accessing API Explorer from the main client interface.
Accessing API Explorer from the main client interface.

The Explorer contains a comprehensive look at every object type – its properties and methods, a hyperlink to the types that they both expect for execution, and what they will return when called or accessed. You can drill down deeply into each object type and see what you can extract from it, and also find out what you need to build custom objects to pass to vSphere / vCenter’s API.

To Search the API Explorer, click the magnifying glass above the API Explorer.

API Explorer inside of an Action or Workflow.
API Explorer inside of an Action or Workflow.

Since you want to find out what you can get from a VC:VirtualMachine object type, search for that. When you double-click it, the parent window finds the object you clicked. It’s a little clunky, but you’ll get used to it. You can click the little arrow to the side to expand the VcVirtualMachine type and see what it has to offer.

API Explorer - Searching for type VirtualMachine.
API Explorer – Searching for type VirtualMachine.

As you can see, lots of potential goodies for you to automate or key off of.
In this case, we’re just trying to find the VMware Tools status, so go down the VcVirtualMachine property list until you find the guest property.

The Guest Information property of VcVirtualMachine.
The Guest Information property of VcVirtualMachine.

Notice at the bottom, it shows the return type of the property of inputVM.guest is VcGuestInfo. If you click that, it will take you to that type definition, and you’ll be able to see what other properties are available. Inside the VcGuestInfo list, there are a number of properties that will give you data about the status of VMware Tools. In this case we’re looking for the toolsVersionStatus property.

API Explorer - Finding the Tools Version property.
API Explorer – Finding the Tools Version property.

This property is a string, but if you look at the text, it will tell you where to find the possible values – in this case under the type VcVirtualMachineToolsVersionStatus. Click that link to see the available values that this property can return.

API Explorer - The Virtual Machine Guest Status Codes.
API Explorer – The Virtual Machine Guest Status Codes.

You now can see what the possible values are and what they represent in each situation.
So after drilling down in the API Explorer to get this data, how do we work with it?

The Code

All you really need to know is, you can access the value of the VMware Tools status using this code in your Action:

System.log("The VMware Tools status for the VM is: "+inputVM.guest.toolsVersionStatus)

It’s really that simple, at least for this particular property. With that in mind, let’s make a couple of different versions of the Action.

First Pass

You can use a simple bit of code here – this just says if it’s not current, return false. If it is current, return true.

if(inputVM.guest.toolsVersionStatus == "guestToolsCurrent") {
  // the VMware Tools are current and up to date.
  return true;
} else {
  // the VMware Tools are not where they should be.
  return false;
}

Pretty simple right?

But what if you want to go a little further with additional checks?

For example, a VM that isn’t powered on will be able to execute the above action, but it will just say “guestToolsNotInstalled” – which may or may not be true! Let’s re-write it a bit using some more exploration of the API.

Second Pass

In the API Explorer, go back to the VcVirtualMachine type that we started with. There’s nothing that obviously tells you the current power state here, but if you dig you’ll find the runtime property that mentions power state, leading you to the VcVirtualMachineRuntimeInfo type.

Keep drilling, and you’ll find the powerState property, giving you a list of all possible states. Let’s use this to make our Action a little more effective.

// is our VM powered on?
if(inputVM.runtime.powerState == "poweredOn") {
  // it's powered up, so let's check the tools info
  if(inputVM.guest.toolsVersionStatus == "guestToolsCurrent") {
    // the tools are current!
    return true
  } else {
    // tools are not current
    return false
  }
} else {
  // the VM isn't powered up, so let's return false
  return false
}

You can just keep building on this Action if you want, or do what I do: keep it simple.
Actions and Workflows are easier to debug if your code is simpler!

Let’s add this action into a workflow with some basic decision making logic.

The Workflow

Go to the Workflows Tab, open your folder and right-click, choosing New Workflow, and name it.

The new Workflow for your Action.
The new Workflow for your Action.

After you do so, you’ll be in the Workflow Designer – choose the Schema Tab.

In the left menu, search for your Action, and drag/drop it into the Schema.

Adding the Action to your Workflow Schema.
Adding the Action to your Workflow Schema.

After that, you will again get the prompt to setup the parameters within the workflow. Click Setup, and configure it like the below:

Binding the Action's inputs and actionResult to your Workflow.
Binding the Action’s inputs and actionResult to your Workflow.

This automatically connects the inputVM parameter as an Input to the workflow, and also configures an Attribute called toolsStatus that is bound to the output of your Action. Easy!  Keep in mind, you can name the attribute whatever you want!

Once that is done, we will add a Decision element to the workflow. This allows us to create a fork in the road based on the value of an attribute, which in this case is whether the Attribute toolsStatus value is TRUE, or FALSE.

Search for a Decision element in the left window, and drag/drop it after the Action in your Schema.

Your schema, with the Decision element.
Your schema, with the Decision element.

Once the element is added, click the pencil icon above it to edit the settings. There isn’t much to change here, so go to the Decision tab. Click the link there to choose which Attribute in the workflow you wish to check on. It should be toolsStatus in this case – no binding is required for this element.

Setting up the Decision element.
Setting up the Decision element.

You now have a Workflow that can act based on the output of your Action. A few ideas to try:

  • Add the built-in workflow to Upgrade Tools, or Upgrade Tools at Next Reboot on the FALSE workflow path
  • Write a log entry indicating the tools are up to date on the TRUE workflow path

Setting these particular capabilities up are drag and drop affairs, just like adding your Actions and Scriptable Tasks. I realize it sounds lame, but the only limit to what you can do is imagination – you just have to consider your use cases and impact of your design. If you want the workflow to automatically install upgraded tools, can it be rebooted right after if needed? There are many things to consider.

In the next post, we will dive a bit deeper into working with Arrays of objects, such as ESX Hosts or Virtual Machines. Thanks for reading, and hopefully if you’re just getting started with VCO, this was helpful!

 

VCO – All about that Base64 Action


In my time working with integration with other systems with REST APIs – just about every system using Basic Authentication needs a Base64 encoded string for the password. I figured, why not just make this an Action that I can reference easily later? Spoiler alert: I reference this Action a LOT.

The Code

The Base64 function is culled from various online resources. A few minor modifications, and we have an action that takes input of the string to encode, and a boolean of whether you are encoding the string, or decoding it. That way, we put both capabilities into a single action!

This particular version references the JSFiddle code from here: http://jsfiddle.net/gabrieleromanato/qaght/

The code is unmodified except for the final lines attempting to write into a document – which are removed. A slight bit of logic in VCO later, you have a simple encode/decode Action for your use.

Of note, if you have other JavaScript functions like this you want to use in VCO – this can be a template of sorts! Hopefully you find it as useful as I have.

You can download a ZIP of the Action for import into your VCO right here.

Learning vCO – Beginner Actions, World 1-1

As David Hasslehoff would say, you need some action(s)!

In Orchestrator, Actions are akin to functions in typical programming languages – in this case, Javascript. Functions and Actions can run the spectrum in terms of complexity – some are extremely simple, others can be extremely complicated. But ultimately, if the Action is a repeatable task you’d rather call than write over and over again, making an Action is the sensible thing to do.

Out of the box, VMware piles on numerous Actions you can use in your workflows. These can range from typical things you want to pull from vCenter, such as getting a list of all VMs in a cluster, or getting all clusters in a datacenter. Others can get you a list of VMs that are running a particular OS, such as Windows or Linux.

This post will be the first in a series of creating basic Actions, moving to the more complex, along with integration into a workflow.

The best way to learn the value of Actions, much like anything in Orchestrator, is to work with them or create them regularly.

NOTE: If you are not familiar with JavaScript and wish to use Orchestrator, I would recommend getting familiar fast!
The best online and free JavaScript training I have seen is CodeAcademy. It can take up to 10 hours or so, but you work at your own pace, and get fantastic feedback as you go.

Time to get Modular

The first thing to do is to create your own module in Orchestrator. Creating a module is useful, as it allows you the ability to call your Actions from pretty much anywhere, and export/import them wherever you like. Plus, all the cool kids are sharing their Actions on FlowGrab, so get on it!

From the Design menu in the Orchestrator client, go to the Actions icon, which looks like a gear icon.

The vCO Actions Menu.
The vCO Actions Menu.

In here, you’ll see piles of Actions for many vSphere objects and other types, based on the plugins you have installed. Browse around and look at them – you’ll see many of them are not particularly complicated scripts, but it does vary. Our example in this post will be VERY simple, but it will give you a good sense of how to both build an Action, and call the Action, from top to bottom.

So, let’s create your own module. The typical scheme is a reverse FQDN format. In the screenshot above it is A.NSFV.LAB.REPOSITORY. I could have followed the domain, but I like my stuff at the top!

With that done, right-click the module you created and choose Add Action. Name the Action combineTwoParameters.

Creating your new Action.
Creating your new Action.

Once it is created, you will immediately be taken into the Action for editing. When creating an Action, it’s good to have an idea of what is going in and what you are expecting will come out of it when the code is done running.

Setting up your Action.
Setting up your Action.

In our case, we are doing a simple combination of two values we input into the parameter listing, so the setup and code should be very easy.

Click the 03-edit-action-arrowicon icon above the parameter listing twice. This will create two input parameters named arg0 and arg1, of type String.

Once you have created the parameters, click the Return Type option (which is void by default), and choose the type String. This is probably one of the most important things to do – if you do not specify the return type, the Action will always return nothing!

Adding parameters to your Action.
Adding parameters to your Action.

With that done, below the parameter list will be your code window, as seen here with the API Explorer on the left.

The Action code window.
The Action code window, and your API Explorer.

Now, you’re ready to code the Action itself.
Since we’re keeping it simple for this example, you can copy/paste the code below.

var output = arg0+arg1
System.log("The combined value: "+output)
return output

Admittedly, that’s pretty easy! We’re taking the arg0 and arg1 values and just combining them, assigning the value to the variable output.

Then, we are returning the value of the output variable.

Once this is done, click Save and Close, and go to the Workflows tab.
You’re done! But now it’s time to show you a couple of ways you can use your new Action.

Using your Action in the GUI

The first way to use the Action you created is to use the GUI and add it to a workflow.

Begin by right-clicking and choosing Add Folder. Create your own folder of choice, outside of the standard workflow library.

Next, right-click and choose New Workflow. I named mine based on the post, but obviously, you can name it to your choosing.

Long name for a simple workflow.
Long name for a simple workflow.

When you have created the workflow, it will take you straight into editing mode. Click on the Schema tab.

A workflow's blank slate.
A workflow’s blank slate.

In the search bar, you can type the name of your Action and it should show up. Click and drag it into the workflow area and place it on the arrow.

Adding your Action to the new workflow.
Adding your Action to the new workflow.

At this point, you’ll see a message pop up about adding the “activity’s” input/output to the workflow. In this case, click Setup to do so.

Setting up Action and Workflow bindings.
Setting up Action and Workflow bindings.

This menu can help get the values of your action assigned to the workflow more efficiently, or mapped/bound to other attributes.  For this exercise, arg0 and arg1 can be set to Input, and the actionResult can be set to Local Variable. Then, click Promote.

Now, you can run the workflow, and give it a go.

This should be pretty easy.
This should be pretty easy.
Run that bad boy!
Run that bad boy!

The Trace View should output the value of the two strings added together.

The moment of truth!
The moment of truth!

In addition, the value has been assigned to the workflow attribute actionResult, and you could bind that attribute to other elements in the workflow as an argument or parameter.

Using your Action, in a script

I indicated earlier that Actions can be called in different ways.  Here’s an example of doing just that, in a single Scriptable Task element.

Instead of dropping a copy of the Action you created into the workflow, drop in a Scriptable Task.

Using a scriptable task instead of your Action.
Using a scriptable task instead of your Action.

These elements are generally used for specific tasks that are unique to the workflow.
They can also be the only thing a workflow designer uses if they are particularly comfortable and familiar with the APIs they are working with.

Once you have added the Scriptable Task element, edit it as-is. Input the following lines of code:

var output = System.getModule("a.nsfv.lab.repository").combineTwoParameters("Jump To","Conclusions Mat")
System.log(output)

This format should be fairly simple to follow, but let’s break it down.
Remember that module you made at the beginning of the post?  This is where it comes into play.

You are defining a variable, output, and calling the Action combineTwoParameters which resides inside the module a.nsfv.lab.repository. When you call it, you are assigning the same string values you did earlier to the arguments in parentheses.

(Hopefully, that made some sense. I’m still working on my delivery.)

An interesting side note: if you do drag and drop the Action into your workflow and attempt to edit it, click on the Scripting tab. In there, you will see a line of code which looks just like the above. So the Action you are dragging into your workflow schema is really just an automatically generated script that calls an instance of your Action code.

How to call your Action code programatically, exposed!
How to call your Action code programatically, exposed!

I promise it’s not as complicated as it sounds. If anything, it is reducing the amount of code you would otherwise write.

Theoretically, you could call countless Actions in a single Scriptable Task. But you may not necessarily want to. The decision is up to you, but my advice would be to do as much as you can in the GUI so that others can more easily follow your work if they need to visit it. Not only that, I find it helps me out too, when I’m working on complicated workflows. It’s all a matter of preference.

My next post will continue with some simple VM tasks and working with the API Explorer. In the meantime, practice up, and look at the Actions that are already available to you. You may find that there are quite a few gaps – hopefully after going through these posts, you’ll be able to fill in your own gaps!