
    VhuI                         d dl mZmZmZ eZdZdZdZd dl	Z	d dl
Z
d dlZd dlmZ d dlmZmZ d dlmZmZ d d	lmZmZ d
ZdZdddd dZdddZdZd ZdZd Zd ZddZ d Z!d Z"d Z#d Z$d Z%e&dk(  r e%        yy)    )absolute_importdivisionprint_functiona  
---
module: idrac_user
short_description: Configure settings for user accounts
version_added: "2.1.0"
description:
  - This module allows to perform the following,
  - Add a new user account.
  - Edit a user account.
  - Enable or Disable a user account.
extends_documentation_fragment:
  - dellemc.openmanage.idrac_x_auth_options
options:
  state:
    type: str
    description:
      - Select C(present) to create or modify a user account.
      - Select C(absent) to remove a user account.
    choices: [present, absent]
    default: present
  user_name:
    type: str
    required: true
    description: Provide the I(user_name) of the account to be created, deleted or modified.
  user_password:
    type: str
    description:
      - Provide the password for the user account. The password can be changed when the user account is modified.
      - To ensure security, the I(user_password) must be at least eight characters long and must contain
        lowercase and upper-case characters, numbers, and special characters.
  new_user_name:
    type: str
    description: Provide the I(user_name) for the account to be modified.
  privilege:
    type: str
    description:
      - Following are the role-based privileges.
      - A user with C(Administrator) privilege can log in to iDRAC, and then configure iDRAC, configure users,
        clear logs, control and configure system, access virtual console, access virtual media, test alerts,
        and execute debug commands.
      - A user with C(Operator) privilege can log in to iDRAC, and then configure iDRAC, control and configure system,
        access virtual console, access virtual media, and execute debug commands.
      - A user with C(ReadOnly) privilege can only log in to iDRAC.
      - A user with C(None), no privileges assigned.
      - Will be ignored, if custom_privilege parameter is provided.
    choices: [Administrator, ReadOnly, Operator, None]
  custom_privilege:
    type: int
    description:
      - The privilege level assigned to the user.
    version_added: "8.1.0"
  ipmi_lan_privilege:
    type: str
    description: The Intelligent Platform Management Interface LAN privilege level assigned to the user.
    choices: [Administrator, Operator, User, No Access]
  ipmi_serial_privilege:
    type: str
    description:
      - The Intelligent Platform Management Interface Serial Port privilege level assigned to the user.
      - This option is only applicable for rack and tower servers.
    choices: [Administrator, Operator, User, No Access]
  enable:
    type: bool
    description: Provide the option to enable or disable a user from logging in to iDRAC.
  sol_enable:
    type: bool
    description: Enables Serial Over Lan (SOL) for an iDRAC user.
  protocol_enable:
    type: bool
    description: Enables protocol for the iDRAC user.
  authentication_protocol:
    type: str
    description:
      - This option allows to configure one of the following authentication protocol
        types to authenticate the iDRAC user.
      - Secure Hash Algorithm C(SHA).
      - Message Digest 5 C(MD5).
      - An authentication protocol is not configured if C(None) is selected.
    choices: [None, SHA, MD5]
  privacy_protocol:
    type: str
    description:
      - This option allows to configure one of the following privacy encryption protocols for the iDRAC user.
      - Data Encryption Standard C(DES).
      - Advanced Encryption Standard C(AES).
      - A privacy protocol is not configured if C(None) is selected.
    choices: [None, DES, AES]
requirements:
  - "python >= 3.9.6"
author: "Felix Stephen (@felixs88)"
notes:
    - Run this module from a system that has direct access to Dell iDRAC.
    - This module supports C(check_mode).
a2  
---
- name: Configure a new iDRAC user
  dellemc.openmanage.idrac_user:
    idrac_ip: 198.162.0.1
    idrac_user: idrac_user
    idrac_password: idrac_password
    ca_path: "/path/to/ca_cert.pem"
    state: present
    user_name: user_name
    user_password: user_password
    privilege: Administrator
    ipmi_lan_privilege: Administrator
    ipmi_serial_privilege: Administrator
    enable: true
    sol_enable: true
    protocol_enable: true
    authentication_protocol: SHA
    privacy_protocol: AES

- name: Modify existing iDRAC user username and password
  dellemc.openmanage.idrac_user:
    idrac_ip: 198.162.0.1
    idrac_user: idrac_user
    idrac_password: idrac_password
    ca_path: "/path/to/ca_cert.pem"
    state: present
    user_name: user_name
    new_user_name: new_user_name
    user_password: user_password

