Forcepoint Security Management Center

Forcepoint SMC provides unified, centralized management of all models of Forcepoint engines whether physical, virtual or cloud—across large, geographically distributed enterprise environments.

Network Security · Forcepoint Security Management Center

Details

IDForcepoint Security Management Center
ProviderFrancisco Partners
CategoryNetwork Security
From Version6.8.0
Docker Imagedemisto/vendors-sdk:1.0.0.10120494
Supported ModulesAgentix XSIAM

README

Forcepoint SMC provides unified, centralized management of all models of Forcepoint engines whether physical, virtual or cloud—across large, geographically distributed enterprise environments.
This integration was integrated and tested with version 6.10 of Forcepoint Security Management Center

Configure Forcepoint Security Management Center in Cortex

Parameter Description Required
Server URL   True
API Key The API Key to use for connection True
Port   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.

forcepoint-smc-ip-list-create


Creates an IP list.

Base Command

forcepoint-smc-ip-list-create

Input

Argument Name Description Required
name The name of the IP list to create. Required
addresses A comma-separated list of IP addresses. Optional
comment The comment to add to the IP List. Optional

Context Output

Path Type Description
ForcepointSMC.IPList.Name String The name of the IP list.
ForcepointSMC.IPList.Addresses Unknown The list of addresses in the IP list.
ForcepointSMC.IPList.Comment String The comment for the IP list.

Command example

!forcepoint-smc-ip-list-create name="name" addresses="1.1.1.1" comment="test"

Context Example

{
    "ForcepointSMC": {
        "IPList": {
            "Addresses": [
                "1.1.1.1"
            ],
            "Comment": "test",
            "Name": "name"
        }
    }
}

Human Readable Output

IP List name was created successfully.

forcepoint-smc-ip-list-update


Updates an IP list.

Base Command

forcepoint-smc-ip-list-update

Input

Argument Name Description Required
name The name of the IP list. Required
addresses A comma-separated list of addresses to update. Optional
is_override If false, the list of addresses will be appended to the existing one. Else, the list will be overwritten. Default is False. Possible values are: False, True. Optional

Context Output

Path Type Description
ForcepointSMC.IPList.Name String The name of the IP list.
ForcepointSMC.IPList.Addresses Unknown The list of addresses in the IPList
ForcepointSMC.IPList.Comment String The comment for the IP list.

Command example

!forcepoint-smc-ip-list-update name="name" addresses="1.2.3.4" comment="test" is_override=True

Context Example

{
    "ForcepointSMC": {
        "IPList": {
            "Addresses": [
                "1.2.3.4"
            ],
            "Comment": "test",
            "Name": "name"
        }
    }
}

Human Readable Output

IP List name was updated successfully.

forcepoint-smc-ip-list-list


Lists the IP Lists in the system.

Base Command

forcepoint-smc-ip-list-list

Input

Argument Name Description Required
name The name of a specific IP list to fetch. Overrides the other arguments if used. Optional
limit The maximum number of IP lists to return. Default value is 50. Optional
all_results Whether to return all of the results or not. Default value is False. Optional

Context Output

Path Type Description
ForcepointSMC.IPList.Name String The name of the IP list.
ForcepointSMC.IPList.Addresses Unknown The list of addresses in the IP list.
ForcepointSMC.IPList.Comment String The comment of the IPList

Command example

!forcepoint-smc-ip-list-list name="name"

Context Example

{
    "ForcepointSMC": {
        "IPList": {
            "Addresses": [
                "1.2.3.4"
            ],
            "Comment": "test",
            "Name": "name"
        }
    }
}

Human Readable Output

IP Lists

Name Addresses Comment
name 1.2.3.4 test

forcepoint-smc-ip-list-delete


Deletes an IP list.

Base Command

forcepoint-smc-ip-list-delete

Input

Argument Name Description Required
name The name of the IP list to delete. Required

Context Output

Path Type Description
ForcepointSMC.IPList.Name String The name of the IP list.
ForcepointSMC.IPList.Deleted Boolean Whether the IP list was deleted.

Command example

!forcepoint-smc-ip-list-delete name="name"

Context Example

{
    "ForcepointSMC": {
        "IPList": {
            "Deleted": true,
            "Name": "name"
        }
    }
}

Human Readable Output

IP List name was deleted successfully.

forcepoint-smc-host-list


Lists the hosts in the system.

Base Command

forcepoint-smc-host-list

Input

Argument Name Description Required
name The name of a specific host to fetch. Optional
limit The maximum number of hosts to return. Default value is 50. Optional
all_results Whether to return all of the results. Overrides the other arguments if used. Default value is False. Optional

Context Output

Path Type Description
ForcepointSMC.Host.Name String The name of the host.
ForcepointSMC.Host.Address String The address of the host.
ForcepointSMC.Host.IPv6_address String The IPv6 address of the host.
ForcepointSMC.Host.Secondary_address String The secondary address of the host.
ForcepointSMC.Host.Comment String The comment for the host.

Command example

!forcepoint-smc-host-list name="name"

Context Example

{
    "ForcepointSMC": {
        "Host": {
            "Address": "1.1.1.1",
            "Comment": null,
            "IPv6_address": "",
            "Name": "name",
            "Secondary_address": []
        }
    }
}

Human Readable Output

Hosts

Name Address
name 1.1.1.1

forcepoint-smc-host-create


Creates a new host.

Base Command

forcepoint-smc-host-create

Input

Argument Name Description Required
name The name of a specific host to fetch. Required
address The address of the host. Cannot be combined with the ipv6_address argument. Optional
ipv6_address The IPv6 address of the host. Cannot be combined with the address argument. Optional
secondary_address A comma-separated list of secondary addresses of the host. Optional
comment The comment to add to the host. Optional

