Skyhigh Secure Web Gateway (On Prem)

Manages the block and allow lists within Skyhigh Secure Web Gateway.

Network Security · McAfee Web Gateway

Details

IDSkyhigh Secure Web Gateway (On Prem)
ProviderSkyhigh Security
CategoryNetwork Security
From Version6.8.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix XSIAM

README

Manages the block and allow lists within Skyhigh Secure Web Gateway.
This integration was integrated and tested with version 11.2.9 of Skyhigh Secure Web Gateway (On Prem)

Configure Skyhigh Secure Web Gateway (On Prem) in Cortex

Parameter Required
Server URL (e.g. https://192.168.100.55:4712) True
Password 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.

swg-get-available-lists


Get all available lists.

Base Command

swg-get-available-lists

Input

Argument Name Description Required
name Filter to be applied on a list name. Optional
type Filter to be applied on a list type. Optional

Context Output

Path Type Description
SWG.List.ID Unknown List ID.
SWG.List.Title Unknown List title.
SWG.List.Type Unknown List type.

Command example

!swg-get-available-lists name=blocklist

Context Example

{
    "SWG": {
        "List": {
            "ID": "com.scur.type.regex.386",
            "Title": "blocklist",
            "Type": "regex"
        }
    }
}

Human Readable Output

Lists

Title ID Type
blocklist com.scur.type.regex.386 regex
Category Blocklist 5145 category
Upload Media Type Blocklist 5146 mediatype

swg-get-list


Retrieve a specific list.

Base Command

swg-get-list

Input

Argument Name Description Required
list_id List ID. Required

Context Output

Path Type Description
SWG.List.ListEntries.ListID Unknown List ID of the entry’s list.
SWG.List.ListEntries.Name Unknown Entry name.
SWG.List.ListEntries.Description Unknown Entry description.
SWG.List.ListEntries.Position Unknown Entry position in list.
SWG.List.ID Unknown List ID.
SWG.List.Title Unknown List title.
SWG.List.Type Unknown List Type
SWG.List.Description Unknown List description.

Command example

!swg-get-list list_id=com.scur.type.regex.386

Context Example

{
    "SWG": {
        "List": {
            "Description": "blocklist",
            "ID": "com.scur.type.regex.386",
            "Title": "blocklist",
            "Type": "regex",
            "ListEntries": [
                {
                    "Description": "this is really evil",
                    "ListID": "com.scur.type.regex.386",
                    "Name": "http*://test.evil/*",
                    "Position": 0
                },
                {
                    "Description": "this is really evil",
                    "ListID": "com.scur.type.regex.386",
                    "Name": "http*://test-more.evil/*",
                    "Position": 1
                }
            ]
        }
    }
}

Human Readable Output

List Properties

Title ID Description Type
blocklist com.scur.type.regex.386 blocklist regex

blocklist

Position Name Description
0 http://test.evil/ this is really evil
1 http://test-more.evil/ this is really evil

swg-get-list-entry


Retrieve a specific entry from a list.

Base Command

swg-get-list-entry

Input

Argument Name Description Required
list_id List ID. Required
entry_pos Entry position in the table. Required

Context Output

Path Type Description
SWG.List.ID Unknown List ID of the entry’s list.
SWG.List.ListEntries.ListID Unknown List ID of the entry’s list.
SWG.List.ListEntries.Name Unknown Entry name.
SWG.List.ListEntries.Position Unknown Entry position in the list.
SWG.List.ListEntries.Description Unknown Entry description.

Command example

!swg-get-list-entry list_id=com.scur.type.regex.386 entry_pos=0

Context Example

{
    "SWG": {
        "List": {
            "ID": "com.scur.type.regex.386",
            "ListEntries": {
                "Description": "this is really evil",
                "ListID": "com.scur.type.regex.386",
                "Name": "http*://test.evil/*",
                "Position": "0"
            }
        }
    }
}

Human Readable Output

List entry at position 0

ListID Position Name Description
com.scur.type.regex.386 0 http://test.evil/ this is really evil

swg-insert-entry


Insert a new entry to a list.

Base Command

swg-insert-entry

Input

Argument Name Description Required
list_id List ID. Required
entry_pos Entry position in the table. Required
description Entry description. Optional
name Entry name. Required

Context Output

Path Type Description
SWG.List.ID Unknown List ID of the entry’s list.
SWG.List.ListEntries.ListID Unknown List ID of the entry’s list.
SWG.List.ListEntries.Name Unknown Entry name.
SWG.List.ListEntries.Position Unknown Entry position in the list.
SWG.List.ListEntries.Description Unknown Entry description.

Command example

!swg-insert-entry list_id=com.scur.type.regex.386 entry_pos=0 name="http*://evil.corp/*" description="ticket #1: This is an evil domain"

Context Example

{
    "SWG": {
        "List": {
            "ID": "com.scur.type.regex.386",
            "ListEntries": {
                "Description": "ticket #1: This is an evil domain",
                "ListID": "com.scur.type.regex.386",
                "Name": "http*://evil.corp/*",
                "Position": "0"
            }
        }
    }
}

Human Readable Output

Added List entry at position 0

ListID Position Name Description
com.scur.type.regex.386 0 http://evil.corp/ ticket #1: This is an evil domain

swg-delete-entry


Insert a new entry to a list.

Base Command

swg-delete-entry

Input

Argument Name Description Required
list_id List ID. Required
entry_pos Entry position in the table. Required

Context Output

There is no context output for this command.

Command example

!swg-delete-entry list_id=com.scur.type.regex.386 entry_pos=0

Human Readable Output

Deleted List entry at position 0

ListID Position Name Description
com.scur.type.regex.386 0 http://evil.corp ticket #1: This is an evil domain

swg-modify-list


Overwrites the complete XML configuration of a list.

Base Command

swg-modify-list

Input

Argument Name Description Required
list_id List ID. Required
config XML configuration to write to the list. Required

Context Output

Path Type Description
SWG.List.ListEntries.ListID Unknown List ID of the entry’s list.
SWG.List.ListEntries.Name Unknown Entry name.
SWG.List.ListEntries.Description Unknown Entry description.
SWG.List.ListEntries.Position Unknown Entry position in list.
SWG.List.ID Unknown List ID.
SWG.List.Title Unknown List title.
SWG.List.Type Unknown List type.
SWG.List.Description Unknown List description.

Command example

!swg-modify-list list_id=com.scur.type.regex.386 config=`<list version="1.0.3.46" mwg-version="11.2.9-44482" name="blocklist" id="com.scur.type.regex.386" typeId="com.scur.type.regex" classifier="Other" systemList="false" structuralList="false" defaultRights="2"><description>blocklist</description><content><listEntry><entry>http*://evil.corp/*</entry><description>ticket #1: This is an evil domain</description></listEntry></content></list>`

Context Example

{
    "SWG": {
        "List": {
            "Description": "blocklist",
            "ID": "com.scur.type.regex.386",
            "Title": "blocklist",
            "Type": "regex",
            "ListEntries": [
                {
                    "Description": "ticket #1: This is an evil domain",
                    "ListID": "com.scur.type.regex.386",
                    "Name": "http*://evil.corp/*",
                    "Position": 0
                }
            ]
        }
    }
}

Human Readable Output

Modified blocklist

Title ID Description Type
blocklist com.scur.type.regex.386 blocklist regex

swg-create-list


Create a new list.

Base Command

swg-create-list

Input

Argument Name Description Required
name Name for the list to be created. Required
type Type for the list to be created. Possible values are: category, ip, iprange, mediatype, number, regex, string. Default is string. Required

Context Output

Path Type Description
SWG.List.ID Unknown List ID.
SWG.List.Title Unknown List title.
SWG.List.Type Unknown List type.
SWG.List.Description Unknown List description.

Command example

!swg-create-list name="blocklist" type=regex

Context Example

{
    "SWG": {
        "List": {
            "Description": "",
            "ID": "com.scur.type.regex.460",
            "Title": "blocklist",
            "Type": "regex"
        }
    }
}

Human Readable Output

Created List Properties

Title ID Description Type
blocklist com.scur.type.regex.460   regex

swg-delete-list


Delete a list.

Base Command

swg-delete-list

Input

Argument Name Description Required
list_id List ID. Required

Context Output

There is no context output for this command.

Command example

!swg-delete-list list_id=com.scur.type.regex.460

Human Readable Output

Deleted List Properties

Title ID Description Type
blocklist com.scur.type.regex.460   regex

Configuration parameters

  • url — Server URL (e.g., https://192.168.100.55:4712) (required)
  • credentials — Username (required)
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (8)

  • swg-create-list

    Create a new list.

  • swg-delete-entry

    Delete entry to from a list.

  • swg-delete-list

    Delete a list.

  • swg-get-available-lists

    Get all available lists.

  • swg-get-list

    Retrieve a specific list.

  • swg-get-list-entry

    Retrieve a specific entry from a list.

  • swg-insert-entry

    Insert a new entry to a list.

  • swg-modify-list

    Overwrites the complete XML configuration of a list.

import demistomock as demisto
from CommonServerPython import *  # noqa # pylint: disable=unused-wildcard-import

from CommonServerUserPython import *  # noqa

""" IMPORTS """

import urllib
from typing import Any

import urllib3

# Disable insecure warnings
urllib3.disable_warnings()

""" CLIENT CLASS """


class Client(BaseClient):
    """Client class to interact with the service API"""

    def __init__(self, username, password, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.username = username
        self.password = password

    def __enter__(self):
        self.connect()
        return self

    def __exit__(self, _type: Any, *args: Any):
        self.close()

    def connect(self):
        """User login"""
        self._http_request(
            method="POST",
            url_suffix=f"/login?{urllib.parse.urlencode({'userName':self.username,'pass':self.password})}",
            resp_type="xml",
        )

    def close(self):
        """User logout"""
        self._http_request(method="POST", url_suffix="/logout", resp_type="text")

    def get_lists(self, list_name: str | None = None, list_type: str | None = None) -> str:
        """Gets all available lists using the '/list' API endpoint"""
        url_suffix = "/list"
        list_filter = []
        if list_name:
            list_filter.append(f"name={list_name}")
        if list_type:
            list_filter.append(f"type={list_type}")
        if list_filter:
            url_suffix += f"?{'&'.join(list_filter)}"
        return self._http_request(method="GET", url_suffix=url_suffix, resp_type="text")

    def get_list(self, list_id: str):
        return self._http_request(method="GET", url_suffix=f"/list/{list_id}", resp_type="text")

    def get_list_entry(self, list_id: str, entry_pos: str):
        return self._http_request(
            method="GET",
            url_suffix=f"/list/{list_id}/entry/{entry_pos}",
            resp_type="text",
            ok_codes=(200, 202, 203, 404),
        )

    def commit(self):
        return self._http_request(method="POST", url_suffix="/commit", resp_type="text")

    def put_list(self, list_id: str, config: bytes):
        return self._http_request(method="PUT", url_suffix=f"/list/{list_id}", data=config, resp_type="text")

    def insert_entry(self, list_id: str, entry_pos: str, data: str):
        return self._http_request(
            method="POST",
            url_suffix=f"/list/{list_id}/entry/{entry_pos}/insert",
            data=data,
            resp_type="text",
        )

    def delete_entry(self, list_id: str, entry_pos: str):
        return self._http_request(
            method="DELETE",
            url_suffix=f"/list/{list_id}/entry/{entry_pos}",
            resp_type="text",
        )

    def create_list(self, data: str):
        return self._http_request(method="POST", url_suffix="/list", resp_type="text", data=data)

    def delete_list(self, list_id: str):
        return self._http_request(method="Delete", url_suffix=f"/list/{list_id}", resp_type="text")


""" COMMAND FUNCTIONS """


def test_module(client: Client, args: dict[str, Any]) -> str:
    """Tests API connectivity and authentication'

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

    Args:
        client (Client): API client to use.
        args (dict): all command arguments, usually passed from ``demisto.args()``.

    Returns:
        str: 'ok' if test passed, anything else will raise an exception and will fail the test.
    """
    client.get_lists()
    return "ok"


def get_lists_command(client: Client, args: dict[str, Any]) -> CommandResults:
    """
    get lists command: Returns available lists for matching pattern

    Args:
        client (Client): API client to use.
        args (dict): all command arguments, usually passed from ``demisto.args()``.
            ``args['name']`` is used to filter lists by name.
            ``args['type']`` is used to filter lists by type.

    Returns:
        CommandResults: A ``CommandResults`` object that is then passed to ``return_results``, that contains available lists.
    """
    list_name = args.get("name", "")
    list_type = args.get("type", "")
    res = []
    result = client.get_lists(list_name, list_type)
    data = json.loads(xml2json(result))
    title = demisto.get(data, "feed.title")
    entries = demisto.get(data, "feed.entry", [])
    if isinstance(entries, dict):
        entries = [entries]
    for entry in entries:
        res.append(
            {
                "Title": entry.get("title", ""),
                "ID": entry.get("id", ""),
                "Type": entry.get("listType", ""),
            }
        )

    return CommandResults(
        readable_output=tableToMarkdown(title, res, headers=["Title", "ID", "Type"]),
        outputs_prefix="SWG.List",
        outputs_key_field="ID",
        outputs=res,
        raw_response=result,
    )


def get_list_command(client: Client, args: dict[str, Any]) -> CommandResults | str:
    """
    get list command: Returns list details and content

    Args:
        client (Client): API client to use.
        args (dict): all command arguments, usually passed from ``demisto.args()``.
            ``args['list_id']`` the list id to query.

    Returns:
        CommandResults: A ``CommandResults`` object that is then passed to ``return_results``,
                        that contains the list details and content.
    """
    resEntries = []
    list_id: str = args.get("list_id", "")
    result = client.get_list(list_id)

    data = json.loads(xml2json(result))
    config = json2xml(demisto.get(data, "entry.content", data)).decode("utf-8")
    title = demisto.get(data, "entry.title")
    res = {
        "ID": list_id,
        "Title": title,
        "Type": demisto.get(data, "entry.listType", ""),
        "Description": demisto.get(data, "entry.content.list.description"),
    }

    entries = demisto.get(data, "entry.content.list.content.listEntry", [])
    if isinstance(entries, dict):
        entries = [entries]
    for pos, entry in enumerate(entries):
        description = entry.get("description")
        if not description:
            description = ""
        resEntries.append(
            {
                "ListID": list_id,
                "Position": str(pos),
                "Name": entry.get("entry", ""),
                "Description": description,
            }
        )

    hr = tableToMarkdown("List Properties", res, headers=["Title", "ID", "Description", "Type"])
    res["ListEntries"] = resEntries

    return CommandResults(
        readable_output=hr + tableToMarkdown(title, resEntries, headers=["Position", "Name", "Description"]),
        outputs_prefix="SWG.List",
        outputs_key_field=["ID"],
        outputs=res,
        raw_response=config,
    )


def get_list_entry_command(client: Client, args: dict[str, Any]) -> CommandResults | str:
    """
    get list entry command: Returns a single entry form a list

    Args:
        client (Client): API client to use.
        args (dict): all command arguments, usually passed from ``demisto.args()``.
            ``args['list_id']`` the list id to query.
            ``args['entry_pos']`` the entry position to query.

    Returns:
        CommandResults: A ``CommandResults`` object that is then passed to ``return_results``, that contains the list entry.
    """
    list_id: str = args.get("list_id", "")
    entry_pos: str = args.get("entry_pos", "")

    result = client.get_list_entry(list_id, entry_pos)

    data = json.loads(xml2json(result))
    title = demisto.get(data, "entry.title")

    entry = demisto.get(data, "entry.content.listEntry", {})
    description = entry.get("description")
    if not description:
        description = ""
    res = {
        "ID": list_id,
        "ListEntries": [
            {
                "ListID": list_id,
                "Position": entry_pos,
                "Name": entry.get("entry", ""),
                "Description": description,
            }
        ],
    }

    return CommandResults(
        readable_output=tableToMarkdown(title, res["ListEntries"], headers=["ListID", "Position", "Name", "Description"]),
        outputs_prefix="SWG.List",
        outputs_key_field=["ID"],
        outputs=res,
        raw_response=result,
    )


def modify_list_command(client: Client, args: dict[str, Any]) -> CommandResults | str:
    """
    modify list command: Modify the list content

    Args:
        client (Client): API client to use.
        args (dict): all command arguments, usually passed from ``demisto.args()``.
            ``args['list_id']`` the list id to be modified.
            ``args['config']`` the config that should be modified to.

    Returns:
        CommandResults: A ``CommandResults`` object that is then passed to ``return_results``,
                        that contains the list details and content.
    """
    resEntries = []
    list_id: str = args.get("list_id", "")
    conf: str = args.get("config", "")

    result = client.put_list(list_id, conf.encode("utf-8"))
    client.commit()

    data = json.loads(xml2json(result))
    config = json2xml(demisto.get(data, "entry.content", data)).decode("utf-8")
    title = demisto.get(data, "entry.title", "")
    description = demisto.get(data, "entry.content.list.description")
    if not description:
        description = ""

    res = {
        "ID": list_id,
        "Title": title,
        "Type": demisto.get(data, "entry.listType", ""),
        "Description": description,
    }

    entries = demisto.get(data, "entry.content.list.content.listEntry", [])
    if isinstance(entries, dict):
        entries = [entries]
    for pos, entry in enumerate(entries):
        description = entry.get("description")
        if not description:
            description = ""
        resEntries.append(
            {
                "ListID": list_id,
                "Position": str(pos),
                "Name": entry.get("entry", ""),
                "Description": description,
            }
        )

    hr = tableToMarkdown("List Properties", res, headers=["Title", "ID", "Description", "Type"])
    res["ListEntries"] = resEntries

    return CommandResults(
        readable_output=hr + tableToMarkdown(title, resEntries, headers=["Position", "Name", "Description"]),
        outputs_prefix="SWG.List",
        outputs_key_field=["ID"],
        outputs=res,
        raw_response=config,
    )


def insert_entry_command(client: Client, args: dict[str, Any]) -> CommandResults | str:
    """
    insert entry command: Insert an entry to the list

    Args:
        client (Client): API client to use.
        args (dict): all command arguments, usually passed from ``demisto.args()``.
            ``args['list_id']`` the list id to be modified.
            ``args['entry_pos']`` the entry position to insert at.

    Returns:
        CommandResults: A ``CommandResults`` object that is then passed to ``return_results``,
                        that contains the inserted list entry.
    """
    list_id: str = args.get("list_id", "")
    entry_pos: str = args.get("entry_pos", "")
    name: str = args.get("name", "")
    description: str = args.get("description", "")

    entry = f"<listEntry><entry>{name}</entry><description>{description}</description></listEntry>"

    result = client.insert_entry(list_id, entry_pos, entry)
    client.commit()

    data = json.loads(xml2json(result))
    title = f'Added {demisto.get(data, "entry.title")}'

    entry = demisto.get(data, "entry.content.listEntry", {})
    description = entry.get("description")
    if not description:
        description = ""
    entry_name = entry.get("entry", "")
    list_entry = {
        "ListID": list_id,
        "Position": entry_pos,
        "Name": entry_name,
        "Description": description,
    }

    swg_lists = demisto.get(demisto.context(), "SWG.List", [])
    if isinstance(swg_lists, dict):
        swg_lists = [swg_lists]
    if any(item["ID"] == list_id for item in swg_lists):
        outputs_prefix = f'SWG.List(val.ID && val.ID == "{list_id}").ListEntries'
        outputs_key_field = "Name"
        res = list_entry
    else:
        outputs_prefix = "SWG.List"
        outputs_key_field = "ID"
        res = {"ID": list_id, "ListEntries": [list_entry]}

    return CommandResults(
        readable_output=tableToMarkdown(title, list_entry, headers=["ListID", "Position", "Name", "Description"]),
        outputs_prefix=outputs_prefix,
        outputs_key_field=outputs_key_field,
        outputs=res,
        raw_response=result,
    )


def delete_entry_command(client: Client, args: dict[str, Any]) -> CommandResults | str:
    """
    delete entry command: Delete the list entry

    Args:
        client (Client): API client to use.
        args (dict): all command arguments, usually passed from ``demisto.args()``.
            ``args['list_id']`` the list id to be modified.
            ``args['entry_pos']`` the entry position to be deleted.

    Returns:
        CommandResults: A ``CommandResults`` object that is then passed to ``return_results``, that contains the list entry.
    """
    list_id: str = args.get("list_id", "")
    entry_pos: str = args.get("entry_pos", "")

    result = client.delete_entry(list_id, entry_pos)
    client.commit()

    data = json.loads(xml2json(result))
    title = f'Deleted {demisto.get(data, "entry.title")}'

    entry = demisto.get(data, "entry.content.listEntry", {})
    description = entry.get("description")
    if not description:
        description = ""
    res = {
        "ID": list_id,
        "ListEntries": [
            {
                "ListID": list_id,
                "Position": entry_pos,
                "Name": entry.get("entry", ""),
                "Description": description,
            }
        ],
    }

    return CommandResults(
        readable_output=tableToMarkdown(title, res["ListEntries"], headers=["ListID", "Position", "Name", "Description"]),
        raw_response=result,
    )


def create_list_command(client: Client, args: dict[str, Any]) -> CommandResults | str:
    """
    create list command: Create an empty list

    Args:
        client (Client): API client to use.
        args (dict): all command arguments, usually passed from ``demisto.args()``.
            ``args['name']`` the list name to be added.
            ``args['type']`` the list type to be added.

    Returns:
        CommandResults: A ``CommandResults`` object that is then passed to ``return_results``, that contains the list entry.
    """
    list_name: str = args.get("name", "")
    list_type: str = args.get("type", "")

    list_data = (
        f'<list name="{list_name}" typeId="com.scur.type.{list_type}" classifier="Other" systemList="false" '
        + 'structuralList="false" defaultRights="2"><description /><content /></list>'
    )

    result = client.create_list(list_data)
    client.commit()

    data = json.loads(xml2json(result))
    config = json2xml(demisto.get(data, "entry.content", data)).decode("utf-8")

    title = demisto.get(data, "entry.title")
    description = demisto.get(data, "entry.content.list.description")
    if not description:
        description = ""
    res = {
        "ID": demisto.get(data, "entry.id"),
        "Title": title,
        "Type": demisto.get(data, "entry.listType"),
        "Description": description,
    }
    hr = tableToMarkdown("Created List Properties", res, headers=["Title", "ID", "Description", "Type"])

    return CommandResults(
        readable_output=hr, outputs_prefix="SWG.List", outputs_key_field=["ID"], outputs=res, raw_response=config
    )


def delete_list_command(client: Client, args: dict[str, Any]) -> CommandResults | str:
    """
    create list command: Create an empty list

    Args:
        client (Client): API client to use.
        args (dict): all command arguments, usually passed from ``demisto.args()``.
            ``args['list_id']`` the list id to be deleted.

    Returns:
        CommandResults: A ``CommandResults`` object that is then passed to ``return_results``, that contains the list entry.
    """
    list_id: str = args.get("list_id", "")

    result = client.delete_list(list_id)
    client.commit()

    data = json.loads(xml2json(result))

    title = demisto.get(data, "entry.title")
    description = demisto.get(data, "entry.content.list.description")
    if not description:
        description = ""
    res = {
        "ID": demisto.get(data, "entry.id"),
        "Title": title,
        "Type": demisto.get(data, "entry.listType"),
        "Description": description,
    }
    hr = tableToMarkdown("Deleted List Properties", res, headers=["Title", "ID", "Description", "Type"])

    return CommandResults(readable_output=hr, raw_response=result)


""" MAIN FUNCTION """


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

    user = demisto.params().get("credentials", {}).get("identifier")
    password = demisto.params().get("credentials", {}).get("password")

    base_url = urljoin(demisto.params()["url"], "/Konfigurator/REST")
    verify_certificate = not demisto.params().get("insecure", False)
    proxy = demisto.params().get("proxy", False)
    headers = {"Content-Type": "application/mwg+xml"}

    command = demisto.command()

    demisto.debug(f"Command being called is {command}")

    try:
        with Client(
            username=user,
            password=password,
            base_url=base_url,
            verify=verify_certificate,
            headers=headers,
            proxy=proxy,
        ) as client:
            commands = {
                "test-module": test_module,
                "swg-get-available-lists": get_lists_command,
                "swg-get-list": get_list_command,
                "swg-get-list-entry": get_list_entry_command,
                "swg-modify-list": modify_list_command,
                "swg-insert-entry": insert_entry_command,
                "swg-delete-entry": delete_entry_command,
                "swg-create-list": create_list_command,
                "swg-delete-list": delete_list_command,
            }
            if command not in commands:
                raise NotImplementedError(f"Command {command} was not implemented.")
            return_results(commands[command](client, demisto.args()))
    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()