
    Vh                         d Z ddlmZmZmZ eZdZdZdZ	ddl
mZ ddlmZ  ej                  d      Zd	Zd
 Z G d de      Zd Zd Zedk(  r e        yy)z,Ansible module for managing volumes on Unity    )absolute_importdivisionprint_functiona  

module: volume
version_added: '1.1.0'
short_description: Manage volume on Unity storage system
description:
- Managing volume on Unity storage system includes-
  Create new volume,
  Modify volume attributes,
  Map Volume to host,
  Unmap volume to host,
  Display volume details,
  Delete volume.

extends_documentation_fragment:
  - dellemc.unity.unity

author:
- Arindam Datta (@arindam-emc) <ansible.team@dell.com>
- Pavan Mudunuri(@Pavan-Mudunuri) <ansible.team@dell.com>

options:
  vol_name:
    description:
    - The name of the volume. Mandatory only for create operation.
    type: str
  vol_id:
    description:
    - The id of the volume.
    - It can be used only for get, modify, map/unmap host, or delete operation.
    type: str
  pool_name:
    description:
    - This is the name of the pool where the volume will be created.
    - Either the I(pool_name) or I(pool_id) must be provided to create a new volume.
    type: str
  pool_id:
    description:
    - This is the id of the pool where the volume will be created.
    - Either the I(pool_name) or I(pool_id) must be provided to create a new volume.
    type: str
  size:
    description:
    - The size of the volume.
    type: int
  cap_unit:
    description:
    - The unit of the volume size. It defaults to C(GB), if not specified.
    choices: ['GB' , 'TB']
    type: str
  description:
    description:
    - Description about the volume.
    - Description can be removed by passing empty string ("").
    type: str
  snap_schedule:
    description:
    - Snapshot schedule assigned to the volume.
    - Add/Remove/Modify the snapshot schedule for the volume.
    type: str
  compression:
    description:
    - Boolean variable, Specifies whether or not to enable compression.
      Compression is supported only for thin volumes.
    type: bool
  advanced_dedup:
    description:
    - Boolean variable, Indicates whether or not to enable advanced deduplication.
    - Compression should be enabled to enable advanced deduplication.
    - It can only be enabled on the all flash high end platforms.
    - Deduplicated data will remain as is even after advanced deduplication is disabled.
    type: bool
  is_thin:
    description:
    - Boolean variable, Specifies whether or not it is a thin volume.
    - The value is set as C(true) by default if not specified.
    type: bool
  sp:
    description:
    - Storage Processor for this volume.
    choices: ['SPA' , 'SPB']
    type: str
  io_limit_policy:
    description:
    - IO limit policy associated with this volume.
      Once it is set, it cannot be removed through ansible module but it can
      be changed.
    type: str
  host_name:
    description:
    - Name of the host to be mapped/unmapped with this volume.
    - Either I(host_name) or I(host_id) can be specified in one task along with
      I(mapping_state).
    type: str
  host_id:
    description:
    - ID of the host to be mapped/unmapped with this volume.
    - Either I(host_name) or I(host_id) can be specified in one task along with
      I(mapping_state).
    type: str
  hlu:
    description:
    - Host Lun Unit to be mapped/unmapped with this volume.
    - It is an optional parameter, hlu can be specified along
      with I(host_name) or I(host_id) and I(mapping_state).
    - If I(hlu) is not specified, unity will choose it automatically.
      The maximum value supported is C(255).
    type: int
  mapping_state:
    description:
    - State of host access for volume.
    choices: ['mapped' , 'unmapped']
    type: str
  new_vol_name:
    description:
    - New name of the volume for rename operation.
    type: str
  tiering_policy:
    description:
    - Tiering policy choices for how the storage resource data will be
      distributed among the tiers available in the pool.
    choices: ['AUTOTIER_HIGH', 'AUTOTIER', 'HIGHEST', 'LOWEST']
    type: str
  state:
    description:
    - State variable to determine whether volume will exist or not.
    choices: ['absent', 'present']
    required: true
    type: str
  hosts:
    description:
    - Name of hosts for mapping to a volume.
    type: list
    elements: dict
    suboptions:
      host_name:
        description:
        - Name of the host.
        type: str
      host_id:
        description:
        - ID of the host.
        type: str
      hlu:
        description:
        - Host Lun Unit to be mapped/unmapped with this volume.
        - It is an optional parameter, I(hlu) can be specified along
          with I(host_name) or I(host_id) and I(mapping_state).
        - If I(hlu) is not specified, unity will choose it automatically.
          The maximum value supported is C(255).
        type: str

notes:
  - The I(check_mode) is not supported.
at
  
- name: Create Volume
  dellemc.unity.volume:
    unispherehost: "{{unispherehost}}"
    username: "{{username}}"
    password: "{{password}}"
    validate_certs: "{{validate_certs}}"
    vol_name: "{{vol_name}}"
    description: "{{description}}"
    pool_name: "{{pool}}"
    size: 2
    cap_unit: "{{cap_GB}}"
    is_thin: true
    compression: true
    advanced_dedup: true
    state: "{{state_present}}"

