
    Vh,L                     l   d Z ddlmZmZmZ eZdZdZddl	m
Z
mZ ddlmZmZmZmZmZmZmZmZ 	 ddlmZ d Zd	 Zd
 Zd Zd Zd Zed        Zed        Zed        Z ed        Z!ed        Z"ed        Z#ed        Z$ed        Z%d Z&d Z'd Z(d Z)d Z*d Z+d Z,e-dk(  r e,        yy# e$ r Y |w xY w)z?This module creates, deletes or modifies mappings on Infinibox.    )absolute_importdivisionprint_functiona  
---
module: infini_map
version_added: 2.9.0
short_description: Create and Delete mapping of a volume to a host or cluster on Infinibox
description:
    - This module creates or deletes mappings of volumes to hosts or clusters
      on Infinibox.
    - For Linux hosts, after calling this module, the playbook should execute "rescan-scsi-bus.sh" on the host when creating mappings.
    - When removing mappings "rescan-scsi-bus.sh --remove" should be called.
    - For Windows hosts, consider using "'rescan' | diskpart" or "Update-HostStorageCache".
author: David Ohlemacher (@ohlemacher)
options:
  host:
    description:
      - Host Name
    type: str
    required: false
  cluster:
    description:
      - Cluster Name
    type: str
    required: false
  state:
    description:
      - Creates mapping when present or removes when absent, or provides
        details of a mapping when stat.
    required: false
    default: present
    choices: [ "stat", "present", "absent" ]
    type: str
  volume:
    description:
      - Volume name to map to the host.
    type: str
    required: true
  lun:
    description:
      - Volume lun.
    type: int
extends_documentation_fragment:
    - infinibox
a  
- name: Map a volume to an existing host
  infini_map:
    host: foo.example.com
    volume: bar
    state: present  # Default
    user: admin
    password: secret
    system: ibox001

- name: Map a volume to an existing cluster
  infini_map:
    cluster: test-cluster
    volume: bar
    state: present  # Default
    user: admin
    password: secret
    system: ibox001

- name: Unmap volume bar from host foo.example.com
  infini_map:
    host: foo.example.com
    volume: bar
    state: absent
    system: ibox01
    user: admin
    password: secret

- name: Stat mapping of volume bar to host foo.example.com
  infini_map:
    host: foo.example.com
    volume: bar
    state: stat
    system: ibox01
    user: admin
    password: secret
)AnsibleModulemissing_required_lib)HAS_INFINISDKapi_wrapperget_clusterget_host
get_system
get_volumeinfinibox_argument_specmerge_two_dicts)APICommandFailedc                 T    |j                         }|D ]  }|j                  | k(  s y y)z4 Return a bool showing if a vol is mapped to a host TFget_lunsvolume)r   host	host_lunsluns       r/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/infinidat/infinibox/plugins/modules/infini_map.pyvol_is_mapped_to_hostr   v   s0    I ::     c                 T    |j                         }|D ]  }|j                  | k(  s y y)z7 Return a bool showing if a vol is mapped to a cluster TFr   )r   clustercluster_lunsr   s       r   vol_is_mapped_to_clusterr      s3    ##%L :: r   c                     ddd}| j                   d   }|r?|j                         D ],  }||j                  k(  s|j                  |k(  rddd}(ddd}. |S )z7 Return a dict showing if a host lun matches a volume. Flun_usedlun_volume_matchesr   T)paramsr   r   r   )moduler   r   check_resultdesired_lunhost_luns         r   find_host_lun_user(      sh     %UCL--&K 	SHhll*??f,04D#QL04E#RL	S r   c                     ddd}| j                   d   }|r5|j                         D ]"  }||k(  s	|j                  |k(  rddd}ddd}$ |S )z: Return a dict showing if a cluster lun matches a volume. Fr    r   T)r#   r   r   )r$   r   r   r%   r&   cluster_luns         r   find_cluster_lun_user+      sg     %UCL--&K"++- 	SKk)>>V+04D#QL04E#RL	S r   c                 p    d}| j                         }|D ]  }|j                  |k(  s|j                  }  |S )z Find a hosts lun Nr   r   r   )r   r   	found_lunlunsr   s        r   find_host_lunr0      s>    I==?D  ::I  r   c                 p    d}| j                         }|D ]  }|j                  |k(  s|j                  }  |S )z Find a cluster's LUN Nr-   )r   r   r.   r/   r   s        r   find_cluster_lunr2      sA    ID  ::I  r   c                     t        | |      }t        | |      }|rt        | |      }|S |rt        | |      }|S d}| j	                  |       S )z_ Create mapping of volume to host or cluster. If already mapped, exit_json with changed False. z4A programming error has occurred in create_mapping()msg)r   r
   create_mapping_to_hostcreate_mapping_to_cluster	fail_jsonr$   systemr   r   changedr5   s         r   create_mappingr<      sj     FF#D&&)G(8 N 
