CimTrak

The CimTrak integration helps you detect unexpected system/device/config modifications and automatically respond/react to threats.

Forensics & Malware Analysis · CimTrak - System Integrity Assurance

Details

IDCimTrak
ProviderCimcor Inc
CategoryForensics & Malware Analysis
From Version6.0.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix XSIAM

README

CimTrak XSOAR integration.

Configure CimTrak on Cortex XSOAR

  • Fill in the URL to your App Server
  • Create an API Key in the CimTrak Management Console and populate in XSOAR
  • Fill in the Repository IP relative to the App Server (IE: If App Server is running on the same machine as the Repository you can use 127.0.0.1)
  • Fill in Repository Port
  • Once configured all unreconciled items from CimTrak will be brought into XSOAR.

Commands

get-events

Input

Argument Name Description Required
Start number Starting number of record to get
End number Ending number of record to get
Filter json Filter array to limit results IE: [{name: id, operator:>, value:5}]
Sorts json Sort array to sort data IE: [{field: id, descending: False}]

Context Output

Path Type Description
CimTrak.Event.id number Event ID
CimTrak.Event.leventid number Event ID
CimTrak.Event.lagentid number Agent ID
CimTrak.Event.lobjectid number Object ID
CimTrak.Event.lobjectdetailid number Object Detail ID
CimTrak.Event.lobjectdetailidint number Object Detail Intrusion ID
CimTrak.Event.lmessagelevel number Message Level
CimTrak.Event.szuser string User
CimTrak.Event.szfileuser string File User
CimTrak.Event.szmessageid string Message ID
CimTrak.Event.szmessage string Message
CimTrak.Event.szfile string File
CimTrak.Event.szcorrectionid string Correction ID
CimTrak.Event.szcorrection string Correction
CimTrak.Event.lcategory number Category
CimTrak.Event.lemailsent number Email Sent
CimTrak.Event.lstoragestatus number Storage Status
CimTrak.Event.dtmdatetime1 string Date Time 1
CimTrak.Event.dtmdatetime2 string Date Time 2
CimTrak.Event.szchecksum string Checksum
CimTrak.Event.status string Status
CimTrak.Event.lprocessid number Process ID
CimTrak.Event.lthreadid number Thread ID
CimTrak.Event.szprocess string Process
CimTrak.Event.szforensicdata string Forensic Data
CimTrak.Event.dtmdeleted string Deteled Date Time
CimTrak.Event.ltickcount number Tick Count
CimTrak.Event.lsubtype number SubType
CimTrak.Event.ticketNumber string Ticket Number
CimTrak.Event.ldeleteobjectdetailid number Deleted Object Detail ID
CimTrak.Event.bfoundinblacklist number Found In Blacklist
CimTrak.Event.filecontenthash string File Content Hash
CimTrak.Event.lobjectsettingid number Object Setting ID
CimTrak.Event.reconciled number Reconciled
CimTrak.Event.isauthcopy number Is Auth Copy
CimTrak.Event.externalticketnumber string External Ticket Number
CimTrak.Event.lparentid number Parent ID
CimTrak.Event.szobjectpath string Object Path
CimTrak.Event.dfilesize number File Size

file-analysis-by-hash

Input

Argument Name Description Required
Hash string Hash of file to check

Context Output

Path Type Description
CimTrak.FileAnalysis.analysisEngine string Analysis Engine used
CimTrak.FileAnalysis.analysisSuccess boolean Analysis Success Flag
CimTrak.FileAnalysis.analysisResults string Agent ID

file-analysis-by-objectdetail-id

Input

Argument Name Description Required
ObjectDetailId number Object Detail Id of file to check

Context Output

Path Type Description
CimTrak.FileAnalysis.analysisEngine string Analysis Engine used
CimTrak.FileAnalysis.analysisSuccess boolean Analysis Success Flag
CimTrak.FileAnalysis.analysisResults string Agent ID

check-file-against-trusted-file-registry-by-hash

Input

Argument Name Description Required
Hashes list Array of hashes of file to check IE:B47DD22BFE1E5554448262D0C8E6555496B1AA6685AF50F49A12AD82D1109769,D2B3289F12102506717E2A1FB883F62E7DCE09FBDA48BE192905669684E68FD0

Context Output

Path Type Description
CimTrak.TrustedFileRegistry.hash string Hash found in registry

promote-authoritative-baseline-files

Input

Argument Name Description Required
ObjectDetaildIds list Array of object detail IDs of file to check IE:42,43

Context Output

Path Type Description
CimTrak.AuthoritizeBaseline.objectDetailId number objectDetailId of file
CimTrak.AuthoritizeBaseline.status string Status
CimTrak.AuthoritizeBaseline.errorCode string Error Code
CimTrak.AuthoritizeBaseline.errorDescription string Status

demote-authoritative-baseline-files

Input

Argument Name Description Required
ObjectDetaildIds list Array of object detail IDs of file to check IE:42,43

Context Output

Path Type Description
CimTrak.AuthoritizeBaseline.objectDetailId number objectDetailId of file
CimTrak.AuthoritizeBaseline.status string Status

update-task-disposition

Input

Argument Name Description Required
taskId number Task ID
Disposition string Disposition of task

Context Output

Path Type Description
CimTrak.TaskDisposition.taskId number Task Id
CimTrak.TaskDisposition.status string Status

get-tickets

Input

| Argument Name | Description | Required |
| — | — | — |

Context Output

Path Type Description
CimTrak.Ticket.id number Ticket Id
CimTrak.Ticket.ticketNumber string Ticket number
CimTrak.Ticket.sentiment string Ticket sentiment
CimTrak.Ticket.sentimenttypeid string Ticket sentiment id
CimTrak.Ticket.title string Ticket title
CimTrak.Ticket.description string Ticket description
CimTrak.Ticket.priority number Ticket priority
CimTrak.Ticket.disposition string Ticket disposition
CimTrak.Ticket.creationDate string Ticket creation date
CimTrak.Ticket.createdByUser string Ticket created by user
CimTrak.Ticket.modificationDate string Ticket modification date
CimTrak.Ticket.modifiedByUser string Ticket modified by user
CimTrak.Ticket.requiresAcknowledgement boolean Ticket requires acknowledgement
CimTrak.Ticket.requiresConfirmation boolean Ticket requires confirmation
CimTrak.Ticket.requiresAssessment boolean Ticket requires assessment
CimTrak.Ticket.startDate string Ticket start date
CimTrak.Ticket.endDate string Ticket end date
CimTrak.Ticket.autoPromote boolean Ticket auto promote
CimTrak.Ticket.assignedToUserId number Ticket assigned yo UserId
CimTrak.Ticket.assignedToUser string Ticket assigned to user
CimTrak.Ticket.assignedToGroupId number Ticket assigned to GroupId
CimTrak.Ticket.assignedToGroup string Ticket assigned to group
CimTrak.Ticket.externalTicketNumber string Ticket external ticket number
CimTrak.Ticket.externalTicketType string Ticket external ticket type
CimTrak.Ticket.tasks string Ticket tasks
CimTrak.Ticket.comments string Ticket comments
CimTrak.Ticket.events string Ticket events

get-ticket-tasks

Input

| Argument Name | Description | Required |
| — | — | — |

Context Output

Path Type Description
CimTrak.TicketTask.id number Ticket Task Id
CimTrak.TicketTask.ticketId number Ticket Id
CimTrak.TicketTask.agentObjectId number Agent Object id
CimTrak.TicketTask.startDate string Ticket start date
CimTrak.TicketTask.endDate string Ticket end date
CimTrak.TicketTask.disposition string Ticket disposition
CimTrak.TicketTask.creationDate string Ticket creation date
CimTrak.TicketTask.createdByUserId number Ticket created by user Id
CimTrak.TicketTask.modificationDate string Ticket modification date
CimTrak.TicketTask.modifiedByUserId number Ticket modified by user Id
CimTrak.TicketTask.assignedToUserId number Ticket assigned yo UserId
CimTrak.TicketTask.assignedToGroupId number Ticket assigned to GroupId
CimTrak.TicketTask.assigneeDisposition string Assignee Disposition
CimTrak.TicketTask.ticketTitle string Ticket title
CimTrak.TicketTask.description string Ticket description
CimTrak.TicketTask.priority number Ticket priority
CimTrak.TicketTask.ticketDisposition string Ticket disposition
CimTrak.TicketTask.ticketCreationDate string Ticket creation date
CimTrak.TicketTask.ticketCreatedByUserId string Ticket vreated by user Id
CimTrak.TicketTask.ticketModificationDate string Ticket modification date
CimTrak.TicketTask.requiresAcknowledgement string Ticket requires acknowlegment
CimTrak.TicketTask.requiresConfirmation string Ticket requires confirmation
CimTrak.TicketTask.requiresAssessment string Ticket requires assessment
CimTrak.TicketTask.ticketNumber string Ticket number
CimTrak.TicketTask.agentName string Agent name
CimTrak.TicketTask.createdByUsername string Created By Username
CimTrak.TicketTask.modifiedByUsername string Modified by username
CimTrak.TicketTask.assigneeName string Assignee Name

add-ticket

Input

Argument Name Description Required
title string Title of ticket
priority number Ticket priority
description string Ticket description
startDate string Ticket start date
endDate string Ticket end date
externalTicketNumber string External ticket number
externalTicketType string External ticket type
autoPromote boolean Auto promote
disposition string Ticket disposition
requiresAcknowledgement boolean Requires acknowledgement
requiresAssessment boolean Requires assessment
requiresConfirmation boolean Requires confirmation
assignedToUserId number Assigned to user Id
assignedToUser string Assigned to user
assignedToGroupId number Assigned to group Id
assignedToGroup string Assigned to group

Context Output

Path Type Description
CimTrak.Ticket.id number Ticket Id
CimTrak.Ticket.ticketNumber string Ticket number
CimTrak.Ticket.sentiment string Ticket sentiment
CimTrak.Ticket.sentimenttypeid string Ticket sentiment id
CimTrak.Ticket.title string Ticket title
CimTrak.Ticket.description string Ticket description
CimTrak.Ticket.priority number Ticket priority
CimTrak.Ticket.disposition string Ticket disposition
CimTrak.Ticket.creationDate string Ticket creation date
CimTrak.Ticket.createdByUser string Ticket created by user
CimTrak.Ticket.modificationDate string Ticket modification date
CimTrak.Ticket.modifiedByUser string Ticket modified by user
CimTrak.Ticket.requiresAcknowledgement boolean Ticket requires acknowledgement
CimTrak.Ticket.requiresConfirmation boolean Ticket requires confirmation
CimTrak.Ticket.requiresAssessment boolean Ticket requires assessment
CimTrak.Ticket.startDate string Ticket start date
CimTrak.Ticket.endDate string Ticket end date
CimTrak.Ticket.autoPromote boolean Ticket auto promote
CimTrak.Ticket.assignedToUserId number Ticket assigned yo UserId
CimTrak.Ticket.assignedToUser string Ticket assigned to user
CimTrak.Ticket.assignedToGroupId number Ticket assigned to GroupId
CimTrak.Ticket.assignedToGroup string Ticket assigned to group
CimTrak.Ticket.externalTicketNumber string Ticket external ticket number
CimTrak.Ticket.externalTicketType string Ticket external ticket type
CimTrak.Ticket.tasks string Ticket tasks
CimTrak.Ticket.comments string Ticket comments
CimTrak.Ticket.events string Ticket events

update-ticket

Input

Argument Name Description Required
ticketId number Ticket Id
title string Title of ticket
priority number Ticket priority
description string Ticket description
startDate string Ticket start date
endDate string Ticket end date
externalTicketNumber string External ticket number
externalTicketType string External ticket type
autoPromote boolean Auto promote
disposition string Ticket disposition
requiresAcknowledgement boolean Requires acknowledgement
requiresAssessment boolean Requires assessment
requiresConfirmation boolean Requires confirmation
assignedToUserId number Assigned to user Id
assignedToUser string Assigned to user
assignedToGroupId number Assigned to group Id
assignedToGroup string Assigned to group

Context Output

Path Type Description
CimTrak.Ticket.id number Ticket Id
CimTrak.Ticket.ticketNumber string Ticket number
CimTrak.Ticket.sentiment string Ticket sentiment
CimTrak.Ticket.sentimenttypeid string Ticket sentiment id
CimTrak.Ticket.title string Ticket title
CimTrak.Ticket.description string Ticket description
CimTrak.Ticket.priority number Ticket priority
CimTrak.Ticket.disposition string Ticket disposition
CimTrak.Ticket.creationDate string Ticket creation date
CimTrak.Ticket.createdByUser string Ticket created by user
CimTrak.Ticket.modificationDate string Ticket modification date
CimTrak.Ticket.modifiedByUser string Ticket modified by user
CimTrak.Ticket.requiresAcknowledgement boolean Ticket requires acknowledgement
CimTrak.Ticket.requiresConfirmation boolean Ticket requires confirmation
CimTrak.Ticket.requiresAssessment boolean Ticket requires assessment
CimTrak.Ticket.startDate string Ticket start date
CimTrak.Ticket.endDate string Ticket end date
CimTrak.Ticket.autoPromote boolean Ticket auto promote
CimTrak.Ticket.assignedToUserId number Ticket assigned yo UserId
CimTrak.Ticket.assignedToUser string Ticket assigned to user
CimTrak.Ticket.assignedToGroupId number Ticket assigned to GroupId
CimTrak.Ticket.assignedToGroup string Ticket assigned to group
CimTrak.Ticket.externalTicketNumber string Ticket external ticket number
CimTrak.Ticket.externalTicketType string Ticket external ticket type
CimTrak.Ticket.tasks string Ticket tasks
CimTrak.Ticket.comments string Ticket comments
CimTrak.Ticket.events string Ticket events

add-ticket-comment

Input

