lmonaco
Hot Shot
Hot Shot

Convert vCAC Designer workflow to a vCO workflow.

I'm currently using vCAC Designer to modify the WFStubMachineProvisioned workflow to call a PowerShell script to add a DNS record.

In the script, I collect the info below, then use it later in the script to add the records. Works great.

$Hostname = $Properties["VirtualMachineName"]

$IPAddress = $Properties["VirtualMachine.Network0.Address"]

$ZoneName = $Properties["ZoneName"]

How would I go about doing this in vCO?

I do have the vCAC 6.0 extensibility package installed in vCO 5.5, but I'm new to vCO and am looking for an example of how to pull and pass vCAC VM properties in a PowerShell script.

14 Replies
qc4vmware
Virtuoso
Virtuoso

There is a sample template which will get you started at Libraray\vCloud Automation Center\Extensibility\Workflow Template .  This is a good item to duplicate and start creating your workflow.  I also created this action which will pull pretty much everything I need into one properties type.  Then you can just do allProps.get("whateverpropertyyouneed");  In this example I am using a call to a couple of other actions I have posted on here recently.  One that gets the vCenter vm from the vCAC vm and one the gets the vCACHost from the vCACVm.  This way only have to pass the action the vCACVM.  For some reason neither of those things is a simple attribute of the vCACVM:VirtualMachine object type.  Just look at my other recent posts and you can grab the sample code for those actions.

var allProps = new Properties();

var virtualMachineEntity = vCACVm.getEntity();

// System.log("Got vCAC virtual machine " + vCACVm.virtualMachineName);

// System.log("Matching virtual machine entity " + virtualMachineEntity.keyString);

var vCenterVm = System.getModule("com.qualcomm.basic").QCgetvCenterVmFromvCACVm(vCACVm);

var vCACVmProperties = vCACVm.getEntity().getProperties();

if (vCenterVm != null) {

  // System.log("Got vCenter VM " + vCenterVm.name + ", ID: " + vCenterVm.id);

  allProps.put("vCenterVm", vCenterVm);

}

//Load vCAC VM properties

if (vCACVmProperties != null) {

  for each (var key in vCACVmProperties.keys) {

  allProps.put(key, vCACVmProperties.get(key));

  }

}

var vCACHost = System.getModule("com.qualcomm.basic").QCgetvCACHostForvCACVm(vCACVm);

var vCACVmExtendedProps = System.getModule("com.vmware.library.vcac").getPropertiesFromVirtualMachine(vCACHost,vCACVm);

//Load vCAC VM Extended properties

if (vCACVmExtendedProps != null) {

  for each (var key in vCACVmExtendedProps.keys) {

  allProps.put(key, vCACVmExtendedProps.get(key));

  }

}

for each (var key in allProps.keys) System.log(key + ": " + allProps.get(key));

return allProps;

0 Kudos
lmonaco
Hot Shot
Hot Shot

Thanks qc4vmware...

Can this be done with PowerShell?

Do I just take your code above and create a new action, then call that action from a workflow?

How do I pass the hostname & IP to a PowerShell script?

Do you have an example workflow you can share?

0 Kudos
qc4vmware
Virtuoso
Virtuoso

In all you'll have to create three new actions or replace the actions I am making calls to with the code itself. Yes you just create a new action with one input of type vCAC:VirtualMachine l named vCACVm, the output is type "Properties", then just cut and paste the code above as a script.

My other posts are here Get the vCAC:VCACHost from the vCAC:VirtualMachine and here get vCenter VM from vCAC VM .

As for what you can and/or can't do with PowerShell I'm not sure.  If you are using a windows based vCO server and have the powershell scripts local you can easily call them using the "Command" scripting object.  There is also the powershell plugin for vCO but I have never tried using that so I am not exactly sure how it is implemented.  You should be able to just recreate the powershell script natively in vCO which will probably be the best option long term.

Once you create this action and run it against a vm it will spit all the properties and their values into the logs.  What you will most likely want are the "hostname" and the ip address of the first nic.  So the code would be:

var hostname = allProps.get("VirtualMachineName"); // using your example above... you might also want allProps.get("hostname");

var ipaddress = allProps.get("VirtualMachine.Network0.Address");

var zonename = allProps.get("ZoneName");

Then to call your powershell script something like

var psCommand = new Command("c/path/script.ps " + hostname + " " + ipaddress + " " + zonename);

