Ejemplo n.º 1
0
def make_multi_hosts(module):
    """Create multiple hosts"""
    changed = True
    if not module.check_mode:
        hosts = []
        array = get_array(module)
        for host_num in range(module.params["start"],
                              module.params["count"] + module.params["start"]):
            hosts.append(module.params["name"] +
                         str(host_num).zfill(module.params["digits"]) +
                         module.params["suffix"])
        if module.params["personality"]:
            host = flasharray.HostPost(
                personality=module.params["personality"])
        else:
            host = flasharray.HostPost()
        res = array.post_hosts(names=hosts, host=host)
        if res.status_code != 200:
            module.fail_json(
                msg="Multi-Host {0}#{1} creation failed: {2}".format(
                    module.params["name"],
                    module.params["suffix"],
                    res.errors[0].message,
                ))
    module.exit_json(changed=changed)
Ejemplo n.º 2
0
def get_multi_hosts(module):
    """Return True is all hosts exist"""
    hosts = []
    array = get_array(module)
    for host_num in range(module.params['start'], module.params['count'] + module.params['start']):
        hosts.append(module.params['name'] + str(host_num).zfill(module.params['digits']) + module.params['suffix'])
    return bool(array.get_hosts(names=hosts).status_code == 200)
Ejemplo n.º 3
0
def main():
    argument_spec = purefa_argument_spec()
    argument_spec.update(
        dict(
            address=dict(type="str", required=True),
            protocol=dict(type="str",
                          choices=["tcp", "tls", "udp"],
                          required=True),
            port=dict(type="str"),
            name=dict(type="str"),
            state=dict(type="str",
                       default="present",
                       choices=["absent", "present"]),
        ))

    module = AnsibleModule(argument_spec, supports_check_mode=True)

    array = get_system(module)

    if module.params["name"] and not HAS_PURESTORAGE:
        module.fail_json(msg="py-pure-client sdk is required for this module")

    api_version = array._list_available_rest_versions()

    if SYSLOG_NAME_API in api_version and module.params["name"]:
        arrayv6 = get_array(module)
    else:
        arrayv6 = None

    if module.params["state"] == "absent":
        delete_syslog(module, array)
    else:
        add_syslog(module, array, arrayv6)

    module.exit_json(changed=False)
Ejemplo n.º 4
0
def main():
    argument_spec = purefa_argument_spec()
    argument_spec.update(
        dict(
            state=dict(type="str",
                       default="present",
                       choices=["absent", "present"]),
            nfs_access=dict(
                type="str",
                default="root-squash",
                choices=["root-squash", "no-root-squash"],
            ),
            nfs_permission=dict(type="str", default="rw", choices=["rw",
                                                                   "ro"]),
            policy=dict(type="str",
                        required=True,
                        choices=["nfs", "smb", "snapshot"]),
            name=dict(type="str", required=True),
            rename=dict(type="str"),
            client=dict(type="str"),
            enabled=dict(type="bool", default=True),
            snap_at=dict(type="str"),
            snap_every=dict(type="int"),
            snap_keep_for=dict(type="int"),
            snap_client_name=dict(type="str"),
            smb_anon_allowed=dict(type="bool", default=False),
            smb_encrypt=dict(type="bool", default=False),
        ))

    required_together = [["snap_keep_for", "snap_every"]]
    module = AnsibleModule(argument_spec,
                           required_together=required_together,
                           supports_check_mode=True)

    if not HAS_PURESTORAGE:
        module.fail_json(msg="py-pure-client sdk is required for this module")

    array = get_system(module)
    api_version = array._list_available_rest_versions()
    if MIN_REQUIRED_API_VERSION not in api_version:
        module.fail_json(
            msg="FlashArray REST version not supported. "
            "Minimum version required: {0}".format(MIN_REQUIRED_API_VERSION))
    array = get_array(module)
    state = module.params["state"]

    exists = bool(
        array.get_policies(names=[module.params["name"]]).status_code == 200)

    if state == "present" and not exists:
        create_policy(module, array)
    elif state == "present" and exists and module.params["rename"]:
        rename_policy(module, array)
    elif state == "present" and exists:
        update_policy(module, array)
    elif state == "absent" and exists:
        delete_policy(module, array)

    module.exit_json(changed=False)
Ejemplo n.º 5
0
def get_multi_volumes(module, destroyed=False):
    """Return True is all volumes exist or None"""
    names = []
    array = get_array(module)
    for vol_num in range(module.params['start'],
                         module.params['count'] + module.params['start']):
        names.append(module.params['name'] +
                     str(vol_num).zfill(module.params['digits']) +
                     module.params['suffix'])
    return bool(
        array.get_volumes(names=names, destroyed=destroyed).status_code == 200)
Ejemplo n.º 6
0
def get_multi_vgroups(module, destroyed=False):
    """Return True is all volume groups exist or None"""
    names = []
    array = get_array(module)
    for vg_num in range(module.params["start"],
                        module.params["count"] + module.params["start"]):
        names.append(module.params["name"] +
                     str(vg_num).zfill(module.params["digits"]) +
                     module.params["suffix"])
    return bool(
        array.get_volume_groups(names=names, destroyed=destroyed).status_code
        == 200)
