QuestKace

Use the Comprehensive Quest KACE solution to Provision, manage, secure, and service all network-connected devices.

Case Management · Quest Kace

Details

IDQuestKace
ProviderQuest Software
CategoryCase Management
From Version5.0.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix XSIAM

README

This is the Quest KACE integration.
This integration was integrated and tested with version v10.0.290 of QuestKace

Limitations

For kace-ticket-create and kace-ticket-update, When the queue_id is not the default:
Status,Category,Priority,Impact - values from the option list might cause an error as they correspond to different values.
If a value not from the list will be inserted - This value will pass to the API as is.
e.g. kace-ticket-create status=”Opened” impact=13 Priority=25

Tickets custom fields will not be returned in the kace-tickets-list command and not in fetch incidents due to API limitation.

Custom fields of tickets are represented by their custom number and not but their display name. e.g. For custom field: custom_1 with display name: date, the command should be !kace-ticket-create custom_fields=custom_1=testfromdemisto

Configure QuestKace in Cortex

Parameter Description Required
url Quest KACE URL, in the format: https://company.works.com/ True
credentials Username True
isFetch Fetch incidents False
fetch_time First fetch time range (<number> <time unit>, e.g., 1 hour, 30 minutes) False
fetch_shaping Shaping query parameter for tickets False
fetch_filter Filter for the tickets False
fetch_limit Fetch limit per query False
fetch_queue_id Queue number for fetch query False
incidentType Incident type False
insecure Trust any certificate (not secure) False
proxy Use system proxy settings False

Commands

You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.

kace-machines-list


Returns a list of all machines in system.

Base Command

kace-machines-list

Input

Argument Name Description Required
limit The maximum number of machines to return. The default value is 50. Optional
custom_filter Filter for the query. Each filter is specified by an optional entity name, a field name, an
operator, and a value. e.g. “title eq test” / “id gt 1 / hd_queue_id in 1;2;3” . Combination of filters is seperated by comma.
Optional

Context Output

Path Type Description
QuestKace.Machine.ID String ID of machine
QuestKace.Machine.Modified String Last modified date of the machine.
QuestKace.Machine.Created String Created date of the machine in KACE system.
QuestKace.Machine.User String User of the machine.
QuestKace.Machine.Name String Name of the machine.
QuestKace.Machine.IP String IP address of the machine.
QuestKace.Machine.OSName String OS name of the machine.
QuestKace.Machine.OSNumber String Number of operating systems of the machine.
QuestKace.Machine.LastInventory String Last inventory date of the machine.
QuestKace.Machine.LastSync String Last sync date of the machine.
QuestKace.Machine.RamTotal String Total RAM of the machine in bytes.
QuestKace.Machine.RamUsed String Used RAM of the machine.
QuestKace.Machine.RamMax String Maximum RAM of the machine.
QuestKace.Machine.BiosIdentificationCode String BIOS identification code of the machine.
QuestKace.Machine.SoundDevices String Connected sound devices of the machine.
QuestKace.Machine.CdromDevices String Connected CD-ROM devices to the machine.
QuestKace.Machine.VideoControllers String Video controllers of the machine.
QuestKace.Machine.Monitor String Monitor of the machine.
QuestKace.Machine.RegistrySize String Registry size of the machine.
QuestKace.Machine.RegistryMaxSize String Maximum size of the registry of the machine.
QuestKace.Machine.PagefileSize String Size of the page file of the machine.
QuestKace.Machine.PagefileMaxSize String Maximum size of the page file of the machine.
QuestKace.Machine.ManualEntry String Number of manual entries to the machine.

Command Example

!kace-machines-list custom_filter="id gt 1"

Context Example

{
    "QuestKace": {
        "Machine": null
    }
}

Human Readable Output

Quest Kace Machines

No entries.

kace-assets-list


Returns a list of all assets in Quest KACE.

Base Command

kace-assets-list

Input

Argument Name Description Required
limit The maximum number of assets to return. The default value is 50. Optional
custom_filter Filter for the query. Each filter is specified by an optional entity name, a field name, an
operator, and a value. e.g. “title eq test” / “id gt 1 / hd_queue_id in 1;2;3” . Combination of filters is seperated by comma.
Optional

Context Output

Path Type Description
QuestKace.Asset.ID Number ID of the asset.
QuestKace.Asset.AssetTypeID Number Type ID of the asset.
QuestKace.Asset.Name String Name of the asset.
QuestKace.Asset.AssetDataID Number Data ID of the asset.
QuestKace.Asset.OwnerID Number Owner ID of the asset.
QuestKace.Asset.Modified String Last modified date of the asset.
QuestKace.Asset.Created String Created date of the asset.
QuestKace.Asset.MappedID Number Mapped ID of the asset.
QuestKace.Asset.AssetClassID Number Class ID of the asset.
QuestKace.Asset.Archieve String Archive of the asset.
QuestKace.Asset.AssetStatusID Number Status ID of the asset.
QuestKace.Asset.AssetTypeName String Type name of the asset.

Command Example

!kace-assets-list custom_filter="name eq Mac"

Context Example

{
    "QuestKace": {
        "Asset": {
            "Archive": "",
            "AssetClassID": 10000,
            "AssetDataID": 1,
            "AssetStatusID": 0,
            "AssetSubtypeName": "Laser Printer: Color",
            "AssetTypeID": 5,
            "AssetTypeName": "Device",
            "Created": "2020-06-09 03:57:30",
            "ID": 2,
            "MappedID": 0,
            "Modified": "2020-06-09 03:57:30",
            "Name": "Mac",
            "OwnerID": 0
        }
    }
}

Human Readable Output

Quest Kace Assets

ID Name Created Modified OwnerID MappedID AssetClassID AssetDataID AssetStatusID AssetTypeID AssetTypeName
2 Mac 2020-06-09 03:57:30 2020-06-09 03:57:30 0 0 10000 1 0 5 Device

kace-queues-list


Returns a list of all queues in Quest KACE.

Base Command

kace-queues-list

Input

Argument Name Description Required
limit The maximum number of tickets to return. The default value is 50. Optional
custom_filter Filter for the query. Each filter is specified by an optional entity name, a field name, an
operator, and a value. e.g. “title eq test” / “id gt 1 / hd_queue_id in 1;2;3” . Combination of filters is seperated by comma.
Optional

Context Output

Path Type Description
QuestKace.Queue.ID Number ID of the queue.
QuestKace.Queue.Name String Name of the queue.
QuestKace.Queue.Field.ID Number ID of the field of the queue.
QuestKace.Queue.Field.HdQueueID Number Queue ID of the field.
QuestKace.Queue.Field.Name String Name of the field.
QuestKace.Queue.Field.HdTicketFieldName String View field name.
QuestKace.Queue.Field.Ordinal Number Ordinal of the field.
QuestKace.Queue.Field.RequiredState String Required state of the field, if exists.
QuestKace.Queue.Field.FieldLabel String Field label.
QuestKace.Queue.Field.Visible String Visibility of the field.

Command Example

!kace-queues-list custom_filter="id neq 1"

Context Example

