
    Vhc@                     l   d dl mZmZmZ eZdZdZdZd dl	Z	d dl
mZ d dlmZm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ZdZdZdZdZdZ dZ!dZ"dZ#dZ$dZ%g dZ&e&dgdgdZ'ddddZ(ddd Z)d!d"d#d$d%id&d'd(d)d*dZ*d+d,d-dZ+d. Z,d/ Z-d0 Z.d1 Z/d2 Z0d3 Z1d4 Z2d5 Z3d6 Z4d7 Z5e6d8k(  r e5        yy)9    )absolute_importdivisionprint_functiona	  
---
module: ome_devices
short_description: Perform device-specific operations on target devices
description: Perform device-specific operations such as refresh inventory, clear iDRAC job queue, and reset iDRAC from OpenManage Enterprise.
version_added: 6.1.0
extends_documentation_fragment:
  - dellemc.openmanage.oment_auth_options
options:
  device_service_tags:
    description:
      - Service tag of the target devices.
      - This is mutually exclusive with I(device_ids).
    type: list
    elements: str
  device_ids:
    description:
      - IDs of the target devices.
      - This is mutually exclusive with I(device_service_tags).
    type: list
    elements: int
  state:
    description:
      - C(present) Allows to perform the I(device_action) on the target devices.
      - "C(absent) Removes the device from OpenManage Enterprise. Job is not triggered. I(job_wait), I(job_schedule),
      I(job_name), and I(job_description) are not applicable to this operation."
    type: str
    choices: [present, absent]
    default: present
  device_action:
    description:
      - C(refresh_inventory) refreshes the inventory on the target devices.
      - C(reset_idrac) Triggers a reset on the target iDRACs.
      - C(clear_idrac_job_queue) Clears the job queue on the target iDRACs.
      - A job is triggered for each action.
    type: str
    choices: [refresh_inventory, reset_idrac, clear_idrac_job_queue]
    default: refresh_inventory
  job_wait:
    description:
      - Provides an option to wait for the job completion.
      - This option is applicable when I(state) is C(present).
      - This is applicable when I(job_schedule) is C(startnow).
    type: bool
    default: true
  job_wait_timeout:
    description:
      - The maximum wait time of I(job_wait) in seconds. The job is tracked only for this duration.
      - This option is applicable when I(job_wait) is C(true).
    type: int
    default: 1200
  job_schedule:
    description: Provide the cron string to schedule the job.
    type: str
    default: startnow
  job_name:
    description: Optional name for the job.
    type: str
  job_description:
    description: Optional description for the job.
    type: str
requirements:
  - "python >= 3.9.6"
author:
  - Jagadeesh N V(@jagadeeshnv)
  - ShivamSh3(@ShivamSh3)
notes:
  - For C(idrac_reset), the job triggers only the iDRAC reset operation and does not track the complete reset cycle.
  - Run this module from a system that has direct access to Dell OpenManage Enterprise.
  - This module supports C(check_mode).
a  
---
- name: Refresh Inventory
  dellemc.openmanage.ome_devices:
    hostname: "192.168.0.1"
    username: "username"
    password: "password"
    ca_path: "/path/to/ca_cert.pem"
    device_action: refresh_inventory
    device_service_tags:
      - SVCTAG1

- name: Clear iDRAC job queue
  dellemc.openmanage.ome_devices:
    hostname: "192.168.0.1"
    username: "username"
    password: "password"
    ca_path: "/path/to/ca_cert.pem"
    device_action: clear_idrac_job_queue
    device_service_tags:
      - SVCTAG1

- name: Reset iDRAC using the service tag
  dellemc.openmanage.ome_devices:
    hostname: "192.168.0.1"
    username: "username"
    password: "password"
    ca_path: "/path/to/ca_cert.pem"
    device_action: reset_idrac
    device_service_tags:
      - SVCTAG1

- name: Remove devices using servicetags
  dellemc.openmanage.ome_devices:
    hostname: "192.168.0.1"
    username: "username"
    password: "password"
    ca_path: "/path/to/ca_cert.pem"
    state: absent
    device_service_tags:
      - SVCTAG1
      - SVCTAF2

- name: Remove devices using IDs
  dellemc.openmanage.ome_devices:
    hostname: "192.168.0.1"
    username: "username"
    password: "password"
    ca_path: "/path/to/ca_cert.pem"
    state: absent
    device_ids:
      - 10235
aH	  
---
msg:
  type: str
  description: Overall status of the devices operation.
  returned: always
  sample: "Successfully removed the device(s)."