Ejemplo n.º 7
0
def create_connection(module, array):
    """Create connection between arrays"""
    changed = True
    if not module.check_mode:
        remote_array = module.params["target_url"]
        user_agent = "%(base)s %(class)s/%(version)s (%(platform)s)" % {
            "base": "Ansible",
            "class": __name__,
            "version": 1.2,
            "platform": platform.platform(),
        }
        try:
            remote_system = FlashArray(
                module.params["target_url"],
                api_token=module.params["target_api"],
                user_agent=user_agent,
            )
            connection_key = remote_system.get(
                connection_key=True)["connection_key"]
            remote_array = remote_system.get()["array_name"]
            api_version = array._list_available_rest_versions()
            # TODO: Refactor when FC async is supported
            if (FC_REPL_VERSION in api_version
                    and module.params["transport"].lower() == "fc"):
                if module.params["connection"].lower() == "async":
                    module.fail_json(
                        msg=
                        "Asynchronous replication not supported using FC transport"
                    )
                array_connection = flasharray.ArrayConnectionPost(
                    type="sync-replication",
                    management_address=module.params["target_url"],
                    replication_transport="fc",
                    connection_key=connection_key,
                )
                array = get_array(module)
                res = array.post_array_connections(
                    array_connection=array_connection)
                if res.status_code != 200:
                    module.fail_json(msg="Array Connection failed. Error: {0}".
                                     format(res.errors[0].message))
            else:
                array.connect_array(
                    module.params["target_url"],
                    connection_key,
                    [module.params["connection"]],
                )
        except Exception:
            module.fail_json(msg="Failed to connect to remote array {0}.".
                             format(remote_array))
    module.exit_json(changed=changed)
Ejemplo n.º 8
0
def main():
    argument_spec = purefa_argument_spec()
    argument_spec.update(
        dict(
            state=dict(type="str",
                       default="present",
                       choices=["absent", "present"]),
            enabled=dict(type="bool", default=True),
            name=dict(type="str", required=True),
            role=dict(
                type="str",
                choices=[
                    "readonly", "ops_admin", "storage_admin", "array_admin"
                ],
            ),
            public_key=dict(type="str", no_log=True),
            token_ttl=dict(type="int", default=86400, no_log=False),
            issuer=dict(type="str"),
        ))

    module = AnsibleModule(argument_spec, supports_check_mode=True)

    if not HAS_PURESTORAGE:
        module.fail_json(msg="py-pure-client sdk is required for this module")

    array = get_system(module)
    api_version = array._list_available_rest_versions()

    if MIN_REQUIRED_API_VERSION not in api_version:
        module.fail_json(
            msg="FlashArray REST version not supported. "
            "Minimum version required: {0}".format(MIN_REQUIRED_API_VERSION))
    array = get_array(module)
    state = module.params["state"]

    try:
        client = list(
            array.get_api_clients(names=[module.params["name"]]).items)[0]
        exists = True
    except Exception:
        exists = False

    if not exists and state == "present":
        create_client(module, array)
    elif exists and state == "present":
        update_client(module, array, client)
    elif exists and state == "absent":
        delete_client(module, array)

    module.exit_json(changed=False)
def main():
    argument_spec = purefa_argument_spec()
    argument_spec.update(
        dict(
            state=dict(type='str',
                       default='present',
                       choices=['absent', 'present']),
            filesystem=dict(type='str', required=True),
            name=dict(type='str', required=True),
            rename=dict(type='str'),
            path=dict(type='str'),
        ))

    module = AnsibleModule(argument_spec, supports_check_mode=True)

    if not HAS_PURESTORAGE:
        module.fail_json(msg='py-pure-client sdk is required for this module')

    array = get_system(module)
    api_version = array._list_available_rest_versions()
    if MIN_REQUIRED_API_VERSION not in api_version:
        module.fail_json(
            msg='FlashArray REST version not supported. '
            'Minimum version required: {0}'.format(MIN_REQUIRED_API_VERSION))
    array = get_array(module)
    state = module.params['state']

    try:
        filesystem = list(
            array.get_file_systems(
                names=[module.params['filesystem']]).items)[0]
    except Exception:
        module.fail_json(msg="Selected file system {0} does not exist".format(
            module.params['filesystem']))
    res = array.get_directories(
        names=[module.params['filesystem'] + ":" + module.params['name']])
    exists = bool(res.status_code == 200)

    if state == 'present' and not exists:
        create_dir(module, array)
    elif state == "present" and exists and module.params[
            'rename'] and not filesystem.destroyed:
        rename_dir(module, array)
    elif state == 'absent' and exists:
        delete_dir(module, array)

    module.exit_json(changed=False)
Ejemplo n.º 10
0
def main():
    argument_spec = purefa_argument_spec()
    argument_spec.update(
        dict(state=dict(type='str',
                        default='present',
                        choices=['absent', 'present']),
             enabled=dict(type='bool', default=True),
             name=dict(type='str', required=True),
             role=dict(type='str',
                       choices=[
                           'readonly', 'ops_admin', 'storage_admin',
                           'array_admin'
                       ]),
             public_key=dict(type='str', no_log=True),
             token_ttl=dict(type='int', default=86400),
             issuer=dict(type='str')))

    module = AnsibleModule(argument_spec, supports_check_mode=True)

    if not HAS_PURESTORAGE:
        module.fail_json(msg='py-pure-client sdk is required for this module')

    array = get_system(module)
    api_version = array._list_available_rest_versions()

    if MIN_REQUIRED_API_VERSION not in api_version:
        module.fail_json(
            msg='FlashArray REST version not supported. '
            'Minimum version required: {0}'.format(MIN_REQUIRED_API_VERSION))
    array = get_array(module)
    state = module.params['state']

    try:
        client = list(
            array.get_api_clients(names=[module.params['name']]).items)[0]
        exists = True
    except Exception:
        exists = False

    if not exists and state == 'present':
        create_client(module, array)
    elif exists and state == 'present':
        update_client(module, array, client)
    elif exists and state == 'absent':
        delete_client(module, array)

    module.exit_json(changed=False)
