| Server IP : 85.214.239.14 / Your IP : 216.73.216.27 Web Server : Apache/2.4.65 (Debian) System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Mon Sep 30 15:36:27 MSK 2024 x86_64 User : www-data ( 33) PHP Version : 8.2.29 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /lib/python3/dist-packages/ansible_collections/community/vmware/plugins/modules/ |
Upload File : |
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: (c) 2021, Ansible Project
# Copyright: (c) 2021, VMware, Inc. All Rights Reserved.
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = r'''
---
module: vmware_guest_tpm
short_description: Add or remove vTPM device for specified VM.
description: >
This module is used for adding or removing Virtual Trusted Platform Module(vTPM) device for an existing
Virtual Machine. You must create a key provider on vCenter before you can add a vTPM. The ESXi hosts
running in your environment must be ESXi 6.7 or later (Windows guest OS), or 7.0 Update 2 (Linux guest OS).
author:
- Diane Wang (@Tomorrow9) <dianew@vmware.com>
options:
name:
description:
- Name of the virtual machine.
- This is required if parameter C(uuid) or C(moid) is not supplied.
type: str
uuid:
description:
- UUID of the instance to manage if known, this is VMware's unique identifier.
- This is required if parameter C(name) or C(moid) is not supplied.
type: str
moid:
description:
- Managed Object ID of the instance to manage if known, this is a unique identifier only within a single vCenter instance.
- This is required if C(name) or C(uuid) is not supplied.
type: str
folder:
description:
- VM folder, absolute or relative path to find an existing VM.
- This parameter is not required, only when multiple VMs are found with the same name.
- The folder should include the datacenter name.
- 'Examples:'
- ' folder: /datacenter1/vm'
- ' folder: datacenter1/vm'
- ' folder: /datacenter1/vm/folder1'
- ' folder: datacenter1/vm/folder1'
- ' folder: /folder1/datacenter1/vm'
- ' folder: folder1/datacenter1/vm'
- ' folder: /folder1/datacenter1/vm/folder2'
type: str
datacenter:
description:
- The vCenter datacenter name used to get specified cluster or host.
- This parameter is case sensitive.
type: str
required: true
state:
description:
- State of vTPM device.
- If set to 'absent', vTPM device will be removed from VM.
- If set to 'present', vTPM device will be added if not present.
- Virtual machine should be turned off before add or remove vTPM device.
- Virtual machine should not contain snapshots before add vTPM device.
type: str
choices: ['present', 'absent']
default: 'present'
extends_documentation_fragment:
- community.vmware.vmware.documentation
'''
EXAMPLES = r'''
- name: Add vTPM to specified VM
community.vmware.vmware_guest_tpm:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
datacenter: "{{ datacenter }}"
name: "Test_VM"
state: present
delegate_to: localhost
- name: Remove vTPM from specified VM
community.vmware.vmware_guest_tpm:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
datacenter: "{{ datacenter }}"
name: "Test_VM"
state: absent
delegate_to: localhost
'''
RETURN = r'''
instance:
description: metadata about the VM vTPM device
returned: always
type: dict
sample: None
'''
HAS_PYVMOMI = False
try:
from pyVmomi import vim
HAS_PYVMOMI = True
except ImportError:
pass
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils._text import to_native
from ansible_collections.community.vmware.plugins.module_utils.vmware import vmware_argument_spec, PyVmomi, wait_for_task
from ansible_collections.community.vmware.plugins.module_utils.vm_device_helper import PyVmomiDeviceHelper
class PyVmomiHelper(PyVmomi):
def __init__(self, module):
super(PyVmomiHelper, self).__init__(module)
self.device_helper = PyVmomiDeviceHelper(self.module)
self.config_spec = vim.vm.ConfigSpec()
self.config_spec.deviceChange = []
self.vm = None
self.vtpm_device = None
def get_vtpm_info(self, vm_obj=None, vtpm_device=None):
vtpm_info = dict()
if vm_obj:
for device in vm_obj.config.hardware.device:
if self.device_helper.is_tpm_device(device):
vtpm_device = device
if vtpm_device:
vtpm_info = dict(
key=vtpm_device.key,
label=vtpm_device.deviceInfo.label,
summary=vtpm_device.deviceInfo.summary,
)
return vtpm_info
def vtpm_operation(self, vm_obj=None):
results = {'failed': False, 'changed': False}
if not self.is_vcenter():
self.module.fail_json(msg="Please connect to vCenter Server to configure vTPM device of virtual machine.")
self.vm = vm_obj
if self.vm.runtime.powerState != vim.VirtualMachinePowerState.poweredOff:
self.module.fail_json(msg="Please make sure VM is powered off before configuring vTPM device,"
" current state is '%s'" % self.vm.runtime.powerState)
for device in self.vm.config.hardware.device:
if self.device_helper.is_tpm_device(device):
self.vtpm_device = device
if self.module.params['state'] == 'present':
if self.module.check_mode:
results['desired_operation'] = "add vTPM"
else:
results['vtpm_operation'] = "add vTPM"
if self.vtpm_device:
results['vtpm_info'] = self.get_vtpm_info(vtpm_device=self.vtpm_device)
results['msg'] = "vTPM device already exist on VM"
self.module.exit_json(**results)
else:
if self.module.check_mode:
results['changed'] = True
self.module.exit_json(**results)
vtpm_device_spec = self.device_helper.create_tpm()
if self.module.params['state'] == 'absent':
if self.module.check_mode:
results['desired_operation'] = "remove vTPM"
else:
results['vtpm_operation'] = "remove vTPM"
if self.vtpm_device is None:
results['msg'] = "No vTPM device found on VM"
self.module.exit_json(**results)
else:
if self.module.check_mode:
results['changed'] = True
self.module.exit_json(**results)
vtpm_device_spec = self.device_helper.remove_tpm(self.vtpm_device)
self.config_spec.deviceChange.append(vtpm_device_spec)
try:
task = self.vm.ReconfigVM_Task(spec=self.config_spec)
wait_for_task(task)
except Exception as e:
self.module.fail_json(msg="Failed to configure vTPM device on virtual machine due to '%s'" % to_native(e))
if task.info.state == 'error':
self.module.fail_json(msg='Failed to reconfigure VM with vTPM device', detail=task.info.error.msg)
results['changed'] = True
results['vtpm_info'] = self.get_vtpm_info(vm_obj=self.vm)
self.module.exit_json(**results)
def main():
argument_spec = vmware_argument_spec()
argument_spec.update(
name=dict(type='str'),
uuid=dict(type='str'),
moid=dict(type='str'),
folder=dict(type='str'),
datacenter=dict(type='str', required=True),
state=dict(type='str', default='present', choices=['present', 'absent']),
)
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
required_one_of=[['name', 'uuid', 'moid']],
)
if module.params['folder']:
# FindByInventoryPath() does not require an absolute path
# so we should leave the input folder path unmodified
module.params['folder'] = module.params['folder'].rstrip('/')
vm_config_vtpm = PyVmomiHelper(module)
vm = vm_config_vtpm.get_vm()
if not vm:
vm_id = (module.params.get('name') or module.params.get('uuid') or module.params.get('moid'))
module.fail_json(msg="Unable to configure vTPM device for non-existing virtual machine '%s'." % vm_id)
try:
vm_config_vtpm.vtpm_operation(vm_obj=vm)
except Exception as e:
module.fail_json(msg="Failed to configure vTPM device of virtual machine '%s' with exception : %s"
% (vm.name, to_native(e)))
if __name__ == "__main__":
main()