Argument Name Description Required
ticketId number Ticket Id
comment string Comment for ticket

Context Output

| Path | Type | Description |
| — | — | — |

add-hash-allow-list

Input

Argument Name Description Required
hash string Hash
filename string Filename for hash
source string Source for hash
sourceReference string SourceReference for hash

Context Output

Path Type Description
CimTrak.AllowList.status string Status of adding hash
CimTrak.AllowList.errorCode string Error Code of adding hash
CimTrak.AllowList.errorDescription string Error Description of adding hash
CimTrak.AllowList.hash string Hash added
CimTrak.AllowList.tagId number TagId of adding hash

add-hash-deny-list

Input

Argument Name Description Required
hash string Hash
filename string Filename for hash
source string Source for hash
sourceReference string SourceReference for hash

Context Output

Path Type Description
CimTrak.DenyList.status string Status of adding hash
CimTrak.DenyList.errorCode string Error Code of adding hash
CimTrak.DenyList.errorDescription string Error Description of adding hash
CimTrak.DenyList.hash string Hash added
CimTrak.DenyList.tagId number TagId of adding hash

delete-hash-allow-list

Input

Argument Name Description Required
hash string Hash
reason string Reason for deleting hash

Context Output

Path Type Description
CimTrak.AllowList.status string Status of deleting hash
CimTrak.AllowList.hash string Hash deleted
CimTrak.AllowList.tagId number TagId of deleting hash

delete-hash-deny-list

Input

Argument Name Description Required
hash string Hash
reason string Reason for deleting hash

Context Output

Path Type Description
CimTrak.DenyList.status string Status of deleting hash
CimTrak.DenyList.hash string Hash deleted
CimTrak.DenyList.tagId number TagId of deleting hash

get-sub-generations

Input

Argument Name Description Required
objectId number Object Id

Context Output

Path Type Description
CimTrak.SubGenerations.caseSensitive number Case Sensitive
CimTrak.SubGenerations.agentObjectId number Agent Object Id
CimTrak.SubGenerations.subGenerationId number SubgenerationId
CimTrak.SubGenerations.objectId number Object Id
CimTrak.SubGenerations.generationId number Generation Id
CimTrak.SubGenerations.subRevision number SubRevision
CimTrak.SubGenerations.notes string Notes
CimTrak.SubGenerations.creationDate string Creation Date
CimTrak.SubGenerations.files number Files
CimTrak.SubGenerations.directories number Directories
CimTrak.SubGenerations.totalSize number Total Size
CimTrak.SubGenerations.revision number Revision
CimTrak.SubGenerations.userName string User Name

deploy

Input

Argument Name Description Required
agentObjectId number Agent Object Id
subGenerationId number Sub Generation Id
notes string Notes

Context Output

| Path | Type | Description |
| — | — | — |

get-object-group

Input

Argument Name Description Required
objectId number Object Id

Context Output

Path Type Description
CimTrak.ObjectGroup.agentIsFilesystem boolean Agent Is Filesystem
CimTrak.ObjectGroup.cancel boolean Cancel
CimTrak.ObjectGroup.connected boolean Connected
CimTrak.ObjectGroup.logsByDays boolean Logs By Days
CimTrak.ObjectGroup.requireNotes boolean Require Notes
CimTrak.ObjectGroup.inService string In Service
CimTrak.ObjectGroup.children number Children
CimTrak.ObjectGroup.events number Events
CimTrak.ObjectGroup.intrusions number Intrusions
CimTrak.ObjectGroup.intrusionSize number Intrusion Size
CimTrak.ObjectGroup.objectId number Object Id
CimTrak.ObjectGroup.objectStatus number Object Status
CimTrak.ObjectGroup.objectSubType number Object SubType
CimTrak.ObjectGroup.objectType number Object Type
CimTrak.ObjectGroup.parentId number Parent Id
CimTrak.ObjectGroup.revisions number Revisions
CimTrak.ObjectGroup.templateId number Template Id
CimTrak.ObjectGroup.securityAdd boolean Security Add
CimTrak.ObjectGroup.securityEdit boolean Security Edit
CimTrak.ObjectGroup.securityLock boolean Security Lock
CimTrak.ObjectGroup.securityReport boolean Security Report
CimTrak.ObjectGroup.securityUnlock boolean Security Unlock
CimTrak.ObjectGroup.securityView boolean Security View
CimTrak.ObjectGroup.warnMinutes number Warn Minutes
CimTrak.ObjectGroup.contact string Contact
CimTrak.ObjectGroup.createDate string Create Date
CimTrak.ObjectGroup.description string Description
CimTrak.ObjectGroup.location string Location
CimTrak.ObjectGroup.name string Name
CimTrak.ObjectGroup.objectPath string Object Path
CimTrak.ObjectGroup.url string URL
CimTrak.ObjectGroup.agentObjectId number Agent Object Id
CimTrak.ObjectGroup.objectsCustom string Objects Custom
CimTrak.ObjectGroup.watchArray string Watch Array
CimTrak.ObjectGroup.comparisonMethod number Comparison Method

unlock

Input

Argument Name Description Required
objectId number Object Id

Context Output

| Path | Type | Description |
| — | — | — |

lock

Input

Argument Name Description Required
objectId number Object Id

Context Output

| Path | Type | Description |
| — | — | — |

get-object

Input

Argument Name Description Required
objectId number Object Id

Context Output

Path Type Description
CimTrak.Object.agentIsFilesystem boolean Agent Is Filesystem
CimTrak.Object.cancel boolean Cancel
CimTrak.Object.connected boolean Connected
CimTrak.Object.logsByDays boolean Logs By Days
CimTrak.Object.requireNotes boolean Require Notes
CimTrak.Object.inService string In Service
CimTrak.Object.children number Children
CimTrak.Object.events number Events
CimTrak.Object.intrusions number Intrusions
CimTrak.Object.intrusionSize number Intrusion Size
CimTrak.Object.objectId number Object Id
CimTrak.Object.objectStatus number Object Status
CimTrak.Object.objectSubType number Object SubType
CimTrak.Object.objectType number Object Type
CimTrak.Object.parentId number Parent Id
CimTrak.Object.revisions number Revisions
CimTrak.Object.templateId number Template Id
CimTrak.Object.securityAdd boolean Security Add
CimTrak.Object.securityEdit boolean Security Edit
CimTrak.Object.securityLock boolean Security Lock
CimTrak.Object.securityReport boolean Security Report
CimTrak.Object.securityUnlock boolean Security Unlock
CimTrak.Object.securityView boolean Security View
CimTrak.Object.warnMinutes number Warn Minutes
CimTrak.Object.contact string Contact
CimTrak.Object.createDate string Create Date
CimTrak.Object.description string Description
CimTrak.Object.location string Location
CimTrak.Object.name string Name
CimTrak.Object.objectPath string Object Path
CimTrak.Object.url string URL
CimTrak.Object.agentObjectId number Agent Object Id

force-sync

Input

Argument Name Description Required
objectId number Object Id

Context Output

| Path | Type | Description |
| — | — | — |

view-file

Input

Argument Name Description Required
objectDetailId number Object Detail Id

Context Output

Path Type Description
CimTrak.Sync.contents string Contents

run-report-by-name

Input

Argument Name Description Required
name string Name
objectId number Object Id
ReportParameters json Parameters for report

Context Output

Path Type Description
CimTrak.Sync.html string HTML Report

deploy-by-date

Input

Argument Name Description Required
date string Date
objectId number Object Id

Context Output

| Path | Type | Description |
| — | — | — |

get-current-compliance-items

Input

Argument Name Description Required
ObjectId number Object ID to retrieve compliance items
ComplianceScanId number Compliance Scan ID to retrieve compliance items

Context Output

Path Type Description
CimTrak.ComplianceItems.objectid number Object ID
CimTrak.ComplianceItems.type number Type of item
CimTrak.ComplianceItems.name string Name
CimTrak.ComplianceItems.description string Description
CimTrak.ComplianceItems.scanstarttime string Scan Start Time
CimTrak.ComplianceItems.scanendtime string Scan End Time
CimTrak.ComplianceItems.scanid number Scanid
CimTrak.ComplianceItems.compliancemappingid number Compliance Mapping id
CimTrak.ComplianceItems.id number id

get-objects

Input

Argument Name Description Required
ObjectType number Object Type to retrieve
ObjectSubType number Object Sub Type to retrieve
ParentId number Parent ID to retrieve
ObjectId number Object ID to retrieve
ObjectPathAndName string Object path and name to retrieve
Recursive boolean Recursive

Context Output

Path Type Description
CimTrak.Objects.repositoryDisplayName string Repository display name
CimTrak.Objects.connected boolean Connected
CimTrak.Objects.agentObjectId number Agent object Id
CimTrak.Objects.description string Description
CimTrak.Objects.name string Name
CimTrak.Objects.objectPath string Object Path
CimTrak.Objects.agentIsFilesystem boolean Agent is filesystem
CimTrak.Objects.cancel boolean Cancel
CimTrak.Objects.logsByDays boolean Logs by days
CimTrak.Objects.requireNotes boolean Require notes
CimTrak.Objects.inService string In service
CimTrak.Objects.events number Events
CimTrak.Objects.intrusions number Intrusions
CimTrak.Objects.intrusionSize number Intrusion size
CimTrak.Objects.objectId number Object ID
CimTrak.Objects.objectStatus number Object Status
CimTrak.Objects.objectSubType number object subtype
CimTrak.Objects.objectType number object type
CimTrak.Objects.parentId number Parent ID
CimTrak.Objects.revisions number Revisions
CimTrak.Objects.templateId number Template Id
CimTrak.Objects.securityAdd boolean Security add
CimTrak.Objects.securityEdit boolean Security edit
CimTrak.Objects.securityLock boolean Security lock
CimTrak.Objects.securityReport boolean Security report
CimTrak.Objects.securityUnlock boolean Security unlock
CimTrak.Objects.securityView boolean Security view
CimTrak.Objects.warnMinutes number Warn minutes
CimTrak.Objects.contact string Contact
CimTrak.Objects.createDate string Create date
CimTrak.Objects.location string Location
CimTrak.Objects.url string Url
CimTrak.Objects.parentName string Parent name
CimTrak.Objects.children number Children
CimTrak.Objects.agentVersion string Agent version
CimTrak.Objects.agentBuild number Agent build
CimTrak.Objects.agentOsVersion string Agent Os version
CimTrak.Objects.agentIp string agent Ip
CimTrak.Objects.agentName string Agent name
CimTrak.Objects.agentInstalled boolean Agent installed

get-agent-info

Input

Argument Name Description Required
ObjectId number Object ID to retrieve compliance items

Context Output

Path Type Description
CimTrak.AgentInfo.objectData string Object data
CimTrak.AgentInfo.objectsCustom string Object custom
CimTrak.AgentInfo.agentData string Agent data
CimTrak.AgentInfo.state string State

get-compliance-archive-details

Input

Argument Name Description Required
ObjectId number Object ID to retrieve compliance items
ComplianceScanId number Compliance Scan ID to retrieve compliance items
Filter json Filter array to limit results IE: [{name: id, operator:>, value:5}]
Start number Starting number of record to get
End number Ending number of record to get

Context Output

Path Type Description
CimTrak.Compliance.testdate string Test Date
CimTrak.Compliance.datatype string Data Type
CimTrak.Compliance.scanid number Scan id
CimTrak.Compliance.ipaddress string IP address
CimTrak.Compliance.lobjectid number Object Id
CimTrak.Compliance.alternatesystemid string Alternate System ID
CimTrak.Compliance.agentuuid string Agent uuid
CimTrak.Compliance.agentname string Agent name
CimTrak.Compliance.objectpath string Object path
CimTrak.Compliance.benchmark string Benchmark
CimTrak.Compliance.profile string Profile
CimTrak.Compliance.test string Test
CimTrak.Compliance.pass boolean Pass
CimTrak.Compliance.iswaived boolean Is waived
CimTrak.Compliance.adjustedscore number Adjusted score
CimTrak.Compliance.possiblescore number Possible score
CimTrak.Compliance.rawscore number Raws core
CimTrak.Compliance.weight number Weight
CimTrak.Compliance.testran boolean Test ran
CimTrak.Compliance.remediation string Remediation
CimTrak.Compliance.severity string Severity
CimTrak.Compliance.version string Version
CimTrak.Compliance.rationale string Rationale
CimTrak.Compliance.description string Description
CimTrak.Compliance.assessment string Assessment
CimTrak.Compliance.disposition string Disposition
CimTrak.Compliance.conjunction string Conjunction
CimTrak.Compliance.negatatevalue boolean Negatate value
CimTrak.Compliance.comment string Comment
CimTrak.Compliance.controlversion string Controlversion
CimTrak.Compliance.controlnumber string Control number
CimTrak.Compliance.osversion string OS version
CimTrak.Compliance.personality string Personality
CimTrak.Compliance.objectid number Object id
CimTrak.Compliance.userId number User id
CimTrak.Compliance.block boolean Lock
CimTrak.Compliance.bunlock boolean Unlock
CimTrak.Compliance.bview boolean View
CimTrak.Compliance.bedit boolean Edit
CimTrak.Compliance.badd boolean Add
CimTrak.Compliance.breports boolean Reports
CimTrak.Compliance.blogon boolean Logon
CimTrak.Compliance.isadmin boolean Is admin

get-compliance-archive-summary

Input

Argument Name Description Required
ObjectId number Object ID to retrieve compliance items
ComplianceScanId number Compliance Scan ID to retrieve compliance items
Filter json Filter array to limit results IE: [{name: id, operator:>, value:5}]
Start number Starting number of record to get
End number Ending number of record to get

Context Output