Ejemplo n.º 11
0
def main():
    argument_spec = purefa_argument_spec()
    argument_spec.update(dict(
        state=dict(type='str', default='present', choices=['absent', 'present']),
        nfs_access=dict(type='str', default='root-squash', choices=['root-squash', 'no-root-squash']),
        nfs_permission=dict(type='str', default='rw', choices=['rw', 'ro']),
        policy=dict(type='str', required=True, choices=['nfs', 'smb', 'snapshot']),
        name=dict(type='str', required=True),
        rename=dict(type='str'),
        client=dict(type='str'),
        enabled=dict(type='bool', default=True),
        snap_at=dict(type='str'),
        snap_every=dict(type='int'),
        snap_keep_for=dict(type='int'),
        snap_client_name=dict(type='str'),
        smb_anon_allowed=dict(type='bool', default=False),
        smb_encrypt=dict(type='bool', default=False),
    ))

    required_together = [['snap_keep_for', 'snap_every']]
    module = AnsibleModule(argument_spec,
                           required_together=required_together,
                           supports_check_mode=True)

    if not HAS_PURESTORAGE:
        module.fail_json(msg='py-pure-client sdk is required for this module')

    array = get_system(module)
    api_version = array._list_available_rest_versions()
    if MIN_REQUIRED_API_VERSION not in api_version:
        module.fail_json(msg='FlashArray REST version not supported. '
                             'Minimum version required: {0}'.format(MIN_REQUIRED_API_VERSION))
    array = get_array(module)
    state = module.params['state']

    exists = bool(array.get_policies(names=[module.params['name']]).status_code == 200)

    if state == 'present' and not exists:
        create_policy(module, array)
    elif state == 'present' and exists and module.params['rename']:
        rename_policy(module, array)
    elif state == 'present' and exists:
        update_policy(module, array)
    elif state == 'absent' and exists:
        delete_policy(module, array)

    module.exit_json(changed=False)
Ejemplo n.º 12
0
def generate_config_dict(module, array):
    config_info = {}
    api_version = array._list_available_rest_versions()
    config_info['console_lock'] = array.get_console_lock_status(
    )['console_lock']
    config_info['dns'] = array.get_dns()
    config_info['smtp'] = array.list_alert_recipients()
    config_info['snmp'] = array.list_snmp_managers()
    config_info['snmp_v3_engine_id'] = array.get_snmp_engine_id()['engine_id']
    try:
        config_info['directory_service'] = array.get_directory_service()
    except Exception:
        config_info['directory_service'] = [
            'Array and Data Configurations found'
        ]
    if S3_REQUIRED_API_VERSION in api_version:
        config_info['directory_service_roles'] = {}
        roles = array.list_directory_service_roles()
        for role in range(0, len(roles)):
            role_name = roles[role]['name']
            config_info['directory_service_roles'][role_name] = {
                'group': roles[role]['group'],
                'group_base': roles[role]['group_base'],
            }
    else:
        config_info['directory_service'].update(
            array.get_directory_service(groups=True))
    config_info['ntp'] = array.get(ntpserver=True)['ntpserver']
    config_info['syslog'] = array.get(syslogserver=True)['syslogserver']
    config_info['phonehome'] = array.get(phonehome=True)['phonehome']
    config_info['proxy'] = array.get(proxy=True)['proxy']
    config_info['relayhost'] = array.get(relayhost=True)['relayhost']
    config_info['senderdomain'] = array.get(senderdomain=True)['senderdomain']
    config_info['syslog'] = array.get(syslogserver=True)['syslogserver']
    config_info['idle_timeout'] = array.get(idle_timeout=True)['idle_timeout']
    config_info['scsi_timeout'] = array.get(scsi_timeout=True)['scsi_timeout']
    if S3_REQUIRED_API_VERSION in api_version:
        config_info['global_admin'] = array.get_global_admin_attributes()
    if V6_MINIMUM_API_VERSION in api_version:
        array = get_array(module)
        smi_s = list(array.get_smi_s().items)[0]
        config_info['smi-s'] = {
            'slp_enabled': smi_s.slp_enabled,
            'wbem_https_enabled': smi_s.wbem_https_enabled
        }
    return config_info
Ejemplo n.º 13
0
def make_multi_vgroups(module):
    """Create multiple Volume Groups"""
    changed = True
    if not module.check_mode:
        bw_qos_size = iops_qos_size = 0
        names = []
        array = get_array(module)
        for vg_num in range(module.params["start"],
                            module.params["count"] + module.params["start"]):
            names.append(module.params["name"] +
                         str(vg_num).zfill(module.params["digits"]) +
                         module.params["suffix"])
        if module.params["bw_qos"]:
            bw_qos = int(human_to_bytes(module.params["bw_qos"]))
            if bw_qos in range(1048576, 549755813888):
                bw_qos_size = bw_qos
            else:
                module.fail_json(msg="Bandwidth QoS value out of range.")
        if module.params["iops_qos"]:
            iops_qos = int(human_to_real(module.params["iops_qos"]))
            if iops_qos in range(100, 100000000):
                iops_qos_size = iops_qos
            else:
                module.fail_json(msg="IOPs QoS value out of range.")
        if bw_qos_size != 0 and iops_qos_size != 0:
            volume_group = flasharray.VolumeGroupPost(qos=flasharray.Qos(
                bandwidth_limit=bw_qos_size, iops_limit=iops_qos_size))
        elif bw_qos_size == 0 and iops_qos_size == 0:
            volume_group = flasharray.VolumeGroupPost()
        elif bw_qos_size == 0 and iops_qos_size != 0:
            volume_group = flasharray.VolumeGroupPost(qos=flasharray.Qos(
                iops_limit=iops_qos_size))
        elif bw_qos_size != 0 and iops_qos_size == 0:
            volume_group = flasharray.VolumeGroupPost(qos=flasharray.Qos(
                bandwidth_limit=bw_qos_size))
        res = array.post_volume_groups(names=names, volume_group=volume_group)
        if res.status_code != 200:
            module.fail_json(
                msg="Multi-Vgroup {0}#{1} creation failed: {2}".format(
                    module.params["name"],
                    module.params["suffix"],
                    res.errors[0].message,
                ))
    module.exit_json(changed=changed)