- name: Expand Volume by volume id
  dellemc.unity.volume:
    unispherehost: "{{unispherehost}}"
    username: "{{username}}"
    password: "{{password}}"
    validate_certs: "{{validate_certs}}"
    vol_id: "{{vol_id}}"
    size: 5
    cap_unit: "{{cap_GB}}"
    state: "{{state_present}}"

- name: Modify Volume, map host by host_name
  dellemc.unity.volume:
    unispherehost: "{{unispherehost}}"
    username: "{{username}}"
    password: "{{password}}"
    validate_certs: "{{validate_certs}}"
    vol_name: "{{vol_name}}"
    host_name: "{{host_name}}"
    hlu: 5
    mapping_state: "{{state_mapped}}"
    state: "{{state_present}}"

- name: Modify Volume, unmap host mapping by host_name
  dellemc.unity.volume:
    unispherehost: "{{unispherehost}}"
    username: "{{username}}"
    password: "{{password}}"
    validate_certs: "{{validate_certs}}"
    vol_name: "{{vol_name}}"
    host_name: "{{host_name}}"
    mapping_state: "{{state_unmapped}}"
    state: "{{state_present}}"

- name: Map multiple hosts to a Volume
  dellemc.unity.volume:
    unispherehost: "{{unispherehost}}"
    username: "{{username}}"
    password: "{{password}}"
    validate_certs: "{{validate_certs}}"
    vol_id: "{{vol_id}}"
    hosts:
      - host_name: "10.226.198.248"
        hlu: 1
      - host_id: "Host_929"
        hlu: 2
    mapping_state: "mapped"
    state: "present"

- name: Modify Volume attributes
  dellemc.unity.volume:
    unispherehost: "{{unispherehost}}"
    username: "{{username}}"
    password: "{{password}}"
    validate_certs: "{{validate_certs}}"
    vol_name: "{{vol_name}}"
    new_vol_name: "{{new_vol_name}}"
    tiering_policy: "AUTOTIER"
    compression: true
    is_thin: true
    advanced_dedup: true
    state: "{{state_present}}"

- name: Delete Volume by vol name
  dellemc.unity.volume:
    unispherehost: "{{unispherehost}}"
    username: "{{username}}"
    password: "{{password}}"
    validate_certs: "{{validate_certs}}"
    vol_name: "{{vol_name}}"
    state: "{{state_absent}}"

- name: Delete Volume by vol id
  dellemc.unity.volume:
    unispherehost: "{{unispherehost}}"
    username: "{{username}}"
    password: "{{password}}"
    validate_certs: "{{validate_certs}}"
    vol_id: "{{vol_id}}"
    state: "{{state_absent}}"
a  

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

volume_details:
    description: Details of the volume.
    returned: When volume exists
    type: dict
    contains:
        id:
            description: The system generated ID given to the volume.
            type: str
        name:
            description: Name of the volume.
            type: str
        description:
            description: Description about the volume.
            type: str
        is_data_reduction_enabled:
            description: Whether or not compression enabled on this volume.
            type: bool
        size_total_with_unit:
            description: Size of the volume with actual unit.
            type: str
        snap_schedule:
            description: Snapshot schedule applied to this volume.
            type: dict
        tiering_policy:
            description: Tiering policy applied to this volume.
            type: str
        current_sp:
            description: Current storage processor for this volume.
            type: str
        pool:
            description: The pool in which this volume is allocated.
            type: dict
        host_access:
            description: Host mapped to this volume.
            type: list
        io_limit_policy:
            description: IO limit policy associated with this volume.
            type: dict
        wwn:
            description: The world wide name of this volume.
            type: str
        is_thin_enabled:
            description: Indicates whether thin provisioning is enabled for this
                         volume.
            type: bool
    sample: {
        "current_node": "NodeEnum.SPB",
        "data_reduction_percent": 0,
        "data_reduction_ratio": 1.0,
        "data_reduction_size_saved": 0,
        "default_node": "NodeEnum.SPB",
        "description": null,
        "effective_io_limit_max_iops": null,
        "effective_io_limit_max_kbps": null,
        "existed": true,
        "family_base_lun": {
            "UnityLun": {
                "hash": 8774954523796,
                "id": "sv_27"
            }
        },
        "family_clone_count": 0,
        "hash": 8774954522426,
        "health": {
            "UnityHealth": {
                "hash": 8774954528278
            }
        },
        "host_access": [
            {
                "accessMask": "PRODUCTION",
                "hlu": 0,
                "id": "Host_75",
                "name": "10.226.198.250"
            }
        ],
        "id": "sv_27",
        "io_limit_policy": null,
        "is_advanced_dedup_enabled": false,
        "is_compression_enabled": null,
        "is_data_reduction_enabled": false,
        "is_replication_destination": false,
        "is_snap_schedule_paused": false,
        "is_thin_clone": false,
        "is_thin_enabled": false,
        "metadata_size": 4294967296,
        "metadata_size_allocated": 4026531840,
        "name": "VSI-UNITY-test-task",
        "per_tier_size_used": [
            111400714240,
            0,
            0
        ],
        "pool": {
            "id": "pool_3",
            "name": "Extreme_Perf_tier"
        },
        "size_allocated": 107374182400,
        "size_total": 107374182400,
        "size_total_with_unit": "100.0 GB",
        "size_used": null,
        "snap_count": 0,
        "snap_schedule": null,
        "snap_wwn": "60:06:01:60:5C:F0:50:00:94:3E:91:4D:51:5A:4F:97",
        "snaps_size": 0,
        "snaps_size_allocated": 0,
        "storage_resource": {
            "UnityStorageResource": {
                "hash": 8774954518887
            }
        },
        "tiering_policy": "TieringPolicyEnum.AUTOTIER_HIGH",
        "type": "LUNTypeEnum.VMWARE_ISCSI",
        "wwn": "60:06:01:60:5C:F0:50:00:00:B5:95:61:2E:34:DB:B2"
    }
)AnsibleModule)utilsvolumezAnsible/1.7.1c                 :    |  xs t        t        |             dk  S )z9 validates the input string for None or empty values
    r   )lenstr)params    h/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/dellemc/unity/plugins/modules/volume.pyis_none_or_empty_stringr     s     9,CJ1,,    c                       e Zd ZdZdZdZdZd ZddZddZ	d Z