{
    "QuestKace": {
        "Queue": {
            "Fields": [
                {
                    "FieldLabel": "Please tell us about your recent help desk experience",
                    "HdQueueID": 3,
                    "HdTicketFieldName": "sat_survey",
                    "ID": 36,
                    "Name": "SAT_SURVEY",
                    "Ordinal": 0,
                    "RequiredState": "none",
                    "Visible": "usermodify"
                },
                {
                    "FieldLabel": "Title",
                    "HdQueueID": 3,
                    "HdTicketFieldName": "title",
                    "ID": 37,
                    "Name": "TITLE",
                    "Ordinal": 1,
                    "RequiredState": "all",
                    "Visible": "usercreate"
                },
                {
                    "FieldLabel": "Summary",
                    "HdQueueID": 3,
                    "HdTicketFieldName": "summary",
                    "ID": 38,
                    "Name": "SUMMARY",
                    "Ordinal": 2,
                    "RequiredState": "none",
                    "Visible": "usercreate"
                },
                {
                    "FieldLabel": "Impact",
                    "HdQueueID": 3,
                    "HdTicketFieldName": "impact_id",
                    "ID": 39,
                    "Name": "IMPACT",
                    "Ordinal": 3,
                    "RequiredState": "none",
                    "Visible": "usercreate"
                },
                {
                    "FieldLabel": "Category",
                    "HdQueueID": 3,
                    "HdTicketFieldName": "category_id",
                    "ID": 40,
                    "Name": "CATEGORY",
                    "Ordinal": 4,
                    "RequiredState": "none",
                    "Visible": "usercreate"
                },
                {
                    "FieldLabel": "Status",
                    "HdQueueID": 3,
                    "HdTicketFieldName": "status_id",
                    "ID": 41,
                    "Name": "STATUS",
                    "Ordinal": 5,
                    "RequiredState": "none",
                    "Visible": "uservisible"
                },
                {
                    "FieldLabel": "Priority",
                    "HdQueueID": 3,
                    "HdTicketFieldName": "priority_id",
                    "ID": 42,
                    "Name": "PRIORITY",
                    "Ordinal": 6,
                    "RequiredState": "none",
                    "Visible": "uservisible"
                },
                {
                    "FieldLabel": "Owner",
                    "HdQueueID": 3,
                    "HdTicketFieldName": "owner_id",
                    "ID": 43,
                    "Name": "OWNER",
                    "Ordinal": 7,
                    "RequiredState": "none",
                    "Visible": "uservisible"
                },
                {
                    "FieldLabel": "Device",
                    "HdQueueID": 3,
                    "HdTicketFieldName": "machine_id",
                    "ID": 44,
                    "Name": "MACHINE",
                    "Ordinal": 8,
                    "RequiredState": "none",
                    "Visible": "uservisible"
                },
                {
                    "FieldLabel": "Asset",
                    "HdQueueID": 3,
                    "HdTicketFieldName": "asset_id",
                    "ID": 45,
                    "Name": "ASSET",
                    "Ordinal": 9,
                    "RequiredState": "none",
                    "Visible": "uservisible"
                },
                {
                    "FieldLabel": "Due Date",
                    "HdQueueID": 3,
                    "HdTicketFieldName": "due_date",
                    "ID": 61,
                    "Name": "DUE_DATE",
                    "Ordinal": 25,
                    "RequiredState": "none",
                    "Visible": "userhidden"
                },
                {
                    "FieldLabel": "CC List",
                    "HdQueueID": 3,
                    "HdTicketFieldName": "cc_list",
                    "ID": 62,
                    "Name": "CC_LIST",
                    "Ordinal": 26,
                    "RequiredState": "none",
                    "Visible": "userhidden"
                },
                {
                    "FieldLabel": "Created",
                    "HdQueueID": 3,
                    "ID": 63,
                    "Name": "CREATED",
                    "Ordinal": 27,
                    "RequiredState": "none",
                    "Visible": "uservisible"
                },
                {
                    "FieldLabel": "Modified",
                    "HdQueueID": 3,
                    "ID": 64,
                    "Name": "MODIFIED",
                    "Ordinal": 28,
                    "RequiredState": "none",
                    "Visible": "uservisible"
                },
                {
                    "FieldLabel": "Submitter",
                    "HdQueueID": 3,
                    "HdTicketFieldName": "submitter_id",
                    "ID": 65,
                    "Name": "SUBMITTER",
                    "Ordinal": 29,
                    "RequiredState": "none",
                    "Visible": "usercreate"
                },
                {
                    "FieldLabel": "See Also",
                    "HdQueueID": 3,
                    "HdTicketFieldName": "related_ticket_ids",
                    "ID": 68,
                    "Name": "SEE_ALSO",
                    "Ordinal": 32,
                    "RequiredState": "none",
                    "Visible": "userhidden"
                },
                {
                    "FieldLabel": "Referrers",
                    "HdQueueID": 3,
                    "ID": 69,
                    "Name": "REFERRERS",
                    "Ordinal": 33,
                    "RequiredState": "none",
                    "Visible": "userhidden"
                },
                {
                    "FieldLabel": "Resolution",
                    "HdQueueID": 3,
                    "HdTicketFieldName": "resolution",
                    "ID": 70,
                    "Name": "RESOLUTION",
                    "Ordinal": 34,
                    "RequiredState": "none",
                    "Visible": "uservisible"
                }
            ],
            "ID": 3,
            "Name": "New Queue 2"
        }
    }
}

Human Readable Output

Quest Kace Queues

ID Name Fields
3 New Queue 2 {‘ID’: 36, ‘HdQueueID’: 3, ‘Name’: ‘SAT_SURVEY’, ‘HdTicketFieldName’: ‘sat_survey’, ‘Ordinal’: 0, ‘RequiredState’: ‘none’, ‘FieldLabel’: ‘Please tell us about your recent help desk experience’, ‘Visible’: ‘usermodify’},
{‘ID’: 37, ‘HdQueueID’: 3, ‘Name’: ‘TITLE’, ‘HdTicketFieldName’: ‘title’, ‘Ordinal’: 1, ‘RequiredState’: ‘all’, ‘FieldLabel’: ‘Title’, ‘Visible’: ‘usercreate’},
{‘ID’: 38, ‘HdQueueID’: 3, ‘Name’: ‘SUMMARY’, ‘HdTicketFieldName’: ‘summary’, ‘Ordinal’: 2, ‘RequiredState’: ‘none’, ‘FieldLabel’: ‘Summary’, ‘Visible’: ‘usercreate’},
{‘ID’: 39, ‘HdQueueID’: 3, ‘Name’: ‘IMPACT’, ‘HdTicketFieldName’: ‘impact_id’, ‘Ordinal’: 3, ‘RequiredState’: ‘none’, ‘FieldLabel’: ‘Impact’, ‘Visible’: ‘usercreate’},
{‘ID’: 40, ‘HdQueueID’: 3, ‘Name’: ‘CATEGORY’, ‘HdTicketFieldName’: ‘category_id’, ‘Ordinal’: 4, ‘RequiredState’: ‘none’, ‘FieldLabel’: ‘Category’, ‘Visible’: ‘usercreate’},
{‘ID’: 41, ‘HdQueueID’: 3, ‘Name’: ‘STATUS’, ‘HdTicketFieldName’: ‘status_id’, ‘Ordinal’: 5, ‘RequiredState’: ‘none’, ‘FieldLabel’: ‘Status’, ‘Visible’: ‘uservisible’},
{‘ID’: 42, ‘HdQueueID’: 3, ‘Name’: ‘PRIORITY’, ‘HdTicketFieldName’: ‘priority_id’, ‘Ordinal’: 6, ‘RequiredState’: ‘none’, ‘FieldLabel’: ‘Priority’, ‘Visible’: ‘uservisible’},
{‘ID’: 43, ‘HdQueueID’: 3, ‘Name’: ‘OWNER’, ‘HdTicketFieldName’: ‘owner_id’, ‘Ordinal’: 7, ‘RequiredState’: ‘none’, ‘FieldLabel’: ‘Owner’, ‘Visible’: ‘uservisible’},
{‘ID’: 44, ‘HdQueueID’: 3, ‘Name’: ‘MACHINE’, ‘HdTicketFieldName’: ‘machine_id’, ‘Ordinal’: 8, ‘RequiredState’: ‘none’, ‘FieldLabel’: ‘Device’, ‘Visible’: ‘uservisible’},
{‘ID’: 45, ‘HdQueueID’: 3, ‘Name’: ‘ASSET’, ‘HdTicketFieldName’: ‘asset_id’, ‘Ordinal’: 9, ‘RequiredState’: ‘none’, ‘FieldLabel’: ‘Asset’, ‘Visible’: ‘uservisible’},
{‘ID’: 61, ‘HdQueueID’: 3, ‘Name’: ‘DUE_DATE’, ‘HdTicketFieldName’: ‘due_date’, ‘Ordinal’: 25, ‘RequiredState’: ‘none’, ‘FieldLabel’: ‘Due Date’, ‘Visible’: ‘userhidden’},
{‘ID’: 62, ‘HdQueueID’: 3, ‘Name’: ‘CC_LIST’, ‘HdTicketFieldName’: ‘cc_list’, ‘Ordinal’: 26, ‘RequiredState’: ‘none’, ‘FieldLabel’: ‘CC List’, ‘Visible’: ‘userhidden’},
{‘ID’: 63, ‘HdQueueID’: 3, ‘Name’: ‘CREATED’, ‘Ordinal’: 27, ‘RequiredState’: ‘none’, ‘FieldLabel’: ‘Created’, ‘Visible’: ‘uservisible’},
{‘ID’: 64, ‘HdQueueID’: 3, ‘Name’: ‘MODIFIED’, ‘Ordinal’: 28, ‘RequiredState’: ‘none’, ‘FieldLabel’: ‘Modified’, ‘Visible’: ‘uservisible’},
{‘ID’: 65, ‘HdQueueID’: 3, ‘Name’: ‘SUBMITTER’, ‘HdTicketFieldName’: ‘submitter_id’, ‘Ordinal’: 29, ‘RequiredState’: ‘none’, ‘FieldLabel’: ‘Submitter’, ‘Visible’: ‘usercreate’},
{‘ID’: 68, ‘HdQueueID’: 3, ‘Name’: ‘SEE_ALSO’, ‘HdTicketFieldName’: ‘related_ticket_ids’, ‘Ordinal’: 32, ‘RequiredState’: ‘none’, ‘FieldLabel’: ‘See Also’, ‘Visible’: ‘userhidden’},
{‘ID’: 69, ‘HdQueueID’: 3, ‘Name’: ‘REFERRERS’, ‘Ordinal’: 33, ‘RequiredState’: ‘none’, ‘FieldLabel’: ‘Referrers’, ‘Visible’: ‘userhidden’},
{‘ID’: 70, ‘HdQueueID’: 3, ‘Name’: ‘RESOLUTION’, ‘HdTicketFieldName’: ‘resolution’, ‘Ordinal’: 34, ‘RequiredState’: ‘none’, ‘FieldLabel’: ‘Resolution’, ‘Visible’: ‘uservisible’}

kace-tickets-list


Returns a list of all tickets in Quest KACE.

Base Command

kace-tickets-list

Input

Argument Name Description Required
custom_shaping The shaping query parameter limits the amount of returned data is specified. The returned fields for each
associated entity is controlled by two query values. The first is the name of the entity, while the second half of the
pair is the associated level. e.g. “submitter all, asset limited”.
Optional
limit The maximum number of tickets to return. The default value is 50. Optional
custom_filter Filter for the query. Each filter is specified by an optional entity name, a field name, an
operator, and a value. e.g. “title eq test” / “id gt 1 / hd_queue_id in 1;2;3” . Combination of filters is seperated by comma.
Optional

Context Output