Ejemplo n.º 14
0
def main():
    argument_spec = purefa_argument_spec()
    argument_spec.update(
        dict(
            state=dict(type="str",
                       default="present",
                       choices=["absent", "present"]),
            filesystem=dict(type="str", required=True),
            directory=dict(type="str", required=True),
            name=dict(type="str", required=True),
            nfs_policy=dict(type="str"),
            smb_policy=dict(type="str"),
        ))

    required_if = [["state", "present", ["filesystem", "directory"]]]
    module = AnsibleModule(argument_spec,
                           required_if=required_if,
                           supports_check_mode=True)

    if not HAS_PURESTORAGE:
        module.fail_json(msg="py-pure-client sdk is required for this module")

    array = get_system(module)
    api_version = array._list_available_rest_versions()
    if MIN_REQUIRED_API_VERSION not in api_version:
        module.fail_json(
            msg="FlashArray REST version not supported. "
            "Minimum version required: {0}".format(MIN_REQUIRED_API_VERSION))
    array = get_array(module)
    state = module.params["state"]

    exists = bool(
        array.get_directory_exports(
            export_names=[module.params["name"]]).status_code == 200)

    if state == "present":
        create_export(module, array)
    elif state == "absent" and exists:
        delete_export(module, array)

    module.exit_json(changed=False)
Ejemplo n.º 15
0
def main():
    argument_spec = purefa_argument_spec()
    argument_spec.update(
        dict(
            state=dict(type='str',
                       default='present',
                       choices=['absent', 'present']),
            filesystem=dict(type='str', required=True),
            directory=dict(type='str', required=True),
            name=dict(type='str', required=True),
            nfs_policy=dict(type='str'),
            smb_policy=dict(type='str'),
        ))

    required_if = [['state', 'present', ['filesystem', 'directory']]]
    module = AnsibleModule(argument_spec,
                           required_if=required_if,
                           supports_check_mode=True)

    if not HAS_PURESTORAGE:
        module.fail_json(msg='py-pure-client sdk is required for this module')

    array = get_system(module)
    api_version = array._list_available_rest_versions()
    if MIN_REQUIRED_API_VERSION not in api_version:
        module.fail_json(
            msg='FlashArray REST version not supported. '
            'Minimum version required: {0}'.format(MIN_REQUIRED_API_VERSION))
    array = get_array(module)
    state = module.params['state']

    exists = bool(
        array.get_directory_exports(
            export_names=[module.params['name']]).status_code == 200)

    if state == 'present':
        create_export(module, array)
    elif state == 'absent' and exists:
        delete_export(module, array)

    module.exit_json(changed=False)
Ejemplo n.º 16
0
def main():
    argument_spec = purefa_argument_spec()
    argument_spec.update(
        dict(
            timeout=dict(type="int", default=3600),
            state=dict(type="str",
                       default="present",
                       choices=["absent", "present"]),
        ))

    module = AnsibleModule(argument_spec, supports_check_mode=True)

    if not HAS_PURESTORAGE:
        module.fail_json(msg="py-pure-client sdk is required for this module")

    array = get_array(module)

    if module.params["state"] == "absent":
        delete_window(module, array)
    else:
        set_window(module, array)

    module.exit_json(changed=False)
Ejemplo n.º 17
0
def main():
    argument_spec = purefa_argument_spec()
    argument_spec.update(
        dict(
            smis=dict(type="bool", default=True),
            slp=dict(type="bool", default=True),
        ))

    module = AnsibleModule(argument_spec, supports_check_mode=True)

    if not HAS_PURESTORAGE:
        module.fail_json(msg="py-pure-client sdk is required for this module")

    array = get_system(module)
    api_version = array._list_available_rest_versions()

    if MIN_REQUIRED_API_VERSION not in api_version:
        module.fail_json(
            msg="FlashArray REST version not supported. "
            "Minimum version required: {0}".format(MIN_REQUIRED_API_VERSION))
    array = get_array(module)

    update_smis(module, array)