ddZddZd	 Zd
 ZddZd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zy)VolumezClass with volume operationsNc                 |   t        j                         | _        | j                  j                  t	                      ddgddgddgg}ddgg}t        | j                  d||      | _        t        j                  | j                         t        j                  | j                  j                  t              | _        y	)
z-Define all parameters required by this modulevol_namevol_id	pool_namepool_id	host_namehost_idF)argument_specsupports_check_modemutually_exclusiverequired_one_ofN)r   $get_unity_management_host_parametersmodule_paramsupdateget_volume_parametersr   moduleensure_required_libsget_unity_unisphere_connectionparamsapplication_type
unity_conn)selfr   r   s      r   __init__zVolume.__init__  s    "GGI!!"7"9:)84*I6*I68 '12 $,, %1+	-
 	""4;;/>>KK 02r   c                    |r|n|}d}	 | j                   j                  ||      }|r$|j                  rt        j	                  d|       |S |rt        j	                  d|       |S t        j	                  d|       y# t
        j                  $ r}|j                  dk(  rJdj                  |j                        }|j                  ||      }| j                  j                  |       n<|j                  |t        |            }| j                  j                  |       Y d}~yY d}~yd}~wt
        j                  $ r:}|j                  |t        |            }t        j                  |       Y d}~yd}~wt        $ rV}|j                  |t        |            }t        j                  |       | j                  j                  |       Y d}~yd}~ww xY w)	zGet the details of a volume.
            :param vol_name: The name of the volume
            :param vol_id: The id of the volume
            :return: instance of the respective volume if exist.
        z+Failed to get the volume {0} with error {1}name_idz&Successfully got the volume object %s zFailed to get the volume %sNi  z$Incorrect username or password , {0}msg)r&   get_lunexistedLOGinfor   	HttpErrorhttp_statusformatmessager!   	fail_jsonr   UnityResourceNotFoundErrorerror	Exception)	r'   r   r   
id_or_nameerrormsgobj_volecred_errr.   s	            r   
get_volumezVolume.get_volume  sv     &V8
@ 	+oo--8-HG'//A7KA7K6
C 	/}}#AHHIIooj(;%%#%.ooj#a&9%%#%.. /
 // 	//*c!f5CIIcN 	+//*c!f5CIIcNKK!!c!**	+s>   AA> A> 'A> >GBD++G0E66GAGGc                    |r|n|}d}	 | j                   j                  ||      }|r$|j                  rt        j	                  d|       |S |rt        j	                  d|       |S dj                  |      }t        j                  |       | j                  j                  |       y# t        $ rV}|j                  |t        |            }t        j                  |       | j                  j                  |       Y d}~yd}~ww xY w)zGet the instance of a host.
            :param host_name: The name of the host
            :param host_id: The id of the volume
            :return: instance of the respective host if exist.
        z)Failed to get the host {0} with error {1}r*   z$Successfully got the host object %s zFailed to get the host {0}r-   N)r&   get_hostr0   r1   r2   r5   r9   r!   r7   r:   r   )r'   r   r   r;   r<   obj_hostr.   r>   s           r   rB   zVolume.get_host  s     !(WY