+FF; N ES! Nr   c           	         d}t        | |      }t        | |      }| j                  d   }| j                  d   }| j                  d   }t        | ||      }|d   rd| d| d| d	}	| j	                  |	
       	 | j                  d   }
| j
                  s|j                  ||
       d}|S # t        $ r?}dt        |      vr'd| d| dt        |       d}	| j	                  |	
       Y d}~|S d}~ww xY w)zW Create mapping of volume to cluster. If already mapped, exit_json with changed False. Fr   r   r   r!   !Cannot create mapping of volume '' to cluster '' using lun ''. Lun in use.r4   r   Tis already mappedCannot map volume '': . Already mapped.N)	r
   r   r#   r+   r8   
check_mode
map_volumer   str)r$   r:   r;   r   r   volume_namecluster_namelun_namelun_user5   r&   errs               r   r7   r7      s'    G&&)G'F--)K==+L}}U#H"67F;Gz1+n\NZghpgqq  AS!&mmE*  v;7 N  &c#h.'}N<.PSTWX[T\S]]noC%N&s   90B+ +	C344C..C3c           	      &   d}|j                   j                  | j                  d         }t        | |      }| j                  d   }| j                  d   }| j                  d   }t	        | ||      }|d   rd| d| d	| d
}	| j                  |	       	 | j                  d   }
| j                  s|j                  ||
       d}|S # t        $ r?}dt        |      vr'd| d| dt        |       d}	| j                  |	       Y d}~|S d}~ww xY w)zT Create mapping of volume to host. If already mapped, exit_json with changed False. Fr   )namer   r   r!   r>   ' to host 'r@   rA   r4   rB   TrC   rD   rE   rF   N)
hostsgetr#   r   r(   r8   rG   rH   r   rI   )r$   r:   r;   r   r   rJ   	host_namerL   rM   r5   r&   rN   s               r   r6   r6      s1    G<<v!67D'F--)Kf%I}}U#Hf5Gz1+k)TabjakkyzS!&mmE*  OOFO4 N  &c#h.'	{+i[CPSH:UfgC%N&s   0C 	D4DDc           	      J   t        | |      }t        | |      }| j                  d   }| j                  d   }| j                  d   }t        ||      sd| d| d}| j	                  |       |r2t        ||      }||k7  r!d| d	| d
| d| d	}| j	                  |       d}	|	S )z Update a mapping to a host r   r   r   Volume '' is not mapped to host ''r4   Cannot change the lun from '' to '"' for existing mapping of volume 'rQ   F)r   r   r#   r   r8   r0   )
r$   r:   r   r   rJ   rT   r&   r5   r.   r;   s
             r   update_mapping_to_hostr\     s     FF#D'F--)Kf%I--&K .%>ykKS!!$/	#06+Npq|p}  ~I  JS  IT  TU  VC%GNr   c           	      H   t        | |      }t        | |      }| j                  d   }| j                  d   }| j                  d   }t        ||      sd| d| }| j	                  |       |r2t        ||      }||k7  r!d| d| d	| d
| d	}| j	                  |       d}	|	S )z Update a mapping to a cluster r   r   r   zVolume z is not mapped to cluster r4   rY   rZ   r[   r?   rX   F)r
   r   r#   r   r8   r2   )
r$   r:   r   r   r&   rJ   rK   r5   r.   r;   s
             r   update_mapping_to_clusterr^   &  s     &&)G'F--&K--)K==+L#FG4}$>|nMS!$Wf5	#06+Npq|p}  ~L  MY  LZ  Z[  \C%GNr   c                     t        | |      }t        | |      }|rt        | |      }|S |rt        | |      }|S d}| j	                  |       S )z Delete a mapping z4A programming error has occurred in delete_mapping()r4   )r   r
   delete_mapping_to_hostdelete_mapping_to_clusterr8   r9   s         r   delete_mappingrb   =  sj     FF#D&&)G(8 N 