- name: Delete existing iDRAC user account
  dellemc.openmanage.idrac_user:
    idrac_ip: 198.162.0.1
    idrac_user: idrac_user
    idrac_password: idrac_password
    ca_path: "/path/to/ca_cert.pem"
    state: absent
    user_name: user_name
a  
---
msg:
  description: Status of the iDRAC user configuration.
  returned: always
  type: str
  sample: "Successfully created user account details."
status:
  description: Configures the iDRAC users attributes.
  returned: success
  type: dict
  sample: {
    "@Message.ExtendedInfo": [{
      "Message": "Successfully Completed Request",
      "MessageArgs": [],
      "MessageArgs@odata.count": 0,
      "MessageId": "Base.1.5.Success",
      "RelatedProperties": [],
      "RelatedProperties@odata.count": 0,
      "Resolution": "None",
      "Severity": "OK"
      }, {
      "Message": "The operation successfully completed.",
      "MessageArgs": [],
      "MessageArgs@odata.count": 0,
      "MessageId": "IDRAC.2.1.SYS413",
      "RelatedProperties": [],
      "RelatedProperties@odata.count": 0,
      "Resolution": "No response action is required.",
      "Severity": "Informational"}
      ]}
error_info:
  description: Details of the HTTP Error.
  returned: on HTTP error
  type: dict
  sample: {
    "error": {
      "code": "Base.1.0.GeneralError",
      "message": "A general error has occurred. See ExtendedInfo for more information.",
      "@Message.ExtendedInfo": [
        {
          "MessageId": "GEN1234",
          "RelatedProperties": [],
          "Message": "Unable to process the request because an error occurred.",
          "MessageArgs": [],
          "Severity": "Critical",
          "Resolution": "Retry the operation. If the issue persists, contact your system administrator."
        }
      ]
    }
  }
N)SSLError)URLError	HTTPError)ConnectionErrorSSLValidationError)iDRACRedfishAPIIdracAnsibleModulez//redfish/v1/Managers/iDRAC.Embedded.1/Accounts/z1/redfish/v1/Managers/iDRAC.Embedded.1/Attributes/i  i     )AdministratorOperatorReadOnlyNoneDisabledEnabled)r   r   z/custom_privilege value should be from 0 to 511.c           	      V   | j                         }t        |      j                         D ]7  \  }}|j                  d      d   }|dk(  rd} |S |dk(  s*t	        |      ||<   9 t        t        t        |j                               t        |j                               z
              }|S )a/  
    :param json_payload: json payload created for update operation
    :param idrac_attr: idrac user attributes
    case1: always skip password for difference
    case2: as idrac_attr returns privilege in the format of string so
    convert payload to string only for comparision
    :return: bool
    #r   PasswordT	Privilege)copydictitemssplitstrboollistset)json_payload
idrac_attr	copy_jsonkeyval	split_keyis_change_requireds          q/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/dellemc/openmanage/plugins/modules/idrac_user.pycompare_payloadr(      s     !!#IO))+ ZSIIcN1%	
"!%
 	 # XIcNZ "$s9??+<'=JDTDTDV@W'W"XY    c                    d\  }}}}| j                   d   s| j                  d       |j                  dddd	      }|j                  |j                  d
      }t        t        dd            }|D ]w  }	dj                  |	      }
|j                  |
      | j                   d   k(  r|	}t        t        |	      z   } n/|j                  |
      r]|xr |d|	}t        t        |	      z   }y |||||fS )z
    This function gets the slot id and slot uri for create and modify.
    :param module: ansible module arguments
    :param idrac: idrac objects
    :return: user_attr, slot_uri, slot_id, empty_slot, empty_slot_uri
    )NNNN	user_namezUser name is not valid.msgJSONDefaultIDRACT)export_format
export_usetargetjob_waitziDRAC.Embedded.1)fqdd      zUsers.{0}#UserName)params	fail_json
export_scpget_idrac_local_account_attr	json_datatuplerangeformatgetACCOUNT_URIr   )moduleidracslot_urislot_id
empty_slotempty_slot_uriresponseuser_attributesslot_numnumr+   s              r'   get_user_accountrL      s    5K1Hgz>==%67fSZeijH889K9KRd8eOU1b\"H 4(//4	y)V]];-GGG"SX-H""9->3Pj2YJ(3s83N4 Hgz>IIr)   c                 P   d| j                   v r| j                   d   | j                   d   n!t        j                  | j                   d         }| j                   d   | j                   d   t        j                  | j                   d         || j                   d   | j                   d   t        j                  | j                   d         t        j                  | j                   d	         | j                   d
   | j                   d   d
}| j                   d   )|dk(  r$dj	                  |      }| j                   d   ||<   n| j                   d   dk(  rdddddddddd	}t        |j                         D cg c]  \  }}|	|j	                  |      |f c}}      }|S c c}}w )a  
    This function creates the payload with slot id.
    :param module: ansible module arguments
    :param action: new user name is only applicable in case of update user name.
    :param slot_id: slot id for user slot
    :return: json data with slot id
    custom_privilege	privileger+   user_passwordenableipmi_lan_privilegeipmi_serial_privilege