>	+//YG/LH8++?J?J299*E		#%%#%. 	+//*c!f5CIIcNKK!!c!**		+&   AB* B* 'AB* *	D	3ADD	c                 8   d}	 t         j                  d|       t        j                  j	                  | j
                  j                  |      }|r&t        |      dkD  rt         j                  d|       |S dj                  |      }t         j                  |       | j                  j                  |       y# t        $ rV}|j                  |t        |            }t         j                  |       | j                  j                  |       Y d}~yd}~ww xY w)	zGet the instance of a snapshot schedule.
            :param name: The name of the snapshot schedule
            :return: instance of the respective snapshot schedule if exist.
        z6Failed to get the snapshot schedule {0} with error {1}z0Attempting to get Snapshot Schedule with name %sr+   r   z%Successfully got Snapshot Schedule %sz-Failed to get snapshot schedule with name {0}r-   N)r1   debugr   UnitySnapScheduleListgetr&   _clir
   r2   r5   r9   r!   r7   r:   r   )r'   r+   r<   obj_ssr.   r>   s         r   get_snap_schedulezVolume.get_snap_schedule  s     L	+IIH0044T__5I5I:> 5 @F3v;?@&I&&,fTl 		#%%#%. 	+//$A/CIIcNKK!!c!**	+s    A2B: 7AB: :	DADDc                    d}|r|n|}	 | j                   j                  ||      }|r$|j                  rt        j	                  d|       |S |rt        j	                  d|       |S dj                  |      }t        j                  |       | j                  j                  |       y# t        $ rV}|j                  |t        |            }t        j                  |       | j                  j                  |       Y d}~yd}~ww xY w)zGet the instance of a io limit policy.
            :param name: The io limit policy name
            :param id: The io limit policy id
            :return: instance of the respective io_limit_policy if exist.
        z4Failed to get the io limit policy {0} with error {1})r,   r+   z.Successfully got the IO limit policy object %sz/Successfully got the IO limit policy object %s z*Failed to get the io limit policy with {0}r-   N)r&   get_io_limit_policyr0   r1   r2   r5   r9   r!   r7   r:   r   )r'   r+   idr<   r;   	obj_iopolr.   r>   s           r   rN   zVolume.get_io_limit_policy  s     J!Tr
	+;;;NIi''I"$  J"$  BII 		#%%#%. 	+//$A/CIIcNKK!!c!**	+rD   c                    |r|n|}d}	 | j                   j                  ||      }|r$|j                  rt        j	                  d|       |S |rt        j	                  d|       |S dj                  |      }t        j                  |       | j                  j                  |       y# t        $ rV}|j                  |t        |            }t        j                  |       | j                  j                  |       Y d}~yd}~ww xY w)zGet the instance of a pool.
            :param pool_name: The name of the pool
            :param pool_id: The id of the pool
            :return: Dict containing pool details if exists
        z)Failed to get the pool {0} with error {1}r*   z#Successfully got the pool object %szSuccessfully got pool %szFailed to get the pool with {0}r-   N)r&   get_poolr0   r1   r2   r5   r9   r!   r7   r:   r   )r'   r   r   r;   r<   obj_poolr.   r>   s           r   rR   zVolume.get_pool;  s     !(WY
>	+//YG/LH8++>!#3X>"F:. 		#%%#%. 	+//*c!f5CIIcNKK!!c!**	+rD   c                     |t         j                  j                  v rt         j                  |   S dj                  |      }t        j                  |       | j                  j                  |       y)zGet the storage processor enum.
             :param sp: The storage processor string
             :return: storage processor enum
        z(Invalid choice {0} for storage processorr-   N)r   NodeEnum__members__r5   r1   r9   r!   r7   )r'   spr<   s      r   get_node_enumzVolume.get_node_enumZ  sY     +++>>"%%AHHHIIhKK!!h!/r   c                     |t         j                  j                  v rt         j                  |   S dj                  |      }t        j                  |       | j                  j                  |       y)zGet the tiering_policy enum.
             :param tiering_policy: The tiering_policy string
             :return: tiering_policy enum
        z%Invalid choice {0} for tiering policyr-   N)r   TieringPolicyEnumrV   r5   r1   r9   r!   r7   )r'   tiering_policyr<   s      r   get_tiering_policy_enumzVolume.get_tiering_policy_enumh  s]     U44@@@**>::>EE HIIhKK!!h!/r   c                    | j                   j                  d   }	 | j                   j                  d   }| j                   j                  d   }| j                   j                  d   }| j                   j                  d   }d}	| j                   j                  d   }
|
r| j                  |
      nd}
| j                   j                  d   r| j                  | j                  	      nd}| j
                  rd
| j
                  i}	| j                   j                  d   }|r| j                  |      nd}|j                  |||
|||||	|||      }t        j                  d|       |S # t        $ rV}dj                  |t        |            }t        j                  |       | j                   j                  |       Y d}~yd}~ww xY w)zCreate a volume.
            :param obj_pool: pool object instance
            :param size: size of the volume in GB
            :param host_access: host to be associated with this volume
            :return: Volume object on successful creation
        r   descriptioncompressionadvanced_dedupis_thinNrW   io_limit_policyrO   r+   r[   )lun_namesize_gbrW   host_accessra   r^   r[   snap_schedulerb   is_compressionis_advanced_dedup_enabled Successfully created volume , %sz1Create volume operation {0} failed with error {1}r-   )r!   r$   rX   rN   param_io_limit_pol_idparam_snap_schedule_namer\   
create_lunr1   r2   r:   r5   r   r9   r7   )r'   rS   sizerf   r   r^   r_   r`   ra   rg   rW   rb   r[   r=   r>   r<   s                   r   create_volumezVolume.create_volumev  s    ;;%%j1*	0++,,];K++,,];K![[//0@ANkk((3G M##D)B+-##B'4B ;;%%&78 #66-- 7 />B  ,,!')F)F G![[//0@AN! "99.I'+  ))826-/6A296A9G8E:I9DDR * 
TG HH7AN 	0))/#a&)A IIhKK!!h!//		0s   EE" "	G+AF<<Gc                    	 d}| j                   j                  d   }g }g }g }|s| j                  r|dk(  r|S |r|j                  D ]  }|j	                  |j
                         | j                  |j
                        j                         }|j                  j                         }	t        j                  d|	       d|	j                         v s|j	                  |	d           |dk(  rb| j                  |vrT| j                  D ]"  }