psCommand.execute(true);

LividBliss
Enthusiast
Enthusiast

So poster "lmonaco" and I have been working on this one, we have a workflow that add A/PTR records to the parent zone.  How do we combine the VirtualMachineName with "ZoneName" (Blueprint Custom Property with .child.domain.com)?

Working Parent Zone:

var recordName = vcacVM.getProperty("VirtualMachineName");

var vmProps = vcacVM.getLink(vcacHost,"VirtualMachineProperties");

    for each (var prop in vmProps) {

        var propertyName = prop.getProperty("PropertyName");

        var propertyValue = prop.getProperty("PropertyValue");

        if (propertyName == "VirtualMachine.Network0.Address") {

            var recordValue = propertyValue;

        }

}

----------------------------------------------------------------------------------------------------------------------

Would like to add "ZoneName", something like this?

var recordName = vcacVM.getProperties("VirtualMachineName"+"ZoneName");

I am still learning how to script; I get the feeling another line is needed to combine the properties right?

0 Kudos
Burke-
VMware Employee
VMware Employee

You need to get the VirtualMachineName and ZoneName properties and store them each in their own variable (\, once you have done that, THEN you concatenate them like:

var recordName = vmName + zoneName;

In the above example, you would have stored the "VirtualMachineName" property in the variable "vmName" and the "ZoneName" property in the variable "zoneName".

If my answer resolved or helped you, please mark it as Correct or Helpful to award points. Thank you! Visit http://www.vcoteam.info & http://blogs.vmware.com/orchestrator for vRealize Orchestrator tips and tutorials - @TechnicalValues on Twitter
0 Kudos
LividBliss
Enthusiast
Enthusiast

This isn’t working but I feel I am close:



var recordName = vmName + childName;
var vmProps = vcacVM.getLink(vcacHost,"VirtualMachineProperties");
    for each (var prop in vmProps) {
        var propertyName = prop.getProperty("PropertyName");
        var propertyValue = prop.getProperty("PropertyValue");
        if (propertyName == "VirtualMachine.Network0.Address") {
            var recordValue = propertyValue;
            var vmName = prop.getProperty("VirtualMachineName")
            var childName = prop.getProperty("ChildName")
        }
}

0 Kudos
Burke-
VMware Employee
VMware Employee

In the lines above that code, are you setting/retrieving values for "vmName" and "childName" ?

It looks like you should move that first line to the last line of code inside your If statement.... that seems to be where you are defining values for those two variables.. you can't concatenate the values until they have been assigned Smiley Wink

var vmProps = vcacVM.getLink(vcacHost,"VirtualMachineProperties");

    for each (var prop in vmProps) {

        var propertyName = prop.getProperty("PropertyName");

        var propertyValue = prop.getProperty("PropertyValue");

        if (propertyName == "VirtualMachine.Network0.Address") {

            var recordValue = propertyValue;

            var vmName = prop.getProperty("VirtualMachineName")

            var childName = prop.getProperty("ChildName")

            var recordName = vmName + childName;

        }

}

If my answer resolved or helped you, please mark it as Correct or Helpful to award points. Thank you! Visit http://www.vcoteam.info & http://blogs.vmware.com/orchestrator for vRealize Orchestrator tips and tutorials - @TechnicalValues on Twitter
0 Kudos
LividBliss
Enthusiast
Enthusiast

Got it working with this:

var vmName = vcacVM.getProperty("VirtualMachineName");

var recordName = (vmName + '.' + 'child-domain');

var vmProps = vcacVM.getLink(vcacHost,"VirtualMachineProperties"); 

        for each (var prop in vmProps) { 

            var propertyName = prop.getProperty("PropertyName"); 

            var propertyValue = prop.getProperty("PropertyValue"); 

            if (propertyName == "VirtualMachine.Network0.Address") { 

                var recordValue = propertyValue;

            } 

    } 

Still having trouble pulling vcacVM properties like "VirtualMachine.Network0.DnsSuffix" and "ChildZone" (Custom Prop with FQDN).  I didn't write the original script but managed to get this one working by adding the  "." and the "child-domain" in text in the second line.

Thanks for the guidance!

0 Kudos
jlholbrook
Enthusiast
Enthusiast

Can this be adapted for vCloud vApp deployments. I am modifying the MachineProvisioned workflow and vCAC is not sending a value for the vCloudvApp In parameter. It appears I do have the vCloud:VM Object Id as a property of the vCACVmProperties.

var vcVmUuid = vCACVmProperties.get("VirtualMachine.Admin.UUID");

How can I get the vCloud:VM and then the VCVirtualMachine thta I can then take action on?

Any guidance would be appreciated.

0 Kudos
bogdan1977
Contributor
Contributor

Hello,

  I am working with VCO scripting and I build a workflow.

  I am  trying  to obtain a VCAC Virtual machine object from a VCAC Guid.  All that I found in the API is this

var vCACEntity =  System.getModule("com.vmware.library.vcac").getVirtualMachineEntityFromId( null, virtualMachineId );

I obtain a VCACEntity. Next I need to obtain the VCACVirtualMachine object in order to extract its extended properties.

Code would be something like this:

vCACVmExtendedProps = System.getModule("com.vmware.library.vcac").getPropertiesFromVirtualMachine(host, vCACvm);

where the vCACvm is the VCACVirtualMachine object.

I can't (don't know) to make the connection between VCACEntity and VCACVirtualMachine object.