Path Type Description
QuestKace.Ticket.Submitter.ID Number Submitter id of the ticket.
QuestKace.Ticket.Submitter.UserName String Submitter user name of the ticket.
QuestKace.Ticket.Submitter.Email String Email address of user that submitted the email.
QuestKace.Ticket.Submitter.FullName String Full name of the user that submitted the ticket.
QuestKace.Ticket.Asset.ID Number ID of the asset of the ticket.
QuestKace.Ticket.Asset.AssetTypeId Number Asset type ID of the ticket.
QuestKace.Ticket.Asset.Name String Name of the asset of the ticket.
QuestKace.Ticket.Asset.OwnerId Number Owner ID of the asset of the ticket.
QuestKace.Ticket.Asset.AssetClassId Number Asset class id of the ticket.
QuestKace.Ticket.Machine.ID Number ID of the machine of the ticket.
QuestKace.Ticket.Machine.Name String Name of the machine of the ticket.
QuestKace.Ticket.Priority.ID Number Priority id of the ticket.
QuestKace.Ticket.Priority.Name String Priority name of the ticket.
QuestKace.Ticket.Priority.Ordinal Number Priority ordinal of the ticket.
QuestKace.Ticket.Priority.Color String Priority color of the ticket.
QuestKace.Ticket.Priority.IsSlaEnable Number Whether SLA is enabled on the priority of the ticket.
QuestKace.Ticket.Category.ID Number Category ID of the ticket.
QuestKace.Ticket.Category.Name String Category name of the ticket.
QuestKace.Ticket.Impact.ID Number ID of the impact of the ticket.
QuestKace.Ticket.Impact.Ordinal Number Ordinal of the impact of the ticket.
QuestKace.Ticket.Impact.Name String Name of the impact of the ticket.
QuestKace.Ticket.Status.ID Number ID of the status of the ticket.
QuestKace.Ticket.Status.Name String Name of the status of the tickets.
QuestKace.Ticket.Status.Ordinal Number Ordinal of the status of the ticket.
QuestKace.Ticket.Status.State String State of the status of the ticket.
QuestKace.Ticket.ID Number ID of the ticket.
QuestKace.Ticket.Title String Title of the ticket.
QuestKace.Ticket.Summary String Summary of the ticket.
QuestKace.Ticket.Modified String Last modified date of the ticket.
QuestKace.Ticket.Created String Created date of the ticket.
QuestKace.Ticket.HdQueueID Number Queue number that the ticket is related to.
QuestKace.Ticket.CcList String CC list of the ticket.
QuestKace.Ticket.IsManualDueDate Number Whether the due date is manual.
QuestKace.Ticket.Resolution String Resolution of the ticket.
QuestKace.Ticket.DueDate String Dua date of the ticket.

Command Example

!kace-tickets-list custom_shaping="hd_ticket all,submitter limited,owner limited, asset limited,machine limited,priority limited,category limited, impact limited,status limited"

Context Example