|j	                  |
j                  d             $ t        t!        |      t!        |      z
        syd	}|dk(  r| j                  ry| j                  D ]"  }
|j	                  |
j                  d             $ t        t!        |      t!        |      z
        ryt        t!        |      t!        |      z
        | _        d	}t        j                  d
t%        |             |S # t&        $ rV}dj)                  |t%        |            }t        j+                  |       | j                   j-                  |       Y d}~yd}~ww xY w)zCheck if host access modification is required
            :param host_access_list: host access dict list
            :return: Dict with attributes to modify, or None if no
            modification is required.
        Fmapping_stateunmappedr   zcheck if hlu present : %shlumappedr   Tz!host_access_modify_required : %s z4Failed to compare the host_access with error {0} {1}r-   N)r!   r$   new_host_listhostappendrO   rB   r   	host_luns_get_propertiesr1   rG   keysparam_host_idrI   listsetoverlapping_listr   r:   r5   r9   r7   )r'   host_access_list	to_modifyrq   host_id_listhlu_listnew_listrf   rw   	host_dictitemr>   r<   s                r   host_access_modify_requiredz"Volume.host_access_modify_required  s   ,	0I KK..?MLHH#(:(:!Z/  !#3#8#8 :K ''7===@GGID $ > > @III99E	 00 	%(89: (&&l: $ 2 2 = (;<=HL0A AB$ $I
*%% $ 2 2 = (;<=CMC,==>$,0\1BS]1R,SD) $III93y>J 	0#V$4c!f= IIhKK!!h!//		0s3   5G9 BG9 A:G9 A$G9 1AG9 9	IAIIc                 
   	 i }| j                   j                  d   }|r"|j                  |k7  r|j                  d|i       | j                   j                  d   }|r"|j                  |k7  r|j                  d|i       | j                   j                  d   }|ro|rmt        t        j                  ||            }||j                  k  r| j                   j                  d       n"||j                  kD  r|j                  d|i       | j                   j                  d   }|"||j                  k7  r|j                  d	|i       | j                   j                  d
   }	|	"|	|j                  k7  r|j                  d|	i       | j                   j                  d   }
|
+|
|j                  k7  r| j                   j                  d       | j                   j                  d   }|r@| j                  |      |j                  k7  r"|j                  d| j                  |      i       | j                   j                  d   }|r@| j                  |      |j                   k7  r"|j                  d| j                  |      i       | j"                  rL|j$                  r#| j"                  |j$                  j&                  k7  r|j                  d| j"                  i       | j(                  rL|j*                  r#| j(                  |j*                  j                  k7  r|j                  d| j(                  i       | j(                  dk(  r5|j*                  r|j                  ddi       nt,        j/                  d       t,        j1                  d|       t3        |      dkD  r|S y# t4        $ r`}dj7                  |j                  t9        |            }t,        j;                  |       | j                   j                  |       Y d}~yd}~ww xY w)zCheck if volume modification is required
            :param obj_vol: volume instance
            :param cap_unit: capacity unit
            :return: Boolean value to indicate if modification is required
        new_vol_namer+   r^   rn   z Volume size can be expanded onlyr-   r_   Nrh   r`   ri   ra   z Modifying is_thin is not allowedrW   r[   rb   rg    is_snap_schedule_pausedFz"No snapshot schedule is associatedzVolume to modify  Dict : %sr   zGFailed to determine if volume {0},requires modification, with error {1})r!   r$   r+   r   r^   intr   get_size_bytes
size_totalr7   is_data_reduction_enabledri   is_thin_enabledrX   current_noder\   r[   rk   rb   rO   rl   rg   r1   warnrG   r
   r:   r5   r   r9   )r'   r=   cap_unit	to_updater   r^   rn   	size_byter_   r`   ra   rW   r[   r>   r<   s                  r   volume_modify_requiredzVolume.volume_modify_required  s   O	0I;;--n=L <  &,!78++,,];Kw22kA  -!=>;;%%f-D 4 4T8 DE	w111KK)) />) ?!3!33$$fi%89++,,];K&7#D#DD  "2K!@A![[//0@AN)"g&G&GG  "=~!NOkk((3G"w'2I2I'I%%*L%M##D)Bd((,0D0DD  $(:(:2(>!?@![[//0@AN$">">"#$'.'='=#>  "2"&">">&4#6"7 8
 ))// 66&6699:$$*D,F,FGI ,,-- 99&4499:$$o&*&C&C&E F ,,2(($$&?%GHHHABII3Y?9~!   	066<fW\\=@V7E  IIhKK!!h!//	0s   NN 	P"AO==Pc                 
   	 g }| j                  |      }|D ].  }|j                  t        d|d   z         d|d   i|d   d       0 |D ]7  }|j                  t        j                  j
                  d|d   i|d   d       9 |j                  |      }|S # t        $ ra}dj                  ||j                  t        |            }	t        j                  |	       | j                  j                  |		       Y d
}~y
d
}~ww xY w)zAttach multiple hosts to a volume
        :param host_dic_list: hosts to map the volume
        :param obj_vol: volume instance
        :return: response from API call
        zutils.HostLUNAccessEnum.