Ejemplo n.º 18
0
def create_multi_volume(module, array):
    """Create Volume"""
    changed = True
    volfact = {}
    if not module.check_mode:
        bw_qos_size = iops_qos_size = 0
        names = []
        if "/" in module.params["name"] and not check_vgroup(module, array):
            module.fail_json(
                msg=
                "Multi-volume create failed. Volume Group {0} does not exist.".
                format(module.params["name"].split("/")[0]))
        if "::" in module.params["name"]:
            if not check_pod(module, array):
                module.fail_json(
                    msg="Multi-volume create failed. Pod {0} does not exist".
                    format(module.params["name"].split(":")[0]))
            pod_name = module.params["name"].split("::")[0]
            if array.get_pod(pod_name)["promotion_status"] == "demoted":
                module.fail_json(
                    msg="Volume cannot be created in a demoted pod")
        array = get_array(module)
        for vol_num in range(module.params["start"],
                             module.params["count"] + module.params["start"]):
            names.append(module.params["name"] +
                         str(vol_num).zfill(module.params["digits"]) +
                         module.params["suffix"])
        if module.params["bw_qos"]:
            bw_qos = int(human_to_bytes(module.params["bw_qos"]))
            if bw_qos in range(1048576, 549755813888):
                bw_qos_size = bw_qos
            else:
                module.fail_json(msg="Bandwidth QoS value out of range.")
        if module.params["iops_qos"]:
            iops_qos = int(human_to_real(module.params["iops_qos"]))
            if iops_qos in range(100, 100000000):
                iops_qos_size = iops_qos
            else:
                module.fail_json(msg="IOPs QoS value out of range.")
        if bw_qos_size != 0 and iops_qos_size != 0:
            vols = flasharray.VolumePost(
                provisioned=human_to_bytes(module.params["size"]),
                qos=flasharray.Qos(bandwidth_limit=bw_qos_size,
                                   iops_limit=iops_qos_size),
                subtype="regular",
            )
        elif bw_qos_size == 0 and iops_qos_size == 0:
            vols = flasharray.VolumePost(provisioned=human_to_bytes(
                module.params["size"]),
                                         subtype="regular")
        elif bw_qos_size == 0 and iops_qos_size != 0:
            vols = flasharray.VolumePost(
                provisioned=human_to_bytes(module.params["size"]),
                qos=flasharray.Qos(iops_limit=iops_qos_size),
                subtype="regular",
            )
        elif bw_qos_size != 0 and iops_qos_size == 0:
            vols = flasharray.VolumePost(
                provisioned=human_to_bytes(module.params["size"]),
                qos=flasharray.Qos(bandwidth_limit=bw_qos_size),
                subtype="regular",
            )
        res = array.post_volumes(names=names, volume=vols)
        if res.status_code != 200:
            module.fail_json(
                msg="Multi-Volume {0}#{1} creation failed: {2}".format(
                    module.params["name"],
                    module.params["suffix"],
                    res.errors[0].message,
                ))
        else:
            temp = list(res.items)
            for count in range(0, len(temp)):
                vol_name = temp[count].name
                volfact[vol_name] = {
                    "size":
                    temp[count].provisioned,
                    "serial":
                    temp[count].serial,
                    "created":
                    time.strftime("%Y-%m-%d %H:%M:%S",
                                  time.localtime(temp[count].created / 1000)),
                }
                if bw_qos_size != 0:
                    volfact[vol_name]["bandwidth_limit"] = temp[
                        count].qos.bandwidth_limit
                if iops_qos_size != 0:
                    volfact[vol_name]["iops_limit"] = temp[
                        count].qos.iops_limit

    module.exit_json(changed=changed, volfact=volfact)
def main():
    argument_spec = purefa_argument_spec()
    argument_spec.update(
        dict(
            state=dict(
                type="str",
                default="present",
                choices=["absent", "present", "import", "export", "sign"],
            ),
            generate=dict(type="bool", default=False),
            name=dict(type="str", default="management"),
            country=dict(type="str"),
            province=dict(type="str"),
            locality=dict(type="str"),
            organization=dict(type="str"),
            org_unit=dict(type="str"),
            common_name=dict(type="str"),
            email=dict(type="str"),
            key_size=dict(type="int", default=2048, choices=[1024, 2048, 4096]),
            certificate=dict(type="str", no_log=True),
            intermeadiate_cert=dict(type="str", no_log=True),
            key=dict(type="str", no_log=True),
            export_file=dict(type="str"),
            passphrase=dict(type="str", no_log=True),
            days=dict(type="int", default=3650),
        )
    )

    mutually_exclusive = [["certificate", "key_size"]]
    required_if = [
        ["state", "import", ["certificate"]],
        ["state", "export", ["export_file"]],
    ]

    module = AnsibleModule(
        argument_spec,
        mutually_exclusive=mutually_exclusive,
        required_if=required_if,
        supports_check_mode=True,
    )

    if not HAS_PURESTORAGE:
        module.fail_json(msg="py-pure-client sdk is required for this module")

    if not HAS_PYCOUNTRY:
        module.fail_json(msg="pycountry sdk is required for this module")

    email_pattern = r"^(\w|\.|\_|\-)+[@](\w|\_|\-|\.)+[.]\w{2,3}$"
    array = get_system(module)
    api_version = array._list_available_rest_versions()

    if MIN_REQUIRED_API_VERSION not in api_version:
        module.fail_json(
            msg="FlashArray REST version not supported. "
            "Minimum version required: {0}".format(MIN_REQUIRED_API_VERSION)
        )

    array = get_array(module)
    if module.params["email"]:
        if not re.search(email_pattern, module.params["email"]):
            module.fail_json(
                msg="Email {0} is not valid".format(module.params["email"])
            )
    if module.params["country"]:
        if len(module.params["country"]) != 2:
            module.fail_json(msg="Country must be a two-letter country (ISO) code")
        if not pycountry.countries.get(alpha_2=module.params["country"].upper()):
            module.fail_json(
                msg="Country code {0} is not an assigned ISO 3166-1 code".format(
                    module.params["country"].upper()
                )
            )
    state = module.params["state"]
    if state in ["present", "sign"]:
        if not module.params["common_name"]:
            module.params["common_name"] = list(array.get_arrays().items)[0].name
        module.params["common_name"] = module.params["common_name"][:64]

    exists = bool(
        array.get_certificates(names=[module.params["name"]]).status_code == 200
    )

    if not exists and state == "present":
        create_cert(module, array)
    elif exists and state == "present":
        update_cert(module, array)
    elif state == "sign":
        create_csr(module, array)
    elif not exists and state == "import":
        import_cert(module, array)
    elif state == "export":
        export_cert(module, array)
    elif exists and state == "absent":
        delete_cert(module, array)

    module.exit_json(changed=False)