Path Type Description
CimTrak.Compliance.testdate string Test Date
CimTrak.Compliance.scanid number Scan id
CimTrak.Compliance.ipaddress string IP address
CimTrak.Compliance.datatype string Data Type
CimTrak.Compliance.alternatesystemid string Alternate System ID
CimTrak.Compliance.agentuuid string Agent uuid
CimTrak.Compliance.agentname string Agent name
CimTrak.Compliance.objectpath string Object path
CimTrak.Compliance.lobjectid number Object Id
CimTrak.Compliance.benchmark string Benchmark
CimTrak.Compliance.profile string Profile
CimTrak.Compliance.totalfailcount number Total fail count
CimTrak.Compliance.totalpasscount number Total pass count
CimTrak.Compliance.totaltestsskipped number Total tests skipped
CimTrak.Compliance.totalwaivecount number Total waive count
CimTrak.Compliance.pass boolean Pass
CimTrak.Compliance.totaltestsran number Total tests ran
CimTrak.Compliance.osversion string OS version
CimTrak.Compliance.personality string Personality
CimTrak.Compliance.userId number User id
CimTrak.Compliance.objectid number Object id
CimTrak.Compliance.block boolean Lock
CimTrak.Compliance.bunlock boolean Unlock
CimTrak.Compliance.bview boolean View
CimTrak.Compliance.bedit boolean Edit
CimTrak.Compliance.badd boolean Add
CimTrak.Compliance.breports boolean Reports
CimTrak.Compliance.blogon boolean Logon

compliance-scan-children

Input

Argument Name Description Required
objectParentId number Parent Object Id

Context Output

| Path | Type | Description |
| — | — | — |

compliance-scan-with-summary

Input

Argument Name Description Required
objectId number Object Id
retryCount number Number of times to retry to check if scan has completed
retrySeconds number Number of seconds to wait before retry to check if scan completed

Context Output

Path Type Description
CimTrak.Compliance.testdate string Test Date
CimTrak.Compliance.scanid number Scan id
CimTrak.Compliance.ipaddress string IP address
CimTrak.Compliance.datatype string Data Type
CimTrak.Compliance.alternatesystemid string Alternate System ID
CimTrak.Compliance.agentuuid string Agent uuid
CimTrak.Compliance.agentname string Agent name
CimTrak.Compliance.objectpath string Object path
CimTrak.Compliance.lobjectid number Object Id
CimTrak.Compliance.benchmark string Benchmark
CimTrak.Compliance.profile string Profile
CimTrak.Compliance.totalfailcount number Total fail count
CimTrak.Compliance.totalpasscount number Total pass count
CimTrak.Compliance.totaltestsskipped number Total tests skipped
CimTrak.Compliance.totalwaivecount number Total waive count
CimTrak.Compliance.pass boolean Pass
CimTrak.Compliance.totaltestsran number Total tests ran
CimTrak.Compliance.osversion string OS version
CimTrak.Compliance.personality string Personality
CimTrak.Compliance.userId number User id
CimTrak.Compliance.objectid number Object id
CimTrak.Compliance.block boolean Lock
CimTrak.Compliance.bunlock boolean Unlock
CimTrak.Compliance.bview boolean View
CimTrak.Compliance.bedit boolean Edit
CimTrak.Compliance.badd boolean Add
CimTrak.Compliance.breports boolean Reports
CimTrak.Compliance.blogon boolean Logon

get-agent-object-id-by-alternate-system-id

Input

Argument Name Description Required
alternateSystemId string Alternate system Id

Context Output

Path Type Description
CimTrak.Object.agentObjectId number Object Id of agent

get-agent-object-by-name

Input

Argument Name Description Required
agentName string Agent name

Context Output

Path Type Description
CimTrak.Object.agentIsFilesystem boolean Agent Is Filesystem
CimTrak.Object.cancel boolean Cancel
CimTrak.Object.connected boolean Connected
CimTrak.Object.logsByDays boolean Logs By Days
CimTrak.Object.requireNotes boolean Require Notes
CimTrak.Object.inService string In Service
CimTrak.Object.children number Children
CimTrak.Object.events number Events
CimTrak.Object.intrusions number Intrusions
CimTrak.Object.intrusionSize number Intrusion Size
CimTrak.Object.objectId number Object Id
CimTrak.Object.objectStatus number Object Status
CimTrak.Object.objectSubType number Object SubType
CimTrak.Object.objectType number Object Type
CimTrak.Object.parentId number Parent Id
CimTrak.Object.revisions number Revisions
CimTrak.Object.templateId number Template Id
CimTrak.Object.securityAdd boolean Security Add
CimTrak.Object.securityEdit boolean Security Edit
CimTrak.Object.securityLock boolean Security Lock
CimTrak.Object.securityReport boolean Security Report
CimTrak.Object.securityUnlock boolean Security Unlock
CimTrak.Object.securityView boolean Security View
CimTrak.Object.warnMinutes number Warn Minutes
CimTrak.Object.contact string Contact
CimTrak.Object.createDate string Create Date
CimTrak.Object.description string Description
CimTrak.Object.location string Location
CimTrak.Object.name string Name
CimTrak.Object.objectPath string Object Path
CimTrak.Object.url string URL
CimTrak.Object.agentObjectId number Agent Object Id

get-agent-object-by-alternate-id

Input

Argument Name Description Required
alternateSystemId string Agent alternate id

Context Output

Path Type Description
CimTrak.Object.agentIsFilesystem boolean Agent Is Filesystem
CimTrak.Object.cancel boolean Cancel
CimTrak.Object.connected boolean Connected
CimTrak.Object.logsByDays boolean Logs By Days
CimTrak.Object.requireNotes boolean Require Notes
CimTrak.Object.inService string In Service
CimTrak.Object.children number Children
CimTrak.Object.events number Events
CimTrak.Object.intrusions number Intrusions
CimTrak.Object.intrusionSize number Intrusion Size
CimTrak.Object.objectId number Object Id
CimTrak.Object.objectStatus number Object Status
CimTrak.Object.objectSubType number Object SubType
CimTrak.Object.objectType number Object Type
CimTrak.Object.parentId number Parent Id
CimTrak.Object.revisions number Revisions
CimTrak.Object.templateId number Template Id
CimTrak.Object.securityAdd boolean Security Add
CimTrak.Object.securityEdit boolean Security Edit
CimTrak.Object.securityLock boolean Security Lock
CimTrak.Object.securityReport boolean Security Report
CimTrak.Object.securityUnlock boolean Security Unlock
CimTrak.Object.securityView boolean Security View
CimTrak.Object.warnMinutes number Warn Minutes
CimTrak.Object.contact string Contact
CimTrak.Object.createDate string Create Date
CimTrak.Object.description string Description
CimTrak.Object.location string Location
CimTrak.Object.name string Name
CimTrak.Object.objectPath string Object Path
CimTrak.Object.url string URL
CimTrak.Object.agentObjectId number Agent Object Id

get-agent-object-by-ip

Input

Argument Name Description Required
ip string Agent alternate id

Context Output

Path Type Description
CimTrak.Object.agentIsFilesystem boolean Agent Is Filesystem
CimTrak.Object.cancel boolean Cancel
CimTrak.Object.connected boolean Connected
CimTrak.Object.logsByDays boolean Logs By Days
CimTrak.Object.requireNotes boolean Require Notes
CimTrak.Object.inService string In Service
CimTrak.Object.children number Children
CimTrak.Object.events number Events
CimTrak.Object.intrusions number Intrusions
CimTrak.Object.intrusionSize number Intrusion Size
CimTrak.Object.objectId number Object Id
CimTrak.Object.objectStatus number Object Status
CimTrak.Object.objectSubType number Object SubType
CimTrak.Object.objectType number Object Type
CimTrak.Object.parentId number Parent Id
CimTrak.Object.revisions number Revisions
CimTrak.Object.templateId number Template Id
CimTrak.Object.securityAdd boolean Security Add
CimTrak.Object.securityEdit boolean Security Edit
CimTrak.Object.securityLock boolean Security Lock
CimTrak.Object.securityReport boolean Security Report
CimTrak.Object.securityUnlock boolean Security Unlock
CimTrak.Object.securityView boolean Security View
CimTrak.Object.warnMinutes number Warn Minutes
CimTrak.Object.contact string Contact
CimTrak.Object.createDate string Create Date
CimTrak.Object.description string Description
CimTrak.Object.location string Location
CimTrak.Object.name string Name
CimTrak.Object.objectPath string Object Path
CimTrak.Object.url string URL
CimTrak.Object.agentObjectId number Agent Object Id

Configuration parameters

  • url — App Server URL (required)
  • isFetch — Fetch incidents
  • incidentType — Incident type
  • apikey — API Key (required)
  • insecure — Trust any certificate (not secure)
  • Repository URL — Repository URL (required)
  • Repository Port — Repository Port (required)
  • incidentFetchInterval — Incidents Fetch Interval
  • proxy — Use system proxy settings
  • first_fetch — First fetch timestamp (<number> <time unit>, e.g., 12 hours, 7 days)
  • max_fetch — Maximum number of incidents to fetch every time

