ansible-collections / community.vmware

Ansible Collection for VMware
GNU General Public License v3.0
346 stars 334 forks source link

Some advanced system settings are missing and non-configurable with the module #2105

Open zaiguiw opened 2 months ago

zaiguiw commented 2 months ago
SUMMARY

Some advanced system settings are missing from the VMware host configure manager ansible module. For example, when I try to set the value of "/VSAN/IgnoreClusterMemberListUpdates" with this ansible task, I get a fatal error saying "Unsupported option VSAN.IgnoreClusterMemberListUpdates"

  - name: set esxi configuration
    community.vmware.vmware_host_config_manager:
      hostname: '{{ vc }}'
      username: '{{ user }}'
      password: '{{ password }}'
      esxi_hostname: '{{ inventory_hostname }}'
      validate_certs: false
      options:
          'VSAN.IgnoreClusterMemberListUpdates': 0 
    delegate_to: localhost
ISSUE TYPE
COMPONENT NAME
ANSIBLE VERSION
COLLECTION VERSION
CONFIGURATION
OS / ENVIRONMENT

~] vmware -lv VMware ESXi 8.0.2 build-22380479

Here is to show the settings is there and can be set: ~] esxcli system settings advanced set -o /VSAN/IgnoreClusterMemberListUpdates -i 1 :~] esxcli system settings advanced list -o /VSAN/IgnoreClusterMemberListUpdates Path: /VSAN/IgnoreClusterMemberListUpdates Type: integer Int Value: 1 Default Int Value: 0 Min Value: 0 Max Value: 1 String Value: Default String Value: Valid Characters: Description: Host will ignore cluster membership list updates Host Specific: false Impact: none ~] esxcli system settings advanced set -o /VSAN/IgnoreClusterMemberListUpdates -i 0 ~]

STEPS TO REPRODUCE

See the ansible code above.

EXPECTED RESULTS
ACTUAL RESULTS
ihumster commented 2 months ago

Please give an example of an error.

zaiguiw commented 2 months ago

Thanks for looking into this. Here you go:

ansible-playbook manage-esxi-config.yml --ask-vault-pass -i esxi-host, -t set

Vault password:

PLAY [all] ****

TASK [set esxi configuration] ** fatal: [esxi-host -> localhost]: FAILED! => changed=false msg: Unsupported option VSAN.IgnoreClusterMemberListUpdates

PLAY RECAP ***** esxi-host : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0

cat manage-esxi-config.yml


ihumster commented 2 months ago

Run your playbook with -vvv and get full error log.

mariolenz commented 2 months ago

The module doesn't have a list of supported advanced settings, it tries to find out what advanced settings are supported:

https://github.com/ansible-collections/community.vmware/blob/f9854125b4d6bd4c4c2579eeefdc2e35ff95a579/plugins/modules/vmware_host_config_manager.py#L105-L141

I'm not sure if we have a bug in the module or if there's a bug in the vSphere API (that is not specifying VSAN.IgnoreClusterMemberListUpdates as a supported option in OptionManager).

I'm afraid I don't have to test with with 8.0 U2 at the moment :-/

mariolenz commented 2 months ago

This is weird. VSAN.IgnoreClusterMemberListUpdates is documented (here and in other places) but OptionManager doesn't list it as a supportedOption. At least not in 7.0 U3. I don't have a test environment running 8.0+ ATM where I could have a look.

Maybe a bug in the vSphere API?

zaiguiw commented 2 months ago

My understanding is that this might be a "hidden" option. Hidden options don't show up when listed, but can still be manipulated when targeted.

mariolenz commented 2 months ago

I don't think it's a good idea to support any "hidden" options, sounds like an accident waiting to happen. 1) The name might change anytime and 2) we can't find out the type (integer, boolean, string...) automatically.

Do you have a support contract with ~VMware~ Broadcom that allows you to address this? If it's a supported option their API should tell us. "Hidden" options suck...

zaiguiw commented 2 months ago

I am trying to replicate this issue with pvmomi. Will update once I have some clarification.

zaiguiw commented 2 months ago

pyvmomi works fine for me. The key is that when querying the advanced setting, you'll need to target that particular setting, instead of getting a list and iterate through. That is, instead of using QueryOptions() and iterate

use QueryOptions(option_key)

Here is a sample code to demo this:

#!/usr/bin/python3

from pyVim.connect import SmartConnect, Disconnect
from pyVmomi import vim, vmodl, VmomiSupport
import ssl, atexit, time, argparse, getpass

def get_args():
    parser = argparse.ArgumentParser(description='VC inventory search by type. Arguments for talking to vCenter')
    parser.add_argument('-s', '--server', required=True, action='store', help='VC to onnect to')
    parser.add_argument('--host', required=True, action='store', help='hostname of ESXi')
    parser.add_argument('-u', '--user', required=True, action='store', help='User name')
    parser.add_argument('-p', '--password', required=False, action='store', help='user password')
    parser.add_argument('-k', '--key', required=True, action='store', help='Setting key')
    parser.add_argument('-v', '--value', required=True, action='store', help='Setting value')
    args = parser.parse_args()
    return args

def connect():
    context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
    context.verify_mode = ssl.CERT_NONE

    si = SmartConnect(host=args.server, user=args.user, pwd=args.password, port=443, sslContext=context)
    atexit.register(Disconnect, si)
    content = si.RetrieveContent()
    return content

def get_obj(content, vimtype, name):
    """
    Return an object by name, if name is None the
    first found object is returned
    """
    obj = None
    if name in ['', None]:
        obj = []
    container = content.viewManager.CreateContainerView(content.rootFolder, vimtype, True)
    for c in container.view:
        if name:
            if c.name == name:
                obj = c
                break
        else:
            obj.append(c)

    container.Destroy()
    return obj

####
args = get_args()
if not args.password:       
    args.password = getpass.getpass( prompt='Password for %s (%s): ' % (args.user, args.server))

content = connect()
host = get_obj(content, [vim.HostSystem], args.host)
option_manager = host.configManager.advancedOption
option = vim.option.OptionValue(key=args.key, value=VmomiSupport.vmodlTypes['int'](args.value))
option_manager.UpdateOptions(changedValue=[option])
#
print (option_manager.QueryOptions(args.key)[0].value)
zaiguiw commented 2 months ago

and a sample execution:

# ./set-adv-setting.py -s test_vcenter --host test_host -u user -k VSAN.IgnoreClusterMemberListUpdates -v 0
Password for user (test_vcenter): 
0