summaryrefslogtreecommitdiffstats
path: root/ansible_collections/dellemc/unity/plugins/modules/nfsserver.py
diff options
context:
space:
mode:
Diffstat (limited to 'ansible_collections/dellemc/unity/plugins/modules/nfsserver.py')
-rw-r--r--ansible_collections/dellemc/unity/plugins/modules/nfsserver.py494
1 files changed, 494 insertions, 0 deletions
diff --git a/ansible_collections/dellemc/unity/plugins/modules/nfsserver.py b/ansible_collections/dellemc/unity/plugins/modules/nfsserver.py
new file mode 100644
index 00000000..cca15433
--- /dev/null
+++ b/ansible_collections/dellemc/unity/plugins/modules/nfsserver.py
@@ -0,0 +1,494 @@
+#!/usr/bin/python
+# Copyright: (c) 2022, Dell Technologies
+
+# Apache License version 2.0 (see MODULE-LICENSE or http://www.apache.org/licenses/LICENSE-2.0.txt)
+
+"""Ansible module for managing NFS server on Unity"""
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = r'''
+module: nfsserver
+version_added: '1.4.0'
+short_description: Manage NFS server on Unity storage system
+description:
+- Managing the NFS server on the Unity storage system includes creating NFS server, getting NFS server details
+ and deleting NFS server attributes.
+
+extends_documentation_fragment:
+ - dellemc.unity.unity
+
+author:
+- Meenakshi Dembi (@dembim) <ansible.team@dell.com>
+
+options:
+ nas_server_name:
+ description:
+ - Name of the NAS server on which NFS server will be hosted.
+ type: str
+ nas_server_id:
+ description:
+ - ID of the NAS server on which NFS server will be hosted.
+ type: str
+ nfs_server_id:
+ description:
+ - ID of the NFS server.
+ type: str
+ host_name:
+ description:
+ - Host name of the NFS server.
+ type: str
+ nfs_v4_enabled:
+ description:
+ - Indicates whether the NFSv4 is enabled on the NAS server.
+ type: bool
+ is_secure_enabled:
+ description:
+ - Indicates whether the secure NFS is enabled.
+ type: bool
+ kerberos_domain_controller_type:
+ description:
+ - Type of Kerberos Domain Controller used for secure NFS service.
+ choices: [CUSTOM, UNIX, WINDOWS]
+ type: str
+ kerberos_domain_controller_username:
+ description:
+ - Kerberos Domain Controller administrator username.
+ type: str
+ kerberos_domain_controller_password:
+ description:
+ - Kerberos Domain Controller administrator password.
+ type: str
+ is_extended_credentials_enabled:
+ description:
+ - Indicates whether support for more than 16 unix groups in a Unix credential.
+ type: bool
+ remove_spn_from_kerberos:
+ description:
+ - Indicates whether to remove the SPN from Kerberos Domain Controller.
+ default: true
+ type: bool
+ state:
+ description:
+ - Define whether the NFS server should exist or not.
+ choices: [absent, present]
+ required: true
+ type: str
+notes:
+- The I(check_mode) is supported.
+- Modify operation for NFS Server is not supported.
+- When I(kerberos_domain_controller_type) is C(UNIX), I(kdc_type) in I(nfs_server_details) output is displayed as C(null).
+'''
+
+EXAMPLES = r'''
+
+ - name: Create NFS server with kdctype as Windows
+ dellemc.unity.nfsserver:
+ unispherehost: "{{unispherehost}}"
+ username: "{{username}}"
+ password: "{{password}}"
+ validate_certs: "{{validate_certs}}"
+ nas_server_name: "dummy_nas"
+ host_name: "dummy_nas23"
+ is_secure_enabled: True
+ kerberos_domain_controller_type: "WINDOWS"
+ kerberos_domain_controller_username: "administrator"
+ kerberos_domain_controller_password: "Password123!"
+ is_extended_credentials_enabled: True
+ nfs_v4_enabled: True
+ state: "present"
+
+ - name: Create NFS server with kdctype as Unix
+ dellemc.unity.nfsserver:
+ unispherehost: "{{unispherehost}}"
+ username: "{{username}}"
+ password: "{{password}}"
+ validate_certs: "{{validate_certs}}"
+ nas_server_name: "dummy_nas"
+ host_name: "dummy_nas23"
+ is_secure_enabled: True
+ kerberos_domain_controller_type: "UNIX"
+ is_extended_credentials_enabled: True
+ nfs_v4_enabled: True
+ state: "present"
+
+ - name: Get NFS server details
+ dellemc.unity.nfsserver:
+ unispherehost: "{{unispherehost}}"
+ username: "{{username}}"
+ password: "{{password}}"
+ validate_certs: "{{validate_certs}}"
+ nas_server_name: "dummy_nas"
+ state: "present"
+
+ - name: Delete NFS server
+ dellemc.unity.nfsserver:
+ unispherehost: "{{unispherehost}}"
+ username: "{{username}}"
+ password: "{{password}}"
+ validate_certs: "{{validate_certs}}"
+ nas_server_name: "dummy_nas"
+ kerberos_domain_controller_username: "administrator"
+ kerberos_domain_controller_password: "Password123!"
+ unjoin_server_account: False
+ state: "absent"
+'''
+
+RETURN = r'''
+changed:
+ description: Whether or not the resource has changed.
+ returned: always
+ type: bool
+ sample: true
+nfs_server_details:
+ description: Details of the NFS server.
+ returned: When NFS server exists
+ type: dict
+ contains:
+ credentials_cache_ttl:
+ description: Credential cache refresh timeout. Resolution is in minutes. Default value is 15 minutes.
+ type: str
+ existed:
+ description: Indicates if NFS Server exists.
+ type: bool
+ host_name:
+ description: Host name of the NFS server.
+ type: str
+ id:
+ description: Unique identifier of the NFS Server instance.
+ type: str
+ is_extended_credentials_enabled:
+ description: Indicates whether the NFS server supports more than 16 Unix groups in a Unix credential.
+ type: bool
+ is_secure_enabled:
+ description: Indicates whether secure NFS is enabled on the NFS server.
+ type: bool
+ kdc_type:
+ description: Type of Kerberos Domain Controller used for secure NFS service.
+ type: str
+ nfs_v4_enabled:
+ description: Indicates whether NFSv4 is enabled on the NAS server.
+ type: bool
+ servicee_principal_name:
+ description: The Service Principal Name (SPN) for the NFS Server.
+ type: str
+ sample: {
+ "credentials_cache_ttl": "0:15:00",
+ "existed": true,
+ "file_interfaces": {
+ "UnityFileInterfaceList": [
+ {
+ "UnityFileInterface": {
+ "hash": 8778980109421,
+ "id": "if_37"
+ }
+ }
+ ]
+ },
+ "hash": 8778980109388,
+ "host_name": "dummy_nas23.pie.lab.emc.com",
+ "id": "nfs_51",
+ "is_extended_credentials_enabled": true,
+ "is_secure_enabled": true,
+ "kdc_type": "KdcTypeEnum.WINDOWS",
+ "nas_server": {
+ "UnityNasServer": {
+ "hash": 8778980109412
+ }
+ },
+ "nfs_v4_enabled": true,
+ "servicee_principal_name": null
+ }
+'''
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible_collections.dellemc.unity.plugins.module_utils.storage.dell \
+ import utils
+
+LOG = utils.get_logger('nfsserver')
+
+application_type = "Ansible/1.5.0"
+
+
+class NFSServer(object):
+ """Class with NFS server 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_nfs_server_parameters())
+
+ mutually_exclusive = [['nas_server_name', 'nas_server_id']]
+ required_one_of = [['nfs_server_id', 'nas_server_name', 'nas_server_id']]
+
+ # initialize the Ansible module
+ self.module = AnsibleModule(
+ argument_spec=self.module_params,
+ supports_check_mode=True,
+ mutually_exclusive=mutually_exclusive,
+ required_one_of=required_one_of
+ )
+ utils.ensure_required_libs(self.module)
+
+ self.unity_conn = utils.get_unity_unisphere_connection(
+ self.module.params, application_type)
+ LOG.info('Check Mode Flag %s', self.module.check_mode)
+
+ def get_nfs_server_details(self, nfs_server_id=None, nas_server_id=None):
+ """Get NFS server details.
+ :param: nfs_server_id: The ID of the NFS server
+ :param: nas_server_id: The name of the NAS server
+ :return: Dict containing NFS server details if exists
+ """
+ LOG.info("Getting NFS server details")
+ try:
+ if nfs_server_id:
+ nfs_server_details = self.unity_conn.get_nfs_server(_id=nfs_server_id)
+ return nfs_server_details._get_properties()
+ elif nas_server_id:
+ nfs_server_details = self.unity_conn.get_nfs_server(nas_server=nas_server_id)
+ if len(nfs_server_details) > 0:
+ return process_dict(nfs_server_details._get_properties())
+ return None
+ except utils.HttpError as e:
+ if e.http_status == 401:
+ msg = 'Incorrect username or password provided.'
+ LOG.error(msg)
+ self.module.fail_json(msg=msg)
+ else:
+ err_msg = "Failed to get details of NFS Server" \
+ " with error {0}".format(str(e))
+ LOG.error(err_msg)
+ self.module.fail_json(msg=err_msg)
+
+ except utils.UnityResourceNotFoundError as e:
+ err_msg = "Failed to get details of NFS Server" \
+ " with error {0}".format(str(e))
+ LOG.error(err_msg)
+ return None
+
+ def get_nfs_server_instance(self, nfs_server_id):
+ """Get NFS server instance.
+ :param: nfs_server_id: The ID of the NFS server
+ :return: Return NFS server instance if exists
+ """
+
+ try:
+ nfs_server_obj = self.unity_conn.get_nfs_server(_id=nfs_server_id)
+ return nfs_server_obj
+ except Exception as e:
+ error_msg = "Failed to get the NFS server %s instance" \
+ " with error %s" % (nfs_server_id, str(e))
+ LOG.error(error_msg)
+ self.module.fail_json(msg=error_msg)
+
+ def delete_nfs_server(self, nfs_server_id, skip_unjoin=None, domain_username=None, domain_password=None):
+ """Delete NFS server.
+ :param: nfs_server_id: The ID of the NFS server
+ :param: skip_unjoin: Flag indicating whether to unjoin SMB server account from AD before deletion
+ :param: domain_username: The domain username
+ :param: domain_password: The domain password
+ :return: Return True if NFS server is deleted
+ """
+
+ LOG.info("Deleting NFS server")
+ try:
+ if not self.module.check_mode:
+ nfs_obj = self.get_nfs_server_instance(nfs_server_id=nfs_server_id)
+ nfs_obj.delete(skip_kdc_unjoin=skip_unjoin, username=domain_username, password=domain_password)
+ return True
+ except Exception as e:
+ msg = "Failed to delete NFS server: %s with error: %s" % (nfs_server_id, str(e))
+ LOG.error(msg)
+ self.module.fail_json(msg=msg)
+
+ def get_nas_server_id(self, nas_server_name):
+ """Get NAS server ID.
+ :param: nas_server_name: The name of NAS server
+ :return: Return NAS server ID if exists
+ """
+
+ LOG.info("Getting NAS server ID")
+ try:
+ obj_nas = self.unity_conn.get_nas_server(name=nas_server_name)
+ return obj_nas.get_id()
+ except Exception as e:
+ msg = "Failed to get details of NAS server: %s with error: %s" % (nas_server_name, str(e))
+ LOG.error(msg)
+ self.module.fail_json(msg=msg)
+
+ def is_modification_required(self, is_extended_credentials_enabled, nfs_server_details):
+ """Check if modification is required in existing NFS server
+ :param: is_extended_credentials_enabled: Indicates whether the NFS server supports more than 16 Unix groups in a Unix credential.
+ :param: nfs_server_details: NFS server details
+ :return: True if modification is required
+ """
+
+ LOG.info("Checking if any modification is required")
+ # Check for Extend Credential
+ if is_extended_credentials_enabled is not None and \
+ is_extended_credentials_enabled != nfs_server_details['is_extended_credentials_enabled']:
+ return True
+
+ def create_nfs_server(self, nas_server_id, host_name=None, nfs_v4_enabled=None, is_secure_enabled=None,
+ kerberos_domain_controller_type=None, kerberos_domain_controller_username=None,
+ kerberos_domain_controller_password=None, is_extended_credentials_enabled=None):
+ """Create NFS server.
+ :param: nas_server_id: The ID of NAS server.
+ :param: host_name: Name of NFS Server.
+ :param: nfs_v4_enabled: Indicates whether the NFSv4 is enabled on the NAS server.
+ :param: is_secure_enabled: Indicates whether the secure NFS is enabled.
+ :param: kerberos_domain_controller_type: Type of Kerberos Domain Controller used for secure NFS service.
+ :param: kerberos_domain_controller_username: Kerberos Domain Controller administrator username.
+ :param: kerberos_domain_controller_password: Kerberos Domain Controller administrator password.
+ :param: is_extended_credentials_enabled: Indicates whether support for more than 16 unix groups in a Unix credential.
+ """
+
+ LOG.info("Creating NFS server")
+ try:
+ if not self.module.check_mode:
+ kdc_enum_type = get_enum_kdctype(kerberos_domain_controller_type)
+ if kerberos_domain_controller_type == "UNIX":
+ is_extended_credentials_enabled = None
+ is_secure_enabled = None
+ utils.UnityNfsServer.create(cli=self.unity_conn._cli, nas_server=nas_server_id, host_name=host_name,
+ nfs_v4_enabled=nfs_v4_enabled,
+ is_secure_enabled=is_secure_enabled, kdc_type=kdc_enum_type,
+ kdc_username=kerberos_domain_controller_username,
+ kdc_password=kerberos_domain_controller_password,
+ is_extended_credentials_enabled=is_extended_credentials_enabled)
+ return True
+ except Exception as e:
+ msg = "Failed to create NFS server with on NAS Server %s with error: %s" % (nas_server_id, str(e))
+ LOG.error(msg)
+ self.module.fail_json(msg=msg)
+
+ def validate_input_params(self):
+ param_list = ["nfs_server_id", "nas_server_id", "nas_server_name", "host_name", "kerberos_domain_controller_username",
+ "kerberos_domain_controller_password"]
+
+ for param in param_list:
+ msg = "Please provide valid value for: %s" % param
+ if self.module.params[param] is not None and len(self.module.params[param].strip()) == 0:
+ errmsg = msg.format(param)
+ self.module.fail_json(msg=errmsg)
+
+ def perform_module_operation(self):
+ """
+ Perform different actions on NFS server module based on parameters
+ passed in the playbook
+ """
+ nfs_server_id = self.module.params['nfs_server_id']
+ nas_server_id = self.module.params['nas_server_id']
+ nas_server_name = self.module.params['nas_server_name']
+ host_name = self.module.params['host_name']
+ nfs_v4_enabled = self.module.params['nfs_v4_enabled']
+ is_secure_enabled = self.module.params['is_secure_enabled']
+ kerberos_domain_controller_type = self.module.params['kerberos_domain_controller_type']
+ kerberos_domain_controller_username = self.module.params['kerberos_domain_controller_username']
+ kerberos_domain_controller_password = self.module.params['kerberos_domain_controller_password']
+ is_extended_credentials_enabled = self.module.params['is_extended_credentials_enabled']
+ remove_spn_from_kerberos = self.module.params['remove_spn_from_kerberos']
+ state = self.module.params['state']
+
+ # result is a dictionary that contains changed status and NFS server details
+ result = dict(
+ changed=False,
+ nfs_server_details={}
+ )
+
+ modify_flag = False
+
+ self.validate_input_params()
+
+ if nas_server_name:
+ nas_server_id = self.get_nas_server_id(nas_server_name)
+
+ nfs_server_details = self.get_nfs_server_details(nfs_server_id=nfs_server_id,
+ nas_server_id=nas_server_id)
+
+ # Check if modification is required
+ if nfs_server_details and state == 'present':
+ modify_flag = self.is_modification_required(is_extended_credentials_enabled, nfs_server_details)
+ if modify_flag:
+ self.module.fail_json(msg="Modification of NFS Server parameters is not supported through Ansible module")
+
+ if not nfs_server_details and state == 'present':
+ if not nas_server_id:
+ self.module.fail_json(msg="Please provide nas server id/name to create NFS server.")
+
+ result['changed'] = self.create_nfs_server(nas_server_id, host_name, nfs_v4_enabled,
+ is_secure_enabled, kerberos_domain_controller_type,
+ kerberos_domain_controller_username,
+ kerberos_domain_controller_password,
+ is_extended_credentials_enabled)
+
+ if state == 'absent' and nfs_server_details:
+ skip_unjoin = not remove_spn_from_kerberos
+ result['changed'] = self.delete_nfs_server(nfs_server_details["id"], skip_unjoin,
+ kerberos_domain_controller_username,
+ kerberos_domain_controller_password)
+
+ if state == 'present':
+ result['nfs_server_details'] = self.get_nfs_server_details(nfs_server_id=nfs_server_id,
+ nas_server_id=nas_server_id)
+ self.module.exit_json(**result)
+
+
+def get_nfs_server_parameters():
+ """This method provide parameters required for the ansible
+ NFS server module on Unity"""
+ return dict(
+ nfs_server_id=dict(type='str'),
+ host_name=dict(type='str'),
+ nfs_v4_enabled=dict(type='bool'),
+ is_secure_enabled=dict(type='bool'),
+ kerberos_domain_controller_type=dict(type='str', choices=['UNIX', 'WINDOWS', 'CUSTOM']),
+ kerberos_domain_controller_username=dict(type='str'),
+ kerberos_domain_controller_password=dict(type='str', no_log=True),
+ nas_server_name=dict(type='str'),
+ nas_server_id=dict(type='str'),
+ is_extended_credentials_enabled=dict(type='bool'),
+ remove_spn_from_kerberos=dict(default=True, type='bool'),
+ state=dict(required=True, type='str', choices=['present', 'absent']),
+ )
+
+
+def get_enum_kdctype(kerberos_domain_controller_type):
+ """Getting correct enum values for kerberos_domain_controller_type
+ :param: kerberos_domain_controller_type: Type of Kerberos Domain Controller used for secure NFS service.
+ :return: enum value for kerberos_domain_controller_type.
+ """
+
+ if utils.KdcTypeEnum[kerberos_domain_controller_type]:
+ kerberos_domain_controller_type = utils.KdcTypeEnum[kerberos_domain_controller_type]
+ return kerberos_domain_controller_type
+
+
+def process_dict(nfs_server_details):
+ """Process NFS server details.
+ :param: nfs_server_details: Dict containing NFS server details
+ :return: Processed dict containing NFS server details
+ """
+ param_list = ['credentials_cache_ttl', 'file_interfaces', 'host_name', 'id', 'kdc_type', 'nas_server', 'is_secure_enabled',
+ 'is_extended_credentials_enabled', 'nfs_v4_enabled', 'servicee_principal_name']
+
+ for param in param_list:
+ if param in nfs_server_details and param == 'credentials_cache_ttl':
+ nfs_server_details[param] = str(nfs_server_details[param][0])
+ else:
+ nfs_server_details[param] = nfs_server_details[param][0]
+ return nfs_server_details
+
+
+def main():
+ """Create Unity NFS server object and perform action on it
+ based on user input from playbook"""
+ obj = NFSServer()
+ obj.perform_module_operation()
+
+
+if __name__ == '__main__':
+ main()