Context Output

Path Type Description
ForcepointSMC.Host.Name String The name of the host.
ForcepointSMC.Host.Address String The address of the host.
ForcepointSMC.Host.IPv6_address String The IPv6 address of the host.
ForcepointSMC.Host.Secondary_address Unknown The secondary address of the host.
ForcepointSMC.Host.Comment String The comment for the host.

Command example

!forcepoint-smc-host-create name="name" address="1.1.1.1"

Context Example

{
    "ForcepointSMC": {
        "Host": {
            "Address": "1.1.1.1",
            "Comment": "",
            "IPv6_address": "",
            "Name": "name",
            "Secondary_address": []
        }
    }
}

Human Readable Output

Host name was created successfully.

forcepoint-smc-host-update


Updates a host.

Base Command

forcepoint-smc-host-update

Input

Argument Name Description Required
name The name of the host to update. Required
address The address of the host. Cannot be combined with the ipv6_address argument. Optional
ipv6_address The IPv6 address of the host. Cannot be combined with the address argument. Optional
secondary_address comma-separated list of secondary addresses of the host. Optional
comment The comment to add to the host. Optional

Context Output

Path Type Description
ForcepointSMC.Host.Name String The name of the host.
ForcepointSMC.Host.Address String The address of the host.
ForcepointSMC.Host.IPv6_address String The IPv6 address of the host.
ForcepointSMC.Host.Secondary_address String The secondary address of the host.
ForcepointSMC.Host.Comment String The comment for the host.

Command example

!forcepoint-smc-host-update name="name" address="1.2.3.4"

Context Example

{
    "ForcepointSMC": {
        "Host": {
            "Address": "1.2.3.4",
            "Comment": null,
            "IPv6_address": "",
            "Name": "name",
            "Secondary_address": []
        }
    }
}

Human Readable Output

Host name was updated successfully.

forcepoint-smc-host-delete


Deletes a host.

Base Command

forcepoint-smc-host-delete

Input

Argument Name Description Required
name The name of the host to delete. Required

Context Output

Path Type Description
ForcepointSMC.Host.Name String The name of the host.
ForcepointSMC.Host.Deleted Boolean Whether the host was deleted.

Command example

!forcepoint-smc-host-delete name="name"

Context Example

{
    "ForcepointSMC": {
        "Host": {
            "Deleted": true,
            "Name": "name"
        }
    }
}

Human Readable Output

Host name was deleted successfully.

forcepoint-smc-domain-create


Creates a new domain.

Base Command

forcepoint-smc-domain-create

Input

Argument Name Description Required
name The name of the domain to create. Required
comment The comment to add to the domain. Optional

Context Output

Path Type Description
ForcepointSMC.Domain.Name String The name of the host.
ForcepointSMC.Domain.Comment String The comment of the host.

Command example

!forcepoint-smc-domain-create name="name"

Context Example

{
    "ForcepointSMC": {
        "Domain": {
            "Comment": "",
            "Name": "name"
        }
    }
}

Human Readable Output

Domain name was created successfully.

forcepoint-smc-domain-list


Lists the domains in the system.

Base Command

forcepoint-smc-domain-list

Input

Argument Name Description Required
name The name of a specific domain to fetch. Optional
limit The maximum number of hosts to return. Default value is 50. Optional
all_results Whether to return all of the results. Overrides the other arguments if used. Default value is False. Optional

Context Output

Path Type Description
ForcepointSMC.Domain.Name String The name of the domain.
ForcepointSMC.Domain.Comment String The comment for the domain.

Command example

!forcepoint-smc-domain-list name="name"

Context Example

{
    "ForcepointSMC": {
        "Domain": {
            "Comment": null,
            "Name": "name"
        }
    }
}

Human Readable Output

Domains

Name
name

forcepoint-smc-domain-delete


Deletes a domain.

Base Command

forcepoint-smc-domain-delete

Input

Argument Name Description Required
name The name of the domain to delete. Required

Context Output

Path Type Description
ForcepointSMC.Domain.Name String The name of the domain.
ForcepointSMC.Domain.Deleted Boolean Whether the domain was deleted.

Command example

!forcepoint-smc-domain-delete name="name"

Context Example

{
    "ForcepointSMC": {
        "Domain": {
            "Deleted": true,
            "Name": "name"
        }
    }
}

Human Readable Output

Domain name was deleted successfully.

forcepoint-smc-policy-template-list


Lists the policy templates in the system.

Base Command

forcepoint-smc-policy-template-list

Input

Argument Name Description Required
limit The maximum number of policy templates to return. Default value is 50. Optional
all_results Whether to return all of the results. Overrides the other arguments if used. Default value is False. Optional

Context Output

Path Type Description
ForcepointSMC.PolicyTemplate.Name String The name of the firewall policy template.
ForcepointSMC.PolicyTemplate.Comment String The comment for the firewall policy.

Command example

!forcepoint-smc-policy-template-list limit=1

Context Example

{
    "ForcepointSMC": {
        "PolicyTemplate": {
            "Comment": "Firewall Template Policy that uses Inspection rules from the No Inspection Policy.",
            "Name": "Firewall Template"
        }
    }
}

Human Readable Output

Policy template

Name Comment
Firewall Template Firewall Template Policy that uses Inspection rules from the No Inspection Policy.

forcepoint-smc-firewall-policy-list


Lists the firewall policies in the system.

Base Command

forcepoint-smc-firewall-policy-list

Input