Ejemplo n.º 20
0
def create_offload(module, array):
    """Create offload target"""
    changed = True
    api_version = array._list_available_rest_versions()
    if not module.check_mode:
        # First check if the offload network inteface is there and enabled
        try:
            if not array.get_network_interface('@offload.data')['enabled']:
                module.fail_json(
                    msg='Offload Network interface not enabled. Please resolve.'
                )
        except Exception:
            module.fail_json(
                msg=
                'Offload Network interface not correctly configured. Please resolve.'
            )
        if module.params['protocol'] == 'nfs':
            try:
                array.connect_nfs_offload(
                    module.params['name'],
                    mount_point=module.params['share'],
                    address=module.params['address'],
                    mount_options=module.params['options'])
            except Exception:
                module.fail_json(msg='Failed to create NFS offload {0}. '
                                 'Please perform diagnostic checks.'.format(
                                     module.params['name']))
        if module.params['protocol'] == 's3':
            if P53_API_VERSION in api_version:
                try:
                    array.connect_s3_offload(
                        module.params['name'],
                        access_key_id=module.params['access_key'],
                        secret_access_key=module.params['secret'],
                        bucket=module.params['bucket'],
                        placement_strategy=module.params['placement'],
                        initialize=module.params['initialize'])
                except Exception:
                    module.fail_json(msg='Failed to create S3 offload {0}. '
                                     'Please perform diagnostic checks.'.
                                     format(module.params['name']))
            else:
                try:
                    array.connect_s3_offload(
                        module.params['name'],
                        access_key_id=module.params['access_key'],
                        secret_access_key=module.params['secret'],
                        bucket=module.params['bucket'],
                        initialize=module.params['initialize'])
                except Exception:
                    module.fail_json(msg='Failed to create S3 offload {0}. '
                                     'Please perform diagnostic checks.'.
                                     format(module.params['name']))
        if module.params[
                'protocol'] == 'azure' and P53_API_VERSION in api_version:
            try:
                array.connect_azure_offload(
                    module.params['name'],
                    container_name=module.params['container'],
                    secret_access_key=module.params['secret'],
                    account_name=module.params['.bucket'],
                    initialize=module.params['initialize'])
            except Exception:
                module.fail_json(msg='Failed to create Azure offload {0}. '
                                 'Please perform diagnostic checks.'.format(
                                     module.params['name']))
        if module.params[
                'protocol'] == 'gcp' and GCP_API_VERSION in api_version:
            arrayv6 = get_array(module)
            bucket = flasharray.OffloadGoogleCloud(
                access_key_id=module.params['access_key'],
                bucket=module.params['bucket'],
                secret_access_key=module.params['secret'])
            offload = flasharray.OffloadPost(google_cloud=bucket)
            res = arrayv6.post_offloads(offload=offload,
                                        initialize=module.params['initialize'],
                                        names=[module.params['name']])
            if res.status_code != 200:
                module.fail_json(
                    msg='Failed to create GCP offload {0}. Error: {1}'
                    'Please perform diagnostic checks.'.format(
                        module.params['name'], res.errors[0].message))
    module.exit_json(changed=changed)
Ejemplo n.º 21
0
def main():
    argument_spec = purefa_argument_spec()
    argument_spec.update(
        dict(
            name=dict(type="str", required=True),
            suffix=dict(type="str"),
            target=dict(type="str"),
            offload=dict(type="str"),
            ignore_repl=dict(type="bool", default=False),
            overwrite=dict(type="bool", default=False),
            eradicate=dict(type="bool", default=False),
            state=dict(
                type="str",
                default="present",
                choices=["absent", "copy", "present", "rename"],
            ),
        )
    )

    required_if = [("state", "copy", ["target", "suffix"])]

    module = AnsibleModule(
        argument_spec, required_if=required_if, supports_check_mode=True
    )
    pattern = re.compile("^(?=.*[a-zA-Z-])[a-zA-Z0-9]([a-zA-Z0-9-]{0,63}[a-zA-Z0-9])?$")

    state = module.params["state"]
    if module.params["suffix"] is None:
        suffix = "snap-" + str(
            (datetime.utcnow() - datetime(1970, 1, 1, 0, 0, 0, 0)).total_seconds()
        )
        module.params["suffix"] = suffix.replace(".", "")
    else:
        if not module.params["offload"]:
            if not pattern.match(module.params["suffix"]) and state not in [
                "absent",
                "rename",
            ]:
                module.fail_json(
                    msg="Suffix name {0} does not conform to suffix name rules".format(
                        module.params["suffix"]
                    )
                )
    if state == "rename" and module.params["target"] is not None:
        if not pattern.match(module.params["target"]):
            module.fail_json(
                msg="Suffix target {0} does not conform to suffix name rules".format(
                    module.params["target"]
                )
            )

    array = get_system(module)
    api_version = array._list_available_rest_versions()
    if GET_SEND_API not in api_version:
        arrayv6 = None
        if module.params["offload"]:
            module.fail_json(
                msg="Purity 6.1, or higher, is required to support single volume offload snapshots"
            )
        if state == "rename":
            module.fail_json(
                msg="Purity 6.1, or higher, is required to support snapshot rename"
            )
    else:
        if not HAS_PURESTORAGE:
            module.fail_json(msg="py-pure-client sdk is required for this module")
        arrayv6 = get_array(module)
        if module.params["offload"]:
            if not _check_offload(module, arrayv6) and not _check_target(
                module, arrayv6
            ):
                module.fail_json(
                    msg="Selected offload {0} not connected.".format(
                        module.params["offload"]
                    )
                )
    if (
        state == "copy"
        and module.params["offload"]
        and not _check_target(module, arrayv6)
    ):
        module.fail_json(
            msg="Snapshot copy is not supported when an offload target is defined"
        )
    destroyed = False
    array_snap = offload_snap = False
    volume = get_volume(module, array)
    if module.params["offload"] and not _check_target(module, arrayv6):
        offload_snap = _check_offload_snapshot(module, arrayv6)
        if offload_snap is None:
            offload_snap = False
        else:
            offload_snap = not offload_snap.destroyed
    else:
        array_snap = get_snapshot(module, array)
    snap = array_snap or offload_snap
    if not snap:
        destroyed = get_deleted_snapshot(module, array, arrayv6)
    if state == "present" and volume and not destroyed:
        create_snapshot(module, array, arrayv6)
    elif state == "present" and volume and destroyed:
        recover_snapshot(module, array, arrayv6)
    elif state == "rename" and volume and snap:
        update_snapshot(module, arrayv6)
    elif state == "copy" and snap:
        create_from_snapshot(module, array)
    elif state == "absent" and snap and not destroyed:
        delete_snapshot(module, array, arrayv6)
    elif state == "absent" and destroyed and module.params["eradicate"]:
        eradicate_snapshot(module, array, arrayv6)
    elif state == "absent" and not snap:
        module.exit_json(changed=False)

    module.exit_json(changed=False)
