예제 #1
0
    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'])
예제 #4
0
    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'])
예제 #7
0
    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', {}, [])
예제 #12
0
    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)
예제 #16
0
    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)
예제 #20
0
    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
        )
예제 #21
0
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)
예제 #24
0
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)
예제 #30
0
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)