{
    "QuestKace": {
        "Ticket": [
            {
                "Category": {
                    "ID": 2,
                    "Name": "Other"
                },
                "CcList": "",
                "Created": "2020-05-19 05:54:42",
                "DueDate": "0000-00-00 00:00:00",
                "HdQueueID": 1,
                "ID": 11,
                "Impact": {
                    "ID": 1,
                    "Name": "1 person cannot work",
                    "Ordinal": 2
                },
                "IsDeleted": false,
                "IsManualDueDate": 0,
                "Modified": "2020-05-19 05:54:42",
                "Priority": {
                    "Color": "",
                    "ID": 1,
                    "IsSlaEnabled": 0,
                    "Name": "Medium",
                    "Ordinal": 1
                },
                "Resolution": "",
                "Status": {
                    "ID": 4,
                    "Name": "New",
                    "Ordinal": 0,
                    "State": "stalled"
                },
                "Summary": "",
                "Title": "Untitled"
            },
            {
                "Category": {
                    "ID": 2,
                    "Name": "Other"
                },
                "CcList": "",
                "Created": "2020-05-19 05:55:43",
                "DueDate": "0000-00-00 00:00:00",
                "HdQueueID": 1,
                "ID": 12,
                "Impact": {
                    "ID": 1,
                    "Name": "1 person cannot work",
                    "Ordinal": 2
                },
                "IsDeleted": false,
                "IsManualDueDate": 0,
                "Modified": "2020-05-19 05:55:43",
                "Priority": {
                    "Color": "",
                    "ID": 1,
                    "IsSlaEnabled": 0,
                    "Name": "Medium",
                    "Ordinal": 1
                },
                "Resolution": "",
                "Status": {
                    "ID": 4,
                    "Name": "New",
                    "Ordinal": 0,
                    "State": "stalled"
                },
                "Summary": "",
                "Title": "test num 2 from demisto"
            },
            {
                "Category": {
                    "ID": 2,
                    "Name": "Other"
                },
                "CcList": "",
                "Created": "2020-05-19 05:56:08",
                "HdQueueID": 1,
                "ID": 13,
                "Impact": {
                    "ID": 1,
                    "Name": "1 person cannot work",
                    "Ordinal": 2
                },
                "IsDeleted": false,
                "IsManualDueDate": 0,
                "Modified": "2020-05-19 06:16:17",
                "Priority": {
                    "Color": "",
                    "ID": 1,
                    "IsSlaEnabled": 0,
                    "Name": "Medium",
                    "Ordinal": 1
                },
                "Resolution": "",
                "Status": {
                    "ID": 2,
                    "Name": "Closed",
                    "Ordinal": 3,
                    "State": "closed"
                },
                "Summary": "",
                "Title": "test num 4 from demisto"
            },
            {
                "Category": {
                    "ID": 2,
                    "Name": "Other"
                },
                "CcList": "",
                "Created": "2020-05-19 06:15:48",
                "DueDate": "0000-00-00 00:00:00",
                "HdQueueID": 1,
                "ID": 14,
                "Impact": {
                    "ID": 1,
                    "Name": "1 person cannot work",
                    "Ordinal": 2
                },
                "IsDeleted": false,
                "IsManualDueDate": 0,
                "Modified": "2020-05-19 06:15:48",
                "Priority": {
                    "Color": "",
                    "ID": 1,
                    "IsSlaEnabled": 0,
                    "Name": "Medium",
                    "Ordinal": 1
                },
                "Resolution": "",
                "Status": {
                    "ID": 2,
                    "Name": "Closed",
                    "Ordinal": 3,
                    "State": "closed"
                },
                "Summary": "dont know",
                "Title": "test num 3 from demisto"
            },
            {
                "Category": {
                    "ID": 2,
                    "Name": "Other"
                },
                "CcList": "",
                "Created": "2020-05-19 07:01:12",
                "DueDate": "0000-00-00 00:00:00",
                "HdQueueID": 1,
                "ID": 15,
                "Impact": {
                    "ID": 1,
                    "Name": "1 person cannot work",
                    "Ordinal": 2
                },
                "IsDeleted": false,
                "IsManualDueDate": 0,
                "Modified": "2020-05-19 07:01:12",
                "Priority": {
                    "Color": "",
                    "ID": 1,
                    "IsSlaEnabled": 0,
                    "Name": "Medium",
                    "Ordinal": 1
                },
                "Resolution": "",
                "Status": {
                    "ID": 4,
                    "Name": "New",
                    "Ordinal": 0,
                    "State": "stalled"
                },
                "Submitter": {
                    "Email": "tmalache@example.com",
                    "FullName": "admin",
                    "ID": 10,
                    "UserName": "admin"
                },
                "Summary": "",
                "Title": "TestCustomFieldsUI"
            },
            {
                "Category": {
                    "ID": 3,
                    "Name": "Hardware"
                },
                "CcList": "",
                "Created": "2020-05-19 07:02:30",
                "DueDate": "0000-00-00 00:00:00",
                "HdQueueID": 1,
                "ID": 16,
                "Impact": {
                    "ID": 3,
                    "Name": "1 person inconvenienced",
                    "Ordinal": 3
                },
                "IsDeleted": false,
                "IsManualDueDate": 0,
                "Modified": "2020-05-19 07:02:30",
                "Priority": {
                    "Color": "gray",
                    "ID": 3,
                    "IsSlaEnabled": 0,
                    "Name": "Low",
                    "Ordinal": 2
                },
                "Resolution": "",
                "Status": {
                    "ID": 8,
                    "Name": "Waiting on Third Party",
                    "Ordinal": 7,
                    "State": "stalled"
                },
                "Summary": "just checking",
                "Title": "TATATA"
            },
            {
                "Category": {
                    "ID": 2,
                    "Name": "Other"
                },
                "CcList": "",
                "Created": "2020-05-19 07:03:30",
                "DueDate": "0000-00-00 00:00:00",
                "HdQueueID": 1,
                "ID": 17,
                "Impact": {
                    "ID": 1,
                    "Name": "1 person cannot work",
                    "Ordinal": 2
                },
                "IsDeleted": false,
                "IsManualDueDate": 0,
                "Modified": "2020-05-19 07:03:30",
                "Priority": {
                    "Color": "",
                    "ID": 1,
                    "IsSlaEnabled": 0,
                    "Name": "Medium",
                    "Ordinal": 1
                },
                "Resolution": "",
                "Status": {
                    "ID": 2,
                    "Name": "Closed",
                    "Ordinal": 3,
                    "State": "closed"
                },
                "Summary": "dont know",
                "Title": "test num 3 from demisto"
            },
            {
                "Category": {
                    "ID": 1,
                    "Name": "Network"
                },
                "CcList": "",
                "Created": "2020-06-09 03:52:25",
                "DueDate": "0000-00-00 00:00:00",
                "HdQueueID": 1,
                "ID": 23,
                "Impact": {
                    "ID": 1,
                    "Name": "1 person cannot work",
                    "Ordinal": 2
                },
                "IsDeleted": false,
                "IsManualDueDate": 0,
                "Modified": "2020-06-09 03:52:25",
                "Priority": {
                    "Color": "",
                    "ID": 1,
                    "IsSlaEnabled": 0,
                    "Name": "Medium",
                    "Ordinal": 1
                },
                "Resolution": "",
                "Status": {
                    "ID": 1,
                    "Name": "Opened",
                    "Ordinal": 1,
                    "State": "opened"
                },
                "Summary": "test of Quest Kace integration ticket create",
                "Title": "test1"
            },
            {
                "Category": {
                    "ID": 2,
                    "Name": "Other"
                },
                "CcList": "",
                "Created": "2020-06-09 03:55:07",
                "DueDate": "0000-00-00 00:00:00",
                "HdQueueID": 1,
                "ID": 24,
                "Impact": {
                    "ID": 1,
                    "Name": "1 person cannot work",
                    "Ordinal": 2
                },
                "IsDeleted": false,
                "IsManualDueDate": 0,
                "Modified": "2020-06-09 03:55:07",
                "Priority": {
                    "Color": "",
                    "ID": 1,
                    "IsSlaEnabled": 0,
                    "Name": "Medium",
                    "Ordinal": 1
                },
                "Resolution": "",
                "Status": {
                    "ID": 4,
                    "Name": "New",
                    "Ordinal": 0,
                    "State": "stalled"
                },
                "Submitter": {
                    "Email": "tmalache@example.com",
                    "FullName": "admin",
                    "ID": 10,
                    "UserName": "admin"
                },
                "Summary": "",
                "Title": "test"
            },
            {
                "Category": {
                    "ID": 1,
                    "Name": "Network"
                },
                "CcList": "",
                "Created": "2020-06-09 03:59:41",
                "DueDate": "0000-00-00 00:00:00",
                "HdQueueID": 1,
                "ID": 25,
                "Impact": {
                    "ID": 1,
                    "Name": "1 person cannot work",
                    "Ordinal": 2
                },
                "IsDeleted": false,
                "IsManualDueDate": 0,
                "Modified": "2020-06-09 03:59:41",
                "Priority": {
                    "Color": "",
                    "ID": 1,
                    "IsSlaEnabled": 0,
                    "Name": "Medium",
                    "Ordinal": 1
                },
                "Resolution": "",
                "Status": {
                    "ID": 1,
                    "Name": "Opened",
                    "Ordinal": 1,
                    "State": "opened"
                },
                "Summary": "test of Quest Kace integration ticket create",
                "Title": "test1"
            },
            {
                "Category": {
                    "ID": 1,
                    "Name": "Network"
                },
                "CcList": "",
                "Created": "2020-06-09 04:00:03",
                "DueDate": "0000-00-00 00:00:00",
                "HdQueueID": 1,
                "ID": 26,
                "Impact": {
                    "ID": 1,
                    "Name": "1 person cannot work",
                    "Ordinal": 2
                },
                "IsDeleted": false,
                "IsManualDueDate": 0,
                "Modified": "2020-06-09 04:00:03",
                "Priority": {
                    "Color": "",
                    "ID": 1,
                    "IsSlaEnabled": 0,
                    "Name": "Medium",
                    "Ordinal": 1
                },
                "Resolution": "",
                "Status": {
                    "ID": 1,
                    "Name": "Opened",
                    "Ordinal": 1,
                    "State": "opened"
                },
                "Summary": "test of Quest Kace integration ticket create",
                "Title": "test1"
            },
            {
                "Category": {
                    "ID": 1,
                    "Name": "Network"
                },
                "CcList": "",
                "Created": "2020-06-09 04:00:33",
                "DueDate": "0000-00-00 00:00:00",
                "HdQueueID": 1,
                "ID": 27,
                "Impact": {
                    "ID": 1,
                    "Name": "1 person cannot work",
                    "Ordinal": 2
                },
                "IsDeleted": false,
                "IsManualDueDate": 0,
                "Modified": "2020-06-09 04:00:33",
                "Priority": {
                    "Color": "",
                    "ID": 1,
                    "IsSlaEnabled": 0,
                    "Name": "Medium",
                    "Ordinal": 1
                },
                "Resolution": "",
                "Status": {
                    "ID": 1,
                    "Name": "Opened",
                    "Ordinal": 1,
                    "State": "opened"
                },
                "Summary": "test of Quest Kace integration ticket create",
                "Title": "test1"
            },
            {
                "Category": {
                    "ID": 1,
                    "Name": "Network"
                },
                "CcList": "",
                "Created": "2020-06-09 04:57:39",
                "DueDate": "0000-00-00 00:00:00",
                "HdQueueID": 1,
                "ID": 28,
                "Impact": {
                    "ID": 1,
                    "Name": "1 person cannot work",
                    "Ordinal": 2
                },
                "IsDeleted": false,
                "IsManualDueDate": 0,
                "Modified": "2020-06-09 04:57:39",
                "Priority": {
                    "Color": "",
                    "ID": 1,
                    "IsSlaEnabled": 0,
                    "Name": "Medium",
                    "Ordinal": 1
                },
                "Resolution": "",
                "Status": {
                    "ID": 1,
                    "Name": "Opened",
                    "Ordinal": 1,
                    "State": "opened"
                },
                "Summary": "test of Quest Kace integration ticket create",
                "Title": "test1"
            },
            {
                "Category": {
                    "ID": 3,
                    "Name": "Hardware"
                },
                "CcList": "",
                "Created": "2020-06-09 05:12:37",
                "DueDate": "0000-00-00 00:00:00",
                "HdQueueID": 1,
                "ID": 30,
                "Impact": {
                    "ID": 1,
                    "Name": "1 person cannot work",
                    "Ordinal": 2
                },
                "IsDeleted": false,
                "IsManualDueDate": 0,
                "Modified": "2020-06-09 05:12:37",
                "Priority": {
                    "Color": "red",
                    "ID": 2,
                    "IsSlaEnabled": 0,
                    "Name": "High",
                    "Ordinal": 0
                },
                "Resolution": "",
                "Status": {
                    "ID": 2,
                    "Name": "Closed",
                    "Ordinal": 3,
                    "State": "closed"
                },
                "Summary": "Test docs",
                "Title": "Test"
            },
            {
                "CcList": "",
                "Created": "2020-06-09 05:14:51",
                "DueDate": "0000-00-00 00:00:00",
                "HdQueueID": 1,
                "ID": 31,
                "IsDeleted": false,
                "IsManualDueDate": 0,
                "Modified": "2020-06-09 05:14:51",
                "Resolution": "",
                "Summary": "blah blah",
                "Title": "foo foo"
            },
            {
                "Category": {
                    "ID": 1,
                    "Name": "Network"
                },
                "CcList": "",
                "Created": "2020-06-09 05:18:10",
                "DueDate": "0000-00-00 00:00:00",
                "HdQueueID": 1,
                "ID": 33,
                "Impact": {
                    "ID": 1,
                    "Name": "1 person cannot work",
                    "Ordinal": 2
                },
                "IsDeleted": false,
                "IsManualDueDate": 0,
                "Modified": "2020-06-09 05:18:10",
                "Priority": {
                    "Color": "",
                    "ID": 1,
                    "IsSlaEnabled": 0,
                    "Name": "Medium",
                    "Ordinal": 1
                },
                "Resolution": "",
                "Status": {
                    "ID": 1,
                    "Name": "Opened",
                    "Ordinal": 1,
                    "State": "opened"
                },
                "Summary": "test of Quest Kace integration ticket create",
                "Title": "test1"
            },
            {
                "Category": {
                    "ID": 1,
                    "Name": "Network"
                },
                "CcList": "",
                "Created": "2020-06-09 05:19:13",
                "DueDate": "0000-00-00 00:00:00",
                "HdQueueID": 1,
                "ID": 34,
                "Impact": {
                    "ID": 1,
                    "Name": "1 person cannot work",
                    "Ordinal": 2
                },
                "IsDeleted": false,
                "IsManualDueDate": 0,
                "Modified": "2020-06-09 05:19:13",
                "Priority": {
                    "Color": "",
                    "ID": 1,
                    "IsSlaEnabled": 0,
                    "Name": "Medium",
                    "Ordinal": 1
                },
                "Resolution": "",
                "Status": {
                    "ID": 1,
                    "Name": "Opened",
                    "Ordinal": 1,
                    "State": "opened"
                },
                "Summary": "test of Quest Kace integration ticket create",
                "Title": "test1"
            },
            {
                "Category": {
                    "ID": 5,
                    "Name": "Software"
                },
                "CcList": "",
                "Created": "2020-06-09 05:11:59",
                "DueDate": "0000-00-00 00:00:00",
                "HdQueueID": 3,
                "ID": 29,
                "Impact": {
                    "ID": 7,
                    "Name": "1 person cannot work",
                    "Ordinal": 2
                },
                "IsDeleted": false,
                "IsManualDueDate": 0,
                "Modified": "2020-06-09 05:11:59",
                "Priority": {
                    "Color": "",
                    "ID": 5,
                    "IsSlaEnabled": 0,
                    "Name": "Medium",
                    "Ordinal": 1
                },
                "Resolution": "",
                "Status": {
                    "ID": 9,
                    "Name": "New",
                    "Ordinal": 0,
                    "State": "stalled"
                },
                "Submitter": {
                    "Email": "tmalache@example.com",
                    "FullName": "admin",
                    "ID": 10,
                    "UserName": "admin"
                },
                "Summary": "",
                "Title": "Tests"
            },
            {
                "CcList": "",
                "Created": "2020-06-09 05:14:55",
                "DueDate": "0000-00-00 00:00:00",
                "HdQueueID": 3,
                "ID": 32,
                "IsDeleted": false,
                "IsManualDueDate": 0,
                "Modified": "2020-06-09 05:14:55",
                "Resolution": "",
                "Summary": "blah blah",
                "Title": "foo foo"
            }
        ]
    }
}