Argument Name Description Required
limit The maximum number of firewall policies to return. Default value is 50. Optional
all_results Whether to return all of the results. Overrides the other arguments if used. Default value is False. Optional

Context Output

Path Type Description
ForcepointSMC.Policy.Name String The name of the firewall policy.
ForcepointSMC.Policy.Comment String The comment for the firewall policy.

Command example

!forcepoint-smc-firewall-policy-list limit=1

Context Example

{
    "ForcepointSMC": {
        "FirewallPolicy": {
            "Comment": null,
            "Name": "Policy For May To Test PC"
        }
    }
}

Human Readable Output

Firewall policies

Name
Policy For May To Test PC

forcepoint-smc-firewall-policy-create


Creates a firewall policy.

Base Command

forcepoint-smc-firewall-policy-create

Input

Argument Name Description Required
name The name of the firewall policy. Required
template The template name to use to create the firewall policy. Run the forcepoint-smc-policy-template-list command to get the list of policy templates. Required

Context Output

Path Type Description
ForcepointSMC.Policy.Name String The name of the firewall policy.
ForcepointSMC.Policy.Comment String The comment for the firewall policy.

Command example

!forcepoint-smc-firewall-policy-create name="name" template="Firewall Template"

Context Example

{
    "ForcepointSMC": {
        "Policy": {
            "Comment": null,
            "Name": "name"
        }
    }
}

Human Readable Output

Firewall policy name was created successfully.

forcepoint-smc-firewall-policy-delete


Deletes a firewall policy.

Base Command

forcepoint-smc-firewall-policy-delete

Input

Argument Name Description Required
name The name of the policy to delete. Required

Context Output

Path Type Description
ForcepointSMC.Policy.Name String The name of the firewall policy.
ForcepointSMC.Policy.Deleted Boolean Whether the policy was deleted.

Command example

!forcepoint-smc-firewall-policy-delete name="name"

Context Example

{
    "ForcepointSMC": {
        "Policy": {
            "Deleted": true,
            "Name": "name"
        }
    }
}

Human Readable Output

Firewall policy name was deleted successfully.

forcepoint-smc-rule-create


Creates a rule.

Base Command

forcepoint-smc-rule-create

Input

Argument Name Description Required
policy_name The name of the firewall policy. Required
rule_name The name of the rule to create. Required
ip_version The ip_version of the rule. Possible values are: V4, V6. Required
source_ip_list A comma-separated list of source ip-list names to use to create the rule. Run the forcepoint-ip-list-list command to get the list of ip lists. Optional
source_host A comma-separated list of source host names to use to create the rule. Run the forcepoint-host-list command to get the list of hosts. Optional
source_domain A comma-separated list of source domain names to use to create the rule. Run the forcepoint-domain-list command to get the list of domains. Optional
destination_ip_list A comma-separated list of destination ip-list names to use to create the rule. Run the forcepoint-ip-list-list command to get the list of ip lists. Optional
destination_host A comma-separated list of destination host names to use to create the rule. Run the forcepoint-host-list command to get the list of hosts. Optional
destination_domain A comma-separated list of destination domain names to use to create the rule. Run the forcepoint-domain-list command to get the list of domains. Optional
action The action of the rule. Possible values are: allow, continue, discard, refuse, enforce_vpn, apply_vpn, forward_vpn, blacklist, forced_next_hop. Required
comment The comment to add to the rule. Optional

Context Output

Path Type Description
ForcepointSMC.Rule.Name String The name of the rule.
ForcepointSMC.Rule.ID String The ID of the rule.
ForcepointSMC.Rule.IP_version String The IP version of the rule.
ForcepointSMC.Rule.Action String The action of the rule.
ForcepointSMC.Rule.Comment String The comment for the rule.

Command example

!forcepoint-smc-rule-create policy_name="name" action=allow rule_name="test" destination_ip_list="test" ip_version="V4"

Context Example

{
    "ForcepointSMC": {
        "Rule": {
            "Action": [
                "allow"
            ],
            "Comment": "",
            "Destinations": [
                "test"
            ],
            "ID": "2097186.0",
            "IP_version": "V4",
            "Name": "test",
            "Services": [],
            "Sources": []
        }
    }
}

Human Readable Output

The rule test to the policy name was created successfully.

forcepoint-smc-rule-update


Updates a rule.

Base Command

forcepoint-smc-rule-update

Input

Argument Name Description Required
policy_name The name of the firewall policy. Required
rule_name The name of the rule to update. Required
is_override Whether to override the existing values. Default value is False. Possible values are: False, True. Optional
ip_version The ip_version of the rule. Possible values are: V4, V6. Required
source_ip_list A comma-separated list of source ip-list names to use to update the rule. Run the forcepoint-ip-list-list command to get the list of ip lists. Optional
source_host A comma-separated list of source host names to use to update the rule. Run the forcepoint-host-list command to get the list of hosts. Optional
source_domain A comma-separated list of source domain names to use to update the rule. Run the forcepoint-domain-list command to get the list of domains. Optional
destination_ip_list A comma-separated list of destination ip-list names to use to update the rule. Run the forcepoint-ip-list-list command to get the list of ip lists. Optional
destination_host A comma-separated list of destination host names to use to update the rule. Run the forcepoint-host-list command to get the list of hosts. Optional
destination_domain A comma-separated list of destination domain names to use to update the rule. Run the forcepoint-domain-list command to get the list of domains. Optional
action The action of the rule. Possible values are: allow, continue, discard, refuse, enforce_vpn, apply_vpn, forward_vpn, blacklist, forced_next_hop. Optional
comment The comment to add to the rule. Optional

