VMware Cloud Community
frefal
Enthusiast
Enthusiast

Get all vms in vCD organization

Hello!

I am an Orchestrator newbie and I am trying to create a workflow that will get all VMs inside a specific organization and then suspend all of those VMs via the vcloud director / vapp / vm / power / suspend a virtual machine workflow.

So I thought that I would first use the Action element to catch all my VMs in an org, but I can't find any element that matches my wish. How do I accomplish this task?

Thank you!

Reply
0 Kudos
15 Replies
cdecanini_
VMware Employee
VMware Employee

There are different ways of doing this:

-1- Get all Org VDCs, for each VDC get all vApps, for each vApp get all VMs

-2- Use the query service to get all the vApps belonging to an org (using the organization as a container - this may also work for a VM).

For 2) a good reference is : Leveraging the VMware vCloud Director query service

It has links to other examples.

If you don't manage to build your query with the contaoner org you can always use one of the examples getting all vApps or VMs and then iterate on the array to check if the parent organization is the one you are expecting.

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
Reply
0 Kudos
frefal
Enthusiast
Enthusiast

Thank you for the information.

Since we only have one vdc per org I thought I would firstly get all vApps in the vdc by using the action element getvdcvapps, then get the vms in the vapps and so on.

So I add getVdcVapps to my brand new workflow and I run "promote Workflow input/output parameters" and set the vdc as a value for vdc and I leave the output as is.

Then my idea here is to run the workflow in debug mode to see that it is actually getting expected results to the output variable, but instead it fails with the error "Cannot find function getHost in object notfound. (Dynamic Script Module name : getVdcVapps#64720)"

Reply
0 Kudos
cdecanini_
VMware Employee
VMware Employee

This is a typical problem whan vCD is used with a load balancer and that the public API specified in vCD does not match the one specified in the vCD plug-in.

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
Reply
0 Kudos
frefal
Enthusiast
Enthusiast

There was a missmatch between the urls in the plugin & the public api. Thanks! Now I can continue Smiley Happy

Reply
0 Kudos
frefal
Enthusiast
Enthusiast

Ok, so now I run "getVdcVapps" against a vdc and the variable gets filled with the different vApps. Great.

Now I want to take each of those vApps in the variable and extract the VMs.

I tried to use "getChildrenVmsVApp" and used the out attributes from getVdcVapps as in attribute in the getChildrenVmsVApp. I have set the an out parameter in the getChildrenVmsVApp.

