pyvcloud
pyvcloud copied to clipboard
Can't get all VMs from vApp
With the following methods:
from pyvcloud.vcd.client import BasicLoginCredentials, Client, EntityType
from pyvcloud.vcd.org import Org
from pyvcloud.vcd.vapp import VApp
from pyvcloud.vcd.vm import VM
from pyvcloud.vcd.vdc import VDC
from typing import List
import requests
requests.packages.urllib3.disable_warnings()
class VCDCollector:
def __init__(self, url, username, password, org):
self.url = url
self.username = username
self.password = password
self.org = org
self.client = Client(
self.url,
verify_ssl_certs=False,
log_file=f'logs/vcd_{org}.log',
)
self.client.set_highest_supported_version()
self.client.set_credentials(BasicLoginCredentials(
self.username,
self.org,
self.password
))
self.vcd_org = Org(self.client, resource=self.client.get_org())
def get_vdcs(self) -> List[VDC]:
return [VDC(self.client, resource=self.vcd_org.get_vdc(vdc['name'])) for vdc in self.vcd_org.list_vdcs()]
def get_vapps(self, vdc: VDC) -> List[VApp]:
vapps = vdc.list_resources(EntityType.VAPP)
vcd_vapps = []
for vapp in vapps:
vcd_vapps.append(
VApp(client=self.client,
resource=vdc.get_vapp(name=vapp['name']))
)
return vcd_vapps
def get_vms_from_vapp(self, vapp: VApp) -> List[VM]:
print(vapp.get_all_vms())
The get_vms_from_vapp
method doesn't print anything.
This is my code used to call the above methods:
vcd_col = VCDCollector(url="vcd_url", username='test', password='test', org='test')
for vdc in vcd_col.get_vdcs():
vapps = vcd_col.get_vapps(vdc=vdc)
for vapp in vapps:
vms = vcd_col.get_vms_from_vapp(vapp=vapp)
Hi,
I have the same issue. I'm not trying to do fancy things: just retrieve a list of Virtual Machines in a first time. Is there a known pyvcloud version where this is not broken? (Vapp object creation via resource instead of href)
Additionally here is a little debug I have done. (edit : I was not expecting to find a way to make this work)
- get_all_vms is looking for some attributes which are non-existent in my case :
hasattr(self.resource.Children, 'Vm')
- I am using 'resource' to set my vapp as the vdc does not return a 'href' for the vapp:
currentVapp = VApp(client, resource=resource)
- Even after VApp object initialisation, href is empty.
- If I call the VApp
reload()
method I got errors like "requests.exceptions.MissingSchema: Invalid URL 'None': " which seems related to the empty href. - I tried to instantiate the object via 'href' instead of 'resource', and then
reload()
andget_all_vms()
works. The problem with this is that the Vdc object does not return 'href' for vapps, just names. - I just found that there is a vdc method
get_vapp_href()
which works. - now I am able to properly create the VApp object and the
get_all_vms()
function is properly working.
Here is my quick&dirty testing code which now works:
# Pyvcloud Examples
#
# Copyright (c) 2018 VMware, Inc. All Rights Reserved.
#
# This product is licensed to you under the
# Apache License, Version 2.0 (the "License").
# You may not use this product except in compliance with the License.
#
# This product may include a number of subcomponents with
# separate copyright notices and license terms. Your use of the source
# code for the these subcomponents is subject to the terms and
# conditions of the subcomponent's license, as noted in the LICENSE file.
#
# Illustrates how to list resources associated with org VDCs.
import sys
from pyvcloud.vcd.client import BasicLoginCredentials
from pyvcloud.vcd.client import Client
from pyvcloud.vcd.org import Org
from pyvcloud.vcd.vdc import VDC
from pyvcloud.vcd.vapp import VApp
from pyvcloud.vcd.vm import VM
import requests
host = "https://yourvcloud.tld"
user = "adminOrAnotherUser"
password = "yourPassword"
org = "system" # If you want to login as a cloud provider
# Disable warnings from self-signed certificates.
requests.packages.urllib3.disable_warnings()
# Login. SSL certificate verification is turned off to allow self-signed
# certificates. You should only do this in trusted environments.
print("Logging in: host={0}, org={1}, user={2}".format(host, org, user))
client = Client(host, verify_ssl_certs=False)
client.set_highest_supported_version()
client.set_credentials(BasicLoginCredentials(user, org, password))
orgs = client.get_org_list()
for org in orgs:
orgObject = Org(client, href=org.attrib["href"])
orgName = org.attrib["name"]
for vdc_info in orgObject.list_vdcs():
vdcName = vdc_info['name']
vdcHref = vdc_info['href']
vdc = VDC(client, href=vdcHref)
for resource in vdc.list_resources():
if resource["type"] == "application/vnd.vmware.vcloud.vApp+xml":
currentVappHref = vdc.get_vapp_href(resource["name"])
currentVapp = VApp(client, href=currentVappHref)
vmList = currentVapp.get_all_vms()
for vmElement in vmList:
vmName = vmElement.attrib["name"]
# vm = VM(client, resource=vmElement) # no needed in my case
print(f"{orgName=} {vdcName=} {vmName=}") # Python >= 3.8
# Log out.
print("Logging out")
client.logout()```
@RyanW8, get_all_vms()
returns a list of lxml.objectify.ObjectifiedElement
. You need to get inside the object to fetch values. Below is the pythonic way which I believe should work for you,
for vm in vapp.get_all_vms():
print(vm.get('name'))
As suggested by @mukultaneja , I'm able to get VMS ! Hence, the question can be closed