Context Output

There is no context output for this command.

Command example

!forcepoint-smc-rule-update policy_name="name" action=continue rule_name="test" source_ip_list="test" ip_version="V4"

Human Readable Output

The rule test to the policy name was updated successfully.

forcepoint-smc-rule-list


Lists the rules in a specific policy.

Base Command

forcepoint-smc-rule-list

Input

Argument Name Description Required
policy_name The name of the firewall policy. Required

Context Output

Path Type Description
ForcepointSMC.Rule.Name String The name of the rule.
ForcepointSMC.Rule.ID String The ID of the rule.
ForcepointSMC.Rule.IP_version String The IP version of the rule.
ForcepointSMC.Rule.Sources Unknown The sources of the rule.
ForcepointSMC.Rule.Destinations Unknown The destinations of the rule.
ForcepointSMC.Rule.Services Unknown The services of the rule.
ForcepointSMC.Rule.Actions Unknown The actions of the rule.
ForcepointSMC.Rule.Comment String The comment of the rule.

Command example

!forcepoint-smc-rule-list policy_name="name"

Context Example

{
    "ForcepointSMC": {
        "Rule": {
            "Actions": [
                "continue"
            ],
            "Comment": "",
            "Destinations": [
                "test"
            ],
            "ID": "2097186.1",
            "IP_version": "V4",
            "Name": "test",
            "Services": [],
            "Sources": [
                "test"
            ]
        }
    }
}

Human Readable Output

Rules

Name ID IP_version Sources Destinations Actions
test 2097186.1 V4 test test continue

forcepoint-smc-rule-delete


Deletes a rule.

Base Command

forcepoint-smc-rule-delete

Input

Argument Name Description Required
policy_name The name of the firewall policy. Required
rule_name The name of the rule to delete. Required
ip_version The ip_version of the rule. Possible values are: V4, V6. Required

Context Output

Path Type Description
ForcepointSMC.Rule.ID String The ID of the rule.
ForcepointSMC.Rule.Deleted Boolean Whether the rule was deleted.

Command example

!forcepoint-smc-rule-delete policy_name="name" rule_name="test" ip_version=V4

Context Example

{
    "ForcepointSMC": {
        "Rule": {
            "Deleted": true,
            "Name": "test"
        }
    }
}

Human Readable Output

Rule test was deleted successfully.

forcepoint-smc-engine-list


Lists the engines in the system.

Base Command

forcepoint-smc-engine-list

Input

Argument Name Description Required
limit The maximum number of engines to return. Default value is 50. Optional
all_results Whether to return all of the results or not, overrides the other arguments if used. Default value is False. Optional

Context Output

Path Type Description
ForcepointSMC.Engine.Name String The name of the engine.
ForcepointSMC.Engine.Comment String The comment for the engine.

Command example

!forcepoint-smc-engine-list limit=1

Context Example

{
    "ForcepointSMC": {
        "Engine": {
            "Comment": "Forcepoint Engine element pre-populated by installer",
            "Name": "Forcepoint Engine"
        }
    }
}

Human Readable Output

Engines

Name Comment
Forcepoint Engine Forcepoint Engine element pre-populated by installer

forcepoint-smc-engine-refresh


Refreshes the specified engines. Use the forcepoint-smc-engine-list command to list the engines in the system.

Base Command

forcepoint-smc-engine-refresh

Input

Argument Name Description Required
engine_name A comma-separated list of engine names to refresh. Required
interval_in_seconds The interval in seconds between polling attempts. To prevent search timeouts, set this value within the 60-90 second range. Default is 60. Optional
timeout_in_seconds The timeout for polling in seconds. Default is 600. Optional

Context Output

There is no context output for this command.

Configuration parameters

  • url — Server URL (required)
  • credentials — (required)
  • port — Port (required)
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (21)

  • forcepoint-smc-domain-create

    Creates a new domain.

  • forcepoint-smc-domain-delete

    Deletes a domain.

  • forcepoint-smc-domain-list

    Lists the domains in the system.

  • forcepoint-smc-engine-list

    Lists the engines in the system.

  • forcepoint-smc-engine-refresh

    Refreshes the specified engines. Use the forcepoint-smc-engine-list command to list the engines in the system.

  • forcepoint-smc-firewall-policy-create

    Creates a firewall policy.

  • forcepoint-smc-firewall-policy-delete

    Deletes a firewall policy.

  • forcepoint-smc-firewall-policy-list

    Lists the firewall policies in the system.

  • forcepoint-smc-host-create

    Creates a new host.

  • forcepoint-smc-host-delete

    Deletes a host.

  • forcepoint-smc-host-list

    Lists the hosts in the system.

  • forcepoint-smc-host-update

    Updates a host.

  • forcepoint-smc-ip-list-create

    Creates an IP list.

  • forcepoint-smc-ip-list-delete

    Deletes an IP list.

  • forcepoint-smc-ip-list-list

    Lists the IP Lists in the system.

  • forcepoint-smc-ip-list-update

    Updates an IP list.

  • forcepoint-smc-policy-template-list

    Lists the policy templates in the system.

  • forcepoint-smc-rule-create

    Creates a rule.

  • forcepoint-smc-rule-delete

    Deletes a rule.

  • forcepoint-smc-rule-list

    Lists the rules in a specific policy.

  • forcepoint-smc-rule-update

    Updates a rule.