job:
  type: dict
  description: Job details of the devices operation.
  returned: success
  sample: {
    "Id": 14874,
    "JobName": "Refresh inventory",
    "JobDescription": "The Refresh inventory task initiated from OpenManage Ansible Modules for devices with the ids '13216'.",
    "Schedule": "startnow",
    "State": "Enabled",
    "CreatedBy": "admin",
    "UpdatedBy": null,
    "Visible": true,
    "Editable": true,
    "Builtin": false,
    "UserGenerated": true,
    "Targets": [
        {
            "JobId": 14874,
            "Id": 13216,
            "Data": "",
            "TargetType": {
                "Id": 1000,
                "Name": "DEVICE"
            }
        }
    ],
    "Params": [
        {
            "JobId": 14874,
            "Key": "action",
            "Value": "CONFIG_INVENTORY"
        },
        {
            "JobId": 14874,
            "Key": "isCollectDriverInventory",
            "Value": "true"
        }
    ],
    "LastRunStatus": {
        "@odata.type": "#JobService.JobStatus",
        "Id": 2060,
        "Name": "Completed"
    },
    "JobType": {
        "@odata.type": "#JobService.JobType",
        "Id": 8,
        "Name": "Inventory_Task",
        "Internal": false
    },
    "JobStatus": {
        "@odata.type": "#JobService.JobStatus",
        "Id": 2020,
        "Name": "Scheduled"
    },
    "ExecutionHistories@odata.navigationLink": "/api/JobService/Jobs(14874)/ExecutionHistories",
    "LastExecutionDetail": {
        "@odata.id": "/api/JobService/Jobs(14874)/LastExecutionDetail"
    }
}
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": "CGEN1002",
                "RelatedProperties": [],
                "Message": "Unable to complete the operation because the requested URI is invalid.",
                "MessageArgs": [],
                "Severity": "Critical",
                "Resolution": "Enter a valid URI and retry the operation."
            }
        ]
    }
}
N)SSLError)URLError	HTTPError)ConnectionError)RestOMEOmeAnsibleModule)strip_substr_dictjob_tracking)CHANGES_MSGNO_CHANGES_MSGzDeviceService/DeviceszJobService/JobszJobService/Jobs({job_id})z%JobService/Actions/JobService.RunJobsz-JobService/Jobs({job_id})/LastExecutionDetailz1DeviceService/Actions/DeviceService.RemoveDevicesz(The devices(s) are removed successfully.zXUnable to complete the operation because the entered target device(s) '{0}' are invalid.zVThe {0} task initiated from OpenManage Ansible Modules for devices with the ids '{1}'.z-Successfully initiated the device action job.z"The job is scheduled successfully.z/The device operation is performed successfully.zBThe parameter `job_wait_timeout` value cannot be negative or zero.)  i  i  i  iX  i@  i)#  r   refresh_inventoryreset_idracclear_idrac_job_queue      DeviceAction_TaskInventory_Task)r   r   CONFIG_INVENTORYtrue)actionisCollectDriverInventoryoperationNameRESET_IDRACREMOTE_RACADM_EXECz%jobqueue delete -i JID_CLEARALL_FORCE601000)r   CommandCommandTimeoutdeviceTypeszRefresh inventoryzReset iDRACzClear iDRAC job queuec           
      >   t               }| j                  j                  d      }d}d}|s| j                  j                  d      }d}d}g }|D ]  }|j                  dt        d|j                  ||      i	      }	|	j                  j                  d
      }
|
s|j                  |       |
D ]6  }||   |k(  s|d   |v r|j                  |
       n|j                  |         |j                  |        |D cg c]  }|j                  d       }}||fS c c}w )N
device_idsz
{0} eq {1}Iddevice_service_tagsz{0} eq '{1}'
IdentifierGET$filterquery_paramvalueType)	setparamsgetinvoke_request
DEVICE_URIformat	json_dataaddextend)modulerest_objtypesinvalidsstsparamsrchdevsstrespvalvdvvalidss                 r/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/dellemc/openmanage/plugins/modules/ome_devices.pyget_dev_idsrH     s(   uH
--

L
)CEDmm 56D &&ujyRWR^R^_cegRhFi&jnn  )LL 	Aw"}V9%KK$LL$	 LL (,,rvvd|,F,8 -s   <Dc                     | j                   r| j                  t        d       dt        |      i}|j	                  dt
        |       | j                  t        d       y )NTmsgchanged	DeviceIdsPOSTdata)