accessMaskrO   rt   r   rw   rt   r   rf   z:Failed to attach hosts {0} with volume {1} with error {2} r-   N)get_volume_host_access_listrx   evalr   HostLUNAccessEnum
PRODUCTIONmodifyr:   r5   r+   r   r1   r9   r!   r7   )
r'   host_dic_listr=   rf   current_hostsexisting_hostr   respr>   r<   s
             r   multiple_host_mapzVolume.multiple_host_map9  s!   	0K <<WEM!. T""#'(B]S_E`(`#ad 34]5=QSTT
 & G""#(#:#:#E#EY0eFGG
 >>k>:DK 	0SZZ[hjqjvjvx{|}x~HIIhKK!!h!//	0s   BB 	D!AC==Dc                 t   	 g }|D ]0  }|j                  t        j                  j                  d|id       2 |j	                  |      }|S # t
        $ ra}dj                  ||j                  t        |            }t        j                  |       | j                  j                  |       Y d}~yd}~ww xY w)zDetach multiple hosts from a volume
        :param host_list_detach: hosts to unmap the volume
        :param obj_vol: volume instance
        :return: response from API call
        rO   r   rw   r   z:Failed to detach hosts {0} from volume {1} with error {2} r-   N)rx   r   r   r   r   r:   r5   r+   r   r1   r9   r!   r7   )r'   host_list_detachr=   rf   r   r   r>   r<   s           r   multiple_detachzVolume.multiple_detachT  s    
	0K( ;""%2I2I2T2T-14L$: ;; >>k>:DK 	0SZZ[kmtmymy{~  @A  |B  CHIIhKK!!h!//	0s   A
A 	B7AB22B7c                    	 d|j                         v r| j                  |d         |d<   d|j                         v r|d   dk7  r
d|d   i|d<   g d}|D ](  }||j                         vs|j                  |di       * t        j	                  d|       |j                  |d   |d	   |d
   |d   |d   |d   |d   |d   |d   |d   |d          y# t        $ r`}dj                  |j                  t        |            }t        j                  |       | j                  j                  |       Y d}~yd}~ww xY w)zmodify volume attributes
            :param obj_vol: volume instance
            :param to_modify_dict: dict containing attributes to be modified.
            :return: None
        rb   rc   rg   r   r+   )r+   rn   rf   r^   rW   rb   r[   rg   r   rh   ri   Nz,Final update dict before modify api call: %srn   rf   r^   rW   r[   r   rh   ri   z.Failed to modify the volume {0} with error {1}r-   )r{   rN   r   r1   rG   r   r:   r5   r+   r   r9   r!   r7   )r'   r=   to_modify_dict
param_listr   r>   r<   s          r   modify_volumezVolume.modify_volumeg  s   '	0 N$7$7$99484L4L%&78 5M 5:01 ."5"5"77"?3r9^O<= /IJ
 # 8~2244"))4,78 II %&46 NNv 6 .v 6'5m'D'5m'D,T2+9:K+L*89I*J)7)H3AB[3\*89I*J5CD_5`  
b  	0((.w||SV(D IIhKK!!h!//		0s    A)C ,A(C 	D>AD99D>c                    	 | j                  |      }|j                  d       y# t        $ rZ}dj                  t        t        |            }t        j                  |       | j                  j                  |       Y d}~yd}~ww xY w)z_Delete volume.
        :param vol_obj: The object instance of the volume to be deleted
        )r   F)force_snap_deleteTz7Delete operation of volume id:{0} failed with error {1}r-   N)
r@   deleter:   r5   rO   r   r1   r9   r!   r7   )r'   r   r=   r>   r<   s        r   delete_volumezVolume.delete_volume  s{    

	0ooVo4GNNUN3 	0//5vb69!f0>  IIhKK!!h!//	0s   $' 	B
