McAfeeNSMv2

McAfee Network Security Manager gives you real-time visibility and control over all McAfee intrusion prevention systems deployed across your network.

Utilities · McAfee NSM

Details

IDMcAfeeNSMv2
ProviderTrellix
CategoryUtilities
From Version6.5.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix XSIAM

README

McAfee Network Security Manager gives you real-time visibility and control over all McAfee intrusion prevention systems deployed across your network.
This integration was integrated and tested with version 9.1 of McAfeeNSMv2

Some changes have been made that might affect your existing content.
If you are upgrading from a previous of this integration, see Breaking Changes.

Configure McAfee NSM v2 in Cortex

Parameter Required
URL (for example: https://192.168.0.1:5000) True
User Name True
Password True
Product Version True
Trust any certificate (not secure) False
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.

nsm-list-domain-firewall-policy


Gets the list of firewall policies defined in a particular domain.

Base Command

nsm-list-domain-firewall-policy

Input

Argument Name Description Required
domain_id The ID of the domain. To get the domain_id, use the !nsm-get-domains command. Required
limit The maximum number of records to return. Default is 50. Optional
page The specific result page to display. Optional
page_size The number of records in a page. Optional

Context Output

Path Type Description
NSM.Policy.policyId Number The ID of the policy.
NSM.Policy.policyName String Name of the firewall policy.
NSM.Policy.domainId Number The ID of the domain.
NSM.Policy.visibleToChild Boolean Whether the policy is visible to child domains.
NSM.Policy.description String Policy description.
NSM.Policy.isEditable Boolean Whether the policy is editable.
NSM.Policy.policyType String Policy type. Can be “ADVANCED” or “CLASSIC”.
NSM.Policy.policyVersion Number Policy version.
NSM.Policy.lastModUser String Last user who modified the policy.

Command example

!nsm-list-domain-firewall-policy domain_id=0 limit=2

Context Example

{
    "NSM": {
        "Policy": [
            {
                "description": "hello updatingg",
                "domainId": 0,
                "isEditable": true,
                "lastModUser": "user",
                "policyId": 292,
                "policyName": "another policy",
                "policyType": "ADVANCED",
                "policyVersion": 1,
                "visibleToChild": true
            },
            {
                "description": "hello updatingg",
                "domainId": 0,
                "isEditable": true,
                "lastModUser": "user",
                "policyId": 161,
                "policyName": "policy",
                "policyType": "ADVANCED",
                "policyVersion": 1,
                "visibleToChild": true
            }
        ]
    }
}

Human Readable Output

Firewall Policies List

policyId policyName domainId visibleToChild description isEditable policyType policyVersion lastModUser
292 another policy 0 true hello updatingg true ADVANCED 1 user
161 policy 0 true hello updatingg true ADVANCED 1 user

nsm-get-firewall-policy


Gets the firewall policy details.

Base Command

nsm-get-firewall-policy

Input

Argument Name Description Required
policy_id The ID of the policy. To get the policy_id, use the !nsm-list-domain-firewall-policy command. Required
include_rule_objects Whether to insert the rule objects that are linked to the policy in the context. True- the rule object will be inserted. False- not inserted. Possible values are: true, false. Default is false. Optional

Context Output

Path Type Description
NSM.Policy.FirewallPolicyId Number Unique firewall policy ID.
NSM.Policy.Name String Policy name.
NSM.Policy.DomainId Number ID of the domain to which this firewall policy belongs.
NSM.Policy.VisibleToChild Boolean Whether the policy is visible to a child domain.
NSM.Policy.Description String Firewall policy description.
NSM.Policy.LastModifiedTime Date Last modified time of the firewall Policy.
NSM.Policy.IsEditable Boolean Whether the policy is editable.
NSM.Policy.PolicyType String Policy type. Can be “Advanced” / “Classic”.
NSM.Policy.PolicyVersion Number Policy version.
NSM.Policy.LastModifiedUser String Last user user modified the policy.
NSM.Policy.MemberDetails.MemberRuleList.Description String Rule description.
NSM.Policy.MemberDetails.MemberRuleList.Enabled Boolean Whether the rule is enabled.
NSM.Policy.MemberDetails.MemberRuleList.Response String Action to be performed if the traffic matches this rule. Can be “Scan” / “Drop” / “Deny” / “Ignore” / “Stateless Ignore” / “Stateless Drop” / “Require Authentication”.
NSM.Policy.MemberDetails.MemberRuleList.IsLogging Boolean Whether logging is enabled for this rule.
NSM.Policy.MemberDetails.MemberRuleList.Direction String Rule direction. Can be “Inbound” / “Outbound” / “Either”.
NSM.Policy.MemberDetails.MemberRuleList.SourceAddressObjectList.RuleObjectId String Unique rule object ID.
NSM.Policy.MemberDetails.MemberRuleList.SourceAddressObjectList.Name String Rule object name.
NSM.Policy.MemberDetails.MemberRuleList.SourceAddressObjectList.RuleObjectType Unknown Source or destination mode. Can be “Endpoint IP V.4” / “Range IP V.4” / “Network IP V.4” / “Endpoint IP V.6” / “Range IP V.6” / “Network IP V.6”.
NSM.Policy.MemberDetails.MemberRuleList.DestinationAddressObjectList.RuleObjectId String Unique rule object ID.
NSM.Policy.MemberDetails.MemberRuleList.DestinationAddressObjectList.Name String Rule object name.
NSM.Policy.MemberDetails.MemberRuleList.DestinationAddressObjectList.RuleObjectType Unknown Source or destination mode. Can be “Endpoint IP V.4” / “Range IP V.4” / “Endpoint IP V.6” / “Range IP V.6” / “Network IP V.6”.
NSM.Policy.MemberDetails.MemberRuleList.SourceUserObjectList.RuleObjectId String Unique rule object ID.
NSM.Policy.MemberDetails.MemberRuleList.SourceUserObjectList.Name String Rule object name.
NSM.Policy.MemberDetails.MemberRuleList.SourceUserObjectList.RuleObjectType String Source user. Can be “USER” / “USER_GROUP”.
NSM.Policy.MemberDetails.MemberRuleList.ServiceObjectList.RuleObjectId String Unique service rule object ID.
NSM.Policy.MemberDetails.MemberRuleList.ServiceObjectList.Name String Rule object name.
NSM.Policy.MemberDetails.MemberRuleList.ServiceObjectList.RuleObjectType Unknown Service/ application mode. Can be “APPLICATION” / “APPLICATION_GROUP” / “APPLICATION_ON_CUSTOM_PORT” / “SERVICE” / “SERVICE_GROUP”.
NSM.Policy.MemberDetails.MemberRuleList.ServiceObjectList.ApplicationType Unknown Application type. Can be “DEFAULT” / “CUSTOM”.
NSM.Policy.MemberDetails.MemberRuleList.ApplicationObjectList.RuleObjectId String Unique service rule object ID.
NSM.Policy.MemberDetails.MemberRuleList.ApplicationObjectList.Name String Rule object name.
NSM.Policy.MemberDetails.MemberRuleList.ApplicationObjectList.RuleObjectType Unknown Service/ application mode. Can be “APPLICATION” / “APPLICATION_GROUP” / “APPLICATION_ON_CUSTOM_PORT” / “SERVICE” / “SERVICE_GROUP”.
NSM.Policy.MemberDetails.MemberRuleList.ApplicationObjectList.ApplicationType Unknown Application type. Can be “DEFAULT” / “CUSTOM”.
NSM.Policy.MemberDetails.MemberRuleList.TimeObjectList.RuleObjectId String Unique service rule object ID.
NSM.Policy.MemberDetails.MemberRuleList.TimeObjectList.Name String Rule object name.
NSM.Policy.MemberDetails.MemberRuleList.TimeObjectList.RuleObjectType Unknown Time mode. Can be “FINITE_TIME_PERIOD” / “RECURRING_TIME_PERIOD” / “RECURRING_TIME_PERIOD_GROUP”.

Command example

!nsm-get-firewall-policy policy_id=147 include_rule_objects=true

Context Example

{
    "NSM": {
        "Policy": {
            "Description": "update policy",
            "DomainId": 0,
            "FirewallPolicyId": 147,
            "IsEditable": true,
            "LastModifiedTime": "2022-12-28 05:37:23",
            "LastModifiedUser": "user",
            "MemberDetails": {
                "MemberRuleList": [
                    {
                        "ApplicationObjectList": [],
                        "Description": "r",
                        "DestinationAddressObjectList": [
                            {
                                "Name": "Any",
                                "RuleObjectId": "-1",
                                "RuleObjectType": null
                            }
                        ],
                        "Direction": "EITHER",
                        "Enabled": true,
                        "IsLogging": false,
                        "Response": "SCAN",
                        "ServiceObjectList": [
                            {
                                "ApplicationType": null,
                                "Name": "Any",
                                "RuleObjectId": "-1",
                                "RuleObjectType": null
                            }
                        ],
                        "SourceAddressObjectList": [
                            {
                                "Name": "Range V6 Test",
                                "RuleObjectId": "117",
                                "RuleObjectType": "IPV_6_ADDRESS_RANGE"
                            }
                        ],
                        "SourceUserObjectList": [
                            {
                                "Name": "Any",
                                "RuleObjectId": "-1",
                                "RuleObjectType": "USER"
                            }
                        ],
                        "TimeObjectList": [
                            {
                                "Name": "Always",
                                "RuleObjectId": "-1",
                                "RuleObjectType": null
                            }
                        ]
                    }
                ]
            },
            "Name": "name147",
            "PolicyType": "ADVANCED",
            "PolicyVersion": 1,
            "VisibleToChild": true
        }
    }
}

Human Readable Output

Firewall Policy 147

Name Description VisibleToChild IsEditable PolicyType PolicyVersion LastModifiedUser LastModifiedTime
name147 update policy true true ADVANCED 1 user 2022-12-28 05:37:23

nsm-create-firewall-policy


Adds a new firewall policy and access rules. You have to provide at lease one of the source/destination rule objects. If you provide the id or type of the source/destination rule object, you must provide the matching type or id the source/destination rule object as well.

Base Command

nsm-create-firewall-policy

Input

Argument Name Description Required
domain The ID of the domain. To get the domain ID, use the !nsm-get-domains command. Required
name The policy name. Required
visible_to_child Whether the policy is visible to the child domain. Possible values are: yes, no. Default is yes. Optional
description The description of the policy. Required
is_editable Whether the policy is editable. Possible values are: yes, no. Default is yes. Optional
policy_type The type of the policy. Possible values are: Advanced, Classic. Required
rule_description The rule description. Required
response Action to be performed if the traffic matches this rule. Possible values are: Scan, Drop, Deny, Ignore, Stateless Ignore, Stateless Drop, Require Authentication. Required
rule_enabled Whether the rule is enabled. Possible values are: yes, no. Default is yes. Optional
direction The direction of the rule. Possible values are: Inbound, Outbound, Either. Required
source_rule_object_id The ID of the rule connected to the policy. To get the rule_object_id use the command ‘!nsm-list-domain-rule-object’. Optional
source_rule_object_type The type of the rule connected to the policy. To get the rule_object_type use the command ‘!nsm-list-domain-rule-object’. Possible values are: Endpoint IP V.4, Range IP V.4, Network IP V.4, Endpoint IP V.6, Range IP V.6, Network IP V.6. Optional
destination_rule_object_id The ID of the rule connected to the policy. To get the rule_object_id use the command ‘!nsm-list-domain-rule-object’. Optional
destination_rule_object_type The type of the rule connected to the policy. To get the rule_object_type use the command ‘!nsm-list-domain-rule-object’. Possible values are: Endpoint IP V.4, Range IP V.4, Network IP V.4, Endpoint IP V.6, Range IP V.6, Network IP V.6. Optional

Context Output

Path Type Description
NSM.Policy.FirewallPolicyId Number The ID of the newly created firewall policy.

Command example

!nsm-create-firewall-policy domain=0 name=policy visible_to_child=yes description="a new policy" is_editable=yes policy_type=Advanced response=Scan rule_description="Test Member Rule" direction=Inbound destination_rule_object_id=111 destination_rule_object_type="Range IP V.4"

Context Example

{
    "NSM": {
        "Policy": {
            "FirewallPolicyId":112
        }
    }
}

Human Readable Output

The firewall policy no.112 was created successfully

nsm-update-firewall-policy


Updates the firewall policy details. If the argument is_overwrite=true, the new values of the provided addresses will replace the existing values, otherwise the addresses will be added to them.

  • If you want to delete a rule, enter is_overwrite=true and the relevant rule_object_id=-1.
  • If is_overwrite=false and there is no value in one of the rules (source or destination), their value will be as before.
  • If is_overwrite=true, at least one of the rules (source or destination) must be provided.
  • If you provide the id or type of the source/destination rule object, you must provide the matching type or id the source/destination rule object as well.

Base Command

nsm-update-firewall-policy

Input

Argument Name Description Required
policy_id The ID of the policy. To get the policy ID, use the !nsm-list-domain-firewall-policy. Required
domain The ID of the domain. To get the domain ID, use the !nsm-get-domains command. Optional
name The policy name. Optional
visible_to_child Whether the policy is visible to the child domain. Possible values are: yes, no. Default is yes. Optional
description The description of the policy. Optional
is_editable Whether the policy is editable. Possible values are: yes, no. Optional
policy_type The type of the policy. Possible values are: Advanced, Classic. Optional
rule_description The rule description. Optional
response Action to be performed if the traffic matches this rule. Possible values are: Scan, Drop, Deny, Ignore, Stateless Ignore, Stateless Drop, Require Authentication. Optional
rule_enabled Whether the rule is enabled. Possible values are: yes, no. Default is yes. Optional
direction The direction of the rule. Possible values are: Inbound, Outbound, Either. Optional
source_rule_object_id The ID of the rule connected to the policy. To get the rule_object_id use the command ‘!nsm-list-domain-rule-object’. Optional
source_rule_object_type The type of the rule connected to the policy. To get the rule_object_type use the command ‘!nsm-list-domain-rule-object’. Possible values are: Endpoint IP V.4, Range IP V.4, Network IP V.4, Endpoint IP V.6, Range IP V.6, Network IP V.6. Optional
destination_rule_object_id The ID of the rule connected to the policy. To get the rule_object_id use the command ‘!nsm-list-domain-rule-object’. Optional
destination_rule_object_type The type of the rule connected to the policy. To get the rule_object_type use the command ‘!nsm-list-domain-rule-object’. Possible values are: Endpoint IP V.4, Range IP V.4, Network IP V.4, Endpoint IP V.6, Range IP V.6, Network IP V.6. Optional
is_overwrite Whether the new addresses that were provided in the update processes will override the current ones or will be added to them. Possible values are: true, false. Optional

Context Output

There is no context output for this command.

Command example

!nsm-update-firewall-policy policy_id=147 description="update policy"

Human Readable Output

The firewall policy no.147 was updated successfully

nsm-delete-firewall-policy


Deletes the specified firewall policy.

Base Command

nsm-delete-firewall-policy

Input

Argument Name Description Required
policy_id The ID of the policy to delete. To get the policy ID, use the !nsm-list-domain-firewall-policy. Required

Context Output

There is no context output for this command.

Command example

!nsm-delete-firewall-policy policy_id=101

Human Readable Output

The firewall policy no.101 was deleted successfully

nsm-list-domain-rule-object


Gets the list of rule objects defined in a particular domain.

Base Command

nsm-list-domain-rule-object

Input

Argument Name Description Required
domain_id The ID of the domain. To get the domain ID, use the !nsm-get-domains command. Required
type The type of the rule. Possible values are: Endpoint IP V.4, Range IP V.4, Network IP V.4, Endpoint IP V.6, Range IP V.6, Network IP V.6, All. Default is All. Optional
limit The maximum number of records to return. Default is 50. Optional
page The specific result page to display. Optional
page_size The number of records in a page. Optional

Context Output

Path Type Description
NSM.Rule.ruleobjId String The ID of the rule object.
NSM.Rule.ruleobjType String The type of the rule object.
NSM.Rule.name String The name of the rule object.
NSM.Rule.description String The description of the rule object.
NSM.Rule.domain Number The name of the rule object.
NSM.Rule.visibleToChild Boolean Whether the rule is visible to child domains.
NSM.Rule.hostCriticality String The critical level of the host.
NSM.Rule.ApplicationGroup Unknown Application Group object. Should be defined if ruleobjType is “APPLICATION_GROUP”.
NSM.Rule.ApplicationOnCustomPort Unknown Application defined on Custom Port object. Should be defined if ruleobjType is “APPLICATION_ON_CUSTOM_PORT”.
NSM.Rule.FiniteTimePeriod Unknown Finite Time Period object. Should be defined if ruleobjType is “FINITE_TIME_PERIOD”.
NSM.Rule.HostIPv4 Unknown Host IPv4 Address object. Should be defined if ruleobjType is “HOST_IPV_4”.
NSM.Rule.HostIPv6 Unknown Host IPv6 Address object. Should be defined if ruleobjType is “HOST_IPV_6”.
NSM.Rule.HostDNSName Unknown Host DNS Name object. Should be defined if ruleobjType is “HOST_DNS_NAME”.
NSM.Rule.IPv4AddressRange Unknown IPv4 Address Range object. Should be defined if ruleobjType is “IPV_4_ADDRESS_RANGE”.
NSM.Rule.IPv6AddressRange Unknown IPv6 Address Range object. Should be defined if ruleobjType is “IPV_6_ADDRESS_RANGE”.
NSM.Rule.Network_IPV_4 Unknown IPv4 Network object. Should be defined if ruleobjType is “NETWORK_IPV_4.
NSM.Rule.Network_IPV_6 String IPv6 Network object. Should be defined if ruleobjType is “NETWORK_IPV_6”.
NSM.Rule.NetworkGroup Unknown Network Group object. Should be defined if ruleobjType is “NETWORK_GROUP”.
NSM.Rule.RecurringTimePeriod Unknown Recurring Time Period object. Should be defined if ruleobjType is “RECURRING_TIME_PERIOD”.
NSM.Rule.RecurringTimePeriodGroup Unknown Recurring Time Period Group object. Should be defined if ruleobjType is “RECURRING_TIME_PERIOD_GROUP”.
NSM.Rule.Service Unknown Service object. Should be defined if ruleobjType is “CUSTOM_SERVICE”.
NSM.Rule.ServiceGroup Unknown Service Group object. Should be defined if ruleobjType is “SERVICE_GROUP”.
NSM.Rule.ServiceRange Unknown Service Range object. Should be defined if ruleobjType is “SERVICE_RANGE”.
NSM.Rule.IPv6AddressRange.IPV6RangeList String List of IPv6 Address Range.
NSM.Rule.HostIPv6.hostIPv6AddressList String Host IPv6 address list.
NSM.Rule.Network_IPV_4.networkIPV4List String Network IPV4 list.
NSM.Rule.IPv4AddressRange.IPV4RangeList String List of IPv4 address range.
NSM.Rule.HostIPv4.hostIPv4AddressList String Host IPv4 address list.
NSM.Rule.Network_IPV_6.networkIPV6List String Network IPV6 list.

Command example

!nsm-list-domain-rule-object domain_id=0 limit=2

Context Example

{
    "NSM": {
        "Rule": [
            {
                "ApplicationGroup": null,
                "ApplicationOnCustomPort": null,
                "FiniteTimePeriod": null,
                "HostDNSName": null,
                "HostIPv4": {
                    "hostIPv4AddressList": [
                        "1.1.1.1"
                    ]
                },
                "HostIPv6": null,
                "IPv4AddressRange": null,
                "IPv6AddressRange": null,
                "NetworkGroup": null,
                "Network_IPV_4": null,
                "Network_IPV_6": null,
                "RecurringTimePeriod": null,
                "RecurringTimePeriodGroup": null,
                "Service": null,
                "ServiceGroup": null,
                "ServiceRange": null,
                "description": null,
                "domain": 0,
                "hostCriticality": "HIGH",
                "name": "testing",
                "ruleobjId": "134",
                "ruleobjType": "Endpoint IP V.4",
                "visibleToChild": true
            },
            {
                "ApplicationGroup": null,
                "ApplicationOnCustomPort": null,
                "FiniteTimePeriod": null,
                "HostDNSName": null,
                "HostIPv4": null,
                "HostIPv6": null,
                "IPv4AddressRange": {
                    "IPV4RangeList": [
                        {
                            "FromAddress": "1.1.1.1",
                            "ToAddress": "2.2.2.2"
                        }
                    ]
                },
                "IPv6AddressRange": null,
                "NetworkGroup": null,
                "Network_IPV_4": null,
                "Network_IPV_6": null,
                "RecurringTimePeriod": null,
                "RecurringTimePeriodGroup": null,
                "Service": null,
                "ServiceGroup": null,
                "ServiceRange": null,
                "description": null,
                "domain": 0,
                "hostCriticality": null,
                "name": "ruleo",
                "ruleobjId": "133",
                "ruleobjType": "Range IP V.4",
                "visibleToChild": true
            }
        ]
    }
}

Human Readable Output

List of Rule Objects

RuleId Name VisibleToChild RuleType
134 testing true Endpoint IP V.4
133 ruleo true Range IP V.4

nsm-get-rule-object


Gets the details of a rule object.

Base Command

nsm-get-rule-object

Input

Argument Name Description Required
rule_id The ID of the rule object. To get the rule object ID, use the !nsm-list-domain-rule-object. Required

Context Output

Path Type Description
NSM.Rule.ruleobjId String The ID of the rule object.
NSM.Rule.ruleobjType String The type of the rule object.
NSM.Rule.name String The name of the rule object.
NSM.Rule.description String The description of the rule object.
NSM.Rule.domain Number The name of the rule object.
NSM.Rule.visibleToChild Boolean Whether the rule is visible to child domains.
NSM.Rule.ApplicationGroup Unknown Application Group object. Should be defined if ruleobjType is “APPLICATION_GROUP”.
NSM.Rule.ApplicationOnCustomPort Unknown Application defined on Custom Port object. Should be defined if ruleobjType is “APPLICATION_ON_CUSTOM_PORT”.
NSM.Rule.FiniteTimePeriod Unknown Finite Time Period object. Should be defined if ruleobjType is “FINITE_TIME_PERIOD”.
NSM.Rule.HostIPv4 Unknown Host IPv4 Address object. Should be defined if ruleobjType is “HOST_IPV_4”.
NSM.Rule.HostIPv6 Unknown Host IPv6 Address object. Should be defined if ruleobjType is “HOST_IPV_6”.
NSM.Rule.HostDNSName Unknown Host DNS Name object. Should be defined if ruleobjType is “HOST_DNS_NAME”.
NSM.Rule.IPv4AddressRange Unknown IPv4 Address Range object. Should be defined if ruleobjType is “IPV_4_ADDRESS_RANGE”.
NSM.Rule.IPv6AddressRange Unknown IPv6 Address Range object. Should be defined if ruleobjType is “IPV_6_ADDRESS_RANGE”.
NSM.Rule.Network_IPV_4 Unknown IPv4 Network object. Should be defined if ruleobjType is “NETWORK_IPV_4.
NSM.Rule.Network_IPV_6 String IPv6 Network object. Should be defined if ruleobjType is “NETWORK_IPV_6”.
NSM.Rule.NetworkGroup Unknown Network Group object. Should be defined if ruleobjType is “NETWORK_GROUP”.
NSM.Rule.RecurringTimePeriod Unknown Recurring Time Period object. Should be defined if ruleobjType is “RECURRING_TIME_PERIOD”.
NSM.Rule.RecurringTimePeriodGroup Unknown Recurring Time Period Group object. Should be defined if ruleobjType is “RECURRING_TIME_PERIOD_GROUP”.
NSM.Rule.Service Unknown Service object. Should be defined if ruleobjType is “CUSTOM_SERVICE”.
NSM.Rule.ServiceGroup Unknown Service Group object. Should be defined if ruleobjType is “SERVICE_GROUP”.
NSM.Rule.ServiceRange Unknown Service Range object. Should be defined if ruleobjType is “SERVICE_RANGE”.
NSM.Rule.IPv6AddressRange.IPV6RangeList String List of IPv6 Address Range.
NSM.Rule.HostIPv6.hostIPv6AddressList String Host IPv6 address list.
NSM.Rule.Network_IPV_4.networkIPV4List String Network IPV4 list.
NSM.Rule.Network_IPV_6.networkIPV6List String Network IPV6 list.
NSM.Rule.IPv4AddressRange.IPV4RangeList String List of IPv4 Address Range.
NSM.Rule.HostIPv4.hostIPv4AddressList String Host IPv4 address list.

nsm-create-rule-object


Adds a new rule object.

  • If the type is “Endpoint IP V.X” or “Network IP V.X”, only the argument “address_ip_v.X” must contain a value.
  • If the type is “Range IP V.X”, only the arguments “from_address_ip_v.X”, “to_address_ip_v.X” must contain a value. Where X is 4 or 6 respectively.

Base Command

nsm-create-rule-object

Input

Argument Name Description Required
domain The ID of the domain. To get the domain ID, use the !nsm-get-domains command. Required
rule_object_type The type of the rule.
If the type is “Endpoint IP V.X” or “Network IP V.X”, only the argument “address_ip_v.X” must contain a value.
If the type is “Range IP V.X”, only the arguments “from_address_ip_v.X”, “to_address_ip_v.X” must contain a value, where X is 4 or 6 respectively.
* Possible values are: Endpoint IP V.4, Range IP V.4, Network IP V.4, Endpoint IP V.6, Range IP V.6, Network IP V.6.
Required
name The rule object name. Required
visible_to_child Whether the rule object is visible to the child domain. Possible values are: yes, no. Default is yes. Optional
description The description of the rule object. Optional
address_ip_v.4 List of IPv4 Host Address, separated by a comma. Optional
from_address_ip_v.4 Start of the IPv4 range. Optional
to_address_ip_v.4 End of the IPv4 range. Optional
address_ip_v.6 List of IPv6 host addresses, separated by a comma. Optional
from_address_ip_v.6 Start of the IPv6 range. Optional
to_address_ip_v.6 End of the IPv6 range. Optional
state Whether to enable or disable the rule object. Note: This argument is only relevant to version 10x. Default value is ‘Enabled’ Optional

Context Output

Path Type Description
NSM.Rule.ruleobjId Number The ID of the newly created rule object.

Command example

!nsm-create-rule-object domain=0 rule_object_type="Range IP V.4" name="ruleo" visible_to_child=yes from_address_ip_v.4=1.1.1.1 to_address_ip_v.4=2.2.2.2

Context Example

{
    "NSM": {
        "Rule": {
            "ruleobjId": 154
        }
    }
}

Human Readable Output

The rule object no.154 was created successfully

nsm-update-rule-object


Updates a Rule object. In case of address rule update:

  • if the rule type is “Endpoint IP V.X” or “Network IP V.X”, only the argument “address_ip_v.X” should contain a value.
  • If the type is “Range IP V.X”, only the arguments “from_address_ip_v.X”, “to_address_ip_v.X” should contain a value, Where X is 4 or 6 respectively.

Base Command

nsm-update-rule-object

Input

Argument Name Description Required
domain The ID of the domain. To get the domain ID, use the !nsm-get-domains command. Required
rule_id The ID of the rule. To get the rule object ID, use the !nsm-list-domain-rule-object. Required
name The rule object name. Optional
visible_to_child Whether the rule object is visible to the child domain. Possible values are: yes, no. Default is yes. Optional
description The description of the rule object. Optional
address_ip_v.4 List of IPv4 host addresses, separated by a comma. Optional
from_address_ip_v.4 Start of the IPv4 range. Optional
to_address_ip_v.4 End of the IPv4 range. Optional
address_ip_v.6 List of IPv6 host addresses, separated by a comma. Optional
from_address_ip_v.6 Start of the IPv6 range. Optional
to_address_ip_v.6 End of the IPv6 range. Optional
is_overwrite Whether the new addresses that were provided in the update processes will override the current ones or will be added to them. The default is false, and the addresses will be added. Possible values are: true, false. Optional
state Whether to enable or disable the rule object. Note: This argument is only relevant to version 10x. Default value is ‘Enabled’ Optional

Context Output

There is no context output for this command.

Command example

!nsm-update-rule-object domain=0 rule_id=125 description="new desc"

Human Readable Output

The rule object no.125 was updated successfully.

nsm-delete-rule-object


Deletes a rule object.

Base Command

nsm-delete-rule-object

Input

Argument Name Description Required
rule_id The ID of the rule object. To get the rule object ID, use the !nsm-list-domain-rule-object. Required

Context Output

There is no context output for this command.

Command example

!nsm-delete-rule-object rule_id=125

Human Readable Output

The rule object no.125 was deleted successfully.

nsm-get-alerts


Retrieves the alerts.

Base Command

nsm-get-alerts

Input

Argument Name Description Required
limit The maximum number of records to return. Default is 50. Optional
page The specific result page to display. Optional
page_size The number of records in a page. Optional
time_period Time period. Possible values are: LAST_5_MINUTES, LAST_1_HOUR, LAST_6_HOURS, LAST_12_HOURS, LAST_24_HOURS, LAST_7_DAYS, LAST_14_DAYS, CUSTOM. Default is LAST_7_DAYS. Optional
start_time Start time in “mm/dd/yyyy HH:MM” format. Used for custom time only. Optional
end_time End time in “mm/dd/yyyy HH:MM” format. Used for custom time only. Optional
state Alert state. Possible values are: ANY, Acknowledged, Unacknowledged. Default is ANY. Optional
search Search string in alert details. Optional
filter Filter alert by fields. For example: “name:hello;direction:Inbound,Outbound;attackcount:>3,<4”. To use the “name” field in the filter, enter only one name in each command run. Filter on the following columns is allowed- name, assignTo, application, layer7Data, result, attackCount, relevance, alertId, direction, device, domain, interface, attackSeverity, nspId, btp, attackCategory, malwarefileName, malwarefileHash, malwareName, malwareConfidence, malwareEngine ,executableName, executableHash, executableConfidenceName, attackerIPAddress, attackerPort, attackerRisk, attackerProxyIP, attackerHostname, targetIPAddress, targetPort, targetRisk, targetProxyIP, targetHostname, botnetFamily. Optional
domain_id The ID of the domain. To get the domain_id, use the !nsm-get-domains command. Optional

Context Output

Path Type Description
NSM.Alerts.ID number Alert ID.
NSM.Alerts.Name String Alert name.
NSM.Alerts.uniqueAlertId String Unique alert ID.
NSM.Alerts.State String Alert state (Acknowledged,Unacknowledged).
NSM.Alerts.Assignee String Alert assignee.
NSM.Alerts.CreatedTime String Alert creation time.
NSM.Alerts.AttackSeverity String Alert severity.
NSM.Alerts.Event.time Date The creation time of the event that triggered the alert.
NSM.Alerts.Event.direction String The direction of the event (Outbound, Inbound).
NSM.Alerts.Event.result String The result of the event.
NSM.Alerts.Event.attackCount Number Attack count.
NSM.Alerts.Event.relevance String The event relevance.
NSM.Alerts.Event.alertId String Alert ID.
NSM.Alerts.Event.domain String The event’s domain.
NSM.Alerts.Event.interface String The event’s interface.
NSM.Alerts.Event.device String The relevant device.
NSM.Alerts.Attack.nspId String Network Security Platform (NSP) ID.
NSM.Alerts.Attack.btp String Benign Trigger Probability (BTP).
NSM.Alerts.Attack.attackCategory String The attack category.
NSM.Alerts.Attacker.ipAddrs String The attacker IP address.
NSM.Alerts.Attacker.port Number The attacker port.
NSM.Alerts.Attacker.hostName String The attacker host name.
NSM.Alerts.Attacker.country String The attacker country.
NSM.Alerts.Attacker.os Unknown The attacker operating system.
NSM.Alerts.Attacker.vmName Unknown The attacker VM name.
NSM.Alerts.Attacker.proxyIP String The attacker proxy IP.
NSM.Alerts.Attacker.user Unknown The user.
NSM.Alerts.Attacker.risk String Attacker risk.
NSM.Alerts.Attacker.networkObject Unknown The attacker network object.
NSM.Alerts.Target.ipAddrs String The target IP address.
NSM.Alerts.Target.port Number The target port.
NSM.Alerts.Target.hostName String The target host name.
NSM.Alerts.Target.country String The target country.
NSM.Alerts.Target.os Unknown The target operating system.
NSM.Alerts.Target.vmName Unknown The target VM name.
NSM.Alerts.Target.proxyIP String The target proxy IP.
NSM.Alerts.Target.user Unknown The target user.
NSM.Alerts.Target.risk String The target risk.
NSM.Alerts.Target.networkObject Unknown The target network object.
NSM.Alerts.MalwareFile.fileName String The name of the malware file.
NSM.Alerts.MalwareFile.fileHash String The file hash of the malware file.
NSM.Alerts.MalwareFile.fileSHA1Hash String The malware file SHA1 hash.
NSM.Alerts.MalwareFile.fileSHA256Hash Unknown The file SHA256 hash of the malware file.
NSM.Alerts.MalwareFile.malwareName String The name of the malware.
NSM.Alerts.MalwareFile.malwareConfidence String Malware confidence
NSM.Alerts.MalwareFile.engine String Malware file engine.
NSM.Alerts.MalwareFile.engineId Number Malware file engine ID.
NSM.Alerts.MalwareFile.size Unknown The malware file size.
NSM.Alerts.MalwareFile.description Unknown Malware file description.
NSM.Alerts.MalwareFile.additionalReference Unknown Malware file additional reference.
NSM.Alerts.MalwareFile.cveId Unknown Malware file CVE ID.
NSM.Alerts.endpointExcutable.name String Endpoint executable name.
NSM.Alerts.endpointExcutable.hash String Endpoint executable hash.
NSM.Alerts.endpointExcutable.malwareConfidence String Endpoint executable malware confidence.
NSM.Alerts.detection.managerId Number manager ID.
NSM.Alerts.detection.manager Unknown The detection manager.
NSM.Alerts.detection.domain String Detection domain.
NSM.Alerts.detection.device String Detection device.
NSM.Alerts.detection.deviceId String Detection device ID.
NSM.Alerts.detection.interface String Detection interface.
NSM.Alerts.Application String The application associated to the alert.
NSM.Alerts.layer7Data String Layer 7 information.
NSM.Alerts.EventResult String Event result.
NSM.Alerts.SensorID String Sensor ID.

Command example

!nsm-get-alerts domain_id=0 time_period=CUSTOM start_time="12/17/2000 14:14:22" end_time="12/18/2022 00:26:45" limit=2

Context Example

{
    "NSM": {
        "Alerts": [
            {
                "Application": "HTTP",
                "Assignee": "",
                "Attack": {
                    "attackCategory": "Exploit",
                    "btp": "Medium",
                    "nspId": "0x00000000"
                },
                "Attacker": {
                    "country": null,
                    "hostName": "",
                    "ipAddrs": "1.1.1.1",
                    "networkObject": null,
                    "os": null,
                    "port": 22222,
                    "proxyIP": "",
                    "risk": "Disabled",
                    "user": null,
                    "vmName": null
                },
                "CreatedTime": "Dec 17, 2018 21:06:21",
                "Event": {
                    "alertId": "3333333333333333333",
                    "attackCount": 1,
                    "device": "VVVV1",
                    "direction": "Outbound",
                    "domain": "/My Domain",
                    "interface": "1-2",
                    "relevance": "Unknown",
                    "result": "Inconclusive",
                    "time": "Dec 17, 2018 21:06:21"
                },
                "EventResult": "Inconclusive",
                "ID": "3333333333333333333",
                "MalwareFile": {
                    "additionalReference": null,
                    "cveId": null,
                    "description": null,
                    "engine": "",
                    "engineId": 0,
                    "fileHash": "",
                    "fileName": "",
                    "malwareConfidence": "",
                    "malwareName": "",
                    "size": null
                },
                "Name": "HTTP: vulnerability",
                "SensorID": "4444",
                "Target": {
                    "country": null,
                    "hostName": "",
                    "ipAddrs": "2.2.2.2",
                    "networkObject": null,
                    "os": null,
                    "port": 80,
                    "proxyIP": "",
                    "risk": "Disabled",
                    "user": null,
                    "vmName": null
                },
                "State": "Acknowledged",
                "attackSeverity": "High",
                "detection": {
                    "device": "VVVV1",
                    "deviceId": "4444",
                    "domain": "/My Domain",
                    "interface": "1-2",
                    "manager": null,
                    "managerId": 0
                },
                "endpointExcutable": {
                    "hash": "",
                    "malwareConfidence": "",
                    "name": ""
                },
                "layer7Data": "HTTP Request Method: GET ",
                "uniqueAlertId": "1212121212121212121"
            },
            {
                "Application": "Web",
                "Assignee": "",
                "Attack": {
                    "attackCategory": "Exploit",
                    "btp": "Low",
                    "nspId": "0x00000000"
                },
                "Attacker": {
                    "country": null,
                    "hostName": "",
                    "ipAddrs": "1.1.1.1",
                    "networkObject": null,
                    "os": null,
                    "port": 12345,
                    "proxyIP": "",
                    "risk": "---",
                    "user": null,
                    "vmName": null
                },
                "CreatedTime": "Dec 17, 2018 21:04:21",
                "Event": {
                    "alertId": "5555555555555555555",
                    "attackCount": 1,
                    "device": "VVVV1",
                    "direction": "Inbound",
                    "domain": "/My Dmain",
                    "interface": "1-2",
                    "relevance": "Unknown",
                    "result": "Inconclusive",
                    "time": "Dec 17, 2018 21:04:21"
                },
                "EventResult": "Inconclusive",
                "ID": "5555555555555555555",
                "MalwareFile": {
                    "additionalReference": null,
                    "cveId": null,
                    "description": null,
                    "engine": "",
                    "engineId": 0,
                    "fileHash": "",
                    "fileName": "",
                    "malwareConfidence": "",
                    "malwareName": "",
                    "size": null
                },
                "Name": "HTTP: IIS 6.0 (CVE-2017-7269)",
                "SensorID": "4444",
                "Target": {
                    "country": null,
                    "hostName": "",
                    "ipAddrs": "2.2.2.2",
                    "networkObject": null,
                    "os": null,
                    "port": 80,
                    "proxyIP": "",
                    "risk": "---",
                    "user": null,
                    "vmName": null
                },
                "alertState": "Acknowledged",
                "attackSeverity": "High",
                "detection": {
                    "device": "VVVV1",
                    "deviceId": "4444",
                    "domain": "/My Domain",
                    "interface": "1-2",
                    "manager": null,
                    "managerId": 0
                },
                "endpointExcutable": {
                    "hash": "",
                    "malwareConfidence": "",
                    "name": ""
                },
                "layer7Data": "HTTP Request Method: PROPFIND",
                "uniqueAlertId": "2323232323232323232"
            }
        ]
    }
}

Human Readable Output

Alerts list. Showing 2 of 20

ID Name Severity State
3333333333333333333 HTTP: vulnerability High Acknowledged
5555555555555555555 HTTP: IIS 6.0 (CVE-2017-7269) High Acknowledged

nsm-get-alert-details


Retrieves the relevant alert details.

Base Command

nsm-get-alert-details

Input

Argument Name Description Required
alert_id Alert ID. In order to get the alert ID, use the command ‘!nsm-get-alerts’ and use the output field “ID”. Required
sensor_id Sensor ID. In order to get the sensor ID, use the command ‘!nsm-get-alerts’ and use the output field “SensorID”. Required

Context Output

Path Type Description
NSM.Alerts.ID number Alert ID.
NSM.Alerts.Name String Alert name.
NSM.Alerts.CreatedTime String Alert creation time.
NSM.Alerts.uniqueAlertId String Unique alert ID.
NSM.Alerts.State String The state of the alert.
NSM.Alerts.Assignee String Alert assignee.
NSM.Alerts.Event.application String The event application.
NSM.Alerts.Event.protocol Unknown The event protocol.
NSM.Alerts.Event.domain String The domain of the event.
NSM.Alerts.Event.manager Unknown The event manager.
NSM.Alerts.Event.device String The event device.
NSM.Alerts.Event.deviceId String The ID of the device related to the event.
NSM.Alerts.Event.matchedPolicy String The policy that matched the event.
NSM.Alerts.Event.zone Unknown The event zone.
NSM.Alerts.Event.vlan String The event VLAN.
NSM.Alerts.Event.detection String The event detection.
NSM.Alerts.CreatedTime Date The creation time of the event.
NSM.Alerts.EventResult String The event result.
NSM.Alerts.Event.attackCount Number Event attack count.
NSM.Alerts.Event.relevance String The relevance of the event.
NSM.Alerts.Event.alertId String Alert ID.
NSM.Alerts.Attacker.ipAddrs Unknown Attacker IP addresses.
NSM.Alerts.Attacker.port Number Attacker port.
NSM.Alerts.Attacker.hostName Unknown Attacker host name.
NSM.Alerts.Attacker.country Unknown Attacker country.
NSM.Alerts.Attacker.os String Attacker operating system.
NSM.Alerts.Attacker.vmName Unknown Attacker VM name.
NSM.Alerts.Attacker.proxyIP Unknown Attacker proxy IP.
NSM.Alerts.Attacker.user String Attacker user.
NSM.Alerts.Attacker.risk String Attacker risk.
NSM.Alerts.Attacker.networkObject String Attacker network object.
NSM.Alerts.Target.ipAddrs Unknown Target IP address.
NSM.Alerts.Target.port Number Target port.
NSM.Alerts.Target.hostName Unknown Target host name.
NSM.Alerts.Target.country Unknown Target country.
NSM.Alerts.Target.os String Target operating system.
NSM.Alerts.Target.vmName Unknown Target VM name.
NSM.Alerts.Target.proxyIP Unknown Target proxy IP.
NSM.Alerts.Target.user String Target user.
NSM.Alerts.Target.risk String Target risk.
NSM.Alerts.Target.networkObject String Target network object.
NSM.Alerts.summary.source Unknown The source of the alert.
NSM.Alerts.summary.destination Unknown The destination of the alert.
NSM.Alerts.summary.zoombie Unknown Alert zoombie.
NSM.Alerts.summary.cAndcServer Unknown The command and control server.
NSM.Alerts.summary.fastFluxAgent Unknown Fast flux agent.
NSM.Alerts.summary.attackedHIPEndpoint Unknown Attacked host intrusion prevention (HIP) endpoint.
NSM.Alerts.summary.compromisedEndpoint Unknown Compromised endpoint.
NSM.Alerts.Details.matchedSignature Unknown Matched signature.
NSM.Alerts.MalwareFile Unknown Malware file.
NSM.Alerts.Details.hostSweep Unknown Host sweep.
NSM.Alerts.Details.portScan Unknown Port scan.
NSM.Alerts.Details.fastFlux Unknown Fast flux.
NSM.Alerts.Details.triggeredComponentAttacks Unknown Triggered component attack.
NSM.Alerts.Details.sqlInjection Unknown SQL injection.
NSM.Alerts.Details.callbackDetectors Unknown Callback detectors.
NSM.Alerts.Details.exceededThreshold Unknown Exceeded threshold.
NSM.Alerts.Details.communicationRuleMatch Unknown Communication rule match.
NSM.Alerts.Description String Description.
NSM.Alerts.Description.btp String Benign Trigger Probability (BTP).
NSM.Alerts.Description.rfSB String Recommended For Smart Blocking (RFSB).
NSM.Alerts.Description.protectionCategory String Protection category.
NSM.Alerts.Description.target String The target.
NSM.Alerts.Description.httpResponseAttack String HTTP response attack.
NSM.Alerts.Description.priority String Priority.
NSM.Alerts.Protocols String Protocols.
NSM.Alerts.Attack.attackCategory String Attack category.
NSM.Alerts.Attack.attackSubCategory String Attack sub-category.
NSM.Alerts.Description.snortEngine String Snort engine.
NSM.Alerts.Description.versionAdded String The date the version was added.
NSM.Alerts.Description.versionUpdated Unknown The date the version was updated.
NSM.Alerts.Attack.nspId String Network Security Platform (NSP) ID.
NSM.Alerts.Description.reference.cveId String Common Vulnerabilities and Exposures (CVE) ID.
NSM.Alerts.Description.reference.microsoftId String Microsoft ID.
NSM.Alerts.Description.reference.bugtraqId String Bugtraq ID.
NSM.Alerts.Description.reference.certId Unknown Cert ID.
NSM.Alerts.Description.reference.arachNidsId String Arachnics ID.
NSM.Alerts.Description.reference.additionInfo String Additional information.
NSM.Alerts.Description.comments.comments String Comments.
NSM.Alerts.Description.comments.availabeToChildDomains Boolean Whether the alert is available to child domains.
NSM.Alerts.Description.comments.parentDomainComments Unknown Parent domain comments.
NSM.Alerts.Event.direction String The event direction.
NSM.Alerts.Event.interface String The event interface.

Command example

!nsm-get-alert-details alert_id=6666666666666666666 sensor_id=1001

Context Example

{
    "NSM": {
        "Alerts": {
            "ID": "6666666666666666666",
            "Name": "Buffer Overflow",
            "uniqueAlertId": "3333333333333333333",
            "State": "UnAcknowledged",
            "CreatedTime": "Apr 23, 2020 22:26:13",
            "Assignee": "---",
            "Description": "some description",
            "EventResult": "Inconclusive",
            "Attack": {
                "attackCategory": "Exploit",
                "attackSubCategory": "Buffer Overflow",
                "nspId": "0x00000000"
            },
            "Protocols": "dns",
            "SensorID": "1001",
            "Event": {
                    "application": "Not Available",
                    "protocol": "telnet",
                    "domain": "/My Domain",
                    "manager": null,
                    "device": "vm600-nsmapi-cc",
                    "interface": "1-2",
                    "matchedPolicy": "Default Prevention",
                    "zone": null,
                    "vlan": "-10",
                    "detection": "Application anomaly",
                    "direction": "Inbound",
                    "attackCount": 1,
                    "relevance": "Unknown",
                    "alertId": "6666666666666666666"
                },
            "Attacker": {
                    "ipAddrs": "9.9.9.9",
                    "port": 11111,
                    "hostName": null,
                    "country": null,
                    "os": "Microsoft Windows Server 2008",
                    "vmName": null,
                    "proxyIP": null,
                    "user": "Unknown",
                    "risk": "N/A",
                    "networkObject": "---"
                },
            "Target": {
                    "ipAddrs": "1.1.1.1",
                    "port": 88888,
                    "hostName": null,
                    "country": null,
                    "os": "Microsoft Windows Server 2003 Service Pack 1",
                    "vmName": null,
                    "proxyIP": null,
                    "user": "Unknown",
                    "risk": "N/A",
                    "networkObject": "---"
                },
            "MalwareFile": null,
            "summary": {
                "source": null,
                "destination": null,
                "zoombie": null,
                "cAndcServer": null,
                "fastFluxAgent": null,
                "attackedHIPEndpoint": null,
                "compromisedEndpoint": null
            },
            "Details": {
                "matchedSignature": {
                    "signatureName": "overflow-iquery.c",
                    "signature": {
                        "name": "Signature#1",
                        "conditions": [
                            "condition 1",
                            "condition 2",
                            "condition 3",
                            "condition 4"
                        ]
                    }
                },
                "layer7": null,
                "hostSweep": null,
                "portScan": null,
                "fastFlux": null,
                "triggeredComponentAttacks": null,
                "sqlInjection": null,
                "callbackDetectors": null,
                "exceededThreshold": null,
                "communicationRuleMatch": null
            },
            "description": {
                "btp": "Low",
                "rfSB": "Yes",
                "protectionCategory": "[Server Protection/Name Servers]",
                "target": "Server",
                "httpResponseAttack": "No",
                "priority": "High",
                "reference": {
                    "cveId": "CVE-1999-0009",
                    "microsoftId": "",
                    "bugtraqId": "123",
                    "certId": null,
                    "arachNidsId": "",
                    "additionInfo": "http://www.website.com/"
                },
                "signatures": [
                    {
                        "name": "Signature#1",
                        "conditions": [
                            "condition 1",
                            "condition 2",
                            "condition 3",
                            "condition 4"
                        ]
                    },
                    {
                        "name": "Signature#2",
                        "conditions": [
                            "condition 1",
                            "condition 2",
                            "condition 3",
                            "condition 4"
                        ]
                    },
                    {
                        "name": "Signature#3",
                        "conditions": [
                            "condition 1",
                            "condition 2",
                            "condition 3",
                            "condition 4",
                            "condition 5"
                        ]
                    }
                ],
                "componentAttacks": [],
                "comments": {
                    "comments": "",
                    "availabeToChildDomains": true,
                    "parentDomainComments": null
                }
            }
        }
    }
}

Human Readable Output

Alerts list. Showing 2 of 20

ID Name Event Time State Direction Result Attack Count Attacker IP Target IP
6666666666666666666 Buffer Overflow Apr 23, 2020 22:26:13 UnAcknowledged Inbound Inconclusive 1 9.9.9.9 1.1.1.1

nsm-get-attacks


If an attack is given, the command returns the details for the specific attack. Otherwise, gets all available attack definitions in the Manager UI. This command can take a few minutes. If you get a timeout error, increase the timeout by using the parameter “execution-timeout”.

Base Command

nsm-get-attacks

Input

Argument Name Description Required
attack_id The ID of the attack. To get the attack_id, use the !nsm-get-attacks command, without an attack ID. Optional

Context Output

Path Type Description
InfoFile.Name string File name.
InfoFile.EntryID string The entry ID of the report.
InfoFile.Size number File size.
InfoFile.Type string File type, e.g., “PE”.
InfoFile.Info string Basic information about the file.
NSM.Attacks.Direction Unknown Attack direction.
NSM.Attacks.Severity Number Attack severity.
NSM.Attacks.ID String Attack ID.
NSM.Attacks.Name String Attack name.
NSM.Attacks.Category String Attack category.
NSM.Attacks.description.definition String Attack Definition
NSM.Attacks.description.btp String Benign Trigger Probability (BTP).
NSM.Attacks.description.rfSB String Recommended For Smart Blocking (RFSB).
NSM.Attacks.description.protectionCategory String Protection category.
NSM.Attacks.description.target String Attack target.
NSM.Attacks.description.httpResponseAttack String HTTP Response Attack.
NSM.Attacks.description.priority String Attack priority.
NSM.Attacks.description.protocols String Attack protocols.
NSM.Attacks.description.attackCategory String Attack category.
NSM.Attacks.description.attackSubCategory String Attack sub-category.
NSM.Attacks.description.snortEngine String Attack snort engine.
NSM.Attacks.description.versionAdded String The date the attack version was added.
NSM.Attacks.description.versionUpdated String The date the attack version was updated.
NSM.Attacks.description.reference.nspId String Attack Network Security Platform (NSP) ID.
NSM.Attacks.description.reference.cveId String Attack Common Vulnerabilities and Exposures (CVE) ID.
NSM.Attacks.description.reference.microsoftId String Attack Microsoft ID.
NSM.Attacks.description.reference.bugtraqId String Attack bugtraq ID.
NSM.Attacks.description.reference.certId String Attack cert ID.
NSM.Attacks.description.reference.arachNidsId String Arachnids ID.
NSM.Attacks.description.reference.additionInfo Unknown Additional information.
NSM.Attacks.description.comments.comments String Comments.
NSM.Attacks.description.comments.availabeToChildDomains Boolean Whether the attack is available to child domains.
NSM.Attacks.description.comments.parentDomainComments Unknown Parent domain comments.

Command example

!nsm-get-attacks attack_id=0x00000100

Context Example

{
    "NSM": {
        "Attacks": {
            "Category": null,
            "Direction": null,
            "ID": "0x00000100",
            "Name": "IP: too Large",
            "Severity": 5,
            "UiCategory": "EXPLOIT"
        }
    }
}

Human Readable Output

Attack no.0x00000100

ID Name Severity
0x00000100 IP: too Large 5

nsm-get-domains


If a domain ID is given, the command returns the details of the specific domain. Otherwise, gets all available domains.

Base Command

nsm-get-domains

Input

Argument Name Description Required
domain_id Specific domain ID. Leave blank for all domains. To get the domain_id use !nsm-get-domains command and leave the parameter blank. Optional
limit The maximum number of records to return. Default is 50.0. Optional
page The specific result page to display. Optional
page_size The number of records in a page. Optional

Context Output

Path Type Description
NSM.Domains.ID Number Domain ID.
NSM.Domains.Name String Domain name.
NSM.Domains.childdomains Unknown The children of the domain.

Command example


#### Context Example

```json
{
    "NSM": {
        "Domains": {
            "ID": 0,
            "Name": "My Company",
            "childdomains": []
        }
    }
}

Human Readable Output

List of Domains

ID Name
0 My Company

nsm-get-sensors


Gets the list of sensors available in the specified domain. If the domain is not specified, details of all the sensors in all ADs will be provided.

Base Command

nsm-get-sensors

Input

Argument Name Description Required
domain_id Specific domain ID. Leave blank for all domains. To get the domain_id use !nsm-get-domains command and leave the parameter blank. Optional
limit The maximum number of records to return. Default is 50. Optional
page The specific result page to display. Optional
page_size The number of records in a page. Optional

Context Output

Path Type Description
NSM.Sensors.ID Number Sensor ID.
NSM.Sensors.Name String Name of the sensor.
NSM.Sensors.model String Sensor model.
NSM.Sensors.Description String Sensor description.
NSM.Sensors.DomainID Number ID of the domain to which this sensor belongs.
NSM.Sensors.isFailOver Boolean Whether the sensor is failover.
NSM.Sensors.isNTBA Boolean Whether there is Network Threat Behavior Analysis (NTBA).
NSM.Sensors.isLoadBalancer Boolean Whether the sensor is a load balancer.
NSM.Sensors.SerialNumber Unknown The sensor serial number.
NSM.Sensors.SigsetVersion String Signature set version number applied to the sensor.
NSM.Sensors.DATVersion String DAT version of the sensor.
NSM.Sensors.SoftwareVersion String Sensor software version.
NSM.Sensors.LastSignatureUpdateTs Date Last configuration download timestamp.
NSM.Sensors.IPSPolicyID Number Intrusion prevent system (IPS) policy ID applied to the sensor.
NSM.Sensors.ReconPolicyID Number Recon policy ID applied to the sensor.
NSM.Sensors.LastModTs Unknown Last modified timestamp.
NSM.Sensors.IP Address String Sensor IP address.
NSM.Sensors.nsmVersion String Network Security Manager (NSM) version.
NSM.Sensors.MemberSensors Unknown Sensors members.

Command example


#### Context Example

```json
{
    "NSM": {
        "Sensors": {
            "DATVersion": null,
            "Description": "MCAFEE-NETWORK-SECURITY-PLATFORM",
            "DomainID": 0,
            "ID": 1111,
            "IP Address": "1.1.1.1",
            "IPSPolicyID": 0,
            "LastModTs": null,
            "LastSignatureUpdateTs": "2022-12-04 02:07:45",
            "MemberSensors": [],
            "Name": "VVVV1",
            "ReconPolicyID": 0,
            "SigsetVersion": null,
            "SoftwareVersion": "9.9.9.9",
            "isFailOver": false,
            "isLoadBalancer": false,
            "model": "IPS-VM100",
            "nsmVersion": "9.1"
        }
    }
}

Human Readable Output

Sensors List

ID Name Description DomainID IPSPolicyID IP Address
1111 VVVV1 MCAFEE-NETWORK-SECURITY-PLATFORM 0 0 1.1.1.1

nsm-get-ips-policies


Gets all the IPS policies defined in the specific domain.

Base Command

nsm-get-ips-policies

Input

Argument Name Description Required
domain_id Specific domain ID. To get the domain_id use !nsm-get-domains command and leave the parameter blank. Required
limit The maximum number of records to return. Default is 50. Optional
page The specific result page to display. Optional
page_size The number of records in a page. Optional

Context Output

Path Type Description
NSM.IPSPolicies.IsEditable Boolean Whether the IPS policy is editable.
NSM.IPSPolicies.DomainID Number ID of the domain to which this policy belongs.
NSM.IPSPolicies.VisibleToChildren Boolean Policy visible to child domain.
NSM.IPSPolicies.ID Number IPS policy ID.
NSM.IPSPolicies.Name String IPS policy name.

Command example

!nsm-get-ips-policies domain_id=0 limit=2

Context Example

{
    "NSM": {
        "IPSPolicies": [
            {
                "DomainID": 0,
                "ID": -1,
                "IsEditable": true,
                "Name": "Master",
                "VisibleToChildren": true
            },
            {
                "DomainID": 0,
                "ID": 0,
                "IsEditable": true,
                "Name": "Default",
                "VisibleToChildren": true
            }
        ]
    }
}

Human Readable Output

IPS Policies List of Domain no.0

ID Name DomainID IsEditable VisibleToChildren
-1 Master 0 true true
0 Default 0 true true

nsm-get-ips-policy-details


Gets all the IPS policies defined in the specific domain.

Base Command

nsm-get-ips-policy-details

Input

Argument Name Description Required
policy_id Specific IPS policy ID. To get the policy_id use !nsm-get-ips-policies command. Required

Context Output

Path Type Description
NSM.IPSPolicies.ID number IPS policy ID.
NSM.IPSPolicies.Name string IPS policy name.
NSM.IPSPolicies.Description string IPS policy information.
NSM.IPSPolicies.CreatedTime string Policy creation time.
NSM.IPSPolicies.IsEditable boolean Whether the IPS policy is editable.
NSM.IPSPolicies.VisibleToChildren boolean Whether the IPS Policy is visible to the domain’s children.
NSM.IPSPolicies.Version number IPS policy version.
NSM.IPSPolicies.InboundRuleSet string Inbound rule set.
NSM.IPSPolicies.OutboundRuleSet string Outbound rule set.
NSM.IPSPolicies.ExploitAttacks Unknown A list of exploit attacks related to the IPS policy.

Command example

!nsm-get-ips-policy-details policy_id=17

Context Example

{
    "NSM": {
        "IPSPolicies": {
           "ID": 17,
           "Name": "IpsPolicy",
           "Description": "To test the IPS policy",
           "VisibleToChildren": true,
           "InboundRuleSet": "TestIPS",
           "OutboundRuleSet": "Null",
           "ExpolitAttack":
               [
                   {
                       "attackName": "FTP: VMware",
                       "nspId": "0x00000000",
                       "severity": 7,
                       "isSeverityCustomized": false,
                       "isEnabled": true,
                       "isAlertCustomized": false,
                       "isRecommendedForSmartBlocking": false,
                       "AttackResponse":
                       {
                           "TCPReset": "DISABLED",
                           "isTcpResetCustomized": false,
                           "isICMPSend": false,
                           "isICMPSendCustomized": false,
                           "mcAfeeNACNotification": "DISABLED",
                           "isMcAfeeNACNotificationEnabled": false,
                           "isQuarantineCustomized": false,
                           "isRemediateEnabled": false,
                           "blockingOption": "DISABLE",
                           "isBlockingOptionCustomized": false,
                           "isCapturedPrior": true,
                           "isCapturedPriorCustomized": false,
                           "action": "SEND_ALERT_ONLY",
                           "isLogCustomized": false,
                           "isFlowCustomized": false,
                           "isNbytesCustomized": false,
                           "numberOfBytesInEachPacket":
                           {
                               "LogEntirePacket":
                               {
                               }
                           }
                       },
                       "notification":
                       {
                           "isEmail": false,
                           "isPager": false,
                           "isScript": false,
                           "isAutoAck": false,
                           "isSnmp": false,
                           "isSyslog": false,
                           "isEmailCustomized": false,
                           "isPagerCustomized": false,
                           "isScriptCustomized": false,
                           "isAutoAckCustomized": false,
                           "isSnmpCustomized": false,
                           "isSyslogCustomized": false
                       },
                       "protocolList":
                       [
                           "ftp"
                       ],
                       "benignTriggerProbability": "1 (Low)",
                       "blockingType": "attack-packet",
                       "subCategory": "code-execution",
                       "direction": "INBOUND",
                       "isAttackCustomized": false
                   }
               ],
           "AttackCategory":
           {
               
           },
           "OutboundAttackCategory":
           {
           },
           "DosPolicy":
           {
               "LearningAttack":
               [
                   {
                       "attackName": "TCP Control Segment Anomaly",
                       "nspId": "0x00000000",
                       "isSeverityCustomized": false,
                       "severity": 7,
                       "isBlockingSettingCustomized": false,
                       "isDropPacket": false,
                       "IsAlertCustomized": false,
                       "isSendAlertToManager": true,
                       "direction": "BOTH",
                       "notification":
                       {
                           "isEmail": false,
                           "isPager": false,
                           "isScript": false,
                           "isAutoAck": false,
                           "isSnmp": false,
                           "isSyslog": false,
                           "isEmailCustomized": false,
                           "isPagerCustomized": false,
                           "isScriptCustomized": false,
                           "isAutoAckCustomized": false,
                           "isSnmpCustomized": false,
                           "isSyslogCustomized": false
                       },
                       "isAttackCustomized": false
                   }
               ],
               "ThresholdAttack":
               [
                   {
                       "attackName": "Too Many Inbound TCP SYNs",
                       "nspId": "0x00000000",
                       "isSeverityCustomized": false,
                       "severity": 6,
                       "isThresholdValueCustomized": false,
                       "isThresholdDurationCustomized": false,
                       "ThresholdValue": 2000,
                       "ThresholdDuration": 5,
                       "isAlertCustomized": false,
                       "isSendAlertToManager": false,
                       "Notification":
                       {
                           "isEmail": false,
                           "isPager": false,
                           "isScript": false,
                           "isAutoAck": false,
                           "isSnmp": false,
                           "isSyslog": false,
                           "isEmailCustomized": false,
                           "isPagerCustomized": false,
                           "isScriptCustomized": false,
                           "isAutoAckCustomized": false,
                           "isSnmpCustomized": false,
                           "isSyslogCustomized": false
                       },
                       "direction": "INBOUND",
                       "isAttackCustomized": false
                   }
               ],
               "TimeStamp": "2012-06-20 18:44:55.000"
           },
           "DosResponseSensitivityLevel": 0,
           "IsEditable": false,
           "CreatedTime": "2012-06-20 18:44:55.000",
           "Version": 1,
           "IsLightWeightPolicy": false
       }
    }
}

Human Readable Output

IPS Policy no.17 Details

ID Name Description CreatedTime IsEditable VisibleToChildren Version InboundRuleSet OutboundRuleSet
17 IpsPolicy To test the IPS policy To test the IPS policy false true 1 To test the IPS policy Null

nsm-update-alerts


Update state or assignee of alerts. It is required to provide at least one of them. If none of the alerts match the time_period they won’t be updated.

Base Command

nsm-update-alerts

Input

Argument Name Description Required
state Alert state. Possible values are: ANY, Acknowledged, Unacknowledged. Default is ANY. Optional
time_period Time period. Possible values are: LAST_5_MINUTES, LAST_1_HOUR, LAST_6_HOURS, LAST_12_HOURS, LAST_24_HOURS, LAST_7_DAYS, LAST_14_DAYS, CUSTOM. Default is LAST_7_DAYS. Optional
start_time Start time in “mm/dd/yyyy HH:MM” format. Used for custom time only. Optional
end_time End time in “mm/dd/yyyy HH:MM” format. Used for custom time only. Optional
new_state The new alert state. Possible values are: Acknowledged, Unacknowledged. Optional
new_assignee The new assignee. Optional
search Search string in alert details. Optional
filter Filter alert by fields. example: “name:hello;direction:Inbound,Outbound;attackcount:>3,<4”. To use the “name” field in the filter, enter only one name in each command run. Filter on the following columns is allowed - name, assignTo, application, layer7Data, result, attackCount, relevance, alertId, direction, device, domain, interface, attackSeverity, nspId, btp, attackCategory, malwarefileName, malwarefileHash, malwareName, malwareConfidence, malwareEngine ,executableName, executableHash, executableConfidenceName, attackerIPAddress, attackerPort, attackerRisk, attackerProxyIP, attackerHostname, targetIPAddress, targetPort, targetRisk, targetProxyIP, targetHostname, botnetFamily. Optional

Context Output

Path Type Description
NSM.Alerts.ID number Alert ID.
NSM.Alerts.Name String Alert name.
NSM.Alerts.uniqueAlertId String Unique alert ID.
NSM.Alerts.State String Alert state (Acknowledged,Unacknowledged).
NSM.Alerts.Assignee String Alert assignee.
NSM.Alerts.CreatedTime String Alert creation time.
NSM.Alerts.AttackSeverity String Alert severity.
NSM.Alerts.Event.time Date The creation time of the event that triggered the alert.
NSM.Alerts.Event.direction String The direction of the event (Outbound, Inbound).
NSM.Alerts.Event.result String The result of the event.
NSM.Alerts.Event.attackCount Number Attack count.
NSM.Alerts.Event.relevance String The event relevance.
NSM.Alerts.Event.alertId String Alert ID.
NSM.Alerts.Event.domain String The domain.
NSM.Alerts.Event.interface String The event’s interface.
NSM.Alerts.Event.device String The relevant device.
NSM.Alerts.Attack.nspId String Network Security Platform (NSP) ID.
NSM.Alerts.Attack.btp String Benign Trigger Probability (BTP).
NSM.Alerts.Attack.attackCategory String The attack category.
NSM.Alerts.Attacker.ipAddrs String The attacker IP address.
NSM.Alerts.Attacker.port Number The port.
NSM.Alerts.Attacker.hostName String The attacker host name.
NSM.Alerts.Attacker.country String The attacker country.
NSM.Alerts.Attacker.os Unknown The attacker operating system.
NSM.Alerts.Attacker.vmName Unknown The attacker VM name.
NSM.Alerts.Attacker.proxyIP String The attacker proxy IP.
NSM.Alerts.Attacker.user Unknown The user.
NSM.Alerts.Attacker.risk String Attacker risk.
NSM.Alerts.Attacker.networkObject Unknown The attacker network object.
NSM.Alerts.Target.ipAddrs String The target IP address.
NSM.Alerts.Target.port Number The target port.
NSM.Alerts.Target.hostName String The target host name.
NSM.Alerts.Target.country String The target country.
NSM.Alerts.Target.os Unknown The target operating system.
NSM.Alerts.Target.vmName Unknown The target VM name.
NSM.Alerts.Target.proxyIP String The target proxy IP.
NSM.Alerts.Target.user Unknown The target user.
NSM.Alerts.Target.risk String The target risk.
NSM.Alerts.Target.networkObject Unknown The target network object.
NSM.Alerts.MalwareFile.fileName String The name of the malware file.
NSM.Alerts.MalwareFile.fileHash String The file hash of the malware file.
NSM.Alerts.MalwareFile.fileSHA1Hash String The malware file SHA1 hash.
NSM.Alerts.MalwareFile.fileSHA256Hash Unknown The file SHA256 hash of the malware file.
NSM.Alerts.MalwareFile.malwareName String The name of the malware.
NSM.Alerts.MalwareFile.malwareConfidence String Malware confidence.
NSM.Alerts.MalwareFile.engine String Malware file engine.
NSM.Alerts.MalwareFile.engineId Number Malware file engine ID.
NSM.Alerts.MalwareFile.size Unknown The Malware file size.
NSM.Alerts.MalwareFile.description Unknown Malware file description.
NSM.Alerts.MalwareFile.additionalReference Unknown Malware file additional reference.
NSM.Alerts.MalwareFile.cveId Unknown Malware File CVE ID.
NSM.Alerts.endpointExcutable.name String Endpoint executable name.
NSM.Alerts.endpointExcutable.hash String Endpoint executable hash.
NSM.Alerts.endpointExcutable.malwareConfidence String Endpoint executable malware confidence.
NSM.Alerts.detection.managerId Number Manager ID.
NSM.Alerts.detection.manager Unknown The detection manager.
NSM.Alerts.detection.domain String Detection domain.
NSM.Alerts.detection.device String Detection device.
NSM.Alerts.detection.deviceId String Detection device ID.
NSM.Alerts.detection.interface String Detection interface.
NSM.Alerts.Application String The application associated with the alert.
NSM.Alerts.layer7Data String Layer 7 information.
NSM.Alerts.EventResult String Event result.
NSM.Alerts.SensorID String Sensor ID.

Command example

!nsm-update-alerts state=Unacknowledged new_state=Acknowledged 'time_period': 'CUSTOM', 'start_time': '12/17/2000 14:14:22', 'end_time': '12/28/2022 00:26:45'

Context Example

{
    "NSM": {
        "Alerts": [
            {
                "Application": "HTTP",
                "Assignee": "",
                "Attack": {
                    "attackCategory": "Exploit",
                    "btp": "Medium",
                    "nspId": "0x00000000"
                },
                "Attacker": {
                    "country": null,
                    "hostName": "",
                    "ipAddrs": "1.1.1.1",
                    "networkObject": null,
                    "os": null,
                    "port": 22222,
                    "proxyIP": "",
                    "risk": "Disabled",
                    "user": null,
                    "vmName": null
                },
                "CreatedTime": "Dec 17, 2018 21:06:21",
                "Event": {
                    "alertId": "3333333333333333333",
                    "attackCount": 1,
                    "device": "VVVV1",
                    "direction": "Outbound",
                    "domain": "/My Domain",
                    "interface": "1-2",
                    "relevance": "Unknown",
                    "result": "Inconclusive",
                    "time": "Dec 17, 2018 21:06:21"
                },
                "EventResult": "Inconclusive",
                "ID": "3333333333333333333",
                "MalwareFile": {
                    "additionalReference": null,
                    "cveId": null,
                    "description": null,
                    "engine": "",
                    "engineId": 0,
                    "fileHash": "",
                    "fileName": "",
                    "malwareConfidence": "",
                    "malwareName": "",
                    "size": null
                },
                "Name": "HTTP: vulnerability",
                "SensorID": "4444",
                "Target": {
                    "country": null,
                    "hostName": "",
                    "ipAddrs": "2.2.2.2",
                    "networkObject": null,
                    "os": null,
                    "port": 80,
                    "proxyIP": "",
                    "risk": "Disabled",
                    "user": null,
                    "vmName": null
                },
                "State": "Acknowledged",
                "attackSeverity": "High",
                "detection": {
                    "device": "VVVV1",
                    "deviceId": "4444",
                    "domain": "/My Domain",
                    "interface": "1-2",
                    "manager": null,
                    "managerId": 0
                },
                "endpointExcutable": {
                    "hash": "",
                    "malwareConfidence": "",
                    "name": ""
                },
                "layer7Data": "HTTP Request Method: GET",
                "uniqueAlertId": "1212121212121212121"
            },
            {
                "Application": "WebDAV",
                "Assignee": "",
                "Attack": {
                    "attackCategory": "Exploit",
                    "btp": "Low",
                    "nspId": "0x00000000"
                },
                "Attacker": {
                    "country": null,
                    "hostName": "",
                    "ipAddrs": "1.1.1.1",
                    "networkObject": null,
                    "os": null,
                    "port": 11111,
                    "proxyIP": "",
                    "risk": "---",
                    "user": null,
                    "vmName": null
                },
                "CreatedTime": "Dec 17, 2018 21:04:21",
                "Event": {
                    "alertId": "5555555555555555555",
                    "attackCount": 1,
                    "device": "VVVV1",
                    "direction": "Inbound",
                    "domain": "/My Dmain",
                    "interface": "1-2",
                    "relevance": "Unknown",
                    "result": "Inconclusive",
                    "time": "Dec 17, 2018 21:04:21"
                },
                "EventResult": "Inconclusive",
                "ID": "5555555555555555555",
                "MalwareFile": {
                    "additionalReference": null,
                    "cveId": null,
                    "description": null,
                    "engine": "",
                    "engineId": 0,
                    "fileHash": "",
                    "fileName": "",
                    "malwareConfidence": "",
                    "malwareName": "",
                    "size": null
                },
                "Name": "HTTP: IIS 6.0 (CVE-2017-7269)",
                "SensorID": "4444",
                "Target": {
                    "country": null,
                    "hostName": "",
                    "ipAddrs": "2.2.2.2",
                    "networkObject": null,
                    "os": null,
                    "port": 80,
                    "proxyIP": "",
                    "risk": "---",
                    "user": null,
                    "vmName": null
                },
                "alertState": "Acknowledged",
                "attackSeverity": "High",
                "detection": {
                    "device": "VVVV1",
                    "deviceId": "4444",
                    "domain": "/My Domain",
                    "interface": "1-2",
                    "manager": null,
                    "managerId": 0
                },
                "endpointExcutable": {
                    "hash": "",
                    "malwareConfidence": "",
                    "name": ""
                },
                "layer7Data": "HTTP Request Method: PROPFIND",
                "uniqueAlertId": "2323232323232323232"
            }
        ]
    }
}

Human Readable Output

Updated Alerts list. Showing 2 of 20

ID Name Severity State
3333333333333333333 HTTP: vulnerability High Acknowledged
5555555555555555555 HTTP: IIS 6.0 (CVE-2017-7269) High Acknowledged

nsm-list-pcap-file


Retrieves the list of captured PCAP files.

Base Command

nsm-list-pcap-file

Input

Argument Name Description Required
sensor_id The ID of the sensor. To get the sensor_id, use the !nsm-get-sensors command. Required
limit The maximum number of records to return. Default is 50. Optional
page The specific result page to display. The default is 1. Optional
page_size The number of records in a page. Optional

Context Output

Path Type Description
NSM.PcapFile string PCAP file name.

Command example

!nsm-update-alerts state=Unacknowledged new_state=Acknowledged 'time_period': 'CUSTOM', 'start_time': '12/17/2000 14:14:22', 'end_time': '12/28/2022 00:26:45'

Context Example

{
    "NSM": {
        "PcapFile": [
                      {
              "files":["capture_Mon_Aug_18_16_12_49_IST_2014.pcap", "capture_Mon_Aug_18_16_12_55_IST_2014.pcap"]
            }
        ]
    }
}

Human Readable Output

PCAP files List

FileName
capture_Mon_Aug_18_16_12_49_IST_2014.pcap
capture_Mon_Aug_18_16_12_55_IST_2014.pcap

nsm-export-pcap-file


Exports the captured PCAP file.

Base Command

nsm-export-pcap-file

Input

Argument Name Description Required
sensor_id The ID of the sensor. To get the sensor_id, use the command !nsm-get-sensors. Required
file_name The name of the wanted file. To get the file_name, use the command !nsm-list-pcap-file. Required

Context Output

Path Type Description
InfoFile.Name string File name.
InfoFile.EntryID string The entry ID of the report.
InfoFile.Size number File size.
InfoFile.Type string File type, e.g., “PE”.
InfoFile.Info string Basic information about the file.

Command example

!nsm-export-pcap-file sensor_id=1003 file_name=Dummy Device Name-PacketCapture-2022-12-21_16-25-52.pcap

Human Readable Output

There isn’t a human readable.

Breaking changes from the previous version of this integration - McAfee NSM v2

The following sections list the changes in this version.

Arguments

The following arguments were removed in this version

In the nsm-get-sensors command:

  • domainID - this argument was replaced by domain_id.

In the nsm-get-domains command:

  • domain - this argument was replaced by domain_id.

The behavior of the following arguments was changed

In the nsm-get-alerts command:

  • time_period - The default value changed to ‘LAST_7_DAYS’.
  • domain_id - The default value changed to 0.

In the nsm-get-alert-details command:

  • sensor_id - Is now required.

nsm-list-domain-device


List the devices related to a given domain.

Base Command

nsm-list-domain-device

Input

Argument Name Description Required
domain_id The ID of the domain. To get the domain_id, use the !nsm-get-domains command. Required
limit The maximum number of devices to return. Optional
all_results Return all devices related to the given domain. Possible values are: yes, no. Optional

Context Output

Path Type Description
NSM.Device.ContactInformation string The contact information of the device.
NSM.Device.DeviceId number The id of the device.
NSM.Device.DeviceName string The name of the device.
NSM.Device.DeviceType string The type of the device.
NSM.Device.Location string The location of the device.
NSM.Device.UpdatingMode string The updating mode of the device.

Command example

!nsm-list-domain-device domain_id=0

Context Example

{
    "NSM": {
        "Device": [
            {
                "ContactInformation": null,
                "DeviceId": 1003,
                "DeviceName": "Dummy Device Name",
                "DeviceType": "IPS_NAC_SENSOR",
                "Location": null,
                "UpdatingMode": "ONLINE"
            }
        ]
    }
}

Human Readable Output

Domain devices List

DeviceId DeviceName DeviceType UpdatingMode
1003 Dummy Device Name IPS_NAC_SENSOR ONLINE

nsm-list-device-interface


List the interfaces related to a given device.

Base Command

nsm-list-device-interface

Input

Argument Name Description Required
domain_id The ID of the domain. To get the domain_id, use the !nsm-get-domains command. Required
device_id The ID of the device. To get the device ID, use the !nsm-list-domain-device command. Required
limit The maximum number of interfaces to return. Optional
all_results Return all interfaces related to the given device. Possible values are: yes, no. Optional

Context Output

Path Type Description
NSM.Interface.InterfaceId number The id of the interface.
NSM.Interface.InterfaceName Unknown The name of the interface.
NSM.Interface.InterfaceType string The type of the interface.

Command example

!nsm-list-device-interface device_id=1003 domain_id=0

Context Example

{
    "NSM": {
        "Interface": [
            {
                "InterfaceId": 102,
                "InterfaceName": "5-6",
                "InterfaceType": "Dedicated"
            },
            {
                "InterfaceId": 103,
                "InterfaceName": "3-4",
                "InterfaceType": "Dedicated"
            },
            {
                "InterfaceId": 104,
                "InterfaceName": "1-2",
                "InterfaceType": "Dedicated"
            }
        ]
    }
}

Human Readable Output

Device interfaces List

InterfaceId InterfaceName InterfaceType
102 5-6 Dedicated
103 3-4 Dedicated
104 1-2 Dedicated

nsm-list-device-policy


List all the policies assigned to a domain or a specific device.

Base Command

nsm-list-device-policy

Input

Argument Name Description Required
domain_id The ID of the domain. To get the domain_id, use the !nsm-get-domains command. Required
device_id The ID of the device. To get the device ID, use the !nsm-list-domain-device command. Optional
limit The maximum number of policies to return. Optional
all_results Return all policies assigned to a domain or a specific device. Possible values are: yes, no. Optional

Context Output

Path Type Description
NSM.DevicePolicy.DeviceName string The name of the device.
NSM.DevicePolicy.AtdUserForInboundATDAnalysis Unknown  
NSM.DevicePolicy.InterfaceName string The name of the interface.
NSM.DevicePolicy.FirewallPolicyLast Unknown  
NSM.DevicePolicy.ReconnaissancePolicy Unknown  
NSM.DevicePolicy.PolicyGroup Unknown  
NSM.DevicePolicy.AtdUserForOutboundATDAnalysis Unknown  
NSM.DevicePolicy.DeviceId number The id of the device.
NSM.DevicePolicy.AdvancedMalwareOutboundPolicy Unknown  
NSM.DevicePolicy.QosInboundPolicy Unknown  
NSM.DevicePolicy.ConnectionLimitingPolicy Unknown  
NSM.DevicePolicy.QosOutboundPolicy Unknown  
NSM.DevicePolicy.ProtectionOptionsPolicy Unknown  
NSM.DevicePolicy.AdvancedMalwareInboundPolicy Unknown  
NSM.DevicePolicy.QosOutboundRateLimitingProfile Unknown  
NSM.DevicePolicy.IpsPolicy Unknown  
NSM.DevicePolicy.QosInboundRateLimitingProfile Unknown  
NSM.DevicePolicy.FirewallPolicyFirst Unknown  

Command example

!nsm-list-device-policy domain_id=0

Context Example

{
    "NSM": {
        "DevicePolicy": [
            {
                "AdvancedMalwareInboundPolicy": null,
                "AdvancedMalwareOutboundPolicy": null,
                "AtdUserForInboundATDAnalysis": null,
                "AtdUserForOutboundATDAnalysis": null,
                "ConnectionLimitingPolicy": null,
                "DeviceId": 1003,
                "DeviceName": "Dummy Device Name",
                "FirewallPolicy": null,
                "FirewallPolicyFirst": "Test",
                "FirewallPolicyLast": null,
                "FirewallPortPolicy": null,
                "InterfaceId": 0,
                "InterfaceName": null,
                "IpsPolicy": null,
                "PolicyGroup": null,
                "ProtectionOptionsPolicy": null,
                "QosInboundPolicy": null,
                "QosInboundRateLimitingProfile": null,
                "QosOutboundPolicy": null,
                "QosOutboundRateLimitingProfile": null,
                "ReconnaissancePolicy": null
            }
        ]
    }
}

Human Readable Output

Device policy List

DeviceId DeviceName FirewallPolicyFirst InterfaceId
1003 Dummy Device Name Test 0

nsm-list-interface-policy


List all the policies assigned to all interfaces or a specific interface.

Base Command

nsm-list-interface-policy

Input

Argument Name Description Required
domain_id The ID of the domain. To get the domain_id, use the !nsm-get-domains command. Required
interface_id The ID of the interface. To get the interface ID, use the !nsm-list-device-interface command. Optional
limit The maximum number of policies to return. Optional
all_results Return all policies assigned to all interfaces or a specific interface. Possible values are: yes, no. Optional

Context Output

Path Type Description
NSM.InterfacePolicy.DeviceName string The name of the device.
NSM.InterfacePolicy.AtdUserForInboundATDAnalysis Unknown  
NSM.InterfacePolicy.InterfaceName string The name of the interface.
NSM.InterfacePolicy.FirewallPolicyLast Unknown  
NSM.InterfacePolicy.ReconnaissancePolicy Unknown  
NSM.InterfacePolicy.PolicyGroup Unknown  
NSM.InterfacePolicy.AtdUserForOutboundATDAnalysis Unknown  
NSM.InterfacePolicy.DeviceId number The id of the device.
NSM.InterfacePolicy.AdvancedMalwareOutboundPolicy Unknown  
NSM.InterfacePolicy.QosInboundPolicy Unknown  
NSM.InterfacePolicy.ConnectionLimitingPolicy Unknown  
NSM.InterfacePolicy.QosOutboundPolicy Unknown  
NSM.InterfacePolicy.ProtectionOptionsPolicy Unknown  
NSM.InterfacePolicy.AdvancedMalwareInboundPolicy Unknown  
NSM.InterfacePolicy.QosOutboundRateLimitingProfile Unknown  
NSM.InterfacePolicy.IpsPolicy Unknown  
NSM.InterfacePolicy.QosInboundRateLimitingProfile Unknown  
NSM.InterfacePolicy.FirewallPolicyFirst Unknown  

Command example

!nsm-list-interface-policy domain_id=0

Context Example

{
    "NSM": {
        "InterfacePolicy": [
            {
                "AdvancedMalwareInboundPolicy": null,
                "AdvancedMalwareOutboundPolicy": null,
                "AtdUserForInboundATDAnalysis": null,
                "AtdUserForOutboundATDAnalysis": null,
                "ConnectionLimitingPolicy": null,
                "DeviceId": 1003,
                "DeviceName": "Dummy Device Name",
                "FirewallPolicy": "a policy",
                "FirewallPolicyFirst": null,
                "FirewallPolicyLast": null,
                "FirewallPortPolicy": null,
                "InterfaceId": 104,
                "InterfaceName": "1-2",
                "IpsPolicy": "Default Prevention",
                "PolicyGroup": null,
                "ProtectionOptionsPolicy": null,
                "QosInboundPolicy": null,
                "QosInboundRateLimitingProfile": null,
                "QosOutboundPolicy": null,
                "QosOutboundRateLimitingProfile": null,
                "ReconnaissancePolicy": null
            },
            {
                "AdvancedMalwareInboundPolicy": null,
                "AdvancedMalwareOutboundPolicy": null,
                "AtdUserForInboundATDAnalysis": null,
                "AtdUserForOutboundATDAnalysis": null,
                "ConnectionLimitingPolicy": null,
                "DeviceId": 1003,
                "DeviceName": "Dummy Device Name",
                "FirewallPolicy": null,
                "FirewallPolicyFirst": null,
                "FirewallPolicyLast": null,
                "FirewallPortPolicy": null,
                "InterfaceId": 103,
                "InterfaceName": "3-4",
                "IpsPolicy": "testing",
                "PolicyGroup": null,
                "ProtectionOptionsPolicy": null,
                "QosInboundPolicy": null,
                "QosInboundRateLimitingProfile": null,
                "QosOutboundPolicy": null,
                "QosOutboundRateLimitingProfile": null,
                "ReconnaissancePolicy": null
            },
            {
                "AdvancedMalwareInboundPolicy": null,
                "AdvancedMalwareOutboundPolicy": null,
                "AtdUserForInboundATDAnalysis": null,
                "AtdUserForOutboundATDAnalysis": null,
                "ConnectionLimitingPolicy": null,
                "DeviceId": 1003,
                "DeviceName": "Dummy Device Name",
                "FirewallPolicy": null,
                "FirewallPolicyFirst": null,
                "FirewallPolicyLast": null,
                "FirewallPortPolicy": null,
                "InterfaceId": 102,
                "InterfaceName": "5-6",
                "IpsPolicy": "testing",
                "PolicyGroup": null,
                "ProtectionOptionsPolicy": null,
                "QosInboundPolicy": null,
                "QosInboundRateLimitingProfile": null,
                "QosOutboundPolicy": null,
                "QosOutboundRateLimitingProfile": null,
                "ReconnaissancePolicy": null
            }
        ]
    }
}

Human Readable Output

Interface policy List

DeviceId DeviceName FirewallPolicy InterfaceId InterfaceName IpsPolicy
1003 Dummy Device Name a policy 104 1-2 Default Prevention
1003 Dummy Device Name   103 3-4 testing
1003 Dummy Device Name   102 5-6 testing

nsm-assign-device-policy


Assign a policy to a specific device.

Base Command

nsm-assign-device-policy

Input

Argument Name Description Required
domain_id The ID of the domain. To get the domain_id, use the !nsm-get-domains command. Required
device_id The ID of the device. To get the device ID, use the !nsm-list-domain-device command. Required
pre_firewall_policy_name The name of the policy to add to the top of the rule order and evaluated first. To get the policies, use the !nsm-list-domain-firewall-policy command. Optional
post_firewall_policy_name The name of the policy to add to the end of the rule order and evaluated last. To get the policies, use the !nsm-list-domain-firewall-policy command. Optional

Context Output

There is no context output for this command.

Command example

!nsm-assign-device-policy device_id=1003 domain_id=0 pre_firewall_policy_name=Test

Human Readable Output

Policy assigned successfully.

nsm-assign-interface-policy


Assign a policy to a specific interface.

Base Command

nsm-assign-interface-policy

Input

Argument Name Description Required
domain_id The ID of the domain. To get the domain_id, use the !nsm-get-domains command. Required
interface_id The ID of the interface. To get the interface ID, use the !nsm-list-device-interface command. Required
firewall_policy_name The name of the firewall policy that will be connected to the interface. To get the policy name, use the !nsm-list-domain-firewall-policy command. Optional
firewall_port_policy_name The name of the firewall policy that will be connected to the interface/port. To get the policy name, use the !nsm-list-domain-firewall-policy command. Optional
ips_policy_name The name of the IPS policy that will be connected to the interface. To get the policy name, use the !nsm-get-ips-policies command. Optional
custom_policy_json A Json with firewall policy types as keys and firewall policy names as values. (e.g {"advancedMalwareInboundPolicy":"test"}). To see all the firewall policy options visit this page https://docs.trellix.com/bundle/network-security-platform-9.1.x-manager-api-reference-guide/page/GUID-5E5F9514-935F-4F16-B2F0-C48E465A4E7C.html. Optional

Context Output

There is no context output for this command.

Command example

!nsm-assign-interface-policy domain_id=0 interface_id=102 ips_policy_name=testing

Human Readable Output

Policy assigned successfully.

nsm-get-device-configuration


Provides configuration information of a given device.

Base Command

nsm-get-device-configuration

Input

Argument Name Description Required
device_id The ID of the device. To get the device ID, use the !nsm-get-sensors command. Required

Context Output

Path Type Description
NSM.DeviceConfiguration.IsSSLConfigurationChanged boolean Was the ssl configuration changed.
NSM.DeviceConfiguration.DeviceName string The name of the device.
NSM.DeviceConfiguration.IsConfigurationChanged boolean Was the configuration changed.
NSM.DeviceConfiguration.IsMalwareConfigurationChanged boolean  
NSM.DeviceConfiguration.LastUpdateTime Unknown  
NSM.DeviceConfiguration.IsGAMUpdateRequired boolean  
NSM.DeviceConfiguration.IsSignatureSetConfigurationChanged Unknown  
NSM.DeviceConfiguration.IsSigsetConfigPushRequired boolean  
NSM.DeviceConfiguration.IsBotnetPushRequired boolean  
NSM.DeviceConfiguration.IsPolicyConfigurationChanged boolean  
NSM.DeviceConfiguration.IsSSLPushRequired boolean  
NSM.DeviceConfiguration.IsGloablPolicyConfigurationChanged boolean  
NSM.DeviceConfiguration.IsBotnetConfigurationChanged boolean  

Command example

!nsm-get-device-configuration device_id=1003

Context Example

{
    "NSM": {
        "DeviceConfiguration": {
            "DeviceName": "Dummy Device Name",
            "IsBotnetConfigurationChanged": false,
            "IsBotnetPushRequired": false,
            "IsConfigurationChanged": true,
            "IsGAMUpdateRequired": false,
            "IsGloablPolicyConfigurationChanged": false,
            "IsMalwareConfigurationChanged": false,
            "IsPolicyConfigurationChanged": false,
            "IsSSLConfigurationChanged": false,
            "IsSSLPushRequired": false,
            "IsSignatureSetConfigurationChanged": false,
            "IsSigsetConfigPushRequired": true,
            "LastUpdateTime": "2023-03-25 20:52:59.600 UTC"
        }
    }
}

Human Readable Output

Device Configuration

DeviceName IsBotnetConfigurationChanged IsBotnetPushRequired IsConfigurationChanged IsGAMUpdateRequired IsGloablPolicyConfigurationChanged IsMalwareConfigurationChanged IsPolicyConfigurationChanged IsSSLConfigurationChanged IsSSLPushRequired IsSignatureSetConfigurationChanged IsSigsetConfigPushRequired LastUpdateTime
Dummy Device Name false false true false false false false false false false true 2023-03-25 20:52:59.600 UTC

nsm-deploy-device-configuration


Deploy the pending changes.
Note: In order to avoid extra run time, it is recommended to deploy only the changes that are pending.
To get the pending changes, use the !nsm-get-device-configuration command.

Base Command

nsm-deploy-device-configuration

Input

Argument Name Description Required
request_id This is for the polling to work. not for the user. Optional
device_id The ID of the device. To get the device ID, use the !nsm-get-sensors command. Required
push_ssl_key Deploy the SSL configuration pending changes. Possible values are: true, false. Optional
push_gam_updates Deploy the Gateway Anti-Malware configuration pending changes. Possible values are: true, false. Optional
push_configuration_signature_set Deploy the Signature set configuration pending changes. Possible values are: true, false. Optional
push_botnet Deploy the Firewall policy description pending changes. Possible values are: true, false. Optional
interval_in_seconds The interval between status checks. Optional

Context Output

There is no context output for this command.

Command example

!nsm-deploy-device-configuration device_id=1003 push_configuration_signature_set="true" interval_in_seconds=10

Human Readable Output

The current percentage of deployment for ‘push_configuration_signature_set’ is: 0%

And the current message is: NA

Checking again in 10 seconds…

Configuration parameters

  • url — URL (for example: https://192.168.0.1:5000) (required)
  • credentials — User Name (required)
  • version — Product Version
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (28)

  • nsm-assign-device-policy

    Assign a policy to a specific device.

  • nsm-assign-interface-policy

    Assign a policy to a specific interface.

  • nsm-create-firewall-policy

    Adds a new firewall policy and access rules. You have to provide at lease one of the source/destination rule objects. If you provide the id or type of the source/destination rule object, you must provide the matching type or id the source/destination rule object as well.

  • nsm-create-rule-object

    Adds a new rule object. If the type is “Endpoint IP V.X” or “Network IP V.X”, only the argument “address_ip_v.X” must contain a value. If the type is “Range IP V.X”, only the arguments “from_address_ip_v.X”, “to_address_ip_v.X” must contain a value. Where X is 4 or 6 respectively.

  • nsm-delete-firewall-policy

    Deletes the specified firewall policy.

  • nsm-delete-rule-object

    Deletes a rule object.

  • nsm-deploy-device-configuration

    Deploy the pending changes. Note: In order to avoid extra run time, it is recommended to deploy only the changes that are pending. To get the pending changes, use the !nsm-get-device-configuration command.

  • nsm-export-pcap-file

    Exports the captured PCAP file.

  • nsm-get-alert-details

    Retrieves the relevant alert details.

  • nsm-get-alerts

    Retrieves the alerts.

  • nsm-get-attacks

    If an attack is given, the command returns the details for the specific attack. Otherwise, gets all available attack definitions in the Manager UI. This command can take a few minutes. If you get a timeout error, increase the timeout by using the parameter "execution-timeout".

  • nsm-get-device-configuration

    Provides configuration information of a given device.

  • nsm-get-domains

    If a domain ID is given, the command returns the details of the specific domain. Otherwise, gets all available domains.

  • nsm-get-firewall-policy

    Gets the firewall policy details.

  • nsm-get-ips-policies

    Gets all the IPS policies defined in the specific domain.

  • nsm-get-ips-policy-details

    Gets all the IPS policies defined in the specific domain.

  • nsm-get-rule-object

    Gets the details of a rule object.

  • nsm-get-sensors

    Gets the list of sensors available in the specified domain. If the domain is not specified, details of all the sensors in all ADs will be provided.

  • nsm-list-device-interface

    List the interfaces related to a given device.

  • nsm-list-device-policy

    List all the policies assigned to a domain or a specific device.

  • nsm-list-domain-device

    List the devices related to a given domain.

  • nsm-list-domain-firewall-policy

    Gets the list of firewall policies defined in a particular domain.

  • nsm-list-domain-rule-object

    Gets the list of rule objects defined in a particular domain.

  • nsm-list-interface-policy

    List all the policies assigned to all interfaces or a specific interface.

  • nsm-list-pcap-file

    Retrieves the list of captured PCAP files.

  • nsm-update-alerts

    Update state or assignee of alerts. It is required to provide at least one of them. If none of the alerts match the time_period they won't be updated.

  • nsm-update-firewall-policy

    Updates the firewall policy details. If the argument is_overwrite=true, the new values of the provided addresses will replace the existing values, otherwise the addresses will be added to them. If you want to delete a rule, enter is_overwrite=true and the relevant rule_object_id=-1. If is_overwrite=false and there is no value in one of the rules (source or destination), their value will be as before. If is_overwrite=true, at least one of the rules (source or destination) must be provided. If you provide the id or type of the source/destination rule object, you must provide the matching type or id the source/destination rule object as well.

  • nsm-update-rule-object

    Updates a Rule object. In case of address rule update, if the rule type is “Endpoint IP V.X” or “Network IP V.X”, only the argument “address_ip_v.X” should contain a value. If the type is “Range IP V.X”, only the arguments “from_address_ip_v.X”, “to_address_ip_v.X” should contain a value, where X is 4 or 6 respectively.

import base64
import re
from typing import Any

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

from CommonServerUserPython import *  # noqa

# Disable insecure warnings
urllib3.disable_warnings()

V10 = "V10x"
V9 = "V9x"
VERSION = demisto.params().get("version", V9)
DEFAULT_LIMIT = 50
HOST = "HOST"
ADDRESS_RANGE = "ADDRESS_RANGE"
STATE_TO_NUMBER = {"Disabled": 0, "Enabled": 1}
DEPLOY_ARGUMENT_MAPPER = {
    "push_ssl_key": "SSLPercentageComplete",
    "push_gam_updates": "GamUpdatePercentageComplete",
    "push_configuration_signature_set": "sigsetConfigPercentageComplete",
    "push_botnet": "botnetPercentageComplete",
}

MESSAGE_MAP = {
    "push_ssl_key": "SSLStatusMessage",
    "push_gam_updates": "GamUpdateStatusMessage",
    "push_configuration_signature_set": "sigsetConfigStatusMessage",
    "push_botnet": "botnetStatusMessage",
}

ADDRESS_LIST_MAP = {
    "IPv6AddressRange": "IPV6RangeList",
    "IPv4AddressRange": "IPV4RangeList",
    "HostIPv4": "hostIPv4AddressList",
    "HostIPv6": "hostIPv6AddressList",
    "Network_IPV_6": "networkIPV6List",
    "Network_IPV_4": "networkIPV4List",
}
INTERVAL = arg_to_number(demisto.args().get("interval_in_seconds", 30))

""" CLIENT CLASS """


class Client(BaseClient):
    def __init__(self, url: str, auth: tuple, headers: dict, proxy: bool = False, verify: bool = False):
        self.url = url
        self.headers = headers
        super().__init__(base_url=url, verify=verify, proxy=proxy, auth=auth, headers=headers)

    def get_session_request(self, encoded_str: str) -> dict:
        """Gets a session from the API.
        Args:
            encoded_str: str - The string that contains username:password in base64.
        Returns:
            A dictionary with the session details.
        """
        url_suffix = "/session"
        self.headers["NSM-SDK-API"] = encoded_str
        return self._http_request(method="GET", url_suffix=url_suffix)

    def list_domain_firewall_policy_request(self, domain_id: int) -> dict:
        """Gets the list of Firewall Policies defined in a particular domain.
        Args:
            domain_id: int - The id of the domain.
        Returns:
            A dictionary with the firewall policy list.
        """
        url_suffix = f"/domain/{domain_id}/firewallpolicy"
        return self._http_request(method="GET", url_suffix=url_suffix)

    def get_firewall_policy_request(self, policy_id: int) -> dict:
        """Gets the Firewall Policy details.
        Args:
            policy_id: int - The id of the policy.
        Returns:
            A dictionary with the policy details.
        """
        url_suffix = f"/firewallpolicy/{policy_id}"
        return self._http_request(method="GET", url_suffix=url_suffix)

    def create_firewall_policy_request(self, body: dict) -> dict:
        """Adds a new Firewall Policy and Access Rules.
        Args:
            body: Dict - The params to the API call.
        Returns:
            A dictionary with the id of the newly created policy.
        """
        url_suffix = "/firewallpolicy"
        return self._http_request(method="POST", url_suffix=url_suffix, json_data=body)

    def update_firewall_policy_request(self, body: dict, policy_id: int) -> dict:
        """Updates an existing Firewall Policy and Access Rules.
        Args:
            body: Dict - The params to the API call.
            policy_id: int - The id of the updated policy.
        Returns:
            A dictionary with the request status, if it succeeded or not.
        """
        url_suffix = f"/firewallpolicy/{policy_id}"
        return self._http_request(method="PUT", url_suffix=url_suffix, json_data=body)

    def delete_firewall_policy_request(self, policy_id: int) -> dict:
        """Updates an existing Firewall Policy and Access Rules.
        Args:
            policy_id: int - The id of the updated policy.
        Returns:
            A dictionary with the request status, if it succeeded or not.
        """
        url_suffix = f"/firewallpolicy/{policy_id}"
        return self._http_request(method="DELETE", url_suffix=url_suffix)

    def list_domain_rule_objects_request(self, domain_id: int, rule_type: str) -> dict:
        """Gets the list of rule objects defined in a particular domain.
        Args:
            domain_id: int - The id of the domain.
            rule_type: str - The type of the rules to be returned.
        Returns:
            A dictionary with the rule objects list.
        """
        url_suffix = f"/domain/{domain_id}/ruleobject?type={rule_type}"
        return self._http_request(method="GET", url_suffix=url_suffix)

    def get_rule_object_request(self, rule_id: int) -> dict:
        """Gets the list of rule objects defined in a particular domain.
        Args:
            rule_id: int - The id of the rule.
        Returns:
            A dictionary with the rule object information.
        """
        url_suffix = f"/ruleobject/{rule_id}"
        return self._http_request(method="GET", url_suffix=url_suffix)

    def create_rule_object_request(self, body: dict) -> dict:
        """Gets the list of rule objects defined in a particular domain.
        Args:
            body: Dict - The params to the API call.
        Returns:
            A dictionary with the id of the new rule object.
        """
        url_suffix = "/ruleobject"
        return self._http_request(method="POST", url_suffix=url_suffix, json_data=body)

    def update_rule_object_request(self, body: dict, rule_id: int) -> dict:
        """Updates a Rule Object.
        Args:
            body: Dict - The params to the API call.
            rule_id: int - The rule id.
        Returns:
            A dictionary with the status of the request.
        """
        url_suffix = f"/ruleobject/{rule_id}"
        return self._http_request(method="PUT", url_suffix=url_suffix, json_data=body, resp_type="response")

    def delete_rule_object_request(self, rule_id: int) -> dict:
        """Updates a Rule Object.
        Args:
            rule_id: int - The rule id.
        Returns:
            A dictionary with the status of the request.
        """
        url_suffix = f"/ruleobject/{rule_id}"
        return self._http_request(method="DELETE", url_suffix=url_suffix)

    def get_alerts_request(
        self,
        time_period: str,
        start_time: str,
        end_time: str,
        state: str,
        search: str,
        filter_arg: str,
        domain_id: int,
        page: str = None,
    ) -> dict:
        """Retrieves All Alerts.
        Args:
            time_period: str - The time period of the alert.
            start_time: str - The start time of the alert.
            end_time: str - The end time of the alert.
            state: str - The state of the alert.
            search: str - Search string in alert details.
            filter_arg: str - Filter alert by fields.
            page: str - Next/Previous page.
            domain_id: int - The id of the domain
        Returns:
            A dictionary with the list of alerts and info about the list.
        """
        params = {}
        if time_period:
            params["timeperiod"] = time_period
            if time_period == "CUSTOM":
                params["starttime"] = start_time
                params["endtime"] = end_time
        if state:
            params["alertstate"] = state
        if search:
            params["search"] = search
        if filter_arg:
            params["filter"] = filter_arg
        if page:
            params["page"] = page
        if domain_id:
            params["domainId"] = f"{domain_id}"
        url_suffix = "/alerts"
        return self._http_request(method="GET", url_suffix=url_suffix, params=params)

    def get_alert_details_request(self, alert_id: int, sensor_id: int) -> dict:
        """Retrieves the alert details.
        Args:
            alert_id: int - The id of the relevant alert.
            sensor_id: int - The id of the relevant sensor.
        Returns:
            A dictionary with the alert details.
        """
        url_suffix = f"/alerts/{alert_id}"
        params = {"sensorId": sensor_id}
        return self._http_request(method="GET", url_suffix=url_suffix, params=params)

    def get_attacks_request(self, attack_id: Optional[str]) -> dict:
        """If an attack id is given The command returns the details of the specific attack. Else, gets all available
        attack definitions in the Manager UI.
            Args:
                attack_id: str - The id of the relevant attack.
            Returns:
                A dictionary with the attack list of the specific attack details.
        """
        if attack_id:
            url_suffix = f"/attack/{attack_id}"
        else:
            url_suffix = "/attacks"
        response = self._http_request(method="GET", timeout=5000, url_suffix=url_suffix)
        return response

    def get_domains_request(self, domain_id: Optional[int]) -> dict:
        """If a domain id is given The command returns the details of the specific domain.
        Else, gets all available domains.
        Args:
            domain_id: Optional[int] - The id of the relevant attack.
        Returns:
            A dictionary with the attack list of the specific attack details.
        """
        url_suffix = "/domain"
        if domain_id:
            url_suffix = f"{url_suffix}/{domain_id}"
        return self._http_request(method="GET", url_suffix=url_suffix)

    def get_sensors_request(self, domain_id: Optional[int]) -> dict:
        """If a domain id is given The command returns the details of the sensors in the specific domain.
        Else, gets all available sensors.
        Args:
            domain_id: Optional[int] - The id of the relevant domain.
        Returns:
            A dictionary with the domains list of the specific domain details.
        """
        url_suffix = "/sensors"
        params = {}
        if domain_id:
            params["domain"] = domain_id
        return self._http_request(method="GET", url_suffix=url_suffix, params=params)

    def get_ips_policies_request(self, domain_id: int) -> dict:
        """Gets all the IPS Policies defined in the specific domain.
        Args:
            domain_id: int - The id of the relevant domain.
        Returns:
            A dictionary with ips policies list of the specific domain details.
        """
        url_suffix = f"/domain/{domain_id}/ipspolicies"
        return self._http_request(method="GET", url_suffix=url_suffix)

    def get_ips_policy_details_request(self, policy_id: int) -> dict:
        """Gets the policy details for the specific IPS policy.
        Args:
            policy_id: int - The id of the relevant ips policy.
        Returns:
            A dictionary with the ips policy details.
        """
        url_suffix = f"/ipspolicy/{policy_id}"
        return self._http_request(method="GET", url_suffix=url_suffix)

    def update_alerts_request(
        self, time_period: str, start_time: str, end_time: str, state: str, search: str, filter_arg: str, body: dict
    ) -> dict:
        """Updates all relevant alerts.
        Args:
            time_period: str - The time period of the alert.
            start_time: str - The start time of the alert.
            end_time: str - The end time of the alert.
            state: str - The state of the alert.
            search: str - Search string in alert details.
            filter_arg: str - Filter alert by fields.
            body: Dict - The body of the request.
        Returns:
            A dictionary with the request status.
        """
        params = {}
        if time_period:
            params["timeperiod"] = time_period
            if time_period == "CUSTOM":
                params["starttime"] = start_time
                params["endtime"] = end_time
        if state:
            params["alertstate"] = state
        if search:
            params["search"] = search
        if filter_arg:
            params["filter"] = filter_arg
        url_suffix = "/alerts"
        return self._http_request(method="PUT", url_suffix=url_suffix, params=params, json_data=body)

    def list_pcap_file_request(self, sensor_id: int) -> dict:
        """Retrieves the list of captured PCAP files.
        Args:
            sensor_id: int - the relevant sensor id.
        Returns:
            A dictionary with a list of PCAP file names.
        """
        url_suffix = f"/sensor/{sensor_id}/packetcapturepcapfiles"
        return self._http_request(method="GET", url_suffix=url_suffix)

    def export_pcap_file_request(self, sensor_id: int, body: dict) -> Response:
        """Retrieves the list of captured PCAP files.
        Args:
            sensor_id: int - The relevant sensor id.
            body: Dict - The parameter for the http request (file name).
        Returns:
            A dictionary with a list of PCAP file names.
        """
        url_suffix = f"/sensor/{sensor_id}/packetcapturepcapfile/export"
        self.headers["Accept"] = "application/octet-stream"
        return self._http_request(method="PUT", url_suffix=url_suffix, json_data=body, resp_type="response")

    def list_domain_device_request(self, domain_id: int) -> dict:
        """Retrieves the list of devices in a domain.
        Args:
            domain_id: int - The relevant domain id.
        Returns:
            A dictionary with a list of devices.
        """
        url_suffix = f"/domain/{domain_id}/device"
        return self._http_request(method="GET", url_suffix=url_suffix)

    def list_device_interface_request(self, domain_id: int, device_id: int) -> dict[str, List]:
        """Retrieves the list of interfaces related to a device.
        Args:
            device_id: int - The relevant device id.
            domain_id: int - The relevant domain id.
        Returns:
            A dictionary with a list of interfaces.
        """
        url_suffix = f"/domain/{domain_id}/sensor/{device_id}/allocatedinterfaces"
        return self._http_request(method="GET", url_suffix=url_suffix)

    def assign_device_policy_request(
        self, domain_id: int, device_id: int, pre_firewall_policy: Optional[str], post_firewall_policy: Optional[str]
    ) -> dict:
        """Assigns a policy to a device.
        Args:
            device_id: int - The relevant device id.
            domain_id: int - The relevant domain id.
            pre_firewall_policy: Optional[str] - The pre firewall policy.
            post_firewall_policy: Optional[str] - The post firewall policy.
        Returns:
            A success or failure code.
        """
        url_suffix = f"/domain/{domain_id}/policyassignments/device/{device_id}"
        json_data = {"firewallPolicyLast": post_firewall_policy, "firewallPolicyFirst": pre_firewall_policy}
        return self._http_request(method="PUT", url_suffix=url_suffix, json_data=json_data)

    def list_device_policy_request(self, domain_id: int, device_id: Optional[int]) -> dict:
        """Retrieves the list of policies assigned to a device.
        Args:
            device_id: int - The relevant device id.
            domain_id: int - The relevant domain id.
        Returns:
            A dictionary with a list of policies.
        """
        if device_id:
            url_suffix = f"/domain/{domain_id}/policyassignments/device/{device_id}"
        else:
            url_suffix = f"/domain/{domain_id}/policyassignments/device"
        return self._http_request(method="GET", url_suffix=url_suffix)

    def assign_interface_policy_request(
        self,
        domain_id: int,
        interface_id: int,
        firewall_policy: Optional[str],
        firewall_port_policy: Optional[str],
        ips_policy: Optional[str],
        custom_policy_json: Optional[dict],
    ) -> dict:
        """Assigns a policy to an interface.
        Args:
            domain_id: int - The relevant domain id.
            interface_id: int - The relevant interface id.
            firewall_policy: str - The firewall policy.
            firewall_port_policy: str - The firewall port policy.
            ips_policy: str - The IPS policy.
            custom_policy_json: Dict - A dict of custom policies.
        Returns:
            A success or failure code.

        """
        url_suffix = f"/domain/{domain_id}/policyassignments/interface/{interface_id}"
        json_data = {"firewallPolicy": firewall_policy, "firewallPortPolicy": firewall_port_policy, "ipsPolicy": ips_policy}
        if custom_policy_json:
            json_data |= custom_policy_json

        return self._http_request(method="PUT", url_suffix=url_suffix, json_data=json_data)

    def list_interface_policy_request(self, domain_id: int, interface_id: Optional[int]) -> dict:
        """Retrieves the list of policies assigned to an interface.
        Args:
            domain_id: int - The relevant domain id.
            interface_id: int - The relevant interface id.
        Returns:
            A dictionary with a list of policies.
        """
        if interface_id:
            url_suffix = f"/domain/{domain_id}/policyassignments/interface/{interface_id}"
        else:
            url_suffix = f"/domain/{domain_id}/policyassignments/interface"
        return self._http_request(method="GET", url_suffix=url_suffix)

    def get_device_configuration_request(self, device_id: int) -> dict:
        """Retrieves the configuration of a device.
        Args:
            device_id: int - The relevant device id.
        Returns:
            A dictionary with the device configuration.
        """
        url_suffix = f"/sensor/{device_id}/action/update_sensor_config"
        return self._http_request(method="GET", url_suffix=url_suffix)

    def deploy_device_configuration_request(
        self,
        device_id: int,
        is_SSL_Push_Required: bool = False,
        is_GAM_Update_Required: bool = False,
        is_Sigset_Config_Push_Required: bool = False,
        is_Botnet_Push_Required: bool = False,
    ) -> dict:
        """Deploy a device configuration.
        Args:
            device_id: int - The relevant device id.
            is_SSL_Push_Required: bool - Is SSL push required.
            is_GAM_Update_Required: bool - Is GAM update required.
            is_Sigset_Config_Push_Required: bool - Is signature set configuration push required.
            is_Botnet_Push_Required: bool - Is botnet push required.

        Returns:
            A success or failure code.
        """
        json_data = {
            "isSSLPushRequired": is_SSL_Push_Required,
            "isGAMUpdateRequired": is_GAM_Update_Required,
            "isSigsetConfigPushRequired": is_Sigset_Config_Push_Required,
            "isBotnetPushRequired": is_Botnet_Push_Required,
        }

        url_suffix = f"/sensor/{device_id}/action/update_sensor_config"
        return self._http_request(method="PUT", url_suffix=url_suffix, json_data=json_data)

    def check_deploy_device_configuration_request_status(self, device_id, request_id):
        """
        Checks the status of a device configuration deployment.
        Args:
            device_id (int): The relevant device id.
            request_id (int): The relevant request id.

        Returns: A dictionary with the status of deployment for all optional deployment categories.
        """
        url_suffix = f"/sensor/{device_id}/action/update_sensor_config/{request_id}"
        return self._http_request(method="GET", url_suffix=url_suffix)


""" HELPER FUNCTIONS """


def encode_to_base64(str_to_convert: str) -> str:
    """Converts a string to base64 string.
    Args:
        str_to_convert: str - The string that needs to be converted to base64.
    Returns:
        The converted string.
    """
    b = base64.b64encode(bytes(str_to_convert, "utf-8"))  # bytes
    base64_str = b.decode("utf-8")  # convert bytes to string
    return base64_str


def get_session(client: Client, user_name_n_password: str) -> str:
    """Gets the session string.
    Args:
        client: Client - A McAfeeNSM client.
        user_name_n_password: str - The username and password that needs to be encoded to base64
            in order to get the session information.
    Returns:
        The converted string.
    """
    user_name_n_password_encoded = encode_to_base64(user_name_n_password)
    session = client.get_session_request(user_name_n_password_encoded)
    return encode_to_base64(f'{session.get("session")}:{session.get("userId")}')


def pagination(records_list: List, limit: int, page: Optional[int], page_size: Optional[int]) -> List[dict]:
    """Returns the wanted records.
    Args:
        records_list: List - The original list of objects.
        limit: str - The amount of records to be returned
        page: Optional[int] - The page of the results (The results in page 1, 2 ...)
        page_size: Optional[int] - the number of records that will be in the page.
    Returns:
        The wanted records.
    """
    if page and page_size:
        num_rec_2_remove = page_size * (page - 1)
        results_list = records_list[num_rec_2_remove:]
        return results_list[:page_size]
    else:
        return records_list[:limit]


def alerts_list_pagination(
    records_list: List,
    limit: int,
    page: Optional[int],
    page_size: Optional[int],
    time_period: str,
    start_time: str,
    end_time: str,
    state: str,
    search: str,
    filter_arg: str,
    client: Client,
    domain_id: int,
) -> List:
    """Returns the wanted records.
    Args:
        records_list: List - The original list of objects.
        limit: int - The amount of records to be returned
        page: Optional[int] - The page of the results (The results in page 1, 2 ...)
        page_size: Optional[int] - The number of records in a page.
        time_period: str - The time period of the alert.
        start_time: str - The start time of the alert.
        end_time: str - The end time of the alert.
        state: str - The state of the alert.
        search: str - Search string in alert details.
        filter_arg: str - Filter alert by fields.
        client: Client - McAfeeNSMv2 client
        domain_id: str - The id of the domain.
    Returns:
        The wanted records.
    """
    if page and page_size:
        offset = page_size * (page - 1)
        results_list = []
        while (offset + page_size > 1000) and (len(records_list) == 1000):
            records_list = records_list[offset:]
            results_list.extend(records_list)
            page_size = page_size - len(records_list)
            offset = 0 if offset <= 1000 else offset - 1000
            response = client.get_alerts_request(time_period, start_time, end_time, state, search, filter_arg, domain_id, "next")
            records_list = response.get("alertsList", [])

        records_list = records_list[offset:]
        results_list.extend(records_list[:page_size])
        return results_list
    else:
        results_list = []
        while limit > 1000 and (len(records_list) == 1000):
            results_list.extend(records_list)
            limit = limit - len(records_list)
            response = client.get_alerts_request(time_period, start_time, end_time, state, search, filter_arg, domain_id, "next")
            records_list = response.get("alertsList", [])
        results_list.extend(records_list[:limit])
        return results_list


def response_cases(response_str: str) -> str:
    """Checks the response param and returns the correct response string.
    Args:
        response_str: str - The response string.
    Returns:
        The correct response string.
    Example:
        Scan -> SCAN
        Drop -> DROP
        Deny -> DENY
        Ignore -> IGNORE
        Stateless Ignore -> STATELESS_IGNORE
        Stateless Drop -> STATELESS_DROP
        Require Authentication-> REQUIRE_AUTHENTICATION
    """
    split_str = response_str.upper().split()
    if len(split_str) == 1:
        return split_str[0]
    else:
        return "_".join(split_str)


def rule_object_type_cases(str_type: str, case: str) -> str:
    """Checks the rule_object_type params and returns the correct format of them.
    Args:
        str_type: str - The type string.
        case: str - In what case should the letters be, upper or lower case.
    Returns:
        The correct rule_object_type string.
    Examples:
        - In list_domain_rule_objects_command the arguments should be in lower case and in this form:
            Endpoint IP V.4 -> hostipv4
            Range IP V.4 -> ipv4addressrange
            Network IP V.4 -> networkipv4
            Endpoint IP V.6 -> hostipv6
            Range IP V.6 -> ipv6addressrange
            Network IP V.6 -> networkipv6
        - In all the other commands that use this function, the arguments should be in upper case and in this form:
            Endpoint IP V.4 -> HOST_IPV_4
            Range IP V.4 -> IPV_4_ADDRESS_RANGE
            Network IP V.4 -> NETWORK_IPV_4
            Endpoint IP V.6 -> HOST_IPV_6
            Range IP V.6 -> IPV_6_ADDRESS_RANGE
            Network IP V.6 -> NETWORK_IPV_6
    """
    type_split = str_type.upper().replace(".", " ").split()
    if "ENDPOINT" in type_split[0]:
        r_type = f"HOST_IPV_{type_split[-1]}"
    elif "RANGE" in type_split[0]:
        r_type = f"IPV_{type_split[-1]}_ADDRESS_RANGE"
    else:
        r_type = f"NETWORK_IPV_{type_split[-1]}"
    if case == "low":
        return r_type.lower().replace("_", "")
    return r_type


def reverse_rule_object_type_cases(rule_type: str) -> str:
    """Checks the rule_object_type params that return from the API call and returns the matching string in the UI.
    Args:
        rule_type: str - The type string.
    Returns:
        The matching string.
    Example:
        HOST_IPV_4 -> Endpoint IP V.4
        IPV_4_ADDRESS_RANGE -> Range IP V.4
        NETWORK_IPV_4 -> Network IP V.4
        HOST_IPV_6 -> Endpoint IP V.6
        IPV_6_ADDRESS_RANGE -> Range IP V.6
        NETWORK_IPV_6 -> Network IP V.6
    """
    number = "4" if ("4" in rule_type) else "6"
    if HOST in rule_type:
        return f"Endpoint IP V.{number}"
    elif ADDRESS_RANGE in rule_type:
        return f"Range IP V.{number}"
    else:
        return f"Network IP V.{number}"


def check_source_and_destination(
    source_rule_object_id: Optional[int],
    source_rule_object_type: Optional[str],
    destination_rule_object_id: Optional[int],
    destination_rule_object_type: Optional[str],
    create_or_update: str,
):
    """Checks the source and destination objects.
    Args:
        source_rule_object_id: Optional[int] - Unique Rule Object ID.
        source_rule_object_type: Optional[str] - Source / Destination Mode.
        destination_rule_object_id: Optional[int] - Unique Rule Object ID.
        destination_rule_object_type: Optional[str] - Source / Destination Mode.
        create_or_update: str - From what function it was called.
    Returns:
        Throws exception .
    """
    if (source_rule_object_id and not source_rule_object_type and source_rule_object_id != -1) or (
        not source_rule_object_id and source_rule_object_type
    ):
        # If the user provides source_rule_object_id he must provide source_rule_object_type and vice versa
        raise Exception("Please provide both source_rule_object_id and source_rule_object_type.")
    if (destination_rule_object_id and not destination_rule_object_type and destination_rule_object_id != -1) or (
        not destination_rule_object_id and destination_rule_object_type
    ):
        # If the user provides destination_rule_object_id he must provide destination_rule_object_type and vice versa
        raise Exception("Please provide both destination_rule_object_id and destination_rule_object_type.")
    if create_or_update == "create":  # noqa: SIM102
        # if the user wants to create a new firewall policy, he must provide a source rule or destination rule or both.
        if source_rule_object_id == -1 and destination_rule_object_id == -1:
            raise Exception("You must provide the source fields or destination fields or both.")


def create_body_firewall_policy(
    domain: int,
    name: str,
    visible_to_child: bool,
    description: str,
    is_editable: bool,
    policy_type: str,
    rule_description: str,
    response_param: str,
    rule_enabled: bool,
    direction: str,
    source_object: List,
    destination_object: List,
) -> dict:
    """
    Args:
        domain: int - The id of the domain.
        name: str - The name of the policy.
        visible_to_child: bool - Will the policy be visible to the child domain.
        description: str - the policy description.
        is_editable: bool - Is the policy editable.
        policy_type: str - The type of the policy.
        rule_description: str - The description of the rule.
        response_param: str - Action to be performed if the traffic matches this rule.
        rule_enabled: bool - Is Rule Enabled or not.
        direction: str - The rule direction.
        source_object: List - Information about the source addresses.
        destination_object: List - Information about the destination addresses.
    Returns:
        Returns the body for the request.
    """
    return {
        "Name": name,
        "DomainId": domain,
        "VisibleToChild": visible_to_child,
        "Description": description,
        "IsEditable": is_editable,
        "PolicyType": policy_type,
        "MemberDetails": {
            "MemberRuleList": [
                {
                    "Description": rule_description,
                    "Enabled": rule_enabled,
                    "Response": response_param,
                    "Direction": direction,
                    "SourceAddressObjectList": source_object,
                    "DestinationAddressObjectList": destination_object,
                    "SourceUserObjectList": [{"RuleObjectId": "-1", "Name": "Any", "RuleObjectType": "USER"}],
                    "ServiceObjectList": [{"RuleObjectId": "-1", "Name": "Any", "RuleObjectType": None, "ApplicationType": None}],
                    "ApplicationObjectList": [],
                    "TimeObjectList": [{"RuleObjectId": "-1", "Name": "Always", "RuleObjectType": None}],
                }
            ]
        },
    }


def create_body_create_rule(rule_type: str, address: List, number: int, from_to_list: list[dict[str, Optional[Any]]]) -> tuple:
    """create part of the body for the command create_rule_object
    Args:
        rule_type: str - The type of the rule.
        address: List - A list of addresses, if relevant.
        number: int - The number of the IPV.
        from_to_list: List - A list that contains dictionaries with from and to addresses.
    Returns:
        Returns the body for the request.
    """
    if HOST in rule_type:
        return f"HostIPv{number}", {f"hostIPv{number}AddressList": address}
    elif ADDRESS_RANGE in rule_type:
        return f"IPv{number}AddressRange", {f"IPV{number}RangeList": from_to_list}
    else:
        return f"Network_IPV_{number}", {f"networkIPV{number}List": address}


def create_body_create_rule_for_v10(
    rule_type: str, address: List, number: int, from_to_list: List[dict[str, Optional[Any]]], state: str = "Enabled"
) -> tuple:
    """create part of the body for the command create_rule_object for v10
    Args:
        rule_type: str - The type of the rule.
        address: List - A list of addresses, if relevant.
        number: int - The number of the IPV.
        from_to_list: List - A list that contains dictionaries with from and to addresses.
        state: str - An Enabled or Disabled state.
    Returns:
        Returns the body for the request.
    """
    # build a list of dictionaries with the state and the address
    list_to_send: list[dict] = [{"value": single_address, "state": STATE_TO_NUMBER.get(state)} for single_address in address]
    # for parameters with a range, we need to add the state to the dictionary
    if from_to_list:
        from_to_list[0].update({"state": STATE_TO_NUMBER.get(state)})

    if HOST in rule_type:
        return f"HostIPv{number}", {f"hostIPv{number}AddressList": list_to_send}
    elif ADDRESS_RANGE in rule_type:
        return f"IPv{number}AddressRange", {f"IPV{number}RangeList": from_to_list}
    else:
        return f"Network_IPV_{number}", {f"networkIPV{number}List": list_to_send}


def create_body_update_rule_for_v10(
    rule_type: str, address: List, number: int, from_to_list: List[dict[str, Optional[Any]]], state: str = "Enabled"
) -> tuple:
    """create part of the body for the command update_rule_object for v10
    Args:
        rule_type: str - The type of the rule.
        address: List - A list of addresses, if relevant.
        number: int - The number of the IPV.
        from_to_list: List - A list that contains dictionaries with from and to addresses.
        state: str - An Enabled or Disabled state.
    Returns:
        Returns the body for the request.
    """
    # build a list of dictionaries with the state, the address, and changedState for update or delete
    # code explanations:
    # changedState: 1 = add, 3 = delete, depends on the choice of the user to overwrite or not
    # AS you can tell from the 'update_rule_object_command', address is a list of dictionaries or strings.
    # The existing addresses are dictionaries and the upcoming addresses are strings
    # if the address is a dictionary, the user wants to delete and overwrite that's the reason we kept that address in the list.
    list_to_send: list[dict] = []
    for single_address in address:
        if type(single_address) is dict:  # if its a dict == its an existing address to overwrite, we saved from the 'get' call
            list_to_send.append({"value": single_address.get("value"), "state": STATE_TO_NUMBER.get(state), "changedState": 3})
        else:  # its a new address the user wants to add
            list_to_send.append({"value": single_address, "state": STATE_TO_NUMBER.get(state), "changedState": 1})

    # for parameters with a range, we need to add the state and the changeState to the dictionary
    # Similar logic to above, if "state" is in the dictionary, the user wants to delete and overwrite that's the reason
    # we kept that range in the list.
    if from_to_list:
        for dictionary in from_to_list:
            if "state" in dictionary:  # if the state is in the dictionary, it means the user wants to delete that range.
                dictionary.update({"changedState": 3})
            else:  # if the state is not in the dictionary, it means the user wants to add that range of addresses
                dictionary.update({"state": STATE_TO_NUMBER.get(state), "changedState": 1})

    if HOST in rule_type:
        return f"HostIPv{number}", {f"hostIPv{number}AddressList": list_to_send}
    elif ADDRESS_RANGE in rule_type:
        return f"IPv{number}AddressRange", {f"IPV{number}RangeList": from_to_list}
    else:
        return f"Network_IPV_{number}", {f"networkIPV{number}List": list_to_send}


def modify_v10_results_to_v9_format(response: List[dict[Any, Any]]) -> List[dict[Any, Any]]:
    """
    Modify the response of v10 to be in the same format as in v9.
    The main difference is that in v10 the API returns the addresses in a list of dictionaries,
    A dictionary for each address with extra information, and in v9 all the addresses are in one list.

    This function takes a v10 response and returns a v9 response (to maintain backward compatibility).
    Args:
        response: List[Dict[Any, Any]] - The response of the command of v10.
    Returns:
        A list of dictionaries in the same format as in v9.
    """
    key_list = ["IPv6AddressRange", "HostIPv6", "Network_IPV_6", "Network_IPV_4", "HostIPv4", "IPv4AddressRange"]
    for record in response:
        for key, value in record.items():
            if key in key_list and value:  # find the key that its value is the dict contains the addresses
                address_list: list = []
                my_key = key

                # The value of the first (and only) key is a list containing dict with addresses
                addresses = value[ADDRESS_LIST_MAP.get(key)]
                for inner_dict in addresses:
                    temp_dict = {}
                    for key in inner_dict:
                        # choose the relevant keys and values and saves them in a temp dict
                        if key == "value":
                            address_list.append(inner_dict[key])
                        elif key in ["FromAddress", "ToAddress"]:
                            temp_dict[key] = inner_dict[key]

                    address_list.append(temp_dict) if temp_dict else None

                if address_list:
                    # replace the list of dicts in the original record with a list of strings containing the addresses
                    record[my_key] = {ADDRESS_LIST_MAP.get(my_key): address_list}

    return response


def capitalize_key_first_letter(input_lst: List[dict], check_lst: List = []) -> List[dict]:
    """
    Capitalize the first letter of all keys in all given dictionaries,
    while keeping the rest of the key as it is.(can't use 'capitalize()').
    Args:
        input_lst: List - A list of dictionaries.
        check_lst: List - A list of keys to check if they exist in the dictionary.
    Returns:
        Returns the dict with the first letter of all keys capitalized.
    """
    capitalize_lst = []
    for my_dict in input_lst:
        my_dict = (
            {k[:1].upper() + k[1:]: v for k, v in my_dict.items() if k in check_lst}
            if check_lst
            else {k[:1].upper() + k[1:]: v for k, v in my_dict.items()}
        )
        capitalize_lst.append(my_dict) if my_dict else None
    return capitalize_lst


def flatten_and_capitalize(main_dict: dict, inner_dict_key: str, check_lst: List = []) -> dict:
    """
     Flatten a nested dictionary and capitalize the first letter of all the nested dictionary's key
    Args:
        main_dict: Dict - A dictionary with a nested dict.
        inner_dict_key: str - The key of the nested dictionary.
        check_lst: List - A list of keys to check if they exist in the dictionary.
    Returns:
        Returns a flat dict with the first letter of all keys capitalized.
    """
    if inner_dict := main_dict.pop(inner_dict_key, None):
        capitalized_inner = capitalize_key_first_letter(input_lst=[inner_dict], check_lst=check_lst)[0]
        main_dict |= capitalized_inner
    return main_dict


def deploy_polling_message(status: dict, args: dict):
    """
    Builds a message and a fail or success list for the polling command
    Args:
        status: the status of the deployment
        args: the arguments of the deployment command
    Returns:
        fail_or_success_list: a list of 0 or 1, 0 for failure and 1 for success
        message: a message to be printed to the user
    """
    fail_or_success_list = []
    build_a_massage = ""
    for k, v in args.items():
        if v == "true":  # if the value is true that is one of the arguments to deploy and we need to check its status
            current_percentage_status = status.get(DEPLOY_ARGUMENT_MAPPER.get(str(k)))
            current_message_status = status.get(MESSAGE_MAP.get(str(k)))
            if current_percentage_status != 100 or current_message_status != "DOWNLOAD COMPLETE":
                fail_or_success_list.append(0)
                build_a_massage += f"""\nThe current percentage of deployment for '{k}' is: {current_percentage_status}%
                \nAnd the current message is: {current_message_status}\n"""
            else:
                fail_or_success_list.append(1)
    return fail_or_success_list, build_a_massage


def check_required_arg(arg_name: str, arg_value: int | None) -> int:
    """Check if the required arguments are present in the command.
    Args:
        arg_value: int - The expected value for the argument.
        arg_name: str - The name of the argument.
    """
    if not arg_value and arg_value != 0:
        raise DemistoException(f"Please provide a {arg_name} argument.")
    return arg_value


def check_args_create_rule(rule_type: str, address: List, from_address: str, to_address: str, number: int):
    """Validate the arguments of the function
    Args:
        rule_type: str - The type of the rule.
        address: List - A list of addresses, if relevant.
        from_address: str - The from address, if relevant.
        to_address: str - The to address, if relevant.
        number: int - The number of the addresses IP V.
    """
    if not address and not from_address and not to_address:
        raise Exception("Please enter a matching address.")
    if ("4" in rule_type and number == 6) or ("6" in rule_type and number == 4):
        raise Exception('The version of the IP in "rule_object_type" should match the addresses version.')
    if (HOST in rule_type or "NETWORK" in rule_type) and (not address or from_address or to_address):
        raise Exception(
            f'If the "rule_object_type" is “Endpoint IP V.{number}” or “Network IP V.{number}” than only'
            f" the argument “address_ip_v.{number}” must contain a value. The other address arguments "
            f"should be empty."
        )
    if ADDRESS_RANGE in rule_type and (not to_address or not from_address or address):
        raise Exception(
            f'If the "rule_object_type" is “Range IP V.{number}” than only the arguments '
            f"“from_address_ip_v.{number}” and “to_address_ip_v.{number}” must contain a value, the other"
            f" address arguments should be empty."
        )


def h_r_get_domains(children: List[dict], contents: List):
    """Creates the human readable for the command get_domains.
    Args:
        children: List[Dict] - A list of the children.
        contents: List - The human readable object.
    Returns:
        The human readable contains the relevant values.
    """
    for child in children:
        child["ID"] = child.get("id")
        del child["id"]
        child["Name"] = child.get("name")
        del child["name"]
        d = {"ID": child.get("ID"), "Name": child.get("Name")}
        contents.append(d)
        if child.get("childdomains", []):
            h_r_get_domains(child.get("childdomains", []), contents)


def update_source_destination_object(
    obj: List[dict], rule_object_id: Optional[int], rule_object_type: Optional[str]
) -> List[dict]:
    """Updates the source and destination objects in the command update_firewall_policy.
    Args:
        obj: List[Dict] - The relevant object.
        rule_object_id: Optional[int] - The id of the rule.
        rule_object_type: Optional[str] - The type of the rule
    Returns:
        The updated object.
    """
    if rule_object_id:
        if rule_object_id == -1:
            raise Exception(
                "If you want to delete an address please provide is_overwrite=true and the relevant rule_object_id=-1."
            )
        new_object = {"RuleObjectId": rule_object_id, "RuleObjectType": rule_object_type}
        old_id = obj[0].get("RuleObjectId")
        # if the old id is -1, it means that there wasn't any specific rule before, and we need to overwrite the
        # "placeholder" rule.
        if old_id == "-1":
            obj = [new_object]
        else:
            obj.append(new_object)
    return obj


def overwrite_source_destination_object(
    rule_object_id: Optional[int], rule_object_type: Optional[str], dest_or_src: str, member_rule_list: dict
) -> List:
    """overwrite the source and destination objects in the command update_firewall_policy.
    Args:
        rule_object_id: Optional [int] - The id of the rule.
        rule_object_type: Optional[str] - The type of the rule.
        dest_or_src: str - Overwrite the destination or source object.
        member_rule_list: Dict - The first object in MemberRuleList in the API response.
    Returns:
        The overwrite object.
    """
    if rule_object_id:
        if rule_object_id == -1:
            return [{"RuleObjectId": -1, "RuleObjectType": None}]
        else:
            return [{"RuleObjectId": rule_object_id, "RuleObjectType": rule_object_type}]
    else:
        return member_rule_list.get(f"{dest_or_src}AddressObjectList", [dict])


def update_filter(filter_arg: str) -> str:
    """Removes the special characters from the name argument in filter, because tha api do not work with special
    characters.
    Args:
        filter_arg: str - The original filter
    Returns:
        The updated filter, without special chars.
    Example:
        - name:HTTP: IIS 6.0 (CVE-0000-0000) -> name:HTTP  IIS 6 0  CVE 0000 0000
    """
    split_filter = filter_arg.split(";")
    for index, s in enumerate(split_filter):
        if "name" in s:
            s = s.replace("name:", "")
            s = re.sub("[^a-zA-Z0-9]", " ", s)
            s = f"name:{s}"
            split_filter[index] = s
            break
    return ";".join(split_filter)


def get_addresses_from_response(response: dict) -> List:
    """Returns the addresses from the response, for the human-readable in the command get_rule_object.
    Args:
        response: Dict - The response from the API.
    Returns:
        The list of addresses.
    """
    rule_type = response.get("ruleobjType", "")
    number = 4 if "4" in rule_type else 6
    if HOST in rule_type:
        return response.get(f"HostIPv{number}", {}).get(f"hostIPv{number}AddressList", [])
    elif ADDRESS_RANGE in rule_type:
        return response.get(f"IPv{number}AddressRange", {}).get(f"IPV{number}RangeList", [dict])
    else:  # 'NETWORK'
        return response.get(f"Network_IPV_{number}", {}).get(f"networkIPV{number}List", [])


""" COMMAND FUNCTIONS """


def test_module(client: Client, username_n_password: str) -> str:
    """Test the connection to McAfee NSM.
    Args:
        client: Client - A McAfeeNSM client.
        username_n_password: str - The string that contains username:password to be encoded.
    Returns:
        'ok' if the connection was successful, else throws exception.
    """
    try:
        get_session(client, username_n_password)
        return "ok"
    except DemistoException as e:
        raise Exception(e.message)


def list_domain_firewall_policy_command(client: Client, args: dict) -> CommandResults:
    """Gets the list of Firewall Policies defined in a particular domain.
    Args:
        client: client - A McAfeeNSM client.
        args: Dict - The function arguments.
    Returns:
        A CommandResult object with the list of Firewall Policies defined in a particular domain.
    """
    domain_id = int(args.get("domain_id", 0))
    limit = arg_to_number(args.get("limit", DEFAULT_LIMIT)) or DEFAULT_LIMIT
    page = arg_to_number(args.get("page"))
    page_size = arg_to_number(args.get("page_size"))
    if (page and not page_size) or (not page and page_size):
        raise Exception("Please provide both page and page_size arguments.")

    response = client.list_domain_firewall_policy_request(domain_id)
    result = sorted(response.get("FirewallPoliciesForDomainResponseList", []), key=lambda k: k["policyId"], reverse=True)
    result = pagination(result, limit, page, page_size)
    contents = []
    for value in result:
        d = {
            "policyId": value.get("policyId"),
            "policyName": value.get("policyName"),
            "domainId": value.get("domainId"),
            "visibleToChild": value.get("visibleToChild"),
            "description": value.get("description"),
            "isEditable": value.get("isEditable"),
            "policyType": value.get("policyType"),
            "policyVersion": value.get("policyVersion"),
            "lastModUser": value.get("lastModUser"),
        }
        contents.append(d)

    headers = [
        "policyId",
        "policyName",
        "domainId",
        "visibleToChild",
        "description",
        "isEditable",
        "policyType",
        "policyVersion",
        "lastModUser",
    ]
    readable_output = tableToMarkdown(name="Firewall Policies List", t=contents, removeNull=True, headers=headers)

    return CommandResults(
        readable_output=readable_output,
        outputs_prefix="NSM.Policy",
        outputs_key_field="policyId",
        outputs=result,
        raw_response=result,
    )


def get_firewall_policy_command(client: Client, args: dict) -> CommandResults:
    """Gets the Firewall Policy details.
    Args:
        client: client - A McAfeeNSM client.
        args: Dict - The function arguments.
    Returns:
        A CommandResult object with the Firewall Policy details.
    """
    policy_id = int(args.get("policy_id", ""))
    include_rule_objects = argToBoolean(args.get("include_rule_objects", False))
    response = client.get_firewall_policy_request(policy_id)
    if not include_rule_objects:
        member_rule_list = response.get("MemberDetails", {}).get("MemberRuleList", [dict])
        updated_member_rule_list = []
        for member in member_rule_list:
            d = {
                "Description": member.get("Description"),
                "Direction": member.get("Direction"),
                "Enabled": member.get("Enabled"),
                "Response": member.get("Response"),
                "IsLogging": member.get("IsLogging"),
            }
            updated_member_rule_list.append(d)
        response.get("MemberDetails", {})["MemberRuleList"] = updated_member_rule_list
    contents = {
        "FirewallPolicyId": response.get("FirewallPolicyId"),
        "Name": response.get("Name"),
        "Description": response.get("Description"),
        "VisibleToChild": response.get("VisibleToChild"),
        "IsEditable": response.get("IsEditable"),
        "PolicyType": response.get("PolicyType"),
        "PolicyVersion": response.get("PolicyVersion"),
        "LastModifiedUser": response.get("LastModifiedUser"),
        "LastModifiedTime": response.get("LastModifiedTime"),
    }
    headers = [
        "PolicyId",
        "Name",
        "Description",
        "VisibleToChild",
        "IsEditable",
        "PolicyType",
        "PolicyVersion",
        "LastModifiedUser",
        "LastModifiedTime",
    ]
    readable_output = tableToMarkdown(name=f"Firewall Policy {policy_id}", t=contents, removeNull=True, headers=headers)
    return CommandResults(
        readable_output=readable_output,
        outputs_prefix="NSM.Policy",
        outputs=response,
        raw_response=response,
        outputs_key_field="FirewallPolicyId",
    )


def create_firewall_policy_command(client: Client, args: dict) -> CommandResults:
    """Adds a new Firewall Policy and Access Rules.
    Args:
        client: client - A McAfeeNSM client.
        args: Dict - The function arguments.
    Returns:
        A CommandResult object with a success message.
    """
    domain = arg_to_number(args.get("domain", "0"), required=True) or 0
    name = args.get("name", "")
    visible_to_child = argToBoolean(args.get("visible_to_child", True))
    description = args.get("description", "")
    is_editable = argToBoolean(args.get("is_editable", True)) or True
    policy_type = args.get("policy_type", "").upper()
    rule_description = args.get("rule_description", "")
    rule_enabled = argToBoolean(args.get("rule_enabled", True))
    response_param = response_cases(args.get("response", ""))
    direction = args.get("direction", "").upper()
    source_rule_object_id = arg_to_number(args.get("source_rule_object_id", -1))
    source_rule_object_type = args.get("source_rule_object_type", None)
    destination_rule_object_id = arg_to_number(args.get("destination_rule_object_id", -1))
    destination_rule_object_type = args.get("destination_rule_object_type", None)

    check_source_and_destination(
        source_rule_object_id, source_rule_object_type, destination_rule_object_id, destination_rule_object_type, "create"
    )

    source_rule_object_type = rule_object_type_cases(source_rule_object_type, "up") if source_rule_object_type else None
    destination_rule_object_type = (
        rule_object_type_cases(destination_rule_object_type, "up") if destination_rule_object_type else None
    )
    source_object = overwrite_source_destination_object(source_rule_object_id, source_rule_object_type, "", {})
    destination_object = overwrite_source_destination_object(destination_rule_object_id, destination_rule_object_type, "", {})

    body = create_body_firewall_policy(
        domain,
        name,
        visible_to_child,
        description,
        is_editable,
        policy_type,
        rule_description,
        response_param,
        rule_enabled,
        direction,
        source_object,
        destination_object,
    )

    response = client.create_firewall_policy_request(body)
    response = {"FirewallPolicyId": response.get("createdResourceId")}
    new_firewall_policy_id = response.get("FirewallPolicyId")
    return CommandResults(
        readable_output=f"The firewall policy no.{new_firewall_policy_id} was created successfully",
        outputs_prefix="NSM.Policy",
        outputs=response,
        raw_response=response,
        outputs_key_field="FirewallPolicyId",
    )


def update_firewall_policy_command(client: Client, args: dict) -> CommandResults:
    """Updates the Firewall Policy details.
    Args:
        client: client - A McAfeeNSM client.
        args: Dict - The function arguments.
    Returns:
        A CommandResult object with a success message.
    """
    policy_id = int(args.get("policy_id", ""))
    domain = args.get("domain")
    name = args.get("name")
    visible_to_child = args.get("visible_to_child")
    description = args.get("description")
    is_editable = args.get("is_editable")
    policy_type = args.get("policy_type")
    rule_description = args.get("rule_description")
    response_param = args.get("response")
    rule_enabled = args.get("rule_enabled")
    direction = args.get("direction")
    source_rule_object_id = arg_to_number(args.get("source_rule_object_id", None))
    source_rule_object_type = args.get("source_rule_object_type", None)
    source_rule_object_type = rule_object_type_cases(source_rule_object_type, "up") if source_rule_object_type else None
    destination_rule_object_id = arg_to_number(args.get("destination_rule_object_id", None))
    destination_rule_object_type = args.get("destination_rule_object_type")
    destination_rule_object_type = (
        rule_object_type_cases(destination_rule_object_type, "up") if destination_rule_object_type else None
    )
    is_overwrite = argToBoolean(args.get("is_overwrite", False))

    if is_overwrite and (not source_rule_object_id and not destination_rule_object_id):
        raise Exception("If is_overwrite=true than at least one of the rules (source or destination) must be provided.")

    check_source_and_destination(
        source_rule_object_id, source_rule_object_type, destination_rule_object_id, destination_rule_object_type, "update"
    )

    policy_get_details = client.get_firewall_policy_request(policy_id)

    if not policy_get_details.get("IsEditable"):
        raise Exception(f"The policy no.{policy_id} can't be edited")

    member_rule_list = policy_get_details.get("MemberDetails", {}).get("MemberRuleList", [dict])[0]
    domain = domain if domain else policy_get_details.get("DomainId")
    name = name if name else policy_get_details.get("Name")
    visible_to_child = policy_get_details.get("VisibleToChild") if not visible_to_child else argToBoolean(visible_to_child)
    description = description if description else policy_get_details.get("Description")
    is_editable = policy_get_details.get("IsEditable") if not is_editable else argToBoolean(is_editable)
    policy_type = policy_get_details.get("PolicyType") if not policy_type else policy_type.upper()
    rule_description = member_rule_list.get("Description") if not rule_description else argToBoolean(rule_description)
    response_param = member_rule_list.get("Response") if not response_param else response_cases(response_param)
    rule_enabled = member_rule_list.get("Enabled") if not rule_enabled else argToBoolean(rule_enabled)
    direction = member_rule_list.get("Direction") if not direction else direction.upper()

    if is_overwrite:
        source_object = overwrite_source_destination_object(
            source_rule_object_id, source_rule_object_type, "Source", member_rule_list
        )
        destination_object = overwrite_source_destination_object(
            destination_rule_object_id, destination_rule_object_type, "Destination", member_rule_list
        )
    else:
        source_object = member_rule_list.get("SourceAddressObjectList", [dict])
        source_object = update_source_destination_object(source_object, source_rule_object_id, source_rule_object_type)

        destination_object = member_rule_list.get("DestinationAddressObjectList", [])
        destination_object = update_source_destination_object(
            destination_object, destination_rule_object_id, destination_rule_object_type
        )

    body = create_body_firewall_policy(
        domain,  # type: ignore[arg-type]
        name,  # type: ignore[arg-type]
        visible_to_child,  # type: ignore[arg-type]
        description,  # type: ignore[arg-type]
        is_editable,  # type: ignore[arg-type]
        policy_type,  # type: ignore[arg-type]
        rule_description,
        response_param,
        rule_enabled,
        direction,
        source_object,
        destination_object,
    )

    client.update_firewall_policy_request(body, policy_id)
    return CommandResults(readable_output=f"The firewall policy no.{policy_id} was updated successfully")


def delete_firewall_policy_command(client: Client, args: dict) -> CommandResults:
    """Deletes the specified Firewall Policy.
    Args:
        client: client - A McAfeeNSM client.
        args: Dict - The function arguments.
    Returns:
        A CommandResult object with a success message.
    """
    policy_id = int(args.get("policy_id", ""))
    client.delete_firewall_policy_request(policy_id)
    return CommandResults(readable_output=f"The firewall policy no.{policy_id} was deleted successfully")


def list_domain_rule_objects_command(client: Client, args: dict) -> CommandResults:
    """Gets the list of rule objects defined in a particular domain.
    Args:
        client: client - A McAfeeNSM client.
        args: Dict - The function arguments.
    Returns:
        A CommandResult object with the list.
    """
    domain_id = arg_to_number(args.get("domain_id"), required=True) or 0
    rule_type = args.get("type", "All")
    limit = arg_to_number(args.get("limit", DEFAULT_LIMIT)) or DEFAULT_LIMIT
    page = arg_to_number(args.get("page"))
    page_size = arg_to_number(args.get("page_size"))

    if (page and not page_size) or (not page and page_size):
        raise Exception("Please provide both page and page_size arguments.")

    if rule_type == "All":
        rule_type = "hostipv4,hostipv6,ipv4addressrange,ipv6addressrange,networkipv4,networkipv6"
    else:
        rule_type = rule_object_type_cases(rule_type, "low")
    response = client.list_domain_rule_objects_request(domain_id, rule_type)
    results = pagination(response.get("RuleObjDef", []), limit, page, page_size)
    # modify the results in v10 to match the v9 pattern
    if VERSION == V10:
        results = modify_v10_results_to_v9_format(results)

    contents = []
    for record in results:
        record["ruleobjType"] = reverse_rule_object_type_cases(record.get("ruleobjType", None))
        d = {
            "RuleId": record.get("ruleobjId"),
            "Name": record.get("name"),
            "Description": record.get("description"),
            "VisibleToChild": record.get("visibleToChild"),
            "RuleType": record.get("ruleobjType"),
        }
        contents.append(d)
    headers = ["RuleId", "Name", "Description", "VisibleToChild", "RuleType"]
    readable_output = tableToMarkdown(name="List of Rule Objects", t=contents, removeNull=True, headers=headers)

    return CommandResults(
        readable_output=readable_output,
        outputs_prefix="NSM.Rule",
        outputs=results,
        raw_response=results,
        outputs_key_field="ruleobjId",
    )


def get_rule_object_command(client: Client, args: dict) -> CommandResults:
    """Gets the details of a Rule Object.
    Args:
        client: client - A McAfeeNSM client.
        args: Dict - The function arguments.
    Returns:
        A CommandResult object with information about the rule object.
    """
    rule_id = int(args.get("rule_id", ""))
    response = client.get_rule_object_request(rule_id)
    response = response.get("RuleObjDef", {})
    addresses = get_addresses_from_response(response)
    # modify the results in v10 to match the v9 pattern
    if VERSION == V10:
        response = modify_v10_results_to_v9_format([response])[0]
    addresses = get_addresses_from_response(response)
    response["ruleobjType"] = reverse_rule_object_type_cases(response.get("ruleobjType"))
    contents = {
        "RuleId": response.get("ruleobjId"),
        "Name": response.get("name"),
        "Description": response.get("description"),
        "VisibleToChild": response.get("visibleToChild"),
        "RuleType": response.get("ruleobjType"),
        "Addresses": addresses,
    }
    headers = ["RuleId", "Name", "Description", "VisibleToChild", "RuleType", "Addresses"]
    readable_output = tableToMarkdown(name=f"Rule Objects {rule_id}", t=contents, removeNull=True, headers=headers)
    return CommandResults(
        readable_output=readable_output,
        outputs_prefix="NSM.Rule",
        outputs=response,
        raw_response=response,
        outputs_key_field="ruleobjId",
    )


def create_rule_object_command(client: Client, args: dict) -> CommandResults:
    """Adds a new Rule Object.
    Args:
        client: client - A McAfeeNSM client.
        args: Dict - The function arguments.
    Returns:
        A CommandResult object with a success message.
    """
    domain = arg_to_number(args.get("domain", 0))
    rule_type = rule_object_type_cases(args.get("rule_object_type", ""), "up")
    name = args.get("name")
    visible_to_child = argToBoolean(args.get("visible_to_child", True))
    description = args.get("description")
    address_ip_v_4 = argToList(args.get("address_ip_v.4", None))
    from_address_ip_v_4 = args.get("from_address_ip_v.4")
    to_address_ip_v_4 = args.get("to_address_ip_v.4")
    address_ip_v_6 = argToList(args.get("address_ip_v.6"))
    from_address_ip_v_6 = args.get("from_address_ip_v.6")
    to_address_ip_v_6 = args.get("to_address_ip_v.6")
    state: str = args.get("state", "Enabled")

    if (
        (address_ip_v_4 and address_ip_v_6)
        or (from_address_ip_v_4 and from_address_ip_v_6)
        or (to_address_ip_v_4 and to_address_ip_v_6)
    ):
        raise Exception(
            "Those pairs of arguments (address_ip_v_4 and address_ip_v_6) or "
            "(from_address_ip_v_4 and from_address_ip_v_6) or (to_address_ip_v_4 and to_address_ip_v_6)"
            "should not have values in parallel, only one at a time."
        )
    address = address_ip_v_4 if address_ip_v_4 else address_ip_v_6
    number = 4 if (address_ip_v_4 or from_address_ip_v_4) else 6
    from_address = from_address_ip_v_4 if from_address_ip_v_4 else from_address_ip_v_6
    to_address = to_address_ip_v_4 if to_address_ip_v_4 else to_address_ip_v_6

    check_args_create_rule(rule_type, address, from_address, to_address, number)  # type: ignore[arg-type]

    body = {
        "RuleObjDef": {
            "domain": domain,
            "ruleobjType": rule_type,
            "visibleToChild": visible_to_child,
            "description": description,
            "name": name,
        }
    }

    from_to_list = [{"FromAddress": from_address, "ToAddress": to_address}]
    # create the body according to the version of the NSM
    if VERSION == V10:
        d_name, extra_body = create_body_create_rule_for_v10(
            rule_type=rule_type, address=address, number=number, from_to_list=from_to_list, state=state
        )
    else:
        d_name, extra_body = create_body_create_rule(rule_type, address, number, from_to_list)

    rule_obj_def = body.get("RuleObjDef", {})
    rule_obj_def[d_name] = extra_body
    response = client.create_rule_object_request(body)
    response = {"ruleobjId": response.get("createdResourceId")}

    return CommandResults(
        readable_output=f'The rule object no.{response.get("ruleobjId")} was created successfully',
        outputs_prefix="NSM.Rule",
        outputs=response,
        raw_response=response,
        outputs_key_field="ruleobjId",
    )


def update_rule_object_command(client: Client, args: dict) -> CommandResults:
    """Updates a Rule Object.
    Args:
        client: client - A McAfeeNSM client.
        args: Dict - The function arguments.
    Returns:
        A CommandResult object with a success message.
    """
    domain = arg_to_number(args.get("domain", 0)) or 0
    rule_id = int(args.get("rule_id", ""))
    name = args.get("name")
    visible_to_child = args.get("visible_to_child")
    description = args.get("description")
    address_ip_v_4 = argToList(args.get("address_ip_v.4", None))
    from_address_ip_v_4 = args.get("from_address_ip_v.4")
    to_address_ip_v_4 = args.get("to_address_ip_v.4")
    address_ip_v_6 = argToList(args.get("address_ip_v.6"))
    from_address_ip_v_6 = args.get("from_address_ip_v.6")
    to_address_ip_v_6 = args.get("to_address_ip_v.6")
    is_overwrite = argToBoolean(args.get("is_overwrite", False))
    state: str = args.get("state", "Enabled")
    response_get = client.get_rule_object_request(rule_id)
    response_get = response_get.get("RuleObjDef", {})

    rule_type = response_get.get("ruleobjType")
    if (rule_type == "HOST_IPV_4" or rule_type == "NETWORK_IPV_4") and (
        from_address_ip_v_4 or to_address_ip_v_4 or address_ip_v_6 or from_address_ip_v_6 or to_address_ip_v_6
    ):
        raise Exception(
            "If the rule object type is Endpoint IP V.4 or Network IP V.4 than only the argument "
            '"address_ip_v_4" should contain a value'
        )
    elif (rule_type == "IPV_4_ADDRESS_RANGE") and (
        (from_address_ip_v_4 and not to_address_ip_v_4) or (not from_address_ip_v_4 and to_address_ip_v_4)
    ):
        raise Exception(
            'If the rule object type is Range IP V.4 than both "from_address_ip_v_4" and '
            '"to_address_ip_v_4" must contain a value or be empty.'
        )
    elif (rule_type == "IPV_4_ADDRESS_RANGE") and (address_ip_v_4 or address_ip_v_6 or from_address_ip_v_6 or to_address_ip_v_6):
        raise Exception(
            'If the rule object type is Range IP V.4 than only the arguments "from_address_ip_v_4" and '
            '"to_address_ip_v_4" should contain a value'
        )
    elif (rule_type == "HOST_IPV_6" or rule_type == "NETWORK_IPV_6") and (
        address_ip_v_4 or from_address_ip_v_4 or to_address_ip_v_4 or from_address_ip_v_6 or to_address_ip_v_6
    ):
        raise Exception(
            "If the rule object type is Endpoint IP V.6 or Network IP V.6 than only the argument "
            '"address_ip_v_6" should contain a value'
        )
    elif (rule_type == "IPV_6_ADDRESS_RANGE") and (
        (from_address_ip_v_6 and not to_address_ip_v_6) or (not from_address_ip_v_6 and to_address_ip_v_6)
    ):
        raise Exception(
            'If the rule object type is Range IP V.6 than both "from_address_ip_v_6" and '
            '"to_address_ip_v_6" must contain a value or be empty.'
        )
    elif (rule_type == "IPV_6_ADDRESS_RANGE") and (address_ip_v_4 or address_ip_v_6 or from_address_ip_v_4 or to_address_ip_v_4):
        raise Exception(
            'If the rule object type is Range IP V.6 than only the arguments "from_address_ip_v_6" and '
            '"to_address_ip_v_6" should contain a value'
        )

    name = name if name else response_get.get("name")
    visible_to_child = argToBoolean(visible_to_child) if visible_to_child else response_get.get("visibleToChild")
    description = description if description else response_get.get("description")
    from_to_address_ip_v_6 = []
    from_to_address_ip_v_4 = []
    # in v9 if the user wants to overwrite the addresses we send only the new values,
    # in v10 we do the same thing if the user dose not want to overwrite the addresses
    if (VERSION == V9 and is_overwrite) or (VERSION == V10 and not is_overwrite):
        if rule_type == "HOST_IPV_4":
            address_ip_v_4 = address_ip_v_4 if address_ip_v_4 else response_get.get("HostIPv4", {}).get("hostIPv4AddressList")
        if rule_type == "NETWORK_IPV_4":
            address_ip_v_4 = address_ip_v_4 if address_ip_v_4 else response_get.get("Network_IPV_4", {}).get("networkIPV4List")
        if from_address_ip_v_4:
            from_to_address_ip_v_4 = [{"FromAddress": from_address_ip_v_4, "ToAddress": to_address_ip_v_4}]
        elif not from_address_ip_v_4 and rule_type == "IPV_4_ADDRESS_RANGE":
            from_to_address_ip_v_4 = response_get.get("IPv4AddressRange", {}).get("IPV4RangeList")
        if rule_type == "HOST_IPV_6":
            address_ip_v_6 = address_ip_v_6 if address_ip_v_6 else response_get.get("HostIPv6", {}).get("hostIPv6AddressList")
        if rule_type == "NETWORK_IPV_6":
            address_ip_v_6 = address_ip_v_6 if address_ip_v_6 else response_get.get("Network_IPV_6", {}).get("networkIPV6List")
        if from_address_ip_v_6:
            from_to_address_ip_v_6 = [{"FromAddress": from_address_ip_v_6, "ToAddress": to_address_ip_v_6}]
        elif not from_address_ip_v_6 and rule_type == "IPV_6_ADDRESS_RANGE":
            from_to_address_ip_v_6 = response_get.get("IPv6AddressRange", {}).get("IPV6RangeList")
    # in v9 if the user wants to add new addresses we send the old values and the new addresses,
    # in v10 we do the same thing if the user wants to overwrite the addresses
    elif (VERSION == V9 and not is_overwrite) or (VERSION == V10 and is_overwrite):
        if rule_type == "HOST_IPV_4":
            old_address_ip_v_4 = response_get.get("HostIPv4", {}).get("hostIPv4AddressList", [])
            if address_ip_v_4:
                old_address_ip_v_4.extend(address_ip_v_4)
            address_ip_v_4 = old_address_ip_v_4
        elif rule_type == "NETWORK_IPV_4":
            old_address_ip_v_4 = response_get.get("Network_IPV_4", {}).get("networkIPV4List", [])
            if address_ip_v_4:
                old_address_ip_v_4.extend(address_ip_v_4)
            address_ip_v_4 = old_address_ip_v_4
        elif rule_type == "IPV_4_ADDRESS_RANGE":
            from_to_address_ip_v_4 = response_get.get("IPv4AddressRange", {}).get("IPV4RangeList", [])
            if from_address_ip_v_4 and to_address_ip_v_4:
                from_to_address_ip_v_4.append({"FromAddress": from_address_ip_v_4, "ToAddress": to_address_ip_v_4})
        elif rule_type == "HOST_IPV_6":
            old_address_ip_v_6 = response_get.get("HostIPv6", {}).get("hostIPv6AddressList", [])
            if address_ip_v_6:
                old_address_ip_v_6.extend(address_ip_v_6)
            address_ip_v_6 = old_address_ip_v_6
        elif rule_type == "NETWORK_IPV_6":
            old_address_ip_v_6 = response_get.get("Network_IPV_6", {}).get("hostIPv6AddressList", [])
            if address_ip_v_6:
                old_address_ip_v_6.extend(address_ip_v_6)
            address_ip_v_6 = old_address_ip_v_6
        elif rule_type == "IPV_6_ADDRESS_RANGE":
            from_to_address_ip_v_6 = response_get.get("IPv6AddressRange", {}).get("networkIPV6List", [])
            if from_address_ip_v_6 and to_address_ip_v_6:
                from_to_address_ip_v_6.append({"FromAddress": from_address_ip_v_6, "ToAddress": to_address_ip_v_6})

    body = {
        "RuleObjDef": {
            "domain": domain,
            "ruleobjType": rule_type,
            "visibleToChild": visible_to_child,
            "description": description,
            "name": name,
        }
    }
    address = address_ip_v_4 if address_ip_v_4 else address_ip_v_6
    number = 4 if (address_ip_v_4 or from_to_address_ip_v_4) else 6
    from_to_list = from_to_address_ip_v_4 if from_to_address_ip_v_4 else from_to_address_ip_v_6
    # create the body according to the version of the NSM
    if VERSION == V10:
        d_name, extra_body = create_body_update_rule_for_v10(
            rule_type=rule_type, address=address, number=number, from_to_list=from_to_list, state=state
        )

    else:
        d_name, extra_body = create_body_create_rule(rule_type, address, number, from_to_list)

    rule_obj_def = body.get("RuleObjDef", {})
    rule_obj_def[d_name] = extra_body
    client.update_rule_object_request(body, rule_id)
    return CommandResults(readable_output=f"The rule object no.{rule_id} was updated successfully.")


def delete_rule_object_command(client: Client, args: dict) -> CommandResults:
    """Deletes a Rule Object.
    Args:
        client: client - A McAfeeNSM client.
        args: Dict - The function arguments.
    Returns:
        A CommandResult object with a success message.
    """
    rule_id = int(args.get("rule_id", ""))
    client.delete_rule_object_request(rule_id)
    return CommandResults(readable_output=f"The rule object no.{rule_id} was deleted successfully")


def get_alerts_command(client: Client, args: dict) -> CommandResults:
    """Retrieves All Alerts.
    Args:
        client: client - A McAfeeNSM client.
        args: Dict - The function arguments.
    Returns:
        A CommandResult object with a list of alerts.
    """
    limit = arg_to_number(args.get("limit", DEFAULT_LIMIT)) or DEFAULT_LIMIT
    page = arg_to_number(args.get("page"))
    page_size = arg_to_number(args.get("page_size"))
    time_period = args.get("time_period", "LAST_7_DAYS")
    start_time = args.get("start_time", None)
    end_time = args.get("end_time", None)
    state = args.get("state", None)
    search = args.get("search", None)
    filter_arg = args.get("filter", None)
    domain_id = arg_to_number(args.get("domain_id")) or 0
    if args.get("new_state"):
        state = args.get("new_state")

    if (page and not page_size) or (not page and page_size):
        raise Exception("Please provide both page and page_size arguments.")
    if (start_time and not end_time) or (not start_time and end_time):
        raise Exception("If you provide one of the time parameters, you must provide the other as well.")
    if start_time and time_period != "CUSTOM":
        time_period = "CUSTOM"
    if time_period == "CUSTOM" and not start_time:
        raise Exception('If you enter "time_period=CUSTOM" please enter start_time and end_time as well.')

    if filter_arg and "name" in filter_arg:
        filter_arg = update_filter(filter_arg)

    response = client.get_alerts_request(time_period, start_time, end_time, state, search, filter_arg, domain_id)
    total_alerts_count = response.get("totalAlertsCount", 0)
    alerts_list = alerts_list_pagination(
        response.get("alertsList", []),
        limit,
        page,
        page_size,
        time_period,
        start_time,
        end_time,
        state,
        search,
        filter_arg,
        client,
        domain_id,
    )
    result_list = []
    for alert in alerts_list:
        record = {
            "ID": alert.get("event", {}).get("alertId"),
            "Name": alert.get("name"),
            "State": alert.get("alertState"),
            "CreatedTime": alert.get("event", {}).get("time"),
            "Assignee": alert.get("assignTo"),
            "AttackSeverity": alert.get("attackSeverity"),
            "Application": alert.get("application"),
            "EventResult": alert.get("event", {}).get("result"),
            "SensorID": alert.get("detection", {}).get("deviceId"),
            "uniqueAlertId": alert.get("uniqueAlertId"),
            "Event": alert.get("event"),
            "Attack": alert.get("attack"),
            "Attacker": alert.get("attacker"),
            "Target": alert.get("target"),
            "MalwareFile": alert.get("malwareFile"),
            "endpointExcutable": alert.get("endpointExcutable"),
            "detection": alert.get("detection"),
            "layer7Data": alert.get("layer7Data"),
        }
        event_obj = record.get("Event", {})
        event_obj["domain"] = alert.get("detection", {}).get("domain")
        event_obj["interface"] = alert.get("detection", {}).get("interface")
        event_obj["device"] = alert.get("detection", {}).get("device")
        result_list.append(record)
    alerts_list = result_list
    contents = []
    for alert_info in alerts_list:
        d = {
            "ID": alert_info.get("ID"),
            "Name": alert_info.get("Name"),
            "Event Time": alert_info.get("CreatedTime"),
            "Severity": alert_info.get("AttackSeverity"),
            "State": alert_info.get("State"),
            "Direction": alert_info.get("Event", {}).get("direction"),
            "Result": alert_info.get("Event.result"),
            "Attack Count": alert_info.get("EventResult"),
            "Attacker IP": alert_info.get("Attacker", {}).get("ipAddrs"),
            "Target IP": alert_info.get("Target", {}).get("ipAddrs"),
        }
        contents.append(d)

    headers = ["ID", "Name", "Event Time", "Severity", "State", "Direction", "Result", "Attack Count", "Attacker IP", "Target IP"]
    if args.get("new_state"):
        title = f"Updated Alerts list. Showing {len(alerts_list)} of {total_alerts_count}"
    else:
        title = f"Alerts list. Showing {len(alerts_list)} of {total_alerts_count}"
    readable_output = tableToMarkdown(name=title, t=contents, removeNull=True, headers=headers)
    return CommandResults(
        readable_output=readable_output,
        outputs_prefix="NSM.Alerts",
        outputs=alerts_list,
        raw_response=response,
        outputs_key_field="ID",
    )


def get_alert_details_command(client: Client, args: dict) -> CommandResults:
    """Retrieves the relevant alert.
    Args:
        client: client - A McAfeeNSM client.
        args: Dict - The function arguments.
    Returns:
        A CommandResult object with the alert details.
    """
    alert_id = int(args.get("alert_id", ""))
    sensor_id = int(args.get("sensor_id", ""))
    response = client.get_alert_details_request(alert_id, sensor_id)
    response = {
        "ID": response.get("summary", {}).get("event", {}).get("alertId"),
        "Name": response.get("name"),
        "State": response.get("alertState"),
        "CreatedTime": response.get("summary", {}).get("event", {}).get("time"),
        "Assignee": response.get("assignTo"),
        "Description": response.get("description", {}).get("definition"),
        "EventResult": response.get("summary", {}).get("event", {}).get("result"),
        "Attack": {
            "attackCategory": response.get("description", {}).get("attackCategory"),
            "attackSubCategory": response.get("description", {}).get("attackSubCategory"),
            "nspId": response.get("description", {}).get("reference", {}).get("nspId"),
        },
        "Protocols": response.get("description", {}).get("protocols"),
        "SensorID": response.get("summary", {}).get("event", {}).get("deviceId"),
        "Event": response.get("summary", {}).get("event"),
        "Attacker": response.get("summary", {}).get("attacker"),
        "Target": response.get("summary", {}).get("target"),
        "MalwareFile": response.get("details", {}).get("malwareFile"),
        "Details": response.get("details"),
        "uniqueAlertId": response.get("uniqueAlertId"),
        "summary": response.get("summary"),
        "description": response.get("description"),
    }
    summary_obj = response.get("summary", {})
    del summary_obj["event"]
    del summary_obj["attacker"]
    del summary_obj["target"]
    contents = {
        "ID": response.get("ID"),
        "Name": response.get("Name"),
        "Event Time": response.get("CreatedTime"),
        "State": response.get("State"),
        "Direction": response.get("Event", {}).get("direction"),
        "Result": response.get("EventResult"),
        "Attack Count": response.get("Event", {}).get("attackCount"),
        "Attacker IP": response.get("Attacker", {}).get("ipAddrs"),
        "Target IP": response.get("Target", {}).get("ipAddrs"),
    }
    headers = ["ID", "Name", "Event Time", "State", "Direction", "Result", "Attack Count", "Attacker IP", "Target IP"]
    readable_output = tableToMarkdown(name=f"Alert no.{alert_id}", t=contents, removeNull=True, headers=headers)
    return CommandResults(
        readable_output=readable_output,
        outputs_prefix="NSM.Alerts",
        outputs=response,
        raw_response=response,
        outputs_key_field="uniqueAlertId",
    )


def get_attacks_command(client: Client, args: dict) -> List:
    """If an attack id is given The command returns the details for the specific attack.
    Else, gets all available attack definitions in the Manager UI.
    Args:
        client: client - A McAfeeNSM client.
        args: Dict - The function arguments.
    Returns:
        A CommandResult object with The attack details or attacks list.
    """
    attack_id = args.get("attack_id")
    if attack_id and not re.match("^0x[0-9A-Fa-f]{8}$", attack_id):
        raise Exception("Error! Attack ID must be formatted as 32-bit hexadecimal number. for example: 0x1234BEEF")

    response = client.get_attacks_request(attack_id)

    if not attack_id:
        title = "Attacks List"
        attacks_list = response.get("AttackDescriptorDetailsList", [])
    else:
        title = f"Attack no.{attack_id}"
        attacks_list = [response.get("AttackDescriptor", {})]
    result_list = []
    for attack in attacks_list:
        record = {
            "ID": attack.get("attackId"),
            "Name": attack.get("name"),
            "Direction": attack.get("DosDirection"),
            "Category": attack.get("description", {}).get("attackCategory"),
            "Severity": attack.get("Severity"),
            "description": attack.get("description"),
        }
        result_list.append(record)
    attacks_list = result_list
    contents = []
    for attack in attacks_list:
        d = {
            "ID": attack.get("ID"),
            "Name": attack.get("Name"),
            "Direction": attack.get("Direction"),
            "Severity": attack.get("Severity"),
            "Category": attack.get("Category"),
        }
        contents.append(d)
    headers = ["ID", "Name", "Direction", "Severity", "Category"]
    readable_outputs = tableToMarkdown(name=title, t=contents, removeNull=True, headers=headers)
    if not attack_id:
        file_ = fileResult(filename="get-attacks-file-result", data=readable_outputs, file_type=entryTypes["entryInfoFile"])
        return [file_]
    else:
        return [
            CommandResults(
                readable_output=readable_outputs,
                outputs_prefix="NSM.Attacks",
                outputs=attacks_list,
                raw_response=attacks_list,
                outputs_key_field="ID",
            )
        ]


def get_domains_command(client: Client, args: dict) -> CommandResults:
    """If a domain id is given The command returns the details for the specific domain.
    Else, gets all available domains.
    Args:
        client: client - A McAfeeNSM client.
        args: Dict - The function arguments.
    Returns:
        A CommandResult object with The domain details or domains list.
    """
    domain_id = arg_to_number(args.get("domain_id", None))
    limit = arg_to_number(args.get("limit", DEFAULT_LIMIT)) or DEFAULT_LIMIT
    page = arg_to_number(args.get("page"))
    page_size = arg_to_number(args.get("page_size"))
    if (page and not page_size) or (not page and page_size):
        raise Exception("Please provide both page and page_size arguments.")

    response = client.get_domains_request(domain_id)
    results = response.get("DomainDescriptor", {})
    contents = []
    if domain_id is not None:
        title = f"Domain no.{domain_id}"
        results = {"ID": results.get("id"), "Name": results.get("name"), "childdomains": results.get("childdomains")}
        contents = [{"ID": results.get("ID"), "Name": results.get("Name")}]
    else:
        title = "List of Domains"
        children = [results]
        h_r_get_domains(children, contents)
    contents = pagination(contents, limit, page, page_size)
    readable_outputs = tableToMarkdown(name=title, t=contents, removeNull=True)
    return CommandResults(
        readable_output=readable_outputs,
        outputs_prefix="NSM.Domains",
        outputs=results,
        raw_response=results,
        outputs_key_field="ID",
    )


def get_sensors_command(client: Client, args: dict) -> CommandResults:
    """Gets the list of sensors available in the specified domain. If the domain is not specified, details of all
    the sensors in all domains will be provided.
    Args:
        client: client - A McAfeeNSM client.
        args: Dict - The function arguments.
    Returns:
        A CommandResult object with The relevant sensors.
    """
    domain_id = arg_to_number(args.get("domain_id"))
    limit = arg_to_number(args.get("limit", DEFAULT_LIMIT)) or DEFAULT_LIMIT
    page = arg_to_number(args.get("page"))
    page_size = arg_to_number(args.get("page_size"))
    if (page and not page_size) or (not page and page_size):
        raise Exception("Please provide both page and page_size arguments.")

    response = client.get_sensors_request(domain_id)
    sensors_list = pagination(response.get("SensorDescriptor", [dict]), limit, page, page_size)
    result_list = []
    for sensor in sensors_list:
        record = {
            "ID": sensor.get("sensorId"),
            "Name": sensor.get("name"),
            "Description": sensor.get("Description"),
            "DomainID": sensor.get("DomainID"),
            "IPSPolicyID": sensor.get("IPSPolicyID"),
            "IP Address": sensor.get("sensorIPAddress"),
            "model": sensor.get("model"),
            "isFailOver": sensor.get("isFailOver"),
            "isNTBA": sensor.get("isNTBA"),
            "isLoadBalancer": sensor.get("isLoadBalancer"),
            "SerialNumber": sensor.get("SerialNumber"),
            "SigsetVersion": sensor.get("SigsetVersion"),
            "DATVersion": sensor.get("DATVersion"),
            "SoftwareVersion": sensor.get("SoftwareVersion"),
            "LastSignatureUpdateTs": sensor.get("LastSignatureUpdateTs"),
            "ReconPolicyID": sensor.get("ReconPolicyID"),
            "LastModTs": sensor.get("LastModTs"),
            "nsmVersion": sensor.get("nsmVersion"),
            "MemberSensors": sensor.get("MemberSensors"),
        }
        result_list.append(record)
    sensors_list = result_list
    contents = []
    for sensor in sensors_list:
        d = {
            "ID": sensor.get("ID"),
            "Name": sensor.get("Name"),
            "Description": sensor.get("Description"),
            "DomainID": sensor.get("DomainID"),
            "IPSPolicyID": sensor.get("IPSPolicyID"),
            "IP Address": sensor.get("IP Address"),
        }
        contents.append(d)
    headers = ["ID", "Name", "Description", "DomainID", "IPSPolicyID", "IP Address"]
    if domain_id:
        title = f"The Sensors of Domain no.{domain_id}"
    else:
        title = "Sensors List"
    readable_output = tableToMarkdown(name=title, t=contents, removeNull=True, headers=headers)
    return CommandResults(
        readable_output=readable_output,
        outputs_prefix="NSM.Sensors",
        outputs=sensors_list,
        raw_response=sensors_list,
        outputs_key_field="ID",
    )


def get_ips_policies_command(client: Client, args: dict) -> CommandResults:
    """Gets all the IPS Policies defined in the specific domain.
    Args:
        client: client - A McAfeeNSM client.
        args: Dict - The function arguments.
    Returns:
        A CommandResult object with The relevant ips policies.
    """
    domain_id = arg_to_number(args.get("domain_id")) or 0
    limit = arg_to_number(args.get("limit", DEFAULT_LIMIT)) or DEFAULT_LIMIT
    page = arg_to_number(args.get("page"))
    page_size = arg_to_number(args.get("page_size"))
    if (page and not page_size) or (not page and page_size):
        raise Exception("Please provide both page and page_size arguments.")

    response = client.get_ips_policies_request(domain_id)
    policies_list = pagination(response.get("PolicyDescriptorDetailsList", [dict]), limit, page, page_size)
    result_list = []
    for policy in policies_list:
        record = {
            "ID": policy.get("policyId"),
            "Name": policy.get("name"),
            "DomainID": policy.get("DomainId"),
            "VisibleToChildren": policy.get("VisibleToChild"),
            "IsEditable": policy.get("IsEditable"),
        }
        result_list.append(record)
    policies_list = result_list
    contents = []
    for policy in policies_list:
        d = {
            "ID": policy.get("ID"),
            "Name": policy.get("Name"),
            "DomainID": policy.get("DomainID"),
            "IsEditable": policy.get("IsEditable"),
            "VisibleToChildren": policy.get("VisibleToChildren"),
        }
        contents.append(d)
    headers = ["ID", "Name", "DomainID", "IsEditable", "VisibleToChildren"]
    readable_output = tableToMarkdown(
        name=f"IPS Policies List of Domain no.{domain_id}", t=contents, removeNull=True, headers=headers
    )
    return CommandResults(
        readable_output=readable_output,
        outputs_prefix="NSM.IPSPolicies",
        outputs=policies_list,
        raw_response=policies_list,
        outputs_key_field="ID",
    )


def get_ips_policy_details_command(client: Client, args: dict) -> CommandResults:
    """gets the policy details for the specific IPS policy.
    Args:
        client: client - A McAfeeNSM client.
        args: Dict - The function arguments.
    Returns:
        A CommandResult object with The relevant ips policy details.
    """
    policy_id = int(args.get("policy_id", ""))
    response = client.get_ips_policy_details_request(policy_id)
    policy_details = response.get("PolicyDescriptor", {})
    policy_details = {
        "ID": policy_id,
        "Name": policy_details.get("PolicyName"),
        "CreatedTime": policy_details.get("Timestamp"),
        "VisibleToChildren": policy_details.get("IsVisibleToChildren"),
        "Version": policy_details.get("VersionNum"),
        "ExploitAttacks": policy_details.get("AttackCategory", {}).get("ExpolitAttackList"),
        "Description": policy_details.get("Description"),
        "InboundRuleSet": policy_details.get("InboundRuleSet"),
        "OutboundRuleSet": policy_details.get("OutboundRuleSet"),
        "OutboundAttackCategory": policy_details.get("OutboundAttackCategory"),
        "DosPolicy": policy_details.get("DosPolicy"),
        "DosResponseSensitivityLevel": policy_details.get("DosResponseSensitivityLevel"),
        "IsEditable": policy_details.get("IsEditable"),
        "IsLightWeightPolicy": policy_details.get("IsLightWeightPolicy"),
    }
    contents = {
        "ID": policy_details.get("ID"),
        "Name": policy_details.get("Name"),
        "Description": policy_details.get("Description"),
        "CreatedTime": policy_details.get("CreatedTime"),
        "IsEditable": policy_details.get("IsEditable"),
        "VisibleToChildren": policy_details.get("VisibleToChildren"),
        "Version": policy_details.get("Version"),
        "InboundRuleSet": policy_details.get("InboundRuleSet"),
        "OutboundRuleSet": policy_details.get("OutboundRuleSet"),
    }
    headers = [
        "ID",
        "Name",
        "Description",
        "CreatedTime",
        "IsEditable",
        "VisibleToChildren",
        "Version",
        "InboundRuleSet",
        "OutboundRuleSet",
    ]
    readable_output = tableToMarkdown(name=f"IPS Policy no.{policy_id} Details", t=contents, removeNull=True, headers=headers)
    return CommandResults(
        readable_output=readable_output,
        outputs_prefix="NSM.IPSPolicies",
        outputs=policy_details,
        raw_response=policy_details,
        outputs_key_field="ID",
    )


def update_alerts_command(client: Client, args: dict) -> CommandResults:
    """Updates all the relevant alerts.
    Args:
        client: client - A McAfeeNSM client.
        args: Dict - The function arguments.
    Returns:
        A CommandResult object with the list of the changed alerts.
    """
    state = args.get("state", "Any")
    time_period = args.get("time_period", None)
    start_time = args.get("start_time", None)
    end_time = args.get("end_time", None)
    new_state = args.get("new_state", None)
    new_assignee = args.get("new_assignee", None)
    search = args.get("search", None)
    filter_arg = args.get("filter", None)

    if not new_state and not new_assignee:
        raise Exception("Error! You must specify a new alert state or a new assignee")
    if (start_time and not end_time) or (not start_time and end_time):
        raise Exception("If you provide one of the time parameters, you must provide the other as well")
    if start_time and time_period != "CUSTOM":
        time_period = "CUSTOM"

    if filter_arg and "name" in filter_arg:
        filter_arg = update_filter(filter_arg)

    body = {"alertState": new_state, "assignTo": new_assignee}

    response = client.update_alerts_request(time_period, start_time, end_time, state, search, filter_arg, body)

    if response.get("status") != 1:
        raise Exception("Error! Failed to update alerts.")
    return get_alerts_command(client, args)


def list_pcap_file_command(client: Client, args: dict) -> CommandResults:
    """Retrieves the list of captured PCAP files.
    Args:
        client: client - A McAfeeNSM client.
        args: Dict - The function arguments.
    Returns:
        A CommandResult object with a list of captured PCAP files.
    """
    sensor_id = int(args.get("sensor_id", ""))
    limit = arg_to_number(args.get("limit", DEFAULT_LIMIT)) or DEFAULT_LIMIT
    page = arg_to_number(args.get("page"))
    page_size = arg_to_number(args.get("page_size"))
    if (page and not page_size) or (not page and page_size):
        raise Exception("Please provide both page and page_size arguments.")

    response = client.list_pcap_file_request(sensor_id)
    files_list = pagination(response.get("files", []), limit, page, page_size)
    contents = []
    for file_name in files_list:
        d = {"FileName": file_name}
        contents.append(d)
    readable_output = tableToMarkdown(name="PCAP files List", t=contents, removeNull=True)
    return CommandResults(
        readable_output=readable_output, outputs_prefix="NSM.PcapFile", outputs=files_list, raw_response=files_list
    )


def export_pcap_file_command(client: Client, args: dict) -> List:
    """Exports the captured PCAP file.
    Args:
        client: client - A McAfeeNSM client.
        args: Dict - The function arguments.
    Returns:
        A CommandResult object with a list of captured PCAP files.
    """
    sensor_id = int(args.get("sensor_id", ""))
    file_name = args.get("file_name")
    body = {"fileName": file_name}
    response = client.export_pcap_file_request(sensor_id, body)
    file_ = fileResult(filename=file_name, data=response.content, file_type=EntryType.ENTRY_INFO_FILE)
    return [file_]


def list_domain_device_command(client: Client, args: dict) -> CommandResults:
    """
    Retrieves the list of devices related to a given domain.
    Args:
        client(Client): client - A McAfeeNSM client.
        args(Dict): - The function arguments.
    Returns:
        A CommandResult object with a list of domain devices.
    """
    domain_id = arg_to_number(args.get("domain_id"), arg_name="domain_id", required=True)
    domain_id = check_required_arg(arg_name="domain_id", arg_value=domain_id)
    limit = arg_to_number(args.get("limit", DEFAULT_LIMIT))
    all_results = argToBoolean(args.get("all_results", False))

    response = client.list_domain_device_request(domain_id)
    devices: List = response.get("DeviceResponseList", [])

    capitalize_devices = capitalize_key_first_letter(devices) if all_results else capitalize_key_first_letter(devices)[:limit]

    readable_output = tableToMarkdown(name="Domain devices List", t=capitalize_devices, removeNull=True)

    return CommandResults(
        readable_output=readable_output,
        outputs_prefix="NSM.Device",
        outputs=capitalize_devices,
        raw_response=response,
    )


def list_device_interface_command(client: Client, args: dict) -> CommandResults:
    """
    Retrieves the list of interfaces related to a given device.
    Args:
        client(Client): client - A McAfeeNSM client.
        args(Dict): - The function arguments.
    Returns:
        A CommandResult object with a list of device interfaces.
    """
    device_id = arg_to_number(args.get("device_id"), arg_name="device_id", required=True)
    device_id = check_required_arg(arg_name="device_id", arg_value=device_id)
    domain_id = arg_to_number(args.get("domain_id"), arg_name="domain_id", required=True)
    domain_id = check_required_arg(arg_name="domain_id", arg_value=domain_id)
    limit = arg_to_number(args.get("limit", DEFAULT_LIMIT))
    all_results = argToBoolean(args.get("all_results", False))

    response = client.list_device_interface_request(domain_id=domain_id, device_id=device_id)
    interfaces = response.get("allocatedInterfaceList", [])

    key_list = ["interfaceId", "interfaceName", "interfaceType"]
    capitalize_interfaces = (
        capitalize_key_first_letter(interfaces, key_list)
        if all_results
        else capitalize_key_first_letter(interfaces, key_list)[:limit]
    )

    readable_output = tableToMarkdown(name="Device interfaces List", t=capitalize_interfaces, removeNull=True)

    return CommandResults(
        readable_output=readable_output, outputs_prefix="NSM.Interface", outputs=capitalize_interfaces, raw_response=response
    )


def assign_device_policy_command(client: Client, args: dict) -> CommandResults:
    """
    Assigns a policy to a device.
    Args:
        client(Client): client - A McAfeeNSM client.
        args(Dict): - The function arguments.
    Returns:
        A CommandResult object with a success or failure message.
    """
    device_id = arg_to_number(args.get("device_id"), arg_name="device_id", required=True)
    device_id = check_required_arg(arg_name="device_id", arg_value=device_id)
    domain_id = arg_to_number(args.get("domain_id"), arg_name="domain_id", required=True)
    domain_id = check_required_arg(arg_name="domain_id", arg_value=domain_id)
    pre_firewall_policy = args.get("pre_firewall_policy_name")
    post_firewall_policy = args.get("post_firewall_policy_name")

    response = client.assign_device_policy_request(
        domain_id=domain_id,
        device_id=device_id,
        pre_firewall_policy=pre_firewall_policy,
        post_firewall_policy=post_firewall_policy,
    )
    readable_output = "Policy assigned successfully." if response.get("status") == 1 else "Policy assignment failed."
    return CommandResults(readable_output=readable_output, raw_response=response)


def list_device_policy_command(client: Client, args: dict) -> CommandResults:
    """
    Retrieves a list of policies related to the domain or a specific device.
    Args:
        client(Client): client - A McAfeeNSM client.
        args(Dict): - The function arguments.

    Returns:
         A CommandResult object with a list of device policies.
    """
    device_id = arg_to_number(args.get("device_id"))
    domain_id = arg_to_number(args.get("domain_id"), arg_name="domain_id", required=True)
    domain_id = check_required_arg(arg_name="domain_id", arg_value=domain_id)
    limit = arg_to_number(args.get("limit", DEFAULT_LIMIT))
    all_results = argToBoolean(args.get("all_results", False))

    response = client.list_device_policy_request(domain_id=domain_id, device_id=device_id)
    all_policies = response.get("policyAssignmentsList", [])

    capitalize_policies = (
        capitalize_key_first_letter(all_policies) if all_results else capitalize_key_first_letter(all_policies)[:limit]
    )

    readable_output = tableToMarkdown(name="Device policy List", t=capitalize_policies, removeNull=True)

    return CommandResults(
        readable_output=readable_output, outputs_prefix="NSM.DevicePolicy", outputs=capitalize_policies, raw_response=response
    )


def assign_interface_policy_command(client: Client, args: dict) -> CommandResults:
    """
    Assigns an existing policy to an interface.
    Args:
        client(Client): - A McAfeeNSM client.
        args(Dict): - The function arguments.
    Returns:
        A CommandResult object with a success or failure message.
    """
    domain_id = arg_to_number(args.get("domain_id"), arg_name="domain_id", required=True)
    domain_id = check_required_arg(arg_name="domain_id", arg_value=domain_id)
    interface_id = arg_to_number(args.get("interface_id"), arg_name="interface_id", required=True)
    interface_id = check_required_arg(arg_name="interface_id", arg_value=interface_id)
    firewall_policy = args.get("firewall_policy_name")
    firewall_port_policy = args.get("firewall_port_policy_name")
    ips_policy = args.get("ips_policy_name")
    custom_policy_json: str = args.get("custom_policy_json") or ""
    custom_policy_json = json.loads(custom_policy_json) if custom_policy_json else {}

    # Check if at least one policy was provided
    if not firewall_policy and not firewall_port_policy and not ips_policy and not custom_policy_json:
        raise DemistoException("Please provide at least one policy to assign.")

    response = client.assign_interface_policy_request(
        domain_id=domain_id,
        interface_id=interface_id,
        firewall_policy=firewall_policy,
        firewall_port_policy=firewall_port_policy,
        ips_policy=ips_policy,
        custom_policy_json=custom_policy_json,
    )
    readable_output = "Policy assigned successfully." if response.get("status") == 1 else "Policy assignment failed."
    return CommandResults(readable_output=readable_output, raw_response=response)


def list_interface_policy_command(client: Client, args: dict) -> CommandResults:
    """
    Retrieves a list of policies related to the domain or a specific interface.
    Args:
        client (Client):  - A McAfeeNSM client.
        args (Dict): - The function arguments.

    Returns:
        A CommandResult object with a list of policies.
    """
    domain_id = arg_to_number(args.get("domain_id"), arg_name="domain_id", required=True)
    domain_id = check_required_arg(arg_name="domain_id", arg_value=domain_id)
    interface_id = arg_to_number(args.get("interface_id"))
    limit = arg_to_number(args.get("limit", DEFAULT_LIMIT))
    all_results = argToBoolean(args.get("all_results", False))

    response = client.list_interface_policy_request(domain_id=domain_id, interface_id=interface_id)
    all_policies: list = [response] if interface_id else response.get("policyAssignmentsList") or []

    capitalize_policies = (
        capitalize_key_first_letter(all_policies) if all_results else capitalize_key_first_letter(all_policies)[:limit]
    )
    return CommandResults(
        readable_output=tableToMarkdown(name="Interface policy List", t=capitalize_policies, removeNull=True),
        outputs_prefix="NSM.InterfacePolicy",
        outputs=capitalize_policies,
        raw_response=response,
    )


def get_device_configuration_command(client: Client, args: dict) -> CommandResults:
    """
    Retrieves the configuration of a device(e.g pending changes).
    Args:
        client (Client):  - A McAfeeNSM client.
        args (Dict): - The function arguments.

    Returns:
        A CommandResult object with the device configuration information.
    """
    device_id = arg_to_number(args.get("device_id"), arg_name="device_id", required=True)
    device_id = check_required_arg(arg_name="device_id", arg_value=device_id)

    response = client.get_device_configuration_request(device_id=device_id)
    capitalize_response = capitalize_key_first_letter([response])[0]
    flattened_response = flatten_and_capitalize(main_dict=capitalize_response, inner_dict_key="PendingChanges")

    readable_output = tableToMarkdown(name="Device Configuration", t=flattened_response, removeNull=True)

    return CommandResults(
        readable_output=readable_output,
        outputs_prefix="NSM.DeviceConfiguration",
        outputs=flattened_response,
        raw_response=response,
    )


@polling_function(name="nsm-deploy-device-configuration", interval=INTERVAL, requires_polling_arg=False)
def deploy_device_configuration_command(args: dict, client: Client) -> PollResult:
    """
    Deploy the configuration of a device.(e.g activate pending changes).
    Args:
        args (Dict): - The function arguments.
        client (Client): - A McAfeeNSM client.

    Returns:
        A PollResult object with a success or failure message.
    """

    request_id = arg_to_number(args.get("request_id"))
    device_id = arg_to_number(args.get("device_id"), arg_name="device_id", required=True)
    device_id = check_required_arg(arg_name="device_id", arg_value=device_id)

    if not request_id:  # if this is the first time the function is called
        is_ssl_push_required = argToBoolean(args.get("push_ssl_key", False))
        is_gam_update_required = argToBoolean(args.get("push_gam_updates", False))
        is_sigset_config_push_required = argToBoolean(args.get("push_configuration_signature_set", False))
        is_botnet_push_required = argToBoolean(args.get("push_botnet", False))

        if not any([is_ssl_push_required, is_gam_update_required, is_sigset_config_push_required, is_botnet_push_required]):
            raise DemistoException("Please provide at least one argument to deploy.")

        if requests_id := client.deploy_device_configuration_request(
            device_id=device_id,
            is_SSL_Push_Required=is_ssl_push_required,
            is_GAM_Update_Required=is_gam_update_required,
            is_Sigset_Config_Push_Required=is_sigset_config_push_required,
            is_Botnet_Push_Required=is_botnet_push_required,
        ).get("RequestId"):
            args["request_id"] = requests_id

        else:
            raise DemistoException("Failed to deploy the device configuration.")

    status = client.check_deploy_device_configuration_request_status(device_id=device_id, request_id=request_id)

    fail_or_success_list, message_to_return = deploy_polling_message(args=args, status=status)
    message = CommandResults(readable_output=f"{message_to_return}\n\nChecking again in {INTERVAL} seconds...")

    if not all(fail_or_success_list):  # if one of the arguments was not fully deployed yet, the polling will continue
        return PollResult(
            partial_result=message,
            response=None,
            continue_to_poll=True,
            args_for_next_run={"request_id": request_id, "device_id": device_id, **args},
        )

    message = CommandResults(readable_output="The device configuration has been deployed successfully.")
    return PollResult(response=message, continue_to_poll=False)


""" MAIN FUNCTION """


def main() -> None:  # pragma: no cover
    args = demisto.args()
    command = demisto.command()
    params = demisto.params()

    url = f"{params.get('url')}/sdkapi"
    user_name = params.get("credentials", {}).get("identifier", "")
    password = params.get("credentials", {}).get("password", "")
    verify_certificate = not params.get("insecure", False)
    proxy = params.get("proxy", False)
    auth = (user_name, password)

    demisto.debug(f"Command being called is {command}")
    try:
        headers: dict = {"Accept": "application/vnd.nsm.v1.0+json", "Content-Type": "application/json"}

        client = Client(url=url, auth=auth, headers=headers, proxy=proxy, verify=verify_certificate)
        if command != "test-module":
            session_str = get_session(client, f"{user_name}:{password}")
            headers["NSM-SDK-API"] = session_str
            client = Client(url=url, auth=auth, headers=headers, proxy=proxy, verify=verify_certificate)
        results: Union[CommandResults, list[CommandResults], str]
        if command == "test-module":
            # This is the call made when pressing the integration Test button.
            results = test_module(client, f"{user_name}:{password}")
            # return_results(str_results)
        elif command == "nsm-list-domain-firewall-policy":
            results = list_domain_firewall_policy_command(client, args)
        elif command == "nsm-get-firewall-policy":
            results = get_firewall_policy_command(client, args)
        elif command == "nsm-create-firewall-policy":
            results = create_firewall_policy_command(client, args)
        elif command == "nsm-update-firewall-policy":
            results = update_firewall_policy_command(client, args)
        elif command == "nsm-delete-firewall-policy":
            results = delete_firewall_policy_command(client, args)
        elif command == "nsm-list-domain-rule-object":
            results = list_domain_rule_objects_command(client, args)
        elif command == "nsm-get-rule-object":
            results = get_rule_object_command(client, args)
        elif command == "nsm-create-rule-object":
            results = create_rule_object_command(client, args)
        elif command == "nsm-update-rule-object":
            results = update_rule_object_command(client, args)
        elif command == "nsm-delete-rule-object":
            results = delete_rule_object_command(client, args)
        elif command == "nsm-get-alerts":
            results = get_alerts_command(client, args)
        elif command == "nsm-get-alert-details":
            results = get_alert_details_command(client, args)
        elif command == "nsm-get-attacks":
            results = get_attacks_command(client, args)
        elif command == "nsm-get-domains":
            results = get_domains_command(client, args)
        elif command == "nsm-get-sensors":
            results = get_sensors_command(client, args)
        elif command == "nsm-get-ips-policies":
            results = get_ips_policies_command(client, args)
        elif command == "nsm-get-ips-policy-details":
            results = get_ips_policy_details_command(client, args)
        elif command == "nsm-update-alerts":
            results = update_alerts_command(client, args)
        elif command == "nsm-list-pcap-file":
            results = list_pcap_file_command(client, args)
        elif command == "nsm-export-pcap-file":
            results = export_pcap_file_command(client, args)
        elif command == "nsm-list-device-interface":
            results = list_device_interface_command(client, args)
        elif command == "nsm-list-domain-device":
            results = list_domain_device_command(client, args)
        elif command == "nsm-assign-device-policy":
            results = assign_device_policy_command(client, args)
        elif command == "nsm-list-device-policy":
            results = list_device_policy_command(client, args)
        elif command == "nsm-assign-interface-policy":
            results = assign_interface_policy_command(client, args)
        elif command == "nsm-list-interface-policy":
            results = list_interface_policy_command(client, args)
        elif command == "nsm-get-device-configuration":
            results = get_device_configuration_command(client, args)
        elif command == "nsm-deploy-device-configuration":
            results = deploy_device_configuration_command(args, client)
        else:
            raise NotImplementedError("This command is not implemented yet.")
        return_results(results)

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


""" ENTRY POINT """

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