def __init__(self): argument_spec = svc_argument_spec() argument_spec.update( dict( objectname=dict(type='str'), gather_subset=dict(type='list', elements='str', required=False, default=['all'], choices=[ 'vol', 'pool', 'node', 'iog', 'host', 'hc', 'fc', 'fcport', 'targetportfc', 'iscsiport', 'fcmap', 'rcrelationship', 'fcconsistgrp', 'rcconsistgrp', 'vdiskcopy', 'array', 'system', 'all' ]), )) self.module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) # logging setup log_path = self.module.params['log_path'] self.log = get_logger(self.__class__.__name__, log_path) self.objectname = self.module.params['objectname'] self.restapi = IBMSVCRestApi( module=self.module, clustername=self.module.params['clustername'], domain=self.module.params['domain'], username=self.module.params['username'], password=self.module.params['password'], validate_certs=self.module.params['validate_certs'], log_path=log_path)
def __init__(self): argument_spec = svc_argument_spec() argument_spec.update( dict( volname=dict(type='str', required=True), host=dict(type='str', required=True), state=dict(type='str', required=True, choices=['absent', 'present']), )) self.module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) # logging setup log_path = self.module.params['log_path'] log = get_logger(self.__class__.__name__, log_path) self.log = log.info # Required self.volname = self.module.params['volname'] self.host = self.module.params['host'] self.state = self.module.params['state'] # Optional self.restapi = IBMSVCRestApi( module=self.module, clustername=self.module.params['clustername'], domain=self.module.params['domain'], username=self.module.params['username'], password=self.module.params['password'], validate_certs=self.module.params['validate_certs'], log_path=log_path)
def __init__(self): argument_spec = svc_argument_spec() argument_spec.update( dict(name=dict(type='str', required=True), copytype=dict(type='str', required=False, choices=['snapshot', 'clone']), source=dict(type='str', required=False), target=dict(type='str', required=False), mdiskgrp=dict(type='str', required=False), state=dict(type='str', required=True, choices=['present', 'absent']), consistgrp=dict(type='str', required=False), noconsistgrp=dict(type='bool', required=False), copyrate=dict(type='str', required=False), grainsize=dict(type='str', required=False), force=dict(type='bool', required=False))) self.module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) # logging setup log_path = self.module.params['log_path'] log = get_logger(self.__class__.__name__, log_path) self.log = log.info # Required self.name = self.module.params['name'] self.state = self.module.params['state'] # Optional self.copytype = self.module.params.get('copytype', False) self.source = self.module.params.get('source', False) self.target = self.module.params.get('target', False) self.mdiskgrp = self.module.params.get('mdiskgrp', False) self.consistgrp = self.module.params.get('consistgrp', False) self.noconsistgrp = self.module.params.get('noconsistgrp', False) self.grainsize = self.module.params.get('grainsize', False) self.copyrate = self.module.params.get('copyrate', False) self.force = self.module.params.get('force', False) # Handline for mandatory parameter name if not self.name: self.module.fail_json(msg="Missing mandatory parameter: name") # Handline for mandatory parameter state if not self.state: self.module.fail_json(msg="Missing mandatory parameter: state") self.restapi = IBMSVCRestApi( module=self.module, clustername=self.module.params['clustername'], domain=self.module.params['domain'], username=self.module.params['username'], password=self.module.params['password'], validate_certs=self.module.params['validate_certs'], log_path=log_path, token=self.module.params['token'])
def __init__(self): argument_spec = svc_argument_spec() argument_spec.update( dict( name=dict(type='str'), state=dict(type='str', required=True, choices=['present', 'absent']), remotecluster=dict(type='str'), copytype=dict(type='str', choices=['metro', 'global', 'GMCV']), master=dict(type='str'), aux=dict(type='str'), force=dict(type='bool', required=False), consistgrp=dict(type='str'), noconsistgrp=dict(type='bool', default=False), sync=dict(type='bool', default=False), cyclingperiod=dict(type='int') ) ) self.module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) # logging setup log_path = self.module.params['log_path'] log = get_logger(self.__class__.__name__, log_path) self.log = log.info # Required self.name = self.module.params['name'] self.state = self.module.params['state'] self.remotecluster = self.module.params['remotecluster'] # Optional self.consistgrp = self.module.params.get('consistgrp', None) self.aux = self.module.params.get('aux') self.master = self.module.params.get('master') self.sync = self.module.params.get('sync', False) self.noconsistgrp = self.module.params.get('noconsistgrp', False) self.copytype = self.module.params.get('copytype', None) self.force = self.module.params.get('force', False) self.cyclingperiod = self.module.params.get('cyclingperiod') # Handling missing mandatory parameter name if not self.name: self.module.fail_json(msg='Missing mandatory parameter: name') self.restapi = IBMSVCRestApi( module=self.module, clustername=self.module.params['clustername'], domain=self.module.params['domain'], username=self.module.params['username'], password=self.module.params['password'], validate_certs=self.module.params['validate_certs'], log_path=log_path, token=self.module.params['token'] )
def setUp(self, connect): self.mock_module_helper = patch.multiple(basic.AnsibleModule, exit_json=exit_json, fail_json=fail_json) self.mock_module_helper.start() self.addCleanup(self.mock_module_helper.stop) self.restapi = IBMSVCRestApi(self.mock_module_helper, '1.2.3.4', 'domain.ibm.com', 'username', 'password', False, '/tmp/test.log')
def __init__(self): argument_spec = svc_argument_spec() argument_spec.update( dict(name=dict(type='str', required=True), state=dict(type='str', required=True, choices=['absent', 'present']), datareduction=dict(type='str', default='no', choices=['yes', 'no']), easytier=dict(type='str', default='off', choices=['on', 'off', 'auto']), encrypt=dict(type='str', default='no', choices=['yes', 'no']), ext=dict(type='int'), parentmdiskgrp=dict(type='str'), size=dict(type='int'), unit=dict(type='str'))) mutually_exclusive = [] self.module = AnsibleModule(argument_spec=argument_spec, mutually_exclusive=mutually_exclusive, supports_check_mode=True) # logging setup log_path = self.module.params['log_path'] log = get_logger(self.__class__.__name__, log_path) self.log = log.info # Required self.name = self.module.params['name'] self.state = self.module.params['state'] # Optional self.datareduction = self.module.params.get('datareduction', None) self.easytier = self.module.params.get('easytier', None) self.encrypt = self.module.params.get('encrypt', None) self.ext = self.module.params.get('ext', None) self.parentmdiskgrp = self.module.params.get('parentmdiskgrp', None) self.size = self.module.params.get('size', None) self.unit = self.module.params.get('unit', None) # Handling missing mandatory parameters name if not self.name: self.module.fail_json(msg='Missing mandatory parameter: name') self.restapi = IBMSVCRestApi( module=self.module, clustername=self.module.params['clustername'], domain=self.module.params['domain'], username=self.module.params['username'], password=self.module.params['password'], validate_certs=self.module.params['validate_certs'], log_path=log_path, token=self.module.params['token'])
def __init__(self): argument_spec = svc_argument_spec() argument_spec.update( dict(name=dict(type='str', required=True), state=dict(type='str', required=True, choices=['absent', 'present']), mdiskgrp=dict(type='str', required=False), size=dict(type='str', required=False), unit=dict(type='str', default='mb', choices=['b', 'kb', 'mb', 'gb', 'tb', 'pb']), easytier=dict(type='str', choices=['on', 'off']), rsize=dict(type='str', required=False), autoexpand=dict(type='bool', required=False))) self.module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) self.resizevdisk_flag = False self.expand_flag = False self.shrink_flag = False # logging setup log_path = self.module.params['log_path'] log = get_logger(self.__class__.__name__, log_path) self.log = log.info # Required self.name = self.module.params['name'] self.state = self.module.params['state'] # Optional self.mdiskgrp = self.module.params['mdiskgrp'] self.size = self.module.params['size'] self.unit = self.module.params['unit'] self.easytier = self.module.params.get('easytier', None) self.rsize = self.module.params['rsize'] self.autoexpand = self.module.params['autoexpand'] # Handling missing mandatory parameter name if not self.name: self.module.fail_json('Missing mandatory parameter: name') self.restapi = IBMSVCRestApi( module=self.module, clustername=self.module.params['clustername'], domain=self.module.params['domain'], username=self.module.params['username'], password=self.module.params['password'], validate_certs=self.module.params['validate_certs'], log_path=log_path, token=self.module.params['token'])
def __init__(self): argument_spec = svc_argument_spec() argument_spec.update( dict( name=dict(type='str'), state=dict(type='str', required=True, choices=['started', 'stopped']), force=dict(type='bool', required=False), primary=dict(type='str', choices=['master', 'aux']), clean=dict(type='bool', default=False), access=dict(type='bool', default=False), isgroup=dict(type='bool', default=False), )) self.module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) # logging setup log_path = self.module.params['log_path'] log = get_logger(self.__class__.__name__, log_path) self.log = log.info # Required self.name = self.module.params['name'] self.state = self.module.params['state'] # Optional self.primary = self.module.params.get('primary', None) self.clean = self.module.params.get('clean', False) self.access = self.module.params.get('access', False) self.force = self.module.params.get('force', False) self.isgroup = self.module.params.get('isgroup', False) # Handling missing mandatory parameter name if not self.name: self.module.fail_json(msg='Missing mandatory parameter: name') self.restapi = IBMSVCRestApi( module=self.module, clustername=self.module.params['clustername'], domain=self.module.params['domain'], username=self.module.params['username'], password=self.module.params['password'], validate_certs=self.module.params['validate_certs'], log_path=log_path, token=self.module.params['token'])
def __init__(self): argument_spec = svc_argument_spec() argument_spec.update( dict(name=dict(type='str', required=True), state=dict(type='str', required=True, choices=[ 'absent', 'present', 'prestart', 'start', 'stop' ]), restore=dict(type='bool', required=False, default=False), prep=dict(type='bool', required=False, default=False), force=dict(type='bool', required=False, default=False), split=dict(type='bool', required=False, default=False), autodelete=dict(type='str', required=False, choices=['on', 'off'], default='off'))) self.module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) # logging setup log_path = self.module.params['log_path'] log = get_logger(self.__class__.__name__, log_path) self.log = log.info # Required self.name = self.module.params['name'] self.state = self.module.params['state'] # Optional self.prep = self.module.params.get('prep', False) self.autodelete = self.module.params.get('autodelete', 'off') self.restore = self.module.params.get('restore', False) self.split = self.module.params.get('split', False) self.force = self.module.params.get('force', False) self.restapi = IBMSVCRestApi( module=self.module, clustername=self.module.params['clustername'], domain=self.module.params['domain'], username=self.module.params['username'], password=self.module.params['password'], validate_certs=self.module.params['validate_certs'], log_path=log_path)
def __init__(self): argument_spec = svc_argument_spec() argument_spec.update( dict( name=dict(type='str', required=True), state=dict(type='str', required=True, choices=['absent', 'present']), fcwwpn=dict(type='str', required=False), iscsiname=dict(type='str', required=False), iogrp=dict(type='str', required=False, default='0:1:2:3'), protocol=dict(type='str', required=False, default='scsi', choices=['scsi', 'nvme']), type=dict(type='str') ) ) self.module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) # logging setup log_path = self.module.params['log_path'] log = get_logger(self.__class__.__name__, log_path) self.log = log.info # Required self.name = self.module.params['name'] self.state = self.module.params['state'] # Optional self.fcwwpn = self.module.params.get('fcwwpn', '') self.iscsiname = self.module.params.get('iscsiname', '') self.iogrp = self.module.params.get('iogrp', '') self.protocol = self.module.params.get('protocol', '') self.type = self.module.params.get('type', '') self.restapi = IBMSVCRestApi( module=self.module, clustername=self.module.params['clustername'], domain=self.module.params['domain'], username=self.module.params['username'], password=self.module.params['password'], validate_certs=self.module.params['validate_certs'], log_path=log_path )
def test_svc_rest_with_module(self, mock_svc_token_wrap, mock_module, mock_svc_authorize): PARAMS_FOR_PRESENT = { 'clustername': 'clustername', 'domain': 'domain', 'state': 'present', 'username': '******', 'password': '******' } mock_module.params = PARAMS_FOR_PRESENT mock_module.return_value = mock_module mock_svc_token_wrap.return_value = {'err': 'err', 'out': []} self.restapi = IBMSVCRestApi(mock_module, '1.2.3.4', 'domain.ibm.com', 'username', 'password', False, '/tmp/test.log') self.restapi.svc_run_command('lshost', {}, [])
def __init__(self): argument_spec = svc_argument_spec() argument_spec.update( dict(state=dict(type='str', required=True, choices=['present', 'absent']), rname=dict(type='str', required=True), cvname=dict(type='str', required=True), basevolume=dict(type='str'), ismaster=dict(type='bool', default=True))) self.module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) # logging setup log_path = self.module.params['log_path'] log = get_logger(self.__class__.__name__, log_path) self.log = log.info # Required self.state = self.module.params['state'] self.rname = self.module.params['rname'] self.cvname = self.module.params['cvname'] # Optional self.basevolume = self.module.params['basevolume'] self.ismaster = self.module.params['ismaster'] # Handling missing mandatory parameter rname if not self.rname: self.module.fail_json(msg='Missing mandatory parameter: rname') # Handling missing mandatory parameter cvname if not self.cvname: self.module.fail_json(msg='Missing mandatory parameter: cvname') self.restapi = IBMSVCRestApi( module=self.module, clustername=self.module.params['clustername'], domain=self.module.params['domain'], username=self.module.params['username'], password=self.module.params['password'], validate_certs=self.module.params['validate_certs'], log_path=log_path, token=self.module.params['token'])
def __init__(self): argument_spec = svc_argument_spec() argument_spec.update( dict( name=dict(type='str', required=True), state=dict(type='str', required=True, choices=['absent', 'present']), ownershipgroup=dict(type='str'), removeallhosts=dict(type='bool') ) ) self.changed = "" self.module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) # logging setup log_path = self.module.params['log_path'] log = get_logger(self.__class__.__name__, log_path) self.log = log.info # Required self.name = self.module.params['name'] self.state = self.module.params['state'] # Optional self.ownershipgroup = self.module.params.get('ownershipgroup', '') self.removeallhosts = self.module.params.get('removeallhosts', '') # Handling missing mandatory parameter name if not self.name: self.module.fail_json(msg='Missing mandatory parameter: name') self.restapi = IBMSVCRestApi( module=self.module, clustername=self.module.params['clustername'], domain=self.module.params['domain'], username=self.module.params['username'], password=self.module.params['password'], validate_certs=self.module.params['validate_certs'], log_path=log_path, token=self.module.params['token'] )
def __init__(self): argument_spec = svc_argument_spec() argument_spec.update( dict( name=dict(type='str', required=True), state=dict(type='str', required=True, choices=['absent', 'present']), remotecluster=dict(type='str', required=False), force=dict(type='bool', required=False), copytype=dict(type='str', choices=['metro', 'global']), cyclingmode=dict(type='str', required=False, choices=['multi', 'none']), cyclingperiod=dict(type='int', required=False) ) ) self.module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) # logging setup log_path = self.module.params['log_path'] log = get_logger(self.__class__.__name__, log_path) self.log = log.info # Required self.name = self.module.params['name'] self.state = self.module.params['state'] # Optional self.cluster = self.module.params.get('remotecluster', None) self.force = self.module.params.get('force', False) self.copytype = self.module.params.get('copytype', None) self.cyclingmode = self.module.params.get('cyclingmode', None) self.cyclingperiod = self.module.params.get('cyclingperiod', None) self.restapi = IBMSVCRestApi( module=self.module, clustername=self.module.params['clustername'], domain=self.module.params['domain'], username=self.module.params['username'], password=self.module.params['password'], validate_certs=self.module.params['validate_certs'], log_path=log_path )
def __init__(self): argument_spec = svc_argument_spec() argument_spec.update( dict(name=dict(type='str', required=True), state=dict(type='str', required=True, choices=['absent', 'present']), mdiskgrp=dict(type='str', required=False), size=dict(type='str', required=False), unit=dict(type='str', default='mb', choices=['b', 'kb', 'mb', 'gb', 'tb', 'pb']), easytier=dict(type='str', default='off', choices=['on', 'off', 'auto']))) self.module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) # logging setup log_path = self.module.params['log_path'] log = get_logger(self.__class__.__name__, log_path) self.log = log.info # Required self.name = self.module.params['name'] self.state = self.module.params['state'] # Optional self.mdiskgrp = self.module.params['mdiskgrp'] self.size = self.module.params['size'] self.unit = self.module.params['unit'] self.easytier = self.module.params.get('easytier', None) self.restapi = IBMSVCRestApi( module=self.module, clustername=self.module.params['clustername'], domain=self.module.params['domain'], username=self.module.params['username'], password=self.module.params['password'], validate_certs=self.module.params['validate_certs'], log_path=log_path)
def __init__(self): argument_spec = svc_argument_spec() argument_spec.update( dict(name=dict(type='str', required=True), state=dict(type='str', required=True, choices=['absent', 'present']), level=dict( type='str', choices=['raid0', 'raid1', 'raid5', 'raid6', 'raid10']), drive=dict(type='str', default=None), encrypt=dict(type='str', default='no', choices=['yes', 'no']), mdiskgrp=dict(type='str', required=True))) mutually_exclusive = [] self.module = AnsibleModule(argument_spec=argument_spec, mutually_exclusive=mutually_exclusive, supports_check_mode=True) # logging setup log_path = self.module.params['log_path'] log = get_logger(self.__class__.__name__, log_path) self.log = log.info # Required self.name = self.module.params['name'] self.state = self.module.params['state'] # Optional self.level = self.module.params.get('level', None) self.drive = self.module.params.get('drive', None) self.encrypt = self.module.params.get('encrypt', None) self.mdiskgrp = self.module.params.get('mdiskgrp', None) self.restapi = IBMSVCRestApi( module=self.module, clustername=self.module.params['clustername'], domain=self.module.params['domain'], username=self.module.params['username'], password=self.module.params['password'], validate_certs=self.module.params['validate_certs'], log_path=log_path)
def __init__(self): argument_spec = svc_argument_spec() argument_spec.update( dict(volname=dict(type='str', required=True), host=dict(type='str', required=False), state=dict(type='str', required=True, choices=['absent', 'present']), scsi=dict(type='int', required=False), hostcluster=dict(type='str', required=False))) self.module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) # logging setup log_path = self.module.params['log_path'] log = get_logger(self.__class__.__name__, log_path) self.log = log.info # Required self.volname = self.module.params['volname'] self.state = self.module.params['state'] # Optional self.host = self.module.params['host'] self.hostcluster = self.module.params['hostcluster'] self.scsi = self.module.params['scsi'] # Handline for mandatory parameter volname if not self.volname: self.module.fail_json(msg="Missing mandatory parameter: volname") self.restapi = IBMSVCRestApi( module=self.module, clustername=self.module.params['clustername'], domain=self.module.params['domain'], username=self.module.params['username'], password=self.module.params['password'], validate_certs=self.module.params['validate_certs'], log_path=log_path, token=self.module.params['token'])
def __init__(self): argument_spec = svc_argument_spec() self.module = AnsibleModule(argument_spec=argument_spec) # logging setup log_path = self.module.params['log_path'] log = get_logger(self.__class__.__name__, log_path) self.log = log.info self.restapi = IBMSVCRestApi( module=self.module, clustername=self.module.params['clustername'], domain=self.module.params['domain'], username=self.module.params['username'], password=self.module.params['password'], validate_certs=self.module.params['validate_certs'], log_path=log_path, token=None)
class IBMSVCvdisk(object): def __init__(self): argument_spec = svc_argument_spec() argument_spec.update( dict(name=dict(type='str', required=True), state=dict(type='str', required=True, choices=['absent', 'present']), mdiskgrp=dict(type='str', required=False), size=dict(type='str', required=False), unit=dict(type='str', default='mb', choices=['b', 'kb', 'mb', 'gb', 'tb', 'pb']), easytier=dict(type='str', default='off', choices=['on', 'off', 'auto']))) self.module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) # logging setup log_path = self.module.params['log_path'] log = get_logger(self.__class__.__name__, log_path) self.log = log.info # Required self.name = self.module.params['name'] self.state = self.module.params['state'] # Optional self.mdiskgrp = self.module.params['mdiskgrp'] self.size = self.module.params['size'] self.unit = self.module.params['unit'] self.easytier = self.module.params.get('easytier', None) self.restapi = IBMSVCRestApi( module=self.module, clustername=self.module.params['clustername'], domain=self.module.params['domain'], username=self.module.params['username'], password=self.module.params['password'], validate_certs=self.module.params['validate_certs'], log_path=log_path) def get_existing_vdisk(self): merged_result = {} data = self.restapi.svc_obj_info(cmd='lsvdisk', cmdopts=None, cmdargs=[self.name]) if isinstance(data, list): for d in data: merged_result.update(d) else: merged_result = data return merged_result # TBD: Implement a more generic way to check for properties to modify. def vdisk_probe(self, data): props = [] # TBD: The parameter is easytier but the view has easy_tier label. if self.easytier: if self.easytier != data['easy_tier']: props += ['easytier'] if props is []: props = None self.log("vdisk_probe props='%s'", data) return props def vdisk_create(self): if self.module.check_mode: self.changed = True return if not self.mdiskgrp: self.module.fail_json(msg="You must pass in " "mdiskgrp to the module.") if not self.size: self.module.fail_json(msg="You must pass in size to the module.") if not self.unit: self.module.fail_json(msg="You must pass in unit to the module.") self.log("creating vdisk '%s'", self.name) # Make command cmd = 'mkvdisk' cmdopts = {} if self.mdiskgrp: cmdopts['mdiskgrp'] = self.mdiskgrp if self.size: cmdopts['size'] = self.size if self.unit: cmdopts['unit'] = self.unit if self.easytier: cmdopts['easytier'] = self.easytier cmdopts['name'] = self.name self.log("creating vdisk command %s opts %s", cmd, cmdopts) # Run command result = self.restapi.svc_run_command(cmd, cmdopts, cmdargs=None) self.log("create vdisk result %s", result) if 'message' in result: self.changed = True self.log("create vdisk result message %s", result['message']) else: self.module.fail_json(msg="Failed to create vdisk [%s]" % self.name) def vdisk_update(self, modify): # update the vdisk self.log("updating vdisk '%s'", self.name) cmd = 'chvdisk' cmdopts = {} # TBD: Be smarter handling many properties. if 'easytier' in modify: cmdopts['easytier'] = self.easytier cmdargs = [self.name] self.restapi.svc_run_command(cmd, cmdopts, cmdargs) # Any error will have been raised in svc_run_command # chvdisk does not output anything when successful. self.changed = True def vdisk_delete(self): self.log("deleting vdisk '%s'", self.name) cmd = 'rmvdisk' cmdopts = None cmdargs = [self.name] self.restapi.svc_run_command(cmd, cmdopts, cmdargs) # Any error will have been raised in svc_run_command # chmvdisk does not output anything when successful. self.changed = True def apply(self): changed = False msg = None modify = [] vdisk_data = self.get_existing_vdisk() if vdisk_data: if self.state == 'absent': self.log("CHANGED: vdisk exists, but requested " "state is 'absent'") changed = True elif self.state == 'present': # This is where we detect if chvdisk should be called modify = self.vdisk_probe(vdisk_data) if modify: changed = True else: if self.state == 'present': self.log("CHANGED: vdisk does not exist, " "but requested state is 'present'") changed = True if changed: if self.module.check_mode: self.log('skipping changes due to check mode') else: if self.state == 'present': if not vdisk_data: self.vdisk_create() msg = "vdisk %s has been created." % self.name else: # This is where we would modify self.vdisk_update(modify) msg = "vdisk [%s] has been modified." % self.name elif self.state == 'absent': self.vdisk_delete() msg = "vdisk [%s] has been deleted." % self.name else: self.log("exiting with no changes") if self.state == 'absent': msg = "vdisk [%s] did not exist." % self.name else: msg = "vdisk [%s] already exists." % self.name self.module.exit_json(msg=msg, changed=changed)
def __init__(self): argument_spec = svc_argument_spec() argument_spec.update( dict( name=dict(type='str', required=True), state=dict(type='str', required=True, choices=['absent', 'present', 'prestart', 'start', 'stop']), mdiskgrp=dict(type='str', required=False), volume=dict(type='str', required=True), clone=dict(type='str', required=True), consistgrp=dict(type='str', required=False), grainsize=dict(type='str', required=False, choices=['64', '256']), iogrp=dict(type='str', required=False), copyrate=dict(type='str', required=False, default='50'), cleanrate=dict(type='str', required=False, default='50'), keeptarget=dict(type='bool', required=False), restore=dict(type='bool', required=False), prep=dict(type='bool', required=False), force=dict(type='bool', required=False), split=dict(type='bool', required=False), autodelete=dict(type='str', required=False, choices=['on', 'off'], default='on') ) ) self.module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) # logging setup log_path = self.module.params['log_path'] log = get_logger(self.__class__.__name__, log_path) self.log = log.info # Required self.name = self.module.params['name'] self.state = self.module.params['state'] self.volume = self.module.params['volume'] self.clone = self.module.params['clone'] # Optional self.mdiskgrp = self.module.params.get('mdiskgrp', None) self.consistgrp = self.module.params.get('consistgrp', None) self.grainsize = self.module.params.get('grainsize', None) self.iogrp = self.module.params.get('iogrp', None) self.copyrate = self.module.params.get('copyrate', '50') self.cleanrate = self.module.params.get('cleanrate', '50') self.keeptarget = self.module.params.get('keeptarget', False) self.restore = self.module.params.get('restore', False) self.prep = self.module.params.get('prep', False) self.force = self.module.params.get('force', False) self.split = self.module.params.get('split', False) self.autodelete = self.module.params.get('autodelete', 'on') # Store source vol info self.source_vol_info = {} self.restapi = IBMSVCRestApi( module=self.module, clustername=self.module.params['clustername'], domain=self.module.params['domain'], username=self.module.params['username'], password=self.module.params['password'], validate_certs=self.module.params['validate_certs'], log_path=log_path )
class IBMSVCClone(object): def __init__(self): argument_spec = svc_argument_spec() argument_spec.update( dict( name=dict(type='str', required=True), state=dict(type='str', required=True, choices=['absent', 'present', 'prestart', 'start', 'stop']), mdiskgrp=dict(type='str', required=False), volume=dict(type='str', required=True), clone=dict(type='str', required=True), consistgrp=dict(type='str', required=False), grainsize=dict(type='str', required=False, choices=['64', '256']), iogrp=dict(type='str', required=False), copyrate=dict(type='str', required=False, default='50'), cleanrate=dict(type='str', required=False, default='50'), keeptarget=dict(type='bool', required=False), restore=dict(type='bool', required=False), prep=dict(type='bool', required=False), force=dict(type='bool', required=False), split=dict(type='bool', required=False), autodelete=dict(type='str', required=False, choices=['on', 'off'], default='on') ) ) self.module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) # logging setup log_path = self.module.params['log_path'] log = get_logger(self.__class__.__name__, log_path) self.log = log.info # Required self.name = self.module.params['name'] self.state = self.module.params['state'] self.volume = self.module.params['volume'] self.clone = self.module.params['clone'] # Optional self.mdiskgrp = self.module.params.get('mdiskgrp', None) self.consistgrp = self.module.params.get('consistgrp', None) self.grainsize = self.module.params.get('grainsize', None) self.iogrp = self.module.params.get('iogrp', None) self.copyrate = self.module.params.get('copyrate', '50') self.cleanrate = self.module.params.get('cleanrate', '50') self.keeptarget = self.module.params.get('keeptarget', False) self.restore = self.module.params.get('restore', False) self.prep = self.module.params.get('prep', False) self.force = self.module.params.get('force', False) self.split = self.module.params.get('split', False) self.autodelete = self.module.params.get('autodelete', 'on') # Store source vol info self.source_vol_info = {} self.restapi = IBMSVCRestApi( module=self.module, clustername=self.module.params['clustername'], domain=self.module.params['domain'], username=self.module.params['username'], password=self.module.params['password'], validate_certs=self.module.params['validate_certs'], log_path=log_path ) def get_existing_clone(self): merged_result = {} self.log('Trying to get the clone %s', self.clone) data = self.restapi.svc_obj_info(cmd='lsvdisk', cmdopts=None, cmdargs=[self.clone]) if isinstance(data, list): for d in data: merged_result.update(d) else: merged_result = data return merged_result def get_fc_mapping(self): merged_result = {} self.log('Trying to get the fc mapping: %s', self.name) data = self.restapi.svc_obj_info(cmd='lsfcmap', cmdopts=None, cmdargs=[self.name]) if isinstance(data, list): for d in data: merged_result.update(d) else: merged_result = data return merged_result def get_info_from_source_volume(self): self.log("Getting info from source volume %s", self.volume) data = self.restapi.svc_obj_info(cmd='lsvdisk', cmdopts={'bytes': True}, cmdargs=[self.volume]) if not data: self.module.fail_json(msg="You must specify an " "existing source volume.") if isinstance(data, list): for d in data: self.source_vol_info.update(d) else: self.source_vol_info = data def target_volume_create(self): self.log("Creating target volume '%s'", self.clone) self.get_info_from_source_volume() # Make command cmd = 'mkvdisk' cmdopts = {} cmdopts['name'] = self.clone if self.mdiskgrp: cmdopts['mdiskgrp'] = self.mdiskgrp else: cmdopts['mdiskgrp'] = self.source_vol_info['mdisk_grp_name'] cmdopts['size'] = self.source_vol_info['capacity'] cmdopts['unit'] = 'b' cmdopts['iogrp'] = self.source_vol_info['IO_group_name'] self.log("Creating vdisk command %s opts %s", cmd, cmdopts) # Run command result = self.restapi.svc_run_command(cmd, cmdopts, cmdargs=None) self.log("Create target volume result %s", result) if 'message' in result: self.changed = True self.log("Create target volume result message %s", result['message']) else: self.module.fail_json( msg="Failed to create target volume [%s]" % self.clone) def prestartfcmap(self): self.log("Prestart fc map for %s", self.name) cmd = 'prestartfcmap' cmdopts = {} if self.restore: cmdopts = {'restore': True} self.log("Prestartfcmap fc map %s opts %s", cmd, cmdopts) self.restapi.svc_run_command(cmd, cmdopts, cmdargs=[self.name]) self.log("Prestartfcmap fc map finished") def startfcmap(self): self.log("Start fc map for %s", self.name) cmd = 'startfcmap' cmdopts = {} if self.prep: cmdopts['prep'] = True if self.restore: cmdopts['restore'] = True self.log("Starting fc map %s opts %s", cmd, cmdopts) self.restapi.svc_run_command(cmd, cmdopts, cmdargs=[self.name]) self.log("Start fc map finished") def stopfcmap(self): self.log("Stop fc map for %s", self.name) cmd = 'stopfcmap' cmdopts = {} if self.force: cmdopts['force'] = True if self.split: cmdopts['split'] = True self.log("Stopping fc map %s opts %s", cmd, cmdopts) self.restapi.svc_run_command(cmd, cmdopts, cmdargs=[self.name]) self.log("Stop fc map finished") def rmfcmap(self): self.log("Delete fc map for %s", self.name) cmd = 'rmfcmap' cmdopts = {} if self.force: cmdopts['force'] = True self.log("Delete fc map %s opts %s", cmd, cmdopts) self.restapi.svc_run_command(cmd, cmdopts, cmdargs=[self.name]) self.log("Delete fc map finished") # TBD: Implement a more generic way to check for properties to modify. def flashcopymap_probe(self, data): props = {} self.log("Probe which properties need to be updated...") if self.consistgrp is not None and self.consistgrp != data['group_name']: props['consistgrp'] = self.consistgrp if self.copyrate != data['copy_rate']: props['copyrate'] = self.copyrate if self.cleanrate != data['clean_rate']: props['cleanrate'] = self.cleanrate if self.autodelete != data['autodelete']: props['autodelete'] = self.autodelete return props def flashcopymap_create(self): self.log("Checking the target volume...") data = self.get_existing_clone() if not data: self.target_volume_create() self.log("Creating flash copy mapping relationship'%s'", self.name) # Make command cmd = 'mkfcmap' cmdopts = {'name': self.name, 'source': self.volume, 'target': self.clone} if self.grainsize: cmdopts['grainsize'] = self.grainsize if self.keeptarget: cmdopts['keeptarget'] = True if self.consistgrp: cmdopts['consistgrp'] = self.consistgrp if self.iogrp: cmdopts['iogrp'] = self.iogrp cmdopts['copyrate'] = self.copyrate cmdopts['cleanrate'] = self.cleanrate if self.autodelete == 'on': cmdopts['autodelete'] = True self.log("Creating clone relationship command %s opts %s", cmd, cmdopts) # Run command result = self.restapi.svc_run_command(cmd, cmdopts, cmdargs=None) self.log("Create flash copy mapping relationship result %s", result) if 'message' in result: self.changed = True self.log("Create flash copy mapping relationship result " "message %s", result['message']) else: self.module.fail_json(msg="Failed to create FlashCopy mapping " "relationship [%s]" % self.name) def flashcopymap_update(self, modify): if modify: self.log("updating fcmap with properties %s", modify) cmd = 'chfcmap' cmdopts = {} for prop in modify: cmdopts[prop] = modify[prop] cmdargs = [self.name] self.restapi.svc_run_command(cmd, cmdopts, cmdargs) # Any error will have been raised in svc_run_command # chfcmap does not output anything when successful. self.changed = True else: self.log("There is no property need to be updated") self.changed = False def flashcopymap_delete(self): self.log("Delete flash copy mapping '%s'", self.name) cmd = 'rmfcmap' cmdopts = {} if self.force: cmdopts['force'] = True cmdargs = [self.name] self.restapi.svc_run_command(cmd, cmdopts, cmdargs) # Any error will have been raised in svc_run_command # rmfcmap does not output anything when successful. self.changed = True def apply(self): changed = False msg = None modify = {} fcmap_data = self.get_fc_mapping() if fcmap_data: if self.state == 'absent': self.log("CHANGED: FlashCopy mapping exists," "requested state is 'absent'") changed = True elif self.state == 'present': # This is where we detect if chfcmap should be called modify = self.flashcopymap_probe(fcmap_data) if modify: changed = True elif self.state in ['prestart', 'start', 'stop']: self.log("The state is %s", self.state) changed = True else: if self.state == 'present': self.log("CHANGED: FlashCopy mapping does not exist, " "a new FlashCopy mapping will be created.") changed = True if changed: if self.module.check_mode: self.log('skipping changes due to check mode') else: if self.state == 'present': if not fcmap_data: self.flashcopymap_create() msg = ("FlashCopy mapping %s has been " "created." % self.name) else: # This is where we would modify self.flashcopymap_update(modify) msg = ("FlashCopy mapping [%s] has " "been modified." % self.name) elif self.state == 'absent': self.flashcopymap_delete() msg = ("FlashCopy mapping [%s] has been " "deleted." % self.name) elif self.state == 'prestart': self.prestartfcmap() msg = ("FlashCopy mapping [%s] has been " "prestarted." % self.name) elif self.state == 'start': self.startfcmap() msg = ("FlashCopy mapping [%s] has been " "started." % self.name) elif self.state == 'stop': self.stopfcmap() msg = ("FlashCopy mapping [%s] has been " "stopped." % self.name) else: self.log("Exiting with no changes") if self.state in ['absent', 'prestart', 'start', 'stop']: msg = "FlashCopy mapping [%s] did not exist." % self.name else: msg = "FlashCopy mapping [%s] already exists." % self.name self.module.exit_json(msg=msg, changed=changed)
class IBMSVCchangevolume(object): def __init__(self): argument_spec = svc_argument_spec() argument_spec.update( dict(state=dict(type='str', required=True, choices=['present', 'absent']), rname=dict(type='str', required=True), cvname=dict(type='str', required=True), basevolume=dict(type='str'), ismaster=dict(type='bool', default=True))) self.module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) # logging setup log_path = self.module.params['log_path'] log = get_logger(self.__class__.__name__, log_path) self.log = log.info # Required self.state = self.module.params['state'] self.rname = self.module.params['rname'] self.cvname = self.module.params['cvname'] # Optional self.basevolume = self.module.params['basevolume'] self.ismaster = self.module.params['ismaster'] self.restapi = IBMSVCRestApi( module=self.module, clustername=self.module.params['clustername'], domain=self.module.params['domain'], username=self.module.params['username'], password=self.module.params['password'], validate_certs=self.module.params['validate_certs'], log_path=log_path) def get_existing_rc(self): """ find the remote copy relationships such as Metro Mirror, Global Mirror relationships visible to the system. Returns: None if no matching instances or a list including all the matching instances """ self.log('Trying to get the remote copy relationship %s', self.rname) data = self.restapi.svc_obj_info(cmd='lsrcrelationship', cmdopts=None, cmdargs=[self.rname]) return data def get_existing_vdisk(self, volname): merged_result = {} data = self.restapi.svc_obj_info(cmd='lsvdisk', cmdopts={'bytes': True}, cmdargs=[volname]) if not data: self.log("source volume %s does not exist", volname) return if isinstance(data, list): for d in data: merged_result.update(d) else: merged_result = data return merged_result def change_volume_attach(self, rcrelationship_data): cmdopts = {} if rcrelationship_data['copy_type'] != 'global': self.module.fail_json(msg="Relationship '%s' type must be global" % self.rname) if self.ismaster: cmdopts['masterchange'] = self.cvname else: cmdopts['auxchange'] = self.cvname # command cmd = 'chrcrelationship' cmdargs = [self.rname] self.log("updating chrcrelationship %s with properties %s", cmd, cmdopts) # Run command self.restapi.svc_run_command(cmd, cmdopts, cmdargs) self.changed = True self.log("Updated remote copy relationship ") def change_volume_detach(self, rcrelationship_data): cmdopts = {} if self.ismaster: cmdopts = {'nomasterchange': True} else: cmdopts = {'noauxchange': True} # command cmd = 'chrcrelationship' cmdargs = [self.rname] self.log("updating chrcrelationship %s with properties %s", cmd, cmdopts) # Run command self.restapi.svc_run_command(cmd, cmdopts, cmdargs) self.changed = True self.log("Updated remote copy relationship ") def change_volume_probe(self): is_update_required = False rcrelationship_data = self.get_existing_rc() if not rcrelationship_data: self.module.fail_json( msg= "Relationship '%s' does not exists, relationship must exists before calling this module" % self.rname) if self.ismaster: if self.cvname == rcrelationship_data['master_change_vdisk_name']: self.log( "Master change volume %s is already attached to the relationship", self.cvname) elif rcrelationship_data['master_change_vdisk_name'] != '': self.module.fail_json( msg= "Master change volume %s is already attached to the relationship" % rcrelationship_data['master_change_vdisk_name']) else: is_update_required = True else: if self.cvname == rcrelationship_data['aux_change_vdisk_name']: self.log( "Aux change volume %s is already attached to the relationship", self.cvname) elif rcrelationship_data['aux_change_vdisk_name'] != '': self.module.fail_json( msg= "Aux change volume %s is already attached to the relationship" % rcrelationship_data['aux_change_vdisk_name']) else: is_update_required = True return is_update_required def change_volume_delete(self): # command cmd = 'rmvolume' cmdopts = None cmdargs = [self.cvname] # Run command self.restapi.svc_run_command(cmd, cmdopts, cmdargs) self.changed = True self.log("Delete vdisk %s", self.cvname) def change_volume_create(self): if self.module.check_mode: self.changed = True return if not self.basevolume: self.module.fail_json( msg="You must pass in name of the master or auxiliary volume.") # lsvdisk <basevolume> vdisk_data = self.get_existing_vdisk(self.basevolume) if not vdisk_data: self.module.fail_json( msg="%s volume does not exist, change volume not created" % self.basevolume) # Make command cmd = 'mkvdisk' cmdopts = {} cmdopts['name'] = self.cvname cmdopts['mdiskgrp'] = vdisk_data['mdisk_grp_name'] cmdopts['size'] = vdisk_data['capacity'] cmdopts['unit'] = 'b' cmdopts['rsize'] = '0%' cmdopts['autoexpand'] = True cmdopts['iogrp'] = vdisk_data['IO_group_name'] self.log("creating vdisk command %s opts %s", cmd, cmdopts) # Run command result = self.restapi.svc_run_command(cmd, cmdopts, cmdargs=None) if 'message' in result: self.changed = True self.log("Create vdisk result message %s", result['message']) else: self.module.fail_json(msg="Failed to create vdisk [%s]" % self.cvname) def apply(self): changed = False msg = None modify = [] vdisk_data = self.get_existing_vdisk(self.cvname) if vdisk_data: if self.state == 'absent': self.log( "CHANGED: Change volume exists, requested state is 'absent'" ) changed = True elif self.state == 'present': modify = self.change_volume_probe() if modify: changed = True else: self.log("No change detected") else: if self.state == 'present': changed = True self.log( "CHANGED: Change volume does not exist, but requested state is '%s'", self.state) if changed: if self.module.check_mode: self.log('skipping changes due to check mode.') else: rcrelationship_data = self.get_existing_rc() if not rcrelationship_data: self.module.fail_json( msg= "Relationship '%s' does not exists, relationship must exists before calling this module" % self.rname) else: if self.state == 'present' and modify: self.change_volume_attach(rcrelationship_data) msg = "Change volume %s configured to the remote copy relationship." % self.cvname elif self.state == 'present': self.change_volume_create() self.change_volume_attach(rcrelationship_data) msg = "vdisk %s has been created and configured to remote copy relationship." % self.cvname elif self.state == 'absent': self.change_volume_detach(rcrelationship_data) self.change_volume_delete() msg = "vdisk %s has been deleted and detached from remote copy relationship." % self.cvname else: self.log("Exiting with no changes") if self.state in ['absent']: msg = "Change volume [%s] does not exist." % self.cvname else: msg = "No Modifications detected, Change volume [%s] already configured." % self.cvname self.module.exit_json(msg=msg, changed=changed)
class IBMSVChost(object): def __init__(self): argument_spec = svc_argument_spec() argument_spec.update( dict( name=dict(type='str', required=True), state=dict(type='str', required=True, choices=['absent', 'present']), fcwwpn=dict(type='str', required=False), iscsiname=dict(type='str', required=False), iogrp=dict(type='str', required=False, default='0:1:2:3'), protocol=dict(type='str', required=False, default='scsi', choices=['scsi', 'nvme']), type=dict(type='str') ) ) self.module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) # logging setup log_path = self.module.params['log_path'] log = get_logger(self.__class__.__name__, log_path) self.log = log.info # Required self.name = self.module.params['name'] self.state = self.module.params['state'] # Optional self.fcwwpn = self.module.params.get('fcwwpn', '') self.iscsiname = self.module.params.get('iscsiname', '') self.iogrp = self.module.params.get('iogrp', '') self.protocol = self.module.params.get('protocol', '') self.type = self.module.params.get('type', '') self.restapi = IBMSVCRestApi( module=self.module, clustername=self.module.params['clustername'], domain=self.module.params['domain'], username=self.module.params['username'], password=self.module.params['password'], validate_certs=self.module.params['validate_certs'], log_path=log_path ) def get_existing_host(self): merged_result = {} data = self.restapi.svc_obj_info(cmd='lshost', cmdopts=None, cmdargs=[self.name]) if isinstance(data, list): for d in data: merged_result.update(d) else: merged_result = data return merged_result # TBD: Implement a more generic way to check for properties to modify. def host_probe(self, data): props = [] # TBD: The parameter is fcwwpn but the view has fcwwpn label. if self.type: if self.type != data['type']: props += ['type'] if self.fcwwpn: self.existing_fcwwpn = [node["WWPN"] for node in data['nodes'] if "WWPN" in node] self.input_fcwwpn = self.fcwwpn.upper().split(":") if set(self.existing_fcwwpn).symmetric_difference(set(self.input_fcwwpn)): props += ['fcwwpn'] if props is []: props = None self.log("host_probe props='%s'", data) return props def host_create(self): if self.module.check_mode: self.changed = True return if (not self.fcwwpn) and (not self.iscsiname): self.module.fail_json(msg="You must pass in fcwwpn or iscsiname " "to the module.") if self.fcwwpn and self.iscsiname: self.module.fail_json(msg="You must not pass in both fcwwpn and " "iscsiname to the module.") if not self.protocol: self.module.fail_json(msg="You must pass in protocol " "to the module.") self.log("creating host '%s'", self.name) # Make command cmd = 'mkhost' cmdopts = {'name': self.name, 'force': True} if self.fcwwpn: cmdopts['fcwwpn'] = self.fcwwpn elif self.iscsiname: cmdopts['iscsiname'] = self.iscsiname if self.protocol: cmdopts['protocol'] = self.protocol if self.iogrp: cmdopts['iogrp'] = self.iogrp if self.type: cmdopts['type'] = self.type self.log("creating host command '%s' opts '%s'", self.fcwwpn, self.type) # Run command result = self.restapi.svc_run_command(cmd, cmdopts, cmdargs=None) self.log("create host result '%s'", result) if 'message' in result: self.changed = True self.log("create host result message '%s'", (result['message'])) else: self.module.fail_json( msg="Failed to create host [%s]" % self.name) def host_fcwwpn_update(self): to_be_removed = ':'.join(list(set(self.existing_fcwwpn) - set(self.input_fcwwpn))) if to_be_removed: self.restapi.svc_run_command( 'rmhostport', {'fcwwpn': to_be_removed, 'force': True}, [self.name] ) self.log('%s removed from %s', to_be_removed, self.name) to_be_added = ':'.join(list(set(self.input_fcwwpn) - set(self.existing_fcwwpn))) if to_be_added: self.restapi.svc_run_command( 'addhostport', {'fcwwpn': to_be_added, 'force': True}, [self.name] ) self.log('%s added to %s', to_be_added, self.name) def host_update(self, modify): # update the host self.log("updating host '%s'", self.name) # TBD: Be smarter handling many properties. if 'fcwwpn' in modify: self.host_fcwwpn_update() self.changed = True self.log("fcwwpn of %s updated", self.name) if 'type' in modify: cmd = 'chhost' cmdopts = {} cmdopts['type'] = self.type cmdargs = [self.name] self.restapi.svc_run_command(cmd, cmdopts, cmdargs) # Any error will have been raised in svc_run_command # chhost does not output anything when successful. self.changed = True self.log("type of %s updated", self.name) def host_delete(self): self.log("deleting host '%s'", self.name) cmd = 'rmhost' cmdopts = None cmdargs = [self.name] self.restapi.svc_run_command(cmd, cmdopts, cmdargs) # Any error will have been raised in svc_run_command # chhost does not output anything when successful. self.changed = True def apply(self): changed = False msg = None modify = [] host_data = self.get_existing_host() if host_data: if self.state == 'absent': self.log("CHANGED: host exists, but requested " "state is 'absent'") changed = True elif self.state == 'present': # This is where we detect if chhost should be called modify = self.host_probe(host_data) if modify: changed = True else: if self.state == 'present': self.log("CHANGED: host does not exist, " "but requested state is 'present'") changed = True if changed: if self.module.check_mode: self.log('skipping changes due to check mode') else: if self.state == 'present': if not host_data: self.host_create() msg = "host %s has been created." % self.name else: # This is where we would modify self.host_update(modify) msg = "host [%s] has been modified." % self.name elif self.state == 'absent': self.host_delete() msg = "host [%s] has been deleted." % self.name else: self.log("exiting with no changes") if self.state == 'absent': msg = "host [%s] did not exist." % self.name else: msg = "host [%s] already exists." % self.name self.module.exit_json(msg=msg, changed=changed)
class IBMSVCvdisk(object): def __init__(self): argument_spec = svc_argument_spec() argument_spec.update( dict(name=dict(type='str', required=True), state=dict(type='str', required=True, choices=['absent', 'present']), mdiskgrp=dict(type='str', required=False), size=dict(type='str', required=False), unit=dict(type='str', default='mb', choices=['b', 'kb', 'mb', 'gb', 'tb', 'pb']), easytier=dict(type='str', choices=['on', 'off']), rsize=dict(type='str', required=False), autoexpand=dict(type='bool', required=False))) self.module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) self.resizevdisk_flag = False self.expand_flag = False self.shrink_flag = False # logging setup log_path = self.module.params['log_path'] log = get_logger(self.__class__.__name__, log_path) self.log = log.info # Required self.name = self.module.params['name'] self.state = self.module.params['state'] # Optional self.mdiskgrp = self.module.params['mdiskgrp'] self.size = self.module.params['size'] self.unit = self.module.params['unit'] self.easytier = self.module.params.get('easytier', None) self.rsize = self.module.params['rsize'] self.autoexpand = self.module.params['autoexpand'] # Handling missing mandatory parameter name if not self.name: self.module.fail_json('Missing mandatory parameter: name') self.restapi = IBMSVCRestApi( module=self.module, clustername=self.module.params['clustername'], domain=self.module.params['domain'], username=self.module.params['username'], password=self.module.params['password'], validate_certs=self.module.params['validate_certs'], log_path=log_path, token=self.module.params['token']) def convert_to_bytes(self): return int(self.size) * (1024**(['b', 'kb', 'mb', 'gb', 'tb', 'pb' ].index((self.unit).lower()))) def get_existing_vdisk(self): self.log("Entering function get_existing_vdisk") cmd = 'lsvdisk' cmdargs = {} cmdopts = {'bytes': True} cmdargs = [self.name] existing_vdisk_data = self.restapi.svc_obj_info(cmd, cmdopts, cmdargs) return existing_vdisk_data # TBD: Implement a more generic way to check for properties to modify. def vdisk_probe(self, data): props = [] # Check if change in vdisk size is required input_size = int(self.convert_to_bytes()) actual_size = int(data[0]['capacity']) if self.size: if input_size != actual_size: props += ['resize'] if input_size > actual_size: self.expand_flag = True self.change_in_size = input_size - actual_size else: self.shrink_flag = True self.change_in_size = actual_size - input_size # TBD: The parameter is easytier but the view has easy_tier label. if self.easytier: if self.easytier != data[1]['easy_tier']: props += ['easytier'] self.log("vdisk_probe props='%s'", props) return props def detect_vdisk_type(self, data): isMirrored = False if data[0]['type'] == "many": isMirrored = True if not isMirrored: relationship_name = data[0]['RC_name'] if relationship_name: rel_data = self.restapi.svc_obj_info( cmd='lsrcrelationship', cmdopts=None, cmdargs=[relationship_name]) if rel_data['copy_type'] == "activeactive": isMirrored = True if isMirrored: self.module.fail_json( msg="Mirror volumes cannot be managed using this module.\ To manage mirror volumes, module 'ibm_svc_manange_mirrored_volume' can be used" ) def resizevdisk(self): cmdopts = {} if self.expand_flag: cmd = "expandvdisksize" elif self.shrink_flag: cmd = "shrinkvdisksize" cmdopts["size"] = str(self.change_in_size) cmdopts["unit"] = "b" cmdargs = [self.name] self.restapi.svc_run_command(cmd, cmdopts, cmdargs) self.changed = True def vdisk_create(self): if not self.mdiskgrp: self.module.fail_json(msg="You must pass in " "mdiskgrp to the module.") if not self.size: self.module.fail_json(msg="You must pass in size to the module.") if not self.unit: self.module.fail_json(msg="You must pass in unit to the module.") if self.module.check_mode: self.changed = True return self.log("creating vdisk '%s'", self.name) # Make command cmd = 'mkvdisk' cmdopts = {} if self.mdiskgrp: cmdopts['mdiskgrp'] = self.mdiskgrp if self.size: cmdopts['size'] = self.size if self.unit: cmdopts['unit'] = self.unit if self.easytier: cmdopts['easytier'] = self.easytier if self.rsize: cmdopts['rsize'] = self.rsize if self.autoexpand: cmdopts['autoexpand'] = self.autoexpand cmdopts['name'] = self.name self.log("creating vdisk command %s opts %s", cmd, cmdopts) # Run command result = self.restapi.svc_run_command(cmd, cmdopts, cmdargs=None) self.log("create vdisk result %s", result) if 'message' in result: self.changed = True self.log("create vdisk result message %s", result['message']) else: self.module.fail_json(msg="Failed to create vdisk [%s]" % self.name) def vdisk_update(self, modify): self.log("updating vdisk '%s'", self.name) if 'resize' in modify and 'easytier' in modify: self.module.fail_json( msg= "You cannot resize a volume while modifying other attributes") if self.module.check_mode: self.changed = True return if 'resize' in modify: self.resizevdisk() self.changed = True elif 'easytier' in modify: cmd = 'chvdisk' cmdopts = {} cmdopts['easytier'] = self.easytier cmdargs = [self.name] self.restapi.svc_run_command(cmd, cmdopts, cmdargs) # Any error will have been raised in svc_run_command # chvdisk does not output anything when successful. self.changed = True def vdisk_delete(self): if self.module.check_mode: self.changed = True return self.log("deleting vdisk '%s'", self.name) cmd = 'rmvdisk' cmdopts = None cmdargs = [self.name] self.restapi.svc_run_command(cmd, cmdopts, cmdargs) # Any error will have been raised in svc_run_command # chmvdisk does not output anything when successful. self.changed = True def apply(self): changed = False msg = None modify = [] vdisk_data = self.get_existing_vdisk() if vdisk_data: self.detect_vdisk_type(vdisk_data) if self.state == 'absent': self.log("CHANGED: vdisk exists, but requested " "state is 'absent'") changed = True elif self.state == 'present': # This is where we detect if chvdisk or resize should be called modify = self.vdisk_probe(vdisk_data) if modify: changed = True else: if self.state == 'present': self.log("CHANGED: vdisk does not exist, " "but requested state is 'present'") changed = True if changed: if self.state == 'present': if not vdisk_data: self.vdisk_create() msg = "vdisk [%s] has been created." % self.name else: # This is where we would modify self.vdisk_update(modify) msg = "vdisk [%s] has been modified." % self.name elif self.state == 'absent': self.vdisk_delete() msg = "vdisk [%s] has been deleted." % self.name if self.module.check_mode: msg = 'skipping changes due to check mode' else: self.log("exiting with no changes") if self.state == 'absent': msg = "vdisk [%s] did not exist." % self.name else: msg = "vdisk [%s] already exists." % self.name self.module.exit_json(msg=msg, changed=changed)
class IBMSVChostcluster(object): def __init__(self): argument_spec = svc_argument_spec() argument_spec.update( dict( name=dict(type='str', required=True), state=dict(type='str', required=True, choices=['absent', 'present']), ownershipgroup=dict(type='str'), removeallhosts=dict(type='bool') ) ) self.changed = "" self.module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) # logging setup log_path = self.module.params['log_path'] log = get_logger(self.__class__.__name__, log_path) self.log = log.info # Required self.name = self.module.params['name'] self.state = self.module.params['state'] # Optional self.ownershipgroup = self.module.params.get('ownershipgroup', '') self.removeallhosts = self.module.params.get('removeallhosts', '') # Handling missing mandatory parameter name if not self.name: self.module.fail_json(msg='Missing mandatory parameter: name') self.restapi = IBMSVCRestApi( module=self.module, clustername=self.module.params['clustername'], domain=self.module.params['domain'], username=self.module.params['username'], password=self.module.params['password'], validate_certs=self.module.params['validate_certs'], log_path=log_path, token=self.module.params['token'] ) def get_existing_hostcluster(self): merged_result = {} data = self.restapi.svc_obj_info(cmd='lshostcluster', cmdopts=None, cmdargs=[self.name]) if isinstance(data, list): for d in data: merged_result.update(d) else: merged_result = data return merged_result def hostcluster_create(self): if self.removeallhosts: self.module.fail_json(msg="Parameter 'removeallhosts' cannot be passed while creating hostcluster") if self.module.check_mode: self.changed = True return # Make command cmd = 'mkhostcluster' cmdopts = {'name': self.name} if self.ownershipgroup: cmdopts['ownershipgroup'] = self.ownershipgroup self.log("creating host cluster command opts '%s'", self.ownershipgroup) # Run command result = self.restapi.svc_run_command(cmd, cmdopts, cmdargs=None) self.log("create host cluster result '%s'", result) if 'message' in result: self.changed = True self.log("create host cluster result message '%s'", (result['message'])) else: self.module.fail_json( msg="Failed to create host cluster [%s]" % self.name) def hostcluster_delete(self): if self.module.check_mode: self.changed = True return self.log("deleting host cluster '%s'", self.name) cmd = 'rmhostcluster' cmdopts = {} cmdargs = [self.name] if self.removeallhosts: cmdopts = {'force': True} cmdopts['removeallhosts'] = self.removeallhosts self.restapi.svc_run_command(cmd, cmdopts, cmdargs) # Any error will have been raised in svc_run_command # chhost does not output anything when successful. self.changed = True def apply(self): changed = False msg = None modify = [] hc_data = self.get_existing_hostcluster() if hc_data: if self.state == 'absent': self.log("CHANGED: host cluster exists, but requested " "state is 'absent'") changed = True else: if self.state == 'present': self.log("CHANGED: host cluster does not exist, " "but requested state is 'present'") changed = True if changed: if self.state == 'present': if not hc_data: self.hostcluster_create() msg = "host cluster %s has been created." % self.name elif self.state == 'absent': self.hostcluster_delete() msg = "host cluster [%s] has been deleted." % self.name if self.module.check_mode: msg = "skipping changes due to check mode" else: self.log("exiting with no changes") if self.state == 'absent': msg = "host cluster [%s] did not exist." % self.name else: msg = "host cluster [%s] already exists. No modifications done." % self.name self.module.exit_json(msg=msg, changed=changed)
class IBMSVCFCCG(object): def __init__(self): argument_spec = svc_argument_spec() argument_spec.update( dict(name=dict(type='str', required=True), state=dict(type='str', required=True, choices=[ 'absent', 'present', 'prestart', 'start', 'stop' ]), restore=dict(type='bool', required=False, default=False), prep=dict(type='bool', required=False, default=False), force=dict(type='bool', required=False, default=False), split=dict(type='bool', required=False, default=False), autodelete=dict(type='str', required=False, choices=['on', 'off'], default='off'))) self.module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) # logging setup log_path = self.module.params['log_path'] log = get_logger(self.__class__.__name__, log_path) self.log = log.info # Required self.name = self.module.params['name'] self.state = self.module.params['state'] # Optional self.prep = self.module.params.get('prep', False) self.autodelete = self.module.params.get('autodelete', 'off') self.restore = self.module.params.get('restore', False) self.split = self.module.params.get('split', False) self.force = self.module.params.get('force', False) self.restapi = IBMSVCRestApi( module=self.module, clustername=self.module.params['clustername'], domain=self.module.params['domain'], username=self.module.params['username'], password=self.module.params['password'], validate_certs=self.module.params['validate_certs'], log_path=log_path) def get_existing_fccg(self): merged_result = {} data = self.restapi.svc_obj_info(cmd='lsfcconsistgrp', cmdopts=None, cmdargs=[self.name]) if isinstance(data, list): for d in data: merged_result.update(d) else: merged_result = data return merged_result # TBD: Implement a more generic way to check for properties to modify. def fccg_probe(self, data): props = {} self.log("Probe which properties need to be updated...") if self.autodelete != data['autodelete']: props['autodelete'] = self.autodelete return props def fccg_create(self): self.log("creating fc consistgrp '%s'", self.name) # Make command cmd = 'mkfcconsistgrp' cmdopts = {'name': self.name} if self.autodelete == 'on': cmdopts['autodelete'] = True # Run command result = self.restapi.svc_run_command(cmd, cmdopts, cmdargs=None) self.log("create fc consistgrp result '%s'", result) if 'message' in result: self.changed = True self.log("create fc consistgrp result message '%s'", result['message']) else: self.module.fail_json(msg="Failed to create fc consistgrp [%s]" % self.name) def fccg_prestart(self): self.log("prestart fc consistgrp '%s'", self.name) # Make command cmd = 'prestartfcconsistgrp' cmdopts = {'restore': self.restore} result = self.restapi.svc_run_command(cmd, cmdopts, cmdargs=[self.name]) self.log("prestart fc consistgrp result '%s'", result) self.changed = True self.log("prestart fc consistgrp successfully") def fccg_start(self): self.log("start fc consistgrp '%s'", self.name) # Make command cmd = 'startfcconsistgrp' cmdopts = {'restore': self.restore, 'prep': self.prep} result = self.restapi.svc_run_command(cmd, cmdopts, cmdargs=[self.name]) self.changed = True self.log("start fc consistgrp successfully") def fccg_stop(self): self.log("stop fc consistgrp '%s'", self.name) # Make command cmd = 'stopfcconsistgrp' cmdopts = {'force': self.force, 'split': self.split} result = self.restapi.svc_run_command(cmd, cmdopts, cmdargs=[self.name]) self.log("stop fc consistgrp result '%s'", result) self.changed = True self.log("stop fc consistgrp successfully") def fccg_update(self, modify): if modify: self.log("updating fc consistgrp '%s'", self.name) cmd = 'chfcconsistgrp' cmdopts = {} for prop in modify: cmdopts[prop] = modify[prop] cmdargs = [self.name] self.restapi.svc_run_command(cmd, cmdopts, cmdargs) # Any error will have been raised in svc_run_command # chfcconsistgrp does not output anything when successful. self.changed = True else: self.log("No property need to be update for fccg: %s", self.name) self.changed = False def fccg_delete(self): self.log("deleting fc consistgrp '%s'", self.name) cmd = 'rmfcconsistgrp' cmdopts = {} if self.force: cmdopts['force'] = True cmdargs = [self.name] self.restapi.svc_run_command(cmd, cmdopts, cmdargs) # Any error will have been raised in svc_run_command # rmfcconsistgrp does not output anything when successful. self.changed = True def apply(self): changed = False msg = None modify = [] fccg_data = self.get_existing_fccg() if fccg_data: if self.state == 'absent': self.log("CHANGED: fc consistgrp exists, and requested " "state is 'absent'") changed = True elif self.state == 'present': # This is where we detect if chfcconsistgrp should be called modify = self.fccg_probe(fccg_data) if modify: changed = True elif self.state in ['prestart', 'start', 'stop']: changed = True self.log('The operation for the fc' 'consistgrp is %s', self.state) else: if self.state == 'present': self.log("CHANGED: fc consistgrp does not exist, " "but requested state is 'present'") changed = True if changed: if self.module.check_mode: self.log('skipping changes due to check mode') else: if self.state == 'present': if not fccg_data: self.fccg_create() msg = "fc consistgrp %s has been created." % ( self.name) else: # This is where we would modify self.fccg_update(modify) msg = "fc consistgrp [%s] has been modified." % ( self.name) elif self.state == 'absent': self.fccg_delete() msg = "fc consistgrp [%s] has been deleted." % self.name elif self.state == 'prestart': self.fccg_prestart() msg = "fc consistgrp [%s] has been prestarted." % self.name elif self.state == 'start': self.fccg_start() msg = "fc consistgrp [%s] has been started." % self.name elif self.state == 'stop': self.fccg_stop() msg = "fc consistgrp [%s] has been stopped." % self.name else: self.log("exiting with no changes") if self.state in ['absent', 'prestart', 'start', 'stop']: msg = ('fc consistgrp %s did not exist and the' 'operations is %s', self.name, self.state) self.log(msg) else: msg = "fc consistgrp [%s] already exists." % self.name self.module.exit_json(msg=msg, changed=changed)
class IBMSVCvdiskhostmap(object): def __init__(self): argument_spec = svc_argument_spec() argument_spec.update( dict( volname=dict(type='str', required=True), host=dict(type='str', required=True), state=dict(type='str', required=True, choices=['absent', 'present']), )) self.module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) # logging setup log_path = self.module.params['log_path'] log = get_logger(self.__class__.__name__, log_path) self.log = log.info # Required self.volname = self.module.params['volname'] self.host = self.module.params['host'] self.state = self.module.params['state'] # Optional self.restapi = IBMSVCRestApi( module=self.module, clustername=self.module.params['clustername'], domain=self.module.params['domain'], username=self.module.params['username'], password=self.module.params['password'], validate_certs=self.module.params['validate_certs'], log_path=log_path) def get_existing_vdiskhostmap(self): merged_result = [] data = self.restapi.svc_obj_info(cmd='lsvdiskhostmap', cmdopts=None, cmdargs=[self.volname]) if isinstance(data, list): for d in data: merged_result.append(d) elif data: merged_result = [data] return merged_result # TBD: Implement a more generic way to check for properties to modify. def vdiskhostmap_probe(self, mdata): props = [] self.log("vdiskhostmap_probe props='%s'", mdata) # TBD: The parameter is easytier but the view has easy_tier label. mapping_exist = False for data in mdata: if (self.host == data['host_name']) and (self.volname == data['name']): mapping_exist = True if not mapping_exist: props += ["map"] if props is []: props = None self.log("vdiskhostmap_probe props='%s'", props) return props def vdiskhostmap_create(self): if self.module.check_mode: self.changed = True return if not self.volname: self.module.fail_json(msg="You must pass in " "volname to the module.") if not self.host: self.module.fail_json(msg="You must pass in host " "name to the module.") self.log("creating vdiskhostmap '%s' '%s'", self.volname, self.host) # Make command cmd = 'mkvdiskhostmap' cmdopts = {'force': True} cmdopts['host'] = self.host cmdargs = [self.volname] self.log("creating vdiskhostmap command %s opts %s args %s", cmd, cmdopts, cmdargs) # Run command result = self.restapi.svc_run_command(cmd, cmdopts, cmdargs) self.log("create vdiskhostmap result %s", result) if 'message' in result: self.changed = True self.log("create vdiskhostmap result message %s", result['message']) else: self.module.fail_json(msg="Failed to create vdiskhostmap.") def vdiskhostmap_update(self, modify): # vdiskhostmap_update() doesn't actually update anything as of now, it is here just as a placeholder. # update the vdiskhostmap self.log("updating vdiskhostmap") if 'host_name' in modify: self.log("host name is changed.") if 'volname' in modify: self.log("vol name is changed.") self.changed = True def vdiskhostmap_delete(self): self.log("deleting vdiskhostmap '%s'", self.volname) cmd = 'rmvdiskhostmap' cmdopts = {} cmdopts['host'] = self.host cmdargs = [self.volname] self.restapi.svc_run_command(cmd, cmdopts, cmdargs) # Any error will have been raised in svc_run_command # chmvdisk does not output anything when successful. self.changed = True def apply(self): changed = False msg = None modify = [] vdiskhostmap_data = self.get_existing_vdiskhostmap() self.log("volume mapping data is : '%s'", vdiskhostmap_data) if vdiskhostmap_data: if self.state == 'absent': self.log("vdiskhostmap exists, " "and requested state is 'absent'") changed = True elif self.state == 'present': probe_data = self.vdiskhostmap_probe(vdiskhostmap_data) if probe_data: self.log( "vdiskhostmap does not exist, but requested state is 'present'" ) changed = True else: if self.state == 'present': self.log("vdiskhostmap does not exist, " "but requested state is 'present'") changed = True if changed: if self.module.check_mode: self.log('skipping changes due to check mode') msg = 'skipping changes due to check mode' else: if self.state == 'present': self.vdiskhostmap_create() msg = "vdiskhostmap %s %s has been created." % ( self.volname, self.host) elif self.state == 'absent': self.vdiskhostmap_delete() msg = "vdiskhostmap [%s] has been deleted." % self.volname else: self.log("exiting with no changes") if self.state == 'absent': msg = "vdiskhostmap [%s] did not exist." % self.volname else: msg = "vdiskhostmap [%s] already exists." % self.volname self.module.exit_json(msg=msg, changed=changed)
class IBMSVCManageReplication(object): def __init__(self): argument_spec = svc_argument_spec() argument_spec.update( dict(name=dict(type='str'), state=dict(type='str', required=True, choices=['present', 'absent']), remotecluster=dict(type='str'), copytype=dict(type='str', choices=['metro', 'global', 'GMCV']), master=dict(type='str'), aux=dict(type='str'), force=dict(type='bool', required=False), consistgrp=dict(type='str'), noconsistgrp=dict(type='bool', default=False), sync=dict(type='bool', default=False), cyclingperiod=dict(type='int'))) self.module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) # logging setup log_path = self.module.params['log_path'] log = get_logger(self.__class__.__name__, log_path) self.log = log.info # Required self.name = self.module.params['name'] self.state = self.module.params['state'] self.remotecluster = self.module.params['remotecluster'] # Optional self.consistgrp = self.module.params.get('consistgrp', None) self.aux = self.module.params.get('aux') self.master = self.module.params.get('master') self.sync = self.module.params.get('sync', False) self.noconsistgrp = self.module.params.get('noconsistgrp', False) self.copytype = self.module.params.get('copytype', None) self.force = self.module.params.get('force', False) self.cyclingperiod = self.module.params.get('cyclingperiod') self.restapi = IBMSVCRestApi( module=self.module, clustername=self.module.params['clustername'], domain=self.module.params['domain'], username=self.module.params['username'], password=self.module.params['password'], validate_certs=self.module.params['validate_certs'], log_path=log_path) def existing_vdisk(self, volname): merged_result = {} data = self.restapi.svc_obj_info(cmd='lsvdisk', cmdopts={'bytes': True}, cmdargs=[volname]) if not data: self.log("source volume %s does not exist", volname) return if isinstance(data, list): for d in data: merged_result.update(d) else: merged_result = data return merged_result def cycleperiod_update(self): """ Use the chrcrelationship command to update cycling period in remote copy relationship. """ if (self.copytype == 'GMCV') and (self.cyclingperiod): cmd = 'chrcrelationship' cmdopts = {} cmdopts['cycleperiodseconds'] = self.cyclingperiod cmdargs = [self.name] self.restapi.svc_run_command(cmd, cmdopts, cmdargs) else: self.log("not updating chrcrelationship with cyclingperiod %s", self.cyclingperiod) def cyclemode_update(self): """ Use the chrcrelationship command to update cycling mode in remote copy relationship. """ cmd = 'chrcrelationship' cmdopts = {} cmdargs = [self.name] if self.copytype == 'GMCV': self.log("updating chrcrelationship with cyclingmode multi") cmdopts['cyclingmode'] = 'multi' else: self.log("updating chrcrelationship with no cyclingmode") cmdopts['cyclingmode'] = 'none' self.restapi.svc_run_command(cmd, cmdopts, cmdargs) def existing_rc(self): """ find the remote copy relationships such as Metro Mirror, Global Mirror relationships visible to the system. Returns: None if no matching instances or a list including all the matching instances """ self.log('Trying to get the remote copy relationship %s', self.name) data = self.restapi.svc_obj_info(cmd='lsrcrelationship', cmdopts=None, cmdargs=[self.name]) return data def rcrelationship_probe(self, data): props = {} propscv = {} if data['consistency_group_name'] and self.noconsistgrp: props['noconsistgrp'] = self.noconsistgrp if self.consistgrp is not None and self.consistgrp != data[ 'consistency_group_name']: props['consistgrp'] = self.consistgrp if self.master is not None and self.master != data['master_vdisk_name']: props['master'] = self.master if self.aux is not None and self.aux != data['aux_vdisk_name']: props['aux'] = self.aux if self.copytype == 'global' and data['copy_type'] == 'metro': props['global'] = True if (self.copytype == 'metro' or self.copytype is None) and ( data['copy_type'] == 'global' and data['cycling_mode'] == 'multi'): self.module.fail_json( msg= "Changing relationship type from GMCV to metro is not allowed") elif (self.copytype == 'metro' or self.copytype is None) and data['copy_type'] == 'global': props['metro'] = True if self.copytype == 'GMCV' and data[ 'copy_type'] == 'global' and self.consistgrp is None: if data['cycling_mode'] != 'multi': propscv['cyclingmode'] = 'multi' if self.cyclingperiod is not None and self.cyclingperiod != int( data['cycle_period_seconds']): propscv['cycleperiodseconds'] = self.cyclingperiod if self.copytype == 'global' and (data['copy_type'] == 'global' and (data['master_change_vdisk_name'] or data['aux_change_vdisk_name'])): propscv['cyclingmode'] = 'none' if self.copytype == 'GMCV' and data['copy_type'] == 'metro': self.module.fail_json( msg= "Changing relationship type from metro to GMCV is not allowed") if self.copytype != 'metro' and self.copytype != 'global' and self.copytype != 'GMCV' and self.copytype is not None: self.module.fail_json( msg= "Unsupported mirror type: %s. Only 'global', 'metro' and 'GMCV' are supported when modifying" % self.copytype) return props, propscv def rcrelationship_update(self, modify, modifycv): """ Use the chrcrelationship command to modify certain attributes of an existing relationship, such as to add a relationship to a consistency group to remove a relationship from a consistency group. You can change one attribute at a time. """ if modify: self.log("updating chrcrelationship with properties %s", modify) cmd = 'chrcrelationship' cmdopts = {} for prop in modify: cmdopts[prop] = modify[prop] cmdargs = [self.name] self.restapi.svc_run_command(cmd, cmdopts, cmdargs) # Error(if any) will be raised in svc_run_command self.changed = True if modifycv: if 'cycleperiodseconds' in modifycv: self.cycleperiod_update() self.log("cyclingperiod in change volume updated") if 'cyclingmode' in modifycv: self.cyclemode_update() self.log("cyclingmode in change volume updated") # Error(if any) will be raised in svc_run_command self.changed = True if not modify and not modifycv: self.log("There is no property need to be updated") self.changed = False def create(self): """ Specify the mkrcrelationship command to create a new Global Mirror, Metro Mirror in the same system, forming an intrasystem Metro Mirror relationship or intersystem relationship (if it involves more than one system). Returns: a remote copy instance """ if self.module.check_mode: self.changed = True return if not self.name: self.module.fail_json(msg="You must pass in name to the module.") if not self.master: self.module.fail_json(msg="You must pass in master to the module.") if not self.aux: self.module.fail_json(msg="You must pass in aux to the module.") if not self.remotecluster: self.module.fail_json( msg="You must pass in remotecluster to the module.") self.log("Creating remote copy '%s'", self.name) # Make command cmd = 'mkrcrelationship' cmdopts = {} if self.remotecluster: cmdopts['cluster'] = self.remotecluster if self.master: cmdopts['master'] = self.master if self.aux: cmdopts['aux'] = self.aux if self.name: cmdopts['name'] = self.name if self.copytype: if self.copytype == 'global' or self.copytype == 'GMCV': cmdopts['global'] = True elif self.copytype == 'metro' or self.copytype == 'blank': pass else: msg = "Invalid parameter specified as the Copy Type(%s) when creating Remotecopy" % self.copytype self.module.fail_json(msg=msg) if self.copytype != 'GMCV' and self.cyclingperiod is not None: msg = "Provided copytype is %s. Copy Type must be GMCV when creating Remotecopy relationship with change volumes and cycling period" % self.copytype self.module.fail_json(msg=msg) if self.consistgrp: cmdopts['consistgrp'] = self.consistgrp if self.sync: cmdopts['sync'] = self.sync # Run command self.log("Command %s opts %s", cmd, cmdopts) result = self.restapi.svc_run_command(cmd, cmdopts, cmdargs=None) self.log("create remote copy result %s", result) if 'message' in result: self.changed = True data = self.existing_rc() self.log("Succeeded to create remote copy result message %s", result['message']) return data else: msg = "Failed to create remote copy [%s]" % self.name self.module.fail_json(msg=msg) def delete(self): """ Use the rmrcrelationship command to delete an existing remote copy relationship. """ cmd = 'rmrcrelationship' cmdopts = {} if self.force: cmdopts['force'] = self.force cmdargs = [self.name] result = self.restapi.svc_run_command(cmd, cmdopts, cmdargs) # Any error will have been raised in svc_run_command # Command does not output anything when successful. if result == '': self.changed = True self.log("succeeded to delete the remote copy %s", self.name) elif 'message' in result: self.changed = True self.log("delete the remote copy %s with result message %s", self.name, result['message']) else: self.module.fail_json(msg="Failed to delete the remote copy [%s]" % self.name) def ishyperswap(self, data): if data: if data['copy_type'] == "activeactive": return True def apply(self): changed = False msg = None ishyperswap = False modify = {} modifycv = {} rcrelationship_data = self.existing_rc() if rcrelationship_data: ishyperswap = self.ishyperswap(rcrelationship_data) if (ishyperswap): self.module.fail_json( msg="active-active relationships are not supported") if self.state == 'absent': self.log( "CHANGED: RemoteCopy relationship exists, requested state is 'absent'" ) changed = True elif self.state == 'present': modify, modifycv = self.rcrelationship_probe( rcrelationship_data) if modify or modifycv: changed = True else: if self.state == 'present': changed = True self.log( "CHANGED: Remotecopy relationship does not exist, but requested state is '%s'", self.state) if changed: if self.module.check_mode: self.log('skipping changes due to check mode.') else: if self.state == 'present': if not rcrelationship_data: self.create() if self.copytype == 'GMCV' and self.consistgrp is None: self.cycleperiod_update() self.cyclemode_update() msg = "remote copy relationship with change volume %s has been created." % self.name else: msg = "remote copy relationship %s has been created." % self.name else: self.rcrelationship_update(modify, modifycv) msg = "remote copy relationship [%s] has been modified." % self.name elif self.state == 'absent': self.delete() msg = "remote copy relationship [%s] has been deleted." % self.name else: self.log("exiting with no changes") if self.state in ['absent']: msg = "Remotecopy relationship [%s] does not exist." % self.name else: msg = "No Modifications detected, Remotecopy relationship [%s] already exists." % self.name self.module.exit_json(msg=msg, changed=changed)
class IBMSVCFlashcopy(object): def __init__(self): argument_spec = svc_argument_spec() argument_spec.update( dict(name=dict(type='str', required=True), copytype=dict(type='str', required=False, choices=['snapshot', 'clone']), source=dict(type='str', required=False), target=dict(type='str', required=False), mdiskgrp=dict(type='str', required=False), state=dict(type='str', required=True, choices=['present', 'absent']), consistgrp=dict(type='str', required=False), noconsistgrp=dict(type='bool', required=False), copyrate=dict(type='str', required=False), grainsize=dict(type='str', required=False), force=dict(type='bool', required=False))) self.module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) # logging setup log_path = self.module.params['log_path'] log = get_logger(self.__class__.__name__, log_path) self.log = log.info # Required self.name = self.module.params['name'] self.state = self.module.params['state'] # Optional self.copytype = self.module.params.get('copytype', False) self.source = self.module.params.get('source', False) self.target = self.module.params.get('target', False) self.mdiskgrp = self.module.params.get('mdiskgrp', False) self.consistgrp = self.module.params.get('consistgrp', False) self.noconsistgrp = self.module.params.get('noconsistgrp', False) self.grainsize = self.module.params.get('grainsize', False) self.copyrate = self.module.params.get('copyrate', False) self.force = self.module.params.get('force', False) # Handline for mandatory parameter name if not self.name: self.module.fail_json(msg="Missing mandatory parameter: name") # Handline for mandatory parameter state if not self.state: self.module.fail_json(msg="Missing mandatory parameter: state") self.restapi = IBMSVCRestApi( module=self.module, clustername=self.module.params['clustername'], domain=self.module.params['domain'], username=self.module.params['username'], password=self.module.params['password'], validate_certs=self.module.params['validate_certs'], log_path=log_path, token=self.module.params['token']) def run_command(self, cmd): return self.restapi.svc_obj_info(cmd=cmd[0], cmdopts=cmd[1], cmdargs=cmd[2]) def gather_data(self): result = [None, None, None, []] commands = [["lsfcmap", None, [self.name]]] if self.state == "present" and self.source: commands.append([ "lsvdisk", { 'bytes': True, 'filtervalue': 'name=%s' % self.source }, None ]) if self.state == "present" and self.target: commands.append([ "lsvdisk", { 'bytes': True, 'filtervalue': 'name=%s' % self.target }, None ]) commands.append([ "lsvdisk", { 'bytes': True, 'filtervalue': 'name=%s' % self.target + "_temp_*" }, None ]) res = list(map(self.run_command, commands)) if len(res) == 1: result[0] = res[0] elif len(res) == 2: result[0] = res[0] result[1] = res[1] elif len(res) == 4: result = res return result def target_create(self, temp_target_name, sdata): cmd = 'mkvdisk' cmdopts = {} cmdopts['name'] = temp_target_name if self.mdiskgrp: cmdopts['mdiskgrp'] = self.mdiskgrp else: cmdopts['mdiskgrp'] = sdata['mdisk_grp_name'] cmdopts['size'] = sdata['capacity'] cmdopts['unit'] = 'b' cmdopts['iogrp'] = sdata['IO_group_name'] if self.copytype == 'snapshot': cmdopts['rsize'] = '0%' cmdopts['autoexpand'] = True if self.module.check_mode: self.changed = True return self.log("Creating vdisk.. Command %s opts %s", cmd, cmdopts) # Run command result = self.restapi.svc_run_command(cmd, cmdopts, cmdargs=None) self.log("Create target volume result %s", result) if 'message' in result: self.changed = True self.log("Create target volume result message %s", result['message']) else: self.module.fail_json(msg="Failed to create target volume [%s]" % self.target) def fcmap_create(self, temp_target_name): if self.copyrate: if self.copytype == 'clone': if int(self.copyrate) not in range(1, 151): self.module.fail_json( msg="Copyrate for clone must be in range 1-150") if self.copytype == 'snapshot': if int(self.copyrate) not in range(0, 151): self.module.fail_json( msg="Copyrate for snapshot must be in range 0-150") else: if self.copytype == 'clone': self.copyrate = 50 elif self.copytype == 'snapshot': self.copyrate = 0 if self.module.check_mode: self.changed = True return cmd = 'mkfcmap' cmdopts = {} cmdopts['name'] = self.name cmdopts['source'] = self.source cmdopts['target'] = temp_target_name cmdopts['copyrate'] = self.copyrate if self.grainsize: cmdopts['grainsize'] = self.grainsize if self.consistgrp: cmdopts['consistgrp'] = self.consistgrp if self.copytype == 'clone': cmdopts['autodelete'] = True self.log("Creating fc mapping.. Command %s opts %s", cmd, cmdopts) # Run command result = self.restapi.svc_run_command(cmd, cmdopts, cmdargs=None) self.log("Create flash copy mapping relationship result %s", result) if 'message' in result: self.changed = True self.log( "Create flash copy mapping relationship result " "message %s", result['message']) else: self.module.fail_json(msg="Failed to create FlashCopy mapping " "relationship [%s]" % self.name) def fcmap_delete(self): self.log("Deleting flash copy mapping relationship'%s'", self.name) if self.module.check_mode: self.changed = True return cmd = 'rmfcmap' cmdopts = {} if self.force: cmdopts['force'] = self.force self.restapi.svc_run_command(cmd, cmdopts, cmdargs=[self.name]) def rename_temp_to_target(self, temp_name): if self.module.check_mode: self.changed = True return cmd = 'chvdisk' cmdopts = {} cmdopts['name'] = self.target self.log("Rename %s to %s", cmd, cmdopts) self.restapi.svc_run_command(cmd, cmdopts, cmdargs=[temp_name]) def fcmap_probe(self, data): props = {} props_not_supported = [] if self.source: if data["source_vdisk_name"] != self.source: props_not_supported.append("source") if self.target: if data["target_vdisk_name"] != self.target: props_not_supported.append("target") if self.copytype: if (self.copytype == "snapshot" and data['autodelete'] == "on") or (self.copytype == "clone" and data["autodelete"] != "on"): props_not_supported.append("copytype") if self.grainsize: if data['grain_size'] != self.grainsize: props_not_supported.append("grainsize") if props_not_supported: self.module.fail_json(msg="Update not supported for parameter: " + ", ".join(props_not_supported)) self.log("Probe which properties need to be updated...") if data['group_name'] and self.noconsistgrp: props['consistgrp'] = 0 if not self.noconsistgrp: if self.consistgrp: if self.consistgrp != data['group_name']: props['consistgrp'] = self.consistgrp if self.copyrate: if self.copyrate != data['copy_rate']: props['copyrate'] = self.copyrate return props def fcmap_update(self, modify): if self.module.check_mode: self.changed = True return if modify: self.log("updating fcmap with properties %s", modify) cmd = 'chfcmap' cmdopts = {} for prop in modify: cmdopts[prop] = modify[prop] cmdargs = [self.name] self.restapi.svc_run_command(cmd, cmdopts, cmdargs) def apply(self): changed = False msg = None modify = [] mdata, sdata, tdata, temp = self.gather_data() if mdata: if self.state == "present": modify = self.fcmap_probe(mdata) if modify: changed = True else: msg = "mapping [%s] already exists" % self.name elif self.state == "absent": changed = True else: if self.state == "present": if not sdata: self.module.fail_json( msg="The source volume [%s] doesn't exist." % self.source) if tdata: if sdata[0]["capacity"] == tdata[0]["capacity"]: if self.copytype == 'clone': msg = "target [%s] already exists." % self.target elif self.copytype == 'snapshot': msg = "target [%s] already exists, fcmap would not be created." % self.target elif sdata[0]["capacity"] != tdata[0]["capacity"]: self.module.fail_json( msg="source and target must be of same size") if sdata and not tdata: changed = True elif self.state == "absent": msg = "mapping [%s] does not exist" % self.name if changed: if self.state == "present" and not modify: if None in [self.source, self.target, self.copytype]: self.module.fail_json( msg= "Required while creating FlashCopy mapping: 'source', 'target' and 'copytype'" ) temp_target = "%s_temp_%s" % (self.target, time.time()) if len(temp) == 0: self.target_create(temp_target, sdata[0]) self.fcmap_create(temp_target) self.rename_temp_to_target(temp_target) msg = "mapping [%s] has been created" % self.name elif len(temp) == 1: self.fcmap_create(temp[0]["name"]) self.rename_temp_to_target(temp[0]["name"]) msg = "mapping [%s] has been created" % self.name elif len(temp) > 1: self.module.fail_json( msg="Multiple %s_temp_* volumes exists" % self.target) elif self.state == "present" and modify: self.fcmap_update(modify) msg = "mapping [%s] has been modified" % self.name elif self.state == "absent": self.fcmap_delete() msg = "mapping [%s] has been deleted" % self.name if self.module.check_mode: msg = 'skipping changes due to check mode.' else: if self.state == "absent": msg = "mapping [%s] does not exist" % self.name self.module.exit_json(msg=msg, changed=changed)
class IBMSVCGatherInfo(object): def __init__(self): argument_spec = svc_argument_spec() argument_spec.update( dict( name=dict(type='str', required=True), state=dict(type='str', default='info', choices=['info']), objectname=dict(type='str'), gather_subset=dict(type='list', required=False, default=['all'], choices=[ 'vol', 'pool', 'node', 'iog', 'host', 'hc', 'fc', 'fcport', 'targetportfc', 'iscsiport', 'fcmap', 'rcrelationship', 'fcconsistgrp', 'rcconsistgrp', 'vdiskcopy', 'array', 'system', 'all' ]), )) self.module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) # logging setup log_path = self.module.params['log_path'] self.log = get_logger(self.__class__.__name__, log_path) self.name = self.module.params['name'] self.objectname = self.module.params['objectname'] self.restapi = IBMSVCRestApi( module=self.module, clustername=self.module.params['clustername'], domain=self.module.params['domain'], username=self.module.params['username'], password=self.module.params['password'], validate_certs=self.module.params['validate_certs'], log_path=log_path) def get_volumes_list(self): try: cmdargs = [self.objectname] if self.objectname else None vols = self.restapi.svc_obj_info(cmd='lsvdisk', cmdopts=None, cmdargs=cmdargs) self.log.info("Successfully listed %d volumes from array %s", len(vols), self.module.params['clustername']) return vols except Exception as e: msg = ('Get Volumes from array %s failed with error %s ', self.module.params['clustername'], str(e)) self.log.error(msg) self.module.fail_json(msg=msg) def get_pools_list(self): try: cmdargs = [self.objectname] if self.objectname else None pools = self.restapi.svc_obj_info(cmd='lsmdiskgrp', cmdopts=None, cmdargs=cmdargs) self.log.info('Successfully listed %d pools from array ' '%s', len(pools), self.module.params['clustername']) return pools except Exception as e: msg = ('Get Pools from array %s failed with error %s ', self.module.params['clustername'], str(e)) self.log.error(msg) self.module.fail_json(msg=msg) def get_nodes_list(self): try: cmdargs = [self.objectname] if self.objectname else None nodes = self.restapi.svc_obj_info(cmd='lsnode', cmdopts=None, cmdargs=cmdargs) self.log.info('Successfully listed %d pools from array %s', len(nodes), self.module.params['clustername']) return nodes except Exception as e: msg = ('Get Nodes from array %s failed with error %s ', self.module.params['clustername'], str(e)) self.log.error(msg) self.module.fail_json(msg=msg) def get_hosts_list(self): try: cmdargs = [self.objectname] if self.objectname else None hosts = self.restapi.svc_obj_info(cmd='lshost', cmdopts=None, cmdargs=cmdargs) self.log.info('Successfully listed %d hosts from array ' '%s', len(hosts), self.module.params['clustername']) return hosts except Exception as e: msg = ('Get Hosts from array %s failed with error %s ', self.module.params['clustername'], str(e)) self.log.error(msg) self.module.fail_json(msg=msg) def get_iogroups_list(self): try: cmdargs = [self.objectname] if self.objectname else None iogrps = self.restapi.svc_obj_info(cmd='lsiogrp', cmdopts=None, cmdargs=cmdargs) self.log.info('Successfully listed %d hosts from array ' '%s', len(iogrps), self.module.params['clustername']) return iogrps except Exception as e: msg = ('Get IO Groups from array %s failed with error %s ', self.module.params['clustername'], str(e)) self.log.error(msg) self.module.fail_json(msg=msg) def get_host_clusters_list(self): try: cmdargs = [self.objectname] if self.objectname else None hcs = self.restapi.svc_obj_info(cmd='lshostcluster', cmdopts=None, cmdargs=cmdargs) self.log.info( 'Successfully listed %d host clusters from array ' '%s', len(hcs), self.module.params['clustername']) return hcs except Exception as e: msg = ('Get Host Cluster from array %s failed with error %s ', self.module.params['clustername'], str(e)) self.log.error(msg) self.module.fail_json(msg=msg) def get_fc_connectivity_list(self): try: cmdargs = [self.objectname] if self.objectname else None fc = self.restapi.svc_obj_info(cmd='lsfabric', cmdopts=None, cmdargs=cmdargs) self.log.info( 'Successfully listed %d fc connectivity from array ' '%s', len(fc), self.module.params['clustername']) return fc except Exception as e: msg = ('Get FC Connectivity from array %s failed with error %s ', self.module.params['clustername'], str(e)) self.log.error(msg) self.module.fail_json(msg=msg) def get_fc_ports_list(self): try: cmdargs = [self.objectname] if self.objectname else None fcports = self.restapi.svc_obj_info(cmd='lsportfc', cmdopts=None, cmdargs=cmdargs) self.log.info('Successfully listed %d fc ports from array %s', len(fcports), self.module.params['clustername']) return fcports except Exception as e: msg = ('Get fc ports from array %s failed with error %s ', self.module.params['clustername'], str(e)) self.log.error(msg) self.module.fail_json(msg=msg) def get_target_port_fc_list(self): try: cmdargs = [self.objectname] if self.objectname else None targetportfc = self.restapi.svc_obj_info(cmd='lstargetportfc', cmdopts=None, cmdargs=cmdargs) self.log.info( 'Successfully listed %d target port fc ' 'from array %s', len(targetportfc), self.module.params['clustername']) return targetportfc except Exception as e: msg = ('Get target port fc from array %s failed with error %s ', self.module.params['clustername'], str(e)) self.log.error(msg) self.module.fail_json(msg=msg) def get_iscsi_ports_list(self): try: cmdargs = [self.objectname] if self.objectname else None ipports = self.restapi.svc_obj_info(cmd='lsportip', cmdopts=None, cmdargs=cmdargs) self.log.info('Successfully listed %d iscsi ports from array %s', len(ipports), self.module.params['clustername']) return ipports except Exception as e: msg = ('Get iscsi ports from array %s failed with error %s ', self.module.params['clustername'], str(e)) self.log.error(msg) self.module.fail_json(msg=msg) def get_fc_map_list(self): try: cmdargs = [self.objectname] if self.objectname else None fcmaps = self.restapi.svc_obj_info(cmd='lsfcmap', cmdopts=None, cmdargs=cmdargs) self.log.info('Successfully listed %d fc maps from array %s', len(fcmaps), self.module.params['clustername']) return fcmaps except Exception as e: msg = ('Get fc maps from array %s failed with error %s ', self.module.params['clustername'], str(e)) self.log.error(msg) self.module.fail_json(msg=msg) def get_rcrel_list(self): try: cmdargs = [self.objectname] if self.objectname else None rcrel = self.restapi.svc_obj_info(cmd='lsrcrelationship', cmdopts=None, cmdargs=cmdargs) self.log.info('Successfully listed %d remotecopy from array %s', len(rcrel), self.module.params['clustername']) return rcrel except Exception as e: msg = ('Get remotecopies from array %s failed with error %s ', self.module.params['clustername'], str(e)) self.log.error(msg) self.module.fail_json(msg=msg) def get_array_list(self): try: cmdargs = [self.objectname] if self.objectname else None array = self.restapi.svc_obj_info(cmd='lsarray', cmdopts=None, cmdargs=cmdargs) self.log.info('Successfully listed %d array info from array %s', len(array), self.module.params['clustername']) return array except Exception as e: msg = ('Get Array info from array %s failed with error %s ', self.module.params['clustername'], str(e)) self.log.error(msg) self.module.fail_json(msg=msg) def get_system_list(self): try: cmdargs = [self.objectname] if self.objectname else None if self.objectname: self.log.warn( 'The objectname %s is ignored when retrieving ' 'the system information', self.objectname) system = self.restapi.svc_obj_info(cmd='lssystem', cmdopts=None, cmdargs=None) self.log.info('Successfully listed %d system info from array %s', len(system), self.module.params['clustername']) return system except Exception as e: msg = ('Get System info from array %s failed with error %s ', self.module.params['clustername'], str(e)) self.log.error(msg) self.module.fail_json(msg=msg) def get_fcconsistgrp_list(self): try: cmdargs = [self.objectname] if self.objectname else None fcconsistgrp = self.restapi.svc_obj_info(cmd='lsfcconsistgrp', cmdopts=None, cmdargs=cmdargs) self.log.info( 'Successfully listed %d fcconsistgrp info ' 'from array %s', len(fcconsistgrp), self.module.params['clustername']) return fcconsistgrp except Exception as e: msg = ('Get fcconsistgrp info from array %s failed with error %s ', self.module.params['clustername'], str(e)) self.log.error(msg) self.module.fail_json(msg=msg) def get_rcconsistgrp_list(self): try: cmdargs = [self.objectname] if self.objectname else None rcconsistgrp = self.restapi.svc_obj_info(cmd='lsrcconsistgrp', cmdopts=None, cmdargs=cmdargs) self.log.info( 'Successfully listed %d rcconsistgrp info ' 'from array %s', len(rcconsistgrp), self.module.params['clustername']) return rcconsistgrp except Exception as e: msg = ('Get rcconsistgrp info from array %s failed with error %s ', self.module.params['clustername'], str(e)) self.log.error(msg) self.module.fail_json(msg=msg) def get_vdiskcopy_list(self): try: cmdargs = [self.objectname] if self.objectname else None vdiskcopy = self.restapi.svc_obj_info(cmd='lsvdiskcopy', cmdopts=None, cmdargs=cmdargs) self.log.info( 'Successfully listed %d vdiskcopy info ' 'from array %s', len(vdiskcopy), self.module.params['clustername']) return vdiskcopy except Exception as e: msg = ('Get vdiskcopy info from array %s failed with error %s ', self.module.params['clustername'], str(e)) self.log.error(msg) self.module.fail_json(msg=msg) def apply(self): all = [ 'vol', 'pool', 'node', 'iog', 'host', 'hc', 'fc', 'fcport', 'iscsiport', 'fcmap', 'rcrelationship', 'fcconsistgrp', 'rcconsistgrp', 'vdiskcopy', 'targetportfc', 'array', 'system' ] subset = self.module.params['gather_subset'] if self.objectname and len(subset) != 1: msg = ( "objectname(%s) is specified while gather_subset(%s) is not " "one of %s" % (self.objectname, self.subset, all)) self.module.fail_json(msg=msg) if len(subset) == 0 or 'all' in subset: self.log.info("The default value for gather_subset is all") subset = all vol = [] pool = [] node = [] iog = [] host = [] hc = [] fc = [] fcport = [] targetportfc = [] iscsiport = [] fcmap = [] fcconsistgrp = [] rcrelationship = [] rcconsistgrp = [] vdiskcopy = [] array = [] system = [] if 'vol' in subset: vol = self.get_volumes_list() if 'pool' in subset: pool = self.get_pools_list() if 'node' in subset: node = self.get_nodes_list() if 'iog' in subset: iog = self.get_iogroups_list() if 'host' in subset: host = self.get_hosts_list() if 'hc' in subset: hc = self.get_host_clusters_list() if 'fc' in subset: fc = self.get_fc_connectivity_list() if 'targetportfc' in subset: targetportfc = self.get_target_port_fc_list() if 'fcport' in subset: fcport = self.get_fc_ports_list() if 'iscsiport' in subset: iscsiport = self.get_iscsi_ports_list() if 'fcmap' in subset: fcmap = self.get_fc_map_list() if 'fcconsistgrp' in subset: fcconsistgrp = self.get_fcconsistgrp_list() if 'rcrelationship' in subset: rcrelationship = self.get_rcrel_list() if 'rcconsistgrp' in subset: rcconsistgrp = self.get_rcconsistgrp_list() if 'vdiskcopy' in subset: vdiskcopy = self.get_vdiskcopy_list() if 'array' in subset: array = self.get_array_list() if 'system' in subset: system = self.get_system_list() self.module.exit_json(Volume=vol, Pool=pool, Node=node, IOGroup=iog, Host=host, HostCluster=hc, FCConnectivitie=fc, FCConsistgrp=fcconsistgrp, RCConsistgrp=rcconsistgrp, VdiskCopy=vdiskcopy, FCPort=fcport, TargetPortFC=targetportfc, iSCSIPort=iscsiport, FCMap=fcmap, RemoteCopy=rcrelationship, Array=array, System=system)