sol_enableprotocol_enableauthentication_protocolprivacy_protocol)
Users.{0}.UserNamezUsers.{0}.PasswordUsers.{0}.EnableUsers.{0}.PrivilegeUsers.{0}.IpmiLanPrivilegeUsers.{0}.IpmiSerialPrivilegeUsers.{0}.SolEnableUsers.{0}.ProtocolEnable Users.{0}.AuthenticationProtocolUsers.{0}.PrivacyProtocolnew_user_nameupdaterX   stateabsent r   r   	No AccessSHAAES)	rX   rY   rZ   r[   r\   r]   r^   r_   r`   )r8   
USER_ROLESr@   ACCESSr?   r   r   )	rB   rE   actionuser_privilegeslot_payloadr+   kvpayloads	            r'   get_payloadrq     s    ;MPVP]P]:]()5 ]]#56;E>>&--XcJd;e  +1--*D*0--*H(.

6==3J(K+928--@T2U5;]]CZ5[+1::fmmL6Q+R06

6==IZ;[0\8>F_8`17?Q1R	VL }}_%1f6H(//8	"(--"@Y	w	8	+.0jij6Ado/9Wa<A`eg |7I7I7K]tq!q}QXXg&*]^GN ^s   8
F"
F"
c                     d}d}i }| j                         D ]6  \  }}t        j                  dd|      }|dj                  ||      z  }|||<   8 |j                  |      }||fS )z
    this function converts payload to xml and json data.
    :param payload: user input for payload
    :return: returns xml and json data
    z]<SystemConfiguration><Component FQDD="iDRAC.Embedded.1">{0}</Component></SystemConfiguration>re   z	(?<=\d)\.r   z%<Attribute Name="{0}">{1}</Attribute>)r   resubr?   )rp   rootattrr    rn   ro   r#   s          r'   convert_payload_xmlrw   /  s|     oDDL 1ff\3*7>>sAFFS ;;tDr)   c                 H   |j                   }|d   }di }
}	|xr ||xr |d}	t        | |d      }| j                  r| j                  dd       |d	k\  r|j	                  t
        d
d|i      }
|
|	fS |d	k  r7t        |      \  }}t        j                  d       |j                  |dd      }
|
|	fS |xr |d}	t        | |d      }t        |      \  }}t        ||      }| j                  r'|r| j                  dd       | j                  d       |s| j                  d       |d	k\  r|j	                  t
        d
d|i      }
|
|	fS |d	k  r)t        j                  d       |j                  |dd      }
|
|	fS |xr
 |xr |xr || j                  d       |
|	fS )ah  
    This function create user account in case not exists else update it.
    :param module: user account module arguments
    :param idrac: idrac object
    :param slot_uri: slot uri for update
    :param slot_id: slot id for update
    :param empty_slot_id: empty slot id for create
    :param empty_slot_uri: empty slot uri for create
    :return: json
    r   z$Unable to retrieve the user details.z"Successfully created user account.createrk   Changes found to commit!Tr-   changed   PATCH
Attributes)data
   ALLimport_bufferr3   r4   z"Successfully updated user account.rb   No changes found to commit!r,   z7Requested changes are already present in the user slot.zOMaximum number of users reached. Delete a user account and retry the operation.)get_server_generationrq   