Human Readable Output

Quest Kace Tickets

ID Title Created Modified HdQueueID DueDate
11 Untitled 2020-05-19 05:54:42 2020-05-19 05:54:42 1 0000-00-00 00:00:00
12 test num 2 from demisto 2020-05-19 05:55:43 2020-05-19 05:55:43 1 0000-00-00 00:00:00
13 test num 4 from demisto 2020-05-19 05:56:08 2020-05-19 06:16:17 1  
14 test num 3 from demisto 2020-05-19 06:15:48 2020-05-19 06:15:48 1 0000-00-00 00:00:00
15 TestCustomFieldsUI 2020-05-19 07:01:12 2020-05-19 07:01:12 1 0000-00-00 00:00:00
16 TATATA 2020-05-19 07:02:30 2020-05-19 07:02:30 1 0000-00-00 00:00:00
17 test num 3 from demisto 2020-05-19 07:03:30 2020-05-19 07:03:30 1 0000-00-00 00:00:00
23 test1 2020-06-09 03:52:25 2020-06-09 03:52:25 1 0000-00-00 00:00:00
24 test 2020-06-09 03:55:07 2020-06-09 03:55:07 1 0000-00-00 00:00:00
25 test1 2020-06-09 03:59:41 2020-06-09 03:59:41 1 0000-00-00 00:00:00
26 test1 2020-06-09 04:00:03 2020-06-09 04:00:03 1 0000-00-00 00:00:00
27 test1 2020-06-09 04:00:33 2020-06-09 04:00:33 1 0000-00-00 00:00:00
28 test1 2020-06-09 04:57:39 2020-06-09 04:57:39 1 0000-00-00 00:00:00
30 Test 2020-06-09 05:12:37 2020-06-09 05:12:37 1 0000-00-00 00:00:00
31 foo foo 2020-06-09 05:14:51 2020-06-09 05:14:51 1 0000-00-00 00:00:00
33 test1 2020-06-09 05:18:10 2020-06-09 05:18:10 1 0000-00-00 00:00:00
34 test1 2020-06-09 05:19:13 2020-06-09 05:19:13 1 0000-00-00 00:00:00
29 Tests 2020-06-09 05:11:59 2020-06-09 05:11:59 3 0000-00-00 00:00:00
32 foo foo 2020-06-09 05:14:55 2020-06-09 05:14:55 3 0000-00-00 00:00:00

kace-ticket-create


Creates a new ticket to the system.

Base Command

kace-ticket-create

Input

Argument Name Description Required
title Title of the new ticket. Optional
summary Summary of the new ticket. Optional
impact Name of the impact of the new ticket. Optional
category Category of the new ticket. Optional
status Status of the new ticket. Optional
priority Priority of the new ticket. Optional
machine Name of the machine of the new ticket. Optional
asset Name of the asset of the new ticket. Optional
custom_fields Custom (user defined) fields in the format - fieldname1=value;fieldname2=value. Optional
queue_id Queue to which the new ticket should be related. Optional

Context Output

There is no context output for this command.

Command Example

!kace-ticket-create title="test1" status="Opened" summary="test of Quest Kace integration ticket create" category="Network" queue_id=1

Context Example

{}

Human Readable Output

New ticket was added successfully, ticket number 35

created due_date hd_queue_id id modified title
2020-06-09 05:19:37 0000-00-00 00:00:00 1 35 2020-06-09 05:19:37 test1

kace-ticket-update


Updates a ticket in the system.

Base Command

kace-ticket-update

Input

Argument Name Description Required
title Updated title of the ticket. Optional
summary Updated summary for the ticket. Optional
impact Updated impact of the ticket. Optional
category Updated category of the ticket. Optional
status Updated status of the ticket. Optional
priority Updated priority of the ticket. Optional
machine Updated machine of the ticket. Optional
asset Updated asset of the ticket. Optional
custom_fields Custom (user defined) fields in the format - fieldname1=value;fieldname2=value. Optional
ticket_id ID of the ticket to update. Required

Context Output

There is no context output for this command.

Command Example

!kace-ticket-update ticket_id=11 title="updated test1"

Context Example

{}

Human Readable Output

Ticket number 11 was updated successfully

created hd_queue_id id modified title
2020-05-19 05:54:42 1 11 2020-06-09 05:19:38 updated test1

kace-ticket-delete


Deletes the specified ticket.

Base Command

kace-ticket-delete

Input

Argument Name Description Required
ticket_id Ticket ID to delete. Required

Context Output

There is no context output for this command.

Command Example

!kace-ticket-delete ticket_id=11

Context Example

{}

Human Readable Output

Ticket was deleted successfully. Ticket number 11

Configuration parameters

  • url — Quest KACE URL, in the format https://company.works.com/ (required)
  • credentials — Username (required)
  • isFetch — Fetch incidents
  • fetch_time — First fetch time range (<number> <time unit>, e.g., 1 hour, 30 minutes)
  • fetch_shaping — Shaping query parameter for tickets
  • fetch_filter — Filter for the tickets
  • fetch_limit — Fetch limit per query
  • fetch_queue_id — Queue number for fetch query
  • incidentType — Incident type
  • incidentFetchInterval — Incidents Fetch Interval
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (7)

  • kace-assets-list

    Returns a list of all assets in Quest KACE.

  • kace-machines-list

    Returns a list of all machines in system.

  • kace-queues-list

    Returns a list of all queues in Quest KACE.

  • kace-ticket-create

    Creates a new ticket to the system.

  • kace-ticket-delete

    Deletes the specified ticket.

  • kace-ticket-update

    Updates a ticket in the system.

  • kace-tickets-list

    Returns a list of all tickets in Quest KACE.

import json
from collections.abc import Callable
from typing import Any

import dateparser
import demistomock as demisto  # noqa: F401
import requests
import urllib3
from CommonServerPython import *  # noqa: F401

from CommonServerUserPython import *

# Disable insecure warnings
urllib3.disable_warnings()

# key =  field of a ticket , val = dict of (name,id) of options
TICKETS_OBJECTS = {
    "impact": {
        "1 person cannot work": 1,
        "Many people cannot work": 2,
        "1 person inconvenienced": 3,
        "Many people inconvenienced": 4,
    },
    "category": {"Network": 1, "Other": 2, "Software": 4, "Hardware": 3},
    "priority": {"Medium": 1, "High": 2, "Low": 3},
    "status": {
        "Opened": 1,
        "Closed": 2,
        "Need More Info": 3,
        "New": 4,
        "Reopened": 5,
        "Waiting Overdue": 6,
        "Waiting on Customer": 7,
        "Waiting on Third Party": 8,
    },
}


def convert_snake_to_camel(snake_str: str) -> str:
    """Convert a specific string of snake case to camel case.
    Args:
        snake_str: The string that we would like to convert.
    Returns:
        converted string.
    """
    snake_split = snake_str.split("_")
    camel_string = "".join(map(str.capitalize, snake_split))
    camel_string = convert_specific_keys(camel_string)
    return camel_string


def convert_specific_keys(string: str):
    """
    Convert specific keys to demisto standard
    Args:
        string: the text to transform
    Returns:
        A Demisto output standard string
    """
    if string == "OsName":
        return "OSName"
    if string == "OsNumber":
        return "OSNumber"
    if string == "Ram total":
        return "RamTotal"
    if string == "AssetDataId":
        return "AssetDataID"
    if string == "AssetClassId":
        return "AssetClassID"
    if string == "AssetStatusId":
        return "AssetStatusID"
    if string == "AssetTypeId":
        return "AssetTypeID"
    if string == "MappedId":
        return "MappedID"
    if string == "OwnerId":
        return "OwnerID"
    if string == "HdQueueId":
        return "HdQueueID"
    if string == "Ip":
        return "IP"
    return string


def convert_dict_snake_to_camel(dic: dict) -> dict:
    """Convert a dictionary of snake case to camel case.
    Args:
        dic: The dictionary that we would like to convert.
    Returns:
        converted dictionary.
    """
    context_dict = {}
    for snake_str in dic:
        if type(dic[snake_str]) is dict:
            inner_dict = convert_dict_snake_to_camel(dic[snake_str])
            camel = convert_snake_to_camel(snake_str)
            context_dict[camel] = inner_dict
        elif type(dic[snake_str]) is list:
            inner_dict = parse_response(dic[snake_str])
            camel = convert_snake_to_camel(snake_str)
            context_dict[camel] = inner_dict
        elif snake_str in ["id", "Id"]:
            context_dict["ID"] = dic.get(snake_str, "")
        else:
            camel = convert_snake_to_camel(snake_str)
            context_dict[camel] = dic.get(snake_str, "")
    return context_dict


def parse_response(lst: list):
    """Convert a Api response to wanted format.
    Args:
        lst: A list of dictionaries that return from api call.
    Returns:
        converted list of dictionaries from snake case to camel case.
    """
    list_res = []
    for dic in lst:
        context_dict = convert_dict_snake_to_camel(dic)
        list_res.append(context_dict)
    return list_res


