From e2021814a26b4ca1af662689cacb9392b7357ce7 Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Fri, 9 Aug 2024 01:32:42 +0300 Subject: [PATCH 01/14] Cyble enhancements (#35808) * Cyble enhancements (#35788) * IOC Updates * Module imports fixups * Review changes * Update Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2.yml * Update Packs/CybleEventsV2/ReleaseNotes/1_0_4.md --------- Co-authored-by: cyble-dev <101622497+cyble-dev@users.noreply.github.com> Co-authored-by: israelpoli <72099621+israelpoli@users.noreply.github.com> --- .../CybleEventsV2/CybleEventsV2.py | 82 ++++++++++++----- .../CybleEventsV2/CybleEventsV2.yml | 6 +- .../CybleEventsV2/CybleEventsV2_test.py | 47 +++++----- .../Integrations/CybleEventsV2/README.md | 22 ++--- .../test_data/dummy_fetch_iocs.json | 90 +++++++------------ Packs/CybleEventsV2/ReleaseNotes/1_0_4.md | 9 ++ Packs/CybleEventsV2/pack_metadata.json | 2 +- 7 files changed, 143 insertions(+), 115 deletions(-) create mode 100644 Packs/CybleEventsV2/ReleaseNotes/1_0_4.md diff --git a/Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2.py b/Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2.py index 20a557af32de..dfd3d3c641d9 100644 --- a/Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2.py +++ b/Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2.py @@ -2,10 +2,13 @@ ''' IMPORTS ''' import requests -from datetime import datetime, timezone +from datetime import datetime +import pytz import urllib3 import json +UTC = pytz.UTC + # Disable insecure warnings urllib3.disable_warnings() @@ -113,9 +116,9 @@ def validate_input(args, is_iocs=False): _start_date = datetime(1, 1, 1, 0, 0) _end_date = datetime(1, 1, 1, 0, 0) - if limit <= 0 or limit > 1000: + if limit <= 0 or limit > 100: raise ValueError( - f"The limit argument should contain a positive number, up to 1000, limit: {limit}") + f"The limit argument should contain a positive number, up to 100, limit: {limit}") if _start_date > datetime.utcnow(): raise ValueError( @@ -132,10 +135,10 @@ def validate_input(args, is_iocs=False): if limit <= 0 or limit > LIMIT_EVENT_ITEMS: raise ValueError(f"The limit argument should contain a positive number, up to 1000, limit: {limit}") - if _start_date > datetime.now(tz=timezone.utc): + if _start_date > datetime.now(tz=UTC): raise ValueError( - f"Start date must be a date before or equal to {datetime.now(tz=timezone.utc).strftime(date_format)}") - if _end_date > datetime.now(tz=timezone.utc): + f"Start date must be a date before or equal to {datetime.now(tz=UTC).strftime(date_format)}") + if _end_date > datetime.now(tz=UTC): raise ValueError( f"End date must be a date before or equal to {args.get('end_date')}") if _start_date > _end_date: @@ -229,6 +232,11 @@ def format_incidents(alerts, hide_cvv_expiry): alert['data_message']['data']['bank']['card']['cvv'] = "xxx" alert['data_message']['data']['bank']['card']['expiry'] = "xx/xx/xxxx" + keyword = "" + if alert.get('metadata') and alert['metadata'].get('entity'): + if alert['metadata']['entity'].get('keyword') and alert['metadata']['entity']['keyword']['tag_name']: + keyword = alert['metadata']['entity']['keyword']['tag_name'] + alert_details = { "name": "Cyble Vision Alert on {}".format(alert['service']), "event_type": "{}".format(alert['service']), @@ -236,7 +244,7 @@ def format_incidents(alerts, hide_cvv_expiry): "alert_group_id": "{}".format(alert['alert_group_id']), "event_id": "{}".format(alert['id']), "data_message": json.dumps(alert['data_message']), - "keyword": "{}".format(alert['metadata']['entity']['keyword']['tag_name']), + "keyword": "{}".format(keyword), "created_at": "{}".format(alert['created_at']), "status": "{}".format(alert['status']), "mirrorInstance": demisto.integrationInstance() @@ -710,32 +718,64 @@ def cyble_fetch_iocs(client, method, token, args, url): if args.get('end_date'): input_params_alerts_iocs['endDate'] = args.get('end_date') - iocs = set_request(client, method, token, input_params_alerts_iocs, url) + response = set_request(client, method, token, input_params_alerts_iocs, url) try: lst_iocs = [] - for ioc in iocs['result']: + for ioc in response['iocs']: + + sources = [] + behaviour_tags = [] + target_countries = [] + target_regions = [] + target_industries = [] + related_malwares = [] + related_threat_actors = [] + + if ioc.get('sources'): + for source in ioc.get('sources'): + sources.append(source) + + if ioc.get('behaviour_tags'): + for behaviour_tag in ioc.get('behaviour_tags'): + behaviour_tags.append(behaviour_tag) + + if ioc.get('target_countries'): + for target_country in ioc.get('target_countries'): + target_countries.append(target_country) + + if ioc.get('target_regions'): + for target_region in ioc.get('target_regions'): + target_regions.append(target_region) - lst_attack = [] - lst_tags = [] + if ioc.get('target_industries'): + for target_industry in ioc.get('target_industries'): + target_industries.append(target_industry) - for attack_details in ioc['attack_id']: - lst_attack.append(attack_details['attack_id']) + if ioc.get('related_malware'): + for related_malware in ioc.get('related_malware'): + related_malwares.append(related_malware) - for ioc_tags in ioc['ioc_tags']: - lst_tags.append(ioc_tags['name']) + if ioc.get('related_threat_actors'): + for related_threat_actor in ioc.get('related_threat_actors'): + related_threat_actors.append(related_threat_actor) lst_iocs.append({'ioc': "{}".format(ioc['ioc']), + 'ioc_type': "{}".format(ioc['ioc_type']), 'first_seen': "{}".format(ioc['first_seen']), 'last_seen': "{}".format(ioc['last_seen']), - 'risk_rating': "{}".format(ioc['risk_rating']), - 'confident_rating': "{}".format(ioc['confident_rating']), - 'ioc_type': "{}".format(ioc['ioc_type']['name']), - 'attack': f"{lst_attack}", - 'tags': f"{lst_tags}" + 'risk_score': "{}".format(ioc['risk_score']), + 'confidence_rating': "{}".format(ioc['confidence_rating']), + 'sources': f"{sources}", + 'behaviour_tags': f"{behaviour_tags}", + 'target_countries': f"{target_countries}", + 'target_regions': f"{target_regions}", + 'target_industries': f"{target_industries}", + 'related_malware': f"{related_malwares}", + 'related_threat_actors': f"{related_threat_actors}", }) except Exception as e: - raise Exception(f"Error: [{e}] for response [{iocs}]") + raise Exception(f"Error: [{e}] for response [{response}]") markdown = tableToMarkdown('Indicator of Compromise:', lst_iocs, ) diff --git a/Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2.yml b/Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2.yml index 81686614a9b6..ab57d2a23609 100644 --- a/Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2.yml +++ b/Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2.yml @@ -103,11 +103,11 @@ script: - Emai - description: Returns records for the specified indicator value. name: ioc - - defaultValue: '0' + - defaultValue: '1' description: Returns records that starts from the given page number (the value of the form parameter) in the results list. name: from - defaultValue: '1' - description: Number of records to return (max 1000). Using a smaller limit will get faster responses. + description: Number of records to return (max 100). Using a smaller limit will get faster responses. name: limit - auto: PREDEFINED defaultValue: last_seen @@ -202,7 +202,7 @@ script: type: String - description: Retrieves a User Profile schema, which holds all of the user fields within the application. Used for outgoing-mapping through the Get Schema option. name: get-mapping-fields - dockerimage: demisto/python3:3.10.13.80014 + dockerimage: demisto/python3:3.11.9.107902 isfetch: true runonce: false script: '-' diff --git a/Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2_test.py b/Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2_test.py index 6eb842a32e62..7552c4259308 100644 --- a/Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2_test.py +++ b/Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2_test.py @@ -11,12 +11,15 @@ """ import json -from datetime import datetime, timezone, timedelta +from datetime import datetime, timedelta +import pytz import pytest import demistomock as demisto +UTC = pytz.UTC + def util_load_json(path): with open("test_data/" + path, encoding='utf-8') as f: @@ -120,10 +123,10 @@ def test_get_iocs(requests_mock, offset): assert isinstance(response, list) assert isinstance(response[0], dict) assert response[0]['ioc'] == 'Indicator' - assert response[0]['last_seen'] == '2023-02-20 21:00:55' - assert response[0]['first_seen'] == '2023-02-20 21:00:55' - assert response[0]['ioc_type'] == 'some indicator type' - assert response[0]['risk_rating'] == 'Some Risk Rating' + assert response[0]['ioc_type'] == 'Some IOC Type' + assert response[0]['first_seen'] == '1722227702' + assert response[0]['last_seen'] == '1722472568' + assert response[0]['risk_score'] == '70' def test_get_alert_group(requests_mock): @@ -238,8 +241,8 @@ def test_limit_validate_input(capfd): from CybleEventsV2 import validate_input args = { - 'start_date': datetime.now(tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%S%z"), - 'end_date': datetime.now(tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%S%z"), + 'start_date': datetime.now(tz=UTC).strftime("%Y-%m-%dT%H:%M:%S%z"), + 'end_date': datetime.now(tz=UTC).strftime("%Y-%m-%dT%H:%M:%S%z"), 'from': '0', 'limit': '-1', } @@ -260,7 +263,7 @@ def test_limit_validate_ioc_input(capfd): } with capfd.disabled(), pytest.raises(ValueError, match="The limit argument should contain a positive number," - f" up to 1000, limit: {args.get('limit', '50')}"): + f" up to 100, limit: {args.get('limit', '50')}"): validate_input(args=args, is_iocs=True) @@ -284,8 +287,8 @@ def test_edate_validate_input(capfd): from CybleEventsV2 import validate_input args = { - 'start_date': datetime.now(tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%S%z"), - 'end_date': (datetime.now(tz=timezone.utc) + timedelta(days=4)).strftime("%Y-%m-%dT%H:%M:%S%z"), + 'start_date': datetime.now(tz=UTC).strftime("%Y-%m-%dT%H:%M:%S%z"), + 'end_date': (datetime.now(tz=UTC) + timedelta(days=4)).strftime("%Y-%m-%dT%H:%M:%S%z"), 'from': '0', 'limit': '1' } @@ -300,8 +303,8 @@ def test_date_validate_input(capfd): from CybleEventsV2 import validate_input args = { - 'start_date': datetime.now(tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%S%z"), - 'end_date': (datetime.now(tz=timezone.utc) - timedelta(days=4)).strftime("%Y-%m-%dT%H:%M:%S%z"), + 'start_date': datetime.now(tz=UTC).strftime("%Y-%m-%dT%H:%M:%S%z"), + 'end_date': (datetime.now(tz=UTC) - timedelta(days=4)).strftime("%Y-%m-%dT%H:%M:%S%z"), 'from': '0', 'limit': '1' } @@ -337,8 +340,8 @@ def test_offset_cyble_vision_fetch_detail(requests_mock, capfd): args = { 'from': '-1', 'limit': 1, - 'start_date': datetime.now(tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%S%z"), - 'end_date': datetime.now(tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%S%z") + 'start_date': datetime.now(tz=UTC).strftime("%Y-%m-%dT%H:%M:%S%z"), + 'end_date': datetime.now(tz=UTC).strftime("%Y-%m-%dT%H:%M:%S%z") } url = "https://test.com/apollo/api/v1/y/alerts" @@ -368,8 +371,8 @@ def test_get_alert_fetch(requests_mock): args = { 'from': 1, 'limit': 1, - 'start_date': datetime.now(tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%S%z"), - 'end_date': datetime.now(tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%S%z") + 'start_date': datetime.now(tz=UTC).strftime("%Y-%m-%dT%H:%M:%S%z"), + 'end_date': datetime.now(tz=UTC).strftime("%Y-%m-%dT%H:%M:%S%z") } url = "https://test.com/apollo/api/v1/y/alerts" @@ -400,8 +403,8 @@ def test_get_alert_fetch2(requests_mock): args = { 'from': 1, 'limit': 1, - 'start_date': datetime.now(tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%S%z"), - 'end_date': datetime.now(tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%S%z") + 'start_date': datetime.now(tz=UTC).strftime("%Y-%m-%dT%H:%M:%S%z"), + 'end_date': datetime.now(tz=UTC).strftime("%Y-%m-%dT%H:%M:%S%z") } url = "https://test.com/apollo/api/v1/y/alerts" @@ -451,8 +454,8 @@ def test_data_alert_invalidate_date(capfd): from CybleEventsV2 import validate_input args = { - 'start_date': datetime.now(tz=timezone.utc).strftime("%Y-%m-%dT%H:%M"), - 'end_date': (datetime.now(tz=timezone.utc) - timedelta(days=4)).strftime("%Y-%m-%dT%H:%M"), + 'start_date': datetime.now(tz=UTC).strftime("%Y-%m-%dT%H:%M"), + 'end_date': (datetime.now(tz=UTC) - timedelta(days=4)).strftime("%Y-%m-%dT%H:%M"), 'from': '0', 'limit': '1' } @@ -467,8 +470,8 @@ def test_data_alert_iocs_date(capfd): from CybleEventsV2 import validate_input args = { - 'start_date': datetime.now(tz=timezone.utc).strftime("%Y-%m-%dT%H:%M"), - 'end_date': (datetime.now(tz=timezone.utc) - timedelta(days=4)).strftime("%Y-%m-%dT%H:%M"), + 'start_date': datetime.now(tz=UTC).strftime("%Y-%m-%dT%H:%M"), + 'end_date': (datetime.now(tz=UTC) - timedelta(days=4)).strftime("%Y-%m-%dT%H:%M"), 'from': '0', 'limit': '1' } diff --git a/Packs/CybleEventsV2/Integrations/CybleEventsV2/README.md b/Packs/CybleEventsV2/Integrations/CybleEventsV2/README.md index d90ec4d78933..2900406b6b38 100644 --- a/Packs/CybleEventsV2/Integrations/CybleEventsV2/README.md +++ b/Packs/CybleEventsV2/Integrations/CybleEventsV2/README.md @@ -60,17 +60,17 @@ Fetch the indicators in the given timeline. #### Input -| **Argument Name** | **Description** | **Required** | -|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------|--------------| -| ioc_type | Returns records according to their type (Domain, FileHash-MD5, FileHash-SHA1, FileHash-SHA256, IPv4, IPv6, URL, Email). Default is Domain. | Optional | -| ioc | Returns records for the specified indicator value. | Optional | -| from | Returns records that starts from the given page number (the value of the form parameter) in the results list. Default is 0. | Optional | -| limit | Number of records to return (max 1000). Using a smaller limit will get faster responses. Default is 1. | Optional | -| sort_by | Sorting based on the column(last_seen,first_seen,ioc_type). Possible values are: last_seen, first_seen, ioc_type. Default is last_seen. | Optional | -| order | Sorting order for ioc either Ascending or Descending based on sort by. Default is desc. | Optional | -| tags | Returns records for the specified tags. | Optional | -| start_date | Timeline start date in the format "YYYY-MM-DD". Should be used with start_date as timeline range. | Optional | -| end_date | Timeline end date in the format "YYYY-MM-DD". Should be used with end_date as timeline range. | Optional | +| **Argument Name** | **Description** | **Required** | +|-------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------| +| ioc_type | Returns records according to their type (Domain, FileHash-MD5, FileHash-SHA1, FileHash-SHA256, IPv4, IPv6, URL, Email, Wallet-Address). Default is Domain. | Optional | +| ioc | Returns records for the specified indicator value. | Optional | +| from | Returns records that starts from the given page number (the value of the form parameter) in the results list. Default is 1. | Optional | +| limit | Number of records to return (max 100). Using a smaller limit will get faster responses. Default is 1. | Optional | +| sort_by | Sorting based on the column(last_seen,first_seen,ioc_type). Possible values are: last_seen, first_seen, ioc_type. Default is last_seen. | Optional | +| order | Sorting order for ioc either Ascending or Descending based on sort by. Default is desc. | Optional | +| tags | Returns records for the specified tags. | Optional | +| start_date | Timeline start date in the format "YYYY-MM-DD". Should be used with start_date as timeline range. | Optional | +| end_date | Timeline end date in the format "YYYY-MM-DD". Should be used with end_date as timeline range. | Optional | #### Context Output diff --git a/Packs/CybleEventsV2/Integrations/CybleEventsV2/test_data/dummy_fetch_iocs.json b/Packs/CybleEventsV2/Integrations/CybleEventsV2/test_data/dummy_fetch_iocs.json index a3031900a29d..2fb727f4442a 100644 --- a/Packs/CybleEventsV2/Integrations/CybleEventsV2/test_data/dummy_fetch_iocs.json +++ b/Packs/CybleEventsV2/Integrations/CybleEventsV2/test_data/dummy_fetch_iocs.json @@ -1,64 +1,40 @@ { "data": { "pagination": { - "count": 17381117, - "items_per_page": 10, - "page": 1 + "total_count": 17381117, + "page": 1, + "limit": 10 }, - "result": [ - { - "asn_id": null, - "attack_id": [ - { - "created_at": "2023-01-05T04:09:37.034894Z", - "attack_id": "T1071.001", - "name": "sample protocol name", - "updated_at": "2023-01-05T04:09:37.034894Z", - "uuid": "00000000-0000-0000-0000-000000000000", - "pivot": { - "ioc_id": "00000000-0000-0000-0000-000000000000", - "ioc_attack_id": "8992fe13-010f-5863-b025-6c15c07d00a7" - } - } - ], - "confident_rating": "Some confident Rating", - "created_at": "2023-02-21T02:51:38.959289Z", - "created_by": null, - "first_seen": "2023-02-20 21:00:55", - "ioc": "Indicator", - "ioc_type": { - "created_at": "2023-01-05T03:00:46.918397Z", - "created_by": null, - "updated_at": "2023-01-05T03:00:46.918397Z", - "uuid": "00000000-0000-0000-0000-000000000000", - "name": "some indicator type" - }, - "ioc_tags": [ - { - "created_at": "2023-02-12T16:57:07.204597Z", - "name": "Tag Name", - "pivot": { - "ioc_id": "00000000-0000-0000-0000-000000000000", - "tag_id": "00000000-0000-0000-0000-000000000000" - }, - "tag_type_id": "00000000-0000-0000-0000-000000000000", - "updated_at": "2023-02-12T16:57:07.204597Z", - "uuid": "00000000-0000-0000-0000-000000000000" - } - ], - "iocs_source_name": { - "created_at": "2023-02-10T06:20:56.328463Z", - "name": "Feed Name", - "updated_at": "2023-02-10T06:20:56.328463Z", - "uuid": "00000000-0000-0000-0000-000000000000" - }, - "last_seen": "2023-02-20 21:00:55", - "reference_link": null, - "risk_rating": "Some Risk Rating", - "source_name_id": "00000000-0000-0000-0000-000000000000", - "updated_at": "2023-02-21T02:51:38.959289Z", - "uuid": "00000000-0000-0000-0000-000000000000" - } + "iocs": [ + { + "ioc": "Indicator", + "ioc_type": "Some IOC Type", + "first_seen": 1722227702, + "last_seen": 1722472568, + "risk_score": 70, + "sources": [ + "Some Source" + ], + "behaviour_tags": [ + "Some Tags" + ], + "confidence_rating": "Some Rating", + "target_countries": [ + "Some Countries" + ], + "target_regions": [ + "Some Regions" + ], + "target_industries": [ + "Some Industries" + ], + "related_malware": [ + "Some Malware" + ], + "related_threat_actors": [ + "Some Actors" + ] + } ] }, "success": true diff --git a/Packs/CybleEventsV2/ReleaseNotes/1_0_4.md b/Packs/CybleEventsV2/ReleaseNotes/1_0_4.md new file mode 100644 index 000000000000..5434b5c013a6 --- /dev/null +++ b/Packs/CybleEventsV2/ReleaseNotes/1_0_4.md @@ -0,0 +1,9 @@ +#### Integrations + +##### CybleEvents v2 + +- Updated the Docker image to: *demisto/python3:3.11.9.107902*. +- Updated app code to incorporate IOC changes +- New max IOC limit is 100 +- Added new IOC Type: Wallet-Address +- Big fixes in Alerts fetching code diff --git a/Packs/CybleEventsV2/pack_metadata.json b/Packs/CybleEventsV2/pack_metadata.json index 087f671ec191..9744e6ea9ed6 100644 --- a/Packs/CybleEventsV2/pack_metadata.json +++ b/Packs/CybleEventsV2/pack_metadata.json @@ -2,7 +2,7 @@ "name": "CybleEventsV2", "description": "Cyble Events for Vision Users. Must have Vision API access to use the threat intelligence.", "support": "partner", - "currentVersion": "1.0.3", + "currentVersion": "1.0.4", "author": "Cyble Info Sec", "url": "https://cyble.com/", "email": "", From 0f5d065aafbf4dd401a75d2ebae0a57a59adef78 Mon Sep 17 00:00:00 2001 From: Yaakov Praisler <59408745+yaakovpraisler@users.noreply.github.com> Date: Fri, 9 Aug 2024 08:11:39 +0300 Subject: [PATCH 02/14] Fix issue in ParseEmails script (#35796) * Fix issue in ParseEmails script * Bump pack from version CommonScripts to 1.15.47. * empty --------- Co-authored-by: Content Bot --- Packs/CommonScripts/ReleaseNotes/1_15_47.md | 7 +++++++ .../Scripts/ParseEmailFilesV2/ParseEmailFilesV2.yml | 2 +- Packs/CommonScripts/pack_metadata.json | 2 +- Tests/docker_native_image_config.json | 9 +++++++++ 4 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 Packs/CommonScripts/ReleaseNotes/1_15_47.md diff --git a/Packs/CommonScripts/ReleaseNotes/1_15_47.md b/Packs/CommonScripts/ReleaseNotes/1_15_47.md new file mode 100644 index 000000000000..615486c0b136 --- /dev/null +++ b/Packs/CommonScripts/ReleaseNotes/1_15_47.md @@ -0,0 +1,7 @@ + +#### Scripts + +##### ParseEmailFilesV2 + +- Fixed an issue where parsing p7m files fails to remove signature. +- Updated the Docker image to: *demisto/parse-emails:1.0.0.107885*. diff --git a/Packs/CommonScripts/Scripts/ParseEmailFilesV2/ParseEmailFilesV2.yml b/Packs/CommonScripts/Scripts/ParseEmailFilesV2/ParseEmailFilesV2.yml index ce977a199868..0a8cf8e955fd 100644 --- a/Packs/CommonScripts/Scripts/ParseEmailFilesV2/ParseEmailFilesV2.yml +++ b/Packs/CommonScripts/Scripts/ParseEmailFilesV2/ParseEmailFilesV2.yml @@ -116,4 +116,4 @@ type: python fromversion: 5.0.0 tests: - ParseEmailFilesV2-test -dockerimage: demisto/parse-emails:1.0.0.106927 +dockerimage: demisto/parse-emails:1.0.0.107885 diff --git a/Packs/CommonScripts/pack_metadata.json b/Packs/CommonScripts/pack_metadata.json index e361fe5c184a..54905d0635a6 100644 --- a/Packs/CommonScripts/pack_metadata.json +++ b/Packs/CommonScripts/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Common Scripts", "description": "Frequently used scripts pack.", "support": "xsoar", - "currentVersion": "1.15.46", + "currentVersion": "1.15.47", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Tests/docker_native_image_config.json b/Tests/docker_native_image_config.json index 75566a0015a7..31c804b0aca0 100644 --- a/Tests/docker_native_image_config.json +++ b/Tests/docker_native_image_config.json @@ -144,6 +144,15 @@ "native:candidate" ] }, + { + "id":"ParseEmailFilesV2", + "reason":"Script uses an updated openssl lib than native, see CIAC-11469", + "ignored_native_images":[ + "native:8.6", + "native:dev", + "native:candidate" + ] + }, { "id": "Github Feed", "reason": "update docker image", From 1243a19b77d0364ae608249f096c8ed3517fe1f4 Mon Sep 17 00:00:00 2001 From: Jacob Levy <129657918+jlevypaloalto@users.noreply.github.com> Date: Fri, 9 Aug 2024 19:11:38 +0300 Subject: [PATCH 03/14] [Cortex XDR - IR] Fix multiple incidents pulled (#35811) * init * init * RN --- Packs/CortexXDR/Integrations/CortexXDRIR/CortexXDRIR.py | 2 +- .../CortexXDR/Integrations/CortexXDRIR/CortexXDRIR_test.py | 4 ++-- Packs/CortexXDR/ReleaseNotes/6_1_62.md | 6 ++++++ Packs/CortexXDR/pack_metadata.json | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 Packs/CortexXDR/ReleaseNotes/6_1_62.md diff --git a/Packs/CortexXDR/Integrations/CortexXDRIR/CortexXDRIR.py b/Packs/CortexXDR/Integrations/CortexXDRIR/CortexXDRIR.py index ba1c68ab6f54..501d61bf4947 100644 --- a/Packs/CortexXDR/Integrations/CortexXDRIR/CortexXDRIR.py +++ b/Packs/CortexXDR/Integrations/CortexXDRIR/CortexXDRIR.py @@ -1161,7 +1161,7 @@ def fetch_incidents(client, first_fetch_time, integration_instance, exclude_arti next_run['incidents_from_previous_run'] = [] next_run['time'] = last_fetch - next_run['incidents_at_last_timestamp'] = new_incidents_at_last_timestamp + next_run['incidents_at_last_timestamp'] = new_incidents_at_last_timestamp or last_run.get('incidents_at_last_timestamp', []) return next_run, incidents diff --git a/Packs/CortexXDR/Integrations/CortexXDRIR/CortexXDRIR_test.py b/Packs/CortexXDR/Integrations/CortexXDRIR/CortexXDRIR_test.py index 6da27f6d918e..7207420ba936 100644 --- a/Packs/CortexXDR/Integrations/CortexXDRIR/CortexXDRIR_test.py +++ b/Packs/CortexXDR/Integrations/CortexXDRIR/CortexXDRIR_test.py @@ -1639,7 +1639,7 @@ def get_multiple_incidents_extra_data(self, gte_creation_time_milliseconds=0, li assert 'XDR Incident 4' in result_2[1]['name'] assert last_run['incidents_at_last_timestamp'] == ['4'] - # run empty test and assert last_run['incidents_at_last_timestamp'] is empty + # run empty test and assert last_run['incidents_at_last_timestamp'] stays the same last_run, result_2 = fetch_incidents( client=mock_client, first_fetch_time='3 days', @@ -1649,4 +1649,4 @@ def get_multiple_incidents_extra_data(self, gte_creation_time_milliseconds=0, li max_fetch=0, ) - assert last_run['incidents_at_last_timestamp'] == [] + assert last_run['incidents_at_last_timestamp'] == ['4'] diff --git a/Packs/CortexXDR/ReleaseNotes/6_1_62.md b/Packs/CortexXDR/ReleaseNotes/6_1_62.md new file mode 100644 index 000000000000..9a62c9fde864 --- /dev/null +++ b/Packs/CortexXDR/ReleaseNotes/6_1_62.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Palo Alto Networks Cortex XDR - Investigation and Response + +- Fixed an issue in which an incident was fetched multiple times. diff --git a/Packs/CortexXDR/pack_metadata.json b/Packs/CortexXDR/pack_metadata.json index ee1038fa4a90..3c2e5f4f234e 100644 --- a/Packs/CortexXDR/pack_metadata.json +++ b/Packs/CortexXDR/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Cortex XDR by Palo Alto Networks", "description": "Automates Cortex XDR incident response, and includes custom Cortex XDR incident views and layouts to aid analyst investigations.", "support": "xsoar", - "currentVersion": "6.1.61", + "currentVersion": "6.1.62", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From dfbc41dc0bda39d4cf270724df1b29a0426a7a02 Mon Sep 17 00:00:00 2001 From: Moshe Eichler <78307768+MosheEichler@users.noreply.github.com> Date: Sun, 11 Aug 2024 10:38:36 +0300 Subject: [PATCH 04/14] fixed the searchAfter in the searchIndicators function (#35795) --- Tests/demistomock/demistomock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/demistomock/demistomock.py b/Tests/demistomock/demistomock.py index b4689d34c018..f56355da5836 100644 --- a/Tests/demistomock/demistomock.py +++ b/Tests/demistomock/demistomock.py @@ -1074,7 +1074,7 @@ def searchIndicators(fromDate='', query='', size=100, page=0, toDate='', value=' page (int): Response paging (Default value = 0) todate (str): The end date to search until to (Default value = '') value (str): The indicator value to search (Default value = '') - searchAfter (str): Use the last searchIndicators() outputs for search batch (Default value = None) + searchAfter (list): Use the last searchIndicators() outputs for search batch (Default value = None) populateFields (str): Comma separated fields to filter (e.g. "value,type") Returns: From 0c8bd66d324d2b1f0b1f41638a915d9999e8a250 Mon Sep 17 00:00:00 2001 From: Ko Ga <85439776+kgal-pan@users.noreply.github.com> Date: Sun, 11 Aug 2024 11:26:51 +0300 Subject: [PATCH 05/14] Remove `mypy` Global Ignores (#35643) * Remove mypy global ignores * update docker images * update docker images p2 * update rn * update rn p2 * add rn to gcp iam * Bump pack from version CommonScripts to 1.15.40. * install missing my dep types-request * update mispv3 docker image add missing mypy deps * revert mispv3 docker image * Bump pack from version CommonScripts to 1.15.41. * Bump pack from version Base to 1.34.32. * add missing type hints * Bump pack from version CommonScripts to 1.15.42. * Bump pack from version Base to 1.34.33. * revert precommit template * Bump pack from version Base to 1.34.34. * Bump pack from version CommonScripts to 1.15.43. * Bump pack from version CommonScripts to 1.15.44. * fix rn * Bump pack from version CommonScripts to 1.15.45. * Bump pack from version AzureDataExplorer to 1.3.2. * Bump pack from version AzureDevOps to 1.4.2. * Bump pack from version CommonScripts to 1.15.46. * Bump pack from version CommonScripts to 1.15.47. * Bump pack from version CommonScripts to 1.15.48. --------- Co-authored-by: Content Bot --- .../AzureDataExplorer/AzureDataExplorer.py | 32 +- Packs/AzureDataExplorer/ReleaseNotes/1_3_2.md | 6 + Packs/AzureDataExplorer/pack_metadata.json | 2 +- .../Integrations/AzureDevOps/AzureDevOps.py | 2 +- Packs/AzureDevOps/ReleaseNotes/1_4_2.md | 6 + Packs/AzureDevOps/pack_metadata.json | 2 +- Packs/Base/ReleaseNotes/1_34_31.md | 2 +- Packs/Base/ReleaseNotes/1_34_34.md | 6 + .../FindSimilarIncidentsByText.py | 1 - Packs/Base/pack_metadata.json | 2 +- Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.py | 651 +++++++++--------- Packs/BmcITSM/ReleaseNotes/1_0_24.md | 6 + Packs/BmcITSM/pack_metadata.json | 2 +- .../CheckPointDome9/CheckPointDome9.py | 296 ++++---- .../CheckPointDome9/CheckPointDome9.yml | 2 +- .../CheckPointDome9/CheckPointDome9_test.py | 3 +- Packs/CheckPointDome9/ReleaseNotes/1_0_17.md | 6 + Packs/CheckPointDome9/pack_metadata.json | 2 +- Packs/CommonScripts/ReleaseNotes/1_15_48.md | 6 + .../FindSimilarIncidentsV2.py | 2 - Packs/CommonScripts/pack_metadata.json | 2 +- .../CyrenInboxSecurity/ReleaseNotes/1_1_13.md | 9 + .../CyrenFindSimilarIncidents.py | 3 - .../CyrenShowThreatIndicators.py | 3 - Packs/CyrenInboxSecurity/pack_metadata.json | 2 +- .../ForescoutEyeInspect.py | 197 +++--- .../ForescoutEyeInspect.yml | 2 +- .../ReleaseNotes/1_0_22.md | 6 + Packs/ForescoutEyeInspect/pack_metadata.json | 2 +- .../Integrations/FortiSIEMV2/FortiSIEMV2.py | 176 ++--- .../Integrations/FortiSIEMV2/FortiSIEMV2.yml | 2 +- Packs/FortiSIEM/ReleaseNotes/2_0_36.md | 6 + Packs/FortiSIEM/pack_metadata.json | 2 +- Packs/GCP-IAM/Integrations/GCPIAM/GCPIAM.py | 2 +- Packs/GCP-IAM/Integrations/GCPIAM/GCPIAM.yml | 2 +- Packs/GCP-IAM/ReleaseNotes/1_0_26.md | 6 + Packs/GCP-IAM/pack_metadata.json | 2 +- .../IronDefense/IronDefense_test.py | 65 +- Packs/MISP/Integrations/MISPV3/MISPV3.py | 9 +- Packs/MISP/Integrations/MISPV3/MISPV3_test.py | 2 +- Packs/MISP/Integrations/MISP_V2/MISP_V2.py | 2 - Packs/MISP/ReleaseNotes/2_1_44.md | 9 + Packs/MISP/pack_metadata.json | 2 +- .../NetskopeAPIv1/NetskopeAPIv1.py | 112 +-- .../NetskopeAPIv1/NetskopeAPIv1.yml | 2 +- Packs/Netskope/ReleaseNotes/3_3_11.md | 6 + Packs/Netskope/pack_metadata.json | 2 +- .../Tenable_io/Tenable_io_test.py | 1 - 48 files changed, 876 insertions(+), 797 deletions(-) create mode 100644 Packs/AzureDataExplorer/ReleaseNotes/1_3_2.md create mode 100644 Packs/AzureDevOps/ReleaseNotes/1_4_2.md create mode 100644 Packs/Base/ReleaseNotes/1_34_34.md create mode 100644 Packs/BmcITSM/ReleaseNotes/1_0_24.md create mode 100644 Packs/CheckPointDome9/ReleaseNotes/1_0_17.md create mode 100644 Packs/CommonScripts/ReleaseNotes/1_15_48.md create mode 100644 Packs/CyrenInboxSecurity/ReleaseNotes/1_1_13.md create mode 100644 Packs/ForescoutEyeInspect/ReleaseNotes/1_0_22.md create mode 100644 Packs/FortiSIEM/ReleaseNotes/2_0_36.md create mode 100644 Packs/GCP-IAM/ReleaseNotes/1_0_26.md create mode 100644 Packs/MISP/ReleaseNotes/2_1_44.md create mode 100644 Packs/Netskope/ReleaseNotes/3_3_11.md diff --git a/Packs/AzureDataExplorer/Integrations/AzureDataExplorer/AzureDataExplorer.py b/Packs/AzureDataExplorer/Integrations/AzureDataExplorer/AzureDataExplorer.py index 2742c91d99c8..5f8c310408a1 100644 --- a/Packs/AzureDataExplorer/Integrations/AzureDataExplorer/AzureDataExplorer.py +++ b/Packs/AzureDataExplorer/Integrations/AzureDataExplorer/AzureDataExplorer.py @@ -1,5 +1,3 @@ -# type: ignore -# Disable insecure warnings from CommonServerPython import * ''' IMPORTS ''' @@ -257,12 +255,18 @@ def search_queries_list_command(client: DataExplorerClient, args: dict[str, Any] page_size = arg_to_number(args.get('page_size')) limit = arg_to_number(args.get('limit', DEFAULT_LIMIT)) client_activity_id = str(args.get('client_activity_id', '')) - validate_list_command_arguments(page, page_size, limit) + validate_list_command_arguments(page, page_size, limit) # type: ignore[arg-type] response = client.search_queries_list_request( database_name, client_activity_id) - return retrieve_command_results_of_list_commands(response, 'List of Completed Search Queries', - page, page_size, limit, 'AzureDataExplorer.SearchQuery') + return retrieve_command_results_of_list_commands( + response, + 'List of Completed Search Queries', + page, # type: ignore[arg-type] + page_size, # type: ignore[arg-type] + limit, # type: ignore[arg-type] + 'AzureDataExplorer.SearchQuery' + ) def running_search_queries_list_command(client: DataExplorerClient, args: dict[str, Any]) -> CommandResults: @@ -281,12 +285,18 @@ def running_search_queries_list_command(client: DataExplorerClient, args: dict[s limit = arg_to_number(args.get('limit', DEFAULT_LIMIT)) client_activity_id = str(args.get('client_activity_id', '')) - validate_list_command_arguments(page, page_size, limit) + validate_list_command_arguments(page, page_size, limit) # type: ignore[arg-type] response = client.running_search_queries_list_request( database_name, client_activity_id) - return retrieve_command_results_of_list_commands(response, 'List of Currently running Search Queries', - page, page_size, limit, 'AzureDataExplorer.RunningSearchQuery') + return retrieve_command_results_of_list_commands( + response, + 'List of Currently running Search Queries', + page, # type: ignore[arg-type] + page_size, # type: ignore[arg-type] + limit, # type: ignore[arg-type] + 'AzureDataExplorer.RunningSearchQuery' + ) def running_search_query_cancel_command(client: DataExplorerClient, args: dict[str, Any]) -> \ @@ -461,7 +471,7 @@ def retrieve_common_request_body(database_name: str, query: str, "csl": query } if properties: - data['properties'] = properties + data['properties'] = properties # type: ignore[assignment] return data @@ -587,8 +597,8 @@ def main() -> None: demisto.debug(f'Command being called is {command}') try: - requests.packages.urllib3.disable_warnings() - client: DataExplorerClient = DataExplorerClient(cluster_url, client_id, client_activity_prefix, + requests.packages.urllib3.disable_warnings() # type: ignore[attr-defined] + client: DataExplorerClient = DataExplorerClient(cluster_url, client_id, client_activity_prefix, # type: ignore[arg-type] verify_certificate, proxy, connection_type, tenant_id, enc_key, auth_code, redirect_uri) diff --git a/Packs/AzureDataExplorer/ReleaseNotes/1_3_2.md b/Packs/AzureDataExplorer/ReleaseNotes/1_3_2.md new file mode 100644 index 000000000000..61d7022c3a3c --- /dev/null +++ b/Packs/AzureDataExplorer/ReleaseNotes/1_3_2.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Azure Data Explorer + +- Maintenance and stability enhancements. diff --git a/Packs/AzureDataExplorer/pack_metadata.json b/Packs/AzureDataExplorer/pack_metadata.json index e72012f2dbc0..991f98e41cae 100644 --- a/Packs/AzureDataExplorer/pack_metadata.json +++ b/Packs/AzureDataExplorer/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Azure Data Explorer", "description": "Use Azure Data Explorer integration to collect and analyze data inside clusters of Azure Data Explorer and manage search queries.", "support": "xsoar", - "currentVersion": "1.3.1", + "currentVersion": "1.3.2", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/AzureDevOps/Integrations/AzureDevOps/AzureDevOps.py b/Packs/AzureDevOps/Integrations/AzureDevOps/AzureDevOps.py index a673ec52170d..ec3982072868 100644 --- a/Packs/AzureDevOps/Integrations/AzureDevOps/AzureDevOps.py +++ b/Packs/AzureDevOps/Integrations/AzureDevOps/AzureDevOps.py @@ -3,7 +3,7 @@ import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 -# type: ignore + from MicrosoftApiModule import * # noqa: E402 import copy from requests import Response diff --git a/Packs/AzureDevOps/ReleaseNotes/1_4_2.md b/Packs/AzureDevOps/ReleaseNotes/1_4_2.md new file mode 100644 index 000000000000..b604c1ed06be --- /dev/null +++ b/Packs/AzureDevOps/ReleaseNotes/1_4_2.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### AzureDevOps + +- Maintenance and stability enhancements. diff --git a/Packs/AzureDevOps/pack_metadata.json b/Packs/AzureDevOps/pack_metadata.json index e15d328afd43..9b3d4e3e91b8 100644 --- a/Packs/AzureDevOps/pack_metadata.json +++ b/Packs/AzureDevOps/pack_metadata.json @@ -2,7 +2,7 @@ "name": "AzureDevOps", "description": "Create and manage Git repositories in Azure DevOps Services.", "support": "xsoar", - "currentVersion": "1.4.1", + "currentVersion": "1.4.2", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Base/ReleaseNotes/1_34_31.md b/Packs/Base/ReleaseNotes/1_34_31.md index 41ae70613f92..fa06a17c3fad 100644 --- a/Packs/Base/ReleaseNotes/1_34_31.md +++ b/Packs/Base/ReleaseNotes/1_34_31.md @@ -18,4 +18,4 @@ - Updated the Docker image to: *demisto/ml:1.0.0.105874*. ##### DBotPreProcessTextData -- Updated the Docker image to: *demisto/ml:1.0.0.105874*. \ No newline at end of file +- Updated the Docker image to: *demisto/ml:1.0.0.105874*. diff --git a/Packs/Base/ReleaseNotes/1_34_34.md b/Packs/Base/ReleaseNotes/1_34_34.md new file mode 100644 index 000000000000..6b166caea021 --- /dev/null +++ b/Packs/Base/ReleaseNotes/1_34_34.md @@ -0,0 +1,6 @@ + +#### Scripts + +##### FindSimilarIncidentsByText + +- Maintenance and stability enhancements. diff --git a/Packs/Base/Scripts/FindSimilarIncidentsByText/FindSimilarIncidentsByText.py b/Packs/Base/Scripts/FindSimilarIncidentsByText/FindSimilarIncidentsByText.py index 4d381231df47..56661c2f14d5 100644 --- a/Packs/Base/Scripts/FindSimilarIncidentsByText/FindSimilarIncidentsByText.py +++ b/Packs/Base/Scripts/FindSimilarIncidentsByText/FindSimilarIncidentsByText.py @@ -1,4 +1,3 @@ -# type: ignore import dateutil.parser from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import linear_kernel diff --git a/Packs/Base/pack_metadata.json b/Packs/Base/pack_metadata.json index 9d147bce86bd..ec6704e5d622 100644 --- a/Packs/Base/pack_metadata.json +++ b/Packs/Base/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Base", "description": "The base pack for Cortex XSOAR.", "support": "xsoar", - "currentVersion": "1.34.33", + "currentVersion": "1.34.34", "author": "Cortex XSOAR", "serverMinVersion": "6.0.0", "url": "https://www.paloaltonetworks.com/cortex", diff --git a/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.py b/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.py index 29690795fd97..830f929b7858 100644 --- a/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.py +++ b/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.py @@ -1,7 +1,6 @@ import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 -# type: ignore -# mypy: ignore-errors + from copy import deepcopy from collections.abc import Callable @@ -281,7 +280,7 @@ TICKET_INCIDENT_TYPES = [ "BMC Change-Request", "BMC Incident", - "BMC Problem – Known Error", + "BMC Problem - Known Error", "BMC Problem Investigation incident", "BMC Service Request", "BMC Task", @@ -293,7 +292,7 @@ CHANGE_REQUEST: "BMC Change-Request", INCIDENT: "BMC Incident", PROBLEM_INVESTIGATION: "BMC Problem Investigation incident", - KNOWN_ERROR: "BMC Problem – Known Error", + KNOWN_ERROR: "BMC Problem - Known Error", TASK: "BMC Task", WORK_ORDER: "BMC Work Order", } @@ -1478,7 +1477,7 @@ def list_command( Returns: CommandResults: Command reuslts. """ - query: str = args.get("query") + query: str = args.get("query") # type: ignore[assignment] page = arg_to_number(args.get("page")) page_size = arg_to_number(args.get("page_size")) limit = arg_to_number(args.get("limit")) @@ -1490,7 +1489,7 @@ def list_command( response = client.list_request(form_name, query_with_filtering if query_with_filtering else None) - relevant_records, header_suffix = get_paginated_records_with_hr(response.get("entries"), limit, + relevant_records, header_suffix = get_paginated_records_with_hr(response.get("entries"), limit, # type: ignore[arg-type] page, page_size) outputs = format_command_output(relevant_records, context_output_mapper, arranger) readable_output = tableToMarkdown( @@ -1781,30 +1780,30 @@ def service_request_create_command(client: Client, args: Dict[str, Any]) -> Comm last_name = args.get("last_name") login_id = args.get("login_id") - additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), + additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), # type: ignore[arg-type] "additional_fields") service_request_definition_params = extract_args_from_additional_fields_arg( - args.get("service_request_definition_params"), + args.get("service_request_definition_params"), # type: ignore[arg-type] "service_request_definition_params", ) validate_related_arguments_provided(first_name=first_name, last_name=last_name, login_id=login_id) - response = client.create_service_request_request( + response = client.create_service_request_request( # type: ignore[arg-type,call-arg] srd_instance_id, - summary, - urgency, - impact, - first_name, - last_name, - login_id, - status, + summary, # type: ignore[arg-type] + urgency, # type: ignore[arg-type] + impact, # type: ignore[arg-type] + first_name, # type: ignore[arg-type] + last_name, # type: ignore[arg-type] + login_id, # type: ignore[arg-type] + status, # type: ignore[arg-type] **additional_fields, **service_request_definition_params, ) - outputs = format_create_ticket_outputs(response.get("values")) + outputs = format_create_ticket_outputs(response.get("values")) # type: ignore[arg-type] readable_output = tableToMarkdown("Service Request successfully Created", outputs, headerTransform=pascalToSpace) @@ -1843,28 +1842,28 @@ def service_request_update_command(client: Client, args: Dict[str, Any]) -> Comm site_group = args.get("site_group") region = args.get("region") site = args.get("site") - additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), + additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), # type: ignore[arg-type] "additional_fields") - formatted_service_request_id = format_ticket_request_id(service_request_id) + formatted_service_request_id = format_ticket_request_id(service_request_id) # type: ignore[arg-type] validate_related_arguments_provided(status=status, status_reason=status_reason) validate_related_arguments_provided(customer_first_name=customer_first_name, customer_last_name=customer_last_name) - client.service_request_update_request( + client.service_request_update_request( # type: ignore[arg-type,call-arg] formatted_service_request_id, summary, - status, - urgency, - impact, - customer_first_name, - customer_last_name, + status, # type: ignore[arg-type] + urgency, # type: ignore[arg-type] + impact, # type: ignore[arg-type] + customer_first_name, # type: ignore[arg-type] + customer_last_name, # type: ignore[arg-type] location_company, - site_group, - region, - site, - assignee, - status_reason, + site_group, # type: ignore[arg-type] + region, # type: ignore[arg-type] + site, # type: ignore[arg-type] + assignee, # type: ignore[arg-type] + status_reason, # type: ignore[arg-type] **additional_fields, ) command_results = CommandResults( @@ -1903,7 +1902,7 @@ def incident_create_command(client: Client, args: Dict[str, Any]) -> CommandResu site = args.get("site") region = args.get("region") - additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), + additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), # type: ignore[arg-type] "additional_fields") validate_related_arguments_provided(assignee_login_id=assignee_login_id, assignee=assignee) @@ -1912,32 +1911,32 @@ def incident_create_command(client: Client, args: Dict[str, Any]) -> CommandResu service_type=service_type, reported_source=reported_source) - response = client.create_incident_request( - template_id, - first_name, - last_name, - summary, - urgency=urgency, - impact=impact, - status=status, - service_type=service_type, - reported_source=reported_source, - details=details, - company=company, - assigned_support_organization=assigned_support_organization, - assigned_support_company=assigned_support_company, - assigned_support_group_name=assigned_support_group_name, - assignee=assignee, - assignee_login_id=assignee_login_id, - site_group=site_group, - site=site, - region=region, + response = client.create_incident_request( # type: ignore[arg-type,call-arg] + template_id, # type: ignore[arg-type] + first_name, # type: ignore[arg-type] + last_name, # type: ignore[arg-type] + summary, # type: ignore[arg-type] + urgency=urgency, # type: ignore[arg-type] + impact=impact, # type: ignore[arg-type] + status=status, # type: ignore[arg-type] + service_type=service_type, # type: ignore[arg-type] + reported_source=reported_source, # type: ignore[arg-type] + details=details, # type: ignore[arg-type] + company=company, # type: ignore[arg-type] + assigned_support_organization=assigned_support_organization, # type: ignore[arg-type] + assigned_support_company=assigned_support_company, # type: ignore[arg-type] + assigned_support_group_name=assigned_support_group_name, # type: ignore[arg-type] + assignee=assignee, # type: ignore[arg-type] + assignee_login_id=assignee_login_id, # type: ignore[arg-type] + site_group=site_group, # type: ignore[arg-type] + site=site, # type: ignore[arg-type] + region=region, # type: ignore[arg-type] **additional_fields, ) incident_request_id = extract_ticket_request_id_following_create( client, INCIDENT, response) # The right request ID is not retrieved by the create endpoint. - outputs = format_create_ticket_outputs(response.get("values")) + outputs = format_create_ticket_outputs(response.get("values")) # type: ignore[arg-type] outputs["RequestID"] = incident_request_id readable_output = tableToMarkdown("Incident ticket successfully Created", @@ -1988,7 +1987,7 @@ def incident_update_command(client: Client, args: Dict[str, Any]) -> CommandResu resolution = args.get("resolution") status_reason = args.get("status_reason") - additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), + additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), # type: ignore[arg-type] "additional_fields") validate_related_arguments_provided(first_name=first_name, last_name=last_name) @@ -1997,28 +1996,28 @@ def incident_update_command(client: Client, args: Dict[str, Any]) -> CommandResu status_reason=status_reason, resolution=resolution) - client.update_incident_request( - format_ticket_request_id(incident_request_id), - first_name, - last_name, - summary, - urgency=urgency, - impact=impact, - status=status, - service_type=service_type, - reported_source=reported_source, - details=details, - company=company, - assigned_support_organization=assigned_support_organization, - assigned_support_company=assigned_support_company, - assigned_support_group_name=assigned_support_group_name, - assignee=assignee, - assignee_login_id=assignee_login_id, - site_group=site_group, - site=site, - region=region, - status_reason=status_reason, - resolution=resolution, + client.update_incident_request( # type: ignore[arg-type,call-arg] + format_ticket_request_id(incident_request_id), # type: ignore[arg-type] + first_name, # type: ignore[arg-type] + last_name, # type: ignore[arg-type] + summary, # type: ignore[arg-type] + urgency=urgency, # type: ignore[arg-type] + impact=impact, # type: ignore[arg-type] + status=status, # type: ignore[arg-type] + service_type=service_type, # type: ignore[arg-type] + reported_source=reported_source, # type: ignore[arg-type] + details=details, # type: ignore[arg-type] + company=company, # type: ignore[arg-type] + assigned_support_organization=assigned_support_organization, # type: ignore[arg-type] + assigned_support_company=assigned_support_company, # type: ignore[arg-type] + assigned_support_group_name=assigned_support_group_name, # type: ignore[arg-type] + assignee=assignee, # type: ignore[arg-type] + assignee_login_id=assignee_login_id, # type: ignore[arg-type] + site_group=site_group, # type: ignore[arg-type] + site=site, # type: ignore[arg-type] + region=region, # type: ignore[arg-type] + status_reason=status_reason, # type: ignore[arg-type] + resolution=resolution, # type: ignore[arg-type] **additional_fields, ) @@ -2051,7 +2050,7 @@ def change_request_create_command(client: Client, args: Dict[str, Any]) -> Comma risk_level = args.get("risk_level") change_type = args.get("change_type") location_company = args.get("location_company") - additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), + additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), # type: ignore[arg-type] "additional_fields") if not template_id: validate_related_arguments_provided( @@ -2061,24 +2060,24 @@ def change_request_create_command(client: Client, args: Dict[str, Any]) -> Comma location_company=location_company, ) - response = client.change_request_create_request( - template_id, - first_name, - last_name, - summary, - location_company, - urgency=urgency, - impact=impact, - status=status, - risk_level=risk_level, - change_type=change_type, - customer_first_name=customer_first_name, - customer_last_name=customer_last_name, - priority=priority, + response = client.change_request_create_request( # type: ignore[arg-type,call-arg] + template_id, # type: ignore[arg-type] + first_name, # type: ignore[arg-type] + last_name, # type: ignore[arg-type] + summary, # type: ignore[arg-type] + location_company, # type: ignore[arg-type] + urgency=urgency, # type: ignore[arg-type] + impact=impact, # type: ignore[arg-type] + status=status, # type: ignore[arg-type] + risk_level=risk_level, # type: ignore[arg-type] + change_type=change_type, # type: ignore[arg-type] + customer_first_name=customer_first_name, # type: ignore[arg-type] + customer_last_name=customer_last_name, # type: ignore[arg-type] + priority=priority, # type: ignore[arg-type] **additional_fields, ) - outputs = format_create_ticket_outputs(response.get("values")) + outputs = format_create_ticket_outputs(response.get("values")) # type: ignore[arg-type] readable_output = tableToMarkdown( "Change Request ticket successfully Created", @@ -2130,37 +2129,37 @@ def change_request_update_command(client: Client, args: Dict[str, Any]) -> Comma company = args.get("company") region = args.get("region") - additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), + additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), # type: ignore[arg-type] "additional_fields") validate_related_arguments_provided(first_name=first_name, last_name=last_name) validate_related_arguments_provided(status=status, status_reason=status_reason) - client.change_request_update_request( - format_ticket_request_id(change_request_id), - first_name, - last_name, - summary, - location_company, - urgency=urgency, - impact=impact, - status=status, - risk_level=risk_level, - change_type=change_type, - customer_first_name=customer_first_name, - customer_last_name=customer_last_name, - priority=priority, - details=details, - status_reason=status_reason, - organization=organization, - department=department, - site_group=site_group, - site=site, - support_organization=support_organization, - support_group_name=support_group_name, - company=company, - region=region, + client.change_request_update_request( # type: ignore[arg-type,call-arg] + format_ticket_request_id(change_request_id), # type: ignore[arg-type] + first_name, # type: ignore[arg-type] + last_name, # type: ignore[arg-type] + summary, # type: ignore[arg-type] + location_company, # type: ignore[arg-type] + urgency=urgency, # type: ignore[arg-type] + impact=impact, # type: ignore[arg-type] + status=status, # type: ignore[arg-type] + risk_level=risk_level, # type: ignore[arg-type] + change_type=change_type, # type: ignore[arg-type] + customer_first_name=customer_first_name, # type: ignore[arg-type] + customer_last_name=customer_last_name, # type: ignore[arg-type] + priority=priority, # type: ignore[arg-type] + details=details, # type: ignore[arg-type] + status_reason=status_reason, # type: ignore[arg-type] + organization=organization, # type: ignore[arg-type] + department=department, # type: ignore[arg-type] + site_group=site_group, # type: ignore[arg-type] + site=site, # type: ignore[arg-type] + support_organization=support_organization, # type: ignore[arg-type] + support_group_name=support_group_name, # type: ignore[arg-type] + company=company, # type: ignore[arg-type] + region=region, # type: ignore[arg-type] **additional_fields, ) @@ -2200,40 +2199,40 @@ def task_create_command(client: Client, args: Dict[str, Any]) -> CommandResults: assigned_support_group_name = args.get("assigned_support_group") assignee = args.get("assignee") company = args.get("location_company") - root_ticket_type = TICKET_TYPE_TO_DELETE_FORM[args.get("root_ticket_type")] - scedulded_start_date: datetime = arg_to_datetime(args.get("scedulded_start_date")) - scedulded_end_date: datetime = arg_to_datetime(args.get("scedulded_end_date")) + root_ticket_type = TICKET_TYPE_TO_DELETE_FORM[args.get("root_ticket_type")] # type: ignore[index] + scedulded_start_date: datetime = arg_to_datetime(args.get("scedulded_start_date")) # type: ignore[assignment] + scedulded_end_date: datetime = arg_to_datetime(args.get("scedulded_end_date")) # type: ignore[assignment] - additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), + additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), # type: ignore[arg-type] "additional_fields") - parent_ticket = get_ticket(client, args.get("root_ticket_type"), root_request_id) - response = client.create_task_request( - template_id, - parent_ticket.get("InstanceId"), - root_request_name or parent_ticket.get("DisplayID"), - parent_ticket.get("DisplayID"), - first_name, - last_name, - summary, - status=status, - impact=impact, - urgency=urgency, - priority=priority, - details=details, - task_type=task_type, - support_company=support_company, - assignee=assignee, - location_company=company, - root_request_mode=root_request_mode, + parent_ticket = get_ticket(client, args.get("root_ticket_type"), root_request_id) # type: ignore[arg-type] + response = client.create_task_request( # type: ignore[arg-type,call-arg] + template_id, # type: ignore[arg-type] + parent_ticket.get("InstanceId"), # type: ignore[arg-type] + root_request_name or parent_ticket.get("DisplayID"), # type: ignore[arg-type] + parent_ticket.get("DisplayID"), # type: ignore[arg-type] + first_name, # type: ignore[arg-type] + last_name, # type: ignore[arg-type] + summary, # type: ignore[arg-type] + status=status, # type: ignore[arg-type] + impact=impact, # type: ignore[arg-type] + urgency=urgency, # type: ignore[arg-type] + priority=priority, # type: ignore[arg-type] + details=details, # type: ignore[arg-type] + task_type=task_type, # type: ignore[arg-type] + support_company=support_company, # type: ignore[arg-type] + assignee=assignee, # type: ignore[arg-type] + location_company=company, # type: ignore[arg-type] + root_request_mode=root_request_mode, # type: ignore[arg-type] root_ticket_type=root_ticket_type, - assigned_support_group_name=assigned_support_group_name, - assigned_support_organization=assigned_support_organization, - scedulded_start_date=scedulded_start_date.isoformat() if scedulded_start_date else None, - scedulded_end_date=scedulded_end_date.isoformat() if scedulded_end_date else None, + assigned_support_group_name=assigned_support_group_name, # type: ignore[arg-type] + assigned_support_organization=assigned_support_organization, # type: ignore[arg-type] + scedulded_start_date=scedulded_start_date.isoformat() if scedulded_start_date else None, # type: ignore[arg-type] + scedulded_end_date=scedulded_end_date.isoformat() if scedulded_end_date else None, # type: ignore[arg-type] **additional_fields, ) - outputs = format_create_ticket_outputs(response.get("values")) + outputs = format_create_ticket_outputs(response.get("values")) # type: ignore[arg-type] outputs["RequestID"] = outputs["DisplayID"] readable_output = tableToMarkdown("Task ticket successfully Created.", outputs, @@ -2281,32 +2280,32 @@ def task_update_command(client: Client, args: Dict[str, Any]) -> CommandResults: assigned_support_organization = args.get("assigned_support_organization") assigned_support_group_name = args.get("assigned_group") assignee = args.get("assignee") - scedulded_start_date: datetime = arg_to_datetime(args.get("scedulded_start_date")) - schedulded_end_date: datetime = arg_to_datetime(args.get("schedulded_end_date")) + scedulded_start_date: datetime = arg_to_datetime(args.get("scedulded_start_date")) # type: ignore[assignment] + schedulded_end_date: datetime = arg_to_datetime(args.get("schedulded_end_date")) # type: ignore[assignment] - additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), + additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), # type: ignore[arg-type] "additional_fields") - client.update_task_request( - format_ticket_request_id(task_id), - root_request_name, - summary=summary, - status=status, - priority=priority, - details=details, - task_type=task_type, + client.update_task_request( # type: ignore[arg-type,call-arg] + format_ticket_request_id(task_id), # type: ignore[arg-type] + root_request_name, # type: ignore[arg-type] + summary=summary, # type: ignore[arg-type] + status=status, # type: ignore[arg-type] + priority=priority, # type: ignore[arg-type] + details=details, # type: ignore[arg-type] + task_type=task_type, # type: ignore[arg-type] organization=organization, department=department, site_group=site_group, site=site, - assigned_support_company=support_company, - assignee=assignee, - company=company, - location_company=location_company, - status_reason=status_reason, - assigned_support_organization=assigned_support_organization, - assigned_support_group_name=assigned_support_group_name, - scedulded_start_date=scedulded_start_date.isoformat() if scedulded_start_date else None, - schedulded_end_date=schedulded_end_date.isoformat if schedulded_end_date else None, + assigned_support_company=support_company, # type: ignore[arg-type] + assignee=assignee, # type: ignore[arg-type] + company=company, # type: ignore[arg-type] + location_company=location_company, # type: ignore[arg-type] + status_reason=status_reason, # type: ignore[arg-type] + assigned_support_organization=assigned_support_organization, # type: ignore[arg-type] + assigned_support_group_name=assigned_support_group_name, # type: ignore[arg-type] + scedulded_start_date=scedulded_start_date.isoformat() if scedulded_start_date else None, # type: ignore[arg-type] + schedulded_end_date=schedulded_end_date.isoformat if schedulded_end_date else None, # type: ignore[arg-type] **additional_fields, ) @@ -2345,11 +2344,11 @@ def problem_investigation_create_command(client: Client, args: Dict[str, Any]) - support_organization_pbm_mgr = args.get("support_organization_pbm_mgr") assignee_pbm_mgr = args.get("assignee_pbm_mgr") temporary_workaround = args.get("temporary_workaround") - target_resolution_date: datetime = arg_to_datetime(args.get("target_resolution_date")) + target_resolution_date: datetime = arg_to_datetime(args.get("target_resolution_date")) # type: ignore[assignment] resolution = args.get("resolution") investigation_justification = args.get("investigation_justification") investigation_driver = args.get("investigation_driver") - additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), + additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), # type: ignore[arg-type] "additional_fields") validate_related_arguments_provided(company=company, @@ -2368,33 +2367,33 @@ def problem_investigation_create_command(client: Client, args: Dict[str, Any]) - support_organization_pbm_mgr=support_organization_pbm_mgr, ) - response = client.create_problem_investigation_request( + response = client.create_problem_investigation_request( # type: ignore[arg-type] PROBLEM_INVESTIGATION, - summary, + summary, # type: ignore[arg-type] first_name=first_name, last_name=last_name, - urgency=urgency, - impact=impact, - status=status, - details=details, - company=company, - assigned_support_organization=assigned_support_organization, - assigned_support_company=assigned_support_company, - assigned_support_group_name=assigned_support_group_name, - assignee=assignee, - site_group=site_group, - site=site, - region=region, - assigned_group_pbm_mgr=assigned_group_pbm_mgr, - support_company_pbm_mgr=support_company_pbm_mgr, - support_organization_pbm_mgr=support_organization_pbm_mgr, - temporary_workaround=temporary_workaround, - target_resolution_date=target_resolution_date.isoformat() + urgency=urgency, # type: ignore[arg-type] + impact=impact, # type: ignore[arg-type] + status=status, # type: ignore[arg-type] + details=details, # type: ignore[arg-type] + company=company, # type: ignore[arg-type] + assigned_support_organization=assigned_support_organization, # type: ignore[arg-type] + assigned_support_company=assigned_support_company, # type: ignore[arg-type] + assigned_support_group_name=assigned_support_group_name, # type: ignore[arg-type] + assignee=assignee, # type: ignore[arg-type] + site_group=site_group, # type: ignore[arg-type] + site=site, # type: ignore[arg-type] + region=region, # type: ignore[arg-type] + assigned_group_pbm_mgr=assigned_group_pbm_mgr, # type: ignore[arg-type] + support_company_pbm_mgr=support_company_pbm_mgr, # type: ignore[arg-type] + support_organization_pbm_mgr=support_organization_pbm_mgr, # type: ignore[arg-type] + temporary_workaround=temporary_workaround, # type: ignore[arg-type] + target_resolution_date=target_resolution_date.isoformat() # type: ignore[arg-type] if target_resolution_date else None, investigation_justification=investigation_justification, investigation_driver=investigation_driver, resolution=resolution, - assignee_pbm_mgr=assignee_pbm_mgr, + assignee_pbm_mgr=assignee_pbm_mgr, # type: ignore[arg-type] **additional_fields, ) @@ -2454,10 +2453,10 @@ def problem_investigation_update_command(client: Client, args: Dict[str, Any]) - assignee_pbm_mgr = args.get("assignee_pbm_mgr") temporary_workaround = args.get("temporary_workaround") resolution = args.get("resolution") - target_resolution_date: datetime = arg_to_datetime(args.get("target_resolution_date")) + target_resolution_date: datetime = arg_to_datetime(args.get("target_resolution_date")) # type: ignore[assignment] investigation_justification = args.get("investigation_justification") investigation_driver = args.get("investigation_driver") - additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), + additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), # type: ignore[arg-type] "additional_fields") validate_related_arguments_provided(company=company, @@ -2476,34 +2475,34 @@ def problem_investigation_update_command(client: Client, args: Dict[str, Any]) - support_organization_pbm_mgr=support_organization_pbm_mgr, ) - client.update_problem_investigation_request( - format_ticket_request_id(problem_investigation_id), - first_name, - last_name, - summary, - urgency=urgency, - impact=impact, - status=status, - status_reason=status_reason, - details=details, - company=company, - assigned_support_organization=assigned_support_organization, - assigned_support_company=assigned_support_company, - assigned_support_group_name=assigned_support_group_name, - assignee=assignee, - assignee_login_id=assignee_login_id, - site_group=site_group, - site=site, - region=region, - assigned_group_pbm_mgr=assigned_group_pbm_mgr, - support_company_pbm_mgr=support_company_pbm_mgr, - support_organization_pbm_mgr=support_organization_pbm_mgr, - temporary_workaround=temporary_workaround, - resolution=resolution, - target_resolution_date=target_resolution_date.isoformat() + client.update_problem_investigation_request( # type: ignore[arg-type,call-arg] + format_ticket_request_id(problem_investigation_id), # type: ignore[arg-type] + first_name, # type: ignore[arg-type] + last_name, # type: ignore[arg-type] + summary, # type: ignore[arg-type] + urgency=urgency, # type: ignore[arg-type] + impact=impact, # type: ignore[arg-type] + status=status, # type: ignore[arg-type] + status_reason=status_reason, # type: ignore[arg-type] + details=details, # type: ignore[arg-type] + company=company, # type: ignore[arg-type] + assigned_support_organization=assigned_support_organization, # type: ignore[arg-type] + assigned_support_company=assigned_support_company, # type: ignore[arg-type] + assigned_support_group_name=assigned_support_group_name, # type: ignore[arg-type] + assignee=assignee, # type: ignore[arg-type] + assignee_login_id=assignee_login_id, # type: ignore[arg-type] + site_group=site_group, # type: ignore[arg-type] + site=site, # type: ignore[arg-type] + region=region, # type: ignore[arg-type] + assigned_group_pbm_mgr=assigned_group_pbm_mgr, # type: ignore[arg-type] + support_company_pbm_mgr=support_company_pbm_mgr, # type: ignore[arg-type] + support_organization_pbm_mgr=support_organization_pbm_mgr, # type: ignore[arg-type] + temporary_workaround=temporary_workaround, # type: ignore[arg-type] + resolution=resolution, # type: ignore[arg-type] + target_resolution_date=target_resolution_date.isoformat() # type: ignore[arg-type] if target_resolution_date else None, - investigation_justification=investigation_justification, - investigation_driver=investigation_driver, + investigation_justification=investigation_justification, # type: ignore[arg-type] + investigation_driver=investigation_driver, # type: ignore[arg-type] assignee_pbm_mgr=assignee_pbm_mgr, **additional_fields, ) @@ -2541,9 +2540,9 @@ def known_error_create_command(client: Client, args: Dict[str, Any]) -> CommandR assignee_pbm_mgr = args.get("assignee_pbm_mgr") temporary_workaround = args.get("temporary_workaround") resolution = args.get("resolution") - target_resolution_date = arg_to_datetime(args.get("target_resolution_date")).isoformat() + target_resolution_date = arg_to_datetime(args.get("target_resolution_date")).isoformat() # type: ignore[union-attr] view_access = args.get("view_access") - additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), + additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), # type: ignore[arg-type] "additional_fields") validate_related_arguments_provided( @@ -2557,29 +2556,29 @@ def known_error_create_command(client: Client, args: Dict[str, Any]) -> CommandR support_company_pbm_mgr=support_company_pbm_mgr, support_organization_pbm_mgr=support_organization_pbm_mgr, ) - response = client.create_problem_investigation_request( + response = client.create_problem_investigation_request( # type: ignore[arg-type] KNOWN_ERROR, - summary, - urgency=urgency, - impact=impact, - status=status, - details=details, - company=company, - assigned_support_organization=assigned_support_organization, - assigned_support_company=assigned_support_company, - assigned_support_group_name=assigned_support_group_name, - assignee=assignee, - site_group=site_group, - site=site, - region=region, - assigned_group_pbm_mgr=assigned_group_pbm_mgr, - support_company_pbm_mgr=support_company_pbm_mgr, - support_organization_pbm_mgr=support_organization_pbm_mgr, - temporary_workaround=temporary_workaround, + summary, # type: ignore[arg-type] + urgency=urgency, # type: ignore[arg-type] + impact=impact, # type: ignore[arg-type] + status=status, # type: ignore[arg-type] + details=details, # type: ignore[arg-type] + company=company, # type: ignore[arg-type] + assigned_support_organization=assigned_support_organization, # type: ignore[arg-type] + assigned_support_company=assigned_support_company, # type: ignore[arg-type] + assigned_support_group_name=assigned_support_group_name, # type: ignore[arg-type] + assignee=assignee, # type: ignore[arg-type] + site_group=site_group, # type: ignore[arg-type] + site=site, # type: ignore[arg-type] + region=region, # type: ignore[arg-type] + assigned_group_pbm_mgr=assigned_group_pbm_mgr, # type: ignore[arg-type] + support_company_pbm_mgr=support_company_pbm_mgr, # type: ignore[arg-type] + support_organization_pbm_mgr=support_organization_pbm_mgr, # type: ignore[arg-type] + temporary_workaround=temporary_workaround, # type: ignore[arg-type] resolution=resolution, target_resolution_date=target_resolution_date, view_access=view_access, - assignee_pbm_mgr=assignee_pbm_mgr, + assignee_pbm_mgr=assignee_pbm_mgr, # type: ignore[arg-type] **additional_fields, ) @@ -2635,8 +2634,8 @@ def known_error_update_command(client: Client, args: Dict[str, Any]) -> CommandR target_resolution_date = arg_to_datetime(args.get("target_resolution_date")) view_access = args.get("view_access") - target_resolution_date: datetime = arg_to_datetime(args.get("target_resolution_date")) - additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), + target_resolution_date: datetime = arg_to_datetime(args.get("target_resolution_date")) # type: ignore[no-redef] + additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), # type: ignore[arg-type] "additional_fields") validate_related_arguments_provided( @@ -2653,27 +2652,27 @@ def known_error_update_command(client: Client, args: Dict[str, Any]) -> CommandR validate_related_arguments_provided(status=status, status_reason=status_reason) - client.update_known_error_request( - format_ticket_request_id(known_error_id), - summary, - urgency=urgency, - impact=impact, - status=status, - details=details, - assigned_support_organization=assigned_support_organization, - assigned_support_company=assigned_support_company, - assigned_support_group_name=assigned_support_group_name, - assignee=assignee, - assigned_group_pbm_mgr=assigned_group_pbm_mgr, - support_company_pbm_mgr=support_company_pbm_mgr, - support_organization_pbm_mgr=support_organization_pbm_mgr, - target_resolution_date=target_resolution_date.isoformat() + client.update_known_error_request( # type: ignore[arg-type,call-arg] + format_ticket_request_id(known_error_id), # type: ignore[arg-type] + summary, # type: ignore[arg-type] + urgency=urgency, # type: ignore[arg-type] + impact=impact, # type: ignore[arg-type] + status=status, # type: ignore[arg-type] + details=details, # type: ignore[arg-type] + assigned_support_organization=assigned_support_organization, # type: ignore[arg-type] + assigned_support_company=assigned_support_company, # type: ignore[arg-type] + assigned_support_group_name=assigned_support_group_name, # type: ignore[arg-type] + assignee=assignee, # type: ignore[arg-type] + assigned_group_pbm_mgr=assigned_group_pbm_mgr, # type: ignore[arg-type] + support_company_pbm_mgr=support_company_pbm_mgr, # type: ignore[arg-type] + support_organization_pbm_mgr=support_organization_pbm_mgr, # type: ignore[arg-type] + target_resolution_date=target_resolution_date.isoformat() # type: ignore[arg-type] if target_resolution_date else None, - status_reason=status_reason, - assignee_pbm_mgr=assignee_pbm_mgr, - temporary_workaround=temporary_workaround, - resolution=resolution, - view_access=view_access, + status_reason=status_reason, # type: ignore[arg-type] + assignee_pbm_mgr=assignee_pbm_mgr, # type: ignore[arg-type] + temporary_workaround=temporary_workaround, # type: ignore[arg-type] + resolution=resolution, # type: ignore[arg-type] + view_access=view_access, # type: ignore[arg-type] **additional_fields, ) @@ -2767,31 +2766,31 @@ def work_order_create_command(client: Client, args: Dict[str, Any]) -> CommandRe priority = args.get("priority") work_order_type = args.get("work_order_type") location_company = args.get("location_company") - scedulded_start_date: datetime = arg_to_datetime(args.get("scedulded_start_date")) - scedulded_end_date: datetime = arg_to_datetime(args.get("scedulded_end_date")) + scedulded_start_date: datetime = arg_to_datetime(args.get("scedulded_start_date")) # type: ignore[assignment] + scedulded_end_date: datetime = arg_to_datetime(args.get("scedulded_end_date")) # type: ignore[assignment] - additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), + additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), # type: ignore[arg-type] "additional_fields") - response = client.create_work_order_request( - template_guid, - first_name, - last_name, - customer_person_id, - customer_first_name, - customer_last_name, - customer_company, - summary, - detailed_description, - status, - priority, - work_order_type, - location_company, - scedulded_start_date=scedulded_start_date.isoformat() if scedulded_start_date else None, - scedulded_end_date=scedulded_end_date.isoformat() if scedulded_end_date else None, + response = client.create_work_order_request( # type: ignore[arg-type,call-arg] + template_guid, # type: ignore[arg-type] + first_name, # type: ignore[arg-type] + last_name, # type: ignore[arg-type] + customer_person_id, # type: ignore[arg-type] + customer_first_name, # type: ignore[arg-type] + customer_last_name, # type: ignore[arg-type] + customer_company, # type: ignore[arg-type] + summary, # type: ignore[arg-type] + detailed_description, # type: ignore[arg-type] + status, # type: ignore[arg-type] + priority, # type: ignore[arg-type] + work_order_type, # type: ignore[arg-type] + location_company, # type: ignore[arg-type] + scedulded_start_date=scedulded_start_date.isoformat() if scedulded_start_date else None, # type: ignore[arg-type] + scedulded_end_date=scedulded_end_date.isoformat() if scedulded_end_date else None, # type: ignore[arg-type] **additional_fields, ) - outputs = format_create_ticket_outputs(response.get("values")) + outputs = format_create_ticket_outputs(response.get("values")) # type: ignore[arg-type] # Fixing API returning RequestID in form 000...NNN instead of WO0...NNN outputs["RequestID"] = "WO0" + outputs["RequestID"][3:] readable_output = tableToMarkdown("Work order ticket successfully created.", @@ -2832,29 +2831,29 @@ def work_order_update_command(client: Client, args: Dict[str, Any]) -> CommandRe support_organization = args.get("support_organization") support_group = args.get("support_group") location_company = args.get("location_company") - scedulded_start_date: datetime = arg_to_datetime(args.get("scedulded_start_date")) - schedulded_end_date: datetime = arg_to_datetime(args.get("schedulded_end_date")) + scedulded_start_date: datetime = arg_to_datetime(args.get("scedulded_start_date")) # type: ignore[assignment] + schedulded_end_date: datetime = arg_to_datetime(args.get("schedulded_end_date")) # type: ignore[assignment] - additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), + additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), # type: ignore[arg-type] "additional_fields") validate_related_arguments_provided(support_organization=support_organization, support_group=support_group) - client.update_work_order_request( - request_id, - summary=summary, - detailed_description=detailed_description, - status=status, - status_reason=status_reason, - priority=priority, - work_order_type=work_order_type, - company=company, - assignee=assignee, - support_organization=support_organization, - support_group_name=support_group, - location_company=location_company, - scedulded_start_date=scedulded_start_date.isoformat() if scedulded_start_date else None, - schedulded_end_date=schedulded_end_date.isoformat if schedulded_end_date else None, + client.update_work_order_request( # type: ignore[arg-type,call-arg] + request_id, # type: ignore[arg-type] + summary=summary, # type: ignore[arg-type] + detailed_description=detailed_description, # type: ignore[arg-type] + status=status, # type: ignore[arg-type] + status_reason=status_reason, # type: ignore[arg-type] + priority=priority, # type: ignore[arg-type] + work_order_type=work_order_type, # type: ignore[arg-type] + company=company, # type: ignore[arg-type] + assignee=assignee, # type: ignore[arg-type] + support_organization=support_organization, # type: ignore[arg-type] + support_group_name=support_group, # type: ignore[arg-type] + location_company=location_company, # type: ignore[arg-type] + scedulded_start_date=scedulded_start_date.isoformat() if scedulded_start_date else None, # type: ignore[arg-type] + schedulded_end_date=schedulded_end_date.isoformat if schedulded_end_date else None, # type: ignore[arg-type] **additional_fields, ) @@ -2886,26 +2885,26 @@ def format_command_output(records: List[dict], record_attributes = record.get("values") for origin_attrib_name, formatted_attrib_name in mapper.items(): - if origin_attrib_name in record_attributes: + if origin_attrib_name in record_attributes: # type: ignore[operator] if formatted_attrib_name in ( "RequestID", "ID", ): # extract request ID out of pattern: -> id formatted_record[formatted_attrib_name] = extract_ticket_request_id( - record_attributes[origin_attrib_name]) + record_attributes[origin_attrib_name]) # type: ignore[index] - elif ("Date" in formatted_attrib_name and record_attributes[origin_attrib_name]): + elif ("Date" in formatted_attrib_name and record_attributes[origin_attrib_name]): # type: ignore[index] formatted_record[formatted_attrib_name] = FormatIso8601( - arg_to_datetime(record_attributes[origin_attrib_name])) + arg_to_datetime(record_attributes[origin_attrib_name])) # type: ignore[index] else: - formatted_record[formatted_attrib_name] = record_attributes[origin_attrib_name] + formatted_record[formatted_attrib_name] = record_attributes[origin_attrib_name] # type: ignore[index] if context_data_arranger: context_data_arranger(formatted_record) outputs.append(formatted_record) - return outputs + return outputs # type: ignore[return-value] def get_paginated_records_with_hr( @@ -2937,7 +2936,7 @@ def get_paginated_records_with_hr( header = (f"Showing page {page} out of {total_pages} total pages." f" Current page size: {page_size}.") else: - relevant_raw_data = raw_data[:min(rows_count, limit)] + relevant_raw_data = raw_data[:min(rows_count, limit)] # type: ignore[type-var] header = f"Showing {len(relevant_raw_data)} records out of {rows_count}." return relevant_raw_data, header if relevant_raw_data else "" @@ -3011,7 +3010,7 @@ def extract_args_from_additional_fields_arg(additional_fields: str, formatted_additional_fields = {} if not additional_fields: - return {} + return {} # type: ignore[return-value] try: fields = additional_fields.split(FIELD_DELIMITER) for each_field in fields: @@ -3022,7 +3021,7 @@ def extract_args_from_additional_fields_arg(additional_fields: str, raise ValueError( f'Please validate the format of the argument: {field_name}. For example: "fieldname1=value;fieldname2=value". ' ) from error - return formatted_additional_fields + return formatted_additional_fields # type: ignore[return-value] def arrange_ticket_context_data(ticket: Dict[str, Any]) -> Dict[str, Any]: @@ -3162,8 +3161,8 @@ def generate_query_filter_mapper_by_args(args: Dict[str, Any], record_id_key: Op """ ids_filter_mapper = {record_id_key: args.get("ids")} - status_key = TICKET_TYPE_TO_STATUS_FIELD.get(ticket_type, "Status") - summary = TICKET_TYPE_TO_SUMMARY_KEY.get(ticket_type, "Summary") + status_key = TICKET_TYPE_TO_STATUS_FIELD.get(ticket_type, "Status") # type: ignore[arg-type] + summary = TICKET_TYPE_TO_SUMMARY_KEY.get(ticket_type, "Summary") # type: ignore[arg-type] equal_filter_mapper = { status_key: args.get("status"), "Impact": args.get("impact"), @@ -3210,7 +3209,7 @@ def generate_query_with_filtering(custom_query: str, filter_mapper: Dict[str, An records_id_name = next(iter(ids_filter), None) records_ids = ids_filter.get(records_id_name) or [] - ids_query = gen_single_filters_statement(records_id_name, records_ids, "=", " OR ") + ids_query = gen_single_filters_statement(records_id_name, records_ids, "=", " OR ") # type: ignore[arg-type] equal_oper_filter_query = gen_multi_filters_statement(equal_oper_filters, "=", " AND ") @@ -3389,8 +3388,8 @@ def fetch_relevant_tickets_by_ticket_type( ) response = client.list_request(ticket_form, fetch_query) - relevant_records, _ = get_paginated_records_with_hr(response.get("entries"), max_fetch) - outputs: List[dict] = format_command_output( + relevant_records, _ = get_paginated_records_with_hr(response.get("entries"), max_fetch) # type: ignore[arg-type] + outputs: List[dict] = format_command_output( # type: ignore[assignment] deepcopy(relevant_records), generate_ticket_context_data_mapper(ticket_type), arrange_ticket_context_data, @@ -3655,7 +3654,7 @@ def get_ticket(client: Client, if not outputs: raise ValueError( f"The ticket type: {ticket_type} with request ID: {root_request_id} does not exist.") - return next(iter(outputs)) + return next(iter(outputs)) # type: ignore[call-overload] def get_remote_data_command(client: Client, args: Dict[str, Any], @@ -3708,7 +3707,7 @@ def get_modified_remote_data(client: Client, args: Dict[str, Any]) -> GetModifie last_update_utc = date_to_epoch_for_fetch( arg_to_datetime(last_update)) # converts to a UTC timestamp - modified_tickets = [] + modified_tickets = [] # type: ignore[var-annotated] modified_ticket_ids = [] for ticket_type in ALL_TICKETS: @@ -3722,7 +3721,7 @@ def get_modified_remote_data(client: Client, args: Dict[str, Any]) -> GetModifie }, ).outputs if modified_tickets_by_type: - modified_tickets += modified_tickets_by_type + modified_tickets += modified_tickets_by_type # type: ignore[arg-type] for raw_ticket in modified_tickets: ticket_id = raw_ticket.get("RequestID") @@ -3829,8 +3828,8 @@ def get_mapping_fields_command() -> GetMappingFieldsResponse: mapping_response = GetMappingFieldsResponse() for ticket_type, incident_type in TICKET_TYPE_TO_INCIDENT_TYPE.items(): incident_type_scheme = SchemeTypeMapping(type_name=incident_type) - outgoing_fields = MIRRORING_COMMON_FIELDS + TICKET_TYPE_TO_ADDITIONAL_MIRRORING_FIELDS[ - ticket_type] + outgoing_fields = MIRRORING_COMMON_FIELDS + \ + TICKET_TYPE_TO_ADDITIONAL_MIRRORING_FIELDS[ticket_type] # type: ignore[union-attr,operator] for field in outgoing_fields: incident_type_scheme.add_field(field) @@ -3883,8 +3882,8 @@ def main() -> None: verify_certificate: bool = not params.get("insecure", False) proxy = params.get("proxy", False) credentials = params.get("credentials") - username = credentials.get("identifier") - password = credentials.get("password") + username = credentials.get("identifier") # type: ignore[union-attr] + password = credentials.get("password") # type: ignore[union-attr] max_fetch = arg_to_number(params.get("max_fetch", DEFAULT_MAX_FETCH)) first_fetch = params.get("first_fetch") @@ -3893,7 +3892,7 @@ def main() -> None: ticket_impacts = argToList(params.get("ticket_impact")) ticket_urgencies = argToList(params.get("ticket_urgency")) ticket_custom_query = params.get("query") - mirror_direction = MIRROR_DIRECTION_MAPPING[params.get("mirror_direction")] + mirror_direction = MIRROR_DIRECTION_MAPPING[params.get("mirror_direction")] # type: ignore[index] close_incident = params.get("close_incident") close_ticket = params.get("close_ticket") @@ -3905,8 +3904,8 @@ def main() -> None: demisto.debug(f"Command being called is {command}") try: - requests.packages.urllib3.disable_warnings() - client: Client = Client(url, username, password, verify=verify_certificate, proxy=proxy) + requests.packages.urllib3.disable_warnings() # type: ignore[attr-defined] + client: Client = Client(url, username, password, verify=verify_certificate, proxy=proxy) # type: ignore[arg-type] commands = { "bmc-itsm-ticket-list": ticket_list_command, @@ -3940,25 +3939,25 @@ def main() -> None: elif command == "fetch-incidents": incidents, last_run = fetch_incidents( client, - max_fetch, - first_fetch, + max_fetch, # type: ignore[arg-type] + first_fetch, # type: ignore[arg-type] demisto.getLastRun(), ticket_type_filter, ticket_status_filter, ticket_impact_filter, ticket_urgency_filter, - ticket_custom_query, - mirror_direction, + ticket_custom_query, # type: ignore[arg-type] + mirror_direction, # type: ignore[arg-type] ) demisto.setLastRun(last_run) demisto.incidents(incidents) elif command == "get-remote-data": - return_results(get_remote_data_command(client, args, close_incident)) + return_results(get_remote_data_command(client, args, close_incident)) # type: ignore[arg-type] elif command == "get-modified-remote-data": return_results(get_modified_remote_data(client, args)) elif command == "update-remote-system": - return_results(update_remote_system(client, args, close_ticket)) + return_results(update_remote_system(client, args, close_ticket)) # type: ignore[arg-type] elif command == "get-mapping-fields": return_results(get_mapping_fields_command()) elif command in commands: diff --git a/Packs/BmcITSM/ReleaseNotes/1_0_24.md b/Packs/BmcITSM/ReleaseNotes/1_0_24.md new file mode 100644 index 000000000000..34cb12f1f055 --- /dev/null +++ b/Packs/BmcITSM/ReleaseNotes/1_0_24.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### BMC Helix ITSM + +- Maintenance and stability enhancements. diff --git a/Packs/BmcITSM/pack_metadata.json b/Packs/BmcITSM/pack_metadata.json index 66cfdbd19553..d4c7bae1259a 100644 --- a/Packs/BmcITSM/pack_metadata.json +++ b/Packs/BmcITSM/pack_metadata.json @@ -2,7 +2,7 @@ "name": "BMC Helix ITSM", "description": "BMC Helix ITSM allows customers to manage service request, incident, change request, task, problem investigation, known error and work order tickets.", "support": "xsoar", - "currentVersion": "1.0.23", + "currentVersion": "1.0.24", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/CheckPointDome9/Integrations/CheckPointDome9/CheckPointDome9.py b/Packs/CheckPointDome9/Integrations/CheckPointDome9/CheckPointDome9.py index bc4d118a4a49..328ed9982e26 100644 --- a/Packs/CheckPointDome9/Integrations/CheckPointDome9/CheckPointDome9.py +++ b/Packs/CheckPointDome9/Integrations/CheckPointDome9/CheckPointDome9.py @@ -1,8 +1,7 @@ import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 -# type: ignore -# mypy: ignore-errors -from typing import Any, Dict, Tuple + +from typing import Any TIME_FORMAT = '%Y-%m-%dT%H:%M:%S.%fZ' @@ -15,7 +14,7 @@ def __init__(self, base_url: str, key_id: str, key_secret: str, proxy: bool, ver auth = (key_id, key_secret) super().__init__(base_url=base_url, auth=auth, verify=verify, headers=headers, proxy=proxy) - def access_lease_list_request(self) -> Dict[str, Any]: + def access_lease_list_request(self) -> dict[str, Any]: """ Get Access lease list. Returns: @@ -34,13 +33,13 @@ def access_lease_delete_request(self, lease_id: str) -> str: """ return self._http_request('DELETE', f'AccessLease/{lease_id}', resp_type='text') - def access_lease_invitation_list_request(self, invitation_id: str = None) -> Dict[str, Any]: + def access_lease_invitation_list_request(self, invitation_id: str = None) -> dict[str, Any]: """ Get Access lease invitation list. Returns: Dict[str, Any]: API response from Dome9. """ - url_prefix = create_url_prefix(invitation_id) + url_prefix = create_url_prefix(invitation_id) # type: ignore[arg-type] response = self._http_request('GET', f'AccessLeaseInvitation{url_prefix}') @@ -64,7 +63,7 @@ def findings_search_request(self, alert_severity: List[str] = None, alert_region: List[str] = None, alert_entity_type: List[str] = None, - alert_acknowledged: bool = None) -> Dict[str, Any]: + alert_acknowledged: bool = None) -> dict[str, Any]: """ Search findings. Filter findings by account, region, VPC, IP, or instance name. @@ -82,7 +81,7 @@ def findings_search_request(self, fields.append({"name": "entityTypeByEnvironmentType", "value": entity_type}) if alert_acknowledged: - fields.append({"name": "acknowledged", "value": alert_acknowledged}) + fields.append({"name": "acknowledged", "value": alert_acknowledged}) # type: ignore[dict-item] data = { "pageSize": max_fetch, @@ -101,7 +100,7 @@ def findings_search_request(self, def ip_list_create_request(self, name: str, description: str, - items: List[Dict[str, Any]] = None) -> Dict[str, Any]: + items: List[dict[str, Any]] = None) -> dict[str, Any]: """ Create a new IP list. Args: @@ -119,7 +118,7 @@ def ip_list_create_request(self, def ip_list_update_request(self, list_id: str, description: str, - items: List[Dict[str, Any]] = None) -> str: + items: List[dict[str, Any]] = None) -> str: """ Update exist IP list. Args: @@ -134,7 +133,7 @@ def ip_list_update_request(self, response = self._http_request('PUT', f'IpList/{list_id}', json_data=data, resp_type='text') return response - def ip_list_get_request(self, list_id: str) -> Dict[str, Any]: + def ip_list_get_request(self, list_id: str) -> dict[str, Any]: """ Get an IP List by ID. Args: @@ -159,7 +158,7 @@ def ip_list_delete_request(self, list_id: str) -> str: return self._http_request('DELETE', f'IpList/{list_id}', resp_type='text') - def ip_list_metadata_list_request(self) -> Dict[str, Any]: + def ip_list_metadata_list_request(self) -> dict[str, Any]: """ Get all IP addresses metadata. Returns: @@ -172,7 +171,7 @@ def ip_list_metadata_create_request( cidr: str, name: str, classification: str, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: """ Add a new IP address metadata. An Ip Address metadata must contain CIDR, Name and Classification. Classification can be External or Unsafe or Dmz or InternalVpc or InternalDc or NoClassification. @@ -195,7 +194,7 @@ def ip_list_metadata_update_request( list_id: str, classification: str, name: str, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: """ Update an existing IP address metadata. Classification can only be External or Unsafe or Dmz or InternalVpc or InternalDc or NoClassification. @@ -237,7 +236,7 @@ def ip_list_metadata_delete_request( return response - def compliance_remediation_get_request(self) -> Dict[str, Any]: + def compliance_remediation_get_request(self) -> dict[str, Any]: """ Get a list of remediation for the account. Returns: @@ -247,7 +246,7 @@ def compliance_remediation_get_request(self) -> Dict[str, Any]: return self._http_request('GET', 'ComplianceRemediation') def compliance_remediation_create_request(self, ruleset_id: str, rule_logic_hash: str, - comment: str, cloudbots: list) -> Dict[str, Any]: + comment: str, cloudbots: list) -> dict[str, Any]: """ Add a new remediation. Args: @@ -275,7 +274,7 @@ def compliance_remediation_update_request( rule_logic_hash: str, comment: str, cloudbots: list, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: """ Update a remediation. Args: @@ -313,7 +312,7 @@ def compliance_remediation_delete_request(self, remediation_id: str) -> str: f'ComplianceRemediation/{remediation_id}', resp_type='text') - def compliance_ruleset_list_request(self) -> Dict[str, Any]: + def compliance_ruleset_list_request(self) -> dict[str, Any]: """ Get all rulesets for the account. Returns: @@ -321,7 +320,7 @@ def compliance_ruleset_list_request(self) -> Dict[str, Any]: """ return self._http_request('GET', 'Compliance/Ruleset/view') - def compliance_ruleset_rule_list_request(self, rule_id: int) -> Dict[str, Any]: + def compliance_ruleset_rule_list_request(self, rule_id: int) -> dict[str, Any]: """ Get rule details (get rule logic hash). Args: @@ -337,7 +336,7 @@ def security_group_attach_request( instance_id: str, sg_id: str, nic_name: str, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: """ Attach security Group to an AWS EC2 Instance. Args: @@ -356,7 +355,7 @@ def security_group_attach_request( return response - def instance_list_request(self, instance_id: str) -> Dict[str, Any]: + def instance_list_request(self, instance_id: str) -> dict[str, Any]: """ Get an AWS EC2 Instances list. Args: @@ -387,7 +386,7 @@ def security_group_service_delete_request(self, sg_id: str, service_id: str) -> return response def security_group_tags_update_request(self, sg_id: str, key: str, - value: str) -> Dict[str, Any]: + value: str) -> dict[str, Any]: """ Create and Update a security group tag. Args: @@ -420,7 +419,7 @@ def security_group_service_create_request( inbound: bool = None, icmptype: str = None, icmpv6type: str = None, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: """ Create new security group service. Args: @@ -488,7 +487,7 @@ def security_group_service_update_request( inbound: bool = None, icmptype: str = None, icmpv6type: str = None, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: """ Update security group service. Args: @@ -548,7 +547,7 @@ def security_group_instance_detach_request( instance_id: str, sg_id: str, nic_name: str, - ) -> Dict[str, Any]: + ) -> dict[str, Any]: """ Detach security Group from an AWS EC2 Instance. Args: @@ -567,7 +566,7 @@ def security_group_instance_detach_request( return response - def protection_mode_update_request(self, sg_id: str, protection_mode: str) -> Dict[str, Any]: + def protection_mode_update_request(self, sg_id: str, protection_mode: str) -> dict[str, Any]: """ Change the protection mode for an AWS security group (FullManage or ReadOnly). Args: @@ -585,30 +584,30 @@ def protection_mode_update_request(self, sg_id: str, protection_mode: str) -> Di return response - def cloud_accounts_list_request(self, account_id: str = None) -> Dict[str, Any]: + def cloud_accounts_list_request(self, account_id: str = None) -> dict[str, Any]: """ Get cloud accounts list. Returns: Dict[str, Any]: API response from Dome9. """ - url_prefix = create_url_prefix(account_id) + url_prefix = create_url_prefix(account_id) # type: ignore[arg-type] response = self._http_request('GET', f'CloudAccounts{url_prefix}') return response - def check_ip_list_security_group_attach_request(self, sg_id: str = None) -> Dict[str, Any]: + def check_ip_list_security_group_attach_request(self, sg_id: str = None) -> dict[str, Any]: """ Get AWS cloud accounts for a specific security group and region and check if there is an IP-list that attach to a security group. Returns: Dict[str, Any]: API response from Dome9. """ - url_prefix = create_url_prefix(sg_id) + url_prefix = create_url_prefix(sg_id) # type: ignore[arg-type] response = self._http_request('GET', f'CloudSecurityGroup{url_prefix}') return response - def security_group_list_request(self) -> Dict[str, Any]: + def security_group_list_request(self) -> dict[str, Any]: """ Get security group list. Returns: @@ -618,7 +617,7 @@ def security_group_list_request(self) -> Dict[str, Any]: return response - def global_search_get_request(self) -> Dict[str, Any]: + def global_search_get_request(self) -> dict[str, Any]: """ Get top results for each service. Returns: @@ -629,7 +628,7 @@ def global_search_get_request(self) -> Dict[str, Any]: return response - def cloud_trail_get_request(self) -> Dict[str, Any]: + def cloud_trail_get_request(self) -> dict[str, Any]: """ Get Cloud Trail events for a Dome9 user. Returns: @@ -639,7 +638,7 @@ def cloud_trail_get_request(self) -> Dict[str, Any]: return response - def findings_bundle_get_request(self, bundle_id: str, rule_logic_hash: str) -> Dict[str, Any]: + def findings_bundle_get_request(self, bundle_id: str, rule_logic_hash: str) -> dict[str, Any]: """ Get the findings for a specific rule in a bundle, for all of the user's accounts. Args: @@ -655,7 +654,7 @@ def findings_bundle_get_request(self, bundle_id: str, rule_logic_hash: str) -> D params=params) return response - def finding_get_request(self, finding_id: str) -> Dict[str, Any]: + def finding_get_request(self, finding_id: str) -> dict[str, Any]: """ Get a findings by its ID. Args: @@ -667,7 +666,7 @@ def finding_get_request(self, finding_id: str) -> Dict[str, Any]: response = self._http_request('GET', f'Compliance/Finding/{finding_id}') return response - def organizational_unit_view_get_request(self) -> Dict[str, Any]: + def organizational_unit_view_get_request(self) -> dict[str, Any]: """ Get organizational unit view entities. Returns: @@ -676,7 +675,7 @@ def organizational_unit_view_get_request(self) -> Dict[str, Any]: response = self._http_request('GET', 'organizationalunit/view') return response - def organizational_unit_flat_get_request(self) -> Dict[str, Any]: + def organizational_unit_flat_get_request(self) -> dict[str, Any]: """ Get all organizational units flat. Returns: @@ -685,7 +684,7 @@ def organizational_unit_flat_get_request(self) -> Dict[str, Any]: response = self._http_request('GET', 'organizationalunit/GetFlatOrganizationalUnits') return response - def organizational_unit_get_request(self, unit_id: str) -> Dict[str, Any]: + def organizational_unit_get_request(self, unit_id: str) -> dict[str, Any]: """ Get an organizational unit by its ID. Args: @@ -741,20 +740,17 @@ def validate_pagination_arguments(page: int = None, page_size: int = None, limit Raises: ValueError: Appropriate error message. """ - if page_size: - if page_size < 1 or page_size > 50: - raise ValueError('page size argument must be greater than 1 and smaller than 50.') + if page_size and (page_size < 1 or page_size > 50): + raise ValueError('page size argument must be greater than 1 and smaller than 50.') - if page: - if page < 1: - raise ValueError('page argument must be greater than 0.') + if page and page < 1: + raise ValueError('page argument must be greater than 0.') - if limit: - if limit < 1 or limit > 50: - raise ValueError('limit argument must be greater than 1.') + if limit and (limit < 1 or limit > 50): + raise ValueError('limit argument must be greater than 1.') -def pagination(response: dict, args: Dict[str, Any]) -> Tuple: +def pagination(response: dict, args: dict[str, Any]) -> tuple: """ Executing Manual Pagination (using the page and page size arguments) or Automatic Pagination (display a number of total results). @@ -771,7 +767,7 @@ def pagination(response: dict, args: Dict[str, Any]) -> Tuple: page_size = arg_to_number(args.get('page_size')) limit = arg_to_number(args.get('limit')) - validate_pagination_arguments(page, page_size, limit) + validate_pagination_arguments(page, page_size, limit) # type: ignore[arg-type] output = response @@ -814,10 +810,10 @@ def get_service_type_and_data(service: list) -> list: if service: service_scope = service[0]['scope'] if service_scope: - service_type = service_scope[0]['type'] - service_data = service_scope[0]['data'] + service_type = service_scope[0]['type'] # type: ignore[index] + service_data = service_scope[0]['data'] # type: ignore[index] - return service_type, service_data + return service_type, service_data # type: ignore[return-value] def create_url_prefix(path_variable: str) -> str: @@ -870,7 +866,7 @@ def create_sg_list(fix_output: list) -> list: return security_group_list -def access_lease_list_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def access_lease_list_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Get a access lease list. Args: @@ -901,7 +897,7 @@ def access_lease_list_command(client: Client, args: Dict[str, Any]) -> CommandRe return command_results -def access_lease_delete_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def access_lease_delete_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Delete access lease by ID. Args: @@ -912,7 +908,7 @@ def access_lease_delete_command(client: Client, args: Dict[str, Any]) -> Command CommandResults: outputs, readable outputs and raw response for XSOAR. """ lease_id = args.get('lease_id') - response = client.access_lease_delete_request(lease_id) + response = client.access_lease_delete_request(lease_id) # type: ignore[arg-type] command_results = CommandResults(readable_output="Access Lease Deleted successfully", outputs_prefix='CheckPointDome9.AccessLease', outputs_key_field='', @@ -922,7 +918,7 @@ def access_lease_delete_command(client: Client, args: Dict[str, Any]) -> Command return command_results -def access_lease_invitation_list_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def access_lease_invitation_list_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Get a specific lease invitation. Args: @@ -933,7 +929,7 @@ def access_lease_invitation_list_command(client: Client, args: Dict[str, Any]) - CommandResults: outputs, readable outputs and raw response for XSOAR. """ invitation_id = args.get('invitation_id') - response = client.access_lease_invitation_list_request(invitation_id) + response = client.access_lease_invitation_list_request(invitation_id) # type: ignore[arg-type] fix_output, pagination_message = pagination(response, args) readable_output = tableToMarkdown( @@ -952,7 +948,7 @@ def access_lease_invitation_list_command(client: Client, args: Dict[str, Any]) - return command_results -def access_lease_invitation_delete_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def access_lease_invitation_delete_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Delete a lease invitation. Args: @@ -963,7 +959,7 @@ def access_lease_invitation_delete_command(client: Client, args: Dict[str, Any]) CommandResults: outputs, readable outputs and raw response for XSOAR. """ invitation_id = args.get('invitation_id') - response = client.access_lease_invitation_delete_request(invitation_id) + response = client.access_lease_invitation_delete_request(invitation_id) # type: ignore[arg-type] command_results = CommandResults(readable_output="Access Lease Invitation Deleted successfully", outputs_prefix='CheckPointDome9.AccessLease.Invitation', outputs_key_field='', @@ -973,7 +969,7 @@ def access_lease_invitation_delete_command(client: Client, args: Dict[str, Any]) return command_results -def findings_search_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def findings_search_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Search findings for the account. Args: @@ -984,13 +980,13 @@ def findings_search_command(client: Client, args: Dict[str, Any]) -> CommandResu CommandResults: outputs, readable outputs and raw response for XSOAR. """ severity = argToList(args.get('severity')) - acknowledged = arg_to_boolean(args.get('acknowledged')) + acknowledged = arg_to_boolean(args.get('acknowledged')) # type: ignore[arg-type] entity_type = argToList(args.get('entity_type')) region = argToList(args.get('region')) page_size = arg_to_number(args.get('limit')) - response = client.findings_search_request(page_size, severity, region, entity_type, - acknowledged) + response = client.findings_search_request(page_size, severity, region, entity_type, # type: ignore[arg-type] + acknowledged) # type: ignore[arg-type] output = response['findings'] fix_output, pagination_message = pagination(output, args) @@ -1013,7 +1009,7 @@ def findings_search_command(client: Client, args: Dict[str, Any]) -> CommandResu return command_results -def ip_list_create_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def ip_list_create_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Create a new IP-list. Args: @@ -1029,9 +1025,9 @@ def ip_list_create_command(client: Client, args: Dict[str, Any]) -> CommandResul comment_list = argToList(args.get('comment')) # insure comment_list has the same length as ip_list - items = attach_comment_to_ip(ip_list, comment_list, description) + items = attach_comment_to_ip(ip_list, comment_list, description) # type: ignore[arg-type] - response = client.ip_list_create_request(name, description, items) + response = client.ip_list_create_request(name, description, items) # type: ignore[arg-type] command_results = CommandResults(readable_output="IP list created successfully", outputs_prefix='CheckPointDome9.IpList', outputs_key_field='id', @@ -1041,7 +1037,7 @@ def ip_list_create_command(client: Client, args: Dict[str, Any]) -> CommandResul return command_results -def ip_list_update_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def ip_list_update_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Update IP list (description or items). Args: @@ -1058,15 +1054,15 @@ def ip_list_update_command(client: Client, args: Dict[str, Any]) -> CommandResul comment_list = argToList(args.get('comment')) # insure comment_list has the same length as ip_list - items = attach_comment_to_ip(ip_list, comment_list, description) + items = attach_comment_to_ip(ip_list, comment_list, description) # type: ignore[arg-type] # This command replace items. To make the command update the list # we first get the old items if update_mode == 'add_new_items': - old_items = client.ip_list_get_request(list_id=list_id) - items += old_items.get('items') + old_items = client.ip_list_get_request(list_id=list_id) # type: ignore[arg-type] + items += old_items.get('items') # type: ignore[arg-type] - response = client.ip_list_update_request(list_id, description, items) + response = client.ip_list_update_request(list_id, description, items) # type: ignore[arg-type] command_results = CommandResults(readable_output="IP list updated successfully", outputs_prefix='CheckPointDome9.IpList', @@ -1077,7 +1073,7 @@ def ip_list_update_command(client: Client, args: Dict[str, Any]) -> CommandResul return command_results -def ip_list_get_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def ip_list_get_command(client: Client, args: dict[str, Any]) -> CommandResults: """ List all IP Lists or Get individual by list ID. Args: client (Client): Dome9 API client. @@ -1088,7 +1084,7 @@ def ip_list_get_command(client: Client, args: Dict[str, Any]) -> CommandResults: """ list_id = args.get('list_id') - response = client.ip_list_get_request(list_id) + response = client.ip_list_get_request(list_id) # type: ignore[arg-type] if isinstance(response, dict): response = [response] # type: ignore @@ -1096,12 +1092,12 @@ def ip_list_get_command(client: Client, args: Dict[str, Any]) -> CommandResults: ip_lists = [] for ip_list in response: - items = [item['ip'] for item in ip_list['items']] + items = [item['ip'] for item in ip_list['items']] # type: ignore[index] item = { - 'id': ip_list['id'], + 'id': ip_list['id'], # type: ignore[index] 'items': items, - 'name': ip_list['name'], - 'description': ip_list['description'] + 'name': ip_list['name'], # type: ignore[index] + 'description': ip_list['description'] # type: ignore[index] } ip_lists.append(item) @@ -1119,7 +1115,7 @@ def ip_list_get_command(client: Client, args: Dict[str, Any]) -> CommandResults: return command_results -def ip_list_delete_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def ip_list_delete_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Delete list by list ID. Args: @@ -1131,7 +1127,7 @@ def ip_list_delete_command(client: Client, args: Dict[str, Any]) -> CommandResul """ list_id = args.get('list_id') - response = client.ip_list_delete_request(list_id) + response = client.ip_list_delete_request(list_id) # type: ignore[arg-type] command_results = CommandResults(readable_output="IP list deleted successfully", outputs_prefix='CheckPointDome9.IpList', outputs_key_field='id', @@ -1141,7 +1137,7 @@ def ip_list_delete_command(client: Client, args: Dict[str, Any]) -> CommandResul return command_results -def ip_list_metadata_list_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def ip_list_metadata_list_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Get IP address metadata. Args: @@ -1168,7 +1164,7 @@ def ip_list_metadata_list_command(client: Client, args: Dict[str, Any]) -> Comma return command_results -def ip_list_metadata_create_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def ip_list_metadata_create_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Add a new IP address metadata. Args: @@ -1182,7 +1178,7 @@ def ip_list_metadata_create_command(client: Client, args: Dict[str, Any]) -> Com name = args.get('name') classification = args.get('classification') - response = client.ip_list_metadata_create_request(cidr, name, classification) + response = client.ip_list_metadata_create_request(cidr, name, classification) # type: ignore[arg-type] readable_output = tableToMarkdown(name='IP List metadata created successfully', t=response, @@ -1196,7 +1192,7 @@ def ip_list_metadata_create_command(client: Client, args: Dict[str, Any]) -> Com return command_results -def ip_list_metadata_update_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def ip_list_metadata_update_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Update IP address metadata. Args: @@ -1210,7 +1206,7 @@ def ip_list_metadata_update_command(client: Client, args: Dict[str, Any]) -> Com classification = args.get('classification') name = args.get('name') - response = client.ip_list_metadata_update_request(list_metadata_id, classification, name) + response = client.ip_list_metadata_update_request(list_metadata_id, classification, name) # type: ignore[arg-type] readable_output = tableToMarkdown(name='IP List metadata updated successfully', t=response, headerTransform=string_to_table_header) @@ -1223,7 +1219,7 @@ def ip_list_metadata_update_command(client: Client, args: Dict[str, Any]) -> Com return command_results -def ip_list_metadata_delete_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def ip_list_metadata_delete_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Delete IP address metadata. Args: @@ -1237,7 +1233,7 @@ def ip_list_metadata_delete_command(client: Client, args: Dict[str, Any]) -> Com address = args.get('address') mask = args.get('mask') - response = client.ip_list_metadata_delete_request(account_id, address, mask) + response = client.ip_list_metadata_delete_request(account_id, address, mask) # type: ignore[arg-type] command_results = CommandResults(readable_output="IP List metadata deleted successfully", outputs_prefix='CheckPointDome9.IpList.Metadata', outputs_key_field='', @@ -1247,7 +1243,7 @@ def ip_list_metadata_delete_command(client: Client, args: Dict[str, Any]) -> Com return command_results -def compliance_remediation_get_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def compliance_remediation_get_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Get a list of remediations for the account. Args: @@ -1273,7 +1269,7 @@ def compliance_remediation_get_command(client: Client, args: Dict[str, Any]) -> return command_results -def compliance_remediation_create_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def compliance_remediation_create_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Add a new remediation. Args: @@ -1288,7 +1284,7 @@ def compliance_remediation_create_command(client: Client, args: Dict[str, Any]) comment = args.get('comment') cloudbots = argToList(args.get('cloudbots')) - response = client.compliance_remediation_create_request(ruleset_id, rule_logic_hash, comment, + response = client.compliance_remediation_create_request(ruleset_id, rule_logic_hash, comment, # type: ignore[arg-type] cloudbots) readable_output = tableToMarkdown( @@ -1305,7 +1301,7 @@ def compliance_remediation_create_command(client: Client, args: Dict[str, Any]) return command_results -def compliance_remediation_update_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def compliance_remediation_update_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Update a remediation. Args: @@ -1321,8 +1317,8 @@ def compliance_remediation_update_command(client: Client, args: Dict[str, Any]) cloudbots = argToList(args.get('cloudbots')) rule_logic_hash = args.get('rule_logic_hash') - response = client.compliance_remediation_update_request(remediation_id, ruleset_id, - rule_logic_hash, comment, cloudbots) + response = client.compliance_remediation_update_request(remediation_id, ruleset_id, # type: ignore[arg-type] + rule_logic_hash, comment, cloudbots) # type: ignore[arg-type] readable_output = tableToMarkdown( name='Remediation updated successfully', @@ -1338,7 +1334,7 @@ def compliance_remediation_update_command(client: Client, args: Dict[str, Any]) return command_results -def compliance_remediation_delete_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def compliance_remediation_delete_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Delete a remediation. Args: @@ -1350,7 +1346,7 @@ def compliance_remediation_delete_command(client: Client, args: Dict[str, Any]) """ remediation_id = args.get('remediation_id') - response = client.compliance_remediation_delete_request(remediation_id) + response = client.compliance_remediation_delete_request(remediation_id) # type: ignore[arg-type] command_results = CommandResults(readable_output='Remediation deleted successfully', outputs_prefix='CheckPointDome9.ComplianceRemediation', outputs_key_field='id', @@ -1360,7 +1356,7 @@ def compliance_remediation_delete_command(client: Client, args: Dict[str, Any]) return command_results -def compliance_ruleset_list_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def compliance_ruleset_list_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Get all rulesets for the account. Args: client (Client): Dome9 API client. @@ -1388,7 +1384,7 @@ def compliance_ruleset_list_command(client: Client, args: Dict[str, Any]) -> Com return command_results -def compliance_ruleset_rule_list_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def compliance_ruleset_rule_list_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Get all rulesets for the account (get rule logic hash for create remediation). Args: @@ -1400,7 +1396,7 @@ def compliance_ruleset_rule_list_command(client: Client, args: Dict[str, Any]) - """ rule_id = args.get('rule_id') - response = client.compliance_ruleset_rule_list_request(rule_id) + response = client.compliance_ruleset_rule_list_request(rule_id) # type: ignore[arg-type] output = response['rules'] @@ -1421,7 +1417,7 @@ def compliance_ruleset_rule_list_command(client: Client, args: Dict[str, Any]) - return command_results -def security_group_instance_attach_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def security_group_instance_attach_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Attach security Group to an AWS EC2 Instance. Args: @@ -1436,7 +1432,7 @@ def security_group_instance_attach_command(client: Client, args: Dict[str, Any]) nic_name = args.get('nic_name') try: - response = client.security_group_attach_request(instance_id, sg_id, nic_name) + response = client.security_group_attach_request(instance_id, sg_id, nic_name) # type: ignore[arg-type] except Exception: raise ValueError('Security group already attached') @@ -1449,7 +1445,7 @@ def security_group_instance_attach_command(client: Client, args: Dict[str, Any]) return command_results -def security_group_service_delete_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def security_group_service_delete_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Delete a service from an AWS security group. Args: @@ -1462,7 +1458,7 @@ def security_group_service_delete_command(client: Client, args: Dict[str, Any]) sg_id = args.get('sg_id') service_id = args.get('service_id') - response = client.security_group_service_delete_request(sg_id, service_id) + response = client.security_group_service_delete_request(sg_id, service_id) # type: ignore[arg-type] command_results = CommandResults(readable_output="Service deleted successfully", outputs_prefix='CheckPointDome9.SecurityGroup.Service', @@ -1473,7 +1469,7 @@ def security_group_service_delete_command(client: Client, args: Dict[str, Any]) return command_results -def security_group_tags_update_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def security_group_tags_update_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Update the list of tags for an AWS security group. Args: @@ -1487,7 +1483,7 @@ def security_group_tags_update_command(client: Client, args: Dict[str, Any]) -> key = args.get('key') value = args.get('value') - response = client.security_group_tags_update_request(sg_id, key, value) + response = client.security_group_tags_update_request(sg_id, key, value) # type: ignore[arg-type] readable_output = tableToMarkdown(name='Tag updated successfully', t=response, headerTransform=string_to_table_header) @@ -1501,7 +1497,7 @@ def security_group_tags_update_command(client: Client, args: Dict[str, Any]) -> return command_results -def security_group_service_create_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def security_group_service_create_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Create a new Service (rule) for the security group. Args: @@ -1516,20 +1512,20 @@ def security_group_service_create_command(client: Client, args: Dict[str, Any]) protocol_type = args.get('protocol_type') # mandatory port = arg_to_number(args.get('port')) # mandatory policy_type = args.get('policy_type') - open_for_all = arg_to_boolean(args.get('open_for_all')) + open_for_all = arg_to_boolean(args.get('open_for_all')) # type: ignore[arg-type] description = args.get('description') data_id = args.get('data_id') data_name = args.get('data_name') scope_type = args.get('type') is_valid = args.get('is_valid') - inbound = arg_to_boolean(args.get('inbound')) + inbound = arg_to_boolean(args.get('inbound')) # type: ignore[arg-type] icmptype = args.get('icmptype') icmpv6type = args.get('icmpv6type') - response = client.security_group_service_create_request(sg_id, name, protocol_type, port, - policy_type, open_for_all, description, - data_id, data_name, scope_type, - is_valid, inbound, icmptype, icmpv6type) + response = client.security_group_service_create_request(sg_id, name, protocol_type, port, # type: ignore[arg-type] + policy_type, open_for_all, description, # type: ignore[arg-type] + data_id, data_name, scope_type, # type: ignore[arg-type] + is_valid, inbound, icmptype, icmpv6type) # type: ignore[arg-type] sg_service = [{ 'id': response['id'], 'name': response['name'], @@ -1552,7 +1548,7 @@ def security_group_service_create_command(client: Client, args: Dict[str, Any]) return command_results -def security_group_service_update_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def security_group_service_update_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Update a service (rule) for an AWS security group. Can update only port and name. Args: @@ -1577,11 +1573,11 @@ def security_group_service_update_command(client: Client, args: Dict[str, Any]) icmptype = args.get('icmptype') icmpv6type = args.get('icmpv6type') - response = client.security_group_service_update_request(sg_id, service_name, protocol_type, - port, policy_type, open_for_all, - description, data_id, data_name, - scope_type, is_valid, inbound, icmptype, - icmpv6type) + response = client.security_group_service_update_request(sg_id, service_name, protocol_type, # type: ignore[arg-type] + port, policy_type, open_for_all, # type: ignore[arg-type] + description, data_id, data_name, # type: ignore[arg-type] + scope_type, is_valid, inbound, icmptype, # type: ignore[arg-type] + icmpv6type) # type: ignore[arg-type] sg_service = [{ 'id': response['id'], @@ -1606,7 +1602,7 @@ def security_group_service_update_command(client: Client, args: Dict[str, Any]) return command_results -def security_group_instance_detach_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def security_group_instance_detach_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Detach security Group from an AWS EC2 Instance. Args: @@ -1621,7 +1617,7 @@ def security_group_instance_detach_command(client: Client, args: Dict[str, Any]) nic_name = args.get('nic_name') try: - response = client.security_group_instance_detach_request(instance_id, sg_id, nic_name) + response = client.security_group_instance_detach_request(instance_id, sg_id, nic_name) # type: ignore[arg-type] except Exception: raise ValueError('Security group already detached') @@ -1635,7 +1631,7 @@ def security_group_instance_detach_command(client: Client, args: Dict[str, Any]) def security_group_protection_mode_update_command(client: Client, - args: Dict[str, Any]) -> CommandResults: + args: dict[str, Any]) -> CommandResults: """ Change the protection mode for an AWS security group (FullManage or ReadOnly). Args: @@ -1648,7 +1644,7 @@ def security_group_protection_mode_update_command(client: Client, protection_mode = args.get('protection_mode') sg_id = args.get('sg_id') - response = client.protection_mode_update_request(sg_id, protection_mode) + response = client.protection_mode_update_request(sg_id, protection_mode) # type: ignore[arg-type] security_group_list = create_sg_list([response]) readable_output = tableToMarkdown(name='protection mode updated for security group :', @@ -1664,7 +1660,7 @@ def security_group_protection_mode_update_command(client: Client, return command_results -def cloud_accounts_list_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def cloud_accounts_list_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Get cloud account list. Args: @@ -1675,7 +1671,7 @@ def cloud_accounts_list_command(client: Client, args: Dict[str, Any]) -> Command CommandResults: outputs, readable outputs and raw response for XSOAR. """ account_id = args.get('account_id') - response = client.cloud_accounts_list_request(account_id) + response = client.cloud_accounts_list_request(account_id) # type: ignore[arg-type] if account_id: fix_output, pagination_message = response, "" else: @@ -1697,7 +1693,7 @@ def cloud_accounts_list_command(client: Client, args: Dict[str, Any]) -> Command return command_results -def instance_list_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def instance_list_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Get AWS instances. Args: @@ -1708,7 +1704,7 @@ def instance_list_command(client: Client, args: Dict[str, Any]) -> CommandResult CommandResults: outputs, readable outputs and raw response for XSOAR. """ instance_id = args.get('instance_id') - response = client.instance_list_request(instance_id) + response = client.instance_list_request(instance_id) # type: ignore[arg-type] fix_output, pagination_message = pagination(response, args) instance_list = [] @@ -1738,7 +1734,7 @@ def instance_list_command(client: Client, args: Dict[str, Any]) -> CommandResult return command_results -def check_ip_list_security_group_attach_command(client: Client, args: Dict[str, +def check_ip_list_security_group_attach_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Get AWS cloud accounts for a specific security group and region and check if there is an IP-list that attach to a security group. @@ -1752,7 +1748,7 @@ def check_ip_list_security_group_attach_command(client: Client, args: Dict[str, """ sg_id = args.get('sg_id') - response = client.check_ip_list_security_group_attach_request(sg_id) + response = client.check_ip_list_security_group_attach_request(sg_id) # type: ignore[arg-type] fix_output, pagination_message = pagination(response, args) @@ -1772,7 +1768,7 @@ def check_ip_list_security_group_attach_command(client: Client, args: Dict[str, return command_results -def security_group_list_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def security_group_list_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Get all security group Entities. Args: @@ -1810,7 +1806,7 @@ def security_group_list_command(client: Client, args: Dict[str, Any]) -> Command return command_results -def global_search_get_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def global_search_get_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Get top results for each service. Args: @@ -1853,7 +1849,7 @@ def global_search_get_command(client: Client, args: Dict[str, Any]) -> CommandRe return command_results -def cloud_trail_get_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def cloud_trail_get_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Get CloudTrail events for a Dome9 user. Args: @@ -1865,7 +1861,7 @@ def cloud_trail_get_command(client: Client, args: Dict[str, Any]) -> CommandResu """ response = client.cloud_trail_get_request() - cloud_trail = response[0] + cloud_trail = response[0] # type: ignore[index] cloud_trail_output = [] cloud_trail_output.append({ 'name': cloud_trail['name'], @@ -1888,7 +1884,7 @@ def cloud_trail_get_command(client: Client, args: Dict[str, Any]) -> CommandResu return command_results -def findings_bundle_get_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def findings_bundle_get_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Get the findings for a specific rule in a bundle, for all of the user's accounts. Args: @@ -1901,7 +1897,7 @@ def findings_bundle_get_command(client: Client, args: Dict[str, Any]) -> Command bundle_id = arg_to_number(args.get('bundle_id')) rule_logic_hash = args.get('rule_logic_hash') - response = client.findings_bundle_get_request(bundle_id, rule_logic_hash) + response = client.findings_bundle_get_request(bundle_id, rule_logic_hash) # type: ignore[arg-type] readable_output = tableToMarkdown(name='Findings Bundle', t=response, @@ -1915,7 +1911,7 @@ def findings_bundle_get_command(client: Client, args: Dict[str, Any]) -> Command return command_results -def organizational_unit_view_get_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def organizational_unit_view_get_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Get organizational unit view entities. Args: @@ -1940,7 +1936,7 @@ def organizational_unit_view_get_command(client: Client, args: Dict[str, Any]) - return command_results -def organizational_unit_flat_get_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def organizational_unit_flat_get_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Get organizational unit view entities. Args: @@ -1967,7 +1963,7 @@ def organizational_unit_flat_get_command(client: Client, args: Dict[str, Any]) - return command_results -def organizational_unit_get_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def organizational_unit_get_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Get an organizational unit by its ID. Args: @@ -1978,8 +1974,8 @@ def organizational_unit_get_command(client: Client, args: Dict[str, Any]) -> Com CommandResults: outputs, readable outputs and raw response for XSOAR. """ unit_id = args.get('unit_id') - response = client.organizational_unit_get_request(unit_id) - output = response[0]['item'] + response = client.organizational_unit_get_request(unit_id) # type: ignore[arg-type] + output = response[0]['item'] # type: ignore[index] organizational_unit_list = [] @@ -2006,7 +2002,7 @@ def organizational_unit_get_command(client: Client, args: Dict[str, Any]) -> Com return command_results -def finding_get_command(client: Client, args: Dict[str, Any]) -> CommandResults: +def finding_get_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Get a findings by its ID. Args: @@ -2017,7 +2013,7 @@ def finding_get_command(client: Client, args: Dict[str, Any]) -> CommandResults: CommandResults: outputs, readable outputs and raw response for XSOAR. """ finding_id = args.get('finding_id') - response = client.finding_get_request(finding_id) + response = client.finding_get_request(finding_id) # type: ignore[arg-type] readable_output = tableToMarkdown(name='Findings:', t=response, headers=[ @@ -2045,11 +2041,11 @@ def parse_incident(alert: dict) -> dict: Returns: dict: XSOAR Incident. """ - alert_date = datetime.strptime(alert.get("createdTime"), TIME_FORMAT) + alert_date = datetime.strptime(alert.get("createdTime"), TIME_FORMAT) # type: ignore[arg-type] iso_time = FormatIso8601(alert_date) + 'Z' incident = { - 'name': "Dome9 Alert ID: " + alert.get('id'), + 'name': "Dome9 Alert ID: " + alert.get('id'), # type: ignore[arg-type,operator] 'occurred': iso_time, 'rawJSON': json.dumps(alert) } @@ -2090,17 +2086,17 @@ def fetch_incidents(client: Client, args: dict) -> None: assert isinstance(first_fetch_timestamp, int) - alert_list = client.findings_search_request(max_fetch, alert_severity, alert_region) + alert_list = client.findings_search_request(max_fetch, alert_severity, alert_region) # type: ignore[arg-type] incidents = [] # convert the last_run_time to dome9 time format last_run_datetime = dateparser.parse(last_run_time) - last_run_str = last_run_datetime.strftime(TIME_FORMAT) + last_run_str = last_run_datetime.strftime(TIME_FORMAT) # type: ignore[union-attr] last_run_datetime = dateparser.parse(last_run_str) for alert in alert_list['findings']: alert_time = dateparser.parse(alert['createdTime']) - if alert.get('id') != last_run_id and last_run_datetime < alert_time: + if alert.get('id') != last_run_id and last_run_datetime < alert_time: # type: ignore[return-value,operator] incidents.append(parse_incident(alert)) demisto.incidents(incidents) @@ -2116,16 +2112,16 @@ def test_module(client: Client) -> None: client.access_lease_list_request() except DemistoException as e: if 'password' in str(e): - return 'Authorization Error: make sure API key ID & secret are correctly set' + return 'Authorization Error: make sure API key ID & secret are correctly set' # type: ignore[return-value] else: raise e - return 'ok' + return 'ok' # type: ignore[return-value] def main() -> None: - params: Dict[str, Any] = demisto.params() - args: Dict[str, Any] = demisto.args() + params: dict[str, Any] = demisto.params() + args: dict[str, Any] = demisto.args() base_url = params.get('base_url') @@ -2191,11 +2187,11 @@ def main() -> None: } try: - client: Client = Client(base_url, key_id, key_secret, proxy, + client: Client = Client(base_url, key_id, key_secret, proxy, # type: ignore[arg-type] verify_certificate) # type: ignore if command == 'test-module': - return_results(test_module(client)) + return_results(test_module(client)) # type: ignore[func-returns-value] if command == 'fetch-incidents': fetch_incidents(client, params) elif command in commands: diff --git a/Packs/CheckPointDome9/Integrations/CheckPointDome9/CheckPointDome9.yml b/Packs/CheckPointDome9/Integrations/CheckPointDome9/CheckPointDome9.yml index 8648fc9c2975..c1d66b9d9160 100644 --- a/Packs/CheckPointDome9/Integrations/CheckPointDome9/CheckPointDome9.yml +++ b/Packs/CheckPointDome9/Integrations/CheckPointDome9/CheckPointDome9.yml @@ -1363,7 +1363,7 @@ script: - contextPath: CheckPointDome9.FindingsBundle.region description: The CloudTrail account ID. type: String - dockerimage: demisto/python3:3.10.13.84405 + dockerimage: demisto/python3:3.11.9.105369 isfetch: true runonce: false script: '-' diff --git a/Packs/CheckPointDome9/Integrations/CheckPointDome9/CheckPointDome9_test.py b/Packs/CheckPointDome9/Integrations/CheckPointDome9/CheckPointDome9_test.py index d454667c611f..d6085c3c5c06 100644 --- a/Packs/CheckPointDome9/Integrations/CheckPointDome9/CheckPointDome9_test.py +++ b/Packs/CheckPointDome9/Integrations/CheckPointDome9/CheckPointDome9_test.py @@ -1,4 +1,3 @@ -# type: ignore import json import os import pytest @@ -19,7 +18,7 @@ def load_mock_response(file_name: str) -> str: str: Mock file content. """ - with open(os.path.join('test_data', file_name), mode='r', encoding='utf-8') as mock_file: + with open(os.path.join('test_data', file_name), encoding='utf-8') as mock_file: return json.loads(mock_file.read()) diff --git a/Packs/CheckPointDome9/ReleaseNotes/1_0_17.md b/Packs/CheckPointDome9/ReleaseNotes/1_0_17.md new file mode 100644 index 000000000000..f88650f4aca6 --- /dev/null +++ b/Packs/CheckPointDome9/ReleaseNotes/1_0_17.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Check Point Dome9 (CloudGuard) + +- Maintenance and stability enhancements. diff --git a/Packs/CheckPointDome9/pack_metadata.json b/Packs/CheckPointDome9/pack_metadata.json index 7beb2d7a4c87..100324dafc6e 100644 --- a/Packs/CheckPointDome9/pack_metadata.json +++ b/Packs/CheckPointDome9/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Check Point Dome9 (CloudGuard)", "description": "Dome9 integration allows to easily manage the security and compliance of the public cloud.", "support": "xsoar", - "currentVersion": "1.0.16", + "currentVersion": "1.0.17", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/CommonScripts/ReleaseNotes/1_15_48.md b/Packs/CommonScripts/ReleaseNotes/1_15_48.md new file mode 100644 index 000000000000..431f72eb8915 --- /dev/null +++ b/Packs/CommonScripts/ReleaseNotes/1_15_48.md @@ -0,0 +1,6 @@ + +#### Scripts + +##### FindSimilarIncidents + +- Maintenance and stability enhancements. diff --git a/Packs/CommonScripts/Scripts/FindSimilarIncidentsV2/FindSimilarIncidentsV2.py b/Packs/CommonScripts/Scripts/FindSimilarIncidentsV2/FindSimilarIncidentsV2.py index 79d3a3a34da0..b0c60acdd988 100644 --- a/Packs/CommonScripts/Scripts/FindSimilarIncidentsV2/FindSimilarIncidentsV2.py +++ b/Packs/CommonScripts/Scripts/FindSimilarIncidentsV2/FindSimilarIncidentsV2.py @@ -1,5 +1,3 @@ -# type: ignore - from CommonServerPython import * from dateutil import parser # type: ignore[import] diff --git a/Packs/CommonScripts/pack_metadata.json b/Packs/CommonScripts/pack_metadata.json index 54905d0635a6..11adae30f2f5 100644 --- a/Packs/CommonScripts/pack_metadata.json +++ b/Packs/CommonScripts/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Common Scripts", "description": "Frequently used scripts pack.", "support": "xsoar", - "currentVersion": "1.15.47", + "currentVersion": "1.15.48", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/CyrenInboxSecurity/ReleaseNotes/1_1_13.md b/Packs/CyrenInboxSecurity/ReleaseNotes/1_1_13.md new file mode 100644 index 000000000000..6348c66f7676 --- /dev/null +++ b/Packs/CyrenInboxSecurity/ReleaseNotes/1_1_13.md @@ -0,0 +1,9 @@ + +#### Scripts + +##### Cyren-Show-Threat-Indicators + +- Maintenance and stability enhancements. +##### Cyren-Find-Similar-Incidents + +- Maintenance and stability enhancements. diff --git a/Packs/CyrenInboxSecurity/Scripts/CyrenFindSimilarIncidents/CyrenFindSimilarIncidents.py b/Packs/CyrenInboxSecurity/Scripts/CyrenFindSimilarIncidents/CyrenFindSimilarIncidents.py index d6e593144535..33c6b7a47056 100644 --- a/Packs/CyrenInboxSecurity/Scripts/CyrenFindSimilarIncidents/CyrenFindSimilarIncidents.py +++ b/Packs/CyrenInboxSecurity/Scripts/CyrenFindSimilarIncidents/CyrenFindSimilarIncidents.py @@ -1,8 +1,5 @@ import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 -# noqa: F401 -# noqa: F401 -# type: ignore TIME_FIELD = "created" MAX_CANDIDATES_IN_LIST = 1000 diff --git a/Packs/CyrenInboxSecurity/Scripts/CyrenShowThreatIndicators/CyrenShowThreatIndicators.py b/Packs/CyrenInboxSecurity/Scripts/CyrenShowThreatIndicators/CyrenShowThreatIndicators.py index a1aa7adf97e6..bdafbd1a39a1 100644 --- a/Packs/CyrenInboxSecurity/Scripts/CyrenShowThreatIndicators/CyrenShowThreatIndicators.py +++ b/Packs/CyrenInboxSecurity/Scripts/CyrenShowThreatIndicators/CyrenShowThreatIndicators.py @@ -1,8 +1,5 @@ import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 -# noqa: F401 -# noqa: F401 -# type: ignore import json diff --git a/Packs/CyrenInboxSecurity/pack_metadata.json b/Packs/CyrenInboxSecurity/pack_metadata.json index db2f72369234..00ced76ba114 100644 --- a/Packs/CyrenInboxSecurity/pack_metadata.json +++ b/Packs/CyrenInboxSecurity/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Cyren Inbox Security", "description": "Cyren Inbox Security protects Office 365 mailboxes from evasive phishing, business email compromise, and fraud.", "support": "partner", - "currentVersion": "1.1.12", + "currentVersion": "1.1.13", "author": "Cyren", "url": "https://www.cyren.com/products/cyren-inbox-security", "email": "paltoalto-cortex-xsoar@cyren.com", diff --git a/Packs/ForescoutEyeInspect/Integrations/ForescoutEyeInspect/ForescoutEyeInspect.py b/Packs/ForescoutEyeInspect/Integrations/ForescoutEyeInspect/ForescoutEyeInspect.py index e7a9921edbc2..39fc69255eae 100644 --- a/Packs/ForescoutEyeInspect/Integrations/ForescoutEyeInspect/ForescoutEyeInspect.py +++ b/Packs/ForescoutEyeInspect/Integrations/ForescoutEyeInspect/ForescoutEyeInspect.py @@ -1,10 +1,9 @@ import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 -# type: ignore -# mypy: ignore-errors + from copy import deepcopy -from typing import Any, Dict, Tuple, Type -from urllib.parse import urljoin +from typing import Any +from urllib.parse import urljoin # type: ignore import urllib3 @@ -61,7 +60,7 @@ def list_hosts_request(self, last_seen: Optional[str] = None, id_min: Optional[int] = None, sort_field: Optional[str] = None, - sort_ascending: Optional[bool] = None) -> List[Dict[str, Any]]: + sort_ascending: Optional[bool] = None) -> List[dict[str, Any]]: """ Retrieves information about the hosts in the eyeInspect CC database. @@ -99,7 +98,7 @@ def list_links_request(self, last_seen: Optional[str] = None, id_min: Optional[int] = None, sort_field: Optional[str] = None, - sort_ascending: Optional[bool] = None) -> List[Dict[str, Any]]: + sort_ascending: Optional[bool] = None) -> List[dict[str, Any]]: """ Retrieves information about the links in the eyeInspect CC database. @@ -134,7 +133,7 @@ def list_links_request(self, return self._http_request(method='GET', url_suffix='links', params=params) - def get_vulnerability_info_request(self, cve_id: str) -> Dict[str, Any]: + def get_vulnerability_info_request(self, cve_id: str) -> dict[str, Any]: """ Retrieves information about a specific vulnerability stored in the eyeInspect CC database. @@ -161,7 +160,7 @@ def list_alerts_request(self, dst_port: Optional[int] = None, src_host_id: Optional[int] = None, dst_host_id: Optional[int] = None, - host_id: Optional[int] = None) -> List[Dict[str, Any]]: + host_id: Optional[int] = None) -> List[dict[str, Any]]: """ Retrieves information about the alerts inside eyeInspect CC. @@ -225,7 +224,7 @@ def get_alert_pcap_request(self, alert_id: int) -> bytes: def list_sensors_request(self, offset: Optional[int] = None, limit: Optional[int] = None, - all_sensors: Optional[bool] = None) -> List[Dict[str, Any]]: + all_sensors: Optional[bool] = None) -> List[dict[str, Any]]: """ Retrieves information about the sensors associated to the eyeInspect CC. @@ -249,7 +248,7 @@ def list_sensors_request(self, def list_sensor_modules_request(self, sensor_id: int, offset: Optional[int] = None, - limit: Optional[int] = None) -> List[Dict[str, Any]]: + limit: Optional[int] = None) -> List[dict[str, Any]]: """ Retrieves information about the Modules of the specified Sensor. @@ -274,7 +273,7 @@ def update_sensor_module_request(self, name: Optional[str] = None, description: Optional[str] = None, started: Optional[bool] = None, - operational_mode: Optional[str] = None) -> Dict[str, Any]: + operational_mode: Optional[str] = None) -> dict[str, Any]: """ Changes the specified properties of the specified Module. @@ -317,7 +316,7 @@ def delete_sensor_module_request(self, sensor_id: int, module_id: int) -> None: def get_ip_blacklist_request(self, sensor_id: int, offset: Optional[int] = None, - limit: Optional[int] = None) -> List[Dict[str, Any]]: + limit: Optional[int] = None) -> List[dict[str, Any]]: """ Retrieves the IP blacklist from the Industrial Threat Library of the specified Sensor. @@ -356,7 +355,7 @@ def add_ip_blacklist_request(self, sensor_id: int, address: str, comment: str = def get_domain_blacklist_request(self, sensor_id: int, offset: Optional[int] = None, - limit: Optional[int] = None) -> List[Dict[str, Any]]: + limit: Optional[int] = None) -> List[dict[str, Any]]: """ Retrieves the domain name blacklist from the Industrial Threat Library of the specified Sensor. @@ -399,7 +398,7 @@ def add_domain_blacklist_request(self, def get_ssl_client_blacklist_request(self, sensor_id: int, offset: Optional[int] = None, - limit: Optional[int] = None) -> List[Dict[str, Any]]: + limit: Optional[int] = None) -> List[dict[str, Any]]: """ Retrieves the SSL client application blacklist from the Industrial Threat Library of the specified Sensor. @@ -447,7 +446,7 @@ def add_ssl_client_blacklist_request(self, def get_file_operation_blacklist_request(self, sensor_id: int, offset: Optional[int] = None, - limit: Optional[int] = None) -> List[Dict[str, str]]: + limit: Optional[int] = None) -> List[dict[str, str]]: """ Retrieves the file operation blacklist from the Industrial Threat Library of the specified Sensor. @@ -495,7 +494,7 @@ def add_file_operation_blacklist_request(self, json_data=body, resp_type='text') - def get_diagnostics_information_request(self) -> Dict[str, Any]: + def get_diagnostics_information_request(self) -> dict[str, Any]: """ Retrieves information about all monitored Command Center resources and their health status excluding the logs. @@ -528,7 +527,7 @@ def get_diagnostic_logs_request(self, def list_group_policies_request(self, offset: Optional[int] = None, - limit: Optional[int] = None) -> List[Dict[str, Any]]: + limit: Optional[int] = None) -> List[dict[str, Any]]: """ Get all group policies. @@ -545,7 +544,7 @@ def list_group_policies_request(self, return self._http_request(method='GET', url_suffix='group_policy', params=params) def create_group_policy_request(self, name: str, description: str, - constraints: List[Dict[str, Any]]) -> Dict[str, Any]: + constraints: List[dict[str, Any]]) -> dict[str, Any]: """ Create a new group policy. @@ -563,7 +562,7 @@ def create_group_policy_request(self, name: str, description: str, return self._http_request(method='POST', url_suffix='group_policy', json_data=body) def update_group_policy_request(self, policy_id: int, name: str, description: str, - constraints: List[Dict[str, Any]]) -> Dict[str, Any]: + constraints: List[dict[str, Any]]) -> dict[str, Any]: """ Update a group policy. @@ -596,7 +595,7 @@ def delete_group_policy_request(self, policy_id: int) -> None: resp_type='text') def assign_group_policy_hosts_request(self, policy_id: int, filter_type: str, - filter_value: str) -> Dict[str, Any]: + filter_value: str) -> dict[str, Any]: """ Add all hosts not assigned to any policy (individual or group) matching the filter to the group policy. @@ -616,7 +615,7 @@ def assign_group_policy_hosts_request(self, policy_id: int, filter_type: str, json_data=body) def unassign_group_policy_hosts_request(self, policy_id: int, filter_type: str, - filter_value: str) -> Dict[str, Any]: + filter_value: str) -> dict[str, Any]: """ Unassign all hosts assigned to the group policy matching the filter. @@ -637,7 +636,7 @@ def unassign_group_policy_hosts_request(self, policy_id: int, filter_type: str, def list_ip_reuse_domains_request(self, offset: Optional[int] = None, - limit: Optional[int] = None) -> List[Dict[str, Any]]: + limit: Optional[int] = None) -> List[dict[str, Any]]: """ Get all IP reuse domains. @@ -660,7 +659,7 @@ def list_hosts_changelog_request(self, start_timestamp: Optional[str] = None, end_timestamp: Optional[str] = None, event_type_id: Optional[str] = None, - event_category: Optional[str] = None) -> List[Dict[str, Any]]: + event_category: Optional[str] = None) -> List[dict[str, Any]]: """ Retrieves information about the changes of host properties and configuration from the eyeInspect CC database. @@ -696,7 +695,7 @@ def _http_request(self, method: str, url_suffix: str = '', full_url: str = None, - headers: Dict[str, str] = None, + headers: dict[str, str] = None, *args, **kwargs): if method in ['POST', 'PUT', 'DELETE']: @@ -723,7 +722,7 @@ def _get_csrf_token(self) -> str: return token_response.headers['X-CSRF-Token'] -def arg_to_type_list(arg: str, item_type: Type[Any]) -> List[Any]: +def arg_to_type_list(arg: str, item_type: type[Any]) -> List[Any]: """ Converts XSOAR argument to list with certain type. @@ -815,7 +814,7 @@ def matches_one_item(items: List[Any], container_list: List[Any]) -> bool: return any(True for item in items if item in container_list) -def filter_single_result(result: Dict[str, Any], **fields: List[Any]) -> bool: +def filter_single_result(result: dict[str, Any], **fields: List[Any]) -> bool: """ Filters a single result of the API, based on the results fields. @@ -841,7 +840,7 @@ def filter_single_result(result: Dict[str, Any], **fields: List[Any]) -> bool: return True -def filter_results(results: List[Dict[str, Any]], **fields: List[Any]) -> List[Dict[str, Any]]: +def filter_results(results: List[dict[str, Any]], **fields: List[Any]) -> List[dict[str, Any]]: """ Filters records from the API based on the provided fields. This is required due to lack of essential fields inside the API filtering. @@ -856,7 +855,7 @@ def filter_results(results: List[Dict[str, Any]], **fields: List[Any]) -> List[D return [result for result in results if filter_single_result(result, **fields)] -def add_alerts_fields(client: Client, alerts: List[Dict[str, Any]]) -> None: +def add_alerts_fields(client: Client, alerts: List[dict[str, Any]]) -> None: """ Adds additional data to the alerts. @@ -870,7 +869,7 @@ def add_alerts_fields(client: Client, alerts: List[Dict[str, Any]]) -> None: alert['xsoar_severity'] = XSOAR_SEVERITY_MAPPING.get(alert['severity'], alert['severity']) -def get_pagination_arguments(args: Dict[str, Any]) -> Tuple[int, int, int]: +def get_pagination_arguments(args: dict[str, Any]) -> tuple[int, int, int]: """ Gets and validates pagination arguments for client (offset and limit). @@ -884,12 +883,12 @@ def get_pagination_arguments(args: Dict[str, Any]) -> Tuple[int, int, int]: page = arg_to_number(args.get('page', DEFAULT_PAGE)) limit = arg_to_number(args.get('limit', DEFAULT_LIMIT)) - if page < 1: + if page < 1: # type: ignore[operator] raise DemistoException('Page argument must be greater than 1') - if not 1 <= limit <= MAX_LIMIT: + if not 1 <= limit <= MAX_LIMIT: # type: ignore[operator] raise DemistoException(f'Limit argument must be between 1 to {MAX_LIMIT}') - return page, (page - 1) * limit, limit + return page, (page - 1) * limit, limit # type: ignore[operator,return-value] def validate_fetch_params(max_fetch: int, first_fetch: str) -> None: @@ -911,7 +910,7 @@ def validate_fetch_params(max_fetch: int, first_fetch: str) -> None: f'The Maximum number of incidents per fetch should not exceed {MAX_FETCH_INCIDENTS}.') -def list_hosts_command(client: Client, args: Dict[str, str]) -> CommandResults: +def list_hosts_command(client: Client, args: dict[str, str]) -> CommandResults: """ Retrieves information about the hosts in the eyeInspect CC database. @@ -935,12 +934,12 @@ def list_hosts_command(client: Client, args: Dict[str, str]) -> CommandResults: id_min=id_min, sort_field=sort_field, sort_ascending=sort_ascending) - outputs = response['results'] + outputs = response['results'] # type: ignore[call-overload] ip_addresses = argToList(args.get('ip')) vlan_ids = argToList(args.get('vlan_id')) mac_addresses = argToList(args.get('mac_address')) - sensor_ids = arg_to_type_list(args.get('sensor_id'), int) + sensor_ids = arg_to_type_list(args.get('sensor_id'), int) # type: ignore[arg-type] outputs = filter_results(outputs, ip=ip_addresses, vlans=vlan_ids, @@ -962,7 +961,7 @@ def list_hosts_command(client: Client, args: Dict[str, str]) -> CommandResults: raw_response=response) -def list_links_command(client: Client, args: Dict[str, str]) -> CommandResults: +def list_links_command(client: Client, args: dict[str, str]) -> CommandResults: """ Retrieves information about the links in the eyeInspect CC database. @@ -994,7 +993,7 @@ def list_links_command(client: Client, args: Dict[str, str]) -> CommandResults: id_min=id_min, sort_field=sort_field, sort_ascending=sort_ascending) - outputs = response['results'] + outputs = response['results'] # type: ignore[call-overload] readable_output = tableToMarkdown('Host Links List:', outputs, @@ -1010,7 +1009,7 @@ def list_links_command(client: Client, args: Dict[str, str]) -> CommandResults: raw_response=response) -def get_vulnerability_info_command(client: Client, args: Dict[str, str]) -> CommandResults: +def get_vulnerability_info_command(client: Client, args: dict[str, str]) -> CommandResults: """ Retrieves information about a specific vulnerability stored in the eyeInspect CC database. @@ -1039,7 +1038,7 @@ def get_vulnerability_info_command(client: Client, args: Dict[str, str]) -> Comm raw_response=response) -def list_alerts_command(client: Client, args: Dict[str, str]) -> CommandResults: +def list_alerts_command(client: Client, args: dict[str, str]) -> CommandResults: """ Retrieves information about the alerts inside eyeInspect CC. @@ -1071,11 +1070,11 @@ def list_alerts_command(client: Client, args: Dict[str, str]) -> CommandResults: src_ip=src_ip, dst_ip=dst_ip, ip=ip) - outputs = response['results'] + outputs = response['results'] # type: ignore[call-overload] sensor_names = argToList(args.get('sensor_name')) vlan_ids = argToList(args.get('vlan_id')) - severities = arg_to_type_list(args.get('severity'), int) + severities = arg_to_type_list(args.get('severity'), int) # type: ignore[arg-type] statuses = argToList(args.get('status')) outputs = filter_results(outputs, sensor_name=sensor_names, @@ -1099,7 +1098,7 @@ def list_alerts_command(client: Client, args: Dict[str, str]) -> CommandResults: raw_response=response) -def get_alert_pcap_command(client: Client, args: Dict[str, str]) -> Dict[str, Any]: +def get_alert_pcap_command(client: Client, args: dict[str, str]) -> dict[str, Any]: """ Retrieves the PCAP file associated to a given Alert. @@ -1112,14 +1111,14 @@ def get_alert_pcap_command(client: Client, args: Dict[str, str]) -> Dict[str, An """ alert_id = arg_to_number(args['alert_id']) - response = client.get_alert_pcap_request(alert_id=alert_id) + response = client.get_alert_pcap_request(alert_id=alert_id) # type: ignore[arg-type] return fileResult(filename=f'alert_{alert_id}_sniff.pcap', data=response, file_type=EntryType.ENTRY_INFO_FILE) -def list_sensors_command(client: Client, args: Dict[str, str]) -> CommandResults: +def list_sensors_command(client: Client, args: dict[str, str]) -> CommandResults: """ Retrieves information about the sensors associated to the eyeInspect CC. @@ -1135,11 +1134,11 @@ def list_sensors_command(client: Client, args: Dict[str, str]) -> CommandResults all_sensors = arg_to_boolean(args.get('all_sensors')) response = client.list_sensors_request(offset=offset, limit=limit, all_sensors=all_sensors) - outputs = response['results'] + outputs = response['results'] # type: ignore[call-overload] names = argToList(args.get('name')) addresses = argToList(args.get('address')) - ports = arg_to_type_list(args.get('port'), int) + ports = arg_to_type_list(args.get('port'), int) # type: ignore[arg-type] sensor_types = argToList(args.get('type')) states = argToList(args.get('state')) outputs = filter_results(outputs, @@ -1163,7 +1162,7 @@ def list_sensors_command(client: Client, args: Dict[str, str]) -> CommandResults raw_response=response) -def list_sensor_modules_command(client: Client, args: Dict[str, str]) -> CommandResults: +def list_sensor_modules_command(client: Client, args: dict[str, str]) -> CommandResults: """ Retrieves information about the Modules of the specified Sensor. @@ -1178,8 +1177,8 @@ def list_sensor_modules_command(client: Client, args: Dict[str, str]) -> Command sensor_id = arg_to_number(args['sensor_id']) page, offset, limit = get_pagination_arguments(args) - response = client.list_sensor_modules_request(sensor_id=sensor_id, offset=offset, limit=limit) - outputs = response['results'] + response = client.list_sensor_modules_request(sensor_id=sensor_id, offset=offset, limit=limit) # type: ignore[arg-type] + outputs = response['results'] # type: ignore[call-overload] readable_output = tableToMarkdown(f'Sensor {sensor_id} Modules List:', outputs, @@ -1195,7 +1194,7 @@ def list_sensor_modules_command(client: Client, args: Dict[str, str]) -> Command raw_response=response) -def update_sensor_module_command(client: Client, args: Dict[str, str]) -> CommandResults: +def update_sensor_module_command(client: Client, args: dict[str, str]) -> CommandResults: """ Changes the specified properties of the specified Module. @@ -1214,8 +1213,8 @@ def update_sensor_module_command(client: Client, args: Dict[str, str]) -> Comman started = arg_to_boolean(args.get('started')) operational_mode = args.get('operational_mode') - response = client.update_sensor_module_request(sensor_id=sensor_id, - module_id=module_id, + response = client.update_sensor_module_request(sensor_id=sensor_id, # type: ignore[arg-type] + module_id=module_id, # type: ignore[arg-type] name=name, description=description, started=started, @@ -1233,7 +1232,7 @@ def update_sensor_module_command(client: Client, args: Dict[str, str]) -> Comman raw_response=response) -def delete_sensor_module_command(client: Client, args: Dict[str, str]) -> CommandResults: +def delete_sensor_module_command(client: Client, args: dict[str, str]) -> CommandResults: """ Deletes the specified Module from the specified Sensor and from the eyeInspect CC database. @@ -1248,13 +1247,13 @@ def delete_sensor_module_command(client: Client, args: Dict[str, str]) -> Comman sensor_id = arg_to_number(args['sensor_id']) module_id = arg_to_number(args['module_id']) - client.delete_sensor_module_request(sensor_id=sensor_id, module_id=module_id) + client.delete_sensor_module_request(sensor_id=sensor_id, module_id=module_id) # type: ignore[arg-type] readable_output = f'## The module {module_id} of sensor {sensor_id} was successfully deleted!' return CommandResults(readable_output=readable_output) -def get_ip_blacklist_command(client: Client, args: Dict[str, str]) -> CommandResults: +def get_ip_blacklist_command(client: Client, args: dict[str, str]) -> CommandResults: """ Retrieves the IP blacklist from the Industrial Threat Library of the specified Sensor. @@ -1269,9 +1268,9 @@ def get_ip_blacklist_command(client: Client, args: Dict[str, str]) -> CommandRes sensor_id = arg_to_number(args['sensor_id']) page, offset, limit = get_pagination_arguments(args) - response = client.get_ip_blacklist_request(sensor_id=sensor_id, offset=offset, limit=limit) + response = client.get_ip_blacklist_request(sensor_id=sensor_id, offset=offset, limit=limit) # type: ignore[arg-type] - outputs = deepcopy(response['results']) + outputs = deepcopy(response['results']) # type: ignore[call-overload] for entry in outputs: entry['sensor_id'] = sensor_id @@ -1289,7 +1288,7 @@ def get_ip_blacklist_command(client: Client, args: Dict[str, str]) -> CommandRes raw_response=response) -def add_ip_blacklist_command(client: Client, args: Dict[str, str]) -> CommandResults: +def add_ip_blacklist_command(client: Client, args: dict[str, str]) -> CommandResults: """ Adds a new entry to the IP blacklist from the Industrial Threat Library of the specified Sensor. @@ -1305,7 +1304,7 @@ def add_ip_blacklist_command(client: Client, args: Dict[str, str]) -> CommandRes address = args['address'] comment = args.get('comment', '') - client.add_ip_blacklist_request(sensor_id=sensor_id, address=address, comment=comment) + client.add_ip_blacklist_request(sensor_id=sensor_id, address=address, comment=comment) # type: ignore[arg-type] outputs = {'address': address, 'comment': comment} readable_output = tableToMarkdown(f'New IP Blacklist Entry of Sensor {sensor_id}:', @@ -1317,7 +1316,7 @@ def add_ip_blacklist_command(client: Client, args: Dict[str, str]) -> CommandRes return CommandResults(readable_output=readable_output) -def get_domain_blacklist_command(client: Client, args: Dict[str, str]) -> CommandResults: +def get_domain_blacklist_command(client: Client, args: dict[str, str]) -> CommandResults: """ Retrieves the domain name blacklist from the Industrial Threat Library of the specified Sensor. @@ -1332,9 +1331,9 @@ def get_domain_blacklist_command(client: Client, args: Dict[str, str]) -> Comman sensor_id = arg_to_number(args['sensor_id']) page, offset, limit = get_pagination_arguments(args) - response = client.get_domain_blacklist_request(sensor_id=sensor_id, offset=offset, limit=limit) + response = client.get_domain_blacklist_request(sensor_id=sensor_id, offset=offset, limit=limit) # type: ignore[arg-type] - outputs = deepcopy(response['results']) + outputs = deepcopy(response['results']) # type: ignore[call-overload] for entry in outputs: entry['sensor_id'] = sensor_id @@ -1352,7 +1351,7 @@ def get_domain_blacklist_command(client: Client, args: Dict[str, str]) -> Comman raw_response=response) -def add_domain_blacklist_command(client: Client, args: Dict[str, str]) -> CommandResults: +def add_domain_blacklist_command(client: Client, args: dict[str, str]) -> CommandResults: """ Adds a new entry to the domain name blacklist from the Industrial Threat Library of the specified Sensor. @@ -1368,7 +1367,7 @@ def add_domain_blacklist_command(client: Client, args: Dict[str, str]) -> Comman domain_name = args['domain_name'] comment = args.get('comment', '') - client.add_domain_blacklist_request(sensor_id=sensor_id, + client.add_domain_blacklist_request(sensor_id=sensor_id, # type: ignore[arg-type] domain_name=domain_name, comment=comment) @@ -1382,7 +1381,7 @@ def add_domain_blacklist_command(client: Client, args: Dict[str, str]) -> Comman return CommandResults(readable_output=readable_output) -def get_ssl_client_blacklist_command(client: Client, args: Dict[str, str]) -> CommandResults: +def get_ssl_client_blacklist_command(client: Client, args: dict[str, str]) -> CommandResults: """ Retrieves the SSL client application blacklist from the Industrial Threat Library of the specified Sensor. @@ -1397,11 +1396,11 @@ def get_ssl_client_blacklist_command(client: Client, args: Dict[str, str]) -> Co sensor_id = arg_to_number(args['sensor_id']) page, offset, limit = get_pagination_arguments(args) - response = client.get_ssl_client_blacklist_request(sensor_id=sensor_id, + response = client.get_ssl_client_blacklist_request(sensor_id=sensor_id, # type: ignore[arg-type] offset=offset, limit=limit) - outputs = deepcopy(response['results']) + outputs = deepcopy(response['results']) # type: ignore[call-overload] for entry in outputs: entry['sensor_id'] = sensor_id @@ -1419,7 +1418,7 @@ def get_ssl_client_blacklist_command(client: Client, args: Dict[str, str]) -> Co raw_response=response) -def add_ssl_client_blacklist_command(client: Client, args: Dict[str, str]) -> CommandResults: +def add_ssl_client_blacklist_command(client: Client, args: dict[str, str]) -> CommandResults: """ Adds a new entry to the SSL client application blacklist from the Industrial Threat Library of the specified Sensor. @@ -1436,7 +1435,7 @@ def add_ssl_client_blacklist_command(client: Client, args: Dict[str, str]) -> Co ja3_hash = args['ja3_hash'] comment = args.get('comment', '') - client.add_ssl_client_blacklist_request(sensor_id=sensor_id, + client.add_ssl_client_blacklist_request(sensor_id=sensor_id, # type: ignore[arg-type] application_name=application_name, ja3_hash=ja3_hash, comment=comment) @@ -1455,7 +1454,7 @@ def add_ssl_client_blacklist_command(client: Client, args: Dict[str, str]) -> Co return CommandResults(readable_output=readable_output) -def get_file_operation_blacklist_command(client: Client, args: Dict[str, str]) -> CommandResults: +def get_file_operation_blacklist_command(client: Client, args: dict[str, str]) -> CommandResults: """ Retrieves the file operation blacklist from the Industrial Threat Library of the specified Sensor. @@ -1470,11 +1469,11 @@ def get_file_operation_blacklist_command(client: Client, args: Dict[str, str]) - sensor_id = arg_to_number(args['sensor_id']) page, offset, limit = get_pagination_arguments(args) - response = client.get_file_operation_blacklist_request(sensor_id=sensor_id, + response = client.get_file_operation_blacklist_request(sensor_id=sensor_id, # type: ignore[arg-type] offset=offset, limit=limit) - outputs = deepcopy(response['results']) + outputs = deepcopy(response['results']) # type: ignore[call-overload] for entry in outputs: entry['sensor_id'] = sensor_id @@ -1493,7 +1492,7 @@ def get_file_operation_blacklist_command(client: Client, args: Dict[str, str]) - raw_response=response) -def add_file_operation_blacklist_command(client: Client, args: Dict[str, str]) -> CommandResults: +def add_file_operation_blacklist_command(client: Client, args: dict[str, str]) -> CommandResults: """ Adds entries to the file operation blacklist from the Industrial Threat Library of the specified Sensor. @@ -1511,7 +1510,7 @@ def add_file_operation_blacklist_command(client: Client, args: Dict[str, str]) - operation = args['operation'] comment = args.get('comment', '') - client.add_file_operation_blacklist_request(sensor_id=sensor_id, + client.add_file_operation_blacklist_request(sensor_id=sensor_id, # type: ignore[arg-type] matching_type=matching_type, file_or_folder=file_or_folder, operation=operation, @@ -1559,7 +1558,7 @@ def get_diagnostics_information_command(client: Client, *_) -> CommandResults: raw_response=response) -def get_diagnostic_logs_command(client: Client, args: Dict[str, str]) -> Dict[str, Any]: +def get_diagnostic_logs_command(client: Client, args: dict[str, str]) -> dict[str, Any]: """ Download the ZIP file which contains diagnostic logs of the Command Center. @@ -1581,7 +1580,7 @@ def get_diagnostic_logs_command(client: Client, args: Dict[str, str]) -> Dict[st file_type=EntryType.ENTRY_INFO_FILE) -def list_group_policies_command(client: Client, args: Dict[str, str]) -> CommandResults: +def list_group_policies_command(client: Client, args: dict[str, str]) -> CommandResults: """ Get all group policies. @@ -1596,7 +1595,7 @@ def list_group_policies_command(client: Client, args: Dict[str, str]) -> Command page, offset, limit = get_pagination_arguments(args) response = client.list_group_policies_request(offset=offset, limit=limit) - outputs = response['results'] + outputs = response['results'] # type: ignore[call-overload] readable_output = tableToMarkdown('Group Policies List:', outputs, @@ -1614,7 +1613,7 @@ def list_group_policies_command(client: Client, args: Dict[str, str]) -> Command ) -def create_group_policy_command(client: Client, args: Dict[str, str]) -> CommandResults: +def create_group_policy_command(client: Client, args: dict[str, str]) -> CommandResults: """ Create a group policy. @@ -1655,7 +1654,7 @@ def create_group_policy_command(client: Client, args: Dict[str, str]) -> Command raw_response=response) -def update_group_policy_command(client: Client, args: Dict[str, str]) -> CommandResults: +def update_group_policy_command(client: Client, args: dict[str, str]) -> CommandResults: """ Update a group policy. @@ -1672,7 +1671,7 @@ def update_group_policy_command(client: Client, args: Dict[str, str]) -> Command description = args['description'] constraints = argToList(args['constraints']) - response = client.update_group_policy_request(policy_id=policy_id, + response = client.update_group_policy_request(policy_id=policy_id, # type: ignore[arg-type] name=name, description=description, constraints=constraints) @@ -1700,7 +1699,7 @@ def update_group_policy_command(client: Client, args: Dict[str, str]) -> Command ) -def delete_group_policy_command(client: Client, args: Dict[str, str]) -> CommandResults: +def delete_group_policy_command(client: Client, args: dict[str, str]) -> CommandResults: """ Delete a group policy. @@ -1714,12 +1713,12 @@ def delete_group_policy_command(client: Client, args: Dict[str, str]) -> Command policy_id = arg_to_number(args['policy_id']) - client.delete_group_policy_request(policy_id=policy_id) + client.delete_group_policy_request(policy_id=policy_id) # type: ignore[arg-type] return CommandResults( readable_output=f'## The group policy {policy_id} was successfully deleted!') -def assign_group_policy_hosts_command(client: Client, args: Dict[str, str]) -> CommandResults: +def assign_group_policy_hosts_command(client: Client, args: dict[str, str]) -> CommandResults: """ Add all hosts not assigned to any policy (individual or group) matching the filter to the group policy. @@ -1735,7 +1734,7 @@ def assign_group_policy_hosts_command(client: Client, args: Dict[str, str]) -> C filter_type = args['filter_type'] filter_value = args['filter_value'] - response = client.assign_group_policy_hosts_request(policy_id=policy_id, + response = client.assign_group_policy_hosts_request(policy_id=policy_id, # type: ignore[arg-type] filter_type=filter_type, filter_value=filter_value) readable_output = f'## {response["count"]} Additional Hosts Were Assigned to Group Policy {policy_id}!' @@ -1743,7 +1742,7 @@ def assign_group_policy_hosts_command(client: Client, args: Dict[str, str]) -> C return CommandResults(readable_output=readable_output, raw_response=response) -def unassign_group_policy_hosts_command(client: Client, args: Dict[str, str]) -> CommandResults: +def unassign_group_policy_hosts_command(client: Client, args: dict[str, str]) -> CommandResults: """ Unassign all hosts assigned to the group policy matching the filter. @@ -1759,7 +1758,7 @@ def unassign_group_policy_hosts_command(client: Client, args: Dict[str, str]) -> filter_type = args['filter_type'] filter_value = args['filter_value'] - response = client.unassign_group_policy_hosts_request(policy_id=policy_id, + response = client.unassign_group_policy_hosts_request(policy_id=policy_id, # type: ignore[arg-type] filter_type=filter_type, filter_value=filter_value) readable_output = f'## {response["count"]} Additional Hosts Were Unassigned from Group Policy {policy_id}!' @@ -1767,7 +1766,7 @@ def unassign_group_policy_hosts_command(client: Client, args: Dict[str, str]) -> return CommandResults(readable_output=readable_output, raw_response=response) -def list_ip_reuse_domains_command(client: Client, args: Dict[str, str]) -> CommandResults: +def list_ip_reuse_domains_command(client: Client, args: dict[str, str]) -> CommandResults: """ Get all IP reuse domains. @@ -1782,7 +1781,7 @@ def list_ip_reuse_domains_command(client: Client, args: Dict[str, str]) -> Comma page, offset, limit = get_pagination_arguments(args) response = client.list_ip_reuse_domains_request(offset=offset, limit=limit) - outputs = response['results'] + outputs = response['results'] # type: ignore[call-overload] readable_output = tableToMarkdown('IP Reuse Domains List:', outputs, @@ -1798,7 +1797,7 @@ def list_ip_reuse_domains_command(client: Client, args: Dict[str, str]) -> Comma raw_response=response) -def list_hosts_changelog_command(client: Client, args: Dict[str, str]) -> CommandResults: +def list_hosts_changelog_command(client: Client, args: dict[str, str]) -> CommandResults: """ Retrieves information about the changes of host properties and configuration from the eyeInspect CC database. @@ -1824,7 +1823,7 @@ def list_hosts_changelog_command(client: Client, args: Dict[str, str]) -> Comman end_timestamp=end_timestamp, event_type_id=event_type_id, event_category=event_category) - outputs = response['results'] + outputs = response['results'] # type: ignore[call-overload] readable_output = tableToMarkdown( 'Hosts Changes List:', @@ -1872,7 +1871,7 @@ def test_module(client: Client, should_fetch: bool, first_fetch: str, max_fetch: def fetch_alerts(client: Client, last_time: datetime, max_fetch: int, - last_incident_id: int) -> List[Dict[str, Any]]: + last_incident_id: int) -> List[dict[str, Any]]: """ Fetches alerts with pagination. This is essential since the API might return earlier alerts @@ -1888,11 +1887,11 @@ def fetch_alerts(client: Client, last_time: datetime, max_fetch: int, List[Dict[str, Any]]: The new fetched alerts. """ - alerts = [] + alerts = [] # type: ignore[var-annotated] offset = 0 while max_fetch > 0: - results = client.list_alerts_request(offset=offset, + results = client.list_alerts_request(offset=offset, # type: ignore[union-attr,call-overload] limit=max_fetch, start_timestamp=last_time.isoformat())['results'] offset += len(results) @@ -1923,10 +1922,10 @@ def fetch_incidents(client: Client, first_fetch: str, max_fetch: int) -> None: validate_fetch_params(max_fetch=max_fetch, first_fetch=first_fetch) last_run = demisto.getLastRun() or {} - last_time = arg_to_datetime(last_run.get('time') or first_fetch).astimezone() + last_time = arg_to_datetime(last_run.get('time') or first_fetch).astimezone() # type: ignore[union-attr] last_incident_id = last_run.get('incident_id') - alerts = fetch_alerts(client, last_time, max_fetch, last_incident_id) + alerts = fetch_alerts(client, last_time, max_fetch, last_incident_id) # type: ignore[arg-type] add_alerts_fields(client, alerts) incidents = [] @@ -1957,7 +1956,7 @@ def main(): client = Client(server_url, username, password, use_ssl, use_proxy) max_fetch = arg_to_number(params.get('max_fetch', DEFAULT_FETCH_INCIDENTS)) - max_fetch = min(max_fetch, MAX_FETCH_INCIDENTS) + max_fetch = min(max_fetch, MAX_FETCH_INCIDENTS) # type: ignore[type-var] first_fetch = params.get('first_fetch', DEFAULT_FIRST_FETCH) commands = { @@ -1994,12 +1993,12 @@ def main(): command = demisto.command() if command == 'fetch-incidents': - fetch_incidents(client, first_fetch, max_fetch) + fetch_incidents(client, first_fetch, max_fetch) # type: ignore[arg-type] elif command == 'test-module': should_fetch = arg_to_boolean(params.get('isFetch')) - return_results(test_module(client, should_fetch, first_fetch, max_fetch)) + return_results(test_module(client, should_fetch, first_fetch, max_fetch)) # type: ignore[arg-type] elif command in commands: - return_results(commands[command](client, demisto.args())) + return_results(commands[command](client, demisto.args())) # type: ignore[operator] else: raise NotImplementedError(f'The command {command} does not exist!') except Exception as e: diff --git a/Packs/ForescoutEyeInspect/Integrations/ForescoutEyeInspect/ForescoutEyeInspect.yml b/Packs/ForescoutEyeInspect/Integrations/ForescoutEyeInspect/ForescoutEyeInspect.yml index 04ce7065411e..8a9eed3dc7f7 100644 --- a/Packs/ForescoutEyeInspect/Integrations/ForescoutEyeInspect/ForescoutEyeInspect.yml +++ b/Packs/ForescoutEyeInspect/Integrations/ForescoutEyeInspect/ForescoutEyeInspect.yml @@ -1113,7 +1113,7 @@ script: - contextPath: ForescoutEyeInspect.HostChangeLog.host_mac_addresses description: The MAC addresses associated to the host. type: String - dockerimage: demisto/python3:3.10.13.87159 + dockerimage: demisto/python3:3.11.9.105369 isfetch: true runonce: false script: "-" diff --git a/Packs/ForescoutEyeInspect/ReleaseNotes/1_0_22.md b/Packs/ForescoutEyeInspect/ReleaseNotes/1_0_22.md new file mode 100644 index 000000000000..30d65c742e9c --- /dev/null +++ b/Packs/ForescoutEyeInspect/ReleaseNotes/1_0_22.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Forescout EyeInspect + +- Maintenance and stability enhancements. diff --git a/Packs/ForescoutEyeInspect/pack_metadata.json b/Packs/ForescoutEyeInspect/pack_metadata.json index 550b2fa3c6bb..0f194fae75c4 100644 --- a/Packs/ForescoutEyeInspect/pack_metadata.json +++ b/Packs/ForescoutEyeInspect/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Forescout EyeInspect", "description": "Get in-depth device visibility for OT networks", "support": "xsoar", - "currentVersion": "1.0.21", + "currentVersion": "1.0.22", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/FortiSIEM/Integrations/FortiSIEMV2/FortiSIEMV2.py b/Packs/FortiSIEM/Integrations/FortiSIEMV2/FortiSIEMV2.py index b6509a19ef48..68108526d021 100644 --- a/Packs/FortiSIEM/Integrations/FortiSIEMV2/FortiSIEMV2.py +++ b/Packs/FortiSIEM/Integrations/FortiSIEMV2/FortiSIEMV2.py @@ -1,7 +1,6 @@ import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 -# type: ignore -# mypy: ignore-errors + import json import re from collections.abc import Callable @@ -128,8 +127,8 @@ def cmdb_devices_list_request(self, include_ip_list: list, exclude_ip_list: list Returns: Dict[str,Any]: API response from FortiSIEM. """ - include_ip_set = build_ip_set([include_ip_list, include_ip_range]) - exclude_ip_set = build_ip_set([exclude_ip_list, exclude_ip_rage]) + include_ip_set = build_ip_set([include_ip_list, include_ip_range]) # type: ignore[list-item] + exclude_ip_set = build_ip_set([exclude_ip_list, exclude_ip_rage]) # type: ignore[list-item] params = assign_params(includeIps=include_ip_set, excludeIps=exclude_ip_set) @@ -425,7 +424,7 @@ def search_events_with_polling_command(client: FortiSIEMClient, args: dict[str, """ ScheduledCommand.raise_error_if_not_supported() interval_in_secs = arg_to_number(args.get('interval_in_seconds', '10')) - if interval_in_secs < 10: + if interval_in_secs < 10: # type: ignore[operator] raise ValueError( "The minimum time to wait between command execution when 'polling' should be at least 10 seconds.") timeout = arg_to_number(args.get('timeout_in_seconds', '60')) @@ -442,7 +441,7 @@ def search_events_with_polling_command(client: FortiSIEMClient, args: dict[str, # schedule first poll scheduled_command = ScheduledCommand( command=cmd, - next_run_in_seconds=interval_in_secs, + next_run_in_seconds=interval_in_secs, # type: ignore[arg-type] args=polling_args, timeout_in_seconds=timeout) command_results.scheduled_command = scheduled_command @@ -459,7 +458,7 @@ def search_events_with_polling_command(client: FortiSIEMClient, args: dict[str, } scheduled_command = ScheduledCommand( command=cmd, - next_run_in_seconds=interval_in_secs, + next_run_in_seconds=interval_in_secs, # type: ignore[arg-type] args=polling_args, timeout_in_seconds=timeout) command_results = CommandResults(scheduled_command=scheduled_command) @@ -478,13 +477,13 @@ def events_search_init_command(client: FortiSIEMClient, args: dict[str, Any]) -> Returns: CommandResults: Command results with raw response, outputs and readable outputs. """ - from_time = convert_date_to_timestamp(arg_to_datetime(args['from_time'])) - to_time = convert_date_to_timestamp(arg_to_datetime(args['to_time'])) + from_time = convert_date_to_timestamp(arg_to_datetime(args['from_time'])) # type: ignore[arg-type] + to_time = convert_date_to_timestamp(arg_to_datetime(args['to_time'])) # type: ignore[arg-type] query = args.get('query') extend_data = argToBoolean(args.get('extended_data', False)) events_constraint = query or build_constraint_from_args(copy.deepcopy(args)) - payload = build_query_xml(events_constraint, from_time, to_time, extend_data) - response = client.events_search_init_request(payload.decode('utf-8')) + payload = build_query_xml(events_constraint, from_time, to_time, extend_data) # type: ignore[arg-type] + response = client.events_search_init_request(payload.decode('utf-8')) # type: ignore[attr-defined] if " validate_ip_address(include_ip_list, exclude_ip_list) validate_ip_ranges(include_ip_range, exclude_ip_range) - response = client.cmdb_devices_list_request(include_ip_list, exclude_ip_list, include_ip_range, exclude_ip_range) - outputs, total_pages = format_list_commands_output(response, ['devices', 'device'], page, limit) - header = format_readable_output_header('List CMDB devices', limit, page, total_pages) + response = client.cmdb_devices_list_request(include_ip_list, exclude_ip_list, # type: ignore[arg-type] + include_ip_range, exclude_ip_range) # type: ignore[arg-type] + outputs, total_pages = format_list_commands_output(response, ['devices', 'device'], page, limit) # type: ignore[arg-type] + header = format_readable_output_header('List CMDB devices', limit, page, total_pages) # type: ignore[arg-type] readable_output = tableToMarkdown(header, outputs, headers=['name', 'accessIp', 'approved', 'unmanaged', 'deviceType'], @@ -616,7 +617,7 @@ def cmdb_device_get_command(client: FortiSIEMClient, args: dict[str, Any]) -> Li try: validate_ip_address(ip_address) response = client.cmdb_device_get_request(ip_address) - outputs = format_outputs_time_attributes_to_iso(copy.deepcopy(response.get('device'))) + outputs = format_outputs_time_attributes_to_iso(copy.deepcopy(response.get('device'))) # type: ignore[arg-type] readable_output = tableToMarkdown(f'CMDB device {ip_address}', outputs, headers=['name', 'accessIp', 'approved', 'unmanaged', 'deviceType', 'discoverTime', 'discoverMethod'], @@ -650,10 +651,11 @@ def monitored_organizations_list_command(client: FortiSIEMClient, args: dict[str limit = arg_to_number(args.get('limit', DEFAULT_LIMIT)) page = arg_to_number(args.get('page', DEFAULT_PAGE)) response = client.monitored_organizations_list_request() - outputs, total_pages_number = format_organizations_output(response, page, limit) + outputs, total_pages_number = format_organizations_output(response, page, limit) # type: ignore[arg-type] readable_output = tableToMarkdown( - format_readable_output_header('List Monitored Organizations', limit, page, total_pages_number), outputs, + format_readable_output_header('List Monitored Organizations', limit, page, # type: ignore[arg-type] + total_pages_number), outputs, # type: ignore[arg-type] headers=['domainId', 'name', 'custId', 'creationTime', 'lastModified', 'disabled'], headerTransform=pascalToSpace) command_results = CommandResults( @@ -688,8 +690,15 @@ def incident_update_command(client: FortiSIEMClient, args: dict[str, Any]) -> Co external_ticket_state = args.get('external_ticket_state') external_assigned_user = args.get('external_assigned_user') - response = client.incident_update_request(incident_id, comments, incident_status, external_ticket_type, - external_ticket_id, external_ticket_state, external_assigned_user) + response = client.incident_update_request( + incident_id, + comments, # type: ignore[arg-type] + incident_status, # type: ignore[arg-type] + external_ticket_type, # type: ignore[arg-type] + external_ticket_id, # type: ignore[arg-type] + external_ticket_state, # type: ignore[arg-type] + external_assigned_user # type: ignore[arg-type] + ) command_results = CommandResults(readable_output=format_update_incident_readable_output(incident_id, response)) return command_results @@ -708,10 +717,10 @@ def events_list_command(client: FortiSIEMClient, args: dict[str, Any]) -> Comman limit = arg_to_number(args.get('limit', DEFAULT_LIMIT)) page = arg_to_number(args.get('page', DEFAULT_PAGE)) incident_id = args['incident_id'] - response = client.events_list_request(limit * page, incident_id) - outputs = format_list_events_output(response, incident_id, page, limit) + response = client.events_list_request(limit * page, incident_id) # type: ignore[operator] + outputs = format_list_events_output(response, incident_id, page, limit) # type: ignore[arg-type] readable_output = tableToMarkdown( - format_readable_output_header(f'List Events for incident ID {incident_id}', limit, page), + format_readable_output_header(f'List Events for incident ID {incident_id}', limit, page), # type: ignore[arg-type] get_list_events_readable_output(outputs), headers=["eventID", "eventReceiveTime", "eventType", "message", "sourceIP", "destinationIP", "hostName", "hostIp", "user", "fileName", "command", "filePath", "SHA256Hash", "MD5Hash", "rawEventLog" @@ -746,7 +755,7 @@ def watchlist_list_command(client: FortiSIEMClient, args: dict[str, Any]) -> Com response = client.watchlist_list_all() outputs, total_pages = format_watchlist_output(response, page=page, limit=limit) readable_outputs = tableToMarkdown( - format_readable_output_header('List Watchlist Groups', limit, page, total_pages), + format_readable_output_header('List Watchlist Groups', limit, page, total_pages), # type: ignore[arg-type] outputs, headers=['id', 'name', 'displayName', 'description', 'valueType'], headerTransform=pascalToSpace) command_results = CommandResults( @@ -849,22 +858,22 @@ def watchlist_add_command(client: FortiSIEMClient, args: dict[str, Any]) -> Comm is_case_sensitive = argToBoolean(args.get('is_case_sensitive')) data_creation_type = args.get('data_creation_type') value_type = args.get('value_type') - age_out = datetime_to_age_out_in_days(arg_to_datetime(args.get('age_out'))) + age_out = datetime_to_age_out_in_days(arg_to_datetime(args.get('age_out'))) # type: ignore[arg-type] inclusive = argToBoolean(args.get('entry_inclusive')) entry_value = args.get('entry_value') - entry_age_out = datetime_to_age_out_in_days(arg_to_datetime(args.get('entry_age_out'))) + entry_age_out = datetime_to_age_out_in_days(arg_to_datetime(args.get('entry_age_out'))) # type: ignore[arg-type] count = args.get('entry_count') - first_seen = convert_date_to_timestamp(arg_to_datetime(args.get('entry_first_seen'))) - last_seen = convert_date_to_timestamp(arg_to_datetime(args.get('entry_last_seen'))) + first_seen = convert_date_to_timestamp(arg_to_datetime(args.get('entry_first_seen'))) # type: ignore[arg-type] + last_seen = convert_date_to_timestamp(arg_to_datetime(args.get('entry_last_seen'))) # type: ignore[arg-type] triggering_rules = args.get('triggering_rules') - validate_add_watchlist_args(first_seen, last_seen) - response = client.watchlist_add_request(display_name, description, is_case_sensitive, - data_creation_type, - value_type, age_out, inclusive, - entry_value, - entry_age_out, count, first_seen, last_seen, - triggering_rules) + validate_add_watchlist_args(first_seen, last_seen) # type: ignore[arg-type] + response = client.watchlist_add_request(display_name, description, is_case_sensitive, # type: ignore[arg-type] + data_creation_type, # type: ignore[arg-type] + value_type, age_out, inclusive, # type: ignore[arg-type] + entry_value, # type: ignore[arg-type] + entry_age_out, count, first_seen, last_seen, # type: ignore[arg-type] + triggering_rules) # type: ignore[arg-type] output, _ = format_watchlist_output(response, f"The Watchlist group: {display_name} " @@ -898,19 +907,19 @@ def watchlist_entry_add_command(client: FortiSIEMClient, args: dict[str, Any]) - count = arg_to_number(args.get('count')) triggering_rules = args.get('triggering_rules') value = args.get('value') - age_out = datetime_to_age_out_in_days(arg_to_datetime(args.get('age_out'))) - first_seen = convert_date_to_timestamp(arg_to_datetime(args.get('first_seen'))) - last_seen = convert_date_to_timestamp(arg_to_datetime(args.get('last_seen'))) + age_out = datetime_to_age_out_in_days(arg_to_datetime(args.get('age_out'))) # type: ignore[arg-type] + first_seen = convert_date_to_timestamp(arg_to_datetime(args.get('first_seen'))) # type: ignore[arg-type] + last_seen = convert_date_to_timestamp(arg_to_datetime(args.get('last_seen'))) # type: ignore[arg-type] data_creation_type = args.get('data_creation_type') description = args.get('description') - validate_add_watchlist_args(first_seen, last_seen) + validate_add_watchlist_args(first_seen, last_seen) # type: ignore[arg-type] disable_age_out = not age_out - response = client.watchlist_entry_add_request(watchlist_id, value, inclusive, count, - triggering_rules, - age_out, last_seen, first_seen, - data_creation_type, description, disable_age_out) + response = client.watchlist_entry_add_request(watchlist_id, value, inclusive, count, # type: ignore[arg-type] + triggering_rules, # type: ignore[arg-type] + age_out, last_seen, first_seen, # type: ignore[arg-type] + data_creation_type, description, disable_age_out) # type: ignore[arg-type] command_results = CommandResults( - readable_output=format_add_watchlist_entry_message(watchlist_id, value, response) + readable_output=format_add_watchlist_entry_message(watchlist_id, value, response) # type: ignore[arg-type] ) return command_results @@ -931,15 +940,15 @@ def watchlist_entry_update_command(client: FortiSIEMClient, args: dict[str, Any] count = arg_to_number(args.get('count')) triggering_rules = args.get('triggering_rules') value = args.get('value') - age_out = datetime_to_age_out_in_days(arg_to_datetime(args.get('age_out'))) - first_seen = convert_date_to_timestamp(arg_to_datetime(args.get('first_seen'))) - last_seen = convert_date_to_timestamp(arg_to_datetime(args.get('last_seen'))) - expiry_time = convert_date_to_timestamp(arg_to_datetime(args.get('expired_time'))) + age_out = datetime_to_age_out_in_days(arg_to_datetime(args.get('age_out'))) # type: ignore[arg-type] + first_seen = convert_date_to_timestamp(arg_to_datetime(args.get('first_seen'))) # type: ignore[arg-type] + last_seen = convert_date_to_timestamp(arg_to_datetime(args.get('last_seen'))) # type: ignore[arg-type] + expiry_time = convert_date_to_timestamp(arg_to_datetime(args.get('expired_time'))) # type: ignore[arg-type] data_creation_type = args.get('data_creation_type') description = args.get('description') - validate_add_watchlist_args(first_seen, last_seen) + validate_add_watchlist_args(first_seen, last_seen) # type: ignore[arg-type] - response = client.watchlist_entry_update_request(entry_id, value, inclusive=inclusive, count=count, + response = client.watchlist_entry_update_request(entry_id, value, inclusive=inclusive, count=count, # type: ignore[arg-type] description=description, triggeringRules=triggering_rules, ageOut=age_out, firstSeen=first_seen, lastSeen=last_seen, expiredTime=expiry_time, @@ -1128,10 +1137,10 @@ def watchlist_entry_get_command(client: FortiSIEMClient, args: dict[str, Any]) - ) command_results_list.append(command_results) except Exception as error: - error = CommandResults( + error = CommandResults( # type: ignore[assignment] readable_output=f'**{error}**' ) - command_results_list.append(error) + command_results_list.append(error) # type: ignore[arg-type] return command_results_list @@ -1424,7 +1433,7 @@ def format_watchlist_output(response: dict[str, Any], failure_message: str = Non message = failure_message or response_content raise ValueError(message) - outputs, total_results = format_list_commands_output(response_content, [], page or 1, limit or 1) + outputs, total_results = format_list_commands_output(response_content, [], page or 1, limit or 1) # type: ignore[arg-type] for watchlist in outputs: if watchlist.get('entries'): watchlist['entries'] = format_outputs_time_attributes_to_iso(watchlist['entries']) @@ -1443,7 +1452,7 @@ def format_message_delete_watchlist(watchlist_id: int, response: dict[str, Any]) status = response.get('status') message = response.get('response') if status == 'Success': - deleted_count = int(message.split(": ")[1]) + deleted_count = int(message.split(": ")[1]) # type: ignore[union-attr] if deleted_count >= 1: return f'The watchlist {watchlist_id} was deleted successfully.' raise ValueError(f'Failed to delete Watchlist group: {watchlist_id}.') @@ -1461,7 +1470,7 @@ def format_message_delete_entry(entry_id: int, response: dict[str, Any]) -> str: status = response.get('status') message = response.get('response') if status == 'Success': - deleted_count = int(message.split("- ")[1]) + deleted_count = int(message.split("- ")[1]) # type: ignore[union-attr] if deleted_count >= 1: return f'The entry {entry_id} were deleted successfully.' raise ValueError(f'Failed to delete entry {entry_id}.') @@ -1547,7 +1556,7 @@ def fetch_relevant_incidents(client: FortiSIEMClient, List[dict]: Relevant incidents. """ demisto.debug(f'Fetch incident from: {str(time_from)} to {str(time_to)}') - filtered_incidents = [] + filtered_incidents = [] # type: ignore[var-annotated] start_index = last_run.get('start_index') or 0 last_incident_create_time = last_run.get('create_time') or time_from last_fetch_incidents: List[int] = last_run.get('last_incidents') or [] @@ -1558,13 +1567,13 @@ def fetch_relevant_incidents(client: FortiSIEMClient, total = response.get('total') demisto.debug(f'Got: {total} total incidents.') # filtering & pagination - while len(filtered_incidents) < max_fetch and start_index < total: - for incident in incidents: + while len(filtered_incidents) < max_fetch and start_index < total: # type: ignore[operator] + for incident in incidents: # type: ignore[union-attr] if incident.get('incidentId') not in last_fetch_incidents and \ len(filtered_incidents) < max_fetch and \ incident.get('incidentFirstSeen') >= last_incident_create_time: filtered_incidents.append(incident) - if len(incidents) < page_size: # last page + if len(incidents) < page_size: # type: ignore[arg-type] break start_index += page_size @@ -1585,7 +1594,8 @@ def format_incidents(relevant_incidents: List[dict]) -> List[dict]: List[dict]: Formatted incidents. """ for incident in relevant_incidents: - incident['normalizedEventSeverity'] = INCIDENT_EVENT_CATEGORY_MAPPING.get(incident.get('eventSeverityCat'), 0.5) + incident['normalizedEventSeverity'] = INCIDENT_EVENT_CATEGORY_MAPPING.get( + incident.get('eventSeverityCat'), 0.5) # type: ignore[arg-type] format_integer_field_to_verbal(incident) # formatting integer attributes. for attribute_name in REFORMAT_INCIDENT_FIELDS: # formatting nested attributes. @@ -1602,7 +1612,7 @@ def format_incidents(relevant_incidents: List[dict]) -> List[dict]: return relevant_incidents -def format_nested_incident_attribute(attribute_value: str | None) -> tuple: +def format_nested_incident_attribute(attribute_value: str | None) -> tuple: # type: ignore[return] """ Format nested attributes to be readable. For example: for the attribute_value "srcIpAddr:192.168.1.1,", @@ -1664,7 +1674,7 @@ def get_mapping_for_verbal_incident_attrib(field_name: str) -> tuple: 'incidentReso': (INCIDENT_RESOLUTION_INT_VERBAL_MAPPING, 'None'), 'phIncidentCategory': (INCIDENT_CATEGORY_INT_VERBAL_MAPPING, 'AVAILABILITY') } - return routing.get(field_name) + return routing.get(field_name) # type: ignore[return-value] def build_readable_attribute_key(key: str, attribute_name: str): @@ -1770,18 +1780,18 @@ def get_list_events_readable_output(outputs: List[dict]) -> List[dict]: "eventReceiveTime": event.get('receiveTime'), "eventID": event.get('id'), "eventType": event.get('eventType'), - "message": attributes.get('rawMessage') or event.get('msg'), - "sourceIP": attributes.get("Source IP") or attributes.get('srcIpAddr'), - "destinationIP": attributes.get("Destination IP") or attributes.get('destIpAddr'), - "hostName": attributes.get("Host Name") or attributes.get('hostName'), - "hostIp": attributes.get("Host IP") or attributes.get('hostIpAddr'), - "user": attributes.get("User") or attributes.get('user'), - "fileName": attributes.get("File Name") or attributes.get('fileName'), - "command": attributes.get("Command") or attributes.get('command'), - "filePath": attributes.get("File Path") or attributes.get('filePath'), - "SHA256Hash": attributes.get("SHA256 Hash") or attributes.get('hashSHA256'), - "MD5Hash": attributes.get("MD5 Hash") or attributes.get('hashMD5'), - "rawEventLog": attributes.get("Raw Event Log") or attributes.get('rawEventMsg'), + "message": attributes.get('rawMessage') or event.get('msg'), # type: ignore[union-attr] + "sourceIP": attributes.get("Source IP") or attributes.get('srcIpAddr'), # type: ignore[union-attr] + "destinationIP": attributes.get("Destination IP") or attributes.get('destIpAddr'), # type: ignore[union-attr] + "hostName": attributes.get("Host Name") or attributes.get('hostName'), # type: ignore[union-attr] + "hostIp": attributes.get("Host IP") or attributes.get('hostIpAddr'), # type: ignore[union-attr] + "user": attributes.get("User") or attributes.get('user'), # type: ignore[union-attr] + "fileName": attributes.get("File Name") or attributes.get('fileName'), # type: ignore[union-attr] + "command": attributes.get("Command") or attributes.get('command'), # type: ignore[union-attr] + "filePath": attributes.get("File Path") or attributes.get('filePath'), # type: ignore[union-attr] + "SHA256Hash": attributes.get("SHA256 Hash") or attributes.get('hashSHA256'), # type: ignore[union-attr] + "MD5Hash": attributes.get("MD5 Hash") or attributes.get('hashMD5'), # type: ignore[union-attr] + "rawEventLog": attributes.get("Raw Event Log") or attributes.get('rawEventMsg'), # type: ignore[union-attr] }) return readable_outputs @@ -1799,7 +1809,7 @@ def datetime_to_age_out_in_days(age_out_date: datetime) -> str: delta = now - age_out_date days = delta.days # interested in interval only. return f'{days}d' - return None + return None # type: ignore[return-value] def update_last_run_obj(last_run: dict[str, Any], formatted_incidents: List[dict]): @@ -1834,13 +1844,13 @@ def main() -> None: fetch_with_events = params.get('fetch_mode') == 'Fetch With Events' max_events_fetch = arg_to_number(params.get('max_events_fetch', DEFAULT_EVENTS_FETCH)) status_filter_list = argToList(params.get('status')) - headers = {} + headers = {} # type: ignore[var-annotated] command = demisto.command() demisto.debug(f'Command being called is {command}') try: - requests.packages.urllib3.disable_warnings() + requests.packages.urllib3.disable_warnings() # type: ignore[attr-defined] client: FortiSIEMClient = FortiSIEMClient(urljoin(url, ''), verify_certificate, proxy, headers=headers, auth=(f'super/{username}', password)) @@ -1879,10 +1889,10 @@ def main() -> None: status_filter_list) elif command == 'fetch-incidents': - incidents, last_run = fetch_incidents(client, max_fetch, - first_fetch, + incidents, last_run = fetch_incidents(client, max_fetch, # type: ignore[arg-type] + first_fetch, # type: ignore[arg-type] status_filter_list, fetch_with_events, - max_events_fetch, demisto.getLastRun()) + max_events_fetch, demisto.getLastRun()) # type: ignore[arg-type] demisto.setLastRun(last_run) demisto.incidents(incidents) diff --git a/Packs/FortiSIEM/Integrations/FortiSIEMV2/FortiSIEMV2.yml b/Packs/FortiSIEM/Integrations/FortiSIEMV2/FortiSIEMV2.yml index ea88574e6616..6683f4c286fc 100644 --- a/Packs/FortiSIEM/Integrations/FortiSIEMV2/FortiSIEMV2.yml +++ b/Packs/FortiSIEM/Integrations/FortiSIEMV2/FortiSIEMV2.yml @@ -701,7 +701,7 @@ script: - contextPath: FortiSIEM.WatchlistEntry.ageOut description: Expiration date of the entry. type: String - dockerimage: demisto/python3:3.10.14.91134 + dockerimage: demisto/python3:3.11.9.105369 isfetch: true runonce: false script: '-' diff --git a/Packs/FortiSIEM/ReleaseNotes/2_0_36.md b/Packs/FortiSIEM/ReleaseNotes/2_0_36.md new file mode 100644 index 000000000000..877d28c03ed2 --- /dev/null +++ b/Packs/FortiSIEM/ReleaseNotes/2_0_36.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### FortiSIEM v2 + +- Maintenance and stability enhancements. diff --git a/Packs/FortiSIEM/pack_metadata.json b/Packs/FortiSIEM/pack_metadata.json index fb0d7a71c02c..dd0ae5393e04 100644 --- a/Packs/FortiSIEM/pack_metadata.json +++ b/Packs/FortiSIEM/pack_metadata.json @@ -2,7 +2,7 @@ "name": "FortiSIEM", "description": "Search and update events of FortiSIEM and manage resource lists.", "support": "xsoar", - "currentVersion": "2.0.35", + "currentVersion": "2.0.36", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/GCP-IAM/Integrations/GCPIAM/GCPIAM.py b/Packs/GCP-IAM/Integrations/GCPIAM/GCPIAM.py index bb96aa0fae66..4aa612cc8ec5 100644 --- a/Packs/GCP-IAM/Integrations/GCPIAM/GCPIAM.py +++ b/Packs/GCP-IAM/Integrations/GCPIAM/GCPIAM.py @@ -1,6 +1,6 @@ import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 -# type: ignore + # pylint: disable=no-member import copy from collections.abc import Callable diff --git a/Packs/GCP-IAM/Integrations/GCPIAM/GCPIAM.yml b/Packs/GCP-IAM/Integrations/GCPIAM/GCPIAM.yml index 07b805a52319..ddd807243bf9 100644 --- a/Packs/GCP-IAM/Integrations/GCPIAM/GCPIAM.yml +++ b/Packs/GCP-IAM/Integrations/GCPIAM/GCPIAM.yml @@ -1250,7 +1250,7 @@ script: description: Create a short-lived access token for a service account. The generated token will be exposed to the context menu and War Room, and can potentially be logged. execution: true name: gcp-iam-service-account-generate-access-token - dockerimage: demisto/google-api-py3:1.0.0.78763 + dockerimage: demisto/google-api-py3:1.0.0.105788 runonce: false script: '-' subtype: python3 diff --git a/Packs/GCP-IAM/ReleaseNotes/1_0_26.md b/Packs/GCP-IAM/ReleaseNotes/1_0_26.md new file mode 100644 index 000000000000..8e9cc08ca840 --- /dev/null +++ b/Packs/GCP-IAM/ReleaseNotes/1_0_26.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### GCP-IAM + +- Maintenance and stability enhancements. diff --git a/Packs/GCP-IAM/pack_metadata.json b/Packs/GCP-IAM/pack_metadata.json index 2ff989a7b7b6..70b342e90e02 100644 --- a/Packs/GCP-IAM/pack_metadata.json +++ b/Packs/GCP-IAM/pack_metadata.json @@ -2,7 +2,7 @@ "name": "GCP IAM", "description": "Manage identity and access control for Google Cloud Platform resources.", "support": "xsoar", - "currentVersion": "1.0.25", + "currentVersion": "1.0.26", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/IronDefense/Integrations/IronDefense/IronDefense_test.py b/Packs/IronDefense/Integrations/IronDefense/IronDefense_test.py index 8ec90ffd8906..3230de30d30d 100644 --- a/Packs/IronDefense/Integrations/IronDefense/IronDefense_test.py +++ b/Packs/IronDefense/Integrations/IronDefense/IronDefense_test.py @@ -1,4 +1,3 @@ -# type: ignore import json import unittest import demistomock as demisto @@ -7,7 +6,6 @@ from unittest import TestCase, mock from unittest.mock import Mock, call import requests -from typing import Dict from http.client import HTTPException requests.packages.urllib3.disable_warnings() @@ -53,17 +51,16 @@ def test_get_jwt(self): test_context = { 'JWT': test_jwt } - self.assertEqual(test_jwt, self.class_under_test._get_jwt(test_context), 'Unexpected result') - self.assertEqual(None, self.class_under_test._get_jwt(None), 'None context should return None') - self.assertEqual(None, self.class_under_test._get_jwt({'bogus': 'context'}), - 'Missing jwt in context should return None') + assert test_jwt == self.class_under_test._get_jwt(test_context), 'Unexpected result' + assert None is self.class_under_test._get_jwt(None), 'None context should return None' + assert None is self.class_under_test._get_jwt({'bogus': 'context'}), 'Missing jwt in context should return None' def test_configure_session_auth(self): self.mock_session.headers = {} # test no jwt token self.class_under_test._configure_session_auth({}) - self.assertIsNone(self.mock_session.headers.get('authentication', None)) + assert self.mock_session.headers.get('authentication', None) is None # test loading jwt token test_jwt = 'jwt token' @@ -71,19 +68,19 @@ def test_configure_session_auth(self): 'JWT': test_jwt } self.class_under_test._configure_session_auth(test_context) - self.assertEqual('Bearer ' + test_jwt, self.mock_session.headers.get('Authorization')) + assert 'Bearer ' + test_jwt == self.mock_session.headers.get('Authorization') @mock.patch('requests.Response', autospec=True) def test_http_request(self, MockResponse): MockResponse.return_value.headers = {} method = 'GET' uri = '/something' - headers: Dict[str, str] = {} + headers: dict[str, str] = {} data = '{}' - params: Dict[str, str] = {} + params: dict[str, str] = {} files = None mock_jwt_value = 'jwt token' - expected_uri = 'https://{}:{}{}{}'.format(self.host, self.port, self.url_prefix, uri) + expected_uri = f'https://{self.host}:{self.port}{self.url_prefix}{uri}' '''Test successful response''' mock_response = MockResponse() @@ -94,7 +91,7 @@ def test_http_request(self, MockResponse): self.mock_session.request.assert_called_with(method, expected_uri, headers=headers, data=data, params=params, files=files, timeout=self.class_under_test.request_timeout, auth=None, verify=False) - self.assertEqual(test_response, mock_response) + assert test_response == mock_response '''Test incorrect creds''' mock_response = MockResponse() @@ -107,7 +104,7 @@ def test_http_request(self, MockResponse): auth=( self.credentials['identifier'], self.credentials['password']), verify=False) - self.assertEqual(test_response, mock_response) + assert test_response == mock_response '''Test expired jwt''' self.mock_session.request.reset_mock() @@ -142,10 +139,9 @@ def side_effect(self, *args, **kwargs): auth=(self.credentials['identifier'], self.credentials['password']), verify=False) ]) # check to see if the jwt was stored - self.assertDictEqual({'JWT': mock_jwt_value}, demisto.getIntegrationContext(), 'JWT value should be the same ' - 'as the stored value.') - self.assertEqual(200, test_response.status_code, 'Unexpected status code') - self.assertEqual(2, self.mock_session.request.call_count, '_http_request should have made 2 calls') + assert {'JWT': mock_jwt_value} == demisto.getIntegrationContext() + assert test_response.status_code == 200, 'Unexpected status code' + assert self.mock_session.request.call_count == 2, '_http_request should have made 2 calls' '''Test 5xx response''' self.mock_session.request.reset_mock() @@ -160,7 +156,7 @@ def side_effect(self, *args, **kwargs): self.mock_session.request.assert_called_with(method, expected_uri, headers=headers, data=data, params=params, files=files, timeout=self.class_under_test.request_timeout, auth=None, verify=False) - self.assertEqual(test_response, mock_response) + assert test_response == mock_response @mock.patch('requests.Response', autospec=True) def test_test_module(self, MockResponse): @@ -178,7 +174,7 @@ def test_test_module(self, MockResponse): auth=(self.credentials['identifier'], self.credentials[ 'password']), verify=False) - self.assertEqual('ok', result, 'Result should be "ok"') + assert result == 'ok', 'Result should be "ok"' # test failed response error_json = { @@ -197,7 +193,7 @@ def test_test_module(self, MockResponse): auth=(self.credentials['identifier'], self.credentials[ 'password']), verify=False) - self.assertNotEqual('ok', result, 'Result should have an error message') + assert result != 'ok', 'Result should have an error message' @mock.patch('requests.Response', autospec=True) def test_update_analyst_ratings(self, MockResponse): @@ -765,7 +761,7 @@ def test_fetch_alert_incidents_filtering(self, MockResponse): result = [init_result[0]["rawJSON"], init_result[1]["rawJSON"], init_result[2]["rawJSON"], init_result[3]["rawJSON"]] - self.assertEqual(expected_resp_data, result) + assert expected_resp_data == result # Test default filtering on Alert Notifications @mock.patch('requests.Response', autospec=True) @@ -814,7 +810,7 @@ def test_fetch_alert_incidents_action_default(self, MockResponse): init_result[3]["rawJSON"], init_result[4]["rawJSON"], init_result[5]["rawJSON"], init_result[6]["rawJSON"]] - self.assertEqual(expected_resp_data, result) + assert expected_resp_data == result # Mock Json Data for fetch_event_incidents() def mock_fetch_event_incidents_data(self): @@ -985,7 +981,7 @@ def test_fetch_event_incidents_filtering(self, MockResponse): result = [init_result[0]["rawJSON"], init_result[1]["rawJSON"], init_result[2]["rawJSON"], init_result[3]["rawJSON"]] - self.assertEqual(expected_resp_data, result) + assert expected_resp_data == result # Test default filtering on Event Notifications @mock.patch('requests.Response', autospec=True) @@ -1034,7 +1030,7 @@ def test_fetch_event_incidents_action_default(self, MockResponse): init_result[3]["rawJSON"], init_result[4]["rawJSON"], init_result[5]["rawJSON"], init_result[6]["rawJSON"]] - self.assertEqual(expected_resp_data, result) + assert expected_resp_data == result @mock.patch('requests.Response', autospec=True) def test_get_alert_irondome_information(self, MockResponse): @@ -1084,12 +1080,12 @@ def test_get_error_msg_from_response(self, MockResponse): mock_response.json.return_value = error_json error_msg = self.class_under_test._get_error_msg_from_response(mock_response) - self.assertEqual(expected_error_msg, error_msg, 'Error message was not properly extracted') + assert expected_error_msg == error_msg, 'Error message was not properly extracted' mock_response.json.return_value = {} mock_response.text = expected_error_msg error_msg = self.class_under_test._get_error_msg_from_response(mock_response) - self.assertEqual(expected_error_msg, error_msg, 'Error message was not properly extracted') + assert expected_error_msg == error_msg, 'Error message was not properly extracted' @mock.patch('IronDefense.demisto') def test_test_module_command(self, mock_demisto): @@ -1125,6 +1121,7 @@ def getArg_side_effect(arg): return expected_severity if arg == 'expectation': return expected_expectation + return None mock_demisto.getArg.side_effect = getArg_side_effect @@ -1153,6 +1150,7 @@ def getArg_side_effect(arg): return expected_comment if arg == 'share_comment_with_irondome': return 'true' + return None mock_demisto.getArg.side_effect = getArg_side_effect @@ -1182,6 +1180,7 @@ def getArg_side_effect(arg): return 'true' if arg == 'status': return expected_status + return None mock_demisto.getArg.side_effect = getArg_side_effect @@ -1219,6 +1218,7 @@ def getArg_side_effect(arg): return expected_activity_start_time if arg == 'activity_end_time': return expected_activity_end_time + return None mock_demisto.getArg.side_effect = getArg_side_effect @@ -1356,6 +1356,7 @@ def test_get_event_command(self, mock_demisto): def getArg_side_effect(arg): if arg == 'event_id': return expected_event_id + return None def event_context_table_contains_multi_columns_side_effect(table): return table.get('name') == 'enterprise_ips' @@ -1771,7 +1772,7 @@ def test_event_context_table_to_dict_list(self): actual_dict_table_list = self.class_under_test.event_context_table_to_dict_list(event_context_table) # Assert results - self.assertEqual(expected_dict_table_list, actual_dict_table_list) + assert expected_dict_table_list == actual_dict_table_list def test_event_context_to_dict(self): # Expectations @@ -1789,7 +1790,7 @@ def test_event_context_to_dict(self): actual_dict_table = self.class_under_test.event_context_table_to_dict(event_context_table) # Assert results - self.assertEqual(expected_dict_table, actual_dict_table) + assert expected_dict_table == actual_dict_table def test_event_context_table_contains_multi_columns(self): # Execute test @@ -1797,13 +1798,13 @@ def test_event_context_table_contains_multi_columns(self): json_data = event_context_table_file.read() event_context_table = json.loads(json_data) result = self.class_under_test.event_context_table_contains_multi_columns(event_context_table) - self.assertTrue(result) + assert result with open('./test-data/event-context-key-value-table.json') as event_context_table_file: json_data = event_context_table_file.read() event_context_table = json.loads(json_data) result = self.class_under_test.event_context_table_contains_multi_columns(event_context_table) - self.assertFalse(result) + assert not result def test_create_markdown_link(self): # Expectations @@ -1815,7 +1816,7 @@ def test_create_markdown_link(self): actual_markdown_link = self.class_under_test.create_markdown_link(link_text, url) # Assert - self.assertEqual(expected_markdown_link, actual_markdown_link) + assert expected_markdown_link == actual_markdown_link def test_create_dome_markdown_link(self): # Expectations @@ -1828,7 +1829,7 @@ def test_create_dome_markdown_link(self): actual_markdown_link = self.class_under_test.create_dome_markdown_link(link_text, alert_id) # Assert - self.assertEqual(expected_markdown_link, actual_markdown_link) + assert expected_markdown_link == actual_markdown_link if __name__ == '__main__': diff --git a/Packs/MISP/Integrations/MISPV3/MISPV3.py b/Packs/MISP/Integrations/MISPV3/MISPV3.py index 54a5dfc3f738..2f1f3fdeaa28 100644 --- a/Packs/MISP/Integrations/MISPV3/MISPV3.py +++ b/Packs/MISP/Integrations/MISPV3/MISPV3.py @@ -1,7 +1,6 @@ import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 -# type: ignore import urllib3 import copy @@ -326,9 +325,9 @@ def build_custom_object(template_name: str, args: list[dict]): custom_obj = PYMISP.get_raw_object_template(template_name) - if not os.path.exists('/tmp/{}'.format(template_name)): - os.mkdir('/tmp/{}'.format(template_name)) - open('/tmp/{}/definition.json'.format(template_name), 'w').write(json.dumps(custom_obj)) + if not os.path.exists(f'/tmp/{template_name}'): + os.mkdir(f'/tmp/{template_name}') + open(f'/tmp/{template_name}/definition.json', 'w').write(json.dumps(custom_obj)) misp_object = MISPObject(name=template_name, misp_objects_path_custom='/tmp') @@ -1549,7 +1548,7 @@ def add_custom_object_command(demisto_args: dict): if obj is not False: return add_object(event_id, obj) else: - raise DemistoException('Unable to find custom template {}'. format(template)) + raise DemistoException(f'Unable to find custom template {template}') except ValueError as e: raise DemistoException( diff --git a/Packs/MISP/Integrations/MISPV3/MISPV3_test.py b/Packs/MISP/Integrations/MISPV3/MISPV3_test.py index 46e7fe9a90d0..a179dc2467e4 100644 --- a/Packs/MISP/Integrations/MISPV3/MISPV3_test.py +++ b/Packs/MISP/Integrations/MISPV3/MISPV3_test.py @@ -750,7 +750,7 @@ def test_add_custom_object(mocker): result = add_custom_object_command(demisto_args) expected_output = { - 'readable_output': 'Object has been added to MISP event ID {}'.format(event_id), + 'readable_output': f'Object has been added to MISP event ID {event_id}', 'outputs': response_add_obj } assert result.readable_output == expected_output['readable_output'] diff --git a/Packs/MISP/Integrations/MISP_V2/MISP_V2.py b/Packs/MISP/Integrations/MISP_V2/MISP_V2.py index 366652e6d975..428e42e9fc7d 100644 --- a/Packs/MISP/Integrations/MISP_V2/MISP_V2.py +++ b/Packs/MISP/Integrations/MISP_V2/MISP_V2.py @@ -1,5 +1,3 @@ -# type: ignore - import logging import warnings from typing import Union, List, Any, Tuple, Dict diff --git a/Packs/MISP/ReleaseNotes/2_1_44.md b/Packs/MISP/ReleaseNotes/2_1_44.md new file mode 100644 index 000000000000..e62866b647d6 --- /dev/null +++ b/Packs/MISP/ReleaseNotes/2_1_44.md @@ -0,0 +1,9 @@ + +#### Integrations + +##### MISP v2 (Deprecated) + +- Maintenance and stability enhancements. +##### MISP v3 + +- Maintenance and stability enhancements. diff --git a/Packs/MISP/pack_metadata.json b/Packs/MISP/pack_metadata.json index 3cce685e4101..df489973c90f 100644 --- a/Packs/MISP/pack_metadata.json +++ b/Packs/MISP/pack_metadata.json @@ -2,7 +2,7 @@ "name": "MISP", "description": "Malware information and threat sharing platform.", "support": "xsoar", - "currentVersion": "2.1.43", + "currentVersion": "2.1.44", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Netskope/Integrations/NetskopeAPIv1/NetskopeAPIv1.py b/Packs/Netskope/Integrations/NetskopeAPIv1/NetskopeAPIv1.py index 5f17cca88b4e..a0cab1db02ad 100644 --- a/Packs/Netskope/Integrations/NetskopeAPIv1/NetskopeAPIv1.py +++ b/Packs/Netskope/Integrations/NetskopeAPIv1/NetskopeAPIv1.py @@ -1,8 +1,8 @@ import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 -# type: ignore + from copy import deepcopy -from typing import Any, Dict, List, Optional, Tuple +from typing import Any import urllib3 @@ -47,16 +47,16 @@ def __init__(self, base_url: str, token: str, use_ssl: bool, use_proxy: bool): self._session.params['token'] = token # type: ignore def list_events_request(self, - query: Optional[str] = None, - event_type: Optional[str] = None, - timeperiod: Optional[int] = None, - start_time: Optional[int] = None, - end_time: Optional[int] = None, - insertion_start_time: Optional[int] = None, - insertion_end_time: Optional[int] = None, - limit: Optional[int] = None, - skip: Optional[int] = None, - unsorted: Optional[bool] = None) -> Dict[str, Any]: + query: str | None = None, + event_type: str | None = None, + timeperiod: int | None = None, + start_time: int | None = None, + end_time: int | None = None, + insertion_start_time: int | None = None, + insertion_end_time: int | None = None, + limit: int | None = None, + skip: int | None = None, + unsorted: bool | None = None) -> dict[str, Any]: """ Get events extracted from SaaS traffic and or logs. @@ -94,17 +94,17 @@ def list_events_request(self, return self._http_request(method='POST', url_suffix='events', json_data=body) def list_alerts_request(self, - query: Optional[str] = None, - alert_type: Optional[str] = None, - acked: Optional[bool] = None, - timeperiod: Optional[int] = None, - start_time: Optional[int] = None, - end_time: Optional[int] = None, - insertion_start_time: Optional[int] = None, - insertion_end_time: Optional[int] = None, - limit: Optional[int] = None, - skip: Optional[int] = None, - unsorted: Optional[bool] = None) -> Dict[str, Any]: + query: str | None = None, + alert_type: str | None = None, + acked: bool | None = None, + timeperiod: int | None = None, + start_time: int | None = None, + end_time: int | None = None, + insertion_start_time: int | None = None, + insertion_end_time: int | None = None, + limit: int | None = None, + skip: int | None = None, + unsorted: bool | None = None) -> dict[str, Any]: """ Get alerts generated by Netskope, including policy, DLP, and watch list alerts. @@ -144,10 +144,10 @@ def list_alerts_request(self, return self._http_request(method='POST', url_suffix='alerts', json_data=body) def list_quarantined_files_request(self, - start_time: Optional[int] = None, - end_time: Optional[int] = None, - limit: Optional[int] = None, - skip: Optional[int] = None) -> Dict[str, Any]: + start_time: int | None = None, + end_time: int | None = None, + limit: int | None = None, + skip: int | None = None) -> dict[str, Any]: """ List all quarantined files. @@ -214,7 +214,7 @@ def update_quarantined_file_request(self, quarantine_profile_id: str, file_id: s self._http_request(method='POST', url_suffix='quarantine', json_data=body, resp_type='text') - def update_url_list_request(self, name: str, urls: List[str]) -> None: + def update_url_list_request(self, name: str, urls: list[str]) -> None: """ Update the URL List with the values provided. @@ -226,7 +226,7 @@ def update_url_list_request(self, name: str, urls: List[str]) -> None: body = {'name': name, 'list': ','.join(urls)} self._http_request(method='POST', url_suffix='updateUrlList', json_data=body) - def update_file_hash_list_request(self, name: str, hashes: List[str]) -> None: + def update_file_hash_list_request(self, name: str, hashes: list[str]) -> None: """ Update file hash list with the values provided. @@ -239,9 +239,9 @@ def update_file_hash_list_request(self, name: str, hashes: List[str]) -> None: return self._http_request(method='POST', url_suffix='updateFileHashList', json_data=body) def list_clients_request(self, - query: Optional[str] = None, - limit: Optional[int] = None, - skip: Optional[int] = None) -> Dict[str, Any]: + query: str | None = None, + limit: int | None = None, + skip: int | None = None) -> dict[str, Any]: """ Get information about the Netskope clients. @@ -266,7 +266,7 @@ def _http_request(self, *args, **kwargs): return response -def arg_to_boolean(arg: Optional[str]) -> Optional[bool]: +def arg_to_boolean(arg: str | None) -> bool | None: """ Converts an XSOAR argument to a Python boolean or None. @@ -284,7 +284,7 @@ def arg_to_boolean(arg: Optional[str]) -> Optional[bool]: return argToBoolean(arg) -def arg_to_seconds_timestamp(arg: Optional[str]): +def arg_to_seconds_timestamp(arg: str | None): """ Converts an XSOAR date string argument to a timestamp in seconds. @@ -316,11 +316,11 @@ def date_to_seconds_timestamp(date_str_or_dt: Union[str, datetime]) -> int: return date_to_timestamp(date_str_or_dt) // 1000 -def validate_time_arguments(start_time: Optional[int] = None, - end_time: Optional[int] = None, - insertion_start_time: Optional[int] = None, - insertion_end_time: Optional[int] = None, - timeperiod: Optional[int] = None) -> None: +def validate_time_arguments(start_time: int | None = None, + end_time: int | None = None, + insertion_start_time: int | None = None, + insertion_end_time: int | None = None, + timeperiod: int | None = None) -> None: """ Validates time arguments from the user. The user must provide one of the following: @@ -353,7 +353,7 @@ def validate_time_arguments(start_time: Optional[int] = None, def validate_fetch_params(max_fetch: int, max_events_fetch: int, fetch_events: bool, - first_fetch: str, event_types: List[str]) -> None: + first_fetch: str, event_types: list[str]) -> None: """ Validates the parameters for fetch incident command. @@ -382,7 +382,7 @@ def get_pagination_readable_message(header: str, page: int, limit: int) -> str: return f'{header}\n Current page size: {limit}\n Showing page {page} out of others that may exist.' -def get_pagination_arguments(args: Dict[str, Any]) -> Tuple[int, int, int]: +def get_pagination_arguments(args: dict[str, Any]) -> tuple[int, int, int]: """ Gets and validates pagination arguments for client (skip and limit). @@ -404,7 +404,7 @@ def get_pagination_arguments(args: Dict[str, Any]) -> Tuple[int, int, int]: return page, (page - 1) * limit, limit -def list_events_command(client: Client, args: Dict[str, str]) -> CommandResults: +def list_events_command(client: Client, args: dict[str, str]) -> CommandResults: """ Get events extracted from SaaS traffic and or logs. @@ -461,7 +461,7 @@ def list_events_command(client: Client, args: Dict[str, str]) -> CommandResults: raw_response=response) -def list_alerts_command(client: Client, args: Dict[str, str]) -> CommandResults: +def list_alerts_command(client: Client, args: dict[str, str]) -> CommandResults: """ Get alerts generated by Netskope, including policy, DLP, and watch list alerts. @@ -520,7 +520,7 @@ def list_alerts_command(client: Client, args: Dict[str, str]) -> CommandResults: raw_response=response) -def list_quarantined_files_command(client: Client, args: Dict[str, str]) -> CommandResults: +def list_quarantined_files_command(client: Client, args: dict[str, str]) -> CommandResults: """ List all quarantined files. @@ -567,7 +567,7 @@ def list_quarantined_files_command(client: Client, args: Dict[str, str]) -> Comm raw_response=response) -def get_quarantined_file_command(client: Client, args: Dict[str, str]) -> CommandResults: +def get_quarantined_file_command(client: Client, args: dict[str, str]) -> CommandResults: """ Download a quarantined file. @@ -588,7 +588,7 @@ def get_quarantined_file_command(client: Client, args: Dict[str, str]) -> Comman return fileResult(filename=file_name, data=response, file_type=EntryType.FILE) -def update_quarantined_file_command(client: Client, args: Dict[str, str]) -> CommandResults: +def update_quarantined_file_command(client: Client, args: dict[str, str]) -> CommandResults: """ Take an action on a quarantined file. @@ -612,7 +612,7 @@ def update_quarantined_file_command(client: Client, args: Dict[str, str]) -> Com return CommandResults(readable_output=readable_output) -def update_url_list_command(client: Client, args: Dict[str, str]) -> CommandResults: +def update_url_list_command(client: Client, args: dict[str, str]) -> CommandResults: """ Update the URL List with the values provided. @@ -638,7 +638,7 @@ def update_url_list_command(client: Client, args: Dict[str, str]) -> CommandResu readable_output=readable_output) -def update_file_hash_list_command(client: Client, args: Dict[str, str]) -> CommandResults: +def update_file_hash_list_command(client: Client, args: dict[str, str]) -> CommandResults: """ Update file hash list with the values provided. @@ -664,7 +664,7 @@ def update_file_hash_list_command(client: Client, args: Dict[str, str]) -> Comma readable_output=readable_output) -def list_clients_command(client: Client, args: Dict[str, str]) -> CommandResults: +def list_clients_command(client: Client, args: dict[str, str]) -> CommandResults: """ Get information about the Netskope clients. @@ -698,7 +698,7 @@ def list_clients_command(client: Client, args: Dict[str, str]) -> CommandResults raw_response=response) -def list_host_associated_user_command(client: Client, args: Dict[str, str]) -> CommandResults: +def list_host_associated_user_command(client: Client, args: dict[str, str]) -> CommandResults: """ List all users of certain host by its hostname. @@ -737,7 +737,7 @@ def list_host_associated_user_command(client: Client, args: Dict[str, str]) -> C raw_response=response) -def list_user_associated_host_command(client: Client, args: Dict[str, str]) -> CommandResults: +def list_user_associated_host_command(client: Client, args: dict[str, str]) -> CommandResults: """ List all hosts related to a certain username. @@ -777,7 +777,7 @@ def list_user_associated_host_command(client: Client, args: Dict[str, str]) -> C def test_module(client: Client, max_fetch: int, first_fetch: str, fetch_events: bool, - max_events_fetch: int, event_types: List[str]) -> str: + max_events_fetch: int, event_types: list[str]) -> str: """ Validates all integration parameters, and tests connection to Netskope instance. """ @@ -791,8 +791,8 @@ def test_module(client: Client, max_fetch: int, first_fetch: str, fetch_events: def fetch_multiple_type_events(client: Client, max_fetch: int, start_time: int, - event_types: List[str], - query: Optional[str]) -> List[Dict[str, Any]]: + event_types: list[str], + query: str | None) -> list[dict[str, Any]]: """ Fetches events from multiple types. The function makes an API call for each type, since the API requires @@ -830,8 +830,8 @@ def fetch_multiple_type_events(client: Client, max_fetch: int, start_time: int, def fetch_incidents(client: Client, max_fetch: int, first_fetch: str, fetch_events: bool, - max_events_fetch: int, event_types: List[str], alerts_query: Optional[str], - events_query: Optional[str]) -> None: + max_events_fetch: int, event_types: list[str], alerts_query: str | None, + events_query: str | None) -> None: """ Fetches alerts and events as incidents. diff --git a/Packs/Netskope/Integrations/NetskopeAPIv1/NetskopeAPIv1.yml b/Packs/Netskope/Integrations/NetskopeAPIv1/NetskopeAPIv1.yml index 3ffad54de17e..750ea017aae4 100644 --- a/Packs/Netskope/Integrations/NetskopeAPIv1/NetskopeAPIv1.yml +++ b/Packs/Netskope/Integrations/NetskopeAPIv1/NetskopeAPIv1.yml @@ -494,7 +494,7 @@ script: - contextPath: Netskope.Host.agent_status description: The status of the agent on the device. type: String - dockerimage: demisto/python3:3.10.13.89009 + dockerimage: demisto/python3:3.11.9.105369 isfetch: true runonce: false script: "-" diff --git a/Packs/Netskope/ReleaseNotes/3_3_11.md b/Packs/Netskope/ReleaseNotes/3_3_11.md new file mode 100644 index 000000000000..18f6da06db8f --- /dev/null +++ b/Packs/Netskope/ReleaseNotes/3_3_11.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Netskope (API v1) + +- Maintenance and stability enhancements. diff --git a/Packs/Netskope/pack_metadata.json b/Packs/Netskope/pack_metadata.json index 37c87fa447cc..652806da5b04 100644 --- a/Packs/Netskope/pack_metadata.json +++ b/Packs/Netskope/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Netskope", "description": "Cloud access security broker that enables to find, understand, and secure cloud apps.", "support": "xsoar", - "currentVersion": "3.3.10", + "currentVersion": "3.3.11", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Tenable_io/Integrations/Tenable_io/Tenable_io_test.py b/Packs/Tenable_io/Integrations/Tenable_io/Tenable_io_test.py index d9eea45fb6df..8328b8d9ea82 100644 --- a/Packs/Tenable_io/Integrations/Tenable_io/Tenable_io_test.py +++ b/Packs/Tenable_io/Integrations/Tenable_io/Tenable_io_test.py @@ -4,7 +4,6 @@ from CommonServerPython import * import json -# mypy: disable-error-code="operator" MOCK_PARAMS = { 'access-key': 'fake_access_key', From 99a620947f917f58ca929bf1ca8de5ad5f469c8b Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Sun, 11 Aug 2024 12:41:50 +0300 Subject: [PATCH 06/14] [Marketplace Contribution] AWS - IAM - Content Pack Update (#35266) (#35822) * "contribution update to pack 'AWS - IAM'" * Update 1_1_64.md * Update AWS-IAM.py Pagination Pagination added to the list_mfa_devices command. * Update AWS-IAM.yml - AWS Default Region set to true - AWS STS Regional Endpoints parameter added - aws-iam-list-attached-role-policies command added - aws-iam-list-mfa-devices command contextPath updated - aws-iam-list-mfa-devices command arguments userName set to required: true, serialNumber set to required: true - aws-iam-deactivate-mfa-devices command arguments serialNumber set to required: true * Update AWSApiModule.py Previous state of the AWSApiModule.py file restored * Update README.md Updating the Configure a new integration instance of the Readme.md file * Update README.md Including Required for the Readme files * Update README.md Updating the Readme contents * Update README.md - Adding roleArn, roleSessionName and roleSessionDuration as input arguments for the mfa commands. - Adding Command Examples for the 3 mfa commands * Update AWS-IAM.yml Update yml to include the roleArn, rolseSessionDuration, RoleSessionName * Update AWS-IAM.yml Update yml to include marker * Update AWS-IAM.yml Marker added in Context Output * Update README.md Updating Readme to match the yml with the marker additions * Update AWS-IAM.py Update spacing * fix yml * restore AWSApiModule.py * order the readme file * add UTs * add UT * pre-commit * fix yml * fix yml again --------- Co-authored-by: xsoar-bot <67315154+xsoar-bot@users.noreply.github.com> Co-authored-by: Winnie875 <62045155+Winnie875@users.noreply.github.com> Co-authored-by: Danny Fried Co-authored-by: israelpoli <72099621+israelpoli@users.noreply.github.com> Co-authored-by: ipolishuk --- Packs/AWS-IAM/Integrations/AWS-IAM/AWS-IAM.py | 58 ++++++++++ .../AWS-IAM/Integrations/AWS-IAM/AWS-IAM.yml | 66 ++++++++++- .../AWS-IAM/AWS-IAM_description.md | 0 .../Integrations/AWS-IAM/AWS-IAM_test.py | 107 +++++++++++++++++- Packs/AWS-IAM/Integrations/AWS-IAM/README.md | 72 ++++++++++++ Packs/AWS-IAM/ReleaseNotes/1_1_64.md | 8 ++ Packs/AWS-IAM/pack_metadata.json | 2 +- 7 files changed, 310 insertions(+), 3 deletions(-) create mode 100644 Packs/AWS-IAM/Integrations/AWS-IAM/AWS-IAM_description.md create mode 100644 Packs/AWS-IAM/ReleaseNotes/1_1_64.md diff --git a/Packs/AWS-IAM/Integrations/AWS-IAM/AWS-IAM.py b/Packs/AWS-IAM/Integrations/AWS-IAM/AWS-IAM.py index a65f6c2465bb..9e421a3d05b4 100644 --- a/Packs/AWS-IAM/Integrations/AWS-IAM/AWS-IAM.py +++ b/Packs/AWS-IAM/Integrations/AWS-IAM/AWS-IAM.py @@ -1,5 +1,7 @@ import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 + + import botocore.exceptions from datetime import datetime, date @@ -385,6 +387,56 @@ def delete_access_key(args, client): # pragma: no cover demisto.results("The Access Key was deleted") +def list_mfa_devices(args, client): + user_name = args.get('userName', "") + marker = args.get('marker', None) + limit, is_manual, page_size = get_limit(args) + + kwargs = { + 'UserName': user_name, + 'MaxItems': limit + } + if marker: + kwargs.update({'Marker': marker}) + response = client.list_mfa_devices(**kwargs) + + mfa_devices = response['MFADevices'] + data = [] + + for mfa_device in mfa_devices: + data.append({ + 'UserName': mfa_device['UserName'], + 'SerialNumber': mfa_device['SerialNumber'], + 'EnableDate': datetime.strftime(mfa_device['EnableDate'], '%Y-%m-%d %H:%M:%S'), + }) + if is_manual and page_size and len(data) > page_size: + data = data[-1 * page_size:] + human_readable = tableToMarkdown('AWS IAM Users MFA Devices', data) + return CommandResults( + readable_output=human_readable, + outputs_key_field="UserName", + outputs_prefix="AWS.IAM.MFADevices", + outputs={"Devices": data, "Marker": response["Marker"]}, + ) + + +def deactivate_mfa_device(args, client): + response = client.deactivate_mfa_device( + UserName=args['userName'], + SerialNumber=args['serialNumber'] + ) + if response['ResponseMetadata']['HTTPStatusCode'] == 200: + demisto.results('The User {} mfa device has been deactivated'.format(args.get('userName'))) + + +def delete_virtual_mfa_device(args, client): + response = client.delete_virtual_mfa_device( + SerialNumber=args['serialNumber'] + ) + if response['ResponseMetadata']['HTTPStatusCode'] == 200: + demisto.results('The User {} mfa device has been deleted'.format(args.get('serialNumber'))) + + def create_instance_profile(args, client): # pragma: no cover kwargs = {'InstanceProfileName': args.get('instanceProfileName')} if args.get('path') is not None: @@ -1321,6 +1373,12 @@ def main(): # pragma: no cover remove_user_from_group(args, client) elif command == 'aws-iam-delete-access-key': delete_access_key(args, client) + elif command == 'aws-iam-list-mfa-devices': + list_mfa_devices(args, client) + elif command == 'aws-iam-deactivate-mfa-devices': + deactivate_mfa_device(args, client) + elif command == 'aws-iam-delete-mfa-devices': + delete_virtual_mfa_device(args, client) elif command == 'aws-iam-create-instance-profile': create_instance_profile(args, client) elif command == 'aws-iam-delete-instance-profile': diff --git a/Packs/AWS-IAM/Integrations/AWS-IAM/AWS-IAM.yml b/Packs/AWS-IAM/Integrations/AWS-IAM/AWS-IAM.yml index c606dfa482b0..d12aeda68d78 100644 --- a/Packs/AWS-IAM/Integrations/AWS-IAM/AWS-IAM.yml +++ b/Packs/AWS-IAM/Integrations/AWS-IAM/AWS-IAM.yml @@ -1545,7 +1545,71 @@ script: - contextPath: AWS.IAM.Roles.AttachedPolicies.Query.Marker description: When IsTruncated is true, this element is present and contains the value to use for the Marker parameter in a subsequent pagination request. type: string - dockerimage: demisto/boto3py3:1.0.0.100468 + - arguments: + - description: The name of the user whose MFA devices you want to list. + name: userName + required: true + - description: The Amazon Resource Name (ARN) of the role to assume. + name: roleArn + required: false + - description: An identifier for the assumed role session. + name: roleSessionName + required: false + - description: The duration, in seconds, of the role session. The value can range from 900 seconds (15 minutes) up to the maximum session duration setting for the role. + name: roleSessionDuration + required: false + - description: Use this parameter only when paginating results and only after you receive a response indicating that the results are truncated. Set it to the value of the Marker element in the response that you received to indicate where the next call should start. + name: marker + required: false + name: aws-iam-list-mfa-devices + description: Lists the MFA devices for an IAM user. + outputs: + - contextPath: AWS.IAM.MFADevices.Devices.UserName + description: The user with whom the MFA device is associated. + type: string + - contextPath: AWS.IAM.MFADevices.Devices.SerialNumber + description: The serial number that uniquely identifies the MFA device. For virtual MFA devices, the serial number is the device ARN. + type: string + - contextPath: AWS.IAM.MFADevices.Devices.EnableDate + description: The date when the MFA device was enabled for the user. + type: date + - contextPath: MFADevices.Devices.Marker + description: First element of next page of items. + type: string + - arguments: + - description: The name of the user whose MFA devices you want to list. + name: userName + required: true + - description: The serial number that uniquely identifies the MFA device. For virtual MFA devices, the serial number is the same as the ARN. + name: serialNumber + required: true + - description: The Amazon Resource Name (ARN) of the role to assume. + name: roleArn + required: false + - description: An identifier for the assumed role session. + name: roleSessionName + required: false + - description: The duration, in seconds, of the role session. The value can range from 900 seconds (15 minutes) up to the maximum session duration setting for the role. + name: roleSessionDuration + required: false + description: Deactivates the specified MFA device and removes it from association with the user name for which it was originally enabled. + name: aws-iam-deactivate-mfa-devices + - arguments: + - description: The serial number that uniquely identifies the MFA device. For virtual MFA devices, the serial number is the same as the ARN. + name: serialNumber + required: true + - description: The Amazon Resource Name (ARN) of the role to assume. + name: roleArn + required: false + - description: An identifier for the assumed role session. + name: roleSessionName + required: false + - description: The duration, in seconds, of the role session. The value can range from 900 seconds (15 minutes) up to the maximum session duration setting for the role. + name: roleSessionDuration + required: false + description: Deletes a virtual MFA device. + name: aws-iam-delete-mfa-devices + dockerimage: demisto/boto3py3:1.0.0.101103 runonce: false script: '-' subtype: python3 diff --git a/Packs/AWS-IAM/Integrations/AWS-IAM/AWS-IAM_description.md b/Packs/AWS-IAM/Integrations/AWS-IAM/AWS-IAM_description.md new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/Packs/AWS-IAM/Integrations/AWS-IAM/AWS-IAM_test.py b/Packs/AWS-IAM/Integrations/AWS-IAM/AWS-IAM_test.py index 675f39f7e888..46d0784bcc5f 100644 --- a/Packs/AWS-IAM/Integrations/AWS-IAM/AWS-IAM_test.py +++ b/Packs/AWS-IAM/Integrations/AWS-IAM/AWS-IAM_test.py @@ -3,7 +3,7 @@ import pytest import importlib import demistomock as demisto - +from pytest_mock import MockerFixture AWS_IAM = importlib.import_module("AWS-IAM") ATTACHED_POLICIES = [ @@ -81,6 +81,15 @@ def get_user(self): def list_attached_role_policies(self): pass + def deactivate_mfa_device(self): + pass + + def delete_virtual_mfa_device(self): + pass + + def list_mfa_devices(self): + pass + @property def exceptions(self): raise NoSuchEntityException @@ -516,3 +525,99 @@ def test_list_attached_role_policies(mocker, is_truncated: bool, expeted_second_ assert result[1].outputs.get('Marker') == expected_marker assert result[1].raw_response == response assert result[1].readable_output == expeted_second_output + + +def test_deactivate_mfa_device(mocker: MockerFixture): + """ + Given: + args - userName, serialNumber. + When: + calling deactivate_mfa_device function. + Then: + Ensure that the response returns as expected and contains the userName. + """ + mock_res = { + "ResponseMetadata": { + "HTTPStatusCode": 200 + } + } + + args = { + "userName": "test", + "serialNumber": "test1" + } + mocker.patch.object(Boto3Client, "deactivate_mfa_device", return_value=mock_res) + results = mocker.patch.object(demisto, 'results') + + client = Boto3Client() + AWS_IAM.deactivate_mfa_device(args, client) + + assert results.call_args[0][0] == "The User test mfa device has been deactivated" + + +def test_delete_virtual_mfa_device(mocker: MockerFixture): + """ + Given: + args - serialNumber. + When: + calling delete_virtual_mfa_device function. + Then: + Ensure that the response returns as expected and contains the userName. + """ + mock_res = { + "ResponseMetadata": { + "HTTPStatusCode": 200 + } + } + + args = { + "serialNumber": "test1" + } + mocker.patch.object(Boto3Client, "delete_virtual_mfa_device", return_value=mock_res) + results = mocker.patch.object(demisto, 'results') + + client = Boto3Client() + AWS_IAM.delete_virtual_mfa_device(args, client) + + assert results.call_args[0][0] == "The User test1 mfa device has been deleted" + + +@pytest.mark.parametrize( + "page_size", + [ + 1, + 2 + ] +) +def test_list_mfa_devices(mocker: MockerFixture, page_size: int): + """ + Given: + - page_size argument + Then: + - run `list_mfa_devices` function + When: + - Ensure that `outputs_prefix` is as expected + - Ensure that the number of returned devices is as expected + """ + mock_res = { + "MFADevices": [ + { + "UserName": "test", + "SerialNumber": "test", + "EnableDate": datetime.datetime(2021, 11, 7, 15, 55, 3) + }, + { + "UserName": "test2", + "SerialNumber": "test2", + "EnableDate": datetime.datetime(2022, 11, 7, 15, 55, 3) + } + ], + "Marker": "test" + } + mocker.patch.object(Boto3Client, "list_mfa_devices", return_value=mock_res) + + client = Boto3Client() + res = AWS_IAM.list_mfa_devices({"page_size": page_size, "page": 1}, client) + + assert len(res.outputs["Devices"]) == page_size + assert res.outputs_prefix == "AWS.IAM.MFADevices" diff --git a/Packs/AWS-IAM/Integrations/AWS-IAM/README.md b/Packs/AWS-IAM/Integrations/AWS-IAM/README.md index 12bbf8900adf..a37cccc228ce 100644 --- a/Packs/AWS-IAM/Integrations/AWS-IAM/README.md +++ b/Packs/AWS-IAM/Integrations/AWS-IAM/README.md @@ -1975,3 +1975,75 @@ List all managed policies that are attached to the specified IAM role. Listed 2 attached policies for role test-role + +### aws-iam-list-mfa-devices + +*** +Lists the MFA devices for an IAM user. + +#### Base Command + +`aws-iam-list-mfa-devices` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| userName | The name of the user whose MFA devices you want to list. | Required | +| roleArn | The Amazon Resource Name (ARN) of the role to assume. | Optional | +| roleSessionName | An identifier for the assumed role session. | Optional | +| roleSessionDuration | The duration, in seconds, of the role session. The value can range from 900 seconds (15 minutes) up to the maximum session duration setting for the role. | Optional | +| marker | Use this parameter only when paginating results and only after you receive a response indicating that the results are truncated. Set it to the value of the Marker element in the response that you received to indicate where the next call should start. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| AWS.IAM.MFADevices.Devices.UserName | string | The user with whom the MFA device is associated. | +| AWS.IAM.MFADevices.Devices.SerialNumber | string | The serial number that uniquely identifies the MFA device. For virtual MFA devices, the serial number is the device ARN. | +| AWS.IAM.MFADevices.Devices.EnableDate | date | The date when the MFA device was enabled for the user. | +| MFADevices.Devices.Marker | string | First element of next page of items. | + +### aws-iam-delete-mfa-devices + +*** +Deletes a virtual MFA device. + +#### Base Command + +`aws-iam-delete-mfa-devices` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| serialNumber | The serial number that uniquely identifies the MFA device. For virtual MFA devices, the serial number is the same as the ARN. | Required | +| roleArn | The Amazon Resource Name (ARN) of the role to assume. | Optional | +| roleSessionName | An identifier for the assumed role session. | Optional | +| roleSessionDuration | The duration, in seconds, of the role session. The value can range from 900 seconds (15 minutes) up to the maximum session duration setting for the role. | Optional | + +#### Context Output + +There is no context output for this command. +### aws-iam-deactivate-mfa-devices + +*** +Deactivates the specified MFA device and removes it from association with the user name for which it was originally enabled. + +#### Base Command + +`aws-iam-deactivate-mfa-devices` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| userName | The name of the user whose MFA devices you want to list. | Required | +| serialNumber | The serial number that uniquely identifies the MFA device. For virtual MFA devices, the serial number is the same as the ARN. | Required | +| roleArn | The Amazon Resource Name (ARN) of the role to assume. | Optional | +| roleSessionName | An identifier for the assumed role session. | Optional | +| roleSessionDuration | The duration, in seconds, of the role session. The value can range from 900 seconds (15 minutes) up to the maximum session duration setting for the role. | Optional | + +#### Context Output + +There is no context output for this command. diff --git a/Packs/AWS-IAM/ReleaseNotes/1_1_64.md b/Packs/AWS-IAM/ReleaseNotes/1_1_64.md new file mode 100644 index 000000000000..755b53b01768 --- /dev/null +++ b/Packs/AWS-IAM/ReleaseNotes/1_1_64.md @@ -0,0 +1,8 @@ + +#### Integrations + +##### AWS - Identity and Access Management + +- Added the aws-iam-list-mfa-devices command. +- Added the aws-iam-deactivate-mfa-devices command. +- Added the aws-iam-delete-mfa-devices command. diff --git a/Packs/AWS-IAM/pack_metadata.json b/Packs/AWS-IAM/pack_metadata.json index 6f8d4712c802..136e6cab918a 100644 --- a/Packs/AWS-IAM/pack_metadata.json +++ b/Packs/AWS-IAM/pack_metadata.json @@ -3,7 +3,7 @@ "description": "Amazon Web Services Identity and Access Management (IAM)", "support": "xsoar", "author": "Cortex XSOAR", - "currentVersion": "1.1.63", + "currentVersion": "1.1.64", "url": "https://www.paloaltonetworks.com/cortex", "email": "", "created": "2020-04-14T00:00:00Z", From 509022bf02e055dfa7300c9e980c26d8f359650b Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Sun, 11 Aug 2024 13:04:16 +0300 Subject: [PATCH 07/14] [AWS E+R] EXPANDR-10800 (#35793) (#35823) * fix bug * RN Co-authored-by: johnnywilkes <32227961+johnnywilkes@users.noreply.github.com> --- Packs/AWS-Enrichment-Remediation/ReleaseNotes/1_1_20.md | 6 ++++++ .../Scripts/AWSRecreateSG/AWSRecreateSG.py | 4 ++-- .../Scripts/AWSRecreateSG/AWSRecreateSG.yml | 2 +- Packs/AWS-Enrichment-Remediation/pack_metadata.json | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 Packs/AWS-Enrichment-Remediation/ReleaseNotes/1_1_20.md diff --git a/Packs/AWS-Enrichment-Remediation/ReleaseNotes/1_1_20.md b/Packs/AWS-Enrichment-Remediation/ReleaseNotes/1_1_20.md new file mode 100644 index 000000000000..1c4a07d6729a --- /dev/null +++ b/Packs/AWS-Enrichment-Remediation/ReleaseNotes/1_1_20.md @@ -0,0 +1,6 @@ + +#### Scripts + +##### AWSRecreateSG + +Fixed an issue where `All UDP` and `All TCP` Security Group rules were being treated as if they were `All Traffic` rules. diff --git a/Packs/AWS-Enrichment-Remediation/Scripts/AWSRecreateSG/AWSRecreateSG.py b/Packs/AWS-Enrichment-Remediation/Scripts/AWSRecreateSG/AWSRecreateSG.py index c221214a2a79..1be43cd69bf5 100644 --- a/Packs/AWS-Enrichment-Remediation/Scripts/AWSRecreateSG/AWSRecreateSG.py +++ b/Packs/AWS-Enrichment-Remediation/Scripts/AWSRecreateSG/AWSRecreateSG.py @@ -22,7 +22,7 @@ def split_rule(rule: dict, port: int, protocol: str) -> list[dict]: """ res_list = [] # Check if 'FromPort' is in rule, else it is an "all traffic rule". - if rule.get('FromPort'): + if 'FromPort' in rule: # Port of interest is in front of back of range, therefore, edit the original rule. if rule['FromPort'] == port: rule['FromPort'] = rule['FromPort'] + 1 @@ -77,7 +77,7 @@ def sg_fix(sg_info: list, port: int, protocol: str, assume_role: str, instance_t for rule in info['IpPermissions']: if rule.get('IpRanges') and len(rule.get('IpRanges')) > 0: # Check if 'FromPort' is in rule, else it is an "all traffic rule". - if rule.get('FromPort'): + if 'FromPort' in rule: # Don't recreate if it targets just the port of interest. if ( rule['FromPort'] == port diff --git a/Packs/AWS-Enrichment-Remediation/Scripts/AWSRecreateSG/AWSRecreateSG.yml b/Packs/AWS-Enrichment-Remediation/Scripts/AWSRecreateSG/AWSRecreateSG.yml index f9f15a05f2c9..ccdd5f9f5934 100644 --- a/Packs/AWS-Enrichment-Remediation/Scripts/AWSRecreateSG/AWSRecreateSG.yml +++ b/Packs/AWS-Enrichment-Remediation/Scripts/AWSRecreateSG/AWSRecreateSG.yml @@ -51,7 +51,7 @@ dependson: - AWS - EC2|||aws-ec2-authorize-security-group-egress-rule - AWS - EC2|||aws-ec2-revoke-security-group-ingress-rule - AWS - EC2|||aws-ec2-revoke-security-group-egress-rule -dockerimage: demisto/python3:3.10.13.87159 +dockerimage: demisto/python3:3.11.9.107421 enabled: true name: AWSRecreateSG runas: DBotWeakRole diff --git a/Packs/AWS-Enrichment-Remediation/pack_metadata.json b/Packs/AWS-Enrichment-Remediation/pack_metadata.json index b46cb27eb6ec..76818fdeefb0 100644 --- a/Packs/AWS-Enrichment-Remediation/pack_metadata.json +++ b/Packs/AWS-Enrichment-Remediation/pack_metadata.json @@ -2,7 +2,7 @@ "name": "AWS Enrichment and Remediation", "description": "Playbooks using multiple AWS content packs for enrichment and remediation purposes", "support": "xsoar", - "currentVersion": "1.1.19", + "currentVersion": "1.1.20", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 06a089162573114adb1ad6b905190322566afd04 Mon Sep 17 00:00:00 2001 From: omerKarkKatz <95565843+omerKarkKatz@users.noreply.github.com> Date: Sun, 11 Aug 2024 13:33:02 +0300 Subject: [PATCH 08/14] added the incident endpoint to netskope collector (#35653) * added the incident endpoint * commit * RN * added UT * added UT * added desc * Bump pack from version Netskope to 3.3.12. --------- Co-authored-by: Content Bot --- .../NetskopeEventCollector.py | 2 +- .../NetskopeEventCollector.yml | 7 ++-- .../NetskopeEventCollector_test.py | 37 ++++++++++++++++--- .../test_data/multiple_events_raw.json | 5 +++ Packs/Netskope/ReleaseNotes/3_3_12.md | 7 ++++ Packs/Netskope/pack_metadata.json | 2 +- 6 files changed, 50 insertions(+), 10 deletions(-) create mode 100644 Packs/Netskope/ReleaseNotes/3_3_12.md diff --git a/Packs/Netskope/Integrations/NetskopeEventCollector/NetskopeEventCollector.py b/Packs/Netskope/Integrations/NetskopeEventCollector/NetskopeEventCollector.py index af7dc9396b76..e752ebc1156d 100644 --- a/Packs/Netskope/Integrations/NetskopeEventCollector/NetskopeEventCollector.py +++ b/Packs/Netskope/Integrations/NetskopeEventCollector/NetskopeEventCollector.py @@ -11,7 +11,7 @@ ''' CONSTANTS ''' -ALL_SUPPORTED_EVENT_TYPES = ['application', 'alert', 'page', 'audit', 'network'] +ALL_SUPPORTED_EVENT_TYPES = ['application', 'alert', 'page', 'audit', 'network', 'incident'] MAX_EVENTS_PAGE_SIZE = 10000 MAX_SKIP = 50000 diff --git a/Packs/Netskope/Integrations/NetskopeEventCollector/NetskopeEventCollector.yml b/Packs/Netskope/Integrations/NetskopeEventCollector/NetskopeEventCollector.yml index 70d0f0f8bde8..8163cc7c756c 100644 --- a/Packs/Netskope/Integrations/NetskopeEventCollector/NetskopeEventCollector.yml +++ b/Packs/Netskope/Integrations/NetskopeEventCollector/NetskopeEventCollector.yml @@ -37,14 +37,15 @@ configuration: name: event_types_to_fetch type: 16 required: false - additionalinfo: 'Event types to fetch. Default is all available types: Application, Alert, Page, Audit, Network.' - defaultvalue: Application,Alert,Page,Audit,Network + additionalinfo: 'Event types to fetch. Default is all available types: Application, Alert, Page, Audit, Network, Incident.' + defaultvalue: Application,Alert,Page,Audit,Network,Incident options: - Application - Alert - Page - Audit - Network + - Incident - display: Trust any certificate (not secure) section: Connect name: insecure @@ -74,7 +75,7 @@ script: defaultValue: 10000 description: Returns events extracted from SaaS traffic and or logs. name: netskope-get-events - dockerimage: demisto/python3:3.10.13.87159 + dockerimage: demisto/python3:3.11.9.107421 runonce: false script: '-' subtype: python3 diff --git a/Packs/Netskope/Integrations/NetskopeEventCollector/NetskopeEventCollector_test.py b/Packs/Netskope/Integrations/NetskopeEventCollector/NetskopeEventCollector_test.py index 5ae225a6d12b..db861d6c9ece 100644 --- a/Packs/Netskope/Integrations/NetskopeEventCollector/NetskopeEventCollector_test.py +++ b/Packs/Netskope/Integrations/NetskopeEventCollector/NetskopeEventCollector_test.py @@ -1,7 +1,8 @@ import json import re import time - +from unittest.mock import MagicMock +import demistomock as demisto import dateparser import pytest from NetskopeEventCollector import ALL_SUPPORTED_EVENT_TYPES, RATE_LIMIT_REMAINING, RATE_LIMIT_RESET, Client @@ -75,7 +76,7 @@ def json_callback(request, _): url_matcher = re.compile('https://netskope[.]example[.]com/events/dataexport/events') requests_mock.get(url_matcher, json=json_callback) events, new_last_run = get_all_events(client, FIRST_LAST_RUN) - assert len(events) == 25 + assert len(events) == 26 assert events[0].get('event_id') == '1' assert events[0].get('_time') == '2023-05-22T10:30:16.000Z' assert all(new_last_run[event_type]['operation'] == 'next' for event_type in ALL_SUPPORTED_EVENT_TYPES) @@ -141,7 +142,8 @@ def test_honor_rate_limiting(mocker, headers, endpoint, expected_sleep): 'alert': {'operation': 'next'}, 'page': {'operation': 'next'}, 'audit': {'operation': 'next'}, - 'network': {'operation': 'next'}}, 'next'), + 'network': {'operation': 'next'}, + 'incident': {'operation': 'next'}}, 'next'), ]) def test_setup_last_run(mocker, last_run_dict, expected_operation_value): """ @@ -161,13 +163,14 @@ def test_setup_last_run(mocker, last_run_dict, expected_operation_value): first_fetch = dateparser.parse('2023-01-01T10:00:00Z') mocker.patch.object(dateparser, "parse", return_value=first_fetch) last_run = setup_last_run(last_run_dict, ALL_SUPPORTED_EVENT_TYPES) - assert all(val.get('operation') == expected_operation_value for key, val in last_run.items()) + assert all(val.get('operation') == expected_operation_value for _, val in last_run.items()) @pytest.mark.parametrize('event_types_to_fetch_param, expected_value', [ ('Application', ['application']), ('Alert, Page, Audit', ['alert', 'page', 'audit']), - (['Application', 'Audit', 'Network'], ['application', 'audit', 'network']), + (['Application', 'Audit', 'Network', 'Incident'], ['application', 'audit', 'network', 'incident']), + ('Incident', ['incident']), (None, ALL_SUPPORTED_EVENT_TYPES), ]) def test_event_types_to_fetch_parameter_handling(event_types_to_fetch_param, expected_value): @@ -253,3 +256,27 @@ def test_fix_last_run(last_run, supported_event_types, expected_result): from NetskopeEventCollector import remove_unsupported_event_types remove_unsupported_event_types(last_run, supported_event_types) assert last_run == expected_result + + +def test_incident_endpoint(mocker): + """ + Given: + - Netskope client set to fetch incident events. + When: + - Fetching events. + Then: + - Assert that the Netskope end point is called with the proper url and paras. + """ + from datetime import datetime + from NetskopeEventCollector import handle_data_export_single_event_type + mocker.patch.object(demisto, 'callingContext', {'context': {'IntegrationInstance': 'test_instance'}}) + mocker.patch('NetskopeEventCollector.is_execution_time_exceeded', return_value=False) + mocker.patch('NetskopeEventCollector.print_event_statistics_logs') + client = Client(BASE_URL, 'dummy_token', False, False, event_types_to_fetch=['incident']) + mock_response = MagicMock() + mock_response.json.return_value = {'result': 'fake_result', 'wait_time': 0} + request_mock = mocker.patch.object(Client, '_http_request', return_value=mock_response) + handle_data_export_single_event_type(client, 'incident', 'next', limit=50, execution_start_time=datetime.now()) + kwargs = request_mock.call_args.kwargs + assert kwargs['url_suffix'] == 'events/dataexport/events/incident' + assert kwargs['params'] == {'index': 'xsoar_collector_test_instance_incident', 'operation': 'next'} diff --git a/Packs/Netskope/Integrations/NetskopeEventCollector/test_data/multiple_events_raw.json b/Packs/Netskope/Integrations/NetskopeEventCollector/test_data/multiple_events_raw.json index f459467199c0..bb8d874cd38b 100644 --- a/Packs/Netskope/Integrations/NetskopeEventCollector/test_data/multiple_events_raw.json +++ b/Packs/Netskope/Integrations/NetskopeEventCollector/test_data/multiple_events_raw.json @@ -1703,5 +1703,10 @@ "userkey": "some@email.com" } ] + }, + "incident": { + "status": "success", + "msg": "", + "result": [{"timestamp": 1684751416}] } } diff --git a/Packs/Netskope/ReleaseNotes/3_3_12.md b/Packs/Netskope/ReleaseNotes/3_3_12.md new file mode 100644 index 000000000000..1730c096c6b7 --- /dev/null +++ b/Packs/Netskope/ReleaseNotes/3_3_12.md @@ -0,0 +1,7 @@ + +#### Integrations + +##### Netskope Event Collector + +- Added the option to fetch events from Netskope *events/dataexport/events/incident* endpoint +- Updated the Docker image to: *demisto/python3:3.11.9.107421*. diff --git a/Packs/Netskope/pack_metadata.json b/Packs/Netskope/pack_metadata.json index 652806da5b04..d6a8b1632d12 100644 --- a/Packs/Netskope/pack_metadata.json +++ b/Packs/Netskope/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Netskope", "description": "Cloud access security broker that enables to find, understand, and secure cloud apps.", "support": "xsoar", - "currentVersion": "3.3.11", + "currentVersion": "3.3.12", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 8490427917da140ec0e8861c5a818aca5b850015 Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Sun, 11 Aug 2024 14:57:23 +0300 Subject: [PATCH 09/14] feat: Fixing but - not has customer company (#35821) * squash * rn --------- Co-authored-by: Judah Schwartz --- Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.py | 11 +- .../BmcITSM/Integrations/BmcITSM/BmcITSM.yml | 8 + Packs/BmcITSM/Integrations/BmcITSM/README.md | 799 +++++++++--------- Packs/BmcITSM/ReleaseNotes/1_0_25.md | 6 + Packs/BmcITSM/pack_metadata.json | 2 +- 5 files changed, 425 insertions(+), 401 deletions(-) create mode 100644 Packs/BmcITSM/ReleaseNotes/1_0_25.md diff --git a/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.py b/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.py index 830f929b7858..ab6b8885f7c1 100644 --- a/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.py +++ b/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.py @@ -877,6 +877,7 @@ def create_task_request( urgency: str, scedulded_start_date: str, scedulded_end_date: str, + customer_company: str, **additional_fields, ) -> Dict[str, Any]: """ @@ -905,6 +906,7 @@ def create_task_request( urgency (str): Ticket urgency. scedulded_start_date (str): Schedulded start date. scedulded_end_date (str): Schedulded end date. + customer_company (str): Customer company name. Returns: Dict[str, Any]: API respnse from BmcITSM. @@ -932,7 +934,7 @@ def create_task_request( "Urgency": urgency, "State": "Active", "Parent Linked": "Active", - "Customer Company": "Calbro Services", + "Customer Company": customer_company, "Assigned To": assignee, "Scheduled Start Date": scedulded_start_date, "Scheduled End Date": scedulded_end_date, @@ -965,6 +967,7 @@ def update_task_request( location_company: str, scedulded_start_date: str, schedulded_end_date: str, + customer_company: str, **additional_fields, ): """ @@ -987,6 +990,7 @@ def update_task_request( location_company (str): Company assoiciated with ticet process. scedulded_start_date (str): Schedulded start date. scedulded_end_date (str): Schedulded end date. + customer_company (str): Customer company name. Returns: str: API respnse from BmcITSM. """ @@ -1008,6 +1012,7 @@ def update_task_request( "Assignee": assignee, "Scheduled Start Date": scedulded_start_date, "Scheduled End Date": schedulded_end_date, + "Customer Company": customer_company, **additional_fields, }) data = {"values": properties} @@ -2194,6 +2199,7 @@ def task_create_command(client: Client, args: Dict[str, Any]) -> CommandResults: impact = args.get("impact") urgency = args.get("urgency") support_company = args.get("support_company") + customer_company = args.get("customer_company") assigned_support_organization = args.get("assigned_support_organization") assigned_support_group_name = args.get("assigned_support_group") @@ -2229,6 +2235,7 @@ def task_create_command(client: Client, args: Dict[str, Any]) -> CommandResults: assigned_support_organization=assigned_support_organization, # type: ignore[arg-type] scedulded_start_date=scedulded_start_date.isoformat() if scedulded_start_date else None, # type: ignore[arg-type] scedulded_end_date=scedulded_end_date.isoformat() if scedulded_end_date else None, # type: ignore[arg-type] + customer_company=customer_company, # type: ignore[arg-type] **additional_fields, ) @@ -2282,6 +2289,7 @@ def task_update_command(client: Client, args: Dict[str, Any]) -> CommandResults: assignee = args.get("assignee") scedulded_start_date: datetime = arg_to_datetime(args.get("scedulded_start_date")) # type: ignore[assignment] schedulded_end_date: datetime = arg_to_datetime(args.get("schedulded_end_date")) # type: ignore[assignment] + customer_company = args.get("customer_company") # type: ignore[assignment] additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), # type: ignore[arg-type] "additional_fields") @@ -2306,6 +2314,7 @@ def task_update_command(client: Client, args: Dict[str, Any]) -> CommandResults: assigned_support_group_name=assigned_support_group_name, # type: ignore[arg-type] scedulded_start_date=scedulded_start_date.isoformat() if scedulded_start_date else None, # type: ignore[arg-type] schedulded_end_date=schedulded_end_date.isoformat if schedulded_end_date else None, # type: ignore[arg-type] + customer_company=customer_company, # type: ignore[arg-type] **additional_fields, ) diff --git a/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.yml b/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.yml index 224b419e8cf4..9cae1604303b 100644 --- a/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.yml +++ b/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.yml @@ -1161,6 +1161,10 @@ script: description: The task ticket summary. required: true defaultValue: "" + - name: customer_company + description: The name of the customer company. + required: false + defaultValue: "" - name: details description: The task ticket detailed description. required: true @@ -1282,6 +1286,10 @@ script: description: The ID of the task ticket to update. required: true defaultValue: "" + - name: customer_company + description: The name of the customer company. + required: false + defaultValue: "" - name: summary description: The task ticket summary. - name: details diff --git a/Packs/BmcITSM/Integrations/BmcITSM/README.md b/Packs/BmcITSM/Integrations/BmcITSM/README.md index 8b42b26fce92..88cc0960494c 100644 --- a/Packs/BmcITSM/Integrations/BmcITSM/README.md +++ b/Packs/BmcITSM/Integrations/BmcITSM/README.md @@ -43,25 +43,25 @@ Retrieves a list of user profiles from BMC Helix ITSM. The records are retrieved | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| user_ids | A comma-separated list of user IDs. Used as a filtering argument. | Optional | -| query | The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). | Optional | -| limit | The maximum number of records to retrieve. Default is 50. | Optional | -| page_size | The maximum number of records to retrieve per page. | Optional | -| page | The page number of the results to retrieve. | Optional | -| first_name | The user first name. Used as a filtering argument. | Optional | -| last_name | The user first name. Used as a filtering argument. | Optional | -| company | The user company name. Used as a filtering argument. | Optional | -| department | The user department name. Used as a filtering argument. | Optional | -| organization | The user organization name. Used as a filtering argument. | Optional | +| user_ids | A comma-separated list of user IDs. Used as a filtering argument. | Optional | +| query | The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). | Optional | +| limit | The maximum number of records to retrieve. Default is 50. | Optional | +| page_size | The maximum number of records to retrieve per page. | Optional | +| page | The page number of the results to retrieve. | Optional | +| first_name | The user first name. Used as a filtering argument. | Optional | +| last_name | The user first name. Used as a filtering argument. | Optional | +| company | The user company name. Used as a filtering argument. | Optional | +| department | The user department name. Used as a filtering argument. | Optional | +| organization | The user organization name. Used as a filtering argument. | Optional | #### Context Output | **Path** | **Type** | **Description** | | --- | --- | --- | -| BmcITSM.User.Id | String | The user ID. | -| BmcITSM.User.FirstName | String | The user first name. | -| BmcITSM.User.LastName | String | The user last name. | +| BmcITSM.User.Id | String | The user ID. | +| BmcITSM.User.FirstName | String | The user first name. | +| BmcITSM.User.LastName | String | The user last name. | #### Command example ```!bmc-itsm-user-list limit=2``` @@ -119,22 +119,22 @@ Retrieves a list of companies from BMC Helix ITSM. The records are retrieved by | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| company_ids | A comma-separated list of company ID. Filtering argument. | Optional | -| query | The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). | Optional | -| limit | The maximum number of records to retrieve. Default is 50. | Optional | -| page_size | The maximum number of records to retrieve per page. | Optional | -| page | The page number of the results to retrieve. | Optional | -| company | The user company name. Used as a filtering argument. | Optional | -| company_type | The user company type. Used as a filtering argument. | Optional | +| company_ids | A comma-separated list of company ID. Filtering argument. | Optional | +| query | The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). | Optional | +| limit | The maximum number of records to retrieve. Default is 50. | Optional | +| page_size | The maximum number of records to retrieve per page. | Optional | +| page | The page number of the results to retrieve. | Optional | +| company | The user company name. Used as a filtering argument. | Optional | +| company_type | The user company type. Used as a filtering argument. | Optional | #### Context Output | **Path** | **Type** | **Description** | | --- | --- | --- | -| BmcITSM.Company.Id | String | The company ID. | -| BmcITSM.Company.Name | String | The company name. | -| BmcITSM.Company.Type | String | The company type. | +| BmcITSM.Company.Id | String | The company ID. | +| BmcITSM.Company.Name | String | The company name. | +| BmcITSM.Company.Type | String | The company type. | #### Command example ```!bmc-itsm-company-list limit=2``` @@ -180,21 +180,21 @@ Retrieves a list of service request definitions. The records are retrieved by th | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| srd_ids | A comma-separated list of service request definition IDs. Used as a filtering argument. | Optional | -| query | The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). | Optional | -| limit | The maximum number of records to retrieve. Default is 50. | Optional | -| page_size | The maximum number of records to retrieve per page. | Optional | -| page | The page number of the results to retrieve. | Optional | -| description | The service request ticket definition description. Used as a filtering argument. | Optional | +| srd_ids | A comma-separated list of service request definition IDs. Used as a filtering argument. | Optional | +| query | The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). | Optional | +| limit | The maximum number of records to retrieve. Default is 50. | Optional | +| page_size | The maximum number of records to retrieve per page. | Optional | +| page | The page number of the results to retrieve. | Optional | +| description | The service request ticket definition description. Used as a filtering argument. | Optional | #### Context Output | **Path** | **Type** | **Description** | | --- | --- | --- | -| BmcITSM.ServiceRequestDefinition.Id | String | The service request ticket definition ID. | -| BmcITSM.ServiceRequestDefinition.Description | String | The service request ticket definition description. | -| BmcITSM.ServiceRequestDefinition.InstanceID | String | The service request ticket instance ID. Used for creating service requests. | +| BmcITSM.ServiceRequestDefinition.Id | String | The service request ticket definition ID. | +| BmcITSM.ServiceRequestDefinition.Description | String | The service request ticket definition description. | +| BmcITSM.ServiceRequestDefinition.InstanceID | String | The service request ticket instance ID. Used for creating service requests. | #### Command example ```!bmc-itsm-service-request-definition-list limit=2``` @@ -240,44 +240,44 @@ Retrieves a list of BMC Helix ITSM tickets. The records are retrieved by the que | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| ticket_type | The type of tickets to search for. Possible values are: service request, incident, task, change request, problem investigation, known error, work order. | Required | -| query | The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). | Optional | -| limit | The maximum number of records to retrieve. Default is 50. | Optional | -| page_size | The maximum number of records to retrieve per page. | Optional | -| page | The page number of the results to retrieve. | Optional | -| ticket_ids | A comma-separated list of ticket request IDs. Used as a filtering argument. Use Display ID for work order type. | Optional | -| status | The status of the tickets to fetch. Since each ticket type has its own unique set of statuses, select only statuses that match the selected ticket type(s). Possible values are: Draft, In Cart, In Review, Submitted, Pending, Waiting Approval, Planning, In Progress, Completed, Rejected, Cancelled, Closed, New, Assigned, Resolved, Request For Authorization, Request For Change, Planning In Progress, Scheduled For Review, Scheduled For Approval, Scheduled, Implementation In Progress, Staged, Work In Progress, Waiting, Bypassed, Under Review, Under Investigation, Scheduled For Correction, Assigned To Vendor, No Action Planned, Corrected. | Optional | -| impact | The ticket impact. Used as a filtering argument. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Optional | -| urgency | The ticket urgency. Used as a filtering argument. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Optional | -| priority | The ticket priority. Used as a filtering argument. Possible values are: Critical, High, Medium, Low. | Optional | -| risk_level | The ticket risk level. Used as a filtering argument. Possible values are: Risk Level 1, Risk Level 2, Risk Level 3, Risk Level 4. | Optional | -| change_type | The ticket change type level. Relevant only for ticket type change requests. Used as a filtering argument. Possible values are: Project, Change, Release, Asset Configuration, Asset Management, Asset Lease, Purchase Requisition, Asset Maintenance. | Optional | -| summary | The ticket summary. Used as a filtering argument. | Optional | +| ticket_type | The type of tickets to search for. Possible values are: service request, incident, task, change request, problem investigation, known error, work order. | Required | +| query | The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). | Optional | +| limit | The maximum number of records to retrieve. Default is 50. | Optional | +| page_size | The maximum number of records to retrieve per page. | Optional | +| page | The page number of the results to retrieve. | Optional | +| ticket_ids | A comma-separated list of ticket request IDs. Used as a filtering argument. Use Display ID for work order type. | Optional | +| status | The status of the tickets to fetch. Since each ticket type has its own unique set of statuses, select only statuses that match the selected ticket type(s). Possible values are: Draft, In Cart, In Review, Submitted, Pending, Waiting Approval, Planning, In Progress, Completed, Rejected, Cancelled, Closed, New, Assigned, Resolved, Request For Authorization, Request For Change, Planning In Progress, Scheduled For Review, Scheduled For Approval, Scheduled, Implementation In Progress, Staged, Work In Progress, Waiting, Bypassed, Under Review, Under Investigation, Scheduled For Correction, Assigned To Vendor, No Action Planned, Corrected. | Optional | +| impact | The ticket impact. Used as a filtering argument. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Optional | +| urgency | The ticket urgency. Used as a filtering argument. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Optional | +| priority | The ticket priority. Used as a filtering argument. Possible values are: Critical, High, Medium, Low. | Optional | +| risk_level | The ticket risk level. Used as a filtering argument. Possible values are: Risk Level 1, Risk Level 2, Risk Level 3, Risk Level 4. | Optional | +| change_type | The ticket change type level. Relevant only for ticket type change requests. Used as a filtering argument. Possible values are: Project, Change, Release, Asset Configuration, Asset Management, Asset Lease, Purchase Requisition, Asset Maintenance. | Optional | +| summary | The ticket summary. Used as a filtering argument. | Optional | #### Context Output | **Path** | **Type** | **Description** | | --- | --- | --- | -| BmcITSM.Ticket.RequestID | String | The ticket ID. | -| BmcITSM.Ticket.DisplayID | String | The ticket request number. | -| BmcITSM.Ticket.InstanceId | String | The ticket instance ID. | -| BmcITSM.Ticket.Type | String | The ticket type. | -| BmcITSM.Ticket.TargetDate | Date | The ticket target date in UTC. | -| BmcITSM.Ticket.Status | String | The ticket status. | -| BmcITSM.Ticket.StatusReason | String | The ticket status reason. | -| BmcITSM.Ticket.Submitter | String | The ticket submitter. | -| BmcITSM.Ticket.Priority | String | The ticket priority. | -| BmcITSM.Ticket.RiskLevel | String | The ticket risk level. | -| BmcITSM.Ticket.Impact | String | The ticket impact. | -| BmcITSM.Ticket.Urgency | String | The ticket urgency. | -| BmcITSM.Ticket.Requester | Unknown | The ticket requester info. | -| BmcITSM.Ticket.Customer | Unknown | The ticket customer info. | -| BmcITSM.Ticket.assignee | Unknown | The ticket assignee info. | -| BmcITSM.Ticket.Summary | String | The ticket summary. | -| BmcITSM.Ticket.Details | String | The ticket details. | -| BmcITSM.Ticket.CreateDate | Date | The ticket create date time in UTC. | -| BmcITSM.Ticket.LastModifiedDate | Date | The ticket last update date time in UTC. | +| BmcITSM.Ticket.RequestID | String | The ticket ID. | +| BmcITSM.Ticket.DisplayID | String | The ticket request number. | +| BmcITSM.Ticket.InstanceId | String | The ticket instance ID. | +| BmcITSM.Ticket.Type | String | The ticket type. | +| BmcITSM.Ticket.TargetDate | Date | The ticket target date in UTC. | +| BmcITSM.Ticket.Status | String | The ticket status. | +| BmcITSM.Ticket.StatusReason | String | The ticket status reason. | +| BmcITSM.Ticket.Submitter | String | The ticket submitter. | +| BmcITSM.Ticket.Priority | String | The ticket priority. | +| BmcITSM.Ticket.RiskLevel | String | The ticket risk level. | +| BmcITSM.Ticket.Impact | String | The ticket impact. | +| BmcITSM.Ticket.Urgency | String | The ticket urgency. | +| BmcITSM.Ticket.Requester | Unknown | The ticket requester info. | +| BmcITSM.Ticket.Customer | Unknown | The ticket customer info. | +| BmcITSM.Ticket.assignee | Unknown | The ticket assignee info. | +| BmcITSM.Ticket.Summary | String | The ticket summary. | +| BmcITSM.Ticket.Details | String | The ticket details. | +| BmcITSM.Ticket.CreateDate | Date | The ticket create date time in UTC. | +| BmcITSM.Ticket.LastModifiedDate | Date | The ticket last update date time in UTC. | #### Command example ```!bmc-itsm-ticket-list ticket_type="service request" limit=2``` @@ -397,24 +397,24 @@ Creates a new service request ticket. A service request ticket is the request re | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| srd_instance_id | The instance ID of the service request ticket. It can be retrieved by executing bmc-itsm-service-request-definition-list command. | Required | -| first_name | The requester first name. By default it is determined by the logged in user. If provided, login_id, first_name, and last_name arguments must be provided together. | Optional | -| last_name | The requester last name. By default it is determined by the logged in user. If provided, login_id, first_name, and last_name arguments must be provided together. | Optional | -| login_id | The requester login ID. By default it is determined by the logged in user. If provided, login_id, first_name, and last_name arguments must be provided together. | Optional | -| summary | The service request ticket summary. | Optional | -| status | The service request ticket status. Possible values are: Draft, In Cart, In Review, Submitted, Pending, Waiting Approval, Planning, In Progress, Completed, Rejected, Cancelled, Closed. | Optional | -| urgency | The ticket urgency. Required when the ticket creation is without a template. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Optional | -| impact | The ticket impact. Required when the ticket creation is without a template. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Optional | -| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee, or any other custom field. | Optional | +| srd_instance_id | The instance ID of the service request ticket. It can be retrieved by executing bmc-itsm-service-request-definition-list command. | Required | +| first_name | The requester first name. By default it is determined by the logged in user. If provided, login_id, first_name, and last_name arguments must be provided together. | Optional | +| last_name | The requester last name. By default it is determined by the logged in user. If provided, login_id, first_name, and last_name arguments must be provided together. | Optional | +| login_id | The requester login ID. By default it is determined by the logged in user. If provided, login_id, first_name, and last_name arguments must be provided together. | Optional | +| summary | The service request ticket summary. | Optional | +| status | The service request ticket status. Possible values are: Draft, In Cart, In Review, Submitted, Pending, Waiting Approval, Planning, In Progress, Completed, Rejected, Cancelled, Closed. | Optional | +| urgency | The ticket urgency. Required when the ticket creation is without a template. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Optional | +| impact | The ticket impact. Required when the ticket creation is without a template. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Optional | +| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee, or any other custom field. | Optional | #### Context Output | **Path** | **Type** | **Description** | | --- | --- | --- | -| BmcITSM.ServiceRequest.RequestID | String | The service request ticket unique request ID. | -| BmcITSM.ServiceRequest.DisplayID | String | The service request ticket request number. | -| BmcITSM.ServiceRequest.CreateDate | Date | The service request ticket create date time in UTC. | +| BmcITSM.ServiceRequest.RequestID | String | The service request ticket unique request ID. | +| BmcITSM.ServiceRequest.DisplayID | String | The service request ticket request number. | +| BmcITSM.ServiceRequest.CreateDate | Date | The service request ticket create date time in UTC. | #### Command example ```!bmc-itsm-service-request-create service_request_definition_id=SRGAA5V0GENAWAO6ZQWYO6EBWDOUAU``` @@ -449,19 +449,19 @@ Updates the details of a service request ticket for a given request ID. User and | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| ticket_request_id | The unique identifier of the service request ticket to update. | Required | -| customer_first_name | The customer first name. By default it is determined by the logged in user. | Optional | -| customer_last_name | The customer last name. By default it is determined by the logged in user. | Optional | -| status | The service request ticket status. Possible values are: Draft, In Cart, In Review, Submitted, Pending, Waiting Approval, Planning, In Progress, Completed, Rejected, Cancelled, Closed. | Optional | -| urgency | The ticket request urgency. Required when the ticket creation is without a template. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Optional | -| impact | Incident Request impact. Required when the ticket creation is without a template. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Optional | -| status_reason | The reason for updating the status. Required only if status argument is provided. Possible values are: Review, Need More Information, Approval, System Error, With Issues, Automatically Closed, Successful, By User, By Provider, System, Cancelled, Reopen By User. | Optional | -| location_company | The company associated with the service request process. | Optional | -| region | The region associated with the company location. | Optional | -| site_group | The site group associated with the region. | Optional | -| site | The site associated with the site group. | Optional | -| assignee | The full name of the employee the ticket will be assigned to. It can be retrieved by using the bmc-itsm-user-list command. | Optional | -| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee, or any other custom field. | Optional | +| ticket_request_id | The unique identifier of the service request ticket to update. | Required | +| customer_first_name | The customer first name. By default it is determined by the logged in user. | Optional | +| customer_last_name | The customer last name. By default it is determined by the logged in user. | Optional | +| status | The service request ticket status. Possible values are: Draft, In Cart, In Review, Submitted, Pending, Waiting Approval, Planning, In Progress, Completed, Rejected, Cancelled, Closed. | Optional | +| urgency | The ticket request urgency. Required when the ticket creation is without a template. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Optional | +| impact | Incident Request impact. Required when the ticket creation is without a template. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Optional | +| status_reason | The reason for updating the status. Required only if status argument is provided. Possible values are: Review, Need More Information, Approval, System Error, With Issues, Automatically Closed, Successful, By User, By Provider, System, Cancelled, Reopen By User. | Optional | +| location_company | The company associated with the service request process. | Optional | +| region | The region associated with the company location. | Optional | +| site_group | The site group associated with the region. | Optional | +| site | The site associated with the site group. | Optional | +| assignee | The full name of the employee the ticket will be assigned to. It can be retrieved by using the bmc-itsm-user-list command. | Optional | +| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee, or any other custom field. | Optional | #### Context Output @@ -475,7 +475,7 @@ There is no context output for this command. ### bmc-itsm-incident-update *** -Update incident ticket. +Update incident ticket. #### Base Command @@ -485,28 +485,28 @@ Update incident ticket. | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| ticket_request_id | The ID of the incident ticket to update. | Required | -| first_name | The customer first name the incident ticket is for. | Optional | -| last_name | The customer last name the incident ticket is for. | Optional | -| summary | The incident ticket summary. | Optional | -| service_type | The type of the incident ticket. Possible values are: User Service Restoration, User Service Request, Infrastructure Restoration, Infrastructure Event, Security Incident. | Optional | -| urgency | The ticket urgency. Required when the ticket creation is without a template. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Optional | -| impact | The ticket impact. Required when the ticket creation is without a template. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Optional | -| status | The incident ticket status. Possible values are: New, Assigned, In Progress, Pending, Resolved, Closed, Cancelled. | Optional | -| reported_source | The incident ticket reported source. Possible values are: Direct Input, Email,External Escalation, Fax, Self Service, Systems Management, Phone, Voice Mail, Walk In, Web, Other, BMC Impact Manager Event. | Optional | -| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee, or any other custom field. Possible values are: The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value".Possible fields: Assigned Group, Assignee, or any other custom field.. | Optional | -| detailed_description | The incident ticket summary. | Optional | -| company | The company associated with the requester. By default it is determined by the logged in user. | Optional | -| assigned_support_company | The company for the assignee’s support organization. It makes up the first tier of the assignee’s support organization data structure. | Optional | -| assigned_support_organization | The organization for the assignee’s support organization. It makes up the second tier of the assignee’s support organization data structure. | Optional | -| assigned_group | The group for the assignee’s support organization. It makes up the third tier of the assignee’s support organization data structure. | Optional | -| assignee | The full name of the employee the ticket will be assigned to. It can be retrieved by using the bmc-itsm-user-list command. | Optional | -| assignee_login_id | The login ID of the assignee. The assignee and assignee_login_id arguments must be provided together. | Optional | -| region | The region, which makes up the second tier of the customer’s business organization data structure. | Optional | -| site_group | The site group associated with the region. | Optional | -| site | The site associated with the site group. | Optional | -| status_reason | The reason for updating the ticket status. Required when status is provided. Possible values are: Infrastructure Change Created, Local Site Action Required, Purchase Order Approval, Registration Approval, Supplier Delivery, Support Contact Hold, Third Party Vendor Action Reqd, Client Action Required, Infrastructure Change Request, Future Enhancement, Pending Original Incident, Client Hold, Monitoring Incident, Customer Follow-Up Required, Temporary Corrective Action, No Further Action Required, Resolved by Original Incident, Automated Resolution Reported, No longer a Causal CI, Pending Causal Incident Resolution, Resolved by Causal Incident. | Optional | -| resolution | The ticket resolution description. Required when status is provided. | Optional | +| ticket_request_id | The ID of the incident ticket to update. | Required | +| first_name | The customer first name the incident ticket is for. | Optional | +| last_name | The customer last name the incident ticket is for. | Optional | +| summary | The incident ticket summary. | Optional | +| service_type | The type of the incident ticket. Possible values are: User Service Restoration, User Service Request, Infrastructure Restoration, Infrastructure Event, Security Incident. | Optional | +| urgency | The ticket urgency. Required when the ticket creation is without a template. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Optional | +| impact | The ticket impact. Required when the ticket creation is without a template. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Optional | +| status | The incident ticket status. Possible values are: New, Assigned, In Progress, Pending, Resolved, Closed, Cancelled. | Optional | +| reported_source | The incident ticket reported source. Possible values are: Direct Input, Email,External Escalation, Fax, Self Service, Systems Management, Phone, Voice Mail, Walk In, Web, Other, BMC Impact Manager Event. | Optional | +| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee, or any other custom field. Possible values are: The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value".Possible fields: Assigned Group, Assignee, or any other custom field.. | Optional | +| detailed_description | The incident ticket summary. | Optional | +| company | The company associated with the requester. By default it is determined by the logged in user. | Optional | +| assigned_support_company | The company for the assignee’s support organization. It makes up the first tier of the assignee’s support organization data structure. | Optional | +| assigned_support_organization | The organization for the assignee’s support organization. It makes up the second tier of the assignee’s support organization data structure. | Optional | +| assigned_group | The group for the assignee’s support organization. It makes up the third tier of the assignee’s support organization data structure. | Optional | +| assignee | The full name of the employee the ticket will be assigned to. It can be retrieved by using the bmc-itsm-user-list command. | Optional | +| assignee_login_id | The login ID of the assignee. The assignee and assignee_login_id arguments must be provided together. | Optional | +| region | The region, which makes up the second tier of the customer’s business organization data structure. | Optional | +| site_group | The site group associated with the region. | Optional | +| site | The site associated with the site group. | Optional | +| status_reason | The reason for updating the ticket status. Required when status is provided. Possible values are: Infrastructure Change Created, Local Site Action Required, Purchase Order Approval, Registration Approval, Supplier Delivery, Support Contact Hold, Third Party Vendor Action Reqd, Client Action Required, Infrastructure Change Request, Future Enhancement, Pending Original Incident, Client Hold, Monitoring Incident, Customer Follow-Up Required, Temporary Corrective Action, No Further Action Required, Resolved by Original Incident, Automated Resolution Reported, No longer a Causal CI, Pending Causal Incident Resolution, Resolved by Causal Incident. | Optional | +| resolution | The ticket resolution description. Required when status is provided. | Optional | #### Context Output @@ -530,8 +530,8 @@ Deletes a ticket by its request ID. Only admin users can perform this command. | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| ticket_ids | A comma-separated list of ticket request IDs to delete. | Required | -| ticket_type | The type of the tickets to delete. Possible values are: incident, task, change request, problem investigation, known error, work order. | Required | +| ticket_ids | A comma-separated list of ticket request IDs to delete. | Required | +| ticket_type | The type of the tickets to delete. Possible values are: incident, task, change request, problem investigation, known error, work order. | Required | #### Context Output @@ -545,7 +545,7 @@ There is no context output for this command. ### bmc-itsm-incident-create *** -Creates a new incident ticket. An incident is any event that is not part of the standard operation of a service and that causes an interruption to or a reduction in the quality of that service. +Creates a new incident ticket. An incident is any event that is not part of the standard operation of a service and that causes an interruption to or a reduction in the quality of that service. #### Base Command @@ -555,35 +555,35 @@ Creates a new incident ticket. An incident is any event that is not part of the | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| first_name | The customer first name the incident ticket is for. | Required | -| last_name | The customer last name the incident ticket is for. | Required | -| template_instance_id | The instance ID of the template to use. Required only when the ticket attributes should be based on the template's fields. The instance ID can be retrieved by executing the bmc-itsm-incident-template-list command. | Optional | -| summary | The incident ticket summary. Required when the template_instance_id argument is not provided. | Optional | -| service_type | The type of the incident ticket. Required when the template_instance_id argument is not provided. Possible values are: User Service Restoration, User Service Request, Infrastructure Restoration, Infrastructure Event, Security Incident. | Optional | -| urgency | The ticket urgency. Required when the ticket creation is without a template. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Required | -| impact | The ticket impact. Required when the creation is without a template. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Required | -| status | Incident status. Possible values are: New, Assigned, In Progress, Pending, Resolved, Closed, Cancelled. | Required | -| reported_source | The incident ticket reported source. Required when the template_instance_id argument is not provided. Possible values are: Direct Input, Email,External Escalation, Fax, Self Service, Systems Management, Phone, Voice Mail, Walk In, Web, Other, BMC Impact Manager Event. | Optional | -| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee, or any other custom field. Possible values are: The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value".Possible fields: Assigned Group, Assignee, or any other custom field.. | Optional | -| details | The incident ticket detailed description. | Optional | -| company | The company associated with the requester. By default it is determined by the logged in user. | Optional | -| assigned_support_company | The company for the assignee’s support organization. It makes up the first tier of the assignee’s support organization data structure. | Optional | -| assigned_support_organization | The organization for the assignee’s support organization. It makes up the second tier of the assignee’s support organization data structure. | Optional | -| assigned_group | The group for the assignee’s support organization. It makes up the third tier of the assignee’s support organization data structure. | Optional | -| assignee | The full name of the employee the ticket will be assigned to. The assignee and assignee_login_id arguments must be provided together. It can be retrieved by using the bmc-itsm-user-list command. | Optional | -| assignee_login_id | The login ID of the assignee. The assignee and assignee_login_id arguments must be provided together. It can be retrieved by using the bmc-itsm-user-list command. | Optional | -| region | The region associated with the company. | Optional | -| site_group | The site group associated with the region. | Optional | -| site | The site associated with the site group. | Optional | +| first_name | The customer first name the incident ticket is for. | Required | +| last_name | The customer last name the incident ticket is for. | Required | +| template_instance_id | The instance ID of the template to use. Required only when the ticket attributes should be based on the template's fields. The instance ID can be retrieved by executing the bmc-itsm-incident-template-list command. | Optional | +| summary | The incident ticket summary. Required when the template_instance_id argument is not provided. | Optional | +| service_type | The type of the incident ticket. Required when the template_instance_id argument is not provided. Possible values are: User Service Restoration, User Service Request, Infrastructure Restoration, Infrastructure Event, Security Incident. | Optional | +| urgency | The ticket urgency. Required when the ticket creation is without a template. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Required | +| impact | The ticket impact. Required when the creation is without a template. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Required | +| status | Incident status. Possible values are: New, Assigned, In Progress, Pending, Resolved, Closed, Cancelled. | Required | +| reported_source | The incident ticket reported source. Required when the template_instance_id argument is not provided. Possible values are: Direct Input, Email,External Escalation, Fax, Self Service, Systems Management, Phone, Voice Mail, Walk In, Web, Other, BMC Impact Manager Event. | Optional | +| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee, or any other custom field. Possible values are: The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value".Possible fields: Assigned Group, Assignee, or any other custom field.. | Optional | +| details | The incident ticket detailed description. | Optional | +| company | The company associated with the requester. By default it is determined by the logged in user. | Optional | +| assigned_support_company | The company for the assignee’s support organization. It makes up the first tier of the assignee’s support organization data structure. | Optional | +| assigned_support_organization | The organization for the assignee’s support organization. It makes up the second tier of the assignee’s support organization data structure. | Optional | +| assigned_group | The group for the assignee’s support organization. It makes up the third tier of the assignee’s support organization data structure. | Optional | +| assignee | The full name of the employee the ticket will be assigned to. The assignee and assignee_login_id arguments must be provided together. It can be retrieved by using the bmc-itsm-user-list command. | Optional | +| assignee_login_id | The login ID of the assignee. The assignee and assignee_login_id arguments must be provided together. It can be retrieved by using the bmc-itsm-user-list command. | Optional | +| region | The region associated with the company. | Optional | +| site_group | The site group associated with the region. | Optional | +| site | The site associated with the site group. | Optional | #### Context Output | **Path** | **Type** | **Description** | | --- | --- | --- | -| BmcITSM.Incident.RequestID | String | The incident ticket request ID. | -| BmcITSM.Incident.DisplayID | String | The incident ticket display ID. | -| BmcITSM.Incident.CreateDate | Date | The incident ticket create date time in UTC. | +| BmcITSM.Incident.RequestID | String | The incident ticket request ID. | +| BmcITSM.Incident.DisplayID | String | The incident ticket display ID. | +| BmcITSM.Incident.CreateDate | Date | The incident ticket create date time in UTC. | #### Command example ```!bmc-itsm-incident-create first_name=Allen last_name=Allbrook impact="1-Extensive/Widespread" status=Assigned urgency="1-Critical" template_instance_id=AG00123F73CF5EKnsTSQ5rvrAAZfQA``` @@ -620,29 +620,29 @@ Creates a change request ticket in BMC Helix ITSM. The ticket is created by usin | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| first_name | The requester first name. | Required | -| last_name | The requester last name. | Required | -| customer_first_name | The customer first name. | Optional | -| customer_last_name | The customer last name. | Optional | -| summary | The change request ticket title. Required when the template ID argument is not provided. | Optional | -| template_id | The instance ID of the template to use. Required only when the ticket attributes should be based on the template's fields. The ID can be retrieved by executing the bmc-itsm-change-request-template-list command. | Optional | -| change_type | The change request ticket type. Required when the ticket creation is without a template. Possible values are: Project, Change, Release, Asset Configuration, Asset Management, Asset Lease, Purchase Requisition, Asset Maintenance. | Optional | -| change_timing | The class of the change request ticket which best describes your scenario. Possible values are: Emergency, Expedited, Latent, Normal, No Impact, Standard. | Optional | -| impact | The change request ticket impact. Required when the ticket creation is without a template. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Optional | -| urgency | The change request ticket urgency. Required when the ticket creation is without a template. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Optional | -| risk_level | The change request ticket risk level. Required when the ticket creation is without a template. Possible values are: Risk Level 1, Risk Level 2, Risk Level 3, Risk Level 4, Risk Level 5. | Optional | -| status | The change request ticket status. Required when the ticket creation is without a template. Possible values are: Request For Authorization, Request For Change, Planning In Progress, Scheduled For Review, Scheduled For Approval, Scheduled, Implementation In Progress, Pending, Rejected, Completed, Closed, Cancelled. | Optional | -| location_company | The company associated with the change request process. Required when template ID argument is not provided. | Optional | -| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee, or any other custom field. | Optional | +| first_name | The requester first name. | Required | +| last_name | The requester last name. | Required | +| customer_first_name | The customer first name. | Optional | +| customer_last_name | The customer last name. | Optional | +| summary | The change request ticket title. Required when the template ID argument is not provided. | Optional | +| template_id | The instance ID of the template to use. Required only when the ticket attributes should be based on the template's fields. The ID can be retrieved by executing the bmc-itsm-change-request-template-list command. | Optional | +| change_type | The change request ticket type. Required when the ticket creation is without a template. Possible values are: Project, Change, Release, Asset Configuration, Asset Management, Asset Lease, Purchase Requisition, Asset Maintenance. | Optional | +| change_timing | The class of the change request ticket which best describes your scenario. Possible values are: Emergency, Expedited, Latent, Normal, No Impact, Standard. | Optional | +| impact | The change request ticket impact. Required when the ticket creation is without a template. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Optional | +| urgency | The change request ticket urgency. Required when the ticket creation is without a template. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Optional | +| risk_level | The change request ticket risk level. Required when the ticket creation is without a template. Possible values are: Risk Level 1, Risk Level 2, Risk Level 3, Risk Level 4, Risk Level 5. | Optional | +| status | The change request ticket status. Required when the ticket creation is without a template. Possible values are: Request For Authorization, Request For Change, Planning In Progress, Scheduled For Review, Scheduled For Approval, Scheduled, Implementation In Progress, Pending, Rejected, Completed, Closed, Cancelled. | Optional | +| location_company | The company associated with the change request process. Required when template ID argument is not provided. | Optional | +| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee, or any other custom field. | Optional | #### Context Output | **Path** | **Type** | **Description** | | --- | --- | --- | -| BmcITSM.ChangeRequest.RequestID | String | The change request ticket unique request ID. | -| BmcITSM.ChangeRequest.DisplayID | String | The change request ticket request number. | -| BmcITSM.ChangeRequest.CreateDate | Date | The change request ticket create date time. | +| BmcITSM.ChangeRequest.RequestID | String | The change request ticket unique request ID. | +| BmcITSM.ChangeRequest.DisplayID | String | The change request ticket request number. | +| BmcITSM.ChangeRequest.CreateDate | Date | The change request ticket create date time. | #### Command example ```!bmc-itsm-change-request-create template_id=AG00123F73CF5EK3sTSQTb3rAAbfQA first_name=Allen last_name=Allbrook summary="Change request for README"``` @@ -679,28 +679,28 @@ Updates the details of change request ticket for the specified request ID. | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| ticket_request_id | The ID of the change request ticket to update. | Required | -| first_name | The customer first name the change request ticket is for. | Optional | -| last_name | The customer last name the change request ticket is for. | Optional | -| summary | The change request ticket summary. | Optional | -| change_type | The change request ticket type. Possible values are: Project, Change, Release, Asset Configuration, Asset Management, Asset Lease, Purchase Requisition, Asset Maintenance. | Optional | -| change_timing | The class of the change request ticket which best describes your scenario. Possible values are: Emergency, Expedited, Latent, Normal, No Impact, Standard. | Optional | -| impact | The change request ticket impact. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Optional | -| urgency | The change request ticket urgency. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Optional | -| risk_level | The change request ticket risk level. Possible values are: Risk Level 1, Risk Level 2, Risk Level 3, Risk Level 4, Risk Level 5. | Optional | -| status | The change request ticket status. Possible values are: Request For Authorization, Request For Change, Planning In Progress, Scheduled For Review, Scheduled For Approval, Scheduled, Implementation In Progress, Pending, Rejected, Completed, Closed, Cancelled. | Optional | -| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee, or any other custom field. | Optional | -| company | The company associated with the requester. By default it is determined by the logged in user. | Optional | -| organization | The organization associated with the requester. | Optional | -| department | The department associated with the requester. | Optional | -| location_company | The company associated with the change request process. | Optional | -| region | The region associated with the company location. | Optional | -| site_group | The site group associated with the region. | Optional | -| site | The site associated with the site group. | Optional | -| support_organization | The second tier of the change manager’s support organization data structure. | Optional | -| support_group_name | The third tier of the change manager’s support organization data structure. | Optional | -| status_reason | The reason for updating the ticket status. Required when status is provided. Possible values are: No Longer Required, Funding Not Available, To Be Re-Scheduled, Resources Not Available, Successful, Successful with Issues, Unsuccessful, Backed Out, Final Review Complete, Final Review Required, Additional Coding Required, Insufficient Task Data, In Verification, In Rollout, Insufficient Change Data, Schedule Conflicts, In Development, In Test, In Build, In Rollback, In Documentation, Vendor Purchase, Support Group Communication, Task Review, Miscellaneous, Future Enhancement, Manager Intervention, Accepted, Assigned, Built, On Hold. | Optional | -| details | The change request ticket details. | Optional | +| ticket_request_id | The ID of the change request ticket to update. | Required | +| first_name | The customer first name the change request ticket is for. | Optional | +| last_name | The customer last name the change request ticket is for. | Optional | +| summary | The change request ticket summary. | Optional | +| change_type | The change request ticket type. Possible values are: Project, Change, Release, Asset Configuration, Asset Management, Asset Lease, Purchase Requisition, Asset Maintenance. | Optional | +| change_timing | The class of the change request ticket which best describes your scenario. Possible values are: Emergency, Expedited, Latent, Normal, No Impact, Standard. | Optional | +| impact | The change request ticket impact. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Optional | +| urgency | The change request ticket urgency. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Optional | +| risk_level | The change request ticket risk level. Possible values are: Risk Level 1, Risk Level 2, Risk Level 3, Risk Level 4, Risk Level 5. | Optional | +| status | The change request ticket status. Possible values are: Request For Authorization, Request For Change, Planning In Progress, Scheduled For Review, Scheduled For Approval, Scheduled, Implementation In Progress, Pending, Rejected, Completed, Closed, Cancelled. | Optional | +| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee, or any other custom field. | Optional | +| company | The company associated with the requester. By default it is determined by the logged in user. | Optional | +| organization | The organization associated with the requester. | Optional | +| department | The department associated with the requester. | Optional | +| location_company | The company associated with the change request process. | Optional | +| region | The region associated with the company location. | Optional | +| site_group | The site group associated with the region. | Optional | +| site | The site associated with the site group. | Optional | +| support_organization | The second tier of the change manager’s support organization data structure. | Optional | +| support_group_name | The third tier of the change manager’s support organization data structure. | Optional | +| status_reason | The reason for updating the ticket status. Required when status is provided. Possible values are: No Longer Required, Funding Not Available, To Be Re-Scheduled, Resources Not Available, Successful, Successful with Issues, Unsuccessful, Backed Out, Final Review Complete, Final Review Required, Additional Coding Required, Insufficient Task Data, In Verification, In Rollout, Insufficient Change Data, Schedule Conflicts, In Development, In Test, In Build, In Rollback, In Documentation, Vendor Purchase, Support Group Communication, Task Review, Miscellaneous, Future Enhancement, Manager Intervention, Accepted, Assigned, Built, On Hold. | Optional | +| details | The change request ticket details. | Optional | #### Context Output @@ -723,35 +723,36 @@ Creates a new task ticket. By splitting cases into individual tasks (assignments | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| template_id | The instance ID of the template to use. The ID can be retrieved by executing the bmc-itsm-task-template-list command. | Optional | -| summary | The task ticket summary. | Required | -| details | The task ticket detailed description. | Required | -| root_ticket_type | The parent ticket type. Possible values are: change request, incident, problem investigation, known error, work order. | Required | -| root_request_id | The request ID of the parent ticket. Can be found in the context output of the bmc-itsm-ticket-list command. Use Display ID for work orders. | Required | -| root_request_name | The display name of the parent ticket in the task ticket. If not provided, the parent ticket displayID is displayed. | Optional | -| root_request_mode | The parent ticket request mode. Possible values are: Real, Simulation. Default is Real. | Optional | -| status | The task status. Possible values are: Staged, Assigned, Pending, Work In Progress, Waiting, Closed, Bypassed. | Required | -| task_type | Whether the task is manual or automatic. Possible values are: Automatic, Manual. | Optional | -| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assignee or any other custom field. Possible values are: The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value".Possible fields: Assignee or any other custom field.. | Optional | -| priority | The task ticket priority. Possible values are: Critical, High, Medium, Low. | Required | -| location_company | The company associated with the task process. | Required | -| support_company | The technical support team associated with the company. | Optional | -| assigned_support_organization | The organization for the task's support organization. It makes up the second tier of the task’s support organization data structure. The arguments assigned_support_organization, assigned_group, and support_company should be provided together. | Optional | -| assigned_support_group | The group for the task's support organization. It makes up the third tier of the task's support organization data structure. The arguments assigned_support_organization, assigned_group, and support_company should be provided together. | Optional | -| impact | The task ticket impact. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Optional | -| urgency | The task ticket urgency. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Optional | -| assignee | The full name of the employee the ticket will be assigned to. It can be retrieved by using the bmc-itsm-user-list command. | Optional | -| scedulded_start_date | The task ticket scheduled future start date. For example, in 12 hours, in 7 days. | Optional | -| scedulded_end_date | The task ticket scheduled future end date. For example, in 12 hours, in 7 days. | Optional | +| template_id | The instance ID of the template to use. The ID can be retrieved by executing the bmc-itsm-task-template-list command. | Optional | +| summary | The task ticket summary. | Required | +| details | The task ticket detailed description. | Required | +| root_ticket_type | The parent ticket type. Possible values are: change request, incident, problem investigation, known error, work order. | Required | +| root_request_id | The request ID of the parent ticket. Can be found in the context output of the bmc-itsm-ticket-list command. Use Display ID for work orders. | Required | +| customer_company | The name of the customer company. | Optional | +| root_request_name | The display name of the parent ticket in the task ticket. If not provided, the parent ticket displayID is displayed. | Optional | +| root_request_mode | The parent ticket request mode. Possible values are: Real, Simulation. Default is Real. | Optional | +| status | The task status. Possible values are: Staged, Assigned, Pending, Work In Progress, Waiting, Closed, Bypassed. | Required | +| task_type | Whether the task is manual or automatic. Possible values are: Automatic, Manual. | Optional | +| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assignee or any other custom field. Possible values are: The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value".Possible fields: Assignee or any other custom field.. | Optional | +| priority | The task ticket priority. Possible values are: Critical, High, Medium, Low. | Required | +| location_company | The company associated with the task process. | Required | +| support_company | The technical support team associated with the company. | Optional | +| assigned_support_organization | The organization for the task's support organization. It makes up the second tier of the task’s support organization data structure. The arguments assigned_support_organization, assigned_group, and support_company should be provided together. | Optional | +| assigned_support_group | The group for the task's support organization. It makes up the third tier of the task's support organization data structure. The arguments assigned_support_organization, assigned_group, and support_company should be provided together. | Optional | +| impact | The task ticket impact. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Optional | +| urgency | The task ticket urgency. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Optional | +| assignee | The full name of the employee the ticket will be assigned to. It can be retrieved by using the bmc-itsm-user-list command. | Optional | +| scedulded_start_date | The task ticket scheduled future start date. For example, in 12 hours, in 7 days. | Optional | +| scedulded_end_date | The task ticket scheduled future end date. For example, in 12 hours, in 7 days. | Optional | #### Context Output | **Path** | **Type** | **Description** | | --- | --- | --- | -| BmcITSM.Task.RequestID | String | The task ticket unique Request ID. | -| BmcITSM.Task.DisplayID | String | The task ticket request display ID. | -| BmcITSM.Task.CreateDate | Date | The task ticket creation date time in UTC. | +| BmcITSM.Task.RequestID | String | The task ticket unique Request ID. | +| BmcITSM.Task.DisplayID | String | The task ticket request display ID. | +| BmcITSM.Task.CreateDate | Date | The task ticket creation date time in UTC. | #### Command example ```!bmc-itsm-task-create location_company="Calbro Services" details="Details" priority=Critical root_request_id=PBI000000000322 root_request_name=error root_ticket_type="problem investigation" status=Assigned summary="Summary task" assigned_support_group="Service Desk" assigned_support_organization="IT Support" support_company="Calbro Services" task_type=Manual assignee="Francie Stafford" scedulded_end_date="in 10 days" scedulded_start_date="in 2 days"``` @@ -778,7 +779,7 @@ Creates a new task ticket. By splitting cases into individual tasks (assignments ### bmc-itsm-task-update *** -Updates the task ticket. +Updates the task ticket. #### Base Command @@ -788,22 +789,23 @@ Updates the task ticket. | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| ticket_request_id | The ID of the task ticket to update. | Required | -| summary | The task ticket summary. | Optional | -| details | The task ticket detailed description. | Optional | -| priority | The task ticket priority. Possible values are: Critical, High, Medium, Low. | Optional | -| status | The task ticket status. Possible values are: Staged, Assigned, Pending, Work In Progress, Waiting, Closed, Bypassed. | Optional | -| status_reason | The reason for changing the ticket status. Required when the status is changed. Possible values are: Success, Failed, Cancelled, Assignment, Staging in Progress, Staging Complete, Acknowledgment, Another Task, Task Rule, Completion, Error. | Optional | -| company | The company associated with the requester. By default it is determined by the logged in user. | Optional | -| location_company | The company associated with the task process. | Optional | -| support_company | The technical support team associated with the company. | Optional | -| assignee | The full name of the employee the ticket is assigned to. It can be retrieved by using the bmc-itsm-user-list command. | Optional | -| assigned_support_organization | The organization for the problem assignee’s support organization. It makes up the second tier of the problem assignee’s support organization data structure. The arguments assigned_support_organization, assigned_group, and assigned_support_company should be provided together. | Optional | -| assigned_group | The group for the problem assignee's support organization. It makes up the third tier of the problem assignee's support organization data structure. The arguments assigned_support_organization, assigned_group, and support_company should be provided together. | Optional | -| task_type | The task ticket type. Possible values are: Automatic, Manual. | Optional | -| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assignee or any other custom field. Possible values are: The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value".Possible fields: Assignee or any other custom field.. | Optional | -| scedulded_start_date | The task ticket scheduled future start date. For example, in 12 hours, in 7 days. | Optional | -| scedulded_end_date | The task ticket scheduled future end date. For example, in 12 hours, in 7 days. | Optional | +| ticket_request_id | The ID of the task ticket to update. | Required | +| summary | The task ticket summary. | Optional | +| details | The task ticket detailed description. | Optional | +| priority | The task ticket priority. Possible values are: Critical, High, Medium, Low. | Optional | +| customer_company | The name of the customer company. | Optional | +| status | The task ticket status. Possible values are: Staged, Assigned, Pending, Work In Progress, Waiting, Closed, Bypassed. | Optional | +| status_reason | The reason for changing the ticket status. Required when the status is changed. Possible values are: Success, Failed, Cancelled, Assignment, Staging in Progress, Staging Complete, Acknowledgment, Another Task, Task Rule, Completion, Error. | Optional | +| company | The company associated with the requester. By default it is determined by the logged in user. | Optional | +| location_company | The company associated with the task process. | Optional | +| support_company | The technical support team associated with the company. | Optional | +| assignee | The full name of the employee the ticket is assigned to. It can be retrieved by using the bmc-itsm-user-list command. | Optional | +| assigned_support_organization | The organization for the problem assignee’s support organization. It makes up the second tier of the problem assignee’s support organization data structure. The arguments assigned_support_organization, assigned_group, and assigned_support_company should be provided together. | Optional | +| assigned_group | The group for the problem assignee's support organization. It makes up the third tier of the problem assignee's support organization data structure. The arguments assigned_support_organization, assigned_group, and support_company should be provided together. | Optional | +| task_type | The task ticket type. Possible values are: Automatic, Manual. | Optional | +| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assignee or any other custom field. Possible values are: The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value".Possible fields: Assignee or any other custom field.. | Optional | +| scedulded_start_date | The task ticket scheduled future start date. For example, in 12 hours, in 7 days. | Optional | +| scedulded_end_date | The task ticket scheduled future end date. For example, in 12 hours, in 7 days. | Optional | #### Context Output @@ -817,7 +819,7 @@ There is no context output for this command. ### bmc-itsm-problem-investigation-create *** -Creates a problem investigation ticket. +Creates a problem investigation ticket. #### Base Command @@ -827,40 +829,40 @@ Creates a problem investigation ticket. | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| first_name | The customer first name the ticket request is for. | Required | -| last_name | The customer last name the ticket request is for. | Required | -| status | The problem investigation ticket status. Possible values are: Draft, Under Review, Request for Authorization, Assigned, Under Investigation, Pending, Completed, Rejected, Closed, Cancelled. | Required | -| investigation_driver | The problem investigation ticket driver. Possible values are: High Impact Incident, Re-Occurring Incidents, Non-Routine Incident, Other. | Required | -| summary | The problem investigation ticket summary. | Required | -| details | The detailed description on the problem investigation ticket. | Optional | -| impact | The problem investigation ticket impact. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Required | -| urgency | The problem investigation ticket urgency. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Required | -| target_resolution_date | The future resolution date. For example, in 12 hours, in 7 days. | Optional | -| company | The company associated with the requester. By default it is determined by the logged in user. | Optional | -| region | The region of the problem investigation location. The arguments region, site_group, and site should be provided together. | Optional | -| site_group | The site group of the problem investigation location. The arguments region, site_group, and site should be provided together. | Optional | -| site | The site of the problem investigation location. The arguments region, site_group, and site should be provided together. | Optional | -| assignee | The full name of the employee the ticket will be assigned to. It can be retrieved by using the bmc-itsm-user-list command. | Optional | -| assignee_pbm_mgr | The full name of the employee the ticket will be assigned to as the problem coordinator. It can be retrieved by using the bmc-itsm-user-list command. | Optional | -| assigned_group_pbm_mgr | The group for the problem coordinator’s support organization, which makes up the third tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. | Optional | -| support_company_pbm_mgr | The company for the problem coordinator’s support organization, which makes up the first tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. | Optional | -| support_organization_pbm_mgr | The organization for the problem coordinator’s support organization, which makes up the second tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. | Optional | -| assigned_support_company | The company for the problem assignee’s support organization. It makes up the first tier of the problem assignee’s support organization data structure. The arguments assigned_support_organization, assigned_group, and assigned_support_company should be provided together. | Optional | -| assigned_support_organization | The organization for the problem assignee’s support organization. It makes up the second tier of the problem assignee’s support organization data structure. The arguments assigned_support_organization, assigned_group, and assigned_support_company should be provided together. | Optional | -| assigned_group | The group for the problem assignee's support organization. It makes up the third tier of the problem assignee's support organization data structure. The arguments assigned_support_organization, assigned_group, and support_company should be provided together. | Optional | -| investigation_justification | The justification for the ticket creation. | Optional | -| temporary_workaround | The problem workaround. | Optional | -| resolution | The ticket resolution. | Optional | -| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee or any other custom field. | Optional | +| first_name | The customer first name the ticket request is for. | Required | +| last_name | The customer last name the ticket request is for. | Required | +| status | The problem investigation ticket status. Possible values are: Draft, Under Review, Request for Authorization, Assigned, Under Investigation, Pending, Completed, Rejected, Closed, Cancelled. | Required | +| investigation_driver | The problem investigation ticket driver. Possible values are: High Impact Incident, Re-Occurring Incidents, Non-Routine Incident, Other. | Required | +| summary | The problem investigation ticket summary. | Required | +| details | The detailed description on the problem investigation ticket. | Optional | +| impact | The problem investigation ticket impact. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Required | +| urgency | The problem investigation ticket urgency. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Required | +| target_resolution_date | The future resolution date. For example, in 12 hours, in 7 days. | Optional | +| company | The company associated with the requester. By default it is determined by the logged in user. | Optional | +| region | The region of the problem investigation location. The arguments region, site_group, and site should be provided together. | Optional | +| site_group | The site group of the problem investigation location. The arguments region, site_group, and site should be provided together. | Optional | +| site | The site of the problem investigation location. The arguments region, site_group, and site should be provided together. | Optional | +| assignee | The full name of the employee the ticket will be assigned to. It can be retrieved by using the bmc-itsm-user-list command. | Optional | +| assignee_pbm_mgr | The full name of the employee the ticket will be assigned to as the problem coordinator. It can be retrieved by using the bmc-itsm-user-list command. | Optional | +| assigned_group_pbm_mgr | The group for the problem coordinator’s support organization, which makes up the third tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. | Optional | +| support_company_pbm_mgr | The company for the problem coordinator’s support organization, which makes up the first tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. | Optional | +| support_organization_pbm_mgr | The organization for the problem coordinator’s support organization, which makes up the second tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. | Optional | +| assigned_support_company | The company for the problem assignee’s support organization. It makes up the first tier of the problem assignee’s support organization data structure. The arguments assigned_support_organization, assigned_group, and assigned_support_company should be provided together. | Optional | +| assigned_support_organization | The organization for the problem assignee’s support organization. It makes up the second tier of the problem assignee’s support organization data structure. The arguments assigned_support_organization, assigned_group, and assigned_support_company should be provided together. | Optional | +| assigned_group | The group for the problem assignee's support organization. It makes up the third tier of the problem assignee's support organization data structure. The arguments assigned_support_organization, assigned_group, and support_company should be provided together. | Optional | +| investigation_justification | The justification for the ticket creation. | Optional | +| temporary_workaround | The problem workaround. | Optional | +| resolution | The ticket resolution. | Optional | +| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee or any other custom field. | Optional | #### Context Output | **Path** | **Type** | **Description** | | --- | --- | --- | -| BmcITSM.ProblemInvestigation.RequestID | String | The problem investigation ticket unique Request ID. | -| BmcITSM.ProblemInvestigation.DisplayID | String | The problem investigation ticket display ID. | -| BmcITSM.ProblemInvestigation.CreateDate | Date | The problem investigation ticket creation date time in UTC. | +| BmcITSM.ProblemInvestigation.RequestID | String | The problem investigation ticket unique Request ID. | +| BmcITSM.ProblemInvestigation.DisplayID | String | The problem investigation ticket display ID. | +| BmcITSM.ProblemInvestigation.CreateDate | Date | The problem investigation ticket creation date time in UTC. | #### Command example ```!bmc-itsm-problem-investigation-create first_name=Allen last_name=Allbrook summary=Test-create-prob urgency="1-Critical" impact="4-Minor/Localized" details="Problem details" status=Assigned target_resolution_date="in 3 days" assigned_support_company="Calbro Services" assigned_support_organization="IT Support" assigned_group="Backoffice Support" investigation_driver="High Impact Incident"``` @@ -897,29 +899,29 @@ Updates The problem investigation ticket type. | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| ticket_request_id | The problem investigation ticket request ID. | Required | -| status | The problem investigation ticket status. Possible values are: Draft, Under Review, Request for Authorization, Assigned, Under Investigation, Pending, Completed, Rejected, Closed, Cancelled. | Optional | -| investigation_driver | The problem investigation ticket driver. Possible values are: High Impact Incident, Re-Occuring Incidents, Non-Routine Incident, Other. | Optional | -| summary | The problem investigation ticket summary. | Optional | -| impact | The problem investigation ticket impact. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Optional | -| urgency | The problem investigation ticket urgency. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Optional | -| target_resolution_date | The problem investigation ticket target resolution date. For example, in 12 hours, in 7 days. | Optional | -| details | The problem investigation ticket detailed description. | Optional | -| company | The company associated with the requester. By default it is determined by the logged in user. | Optional | -| region | The region of the problem investigation location. The arguments region, site_group, and site should be provided together. | Optional | -| site_group | The site group of the problem investigation location. The arguments region, site_group, and site should be provided together. | Optional | -| site | The site of the problem investigation location.The arguments region, site_group, and site should be provided together. | Optional | -| assigned_to | The technical support person the ticket is assigned to. | Optional | -| assigned_group_pbm_mgr | The group for the problem coordinator’s support organization, which makes up the third tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. | Optional | -| support_company_pbm_mgr | The company for the problem coordinator’s support organization, which makes up the first tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. | Optional | -| support_organization_pbm_mgr | The organization for the problem coordinator’s support organization, which makes up the second tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. | Optional | -| assigned_support_company | The company for the problem assignee’s support organization. It makes up the first tier of the problem assignee’s support organization data structure. The arguments assigned_support_organization, assigned_group, and assigned_support_company should be provided together. | Optional | -| assigned_support_organization | The organization for the problem assignee’s support organization. It makes up the second tier of the problem assignee’s support organization data structure. The arguments assigned_support_organization, assigned_group, and assigned_support_company should be provided together. | Optional | -| assigned_group | The group for the problem assignee's support organization. It makes up the third tier of the problem assignee's support organization data structure. The arguments assigned_support_organization, assigned_group, and support_company should be provided together. | Optional | -| investigation_justification | The justification for the ticket creation. | Optional | -| temporary_workaround | The problem workaround. | Optional | -| resolution | The ticket resolution. | Optional | -| status_reason | The reason for changing the status. Required when the status argument is provided. Possible values are: Publish, Reject, Not Applicable. | Optional | +| ticket_request_id | The problem investigation ticket request ID. | Required | +| status | The problem investigation ticket status. Possible values are: Draft, Under Review, Request for Authorization, Assigned, Under Investigation, Pending, Completed, Rejected, Closed, Cancelled. | Optional | +| investigation_driver | The problem investigation ticket driver. Possible values are: High Impact Incident, Re-Occuring Incidents, Non-Routine Incident, Other. | Optional | +| summary | The problem investigation ticket summary. | Optional | +| impact | The problem investigation ticket impact. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Optional | +| urgency | The problem investigation ticket urgency. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Optional | +| target_resolution_date | The problem investigation ticket target resolution date. For example, in 12 hours, in 7 days. | Optional | +| details | The problem investigation ticket detailed description. | Optional | +| company | The company associated with the requester. By default it is determined by the logged in user. | Optional | +| region | The region of the problem investigation location. The arguments region, site_group, and site should be provided together. | Optional | +| site_group | The site group of the problem investigation location. The arguments region, site_group, and site should be provided together. | Optional | +| site | The site of the problem investigation location.The arguments region, site_group, and site should be provided together. | Optional | +| assigned_to | The technical support person the ticket is assigned to. | Optional | +| assigned_group_pbm_mgr | The group for the problem coordinator’s support organization, which makes up the third tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. | Optional | +| support_company_pbm_mgr | The company for the problem coordinator’s support organization, which makes up the first tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. | Optional | +| support_organization_pbm_mgr | The organization for the problem coordinator’s support organization, which makes up the second tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. | Optional | +| assigned_support_company | The company for the problem assignee’s support organization. It makes up the first tier of the problem assignee’s support organization data structure. The arguments assigned_support_organization, assigned_group, and assigned_support_company should be provided together. | Optional | +| assigned_support_organization | The organization for the problem assignee’s support organization. It makes up the second tier of the problem assignee’s support organization data structure. The arguments assigned_support_organization, assigned_group, and assigned_support_company should be provided together. | Optional | +| assigned_group | The group for the problem assignee's support organization. It makes up the third tier of the problem assignee's support organization data structure. The arguments assigned_support_organization, assigned_group, and support_company should be provided together. | Optional | +| investigation_justification | The justification for the ticket creation. | Optional | +| temporary_workaround | The problem workaround. | Optional | +| resolution | The ticket resolution. | Optional | +| status_reason | The reason for changing the status. Required when the status argument is provided. Possible values are: Publish, Reject, Not Applicable. | Optional | #### Context Output @@ -933,7 +935,7 @@ There is no context output for this command. ### bmc-itsm-known-error-create *** -Create known error ticket. +Create known error ticket. #### Base Command @@ -943,35 +945,35 @@ Create known error ticket. | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| status | The known error ticket status. Possible values are: Assigned, Scheduled For Correction, Assigned To Vendor, No Action Planned, Corrected, Closed, Cancelled. | Required | -| summary | The known error ticket summary. | Required | -| details | The known error ticket Detailed description. | Required | -| impact | The known error ticket impact. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Required | -| urgency | The known error ticket urgency. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Required | -| view_access | Whether if the ticket is for internal view or public view. Possible values are: Public, Internal. | Required | -| company | Company associated with the Requester. | Required | -| target_resolution_date | Known error resolution date. Future resolution date. For example, in 12 hours, in 7 days. | Required | -| resolution | Ticket resolution. | Optional | -| assigned_group_pbm_mgr | It makes up the third tier of the Problem Coordinator’s Support Organization data structure. | Optional | -| support_company_pbm_mgr | the Company for the Problem Coordinator’s Support Organization. It makes up the first tier of it. | Optional | -| support_organization_pbm_mgr | It makes up the second tier of the Problem Coordinator’s Support Organization data structure. | Optional | -| assigned_support_company | The company for the problem assignee’s support organization. It makes up the first tier of the problem assignee’s support organization data structure. | Optional | -| assigned_support_organization | The organization for the problem assignee’s support organization. It makes up the second tier of the problem assignee’s support organization data structure. | Optional | -| assigned_group | The group for the problem assignee’s support organization. It makes up the third tier of the problem assignee’s support organization data structure. | Optional | -| investigation_justification | The justification for the ticket creation. | Optional | -| assignee | The full name of the staff member to whom the ticket will be assigned to. It can be retrieved by using the 'bmc-itsm-user-list' command. | Optional | -| assignee_pbm_mgr | The full name of the staff member to whom the ticket will be assign to as the problem coordinator. It can be retrieved by using the 'bmc-itsm-user-list' command. | Optional | -| temporary_workaround | Error workaround. | Optional | -| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee or any other custom field. | Optional | +| status | The known error ticket status. Possible values are: Assigned, Scheduled For Correction, Assigned To Vendor, No Action Planned, Corrected, Closed, Cancelled. | Required | +| summary | The known error ticket summary. | Required | +| details | The known error ticket Detailed description. | Required | +| impact | The known error ticket impact. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Required | +| urgency | The known error ticket urgency. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Required | +| view_access | Whether if the ticket is for internal view or public view. Possible values are: Public, Internal. | Required | +| company | Company associated with the Requester. | Required | +| target_resolution_date | Known error resolution date. Future resolution date. For example, in 12 hours, in 7 days. | Required | +| resolution | Ticket resolution. | Optional | +| assigned_group_pbm_mgr | It makes up the third tier of the Problem Coordinator’s Support Organization data structure. | Optional | +| support_company_pbm_mgr | the Company for the Problem Coordinator’s Support Organization. It makes up the first tier of it. | Optional | +| support_organization_pbm_mgr | It makes up the second tier of the Problem Coordinator’s Support Organization data structure. | Optional | +| assigned_support_company | The company for the problem assignee’s support organization. It makes up the first tier of the problem assignee’s support organization data structure. | Optional | +| assigned_support_organization | The organization for the problem assignee’s support organization. It makes up the second tier of the problem assignee’s support organization data structure. | Optional | +| assigned_group | The group for the problem assignee’s support organization. It makes up the third tier of the problem assignee’s support organization data structure. | Optional | +| investigation_justification | The justification for the ticket creation. | Optional | +| assignee | The full name of the staff member to whom the ticket will be assigned to. It can be retrieved by using the 'bmc-itsm-user-list' command. | Optional | +| assignee_pbm_mgr | The full name of the staff member to whom the ticket will be assign to as the problem coordinator. It can be retrieved by using the 'bmc-itsm-user-list' command. | Optional | +| temporary_workaround | Error workaround. | Optional | +| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee or any other custom field. | Optional | #### Context Output | **Path** | **Type** | **Description** | | --- | --- | --- | -| BmcITSM.KnownError.RequestID | String | Known Error unique Request ID. | -| BmcITSM.KnownError.DisplayID | String | KnownError Display ID. | -| BmcITSM.KnownError.CreateDate | Date | KnownError Create time in UTC. | +| BmcITSM.KnownError.RequestID | String | Known Error unique Request ID. | +| BmcITSM.KnownError.DisplayID | String | KnownError Display ID. | +| BmcITSM.KnownError.CreateDate | Date | KnownError Create time in UTC. | #### Command example ```!bmc-itsm-known-error-create summary="New Error API" details="New Error API Details" target_resolution_date=" in 5 days" company="Calbro Services" resolution="error resolution" investigation_justification=look assignee="Bob Baxter" assigned_support_company="Calbro Services" assigned_support_organization="IT Support" assigned_group="Backoffice Support" impact="2-Significant/Large" status=Assigned urgency="2-High" view_access=Internal ``` @@ -998,7 +1000,7 @@ Create known error ticket. ### bmc-itsm-known-error-update *** -Update Known Error ticket type. +Update Known Error ticket type. #### Base Command @@ -1008,27 +1010,27 @@ Update Known Error ticket type. | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| ticket_request_id | The known error ticket request ID. | Required | -| status | The known error ticket status. Possible values are: Assigned, Scheduled For Correction, Assigned To Vendor, No Action Planned, Corrected, Closed, Cancelled. | Optional | -| summary | The known error ticket summary. | Optional | -| details | The known error ticket detailed description. | Optional | -| impact | The known error ticket impact. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Optional | -| urgency | The known error ticket urgency. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Optional | -| view_access | The known error ticket internal access. Possible values are: Public, Internal. | Optional | -| company | Company associated with the Requester. By default is determined by the logged in user. | Optional | -| target_resolution_date | Known error resolution date. Future resolution date. For example, in 12 hours, in 7 days. | Optional | -| resolution | Ticket resolution. | Optional | -| assigned_group_pbm_mgr | It makes up the third tier of the Problem Coordinator’s Support Organization data structure. | Optional | -| support_company_pbm_mgr | the Company for the Problem Coordinator’s Support Organization. It makes up the first tier of it. | Optional | -| support_organization_pbm_mgr | It makes up the second tier of the Problem Coordinator’s Support Organization data structure. | Optional | -| assigned_support_company | The company for the problem assignee’s support organization. It makes up the first tier of the problem assignee’s support organization data structure. | Optional | -| assigned_support_organization | The organization for the problem assignee’s support organization. It makes up the second tier of the problem assignee’s support organization data structure. | Optional | -| assigned_group | The group for the problem assignee’s support organization. It makes up the third tier of the problem assignee’s support organization data structure. | Optional | -| temporary_workaround | Error workaround. | Optional | -| status_reason | The reason for changing the status. Required when the status is provided. Possible values are: Duplicate, No Longer Applicable, Pending PIR, Funding Not Available, Pending Infrastructure Change, Pending Third Party Vendor. | Optional | -| assignee | The full name of the employee the ticket will be assigned to. It can be retrieved by using the bmc-itsm-user-list command. | Optional | -| assignee_pbm_mgr | The full name of the employee the ticket will be assign to as the problem coordinator. It can be retrieved by using the bmc-itsm-user-list command. | Optional | -| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee or any other custom field. | Optional | +| ticket_request_id | The known error ticket request ID. | Required | +| status | The known error ticket status. Possible values are: Assigned, Scheduled For Correction, Assigned To Vendor, No Action Planned, Corrected, Closed, Cancelled. | Optional | +| summary | The known error ticket summary. | Optional | +| details | The known error ticket detailed description. | Optional | +| impact | The known error ticket impact. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Optional | +| urgency | The known error ticket urgency. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Optional | +| view_access | The known error ticket internal access. Possible values are: Public, Internal. | Optional | +| company | Company associated with the Requester. By default is determined by the logged in user. | Optional | +| target_resolution_date | Known error resolution date. Future resolution date. For example, in 12 hours, in 7 days. | Optional | +| resolution | Ticket resolution. | Optional | +| assigned_group_pbm_mgr | It makes up the third tier of the Problem Coordinator’s Support Organization data structure. | Optional | +| support_company_pbm_mgr | the Company for the Problem Coordinator’s Support Organization. It makes up the first tier of it. | Optional | +| support_organization_pbm_mgr | It makes up the second tier of the Problem Coordinator’s Support Organization data structure. | Optional | +| assigned_support_company | The company for the problem assignee’s support organization. It makes up the first tier of the problem assignee’s support organization data structure. | Optional | +| assigned_support_organization | The organization for the problem assignee’s support organization. It makes up the second tier of the problem assignee’s support organization data structure. | Optional | +| assigned_group | The group for the problem assignee’s support organization. It makes up the third tier of the problem assignee’s support organization data structure. | Optional | +| temporary_workaround | Error workaround. | Optional | +| status_reason | The reason for changing the status. Required when the status is provided. Possible values are: Duplicate, No Longer Applicable, Pending PIR, Funding Not Available, Pending Infrastructure Change, Pending Third Party Vendor. | Optional | +| assignee | The full name of the employee the ticket will be assigned to. It can be retrieved by using the bmc-itsm-user-list command. | Optional | +| assignee_pbm_mgr | The full name of the employee the ticket will be assign to as the problem coordinator. It can be retrieved by using the bmc-itsm-user-list command. | Optional | +| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee or any other custom field. | Optional | #### Context Output @@ -1052,21 +1054,21 @@ Lists all change requests ticket templates. Useful for creating change request t | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| template_ids | A comma-separated list of change request template IDs. Used as a filtering argument. | Optional | -| query | The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). | Optional | -| limit | The maximum number of records to retrieve. Default is 50. | Optional | -| page_size | The maximum number of records to retrieve per page. | Optional | -| page | The page number of the results to retrieve. | Optional | -| description | The change request ticket description. Used as a filtering argument. | Optional | +| template_ids | A comma-separated list of change request template IDs. Used as a filtering argument. | Optional | +| query | The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). | Optional | +| limit | The maximum number of records to retrieve. Default is 50. | Optional | +| page_size | The maximum number of records to retrieve per page. | Optional | +| page | The page number of the results to retrieve. | Optional | +| description | The change request ticket description. Used as a filtering argument. | Optional | #### Context Output | **Path** | **Type** | **Description** | | --- | --- | --- | -| BmcITSM.ChangeRequestTemplate.Id | String | The change request ticket template ID. | -| BmcITSM.ChangeRequestTemplate.Description | String | The change request ticket template description. | -| BmcITSM.ChangeRequestTemplate.InstanceID | String | The change request ticket template instance ID. Useful for creating change request tickets. | +| BmcITSM.ChangeRequestTemplate.Id | String | The change request ticket template ID. | +| BmcITSM.ChangeRequestTemplate.Description | String | The change request ticket template description. | +| BmcITSM.ChangeRequestTemplate.InstanceID | String | The change request ticket template instance ID. Useful for creating change request tickets. | #### Command example ```!bmc-itsm-change-request-template-list limit=2``` @@ -1112,21 +1114,21 @@ Lists all incident requests ticket templates. Useful for create incident tickets | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| query | The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). | Optional | -| limit | The maximum number of records to retrieve. Default is 50. | Optional | -| page_size | The maximum number of records to retrieve per page. | Optional | -| page | The page number of the results to retrieve. | Optional | -| description | The incident ticket template description. Used as a filtering argument. | Optional | -| template_ids | A comma-separated list of incident template IDs. Used as a filtering argument. | Optional | +| query | The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). | Optional | +| limit | The maximum number of records to retrieve. Default is 50. | Optional | +| page_size | The maximum number of records to retrieve per page. | Optional | +| page | The page number of the results to retrieve. | Optional | +| description | The incident ticket template description. Used as a filtering argument. | Optional | +| template_ids | A comma-separated list of incident template IDs. Used as a filtering argument. | Optional | #### Context Output | **Path** | **Type** | **Description** | | --- | --- | --- | -| BmcITSM.IncidentTemplate.Id | String | The incident ticket template ID. | -| BmcITSM.IncidentTemplate.Description | String | The incident ticket template description. | -| BmcITSM.IncidentTemplate.InstanceID | String | The incident ticket template ID. Useful for creating change request tickets. | +| BmcITSM.IncidentTemplate.Id | String | The incident ticket template ID. | +| BmcITSM.IncidentTemplate.Description | String | The incident ticket template description. | +| BmcITSM.IncidentTemplate.InstanceID | String | The incident ticket template ID. Useful for creating change request tickets. | #### Command example ```!bmc-itsm-incident-template-list limit=2``` @@ -1172,21 +1174,21 @@ Lists all task ticket templates. Useful for creating task tickets. The records a | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| query | The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). | Optional | -| limit | The maximum number of records to retrieve. Default is 50. | Optional | -| page_size | The maximum number of records to retrieve per page. | Optional | -| page | The page number of the results to retrieve. | Optional | -| template_ids | A comma-separated list of task template IDs. Used as a filtering argument. | Optional | -| task_name | The task ticket template name. Used as a filtering argument. | Optional | +| query | The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). | Optional | +| limit | The maximum number of records to retrieve. Default is 50. | Optional | +| page_size | The maximum number of records to retrieve per page. | Optional | +| page | The page number of the results to retrieve. | Optional | +| template_ids | A comma-separated list of task template IDs. Used as a filtering argument. | Optional | +| task_name | The task ticket template name. Used as a filtering argument. | Optional | #### Context Output | **Path** | **Type** | **Description** | | --- | --- | --- | -| BmcITSM.TaskTemplate.Id | String | The task ticket template ID. | -| BmcITSM.TaskTemplate.TaskName | String | The task template name. | -| BmcITSM.TaskTemplate.InstanceID | String | The task ticket template ID. Useful for creating change request tickets. | +| BmcITSM.TaskTemplate.Id | String | The task ticket template ID. | +| BmcITSM.TaskTemplate.TaskName | String | The task template name. | +| BmcITSM.TaskTemplate.InstanceID | String | The task ticket template ID. Useful for creating change request tickets. | #### Command example ```!bmc-itsm-task-template-list limit=2``` @@ -1249,8 +1251,8 @@ Gets remote data from a remote incident. This method does not update the current | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| id | The ticket ID. | Required | -| lastUpdate | Retrieves entries that were created after lastUpdate. | Required | +| id | The ticket ID. | Required | +| lastUpdate | Retrieves entries that were created after lastUpdate. | Required | #### Context Output @@ -1269,7 +1271,7 @@ Gets the list of incidents that were modified since the last update time. Note t | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| lastUpdate | A date string in local time representing the last time the incident was updated. The incident is only returned if it was modified after the last update time. | Optional | +| lastUpdate | A date string in local time representing the last time the incident was updated. The incident is only returned if it was modified after the last update time. | Optional | #### Context Output @@ -1289,21 +1291,21 @@ Lists all support groups. Useful for getting possible (Company, Support Organiza | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| limit | The maximum number of records to retrieve. Default is 50. | Optional | -| page_size | The maximum number of records to retrieve per page. | Optional | -| page | The page number of the results to retrieve. | Optional | -| company | Company name. Used as a filtering argument. | Optional | -| support_organization | Support organization name. Used as a filtering argument. | Optional | -| support_group | Support group name. Used as a filtering argument. | Optional | +| limit | The maximum number of records to retrieve. Default is 50. | Optional | +| page_size | The maximum number of records to retrieve per page. | Optional | +| page | The page number of the results to retrieve. | Optional | +| company | Company name. Used as a filtering argument. | Optional | +| support_organization | Support organization name. Used as a filtering argument. | Optional | +| support_group | Support group name. Used as a filtering argument. | Optional | #### Context Output | **Path** | **Type** | **Description** | | --- | --- | --- | -| BmcITSM.SupportGroup.SupportGroupID | String | The support group ID. | -| BmcITSM.SupportGroup.Company | String | The support company. | -| BmcITSM.SupportGroup.SupportOrganization | String | The support organization. | -| BmcITSM.SupportGroup.SupportGroupName | String | The support group. | +| BmcITSM.SupportGroup.SupportGroupID | String | The support group ID. | +| BmcITSM.SupportGroup.Company | String | The support company. | +| BmcITSM.SupportGroup.SupportOrganization | String | The support organization. | +| BmcITSM.SupportGroup.SupportGroupName | String | The support group. | #### Command example ```!bmc-itsm-support-group-list limit=2``` @@ -1352,20 +1354,20 @@ Lists all work order templates. Useful for creating work orders. The records are | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| query | The query to search by. For example, query="Company like \"BMCOpsMonitoring\"". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). | Optional | -| limit | The maximum number of records to retrieve. Default is 50. | Optional | -| page_size | The maximum number of records to retrieve per page. | Optional | -| page | The page number of the results to retrieve. | Optional | -| template_ids | A comma-separated list of work order template GUIDs. Used as a filtering argument. | Optional | -| template_name | The work order template name. Used as a filtering argument. | Optional | +| query | The query to search by. For example, query="Company like \"BMCOpsMonitoring\"". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). | Optional | +| limit | The maximum number of records to retrieve. Default is 50. | Optional | +| page_size | The maximum number of records to retrieve per page. | Optional | +| page | The page number of the results to retrieve. | Optional | +| template_ids | A comma-separated list of work order template GUIDs. Used as a filtering argument. | Optional | +| template_name | The work order template name. Used as a filtering argument. | Optional | #### Context Output | **Path** | **Type** | **Description** | | --- | --- | --- | -| BmcITSM.WorkOrderTemplate.Id | String | The work order template ID. | -| BmcITSM.WorkOrderTemplate.Name | String | The work order template name. | -| BmcITSM.WorkOrderTemplate.GUID | String | The work order template GUID. | +| BmcITSM.WorkOrderTemplate.Id | String | The work order template ID. | +| BmcITSM.WorkOrderTemplate.Name | String | The work order template name. | +| BmcITSM.WorkOrderTemplate.GUID | String | The work order template GUID. | #### Command example ```!bmc-itsm-work-order-template-list limit=2``` @@ -1412,30 +1414,30 @@ Creates a new work order ticket. | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| template_guid | The instance GUID of the template to use. The GUID can be retrieved by executing the bmc-itsm-work-order-template-list command. | Optional | -| first_name | Requester first name. | Optional | -| last_name | Requester last name. | Optional | -| customer_first_name | Customer first name. | Required | -| customer_last_name | Customer last name. | Required | -| customer_company | Customer company. | Required | -| customer_person_id | Customer person ID. Use it when customer first and last name pair is not unique. | Optional | -| summary | The work order summary. | Required | -| detailed_description | The work order ticket detailed description. | Required | -| status | The work order status. Possible values are: Assigned, Pending, Waiting Approval, Planning, In Progress, Completed, Rejected, Cancelled, Closed. | Required | -| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Example: additional_fields="Support Company=Calbro Services;Support Organization=IT Support;Support Group Name=Service Desk;Request Assignee=Scully Agent". | Optional | -| priority | The work order ticket priority. Possible values are: Critical, High, Medium, Low. | Required | -| work_order_type | The work order ticket type. Possible values are: General, Project. | Optional | -| location_company | The company associated with the task process. | Required | -| scedulded_start_date | The work order ticket scheduled future start date. For example, in 12 hours, in 7 days. | Optional | -| scedulded_end_date | The work order ticket scheduled future end date. For example, in 12 hours, in 7 days. | Optional | +| template_guid | The instance GUID of the template to use. The GUID can be retrieved by executing the bmc-itsm-work-order-template-list command. | Optional | +| first_name | Requester first name. | Optional | +| last_name | Requester last name. | Optional | +| customer_first_name | Customer first name. | Required | +| customer_last_name | Customer last name. | Required | +| customer_company | Customer company. | Required | +| customer_person_id | Customer person ID. Use it when customer first and last name pair is not unique. | Optional | +| summary | The work order summary. | Required | +| detailed_description | The work order ticket detailed description. | Required | +| status | The work order status. Possible values are: Assigned, Pending, Waiting Approval, Planning, In Progress, Completed, Rejected, Cancelled, Closed. | Required | +| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Example: additional_fields="Support Company=Calbro Services;Support Organization=IT Support;Support Group Name=Service Desk;Request Assignee=Scully Agent". | Optional | +| priority | The work order ticket priority. Possible values are: Critical, High, Medium, Low. | Required | +| work_order_type | The work order ticket type. Possible values are: General, Project. | Optional | +| location_company | The company associated with the task process. | Required | +| scedulded_start_date | The work order ticket scheduled future start date. For example, in 12 hours, in 7 days. | Optional | +| scedulded_end_date | The work order ticket scheduled future end date. For example, in 12 hours, in 7 days. | Optional | #### Context Output | **Path** | **Type** | **Description** | | --- | --- | --- | -| BmcITSM.WorkOrder.RequestID | String | The work order ticket unique Request ID. | -| BmcITSM.WorkOrder.DisplayID | String | The work order ticket unique Display ID. | -| BmcITSM.WorkOrder.CreateDate | Date | The work order ticket creation date time in UTC. | +| BmcITSM.WorkOrder.RequestID | String | The work order ticket unique Request ID. | +| BmcITSM.WorkOrder.DisplayID | String | The work order ticket unique Display ID. | +| BmcITSM.WorkOrder.CreateDate | Date | The work order ticket creation date time in UTC. | #### Command example ```!bmc-itsm-work-order-create customer_company="Calbro Services" customer_first_name="Scully" customer_last_name="Agent" detailed_description="Easy peasy work order" location_company="Calbro Services" priority=Low status=Pending summary="Easy peasy work order. No, really." customer_person_id=PPL000000000607 additional_fields="Support Company=Calbro Services;Support Organization=IT Support;Support Group Name=Service Desk;Request Assignee=Scully Agent"``` @@ -1473,21 +1475,21 @@ Updates the work order ticket. | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| request_id | The ID of the work order ticket to update. | Required | -| summary | The work order ticket summary. | Optional | -| detailed_description | The work order ticket detailed description. | Optional | -| priority | The work order ticket priority. Possible values are: Critical, High, Medium, Low. | Optional | -| status | The work order ticket status. Possible values are: Assigned, Pending, Waiting Approval, Planning, In Progress, Completed, Rejected, Cancelled, Closed. | Optional | -| status_reason | The reason for changing the ticket status. Possible values are: Initial Status, Awaiting Request Assignee, Client Hold, Client Additional Information Requested, Client Action Required, Support Contact Hold, Local Site Action Required, Purchase Order Approval, Supplier Delivery, Third Party Vendor Action Required, Infrastructure Change, Work not started, Successful, Successful with Issues, Cancelled by Requester, Cancelled by Support, Customer Close, System Close, System Close with Issues. | Optional | -| company | The company associated with the requester. By default it is determined by the logged in user. | Optional | -| location_company | The company associated with the work order process. | Optional | -| assignee | The full name of the employee the work order is assigned to. It can be retrieved by using the bmc-itsm-user-list command. | Optional | -| support_organization | The organization for the problem assignee's support organization. It makes up the second tier of the problem assignee's support organization data structure. The arguments support_organization, support_group should be provided together. It can be retrieved by using the bmc-itsm-support-group-list command. | Optional | -| support_group | The group for the problem assignee's support group. It makes up the third tier of the problem assignee's support organization data structure. The arguments support_organization, support_group should be provided together. It can be retrieved by using the bmc-itsm-support-group-list command. | Optional | -| work_order_type | The work order ticket type. Possible values are: General, Project. | Optional | -| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Example: additional_fields="Support Company=Calbro Services;Support Organization=IT Support;Support Group Name=Service Desk;Request Assignee=Scully Agent". | Optional | -| scedulded_start_date | The work order ticket scheduled future start date. For example, in 12 hours, in 7 days. | Optional | -| scedulded_end_date | The work order ticket scheduled future end date. For example, in 12 hours, in 7 days. | Optional | +| request_id | The ID of the work order ticket to update. | Required | +| summary | The work order ticket summary. | Optional | +| detailed_description | The work order ticket detailed description. | Optional | +| priority | The work order ticket priority. Possible values are: Critical, High, Medium, Low. | Optional | +| status | The work order ticket status. Possible values are: Assigned, Pending, Waiting Approval, Planning, In Progress, Completed, Rejected, Cancelled, Closed. | Optional | +| status_reason | The reason for changing the ticket status. Possible values are: Initial Status, Awaiting Request Assignee, Client Hold, Client Additional Information Requested, Client Action Required, Support Contact Hold, Local Site Action Required, Purchase Order Approval, Supplier Delivery, Third Party Vendor Action Required, Infrastructure Change, Work not started, Successful, Successful with Issues, Cancelled by Requester, Cancelled by Support, Customer Close, System Close, System Close with Issues. | Optional | +| company | The company associated with the requester. By default it is determined by the logged in user. | Optional | +| location_company | The company associated with the work order process. | Optional | +| assignee | The full name of the employee the work order is assigned to. It can be retrieved by using the bmc-itsm-user-list command. | Optional | +| support_organization | The organization for the problem assignee's support organization. It makes up the second tier of the problem assignee's support organization data structure. The arguments support_organization, support_group should be provided together. It can be retrieved by using the bmc-itsm-support-group-list command. | Optional | +| support_group | The group for the problem assignee's support group. It makes up the third tier of the problem assignee's support organization data structure. The arguments support_organization, support_group should be provided together. It can be retrieved by using the bmc-itsm-support-group-list command. | Optional | +| work_order_type | The work order ticket type. Possible values are: General, Project. | Optional | +| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Example: additional_fields="Support Company=Calbro Services;Support Organization=IT Support;Support Group Name=Service Desk;Request Assignee=Scully Agent". | Optional | +| scedulded_start_date | The work order ticket scheduled future start date. For example, in 12 hours, in 7 days. | Optional | +| scedulded_end_date | The work order ticket scheduled future end date. For example, in 12 hours, in 7 days. | Optional | #### Context Output @@ -1518,4 +1520,3 @@ To set up the mirroring: Newly fetched incidents will be mirrored in the chosen direction. However, this selection does not affect existing incidents. **Important Note:** To ensure the mirroring works as expected, mappers are required, both for incoming and outgoing, to map the expected fields in Cortex XSOAR and BMC Helix ITSM. - diff --git a/Packs/BmcITSM/ReleaseNotes/1_0_25.md b/Packs/BmcITSM/ReleaseNotes/1_0_25.md new file mode 100644 index 000000000000..e28c0647db79 --- /dev/null +++ b/Packs/BmcITSM/ReleaseNotes/1_0_25.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### BMC Helix ITSM + +- Added the argument *customer_company* to the *bmc-itsm-task-create* and *bmc-itsm-task-update* commands. diff --git a/Packs/BmcITSM/pack_metadata.json b/Packs/BmcITSM/pack_metadata.json index d4c7bae1259a..7441f51ff55d 100644 --- a/Packs/BmcITSM/pack_metadata.json +++ b/Packs/BmcITSM/pack_metadata.json @@ -2,7 +2,7 @@ "name": "BMC Helix ITSM", "description": "BMC Helix ITSM allows customers to manage service request, incident, change request, task, problem investigation, known error and work order tickets.", "support": "xsoar", - "currentVersion": "1.0.24", + "currentVersion": "1.0.25", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 22ef48df2fc149d31647ca3e776e8adce8524923 Mon Sep 17 00:00:00 2001 From: Jacob Levy <129657918+jlevypaloalto@users.noreply.github.com> Date: Sun, 11 Aug 2024 15:47:08 +0300 Subject: [PATCH 10/14] [FileToBase64List] Remove "runeonce: true" (#35481) * init * RN * minor changes * Bump pack from version CommonScripts to 1.15.43. * Bump pack from version CommonScripts to 1.15.44. * Bump pack from version CommonScripts to 1.15.45. * Bump pack from version CommonScripts to 1.15.46. * Bump pack from version CommonScripts to 1.15.47. * Bump pack from version CommonScripts to 1.15.48. * RN * Bump pack from version CommonScripts to 1.15.49. * RN --------- Co-authored-by: Content Bot --- Packs/CommonScripts/ReleaseNotes/1_15_49.md | 7 ++++ .../FileToBase64List/FileToBase64List.py | 32 ++++++++++--------- .../FileToBase64List/FileToBase64List.yml | 3 +- .../file_to_base64_list_test.py | 10 +++--- Packs/CommonScripts/pack_metadata.json | 2 +- 5 files changed, 31 insertions(+), 23 deletions(-) create mode 100644 Packs/CommonScripts/ReleaseNotes/1_15_49.md diff --git a/Packs/CommonScripts/ReleaseNotes/1_15_49.md b/Packs/CommonScripts/ReleaseNotes/1_15_49.md new file mode 100644 index 000000000000..3fff51156644 --- /dev/null +++ b/Packs/CommonScripts/ReleaseNotes/1_15_49.md @@ -0,0 +1,7 @@ + +#### Scripts + +##### FileToBase64List + +- Improved implementation to prevent the script from running in a new docker container for each call. +- Updated the Docker image to: *demisto/python3:3.11.9.107902*. diff --git a/Packs/CommonScripts/Scripts/FileToBase64List/FileToBase64List.py b/Packs/CommonScripts/Scripts/FileToBase64List/FileToBase64List.py index 653326549b26..0c9d9e1884f2 100644 --- a/Packs/CommonScripts/Scripts/FileToBase64List/FileToBase64List.py +++ b/Packs/CommonScripts/Scripts/FileToBase64List/FileToBase64List.py @@ -5,39 +5,41 @@ import zlib -def get_file_data(file_path, zip=False): +def get_file_data(file_path: str, is_zip: bool = False): with open(file_path, 'rb') as f: data = f.read() - if zip: - data = zlib.compress(data) - + if is_zip: + data = zlib.compress(data) return base64.b64encode(data).decode('utf-8') def main(): - LIST_NAME = demisto.args()['listName'] - TO_ZIP = (demisto.args()['zipFile'] == 'true') - + list_name = demisto.args()['listName'] + is_zip = (demisto.args()['zipFile'] == 'true') entry_id = demisto.args()['entryId'] + res = demisto.getFilePath(entry_id) if not res: - return_error("Entry {} not found".format(entry_id)) + return_error(f"Entry {entry_id} not found") file_path = res['path'] - file_base64 = get_file_data(file_path, TO_ZIP) + file_base64 = get_file_data(file_path, is_zip) - res = demisto.executeCommand("createList", {"listName": LIST_NAME, "listData": file_base64}) + res = demisto.executeCommand("createList", {"listName": list_name, "listData": file_base64}) if isError(res): return res return { 'Contents': file_base64, 'ContentsFormat': formats['text'], - 'HumanReadable': tableToMarkdown('Success store file in list', { - 'File Entry ID': entry_id, - 'List Name': LIST_NAME, - 'Size': len(file_base64) - }), + 'HumanReadable': tableToMarkdown( + 'File successfully stored in list', + { + 'File Entry ID': entry_id, + 'List Name': list_name, + 'Size': len(file_base64) + } + ), 'HumanReadableFormat': formats['markdown'], } diff --git a/Packs/CommonScripts/Scripts/FileToBase64List/FileToBase64List.yml b/Packs/CommonScripts/Scripts/FileToBase64List/FileToBase64List.yml index 7ac263406de6..6b0ccc45ce4d 100644 --- a/Packs/CommonScripts/Scripts/FileToBase64List/FileToBase64List.yml +++ b/Packs/CommonScripts/Scripts/FileToBase64List/FileToBase64List.yml @@ -27,8 +27,7 @@ timeout: '0' type: python subtype: python3 runas: DBotWeakRole -runonce: true tests: - No Test fromversion: 5.0.0 -dockerimage: demisto/python3:3.10.13.83255 +dockerimage: demisto/python3:3.11.9.107902 diff --git a/Packs/CommonScripts/Scripts/FileToBase64List/file_to_base64_list_test.py b/Packs/CommonScripts/Scripts/FileToBase64List/file_to_base64_list_test.py index 425392bedf8d..3dbbabc932b2 100644 --- a/Packs/CommonScripts/Scripts/FileToBase64List/file_to_base64_list_test.py +++ b/Packs/CommonScripts/Scripts/FileToBase64List/file_to_base64_list_test.py @@ -9,16 +9,15 @@ TEST_FILE_PATH = os.path.join('test_data', 'file.txt') -def executeCommand(name, args=None): - if name == 'createList': +def executeCommand(command, args=None): + if command == 'createList': return [ { 'Type': entryTypes['note'], 'Contents': 'List created successfully' } ] - else: - raise ValueError('Unimplemented command called: {}'.format(name)) + raise ValueError(f'Unimplemented command called: {command}') def test_file_to_base64_list(mocker): @@ -32,7 +31,8 @@ def test_file_to_base64_list(mocker): mocker.patch.object(demisto, 'executeCommand', side_effect=executeCommand) mocker.patch.object(demisto, 'results') result_entry = main() - assert 'Success' in result_entry['HumanReadable'] and 'Size' in result_entry['HumanReadable'] + assert result_entry['HumanReadable'] == ( + '### File successfully stored in list\n|File Entry ID|List Name|Size|\n|---|---|---|\n| 1 | test | 28 |\n') assert len(result_entry['Contents']) > 0 diff --git a/Packs/CommonScripts/pack_metadata.json b/Packs/CommonScripts/pack_metadata.json index 11adae30f2f5..1dca0f781de1 100644 --- a/Packs/CommonScripts/pack_metadata.json +++ b/Packs/CommonScripts/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Common Scripts", "description": "Frequently used scripts pack.", "support": "xsoar", - "currentVersion": "1.15.48", + "currentVersion": "1.15.49", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From e3b0c8005a3b93262e0b9e78823f705133a984b5 Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Sun, 11 Aug 2024 16:17:28 +0300 Subject: [PATCH 11/14] Add new script to convert json to html table (#35758) * Add new script to convert json to html table (#35633) * Add new script to convert json to html table * Update docker image * Remove start import for json2html * Remove start import for json2html in test file * handle json2html import --------- Co-authored-by: Nik Stuckenbrock <35262568+nikstuckenbrock@users.noreply.github.com> Co-authored-by: samuelFain <65926551+samuelFain@users.noreply.github.com> --- .../CommunityCommonScripts/CONTRIBUTORS.json | 2 +- .../ReleaseNotes/1_2_6.md | 6 ++ .../Scripts/Json2HtmlTable/Json2HtmlTable.py | 85 +++++++++++++++++++ .../Scripts/Json2HtmlTable/Json2HtmlTable.yml | 18 ++++ .../Json2HtmlTable/Json2HtmlTable_test.py | 34 ++++++++ .../Scripts/Json2HtmlTable/README.md | 24 ++++++ .../CommunityCommonScripts/pack_metadata.json | 2 +- 7 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 Packs/CommunityCommonScripts/ReleaseNotes/1_2_6.md create mode 100644 Packs/CommunityCommonScripts/Scripts/Json2HtmlTable/Json2HtmlTable.py create mode 100644 Packs/CommunityCommonScripts/Scripts/Json2HtmlTable/Json2HtmlTable.yml create mode 100644 Packs/CommunityCommonScripts/Scripts/Json2HtmlTable/Json2HtmlTable_test.py create mode 100644 Packs/CommunityCommonScripts/Scripts/Json2HtmlTable/README.md diff --git a/Packs/CommunityCommonScripts/CONTRIBUTORS.json b/Packs/CommunityCommonScripts/CONTRIBUTORS.json index 72f841543a29..595a9dc775b4 100644 --- a/Packs/CommunityCommonScripts/CONTRIBUTORS.json +++ b/Packs/CommunityCommonScripts/CONTRIBUTORS.json @@ -1 +1 @@ -["Mandar Naik"] +["Mandar Naik", "nikstuckenbrock"] diff --git a/Packs/CommunityCommonScripts/ReleaseNotes/1_2_6.md b/Packs/CommunityCommonScripts/ReleaseNotes/1_2_6.md new file mode 100644 index 000000000000..1738e7ef8147 --- /dev/null +++ b/Packs/CommunityCommonScripts/ReleaseNotes/1_2_6.md @@ -0,0 +1,6 @@ + +#### Scripts + +##### New: Json2HtmlTable + +- New: Converts JSON objects to HTML tables. diff --git a/Packs/CommunityCommonScripts/Scripts/Json2HtmlTable/Json2HtmlTable.py b/Packs/CommunityCommonScripts/Scripts/Json2HtmlTable/Json2HtmlTable.py new file mode 100644 index 000000000000..5e730893e189 --- /dev/null +++ b/Packs/CommunityCommonScripts/Scripts/Json2HtmlTable/Json2HtmlTable.py @@ -0,0 +1,85 @@ +import demistomock as demisto # noqa: F401 +from CommonServerPython import * # noqa: F401 +"""Converts a JSON object into a HTML table""" + +from CommonServerUserPython import * +import json +from json2html import json2html +from typing import Any + + +''' STANDALONE FUNCTION ''' + + +def get_json_from_string(value: Any) -> dict | str | None: + """Returns the JSON content from a string if possible + + Args: + value (Any): The input to be parsed + + Returns: + dict | str: The parsed JSON content if possible + """ + + json_string: str | None = None + + if isinstance(value, str): + json_string = value + + if isinstance(value, list) and len(value) == 1 and isinstance(value[0], str): + json_string = value[0] + + try: + return json.loads(json_string) if json_string else None + except json.JSONDecodeError: + return json_string + + +def json_to_html(value: str) -> str: + """Converts the given JSON string into a HTML table + + Args: + value (str): The JSON object string to convert + + Returns: + str: The HTML table string + """ + + json_value: dict | str | None = get_json_from_string(value=value) + + return json2html.convert(json=json_value) + + +''' COMMAND FUNCTION ''' + + +def json_to_html_command(args: dict[str, Any]) -> CommandResults: + + json_value = args.get('value', None) + if not json_value: + raise ValueError('JSON object was not specified!') + + result = json_to_html(value=json_value) + + return CommandResults( + outputs_prefix='Json2HtmlTable', + outputs_key_field='', + outputs=result, + ) + + +''' MAIN FUNCTION ''' + + +def main(): + try: + return_results(json_to_html_command(demisto.args())) + except Exception as ex: + return_error(f'Failed to execute Json2HtmlTable. Error: {str(ex)}') + + +''' ENTRY POINT ''' + + +if __name__ in ('__main__', '__builtin__', 'builtins'): + main() diff --git a/Packs/CommunityCommonScripts/Scripts/Json2HtmlTable/Json2HtmlTable.yml b/Packs/CommunityCommonScripts/Scripts/Json2HtmlTable/Json2HtmlTable.yml new file mode 100644 index 000000000000..6cd8f1d21a8e --- /dev/null +++ b/Packs/CommunityCommonScripts/Scripts/Json2HtmlTable/Json2HtmlTable.yml @@ -0,0 +1,18 @@ +args: +- description: 'The JSON object that should be converted to a HTML table.' + name: value + required: true +comment: 'Converts JSON objects to HTML tables.' +commonfields: + id: Json2HtmlTable + version: -1 +name: Json2HtmlTable +script: '-' +tags: +- basescript +- tansformer +timeout: '0' +type: python +subtype: python3 +dockerimage: demisto/py3-tools:1.0.0.105909 +fromversion: 5.5.0 diff --git a/Packs/CommunityCommonScripts/Scripts/Json2HtmlTable/Json2HtmlTable_test.py b/Packs/CommunityCommonScripts/Scripts/Json2HtmlTable/Json2HtmlTable_test.py new file mode 100644 index 000000000000..1ccbbd4831ae --- /dev/null +++ b/Packs/CommunityCommonScripts/Scripts/Json2HtmlTable/Json2HtmlTable_test.py @@ -0,0 +1,34 @@ +import demistomock as demisto # noqa: F401 +from CommonServerPython import * # noqa: F401 + +"""Tests the script functions of the Json2HtmlTable script""" + +import pytest +import Json2HtmlTable + + +@pytest.mark.parametrize("value,exptected", [ + (None, None), + ('{"test": "value"}', {"test": "value"}), + (['{"test": "value"}'], {"test": "value"}) +]) +def test_get_json_from_string(value, exptected): + """Tests the get_json_from_string function""" + + result: dict | str | None = Json2HtmlTable.get_json_from_string(value=value) + assert result == exptected + + +@pytest.mark.parametrize("value,expected", [ + ('{"test": "value"}', '
testvalue
'), + (['{"test": "value"}'], '
testvalue
') +]) +def test_json_to_html_command(value, expected): + + demisto_args: dict = { + "value": value + } + result: CommandResults = Json2HtmlTable.json_to_html_command( + args=demisto_args + ) + assert result.outputs == expected diff --git a/Packs/CommunityCommonScripts/Scripts/Json2HtmlTable/README.md b/Packs/CommunityCommonScripts/Scripts/Json2HtmlTable/README.md new file mode 100644 index 000000000000..cba376f191de --- /dev/null +++ b/Packs/CommunityCommonScripts/Scripts/Json2HtmlTable/README.md @@ -0,0 +1,24 @@ +Converts JSON objects to HTML tables. + +## Script Data + +--- + +| **Name** | **Description** | +| --- | --- | +| Script Type | python3 | +| Tags | basescript, tansformer | +| Cortex XSOAR Version | 5.5.0 | + +## Inputs + +--- + +| **Argument Name** | **Description** | +| --- | --- | +| value | The JSON object that should be converted to a HTML table. | + +## Outputs + +--- +There are no outputs for this script. diff --git a/Packs/CommunityCommonScripts/pack_metadata.json b/Packs/CommunityCommonScripts/pack_metadata.json index 00da6dbe5711..2d60191e6d92 100644 --- a/Packs/CommunityCommonScripts/pack_metadata.json +++ b/Packs/CommunityCommonScripts/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Community Common Scripts", "description": "A pack that contains community scripts", "support": "community", - "currentVersion": "1.2.5", + "currentVersion": "1.2.6", "author": "", "url": "https://live.paloaltonetworks.com/t5/cortex-xsoar-discussions/bd-p/Cortex_XSOAR_Discussions", "email": "", From 67c623a8c924dc5ecf257c708f0d83fe1b60212d Mon Sep 17 00:00:00 2001 From: inbalapt1 <164751454+inbalapt1@users.noreply.github.com> Date: Sun, 11 Aug 2024 18:03:18 +0300 Subject: [PATCH 12/14] Re-organization of Marketplace Categories (#35800) * categories updates in pack_metadata.json " + approved_categories * Your commit message * remove spaces * fix silverfort --- Config/approved_categories.json | 5 ++++- Packs/AWS-ACM/pack_metadata.json | 2 +- Packs/AWS-Athena/pack_metadata.json | 2 +- Packs/AWS-CloudTrail/pack_metadata.json | 2 +- Packs/AWS-EC2/pack_metadata.json | 2 +- Packs/AWS-EKS/pack_metadata.json | 2 +- Packs/AWS-GuardDuty/pack_metadata.json | 2 +- Packs/AWS-IAM/pack_metadata.json | 2 +- Packs/AWS-ILM/pack_metadata.json | 2 +- Packs/AWS-Lambda/pack_metadata.json | 2 +- Packs/AWS-Route53/pack_metadata.json | 2 +- Packs/AWS-S3/pack_metadata.json | 2 +- Packs/AWS-SNS-Listener/pack_metadata.json | 2 +- Packs/AWS-SNS/pack_metadata.json | 2 +- Packs/AWS-SQS/pack_metadata.json | 2 +- Packs/AWS-SecurityHub/pack_metadata.json | 2 +- Packs/AWS_SystemManager/pack_metadata.json | 2 +- Packs/Active_Directory_Query/pack_metadata.json | 2 +- Packs/AnsibleAlibabaCloud/pack_metadata.json | 2 +- Packs/AnsibleAzure/pack_metadata.json | 2 +- Packs/AnsibleHetznerCloud/pack_metadata.json | 2 +- Packs/AnsibleKubernetes/pack_metadata.json | 2 +- Packs/AnsibleLinux/pack_metadata.json | 2 +- Packs/AnsibleMicrosoftWindows/pack_metadata.json | 2 +- Packs/Attlasian/pack_metadata.json | 2 +- Packs/Aws-SecretsManager/pack_metadata.json | 2 +- Packs/AzureActiveDirectory/pack_metadata.json | 2 +- Packs/AzureCompute/pack_metadata.json | 2 +- Packs/AzureDataExplorer/pack_metadata.json | 2 +- Packs/AzureKeyVault/pack_metadata.json | 2 +- Packs/AzureKubernetesServices/pack_metadata.json | 2 +- Packs/AzureResourceGraph/pack_metadata.json | 2 +- Packs/AzureRiskyUsers/pack_metadata.json | 2 +- Packs/AzureStorage/pack_metadata.json | 2 +- Packs/AzureStorageContainer/pack_metadata.json | 2 +- Packs/AzureStorageFileShare/pack_metadata.json | 2 +- Packs/AzureStorageQueue/pack_metadata.json | 2 +- Packs/AzureStorageTable/pack_metadata.json | 2 +- Packs/BeyondTrust_Password_Safe/pack_metadata.json | 2 +- Packs/Bitbucket/pack_metadata.json | 2 +- Packs/CentrifyVault/pack_metadata.json | 2 +- Packs/Clarizen/pack_metadata.json | 2 +- Packs/CyberArkPAS/pack_metadata.json | 2 +- Packs/DelineaDSV/pack_metadata.json | 2 +- Packs/DelineaSS/pack_metadata.json | 2 +- Packs/DuoAdminApi/pack_metadata.json | 2 +- Packs/Envoy/pack_metadata.json | 2 +- Packs/FortiAuthenticator/pack_metadata.json | 2 +- Packs/GSuiteAdmin/pack_metadata.json | 2 +- Packs/GitHub/pack_metadata.json | 2 +- Packs/GitLab/pack_metadata.json | 2 +- Packs/GoogleCalendar/pack_metadata.json | 2 +- Packs/GoogleCloudCompute/pack_metadata.json | 2 +- Packs/GoogleCloudFunctions/pack_metadata.json | 2 +- Packs/GoogleCloudLogging/pack_metadata.json | 2 +- Packs/GoogleCloudSCC/pack_metadata.json | 2 +- Packs/GoogleCloudTranslate/pack_metadata.json | 2 +- Packs/GoogleDocs/pack_metadata.json | 2 +- Packs/GoogleKeyManagementService/pack_metadata.json | 2 +- Packs/GoogleKubernetesEngine/pack_metadata.json | 2 +- Packs/GoogleMaps/pack_metadata.json | 2 +- Packs/GoogleResourceManager/pack_metadata.json | 2 +- Packs/GoogleSheets/pack_metadata.json | 2 +- Packs/GoogleVault/pack_metadata.json | 2 +- Packs/GoogleVisionAPI/pack_metadata.json | 2 +- Packs/GsuiteAuditor/pack_metadata.json | 2 +- Packs/HashiCorp-Vault/pack_metadata.json | 2 +- Packs/JWT/pack_metadata.json | 2 +- Packs/KeeperSecretsManager/pack_metadata.json | 2 +- Packs/ManageEngine_PAM360/pack_metadata.json | 2 +- Packs/MicrosoftGraphAPI/pack_metadata.json | 2 +- Packs/MicrosoftGraphApplications/pack_metadata.json | 2 +- Packs/MicrosoftGraphCalendar/pack_metadata.json | 2 +- Packs/MicrosoftGraphGroups/pack_metadata.json | 2 +- Packs/MicrosoftGraphIdentityandAccess/pack_metadata.json | 2 +- Packs/MicrosoftGraphListener/pack_metadata.json | 2 +- Packs/MicrosoftGraphMail/pack_metadata.json | 2 +- Packs/MicrosoftGraphSearch/pack_metadata.json | 2 +- Packs/MicrosoftManagementActivity/pack_metadata.json | 2 +- Packs/Office365AndAzureAuditLog/pack_metadata.json | 2 +- Packs/Okta/pack_metadata.json | 2 +- Packs/OpenLDAP/pack_metadata.json | 2 +- Packs/OracleCloudInfrastructure/pack_metadata.json | 2 +- Packs/OracleCloudInfrastructureFeed/pack_metadata.json | 2 +- Packs/Oracle_IAM/pack_metadata.json | 2 +- Packs/PingIdentity/pack_metadata.json | 2 +- Packs/PrismaAccess/pack_metadata.json | 2 +- Packs/PrismaCloudComputeReporting/pack_metadata.json | 2 +- Packs/SafeNet_Trusted_Access/pack_metadata.json | 2 +- Packs/Safewalk/pack_metadata.json | 2 +- Packs/SalesforceFusion/pack_metadata.json | 2 +- Packs/Silverfort/pack_metadata.json | 2 +- Packs/SingleConnect/pack_metadata.json | 2 +- Packs/ThalesCipherTrustManager/pack_metadata.json | 2 +- Packs/Thycotic/pack_metadata.json | 2 +- Packs/ThycoticDSV/pack_metadata.json | 2 +- Packs/WALLIXBastion/pack_metadata.json | 2 +- Packs/cyberark_AIM/pack_metadata.json | 2 +- 98 files changed, 101 insertions(+), 98 deletions(-) diff --git a/Config/approved_categories.json b/Config/approved_categories.json index 17bfad346ba4..c1c42e3e663e 100644 --- a/Config/approved_categories.json +++ b/Config/approved_categories.json @@ -17,6 +17,9 @@ "Utilities", "Vulnerability Management", "Authentication & Identity Management", - "Email" + "Email", + "Cloud Service Provider", + "Code Repositories", + "CI/CD" ] } diff --git a/Packs/AWS-ACM/pack_metadata.json b/Packs/AWS-ACM/pack_metadata.json index 117de8829811..592b13a16ffa 100644 --- a/Packs/AWS-ACM/pack_metadata.json +++ b/Packs/AWS-ACM/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-14T00:00:00Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/AWS-Athena/pack_metadata.json b/Packs/AWS-Athena/pack_metadata.json index 289bfa06ab9d..37ffb3663625 100644 --- a/Packs/AWS-Athena/pack_metadata.json +++ b/Packs/AWS-Athena/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-14T00:00:00Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/AWS-CloudTrail/pack_metadata.json b/Packs/AWS-CloudTrail/pack_metadata.json index 03ac2ad494b0..b682d3997d57 100644 --- a/Packs/AWS-CloudTrail/pack_metadata.json +++ b/Packs/AWS-CloudTrail/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-14T00:00:00Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/AWS-EC2/pack_metadata.json b/Packs/AWS-EC2/pack_metadata.json index 1c22348814ad..c120f3b866a2 100644 --- a/Packs/AWS-EC2/pack_metadata.json +++ b/Packs/AWS-EC2/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-14T00:00:00Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/AWS-EKS/pack_metadata.json b/Packs/AWS-EKS/pack_metadata.json index 207de2fcdf42..368cb0ae7fb3 100644 --- a/Packs/AWS-EKS/pack_metadata.json +++ b/Packs/AWS-EKS/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/AWS-GuardDuty/pack_metadata.json b/Packs/AWS-GuardDuty/pack_metadata.json index efecb3ce0fff..3f5a64ac50e9 100644 --- a/Packs/AWS-GuardDuty/pack_metadata.json +++ b/Packs/AWS-GuardDuty/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-14T00:00:00Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "itemPrefix": [ diff --git a/Packs/AWS-IAM/pack_metadata.json b/Packs/AWS-IAM/pack_metadata.json index 136e6cab918a..3b5eee03c93c 100644 --- a/Packs/AWS-IAM/pack_metadata.json +++ b/Packs/AWS-IAM/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-14T00:00:00Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/AWS-ILM/pack_metadata.json b/Packs/AWS-ILM/pack_metadata.json index 1768302c7f6f..f7f27337d1bc 100644 --- a/Packs/AWS-ILM/pack_metadata.json +++ b/Packs/AWS-ILM/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/AWS-Lambda/pack_metadata.json b/Packs/AWS-Lambda/pack_metadata.json index 1d4292a88696..a822d06b5b84 100644 --- a/Packs/AWS-Lambda/pack_metadata.json +++ b/Packs/AWS-Lambda/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-14T00:00:00Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/AWS-Route53/pack_metadata.json b/Packs/AWS-Route53/pack_metadata.json index b797842d69c8..5dfd4b5aff8e 100644 --- a/Packs/AWS-Route53/pack_metadata.json +++ b/Packs/AWS-Route53/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-14T00:00:00Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/AWS-S3/pack_metadata.json b/Packs/AWS-S3/pack_metadata.json index 5cdecad892d1..bc40e02f14a0 100644 --- a/Packs/AWS-S3/pack_metadata.json +++ b/Packs/AWS-S3/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-14T00:00:00Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/AWS-SNS-Listener/pack_metadata.json b/Packs/AWS-SNS-Listener/pack_metadata.json index f5ace54c2535..399c349d177b 100644 --- a/Packs/AWS-SNS-Listener/pack_metadata.json +++ b/Packs/AWS-SNS-Listener/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2023-01-12T00:00:00Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/AWS-SNS/pack_metadata.json b/Packs/AWS-SNS/pack_metadata.json index 6528d4fa7e83..3b3ed7dfb931 100644 --- a/Packs/AWS-SNS/pack_metadata.json +++ b/Packs/AWS-SNS/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2022-05-25T03:52:46Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/AWS-SQS/pack_metadata.json b/Packs/AWS-SQS/pack_metadata.json index cbfa848729d9..0c9520bc0b2c 100644 --- a/Packs/AWS-SQS/pack_metadata.json +++ b/Packs/AWS-SQS/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-14T00:00:00Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/AWS-SecurityHub/pack_metadata.json b/Packs/AWS-SecurityHub/pack_metadata.json index 5a367e3bed1b..80636955ad2e 100644 --- a/Packs/AWS-SecurityHub/pack_metadata.json +++ b/Packs/AWS-SecurityHub/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-14T00:00:00Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/AWS_SystemManager/pack_metadata.json b/Packs/AWS_SystemManager/pack_metadata.json index 194b56d5cf7b..1159d07f17fa 100644 --- a/Packs/AWS_SystemManager/pack_metadata.json +++ b/Packs/AWS_SystemManager/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/Active_Directory_Query/pack_metadata.json b/Packs/Active_Directory_Query/pack_metadata.json index 420ce5a6c93e..8199aecda9e9 100644 --- a/Packs/Active_Directory_Query/pack_metadata.json +++ b/Packs/Active_Directory_Query/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-03-09T14:47:00Z", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/AnsibleAlibabaCloud/pack_metadata.json b/Packs/AnsibleAlibabaCloud/pack_metadata.json index 380a11057a29..e9f3a9312625 100644 --- a/Packs/AnsibleAlibabaCloud/pack_metadata.json +++ b/Packs/AnsibleAlibabaCloud/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/AnsibleAzure/pack_metadata.json b/Packs/AnsibleAzure/pack_metadata.json index 5f5f259b9450..298773464c82 100644 --- a/Packs/AnsibleAzure/pack_metadata.json +++ b/Packs/AnsibleAzure/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/AnsibleHetznerCloud/pack_metadata.json b/Packs/AnsibleHetznerCloud/pack_metadata.json index 498135018125..8f1548734fd3 100644 --- a/Packs/AnsibleHetznerCloud/pack_metadata.json +++ b/Packs/AnsibleHetznerCloud/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Cloud Services" + "Utilities" ], "tags": [], "useCases": [], diff --git a/Packs/AnsibleKubernetes/pack_metadata.json b/Packs/AnsibleKubernetes/pack_metadata.json index f9d7213b4510..b2485ebed3a3 100644 --- a/Packs/AnsibleKubernetes/pack_metadata.json +++ b/Packs/AnsibleKubernetes/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Cloud Services" + "Utilities" ], "tags": [], "useCases": [], diff --git a/Packs/AnsibleLinux/pack_metadata.json b/Packs/AnsibleLinux/pack_metadata.json index 35d8be178f8f..76c0da901bbd 100644 --- a/Packs/AnsibleLinux/pack_metadata.json +++ b/Packs/AnsibleLinux/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Cloud Services" + "IT Services" ], "tags": [], "useCases": [], diff --git a/Packs/AnsibleMicrosoftWindows/pack_metadata.json b/Packs/AnsibleMicrosoftWindows/pack_metadata.json index 28d4202f0739..f64a950379ef 100644 --- a/Packs/AnsibleMicrosoftWindows/pack_metadata.json +++ b/Packs/AnsibleMicrosoftWindows/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Cloud Services" + "IT Services" ], "tags": [], "useCases": [], diff --git a/Packs/Attlasian/pack_metadata.json b/Packs/Attlasian/pack_metadata.json index 5a3a2d901a08..0651a566d49e 100644 --- a/Packs/Attlasian/pack_metadata.json +++ b/Packs/Attlasian/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2021-02-01T11:04:01Z", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/Aws-SecretsManager/pack_metadata.json b/Packs/Aws-SecretsManager/pack_metadata.json index bbb57346470c..3a549b4a410c 100644 --- a/Packs/Aws-SecretsManager/pack_metadata.json +++ b/Packs/Aws-SecretsManager/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/AzureActiveDirectory/pack_metadata.json b/Packs/AzureActiveDirectory/pack_metadata.json index fe587f8e8b04..7af1fac36574 100644 --- a/Packs/AzureActiveDirectory/pack_metadata.json +++ b/Packs/AzureActiveDirectory/pack_metadata.json @@ -8,7 +8,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/AzureCompute/pack_metadata.json b/Packs/AzureCompute/pack_metadata.json index 6efae5549bef..a6cfb62a7209 100644 --- a/Packs/AzureCompute/pack_metadata.json +++ b/Packs/AzureCompute/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-14T00:00:00Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/AzureDataExplorer/pack_metadata.json b/Packs/AzureDataExplorer/pack_metadata.json index 991f98e41cae..655b49f5ff17 100644 --- a/Packs/AzureDataExplorer/pack_metadata.json +++ b/Packs/AzureDataExplorer/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/AzureKeyVault/pack_metadata.json b/Packs/AzureKeyVault/pack_metadata.json index 89c71d5bc679..a424529acb3a 100644 --- a/Packs/AzureKeyVault/pack_metadata.json +++ b/Packs/AzureKeyVault/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/AzureKubernetesServices/pack_metadata.json b/Packs/AzureKubernetesServices/pack_metadata.json index 0579d097f68c..3f221ab8101e 100644 --- a/Packs/AzureKubernetesServices/pack_metadata.json +++ b/Packs/AzureKubernetesServices/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-01-17T14:56:54Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/AzureResourceGraph/pack_metadata.json b/Packs/AzureResourceGraph/pack_metadata.json index f8f52f3be737..cf84c270b5c5 100644 --- a/Packs/AzureResourceGraph/pack_metadata.json +++ b/Packs/AzureResourceGraph/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/AzureRiskyUsers/pack_metadata.json b/Packs/AzureRiskyUsers/pack_metadata.json index 32d0662da7d0..1072e7fa51bb 100644 --- a/Packs/AzureRiskyUsers/pack_metadata.json +++ b/Packs/AzureRiskyUsers/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2021-12-09T08:00:00Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/AzureStorage/pack_metadata.json b/Packs/AzureStorage/pack_metadata.json index c5bcd9ee825e..32d8e92f2a4b 100644 --- a/Packs/AzureStorage/pack_metadata.json +++ b/Packs/AzureStorage/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/AzureStorageContainer/pack_metadata.json b/Packs/AzureStorageContainer/pack_metadata.json index c3f40fc8982a..ca2c2bd5cba8 100644 --- a/Packs/AzureStorageContainer/pack_metadata.json +++ b/Packs/AzureStorageContainer/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/AzureStorageFileShare/pack_metadata.json b/Packs/AzureStorageFileShare/pack_metadata.json index 96073b0c5c95..b0a67e5a4d28 100644 --- a/Packs/AzureStorageFileShare/pack_metadata.json +++ b/Packs/AzureStorageFileShare/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/AzureStorageQueue/pack_metadata.json b/Packs/AzureStorageQueue/pack_metadata.json index 5aa708070714..92f1cd0689b0 100644 --- a/Packs/AzureStorageQueue/pack_metadata.json +++ b/Packs/AzureStorageQueue/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/AzureStorageTable/pack_metadata.json b/Packs/AzureStorageTable/pack_metadata.json index 7011f4fbae61..bb99c490992a 100644 --- a/Packs/AzureStorageTable/pack_metadata.json +++ b/Packs/AzureStorageTable/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/BeyondTrust_Password_Safe/pack_metadata.json b/Packs/BeyondTrust_Password_Safe/pack_metadata.json index 8d7b1e09e136..dbf1d3cce55e 100644 --- a/Packs/BeyondTrust_Password_Safe/pack_metadata.json +++ b/Packs/BeyondTrust_Password_Safe/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-14T00:00:00Z", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/Bitbucket/pack_metadata.json b/Packs/Bitbucket/pack_metadata.json index ed93d0fa5d53..114371e95754 100644 --- a/Packs/Bitbucket/pack_metadata.json +++ b/Packs/Bitbucket/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Utilities" + "CI/CD" ], "tags": [], "useCases": [], diff --git a/Packs/CentrifyVault/pack_metadata.json b/Packs/CentrifyVault/pack_metadata.json index 663b599081da..1feb09be8849 100644 --- a/Packs/CentrifyVault/pack_metadata.json +++ b/Packs/CentrifyVault/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-12-08T01:52:58Z", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/Clarizen/pack_metadata.json b/Packs/Clarizen/pack_metadata.json index 817070585ee2..f256856bf599 100644 --- a/Packs/Clarizen/pack_metadata.json +++ b/Packs/Clarizen/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/CyberArkPAS/pack_metadata.json b/Packs/CyberArkPAS/pack_metadata.json index 34a64bdc8e34..2f5bb273e8cd 100644 --- a/Packs/CyberArkPAS/pack_metadata.json +++ b/Packs/CyberArkPAS/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-06-03T21:49:36Z", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/DelineaDSV/pack_metadata.json b/Packs/DelineaDSV/pack_metadata.json index 0a5608c2c277..386d0221ffc3 100644 --- a/Packs/DelineaDSV/pack_metadata.json +++ b/Packs/DelineaDSV/pack_metadata.json @@ -8,7 +8,7 @@ "email": "support@delinea.com", "created": "2022-08-10T08:04:48Z", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/DelineaSS/pack_metadata.json b/Packs/DelineaSS/pack_metadata.json index 3c940ac86262..8b2fd02c2571 100644 --- a/Packs/DelineaSS/pack_metadata.json +++ b/Packs/DelineaSS/pack_metadata.json @@ -8,7 +8,7 @@ "email": "support@delinea.com", "created": "2022-08-10T14:49:56Z", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/DuoAdminApi/pack_metadata.json b/Packs/DuoAdminApi/pack_metadata.json index cbbecc05209b..b96339b38cf1 100644 --- a/Packs/DuoAdminApi/pack_metadata.json +++ b/Packs/DuoAdminApi/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-14T00:00:00Z", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/Envoy/pack_metadata.json b/Packs/Envoy/pack_metadata.json index 0edabfcd90af..4aa1066d3086 100644 --- a/Packs/Envoy/pack_metadata.json +++ b/Packs/Envoy/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/FortiAuthenticator/pack_metadata.json b/Packs/FortiAuthenticator/pack_metadata.json index 3b587bacdb36..2ac2816cdf29 100644 --- a/Packs/FortiAuthenticator/pack_metadata.json +++ b/Packs/FortiAuthenticator/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2022-05-22T18:22:50Z", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/GSuiteAdmin/pack_metadata.json b/Packs/GSuiteAdmin/pack_metadata.json index be0708c77674..eac8ca7c2cd3 100644 --- a/Packs/GSuiteAdmin/pack_metadata.json +++ b/Packs/GSuiteAdmin/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-08-14T10:49:54Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/GitHub/pack_metadata.json b/Packs/GitHub/pack_metadata.json index 7eb36ef18cc4..8eca21a69d5e 100644 --- a/Packs/GitHub/pack_metadata.json +++ b/Packs/GitHub/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-14T00:00:00Z", "categories": [ - "Utilities" + "Code Repositories" ], "tags": [], "useCases": [], diff --git a/Packs/GitLab/pack_metadata.json b/Packs/GitLab/pack_metadata.json index 203d0f258ad5..6b0c28f171d0 100644 --- a/Packs/GitLab/pack_metadata.json +++ b/Packs/GitLab/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-14T00:00:00Z", "categories": [ - "Utilities" + "Code Repositories" ], "tags": [], "useCases": [], diff --git a/Packs/GoogleCalendar/pack_metadata.json b/Packs/GoogleCalendar/pack_metadata.json index 927db21cd044..6c65161b953d 100644 --- a/Packs/GoogleCalendar/pack_metadata.json +++ b/Packs/GoogleCalendar/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-08-14T10:49:54Z", "categories": [ - "Cloud Services" + "Utilities" ], "tags": [], "useCases": [], diff --git a/Packs/GoogleCloudCompute/pack_metadata.json b/Packs/GoogleCloudCompute/pack_metadata.json index 1a750e83475a..9614dbc4f90e 100644 --- a/Packs/GoogleCloudCompute/pack_metadata.json +++ b/Packs/GoogleCloudCompute/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-14T00:00:00Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/GoogleCloudFunctions/pack_metadata.json b/Packs/GoogleCloudFunctions/pack_metadata.json index 8f9d5db56712..9e82c80cdf46 100644 --- a/Packs/GoogleCloudFunctions/pack_metadata.json +++ b/Packs/GoogleCloudFunctions/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-02T07:37:03Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/GoogleCloudLogging/pack_metadata.json b/Packs/GoogleCloudLogging/pack_metadata.json index 4ac2ed322f8a..f6a0ccd47e2d 100644 --- a/Packs/GoogleCloudLogging/pack_metadata.json +++ b/Packs/GoogleCloudLogging/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/GoogleCloudSCC/pack_metadata.json b/Packs/GoogleCloudSCC/pack_metadata.json index 13e37f1d88de..59225c48dd97 100644 --- a/Packs/GoogleCloudSCC/pack_metadata.json +++ b/Packs/GoogleCloudSCC/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-12-17T10:49:54Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/GoogleCloudTranslate/pack_metadata.json b/Packs/GoogleCloudTranslate/pack_metadata.json index 848ef12dea6f..e3c096fc0394 100644 --- a/Packs/GoogleCloudTranslate/pack_metadata.json +++ b/Packs/GoogleCloudTranslate/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-14T00:00:00Z", "categories": [ - "Cloud Services" + "Utilities" ], "tags": [], "useCases": [], diff --git a/Packs/GoogleDocs/pack_metadata.json b/Packs/GoogleDocs/pack_metadata.json index ea11522fe99e..99ef537190e6 100644 --- a/Packs/GoogleDocs/pack_metadata.json +++ b/Packs/GoogleDocs/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-14T00:00:00Z", "categories": [ - "Cloud Services" + "Utilities" ], "tags": [], "useCases": [], diff --git a/Packs/GoogleKeyManagementService/pack_metadata.json b/Packs/GoogleKeyManagementService/pack_metadata.json index b0c4571d41e6..d3246c9a9c5f 100644 --- a/Packs/GoogleKeyManagementService/pack_metadata.json +++ b/Packs/GoogleKeyManagementService/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-14T00:00:00Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/GoogleKubernetesEngine/pack_metadata.json b/Packs/GoogleKubernetesEngine/pack_metadata.json index 572a71dbe871..23b5c51585d8 100644 --- a/Packs/GoogleKubernetesEngine/pack_metadata.json +++ b/Packs/GoogleKubernetesEngine/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "created": "2020-05-04T06:42:33Z", diff --git a/Packs/GoogleMaps/pack_metadata.json b/Packs/GoogleMaps/pack_metadata.json index 94fceba41421..40b2f4691821 100644 --- a/Packs/GoogleMaps/pack_metadata.json +++ b/Packs/GoogleMaps/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2021-05-20T09:00:00Z", "categories": [ - "Cloud Services" + "Utilities" ], "tags": [], "useCases": [], diff --git a/Packs/GoogleResourceManager/pack_metadata.json b/Packs/GoogleResourceManager/pack_metadata.json index 04c18d3cc213..4153c772ba4e 100644 --- a/Packs/GoogleResourceManager/pack_metadata.json +++ b/Packs/GoogleResourceManager/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-14T00:00:00Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/GoogleSheets/pack_metadata.json b/Packs/GoogleSheets/pack_metadata.json index af8edf32a66e..f118bb552a16 100644 --- a/Packs/GoogleSheets/pack_metadata.json +++ b/Packs/GoogleSheets/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Cloud Services" + "Utilities" ], "tags": [], "useCases": [], diff --git a/Packs/GoogleVault/pack_metadata.json b/Packs/GoogleVault/pack_metadata.json index 3d12651f95fa..cb648979882c 100644 --- a/Packs/GoogleVault/pack_metadata.json +++ b/Packs/GoogleVault/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-14T00:00:00Z", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/GoogleVisionAPI/pack_metadata.json b/Packs/GoogleVisionAPI/pack_metadata.json index c4445a6e072f..3720394c4282 100644 --- a/Packs/GoogleVisionAPI/pack_metadata.json +++ b/Packs/GoogleVisionAPI/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-14T00:00:00Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/GsuiteAuditor/pack_metadata.json b/Packs/GsuiteAuditor/pack_metadata.json index 21e5c0e7d222..e8fb5e4b483a 100644 --- a/Packs/GsuiteAuditor/pack_metadata.json +++ b/Packs/GsuiteAuditor/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/HashiCorp-Vault/pack_metadata.json b/Packs/HashiCorp-Vault/pack_metadata.json index 9dbc27239b15..1059c306d28c 100644 --- a/Packs/HashiCorp-Vault/pack_metadata.json +++ b/Packs/HashiCorp-Vault/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-14T00:00:00Z", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/JWT/pack_metadata.json b/Packs/JWT/pack_metadata.json index c8b6502a5551..851bd4d3ff1d 100644 --- a/Packs/JWT/pack_metadata.json +++ b/Packs/JWT/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://live.paloaltonetworks.com/t5/cortex-xsoar-discussions/bd-p/Cortex_XSOAR_Discussions", "email": "", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/KeeperSecretsManager/pack_metadata.json b/Packs/KeeperSecretsManager/pack_metadata.json index d2df9a4837d8..5999012788d2 100644 --- a/Packs/KeeperSecretsManager/pack_metadata.json +++ b/Packs/KeeperSecretsManager/pack_metadata.json @@ -8,7 +8,7 @@ "email": "sm@keepersecurity.com", "created": "2022-08-15T15:04:05Z", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/ManageEngine_PAM360/pack_metadata.json b/Packs/ManageEngine_PAM360/pack_metadata.json index 907d7a7cde49..80903d9249cf 100644 --- a/Packs/ManageEngine_PAM360/pack_metadata.json +++ b/Packs/ManageEngine_PAM360/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.manageengine.com/privileged-access-management/support.html", "email": "pam360-support@manageengine.com", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/MicrosoftGraphAPI/pack_metadata.json b/Packs/MicrosoftGraphAPI/pack_metadata.json index d86fa2d7442e..2711445d7ef3 100644 --- a/Packs/MicrosoftGraphAPI/pack_metadata.json +++ b/Packs/MicrosoftGraphAPI/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-10-23T13:55:23Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/MicrosoftGraphApplications/pack_metadata.json b/Packs/MicrosoftGraphApplications/pack_metadata.json index 59882d1b03e1..4081eb48a8b2 100644 --- a/Packs/MicrosoftGraphApplications/pack_metadata.json +++ b/Packs/MicrosoftGraphApplications/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/MicrosoftGraphCalendar/pack_metadata.json b/Packs/MicrosoftGraphCalendar/pack_metadata.json index 4b995f543ebf..26d52da99bad 100644 --- a/Packs/MicrosoftGraphCalendar/pack_metadata.json +++ b/Packs/MicrosoftGraphCalendar/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-01-08T13:16:53Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/MicrosoftGraphGroups/pack_metadata.json b/Packs/MicrosoftGraphGroups/pack_metadata.json index 1d31ea86a34f..40fe5f8095ac 100644 --- a/Packs/MicrosoftGraphGroups/pack_metadata.json +++ b/Packs/MicrosoftGraphGroups/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-20T11:24:15Z", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/MicrosoftGraphIdentityandAccess/pack_metadata.json b/Packs/MicrosoftGraphIdentityandAccess/pack_metadata.json index 80b2a1fea6e3..e51dad0b273c 100644 --- a/Packs/MicrosoftGraphIdentityandAccess/pack_metadata.json +++ b/Packs/MicrosoftGraphIdentityandAccess/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/MicrosoftGraphListener/pack_metadata.json b/Packs/MicrosoftGraphListener/pack_metadata.json index 307d37467cb0..dd14b4b11216 100644 --- a/Packs/MicrosoftGraphListener/pack_metadata.json +++ b/Packs/MicrosoftGraphListener/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-14T00:00:00Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/MicrosoftGraphMail/pack_metadata.json b/Packs/MicrosoftGraphMail/pack_metadata.json index cad39b458d9a..adbbd1e2ada2 100644 --- a/Packs/MicrosoftGraphMail/pack_metadata.json +++ b/Packs/MicrosoftGraphMail/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-14T00:00:00Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/MicrosoftGraphSearch/pack_metadata.json b/Packs/MicrosoftGraphSearch/pack_metadata.json index bf4d0ab55f66..6808e633c0ac 100644 --- a/Packs/MicrosoftGraphSearch/pack_metadata.json +++ b/Packs/MicrosoftGraphSearch/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2023-03-03T14:38:36Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/MicrosoftManagementActivity/pack_metadata.json b/Packs/MicrosoftManagementActivity/pack_metadata.json index 8e8ef5e97f4d..60dfe109f469 100644 --- a/Packs/MicrosoftManagementActivity/pack_metadata.json +++ b/Packs/MicrosoftManagementActivity/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-13T06:33:31Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/Office365AndAzureAuditLog/pack_metadata.json b/Packs/Office365AndAzureAuditLog/pack_metadata.json index 2d88e4397a19..a6b28b3ac034 100644 --- a/Packs/Office365AndAzureAuditLog/pack_metadata.json +++ b/Packs/Office365AndAzureAuditLog/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/Okta/pack_metadata.json b/Packs/Okta/pack_metadata.json index f05ec8523408..92d98c310617 100644 --- a/Packs/Okta/pack_metadata.json +++ b/Packs/Okta/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-14T00:00:00Z", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/OpenLDAP/pack_metadata.json b/Packs/OpenLDAP/pack_metadata.json index 104559a7c840..b4312cf2f227 100644 --- a/Packs/OpenLDAP/pack_metadata.json +++ b/Packs/OpenLDAP/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-14T00:00:00Z", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/OracleCloudInfrastructure/pack_metadata.json b/Packs/OracleCloudInfrastructure/pack_metadata.json index a04a8405095d..42ee02cccbeb 100644 --- a/Packs/OracleCloudInfrastructure/pack_metadata.json +++ b/Packs/OracleCloudInfrastructure/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/OracleCloudInfrastructureFeed/pack_metadata.json b/Packs/OracleCloudInfrastructureFeed/pack_metadata.json index be1efbe17f34..93daf697569b 100644 --- a/Packs/OracleCloudInfrastructureFeed/pack_metadata.json +++ b/Packs/OracleCloudInfrastructureFeed/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2023-06-22T18:59:06Z", "categories": [ - "Cloud Services" + "Cloud Service Provider" ], "tags": [], "useCases": [], diff --git a/Packs/Oracle_IAM/pack_metadata.json b/Packs/Oracle_IAM/pack_metadata.json index 64dc9a82a525..0ed4ac4049ee 100644 --- a/Packs/Oracle_IAM/pack_metadata.json +++ b/Packs/Oracle_IAM/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/PingIdentity/pack_metadata.json b/Packs/PingIdentity/pack_metadata.json index a27ee37e3e3c..1a730b95462c 100644 --- a/Packs/PingIdentity/pack_metadata.json +++ b/Packs/PingIdentity/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://docs.pingidentity.com/bundle/p14c/page/als1564020488261.html", "email": "tap-global@pingidentity.com", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/PrismaAccess/pack_metadata.json b/Packs/PrismaAccess/pack_metadata.json index 139a6e2556cc..249ecfcce44c 100644 --- a/Packs/PrismaAccess/pack_metadata.json +++ b/Packs/PrismaAccess/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2020-04-16T22:51:04Z", "categories": [ - "Cloud Services" + "Cloud Security" ], "tags": [ "Palo Alto Networks Products" diff --git a/Packs/PrismaCloudComputeReporting/pack_metadata.json b/Packs/PrismaCloudComputeReporting/pack_metadata.json index fe81cf9497a5..4f0d044fe991 100644 --- a/Packs/PrismaCloudComputeReporting/pack_metadata.json +++ b/Packs/PrismaCloudComputeReporting/pack_metadata.json @@ -8,7 +8,7 @@ "url": "https://live.paloaltonetworks.com/t5/cortex-xsoar-discussions/bd-p/Cortex_XSOAR_Discussions", "email": "", "categories": [ - "Cloud Services" + "Cloud Security" ], "tags": [ "Palo Alto Networks Products" diff --git a/Packs/SafeNet_Trusted_Access/pack_metadata.json b/Packs/SafeNet_Trusted_Access/pack_metadata.json index 752eb3bca022..464aa7fbec6b 100644 --- a/Packs/SafeNet_Trusted_Access/pack_metadata.json +++ b/Packs/SafeNet_Trusted_Access/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://supportportal.gemalto.com/csm/?id=portal_home_page", "email": "", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/Safewalk/pack_metadata.json b/Packs/Safewalk/pack_metadata.json index 32ff3330eb93..903940aff8c6 100644 --- a/Packs/Safewalk/pack_metadata.json +++ b/Packs/Safewalk/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.altipeaksecurity.com", "email": "support@altipeak.com", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/SalesforceFusion/pack_metadata.json b/Packs/SalesforceFusion/pack_metadata.json index 9f0fd1dae158..ae4a4d618f22 100644 --- a/Packs/SalesforceFusion/pack_metadata.json +++ b/Packs/SalesforceFusion/pack_metadata.json @@ -8,7 +8,7 @@ "email": "", "created": "2021-10-19T00:00:00Z", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/Silverfort/pack_metadata.json b/Packs/Silverfort/pack_metadata.json index e30ac8926c42..3a800e076f3a 100644 --- a/Packs/Silverfort/pack_metadata.json +++ b/Packs/Silverfort/pack_metadata.json @@ -8,7 +8,7 @@ "email": "support@silverfort.com", "created": "2020-03-17T16:09:03Z", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/SingleConnect/pack_metadata.json b/Packs/SingleConnect/pack_metadata.json index 1d463af0dffa..a92d1755b5ee 100644 --- a/Packs/SingleConnect/pack_metadata.json +++ b/Packs/SingleConnect/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://kron.com.tr/en/single-connect", "email": "", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/ThalesCipherTrustManager/pack_metadata.json b/Packs/ThalesCipherTrustManager/pack_metadata.json index e12038ae945f..b459ae508577 100644 --- a/Packs/ThalesCipherTrustManager/pack_metadata.json +++ b/Packs/ThalesCipherTrustManager/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.paloaltonetworks.com/cortex", "email": "", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/Thycotic/pack_metadata.json b/Packs/Thycotic/pack_metadata.json index 2e517660f110..e4905f884787 100644 --- a/Packs/Thycotic/pack_metadata.json +++ b/Packs/Thycotic/pack_metadata.json @@ -8,7 +8,7 @@ "email": "support@thycotic.com", "created": "2020-10-09T14:49:56Z", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/ThycoticDSV/pack_metadata.json b/Packs/ThycoticDSV/pack_metadata.json index 0f5308068ec9..74fee2dca100 100644 --- a/Packs/ThycoticDSV/pack_metadata.json +++ b/Packs/ThycoticDSV/pack_metadata.json @@ -8,7 +8,7 @@ "email": "support@thycotic.com", "created": "2020-12-17T08:04:48Z", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [], diff --git a/Packs/WALLIXBastion/pack_metadata.json b/Packs/WALLIXBastion/pack_metadata.json index 2c15653af16b..24f5721a6209 100644 --- a/Packs/WALLIXBastion/pack_metadata.json +++ b/Packs/WALLIXBastion/pack_metadata.json @@ -7,7 +7,7 @@ "url": "https://www.wallix.com/privileged-access-management/", "email": "", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [ "Compliance", diff --git a/Packs/cyberark_AIM/pack_metadata.json b/Packs/cyberark_AIM/pack_metadata.json index d37f0378b50d..ab768d5096c5 100644 --- a/Packs/cyberark_AIM/pack_metadata.json +++ b/Packs/cyberark_AIM/pack_metadata.json @@ -8,7 +8,7 @@ "email": "https://www.cyberark.com/services-support/technical-support-contact/", "created": "2020-04-14T00:00:00Z", "categories": [ - "Authentication & Identity Management" + "Identity and Access Management" ], "tags": [], "useCases": [ From be429cd8d8d6000b860ae71f02e9ac783a615603 Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Sun, 11 Aug 2024 18:54:37 +0300 Subject: [PATCH 13/14] Team Cymru - Release 2.0.0 (#35722) (#35777) * Team Cymru - Release 2.0.0 * docs: Updated YML and README for suggested changes in context path type * docs: Changes in YML and in README as per the review comments --------- Co-authored-by: Crest Data <60967033+crestdatasystems@users.noreply.github.com> Co-authored-by: crestdatasystems --- Packs/TeamCymru/.pack-ignore | 33 +- Packs/TeamCymru/.secrets-ignore | 8 +- .../Integrations/TeamCymruScout/README.md | 1512 ++++++++++++++++ .../TeamCymruScout/TeamCymruScout.py | 1132 ++++++++++++ .../TeamCymruScout/TeamCymruScout.yml | 1581 +++++++++++++++++ .../TeamCymruScout_description.md | 37 + .../TeamCymruScout/TeamCymruScout_image.png | Bin 0 -> 4716 bytes .../TeamCymruScout/TeamCymruScout_test.py | 472 +++++ .../TeamCymruScout/command_examples | 4 + .../TeamCymruScout/test_data/ip_hr.md | 39 + .../test_data/ip_indicator.json | 94 + .../TeamCymruScout/test_data/ip_output.json | 859 +++++++++ .../test_data/ip_raw_response.json | 856 +++++++++ .../test_data/ip_relationships.json | 72 + .../TeamCymruScout/test_data/ip_response.json | 883 +++++++++ .../test_data/scout_api_usage_hr.md | 4 + .../test_data/scout_api_usage_output.json | 11 + .../test_data/scout_api_usage_response.json | 10 + .../scout_indicator_search_entry_context.json | 204 +++ .../test_data/scout_indicator_search_hr.md | 42 + .../scout_indicator_search_output.json | 222 +++ .../scout_indicator_search_response.json | 166 ++ .../test_data/scout_ip_list_hr.md | 4 + .../test_data/scout_ip_list_output.json | 78 + .../test_data/scout_ip_list_response.json | 53 + Packs/TeamCymru/README.md | 20 +- Packs/TeamCymru/ReleaseNotes/2_0_0.md | 6 + Packs/TeamCymru/pack_metadata.json | 35 +- 28 files changed, 8429 insertions(+), 8 deletions(-) create mode 100644 Packs/TeamCymru/Integrations/TeamCymruScout/README.md create mode 100644 Packs/TeamCymru/Integrations/TeamCymruScout/TeamCymruScout.py create mode 100644 Packs/TeamCymru/Integrations/TeamCymruScout/TeamCymruScout.yml create mode 100644 Packs/TeamCymru/Integrations/TeamCymruScout/TeamCymruScout_description.md create mode 100644 Packs/TeamCymru/Integrations/TeamCymruScout/TeamCymruScout_image.png create mode 100644 Packs/TeamCymru/Integrations/TeamCymruScout/TeamCymruScout_test.py create mode 100644 Packs/TeamCymru/Integrations/TeamCymruScout/command_examples create mode 100644 Packs/TeamCymru/Integrations/TeamCymruScout/test_data/ip_hr.md create mode 100644 Packs/TeamCymru/Integrations/TeamCymruScout/test_data/ip_indicator.json create mode 100644 Packs/TeamCymru/Integrations/TeamCymruScout/test_data/ip_output.json create mode 100644 Packs/TeamCymru/Integrations/TeamCymruScout/test_data/ip_raw_response.json create mode 100644 Packs/TeamCymru/Integrations/TeamCymruScout/test_data/ip_relationships.json create mode 100644 Packs/TeamCymru/Integrations/TeamCymruScout/test_data/ip_response.json create mode 100644 Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_api_usage_hr.md create mode 100644 Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_api_usage_output.json create mode 100644 Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_api_usage_response.json create mode 100644 Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_indicator_search_entry_context.json create mode 100644 Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_indicator_search_hr.md create mode 100644 Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_indicator_search_output.json create mode 100644 Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_indicator_search_response.json create mode 100644 Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_ip_list_hr.md create mode 100644 Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_ip_list_output.json create mode 100644 Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_ip_list_response.json create mode 100644 Packs/TeamCymru/ReleaseNotes/2_0_0.md diff --git a/Packs/TeamCymru/.pack-ignore b/Packs/TeamCymru/.pack-ignore index b28e0c66cd9b..38db7848d007 100644 --- a/Packs/TeamCymru/.pack-ignore +++ b/Packs/TeamCymru/.pack-ignore @@ -1,2 +1,33 @@ [known_words] -Cymru \ No newline at end of file +Cymru +BGP +ASNS +TLP +pdns +nameserver +nameservers +css +DBotScore +Bool +B +D +n +LLC +UDP +RIR +altnames +testserial +https +ltd +blvd +tcp +tls +cdn +jarm +testsignature +cc +Interworks +aaa +pdr +cdns +CLOUDFLARENET \ No newline at end of file diff --git a/Packs/TeamCymru/.secrets-ignore b/Packs/TeamCymru/.secrets-ignore index bb644a617986..e712e17a1198 100644 --- a/Packs/TeamCymru/.secrets-ignore +++ b/Packs/TeamCymru/.secrets-ignore @@ -9,4 +9,10 @@ 1.1.2.2 4.0.0.0 6.6.6.0 -team_cymru_bulk_whois \ No newline at end of file +team_cymru_bulk_whois +0.0.0 +pdns +x509 +scout +cymru +backoff \ No newline at end of file diff --git a/Packs/TeamCymru/Integrations/TeamCymruScout/README.md b/Packs/TeamCymru/Integrations/TeamCymruScout/README.md new file mode 100644 index 000000000000..dcb31274128b --- /dev/null +++ b/Packs/TeamCymru/Integrations/TeamCymruScout/README.md @@ -0,0 +1,1512 @@ +## Overview + +The Team Cymru Scout integration enables getting immediate insight on IP addresses and domains for threat investigations. +This integration was integrated and tested with API of Team Cymru Scout. + +### Key Features + +- Explore the communication data to identify commonalities between IPs, identify compromised hosts, and uncover other indications of an attack. +- Access to NetFlow communications, Whois information, PDNS, X509 certificates, and fingerprinting details. +- Supports both IPv4 and IPv6 address queries. +- Provides real-time threat intelligence and helps in identifying and mitigating potential security threats. +- Offers extensive documentation and support resources to assist with setup, configuration, and troubleshooting. + +## Prerequisites for configuring integration instance + +- Access to the [Team Cymru Scout platform](https://scout.cymru.com/scout). +- An API Key or Basic Auth credentials for authentication. + +### Generate API Keys + +If you prefer to use an API key for authentication, you can generate one as follows: + +1. Go to the [API Keys page](https://scout.cymru.com/api_keys). +2. Click on the "Create" button. +3. Provide the description for the key, if needed. +4. Click on the "Create Key" button to generate the API key. + +Note: + +- The number of API keys allowed for each organization is equal to the number of user seats. Therefore, an individual user may have multiple keys, but all the users in your organization may have a maximum of 5 keys. The [API Keys page](https://scout.cymru.com/api_keys) shows the total number of keys used by your organization. +- If the "Create" button is disabled, it indicates that you have reached the maximum number of keys allowed for your organization. To generate a new key, you need to: + - Click on the "Revoke" button next to an old key. + - Click on the "Create Key" button to start generating a new key. + +## Configure Team Cymru Scout on Cortex XSOAR + +1. Navigate to **Settings** > **Integrations** > **Servers & Services**. +2. Search for Team Cymru Scout. +3. Click **Add instance** to create and configure a new integration instance. + + | **Parameter** | **Description** | **Required** | + | --- | --- | --- | + | Authentication Type | The authentication type used for secure communication with the Team Cymru Scout platform. | True | + | API Key | The API key used for secure communication with the Team Cymru Scout platform. Required if "API Key" as Authentication Type is selected. | False | + | Username, Password | The username and password used for secure communication with the Team Cymru Scout platform. Required if "Basic Auth" as Authentication Type is selected. | False | + | Source Reliability | Reliability of the source providing the intelligence data. | False | + | Create relationships | Create relationships between indicators as part of enrichment. | False | + | Use system proxy settings | | False | + | Trust any certificate (not secure) | | False | + +4. Click **Test** to validate the URLs, token, and connection. + +## Commands + +You can execute these commands from the Cortex XSOAR 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. + +### scout-api-usage + +*** +Returns all the information on used queries and remaining queries with the query limit. + +#### Base Command + +`scout-api-usage` + +#### Input + +There are no input arguments for this command. + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| TeamCymruScout.QueryUsage.command_name | String | The name of the Cortex XSOAR command that triggered the Foundation API. | +| TeamCymruScout.QueryUsage.used_queries | Number | The number of queries used. | +| TeamCymruScout.QueryUsage.remaining_queries | Number | The number of remaining queries. | +| TeamCymruScout.QueryUsage.query_limit | Number | The total number of queries allowed. | +| TeamCymruScout.QueryUsage.foundation_api_usage.used_queries | Number | The number of queries used for the Foundation API. | +| TeamCymruScout.QueryUsage.foundation_api_usage.remaining_queries | Number | The number of remaining queries for the Foundation API. | +| TeamCymruScout.QueryUsage.foundation_api_usage.query_limit | Number | The total number of queries allowed for the Foundation API. | + +#### Command example +```!scout-api-usage``` +#### Context Example +```json +{ + "TeamCymruScout": { + "QueryUsage": { + "command_name": "scout-api-usage", + "foundation_api_usage": { + "query_limit": 0, + "remaining_queries": 0, + "used_queries": 9 + }, + "query_limit": 50000, + "remaining_queries": 49834, + "used_queries": 166 + } + } +} +``` + +#### Human Readable Output + +>### API Usage +>|Used Queries|Remaining Queries|Query Limit|Foundation Used Queries|Foundation Remaining Queries|Foundation Query Limit| +>|---|---|---|---|---|---| +>| 166 | 49834 | 50000 | 9 | 0 | 0 | + + +### ip + +*** +Return all the detailed information available for the given IP address. + +#### Base Command + +`ip` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| ip | The IP address for which to retrieve available IP details. | Required | +| start_date | The start date for detailed information.

Supported formats: 2 days, 2 weeks, 2 months, yyyy-mm-dd.

For example: 01 June 2024, 2024-06-17. Default is 30 days. | Optional | +| end_date | The end date for detailed information.

Supported formats: 2 days, 2 weeks, 2 months, yyyy-mm-dd.

For example: 01 June 2024, 2024-06-17. Default is now. | Optional | +| days | Relative offset in days from the current time. It cannot exceed the maximum range of 30 days.

Note: This will take priority over start_date and end_date if all three are passed. | Optional | +| size | The maximum number of records to return.

Note: The maximum allowed size is 1000. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| DBotScore.Indicator | String | The indicator that was tested. | +| DBotScore.Type | String | The indicator type. | +| DBotScore.Vendor | String | The vendor used to calculate the score. | +| DBotScore.Score | Number | The actual score. | +| DBotScore.Reliability | String | Reliability of the source providing the intelligence data. | +| IP.Address | String | IP address. | +| IP.Relationships.EntityA | String | The source of the relationship. | +| IP.Relationships.EntityB | String | The destination of the relationship. | +| IP.Relationships.Relationship | String | The name of the relationship. | +| IP.Relationships.EntityAType | String | The type of the source of the relationship. | +| IP.Relationships.EntityBType | String | The type of the destination of the relationship. | +| IP.ASN | String | The autonomous system name for the IP address, for example: "AS8948". | +| IP.Hostname | String | The hostname that is mapped to this IP address. | +| IP.Geo.Location | String | The geolocation where the IP address is located, in the format: latitude:longitude. | +| IP.Geo.Country | String | The country in which the IP address is located. | +| IP.Geo.Description | String | Additional information about the location. | +| IP.DetectionEngines | Number | The total number of engines that checked the indicator. | +| IP.PositiveDetections | Number | The number of engines that positively detected the indicator as malicious. | +| IP.Malicious.Vendor | String | The vendor reporting the IP address as malicious. | +| IP.Malicious.Description | String | A description explaining why the IP address was reported as malicious. | +| IP.Tags | Unknown | \(List\) Tags of the IP address. | +| IP.FeedRelatedIndicators.value | String | Indicators that are associated with the IP address. | +| IP.FeedRelatedIndicators.type | String | The type of the indicators that are associated with the IP address. | +| IP.FeedRelatedIndicators.description | String | The description of the indicators that are associated with the IP address. | +| IP.MalwareFamily | String | The malware family associated with the IP address. | +| IP.Organization.Name | String | The organization of the IP address. | +| IP.Organization.Type | String | The organization type of the IP address. | +| IP.ASOwner | String | The autonomous system owner of the IP address. | +| IP.Region | String | The region in which the IP address is located. | +| IP.Port | String | Ports that are associated with the IP address. | +| IP.Internal | Boolean | Whether the IP address is internal or external. | +| IP.UpdatedDate | Date | The date that the IP address was last updated. | +| IP.Registrar.Abuse.Name | String | The name of the contact for reporting abuse. | +| IP.Registrar.Abuse.Address | String | The address of the contact for reporting abuse. | +| IP.Registrar.Abuse.Country | String | The country of the contact for reporting abuse. | +| IP.Registrar.Abuse.Network | String | The network of the contact for reporting abuse. | +| IP.Registrar.Abuse.Phone | String | The phone number of the contact for reporting abuse. | +| IP.Registrar.Abuse.Email | String | The email address of the contact for reporting abuse. | +| IP.Campaign | String | The campaign associated with the IP address. | +| IP.TrafficLightProtocol | String | The Traffic Light Protocol \(TLP\) color that is suitable for the IP address. | +| IP.CommunityNotes.note | String | Notes on the IP address that were given by the community. | +| IP.CommunityNotes.timestamp | Date | The time in which the note was published. | +| IP.Publications.source | String | The source in which the article was published. | +| IP.Publications.title | String | The name of the article. | +| IP.Publications.link | String | A link to the original article. | +| IP.Publications.timestamp | Date | The time in which the article was published. | +| IP.ThreatTypes.threatcategory | String | The threat category associated to this indicator by the source vendor. For example, Phishing, Control, TOR, etc. | +| IP.ThreatTypes.threatcategoryconfidence | String | The confidence level provided by the vendor for the threat type category For example, a confidence of 90 for the threat type category 'malware' means that the vendor rates that this is 90% confidence of being a malware. | +| TeamCymruScout.QueryUsage.request_id | String | The request ID of the API call. | +| TeamCymruScout.QueryUsage.size | Number | The number of records returned. | +| TeamCymruScout.QueryUsage.start_date | Date | The earliest date for detailed information. | +| TeamCymruScout.QueryUsage.end_date | Date | The latest date for detailed information. | +| TeamCymruScout.QueryUsage.used_queries | Number | The number of queries used. | +| TeamCymruScout.QueryUsage.remaining_queries | Number | The number of remaining queries. | +| TeamCymruScout.QueryUsage.query_limit | Number | The maximum number of queries allowed. | +| TeamCymruScout.QueryUsage.foundation_api_usage.used_queries | Number | The number of queries used by the Foundation API. | +| TeamCymruScout.QueryUsage.foundation_api_usage.remaining_queries | Number | The number of remaining queries for the Foundation API. | +| TeamCymruScout.QueryUsage.foundation_api_usage.query_limit | Numbe | The maximum number of queries allowed for the Foundation API. | +| TeamCymruScout.IP.ip | String | The IP address. | +| TeamCymruScout.IP.sections | String | The sections of data returned. | +| TeamCymruScout.IP.identity.tags | Unknown | The tags associated with the IP address. | +| TeamCymruScout.IP.identity.reverse_hostnames | Unknown | The reverse hostnames associated with the IP address. | +| TeamCymruScout.IP.identity.asn | Number | The autonomous system number associated with the IP address. | +| TeamCymruScout.IP.identity.as_name | String | The name associated with the autonomous system number. | +| TeamCymruScout.IP.identity.net_name | String | The name associated with the network. | +| TeamCymruScout.IP.identity.org_name | String | The name associated with the organization. | +| TeamCymruScout.IP.whois.modified | Date | The date the WHOIS information was last modified. | +| TeamCymruScout.IP.whois.asn | Number | The autonomous system number associated with the IP address. | +| TeamCymruScout.IP.whois.cidr | String | The network associated with the IP address. | +| TeamCymruScout.IP.whois.as_name | String | The name associated with the autonomous system number. | +| TeamCymruScout.IP.whois.bgp_asn | Number | The Border Gateway Protocol \(BGP\) autonomous system number \(ASN\) associated with the IP address. | +| TeamCymruScout.IP.whois.bgp_asn_name | String | The name associated with the Border Gateway Protocol \(BGP\) autonomous system number \(ASN\). | +| TeamCymruScout.IP.whois.net_name | String | The name associated with the network. | +| TeamCymruScout.IP.whois.net_handle | String | The handle associated with the network. | +| TeamCymruScout.IP.whois.description | String | The description associated with the network. | +| TeamCymruScout.IP.whois.cc | String | The country code associated with the network. | +| TeamCymruScout.IP.whois.city | String | The city associated with the network. | +| TeamCymruScout.IP.whois.address | String | The address associated with the network. | +| TeamCymruScout.IP.whois.abuse_contact_id | String | The abuse contact ID associated with the network. | +| TeamCymruScout.IP.whois.about_contact_role | String | The role associated with the about contact. | +| TeamCymruScout.IP.whois.about_contact_person | String | The person associated with the about contact. | +| TeamCymruScout.IP.whois.about_contact_email | String | The email associated with the about contact. | +| TeamCymruScout.IP.whois.about_contact_phone | String | The phone number associated with the about contact. | +| TeamCymruScout.IP.whois.about_contact_country | String | The country associated with the about contact. | +| TeamCymruScout.IP.whois.about_contact_city | String | The city associated with the about contact. | +| TeamCymruScout.IP.whois.about_contact_address | String | The address associated with the about contact. | +| TeamCymruScout.IP.whois.admin_contact_id | String | The ID associated with the admin contact. | +| TeamCymruScout.IP.whois.admin_contact_role | String | The role associated with the admin contact. | +| TeamCymruScout.IP.whois.admin_contact_person | String | The person associated with the admin contact. | +| TeamCymruScout.IP.whois.admin_contact_email | String | The email associated with the admin contact. | +| TeamCymruScout.IP.whois.admin_contact_phone | String | The phone number associated with the admin contact. | +| TeamCymruScout.IP.whois.admin_contact_country | String | The country associated with the admin contact. | +| TeamCymruScout.IP.whois.admin_contact_city | String | The city associated with the admin contact. | +| TeamCymruScout.IP.whois.admin_contact_address | String | The address associated with the admin contact. | +| TeamCymruScout.IP.whois.tech_contact_id | String | The ID associated with the tech contact. | +| TeamCymruScout.IP.whois.tech_contact_role | String | The role associated with the tech contact. | +| TeamCymruScout.IP.whois.tech_contact_person | String | The person associated with the tech contact. | +| TeamCymruScout.IP.whois.tech_contact_email | String | The email associated with the tech contact. | +| TeamCymruScout.IP.whois.tech_contact_phone | String | The phone number associated with the tech contact. | +| TeamCymruScout.IP.whois.tech_contact_country | String | The country associated with the tech contact. | +| TeamCymruScout.IP.whois.tech_contact_city | String | The city associated with the tech contact. | +| TeamCymruScout.IP.whois.tech_contact_address | String | The address associated with the tech contact. | +| TeamCymruScout.IP.whois.org_id | String | The ID associated with the organization. | +| TeamCymruScout.IP.whois.org_name | String | The name associated with the organization. | +| TeamCymruScout.IP.whois.org_email | String | The email associated with the organization. | +| TeamCymruScout.IP.whois.org_phone | String | The phone number associated with the organization. | +| TeamCymruScout.IP.whois.org_country | String | The country associated with the organization. | +| TeamCymruScout.IP.whois.org_city | String | The city associated with the organization. | +| TeamCymruScout.IP.whois.org_address | String | The address associated with the organization. | +| TeamCymruScout.IP.whois.mnt_by_email | String | The email associated with the maintainer. | +| TeamCymruScout.IP.whois.mnt_lower_email | String | The email associated with the lower maintenance router. | +| TeamCymruScout.IP.whois.mnt_router_email | String | The email associated with the maintenance router. | +| TeamCymruScout.IP.communications.event_count | Number | The count of events associated with the communication. | +| TeamCymruScout.IP.communications.peers.proto | Number | The protocol associated with the peer. | +| TeamCymruScout.IP.communications.peers.proto_text | String | The text associated with the protocol of the peer. | +| TeamCymruScout.IP.communications.peers.local.ip | String | The IP address associated with the local peer. | +| TeamCymruScout.IP.communications.peers.local.min_port | Number | The minimum port associated with the local peer. | +| TeamCymruScout.IP.communications.peers.local.max_port | Number | The maximum port associated with the local peer. | +| TeamCymruScout.IP.communications.peers.local.country_codes | String | The country codes associated with the local peer. | +| TeamCymruScout.IP.communications.peers.local.as_info.asn | Number | The autonomous system number associated with the local peer. | +| TeamCymruScout.IP.communications.peers.local.as_info.as_name | String | The name associated with the autonomous system number of the local peer. | +| TeamCymruScout.IP.communications.peers.local.tags.id | Number | The ID of the tags associated with the local peer. | +| TeamCymruScout.IP.communications.peers.local.tags.name | String | The name of the tags associated with the local peer. | +| TeamCymruScout.IP.communications.peers.local.tags.children.id | Number | The ID of the child tags associated with the local peer. | +| TeamCymruScout.IP.communications.peers.local.tags.children.name | String | The name of the child tags associated with the local peer. | +| TeamCymruScout.IP.communications.peers.local.tags.children.children | Unknown | The children of the child tags associated with the local peer. | +| TeamCymruScout.IP.communications.peers.local.unique_ports | Number | The unique ports associated with the local peer. | +| TeamCymruScout.IP.communications.peers.local.top_services.service_name | String | The name of the top service associated with the local peer. | +| TeamCymruScout.IP.communications.peers.local.top_services.port | Number | The port associated with the top service of the local peer. | +| TeamCymruScout.IP.communications.peers.local.top_services.proto_number | Number | The protocol number associated with the top service of the local peer. | +| TeamCymruScout.IP.communications.peers.local.top_services.description | String | The description associated with the top service of the local peer. | +| TeamCymruScout.IP.communications.peers.peer.ip | String | The IP address associated with the peer. | +| TeamCymruScout.IP.communications.peers.peer.min_port | Number | The minimum port associated with the peer. | +| TeamCymruScout.IP.communications.peers.peer.max_port | Number | The maximum port associated with the peer. | +| TeamCymruScout.IP.communications.peers.peer.country_codes | String | The country codes associated with the peer. | +| TeamCymruScout.IP.communications.peers.peer.as_info.asn | Number | The autonomous system number associated with the peer. | +| TeamCymruScout.IP.communications.peers.peer.as_info.as_name | String | The name associated with the autonomous system number of the peer. | +| TeamCymruScout.IP.communications.peers.peer.tags | Unknown | The tags associated with the peer. | +| TeamCymruScout.IP.communications.peers.peer.unique_ports | Number | The unique ports associated with the peer. | +| TeamCymruScout.IP.communications.peers.peer.top_services.service_name | String | The name of the top service associated with the peer. | +| TeamCymruScout.IP.communications.peers.peer.top_services.port | Number | The port associated with the top service of the peer. | +| TeamCymruScout.IP.communications.peers.peer.top_services.proto_number | Number | The protocol number associated with the top service of the peer. | +| TeamCymruScout.IP.communications.peers.peer.top_services.description | String | The description associated with the top service of the peer. | +| TeamCymruScout.IP.communications.peers.event_count | Number | The number of events associated with the communication. | +| TeamCymruScout.IP.communications.peers.first_seen | Date | The first seen date associated with the communication. | +| TeamCymruScout.IP.communications.peers.last_seen | Date | The last seen date associated with the communication. | +| TeamCymruScout.IP.communications.peers.peer.tags.id | Number | The ID of the tags associated with the peer. | +| TeamCymruScout.IP.communications.peers.peer.tags.name | String | The name of the tags associated with the peer. | +| TeamCymruScout.IP.communications.peers.peer.tags.children.id | Number | The ID of the child tags associated with the peer. | +| TeamCymruScout.IP.communications.peers.peer.tags.children.name | String | The name of the child tags associated with the peer. | +| TeamCymruScout.IP.communications.peers.peer.tags.children.children.id | Number | The ID of the grandchild tags associated with the peer. | +| TeamCymruScout.IP.communications.peers.peer.tags.children.children.name | String | The name of the grandchild tags associated with the peer. | +| TeamCymruScout.IP.communications.peers.peer.tags.children.children.children | Unknown | The children of the grandchild tags associated with the peer. | +| TeamCymruScout.IP.communications.peers.peer.tags.children.children | Unknown | The grandchild tags associated with the peer. | +| TeamCymruScout.IP.communications.peers.peer.tags.children | Unknown | The child tags associated with the peer. | +| TeamCymruScout.IP.pdns.event_count | Number | The number of events associated with the PDNS. | +| TeamCymruScout.IP.pdns.pdns.ip | String | The IP address associated with the PDNS. | +| TeamCymruScout.IP.pdns.pdns.domain | String | The domain associated with the PDNS. | +| TeamCymruScout.IP.pdns.pdns.root | String | The root associated with the PDNS. | +| TeamCymruScout.IP.pdns.pdns.tld | String | The top level domain \(TLD\) associated with the PDNS. | +| TeamCymruScout.IP.pdns.pdns.type | String | The type associated with the PDNS. | +| TeamCymruScout.IP.pdns.pdns.registrar | String | The registrar associated with the PDNS. | +| TeamCymruScout.IP.pdns.pdns.domain_created | Date | The creation date associated with the PDNS. | +| TeamCymruScout.IP.pdns.pdns.domain_expires | Date | The expiration date associated with the PDNS. | +| TeamCymruScout.IP.pdns.pdns.nameservers.root | String | The root of the nameserver associated with the PDNS. | +| TeamCymruScout.IP.pdns.pdns.nameservers.nameservers | String | The nameservers associated with the PDNS. | +| TeamCymruScout.IP.pdns.pdns.country_codes | String | The country codes associated with the PDNS. | +| TeamCymruScout.IP.pdns.pdns.as_info.asn | Number | The autonomous system number associated with the PDNS. | +| TeamCymruScout.IP.pdns.pdns.as_info.as_name | String | The name associated with the autonomous system number of the PDNS. | +| TeamCymruScout.IP.pdns.pdns.tags | Unknown | The tags associated with the PDNS. | +| TeamCymruScout.IP.pdns.pdns.distinct_ips | Number | The number of distinct IP addresses associated with the PDNS. | +| TeamCymruScout.IP.pdns.pdns.active_days | Number | The number of active days associated with the PDNS. | +| TeamCymruScout.IP.pdns.pdns.event_count | Number | The count of events associated with the PDNS. | +| TeamCymruScout.IP.pdns.pdns.first_seen | Date | The first date the PDNS was seen. | +| TeamCymruScout.IP.pdns.pdns.last_seen | Date | The last date the PDNS was seen. | +| TeamCymruScout.IP.pdns.pdns.nameservers | Unknown | The nameservers of the PDNS. | +| TeamCymruScout.IP.fingerprints.event_count | Number | The number of events associated with the fingerprints. | +| TeamCymruScout.IP.fingerprints.fingerprints.ip | String | The IP address of the fingerprint. | +| TeamCymruScout.IP.fingerprints.fingerprints.type | String | The type of the fingerprint. | +| TeamCymruScout.IP.fingerprints.fingerprints.fingerprint | String | The fingerprint of the host. | +| TeamCymruScout.IP.fingerprints.fingerprints.port | Number | The port of the fingerprint. | +| TeamCymruScout.IP.fingerprints.fingerprints.first_seen | Date | The first date the fingerprint was seen. | +| TeamCymruScout.IP.fingerprints.fingerprints.last_seen | Date | The last date the fingerprint was seen. | +| TeamCymruScout.IP.fingerprints.fingerprints.distinct_ips | Number | The number of distinct IP addresses associated with the fingerprints. | +| TeamCymruScout.IP.fingerprints.fingerprints.active_days | Number | The number of active days associated with the fingerprints. | +| TeamCymruScout.IP.fingerprints.fingerprints.event_count | Number | The number of events associated with the fingerprints. | +| TeamCymruScout.IP.open_ports.event_count | Number | The number of events associated with the open ports. | +| TeamCymruScout.IP.open_ports.unique_ports | Number | The number of unique ports in the open ports. | +| TeamCymruScout.IP.open_ports.open_ports.ip | String | The IP address of the open port. | +| TeamCymruScout.IP.open_ports.open_ports.port | Number | The port of the open port. | +| TeamCymruScout.IP.open_ports.open_ports.protocol | Number | The protocol of the open port. | +| TeamCymruScout.IP.open_ports.open_ports.protocol_text | String | The protocol text of the open port. | +| TeamCymruScout.IP.open_ports.open_ports.service | String | The service of the open port. | +| TeamCymruScout.IP.open_ports.open_ports.banner | String | The banner of the open port. | +| TeamCymruScout.IP.open_ports.open_ports.banner_sha1 | String | The SHA1 hash of the banner of the open port. | +| TeamCymruScout.IP.open_ports.open_ports.first_seen | Date | The first date the open port was seen. | +| TeamCymruScout.IP.open_ports.open_ports.last_seen | Date | The last date the open port was seen. | +| TeamCymruScout.IP.open_ports.open_ports.country_codes | String | The country codes of the open port. | +| TeamCymruScout.IP.open_ports.open_ports.as_info.asn | Number | The autonomous system number of the open port. | +| TeamCymruScout.IP.open_ports.open_ports.as_info.as_name | String | The name of the autonomous system number of the open port. | +| TeamCymruScout.IP.open_ports.open_ports.tags.id | Number | The ID of the tag associated with the open port. | +| TeamCymruScout.IP.open_ports.open_ports.tags.name | String | The name of the tag associated with the open port. | +| TeamCymruScout.IP.open_ports.open_ports.tags.children.id | Number | The ID of the child tag associated with the open port. | +| TeamCymruScout.IP.open_ports.open_ports.tags.children.name | String | The name of the child tag associated with the open port. | +| TeamCymruScout.IP.open_ports.open_ports.tags.children.children | Unknown | The child tags of the child tag associated with the open port. | +| TeamCymruScout.IP.open_ports.open_ports.event_count | Number | The number of events associated with the open port. | +| TeamCymruScout.IP.x509.event_count | Number | The number of events associated with the x509 certificate. | +| TeamCymruScout.IP.x509.x509.ip | String | The IP address associated with the x509 certificate. | +| TeamCymruScout.IP.x509.x509.issuer | String | The issuer of the x509 certificate. | +| TeamCymruScout.IP.x509.x509.issuer_common_name | String | The common name of the issuer of the x509 certificate. | +| TeamCymruScout.IP.x509.x509.common_name | String | The common name of the x509 certificate. | +| TeamCymruScout.IP.x509.x509.altnames | String | The alternative names associated with the x509 certificate. | +| TeamCymruScout.IP.x509.x509.serial | String | The serial number of the x509 certificate. | +| TeamCymruScout.IP.x509.x509.subject | String | The subject of the x509 certificate. | +| TeamCymruScout.IP.x509.x509.not_after | Date | The expiration date of the x509 certificate. | +| TeamCymruScout.IP.x509.x509.not_before | Date | The start date of the x509 certificate. | +| TeamCymruScout.IP.x509.x509.validity_period | String | The validity period of the x509 certificate. | +| TeamCymruScout.IP.x509.x509.md5 | String | The MD5 hash of the x509 certificate. | +| TeamCymruScout.IP.x509.x509.sha1 | String | The SHA1 hash of the x509 certificate. | +| TeamCymruScout.IP.x509.x509.sha256 | String | The SHA256 hash of the x509 certificate. | +| TeamCymruScout.IP.x509.x509.first_seen | Date | The first date the x509 certificate was seen. | +| TeamCymruScout.IP.x509.x509.last_seen | Date | The last date the x509 certificate was seen. | +| TeamCymruScout.IP.x509.x509.port | Number | The port associated with the x509 certificate. | +| TeamCymruScout.IP.x509.x509.self_signed | Boolean | Indicates whether the x509 certificate is self-signed. | +| TeamCymruScout.IP.x509.x509.country_codes | String | The country codes associated with the x509 certificate. | +| TeamCymruScout.IP.x509.x509.as_info.asn | Number | The autonomous system number associated with the x509 certificate. | +| TeamCymruScout.IP.x509.x509.as_info.as_name | String | The autonomous system name associated with the x509 certificate. | +| TeamCymruScout.IP.x509.x509.tags.id | Number | The ID of the tag associated with the x509 certificate. | +| TeamCymruScout.IP.x509.x509.tags.name | String | The name of the tag associated with the x509 certificate. | +| TeamCymruScout.IP.x509.x509.tags.children.id | Number | The ID of the child tag associated with the x509 certificate. | +| TeamCymruScout.IP.x509.x509.tags.children.name | String | The name of the child tag associated with the x509 certificate. | +| TeamCymruScout.IP.x509.x509.tags.children.children | Unknown | The children of the child tag associated with the x509 certificate. | +| TeamCymruScout.IP.x509.x509.count | Number | The count of the x509 certificate. | +| TeamCymruScout.IP.summary.total | Number | The total count of the summary. | +| TeamCymruScout.IP.summary.ip | String | The IP address associated with the summary. | +| TeamCymruScout.IP.summary.start_date | Date | The start date of the summary. | +| TeamCymruScout.IP.summary.end_date | Date | The end date of the summary. | +| TeamCymruScout.IP.summary.geo_ip_cc | String | The country code associated with the geographic IP. | +| TeamCymruScout.IP.summary.tags.id | Number | The ID of the tag associated with the summary. | +| TeamCymruScout.IP.summary.tags.name | String | The name of the tag associated with the summary. | +| TeamCymruScout.IP.summary.tags.children.id | Number | The ID of the child tag associated with the summary. | +| TeamCymruScout.IP.summary.tags.children.name | String | The name of the child tag associated with the summary. | +| TeamCymruScout.IP.summary.tags.children.children | Unknown | The children of the child tag associated with the summary. | +| TeamCymruScout.IP.summary.reverse_hostnames | Unknown | The reverse hostnames associated with the summary. | +| TeamCymruScout.IP.summary.bgp_asn | Number | The autonomous system number associated with the BGP. | +| TeamCymruScout.IP.summary.bgp_asname | String | The autonomous system name associated with the BGP. | +| TeamCymruScout.IP.summary.whois.asn | Number | The autonomous system number associated with the IP address. | +| TeamCymruScout.IP.summary.whois.as_name | String | The name associated with the autonomous system number. | +| TeamCymruScout.IP.summary.whois.net_name | String | The name associated with the network. | +| TeamCymruScout.IP.summary.whois.org_name | String | The name associated with the organization. | +| TeamCymruScout.IP.summary.pdns.total | Number | The total count of the DNS queries associated with the IP address. | +| TeamCymruScout.IP.summary.pdns.top_pdns.event_count | Number | The number of events associated with the top DNS query. | +| TeamCymruScout.IP.summary.pdns.top_pdns.domain | String | The domain associated with the top DNS query. | +| TeamCymruScout.IP.summary.pdns.top_pdns.first_seen | Date | The first date the top DNS query was seen. | +| TeamCymruScout.IP.summary.pdns.top_pdns.last_seen | Date | The last date the top DNS query was seen. | +| TeamCymruScout.IP.summary.pdns.top_pdns.css_color | String | The CSS color associated with the top DNS query. | +| TeamCymruScout.IP.summary.open_ports.total | Number | The total number of the open ports associated with the IP address. | +| TeamCymruScout.IP.summary.open_ports.unique_ports | Number | The number of unique ports in the open ports. | +| TeamCymruScout.IP.summary.open_ports.top_open_ports.event_count | Number | The number of events associated with the top open port. | +| TeamCymruScout.IP.summary.open_ports.top_open_ports.port | Number | The port associated with the top open port. | +| TeamCymruScout.IP.summary.open_ports.top_open_ports.protocol | Number | The protocol number associated with the top open port. | +| TeamCymruScout.IP.summary.open_ports.top_open_ports.protocol_text | String | The protocol text associated with the top open port. | +| TeamCymruScout.IP.summary.open_ports.top_open_ports.service | String | The service associated with the top open port. | +| TeamCymruScout.IP.summary.open_ports.top_open_ports.inferred_service_name | Unknown | The inferred service name associated with the top open port. | +| TeamCymruScout.IP.summary.open_ports.top_open_ports.first_seen | Date | The first date the top open port was seen. | +| TeamCymruScout.IP.summary.open_ports.top_open_ports.last_seen | Date | The last date the top open port was seen. | +| TeamCymruScout.IP.summary.open_ports.top_open_ports.css_color | String | The CSS color associated with the top open port. | +| TeamCymruScout.IP.summary.certs.top_certs.issuer | String | The issuer of the certificate. | +| TeamCymruScout.IP.summary.certs.top_certs.issuer_common_name | String | The common name of the issuer of the certificate. | +| TeamCymruScout.IP.summary.certs.top_certs.common_name | String | The common name of the certificate. | +| TeamCymruScout.IP.summary.certs.top_certs.subject | String | The subject of the certificate. | +| TeamCymruScout.IP.summary.certs.top_certs.port | Number | The port associated with the certificate. | +| TeamCymruScout.IP.summary.certs.top_certs.first_seen | Date | The first date the certificate was seen. | +| TeamCymruScout.IP.summary.certs.top_certs.last_seen | Date | The last date the certificate was seen. | +| TeamCymruScout.IP.summary.certs.top_certs.self_signed | Boolean | Indicates whether the certificate is self-signed. | +| TeamCymruScout.IP.summary.certs.top_certs.not_before | Date | The date before which the certificate is not valid. | +| TeamCymruScout.IP.summary.certs.top_certs.not_after | Date | The date after which the certificate is not valid. | +| TeamCymruScout.IP.summary.certs.top_certs.valid_days | Number | The number of valid days for the certificate. | +| TeamCymruScout.IP.summary.certs.top_certs.md5 | String | The MD5 hash of the certificate. | +| TeamCymruScout.IP.summary.certs.top_certs.sha1 | String | The SHA1 hash of the certificate. | +| TeamCymruScout.IP.summary.certs.top_certs.sha256 | String | The SHA256 hash of the certificate. | +| TeamCymruScout.IP.summary.certs.top_certs.css_color | String | The CSS color associated with the certificate. | +| TeamCymruScout.IP.summary.tag_timeline.data.tag.id | Number | The ID of the tag. | +| TeamCymruScout.IP.summary.tag_timeline.data.tag.name | String | The name of the tag. | +| TeamCymruScout.IP.summary.tag_timeline.data.tag.description | String | The description of the tag. | +| TeamCymruScout.IP.summary.tag_timeline.data.tag.parent_ids | Number | The parent IDs of the tag. | +| TeamCymruScout.IP.summary.tag_timeline.data.tag.css_color | String | The CSS color associated with the tag. | +| TeamCymruScout.IP.summary.tag_timeline.data.tag.parents | Unknown | The parents of the tag. | +| TeamCymruScout.IP.summary.tag_timeline.data.first_seen | Date | The first date the tag was seen. | +| TeamCymruScout.IP.summary.tag_timeline.data.last_seen | Date | The last date the tag was seen. | +| TeamCymruScout.IP.summary.tag_timeline.data.tag.parents.id | Number | The ID of the parent tag. | +| TeamCymruScout.IP.summary.tag_timeline.data.tag.parents.name | String | The name of the parent tag. | +| TeamCymruScout.IP.summary.tag_timeline.data.tag.parents.description | String | The description of the parent tag. | +| TeamCymruScout.IP.summary.tag_timeline.data.tag.parents.parent_ids | Unknown | The parent IDs of the parent tag. | +| TeamCymruScout.IP.summary.tag_timeline.data.tag.parents.css_color | String | The CSS color associated with the parent tag. | +| TeamCymruScout.IP.summary.tag_timeline.data.tag.parents.parents | Unknown | The parents of the parent tag. | +| TeamCymruScout.IP.summary.insights.overall_rating | String | The overall rating of the insights. | +| TeamCymruScout.IP.summary.insights.total | Number | The total count of the insights. | +| TeamCymruScout.IP.summary.insights.insights.rating | String | The rating of the insight. | +| TeamCymruScout.IP.summary.insights.insights.message | String | The message of the insight. | +| TeamCymruScout.IP.summary.fingerprints.top_fingerprints.type | String | The type of the fingerprint. | +| TeamCymruScout.IP.summary.fingerprints.top_fingerprints.signature | String | The signature of the fingerprint. | +| TeamCymruScout.IP.summary.fingerprints.top_fingerprints.port | Number | The port associated with the fingerprint. | +| TeamCymruScout.IP.summary.fingerprints.top_fingerprints.first_seen | Date | The first date the fingerprint was seen. | +| TeamCymruScout.IP.summary.fingerprints.top_fingerprints.last_seen | Date | The last date the fingerprint was seen. | +| TeamCymruScout.IP.summary.fingerprints.top_fingerprints.count | Number | The count of the fingerprint. | + +#### Command example +```!ip ip=0.0.0.1``` +#### Context Example +```json +{ + "DBotScore": { + "Indicator": "0.0.0.1", + "Reliability": "A - Completely reliable", + "Score": 2, + "Type": "ip", + "Vendor": "Team Cymru Scout" + }, + "IP": { + "ASN": 15133, + "ASOwner": "test_name", + "Address": "0.0.0.1", + "Description": "[\"data-03-EU-93-184-216-0-24\"]", + "Organization": { + "Name": "test_name Inc." + }, + "Port": "443, 80", + "Region": "EU", + "Relationships": [ + { + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "0.0.0.2", + "EntityBType": "IP", + "Relationship": "communicated-with" + } + ], + "Tags": "cdn: (test_name)", + "UpdatedDate": "2012-06-22" + }, + "TeamCymruScout": { + "IP": { + "ip": "0.0.0.1", + "sections": [ + "identity", + "comms", + "pdns", + "open_ports", + "x509", + "fingerprints", + "whois", + "summary" + ], + "identity": { + "asn": 15133, + "as_name": "test_name", + "net_name": "test_name-data-03", + "org_name": "test_name Inc." + }, + "whois": { + "modified": "2012-06-22", + "asn": 15133, + "cidr": "0.0.0.1/24", + "as_name": "test_name", + "bgp_asn": 15133, + "bgp_asn_name": "test_name, US", + "net_name": "test_name-data-03", + "net_handle": "", + "description": "[\"data-03-EU-93-184-216-0-24\"]", + "cc": "EU", + "city": "", + "address": "", + "abuse_contact_id": "", + "about_contact_role": "", + "about_contact_person": "", + "about_contact_email": "", + "about_contact_phone": "", + "about_contact_country": "", + "about_contact_city": "", + "about_contact_address": "", + "admin_contact_id": "DS7892-RIPE", + "admin_contact_role": "", + "admin_contact_person": "Derrick Sawyer", + "admin_contact_email": "", + "admin_contact_phone": "+18123456789", + "admin_contact_country": "", + "admin_contact_city": "", + "admin_contact_address": "[\"11811 N. Tatum Blvd, Suite 3031, Phoenix, AZ 85028\"]", + "tech_contact_id": "DS7892-RIPE", + "tech_contact_role": "", + "tech_contact_person": "Derrick Sawyer", + "tech_contact_email": "", + "tech_contact_phone": "+18987654321", + "tech_contact_country": "", + "tech_contact_city": "", + "tech_contact_address": "[\"11811 N. Tatum Blvd, Suite 3031, Phoenix, AZ 85028\"]", + "org_id": "", + "org_name": "test_name Inc.", + "org_email": "", + "org_phone": "", + "org_country": "", + "org_city": "", + "org_address": "", + "mnt_by_email": "", + "mnt_lower_email": "", + "mnt_router_email": "" + }, + "communications": { + "event_count": 33264, + "peers": [ + { + "proto": 6, + "proto_text": "TCP", + "local": { + "ip": "0.0.0.1", + "min_port": 80, + "max_port": 80, + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "test_name, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name" + } + ] + } + ], + "unique_ports": 1, + "top_services": [ + { + "service_name": "http", + "port": 80, + "proto_number": 6, + "description": "World Wide Web HTTP" + } + ] + }, + "peer": { + "ip": "0.0.0.2", + "min_port": 52049, + "max_port": 64552, + "country_codes": [ + "ZA" + ], + "as_info": [ + { + "asn": 327983, + "as_name": "Interworks-Wireless-Solutions, ZA" + } + ], + "unique_ports": 3669, + "top_services": [ + { + "service_name": "", + "port": 64552, + "proto_number": 6, + "description": "" + } + ] + }, + "event_count": 6040, + "first_seen": "2024-06-04", + "last_seen": "2024-06-04" + } + ] + }, + "pdns": { + "event_count": 1338, + "pdns": [ + { + "ip": "0.0.0.1", + "domain": "test1.aaa", + "root": "test1.aaa", + "tld": "aaa", + "type": "A", + "registrar": "PDR Ltd. d/b/a test1.com", + "domain_created": "2023-03-03", + "domain_expires": "2025-03-03", + "nameservers": [ + { + "root": "test1.com.br", + "nameservers": [ + "ns1036.test1.com.br", + "ns1037.test1.com.br" + ] + } + ], + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "" + } + ], + "distinct_ips": 1, + "active_days": 20, + "event_count": 78, + "first_seen": "2024-05-27", + "last_seen": "2024-06-25" + } + ] + }, + "fingerprints": { + "event_count": 5, + "fingerprints": [ + { + "ip": "0.0.0.1", + "type": "jarm", + "fingerprint": "testsignature", + "port": 443, + "first_seen": "2024-05-30", + "last_seen": "2024-06-21", + "distinct_ips": 830, + "active_days": 5, + "event_count": 5 + } + ] + }, + "open_ports": { + "event_count": 2, + "unique_ports": 2, + "open_ports": [ + { + "ip": "0.0.0.1", + "port": 443, + "protocol": 6, + "protocol_text": "TCP", + "service": "https", + "banner": "TLS/1.1 cipher:0xc013, www.example.org, www.example.org, example.net, example.edu, example.com, example.org, www.example.com, www.example.edu, www.example.net", + "banner_sha1": "test_sha1", + "first_seen": "2024-05-30", + "last_seen": "2024-06-21", + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "test_name, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name" + } + ] + } + ], + "event_count": 5 + } + ] + }, + "x509": { + "event_count": 5, + "x509": [ + { + "ip": "0.0.0.1", + "issuer": "CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1, O=DigiCert Inc, C=US", + "issuer_common_name": "DigiCert Global G2 TLS RSA SHA256 2020 CA1", + "common_name": "www.example.org", + "altnames": [ + "example.com", + "example.edu", + "example.net", + "example.org", + "www.example.com", + "www.example.edu", + "www.example.net", + "www.example.org" + ], + "serial": "testserial", + "subject": "CN=www.example.org, O=Internet Corporation for Assigned Names and Numbers.", + "not_after": "2025-03-01", + "not_before": "2024-01-30", + "validity_period": "397 Days", + "md5": "testmd5", + "sha1": "testsha1", + "sha256": "testsha256", + "first_seen": "2024-05-30", + "last_seen": "2024-06-21", + "port": 443, + "self_signed": false, + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "test_name, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name" + } + ] + } + ], + "count": 5 + } + ] + }, + "summary": { + "total": 1, + "ip": "0.0.0.1", + "start_date": "2024-05-27", + "end_date": "2024-06-25", + "geo_ip_cc": "US", + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name" + } + ] + } + ], + "bgp_asn": 15133, + "bgp_asname": "test_name, US", + "whois": { + "asn": 15133, + "as_name": "test_name", + "net_name": "test_name-data-03", + "org_name": "test_name Inc." + }, + "pdns": { + "total": 1338, + "top_pdns": [ + { + "event_count": 78, + "domain": "test1.aaa", + "first_seen": "2024-05-27", + "last_seen": "2024-06-25", + "css_color": "#a6abb7" + } + ] + }, + "open_ports": { + "total": 2, + "unique_ports": 2, + "top_open_ports": [ + { + "event_count": 53, + "port": 80, + "protocol": 6, + "protocol_text": "TCP", + "service": "http", + "first_seen": "2024-05-27", + "last_seen": "2024-06-25", + "css_color": "#a6abb7" + } + ] + }, + "certs": { + "top_certs": [ + { + "issuer": "CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1, O=DigiCert Inc, C=US", + "issuer_common_name": "DigiCert Global G2 TLS RSA SHA256 2020 CA1", + "common_name": "www.example.org", + "subject": "CN=www.example.org, O=Internet Corporation for Assigned Names and Numbers.", + "port": 443, + "first_seen": "2024-05-30", + "last_seen": "2024-06-21", + "self_signed": false, + "not_before": "2024-01-30", + "not_after": "2025-03-01", + "valid_days": 397, + "md5": "testmd5", + "sha1": "testsha1", + "sha256": "testsha256", + "css_color": "#b382d9" + } + ] + }, + "tag_timeline": { + "data": [ + { + "tag": { + "id": 176, + "name": "cdn", + "description": "The CDN tag characterizes IP addresses associated with Content Delivery Networks (CDNs).", + "css_color": "#8A532C" + }, + "first_seen": "2024-05-27", + "last_seen": "2024-06-25" + } + ] + }, + "insights": { + "overall_rating": "suspicious", + "total": 8, + "insights": [ + { + "rating": "no_rating", + "message": "x509 subject \"CN=www.example.org, O=Internet Corporation for Assigned Names and Numbers." + } + ] + }, + "fingerprints": { + "top_fingerprints": [ + { + "type": "jarm", + "signature": "testsignature", + "port": 443, + "first_seen": "2024-05-30", + "last_seen": "2024-06-21", + "count": 5 + } + ] + } + } + }, + "QueryUsage": { + "command_name": "ip", + "foundation_api_usage": { + "query_limit": 0, + "remaining_queries": 0, + "used_queries": 15 + }, + "query_limit": 50000, + "remaining_queries": 49739, + "request_id": "test_id", + "size": 1000, + "start_date": "2024-05-27", + "end_date": "2024-06-25", + "used_queries": 261 + } + } +} +``` + +#### Human Readable Output + +>### Summary Information For The Given Suspicious IP: [0.0.0.1](https://scout.cymru.com/scout/details?query=0.0.0.1) +>|Country Code|Whois|Tags|Insights| +>|---|---|---|---| +>| US | ***asn***: 15133
***as_name***: test_name
***net_name***: test_name-data-03
***org_name***: test_name Inc. | **-** ***id***: 176
***name***: cdn
**children**:
**-** ***id***: 206
***name***: test_name | **-** ***rating***: no_rating
***message***: x509 subject "CN=www.example.org, O=Internet Corporation for Assigned Names and Numbers. | +> +>### Top PDNS +>|Domain|Event Count|First Seen|Last Seen| +>|---|---|---|---| +>| test1.aaa | 78 | 2024-05-27 | 2024-06-25 | +> +>### Top Peers +>|Proto|Client IP|Client Country Code(s)|Client Services|Server IP|Server Country Code(s)|Server Tag(s)|Server Services|Event Count|First Seen|Last Seen|Client AS Name|Server AS Name| +>|---|---|---|---|---|---|---|---|---|---|---|---|---| +>| TCP | 0.0.0.2 | ZA | **-** ***port***: 64552
***proto_number***: 6 | 0.0.0.1 | US | cdn: (test_name) | **-** ***service_name***: http
***port***: 80
***proto_number***: 6
***description***: World Wide Web HTTP | 6040 | 2024-06-04 | 2024-06-04 | Interworks-Wireless-Solutions, ZA | test_name, US | +> +>### Top Open Ports +>|Event Count|Port|Protocol|Protocol Text|Service|First Seen|Last Seen| +>|---|---|---|---|---|---|---| +>| 53 | 80 | 6 | TCP | http | 2024-05-27 | 2024-06-25 | +> +>### Top Fingerprints +>|Count|First Seen|Last Seen|Port|Signature|Type| +>|---|---|---|---|---|---| +>| 5 | 2024-05-30 | 2024-06-21 | 443 | testsignature | jarm | +> +>### Top Certificates +>|Common Name|First Seen|Issuer|Issuer Common Name|Last Seen|Md5|Not After|Not Before|Port|Self Signed|Sha1|Sha256|Subject|Valid Days| +>|---|---|---|---|---|---|---|---|---|---|---|---|---|---| +>| www.example.org | 2024-05-30 | CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1, O=DigiCert Inc, C=US | DigiCert Global G2 TLS RSA SHA256 2020 CA1 | 2024-06-21 | testmd5 | 2025-03-01 | 2024-01-30 | 443 | false | testsha1 | testsha256 | CN=www.example.org, O=Internet Corporation for Assigned Names and Numbers. | 397 | + +### scout-indicator-search + +*** +Return the summary information available for the given domain or IP address using Scout query language. + +#### Base Command + +`scout-indicator-search` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| query | A simple or advanced Scout query which may contain the domain or IP address.

For example: comms.ip="0.0.0.1/24". | Required | +| start_date | The start date to filter indicators.

Supported formats: 2 days, 2 weeks, 2 months, yyyy-mm-dd.

For example: 01 June 2024, 2024-06-17. Default is 30 days. | Optional | +| end_date | The end date to filter indicators.

Supported formats: 2 days, 2 weeks, 2 months, yyyy-mm-dd.

For example: 01 June 2024, 2024-06-17. Default is now. | Optional | +| days | Relative offset in days from current time. It cannot exceed the maximum range of 30 days.

Note: This will take priority over start_date and end_date if all three are passed. | Optional | +| size | The maximum number of indicators to fetch.

Note: The maximum allowed size is 5000. Default is 20. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| TeamCymruScout.IP.ip | String | The IP address. | +| TeamCymruScout.IP.country_codes | String | The country code\(s\). | +| TeamCymruScout.IP.as_info.asn | Number | The autonomous system number. | +| TeamCymruScout.IP.as_info.as_name | String | The autonomous system name. | +| TeamCymruScout.IP.tags.id | Number | The ID of the tag. | +| TeamCymruScout.IP.tags.name | String | The name of the tag. | +| TeamCymruScout.IP.tags.children.id | Number | The ID of the child tag. | +| TeamCymruScout.IP.tags.children.name | String | The name of the child tag. | +| TeamCymruScout.IP.tags.children.children | Unknown | The children of the child tag. | +| TeamCymruScout.IP.event_count | Number | The number of events related to the IP address. | +| TeamCymruScout.IP.summary.last_seen | Date | The last time the IP was seen. | +| TeamCymruScout.IP.summary.whois.asn | Number | The autonomous system number associated with the IP. | +| TeamCymruScout.IP.summary.whois.as_name | String | The name of the autonomous system associated with the IP. | +| TeamCymruScout.IP.summary.whois.net_name | String | The network name associated with the IP. | +| TeamCymruScout.IP.summary.whois.org_name | String | The organization name associated with the IP. | +| TeamCymruScout.IP.summary.open_ports.ip | String | The IP address associated with the open port. | +| TeamCymruScout.IP.summary.open_ports.port | Number | The port number associated with the open port. | +| TeamCymruScout.IP.summary.open_ports.protocol | Number | The protocol number associated with the open port. | +| TeamCymruScout.IP.summary.open_ports.protocol_text | String | The protocol name associated with the open port. | +| TeamCymruScout.IP.summary.open_ports.service | String | The service name associated with the open port. | +| TeamCymruScout.IP.summary.open_ports.event_count | Number | The number of events related to the open port. | +| TeamCymruScout.IP.summary.pdns.ip | String | The IP address associated with the domain. | +| TeamCymruScout.IP.summary.pdns.domain | String | The domain associated with the IP. | +| TeamCymruScout.IP.summary.pdns.event_count | Number | The number of events related to the domain. | +| TeamCymruScout.IP.summary.top_peers.ip | String | The IP address of the top peer. | +| TeamCymruScout.IP.summary.top_peers.event_count | Number | The number of events related to the top peer. | +| TeamCymruScout.IP.summary.comms_total | Number | The total number of communications related to the IP address. | +| TeamCymruScout.IP.summary.service_counts.proto | Number | The protocol number associated with the service count. | +| TeamCymruScout.IP.summary.service_counts.proto_text | String | The protocol name associated with the service count. | +| TeamCymruScout.IP.summary.service_counts.port | Number | The port number associated with the service count. | +| TeamCymruScout.IP.summary.service_counts.event_count | Number | The number of events related to the service count. | +| TeamCymruScout.IP.summary.service_counts.service.service_name | String | The service name associated with the service count. | +| TeamCymruScout.IP.summary.service_counts.service.port | Number | The port number associated with the service count. | +| TeamCymruScout.IP.summary.service_counts.service.proto_number | Number | The protocol number associated with the service count. | +| TeamCymruScout.IP.summary.service_counts.service.description | String | The description of the service associated with the service count. | +| TeamCymruScout.IP.summary.fingerprints.ip | String | The IP address associated with the fingerprint. | +| TeamCymruScout.IP.summary.fingerprints.type | String | The type of the fingerprint. | +| TeamCymruScout.IP.summary.fingerprints.signature | String | The signature of the fingerprint. | +| TeamCymruScout.IP.summary.fingerprints.event_count | Number | The number of events related to the fingerprint. | +| TeamCymruScout.IP.summary.certs.ip | String | The IP address associated with the certificate. | +| TeamCymruScout.IP.summary.certs.issuer | String | The issuer of the certificate. | +| TeamCymruScout.IP.summary.certs.issuer_common_name | String | The common name of the issuer of the certificate. | +| TeamCymruScout.IP.summary.certs.common_name | String | The common name of the certificate. | +| TeamCymruScout.IP.summary.certs.port | Number | The port number associated with the certificate. | +| TeamCymruScout.IP.summary.certs.event_count | Number | The number of events related to the certificate. | +| TeamCymruScout.QueryUsage.command_name | String | The name of the Cortex XSOAR command that triggered the Foundation API. | +| TeamCymruScout.QueryUsage.request_id | String | The unique request ID of the Foundation API response. | +| TeamCymruScout.QueryUsage.total | Number | The total number of records available for provided filters. | +| TeamCymruScout.QueryUsage.query | String | The query for which the search API was triggered. | +| TeamCymruScout.QueryUsage.size | Number | The number of records requested using parameters. | +| TeamCymruScout.QueryUsage.start_date | String | The start date from which the indicators are returned. | +| TeamCymruScout.QueryUsage.end_date | String | The end date from which the indicators are returned. | +| TeamCymruScout.QueryUsage.used_queries | Number | The number of queries used. | +| TeamCymruScout.QueryUsage.remaining_queries | Number | The number of remaining queries. | +| TeamCymruScout.QueryUsage.query_limit | Number | The total number of queries allowed. | +| TeamCymruScout.QueryUsage.foundation_api_usage.used_queries | Number | The number of queries used for the Foundation API. | +| TeamCymruScout.QueryUsage.foundation_api_usage.remaining_queries | Number | The number of remaining queries for the Foundation API. | +| TeamCymruScout.QueryUsage.foundation_api_usage.query_limit | Number | The total number of queries allowed for the Foundation API. | +| IP.Address | String | IP address. | +| IP.Relationships.EntityA | String | The source of the relationship. | +| IP.Relationships.EntityB | String | The destination of the relationship. | +| IP.Relationships.Relationship | String | The name of the relationship. | +| IP.Relationships.EntityAType | String | The type of the source of the relationship. | +| IP.Relationships.EntityBType | String | The type of the destination of the relationship. | +| IP.ASN | String | The autonomous system name for the IP address, for example: "AS8948". | +| IP.Hostname | String | The hostname that is mapped to this IP address. | +| IP.Geo.Location | String | The geolocation where the IP address is located, in the format: latitude:longitude. | +| IP.Geo.Country | String | The country in which the IP address is located. | +| IP.Geo.Description | String | Additional information about the location. | +| IP.DetectionEngines | Number | The total number of engines that checked the indicator. | +| IP.PositiveDetections | Number | The number of engines that positively detected the indicator as malicious. | +| IP.Malicious.Vendor | String | The vendor reporting the IP address as malicious. | +| IP.Malicious.Description | String | A description explaining why the IP address was reported as malicious. | +| IP.Tags | Unknown | \(List\) Tags of the IP address. | +| IP.FeedRelatedIndicators.value | String | Indicators that are associated with the IP address. | +| IP.FeedRelatedIndicators.type | String | The type of the indicators that are associated with the IP address. | +| IP.FeedRelatedIndicators.description | String | The description of the indicators that are associated with the IP address. | +| IP.MalwareFamily | String | The malware family associated with the IP address. | +| IP.Organization.Name | String | The organization of the IP address. | +| IP.Organization.Type | String | The organization type of the IP address. | +| IP.ASOwner | String | The autonomous system owner of the IP address. | +| IP.Region | String | The region in which the IP address is located. | +| IP.Port | String | Ports that are associated with the IP address. | +| IP.Internal | Boolean | Whether the IP address is internal or external. | +| IP.UpdatedDate | Date | The date that the IP address was last updated. | +| IP.Registrar.Abuse.Name | String | The name of the contact for reporting abuse. | +| IP.Registrar.Abuse.Address | String | The address of the contact for reporting abuse. | +| IP.Registrar.Abuse.Country | String | The country of the contact for reporting abuse. | +| IP.Registrar.Abuse.Network | String | The network of the contact for reporting abuse. | +| IP.Registrar.Abuse.Phone | String | The phone number of the contact for reporting abuse. | +| IP.Registrar.Abuse.Email | String | The email address of the contact for reporting abuse. | +| IP.Campaign | String | The campaign associated with the IP address. | +| IP.TrafficLightProtocol | String | The Traffic Light Protocol \(TLP\) color that is suitable for the IP address. | +| IP.CommunityNotes.note | String | Notes on the IP address that were given by the community. | +| IP.CommunityNotes.timestamp | Date | The time in which the note was published. | +| IP.Publications.source | String | The source in which the article was published. | +| IP.Publications.title | String | The name of the article. | +| IP.Publications.link | String | A link to the original article. | +| IP.Publications.timestamp | Date | The time in which the article was published. | +| IP.ThreatTypes.threatcategory | String | The threat category associated to this indicator by the source vendor. For example, Phishing, Control, TOR, etc. | +| IP.ThreatTypes.threatcategoryconfidence | String | The confidence level provided by the vendor for the threat type category For example a confidence of 90 for threat type category 'malware' means that the vendor rates that this is 90% confidence of being a malware. | +| DBotScore.Indicator | String | The indicator that was tested. | +| DBotScore.Reliability | String | Reliability of the source providing the intelligence data. | +| DBotScore.Type | String | The indicator type. | +| DBotScore.Vendor | String | The vendor used to calculate the score. | +| DBotScore.Score | Number | The reputation score \(0: Unknown, 1: Good, 2: Suspicious, 3: Bad\). | + +#### Command example +```!scout-indicator-search query="0.0.0.1" size=1 start_date="30 days" end_date="now"``` +#### Context Example +```json +{ + "DBotScore": { + "Indicator": "0.0.0.1", + "Type": "ip", + "Vendor": "Team Cymru Scout", + "Score": 0, + "Reliability": "B - Usually reliable" + }, + "IP": { + "Address": "0.0.0.1", + "ASN": 15169, + "ASOwner": "DUMMY", + "Region": "US", + "Port": "53,443", + "UpdatedDate": "2024-06-27", + "Hostname": "dns.dummy", + "Geo": { + "Country": "US" + }, + "Organization": { + "Name": "Dummy LLC" + }, + "Tags": "cdn: (cloudflare)", + "Relationships": [ + { + "Relationship": "communicated-with", + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "0.0.0.2", + "EntityBType": "IP" + }, + { + "Relationship": "communicated-with", + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "0.0.0.3", + "EntityBType": "IP" + }, + { + "Relationship": "resolves-to", + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "dns.dummy", + "EntityBType": "Domain" + }, + { + "Relationship": "resolves-to", + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "dns.dummy.com", + "EntityBType": "Domain" + } + ] + }, + "TeamCymruScout": { + "IP": { + "ip": "0.0.0.1", + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15169, + "as_name": "DUMMY, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 210, + "name": "cloudflare" + } + ] + } + ], + "event_count": 164273621518, + "summary": { + "last_seen": "2024-06-27", + "whois": { + "asn": 15169, + "as_name": "DUMMY", + "net_name": "DUMMY", + "org_name": "Dummy LLC" + }, + "open_ports": [ + { + "ip": "0.0.0.1", + "port": 53, + "protocol": 17, + "protocol_text": "UDP", + "service": "domain", + "event_count": 296728 + }, + { + "ip": "0.0.0.1", + "port": 443, + "protocol": 6, + "protocol_text": "TCP", + "service": "https", + "event_count": 257 + } + ], + "pdns": [ + { + "ip": "0.0.0.1", + "domain": "dns.dummy", + "event_count": 53408038 + }, + { + "ip": "0.0.0.1", + "domain": "dns.dummy.com", + "event_count": 2791811 + } + ], + "top_peers": [ + { + "ip": "0.0.0.2", + "event_count": 2784287448 + }, + { + "ip": "0.0.0.3", + "event_count": 1469283767 + } + ], + "comms_total": 166356036813, + "service_counts": [ + { + "proto": 17, + "proto_text": "", + "port": 53, + "event_count": 141248029324, + "service": { + "service_name": "domain", + "port": 53, + "proto_number": 17, + "description": "Domain Name Server" + } + }, + { + "proto": 17, + "proto_text": "", + "port": 443, + "event_count": 7214447854, + "service": { + "service_name": "https", + "port": 443, + "proto_number": 17, + "description": "http protocol over TLS/SSL" + } + }, + { + "proto": 6, + "proto_text": "", + "port": 443, + "event_count": 4130470538, + "service": { + "service_name": "https", + "port": 443, + "proto_number": 6, + "description": "http protocol over TLS/SSL" + } + } + ], + "fingerprints": [ + { + "ip": "0.0.0.1", + "type": "ja3s", + "signature": "00000000000000000000000000000001", + "event_count": 144337 + }, + { + "ip": "0.0.0.1", + "type": "ja3", + "signature": "00000000000000000000000000000001", + "event_count": 40708 + } + ], + "certs": [ + { + "ip": "0.0.0.1", + "issuer": "CN=WR2, O=Dummy Trust Services, C=US", + "issuer_common_name": "WR2", + "common_name": "dns.dummy", + "port": 853, + "event_count": 418 + }, + { + "ip": "0.0.0.1", + "issuer": "CN=WR2, O=Dummy Trust Services, C=US", + "issuer_common_name": "WR2", + "common_name": "dns.dummy", + "port": 443, + "event_count": 372 + } + ] + } + }, + "QueryUsage": { + "command_name": "scout-indicator-search", + "request_id": "00000000-0000-0000-0000-000000000001", + "total": 1, + "query": "0.0.0.1", + "size": 1, + "start_date": "2024-05-28", + "end_date": "2024-06-26", + "used_queries": 261, + "remaining_queries": 49739, + "query_limit": 50000, + "foundation_api_usage": { + "used_queries": 15, + "remaining_queries": 0, + "query_limit": 0 + } + } + } +} +``` + +#### Human Readable Output + +>### Summary Information for the given indicator: [0.0.0.1](https://scout.cymru.com/scout/details?query=0.0.0.1) +>|Country Code(S)|Whois|Event Count|Tags|Last Seen| +>|---|---|---|---|---| +>| US | ***asn***: 15169
***as_name***: DUMMY
***net_name***: DUMMY
***org_name***: Dummy LLC | 164273621518 | **-** ***id***: 176
***name***: cdn
**children**:
**-** ***id***: 210
***name***: cloudflare | 2024-06-27 | +> +>### PDNS Information +>|Domain|Event Count|IP| +>|---|---|---| +>| dns.dummy | 53408038 | 0.0.0.1 | +>| dns.dummy.com | 2791811 | 0.0.0.1 | +> +>### Open Ports Information +>|Event Count|IP|Port|Protocol|Protocol Text|Service| +>|---|---|---|---|---|---| +>| 296728 | 0.0.0.1 | 53 | 17 | UDP | domain | +>| 257 | 0.0.0.1 | 443 | 6 | TCP | https | +> +>### Top Peers Information +>|Source IP|Event Count|IP| +>|---|---|---| +>| 0.0.0.1 | 2784287448 | 0.0.0.2 | +>| 0.0.0.1 | 1469283767 | 0.0.0.3 | +> +>### Service Counts Information +>|Source IP|Event Count|Port|Proto|Service| +>|---|---|---|---|---| +>| 0.0.0.1 | 141248029324 | 53 | 17 | service_name: domain
port: 53
proto_number: 17
description: Domain Name Server | +>| 0.0.0.1 | 7214447854 | 443 | 17 | service_name: https
port: 443
proto_number: 17
description: http protocol over TLS/SSL | +>| 0.0.0.1 | 4130470538 | 443 | 6 | service_name: https
port: 443
proto_number: 6
description: http protocol over TLS/SSL | +> +>### Fingerprints Information +>|Event Count|IP|Signature|Type| +>|---|---|---|---| +>| 144337 | 0.0.0.1 | 00000000000000000000000000000001 | ja3s | +>| 40708 | 0.0.0.1 | 00000000000000000000000000000001 | ja3 | +> +>### Certs Information +>|Common Name|Event Count|IP|Issuer|Issuer Common Name|Port| +>|---|---|---|---|---|---| +>| dns.dummy | 418 | 0.0.0.1 | CN=WR2, O=Dummy Trust Services, C=US | WR2 | 853 | +>| dns.dummy | 372 | 0.0.0.1 | CN=WR2, O=Dummy Trust Services, C=US | WR2 | 443 | +> +>### API Usage +>|Used Queries|Remaining Queries|Query Limit|Foundation Used Queries|Foundation Remaining Queries|Foundation Query Limit| +>|---|---|---|---|---|---| +>| 261 | 49739 | 50000 | 15 | 0 | 0 | + +### scout-ip-list + +*** +Returns the summary information available for the given list of IP addresses. + +#### Base Command + +`scout-ip-list` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| ip_addresses | A comma-separated list of IP addresses to retrieve available IP details. Note: Maximum of 10 IP addresses are allowed. | Required | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| TeamCymruScout.IP.ip | String | The IP address. | +| TeamCymruScout.IP.country_code | String | The country code. | +| TeamCymruScout.IP.as_info.asn | Number | The autonomous system number. | +| TeamCymruScout.IP.as_info.as_name | String | The autonomous system name. | +| TeamCymruScout.IP.insights.overall_rating | String | The overall rating for the IP address. | +| TeamCymruScout.IP.insights.insights.rating | String | The individual insight rating for the IP address. | +| TeamCymruScout.IP.insights.insights.message | String | The individual insight message for the IP address. | +| TeamCymruScout.IP.tags.id | Number | The ID of the tag. | +| TeamCymruScout.IP.tags.name | String | The name of the tag. | +| TeamCymruScout.IP.tags.children.id | Number | The ID of the child tag. | +| TeamCymruScout.IP.tags.children.name | String | The name of the child tag. | +| TeamCymruScout.IP.tags.children.children | Unknown | The children of the child tag. | +| TeamCymruScout.QueryUsage.command_name | String | The name of the Cortex XSOAR command that triggered the Foundation API. | +| TeamCymruScout.QueryUsage.request_id | String | The unique request ID of the Foundation API response. | +| TeamCymruScout.QueryUsage.ips | Unknown | The list of IP addresses for which the Foundation API was triggered. | +| TeamCymruScout.QueryUsage.used_queries | Number | The number of queries used. | +| TeamCymruScout.QueryUsage.remaining_queries | Number | The number of remaining queries. | +| TeamCymruScout.QueryUsage.query_limit | Number | The total number of queries allowed. | +| TeamCymruScout.QueryUsage.foundation_api_usage.used_queries | Number | The number of queries used for the Foundation API. | +| TeamCymruScout.QueryUsage.foundation_api_usage.remaining_queries | Number | The number of remaining queries for the Foundation API. | +| TeamCymruScout.QueryUsage.foundation_api_usage.query_limit | Number | The total number of queries allowed for the Foundation API. | +| IP.Address | String | IP address. | +| IP.Relationships.EntityA | String | The source of the relationship. | +| IP.Relationships.EntityB | String | The destination of the relationship. | +| IP.Relationships.Relationship | String | The name of the relationship. | +| IP.Relationships.EntityAType | String | The type of the source of the relationship. | +| IP.Relationships.EntityBType | String | The type of the destination of the relationship. | +| IP.ASN | String | The autonomous system name for the IP address, for example: "AS8948". | +| IP.Hostname | String | The hostname that is mapped to this IP address. | +| IP.Geo.Location | String | The geolocation where the IP address is located, in the format: latitude:longitude. | +| IP.Geo.Country | String | The country in which the IP address is located. | +| IP.Geo.Description | String | Additional information about the location. | +| IP.DetectionEngines | Number | The total number of engines that checked the indicator. | +| IP.PositiveDetections | Number | The number of engines that positively detected the indicator as malicious. | +| IP.Malicious.Vendor | String | The vendor reporting the IP address as malicious. | +| IP.Malicious.Description | String | A description explaining why the IP address was reported as malicious. | +| IP.Tags | Unknown | \(List\) Tags of the IP address. | +| IP.FeedRelatedIndicators.value | String | Indicators that are associated with the IP address. | +| IP.FeedRelatedIndicators.type | String | The type of the indicators that are associated with the IP address. | +| IP.FeedRelatedIndicators.description | String | The description of the indicators that are associated with the IP address. | +| IP.MalwareFamily | String | The malware family associated with the IP address. | +| IP.Organization.Name | String | The organization of the IP address. | +| IP.Organization.Type | String | The organization type of the IP address. | +| IP.ASOwner | String | The autonomous system owner of the IP address. | +| IP.Region | String | The region in which the IP address is located. | +| IP.Port | String | Ports that are associated with the IP address. | +| IP.Internal | Boolean | Whether the IP address is internal or external. | +| IP.UpdatedDate | Date | The date that the IP address was last updated. | +| IP.Registrar.Abuse.Name | String | The name of the contact for reporting abuse. | +| IP.Registrar.Abuse.Address | String | The address of the contact for reporting abuse. | +| IP.Registrar.Abuse.Country | String | The country of the contact for reporting abuse. | +| IP.Registrar.Abuse.Network | String | The network of the contact for reporting abuse. | +| IP.Registrar.Abuse.Phone | String | The phone number of the contact for reporting abuse. | +| IP.Registrar.Abuse.Email | String | The email address of the contact for reporting abuse. | +| IP.Campaign | String | The campaign associated with the IP address. | +| IP.TrafficLightProtocol | String | The Traffic Light Protocol \(TLP\) color that is suitable for the IP address. | +| IP.CommunityNotes.note | String | Notes on the IP address that were given by the community. | +| IP.CommunityNotes.timestamp | Date | The time in which the note was published. | +| IP.Publications.source | String | The source in which the article was published. | +| IP.Publications.title | String | The name of the article. | +| IP.Publications.link | String | A link to the original article. | +| IP.Publications.timestamp | Date | The time in which the article was published. | +| IP.ThreatTypes.threatcategory | String | The threat category associated to this indicator by the source vendor. For example, Phishing, Control, TOR, etc. | +| IP.ThreatTypes.threatcategoryconfidence | String | The confidence level provided by the vendor for the threat type category For example a confidence of 90 for threat type category 'malware' means that the vendor rates that this is 90% confidence of being a malware. | +| DBotScore.Indicator | String | The indicator that was tested. | +| DBotScore.Type | String | The indicator type. | +| DBotScore.Vendor | String | The vendor used to calculate the score. | +| DBotScore.Score | Number | The reputation score \(0: Unknown, 1: Good, 2: Suspicious, 3: Bad\). | +| DBotScore.Reliability | String | Reliability of the source providing the intelligence data. | + +#### Command example +```!scout-ip-list ip_addresses="0.0.0.1"``` +#### Context Example +```json +{ + "DBotScore": [ + { + "Indicator": "0.0.0.1", + "Reliability": "B - Usually reliable", + "Score": 2, + "Type": "ip", + "Vendor": "Team Cymru Scout" + } + ], + "IP": [ + { + "Address": "0.0.0.1", + "ASN": 13335, + "ASOwner": "NET, US", + "Region": "US", + "Description": "0.0.0.1 has been identified as a \"cdn\", indicating private and reserved addresses defined by RFC 1918, RFC 5735, and RFC 6598, as well as net that have not been allocated to a Regional Internet Registry (RIR) by the Internet Assigned Numbers Authority.", + "Geo": { + "Country": "US" + }, + "Organization": { + "Name": "NET, US" + }, + "Tags": "cdn: (cloudflare)" + } + ], + "TeamCymruScout": { + "IP": [ + { + "ip": "0.0.0.1", + "country_code": "US", + "as_info": [ + { + "asn": 13335, + "as_name": "NET, US" + } + ], + "insights": { + "overall_rating": "suspicious", + "insights": [ + { + "rating": "suspicious", + "message": "0.0.0.1 has been identified as a \"cdn\", indicating private and reserved addresses defined by RFC 1918, RFC 5735, and RFC 6598, as well as net that have not been allocated to a Regional Internet Registry (RIR) by the Internet Assigned Numbers Authority." + } + ] + }, + "tags": [ + { + "id": 81, + "name": "cdn", + "children": [ + { + "id": 210, + "name": "cloudflare" + } + ] + } + ] + } + ], + "QueryUsage": { + "command_name": "scout-ip-list", + "foundation_api_usage": { + "query_limit": 0, + "remaining_queries": 0, + "used_queries": 3 + }, + "ips": [ + "0.0.0.1" + ], + "query_limit": 50000, + "remaining_queries": 49840, + "request_id": "00000000-0000-0000-0000-000000000001", + "used_queries": 160 + } + } +} +``` + +#### Human Readable Output + +>### Summary Information for the given Suspicious IP: [0.0.0.1](https://scout.cymru.com/scout/details?query=0.0.0.1) +>|Country Code|AS Info|Insights|Tags| +>|---|---|---|---| +>| US | **-** ***asn***: 13335
***as_name***: NET, US | ***overall_rating***: suspicious
**insights**:
**-** ***rating***: suspicious
***message***: 0.0.0.1 has been identified as a "cdn", indicating private and reserved addresses defined by RFC 1918, RFC 5735, and RFC 6598, as well as net that have not been allocated to a Regional Internet Registry (RIR) by the Internet Assigned Numbers Authority. | **-** ***id***: 81
***name***: cdn
**children**:
**-** ***id***: 210
***name***: cloudflare | +> +>### API Usage +>|Used Queries|Remaining Queries|Query Limit|Foundation Used Queries|Foundation Remaining Queries|Foundation Query Limit| +>|---|---|---|---|---|---| +>| 160 | 49840 | 50000 | 3 | 0 | 0 | + diff --git a/Packs/TeamCymru/Integrations/TeamCymruScout/TeamCymruScout.py b/Packs/TeamCymru/Integrations/TeamCymruScout/TeamCymruScout.py new file mode 100644 index 000000000000..0958e61722eb --- /dev/null +++ b/Packs/TeamCymru/Integrations/TeamCymruScout/TeamCymruScout.py @@ -0,0 +1,1132 @@ +""" IMPORTS """ + +from copy import deepcopy # noqa E402 +from datetime import datetime # noqa E402 +from typing import Any, Callable, Dict, List, Optional, Tuple # noqa E402 + +import urllib3 # noqa E402 + +import demistomock as demisto # noqa E402 +from CommonServerPython import * # noqa # pylint: disable=unused-wildcard-import +from CommonServerUserPython import * # noqa + +# Disable insecure warnings +urllib3.disable_warnings() + +''' CONSTANTS ''' + +DATE_FORMAT = '%Y-%m-%d' +BASE_URL = 'https://scout.cymru.com/api/scout' +INDICATOR_SEARCH_URL = 'https://scout.cymru.com/scout/details?query={}' +MD_LINK = '[{}]({})' +VENDOR_NAME = 'Team Cymru Scout' +TOTAL_RETRIES = 4 +STATUS_CODE_TO_RETRY = [429, + *(status_code for status_code in requests.status_codes._codes if status_code >= 500)] # type: ignore +OK_CODES = [200, 201] +BACKOFF_FACTOR = 7.5 # Sleep for [0s, 15s, 30s, 60s] between retries. +DATE_FORMAT = '%Y-%m-%d' + +DEFAULT_START_DATE = '30 days' +DEFAULT_END_DATE = 'now' +DEFAULT_PAGE_SIZE = 20 + +MINIMUM_PAGE_SIZE = 1 +DEFAULT_PAGE_SIZE = 20 +MINIMUM_DETAIL_IP_SIZE = 1 +MAXIMUM_DETAIL_IP_SIZE = 1000 +MINIMUM_DAY = 1 +MAXIMUM_DAY = 30 +MAXIMUM_START_DAY = 90 +MAXIMUM_INDICATOR_SEARCH_SIZE = 5000 +MAXIMUM_IP_LIST_SIZE = 10 + +DEFAULT_START_DATE = '30 days' +START_DATE_LIMIT = '90 days' +DEFAULT_END_DATE = 'now' + +DBOT_SCORE_MAPPING = { + 'no_rating': 0, # Unknown + 'informational': 1, # Good + 'suspicious': 2, # Suspicious + 'malicious': 3 # Bad +} +SEVERITY_MAPPING = { + 'no_rating': 'Unknown', + 'informational': 'Good', + 'suspicious': 'Suspicious', + 'malicious': 'Bad' +} + +KEYS_TO_REMOVE_FROM_AN_IP_AND_ADD_TO_USAGE_CONTEXT = ['request_id', 'size', 'start_date', 'end_date'] + +API_KEY = 'API Key' +BASIC_AUTH = 'Basic Auth' + +OUTPUT_PREFIX = { + 'IP': 'TeamCymruScout.IP', + 'QUERY_USAGE': 'TeamCymruScout.QueryUsage' +} + +OUTPUT_KEY_FIELD = { + 'IP': 'ip', + 'QUERY_USAGE': 'command_name', +} + +ENDPOINTS = { + 'LIST_IPS': '/ip/foundation', + 'IP_DETAILS': '/ip/{}/details', + 'QUERY_USAGE': '/usage', + 'SEARCH_INDICATORS': '/search', +} + +ERROR_MESSAGES = { + 'NO_PARAM_PROVIDED': 'Please provide the {}.', + 'INVALID_PAGE_SIZE': '{} is invalid value for size. Value of size should be between {} and {}.', + 'START_DATE_GREATER_THAN_END_DATE': 'Please provide the start date less than the end date.', + 'END_DATE_GREATER_THAN_CURRENT_TIME': 'Please provide the end date less than current time.', + 'REACHED_MAXIMUM_DIFF_DAYS': f'Please provide the start date less than {MAXIMUM_DAY} days from the end date.', + 'REACHED_MAXIMUM_START_DAYS': f'Please provide the start date less than {MAXIMUM_START_DAY} days.', + 'INVALID_DAY': '{} is invalid value for days.' + f'Value of days should be between {MINIMUM_DAY} and {MAXIMUM_DAY}.', + 'NO_INDICATORS_FOUND': 'No indicators found for given query and filters.', + 'INVALID_IP_ADDRESSES': 'The following IP Addresses were found invalid: {}', + 'INVALID_IP_ADDRESS_SIZE': ('{} valid IP Addresses provided. ' + 'Please provide the list of IP Addresses less than or equal to {}.'), +} + +''' CLIENT CLASS ''' + + +class Client(BaseClient): + ''' + Client class to interact with the Team Cymru Scout server API. + + This Client implements API calls, and does not contain any XSOAR logic. + ''' + + def __init__(self, server_url: str, verify: bool, proxy: bool, headers: Dict, auth: Optional[Tuple]): + ''' + Initializes the Client class with the provided parameters. + + :type server_url: ``str`` + :param server_url: The URL of the Team Cymru Scout server. + + :type verify: ``bool`` + :param verify: Whether to verify the server's SSL certificate. + + :type proxy: ``bool`` + :param proxy: The proxy settings to be used. + + :type headers: ``Dict`` + :param headers: Additional headers to be included in the requests. + + :type auth: ``Optional[Tuple]`` + :param auth: The authentication tuple to be used. + ''' + super().__init__(base_url=server_url, verify=verify, proxy=proxy, headers=headers, auth=auth) + + def http_request(self, *args, **kwargs): + ''' + A wrapper for BaseClient.http_request method with the retries added. + + :type args: ``tuple`` + :param args: The tuple to send in a request. + + :type kwargs: ``Dict`` + :param kwargs: The dictionary to send in a request. + + :return: Depends on the resp_type parameter. + :rtype: ``Dict`` or ``str`` or ``bytes`` or ``xml.etree.ElementTree.Element`` or ``requests.Response`` + ''' + return self._http_request(retries=TOTAL_RETRIES, status_list_to_retry=STATUS_CODE_TO_RETRY, + backoff_factor=BACKOFF_FACTOR, raise_on_redirect=False, ok_codes=OK_CODES, + raise_on_status=True, *args, **kwargs) # type: ignore + + def scout_api_usage_request(self) -> Dict: + ''' + A function to request the information for the API usage. + + :return: The response containing the api usage. + :rtype: ``Dict`` + ''' + response = self.http_request('GET', ENDPOINTS['QUERY_USAGE']) + + return response + + def ip_request(self, ip: str, start_date: Optional[str], end_date: Optional[str], days: Optional[int], + size: Optional[int]) -> Dict: + ''' + A function to request the information for the given IP. + + :type ip: ``str`` + :param ip: The IP to search for. + + :type start_date: ``Optional[str]`` + :param start_date: The start date for detailed information. + + :type end_date: ``Optional[str]`` + :param end_date: The end date for detailed information. + + :type days: ``Optional[int]`` + :param days: The number of days in past for detailed information. + + :type size: ``Optional[int]`` + :param size: The number of results to return. + + :return: The response containing information for the given IP. + :rtype: ``Dict`` + ''' + params = assign_params(start_date=start_date, end_date=end_date, days=days, size=size) + + response = self.http_request('GET', ENDPOINTS['IP_DETAILS'].format(ip), params=params) + + return response + + def scout_indicator_search_request(self, query: str, start_date: Optional[str], end_date: Optional[str], + days: Optional[int], size: Optional[int]) -> Dict: + ''' + A function to search the indicators based on specified parameters. + + :type query: str + :param query: The query to search for. + + :type start_date: Optional[str] + :param start_date: The start date to filter indicators. + + :type end_date: Optional[str] + :param end_date: The end date to filter indicators. + + :type days: Optional[int] + :param days: The number of days in past to filter indicators. + + :type size: Optional[int] + :param size: The number of results to return. + + :rtype: Dict[str, str] + :return: The response containing the details for the queried indicators. + ''' + params = assign_params(query=query, start_date=start_date, end_date=end_date, days=days, size=size) + + response = self.http_request('GET', ENDPOINTS['SEARCH_INDICATORS'], params=params) + + return response + + def scout_ip_list(self, params) -> Dict: + ''' + A function to request the information for the IPs. + + :type params: Dict + :param params: The parameters to send in the request. + + :rtype: Dict[str, str] + :return: The response containing the ip's data. + ''' + response = self.http_request('GET', ENDPOINTS['LIST_IPS'], params=params) + + return response + + +''' HELPER FUNCTIONS ''' + + +def trim_spaces_from_args(args: Dict): + '''Remove space from args.''' + for key in args.keys(): + if isinstance(args[key], str): + args[key] = args[key].strip() + return args + + +def validate_params(params: Dict): + ''' + Validate the parameters. + + :type params: ``Dict`` + :param params: Params to validate. + ''' + authentication_type: str = params.get('authentication_type', '') + + if authentication_type == API_KEY: + api_key = str(params.get('api_key', {}).get('password', '')).strip() + if not api_key: + raise DemistoException(ERROR_MESSAGES['NO_PARAM_PROVIDED'].format(API_KEY)) + elif authentication_type == BASIC_AUTH: + basic_auth = params.get('basic_auth', {}) + username = str(basic_auth.get('identifier', '')).strip() + if not username: + raise DemistoException(ERROR_MESSAGES['NO_PARAM_PROVIDED'].format('Username')) + password = str(basic_auth.get('password', '')).strip() + if not password: + raise DemistoException(ERROR_MESSAGES['NO_PARAM_PROVIDED'].format('Password')) + + +def header_transformer_for_ip(header: str) -> str: + ''' + To transform the header for the markdown table. + + :type header: ``str`` + :param header: Header name. + + :return: The title cased header. + :rtype: ``str`` + ''' + return header.replace('_', ' ').title().replace('Ip', 'IP') + + +def create_tag_list(tags: list) -> str: + ''' + Create comma separated tag list. + + :type tags: ``list`` + :param tags: List of tags from response. + + :return: Comma separated tag list. + :rtype: ``str`` + ''' + tag_list = [] + for tag_dict in tags: + tag = tag_dict.get('name', '') + sub_tags = [] + for child_tag in tag_dict.get('children', []): + sub_tags.append(child_tag.get('name', '')) + if sub_tags: + tag += f': ({", ".join(sub_tags)})' + tag_list.append(tag) + return ', '.join(tag_list) + + +def remove_empty_elements_for_hr(d): + """ + Recursively remove empty lists, empty dicts, or None elements from a dictionary. + + :type d: ``dict`` + :param d: Input dictionary. + + :return: Dictionary with all empty lists, and empty dictionaries removed. + :rtype: ``dict`` + """ + + def empty(x): + return x is None or x == {} or x == [] or x == '' + + if not isinstance(d, (dict, list)): + return d + elif isinstance(d, list): + return [v for v in (remove_empty_elements_for_hr(v) for v in d) if not empty(v)] + else: + return {k: v for k, v in ((k, remove_empty_elements_for_hr(v)) for k, v in d.items()) if not empty(v)} + + +def validate_common_search_command_args(args: Dict[str, str], required_arg: str, + maximum_page_size: int = MAXIMUM_DETAIL_IP_SIZE) -> Tuple: + ''' + To validate common arguments of all command. + + :type args: ``dict`` + :param args: Command arguments. + + :type required_arg: ``str`` + :param required_arg: Required argument. + + :type maximum_page_size: ``int`` + :param maximum_page_size: Maximum page size. + + :rtype: Tuple + :return: The tuple containing the extracted arguments with pagination parameters. + ''' + required_arg_val: str = args.get(required_arg, '') + if not required_arg_val: + raise DemistoException(ERROR_MESSAGES['NO_PARAM_PROVIDED'].format(required_arg)) + + start_date_str = args.get('start_date', DEFAULT_START_DATE) + end_date_str = args.get('end_date', DEFAULT_END_DATE) + + start_date_obj = arg_to_datetime(start_date_str, 'start_date') + end_date_obj = arg_to_datetime(end_date_str, 'end_date') + current_date_obj = arg_to_datetime(DEFAULT_END_DATE) + + start_date = start_date_obj.strftime(DATE_FORMAT) if isinstance(start_date_obj, datetime) else start_date_obj + start_date_obj = arg_to_datetime(start_date) + end_date = end_date_obj.strftime(DATE_FORMAT) if isinstance(end_date_obj, datetime) else end_date_obj + end_date_obj = arg_to_datetime(end_date) + + if start_date_obj > end_date_obj: # type: ignore + raise DemistoException(ERROR_MESSAGES['START_DATE_GREATER_THAN_END_DATE']) + if end_date_obj > current_date_obj: # type: ignore + raise DemistoException(ERROR_MESSAGES['END_DATE_GREATER_THAN_CURRENT_TIME']) + + if start_date_obj <= current_date_obj - timedelta(days=MAXIMUM_START_DAY): # type: ignore + raise DemistoException(ERROR_MESSAGES['REACHED_MAXIMUM_START_DAYS']) + + if end_date_obj - start_date_obj >= timedelta(days=MAXIMUM_DAY): # type: ignore + if start_date_str.lower() in DEFAULT_START_DATE: + start_date_obj += timedelta(days=1) # type: ignore + start_date = start_date_obj.strftime(DATE_FORMAT) # type: ignore + else: + raise DemistoException(ERROR_MESSAGES['REACHED_MAXIMUM_DIFF_DAYS']) + + days = arg_to_number(args.get('days'), 'days') + if isinstance(days, int) and not (MINIMUM_DAY <= days <= MAXIMUM_DAY): + raise DemistoException(ERROR_MESSAGES['INVALID_DAY'].format(days)) + + size = arg_to_number(args.get('size', DEFAULT_PAGE_SIZE), 'size') + if isinstance(size, int) and not (MINIMUM_PAGE_SIZE <= size <= maximum_page_size): + raise DemistoException(ERROR_MESSAGES['INVALID_PAGE_SIZE'].format( + size, MINIMUM_PAGE_SIZE, maximum_page_size)) + + return required_arg_val, start_date, end_date, days, size + + +def validate_ip_addresses(ips_list: List[str]) -> Tuple[List[str], List[str]]: + ''' + Given a list of IP addresses, returns the invalid and valid ips. + + :type ips_list: ``List[str]`` + :param ips_list: List of ip addresses. + + :return: invalid_ip_addresses and valid_ip_addresses. + :rtype: ``Tuple[List[str], List[str]]`` + ''' + invalid_ip_addresses = [] + valid_ip_addresses = [] + for ip in ips_list: + ip = ip.strip().strip('\"') + if ip: + if is_ip_valid(ip, accept_v6_ips=True): + valid_ip_addresses.append(ip) + else: + invalid_ip_addresses.append(ip) + return invalid_ip_addresses, valid_ip_addresses + + +def validate_ip_list_args(args: Dict) -> Dict: + ''' + Validate the ip list arguments. + + :param args: Arguments to validate. + :type args: Dict + + :return: Validated arguments. + :rtype: Dict + ''' + ip_addresses = argToList(args.get('ip_addresses')) + + invalid_ips, valid_ips = validate_ip_addresses(ip_addresses) + + if invalid_ips: + return_warning(ERROR_MESSAGES['INVALID_IP_ADDRESSES'].format(', '.join(invalid_ips)), + exit=len(invalid_ips) == len(ip_addresses)) + + if not valid_ips: + raise DemistoException(ERROR_MESSAGES['NO_PARAM_PROVIDED'].format('ip_addresses')) + + if len(valid_ips) > 10: + raise DemistoException(ERROR_MESSAGES['INVALID_IP_ADDRESS_SIZE'].format(len(valid_ips), MAXIMUM_IP_LIST_SIZE)) + + return {'ips': ','.join(valid_ips)} + + +def remove_key_from_ip_and_add_to_usage(ip_response: dict, usage_response: dict) -> Tuple[Dict, Dict]: + ''' + Prepare context ip command. + + :type ip_response: ``dict`` + :param ip_response: Response contain detailed information about ip. + + :type usage_response: ``dict`` + :param usage_response: Response contain information about api usage. + + :return: Modified ip_response and usage_response. + :rtype: ``Tuple[Dict, Dict]`` + ''' + for key in KEYS_TO_REMOVE_FROM_AN_IP_AND_ADD_TO_USAGE_CONTEXT: + usage_response[key] = ip_response.get(key) + del ip_response[key] + + usage_response['command_name'] = 'ip' + del ip_response['usage'] + + return ip_response, usage_response + + +def find_description(ip: str, insights: list) -> str: + ''' + Finding the description for ip from insights response. + + :type ip: ``str`` + :param ip: Used to find description. + + :type insights: ``list`` + :param insights: Insights related to ip. + + :return: Description related to ip. + :rtype: ``str`` + ''' + description = '' + + for insight in insights: + message = insight.get('message') + if ip in message: + return message + description += message + description += '\n' + + return description + + +def prepare_hr_for_ip(response: dict) -> str: + ''' + Prepare Human Readable output for ip command. + + :type response: ``Dict`` + :param response: Response from API. + + :rtype: ``str`` + :return: Human readable output. + ''' + data = response + summary_hr = [{ + 'Country Code': data.get('summary', {}).get('geo_ip_cc'), + 'Whois': remove_empty_elements_for_hr(data.get('summary', {}).get('whois')), + 'Tags': remove_empty_elements_for_hr(data.get('summary', {}).get('tags', [])), + 'Insights': remove_empty_elements_for_hr(data.get('summary', {}).get('insights', {}).get('insights')) + }] + + severity = SEVERITY_MAPPING.get((response.get('summary', {}).get('insights', {}).get('overall_rating')).lower()) + ip_md_link = MD_LINK.format(data.get('ip'), INDICATOR_SEARCH_URL.format(data.get('ip'))) + + for pdns_data in data.get('summary', {}).get('pdns', {}).get('top_pdns', []): + del pdns_data['css_color'] + + pdns_hr = data.get('summary', {}).get('pdns', {}).get('top_pdns', []) + + top_peers_hr = [{ + 'Proto': peer.get('proto_text'), + 'Event Count': peer.get('event_count'), + 'Server IP': peer.get('local', {}).get('ip'), + 'Server Country Code(s)': peer.get('local', {}).get('country_codes'), + 'Server Tag(s)': create_tag_list(tags=peer.get('local', {}).get('tags', [])), + 'Server Services': remove_empty_elements_for_hr(peer.get('local', {}).get('top_services', [])[:5]), + 'Server AS Name': [as_info.get('as_name') for as_info in peer.get('local', {}).get('as_info', [])], + 'Client IP': peer.get('peer', {}).get('ip'), + 'Client Country Code(s)': peer.get('peer', {}).get('country_codes'), + 'Client Tag(s)': create_tag_list(tags=peer.get('peer', {}).get('tags', [])), + 'Client Services': remove_empty_elements_for_hr(peer.get('peer', {}).get('top_services', [])[:5]), + 'Client AS Name': [as_info.get('as_name') for as_info in peer.get('peer', {}).get('as_info', [])], + 'First Seen': peer.get('first_seen'), + 'Last Seen': peer.get('last_seen') + } for peer in data.get('communications', {}).get('peers', [])[:5]] + + open_port_hr = [{ + 'Event Count': port_data.get('event_count'), + 'Port': port_data.get('port'), + 'Protocol': port_data.get('protocol'), + 'Protocol Text': port_data.get('protocol_text'), + 'Service': port_data.get('service'), + 'First Seen': port_data.get('first_seen'), + 'Last Seen': port_data.get('last_seen') + } for port_data in data.get('summary', {}).get('open_ports', {}).get('top_open_ports', [])] + + fingerprints_hr = data.get('summary', {}).get('fingerprints', {}).get('top_fingerprints', []) + + for certs_data in data.get('summary', {}).get('certs', {}).get('top_certs', []): + del certs_data['css_color'] + + certs_hr = data.get('summary', {}).get('certs', {}).get('top_certs', []) + + hr_list = [summary_hr, pdns_hr, top_peers_hr, open_port_hr, fingerprints_hr, certs_hr] + new_hr_list = [] + for hr_data in hr_list: + hr_data = remove_empty_elements_for_hr(hr_data) + [remove_nulls_from_dictionary(data) for data in hr_data] + new_hr_list.append(hr_data) + + (summary_hr, pdns_hr, top_peers_hr, open_port_hr, fingerprints_hr, certs_hr) = new_hr_list + + human_readable = tableToMarkdown(f'Summary Information For The Given {severity} IP: {ip_md_link}', summary_hr, + json_transform_mapping={'Whois': JsonTransformer(), 'Insights': JsonTransformer(), + 'Tags': JsonTransformer()}, + removeNull=True, headers=['Country Code', 'Whois', 'Tags', 'Insights']) + '\n' + human_readable += tableToMarkdown( + 'Top PDNS', pdns_hr, headerTransform=header_transformer_for_ip, removeNull=True) + '\n' if pdns_hr else '' + human_readable += tableToMarkdown('Top Peers', top_peers_hr, removeNull=True, + json_transform_mapping={'Client Services': JsonTransformer(), + 'Server Services': JsonTransformer()}, + headers=['Proto', 'Client IP', 'Client Country Code(s)', 'Client Tag(s)', 'Client Services', + 'Server IP', 'Server Country Code(s)', 'Server Tag(s)', 'Server Services', + 'Event Count', 'First Seen', 'Last Seen', 'Client AS Name', + 'Server AS Name']) + '\n' if top_peers_hr else '' + human_readable += tableToMarkdown('Top Open Ports', open_port_hr, removeNull=True, headers=['Event Count', 'Port', 'Protocol', + 'Protocol Text', 'Service', 'First Seen', 'Last Seen']) + '\n' if open_port_hr else '' + human_readable += tableToMarkdown('Top Fingerprints', fingerprints_hr, removeNull=True, + headerTransform=header_transformer_for_ip) + '\n' if fingerprints_hr else '' + human_readable += tableToMarkdown('Top Certificates', certs_hr, removeNull=True, + headerTransform=header_transformer_for_ip) + '\n' if certs_hr else '' + + return human_readable + + +def create_relationship_for_indicator_search(response: dict) -> List: + ''' + Create a list of relationships objects from the response. + + :type response: ``dict`` + :param response: Response of API. + + :return: List of EntityRelationship objects containing all the relationships. + :rtype: ``List`` + ''' + relationships = [] + source_ip = response.get('ip', '') + integration_reliability = demisto.params().get('integrationReliability') + + for peer in response.get('summary', {}).get('top_peers', []): + client_ip = peer.get('ip') + fields = {key: value for key, value in peer.items() if key != 'ip'} + relationships.append(EntityRelationship(name=EntityRelationship.Relationships.COMMUNICATED_WITH, + entity_a=source_ip, + entity_a_type=FeedIndicatorType.IP, + entity_b=client_ip, + entity_b_type=FeedIndicatorType.IP, + source_reliability=integration_reliability, + brand=VENDOR_NAME, fields=fields)) + + for pdns in response.get('summary', {}).get('pdns', []): + ip = pdns.get('ip') + domain = pdns.get('domain') + fields = {key: value for key, value in pdns.items() if key not in ['ip', 'domain']} + relationships.append(EntityRelationship(name=EntityRelationship.Relationships.RESOLVES_TO, + entity_a=ip, + entity_a_type=FeedIndicatorType.IP, + entity_b=domain, + entity_b_type=FeedIndicatorType.Domain, + source_reliability=integration_reliability, + brand=VENDOR_NAME, fields=fields)) + + return relationships + + +def prepare_hr_and_context_for_indicator_search(response: Dict) -> Tuple[str, Dict, Common.IP, List]: + ''' + A function to prepare the human readable and context output for the indicator search. + + :type response: Dict + :param response: The response containing the list of indicators. + + :rtype: Tuple[str, Dict, Common.IP, List] + :return: The human readable, context output, IP indicator and relationships. + ''' + scout_ip_data = remove_empty_elements(response) + remove_nulls_from_dictionary(scout_ip_data) + + ip_address = scout_ip_data.get('ip') + + dbot_score = Common.DBotScore( + indicator=ip_address, + indicator_type=DBotScoreType.IP, + integration_name=VENDOR_NAME, + score=Common.DBotScore.NONE, + reliability=demisto.params().get('integrationReliability') + ) + + relationships = [] + create_relationships = demisto.params().get('create_relationships') + if create_relationships: + relationships = create_relationship_for_indicator_search(response) + + country_codes = scout_ip_data.get('country_codes', []) + scout_ip_hr = [{ + 'Country Code(s)': country_codes, + 'Whois': scout_ip_data.get('summary').get('whois'), + 'Event Count': scout_ip_data.get('event_count'), + 'Tags': scout_ip_data.get('tags', []), + 'Last Seen': scout_ip_data.get('summary', {}).get('last_seen'), + }] + pdns_hr = list(pdn for pdn in scout_ip_data.get('summary', {}).get('pdns', [])) + open_ports_hr = list(open_port for open_port in scout_ip_data.get('summary', {}).get('open_ports', [])) + top_peers_hr = list({'Source IP': ip_address, **top_peer} for top_peer in scout_ip_data.get( + 'summary', {}).get('top_peers', [])) + service_counts_hr = list({'Source IP': ip_address, **service_count} for service_count in scout_ip_data.get( + 'summary', {}).get('service_counts', [])) + fingerprints_hr = list(fingerprint for fingerprint in scout_ip_data.get('summary', {}).get('fingerprints', [])) + certs_hr = list(cert for cert in scout_ip_data.get('summary', {}).get('certs', [])) + + hr_list = [scout_ip_hr, pdns_hr, open_ports_hr, top_peers_hr, service_counts_hr, fingerprints_hr, certs_hr] + new_hr_list = [] + for hr_data in hr_list: + hr_data = remove_empty_elements(hr_data) + [remove_nulls_from_dictionary(data) for data in hr_data] + new_hr_list.append(hr_data) + + (scout_ip_hr, pdns_hr, open_ports_hr, top_peers_hr, service_counts_hr, fingerprints_hr, certs_hr) = new_hr_list + + top_host_name = None + top_host_event_count = 0 + for pdn in pdns_hr: + if pdn.get('event_count') > top_host_event_count: + top_host_event_count = pdn.get('event_count') + top_host_name = pdn.get('domain') + + ip_indicator = Common.IP( + ip=ip_address, + dbot_score=dbot_score, + asn=response.get('summary', {}).get('whois', {}).get('asn'), + as_owner=response.get('summary', {}).get('whois', {}).get('as_name'), + region=', '.join(country_codes), + port=','.join([str(open_port.get('port', '')) + for open_port in response.get('summary', {}).get('open_ports', [])]), + updated_date=response.get('summary', {}).get('last_seen'), + organization_name=response.get('summary', {}).get('whois', {}).get('org_name'), + hostname=top_host_name, + geo_country=', '.join(country_codes), + tags=create_tag_list(scout_ip_data.get('tags', [])), + relationships=relationships, + ) + + ip_md_link = MD_LINK.format(ip_address, INDICATOR_SEARCH_URL.format(ip_address)) + human_readable = tableToMarkdown(f'Summary Information for the given indicator: {ip_md_link}', scout_ip_hr, + json_transform_mapping={'Whois': JsonTransformer(), 'Tags': JsonTransformer()}, + removeNull=True, headerTransform=header_transformer_for_ip, + headers=['IP', 'Country Code(s)', 'Whois', 'Event Count', 'Tags', 'Last Seen']) + '\n' + human_readable += tableToMarkdown('PDNS Information', pdns_hr, + headerTransform=header_transformer_for_ip) + '\n' if pdns_hr else '' + human_readable += tableToMarkdown('Open Ports Information', open_ports_hr, + headerTransform=header_transformer_for_ip) + '\n' if open_ports_hr else '' + human_readable += tableToMarkdown( + 'Top Peers Information', top_peers_hr, headerTransform=header_transformer_for_ip) + '\n' if top_peers_hr else '' + human_readable += tableToMarkdown('Service Counts Information', service_counts_hr, + headerTransform=header_transformer_for_ip) + '\n' if service_counts_hr else '' + human_readable += tableToMarkdown('Fingerprints Information', fingerprints_hr, + headerTransform=header_transformer_for_ip) + '\n' if fingerprints_hr else '' + human_readable += tableToMarkdown('Certs Information', certs_hr, + headerTransform=header_transformer_for_ip) + '\n' if certs_hr else '' + + return human_readable, scout_ip_data, ip_indicator, relationships + + +def prepare_hr_and_context_for_ip_list(response: dict) -> Tuple[str, Dict, Common.IP]: + ''' + A function to prepare the human readable and context output for the ip list command. + + :type response: dict + :param response: The response from the server. + + :rtype: Tuple[str, Dict, Common.IP] + :return: The human readable, context output and the indicator for the ip. + ''' + scout_ip_data = remove_empty_elements(response) + + ip_address = scout_ip_data.get('ip') + + score = DBOT_SCORE_MAPPING[scout_ip_data.get('insights', {}).get('overall_rating') or 'no_rating'] + country_code = scout_ip_data.get('country_code', '') + as_info = scout_ip_data.get('as_info', []) + as_name = '' + asn = '' + if isinstance(as_info, list) and len(as_info) > 0: + as_info_dict = as_info[0] + as_name = as_info_dict.get('as_name', '') + asn = as_info_dict.get('asn', '') + + dbot_score = Common.DBotScore( + indicator=ip_address, + indicator_type=DBotScoreType.IP, + integration_name=VENDOR_NAME, + score=score, + reliability=demisto.params().get('integrationReliability') + ) + + tags = create_tag_list(scout_ip_data.get('tags', [])) + + insight_message = find_description(ip_address, scout_ip_data.get('insights', {}).get('insights', [])) + + ip_ioc = Common.IP( + ip=ip_address, + dbot_score=dbot_score, + asn=asn, + as_owner=as_name, + region=country_code, + geo_country=country_code, + tags=tags, + description=insight_message, + organization_name=as_name, + ) + + ip_md_link = MD_LINK.format(ip_address, INDICATOR_SEARCH_URL.format(ip_address)) + + hr_list = [{ + 'Country Code': scout_ip_data.get('country_code', ''), + 'AS Info': scout_ip_data.get('as_info', ''), + 'Insights': scout_ip_data.get('insights', ''), + 'Tags': scout_ip_data.get('tags', '') + }] + + table_title = f'Summary Information for the given {scoreToReputation(score)} IP: {ip_md_link}' + table_headers = ['Country Code', 'AS Info', 'Insights', 'Tags'] + + hr = tableToMarkdown(table_title, hr_list, removeNull=True, headers=table_headers, + json_transform_mapping={'AS Info': JsonTransformer(), 'Insights': JsonTransformer(), + 'Tags': JsonTransformer()}) + + return hr, scout_ip_data, ip_ioc + + +def prepare_hr_and_context_for_api_usage(response: dict, command_name: str) -> Tuple[str, Dict]: + ''' + A function to prepare the human readable and context output for the api usage. + + :type response: dict + :param response: The response containing the api usage. + + :type command_name: str + :param command_name: The name of the command. + + :rtype: Tuple[str, Dict] + :return: The human readable and context output for the api usage. + ''' + hr_list = [{ + 'Used Queries': response.get('used_queries'), + 'Remaining Queries': response.get('remaining_queries'), + 'Query Limit': response.get('query_limit'), + 'Foundation Used Queries': response.get('foundation_api_usage', {}).get('used_queries'), + 'Foundation Remaining Queries': response.get('foundation_api_usage', {}).get('remaining_queries'), + 'Foundation Query Limit': response.get('foundation_api_usage', {}).get('query_limit'), + }] + + context = {'command_name': command_name, **response} + + table_headers = ['Used Queries', 'Remaining Queries', 'Query Limit', 'Foundation Used Queries', + 'Foundation Remaining Queries', 'Foundation Query Limit'] + + hr = tableToMarkdown('API Usage', hr_list, removeNull=True, headers=table_headers) + + return hr, context + + +def create_relationship(response: dict) -> List: + ''' + Create a list of relationships objects from the response. + + :type response: ``dict`` + :param response: Response of API. + + :return: List of EntityRelationship objects containing all the relationships. + :rtype: ``List`` + ''' + relationships = [] + + for peer in response.get('communications', {}).get('peers', []): + server_ip = peer.get('local', {}).get('ip') + client_ip = peer.get('peer', {}).get('ip') + relationships.append(EntityRelationship(name=EntityRelationship.Relationships.COMMUNICATED_WITH, + entity_a=server_ip, + entity_a_type=FeedIndicatorType.IP, + entity_b=client_ip, + entity_b_type=FeedIndicatorType.IP, + source_reliability=demisto.params().get('integrationReliability'), + brand=VENDOR_NAME)) + + for pdns in response.get('pdns', {}).get('pdns', []): + ip = pdns.get('ip') + domain = pdns.get('domain') + relationships.append(EntityRelationship(name=EntityRelationship.Relationships.RESOLVES_TO, + entity_a=ip, + entity_a_type=FeedIndicatorType.IP, + entity_b=domain, + entity_b_type=FeedIndicatorType.Domain, + source_reliability=demisto.params().get('integrationReliability'), + brand=VENDOR_NAME)) + + return relationships + + +""" COMMAND FUNCTIONS """ + + +def ip_command(client: Client, args: Dict[str, Any]) -> List[CommandResults]: + ''' + Retrieve the detail information of ip that meet the specified filter criteria. + + :type client: ``Client`` + :param client: Object of Client class. + + :type args: ``Dict[str, Any]`` + :param args: Arguments provided by user. + + :rtype: ``List[CommandResults]`` + :return: List of standard command result. + ''' + ips, start_date, end_date, days, size = validate_common_search_command_args(args=args, required_arg='ip') + size = arg_to_number(args.get('size'), 'size') + + ips = argToList(args.get('ip')) + invalid_ips, valid_ips = validate_ip_addresses(ips) + if invalid_ips: + return_warning('The following IP Addresses were found invalid: {}'.format(', '.join(invalid_ips)), + exit=len(invalid_ips) == len(ips)) + + command_results = [] + + for ip in valid_ips: + response = client.ip_request(ip, start_date, end_date, days, size) + response = remove_empty_elements(response) + + ip_response, hr_response = deepcopy(response), deepcopy(response) + usage_response = deepcopy(response.get('usage', {})) + + ip_response, usage_response = remove_key_from_ip_and_add_to_usage(ip_response, usage_response) + + ip_hr_output = prepare_hr_for_ip(response=hr_response) + hr, context = prepare_hr_and_context_for_api_usage(usage_response, 'ip') + + dbot_score = Common.DBotScore( + indicator=ip, + indicator_type=DBotScoreType.IP, + integration_name=VENDOR_NAME, + score=DBOT_SCORE_MAPPING.get(response.get('summary', {}).get('insights', {}).get('overall_rating') or 'no_rating'), + malicious_description=find_description(ip, response.get('summary', {}).get('insights', {}).get('insights', [])), + reliability=demisto.params().get('integrationReliability') + ) + + relationships = [] + create_relationships = demisto.params().get('create_relationships') + if create_relationships: + relationships = create_relationship(response) + + ip_indicator = Common.IP( + ip=ip, + asn=response.get('whois', {}).get('asn'), + as_owner=response.get('whois', {}).get('as_name'), + region=response.get('whois', {}).get('cc'), + organization_name=response.get('whois', {}).get('org_name'), + updated_date=response.get('whois', {}).get('modified'), + description=find_description(ip, response.get('summary', {}).get('insights', {}).get('insights', [])), + port=', '.join([str(data.get('port', '')) for data in response.get('open_ports', {}).get('open_ports', [])]), + tags=create_tag_list(response.get('summary', {}).get('tags', [])), + dbot_score=dbot_score, + relationships=relationships + ) + + command_result = [CommandResults( + outputs_prefix=OUTPUT_PREFIX['IP'], + outputs_key_field=OUTPUT_KEY_FIELD['IP'], + outputs=ip_response, + raw_response=response, + readable_output=ip_hr_output, + indicator=ip_indicator, + relationships=relationships + ), CommandResults( + outputs_prefix=OUTPUT_PREFIX['QUERY_USAGE'], + outputs_key_field=OUTPUT_KEY_FIELD['QUERY_USAGE'], + outputs=context, + raw_response=response, + readable_output=hr, + )] + + command_results.extend(command_result) + + return command_results + + +def scout_api_usage_command(client: Client, *_) -> CommandResults: + ''' + The command function to request the information for the API usage. + + :type client: Client + :param client: The client object. + + :rtype: CommandResults + :return: The command results containing the human readable and context output for the api usage. + ''' + + response = client.scout_api_usage_request() + + hr, context = prepare_hr_and_context_for_api_usage(response, 'scout-api-usage') + + command_results = CommandResults( + outputs_prefix=OUTPUT_PREFIX['QUERY_USAGE'], + outputs_key_field='command_name', + outputs=context, + raw_response=response, + readable_output=hr, + ) + + return command_results + + +def scout_indicator_search_command(client: Client, args: Dict[str, Any]) -> List[CommandResults]: + ''' + The command function to request the information for the API usage. + + :type client: Client + :param client: The client object. + + :type args: Dict + :param args: The arguments passed to the command. + + :rtype: CommandResults + :return: The command results containing the human readable and context output for the api usage. + ''' + validated_args = validate_common_search_command_args(args, 'query', MAXIMUM_INDICATOR_SEARCH_SIZE) + + response = client.scout_indicator_search_request(*validated_args) # type: ignore + + ips_response = response.get('ips', []) + ip_command_results = [] + if not ips_response: + ip_command_results.append(CommandResults( + readable_output=ERROR_MESSAGES['NO_INDICATORS_FOUND'], + )) + else: + for ip_response in ips_response: + raw_ip_response = deepcopy(ip_response) + ip_response = remove_empty_elements(ip_response) + ip_hr, ip_context, ip_indicator, relationships = prepare_hr_and_context_for_indicator_search(ip_response) + ip_command_results.append(CommandResults( + outputs_prefix=OUTPUT_PREFIX['IP'], + outputs_key_field='ip', + outputs=ip_context, + raw_response=raw_ip_response, + readable_output=ip_hr, + indicator=ip_indicator, + relationships=relationships, + )) + + usage_response = {key: value for key, value in response.items() if key != 'ips'} + + usage_hr, usage_context = prepare_hr_and_context_for_api_usage( + usage_response.get('usage', {}), 'scout-indicator-search') + usage_context.update(usage_response) + remove_empty_elements(usage_context) + usage_context.pop('usage', None) + + usage_command_result = CommandResults( + outputs_prefix=OUTPUT_PREFIX['QUERY_USAGE'], + outputs_key_field='command_name', + outputs=usage_context, + raw_response=usage_response, + readable_output=usage_hr, + ) + + return [*ip_command_results, usage_command_result] + + +def scout_ip_list_command(client: Client, args: Dict) -> List[CommandResults]: + ''' + A function to get the ip list from the Team Cymru Scout server. + + :type client: Client + :param client: The client object. + + :type args: Dict + :param args: The arguments passed to the command. + + :rtype: List[CommandResults] + :return: The command results containing the human readable and context output for the ip list and api usage. + ''' + validated_args = validate_ip_list_args(args) + response = client.scout_ip_list(params=validated_args) + ips_data = deepcopy(response.get('data', [])) + ip_command_results = [] + + if not ips_data: + ip_command_results.append(CommandResults( + readable_output=ERROR_MESSAGES['NO_INDICATORS_FOUND'], + )) + else: + for ip_response in ips_data: + ip_hr, ip_context, ip_indicator = prepare_hr_and_context_for_ip_list(ip_response) + ip_command_results.append(CommandResults( + outputs_prefix=OUTPUT_PREFIX['IP'], + outputs_key_field=OUTPUT_KEY_FIELD['IP'], + outputs=ip_context, + raw_response=ip_response, + readable_output=ip_hr, + indicator=ip_indicator, + )) + + usage_response = {key: value for key, value in response.items() if key != 'data'} + + usage_hr, usage_context = prepare_hr_and_context_for_api_usage(usage_response.get('usage', {}), 'scout-ip-list') + usage_context.update(usage_response) + remove_empty_elements(usage_context) + usage_context.pop('usage', None) + + usage_command_result = CommandResults( + outputs_prefix=OUTPUT_PREFIX['QUERY_USAGE'], + outputs_key_field=OUTPUT_KEY_FIELD['QUERY_USAGE'], + outputs=usage_context, + raw_response=usage_response, + readable_output=usage_hr, + ) + return [*ip_command_results, usage_command_result] + + +def test_module(client: Client) -> str: + ''' + Test the Team Cymru Scout instance configuration. + + :type client: ``Client`` + :param: client: Object of Client class. + + :return: 'ok' if test passed, anything else will fail the test. + :rtype: ``str`` + ''' + client.scout_api_usage_request() + return 'ok' + + +def main() -> None: + '''main function, parses params and runs command functions.''' + params = trim_spaces_from_args(demisto.params()) + remove_nulls_from_dictionary(params) + + args = trim_spaces_from_args(demisto.args()) + remove_nulls_from_dictionary(args) + + verify_certificate: bool = not argToBoolean(params.get('insecure', False)) + proxy: bool = argToBoolean(params.get('proxy', False)) + + headers = {} + authentication_type = params.get('authentication_type', '') + + if authentication_type == API_KEY: + api_key = str(params.get('api_key', {}).get('password', '')).strip() + headers['Authorization'] = f'Token {api_key}' + auth_tuple = None + elif authentication_type == BASIC_AUTH: + basic_auth = params.get('basic_auth', {}) + username = str(basic_auth.get('identifier', '')).strip() + password = str(basic_auth.get('password', '')).strip() + auth_tuple = (username, password) + + command = demisto.command() + demisto.debug(f'Command being called is {command}.') + + try: + urllib3.disable_warnings() + validate_params(params) + + client: Client = Client(BASE_URL, verify_certificate, proxy, headers=headers, auth=auth_tuple) + + commands: Dict[str, Callable] = { + 'ip': ip_command, + 'scout-api-usage': scout_api_usage_command, + 'scout-indicator-search': scout_indicator_search_command, + 'scout-ip-list': scout_ip_list_command, + } + + if command == 'test-module': + return_results(test_module(client)) + elif command in commands: + return_results(commands[command](client, args)) + else: + raise NotImplementedError(f'{command} command is not implemented.') + + except Exception as e: + return_error(str(e)) + + +if __name__ in ['__main__', 'builtin', 'builtins']: + main() diff --git a/Packs/TeamCymru/Integrations/TeamCymruScout/TeamCymruScout.yml b/Packs/TeamCymru/Integrations/TeamCymruScout/TeamCymruScout.yml new file mode 100644 index 000000000000..d4aed2864eaf --- /dev/null +++ b/Packs/TeamCymru/Integrations/TeamCymruScout/TeamCymruScout.yml @@ -0,0 +1,1581 @@ +commonfields: + id: Team Cymru Scout + version: -1 +name: Team Cymru Scout +display: Team Cymru Scout +category: Data Enrichment & Threat Intelligence +description: The Team Cymru Scout integration enables getting immediate insight on IP addresses and domains for threat investigations. +configuration: +- additionalinfo: The authentication type used for secure communication with the Team Cymru Scout platform. + defaultvalue: API Key + display: Authentication Type + name: authentication_type + options: + - API Key + - Basic Auth + type: 15 + required: true +- displaypassword: API Key + additionalinfo: "The API key used for secure communication with the Team Cymru Scout platform. Required if \"API Key\" as Authentication Type is selected." + name: api_key + hiddenusername: true + type: 9 + required: false +- display: Username + displaypassword: Password + additionalinfo: "The username and password used for secure communication with the Team Cymru Scout platform. Required if \"Basic Auth\" as Authentication Type is selected." + name: basic_auth + type: 9 + required: false +- additionalinfo: Reliability of the source providing the intelligence data. + defaultvalue: A - Completely reliable + display: Source Reliability + name: integrationReliability + options: + - A+ - 3rd party enrichment + - A - Completely reliable + - B - Usually reliable + - C - Fairly reliable + - D - Not usually reliable + - E - Unreliable + - F - Reliability cannot be judged + type: 15 + required: false +- defaultvalue: 'true' + additionalinfo: Create relationships between indicators as part of enrichment. + display: Create relationships + name: create_relationships + type: 8 + required: false +- name: proxy + display: Use system proxy settings + defaultvalue: 'false' + type: 8 + required: false +- name: insecure + display: Trust any certificate (not secure) + defaultvalue: 'false' + type: 8 + required: false +script: + script: '' + type: python + subtype: python3 + dockerimage: demisto/python3:3.11.9.106968 + isfetch: false + commands: + - name: scout-api-usage + description: 'Returns all the information on used queries and remaining queries with the query limit.' + outputs: + - type: String + contextPath: TeamCymruScout.QueryUsage.command_name + description: 'The name of the Cortex XSOAR command that triggered the Foundation API.' + - type: Number + contextPath: TeamCymruScout.QueryUsage.used_queries + description: 'The number of queries used.' + - type: Number + contextPath: TeamCymruScout.QueryUsage.remaining_queries + description: 'The number of remaining queries.' + - type: Number + contextPath: TeamCymruScout.QueryUsage.query_limit + description: 'The total number of queries allowed.' + - type: Number + contextPath: TeamCymruScout.QueryUsage.foundation_api_usage.used_queries + description: 'The number of queries used for the Foundation API.' + - type: Number + contextPath: TeamCymruScout.QueryUsage.foundation_api_usage.remaining_queries + description: 'The number of remaining queries for the Foundation API.' + - type: Number + contextPath: TeamCymruScout.QueryUsage.foundation_api_usage.query_limit + description: 'The total number of queries allowed for the Foundation API.' + - name: ip + description: Return all the detailed information available for the given IP address. + arguments: + - name: ip + description: The IP address for which to retrieve available IP details. + required: true + isArray: true + default: true + - name: start_date + defaultValue: '30 days' + description: "The start date for detailed information.\n\nSupported formats: 2 days, 2 weeks, 2 months, yyyy-mm-dd.\n\nFor example: 01 June 2024, 2024-06-17." + - name: end_date + defaultValue: 'now' + description: "The end date for detailed information.\n\nSupported formats: 2 days, 2 weeks, 2 months, yyyy-mm-dd.\n\nFor example: 01 June 2024, 2024-06-17." + - name: days + description: "Relative offset in days from the current time. It cannot exceed the maximum range of 30 days.\n\nNote: This will take priority over start_date and end_date if all three are passed." + - name: size + description: "The maximum number of records to return.\n\nNote: The maximum allowed size is 1000." + outputs: + - contextPath: DBotScore.Indicator + description: The indicator that was tested. + type: String + - contextPath: DBotScore.Type + description: The indicator type. + type: String + - contextPath: DBotScore.Vendor + description: The vendor used to calculate the score. + type: String + - contextPath: DBotScore.Score + description: The actual score. + type: Number + - contextPath: DBotScore.Reliability + description: Reliability of the source providing the intelligence data. + type: String + - contextPath: IP.Address + description: IP address. + type: String + - contextPath: IP.Relationships.EntityA + description: The source of the relationship. + type: String + - contextPath: IP.Relationships.EntityB + description: The destination of the relationship. + type: String + - contextPath: IP.Relationships.Relationship + description: The name of the relationship. + type: String + - contextPath: IP.Relationships.EntityAType + description: The type of the source of the relationship. + type: String + - contextPath: IP.Relationships.EntityBType + description: The type of the destination of the relationship. + type: String + - contextPath: IP.ASN + description: 'The autonomous system name for the IP address, for example: "AS8948".' + type: String + - contextPath: IP.Hostname + description: The hostname that is mapped to this IP address. + type: String + - contextPath: IP.Geo.Location + description: 'The geolocation where the IP address is located, in the format: latitude:longitude.' + type: String + - contextPath: IP.Geo.Country + description: The country in which the IP address is located. + type: String + - contextPath: IP.Geo.Description + description: Additional information about the location. + type: String + - contextPath: IP.DetectionEngines + description: The total number of engines that checked the indicator. + type: Number + - contextPath: IP.PositiveDetections + description: The number of engines that positively detected the indicator as malicious. + type: Number + - contextPath: IP.Malicious.Vendor + description: The vendor reporting the IP address as malicious. + type: String + - contextPath: IP.Malicious.Description + description: A description explaining why the IP address was reported as malicious. + type: String + - contextPath: IP.Tags + description: (List) Tags of the IP address. + type: Unknown + - contextPath: IP.FeedRelatedIndicators.value + description: Indicators that are associated with the IP address. + type: String + - contextPath: IP.FeedRelatedIndicators.type + description: The type of the indicators that are associated with the IP address. + type: String + - contextPath: IP.FeedRelatedIndicators.description + description: The description of the indicators that are associated with the IP address. + type: String + - contextPath: IP.MalwareFamily + description: The malware family associated with the IP address. + type: String + - contextPath: IP.Organization.Name + description: The organization of the IP address. + type: String + - contextPath: IP.Organization.Type + description: The organization type of the IP address. + type: String + - contextPath: IP.ASOwner + description: The autonomous system owner of the IP address. + type: String + - contextPath: IP.Region + description: The region in which the IP address is located. + type: String + - contextPath: IP.Port + description: Ports that are associated with the IP address. + type: String + - contextPath: IP.Internal + description: Whether the IP address is internal or external. + type: Boolean + - contextPath: IP.UpdatedDate + description: The date that the IP address was last updated. + type: Date + - contextPath: IP.Registrar.Abuse.Name + description: The name of the contact for reporting abuse. + type: String + - contextPath: IP.Registrar.Abuse.Address + description: The address of the contact for reporting abuse. + type: String + - contextPath: IP.Registrar.Abuse.Country + description: The country of the contact for reporting abuse. + type: String + - contextPath: IP.Registrar.Abuse.Network + description: The network of the contact for reporting abuse. + type: String + - contextPath: IP.Registrar.Abuse.Phone + description: The phone number of the contact for reporting abuse. + type: String + - contextPath: IP.Registrar.Abuse.Email + description: The email address of the contact for reporting abuse. + type: String + - contextPath: IP.Campaign + description: The campaign associated with the IP address. + type: String + - contextPath: IP.TrafficLightProtocol + description: The Traffic Light Protocol (TLP) color that is suitable for the IP address. + type: String + - contextPath: IP.CommunityNotes.note + description: Notes on the IP address that were given by the community. + type: String + - contextPath: IP.CommunityNotes.timestamp + description: The time in which the note was published. + type: Date + - contextPath: IP.Publications.source + description: The source in which the article was published. + type: String + - contextPath: IP.Publications.title + description: The name of the article. + type: String + - contextPath: IP.Publications.link + description: A link to the original article. + type: String + - contextPath: IP.Publications.timestamp + description: The time in which the article was published. + type: Date + - contextPath: IP.ThreatTypes.threatcategory + description: The threat category associated to this indicator by the source vendor. For example, Phishing, Control, TOR, etc. + type: String + - contextPath: IP.ThreatTypes.threatcategoryconfidence + description: The confidence level provided by the vendor for the threat type category For example, a confidence of 90 for the threat type category 'malware' means that the vendor rates that this is 90% confidence of being a malware. + type: String + - contextPath: TeamCymruScout.QueryUsage.request_id + description: 'The request ID of the API call.' + type: String + - contextPath: TeamCymruScout.QueryUsage.size + description: 'The number of records returned.' + type: Number + - contextPath: TeamCymruScout.QueryUsage.start_date + description: 'The earliest date for detailed information.' + type: Date + - contextPath: TeamCymruScout.QueryUsage.end_date + description: 'The latest date for detailed information.' + type: Date + - contextPath: TeamCymruScout.QueryUsage.used_queries + description: 'The number of queries used.' + type: Number + - contextPath: TeamCymruScout.QueryUsage.remaining_queries + description: 'The number of remaining queries.' + type: Number + - contextPath: TeamCymruScout.QueryUsage.query_limit + description: 'The maximum number of queries allowed.' + type: Number + - contextPath: TeamCymruScout.QueryUsage.foundation_api_usage.used_queries + description: 'The number of queries used by the Foundation API.' + type: Number + - contextPath: TeamCymruScout.QueryUsage.foundation_api_usage.remaining_queries + description: 'The number of remaining queries for the Foundation API.' + type: Number + - contextPath: TeamCymruScout.QueryUsage.foundation_api_usage.query_limit + description: 'The maximum number of queries allowed for the Foundation API.' + type: Numbe + - contextPath: TeamCymruScout.IP.ip + description: 'The IP address.' + type: String + - contextPath: TeamCymruScout.IP.sections + description: 'The sections of data returned.' + type: String + - contextPath: TeamCymruScout.IP.identity.tags + description: 'The tags associated with the IP address.' + type: Unknown + - contextPath: TeamCymruScout.IP.identity.reverse_hostnames + description: 'The reverse hostnames associated with the IP address.' + type: Unknown + - contextPath: TeamCymruScout.IP.identity.asn + description: 'The autonomous system number associated with the IP address.' + type: Number + - contextPath: TeamCymruScout.IP.identity.as_name + description: 'The name associated with the autonomous system number.' + type: String + - contextPath: TeamCymruScout.IP.identity.net_name + description: 'The name associated with the network.' + type: String + - contextPath: TeamCymruScout.IP.identity.org_name + description: 'The name associated with the organization.' + type: String + - contextPath: TeamCymruScout.IP.whois.modified + description: 'The date the WHOIS information was last modified.' + type: Date + - contextPath: TeamCymruScout.IP.whois.asn + description: 'The autonomous system number associated with the IP address.' + type: Number + - contextPath: TeamCymruScout.IP.whois.cidr + description: 'The network associated with the IP address.' + type: String + - contextPath: TeamCymruScout.IP.whois.as_name + description: 'The name associated with the autonomous system number.' + type: String + - contextPath: TeamCymruScout.IP.whois.bgp_asn + description: 'The Border Gateway Protocol (BGP) autonomous system number (ASN) associated with the IP address.' + type: Number + - contextPath: TeamCymruScout.IP.whois.bgp_asn_name + description: 'The name associated with the Border Gateway Protocol (BGP) autonomous system number (ASN).' + type: String + - contextPath: TeamCymruScout.IP.whois.net_name + description: 'The name associated with the network.' + type: String + - contextPath: TeamCymruScout.IP.whois.net_handle + description: 'The handle associated with the network.' + type: String + - contextPath: TeamCymruScout.IP.whois.description + description: 'The description associated with the network.' + type: String + - contextPath: TeamCymruScout.IP.whois.cc + description: 'The country code associated with the network.' + type: String + - contextPath: TeamCymruScout.IP.whois.city + description: 'The city associated with the network.' + type: String + - contextPath: TeamCymruScout.IP.whois.address + description: 'The address associated with the network.' + type: String + - contextPath: TeamCymruScout.IP.whois.abuse_contact_id + description: 'The abuse contact ID associated with the network.' + type: String + - contextPath: TeamCymruScout.IP.whois.about_contact_role + description: 'The role associated with the about contact.' + type: String + - contextPath: TeamCymruScout.IP.whois.about_contact_person + description: 'The person associated with the about contact.' + type: String + - contextPath: TeamCymruScout.IP.whois.about_contact_email + description: 'The email associated with the about contact.' + type: String + - contextPath: TeamCymruScout.IP.whois.about_contact_phone + description: 'The phone number associated with the about contact.' + type: String + - contextPath: TeamCymruScout.IP.whois.about_contact_country + description: 'The country associated with the about contact.' + type: String + - contextPath: TeamCymruScout.IP.whois.about_contact_city + description: 'The city associated with the about contact.' + type: String + - contextPath: TeamCymruScout.IP.whois.about_contact_address + description: 'The address associated with the about contact.' + type: String + - contextPath: TeamCymruScout.IP.whois.admin_contact_id + description: 'The ID associated with the admin contact.' + type: String + - contextPath: TeamCymruScout.IP.whois.admin_contact_role + description: 'The role associated with the admin contact.' + type: String + - contextPath: TeamCymruScout.IP.whois.admin_contact_person + description: 'The person associated with the admin contact.' + type: String + - contextPath: TeamCymruScout.IP.whois.admin_contact_email + description: 'The email associated with the admin contact.' + type: String + - contextPath: TeamCymruScout.IP.whois.admin_contact_phone + description: 'The phone number associated with the admin contact.' + type: String + - contextPath: TeamCymruScout.IP.whois.admin_contact_country + description: 'The country associated with the admin contact.' + type: String + - contextPath: TeamCymruScout.IP.whois.admin_contact_city + description: 'The city associated with the admin contact.' + type: String + - contextPath: TeamCymruScout.IP.whois.admin_contact_address + description: 'The address associated with the admin contact.' + type: String + - contextPath: TeamCymruScout.IP.whois.tech_contact_id + description: 'The ID associated with the tech contact.' + type: String + - contextPath: TeamCymruScout.IP.whois.tech_contact_role + description: 'The role associated with the tech contact.' + type: String + - contextPath: TeamCymruScout.IP.whois.tech_contact_person + description: 'The person associated with the tech contact.' + type: String + - contextPath: TeamCymruScout.IP.whois.tech_contact_email + description: 'The email associated with the tech contact.' + type: String + - contextPath: TeamCymruScout.IP.whois.tech_contact_phone + description: 'The phone number associated with the tech contact.' + type: String + - contextPath: TeamCymruScout.IP.whois.tech_contact_country + description: 'The country associated with the tech contact.' + type: String + - contextPath: TeamCymruScout.IP.whois.tech_contact_city + description: 'The city associated with the tech contact.' + type: String + - contextPath: TeamCymruScout.IP.whois.tech_contact_address + description: 'The address associated with the tech contact.' + type: String + - contextPath: TeamCymruScout.IP.whois.org_id + description: 'The ID associated with the organization.' + type: String + - contextPath: TeamCymruScout.IP.whois.org_name + description: 'The name associated with the organization.' + type: String + - contextPath: TeamCymruScout.IP.whois.org_email + description: 'The email associated with the organization.' + type: String + - contextPath: TeamCymruScout.IP.whois.org_phone + description: 'The phone number associated with the organization.' + type: String + - contextPath: TeamCymruScout.IP.whois.org_country + description: 'The country associated with the organization.' + type: String + - contextPath: TeamCymruScout.IP.whois.org_city + description: 'The city associated with the organization.' + type: String + - contextPath: TeamCymruScout.IP.whois.org_address + description: 'The address associated with the organization.' + type: String + - contextPath: TeamCymruScout.IP.whois.mnt_by_email + description: 'The email associated with the maintainer.' + type: String + - contextPath: TeamCymruScout.IP.whois.mnt_lower_email + description: 'The email associated with the lower maintenance router.' + type: String + - contextPath: TeamCymruScout.IP.whois.mnt_router_email + description: 'The email associated with the maintenance router.' + type: String + - contextPath: TeamCymruScout.IP.communications.event_count + description: 'The count of events associated with the communication.' + type: Number + - contextPath: TeamCymruScout.IP.communications.peers.proto + description: 'The protocol associated with the peer.' + type: Number + - contextPath: TeamCymruScout.IP.communications.peers.proto_text + description: 'The text associated with the protocol of the peer.' + type: String + - contextPath: TeamCymruScout.IP.communications.peers.local.ip + description: 'The IP address associated with the local peer.' + type: String + - contextPath: TeamCymruScout.IP.communications.peers.local.min_port + description: 'The minimum port associated with the local peer.' + type: Number + - contextPath: TeamCymruScout.IP.communications.peers.local.max_port + description: 'The maximum port associated with the local peer.' + type: Number + - contextPath: TeamCymruScout.IP.communications.peers.local.country_codes + description: 'The country codes associated with the local peer.' + type: String + - contextPath: TeamCymruScout.IP.communications.peers.local.as_info.asn + description: 'The autonomous system number associated with the local peer.' + type: Number + - contextPath: TeamCymruScout.IP.communications.peers.local.as_info.as_name + description: 'The name associated with the autonomous system number of the local peer.' + type: String + - contextPath: TeamCymruScout.IP.communications.peers.local.tags.id + description: 'The ID of the tags associated with the local peer.' + type: Number + - contextPath: TeamCymruScout.IP.communications.peers.local.tags.name + description: 'The name of the tags associated with the local peer.' + type: String + - contextPath: TeamCymruScout.IP.communications.peers.local.tags.children.id + description: 'The ID of the child tags associated with the local peer.' + type: Number + - contextPath: TeamCymruScout.IP.communications.peers.local.tags.children.name + description: 'The name of the child tags associated with the local peer.' + type: String + - contextPath: TeamCymruScout.IP.communications.peers.local.tags.children.children + description: 'The children of the child tags associated with the local peer.' + type: Unknown + - contextPath: TeamCymruScout.IP.communications.peers.local.unique_ports + description: 'The unique ports associated with the local peer.' + type: Number + - contextPath: TeamCymruScout.IP.communications.peers.local.top_services.service_name + description: 'The name of the top service associated with the local peer.' + type: String + - contextPath: TeamCymruScout.IP.communications.peers.local.top_services.port + description: 'The port associated with the top service of the local peer.' + type: Number + - contextPath: TeamCymruScout.IP.communications.peers.local.top_services.proto_number + description: 'The protocol number associated with the top service of the local peer.' + type: Number + - contextPath: TeamCymruScout.IP.communications.peers.local.top_services.description + description: 'The description associated with the top service of the local peer.' + type: String + - contextPath: TeamCymruScout.IP.communications.peers.peer.ip + description: 'The IP address associated with the peer.' + type: String + - contextPath: TeamCymruScout.IP.communications.peers.peer.min_port + description: 'The minimum port associated with the peer.' + type: Number + - contextPath: TeamCymruScout.IP.communications.peers.peer.max_port + description: 'The maximum port associated with the peer.' + type: Number + - contextPath: TeamCymruScout.IP.communications.peers.peer.country_codes + description: 'The country codes associated with the peer.' + type: String + - contextPath: TeamCymruScout.IP.communications.peers.peer.as_info.asn + description: 'The autonomous system number associated with the peer.' + type: Number + - contextPath: TeamCymruScout.IP.communications.peers.peer.as_info.as_name + description: 'The name associated with the autonomous system number of the peer.' + type: String + - contextPath: TeamCymruScout.IP.communications.peers.peer.tags + description: 'The tags associated with the peer.' + type: Unknown + - contextPath: TeamCymruScout.IP.communications.peers.peer.unique_ports + description: 'The unique ports associated with the peer.' + type: Number + - contextPath: TeamCymruScout.IP.communications.peers.peer.top_services.service_name + description: 'The name of the top service associated with the peer.' + type: String + - contextPath: TeamCymruScout.IP.communications.peers.peer.top_services.port + description: 'The port associated with the top service of the peer.' + type: Number + - contextPath: TeamCymruScout.IP.communications.peers.peer.top_services.proto_number + description: 'The protocol number associated with the top service of the peer.' + type: Number + - contextPath: TeamCymruScout.IP.communications.peers.peer.top_services.description + description: 'The description associated with the top service of the peer.' + type: String + - contextPath: TeamCymruScout.IP.communications.peers.event_count + description: 'The number of events associated with the communication.' + type: Number + - contextPath: TeamCymruScout.IP.communications.peers.first_seen + description: 'The first seen date associated with the communication.' + type: Date + - contextPath: TeamCymruScout.IP.communications.peers.last_seen + description: 'The last seen date associated with the communication.' + type: Date + - contextPath: TeamCymruScout.IP.communications.peers.peer.tags.id + description: 'The ID of the tags associated with the peer.' + type: Number + - contextPath: TeamCymruScout.IP.communications.peers.peer.tags.name + description: 'The name of the tags associated with the peer.' + type: String + - contextPath: TeamCymruScout.IP.communications.peers.peer.tags.children.id + description: 'The ID of the child tags associated with the peer.' + type: Number + - contextPath: TeamCymruScout.IP.communications.peers.peer.tags.children.name + description: 'The name of the child tags associated with the peer.' + type: String + - contextPath: TeamCymruScout.IP.communications.peers.peer.tags.children.children.id + description: 'The ID of the grandchild tags associated with the peer.' + type: Number + - contextPath: TeamCymruScout.IP.communications.peers.peer.tags.children.children.name + description: 'The name of the grandchild tags associated with the peer.' + type: String + - contextPath: TeamCymruScout.IP.communications.peers.peer.tags.children.children.children + description: 'The children of the grandchild tags associated with the peer.' + type: Unknown + - contextPath: TeamCymruScout.IP.communications.peers.peer.tags.children.children + description: 'The grandchild tags associated with the peer.' + type: Unknown + - contextPath: TeamCymruScout.IP.communications.peers.peer.tags.children + description: 'The child tags associated with the peer.' + type: Unknown + - contextPath: TeamCymruScout.IP.pdns.event_count + description: 'The number of events associated with the PDNS.' + type: Number + - contextPath: TeamCymruScout.IP.pdns.pdns.ip + description: 'The IP address associated with the PDNS.' + type: String + - contextPath: TeamCymruScout.IP.pdns.pdns.domain + description: 'The domain associated with the PDNS.' + type: String + - contextPath: TeamCymruScout.IP.pdns.pdns.root + description: 'The root associated with the PDNS.' + type: String + - contextPath: TeamCymruScout.IP.pdns.pdns.tld + description: 'The top level domain (TLD) associated with the PDNS.' + type: String + - contextPath: TeamCymruScout.IP.pdns.pdns.type + description: 'The type associated with the PDNS.' + type: String + - contextPath: TeamCymruScout.IP.pdns.pdns.registrar + description: 'The registrar associated with the PDNS.' + type: String + - contextPath: TeamCymruScout.IP.pdns.pdns.domain_created + description: 'The creation date associated with the PDNS.' + type: Date + - contextPath: TeamCymruScout.IP.pdns.pdns.domain_expires + description: 'The expiration date associated with the PDNS.' + type: Date + - contextPath: TeamCymruScout.IP.pdns.pdns.nameservers.root + description: 'The root of the nameserver associated with the PDNS.' + type: String + - contextPath: TeamCymruScout.IP.pdns.pdns.nameservers.nameservers + description: 'The nameservers associated with the PDNS.' + type: String + - contextPath: TeamCymruScout.IP.pdns.pdns.country_codes + description: 'The country codes associated with the PDNS.' + type: String + - contextPath: TeamCymruScout.IP.pdns.pdns.as_info.asn + description: 'The autonomous system number associated with the PDNS.' + type: Number + - contextPath: TeamCymruScout.IP.pdns.pdns.as_info.as_name + description: 'The name associated with the autonomous system number of the PDNS.' + type: String + - contextPath: TeamCymruScout.IP.pdns.pdns.tags + description: 'The tags associated with the PDNS.' + type: Unknown + - contextPath: TeamCymruScout.IP.pdns.pdns.distinct_ips + description: 'The number of distinct IP addresses associated with the PDNS.' + type: Number + - contextPath: TeamCymruScout.IP.pdns.pdns.active_days + description: 'The number of active days associated with the PDNS.' + type: Number + - contextPath: TeamCymruScout.IP.pdns.pdns.event_count + description: 'The count of events associated with the PDNS.' + type: Number + - contextPath: TeamCymruScout.IP.pdns.pdns.first_seen + description: 'The first date the PDNS was seen.' + type: Date + - contextPath: TeamCymruScout.IP.pdns.pdns.last_seen + description: 'The last date the PDNS was seen.' + type: Date + - contextPath: TeamCymruScout.IP.pdns.pdns.nameservers + description: 'The nameservers of the PDNS.' + type: Unknown + - contextPath: TeamCymruScout.IP.fingerprints.event_count + description: 'The number of events associated with the fingerprints.' + type: Number + - contextPath: TeamCymruScout.IP.fingerprints.fingerprints.ip + description: 'The IP address of the fingerprint.' + type: String + - contextPath: TeamCymruScout.IP.fingerprints.fingerprints.type + description: 'The type of the fingerprint.' + type: String + - contextPath: TeamCymruScout.IP.fingerprints.fingerprints.fingerprint + description: 'The fingerprint of the host.' + type: String + - contextPath: TeamCymruScout.IP.fingerprints.fingerprints.port + description: 'The port of the fingerprint.' + type: Number + - contextPath: TeamCymruScout.IP.fingerprints.fingerprints.first_seen + description: 'The first date the fingerprint was seen.' + type: Date + - contextPath: TeamCymruScout.IP.fingerprints.fingerprints.last_seen + description: 'The last date the fingerprint was seen.' + type: Date + - contextPath: TeamCymruScout.IP.fingerprints.fingerprints.distinct_ips + description: 'The number of distinct IP addresses associated with the fingerprints.' + type: Number + - contextPath: TeamCymruScout.IP.fingerprints.fingerprints.active_days + description: 'The number of active days associated with the fingerprints.' + type: Number + - contextPath: TeamCymruScout.IP.fingerprints.fingerprints.event_count + description: 'The number of events associated with the fingerprints.' + type: Number + - contextPath: TeamCymruScout.IP.open_ports.event_count + description: 'The number of events associated with the open ports.' + type: Number + - contextPath: TeamCymruScout.IP.open_ports.unique_ports + description: 'The number of unique ports in the open ports.' + type: Number + - contextPath: TeamCymruScout.IP.open_ports.open_ports.ip + description: 'The IP address of the open port.' + type: String + - contextPath: TeamCymruScout.IP.open_ports.open_ports.port + description: 'The port of the open port.' + type: Number + - contextPath: TeamCymruScout.IP.open_ports.open_ports.protocol + description: 'The protocol of the open port.' + type: Number + - contextPath: TeamCymruScout.IP.open_ports.open_ports.protocol_text + description: 'The protocol text of the open port.' + type: String + - contextPath: TeamCymruScout.IP.open_ports.open_ports.service + description: 'The service of the open port.' + type: String + - contextPath: TeamCymruScout.IP.open_ports.open_ports.banner + description: 'The banner of the open port.' + type: String + - contextPath: TeamCymruScout.IP.open_ports.open_ports.banner_sha1 + description: 'The SHA1 hash of the banner of the open port.' + type: String + - contextPath: TeamCymruScout.IP.open_ports.open_ports.first_seen + description: 'The first date the open port was seen.' + type: Date + - contextPath: TeamCymruScout.IP.open_ports.open_ports.last_seen + description: 'The last date the open port was seen.' + type: Date + - contextPath: TeamCymruScout.IP.open_ports.open_ports.country_codes + description: 'The country codes of the open port.' + type: String + - contextPath: TeamCymruScout.IP.open_ports.open_ports.as_info.asn + description: 'The autonomous system number of the open port.' + type: Number + - contextPath: TeamCymruScout.IP.open_ports.open_ports.as_info.as_name + description: 'The name of the autonomous system number of the open port.' + type: String + - contextPath: TeamCymruScout.IP.open_ports.open_ports.tags.id + description: 'The ID of the tag associated with the open port.' + type: Number + - contextPath: TeamCymruScout.IP.open_ports.open_ports.tags.name + description: 'The name of the tag associated with the open port.' + type: String + - contextPath: TeamCymruScout.IP.open_ports.open_ports.tags.children.id + description: 'The ID of the child tag associated with the open port.' + type: Number + - contextPath: TeamCymruScout.IP.open_ports.open_ports.tags.children.name + description: 'The name of the child tag associated with the open port.' + type: String + - contextPath: TeamCymruScout.IP.open_ports.open_ports.tags.children.children + description: 'The child tags of the child tag associated with the open port.' + type: Unknown + - contextPath: TeamCymruScout.IP.open_ports.open_ports.event_count + description: 'The number of events associated with the open port.' + type: Number + - contextPath: TeamCymruScout.IP.x509.event_count + description: 'The number of events associated with the x509 certificate.' + type: Number + - contextPath: TeamCymruScout.IP.x509.x509.ip + description: 'The IP address associated with the x509 certificate.' + type: String + - contextPath: TeamCymruScout.IP.x509.x509.issuer + description: 'The issuer of the x509 certificate.' + type: String + - contextPath: TeamCymruScout.IP.x509.x509.issuer_common_name + description: 'The common name of the issuer of the x509 certificate.' + type: String + - contextPath: TeamCymruScout.IP.x509.x509.common_name + description: 'The common name of the x509 certificate.' + type: String + - contextPath: TeamCymruScout.IP.x509.x509.altnames + description: 'The alternative names associated with the x509 certificate.' + type: String + - contextPath: TeamCymruScout.IP.x509.x509.serial + description: 'The serial number of the x509 certificate.' + type: String + - contextPath: TeamCymruScout.IP.x509.x509.subject + description: 'The subject of the x509 certificate.' + type: String + - contextPath: TeamCymruScout.IP.x509.x509.not_after + description: 'The expiration date of the x509 certificate.' + type: Date + - contextPath: TeamCymruScout.IP.x509.x509.not_before + description: 'The start date of the x509 certificate.' + type: Date + - contextPath: TeamCymruScout.IP.x509.x509.validity_period + description: 'The validity period of the x509 certificate.' + type: String + - contextPath: TeamCymruScout.IP.x509.x509.md5 + description: 'The MD5 hash of the x509 certificate.' + type: String + - contextPath: TeamCymruScout.IP.x509.x509.sha1 + description: 'The SHA1 hash of the x509 certificate.' + type: String + - contextPath: TeamCymruScout.IP.x509.x509.sha256 + description: 'The SHA256 hash of the x509 certificate.' + type: String + - contextPath: TeamCymruScout.IP.x509.x509.first_seen + description: 'The first date the x509 certificate was seen.' + type: Date + - contextPath: TeamCymruScout.IP.x509.x509.last_seen + description: 'The last date the x509 certificate was seen.' + type: Date + - contextPath: TeamCymruScout.IP.x509.x509.port + description: 'The port associated with the x509 certificate.' + type: Number + - contextPath: TeamCymruScout.IP.x509.x509.self_signed + description: 'Indicates whether the x509 certificate is self-signed.' + type: Boolean + - contextPath: TeamCymruScout.IP.x509.x509.country_codes + description: 'The country codes associated with the x509 certificate.' + type: String + - contextPath: TeamCymruScout.IP.x509.x509.as_info.asn + description: 'The autonomous system number associated with the x509 certificate.' + type: Number + - contextPath: TeamCymruScout.IP.x509.x509.as_info.as_name + description: 'The autonomous system name associated with the x509 certificate.' + type: String + - contextPath: TeamCymruScout.IP.x509.x509.tags.id + description: 'The ID of the tag associated with the x509 certificate.' + type: Number + - contextPath: TeamCymruScout.IP.x509.x509.tags.name + description: 'The name of the tag associated with the x509 certificate.' + type: String + - contextPath: TeamCymruScout.IP.x509.x509.tags.children.id + description: 'The ID of the child tag associated with the x509 certificate.' + type: Number + - contextPath: TeamCymruScout.IP.x509.x509.tags.children.name + description: 'The name of the child tag associated with the x509 certificate.' + type: String + - contextPath: TeamCymruScout.IP.x509.x509.tags.children.children + description: 'The children of the child tag associated with the x509 certificate.' + type: Unknown + - contextPath: TeamCymruScout.IP.x509.x509.count + description: 'The count of the x509 certificate.' + type: Number + - contextPath: TeamCymruScout.IP.summary.total + description: 'The total count of the summary.' + type: Number + - contextPath: TeamCymruScout.IP.summary.ip + description: 'The IP address associated with the summary.' + type: String + - contextPath: TeamCymruScout.IP.summary.start_date + description: 'The start date of the summary.' + type: Date + - contextPath: TeamCymruScout.IP.summary.end_date + description: 'The end date of the summary.' + type: Date + - contextPath: TeamCymruScout.IP.summary.geo_ip_cc + description: 'The country code associated with the geographic IP.' + type: String + - contextPath: TeamCymruScout.IP.summary.tags.id + description: 'The ID of the tag associated with the summary.' + type: Number + - contextPath: TeamCymruScout.IP.summary.tags.name + description: 'The name of the tag associated with the summary.' + type: String + - contextPath: TeamCymruScout.IP.summary.tags.children.id + description: 'The ID of the child tag associated with the summary.' + type: Number + - contextPath: TeamCymruScout.IP.summary.tags.children.name + description: 'The name of the child tag associated with the summary.' + type: String + - contextPath: TeamCymruScout.IP.summary.tags.children.children + description: 'The children of the child tag associated with the summary.' + type: Unknown + - contextPath: TeamCymruScout.IP.summary.reverse_hostnames + description: 'The reverse hostnames associated with the summary.' + type: Unknown + - contextPath: TeamCymruScout.IP.summary.bgp_asn + description: 'The autonomous system number associated with the BGP.' + type: Number + - contextPath: TeamCymruScout.IP.summary.bgp_asname + description: 'The autonomous system name associated with the BGP.' + type: String + - contextPath: TeamCymruScout.IP.summary.whois.asn + description: 'The autonomous system number associated with the IP address.' + type: Number + - contextPath: TeamCymruScout.IP.summary.whois.as_name + description: 'The name associated with the autonomous system number.' + type: String + - contextPath: TeamCymruScout.IP.summary.whois.net_name + description: 'The name associated with the network.' + type: String + - contextPath: TeamCymruScout.IP.summary.whois.org_name + description: 'The name associated with the organization.' + type: String + - contextPath: TeamCymruScout.IP.summary.pdns.total + description: 'The total count of the DNS queries associated with the IP address.' + type: Number + - contextPath: TeamCymruScout.IP.summary.pdns.top_pdns.event_count + description: 'The number of events associated with the top DNS query.' + type: Number + - contextPath: TeamCymruScout.IP.summary.pdns.top_pdns.domain + description: 'The domain associated with the top DNS query.' + type: String + - contextPath: TeamCymruScout.IP.summary.pdns.top_pdns.first_seen + description: 'The first date the top DNS query was seen.' + type: Date + - contextPath: TeamCymruScout.IP.summary.pdns.top_pdns.last_seen + description: 'The last date the top DNS query was seen.' + type: Date + - contextPath: TeamCymruScout.IP.summary.pdns.top_pdns.css_color + description: 'The CSS color associated with the top DNS query.' + type: String + - contextPath: TeamCymruScout.IP.summary.open_ports.total + description: 'The total number of the open ports associated with the IP address.' + type: Number + - contextPath: TeamCymruScout.IP.summary.open_ports.unique_ports + description: 'The number of unique ports in the open ports.' + type: Number + - contextPath: TeamCymruScout.IP.summary.open_ports.top_open_ports.event_count + description: 'The number of events associated with the top open port.' + type: Number + - contextPath: TeamCymruScout.IP.summary.open_ports.top_open_ports.port + description: 'The port associated with the top open port.' + type: Number + - contextPath: TeamCymruScout.IP.summary.open_ports.top_open_ports.protocol + description: 'The protocol number associated with the top open port.' + type: Number + - contextPath: TeamCymruScout.IP.summary.open_ports.top_open_ports.protocol_text + description: 'The protocol text associated with the top open port.' + type: String + - contextPath: TeamCymruScout.IP.summary.open_ports.top_open_ports.service + description: 'The service associated with the top open port.' + type: String + - contextPath: TeamCymruScout.IP.summary.open_ports.top_open_ports.inferred_service_name + description: 'The inferred service name associated with the top open port.' + type: Unknown + - contextPath: TeamCymruScout.IP.summary.open_ports.top_open_ports.first_seen + description: 'The first date the top open port was seen.' + type: Date + - contextPath: TeamCymruScout.IP.summary.open_ports.top_open_ports.last_seen + description: 'The last date the top open port was seen.' + type: Date + - contextPath: TeamCymruScout.IP.summary.open_ports.top_open_ports.css_color + description: 'The CSS color associated with the top open port.' + type: String + - contextPath: TeamCymruScout.IP.summary.certs.top_certs.issuer + description: 'The issuer of the certificate.' + type: String + - contextPath: TeamCymruScout.IP.summary.certs.top_certs.issuer_common_name + description: 'The common name of the issuer of the certificate.' + type: String + - contextPath: TeamCymruScout.IP.summary.certs.top_certs.common_name + description: 'The common name of the certificate.' + type: String + - contextPath: TeamCymruScout.IP.summary.certs.top_certs.subject + description: 'The subject of the certificate.' + type: String + - contextPath: TeamCymruScout.IP.summary.certs.top_certs.port + description: 'The port associated with the certificate.' + type: Number + - contextPath: TeamCymruScout.IP.summary.certs.top_certs.first_seen + description: 'The first date the certificate was seen.' + type: Date + - contextPath: TeamCymruScout.IP.summary.certs.top_certs.last_seen + description: 'The last date the certificate was seen.' + type: Date + - contextPath: TeamCymruScout.IP.summary.certs.top_certs.self_signed + description: 'Indicates whether the certificate is self-signed.' + type: Boolean + - contextPath: TeamCymruScout.IP.summary.certs.top_certs.not_before + description: 'The date before which the certificate is not valid.' + type: Date + - contextPath: TeamCymruScout.IP.summary.certs.top_certs.not_after + description: 'The date after which the certificate is not valid.' + type: Date + - contextPath: TeamCymruScout.IP.summary.certs.top_certs.valid_days + description: 'The number of valid days for the certificate.' + type: Number + - contextPath: TeamCymruScout.IP.summary.certs.top_certs.md5 + description: 'The MD5 hash of the certificate.' + type: String + - contextPath: TeamCymruScout.IP.summary.certs.top_certs.sha1 + description: 'The SHA1 hash of the certificate.' + type: String + - contextPath: TeamCymruScout.IP.summary.certs.top_certs.sha256 + description: 'The SHA256 hash of the certificate.' + type: String + - contextPath: TeamCymruScout.IP.summary.certs.top_certs.css_color + description: 'The CSS color associated with the certificate.' + type: String + - contextPath: TeamCymruScout.IP.summary.tag_timeline.data.tag.id + description: 'The ID of the tag.' + type: Number + - contextPath: TeamCymruScout.IP.summary.tag_timeline.data.tag.name + description: 'The name of the tag.' + type: String + - contextPath: TeamCymruScout.IP.summary.tag_timeline.data.tag.description + description: 'The description of the tag.' + type: String + - contextPath: TeamCymruScout.IP.summary.tag_timeline.data.tag.parent_ids + description: 'The parent IDs of the tag.' + type: Number + - contextPath: TeamCymruScout.IP.summary.tag_timeline.data.tag.css_color + description: 'The CSS color associated with the tag.' + type: String + - contextPath: TeamCymruScout.IP.summary.tag_timeline.data.tag.parents + description: 'The parents of the tag.' + type: Unknown + - contextPath: TeamCymruScout.IP.summary.tag_timeline.data.first_seen + description: 'The first date the tag was seen.' + type: Date + - contextPath: TeamCymruScout.IP.summary.tag_timeline.data.last_seen + description: 'The last date the tag was seen.' + type: Date + - contextPath: TeamCymruScout.IP.summary.tag_timeline.data.tag.parents.id + description: 'The ID of the parent tag.' + type: Number + - contextPath: TeamCymruScout.IP.summary.tag_timeline.data.tag.parents.name + description: 'The name of the parent tag.' + type: String + - contextPath: TeamCymruScout.IP.summary.tag_timeline.data.tag.parents.description + description: 'The description of the parent tag.' + type: String + - contextPath: TeamCymruScout.IP.summary.tag_timeline.data.tag.parents.parent_ids + description: 'The parent IDs of the parent tag.' + type: Unknown + - contextPath: TeamCymruScout.IP.summary.tag_timeline.data.tag.parents.css_color + description: 'The CSS color associated with the parent tag.' + type: String + - contextPath: TeamCymruScout.IP.summary.tag_timeline.data.tag.parents.parents + description: 'The parents of the parent tag.' + type: Unknown + - contextPath: TeamCymruScout.IP.summary.insights.overall_rating + description: 'The overall rating of the insights.' + type: String + - contextPath: TeamCymruScout.IP.summary.insights.total + description: 'The total count of the insights.' + type: Number + - contextPath: TeamCymruScout.IP.summary.insights.insights.rating + description: 'The rating of the insight.' + type: String + - contextPath: TeamCymruScout.IP.summary.insights.insights.message + description: 'The message of the insight.' + type: String + - contextPath: TeamCymruScout.IP.summary.fingerprints.top_fingerprints.type + description: 'The type of the fingerprint.' + type: String + - contextPath: TeamCymruScout.IP.summary.fingerprints.top_fingerprints.signature + description: 'The signature of the fingerprint.' + type: String + - contextPath: TeamCymruScout.IP.summary.fingerprints.top_fingerprints.port + description: 'The port associated with the fingerprint.' + type: Number + - contextPath: TeamCymruScout.IP.summary.fingerprints.top_fingerprints.first_seen + description: 'The first date the fingerprint was seen.' + type: Date + - contextPath: TeamCymruScout.IP.summary.fingerprints.top_fingerprints.last_seen + description: 'The last date the fingerprint was seen.' + type: Date + - contextPath: TeamCymruScout.IP.summary.fingerprints.top_fingerprints.count + description: 'The count of the fingerprint.' + type: Number + - name: scout-indicator-search + description: Return the summary information available for the given domain or IP address using Scout query language. + arguments: + - name: query + description: "A simple or advanced Scout query which may contain the domain or IP address.\n\nFor example: comms.ip=\"0.0.0.1/24\"." + required: true + - name: start_date + description: "The start date to filter indicators.\n\nSupported formats: 2 days, 2 weeks, 2 months, yyyy-mm-dd.\n\nFor example: 01 June 2024, 2024-06-17." + defaultValue: '30 days' + - name: end_date + description: "The end date to filter indicators.\n\nSupported formats: 2 days, 2 weeks, 2 months, yyyy-mm-dd.\n\nFor example: 01 June 2024, 2024-06-17." + defaultValue: 'now' + - name: days + description: "Relative offset in days from current time. It cannot exceed the maximum range of 30 days.\n\nNote: This will take priority over start_date and end_date if all three are passed." + - name: size + description: "The maximum number of indicators to fetch.\n\nNote: The maximum allowed size is 5000." + defaultValue: '20' + outputs: + - contextPath: TeamCymruScout.IP.ip + description: 'The IP address.' + type: String + - contextPath: TeamCymruScout.IP.country_codes + description: 'The country code(s).' + type: String + - contextPath: TeamCymruScout.IP.as_info.asn + description: 'The autonomous system number.' + type: Number + - contextPath: TeamCymruScout.IP.as_info.as_name + description: 'The autonomous system name.' + type: String + - contextPath: TeamCymruScout.IP.tags.id + description: 'The ID of the tag.' + type: Number + - contextPath: TeamCymruScout.IP.tags.name + description: 'The name of the tag.' + type: String + - contextPath: TeamCymruScout.IP.tags.children.id + description: 'The ID of the child tag.' + type: Number + - contextPath: TeamCymruScout.IP.tags.children.name + description: 'The name of the child tag.' + type: String + - contextPath: TeamCymruScout.IP.tags.children.children + description: 'The children of the child tag.' + type: Unknown + - contextPath: TeamCymruScout.IP.event_count + description: 'The number of events related to the IP address.' + type: Number + - contextPath: TeamCymruScout.IP.summary.last_seen + description: 'The last time the IP was seen.' + type: Date + - contextPath: TeamCymruScout.IP.summary.whois.asn + description: 'The autonomous system number associated with the IP.' + type: Number + - contextPath: TeamCymruScout.IP.summary.whois.as_name + description: 'The name of the autonomous system associated with the IP.' + type: String + - contextPath: TeamCymruScout.IP.summary.whois.net_name + description: 'The network name associated with the IP.' + type: String + - contextPath: TeamCymruScout.IP.summary.whois.org_name + description: 'The organization name associated with the IP.' + type: String + - contextPath: TeamCymruScout.IP.summary.open_ports.ip + description: 'The IP address associated with the open port.' + type: String + - contextPath: TeamCymruScout.IP.summary.open_ports.port + description: 'The port number associated with the open port.' + type: Number + - contextPath: TeamCymruScout.IP.summary.open_ports.protocol + description: 'The protocol number associated with the open port.' + type: Number + - contextPath: TeamCymruScout.IP.summary.open_ports.protocol_text + description: 'The protocol name associated with the open port.' + type: String + - contextPath: TeamCymruScout.IP.summary.open_ports.service + description: 'The service name associated with the open port.' + type: String + - contextPath: TeamCymruScout.IP.summary.open_ports.event_count + description: 'The number of events related to the open port.' + type: Number + - contextPath: TeamCymruScout.IP.summary.pdns.ip + description: 'The IP address associated with the domain.' + type: String + - contextPath: TeamCymruScout.IP.summary.pdns.domain + description: 'The domain associated with the IP.' + type: String + - contextPath: TeamCymruScout.IP.summary.pdns.event_count + description: 'The number of events related to the domain.' + type: Number + - contextPath: TeamCymruScout.IP.summary.top_peers.ip + description: 'The IP address of the top peer.' + type: String + - contextPath: TeamCymruScout.IP.summary.top_peers.event_count + description: 'The number of events related to the top peer.' + type: Number + - contextPath: TeamCymruScout.IP.summary.comms_total + description: 'The total number of communications related to the IP address.' + type: Number + - contextPath: TeamCymruScout.IP.summary.service_counts.proto + description: 'The protocol number associated with the service count.' + type: Number + - contextPath: TeamCymruScout.IP.summary.service_counts.proto_text + description: 'The protocol name associated with the service count.' + type: String + - contextPath: TeamCymruScout.IP.summary.service_counts.port + description: 'The port number associated with the service count.' + type: Number + - contextPath: TeamCymruScout.IP.summary.service_counts.event_count + description: 'The number of events related to the service count.' + type: Number + - contextPath: TeamCymruScout.IP.summary.service_counts.service.service_name + description: 'The service name associated with the service count.' + type: String + - contextPath: TeamCymruScout.IP.summary.service_counts.service.port + description: 'The port number associated with the service count.' + type: Number + - contextPath: TeamCymruScout.IP.summary.service_counts.service.proto_number + description: 'The protocol number associated with the service count.' + type: Number + - contextPath: TeamCymruScout.IP.summary.service_counts.service.description + description: 'The description of the service associated with the service count.' + type: String + - contextPath: TeamCymruScout.IP.summary.fingerprints.ip + description: 'The IP address associated with the fingerprint.' + type: String + - contextPath: TeamCymruScout.IP.summary.fingerprints.type + description: 'The type of the fingerprint.' + type: String + - contextPath: TeamCymruScout.IP.summary.fingerprints.signature + description: 'The signature of the fingerprint.' + type: String + - contextPath: TeamCymruScout.IP.summary.fingerprints.event_count + description: 'The number of events related to the fingerprint.' + type: Number + - contextPath: TeamCymruScout.IP.summary.certs.ip + description: 'The IP address associated with the certificate.' + type: String + - contextPath: TeamCymruScout.IP.summary.certs.issuer + description: 'The issuer of the certificate.' + type: String + - contextPath: TeamCymruScout.IP.summary.certs.issuer_common_name + description: 'The common name of the issuer of the certificate.' + type: String + - contextPath: TeamCymruScout.IP.summary.certs.common_name + description: 'The common name of the certificate.' + type: String + - contextPath: TeamCymruScout.IP.summary.certs.port + description: 'The port number associated with the certificate.' + type: Number + - contextPath: TeamCymruScout.IP.summary.certs.event_count + description: 'The number of events related to the certificate.' + type: Number + - type: String + contextPath: TeamCymruScout.QueryUsage.command_name + description: 'The name of the Cortex XSOAR command that triggered the Foundation API.' + - type: String + contextPath: TeamCymruScout.QueryUsage.request_id + description: 'The unique request ID of the Foundation API response.' + - type: Number + contextPath: TeamCymruScout.QueryUsage.total + description: 'The total number of records available for provided filters.' + - type: String + contextPath: TeamCymruScout.QueryUsage.query + description: 'The query for which the search API was triggered.' + - type: Number + contextPath: TeamCymruScout.QueryUsage.size + description: 'The number of records requested using parameters.' + - type: String + contextPath: TeamCymruScout.QueryUsage.start_date + description: 'The start date from which the indicators are returned.' + - type: String + contextPath: TeamCymruScout.QueryUsage.end_date + description: 'The end date from which the indicators are returned.' + - type: Number + contextPath: TeamCymruScout.QueryUsage.used_queries + description: 'The number of queries used.' + - type: Number + contextPath: TeamCymruScout.QueryUsage.remaining_queries + description: 'The number of remaining queries.' + - type: Number + contextPath: TeamCymruScout.QueryUsage.query_limit + description: 'The total number of queries allowed.' + - type: Number + contextPath: TeamCymruScout.QueryUsage.foundation_api_usage.used_queries + description: 'The number of queries used for the Foundation API.' + - type: Number + contextPath: TeamCymruScout.QueryUsage.foundation_api_usage.remaining_queries + description: 'The number of remaining queries for the Foundation API.' + - type: Number + contextPath: TeamCymruScout.QueryUsage.foundation_api_usage.query_limit + description: 'The total number of queries allowed for the Foundation API.' + - contextPath: IP.Address + description: IP address. + type: String + - contextPath: IP.Relationships.EntityA + description: The source of the relationship. + type: String + - contextPath: IP.Relationships.EntityB + description: The destination of the relationship. + type: String + - contextPath: IP.Relationships.Relationship + description: The name of the relationship. + type: String + - contextPath: IP.Relationships.EntityAType + description: The type of the source of the relationship. + type: String + - contextPath: IP.Relationships.EntityBType + description: The type of the destination of the relationship. + type: String + - contextPath: IP.ASN + description: 'The autonomous system name for the IP address, for example: "AS8948".' + type: String + - contextPath: IP.Hostname + description: The hostname that is mapped to this IP address. + type: String + - contextPath: IP.Geo.Location + description: 'The geolocation where the IP address is located, in the format: latitude:longitude.' + type: String + - contextPath: IP.Geo.Country + description: The country in which the IP address is located. + type: String + - contextPath: IP.Geo.Description + description: Additional information about the location. + type: String + - contextPath: IP.DetectionEngines + description: The total number of engines that checked the indicator. + type: Number + - contextPath: IP.PositiveDetections + description: The number of engines that positively detected the indicator as malicious. + type: Number + - contextPath: IP.Malicious.Vendor + description: The vendor reporting the IP address as malicious. + type: String + - contextPath: IP.Malicious.Description + description: A description explaining why the IP address was reported as malicious. + type: String + - contextPath: IP.Tags + description: (List) Tags of the IP address. + type: Unknown + - contextPath: IP.FeedRelatedIndicators.value + description: Indicators that are associated with the IP address. + type: String + - contextPath: IP.FeedRelatedIndicators.type + description: The type of the indicators that are associated with the IP address. + type: String + - contextPath: IP.FeedRelatedIndicators.description + description: The description of the indicators that are associated with the IP address. + type: String + - contextPath: IP.MalwareFamily + description: The malware family associated with the IP address. + type: String + - contextPath: IP.Organization.Name + description: The organization of the IP address. + type: String + - contextPath: IP.Organization.Type + description: The organization type of the IP address. + type: String + - contextPath: IP.ASOwner + description: The autonomous system owner of the IP address. + type: String + - contextPath: IP.Region + description: The region in which the IP address is located. + type: String + - contextPath: IP.Port + description: Ports that are associated with the IP address. + type: String + - contextPath: IP.Internal + description: Whether the IP address is internal or external. + type: Boolean + - contextPath: IP.UpdatedDate + description: The date that the IP address was last updated. + type: Date + - contextPath: IP.Registrar.Abuse.Name + description: The name of the contact for reporting abuse. + type: String + - contextPath: IP.Registrar.Abuse.Address + description: The address of the contact for reporting abuse. + type: String + - contextPath: IP.Registrar.Abuse.Country + description: The country of the contact for reporting abuse. + type: String + - contextPath: IP.Registrar.Abuse.Network + description: The network of the contact for reporting abuse. + type: String + - contextPath: IP.Registrar.Abuse.Phone + description: The phone number of the contact for reporting abuse. + type: String + - contextPath: IP.Registrar.Abuse.Email + description: The email address of the contact for reporting abuse. + type: String + - contextPath: IP.Campaign + description: The campaign associated with the IP address. + type: String + - contextPath: IP.TrafficLightProtocol + description: The Traffic Light Protocol (TLP) color that is suitable for the IP address. + type: String + - contextPath: IP.CommunityNotes.note + description: Notes on the IP address that were given by the community. + type: String + - contextPath: IP.CommunityNotes.timestamp + description: The time in which the note was published. + type: Date + - contextPath: IP.Publications.source + description: The source in which the article was published. + type: String + - contextPath: IP.Publications.title + description: The name of the article. + type: String + - contextPath: IP.Publications.link + description: A link to the original article. + type: String + - contextPath: IP.Publications.timestamp + description: The time in which the article was published. + type: Date + - contextPath: IP.ThreatTypes.threatcategory + description: The threat category associated to this indicator by the source vendor. For example, Phishing, Control, TOR, etc. + type: String + - contextPath: IP.ThreatTypes.threatcategoryconfidence + description: The confidence level provided by the vendor for the threat type category For example a confidence of 90 for threat type category 'malware' means that the vendor rates that this is 90% confidence of being a malware. + type: String + - contextPath: DBotScore.Indicator + description: The indicator that was tested. + type: String + - contextPath: DBotScore.Reliability + description: Reliability of the source providing the intelligence data. + type: String + - contextPath: DBotScore.Type + description: The indicator type. + type: String + - contextPath: DBotScore.Vendor + description: The vendor used to calculate the score. + type: String + - contextPath: DBotScore.Score + description: "The reputation score (0: Unknown, 1: Good, 2: Suspicious, 3: Bad)." + type: Number + - name: scout-ip-list + description: Returns the summary information available for the given list of IP addresses. + arguments: + - name: ip_addresses + description: 'A comma-separated list of IP addresses to retrieve available IP details. Note: Maximum of 10 IP addresses are allowed.' + required: true + isArray: true + outputs: + - contextPath: TeamCymruScout.IP.ip + description: 'The IP address.' + type: String + - contextPath: TeamCymruScout.IP.country_code + description: 'The country code.' + type: String + - contextPath: TeamCymruScout.IP.as_info.asn + description: 'The autonomous system number.' + type: Number + - contextPath: TeamCymruScout.IP.as_info.as_name + description: 'The autonomous system name.' + type: String + - contextPath: TeamCymruScout.IP.insights.overall_rating + description: 'The overall rating for the IP address.' + type: String + - contextPath: TeamCymruScout.IP.insights.insights.rating + description: 'The individual insight rating for the IP address.' + type: String + - contextPath: TeamCymruScout.IP.insights.insights.message + description: 'The individual insight message for the IP address.' + type: String + - contextPath: TeamCymruScout.IP.tags.id + description: 'The ID of the tag.' + type: Number + - contextPath: TeamCymruScout.IP.tags.name + description: 'The name of the tag.' + type: String + - contextPath: TeamCymruScout.IP.tags.children.id + description: 'The ID of the child tag.' + type: Number + - contextPath: TeamCymruScout.IP.tags.children.name + description: 'The name of the child tag.' + type: String + - contextPath: TeamCymruScout.IP.tags.children.children + description: 'The children of the child tag.' + type: Unknown + - contextPath: TeamCymruScout.QueryUsage.command_name + description: 'The name of the Cortex XSOAR command that triggered the Foundation API.' + type: String + - contextPath: TeamCymruScout.QueryUsage.request_id + description: 'The unique request ID of the Foundation API response.' + type: String + - contextPath: TeamCymruScout.QueryUsage.ips + description: 'The list of IP addresses for which the Foundation API was triggered.' + type: Unknown + - contextPath: TeamCymruScout.QueryUsage.used_queries + description: 'The number of queries used.' + type: Number + - contextPath: TeamCymruScout.QueryUsage.remaining_queries + description: 'The number of remaining queries.' + type: Number + - contextPath: TeamCymruScout.QueryUsage.query_limit + description: 'The total number of queries allowed.' + type: Number + - contextPath: TeamCymruScout.QueryUsage.foundation_api_usage.used_queries + description: 'The number of queries used for the Foundation API.' + type: Number + - contextPath: TeamCymruScout.QueryUsage.foundation_api_usage.remaining_queries + description: 'The number of remaining queries for the Foundation API.' + type: Number + - contextPath: TeamCymruScout.QueryUsage.foundation_api_usage.query_limit + description: 'The total number of queries allowed for the Foundation API.' + type: Number + - contextPath: IP.Address + description: IP address. + type: String + - contextPath: IP.Relationships.EntityA + description: The source of the relationship. + type: String + - contextPath: IP.Relationships.EntityB + description: The destination of the relationship. + type: String + - contextPath: IP.Relationships.Relationship + description: The name of the relationship. + type: String + - contextPath: IP.Relationships.EntityAType + description: The type of the source of the relationship. + type: String + - contextPath: IP.Relationships.EntityBType + description: The type of the destination of the relationship. + type: String + - contextPath: IP.ASN + description: 'The autonomous system name for the IP address, for example: "AS8948".' + type: String + - contextPath: IP.Hostname + description: The hostname that is mapped to this IP address. + type: String + - contextPath: IP.Geo.Location + description: 'The geolocation where the IP address is located, in the format: latitude:longitude.' + type: String + - contextPath: IP.Geo.Country + description: The country in which the IP address is located. + type: String + - contextPath: IP.Geo.Description + description: Additional information about the location. + type: String + - contextPath: IP.DetectionEngines + description: The total number of engines that checked the indicator. + type: Number + - contextPath: IP.PositiveDetections + description: The number of engines that positively detected the indicator as malicious. + type: Number + - contextPath: IP.Malicious.Vendor + description: The vendor reporting the IP address as malicious. + type: String + - contextPath: IP.Malicious.Description + description: A description explaining why the IP address was reported as malicious. + type: String + - contextPath: IP.Tags + description: (List) Tags of the IP address. + type: Unknown + - contextPath: IP.FeedRelatedIndicators.value + description: Indicators that are associated with the IP address. + type: String + - contextPath: IP.FeedRelatedIndicators.type + description: The type of the indicators that are associated with the IP address. + type: String + - contextPath: IP.FeedRelatedIndicators.description + description: The description of the indicators that are associated with the IP address. + type: String + - contextPath: IP.MalwareFamily + description: The malware family associated with the IP address. + type: String + - contextPath: IP.Organization.Name + description: The organization of the IP address. + type: String + - contextPath: IP.Organization.Type + description: The organization type of the IP address. + type: String + - contextPath: IP.ASOwner + description: The autonomous system owner of the IP address. + type: String + - contextPath: IP.Region + description: The region in which the IP address is located. + type: String + - contextPath: IP.Port + description: Ports that are associated with the IP address. + type: String + - contextPath: IP.Internal + description: Whether the IP address is internal or external. + type: Boolean + - contextPath: IP.UpdatedDate + description: The date that the IP address was last updated. + type: Date + - contextPath: IP.Registrar.Abuse.Name + description: The name of the contact for reporting abuse. + type: String + - contextPath: IP.Registrar.Abuse.Address + description: The address of the contact for reporting abuse. + type: String + - contextPath: IP.Registrar.Abuse.Country + description: The country of the contact for reporting abuse. + type: String + - contextPath: IP.Registrar.Abuse.Network + description: The network of the contact for reporting abuse. + type: String + - contextPath: IP.Registrar.Abuse.Phone + description: The phone number of the contact for reporting abuse. + type: String + - contextPath: IP.Registrar.Abuse.Email + description: The email address of the contact for reporting abuse. + type: String + - contextPath: IP.Campaign + description: The campaign associated with the IP address. + type: String + - contextPath: IP.TrafficLightProtocol + description: The Traffic Light Protocol (TLP) color that is suitable for the IP address. + type: String + - contextPath: IP.CommunityNotes.note + description: Notes on the IP address that were given by the community. + type: String + - contextPath: IP.CommunityNotes.timestamp + description: The time in which the note was published. + type: Date + - contextPath: IP.Publications.source + description: The source in which the article was published. + type: String + - contextPath: IP.Publications.title + description: The name of the article. + type: String + - contextPath: IP.Publications.link + description: A link to the original article. + type: String + - contextPath: IP.Publications.timestamp + description: The time in which the article was published. + type: Date + - contextPath: IP.ThreatTypes.threatcategory + description: The threat category associated to this indicator by the source vendor. For example, Phishing, Control, TOR, etc. + type: String + - contextPath: IP.ThreatTypes.threatcategoryconfidence + description: The confidence level provided by the vendor for the threat type category For example a confidence of 90 for threat type category 'malware' means that the vendor rates that this is 90% confidence of being a malware. + type: String + - contextPath: DBotScore.Indicator + description: 'The indicator that was tested.' + type: String + - contextPath: DBotScore.Type + description: 'The indicator type.' + type: String + - contextPath: DBotScore.Vendor + description: 'The vendor used to calculate the score.' + type: String + - contextPath: DBotScore.Score + description: 'The reputation score (0: Unknown, 1: Good, 2: Suspicious, 3: Bad).' + type: Number + - contextPath: DBotScore.Reliability + description: Reliability of the source providing the intelligence data. + type: String +tests: +- No tests +fromversion: 6.10.0 diff --git a/Packs/TeamCymru/Integrations/TeamCymruScout/TeamCymruScout_description.md b/Packs/TeamCymru/Integrations/TeamCymruScout/TeamCymruScout_description.md new file mode 100644 index 000000000000..d55c09728e72 --- /dev/null +++ b/Packs/TeamCymru/Integrations/TeamCymruScout/TeamCymruScout_description.md @@ -0,0 +1,37 @@ +## Team Cymru Scout Help + +Use the Team Cymru Scout integration to get enriched data for IP addresses. +This guide assists you in setting up the Team Cymru Scout integration on Cortex XSOAR to get enriched data for IP addresses. + +## Prerequisites + +- Access to the [Team Cymru Scout platform](https://scout.cymru.com/scout). +- An API Key or Basic Auth credentials for authentication. + +### Generate API Keys + +If you prefer to use an API key for authentication, you can generate one as follows: + +1. Go to the [API Keys page](https://scout.cymru.com/api_keys). +2. Click **Create**. +3. Provide the description for the key, if needed. +4. Click **Create Key** to generate the API key. + +Note: + +- The number of API keys allowed for each organization is equal to the number of user seats. Therefore, an individual user may have multiple keys, but all the users in your organization may have a maximum of 5 keys. The [API Keys page](https://scout.cymru.com/api_keys) shows the total number of keys used by your organization. +- If the "Create" button is disabled, it indicates that you have reached the maximum number of keys allowed for your organization. To generate a new key, you need to: + - Click **Revoke** next to an old key. + - Click **Create Key** to start generating a new key. + +### Configuration Parameters + +Before you start running the commands, you need to configure the integration parameters: + +1. Authentication Type: Select the authentication type used for secure communication with the Team Cymru Scout platform. +2. API Key: The API key used for secure communication with the Team Cymru Scout platform. Required if "API Key" as Authentication Type is selected. +3. Username and Password: The username and password used for secure communication with the Team Cymru Scout platform. Required if "Basic Auth" as Authentication Type is selected. +4. Source Reliability: Select the reliability of the source providing the intelligence data. +5. Create relationships: Select whether to create relationships between indicators as part of enrichment. + +After configuring the integration parameters, you can click **Test** to ensure that the connection to the Team Cymru Scout platform is successful. diff --git a/Packs/TeamCymru/Integrations/TeamCymruScout/TeamCymruScout_image.png b/Packs/TeamCymru/Integrations/TeamCymruScout/TeamCymruScout_image.png new file mode 100644 index 0000000000000000000000000000000000000000..307f0ec6d7e811ade2601b8a59ecb2f55fec5ae9 GIT binary patch literal 4716 zcmZ`-Wl$7=)?Hv}knWalq`PZr0a@BbSQ-|kmRw2@MLMLVRa&}PKoJl@O4=o5X{lY1 z`1pRlH}mGsJ!j6jbN=0#J987wO!UY}m`MNt069os+x(v4_bo|8aF01v9P{@Cbki`_ z000_ONUxpn?=`2hzPT{~5XuJtM8yFBSNB%b4ge4+0RZem006~z004tuLFZ%T`vJi- zLp^Q4-T&A7o~n#{hcEzStV6g>OijqjzJ9x~1^`g`fwVO&;fn|P5q=KCA*+aq!wwAf zQy`Wr6}wKTpV$H&djb8Dz64UvHOd0zE7HjLX2=%JJ)Z&PEhbh;dE~Vl@3kgoECyDZ zEDvoAz1aIP^L#}ytuS#~@j||qO(}ir8#Ocypr#Gr0Z?>da1yJ7j(W2LJr30z-ZS?(Y zXtl6L+jBN`b1`=Uua<9CV~uVc>fxIet;1sv#9yJ%Y25Rw-t%-7!||1Tt;)qLy@gqm zrDH9(M8P@Ou7_7+#3}TXq?ArF8Dg{-<*3G}+kllKM#u5FqIRE`T_y!#AAL?gs|Qt! ze@|h@pQkHNu)P>=>pDC;mREp+>%Ax#BfEz%ITESPINmd+>b|gmQp$oO^0l(*m0Cn! zaP1?QBWiySLh74{%3XVID=5Rv)h*R_*J=#rTWOOI4XA`7Zdz;p%vd%quHdVIQEh)3 zrlW3_>B9X%Vo(%m$7NDswmzHZQ<3Fn-iZ`et~RY;BDJEWzC5j`KwSCKDw@dO;hrkp z;CXN+b5m@z`WGZU|&u!Lj2Ifn1gz9V;Lk>1&6pVjms+P+Z z-@fFgw~?wq&{Y_gmPGa)pS_19*C&56#J61_)uI*8TL)F<4!^y&qFUa zyhEInQ5W|bL%-Zb^+c;amI)dk zSaSmwFXei!kaUX^tcdURsdjYVo;oY-3ckLzogt)!KgrA{J$yWXJC>$~|I{MKDJ0h}EOI75K zw2QLLP)!|Lc^LxlnF-TG>62~Fo0in#PK#1`zaJVTCbx3&K0Ovnzv7TVlWW2}7Sy_Q zug1w*m><-nMS^!CVh|DStEU0hPqDkxm#UEGhTQSCf*kr1j=nb+-6d^M4#(kOpgVyz zvIfUyAmF86{@SX{KR>pJVZY#7xdlVwfjkAv{-5sr`GdJ_ra#BUPsLGoXC9tdRNz9a!b2Q8p0fO%W(OM-zFIr$Fl@)OMuFisXdL5POn@iJWIIfk zo>ACZeJ59;1A8wFl=Pr<_nv?~Ip`TCJ>UH zX0xM>9o0NUkCOt0IRng6L#F+K6h8{mhGOyAsf~cxj{t>3GTVNTVQ`4Oy(J)m}9pa7zMWes~LvS_bI%ia(V zx7=Ul@!09A2uP@xvcDlv?h`LOp|#Jgje;HPe7x1!tn~ga^Lx%zWnzQoh{e{Z)YoE~ z?&q*+CnR?)iI|-!n!MMg$I3mfE+}KpL0~Y$MLk_q* z^?0$$Ax0(8qo#7asdLv$+xbWtlSEP#yEFi}-yTYs^x6}Eq?P{`ny4^iKV;-aDb#iD1EX6L(m^pq7@J$rd1(jeyJvy_@7 z&ey&CB9upbv}yd=p8R29=yW_=4!Kg&h40-D(PzV-r|TBdxE++tkzX>IW1M4L*=~&} zrJm~{+L`@?wcb!$;KWNdQYb%^7jOUUG})Sv@HWd}wt@gC%v3-j@kiU^8Xk2Hs83pN zIp9S9JX%mI0O$xj%==~rGj`&Mjit(tbN%AqGc;*IQ(ty+az5}qyo>BNHF942-vZH} zg*oKttY!Xaep9ue%9KIN$>hu0m@i-q;22chJ?9sQ=jkWr6pc zdB_8JH`}Inqs9Q?q4!xPp&MV-*FPr8ISNSo>Q_`fe5Je~sYs;73}Za$X(%|FGSK5` zOxjdUb3qX(mE|iYe$q5d^^@X^{FC_`O~l9e(3k+~kL{1WG?RW5*v}(;*Rhi`L!e#g zL}{VFI`#^-=3?h9-sqA4#*Z}c+ujyCw_if_^OIgz#;J8U z8n+JO5X7_t3z8c|7=@hrWJTrijaWSUy~tZ$@r4wTlHj{~!o$5iH@{&DSrkrmd4rFt zXX|;eq3%sk__N&YbveWxMcr5O_)8+NEzWu=u-Hn6yV0M4!?aMFli2Lw3G$RCtLzpc7+wla zF(b+I#`A9eFTXglA*F^_0o7+C-6uO`ywbRy#22`Gy!%wF%e0I_14i099;?=nEfYI2 zr>E6=(5!J~PHZNsjmXKbQQ+0i0wn6?@;=O6_jpgnx@XZmP}o`S_>JiG>sv7;`7x0(w+ZA=>N0}$P88YH{ z@~YZ7M1?%CTyN^ntlqgPQr9e9DEf|57Ua#o*yQGep2BT0L;NL*+*$@s*QOVoCFY&2 zoVth-qBv&6BtUMjtP-{_X`6+`gyS0HpD%-~wMzryA2wD&{q#5i5s;4pRGl8lT$YdOsxA2MI*8;{CO6}n6hVEC?`1g{^b-twPt^WLI4#|i#k{QQ_G zUgSx4?YFm`j306HdClr%FIcFn?Tuep)X$54gj>lsL_@r)FsGJY&91l<0BN7-ZmUkr zAbYYjE|0~q+m28E0`T;PZO<$(Mfce}D&fzV-r7rTW>eT9dtwJBdDmgG%r)p4!@tBG zen5y}UoAc^#uHXZvb_!%P_sbc^?zEM08hQepcz<84itjZH>JVrh;*d*%ug4-ib=lC zs6*f|W&NZ5@8!Q4u6KAV^nN6>pI84Vj$D6PVZWj^xU7QvQq-e_d1a-sh@9CU$p zHr;C*2~=&E<`O=b#LC*cwePO(ePNHs&?B-aUF ziz%Si%elx~fBs_35|zMDPlDlS)xl@|`kp%SR3-TG!#GU^8Ukz0CEpL+NLUhwrLel% zInj=TBLY{{HLk}kQN2t<8}rpvDh^v1F??yL?FpE$rj2lqV+#u*A196sdwG&#MPAYa z)Pui%9aTa0c-1&0~cUzd1-b3ie__O1D$RA+jZyYBj7o@J|fhr2$ZtBJqsg#2THIkaJrshN9S&cc?F z;M*cK?GJCHAtF@tu~VU@zY4OgV0+bq0r<@Veu;#*&9-7W+Vf21p$|w^QfoH~ zWm|j9NFPN9x9I0i?&{AqNjua~8kN<=vFbFtG^r|2cXZAD*B9enUL)e}NJ(iOd6E>X z8SdXPya77a0WMAfP(|k#(0c+%N=QnIN+^gvlDCwQQ dict: + '''Load a json to python dict.''' + with open(path, mode='r', encoding='utf-8') as f: + return json.loads(f.read()) + + +def util_load_text_data(path: str) -> str: + '''Load a text file.''' + with open(path, mode='r', encoding='utf-8') as f: + return f.read() + + +@pytest.fixture +def mock_client(): + '''Mock a client object with required data to mock.''' + client = Client(BASE_URL, False, False, {}, None) + return client + + +@pytest.mark.parametrize('params', [BASIC_PARAMS, BASIC_AUTH_PARAMS]) +@patch('TeamCymruScout.return_results') +def test_test_module_using_main_function(mock_return, requests_mock, mocker, params): + ''' + Test case scenario for successful execution of test_module through main function. + + Given: + - mocked client. + When: + - Calling `test_module` function. + Then: + - Returns an ok message. + ''' + response = util_load_json('test_data/scout_api_usage_response.json') + + requests_mock.get(f'{BASE_URL}{ENDPOINTS["QUERY_USAGE"]}', json=response, status_code=200) + + mocker.patch.object(demisto, 'params', return_value=params) + mocker.patch.object(demisto, 'command', return_value='test-module') + + main() + assert 'ok' == mock_return.call_args.args[0] + + +@pytest.mark.parametrize('params, error_message', [ + ({'authentication_type': BASIC_AUTH}, ERROR_MESSAGES['NO_PARAM_PROVIDED'].format('Username')), + ({'authentication_type': BASIC_AUTH, 'basic_auth': {'identifier': 'admin'}}, + ERROR_MESSAGES['NO_PARAM_PROVIDED'].format('Password')), + ({'authentication_type': BASIC_AUTH, 'basic_auth': {'password': 'admin'}}, + ERROR_MESSAGES['NO_PARAM_PROVIDED'].format('Username')), + ({'authentication_type': API_KEY}, ERROR_MESSAGES['NO_PARAM_PROVIDED'].format(API_KEY)), +]) +def test_test_module_for_invalid_auth_using_main_function(requests_mock, mocker, params, capfd, error_message): + ''' + Test case scenario for the execution of test_module with invalid authentication parameters. + + Given: + - mocked client. + When: + - Calling `test_module` function. + Then: + - Returns exception. + ''' + response = util_load_json('test_data/scout_api_usage_response.json') + + requests_mock.get(f'{BASE_URL}{ENDPOINTS["QUERY_USAGE"]}', json=response, status_code=200) + + mocker.patch.object(demisto, 'params', return_value=params) + mocker.patch.object(demisto, 'command', return_value='test-module') + return_error = mocker.patch.object(TeamCymruScout, "return_error") + + capfd.close() + main() + + assert error_message in return_error.call_args[0][0] + + +@patch('TeamCymruScout.return_results') +def test_scout_api_usage_command_using_main_function(mock_return, requests_mock, mocker): + ''' + Test case scenario for successful execution of scout_api_usage_command through main function. + + Given: + - mocked client. + When: + - Calling `scout_api_usage_command` function. + Then: + - Returns CommandResult. + ''' + response = util_load_json('test_data/scout_api_usage_response.json') + output = util_load_json('test_data/scout_api_usage_output.json') + hr = util_load_text_data('test_data/scout_api_usage_hr.md') + + requests_mock.get(f'{BASE_URL}{ENDPOINTS["QUERY_USAGE"]}', json=response, status_code=200) + + mocker.patch.object(demisto, 'params', return_value=BASIC_PARAMS) + mocker.patch.object(demisto, 'command', return_value='scout-api-usage') + + main() + assert output == mock_return.call_args.args[0].outputs + assert response == mock_return.call_args.args[0].raw_response + assert hr == mock_return.call_args.args[0].readable_output + assert 'command_name' == mock_return.call_args.args[0].outputs_key_field + assert OUTPUT_PREFIX['QUERY_USAGE'] == mock_return.call_args.args[0].outputs_prefix + + +@patch('TeamCymruScout.return_results') +def test_ip_command_using_main_function(mock_return, requests_mock, capfd, mocker): + ''' + Test case scenario for successful execution of ip_command through main function. + + Given: + - mocked client. + When: + - Calling `ip_command` function. + Then: + - Returns CommandResult. + ''' + response = util_load_json('test_data/ip_response.json') + output = util_load_json('test_data/ip_output.json') + ip_hr = util_load_text_data('test_data/ip_hr.md') + query_usage_hr = util_load_text_data('test_data/scout_api_usage_hr.md') + raw_response = util_load_json('test_data/ip_raw_response.json') + ip_indicator = util_load_json('test_data/ip_indicator.json') + ip_relationships = util_load_json('test_data/ip_relationships.json') + + requests_mock.get(f'{BASE_URL}{ENDPOINTS["IP_DETAILS"].format("0.0.0.1")}', json=response, status_code=200) + + # create_relationships parameter marked as true. + BASIC_PARAMS['create_relationships'] = 'true' + + mocker.patch.object(demisto, 'params', return_value=BASIC_PARAMS) + mocker.patch.object(demisto, 'args', return_value=IP_ARGS) + mocker.patch.object(demisto, 'command', return_value='ip') + + capfd.close() + main() + + assert output[0] == mock_return.call_args.args[0][0].outputs + assert raw_response == mock_return.call_args.args[0][0].raw_response + assert ip_hr == mock_return.call_args.args[0][0].readable_output + assert OUTPUT_KEY_FIELD['IP'] == mock_return.call_args.args[0][0].outputs_key_field + assert OUTPUT_PREFIX['IP'] == mock_return.call_args.args[0][0].outputs_prefix + assert ip_indicator == mock_return.call_args.args[0][0].indicator.to_context() + assert ip_relationships == [data.to_context() for data in mock_return.call_args.args[0][0].relationships] + + assert output[1] == mock_return.call_args.args[0][1].outputs + assert raw_response == mock_return.call_args.args[0][1].raw_response + assert query_usage_hr == mock_return.call_args.args[0][1].readable_output + assert OUTPUT_KEY_FIELD['QUERY_USAGE'] == mock_return.call_args.args[0][1].outputs_key_field + assert OUTPUT_PREFIX['QUERY_USAGE'] == mock_return.call_args.args[0][1].outputs_prefix + + +@pytest.mark.parametrize('args, error_message', [ + ({}, ERROR_MESSAGES['NO_PARAM_PROVIDED'].format('ip')), + ({'ip': '0.0.0.1', 'start_date': '1 day', 'end_date': '2 day'}, ERROR_MESSAGES['START_DATE_GREATER_THAN_END_DATE']), + ({'ip': '0.0.0.1', 'start_date': '2 day', + 'end_date': str((arg_to_datetime('now') + timedelta(days=2)).strftime(DATE_FORMAT))}, + ERROR_MESSAGES['END_DATE_GREATER_THAN_CURRENT_TIME']), + ({'ip': '0.0.0.1', 'start_date': '60 day', 'end_date': '29 day'}, ERROR_MESSAGES['REACHED_MAXIMUM_DIFF_DAYS']), + ({'ip': '0.0.0.1', 'start_date': '91 day', 'end_date': '70 day'}, ERROR_MESSAGES['REACHED_MAXIMUM_START_DAYS']), + ({'ip': '0.0.0.1', 'days': '31'}, ERROR_MESSAGES['INVALID_DAY'].format('31')), + ({'ip': '0.0.0.1', 'days': '0'}, ERROR_MESSAGES['INVALID_DAY'].format('0')), + ({'ip': '0.0.0.1', 'size': '0'}, ERROR_MESSAGES['INVALID_PAGE_SIZE'].format('0', 1, MAXIMUM_DETAIL_IP_SIZE)), + ({'ip': '0.0.0.1', 'size': MAXIMUM_DETAIL_IP_SIZE + 1}, + ERROR_MESSAGES['INVALID_PAGE_SIZE'].format(MAXIMUM_DETAIL_IP_SIZE + 1, 1, MAXIMUM_DETAIL_IP_SIZE)) +]) +def test_ip_command_for_invalid_arguments_using_main_function(mocker, args, capfd, error_message): + ''' + Test case scenario for the execution of ip_command with invalid arguments. + + Given: + - mocked client. + When: + - Calling `ip_command` function. + Then: + - Returns exception. + ''' + mocker.patch.object(demisto, 'params', return_value=BASIC_PARAMS) + mocker.patch.object(demisto, 'args', return_value=args) + mocker.patch.object(demisto, 'command', return_value='ip') + return_error = mocker.patch.object(TeamCymruScout, "return_error") + + capfd.close() + main() + + assert error_message in return_error.call_args[0][0] + + +def test_scout_indicator_search_command_success(mocker, mock_client, requests_mock): + ''' + Test case scenario for successful execution of scout_indicator_search_command. + + Given: + - mocked client. + When: + - Calling `scout_indicator_search_command` function. + Then: + - Assert for the output, raw response, readable output and indicator response. + ''' + response = util_load_json('test_data/scout_indicator_search_response.json') + output = util_load_json('test_data/scout_indicator_search_output.json') + hr = util_load_text_data('test_data/scout_indicator_search_hr.md') + usage_hr = util_load_text_data('test_data/scout_api_usage_hr.md') + + requests_mock.get(f'{BASE_URL}{ENDPOINTS["SEARCH_INDICATORS"]}', json=response, status_code=200) + + args = {'query': '0.0.0.1', 'limit': 1, 'start_date': '30 day', 'end_date': 'now', 'days': '1'} + + params = {'integrationReliability': DBotScoreReliability.B, 'create_relationships': True} + mocker.patch.object(demisto, 'params', return_value=params) + results = scout_indicator_search_command(mock_client, args) + + assert response['ips'][0] == results[0].raw_response + assert hr == results[0].readable_output + assert 'ip' == results[0].outputs_key_field + assert OUTPUT_PREFIX['IP'] == results[0].outputs_prefix + assert output['entry_context'] == results[0].to_context().get('EntryContext') + + del response['ips'] + assert response == results[1].raw_response + usage_output = output['query_usage'].copy() + usage_output['command_name'] = 'scout-indicator-search' + assert usage_output == results[1].outputs + assert usage_hr == results[1].readable_output + assert 'command_name' == results[1].outputs_key_field + assert OUTPUT_PREFIX['QUERY_USAGE'] == results[1].outputs_prefix + + +def test_scout_indicator_search_command_no_result(mock_client, requests_mock): + ''' + Test case scenario for no result for scout_indicator_search_command. + + Given: + - mocked client. + When: + - Calling `scout_indicator_search_command` function. + Then: + - Assert for the output, raw response, readable output and indicator response. + ''' + response = util_load_json('test_data/scout_indicator_search_response.json') + output = util_load_json('test_data/scout_indicator_search_output.json') + usage_hr = util_load_text_data('test_data/scout_api_usage_hr.md') + + response['ips'] = None + requests_mock.get(f'{BASE_URL}{ENDPOINTS["SEARCH_INDICATORS"]}', json=response, status_code=200) + + args = {'query': '0.0.0.1', 'limit': 1, 'start_date': '30 day', 'end_date': 'now', 'days': '1'} + + results = scout_indicator_search_command(mock_client, args) + + assert response['ips'] == results[0].raw_response + assert ERROR_MESSAGES['NO_INDICATORS_FOUND'] == results[0].readable_output + + del response['ips'] + assert response == results[1].raw_response + usage_output = output['query_usage'].copy() + usage_output['command_name'] = 'scout-indicator-search' + assert usage_output == results[1].outputs + assert usage_hr == results[1].readable_output + assert 'command_name' == results[1].outputs_key_field + assert OUTPUT_PREFIX['QUERY_USAGE'] == results[1].outputs_prefix + + +@pytest.mark.parametrize('args, error_message', [ + ({}, ERROR_MESSAGES['NO_PARAM_PROVIDED'].format('query')), + ({'query': '0.0.0.1', 'start_date': '1 day', 'end_date': '2 day'}, + ERROR_MESSAGES['START_DATE_GREATER_THAN_END_DATE']), + ({'query': '0.0.0.1', 'start_date': '2 day', + 'end_date': (datetime.now() + timedelta(days=2)).strftime(DATE_FORMAT)}, + ERROR_MESSAGES['END_DATE_GREATER_THAN_CURRENT_TIME']), + ({'query': '0.0.0.1', 'start_date': '60 day', 'end_date': '29 day'}, + ERROR_MESSAGES['REACHED_MAXIMUM_DIFF_DAYS']), + ({'query': '0.0.0.1', 'start_date': '91 day', 'end_date': '70 day'}, + ERROR_MESSAGES['REACHED_MAXIMUM_START_DAYS']), + ({'query': '0.0.0.1', 'days': '31'}, ERROR_MESSAGES['INVALID_DAY'].format('31')), + ({'query': '0.0.0.1', 'days': '0'}, ERROR_MESSAGES['INVALID_DAY'].format('0')), + ({'query': '0.0.0.1', 'size': '0'}, + ERROR_MESSAGES['INVALID_PAGE_SIZE'].format('0', 1, MAXIMUM_INDICATOR_SEARCH_SIZE)), + ({'query': '0.0.0.1', 'size': MAXIMUM_INDICATOR_SEARCH_SIZE + 1}, + ERROR_MESSAGES['INVALID_PAGE_SIZE'].format( + MAXIMUM_INDICATOR_SEARCH_SIZE + 1, 1, MAXIMUM_INDICATOR_SEARCH_SIZE)), +]) +def test_scout_indicator_search_command_for_invalid_args(mock_client, args, error_message): + ''' + Test case scenario for the execution of scout_indicator_search_command with invalid arguments. + + Given: + - mocked client + When: + - Calling `scout_indicator_search_command` function. + Then: + - Returns exception. + ''' + with pytest.raises(DemistoException) as err: + scout_indicator_search_command(mock_client, args) + + assert str(err.value) == error_message + + +@patch('TeamCymruScout.return_warning') +def test_scout_ip_list_command_command_success(mock_return, mocker, mock_client, requests_mock): + ''' + Test case scenario for successful execution of scout_ip_list_command_command. + + Given: + - mocked client. + When: + - Calling `scout_ip_list_command_command` function. + Then: + - Assert for the output, raw response, readable output and indicator response. + ''' + response = util_load_json('test_data/scout_ip_list_response.json') + output = util_load_json('test_data/scout_ip_list_output.json') + hr = util_load_text_data('test_data/scout_ip_list_hr.md') + usage_hr = util_load_text_data('test_data/scout_api_usage_hr.md') + + requests_mock.get(f'{BASE_URL}{ENDPOINTS["LIST_IPS"]}', json=response, status_code=200) + + args = {'ip_addresses': '0.0.0.1,a.b.c.d,0:0:0:0:0:0:0:1'} + + params = {'integrationReliability': DBotScoreReliability.B, 'create_relationships': True} + mocker.patch.object(demisto, 'params', return_value=params) + results = scout_ip_list_command(mock_client, args) + + assert ERROR_MESSAGES['INVALID_IP_ADDRESSES'].format('a.b.c.d') == mock_return.call_args[0][0] + + assert response['data'][0] == results[0].raw_response + assert hr == results[0].readable_output + assert OUTPUT_KEY_FIELD['IP'] == results[0].outputs_key_field + assert OUTPUT_PREFIX['IP'] == results[0].outputs_prefix + assert output['entry_context'] == results[0].to_context().get('EntryContext') + + del response['data'] + assert response == results[1].raw_response + usage_output = output['query_usage'].copy() + usage_output['command_name'] = 'scout-ip-list' + assert usage_output == results[1].outputs + assert usage_hr == results[1].readable_output + assert OUTPUT_KEY_FIELD['QUERY_USAGE'] == results[1].outputs_key_field + assert OUTPUT_PREFIX['QUERY_USAGE'] == results[1].outputs_prefix + + +def test_scout_ip_list_command_no_result(mock_client, requests_mock): + ''' + Test case scenario for no result for scout_ip_list_command. + + Given: + - mocked client. + When: + - Calling `scout_ip_list_command` function. + Then: + - Assert for the output, raw response, readable output and indicator response. + ''' + response = util_load_json('test_data/scout_ip_list_response.json') + output = util_load_json('test_data/scout_ip_list_output.json') + usage_hr = util_load_text_data('test_data/scout_api_usage_hr.md') + + response['data'] = None + requests_mock.get(f'{BASE_URL}{ENDPOINTS["LIST_IPS"]}', json=response, status_code=200) + + args = {'ip_addresses': '0.0.0.1,0.0.0.2,0.0.0.3,0.0.0.4,0.0.0.5,0.0.0.6,0.0.0.7,0.0.0.8,0.0.0.9,0.0.0.10'} + + results = scout_ip_list_command(mock_client, args) + + assert response['data'] == results[0].raw_response + assert ERROR_MESSAGES['NO_INDICATORS_FOUND'] == results[0].readable_output + + del response['data'] + assert response == results[1].raw_response + usage_output = output['query_usage'].copy() + usage_output['command_name'] = 'scout-ip-list' + assert usage_output == results[1].outputs + assert usage_hr == results[1].readable_output + assert OUTPUT_KEY_FIELD['QUERY_USAGE'] == results[1].outputs_key_field + assert OUTPUT_PREFIX['QUERY_USAGE'] == results[1].outputs_prefix + + +@pytest.mark.parametrize('reliability', [ + DBotScoreReliability.A_PLUS, DBotScoreReliability.A, + DBotScoreReliability.B, DBotScoreReliability.C, + DBotScoreReliability.D, DBotScoreReliability.E, + DBotScoreReliability.F]) +def test_scout_ip_list_command_with_different_reliability(mock_client, requests_mock, mocker, reliability): + ''' + Test case scenario for the execution of scout_ip_list_command with different source reliability. + + Given: + - mocked client + When: + - Calling `scout_ip_list_command` function. + Then: + - Assert for the output, raw response, readable output and indicator response. + ''' + response = util_load_json('test_data/scout_ip_list_response.json') + + requests_mock.get(f'{BASE_URL}{ENDPOINTS["LIST_IPS"]}', json=response, status_code=200) + + args = {'ip_addresses': '0.0.0.1'} + params = {'integrationReliability': reliability} + mocker.patch.object(demisto, 'params', return_value=params) + results = scout_ip_list_command(mock_client, args) + + assert results[0].indicator.dbot_score.reliability == reliability # type: ignore + + +@pytest.mark.parametrize('args, error_message', [ + ({'ip_addresses': ', ,,, ,,,,,'}, ERROR_MESSAGES['NO_PARAM_PROVIDED'].format('ip_addresses')), + ({'ip_addresses': ' '}, ERROR_MESSAGES['NO_PARAM_PROVIDED'].format('ip_addresses')), + ({'ip_addresses': '0.0.0.1,0.0.0.2,0.0.0.3,0.0.0.4,0.0.0.5,0.0.0.6,0.0.0.7,0.0.0.8,0.0.0.9,0.0.0.10,0.0.0.11'}, + ERROR_MESSAGES['INVALID_IP_ADDRESS_SIZE'].format(11, MAXIMUM_IP_LIST_SIZE)), +]) +def test_scout_ip_list_command_for_invalid_args(mock_client, args, error_message): + ''' + Test case scenario for the execution of scout_ip_list_command with invalid arguments. + + Given: + - mocked client. + When: + - Calling `scout_ip_list_command` function. + Then: + - Returns exception. + ''' + with pytest.raises(DemistoException) as err: + scout_ip_list_command(mock_client, args) + + assert str(err.value) == error_message + + +def test_scout_ip_list_command_for_all_ips_invalid(mock_client): + ''' + Test case scenario for the execution of scout_ip_list_command with invalid ip addresses. + + Given: + - mocked client. + When: + - Calling `scout_ip_list_command` function. + Then: + - Returns exception. + ''' + args = {'ip_addresses': '0: 0: 85a3: 0000: asv: 8a2e: 0370: 7334,2.2.2'} + with pytest.raises(SystemExit) as err: + scout_ip_list_command(mock_client, args) + + assert err.value.code == 0 diff --git a/Packs/TeamCymru/Integrations/TeamCymruScout/command_examples b/Packs/TeamCymru/Integrations/TeamCymruScout/command_examples new file mode 100644 index 000000000000..effc038af15a --- /dev/null +++ b/Packs/TeamCymru/Integrations/TeamCymruScout/command_examples @@ -0,0 +1,4 @@ +!scout-api-usage +!ip ip=0.0.0.1 +!scout-indicator-search query="0.0.0.1" size=1 start_date="30 days" end_date="now" +!scout-ip-list ip_addresses=0.0.0.1 diff --git a/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/ip_hr.md b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/ip_hr.md new file mode 100644 index 000000000000..ceba2d0a97fb --- /dev/null +++ b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/ip_hr.md @@ -0,0 +1,39 @@ +### Summary Information For The Given Suspicious IP: [0.0.0.1](https://scout.cymru.com/scout/details?query=0.0.0.1) +|Country Code|Whois|Tags|Insights| +|---|---|---|---| +| US | ***asn***: 15133
***as_name***: test_name
***net_name***: test_name-data-03
***org_name***: test_name Inc. | **-** ***id***: 176
***name***: cdn
**children**:
**-** ***id***: 206
***name***: test_name | **-** ***rating***: no_rating
***message***: x509 subject "CN=www.example.org, O=Internet Corporation for Assigned Names and Numbers. | + +### Top PDNS +|Domain|Event Count|First Seen|Last Seen| +|---|---|---|---| +| test1.aaa | 78 | 2024-05-27 | 2024-06-25 | +| test2.io | 40 | 2024-05-30 | 2024-06-25 | +| test3.as | 27 | 2024-05-27 | 2024-06-25 | +| test4.com | 24 | 2024-05-27 | 2024-06-24 | +| test5.io | 23 | 2024-05-28 | 2024-06-25 | + +### Top Peers +|Proto|Client IP|Client Country Code(s)|Client Services|Server IP|Server Country Code(s)|Server Tag(s)|Server Services|Event Count|First Seen|Last Seen|Client AS Name|Server AS Name| +|---|---|---|---|---|---|---|---|---|---|---|---|---| +| TCP | 0.0.0.2 | ZA | **-** ***port***: 64552
***proto_number***: 6 | 0.0.0.1 | US | cdn: (test_name) | **-** ***service_name***: http
***port***: 80
***proto_number***: 6
***description***: World Wide Web HTTP | 6040 | 2024-06-04 | 2024-06-04 | Interworks-Wireless-Solutions, ZA | test_name, US | +| TCP | 0.0.0.3 | IT | **-** ***port***: 60230
***proto_number***: 6 | 0.0.0.1 | US | cdn: (test_name) | **-** ***service_name***: http
***port***: 80
***proto_number***: 6
***description***: World Wide Web HTTP | 5536 | 2024-06-20 | 2024-06-21 | IPTECHNOLOGY, IT | test_name, US | +| TCP | 0.0.0.4 | SE | **-** ***port***: 65533
***proto_number***: 6 | 0.0.0.1 | US | cdn: (test_name) | **-** ***service_name***: http
***port***: 80
***proto_number***: 6
***description***: World Wide Web HTTP | 5418 | 2024-06-17 | 2024-06-20 | AS-84GRAMS 84 Grams AB, SE | test_name, US | +| ICMP | 0.0.0.5 | BR | **-** ***port***: 0
***proto_number***: 1 | 0.0.0.1 | US | cdn: (test_name) | **-** ***port***: 0
***proto_number***: 1 | 4070 | 2024-05-27 | 2024-06-25 | VirtuaServer Informatica Ltda, BR | test_name, US | +| TCP | 0.0.0.6 | CZ | **-** ***port***: 62320
***proto_number***: 6 | 0.0.0.1 | US | cdn: (test_name) | **-** ***service_name***: http
***port***: 80
***proto_number***: 6
***description***: World Wide Web HTTP | 3888 | 2024-06-08 | 2024-06-08 | CDT-AS The Czech Republic, CZ | test_name, US | + +### Top Open Ports +|Event Count|Port|Protocol|Protocol Text|Service|First Seen|Last Seen| +|---|---|---|---|---|---|---| +| 53 | 80 | 6 | TCP | http | 2024-05-27 | 2024-06-25 | +| 43 | 443 | 6 | TCP | https | 2024-05-27 | 2024-06-25 | + +### Top Fingerprints +|Count|First Seen|Last Seen|Port|Signature|Type| +|---|---|---|---|---|---| +| 5 | 2024-05-30 | 2024-06-21 | 443 | testsignature | jarm | + +### Top Certificates +|Common Name|First Seen|Issuer|Issuer Common Name|Last Seen|Md5|Not After|Not Before|Port|Self Signed|Sha1|Sha256|Subject|Valid Days| +|---|---|---|---|---|---|---|---|---|---|---|---|---|---| +| www.example.org | 2024-05-30 | CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1, O=DigiCert Inc, C=US | DigiCert Global G2 TLS RSA SHA256 2020 CA1 | 2024-06-21 | testmd5 | 2025-03-01 | 2024-01-30 | 443 | false | testsha1 | testsha256 | CN=www.example.org, O=Internet Corporation for Assigned Names and Numbers. | 397 | + diff --git a/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/ip_indicator.json b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/ip_indicator.json new file mode 100644 index 000000000000..a0dfa2136b0c --- /dev/null +++ b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/ip_indicator.json @@ -0,0 +1,94 @@ +{ + "DBotScore(val.Indicator && val.Indicator == obj.Indicator && val.Vendor == obj.Vendor && val.Type == obj.Type)": { + "Indicator": "0.0.0.1", + "Reliability": "A - Completely reliable", + "Score": 2, + "Type": "ip", + "Vendor": "Team Cymru Scout" + }, + "IP(val.Address && val.Address == obj.Address)": { + "ASN": 15133, + "ASOwner": "test_name", + "Address": "0.0.0.1", + "Description": "x509 subject \"CN=www.example.org, O=Internet Corporation for Assigned Names and Numbers.\n", + "Organization": { + "Name": "test_name Inc." + }, + "Port": "443, 80", + "Region": "EU", + "Relationships": [ + { + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "0.0.0.2", + "EntityBType": "IP", + "Relationship": "communicated-with" + }, + { + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "0.0.0.3", + "EntityBType": "IP", + "Relationship": "communicated-with" + }, + { + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "0.0.0.4", + "EntityBType": "IP", + "Relationship": "communicated-with" + }, + { + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "0.0.0.5", + "EntityBType": "IP", + "Relationship": "communicated-with" + }, + { + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "0.0.0.6", + "EntityBType": "IP", + "Relationship": "communicated-with" + }, + { + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "test1.aaa", + "EntityBType": "Domain", + "Relationship": "resolves-to" + }, + { + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "test2.bb", + "EntityBType": "Domain", + "Relationship": "resolves-to" + }, + { + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "test3.as", + "EntityBType": "Domain", + "Relationship": "resolves-to" + }, + { + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "test4.com", + "EntityBType": "Domain", + "Relationship": "resolves-to" + }, + { + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "test5.ovh", + "EntityBType": "Domain", + "Relationship": "resolves-to" + } + ], + "Tags": "cdn: (test_name)", + "UpdatedDate": "2012-06-22" + } +} \ No newline at end of file diff --git a/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/ip_output.json b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/ip_output.json new file mode 100644 index 000000000000..f0747404e351 --- /dev/null +++ b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/ip_output.json @@ -0,0 +1,859 @@ +[ + { + "ip": "0.0.0.1", + "sections": [ + "identity", + "comms", + "pdns", + "open_ports", + "x509", + "fingerprints", + "whois", + "summary" + ], + "identity": { + "asn": 15133, + "as_name": "test_name", + "net_name": "test_name-data-03", + "org_name": "test_name Inc." + }, + "whois": { + "modified": "2012-06-22", + "asn": 15133, + "cidr": "0.0.0.1/24", + "as_name": "test_name", + "bgp_asn": 15133, + "bgp_asn_name": "test_name, US", + "net_name": "test_name-data-03", + "net_handle": "", + "description": "[\"data-03-EU-93-184-216-0-24\"]", + "cc": "EU", + "city": "", + "address": "", + "abuse_contact_id": "", + "about_contact_role": "", + "about_contact_person": "", + "about_contact_email": "", + "about_contact_phone": "", + "about_contact_country": "", + "about_contact_city": "", + "about_contact_address": "", + "admin_contact_id": "DS7892-RIPE", + "admin_contact_role": "", + "admin_contact_person": "Derrick Sawyer", + "admin_contact_email": "", + "admin_contact_phone": "+18123456789", + "admin_contact_country": "", + "admin_contact_city": "", + "admin_contact_address": "[\"11811 N. Tatum Blvd, Suite 3031, Phoenix, AZ 85028\"]", + "tech_contact_id": "DS7892-RIPE", + "tech_contact_role": "", + "tech_contact_person": "Derrick Sawyer", + "tech_contact_email": "", + "tech_contact_phone": "+18987654321", + "tech_contact_country": "", + "tech_contact_city": "", + "tech_contact_address": "[\"11811 N. Tatum Blvd, Suite 3031, Phoenix, AZ 85028\"]", + "org_id": "", + "org_name": "test_name Inc.", + "org_email": "", + "org_phone": "", + "org_country": "", + "org_city": "", + "org_address": "", + "mnt_by_email": "", + "mnt_lower_email": "", + "mnt_router_email": "" + }, + "communications": { + "event_count": 33264, + "peers": [ + { + "proto": 6, + "proto_text": "TCP", + "local": { + "ip": "0.0.0.1", + "min_port": 80, + "max_port": 80, + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "test_name, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name" + } + ] + } + ], + "unique_ports": 1, + "top_services": [ + { + "service_name": "http", + "port": 80, + "proto_number": 6, + "description": "World Wide Web HTTP" + } + ] + }, + "peer": { + "ip": "0.0.0.2", + "min_port": 52049, + "max_port": 64552, + "country_codes": [ + "ZA" + ], + "as_info": [ + { + "asn": 327983, + "as_name": "Interworks-Wireless-Solutions, ZA" + } + ], + "unique_ports": 3669, + "top_services": [ + { + "service_name": "", + "port": 64552, + "proto_number": 6, + "description": "" + } + ] + }, + "event_count": 6040, + "first_seen": "2024-06-04", + "last_seen": "2024-06-04" + }, + { + "proto": 6, + "proto_text": "TCP", + "local": { + "ip": "0.0.0.1", + "min_port": 80, + "max_port": 80, + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "test_name, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name" + } + ] + } + ], + "unique_ports": 1, + "top_services": [ + { + "service_name": "http", + "port": 80, + "proto_number": 6, + "description": "World Wide Web HTTP" + } + ] + }, + "peer": { + "ip": "0.0.0.3", + "min_port": 55262, + "max_port": 60230, + "country_codes": [ + "IT" + ], + "as_info": [ + { + "asn": 206476, + "as_name": "IPTECHNOLOGY, IT" + } + ], + "unique_ports": 2767, + "top_services": [ + { + "service_name": "", + "port": 60230, + "proto_number": 6, + "description": "" + } + ] + }, + "event_count": 5536, + "first_seen": "2024-06-20", + "last_seen": "2024-06-21" + }, + { + "proto": 6, + "proto_text": "TCP", + "local": { + "ip": "0.0.0.1", + "min_port": 80, + "max_port": 80, + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "test_name, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name" + } + ] + } + ], + "unique_ports": 1, + "top_services": [ + { + "service_name": "http", + "port": 80, + "proto_number": 6, + "description": "World Wide Web HTTP" + } + ] + }, + "peer": { + "ip": "0.0.0.4", + "min_port": 49160, + "max_port": 65533, + "country_codes": [ + "SE" + ], + "as_info": [ + { + "asn": 57630, + "as_name": "AS-84GRAMS 84 Grams AB, SE" + } + ], + "unique_ports": 4606, + "top_services": [ + { + "service_name": "", + "port": 65533, + "proto_number": 6, + "description": "" + } + ] + }, + "event_count": 5418, + "first_seen": "2024-06-17", + "last_seen": "2024-06-20" + }, + { + "proto": 1, + "proto_text": "ICMP", + "local": { + "ip": "0.0.0.1", + "min_port": 0, + "max_port": 0, + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "test_name, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name" + } + ] + } + ], + "unique_ports": 1, + "top_services": [ + { + "service_name": "", + "port": 0, + "proto_number": 1, + "description": "" + } + ] + }, + "peer": { + "ip": "0.0.0.5", + "min_port": 0, + "max_port": 0, + "country_codes": [ + "BR" + ], + "as_info": [ + { + "asn": 262954, + "as_name": "VirtuaServer Informatica Ltda, BR" + } + ], + "unique_ports": 1, + "top_services": [ + { + "service_name": "", + "port": 0, + "proto_number": 1, + "description": "" + } + ] + }, + "event_count": 4070, + "first_seen": "2024-05-27", + "last_seen": "2024-06-25" + }, + { + "proto": 6, + "proto_text": "TCP", + "local": { + "ip": "0.0.0.1", + "min_port": 80, + "max_port": 80, + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "test_name, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name" + } + ] + } + ], + "unique_ports": 1, + "top_services": [ + { + "service_name": "http", + "port": 80, + "proto_number": 6, + "description": "World Wide Web HTTP" + } + ] + }, + "peer": { + "ip": "0.0.0.6", + "min_port": 56774, + "max_port": 62320, + "country_codes": [ + "CZ" + ], + "as_info": [ + { + "asn": 25512, + "as_name": "CDT-AS The Czech Republic, CZ" + } + ], + "unique_ports": 1963, + "top_services": [ + { + "service_name": "", + "port": 62320, + "proto_number": 6, + "description": "" + } + ] + }, + "event_count": 3888, + "first_seen": "2024-06-08", + "last_seen": "2024-06-08" + } + ] + }, + "pdns": { + "event_count": 1338, + "pdns": [ + { + "ip": "0.0.0.1", + "domain": "test1.aaa", + "root": "test1.aaa", + "tld": "aaa", + "type": "A", + "registrar": "PDR Ltd. d/b/a test1.com", + "domain_created": "2023-03-03", + "domain_expires": "2025-03-03", + "nameservers": [ + { + "root": "test1.com.br", + "nameservers": [ + "ns1036.test1.com.br", + "ns1037.test1.com.br" + ] + } + ], + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "" + } + ], + "distinct_ips": 1, + "active_days": 20, + "event_count": 78, + "first_seen": "2024-05-27", + "last_seen": "2024-06-25" + }, + { + "ip": "0.0.0.1", + "domain": "test2.bb", + "root": "test2.bb", + "tld": "bb", + "type": "A", + "registrar": "Key-Systems GmbH", + "domain_created": "2020-05-20", + "domain_expires": "2025-05-20", + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "" + } + ], + "distinct_ips": 1, + "active_days": 17, + "event_count": 40, + "first_seen": "2024-05-30", + "last_seen": "2024-06-25" + }, + { + "ip": "0.0.0.1", + "domain": "test3.as", + "root": "test3.as", + "tld": "as", + "type": "A", + "registrar": "", + "domain_created": "", + "domain_expires": "", + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "" + } + ], + "distinct_ips": 1, + "active_days": 27, + "event_count": 27, + "first_seen": "2024-05-27", + "last_seen": "2024-06-25" + }, + { + "ip": "0.0.0.1", + "domain": "test4.com", + "root": "test4.com", + "tld": "com", + "type": "A", + "registrar": "RegistryGate GmbH", + "domain_created": "2010-12-11", + "domain_expires": "2024-12-11", + "nameservers": [ + { + "root": "test4.com", + "nameservers": [ + "ns5.test4.com", + "ns6.test4.com" + ] + } + ], + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "" + } + ], + "distinct_ips": 1, + "active_days": 24, + "event_count": 24, + "first_seen": "2024-05-27", + "last_seen": "2024-06-24" + }, + { + "ip": "0.0.0.1", + "domain": "test5.ovh", + "root": "test5.ovh", + "tld": "ovh", + "type": "A", + "registrar": "OVH", + "domain_created": "2024-05-06", + "domain_expires": "2025-05-06", + "nameservers": [ + { + "root": "test5.ca", + "nameservers": [ + "dns10.test5.ca", + "ns10.test5.ca" + ] + } + ], + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "" + } + ], + "distinct_ips": 1, + "active_days": 23, + "event_count": 23, + "first_seen": "2024-05-27", + "last_seen": "2024-06-25" + } + ] + }, + "fingerprints": { + "event_count": 5, + "fingerprints": [ + { + "ip": "0.0.0.1", + "type": "jarm", + "fingerprint": "testsignature", + "port": 443, + "first_seen": "2024-05-30", + "last_seen": "2024-06-21", + "distinct_ips": 830, + "active_days": 5, + "event_count": 5 + } + ] + }, + "open_ports": { + "event_count": 2, + "unique_ports": 2, + "open_ports": [ + { + "ip": "0.0.0.1", + "port": 443, + "protocol": 6, + "protocol_text": "TCP", + "service": "https", + "banner": "TLS/1.1 cipher:0xc013, www.example.org, www.example.org, example.net, example.edu, example.com, example.org, www.example.com, www.example.edu, www.example.net", + "banner_sha1": "test_sha1", + "first_seen": "2024-05-30", + "last_seen": "2024-06-21", + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "test_name, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name" + } + ] + } + ], + "event_count": 5 + }, + { + "ip": "0.0.0.1", + "port": 80, + "protocol": 6, + "protocol_text": "TCP", + "service": "http", + "banner": "404 - Not Found", + "banner_sha1": "test_sha1", + "first_seen": "2024-05-30", + "last_seen": "2024-06-21", + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "test_name, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name" + } + ] + } + ], + "event_count": 5 + } + ] + }, + "x509": { + "event_count": 5, + "x509": [ + { + "ip": "0.0.0.1", + "issuer": "CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1, O=DigiCert Inc, C=US", + "issuer_common_name": "DigiCert Global G2 TLS RSA SHA256 2020 CA1", + "common_name": "www.example.org", + "altnames": [ + "example.com", + "example.edu", + "example.net", + "example.org", + "www.example.com", + "www.example.edu", + "www.example.net", + "www.example.org" + ], + "serial": "testserial", + "subject": "CN=www.example.org, O=Internet Corporation for Assigned Names and Numbers.", + "not_after": "2025-03-01", + "not_before": "2024-01-30", + "validity_period": "397 Days", + "md5": "testmd5", + "sha1": "testsha1", + "sha256": "testsha256", + "first_seen": "2024-05-30", + "last_seen": "2024-06-21", + "port": 443, + "self_signed": false, + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "test_name, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name" + } + ] + } + ], + "count": 5 + } + ] + }, + "summary": { + "total": 1, + "ip": "0.0.0.1", + "start_date": "2024-05-27", + "end_date": "2024-06-25", + "geo_ip_cc": "US", + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name" + } + ] + } + ], + "bgp_asn": 15133, + "bgp_asname": "test_name, US", + "whois": { + "asn": 15133, + "as_name": "test_name", + "net_name": "test_name-data-03", + "org_name": "test_name Inc." + }, + "pdns": { + "total": 1338, + "top_pdns": [ + { + "event_count": 78, + "domain": "test1.aaa", + "first_seen": "2024-05-27", + "last_seen": "2024-06-25", + "css_color": "#a6abb7" + }, + { + "event_count": 40, + "domain": "test2.io", + "first_seen": "2024-05-30", + "last_seen": "2024-06-25", + "css_color": "#f2d561" + }, + { + "event_count": 27, + "domain": "test3.as", + "first_seen": "2024-05-27", + "last_seen": "2024-06-25", + "css_color": "#99a1ff" + }, + { + "event_count": 24, + "domain": "test4.com", + "first_seen": "2024-05-27", + "last_seen": "2024-06-24", + "css_color": "#e57ea1" + }, + { + "event_count": 23, + "domain": "test5.io", + "first_seen": "2024-05-28", + "last_seen": "2024-06-25", + "css_color": "#f2d561" + } + ] + }, + "open_ports": { + "total": 2, + "unique_ports": 2, + "top_open_ports": [ + { + "event_count": 53, + "port": 80, + "protocol": 6, + "protocol_text": "TCP", + "service": "http", + "first_seen": "2024-05-27", + "last_seen": "2024-06-25", + "css_color": "#a6abb7" + }, + { + "event_count": 43, + "port": 443, + "protocol": 6, + "protocol_text": "TCP", + "service": "https", + "first_seen": "2024-05-27", + "last_seen": "2024-06-25", + "css_color": "#99a1ff" + } + ] + }, + "certs": { + "top_certs": [ + { + "issuer": "CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1, O=DigiCert Inc, C=US", + "issuer_common_name": "DigiCert Global G2 TLS RSA SHA256 2020 CA1", + "common_name": "www.example.org", + "subject": "CN=www.example.org, O=Internet Corporation for Assigned Names and Numbers.", + "port": 443, + "first_seen": "2024-05-30", + "last_seen": "2024-06-21", + "self_signed": false, + "not_before": "2024-01-30", + "not_after": "2025-03-01", + "valid_days": 397, + "md5": "testmd5", + "sha1": "testsha1", + "sha256": "testsha256", + "css_color": "#b382d9" + } + ] + }, + "tag_timeline": { + "data": [ + { + "tag": { + "id": 176, + "name": "cdn", + "description": "The CDN tag characterizes IP addresses associated with Content Delivery Networks (CDNs).", + "css_color": "#8A532C" + }, + "first_seen": "2024-05-27", + "last_seen": "2024-06-25" + } + ] + }, + "insights": { + "overall_rating": "suspicious", + "total": 8, + "insights": [ + { + "rating": "no_rating", + "message": "x509 subject \"CN=www.example.org, O=Internet Corporation for Assigned Names and Numbers." + } + ] + }, + "fingerprints": { + "top_fingerprints": [ + { + "type": "jarm", + "signature": "testsignature", + "port": 443, + "first_seen": "2024-05-30", + "last_seen": "2024-06-21", + "count": 5 + } + ] + } + } + }, + { + "command_name": "ip", + "foundation_api_usage": { + "query_limit": 0, + "remaining_queries": 0, + "used_queries": 15 + }, + "query_limit": 50000, + "remaining_queries": 49739, + "request_id": "test_id", + "size": 1000, + "start_date": "2024-05-27", + "end_date": "2024-06-25", + "used_queries": 261 + } +] \ No newline at end of file diff --git a/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/ip_raw_response.json b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/ip_raw_response.json new file mode 100644 index 000000000000..8a77b2ff5e58 --- /dev/null +++ b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/ip_raw_response.json @@ -0,0 +1,856 @@ +{ + "request_id": "test_id", + "size": 1000, + "start_date": "2024-05-27", + "end_date": "2024-06-25", + "ip": "0.0.0.1", + "sections": [ + "identity", + "comms", + "pdns", + "open_ports", + "x509", + "fingerprints", + "whois", + "summary" + ], + "usage": { + "used_queries": 261, + "remaining_queries": 49739, + "query_limit": 50000, + "foundation_api_usage": { + "used_queries": 15, + "remaining_queries": 0, + "query_limit": 0 + } + }, + "identity": { + "asn": 15133, + "as_name": "test_name", + "net_name": "test_name-data-03", + "org_name": "test_name Inc." + }, + "whois": { + "modified": "2012-06-22", + "asn": 15133, + "cidr": "0.0.0.1/24", + "as_name": "test_name", + "bgp_asn": 15133, + "bgp_asn_name": "test_name, US", + "net_name": "test_name-data-03", + "net_handle": "", + "description": "[\"data-03-EU-93-184-216-0-24\"]", + "cc": "EU", + "city": "", + "address": "", + "abuse_contact_id": "", + "about_contact_role": "", + "about_contact_person": "", + "about_contact_email": "", + "about_contact_phone": "", + "about_contact_country": "", + "about_contact_city": "", + "about_contact_address": "", + "admin_contact_id": "DS7892-RIPE", + "admin_contact_role": "", + "admin_contact_person": "Derrick Sawyer", + "admin_contact_email": "", + "admin_contact_phone": "+18123456789", + "admin_contact_country": "", + "admin_contact_city": "", + "admin_contact_address": "[\"11811 N. Tatum Blvd, Suite 3031, Phoenix, AZ 85028\"]", + "tech_contact_id": "DS7892-RIPE", + "tech_contact_role": "", + "tech_contact_person": "Derrick Sawyer", + "tech_contact_email": "", + "tech_contact_phone": "+18987654321", + "tech_contact_country": "", + "tech_contact_city": "", + "tech_contact_address": "[\"11811 N. Tatum Blvd, Suite 3031, Phoenix, AZ 85028\"]", + "org_id": "", + "org_name": "test_name Inc.", + "org_email": "", + "org_phone": "", + "org_country": "", + "org_city": "", + "org_address": "", + "mnt_by_email": "", + "mnt_lower_email": "", + "mnt_router_email": "" + }, + "communications": { + "event_count": 33264, + "peers": [ + { + "proto": 6, + "proto_text": "TCP", + "local": { + "ip": "0.0.0.1", + "min_port": 80, + "max_port": 80, + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "test_name, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name" + } + ] + } + ], + "unique_ports": 1, + "top_services": [ + { + "service_name": "http", + "port": 80, + "proto_number": 6, + "description": "World Wide Web HTTP" + } + ] + }, + "peer": { + "ip": "0.0.0.2", + "min_port": 52049, + "max_port": 64552, + "country_codes": [ + "ZA" + ], + "as_info": [ + { + "asn": 327983, + "as_name": "Interworks-Wireless-Solutions, ZA" + } + ], + "unique_ports": 3669, + "top_services": [ + { + "service_name": "", + "port": 64552, + "proto_number": 6, + "description": "" + } + ] + }, + "event_count": 6040, + "first_seen": "2024-06-04", + "last_seen": "2024-06-04" + }, + { + "proto": 6, + "proto_text": "TCP", + "local": { + "ip": "0.0.0.1", + "min_port": 80, + "max_port": 80, + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "test_name, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name" + } + ] + } + ], + "unique_ports": 1, + "top_services": [ + { + "service_name": "http", + "port": 80, + "proto_number": 6, + "description": "World Wide Web HTTP" + } + ] + }, + "peer": { + "ip": "0.0.0.3", + "min_port": 55262, + "max_port": 60230, + "country_codes": [ + "IT" + ], + "as_info": [ + { + "asn": 206476, + "as_name": "IPTECHNOLOGY, IT" + } + ], + "unique_ports": 2767, + "top_services": [ + { + "service_name": "", + "port": 60230, + "proto_number": 6, + "description": "" + } + ] + }, + "event_count": 5536, + "first_seen": "2024-06-20", + "last_seen": "2024-06-21" + }, + { + "proto": 6, + "proto_text": "TCP", + "local": { + "ip": "0.0.0.1", + "min_port": 80, + "max_port": 80, + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "test_name, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name" + } + ] + } + ], + "unique_ports": 1, + "top_services": [ + { + "service_name": "http", + "port": 80, + "proto_number": 6, + "description": "World Wide Web HTTP" + } + ] + }, + "peer": { + "ip": "0.0.0.4", + "min_port": 49160, + "max_port": 65533, + "country_codes": [ + "SE" + ], + "as_info": [ + { + "asn": 57630, + "as_name": "AS-84GRAMS 84 Grams AB, SE" + } + ], + "unique_ports": 4606, + "top_services": [ + { + "service_name": "", + "port": 65533, + "proto_number": 6, + "description": "" + } + ] + }, + "event_count": 5418, + "first_seen": "2024-06-17", + "last_seen": "2024-06-20" + }, + { + "proto": 1, + "proto_text": "ICMP", + "local": { + "ip": "0.0.0.1", + "min_port": 0, + "max_port": 0, + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "test_name, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name" + } + ] + } + ], + "unique_ports": 1, + "top_services": [ + { + "service_name": "", + "port": 0, + "proto_number": 1, + "description": "" + } + ] + }, + "peer": { + "ip": "0.0.0.5", + "min_port": 0, + "max_port": 0, + "country_codes": [ + "BR" + ], + "as_info": [ + { + "asn": 262954, + "as_name": "VirtuaServer Informatica Ltda, BR" + } + ], + "unique_ports": 1, + "top_services": [ + { + "service_name": "", + "port": 0, + "proto_number": 1, + "description": "" + } + ] + }, + "event_count": 4070, + "first_seen": "2024-05-27", + "last_seen": "2024-06-25" + }, + { + "proto": 6, + "proto_text": "TCP", + "local": { + "ip": "0.0.0.1", + "min_port": 80, + "max_port": 80, + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "test_name, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name" + } + ] + } + ], + "unique_ports": 1, + "top_services": [ + { + "service_name": "http", + "port": 80, + "proto_number": 6, + "description": "World Wide Web HTTP" + } + ] + }, + "peer": { + "ip": "0.0.0.6", + "min_port": 56774, + "max_port": 62320, + "country_codes": [ + "CZ" + ], + "as_info": [ + { + "asn": 25512, + "as_name": "CDT-AS The Czech Republic, CZ" + } + ], + "unique_ports": 1963, + "top_services": [ + { + "service_name": "", + "port": 62320, + "proto_number": 6, + "description": "" + } + ] + }, + "event_count": 3888, + "first_seen": "2024-06-08", + "last_seen": "2024-06-08" + } + ] + }, + "pdns": { + "event_count": 1338, + "pdns": [ + { + "ip": "0.0.0.1", + "domain": "test1.aaa", + "root": "test1.aaa", + "tld": "aaa", + "type": "A", + "registrar": "PDR Ltd. d/b/a test1.com", + "domain_created": "2023-03-03", + "domain_expires": "2025-03-03", + "nameservers": [ + { + "root": "test1.com.br", + "nameservers": [ + "ns1036.test1.com.br", + "ns1037.test1.com.br" + ] + } + ], + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "" + } + ], + "distinct_ips": 1, + "active_days": 20, + "event_count": 78, + "first_seen": "2024-05-27", + "last_seen": "2024-06-25" + }, + { + "ip": "0.0.0.1", + "domain": "test2.bb", + "root": "test2.bb", + "tld": "bb", + "type": "A", + "registrar": "Key-Systems GmbH", + "domain_created": "2020-05-20", + "domain_expires": "2025-05-20", + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "" + } + ], + "distinct_ips": 1, + "active_days": 17, + "event_count": 40, + "first_seen": "2024-05-30", + "last_seen": "2024-06-25" + }, + { + "ip": "0.0.0.1", + "domain": "test3.as", + "root": "test3.as", + "tld": "as", + "type": "A", + "registrar": "", + "domain_created": "", + "domain_expires": "", + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "" + } + ], + "distinct_ips": 1, + "active_days": 27, + "event_count": 27, + "first_seen": "2024-05-27", + "last_seen": "2024-06-25" + }, + { + "ip": "0.0.0.1", + "domain": "test4.com", + "root": "test4.com", + "tld": "com", + "type": "A", + "registrar": "RegistryGate GmbH", + "domain_created": "2010-12-11", + "domain_expires": "2024-12-11", + "nameservers": [ + { + "root": "test4.com", + "nameservers": [ + "ns5.test4.com", + "ns6.test4.com" + ] + } + ], + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "" + } + ], + "distinct_ips": 1, + "active_days": 24, + "event_count": 24, + "first_seen": "2024-05-27", + "last_seen": "2024-06-24" + }, + { + "ip": "0.0.0.1", + "domain": "test5.ovh", + "root": "test5.ovh", + "tld": "ovh", + "type": "A", + "registrar": "OVH", + "domain_created": "2024-05-06", + "domain_expires": "2025-05-06", + "nameservers": [ + { + "root": "test5.ca", + "nameservers": [ + "dns10.test5.ca", + "ns10.test5.ca" + ] + } + ], + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "" + } + ], + "distinct_ips": 1, + "active_days": 23, + "event_count": 23, + "first_seen": "2024-05-27", + "last_seen": "2024-06-25" + } + ] + }, + "fingerprints": { + "event_count": 5, + "fingerprints": [ + { + "ip": "0.0.0.1", + "type": "jarm", + "fingerprint": "testsignature", + "port": 443, + "first_seen": "2024-05-30", + "last_seen": "2024-06-21", + "distinct_ips": 830, + "active_days": 5, + "event_count": 5 + } + ] + }, + "open_ports": { + "event_count": 2, + "unique_ports": 2, + "open_ports": [ + { + "ip": "0.0.0.1", + "port": 443, + "protocol": 6, + "protocol_text": "TCP", + "service": "https", + "banner": "TLS/1.1 cipher:0xc013, www.example.org, www.example.org, example.net, example.edu, example.com, example.org, www.example.com, www.example.edu, www.example.net", + "banner_sha1": "test_sha1", + "first_seen": "2024-05-30", + "last_seen": "2024-06-21", + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "test_name, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name" + } + ] + } + ], + "event_count": 5 + }, + { + "ip": "0.0.0.1", + "port": 80, + "protocol": 6, + "protocol_text": "TCP", + "service": "http", + "banner": "404 - Not Found", + "banner_sha1": "test_sha1", + "first_seen": "2024-05-30", + "last_seen": "2024-06-21", + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "test_name, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name" + } + ] + } + ], + "event_count": 5 + } + ] + }, + "x509": { + "event_count": 5, + "x509": [ + { + "ip": "0.0.0.1", + "issuer": "CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1, O=DigiCert Inc, C=US", + "issuer_common_name": "DigiCert Global G2 TLS RSA SHA256 2020 CA1", + "common_name": "www.example.org", + "altnames": [ + "example.com", + "example.edu", + "example.net", + "example.org", + "www.example.com", + "www.example.edu", + "www.example.net", + "www.example.org" + ], + "serial": "testserial", + "subject": "CN=www.example.org, O=Internet Corporation for Assigned Names and Numbers.", + "not_after": "2025-03-01", + "not_before": "2024-01-30", + "validity_period": "397 Days", + "md5": "testmd5", + "sha1": "testsha1", + "sha256": "testsha256", + "first_seen": "2024-05-30", + "last_seen": "2024-06-21", + "port": 443, + "self_signed": false, + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "test_name, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name" + } + ] + } + ], + "count": 5 + } + ] + }, + "summary": { + "total": 1, + "ip": "0.0.0.1", + "start_date": "2024-05-27", + "end_date": "2024-06-25", + "geo_ip_cc": "US", + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name" + } + ] + } + ], + "bgp_asn": 15133, + "bgp_asname": "test_name, US", + "whois": { + "asn": 15133, + "as_name": "test_name", + "net_name": "test_name-data-03", + "org_name": "test_name Inc." + }, + "pdns": { + "total": 1338, + "top_pdns": [ + { + "event_count": 78, + "domain": "test1.aaa", + "first_seen": "2024-05-27", + "last_seen": "2024-06-25", + "css_color": "#a6abb7" + }, + { + "event_count": 40, + "domain": "test2.io", + "first_seen": "2024-05-30", + "last_seen": "2024-06-25", + "css_color": "#f2d561" + }, + { + "event_count": 27, + "domain": "test3.as", + "first_seen": "2024-05-27", + "last_seen": "2024-06-25", + "css_color": "#99a1ff" + }, + { + "event_count": 24, + "domain": "test4.com", + "first_seen": "2024-05-27", + "last_seen": "2024-06-24", + "css_color": "#e57ea1" + }, + { + "event_count": 23, + "domain": "test5.io", + "first_seen": "2024-05-28", + "last_seen": "2024-06-25", + "css_color": "#f2d561" + } + ] + }, + "open_ports": { + "total": 2, + "unique_ports": 2, + "top_open_ports": [ + { + "event_count": 53, + "port": 80, + "protocol": 6, + "protocol_text": "TCP", + "service": "http", + "first_seen": "2024-05-27", + "last_seen": "2024-06-25", + "css_color": "#a6abb7" + }, + { + "event_count": 43, + "port": 443, + "protocol": 6, + "protocol_text": "TCP", + "service": "https", + "first_seen": "2024-05-27", + "last_seen": "2024-06-25", + "css_color": "#99a1ff" + } + ] + }, + "certs": { + "top_certs": [ + { + "issuer": "CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1, O=DigiCert Inc, C=US", + "issuer_common_name": "DigiCert Global G2 TLS RSA SHA256 2020 CA1", + "common_name": "www.example.org", + "subject": "CN=www.example.org, O=Internet Corporation for Assigned Names and Numbers.", + "port": 443, + "first_seen": "2024-05-30", + "last_seen": "2024-06-21", + "self_signed": false, + "not_before": "2024-01-30", + "not_after": "2025-03-01", + "valid_days": 397, + "md5": "testmd5", + "sha1": "testsha1", + "sha256": "testsha256", + "css_color": "#b382d9" + } + ] + }, + "tag_timeline": { + "data": [ + { + "tag": { + "id": 176, + "name": "cdn", + "description": "The CDN tag characterizes IP addresses associated with Content Delivery Networks (CDNs).", + "css_color": "#8A532C" + }, + "first_seen": "2024-05-27", + "last_seen": "2024-06-25" + } + ] + }, + "insights": { + "overall_rating": "suspicious", + "total": 8, + "insights": [ + { + "rating": "no_rating", + "message": "x509 subject \"CN=www.example.org, O=Internet Corporation for Assigned Names and Numbers." + } + ] + }, + "fingerprints": { + "top_fingerprints": [ + { + "type": "jarm", + "signature": "testsignature", + "port": 443, + "first_seen": "2024-05-30", + "last_seen": "2024-06-21", + "count": 5 + } + ] + } + } + } diff --git a/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/ip_relationships.json b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/ip_relationships.json new file mode 100644 index 000000000000..223fb880ea07 --- /dev/null +++ b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/ip_relationships.json @@ -0,0 +1,72 @@ +[ + { + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "0.0.0.2", + "EntityBType": "IP", + "Relationship": "communicated-with" + }, + { + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "0.0.0.3", + "EntityBType": "IP", + "Relationship": "communicated-with" + }, + { + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "0.0.0.4", + "EntityBType": "IP", + "Relationship": "communicated-with" + }, + { + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "0.0.0.5", + "EntityBType": "IP", + "Relationship": "communicated-with" + }, + { + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "0.0.0.6", + "EntityBType": "IP", + "Relationship": "communicated-with" + }, + { + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "test1.aaa", + "EntityBType": "Domain", + "Relationship": "resolves-to" + }, + { + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "test2.bb", + "EntityBType": "Domain", + "Relationship": "resolves-to" + }, + { + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "test3.as", + "EntityBType": "Domain", + "Relationship": "resolves-to" + }, + { + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "test4.com", + "EntityBType": "Domain", + "Relationship": "resolves-to" + }, + { + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "test5.ovh", + "EntityBType": "Domain", + "Relationship": "resolves-to" + } +] \ No newline at end of file diff --git a/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/ip_response.json b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/ip_response.json new file mode 100644 index 000000000000..590b8f6917bb --- /dev/null +++ b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/ip_response.json @@ -0,0 +1,883 @@ +{ + "request_id": "test_id", + "ip": "0.0.0.1", + "size": 1000, + "start_date": "2024-05-27", + "end_date": "2024-06-25", + "sections": [ + "identity", + "comms", + "pdns", + "open_ports", + "x509", + "fingerprints", + "whois", + "summary" + ], + "usage": { + "used_queries": 261, + "remaining_queries": 49739, + "query_limit": 50000, + "foundation_api_usage": { + "used_queries": 15, + "remaining_queries": 0, + "query_limit": 0 + } + }, + "identity": { + "tags": null, + "reverse_hostnames": null, + "asn": 15133, + "as_name": "test_name", + "net_name": "test_name-data-03", + "org_name": "test_name Inc." + }, + "whois": { + "modified": "2012-06-22", + "asn": 15133, + "cidr": "0.0.0.1/24", + "as_name": "test_name", + "bgp_asn": 15133, + "bgp_asn_name": "test_name, US", + "net_name": "test_name-data-03", + "net_handle": "", + "description": "[\"data-03-EU-93-184-216-0-24\"]", + "cc": "EU", + "city": "", + "address": "", + "abuse_contact_id": "", + "about_contact_role": "", + "about_contact_person": "", + "about_contact_email": "", + "about_contact_phone": "", + "about_contact_country": "", + "about_contact_city": "", + "about_contact_address": "", + "admin_contact_id": "DS7892-RIPE", + "admin_contact_role": "", + "admin_contact_person": "Derrick Sawyer", + "admin_contact_email": "", + "admin_contact_phone": "+18123456789", + "admin_contact_country": "", + "admin_contact_city": "", + "admin_contact_address": "[\"11811 N. Tatum Blvd, Suite 3031, Phoenix, AZ 85028\"]", + "tech_contact_id": "DS7892-RIPE", + "tech_contact_role": "", + "tech_contact_person": "Derrick Sawyer", + "tech_contact_email": "", + "tech_contact_phone": "+18987654321", + "tech_contact_country": "", + "tech_contact_city": "", + "tech_contact_address": "[\"11811 N. Tatum Blvd, Suite 3031, Phoenix, AZ 85028\"]", + "org_id": "", + "org_name": "test_name Inc.", + "org_email": "", + "org_phone": "", + "org_country": "", + "org_city": "", + "org_address": "", + "mnt_by_email": "", + "mnt_lower_email": "", + "mnt_router_email": "" + }, + "communications": { + "event_count": 33264, + "peers": [ + { + "proto": 6, + "proto_text": "TCP", + "local": { + "ip": "0.0.0.1", + "min_port": 80, + "max_port": 80, + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "test_name, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name", + "children": null + } + ] + } + ], + "unique_ports": 1, + "top_services": [ + { + "service_name": "http", + "port": 80, + "proto_number": 6, + "description": "World Wide Web HTTP" + } + ] + }, + "peer": { + "ip": "0.0.0.2", + "min_port": 52049, + "max_port": 64552, + "country_codes": [ + "ZA" + ], + "as_info": [ + { + "asn": 327983, + "as_name": "Interworks-Wireless-Solutions, ZA" + } + ], + "tags": null, + "unique_ports": 3669, + "top_services": [ + { + "service_name": "", + "port": 64552, + "proto_number": 6, + "description": "" + } + ] + }, + "event_count": 6040, + "first_seen": "2024-06-04", + "last_seen": "2024-06-04" + }, + { + "proto": 6, + "proto_text": "TCP", + "local": { + "ip": "0.0.0.1", + "min_port": 80, + "max_port": 80, + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "test_name, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name", + "children": null + } + ] + } + ], + "unique_ports": 1, + "top_services": [ + { + "service_name": "http", + "port": 80, + "proto_number": 6, + "description": "World Wide Web HTTP" + } + ] + }, + "peer": { + "ip": "0.0.0.3", + "min_port": 55262, + "max_port": 60230, + "country_codes": [ + "IT" + ], + "as_info": [ + { + "asn": 206476, + "as_name": "IPTECHNOLOGY, IT" + } + ], + "tags": null, + "unique_ports": 2767, + "top_services": [ + { + "service_name": "", + "port": 60230, + "proto_number": 6, + "description": "" + } + ] + }, + "event_count": 5536, + "first_seen": "2024-06-20", + "last_seen": "2024-06-21" + }, + { + "proto": 6, + "proto_text": "TCP", + "local": { + "ip": "0.0.0.1", + "min_port": 80, + "max_port": 80, + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "test_name, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name", + "children": null + } + ] + } + ], + "unique_ports": 1, + "top_services": [ + { + "service_name": "http", + "port": 80, + "proto_number": 6, + "description": "World Wide Web HTTP" + } + ] + }, + "peer": { + "ip": "0.0.0.4", + "min_port": 49160, + "max_port": 65533, + "country_codes": [ + "SE" + ], + "as_info": [ + { + "asn": 57630, + "as_name": "AS-84GRAMS 84 Grams AB, SE" + } + ], + "tags": null, + "unique_ports": 4606, + "top_services": [ + { + "service_name": "", + "port": 65533, + "proto_number": 6, + "description": "" + } + ] + }, + "event_count": 5418, + "first_seen": "2024-06-17", + "last_seen": "2024-06-20" + }, + { + "proto": 1, + "proto_text": "ICMP", + "local": { + "ip": "0.0.0.1", + "min_port": 0, + "max_port": 0, + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "test_name, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name", + "children": null + } + ] + } + ], + "unique_ports": 1, + "top_services": [ + { + "service_name": "", + "port": 0, + "proto_number": 1, + "description": "" + } + ] + }, + "peer": { + "ip": "0.0.0.5", + "min_port": 0, + "max_port": 0, + "country_codes": [ + "BR" + ], + "as_info": [ + { + "asn": 262954, + "as_name": "VirtuaServer Informatica Ltda, BR" + } + ], + "tags": null, + "unique_ports": 1, + "top_services": [ + { + "service_name": "", + "port": 0, + "proto_number": 1, + "description": "" + } + ] + }, + "event_count": 4070, + "first_seen": "2024-05-27", + "last_seen": "2024-06-25" + }, + { + "proto": 6, + "proto_text": "TCP", + "local": { + "ip": "0.0.0.1", + "min_port": 80, + "max_port": 80, + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "test_name, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name", + "children": null + } + ] + } + ], + "unique_ports": 1, + "top_services": [ + { + "service_name": "http", + "port": 80, + "proto_number": 6, + "description": "World Wide Web HTTP" + } + ] + }, + "peer": { + "ip": "0.0.0.6", + "min_port": 56774, + "max_port": 62320, + "country_codes": [ + "CZ" + ], + "as_info": [ + { + "asn": 25512, + "as_name": "CDT-AS The Czech Republic, CZ" + } + ], + "tags": null, + "unique_ports": 1963, + "top_services": [ + { + "service_name": "", + "port": 62320, + "proto_number": 6, + "description": "" + } + ] + }, + "event_count": 3888, + "first_seen": "2024-06-08", + "last_seen": "2024-06-08" + } + ] + }, + "pdns": { + "event_count": 1338, + "pdns": [ + { + "ip": "0.0.0.1", + "domain": "test1.aaa", + "root": "test1.aaa", + "tld": "aaa", + "type": "A", + "registrar": "PDR Ltd. d/b/a test1.com", + "domain_created": "2023-03-03", + "domain_expires": "2025-03-03", + "nameservers": [ + { + "root": "test1.com.br", + "nameservers": [ + "ns1036.test1.com.br", + "ns1037.test1.com.br" + ] + } + ], + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "" + } + ], + "tags": null, + "distinct_ips": 1, + "active_days": 20, + "event_count": 78, + "first_seen": "2024-05-27", + "last_seen": "2024-06-25" + }, + { + "ip": "0.0.0.1", + "domain": "test2.bb", + "root": "test2.bb", + "tld": "bb", + "type": "A", + "registrar": "Key-Systems GmbH", + "domain_created": "2020-05-20", + "domain_expires": "2025-05-20", + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "" + } + ], + "tags": null, + "distinct_ips": 1, + "active_days": 17, + "event_count": 40, + "first_seen": "2024-05-30", + "last_seen": "2024-06-25" + }, + { + "ip": "0.0.0.1", + "domain": "test3.as", + "root": "test3.as", + "tld": "as", + "type": "A", + "registrar": "", + "domain_created": "", + "domain_expires": "", + "nameservers": null, + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "" + } + ], + "tags": null, + "distinct_ips": 1, + "active_days": 27, + "event_count": 27, + "first_seen": "2024-05-27", + "last_seen": "2024-06-25" + }, + { + "ip": "0.0.0.1", + "domain": "test4.com", + "root": "test4.com", + "tld": "com", + "type": "A", + "registrar": "RegistryGate GmbH", + "domain_created": "2010-12-11", + "domain_expires": "2024-12-11", + "nameservers": [ + { + "root": "test4.com", + "nameservers": [ + "ns5.test4.com", + "ns6.test4.com" + ] + } + ], + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "" + } + ], + "tags": null, + "distinct_ips": 1, + "active_days": 24, + "event_count": 24, + "first_seen": "2024-05-27", + "last_seen": "2024-06-24" + }, + { + "ip": "0.0.0.1", + "domain": "test5.ovh", + "root": "test5.ovh", + "tld": "ovh", + "type": "A", + "registrar": "OVH", + "domain_created": "2024-05-06", + "domain_expires": "2025-05-06", + "nameservers": [ + { + "root": "test5.ca", + "nameservers": [ + "dns10.test5.ca", + "ns10.test5.ca" + ] + } + ], + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "" + } + ], + "tags": null, + "distinct_ips": 1, + "active_days": 23, + "event_count": 23, + "first_seen": "2024-05-27", + "last_seen": "2024-06-25" + } + ] + }, + "fingerprints": { + "event_count": 5, + "fingerprints": [ + { + "ip": "0.0.0.1", + "type": "jarm", + "fingerprint": "testsignature", + "port": 443, + "first_seen": "2024-05-30", + "last_seen": "2024-06-21", + "distinct_ips": 830, + "active_days": 5, + "event_count": 5 + } + ] + }, + "open_ports": { + "event_count": 2, + "unique_ports": 2, + "open_ports": [ + { + "ip": "0.0.0.1", + "port": 443, + "protocol": 6, + "protocol_text": "TCP", + "service": "https", + "banner": "TLS/1.1 cipher:0xc013, www.example.org, www.example.org, example.net, example.edu, example.com, example.org, www.example.com, www.example.edu, www.example.net", + "banner_sha1": "test_sha1", + "first_seen": "2024-05-30", + "last_seen": "2024-06-21", + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "test_name, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name", + "children": null + } + ] + } + ], + "event_count": 5 + }, + { + "ip": "0.0.0.1", + "port": 80, + "protocol": 6, + "protocol_text": "TCP", + "service": "http", + "banner": "404 - Not Found", + "banner_sha1": "test_sha1", + "first_seen": "2024-05-30", + "last_seen": "2024-06-21", + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "test_name, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name", + "children": null + } + ] + } + ], + "event_count": 5 + } + ] + }, + "x509": { + "event_count": 5, + "x509": [ + { + "ip": "0.0.0.1", + "issuer": "CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1, O=DigiCert Inc, C=US", + "issuer_common_name": "DigiCert Global G2 TLS RSA SHA256 2020 CA1", + "common_name": "www.example.org", + "altnames": [ + "example.com", + "example.edu", + "example.net", + "example.org", + "www.example.com", + "www.example.edu", + "www.example.net", + "www.example.org" + ], + "serial": "testserial", + "subject": "CN=www.example.org, O=Internet Corporation for Assigned Names and Numbers.", + "not_after": "2025-03-01", + "not_before": "2024-01-30", + "validity_period": "397 Days", + "md5": "testmd5", + "sha1": "testsha1", + "sha256": "testsha256", + "first_seen": "2024-05-30", + "last_seen": "2024-06-21", + "port": 443, + "self_signed": false, + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15133, + "as_name": "test_name, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name", + "children": null + } + ] + } + ], + "count": 5 + } + ] + }, + "summary": { + "total": 1, + "ip": "0.0.0.1", + "start_date": "2024-05-27", + "end_date": "2024-06-25", + "geo_ip_cc": "US", + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 206, + "name": "test_name", + "children": null + } + ] + } + ], + "reverse_hostnames": null, + "bgp_asn": 15133, + "bgp_asname": "test_name, US", + "whois": { + "asn": 15133, + "as_name": "test_name", + "net_name": "test_name-data-03", + "org_name": "test_name Inc." + }, + "pdns": { + "total": 1338, + "top_pdns": [ + { + "event_count": 78, + "domain": "test1.aaa", + "first_seen": "2024-05-27", + "last_seen": "2024-06-25", + "css_color": "#a6abb7" + }, + { + "event_count": 40, + "domain": "test2.io", + "first_seen": "2024-05-30", + "last_seen": "2024-06-25", + "css_color": "#f2d561" + }, + { + "event_count": 27, + "domain": "test3.as", + "first_seen": "2024-05-27", + "last_seen": "2024-06-25", + "css_color": "#99a1ff" + }, + { + "event_count": 24, + "domain": "test4.com", + "first_seen": "2024-05-27", + "last_seen": "2024-06-24", + "css_color": "#e57ea1" + }, + { + "event_count": 23, + "domain": "test5.io", + "first_seen": "2024-05-28", + "last_seen": "2024-06-25", + "css_color": "#f2d561" + } + ] + }, + "open_ports": { + "total": 2, + "unique_ports": 2, + "top_open_ports": [ + { + "event_count": 53, + "port": 80, + "protocol": 6, + "protocol_text": "TCP", + "service": "http", + "inferred_service_name": null, + "first_seen": "2024-05-27", + "last_seen": "2024-06-25", + "css_color": "#a6abb7" + }, + { + "event_count": 43, + "port": 443, + "protocol": 6, + "protocol_text": "TCP", + "service": "https", + "inferred_service_name": null, + "first_seen": "2024-05-27", + "last_seen": "2024-06-25", + "css_color": "#99a1ff" + } + ] + }, + "certs": { + "top_certs": [ + { + "issuer": "CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1, O=DigiCert Inc, C=US", + "issuer_common_name": "DigiCert Global G2 TLS RSA SHA256 2020 CA1", + "common_name": "www.example.org", + "subject": "CN=www.example.org, O=Internet Corporation for Assigned Names and Numbers.", + "port": 443, + "first_seen": "2024-05-30", + "last_seen": "2024-06-21", + "self_signed": false, + "not_before": "2024-01-30", + "not_after": "2025-03-01", + "valid_days": 397, + "md5": "testmd5", + "sha1": "testsha1", + "sha256": "testsha256", + "css_color": "#b382d9" + } + ] + }, + "tag_timeline": { + "data": [ + { + "tag": { + "id": 176, + "name": "cdn", + "description": "The CDN tag characterizes IP addresses associated with Content Delivery Networks (CDNs).", + "parent_ids": null, + "css_color": "#8A532C", + "parents": null + }, + "first_seen": "2024-05-27", + "last_seen": "2024-06-25" + } + ] + }, + "insights": { + "overall_rating": "suspicious", + "total": 8, + "insights": [ + { + "rating": "no_rating", + "message": "x509 subject \"CN=www.example.org, O=Internet Corporation for Assigned Names and Numbers." + } + ] + }, + "fingerprints": { + "top_fingerprints": [ + { + "type": "jarm", + "signature": "testsignature", + "port": 443, + "first_seen": "2024-05-30", + "last_seen": "2024-06-21", + "count": 5 + } + ] + } + } +} \ No newline at end of file diff --git a/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_api_usage_hr.md b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_api_usage_hr.md new file mode 100644 index 000000000000..78890b2d9c71 --- /dev/null +++ b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_api_usage_hr.md @@ -0,0 +1,4 @@ +### API Usage +|Used Queries|Remaining Queries|Query Limit|Foundation Used Queries|Foundation Remaining Queries|Foundation Query Limit| +|---|---|---|---|---|---| +| 261 | 49739 | 50000 | 15 | 0 | 0 | diff --git a/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_api_usage_output.json b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_api_usage_output.json new file mode 100644 index 000000000000..9d521fd2dc76 --- /dev/null +++ b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_api_usage_output.json @@ -0,0 +1,11 @@ +{ + "command_name": "scout-api-usage", + "used_queries": 261, + "remaining_queries": 49739, + "query_limit": 50000, + "foundation_api_usage": { + "used_queries": 15, + "remaining_queries": 0, + "query_limit": 0 + } +} \ No newline at end of file diff --git a/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_api_usage_response.json b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_api_usage_response.json new file mode 100644 index 000000000000..a06796006a31 --- /dev/null +++ b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_api_usage_response.json @@ -0,0 +1,10 @@ +{ + "used_queries": 261, + "remaining_queries": 49739, + "query_limit": 50000, + "foundation_api_usage": { + "used_queries": 15, + "remaining_queries": 0, + "query_limit": 0 + } +} \ No newline at end of file diff --git a/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_indicator_search_entry_context.json b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_indicator_search_entry_context.json new file mode 100644 index 000000000000..ac56eb918957 --- /dev/null +++ b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_indicator_search_entry_context.json @@ -0,0 +1,204 @@ +{ + "IP(val.Address && val.Address == obj.Address)": [ + { + "Address": "0.0.0.1", + "ASN": 15169, + "ASOwner": "DUMMY", + "Region": "US", + "Port": "53,443", + "UpdatedDate": "2024-06-27", + "Hostname": "dns.dummy", + "Geo": { + "Country": "US" + }, + "Organization": { + "Name": "Dummy LLC" + }, + "Tags": "cdn: (cloudflare)", + "Relationships": [ + { + "Relationship": "communicated-with", + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "0.0.0.2", + "EntityBType": "IP" + }, + { + "Relationship": "communicated-with", + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "0.0.0.3", + "EntityBType": "IP" + }, + { + "Relationship": "resolves-to", + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "dns.dummy", + "EntityBType": "Domain" + }, + { + "Relationship": "resolves-to", + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "dns.dummy.com", + "EntityBType": "Domain" + } + ] + } + ], + "DBotScore(val.Indicator && val.Indicator == obj.Indicator && val.Vendor == obj.Vendor && val.Type == obj.Type)": [ + { + "Indicator": "0.0.0.1", + "Type": "ip", + "Vendor": "Team Cymru Scout", + "Score": 0, + "Reliability": "B - Usually reliable" + } + ], + "TeamCymruScout.IP(val.ip && val.ip == obj.ip)": { + "ip": "0.0.0.1", + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15169, + "as_name": "DUMMY, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 210, + "name": "cloudflare" + } + ] + } + ], + "event_count": 164273621518, + "summary": { + "last_seen": "2024-06-27", + "whois": { + "asn": 15169, + "as_name": "DUMMY", + "net_name": "DUMMY", + "org_name": "Dummy LLC" + }, + "open_ports": [ + { + "ip": "0.0.0.1", + "port": 53, + "protocol": 17, + "protocol_text": "UDP", + "service": "domain", + "event_count": 296728 + }, + { + "ip": "0.0.0.1", + "port": 443, + "protocol": 6, + "protocol_text": "TCP", + "service": "https", + "event_count": 257 + } + ], + "pdns": [ + { + "ip": "0.0.0.1", + "domain": "dns.dummy", + "event_count": 53408038 + }, + { + "ip": "0.0.0.1", + "domain": "dns.dummy.com", + "event_count": 2791811 + } + ], + "top_peers": [ + { + "ip": "0.0.0.2", + "event_count": 2784287448 + }, + { + "ip": "0.0.0.3", + "event_count": 1469283767 + } + ], + "comms_total": 166356036813, + "service_counts": [ + { + "proto": 17, + "proto_text": "", + "port": 53, + "event_count": 141248029324, + "service": { + "service_name": "domain", + "port": 53, + "proto_number": 17, + "description": "Domain Name Server" + } + }, + { + "proto": 17, + "proto_text": "", + "port": 443, + "event_count": 7214447854, + "service": { + "service_name": "https", + "port": 443, + "proto_number": 17, + "description": "http protocol over TLS/SSL" + } + }, + { + "proto": 6, + "proto_text": "", + "port": 443, + "event_count": 4130470538, + "service": { + "service_name": "https", + "port": 443, + "proto_number": 6, + "description": "http protocol over TLS/SSL" + } + } + ], + "fingerprints": [ + { + "ip": "0.0.0.1", + "type": "ja3s", + "signature": "00000000000000000000000000000001", + "event_count": 144337 + }, + { + "ip": "0.0.0.1", + "type": "ja3", + "signature": "00000000000000000000000000000001", + "event_count": 40708 + } + ], + "certs": [ + { + "ip": "0.0.0.1", + "issuer": "CN=WR2, O=Dummy Trust Services, C=US", + "issuer_common_name": "WR2", + "common_name": "dns.dummy", + "port": 853, + "event_count": 418 + }, + { + "ip": "0.0.0.1", + "issuer": "CN=WR2, O=Dummy Trust Services, C=US", + "issuer_common_name": "WR2", + "common_name": "dns.dummy", + "port": 443, + "event_count": 372 + } + ] + } + } +} \ No newline at end of file diff --git a/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_indicator_search_hr.md b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_indicator_search_hr.md new file mode 100644 index 000000000000..8996dfb76683 --- /dev/null +++ b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_indicator_search_hr.md @@ -0,0 +1,42 @@ +### Summary Information for the given indicator: [0.0.0.1](https://scout.cymru.com/scout/details?query=0.0.0.1) +|Country Code(S)|Whois|Event Count|Tags|Last Seen| +|---|---|---|---|---| +| US | ***asn***: 15169
***as_name***: DUMMY
***net_name***: DUMMY
***org_name***: Dummy LLC | 164273621518 | **-** ***id***: 176
***name***: cdn
**children**:
**-** ***id***: 210
***name***: cloudflare | 2024-06-27 | + +### PDNS Information +|Domain|Event Count|IP| +|---|---|---| +| dns.dummy | 53408038 | 0.0.0.1 | +| dns.dummy.com | 2791811 | 0.0.0.1 | + +### Open Ports Information +|Event Count|IP|Port|Protocol|Protocol Text|Service| +|---|---|---|---|---|---| +| 296728 | 0.0.0.1 | 53 | 17 | UDP | domain | +| 257 | 0.0.0.1 | 443 | 6 | TCP | https | + +### Top Peers Information +|Source IP|Event Count|IP| +|---|---|---| +| 0.0.0.1 | 2784287448 | 0.0.0.2 | +| 0.0.0.1 | 1469283767 | 0.0.0.3 | + +### Service Counts Information +|Source IP|Event Count|Port|Proto|Service| +|---|---|---|---|---| +| 0.0.0.1 | 141248029324 | 53 | 17 | service_name: domain
port: 53
proto_number: 17
description: Domain Name Server | +| 0.0.0.1 | 7214447854 | 443 | 17 | service_name: https
port: 443
proto_number: 17
description: http protocol over TLS/SSL | +| 0.0.0.1 | 4130470538 | 443 | 6 | service_name: https
port: 443
proto_number: 6
description: http protocol over TLS/SSL | + +### Fingerprints Information +|Event Count|IP|Signature|Type| +|---|---|---|---| +| 144337 | 0.0.0.1 | 00000000000000000000000000000001 | ja3s | +| 40708 | 0.0.0.1 | 00000000000000000000000000000001 | ja3 | + +### Certs Information +|Common Name|Event Count|IP|Issuer|Issuer Common Name|Port| +|---|---|---|---|---|---| +| dns.dummy | 418 | 0.0.0.1 | CN=WR2, O=Dummy Trust Services, C=US | WR2 | 853 | +| dns.dummy | 372 | 0.0.0.1 | CN=WR2, O=Dummy Trust Services, C=US | WR2 | 443 | + diff --git a/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_indicator_search_output.json b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_indicator_search_output.json new file mode 100644 index 000000000000..520ab15d16f2 --- /dev/null +++ b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_indicator_search_output.json @@ -0,0 +1,222 @@ +{ + "query_usage": { + "request_id": "00000000-0000-0000-0000-000000000001", + "total": 1, + "query": "0.0.0.1", + "size": 5000, + "start_date": "2024-05-28", + "end_date": "2024-06-26", + "used_queries": 261, + "remaining_queries": 49739, + "query_limit": 50000, + "foundation_api_usage": { + "used_queries": 15, + "remaining_queries": 0, + "query_limit": 0 + } + }, + "entry_context": { + "IP(val.Address && val.Address == obj.Address)": [ + { + "Address": "0.0.0.1", + "ASN": 15169, + "ASOwner": "DUMMY", + "Region": "US", + "Port": "53,443", + "UpdatedDate": "2024-06-27", + "Hostname": "dns.dummy", + "Geo": { + "Country": "US" + }, + "Organization": { + "Name": "Dummy LLC" + }, + "Tags": "cdn: (cloudflare)", + "Relationships": [ + { + "Relationship": "communicated-with", + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "0.0.0.2", + "EntityBType": "IP" + }, + { + "Relationship": "communicated-with", + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "0.0.0.3", + "EntityBType": "IP" + }, + { + "Relationship": "resolves-to", + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "dns.dummy", + "EntityBType": "Domain" + }, + { + "Relationship": "resolves-to", + "EntityA": "0.0.0.1", + "EntityAType": "IP", + "EntityB": "dns.dummy.com", + "EntityBType": "Domain" + } + ] + } + ], + "DBotScore(val.Indicator && val.Indicator == obj.Indicator && val.Vendor == obj.Vendor && val.Type == obj.Type)": [ + { + "Indicator": "0.0.0.1", + "Type": "ip", + "Vendor": "Team Cymru Scout", + "Score": 0, + "Reliability": "B - Usually reliable" + } + ], + "TeamCymruScout.IP(val.ip && val.ip == obj.ip)": { + "ip": "0.0.0.1", + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15169, + "as_name": "DUMMY, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 210, + "name": "cloudflare" + } + ] + } + ], + "event_count": 164273621518, + "summary": { + "last_seen": "2024-06-27", + "whois": { + "asn": 15169, + "as_name": "DUMMY", + "net_name": "DUMMY", + "org_name": "Dummy LLC" + }, + "open_ports": [ + { + "ip": "0.0.0.1", + "port": 53, + "protocol": 17, + "protocol_text": "UDP", + "service": "domain", + "event_count": 296728 + }, + { + "ip": "0.0.0.1", + "port": 443, + "protocol": 6, + "protocol_text": "TCP", + "service": "https", + "event_count": 257 + } + ], + "pdns": [ + { + "ip": "0.0.0.1", + "domain": "dns.dummy", + "event_count": 53408038 + }, + { + "ip": "0.0.0.1", + "domain": "dns.dummy.com", + "event_count": 2791811 + } + ], + "top_peers": [ + { + "ip": "0.0.0.2", + "event_count": 2784287448 + }, + { + "ip": "0.0.0.3", + "event_count": 1469283767 + } + ], + "comms_total": 166356036813, + "service_counts": [ + { + "proto": 17, + "proto_text": "", + "port": 53, + "event_count": 141248029324, + "service": { + "service_name": "domain", + "port": 53, + "proto_number": 17, + "description": "Domain Name Server" + } + }, + { + "proto": 17, + "proto_text": "", + "port": 443, + "event_count": 7214447854, + "service": { + "service_name": "https", + "port": 443, + "proto_number": 17, + "description": "http protocol over TLS/SSL" + } + }, + { + "proto": 6, + "proto_text": "", + "port": 443, + "event_count": 4130470538, + "service": { + "service_name": "https", + "port": 443, + "proto_number": 6, + "description": "http protocol over TLS/SSL" + } + } + ], + "fingerprints": [ + { + "ip": "0.0.0.1", + "type": "ja3s", + "signature": "00000000000000000000000000000001", + "event_count": 144337 + }, + { + "ip": "0.0.0.1", + "type": "ja3", + "signature": "00000000000000000000000000000001", + "event_count": 40708 + } + ], + "certs": [ + { + "ip": "0.0.0.1", + "issuer": "CN=WR2, O=Dummy Trust Services, C=US", + "issuer_common_name": "WR2", + "common_name": "dns.dummy", + "port": 853, + "event_count": 418 + }, + { + "ip": "0.0.0.1", + "issuer": "CN=WR2, O=Dummy Trust Services, C=US", + "issuer_common_name": "WR2", + "common_name": "dns.dummy", + "port": 443, + "event_count": 372 + } + ] + } + } + } +} \ No newline at end of file diff --git a/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_indicator_search_response.json b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_indicator_search_response.json new file mode 100644 index 000000000000..d9fe2385f4b4 --- /dev/null +++ b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_indicator_search_response.json @@ -0,0 +1,166 @@ +{ + "request_id": "00000000-0000-0000-0000-000000000001", + "total": 1, + "query": "0.0.0.1", + "size": 5000, + "start_date": "2024-05-28", + "end_date": "2024-06-26", + "usage": { + "used_queries": 261, + "remaining_queries": 49739, + "query_limit": 50000, + "foundation_api_usage": { + "used_queries": 15, + "remaining_queries": 0, + "query_limit": 0 + } + }, + "ips": [ + { + "ip": "0.0.0.1", + "country_codes": [ + "US" + ], + "as_info": [ + { + "asn": 15169, + "as_name": "DUMMY, US" + } + ], + "tags": [ + { + "id": 176, + "name": "cdn", + "children": [ + { + "id": 210, + "name": "cloudflare", + "children": null + } + ] + } + ], + "event_count": 164273621518, + "summary": { + "last_seen": "2024-06-27", + "whois": { + "asn": 15169, + "as_name": "DUMMY", + "net_name": "DUMMY", + "org_name": "Dummy LLC" + }, + "open_ports": [ + { + "ip": "0.0.0.1", + "port": 53, + "protocol": 17, + "protocol_text": "UDP", + "service": "domain", + "event_count": 296728 + }, + { + "ip": "0.0.0.1", + "port": 443, + "protocol": 6, + "protocol_text": "TCP", + "service": "https", + "event_count": 257 + } + ], + "pdns": [ + { + "ip": "0.0.0.1", + "domain": "dns.dummy", + "event_count": 53408038 + }, + { + "ip": "0.0.0.1", + "domain": "dns.dummy.com", + "event_count": 2791811 + } + ], + "top_peers": [ + { + "ip": "0.0.0.2", + "event_count": 2784287448 + }, + { + "ip": "0.0.0.3", + "event_count": 1469283767 + } + ], + "comms_total": 166356036813, + "service_counts": [ + { + "proto": 17, + "proto_text": "", + "port": 53, + "event_count": 141248029324, + "service": { + "service_name": "domain", + "port": 53, + "proto_number": 17, + "description": "Domain Name Server" + } + }, + { + "proto": 17, + "proto_text": "", + "port": 443, + "event_count": 7214447854, + "service": { + "service_name": "https", + "port": 443, + "proto_number": 17, + "description": "http protocol over TLS/SSL" + } + }, + { + "proto": 6, + "proto_text": "", + "port": 443, + "event_count": 4130470538, + "service": { + "service_name": "https", + "port": 443, + "proto_number": 6, + "description": "http protocol over TLS/SSL" + } + } + ], + "fingerprints": [ + { + "ip": "0.0.0.1", + "type": "ja3s", + "signature": "00000000000000000000000000000001", + "event_count": 144337 + }, + { + "ip": "0.0.0.1", + "type": "ja3", + "signature": "00000000000000000000000000000001", + "event_count": 40708 + } + ], + "certs": [ + { + "ip": "0.0.0.1", + "issuer": "CN=WR2, O=Dummy Trust Services, C=US", + "issuer_common_name": "WR2", + "common_name": "dns.dummy", + "port": 853, + "event_count": 418 + }, + { + "ip": "0.0.0.1", + "issuer": "CN=WR2, O=Dummy Trust Services, C=US", + "issuer_common_name": "WR2", + "common_name": "dns.dummy", + "port": 443, + "event_count": 372 + } + ] + } + } + ] +} \ No newline at end of file diff --git a/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_ip_list_hr.md b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_ip_list_hr.md new file mode 100644 index 000000000000..b91da0ee3079 --- /dev/null +++ b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_ip_list_hr.md @@ -0,0 +1,4 @@ +### Summary Information for the given Suspicious IP: [0.0.0.1](https://scout.cymru.com/scout/details?query=0.0.0.1) +|Country Code|AS Info|Insights|Tags| +|---|---|---|---| +| US | **-** ***asn***: 13335
***as_name***: NET, US | ***overall_rating***: suspicious
**insights**:
**-** ***rating***: suspicious
***message***: Test data Insight Message.
**-** ***rating***: suspicious
***message***: 0.0.0.1 has been identified as a "cdn", indicating private and reserved addresses defined by RFC 1918, RFC 5735, and RFC 6598, as well as net that have not been allocated to a Regional Internet Registry (RIR) by the Internet Assigned Numbers Authority. | **-** ***id***: 81
***name***: cdn
**children**:
**-** ***id***: 210
***name***: cloudflare | diff --git a/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_ip_list_output.json b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_ip_list_output.json new file mode 100644 index 000000000000..f94f0c67405a --- /dev/null +++ b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_ip_list_output.json @@ -0,0 +1,78 @@ +{ + "query_usage": { + "request_id": "00000000-0000-0000-0000-000000000001", + "ips": [ + "0.0.0.1" + ], + "used_queries": 261, + "remaining_queries": 49739, + "query_limit": 50000, + "foundation_api_usage": { + "used_queries": 15, + "remaining_queries": 0, + "query_limit": 0 + } + }, + "entry_context": { + "IP(val.Address && val.Address == obj.Address)": [ + { + "Address": "0.0.0.1", + "ASN": 13335, + "ASOwner": "NET, US", + "Region": "US", + "Description": "0.0.0.1 has been identified as a \"cdn\", indicating private and reserved addresses defined by RFC 1918, RFC 5735, and RFC 6598, as well as net that have not been allocated to a Regional Internet Registry (RIR) by the Internet Assigned Numbers Authority.", + "Geo": { + "Country": "US" + }, + "Organization": { + "Name": "NET, US" + }, + "Tags": "cdn: (cloudflare)" + } + ], + "DBotScore(val.Indicator && val.Indicator == obj.Indicator && val.Vendor == obj.Vendor && val.Type == obj.Type)": [ + { + "Indicator": "0.0.0.1", + "Type": "ip", + "Vendor": "Team Cymru Scout", + "Score": 2, + "Reliability": "B - Usually reliable" + } + ], + "TeamCymruScout.IP(val.ip && val.ip == obj.ip)": { + "ip": "0.0.0.1", + "country_code": "US", + "as_info": [ + { + "asn": 13335, + "as_name": "NET, US" + } + ], + "insights": { + "overall_rating": "suspicious", + "insights": [ + { + "rating": "suspicious", + "message": "Test data Insight Message." + }, + { + "rating": "suspicious", + "message": "0.0.0.1 has been identified as a \"cdn\", indicating private and reserved addresses defined by RFC 1918, RFC 5735, and RFC 6598, as well as net that have not been allocated to a Regional Internet Registry (RIR) by the Internet Assigned Numbers Authority." + } + ] + }, + "tags": [ + { + "id": 81, + "name": "cdn", + "children": [ + { + "id": 210, + "name": "cloudflare" + } + ] + } + ] + } + } +} \ No newline at end of file diff --git a/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_ip_list_response.json b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_ip_list_response.json new file mode 100644 index 000000000000..a74769779029 --- /dev/null +++ b/Packs/TeamCymru/Integrations/TeamCymruScout/test_data/scout_ip_list_response.json @@ -0,0 +1,53 @@ +{ + "request_id": "00000000-0000-0000-0000-000000000001", + "ips": [ + "0.0.0.1" + ], + "data": [ + { + "ip": "0.0.0.1", + "country_code": "US", + "as_info": [ + { + "asn": 13335, + "as_name": "NET, US" + } + ], + "insights": { + "overall_rating": "suspicious", + "insights": [ + { + "rating": "suspicious", + "message": "Test data Insight Message." + }, + { + "rating": "suspicious", + "message": "0.0.0.1 has been identified as a \"cdn\", indicating private and reserved addresses defined by RFC 1918, RFC 5735, and RFC 6598, as well as net that have not been allocated to a Regional Internet Registry (RIR) by the Internet Assigned Numbers Authority." + } + ] + }, + "tags": [ + { + "id": 81, + "name": "cdn", + "children": [ + { + "id": 210, + "name": "cloudflare" + } + ] + } + ] + } + ], + "usage": { + "used_queries": 261, + "remaining_queries": 49739, + "query_limit": 50000, + "foundation_api_usage": { + "used_queries": 15, + "remaining_queries": 0, + "query_limit": 0 + } + } +} \ No newline at end of file diff --git a/Packs/TeamCymru/README.md b/Packs/TeamCymru/README.md index bc8e270fee9e..83bca9ce8e7a 100644 --- a/Packs/TeamCymru/README.md +++ b/Packs/TeamCymru/README.md @@ -1,6 +1,22 @@ -Note: Support for this Pack was moved to Partner starting July 29, 2024. In case of any issues arise, please contact the Partner directly at . +Note: Support for this pack was moved to Partner starting July 29, 2024. In case any issues arise, contact the Partner directly at . + +## Overview Team Cymru provides various service options dedicated to mapping IP numbers to BGP prefixes and ASNs. Each of the services is based on the same BGP feeds from 50+ BGP peers and is updated at 4-hour intervals. ## What does this pack do? -This pack checks the reputation of specified IP addresses. + +- This pack checks the reputation of specified IP addresses. + +## The Team Cymru Scout Integration + +The Team Cymru Scout integration provides comprehensive insights on the IP addresses and domains for threat investigations. +It integrates with the API of Team Cymru Scout and allows immediate access to information related to single IPs and domains. + +### Key Features + +- Explore the communication data to identify commonalities between IP addresses, identify compromised hosts, and uncover other indications of an attack. +- Access to NetFlow communications, Whois information, PDNS, X509 certificates, and fingerprinting details. +- Supports both IPv4 and IPv6 address queries. +- Provides real-time threat intelligence and helps in identifying and mitigating potential security threats. +- Offers extensive documentation and support resources to assist with setup, configuration, and troubleshooting. diff --git a/Packs/TeamCymru/ReleaseNotes/2_0_0.md b/Packs/TeamCymru/ReleaseNotes/2_0_0.md new file mode 100644 index 000000000000..14ca2f1d8f05 --- /dev/null +++ b/Packs/TeamCymru/ReleaseNotes/2_0_0.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### New: Team Cymru Scout + +New: The Team Cymru Scout integration enables getting immediate insight on IP addresses and domains for threat investigations. diff --git a/Packs/TeamCymru/pack_metadata.json b/Packs/TeamCymru/pack_metadata.json index b31fdf0104b0..61bd14a89b4a 100644 --- a/Packs/TeamCymru/pack_metadata.json +++ b/Packs/TeamCymru/pack_metadata.json @@ -1,8 +1,8 @@ { "name": "Team Cymru", - "description": "Team Cymru is an internet security firm that offers research services making the internet a more secure place.", + "description": "Team Cymru integration provides comprehensive insights on the IP addresses and domains for threat investigations.", "support": "partner", - "currentVersion": "1.0.24", + "currentVersion": "2.0.0", "author": "Team Cymru", "url": "", "email": "support@cymru.com", @@ -10,12 +10,39 @@ "Data Enrichment & Threat Intelligence" ], "tags": [ + "Network", + "Security", + "Threat Intelligence", + "Security Analytics", + "Relationship", + "Attack", + "Breach", + "Forensics", + "Incident Handling", + "Incident Response", + "Malware", "Getting Started", "Free Enricher", "Plug & Enrich" ], - "useCases": [], - "keywords": [], + "useCases": [ + "Network Security", + "Threat Intelligence Management", + "Hunting", + "Phishing", + "Ransomware" + ], + "keywords": [ + "Cymru", + "Scout", + "IOC", + "real-time", + "Network Security", + "Intelligence", + "Enrichment", + "whois", + "Threat Intelligence" + ], "marketplaces": [ "xsoar", "marketplacev2" From 97ff7c5574faf9a7a1ca499644ff53bfff6f96bc Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Sun, 11 Aug 2024 22:03:02 +0300 Subject: [PATCH 14/14] TEZ-5540: (#35754) (#35833) * TEZ-5540: XSOAR: Analytical attributes of new pulled anomaly are not getting sync in existing case in XSOAR. * TEZ-5540: XSOAR: Analytical attributes of new pulled anomaly are not getting sync in existing case in XSOAR. * TEZ-5540: XSOAR: Analytical attributes of new pulled anomaly are not getting sync in existing case in XSOAR. * TEZ-5540: XSOAR: Analytical attributes of new pulled anomaly are not getting sync in existing case in XSOAR. * TEZ-5540: XSOAR: Analytical attributes of new pulled anomaly are not getting sync in existing case in XSOAR. * TEZ-5540: XSOAR: Analytical attributes of new pulled anomaly are not getting sync in existing case in XSOAR. * TEZ-5540: XSOAR: Analytical attributes of new pulled anomaly are not getting sync in existing case in XSOAR. * TEZ-5540: XSOAR: Analytical attributes of new pulled anomaly are not getting sync in existing case in XSOAR. --------- Co-authored-by: Kiran Gore <94684778+kenjjolhjshiughiuhugh@users.noreply.github.com> Co-authored-by: gra-xsoar --- Packs/Gurucul/CONTRIBUTORS.json | 4 ++ .../Integrations/GuruculGRA/GuruculGRA.py | 15 +++- .../Integrations/GuruculGRA/GuruculGRA.yml | 4 +- .../Gurucul/Integrations/GuruculGRA/README.md | 17 +++++ .../Integrations/GuruculGRA/command_examples | 3 +- Packs/Gurucul/ReleaseNotes/2_0_5.md | 25 +++++++ .../GRAAnomaliesDisplay.py | 69 +++++++++---------- .../GRAAnomaliesDisplay.yml | 2 +- .../graanalyticalfeaturedisplay.py | 37 +++++----- .../graanalyticalfeaturedisplay.yml | 4 +- .../graanalyticalfeaturedisplay_test.py | 15 ++++ .../graupdatecasestatus.py | 8 ++- .../graupdatecasestatus.yml | 8 +-- .../graupdatecasestatus_test.py | 4 +- Packs/Gurucul/pack_metadata.json | 2 +- 15 files changed, 147 insertions(+), 70 deletions(-) create mode 100644 Packs/Gurucul/CONTRIBUTORS.json create mode 100644 Packs/Gurucul/ReleaseNotes/2_0_5.md diff --git a/Packs/Gurucul/CONTRIBUTORS.json b/Packs/Gurucul/CONTRIBUTORS.json new file mode 100644 index 000000000000..2b8759c9e4e9 --- /dev/null +++ b/Packs/Gurucul/CONTRIBUTORS.json @@ -0,0 +1,4 @@ +[ + "Jignesh Patil", + "Kiran Gore" +] \ No newline at end of file diff --git a/Packs/Gurucul/Integrations/GuruculGRA/GuruculGRA.py b/Packs/Gurucul/Integrations/GuruculGRA/GuruculGRA.py index 9582ff855a1e..38e1993ee450 100644 --- a/Packs/Gurucul/Integrations/GuruculGRA/GuruculGRA.py +++ b/Packs/Gurucul/Integrations/GuruculGRA/GuruculGRA.py @@ -196,8 +196,19 @@ def main() -> None: proxy=proxy) if demisto.command() == 'test-module': - result = test_module_command(client) - return_results(result) + try: + result = test_module_command(client) + return_results(result) + except Exception: + return_error('Gurucul services are currently not available. Please contact the administrator for further ' + 'assistance.') + + elif demisto.command() == 'gra-validate-api': + try: + result = client.validate_api_key() + return_results(result) + except Exception: + return_error('Error in service') elif demisto.command() == 'fetch-incidents': diff --git a/Packs/Gurucul/Integrations/GuruculGRA/GuruculGRA.yml b/Packs/Gurucul/Integrations/GuruculGRA/GuruculGRA.yml index 563c9cc2458d..83f8cb0a79b3 100644 --- a/Packs/Gurucul/Integrations/GuruculGRA/GuruculGRA.yml +++ b/Packs/Gurucul/Integrations/GuruculGRA/GuruculGRA.yml @@ -978,7 +978,9 @@ script: description: Current status of anomaly. type: String description: Retrieve anomalies for specified case id. - dockerimage: demisto/python3:3.10.14.95956 + - name: gra-validate-api + description: Verifies the Gurucul platform's operational status by assessing system health, reviewing logs, and checking key performance indicators for any errors. + dockerimage: demisto/python3:3.11.9.106008 isfetch: true subtype: python3 fromversion: 5.0.0 diff --git a/Packs/Gurucul/Integrations/GuruculGRA/README.md b/Packs/Gurucul/Integrations/GuruculGRA/README.md index 8c26d2ef1dc2..e023e266489c 100644 --- a/Packs/Gurucul/Integrations/GuruculGRA/README.md +++ b/Packs/Gurucul/Integrations/GuruculGRA/README.md @@ -1134,5 +1134,22 @@ Retrieve anomalies for specified case id from GRA and update in XSOAR. ``` #### Human Readable Output +### gra-validate-api +*** +Verifies the Gurucul platform's operational status by assessing system health, reviewing logs, and checking key performance indicators for any errors. + +#### Base Command + +`gra-validate-api` + +#### Command Example +```!gra-validate-api``` + +#### Context Example +``` +ok +``` + +#### Human Readable Output diff --git a/Packs/Gurucul/Integrations/GuruculGRA/command_examples b/Packs/Gurucul/Integrations/GuruculGRA/command_examples index 31a5d290006a..fc3053e03d77 100644 --- a/Packs/Gurucul/Integrations/GuruculGRA/command_examples +++ b/Packs/Gurucul/Integrations/GuruculGRA/command_examples @@ -19,4 +19,5 @@ !gra-case-action-anomaly action=modelReviewCaseAnomaly caseId=5 anomalyNames=anomalyName1,anomalyName2 subOption="Tuning Required" caseComment="This is Completed" !gra-case-action-anomaly action=riskAcceptCaseAnomaly caseId=6 anomalyNames=anomalyName subOption="Correct Detection" caseComment=Done riskAcceptDate=2021-05-12 !gra-investigate-anomaly-summary modelName=ModelName -!gra-analytical-features-entity-value modelName=ModelName entityValue=EntityValue \ No newline at end of file +!gra-analytical-features-entity-value modelName=ModelName entityValue=EntityValue +!gra-validate-api \ No newline at end of file diff --git a/Packs/Gurucul/ReleaseNotes/2_0_5.md b/Packs/Gurucul/ReleaseNotes/2_0_5.md new file mode 100644 index 000000000000..5d9b91fbe413 --- /dev/null +++ b/Packs/Gurucul/ReleaseNotes/2_0_5.md @@ -0,0 +1,25 @@ + +#### Integrations + +##### Gurucul-GRA + +- Updated the Docker image to: *demisto/python3:3.11.9.106008*. +- **Bug Fixes**: + - Resolved an issue with incident closing. + - Fixed a problem related to fetching the analytical attribute. + + +#### Scripts + +##### GRAAnalyticalFeatureDisplay + +- Updated the Docker image to: *demisto/python3:3.11.9.106008*. + +##### GRAAnomaliesDisplay + +- Updated the Docker image to: *demisto/python3:3.11.9.106008*. + +##### GRAUpdateCaseStatus + +- Updated the Docker image to: *demisto/python3:3.11.9.106008*. + diff --git a/Packs/Gurucul/Scripts/GRAAnomaliesDisplay/GRAAnomaliesDisplay.py b/Packs/Gurucul/Scripts/GRAAnomaliesDisplay/GRAAnomaliesDisplay.py index 4b4eb6b33646..6ffbf3f1c255 100644 --- a/Packs/Gurucul/Scripts/GRAAnomaliesDisplay/GRAAnomaliesDisplay.py +++ b/Packs/Gurucul/Scripts/GRAAnomaliesDisplay/GRAAnomaliesDisplay.py @@ -11,44 +11,43 @@ def getAnomaliesByCaseId(): caseId = graCaseId.split('-')[-1] if caseId != '': # make rest api call - res = execute_command('gra-cases-anomaly', {'caseId': caseId}) + res = execute_command('gra-cases-anomaly', {'caseId': caseId, 'using': incident['sourceInstance']}) anomaliesChangedCount = 0 if res is not None: - for newAnomalies in res: - if newAnomalies is not None: - updatedAnomalies = [] - for anomaly in newAnomalies: - newAnomaly = { - 'anomalyname': anomaly['anomalyName'], - 'riskaccepteddate': anomaly['riskAcceptedDate'], - 'resourcename': anomaly['resourceName'], - 'riskscore': anomaly['riskScore'], - 'assignee': anomaly['assignee'], - 'assigneetype': anomaly['assigneeType'], - 'status': anomaly['status'], - } - updatedAnomalies.append(newAnomaly) - - for oldAnomaly in oldAnomalies: - if oldAnomaly['anomalyname'] == anomaly['anomalyName'] and \ - (oldAnomaly['status'] != anomaly['status'] or oldAnomaly['assignee'] != anomaly['assignee']): - anomaliesChangedCount += 1 - break - - if anomaliesChangedCount == 0 and len(oldAnomalies) != len(updatedAnomalies): - anomaliesChangedCount = len(updatedAnomalies) - len(oldAnomalies) - - if anomaliesChangedCount != 0: - execute_command("setIncident", {"id": incident['id'], "gracaseanomalydetails": updatedAnomalies}) - if anomaliesChangedCount == 1: - return_results('There is 1 anomaly update identified for this case. ' - 'Refresh Analytical Features for updated attributes list.') - else: - return_results(f'There are {anomaliesChangedCount} anomaly updates identified for this ' - f'case. Refresh Analytical Features for updated attributes list.') - else: - return_results('There are no anomaly changes identified for this case.') + updatedAnomalies = [] + for anomaly in res: + if anomaly is not None: + newAnomaly = { + 'anomalyname': anomaly['anomalyName'], + 'riskaccepteddate': anomaly['riskAcceptedDate'], + 'resourcename': anomaly['resourceName'], + 'riskscore': anomaly['riskScore'], + 'assignee': anomaly['assignee'], + 'assigneetype': anomaly['assigneeType'], + 'status': anomaly['status'], + } + updatedAnomalies.append(newAnomaly) + + for oldAnomaly in oldAnomalies: + if oldAnomaly['anomalyname'] == anomaly['anomalyName'] and \ + (oldAnomaly['status'] != anomaly['status'] or oldAnomaly['assignee'] != anomaly['assignee']): + anomaliesChangedCount += 1 + break + + if anomaliesChangedCount == 0 and len(oldAnomalies) != len(updatedAnomalies): + anomaliesChangedCount = len(updatedAnomalies) - len(oldAnomalies) + + if anomaliesChangedCount != 0: + execute_command("setIncident", {"id": incident['id'], "gracaseanomalydetails": updatedAnomalies}) + if anomaliesChangedCount == 1: + return_results('There is 1 anomaly update identified for this case. ' + 'Refresh Analytical Features for updated attributes list.') + else: + return_results(f'There are {anomaliesChangedCount} anomaly updates identified for this ' + f'case. Refresh Analytical Features for updated attributes list.') + else: + return_results('There are no anomaly changes identified for this case.') def main(): diff --git a/Packs/Gurucul/Scripts/GRAAnomaliesDisplay/GRAAnomaliesDisplay.yml b/Packs/Gurucul/Scripts/GRAAnomaliesDisplay/GRAAnomaliesDisplay.yml index 2c7b3bb9d0e0..b0e623d6bd6b 100644 --- a/Packs/Gurucul/Scripts/GRAAnomaliesDisplay/GRAAnomaliesDisplay.yml +++ b/Packs/Gurucul/Scripts/GRAAnomaliesDisplay/GRAAnomaliesDisplay.yml @@ -11,7 +11,7 @@ enabled: true scripttarget: 0 subtype: python3 timeout: 900ns -dockerimage: demisto/python3:3.10.14.95956 +dockerimage: demisto/python3:3.11.9.106008 runas: DBotWeakRole fromversion: 6.0.0 tests: diff --git a/Packs/Gurucul/Scripts/graanalyticalfeaturedisplay/graanalyticalfeaturedisplay.py b/Packs/Gurucul/Scripts/graanalyticalfeaturedisplay/graanalyticalfeaturedisplay.py index 7e786fd53166..e7770562896b 100644 --- a/Packs/Gurucul/Scripts/graanalyticalfeaturedisplay/graanalyticalfeaturedisplay.py +++ b/Packs/Gurucul/Scripts/graanalyticalfeaturedisplay/graanalyticalfeaturedisplay.py @@ -1,5 +1,4 @@ from CommonServerPython import * # noqa: E402 lgtm [py/polluting-import] -import json from datetime import datetime @@ -13,7 +12,6 @@ def displayAnalyticalFeatures(): anomalyName = '' riskDate = '' entityTypeId = 0 - analyticalFeaturesObj = [] displayData = [] for label in incident['labels']: if label['value'] is not None and label['type'] == 'entityTypeId': @@ -22,15 +20,13 @@ def displayAnalyticalFeatures(): riskDate = datetime.strptime(label['value'], "%m/%d/%Y %H:%M:%S").strftime("%Y-%m-%d") if label['value'] is not None and label['type'] == 'entity': entityValue = label['value'] - if label['value'] is not None and label['type'] == 'anomalies': - anomalies = str(label['value']).replace("null", "\"\"") + anomalies = incident['CustomFields']['gracaseanomalydetails'] if int(entityTypeId) > 0: - anomaliesDetailString = json.loads(anomalies) - for anomalyDetailString in anomaliesDetailString: + for anomalyDetailString in anomalies: anomalyName = '' for key in anomalyDetailString: - if key is not None and key == 'anomalyName': + if key is not None and key == 'anomalyname': anomalyName = anomalyDetailString[key] fromDate = riskDate @@ -42,23 +38,22 @@ def displayAnalyticalFeatures(): 'modelName': anomalyName, 'fromDate': fromDate, 'toDate': toDate, - 'entityTypeId': entityTypeId + 'entityTypeId': entityTypeId, + 'using': incident['sourceInstance'] } ) if res is not None: - for analyticalFeaturesObj in res: - if analyticalFeaturesObj is not None: - for analyticalObj in analyticalFeaturesObj: - if analyticalObj is not None: - for key1 in analyticalObj: - if key1 == 'analyticalFeatureValues': - analyticalFeatures = analyticalObj[key1] - if analyticalFeatures is not None: - for feature in analyticalFeatures: - displayData.append({'Anomaly Name': anomalyName, - 'Analytical Feature': feature, - 'Count': len(analyticalFeatures[feature]), - 'Values': analyticalFeatures[feature]}) + for analyticalObj in res: + if analyticalObj is not None: + for key1 in analyticalObj: + if key1 == 'analyticalFeatureValues': + analyticalFeatures = analyticalObj[key1] + if analyticalFeatures is not None: + for feature in analyticalFeatures: + displayData.append({'Anomaly Name': anomalyName, + 'Analytical Feature': feature, + 'Count': len(analyticalFeatures[feature]), + 'Values': analyticalFeatures[feature]}) if len(displayData) > 0: data = { diff --git a/Packs/Gurucul/Scripts/graanalyticalfeaturedisplay/graanalyticalfeaturedisplay.yml b/Packs/Gurucul/Scripts/graanalyticalfeaturedisplay/graanalyticalfeaturedisplay.yml index 1b5bf7c5c88b..003ad69d1a35 100644 --- a/Packs/Gurucul/Scripts/graanalyticalfeaturedisplay/graanalyticalfeaturedisplay.yml +++ b/Packs/Gurucul/Scripts/graanalyticalfeaturedisplay/graanalyticalfeaturedisplay.yml @@ -6,12 +6,12 @@ script: | type: python tags: - dynamic-section -comment: Display GRA analytical feature on the layout +comment: Display GRA analytical feature on the layout. enabled: true scripttarget: 0 subtype: python3 timeout: 900ns -dockerimage: demisto/python3:3.10.14.90585 +dockerimage: demisto/python3:3.11.9.106008 runas: DBotWeakRole fromversion: 5.5.0 tests: diff --git a/Packs/Gurucul/Scripts/graanalyticalfeaturedisplay/graanalyticalfeaturedisplay_test.py b/Packs/Gurucul/Scripts/graanalyticalfeaturedisplay/graanalyticalfeaturedisplay_test.py index 9da42b7aaecd..24ba085d9817 100644 --- a/Packs/Gurucul/Scripts/graanalyticalfeaturedisplay/graanalyticalfeaturedisplay_test.py +++ b/Packs/Gurucul/Scripts/graanalyticalfeaturedisplay/graanalyticalfeaturedisplay_test.py @@ -3,7 +3,22 @@ _INCIDENT = { + "CustomFields": { + "gracase": "CS-1", + "gracaseanomalydetails": [ + { + "anomalyname": "anomaly_name", + "assignee": "assignee_name", + "assigneetype": "assignee_type", + "resourcename": "resource_name", + "riskaccepteddate": "null", + "riskscore": "0", + "status": "open", + }, + ], + }, 'id': 28862, + 'sourceInstance': 'instance_name', "labels": [ { "type": "Brand", diff --git a/Packs/Gurucul/Scripts/graupdatecasestatus/graupdatecasestatus.py b/Packs/Gurucul/Scripts/graupdatecasestatus/graupdatecasestatus.py index 8b322a382890..7bb01b10d781 100644 --- a/Packs/Gurucul/Scripts/graupdatecasestatus/graupdatecasestatus.py +++ b/Packs/Gurucul/Scripts/graupdatecasestatus/graupdatecasestatus.py @@ -29,11 +29,17 @@ def closeCase(): if _caseId == "": raise Exception('caseId was not found in the incident labels') + res = demisto.executeCommand('gra-validate-api', {'using': incident['sourceInstance']}) + + if res is not None and res[0]['Contents'] == 'Error in service': + raise Exception('Case cannot be closed as GRA services are currently unavailable.') + demisto.executeCommand('gra-case-action', { 'action': action, 'subOption': subOption, 'caseId': _caseId, - 'caseComment': close_notes + 'caseComment': close_notes, + 'using': incident['sourceInstance'] }) diff --git a/Packs/Gurucul/Scripts/graupdatecasestatus/graupdatecasestatus.yml b/Packs/Gurucul/Scripts/graupdatecasestatus/graupdatecasestatus.yml index 1a06939173c0..38137ae60eb5 100644 --- a/Packs/Gurucul/Scripts/graupdatecasestatus/graupdatecasestatus.yml +++ b/Packs/Gurucul/Scripts/graupdatecasestatus/graupdatecasestatus.yml @@ -6,17 +6,17 @@ script: | type: python tags: - post-processing -comment: GRA Update Case Status +comment: GRA Update Case Status. enabled: true args: - name: closeNotes - description: Close Note + description: Close Note. - name: closeReason - description: Close reason + description: Close reason. scripttarget: 0 subtype: python3 timeout: 60ns -dockerimage: demisto/python3:3.10.14.90585 +dockerimage: demisto/python3:3.11.9.106008 runas: DBotWeakRole fromversion: 5.5.0 tests: diff --git a/Packs/Gurucul/Scripts/graupdatecasestatus/graupdatecasestatus_test.py b/Packs/Gurucul/Scripts/graupdatecasestatus/graupdatecasestatus_test.py index 7860f87c3d07..bfde27aa64b3 100644 --- a/Packs/Gurucul/Scripts/graupdatecasestatus/graupdatecasestatus_test.py +++ b/Packs/Gurucul/Scripts/graupdatecasestatus/graupdatecasestatus_test.py @@ -4,6 +4,7 @@ _INCIDENT = { 'id': 28862, + 'sourceInstance': 'instance_name', 'labels': [ { 'type': 'caseId', @@ -33,7 +34,8 @@ def test_gra_update_case_status(monkeypatch, mocker): 'action': 'closeCase', 'subOption': 'True Incident', 'caseId': 'CS-9999', - 'caseComment': '' + 'caseComment': '', + 'using': 'instance_name' } closeCase() execute_mocker.assert_called_with(expected_command, expected_args) diff --git a/Packs/Gurucul/pack_metadata.json b/Packs/Gurucul/pack_metadata.json index b4ffb01598e4..394bad020c55 100644 --- a/Packs/Gurucul/pack_metadata.json +++ b/Packs/Gurucul/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Gurucul Risk Analytics", "description": "Gurucul Risk Analytics (GRA) is a Unified Security and Risk Analytics platform.", "support": "partner", - "currentVersion": "2.0.4", + "currentVersion": "2.0.5", "author": "Gurucul", "url": "https://www.gurucul.com", "email": "support@gurucul.com",