Server IP : 85.214.239.14 / Your IP : 3.133.143.199 Web Server : Apache/2.4.62 (Debian) System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Tue Jan 9 19:45:01 MSK 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.18 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, MySQL : OFF | cURL : OFF | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /lib/python3/dist-packages/ansible_collections/dellemc/unity/plugins/modules/ |
Upload File : |
#!/usr/bin/python # Copyright: (c) 2021, Dell Technologies # Apache License version 2.0 (see MODULE-LICENSE or http://www.apache.org/licenses/LICENSE-2.0.txt) """Ansible module for managing User Quota on Unity""" from __future__ import absolute_import, division, print_function __metaclass__ = type DOCUMENTATION = r''' --- module: user_quota short_description: Manage user quota on the Unity storage system description: - Managing User Quota on the Unity storage system includes Create user quota, Get user quota, Modify user quota, Delete user quota, Create user quota for quota tree, Modify user quota for quota tree and Delete user quota for quota tree. version_added: '1.2.0' extends_documentation_fragment: - dellemc.unity.unity author: - Spandita Panigrahi (@panigs7) <ansible.team@dell.com> options: filesystem_name: description: - The name of the filesystem for which the user quota is created. - For creation of a user quota either I(filesystem_name) or I(filesystem_id) is required. type: str filesystem_id: description: - The ID of the filesystem for which the user quota is created. - For creation of a user quota either I(filesystem_id) or I(filesystem_name) is required. type: str nas_server_name: description: - The name of the NAS server in which the filesystem is created. - For creation of a user quota either I(nas_server_name) or I(nas_server_id) is required. type: str nas_server_id: description: - The ID of the NAS server in which the filesystem is created. - For creation of a user quota either I(filesystem_id) or I(filesystem_name) is required. type: str hard_limit: description: - Hard limitation for a user on the total space available. If exceeded, user cannot write data. - Value C(0) implies no limit. - One of the values of I(soft_limit) and I(hard_limit) can be C(0), however, both cannot be C(0) during creation or modification of user quota. type: int soft_limit: description: - Soft limitation for a user on the total space available. If exceeded, notification will be sent to the user for the grace period mentioned, beyond which the user cannot use space. - Value C(0) implies no limit. - Both I(soft_limit) and I(hard_limit) cannot be C(0) during creation or modification of user quota. type: int cap_unit: description: - Unit of I(soft_limit) and I(hard_limit) size. - It defaults to C(GB) if not specified. choices: ['MB', 'GB', 'TB'] type: str user_type: description: - Type of user creating a user quota. - Mandatory while creating or modifying user quota. choices: ['Unix', 'Windows'] type: str win_domain: description: - Fully qualified or short domain name for Windows user type. - Mandatory when I(user_type) is C(Windows). type: str user_name: description: - User name of the user quota when I(user_type) is C(Windows) or C(Unix). - Option I(user_name) must be specified along with I(win_domain) when I(user_type) is C(Windows). type: str uid: description: - User ID of the user quota. type: str user_quota_id: description: - User quota ID generated after creation of a user quota. type: str tree_quota_id: description: - The ID of the quota tree. - Either I(tree_quota_id) or I(path) to quota tree is required to create/modify/delete user quota for a quota tree. type: str path: description: - The path to the quota tree. - Either I(tree_quota_id) or I(path) to quota tree is required to create/modify/delete user quota for a quota tree. - Path must start with a forward slash '/'. type: str state: description: - The I(state) option is used to mention the existence of the user quota. type: str required: true choices: ['absent', 'present'] notes: - The I(check_mode) is not supported. ''' EXAMPLES = r''' - name: Get user quota details by user quota id dellemc.unity.user_quota: unispherehost: "{{unispherehost}}" username: "{{username}}" password: "{{password}}" validate_certs: "{{validate_certs}}" user_quota_id: "userquota_171798700679_0_123" state: "present" - name: Get user quota details by user quota uid/user name dellemc.unity.user_quota: unispherehost: "{{unispherehost}}" username: "{{username}}" password: "{{password}}" validate_certs: "{{validate_certs}}" filesystem_name: "fs_2171" nas_server_id: "nas_21" user_name: "test" state: "present" - name: Create user quota for a filesystem with filesystem id dellemc.unity.user_quota: unispherehost: "{{unispherehost}}" username: "{{username}}" password: "{{password}}" validate_certs: "{{validate_certs}}" filesystem_id: "fs_2171" hard_limit: 6 cap_unit: "TB" soft_limit: 5 uid: "111" state: "present" - name: Create user quota for a filesystem with filesystem name dellemc.unity.user_quota: unispherehost: "{{unispherehost}}" username: "{{username}}" password: "{{password}}" validate_certs: "{{validate_certs}}" filesystem_name: "Test_filesystem" nas_server_name: "lglad068" hard_limit: 6 cap_unit: "TB" soft_limit: 5 uid: "111" state: "present" - name: Modify user quota limit usage by user quota id dellemc.unity.user_quota: unispherehost: "{{unispherehost}}" username: "{{username}}" password: "{{password}}" validate_certs: "{{validate_certs}}" user_quota_id: "userquota_171798700679_0_123" hard_limit: 10 cap_unit: "TB" soft_limit: 8 state: "present" - name: Modify user quota by filesystem id and user quota uid/user_name dellemc.unity.user_quota: unispherehost: "{{unispherehost}}" username: "{{username}}" password: "{{password}}" validate_certs: "{{validate_certs}}" filesystem_id: "fs_2171" user_type: "Windows" win_domain: "prod" user_name: "sample" hard_limit: 12 cap_unit: "TB" soft_limit: 10 state: "present" - name: Delete user quota dellemc.unity.user_quota: unispherehost: "{{unispherehost}}" username: "{{username}}" password: "{{password}}" validate_certs: "{{validate_certs}}" filesystem_id: "fs_2171" win_domain: "prod" user_name: "sample" state: "absent" - name: Create user quota of a quota tree dellemc.unity.user_quota: unispherehost: "{{unispherehost}}" username: "{{username}}" password: "{{password}}" validate_certs: "{{validate_certs}}" tree_quota_id: "treequota_171798700679_4" user_type: "Windows" win_domain: "prod" user_name: "sample" soft_limit: 9 cap_unit: "TB" state: "present" - name: Create user quota of a quota tree by quota tree path dellemc.unity.user_quota: unispherehost: "{{unispherehost}}" username: "{{username}}" password: "{{password}}" validate_certs: "{{validate_certs}}" filesystem_id: "fs_2171" path: "/sample" user_type: "Unix" user_name: "test" hard_limit: 2 cap_unit: "TB" state: "present" - name: Modify user quota of a quota tree dellemc.unity.user_quota: unispherehost: "{{unispherehost}}" username: "{{username}}" password: "{{password}}" validate_certs: "{{validate_certs}}" tree_quota_id: "treequota_171798700679_4" user_type: "Windows" win_domain: "prod" user_name: "sample" soft_limit: 10 cap_unit: "TB" state: "present" - name: Modify user quota of a quota tree by quota tree path dellemc.unity.user_quota: unispherehost: "{{unispherehost}}" username: "{{username}}" password: "{{password}}" validate_certs: "{{validate_certs}}" filesystem_id: "fs_2171" path: "/sample" user_type: "Windows" win_domain: "prod" user_name: "sample" hard_limit: 12 cap_unit: "TB" state: "present" - name: Delete user quota of a quota tree by quota tree path dellemc.unity.user_quota: unispherehost: "{{unispherehost}}" username: "{{username}}" password: "{{password}}" validate_certs: "{{validate_certs}}" filesystem_id: "fs_2171" path: "/sample" win_domain: "prod" user_name: "sample" state: "absent" - name: Delete user quota of a quota tree by quota tree id dellemc.unity.user_quota: unispherehost: "{{unispherehost}}" username: "{{username}}" password: "{{password}}" validate_certs: "{{validate_certs}}" tree_quota_id: "treequota_171798700679_4" win_domain: "prod" user_name: "sample" state: "absent" ''' RETURN = r''' changed: description: Whether or not the resource has changed. returned: always type: bool sample: True get_user_quota_details: description: Details of the user quota. returned: When user quota exists type: dict contains: filesystem: description: Filesystem details for which the user quota is created. type: dict contains: UnityFileSystem: description: Filesystem details for which the user quota is created. type: dict contains: id: description: ID of the filesystem for which the user quota is created. type: str name: description: Name of filesystem. type: str nas_server: description: Nasserver details where filesystem is created. type: dict contains: name: description: Name of nasserver. type: str id: description: ID of nasserver. type: str tree_quota: description: Quota tree details for which the user quota is created. type: dict contains: UnityTreeQuota: description: Quota tree details for which the user quota is created. type: dict contains: id: description: ID of the quota tree. type: str path: description: Path to quota tree. type: str gp_left: description: The grace period left after the soft limit for the user quota is exceeded. type: int hard_limit: description: Hard limitation for a user on the total space available. If exceeded, user cannot write data. type: int hard_ratio: description: The hard ratio is the ratio between the hard limit size of the user quota and the amount of storage actually consumed. type: str soft_limit: description: Soft limitation for a user on the total space available. If exceeded, notification will be sent to user for the grace period mentioned, beyond which user cannot use space. type: int soft_ratio: description: The soft ratio is the ratio between the soft limit size of the user quota and the amount of storage actually consumed. type: str id: description: User quota ID. type: str size_used: description: Size of used space in the filesystem by the user files. type: int state: description: State of the user quota. type: int uid: description: User ID of the user. type: int unix_name: description: Unix user name for this user quota's uid. type: str windows_names: description: Windows user name that maps to this quota's uid. type: str windows_sids: description: Windows SIDs that maps to this quota's uid type: str sample: { "existed": true, "filesystem": { "UnityFileSystem": { "hash": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", "id": "fs_120", "name": "nfs-multiprotocol", "nas_server": { "id": "nas_1", "name": "lglad072" } } }, "gp_left": null, "hard_limit": "10.0 GB", "hard_ratio": null, "hash": 8752448438089, "id": "userquota_171798694698_0_60000", "size_used": 0, "soft_limit": "10.0 GB", "soft_ratio": null, "state": 0, "tree_quota": null, "uid": 60000, "unix_name": null, "windows_names": null, "windows_sids": null } ''' from ansible.module_utils.basic import AnsibleModule from ansible_collections.dellemc.unity.plugins.module_utils.storage.dell \ import utils LOG = utils.get_logger('user_quota') application_type = "Ansible/1.6.0" class UserQuota(object): """Class with User Quota operations""" def __init__(self): """Define all parameters required by this module""" self.module_params = utils.get_unity_management_host_parameters() self.module_params.update(get_user_quota_parameters()) mutually_exclusive = [['user_name', 'uid'], ['uid', 'win_domain'], ['filesystem_name', 'filesystem_id'], ['nas_server_name', 'nas_server_id'], ['user_name', 'user_quota_id'], ['uid', 'user_quota_id']] required_if = [('user_type', 'Windows', ['win_domain', 'user_name'], False), ('user_type', 'Unix', ['user_name'], False)] # initialize the Ansible module self.module = AnsibleModule( argument_spec=self.module_params, supports_check_mode=False, mutually_exclusive=mutually_exclusive, required_if=required_if) utils.ensure_required_libs(self.module) self.unity_conn = utils.get_unity_unisphere_connection( self.module.params, application_type) def check_user_is_present(self, fs_id, uid, unix, win_name, user_quota_id): """ Check if user quota is present in filesystem. :param fs_id: ID of filesystem where user quota is searched. :param uid: UID of the user quota :param unix: Unix user name of user quota :param win_name: Windows user name of user quota :param user_quota_id: ID of the user quota :return: ID of user quota if it exists else None. """ if not self.check_user_type_provided(win_name, uid, unix): return None user_name_or_uid_or_id = unix if unix else win_name if win_name else uid if \ uid else user_quota_id # All user quotas in the given filesystem all_user_quota = self.unity_conn.get_user_quota(filesystem=fs_id, id=user_quota_id, unix_name=unix, windows_names=win_name, uid=uid) for user_quota in range(len(all_user_quota)): if all_user_quota[user_quota].tree_quota is None: msg = "User quota %s with id %s " \ "is present in filesystem %s" \ % (user_name_or_uid_or_id, all_user_quota[user_quota].id, fs_id) LOG.info(msg) return all_user_quota[user_quota].id return None def check_quota_tree_is_present(self, fs_id, path, tree_quota_id): """ Check if quota tree is present in filesystem. :param fs_id: ID of filesystem where quota tree is searched. :param path: Path to quota tree :param tree_quota_id: ID of the quota tree :return: ID of quota tree if it exists. """ path_or_id = path if path else tree_quota_id tree_quota_obj = self.unity_conn.get_tree_quota(filesystem=fs_id, path=path, id=tree_quota_id) if len(tree_quota_obj) > 0: msg = "Tree quota id %s present in filesystem %s" % (tree_quota_obj[0].id, fs_id) LOG.info(msg) return tree_quota_obj[0].id else: errormsg = "The quota tree '%s' does not exist" % path_or_id LOG.error(errormsg) self.module.fail_json(msg=errormsg) def check_user_quota_in_quota_tree(self, tree_quota_id, uid, unix, win_name, user_quota_id): """ Check if user quota is present in quota tree. :param tree_quota_id: ID of quota tree where user quota is searched. :param uid: UID of user quota :param unix: Unix name of user quota :param win_name: Windows name of user quota :param user_quota_id: ID of the user quota :return: ID of user quota if it exists in quota tree else None. """ if not self.check_user_type_provided(win_name, uid, unix): return None user_quota_name = uid if uid else unix if unix else win_name \ if win_name else user_quota_id user_quota_obj = self.unity_conn.get_user_quota(tree_quota=tree_quota_id, uid=uid, windows_names=win_name, unix_name=unix, id=user_quota_id) if len(user_quota_obj) > 0: msg = "User quota %s is present in quota tree %s " % (user_quota_name, tree_quota_id) LOG.info(msg) return user_quota_obj[0].id else: return None def create_user_quota(self, fs_id, soft_limit, hard_limit, unit, uid, unix, win_name, tree_quota_id): """ Create user quota of a filesystem. :param fs_id: ID of filesystem where user quota is to be created. :param soft_limit: Soft limit :param hard_limit: Hard limit :param unit: Unit of soft limit and hard limit :param uid: UID of the user quota :param unix: Unix user name of user quota :param win_name: Windows user name of user quota :param tree_quota_id: ID of tree quota :return: Object containing new user quota details. """ unix_or_uid_or_win = uid if uid else unix if unix else win_name fs_id_or_tree_quota_id = fs_id if fs_id else tree_quota_id if soft_limit is None and hard_limit is None: errormsg = "Both soft limit and hard limit cannot be empty. " \ "Please provide atleast one to create user quota." LOG.error(errormsg) self.module.fail_json(msg=errormsg) soft_limit_in_bytes = utils.get_size_bytes(soft_limit, unit) hard_limit_in_bytes = utils.get_size_bytes(hard_limit, unit) try: if self.check_user_type_provided(win_name, uid, unix): obj_user_quota = self.unity_conn.create_user_quota(filesystem_id=fs_id, hard_limit=hard_limit_in_bytes, soft_limit=soft_limit_in_bytes, uid=uid, unix_name=unix, win_name=win_name, tree_quota_id=tree_quota_id) LOG.info("Successfully created user quota") return obj_user_quota except Exception as e: errormsg = "Create quota for user {0} on {1} , failed with error {2} "\ .format(unix_or_uid_or_win, fs_id_or_tree_quota_id, str(e)) LOG.error(errormsg) self.module.fail_json(msg=errormsg) def get_filesystem_user_quota_display_attributes(self, user_quota_id): """Get display user quota attributes :param user_quota_id: User quota ID :return: User quota dict to display """ try: user_quota_obj = self.unity_conn.get_user_quota(user_quota_id) user_quota_details = user_quota_obj._get_properties() if user_quota_obj and user_quota_obj.existed: user_quota_details['soft_limit'] = utils. \ convert_size_with_unit(int(user_quota_details['soft_limit'])) user_quota_details['hard_limit'] = utils. \ convert_size_with_unit(int(user_quota_details['hard_limit'])) user_quota_details['filesystem']['UnityFileSystem']['name'] = \ user_quota_obj.filesystem.name user_quota_details['filesystem']['UnityFileSystem'].update( {'nas_server': {'name': user_quota_obj.filesystem.nas_server.name, 'id': user_quota_obj.filesystem.nas_server.id}}) if user_quota_obj.tree_quota: user_quota_details['tree_quota']['UnityTreeQuota']['path'] = \ user_quota_obj.tree_quota.path return user_quota_details else: errormsg = "User quota does not exist." LOG.error(errormsg) self.module.fail_json(msg=errormsg) except Exception as e: errormsg = "Failed to display the details of user quota {0} with " \ "error {1}".format(user_quota_obj.id, str(e)) LOG.error(errormsg) self.module.fail_json(msg=errormsg) def get_filesystem(self, nas_server=None, name=None, id=None): """ Get filesystem details. :param nas_server: Nas server object. :param name: Name of filesystem. :param id: ID of filesystem. :return: Object containing filesystem details if it exists. """ id_or_name = id if id else name try: obj_fs = None if name: if not nas_server: err_msg = "NAS Server is required to get the FileSystem." LOG.error(err_msg) self.module.fail_json(msg=err_msg) obj_fs = self.unity_conn.get_filesystem(name=name, nas_server=nas_server) if obj_fs and obj_fs.existed: LOG.info("Successfully got the filesystem object %s.", obj_fs) return obj_fs if id: if nas_server: obj_fs = self.unity_conn \ .get_filesystem(id=id, nas_server=nas_server) else: obj_fs = self.unity_conn.get_filesystem(id=id) if obj_fs and obj_fs.existed: LOG.info("Successfully got the filesystem object %s.", obj_fs) return obj_fs except Exception as e: error_msg = "Failed to get filesystem %s with error %s." \ % (id_or_name, str(e)) LOG.error(error_msg) self.module.fail_json(msg=error_msg) def get_nas_server_obj(self, name=None, id=None): """ Get nas server details. :param name: Nas server name. :param id: Nas server ID. :return: Object containing nas server details if it exists. """ nas_server = id if id else name error_msg = ("Failed to get NAS server %s." % nas_server) try: obj_nas = self.unity_conn.get_nas_server(_id=id, name=name) if name and obj_nas.existed: LOG.info("Successfully got the NAS server object %s.", obj_nas) return obj_nas elif id and obj_nas.existed: LOG.info("Successfully got the NAS server object %s.", obj_nas) return obj_nas else: LOG.error(error_msg) self.module.fail_json(msg=error_msg) except Exception as e: error_msg = "Failed to get NAS server %s with error %s." \ % (nas_server, str(e)) LOG.error(error_msg) self.module.fail_json(msg=error_msg) def modify_user_quota(self, user_quota_id, soft_limit, hard_limit, unit): """ Modify user quota of filesystem by its uid/username/user quota id. :param user_quota_id: ID of the user quota :param soft_limit: Soft limit :param hard_limit: Hard limit :param unit: Unit of soft limit and hard limit :return: Boolean value whether modify user quota operation is successful. """ if soft_limit is None and hard_limit is None: return False user_quota_obj = self.unity_conn.get_user_quota(user_quota_id)._get_properties() if soft_limit is None: soft_limit_in_bytes = user_quota_obj['soft_limit'] else: soft_limit_in_bytes = utils.get_size_bytes(soft_limit, unit) if hard_limit is None: hard_limit_in_bytes = user_quota_obj['hard_limit'] else: hard_limit_in_bytes = utils.get_size_bytes(hard_limit, unit) if user_quota_obj: if user_quota_obj['soft_limit'] == soft_limit_in_bytes and \ user_quota_obj['hard_limit'] == hard_limit_in_bytes: return False else: error_msg = "The user quota does not exist." LOG.error(error_msg) self.module.fail_json(msg=error_msg) try: obj_user_quota = self.unity_conn.modify_user_quota(user_quota_id=user_quota_id, hard_limit=hard_limit_in_bytes, soft_limit=soft_limit_in_bytes) LOG.info("Successfully modified user quota") if obj_user_quota: return True except Exception as e: errormsg = "Modify user quota {0} failed" \ " with error {1}".format(user_quota_id, str(e)) LOG.error(errormsg) self.module.fail_json(msg=errormsg) def check_user_type_provided(self, win_name, uid, unix_name): """Checks if user type or uid is provided :param win_name: Windows name of user quota :param uid: UID of user quota :param unix_name: Unix name of user quota""" if win_name is None and uid is None and unix_name is None: return False else: return True def perform_module_operation(self): """ Perform different actions on user quota module based on parameters passed in the playbook """ filesystem_id = self.module.params['filesystem_id'] filesystem_name = self.module.params['filesystem_name'] nas_server_name = self.module.params['nas_server_name'] nas_server_id = self.module.params['nas_server_id'] cap_unit = self.module.params['cap_unit'] state = self.module.params['state'] user_quota_id = self.module.params['user_quota_id'] hard_limit = self.module.params['hard_limit'] soft_limit = self.module.params['soft_limit'] user_type = self.module.params['user_type'] uid = self.module.params['uid'] user_name = self.module.params['user_name'] win_domain = self.module.params['win_domain'] tree_quota_id = self.module.params['tree_quota_id'] path = self.module.params['path'] create_user_quota_obj = None win_name = None unix_name = None nas_server_resource = None fs_id = None user_quota_details = '' filesystem_obj = None ''' result is a dictionary to contain end state and user quota details ''' result = dict( changed=False, create_user_quota=False, modify_user_quota=False, get_user_quota_details={}, delete_user_quota=False ) if (soft_limit or hard_limit) and cap_unit is None: cap_unit = 'GB' if soft_limit == 0 and hard_limit == 0: error_message = 'Both soft limit and hard limit cannot be unlimited' LOG.error(error_message) self.module.fail_json(msg=error_message) if soft_limit and utils.is_size_negative(soft_limit): error_message = "Invalid soft_limit provided, " \ "must be greater than 0" LOG.error(error_message) self.module.fail_json(msg=error_message) if hard_limit and utils.is_size_negative(hard_limit): error_message = "Invalid hard_limit provided, " \ "must be greater than 0" LOG.error(error_message) self.module.fail_json(msg=error_message) if (user_type or uid) and filesystem_id is None and \ filesystem_name is None and tree_quota_id is None: error_message = 'Please provide either ' \ 'filesystem_name or filesystem_id' LOG.error(error_message) self.module.fail_json(msg=error_message) if (nas_server_name or nas_server_id) \ and (filesystem_id is None and filesystem_name is None): error_message = 'Please provide either ' \ 'filesystem_name or filesystem_id' LOG.error(error_message) self.module.fail_json(msg=error_message) ''' Validate path to quota tree ''' if path is not None: if utils.is_input_empty(path): self.module.fail_json(msg=" Please provide a valid path.") elif not path.startswith('/'): self.module.fail_json(msg="The path is relative to the root of the file system " "and must start with a forward slash.") if filesystem_id is None and filesystem_name is None: self.module.fail_json(msg="Please provide either filesystem_name or fileystem_id.") if user_type and filesystem_id is None and filesystem_name is None and tree_quota_id is None: error_message = 'Please provide either ' \ 'filesystem_name or filesystem_id to create user quota for a' \ 'filesystem. Or provide tree_quota_id to create user quota for a quota tree.' LOG.error(error_message) self.module.fail_json(msg=error_message) ''' Get NAS server Object ''' if nas_server_name is not None: if utils.is_input_empty(nas_server_name): self.module.fail_json(msg="Invalid nas_server_name given," " Please provide a valid name.") nas_server_resource = self \ .get_nas_server_obj(name=nas_server_name) elif nas_server_id is not None: if utils.is_input_empty(nas_server_id): self.module.fail_json(msg="Invalid nas_server_id given," " Please provide a valid ID.") nas_server_resource = self.get_nas_server_obj(id=nas_server_id) ''' Get filesystem Object ''' if filesystem_name is not None: if utils.is_input_empty(filesystem_name): self.module.fail_json(msg="Invalid filesystem_name given," " Please provide a valid name.") filesystem_obj = self \ .get_filesystem(nas_server=nas_server_resource, name=filesystem_name) fs_id = filesystem_obj.id elif filesystem_id is not None: if utils.is_input_empty(filesystem_id): self.module.fail_json(msg="Invalid filesystem_id given," " Please provide a valid ID.") filesystem_obj = self \ .get_filesystem(id=filesystem_id) if filesystem_obj: filesystem_obj = filesystem_obj[0] fs_id = filesystem_obj.id else: self.module.fail_json(msg="Filesystem does not exist.") if (user_name or win_domain) and (soft_limit or hard_limit) \ and user_type is None: self.module.fail_json(msg="Invalid user_type given," " Please provide a valid user_type.") # Check the sharing protocol supported by the filesystem # while creating a user quota if filesystem_obj and (soft_limit is not None or hard_limit is not None): supported_protocol = filesystem_obj.supported_protocols if supported_protocol == utils.FSSupportedProtocolEnum["CIFS"] \ and (user_type == "Unix" or uid): self.module.fail_json(msg="This filesystem supports only SMB protocol " "and applicable only for windows users. " "Please provide valid windows details.") elif supported_protocol == utils.FSSupportedProtocolEnum["NFS"] \ and user_type == "Windows": self.module.fail_json(msg="This filesystem supports only NFS protocol " "and applicable only for unix users. " "Please provide valid uid or unix details.") ''' Validate user type or uid ''' if uid and (utils.is_input_empty(uid) or not uid.isnumeric()): self.module.fail_json(msg=" UID is empty. Please provide valid UID.") if user_type: if user_type == "Unix": if user_name is None or utils.is_input_empty(user_name): self.module.fail_json(msg=" 'user_name' is empty. Please provide valid user_name.") if user_type == "Windows": if win_domain is None or utils.is_input_empty(win_domain): self.module.fail_json(msg=" 'win_domain' is empty. Please provide valid win_domain.") elif user_name is None or utils.is_input_empty(user_name): self.module.fail_json(msg=" 'user_name' is empty. Please provide valid user_name.") if user_type != "Unix" and win_domain: win_domain = win_domain.replace(".com", "") win_name = win_domain + '\\' + user_name if win_name is None and user_name: unix_name = user_name ''' Check if quota tree is already present in the filesystem ''' if tree_quota_id or path: quota_tree_id_present = self.check_quota_tree_is_present(fs_id, path, tree_quota_id) tree_quota_id = quota_tree_id_present ''' Check if the user quota is already present in the filesystem/ quota tree ''' if tree_quota_id: user_id_present = self.check_user_quota_in_quota_tree(tree_quota_id, uid, unix_name, win_name, user_quota_id) fs_id = None if tree_quota_id is not None else fs_id else: user_id_present = self.check_user_is_present(fs_id, uid, unix_name, win_name, user_quota_id) if user_id_present: user_quota_id = user_id_present if state == "present": if user_quota_id: # Modify user quota. If no change modify_user_quota is false. result['modify_user_quota'] = self.modify_user_quota(user_quota_id, soft_limit, hard_limit, cap_unit) else: LOG.info("Creating user quota") create_user_quota_obj = self.create_user_quota(fs_id, soft_limit, hard_limit, cap_unit, uid, unix_name, win_name, tree_quota_id) if create_user_quota_obj: user_quota_id = create_user_quota_obj.id result['create_user_quota'] = True else: user_quota_id = None ''' Deleting user quota. When both soft limit and hard limit are set to 0, it implies the user quota has unlimited quota. Thereby, Unity removes the user quota id. ''' if state == "absent" and user_quota_id: soft_limit = 0 hard_limit = 0 err_msg = "Deleting user quota %s" % user_quota_id LOG.info(err_msg) result['delete_user_quota'] = self.modify_user_quota(user_quota_id, soft_limit, hard_limit, cap_unit) ''' Get user details ''' if state == "present" and user_quota_id: user_quota_details = self.get_filesystem_user_quota_display_attributes(user_quota_id) result['get_user_quota_details'] = user_quota_details if result['create_user_quota'] or result['modify_user_quota'] or result['delete_user_quota']: result['changed'] = True self.module.exit_json(**result) def get_user_quota_parameters(): """This method provide parameters required for the ansible filesystem user quota module on Unity""" return dict( filesystem_id=dict(required=False, type='str'), filesystem_name=dict(required=False, type='str'), state=dict(required=True, type='str', choices=['present', 'absent']), user_type=dict(required=False, type='str', choices=['Windows', 'Unix']), user_name=dict(required=False, type='str'), uid=dict(required=False, type='str'), win_domain=dict(required=False, type='str'), hard_limit=dict(required=False, type='int'), soft_limit=dict(required=False, type='int'), cap_unit=dict(required=False, type='str', choices=['MB', 'GB', 'TB']), user_quota_id=dict(required=False, type='str'), nas_server_name=dict(required=False, type='str'), nas_server_id=dict(required=False, type='str'), tree_quota_id=dict(required=False, type='str'), path=dict(required=False, type='str', no_log=True) ) def main(): """ Create Unity user quota object and perform action on it based on user input from playbook""" obj = UserQuota() obj.perform_module_operation() if __name__ == '__main__': main()