def create_offload(module, array):
    """Create offload target"""
    changed = True
    api_version = array._list_available_rest_versions()
    if not module.check_mode:
        # First check if the offload network inteface is there and enabled
        try:
            if not array.get_network_interface("@offload.data")["enabled"]:
                module.fail_json(
                    msg="Offload Network interface not enabled. Please resolve."
                )
        except Exception:
            module.fail_json(
                msg=
                "Offload Network interface not correctly configured. Please resolve."
            )
        if module.params["protocol"] == "nfs":
            try:
                array.connect_nfs_offload(
                    module.params["name"],
                    mount_point=module.params["share"],
                    address=module.params["address"],
                    mount_options=module.params["options"],
                )
            except Exception:
                module.fail_json(msg="Failed to create NFS offload {0}. "
                                 "Please perform diagnostic checks.".format(
                                     module.params["name"]))
        if module.params["protocol"] == "s3":
            if P53_API_VERSION in api_version:
                try:
                    array.connect_s3_offload(
                        module.params["name"],
                        access_key_id=module.params["access_key"],
                        secret_access_key=module.params["secret"],
                        bucket=module.params["bucket"],
                        placement_strategy=module.params["placement"],
                        initialize=module.params["initialize"],
                    )
                except Exception:
                    module.fail_json(msg="Failed to create S3 offload {0}. "
                                     "Please perform diagnostic checks.".
                                     format(module.params["name"]))
            else:
                try:
                    array.connect_s3_offload(
                        module.params["name"],
                        access_key_id=module.params["access_key"],
                        secret_access_key=module.params["secret"],
                        bucket=module.params["bucket"],
                        initialize=module.params["initialize"],
                    )
                except Exception:
                    module.fail_json(msg="Failed to create S3 offload {0}. "
                                     "Please perform diagnostic checks.".
                                     format(module.params["name"]))
        if module.params[
                "protocol"] == "azure" and P53_API_VERSION in api_version:
            try:
                array.connect_azure_offload(
                    module.params["name"],
                    container_name=module.params["container"],
                    secret_access_key=module.params["secret"],
                    account_name=module.params[".bucket"],
                    initialize=module.params["initialize"],
                )
            except Exception:
                module.fail_json(msg="Failed to create Azure offload {0}. "
                                 "Please perform diagnostic checks.".format(
                                     module.params["name"]))
        if module.params[
                "protocol"] == "gcp" and GCP_API_VERSION in api_version:
            arrayv6 = get_array(module)
            bucket = flasharray.OffloadGoogleCloud(
                access_key_id=module.params["access_key"],
                bucket=module.params["bucket"],
                secret_access_key=module.params["secret"],
            )
            offload = flasharray.OffloadPost(google_cloud=bucket)
            res = arrayv6.post_offloads(
                offload=offload,
                initialize=module.params["initialize"],
                names=[module.params["name"]],
            )
            if res.status_code != 200:
                module.fail_json(
                    msg="Failed to create GCP offload {0}. Error: {1}"
                    "Please perform diagnostic checks.".format(
                        module.params["name"], res.errors[0].message))
    module.exit_json(changed=changed)
Ejemplo n.º 23
0
def create_multi_volume(module, array):
    """Create Volume"""
    changed = True
    volfact = {}
    if not module.check_mode:
        bw_qos_size = iops_qos_size = 0
        names = []
        if "/" in module.params['name'] and not check_vgroup(module, array):
            module.fail_json(
                msg=
                "Multi-volume create failed. Volume Group {0} does not exist.".
                format(module.params["name"].split('/')[0]))
        if "::" in module.params['name']:
            if not check_pod(module, array):
                module.fail_json(
                    msg="Multi-volume create failed. Pod {0} does not exist".
                    format(module.params["name"].split(':')[0]))
        array = get_array(module)
        for vol_num in range(module.params['start'],
                             module.params['count'] + module.params['start']):
            names.append(module.params['name'] +
                         str(vol_num).zfill(module.params['digits']) +
                         module.params['suffix'])
        if module.params['bw_qos']:
            bw_qos = int(human_to_bytes(module.params['bw_qos']))
            if bw_qos in range(1048576, 549755813888):
                bw_qos_size = bw_qos
            else:
                module.fail_json(msg='Bandwidth QoS value out of range.')
        if module.params['iops_qos']:
            iops_qos = int(human_to_real(module.params['iops_qos']))
            if iops_qos in range(100, 100000000):
                iops_qos_size = iops_qos
            else:
                module.fail_json(msg='IOPs QoS value out of range.')
        if bw_qos_size != 0 and iops_qos_size != 0:
            vols = flasharray.VolumePost(
                provisioned=human_to_bytes(module.params['size']),
                qos=flasharray.Qos(bandwidth_limit=bw_qos_size,
                                   iops_limit=iops_qos_size),
                subtype='regular')
        elif bw_qos_size == 0 and iops_qos_size == 0:
            vols = flasharray.VolumePost(provisioned=human_to_bytes(
                module.params['size']),
                                         subtype='regular')
        elif bw_qos_size == 0 and iops_qos_size != 0:
            vols = flasharray.VolumePost(
                provisioned=human_to_bytes(module.params['size']),
                qos=flasharray.Qos(iops_limit=iops_qos_size),
                subtype='regular')
        elif bw_qos_size != 0 and iops_qos_size == 0:
            vols = flasharray.VolumePost(
                provisioned=human_to_bytes(module.params['size']),
                qos=flasharray.Qos(bandwidth_limit=bw_qos_size),
                subtype='regular')
        res = array.post_volumes(names=names, volume=vols)
        if res.status_code != 200:
            module.fail_json(
                msg='Multi-Volume {0}#{1} creation failed: {2}'.format(
                    module.params['name'], module.params['suffix'],
                    res.errors[0].message))
        else:
            temp = list(res.items)
            for count in range(0, len(temp)):
                vol_name = temp[count].name
                volfact[vol_name] = {
                    'size':
                    temp[count].provisioned,
                    'serial':
                    temp[count].serial,
                    'created':
                    time.strftime('%Y-%m-%d %H:%M:%S',
                                  time.localtime(temp[count].created / 1000)),
                }
                if bw_qos_size != 0:
                    volfact[vol_name]['bandwidth_limit'] = temp[
                        count].qos.bandwidth_limit
                if iops_qos_size != 0:
                    volfact[vol_name]['iops_limit'] = temp[
                        count].qos.iops_limit

    module.exit_json(changed=changed, volfact=volfact)