class Client(BaseClient):
    """
    Client to use in the integration, overrides BaseClient.
    Used for communication with the api.
    """

    def __init__(self, url: str, username: str, password: str, verify: bool, proxy: bool):
        super().__init__(base_url=f"{url}/api", verify=verify, proxy=proxy)
        self._url = url
        self._username = username
        self._password = password
        self._token, self._cookie = self.get_token()

    def get_token(self) -> tuple[str, str]:
        """Get a token for the connection.
        Returns:
            token , cookie for the connection.
        """
        token = ""
        cookie = ""
        data = {"userName": self._username, "password": self._password}
        login_url = f"{self._url}/ams/shared/api/security/login"
        body = json.dumps(data)
        headers = {"Content-Type": "application/json"}
        response = self.token_request(login_url, headers=headers, data=body)
        # Extracting Token
        response_cookies = response.get("cookies").__dict__.get("_cookies")
        if response_cookies:
            cookie_key = list(response_cookies.keys())[0]
            if cookie_key:
                ret_cookie = response_cookies.get(cookie_key).get("/")
                cookie = self.get_cookie(ret_cookie)
                token = ret_cookie.get("KACE_CSRF_TOKEN").__dict__.get("value")
        if not token:
            raise DemistoException("Could not get token")
        if not cookie:
            raise DemistoException("Could not get cookie")
        return token, cookie

    def update_token(self):
        """Update cookie and token.
        Returns:
            Tuple of token and cookie.
        """
        self._token, self._cookie = self.get_token()

    def get_cookie(self, res_cookie: dict) -> str:
        """Get a cookie from an cookie object in the needed format for the requests.
        Args:
            res_cookie: part of the response that the cookie is inside it.
        Returns:
            string that will be sent in the requests which represents the cookie in the header.
        """
        KACE_CSRF_TOKEN = res_cookie.get("KACE_CSRF_TOKEN").__dict__.get("value")
        x_dell_auth_jwt = res_cookie.get("x-dell-auth-jwt").__dict__.get("value")
        kboxid = res_cookie.get("kboxid").__dict__.get("value")
        KACE_LAST_USER_SECURE = res_cookie.get("KACE_LAST_USER_SECURE").__dict__.get("value")
        KACE_LAST_ORG_SECURE = res_cookie.get("KACE_LAST_ORG_SECURE").__dict__.get("value")

        cookie = (
            f"KACE_LAST_USER_SECURE={KACE_LAST_USER_SECURE}; KACE_LAST_ORG_SECURE={KACE_LAST_ORG_SECURE};"
            f" kboxid={kboxid}; x-dell-auth-jwt={x_dell_auth_jwt}; KACE_CSRF_TOKEN={KACE_CSRF_TOKEN}"
        )
        return cookie

    def token_request(self, url: str, headers: dict | None = None, data: str | None = None) -> dict:
        """login request for initiating a connection with the product.
        Args:
            url: full url that the request will be sent to.
            headers: headers of the request.
            data: data of the request which includes username and password.
        Returns:
            Dictionary of the response from the product.
        """
        try:
            response = requests.request("POST", url, headers=headers, data=data, verify=self._verify)
        except requests.exceptions.SSLError:
            err_msg = (
                "SSL Certificate Verification Failed - try selecting 'Trust any certificate' checkbox in"
                " the integration configuration."
            )
            raise DemistoException(err_msg)
        except requests.exceptions.ConnectionError:
            raise DemistoException("Invalid url , Failed to establish a connection")
        if response.status_code == 401:
            raise DemistoException("Error Code 401 - Invalid user or password")
        return response.__dict__

    def machines_list_request(self, filter_fields: str | None = None):
        """List of machines.
        Returns:
            Response from API.
        """
        headers = {
            "Accept": "application/json",
            "x-dell-csrf-token": self._token,
            "x-dell-api-version": "5",
            "Cookie": self._cookie,
        }
        url_suffix = "/inventory/machines"
        if filter_fields:
            url_suffix += f"?filtering={filter_fields}"
        return self._http_request("GET", url_suffix=url_suffix, headers=headers)

    def assets_list_request(self, filter_fields: str | None = None) -> dict:
        """List of assets.
        Returns:
            Response from API.
        """
        headers = {
            "Accept": "application/json",
            "x-dell-csrf-token": self._token,
            "x-dell-api-version": "5",
            "Cookie": self._cookie,
        }
        url_suffix = "/asset/assets"
        if filter_fields:
            url_suffix += f"?filtering={filter_fields}"
        return self._http_request("GET", url_suffix=url_suffix, headers=headers)

    def queues_list_request(self, filter_fields: str | None = None) -> dict:
        """List of queues.
        Returns:
            Response from API.
        """
        headers = {
            "Accept": "application/json",
            "x-dell-csrf-token": self._token,
            "x-dell-api-version": "5",
            "Cookie": self._cookie,
        }
        url_suffix = "/service_desk/queues?shaping=fields all"
        if filter_fields:
            url_suffix += f"&filtering={filter_fields}"
        return self._http_request("GET", url_suffix=url_suffix, headers=headers)

    def queues_list_fields_request(self, queue_number: str) -> dict:
        """List of fields in specific queue.
         Args:
             queue_number: queue nubmer for the request.
        Returns:
            Response from API.
        """
        headers = {
            "Accept": "application/json",
            "x-dell-csrf-token": self._token,
            "x-dell-api-version": "5",
            "Cookie": self._cookie,
        }
        return self._http_request("GET", url_suffix=f"/service_desk/queues/{queue_number}/fields", headers=headers)

    def tickets_list_request(self, shaping_fields: str = None, filter_fields: str = None) -> dict:
        """List of Tickets.
         Args:
             shaping_fields: str of the shaping that will be sent in the request.
             filter_fields: str of filter that will be sent in the request.
        Returns:
            Response from API.
        """
        if not shaping_fields:
            shaping_fields = set_shaping(self)
        self.update_token()
        headers = {
            "Accept": "application/json",
            "x-dell-csrf-token": self._token,
            "x-dell-api-version": "5",
            "Cookie": self._cookie,
        }
        url_suffix = f"/service_desk/tickets?shaping={shaping_fields}"
        if filter_fields:
            url_suffix += f"&filtering={filter_fields}"
        return self._http_request("GET", url_suffix=url_suffix, headers=headers)

    def create_ticket_request(self, data: str) -> dict:
        """Create Ticket
         Args:
             data (str): the body of the request.
        Returns:
            Response from API.
        """
        headers = {
            "Accept": "application/json",
            "x-dell-csrf-token": self._token,
            "x-dell-api-version": "5",
            "Cookie": self._cookie,
            "Content-Type": "application/json",
        }
        return self._http_request("POST", url_suffix="/service_desk/tickets", headers=headers, data=data)

    def update_ticket_request(self, ticket_id: str, data: str) -> dict:
        """Update Ticket.
        Args:
         ticket_id (str): ticket id that will be updated.
         data (str): the body of the request.
        Returns:
            Response from API.
        """
        headers = {
            "Accept": "application/json",
            "x-dell-csrf-token": self._token,
            "x-dell-api-version": "5",
            "Cookie": self._cookie,
            "Content-Type": "application/json",
        }
        return self._http_request("POST", url_suffix=f"/service_desk/tickets/{ticket_id}", headers=headers, data=data)

    def delete_ticket_request(self, ticket_id: str) -> dict:
        """Delete Ticket.
         Args:
             ticket_id (str): ticket id that will be deleted.
        Returns:
            Response from API.
        """
        headers = {
            "Accept": "application/json",
            "x-dell-csrf-token": self._token,
            "x-dell-api-version": "5",
            "Cookie": self._cookie,
            "Content-Type": "application/json",
        }
        return self._http_request("DELETE", url_suffix=f"/service_desk/tickets/{ticket_id}", headers=headers)

    def ticket_by_id_request(self, filtering_id: int) -> dict:
        """Specific ticket details by ID.
         Args:
             filtering_id: id for filtering by it.
        Returns:
            Response from API.
        """
        headers = {
            "Accept": "application/json",
            "x-dell-csrf-token": self._token,
            "x-dell-api-version": "5",
            "Cookie": self._cookie,
        }
        filter_fields = f"id eq {filtering_id}"
        return self._http_request("GET", url_suffix=f"/service_desk/tickets?filtering={filter_fields}", headers=headers)


def test_module(client: Client, *_) -> tuple[str, dict, dict]:
    """Function which checks if there is a connection with the api.
     Args:
         client : Integration client which communicates with the api.
         args: Users arguments of the command.
    Returns:
        human readable, context, raw response of this command.
    """
    _ = client.machines_list_request()
    client.update_token()
    response = client.tickets_list_request()
    list_tickets_res = response.get("Tickets")
    if list_tickets_res and demisto.params().get("isFetch"):
        parse_date_range(demisto.params().get("fetch_time"), date_format="%Y-%m-%dT%H:%M:%SZ")
        parsed_time = datetime.utcnow() - timedelta(days=20)
        incidents, _ = parse_incidents(list_tickets_res, "1", "%Y-%m-%dT%H:%M:%SZ", parsed_time)
    return "ok", {}, {}