check_mode	exit_jsoninvoke_requestATTRIBUTE_URIrw   timesleep
import_scpr(   r9   )rB   rC   rD   rE   empty_slot_idrG   	user_attrgen_details
generationr-   rH   rp   xml_payloadr    values                  r'   create_or_modify_accountr   @  s    --KQJ:BCH%=+K^*X2fmHE!;TJ++M7,X_I`+aH. S=- "_(;G(D%KJJrN''k%Z^'_H& S=% 
h	+2fgh?$7$@!\i8  %? N!>?!Z[++M7,X_I`+aH S= "_JJrN''k%Z^'_H S= 
Ch
C=
C^	LnoS=r)   c                    i d}}t        | |d      }t        |      \  }}| j                  r|xr || j                  dd       ||fS | j                  r|xr || j                  d       ||fS | j                  s3|xr |-t	        j
                  d	       |j                  |d
d      }||fS | j                  d       ||fS )z
    remove user user account by passing empty payload details.
    :param module: user account module arguments.
    :param idrac: idrac object.
    :param slot_uri: user slot uri.
    :param slot_id: user slot id.
    :return: json.
    z"Successfully deleted user account.deleterz   r{   Tr|   r   r,   r   r   r   zThe user account is absent.)rq   rw   r   r   r   r   r   )	rB   rC   rD   rE   rH   r-   rp   r   r    s	            r'   remove_user_accountr   n  s     <cH&'(;G 3G <Kg2(?7F S= 
		 4W=:; S= H$8#E

2##+eVZ#[ S= 	:;S=r)   c                    | j                   d   dk(  ryd| j                   v r| j                   d   | j                   d   n"t        j                  | j                   d   d      }t        |kD  s	|t        kD  r| j                  t               y y y )Nrc   presentrN   rO   r   r,   )r8   ri   r@   INVALID_PRIVILAGE_MININVALID_PRIVILAGE_MAXr9   INVALID_PRIVILAGE_MSG)rB   rl   s     r'   validate_inputr     s    }}W*>PTZTaTa>aMM,-9  '9:?I~~fmm\gNhjk?l 	 >1^F[5[!67 6\ +r)   c                     dddgddddiddiddddg dd	dd
ddg dd	dg dd	ddddddddddg dd	dg dd	d} t        | d      }	 t        |       t        |j                  d      5 }t	        ||      \  }}}}}|j                  d   dk(  rt        |||||||      \  }}	n#|j                  d   dk(  rt        ||||      \  }}	j                  j                  d      }
|j                  j                  d      }|rE|j                  d      j                  d      }ddg}||v r|j                  ||j                         |
r,|j                  |
j                  d      |j                         |j                  	|j                  d       d d d        y # 1 sw Y   y xY w# t        $ r9}|j                  t        |      t        j                  |             Y d }~y d }~wt        $ r&}|j                  t        |      d       Y d }~y d }~wt         t"        t$        t&        t(        t*        t,        t.        f$ r%}|j                  t        |             Y d }~y d }~ww xY w)NFr   rd   )requiredchoicesdefaultr   T)r   no_log)r   r   r   r   )r   r   int)r   type)r   r   Userrf   r   )rg   MD5r   )rh   DESr   )rc   ra   r+   rP   rO   rN   rR   rS   rQ   rT   rU   rV   rW   )argument_specsupports_check_mode)req_sessionrc   errorOemDellMessagez?Unable to complete application of configuration profile values.zGImport of Server Configuration Profile operation completed with errors.)r-   
error_infomessage)r-   statusr}   )r-   unreachabler,   )r   r   r   r8   rL   r   r   r<   r@   r9   r   r   r   jsonloadr   RuntimeErrorr
   r	   KeyErrorImportError
ValueError	TypeErrorr   )specsrB   rC   r   rD   rE   r   rG   rH   r   r   oemoem_msg	error_msgerres                   r'   mainr     s{   #H0ER[\$e, $'&+t<"'4ef).>+0=op.3@r!s$f5#(&9(-v>05BX#Y).;QRE   "F%vV]]= 	SJZ[achJiGIx-}}W%2$<VUHV]_l=KY%X!'w'83$7xQX$Y!'&&**73E$$((/C''&/--i8^fh	i'$$X=O=O$P  UYYy%9hFXFX Y1C1CTR#	S 	S 	S$  BSX$))C.AA 9SX488,oxY: %SV$$%sO   "F. 3D&F"F. "F+'F. +F. .	I-7/G++I-7H0I-I((I-__main__)N)'
__future__r   r   r   r   __metaclass__DOCUMENTATIONEXAMPLESRETURNr   rs   r   sslr   +ansible.module_utils.six.moves.urllib.errorr   r   ansible.module_utils.urlsr	   r
   Iansible_collections.dellemc.openmanage.plugins.module_utils.idrac_redfishr   r   rA   r   ri   rj   r   r   r   r(   rL   rq   rw   r   r   r   r   __name__ r)   r'   <module>r      s    C B]~'R3
l  	   K I y?C"AN
I	&I   ,J2B"+\08-%` zF r)   