import pytest
from ForcepointSecurityManagementCenter import (
    create_iplist_command,
    update_iplist_command,
    list_iplist_command,
    delete_iplist_command,
    create_host_command,
    list_host_command,
    delete_host_command,
    update_host_command,
    create_domain_command,
    list_domain_command,
    delete_domain_command,
    list_policy_template_command,
    list_firewall_policy_command,
    create_firewall_policy_command,
    delete_firewall_policy_command,
    update_rule_command,
    list_engine_command,
    list_rule_command,
    delete_rule_command,
    create_rule_command,
    engine_refresh_command,
    IPList,
    Host,
    DomainName,
    FirewallPolicy,
    DemistoException,
)
from smc.api.exceptions import ElementNotFound, TaskRunFailed
from smc.base.collection import CollectionManager


class mock_Rule:
    def __init__(self):
        self.name = "name"
        self.tag = "tag"
        self.sources = mock_GenericRuleEntity()
        self.destinations = mock_GenericRuleEntity()
        self.action = mock_GenericRuleEntity()
        self.services = mock_GenericRuleEntity()
        self.comment = "comment"

    def all(self):
        return [self]

    def create(self, name, sources, destinations, action, comment):
        return self

    def update(self, **kwargs):
        return self

    def save(
        self,
    ):
        return self


class mock_IPList:
    def __init__(self, name: str, iplist: list, comment: str):
        self.name = name
        self.iplist = iplist
        self.comment = comment


class mock_Host:
    def __init__(self, name: str, address: str, ipv6_address: str, secondary: str, comment: str):
        self.name = name
        self.address = address
        self.ipv6_address = ipv6_address
        self.secondary = secondary
        self.comment = comment


class mock_Domain:
    def __init__(self, name: str, comment: str):
        self.name = name
        self.comment = comment


class mock_FirewallRule:
    def __init__(self):
        self.fw_ipv4_access_rules = mock_Rule()
        self.fw_ipv6_access_rules = mock_Rule()


class mock_GenericRuleEntity:
    def __init__(self):
        self.name = "name"
        self.action = "ALLOW"

    def all(self):
        return [self]

    def filter(self):
        return self

    def add_many(self, elements):
        return self


class mock_Policy:
    def __init__(self, name: str, comment: str):
        self.name = name
        self.comment = comment
        self.fw_ipv4_access_rules = mock_Rule()
        self.fw_ipv6_access_rules = mock_Rule()

    def open(self):
        return

    def save(self):
        return


class mock_Task:
    def __init__(self, href: str, in_progress: bool = True):
        self.href = href
        self.in_progress = in_progress

    def update_status(self):
        return self


class mock_Poller:
    def __init__(self, task: mock_Task):
        self.task = task


class mock_Engine:
    def __init__(self, name: str, comment: str = ""):
        self.name = name
        self.comment = comment
        self.pending_changes = mock_Changes()

    def objects(self):
        return mock_GenericRuleEntity()

    def refresh(self):
        return mock_Poller(mock_Task(href=self.name))


class mock_Changes:
    def __init__(self):
        self.element_name = "element_name"
        self.modifier = "modifier"
        self.changed_on = "changed_on"

    def all(self):
        return self

    def approve_all(self):
        return


def test_create_iplist_command(mocker):
    """
    Given:
        - demisto args
    When:
        - Calling function create_address_command
    Then:
        - Ensure the results holds the expected data
    """

    args = {"name": "name", "addresses": "1.1.1.1,8.8.8.8", "comment": "comment"}
    mocker.patch.object(IPList, "create", return_value=mock_IPList(name="name", iplist=["1.1.1.1", "8.8.8.8"], comment="comment"))
    response = create_iplist_command(args)

    assert response.readable_output == "IP List name was created successfully."
    assert response.outputs.get("Name") == "name"


@pytest.mark.parametrize("is_override,returned_iplist", [(True, ["1.2.3.4"]), (False, ["1.1.1.1", "1.2.3.4"])])
def test_update_iplist_command(mocker, is_override, returned_iplist):
    """
    Given:
        - demisto args
        Case 1: overwriting the existing ip list
        Case 2: appending to the existing list
    When:
        - Calling function update_address_command
    Then:
        - Ensure the results holds the expected data
    """

    args = {"name": "name", "addresses": "1.2.3.4", "is_override": is_override}
    ip_list = mock_IPList(name="name", iplist=returned_iplist, comment="new_comment")
    mocker.patch.object(CollectionManager, "filter", return_value=[ip_list])
    mocker.patch.object(IPList, "update_or_create", return_value=ip_list)
    response = update_iplist_command(args)

    assert response.readable_output == "IP List name was updated successfully."
    assert response.outputs.get("Addresses") == returned_iplist


@pytest.mark.parametrize("args,returned_results", [({"name": "name"}, 1), ({"limit": "2"}, 2), ({"all_results": "True"}, 3)])
def test_list_iplist_command(mocker, args, returned_results):
    """
    Given:
        - demisto args:
        Case 1: stating a specific IPList name
        Case 2: getting 2 results
        Case 3: getting all of the results (3 results)
    When:
        - Calling function list_address_command
    Then:
        - Ensure the results holds the expected data and the correct number of results
    """

    ip_list = mock_IPList(name="name", iplist=["1.1.1.1"], comment="new_comment")
    mocker.patch.object(CollectionManager, "filter", return_value=[ip_list])
    mocker.patch.object(CollectionManager, "limit", return_value=[ip_list, ip_list])
    mocker.patch.object(CollectionManager, "all", return_value=[ip_list, ip_list, ip_list])
    response = list_iplist_command(args)

    assert "IP Lists" in response.readable_output
    assert len(response.outputs) == returned_results


def mock_delete():
    raise ElementNotFound


