Friday 25 May 2018

vRealize Automation - More VM Expiration Notifications

I have been working with a customer who have mentioned concern around VMs suddenly turning themselves off if users forget the VM has a lease or don't regularly use vRA.  This to me is a question of good operating procedures and user education - but Rome wasn't built in a day, so what can we do to help...

The first article I came across was from VMware which seems to provide an out of the box method of notifying users, which is great...
https://docs.vmware.com/en/vRealize-Automation/7.3/com.vmware.vra.prepare.use.doc/GUID-D2EA650F-7A6B-45D2-9CD6-E194EAD73B7D.html
but my problem is that if we want to provide more than one notification (i.e., "You have 5 days to go" and then "Last warning - your VM's going to be shut down if you don't extend the lease" type approach)... 

What I did was write a vRO workflow to find the expiration date from the vCAC:VirtualMachine and check whether it was * number of days ahead of the current date in order to trigger an email to send a custom warning.  My main issue was that the vCAC:VirtualMachine date object is in a format of string like 2018-05-25T10:15:11:254 - which I needed to convert into a vRO Date Object.

I first created an action to take the string of the vCAC Date Object and convert it to a date object.  I couldn't find a better way to do it other than splitting the string, so it looks like this:

//Input  dateString - String
//Output Date
var tempSplit = new Array();
tempSplit = dateString.split("-");
var year = tempSplit[0];
var month = tempSplit[1];
month = month -1;
var dayTime = tempSplit[2];
tempSplit = dayTime.split("T");
var day = tempSplit[0];
tempSplit = tempSplit[1].split(":");
var hour = tempSplit[0];
var minute = tempSplit[1];
tempSplit = tempSplit[2].split(".");
var second = tempSplit[0];
//Return Date Object
return (new Date(year,month,day,hour,minute,second));

From which, I can use the action to convert the date string to a vRO date and use an 'if' statement to filter VMs with a relevant date into the three separate arrays

var vcacVms = Server.findAllForType("vCAC:VirtualMachine");

//Get future dates
var now = new Date();
var dayPlus1 = new Date();
dayPlus1.setDate(dayPlus1.getDate() + 1); 
var dayPlus3 = new Date();
dayPlus3.setDate(dayPlus3.getDate() + 3); 
var dayPlus5 = new Date();
dayPlus5.setDate(dayPlus5.getDate() + 5); 

//Define arrays
var vms5Day = new Array();
var vms3Day = new Array();
var vms1Day = new Array();

//Loop all VMs to idenfity expiration times
for each (var vcacVm in vcacVms) {
System.log (vcacVm.displayName);
var vmExpires =  vcacVm.expires
System.log (vmExpires)
if (vmExpires != null) {
vmExpires = vmExpires.toString();
var dateObj = System.getModule("com.vmware.sjw").convertVraDateStringToDateObject(vmExpires);
if ((dateObj < dayPlus5) && (dateObj > dayPlus3)) {
System.log (vcacVm.displayName + " has 5 days until expiration");
vms5Day.push(vcacVm);
if ((dateObj < dayPlus3) && (dateObj >dayPlus1)) {
System.log (vcacVm.displayName + " has 3 days until expiration");
vms3Day.push(vcacVm);
if ((dateObj < dayPlus1) && (dateObj > now)) {
System.log (vcacVm.displayName + " has 1 days until expiration");
vms1Day.push(vcacVm);
}
};
};

From the three separate arrays, I had three separate tasks for each array (mainly to be able to separate out other actions should we need them in the future)...   This was done using the new EmailMessage(); functionality with HTLM content stored in the WF attributes (mailBody)...  An example is below:

for each (var vm3Day in vms3Day) 
{ var displayName = vm3Day.displayName;
  var expiration = vm3Day.expires;
  var notes = vm3Day.notes;
if (notes == null) {
notes = "No details supplied at provisioning time"}
var messageContent = mailBody
messageContent = messageContent.replace ("{{vmName}}",displayName)
messageContent = messageContent.replace ("{{expirationDate}}",expiration)
messageContent = messageContent.replace ("{{details}}",notes)

//Get Catalog Resource from vCAC VM and get mail address from user reference
var cafeVm = System.getModule("com.vmware.sjw").getCatalogResourceOfVM(vm3Day,"arm")
var owners = new Array();
owners = cafeVm.owners;
var mailAddress = owners[0].getRef();

//Send email 
var message = new EmailMessage() ; 
message.subject = "Warning - less than 3 day on VM " + displayName  + " lease." ; 
message.toAddress = mailAddress ; 
message.addMimePart(messageContent,"text/html");
message.sendMessage();
}

N.B., the action referred in the above 'getCatalogResourceOfVM' info can be found here:
https://gist.github.com/trisharia/7663173413c224dbf62aa9d0dac6a02a


I don't think it's ideal, but it works!