NetQuestOMX
NetQuest’s products are high-capacity service nodes that help security teams access and analyze network traffic. Powerful packet and flow processing features assist security tools in detecting and mitigating security threats as cost effectively as possible.
Utilities · NetQuest OMX
Details
| ID | NetQuestOMX |
|---|---|
| Provider | NetQuest Corporation |
| Category | Utilities |
| From Version | 6.10.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM |
README
NetQuest’s products are high-capacity service nodes that help security teams access and analyze network traffic. Powerful packet and flow processing features assist security tools in detecting and mitigating security threats as cost effectively as possible.
This integration was integrated and tested with version 3.7.5a of NetQuest OMX.
Configure NetQuest OMX in Cortex
| Parameter | Description | Required |
|---|---|---|
| Server URL | The IP of the 5G device using NetQuest OMX, formatted as https://X.X.X.X | True |
| Username | True | |
| Password | True | |
| Slot number | Target NetQuest device slot number. | True |
| Port number | Target NetQuest device port number. | True |
| Fetch Events | Whether to collect events. | False |
| Statistic types to fetch | True | |
| Use system proxy settings | False | |
| Trust any certificate (not secure) | 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.
netquest-address-list-upload
Uploads a .txt file with the address list to the appliance. The appliance temporarily stores the file until it is saved to the Library and replaces any previously loaded list file.
Base Command
netquest-address-list-upload
Input
| Argument Name | Description | Required |
|---|---|---|
| entry_id | The entry ID of the file to upload. | Required |
Context Output
There is no context output for this command.
netquest-address-list-optimize
Optimizes the updated address list. If the traffic elements are IP addresses, the integration will optimize the list by compressing IP addresses into CIDR groups.
Base Command
netquest-address-list-optimize
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| NetQuest.AddressList.OverlappingAddresses | list | A list of overlapping addresses in the address list. |
| NetQuest.AddressList.OverlapsPresent | boolean | A boolean field that indicates whether overlapping IP address ranges are present in the address list. |
| NetQuest.AddressList.MergedAddresses | list | A list that contains consolidated IP address ranges, combining overlapping or contiguous addresses into a unified set. |
| NetQuest.AddressList.MergesPresent | boolean | A boolean field that indicates whether any address ranges in the list have been merged to eliminate overlaps or contiguous entries. |
| NetQuest.AddressList.CountsBefore | Dictionary | A dictionary that stores the number of occurrences of each IP address or address range before any processing or modifications were applied. |
| NetQuest.AddressList.CountsAfter | Dictionary | A dictionary that stores the number of occurrences of each IP address or address range after processing or modifications have been applied. |
netquest-address-list-create
Creates a new address list. This list will replace and override the old list entity.
Base Command
netquest-address-list-create
Input
| Argument Name | Description | Required |
|---|---|---|
| name | The name for the new address list. | Required |
Context Output
There is no context output for this command.
netquest-address-list-rename
Renames an address list. This is only meant to change the name of the list. If you try to give the value of the new_name argument to an existing address list, the command will fail.
Base Command
netquest-address-list-rename
Input
| Argument Name | Description | Required |
|---|---|---|
| new_name | The new name for an existing address list. | Required |
| existing_name | The name of the address list that you want to modify. | Required |
Context Output
There is no context output for this command.
netquest-address-list-delete
Deletes the address list of the name provided.
Base Command
netquest-address-list-delete
Input
| Argument Name | Description | Required |
|---|---|---|
| name | The name of the address list to delete. | Required |
Context Output
There is no context output for this command.
get-events
Gets events from NetQuest OMX. Each event is a report for the specified statistic type. Available only for Cortex XSIAM.
Base Command
get-events
Input
| Argument Name | Description | Required |
|---|---|---|
| should_push_events | When true, the integration creates Cortex XSIAM events. Otherwise, they will only be displayed. Possible values are: true, false. Default is false. | Required |
| statistic_types_to_fetch | Comma-separated list of statistic types to return. Default is Metering Stats,Export Stats,Export Peaks FPS,Optimization Stats. | Required |
Context Output
There is no context output for this command.
<~PLATFORM>
License Requirements
The following configuration parameters require the Cortex XSIAM license:
- Fetch Events
</~PLATFORM>
Configuration parameters
url— Server URL (required)credentials— Username (required)slot— Slot number (required)port— Port number (required)isFetchEvents— Fetch EventseventFetchInterval— Events Fetch Intervalstatistic_types_to_fetch— Statistic types to fetch (required)proxy— Use system proxy settingsinsecure— Trust any certificate (not secure)
Commands (6)
-
get-eventsGets events from NetQuest OMX. Each event is a report for the specified statistic type. Available only for Cortex XSIAM.
-
netquest-address-list-createCreates a new address list. This list will replace and override the old list entity.
-
netquest-address-list-deleteDeletes the address list of the name provided.
-
netquest-address-list-optimizeOptimizes the updated address list. If the traffic elements are IP addresses, the integration will optimize the list by compressing IP addresses into CIDR groups.
-
netquest-address-list-renameRenames an address list. This is only meant to change the name of the list. If you try to give the value of the new_name argument to an existing address list, the command will fail.
-
netquest-address-list-uploadUploads a .txt file with the address list to the appliance. The appliance temporarily stores the file until it is saved to the Library and replaces any previously loaded list file.
import json import pytest from CommonServerPython import * # noqa: F401 from freezegun import freeze_time from NetQuestOMX import ( DATE_FORMAT_FOR_TOKEN, TOKEN_TTL_S, Client, StatType, address_list_create_command, address_list_delete_command, address_list_optimize_command, address_list_rename_command, address_list_upload_command, demisto, fetch_events, get_events, ) from pytest_mock import MockerFixture BASE_URL = "https://www.example.com/api/" def util_load_json(path): with open(path, encoding="utf-8") as f: return json.loads(f.read()) # ----------------------------------------- COMMAND FUNCTIONS TESTS --------------------------- @pytest.fixture def net_quest_omx_client(requests_mock): credentials = {"identifier": "UserName", "password": "Password"} requests_mock.post(f"{BASE_URL}SessionService/Sessions", status_code=200, headers={"X-Auth-Token": "TEST"}) return Client(base_url="https://www.example.com", credentials=credentials, verify=True, proxy=False) @freeze_time("2020-06-03T02:00:00Z") def test_new_token_login_client(requests_mock): """ Given: - NetQuestOMX client object When: - getting the integration context Then: - Ensure the expiration time of the new token is calculated as expected in the integration context """ credentials = {"identifier": "UserName", "password": "Password"} requests_mock.post(f"{BASE_URL}SessionService/Sessions", status_code=200, headers={"X-Auth-Token": "TEST"}) Client(base_url="https://www.example.com", credentials=credentials, verify=True, proxy=False) integration_context = get_integration_context() assert integration_context["expiration_time"] == (datetime.utcnow() + timedelta(seconds=TOKEN_TTL_S)).strftime( DATE_FORMAT_FOR_TOKEN ) @freeze_time("2020-06-03T02:00:00Z") def test_old_token_login_client(mocker: MockerFixture): """ Given: - Mocked integration context which contains a valid token (not expired) When: - Building a client Then: - Ensure that no new token is generated (since the existing token is not expired) """ credentials = {"identifier": "UserName", "password": "Password"} context = { "Token": "TEST", "expiration_time": (datetime.utcnow() + timedelta(seconds=TOKEN_TTL_S)).strftime(DATE_FORMAT_FOR_TOKEN), } mocker.patch.object(demisto, "getIntegrationContext", return_value=context) mocker.patch.object(demisto, "setIntegrationContext") mock_refresh_access_token = mocker.patch.object(Client, "_refresh_access_token") Client(base_url="https://www.example.com", credentials=credentials, verify=True, proxy=False) mock_refresh_access_token.assert_not_called() # ensuring _refresh_access_token was not called def test_fetch_events(requests_mock, net_quest_omx_client): """ Given: - The all 4 statistic_types_to_fetch When: - Executing fetch_events function Then: - Ensure number of events as number of statistic_types_to_fetch (event for each type) - Ensure all events contain the 'STAT_TYPE' field """ slot_number, port_number = "1", "1" requests_mock.get( f"{BASE_URL}Systems/Slot/{slot_number}/Ipfix/Status/Metering", json=util_load_json("test_data/MeteringStas.json") ) requests_mock.get( f"{BASE_URL}Systems/Slot/{slot_number}/Ipfix/Status/Export", json=util_load_json("test_data/ExportStats.json") ) requests_mock.get( f"{BASE_URL}Systems/Slot/{slot_number}/Ipfix/Status/ExportHwm", json=util_load_json("test_data/ExportPeakFPS.json") ) requests_mock.get( f"{BASE_URL}Systems/Slot/{slot_number}/Port/{port_number}/EthernetInterfaces/Status/EthRxTx", json=util_load_json("test_data/OptimizationStats.json"), ) statistic_types_to_fetch = ["Metering Stats", "Export Stats", "Export Peaks FPS", "Optimization Stats"] events = fetch_events( client=net_quest_omx_client, slot_number=slot_number, port_number=port_number, statistic_types_to_fetch=statistic_types_to_fetch, ) assert len(events) == len(statistic_types_to_fetch) for event in events: assert event["STAT_TYPE"] in [statistic_type.replace(" ", "") for statistic_type in statistic_types_to_fetch] def test_get_events(requests_mock, net_quest_omx_client): """ Given: - 2 statistic_types_to_fetch When: - Executing get_events function Then: - Ensure number of events as number of statistic_types_to_fetch (event for each type) """ params = {"slot": "1", "port": "1"} args = {"statistic_types_to_fetch": "Metering Stats,Export Stats"} requests_mock.get( f'{BASE_URL}Systems/Slot/{params["slot"]}/Ipfix/Status/Metering', json=util_load_json("test_data/MeteringStas.json") ) requests_mock.get( f'{BASE_URL}Systems/Slot/{params["slot"]}/Ipfix/Status/Export', json=util_load_json("test_data/ExportStats.json") ) events = get_events(net_quest_omx_client, params, args) assert len(events) == 2 def test_get_events_invalid_input(net_quest_omx_client): """ Given: - invalid inputs - statistic_types_to_fetch When: - Executing get_events function Then: - Ensure an exception is thrown """ params = {"slot": "1", "port": "1"} args = {"statistic_types_to_fetch": "Metering ,Export"} with pytest.raises(DemistoException) as de: get_events(net_quest_omx_client, params, args) assert f"{argToList(args['statistic_types_to_fetch'])} is not a valid type" in de.value.message assert f"Valid types are {list(StatType._value2member_map_.keys())}" in de.value.message def test_address_list_upload_command(mocker, requests_mock, net_quest_omx_client): """ Given: - An entry_id (for a file to upload) - A mocked client When: - Executing netquest-address-list-upload command Then: - Ensure command is not failed and the readable_output as expected """ mocker.patch.object(demisto, "getFilePath", return_value={"path": "test_data/test_file.txt", "name": "test_file"}) requests_post = requests_mock.post(f"{BASE_URL}v1/UpdateService/ImportList/Config", json={}) result = address_list_upload_command(client=net_quest_omx_client, args={"entry_id": "AAAAAAaaaa"}) assert result.readable_output == "Address list was successfully uploaded" assert requests_post.called def test_address_list_optimize_command(requests_mock, net_quest_omx_client): """ Given: - A mocked client When: - Executing netquest-address-list-optimize command Then: - Ensure command is not failed and the outputs_prefix as expected """ requests_mock.get(f"{BASE_URL}Systems/Filters/Address/Status/Optimization", json={}) result = address_list_optimize_command(client=net_quest_omx_client) assert result.outputs_prefix == "NetQuest.AddressList" def test_address_list_create_command(requests_mock, net_quest_omx_client): """ Given: - A mocked client - A name and a value for the new list When: - Executing netquest-address-list-create command Then: - Ensure command is not failed and the readable_output as expected """ name, value = "TEST", "0.0.0.0/24" requests_mock.post(f"{BASE_URL}Systems/Filters/ListImport/Config/Install", json={}) result = address_list_create_command(client=net_quest_omx_client, args={"name": name, "value": value}) assert result.readable_output == f"Successfully created a new instance of {name}" def test_address_list_rename_command(requests_mock, net_quest_omx_client): """ Given: - A mocked client - The name of the list to rename - A new name and a new value for the list When: - Executing netquest-address-list-rename command Then: - Ensure command is not failed and the readable_output as expected """ new_name, new_value, existing_name = "NEW_TEST", "0.0.0.0/24", "TEST" requests_mock.put(f"{BASE_URL}Systems/Filters/ListImport/ListName/{existing_name}/Config/Install", json={}) result = address_list_rename_command( client=net_quest_omx_client, args={"new_name": new_name, "new_value": new_value, "existing_name": existing_name} ) assert result.readable_output == f"Successfully renamed {existing_name} to {new_name}" def test_address_list_delete_command(requests_mock, net_quest_omx_client): """ Given: - A mocked client - The name of the list to rename - A new name for the list When: - Executing netquest-address-list-rename command Then: - Ensure command is not failed and the readable_output as expected """ name = "TEST" requests_mock.delete(f"{BASE_URL}Systems/Filters/Address/ListName/{name}/Config/List", json={}) result = address_list_delete_command(client=net_quest_omx_client, args={"name": name}) assert result.readable_output == f"Successfully deleted {name} list"