def test_delete_address_command(mocker):
    """
    Given:
        - demisto args
    When:
        - Calling function delete_address_command
    Then:
        - Ensure the results holds the expected data in case of an ElementNotFound exception
    """

    mocker.patch.object(IPList, "delete", side_effect=mock_delete)
    response = delete_iplist_command({"name": "name"})

    assert response.readable_output == "IP List name was not found."


def test_create_host_command(mocker):
    """
    Given:
        - demisto args
    When:
        - Calling function create_host_command
    Then:
        - Ensure the results holds the expected data
    """

    args = {"name": "name", "address": "1.1.1.1", "comment": "comment"}
    mocker.patch.object(
        Host, "create", return_value=mock_Host(name="name", address="1.1.1.1", ipv6_address="", secondary="", comment="comment")
    )
    response = create_host_command(args)

    assert response.readable_output == "Host name was created successfully."
    assert response.outputs.get("Name") == "name"


@pytest.mark.parametrize("args,returned_results", [({"name": "name"}, 1), ({"limit": "2"}, 2), ({"all_results": "True"}, 3)])
def test_list_host_command(mocker, args, returned_results):
    """
    Given:
        - demisto args:
        Case 1: stating a specific IPList name
        Case 2: getting 2 results
        Case 3: getting all of the results (3 results)
    When:
        - Calling function list_host_command
    Then:
        - Ensure the results holds the expected data and the correct number of results
    """

    host = mock_Host(name="name", address="1.1.1.1", ipv6_address="", secondary="", comment="comment")
    mocker.patch.object(CollectionManager, "filter", return_value=[host])
    mocker.patch.object(CollectionManager, "limit", return_value=[host, host])
    mocker.patch.object(CollectionManager, "all", return_value=[host, host, host])
    response = list_host_command(args)

    assert "Hosts:" in response.readable_output
    assert len(response.outputs) == returned_results


@pytest.mark.parametrize("is_override,returned_host", [(True, ["1.2.3.4"]), (False, ["1.1.1.1", "1.2.3.4"])])
def test_update_host_command(mocker, is_override, returned_host):
    """
    Given:
        - demisto args
        Case 1: overwriting the existing host
        Case 2: appending to the existing host
    When:
        - Calling function update_host_command
    Then:
        - Ensure the results holds the expected data
    """

    args = {"name": "name", "address": "1.2.3.4", "comment": "new_comment", "is_override": is_override}
    host = mock_Host(name="name", address="1.1.1.1", ipv6_address="", secondary=returned_host, comment="comment")
    mocker.patch.object(CollectionManager, "filter", return_value=[host])
    mocker.patch.object(Host, "update_or_create", return_value=host)
    response = update_host_command(args)

    assert response.readable_output == "Host name was updated successfully."
    assert response.outputs.get("Secondary_address") == returned_host


def mock_return_error(error_str: str):
    raise Exception(error_str)


def test_update_host_with_host_not_found(mocker):
    """
    Given:
        - name of host
    When:
        - Calling function update_host_command
    Then:
        - Ensure the exception is raised with the correct data when a host to update was not found
    """
    args = {
        "name": "name",
    }
    mocker.patch("ForcepointSecurityManagementCenter.return_error", side_effect=mock_return_error)
    with pytest.raises(Exception) as e:
        mocker.patch.object(CollectionManager, "filter", return_value=[])
        update_host_command(args)
        assert str(e) == "Host name was not found"


def test_update_iplist_with_iplist_not_found(mocker):
    """
    Given:
        - name of host
    When:
        - Calling function update_host_command
    Then:
        - Ensure the exception is raised with the correct data when a host to update was not found
    """
    args = {
        "name": "name",
    }
    mocker.patch("ForcepointSecurityManagementCenter.return_error", side_effect=mock_return_error)
    with pytest.raises(Exception) as e:
        mocker.patch.object(CollectionManager, "filter", return_value=[])
        update_iplist_command(args)
        assert str(e) == "IP List name was not found"


def test_delete_host_command(mocker):
    """
    Given:
        - demisto args
    When:
        - Calling function delete_host_command
    Then:
        - Ensure the results holds the expected data in case of an ElementNotFound exception
    """

    mocker.patch.object(Host, "delete", side_effect=mock_delete)
    response = delete_host_command({"name": "name"})

    assert response.readable_output == "Host name was not found."


def test_create_domain_command(mocker):
    """
    Given:
        - demisto args
    When:
        - Calling function create_domain_command
    Then:
        - Ensure the results holds the expected data
    """

    args = {"name": "name", "comment": "comment"}
    mocker.patch.object(DomainName, "create", return_value=mock_Domain(name="name", comment="comment"))
    response = create_domain_command(args)

    assert response.readable_output == "Domain name was created successfully."
    assert response.outputs.get("Name") == "name"


@pytest.mark.parametrize("args,returned_results", [({"name": "name"}, 1), ({"limit": "2"}, 2), ({"all_results": "True"}, 3)])
def test_list_domain_command(mocker, args, returned_results):
    """
    Given:
        - demisto args:
        Case 1: stating a specific Domain name
        Case 2: getting 2 results
        Case 3: getting all of the results (3 results)
    When:
        - Calling function list_domain_command
    Then:
        - Ensure the results holds the expected data and the correct number of results
    """

    domain = mock_Domain(name="name", comment="comment")
    mocker.patch.object(CollectionManager, "filter", return_value=[domain])
    mocker.patch.object(CollectionManager, "limit", return_value=[domain, domain])
    mocker.patch.object(CollectionManager, "all", return_value=[domain, domain, domain])
    response = list_domain_command(args)

    assert "Domains:" in response.readable_output
    assert len(response.outputs) == returned_results