Commands (37)

  • add-hash-allow-list

    Add Hash to allow list.

  • add-hash-deny-list

    Add Hash to deny list.

  • add-ticket

    Creates a ticket.

  • add-ticket-comment

    Adds a comment to a ticket or task.

  • check-file-against-trusted-file-registry-by-hash

    Description Issues a request to check a list of files (specified by hashes) against the trusted file registry.

  • compliance-scan-children

    Launch compliance scan for all children of object.

  • compliance-scan-with-summary

    Launch compliance scan for object and return results.

  • delete-hash-allow-list

    Add Hash to allow list.

  • delete-hash-deny-list

    Add Hash to deny list.

  • demote-authoritative-baseline-files

    This function removes a file (or list of files) from being the authoritative baseline.

  • deploy

    Deploys a specific version of an object group. All existing files will be overwritten with the specified set.

  • deploy-by-date

    Deploy By Date.

  • file-analysis-by-hash

    Submits a file's hash for analysis and returns the results.

  • file-analysis-by-objectdetail-id

    Submits a file's objectDetailId for analysis and returns the results.

  • force-sync

    Sends a request to the server to synchronize an object group.

  • get-agent-info

    Returns an array of agent information given an object ID.

  • get-agent-object-by-alternate-id

    Get agent object from alternate id.

  • get-agent-object-by-ip

    Get agent object from ip address.

  • get-agent-object-by-name

    Get agent object from agent name.

  • get-agent-object-id-by-alternate-system-id

    Get agent object id from alternate system id.

  • get-compliance-archive-details

    Returns compliance scans details.

  • get-compliance-archive-summary

    Returns compliance scans summary.

  • get-current-compliance-items

    This function returns the benchmarks and/or compliance mappings for the compliance policy specified by the object ID.

  • get-events

    Returns Events from the event log.

  • get-object

    Retrieves information for an object.

  • get-object-group

    This function returns an entire data structure describing an object group.

  • get-objects

    Retrieves a list of objects.

  • get-sub-generations

    Returns the subGenerations for an object group (specified by object ID.

  • get-ticket-tasks

    This function gets ticket task information from a CimTrak Master Repository. This function returns an array of ticket task objects.

  • get-tickets

    This function gets ticket information from a CimTrak Master Repository. This function returns an array of ticket objects.

  • lock

    Locks an object group.

  • promote-authoritative-baseline-files

    This function sets a file (or list of files) as the authoritative baseline.

  • run-report-by-name

    This function runs the report specified by the report name. The report name can be obtained from the getReportHeaders API. The report's parameters can be obtained from the getReportArguments API.

  • unlock

    Unlocks an object group.

  • update-task-disposition

    Updates the tasks specified in taskIdArray to the disposition specified in the disposition parameter.

  • update-ticket

    Update Ticket.

  • view-file

    This function returns the contents of the requested file encoded in base64.

import json
import time
import traceback
from datetime import datetime
from operator import itemgetter
from typing import Any

import dateparser
import demistomock as demisto  # noqa: F401

################################################################
# CimTrak Python API Begin
################################################################
import requests
import urllib3
from CommonServerPython import *  # noqa: F401


class CimTrak:
    OBJECT_TYPE_REPOSITORY = -1
    OBJECT_TYPE_AGENT = 1
    OBJECT_TYPE_AREA = 2
    OBJECT_TYPE_SYSTEM = 3
    OBJECT_TYPE_NETWORK_AGENT = 4

    OBJECT_SUBTYPE_FILESYSTEM_AGENT = 1
    OBJECT_SUBTYPE_COLLECTOR_AGENT = 2
    OBJECT_SUBTYPE_FILESYSTEM = 3
    OBJECT_SUBTYPE_NETWORKDEVICE = 4
    OBJECT_SUBTYPE_REGISTRY = 5
    OBJECT_SUBTYPE_FTP = 6
    OBJECT_SUBTYPE_INDUSTRIAL_AGENT = 7
    OBJECT_SUBTYPE_PLC = 8
    OBJECT_SUBTYPE_SOURCE_CONTROL = 9
    OBJECT_SUBTYPE_COMPLIANCE = 10
    OBJECT_SUBTYPE_VIRTUAL_DEVICE_NODE = 11

    url_root = "/CimTrakRestAPI/v1/"
    app_server_url = ""
    verify_cert = False
    auth_token = ""
    debug = 0
    connected = False
    api_key = ""
    server = ""
    port = 0

    def __init__(self, app_server_url, api_key, server, port):
        self.app_server_url = app_server_url
        self.api_key = api_key
        self.server = server
        self.port = port

    def __del__(self):
        self.disconnect()

    def debug_print(self, text):
        return 1

    def http_post(self, url, data, verify_cert):
        response = requests.post(self.app_server_url + url, data=data, verify=verify_cert)
        return response.text

    def disconnect(self):
        if self.connected is True:
            if self.debug >= 1:
                self.debug_print("Disconnecting")
            request_data = {"authToken": self.auth_token}
            if self.debug >= 4:
                self.debug_print("Request Data:" + json.dumps(request_data))
            response = self.http_post(self.url_root + "Client.logoff", json.dumps(request_data), self.verify_cert)
            if self.debug >= 4:
                self.debug_print("Response:" + response)
            request_response = json.loads(response)
            if request_response["status"] == "success":
                self.connected = False
                self.auth_token = ""
                if self.debug >= 1:
                    self.debug_print("Success logging off")
            else:
                if self.debug >= 1:
                    self.debug_print("Failed logging off")

    def connect(self, url, port, username, password):
        if self.debug >= 1:
            self.debug_print("connect")
        self.disconnect()
        request_data = {
            "username": username,
            "password": password,
            "server": url,
            "port": port,
        }
        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(
            self.url_root + "Client.connectToServer",
            json.dumps(request_data),
            self.verify_cert,
        )
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            self.connected = True
            for item in request_response["results"]:
                self.auth_token = item["authToken"]
            if self.debug >= 1:
                self.debug_print("Logon successful, authToken:" + self.auth_token)
        else:
            self.connected = False
            self.auth_token = ""
            if self.debug >= 1:
                self.debug_print("Logon failed")

    def get_events(self, start=1, end=500, filter=None, sorts=None):
        if self.debug >= 1:
            self.debug_print("get_events")
        request_data = {
            "authToken": self.auth_token,
            "cursorName": self.auth_token + "pythonLibrary",
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "refresh": True,
            "start": start,
            "end": end,
        }
        if sorts is not None and sorts != "":
            request_data["sorts"] = sorts
        if filter is not None and filter != "":
            request_data["filter"] = filter
        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(
            self.url_root + "Client.getEventLogRaw",
            json.dumps(request_data),
            self.verify_cert,
        )
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("get_events successful")
        else:
            if self.debug >= 1:
                self.debug_print("get_events failed")
        return request_response

    def get_unreconciled_items(self, start=1, end=500, object_id=0, sorts=None):
        if self.debug >= 1:
            self.debug_print("get_unreconciled_items")
        request_data = {
            "authToken": self.auth_token,
            "cursorName": self.auth_token + "pythonLibrary",
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "refresh": True,
            "start": start,
            "end": end,
            "objectId": object_id,
        }
        if sorts is not None and sorts != "":
            request_data["sorts"] = sorts
        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(
            self.url_root + "Client.getUnreconciledItems",
            json.dumps(request_data),
            self.verify_cert,
        )
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("get_unreconciled_items successful")
        else:
            if self.debug >= 1:
                self.debug_print("get_unreconciled_items failed")
        return request_response

    def file_analysis_by_hash(self, hash):
        if self.debug >= 1:
            self.debug_print("file_analysis_by_hash")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "hash": hash,
        }
        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(
            self.url_root + "Client.fileAnalysisByHash",
            json.dumps(request_data),
            self.verify_cert,
        )
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("file_analysis_by_hash successful")
        else:
            if self.debug >= 1:
                self.debug_print("file_analysis_by_hash failed")
        return request_response

    def file_analysis_by_object_detail_id(self, object_detail_id):
        if self.debug >= 1:
            self.debug_print("file_analysis_by_object_detail_id")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "objectDetailId": object_detail_id,
        }
        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(
            self.url_root + "Client.fileAnalysisByObjectDetailId",
            json.dumps(request_data),
            self.verify_cert,
        )
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("file_analysis_by_object_detail_id successful")
        else:
            if self.debug >= 1:
                self.debug_print("file_analysis_by_object_detail_id failed")
        return request_response

    def check_file_against_trusted_file_registry_by_hash(self, hashes):
        if self.debug >= 1:
            self.debug_print("check_file_against_trusted_file_registry_by_hash")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "hashes": hashes,
        }
        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(
            self.url_root + "Client.checkFileAgainstTrustedFileRegistryByHash",
            json.dumps(request_data),
            self.verify_cert,
        )
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("check_file_against_trusted_file_registry_by_hash successful")
        else:
            if self.debug >= 1:
                self.debug_print("check_file_against_trusted_file_registry_by_hash failed")
        return request_response

    def search_trusted_file_registry_by_hash(self, hash):
        if self.debug >= 1:
            self.debug_print("search_trusted_file_registry_by_hash")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "hash": hash,
        }
        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(
            self.url_root + "Client.searchTrustedFileRegistryByHash",
            json.dumps(request_data),
            self.verify_cert,
        )
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("search_trusted_file_registry_by_hash successful")
        else:
            if self.debug >= 1:
                self.debug_print("search_trusted_file_registry_by_hash failed")
        return request_response

    def promote_authoritative_baseline_files(self, object_detail_ids):
        if self.debug >= 1:
            self.debug_print("promote_authoritative_baseline_files")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "objectDetailId": object_detail_ids,
        }
        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(
            self.url_root + "Client.promoteAuthoritativeBaselineFiles",
            json.dumps(request_data),
            self.verify_cert,
        )
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("promote_authoritative_baseline_files successful")
        else:
            if self.debug >= 1:
                self.debug_print("promote_authoritative_baseline_files failed")
        return request_response

    def demote_authoritative_baseline_files(self, object_detail_ids):
        if self.debug >= 1:
            self.debug_print("demote_authoritative_baseline_files")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "objectDetailId": object_detail_ids,
        }
        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(
            self.url_root + "Client.demoteAuthoritativeBaselineFiles",
            json.dumps(request_data),
            self.verify_cert,
        )
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("demote_authoritative_baseline_files successful")
        else:
            if self.debug >= 1:
                self.debug_print("demote_authoritative_baseline_files failed")
        return request_response

    def get_tickets(self, user_id=-99, filters=None):
        if self.debug >= 1:
            self.debug_print("get_tickets")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
        }
        if user_id != -99:
            request_data["userId"] = user_id
        if filters is not None and filters != "":
            request_data["filters"] = filters

        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(self.url_root + "Client.getTickets", json.dumps(request_data), self.verify_cert)
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("get_tickets successful")
        else:
            if self.debug >= 1:
                self.debug_print("get_tickets failed")
        return request_response

    def get_ticket_tasks(self, showAdminView=False, user_id=-99, filters=None):
        if self.debug >= 1:
            self.debug_print("get_ticket_tasks")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "showAdminView": showAdminView,
        }
        if user_id != -99:
            request_data["userId"] = user_id
        if filters is not None and filters != "":
            request_data["filters"] = filters

        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(
            self.url_root + "Client.getTicketTasks",
            json.dumps(request_data),
            self.verify_cert,
        )
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("get_ticket_tasks successful")
        else:
            if self.debug >= 1:
                self.debug_print("get_ticket_tasks failed")
        return request_response

    def add_ticket(
        self,
        title,
        priority,
        description="",
        start_date="",
        end_date="",
        external_ticket_number="",
        external_ticket_type="",
        auto_promote=False,
        disposition="OPEN",
        requires_acknowledgement=False,
        requires_assessment=False,
        requires_confirmation=False,
        assigned_to_user_id=0,
        assigned_to_user="",
        assigned_to_group_id=0,
        assigned_to_group="",
        tasks=None,
    ):
        if self.debug >= 1:
            self.debug_print("add_ticket")
        ticket = {
            "title": title,
            "priority": priority,
            "description": description,
            "externalTicketNumber": external_ticket_number,
            "externalTicketType": external_ticket_type,
            "autoPromote": auto_promote,
            "disposition": disposition,
            "requiresAcknowledgement": requires_acknowledgement,
            "requiresAssessment": requires_assessment,
            "requiresConfirmation": requires_confirmation,
            "assignedToUserId": assigned_to_user_id,
            "assignedToUser": assigned_to_user,
            "assignedToGroupId": assigned_to_group_id,
            "assignedToGroup": assigned_to_group,
        }
        if start_date != "":
            ticket["startDate"] = start_date
        if end_date != "":
            ticket["endDate"] = end_date
        if tasks is not None and tasks != "":
            ticket["tasks"] = tasks

        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "ticket": ticket,
        }

        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(self.url_root + "Client.addTicket", json.dumps(request_data), self.verify_cert)
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("add_ticket successful")
        else:
            if self.debug >= 1:
                self.debug_print("add_ticket failed")
        return request_response

    def update_ticket(
        self,
        ticket_id,
        title,
        priority,
        description="",
        start_date="",
        end_date="",
        external_ticket_number="",
        external_ticket_type="",
        auto_promote=False,
        disposition="OPEN",
        requires_acknowledgement=False,
        requires_assessment=False,
        requires_confirmation=False,
        assigned_to_user_id=0,
        assigned_to_user="",
        assigned_to_group_id=0,
        assigned_to_group="",
        tasks=None,
    ):
        if self.debug >= 1:
            self.debug_print("update_ticket")
        ticket = {
            "title": title,
            "priority": priority,
            "description": description,
            "externalTicketNumber": external_ticket_number,
            "externalTicketType": external_ticket_type,
            "autoPromote": auto_promote,
            "disposition": disposition,
            "requiresAcknowledgement": requires_acknowledgement,
            "requiresAssessment": requires_assessment,
            "requiresConfirmation": requires_confirmation,
            "assignedToUserId": assigned_to_user_id,
            "assignedToUser": assigned_to_user,
            "assignedToGroupId": assigned_to_group_id,
            "assignedToGroup": assigned_to_group,
        }
        if start_date != "":
            ticket["startDate"] = start_date
        if end_date != "":
            ticket["endDate"] = end_date
        if tasks is not None and tasks != "":
            ticket["tasks"] = tasks

        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "filter": [{"name": "id", "operator": "=", "value": ticket_id}],
            "data": ticket,
        }

        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(
            self.url_root + "Client.updateTickets",
            json.dumps(request_data),
            self.verify_cert,
        )
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("update_ticket successful")
        else:
            if self.debug >= 1:
                self.debug_print("update_ticket failed")
        return request_response

    def add_ticket_comment(self, ticket_id, comment):
        if self.debug >= 1:
            self.debug_print("add_ticket_comment")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "ticketId": ticket_id,
            "taskId": 0,
            "comment": comment,
        }

        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(
            self.url_root + "Client.addTicketComment",
            json.dumps(request_data),
            self.verify_cert,
        )
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("add_ticket_comment successful")
        else:
            if self.debug >= 1:
                self.debug_print("add_ticket_comment failed")
        return request_response

    def update_task_disposition(self, task_id, disposition):
        if self.debug >= 1:
            self.debug_print("update_task_disposition")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "taskIdArray": [task_id],
            "disposition": disposition,
        }

        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(
            self.url_root + "Client.updateTaskDisposition",
            json.dumps(request_data),
            self.verify_cert,
        )
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("update_task_disposition successful")
        else:
            if self.debug >= 1:
                self.debug_print("update_task_disposition failed")
        return request_response

    def add_hash_allow_list(self, hash, filename="", source="", source_reference=""):
        if self.debug >= 1:
            self.debug_print("add_hash_allow_list")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "tagId": [0],
            "hashList": [
                {
                    "hash": hash,
                    "filename": filename,
                    "source": source,
                    "sourceReference": source_reference,
                }
            ],
        }

        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(
            self.url_root + "Client.addHashWhitelist",
            json.dumps(request_data),
            self.verify_cert,
        )
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("add_hash_allow_list successful")
        else:
            if self.debug >= 1:
                self.debug_print("add_hash_allow_list failed")
        return request_response

    def add_hash_deny_list(self, hash, filename="", source="", source_reference=""):
        if self.debug >= 1:
            self.debug_print("add_hash_deny_list")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "tagId": [0],
            "hashList": [
                {
                    "hash": hash,
                    "filename": filename,
                    "source": source,
                    "sourceReference": source_reference,
                }
            ],
        }

        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(
            self.url_root + "Client.addHashBlacklist",
            json.dumps(request_data),
            self.verify_cert,
        )
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("add_hash_deny_list successful")
        else:
            if self.debug >= 1:
                self.debug_print("add_hash_deny_list failed")
        return request_response

    def delete_hash_allow_list(self, reason, hash):
        if self.debug >= 1:
            self.debug_print("delete_hash_allow_list")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "reason": reason,
            "hashTagIdArray": [{"hash": hash, "tag": 0}],
        }

        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(
            self.url_root + "Client.deleteHashWhitelist",
            json.dumps(request_data),
            self.verify_cert,
        )
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("delete_hash_allow_list successful")
        else:
            if self.debug >= 1:
                self.debug_print("delete_hash_allow_list failed")
        return request_response

    def delete_hash_deny_list(self, reason, hash):
        if self.debug >= 1:
            self.debug_print("delete_hash_deny_list")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "reason": reason,
            "hashTagIdArray": [{"hash": hash, "tag": 0}],
        }

        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(
            self.url_root + "Client.deleteHashBlacklist",
            json.dumps(request_data),
            self.verify_cert,
        )
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("delete_hash_deny_list successful")
        else:
            if self.debug >= 1:
                self.debug_print("delete_hash_deny_list failed")
        return request_response

    def get_sub_generations(self, object_id):
        if self.debug >= 1:
            self.debug_print("get_sub_generations")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "objectId": object_id,
        }

        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(
            self.url_root + "Client.getSubGenerations",
            json.dumps(request_data),
            self.verify_cert,
        )
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("get_sub_generations successful")
        else:
            if self.debug >= 1:
                self.debug_print("get_sub_generations failed")
        return request_response

    def deploy(self, agent_object_id, sub_generation_id, notes=""):
        if self.debug >= 1:
            self.debug_print("deploy")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "agentObjectId": agent_object_id,
            "subGenerationId": sub_generation_id,
            "notes": notes,
        }

        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(self.url_root + "Client.deploy", json.dumps(request_data), self.verify_cert)
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("deploy successful")
        else:
            if self.debug >= 1:
                self.debug_print("deploy failed")
        return request_response

    def get_object_group(self, object_id):
        if self.debug >= 1:
            self.debug_print("get_object_group")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "objectId": object_id,
        }

        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(
            self.url_root + "Client.getObjectGroup",
            json.dumps(request_data),
            self.verify_cert,
        )
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("get_object_group successful")
        else:
            if self.debug >= 1:
                self.debug_print("get_object_group failed")
        return request_response

    def unlock(self, object_id):
        if self.debug >= 1:
            self.debug_print("unlock")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "objectId": object_id,
        }

        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(self.url_root + "Client.unlock", json.dumps(request_data), self.verify_cert)
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("unlock successful")
        else:
            if self.debug >= 1:
                self.debug_print("unlock failed")
        return request_response

    def lock(self, object_id):
        if self.debug >= 1:
            self.debug_print("lock")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "objectId": object_id,
        }

        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(self.url_root + "Client.lock", json.dumps(request_data), self.verify_cert)
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("lock successful")
        else:
            if self.debug >= 1:
                self.debug_print("lock failed")
        return request_response

    def get_object(self, object_id):
        if self.debug >= 1:
            self.debug_print("get_object")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "objectId": object_id,
        }

        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(self.url_root + "Client.getObject", json.dumps(request_data), self.verify_cert)
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("get_object successful")
        else:
            if self.debug >= 1:
                self.debug_print("get_object failed")
        return request_response

    def force_sync(self, object_id):
        if self.debug >= 1:
            self.debug_print("force_sync")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "objectId": object_id,
        }

        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(self.url_root + "Client.forceSync", json.dumps(request_data), self.verify_cert)
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("force_sync successful")
        else:
            if self.debug >= 1:
                self.debug_print("force_sync failed")
        return request_response

    def view_file(self, object_detail_id):
        if self.debug >= 1:
            self.debug_print("view_file")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "objectDetailId": object_detail_id,
        }

        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(self.url_root + "Client.viewFile", json.dumps(request_data), self.verify_cert)
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("view_file successful")
        else:
            if self.debug >= 1:
                self.debug_print("view_file failed")
        return request_response

    def run_report_by_name(self, name, object_id=0, report_parameter_values=None):
        if self.debug >= 1:
            self.debug_print("run_report_by_name")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "name": name,
            "objectId": object_id,
        }

        if report_parameter_values is not None and report_parameter_values != "":
            request_data["reportParameterValues"] = report_parameter_values

        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(
            self.url_root + "Client.runReportByName",
            json.dumps(request_data),
            self.verify_cert,
        )
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("run_report_by_name successful")
        else:
            if self.debug >= 1:
                self.debug_print("run_report_by_name failed")
        return request_response

    def get_current_compliance_items(self, object_id, compliance_scan_id=-1):
        if self.debug >= 1:
            self.debug_print("get_current_compliance_items")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "objectId": object_id,
        }
        if compliance_scan_id != -1:
            request_data["complianceScanId"] = compliance_scan_id

        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(
            self.url_root + "Client.getCurrentComplianceItems",
            json.dumps(request_data),
            self.verify_cert,
        )
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("get_current_compliance_items successful")
        else:
            if self.debug >= 1:
                self.debug_print("get_current_compliance_items failed")
        return request_response

    def get_objects(
        self,
        object_type=-1,
        object_subtype=-1,
        parent_id=-1,
        object_id=-1,
        object_path_and_name="",
        recursive=False,
        filter=None,
    ):
        if self.debug >= 1:
            self.debug_print("get_objects")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "recursive": recursive,
            "objectPathAndName": object_path_and_name,
            "includeAllRepositories": True,
        }
        if filter is not None and filter != "":
            request_data["filter"] = filter
        if parent_id != -1:
            request_data["parentId"] = parent_id
        if object_id != -1:
            request_data["objectId"] = object_id
        if object_type != -1:
            request_data["objectType"] = object_type
        if object_subtype != -1:
            request_data["objectSubType"] = object_subtype

        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(
            self.url_root + "Client.getObjects",
            json.dumps(request_data),
            self.verify_cert,
        )
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("get_objects successful")
        else:
            if self.debug >= 1:
                self.debug_print("get_objects failed")
        return request_response

    def get_agent_info(self, object_id):
        if self.debug >= 1:
            self.debug_print("get_agent_info")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "objectId": object_id,
        }

        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(
            self.url_root + "Client.getAgentInfo",
            json.dumps(request_data),
            self.verify_cert,
        )
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("get_agent_info successful")
        else:
            if self.debug >= 1:
                self.debug_print("get_agent_info failed")
        return request_response

    def get_compliance_archive_details(self, object_id, compliance_scan_id=-1, filter=None, start=-1, end=-1):
        if self.debug >= 1:
            self.debug_print("get_compliance_archive_details")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "objectId": object_id,
        }
        if compliance_scan_id != -1:
            request_data["complianceScanId"] = compliance_scan_id
        if start != -1:
            request_data["start"] = start
        if end != -1:
            request_data["end"] = end
        if filter is not None and filter != "":
            request_data["filter"] = filter

        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(
            self.url_root + "Client.getComplianceArchiveDetails",
            json.dumps(request_data),
            self.verify_cert,
        )
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("get_compliance_archive_details successful")
        else:
            if self.debug >= 1:
                self.debug_print("get_compliance_archive_details failed")
        return request_response

    def get_compliance_archive_summary(self, object_id, compliance_scan_id=-1, filter=None, start=-1, end=-1):
        if self.debug >= 1:
            self.debug_print("get_compliance_archive_summary")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "objectId": object_id,
        }
        if compliance_scan_id != -1:
            request_data["complianceScanId"] = compliance_scan_id
        if start != -1:
            request_data["start"] = start
        if end != -1:
            request_data["end"] = end
        if filter is not None and filter != "":
            request_data["filter"] = filter

        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(
            self.url_root + "Client.getComplianceArchiveSummary",
            json.dumps(request_data),
            self.verify_cert,
        )
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("get_compliance_archive_summary successful")
        else:
            if self.debug >= 1:
                self.debug_print("get_compliance_archive_summary failed")
        return request_response

    def get_agent_object_id_by_alternate_system_id(self, alternate_system_id):
        if self.debug >= 1:
            self.debug_print("get_agent_object_id_by_alternate_system_id")
        request_data = {
            "authToken": self.auth_token,
            "server": self.server,
            "port": self.port,
            "apiKey": self.api_key,
            "alternateSystemId": alternate_system_id,
        }

        if self.debug >= 4:
            self.debug_print("Request Data:" + json.dumps(request_data))
        response = self.http_post(
            self.url_root + "Client.getAgentObjectIdByAlternateSystemId",
            json.dumps(request_data),
            self.verify_cert,
        )
        if self.debug >= 4:
            self.debug_print("Response:" + response)
        request_response = json.loads(response)
        if request_response["status"] == "success":
            if self.debug >= 1:
                self.debug_print("get_agent_object_id_by_alternate_system_id successful")
        else:
            if self.debug >= 1:
                self.debug_print("get_agent_object_id_by_alternate_system_id failed")
        return request_response

    def deploy_by_date(self, date, object_id):
        if self.debug >= 4:
            self.debug_print("deploy_by_date")
        request_response = self.get_sub_generations(object_id)
        results = request_response["results"]
        results = sorted(results, key=itemgetter("subGenerationId"), reverse=True)
        target_datetime = datetime.strptime(date, "%Y-%m-%d %H:%M:%S")
        target_gen = 0
        agent_objectId = 0
        for subgen in results:
            subgen_datetime = datetime.strptime(subgen["creationDate"], "%Y-%m-%d %H:%M:%S")
            if subgen_datetime <= target_datetime and target_gen == 0:
                objectGroupResponse = self.get_object_group(subgen["objectId"])
                objectGroupResults = objectGroupResponse.get("results")
                canDeploy = True
                isLocked = False
                for result in objectGroupResults:
                    for watch in result["watchArray"]:
                        if watch["storeAuthoritative"] is False:
                            canDeploy = False
                    if result["objectStatus"] == 2:
                        isLocked = True

                if canDeploy is True:
                    if isLocked is True:
                        self.unlock(subgen["objectId"])
                        while isLocked is True:
                            objectResponse = self.get_object(subgen["objectId"])
                            objectResults = objectResponse["results"]
                            for objectResult in objectResults:
                                if objectResult["objectStatus"] == 1:
                                    isLocked = False
                                else:
                                    time.sleep(2)

                    target_gen = subgen["subGenerationId"]
                    agent_objectId = subgen["agentObjectId"]
        if self.debug >= 4:
            self.debug_print("Got target agent:" + str(target_gen))
        if target_gen != 0:
            return self.deploy(agent_objectId, target_gen)
        else:
            ret_data: dict[str, Any] = {}
            ret_results: list[dict[str, Any]] = []
            ret_data["status"] = "success"
            ret_data["errorCode"] = ""
            ret_data["errorDescription"] = ""
            ret_data["results"] = ret_results
            return ret_data

    def compliance_scan_children(self, object_parent_id):
        request_response = self.get_objects(parent_id=object_parent_id)
        results = request_response["results"]

        for object in results:
            if object["objectSubType"] == self.OBJECT_SUBTYPE_COMPLIANCE:
                if self.debug >= 4:
                    self.debug_print("Scanning compliance object:" + str(object["objectId"]))
                self.force_sync(object["objectId"])
        ret_data: dict[str, Any] = {}
        ret_results: list[dict[str, Any]] = []
        ret_data["status"] = "success"
        ret_data["errorCode"] = ""
        ret_data["errorDescription"] = ""
        ret_data["results"] = ret_results
        return ret_data

    def compliance_scan_with_summary(self, object_id, retry_count=20, retry_seconds=10):
        if self.debug >= 4:
            self.debug_print("compliance_scan_with_summary")
        # Get the last scan id for this object
        request_response = self.get_compliance_archive_summary(object_id)
        results = request_response["results"]
        results = sorted(results, key=itemgetter("scanid"))
        last_scanid = 0

        for scan in results:
            last_scanid = scan["scanid"]
        if self.debug >= 4:
            self.debug_print("Got last scan id:" + str(last_scanid))
        # Get the last log id
        filter = [{"name": "lObjectID", "operator": "=", "value": object_id}]
        sorts = [{"field": "id", "descending": True}]
        request_response = self.get_events(start=1, end=1, filter=filter, sorts=sorts)
        results = request_response["results"]
        last_logid = 0

        for log in results:
            last_logid = log["id"]
        if self.debug >= 4:
            self.debug_print("Got last log id:" + str(last_logid))

        # Start the scan
        self.force_sync(object_id)
        # Wait for sync to complete
        filter = [
            {"name": "lObjectID", "operator": "=", "value": object_id},
            {"name": "", "operator": "AND", "value": 0},
            {"name": "szMessageID", "operator": "=", "value": "S_LOGMSG_0000000135             "},
            {"name": "", "operator": "AND", "value": 0},
            {"name": "id", "operator": ">", "value": last_logid},
        ]
        resultcount = 0
        tries = 0
        while resultcount == 0 and tries < retry_count:
            tries = tries + 1
            if self.debug >= 4:
                self.debug_print("Polling log entries")
            request_response = self.get_events(filter=filter)
            results = request_response["results"]
            for _scan in results:
                resultcount = resultcount + 1
            if resultcount == 0:
                if self.debug >= 4:
                    self.debug_print("Sleeping to wait for compliance results: Try " + str(tries) + " of " + str(retry_count))
                time.sleep(retry_seconds)

        if resultcount == 0 and self.debug >= 4:
            self.debug_print("Timeout waiting for compliance scan to complete")
        # Get results
        filter = [{"name": "scanid", "operator": ">", "value": last_scanid}]
        request_response = self.get_compliance_archive_summary(object_id, filter=filter)
        return request_response

    def get_agent_object_by_name(self, agent_name):
        if self.debug >= 4:
            self.debug_print("get_agent_object_id_by_name")

        request_response = self.get_objects(object_path_and_name=agent_name, object_type=self.OBJECT_TYPE_AGENT)
        results = request_response["results"]
        ret_data: dict[str, Any] = {}
        ret_results: list[dict[str, Any]] = []
        for object in results:
            if object["name"] == agent_name:
                ret_results.append(object)
        ret_data["status"] = "success"
        ret_data["errorCode"] = ""
        ret_data["errorDescription"] = ""
        ret_data["results"] = ret_results
        if self.debug >= 4:
            self.debug_print("get_agent_object_id_by_name returning:" + str(ret_data))

        return ret_data

    def get_agent_object_by_alternate_id(self, alternate_system_id):
        if self.debug >= 4:
            self.debug_print("get_agent_object_by_alternate_id")

        request_response = self.get_agent_object_id_by_alternate_system_id(alternate_system_id=alternate_system_id)
        results = request_response["results"]
        ret_data: dict[str, Any] = {}
        ret_results: list[dict[str, Any]] = []
        for result in results:
            if result["agentObjectId"] > 0:
                request_response_object = self.get_object(result["agentObjectId"])
                results_object = request_response_object["results"]
                for result_object in results_object:
                    ret_results.append(result_object)
        ret_data["status"] = "success"
        ret_data["errorCode"] = ""
        ret_data["errorDescription"] = ""
        ret_data["results"] = ret_results
        if self.debug >= 4:
            self.debug_print("get_agent_object_by_alternate_id returning:" + str(ret_data))

        return ret_data

    def get_agent_object_by_ip(self, ip):
        if self.debug >= 4:
            self.debug_print("get_agent_object_by_ip")
        if ip.find(":") == -1:
            ip_fixed = "cast($DQ$" + ip + "$DQ$::inet - $DQ$0.0.0.0$DQ$::inet as bigint)"
        else:
            ip_fixed = "cast($DQ$" + ip + "$DQ$::inet - $DQ$::ffff:0.0.0.0$DQ$::inet as bigint)"
        ip_if_statement = "cast(iif(position($DQ$:$DQ$ in get_objects.szlastip) > 0  ,"
        ip_if_statement += "cast(get_objects.szlastip::inet - $DQ$::ffff:0.0.0.0$DQ$::inet  as text)"
        ip_if_statement += ",iif(position($DQ$.$DQ$ in get_objects.szlastip) > 0 ,"
        ip_if_statement += "cast(get_objects.szlastip::inet - $DQ$::ffff:0.0.0.0$DQ$::inet as text),$DQ$0$DQ$)) as bigint) - "
        ip_if_statement += ip_fixed
        filter = [
            {"name": "", "operator": "(", "value": ""},
            {"name": "position($DQ$.$DQ$ in get_objects.szlastip)", "operator": ">", "value": 0},
            {"name": "", "operator": "or", "value": ""},
            {"name": "position($DQ$:$DQ$ in get_objects.szlastip)", "operator": ">", "value": 0},
            {"name": "", "operator": ")", "value": ""},
            {"name": "", "operator": "AND", "value": ""},
            {"name": ip_if_statement, "operator": "=", "value": 0},
        ]
        request_response = self.get_objects(object_type=self.OBJECT_TYPE_AGENT, filter=filter)
        results = request_response["results"]
        ret_data: dict[str, Any] = {}
        ret_results: list[dict[str, Any]] = []
        for object in results:
            ret_results.append(object)
        ret_data["status"] = "success"
        ret_data["errorCode"] = ""
        ret_data["errorDescription"] = ""
        ret_data["results"] = ret_results

        if self.debug >= 4:
            self.debug_print("get_agent_object_by_ip returning:" + str(ret_data))
        return ret_data