def get_machines_list_command(client, args) -> tuple[str, dict, dict]:
    """Function which returns all machines in the system.
     Args:
         client : Integretion client which communicates with the api.
         args: Users arguments of the command.
    Returns:
        human readable, context, raw response of this command.
    """
    limit = int(args.get("limit", 50))
    filter_fields = args.get("custom_filter")
    response = client.machines_list_request(filter_fields)
    raw_response = response.get("Machines")[:limit]
    context = parse_response(raw_response)
    human_readable_markdown = tableToMarkdown(
        "Quest Kace Machines",
        context,
        removeNull=True,
        headers=[
            "ID",
            "Name",
            "IP",
            "Created",
            "Modified",
            "LastInventory",
            "LastSync",
            "ManualEntry",
            "PagefileMaxSize",
            "PagefileSize",
            "RamTotal",
            "RamUsed",
        ],
    )
    context = {"QuestKace.Machine(val.ID === obj.ID)": context}
    return human_readable_markdown, context, raw_response


def get_assets_list_command(client, args) -> tuple[str, dict, dict]:
    """Function which returns all assets in the system.
     Args:
         client : Integretion client which communicates with the api.
         args: Users arguments of the command.
    Returns:
        human readable, context, raw response of this command.
    """
    limit = int(args.get("limit", 50))
    filter_fields = args.get("custom_filter")
    response = client.assets_list_request(filter_fields)
    raw_response = response.get("Assets")[:limit]
    context = parse_response(raw_response)
    human_readable_markdown = tableToMarkdown(
        "Quest Kace Assets",
        context,
        removeNull=True,
        headers=[
            "ID",
            "Name",
            "Created",
            "Modified",
            "OwnerID",
            "MappedID",
            "AssetClassID",
            "AssetDataID",
            "AssetStatusID",
            "AssetTypeID",
            "AssetTypeName",
        ],
    )
    context = {"QuestKace.Asset(val.ID === obj.ID)": context}
    return human_readable_markdown, context, raw_response


def get_queues_list_command(client, args) -> tuple[str, dict, dict]:
    """Function which returns all queues in the system.
     Args:
         client : Integretion client which communicates with the api.
         args: Users arguments of the command.
    Returns:
        human readable, context, raw response of this command.
    """
    filter_fields = args.get("custom_filter")
    limit = int(args.get("limit", 50))
    response = client.queues_list_request(filter_fields)
    raw_response = response.get("Queues")[:limit]
    context = parse_response(raw_response)
    human_readable_markdown = tableToMarkdown("Quest Kace Queues", context, removeNull=True, headers=["ID", "Name", "Fields"])
    context = {"QuestKace.Queue(val.ID === obj.ID)": context}
    return human_readable_markdown, context, raw_response


def get_tickets_list_command(client, args) -> tuple[str, dict, dict]:
    """Function which returns all tickets in the system.
     Args:
         client : Integretion client which communicates with the api.
         args: Users arguments of the command.
    Returns:
        human readable, context, raw response of this command.
    """
    limit = int(args.get("limit", 50))
    custom_shaping = args.get("custom_shaping")
    custom_filter = args.get("custom_filter")
    response = client.tickets_list_request(custom_shaping, custom_filter)
    raw_response = response.get("Tickets")[:limit]
    context = parse_response(raw_response)
    for response in context:
        response["IsDeleted"] = False
    human_readable_markdown = tableToMarkdown(
        "Quest Kace Tickets", context, removeNull=True, headers=["ID", "Title", "Created", "Modified", "HdQueueID", "DueDate"]
    )
    context = {"QuestKace.Ticket(val.ID === obj.ID)": context}
    return human_readable_markdown, context, raw_response


def create_ticket_command(client, args) -> tuple[str, dict, dict]:
    """Function which creates a new ticket to the system according to users arguments.
     Args:
         client : Integretion client which communicates with the api.
         args: Users arguments of the command.
    Returns:
        human readable, context, raw response of this command.
    """
    impact = None
    category = None
    status = None
    priority = None
    hd_queue_id = args.get("queue_id")
    custom_fields = args.get("custom_fields")
    if (custom_fields and "hd_queue_id" not in custom_fields) and (not hd_queue_id):
        raise DemistoException("hd_queue_id is a mandatory value, please add it.")
    title = args.get("title")
    summary = args.get("summary")
    if args.get("impact"):
        dict_of_obj = TICKETS_OBJECTS.get("impact")
        impact = args.get("impact")
        if dict_of_obj:
            impact = dict_of_obj.get(args.get("impact"), args.get("impact"))
    if args.get("category"):
        dict_of_obj = TICKETS_OBJECTS.get("category")
        impact = args.get("category")
        if dict_of_obj:
            impact = dict_of_obj.get(args.get("category"), args.get("category"))
    if args.get("status"):
        dict_of_obj = TICKETS_OBJECTS.get("status")
        impact = args.get("status")
        if dict_of_obj:
            impact = dict_of_obj.get(args.get("status"), args.get("status"))
    if args.get("priority"):
        dict_of_obj = TICKETS_OBJECTS.get("priority")
        impact = args.get("priority")
        if dict_of_obj:
            impact = dict_of_obj.get(args.get("priority"), args.get("priority"))
    machine = args.get("machine")
    asset = args.get("asset")
    body_from_args = create_body_from_args(
        hd_queue_id,
        title,
        summary,
        impact,  # type: ignore
        category,  # type: ignore
        status,  # type: ignore
        priority,  # type: ignore
        machine,
        asset,
    )
    if custom_fields:
        splited = split_fields(custom_fields)
        body_from_args.update(splited)
    temp_data = {"Tickets": [body_from_args]}
    data = json.dumps(temp_data)
    response = client.create_ticket_request(data)
    if response.get("Result") != "Success":
        raise DemistoException("Error while adding a new ticket.")
    try:
        id = response.get("IDs")[0]
    except Exception as e:
        raise DemistoException(e)
    client.update_token()
    res = client.ticket_by_id_request(id)
    ticket = res.get("Tickets")
    ticket_view = tableToMarkdown(f"New ticket was added successfully, ticket number {id}.\n", ticket)
    return ticket_view, {}, {}


def create_body_from_args(  # type: ignore
    hd_queue_id: str | int = None,  # type: ignore
    title: str | int = None,  # type: ignore
    summary: str | int = None,  # type: ignore
    impact: str | int = None,  # type: ignore
    category: str | int = None,  # type: ignore
    status: str | int = None,  # type: ignore
    priority: str | int = None,  # type: ignore
    machine: str | int = None,  # type: ignore
    asset: str | int = None,  # type: ignore
) -> dict:
    """Function which creates the body of the request from user arguments.
     Args:
        hd_queue_id: the queue number to insert the ticket to.
        title: title of the ticket.
        summary: summary of the ticket.
        impact: impact of the ticket.
        category: category of the ticket.
        status: status of the ticket.
        priority: priority of the ticket.
        machine: machine of the ticket.
        asset: asset of the ticket.
    Returns:
        body of the request as a dict.
    """
    body = {}
    if hd_queue_id:
        body.update({"hd_queue_id": hd_queue_id})
    if title:
        body.update({"title": title})
    if summary:
        body.update({"summary": summary})
    if impact:
        body.update({"impact": impact})
    if category:
        body.update({"category": category})
    if status:
        body.update({"status": status})
    if priority:
        body.update({"priority": priority})
    if machine:
        body.update({"machine": machine})
    if asset:
        body.update({"asset": asset})
    return body


def update_ticket_command(client, args) -> tuple[str, dict, dict]:
    """Function which updates the body of the request from user arguments.
     Args:
         client : Integretion client which communicates with the api.
         args: Users arguments of the command.
    Returns:
        human readable, context, raw response of this command.
    """
    impact = None
    category = None
    status = None
    priority = None
    ticket_id = args.get("ticket_id")
    title = args.get("title")
    summary = args.get("summary")
    if args.get("impact"):
        impact = TICKETS_OBJECTS["impact"][args.get("impact")]
    if args.get("category"):
        category = TICKETS_OBJECTS["category"][args.get("category")]
    if args.get("status"):
        status = TICKETS_OBJECTS["status"][args.get("status")]
    if args.get("priority"):
        priority = TICKETS_OBJECTS["priority"][args.get("priority")]
    machine = args.get("machine")
    asset = args.get("asset")
    custom_fields = args.get("custom_fields")

    body_from_args = create_body_from_args(  # type: ignore
        title=title,  # type: ignore
        summary=summary,  # type: ignore
        impact=impact,  # type: ignore
        category=category,  # type: ignore
        status=status,  # type: ignore
        priority=priority,  # type: ignore
        machine=machine,  # type: ignore
        asset=asset,  # type: ignore
    )
    if custom_fields:
        splited = split_fields(custom_fields)
        body_from_args.update(splited)
    temp_data = {"Tickets": [body_from_args]}
    data = json.dumps(temp_data)

    response = client.update_ticket_request(ticket_id, data)
    if response.get("Result") != "Success":
        raise DemistoException("Error while updating the ticket.")
    client.update_token()
    res = client.ticket_by_id_request(ticket_id)
    ticket = res.get("Tickets")
    ticket_view = tableToMarkdown(f"Ticket number {ticket_id} was updated successfully.\n", ticket)
    return ticket_view, {}, {}


