VMware: Refactor vmware_target_canonical_facts (#36964)
Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
This commit is contained in:
parent
e0945900df
commit
d1eb4fe58c
4 changed files with 235 additions and 45 deletions
|
@ -15,6 +15,8 @@ See [Porting Guide](http://docs.ansible.com/ansible/devel/porting_guides/porting
|
|||
|
||||
### Minor Changes
|
||||
|
||||
* Ansible 2.6 and onwards, `target_id` parameter in `vmware_target_canonical_facts` module is an optional parameter.
|
||||
|
||||
#### Removed modules (previously deprecated)
|
||||
|
||||
### New Modules
|
||||
|
|
|
@ -1,90 +1,185 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright: (c) 2015, Joseph Callen <jcallen () csc.com>
|
||||
# Copyright: (c) 2018, Ansible Project
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'}
|
||||
ANSIBLE_METADATA = {
|
||||
'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'
|
||||
}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: vmware_target_canonical_facts
|
||||
short_description: Return canonical (NAA) from an ESXi host
|
||||
short_description: Return canonical (NAA) from an ESXi host system
|
||||
description:
|
||||
- Return canonical (NAA) from an ESXi host based on SCSI target ID
|
||||
- This module can be used to gather facts about canonical (NAA) from an ESXi host based on SCSI target ID.
|
||||
|
||||
version_added: "2.0"
|
||||
author:
|
||||
- Joseph Callen (@jcpowermac)
|
||||
- Abhijeet Kasurde (@akasurde)
|
||||
notes:
|
||||
requirements:
|
||||
- Tested on vSphere 5.5
|
||||
- Tested on vSphere 5.5 and 6.5
|
||||
- PyVmomi installed
|
||||
options:
|
||||
target_id:
|
||||
description:
|
||||
- The target id based on order of scsi device
|
||||
required: True
|
||||
target_id:
|
||||
description:
|
||||
- The target id based on order of scsi device.
|
||||
- version 2.6 onwards, this parameter is optional.
|
||||
required: False
|
||||
cluster_name:
|
||||
description:
|
||||
- Name of the cluster.
|
||||
- Facts about all SCSI devices for all host system in the given cluster is returned.
|
||||
- This parameter is required, if C(esxi_hostname) is not provided.
|
||||
version_added: 2.6
|
||||
esxi_hostname:
|
||||
description:
|
||||
- Name of the ESXi host system.
|
||||
- Facts about all SCSI devices for the given ESXi host system is returned.
|
||||
- This parameter is required, if C(cluster_name) is not provided.
|
||||
version_added: 2.6
|
||||
extends_documentation_fragment: vmware.documentation
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Example vmware_target_canonical_facts command from Ansible Playbooks
|
||||
- name: Get Canonical name
|
||||
- name: Get Canonical name of particular target on particular ESXi host system
|
||||
local_action:
|
||||
module: vmware_target_canonical_facts
|
||||
hostname: "{{ ansible_ssh_host }}"
|
||||
username: root
|
||||
password: vmware
|
||||
hostname: vcenter_hostname
|
||||
username: vcenter_user
|
||||
password: vcenter_pass
|
||||
target_id: 7
|
||||
esxi_hostname: esxi_hostname
|
||||
|
||||
- name: Get Canonical name of all target on particular ESXi host system
|
||||
local_action:
|
||||
module: vmware_target_canonical_facts
|
||||
hostname: vcenter_hostname
|
||||
username: vcenter_user
|
||||
password: vcenter_pass
|
||||
esxi_hostname: esxi_hostname
|
||||
|
||||
- name: Get Canonical name of all ESXi hostname on particular Cluster
|
||||
local_action:
|
||||
module: vmware_target_canonical_facts
|
||||
hostname: vcenter_hostname
|
||||
username: vcenter_user
|
||||
password: vcenter_pass
|
||||
cluster_name: cluster_name
|
||||
'''
|
||||
|
||||
RETURN = r"""
|
||||
canonical:
|
||||
description: metadata about SCSI Target device
|
||||
returned: if host system and target id is given
|
||||
type: str
|
||||
sample: "mpx.vmhba0:C0:T0:L0"
|
||||
|
||||
scsi_tgt_facts:
|
||||
description: metadata about all SCSI Target devices
|
||||
returned: if host system or cluster is given
|
||||
type: dict
|
||||
sample: {
|
||||
"DC0_C0_H0": {
|
||||
"scsilun_canonical": {
|
||||
"key-vim.host.ScsiDisk-0000000000766d686261303a303a30": "mpx.vmhba0:C0:T0:L0",
|
||||
"key-vim.host.ScsiLun-0005000000766d686261313a303a30": "mpx.vmhba1:C0:T0:L0"
|
||||
},
|
||||
"target_lun_uuid": {
|
||||
"0": "key-vim.host.ScsiDisk-0000000000766d686261303a303a30"
|
||||
}
|
||||
},
|
||||
"DC0_C0_H1": {
|
||||
"scsilun_canonical": {
|
||||
"key-vim.host.ScsiDisk-0000000000766d686261303a303a30": "mpx.vmhba0:C0:T0:L0",
|
||||
"key-vim.host.ScsiLun-0005000000766d686261313a303a30": "mpx.vmhba1:C0:T0:L0"
|
||||
},
|
||||
"target_lun_uuid": {
|
||||
"0": "key-vim.host.ScsiDisk-0000000000766d686261303a303a30"
|
||||
}
|
||||
},
|
||||
}
|
||||
"""
|
||||
|
||||
try:
|
||||
from pyVmomi import vim, vmodl
|
||||
HAS_PYVMOMI = True
|
||||
except ImportError:
|
||||
HAS_PYVMOMI = False
|
||||
pass
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.vmware import HAS_PYVMOMI, connect_to_api, get_all_objs, vmware_argument_spec
|
||||
from ansible.module_utils.vmware import PyVmomi, vmware_argument_spec
|
||||
|
||||
|
||||
def find_hostsystem(content):
|
||||
host_system = get_all_objs(content, [vim.HostSystem])
|
||||
for host in host_system:
|
||||
return host
|
||||
return None
|
||||
class ScsiTargetFactsManager(PyVmomi):
|
||||
def __init__(self, module):
|
||||
super(ScsiTargetFactsManager, self).__init__(module)
|
||||
cluster_name = self.module.params.get('cluster_name')
|
||||
self.esxi_hostname = self.module.params.get('esxi_hostname')
|
||||
self.hosts = self.get_all_host_objs(cluster_name=cluster_name, esxi_host_name=self.esxi_hostname)
|
||||
|
||||
def gather_scsi_device_facts(self):
|
||||
"""
|
||||
Function to gather facts about SCSI target devices
|
||||
|
||||
"""
|
||||
scsi_tgt_facts = {}
|
||||
target_lun_uuid = {}
|
||||
scsilun_canonical = {}
|
||||
target_id = self.module.params['target_id']
|
||||
|
||||
for host in self.hosts:
|
||||
# Associate the scsiLun key with the canonicalName (NAA)
|
||||
for scsilun in host.config.storageDevice.scsiLun:
|
||||
scsilun_canonical[scsilun.key] = scsilun.canonicalName
|
||||
|
||||
# Associate target number with LUN uuid
|
||||
for target in host.config.storageDevice.scsiTopology.adapter[0].target:
|
||||
for lun in target.lun:
|
||||
target_lun_uuid[target.target] = lun.scsiLun
|
||||
|
||||
scsi_tgt_facts[host.name] = dict(scsilun_canonical=scsilun_canonical,
|
||||
target_lun_uuid=target_lun_uuid)
|
||||
|
||||
if target_id is not None and self.esxi_hostname is not None:
|
||||
canonical = ''
|
||||
temp_lun_data = scsi_tgt_facts[self.esxi_hostname]['target_lun_uuid']
|
||||
if self.esxi_hostname in scsi_tgt_facts and \
|
||||
target_id in temp_lun_data:
|
||||
temp_scsi_data = scsi_tgt_facts[self.esxi_hostname]['scsilun_canonical']
|
||||
temp_target = temp_lun_data[target_id]
|
||||
canonical = temp_scsi_data[temp_target]
|
||||
self.module.exit_json(changed=False, canonical=canonical)
|
||||
|
||||
self.module.exit_json(changed=False, scsi_tgt_facts=scsi_tgt_facts)
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
argument_spec = vmware_argument_spec()
|
||||
argument_spec.update(dict(target_id=dict(required=True, type='int')))
|
||||
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False)
|
||||
argument_spec.update(
|
||||
dict(
|
||||
target_id=dict(required=False, type='int'),
|
||||
cluster_name=dict(type='str', required=False),
|
||||
esxi_hostname=dict(type='str', required=False),
|
||||
)
|
||||
)
|
||||
|
||||
if not HAS_PYVMOMI:
|
||||
module.fail_json(msg='pyvmomi is required for this module')
|
||||
module = AnsibleModule(
|
||||
argument_spec=argument_spec,
|
||||
required_one_of=[
|
||||
['cluster_name', 'esxi_hostname'],
|
||||
],
|
||||
)
|
||||
|
||||
content = connect_to_api(module)
|
||||
host = find_hostsystem(content)
|
||||
|
||||
target_lun_uuid = {}
|
||||
scsilun_canonical = {}
|
||||
|
||||
# Associate the scsiLun key with the canonicalName (NAA)
|
||||
for scsilun in host.config.storageDevice.scsiLun:
|
||||
scsilun_canonical[scsilun.key] = scsilun.canonicalName
|
||||
|
||||
# Associate target number with LUN uuid
|
||||
for target in host.config.storageDevice.scsiTopology.adapter[0].target:
|
||||
for lun in target.lun:
|
||||
target_lun_uuid[target.target] = lun.scsiLun
|
||||
|
||||
module.exit_json(changed=False, canonical=scsilun_canonical[target_lun_uuid[module.params['target_id']]])
|
||||
scsi_tgt_manager = ScsiTargetFactsManager(module)
|
||||
scsi_tgt_manager.gather_scsi_device_facts()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
posix/ci/cloud/group4/vcenter
|
||||
cloud/vcenter
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
# Test code for the vmware_target_canonical_facts module.
|
||||
# Copyright: (c) 2018, Abhijeet Kasurde <akasurde@redhat.com>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
# TODO: vcsim does not support SCSI target releated operations
|
||||
|
||||
#- name: make sure pyvmomi is installed
|
||||
# pip:
|
||||
# name: pyvmomi
|
||||
# state: latest
|
||||
# when: "{{ ansible_user_id == 'root' }}"
|
||||
|
||||
#- name: store the vcenter container ip
|
||||
# set_fact:
|
||||
# vcsim: "{{ lookup('env', 'vcenter_host') }}"
|
||||
|
||||
#- debug: var=vcsim
|
||||
|
||||
#- name: Wait for Flask controller to come up online
|
||||
# wait_for:
|
||||
# host: "{{ vcsim }}"
|
||||
# port: 5000
|
||||
# state: started
|
||||
|
||||
#- name: kill vcsim
|
||||
# uri:
|
||||
# url: http://{{ vcsim }}:5000/killall
|
||||
|
||||
#- name: start vcsim
|
||||
# uri:
|
||||
# url: http://{{ vcsim }}:5000/spawn?cluster=2
|
||||
# register: vcsim_instance
|
||||
|
||||
#- debug:
|
||||
# var: vcsim_instance
|
||||
|
||||
#- name: Wait for vcsim server to come up online
|
||||
# wait_for:
|
||||
# host: "{{ vcsim }}"
|
||||
# port: 443
|
||||
# state: started
|
||||
|
||||
#- name: get a list of Cluster from vcsim
|
||||
# uri:
|
||||
# url: http://{{ vcsim }}:5000/govc_find?filter=CCR
|
||||
# register: clusters
|
||||
|
||||
#- name: get a cluster
|
||||
# set_fact:
|
||||
# ccr1: "{{ clusters.json[0] | basename }}"
|
||||
|
||||
#- name: get a list of hosts from vcsim
|
||||
# uri:
|
||||
# url: http://{{ vcsim }}:5000/govc_find?filter=H
|
||||
# register: hosts
|
||||
|
||||
#- name: get a host
|
||||
# set_fact:
|
||||
# host1: "{{ hosts.json[0] | basename }}"
|
||||
|
||||
#- debug: var=ccr1
|
||||
#- debug: var=host1
|
||||
|
||||
#- name: Gather target facts for all ESXi host from given cluster
|
||||
# vmware_target_canonical_facts:
|
||||
# hostname: "{{ vcsim }}"
|
||||
# username: "{{ vcsim_instance.json.username }}"
|
||||
# password: "{{ vcsim_instance.json.password }}"
|
||||
# validate_certs: False
|
||||
# cluster_name: "{{ ccr1 }}"
|
||||
# register: target_0001_results
|
||||
|
||||
#- assert:
|
||||
# that:
|
||||
# - "not target_0001_results.changed"
|
||||
# - "target_0001_results.scsi_tgt_facts is defined"
|
||||
|
||||
#- name: Gather target facts for ESXi host
|
||||
# vmware_target_canonical_facts:
|
||||
# hostname: "{{ vcsim }}"
|
||||
# username: "{{ vcsim_instance.json.username }}"
|
||||
# password: "{{ vcsim_instance.json.password }}"
|
||||
# validate_certs: False
|
||||
# esxi_hostname: "{{ host1 }}"
|
||||
# register: target_0002_results
|
||||
|
||||
#- assert:
|
||||
# that:
|
||||
# - "not target_0002_results.changed"
|
||||
# - "target_0002_results.scsi_tgt_facts is defined"
|
Loading…
Reference in a new issue