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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)