def delete_ticket_command(client, args) -> tuple[str, dict, dict]:
    """Function which deleted a specific ticket by ticket id.
     Args:
         client : Integretion client which communicates with the api.
         args: Users arguments of the command.
    Returns:
        human readable, context, raw response of this command.
    """
    ticket_id = args.get("ticket_id")
    try:
        response = client.delete_ticket_request(ticket_id)
    except Exception as e:
        raise DemistoException(e)
    if response.get("Result") == "Success":
        context = {}
        old_context = demisto.dt(demisto.context(), f"QuestKace.Ticket(val.ID === {ticket_id})")
        if old_context:
            if isinstance(old_context, list):
                old_context = old_context[0]
            old_context["IsDeleted"] = True
            context = {"QuestKace.Ticket(val.ID === obj.ID)": old_context}
        return f"Ticket was deleted successfully. Ticket number {ticket_id}", context, {}
    else:
        raise DemistoException("Error while deleting the ticket.")


def fetch_incidents(
    client: Client,
    fetch_time: str,
    fetch_shaping: str,
    last_run: dict,
    fetch_limit: str,
    fetch_queue_id: list | None = None,
    fetch_filter: str | None = None,
) -> list:
    """
    This function will execute each interval (default is 1 minute).
    Args:
        client (Client): Quest Kace Client
        fetch_time: time interval for fetch incidents.
        fetch_shaping: shaping for the request.
        fetch_filter: custom filters for the request.
        fetch_limit: limit for number of fetch incidents per fetch.
        fetch_queue_id: queue id for fetch, if not given then fetch runs on all tickets in the system
        last_run (dateparser.time): The greatest incident created_time we fetched from last fetch
    Returns:
        incidents: Incidents that will be created in Demisto
    """
    if not fetch_queue_id or fetch_queue_id[0] == "All":
        fetch_queue_id = get_queue_ids(client)
    time_format = "%Y-%m-%dT%H:%M:%SZ"
    if not last_run:  # if first time running
        new_last_run = {"last_fetch": parse_date_range(fetch_time, date_format=time_format)[0]}
    else:
        new_last_run = last_run

    if not fetch_shaping:
        fetch_shaping = shaping_fetch(client, fetch_queue_id)

    parsed_last_time = datetime.strptime(new_last_run.get("last_fetch", ""), time_format)
    fetch_filter_for_query = f"created gt {parsed_last_time}"
    if fetch_queue_id:
        queue_id_str = ";".join(fetch_queue_id)
        filter_by_queue_id = f"hd_queue_id in {queue_id_str}"
        fetch_filter_for_query = f"{fetch_filter_for_query},{filter_by_queue_id}"
    if fetch_filter:
        fetch_filter_for_query = f"{fetch_filter_for_query},{fetch_filter}"
    demisto.info(
        f"Fetching Incident has Started,\n"
        f"Fetch filter is {fetch_filter_for_query}\n"
        f"Last fetch was on {parsed_last_time!s}"
    )
    client.update_token()
    items: dict = client.tickets_list_request(fetch_shaping, fetch_filter_for_query)
    items: list = items.get("Tickets", [])
    incidents, last_incident_time = parse_incidents(items, fetch_limit, time_format, parsed_last_time)
    last_incident_time = last_incident_time.strftime(time_format)
    demisto.info(
        f"Fetching Incident has Finished\n"
        f"Fetch limit was {fetch_limit}"
        f"Last fetch was on {last_incident_time!s}\n"
        f"Number of incidents was {len(incidents)}"
    )
    demisto.setLastRun({"last_fetch": last_incident_time})
    return incidents


def shaping_fetch(client: Client, fetch_queue_id: list) -> str:
    """
    Create and Update shaping fields once a day and saves them in integration context.
    Args:
        client: Client for the api.
        fetch_queue_id:
    Returns:
        the current shaping.
    """
    integration_context = demisto.getIntegrationContext()
    if integration_context:
        valid_until = integration_context.get("valid_until")
        time_now = int(time.time())
        if time_now < valid_until:
            fetch_shaping = integration_context.get("shaping_fields")
        else:
            fetch_shaping = set_shaping(client, fetch_queue_id)
            integration_context = {"shaping_fields": fetch_shaping, "valid_until": int(time.time()) + 3600 * 24}
            demisto.setIntegrationContext(integration_context)
    else:
        fetch_shaping = set_shaping(client, fetch_queue_id)
        integration_context = {"shaping_fields": fetch_shaping, "valid_until": int(time.time()) + 3600 * 24}
        demisto.setIntegrationContext(integration_context)
    return fetch_shaping


def get_fields_by_queue(client, queue: list | None) -> list:
    """
    Creating a list of all queue ids that are in the system.
    Args:
        client: Client for the api.
    Returns:
        list of queue ids.
    """
    if queue:
        queues_id = queue
    else:
        queues_id = get_queue_ids(client)
    fields: list = []
    for q in queues_id:
        client.update_token()
        fields_by_queue = client.queues_list_fields_request(queue_number=str(q))
        fields_by_queue = fields_by_queue.get("Fields", [])
        for field in fields_by_queue:
            if field.get("jsonKey") not in fields and (
                field.get("jsonKey") != "related_tickets" and field.get("jsonKey") != "referring_tickets"
            ):
                # get internal error 500 from server with related tickets
                fields.append(field.get("jsonKey"))
    return fields


def get_queue_ids(client: Client) -> list:
    """
    Creating a list of all queue ids that are in the system.
    Args:
        client: Client for the api.
    Returns:
        list of queue ids.
    """
    queues = client.queues_list_request()
    queues = queues.get("Queues", [])
    queues_id = []
    for q in queues:
        queues_id.append(str(q.get("id")))
    return queues_id


def shaping_by_fields(fields: list) -> str:
    """
    Creating a shaping for the request which is from the fields and seperated by comma's
    Args:
        fields: List of fields that would be part of the shaping.
    Returns:
        str of the shaping.
    """
    shaping = "hd_ticket all"
    for field in fields:
        shaping += f",{field} limited"
    return shaping


def set_shaping(client, queue: list | None = None) -> str:
    """
    Creating a shaping for the request.
    Args:
        client: Client in order to get the queue fields.
        queue: If specific queue is given for the shaping.
    Returns:
        str of the shaping.
    """
    fields = get_fields_by_queue(client, queue)
    shaping = shaping_by_fields(fields)
    return shaping


def parse_incidents(items: list, fetch_limit: str, time_format: str, parsed_last_time: datetime) -> tuple[list, Any]:
    """
    This function will create a list of incidents
    Args:
        items : List of tickets of the api response.
        fetch_limit: Limit for incidents of fetch cycle.
        time_format: Time format of the integration.
        parsed_last_time: limit for number of fetch incidents per fetch.
    Returns:
        incidents: List of incidents.
        parsed_last_time: Time of last incident.
    """
    count = 0
    incidents = []
    for item in items:
        if count >= int(fetch_limit):
            break

        incident_created_time = dateparser.parse(item["created"])
        assert incident_created_time is not None, f"could not parse {item['created']}"

        incident = {"name": item["title"], "occurred": incident_created_time.strftime(time_format), "rawJSON": json.dumps(item)}

        incidents.append(incident)
        count += 1
        parsed_last_time = incident_created_time
    return incidents, parsed_last_time


def split_fields(fields: str = "") -> dict:
    """Split str fields of Demisto arguments to request fields by the char ';'.
    Args:
        fields: fields in a string representation.
    Returns:
        dic_fields object for request.
    """
    dic_fields = {}
    if fields:
        if "=" not in fields:
            raise Exception(f"The argument: {fields}.\nmust contain a '=' to specify the keys and values. e.g: key=val.")
        arr_fields = fields.split(";")
        for f in arr_fields:
            field = f.split("=", 1)  # a field might include a '=' sign in the value. thus, splitting only once.
            if len(field) > 1:
                dic_fields[field[0]] = field[1]
    return dic_fields


def main():
    """
    PARSE AND VALIDATE INTEGRATION PARAMS
    """
    params = demisto.params()
    username = params.get("credentials").get("identifier")
    password = params.get("credentials").get("password")
    base_url = params.get("url")
    proxy = demisto.params().get("proxy", False)
    verify_certificate = not params.get("insecure", False)

    # fetch incidents params
    fetch_limit = params.get("fetch_limit", 10)
    fetch_time = params.get("fetch_time", "1 day")
    fetch_shaping = params.get("fetch_shaping")
    fetch_filter = params.get("fetch_filter")
    fetch_queue_id = argToList(params.get("fetch_queue_id"))
    try:
        client = Client(url=base_url, username=username, password=password, verify=verify_certificate, proxy=proxy)
        command = demisto.command()
        LOG(f"Command being called is {command}")
        # Commands dict
        commands: dict[str, Callable[[Client, dict[str, str]], tuple[str, dict, dict]]] = {
            "test-module": test_module,
            "kace-machines-list": get_machines_list_command,
            "kace-assets-list": get_assets_list_command,
            "kace-queues-list": get_queues_list_command,
            "kace-tickets-list": get_tickets_list_command,
            "kace-ticket-create": create_ticket_command,
            "kace-ticket-update": update_ticket_command,
            "kace-ticket-delete": delete_ticket_command,
        }
        if command in commands:
            return_outputs(*commands[command](client, demisto.args()))
        elif command == "fetch-incidents":
            incidents = fetch_incidents(
                client,
                fetch_time=fetch_time,
                fetch_shaping=fetch_shaping,
                fetch_filter=fetch_filter,
                fetch_limit=fetch_limit,
                fetch_queue_id=fetch_queue_id,
                last_run=demisto.getLastRun(),
            )
            demisto.incidents(incidents)
        else:
            raise NotImplementedError(f"{command} is not an existing QuestKace command")
    except Exception as e:
        return_error(f"Error from QuestKace Integration.\nFailed to execute {demisto.command()} command.\n\n Error: {e!s}")


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