def test_delete_domain_command(mocker):
    """
    Given:
        - demisto args
    When:
        - Calling function delete_domain_command
    Then:
        - Ensure the results holds the expected data in case of an ElementNotFound exception
    """

    mocker.patch.object(DomainName, "delete", side_effect=mock_delete)
    response = delete_domain_command({"name": "name"})

    assert response.readable_output == "Domain name was not found."


@pytest.mark.parametrize("args,returned_results", [({"limit": "2"}, 2), ({"all_results": "True"}, 3)])
def test_list_policy_template_command(mocker, args, returned_results):
    """
    Given:
        - demisto args:
        Case 1: stating a specific Domain name
        Case 2: getting 2 results
        Case 3: getting all of the results (3 results)
    When:
        - Calling function list_domain_command
    Then:
        - Ensure the results holds the expected data and the correct number of results
    """

    policy = mock_Policy(name="name", comment="comment")
    mocker.patch.object(CollectionManager, "limit", return_value=[policy, policy])
    mocker.patch.object(CollectionManager, "all", return_value=[policy, policy, policy])
    response = list_policy_template_command(args)

    assert "Policy template:" in response.readable_output
    assert len(response.outputs) == returned_results


@pytest.mark.parametrize("args,returned_results", [({"limit": "2"}, 2), ({"all_results": "True"}, 3)])
def test_list_firewall_policy_command(mocker, args, returned_results):
    """
    Given:
        - demisto args:
        Case 1: stating a specific Domain name
        Case 2: getting 2 results
        Case 3: getting all of the results (3 results)
    When:
        - Calling function list_domain_command
    Then:
        - Ensure the results holds the expected data and the correct number of results
    """

    policy = mock_Policy(name="name", comment="comment")
    mocker.patch.object(CollectionManager, "limit", return_value=[policy, policy])
    mocker.patch.object(CollectionManager, "all", return_value=[policy, policy, policy])
    response = list_firewall_policy_command(args)

    assert "Firewall policies:" in response.readable_output
    assert len(response.outputs) == returned_results


def test_create_firewall_policy_command(mocker):
    """
    Given:
        - demisto args
    When:
        - Calling function create_domain_command
    Then:
        - Ensure the results holds the expected data
    """

    args = {"name": "name", "comment": "comment"}
    mocker.patch.object(FirewallPolicy, "create", return_value=mock_Policy(name="name", comment="comment"))
    response = create_firewall_policy_command(args)

    assert response.readable_output == "Firewall policy name was created successfully."
    assert response.outputs.get("Name") == "name"


def test_firewall_policy_delete_command(mocker):
    """
    Given:
        - demisto args
    When:
        - Calling function delete_firewall_policy_command
    Then:
        - Ensure the results holds the expected data in case of an ElementNotFound exception
    """

    mocker.patch.object(FirewallPolicy, "delete", side_effect=mock_delete)
    response = delete_firewall_policy_command({"name": "name"})

    assert response.readable_output == "Firewall policy name was not found."


@pytest.mark.parametrize("args,returned_results", [({"limit": "2"}, 2), ({"all_results": "True"}, 3)])
def test_list_engine_command(mocker, args, returned_results):
    """
    Given:
        - demisto args:
        Case 1: stating a specific Domain name
        Case 2: getting 2 results
        Case 3: getting all of the results (3 results)
    When:
        - Calling function list_domain_command
    Then:
        - Ensure the results holds the expected data and the correct number of results
    """

    engine = mock_Engine(name="name", comment="comment")
    mocker.patch.object(CollectionManager, "limit", return_value=[engine, engine])
    mocker.patch.object(CollectionManager, "all", return_value=[engine, engine, engine])
    response = list_engine_command(args)

    assert "Engines:" in response.readable_output
    assert len(response.outputs) == returned_results


def test_list_rule_command(mocker):
    """
    Given:
        - demisto args:
    When:
        - Calling function list_rule_command
    Then:
        - Ensure the results holds the expected data and the correct number of results
    """

    policy = mock_Policy("name", "comment")
    mocker.patch("ForcepointSecurityManagementCenter.FirewallPolicy", return_value=policy)
    response = list_rule_command({"policy_name": "name"})

    assert "Rules:" in response.readable_output
    assert len(response.outputs) == 2


def test_delete_rule_command_no_policy(mocker):
    """
    Given:
        - demisto args
    When:
        - Calling function delete_rule_command
    Then:
        - Ensure the results holds the expected data in case of an ElementNotFound exception
    """

    mocker.patch.object(CollectionManager, "filter", return_value=[])
    args = {"policy_name": "name", "rule_id": "id"}
    response = delete_rule_command(args)
    assert "Firewall policy name was not found." in response.readable_output


def test_delete_rule_command_no_rule(mocker):
    """
    Given:
        - demisto args
    When:
        - Calling function delete_rule_command
    Then:
        - Ensure the results holds the expected data in case of an ElementNotFound exception
    """
    rule = mock_Rule()
    policy = mock_Policy("name", "comment")
    mocker.patch.object(CollectionManager, "filter", return_value=[policy])
    mocker.patch("ForcepointSecurityManagementCenter.get_policy_rules", return_value=[rule])
    args = {"policy_name": "name", "rule_name": "test", "ip_version": "ip_version"}
    with pytest.raises(DemistoException, match="Rule with name test was not found in policy name."):
        delete_rule_command(args)