################################################################
# CimTrak Python API End
################################################################

# Disable insecure warnings
urllib3.disable_warnings()


""" CONSTANTS """
MAX_INCIDENTS_TO_FETCH = 50

""" CLIENT CLASS """


class Client(BaseClient, CimTrak):
    def http_post(self, URL, data, verify_cert):
        response = self._http_request(method="POST", url_suffix=URL, data=data, resp_type="text")
        return response

    def debug_print(self, text):
        demisto.debug(text)

    """Client class to interact with the service API

    This Client implements API calls, and does not contain any Demisto logic.
    Should only do requests and return data.
    It inherits from BaseClient defined in CommonServer Python.
    Most calls use _http_request() that handles proxy, SSL verification, etc.
    For this HelloWorld implementation, no special attributes defined
    """

    def test(self) -> dict[str, Any]:
        request_response = self.get_unreconciled_items(1, MAX_INCIDENTS_TO_FETCH)
        return request_response


""" HELPER FUNCTIONS """


def parse_domain_date(domain_date: list[str] | str, date_format: str = "%Y-%m-%dT%H:%M:%S.000Z") -> str | None:
    """Converts whois date format to an ISO8601 string

    Converts the HelloWorld domain WHOIS date (YYYY-mm-dd HH:MM:SS) format
    in a datetime. If a list is returned with multiple elements, takes only
    the first one.

    :type domain_date: ``Union[List[str],str]``
    :param date_format:
            a string or list of strings with the format 'YYYY-mm-DD HH:MM:SS'

    :return: Parsed time in ISO8601 format
    :rtype: ``Optional[str]``
    """

    if isinstance(domain_date, str):
        # if str parse the value
        domain_date_dt = dateparser.parse(domain_date)
        if domain_date_dt:
            return domain_date_dt.strftime(date_format)
    elif isinstance(domain_date, list) and len(domain_date) > 0 and isinstance(domain_date[0], str):
        # if list with at least one element, parse the first element
        domain_date_dt = dateparser.parse(domain_date[0])
        if domain_date_dt:
            return domain_date_dt.strftime(date_format)
    # in any other case return nothing
    return None