ABB
c                    g }|j                   r|j                   D ]  }| j                  |j                  j                        j	                         }d}|j
                  D ]2  }|j                  j                  |j                  k(  s'|j                  }4 |j                  |j                  j                  |j                  j                  |j                  j                  |d        |S )zp
        Get volume host access list
        :param obj_vol: volume instance
        :return: host list
        rs   N)r+   rO   r   rt   )rf   rB   rw   rO   r   ry   lunr+   rt   rx   access_mask)r'   r=   	host_listrf   rw   rt   host_luns          r   r   z"Volume.get_volume_host_access_list  s     	&22 	/}}[-=-=-@-@}AHHJ $ +H||((GLL8&ll+   +*:*:*?*?(3(8(8(;(;0;0G0G0L0L),". /	/ r   c                 h   	 |j                         }|j                         }t        j                  t	        |d               |d<   |j                  d| j                  |      i       |j                  r>|j                  d|j                  j                  |j                  j                  di       |j                  r>|j                  d|j                  j                  |j                  j                  di       |j                  r>|j                  d|j                  j                  |j                  j                  di       |S # t        $ r`}dj                  |j                  t        |            }t        j                  |       | j                   j#                  |	       Y d
}~y
d
}~ww xY w)zvget display volume attributes
        :param obj_vol: volume instance
        :return: volume dict to display
        r   size_total_with_unitrf   rg   )r+   rO   rb   poolz/Failed to display the volume {0} with error {1}r-   N)r   rz   r   convert_size_with_unitr   r   rg   r+   rO   rb   r   r:   r5   r   r1   r9   r!   r7   )r'   r=   volume_detailsr>   r<   s        r   get_volume_display_attributesz$Volume.get_volume_display_attributes  s   
	0nn&G$446N5:&&s>,+G'H6JN12!!=$2R2RSZ2["\]$$%%$w/D/D/I/I-4-B-B-E-E'G HI &&%%&1H1H1K1K/6/F/F/I/I)K LM ||%%v8I8I6=lloo0G 'H I "! 	0##)6',,A#? IIhKK!!h!//		0s   EE 	F1AF,,F1c                    d}	 ddg}| j                   j                  D ]d  }| j                   j                  |   }||vs!t        |t              s2||k(  s8dj	                  |      }| j                   j                  |       f y# t        $ rU}dj	                  t        |            }t        j                  |       | j                   j                  |       Y d}~yd}~ww xY w)zB validates the input string checks if it is empty string

        r   rg   r^   z"Invalid input parameter "" for {0}r-   2Failed to validate the module param with error {0}N)	r!   r$   
isinstancer   r5   r7   r:   r1   r9   )r'   invalid_stringno_chk_listkeyvalerrmsgr>   r<   s           r   validate_input_stringzVolume.validate_input_string  s     	0*M:K{{)) 6kk((-k)jc.B>1AHHFKK))f)56  	0##)6#a&> IIhKK!!h!//		0s)   :B B B /B 	C$ACC$c                 P   	 |D ]  }d|j                         v r:d|j                         v r(|d   r#|d   rd}| j                  j                  |       d}|j                         D ],  \  }}|dk(  rt	        |      sd}|dk(  st	        |      r+d}. |sdj                        }| j                  j                  |        y	# t        $ rU}dj                  t        |            }t        j                  |       | j                  j                  |       Y d	}~y	d	}~ww xY w)
zA validates the host_list_input value for None and empty

        r   r   z4parameters are mutually exclusive: host_name|host_idr-   TFzInvalid input parameter for {0}r   N)
r{   r!   r7   itemsr   r5   r:   r   r1   r9   )	r'   host_list_inputr   r   is_host_details_missingr   valuer>   r<   s	            r   validate_host_listzVolume.validate_host_list  s   	0, 6	9>>#33	Y^^EU8U -)I2F!W--&-9*.'"+//"3 8JCk)2I%2P27/	)2I%2P27/	8 +>EEcJFKK))f)56   	0##)6#a&> IIhKK!!h!//		0s+   BC C C /C 	D%AD  D%c                     g }|rl|D ]g  }t               }d}d}|d   r#| j                  |d         }|r|j                  }|d   r|d   }|d   r|d   }||d<   ||d<   |j                  |       i |S )z This method creates a dictionary of hosts and hlu parameter values
            :param hosts: host and hlu value passed from input file
            :return: list of host and hlu dictionary
        Nr   )r   r   rt   )dictrB   rO   rx   )r'   hostshost_list_newr   r   r   rt   rw   s           r   resolve_host_mappingszVolume.resolve_host_mappings  s    
  0 F	$==43D=ED"&''	?"9oG;u+C'.	)$#&	% $$Y/0 r   c                    g | _         g | _        | j                  j                  d   }| j                  j                  d   }| j                  j                  d   }| j                  j                  d   }| j                  j                  d   }| j                  j                  d   }| j                  j                  d   }| j                  j                  d   }| j                  j                  d	   }	| j                  j                  d
   }