check_mode	exit_jsonr   listr3   DELETE_DEVICES_URIDELETE_SUCCESS)r9   r:   	valid_idspayloads       rG   delete_devicesrX   '  sU    [$7DO,GF$6WE
6    c           	         | j                   j                  d      |d<   | j                   j                  d      r| j                   j                  d      |d<   nt        j                  |      |d<   | j                   j                  d      r| j                   j                  d      |d<   y t        j	                  t        j                  |      dj                  t        t        |                  |d<   y )Njob_scheduleSchedulejob_nameJobNamejob_descriptionJobDescription,)r1   r2   jobname_mapJOB_DESCr5   joinmapstr)r9   rW   taskrV   s       rG   update_common_jobrh   /  s     --++N;GJ}}$#]]..z:	(__T2	}}*+$*MM$5$56G$H !$,OOKOOD4I388TWX[]fTgKh$i !rY   c                    ddj                  |d         i}| j                  dt        |      }|j                  j	                  dg       }|D ]  }|d   |d   k(  s|d   |d   k(  s|d	   |d	   k(  s't        d
 |j	                  d      D              }||j	                  d      k(  s]t        d |j	                  d      D              }||j	                  d      k(  s|c S  i S )Nr+   zJobType/Id eq {0}JobTyper*   r,   r.   r^   r`   r\   c              3   `   K   | ]&  }|j                  d       |j                  d      f ( yw)KeyValueNr2   ).0ks     rG   	<genexpr>z$check_similar_job.<locals>.<genexpr>B  s%     SQ155<w8Ss   ,.Paramsc              3   ~   K   | ]5  }|j                  d       |j                  d      j                  d      f 7 yw)r'   
TargetTypeNameNrn   )ro   ts     rG   rq   z$check_similar_job.<locals>.<genexpr>E  s1     cA!%%+quu\':'>'>v'FGcs   ;=Targets)r5   r3   JOBS_URIr6   r2   dict)r:   rW   r-   job_respjob_listjbjb_prmtrgtss           rG   check_similar_jobr   ;  s    1889KLMK&&uhK&PH!!%%gr2H 	i=GI..26F3G7ScKd3d:'*"55S"&&BRSSFW[[22cQSQWQWXaQbccEGKK	22I	 IrY   c                    | j                   }|j                  d      dk7  r!| j                  dt        t	        |             | j                   j                  d      s"| j                  dt
        t	        |             y t        }t        |t        j                  |d         | j                   j                  d      d	
      \  }}}}|rW	 |j                  dt        j                  |d               }	|	j                  j                  d      }|j                  dd      }| j                  ||t	        |      d       y # t        $ r |}Y ,w xY w)Nr[   startnowT)rL   rK   jobjob_waitr'   )job_idjob_wait_timeoutr   )max_job_wait_secinitial_waitr*   rm   
 )failedrK   r   rL   )r1   r2   rR   JOB_SCHEDULEDr   APPLY_TRIGGEREDSUCCESS_MSGr   JOB_URIr5   r3   	LAST_EXECr6   replace	Exception)
r9   r:   r   mparamsjob_msg
job_failedrK   job_dict	wait_timerz   s
             rG   r   r   L  s4   mmG{{>"j0=>OPS>TU==Z(?@QRU@VW/;gnnCIn6IZIZ[mIn0,
C9 #225):J:JRUVZR[:J:\]((,,W5++dC0 	
=Ns=S]ab  s   AE EEc                     i }|j                  dt        j                  | d      i       |j                  dt        j                  | i       i       |S )Nrj   r   rr   )updatejob_type_mapr2   job_params_map)rg   taskloads     rG   get_task_payloadr   a  sH    HOOY 0 0q 9:;OOX~11$;<=OrY   c                 X    t        |       }t        d |D              }||d<   |dt        fS )Nc              3   $   K   | ]  }|d f 
 yw)DEVICEN )ro   rE   s     rG   rq   z%get_payload_method.<locals>.<genexpr>j  s     6bB>6s   rw   rN   )r   ry   rx   )rg   rV   rW   targetss       rG   get_payload_methodr   h  s3    t$G6I66G GIFH$$rY   c           	      0   d| d<   d| d<   | d   }|j                         D cg c]
  \  }}||d c}}| d<   | d   }|j                         D cg c]  \  }}|dd	|d