""" COMMAND FUNCTIONS """


def test_module(client: Client, first_fetch_time: int) -> str:
    """Tests API connectivity and authentication'

    Returning 'ok' indicates that the integration works like it is supposed to.
    Connection to the service is successful.
    Raises exceptions if something goes wrong.

    :type client: ``Client``
    :param Client: HelloWorld client to use

    :type name: ``str``
    :param name: name to append to the 'Hello' string

    :return: 'ok' if test passed, anything else will fail the test.
    :rtype: ``str``
    """

    try:
        request_response = client.test()
        if request_response["status"] == "success":
            return "ok"
    except DemistoException as e:
        if "Forbidden" in str(e):
            return "Authorization Error: make sure API Key is correctly set"
        else:
            raise e
    return request_response["status"] + " : " + request_response["errorDescription"]


def fetch_incidents(
    client: Client,
    max_results: int,
    last_run: dict[str, int],
    first_fetch_time: int | None,
    alert_status: str | None,
    min_severity: str,
    alert_type: str | None,
):
    # Get the last fetch time, if exists
    # last_run is a dict with a single key, called last_fetch
    last_fetch = last_run.get("last_fetch", None)
    # Handle first fetch time
    if last_fetch is None or last_fetch == "":
        # if missing, use what provided via first_fetch_time
        last_fetch = 0
    else:
        # otherwise use the stored last fetch
        last_fetch = int(last_fetch)
    # for type checking, making sure that latest_created_time is int

    # Initialize an empty list of incidents to return
    # Each incident is a dict with a string as a key
    incidents: list[dict[str, Any]] = []
    # Get the CSV list of severities from min_severity
    # severity = ',Low'
    request_response = client.get_unreconciled_items(1, MAX_INCIDENTS_TO_FETCH)

    if request_response["status"] == "success":
        for item in request_response["results"]:
            if item.get("id") > last_fetch:
                incident_name = "CimTrak - " + item["changeFromPrevious"]
                agent_ip = ""
                request_response_agent_info = client.get_agent_info(item.get("parentId"))
                event_results_agent_info = request_response_agent_info["results"]
                for agent_info in event_results_agent_info:
                    agent_info_state = agent_info["state"]
                    agent_ip = agent_info_state["agentIp"]
                item["ip"] = agent_ip
                incident = {
                    "name": incident_name,
                    "details": item["changeFromPrevious"] + ": " + item["dirAndFile"],
                    "occurred": parse_domain_date(item.get("eventTime")),
                    "rawJSON": json.dumps(item),
                    "type": "CimTrak Alert",  # Map to a specific XSOAR incident Type
                    "severity": IncidentSeverity.MEDIUM,
                    "CustomFields": {  # Map specific XSOAR Custom Fields
                        "hash": item.get("hash"),
                        "fileSize": item.get("fileSize"),
                        "ticketNumber": item.get("ticketNumber"),
                        "objectPath": item.get("objectPath"),
                    },
                }

                incidents.append(incident)

                # Update last run and add incident if the incident is newer than last fetch

                # if incident_created_time > latest_created_time:
                last_fetch = item.get("id")

    next_run = {"last_fetch": last_fetch}
    return next_run, incidents


################################################################
# CimTrak Palo Alto Custom Functions Begin
################################################################
def ResolveBool(value):
    return not (value.lower() == "false" or value == "0")


def ResolveString(value):
    if not value or value == "":
        return ""
    else:
        return value


def ResolveJson(value):
    if not value or value == "":
        return None
    else:
        return json.loads(value)


def get_events_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    start = int(ResolveString(args.get("Start")))
    end = int(ResolveString(args.get("End")))
    filter = ResolveJson(args.get("Filter"))
    sorts = ResolveJson(args.get("Sorts"))
    response = client.get_events(start=start, end=end, filter=filter, sorts=sorts)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.Event.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "id",
        "leventid",
        "lagentid",
        "lobjectid",
        "lobjectdetailid",
        "lobjectdetailidint",
        "lmessagelevel",
        "szuser",
        "szfileuser",
        "szmessageid",
        "szmessage",
        "szfile",
        "szcorrectionid",
        "szcorrection",
        "lcategory",
        "lemailsent",
        "lstoragestatus",
        "dtmdatetime1",
        "dtmdatetime2",
        "szchecksum",
        "status",
        "lprocessid",
        "lthreadid",
        "szprocess",
        "szforensicdata",
        "dtmdeleted",
        "ltickcount",
        "lsubtype",
        "ticketNumber",
        "ldeleteobjectdetailid",
        "bfoundinblacklist",
        "filecontenthash",
        "lobjectsettingid",
        "reconciled",
        "isauthcopy",
        "externalticketnumber",
        "lparentid",
        "szobjectpath",
        "dfilesize",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(readable_output=result, outputs_prefix="CimTrak.Event", outputs_key_field="id", outputs=result_final)
        )
    return command_results


def file_analysis_by_hash_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    hash = ResolveString(args.get("Hash"))
    response = client.file_analysis_by_hash(hash=hash)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.FileAnalysis.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "analysisEngine",
        "analysisSuccess",
        "analysisResults",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(
                readable_output=result, outputs_prefix="CimTrak.FileAnalysis", outputs_key_field="id", outputs=result_final
            )
        )
    return command_results


def file_analysis_by_object_detail_id_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    object_detail_id = int(ResolveString(args.get("ObjectDetailId")))
    response = client.file_analysis_by_object_detail_id(object_detail_id=object_detail_id)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.FileAnalysis.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "analysisEngine",
        "analysisSuccess",
        "analysisResults",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(
                readable_output=result, outputs_prefix="CimTrak.FileAnalysis", outputs_key_field="id", outputs=result_final
            )
        )
    return command_results


def check_file_against_trusted_file_registry_by_hash_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    hashes = ResolveString(args.get("Hashes")).split(",")
    response = client.check_file_against_trusted_file_registry_by_hash(hashes=hashes)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.TrustedFileRegistry.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "hash",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(
                readable_output=result, outputs_prefix="CimTrak.TrustedFileRegistry", outputs_key_field="id", outputs=result_final
            )
        )
    return command_results


def promote_authoritative_baseline_files_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    object_detail_ids = ResolveString(args.get("ObjectDetaildIds")).split(",")
    response = client.promote_authoritative_baseline_files(object_detail_ids=object_detail_ids)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.AuthoritizeBaseline.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "objectDetailId",
        "status",
        "errorCode",
        "errorDescription",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(
                readable_output=result, outputs_prefix="CimTrak.AuthoritizeBaseline", outputs_key_field="id", outputs=result_final
            )
        )
    return command_results


def demote_authoritative_baseline_files_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    object_detail_ids = ResolveString(args.get("ObjectDetaildIds")).split(",")
    response = client.demote_authoritative_baseline_files(object_detail_ids=object_detail_ids)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.AuthoritizeBaseline.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "objectDetailId",
        "status",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(
                readable_output=result, outputs_prefix="CimTrak.AuthoritizeBaseline", outputs_key_field="id", outputs=result_final
            )
        )
    return command_results


def update_task_disposition_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    task_id = int(ResolveString(args.get("taskId")))
    disposition = ResolveString(args.get("Disposition"))
    response = client.update_task_disposition(task_id=task_id, disposition=disposition)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.TaskDisposition.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "taskId",
        "status",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(
                readable_output=result, outputs_prefix="CimTrak.TaskDisposition", outputs_key_field="id", outputs=result_final
            )
        )
    return command_results


def get_tickets_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    response = client.get_tickets()
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.Ticket.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "id",
        "ticketNumber",
        "sentiment",
        "sentimenttypeid",
        "title",
        "description",
        "priority",
        "disposition",
        "creationDate",
        "createdByUser",
        "modificationDate",
        "modifiedByUser",
        "requiresAcknowledgement",
        "requiresConfirmation",
        "requiresAssessment",
        "startDate",
        "endDate",
        "autoPromote",
        "assignedToUserId",
        "assignedToUser",
        "assignedToGroupId",
        "assignedToGroup",
        "externalTicketNumber",
        "externalTicketType",
        "tasks",
        "comments",
        "events",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(readable_output=result, outputs_prefix="CimTrak.Ticket", outputs_key_field="id", outputs=result_final)
        )
    return command_results


def get_ticket_tasks_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    response = client.get_ticket_tasks()
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.TicketTask.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "id",
        "ticketId",
        "agentObjectId",
        "startDate",
        "endDate",
        "disposition",
        "creationDate",
        "createdByUserId",
        "modificationDate",
        "modifiedByUserId",
        "assignedToUserId",
        "assignedToGroupId",
        "assigneeDisposition",
        "ticketTitle",
        "description",
        "priority",
        "ticketDisposition",
        "ticketCreationDate",
        "ticketCreatedByUserId",
        "ticketModificationDate",
        "requiresAcknowledgement",
        "requiresConfirmation",
        "requiresAssessment",
        "ticketNumber",
        "agentName",
        "createdByUsername",
        "modifiedByUsername",
        "assigneeName",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(
                readable_output=result, outputs_prefix="CimTrak.TicketTask", outputs_key_field="id", outputs=result_final
            )
        )
    return command_results