| j                  j                  d   }| j                  j                  d   }| j                  j                  d   }| j                  j                  d   }| j                  j                  d   }d}t	        di       }d}d}d}| j                          |r| j                  |       |!|dk(  r| j                  j                  d       |r|sd}||s| j                  j                  d       |r"|	s |
s|s| j                  j                  d       |r"|	s |
s|s| j                  j                  d       | j                  ||      }|	s|
r=|sd}| j                  j                  |       |	|
|dg}| j                  |      | _         |rD|sd}| j                  j                  |       | xj                   | j                  |      z  c_         |r#| j                  |      }|j                  | _        |r&| j                  |      }|j                  d   | _        |dk(  r|| _        |r|j!                         }|j#                         }| j%                  ||      }t&        j)                  d|       |j*                  r3| j-                  |j*                         }t&        j)                  d!|       n>| j                   r2| j-                  |j*                         }t&        j)                  d"|       |d#k(  r|s|s-d$j/                  |      }| j                  j                  |       |dk(  r| j                  j                  d%       |r| j                  j                  d&       |s|s| j                  j                  d'       |s| j                  j                  d(       d}| j                   rg }| j                   D ]n  }|d   r6|j1                  t2        j4                  j6                  d)|d
   i|d   d*       >|j1                  t2        j4                  j6                  d)|d
   id+       p t3        j8                  ||      }| j;                  ||,      }| j=                  |||-      }|rJt&        j)                  d.|       |j                  }|j!                         }t&        j)                  d/|       d0}|d#k(  r|r|r| j?                  ||1       d0}|d#k(  r8|r6|d2k(  r1|r/| j                   r#| jA                  | j                   |3      }|rd0nd}|d#k(  rM|rK|d4k(  rF|rD| j                   r8| jC                  | j                  |5      }t&        jE                  |       |rd0nd}|d6k(  r|r| jG                  |      }d}|d#k(  r|r| jI                  |7      }||d8<   ||d9<    | j                  jJ                  d:i | y);zo
        Perform different actions on volume module based on parameters
        passed in the playbook
        r   r   r   r   rn   r   rg   rb   r   r   rt   rq   r   stater   F)changedr   Nr   zSize can not be 0 (Zero)r-   GBz)cap_unit can be specified along with sizez.hlu can be specified with host_id or host_namezAmapping_state can be specified with host_id or host_name or hosts)r   r   zJ'mapping_state' is required along with 'host_name' or 'host_id' or 'hosts')r   r   rt   rF   r   zVolume Modify Required: %s)r   z"Host Modify Required in access: %szHost Modify Required: %spresentzSvolume with id {0} is not found, unable to create a volume without a valid vol_namezInvalid snap_schedulez3new_vol_name is not required to create a new volumez5pool_id or pool_name is required to create new volumez#Size is required to create a volumerO   r   r   )r   r   )rS   rn   rf   rj   zGot volume id , %sT)r=   r   ru   )r   r=   rr   )r   r=   absent)r=   r   r    )&rv   r   r!   r$   r   r   r   r7   r@   r   rN   rO   rk   rL   r+   rl   rz   get_idr   r1   rG   rf   r   r5   rx   r   r   r   get_size_in_gbrR   ro   r   r   r   r2   r   r   	exit_json)r'   r   r   r   r   rn   r   rg   rb   r   r   rt   rq   r   r   r   r   resultr   r   to_modify_hostr=   r   rw   
msg_nonamerf   r   rS   r   s                                r   perform_module_operationzVolume.perform_module_operation$  s   
   ";;%%j1##H-KK&&{3	++$$Y/{{!!&);;%%j1**?;++,,->?KK&&{3	++$$Y/kk  '**?;{{)).9""7+""7+ 

 ""$##E*	KK!!&@!AH $KK!! '2! 3 	'%KK!! '=! >)GEKK!! 'L! M //(/C ?%%&%1"+LMD!%!;!;D!AD ?%%&%1$"<"<U"CC"66O6LO)8););D& 222FM,9,>,>q,AD) B,9D)$446N^^%F!88(KNII2NC""!%!A!A%,%8%8 "B ":		>O##!%!A!A%,%8%8 "B ":		4nEIn((.v  %%*%5"%%*A%B%% +C% DW%% +A% B%% +6% 7K!!  .. qDE{#**+0+B+B+M+MX\^bcl^mWn$(K12 $**+0+B+B+M+MX\^bcl^mWnoqq ''h7D}}y'}JH(((5@ ) BG		<gF !(!8!8!:		.7I.^w~NGY>!X-.!!--D<N<NX_-`"&$EY>!Z/N!!++T=R=R\c+d"&$EH((0G!NI.!?? @ !N $y#1 ''r   )NN)N)__name__
__module____qualname____doc__r|   rk   rl   r(   r@   rB   rL   rN   rR   rX   r\   ro   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r     s    &M #2,*+X+>+6+>+>0040l30jV0p060&.0`0"(0>0*062j(r   r   c                     t        d*i dt        dd      dt        dd      dt        dd      dt        dd      dt        dd      d	t        dd
      dt        ddddg      dt        dd      dt        dd      dt        dd      dt        ddddg      dt        dd      dt        dd      dt        dd      dt        dd      dt        dddt        t        dd      t        dd      t        dd                  dt        dd
      d t        ddd!d"g      d#t        dd      d$t        ddg d%      d&t        d'dd(d)g      S )+zUThis method provide parameters required for the ansible volume
       module on Unityr   Fr   )requiredtyper   r^   r   r   rn   r   r   r   TB)r   r   choicesra   boolr_   r`   rW   SPASPBrb   rg   r   r   r   r}   r   )r   r   rt   )r   r   elementsoptionsrt   rq   ru   rr   r   r[   )AUTOTIER_HIGHAUTOTIERHIGHESTLOWESTr   Tr   r   r   )r   r   r   r   r    r      s     u51U/ %e4 E2	
 e%0 5u- u54,G e&1 %f5 U8 UUENC e%8 E6 E2 e%0  E#U?!%u5!AU;!, %e,-. E$,j#9;/2 5u534 U A> ?58 Duy(6KL9 r   c                  8    t               } | j                          y)z^ Create Unity volume object and perform action on it
        based on user input from playbookN)r   r   )objs    r   mainr     s     (C  "r   __main__N)r   
__future__r   r   r   r   __metaclass__DOCUMENTATIONEXAMPLESRETURNansible.module_utils.basicr   Cansible_collections.dellemc.unity.plugins.module_utils.storage.dellr   
get_loggerr1   r%   r   objectr   r    r   r   r   r   r   <module>r      s    3 @ @ZxaF{
z 5 ex " -v(V v(r F# zF r   