d c}}| d<   | d   }|t        j                  |      d
| d<   y c c}}w c c}}w )Nr   r'   EnabledStaterr   )rl   rm   rw    r   )r'   ru   )r'   Datart   rj   )items	jtype_mapr2   )rW   prmsrp   rD   r~   jtypes         rG   formalize_job_payloadr   o  s    GDM GG8D>BjjlKda!a0KGHIEejepepers]a]^`a!RdTU?VWsGIIE %y}}U/CDGI	 Lss   BBc                 ~   | j                   j                  d      }t        ||      \  }}}t        | |||       t	        ||      }|s_t        |       | j                  r| j                  t        d       |j                  dt        |d      }t        | ||j                         y | j                   j                  d      dk(  rY|d	   d
   dk7  rN| j                  r| j                  t        d       |j                  dt        d|d
   gi      }t        | ||       | j                  t        t        |             y )Ndevice_actionTrJ   rN   <   )rP   api_timeoutr[   r   LastRunStatusr'   i  JobIdsrO   )rK   r   )r1   r2   r   rh   r   r   rQ   rR   r   r3   rx   r   r6   RUN_JOB_URIr   r   )	r9   r:   rV   rg   rW   methodurir   rB   s	            rG   perform_device_tasksr   z  s%   ==_-D-dI>GVSfgtY7
Hg
.Cg&d;&&vxgSU&V4>>2==^,
:s??STX?Y]a?a    [$ ?**6;hQTUYQZP[E\*]DVXs+^1B31GHrY   c                     dddddddddgdddg dd	dd
ddddddddddiddid	} t        | g dgdgd      }	 |j                  j                  d      r5|j                  j                  d      dk  r|j                  t        d       t        |j                  d      5 }|j                  j                  d      dk(  rt        ||t        j                  |j                  j                  d                  \  }}|rC|j                  dt        j                  dj                  t        t        |                         t        |||       n9t        ||t              \  }}|s|j                  t               t!        |||       d d d        y # 1 sw Y   y xY w# t"        $ r:}|j                  t        |      t%        j&                  |      d       Y d }~y d }~wt(        $ r&}|j                  t        |      d       Y d }~y d }~wt*        t,        t.        t0        t2        t4        t6        t8        t:        f	$ r&}|j                  t        |      d       Y d }~y d }~ww xY w)NrS   rf   )typeelementsintpresentabsent)r   choicesdefaultr   r   boolT)r   r   i  r   r   )	r(   r&   stater   r   r   r[   r]   r_   )r(   r&   )argument_specrequired_ifmutually_exclusiverequired_one_ofsupports_check_moder   r   r   )rK   r   )req_sessionr   r   ra   )r   rK   )rK   )rK   
error_infor   )rK   unreachable)r   r1   r2   rR   TIMEOUT_NEGATIVE_MSGr
   rH   device_type_mapINVALID_DEV_STr5   rd   re   rf   r   all_device_typesr   rX   r   jsonloadr   IOError
ValueErrorr   	TypeErrorr	   AttributeError
IndexErrorKeyErrorOSError)specsr9   r:   rF   r<   errs         rG   mainr     s:   (.EB%59Y,AiX"'4q%8:#5%*t<!&:>UO"E?E 1
 ?? F4==Z(V]]->->?Q-RVW-W!5dCV]]5 	9}}  )Y6#.vx/>/B/B6==CTCTUdCe/f$h $$Dn6K6KCHHUXY\^fUgLh6i$j$VXv>#.vxAQ#R $$$8vx8	9 	9 	9  OSX$))C.NN 9SX488Z9o~Wack 4SXd334sO   A'F" &C'FF" FF" F" "	I(+0G  I(,H5I(I##I(__main__)7
__future__r   r   r   r   __metaclass__DOCUMENTATIONEXAMPLESRETURNr   sslr   +ansible.module_utils.six.moves.urllib.errorr   r   ansible.module_utils.urlsr	   ?ansible_collections.dellemc.openmanage.plugins.module_utils.omer
   r   Aansible_collections.dellemc.openmanage.plugins.module_utils.utilsr   r   r   r   r4   rx   r   r   r   rT   rU   r   rc   r   r   r   r   r   r   r   r   r   rb   rH   rX   rh   r   r   r   r   r   r   r   __name__r   rY   rG   <module>r      sB   C BFP4lW
r   K 5 e m i$

%5;	H ;kcA4?[ = (8$kojpq%&qSTU#(89	2DDJ(L"1=!A=Q7^>BSY,[\ %8(?A87	j"c*%EI(-4` zF rY   