def add_ticket_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    title = ResolveString(args.get("title"))
    priority = int(ResolveString(args.get("priority")))
    description = ResolveString(args.get("description"))
    start_date = ResolveString(args.get("startDate"))
    end_date = ResolveString(args.get("endDate"))
    external_ticket_number = ResolveString(args.get("externalTicketNumber"))
    external_ticket_type = ResolveString(args.get("externalTicketType"))
    auto_promote = ResolveBool(args.get("autoPromote"))
    disposition = ResolveString(args.get("disposition"))
    requires_acknowledgement = ResolveBool(args.get("requiresAcknowledgement"))
    requires_assessment = ResolveBool(args.get("requiresAssessment"))
    requires_confirmation = ResolveBool(args.get("requiresConfirmation"))
    assigned_to_user_id = int(ResolveString(args.get("assignedToUserId")))
    assigned_to_user = ResolveString(args.get("assignedToUser"))
    assigned_to_group_id = int(ResolveString(args.get("assignedToGroupId")))
    assigned_to_group = ResolveString(args.get("assignedToGroup"))
    response = client.add_ticket(
        title=title,
        priority=priority,
        description=description,
        start_date=start_date,
        end_date=end_date,
        external_ticket_number=external_ticket_number,
        external_ticket_type=external_ticket_type,
        auto_promote=auto_promote,
        disposition=disposition,
        requires_acknowledgement=requires_acknowledgement,
        requires_assessment=requires_assessment,
        requires_confirmation=requires_confirmation,
        assigned_to_user_id=assigned_to_user_id,
        assigned_to_user=assigned_to_user,
        assigned_to_group_id=assigned_to_group_id,
        assigned_to_group=assigned_to_group,
    )
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.Ticket.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "id",
        "ticketNumber",
        "sentiment",
        "sentimenttypeid",
        "title",
        "description",
        "priority",
        "disposition",
        "creationDate",
        "createdByUser",
        "modificationDate",
        "modifiedByUser",
        "requiresAcknowledgement",
        "requiresConfirmation",
        "requiresAssessment",
        "startDate",
        "endDate",
        "autoPromote",
        "assignedToUserId",
        "assignedToUser",
        "assignedToGroupId",
        "assignedToGroup",
        "externalTicketNumber",
        "externalTicketType",
        "tasks",
        "comments",
        "events",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(readable_output=result, outputs_prefix="CimTrak.Ticket", outputs_key_field="id", outputs=result_final)
        )
    return command_results


def update_ticket_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    ticket_id = int(ResolveString(args.get("ticketId")))
    title = ResolveString(args.get("title"))
    priority = int(ResolveString(args.get("priority")))
    description = ResolveString(args.get("description"))
    start_date = ResolveString(args.get("startDate"))
    end_date = ResolveString(args.get("endDate"))
    external_ticket_number = ResolveString(args.get("externalTicketNumber"))
    external_ticket_type = ResolveString(args.get("externalTicketType"))
    auto_promote = ResolveBool(args.get("autoPromote"))
    disposition = ResolveString(args.get("disposition"))
    requires_acknowledgement = ResolveBool(args.get("requiresAcknowledgement"))
    requires_assessment = ResolveBool(args.get("requiresAssessment"))
    requires_confirmation = ResolveBool(args.get("requiresConfirmation"))
    assigned_to_user_id = int(ResolveString(args.get("assignedToUserId")))
    assigned_to_user = ResolveString(args.get("assignedToUser"))
    assigned_to_group_id = int(ResolveString(args.get("assignedToGroupId")))
    assigned_to_group = ResolveString(args.get("assignedToGroup"))
    response = client.update_ticket(
        ticket_id=ticket_id,
        title=title,
        priority=priority,
        description=description,
        start_date=start_date,
        end_date=end_date,
        external_ticket_number=external_ticket_number,
        external_ticket_type=external_ticket_type,
        auto_promote=auto_promote,
        disposition=disposition,
        requires_acknowledgement=requires_acknowledgement,
        requires_assessment=requires_assessment,
        requires_confirmation=requires_confirmation,
        assigned_to_user_id=assigned_to_user_id,
        assigned_to_user=assigned_to_user,
        assigned_to_group_id=assigned_to_group_id,
        assigned_to_group=assigned_to_group,
    )
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.Ticket.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "id",
        "ticketNumber",
        "sentiment",
        "sentimenttypeid",
        "title",
        "description",
        "priority",
        "disposition",
        "creationDate",
        "createdByUser",
        "modificationDate",
        "modifiedByUser",
        "requiresAcknowledgement",
        "requiresConfirmation",
        "requiresAssessment",
        "startDate",
        "endDate",
        "autoPromote",
        "assignedToUserId",
        "assignedToUser",
        "assignedToGroupId",
        "assignedToGroup",
        "externalTicketNumber",
        "externalTicketType",
        "tasks",
        "comments",
        "events",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(readable_output=result, outputs_prefix="CimTrak.Ticket", outputs_key_field="id", outputs=result_final)
        )
    return command_results


def add_ticket_comment_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    ticket_id = int(ResolveString(args.get("ticketId")))
    comment = ResolveString(args.get("comment"))
    response = client.add_ticket_comment(ticket_id=ticket_id, comment=comment)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.Ticket.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    return command_results


def add_hash_allow_list_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    hash = ResolveString(args.get("hash"))
    filename = ResolveString(args.get("filename"))
    source = ResolveString(args.get("source"))
    source_reference = ResolveString(args.get("sourceReference"))
    response = client.add_hash_allow_list(hash=hash, filename=filename, source=source, source_reference=source_reference)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.AllowList.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "status",
        "errorCode",
        "errorDescription",
        "hash",
        "tagId",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(
                readable_output=result, outputs_prefix="CimTrak.AllowList", outputs_key_field="id", outputs=result_final
            )
        )
    return command_results


def add_hash_deny_list_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    hash = ResolveString(args.get("hash"))
    filename = ResolveString(args.get("filename"))
    source = ResolveString(args.get("source"))
    source_reference = ResolveString(args.get("sourceReference"))
    response = client.add_hash_deny_list(hash=hash, filename=filename, source=source, source_reference=source_reference)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.DenyList.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "status",
        "errorCode",
        "errorDescription",
        "hash",
        "tagId",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(
                readable_output=result, outputs_prefix="CimTrak.DenyList", outputs_key_field="id", outputs=result_final
            )
        )
    return command_results


def delete_hash_allow_list_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    hash = ResolveString(args.get("hash"))
    reason = ResolveString(args.get("reason"))
    response = client.delete_hash_allow_list(hash=hash, reason=reason)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.AllowList.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "status",
        "hash",
        "tagId",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(
                readable_output=result, outputs_prefix="CimTrak.AllowList", outputs_key_field="id", outputs=result_final
            )
        )
    return command_results


def delete_hash_deny_list_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    hash = ResolveString(args.get("hash"))
    reason = ResolveString(args.get("reason"))
    response = client.delete_hash_deny_list(hash=hash, reason=reason)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.DenyList.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "status",
        "hash",
        "tagId",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(
                readable_output=result, outputs_prefix="CimTrak.DenyList", outputs_key_field="id", outputs=result_final
            )
        )
    return command_results


def get_sub_generations_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    object_id = int(ResolveString(args.get("objectId")))
    response = client.get_sub_generations(object_id=object_id)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.SubGenerations.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "caseSensitive",
        "agentObjectId",
        "subGenerationId",
        "objectId",
        "generationId",
        "subRevision",
        "notes",
        "creationDate",
        "files",
        "directories",
        "totalSize",
        "revision",
        "userName",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(
                readable_output=result, outputs_prefix="CimTrak.SubGenerations", outputs_key_field="id", outputs=result_final
            )
        )
    return command_results


def deploy_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    agent_object_id = int(ResolveString(args.get("agentObjectId")))
    sub_generation_id = int(ResolveString(args.get("subGenerationId")))
    notes = ResolveString(args.get("notes"))
    response = client.deploy(agent_object_id=agent_object_id, sub_generation_id=sub_generation_id, notes=notes)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.Deploy.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    return command_results


def get_object_group_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    object_id = int(ResolveString(args.get("objectId")))
    response = client.get_object_group(object_id=object_id)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.ObjectGroup.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "agentIsFilesystem",
        "cancel",
        "connected",
        "logsByDays",
        "requireNotes",
        "inService",
        "children",
        "events",
        "intrusions",
        "intrusionSize",
        "objectId",
        "objectStatus",
        "objectSubType",
        "objectType",
        "parentId",
        "revisions",
        "templateId",
        "securityAdd",
        "securityEdit",
        "securityLock",
        "securityReport",
        "securityUnlock",
        "securityView",
        "warnMinutes",
        "contact",
        "createDate",
        "description",
        "location",
        "name",
        "objectPath",
        "url",
        "agentObjectId",
        "objectsCustom",
        "watchArray",
        "comparisonMethod",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(
                readable_output=result, outputs_prefix="CimTrak.ObjectGroup", outputs_key_field="id", outputs=result_final
            )
        )
    return command_results


def unlock_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    object_id = int(ResolveString(args.get("objectId")))
    response = client.unlock(object_id=object_id)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.Unlock.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    return command_results


def lock_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    object_id = int(ResolveString(args.get("objectId")))
    response = client.lock(object_id=object_id)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.Lock.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    return command_results


def get_object_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    object_id = int(ResolveString(args.get("objectId")))
    response = client.get_object(object_id=object_id)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.Object.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "agentIsFilesystem",
        "cancel",
        "connected",
        "logsByDays",
        "requireNotes",
        "inService",
        "children",
        "events",
        "intrusions",
        "intrusionSize",
        "objectId",
        "objectStatus",
        "objectSubType",
        "objectType",
        "parentId",
        "revisions",
        "templateId",
        "securityAdd",
        "securityEdit",
        "securityLock",
        "securityReport",
        "securityUnlock",
        "securityView",
        "warnMinutes",
        "contact",
        "createDate",
        "description",
        "location",
        "name",
        "objectPath",
        "url",
        "agentObjectId",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(readable_output=result, outputs_prefix="CimTrak.Object", outputs_key_field="id", outputs=result_final)
        )
    return command_results


def force_sync_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    object_id = int(ResolveString(args.get("objectId")))
    response = client.force_sync(object_id=object_id)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.Sync.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    return command_results


def view_file_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    object_detail_id = int(ResolveString(args.get("objectDetailId")))
    response = client.view_file(object_detail_id=object_detail_id)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.Sync.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "contents",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(readable_output=result, outputs_prefix="CimTrak.Sync", outputs_key_field="id", outputs=result_final)
        )
    return command_results


def run_report_by_name_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    name = ResolveString(args.get("name"))
    object_id = int(ResolveString(args.get("objectId")))
    report_parameter_values = ResolveJson(args.get("ReportParameters"))
    response = client.run_report_by_name(name=name, object_id=object_id, report_parameter_values=report_parameter_values)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.Sync.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "html",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(readable_output=result, outputs_prefix="CimTrak.Sync", outputs_key_field="id", outputs=result_final)
        )
    return command_results


def deploy_by_date_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    date = ResolveString(args.get("date"))
    object_id = int(ResolveString(args.get("objectId")))
    response = client.deploy_by_date(date=date, object_id=object_id)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.Deploy.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    return command_results


def get_current_compliance_items_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    object_id = int(ResolveString(args.get("ObjectId")))
    compliance_scan_id = int(ResolveString(args.get("ComplianceScanId")))
    response = client.get_current_compliance_items(object_id=object_id, compliance_scan_id=compliance_scan_id)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.ComplianceItems.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "objectid",
        "type",
        "name",
        "description",
        "scanstarttime",
        "scanendtime",
        "scanid",
        "compliancemappingid",
        "id",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(
                readable_output=result, outputs_prefix="CimTrak.ComplianceItems", outputs_key_field="id", outputs=result_final
            )
        )
    return command_results


def get_objects_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    object_type = int(ResolveString(args.get("ObjectType")))
    object_subtype = int(ResolveString(args.get("ObjectSubType")))
    parent_id = int(ResolveString(args.get("ParentId")))
    object_id = int(ResolveString(args.get("ObjectId")))
    object_path_and_name = ResolveString(args.get("ObjectPathAndName"))
    recursive = ResolveBool(args.get("Recursive"))
    response = client.get_objects(
        object_type=object_type,
        object_subtype=object_subtype,
        parent_id=parent_id,
        object_id=object_id,
        object_path_and_name=object_path_and_name,
        recursive=recursive,
    )
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.Objects.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "repositoryDisplayName",
        "connected",
        "agentObjectId",
        "description",
        "name",
        "objectPath",
        "agentIsFilesystem",
        "cancel",
        "logsByDays",
        "requireNotes",
        "inService",
        "events",
        "intrusions",
        "intrusionSize",
        "objectId",
        "objectStatus",
        "objectSubType",
        "objectType",
        "parentId",
        "revisions",
        "templateId",
        "securityAdd",
        "securityEdit",
        "securityLock",
        "securityReport",
        "securityUnlock",
        "securityView",
        "warnMinutes",
        "contact",
        "createDate",
        "location",
        "url",
        "parentName",
        "children",
        "agentVersion",
        "agentBuild",
        "agentOsVersion",
        "agentIp",
        "agentName",
        "agentInstalled",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(readable_output=result, outputs_prefix="CimTrak.Objects", outputs_key_field="id", outputs=result_final)
        )
    return command_results


def get_agent_info_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    object_id = int(ResolveString(args.get("ObjectId")))
    response = client.get_agent_info(object_id=object_id)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.AgentInfo.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "objectData",
        "objectsCustom",
        "agentData",
        "state",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(
                readable_output=result, outputs_prefix="CimTrak.AgentInfo", outputs_key_field="id", outputs=result_final
            )
        )
    return command_results


def get_compliance_archive_details_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    object_id = int(ResolveString(args.get("ObjectId")))
    compliance_scan_id = int(ResolveString(args.get("ComplianceScanId")))
    filter = ResolveJson(args.get("Filter"))
    start = int(ResolveString(args.get("Start")))
    end = int(ResolveString(args.get("End")))
    response = client.get_compliance_archive_details(
        object_id=object_id, compliance_scan_id=compliance_scan_id, filter=filter, start=start, end=end
    )
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.Compliance.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "testdate",
        "datatype",
        "scanid",
        "ipaddress",
        "lobjectid",
        "alternatesystemid",
        "agentuuid",
        "agentname",
        "objectpath",
        "benchmark",
        "profile",
        "test",
        "pass",
        "iswaived",
        "adjustedscore",
        "possiblescore",
        "rawscore",
        "weight",
        "testran",
        "remediation",
        "severity",
        "version",
        "rationale",
        "description",
        "assessment",
        "disposition",
        "conjunction",
        "negatatevalue",
        "comment",
        "controlversion",
        "controlnumber",
        "osversion",
        "personality",
        "objectid",
        "userId",
        "block",
        "bunlock",
        "bview",
        "bedit",
        "badd",
        "breports",
        "blogon",
        "isadmin",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(
                readable_output=result, outputs_prefix="CimTrak.Compliance", outputs_key_field="id", outputs=result_final
            )
        )
    return command_results