Ejemplo n.º 24
0
def main():
    argument_spec = purefa_argument_spec()
    argument_spec.update(
        dict(
            uri=dict(type="list", elements="str"),
            state=dict(type="str",
                       default="present",
                       choices=["absent", "present"]),
            enable=dict(type="bool", default=False),
            bind_password=dict(type="str", no_log=True),
            bind_user=dict(type="str"),
            base_dn=dict(type="str"),
            group_base=dict(type="str"),
            user_login=dict(type="str"),
            user_object=dict(type="str"),
            ro_group=dict(type="str"),
            sa_group=dict(type="str"),
            aa_group=dict(type="str"),
            dstype=dict(type="str",
                        default="management",
                        choices=["management", "data"]),
        ))

    module = AnsibleModule(argument_spec, supports_check_mode=True)

    array = get_system(module)
    api_version = array._list_available_rest_versions()

    if not HAS_PURESTORAGE:
        module.fail_json(
            msg="py-pure-client sdk is required to for this module")

    if FAFILES_API_VERSION in api_version:
        arrayv6 = get_array(module)

    if module.params["dstype"] == "data":
        if FAFILES_API_VERSION in api_version:
            if len(list(arrayv6.get_directory_services().items)) == 1:
                module.warn("FA-Files is not enabled  - ignoring")
                module.exit_json(changed=False)
        else:
            module.fail_json(
                msg=
                "'data' directory service requires Purity//FA 6.0.0 or higher")

    state = module.params["state"]
    ds_exists = False
    if FAFILES_API_VERSION in api_version:
        dirserv = list(
            arrayv6.get_directory_services(
                filter="name='" + module.params["dstype"] + "'").items)[0]
        if state == "absent" and dirserv.uris != []:
            delete_ds_v6(module, arrayv6)
        else:
            update_ds_v6(module, arrayv6)
    else:
        dirserv = array.get_directory_service()
        ds_enabled = dirserv["enabled"]
        if dirserv["base_dn"]:
            ds_exists = True

        if state == "absent" and ds_exists:
            delete_ds(module, array)
        elif ds_exists and module.params["enable"] and ds_enabled:
            module.warn(
                "To update an existing directory service configuration in Purity//FA 5.x, please delete and recreate"
            )
            module.exit_json(changed=False)
        elif ds_exists and not module.params["enable"] and ds_enabled:
            disable_ds(module, array)
        elif ds_exists and module.params["enable"] and not ds_enabled:
            enable_ds(module, array)
        elif not ds_exists and state == "present":
            create_ds(module, array)
        else:
            module.exit_json(changed=False)

    module.exit_json(changed=False)
Ejemplo n.º 25
0
def main():
    argument_spec = purefa_argument_spec()
    argument_spec.update(
        dict(
            state=dict(type="str", default="present", choices=["absent", "present"]),
            eradicate=dict(type="bool", default=False),
            name=dict(type="str", required=True),
            rename=dict(type="str"),
        )
    )

    module = AnsibleModule(argument_spec, supports_check_mode=True)

    if not HAS_PURESTORAGE:
        module.fail_json(msg="py-pure-client sdk is required for this module")

    array = get_system(module)
    api_version = array._list_available_rest_versions()

    if MIN_REQUIRED_API_VERSION not in api_version:
        module.fail_json(
            msg="FlashArray REST version not supported. "
            "Minimum version required: {0}".format(MIN_REQUIRED_API_VERSION)
        )
    array = get_array(module)
    state = module.params["state"]

    try:
        filesystem = list(array.get_file_systems(names=[module.params["name"]]).items)[
            0
        ]
        exists = True
    except Exception:
        exists = False

    if state == "present" and not exists:
        create_fs(module, array)
    elif (
        state == "present"
        and exists
        and module.params["rename"]
        and not filesystem.destroyed
    ):
        rename_fs(module, array)
    elif (
        state == "present"
        and exists
        and filesystem.destroyed
        and not module.params["rename"]
    ):
        recover_fs(module, array)
    elif state == "absent" and exists and not filesystem.destroyed:
        delete_fs(module, array)
    elif (
        state == "absent"
        and exists
        and module.params["eradicate"]
        and filesystem.destroyed
    ):
        eradicate_fs(module, array)

    module.exit_json(changed=False)