+FF; N ES! Nr   c                    d}d}| j                   sqt        | |      }t        | |      }| j                  d   }| j                  d   }|r/|r-	 t	        ||      }|j                  |       d}d| d| d| d	}nd| d| d}nd}| j                  ||       y# t        $ rD}	d
t        |	      vr$| j                  d| d| dt        |	              n	d| d| d}Y d}	~	\d}	~	ww xY w)a$  
    Remove mapping of volume from host. If the either the volume or host
    do not exist, then there should be no mapping to unmap. If unmapping
    generates a key error with 'has no logical units' in its message, then
    the volume is not mapped.  Either case, return changed=False.
    F r   r   TrV   z' was unmapped from host '' freeing lun 'rX   has no logical unitsCannot unmap volume 'z' from host 'rE   z' was not mapped to host '#' and so unmapping was not executedNEither volume 'z' or host ',' does not exist. Unmapping was not executedr5   r;   )
rG   r   r   r#   r0   unmap_volumeKeyErrorrI   r8   	exit_json)
r$   r:   r;   r5   r   r   rJ   rT   existing_lunrN   s
             r   r`   r`   R  s'    G
CFF+'mmH-MM&)	d	{,T6:!!&) -G	{Rabnaoopq $K=I;FrsC
g.  {)S9$$'<[MW`Vaadehilemdn%op$[M1KI;VyzC	{s   +B 	C%!:C  C%c           	         d}d}| j                   sqt        | |      }t        | |      }| j                  d   }| j                  d   }|r/|r-	 t	        ||      }|j                  |       d}d| d| d| d	}nd| d| d}nd}| j                  ||       y# t        $ rG}	d
t        |	      vr'd| d| dt        |	       }| j                  |       n	d| d| d}Y d}	~	_d}	~	ww xY w)a*  
    Remove mapping of volume from cluster. If the either the volume or cluster
    do not exist, then there should be no mapping to unmap. If unmapping
    generates a key error with 'has no logical units' in its message, then
    the volume is not mapped.  Either case, return changed=False.
    Frd   r   r   TrV   z' was unmapped from cluster 're   rX   rf   rg   z' from cluster 'rE   r4   z' was not mapped to cluster 'rh   Nri   z' or cluster 'rj   rk   )
rG   r   r
   r#   r2   rl   rm   rI   r8   rn   )
r$   r:   r;   r5   r   r   rJ   rK   ro   rN   s
             r   ra   ra   v  s0    G
CFF+ff-mmH-}}Y/g
A/@$$V, -J<.Xghtguuvw $K=|nLxyC
g.  A)S91+>N|n\_`cdg`h_ijC$$$-$[M1N|n\  ACAs   +B 	C(!=C##C(c                     |j                         }|D ]G  }| j                         |j                  j                         k(  s/t        |j                        }|c S  t               S )z Get mapping fields )id)r   get_namer   dictrr   )r   host_or_clusterr/   r   
field_dicts        r   get_mapping_fieldsrw     s]    ##%D ??

 3 3 5566J  6Mr   c                 l   t        |       }t        | |      }t        | |      }t        | |      }| j                  d   }| j                  d   }| j                  d   }|s| j                  d| d       |s|sd| d| d	}| j                  |       |rt        ||      s7|rt        ||      s)|r
d| d
| d}n|r	d| d| d}| j                         |rS|rQt        ||      }	t        ||      }
|	d| d| d|	 d}t        d|	|      }nd| d
| d}| j                  |       ni|rS|rQt        ||      }	t        ||      }
|	d| d| d|	 d}t        d|	|      }n0d| d| d}| j                  |       nd}| j                  |       t        
      } | j                  di | y)z Return mapping stat r   r   r   rV   ' not foundr4   Neither host '' nor cluster '' foundrW   rX   z' is not mapped to cluster 'Nz' is mapped to host 'r@   F)r;   
