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:
parent
fc94d79c47
commit
8cee127ee4
4 changed files with 112 additions and 18 deletions
2
changelogs/fragments/vmware_host_datastore_for_esxi.yaml
Normal file
2
changelogs/fragments/vmware_host_datastore_for_esxi.yaml
Normal file
|
@ -0,0 +1,2 @@
|
|||
minor_changes:
|
||||
- vmware_host_datastore - Ability to directly target a ESXi.
|
|
@ -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'])
|
||||
)
|
||||
|
||||
|
|
3
test/integration/targets/vmware_host_datastore/aliases
Normal file
3
test/integration/targets/vmware_host_datastore/aliases
Normal file
|
@ -0,0 +1,3 @@
|
|||
cloud/vcenter
|
||||
shippable/vcenter/group1
|
||||
needs/target/prepare_vmware_tests
|
|
@ -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)
|
Loading…
Reference in a new issue