def test_create_rule_command(mocker):
    """
    Given:
        - demisto args:
    When:
        - Calling function create_rule_command
    Then:
        - Ensure the results holds the expected data
    """

    mocker.patch.object(CollectionManager, "filter", return_value=[mock_Domain("name", "comment")])
    args = {
        "policy_name": "name",
        "rule_name": "name",
        "ip_version": "V4",
        "source_ip_list": ["source_ip_list"],
        "source_host": ["source_host"],
        "source_domain": ["source_domain"],
        "destination_ip_list": ["destination_ip_list"],
        "destination_host": ["destination_host"],
        "destination_domain": ["destination_domain"],
        "action": "ALLOW",
        "comment": "test_comment",
    }
    policy = mock_Policy("name", "comment")
    mocker.patch("ForcepointSecurityManagementCenter.FirewallPolicy", return_value=policy)
    response = create_rule_command(args)

    assert "The rule name to the policy name was created successfully." in response.readable_output


def test_create_rule_command_no_sources_or_destinations(mocker):
    """
    Given:
        - demisto args:
    When:
        - Calling function create_rule_command
    Then:
        - Ensure the results holds the expected data
    """

    mocker.patch.object(CollectionManager, "filter", return_value=[mock_Domain("name", "comment")])
    args = {"policy_name": "name", "rule_name": "name", "ip_version": "V4", "action": "ALLOW", "comment": "test_comment"}
    policy = mock_Policy("name", "comment")
    mocker.patch("ForcepointSecurityManagementCenter.FirewallPolicy", return_value=policy)

    response = create_rule_command(args)
    assert "No sources or destinations were provided, provide at least one." in response.readable_output


def test_update_rule_command(mocker):
    """
    Given:
        - demisto args:
    When:
        - Calling function create_rule_command
    Then:
        - Ensure the results holds the expected data
    """

    mocker.patch.object(CollectionManager, "filter", return_value=[mock_Domain("name", "comment")])
    args = {
        "policy_name": "name",
        "rule_name": "name",
        "ip_version": "V4",
        "source_ip_list": ["source_ip_list"],
        "source_host": ["source_host"],
        "source_domain": ["source_domain"],
        "destination_ip_list": ["destination_ip_list"],
        "destination_host": ["destination_host"],
        "destination_domain": ["destination_domain"],
        "comment": "test_comment",
    }
    policy = mock_Policy("name", "comment")
    mocker.patch("ForcepointSecurityManagementCenter.FirewallPolicy", return_value=policy)
    response = update_rule_command(args)

    assert "The rule name to the policy name was updated successfully." in response.readable_output


def test_engine_refresh_command_initiation(mocker):
    """
    Given:
        - engine_name argument
    When:
        - Calling engine_refresh_command for the first time (no task_ids)
    Then:
        - Ensure refresh is initiated, task_ids are returned in args_for_next_run, and continue_to_poll is True
    """
    args = {"engine_name": ["engine1", "engine2"]}
    mocker.patch("ForcepointSecurityManagementCenter.Engine", side_effect=lambda name: mock_Engine(name))
    mocker.patch("ForcepointSecurityManagementCenter.Task", side_effect=lambda d: mock_Task(d.get("follower")))

    result = engine_refresh_command(args)

    assert result.scheduled_command is not None
    assert result.scheduled_command._command is not None
    assert result.scheduled_command._command == "forcepoint-smc-engine-refresh"
    assert result.scheduled_command._args is not None
    assert "task_ids" in result.scheduled_command._args
    assert result.scheduled_command._args["task_ids"] == ["engine1", "engine2"]


def test_engine_refresh_command_polling_in_progress(mocker):
    """
    Given:
        - task_ids and engine_name arguments
    When:
        - Calling engine_refresh_command while tasks are still in progress
    Then:
        - Ensure continue_to_poll is True
    """
    args = {"engine_name": ["engine1"], "task_ids": ["engine1"]}
    mocker.patch("ForcepointSecurityManagementCenter.Task", side_effect=lambda d: mock_Task(d.get("follower"), in_progress=True))

    result = engine_refresh_command(args)

    assert result.scheduled_command is not None
    assert result.scheduled_command._command is not None
    assert result.scheduled_command._command == "forcepoint-smc-engine-refresh"
    assert result.scheduled_command._args is not None
    assert "task_ids" in result.scheduled_command._args
    assert result.scheduled_command._args["task_ids"] == ["engine1"]


def test_engine_refresh_command_polling_complete(mocker):
    """
    Given:
        - task_ids and engine_name arguments
    When:
        - Calling engine_refresh_command when all tasks are finished
    Then:
        - Ensure continue_to_poll is False and success message is returned
    """
    args = {"engine_name": ["engine1", "engine2"], "task_ids": ["engine1", "engine2"]}
    mocker.patch("ForcepointSecurityManagementCenter.Task", side_effect=lambda d: mock_Task(d.get("follower"), in_progress=False))

    result = engine_refresh_command(args)

    assert result.scheduled_command is None
    assert "refreshed successfully" in result.readable_output


def test_engine_refresh_command_failure(mocker):
    """
    Given:
        - engine_name argument
    When:
        - engine.refresh() raises TaskRunFailed
    Then:
        - Ensure DemistoException is raised with the correct engine names
    """
    args = {"engine_name": ["engine1", "engine2"]}

    def mock_engine_side_effect(name):
        engine = mock_Engine(name)
        if name == "engine2":
            mocker.patch.object(engine, "refresh", side_effect=TaskRunFailed("Locked"))
        return engine

    mocker.patch("ForcepointSecurityManagementCenter.Engine", side_effect=mock_engine_side_effect)

    with pytest.raises(DemistoException, match=r"Failed to initiate refresh tasks for engines \(engine2\)"):
        engine_refresh_command(args)