vmware_host_datastore: ability to target a ESXi

Until now, the module was only able to interact with vcenter. This
commit adds the ability to directly target an ESXi without the
`esxi_hostname` parameter.
This commit is contained in:
Gonéri Le Bouder 2019-05-15 17:18:29 -04:00
parent fc94d79c47
commit 8cee127ee4
4 changed files with 112 additions and 18 deletions

View file

@ -0,0 +1,2 @@
minor_changes:
- vmware_host_datastore - Ability to directly target a ESXi.

View file

@ -27,7 +27,7 @@ author:
- Ludovic Rivallain (@lrivallain) <ludovic.rivallain@gmail.com>
- Christian Kotte (@ckotte) <christian.kotte@gmx.de>
notes:
- Tested on vSphere 6.0 and 6.5
- Tested on vSphere 6.0, 6.5 and ESXi 6.7
- NFS v4.1 tested on vSphere 6.5
- Kerberos authentication with NFS v4.1 isn't implemented
requirements:
@ -75,7 +75,8 @@ options:
esxi_hostname:
description:
- ESXi hostname to manage the datastore.
required: true
- Required when used with a vcenter
required: false
state:
description:
- "present: Mount datastore on host if datastore is absent else do nothing."
@ -133,13 +134,12 @@ EXAMPLES = r'''
- { 'name': 'NasDS_vol03', 'server': 'nas01,nas02', 'path': '/mnt/vol01', 'type': 'nfs41'}
- { 'name': 'NasDS_vol04', 'server': 'nas01,nas02', 'path': '/mnt/vol02', 'type': 'nfs41'}
- name: Remove/Umount Datastores from ESXi
- name: Remove/Umount Datastores from a ESXi
vmware_host_datastore:
hostname: '{{ vcenter_hostname }}'
username: '{{ vcenter_username }}'
password: '{{ vcenter_password }}'
hostname: '{{ esxi_hostname }}'
username: '{{ esxi_username }}'
password: '{{ esxi_password }}'
datastore_name: NasDS_vol01
esxi_hostname: '{{ inventory_hostname }}'
state: absent
delegate_to: localhost
'''
@ -153,7 +153,7 @@ except ImportError:
pass
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.vmware import vmware_argument_spec, PyVmomi, find_datastore_by_name
from ansible.module_utils.vmware import vmware_argument_spec, PyVmomi, find_datastore_by_name, find_obj
from ansible.module_utils._text import to_native
@ -173,9 +173,14 @@ class VMwareHostDatastore(PyVmomi):
self.esxi_hostname = module.params['esxi_hostname']
self.state = module.params['state']
self.esxi = self.find_hostsystem_by_name(self.esxi_hostname)
if self.esxi is None:
self.module.fail_json(msg="Failed to find ESXi hostname %s " % self.esxi_hostname)
if self.is_vcenter():
if not self.esxi_hostname:
self.module.fail_json(msg="esxi_hostname is mandatory with a vcenter")
self.esxi = self.find_hostsystem_by_name(self.esxi_hostname)
if self.esxi is None:
self.module.fail_json(msg="Failed to find ESXi hostname %s" % self.esxi_hostname)
else:
self.esxi = find_obj(self.content, [vim.HostSystem], None)
def process_state(self):
ds_states = {
@ -220,14 +225,14 @@ class VMwareHostDatastore(PyVmomi):
if not ds:
self.module.fail_json(msg="No datastore found with name %s" % self.datastore_name)
if self.module.check_mode is False:
error_message_umount = "Cannot umount datastore %s from host %s" % (self.datastore_name, self.esxi_hostname)
error_message_umount = "Cannot umount datastore %s from host %s" % (self.datastore_name, self.esxi.name)
try:
self.esxi.configManager.datastoreSystem.RemoveDatastore(ds)
except (vim.fault.NotFound, vim.fault.HostConfigFault, vim.fault.ResourceInUse) as fault:
self.module.fail_json(msg="%s: %s" % (error_message_umount, to_native(fault.msg)))
except Exception as e:
self.module.fail_json(msg="%s: %s" % (error_message_umount, to_native(e)))
self.module.exit_json(changed=True, result="Datastore %s on host %s" % (self.datastore_name, self.esxi_hostname))
self.module.exit_json(changed=True, result="Datastore %s on host %s" % (self.datastore_name, self.esxi.name))
def mount_datastore_host(self):
if self.datastore_type == 'nfs' or self.datastore_type == 'nfs41':
@ -254,7 +259,7 @@ class VMwareHostDatastore(PyVmomi):
mnt_specs.accessMode = "readOnly"
else:
mnt_specs.accessMode = "readWrite"
error_message_mount = "Cannot mount datastore %s on host %s" % (self.datastore_name, self.esxi_hostname)
error_message_mount = "Cannot mount datastore %s on host %s" % (self.datastore_name, self.esxi.name)
try:
ds = self.esxi.configManager.datastoreSystem.CreateNasDatastore(mnt_specs)
if not ds:
@ -266,7 +271,7 @@ class VMwareHostDatastore(PyVmomi):
self.module.fail_json(msg="%s: %s" % (error_message_mount, to_native(fault.msg)))
except Exception as e:
self.module.fail_json(msg="%s : %s" % (error_message_mount, to_native(e)))
self.module.exit_json(changed=True, result="Datastore %s on host %s" % (self.datastore_name, self.esxi_hostname))
self.module.exit_json(changed=True, result="Datastore %s on host %s" % (self.datastore_name, self.esxi.name))
def mount_vmfs_datastore_host(self):
if self.module.check_mode is False:
@ -276,7 +281,7 @@ class VMwareHostDatastore(PyVmomi):
if self.vmfs_device_name in self.get_used_disks_names():
error_message_used_disk = "VMFS disk %s already in use" % self.vmfs_device_name
self.module.fail_json(msg="%s" % error_message_used_disk)
error_message_mount = "Cannot mount datastore %s on host %s" % (self.datastore_name, self.esxi_hostname)
error_message_mount = "Cannot mount datastore %s on host %s" % (self.datastore_name, self.esxi.name)
try:
vmfs_ds_options = ds_system.QueryVmfsDatastoreCreateOptions(host_ds_system,
ds_path,
@ -289,7 +294,7 @@ class VMwareHostDatastore(PyVmomi):
self.module.fail_json(msg="%s : %s" % (error_message_mount, to_native(fault.msg)))
except Exception as e:
self.module.fail_json(msg="%s : %s" % (error_message_mount, to_native(e)))
self.module.exit_json(changed=True, result="Datastore %s on host %s" % (self.datastore_name, self.esxi_hostname))
self.module.exit_json(changed=True, result="Datastore %s on host %s" % (self.datastore_name, self.esxi.name))
def main():
@ -303,7 +308,7 @@ def main():
nfs_ro=dict(type='bool', default=False),
vmfs_device_name=dict(type='str'),
vmfs_version=dict(type='int'),
esxi_hostname=dict(type='str', required=True),
esxi_hostname=dict(type='str', required=False),
state=dict(type='str', default='present', choices=['absent', 'present'])
)

View file

@ -0,0 +1,3 @@
cloud/vcenter
shippable/vcenter/group1
needs/target/prepare_vmware_tests

View file

@ -0,0 +1,84 @@
- when: vcsim is not defined
block:
- import_role:
name: prepare_vmware_tests
vars:
setup_attach_host: true
- name: Mount NFS (ds1) datastores without esxi_hostname
vmware_host_datastore:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
datastore_name: '{{ ds1 }}'
datastore_type: '{{ infra.datastores[ds1].type }}'
nfs_server: '{{ infra.datastores[ds1].server }}'
nfs_path: '{{ infra.datastores[ds1].path }}'
nfs_ro: '{{ infra.datastores[ds2].ro }}'
state: present
validate_certs: no
ignore_errors: true
register: mount_vmware_host_datastore
- debug: var=mount_vmware_host_datastore
- assert:
that:
- mount_vmware_host_datastore is failed
- mount_vmware_host_datastore.msg == "esxi_hostname is mandatory with a vcenter"
- name: Mount NFS (ds1) datastores with non existing host in esxi_hostname
vmware_host_datastore:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
esxi_hostname: 'nohost'
datastore_name: '{{ ds1 }}'
datastore_type: '{{ infra.datastores[ds1].type }}'
nfs_server: '{{ infra.datastores[ds1].server }}'
nfs_path: '{{ infra.datastores[ds1].path }}'
nfs_ro: '{{ infra.datastores[ds2].ro }}'
state: present
validate_certs: no
ignore_errors: true
register: mount_vmware_host_datastore
- debug: var=mount_vmware_host_datastore
- assert:
that:
- mount_vmware_host_datastore is failed
- mount_vmware_host_datastore.msg == "Failed to find ESXi hostname nohost"
- name: Mount NFS (ds1) datastores on esxi1 using esxi_hostname
vmware_host_datastore:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
esxi_hostname: '{{ esxi1 }}'
datastore_name: '{{ ds1 }}'
datastore_type: '{{ infra.datastores[ds1].type }}'
nfs_server: '{{ infra.datastores[ds1].server }}'
nfs_path: '{{ infra.datastores[ds1].path }}'
nfs_ro: '{{ infra.datastores[ds2].ro }}'
state: present
validate_certs: no
register: mount_vmware_host_datastore
- debug: var=mount_vmware_host_datastore
- assert:
that:
- mount_vmware_host_datastore is changed
- name: Mount NFS (ds1) datastores to ESXi directly
vmware_host_datastore:
hostname: '{{ esxi1 }}'
username: '{{ esxi_user }}'
password: '{{ esxi_password }}'
datastore_name: '{{ ds1 }}'
datastore_type: '{{ infra.datastores[ds1].type }}'
nfs_server: '{{ infra.datastores[ds1].server }}'
nfs_path: '{{ infra.datastores[ds1].path }}'
nfs_ro: '{{ infra.datastores[ds2].ro }}'
state: present
validate_certs: no
register: mount_vmware_host_datastore
- debug: var=mount_vmware_host_datastore
- assert:
that:
- not (mount_vmware_host_datastore is changed)