Any hint how to do this?

much appreciated.

thanks.

Bogdan

0 Kudos
cdecanini_
VMware Employee
VMware Employee

Do

vCACvm = vCACEntity.getInventoryObject();

If my answer resolved or helped you, please mark it as Correct or Helpful to award points. Thank you! Visit http://www.vcoteam.info & http://blogs.vmware.com/orchestrator for vCenter Orchestrator tips and tutorials - @vCOTeam on Twitter
0 Kudos
bogdan1977
Contributor
Contributor

Thanks for that. This works indeed.

Actually what I was trying to do is to change the virtual machine name from the VCO script. This is possible with VCAC Designer workflows, but my intention is to rewrite them completely in VCO.

From another blog I got this command:

System.getModule("com.vmware.library.vcac").addUpdatePropertyFromVirtualMachineEntity(host,vCACvmEntity,'VirtualMachineName',machineName);

However this attempts to create/update a custom property named 'VirtualMachineName' which is wrong (the VM name is not custom property). After this it fails

wirth message

Create property VirtualMachineName : [MODIFIED_VMNAME] on virtualMachine entity [VMNAME]

The validated object is null (Dynamic Script Module name : addUpdatePropertyFromVirtualMachineEntity#42)

In VCAC Designer it's used the ManagementModelEntities object which is able to call the "Update" method for a VM object, combined with powershell.

example:

$Machine.VirtualMachineName = $machineName.ToUpper();

if ( $MgmtContext -ne $null ) {

  $MgmtContext.UpdateObject($Machine)

  $MgmtContext.SaveChanges()

}

So I am not sure if this is even possible directly from VCO scripting.   I use VCAC 5.2 with VCenter 5.5

Any help or hint is much appreciated.

thanks,

Bogdan

0 Kudos
chrisheartland
Enthusiast
Enthusiast

Were you able to fully get this figured out? I want to do the same thing. I am trying to use a workflow called "create / update property on virtual machine entity" which is in essence just calling the "addUpdatePropertyFromVirtualMachineEntity" action for you. I am setting the property name to "VirtualMachine.Network0.Name" and the value is my network label. When it runs however I'm getting the error "The validated object is null (Dynamic Script Module name : addUpdatePropertyFromVirtualMachineEntity#7).

0 Kudos
bogdang77
Contributor
Contributor

I was able to rename a virtual machine by removing and adding back the property. I didn't used anymore the "addUpdatePropertyFromVirtualMachineEntity" method but this:

var vCACvmEntity =  System.getModule("com.vmware.library.vcac").getVirtualMachineEntityFromId( null, virtualMachineId );

var virtualMachineProperties = vCACvmEntity.getProperties();

var machineName = "NEW VM name";

virtualMachineProperties.remove('VirtualMachineName');
virtualMachineProperties.put('VirtualMachineName', machineName);


var hostId = vCACvmEntity.hostId;
var modelName = vCACvmEntity.modelName;
var entitySetName = vCACvmEntity.entitySetName;
var entityIdString = vCACvmEntity.keyString;


actionResult = System.getModule("com.vmware.library.vcac").updateVCACEntity(hostId,modelName,entitySetName,entityIdString,virtualMachineProperties,null,null) ;

However I am not sure if this works for every VM property or if there other unwanted consequences when removing and adding a property.