When I run it it fails with TypeError: Cannot call method "getChildrenVms" of null (Dynamic Script Module name : getChildrenVmsVApp#1)

I was considering if I can use a scriptable task instead to extract the information, although I am not certain of how to do this.

Reply
0 Kudos
cdecanini_
VMware Employee
VMware Employee

The vApp you have as parameter to getChildrenVms is not set.

In a single script this should look like this (I did not test this - I have no vCD environment to test with).

for each (var vApp in vApps) {

     var vms = System.getModule("com.vmware.library.vcd.vapp").getChildrenVmsVapp(vApp) ; //Not sure about the module names, please check

    for each (var vm in vms) {

          //do something on each VM;

     }

}

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
Reply
0 Kudos
frefal
Enthusiast
Enthusiast

Thank you! Great help.

In a test I do get an error though, "ReferenceError: "getChildrenVmsVapp" is not defined."

I found an example from the plug-in doc center which uses the query service, and I can see via the System.log that it finds the VMs in each vApp.

I want to push the results into my output "VMName" which is an array, but it doesnt quite work out.

Error is ch.dunes.model.type.ConvertorException: Not an Array

Heres the script:

var VMName = new Array();

for each (var vapp in vApps) {

var queryService = vapp.getHost().getQueryService();

var expression = new VclExpression(VclQueryVMField.CONTAINER, vapp.getReference().href, VclExpressionType.EQUALS);

var filter = new VclFilter(expression);

var params = new VclQueryParams();

params.setFilter(filter);

var resultSet = queryService.queryRecords(VclQueryRecordType.ADMINVM, params);

while (resultSet != null)  {

     var records = resultSet.getRecords(new VclQueryResultAdminVMRecord());

     System.log(records.length + " records found");

     for (i = 0; i < records.length; i++) {

  System.log(records[i].name);

  VMName.push(records[i].name);

     }

     resultSet = resultSet.getNextPage();

}

     }

Reply
0 Kudos
cdecanini_
VMware Employee
VMware Employee

I have corrected the code I posted before with putting the Syntax to call an action. Please check the module name since I cannot do it in my environment.

As for the query, even if it would work you are getting the VMNames which  woukd not help you to get the underlying VMs. You may want to pursue using the built in actions from teh library and if you want to understand how to use the query you can use this as an example : com.vmware.coe.vcd.qs.getVAppByName.package

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
Reply
0 Kudos
frefal
Enthusiast
Enthusiast

Perfect thanks.

I corrected the module name and added the suspend part;

for each (var vApp in vApps) {

     var vms = System.getModule("com.vmware.library.vCloud.operation").getChildrenVmsVApp(vApp) ; //Not sure about the module names, please check

  

    for each (var vm in vms) {

          System.getModule("com.vmware.library.vCloud.operation").suspendVM(vm);

     }

}

It suspends the first machine in the array since it was powered on, but the other machines are powered off and therefore it could not suspend and it fails.

The requested operation could not be executed since VM "W81x64" is not running.; majorErrorCode=400; minorErrorCode=BAD_REQUEST; vendorSpecificErrorCode=null; (Dynamic Script Module name : suspendVM#1)

How can I accompish that it continues even though an error occured. Or, even better, check the powerstate of the VM and only suspend the Powered On ones and ignore the rest. I was looking for some like "powerStateVM" without success.

Reply
0 Kudos
cdecanini_
VMware Employee
VMware Employee

There is a way to check the VM power state but unfortunately I cannot remember it on top of my head. You may want to look in the API explorer or download some of the packages that are for vCloud in the documents tab.

Also once completed you will get to some automation but you will want to put the scripts in different steps. For example one step to get all the vApps, a workflow loop to iterate over the vApps and one on the VM. This way if the orchestrator service is stopped during the execution it will be able to resume from where it stopped exactly.

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
Reply
0 Kudos
frefal
Enthusiast
Enthusiast

Thanks, once I get this working I will split it up into a loop!

I have been running up and down in the API explorer trying to find something to give me the power status of the vm in plain text but those I´ve tried does not work and I don´t understand the error message.

So now I have all my VMs in an array/vcloud:vm called vm1 and in a new scriptable task i want to get the power status of the vm and if it is on I will go ahead and suspend.

My first try to see what it outputs:

for each (var vm in vm1) {

var status = new VclVMStatus(vm).value ;

  System.log(status);

}

and it fails with: Unable to create object : _VclVMStatus : Class ch.dunes.vso.sdk.DynamicWrapper can not access a member of class com.vmware.vmo.plugin.vcloud.model.sdk.enumerations.VMStatus with modifiers "private"

and also:

var myVclVM = new VclVM(vm).status ;

  System.log(myVclVM);

It gives the error: Unable to create object : VclVM : com.vmware.vmo.plugin.vcloud.model.VM

Any hints?

Reply
0 Kudos
frefal
Enthusiast
Enthusiast

So to get the power status was pretty easy. I did:

for each (var vm in vm1) {

System.log(vm.status);

}

and it returns a status;

8 for powered off

3 for suspend

4 for power on

Now the problem is that these statuses dont seem to update properly. For example, after I powered off a machine it stills returns status 4

Is this working as intended?

Edit: I ran the workflow 20 min later and the status were now correct. I then went ahead and powered on one vm and ran the workflow again, it still showed this machine as powered off. So I guess, another 20mins and the status is correct.

Reply
0 Kudos
frefal
Enthusiast
Enthusiast

Apparently you need to use updateinternalstatevm() for the vm.status to show correctly!

Got the workflow up and running in a loop and all.

Thanks

Reply
0 Kudos
TelefonicaHosti
Contributor
Contributor

a

Reply
0 Kudos
raulgr
Contributor
Contributor

More Easy.

Simply need to launch:

Get-Org -Name 'Name_Org' | Get-CIVM

If you dont know Name Organization , you can to see list of name with "Get-Org" without parameters.

Regards.

Raúl 3k3y