Bug 2024931 - Fencing agent fence_vmware_rest is unable to handle names with VIO UUID's included
Summary: Fencing agent fence_vmware_rest is unable to handle names with VIO UUID's inc...
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Red Hat Enterprise Linux 8
Classification: Red Hat
Component: fence-agents
Version: 8.6
Hardware: All
OS: Linux
unspecified
low
Target Milestone: rc
: ---
Assignee: Oyvind Albrigtsen
QA Contact: cluster-qe@redhat.com
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2021-11-19 14:47 UTC by ttuffin
Modified: 2023-06-28 12:58 UTC (History)
5 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2022-02-28 08:36:09 UTC
Type: Bug
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Red Hat Issue Tracker KCSOPP-1862 0 None None None 2022-05-31 17:43:43 UTC
Red Hat Issue Tracker RHELPLAN-103292 0 None None None 2021-11-19 14:48:15 UTC
Red Hat Knowledge Base (Solution) 3510461 0 None None None 2021-11-22 18:32:26 UTC
Red Hat Knowledge Base (Solution) 7021810 0 None None None 2023-06-28 12:58:46 UTC

Description ttuffin 2021-11-19 14:47:08 UTC
Description of problem:
In a VMWare vSphere environment with VMware Integrated OpenStack (VIO), VM's that are managed by VIO have names in the following format: "<VM short name> (VIO UUID)". This means that when using the 'fence_vmware_rest' fencing agent hostnames are reported back with the VIO UUID included, for example: "host01 (f3285ba4-6246-4284-bbd8-5964c2564518),(<vSphere UUID>)". The inclusion of the VIO UUID appears to cause the agent to fail with "ERROR: Failed: Unable to obtain correct plug status or plug is not available" when specifying the VM hostname/short name. 

The 'fence_vmware_soap' agent does work when specify the vSphere UUID, but this is not an option in environments where SOAP is not available or not allowed. 

Version-Release number of selected component (if applicable):
fence-agents-vmware-rest-4.2.1-41.el7_9.3.x86_64

How reproducible:
Always

Steps to Reproduce:
# fence_vmware_rest -a 'host01.example.com' -l 'svc_abcde' -p 'PASSWORD' --ipport=443 -o status --shell-timeout=30 --plug=fencinghost01.example.com
2020-11-09 17:08:23,965 ERROR: Failed: Unable to obtain correct plug status or plug is not available

Actual results:
'fence_vmware_rest' agent fails when VIO UUID is included in the vSphere VM name.

Expected results:
'fence_vmware_rest' agent handles the VIO UUID by stripping it and using the VM hostname/short name.

Comment 3 Reid Wahl 2021-12-02 10:36:50 UTC
I read over some of the REST API docs today and checked the API responses from the BRQ vCenter to see what we do and don't get. It's frustrating to say the least. The list outputs don't display the VM UUID in any form (which we've already established in another BZ). Running a GET on a particular VM also doesn't seem to give us the UUID.

Another really bad limitation: The filterspec in `vcenter/vm?filter` calls doesn't appear to allow wildcards. You have to specify a list of exactly whatever term you want to match.


Here is the best workaround I've come up with. Every VM seems to have a unique ID, which is the value of the 'vm' key of the response dict. In the following example, the ID is vm-1038.

{'value': [{'memory_size_MiB': 16384, 'vm': 'vm-1038', 'name': 'ocp4-hl8r8-master-1', 'power_state': 'POWERED_OFF', 'cpu_count': 4}]}


We could make a small modification to the fence agent to allow users to pass VM IDs rather than names. We could choose the lookup type in one of at least two ways:
  1. Create a new boolean option that says the plug is a VM ID instead of a VM name. This keeps the number of API calls in the fence agent the same. We would build our API call based on whether the "plug_is_id" option is set or not. (Pick a different option name.)
  2. Try to look up a plug as a VM ID first and then fall back to looking up the plug as a name if that fails. This requires a tad less work on the user's part but potentially doubles the amount of work on the fence agent's part.

I'd prefer option #1 unless you all think of a better approach or find an API mechanism that I didn't find.

Something like this (rough draft, seems to work fine):
~~~
def get_power_status(conn, options):
    if options["--plug_is_id"]:
        options["id"] = options["--plug"]

        try:
            res = send_command(conn, "vcenter/vm/{}".format(urllib.quote(options["--plug"])))["value"]["power_state"]
        except Exception as e:
            logging.debug("Failed: {}".format(e))
            fail(EC_STATUS)

        result = res

    else:
        try:
            res = send_command(conn, "vcenter/vm?filter.names={}".format(urllib.quote(options["--plug"])))["value"]
        except Exception as e:
            logging.debug("Failed: {}".format(e))
            fail(EC_STATUS)

        if len(res) == 0:
            fail(EC_STATUS)

        options["id"] = res[0]["vm"]

        result = res[0]["power_state"]

    return state[result]
~~~

Comment 4 Reid Wahl 2021-12-02 10:53:56 UTC
Ah, looks like all we have to do is quote the VM name that's of the format `<vm_name> (<vm_uuid>)`. Oyvind will have details. I had a mistake in my command line when I tried that simple approach.

Thanks, all.


Note You need to log in before you can comment on or make changes to this bug.