Server IP : 85.214.239.14 / Your IP : 18.225.156.91 Web Server : Apache/2.4.62 (Debian) System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Tue Jan 9 19:45:01 MSK 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.18 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, MySQL : OFF | cURL : OFF | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /lib/python3/dist-packages/ansible_collections/purestorage/fusion/plugins/modules/ |
Upload File : |
#!/usr/bin/python # -*- coding: utf-8 -*- # (c) 2023, Simon Dodsley (simon@purestorage.com), Jan Kodera (jkodera@purestorage.com) # GNU General Public License v3.0+ (see COPYING.GPLv3 or https://www.gnu.org/licenses/gpl-3.0.txt) from __future__ import absolute_import, division, print_function __metaclass__ = type DOCUMENTATION = r""" --- module: fusion_se version_added: '1.0.0' short_description: Manage storage endpoints in Pure Storage Fusion description: - Create or delete storage endpoints in Pure Storage Fusion. notes: - Supports C(check_mode). author: - Pure Storage Ansible Team (@sdodsley) <pure-ansible-team@purestorage.com> options: name: description: - The name of the storage endpoint. type: str required: true display_name: description: - The human name of the storage endpoint. - If not provided, defaults to I(name). type: str state: description: - Define whether the storage endpoint should exist or not. type: str default: present choices: [ absent, present ] region: description: - The name of the region the availability zone is in type: str required: true availability_zone: aliases: [ az ] description: - The name of the availability zone for the storage endpoint. type: str required: true endpoint_type: description: - "DEPRECATED: Will be removed in version 2.0.0" - Type of the storage endpoint. Only iSCSI is available at the moment. type: str iscsi: description: - List of discovery interfaces. type: list elements: dict suboptions: address: description: - IP address to be used in the subnet of the storage endpoint. - IP address must include a CIDR notation. - Only IPv4 is supported at the moment. type: str gateway: description: - Address of the subnet gateway. type: str network_interface_groups: description: - List of network interface groups to assign to the address. type: list elements: str cbs_azure_iscsi: description: - CBS Azure iSCSI type: dict suboptions: storage_endpoint_collection_identity: description: - The Storage Endpoint Collection Identity which belongs to the Azure entities. type: str load_balancer: description: - The Load Balancer id which gives permissions to CBS array applications to modify the Load Balancer. type: str load_balancer_addresses: description: - The IPv4 addresses of the Load Balancer. type: list elements: str network_interface_groups: description: - "DEPRECATED: Will be removed in version 2.0.0" - List of network interface groups to assign to the storage endpoints. type: list elements: str addresses: description: - "DEPRECATED: Will be removed in version 2.0.0" - List of IP addresses to be used in the subnet of the storage endpoint. - IP addresses must include a CIDR notation. - Only IPv4 is supported at the moment. type: list elements: str gateway: description: - "DEPRECATED: Will be removed in version 2.0.0" - Address of the subnet gateway. - Currently this must be provided. type: str extends_documentation_fragment: - purestorage.fusion.purestorage.fusion """ EXAMPLES = r""" - name: Create new storage endpoint foo in AZ bar purestorage.fusion.fusion_se: name: foo availability_zone: bar region: us-west iscsi: - address: 10.21.200.124/24 gateway: 10.21.200.1 network_interface_groups: - subnet-0 - address: 10.21.200.36/24 gateway: 10.21.200.2 network_interface_groups: - subnet-0 - subnet-1 state: present issuer_id: key_name private_key_file: "az-admin-private-key.pem" - name: Create new CBS storage endpoint foo in AZ bar purestorage.fusion.fusion_se: name: foo availability_zone: bar region: us-west cbs_azure_iscsi: storage_endpoint_collection_identity: "/subscriptions/sub/resourcegroups/sec/providers/ms/userAssignedIdentities/secId" load_balancer: "/subscriptions/sub/resourcegroups/sec/providers/ms/loadBalancers/sec-lb" load_balancer_addresses: - 10.21.200.1 - 10.21.200.2 state: present app_id: key_name key_file: "az-admin-private-key.pem" - name: Delete storage endpoint foo in AZ bar purestorage.fusion.fusion_se: name: foo availability_zone: bar region: us-west state: absent issuer_id: key_name private_key_file: "az-admin-private-key.pem" - name: (DEPRECATED) Create new storage endpoint foo in AZ bar purestorage.fusion.fusion_se: name: foo availability_zone: bar gateway: 10.21.200.1 region: us-west addresses: - 10.21.200.124/24 - 10.21.200.36/24 network_interface_groups: - subnet-0 state: present issuer_id: key_name private_key_file: "az-admin-private-key.pem" """ RETURN = r""" """ try: import fusion as purefusion except ImportError: pass from ansible.module_utils.basic import AnsibleModule from ansible_collections.purestorage.fusion.plugins.module_utils.fusion import ( fusion_argument_spec, ) from ansible_collections.purestorage.fusion.plugins.module_utils.networking import ( is_valid_network, is_valid_address, ) from ansible_collections.purestorage.fusion.plugins.module_utils.startup import ( setup_fusion, ) from ansible_collections.purestorage.fusion.plugins.module_utils.operations import ( await_operation, ) ####################################################################### # DEPRECATED CODE SECTION STARTS def create_se_old(module, fusion): """Create Storage Endpoint""" se_api_instance = purefusion.StorageEndpointsApi(fusion) changed = True if not module.check_mode: if not module.params["display_name"]: display_name = module.params["name"] else: display_name = module.params["display_name"] ifaces = [] for address in module.params["addresses"]: if module.params["gateway"]: iface = purefusion.StorageEndpointIscsiDiscoveryInterfacePost( address=address, gateway=module.params["gateway"], network_interface_groups=module.params["network_interface_groups"], ) else: iface = purefusion.StorageEndpointIscsiDiscoveryInterfacePost( address=address, network_interface_groups=module.params["network_interface_groups"], ) ifaces.append(iface) op = purefusion.StorageEndpointPost( endpoint_type="iscsi", iscsi=purefusion.StorageEndpointIscsiPost( discovery_interfaces=ifaces, ), name=module.params["name"], display_name=display_name, ) op = se_api_instance.create_storage_endpoint( op, region_name=module.params["region"], availability_zone_name=module.params["availability_zone"], ) await_operation(fusion, op) module.exit_json(changed=changed) # DEPRECATED CODE SECTION ENDS ####################################################################### def get_se(module, fusion): """Storage Endpoint or None""" se_api_instance = purefusion.StorageEndpointsApi(fusion) try: return se_api_instance.get_storage_endpoint( region_name=module.params["region"], storage_endpoint_name=module.params["name"], availability_zone_name=module.params["availability_zone"], ) except purefusion.rest.ApiException: return None def create_se(module, fusion): """Create Storage Endpoint""" se_api_instance = purefusion.StorageEndpointsApi(fusion) if not module.check_mode: endpoint_type = None iscsi = None if module.params["iscsi"] is not None: iscsi = purefusion.StorageEndpointIscsiPost( discovery_interfaces=[ purefusion.StorageEndpointIscsiDiscoveryInterfacePost(**endpoint) for endpoint in module.params["iscsi"] ] ) endpoint_type = "iscsi" cbs_azure_iscsi = None if module.params["cbs_azure_iscsi"] is not None: cbs_azure_iscsi = purefusion.StorageEndpointCbsAzureIscsiPost( storage_endpoint_collection_identity=module.params["cbs_azure_iscsi"][ "storage_endpoint_collection_identity" ], load_balancer=module.params["cbs_azure_iscsi"]["load_balancer"], load_balancer_addresses=module.params["cbs_azure_iscsi"][ "load_balancer_addresses" ], ) endpoint_type = "cbs-azure-iscsi" op = se_api_instance.create_storage_endpoint( purefusion.StorageEndpointPost( name=module.params["name"], display_name=module.params["display_name"] or module.params["name"], endpoint_type=endpoint_type, iscsi=iscsi, cbs_azure_iscsi=cbs_azure_iscsi, ), region_name=module.params["region"], availability_zone_name=module.params["availability_zone"], ) await_operation(fusion, op) module.exit_json(changed=True) def delete_se(module, fusion): """Delete Storage Endpoint""" se_api_instance = purefusion.StorageEndpointsApi(fusion) if not module.check_mode: op = se_api_instance.delete_storage_endpoint( region_name=module.params["region"], availability_zone_name=module.params["availability_zone"], storage_endpoint_name=module.params["name"], ) await_operation(fusion, op) module.exit_json(changed=True) def update_se(module, fusion, se): """Update Storage Endpoint""" se_api_instance = purefusion.StorageEndpointsApi(fusion) patches = [] if ( module.params["display_name"] and module.params["display_name"] != se.display_name ): patch = purefusion.StorageEndpointPatch( display_name=purefusion.NullableString(module.params["display_name"]), ) patches.append(patch) if not module.check_mode: for patch in patches: op = se_api_instance.update_storage_endpoint( patch, region_name=module.params["region"], availability_zone_name=module.params["availability_zone"], storage_endpoint_name=module.params["name"], ) await_operation(fusion, op) changed = len(patches) != 0 module.exit_json(changed=changed) def main(): """Main code""" argument_spec = fusion_argument_spec() argument_spec.update( dict( name=dict(type="str", required=True), display_name=dict(type="str"), region=dict(type="str", required=True), availability_zone=dict(type="str", required=True, aliases=["az"]), iscsi=dict( type="list", elements="dict", options=dict( address=dict(type="str"), gateway=dict(type="str"), network_interface_groups=dict(type="list", elements="str"), ), ), cbs_azure_iscsi=dict( type="dict", options=dict( storage_endpoint_collection_identity=dict(type="str"), load_balancer=dict(type="str"), load_balancer_addresses=dict(type="list", elements="str"), ), ), state=dict(type="str", default="present", choices=["absent", "present"]), # deprecated, will be removed in 2.0.0 endpoint_type=dict( type="str", removed_in_version="2.0.0", removed_from_collection="purestorage.fusion", ), addresses=dict( type="list", elements="str", removed_in_version="2.0.0", removed_from_collection="purestorage.fusion", ), gateway=dict( type="str", removed_in_version="2.0.0", removed_from_collection="purestorage.fusion", ), network_interface_groups=dict( type="list", elements="str", removed_in_version="2.0.0", removed_from_collection="purestorage.fusion", ), ) ) mutually_exclusive = [ ("iscsi", "cbs_azure_iscsi"), # can not use both deprecated and new fields at the same time ("iscsi", "cbs_azure_iscsi", "addresses"), ("iscsi", "cbs_azure_iscsi", "gateway"), ("iscsi", "cbs_azure_iscsi", "network_interface_groups"), ] module = AnsibleModule( argument_spec, mutually_exclusive=mutually_exclusive, supports_check_mode=True, ) fusion = setup_fusion(module) state = module.params["state"] if module.params["endpoint_type"] is not None: module.warn( "'endpoint_type' parameter is deprecated and will be removed in the version 2.0" ) deprecated_parameters = {"addresses", "gateway", "network_interface_groups"} used_deprecated_parameters = [ key for key in list(deprecated_parameters & module.params.keys()) if module.params[key] is not None ] if len(used_deprecated_parameters) > 0: # user uses deprecated module interface for param_name in used_deprecated_parameters: module.warn( f"'{param_name}' parameter is deprecated and will be removed in the version 2.0" ) if module.params["addresses"]: for address in module.params["addresses"]: if not is_valid_network(address): module.fail_json( msg=f"'{address}' is not a valid address in CIDR notation" ) sendp = get_se(module, fusion) if state == "present" and not sendp: module.fail_on_missing_params(["addresses"]) if not (module.params["addresses"]): module.fail_json( msg="At least one entry in 'addresses' is required to create new storage endpoint" ) create_se_old(module, fusion) elif state == "present" and sendp: update_se(module, fusion, sendp) elif state == "absent" and sendp: delete_se(module, fusion) else: # user uses new module interface if module.params["iscsi"] is not None: for endpoint in module.params["iscsi"]: address = endpoint["address"] if not is_valid_network(address): module.fail_json( msg=f"'{address}' is not a valid address in CIDR notation" ) gateway = endpoint["gateway"] if not is_valid_address(gateway): module.fail_json( msg=f"'{gateway}' is not a valid IPv4 address notation" ) if module.params["cbs_azure_iscsi"] is not None: for address in module.params["cbs_azure_iscsi"]["load_balancer_addresses"]: if not is_valid_address(address): module.fail_json( msg=f"'{address}' is not a valid IPv4 address notation" ) sendp = get_se(module, fusion) if state == "present" and not sendp: if ( module.params["iscsi"] is None and module.params["cbs_azure_iscsi"] is None ): module.fail_json( msg="either 'iscsi' or `cbs_azure_iscsi` parameter is required when creating storage endpoint" ) create_se(module, fusion) elif state == "present" and sendp: update_se(module, fusion, sendp) elif state == "absent" and sendp: delete_se(module, fusion) module.exit_json(changed=False) if __name__ == "__main__": main()