diff --git a/lib/ansible/modules/storage/purestorage/purefb_bucket.py b/lib/ansible/modules/storage/purestorage/purefb_bucket.py deleted file mode 100644 index dc733069e41..00000000000 --- a/lib/ansible/modules/storage/purestorage/purefb_bucket.py +++ /dev/null @@ -1,216 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2017, Simon Dodsley (simon@purestorage.com) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - - -DOCUMENTATION = ''' ---- -module: purefb_bucket -version_added: "2.8" -short_description: Manage Object Store Buckets on a Pure Storage FlashBlade. -description: - - This module managess object store (s3) buckets on Pure Storage FlashBlade. -author: Pure Storage Ansible Team (@sdodsley) -options: - name: - description: - - Bucket Name. - required: true - type: str - account: - description: - - Object Store Account for Bucket. - required: true - type: str - state: - description: - - Create, delete or modifies a bucket. - required: false - default: present - type: str - choices: [ "present", "absent" ] - eradicate: - description: - - Define whether to eradicate the bucket on delete or leave in trash. - required: false - type: bool - default: false -extends_documentation_fragment: -- purestorage.fb -''' - -EXAMPLES = ''' -- name: Create new bucket named foo in account bar - purefb_bucket: - name: foo - account: bar - fb_url: 10.10.10.2 - api_token: T-55a68eb5-c785-4720-a2ca-8b03903bf641 - -- name: Delete bucket named foo in account bar - purefb_bucket: - name: foo - account: bar - state: absent - fb_url: 10.10.10.2 - api_token: T-55a68eb5-c785-4720-a2ca-8b03903bf641 - -- name: Recover deleted bucket named foo in account bar - purefb_bucket: - name: foo - account: bar - state: present - fb_url: 10.10.10.2 - api_token: T-55a68eb5-c785-4720-a2ca-8b03903bf641 - -- name: Eradicate bucket named foo in account bar - purefb_bucket: - name: foo - account: bar - state: absent - eradicate: true - fb_url: 10.10.10.2 - api_token: T-55a68eb5-c785-4720-a2ca-8b03903bf641 -''' - -RETURN = ''' -''' - -HAS_PURITY_FB = True -try: - from purity_fb import Bucket, Reference -except ImportError: - HAS_PURITY_FB = False - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.pure import get_blade, purefb_argument_spec - - -MIN_REQUIRED_API_VERSION = '1.5' - - -def get_s3acc(module, blade): - """Return Object Store Account or None""" - s3acc = None - accts = blade.object_store_accounts.list_object_store_accounts() - for acct in range(0, len(accts.items)): - if accts.items[acct].name == module.params['account']: - s3acc = accts.items[acct] - return s3acc - - -def get_bucket(module, blade): - """Return Bucket or None""" - s3bucket = None - buckets = blade.buckets.list_buckets() - for bucket in range(0, len(buckets.items)): - if buckets.items[bucket].name == module.params['name']: - s3bucket = buckets.items[bucket] - return s3bucket - - -def create_bucket(module, blade): - """Create bucket""" - changed = False - try: - attr = Bucket() - attr.account = Reference(name=module.params['account']) - blade.buckets.create_buckets(names=[module.params['name']], account=attr) - changed = True - except Exception: - module.fail_json(msg='Object Store Bucket {0}: Creation failed'.format(module.params['name'])) - module.exit_json(changed=changed) - - -def delete_bucket(module, blade): - """ Delete Bucket""" - changed = False - try: - blade.buckets.update_buckets(names=[module.params['name']], - destroyed=Bucket(destroyed=True)) - changed = True - if module.params['eradicate']: - try: - blade.buckets.delete_buckets(names=[module.params['name']]) - changed = True - except Exception: - module.fail_json(msg='Object Store Bucket {0}: Eradication failed'.format(module.params['name'])) - except Exception: - module.fail_json(msg='Object Store Bucket {0}: Deletion failed'.format(module.params['name'])) - module.exit_json(changed=changed) - - -def recover_bucket(module, blade): - """ Recover Bucket""" - changed = False - try: - blade.buckets.update_buckets(names=[module.params['name']], - destroyed=Bucket(destroyed=False)) - changed = True - except Exception: - module.fail_json(msg='Object Store Bucket {0}: Recovery failed'.format(module.params['name'])) - module.exit_json(changed=changed) - - -def eradicate_bucket(module, blade): - """ Eradicate Bucket""" - changed = False - try: - blade.buckets.delete_buckets(names=[module.params['name']]) - changed = True - except Exception: - module.fail_json(msg='Object Store Bucket {0}: Eradication failed'.format(module.params['name'])) - module.exit_json(changed=changed) - - -def main(): - argument_spec = purefb_argument_spec() - argument_spec.update( - dict( - name=dict(required=True), - account=dict(required=True), - eradicate=dict(default='false', type='bool'), - state=dict(default='present', choices=['present', 'absent']), - ) - ) - - module = AnsibleModule(argument_spec) - - if not HAS_PURITY_FB: - module.fail_json(msg='purity_fb sdk is required for this module') - - state = module.params['state'] - blade = get_blade(module) - api_version = blade.api_version.list_versions().versions - if MIN_REQUIRED_API_VERSION not in api_version: - module.fail_json(msg="Purity//FB must be upgraded to support this module.") - bucket = get_bucket(module, blade) - if not get_s3acc(module, blade): - module.fail_json(msg="Object Store Account {0} does not exist.".format(module.params['account'])) - - if state == 'present' and not bucket: - create_bucket(module, blade) - elif state == 'present' and bucket and bucket.destroyed: - recover_bucket(module, blade) - elif state == 'absent' and bucket and not bucket.destroyed: - delete_bucket(module, blade) - elif state == 'absent' and bucket and bucket.destroyed and module.params['eradicate']: - eradicate_bucket(module, blade) - elif state == 'absent' and not bucket: - module.exit_json(changed=False) - - module.exit_json(changed=False) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/storage/purestorage/purefb_ds.py b/lib/ansible/modules/storage/purestorage/purefb_ds.py deleted file mode 100644 index 99dcdba2726..00000000000 --- a/lib/ansible/modules/storage/purestorage/purefb_ds.py +++ /dev/null @@ -1,347 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2018, Simon Dodsley (simon@purestorage.com) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: purefb_ds -version_added: '2.8' -short_description: Configure FlashBlade Directory Service -description: -- Create or erase directory services configurations. There is no facility - to SSL certificates at this time. Use the FlashBlade GUI for this - additional configuration work. -- To modify an existing directory service configuration you must first delete - an existing configuration and then recreate with new settings. -author: -- Pure Storage Ansible Team (@sdodsley) -options: - state: - description: - - Create or delete directory service configuration - default: present - type: str - choices: [ absent, present ] - dstype: - description: - - The type of directory service to work on - choices: [ management, nfs, smb ] - type: str - enable: - description: - - Whether to enable or disable directory service support. - default: false - type: bool - uri: - description: - - A list of up to 30 URIs of the directory servers. Each URI must include - the scheme ldap:// or ldaps:// (for LDAP over SSL), a hostname, and a - domain name or IP address. For example, ldap://ad.company.com configures - the directory service with the hostname "ad" in the domain "company.com" - while specifying the unencrypted LDAP protocol. - type: list - base_dn: - description: - - Sets the base of the Distinguished Name (DN) of the directory service - groups. The base should consist of only Domain Components (DCs). The - base_dn will populate with a default value when a URI is entered by - parsing domain components from the URI. The base DN should specify DC= - for each domain component and multiple DCs should be separated by commas. - required: true - type: str - bind_password: - description: - - Sets the password of the bind_user user name account. - type: str - bind_user: - description: - - Sets the user name that can be used to bind to and query the directory. - - For Active Directory, enter the username - often referred to as - sAMAccountName or User Logon Name - of the account that is used to - perform directory lookups. - - For OpenLDAP, enter the full DN of the user. - type: str - nis_servers: - description: - - A list of up to 30 IP addresses or FQDNs for NIS servers. - - This cannot be used in conjunction with LDAP configurations. - type: list - version_added: 2.9 - nis_domain: - description: - - The NIS domain to search - - This cannot be used in conjunction with LDAP configurations. - type: str - version_added: 2.9 - join_ou: - description: - - The optional organizational unit (OU) where the machine account - for the directory service will be created. - type: str - version_added: 2.9 -extends_documentation_fragment: -- purestorage.fb -''' - -EXAMPLES = r''' -- name: Delete existing management directory service - purefb_ds: - dstype: management - state: absent - fb_url: 10.10.10.2 - api_token: e31060a7-21fc-e277-6240-25983c6c4592 - -- name: Create NFS directory service (disabled) - purefb_ds: - dstype: nfs - uri: "ldaps://lab.purestorage.com" - base_dn: "DC=lab,DC=purestorage,DC=com" - bind_user: Administrator - bind_password: password - fb_url: 10.10.10.2 - api_token: e31060a7-21fc-e277-6240-25983c6c4592 - -- name: Enable existing SMB directory service - purefb_ds: - dstypr: smb - enable: true - fb_url: 10.10.10.2 - api_token: e31060a7-21fc-e277-6240-25983c6c4592 - -- name: Disable existing management directory service - purefb_ds: - dstype: management - enable: false - fb_url: 10.10.10.2 - api_token: e31060a7-21fc-e277-6240-25983c6c4592 - -- name: Create NFS directory service (enabled) - purefb_ds: - dstype: nfs - enable: true - uri: "ldaps://lab.purestorage.com" - base_dn: "DC=lab,DC=purestorage,DC=com" - bind_user: Administrator - bind_password: password - fb_url: 10.10.10.2 - api_token: e31060a7-21fc-e277-6240-25983c6c4592 -''' - -RETURN = r''' -''' - - -NIS_API_VERSION = '1.7' -HAS_PURITY_FB = True -try: - from purity_fb import DirectoryService -except ImportError: - HAS_PURITY_FB = False - - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.pure import get_blade, purefb_argument_spec - - -def update_ds(module, blade): - """Update Directory Service""" -# This module is a place-holder until we figure out a way to -# update the config on the fly rather than deleting and resetting - changed = False - module.exit_json(changed=changed) - - -def enable_ds(module, blade): - """Enable Directory Service""" - changed = True - if not module.check_mode: - try: - blade.directory_services.update_directory_services(names=[module.params['dstype']], - directory_service=DirectoryService(enabled=True)) - changed = True - except Exception: - module.fail_json(msg='Enable {0} Directory Service failed: Check Configuration'.format(module.params['dstype'])) - module.exit_json(changed=changed) - - -def disable_ds(module, blade): - """Disable Directory Service""" - changed = True - if not module.check_mode: - try: - blade.directory_services.update_directory_services(names=[module.params['dstype']], - directory_service=DirectoryService(enabled=False)) - except Exception: - module.fail_json(msg='Disable {0} Directory Service failed'.format(module.params['dstype'])) - module.exit_json(changed=changed) - - -def delete_ds(module, blade): - """Delete Directory Service""" - changed = True - if not module.check_mode: - dirserv = blade.directory_services.list_directory_services(names=[module.params['dstype']]) - try: - if module.params['dstype'] == 'management': - if dirserv.items[0].uris: - dir_service = DirectoryService(uris=[''], - base_dn="", - bind_user="", - bind_password="", - enabled=False) - else: - changed = False - elif module.params['dstype'] == 'smb': - if dirserv.items[0].uris: - smb_attrs = {'join_ou': ''} - dir_service = DirectoryService(uris=[''], - base_dn='', - bind_user='', - bind_password='', - smb=smb_attrs, - enabled=False) - else: - changed = False - elif module.params['dstype'] == 'nfs': - if dirserv.items[0].uris: - dir_service = DirectoryService(uris=[''], - base_dn='', - bind_user='', - bind_password='', - enabled=False) - elif dirserv.items[0].nfs.nis_domains: - nfs_attrs = {'nis_domains': [], - 'nis_servers': []} - dir_service = DirectoryService(nfs=nfs_attrs, - enabled=False) - else: - changed = False - if changed: - blade.directory_services.update_directory_services(names=[module.params['dstype']], - directory_service=dir_service) - except Exception: - module.fail_json(msg='Delete {0} Directory Service failed'.format(module.params['dstype'])) - module.exit_json(changed=changed) - - -def create_ds(module, blade): - """Create Directory Service""" - changed = True - if not module.check_mode: - try: - if module.params['dstype'] == 'management': - if module.params['uri']: - dir_service = DirectoryService(uris=module.params['uri'][0:30], - base_dn=module.params['base_dn'], - bind_user=module.params['bind_user'], - bind_password=module.params['bind_password'], - enabled=module.params['enable']) - else: - module.fail_json(msg="URI and associated params must be specified to create dstype {0}".format(module.params['dstype'])) - elif module.params['dstype'] == 'smb': - if module.params['uri']: - smb_attrs = {'join_ou': module.params['join_ou']} - dir_service = DirectoryService(uris=module.params['uri'][0:30], - base_dn=module.params['base_dn'], - bind_user=module.params['bind_user'], - bind_password=module.params['bind_password'], - smb=smb_attrs, - enabled=module.params['enable']) - else: - module.fail_json(msg="URI and associated params must be specified to create dstype {0}".format(module.params['dstype'])) - elif module.params['dstype'] == 'nfs': - if module.params['nis_domain']: - nfs_attrs = {'nis_domains': [module.params['nis_domain']], - 'nis_servers': module.params['nis_servers'][0:30]} - dir_service = DirectoryService(nfs=nfs_attrs, - enabled=module.params['enable']) - else: - dir_service = DirectoryService(uris=module.params['uri'][0:30], - base_dn=module.params['base_dn'], - bind_user=module.params['bind_user'], - bind_password=module.params['bind_password'], - enabled=module.params['enable']) - blade.directory_services.update_directory_services(names=[module.params['dstype']], - directory_service=dir_service) - except Exception: - module.fail_json(msg='Create {0} Directory Service failed: Check configuration'.format(module.params['dstype'])) - module.exit_json(changed=changed) - - -def main(): - argument_spec = purefb_argument_spec() - argument_spec.update(dict( - uri=dict(type='list'), - dstype=dict(required=True, type='str', choices=['management', 'nfs', 'smb']), - 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'), - join_ou=dict(type='str'), - nis_domain=dict(type='str'), - nis_servers=dict(type='list'), - )) - - required_together = [['uri', 'bind_password', 'bind_user', 'base_dn'], - ['nis_servers', 'nis_domain'], - ['join_ou', 'uri']] - mutually_exclusive = [['uri', 'nis_domain']] - - module = AnsibleModule(argument_spec, - required_together=required_together, - mutually_exclusive=mutually_exclusive, - supports_check_mode=True) - if not HAS_PURITY_FB: - module.fail_json(msg='purity_fb sdk is required for this module') - - state = module.params['state'] - blade = get_blade(module) - api_version = blade.api_version.list_versions().versions - ds_configured = False - dirserv = blade.directory_services.list_directory_services(names=[module.params['dstype']]) - ds_enabled = dirserv.items[0].enabled - if dirserv.items[0].base_dn is not None: - ds_configured = True - if (module.params['nis_domain'] or module.params['join_ou']) and (NIS_API_VERSION not in api_version): - module.fail_json(msg="NFS or SMB directory service attributes are not supported in your FlashBlade Purity version.") - ldap_uri = False - set_ldap = False - for uri in range(0, len(dirserv.items[0].uris)): - if "ldap" in dirserv.items[0].uris[uri].lower(): - ldap_uri = True - if module.params['uri']: - for uri in range(0, len(module.params['uri'])): - if "ldap" in module.params['uri'][uri].lower(): - set_ldap = True - if not module.params['uri'] and ldap_uri or \ - module.params['uri'] and set_ldap: - if module.params['nis_servers'] or module.params['nis_domain']: - module.fail_json(msg="NIS configuration not supported in an LDAP environment") - if state == 'absent': - delete_ds(module, blade) - elif ds_configured and module.params['enable'] and ds_enabled: - update_ds(module, blade) - elif ds_configured and not module.params['enable'] and ds_enabled: - disable_ds(module, blade) - elif ds_configured and module.params['enable'] and not ds_enabled: - enable_ds(module, blade) -# Now we have enabled the DS lets make sure there aren't any new updates... - update_ds(module, blade) - elif not ds_configured and state == 'present': - create_ds(module, blade) - else: - module.exit_json(changed=False) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/storage/purestorage/purefb_dsrole.py b/lib/ansible/modules/storage/purestorage/purefb_dsrole.py deleted file mode 100644 index fe4967d06ce..00000000000 --- a/lib/ansible/modules/storage/purestorage/purefb_dsrole.py +++ /dev/null @@ -1,176 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2018, Simon Dodsley (simon@purestorage.com) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: purefb_dsrole -version_added: '2.8' -short_description: Configure FlashBlade Management Directory Service Roles -description: -- Set or erase directory services role configurations. -author: -- Pure Storage Ansible Team (@sdodsley) -options: - state: - description: - - Create or delete directory service role - default: present - type: str - choices: [ absent, present ] - role: - description: - - The directory service role to work on - choices: [ array_admin, ops_admin, readonly, storage_admin ] - type: str - group_base: - description: - - Specifies where the configured group is located in the directory - tree. This field consists of Organizational Units (OUs) that combine - with the base DN attribute and the configured group CNs to complete - the full Distinguished Name of the groups. The group base should - specify OU= for each OU and multiple OUs should be separated by commas. - The order of OUs is important and should get larger in scope from left - to right. - - Each OU should not exceed 64 characters in length. - type: str - group: - description: - - Sets the common Name (CN) of the configured directory service group - containing users for the FlashBlade. This name should be just the - Common Name of the group without the CN= specifier. - - Common Names should not exceed 64 characters in length. - type: str -extends_documentation_fragment: -- purestorage.fb -''' - -EXAMPLES = r''' -- name: Delete existing array_admin directory service role - purefb_dsrole: - role: array_admin - state: absent - fb_url: 10.10.10.2 - api_token: e31060a7-21fc-e277-6240-25983c6c4592 - -- name: Create array_admin directory service role - purefb_dsrole: - role: array_admin - group_base: "OU=PureGroups,OU=SANManagers" - group: pureadmins - fb_url: 10.10.10.2 - api_token: e31060a7-21fc-e277-6240-25983c6c4592 - -- name: Update ops_admin directory service role - purefb_dsrole: - role: ops_admin - group_base: "OU=PureGroups" - group: opsgroup - fb_url: 10.10.10.2 - api_token: e31060a7-21fc-e277-6240-25983c6c4592 -''' - -RETURN = r''' -''' - - -HAS_PURITY_FB = True -try: - from purity_fb import DirectoryServiceRole -except ImportError: - HAS_PURITY_FB = False - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.pure import get_blade, purefb_argument_spec - - -def update_role(module, blade): - """Update Directory Service Role""" - changed = False - role = blade.directory_services.list_directory_services_roles(names=[module.params['role']]) - if role.items[0].group_base != module.params['group_base'] or role.items[0].group != module.params['group']: - try: - role = DirectoryServiceRole(group_base=module.params['group_base'], - group=module.params['group']) - blade.directory_services.update_directory_services_roles(names=[module.params['role']], - directory_service_role=role) - changed = True - except Exception: - module.fail_json(msg='Update Directory Service Role {0} failed'.format(module.params['role'])) - module.exit_json(changed=changed) - - -def delete_role(module, blade): - """Delete Directory Service Role""" - changed = False - try: - role = DirectoryServiceRole(group_base='', - group='') - blade.directory_services.update_directory_services_roles(names=[module.params['role']], - directory_service_role=role) - changed = True - except Exception: - module.fail_json(msg='Delete Directory Service Role {0} failed'.format(module.params['role'])) - module.exit_json(changed=changed) - - -def create_role(module, blade): - """Create Directory Service Role""" - changed = False - try: - role = DirectoryServiceRole(group_base=module.params['group_base'], - group=module.params['group']) - blade.directory_services.update_directory_services_roles(names=[module.params['role']], - directory_service_role=role) - changed = True - except Exception: - module.fail_json(msg='Create Directory Service Role {0} failed: Check configuration'.format(module.params['role'])) - module.exit_json(changed=changed) - - -def main(): - argument_spec = purefb_argument_spec() - argument_spec.update(dict( - role=dict(required=True, type='str', choices=['array_admin', 'ops_admin', 'readonly', 'storage_admin']), - state=dict(type='str', default='present', choices=['absent', 'present']), - group_base=dict(type='str'), - group=dict(type='str'), - )) - - required_together = [['group', 'group_base']] - - module = AnsibleModule(argument_spec, - required_together=required_together, - supports_check_mode=False) - - if not HAS_PURITY_FB: - module.fail_json(msg='purity_fb sdk is required for this module') - - state = module.params['state'] - blade = get_blade(module) - role_configured = False - role = blade.directory_services.list_directory_services_roles(names=[module.params['role']]) - if role.items[0].group is not None: - role_configured = True - - if state == 'absent' and role_configured: - delete_role(module, blade) - elif role_configured and state == 'present': - update_role(module, blade) - elif not role_configured and state == 'present': - create_role(module, blade) - else: - module.exit_json(changed=False) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/storage/purestorage/purefb_fs.py b/lib/ansible/modules/storage/purestorage/purefb_fs.py deleted file mode 100644 index 582c0132040..00000000000 --- a/lib/ansible/modules/storage/purestorage/purefb_fs.py +++ /dev/null @@ -1,438 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2017, Simon Dodsley (simon@purestorage.com) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - - -DOCUMENTATION = ''' ---- -module: purefb_fs -version_added: "2.6" -short_description: Manage filesystemon Pure Storage FlashBlade` -description: - - This module manages filesystems on Pure Storage FlashBlade. -author: Pure Storage Ansible Team (@sdodsley) -options: - name: - description: - - Filesystem Name. - required: true - type: str - state: - description: - - Create, delete or modifies a filesystem. - required: false - default: present - type: str - choices: [ "present", "absent" ] - eradicate: - description: - - Define whether to eradicate the filesystem on delete or leave in trash. - required: false - type: bool - default: false - size: - description: - - Volume size in M, G, T or P units. See examples. - type: str - required: false - default: 32G - nfsv3: - description: - - Define whether to NFSv3 protocol is enabled for the filesystem. - required: false - type: bool - default: true - version_added: 2.9 - nfsv4: - description: - - Define whether to NFSv4.1 protocol is enabled for the filesystem. - required: false - type: bool - default: true - version_added: 2.9 - nfs_rules: - description: - - Define the NFS rules in operation. - required: false - default: '*(rw,no_root_squash)' - type: str - smb: - description: - - Define whether to SMB protocol is enabled for the filesystem. - required: false - type: bool - default: false - http: - description: - - Define whether to HTTP/HTTPS protocol is enabled for the filesystem. - required: false - type: bool - default: false - snapshot: - description: - - Define whether a snapshot directory is enabled for the filesystem. - required: false - type: bool - default: false - fastremove: - description: - - Define whether the fast remove directory is enabled for the filesystem. - required: false - type: bool - default: false - hard_limit: - description: - - Define whether the capacity for a filesystem is a hard limit. - - CAUTION This will cause the filesystem to go Read-Only if the - capacity has already exceeded the logical size of the filesystem. - required: false - type: bool - default: false - version_added: 2.8 - user_quota: - description: - - Default quota in M, G, T or P units for a user under this file system. - required: false - type: str - version_added: 2.9 - group_quota: - description: - - Default quota in M, G, T or P units for a group under this file system. - required: false - type: str - version_added: 2.9 -extends_documentation_fragment: - - purestorage.fb -''' - -EXAMPLES = ''' -- name: Create new filesystem named foo - purefb_fs: - name: foo - size: 1T - state: present - fb_url: 10.10.10.2 - api_token: T-55a68eb5-c785-4720-a2ca-8b03903bf641 - -- name: Delete filesystem named foo - purefb_fs: - name: foo - state: absent - fb_url: 10.10.10.2 - api_token: T-55a68eb5-c785-4720-a2ca-8b03903bf641 - -- name: Recover filesystem named foo - purefb_fs: - name: foo - state: present - fb_url: 10.10.10.2 - api_token: T-55a68eb5-c785-4720-a2ca-8b03903bf641 - -- name: Eradicate filesystem named foo - purefb_fs: - name: foo - state: absent - eradicate: true - fb_url: 10.10.10.2 - api_token: T-55a68eb5-c785-4720-a2ca-8b03903bf641 - -- name: Modify attributes of an existing filesystem named foo - purefb_fs: - name: foo - size: 2T - nfsv3 : false - nfsv4 : true - user_quota: 10K - group_quota: 25M - nfs_rules: '*(ro)' - snapshot: true - fastremove: true - hard_limit: true - smb: true - state: present - fb_url: 10.10.10.2 - api_token: T-55a68eb5-c785-4720-a2ca-8b03903bf641''' - -RETURN = ''' -''' - -HAS_PURITY_FB = True -try: - from purity_fb import FileSystem, ProtocolRule, NfsRule -except ImportError: - HAS_PURITY_FB = False - -from ansible.module_utils.basic import AnsibleModule, human_to_bytes -from ansible.module_utils.pure import get_blade, purefb_argument_spec - - -HARD_LIMIT_API_VERSION = '1.4' -NFSV4_API_VERSION = '1.6' - - -def get_fs(module, blade): - """Return Filesystem or None""" - fsys = [] - fsys.append(module.params['name']) - try: - res = blade.file_systems.list_file_systems(names=fsys) - return res.items[0] - except Exception: - return None - - -def create_fs(module, blade): - """Create Filesystem""" - changed = True - if not module.check_mode: - try: - - if not module.params['size']: - module.params['size'] = '32G' - - size = human_to_bytes(module.params['size']) - - if module.params['user_quota']: - user_quota = human_to_bytes(module.params['user_quota']) - else: - user_quota = None - if module.params['group_quota']: - group_quota = human_to_bytes(module.params['group_quota']) - else: - group_quota = None - - api_version = blade.api_version.list_versions().versions - if HARD_LIMIT_API_VERSION in api_version: - if NFSV4_API_VERSION in api_version: - fs_obj = FileSystem(name=module.params['name'], - provisioned=size, - fast_remove_directory_enabled=module.params['fastremove'], - hard_limit_enabled=module.params['hard_limit'], - snapshot_directory_enabled=module.params['snapshot'], - nfs=NfsRule(v3_enabled=module.params['nfsv3'], - v4_1_enabled=module.params['nfsv4'], - rules=module.params['nfs_rules']), - smb=ProtocolRule(enabled=module.params['smb']), - http=ProtocolRule(enabled=module.params['http']), - default_user_quota=user_quota, - default_group_quota=group_quota - ) - else: - fs_obj = FileSystem(name=module.params['name'], - provisioned=size, - fast_remove_directory_enabled=module.params['fastremove'], - hard_limit_enabled=module.params['hard_limit'], - snapshot_directory_enabled=module.params['snapshot'], - nfs=NfsRule(enabled=module.params['nfsv3'], rules=module.params['nfs_rules']), - smb=ProtocolRule(enabled=module.params['smb']), - http=ProtocolRule(enabled=module.params['http']) - ) - else: - fs_obj = FileSystem(name=module.params['name'], - provisioned=size, - fast_remove_directory_enabled=module.params['fastremove'], - snapshot_directory_enabled=module.params['snapshot'], - nfs=NfsRule(enabled=module.params['nfsv3'], rules=module.params['nfs_rules']), - smb=ProtocolRule(enabled=module.params['smb']), - http=ProtocolRule(enabled=module.params['http']) - ) - blade.file_systems.create_file_systems(fs_obj) - except Exception: - module.fail_json(msg="Failed to create filesystem {0}.".format(module.params['name'])) - module.exit_json(changed=changed) - - -def modify_fs(module, blade): - """Modify Filesystem""" - changed = True - if not module.check_mode: - mod_fs = False - attr = {} - if module.params['user_quota']: - user_quota = human_to_bytes(module.params['user_quota']) - if module.params['group_quota']: - group_quota = human_to_bytes(module.params['group_quota']) - fsys = get_fs(module, blade) - if fsys.destroyed: - attr['destroyed'] = False - mod_fs = True - if module.params['size']: - if human_to_bytes(module.params['size']) != fsys.provisioned: - attr['provisioned'] = human_to_bytes(module.params['size']) - mod_fs = True - api_version = blade.api_version.list_versions().versions - if NFSV4_API_VERSION in api_version: - if module.params['nfsv3'] and not fsys.nfs.v3_enabled: - attr['nfs'] = NfsRule(v3_enabled=module.params['nfsv3']) - mod_fs = True - if not module.params['nfsv3'] and fsys.nfs.v3_enabled: - attr['nfs'] = NfsRule(v3_enabled=module.params['nfsv3']) - mod_fs = True - if module.params['nfsv4'] and not fsys.nfs.v4_1_enabled: - attr['nfs'] = NfsRule(v4_1_enabled=module.params['nfsv4']) - mod_fs = True - if not module.params['nfsv4'] and fsys.nfs.v4_1_enabled: - attr['nfs'] = NfsRule(v4_1_enabled=module.params['nfsv4']) - mod_fs = True - if module.params['nfsv3'] or module.params['nfsv4'] and fsys.nfs.v3_enabled or fsys.nfs.v4_1_enabled: - if fsys.nfs.rules != module.params['nfs_rules']: - attr['nfs'] = NfsRule(rules=module.params['nfs_rules']) - mod_fs = True - if module.params['user_quota'] and user_quota != fsys.default_user_quota: - attr['default_user_quota'] = user_quota - mod_fs = True - if module.params['group_quota'] and group_quota != fsys.default_group_quota: - attr['default_group_quota'] = group_quota - mod_fs = True - else: - if module.params['nfsv3'] and not fsys.nfs.enabled: - attr['nfs'] = NfsRule(enabled=module.params['nfsv3']) - mod_fs = True - if not module.params['nfsv3'] and fsys.nfs.enabled: - attr['nfs'] = NfsRule(enabled=module.params['nfsv3']) - mod_fs = True - if module.params['nfsv3'] and fsys.nfs.enabled: - if fsys.nfs.rules != module.params['nfs_rules']: - attr['nfs'] = NfsRule(rules=module.params['nfs_rules']) - mod_fs = True - if module.params['smb'] and not fsys.smb.enabled: - attr['smb'] = ProtocolRule(enabled=module.params['smb']) - mod_fs = True - if not module.params['smb'] and fsys.smb.enabled: - attr['smb'] = ProtocolRule(enabled=module.params['smb']) - mod_fs = True - if module.params['http'] and not fsys.http.enabled: - attr['http'] = ProtocolRule(enabled=module.params['http']) - mod_fs = True - if not module.params['http'] and fsys.http.enabled: - attr['http'] = ProtocolRule(enabled=module.params['http']) - mod_fs = True - if module.params['snapshot'] and not fsys.snapshot_directory_enabled: - attr['snapshot_directory_enabled'] = module.params['snapshot'] - mod_fs = True - if not module.params['snapshot'] and fsys.snapshot_directory_enabled: - attr['snapshot_directory_enabled'] = module.params['snapshot'] - mod_fs = True - if module.params['fastremove'] and not fsys.fast_remove_directory_enabled: - attr['fast_remove_directory_enabled'] = module.params['fastremove'] - mod_fs = True - if not module.params['fastremove'] and fsys.fast_remove_directory_enabled: - attr['fast_remove_directory_enabled'] = module.params['fastremove'] - mod_fs = True - api_version = blade.api_version.list_versions().versions - if HARD_LIMIT_API_VERSION in api_version: - if not module.params['hard_limit'] and fsys.hard_limit_enabled: - attr['hard_limit_enabled'] = module.params['hard_limit'] - mod_fs = True - if module.params['hard_limit'] and not fsys.hard_limit_enabled: - attr['hard_limit_enabled'] = module.params['hard_limit'] - mod_fs = True - if mod_fs: - n_attr = FileSystem(**attr) - try: - blade.file_systems.update_file_systems(name=module.params['name'], attributes=n_attr) - except Exception: - module.fail_json(msg="Failed to update filesystem {0}.".format(module.params['name'])) - else: - changed = False - module.exit_json(changed=changed) - - -def delete_fs(module, blade): - """ Delete Filesystem""" - changed = True - if not module.check_mode: - try: - api_version = blade.api_version.list_versions().versions - if NFSV4_API_VERSION in api_version: - blade.file_systems.update_file_systems(name=module.params['name'], - attributes=FileSystem(nfs=NfsRule(v3_enabled=False, - v4_1_enabled=False), - smb=ProtocolRule(enabled=False), - http=ProtocolRule(enabled=False), - destroyed=True) - ) - else: - blade.file_systems.update_file_systems(name=module.params['name'], - attributes=FileSystem(nfs=NfsRule(enabled=False), - smb=ProtocolRule(enabled=False), - http=ProtocolRule(enabled=False), - destroyed=True) - ) - - if module.params['eradicate']: - try: - blade.file_systems.delete_file_systems(module.params['name']) - except Exception: - module.fail_json(msg="Failed to delete filesystem {0}.".format(module.params['name'])) - except Exception: - module.fail_json(msg="Failed to update filesystem {0} prior to deletion.".format(module.params['name'])) - module.exit_json(changed=changed) - - -def eradicate_fs(module, blade): - """ Eradicate Filesystem""" - changed = True - if not module.check_mode: - try: - blade.file_systems.delete_file_systems(module.params['name']) - except Exception: - module.fail_json(msg="Failed to eradicate filesystem {0}.".format(module.params['name'])) - module.exit_json(changed=changed) - - -def main(): - argument_spec = purefb_argument_spec() - argument_spec.update( - dict( - name=dict(required=True), - eradicate=dict(default='false', type='bool'), - nfsv3=dict(default='true', type='bool'), - nfsv4=dict(default='true', type='bool'), - nfs_rules=dict(default='*(rw,no_root_squash)'), - smb=dict(default='false', type='bool'), - http=dict(default='false', type='bool'), - snapshot=dict(default='false', type='bool'), - fastremove=dict(default='false', type='bool'), - hard_limit=dict(default='false', type='bool'), - user_quota=dict(type='str'), - group_quota=dict(type='str'), - state=dict(default='present', choices=['present', 'absent']), - size=dict() - ) - ) - - module = AnsibleModule(argument_spec, - supports_check_mode=True) - - if not HAS_PURITY_FB: - module.fail_json(msg='purity_fb sdk is required for this module') - - state = module.params['state'] - blade = get_blade(module) - fsys = get_fs(module, blade) - - if state == 'present' and not fsys: - create_fs(module, blade) - elif state == 'present' and fsys: - modify_fs(module, blade) - elif state == 'absent' and fsys and not fsys.destroyed: - delete_fs(module, blade) - elif state == 'absent' and fsys and fsys.destroyed and module.params['eradicate']: - eradicate_fs(module, blade) - elif state == 'absent' and not fsys: - module.exit_json(changed=False) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/storage/purestorage/purefb_info.py b/lib/ansible/modules/storage/purestorage/purefb_info.py deleted file mode 100644 index 497576b9a07..00000000000 --- a/lib/ansible/modules/storage/purestorage/purefb_info.py +++ /dev/null @@ -1,663 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2019, Simon Dodsley (simon@purestorage.com) -# GNU General Public License v3.0+ (see COPYING or -# https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: purefb_info -version_added: '2.9' -short_description: Collect information from Pure Storage FlashBlade -description: - - Collect information from a Pure Storage FlashBlade running the - Purity//FB operating system. By default, the module will collect basic - information including hosts, host groups, protection - groups and volume counts. Additional information can be collected - based on the configured set of arguments. -author: - - Pure Storage Ansible Team (@sdodsley) -options: - gather_subset: - description: - - When supplied, this argument will define the information to be collected. - Possible values for this include all, minimum, config, performance, - capacity, network, subnets, lags, filesystems and snapshots. - required: false - type: list - default: minimum -extends_documentation_fragment: - - purestorage.fb -''' - -EXAMPLES = r''' -- name: collect default set of info - purefb_info: - fb_url: 10.10.10.2 - api_token: T-55a68eb5-c785-4720-a2ca-8b03903bf641 - register: blade_info -- name: show default information - debug: - msg: "{{ blade_info['purefb_info']['default'] }}" - -- name: collect configuration and capacity info - purefb_info: - gather_subset: - - config - fb_url: 10.10.10.2 - api_token: T-55a68eb5-c785-4720-a2ca-8b03903bf641 - register: blade_info -- name: show config information - debug: - msg: "{{ blade_info['purefb_info']['config'] }}" - -- name: collect all info - purefb_info: - gather_subset: - - all - fb_url: 10.10.10.2 - api_token: T-55a68eb5-c785-4720-a2ca-8b03903bf641 - register: blade_info -- name: show all information - debug: - msg: "{{ blade_info['purefb_info'] }}" -''' - -RETURN = r''' -purefb_info: - description: Returns the information collected from the FlashBlade - returned: always - type: complex - sample: { - "capacity": { - "aggregate": { - "data_reduction": 1.1179228, - "snapshots": 0, - "total_physical": 17519748439, - "unique": 17519748439, - "virtual": 19585726464 - }, - "file-system": { - "data_reduction": 1.3642412, - "snapshots": 0, - "total_physical": 4748219708, - "unique": 4748219708, - "virtual": 6477716992 - }, - "object-store": { - "data_reduction": 1.0263462, - "snapshots": 0, - "total_physical": 12771528731, - "unique": 12771528731, - "virtual": 6477716992 - }, - "total": 83359896948925 - }, - "config": { - "alert_watchers": { - "enabled": true, - "name": "notify@acmestorage.com" - }, - "array_management": { - "base_dn": null, - "bind_password": null, - "bind_user": null, - "enabled": false, - "name": "management", - "services": [ - "management" - ], - "uris": [] - }, - "directory_service_roles": { - "array_admin": { - "group": null, - "group_base": null - }, - "ops_admin": { - "group": null, - "group_base": null - }, - "readonly": { - "group": null, - "group_base": null - }, - "storage_admin": { - "group": null, - "group_base": null - } - }, - "dns": { - "domain": "demo.acmestorage.com", - "name": "demo-fb-1", - "nameservers": [ - "8.8.8.8" - ], - "search": [ - "demo.acmestorage.com" - ] - }, - "nfs_directory_service": { - "base_dn": null, - "bind_password": null, - "bind_user": null, - "enabled": false, - "name": "nfs", - "services": [ - "nfs" - ], - "uris": [] - }, - "ntp": [ - "0.ntp.pool.org" - ], - "smb_directory_service": { - "base_dn": null, - "bind_password": null, - "bind_user": null, - "enabled": false, - "name": "smb", - "services": [ - "smb" - ], - "uris": [] - }, - "smtp": { - "name": "demo-fb-1", - "relay_host": null, - "sender_domain": "acmestorage.com" - }, - "ssl_certs": { - "certificate": "-----BEGIN CERTIFICATE-----\n\n-----END CERTIFICATE-----", - "common_name": "Acme Storage", - "country": "US", - "email": null, - "intermediate_certificate": null, - "issued_by": "Acme Storage", - "issued_to": "Acme Storage", - "key_size": 4096, - "locality": null, - "name": "global", - "organization": "Acme Storage", - "organizational_unit": "Acme Storage", - "passphrase": null, - "private_key": null, - "state": null, - "status": "self-signed", - "valid_from": "1508433967000", - "valid_to": "2458833967000" - } - }, - "default": { - "blades": 15, - "buckets": 7, - "filesystems": 2, - "flashblade_name": "demo-fb-1", - "object_store_accounts": 1, - "object_store_users": 1, - "purity_version": "2.2.0", - "snapshots": 1, - "total_capacity": 83359896948925 - }, - "filesystems": { - "k8s-pvc-d24b1357-579e-11e8-811f-ecf4bbc88f54": { - "destroyed": false, - "fast_remove": false, - "hard_limit": true, - "nfs_rules": "*(rw,no_root_squash)", - "provisioned": 21474836480, - "snapshot_enabled": false - }, - "z": { - "destroyed": false, - "fast_remove": false, - "hard_limit": false, - "provisioned": 1073741824, - "snapshot_enabled": false - } - }, - "lag": { - "uplink": { - "lag_speed": 0, - "port_speed": 40000000000, - "ports": [ - { - "name": "CH1.FM1.ETH1.1" - }, - { - "name": "CH1.FM1.ETH1.2" - }, - ], - "status": "healthy" - } - }, - "network": { - "fm1.admin0": { - "address": "10.10.100.6", - "gateway": "10.10.100.1", - "mtu": 1500, - "netmask": "255.255.255.0", - "services": [ - "support" - ], - "type": "vip", - "vlan": 2200 - }, - "fm2.admin0": { - "address": "10.10.100.7", - "gateway": "10.10.100.1", - "mtu": 1500, - "netmask": "255.255.255.0", - "services": [ - "support" - ], - "type": "vip", - "vlan": 2200 - }, - "nfs1": { - "address": "10.10.100.4", - "gateway": "10.10.100.1", - "mtu": 1500, - "netmask": "255.255.255.0", - "services": [ - "data" - ], - "type": "vip", - "vlan": 2200 - }, - "vir0": { - "address": "10.10.100.5", - "gateway": "10.10.100.1", - "mtu": 1500, - "netmask": "255.255.255.0", - "services": [ - "management" - ], - "type": "vip", - "vlan": 2200 - } - }, - "performance": { - "aggregate": { - "bytes_per_op": 0, - "bytes_per_read": 0, - "bytes_per_write": 0, - "read_bytes_per_sec": 0, - "reads_per_sec": 0, - "usec_per_other_op": 0, - "usec_per_read_op": 0, - "usec_per_write_op": 0, - "write_bytes_per_sec": 0, - "writes_per_sec": 0 - }, - "http": { - "bytes_per_op": 0, - "bytes_per_read": 0, - "bytes_per_write": 0, - "read_bytes_per_sec": 0, - "reads_per_sec": 0, - "usec_per_other_op": 0, - "usec_per_read_op": 0, - "usec_per_write_op": 0, - "write_bytes_per_sec": 0, - "writes_per_sec": 0 - }, - "nfs": { - "bytes_per_op": 0, - "bytes_per_read": 0, - "bytes_per_write": 0, - "read_bytes_per_sec": 0, - "reads_per_sec": 0, - "usec_per_other_op": 0, - "usec_per_read_op": 0, - "usec_per_write_op": 0, - "write_bytes_per_sec": 0, - "writes_per_sec": 0 - }, - "s3": { - "bytes_per_op": 0, - "bytes_per_read": 0, - "bytes_per_write": 0, - "read_bytes_per_sec": 0, - "reads_per_sec": 0, - "usec_per_other_op": 0, - "usec_per_read_op": 0, - "usec_per_write_op": 0, - "write_bytes_per_sec": 0, - "writes_per_sec": 0 - } - }, - "snapshots": { - "z.188": { - "destroyed": false, - "source": "z", - "source_destroyed": false, - "suffix": "188" - } - }, - "subnet": { - "new-mgmt": { - "gateway": "10.10.100.1", - "interfaces": [ - { - "name": "fm1.admin0" - }, - { - "name": "fm2.admin0" - }, - { - "name": "nfs1" - }, - { - "name": "vir0" - } - ], - "lag": "uplink", - "mtu": 1500, - "prefix": "10.10.100.0/24", - "services": [ - "data", - "management", - "support" - ], - "vlan": 2200 - } - } - } -''' - - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.pure import get_blade, purefb_argument_spec - - -MIN_REQUIRED_API_VERSION = '1.3' -HARD_LIMIT_API_VERSION = '1.4' - - -def generate_default_dict(blade): - default_info = {} - defaults = blade.arrays.list_arrays().items[0] - default_info['flashblade_name'] = defaults.name - default_info['purity_version'] = defaults.version - default_info['filesystems'] = \ - len(blade.file_systems.list_file_systems().items) - default_info['snapshots'] = \ - len(blade.file_system_snapshots.list_file_system_snapshots().items) - default_info['buckets'] = len(blade.buckets.list_buckets().items) - default_info['object_store_users'] = \ - len(blade.object_store_users.list_object_store_users().items) - default_info['object_store_accounts'] = \ - len(blade.object_store_accounts.list_object_store_accounts().items) - default_info['blades'] = len(blade.blade.list_blades().items) - default_info['total_capacity'] = \ - blade.arrays.list_arrays_space().items[0].capacity - return default_info - - -def generate_perf_dict(blade): - perf_info = {} - total_perf = blade.arrays.list_arrays_performance() - http_perf = blade.arrays.list_arrays_performance(protocol='http') - s3_perf = blade.arrays.list_arrays_performance(protocol='s3') - nfs_perf = blade.arrays.list_arrays_performance(protocol='nfs') - perf_info['aggregate'] = { - 'bytes_per_op': total_perf.items[0].bytes_per_op, - 'bytes_per_read': total_perf.items[0].bytes_per_read, - 'bytes_per_write': total_perf.items[0].bytes_per_write, - 'read_bytes_per_sec': total_perf.items[0].read_bytes_per_sec, - 'reads_per_sec': total_perf.items[0].reads_per_sec, - 'usec_per_other_op': total_perf.items[0].usec_per_other_op, - 'usec_per_read_op': total_perf.items[0].usec_per_read_op, - 'usec_per_write_op': total_perf.items[0].usec_per_write_op, - 'write_bytes_per_sec': total_perf.items[0].write_bytes_per_sec, - 'writes_per_sec': total_perf.items[0].writes_per_sec, - } - perf_info['http'] = { - 'bytes_per_op': http_perf.items[0].bytes_per_op, - 'bytes_per_read': http_perf.items[0].bytes_per_read, - 'bytes_per_write': http_perf.items[0].bytes_per_write, - 'read_bytes_per_sec': http_perf.items[0].read_bytes_per_sec, - 'reads_per_sec': http_perf.items[0].reads_per_sec, - 'usec_per_other_op': http_perf.items[0].usec_per_other_op, - 'usec_per_read_op': http_perf.items[0].usec_per_read_op, - 'usec_per_write_op': http_perf.items[0].usec_per_write_op, - 'write_bytes_per_sec': http_perf.items[0].write_bytes_per_sec, - 'writes_per_sec': http_perf.items[0].writes_per_sec, - } - perf_info['s3'] = { - 'bytes_per_op': s3_perf.items[0].bytes_per_op, - 'bytes_per_read': s3_perf.items[0].bytes_per_read, - 'bytes_per_write': s3_perf.items[0].bytes_per_write, - 'read_bytes_per_sec': s3_perf.items[0].read_bytes_per_sec, - 'reads_per_sec': s3_perf.items[0].reads_per_sec, - 'usec_per_other_op': s3_perf.items[0].usec_per_other_op, - 'usec_per_read_op': s3_perf.items[0].usec_per_read_op, - 'usec_per_write_op': s3_perf.items[0].usec_per_write_op, - 'write_bytes_per_sec': s3_perf.items[0].write_bytes_per_sec, - 'writes_per_sec': s3_perf.items[0].writes_per_sec, - } - perf_info['nfs'] = { - 'bytes_per_op': nfs_perf.items[0].bytes_per_op, - 'bytes_per_read': nfs_perf.items[0].bytes_per_read, - 'bytes_per_write': nfs_perf.items[0].bytes_per_write, - 'read_bytes_per_sec': nfs_perf.items[0].read_bytes_per_sec, - 'reads_per_sec': nfs_perf.items[0].reads_per_sec, - 'usec_per_other_op': nfs_perf.items[0].usec_per_other_op, - 'usec_per_read_op': nfs_perf.items[0].usec_per_read_op, - 'usec_per_write_op': nfs_perf.items[0].usec_per_write_op, - 'write_bytes_per_sec': nfs_perf.items[0].write_bytes_per_sec, - 'writes_per_sec': nfs_perf.items[0].writes_per_sec, - } - - return perf_info - - -def generate_config_dict(blade): - config_info = {} - config_info['dns'] = blade.dns.list_dns().items[0].to_dict() - config_info['smtp'] = blade.smtp.list_smtp().items[0].to_dict() - config_info['alert_watchers'] = \ - blade.alert_watchers.list_alert_watchers().items[0].to_dict() - api_version = blade.api_version.list_versions().versions - if HARD_LIMIT_API_VERSION in api_version: - config_info['array_management'] = \ - blade.directory_services.list_directory_services(names=['management']).items[0].to_dict() - config_info['directory_service_roles'] = {} - roles = blade.directory_services.list_directory_services_roles() - for role in range(0, len(roles.items)): - role_name = roles.items[role].name - config_info['directory_service_roles'][role_name] = { - 'group': roles.items[role].group, - 'group_base': roles.items[role].group_base - } - config_info['nfs_directory_service'] = \ - blade.directory_services.list_directory_services(names=['nfs']).items[0].to_dict() - config_info['smb_directory_service'] = \ - blade.directory_services.list_directory_services(names=['smb']).items[0].to_dict() - config_info['ntp'] = blade.arrays.list_arrays().items[0].ntp_servers - config_info['ssl_certs'] = \ - blade.certificates.list_certificates().items[0].to_dict() - return config_info - - -def generate_subnet_dict(blade): - sub_info = {} - subnets = blade.subnets.list_subnets() - for sub in range(0, len(subnets.items)): - sub_name = subnets.items[sub].name - if subnets.items[sub].enabled: - sub_info[sub_name] = { - 'gateway': subnets.items[sub].gateway, - 'mtu': subnets.items[sub].mtu, - 'vlan': subnets.items[sub].vlan, - 'prefix': subnets.items[sub].prefix, - 'services': subnets.items[sub].services, - } - sub_info[sub_name]['lag'] = subnets.items[sub].link_aggregation_group.name - sub_info[sub_name]['interfaces'] = [] - for iface in range(0, len(subnets.items[sub].interfaces)): - sub_info[sub_name]['interfaces'].append({'name': subnets.items[sub].interfaces[iface].name}) - return sub_info - - -def generate_lag_dict(blade): - lag_info = {} - groups = blade.link_aggregation_groups.list_link_aggregation_groups() - for groupcnt in range(0, len(groups.items)): - lag_name = groups.items[groupcnt].name - lag_info[lag_name] = { - 'lag_speed': groups.items[groupcnt].lag_speed, - 'port_speed': groups.items[groupcnt].port_speed, - 'status': groups.items[groupcnt].status, - } - lag_info[lag_name]['ports'] = [] - for port in range(0, len(groups.items[groupcnt].ports)): - lag_info[lag_name]['ports'].append({'name': groups.items[groupcnt].ports[port].name}) - return lag_info - - -def generate_network_dict(blade): - net_info = {} - ports = blade.network_interfaces.list_network_interfaces() - for portcnt in range(0, len(ports.items)): - int_name = ports.items[portcnt].name - if ports.items[portcnt].enabled: - net_info[int_name] = { - 'type': ports.items[portcnt].type, - 'mtu': ports.items[portcnt].mtu, - 'vlan': ports.items[portcnt].vlan, - 'address': ports.items[portcnt].address, - 'services': ports.items[portcnt].services, - 'gateway': ports.items[portcnt].gateway, - 'netmask': ports.items[portcnt].netmask, - } - return net_info - - -def generate_capacity_dict(blade): - capacity_info = {} - total_cap = blade.arrays.list_arrays_space() - file_cap = blade.arrays.list_arrays_space(type='file-system') - object_cap = blade.arrays.list_arrays_space(type='object-store') - capacity_info['total'] = total_cap.items[0].capacity - capacity_info['aggregate'] = { - 'data_reduction': total_cap.items[0].space.data_reduction, - 'snapshots': total_cap.items[0].space.snapshots, - 'total_physical': total_cap.items[0].space.total_physical, - 'unique': total_cap.items[0].space.unique, - 'virtual': total_cap.items[0].space.virtual, - } - capacity_info['file-system'] = { - 'data_reduction': file_cap.items[0].space.data_reduction, - 'snapshots': file_cap.items[0].space.snapshots, - 'total_physical': file_cap.items[0].space.total_physical, - 'unique': file_cap.items[0].space.unique, - 'virtual': file_cap.items[0].space.virtual, - } - capacity_info['object-store'] = { - 'data_reduction': object_cap.items[0].space.data_reduction, - 'snapshots': object_cap.items[0].space.snapshots, - 'total_physical': object_cap.items[0].space.total_physical, - 'unique': object_cap.items[0].space.unique, - 'virtual': file_cap.items[0].space.virtual, - } - - return capacity_info - - -def generate_snap_dict(blade): - snap_info = {} - snaps = blade.file_system_snapshots.list_file_system_snapshots() - for snap in range(0, len(snaps.items)): - snapshot = snaps.items[snap].name - snap_info[snapshot] = { - 'destroyed': snaps.items[snap].destroyed, - 'source': snaps.items[snap].source, - 'suffix': snaps.items[snap].suffix, - 'source_destroyed': snaps.items[snap].source_destroyed, - } - return snap_info - - -def generate_fs_dict(blade): - fs_info = {} - fsys = blade.file_systems.list_file_systems() - for fsystem in range(0, len(fsys.items)): - share = fsys.items[fsystem].name - fs_info[share] = { - 'fast_remove': fsys.items[fsystem].fast_remove_directory_enabled, - 'snapshot_enabled': fsys.items[fsystem].snapshot_directory_enabled, - 'provisioned': fsys.items[fsystem].provisioned, - 'destroyed': fsys.items[fsystem].destroyed, - } - if fsys.items[fsystem].http.enabled: - fs_info[share]['http'] = fsys.items[fsystem].http.enabled - if fsys.items[fsystem].smb.enabled: - fs_info[share]['smb_mode'] = fsys.items[fsystem].smb.acl_mode - if fsys.items[fsystem].nfs.enabled: - fs_info[share]['nfs_rules'] = fsys.items[fsystem].nfs.rules - api_version = blade.api_version.list_versions().versions - if HARD_LIMIT_API_VERSION in api_version: - fs_info[share]['hard_limit'] = fsys.items[fsystem].hard_limit_enabled - - return fs_info - - -def main(): - argument_spec = purefb_argument_spec() - argument_spec.update(dict( - gather_subset=dict(default='minimum', type='list',) - )) - - module = AnsibleModule(argument_spec, supports_check_mode=True) - - blade = get_blade(module) - versions = blade.api_version.list_versions().versions - - if MIN_REQUIRED_API_VERSION not in versions: - module.fail_json(msg='FlashBlade REST version not supported. Minimum version required: {0}'.format(MIN_REQUIRED_API_VERSION)) - - subset = [test.lower() for test in module.params['gather_subset']] - valid_subsets = ('all', 'minimum', 'config', 'performance', 'capacity', - 'network', 'subnets', 'lags', - 'filesystems', 'snapshots') - subset_test = (test in valid_subsets for test in subset) - if not all(subset_test): - module.fail_json(msg="value must gather_subset must be one or more of: %s, got: %s" - % (",".join(valid_subsets), ",".join(subset))) - - info = {} - - if 'minimum' in subset or 'all' in subset: - info['default'] = generate_default_dict(blade) - if 'performance' in subset or 'all' in subset: - info['performance'] = generate_perf_dict(blade) - if 'config' in subset or 'all' in subset: - info['config'] = generate_config_dict(blade) - if 'capacity' in subset or 'all' in subset: - info['capacity'] = generate_capacity_dict(blade) - if 'lags' in subset or 'all' in subset: - info['lag'] = generate_lag_dict(blade) - if 'network' in subset or 'all' in subset: - info['network'] = generate_network_dict(blade) - if 'subnets' in subset or 'all' in subset: - info['subnet'] = generate_subnet_dict(blade) - if 'filesystems' in subset or 'all' in subset: - info['filesystems'] = generate_fs_dict(blade) - if 'snapshots' in subset or 'all' in subset: - info['snapshots'] = generate_snap_dict(blade) - - module.exit_json(changed=False, purefb_info=info) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/storage/purestorage/purefb_network.py b/lib/ansible/modules/storage/purestorage/purefb_network.py deleted file mode 100644 index 90dc78b9312..00000000000 --- a/lib/ansible/modules/storage/purestorage/purefb_network.py +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2017, Simon Dodsley (simon@purestorage.com) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - - -DOCUMENTATION = ''' ---- -module: purefb_network -version_added: "2.8" -short_description: Manage network interfaces in a Pure Storage FlashBlade -description: - - This module manages network interfaces on Pure Storage FlashBlade. - - When creating a network interface a subnet must already exist with - a network prefix that covers the IP address of the interface being - created. -author: Pure Storage Ansible Team (@sdodsley) -options: - name: - description: - - Interface Name. - required: true - type: str - state: - description: - - Create, delete or modifies a network interface. - required: false - default: present - choices: [ "present", "absent" ] - type: str - address: - description: - - IP address of interface. - required: false - type: str - services: - description: - - Define which services are configured for the interfaces. - required: false - choices: [ "data" ] - default: data - type: str - itype: - description: - - Type of interface. - required: false - choices: [ "vip" ] - default: vip - type: str -extends_documentation_fragment: - - purestorage.fb -''' - -EXAMPLES = ''' -- name: Create new network interface named foo - purefb_network: - name: foo - address: 10.21.200.23 - state: present - fb_url: 10.10.10.2 - api_token: T-55a68eb5-c785-4720-a2ca-8b03903bf641 - -- name: Change IP address of network interface named foo - purefb_network: - name: foo - state: present - address: 10.21.200.123 - fb_url: 10.10.10.2 - api_token: T-55a68eb5-c785-4720-a2ca-8b03903bf641 - -- name: Delete network interface named foo - purefb_network: - name: foo - state: absent - fb_url: 10.10.10.2 - api_token: T-55a68eb5-c785-4720-a2ca-8b03903bf641''' - -RETURN = ''' -''' - -HAS_PURITY_FB = True -try: - from purity_fb import NetworkInterface -except ImportError: - HAS_PURITY_FB = False - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.pure import get_blade, purefb_argument_spec - - -MINIMUM_API_VERSION = '1.3' - - -def get_iface(module, blade): - """Return Filesystem or None""" - iface = [] - iface.append(module.params['name']) - try: - res = blade.network_interfaces.list_network_interfaces(names=iface) - return res.items[0] - except Exception: - return None - - -def create_iface(module, blade): - """Create Network Interface""" - - iface = [] - services = [] - iface.append(module.params['name']) - services.append(module.params['services']) - try: - blade.network_interfaces.create_network_interfaces(names=iface, - network_interface=NetworkInterface(address=module.params['address'], - services=services, - type=module.params['itype'] - ) - ) - changed = True - except Exception: - module.fail_json(msg='Interface creation failed. Check valid subnet exists for IP address {0}'.format(module.params['address'])) - changed = False - module.exit_json(changed=changed) - - -def modify_iface(module, blade): - """Modify Network Interface IP address""" - changed = False - iface = get_iface(module, blade) - iface_new = [] - iface_new.append(module.params['name']) - if module.params['address'] != iface.address: - try: - blade.network_interfaces.update_network_interfaces(names=iface_new, - network_interface=NetworkInterface(address=module.params['address'])) - changed = True - except Exception: - changed = False - module.exit_json(changed=changed) - - -def delete_iface(module, blade): - """ Delete Network Interface""" - iface = [] - iface.append(module.params['name']) - try: - blade.network_interfaces.delete_network_interfaces(names=iface) - changed = True - except Exception: - changed = False - module.exit_json(changed=changed) - - -def main(): - argument_spec = purefb_argument_spec() - argument_spec.update( - dict( - name=dict(required=True), - state=dict(default='present', choices=['present', 'absent']), - address=dict(), - services=dict(default='data', choices=['data']), - itype=dict(default='vip', choices=['vip']), - ) - ) - - required_if = [["state", "present", ["address"]]] - - module = AnsibleModule(argument_spec, - required_if=required_if, - supports_check_mode=False) - - if not HAS_PURITY_FB: - module.fail_json(msg='purity_fb sdk is required for this module') - - state = module.params['state'] - blade = get_blade(module) - api_version = blade.api_version.list_versions().versions - if MINIMUM_API_VERSION not in api_version: - module.fail_json(msg='Upgrade Purity//FB to enable this module') - iface = get_iface(module, blade) - - if state == 'present' and not iface: - create_iface(module, blade) - elif state == 'present' and iface: - modify_iface(module, blade) - elif state == 'absent' and iface: - delete_iface(module, blade) - elif state == 'absent' and not iface: - module.exit_json(changed=False) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/storage/purestorage/purefb_ra.py b/lib/ansible/modules/storage/purestorage/purefb_ra.py deleted file mode 100644 index fe82125e11e..00000000000 --- a/lib/ansible/modules/storage/purestorage/purefb_ra.py +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2018, Simon Dodsley (simon@purestorage.com) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: purefb_ra -version_added: '2.9' -short_description: Enable or Disable Pure Storage FlashBlade Remote Assist -description: -- Enable or Disable Remote Assist for a Pure Storage FlashBlade. -author: -- Pure Storage Ansible Team (@sdodsley) -options: - state: - description: - - Define state of remote assist - - When set to I(enable) the RA port can be exposed using the - I(debug) module. - type: str - default: present - choices: [ present, absent ] -extends_documentation_fragment: -- purestorage.fb -''' - -EXAMPLES = r''' -- name: Enable Remote Assist port - purefb_ra: - fb_url: 10.10.10.2 - api_token: T-9f276a18-50ab-446e-8a0c-666a3529a1b6 - -- name: Disable Remote Assist port - purefb_ra: - state: absent - fb_url: 10.10.10.2 - api_token: T-9f276a18-50ab-446e-8a0c-666a3529a1b6 -''' - -RETURN = r''' -''' - -HAS_PURITY_FB = True -try: - from purity_fb import Support -except ImportError: - HAS_PURITY_FB = False - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.pure import get_blade, purefb_argument_spec - - -MIN_REQUIRED_API_VERSION = "1.6" - - -def enable_ra(module, blade): - """Enable Remote Assist""" - changed = True - if not module.check_mode: - ra_settings = Support(remote_assist_active=True) - try: - blade.support.update_support(support=ra_settings) - except Exception: - module.fail_json(msg='Enabling Remote Assist failed') - module.exit_json(changed=changed) - - -def disable_ra(module, blade): - """Disable Remote Assist""" - changed = True - if not module.check_mode: - ra_settings = Support(remote_assist_active=False) - try: - blade.support.update_support(support=ra_settings) - except Exception: - module.fail_json(msg='Disabling Remote Assist failed') - module.exit_json(changed=changed) - - -def main(): - argument_spec = purefb_argument_spec() - argument_spec.update(dict( - state=dict(type='str', default='present', choices=['present', 'absent']), - )) - - module = AnsibleModule(argument_spec, - supports_check_mode=True) - - blade = get_blade(module) - api_version = blade.api_version.list_versions().versions - if MIN_REQUIRED_API_VERSION not in api_version: - module.fail_json(msg="Purity//FB must be upgraded to support this module.") - - if not HAS_PURITY_FB: - module.fail_json(msg='purity_fb SDK is required for this module') - - if module.params['state'] == 'present' and not blade.support.list_support().items[0].remote_assist_active: - enable_ra(module, blade) - elif module.params['state'] == 'absent' and blade.support.list_support().items[0].remote_assist_active: - disable_ra(module, blade) - module.exit_json(changed=False) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/storage/purestorage/purefb_s3acc.py b/lib/ansible/modules/storage/purestorage/purefb_s3acc.py deleted file mode 100644 index 041a76f5135..00000000000 --- a/lib/ansible/modules/storage/purestorage/purefb_s3acc.py +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2018, Simon Dodsley (simon@purestorage.com) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: purefb_s3acc -version_added: '2.8' -short_description: Create or delete FlashBlade Object Store accounts -description: -- Create or delete object store accounts on a Pure Storage FlashBlade. -author: -- Pure Storage Ansible Team (@sdodsley) -options: - state: - description: - - Create or delete object store account - default: present - choices: [ absent, present ] - type: str - name: - description: - - The name of object store account - type: str -extends_documentation_fragment: -- purestorage.fb -''' - -EXAMPLES = r''' -- name: Create object store account foo - purefb_s3acc: - name: foo - fb_url: 10.10.10.2 - api_token: e31060a7-21fc-e277-6240-25983c6c4592 - -- name: Delete object store account foo - purefb_s3acc: - name: foo - state: absent - fb_url: 10.10.10.2 - api_token: e31060a7-21fc-e277-6240-25983c6c4592 -''' - -RETURN = r''' -''' - - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.pure import get_blade, purefb_argument_spec - - -MIN_REQUIRED_API_VERSION = '1.3' - - -def get_s3acc(module, blade): - """Return Object Store Account or None""" - s3acc = None - accts = blade.object_store_accounts.list_object_store_accounts() - for acct in range(0, len(accts.items)): - if accts.items[acct].name == module.params['name']: - s3acc = accts.items[acct] - return s3acc - - -def update_s3acc(module, blade): - """Update Object Store Account""" - changed = False - module.exit_json(changed=changed) - - -def create_s3acc(module, blade): - """Create Object Store Account""" - changed = False - try: - blade.object_store_accounts.create_object_store_accounts(names=[module.params['name']]) - changed = True - except Exception: - module.fail_json(msg='Object Store Account {0}: Creation failed'.format(module.params['name'])) - module.exit_json(changed=changed) - - -def delete_s3acc(module, blade): - """Delete Object Store Account""" - changed = False - count = len(blade.object_store_users.list_object_store_users(filter='name=\'' + module.params['name'] + '/*\'').items) - if count != 0: - module.fail_json(msg='Remove all Users from Object Store Account {0} before deletion'.format(module.params['name'])) - else: - try: - blade.object_store_accounts.delete_object_store_accounts(names=[module.params['name']]) - changed = True - except Exception: - module.fail_json(msg='Object Store Account {0}: Deletion failed'.format(module.params['name'])) - module.exit_json(changed=changed) - - -def main(): - argument_spec = purefb_argument_spec() - argument_spec.update(dict( - name=dict(required=True, type='str'), - state=dict(default='present', choices=['present', 'absent']), - )) - - module = AnsibleModule(argument_spec, - supports_check_mode=False) - - state = module.params['state'] - blade = get_blade(module) - versions = blade.api_version.list_versions().versions - - if MIN_REQUIRED_API_VERSION not in versions: - module.fail_json(msg='FlashBlade REST version not supported. Minimum version required: {0}'.format(MIN_REQUIRED_API_VERSION)) - - s3acc = get_s3acc(module, blade) - - if state == 'absent' and s3acc: - delete_s3acc(module, blade) - elif state == 'present' and s3acc: - update_s3acc(module, blade) - elif not s3acc and state == 'present': - create_s3acc(module, blade) - else: - module.exit_json(changed=False) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/storage/purestorage/purefb_s3user.py b/lib/ansible/modules/storage/purestorage/purefb_s3user.py deleted file mode 100644 index 4981ba2e169..00000000000 --- a/lib/ansible/modules/storage/purestorage/purefb_s3user.py +++ /dev/null @@ -1,201 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2018, Simon Dodsley (simon@purestorage.com) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: purefb_s3user -version_added: '2.8' -short_description: Create or delete FlashBlade Object Store account users -description: -- Create or delete object store account users on a Pure Storage FlashBlade. -author: -- Pure Storage Ansible Team (@sdodsley) -options: - state: - description: - - Create or delete object store account user - default: present - choices: [ absent, present ] - type: str - name: - description: - - The name of object store user - type: str - account: - description: - - The name of object store account associated with user - type: str - access_key: - description: - - Create secret access key. - - Key can be exposed using the I(debug) module - type: bool - default: true -extends_documentation_fragment: -- purestorage.fb -''' - -EXAMPLES = r''' -- name: Create object store user (with access ID and key) foo in account bar - purefb_s3user: - name: foo - account: bar - fb_url: 10.10.10.2 - api_token: e31060a7-21fc-e277-6240-25983c6c4592 - register: result - -- debug: - msg: "S3 User: {{ result['s3user_info'] }}" - -- name: Delete object store user foo in account bar - purefb_s3user: - name: foo - account: bar - state: absent - fb_url: 10.10.10.2 - api_token: e31060a7-21fc-e277-6240-25983c6c4592 -''' - -RETURN = r''' -''' - - -HAS_PURITY_FB = True -try: - from purity_fb import ObjectStoreAccessKey -except ImportError: - HAS_PURITY_FB = False - - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.pure import get_blade, purefb_argument_spec - - -MIN_REQUIRED_API_VERSION = '1.3' - - -def get_s3acc(module, blade): - """Return Object Store Account or None""" - s3acc = None - accts = blade.object_store_accounts.list_object_store_accounts() - for acct in range(0, len(accts.items)): - if accts.items[acct].name == module.params['account']: - s3acc = accts.items[acct] - return s3acc - - -def get_s3user(module, blade): - """Return Object Store Account or None""" - full_user = module.params['account'] + "/" + module.params['name'] - s3user = None - s3users = blade.object_store_users.list_object_store_users() - for user in range(0, len(s3users.items)): - if s3users.items[user].name == full_user: - s3user = s3users.items[user] - return s3user - - -def update_s3user(module, blade): - """Update Object Store User""" - changed = False - s3user_facts = {} - user = module.params['account'] + "/" + module.params['name'] - if module.params['access_key']: - try: - result = blade.object_store_access_keys.create_object_store_access_keys( - object_store_access_key=ObjectStoreAccessKey(user={'name': user})) - s3user_facts['fb_s3user'] = {'user': user, - 'access_key': result.items[0].secret_access_key, - 'access_id': result.items[0].name} - except Exception: - delete_s3user(module, blade) - module.fail_json(msg='Object Store User {0}: Creation failed'.format(user)) - changed = True - module.exit_json(changed=changed, s3user_info=s3user_facts) - - -def create_s3user(module, blade): - """Create Object Store Account""" - s3user_facts = {} - changed = False - user = module.params['account'] + "/" + module.params['name'] - try: - blade.object_store_users.create_object_store_users(names=[user]) - if module.params['access_key']: - try: - result = blade.object_store_access_keys.create_object_store_access_keys( - object_store_access_key=ObjectStoreAccessKey(user={'name': user})) - s3user_facts['fb_s3user'] = {'user': user, - 'access_key': result.items[0].secret_access_key, - 'access_id': result.items[0].name} - except Exception: - delete_s3user(module, blade) - module.fail_json(msg='Object Store User {0}: Creation failed'.format(user)) - changed = True - except Exception: - module.fail_json(msg='Object Store User {0}: Creation failed'.format(user)) - module.exit_json(changed=changed, s3user_info=s3user_facts) - - -def delete_s3user(module, blade): - """Delete Object Store Account""" - changed = False - user = module.params['account'] + "/" + module.params['name'] - try: - blade.object_store_users.delete_object_store_users(names=[user]) - changed = True - except Exception: - module.fail_json(msg='Object Store Account {0}: Deletion failed'.format(module.params['name'])) - module.exit_json(changed=changed) - - -def main(): - argument_spec = purefb_argument_spec() - argument_spec.update(dict( - name=dict(required=True, type='str'), - account=dict(required=True, type='str'), - access_key=dict(default='true', type='bool'), - state=dict(default='present', choices=['present', 'absent']), - )) - - module = AnsibleModule(argument_spec, - supports_check_mode=False) - - if not HAS_PURITY_FB: - module.fail_json(msg='purity_fb sdk is required for this module') - - state = module.params['state'] - blade = get_blade(module) - versions = blade.api_version.list_versions().versions - - if MIN_REQUIRED_API_VERSION not in versions: - module.fail_json(msg='FlashBlade REST version not supported. Minimum version required: {0}'.format(MIN_REQUIRED_API_VERSION)) - - s3acc = get_s3acc(module, blade) - if not s3acc: - module.fail_json(msg='Object Store Account {0} does not exist'.format(module.params['account'])) - - s3user = get_s3user(module, blade) - - if state == 'absent' and s3user: - delete_s3user(module, blade) - elif state == 'present' and s3user: - update_s3user(module, blade) - elif not s3user and state == 'present': - create_s3user(module, blade) - else: - module.exit_json(changed=False) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/storage/purestorage/purefb_smtp.py b/lib/ansible/modules/storage/purestorage/purefb_smtp.py deleted file mode 100644 index f1ed16e73ba..00000000000 --- a/lib/ansible/modules/storage/purestorage/purefb_smtp.py +++ /dev/null @@ -1,112 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2018, Simon Dodsley (simon@purestorage.com) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: purefb_smtp -version_added: '2.9' -short_description: Configure SMTP for Pure Storage FlashBlade -description: -- Configure SMTP for a Pure Storage FlashBlade. -- Whilst there can be no relay host, a sender domain must be configured. -author: -- Pure Storage Ansible Team (@sdodsley) -options: - host: - description: Relay server name - type: str - domain: - description: Domain name for alert messages - required: true - type: str -extends_documentation_fragment: -- purestorage.fb -''' - -EXAMPLES = r''' -- name: Configure SMTP settings - purefb_smtp: - host: hostname - domain: xyz.com - fb_url: 10.10.10.2 - api_token: T-9f276a18-50ab-446e-8a0c-666a3529a1b6 -''' - -RETURN = r''' -''' - -HAS_PURITY_FB = True -try: - from purity_fb import Smtp -except ImportError: - HAS_PURITY_FB = False - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.pure import get_blade, purefb_argument_spec - - -MIN_REQUIRED_API_VERSION = "1.6" - - -def set_smtp(module, blade): - """Configure SMTP settings""" - changed = True - if not module.check_mode: - current_smtp = blade.smtp.list_smtp().items[0] - if module.params['host'] and module.params['host'] != current_smtp.relay_host: - smtp_settings = Smtp(relay_host=module.params['host']) - try: - blade.smtp.update_smtp(smtp_settings=smtp_settings) - except Exception: - module.fail_json(msg='Configuring SMTP relay host failed') - elif current_smtp.relay_host and not module.params['host']: - smtp_settings = Smtp(relay_host='') - try: - blade.smtp.update_smtp(smtp_settings=smtp_settings) - except Exception: - module.fail_json(msg='Configuring SMTP relay host failed') - if module.params['domain'] != current_smtp.sender_domain: - smtp_settings = Smtp(sender_domain=module.params['domain']) - try: - blade.smtp.update_smtp(smtp_settings=smtp_settings) - except Exception: - module.fail_json(msg='Configuring SMTP sender domain failed') - else: - changed = False - module.exit_json(changed=changed) - - -def main(): - argument_spec = purefb_argument_spec() - argument_spec.update(dict( - host=dict(type='str'), - domain=dict(type='str', required=True), - )) - - module = AnsibleModule(argument_spec, - supports_check_mode=True) - - blade = get_blade(module) - api_version = blade.api_version.list_versions().versions - if MIN_REQUIRED_API_VERSION not in api_version: - module.fail_json(msg="Purity//FB must be upgraded to support this module.") - - if not HAS_PURITY_FB: - module.fail_json(msg='purity_fb SDK is required for this module') - - set_smtp(module, blade) - module.exit_json(changed=False) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/storage/purestorage/purefb_snap.py b/lib/ansible/modules/storage/purestorage/purefb_snap.py deleted file mode 100644 index eaadea0a139..00000000000 --- a/lib/ansible/modules/storage/purestorage/purefb_snap.py +++ /dev/null @@ -1,227 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2017, Simon Dodsley (simon@purestorage.com) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = r''' ---- -module: purefb_snap -version_added: '2.6' -short_description: Manage filesystem snapshots on Pure Storage FlashBlades -description: -- Create or delete volumes and filesystem snapshots on Pure Storage FlashBlades. -author: -- Pure Storage Ansible Team (@sdodsley) -options: - name: - description: - - The name of the source filesystem. - required: true - type: str - suffix: - description: - - Suffix of snapshot name. - type: str - state: - description: - - Define whether the filesystem snapshot should exist or not. - choices: [ absent, present ] - default: present - type: str - eradicate: - description: - - Define whether to eradicate the snapshot on delete or leave in trash. - type: bool - default: 'no' -extends_documentation_fragment: -- purestorage.fb -''' - -EXAMPLES = r''' -- name: Create snapshot foo.ansible - purefb_snap: - name: foo - suffix: ansible - fb_url: 10.10.10.2 - fb_api_token: e31060a7-21fc-e277-6240-25983c6c4592 - state: present - -- name: Delete snapshot named foo.snap - purefb_snap: - name: foo - suffix: snap - fb_url: 10.10.10.2 - fb_api_token: e31060a7-21fc-e277-6240-25983c6c4592 - state: absent - -- name: Recover deleted snapshot foo.ansible - purefb_snap: - name: foo - suffix: ansible - fb_url: 10.10.10.2 - fb_api_token: e31060a7-21fc-e277-6240-25983c6c4592 - state: present - -- name: Eradicate snapshot named foo.snap - purefb_snap: - name: foo - suffix: snap - eradicate: true - fb_url: 10.10.10.2 - fb_api_token: e31060a7-21fc-e277-6240-25983c6c4592 - state: absent -''' - -RETURN = r''' -''' - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.pure import get_blade, purefb_argument_spec - -from datetime import datetime - -HAS_PURITY_FB = True -try: - from purity_fb import FileSystemSnapshot, SnapshotSuffix -except ImportError: - HAS_PURITY_FB = False - - -def get_fs(module, blade): - """Return Filesystem or None""" - fs = [] - fs.append(module.params['name']) - try: - res = blade.file_systems.list_file_systems(names=fs) - return res.items[0] - except Exception: - return None - - -def get_fssnapshot(module, blade): - """Return Snapshot or None""" - try: - filt = 'source=\'' + module.params['name'] + '\' and suffix=\'' + module.params['suffix'] + '\'' - res = blade.file_system_snapshots.list_file_system_snapshots(filter=filt) - return res.items[0] - except Exception: - return None - - -def create_snapshot(module, blade): - """Create Snapshot""" - if not module.check_mode: - source = [] - source.append(module.params['name']) - try: - blade.file_system_snapshots.create_file_system_snapshots(sources=source, suffix=SnapshotSuffix(module.params['suffix'])) - changed = True - except Exception: - changed = False - module.exit_json(changed=changed) - - -def recover_snapshot(module, blade): - """Recover deleted Snapshot""" - if not module.check_mode: - snapname = module.params['name'] + "." + module.params['suffix'] - new_attr = FileSystemSnapshot(destroyed=False) - try: - blade.file_system_snapshots.update_file_system_snapshots(name=snapname, attributes=new_attr) - changed = True - except Exception: - changed = False - module.exit_json(changed=changed) - - -def update_snapshot(module, blade): - """Update Snapshot""" - changed = False - module.exit_json(changed=changed) - - -def delete_snapshot(module, blade): - """ Delete Snapshot""" - if not module.check_mode: - snapname = module.params['name'] + "." + module.params['suffix'] - new_attr = FileSystemSnapshot(destroyed=True) - try: - blade.file_system_snapshots.update_file_system_snapshots(name=snapname, attributes=new_attr) - changed = True - if module.params['eradicate']: - try: - blade.file_system_snapshots.delete_file_system_snapshots(name=snapname) - changed = True - except Exception: - changed = False - except Exception: - changed = False - module.exit_json(changed=changed) - - -def eradicate_snapshot(module, blade): - """ Eradicate Snapshot""" - if not module.check_mode: - snapname = module.params['name'] + "." + module.params['suffix'] - try: - blade.file_system_snapshots.delete_file_system_snapshots(name=snapname) - changed = True - except Exception: - changed = False - module.exit_json(changed=changed) - - -def main(): - argument_spec = purefb_argument_spec() - argument_spec.update( - dict( - name=dict(required=True), - suffix=dict(type='str'), - eradicate=dict(default='false', type='bool'), - state=dict(default='present', choices=['present', 'absent']) - ) - ) - - module = AnsibleModule(argument_spec, - supports_check_mode=True) - - if not HAS_PURITY_FB: - module.fail_json(msg='purity_fb sdk is required for this module') - - 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(".", "") - - state = module.params['state'] - blade = get_blade(module) - fs = get_fs(module, blade) - snap = get_fssnapshot(module, blade) - - if state == 'present' and fs and not fs.destroyed and not snap: - create_snapshot(module, blade) - elif state == 'present' and fs and not fs.destroyed and snap and not snap.destroyed: - update_snapshot(module, blade) - elif state == 'present' and fs and not fs.destroyed and snap and snap.destroyed: - recover_snapshot(module, blade) - elif state == 'present' and fs and fs.destroyed: - update_snapshot(module, blade) - elif state == 'present' and not fs: - update_snapshot(module, blade) - elif state == 'absent' and snap and not snap.destroyed: - delete_snapshot(module, blade) - elif state == 'absent' and snap and snap.destroyed: - eradicate_snapshot(module, blade) - elif state == 'absent' and not snap: - module.exit_json(changed=False) - - -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/storage/purestorage/purefb_subnet.py b/lib/ansible/modules/storage/purestorage/purefb_subnet.py deleted file mode 100644 index 08b96965731..00000000000 --- a/lib/ansible/modules/storage/purestorage/purefb_subnet.py +++ /dev/null @@ -1,264 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2017, Simon Dodsley (simon@purestorage.com) -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - - -DOCUMENTATION = ''' ---- -module: purefb_subnet -version_added: "2.8" -short_description: Manage network subnets in a Pure Storage FlashBlade -description: - - This module manages network subnets on Pure Storage FlashBlade. -author: Pure Storage Ansible Team (@sdodsley) -options: - name: - description: - - Subnet Name. - required: true - type: str - state: - description: - - Create, delete or modifies a subnet. - required: false - default: present - choices: [ "present", "absent" ] - type: str - gateway: - description: - - IPv4 or IPv6 address of subnet gateway. - required: false - type: str - mtu: - description: - - MTU size of the subnet. Range is 1280 to 9216. - required: false - default: 1500 - type: int - prefix: - description: - - IPv4 or IPv6 address associated with the subnet. - - Supply the prefix length (CIDR) as well as the IP address. - required: false - type: str - vlan: - description: - - VLAN ID of the subnet. - required: false - default: 0 - type: int -extends_documentation_fragment: - - purestorage.fb -notes: - - Requires the netaddr Python package on the host. -requirements: - - netaddr -''' - -EXAMPLES = ''' -- name: Create new network subnet named foo - purefb_subnet: - name: foo - prefix: "10.21.200.3/24" - gateway: 10.21.200.1 - mtu: 9000 - vlan: 2200 - state: present - fb_url: 10.10.10.2 - api_token: T-55a68eb5-c785-4720-a2ca-8b03903bf641 - -- name: Change configuration of existing subnet foo - purefb_network: - name: foo - state: present - prefix: "10.21.100.3/24" - gateway: 10.21.100.1 - mtu: 1500 - address: 10.21.200.123 - fb_url: 10.10.10.2 - api_token: T-55a68eb5-c785-4720-a2ca-8b03903bf641 - -- name: Delete network subnet named foo - purefb_subnet: - name: foo - state: absent - fb_url: 10.10.10.2 - api_token: T-55a68eb5-c785-4720-a2ca-8b03903bf641''' - -RETURN = ''' -''' - -HAS_PURITY_FB = True -try: - from purity_fb import Subnet -except ImportError: - HAS_PURITY_FB = False - -try: - import netaddr - HAS_NETADDR = True -except ImportError: - HAS_NETADDR = False - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.pure import get_blade, purefb_argument_spec - - -MINIMUM_API_VERSION = '1.3' - - -def get_subnet(module, blade): - """Return Subnet or None""" - subnet = [] - subnet.append(module.params['name']) - try: - res = blade.subnets.list_subnets(names=subnet) - return res.items[0] - except Exception: - return None - - -def create_subnet(module, blade): - """Create Subnet""" - - subnet = [] - subnet.append(module.params['name']) - try: - blade.subnets.create_subnets(names=subnet, - subnet=Subnet(prefix=module.params['prefix'], - vlan=module.params['vlan'], - mtu=module.params['mtu'], - gateway=module.params['gateway'] - ) - ) - changed = True - except Exception: - module.fail_json(msg='Failed to create subnet {0}. Confirm supplied parameters'.format(module.params['name'])) - module.exit_json(changed=changed) - - -def modify_subnet(module, blade): - """Modify Subnet settings""" - changed = False - subnet = get_subnet(module, blade) - subnet_new = [] - subnet_new.append(module.params['name']) - if module.params['prefix']: - if module.params['prefix'] != subnet.prefix: - try: - blade.subnets.update_subnets(names=subnet_new, - subnet=Subnet(prefix=module.params['prefix'])) - changed = True - except Exception: - module.fail_json(msg='Failed to change subnet {0} prefix to {1}'.format(module.params['name'], - module.params['prefix'])) - if module.params['vlan']: - if module.params['vlan'] != subnet.vlan: - try: - blade.subnets.update_subnets(names=subnet_new, - subnet=Subnet(vlan=module.params['vlan'])) - changed = True - except Exception: - module.fail_json(msg='Failed to change subnet {0} VLAN to {1}'.format(module.params['name'], - module.params['vlan'])) - if module.params['gateway']: - if module.params['gateway'] != subnet.gateway: - try: - blade.subnets.update_subnets(names=subnet_new, - subnet=Subnet(gateway=module.params['gateway'])) - changed = True - except Exception: - module.fail_json(msg='Failed to change subnet {0} gateway to {1}'.format(module.params['name'], - module.params['gateway'])) - if module.params['mtu']: - if module.params['mtu'] != subnet.mtu: - try: - blade.subnets.update_subnets(names=subnet_new, - subnet=Subnet(mtu=module.params['mtu'])) - changed = True - except Exception: - module.fail_json(msg='Failed to change subnet {0} MTU to {1}'.format(module.params['name'], - module.params['mtu'])) - module.exit_json(changed=changed) - - -def delete_subnet(module, blade): - """ Delete Subnet""" - subnet = [] - subnet.append(module.params['name']) - try: - blade.subnets.delete_subnets(names=subnet) - changed = True - except Exception: - changed = False - module.exit_json(changed=changed) - - -def main(): - argument_spec = purefb_argument_spec() - argument_spec.update( - dict( - name=dict(required=True), - state=dict(default='present', choices=['present', 'absent']), - gateway=dict(), - mtu=dict(type='int', default=1500), - prefix=dict(), - vlan=dict(type='int', default=0), - ) - ) - - required_if = [["state", "present", ["gateway", 'prefix']]] - - module = AnsibleModule(argument_spec, - required_if=required_if, - supports_check_mode=False) - - if not HAS_PURITY_FB: - module.fail_json(msg='purity_fb sdk is required for this module') - - if not HAS_NETADDR: - module.fail_json(msg='netaddr module is required') - - state = module.params['state'] - blade = get_blade(module) - api_version = blade.api_version.list_versions().versions - if MINIMUM_API_VERSION not in api_version: - module.fail_json(msg='Upgrade Purity//FB to enable this module') - subnet = get_subnet(module, blade) - if state == 'present': - if not (1280 <= module.params['mtu'] <= 9216): - module.fail_json(msg='MTU {0} is out of range (1280 to 9216)'.format(module.params['mtu'])) - if not (0 <= module.params['vlan'] <= 4094): - module.fail_json(msg='VLAN ID {0} is out of range (0 to 4094)'.format(module.params['vlan'])) - if netaddr.IPAddress(module.params['gateway']) not in netaddr.IPNetwork(module.params['prefix']): - module.fail_json(msg='Gateway and subnet are not compatible.') - subnets = blade.subnets.list_subnets() - nrange = netaddr.IPSet([module.params['prefix']]) - for sub in range(0, len(subnets.items)): - if subnets.items[sub].vlan == module.params['vlan'] and subnets.items[sub].name != module.params['name']: - module.fail_json(msg='VLAN ID {0} is already in use.'.format(module.params['vlan'])) - if nrange & netaddr.IPSet([subnets.items[sub].prefix]) and subnets.items[sub].name != module.params['name']: - module.fail_json(msg='Prefix CIDR overlaps with existing subnet.') - - if state == 'present' and not subnet: - create_subnet(module, blade) - elif state == 'present' and subnet: - modify_subnet(module, blade) - elif state == 'absent' and subnet: - delete_subnet(module, blade) - elif state == 'absent' and not subnet: - module.exit_json(changed=False) - - -if __name__ == '__main__': - main() diff --git a/test/sanity/ignore.txt b/test/sanity/ignore.txt index 78f741bf381..2922237204e 100644 --- a/test/sanity/ignore.txt +++ b/test/sanity/ignore.txt @@ -993,14 +993,6 @@ lib/ansible/modules/source_control/git.py validate-modules:parameter-type-not-in lib/ansible/modules/source_control/subversion.py validate-modules:doc-required-mismatch lib/ansible/modules/source_control/subversion.py validate-modules:parameter-type-not-in-doc lib/ansible/modules/source_control/subversion.py validate-modules:undocumented-parameter -lib/ansible/modules/storage/purestorage/purefb_ds.py validate-modules:doc-required-mismatch -lib/ansible/modules/storage/purestorage/purefb_ds.py validate-modules:parameter-list-no-elements -lib/ansible/modules/storage/purestorage/purefb_dsrole.py validate-modules:doc-required-mismatch -lib/ansible/modules/storage/purestorage/purefb_fs.py validate-modules:doc-default-does-not-match-spec -lib/ansible/modules/storage/purestorage/purefb_info.py validate-modules:parameter-list-no-elements -lib/ansible/modules/storage/purestorage/purefb_info.py validate-modules:return-syntax-error -lib/ansible/modules/storage/purestorage/purefb_s3acc.py validate-modules:doc-required-mismatch -lib/ansible/modules/storage/purestorage/purefb_s3user.py validate-modules:doc-required-mismatch lib/ansible/modules/system/getent.py validate-modules:parameter-type-not-in-doc lib/ansible/modules/system/hostname.py validate-modules:invalid-ansiblemodule-schema lib/ansible/modules/system/hostname.py validate-modules:parameter-type-not-in-doc