Update purefa_host module (#49157)

pull/49673/head
Simon Dodsley 6 years ago committed by ansibot
parent baf99c8b62
commit f6b211890a

@ -20,6 +20,8 @@ description:
- Create, delete or modify hosts on Pure Storage FlashArrays. - Create, delete or modify hosts on Pure Storage FlashArrays.
author: author:
- Simon Dodsley (@sdodsley) - Simon Dodsley (@sdodsley)
notes:
- If specifying C(lun) option ensure host support requested value
options: options:
host: host:
description: description:
@ -35,21 +37,32 @@ options:
description: description:
- Defines the host connection protocol for volumes. - Defines the host connection protocol for volumes.
default: iscsi default: iscsi
choices: [ fc, iscsi, mixed ] choices: [ fc, iscsi, nvmef, mixed ]
wwns: wwns:
description: description:
- List of wwns of the host if protocol is fc or mixed. - List of wwns of the host if protocol is fc or mixed.
iqn: iqn:
description: description:
- List of IQNs of the host if protocol is iscsi or mixed. - List of IQNs of the host if protocol is iscsi or mixed.
nqn:
description:
- List of NQNs of the host if protocol is nvmef or mixed.
version_added: '2.8'
volume: volume:
description: description:
- Volume name to map to the host. - Volume name to map to the host.
lun:
description:
- LUN ID to assign to volume for host. Must be unique.
- If not provided the ID will be automatically assigned.
- Range for LUN ID is 1 to 4095.
version_added: '2.8'
personality: personality:
description: description:
- Define which operating systen the host is. Recommend for - Define which operating system the host is. Recommend for
ActiveCluster integration ActiveCluster integration.
choices: ['hpux', 'vms', 'aix', 'esxi', 'solaris', 'hitachi-vsp', 'oracle-vm-server', ''] default: ''
choices: ['hpux', 'vms', 'aix', 'esxi', 'solaris', 'hitachi-vsp', 'oracle-vm-server', 'delete', '']
version_added: '2.7' version_added: '2.7'
extends_documentation_fragment: extends_documentation_fragment:
- purestorage.fa - purestorage.fa
@ -89,10 +102,21 @@ EXAMPLES = r'''
fa_url: 10.10.10.2 fa_url: 10.10.10.2
api_token: e31060a7-21fc-e277-6240-25983c6c4592 api_token: e31060a7-21fc-e277-6240-25983c6c4592
- name: Make host bar with NVMeF ports
purefa_host:
host: bar
protocol: nvmef
nqn:
- nqn.2014-08.com.vendor:nvme:nvm-subsystem-sn-d78432
fa_url: 10.10.10.2
api_token: e31060a7-21fc-e277-6240-25983c6c4592
- name: Make mixed protocol host - name: Make mixed protocol host
purefa_host: purefa_host:
host: bar host: bar
protocol: mixed protocol: mixed
nqn:
- nqn.2014-08.com.vendor:nvme:nvm-subsystem-sn-d78432
iqn: iqn:
- iqn.1994-05.com.redhat:7d366003914 - iqn.1994-05.com.redhat:7d366003914
wwns: wwns:
@ -101,10 +125,11 @@ EXAMPLES = r'''
fa_url: 10.10.10.2 fa_url: 10.10.10.2
api_token: e31060a7-21fc-e277-6240-25983c6c4592 api_token: e31060a7-21fc-e277-6240-25983c6c4592
- name: Map host foo to volume bar - name: Map host foo to volume bar as LUN ID 12
purefa_host: purefa_host:
host: foo host: foo
volume: bar volume: bar
lun: 12
fa_url: 10.10.10.2 fa_url: 10.10.10.2
api_token: e31060a7-21fc-e277-6240-25983c6c4592 api_token: e31060a7-21fc-e277-6240-25983c6c4592
''' '''
@ -117,6 +142,7 @@ from ansible.module_utils.pure import get_system, purefa_argument_spec
AC_REQUIRED_API_VERSION = '1.14' AC_REQUIRED_API_VERSION = '1.14'
NVMEF_API_VERSION = '1.16'
try: try:
@ -127,67 +153,158 @@ except ImportError:
def _set_host_initiators(module, array): def _set_host_initiators(module, array):
"""Set host initiators."""
if module.params['protocol'] in ['nvmef', 'mixed']:
if module.params['nqn']:
try:
array.set_host(module.params['host'],
nqnlist=module.params['nqn'])
except:
module.fail_json(msg='Setting of NVMeF NQN failed.')
if module.params['protocol'] in ['iscsi', 'mixed']: if module.params['protocol'] in ['iscsi', 'mixed']:
if module.params['iqn']: if module.params['iqn']:
array.set_host(module.params['host'], try:
addiqnlist=module.params['iqn']) array.set_host(module.params['host'],
iqnlist=module.params['iqn'])
except:
module.fail_json(msg='Setting of iSCSI IQN failed.')
if module.params['protocol'] in ['fc', 'mixed']: if module.params['protocol'] in ['fc', 'mixed']:
if module.params['wwns']: if module.params['wwns']:
array.set_host(module.params['host'], try:
addwwnlist=module.params['wwns']) array.set_host(module.params['host'],
wwnlist=module.params['wwns'])
except:
module.fail_json(msg='Setting of FC WWNs failed.')
def _update_host_initiators(module, array):
"""Change host initiator if iscsi or nvmef or add new FC WWNs"""
if module.params['protocol'] in ['nvmef', 'mixed']:
if module.params['nqn']:
try:
array.set_host(module.params['host'],
nqnlist=module.params['nqn'])
except:
module.fail_json(msg='Change of NVMeF NQN failed.')
if module.params['protocol'] in ['iscsi', 'mixed']:
if module.params['iqn']:
try:
array.set_host(module.params['host'],
iqnlist=module.params['iqn'])
except:
module.fail_json(msg='Change of iSCSI IQN failed.')
if module.params['protocol'] in ['fc', 'mixed']:
if module.params['wwns']:
try:
array.set_host(module.params['host'],
addwwnlist=module.params['wwns'])
except:
module.fail_json(msg='FC WWN additiona failed.')
def _connect_new_volume(module, array, answer=False):
"""Connect volume to host"""
api_version = array._list_available_rest_versions()
if AC_REQUIRED_API_VERSION in api_version and module.params['lun']:
try:
array.connect_host(module.params['host'],
module.params['volume'],
lun=module.params['lun'])
answer = True
except:
module.fail_json(msg='LUN ID {0} invalid. Check for duplicate LUN IDs.'.format(module.params['lun']))
else:
array.connect_host(module.params['host'], module.params['volume'])
answer = True
return answer
def _set_host_personality(module, array): def _set_host_personality(module, array):
"""Set host personality. Only called when AC is supported""" """Set host personality. Only called when supported"""
array.set_host(module.params['host'], if module.params['personality'] != 'delete':
personality=module.params['personality']) array.set_host(module.params['host'],
personality=module.params['personality'])
else:
array.set_host(module.params['host'], personality='')
def _update_host_personality(module, array, answer=False):
"""Change host personality. Only called when supported"""
personality = array.get_host(module.params['host'], personality=True)['personality']
if personality is None and module.params['personality'] != 'delete':
array.set_host(module.params['host'],
personality=module.params['personality'])
answer = True
if personality is not None:
if module.params['personality'] == 'delete':
array.set_host(module.params['host'], personality='')
answer = True
elif personality != module.params['personality']:
array.set_host(module.params['host'],
personality=module.params['personality'])
answer = True
return answer
def get_host(module, array): def get_host(module, array):
host = None host = None
for hst in array.list_hosts(): for hst in array.list_hosts():
if hst["name"] == module.params['host']: if hst["name"] == module.params['host']:
host = hst host = hst
break break
return host return host
def make_host(module, array): def make_host(module, array):
changed = True changed = False
try: try:
array.create_host(module.params['host']) array.create_host(module.params['host'])
changed = True
except:
module.fail_json(msg='Host {0} creation failed.'.format(module.params['host']))
try:
_set_host_initiators(module, array) _set_host_initiators(module, array)
api_version = array._list_available_rest_versions() api_version = array._list_available_rest_versions()
if AC_REQUIRED_API_VERSION in api_version: if AC_REQUIRED_API_VERSION in api_version and module.params['personality']:
_set_host_personality(module, array) _set_host_personality(module, array)
if module.params['volume']: if module.params['volume']:
array.connect_host(module.params['host'], module.params['volume']) if module.params['lun']:
array.connect_host(module.params['host'],
module.params['volume'],
lun=module.params['lun'])
else:
array.connect_host(module.params['host'], module.params['volume'])
except: except:
module.fail_json(msg='Host {0} creation failed.'.format(module.params['host'])) module.fail_json(msg='Host {0} configuration failed.'.format(module.params['host']))
module.exit_json(changed=changed) module.exit_json(changed=changed)
def update_host(module, array): def update_host(module, array):
changed = False changed = False
volumes = array.list_host_connections(module.params['host'])
if module.params['iqn'] or module.params['wwns']:
_update_host_initiators(module, array)
changed = True
if module.params['volume']:
current_vols = [vol['vol'] for vol in volumes]
if not module.params['volume'] in current_vols:
changed = _connect_new_volume(module, array)
api_version = array._list_available_rest_versions() api_version = array._list_available_rest_versions()
if AC_REQUIRED_API_VERSION in api_version: if AC_REQUIRED_API_VERSION in api_version:
try: if module.params['personality']:
_set_host_personality(module, array) changed = _update_host_personality(module, array)
changed = True
except:
module.fail_json(msg='Host {0} personality change failed'.format(module.params['host']))
module.exit_json(changed=changed) module.exit_json(changed=changed)
def delete_host(module, array): def delete_host(module, array):
changed = True changed = False
if not module.check_mode: try:
for vol in array.list_host_connections(module.params['host']): for vol in array.list_host_connections(module.params['host']):
array.disconnect_host(module.params['host'], vol["vol"]) array.disconnect_host(module.params['host'], vol["vol"])
array.delete_host(module.params['host']) array.delete_host(module.params['host'])
changed = True
except:
module.fail_json(msg='Host {0} deletion failed'.format(module.params['host']))
module.exit_json(changed=changed) module.exit_json(changed=changed)
@ -196,13 +313,15 @@ def main():
argument_spec.update(dict( argument_spec.update(dict(
host=dict(type='str', required=True), host=dict(type='str', required=True),
state=dict(type='str', default='present', choices=['absent', 'present']), state=dict(type='str', default='present', choices=['absent', 'present']),
protocol=dict(type='str', default='iscsi', choices=['fc', 'iscsi', 'mixed']), protocol=dict(type='str', default='iscsi', choices=['fc', 'iscsi', 'nvmef', 'mixed']),
nqn=dict(type='list'),
iqn=dict(type='list'), iqn=dict(type='list'),
wwns=dict(type='list'), wwns=dict(type='list'),
volume=dict(type='str'), volume=dict(type='str'),
lun=dict(type='int'),
personality=dict(type='str', default='', personality=dict(type='str', default='',
choices=['hpux', 'vms', 'aix', 'esxi', 'solaris', choices=['hpux', 'vms', 'aix', 'esxi', 'solaris',
'hitachi-vsp', 'oracle-vm-server', '']), 'hitachi-vsp', 'oracle-vm-server', 'delete', '']),
)) ))
module = AnsibleModule(argument_spec, supports_check_mode=False) module = AnsibleModule(argument_spec, supports_check_mode=False)
@ -210,11 +329,15 @@ def main():
if not HAS_PURESTORAGE: if not HAS_PURESTORAGE:
module.fail_json(msg='purestorage sdk is required for this module in host') module.fail_json(msg='purestorage sdk is required for this module in host')
api_version = array._list_available_rest_versions()
if module.params['nqn'] is not None and NVMEF_API_VERSION not in api_version:
module.fail_json(msg='NVMeF protocol not supported. Please upgrade your array.')
state = module.params['state'] state = module.params['state']
protocol = module.params['protocol'] protocol = module.params['protocol']
array = get_system(module) array = get_system(module)
host = get_host(module, array) host = get_host(module, array)
if module.params['lun'] and not 1 <= module.params['lun'] <= 4095:
module.fail_json(msg='LUN ID of {0} is out of range (1 to 4095)'.format(module.params['lun']))
if module.params['volume']: if module.params['volume']:
try: try:
array.get_volume(module.params['volume']) array.get_volume(module.params['volume'])

Loading…
Cancel
Save