def get_compliance_archive_summary_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    object_id = int(ResolveString(args.get("ObjectId")))
    compliance_scan_id = int(ResolveString(args.get("ComplianceScanId")))
    filter = ResolveJson(args.get("Filter"))
    start = int(ResolveString(args.get("Start")))
    end = int(ResolveString(args.get("End")))
    response = client.get_compliance_archive_summary(
        object_id=object_id, compliance_scan_id=compliance_scan_id, filter=filter, start=start, end=end
    )
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.Compliance.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "testdate",
        "scanid",
        "ipaddress",
        "datatype",
        "alternatesystemid",
        "agentuuid",
        "agentname",
        "objectpath",
        "lobjectid",
        "benchmark",
        "profile",
        "totalfailcount",
        "totalpasscount",
        "totaltestsskipped",
        "totalwaivecount",
        "pass",
        "totaltestsran",
        "osversion",
        "personality",
        "userId",
        "objectid",
        "block",
        "bunlock",
        "bview",
        "bedit",
        "badd",
        "breports",
        "blogon",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(
                readable_output=result, outputs_prefix="CimTrak.Compliance", outputs_key_field="id", outputs=result_final
            )
        )
    return command_results


def compliance_scan_children_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    object_parent_id = int(ResolveString(args.get("objectParentId")))
    response = client.compliance_scan_children(object_parent_id=object_parent_id)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.Compliance.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    return command_results


def compliance_scan_with_summary_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    object_id = int(ResolveString(args.get("objectId")))
    retry_count = int(ResolveString(args.get("retryCount")))
    retry_seconds = int(ResolveString(args.get("retrySeconds")))
    response = client.compliance_scan_with_summary(object_id=object_id, retry_count=retry_count, retry_seconds=retry_seconds)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.Compliance.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "testdate",
        "scanid",
        "ipaddress",
        "datatype",
        "alternatesystemid",
        "agentuuid",
        "agentname",
        "objectpath",
        "lobjectid",
        "benchmark",
        "profile",
        "totalfailcount",
        "totalpasscount",
        "totaltestsskipped",
        "totalwaivecount",
        "pass",
        "totaltestsran",
        "osversion",
        "personality",
        "userId",
        "objectid",
        "block",
        "bunlock",
        "bview",
        "bedit",
        "badd",
        "breports",
        "blogon",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(
                readable_output=result, outputs_prefix="CimTrak.Compliance", outputs_key_field="id", outputs=result_final
            )
        )
    return command_results


def get_agent_object_id_by_alternate_system_id_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    alternate_system_id = ResolveString(args.get("alternateSystemId"))
    response = client.get_agent_object_id_by_alternate_system_id(alternate_system_id=alternate_system_id)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.Object.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "agentObjectId",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(readable_output=result, outputs_prefix="CimTrak.Object", outputs_key_field="id", outputs=result_final)
        )
    return command_results


def get_agent_object_by_name_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    agent_name = ResolveString(args.get("agentName"))
    response = client.get_agent_object_by_name(agent_name=agent_name)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.Object.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "agentIsFilesystem",
        "cancel",
        "connected",
        "logsByDays",
        "requireNotes",
        "inService",
        "children",
        "events",
        "intrusions",
        "intrusionSize",
        "objectId",
        "objectStatus",
        "objectSubType",
        "objectType",
        "parentId",
        "revisions",
        "templateId",
        "securityAdd",
        "securityEdit",
        "securityLock",
        "securityReport",
        "securityUnlock",
        "securityView",
        "warnMinutes",
        "contact",
        "createDate",
        "description",
        "location",
        "name",
        "objectPath",
        "url",
        "agentObjectId",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(readable_output=result, outputs_prefix="CimTrak.Object", outputs_key_field="id", outputs=result_final)
        )
    return command_results


def get_agent_object_by_alternate_id_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    alternate_system_id = ResolveString(args.get("alternateSystemId"))
    response = client.get_agent_object_by_alternate_id(alternate_system_id=alternate_system_id)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.Object.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "agentIsFilesystem",
        "cancel",
        "connected",
        "logsByDays",
        "requireNotes",
        "inService",
        "children",
        "events",
        "intrusions",
        "intrusionSize",
        "objectId",
        "objectStatus",
        "objectSubType",
        "objectType",
        "parentId",
        "revisions",
        "templateId",
        "securityAdd",
        "securityEdit",
        "securityLock",
        "securityReport",
        "securityUnlock",
        "securityView",
        "warnMinutes",
        "contact",
        "createDate",
        "description",
        "location",
        "name",
        "objectPath",
        "url",
        "agentObjectId",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(readable_output=result, outputs_prefix="CimTrak.Object", outputs_key_field="id", outputs=result_final)
        )
    return command_results


def get_agent_object_by_ip_command(client: Client, args: dict[str, Any]) -> list[CommandResults]:
    command_results: list[CommandResults] = []
    client.debug = 5
    ip = ResolveString(args.get("ip"))
    response = client.get_agent_object_by_ip(ip=ip)
    command_status = {
        "status": response["status"],
        "errorCode": response["errorCode"],
        "errorDescription": response["errorDescription"],
    }
    command_results.append(
        CommandResults(
            readable_output=response["status"] + " : " + response["errorDescription"],
            outputs_prefix="CimTrak.Object.CommandStatus",
            outputs_key_field="status",
            outputs=command_status,
        )
    )
    results = response["results"]
    result_final = {}
    keys = [
        "agentIsFilesystem",
        "cancel",
        "connected",
        "logsByDays",
        "requireNotes",
        "inService",
        "children",
        "events",
        "intrusions",
        "intrusionSize",
        "objectId",
        "objectStatus",
        "objectSubType",
        "objectType",
        "parentId",
        "revisions",
        "templateId",
        "securityAdd",
        "securityEdit",
        "securityLock",
        "securityReport",
        "securityUnlock",
        "securityView",
        "warnMinutes",
        "contact",
        "createDate",
        "description",
        "location",
        "name",
        "objectPath",
        "url",
        "agentObjectId",
    ]
    for result in results:
        for key in keys:
            result_final[key] = result.get(key, "")
        command_results.append(
            CommandResults(readable_output=result, outputs_prefix="CimTrak.Object", outputs_key_field="id", outputs=result_final)
        )
    return command_results


################################################################
# CimTrak Palo Alto Custom Functions End
################################################################


""" MAIN FUNCTION """


def main() -> None:
    """main function, parses params and runs command functions

    :return:
    :rtype:
    """
    api_key = demisto.params().get("apikey")

    # get the service API url
    base_url = demisto.params()["url"]
    # if your Client class inherits from BaseClient, SSL verification is
    # handled out of the box by it, just pass ``verify_certificate`` to
    # the Client constructor
    verify_certificate = not demisto.params().get("insecure", False)
    # How much time before the first fetch to retrieve incidents
    first_fetch_time = arg_to_datetime(
        arg=demisto.params().get("first_fetch", "3 days"),
        arg_name="First fetch time",
        required=True,
    )

    first_fetch_timestamp = int(first_fetch_time.timestamp()) if first_fetch_time else None
    # Using assert as a type guard (since first_fetch_time is always an int when required=True)
    assert isinstance(first_fetch_timestamp, int)

    demisto.debug(f"Command being called is {demisto.command()}")
    try:
        client = Client(base_url=base_url, verify=verify_certificate)
        Client.api_key = api_key
        Client.server = demisto.params().get("Repository URL")
        Client.port = demisto.params().get("Repository Port")

        if demisto.command() == "test-module":
            # This is the call made when pressing the integration Test button.
            result = test_module(client, first_fetch_timestamp)
            return_results(result)

        elif demisto.command() == "fetch-incidents":
            # Set and define the fetch incidents command to run after activated via integration settings.
            alert_status = demisto.params().get("alert_status", None)
            alert_type = demisto.params().get("alert_type", None)
            min_severity = demisto.params().get("min_severity", None)
            # Convert the argument to an int using helper function or set to MAX_INCIDENTS_TO_FETCH
            max_results = arg_to_number(
                arg=demisto.params().get("max_fetch"),
                arg_name="max_fetch",
                required=False,
            )
            if not max_results or max_results > MAX_INCIDENTS_TO_FETCH:
                max_results = MAX_INCIDENTS_TO_FETCH
            next_run, incidents = fetch_incidents(
                client=client,
                max_results=max_results,
                last_run=demisto.getLastRun(),  # getLastRun() gets the last run dict
                first_fetch_time=first_fetch_timestamp,
                alert_status=alert_status,
                min_severity=min_severity,
                alert_type=alert_type,
            )
            # saves next_run for the time fetch-incidents is invoked
            demisto.setLastRun(next_run)
            # fetch-incidents calls ``demisto.incidents()`` to provide the list
            # of incidents to create
            demisto.incidents(incidents)
        ################################################################
        # CimTrak Palo Alto Custom Functions Dispatch Begin
        ################################################################
        elif demisto.command() == "get-events":
            return_results(get_events_command(client, demisto.args()))
        elif demisto.command() == "file-analysis-by-hash":
            return_results(file_analysis_by_hash_command(client, demisto.args()))
        elif demisto.command() == "file-analysis-by-objectdetail-id":
            return_results(file_analysis_by_object_detail_id_command(client, demisto.args()))
        elif demisto.command() == "check-file-against-trusted-file-registry-by-hash":
            return_results(check_file_against_trusted_file_registry_by_hash_command(client, demisto.args()))
        elif demisto.command() == "promote-authoritative-baseline-files":
            return_results(promote_authoritative_baseline_files_command(client, demisto.args()))
        elif demisto.command() == "demote-authoritative-baseline-files":
            return_results(demote_authoritative_baseline_files_command(client, demisto.args()))
        elif demisto.command() == "update-task-disposition":
            return_results(update_task_disposition_command(client, demisto.args()))
        elif demisto.command() == "get-tickets":
            return_results(get_tickets_command(client, demisto.args()))
        elif demisto.command() == "get-ticket-tasks":
            return_results(get_ticket_tasks_command(client, demisto.args()))
        elif demisto.command() == "add-ticket":
            return_results(add_ticket_command(client, demisto.args()))
        elif demisto.command() == "update-ticket":
            return_results(update_ticket_command(client, demisto.args()))
        elif demisto.command() == "add-ticket-comment":
            return_results(add_ticket_comment_command(client, demisto.args()))
        elif demisto.command() == "add-hash-allow-list":
            return_results(add_hash_allow_list_command(client, demisto.args()))
        elif demisto.command() == "add-hash-deny-list":
            return_results(add_hash_deny_list_command(client, demisto.args()))
        elif demisto.command() == "delete-hash-allow-list":
            return_results(delete_hash_allow_list_command(client, demisto.args()))
        elif demisto.command() == "delete-hash-deny-list":
            return_results(delete_hash_deny_list_command(client, demisto.args()))
        elif demisto.command() == "get-sub-generations":
            return_results(get_sub_generations_command(client, demisto.args()))
        elif demisto.command() == "deploy":
            return_results(deploy_command(client, demisto.args()))
        elif demisto.command() == "get-object-group":
            return_results(get_object_group_command(client, demisto.args()))
        elif demisto.command() == "unlock":
            return_results(unlock_command(client, demisto.args()))
        elif demisto.command() == "lock":
            return_results(lock_command(client, demisto.args()))
        elif demisto.command() == "get-object":
            return_results(get_object_command(client, demisto.args()))
        elif demisto.command() == "force-sync":
            return_results(force_sync_command(client, demisto.args()))
        elif demisto.command() == "view-file":
            return_results(view_file_command(client, demisto.args()))
        elif demisto.command() == "run-report-by-name":
            return_results(run_report_by_name_command(client, demisto.args()))
        elif demisto.command() == "deploy-by-date":
            return_results(deploy_by_date_command(client, demisto.args()))
        elif demisto.command() == "get-current-compliance-items":
            return_results(get_current_compliance_items_command(client, demisto.args()))
        elif demisto.command() == "get-objects":
            return_results(get_objects_command(client, demisto.args()))
        elif demisto.command() == "get-agent-info":
            return_results(get_agent_info_command(client, demisto.args()))
        elif demisto.command() == "get-compliance-archive-details":
            return_results(get_compliance_archive_details_command(client, demisto.args()))
        elif demisto.command() == "get-compliance-archive-summary":
            return_results(get_compliance_archive_summary_command(client, demisto.args()))
        elif demisto.command() == "compliance-scan-children":
            return_results(compliance_scan_children_command(client, demisto.args()))
        elif demisto.command() == "compliance-scan-with-summary":
            return_results(compliance_scan_with_summary_command(client, demisto.args()))
        elif demisto.command() == "get-agent-object-id-by-alternate-system-id":
            return_results(get_agent_object_id_by_alternate_system_id_command(client, demisto.args()))
        elif demisto.command() == "get-agent-object-by-name":
            return_results(get_agent_object_by_name_command(client, demisto.args()))
        elif demisto.command() == "get-agent-object-by-alternate-id":
            return_results(get_agent_object_by_alternate_id_command(client, demisto.args()))
        elif demisto.command() == "get-agent-object-by-ip":
            return_results(get_agent_object_by_ip_command(client, demisto.args()))
        ################################################################
        # CimTrak Palo Alto Custom Functions Dispatch End
        ################################################################
    ######

    # Log exceptions and return errors
    except Exception as e:
        demisto.error(traceback.format_exc())  # print the traceback
        return_error(f"Failed to execute {demisto.command()} command.\nError:\n{e!s}")


""" ENTRY POINT """

if __name__ in ("__main__", "__builtin__", "builtins"):
    main()