Python OpenStack SDK does not return Hypervisor hostname

Monty Taylor mordred at inaugust.com
Thu Jun 25 13:34:06 UTC 2020



> On Jun 23, 2020, at 6:46 PM, Sean Mooney <smooney at redhat.com> wrote:
> 
> On Wed, 2020-06-24 at 00:37 +0100, Sean Mooney wrote:
>> On Tue, 2020-06-23 at 13:12 -0700, Anil Jangam wrote:
>>> I have written a client code as follows.
>>> 
>>> # Get Hypervisor details
>>> try:
>>>    print(f"+----------------------------------------------------------+")
>>>    print(f"| Hypervisor details                                       |")
>>>    print(f"+----------------------------------------------------------+")
>>>    for hypervisor in conn.list_hypervisors():
>>>        print(f"Hypervisor is: {hypervisor}")
>>>        print(f"Hypervisor status:      {hypervisor.status}")
>>>        print(f"Hypervisor vcpus:       {hypervisor.vcpus_used}")
>>>        print(f"Hypervisor type:        {hypervisor.hypervisor_type}")
>>>        print(f"Hypervisor id:          {hypervisor.id}")
>>>        print(f"Hypervisor state:       {hypervisor.state}")
>>>        print(f"Hypervisor host IP:     {hypervisor.host_ip}")
>>>        print(f"Hypervisor running VMs: {hypervisor.running_vms}")
>>>        print(f"Hypervisor running VMs: {hypervisor.vcpus}")
>>>        print(f"Hypervisor hostname:    {hypervisor.hypervisor_hostname}")
>>> 
>>>        print(f"")
>>> except EndpointNotFound as exp:
>>>    print("Error: {}".format(exp))
>>>    print(f"")
>>> 
>>> When I print the 'hypervisor' object itself, most of the values are printed
>>> as shown below, however when I try to access
>>> 'hypervisor.hypervisor_hostname', it throws an exception.
>>> 
>>> +----------------------------------------------------------+
>>>> Hypervisor details                                       |
>>> 
>>> +----------------------------------------------------------+
>>> Hypervisor is: openstack.compute.v2.hypervisor.Hypervisor(status=enabled,
>>> service={'host': 'cl3-Compute3', 'disabled_reason': None, 'id':
>>> '34db399d-25b9-4004-98b9-2d8bbce7b228'}, vcpus_used=0,
>>> hypervisor_type=QEMU, local_gb_used=0, vcpus=52,
>>> hypervisor_hostname=cl3-Compute3, memory_mb_used=25600, memory_mb=262032,
>>> current_workload=0, state=up, host_ip=192.168.10.116, cpu_info={'arch':
>>> 'x86_64', 'model': 'Broadwell', 'vendor': 'Intel', 'features': ['pge',
>>> 'avx', 'xsaveopt', 'clflush', 'sep', 'rtm', 'tsc_adjust', 'tsc-deadline',
>>> 'dtes64', 'invpcid', 'tsc', 'fsgsbase', 'xsave', 'smap', 'vmx', 'erms',
>>> 'xtpr', 'cmov', 'hle', 'smep', 'pcid', 'est', 'pat', 'monitor', 'smx',
>>> 'pbe', 'lm', 'msr', 'adx', '3dnowprefetch', 'nx', 'fxsr', 'syscall', 'tm',
>>> 'sse4.1', 'pae', 'sse4.2', 'pclmuldq', 'acpi', 'fma', 'vme', 'popcnt',
>>> 'mmx', 'osxsave', 'cx8', 'mce', 'de', 'rdtscp', 'ht', 'dca', 'lahf_lm',
>>> 'abm', 'rdseed', 'pdcm', 'mca', 'pdpe1gb', 'apic', 'sse', 'f16c', 'pse',
>>> 'ds', 'invtsc', 'pni', 'tm2', 'avx2', 'aes', 'sse2', 'ss', 'ds_cpl',
>>> 'arat', 'bmi1', 'bmi2', 'ssse3', 'fpu', 'cx16', 'pse36', 'mtrr', 'movbe',
>>> 'rdrand', 'x2apic'], 'topology': {'cores': 14, 'cells': 2, 'threads': 2,
>>> 'sockets': 1}}, running_vms=0, free_disk_gb=852,
>>> hypervisor_version=2012000, disk_available_least=849, local_gb=852,
>>> free_ram_mb=236432, id=1130407d-5afd-41f9-bc0c-2d7babda3ce7,
>>> location=Munch({'cloud': 'defaults', 'region_name': 'RegionOne', 'zone':
>>> None, 'project': Munch({'id': '6d4f1b107bbf4b94832f7ef72df61ef2', 'name':
>>> '5g', 'domain_id': None, 'domain_name': 'default'})}))
>>> Hypervisor status: enabled
>>> Hypervisor vcpus: 0
>>> Hypervisor type:     QEMU
>>> Hypervisor id: 1130407d-5afd-41f9-bc0c-2d7babda3ce7
>>> Hypervisor state: up
>>> Hypervisor host IP: 192.168.10.116
>>> Hypervisor running VMs: 0
>>> Hypervisor running VMs: 52
>>> Traceback (most recent call last):
>>>  File "/Users/workspace/testprogs/python/opsviz/ops_worker.py", line 321,
>>> in <module>
>>>    main()
>>>  File "/Users/workspace/testprogs/python/opsviz/ops_worker.py", line 317,
>>> in main
>>>    print_servers()
>>>  File "/Users/workspace/testprogs/python/opsviz/ops_worker.py", line 115,
>>> in print_servers
>>>    print(f"Hypervisor hostname: {hypervisor.hypervisor_hostname}")
>>>  File
>>> "/Users/inventory/lib/python3.7/site-packages/openstack/resource.py", line
>>> 588, in __getattribute__
>>>    raise e
>>>  File
>>> "/Users/inventory/lib/python3.7/site-packages/openstack/resource.py", line
>>> 582, in __getattribute__
>>>    return object.__getattribute__(self, name)
>>> AttributeError: 'Hypervisor' object has no attribute 'hypervisor_hostname'
>>> 
>>> Is there anything wrong with the use of the API? How do I get the
>>> hypervisor hostname in my application code?
>> 
>> looking at the fields that are in the hypervior object you are not hitting the /os-hypervisors
>> list hyperviors endpoint but are instead hittig the /os-hypervisors/detail endpoint which inluded extra info
>> both shoudl contain hypervisor_hostname
>> https://docs.openstack.org/api-ref/compute/?expanded=list-hypervisors-details-detail
>> is the doc for that api.
>> 
>> by default this is an admin only api.
>> sean at pop-os:~$ openstack --os-cloud sean hypervisor list
>> Policy doesn't allow os_compute_api:os-hypervisors:list-detail to be performed. (HTTP 403) (Request-ID: req-fbc50741-
>> 5a73-4329-a00e-11eef79011ac)
>> 
>> so the fact that you are geting any results indicates that you are using admin creditals so you should recive the full
>> responce and looking at the raw hypervisor print output i has the info so i would guess that its jut missing a
>> property.
>> 
>> looking at https://github.com/openstack/openstacksdk/blob/master/openstack/compute/v2/hypervisor.py#L39
>> it would appear that hypervisor_hostname is being stored in the name property.
>> 
>> im not sure why some of the fields where renamed
>> https://github.com/openstack/openstacksdk/blob/master/openstack/compute/v2/hypervisor.py#L52-L57
>> that feels like a poor desigin choice as it basically means the upstream api docs are not enough to use the sdk
>> you need to girue out what then mapped the fields too.
>> 
>> the object also obviously contains the raw values too or they would not print when you print the object.
>> 
>> that is because that is falling back to the base resouce __repr__ function 
>> 
> https://github.com/openstack/openstacksdk/blob/8b5d4fe7985d3f9319b23121e290ef96dc801863/openstack/resource.py#L540-L552
>> which prints the raw values.
>> 
>> at least i think that is what happening i have not looked at the sdk closely before.
> it looks like it was renamed in patchest 2 of https://review.opendev.org/#/c/298900/2/openstack/compute/v2/hypervisor.py
> and there is no discussion of why any of the new names were chosen in the proxy object and the api break was not called
> out in the commit or a release note but since this was done 4 years ago im guessing it was before the sdk was considerd
> stable or had reached its 1.0 so it was prably overlooked.

It predates me for sure.

I know in general the sdk api for resources is that things should have an id and a name and where some resources have decided to call their id field something different they get coerced because it’s super confusing to users to have to know that ‘id’ is called something else in some resources. This was probably done with that in mind.

That said - I also agree about it being confusing the other direction. We have a capability for aliasing fields in SDK that should be usable here. We’re using it on heat stacks, for instance, to allow sdk users to use id and name but still have stack_id and stack_name work.

I’ll get up a patch in just a sec.

> 
> im not sure  if ths is something that can be fix and how widespread the problemn is but really the upstream names from
> the api responce should also work IMO and this seams like an sdk bug to me.
>> 
>> 
>> 
>>> 
>>> Thank you.




More information about the openstack-discuss mailing list