volume_lunr5   z' is mapped to cluster 'z1A programming error has occurred in handle_stat() )r   r   r   r
   r#   r8   r   r   r0   rw   rt   r2   r   rn   )r$   r:   r   r   r   rJ   rT   rK   r5   r.   rv   results               r   handle_statr     s+   F'FFF#D&&)G--)Kf%I==+Lx}K@AykgNS!-fd;$<VW$M[M)B9+QOC[M)El^STUCS!	!$/	'5
 [M)>ykW`VaabcC$F [M)B9+QOC%	\$Wf5	'8
 [M)A,}]f\gghiC$F [M)El^STUC%AS!VZ0FFvr   c                    t        |       }t        | |      }t        | |      }t        | |      }| j                  d   }| j                  d   }| j                  d   }|s| j                  dd| d       |s$|s"|sd}|sd}| j                  dd	| d
| d       |rGt        ||      st        | |      }d| d| d}	nmt        | |      }t        ||      }
d| d| d|
 d}	nH|rFt        ||      st        | |      }d| d| d}	n$t        | |      }t        ||      }
d| d| d|
 d}	t        	      } | j                  di | y)z Create or update mapping r   r   r   FrV   ry   r;   r5   znot specifiedrz   r{   r|   z' map to host 'z	' createdz' already exists using lun 'rX   z' map to cluster 'Nr~   )r   r   r   r
   r#   r8   r   r<   r\   r0   r   r^   r2   rt   rn   )r$   r:   r   r   r   rJ   rT   rK   r;   r5   ro   r   s               r   handle_presentr     s   F'FFF#D&&)G--)Kf%I==+Lh{m;,OP'I*LnYKWcVddk,lm$VT2$VV4G[M9MC,VV<G(v6L[MC_`l_mmnoC	'8$VV4G[M);L>SC/?G+GV<L[M);L>IefresstuCF Fvr   c           
      B   t        |       }t        | |      }t        | |      }t        | |      }| j                  d   }| j                  d   }| j                  d   }|r|s |s| j                  dd| d| d| d	       yt        | |      }| j                  |d
	       y)z Remove mapping r   r   r   FzMapping of volume z	 to host z or cluster z already absentr   zMapping removedN)r   r   r   r
   r#   rn   rb   )	r$   r:   r   r   r   rJ   rT   rK   r;   s	            r   handle_absentr     s    F'FFF#D&&)G--)Kf%I==+L$w.@YW`Vaamnzm{  |K  -L  	M 0.?@r   c                 *   | j                   d   }	 |dk(  rt        |        n7|dk(  rt        |        n&|dk(  rt        |        n| j	                  d|        t        |       }|j                          y# t        |       }|j                          w xY w)z3Determine which state function to execute and do sostatestatpresentabsentz'Internal handler error. Invalid state: r4   N)r#   r   r   r   r8   r   logout)r$   r   r:   s      r   execute_stater     s    MM'"EF?i6"h&!#J5'!RSF# F#s   AA5 5Bc                     | j                   d   }| j                   d   }|r|rd}| j                  |       |s|sd}| j                  |       yyy)zVerify module options are saner   r   zCinfini_map requires a host or a cluster but not both to be providedr4   z6infini_map requires a host or a cluster to be providedN)r#   r8   )r$   rT   rK   r5   s       r   check_parametersr   ,  s[    f%I==+L\SS!\FS! *9r   c                  L   t               } | j                  t        t        dd      t        dd      t        dg d      t        d      t        d	
                   t        | d      }t        s|j                  t        d             t        |       t        |       y)z Main FN)requireddefaultr   )r   r   r   )r   choicesT)r   int)type)r   r   r   r   r   )supports_check_mode	infinisdkr4   )	r   updatert   r   r   r8   r   r   r   )argument_specr$   s     r   mainr   9  s    +-Mud3%6y2OP&% 	
 =dCF1+>?V&r   __main__N).__doc__
__future__r   r   r   r   __metaclass__DOCUMENTATIONEXAMPLESansible.module_utils.basicr   r   Fansible_collections.infinidat.infinibox.plugins.module_utils.infiniboxr   r	   r
   r   r   r   r   r   infinisdk.core.exceptionsr   ImportErrorr   r   r(   r+   r0   r2   r<   r7   r6   r\   r^   rb   r`   ra   rw   r   r   r   r   r   r   __name__r~   r   r   <module>r      sU   F
 C B*X$P K	 	 		:
    ,  8  8  ,  ,  (  /  /F !/ !/H	8v&RA "
", zF {  		s   B+ +B32B3