diff --git a/.github/wordlist.txt b/.github/wordlist.txt index d00ab463b..7ded7d7a4 100644 --- a/.github/wordlist.txt +++ b/.github/wordlist.txt @@ -16,6 +16,8 @@ BatchGetCmd BatchGetCmdStatus BatchInitSessions BatchRefreshSessions +booleans +CAs CCID CID CIDs @@ -1999,6 +2001,7 @@ AgentTemplates AgentInvocation AgentStudio AgenticStudio +Charlotte Khaitan Yashvardhan MRX @@ -2008,3 +2011,38 @@ ManuelFCastillo khaitan yashvardhan Agentic +Eval +eval +GetAgentInvocationV +PatchAgentInvocationV +GetAgentVersionsV +QueryAgentVersionsV +CreateOrEditAgentExternalV +DeleteAgentV +GetAgentsV +PatchAgentExternalV +QueryAgentsV +CombinedKnowledgeBaseAuditEventsV +EntitiesKnowledgeBaseAuditEventsV +QueriesKnowledgeBaseAuditEventsV +EntitiesKnowledgeBaseFilesCreateV +EntitiesKnowledgeBaseFilesDeleteV +EntitiesKnowledgeBaseFilesDownloadV +EntitiesKnowledgeBaseFilesUpdateV +EntitiesKnowledgeBaseFilesV +QueriesKnowledgeBaseFilesV +CombinedKnowledgeBasesV +EntitiesKnowledgeBasesUpdateV +EntitiesKnowledgeBasesV +QueriesKnowledgeBasesV +EntitiesSkillsCreateV +EntitiesSkillsDeleteV +EntitiesSkillsDownloadV +EntitiesSkillsUpdateV +EntitiesSkillsV +QueriesSkillsV +EntitiesSpansV +QueriesSpansV +StreamInvocationResponseV +EntitiesToolsV +QueriesToolsV diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a24d6cd9..7a0d021f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,230 @@ +# Version 1.6.7 +## Added features and functionality ++ Updated: Renamed the __AgenticStudio__ parent service collection to __Charlotte__, since every one of its sub-services requires a Charlotte AI scope, and added __Eval Cases__, __Eval Dataset Entries__, __Eval Datasets__, __Eval Evaluators__ and __Eval Runs__ to it. `AgenticStudio` remains available as a backward compatible alias, including from `falconpy.agentic_studio`. + - `__init__.py` + - `agentic_studio.py` + - `charlotte.py` + ++ Updated: Added `project_id` as an allowed parameter in the _GetAgentInvocationV3_ and _PatchAgentInvocationV3_ operations within the __Agent Invocation__ service collection. + - `_endpoint/_agent_invocation.py` + - `_payload/_agent_invocation.py` + - `agent_invocation.py` + ++ Updated: Added `project_id` as an allowed parameter in the _GetAgentVersionsV1_ and _QueryAgentVersionsV1_ operations within the __Agent Versions__ service collection. + - `_endpoint/_agent_versions.py` + - `agent_versions.py` + ++ Updated: Added `project_id` as an allowed parameter in the _DeleteAgentV1_, _GetAgentsV2_, _PatchAgentExternalV3_, and _QueryAgentsV2_ operations and added `wait_for_ready` as an allowed parameter in the _CreateOrEditAgentExternalV3_ and _PatchAgentExternalV3_ operations within the __Agents__ service collection. + - `_endpoint/_agents.py` + - `_payload/_agents.py` + - `agents.py` + ++ Added: Added five new operations to the __Browser Security__ service collection. + - _get_sensitive_data_profiles_ + - _create_sensitive_data_profile_ + - _delete_sensitive_data_profile_ + - _update_sensitive_data_profile_ + - _query_sensitive_data_profiles_ + - `_endpoint/_browser_security.py` + - `_payload/__init__.py` + - `_payload/_browser_security.py` + - `browser_security.py` + > Unit testing expanded to complete code coverage. + - `tests/test_browser_security.py` + ++ Added: Added five new operations to the __Case Management__ service collection. + - _add_case_alert_evidence_v2_ + - _add_case_access_tags_ + - _remove_case_access_tags_ + - _add_case_custom_evidence_ + - _add_case_user_evidence_ + - `_endpoint/_case_management.py` + - `_payload/__init__.py` + - `_payload/_case_management.py` + - `case_management.py` + > Unit testing expanded to complete code coverage. + - `tests/test_case_management.py` + ++ Added: New __Eval Cases__ service collection with two operations. + - _get_eval_cases_ + - _query_eval_cases_ + - `_endpoint/__init__.py` + - `_endpoint/_eval_cases.py` + - `_payload/__init__.py` + - `__init__.py` + - `eval_cases.py` + > Unit testing expanded to complete code coverage. + - `tests/test_eval_cases.py` + ++ Added: New __Eval Dataset Entries__ service collection with five operations. + - _get_eval_dataset_entries_ + - _update_eval_dataset_entry_ + - _create_eval_dataset_entry_ + - _delete_eval_dataset_entry_ + - _query_eval_dataset_entries_ + - `_endpoint/__init__.py` + - `_endpoint/_eval_dataset_entries.py` + - `_payload/__init__.py` + - `_payload/_eval_dataset_entries.py` + - `__init__.py` + - `eval_dataset_entries.py` + > Unit testing expanded to complete code coverage. + - `tests/test_eval_dataset_entries.py` + ++ Added: New __Eval Datasets__ service collection with six operations. + - _download_eval_dataset_ + - _get_eval_datasets_ + - _update_eval_dataset_ + - _create_eval_dataset_ + - _delete_eval_dataset_ + - _query_eval_datasets_ + - `_endpoint/__init__.py` + - `_endpoint/_eval_datasets.py` + - `_payload/__init__.py` + - `_payload/_eval_datasets.py` + - `__init__.py` + - `eval_datasets.py` + > Unit testing expanded to complete code coverage. + - `tests/test_eval_datasets.py` + ++ Added: New __Eval Evaluators__ service collection with five operations. + - _get_eval_evaluators_ + - _update_eval_evaluator_ + - _create_eval_evaluator_ + - _delete_eval_evaluator_ + - _query_eval_evaluators_ + - `_endpoint/__init__.py` + - `_endpoint/_eval_evaluators.py` + - `_payload/__init__.py` + - `_payload/_eval_evaluators.py` + - `__init__.py` + - `eval_evaluators.py` + > Unit testing expanded to complete code coverage. + - `tests/test_eval_evaluators.py` + ++ Added: New __Eval Runs__ service collection with five operations. + - _get_eval_runs_ + - _create_eval_run_ + - _delete_eval_run_ + - _perform_eval_run_action_ + - _query_eval_runs_ + - `_endpoint/__init__.py` + - `_endpoint/_eval_runs.py` + - `_payload/__init__.py` + - `_payload/_eval_runs.py` + - `__init__.py` + - `eval_runs.py` + > Unit testing expanded to complete code coverage. + - `tests/test_eval_runs.py` + ++ Updated: Added `device_policies.cloud-container-workload.applied`, `device_policies.cloud-container-workload.policy_id`, `device_policies.cloud-container-workload.policy_type` as allowed `sort` values in the _CombinedHiddenDevicesByFilter_ and _CombinedDevicesByFilter_ operations and added `skip_membership_validation` as an allowed parameter in the _entities_perform_action_ operation within the __Hosts__ service collection. + - `_endpoint/_hosts.py` + - `hosts.py` + ++ Added: Added 13 new operations to the __IT Automation__ service collection. + - _aggregate_patch_deployment_configs_ + - _aggregate_patch_deployment_executions_ + - _aggregate_patch_host_deployments_ + - _query_combined_patch_deployment_configs_ + - _query_combined_patch_deployment_executions_ + - _query_combined_host_deployment_patches_ + - _query_combined_host_deployments_ + - _query_combined_os_assessment_scan_ + - _query_combined_os_assessments_ + - _create_patch_deployment_config_ + - _delete_patch_deployment_configs_ + - _update_patch_deployment_config_ + - _cancel_patch_deployment_executions_ + - `_endpoint/_it_automation.py` + - `_payload/__init__.py` + - `_payload/_it_automation.py` + - `it_automation.py` + > Unit testing expanded to complete code coverage. + - `tests/test_it_automation.py` + ++ Updated: Added `project_id` as an allowed parameter in the _CombinedKnowledgeBaseAuditEventsV1_, _EntitiesKnowledgeBaseAuditEventsV1_, and _QueriesKnowledgeBaseAuditEventsV1_ operations within the __Knowledge Base Audit Events__ service collection. + - `_endpoint/_knowledge_base_audit_events.py` + - `knowledge_base_audit_events.py` + ++ Updated: Added `project_id` as an allowed parameter in the _EntitiesKnowledgeBaseFilesDownloadV1_, _EntitiesKnowledgeBaseFilesV1_, _EntitiesKnowledgeBaseFilesUpdateV1_, _EntitiesKnowledgeBaseFilesCreateV1_, _EntitiesKnowledgeBaseFilesDeleteV1_, and _QueriesKnowledgeBaseFilesV1_ operations within the __Knowledge Base Files__ service collection. + - `_endpoint/_knowledge_base_files.py` + - `knowledge_base_files.py` + ++ Updated: Added `project_id` as an allowed parameter in the _CombinedKnowledgeBasesV1_, _EntitiesKnowledgeBasesV1_, _EntitiesKnowledgeBasesUpdateV1_, and _QueriesKnowledgeBasesV1_ operations within the __Knowledge Bases__ service collection. + - `_endpoint/_knowledge_bases.py` + - `_payload/_knowledge_bases.py` + - `knowledge_bases.py` + ++ Added: Added five new operations to the __NGSIEM__ service collection. + - _get_scheduled_report_ + - _create_scheduled_report_ + - _delete_scheduled_report_ + - _update_scheduled_report_ + - _query_scheduled_reports_ + - `_endpoint/_ngsiem.py` + - `_payload/__init__.py` + - `_payload/_ngsiem.py` + - `ngsiem.py` + > Unit testing expanded to complete code coverage. + - `tests/test_ngsiem.py` + ++ Updated: Added `scan_mode` as an allowed parameter and updated the `file` and `scan` parameter descriptions in the _UploadFileQuickScanPro_ operation within the __Quick Scan Pro__ service collection. + - `_endpoint/_quick_scan_pro.py` + - `quick_scan_pro.py` + ++ Added: Added two new operations to the __SaaS Security__ service collection. + - _set_check_impact_ + - _get_security_check_change_log_ + - `_endpoint/_saas_security.py` + - `_payload/__init__.py` + - `_payload/_saas_security.py` + - `saas_security.py` + > Unit testing expanded to complete code coverage. + - `tests/test_saas_security.py` + ++ Updated: Added `project_id` as an allowed parameter in the _EntitiesSkillsDownloadV2_, _EntitiesSkillsV1_, _EntitiesSkillsUpdateV1_, _EntitiesSkillsCreateV1_, _EntitiesSkillsDeleteV1_, and _QueriesSkillsV1_ operations within the __Skills__ service collection. + - `_endpoint/_skills.py` + - `skills.py` + ++ Updated: Added `project_id` as an allowed parameter in the _EntitiesSpansV1_ and _QueriesSpansV1_ operations within the __Spans__ service collection. + - `_endpoint/_spans.py` + - `spans.py` + ++ Updated: Added `project_id` as an allowed parameter in the _StreamInvocationResponseV1_ operation within the __Stream__ service collection. + - `_endpoint/_stream.py` + - `stream.py` + ++ Updated: Added `project_id` as an allowed parameter in the _EntitiesToolsV1_ and _QueriesToolsV1_ operations within the __Tools__ service collection. + - `_endpoint/_tools.py` + - `tools.py` + ++ Added: Added four new operations to the __User Management__ service collection. + - _get_permission_groups_ + - _get_permissions_ + - _get_role_permissions_ + - _query_permissions_ + - `_endpoint/_user_management.py` + - `_payload/__init__.py` + - `_payload/_user_management.py` + - `user_management.py` + > Unit testing expanded to complete code coverage. + - `tests/test_user_management.py` + +## Issues resolved ++ Fixed: A CA_BUNDLE path (file or directory of trusted certificates) provided to the `ssl_verify` keyword was silently discarded and replaced with `True` when passed to the constructor of the Uber Class (`APIHarnessV2`), the __OAuth2__ class, or any Service Class. Requests were then verified against the default trust store, breaking connectivity behind TLS-inspecting proxies and private CAs. This was a regression introduced in v1.3.0; the legacy Uber Class and v1.2.x Service Classes accepted a path. The constructor and the `ssl_verify` property setter now share the same handling: booleans and CA_BUNDLE paths (`str` or `os.PathLike`) are passed to requests, while empty strings and unsupported types fall back to `True` so verification is never disabled unintentionally. Closes #1521. + - `_api_request/_request.py` + - `_api_request/_request_connection.py` + - `_auth_object/_falcon_interface.py` + - `_auth_object/_interface_config.py` + - `_auth_object/_uber_interface.py` + - `_service_class/_base_service_class.py` + - `_service_class/_service_class.py` + - `_util/_functions.py` + - `oauth2.py` + > Unit testing expanded to cover `ssl_verify` normalization and CA_BUNDLE path handling. + - `tests/test_ssl_verify.py` + - Thanks go out to @tsullivan06 for identifying and reporting this issue! 🙇 + # Version 1.6.6 ## Added Features and functionality + Added: New __AgenticStudio__ parent service collection aggregating all 12 Agentic Studio sub-services via multiple inheritance. diff --git a/README.md b/README.md index 232c4d91f..f046b5e04 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,35 @@ Representing a single CrowdStrike Falcon API service collection, each Service Cl For each CrowdStrike Falcon API service collection, a matching Service Class is available in the FalconPy library. For a complete list of service collections and their related Service Class, please review the [Operations by Collection](https://developer.crowdstrike.com/api-reference/operations-by-collection/) page on the [CrowdStrike Developer Center](https://developer.crowdstrike.com). +#### Parent Service Classes +Some CrowdStrike Falcon API service collections are closely related. A _Parent Service Class_ combines these service collections into a single class using multiple inheritance, providing a method for [every operation available](https://developer.crowdstrike.com/api-reference/operations-by-collection/) within each of the service collections it includes. The Service Class for each individual service collection remains available. + + +| Parent Service Class | Included Service Classes | +| :-- | :-- | +| `Charlotte` | `Agents`, `AgentInvocation`, `AgentTemplates`, `AgentVersions`, `KnowledgeBases`, `KnowledgeBaseFiles`, `KnowledgeBaseAuditEvents`, `Models`, `Skills`, `Spans`, `Tools`, `Stream`, `EvalCases`, `EvalDatasetEntries`, `EvalDatasets`, `EvalEvaluators`, `EvalRuns` | +| `ContainerSecurity` | `ContainerAlerts`, `ContainerDetections`, `ContainerImageCompliance`, `ContainerImages`, `ContainerVulnerabilities`, `DriftIndicators`, `ImageAssessmentPolicies` | +| `Firewall` | `FirewallPolicies`, `FirewallManagement` | +| `Foundry` | `FoundryLookupFiles`, `FoundryLogScale`, `CustomStorage`, `FaaSExecution` | +| `NetworkScan` | `NetworkScanGlobalConfigs`, `NetworkScanScanRunReports`, `NetworkScanScanRuns`, `NetworkScanScanners`, `NetworkScanTemplates`, `NetworkScanNetworks`, `NetworkScanScans`, `NetworkScanZones`, `NetworkScanDetections` | +| `Serverless` | `ServerlessExports`, `ServerlessVulnerabilities` | +| `Spotlight` | `SpotlightVulnerabilities`, `SpotlightVulnerabilityMetadata`, `SpotlightEvaluationLogic` | + + +```python +import os +from falconpy import Charlotte + +charlotte = Charlotte(client_id=os.getenv("FALCON_CLIENT_ID"), + client_secret=os.getenv("FALCON_CLIENT_SECRET") + ) + +# Operations from the Agents and Eval Datasets service collections are available from the same class +agents = charlotte.query_studio_agents(limit=10) +datasets = charlotte.query_eval_datasets(limit=10) +``` + + #### Service Class benefits - Closely follows Python and OpenAPI best practice for code style and syntax. PEP-8 compliant. diff --git a/src/falconpy/__init__.py b/src/falconpy/__init__.py index 96915ca6d..4f9098c50 100644 --- a/src/falconpy/__init__.py +++ b/src/falconpy/__init__.py @@ -111,7 +111,7 @@ from .agent_invocation import AgentInvocation from .agent_templates import AgentTemplates from .agent_versions import AgentVersions -from .agentic_studio import AgenticStudio +from .charlotte import Charlotte from .agents import Agents from .aidr import AIDR from .alerts import Alerts @@ -164,6 +164,11 @@ from .discover import Discover from .downloads import Downloads from .drift_indicators import DriftIndicators +from .eval_cases import EvalCases +from .eval_dataset_entries import EvalDatasetEntries +from .eval_datasets import EvalDatasets +from .eval_evaluators import EvalEvaluators +from .eval_runs import EvalRuns from .event_streams import EventStreams from .exposure_management import ExposureManagement from .faas_execution import FaaSExecution @@ -328,13 +333,17 @@ "CodeSecurity", "NetworkContainment", "NetworkScanDetections", "Skills", "Guardian", "Seraphic", - "AgenticStudio", + "Charlotte", "ContainerSecurity", "Spotlight", "Serverless", "Firewall", - "Foundry" + "Foundry", "EvalCases", + "EvalDatasetEntries", "EvalDatasets", + "EvalEvaluators", "EvalRuns", + "AgenticStudio" ] +AgenticStudio = Charlotte Seraphic = BrowserSecurity Guardian = AIDR """ diff --git a/src/falconpy/_api_request/_request.py b/src/falconpy/_api_request/_request.py index 0443bf279..c343a2357 100644 --- a/src/falconpy/_api_request/_request.py +++ b/src/falconpy/_api_request/_request.py @@ -278,6 +278,6 @@ def timeout(self) -> Optional[Union[int, tuple]]: return self.connection.timeout @property - def verify(self) -> bool: + def verify(self) -> Union[bool, str]: """Return the SSL verification setting.""" return self.connection.verify diff --git a/src/falconpy/_api_request/_request_connection.py b/src/falconpy/_api_request/_request_connection.py index 447dc6e3b..ace0452e5 100644 --- a/src/falconpy/_api_request/_request_connection.py +++ b/src/falconpy/_api_request/_request_connection.py @@ -49,7 +49,7 @@ class RequestConnection: # | | | | | \ | |__] |__| | |___ ___] # user_agent: Optional[str] = None - verify: bool = True + verify: Union[bool, str] = True timeout: Optional[Union[int, tuple]] = None proxy: Optional[Dict[str, str]] = None session: Optional[requests.Session] = None diff --git a/src/falconpy/_auth_object/_falcon_interface.py b/src/falconpy/_auth_object/_falcon_interface.py index 7312c58a7..4e65b1d3c 100644 --- a/src/falconpy/_auth_object/_falcon_interface.py +++ b/src/falconpy/_auth_object/_falcon_interface.py @@ -85,7 +85,7 @@ def __init__(self, # noqa: C901 client_id: Optional[str] = None, client_secret: Optional[str] = None, member_cid: Optional[str] = None, - ssl_verify: Optional[bool] = True, + ssl_verify: Optional[Union[bool, str, os.PathLike]] = True, proxy: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, tuple]] = None, user_agent: Optional[str] = None, @@ -425,12 +425,12 @@ def base_url(self, value): self.config.base_url = value @property - def ssl_verify(self) -> bool: + def ssl_verify(self) -> Union[bool, str]: """Return the SSL verification setting from the configuration object.""" return self.config.ssl_verify @ssl_verify.setter - def ssl_verify(self, value: bool): + def ssl_verify(self, value: Union[bool, str, os.PathLike]): self.config.ssl_verify = value @property diff --git a/src/falconpy/_auth_object/_interface_config.py b/src/falconpy/_auth_object/_interface_config.py index ea8674f5c..daa7632d0 100644 --- a/src/falconpy/_auth_object/_interface_config.py +++ b/src/falconpy/_auth_object/_interface_config.py @@ -35,10 +35,30 @@ For more information, please refer to """ +import os from typing import Dict, Union, Optional import requests +def _normalize_ssl_verify(value: Optional[Union[bool, str, os.PathLike]]) -> Union[bool, str]: + """Return a value that is safe to hand to requests as the verify argument. + + requests accepts a boolean, or the path to a CA_BUNDLE file or a directory of + trusted certificates. Path-like objects are converted to a string path. + + Empty or whitespace-only strings are treated as "not provided" and fall back to True. + requests treats an empty string as falsy and would silently disable verification. + Any other unsupported value also falls back to True so verification stays enabled. + """ + if isinstance(value, bool): + return value + if isinstance(value, os.PathLike): + value = os.fspath(value) + if isinstance(value, str) and value.strip(): + return value + return True + + class InterfaceConfiguration: """This class represents the configuration of the interface.""" @@ -51,7 +71,7 @@ def __init__(self, proxy: Optional[Dict[str, str]] = None, timeout: Optional[Union[int, tuple]] = None, user_agent: Optional[str] = None, - ssl_verify: Optional[bool] = True, + ssl_verify: Optional[Union[bool, str, os.PathLike]] = True, session: Optional[requests.Session] = None ): """Construct an instance of the InterfaceConfiguration class.""" @@ -60,10 +80,8 @@ def __init__(self, self._timeout: Optional[Union[int, tuple]] = timeout self._user_agent: Optional[str] = user_agent self._session: Optional[requests.Session] = session - - self._ssl_verify: bool = True - if isinstance(ssl_verify, bool): - self._ssl_verify = ssl_verify + # Boolean, or the path to a CA_BUNDLE file / directory of trusted certificates. + self._ssl_verify: Union[bool, str] = _normalize_ssl_verify(ssl_verify) # ___ ____ ____ ___ ____ ____ ___ _ ____ ____ # |__] |__/ | | |__] |___ |__/ | | |___ [__ @@ -111,14 +129,14 @@ def user_agent(self, value: Optional[str] = None): self._user_agent = value @property - def ssl_verify(self) -> bool: - """Return the SSL verification setting.""" + def ssl_verify(self) -> Union[bool, str]: + """Return the SSL verification setting (a boolean or a CA_BUNDLE path).""" return self._ssl_verify @ssl_verify.setter - def ssl_verify(self, value: bool): - """Change the SSL verification setting.""" - self._ssl_verify = value + def ssl_verify(self, value: Union[bool, str, os.PathLike]): + """Change the SSL verification setting (a boolean or a CA_BUNDLE path).""" + self._ssl_verify = _normalize_ssl_verify(value) @property def session(self) -> Optional[requests.Session]: diff --git a/src/falconpy/_auth_object/_uber_interface.py b/src/falconpy/_auth_object/_uber_interface.py index f61ca07f3..64ca21022 100644 --- a/src/falconpy/_auth_object/_uber_interface.py +++ b/src/falconpy/_auth_object/_uber_interface.py @@ -35,6 +35,7 @@ For more information, please refer to """ +import os from traceback import extract_tb from typing import Dict, List, Optional, Union import requests @@ -71,7 +72,7 @@ def __init__(self, client_id: Optional[str] = None, client_secret: Optional[str] = None, member_cid: Optional[str] = None, - ssl_verify: Optional[bool] = True, + ssl_verify: Optional[Union[bool, str, os.PathLike]] = True, proxy: Optional[dict] = None, timeout: Optional[Union[float, tuple]] = None, user_agent: Optional[str] = None, @@ -91,7 +92,9 @@ def __init__(self, Keyword arguments: base_url: CrowdStrike API URL to use for requests. [Default: US-1] - ssl_verify: Boolean specifying if SSL verification should be used. [Default: True] + ssl_verify: Boolean specifying if SSL verification should be used or string representing + the path to a CA_BUNDLE file or directory of trusted certificates. + [Default: True] proxy: Dictionary of proxies to be used for requests. timeout: Float or tuple specifying timeouts to use for requests. creds: Dictionary containing CrowdStrike API credentials. diff --git a/src/falconpy/_endpoint/__init__.py b/src/falconpy/_endpoint/__init__.py index d6a9bb3ac..8b4fa386a 100644 --- a/src/falconpy/_endpoint/__init__.py +++ b/src/falconpy/_endpoint/__init__.py @@ -128,6 +128,11 @@ from ._discover import _discover_endpoints from ._downloads import _downloads_endpoints from ._drift_indicators import _drift_indicators_endpoints +from ._eval_cases import _eval_cases_endpoints +from ._eval_dataset_entries import _eval_dataset_entries_endpoints +from ._eval_datasets import _eval_datasets_endpoints +from ._eval_evaluators import _eval_evaluators_endpoints +from ._eval_runs import _eval_runs_endpoints from ._event_streams import _event_streams_endpoints from ._exposure_management import _exposure_management_endpoints from ._faas_execution import _faas_execution_endpoints @@ -271,6 +276,11 @@ api_endpoints.extend(_deployments_endpoints) api_endpoints.extend(_downloads_endpoints) api_endpoints.extend(_drift_indicators_endpoints) +api_endpoints.extend(_eval_cases_endpoints) +api_endpoints.extend(_eval_dataset_entries_endpoints) +api_endpoints.extend(_eval_datasets_endpoints) +api_endpoints.extend(_eval_evaluators_endpoints) +api_endpoints.extend(_eval_runs_endpoints) api_endpoints.extend(_event_streams_endpoints) api_endpoints.extend(_exposure_management_endpoints) api_endpoints.extend(_faas_execution_endpoints) diff --git a/src/falconpy/_endpoint/_agent_invocation.py b/src/falconpy/_endpoint/_agent_invocation.py index 93866cc66..4d22ce5e7 100644 --- a/src/falconpy/_endpoint/_agent_invocation.py +++ b/src/falconpy/_endpoint/_agent_invocation.py @@ -66,6 +66,12 @@ "name": "id", "in": "query", "required": True + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" } ] ], @@ -78,6 +84,12 @@ "terminal state succeeds without changing it.", "agent_invocation", [ + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" + }, { "description": "Invocation ID and the status to move it to. Only cancelled is accepted.", "name": "body", diff --git a/src/falconpy/_endpoint/_agent_versions.py b/src/falconpy/_endpoint/_agent_versions.py index c997d35fe..a264e022f 100644 --- a/src/falconpy/_endpoint/_agent_versions.py +++ b/src/falconpy/_endpoint/_agent_versions.py @@ -54,6 +54,12 @@ "name": "ids", "in": "query", "required": True + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" } ] ], @@ -90,6 +96,12 @@ "description": "FQL query specifying the filter parameters.", "name": "filter", "in": "query" + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" } ] ] diff --git a/src/falconpy/_endpoint/_agents.py b/src/falconpy/_endpoint/_agents.py index e4820f3c6..bfa510fcc 100644 --- a/src/falconpy/_endpoint/_agents.py +++ b/src/falconpy/_endpoint/_agents.py @@ -50,6 +50,12 @@ "name": "id", "in": "query", "required": True + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" } ] ], @@ -70,6 +76,12 @@ "name": "ids", "in": "query", "required": True + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" } ] ], @@ -81,6 +93,14 @@ "response differs from the previous one while the agent ID stays the same.", "agents", [ + { + "type": "boolean", + "default": True, + "description": "Wait for the new version to finish registering before responding. Set to false to " + "respond immediately and poll GetAgentVersionsV1 for is_in_sync instead.", + "name": "wait_for_ready", + "in": "query" + }, { "description": "Agent definition to create or update.", "name": "body", @@ -110,6 +130,20 @@ "name": "dry_run", "in": "query" }, + { + "type": "boolean", + "default": True, + "description": "Wait for the change to finish propagating downstream before responding. Set to false " + "to respond immediately and poll GetAgentVersionsV1 for is_in_sync instead.", + "name": "wait_for_ready", + "in": "query" + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" + }, { "description": "Properties to be modified on the specified agent version (only one modification is " "permitted at a time)", @@ -152,6 +186,12 @@ "description": "FQL query specifying the filter parameters.", "name": "filter", "in": "query" + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" } ] ] diff --git a/src/falconpy/_endpoint/_aidr.py b/src/falconpy/_endpoint/_aidr.py index ff4332ea4..dfe214ec6 100644 --- a/src/falconpy/_endpoint/_aidr.py +++ b/src/falconpy/_endpoint/_aidr.py @@ -295,7 +295,7 @@ "type": "string" }, "collectionFormat": "multi", - "description": "One or more installation IDs (repeatable). Use the Id value from queryAgentInstallationsV1", + "description": "One or more installation IDs (repeatable). Use the Id value from queryAgentInstallationsV1.", "name": "ids", "in": "query", "required": True @@ -339,7 +339,7 @@ }, "collectionFormat": "multi", "description": "One or more session IDs (repeatable: ids=A&ids=B). Use the Id value from " - "queryAgentSessionsV1 This is the AIAgentSession entity key, not a ThreatGraph vertex key.", + "queryAgentSessionsV1. This is the AIAgentSession entity key, not a ThreatGraph vertex key.", "name": "ids", "in": "query", "required": True @@ -439,7 +439,7 @@ "type": "string" }, "collectionFormat": "multi", - "description": "One or more AIModelName IDs (repeatable). Use the Id value from queryModelNamesV1", + "description": "One or more AIModelName IDs (repeatable). Use the Id value from queryModelNamesV1.", "name": "ids", "in": "query", "required": True @@ -523,7 +523,7 @@ "type": "string" }, "collectionFormat": "multi", - "description": "One or more skill frontmatter IDs (repeatable). Use the Id value from querySkillsV1", + "description": "One or more skill frontmatter IDs (repeatable). Use the Id value from querySkillsV1.", "name": "ids", "in": "query", "required": True @@ -543,7 +543,7 @@ "type": "string" }, "collectionFormat": "multi", - "description": "One or more AITool IDs (repeatable: ids=A&ids=B). Use the Id value from queryToolsV1", + "description": "One or more AITool IDs (repeatable: ids=A&ids=B). Use the Id value from queryToolsV1.", "name": "ids", "in": "query", "required": True diff --git a/src/falconpy/_endpoint/_audit.py b/src/falconpy/_endpoint/_audit.py index 93c39aeb7..ef06ac715 100644 --- a/src/falconpy/_endpoint/_audit.py +++ b/src/falconpy/_endpoint/_audit.py @@ -60,14 +60,14 @@ }, { "type": "boolean", - "description": "When true, includes descriptions for category and action fields (default: False)", + "description": "When true, includes descriptions for category and action fields (default: false)", "name": "include_descriptions", "in": "query" }, { "type": "boolean", "description": "When true, filters extension keys based on audit definition YAML and includes " - "descriptions for extension keys (default: False)", + "descriptions for extension keys (default: false)", "name": "include_extension_metadata", "in": "query" } @@ -101,14 +101,14 @@ }, { "type": "boolean", - "description": "When true, includes descriptions for category and action fields (default: False)", + "description": "When true, includes descriptions for category and action fields (default: false)", "name": "include_descriptions", "in": "query" }, { "type": "boolean", "description": "When true, filters extension keys based on audit definition YAML and includes " - "descriptions for extension keys (default: False)", + "descriptions for extension keys (default: false)", "name": "include_extension_metadata", "in": "query" } diff --git a/src/falconpy/_endpoint/_browser_security.py b/src/falconpy/_endpoint/_browser_security.py index 73f3890de..e74557e23 100644 --- a/src/falconpy/_endpoint/_browser_security.py +++ b/src/falconpy/_endpoint/_browser_security.py @@ -45,7 +45,8 @@ "browser_security", [ { - "description": "Request body.", + "description": "Filter, sort and pagination for the agent search. limit accepts up to 2500. " + "filter.protection_type has no effect on this operation.", "name": "body", "in": "body", "required": True @@ -60,7 +61,7 @@ "browser_security", [ { - "description": "Request body.", + "description": "The domains to classify. At least one domain is required.", "name": "body", "in": "body", "required": True @@ -75,7 +76,7 @@ "browser_security", [ { - "description": "Request body.", + "description": "The IDs of the agents to activate. Required, must be non-empty.", "name": "body", "in": "body", "required": True @@ -90,7 +91,7 @@ "browser_security", [ { - "description": "Request body.", + "description": "The IDs of the agents to deactivate. Required, must be non-empty.", "name": "body", "in": "body", "required": True @@ -112,7 +113,9 @@ "required": True }, { - "description": "Request body.", + "description": "The actions to queue on the agent, and an optional ttl in hours (default 72, 1-168). " + "Each action is one of remove_browsing_data, close_all_windows, refresh_all_tabs or dispatch_notification; its " + "args depend on the action type.", "name": "body", "in": "body", "required": True @@ -187,7 +190,8 @@ "browser_security", [ { - "description": "Request body.", + "description": "The destination group to create. name is required; the IP, domain, country and " + "classification lists are all optional and combine into one group.", "name": "body", "in": "body", "required": True @@ -225,7 +229,8 @@ "required": True }, { - "description": "Request body.", + "description": "The fields to change on the destination group. Every field is optional; only those " + "present are updated.", "name": "body", "in": "body", "required": True @@ -241,7 +246,14 @@ [ { "type": "string", - "description": "The extension store.", + "enum": [ + "google", + "mozilla", + "microsoft", + "apple", + "opera" + ], + "description": "The extension store platform.", "name": "store", "in": "query", "required": True @@ -290,7 +302,84 @@ "required": True }, { - "description": "Request body.", + "description": "The changes to apply. Each field is an independent partial update — extension IDs and " + "names to add or remove, target and destination-group changes, and activation status. These are not applied " + "transactionally; a combined body can half-apply.", + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "GetSensitiveDataProfiles", + "GET", + "/seraphic-enterprise-browser/entities/sensitive-data-profiles/v1", + "Retrieve sensitive data profiles by ID, with the rules that reference them.", + "browser_security", + [ + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "description": "One or more resource IDs.", + "name": "ids", + "in": "query", + "required": True + } + ] + ], + [ + "CreateSensitiveDataProfile", + "POST", + "/seraphic-enterprise-browser/entities/sensitive-data-profiles/v1", + "Create a sensitive data profile.", + "browser_security", + [ + { + "description": "The sensitive data profile to create. name is required and must be at least 2 " + "characters; the predefined-PII and custom-regex lists are both optional and combine into one profile.", + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "DeleteSensitiveDataProfile", + "DELETE", + "/seraphic-enterprise-browser/entities/sensitive-data-profiles/v1", + "Delete a sensitive data profile.", + "browser_security", + [ + { + "type": "string", + "description": "The resource ID.", + "name": "id", + "in": "query", + "required": True + } + ] + ], + [ + "UpdateSensitiveDataProfile", + "PATCH", + "/seraphic-enterprise-browser/entities/sensitive-data-profiles/v1", + "Partial-update a sensitive data profile.", + "browser_security", + [ + { + "type": "string", + "description": "The resource ID.", + "name": "id", + "in": "query", + "required": True + }, + { + "description": "The fields to change on the sensitive data profile. Every field is optional, but at " + "least one must be present or console rejects the request.", "name": "body", "in": "body", "required": True @@ -345,7 +434,8 @@ "browser_security", [ { - "description": "Request body.", + "description": "The integration to add to, and the URLs and domains to add. Both fields are required " + "and urls must be non-empty.", "name": "body", "in": "body", "required": True @@ -367,7 +457,8 @@ "required": True }, { - "description": "Request body.", + "description": "The integration to remove from, and the URLs and domains to remove. Both fields are " + "required and urls must be non-empty.", "name": "body", "in": "body", "required": True @@ -382,7 +473,8 @@ "browser_security", [ { - "description": "Request body.", + "description": "Filter, sort and pagination for the agent search. limit accepts up to 1000. " + "filter.protection_type is honoured here.", "name": "body", "in": "body", "required": True @@ -397,7 +489,7 @@ "browser_security", [ { - "description": "Request body.", + "description": "Filter, sort, pagination and name exclusions for the destination-group search.", "name": "body", "in": "body", "required": True @@ -413,13 +505,43 @@ [ { "type": "string", + "enum": [ + "general", + "protection", + "sessions_and_credentials", + "content_governance", + "dlp", + "privacy", + "it_hygiene", + "telemetry", + "proxy", + "extensions", + "applications" + ], "description": "The rule category to query.", "name": "category", "in": "query", "required": True }, { - "description": "Request body.", + "description": "Filter, advanced filter, rule-ID selection, sort and pagination for the rule search. " + "Applies within the category given in the query string.", + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "QuerySensitiveDataProfiles", + "POST", + "/seraphic-enterprise-browser/queries/sensitive-data-profiles/v1", + "Query sensitive data profiles by filter, sort and pagination.", + "browser_security", + [ + { + "description": "Filter, advanced filter, sort, pagination and profile-ID exclusions for the sensitive-" + "data-profile search.", "name": "body", "in": "body", "required": True diff --git a/src/falconpy/_endpoint/_case_management.py b/src/falconpy/_endpoint/_case_management.py index b6527d744..175b8a76c 100644 --- a/src/falconpy/_endpoint/_case_management.py +++ b/src/falconpy/_endpoint/_case_management.py @@ -1043,6 +1043,60 @@ } ] ], + [ + "entities_alert_evidence_post_v2", + "POST", + "/cases/entities/alert-evidence/v2", + "Adds the given list of alert evidence to the specified case and returns the created evidence records.", + "case_management", + [ + { + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "entities_case_access_tags_post_v1", + "POST", + "/cases/entities/case-access-tags/v1", + "Adds the given list of access tags to the specified case.", + "case_management", + [ + { + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "entities_case_access_tags_delete_v1", + "DELETE", + "/cases/entities/case-access-tags/v1", + "Removes the specified access tags from the specified case.", + "case_management", + [ + { + "type": "string", + "description": "The ID of the case to remove access tags from.", + "name": "id", + "in": "query", + "required": True + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "description": "The ID of the access tag to remove from the case.", + "name": "access_tag_id", + "in": "query" + } + ] + ], [ "entities_case_tags_post_v1", "POST", @@ -1126,6 +1180,20 @@ } ] ], + [ + "entities_custom_evidence_post_v1", + "POST", + "/cases/entities/custom-evidence/v1", + "Adds the given custom evidence to the specified case.", + "case_management", + [ + { + "name": "body", + "in": "body", + "required": True + } + ] + ], [ "entities_event_evidence_post_v1", "POST", @@ -1154,6 +1222,20 @@ } ] ], + [ + "entities_user_evidence_post_v1", + "POST", + "/cases/entities/user-evidence/v1", + "Adds user evidence to the specified case.", + "case_management", + [ + { + "name": "body", + "in": "body", + "required": True + } + ] + ], [ "queries_cases_get_v1", "GET", diff --git a/src/falconpy/_endpoint/_cloud_google_cloud_registration.py b/src/falconpy/_endpoint/_cloud_google_cloud_registration.py index faa9c3df5..683f98217 100644 --- a/src/falconpy/_endpoint/_cloud_google_cloud_registration.py +++ b/src/falconpy/_endpoint/_cloud_google_cloud_registration.py @@ -90,7 +90,7 @@ { "type": "boolean", "default": False, - "description": "Include entities with any registration status (default: False)", + "description": "Include entities with any registration status (default: false)", "name": "include_all_statuses", "in": "query" } diff --git a/src/falconpy/_endpoint/_cloud_oci_registration.py b/src/falconpy/_endpoint/_cloud_oci_registration.py index d6997902d..1e19d8daf 100644 --- a/src/falconpy/_endpoint/_cloud_oci_registration.py +++ b/src/falconpy/_endpoint/_cloud_oci_registration.py @@ -47,15 +47,15 @@ { "type": "string", "description": "FQL (Falcon Query Language) string for filtering results. Allowed filters are " - "Set{overall_status, created_at, updated_at, registration_name, tenancy_ocid, tenancy_name, home_region, " - "key_age}", + "Set{home_region, key_age, overall_status, created_at, updated_at, registration_name, tenancy_ocid, " + "tenancy_name}", "name": "filter", "in": "query" }, { "type": "string", - "description": "Field and direction for sorting results - allowed sort fields are Set{created_at, " - "updated_at, registration_name, tenancy_ocid, tenancy_name, home_region, key_age, overall_status}", + "description": "Field and direction for sorting results - allowed sort fields are Set{home_region, " + "key_age, overall_status, created_at, updated_at, registration_name, tenancy_ocid, tenancy_name}", "name": "sort", "in": "query" }, diff --git a/src/falconpy/_endpoint/_cloud_policies.py b/src/falconpy/_endpoint/_cloud_policies.py index d288ab28b..73b860aef 100644 --- a/src/falconpy/_endpoint/_cloud_policies.py +++ b/src/falconpy/_endpoint/_cloud_policies.py @@ -688,11 +688,11 @@ "type": "string", "description": "FQL filter, allowed properties: \n\t\n*rule_auto_remediable*\t\n*rule_category*\t\n*ru " "le_cloneable*\t\n*rule_compliance_benchmark*\t\n*rule_compliance_benchmark_uuid*\t\n*rule_compliance_framework " - "*\t\n*rule_control_requirement*\t\n*rule_control_section*\t\n*rule_created_at*\t\n*rule_description*\t\n*rule_" - "domain*\t\n*rule_mitre_tactic*\t\n*rule_mitre_technique*\t\n*rule_name*\t\n*rule_origin*\t\n*rule_parent_uuid* " - "\t\n*rule_provider*\t\n*rule_resource_type*\t\n*rule_resource_type_name*\t\n*rule_risk_factor*\t\n*rule_annota " - "tion_status*\t\n*rule_service*\t\n*rule_severity*\t\n*rule_short_code*\t\n*rule_status*\t\n*rule_subdomain*\t\n" - "*rule_updated_at*\t\n*rule_updated_by*\t\n", + "*\t\n*rule_control_requirement*\t\n*rule_control_section*\t\n*rule_created_at*\t\n*rule_deleted_at*\t\n*rule_d " + "escription*\t\n*rule_domain*\t\n*rule_mitre_tactic*\t\n*rule_mitre_technique*\t\n*rule_name*\t\n*rule_origin*\t" + "\n*rule_parent_uuid*\t\n*rule_provider*\t\n*rule_resource_type*\t\n*rule_resource_type_name*\t\n*rule_risk_fa " + "ctor*\t\n*rule_annotation_status*\t\n*rule_service*\t\n*rule_severity*\t\n*rule_short_code*\t\n*rule_status*\t" + "\n*rule_subdomain*\t\n*rule_updated_at*\t\n*rule_updated_by*\t\n", "name": "filter", "in": "query" }, @@ -714,11 +714,12 @@ "type": "string", "description": "Field to sort on. Sortable fields: \n\t\n*rule_auto_remediable*\t\n*rule_category*\t\n" "*rule_cloneable*\t\n*rule_compliance_benchmark*\t\n*rule_compliance_benchmark_uuid*\t\n*rule_compliance_framew " - "ork*\t\n*rule_control_requirement*\t\n*rule_control_section*\t\n*rule_created_at*\t\n*rule_description*\t\n*ru " - "le_domain*\t\n*rule_mitre_tactic*\t\n*rule_mitre_technique*\t\n*rule_name*\t\n*rule_origin*\t\n*rule_parent_uu " - "id*\t\n*rule_provider*\t\n*rule_resource_type*\t\n*rule_resource_type_name*\t\n*rule_risk_factor*\t\n*rule_ann " - "otation_status*\t\n*rule_service*\t\n*rule_severity*\t\n*rule_short_code*\t\n*rule_status*\t\n*rule_subdomain* " - "\t\n*rule_updated_at*\t\n*rule_updated_by*\t\n \n\nUse the |asc or |desc suffix to specify sort direction.", + "ork*\t\n*rule_control_requirement*\t\n*rule_control_section*\t\n*rule_created_at*\t\n*rule_deleted_at*\t\n*rul " + "e_description*\t\n*rule_domain*\t\n*rule_mitre_tactic*\t\n*rule_mitre_technique*\t\n*rule_name*\t\n*rule_origi " + "n*\t\n*rule_parent_uuid*\t\n*rule_provider*\t\n*rule_resource_type*\t\n*rule_resource_type_name*\t\n*rule_risk " + "_factor*\t\n*rule_annotation_status*\t\n*rule_service*\t\n*rule_severity*\t\n*rule_short_code*\t\n*rule_status " + "*\t\n*rule_subdomain*\t\n*rule_updated_at*\t\n*rule_updated_by*\t\n \n\nUse the |asc or |desc suffix to " + "specify sort direction.", "name": "sort", "in": "query" } diff --git a/src/falconpy/_endpoint/_cloud_security.py b/src/falconpy/_endpoint/_cloud_security.py index 610c329aa..fab91328a 100644 --- a/src/falconpy/_endpoint/_cloud_security.py +++ b/src/falconpy/_endpoint/_cloud_security.py @@ -106,7 +106,7 @@ }, { "type": "integer", - "default": "0", + "default": 0, "format": "int64", "description": "The starting position of the list operation.", "name": "offset", @@ -114,7 +114,7 @@ }, { "type": "integer", - "default": "100", + "default": 100, "format": "int64", "description": "The maximum number of cloud groups to retrieve.", "name": "limit", @@ -212,7 +212,7 @@ }, { "type": "integer", - "default": "0", + "default": 0, "format": "int64", "description": "The starting position of the list operation.", "name": "offset", @@ -220,7 +220,7 @@ }, { "type": "integer", - "default": "100", + "default": 100, "format": "int64", "description": "The maximum number of cloud groups to retrieve.", "name": "limit", diff --git a/src/falconpy/_endpoint/_cloud_security_assets.py b/src/falconpy/_endpoint/_cloud_security_assets.py index b7b137e32..613668b22 100644 --- a/src/falconpy/_endpoint/_cloud_security_assets.py +++ b/src/falconpy/_endpoint/_cloud_security_assets.py @@ -227,14 +227,16 @@ "data_classifications.tag_id environment exprt_ratings first_seen gcp.multi_region gcp.physical_region " "highest_severity id insights.boolean_value insights.date_value insights.id insights.integer_value " "insights.string_list_value insights.string_value instance_id instance_state ioa_count iom_count " - "legacy_resource_id legacy_uuid managed_by non_compliant.benchmark_name non_compliant.benchmark_version " - "non_compliant.framework non_compliant.policy_id non_compliant.requirement non_compliant.rule " - "non_compliant.rule_name non_compliant.section non_compliant.severity organization_Id os_version " - "platform_name publicly_exposed region resource_gcrn resource_id resource_name resource_parent " - "resource_type resource_type_name sensor_priority service service_category severity snapshot_detections " - "ssm_managed status tag_key tag_value tags tags_string tenant_id updated_at vmware.guest_os_id " - "vmware.guest_os_version vmware.host_system_name vmware.host_type vmware.instance_uuid vmware.vm_host_name " - "vmware.vm_tools_status zone", + "kubernetes.cluster_id kubernetes.cluster_name kubernetes.kind kubernetes.label_keys kubernetes.labels " + "kubernetes.managed_cloud_provider kubernetes.name kubernetes.namespace legacy_resource_id legacy_uuid " + "managed_by non_compliant.benchmark_name non_compliant.benchmark_version non_compliant.framework " + "non_compliant.policy_id non_compliant.requirement non_compliant.rule non_compliant.rule_name " + "non_compliant.section non_compliant.severity organization_Id os_version platform_name publicly_exposed " + "region resource_gcrn resource_id resource_name resource_parent resource_type resource_type_name " + "sensor_priority service service_category severity snapshot_detections ssm_managed status tag_key " + "tag_value tags tags_string tenant_id updated_at vmware.guest_os_id vmware.guest_os_version " + "vmware.host_system_name vmware.host_type vmware.instance_uuid vmware.vm_host_name vmware.vm_tools_status " + "zone", "name": "filter", "in": "query" }, @@ -244,13 +246,14 @@ "aspm.deployment_cloud_resource_id aspm.deployment_provider aspm.deployment_type aspm.exprt_rating " "aspm.technologies cloud_provider cloud_risks.open_risk_count cluster_id cluster_name compartment_name " "compartment_ocid compartment_path creation_time data_classifications.found data_classifications.scanned " - "first_seen id instance_id instance_state ioa_count iom_count managed_by organization_Id os_version " - "platform_name publicly_exposed region resource_id resource_name resource_parent resource_type " - "resource_type_name service service_category ssm_managed status tenancy_name tenancy_ocid tenancy_type " - "tenant_id updated_at vmware.guest_os_id vmware.guest_os_version vmware.host_system_name vmware.host_type " - " vmware.instance_uuid vmware.vm_host_name vmware.vm_tools_status zone publiclyExposedToTheInternet " - "publiclyExposedAccessRange publiclyExposedExposureMethod\n\nUse |asc or |desc suffix to specify sort " - "direction.", + "first_seen id instance_id instance_state ioa_count iom_count kubernetes.cluster_id " + "kubernetes.cluster_name kubernetes.kind kubernetes.managed_cloud_provider kubernetes.name " + "kubernetes.namespace managed_by organization_Id os_version platform_name publicly_exposed region " + "resource_id resource_name resource_parent resource_type resource_type_name service service_category " + "ssm_managed status tenancy_name tenancy_ocid tenancy_type tenant_id updated_at vmware.guest_os_id " + "vmware.guest_os_version vmware.host_system_name vmware.host_type vmware.instance_uuid vmware.vm_host_name " + " vmware.vm_tools_status zone publiclyExposedToTheInternet publiclyExposedAccessRange " + "publiclyExposedExposureMethod\n\nUse |asc or |desc suffix to specify sort direction.", "name": "sort", "in": "query" }, diff --git a/src/falconpy/_endpoint/_data_protection_configuration.py b/src/falconpy/_endpoint/_data_protection_configuration.py index 407610b7f..0ac99b573 100644 --- a/src/falconpy/_endpoint/_data_protection_configuration.py +++ b/src/falconpy/_endpoint/_data_protection_configuration.py @@ -839,9 +839,9 @@ { "type": "string", "description": "Filter results by specific attributes , allowed attributes are " - "[properties.evidence_duplication_enabled properties.protection_mode properties.sensitivity_labels modified_at " - "properties.content_patterns_operator properties.file_types properties.web_sources name created_at created_by " - "modified_by properties.content_patterns]", + "[properties.content_patterns_operator properties.protection_mode name created_by modified_at " + "properties.content_patterns properties.evidence_duplication_enabled properties.file_types " + "properties.sensitivity_labels properties.web_sources created_at modified_by]", "name": "filter", "in": "query" }, @@ -1153,26 +1153,27 @@ }, { "type": "string", - "description": "Filter results by specific attributes , allowed attributes are [name " - "properties.enable_end_user_notifications_unsupported_browser properties.block_notifications " - "properties.evidence_encrypted_enabled properties.be_paste_timeout_duration_milliseconds " - "properties.be_paste_clipboard_max_size properties.be_paste_clipboard_over_size_behaviour_block description " - "precedence modified_at properties.enable_context_inspection properties.inspection_depth " - "properties.be_paste_clipboard_min_size_unit is_enabled properties.enable_content_inspection " - "properties.browsers_without_active_extension properties.block_all_data_access properties.similarity_threshold " - "properties.enable_clipboard_web_origin properties.custom_allow_notification " - "properties.evidence_download_enabled properties.similarity_detection properties.enable_network_inspection " - "properties.network_inspection_files_exceeding_size_limit properties.be_exclude_domains " - "properties.besplash_message_source properties.be_paste_clipboard_min_size properties.max_file_size_to_inspect " - "properties.screen_capture_duration_pre_event is_default properties.min_confidence_level " - "properties.besplash_enabled properties.besplash_custom_message properties.be_upload_timeout_response " - "properties.evidence_storage_free_disk_perc properties.screen_capture_duration_post_event created_at " - "modified_by properties.max_file_size_to_inspect_unit properties.enable_screen_capture properties.enable_ocr " - "properties.network_inspection_exclude_list_v2 created_by properties.enable_clipboard_inspection " - "properties.allow_notifications properties.classifications properties.be_upload_timeout_duration_seconds " - "properties.be_paste_clipboard_max_size_unit properties.evidence_storage_max_size properties.euj_dialog_timeout " - " properties.custom_block_notification properties.evidence_duplication_enabled_default " - "properties.be_paste_timeout_response properties.enable_print_monitor]", + "description": "Filter results by specific attributes , allowed attributes are " + "[properties.enable_context_inspection properties.similarity_threshold " + "properties.enable_end_user_notifications_unsupported_browser properties.besplash_custom_message " + "properties.be_paste_clipboard_min_size properties.evidence_storage_free_disk_perc " + "properties.max_file_size_to_inspect is_enabled is_default created_by properties.be_paste_clipboard_max_size " + "properties.screen_capture_duration_post_event properties.enable_ocr properties.block_all_data_access " + "properties.enable_clipboard_web_origin properties.evidence_duplication_enabled_default " + "properties.be_upload_timeout_duration_seconds properties.be_paste_clipboard_min_size_unit " + "properties.evidence_storage_max_size properties.enable_screen_capture properties.enable_print_monitor " + "properties.min_confidence_level properties.allow_notifications properties.custom_block_notification " + "properties.besplash_enabled properties.be_paste_timeout_response " + "properties.be_paste_clipboard_over_size_behaviour_block properties.euj_dialog_timeout " + "properties.screen_capture_duration_pre_event properties.inspection_depth " + "properties.browsers_without_active_extension properties.network_inspection_exclude_list_v2 precedence " + "created_at modified_at properties.similarity_detection properties.block_notifications " + "properties.evidence_download_enabled properties.evidence_encrypted_enabled properties.classifications " + "properties.enable_content_inspection properties.max_file_size_to_inspect_unit " + "properties.network_inspection_files_exceeding_size_limit properties.be_upload_timeout_response " + "properties.be_paste_timeout_duration_milliseconds properties.be_paste_clipboard_max_size_unit description " + "modified_by host_groups properties.enable_clipboard_inspection properties.custom_allow_notification " + "properties.enable_network_inspection properties.be_exclude_domains properties.besplash_message_source name]", "name": "filter", "in": "query" }, @@ -1195,7 +1196,7 @@ }, { "type": "string", - "description": "The property to sort by, allowed fields are :[precedence created_at modified_at name]", + "description": "The property to sort by, allowed fields are :[name precedence created_at modified_at]", "name": "sort", "in": "query" } diff --git a/src/falconpy/_endpoint/_eval_cases.py b/src/falconpy/_endpoint/_eval_cases.py new file mode 100644 index 000000000..798aa50ec --- /dev/null +++ b/src/falconpy/_endpoint/_eval_cases.py @@ -0,0 +1,108 @@ +"""Internal API endpoint constant library. + + _______ __ _______ __ __ __ +| _ .----.-----.--.--.--.--| | _ | |_.----|__| |--.-----. +|. 1___| _| _ | | | | _ | 1___| _| _| | <| -__| +|. |___|__| |_____|________|_____|____ |____|__| |__|__|__|_____| +|: 1 | |: 1 | +|::.. . | CROWDSTRIKE FALCON |::.. . | FalconPy +`-------' `-------' + +OAuth2 API - Customer SDK + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to +""" + +_eval_cases_endpoints = [ + [ + "EntitiesEvalCasesV1", + "GET", + "/agentic-studio-evals/entities/cases/v1", + "Retrieve evaluation case entities for the provided id.", + "eval_cases", + [ + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "description": "IDs of entities to retrieve.", + "name": "ids", + "in": "query", + "required": True + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" + } + ] + ], + [ + "QueriesEvalCasesV1", + "GET", + "/agentic-studio-evals/queries/cases/v1", + "Query evaluation cases based on the provided filters. Optional run_id filter parameter.", + "eval_cases", + [ + { + "type": "integer", + "description": "Starting index of overall result set from which to return ids.", + "name": "offset", + "in": "query" + }, + { + "type": "integer", + "default": 30, + "maximum": 500, + "minimum": 1, + "description": "Number of IDs to return. Offset + limit should NOT be above 10K.", + "name": "limit", + "in": "query" + }, + { + "type": "string", + "description": "Possible order by fields: created_at. Ex: 'created_at|desc' or 'created_at|asc'.", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "description": "FQL query specifying the filter parameters.", + "name": "filter", + "in": "query" + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" + } + ] + ] +] diff --git a/src/falconpy/_endpoint/_eval_dataset_entries.py b/src/falconpy/_endpoint/_eval_dataset_entries.py new file mode 100644 index 000000000..69c73b33e --- /dev/null +++ b/src/falconpy/_endpoint/_eval_dataset_entries.py @@ -0,0 +1,160 @@ +"""Internal API endpoint constant library. + + _______ __ _______ __ __ __ +| _ .----.-----.--.--.--.--| | _ | |_.----|__| |--.-----. +|. 1___| _| _ | | | | _ | 1___| _| _| | <| -__| +|. |___|__| |_____|________|_____|____ |____|__| |__|__|__|_____| +|: 1 | |: 1 | +|::.. . | CROWDSTRIKE FALCON |::.. . | FalconPy +`-------' `-------' + +OAuth2 API - Customer SDK + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to +""" + +_eval_dataset_entries_endpoints = [ + [ + "EntitiesEvalDatasetEntriesV1", + "GET", + "/agentic-studio-evals/entities/dataset-entries/v1", + "Retrieve evaluation dataset entry entities for the provided id.", + "eval_dataset_entries", + [ + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "description": "IDs of entities to retrieve.", + "name": "ids", + "in": "query", + "required": True + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" + } + ] + ], + [ + "EntitiesEvalDatasetEntriesUpdateV1", + "PUT", + "/agentic-studio-evals/entities/dataset-entries/v1", + "Update an existing evaluation dataset entry.", + "eval_dataset_entries", + [ + { + "description": "Evaluation dataset entry definition with updated fields", + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "EntitiesEvalDatasetEntriesCreateV1", + "POST", + "/agentic-studio-evals/entities/dataset-entries/v1", + "Create a new evaluation dataset entry.", + "eval_dataset_entries", + [ + { + "description": "Evaluation dataset entry definition to create", + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "EntitiesEvalDatasetEntriesDeleteV1", + "DELETE", + "/agentic-studio-evals/entities/dataset-entries/v1", + "Delete an evaluation dataset entry.", + "eval_dataset_entries", + [ + { + "type": "string", + "description": "ID of the dataset entry to delete", + "name": "id", + "in": "query", + "required": True + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" + } + ] + ], + [ + "QueriesEvalDatasetEntriesV1", + "GET", + "/agentic-studio-evals/queries/dataset-entries/v1", + "Query evaluation dataset entries based on the provided filters. Requires dataset_id parameter.", + "eval_dataset_entries", + [ + { + "type": "integer", + "description": "Starting index of overall result set from which to return ids.", + "name": "offset", + "in": "query" + }, + { + "type": "integer", + "default": 30, + "maximum": 500, + "minimum": 1, + "description": "Number of IDs to return. Offset + limit should NOT be above 10K.", + "name": "limit", + "in": "query" + }, + { + "type": "string", + "description": "Possible order by fields: name, created_at. Ex: 'created_at|desc' or 'name|asc'.", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "description": "FQL query specifying the filter parameters.", + "name": "filter", + "in": "query" + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" + } + ] + ] +] diff --git a/src/falconpy/_endpoint/_eval_datasets.py b/src/falconpy/_endpoint/_eval_datasets.py new file mode 100644 index 000000000..902664dfb --- /dev/null +++ b/src/falconpy/_endpoint/_eval_datasets.py @@ -0,0 +1,182 @@ +"""Internal API endpoint constant library. + + _______ __ _______ __ __ __ +| _ .----.-----.--.--.--.--| | _ | |_.----|__| |--.-----. +|. 1___| _| _ | | | | _ | 1___| _| _| | <| -__| +|. |___|__| |_____|________|_____|____ |____|__| |__|__|__|_____| +|: 1 | |: 1 | +|::.. . | CROWDSTRIKE FALCON |::.. . | FalconPy +`-------' `-------' + +OAuth2 API - Customer SDK + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to +""" + +_eval_datasets_endpoints = [ + [ + "EntitiesEvalDatasetsDownloadV1", + "GET", + "/agentic-studio-evals/entities/datasets/download/v1", + "Download all entries of an evaluation dataset as CSV.", + "eval_datasets", + [ + { + "type": "string", + "description": "ID of the dataset to download", + "name": "id", + "in": "query", + "required": True + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" + } + ] + ], + [ + "EntitiesEvalDatasetsV1", + "GET", + "/agentic-studio-evals/entities/datasets/v1", + "Retrieve evaluation dataset entities for the provided id.", + "eval_datasets", + [ + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "description": "IDs of entities to retrieve.", + "name": "ids", + "in": "query", + "required": True + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" + } + ] + ], + [ + "EntitiesEvalDatasetsUpdateV1", + "PUT", + "/agentic-studio-evals/entities/datasets/v1", + "Update an existing evaluation dataset.", + "eval_datasets", + [ + { + "description": "Evaluation dataset definition with updated fields", + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "EntitiesEvalDatasetsCreateV1", + "POST", + "/agentic-studio-evals/entities/datasets/v1", + "Create or update an evaluation dataset.", + "eval_datasets", + [ + { + "description": "Evaluation dataset definition to create", + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "EntitiesEvalDatasetsDeleteV1", + "DELETE", + "/agentic-studio-evals/entities/datasets/v1", + "Delete an evaluation dataset by ID.", + "eval_datasets", + [ + { + "type": "string", + "description": "ID of the dataset to delete", + "name": "id", + "in": "query", + "required": True + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" + } + ] + ], + [ + "QueriesEvalDatasetsV1", + "GET", + "/agentic-studio-evals/queries/datasets/v1", + "Query evaluation datasets based on the provided filters.", + "eval_datasets", + [ + { + "type": "integer", + "description": "Starting index of overall result set from which to return ids.", + "name": "offset", + "in": "query" + }, + { + "type": "integer", + "default": 30, + "maximum": 500, + "minimum": 1, + "description": "Number of IDs to return. Offset + limit should NOT be above 10K.", + "name": "limit", + "in": "query" + }, + { + "type": "string", + "description": "Possible order by fields: name, created_at. Ex: 'created_at|desc' or 'name|asc'.", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "description": "FQL query specifying the filter parameters.", + "name": "filter", + "in": "query" + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" + } + ] + ] +] diff --git a/src/falconpy/_endpoint/_eval_evaluators.py b/src/falconpy/_endpoint/_eval_evaluators.py new file mode 100644 index 000000000..56b215f60 --- /dev/null +++ b/src/falconpy/_endpoint/_eval_evaluators.py @@ -0,0 +1,160 @@ +"""Internal API endpoint constant library. + + _______ __ _______ __ __ __ +| _ .----.-----.--.--.--.--| | _ | |_.----|__| |--.-----. +|. 1___| _| _ | | | | _ | 1___| _| _| | <| -__| +|. |___|__| |_____|________|_____|____ |____|__| |__|__|__|_____| +|: 1 | |: 1 | +|::.. . | CROWDSTRIKE FALCON |::.. . | FalconPy +`-------' `-------' + +OAuth2 API - Customer SDK + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to +""" + +_eval_evaluators_endpoints = [ + [ + "EntitiesEvalEvaluatorsV1", + "GET", + "/agentic-studio-evals/entities/evaluators/v1", + "Retrieve evaluation evaluator entities for the provided id.", + "eval_evaluators", + [ + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "description": "IDs of entities to retrieve.", + "name": "ids", + "in": "query", + "required": True + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" + } + ] + ], + [ + "EntitiesEvalEvaluatorsUpdateV1", + "PUT", + "/agentic-studio-evals/entities/evaluators/v1", + "Update an existing evaluation evaluator.", + "eval_evaluators", + [ + { + "description": "Evaluation evaluator definition with updated fields", + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "EntitiesEvalEvaluatorsCreateV1", + "POST", + "/agentic-studio-evals/entities/evaluators/v1", + "Create or update an evaluation evaluator. For deletion, provide evaluator with IsDeleted=true.", + "eval_evaluators", + [ + { + "description": "Evaluation evaluator definition to create or update", + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "EntitiesEvalEvaluatorsDeleteV1", + "DELETE", + "/agentic-studio-evals/entities/evaluators/v1", + "Delete an evaluation evaluator by ID.", + "eval_evaluators", + [ + { + "type": "string", + "description": "ID of the evaluator to delete", + "name": "id", + "in": "query", + "required": True + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" + } + ] + ], + [ + "QueriesEvalEvaluatorsV1", + "GET", + "/agentic-studio-evals/queries/evaluators/v1", + "Query evaluation evaluators based on the provided filters.", + "eval_evaluators", + [ + { + "type": "integer", + "description": "Starting index of overall result set from which to return ids.", + "name": "offset", + "in": "query" + }, + { + "type": "integer", + "default": 30, + "maximum": 500, + "minimum": 1, + "description": "Number of IDs to return. Offset + limit should NOT be above 10K.", + "name": "limit", + "in": "query" + }, + { + "type": "string", + "description": "Possible order by fields: name, created_at. Ex: 'created_at|desc' or 'name|asc'.", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "description": "FQL query specifying the filter parameters.", + "name": "filter", + "in": "query" + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" + } + ] + ] +] diff --git a/src/falconpy/_endpoint/_eval_runs.py b/src/falconpy/_endpoint/_eval_runs.py new file mode 100644 index 000000000..a7e65de66 --- /dev/null +++ b/src/falconpy/_endpoint/_eval_runs.py @@ -0,0 +1,171 @@ +"""Internal API endpoint constant library. + + _______ __ _______ __ __ __ +| _ .----.-----.--.--.--.--| | _ | |_.----|__| |--.-----. +|. 1___| _| _ | | | | _ | 1___| _| _| | <| -__| +|. |___|__| |_____|________|_____|____ |____|__| |__|__|__|_____| +|: 1 | |: 1 | +|::.. . | CROWDSTRIKE FALCON |::.. . | FalconPy +`-------' `-------' + +OAuth2 API - Customer SDK + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to +""" + +_eval_runs_endpoints = [ + [ + "EntitiesEvalRunsV1", + "GET", + "/agentic-studio-evals/entities/runs/v1", + "Retrieve evaluation run entities for the provided id.", + "eval_runs", + [ + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "description": "IDs of entities to retrieve.", + "name": "ids", + "in": "query", + "required": True + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" + } + ] + ], + [ + "EntitiesEvalRunsCreateV1", + "POST", + "/agentic-studio-evals/entities/runs/v1", + "Create or update an evaluation run. For deletion, provide run with IsDeleted=true.", + "eval_runs", + [ + { + "description": "Evaluation run definition to create or update", + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "EntitiesEvalRunsDeleteV1", + "DELETE", + "/agentic-studio-evals/entities/runs/v1", + "Delete an evaluation run by ID.", + "eval_runs", + [ + { + "type": "string", + "description": "ID of the evaluation run to delete", + "name": "id", + "in": "query", + "required": True + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" + } + ] + ], + [ + "EntitiesEvalRunsActionV1", + "POST", + "/agentic-studio-evals/entities/runs/v1/action", + "Perform an action on an evaluation run (start or stop).", + "eval_runs", + [ + { + "type": "string", + "description": "ID of the evaluation run", + "name": "id", + "in": "query" + }, + { + "type": "string", + "description": "Action to perform: 'start' or 'stop'", + "name": "action_name", + "in": "query" + }, + { + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "QueriesEvalRunsV1", + "GET", + "/agentic-studio-evals/queries/runs/v1", + "Query evaluation runs based on the provided filters.", + "eval_runs", + [ + { + "type": "integer", + "description": "Starting index of overall result set from which to return ids.", + "name": "offset", + "in": "query" + }, + { + "type": "integer", + "default": 30, + "maximum": 500, + "minimum": 1, + "description": "Number of IDs to return. Offset + limit should NOT be above 10K.", + "name": "limit", + "in": "query" + }, + { + "type": "string", + "description": "Possible order by fields: name, created_at. Ex: 'created_at|desc' or 'name|asc'.", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "description": "FQL query specifying the filter parameters.", + "name": "filter", + "in": "query" + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" + } + ] + ] +] diff --git a/src/falconpy/_endpoint/_falconx_sandbox.py b/src/falconpy/_endpoint/_falconx_sandbox.py index b99822013..eb9256ca4 100644 --- a/src/falconpy/_endpoint/_falconx_sandbox.py +++ b/src/falconpy/_endpoint/_falconx_sandbox.py @@ -266,7 +266,7 @@ "(optional): Command line script passed to the submitted file at runtime. Max length: 2048 " "characters\n\n**document_password** (optional): Auto-filled for Adobe or Office files that prompt for a " "password. Max length: 32 characters\n\n**enable_tor** (optional): Deprecated, please use network_settings " - "instead. If true, sandbox analysis routes network traffic via TOR. Default: False.\n\n**network_settings** " + "instead. If true, sandbox analysis routes network traffic via TOR. Default: false.\n\n**network_settings** " "(optional): Specifies the sandbox network_settings used for analysis. Values:\n default: Fully operating " "network tor: Route network traffic via TOR simulated: Simulate network traffic offline: No network " "traffic\n\n**submit_name** (optional): Name of the malware sample that's used for file type detection and " @@ -412,7 +412,7 @@ "default": True, "description": "Defines visibility of this file in Falcon MalQuery, either via the API or the Falcon " "console.\n true: File is only shown to users within your customer account false: File can be seen by other " - "CrowdStrike customers \n\nDefault: True.", + "CrowdStrike customers \n\nDefault: true.", "name": "is_confidential", "in": "formData" } diff --git a/src/falconpy/_endpoint/_hosts.py b/src/falconpy/_endpoint/_hosts.py index 2c4b63a2c..f82862dce 100644 --- a/src/falconpy/_endpoint/_hosts.py +++ b/src/falconpy/_endpoint/_hosts.py @@ -61,204 +61,207 @@ { "type": "string", "enum": [ - "config_id_platform", + "cpu_vendor", + "last_login_uid", + "system_product_name", + "device_policies.firewall.rule_set_id", + "managed_apps.airlock.version", + "pod_namespace", + "default_gateway_ip", + "os_product_name", + "linux_sensor_mode", + "agent_version", "hostname", - "device_policies.data-protection.applied", - "device_policies.remote_response.policy_id", - "external_ip", - "device_policies.ztl.applied", - "device_policies.system-tray.applied", - "device_policies.mobile.applied", - "managed_apps.automox.version", - "email", - "detection_suppression_status", - "device_policies.sensor_update.policy_id", - "device_policies.fim.applied", - "managed_apps.netskope.version", - "connection_mac_address", - "device_policies.aidr.policy_id", - "last_login_user_sid", - "device_policies.prevention.applied", - "device_policies.jumpcloud.policy_id", - "device_policies.aws-verified-access.applied", - "internet_exposure", - "machine_domain", + "product_type", "policy_id", - "device_policies.sensor_update.uninstall_protection", - "device_policies.kubernetes-admission-control.policy_type", - "device_policies.consumer-subscription.policy_type", - "local_ip.raw", - "host_utc_offset", - "device_id", - "platform_name", - "device_policies.identity-protection.policy_type", - "device_policies.sca.policy_type", - "cid", - "k8s_cluster_version", - "os_product_name", - "device_policies.logscale-collector.policy_id", - "device_policies.fem-browser-extension-control.policy_id", - "release_group", - "system_product_name", "policies.policy_type", - "device_policies.fim.policy_id", - "device_policies.host-retention.policy_type", - "pod_annotations", - "k8s_cluster_git_version", - "device_policies.application-abuse-prevention.policy_id", - "config_id_build", - "platform_id", - "device_policies.identity-protection.policy_id", - "device_policies.firewall.applied", - "ou", - "device_policies.netskope.applied", - "device_policies.ztl.policy_type", - "pod_labels", - "pod_service_account_name", - "deployment_type", - "device_policies.browser-extension.policy_id", - "criticality", - "device_policies.it-automation.policy_type", - "group_hash", - "pod_id", + "device_policies.device_control.policy_id", + "device_policies.vulnerability-management.policy_id", + "device_policies.application-abuse-prevention.applied", + "device_policies.jumpcloud.policy_type", "last_reboot", - "agent_version", - "first_login_timestamp", - "first_seen", - "os_build", - "product_type", - "device_policies.netskope.policy_type", - "pointer_size", - "device_policies.fem-browser-extension-control.policy_type", - "device_policies.prevention.policy_type", - "device_policies.device_control.policy_type", - "device_policies.device_control.applied", - "device_policies.cloud-ml.policy_type", - "device_policies.cloud-ml.policy_id", + "device_policies.exposure-management.policy_id", + "device_policies.logscale-collector.applied", + "device_policies.aidr.applied", + "config_id_build", + "config_id_platform", + "site_name", + "mac_address", "instance_id", + "service_provider_account_id", + "agent_load_flags", + "external_ip", + "os_version", + "device_policies.kubernetes-admission-control.policy_id", + "tags", + "kernel_version", + "pod_host_ip6", + "license_activation_state", + "policies.policy_id", "rtr_state", - "device_policies.fem-browser-extension-control.applied", - "last_login_timestamp", - "modified_timestamp", - "device_policies.jumpcloud.policy_type", - "device_policies.it-automation.policy_id", - "cloud_service_compartment_id", - "device_policies.exposure-management.policy_id", + "pod_ip6", + "k8s_cluster_git_version", + "device_policies.network-scan-content.policy_id", "bios_version", + "device_policies.identity-endpoint.policy_type", + "device_policies.cloud-container-workload.policy_id", + "managed_apps.automox.version", + "device_policies.remote_response.policy_type", + "device_policies.fem-browser-extension-control.policy_id", "major_version", - "device_policies.jumpcloud.applied", - "device_policies.vulnerability-management.policy_id", - "device_policies.vulnerability-management.applied", + "device_policies.system-tray.policy_id", + "device_policies.system-tray.applied", + "device_policies.content-update.applied", "device_policies.data-protection-cloud.applied", - "migration_completed_time", - "device_policies.browser-extension.applied", - "bios_manufacturer", - "site_name", + "device_policies.mobile.policy_type", + "cpu_signature", + "device_policies.logscale-collector.policy_id", + "device_policies.sensor_update.policy_type", + "device_policies.cloud-ml.policy_id", + "device_policies.aws-verified-access.policy_type", + "device_policies.aws-verified-access.applied", + "chassis_type", + "first_login_user", "system_manufacturer", - "device_policies.airlock.applied", - "device_policies.identity-protection.applied", + "device_policies.cloud-container-workload.policy_type", + "device_policies.content-update.policy_id", + "device_policies.firewall.applied", + "k8s_cluster_version", + "cid", + "machine_domain", + "device_policies.prevention.applied", + "device_policies.netskope.applied", + "device_policies.data-protection.policy_type", + "pod_host_ip4", + "pod_name", + "detection_suppression_status", + "first_login_timestamp", + "device_policies.sensor_update.uninstall_protection", + "device_policies.system-tray.policy_type", + "email", + "k8s_cluster_id", + "k8s_node_uid", + "device_policies.exposure-management.applied", + "device_policies.fem-browser-extension-control.policy_type", + "first_seen", + "device_policies.device_control.policy_type", + "device_policies.automox.policy_id", "device_policies.vulnerability-management.policy_type", - "device_policies.host-retention.policy_id", - "device_policies.firewall.rule_set_id", - "safe_mode", - "os_version", - "status", - "device_policies.identity-endpoint.policy_id", - "device_policies.it-automation.applied", "_all", - "device_policies.mobile.policy_type", - "cpu_signature", + "device_policies.remote_response.applied", + "pod_ip4", + "pod_service_account_name", + "platform_id", + "status", + "device_policies.consumer-subscription.policy_id", + "service_provider", + "device_policies.remote_response.policy_id", + "serial_number", + "device_policies.browser-extension.policy_type", + "device_policies.exposure-management.policy_type", + "last_login_user", + "criticality", + "pod_id", + "device_policies.ztl.policy_type", + "device_policies.content-update.policy_type", + "pod_annotations", + "device_policies.browser-extension.policy_id", + "device_policies.browser-extension.applied", + "device_id", "device_policies.airlock.policy_id", + "device_policies.fim.applied", + "device_policies.sca.policy_id", + "connection_ip", + "cloud_service_compartment_id", + "device_policies.fem-browser-extension-control.applied", + "device_policies.application-abuse-prevention.policy_type", + "last_seen", "device_policies.data-protection-cloud.policy_type", - "k8s_cluster_id", - "chassis_type_desc", - "device_policies.browser-extension.policy_type", - "device_policies.exposure-management.applied", - "device_policies.logscale-collector.applied", - "device_policies.application-abuse-prevention.applied", + "device_policies.host-retention.policy_type", + "group_hash", + "pointer_size", + "deployment_type", + "filesystem_containment_status", + "device_policies.logscale-collector.policy_type", + "bios_manufacturer", + "device_policies.netskope.policy_type", + "device_policies.jumpcloud.policy_id", + "device_policies.sca.policy_type", "device_policies.sca.applied", - "device_policies.data-protection-cloud.policy_id", - "pod_namespace", - "k8s_node_uid", - "chassis_type", + "managed_apps.jumpcloud.version", + "connection_mac_address", + "device_policies.application-abuse-prevention.policy_id", "config_id_base", - "device_policies.device_control.policy_id", - "device_policies.identity-endpoint.policy_type", - "mac_address", + "device_policies.sensor_update.policy_id", + "device_policies.consumer-subscription.applied", + "device_policies.data-protection-cloud.policy_id", + "groups", + "device_policies.firewall.policy_id", + "managed_apps.netskope.version", + "minor_version", + "os_build", + "policies.applied", + "device_policies.netskope.policy_id", + "device_policies.identity-protection.applied", + "device_policies.data-protection.applied", + "device_policies.cloud-ml.applied", "managed_apps.identity-protection.version", - "managed_apps.aws-verified-access.version", - "kernel_version", + "chassis_type_desc", + "local_ip", "device_policies.automox.applied", - "device_policies.system-tray.policy_type", + "device_policies.identity-protection.policy_id", + "device_policies.jumpcloud.applied", + "device_policies.aws-verified-access.policy_id", + "device_policies.mobile.policy_id", + "migration_completed_time", + "modified_timestamp", + "pod_labels", + "device_policies.prevention.policy_id", + "device_policies.identity-protection.policy_type", + "device_policies.identity-endpoint.policy_id", + "device_policies.kubernetes-admission-control.policy_type", "device_policies.fim.policy_type", - "device_policies.content-update.policy_id", - "service_provider", - "default_gateway_ip", - "filesystem_containment_status", - "device_policies.aidr.applied", - "last_login_user", - "device_policies.consumer-subscription.policy_id", - "service_provider_account_id", - "reduced_functionality_mode", - "zone_group", + "device_policies.consumer-subscription.policy_type", + "device_policies.cloud-ml.policy_type", + "device_policies.data-protection.policy_id", + "last_login_user_sid", "device_policies.sensor_update.applied", - "device_policies.host-retention.applied", - "device_policies.firewall.policy_type", - "device_policies.mobile.policy_id", - "pod_ip4", - "linux_sensor_mode", - "device_policies.network-scan-content.policy_id", - "minor_version", - "device_policies.sensor_update.policy_type", "device_policies.identity-endpoint.applied", - "device_policies.sca.policy_id", - "device_policies.data-protection.policy_id", - "device_policies.firewall.policy_id", - "device_policies.remote_response.applied", - "pod_host_ip4", - "device_policies.prevention.policy_id", - "device_policies.automox.policy_id", - "device_policies.ztl.policy_id", - "device_policies.consumer-subscription.applied", - "device_policies.cloud-ml.applied", - "device_policies.data-protection.policy_type", - "groups", - "managed_apps.jumpcloud.version", + "device_policies.cloud-container-workload.applied", + "device_policies.it-automation.applied", + "local_ip.raw", + "device_policies.firewall.policy_type", + "internet_exposure", + "device_policies.ztl.applied", + "device_policies.it-automation.policy_type", + "device_policies.host-retention.applied", + "device_policies.aidr.policy_type", "product_type_desc", - "policies.applied", - "managed_apps.airlock.version", - "pod_hostname", - "device_policies.network-scan-content.policy_type", - "device_policies.exposure-management.policy_type", - "device_policies.logscale-collector.policy_type", - "last_seen", - "device_policies.netskope.policy_id", - "device_policies.content-update.policy_type", - "device_policies.remote_response.policy_type", - "pod_ip6", - "pod_name", + "device_policies.airlock.policy_type", + "device_policies.airlock.applied", + "device_policies.kubernetes-admission-control.applied", + "device_policies.it-automation.policy_id", "device_policies.network-scan-content.applied", - "device_policies.aidr.policy_type", - "local_ip", - "policies.policy_id", + "device_policies.aidr.policy_id", + "release_group", + "managed_apps.aws-verified-access.version", + "device_policies.network-scan-content.policy_type", + "last_login_timestamp", + "device_policies.device_control.applied", + "device_policies.ztl.policy_id", + "reduced_functionality_mode", + "zone_group", + "pod_hostname", + "platform_name", + "device_policies.vulnerability-management.applied", + "host_utc_offset", + "safe_mode", + "ou", + "device_policies.prevention.policy_type", "device_policies.automox.policy_type", - "device_policies.kubernetes-admission-control.policy_id", - "device_policies.kubernetes-admission-control.applied", - "device_policies.system-tray.policy_id", - "device_policies.aws-verified-access.policy_id", - "license_activation_state", - "last_login_uid", - "device_policies.content-update.applied", - "device_policies.aws-verified-access.policy_type", - "connection_ip", - "device_policies.application-abuse-prevention.policy_type", - "first_login_user", - "device_policies.airlock.policy_type", - "tags", - "cpu_vendor", - "serial_number", - "pod_host_ip6", - "agent_load_flags" + "device_policies.fim.policy_id", + "device_policies.host-retention.policy_id", + "device_policies.mobile.applied" ], "description": "The property to sort by (e.g. status.desc or hostname.asc). If not specified, the " "default sort will be device_id.asc. This should be supplied for each consecutive call.", @@ -369,204 +372,207 @@ { "type": "string", "enum": [ - "config_id_platform", + "cpu_vendor", + "last_login_uid", + "system_product_name", + "device_policies.firewall.rule_set_id", + "managed_apps.airlock.version", + "pod_namespace", + "default_gateway_ip", + "os_product_name", + "linux_sensor_mode", + "agent_version", "hostname", - "device_policies.data-protection.applied", - "device_policies.remote_response.policy_id", - "external_ip", - "device_policies.ztl.applied", - "device_policies.system-tray.applied", - "device_policies.mobile.applied", - "managed_apps.automox.version", - "email", - "detection_suppression_status", - "device_policies.sensor_update.policy_id", - "device_policies.fim.applied", - "managed_apps.netskope.version", - "connection_mac_address", - "device_policies.aidr.policy_id", - "last_login_user_sid", - "device_policies.prevention.applied", - "device_policies.jumpcloud.policy_id", - "device_policies.aws-verified-access.applied", - "internet_exposure", - "machine_domain", + "product_type", "policy_id", - "device_policies.sensor_update.uninstall_protection", - "device_policies.kubernetes-admission-control.policy_type", - "device_policies.consumer-subscription.policy_type", - "local_ip.raw", - "host_utc_offset", - "device_id", - "platform_name", - "device_policies.identity-protection.policy_type", - "device_policies.sca.policy_type", - "cid", - "k8s_cluster_version", - "os_product_name", - "device_policies.logscale-collector.policy_id", - "device_policies.fem-browser-extension-control.policy_id", - "release_group", - "system_product_name", "policies.policy_type", - "device_policies.fim.policy_id", - "device_policies.host-retention.policy_type", - "pod_annotations", - "k8s_cluster_git_version", - "device_policies.application-abuse-prevention.policy_id", - "config_id_build", - "platform_id", - "device_policies.identity-protection.policy_id", - "device_policies.firewall.applied", - "ou", - "device_policies.netskope.applied", - "device_policies.ztl.policy_type", - "pod_labels", - "pod_service_account_name", - "deployment_type", - "device_policies.browser-extension.policy_id", - "criticality", - "device_policies.it-automation.policy_type", - "group_hash", - "pod_id", + "device_policies.device_control.policy_id", + "device_policies.vulnerability-management.policy_id", + "device_policies.application-abuse-prevention.applied", + "device_policies.jumpcloud.policy_type", "last_reboot", - "agent_version", - "first_login_timestamp", - "first_seen", - "os_build", - "product_type", - "device_policies.netskope.policy_type", - "pointer_size", - "device_policies.fem-browser-extension-control.policy_type", - "device_policies.prevention.policy_type", - "device_policies.device_control.policy_type", - "device_policies.device_control.applied", - "device_policies.cloud-ml.policy_type", - "device_policies.cloud-ml.policy_id", + "device_policies.exposure-management.policy_id", + "device_policies.logscale-collector.applied", + "device_policies.aidr.applied", + "config_id_build", + "config_id_platform", + "site_name", + "mac_address", "instance_id", + "service_provider_account_id", + "agent_load_flags", + "external_ip", + "os_version", + "device_policies.kubernetes-admission-control.policy_id", + "tags", + "kernel_version", + "pod_host_ip6", + "license_activation_state", + "policies.policy_id", "rtr_state", - "device_policies.fem-browser-extension-control.applied", - "last_login_timestamp", - "modified_timestamp", - "device_policies.jumpcloud.policy_type", - "device_policies.it-automation.policy_id", - "cloud_service_compartment_id", - "device_policies.exposure-management.policy_id", + "pod_ip6", + "k8s_cluster_git_version", + "device_policies.network-scan-content.policy_id", "bios_version", + "device_policies.identity-endpoint.policy_type", + "device_policies.cloud-container-workload.policy_id", + "managed_apps.automox.version", + "device_policies.remote_response.policy_type", + "device_policies.fem-browser-extension-control.policy_id", "major_version", - "device_policies.jumpcloud.applied", - "device_policies.vulnerability-management.policy_id", - "device_policies.vulnerability-management.applied", + "device_policies.system-tray.policy_id", + "device_policies.system-tray.applied", + "device_policies.content-update.applied", "device_policies.data-protection-cloud.applied", - "migration_completed_time", - "device_policies.browser-extension.applied", - "bios_manufacturer", - "site_name", + "device_policies.mobile.policy_type", + "cpu_signature", + "device_policies.logscale-collector.policy_id", + "device_policies.sensor_update.policy_type", + "device_policies.cloud-ml.policy_id", + "device_policies.aws-verified-access.policy_type", + "device_policies.aws-verified-access.applied", + "chassis_type", + "first_login_user", "system_manufacturer", - "device_policies.airlock.applied", - "device_policies.identity-protection.applied", + "device_policies.cloud-container-workload.policy_type", + "device_policies.content-update.policy_id", + "device_policies.firewall.applied", + "k8s_cluster_version", + "cid", + "machine_domain", + "device_policies.prevention.applied", + "device_policies.netskope.applied", + "device_policies.data-protection.policy_type", + "pod_host_ip4", + "pod_name", + "detection_suppression_status", + "first_login_timestamp", + "device_policies.sensor_update.uninstall_protection", + "device_policies.system-tray.policy_type", + "email", + "k8s_cluster_id", + "k8s_node_uid", + "device_policies.exposure-management.applied", + "device_policies.fem-browser-extension-control.policy_type", + "first_seen", + "device_policies.device_control.policy_type", + "device_policies.automox.policy_id", "device_policies.vulnerability-management.policy_type", - "device_policies.host-retention.policy_id", - "device_policies.firewall.rule_set_id", - "safe_mode", - "os_version", - "status", - "device_policies.identity-endpoint.policy_id", - "device_policies.it-automation.applied", "_all", - "device_policies.mobile.policy_type", - "cpu_signature", + "device_policies.remote_response.applied", + "pod_ip4", + "pod_service_account_name", + "platform_id", + "status", + "device_policies.consumer-subscription.policy_id", + "service_provider", + "device_policies.remote_response.policy_id", + "serial_number", + "device_policies.browser-extension.policy_type", + "device_policies.exposure-management.policy_type", + "last_login_user", + "criticality", + "pod_id", + "device_policies.ztl.policy_type", + "device_policies.content-update.policy_type", + "pod_annotations", + "device_policies.browser-extension.policy_id", + "device_policies.browser-extension.applied", + "device_id", "device_policies.airlock.policy_id", + "device_policies.fim.applied", + "device_policies.sca.policy_id", + "connection_ip", + "cloud_service_compartment_id", + "device_policies.fem-browser-extension-control.applied", + "device_policies.application-abuse-prevention.policy_type", + "last_seen", "device_policies.data-protection-cloud.policy_type", - "k8s_cluster_id", - "chassis_type_desc", - "device_policies.browser-extension.policy_type", - "device_policies.exposure-management.applied", - "device_policies.logscale-collector.applied", - "device_policies.application-abuse-prevention.applied", + "device_policies.host-retention.policy_type", + "group_hash", + "pointer_size", + "deployment_type", + "filesystem_containment_status", + "device_policies.logscale-collector.policy_type", + "bios_manufacturer", + "device_policies.netskope.policy_type", + "device_policies.jumpcloud.policy_id", + "device_policies.sca.policy_type", "device_policies.sca.applied", - "device_policies.data-protection-cloud.policy_id", - "pod_namespace", - "k8s_node_uid", - "chassis_type", + "managed_apps.jumpcloud.version", + "connection_mac_address", + "device_policies.application-abuse-prevention.policy_id", "config_id_base", - "device_policies.device_control.policy_id", - "device_policies.identity-endpoint.policy_type", - "mac_address", + "device_policies.sensor_update.policy_id", + "device_policies.consumer-subscription.applied", + "device_policies.data-protection-cloud.policy_id", + "groups", + "device_policies.firewall.policy_id", + "managed_apps.netskope.version", + "minor_version", + "os_build", + "policies.applied", + "device_policies.netskope.policy_id", + "device_policies.identity-protection.applied", + "device_policies.data-protection.applied", + "device_policies.cloud-ml.applied", "managed_apps.identity-protection.version", - "managed_apps.aws-verified-access.version", - "kernel_version", + "chassis_type_desc", + "local_ip", "device_policies.automox.applied", - "device_policies.system-tray.policy_type", + "device_policies.identity-protection.policy_id", + "device_policies.jumpcloud.applied", + "device_policies.aws-verified-access.policy_id", + "device_policies.mobile.policy_id", + "migration_completed_time", + "modified_timestamp", + "pod_labels", + "device_policies.prevention.policy_id", + "device_policies.identity-protection.policy_type", + "device_policies.identity-endpoint.policy_id", + "device_policies.kubernetes-admission-control.policy_type", "device_policies.fim.policy_type", - "device_policies.content-update.policy_id", - "service_provider", - "default_gateway_ip", - "filesystem_containment_status", - "device_policies.aidr.applied", - "last_login_user", - "device_policies.consumer-subscription.policy_id", - "service_provider_account_id", - "reduced_functionality_mode", - "zone_group", + "device_policies.consumer-subscription.policy_type", + "device_policies.cloud-ml.policy_type", + "device_policies.data-protection.policy_id", + "last_login_user_sid", "device_policies.sensor_update.applied", - "device_policies.host-retention.applied", - "device_policies.firewall.policy_type", - "device_policies.mobile.policy_id", - "pod_ip4", - "linux_sensor_mode", - "device_policies.network-scan-content.policy_id", - "minor_version", - "device_policies.sensor_update.policy_type", "device_policies.identity-endpoint.applied", - "device_policies.sca.policy_id", - "device_policies.data-protection.policy_id", - "device_policies.firewall.policy_id", - "device_policies.remote_response.applied", - "pod_host_ip4", - "device_policies.prevention.policy_id", - "device_policies.automox.policy_id", - "device_policies.ztl.policy_id", - "device_policies.consumer-subscription.applied", - "device_policies.cloud-ml.applied", - "device_policies.data-protection.policy_type", - "groups", - "managed_apps.jumpcloud.version", + "device_policies.cloud-container-workload.applied", + "device_policies.it-automation.applied", + "local_ip.raw", + "device_policies.firewall.policy_type", + "internet_exposure", + "device_policies.ztl.applied", + "device_policies.it-automation.policy_type", + "device_policies.host-retention.applied", + "device_policies.aidr.policy_type", "product_type_desc", - "policies.applied", - "managed_apps.airlock.version", - "pod_hostname", - "device_policies.network-scan-content.policy_type", - "device_policies.exposure-management.policy_type", - "device_policies.logscale-collector.policy_type", - "last_seen", - "device_policies.netskope.policy_id", - "device_policies.content-update.policy_type", - "device_policies.remote_response.policy_type", - "pod_ip6", - "pod_name", + "device_policies.airlock.policy_type", + "device_policies.airlock.applied", + "device_policies.kubernetes-admission-control.applied", + "device_policies.it-automation.policy_id", "device_policies.network-scan-content.applied", - "device_policies.aidr.policy_type", - "local_ip", - "policies.policy_id", + "device_policies.aidr.policy_id", + "release_group", + "managed_apps.aws-verified-access.version", + "device_policies.network-scan-content.policy_type", + "last_login_timestamp", + "device_policies.device_control.applied", + "device_policies.ztl.policy_id", + "reduced_functionality_mode", + "zone_group", + "pod_hostname", + "platform_name", + "device_policies.vulnerability-management.applied", + "host_utc_offset", + "safe_mode", + "ou", + "device_policies.prevention.policy_type", "device_policies.automox.policy_type", - "device_policies.kubernetes-admission-control.policy_id", - "device_policies.kubernetes-admission-control.applied", - "device_policies.system-tray.policy_id", - "device_policies.aws-verified-access.policy_id", - "license_activation_state", - "last_login_uid", - "device_policies.content-update.applied", - "device_policies.aws-verified-access.policy_type", - "connection_ip", - "device_policies.application-abuse-prevention.policy_type", - "first_login_user", - "device_policies.airlock.policy_type", - "tags", - "cpu_vendor", - "serial_number", - "pod_host_ip6", - "agent_load_flags" + "device_policies.fim.policy_id", + "device_policies.host-retention.policy_id", + "device_policies.mobile.applied" ], "description": "The property to sort by (e.g. status.desc or hostname.asc). If not specified, the " "default sort will be device_id.asc. This should be supplied for each consecutive call.", @@ -756,6 +762,13 @@ "name": "disable_hostname_check", "in": "query" }, + { + "type": "boolean", + "default": False, + "description": "Skip membership validation on remove (allows removing unmatched hosts)", + "name": "skip_membership_validation", + "in": "query" + }, { "name": "body", "in": "body", diff --git a/src/falconpy/_endpoint/_intel.py b/src/falconpy/_endpoint/_intel.py index 2852b695e..cf5492940 100644 --- a/src/falconpy/_endpoint/_intel.py +++ b/src/falconpy/_endpoint/_intel.py @@ -546,8 +546,13 @@ { "type": "string", "description": "The rule news report type. Accepted values:\n\nsnort-suricata-master\n\nsnort-" - "suricata-update\n\nsnort-suricata-changelog\n\nyara-master\n\nyara-update\n\nyara-changelog\n\ncommon-event-" - "format\n\nnetwitness\n\ncql-master\n\ncql-update\n\ncql-changelog", + "suricata-update\n\nsnort-suricata-changelog (deprecated)\n\nyara-master\n\nyara-update\n\nyara-changelog " + "(deprecated)\n\ncommon-event-format\n\nnetwitness\n\ncql-master (deprecated)\n\ncql-update " + "(deprecated)\n\ncql-changelog (deprecated)\n\nNote: CQL rules (cql-master, cql-update, cql-changelog) and " + "Changelog rules (snort-suricata-changelog, yara-changelog) are deprecated starting 28 September 2026. cql-" + "changelog belongs to both families. No new rules of these types will be published after that date. Already-" + "published rules will continue to be available via other means (e.g. direct ID-based download, email " + "notifications).", "name": "type", "in": "query", "required": True @@ -918,8 +923,13 @@ { "type": "string", "description": "The rule news report type. Accepted values:\n\nsnort-suricata-master\n\nsnort-" - "suricata-update\n\nsnort-suricata-changelog\n\nyara-master\n\nyara-update\n\nyara-changelog\n\ncommon-event-" - "format\n\nnetwitness\n\ncql-master\n\ncql-update\n\ncql-changelog", + "suricata-update\n\nsnort-suricata-changelog (deprecated)\n\nyara-master\n\nyara-update\n\nyara-changelog " + "(deprecated)\n\ncommon-event-format\n\nnetwitness\n\ncql-master (deprecated)\n\ncql-update " + "(deprecated)\n\ncql-changelog (deprecated)\n\nNote: CQL rules (cql-master, cql-update, cql-changelog) and " + "Changelog rules (snort-suricata-changelog, yara-changelog) are deprecated starting 28 September 2026. cql-" + "changelog belongs to both families. No new rules of these types will be published after that date. Already-" + "published rules will continue to be available via other means (e.g. direct ID-based download, email " + "notifications).", "name": "type", "in": "query", "required": True diff --git a/src/falconpy/_endpoint/_it_automation.py b/src/falconpy/_endpoint/_it_automation.py index 72c898bbb..f545d38d8 100644 --- a/src/falconpy/_endpoint/_it_automation.py +++ b/src/falconpy/_endpoint/_it_automation.py @@ -55,8 +55,9 @@ { "type": "string", "description": "The filter expression that should be used to limit the results. Allowed filter fields: " - " [access_type, created_by, created_time, last_run_time, modified_by, modified_time, name, runs, task_type] " - "Example: example_string_field:'example@example.com'+example_date_field:>='2024-08-27T03:21:32Z'", + " [access_type, created_by, created_time, has_task_parameters, last_run_time, modified_by, modified_time, name, " + " runs, task_type] Example: " + "example_string_field:'example@example.com'+example_date_field:>='2024-08-27T03:21:32Z'", "name": "filter", "in": "query" }, @@ -68,18 +69,18 @@ "in": "query" }, { - "minimum": 0, "type": "integer", "default": 0, + "minimum": 0, "description": "Starting index for record retrieval. Example: 100", "name": "offset", "in": "query" }, { - "maximum": 1000, - "minimum": 1, "type": "integer", "default": 100, + "maximum": 1000, + "minimum": 1, "description": "The maximum records to return. Example: 50", "name": "limit", "in": "query" @@ -112,18 +113,18 @@ "in": "query" }, { - "minimum": 0, "type": "integer", "default": 0, + "minimum": 0, "description": "Starting index for record retrieval. Example: 100", "name": "offset", "in": "query" }, { - "maximum": 1000, - "minimum": 1, "type": "integer", "default": 100, + "maximum": 1000, + "minimum": 1, "description": "The maximum records to return. Example: 50", "name": "limit", "in": "query" @@ -156,18 +157,18 @@ "in": "query" }, { - "minimum": 0, "type": "integer", "default": 0, + "minimum": 0, "description": "Starting index for record retrieval. Example: 100", "name": "offset", "in": "query" }, { - "maximum": 1000, - "minimum": 1, "type": "integer", "default": 100, + "maximum": 1000, + "minimum": 1, "description": "The maximum records to return. Example: 50", "name": "limit", "in": "query" @@ -198,18 +199,18 @@ "in": "query" }, { - "minimum": 0, "type": "integer", "default": 0, + "minimum": 0, "description": "Starting index for record retrieval. Example: 100", "name": "offset", "in": "query" }, { - "maximum": 1000, - "minimum": 1, "type": "integer", "default": 100, + "maximum": 1000, + "minimum": 1, "description": "The maximum records to return. Example: 50", "name": "limit", "in": "query" @@ -226,8 +227,9 @@ { "type": "string", "description": "The filter expression that should be used to limit the results. Allowed filter fields: " - " [access_type, created_by, created_time, last_run_time, modified_by, modified_time, name, runs, task_type] " - "Example: example_string_field:'example@example.com'+example_date_field:>='2024-08-27T03:21:32Z'", + " [access_type, created_by, created_time, has_task_parameters, last_run_time, modified_by, modified_time, name, " + " runs, task_type] Example: " + "example_string_field:'example@example.com'+example_date_field:>='2024-08-27T03:21:32Z'", "name": "filter", "in": "query" }, @@ -240,18 +242,18 @@ "in": "query" }, { - "minimum": 0, "type": "integer", "default": 0, + "minimum": 0, "description": "Starting index for record retrieval. Example: 100", "name": "offset", "in": "query" }, { - "maximum": 1000, - "minimum": 1, "type": "integer", "default": 100, + "maximum": 1000, + "minimum": 1, "description": "The maximum records to return. Example: 50", "name": "limit", "in": "query" @@ -292,6 +294,26 @@ } ] ], + [ + "ITAutomationDeleteUserGroup", + "DELETE", + "/it-automation/entities/it-user-groups/v1", + "Deletes user groups for each provided ids", + "it_automation", + [ + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "description": "Comma separated values of user group ids to delete", + "name": "ids", + "in": "query", + "required": True + } + ] + ], [ "ITAutomationUpdateUserGroup", "PATCH", @@ -313,26 +335,6 @@ } ] ], - [ - "ITAutomationDeleteUserGroup", - "DELETE", - "/it-automation/entities/it-user-groups/v1", - "Deletes user groups for each provided ids", - "it_automation", - [ - { - "type": "array", - "items": { - "type": "string" - }, - "collectionFormat": "multi", - "description": "Comma separated values of user group ids to delete", - "name": "ids", - "in": "query", - "required": True - } - ] - ], [ "ITAutomationRunLiveQuery", "POST", @@ -434,6 +436,26 @@ } ] ], + [ + "ITAutomationDeletePolicy", + "DELETE", + "/it-automation/entities/policies/v1", + "Deletes 1 or more policies.", + "it_automation", + [ + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "description": "list of task ids to delete", + "name": "ids", + "in": "query", + "required": True + } + ] + ], [ "ITAutomationUpdatePolicies", "PATCH", @@ -464,26 +486,6 @@ } ] ], - [ - "ITAutomationDeletePolicy", - "DELETE", - "/it-automation/entities/policies/v1", - "Deletes 1 or more policies.", - "it_automation", - [ - { - "type": "array", - "items": { - "type": "string" - }, - "collectionFormat": "multi", - "description": "list of task ids to delete", - "name": "ids", - "in": "query", - "required": True - } - ] - ], [ "ITAutomationGetScheduledTasks", "GET", @@ -518,6 +520,26 @@ } ] ], + [ + "ITAutomationDeleteScheduledTasks", + "DELETE", + "/it-automation/entities/scheduled-tasks/v1", + "Delete one or more scheduled tasks by providing the scheduled tasks IDs", + "it_automation", + [ + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "description": "Comma separated values of scheduled task IDs to delete", + "name": "ids", + "in": "query", + "required": True + } + ] + ], [ "ITAutomationUpdateScheduledTask", "PATCH", @@ -539,26 +561,6 @@ } ] ], - [ - "ITAutomationDeleteScheduledTasks", - "DELETE", - "/it-automation/entities/scheduled-tasks/v1", - "Delete one or more scheduled tasks by providing the scheduled tasks IDs", - "it_automation", - [ - { - "type": "array", - "items": { - "type": "string" - }, - "collectionFormat": "multi", - "description": "Comma separated values of scheduled task IDs to delete", - "name": "ids", - "in": "query", - "required": True - } - ] - ], [ "ITAutomationCancelTaskExecution", "POST", @@ -608,18 +610,18 @@ "in": "query" }, { - "minimum": 0, "type": "integer", "default": 0, + "minimum": 0, "description": "Starting index for record retrieval. Example: 100", "name": "offset", "in": "query" }, { - "maximum": 1000, - "minimum": 1, "type": "integer", "default": 100, + "maximum": 1000, + "minimum": 1, "description": "The maximum records to return. Example: 50", "name": "limit", "in": "query" @@ -644,7 +646,7 @@ "ITAutomationGetExecutionResultsSearchStatus", "GET", "/it-automation/entities/task-execution-results-search/v1", - "Get the status of an async task execution results. \n\nLook for `is_pending: False` to know search is complete.", + "Get the status of an async task execution results. \n\nLook for `is_pending: false` to know search is complete.", "it_automation", [ { @@ -689,9 +691,9 @@ "required": True }, { - "minimum": 0, "type": "integer", "default": 0, + "minimum": 0, "description": "The offset to start retrieving records from", "name": "offset", "in": "query" @@ -780,6 +782,26 @@ } ] ], + [ + "ITAutomationDeleteTaskGroups", + "DELETE", + "/it-automation/entities/task-groups/v1", + "Delete one or more task groups by providing the task group IDs", + "it_automation", + [ + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "description": "Comma separated values of task group IDs to delete", + "name": "ids", + "in": "query", + "required": True + } + ] + ], [ "ITAutomationUpdateTaskGroup", "PATCH", @@ -801,26 +823,6 @@ } ] ], - [ - "ITAutomationDeleteTaskGroups", - "DELETE", - "/it-automation/entities/task-groups/v1", - "Delete one or more task groups by providing the task group IDs", - "it_automation", - [ - { - "type": "array", - "items": { - "type": "string" - }, - "collectionFormat": "multi", - "description": "Comma separated values of task group IDs to delete", - "name": "ids", - "in": "query", - "required": True - } - ] - ], [ "ITAutomationGetTasks", "GET", @@ -855,6 +857,26 @@ } ] ], + [ + "ITAutomationDeleteTask", + "DELETE", + "/it-automation/entities/tasks/v1", + "Deletes tasks for each provided ID", + "it_automation", + [ + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "description": "IDs of tasks to delete. Use ITAutomationSearchTasks to fetch IDs", + "name": "ids", + "in": "query", + "required": True + } + ] + ], [ "ITAutomationUpdateTask", "PATCH", @@ -876,26 +898,6 @@ } ] ], - [ - "ITAutomationDeleteTask", - "DELETE", - "/it-automation/entities/tasks/v1", - "Deletes tasks for each provided ID", - "it_automation", - [ - { - "type": "array", - "items": { - "type": "string" - }, - "collectionFormat": "multi", - "description": "IDs of tasks to delete. Use ITAutomationSearchTasks to fetch IDs", - "name": "ids", - "in": "query", - "required": True - } - ] - ], [ "ITAutomationSearchUserGroup", "GET", @@ -921,18 +923,18 @@ "in": "query" }, { - "minimum": 0, "type": "integer", "default": 0, + "minimum": 0, "description": "Starting index for record retrieval. Example: 100", "name": "offset", "in": "query" }, { - "maximum": 1000, - "minimum": 1, "type": "integer", "default": 100, + "maximum": 1000, + "minimum": 1, "description": "The maximum records to return. Example: 50", "name": "limit", "in": "query" @@ -947,8 +949,8 @@ "it_automation", [ { - "minimum": 0, "type": "integer", + "minimum": 0, "description": "The offset to start retrieving records from. Defaults to 0 if not specified.", "name": "offset", "in": "query" @@ -969,12 +971,12 @@ "in": "query" }, { + "type": "string", "enum": [ "Windows", "Mac", "Linux" ], - "type": "string", "description": "The platform of policies to retrieve", "name": "platform", "in": "query", @@ -1008,18 +1010,18 @@ "in": "query" }, { - "minimum": 0, "type": "integer", "default": 0, + "minimum": 0, "description": "Starting index for record retrieval. Example: 100", "name": "offset", "in": "query" }, { - "maximum": 1000, - "minimum": 1, "type": "integer", "default": 100, + "maximum": 1000, + "minimum": 1, "description": "The maximum records to return. Example: 50", "name": "limit", "in": "query" @@ -1051,18 +1053,18 @@ "in": "query" }, { - "minimum": 0, "type": "integer", "default": 0, + "minimum": 0, "description": "Starting index for record retrieval. Example: 100", "name": "offset", "in": "query" }, { - "maximum": 1000, - "minimum": 1, "type": "integer", "default": 100, + "maximum": 1000, + "minimum": 1, "description": "The maximum records to return. Example: 50", "name": "limit", "in": "query" @@ -1093,18 +1095,18 @@ "in": "query" }, { - "minimum": 0, "type": "integer", "default": 0, + "minimum": 0, "description": "Starting index for record retrieval. Example: 100", "name": "offset", "in": "query" }, { - "maximum": 1000, - "minimum": 1, "type": "integer", "default": 100, + "maximum": 1000, + "minimum": 1, "description": "The maximum records to return. Example: 50", "name": "limit", "in": "query" @@ -1121,8 +1123,9 @@ { "type": "string", "description": "The filter expression that should be used to limit the results. Allowed filter fields: " - " [access_type, created_by, created_time, last_run_time, modified_by, modified_time, name, runs, task_type] " - "Example: example_string_field:'example@example.com'+example_date_field:>='2024-08-27T03:21:32Z'", + " [access_type, created_by, created_time, has_task_parameters, last_run_time, modified_by, modified_time, name, " + " runs, task_type] Example: " + "example_string_field:'example@example.com'+example_date_field:>='2024-08-27T03:21:32Z'", "name": "filter", "in": "query" }, @@ -1135,21 +1138,346 @@ "in": "query" }, { - "minimum": 0, "type": "integer", "default": 0, + "minimum": 0, "description": "Starting index for record retrieval. Example: 100", "name": "offset", "in": "query" }, { + "type": "integer", + "default": 100, "maximum": 1000, "minimum": 1, + "description": "The maximum records to return. Example: 50", + "name": "limit", + "in": "query" + } + ] + ], + [ + "AggregateDeploymentConfigsV1", + "POST", + "/patch-mgmt/aggregates/deployment-configs/v1", + "Retrieve deployment config aggregations", + "it_automation", + [ + { + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "AggregateDeploymentExecutionsV1", + "POST", + "/patch-mgmt/aggregates/deployment-executions/v1", + "Retrieve deployment execution aggregations", + "it_automation", + [ + { + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "AggregateHostDeploymentsV1", + "POST", + "/patch-mgmt/aggregates/host-deployments/v1", + "Retrieve host deployment aggregations", + "it_automation", + [ + { + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "GetDeploymentConfigsByQueryV1", + "GET", + "/patch-mgmt/combined/deployment-configs/v1", + "Retrieve deployment configs by query", + "it_automation", + [ + { + "type": "string", + "description": "The filter expression that should be used to limit the results.\n\nAllowable categories are: ...", + "name": "filter", + "in": "query" + }, + { + "type": "string", + "description": "The sort expression that should be used to sort the results", + "name": "sort", + "in": "query" + }, + { + "type": "integer", + "description": "The offset to start retrieving records from", + "name": "offset", + "in": "query" + }, + { + "type": "integer", + "description": "The maximum records to return", + "name": "limit", + "in": "query" + } + ] + ], + [ + "GetDeploymentExecutionsByQueryV1", + "GET", + "/patch-mgmt/combined/deployment-executions/v1", + "Retrieve deployment executions by query", + "it_automation", + [ + { + "type": "string", + "description": "The filter expression. Optionally filter by deployment_config.id:'' or status:''.", + "name": "filter", + "in": "query" + }, + { + "type": "string", + "description": "The sort expression that should be used to sort the results", + "name": "sort", + "in": "query" + }, + { + "type": "integer", + "description": "The offset to start retrieving records from", + "name": "offset", + "in": "query" + }, + { + "type": "integer", + "description": "The maximum records to return", + "name": "limit", + "in": "query" + } + ] + ], + [ + "GetHostDeploymentPatchesByQueryV1", + "GET", + "/patch-mgmt/combined/host-deployment-patches/v1", + "Retrieve host deployment patch statuses by query", + "it_automation", + [ + { + "type": "string", + "description": "The filter expression. Must include host_deployment_id:''. Optionally filter by " + "status:'installed|not-installed'.", + "name": "filter", + "in": "query", + "required": True + }, + { + "type": "string", + "description": "The sort expression that should be used to sort the results", + "name": "sort", + "in": "query" + }, + { + "type": "integer", + "description": "The offset to start retrieving records from", + "name": "offset", + "in": "query" + }, + { + "type": "integer", + "description": "The maximum records to return", + "name": "limit", + "in": "query" + } + ] + ], + [ + "GetHostDeploymentsByQueryV1", + "GET", + "/patch-mgmt/combined/host-deployments/v1", + "Retrieve deployment results by query", + "it_automation", + [ + { + "type": "string", + "description": "The filter expression that should be used to limit the results.\n\nAllowable categories are: ...", + "name": "filter", + "in": "query" + }, + { + "type": "string", + "description": "The sort expression that should be used to sort the results", + "name": "sort", + "in": "query" + }, + { + "type": "integer", + "description": "The offset to start retrieving records from", + "name": "offset", + "in": "query" + }, + { + "type": "integer", + "description": "The maximum records to return", + "name": "limit", + "in": "query" + } + ] + ], + [ + "CombinedOSAssessmentScan", + "GET", + "/patch-mgmt/combined/os-assessment-scan/v1", + "Search and retrieve OS assessment scan statuses in a single request", + "it_automation", + [ + { + "type": "string", + "description": "FQL filter expression for searching assessment scans", + "name": "filter", + "in": "query" + }, + { + "type": "string", + "description": "Sort expression", + "name": "sort", + "in": "query" + }, + { "type": "integer", "default": 100, - "description": "The maximum records to return. Example: 50", + "description": "Maximum number of records to return", + "name": "limit", + "in": "query" + }, + { + "type": "string", + "description": "A pagination token used with the limit parameter to manage pagination of results. On " + "your first request, don't provide an after token. On subsequent requests, provide the after token from the " + "previous response to continue from that place in the results.", + "name": "after", + "in": "query" + } + ] + ], + [ + "CombinedOSAssessments", + "GET", + "/patch-mgmt/combined/os-assessments/v1", + "Search and retrieve OS patch assessments in a single request", + "it_automation", + [ + { + "type": "string", + "description": "FQL filter expression for searching assessments", + "name": "filter", + "in": "query" + }, + { + "type": "string", + "description": "Sort expression", + "name": "sort", + "in": "query" + }, + { + "type": "integer", + "default": 100, + "description": "Maximum number of records to return", "name": "limit", "in": "query" + }, + { + "type": "string", + "description": "A pagination token used with the limit parameter to manage pagination of results. On " + "your first request, don't provide an after token. On subsequent requests, provide the after token from the " + "previous response to continue from that place in the results.", + "name": "after", + "in": "query" + }, + { + "type": "string", + "description": "Vulnerability facets to include in response: 'vulnerabilities' (full array), " + "'vulnerability_counts' (summary). Default: vulnerability_counts", + "name": "facets", + "in": "query" + } + ] + ], + [ + "CreateDeploymentConfig", + "POST", + "/patch-mgmt/entities/deployment-configs/v1", + "Creates a new deployment configuration", + "it_automation", + [ + { + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "DeleteDeploymentConfigs", + "DELETE", + "/patch-mgmt/entities/deployment-configs/v1", + "Deletes deployment configurations by IDs", + "it_automation", + [ + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "maxItems": 200, + "description": "Deployment config IDs to delete", + "name": "ids", + "in": "query", + "required": True + } + ] + ], + [ + "UpdateDeploymentConfig", + "PATCH", + "/patch-mgmt/entities/deployment-configs/v1", + "Updates an existing deployment configuration", + "it_automation", + [ + { + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "CancelDeploymentExecutionsV1", + "DELETE", + "/patch-mgmt/entities/deployment-executions/v1", + "Cancel deployment executions by IDs", + "it_automation", + [ + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "maxItems": 200, + "description": "Comma separated values of deployment execution ids to cancel", + "name": "ids", + "in": "query", + "required": True } ] ] diff --git a/src/falconpy/_endpoint/_knowledge_base_audit_events.py b/src/falconpy/_endpoint/_knowledge_base_audit_events.py index 99917afb5..5e3b2443e 100644 --- a/src/falconpy/_endpoint/_knowledge_base_audit_events.py +++ b/src/falconpy/_endpoint/_knowledge_base_audit_events.py @@ -84,6 +84,12 @@ "description": "Include audit events for deleted knowledge bases. Defaults to false.", "name": "include_deleted", "in": "query" + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" } ] ], @@ -118,6 +124,12 @@ "description": "Include audit events for deleted knowledge bases. Defaults to false.", "name": "include_deleted", "in": "query" + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" } ] ], @@ -168,6 +180,12 @@ "description": "Include audit events for deleted knowledge bases. Defaults to false.", "name": "include_deleted", "in": "query" + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" } ] ], diff --git a/src/falconpy/_endpoint/_knowledge_base_files.py b/src/falconpy/_endpoint/_knowledge_base_files.py index 1dd74dce0..bbccd5661 100644 --- a/src/falconpy/_endpoint/_knowledge_base_files.py +++ b/src/falconpy/_endpoint/_knowledge_base_files.py @@ -57,6 +57,12 @@ "name": "id", "in": "query", "required": True + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" } ] ], @@ -91,6 +97,12 @@ "description": "Include deleted knowledge base files in the result. Defaults to false.", "name": "include_deleted", "in": "query" + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" } ] ], @@ -120,6 +132,12 @@ "description": "New description for the knowledge base file", "name": "file_description", "in": "formData" + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "formData" } ] ], @@ -149,6 +167,12 @@ "description": "Description for the uploaded file", "name": "file_description", "in": "formData" + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "formData" } ] ], @@ -172,6 +196,12 @@ "name": "id", "in": "query", "required": True + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" } ] ], @@ -216,6 +246,12 @@ "description": "Include deleted knowledge base files in the result. Defaults to false.", "name": "include_deleted", "in": "query" + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" } ] ] diff --git a/src/falconpy/_endpoint/_knowledge_bases.py b/src/falconpy/_endpoint/_knowledge_bases.py index ae1b8e142..12e399257 100644 --- a/src/falconpy/_endpoint/_knowledge_bases.py +++ b/src/falconpy/_endpoint/_knowledge_bases.py @@ -77,6 +77,12 @@ "description": "Include deleted knowledge bases in the result. Defaults to false.", "name": "include_deleted", "in": "query" + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" } ] ], @@ -104,6 +110,12 @@ "description": "Include deleted knowledge bases in the result. Defaults to false.", "name": "include_deleted", "in": "query" + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" } ] ], @@ -129,6 +141,12 @@ "Update an existing knowledge base.", "knowledge_bases", [ + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" + }, { "description": "Knowledge base definition with updated fields", "name": "body", @@ -177,6 +195,12 @@ "description": "Include deleted knowledge bases in the result. Defaults to false.", "name": "include_deleted", "in": "query" + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" } ] ], diff --git a/src/falconpy/_endpoint/_mssp.py b/src/falconpy/_endpoint/_mssp.py index 7c6f08811..727187999 100644 --- a/src/falconpy/_endpoint/_mssp.py +++ b/src/falconpy/_endpoint/_mssp.py @@ -75,7 +75,7 @@ "getCIDGroupMembersByV1", "GET", "/mssp/entities/cid-group-members/v1", - "Deprecated : Please use getCIDGroupMembersByV2 Get CID group members by CID group ID.", + "Deprecated : Please use getCIDGroupMembersByV2. Get CID group members by CID group ID.", "mssp", [ { @@ -145,7 +145,7 @@ "deleteCIDGroupMembers", "DELETE", "/mssp/entities/cid-group-members/v1", - "Deprecated : Please use deleteCIDGroupMembersV2 Delete CID group members.", + "Deprecated : Please use deleteCIDGroupMembersV2. Delete CID group members.", "mssp", [ { @@ -195,7 +195,7 @@ "getCIDGroupByIdV1", "GET", "/mssp/entities/cid-groups/v1", - "Deprecated : Please use getCIDGroupByIdV2 Get CID groups by ID.", + "Deprecated : Please use getCIDGroupByIdV2. Get CID groups by ID.", "mssp", [ { @@ -364,7 +364,7 @@ "getUserGroupMembersByIDV1", "GET", "/mssp/entities/user-group-members/v1", - "Deprecated : Please use getUserGroupMembersByIDV2 Get user group members by user group ID.", + "Deprecated : Please use getUserGroupMembersByIDV2. Get user group members by user group ID.", "mssp", [ { @@ -454,7 +454,7 @@ "getUserGroupsByIDV1", "GET", "/mssp/entities/user-groups/v1", - "Deprecated : Please use getUserGroupsByIDV2 Get user groups by ID.", + "Deprecated : Please use getUserGroupsByIDV2. Get user groups by ID.", "mssp", [ { diff --git a/src/falconpy/_endpoint/_ngsiem.py b/src/falconpy/_endpoint/_ngsiem.py index 039a47a12..cd19c4541 100644 --- a/src/falconpy/_endpoint/_ngsiem.py +++ b/src/falconpy/_endpoint/_ngsiem.py @@ -1459,6 +1459,84 @@ } ] ], + [ + "GetScheduledReport", + "GET", + "/ngsiem-content/entities/scheduled-reports/v1", + "Get Scheduled Report(s) in LogScale", + "ngsiem", + [ + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "description": "scheduled report ID value(s)", + "name": "ids", + "in": "query" + }, + { + "type": "string", + "description": "name of search domain (view or repo)", + "name": "search_domain", + "in": "query" + } + ] + ], + [ + "CreateScheduledReport", + "POST", + "/ngsiem-content/entities/scheduled-reports/v1", + "Create a Scheduled Report in LogScale", + "ngsiem", + [ + { + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "DeleteScheduledReport", + "DELETE", + "/ngsiem-content/entities/scheduled-reports/v1", + "Delete Scheduled Report(s) in LogScale", + "ngsiem", + [ + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "description": "scheduled report ID value(s). Supports single or multiple IDs for bulk delete.", + "name": "ids", + "in": "query" + }, + { + "type": "string", + "description": "name of search domain (view or repo)", + "name": "search_domain", + "in": "query" + } + ] + ], + [ + "UpdateScheduledReport", + "PATCH", + "/ngsiem-content/entities/scheduled-reports/v1", + "Update a Scheduled Report in LogScale", + "ngsiem", + [ + { + "name": "body", + "in": "body", + "required": True + } + ] + ], [ "ListDashboards", "GET", @@ -1699,6 +1777,45 @@ } ] ], + [ + "ListScheduledReports", + "GET", + "/ngsiem-content/queries/scheduled-reports/v1", + "List Scheduled Reports in a view with Pagination and Filtering. Returns scheduled report details. " + "Supports pagination (default limit: 50) and optional name filtering.", + "ngsiem", + [ + { + "type": "string", + "default": "50", + "pattern": "^\\d{1,4}$", + "description": "maximum number of results to return", + "name": "limit", + "in": "query" + }, + { + "type": "string", + "default": "0", + "pattern": "^\\d{1,4}$", + "description": "number of results to offset the returned results by", + "name": "offset", + "in": "query" + }, + { + "type": "string", + "description": "FQL filter to apply to the name of the content, only currently support text match on " + "name field: name:~'value'", + "name": "filter", + "in": "query" + }, + { + "type": "string", + "description": "name of view or repo", + "name": "view_name", + "in": "query" + } + ] + ], [ "ExternalListDataConnections", "GET", diff --git a/src/falconpy/_endpoint/_quick_scan_pro.py b/src/falconpy/_endpoint/_quick_scan_pro.py index f81c7da3b..122c93e25 100644 --- a/src/falconpy/_endpoint/_quick_scan_pro.py +++ b/src/falconpy/_endpoint/_quick_scan_pro.py @@ -49,7 +49,7 @@ { "type": "file", "description": "Binary file to be uploaded. Max file size: 256 MB. Use --data-binary @$FILE_PATH for " - "octet-stream/cURL uploads", + "octet-stream/cURL uploads.", "name": "file", "in": "formData", "required": True @@ -63,10 +63,25 @@ { "type": "boolean", "default": False, - "description": "If true, after upload, it starts scanning immediately. Default scan mode is 'false'", + "description": "If true, after upload, it starts scanning immediately. Default scan mode is 'false'.", "name": "scan", "in": "formData" }, + { + "type": "string", + "default": "standard", + "enum": [ + "fast", + "standard", + "deep" + ], + "description": "Sets the scan mode for the scan started when 'scan' is true. Default is " + "'standard'.\n\n'fast': less than 5 seconds, ML-based detection and signature matching.\n'standard': less than " + "30 seconds, adds heuristic analysis to fast scan coverage.\n'deep': less than 90 seconds, adds static analysis " + "and dynamic execution monitoring to standard scan coverage.", + "name": "scan_mode", + "in": "formData" + }, { "type": "string", "description": "MULTIPART ONLY - Password for encrypted archives (use for multipart/form-data " @@ -154,6 +169,14 @@ "quick_scan_pro", [ { + "description": "Each resource must include 'sha256' (required); 'password' and 'scan_mode' are " + "optional:\nsha256 (required): SHA256 of a file uploaded through " + "'/quickscanpro/entities/files/v1'.\npassword (optional): Password for encrypted archives or " + "documents.\nscan_mode (optional): How thorough the scan should be. Default is " + "'standard':\n     • fast: less than 5 seconds, ML-based detection and signature " + "matching.\n     • standard: less than 30 seconds, adds heuristic analysis to fast scan " + "coverage.\n     • deep: less than 90 seconds, adds static analysis and dynamic execution " + "monitoring to standard scan coverage.", "name": "body", "in": "body", "required": True diff --git a/src/falconpy/_endpoint/_real_time_response.py b/src/falconpy/_endpoint/_real_time_response.py index 0a667e3c5..0f82b52c5 100644 --- a/src/falconpy/_endpoint/_real_time_response.py +++ b/src/falconpy/_endpoint/_real_time_response.py @@ -191,7 +191,7 @@ "BatchGetCmd", "POST", "/real-time-response/combined/batch-get-command/v1", - "Batch executes `get` command across hosts to retrieve files. After this call is made `BatchGetCmdStatus " + "Batch executes `get` command across hosts to retrieve files. After this call is made `BatchGetCmdStatus` " "is used to query for the results.", "real_time_response", [ diff --git a/src/falconpy/_endpoint/_recon.py b/src/falconpy/_endpoint/_recon.py index 06809eaf2..abed98d54 100644 --- a/src/falconpy/_endpoint/_recon.py +++ b/src/falconpy/_endpoint/_recon.py @@ -166,8 +166,8 @@ "GET", "/recon/entities/exports/v1", "Get the status of export jobs based on their IDs. Export jobs can be launched by calling " - "CreateExportJobsV1 When a job is complete, use the job ID to download the file(s) associated with it using GET " - "entities/export-files/v1.", + "CreateExportJobsV1. When a job is complete, use the job ID to download the file(s) associated with it using " + "GET entities/export-files/v1.", "recon", [ { @@ -187,7 +187,7 @@ "CreateExportJobsV1", "POST", "/recon/entities/exports/v1", - "Launch asynchronous export job. Use the job ID to poll the status of the job using GetExportJobsV1", + "Launch asynchronous export job. Use the job ID to poll the status of the job using GetExportJobsV1.", "recon", [ { @@ -434,7 +434,7 @@ "QueryActionsV1", "GET", "/recon/queries/actions/v1", - "Query actions based on provided criteria. Use the IDs from this response to get the action entities on GetActionsV1", + "Query actions based on provided criteria. Use the IDs from this response to get the action entities on GetActionsV1.", "recon", [ { @@ -529,7 +529,7 @@ "/recon/queries/notifications/v1", "Query notifications based on provided criteria. Use the IDs from this response to get the notification " "+entities on GetNotificationsV1, GetNotificationsDetailedV1, +GetNotificationsTranslatedV1 or " - "GetNotificationsDetailedTranslatedV1", + "GetNotificationsDetailedTranslatedV1.", "recon", [ { diff --git a/src/falconpy/_endpoint/_saas_security.py b/src/falconpy/_endpoint/_saas_security.py index 2b5e5ff21..6845610e3 100644 --- a/src/falconpy/_endpoint/_saas_security.py +++ b/src/falconpy/_endpoint/_saas_security.py @@ -485,6 +485,27 @@ } ] ], + [ + "SetCheckImpactV3", + "POST", + "/saas-security/entities/check-impact/v3", + "POST Set a Security Check Impact", + "saas_security", + [ + { + "name": "body", + "in": "body", + "required": True + }, + { + "type": "string", + "description": "Security Check ID", + "name": "id", + "in": "query", + "required": True + } + ] + ], [ "GetCheckJournalV3", "GET", @@ -666,6 +687,65 @@ } ] ], + [ + "GetSecurityCheckChangeLogV3", + "GET", + "/saas-security/entities/checks-change-log/v3", + "GET Security Check Change Log", + "saas_security", + [ + { + "type": "string", + "description": "Actions to filter by, comma separated (e.g. renamed,impact_changed)", + "name": "action", + "in": "query" + }, + { + "type": "integer", + "description": "The maximum number of objects to return", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "description": "The starting index of the results", + "name": "offset", + "in": "query" + }, + { + "type": "string", + "description": "Supported integration (app) ids to filter by, comma separated", + "name": "app", + "in": "query" + }, + { + "type": "string", + "description": "Security check id - stable across a rename, so it returns the whole history", + "name": "check_id", + "in": "query" + }, + { + "type": "string", + "format": "date-time", + "description": "From Date (in YYYY-MM-DD format)", + "name": "from_date", + "in": "query" + }, + { + "type": "string", + "format": "date-time", + "description": "To Date (in YYYY-MM-DD format)", + "name": "to_date", + "in": "query" + }, + { + "type": "boolean", + "description": "Fetch Total Count?", + "name": "total_count", + "in": "query" + } + ] + ], [ "GetSecurityChecksV3", "GET", diff --git a/src/falconpy/_endpoint/_sample_uploads.py b/src/falconpy/_endpoint/_sample_uploads.py index bd7a4245a..4d26d6cd8 100644 --- a/src/falconpy/_endpoint/_sample_uploads.py +++ b/src/falconpy/_endpoint/_sample_uploads.py @@ -125,7 +125,7 @@ "default": True, "description": "Defines visibility of this file, either via the API or the Falcon console.\n true: " "File is only shown to users within your customer account false: File can be seen by other CrowdStrike " - "customers \n\nDefault: True.", + "customers \n\nDefault: true.", "name": "is_confidential", "in": "query" }, @@ -188,7 +188,7 @@ "default": True, "description": "Defines visibility of this file in Falcon MalQuery, either via the API or the Falcon " "console. For example, use --form is_confidential= when using cURL.\n true: File is only shown to users within " - "your customer account false: File can be seen by other CrowdStrike customers \n\nDefault: True.", + "your customer account false: File can be seen by other CrowdStrike customers \n\nDefault: true.", "name": "is_confidential", "in": "formData" }, @@ -330,7 +330,7 @@ "default": True, "description": "Defines visibility of this file in Falcon MalQuery, either via the API or the Falcon " "console.\n true: File is only shown to users within your customer account false: File can be seen by other " - "CrowdStrike customers \n\nDefault: True.", + "CrowdStrike customers \n\nDefault: true.", "name": "is_confidential", "in": "formData" } diff --git a/src/falconpy/_endpoint/_skills.py b/src/falconpy/_endpoint/_skills.py index 761c3cc99..0e3254f43 100644 --- a/src/falconpy/_endpoint/_skills.py +++ b/src/falconpy/_endpoint/_skills.py @@ -57,6 +57,12 @@ "description": "Include deleted skills in the result. Defaults to false.", "name": "include_deleted", "in": "query" + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" } ] ], @@ -84,6 +90,12 @@ "description": "Include deleted skills in the result. Defaults to false.", "name": "include_deleted", "in": "query" + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" } ] ], @@ -107,6 +119,12 @@ "name": "skill_blob", "in": "formData", "required": True + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "formData" } ] ], @@ -123,6 +141,12 @@ "name": "skill_blob", "in": "formData", "required": True + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "formData" } ] ], @@ -139,6 +163,12 @@ "name": "id", "in": "query", "required": True + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" } ] ], @@ -182,6 +212,12 @@ "description": "Include deleted skills in the result. Defaults to false.", "name": "include_deleted", "in": "query" + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" } ] ] diff --git a/src/falconpy/_endpoint/_spans.py b/src/falconpy/_endpoint/_spans.py index f02de1924..257d61826 100644 --- a/src/falconpy/_endpoint/_spans.py +++ b/src/falconpy/_endpoint/_spans.py @@ -54,6 +54,12 @@ "name": "ids", "in": "query", "required": True + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" } ] ], @@ -90,6 +96,12 @@ "description": "FQL query specifying the filter parameters.", "name": "filter", "in": "query" + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" } ] ] diff --git a/src/falconpy/_endpoint/_spotlight_vulnerabilities.py b/src/falconpy/_endpoint/_spotlight_vulnerabilities.py index 529deff78..691e133d0 100644 --- a/src/falconpy/_endpoint/_spotlight_vulnerabilities.py +++ b/src/falconpy/_endpoint/_spotlight_vulnerabilities.py @@ -118,8 +118,8 @@ "host_info.asset_roles,\n\t\t\t\t\thost_info.internet_exposure, host_info.tags, host_info.groups, " "host_info.product_type_desc, host_info.platform_name, " "suppression_info.is_suppressed,\n\t\t\t\t\tsuppression_info.reason, host_info.instance_state, " - "assessment_status, assessment_reason, rule.name, rule.recommendation_id, " - "rule.cs_id,\n\t\t\t\t\tdata_providers.policy_id, data_providers.rule_group_id\n\t\t\tAvailable filter fields " + "assessment_status, assessment_reason, rule.name, rule.recommendation_id, rule.cs_id, " + "rule.type,\n\t\t\t\t\tdata_providers.policy_id, data_providers.rule_group_id\n\t\t\tAvailable filter fields " "that supports wildcard (*): N/A\n\t\t\tAvailable filter fields that supports range comparisons (>, <, >=, <=): " "created_timestamp, closed_timestamp, updated_timestamp, cve.base_score\n\t\t\t", "name": "filter", @@ -223,8 +223,8 @@ "host_info.internet_exposure, host_info.tags, host_info.groups, host_info.product_type_desc, " "host_info.platform_name,\n\t\t\tsuppression_info.is_suppressed, suppression_info.reason, " "host_info.instance_state,\n\t\t\tassessment_status, assessment_reason, rule.name, rule.recommendation_id, " - "rule.cs_id, data_providers.policy_id, data_providers.rule_group_id\n\t\t\tAvailable filter fields that " - "supports wildcard (*): N/A\n\t\t\tAvailable filter fields that supports range comparisons (>, <, >=, <=): " + "rule.cs_id, rule.type, data_providers.policy_id, data_providers.rule_group_id\n\t\t\tAvailable filter fields " + "that supports wildcard (*): N/A\n\t\t\tAvailable filter fields that supports range comparisons (>, <, >=, <=): " "created_timestamp, closed_timestamp, updated_timestamp, cve.base_score\n\t\t\t", "name": "filter", "in": "query", diff --git a/src/falconpy/_endpoint/_stream.py b/src/falconpy/_endpoint/_stream.py index 9e4e4d3f8..c479d80f6 100644 --- a/src/falconpy/_endpoint/_stream.py +++ b/src/falconpy/_endpoint/_stream.py @@ -50,6 +50,12 @@ "name": "id", "in": "query", "required": True + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" } ] ] diff --git a/src/falconpy/_endpoint/_tools.py b/src/falconpy/_endpoint/_tools.py index 48493af1b..bcebb05bd 100644 --- a/src/falconpy/_endpoint/_tools.py +++ b/src/falconpy/_endpoint/_tools.py @@ -54,6 +54,12 @@ "name": "ids", "in": "query", "required": True + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" } ] ], @@ -90,6 +96,12 @@ "description": "FQL query specifying the filter parameters.", "name": "filter", "in": "query" + }, + { + "type": "string", + "description": "Scope the operation to a project.", + "name": "project_id", + "in": "query" } ] ] diff --git a/src/falconpy/_endpoint/_user_management.py b/src/falconpy/_endpoint/_user_management.py index 06fa9a60a..d4a27d1f8 100644 --- a/src/falconpy/_endpoint/_user_management.py +++ b/src/falconpy/_endpoint/_user_management.py @@ -35,6 +35,7 @@ For more information, please refer to """ +# pylint: disable=C0302 _user_management_endpoints = [ [ @@ -66,8 +67,8 @@ { "type": "string", "enum": [ - "internal", - "external" + "external", + "internal" ], "description": "Filter results by user type (internal or external). Omit to return all users.", "name": "user_type", @@ -79,8 +80,8 @@ "combinedUserRolesV1", "GET", "/user-management/combined/user-roles/v1", - "Deprecated : Please use CombinedUserRolesV2 Get User Grant(s). This endpoint lists both direct as well as " - "flight control grants between a User and a Customer.", + "Deprecated : Please use CombinedUserRolesV2. Get User Grant(s). This endpoint lists both direct as well " + "as flight control grants between a User and a Customer.", "user_management", [ { @@ -314,6 +315,52 @@ } ] ], + [ + "entitiesPermissionGroupsGETV1", + "POST", + "/user-management/entities/permission-groups/GET/v1", + "Get details about permission groups including name and description.", + "user_management", + [ + { + "description": "Maximum of 500 Permission Group IDs can be specified per request.", + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "entitiesPermissionsGETV1", + "POST", + "/user-management/entities/permissions/GET/v1", + "Get details about permissions including name, description, and which permission groups they belong to.", + "user_management", + [ + { + "description": "Maximum of 500 Permission IDs can be specified per request.", + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "entitiesRolePermissionsV1", + "GET", + "/user-management/entities/role-permissions/v1", + "Get permission IDs assigned to a given role.", + "user_management", + [ + { + "type": "string", + "description": "Role ID to get permission IDs for. Find a role ID from queriesRolesV1.", + "name": "id", + "in": "query", + "required": True + } + ] + ], [ "entitiesRolesGETV2", "POST", @@ -537,6 +584,32 @@ } ] ], + [ + "queriesPermissionsV1", + "GET", + "/user-management/queries/permissions/v1", + "List all permission IDs available to your CID based on product subscriptions.", + "user_management", + [ + { + "type": "integer", + "default": 0, + "minimum": 0, + "description": "The offset to start retrieving records from", + "name": "offset", + "in": "query" + }, + { + "type": "integer", + "default": 100, + "maximum": 5000, + "minimum": 1, + "description": "The maximum records to return. [1-5000]", + "name": "limit", + "in": "query" + } + ] + ], [ "queriesRolesV1", "GET", @@ -767,7 +840,7 @@ "GetRoles", "GET", "/user-roles/entities/user-roles/v1", - "Deprecated : Please use entitiesRolesV1 Get info about a role", + "Deprecated : Please use entitiesRolesV1. Get info about a role", "user_management", [ { @@ -787,7 +860,7 @@ "GrantUserRoleIds", "POST", "/user-roles/entities/user-roles/v1", - "Deprecated : Please use userRolesActionV1 Assign one or more roles to a user", + "Deprecated : Please use userRolesActionV1. Assign one or more roles to a user", "user_management", [ { @@ -809,7 +882,7 @@ "RevokeUserRoleIds", "DELETE", "/user-roles/entities/user-roles/v1", - "Deprecated : Please use userRolesActionV1 Revoke one or more roles from a user", + "Deprecated : Please use userRolesActionV1. Revoke one or more roles from a user", "user_management", [ { @@ -836,7 +909,7 @@ "GetAvailableRoleIds", "GET", "/user-roles/queries/user-role-ids-by-cid/v1", - "Deprecated : Please use queriesRolesV1 Show role IDs for all roles available in your customer account. " + "Deprecated : Please use queriesRolesV1. Show role IDs for all roles available in your customer account. " "For more information on each role, provide the role ID to entitiesRolesV1.", "user_management", [] @@ -845,7 +918,7 @@ "GetUserRoleIds", "GET", "/user-roles/queries/user-role-ids-by-user-uuid/v1", - "Deprecated : Please use combinedUserRolesV1 Show role IDs of roles assigned to a user. For more " + "Deprecated : Please use combinedUserRolesV1. Show role IDs of roles assigned to a user. For more " "information on each role, provide the role ID to entitiesRolesV1.", "user_management", [ @@ -882,7 +955,7 @@ "retrieveUser", "GET", "/users/entities/users/v1", - "Deprecated : Please use retrieveUsersGETV1 Get info about a user", + "Deprecated : Please use retrieveUsersGETV1. Get info about a user", "user_management", [ { @@ -902,7 +975,7 @@ "CreateUser", "POST", "/users/entities/users/v1", - "Deprecated : Please use createUserV1 Create a new user. After creating a user, assign one or more roles " + "Deprecated : Please use createUserV1. Create a new user. After creating a user, assign one or more roles " "with GrantUserRoleIds", "user_management", [ @@ -923,7 +996,7 @@ "DeleteUser", "DELETE", "/users/entities/users/v1", - "Deprecated : Please use deleteUserV1 Delete a user permanently", + "Deprecated : Please use deleteUserV1. Delete a user permanently", "user_management", [ { @@ -939,7 +1012,7 @@ "UpdateUser", "PATCH", "/users/entities/users/v1", - "Deprecated : Please use updateUserV1 Modify an existing user's first or last name", + "Deprecated : Please use updateUserV1. Modify an existing user's first or last name", "user_management", [ { @@ -961,8 +1034,8 @@ "RetrieveEmailsByCID", "GET", "/users/queries/emails-by-cid/v1", - "Deprecated : Please use retrieveUsersGETV1 List the usernames (usually an email address) for all users in " - "your customer account", + "Deprecated : Please use retrieveUsersGETV1. List the usernames (usually an email address) for all users " + "in your customer account", "user_management", [] ], @@ -970,7 +1043,7 @@ "RetrieveUserUUIDsByCID", "GET", "/users/queries/user-uuids-by-cid/v1", - "Deprecated : Please use queryUserV1 List user IDs for all users in your customer account. For more " + "Deprecated : Please use queryUserV1. List user IDs for all users in your customer account. For more " "information on each user, provide the user ID to retrieveUser.", "user_management", [] @@ -979,7 +1052,7 @@ "RetrieveUserUUID", "GET", "/users/queries/user-uuids-by-email/v1", - "Deprecated : Please use queryUserV1 Get a user's ID by providing a username (usually an email address)", + "Deprecated : Please use queryUserV1. Get a user's ID by providing a username (usually an email address)", "user_management", [ { diff --git a/src/falconpy/_endpoint/deprecated/_mapping.py b/src/falconpy/_endpoint/deprecated/_mapping.py index e2e88bd0c..f3fe047f1 100644 --- a/src/falconpy/_endpoint/deprecated/_mapping.py +++ b/src/falconpy/_endpoint/deprecated/_mapping.py @@ -76,14 +76,92 @@ "CreateFileV1": "", "UpdateFileV1": "", "combinedQueryInstalledPatches": "", - "AggregatesKnowledgeBaseAuditEventsV1": "", - "AggregatesKnowledgeBasesV1": "", - "WorkflowExecuteInternal": "", - "GetConfigurationDetections": "", + "ArchiveUploadV1": "ArchiveUploadV2", + "AzureDownloadCertificate": "", + "AzureRefreshCertificate": "", + "ConnectCSPMGCPAccount": "", + "CreateCSPMAwsAccount": "", + "CreateCSPMAzureAccount": "", + "CreateCSPMAzureManagementGroup": "", + "CreateCSPMGCPAccount": "", + "CreateParser": "", + "CreateUser": "", + "DeleteCSPMAwsAccount": "", + "DeleteCSPMAzureAccount": "", + "DeleteCSPMAzureManagementGroup": "", + "DeleteCSPMGCPAccount": "", + "DeleteUser": "", + "DownloadFile": "", + "EnumerateFile": "", + "FetchFilesDownloadInfo": "FetchFilesDownloadInfoV2", + "GetAvailableRoleIds": "", + "GetCSPMAwsAccount": "", + "GetCSPMAwsConsoleSetupURLs": "", + "GetCSPMAzureAccount": "", + "GetCSPMAzureManagementGroup": "", + "GetCSPMAzureUserScriptsAttachment": "", + "GetCSPMGCPAccount": "", + "GetCSPMGCPServiceAccountsExt": "", + "GetCSPMGCPUserScriptsAttachment": "", + "GetCSPMGCPValidateAccountsExt": "", + "GetParser": "", + "GetQueriesAlertsV1": "GetQueriesAlertsV2", + "GetRoles": "", + "GetUserRoleIds": "", + "GrantUserRoleIds": "", + "ImageMatchesPolicy": "", + "PatchCSPMAwsAccount": "", + "PatchEntitiesAlertsV2": "PatchEntitiesAlertsV3", + "PostAggregatesAlertsV1": "PostAggregatesAlertsV2", + "PostEntitiesAlertsV1": "PostEntitiesAlertsV2", + "QueryDevicesByFilterScroll": "", + "RetrieveEmailsByCID": "", + "RetrieveUser": "", + "RetrieveUserUUID": "", + "RetrieveUserUUIDsByCID": "", + "RevokeUserRoleIds": "", + "UpdateCSPMAzureAccount": "", + "UpdateCSPMAzureAccountClientID": "", + "UpdateCSPMAzureTenantDefaultSubscriptionID": "", + "UpdateCSPMGCPAccount": "", + "UpdateCSPMGCPServiceAccountsExt": "", + "UpdateParser": "", + "UpdateUser": "", + "ValidateCSPMGCPServiceAccountExt": "", + "aggregates.notification-groups.post.v1": "aggregates_notification_groups_post_v2", + "aggregates_notification_groups_post_v1": "aggregates_notification_groups_post_v2", + "combinedUserRolesV1": "CombinedUserRolesV3", + "createDeviceControlPolicies": "postDeviceControlPoliciesV2", + "deleteCIDGroupMembers": "deleteCIDGroupMembersV2", + "deleteCIDGroupMembersV1": "deleteCIDGroupMembersV2", + "entities.files_download.post.v1": "", + "entities.notification-groups.delete.v1": "entities_notification_groups_delete_v2", + "entities.notification-groups.get.v1": "entities_notification_groups_get_v2", + "entities.notification-groups.patch.v1": "entities_notification_groups_patch_v2", + "entities.notification-groups.post.v1": "entities_notification_groups_post_v2", + "entitiesRolesV1": "", + "entities_files_download_post_v1": "", + "entities_notification_groups_delete_v1": "entities_notification_groups_delete_v2", + "entities_notification_groups_get_v1": "entities_notification_groups_get_v2", + "entities_notification_groups_patch_v1": "entities_notification_groups_patch_v2", + "entities_notification_groups_post_v1": "entities_notification_groups_post_v2", + "getCIDGroupByIdV1": "getCIDGroupByIdV2", + "getCIDGroupMembersByV1": "getCIDGroupMembersByV2", + "getCloudEventIDs": "", + "getDefaultDeviceControlPolicies": "", + "getDeviceControlPolicies": "getDeviceControlPoliciesV2", + "getUserGroupMembersByIDV1": "getUserGroupMembersByIDV2", + "getUserGroupsByIDV1": "getUserGroupsByIDV2", + "queries.notification-groups.get.v1": "queries_notification_groups_get_v2", + "queries_notification_groups_get_v1": "queries_notification_groups_get_v2", + "queryCombinedDeviceControlPolicies": "", + "retrieveUser": "", + "updateDefaultDeviceControlPolicies": "", + "updateDeviceControlPolicies": "patchDeviceControlPoliciesV2" } _deprecated_cls_mapping = { diff --git a/src/falconpy/_payload/__init__.py b/src/falconpy/_payload/__init__.py index 0dee81208..296453f22 100644 --- a/src/falconpy/_payload/__init__.py +++ b/src/falconpy/_payload/__init__.py @@ -38,17 +38,24 @@ apply_agent_tasks_payload, classify_domains_payload, create_destination_group_payload, + create_sensitive_data_profile_payload, deactivate_agents_payload, query_combined_seraphic_agents_payload, query_destination_groups_payload, + query_sensitive_data_profiles_payload, query_seraphic_agents_payload, query_seraphic_rules_payload, update_destination_group_payload, + update_sensitive_data_profile_payload, update_seraphic_rule_payload, ) from ._cloud_security_assets import cloud_security_assets_entities_post_payload from ._cloud_security_detections import cspm_evaluations_iom_entities_post_payload from ._code_security import exchange_github_app_code_payload, register_scm_app_payload +from ._eval_dataset_entries import create_eval_dataset_entry_payload, update_eval_dataset_entry_payload +from ._eval_datasets import create_eval_dataset_payload, update_eval_dataset_payload +from ._eval_evaluators import create_eval_evaluator_payload, update_eval_evaluator_payload +from ._eval_runs import create_eval_run_payload, perform_eval_run_action_payload from ._falcon_id import update_third_party_passkey_registry_payload from ._federated_connections import patch_federated_connections_config_payload, post_federated_connections_config_payload from ._generic import ( @@ -80,6 +87,10 @@ correlation_rules_template_payload ) from ._case_management import ( + add_case_access_tags_payload, + add_case_alert_evidence_v2_payload, + add_case_custom_evidence_payload, + add_case_user_evidence_payload, case_evidence_payload, case_manage_payload, case_management_create_notification_payload, @@ -189,16 +200,21 @@ ioa_ss_default_exclusion_payload ) from ._it_automation import ( - task_payload, - task_execution_payload, + aggregate_patch_deployment_configs_payload, + aggregate_patch_deployment_executions_payload, + aggregate_patch_host_deployments_payload, + automation_live_query_payload, + automation_policy_payload, + automation_user_group_payload, + cancel_task_execution_payload, + create_patch_deployment_config_payload, execution_results_search_payload, + policy_host_group_payload, rerun_payload, scheduled_task_payload, - automation_policy_payload, - policy_host_group_payload, - automation_live_query_payload, - automation_user_group_payload, - cancel_task_execution_payload + task_execution_payload, + task_payload, + update_patch_deployment_config_payload, ) from ._mobile_enrollment import mobile_enrollment_payload from ._network_scan_global_configs import network_scan_global_configs_payload @@ -243,6 +259,7 @@ bulk_update_saved_query_labels_payload, create_parser_extension_payload, create_persisted_aggregation_payload, + create_scheduled_report_payload, ngsiem_auto_update_policy_payload, ngsiem_bulk_install_parsers_payload, ngsiem_clone_parser_payload, @@ -257,6 +274,7 @@ update_parser_extension_payload, update_persisted_aggregation_payload, update_saved_query_labels_payload, + update_scheduled_report_payload, ) from ._prevention_policy import prevention_policy_payload from ._saas_security import ( @@ -264,6 +282,7 @@ create_check_journal_comment_payload, create_user_journal_comment_payload, restore_affected_entity_payload, + set_check_impact_payload, set_check_param_payload, ) from ._scanning_orchestrator import create_schedules_payload, trigger_scan_by_schedule_payload, update_schedules_payload @@ -332,6 +351,8 @@ snapshot_launch_payload ) from ._user_management import ( + get_permission_groups_payload, + get_permissions_payload, get_user_allowed_actions_payload, get_user_invitations_payload, retrieve_users_v2_payload, @@ -461,5 +482,18 @@ "create_check_journal_comment_payload", "create_user_journal_comment_payload", "restore_affected_entity_payload", "set_check_param_payload", "get_user_allowed_actions_payload", "get_user_invitations_payload", - "retrieve_users_v2_payload", "update_user_roles_payload" + "retrieve_users_v2_payload", "update_user_roles_payload", + "create_sensitive_data_profile_payload", "query_sensitive_data_profiles_payload", + "update_sensitive_data_profile_payload", "add_case_access_tags_payload", + "add_case_alert_evidence_v2_payload", "add_case_custom_evidence_payload", + "add_case_user_evidence_payload", "create_eval_dataset_entry_payload", + "update_eval_dataset_entry_payload", "create_eval_dataset_payload", + "update_eval_dataset_payload", "create_eval_evaluator_payload", + "update_eval_evaluator_payload", "create_eval_run_payload", + "perform_eval_run_action_payload", + "aggregate_patch_deployment_configs_payload", "aggregate_patch_deployment_executions_payload", + "aggregate_patch_host_deployments_payload", "create_patch_deployment_config_payload", + "update_patch_deployment_config_payload", "create_scheduled_report_payload", + "update_scheduled_report_payload", "set_check_impact_payload", + "get_permission_groups_payload", "get_permissions_payload" ] diff --git a/src/falconpy/_payload/_agent_invocation.py b/src/falconpy/_payload/_agent_invocation.py index 87982ffb0..b5aac3b50 100644 --- a/src/falconpy/_payload/_agent_invocation.py +++ b/src/falconpy/_payload/_agent_invocation.py @@ -50,7 +50,7 @@ def invoke_published_agent_external_v1_payload(passed_keywords: dict) -> dict: } """ returned_payload = {} - keys = ["credit_cents_limit", "deadline_seconds", "id", "messages"] + keys = ["credit_cents_limit", "deadline_seconds", "id", "messages", "project_id"] for key in keys: if passed_keywords.get(key, None) is not None: returned_payload[key] = passed_keywords.get(key) @@ -72,7 +72,7 @@ def invoke_agent_version_external_v1_payload(passed_keywords: dict) -> dict: } """ returned_payload = {} - keys = ["credit_cents_limit", "deadline_seconds", "id", "messages", "version_id"] + keys = ["credit_cents_limit", "deadline_seconds", "id", "messages", "project_id", "version_id"] for key in keys: if passed_keywords.get(key, None) is not None: returned_payload[key] = passed_keywords.get(key) diff --git a/src/falconpy/_payload/_agents.py b/src/falconpy/_payload/_agents.py index 6f2f22857..18a004e6b 100644 --- a/src/falconpy/_payload/_agents.py +++ b/src/falconpy/_payload/_agents.py @@ -94,7 +94,7 @@ def create_or_update_agent_payload(passed_keywords: dict) -> dict: } """ returned_payload = {} - keys = ["duplicate_from_agent_id", "id", "template_id", "version_definition"] + keys = ["duplicate_from_agent_id", "id", "project_id", "template_id", "version_definition"] for key in keys: if passed_keywords.get(key, None) is not None: returned_payload[key] = passed_keywords.get(key) diff --git a/src/falconpy/_payload/_browser_security.py b/src/falconpy/_payload/_browser_security.py index bd31f714d..27cb8a045 100644 --- a/src/falconpy/_payload/_browser_security.py +++ b/src/falconpy/_payload/_browser_security.py @@ -207,7 +207,7 @@ def apply_agent_tasks_payload(passed_keywords: dict) -> dict: } """ returned_payload = {} - keys = ["actions", "ttl"] + keys = ["actions", "ttlHours"] for key in keys: if passed_keywords.get(key, None) is not None: returned_payload[key] = passed_keywords.get(key) @@ -521,3 +521,77 @@ def query_seraphic_rules_payload(passed_keywords: dict) -> dict: returned_payload[key] = passed_keywords.get(key) return returned_payload + + +def create_sensitive_data_profile_payload(passed_keywords: dict) -> dict: + """Create a properly formatted payload for a CreateSensitiveDataProfile request. + + { + "apply_exact_match": true, + "custom_regex": [ + "string" + ], + "description": "string", + "name": "string", + "predefined_piis": [ + "string" + ] + } + """ + returned_payload = {} + keys = ["apply_exact_match", "custom_regex", "description", "name", "predefined_piis"] + for key in keys: + if passed_keywords.get(key, None) is not None: + returned_payload[key] = passed_keywords.get(key) + + return returned_payload + + +def query_sensitive_data_profiles_payload(passed_keywords: dict) -> dict: + """Create a properly formatted payload for a QuerySensitiveDataProfiles request. + + { + "advanced_filter": "string", + "exclude": [ + "string" + ], + "filter": "string", + "limit": 0, + "search": "string", + "skip": 0, + "sort": [ + "string" + ] + } + """ + returned_payload = {} + keys = ["advanced_filter", "exclude", "filter", "limit", "search", "skip", "sort"] + for key in keys: + if passed_keywords.get(key, None) is not None: + returned_payload[key] = passed_keywords.get(key) + + return returned_payload + + +def update_sensitive_data_profile_payload(passed_keywords: dict) -> dict: + """Create a properly formatted payload for a UpdateSensitiveDataProfile request. + + { + "apply_exact_match": true, + "custom_regex": [ + "string" + ], + "description": "string", + "name": "string", + "predefined_piis": [ + "string" + ] + } + """ + returned_payload = {} + keys = ["apply_exact_match", "custom_regex", "description", "name", "predefined_piis"] + for key in keys: + if passed_keywords.get(key, None) is not None: + returned_payload[key] = passed_keywords.get(key) + + return returned_payload diff --git a/src/falconpy/_payload/_case_management.py b/src/falconpy/_payload/_case_management.py index 57710d2fd..4a6b2a664 100644 --- a/src/falconpy/_payload/_case_management.py +++ b/src/falconpy/_payload/_case_management.py @@ -419,3 +419,79 @@ def entities_merge_post_v1_payload(passed_keywords: dict) -> dict: returned_payload[key] = passed_keywords.get(key) return returned_payload + + +def add_case_access_tags_payload(passed_keywords: dict) -> dict: + """Create a properly formatted payload for a entities_case_access_tags_post_v1 request. + + { + "access_tag_ids": [ + "string" + ], + "id": "string" + } + """ + returned_payload = {} + keys = ["access_tag_ids", "id"] + for key in keys: + if passed_keywords.get(key, None) is not None: + returned_payload[key] = passed_keywords.get(key) + + return returned_payload + + +def add_case_alert_evidence_v2_payload(passed_keywords: dict) -> dict: + """Create a properly formatted payload for a entities_alert_evidence_post_v2 request. + + { + "alerts": [ + "string" + ], + "id": "string" + } + """ + returned_payload = {} + keys = ["alerts", "id"] + for key in keys: + if passed_keywords.get(key, None) is not None: + returned_payload[key] = passed_keywords.get(key) + + return returned_payload + + +def add_case_custom_evidence_payload(passed_keywords: dict) -> dict: + """Create a properly formatted payload for a entities_custom_evidence_post_v1 request. + + { + "case_id": "string", + "evidence": [ + "string" + ] + } + """ + returned_payload = {} + keys = ["case_id", "evidence"] + for key in keys: + if passed_keywords.get(key, None) is not None: + returned_payload[key] = passed_keywords.get(key) + + return returned_payload + + +def add_case_user_evidence_payload(passed_keywords: dict) -> dict: + """Create a properly formatted payload for a entities_user_evidence_post_v1 request. + + { + "id": "string", + "users": [ + "string" + ] + } + """ + returned_payload = {} + keys = ["id", "users"] + for key in keys: + if passed_keywords.get(key, None) is not None: + returned_payload[key] = passed_keywords.get(key) + + return returned_payload diff --git a/src/falconpy/_payload/_eval_dataset_entries.py b/src/falconpy/_payload/_eval_dataset_entries.py new file mode 100644 index 000000000..130947403 --- /dev/null +++ b/src/falconpy/_payload/_eval_dataset_entries.py @@ -0,0 +1,293 @@ +"""Internal payload handling library - EvalDatasetEntries. + + _______ __ _______ __ __ __ +| _ .----.-----.--.--.--.--| | _ | |_.----|__| |--.-----. +|. 1___| _| _ | | | | _ | 1___| _| _| | <| -__| +|. |___|__| |_____|________|_____|____ |____|__| |__|__|__|_____| +|: 1 | |: 1 | +|::.. . | CROWDSTRIKE FALCON |::.. . | FalconPy +`-------' `-------' + +OAuth2 API - Customer SDK + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to +""" + + +def update_eval_dataset_entry_payload(passed_keywords: dict) -> dict: + """Create a properly formatted payload for a EntitiesEvalDatasetEntriesUpdateV1 request. + + { + "created_at": "string", + "created_by": { + "access_granted_at": "string", + "cid": "string", + "created_at": "string", + "factors": [ + "string" + ], + "first_name": "string", + "last_login_at": "string", + "last_name": "string", + "status": "string", + "uid": "string", + "updated_at": "string", + "user_type": "string", + "uuid": "string", + "api_client_id": "string", + "email": "string", + "name": "string" + }, + "data": "string", + "dataset_id": "string", + "description": "string", + "id": "string", + "is_deleted": true, + "metadata": "string", + "name": "string", + "owner": "string", + "project_id": "string", + "tags": [ + "string" + ], + "updated_at": "string", + "updated_by": { + "access_granted_at": "string", + "cid": "string", + "created_at": "string", + "factors": [ + "string" + ], + "first_name": "string", + "last_login_at": "string", + "last_name": "string", + "status": "string", + "uid": "string", + "updated_at": "string", + "user_type": "string", + "uuid": "string", + "api_client_id": "string", + "email": "string", + "name": "string" + } + } + """ + returned_payload = {} + keys = [ + "created_at", + "created_by", + "data", + "dataset_id", + "description", + "id", + "is_deleted", + "metadata", + "name", + "owner", + "project_id", + "tags", + "updated_at", + "updated_by" + ] + for key in keys: + if passed_keywords.get(key, None) is not None: + returned_payload[key] = passed_keywords.get(key) + + created_by_keys = [ + "access_granted_at", + "cid", + "created_at", + "factors", + "first_name", + "last_login_at", + "last_name", + "status", + "uid", + "updated_at", + "user_type", + "uuid", + "api_client_id", + "email", + "name" + ] + if "created_by" not in returned_payload: + returned_payload["created_by"] = {} + for key in created_by_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["created_by"][key] = passed_keywords.get(key) + + updated_by_keys = [ + "access_granted_at", + "cid", + "created_at", + "factors", + "first_name", + "last_login_at", + "last_name", + "status", + "uid", + "updated_at", + "user_type", + "uuid", + "api_client_id", + "email", + "name" + ] + if "updated_by" not in returned_payload: + returned_payload["updated_by"] = {} + for key in updated_by_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["updated_by"][key] = passed_keywords.get(key) + + return returned_payload + + +def create_eval_dataset_entry_payload(passed_keywords: dict) -> dict: + """Create a properly formatted payload for a EntitiesEvalDatasetEntriesCreateV1 request. + + { + "created_at": "string", + "created_by": { + "access_granted_at": "string", + "cid": "string", + "created_at": "string", + "factors": [ + "string" + ], + "first_name": "string", + "last_login_at": "string", + "last_name": "string", + "status": "string", + "uid": "string", + "updated_at": "string", + "user_type": "string", + "uuid": "string", + "api_client_id": "string", + "email": "string", + "name": "string" + }, + "data": "string", + "dataset_id": "string", + "description": "string", + "id": "string", + "is_deleted": true, + "metadata": "string", + "name": "string", + "owner": "string", + "project_id": "string", + "tags": [ + "string" + ], + "updated_at": "string", + "updated_by": { + "access_granted_at": "string", + "cid": "string", + "created_at": "string", + "factors": [ + "string" + ], + "first_name": "string", + "last_login_at": "string", + "last_name": "string", + "status": "string", + "uid": "string", + "updated_at": "string", + "user_type": "string", + "uuid": "string", + "api_client_id": "string", + "email": "string", + "name": "string" + } + } + """ + returned_payload = {} + keys = [ + "created_at", + "created_by", + "data", + "dataset_id", + "description", + "id", + "is_deleted", + "metadata", + "name", + "owner", + "project_id", + "tags", + "updated_at", + "updated_by" + ] + for key in keys: + if passed_keywords.get(key, None) is not None: + returned_payload[key] = passed_keywords.get(key) + + created_by_keys = [ + "access_granted_at", + "cid", + "created_at", + "factors", + "first_name", + "last_login_at", + "last_name", + "status", + "uid", + "updated_at", + "user_type", + "uuid", + "api_client_id", + "email", + "name" + ] + if "created_by" not in returned_payload: + returned_payload["created_by"] = {} + for key in created_by_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["created_by"][key] = passed_keywords.get(key) + + updated_by_keys = [ + "access_granted_at", + "cid", + "created_at", + "factors", + "first_name", + "last_login_at", + "last_name", + "status", + "uid", + "updated_at", + "user_type", + "uuid", + "api_client_id", + "email", + "name" + ] + if "updated_by" not in returned_payload: + returned_payload["updated_by"] = {} + for key in updated_by_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["updated_by"][key] = passed_keywords.get(key) + + return returned_payload diff --git a/src/falconpy/_payload/_eval_datasets.py b/src/falconpy/_payload/_eval_datasets.py new file mode 100644 index 000000000..3453a2074 --- /dev/null +++ b/src/falconpy/_payload/_eval_datasets.py @@ -0,0 +1,195 @@ +"""Internal payload handling library - EvalDatasets. + + _______ __ _______ __ __ __ +| _ .----.-----.--.--.--.--| | _ | |_.----|__| |--.-----. +|. 1___| _| _ | | | | _ | 1___| _| _| | <| -__| +|. |___|__| |_____|________|_____|____ |____|__| |__|__|__|_____| +|: 1 | |: 1 | +|::.. . | CROWDSTRIKE FALCON |::.. . | FalconPy +`-------' `-------' + +OAuth2 API - Customer SDK + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to +""" + + +def update_eval_dataset_payload(passed_keywords: dict) -> dict: + """Create a properly formatted payload for a EntitiesEvalDatasetsUpdateV1 request. + + { + "agent_ids": [ + "string" + ], + "created_at": "string", + "created_by": { + "access_granted_at": "string", + "cid": "string", + "created_at": "string", + "factors": [ + "string" + ], + "first_name": "string", + "last_login_at": "string", + "last_name": "string", + "status": "string", + "uid": "string", + "updated_at": "string", + "user_type": "string", + "uuid": "string", + "api_client_id": "string", + "email": "string", + "name": "string" + }, + "default_prompt_template": "string", + "description": "string", + "entryschema": "string", + "id": "string", + "is_deleted": true, + "metadata": "string", + "name": "string", + "owner": "string", + "project_id": "string", + "tags": [ + "string" + ], + "updated_at": "string", + "updated_by": { + "access_granted_at": "string", + "cid": "string", + "created_at": "string", + "factors": [ + "string" + ], + "first_name": "string", + "last_login_at": "string", + "last_name": "string", + "status": "string", + "uid": "string", + "updated_at": "string", + "user_type": "string", + "uuid": "string", + "api_client_id": "string", + "email": "string", + "name": "string" + } + } + """ + returned_payload = {} + keys = [ + "agent_ids", + "created_at", + "created_by", + "default_prompt_template", + "description", + "entryschema", + "id", + "is_deleted", + "metadata", + "name", + "owner", + "project_id", + "tags", + "updated_at", + "updated_by" + ] + for key in keys: + if passed_keywords.get(key, None) is not None: + returned_payload[key] = passed_keywords.get(key) + + created_by_keys = [ + "access_granted_at", + "cid", + "created_at", + "factors", + "first_name", + "last_login_at", + "last_name", + "status", + "uid", + "updated_at", + "user_type", + "uuid", + "api_client_id", + "email", + "name" + ] + if "created_by" not in returned_payload: + returned_payload["created_by"] = {} + for key in created_by_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["created_by"][key] = passed_keywords.get(key) + + updated_by_keys = [ + "access_granted_at", + "cid", + "created_at", + "factors", + "first_name", + "last_login_at", + "last_name", + "status", + "uid", + "updated_at", + "user_type", + "uuid", + "api_client_id", + "email", + "name" + ] + if "updated_by" not in returned_payload: + returned_payload["updated_by"] = {} + for key in updated_by_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["updated_by"][key] = passed_keywords.get(key) + + return returned_payload + + +def create_eval_dataset_payload(passed_keywords: dict) -> dict: + """Create a properly formatted payload for a EntitiesEvalDatasetsCreateV1 request. + + { + "agent_ids": [ + "string" + ], + "description": "string", + "id": "string", + "metadata": "string", + "name": "string", + "project_id": "string", + "tags": [ + "string" + ] + } + """ + returned_payload = {} + keys = ["agent_ids", "description", "id", "metadata", "name", "project_id", "tags"] + for key in keys: + if passed_keywords.get(key, None) is not None: + returned_payload[key] = passed_keywords.get(key) + + return returned_payload diff --git a/src/falconpy/_payload/_eval_evaluators.py b/src/falconpy/_payload/_eval_evaluators.py new file mode 100644 index 000000000..bd88a4e83 --- /dev/null +++ b/src/falconpy/_payload/_eval_evaluators.py @@ -0,0 +1,301 @@ +"""Internal payload handling library - EvalEvaluators. + + _______ __ _______ __ __ __ +| _ .----.-----.--.--.--.--| | _ | |_.----|__| |--.-----. +|. 1___| _| _ | | | | _ | 1___| _| _| | <| -__| +|. |___|__| |_____|________|_____|____ |____|__| |__|__|__|_____| +|: 1 | |: 1 | +|::.. . | CROWDSTRIKE FALCON |::.. . | FalconPy +`-------' `-------' + +OAuth2 API - Customer SDK + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to +""" + + +def update_eval_evaluator_payload(passed_keywords: dict) -> dict: + """Create a properly formatted payload for a EntitiesEvalEvaluatorsUpdateV1 request. + + { + "agent_ids": [ + "string" + ], + "config": "string", + "created_at": "string", + "created_by": { + "access_granted_at": "string", + "cid": "string", + "created_at": "string", + "factors": [ + "string" + ], + "first_name": "string", + "last_login_at": "string", + "last_name": "string", + "status": "string", + "uid": "string", + "updated_at": "string", + "user_type": "string", + "uuid": "string", + "api_client_id": "string", + "email": "string", + "name": "string" + }, + "description": "string", + "evaluator_type": "string", + "id": "string", + "is_deleted": true, + "metadata": "string", + "name": "string", + "owner": "string", + "project_id": "string", + "tags": [ + "string" + ], + "updated_at": "string", + "updated_by": { + "access_granted_at": "string", + "cid": "string", + "created_at": "string", + "factors": [ + "string" + ], + "first_name": "string", + "last_login_at": "string", + "last_name": "string", + "status": "string", + "uid": "string", + "updated_at": "string", + "user_type": "string", + "uuid": "string", + "api_client_id": "string", + "email": "string", + "name": "string" + } + } + """ + returned_payload = {} + keys = [ + "agent_ids", + "config", + "created_at", + "created_by", + "description", + "evaluator_type", + "id", + "is_deleted", + "metadata", + "name", + "owner", + "project_id", + "tags", + "updated_at", + "updated_by" + ] + for key in keys: + if passed_keywords.get(key, None) is not None: + returned_payload[key] = passed_keywords.get(key) + + created_by_keys = [ + "access_granted_at", + "cid", + "created_at", + "factors", + "first_name", + "last_login_at", + "last_name", + "status", + "uid", + "updated_at", + "user_type", + "uuid", + "api_client_id", + "email", + "name" + ] + if "created_by" not in returned_payload: + returned_payload["created_by"] = {} + for key in created_by_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["created_by"][key] = passed_keywords.get(key) + + updated_by_keys = [ + "access_granted_at", + "cid", + "created_at", + "factors", + "first_name", + "last_login_at", + "last_name", + "status", + "uid", + "updated_at", + "user_type", + "uuid", + "api_client_id", + "email", + "name" + ] + if "updated_by" not in returned_payload: + returned_payload["updated_by"] = {} + for key in updated_by_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["updated_by"][key] = passed_keywords.get(key) + + return returned_payload + + +def create_eval_evaluator_payload(passed_keywords: dict) -> dict: + """Create a properly formatted payload for a EntitiesEvalEvaluatorsCreateV1 request. + + { + "agent_ids": [ + "string" + ], + "config": "string", + "created_at": "string", + "created_by": { + "access_granted_at": "string", + "cid": "string", + "created_at": "string", + "factors": [ + "string" + ], + "first_name": "string", + "last_login_at": "string", + "last_name": "string", + "status": "string", + "uid": "string", + "updated_at": "string", + "user_type": "string", + "uuid": "string", + "api_client_id": "string", + "email": "string", + "name": "string" + }, + "description": "string", + "evaluator_type": "string", + "id": "string", + "is_deleted": true, + "metadata": "string", + "name": "string", + "owner": "string", + "project_id": "string", + "tags": [ + "string" + ], + "updated_at": "string", + "updated_by": { + "access_granted_at": "string", + "cid": "string", + "created_at": "string", + "factors": [ + "string" + ], + "first_name": "string", + "last_login_at": "string", + "last_name": "string", + "status": "string", + "uid": "string", + "updated_at": "string", + "user_type": "string", + "uuid": "string", + "api_client_id": "string", + "email": "string", + "name": "string" + } + } + """ + returned_payload = {} + keys = [ + "agent_ids", + "config", + "created_at", + "created_by", + "description", + "evaluator_type", + "id", + "is_deleted", + "metadata", + "name", + "owner", + "project_id", + "tags", + "updated_at", + "updated_by" + ] + for key in keys: + if passed_keywords.get(key, None) is not None: + returned_payload[key] = passed_keywords.get(key) + + created_by_keys = [ + "access_granted_at", + "cid", + "created_at", + "factors", + "first_name", + "last_login_at", + "last_name", + "status", + "uid", + "updated_at", + "user_type", + "uuid", + "api_client_id", + "email", + "name" + ] + if "created_by" not in returned_payload: + returned_payload["created_by"] = {} + for key in created_by_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["created_by"][key] = passed_keywords.get(key) + + updated_by_keys = [ + "access_granted_at", + "cid", + "created_at", + "factors", + "first_name", + "last_login_at", + "last_name", + "status", + "uid", + "updated_at", + "user_type", + "uuid", + "api_client_id", + "email", + "name" + ] + if "updated_by" not in returned_payload: + returned_payload["updated_by"] = {} + for key in updated_by_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["updated_by"][key] = passed_keywords.get(key) + + return returned_payload diff --git a/src/falconpy/_payload/_eval_runs.py b/src/falconpy/_payload/_eval_runs.py new file mode 100644 index 000000000..c4d305277 --- /dev/null +++ b/src/falconpy/_payload/_eval_runs.py @@ -0,0 +1,260 @@ +"""Internal payload handling library - EvalRuns. + + _______ __ _______ __ __ __ +| _ .----.-----.--.--.--.--| | _ | |_.----|__| |--.-----. +|. 1___| _| _ | | | | _ | 1___| _| _| | <| -__| +|. |___|__| |_____|________|_____|____ |____|__| |__|__|__|_____| +|: 1 | |: 1 | +|::.. . | CROWDSTRIKE FALCON |::.. . | FalconPy +`-------' `-------' + +OAuth2 API - Customer SDK + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to +""" + + +def create_eval_run_payload(passed_keywords: dict) -> dict: + """Create a properly formatted payload for a EntitiesEvalRunsCreateV1 request. + + { + "actual_cost": "string", + "agent_id": "string", + "agent_version_id": "string", + "completed_at": "string", + "created_at": "string", + "created_by": { + "access_granted_at": "string", + "cid": "string", + "created_at": "string", + "factors": [ + "string" + ], + "first_name": "string", + "last_login_at": "string", + "last_name": "string", + "status": "string", + "uid": "string", + "updated_at": "string", + "user_type": "string", + "uuid": "string", + "api_client_id": "string", + "email": "string", + "name": "string" + }, + "dataset_entry_ids": [ + "string" + ], + "dataset_ids": [ + "string" + ], + "entry_tags": [ + "string" + ], + "estimated_cost": "string", + "evaluator_ids": [ + "string" + ], + "id": "string", + "is_deleted": true, + "metadata": "string", + "name": "string", + "owner": "string", + "progress": { + "completed_cases": 0, + "error_cases": 0, + "total_cases": 0 + }, + "project_id": "string", + "status": "string", + "summary": { + "average_latency": 0, + "average_score": "string", + "error_cases": 0, + "evaluator_results": [ + "string" + ], + "failed_cases": 0, + "median_score": "string", + "passed_cases": 0, + "std_deviation": "string", + "total_cases": 0, + "total_duration": 0 + }, + "updated_at": "string", + "updated_by": { + "access_granted_at": "string", + "cid": "string", + "created_at": "string", + "factors": [ + "string" + ], + "first_name": "string", + "last_login_at": "string", + "last_name": "string", + "status": "string", + "uid": "string", + "updated_at": "string", + "user_type": "string", + "uuid": "string", + "api_client_id": "string", + "email": "string", + "name": "string" + }, + "variable_values": "string" + } + """ + returned_payload = {} + keys = [ + "actual_cost", + "agent_id", + "agent_version_id", + "completed_at", + "created_at", + "created_by", + "dataset_entry_ids", + "dataset_ids", + "entry_tags", + "estimated_cost", + "evaluator_ids", + "id", + "is_deleted", + "metadata", + "name", + "owner", + "progress", + "project_id", + "status", + "summary", + "updated_at", + "updated_by", + "variable_values" + ] + for key in keys: + if passed_keywords.get(key, None) is not None: + returned_payload[key] = passed_keywords.get(key) + + created_by_keys = [ + "access_granted_at", + "cid", + "created_at", + "factors", + "first_name", + "last_login_at", + "last_name", + "status", + "uid", + "updated_at", + "user_type", + "uuid", + "api_client_id", + "email", + "name" + ] + if "created_by" not in returned_payload: + returned_payload["created_by"] = {} + for key in created_by_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["created_by"][key] = passed_keywords.get(key) + + progress_keys = ["completed_cases", "error_cases", "total_cases"] + if "progress" not in returned_payload: + returned_payload["progress"] = {} + for key in progress_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["progress"][key] = passed_keywords.get(key) + + summary_keys = [ + "average_latency", + "average_score", + "error_cases", + "evaluator_results", + "failed_cases", + "median_score", + "passed_cases", + "std_deviation", + "total_cases", + "total_duration" + ] + if "summary" not in returned_payload: + returned_payload["summary"] = {} + for key in summary_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["summary"][key] = passed_keywords.get(key) + + updated_by_keys = [ + "access_granted_at", + "cid", + "created_at", + "factors", + "first_name", + "last_login_at", + "last_name", + "status", + "uid", + "updated_at", + "user_type", + "uuid", + "api_client_id", + "email", + "name" + ] + if "updated_by" not in returned_payload: + returned_payload["updated_by"] = {} + for key in updated_by_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["updated_by"][key] = passed_keywords.get(key) + + return returned_payload + + +def perform_eval_run_action_payload(passed_keywords: dict) -> dict: + """Create a properly formatted payload for a EntitiesEvalRunsActionV1 request. + + { + "action": "string", + "case_cost_limit": { + "agent_run_credit_cents": 0, + "judge_run_credit_cents": 0 + }, + "id": "string", + "project_id": "string" + } + """ + returned_payload = {} + keys = ["action", "case_cost_limit", "id", "project_id"] + for key in keys: + if passed_keywords.get(key, None) is not None: + returned_payload[key] = passed_keywords.get(key) + + case_cost_limit_keys = ["agent_run_credit_cents", "judge_run_credit_cents"] + if "case_cost_limit" not in returned_payload: + returned_payload["case_cost_limit"] = {} + for key in case_cost_limit_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["case_cost_limit"][key] = passed_keywords.get(key) + + return returned_payload diff --git a/src/falconpy/_payload/_it_automation.py b/src/falconpy/_payload/_it_automation.py index b2e61ad53..d8e506561 100644 --- a/src/falconpy/_payload/_it_automation.py +++ b/src/falconpy/_payload/_it_automation.py @@ -569,3 +569,544 @@ def automation_live_query_payload(passed_keywords: dict) -> dict: returned_payload[key] = passed_keywords.get(key, None) return returned_payload + + +def aggregate_patch_deployment_configs_payload(passed_keywords: dict) -> dict: + """Create a properly formatted payload for a AggregateDeploymentConfigsV1 request. + + { + "date_ranges": [ + "string" + ], + "exclude": "string", + "extended_bounds": { + "max": "string", + "min": "string" + }, + "field": "string", + "filter": "string", + "filters_spec": { + "filters": "string", + "other_bucket": true, + "other_bucket_key": "string" + }, + "from": 0, + "include": "string", + "interval": "string", + "max_doc_count": 0, + "min_doc_count": 0, + "missing": "string", + "name": "string", + "percents": [ + "string" + ], + "q": "string", + "ranges": [ + "string" + ], + "size": 0, + "sort": "string", + "sub_aggregates": [ + "string" + ], + "time_zone": "string", + "type": "string" + } + """ + returned_payload = {} + keys = [ + "date_ranges", + "exclude", + "extended_bounds", + "field", + "filter", + "filters_spec", + "from", + "include", + "interval", + "max_doc_count", + "min_doc_count", + "missing", + "name", + "percents", + "q", + "ranges", + "size", + "sort", + "sub_aggregates", + "time_zone", + "type" + ] + for key in keys: + if passed_keywords.get(key, None) is not None: + returned_payload[key] = passed_keywords.get(key) + + extended_bounds_keys = ["max", "min"] + if "extended_bounds" not in returned_payload: + returned_payload["extended_bounds"] = {} + for key in extended_bounds_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["extended_bounds"][key] = passed_keywords.get(key) + + filters_spec_keys = ["filters", "other_bucket", "other_bucket_key"] + if "filters_spec" not in returned_payload: + returned_payload["filters_spec"] = {} + for key in filters_spec_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["filters_spec"][key] = passed_keywords.get(key) + + return returned_payload + + +def aggregate_patch_deployment_executions_payload(passed_keywords: dict) -> dict: + """Create a properly formatted payload for a AggregateDeploymentExecutionsV1 request. + + { + "date_ranges": [ + "string" + ], + "exclude": "string", + "extended_bounds": { + "max": "string", + "min": "string" + }, + "field": "string", + "filter": "string", + "filters_spec": { + "filters": "string", + "other_bucket": true, + "other_bucket_key": "string" + }, + "from": 0, + "include": "string", + "interval": "string", + "max_doc_count": 0, + "min_doc_count": 0, + "missing": "string", + "name": "string", + "percents": [ + "string" + ], + "q": "string", + "ranges": [ + "string" + ], + "size": 0, + "sort": "string", + "sub_aggregates": [ + "string" + ], + "time_zone": "string", + "type": "string" + } + """ + returned_payload = {} + keys = [ + "date_ranges", + "exclude", + "extended_bounds", + "field", + "filter", + "filters_spec", + "from", + "include", + "interval", + "max_doc_count", + "min_doc_count", + "missing", + "name", + "percents", + "q", + "ranges", + "size", + "sort", + "sub_aggregates", + "time_zone", + "type" + ] + for key in keys: + if passed_keywords.get(key, None) is not None: + returned_payload[key] = passed_keywords.get(key) + + extended_bounds_keys = ["max", "min"] + if "extended_bounds" not in returned_payload: + returned_payload["extended_bounds"] = {} + for key in extended_bounds_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["extended_bounds"][key] = passed_keywords.get(key) + + filters_spec_keys = ["filters", "other_bucket", "other_bucket_key"] + if "filters_spec" not in returned_payload: + returned_payload["filters_spec"] = {} + for key in filters_spec_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["filters_spec"][key] = passed_keywords.get(key) + + return returned_payload + + +def aggregate_patch_host_deployments_payload(passed_keywords: dict) -> dict: + """Create a properly formatted payload for a AggregateHostDeploymentsV1 request. + + { + "date_ranges": [ + "string" + ], + "exclude": "string", + "extended_bounds": { + "max": "string", + "min": "string" + }, + "field": "string", + "filter": "string", + "filters_spec": { + "filters": "string", + "other_bucket": true, + "other_bucket_key": "string" + }, + "from": 0, + "include": "string", + "interval": "string", + "max_doc_count": 0, + "min_doc_count": 0, + "missing": "string", + "name": "string", + "percents": [ + "string" + ], + "q": "string", + "ranges": [ + "string" + ], + "size": 0, + "sort": "string", + "sub_aggregates": [ + "string" + ], + "time_zone": "string", + "type": "string" + } + """ + returned_payload = {} + keys = [ + "date_ranges", + "exclude", + "extended_bounds", + "field", + "filter", + "filters_spec", + "from", + "include", + "interval", + "max_doc_count", + "min_doc_count", + "missing", + "name", + "percents", + "q", + "ranges", + "size", + "sort", + "sub_aggregates", + "time_zone", + "type" + ] + for key in keys: + if passed_keywords.get(key, None) is not None: + returned_payload[key] = passed_keywords.get(key) + + extended_bounds_keys = ["max", "min"] + if "extended_bounds" not in returned_payload: + returned_payload["extended_bounds"] = {} + for key in extended_bounds_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["extended_bounds"][key] = passed_keywords.get(key) + + filters_spec_keys = ["filters", "other_bucket", "other_bucket_key"] + if "filters_spec" not in returned_payload: + returned_payload["filters_spec"] = {} + for key in filters_spec_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["filters_spec"][key] = passed_keywords.get(key) + + return returned_payload + + +def create_patch_deployment_config_payload(passed_keywords: dict) -> dict: # pylint: disable=R0912 + """Create a properly formatted payload for a CreateDeploymentConfig request. + + { + "block_filter_group_ids": [ + "string" + ], + "disabled": true, + "name": "string", + "patch_filter_group_ids": [ + "string" + ], + "platform": "string", + "post_patch_script_options": { + "content": "string", + "enabled": true, + "run_before_reboot": true, + "script_type": "string" + }, + "pre_patch_script_options": { + "content": "string", + "continue_on_failure": true, + "enabled": true, + "script_type": "string" + }, + "prestage": true, + "reboot_options": { + "allow_end_user_to_defer": true, + "occurrence": "string", + "reboot": true, + "reboot_user_notification_deferral_deadline_hours": 0, + "reboot_user_notification_deferral_deadline_reference": "string", + "user_notification": true, + "user_notification_message": "string", + "user_notification_title": "string" + }, + "recurring": true, + "run_now_no_schedule": true, + "schedule": { + "deployment_duration_minutes": 0, + "deployment_start_time": "string", + "recurrence_day_of_week": "string", + "recurrence_frequency": "string", + "recurrence_time_of_month": "string", + "schedule_activate_date": "string", + "schedule_terminate_date": "string" + }, + "target_hosts": "string", + "target_patches": "string", + "user_notification_options": { + "allow_end_user_to_defer": true, + "user_notification": true, + "user_notification_message": "string", + "user_notification_title": "string" + } + } + """ + returned_payload = {} + keys = [ + "block_filter_group_ids", + "disabled", + "name", + "patch_filter_group_ids", + "platform", + "post_patch_script_options", + "pre_patch_script_options", + "prestage", + "reboot_options", + "recurring", + "run_now_no_schedule", + "schedule", + "target_hosts", + "target_patches", + "user_notification_options" + ] + for key in keys: + if passed_keywords.get(key, None) is not None: + returned_payload[key] = passed_keywords.get(key) + + post_patch_script_options_keys = ["content", "enabled", "run_before_reboot", "script_type"] + if "post_patch_script_options" not in returned_payload: + returned_payload["post_patch_script_options"] = {} + for key in post_patch_script_options_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["post_patch_script_options"][key] = passed_keywords.get(key) + + pre_patch_script_options_keys = ["content", "continue_on_failure", "enabled", "script_type"] + if "pre_patch_script_options" not in returned_payload: + returned_payload["pre_patch_script_options"] = {} + for key in pre_patch_script_options_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["pre_patch_script_options"][key] = passed_keywords.get(key) + + reboot_options_keys = [ + "allow_end_user_to_defer", + "occurrence", + "reboot", + "reboot_user_notification_deferral_deadline_hours", + "reboot_user_notification_deferral_deadline_reference", + "user_notification", + "user_notification_message", + "user_notification_title" + ] + if "reboot_options" not in returned_payload: + returned_payload["reboot_options"] = {} + for key in reboot_options_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["reboot_options"][key] = passed_keywords.get(key) + + schedule_keys = [ + "deployment_duration_minutes", + "deployment_start_time", + "recurrence_day_of_week", + "recurrence_frequency", + "recurrence_time_of_month", + "schedule_activate_date", + "schedule_terminate_date" + ] + if "schedule" not in returned_payload: + returned_payload["schedule"] = {} + for key in schedule_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["schedule"][key] = passed_keywords.get(key) + + user_notification_options_keys = [ + "allow_end_user_to_defer", + "user_notification", + "user_notification_message", + "user_notification_title" + ] + if "user_notification_options" not in returned_payload: + returned_payload["user_notification_options"] = {} + for key in user_notification_options_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["user_notification_options"][key] = passed_keywords.get(key) + + return returned_payload + + +def update_patch_deployment_config_payload(passed_keywords: dict) -> dict: # pylint: disable=R0912 + """Create a properly formatted payload for a UpdateDeploymentConfig request. + + { + "block_filter_group_ids": [ + "string" + ], + "disabled": true, + "id": "string", + "name": "string", + "patch_filter_group_ids": [ + "string" + ], + "platform": "string", + "post_patch_script_options": { + "content": "string", + "enabled": true, + "run_before_reboot": true, + "script_type": "string" + }, + "pre_patch_script_options": { + "content": "string", + "continue_on_failure": true, + "enabled": true, + "script_type": "string" + }, + "prestage": true, + "reboot_options": { + "allow_end_user_to_defer": true, + "occurrence": "string", + "reboot": true, + "reboot_user_notification_deferral_deadline_hours": 0, + "reboot_user_notification_deferral_deadline_reference": "string", + "user_notification": true, + "user_notification_message": "string", + "user_notification_title": "string" + }, + "recurring": true, + "run_now_no_schedule": true, + "schedule": { + "deployment_duration_minutes": 0, + "deployment_start_time": "string", + "recurrence_day_of_week": "string", + "recurrence_frequency": "string", + "recurrence_time_of_month": "string", + "schedule_activate_date": "string", + "schedule_terminate_date": "string" + }, + "target_hosts": "string", + "target_patches": "string", + "user_notification_options": { + "allow_end_user_to_defer": true, + "user_notification": true, + "user_notification_message": "string", + "user_notification_title": "string" + } + } + """ + returned_payload = {} + keys = [ + "block_filter_group_ids", + "disabled", + "id", + "name", + "patch_filter_group_ids", + "platform", + "post_patch_script_options", + "pre_patch_script_options", + "prestage", + "reboot_options", + "recurring", + "run_now_no_schedule", + "schedule", + "target_hosts", + "target_patches", + "user_notification_options" + ] + for key in keys: + if passed_keywords.get(key, None) is not None: + returned_payload[key] = passed_keywords.get(key) + + post_patch_script_options_keys = ["content", "enabled", "run_before_reboot", "script_type"] + if "post_patch_script_options" not in returned_payload: + returned_payload["post_patch_script_options"] = {} + for key in post_patch_script_options_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["post_patch_script_options"][key] = passed_keywords.get(key) + + pre_patch_script_options_keys = ["content", "continue_on_failure", "enabled", "script_type"] + if "pre_patch_script_options" not in returned_payload: + returned_payload["pre_patch_script_options"] = {} + for key in pre_patch_script_options_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["pre_patch_script_options"][key] = passed_keywords.get(key) + + reboot_options_keys = [ + "allow_end_user_to_defer", + "occurrence", + "reboot", + "reboot_user_notification_deferral_deadline_hours", + "reboot_user_notification_deferral_deadline_reference", + "user_notification", + "user_notification_message", + "user_notification_title" + ] + if "reboot_options" not in returned_payload: + returned_payload["reboot_options"] = {} + for key in reboot_options_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["reboot_options"][key] = passed_keywords.get(key) + + schedule_keys = [ + "deployment_duration_minutes", + "deployment_start_time", + "recurrence_day_of_week", + "recurrence_frequency", + "recurrence_time_of_month", + "schedule_activate_date", + "schedule_terminate_date" + ] + if "schedule" not in returned_payload: + returned_payload["schedule"] = {} + for key in schedule_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["schedule"][key] = passed_keywords.get(key) + + user_notification_options_keys = [ + "allow_end_user_to_defer", + "user_notification", + "user_notification_message", + "user_notification_title" + ] + if "user_notification_options" not in returned_payload: + returned_payload["user_notification_options"] = {} + for key in user_notification_options_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["user_notification_options"][key] = passed_keywords.get(key) + + return returned_payload diff --git a/src/falconpy/_payload/_knowledge_bases.py b/src/falconpy/_payload/_knowledge_bases.py index ee8fa4dac..b44a8705c 100644 --- a/src/falconpy/_payload/_knowledge_bases.py +++ b/src/falconpy/_payload/_knowledge_bases.py @@ -92,6 +92,7 @@ def entities_knowledge_bases_create_v1_payload(passed_keywords: dict) -> dict: "id", "is_deleted", "name", + "project_id", "updated_at", "updated_by" ] @@ -195,6 +196,7 @@ def entities_knowledge_bases_update_v1_payload(passed_keywords: dict) -> dict: "id", "is_deleted", "name", + "project_id", "updated_at", "updated_by" ] diff --git a/src/falconpy/_payload/_ngsiem.py b/src/falconpy/_payload/_ngsiem.py index 62ef0a87c..67944916c 100644 --- a/src/falconpy/_payload/_ngsiem.py +++ b/src/falconpy/_payload/_ngsiem.py @@ -858,3 +858,179 @@ def update_persisted_aggregation_payload(passed_keywords: dict) -> dict: returned_payload[key] = passed_keywords.get(key) return returned_payload + + +def create_scheduled_report_payload(passed_keywords: dict) -> dict: + """Create a properly formatted payload for a CreateScheduledReport request. + + { + "dashboard_id": "string", + "description": "string", + "enabled": true, + "labels": [ + "string" + ], + "layout": { + "footer_show_page_numbers": true, + "max_number_of_rows": 0, + "paper_layout": "string", + "paper_orientation": "string", + "paper_size": "string", + "show_description": true, + "show_export_date": true, + "show_parameters": true, + "show_title_frontpage": true, + "show_title_header": true + }, + "name": "string", + "parameters": [ + "string" + ], + "password": "string", + "recipients": [ + "string" + ], + "schedule": { + "cron_expression": "string", + "end_date": 0, + "start_date": 0, + "time_zone": "string" + }, + "time_interval_from": "string", + "view_name": "string" + } + """ + returned_payload = {} + keys = [ + "dashboard_id", + "description", + "enabled", + "labels", + "layout", + "name", + "parameters", + "password", + "recipients", + "schedule", + "time_interval_from", + "view_name" + ] + for key in keys: + if passed_keywords.get(key, None) is not None: + returned_payload[key] = passed_keywords.get(key) + + layout_keys = [ + "footer_show_page_numbers", + "max_number_of_rows", + "paper_layout", + "paper_orientation", + "paper_size", + "show_description", + "show_export_date", + "show_parameters", + "show_title_frontpage", + "show_title_header" + ] + if "layout" not in returned_payload: + returned_payload["layout"] = {} + for key in layout_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["layout"][key] = passed_keywords.get(key) + + schedule_keys = ["cron_expression", "end_date", "start_date", "time_zone"] + if "schedule" not in returned_payload: + returned_payload["schedule"] = {} + for key in schedule_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["schedule"][key] = passed_keywords.get(key) + + return returned_payload + + +def update_scheduled_report_payload(passed_keywords: dict) -> dict: + """Create a properly formatted payload for a UpdateScheduledReport request. + + { + "dashboard_id": "string", + "description": "string", + "enabled": true, + "id": "string", + "labels": [ + "string" + ], + "layout": { + "footer_show_page_numbers": true, + "max_number_of_rows": 0, + "paper_layout": "string", + "paper_orientation": "string", + "paper_size": "string", + "show_description": true, + "show_export_date": true, + "show_parameters": true, + "show_title_frontpage": true, + "show_title_header": true + }, + "name": "string", + "parameters": [ + "string" + ], + "password": "string", + "recipients": [ + "string" + ], + "schedule": { + "cron_expression": "string", + "end_date": 0, + "start_date": 0, + "time_zone": "string" + }, + "time_interval_from": "string", + "view_name": "string" + } + """ + returned_payload = {} + keys = [ + "dashboard_id", + "description", + "enabled", + "id", + "labels", + "layout", + "name", + "parameters", + "password", + "recipients", + "schedule", + "time_interval_from", + "view_name" + ] + for key in keys: + if passed_keywords.get(key, None) is not None: + returned_payload[key] = passed_keywords.get(key) + + layout_keys = [ + "footer_show_page_numbers", + "max_number_of_rows", + "paper_layout", + "paper_orientation", + "paper_size", + "show_description", + "show_export_date", + "show_parameters", + "show_title_frontpage", + "show_title_header" + ] + if "layout" not in returned_payload: + returned_payload["layout"] = {} + for key in layout_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["layout"][key] = passed_keywords.get(key) + + schedule_keys = ["cron_expression", "end_date", "start_date", "time_zone"] + if "schedule" not in returned_payload: + returned_payload["schedule"] = {} + for key in schedule_keys: + if passed_keywords.get(key, None) is not None: + returned_payload["schedule"][key] = passed_keywords.get(key) + + return returned_payload diff --git a/src/falconpy/_payload/_saas_security.py b/src/falconpy/_payload/_saas_security.py index 187e90761..8a94de406 100644 --- a/src/falconpy/_payload/_saas_security.py +++ b/src/falconpy/_payload/_saas_security.py @@ -127,3 +127,21 @@ def create_user_journal_comment_payload(passed_keywords: dict) -> dict: returned_payload[key] = passed_keywords.get(key) return returned_payload + + +def set_check_impact_payload(passed_keywords: dict) -> dict: + """Create a properly formatted payload for a SetCheckImpactV3 request. + + { + "all_future_instances": true, + "impact": "string", + "reason": "string" + } + """ + returned_payload = {} + keys = ["all_future_instances", "impact", "reason"] + for key in keys: + if passed_keywords.get(key, None) is not None: + returned_payload[key] = passed_keywords.get(key) + + return returned_payload diff --git a/src/falconpy/_payload/_user_management.py b/src/falconpy/_payload/_user_management.py index 98e89aa48..37b45ab2b 100644 --- a/src/falconpy/_payload/_user_management.py +++ b/src/falconpy/_payload/_user_management.py @@ -111,3 +111,39 @@ def retrieve_users_v2_payload(passed_keywords: dict) -> dict: returned_payload[key] = passed_keywords.get(key) return returned_payload + + +def get_permission_groups_payload(passed_keywords: dict) -> dict: + """Create a properly formatted payload for a entitiesPermissionGroupsGETV1 request. + + { + "ids": [ + "string" + ] + } + """ + returned_payload = {} + keys = ["ids"] + for key in keys: + if passed_keywords.get(key, None) is not None: + returned_payload[key] = passed_keywords.get(key) + + return returned_payload + + +def get_permissions_payload(passed_keywords: dict) -> dict: + """Create a properly formatted payload for a entitiesPermissionsGETV1 request. + + { + "ids": [ + "string" + ] + } + """ + returned_payload = {} + keys = ["ids"] + for key in keys: + if passed_keywords.get(key, None) is not None: + returned_payload[key] = passed_keywords.get(key) + + return returned_payload diff --git a/src/falconpy/_service_class/_base_service_class.py b/src/falconpy/_service_class/_base_service_class.py index c85afe73c..4ab5ca457 100644 --- a/src/falconpy/_service_class/_base_service_class.py +++ b/src/falconpy/_service_class/_base_service_class.py @@ -36,6 +36,7 @@ For more information, please refer to """ import inspect +import os from abc import ABC, abstractmethod from logging import Logger, getLogger from typing import Dict, Type, Union, Optional @@ -153,13 +154,13 @@ def base_url(self, value: str): self.auth_object.base_url = value @property - def ssl_verify(self) -> bool: + def ssl_verify(self) -> Union[bool, str]: """Provide the ssl_verify value to legacy code.""" return self.auth_object.ssl_verify # Changing this setting will impact all traffic thru the interface. @ssl_verify.setter - def ssl_verify(self, value: bool): + def ssl_verify(self, value: Union[bool, str, os.PathLike]): """Allow code to flip the underlying SSL verify flag via the this class.""" self.auth_object.ssl_verify = value diff --git a/src/falconpy/_service_class/_service_class.py b/src/falconpy/_service_class/_service_class.py index 4b158abfe..0ec26d830 100644 --- a/src/falconpy/_service_class/_service_class.py +++ b/src/falconpy/_service_class/_service_class.py @@ -94,8 +94,9 @@ def __init__(self: "ServiceClass", CrowdStrike API URL to use for requests. [Default: US-1] ext_headers : dict Additional headers to be prepended to the default headers dictionary. - ssl_verify : bool - Flag specifying if SSL verification should be used. [Default: True] + ssl_verify : bool or str + Flag specifying if SSL verification should be used, or the path to a CA_BUNDLE + file or directory of trusted certificates. [Default: True] proxy : dict Dictionary of proxies to be used for requests. timeout : float or tuple diff --git a/src/falconpy/_util/_functions.py b/src/falconpy/_util/_functions.py index d5dcbb8c4..141585e81 100644 --- a/src/falconpy/_util/_functions.py +++ b/src/falconpy/_util/_functions.py @@ -371,7 +371,8 @@ def perform_request(endpoint: str = "", # noqa: C901 - Example: {"limit": 1, "sort": "state.asc"} body: dict - HTTP body payload to send to the API - Example: {"ids": ["123456789abcdefg", "987654321zyxwvutsr"]} - verify: bool - Enable / Disable SSL certificate checks + verify: bool or str - Enable / Disable SSL certificate checks, or the path to a CA_BUNDLE + file or directory of trusted certificates. - Example: True data - Encoded data to send to the API - Example: PAYLOAD = open(FILENAME, 'rb').read() diff --git a/src/falconpy/_version.py b/src/falconpy/_version.py index fbc5c6bcc..6beb5dec8 100644 --- a/src/falconpy/_version.py +++ b/src/falconpy/_version.py @@ -35,7 +35,7 @@ For more information, please refer to """ -_VERSION = '1.6.6' +_VERSION = '1.6.7' _HEC_VERSION = '1.0.0' _MAINTAINER = 'Joshua Hiller' _AUTHOR = 'CrowdStrike' diff --git a/src/falconpy/agent_invocation.py b/src/falconpy/agent_invocation.py index 491eb8fa1..df2ca706e 100644 --- a/src/falconpy/agent_invocation.py +++ b/src/falconpy/agent_invocation.py @@ -140,6 +140,8 @@ def invoke_published_agent_external_v1(self: object, The id value. messages : list The messages value. + project_id : str + The project_id value. This method only supports keywords for providing arguments. @@ -176,6 +178,8 @@ def get_agent_invocation_v3(self: object, ----------------- id : str or list[str] Invocation ID. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. @@ -278,6 +282,8 @@ def invoke_agent_version_external_v1(self: object, The id value. messages : list The messages value. + project_id : str + The project_id value. version_id : str The version_id value. @@ -323,6 +329,8 @@ def update_agent_invocation(self: object, The id value. status : str The status value. + project_id : str + Scope the operation to a project. This method only supports keywords for providing arguments. diff --git a/src/falconpy/agent_invocation.pyi b/src/falconpy/agent_invocation.pyi index 37f9c83e3..25984f2a6 100644 --- a/src/falconpy/agent_invocation.pyi +++ b/src/falconpy/agent_invocation.pyi @@ -13,6 +13,7 @@ class AgentInvocation(ServiceClass): deadline_seconds: Optional[int] = None, id: Optional[str] = None, messages: Optional[list] = None, + project_id: Optional[str] = None, body: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... @@ -20,6 +21,7 @@ class AgentInvocation(ServiceClass): self, *args: Union[str, List[str]], id: Optional[str] = None, + project_id: Optional[str] = None, parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... @@ -30,6 +32,7 @@ class AgentInvocation(ServiceClass): deadline_seconds: Optional[int] = None, id: Optional[str] = None, messages: Optional[list] = None, + project_id: Optional[str] = None, version_id: Optional[str] = None, body: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... @@ -37,6 +40,7 @@ class AgentInvocation(ServiceClass): def update_agent_invocation( self, *, + project_id: Optional[str] = None, id: Optional[str] = None, status: Optional[str] = None, body: Optional[dict] = None, diff --git a/src/falconpy/agent_versions.py b/src/falconpy/agent_versions.py index 60547f0bc..854c46bef 100644 --- a/src/falconpy/agent_versions.py +++ b/src/falconpy/agent_versions.py @@ -73,6 +73,8 @@ def get_agent_versions_v1(self: object, ----------------- ids : str or list[str] IDs of entities to retrieve. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. @@ -119,6 +121,8 @@ def query_agent_versions_v1(self: object, 'created_at|desc'. Ex: filter : str FQL query specifying the filter parameters. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. diff --git a/src/falconpy/agent_versions.pyi b/src/falconpy/agent_versions.pyi index 90d22d4c7..493e90cf0 100644 --- a/src/falconpy/agent_versions.pyi +++ b/src/falconpy/agent_versions.pyi @@ -10,6 +10,7 @@ class AgentVersions(ServiceClass): self, *args: Union[str, List[str]], ids: Optional[Union[str, List[str]]] = None, + project_id: Optional[str] = None, parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... @@ -20,6 +21,7 @@ class AgentVersions(ServiceClass): limit: Optional[int] = None, sort: Optional[str] = None, filter: Optional[str] = None, + project_id: Optional[str] = None, parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... diff --git a/src/falconpy/agentic_studio.py b/src/falconpy/agentic_studio.py index 450bc7dc6..b94c46421 100644 --- a/src/falconpy/agentic_studio.py +++ b/src/falconpy/agentic_studio.py @@ -1,4 +1,4 @@ -"""CrowdStrike Falcon AgenticStudio API interface class. +"""CrowdStrike Falcon AgenticStudio API interface class (backward compatibility). _______ __ _______ __ __ __ | _ .----.-----.--.--.--.--| | _ | |_.----|__| |--.-----. @@ -35,63 +35,5 @@ For more information, please refer to """ - -from .agents import Agents -from .agent_invocation import AgentInvocation -from .agent_templates import AgentTemplates -from .agent_versions import AgentVersions -from .knowledge_bases import KnowledgeBases -from .knowledge_base_files import KnowledgeBaseFiles -from .knowledge_base_audit_events import KnowledgeBaseAuditEvents -from .models import Models -from .skills import Skills -from .spans import Spans -from .tools import Tools -from .stream import Stream - - -class AgenticStudio(Agents, # pylint: disable=too-many-ancestors - AgentInvocation, - AgentTemplates, - AgentVersions, - KnowledgeBases, - KnowledgeBaseFiles, - KnowledgeBaseAuditEvents, - Models, - Skills, - Spans, - Tools, - Stream): - """Combined AgenticStudio service collection providing access to all agentic studio operations. - - This class aggregates all AgenticStudio sub-service collections into a single interface - via multiple inheritance. Operations are provided by the following sub-services: - - - Agents - - AgentInvocation - - AgentTemplates - - AgentVersions - - KnowledgeBases - - KnowledgeBaseFiles - - KnowledgeBaseAuditEvents - - Models - - Skills - - Spans - - Tools - - Stream - - The only requirement to instantiate an instance of this class is one of the following. - - - a valid client_id and client_secret provided as keywords. - - a credential dictionary with client_id and client_secret containing valid API credentials - { - "client_id": "CLIENT_ID_HERE", - "client_secret": "CLIENT_SECRET_HERE" - } - - a previously-authenticated instance of the authentication service class (oauth2.py) - - a valid token provided by the authentication service class (oauth2.py) - """ - - -# Backward compatibility alias -Agentic_Studio = AgenticStudio # pylint: disable=C0103 +# The AgenticStudio parent service collection is now Charlotte; this module keeps the 1.6.6 import path working. +from .charlotte import AgenticStudio, Agentic_Studio, Charlotte # noqa: F401 pylint: disable=W0611 diff --git a/src/falconpy/agents.py b/src/falconpy/agents.py index 79cab673a..cee10803d 100644 --- a/src/falconpy/agents.py +++ b/src/falconpy/agents.py @@ -74,6 +74,8 @@ def delete_agent(self: object, ----------------- id : str or list[str] Agent ID. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. @@ -113,6 +115,8 @@ def get_studio_agents(self: object, ----------------- ids : str or list[str] IDs of entities to retrieve. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. @@ -215,10 +219,15 @@ def create_or_update_agent(self: object, The duplicate_from_agent_id value. id : str The id value. + project_id : str + The project_id value. template_id : str The template_id value. version_definition : dict The version_definition value. + wait_for_ready : bool + Wait for the new version to finish registering before responding. Set to false to respond immediately and poll + GetAgentVersionsV1 for is_in_sync instead. This method only supports keywords for providing arguments. @@ -270,6 +279,11 @@ def update_agent(self: object, The is_published value. version_id : str The version_id value. + wait_for_ready : bool + Wait for the change to finish propagating downstream before responding. Set to false to respond immediately and + poll GetAgentVersionsV1 for is_in_sync instead. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. @@ -317,6 +331,8 @@ def query_studio_agents(self: object, 'created_date|desc'. Ex: filter : str FQL query specifying the filter parameters. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. diff --git a/src/falconpy/agents.pyi b/src/falconpy/agents.pyi index 3f55635f3..2a7786385 100644 --- a/src/falconpy/agents.pyi +++ b/src/falconpy/agents.pyi @@ -10,6 +10,7 @@ class Agents(ServiceClass): self, *args: Union[str, List[str]], id: Optional[str] = None, + project_id: Optional[str] = None, parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... @@ -17,14 +18,17 @@ class Agents(ServiceClass): self, *args: Union[str, List[str]], ids: Optional[Union[str, List[str]]] = None, + project_id: Optional[str] = None, parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... def create_or_update_agent( self, *, + wait_for_ready: Optional[bool] = None, duplicate_from_agent_id: Optional[str] = None, id: Optional[str] = None, + project_id: Optional[str] = None, template_id: Optional[str] = None, version_definition: Optional[dict] = None, body: Optional[dict] = None, @@ -35,6 +39,8 @@ class Agents(ServiceClass): *, id: Optional[str] = None, dry_run: Optional[bool] = None, + wait_for_ready: Optional[bool] = None, + project_id: Optional[str] = None, is_enabled: Optional[bool] = None, is_published: Optional[bool] = None, version_id: Optional[str] = None, @@ -49,6 +55,7 @@ class Agents(ServiceClass): limit: Optional[int] = None, sort: Optional[str] = None, filter: Optional[str] = None, + project_id: Optional[str] = None, parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... diff --git a/src/falconpy/api_integrations.pyi b/src/falconpy/api_integrations.pyi index e03bea869..730be133c 100644 --- a/src/falconpy/api_integrations.pyi +++ b/src/falconpy/api_integrations.pyi @@ -25,6 +25,7 @@ class APIIntegrations(ServiceClass): definition_id: Optional[str] = None, id: Optional[str] = None, operation_id: Optional[str] = None, + redirect: Optional[dict] = None, request: Optional[dict] = None, version: Optional[int] = None, body: Optional[dict] = None, @@ -39,6 +40,7 @@ class APIIntegrations(ServiceClass): definition_id: Optional[str] = None, id: Optional[str] = None, operation_id: Optional[str] = None, + redirect: Optional[dict] = None, request: Optional[dict] = None, version: Optional[int] = None, body: Optional[dict] = None, diff --git a/src/falconpy/aspm.pyi b/src/falconpy/aspm.pyi index 28f423a35..6d87063ca 100644 --- a/src/falconpy/aspm.pyi +++ b/src/falconpy/aspm.pyi @@ -140,14 +140,19 @@ class ASPM(ServiceClass): self, *, additional_header: Optional[str] = None, + availableInstances: Optional[str] = None, + createTime: Optional[str] = None, current_aws_arn: Optional[str] = None, dashboard_url: Optional[str] = None, id: Optional[str] = None, + lastHealthCheck: Optional[str] = None, last_health_check: Optional[int] = None, name: Optional[str] = None, node_type: Optional[str] = None, + organizationId: Optional[str] = None, password: Optional[str] = None, pod_settings: Optional[dict] = None, + projectId: Optional[str] = None, proxy_address: Optional[str] = None, status: Optional[dict] = None, type: Optional[str] = None, @@ -160,14 +165,19 @@ class ASPM(ServiceClass): self, *, additional_header: Optional[str] = None, + availableInstances: Optional[str] = None, + createTime: Optional[str] = None, current_aws_arn: Optional[str] = None, dashboard_url: Optional[str] = None, id: Optional[str] = None, + lastHealthCheck: Optional[str] = None, last_health_check: Optional[int] = None, name: Optional[str] = None, node_type: Optional[str] = None, + organizationId: Optional[str] = None, password: Optional[str] = None, pod_settings: Optional[dict] = None, + projectId: Optional[str] = None, proxy_address: Optional[str] = None, status: Optional[dict] = None, type: Optional[str] = None, @@ -198,14 +208,19 @@ class ASPM(ServiceClass): *, ID: Optional[int] = None, additional_header: Optional[str] = None, + availableInstances: Optional[str] = None, + createTime: Optional[str] = None, current_aws_arn: Optional[str] = None, dashboard_url: Optional[str] = None, id: Optional[str] = None, + lastHealthCheck: Optional[str] = None, last_health_check: Optional[int] = None, name: Optional[str] = None, node_type: Optional[str] = None, + organizationId: Optional[str] = None, password: Optional[str] = None, pod_settings: Optional[dict] = None, + projectId: Optional[str] = None, proxy_address: Optional[str] = None, status: Optional[dict] = None, type: Optional[str] = None, diff --git a/src/falconpy/browser_security.py b/src/falconpy/browser_security.py index b1b5acb5a..d509b9836 100644 --- a/src/falconpy/browser_security.py +++ b/src/falconpy/browser_security.py @@ -35,9 +35,18 @@ For more information, please refer to """ +# pylint: disable=C0302 from typing import Dict, Union from ._util import force_default, process_service_request, handle_single_argument -from ._payload import activate_agents_payload, add_url_domain_list_payload, apply_agent_tasks_payload, classify_domains_payload +from ._payload import ( + activate_agents_payload, + add_url_domain_list_payload, + apply_agent_tasks_payload, + classify_domains_payload, + create_sensitive_data_profile_payload, + query_sensitive_data_profiles_payload, + update_sensitive_data_profile_payload, + ) from ._payload import create_destination_group_payload, deactivate_agents_payload, query_combined_seraphic_agents_payload from ._payload import query_destination_groups_payload, query_seraphic_agents_payload, query_seraphic_rules_payload from ._payload import update_destination_group_payload, update_seraphic_rule_payload @@ -332,10 +341,10 @@ def apply_agent_tasks(self: object, } actions : list The actions value. - ttl : int - The ttl value. parameters : dict Full parameters payload. Not required if using other keywords. + ttlHours : str + Time to live (in hours) for the tasks request. Integer. This method only supports keywords for providing arguments. @@ -1222,16 +1231,293 @@ def query_seraphic_rules(self: object, params=parameters, body=body ) + + @force_default(defaults=["body"], default_types=["dict"]) + def create_sensitive_data_profile(self: object, + body: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Create a sensitive data profile. + + HTTP Method: POST + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/seraphic-enterprise-browser/CreateSensitiveDataProfile + + Keyword arguments + ----------------- + body : dict + Full body payload as a JSON formatted dictionary. Not required if using other keywords. + { + "apply_exact_match": true, + "custom_regex": [ + { + "name": "string", + "regex": "string", + "threshold": 0 + } + ], + "description": "string", + "name": "string", + "predefined_piis": [ + { + "predefined_pii": "string", + "threshold": 0 + } + ] + } + apply_exact_match : bool + When true, retrieve only exact regex matches; when false, retrieve all matches. + custom_regex : list + Custom regular expressions to apply. + description : str + The sensitive data profile description. + name : str + The sensitive data profile name. + predefined_piis : list + The predefined PII detectors to apply. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + if not body: + body = create_sensitive_data_profile_payload(passed_keywords=kwargs) + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="CreateSensitiveDataProfile", + body=body + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def delete_sensitive_data_profile(self: object, + *args, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Delete a sensitive data profile. + + HTTP Method: DELETE + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/seraphic-enterprise-browser/DeleteSensitiveDataProfile + + Keyword arguments + ----------------- + id : str or list[str] + The resource ID. + parameters : dict + Full parameters payload. Not required if using other keywords. + + Arguments + --------- + When not specified, the first argument to this method is assumed to be 'id'. + All others are ignored. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="DeleteSensitiveDataProfile", + keywords=kwargs, + params=handle_single_argument(args, parameters, "id") + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def get_sensitive_data_profiles(self: object, + *args, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Retrieve sensitive data profiles by ID, with the rules that reference them. + + HTTP Method: GET + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/seraphic-enterprise-browser/GetSensitiveDataProfiles + + Keyword arguments + ----------------- + ids : str or list[str] + One or more resource IDs. + parameters : dict + Full parameters payload. Not required if using other keywords. + + Arguments + --------- + When not specified, the first argument to this method is assumed to be 'ids'. + All others are ignored. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="GetSensitiveDataProfiles", + keywords=kwargs, + params=handle_single_argument(args, parameters, "ids") + ) + + @force_default(defaults=["body"], default_types=["dict"]) + def query_sensitive_data_profiles(self: object, + body: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Query sensitive data profiles by filter, sort and pagination. + + HTTP Method: POST + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/seraphic-enterprise-browser/QuerySensitiveDataProfiles + + Keyword arguments + ----------------- + body : dict + Full body payload as a JSON formatted dictionary. Not required if using other keywords. + { + "advanced_filter": "string", + "exclude": [ + "string" + ], + "filter": "string", + "limit": 0, + "search": "string", + "skip": 0, + "sort": [ + "string" + ] + } + advanced_filter : dict + Advanced filter sensitive data profiles by field. + exclude : list + A list of profile IDs to exclude. + filter : dict + Filter sensitive data profiles by field. + limit : int + The maximum number of items to return in the response. + search : str + Search query. Can include wildcards. + skip : int + The number of items to skip before returning results. + sort : list + Sort by field and order. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + if not body: + body = query_sensitive_data_profiles_payload(passed_keywords=kwargs) + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="QuerySensitiveDataProfiles", + body=body + ) + + @force_default(defaults=["body", "parameters"], default_types=["dict", "dict"]) + def update_sensitive_data_profile(self: object, + body: dict = None, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Partial-update a sensitive data profile. + + HTTP Method: PATCH + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/seraphic-enterprise-browser/UpdateSensitiveDataProfile + + Keyword arguments + ----------------- + id : str + The resource ID. + body : dict + Full body payload as a JSON formatted dictionary. Not required if using other keywords. + { + "apply_exact_match": true, + "custom_regex": [ + { + "name": "string", + "regex": "string", + "threshold": 0 + } + ], + "description": "string", + "name": "string", + "predefined_piis": [ + { + "predefined_pii": "string", + "threshold": 0 + } + ] + } + apply_exact_match : bool + When true, retrieve only exact regex matches; when false, retrieve all matches. + custom_regex : list + Custom regular expressions to apply. + description : str + The sensitive data profile description. + name : str + The sensitive data profile name. + predefined_piis : list + The predefined PII detectors to apply. + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + if not body: + body = update_sensitive_data_profile_payload(passed_keywords=kwargs) + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="UpdateSensitiveDataProfile", + keywords=kwargs, + params=parameters, + body=body + ) CombinedQueryAgents = query_combined_seraphic_agents ClassifyDomains = classify_domains ActivateAgents = activate_agents + CreateSensitiveDataProfile = create_sensitive_data_profile DeactivateAgents = deactivate_agents ApplyAgentTasks = apply_agent_tasks + DeleteSensitiveDataProfile = delete_sensitive_data_profile GetAgents = get_seraphic_agents GetAuditLogsMixin0 = get_seraphic_audit_logs GetDestinationGroups = get_destination_groups CreateDestinationGroup = create_destination_group DeleteDestinationGroup = delete_destination_group + GetSensitiveDataProfiles = get_sensitive_data_profiles + QuerySensitiveDataProfiles = query_sensitive_data_profiles UpdateDestinationGroup = update_destination_group GetExtensionAnalysis = get_extension_analysis GetRules = get_seraphic_rules @@ -1243,3 +1529,4 @@ def query_seraphic_rules(self: object, QueryAgents = query_seraphic_agents QueryDestinationGroups = query_destination_groups QueryRulesMixin0 = query_seraphic_rules + UpdateSensitiveDataProfile = update_sensitive_data_profile diff --git a/src/falconpy/browser_security.pyi b/src/falconpy/browser_security.pyi index f1b3ffdb8..0cedbd449 100644 --- a/src/falconpy/browser_security.pyi +++ b/src/falconpy/browser_security.pyi @@ -43,7 +43,7 @@ class BrowserSecurity(ServiceClass): *, agent_id: Optional[str] = None, actions: Optional[list] = None, - ttl: Optional[int] = None, + ttlHours: Optional[int] = None, body: Optional[dict] = None, parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... @@ -209,16 +209,71 @@ class BrowserSecurity(ServiceClass): parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... + def create_sensitive_data_profile( + self, + *, + apply_exact_match: Optional[bool] = None, + custom_regex: Optional[list] = None, + description: Optional[str] = None, + name: Optional[str] = None, + predefined_piis: Optional[list] = None, + body: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def delete_sensitive_data_profile( + self, + *args: Union[str, List[str]], + id: Optional[str] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def get_sensitive_data_profiles( + self, + *args: Union[str, List[str]], + ids: Optional[Union[str, List[str]]] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def query_sensitive_data_profiles( + self, + *, + advanced_filter: Optional[dict] = None, + exclude: Optional[Union[str, List[str]]] = None, + filter: Optional[dict] = None, + limit: Optional[int] = None, + search: Optional[str] = None, + skip: Optional[int] = None, + sort: Optional[list] = None, + body: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def update_sensitive_data_profile( + self, + *, + id: Optional[str] = None, + apply_exact_match: Optional[bool] = None, + custom_regex: Optional[list] = None, + description: Optional[str] = None, + name: Optional[str] = None, + predefined_piis: Optional[list] = None, + body: Optional[dict] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + CombinedQueryAgents = query_combined_seraphic_agents ClassifyDomains = classify_domains ActivateAgents = activate_agents + CreateSensitiveDataProfile = create_sensitive_data_profile DeactivateAgents = deactivate_agents ApplyAgentTasks = apply_agent_tasks + DeleteSensitiveDataProfile = delete_sensitive_data_profile GetAgents = get_seraphic_agents GetAuditLogsMixin0 = get_seraphic_audit_logs GetDestinationGroups = get_destination_groups CreateDestinationGroup = create_destination_group DeleteDestinationGroup = delete_destination_group + GetSensitiveDataProfiles = get_sensitive_data_profiles + QuerySensitiveDataProfiles = query_sensitive_data_profiles UpdateDestinationGroup = update_destination_group GetExtensionAnalysis = get_extension_analysis GetRules = get_seraphic_rules @@ -230,3 +285,4 @@ class BrowserSecurity(ServiceClass): QueryAgents = query_seraphic_agents QueryDestinationGroups = query_destination_groups QueryRulesMixin0 = query_seraphic_rules + UpdateSensitiveDataProfile = update_sensitive_data_profile diff --git a/src/falconpy/case_management.py b/src/falconpy/case_management.py index efffe45ec..7f49e02a6 100644 --- a/src/falconpy/case_management.py +++ b/src/falconpy/case_management.py @@ -35,12 +35,18 @@ For more information, please refer to """ -# pylint: disable=C0302 +# pylint: disable=C0302,R0904 from typing import Dict, Union from ._result import Result from ._service_class import ServiceClass from ._util import force_default, process_service_request, generate_error_result, handle_single_argument -from ._payload import entities_merge_post_v1_payload +from ._payload import ( + entities_merge_post_v1_payload, + add_case_alert_evidence_v2_payload, + add_case_access_tags_payload, + add_case_custom_evidence_payload, + add_case_user_evidence_payload, + ) from ._endpoint._case_management import _case_management_endpoints as Endpoints from ._payload._case_management import ( case_management_notification_groups_payload, @@ -2551,14 +2557,243 @@ def entities_merge_post_v1(self: object, body=body ) + @force_default(defaults=["body"], default_types=["dict"]) + def add_case_alert_evidence_v2(self: object, + body: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Add the given list of alert evidence to the specified case and returns the created evidence records. + + HTTP Method: POST + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/cases/entities.alert-evidence.post.v2 + + Keyword arguments + ----------------- + body : dict + Full body payload as a JSON formatted dictionary. Not required if using other keywords. + { + "alerts": [ + { + "id": "string" + } + ], + "id": "string" + } + alerts : list + The alerts value. + id : str + The id value. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + if not body: + body = add_case_alert_evidence_v2_payload(passed_keywords=kwargs) + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="entities_alert_evidence_post_v2", + body=body + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def remove_case_access_tags(self: object, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Remove the specified access tags from the specified case. + + HTTP Method: DELETE + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/cases/entities.case-access-tags.delete.v1 + + Keyword arguments + ----------------- + id : str + The ID of the case to remove access tags from. + access_tag_id : list + The ID of the access tag to remove from the case. + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="entities_case_access_tags_delete_v1", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["body"], default_types=["dict"]) + def add_case_access_tags(self: object, + body: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Add the given list of access tags to the specified case. + + HTTP Method: POST + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/cases/entities.case-access-tags.post.v1 + + Keyword arguments + ----------------- + body : dict + Full body payload as a JSON formatted dictionary. Not required if using other keywords. + { + "access_tag_ids": [ + "string" + ], + "id": "string" + } + access_tag_ids : list + The access_tag_ids value. + id : str + The id value. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + if not body: + body = add_case_access_tags_payload(passed_keywords=kwargs) + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="entities_case_access_tags_post_v1", + body=body + ) + + @force_default(defaults=["body"], default_types=["dict"]) + def add_case_custom_evidence(self: object, + body: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Add the given custom evidence to the specified case. + + HTTP Method: POST + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/cases/entities.custom-evidence.post.v1 + + Keyword arguments + ----------------- + body : dict + Full body payload as a JSON formatted dictionary. Not required if using other keywords. + { + "case_id": "string", + "evidence": [ + { + "name": "string", + "type": "string" + } + ] + } + case_id : str + The case_id value. + evidence : list + The evidence value. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + if not body: + body = add_case_custom_evidence_payload(passed_keywords=kwargs) + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="entities_custom_evidence_post_v1", + body=body + ) + + @force_default(defaults=["body"], default_types=["dict"]) + def add_case_user_evidence(self: object, + body: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Add user evidence to the specified case. + + HTTP Method: POST + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/cases/entities.user-evidence.post.v1 + + Keyword arguments + ----------------- + body : dict + Full body payload as a JSON formatted dictionary. Not required if using other keywords. + { + "id": "string", + "users": [ + { + "id": "string" + } + ] + } + id : str + The id value. + users : list + The users value. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + if not body: + body = add_case_user_evidence_payload(passed_keywords=kwargs) + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="entities_user_evidence_post_v1", + body=body + ) + aggregates_file_details_post_v1 = aggregates_file_details_post_v1 combined_file_details_get_v1 = query_file_details + entities_alert_evidence_post_v2 = add_case_alert_evidence_v2 + entities_case_access_tags_delete_v1 = remove_case_access_tags + entities_case_access_tags_post_v1 = add_case_access_tags + entities_custom_evidence_post_v1 = add_case_custom_evidence entities_file_details_get_v1 = get_file_details entities_file_details_patch_v1 = update_file_details entities_files_bulk_download_post_v1 = bulk_download_files entities_files_download_get_v1 = download_existing_files entities_files_upload_post_v1 = upload_file entities_files_delete_v1 = delete_file_details + entities_user_evidence_post_v1 = add_case_user_evidence queries_file_details_get_v1 = query_file_detail_ids entities_get_rtr_file_metadata_post_v1 = get_rtr_file_metadata entities_retrieve_rtr_file_post_v1 = retrieve_rtr_file diff --git a/src/falconpy/case_management.pyi b/src/falconpy/case_management.pyi index 013c69547..98c8e181a 100644 --- a/src/falconpy/case_management.pyi +++ b/src/falconpy/case_management.pyi @@ -446,7 +446,9 @@ class CaseManagement(ServiceClass): self, *, access_tags: Optional[list] = None, + assigned_to_group_ids: Optional[Union[str, List[str]]] = None, assigned_to_user_uuid: Optional[str] = None, + custom_fields: Optional[list] = None, description: Optional[str] = None, description_format: Optional[str] = None, description_tagged_users: Optional[Union[str, List[str]]] = None, @@ -457,6 +459,7 @@ class CaseManagement(ServiceClass): status: Optional[str] = None, tags: Optional[Union[str, List[str]]] = None, template: Optional[dict] = None, + templates: Optional[list] = None, body: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... @@ -504,13 +507,58 @@ class CaseManagement(ServiceClass): body: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... + def add_case_alert_evidence_v2( + self, + *, + alerts: Optional[list] = None, + id: Optional[str] = None, + body: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def remove_case_access_tags( + self, + *, + id: Optional[str] = None, + access_tag_id: Optional[Union[str, List[str]]] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def add_case_access_tags( + self, + *, + access_tag_ids: Optional[Union[str, List[str]]] = None, + id: Optional[str] = None, + body: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def add_case_custom_evidence( + self, + *, + case_id: Optional[str] = None, + evidence: Optional[list] = None, + body: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def add_case_user_evidence( + self, + *, + id: Optional[str] = None, + users: Optional[list] = None, + body: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + combined_file_details_get_v1 = query_file_details + entities_alert_evidence_post_v2 = add_case_alert_evidence_v2 + entities_case_access_tags_delete_v1 = remove_case_access_tags + entities_case_access_tags_post_v1 = add_case_access_tags + entities_custom_evidence_post_v1 = add_case_custom_evidence entities_file_details_get_v1 = get_file_details entities_file_details_patch_v1 = update_file_details entities_files_bulk_download_post_v1 = bulk_download_files entities_files_download_get_v1 = download_existing_files entities_files_upload_post_v1 = upload_file entities_files_delete_v1 = delete_file_details + entities_user_evidence_post_v1 = add_case_user_evidence queries_file_details_get_v1 = query_file_detail_ids entities_get_rtr_file_metadata_post_v1 = get_rtr_file_metadata entities_retrieve_rtr_file_post_v1 = retrieve_rtr_file diff --git a/src/falconpy/charlotte.py b/src/falconpy/charlotte.py new file mode 100644 index 000000000..0c36f9cd0 --- /dev/null +++ b/src/falconpy/charlotte.py @@ -0,0 +1,113 @@ +"""CrowdStrike Falcon Charlotte API interface class. + + _______ __ _______ __ __ __ +| _ .----.-----.--.--.--.--| | _ | |_.----|__| |--.-----. +|. 1___| _| _ | | | | _ | 1___| _| _| | <| -__| +|. |___|__| |_____|________|_____|____ |____|__| |__|__|__|_____| +|: 1 | |: 1 | +|::.. . | CROWDSTRIKE FALCON |::.. . | FalconPy +`-------' `-------' + +OAuth2 API - Customer SDK + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to +""" + +from .agents import Agents +from .agent_invocation import AgentInvocation +from .agent_templates import AgentTemplates +from .agent_versions import AgentVersions +from .knowledge_bases import KnowledgeBases +from .knowledge_base_files import KnowledgeBaseFiles +from .knowledge_base_audit_events import KnowledgeBaseAuditEvents +from .models import Models +from .skills import Skills +from .spans import Spans +from .tools import Tools +from .stream import Stream +from .eval_cases import EvalCases +from .eval_dataset_entries import EvalDatasetEntries +from .eval_datasets import EvalDatasets +from .eval_evaluators import EvalEvaluators +from .eval_runs import EvalRuns + + +class Charlotte(Agents, # pylint: disable=too-many-ancestors + AgentInvocation, + AgentTemplates, + AgentVersions, + KnowledgeBases, + KnowledgeBaseFiles, + KnowledgeBaseAuditEvents, + Models, + Skills, + Spans, + Tools, + Stream, + EvalCases, + EvalDatasetEntries, + EvalDatasets, + EvalEvaluators, + EvalRuns): + """Combined Charlotte service collection providing access to all Charlotte AI operations. + + This class aggregates all Charlotte sub-service collections into a single interface + via multiple inheritance. Operations are provided by the following sub-services: + + - Agents + - AgentInvocation + - AgentTemplates + - AgentVersions + - KnowledgeBases + - KnowledgeBaseFiles + - KnowledgeBaseAuditEvents + - Models + - Skills + - Spans + - Tools + - Stream + - EvalCases + - EvalDatasetEntries + - EvalDatasets + - EvalEvaluators + - EvalRuns + + The only requirement to instantiate an instance of this class is one of the following. + + - a valid client_id and client_secret provided as keywords. + - a credential dictionary with client_id and client_secret containing valid API credentials + { + "client_id": "CLIENT_ID_HERE", + "client_secret": "CLIENT_SECRET_HERE" + } + - a previously-authenticated instance of the authentication service class (oauth2.py) + - a valid token provided by the authentication service class (oauth2.py) + """ + + +# Backward compatibility aliases: this collection shipped as AgenticStudio in 1.6.6. +AgenticStudio = Charlotte +Agentic_Studio = Charlotte # pylint: disable=C0103 diff --git a/src/falconpy/cloud_aws_registration.pyi b/src/falconpy/cloud_aws_registration.pyi index 492e4c4d8..99a2478a6 100644 --- a/src/falconpy/cloud_aws_registration.pyi +++ b/src/falconpy/cloud_aws_registration.pyi @@ -41,6 +41,8 @@ class CloudAWSRegistration(ServiceClass): log_ingestion_method: Optional[str] = None, organization_id: Optional[str] = None, products: Optional[list] = None, + registration_description: Optional[str] = None, + registration_name: Optional[str] = None, resource_name_prefix: Optional[str] = None, resource_name_suffix: Optional[str] = None, root_stack_id: Optional[str] = None, @@ -78,6 +80,8 @@ class CloudAWSRegistration(ServiceClass): organization_id: Optional[str] = None, products: Optional[list] = None, reader_role_arn: Optional[str] = None, + registration_description: Optional[str] = None, + registration_name: Optional[str] = None, remediation_region: Optional[str] = None, remediation_tou_accepted: Optional[str] = None, resource_name_prefix: Optional[str] = None, diff --git a/src/falconpy/cloud_google_cloud_registration.pyi b/src/falconpy/cloud_google_cloud_registration.pyi index 4785c0d1a..7ef1bb456 100644 --- a/src/falconpy/cloud_google_cloud_registration.pyi +++ b/src/falconpy/cloud_google_cloud_registration.pyi @@ -40,6 +40,7 @@ class CloudGoogleCloudRegistration(ServiceClass): dspm_settings: Optional[dict] = None, entity_id: Optional[Union[str, List[str]]] = None, excluded_project_patterns: Optional[Union[str, List[str]]] = None, + existing_wif_pool_id: Optional[str] = None, falcon_client_key_id: Optional[str] = None, falcon_client_key_type: Optional[str] = None, infra_manager_region: Optional[str] = None, @@ -66,6 +67,7 @@ class CloudGoogleCloudRegistration(ServiceClass): dspm_settings: Optional[dict] = None, entity_id: Optional[Union[str, List[str]]] = None, excluded_project_patterns: Optional[Union[str, List[str]]] = None, + existing_wif_pool_id: Optional[str] = None, falcon_client_key_id: Optional[str] = None, falcon_client_key_type: Optional[str] = None, infra_manager_region: Optional[str] = None, diff --git a/src/falconpy/eval_cases.py b/src/falconpy/eval_cases.py new file mode 100644 index 000000000..cd4da8a38 --- /dev/null +++ b/src/falconpy/eval_cases.py @@ -0,0 +1,141 @@ +"""CrowdStrike Falcon EvalCases API interface class. + + _______ __ _______ __ __ __ +| _ .----.-----.--.--.--.--| | _ | |_.----|__| |--.-----. +|. 1___| _| _ | | | | _ | 1___| _| _| | <| -__| +|. |___|__| |_____|________|_____|____ |____|__| |__|__|__|_____| +|: 1 | |: 1 | +|::.. . | CROWDSTRIKE FALCON |::.. . | FalconPy +`-------' `-------' + +OAuth2 API - Customer SDK + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to +""" +from typing import Dict, Union +from ._util import force_default, process_service_request +from ._result import Result +from ._service_class import ServiceClass +from ._endpoint._eval_cases import _eval_cases_endpoints as Endpoints + + +class EvalCases(ServiceClass): + """The only requirement to instantiate an instance of this class is one of the following. + + - a valid client_id and client_secret provided as keywords. + - a credential dictionary with client_id and client_secret containing valid API credentials + { + "client_id": "CLIENT_ID_HERE", + "client_secret": "CLIENT_SECRET_HERE" + } + - a previously-authenticated instance of the authentication service class (oauth2.py) + - a valid token provided by the authentication service class (oauth2.py) + """ + + @force_default(defaults=["parameters"], default_types=["dict"]) + def get_eval_cases(self: object, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Retrieve evaluation case entities for the provided id. + + HTTP Method: GET + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/eval-cases/EntitiesEvalCasesV1 + + Keyword arguments + ----------------- + ids : list + IDs of entities to retrieve. + project_id : str + Scope the operation to a project. + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="EntitiesEvalCasesV1", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def query_eval_cases(self: object, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Query evaluation cases based on the provided filters. + + HTTP Method: GET + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/eval-cases/QueriesEvalCasesV1 + + Keyword arguments + ----------------- + offset : int + Starting index of overall result set from which to return ids. + limit : int + Number of IDs to return. Offset + limit should NOT be above 10K. + sort : str + Possible order by String. + fields: + 'created_at|asc'. 'created_at|desc' + Ex: + filter : str + FQL query specifying the filter parameters. + project_id : str + Scope the operation to a project. + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="QueriesEvalCasesV1", + keywords=kwargs, + params=parameters + ) + EntitiesEvalCasesV1 = get_eval_cases + QueriesEvalCasesV1 = query_eval_cases diff --git a/src/falconpy/eval_cases.pyi b/src/falconpy/eval_cases.pyi new file mode 100644 index 000000000..6b5d922e9 --- /dev/null +++ b/src/falconpy/eval_cases.pyi @@ -0,0 +1,29 @@ +"""Type stubs for eval_cases.""" +from typing import Dict, List, Optional, Union +from ._service_class import ServiceClass +from ._result import Result + + +class EvalCases(ServiceClass): + + def get_eval_cases( + self, + *, + ids: Optional[Union[str, List[str]]] = None, + project_id: Optional[str] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def query_eval_cases( + self, + *, + offset: Optional[int] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + filter: Optional[str] = None, + project_id: Optional[str] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + EntitiesEvalCasesV1 = get_eval_cases + QueriesEvalCasesV1 = query_eval_cases diff --git a/src/falconpy/eval_dataset_entries.py b/src/falconpy/eval_dataset_entries.py new file mode 100644 index 000000000..75d18f617 --- /dev/null +++ b/src/falconpy/eval_dataset_entries.py @@ -0,0 +1,413 @@ +"""CrowdStrike Falcon EvalDatasetEntries API interface class. + + _______ __ _______ __ __ __ +| _ .----.-----.--.--.--.--| | _ | |_.----|__| |--.-----. +|. 1___| _| _ | | | | _ | 1___| _| _| | <| -__| +|. |___|__| |_____|________|_____|____ |____|__| |__|__|__|_____| +|: 1 | |: 1 | +|::.. . | CROWDSTRIKE FALCON |::.. . | FalconPy +`-------' `-------' + +OAuth2 API - Customer SDK + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to +""" +from typing import Dict, Union +from ._util import force_default, process_service_request +from ._payload import create_eval_dataset_entry_payload, update_eval_dataset_entry_payload +from ._result import Result +from ._service_class import ServiceClass +from ._endpoint._eval_dataset_entries import _eval_dataset_entries_endpoints as Endpoints + + +class EvalDatasetEntries(ServiceClass): + """The only requirement to instantiate an instance of this class is one of the following. + + - a valid client_id and client_secret provided as keywords. + - a credential dictionary with client_id and client_secret containing valid API credentials + { + "client_id": "CLIENT_ID_HERE", + "client_secret": "CLIENT_SECRET_HERE" + } + - a previously-authenticated instance of the authentication service class (oauth2.py) + - a valid token provided by the authentication service class (oauth2.py) + """ + + @force_default(defaults=["parameters"], default_types=["dict"]) + def get_eval_dataset_entries(self: object, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Retrieve evaluation dataset entry entities for the provided id. + + HTTP Method: GET + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/eval-dataset-entries/EntitiesEvalDatasetEntriesV1 + + Keyword arguments + ----------------- + ids : list + IDs of entities to retrieve. + project_id : str + Scope the operation to a project. + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="EntitiesEvalDatasetEntriesV1", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["body"], default_types=["dict"]) + def update_eval_dataset_entry(self: object, + body: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Update an existing evaluation dataset entry. + + HTTP Method: PUT + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/eval-dataset-entries/EntitiesEvalDatasetEntriesUpdateV1 + + Keyword arguments + ----------------- + body : dict + Full body payload as a JSON formatted dictionary. Not required if using other keywords. + { + "created_at": "string", + "created_by": { + "access_granted_at": "string", + "cid": "string", + "created_at": "string", + "factors": [ + "string" + ], + "first_name": "string", + "last_login_at": "string", + "last_name": "string", + "status": "string", + "uid": "string", + "updated_at": "string", + "user_type": "string", + "uuid": "string", + "api_client_id": "string", + "email": "string", + "name": "string" + }, + "data": "string", + "dataset_id": "string", + "description": "string", + "id": "string", + "is_deleted": true, + "metadata": "string", + "name": "string", + "owner": "string", + "project_id": "string", + "tags": [ + "string" + ], + "updated_at": "string", + "updated_by": { + "access_granted_at": "string", + "cid": "string", + "created_at": "string", + "factors": [ + "string" + ], + "first_name": "string", + "last_login_at": "string", + "last_name": "string", + "status": "string", + "uid": "string", + "updated_at": "string", + "user_type": "string", + "uuid": "string", + "api_client_id": "string", + "email": "string", + "name": "string" + } + } + created_at : str + The created_at value. + created_by : dict + The created_by value. + data : dict + The data value. + dataset_id : str + The dataset_id value. + description : str + The description value. + id : str + The id value. + is_deleted : bool + The is_deleted value. + metadata : dict + The metadata value. + name : str + The name value. + owner : str + The owner value. + project_id : str + The project_id value. + tags : list + The tags value. + updated_at : str + The updated_at value. + updated_by : dict + The updated_by value. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + if not body: + body = update_eval_dataset_entry_payload(passed_keywords=kwargs) + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="EntitiesEvalDatasetEntriesUpdateV1", + body=body + ) + + @force_default(defaults=["body"], default_types=["dict"]) + def create_eval_dataset_entry(self: object, + body: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Create a new evaluation dataset entry. + + HTTP Method: POST + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/eval-dataset-entries/EntitiesEvalDatasetEntriesCreateV1 + + Keyword arguments + ----------------- + body : dict + Full body payload as a JSON formatted dictionary. Not required if using other keywords. + { + "created_at": "string", + "created_by": { + "access_granted_at": "string", + "cid": "string", + "created_at": "string", + "factors": [ + "string" + ], + "first_name": "string", + "last_login_at": "string", + "last_name": "string", + "status": "string", + "uid": "string", + "updated_at": "string", + "user_type": "string", + "uuid": "string", + "api_client_id": "string", + "email": "string", + "name": "string" + }, + "data": "string", + "dataset_id": "string", + "description": "string", + "id": "string", + "is_deleted": true, + "metadata": "string", + "name": "string", + "owner": "string", + "project_id": "string", + "tags": [ + "string" + ], + "updated_at": "string", + "updated_by": { + "access_granted_at": "string", + "cid": "string", + "created_at": "string", + "factors": [ + "string" + ], + "first_name": "string", + "last_login_at": "string", + "last_name": "string", + "status": "string", + "uid": "string", + "updated_at": "string", + "user_type": "string", + "uuid": "string", + "api_client_id": "string", + "email": "string", + "name": "string" + } + } + created_at : str + The created_at value. + created_by : dict + The created_by value. + data : dict + The data value. + dataset_id : str + The dataset_id value. + description : str + The description value. + id : str + The id value. + is_deleted : bool + The is_deleted value. + metadata : dict + The metadata value. + name : str + The name value. + owner : str + The owner value. + project_id : str + The project_id value. + tags : list + The tags value. + updated_at : str + The updated_at value. + updated_by : dict + The updated_by value. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + if not body: + body = create_eval_dataset_entry_payload(passed_keywords=kwargs) + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="EntitiesEvalDatasetEntriesCreateV1", + body=body + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def delete_eval_dataset_entry(self: object, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Delete an evaluation dataset entry. + + HTTP Method: DELETE + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/eval-dataset-entries/EntitiesEvalDatasetEntriesDeleteV1 + + Keyword arguments + ----------------- + id : str + ID of the dataset entry to delete. + project_id : str + Scope the operation to a project. + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="EntitiesEvalDatasetEntriesDeleteV1", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def query_eval_dataset_entries(self: object, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Query evaluation dataset entries based on the provided filters. + + HTTP Method: GET + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/eval-dataset-entries/QueriesEvalDatasetEntriesV1 + + Keyword arguments + ----------------- + offset : int + Starting index of overall result set from which to return ids. + limit : int + Number of IDs to return. Offset + limit should NOT be above 10K. + sort : str + Possible order by fields: name, created_at. Ex: 'created_at|desc' or 'name|asc' + filter : str + FQL query specifying the filter parameters. + project_id : str + Scope the operation to a project. + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="QueriesEvalDatasetEntriesV1", + keywords=kwargs, + params=parameters + ) + EntitiesEvalDatasetEntriesV1 = get_eval_dataset_entries + EntitiesEvalDatasetEntriesUpdateV1 = update_eval_dataset_entry + EntitiesEvalDatasetEntriesCreateV1 = create_eval_dataset_entry + EntitiesEvalDatasetEntriesDeleteV1 = delete_eval_dataset_entry + QueriesEvalDatasetEntriesV1 = query_eval_dataset_entries diff --git a/src/falconpy/eval_dataset_entries.pyi b/src/falconpy/eval_dataset_entries.pyi new file mode 100644 index 000000000..f29dababe --- /dev/null +++ b/src/falconpy/eval_dataset_entries.pyi @@ -0,0 +1,80 @@ +"""Type stubs for eval_dataset_entries.""" +from typing import Dict, List, Optional, Union +from ._service_class import ServiceClass +from ._result import Result + + +class EvalDatasetEntries(ServiceClass): + + def get_eval_dataset_entries( + self, + *, + ids: Optional[Union[str, List[str]]] = None, + project_id: Optional[str] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def update_eval_dataset_entry( + self, + *, + created_at: Optional[str] = None, + created_by: Optional[dict] = None, + data: Optional[dict] = None, + dataset_id: Optional[str] = None, + description: Optional[str] = None, + id: Optional[str] = None, + is_deleted: Optional[bool] = None, + metadata: Optional[dict] = None, + name: Optional[str] = None, + owner: Optional[str] = None, + project_id: Optional[str] = None, + tags: Optional[Union[str, List[str]]] = None, + updated_at: Optional[str] = None, + updated_by: Optional[dict] = None, + body: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def create_eval_dataset_entry( + self, + *, + created_at: Optional[str] = None, + created_by: Optional[dict] = None, + data: Optional[dict] = None, + dataset_id: Optional[str] = None, + description: Optional[str] = None, + id: Optional[str] = None, + is_deleted: Optional[bool] = None, + metadata: Optional[dict] = None, + name: Optional[str] = None, + owner: Optional[str] = None, + project_id: Optional[str] = None, + tags: Optional[Union[str, List[str]]] = None, + updated_at: Optional[str] = None, + updated_by: Optional[dict] = None, + body: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def delete_eval_dataset_entry( + self, + *, + id: Optional[str] = None, + project_id: Optional[str] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def query_eval_dataset_entries( + self, + *, + offset: Optional[int] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + filter: Optional[str] = None, + project_id: Optional[str] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + EntitiesEvalDatasetEntriesV1 = get_eval_dataset_entries + EntitiesEvalDatasetEntriesUpdateV1 = update_eval_dataset_entry + EntitiesEvalDatasetEntriesCreateV1 = create_eval_dataset_entry + EntitiesEvalDatasetEntriesDeleteV1 = delete_eval_dataset_entry + QueriesEvalDatasetEntriesV1 = query_eval_dataset_entries diff --git a/src/falconpy/eval_datasets.py b/src/falconpy/eval_datasets.py new file mode 100644 index 000000000..ba4c36655 --- /dev/null +++ b/src/falconpy/eval_datasets.py @@ -0,0 +1,401 @@ +"""CrowdStrike Falcon EvalDatasets API interface class. + + _______ __ _______ __ __ __ +| _ .----.-----.--.--.--.--| | _ | |_.----|__| |--.-----. +|. 1___| _| _ | | | | _ | 1___| _| _| | <| -__| +|. |___|__| |_____|________|_____|____ |____|__| |__|__|__|_____| +|: 1 | |: 1 | +|::.. . | CROWDSTRIKE FALCON |::.. . | FalconPy +`-------' `-------' + +OAuth2 API - Customer SDK + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to +""" +from typing import Dict, Union +from ._util import force_default, process_service_request +from ._payload import create_eval_dataset_payload, update_eval_dataset_payload +from ._result import Result +from ._service_class import ServiceClass +from ._endpoint._eval_datasets import _eval_datasets_endpoints as Endpoints + + +class EvalDatasets(ServiceClass): + """The only requirement to instantiate an instance of this class is one of the following. + + - a valid client_id and client_secret provided as keywords. + - a credential dictionary with client_id and client_secret containing valid API credentials + { + "client_id": "CLIENT_ID_HERE", + "client_secret": "CLIENT_SECRET_HERE" + } + - a previously-authenticated instance of the authentication service class (oauth2.py) + - a valid token provided by the authentication service class (oauth2.py) + """ + + @force_default(defaults=["parameters"], default_types=["dict"]) + def download_eval_dataset(self: object, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Download all entries of an evaluation dataset as CSV. + + HTTP Method: GET + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/eval-datasets/EntitiesEvalDatasetsDownloadV1 + + Keyword arguments + ----------------- + id : str + ID of the dataset to download. + project_id : str + Scope the operation to a project. + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="EntitiesEvalDatasetsDownloadV1", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def get_eval_datasets(self: object, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Retrieve evaluation dataset entities for the provided id. + + HTTP Method: GET + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/eval-datasets/EntitiesEvalDatasetsV1 + + Keyword arguments + ----------------- + ids : list + IDs of entities to retrieve. + project_id : str + Scope the operation to a project. + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="EntitiesEvalDatasetsV1", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["body"], default_types=["dict"]) + def update_eval_dataset(self: object, + body: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Update an existing evaluation dataset. + + HTTP Method: PUT + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/eval-datasets/EntitiesEvalDatasetsUpdateV1 + + Keyword arguments + ----------------- + body : dict + Full body payload as a JSON formatted dictionary. Not required if using other keywords. + { + "agent_ids": [ + "string" + ], + "created_at": "string", + "created_by": { + "access_granted_at": "string", + "cid": "string", + "created_at": "string", + "factors": [ + "string" + ], + "first_name": "string", + "last_login_at": "string", + "last_name": "string", + "status": "string", + "uid": "string", + "updated_at": "string", + "user_type": "string", + "uuid": "string", + "api_client_id": "string", + "email": "string", + "name": "string" + }, + "default_prompt_template": "string", + "description": "string", + "entryschema": "string", + "id": "string", + "is_deleted": true, + "metadata": "string", + "name": "string", + "owner": "string", + "project_id": "string", + "tags": [ + "string" + ], + "updated_at": "string", + "updated_by": { + "access_granted_at": "string", + "cid": "string", + "created_at": "string", + "factors": [ + "string" + ], + "first_name": "string", + "last_login_at": "string", + "last_name": "string", + "status": "string", + "uid": "string", + "updated_at": "string", + "user_type": "string", + "uuid": "string", + "api_client_id": "string", + "email": "string", + "name": "string" + } + } + agent_ids : list + The agent_ids value. + created_at : str + The created_at value. + created_by : dict + The created_by value. + default_prompt_template : str + The default_prompt_template value. + description : str + The description value. + entryschema : str + The entryschema value. + id : str + The id value. + is_deleted : bool + The is_deleted value. + metadata : dict + The metadata value. + name : str + The name value. + owner : str + The owner value. + project_id : str + The project_id value. + tags : list + The tags value. + updated_at : str + The updated_at value. + updated_by : dict + The updated_by value. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + if not body: + body = update_eval_dataset_payload(passed_keywords=kwargs) + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="EntitiesEvalDatasetsUpdateV1", + body=body + ) + + @force_default(defaults=["body"], default_types=["dict"]) + def create_eval_dataset(self: object, + body: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Create or update an evaluation dataset. + + HTTP Method: POST + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/eval-datasets/EntitiesEvalDatasetsCreateV1 + + Keyword arguments + ----------------- + body : dict + Full body payload as a JSON formatted dictionary. Not required if using other keywords. + { + "agent_ids": [ + "string" + ], + "description": "string", + "id": "string", + "metadata": "string", + "name": "string", + "project_id": "string", + "tags": [ + "string" + ] + } + agent_ids : list + The agent_ids value. + description : str + The description value. + id : str + The id value. + metadata : dict + The metadata value. + name : str + The name value. + project_id : str + The project_id value. + tags : list + The tags value. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + if not body: + body = create_eval_dataset_payload(passed_keywords=kwargs) + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="EntitiesEvalDatasetsCreateV1", + body=body + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def delete_eval_dataset(self: object, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Delete an evaluation dataset by ID. + + HTTP Method: DELETE + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/eval-datasets/EntitiesEvalDatasetsDeleteV1 + + Keyword arguments + ----------------- + id : str + ID of the dataset to delete. + project_id : str + Scope the operation to a project. + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="EntitiesEvalDatasetsDeleteV1", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def query_eval_datasets(self: object, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Query evaluation datasets based on the provided filters. + + HTTP Method: GET + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/eval-datasets/QueriesEvalDatasetsV1 + + Keyword arguments + ----------------- + offset : int + Starting index of overall result set from which to return ids. + limit : int + Number of IDs to return. Offset + limit should NOT be above 10K. + sort : str + Possible order by fields: name, created_at. Ex: 'created_at|desc' or 'name|asc' + filter : str + FQL query specifying the filter parameters. + project_id : str + Scope the operation to a project. + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="QueriesEvalDatasetsV1", + keywords=kwargs, + params=parameters + ) + EntitiesEvalDatasetsDownloadV1 = download_eval_dataset + EntitiesEvalDatasetsV1 = get_eval_datasets + EntitiesEvalDatasetsUpdateV1 = update_eval_dataset + EntitiesEvalDatasetsCreateV1 = create_eval_dataset + EntitiesEvalDatasetsDeleteV1 = delete_eval_dataset + QueriesEvalDatasetsV1 = query_eval_datasets diff --git a/src/falconpy/eval_datasets.pyi b/src/falconpy/eval_datasets.pyi new file mode 100644 index 000000000..10bc6803d --- /dev/null +++ b/src/falconpy/eval_datasets.pyi @@ -0,0 +1,83 @@ +"""Type stubs for eval_datasets.""" +from typing import Dict, List, Optional, Union +from ._service_class import ServiceClass +from ._result import Result + + +class EvalDatasets(ServiceClass): + + def download_eval_dataset( + self, + *, + id: Optional[str] = None, + project_id: Optional[str] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def get_eval_datasets( + self, + *, + ids: Optional[Union[str, List[str]]] = None, + project_id: Optional[str] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def update_eval_dataset( + self, + *, + agent_ids: Optional[Union[str, List[str]]] = None, + created_at: Optional[str] = None, + created_by: Optional[dict] = None, + default_prompt_template: Optional[str] = None, + description: Optional[str] = None, + entryschema: Optional[str] = None, + id: Optional[str] = None, + is_deleted: Optional[bool] = None, + metadata: Optional[dict] = None, + name: Optional[str] = None, + owner: Optional[str] = None, + project_id: Optional[str] = None, + tags: Optional[Union[str, List[str]]] = None, + updated_at: Optional[str] = None, + updated_by: Optional[dict] = None, + body: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def create_eval_dataset( + self, + *, + agent_ids: Optional[Union[str, List[str]]] = None, + description: Optional[str] = None, + id: Optional[str] = None, + metadata: Optional[dict] = None, + name: Optional[str] = None, + project_id: Optional[str] = None, + tags: Optional[Union[str, List[str]]] = None, + body: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def delete_eval_dataset( + self, + *, + id: Optional[str] = None, + project_id: Optional[str] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def query_eval_datasets( + self, + *, + offset: Optional[int] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + filter: Optional[str] = None, + project_id: Optional[str] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + EntitiesEvalDatasetsDownloadV1 = download_eval_dataset + EntitiesEvalDatasetsV1 = get_eval_datasets + EntitiesEvalDatasetsUpdateV1 = update_eval_dataset + EntitiesEvalDatasetsCreateV1 = create_eval_dataset + EntitiesEvalDatasetsDeleteV1 = delete_eval_dataset + QueriesEvalDatasetsV1 = query_eval_datasets diff --git a/src/falconpy/eval_evaluators.py b/src/falconpy/eval_evaluators.py new file mode 100644 index 000000000..9ea54a49f --- /dev/null +++ b/src/falconpy/eval_evaluators.py @@ -0,0 +1,423 @@ +"""CrowdStrike Falcon EvalEvaluators API interface class. + + _______ __ _______ __ __ __ +| _ .----.-----.--.--.--.--| | _ | |_.----|__| |--.-----. +|. 1___| _| _ | | | | _ | 1___| _| _| | <| -__| +|. |___|__| |_____|________|_____|____ |____|__| |__|__|__|_____| +|: 1 | |: 1 | +|::.. . | CROWDSTRIKE FALCON |::.. . | FalconPy +`-------' `-------' + +OAuth2 API - Customer SDK + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to +""" +from typing import Dict, Union +from ._util import force_default, process_service_request +from ._payload import create_eval_evaluator_payload, update_eval_evaluator_payload +from ._result import Result +from ._service_class import ServiceClass +from ._endpoint._eval_evaluators import _eval_evaluators_endpoints as Endpoints + + +class EvalEvaluators(ServiceClass): + """The only requirement to instantiate an instance of this class is one of the following. + + - a valid client_id and client_secret provided as keywords. + - a credential dictionary with client_id and client_secret containing valid API credentials + { + "client_id": "CLIENT_ID_HERE", + "client_secret": "CLIENT_SECRET_HERE" + } + - a previously-authenticated instance of the authentication service class (oauth2.py) + - a valid token provided by the authentication service class (oauth2.py) + """ + + @force_default(defaults=["parameters"], default_types=["dict"]) + def get_eval_evaluators(self: object, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Retrieve evaluation evaluator entities for the provided id. + + HTTP Method: GET + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/eval-evaluators/EntitiesEvalEvaluatorsV1 + + Keyword arguments + ----------------- + ids : list + IDs of entities to retrieve. + project_id : str + Scope the operation to a project. + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="EntitiesEvalEvaluatorsV1", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["body"], default_types=["dict"]) + def update_eval_evaluator(self: object, + body: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Update an existing evaluation evaluator. + + HTTP Method: PUT + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/eval-evaluators/EntitiesEvalEvaluatorsUpdateV1 + + Keyword arguments + ----------------- + body : dict + Full body payload as a JSON formatted dictionary. Not required if using other keywords. + { + "agent_ids": [ + "string" + ], + "config": "string", + "created_at": "string", + "created_by": { + "access_granted_at": "string", + "cid": "string", + "created_at": "string", + "factors": [ + "string" + ], + "first_name": "string", + "last_login_at": "string", + "last_name": "string", + "status": "string", + "uid": "string", + "updated_at": "string", + "user_type": "string", + "uuid": "string", + "api_client_id": "string", + "email": "string", + "name": "string" + }, + "description": "string", + "evaluator_type": "string", + "id": "string", + "is_deleted": true, + "metadata": "string", + "name": "string", + "owner": "string", + "project_id": "string", + "tags": [ + "string" + ], + "updated_at": "string", + "updated_by": { + "access_granted_at": "string", + "cid": "string", + "created_at": "string", + "factors": [ + "string" + ], + "first_name": "string", + "last_login_at": "string", + "last_name": "string", + "status": "string", + "uid": "string", + "updated_at": "string", + "user_type": "string", + "uuid": "string", + "api_client_id": "string", + "email": "string", + "name": "string" + } + } + agent_ids : list + The agent_ids value. + config : str + The config value. + created_at : str + The created_at value. + created_by : dict + The created_by value. + description : str + The description value. + evaluator_type : str + The evaluator_type value. + id : str + The id value. + is_deleted : bool + The is_deleted value. + metadata : dict + The metadata value. + name : str + The name value. + owner : str + The owner value. + project_id : str + The project_id value. + tags : list + The tags value. + updated_at : str + The updated_at value. + updated_by : dict + The updated_by value. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + if not body: + body = update_eval_evaluator_payload(passed_keywords=kwargs) + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="EntitiesEvalEvaluatorsUpdateV1", + body=body + ) + + @force_default(defaults=["body"], default_types=["dict"]) + def create_eval_evaluator(self: object, + body: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Create or update an evaluation evaluator. + + HTTP Method: POST + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/eval-evaluators/EntitiesEvalEvaluatorsCreateV1 + + Keyword arguments + ----------------- + body : dict + Full body payload as a JSON formatted dictionary. Not required if using other keywords. + { + "agent_ids": [ + "string" + ], + "config": "string", + "created_at": "string", + "created_by": { + "access_granted_at": "string", + "cid": "string", + "created_at": "string", + "factors": [ + "string" + ], + "first_name": "string", + "last_login_at": "string", + "last_name": "string", + "status": "string", + "uid": "string", + "updated_at": "string", + "user_type": "string", + "uuid": "string", + "api_client_id": "string", + "email": "string", + "name": "string" + }, + "description": "string", + "evaluator_type": "string", + "id": "string", + "is_deleted": true, + "metadata": "string", + "name": "string", + "owner": "string", + "project_id": "string", + "tags": [ + "string" + ], + "updated_at": "string", + "updated_by": { + "access_granted_at": "string", + "cid": "string", + "created_at": "string", + "factors": [ + "string" + ], + "first_name": "string", + "last_login_at": "string", + "last_name": "string", + "status": "string", + "uid": "string", + "updated_at": "string", + "user_type": "string", + "uuid": "string", + "api_client_id": "string", + "email": "string", + "name": "string" + } + } + agent_ids : list + The agent_ids value. + config : str + The config value. + created_at : str + The created_at value. + created_by : dict + The created_by value. + description : str + The description value. + evaluator_type : str + The evaluator_type value. + id : str + The id value. + is_deleted : bool + The is_deleted value. + metadata : dict + The metadata value. + name : str + The name value. + owner : str + The owner value. + project_id : str + The project_id value. + tags : list + The tags value. + updated_at : str + The updated_at value. + updated_by : dict + The updated_by value. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + if not body: + body = create_eval_evaluator_payload(passed_keywords=kwargs) + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="EntitiesEvalEvaluatorsCreateV1", + body=body + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def delete_eval_evaluator(self: object, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Delete an evaluation evaluator by ID. + + HTTP Method: DELETE + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/eval-evaluators/EntitiesEvalEvaluatorsDeleteV1 + + Keyword arguments + ----------------- + id : str + ID of the evaluator to delete. + project_id : str + Scope the operation to a project. + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="EntitiesEvalEvaluatorsDeleteV1", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def query_eval_evaluators(self: object, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Query evaluation evaluators based on the provided filters. + + HTTP Method: GET + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/eval-evaluators/QueriesEvalEvaluatorsV1 + + Keyword arguments + ----------------- + offset : int + Starting index of overall result set from which to return ids. + limit : int + Number of IDs to return. Offset + limit should NOT be above 10K. + sort : str + Possible order by fields: name, created_at. Ex: 'created_at|desc' or 'name|asc' + filter : str + FQL query specifying the filter parameters. + project_id : str + Scope the operation to a project. + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="QueriesEvalEvaluatorsV1", + keywords=kwargs, + params=parameters + ) + EntitiesEvalEvaluatorsV1 = get_eval_evaluators + EntitiesEvalEvaluatorsUpdateV1 = update_eval_evaluator + EntitiesEvalEvaluatorsCreateV1 = create_eval_evaluator + EntitiesEvalEvaluatorsDeleteV1 = delete_eval_evaluator + QueriesEvalEvaluatorsV1 = query_eval_evaluators diff --git a/src/falconpy/eval_evaluators.pyi b/src/falconpy/eval_evaluators.pyi new file mode 100644 index 000000000..a77da00e1 --- /dev/null +++ b/src/falconpy/eval_evaluators.pyi @@ -0,0 +1,82 @@ +"""Type stubs for eval_evaluators.""" +from typing import Dict, List, Optional, Union +from ._service_class import ServiceClass +from ._result import Result + + +class EvalEvaluators(ServiceClass): + + def get_eval_evaluators( + self, + *, + ids: Optional[Union[str, List[str]]] = None, + project_id: Optional[str] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def update_eval_evaluator( + self, + *, + agent_ids: Optional[Union[str, List[str]]] = None, + config: Optional[str] = None, + created_at: Optional[str] = None, + created_by: Optional[dict] = None, + description: Optional[str] = None, + evaluator_type: Optional[str] = None, + id: Optional[str] = None, + is_deleted: Optional[bool] = None, + metadata: Optional[dict] = None, + name: Optional[str] = None, + owner: Optional[str] = None, + project_id: Optional[str] = None, + tags: Optional[Union[str, List[str]]] = None, + updated_at: Optional[str] = None, + updated_by: Optional[dict] = None, + body: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def create_eval_evaluator( + self, + *, + agent_ids: Optional[Union[str, List[str]]] = None, + config: Optional[str] = None, + created_at: Optional[str] = None, + created_by: Optional[dict] = None, + description: Optional[str] = None, + evaluator_type: Optional[str] = None, + id: Optional[str] = None, + is_deleted: Optional[bool] = None, + metadata: Optional[dict] = None, + name: Optional[str] = None, + owner: Optional[str] = None, + project_id: Optional[str] = None, + tags: Optional[Union[str, List[str]]] = None, + updated_at: Optional[str] = None, + updated_by: Optional[dict] = None, + body: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def delete_eval_evaluator( + self, + *, + id: Optional[str] = None, + project_id: Optional[str] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def query_eval_evaluators( + self, + *, + offset: Optional[int] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + filter: Optional[str] = None, + project_id: Optional[str] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + EntitiesEvalEvaluatorsV1 = get_eval_evaluators + EntitiesEvalEvaluatorsUpdateV1 = update_eval_evaluator + EntitiesEvalEvaluatorsCreateV1 = create_eval_evaluator + EntitiesEvalEvaluatorsDeleteV1 = delete_eval_evaluator + QueriesEvalEvaluatorsV1 = query_eval_evaluators diff --git a/src/falconpy/eval_runs.py b/src/falconpy/eval_runs.py new file mode 100644 index 000000000..691f0ce86 --- /dev/null +++ b/src/falconpy/eval_runs.py @@ -0,0 +1,414 @@ +"""CrowdStrike Falcon EvalRuns API interface class. + + _______ __ _______ __ __ __ +| _ .----.-----.--.--.--.--| | _ | |_.----|__| |--.-----. +|. 1___| _| _ | | | | _ | 1___| _| _| | <| -__| +|. |___|__| |_____|________|_____|____ |____|__| |__|__|__|_____| +|: 1 | |: 1 | +|::.. . | CROWDSTRIKE FALCON |::.. . | FalconPy +`-------' `-------' + +OAuth2 API - Customer SDK + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to +""" +from typing import Dict, Union +from ._util import force_default, process_service_request +from ._payload import create_eval_run_payload, perform_eval_run_action_payload +from ._result import Result +from ._service_class import ServiceClass +from ._endpoint._eval_runs import _eval_runs_endpoints as Endpoints + + +class EvalRuns(ServiceClass): + """The only requirement to instantiate an instance of this class is one of the following. + + - a valid client_id and client_secret provided as keywords. + - a credential dictionary with client_id and client_secret containing valid API credentials + { + "client_id": "CLIENT_ID_HERE", + "client_secret": "CLIENT_SECRET_HERE" + } + - a previously-authenticated instance of the authentication service class (oauth2.py) + - a valid token provided by the authentication service class (oauth2.py) + """ + + @force_default(defaults=["parameters"], default_types=["dict"]) + def get_eval_runs(self: object, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Retrieve evaluation run entities for the provided id. + + HTTP Method: GET + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/eval-runs/EntitiesEvalRunsV1 + + Keyword arguments + ----------------- + ids : list + IDs of entities to retrieve. + project_id : str + Scope the operation to a project. + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="EntitiesEvalRunsV1", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["body"], default_types=["dict"]) + def create_eval_run(self: object, + body: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Create or update an evaluation run. + + HTTP Method: POST + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/eval-runs/EntitiesEvalRunsCreateV1 + + Keyword arguments + ----------------- + body : dict + Full body payload as a JSON formatted dictionary. Not required if using other keywords. + { + "actual_cost": 0.0, + "agent_id": "string", + "agent_version_id": "string", + "completed_at": "string", + "created_at": "string", + "created_by": { + "access_granted_at": "string", + "cid": "string", + "created_at": "string", + "factors": [ + "string" + ], + "first_name": "string", + "last_login_at": "string", + "last_name": "string", + "status": "string", + "uid": "string", + "updated_at": "string", + "user_type": "string", + "uuid": "string", + "api_client_id": "string", + "email": "string", + "name": "string" + }, + "dataset_entry_ids": [ + "string" + ], + "dataset_ids": [ + "string" + ], + "entry_tags": [ + "string" + ], + "estimated_cost": 0.0, + "evaluator_ids": [ + "string" + ], + "id": "string", + "is_deleted": true, + "metadata": "string", + "name": "string", + "owner": "string", + "progress": { + "completed_cases": 0, + "error_cases": 0, + "total_cases": 0 + }, + "project_id": "string", + "status": "string", + "summary": { + "average_latency": 0, + "average_score": 0.0, + "error_cases": 0, + "evaluator_results": [ + { + "average_score": 0.0, + "error_cases": 0, + "evaluator_id": "string", + "evaluator_name": "string", + "failed_cases": 0, + "passed_cases": 0 + } + ], + "failed_cases": 0, + "median_score": 0.0, + "passed_cases": 0, + "std_deviation": 0.0, + "total_cases": 0, + "total_duration": 0 + }, + "updated_at": "string", + "updated_by": { + "access_granted_at": "string", + "cid": "string", + "created_at": "string", + "factors": [ + "string" + ], + "first_name": "string", + "last_login_at": "string", + "last_name": "string", + "status": "string", + "uid": "string", + "updated_at": "string", + "user_type": "string", + "uuid": "string", + "api_client_id": "string", + "email": "string", + "name": "string" + }, + "variable_values": "string" + } + actual_cost : str + The actual_cost value. Float. + agent_id : str + The agent_id value. + agent_version_id : str + The agent_version_id value. + completed_at : str + The completed_at value. + created_at : str + The created_at value. + created_by : dict + The created_by value. + dataset_entry_ids : list + The dataset_entry_ids value. + dataset_ids : list + The dataset_ids value. + entry_tags : list + The entry_tags value. + estimated_cost : str + The estimated_cost value. Float. + evaluator_ids : list + The evaluator_ids value. + id : str + The id value. + is_deleted : bool + The is_deleted value. + metadata : dict + The metadata value. + name : str + The name value. + owner : str + The owner value. + progress : dict + The progress value. + project_id : str + The project_id value. + status : str + The status value. + summary : dict + The summary value. + updated_at : str + The updated_at value. + updated_by : dict + The updated_by value. + variable_values : dict + The variable_values value. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + if not body: + body = create_eval_run_payload(passed_keywords=kwargs) + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="EntitiesEvalRunsCreateV1", + body=body + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def delete_eval_run(self: object, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Delete an evaluation run by ID. + + HTTP Method: DELETE + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/eval-runs/EntitiesEvalRunsDeleteV1 + + Keyword arguments + ----------------- + id : str + ID of the evaluation run to delete. + project_id : str + Scope the operation to a project. + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="EntitiesEvalRunsDeleteV1", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["body", "parameters"], default_types=["dict", "dict"]) + def perform_eval_run_action(self: object, + body: dict = None, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Perform an action on an evaluation run (start or stop). + + HTTP Method: POST + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/eval-runs/EntitiesEvalRunsActionV1 + + Keyword arguments + ----------------- + id : str + ID of the evaluation run. + action_name : str + Action to perform: 'start' or 'stop' + body : dict + Full body payload as a JSON formatted dictionary. Not required if using other keywords. + { + "action": "string", + "case_cost_limit": { + "agent_run_credit_cents": 0, + "judge_run_credit_cents": 0 + }, + "id": "string", + "project_id": "string" + } + action : str + The action value. + case_cost_limit : dict + The case_cost_limit value. + id : str + The id value. + project_id : str + The project_id value. + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + if not body: + body = perform_eval_run_action_payload(passed_keywords=kwargs) + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="EntitiesEvalRunsActionV1", + keywords=kwargs, + params=parameters, + body=body + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def query_eval_runs(self: object, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Query evaluation runs based on the provided filters. + + HTTP Method: GET + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/eval-runs/QueriesEvalRunsV1 + + Keyword arguments + ----------------- + offset : int + Starting index of overall result set from which to return ids. + limit : int + Number of IDs to return. Offset + limit should NOT be above 10K. + sort : str + Possible order by fields: name, created_at. Ex: 'created_at|desc' or 'name|asc' + filter : str + FQL query specifying the filter parameters. + project_id : str + Scope the operation to a project. + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="QueriesEvalRunsV1", + keywords=kwargs, + params=parameters + ) + EntitiesEvalRunsV1 = get_eval_runs + EntitiesEvalRunsCreateV1 = create_eval_run + EntitiesEvalRunsDeleteV1 = delete_eval_run + EntitiesEvalRunsActionV1 = perform_eval_run_action + QueriesEvalRunsV1 = query_eval_runs diff --git a/src/falconpy/eval_runs.pyi b/src/falconpy/eval_runs.pyi new file mode 100644 index 000000000..b173d4de2 --- /dev/null +++ b/src/falconpy/eval_runs.pyi @@ -0,0 +1,81 @@ +"""Type stubs for eval_runs.""" +from typing import Dict, List, Optional, Union +from ._service_class import ServiceClass +from ._result import Result + + +class EvalRuns(ServiceClass): + + def get_eval_runs( + self, + *, + ids: Optional[Union[str, List[str]]] = None, + project_id: Optional[str] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def create_eval_run( + self, + *, + actual_cost: Optional[float] = None, + agent_id: Optional[str] = None, + agent_version_id: Optional[str] = None, + completed_at: Optional[str] = None, + created_at: Optional[str] = None, + created_by: Optional[dict] = None, + dataset_entry_ids: Optional[Union[str, List[str]]] = None, + dataset_ids: Optional[Union[str, List[str]]] = None, + entry_tags: Optional[Union[str, List[str]]] = None, + estimated_cost: Optional[float] = None, + evaluator_ids: Optional[Union[str, List[str]]] = None, + id: Optional[str] = None, + is_deleted: Optional[bool] = None, + metadata: Optional[dict] = None, + name: Optional[str] = None, + owner: Optional[str] = None, + progress: Optional[dict] = None, + project_id: Optional[str] = None, + status: Optional[str] = None, + summary: Optional[dict] = None, + updated_at: Optional[str] = None, + updated_by: Optional[dict] = None, + variable_values: Optional[dict] = None, + body: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def delete_eval_run( + self, + *, + id: Optional[str] = None, + project_id: Optional[str] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def perform_eval_run_action( + self, + *, + id: Optional[str] = None, + action_name: Optional[str] = None, + action: Optional[str] = None, + case_cost_limit: Optional[dict] = None, + project_id: Optional[str] = None, + body: Optional[dict] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def query_eval_runs( + self, + *, + offset: Optional[int] = None, + limit: Optional[int] = None, + sort: Optional[str] = None, + filter: Optional[str] = None, + project_id: Optional[str] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + EntitiesEvalRunsV1 = get_eval_runs + EntitiesEvalRunsCreateV1 = create_eval_run + EntitiesEvalRunsDeleteV1 = delete_eval_run + EntitiesEvalRunsActionV1 = perform_eval_run_action + QueriesEvalRunsV1 = query_eval_runs diff --git a/src/falconpy/foundry_logscale.pyi b/src/falconpy/foundry_logscale.pyi index bfccefa26..fc0a31bcf 100644 --- a/src/falconpy/foundry_logscale.pyi +++ b/src/falconpy/foundry_logscale.pyi @@ -50,6 +50,7 @@ class FoundryLogScale(ServiceClass): metadata: Optional[bool] = None, mode: Optional[str] = None, end: Optional[str] = None, + extra_log_fields: Optional[dict] = None, repo_or_view: Optional[str] = None, search_query: Optional[str] = None, search_query_args: Optional[dict] = None, @@ -82,9 +83,11 @@ class FoundryLogScale(ServiceClass): match_response_schema: Optional[bool] = None, metadata: Optional[bool] = None, end: Optional[str] = None, + extra_log_fields: Optional[dict] = None, id: Optional[str] = None, mode: Optional[str] = None, name: Optional[str] = None, + parameters: Optional[dict] = None, start: Optional[str] = None, version: Optional[str] = None, with_in: Optional[dict] = None, @@ -92,7 +95,6 @@ class FoundryLogScale(ServiceClass): with_renames: Optional[list] = None, with_sort: Optional[dict] = None, body: Optional[dict] = None, - parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... def populate( diff --git a/src/falconpy/hosts.py b/src/falconpy/hosts.py index 242795836..c3b46e990 100644 --- a/src/falconpy/hosts.py +++ b/src/falconpy/hosts.py @@ -112,6 +112,94 @@ def query_hidden_devices_combined(self: object, device_policies.automox.policy_type device_policies.aws-verified-access.applied device_policies.aws-verified-access.policy_id device_policies.aws-verified-access.policy_type device_policies.browser-extension.applied device_policies.browser-extension.policy_id + device_policies.browser-extension.policy_type device_policies.cloud-container-workload.applied + device_policies.cloud-container-workload.policy_id device_policies.cloud-container-workload.policy_type + device_policies.cloud-ml.applied device_policies.cloud-ml.policy_id + device_policies.cloud-ml.policy_type device_policies.consumer-subscription.applied + device_policies.consumer-subscription.policy_id device_policies.consumer-subscription.policy_type + device_policies.content-update.applied device_policies.content-update.policy_id + device_policies.content-update.policy_type device_policies.data-protection-cloud.applied + device_policies.data-protection-cloud.policy_id device_policies.data-protection-cloud.policy_type + device_policies.data-protection.applied device_policies.data-protection.policy_id + device_policies.data-protection.policy_type device_policies.device_control.applied + device_policies.device_control.policy_id device_policies.device_control.policy_type + device_policies.exposure-management.applied device_policies.exposure-management.policy_id + device_policies.exposure-management.policy_type device_policies.fem-browser-extension-control.applied + device_policies.fem-browser-extension-control.policy_iddevice_policies.fem-browser-extension-control.policy_type + device_policies.fim.applied device_policies.fim.policy_id + device_policies.fim.policy_type device_policies.firewall.applied + device_policies.firewall.policy_id device_policies.firewall.policy_type + device_policies.firewall.rule_set_id device_policies.host-retention.applied + device_policies.host-retention.policy_id device_policies.host-retention.policy_type + device_policies.identity-endpoint.applied device_policies.identity-endpoint.policy_id + device_policies.identity-endpoint.policy_type device_policies.identity-protection.applied + device_policies.identity-protection.policy_id device_policies.identity-protection.policy_type + device_policies.it-automation.applied device_policies.it-automation.policy_id + device_policies.it-automation.policy_type device_policies.jumpcloud.applied + device_policies.jumpcloud.policy_id device_policies.jumpcloud.policy_type + device_policies.kubernetes-admission-control.applied device_policies.kubernetes-admission-control.policy_id + device_policies.kubernetes-admission-control.policy_typedevice_policies.logscale-collector.applied + device_policies.logscale-collector.policy_id device_policies.logscale-collector.policy_type + device_policies.mobile.applied device_policies.mobile.policy_id + device_policies.mobile.policy_type device_policies.netskope.applied + device_policies.netskope.policy_id device_policies.netskope.policy_type + device_policies.network-scan-content.applied device_policies.network-scan-content.policy_id + device_policies.network-scan-content.policy_type device_policies.prevention.applied + device_policies.prevention.policy_id device_policies.prevention.policy_type + device_policies.remote_response.applied device_policies.remote_response.policy_id + device_policies.remote_response.policy_type device_policies.sca.applied + device_policies.sca.policy_id device_policies.sca.policy_type + device_policies.sensor_update.applied device_policies.sensor_update.policy_id + device_policies.sensor_update.policy_type device_policies.sensor_update.uninstall_protection + device_policies.system-tray.applied device_policies.system-tray.policy_id + device_policies.system-tray.policy_type device_policies.vulnerability-management.applied + device_policies.vulnerability-management.policy_id device_policies.vulnerability-management.policy_type + device_policies.ztl.applied device_policies.ztl.policy_id + device_policies.ztl.policy_type email + external_ip filesystem_containment_status + first_login_timestamp first_login_user + first_seen group_hash + groups host_utc_offset + hostname instance_id + internet_exposure k8s_cluster_git_version + k8s_cluster_id k8s_cluster_version + k8s_node_uid kernel_version + last_login_timestamp last_login_uid + last_login_user last_login_user_sid + last_reboot last_seen + license_activation_state linux_sensor_mode + local_ip local_ip.raw + mac_address machine_domain + major_version managed_apps.airlock.version + managed_apps.automox.version managed_apps.aws-verified-access.version + managed_apps.identity-protection.version managed_apps.jumpcloud.version + managed_apps.netskope.version migration_completed_time + minor_version modified_timestamp + os_build os_product_name + os_version ou + platform_id platform_name + pod_annotations pod_host_ip4 + pod_host_ip6 pod_hostname + pod_id pod_ip4 + pod_ip6 pod_labels + pod_name pod_namespace + pod_service_account_name pointer_size + policies.applied policies.policy_id + policies.policy_type policy_id + product_type product_type_desc + reduced_functionality_mode release_group + rtr_state safe_mode + serial_number service_provider + service_provider_account_id site_name + status system_manufacturer + system_product_name tags + zone_group + device_policies.airlock.policy_type device_policies.application-abuse-prevention.applied + device_policies.application-abuse-prevention.policy_iddevice_policies.application-abuse-prevention.policy_type + device_policies.automox.applied device_policies.automox.policy_id + device_policies.automox.policy_type device_policies.aws-verified-access.applied + device_policies.aws-verified-access.policy_id device_policies.aws-verified-access.policy_type + device_policies.browser-extension.applied device_policies.browser-extension.policy_id device_policies.browser-extension.policy_type device_policies.cloud-ml.applied device_policies.cloud-ml.policy_id device_policies.cloud-ml.policy_type device_policies.consumer-subscription.applied device_policies.consumer-subscription.policy_id @@ -586,6 +674,8 @@ def perform_group_action(self: object, body: dict = None, parameters: dict = Non Disable the hostname check. ids : str or list[str] Group ID(s) to perform actions against. + skip_membership_validation : bool + Skip membership validation on remove (allows removing unmatched hosts). parameters : dict full parameters payload, not required if action_name is provide as a keyword. @@ -1119,6 +1209,94 @@ def query_devices_by_filter_combined(self: object, device_policies.automox.policy_type device_policies.aws-verified-access.applied device_policies.aws-verified-access.policy_id device_policies.aws-verified-access.policy_type device_policies.browser-extension.applied device_policies.browser-extension.policy_id + device_policies.browser-extension.policy_type device_policies.cloud-container-workload.applied + device_policies.cloud-container-workload.policy_id device_policies.cloud-container-workload.policy_type + device_policies.cloud-ml.applied device_policies.cloud-ml.policy_id + device_policies.cloud-ml.policy_type device_policies.consumer-subscription.applied + device_policies.consumer-subscription.policy_id device_policies.consumer-subscription.policy_type + device_policies.content-update.applied device_policies.content-update.policy_id + device_policies.content-update.policy_type device_policies.data-protection-cloud.applied + device_policies.data-protection-cloud.policy_id device_policies.data-protection-cloud.policy_type + device_policies.data-protection.applied device_policies.data-protection.policy_id + device_policies.data-protection.policy_type device_policies.device_control.applied + device_policies.device_control.policy_id device_policies.device_control.policy_type + device_policies.exposure-management.applied device_policies.exposure-management.policy_id + device_policies.exposure-management.policy_type device_policies.fem-browser-extension-control.applied + device_policies.fem-browser-extension-control.policy_iddevice_policies.fem-browser-extension-control.policy_type + device_policies.fim.applied device_policies.fim.policy_id + device_policies.fim.policy_type device_policies.firewall.applied + device_policies.firewall.policy_id device_policies.firewall.policy_type + device_policies.firewall.rule_set_id device_policies.host-retention.applied + device_policies.host-retention.policy_id device_policies.host-retention.policy_type + device_policies.identity-endpoint.applied device_policies.identity-endpoint.policy_id + device_policies.identity-endpoint.policy_type device_policies.identity-protection.applied + device_policies.identity-protection.policy_id device_policies.identity-protection.policy_type + device_policies.it-automation.applied device_policies.it-automation.policy_id + device_policies.it-automation.policy_type device_policies.jumpcloud.applied + device_policies.jumpcloud.policy_id device_policies.jumpcloud.policy_type + device_policies.kubernetes-admission-control.applied device_policies.kubernetes-admission-control.policy_id + device_policies.kubernetes-admission-control.policy_typedevice_policies.logscale-collector.applied + device_policies.logscale-collector.policy_id device_policies.logscale-collector.policy_type + device_policies.mobile.applied device_policies.mobile.policy_id + device_policies.mobile.policy_type device_policies.netskope.applied + device_policies.netskope.policy_id device_policies.netskope.policy_type + device_policies.network-scan-content.applied device_policies.network-scan-content.policy_id + device_policies.network-scan-content.policy_type device_policies.prevention.applied + device_policies.prevention.policy_id device_policies.prevention.policy_type + device_policies.remote_response.applied device_policies.remote_response.policy_id + device_policies.remote_response.policy_type device_policies.sca.applied + device_policies.sca.policy_id device_policies.sca.policy_type + device_policies.sensor_update.applied device_policies.sensor_update.policy_id + device_policies.sensor_update.policy_type device_policies.sensor_update.uninstall_protection + device_policies.system-tray.applied device_policies.system-tray.policy_id + device_policies.system-tray.policy_type device_policies.vulnerability-management.applied + device_policies.vulnerability-management.policy_id device_policies.vulnerability-management.policy_type + device_policies.ztl.applied device_policies.ztl.policy_id + device_policies.ztl.policy_type email + external_ip filesystem_containment_status + first_login_timestamp first_login_user + first_seen group_hash + groups host_utc_offset + hostname instance_id + internet_exposure k8s_cluster_git_version + k8s_cluster_id k8s_cluster_version + k8s_node_uid kernel_version + last_login_timestamp last_login_uid + last_login_user last_login_user_sid + last_reboot last_seen + license_activation_state linux_sensor_mode + local_ip local_ip.raw + mac_address machine_domain + major_version managed_apps.airlock.version + managed_apps.automox.version managed_apps.aws-verified-access.version + managed_apps.identity-protection.version managed_apps.jumpcloud.version + managed_apps.netskope.version migration_completed_time + minor_version modified_timestamp + os_build os_product_name + os_version ou + platform_id platform_name + pod_annotations pod_host_ip4 + pod_host_ip6 pod_hostname + pod_id pod_ip4 + pod_ip6 pod_labels + pod_name pod_namespace + pod_service_account_name pointer_size + policies.applied policies.policy_id + policies.policy_type policy_id + product_type product_type_desc + reduced_functionality_mode release_group + rtr_state safe_mode + serial_number service_provider + service_provider_account_id site_name + status system_manufacturer + system_product_name tags + zone_group + device_policies.airlock.policy_type device_policies.application-abuse-prevention.applied + device_policies.application-abuse-prevention.policy_iddevice_policies.application-abuse-prevention.policy_type + device_policies.automox.applied device_policies.automox.policy_id + device_policies.automox.policy_type device_policies.aws-verified-access.applied + device_policies.aws-verified-access.policy_id device_policies.aws-verified-access.policy_type + device_policies.browser-extension.applied device_policies.browser-extension.policy_id device_policies.browser-extension.policy_type device_policies.cloud-ml.applied device_policies.cloud-ml.policy_id device_policies.cloud-ml.policy_type device_policies.consumer-subscription.applied device_policies.consumer-subscription.policy_id diff --git a/src/falconpy/hosts.pyi b/src/falconpy/hosts.pyi index 59e81185a..3dc476b6b 100644 --- a/src/falconpy/hosts.pyi +++ b/src/falconpy/hosts.pyi @@ -33,6 +33,7 @@ class Hosts(ServiceClass): ids: Optional[Union[str, List[str]]] = None, action_name: Optional[str] = None, disable_hostname_check: Optional[bool] = None, + skip_membership_validation: Optional[bool] = None, action_parameters: Optional[list] = None, body: Optional[dict] = None, parameters: Optional[dict] = None, diff --git a/src/falconpy/it_automation.py b/src/falconpy/it_automation.py index ee738e4e3..71e8affd7 100644 --- a/src/falconpy/it_automation.py +++ b/src/falconpy/it_automation.py @@ -49,7 +49,12 @@ policy_host_group_payload, automation_live_query_payload, automation_user_group_payload, - cancel_task_execution_payload + cancel_task_execution_payload, + aggregate_patch_deployment_configs_payload, + aggregate_patch_deployment_executions_payload, + aggregate_patch_host_deployments_payload, + create_patch_deployment_config_payload, + update_patch_deployment_config_payload, ) from ._result import Result from ._service_class import ServiceClass @@ -2731,6 +2736,975 @@ def search_tasks(self: object, parameters: dict = None, **kwargs) -> Union[Dict[ params=parameters ) + @force_default(defaults=["body"], default_types=["dict"]) + def aggregate_patch_deployment_configs(self: object, + body: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Retrieve deployment config aggregations. + + HTTP Method: POST + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/deployment-configs/AggregateDeploymentConfigsV1 + + Keyword arguments + ----------------- + body : dict + Full body payload as a JSON formatted dictionary. Not required if using other keywords. + { + "date_ranges": [ + { + "from": "string", + "to": "string" + } + ], + "exclude": "string", + "extended_bounds": { + "max": "string", + "min": "string" + }, + "field": "string", + "filter": "string", + "filters_spec": { + "filters": "string", + "other_bucket": true, + "other_bucket_key": "string" + }, + "from": 0, + "include": "string", + "interval": "string", + "max_doc_count": 0, + "min_doc_count": 0, + "missing": "string", + "name": "string", + "percents": [ + "string" + ], + "q": "string", + "ranges": [ + { + "From": 0.0, + "To": 0.0 + } + ], + "size": 0, + "sort": "string", + "sub_aggregates": [ + "string" + ], + "time_zone": "string", + "type": "string" + } + date_ranges : list + The date_ranges value. + exclude : str + The exclude value. + extended_bounds : dict + The extended_bounds value. + field : str + The field value. + filter : str + The filter value. + filters_spec : dict + The filters_spec value. + from : int + The from value. + include : str + The include value. + interval : str + The interval value. + max_doc_count : int + The max_doc_count value. + min_doc_count : int + The min_doc_count value. + missing : str + The missing value. + name : str + The name value. + percents : list + The percents value. + q : str + The q value. + ranges : list + The ranges value. + size : int + The size value. + sort : str + The sort value. + sub_aggregates : list + The sub_aggregates value. + time_zone : str + The time_zone value. + type : str + The type value. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + if not body: + body = aggregate_patch_deployment_configs_payload(passed_keywords=kwargs) + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="AggregateDeploymentConfigsV1", + body=body + ) + + @force_default(defaults=["body"], default_types=["dict"]) + def aggregate_patch_deployment_executions(self: object, + body: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Retrieve deployment execution aggregations. + + HTTP Method: POST + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/deployment-executions/AggregateDeploymentExecutionsV1 + + Keyword arguments + ----------------- + body : dict + Full body payload as a JSON formatted dictionary. Not required if using other keywords. + { + "date_ranges": [ + { + "from": "string", + "to": "string" + } + ], + "exclude": "string", + "extended_bounds": { + "max": "string", + "min": "string" + }, + "field": "string", + "filter": "string", + "filters_spec": { + "filters": "string", + "other_bucket": true, + "other_bucket_key": "string" + }, + "from": 0, + "include": "string", + "interval": "string", + "max_doc_count": 0, + "min_doc_count": 0, + "missing": "string", + "name": "string", + "percents": [ + "string" + ], + "q": "string", + "ranges": [ + { + "From": 0.0, + "To": 0.0 + } + ], + "size": 0, + "sort": "string", + "sub_aggregates": [ + "string" + ], + "time_zone": "string", + "type": "string" + } + date_ranges : list + The date_ranges value. + exclude : str + The exclude value. + extended_bounds : dict + The extended_bounds value. + field : str + The field value. + filter : str + The filter value. + filters_spec : dict + The filters_spec value. + from : int + The from value. + include : str + The include value. + interval : str + The interval value. + max_doc_count : int + The max_doc_count value. + min_doc_count : int + The min_doc_count value. + missing : str + The missing value. + name : str + The name value. + percents : list + The percents value. + q : str + The q value. + ranges : list + The ranges value. + size : int + The size value. + sort : str + The sort value. + sub_aggregates : list + The sub_aggregates value. + time_zone : str + The time_zone value. + type : str + The type value. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + if not body: + body = aggregate_patch_deployment_executions_payload(passed_keywords=kwargs) + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="AggregateDeploymentExecutionsV1", + body=body + ) + + @force_default(defaults=["body"], default_types=["dict"]) + def aggregate_patch_host_deployments(self: object, + body: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Retrieve host deployment aggregations. + + HTTP Method: POST + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/host-deployments/AggregateHostDeploymentsV1 + + Keyword arguments + ----------------- + body : dict + Full body payload as a JSON formatted dictionary. Not required if using other keywords. + { + "date_ranges": [ + { + "from": "string", + "to": "string" + } + ], + "exclude": "string", + "extended_bounds": { + "max": "string", + "min": "string" + }, + "field": "string", + "filter": "string", + "filters_spec": { + "filters": "string", + "other_bucket": true, + "other_bucket_key": "string" + }, + "from": 0, + "include": "string", + "interval": "string", + "max_doc_count": 0, + "min_doc_count": 0, + "missing": "string", + "name": "string", + "percents": [ + "string" + ], + "q": "string", + "ranges": [ + { + "From": 0.0, + "To": 0.0 + } + ], + "size": 0, + "sort": "string", + "sub_aggregates": [ + "string" + ], + "time_zone": "string", + "type": "string" + } + date_ranges : list + The date_ranges value. + exclude : str + The exclude value. + extended_bounds : dict + The extended_bounds value. + field : str + The field value. + filter : str + The filter value. + filters_spec : dict + The filters_spec value. + from : int + The from value. + include : str + The include value. + interval : str + The interval value. + max_doc_count : int + The max_doc_count value. + min_doc_count : int + The min_doc_count value. + missing : str + The missing value. + name : str + The name value. + percents : list + The percents value. + q : str + The q value. + ranges : list + The ranges value. + size : int + The size value. + sort : str + The sort value. + sub_aggregates : list + The sub_aggregates value. + time_zone : str + The time_zone value. + type : str + The type value. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + if not body: + body = aggregate_patch_host_deployments_payload(passed_keywords=kwargs) + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="AggregateHostDeploymentsV1", + body=body + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def cancel_patch_deployment_executions(self: object, + *args, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Cancel deployment executions by IDs. + + HTTP Method: DELETE + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/deployment-executions/CancelDeploymentExecutionsV1 + + Keyword arguments + ----------------- + ids : str or list[str] + Comma separated values of deployment execution ids to cancel. + parameters : dict + Full parameters payload. Not required if using other keywords. + + Arguments + --------- + When not specified, the first argument to this method is assumed to be 'ids'. + All others are ignored. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="CancelDeploymentExecutionsV1", + keywords=kwargs, + params=handle_single_argument(args, parameters, "ids") + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def query_combined_os_assessment_scan(self: object, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Search and retrieve OS assessment scan statuses in a single request. + + HTTP Method: GET + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/patch-mgmt/CombinedOSAssessmentScan + + Keyword arguments + ----------------- + filter : str + FQL filter expression for searching assessment scans. + sort : str + Sort expression. + limit : int + Maximum number of records to return. + after : str + A pagination token used with the limit parameter to manage pagination of results. On your first request, don't + provide an after token. On subsequent requests, provide the after token from the previous response to continue + from that place in the results. + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="CombinedOSAssessmentScan", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def query_combined_os_assessments(self: object, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Search and retrieve OS patch assessments in a single request. + + HTTP Method: GET + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/patch-mgmt/CombinedOSAssessments + + Keyword arguments + ----------------- + filter : str + FQL filter expression for searching assessments. + sort : str + Sort expression. + limit : int + Maximum number of records to return. + after : str + A pagination token used with the limit parameter to manage pagination of results. On your first request, don't + provide an after token. On subsequent requests, provide the after token from the previous response to continue + from that place in the results. + facets : str + Vulnerability facets to include in response: 'vulnerabilities' (full array), 'vulnerability_counts' + (summary). Default: vulnerability_counts. + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="CombinedOSAssessments", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["body"], default_types=["dict"]) + def create_patch_deployment_config(self: object, + body: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Create a new deployment configuration. + + HTTP Method: POST + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/deployment-configs/CreateDeploymentConfig + + Keyword arguments + ----------------- + body : dict + Full body payload as a JSON formatted dictionary. Not required if using other keywords. + { + "block_filter_group_ids": [ + "string" + ], + "disabled": true, + "name": "string", + "patch_filter_group_ids": [ + "string" + ], + "platform": "string", + "post_patch_script_options": { + "content": "string", + "enabled": true, + "run_before_reboot": true, + "script_type": "string" + }, + "pre_patch_script_options": { + "content": "string", + "continue_on_failure": true, + "enabled": true, + "script_type": "string" + }, + "prestage": true, + "reboot_options": { + "allow_end_user_to_defer": true, + "occurrence": "string", + "reboot": true, + "reboot_user_notification_deferral_deadline_hours": 0, + "reboot_user_notification_deferral_deadline_reference": "string", + "user_notification": true, + "user_notification_message": "string", + "user_notification_title": "string" + }, + "recurring": true, + "run_now_no_schedule": true, + "schedule": { + "deployment_duration_minutes": 0, + "deployment_start_time": "string", + "recurrence_day_of_week": "string", + "recurrence_frequency": "string", + "recurrence_time_of_month": "string", + "schedule_activate_date": "string", + "schedule_terminate_date": "string" + }, + "target_hosts": "string", + "target_patches": "string", + "user_notification_options": { + "allow_end_user_to_defer": true, + "user_notification": true, + "user_notification_message": "string", + "user_notification_title": "string" + } + } + block_filter_group_ids : list + References to block filter groups (is_block=true, additive to global) + disabled : bool + Whether the deployment configuration is disabled. + name : str + Name of the deployment configuration. + patch_filter_group_ids : list + References to patch filter groups (is_block=false) + platform : str + Platforms which are targeted by this deployment configuration. + post_patch_script_options : dict + Post-patch script configuration options. + pre_patch_script_options : dict + Pre-patch script configuration options. + prestage : bool + Whether patches should be downloaded to a host ahead of installation. + reboot_options : dict + Advanced reboot configuration options. + recurring : bool + Whether the deployment is recurring or one-time scheduled. + run_now_no_schedule : bool + Whether the Deployment should run immediately. + schedule : dict + Schedule configuration. + target_hosts : str + FQL query for hosts to target. Supported fields: host.aid | host.name | host.device_type | host.os_version | + host.last_seen | host.asset_criticality | host.organizational_unit | host.country | host.tags | host.groups | + host.internet_exposure | last_scanned. + target_patches : str + FQL query for patches to apply. OS deployment supported fields: patch.id | patch.name | patch.version | + patch.severity | patch.type | patch.classifications | patch.release_date | patch.vendor_name | patch.vendor_url | + patch.size | patch.supersedence | patch.reboot_requirement | patch.repo | patch.description | + vulnerabilities.exprt_ai_rating | vulnerabilities.id. App deployment supported fields: available_update.id | + available_update.vendor | available_update.name | available_update.version | available_update.arch | + available_update.locale | available_update.scope | available_update.application_id | available_update.source | + available_update.publish_date | available_update.family_name | available_update.family_category | + available_update.vendor_name_version | available_update.version_sequence | available_update.is_latest_version | + available_update.is_in_place_update | installation_status | last_scanned | platform | vulnerabilities.id | + vulnerabilities.exprt_ai_rating | vulnerabilities.cvss_attack_vector. + user_notification_options : dict + Advanced user notification configuration options. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + if not body: + body = create_patch_deployment_config_payload(passed_keywords=kwargs) + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="CreateDeploymentConfig", + body=body + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def delete_patch_deployment_configs(self: object, + *args, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Delete deployment configurations by IDs. + + HTTP Method: DELETE + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/deployment-configs/DeleteDeploymentConfigs + + Keyword arguments + ----------------- + ids : str or list[str] + Deployment config IDs to delete. + parameters : dict + Full parameters payload. Not required if using other keywords. + + Arguments + --------- + When not specified, the first argument to this method is assumed to be 'ids'. + All others are ignored. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="DeleteDeploymentConfigs", + keywords=kwargs, + params=handle_single_argument(args, parameters, "ids") + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def query_combined_patch_deployment_configs(self: object, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Retrieve deployment configs by query. + + HTTP Method: GET + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/deployment-configs/GetDeploymentConfigsByQueryV1 + + Keyword arguments + ----------------- + filter : str + The filter expression that should be used to limit the results. Allowable categories are: + sort : str + The sort expression that should be used to sort the results. + offset : int + The offset to start retrieving records from. + limit : int + The maximum records to return. + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="GetDeploymentConfigsByQueryV1", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def query_combined_patch_deployment_executions(self: object, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Retrieve deployment executions by query. + + HTTP Method: GET + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/deployment-executions/GetDeploymentExecutionsByQueryV1 + + Keyword arguments + ----------------- + filter : str + The filter expression. Optionally filter by deployment_config.id:'' or status:'' + sort : str + The sort expression that should be used to sort the results. + offset : int + The offset to start retrieving records from. + limit : int + The maximum records to return. + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="GetDeploymentExecutionsByQueryV1", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def query_combined_host_deployment_patches(self: object, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Retrieve host deployment patch statuses by query. + + HTTP Method: GET + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/host-deployment-patches/GetHostDeploymentPatchesByQueryV1 + + Keyword arguments + ----------------- + filter : str + The filter expression. Must include host_deployment_id:''. Optionally filter by + status:'installed|not-installed' + sort : str + The sort expression that should be used to sort the results. + offset : int + The offset to start retrieving records from. + limit : int + The maximum records to return. + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="GetHostDeploymentPatchesByQueryV1", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def query_combined_host_deployments(self: object, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Retrieve deployment results by query. + + HTTP Method: GET + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/host-deployments/GetHostDeploymentsByQueryV1 + + Keyword arguments + ----------------- + filter : str + The filter expression that should be used to limit the results. Allowable categories are: + sort : str + The sort expression that should be used to sort the results. + offset : int + The offset to start retrieving records from. + limit : int + The maximum records to return. + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="GetHostDeploymentsByQueryV1", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["body"], default_types=["dict"]) + def update_patch_deployment_config(self: object, + body: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Update an existing deployment configuration. + + HTTP Method: PATCH + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/deployment-configs/UpdateDeploymentConfig + + Keyword arguments + ----------------- + body : dict + Full body payload as a JSON formatted dictionary. Not required if using other keywords. + { + "block_filter_group_ids": [ + "string" + ], + "disabled": true, + "id": "string", + "name": "string", + "patch_filter_group_ids": [ + "string" + ], + "platform": "string", + "post_patch_script_options": { + "content": "string", + "enabled": true, + "run_before_reboot": true, + "script_type": "string" + }, + "pre_patch_script_options": { + "content": "string", + "continue_on_failure": true, + "enabled": true, + "script_type": "string" + }, + "prestage": true, + "reboot_options": { + "allow_end_user_to_defer": true, + "occurrence": "string", + "reboot": true, + "reboot_user_notification_deferral_deadline_hours": 0, + "reboot_user_notification_deferral_deadline_reference": "string", + "user_notification": true, + "user_notification_message": "string", + "user_notification_title": "string" + }, + "recurring": true, + "run_now_no_schedule": true, + "schedule": { + "deployment_duration_minutes": 0, + "deployment_start_time": "string", + "recurrence_day_of_week": "string", + "recurrence_frequency": "string", + "recurrence_time_of_month": "string", + "schedule_activate_date": "string", + "schedule_terminate_date": "string" + }, + "target_hosts": "string", + "target_patches": "string", + "user_notification_options": { + "allow_end_user_to_defer": true, + "user_notification": true, + "user_notification_message": "string", + "user_notification_title": "string" + } + } + block_filter_group_ids : list + Block filter group refs (is_block=true). Omit to leave unchanged; send [] to clear. + disabled : bool + Whether the deployment configuration is disabled. + id : str + ID of the deployment configuration to update. + name : str + Name of the deployment configuration. + patch_filter_group_ids : list + References to patch filter groups (is_block=false). Omit to leave existing references unchanged; send [] to clear + all references. + platform : str + Platforms which are targeted by this deployment configuration. + post_patch_script_options : dict + Post-patch script configuration options. + pre_patch_script_options : dict + Pre-patch script configuration options. + prestage : bool + Whether patches should be downloaded to a host ahead of installation. + reboot_options : dict + Advanced reboot configuration options. + recurring : bool + Whether the deployment is recurring or one-time scheduled. + run_now_no_schedule : bool + Whether the Deployment should run immediately. + schedule : dict + Schedule configuration. + target_hosts : str + FQL query for hosts to target. Supported fields: host.aid | host.name | host.device_type | host.os_version | + host.last_seen | host.asset_criticality | host.organizational_unit | host.country | host.tags | host.groups | + host.internet_exposure | last_scanned. + target_patches : str + FQL query for patches to apply. OS deployment supported fields: patch.id | patch.name | patch.version | + patch.severity | patch.type | patch.classifications | patch.release_date | patch.vendor_name | patch.vendor_url | + patch.size | patch.supersedence | patch.reboot_requirement | patch.repo | patch.description | + vulnerabilities.exprt_ai_rating | vulnerabilities.id. App deployment supported fields: available_update.id | + available_update.vendor | available_update.name | available_update.version | available_update.arch | + available_update.locale | available_update.scope | available_update.application_id | available_update.source | + available_update.publish_date | available_update.family_name | available_update.family_category | + available_update.vendor_name_version | available_update.version_sequence | available_update.is_latest_version | + available_update.is_in_place_update | installation_status | last_scanned | platform | vulnerabilities.id | + vulnerabilities.exprt_ai_rating | vulnerabilities.cvss_attack_vector. + user_notification_options : dict + Advanced user notification configuration options. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + if not body: + body = update_patch_deployment_config_payload(passed_keywords=kwargs) + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="UpdateDeploymentConfig", + body=body + ) + + AggregateDeploymentConfigsV1 = aggregate_patch_deployment_configs + AggregateDeploymentExecutionsV1 = aggregate_patch_deployment_executions + AggregateHostDeploymentsV1 = aggregate_patch_host_deployments + CancelDeploymentExecutionsV1 = cancel_patch_deployment_executions + CombinedOSAssessments = query_combined_os_assessments + CombinedOSAssessmentScan = query_combined_os_assessment_scan + CreateDeploymentConfig = create_patch_deployment_config + DeleteDeploymentConfigs = delete_patch_deployment_configs + GetDeploymentConfigsByQueryV1 = query_combined_patch_deployment_configs + GetDeploymentExecutionsByQueryV1 = query_combined_patch_deployment_executions + GetHostDeploymentPatchesByQueryV1 = query_combined_host_deployment_patches + GetHostDeploymentsByQueryV1 = query_combined_host_deployments ITAutomationGetAssociatedTasks = get_associated_tasks ITAutomationCombinedScheduledTasks = scheduled_task_details ITAutomationGetTaskExecutionsByQuery = get_executions_by_query @@ -2773,6 +3747,7 @@ def search_tasks(self: object, parameters: dict = None, **kwargs) -> Union[Dict[ ITAutomationSearchTaskExecutions = search_task_executions ITAutomationSearchTaskGroups = search_task_groups ITAutomationSearchTasks = search_tasks + UpdateDeploymentConfig = update_patch_deployment_config F4IT = ITAutomation diff --git a/src/falconpy/it_automation.pyi b/src/falconpy/it_automation.pyi index cad2fd4b3..864443628 100644 --- a/src/falconpy/it_automation.pyi +++ b/src/falconpy/it_automation.pyi @@ -458,6 +458,214 @@ class ITAutomation(ServiceClass): parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... + def aggregate_patch_deployment_configs( + self, + *, + date_ranges: Optional[list] = None, + exclude: Optional[str] = None, + extended_bounds: Optional[dict] = None, + field: Optional[str] = None, + filter: Optional[str] = None, + filters_spec: Optional[dict] = None, + include: Optional[str] = None, + interval: Optional[str] = None, + max_doc_count: Optional[int] = None, + min_doc_count: Optional[int] = None, + missing: Optional[str] = None, + name: Optional[str] = None, + percents: Optional[list] = None, + q: Optional[str] = None, + ranges: Optional[list] = None, + size: Optional[int] = None, + sort: Optional[str] = None, + sub_aggregates: Optional[list] = None, + time_zone: Optional[str] = None, + type: Optional[str] = None, + body: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def aggregate_patch_deployment_executions( + self, + *, + date_ranges: Optional[list] = None, + exclude: Optional[str] = None, + extended_bounds: Optional[dict] = None, + field: Optional[str] = None, + filter: Optional[str] = None, + filters_spec: Optional[dict] = None, + include: Optional[str] = None, + interval: Optional[str] = None, + max_doc_count: Optional[int] = None, + min_doc_count: Optional[int] = None, + missing: Optional[str] = None, + name: Optional[str] = None, + percents: Optional[list] = None, + q: Optional[str] = None, + ranges: Optional[list] = None, + size: Optional[int] = None, + sort: Optional[str] = None, + sub_aggregates: Optional[list] = None, + time_zone: Optional[str] = None, + type: Optional[str] = None, + body: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def aggregate_patch_host_deployments( + self, + *, + date_ranges: Optional[list] = None, + exclude: Optional[str] = None, + extended_bounds: Optional[dict] = None, + field: Optional[str] = None, + filter: Optional[str] = None, + filters_spec: Optional[dict] = None, + include: Optional[str] = None, + interval: Optional[str] = None, + max_doc_count: Optional[int] = None, + min_doc_count: Optional[int] = None, + missing: Optional[str] = None, + name: Optional[str] = None, + percents: Optional[list] = None, + q: Optional[str] = None, + ranges: Optional[list] = None, + size: Optional[int] = None, + sort: Optional[str] = None, + sub_aggregates: Optional[list] = None, + time_zone: Optional[str] = None, + type: Optional[str] = None, + body: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def cancel_patch_deployment_executions( + self, + *args: Union[str, List[str]], + ids: Optional[Union[str, List[str]]] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def query_combined_os_assessment_scan( + self, + *, + filter: Optional[str] = None, + sort: Optional[str] = None, + limit: Optional[int] = None, + after: Optional[str] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def query_combined_os_assessments( + self, + *, + filter: Optional[str] = None, + sort: Optional[str] = None, + limit: Optional[int] = None, + after: Optional[str] = None, + facets: Optional[str] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def create_patch_deployment_config( + self, + *, + block_filter_group_ids: Optional[Union[str, List[str]]] = None, + disabled: Optional[bool] = None, + name: Optional[str] = None, + patch_filter_group_ids: Optional[Union[str, List[str]]] = None, + platform: Optional[str] = None, + post_patch_script_options: Optional[dict] = None, + pre_patch_script_options: Optional[dict] = None, + prestage: Optional[bool] = None, + reboot_options: Optional[dict] = None, + recurring: Optional[bool] = None, + run_now_no_schedule: Optional[bool] = None, + schedule: Optional[dict] = None, + target_hosts: Optional[str] = None, + target_patches: Optional[str] = None, + user_notification_options: Optional[dict] = None, + body: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def delete_patch_deployment_configs( + self, + *args: Union[str, List[str]], + ids: Optional[Union[str, List[str]]] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def query_combined_patch_deployment_configs( + self, + *, + filter: Optional[str] = None, + sort: Optional[str] = None, + offset: Optional[int] = None, + limit: Optional[int] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def query_combined_patch_deployment_executions( + self, + *, + filter: Optional[str] = None, + sort: Optional[str] = None, + offset: Optional[int] = None, + limit: Optional[int] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def query_combined_host_deployment_patches( + self, + *, + filter: Optional[str] = None, + sort: Optional[str] = None, + offset: Optional[int] = None, + limit: Optional[int] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def query_combined_host_deployments( + self, + *, + filter: Optional[str] = None, + sort: Optional[str] = None, + offset: Optional[int] = None, + limit: Optional[int] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def update_patch_deployment_config( + self, + *, + block_filter_group_ids: Optional[Union[str, List[str]]] = None, + disabled: Optional[bool] = None, + id: Optional[str] = None, + name: Optional[str] = None, + patch_filter_group_ids: Optional[Union[str, List[str]]] = None, + platform: Optional[str] = None, + post_patch_script_options: Optional[dict] = None, + pre_patch_script_options: Optional[dict] = None, + prestage: Optional[bool] = None, + reboot_options: Optional[dict] = None, + recurring: Optional[bool] = None, + run_now_no_schedule: Optional[bool] = None, + schedule: Optional[dict] = None, + target_hosts: Optional[str] = None, + target_patches: Optional[str] = None, + user_notification_options: Optional[dict] = None, + body: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + AggregateDeploymentConfigsV1 = aggregate_patch_deployment_configs + AggregateDeploymentExecutionsV1 = aggregate_patch_deployment_executions + AggregateHostDeploymentsV1 = aggregate_patch_host_deployments + CancelDeploymentExecutionsV1 = cancel_patch_deployment_executions + CombinedOSAssessments = query_combined_os_assessments + CombinedOSAssessmentScan = query_combined_os_assessment_scan + CreateDeploymentConfig = create_patch_deployment_config + DeleteDeploymentConfigs = delete_patch_deployment_configs + GetDeploymentConfigsByQueryV1 = query_combined_patch_deployment_configs + GetDeploymentExecutionsByQueryV1 = query_combined_patch_deployment_executions + GetHostDeploymentPatchesByQueryV1 = query_combined_host_deployment_patches + GetHostDeploymentsByQueryV1 = query_combined_host_deployments ITAutomationGetAssociatedTasks = get_associated_tasks ITAutomationCombinedScheduledTasks = scheduled_task_details ITAutomationGetTaskExecutionsByQuery = get_executions_by_query @@ -500,3 +708,4 @@ class ITAutomation(ServiceClass): ITAutomationSearchTaskExecutions = search_task_executions ITAutomationSearchTaskGroups = search_task_groups ITAutomationSearchTasks = search_tasks + UpdateDeploymentConfig = update_patch_deployment_config diff --git a/src/falconpy/knowledge_base_audit_events.py b/src/falconpy/knowledge_base_audit_events.py index da780c6f1..5af59dbd9 100644 --- a/src/falconpy/knowledge_base_audit_events.py +++ b/src/falconpy/knowledge_base_audit_events.py @@ -187,6 +187,8 @@ def combined_knowledge_base_audit_events_v1(self: object, FQL query specifying the filter parameters. include_deleted : bool Include audit events for deleted knowledge bases. Defaults to false. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. @@ -226,6 +228,8 @@ def entities_knowledge_base_audit_events_v1(self: object, IDs of audit events to retrieve. include_deleted : bool Include audit events for deleted knowledge bases. Defaults to false. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. @@ -271,6 +275,8 @@ def queries_knowledge_base_audit_events_v1(self: object, FQL query specifying the filter parameters. include_deleted : bool Include audit events for deleted knowledge bases. Defaults to false. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. diff --git a/src/falconpy/knowledge_base_audit_events.pyi b/src/falconpy/knowledge_base_audit_events.pyi index 4132ee054..51656c893 100644 --- a/src/falconpy/knowledge_base_audit_events.pyi +++ b/src/falconpy/knowledge_base_audit_events.pyi @@ -23,6 +23,7 @@ class KnowledgeBaseAuditEvents(ServiceClass): sort: Optional[str] = None, filter: Optional[str] = None, include_deleted: Optional[bool] = None, + project_id: Optional[str] = None, parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... @@ -32,6 +33,7 @@ class KnowledgeBaseAuditEvents(ServiceClass): knowledge_base_id: Optional[str] = None, ids: Optional[Union[str, List[str]]] = None, include_deleted: Optional[bool] = None, + project_id: Optional[str] = None, parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... @@ -44,6 +46,7 @@ class KnowledgeBaseAuditEvents(ServiceClass): sort: Optional[str] = None, filter: Optional[str] = None, include_deleted: Optional[bool] = None, + project_id: Optional[str] = None, parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... diff --git a/src/falconpy/knowledge_base_files.py b/src/falconpy/knowledge_base_files.py index e5dbfe5d1..8c9ba44e9 100644 --- a/src/falconpy/knowledge_base_files.py +++ b/src/falconpy/knowledge_base_files.py @@ -74,6 +74,8 @@ def entities_knowledge_base_files_download_v1(self: object, ID of the knowledge base. id : str ID of entities to retrieve. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. @@ -113,6 +115,8 @@ def entities_knowledge_base_files_v1(self: object, IDs of entities to retrieve. include_deleted : bool Include deleted knowledge base files in the result. Defaults to false. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. @@ -154,6 +158,8 @@ def entities_knowledge_base_files_update_v1(self: object, New file content to replace the existing document. file_description : str New description for the document. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. @@ -208,6 +214,8 @@ def entities_knowledge_base_files_create_v1(self: object, File to be uploaded. file_description : str Description for the uploaded file. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. @@ -258,6 +266,8 @@ def entities_knowledge_base_files_delete_v1(self: object, ID of the knowledge base. id : str ID of the document to delete. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. @@ -301,6 +311,8 @@ def queries_knowledge_base_files_v1(self: object, FQL query specifying the filter parameters. include_deleted : bool Include deleted knowledge base files in the result. Defaults to false. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. diff --git a/src/falconpy/knowledge_base_files.pyi b/src/falconpy/knowledge_base_files.pyi index a29ffad49..ae14d1839 100644 --- a/src/falconpy/knowledge_base_files.pyi +++ b/src/falconpy/knowledge_base_files.pyi @@ -11,6 +11,7 @@ class KnowledgeBaseFiles(ServiceClass): *, knowledge_base_id: Optional[str] = None, id: Optional[str] = None, + project_id: Optional[str] = None, parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... @@ -20,6 +21,7 @@ class KnowledgeBaseFiles(ServiceClass): knowledge_base_id: Optional[str] = None, ids: Optional[Union[str, List[str]]] = None, include_deleted: Optional[bool] = None, + project_id: Optional[str] = None, parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... @@ -40,6 +42,7 @@ class KnowledgeBaseFiles(ServiceClass): *, knowledge_base_id: Optional[str] = None, id: Optional[str] = None, + project_id: Optional[str] = None, parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... @@ -51,6 +54,7 @@ class KnowledgeBaseFiles(ServiceClass): limit: Optional[int] = None, filter: Optional[str] = None, include_deleted: Optional[bool] = None, + project_id: Optional[str] = None, parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... diff --git a/src/falconpy/knowledge_bases.py b/src/falconpy/knowledge_bases.py index 73b9c622a..ea3883390 100644 --- a/src/falconpy/knowledge_bases.py +++ b/src/falconpy/knowledge_bases.py @@ -179,6 +179,8 @@ def entities_knowledge_bases_v1(self: object, IDs of entities to retrieve. include_deleted : bool Include deleted knowledge bases in the result. Defaults to false. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. @@ -272,6 +274,8 @@ def entities_knowledge_bases_create_v1(self: object, The is_deleted value. name : str The name value. + project_id : str + The project_id value. updated_at : str The updated_at value. updated_by : dict @@ -373,6 +377,8 @@ def entities_knowledge_bases_update_v1(self: object, The updated_at value. updated_by : dict The updated_by value. + project_id : str + Scope the operation to a project. This method only supports keywords for providing arguments. @@ -416,6 +422,8 @@ def queries_knowledge_bases_v1(self: object, FQL query specifying the filter parameters. include_deleted : bool Include deleted knowledge bases in the result. Defaults to false. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. @@ -459,6 +467,8 @@ def combined_knowledge_bases_v1(self: object, FQL query specifying the filter parameters. include_deleted : bool Include deleted knowledge bases in the result. Defaults to false. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. diff --git a/src/falconpy/knowledge_bases.pyi b/src/falconpy/knowledge_bases.pyi index 9fc8807d8..a2f00ba98 100644 --- a/src/falconpy/knowledge_bases.pyi +++ b/src/falconpy/knowledge_bases.pyi @@ -19,6 +19,7 @@ class KnowledgeBases(ServiceClass): *, ids: Optional[Union[str, List[str]]] = None, include_deleted: Optional[bool] = None, + project_id: Optional[str] = None, parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... @@ -34,6 +35,7 @@ class KnowledgeBases(ServiceClass): id: Optional[str] = None, is_deleted: Optional[bool] = None, name: Optional[str] = None, + project_id: Optional[str] = None, updated_at: Optional[str] = None, updated_by: Optional[dict] = None, body: Optional[dict] = None, @@ -42,6 +44,7 @@ class KnowledgeBases(ServiceClass): def entities_knowledge_bases_update_v1( self, *, + project_id: Optional[str] = None, attribution: Optional[dict] = None, created_at: Optional[str] = None, created_by: Optional[dict] = None, @@ -64,6 +67,7 @@ class KnowledgeBases(ServiceClass): sort: Optional[str] = None, filter: Optional[str] = None, include_deleted: Optional[bool] = None, + project_id: Optional[str] = None, parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... @@ -75,6 +79,7 @@ class KnowledgeBases(ServiceClass): sort: Optional[str] = None, filter: Optional[str] = None, include_deleted: Optional[bool] = None, + project_id: Optional[str] = None, parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... diff --git a/src/falconpy/ml_exclusions.pyi b/src/falconpy/ml_exclusions.pyi index 429a3fb0d..4d713dd69 100644 --- a/src/falconpy/ml_exclusions.pyi +++ b/src/falconpy/ml_exclusions.pyi @@ -77,11 +77,13 @@ class MLExclusions(ServiceClass): def update_exclusions_v2( self, *, + applied_globally: Optional[bool] = None, comment: Optional[str] = None, excluded_from: Optional[Union[str, List[str]]] = None, grandparent_value: Optional[str] = None, groups: Optional[Union[str, List[str]]] = None, id: Optional[str] = None, + is_descendant_process: Optional[bool] = None, parent_value: Optional[str] = None, value: Optional[str] = None, body: Optional[dict] = None, @@ -126,6 +128,7 @@ class MLExclusions(ServiceClass): self, *, comment: Optional[str] = None, + excluded_from: Optional[Union[str, List[str]]] = None, groups: Optional[Union[str, List[str]]] = None, id: Optional[str] = None, is_descendant_process: Optional[bool] = None, @@ -162,6 +165,7 @@ class MLExclusions(ServiceClass): self, *, comment: Optional[str] = None, + excluded_from: Optional[Union[str, List[str]]] = None, groups: Optional[Union[str, List[str]]] = None, id: Optional[str] = None, is_descendant_process: Optional[bool] = None, diff --git a/src/falconpy/ngsiem.py b/src/falconpy/ngsiem.py index 9f50b3ed2..e47df215e 100644 --- a/src/falconpy/ngsiem.py +++ b/src/falconpy/ngsiem.py @@ -81,6 +81,8 @@ create_persisted_aggregation_payload, rollback_parser_payload, update_persisted_aggregation_payload, + create_scheduled_report_payload, + update_scheduled_report_payload, ) from ._result import Result from ._service_class import ServiceClass @@ -4383,6 +4385,321 @@ def update_persisted_aggregation(self: object, body=body ) + @force_default(defaults=["body"], default_types=["dict"]) + def create_scheduled_report(self: object, + body: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Create a Scheduled Report in LogScale. + + HTTP Method: POST + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/ngsiem/CreateScheduledReport + + Keyword arguments + ----------------- + body : dict + Full body payload as a JSON formatted dictionary. Not required if using other keywords. + { + "dashboard_id": "string", + "description": "string", + "enabled": true, + "labels": [ + "string" + ], + "layout": { + "footer_show_page_numbers": true, + "max_number_of_rows": 0, + "paper_layout": "string", + "paper_orientation": "string", + "paper_size": "string", + "show_description": true, + "show_export_date": true, + "show_parameters": true, + "show_title_frontpage": true, + "show_title_header": true + }, + "name": "string", + "parameters": [ + { + "id": "string", + "value": "string" + } + ], + "password": "string", + "recipients": [ + "string" + ], + "schedule": { + "cron_expression": "string", + "end_date": 0, + "start_date": 0, + "time_zone": "string" + }, + "time_interval_from": "string", + "view_name": "string" + } + dashboard_id : str + ID of the dashboard to report on. + description : str + Description of the scheduled report. + enabled : bool + Whether the report is enabled. + labels : list + Labels (max 10, max 60 chars each) + layout : dict + Report layout configuration. + name : str + Name of the scheduled report. + parameters : dict + Parameter values. + password : str + Password to protect generated reports. + recipients : list + Email recipients. + schedule : dict + Schedule configuration. + time_interval_from : str + Relative time interval start. + view_name : str + Name of the view or repo. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + if not body: + body = create_scheduled_report_payload(passed_keywords=kwargs) + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="CreateScheduledReport", + body=body + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def delete_scheduled_report(self: object, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Delete Scheduled Report(s) in LogScale. + + HTTP Method: DELETE + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/ngsiem/DeleteScheduledReport + + Keyword arguments + ----------------- + ids : list + scheduled report ID value(s). Supports single or multiple IDs for bulk delete. + search_domain : str + name of search domain (view or repo) + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="DeleteScheduledReport", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def get_scheduled_report(self: object, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Get Scheduled Report(s) in LogScale. + + HTTP Method: GET + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/ngsiem/GetScheduledReport + + Keyword arguments + ----------------- + ids : list + scheduled report ID value(s) + search_domain : str + name of search domain (view or repo) + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="GetScheduledReport", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def query_scheduled_reports(self: object, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """List Scheduled Reports in a view with Pagination and Filtering. + + HTTP Method: GET + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/ngsiem/ListScheduledReports + + Keyword arguments + ----------------- + limit : str + maximum number of results to return. + offset : str + number of results to offset the returned results by. + filter : str + FQL filter to apply to the name of the content, only currently support text match on name field: + name:~'value' + view_name : str + name of view or repo. + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="ListScheduledReports", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["body"], default_types=["dict"]) + def update_scheduled_report(self: object, + body: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Update a Scheduled Report in LogScale. + + HTTP Method: PATCH + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/ngsiem/UpdateScheduledReport + + Keyword arguments + ----------------- + body : dict + Full body payload as a JSON formatted dictionary. Not required if using other keywords. + { + "dashboard_id": "string", + "description": "string", + "enabled": true, + "id": "string", + "labels": [ + "string" + ], + "layout": { + "footer_show_page_numbers": true, + "max_number_of_rows": 0, + "paper_layout": "string", + "paper_orientation": "string", + "paper_size": "string", + "show_description": true, + "show_export_date": true, + "show_parameters": true, + "show_title_frontpage": true, + "show_title_header": true + }, + "name": "string", + "parameters": [ + { + "id": "string", + "value": "string" + } + ], + "password": "string", + "recipients": [ + "string" + ], + "schedule": { + "cron_expression": "string", + "end_date": 0, + "start_date": 0, + "time_zone": "string" + }, + "time_interval_from": "string", + "view_name": "string" + } + dashboard_id : str + New dashboard ID. + description : str + New description. + enabled : bool + Enable/disable. + id : str + ID of the scheduled report. + labels : list + New labels. + layout : dict + New layout. + name : str + New name. + parameters : dict + New parameters. + password : str + New password. + recipients : list + New recipients. + schedule : dict + New schedule. + time_interval_from : str + New time interval. + view_name : str + Name of the view or repo. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + if not body: + body = update_scheduled_report_payload(passed_keywords=kwargs) + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="UpdateScheduledReport", + body=body + ) + addDashboardLabels = add_dashboard_labels addFileLabels = add_file_labels addSavedQueryLabels = add_saved_query_labels @@ -4406,10 +4723,14 @@ def update_persisted_aggregation(self: object, bulkUpdateSavedQueryLabels = bulk_update_saved_query_labels CreateParserExtension = create_parser_extension CreatePersistedAggregation = create_persisted_aggregation + CreateScheduledReport = create_scheduled_report DeletePersistedAggregation = delete_persisted_aggregation + DeleteScheduledReport = delete_scheduled_report GetParserRollbackOptions = get_parser_rollback_options GetPersistedAggregation = get_persisted_aggregation + GetScheduledReport = get_scheduled_report ListPersistedAggregations = list_persisted_aggregations + ListScheduledReports = query_scheduled_reports removeDashboardLabels = remove_dashboard_labels removeFileLabels = remove_file_labels removeSavedQueryLabels = remove_saved_query_labels @@ -4419,6 +4740,7 @@ def update_persisted_aggregation(self: object, UpdateParserExtension = update_parser_extension UpdatePersistedAggregation = update_persisted_aggregation updateSavedQueryLabels = update_saved_query_labels + UpdateScheduledReport = update_scheduled_report UploadLookupV1 = upload_file GetLookupV1 = get_file GetLookupFromPackageWithNamespaceV1 = get_file_from_package_with_namespace diff --git a/src/falconpy/ngsiem.pyi b/src/falconpy/ngsiem.pyi index 0dc89bf60..6d4a45eb3 100644 --- a/src/falconpy/ngsiem.pyi +++ b/src/falconpy/ngsiem.pyi @@ -754,6 +754,69 @@ class NGSIEM(ServiceClass): body: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... + def create_scheduled_report( + self, + *, + dashboard_id: Optional[str] = None, + description: Optional[str] = None, + enabled: Optional[bool] = None, + labels: Optional[Union[str, List[str]]] = None, + layout: Optional[dict] = None, + name: Optional[str] = None, + parameters: Optional[list] = None, + password: Optional[str] = None, + recipients: Optional[Union[str, List[str]]] = None, + schedule: Optional[dict] = None, + time_interval_from: Optional[str] = None, + view_name: Optional[str] = None, + body: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def delete_scheduled_report( + self, + *, + ids: Optional[Union[str, List[str]]] = None, + search_domain: Optional[str] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def get_scheduled_report( + self, + *, + ids: Optional[Union[str, List[str]]] = None, + search_domain: Optional[str] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def query_scheduled_reports( + self, + *, + limit: Optional[str] = None, + offset: Optional[str] = None, + filter: Optional[str] = None, + view_name: Optional[str] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def update_scheduled_report( + self, + *, + dashboard_id: Optional[str] = None, + description: Optional[str] = None, + enabled: Optional[bool] = None, + id: Optional[str] = None, + labels: Optional[Union[str, List[str]]] = None, + layout: Optional[dict] = None, + name: Optional[str] = None, + parameters: Optional[list] = None, + password: Optional[str] = None, + recipients: Optional[Union[str, List[str]]] = None, + schedule: Optional[dict] = None, + time_interval_from: Optional[str] = None, + view_name: Optional[str] = None, + body: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + addDashboardLabels = add_dashboard_labels addFileLabels = add_file_labels addSavedQueryLabels = add_saved_query_labels @@ -777,10 +840,14 @@ class NGSIEM(ServiceClass): bulkUpdateSavedQueryLabels = bulk_update_saved_query_labels CreateParserExtension = create_parser_extension CreatePersistedAggregation = create_persisted_aggregation + CreateScheduledReport = create_scheduled_report DeletePersistedAggregation = delete_persisted_aggregation + DeleteScheduledReport = delete_scheduled_report GetParserRollbackOptions = get_parser_rollback_options GetPersistedAggregation = get_persisted_aggregation + GetScheduledReport = get_scheduled_report ListPersistedAggregations = list_persisted_aggregations + ListScheduledReports = query_scheduled_reports removeDashboardLabels = remove_dashboard_labels removeFileLabels = remove_file_labels removeSavedQueryLabels = remove_saved_query_labels @@ -790,6 +857,7 @@ class NGSIEM(ServiceClass): UpdateParserExtension = update_parser_extension UpdatePersistedAggregation = update_persisted_aggregation updateSavedQueryLabels = update_saved_query_labels + UpdateScheduledReport = update_scheduled_report UploadLookupV1 = upload_file GetLookupV1 = get_file GetLookupFromPackageWithNamespaceV1 = get_file_from_package_with_namespace diff --git a/src/falconpy/oauth2.py b/src/falconpy/oauth2.py index b7d406ace..8333d60c8 100644 --- a/src/falconpy/oauth2.py +++ b/src/falconpy/oauth2.py @@ -36,6 +36,7 @@ For more information, please refer to """ # pylint: disable=R0902,R0913 +import os from logging import Logger from typing import Dict, Optional, Union import requests @@ -81,7 +82,7 @@ class OAuth2(FalconInterface): def __init__(self, access_token: Optional[Union[str, bool]] = False, base_url: Optional[str] = "https://api.crowdstrike.com", - ssl_verify: Optional[bool] = True, + ssl_verify: Optional[Union[bool, str, os.PathLike]] = True, proxy: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, tuple]] = None, creds: Optional[Dict[str, str]] = None, @@ -107,8 +108,9 @@ def __init__(self, ----------------- base_url : str CrowdStrike API URL to use for requests. [Default: US-1] - ssl_verify : bool - Flag specifying if SSL verification should be used. [Default: True] + ssl_verify : bool or str + Flag specifying if SSL verification should be used, or the path to a CA_BUNDLE + file or directory of trusted certificates. [Default: True] proxy : dict Dictionary of proxies to be used for requests. timeout : float or tuple diff --git a/src/falconpy/quick_scan_pro.py b/src/falconpy/quick_scan_pro.py index 6898312b6..b52a4b348 100644 --- a/src/falconpy/quick_scan_pro.py +++ b/src/falconpy/quick_scan_pro.py @@ -85,6 +85,11 @@ def upload_file(self: object, parameters: dict = None, **kwargs) -> Union[Dict[s x_file_password : str OCTET-STREAM ONLY - Password for encrypted archives (use for octet-stream uploads). If 'scan' is true, the value is used for the scan just starting. + scan_mode : str + Sets the scan mode for the scan started when 'scan' is true. Default is 'standard'. 'fast': less than 5 seconds, + ML-based detection and signature matching. 'standard': less than 30 seconds, adds heuristic analysis to fast scan + coverage. 'deep': less than 90 seconds, adds static analysis and dynamic execution monitoring to standard scan + coverage. This method only supports keywords for providing arguments. diff --git a/src/falconpy/quick_scan_pro.pyi b/src/falconpy/quick_scan_pro.pyi index da84d19a8..d518d2e4c 100644 --- a/src/falconpy/quick_scan_pro.pyi +++ b/src/falconpy/quick_scan_pro.pyi @@ -31,6 +31,7 @@ class QuickScanPro(ServiceClass): self, *, password: Optional[str] = None, + scan_mode: Optional[str] = None, sha256: Optional[str] = None, body: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... diff --git a/src/falconpy/recon.pyi b/src/falconpy/recon.pyi index 4cb3f8fa1..4b2fb709e 100644 --- a/src/falconpy/recon.pyi +++ b/src/falconpy/recon.pyi @@ -205,6 +205,7 @@ class Recon(ServiceClass): name: Optional[str] = None, originating_template_id: Optional[str] = None, permissions: Optional[str] = None, + pir_ids: Optional[Union[str, List[str]]] = None, priority: Optional[str] = None, substring_matching_enabled: Optional[bool] = None, topic: Optional[str] = None, @@ -231,6 +232,7 @@ class Recon(ServiceClass): match_on_tsq_result_types: Optional[Union[str, List[str]]] = None, name: Optional[str] = None, permissions: Optional[str] = None, + pir_ids: Optional[Union[str, List[str]]] = None, priority: Optional[str] = None, substring_matching_enabled: Optional[bool] = None, tsq_match_edit_distance: Optional[str] = None, diff --git a/src/falconpy/saas_security.py b/src/falconpy/saas_security.py index 74766a96c..01a6054b8 100644 --- a/src/falconpy/saas_security.py +++ b/src/falconpy/saas_security.py @@ -44,6 +44,7 @@ create_user_journal_comment_payload, restore_affected_entity_payload, set_check_param_payload, + set_check_impact_payload, ) from ._result import Result from ._service_class import ServiceClass @@ -1631,6 +1632,108 @@ def set_check_param(self: object, body=body ) + @force_default(defaults=["parameters"], default_types=["dict"]) + def get_security_check_change_log(self: object, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """GET Security Check Change Log. + + HTTP Method: GET + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/saas-security/GetSecurityCheckChangeLogV3 + + Keyword arguments + ----------------- + action : str + Actions to filter by, comma separated (e.g. renamed,impact_changed) + limit : int + The maximum number of objects to return. + offset : int + The starting index of the results. + app : str + Supported integration (app) ids to filter by, comma separated. + check_id : str + Security check id - stable across a rename, so it returns the whole history. + from_date : str + From Date (in YYYY-MM-DD format) + to_date : str + To Date (in YYYY-MM-DD format) + total_count : bool + Fetch Total Count? + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="GetSecurityCheckChangeLogV3", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["body", "parameters"], default_types=["dict", "dict"]) + def set_check_impact(self: object, + body: dict = None, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """POST Set a Security Check Impact. + + HTTP Method: POST + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/saas-security/SetCheckImpactV3 + + Keyword arguments + ----------------- + id : str + Security Check ID. + body : dict + Full body payload as a JSON formatted dictionary. Not required if using other keywords. + { + "all_future_instances": true, + "impact": "string", + "reason": "string" + } + all_future_instances : bool + Also apply this impact to future instances of the same SaaS. + impact : str + The new impact. + reason : str + Why the impact was changed. Recorded on the check's timeline. + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + if not body: + body = set_check_impact_payload(passed_keywords=kwargs) + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="SetCheckImpactV3", + keywords=kwargs, + params=parameters, + body=body + ) + ConnectCheckTagV3 = connect_check_tag CreateAppJournalCommentV3 = create_app_journal_comment CreateCheckJournalCommentV3 = create_check_journal_comment @@ -1649,6 +1752,7 @@ def set_check_param(self: object, GetSecurityCheckAffectedV3 = get_security_check DismissAffectedEntityV3 = dismiss_affected_entity DismissSecurityCheckV3 = dismiss_security_check + GetSecurityCheckChangeLogV3 = get_security_check_change_log GetSecurityChecksV3 = get_security_checks GetSecurityCheckComplianceV3 = get_security_check_compliance GetUserJournalV3 = get_user_journal @@ -1666,4 +1770,5 @@ def set_check_param(self: object, GetUserInventoryV3 = get_user_inventory RestoreAffectedEntityV3 = restore_affected_entity RestoreSecurityCheckV3 = restore_security_check + SetCheckImpactV3 = set_check_impact SetCheckParamV3 = set_check_param diff --git a/src/falconpy/saas_security.pyi b/src/falconpy/saas_security.pyi index 24dda2063..46de14669 100644 --- a/src/falconpy/saas_security.pyi +++ b/src/falconpy/saas_security.pyi @@ -363,6 +363,31 @@ class SaasSecurity(ServiceClass): parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... + def get_security_check_change_log( + self, + *, + action: Optional[str] = None, + limit: Optional[int] = None, + offset: Optional[int] = None, + app: Optional[str] = None, + check_id: Optional[str] = None, + from_date: Optional[str] = None, + to_date: Optional[str] = None, + total_count: Optional[bool] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def set_check_impact( + self, + *, + id: Optional[str] = None, + all_future_instances: Optional[bool] = None, + impact: Optional[str] = None, + reason: Optional[str] = None, + body: Optional[dict] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + ConnectCheckTagV3 = connect_check_tag CreateAppJournalCommentV3 = create_app_journal_comment CreateCheckJournalCommentV3 = create_check_journal_comment @@ -381,6 +406,7 @@ class SaasSecurity(ServiceClass): GetSecurityCheckAffectedV3 = get_security_check DismissAffectedEntityV3 = dismiss_affected_entity DismissSecurityCheckV3 = dismiss_security_check + GetSecurityCheckChangeLogV3 = get_security_check_change_log GetSecurityChecksV3 = get_security_checks GetSecurityCheckComplianceV3 = get_security_check_compliance GetUserJournalV3 = get_user_journal @@ -398,4 +424,5 @@ class SaasSecurity(ServiceClass): GetUserInventoryV3 = get_user_inventory RestoreAffectedEntityV3 = restore_affected_entity RestoreSecurityCheckV3 = restore_security_check + SetCheckImpactV3 = set_check_impact SetCheckParamV3 = set_check_param diff --git a/src/falconpy/skills.py b/src/falconpy/skills.py index c8d538a91..7a358992a 100644 --- a/src/falconpy/skills.py +++ b/src/falconpy/skills.py @@ -74,6 +74,8 @@ def download_studio_skill(self: object, ID of the skill to download. include_deleted : bool Include deleted skills in the result. Defaults to false. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. @@ -111,6 +113,8 @@ def get_studio_skills(self: object, IDs of skills to retrieve. include_deleted : bool Include deleted skills in the result. Defaults to false. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. @@ -150,6 +154,8 @@ def update_studio_skill(self: object, ID of the skill to update. skill_blob : str Updated skill zip archive. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. @@ -201,6 +207,8 @@ def create_studio_skill(self: object, Name to use for the uploaded file. skill_blob : str Skill zip archive to upload. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. @@ -249,6 +257,8 @@ def delete_studio_skill(self: object, ----------------- id : str or list[str] ID of the skill to delete. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. @@ -297,6 +307,8 @@ def query_studio_skills(self: object, FQL query specifying the filter parameters. include_deleted : bool Include deleted skills in the result. Defaults to false. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. diff --git a/src/falconpy/skills.pyi b/src/falconpy/skills.pyi index 3deeea533..3b82cbed0 100644 --- a/src/falconpy/skills.pyi +++ b/src/falconpy/skills.pyi @@ -11,6 +11,7 @@ class Skills(ServiceClass): *, id: Optional[str] = None, include_deleted: Optional[bool] = None, + project_id: Optional[str] = None, parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... @@ -19,6 +20,7 @@ class Skills(ServiceClass): *, ids: Optional[Union[str, List[str]]] = None, include_deleted: Optional[bool] = None, + project_id: Optional[str] = None, parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... @@ -38,6 +40,7 @@ class Skills(ServiceClass): self, *args: Union[str, List[str]], id: Optional[str] = None, + project_id: Optional[str] = None, parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... @@ -49,6 +52,7 @@ class Skills(ServiceClass): sort: Optional[str] = None, filter: Optional[str] = None, include_deleted: Optional[bool] = None, + project_id: Optional[str] = None, parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... diff --git a/src/falconpy/spans.py b/src/falconpy/spans.py index e2b1b3ac1..79bc6fe41 100644 --- a/src/falconpy/spans.py +++ b/src/falconpy/spans.py @@ -73,6 +73,8 @@ def entities_spans_v1(self: object, ----------------- ids : str or list[str] IDs of entities to retrieve. Maximum of 1000 ids per request. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. @@ -117,6 +119,8 @@ def queries_spans_v1(self: object, Possible order by fields. E.g.: 'start_time|desc' filter : str FQL query specifying the filter parameters. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. diff --git a/src/falconpy/spans.pyi b/src/falconpy/spans.pyi index 908a171c0..5e3a86712 100644 --- a/src/falconpy/spans.pyi +++ b/src/falconpy/spans.pyi @@ -10,6 +10,7 @@ class Spans(ServiceClass): self, *args: Union[str, List[str]], ids: Optional[Union[str, List[str]]] = None, + project_id: Optional[str] = None, parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... @@ -20,6 +21,7 @@ class Spans(ServiceClass): limit: Optional[int] = None, sort: Optional[str] = None, filter: Optional[str] = None, + project_id: Optional[str] = None, parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... diff --git a/src/falconpy/stream.py b/src/falconpy/stream.py index df0d20dd5..63ea2c744 100644 --- a/src/falconpy/stream.py +++ b/src/falconpy/stream.py @@ -73,6 +73,8 @@ def stream_invocation_response_v1(self: object, ----------------- id : str or list[str] Invocation ID. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. diff --git a/src/falconpy/stream.pyi b/src/falconpy/stream.pyi index f16e5ca00..9fa808743 100644 --- a/src/falconpy/stream.pyi +++ b/src/falconpy/stream.pyi @@ -10,6 +10,7 @@ class Stream(ServiceClass): self, *args: Union[str, List[str]], id: Optional[str] = None, + project_id: Optional[str] = None, parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... diff --git a/src/falconpy/tools.py b/src/falconpy/tools.py index af7443691..61161fb7e 100644 --- a/src/falconpy/tools.py +++ b/src/falconpy/tools.py @@ -73,6 +73,8 @@ def entities_tools_v1(self: object, ----------------- ids : str or list[str] IDs of entities to retrieve. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. @@ -117,6 +119,8 @@ def queries_tools_v1(self: object, Possible order by fields: id, name, description, category. Ex: 'name|desc' filter : str FQL query specifying the filter parameters. + project_id : str + Scope the operation to a project. parameters : dict Full parameters payload. Not required if using other keywords. diff --git a/src/falconpy/tools.pyi b/src/falconpy/tools.pyi index 678096cad..d37a0a47f 100644 --- a/src/falconpy/tools.pyi +++ b/src/falconpy/tools.pyi @@ -10,6 +10,7 @@ class Tools(ServiceClass): self, *args: Union[str, List[str]], ids: Optional[Union[str, List[str]]] = None, + project_id: Optional[str] = None, parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... @@ -20,6 +21,7 @@ class Tools(ServiceClass): limit: Optional[int] = None, sort: Optional[str] = None, filter: Optional[str] = None, + project_id: Optional[str] = None, parameters: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... diff --git a/src/falconpy/user_management.py b/src/falconpy/user_management.py index ec9fff855..f40de0d0e 100644 --- a/src/falconpy/user_management.py +++ b/src/falconpy/user_management.py @@ -45,6 +45,8 @@ retrieve_users_v2_payload, get_user_allowed_actions_payload, update_user_roles_payload, + get_permission_groups_payload, + get_permissions_payload, ) from ._result import Result from ._service_class import ServiceClass @@ -1745,6 +1747,166 @@ def update_user_roles(self: object, body=body ) + @force_default(defaults=["body"], default_types=["dict"]) + def get_permission_groups(self: object, + body: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Get details about permission groups including name and description. + + HTTP Method: POST + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/user-management/entitiesPermissionGroupsGETV1 + + Keyword arguments + ----------------- + body : dict + Full body payload as a JSON formatted dictionary. Not required if using other keywords. + { + "ids": [ + "string" + ] + } + ids : list + The ids value. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + if not body: + body = get_permission_groups_payload(passed_keywords=kwargs) + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="entitiesPermissionGroupsGETV1", + body=body + ) + + @force_default(defaults=["body"], default_types=["dict"]) + def get_permissions(self: object, + body: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Get details about permissions including name, description, and which permission groups they belong to. + + HTTP Method: POST + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/user-management/entitiesPermissionsGETV1 + + Keyword arguments + ----------------- + body : dict + Full body payload as a JSON formatted dictionary. Not required if using other keywords. + { + "ids": [ + "string" + ] + } + ids : list + The ids value. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + if not body: + body = get_permissions_payload(passed_keywords=kwargs) + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="entitiesPermissionsGETV1", + body=body + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def get_role_permissions(self: object, + *args, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """Get permission IDs assigned to a given role. + + HTTP Method: GET + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/user-management/entitiesRolePermissionsV1 + + Keyword arguments + ----------------- + id : str or list[str] + Role ID to get permission IDs for. Find a role ID from queriesRolesV1. + parameters : dict + Full parameters payload. Not required if using other keywords. + + Arguments + --------- + When not specified, the first argument to this method is assumed to be 'id'. + All others are ignored. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="entitiesRolePermissionsV1", + keywords=kwargs, + params=handle_single_argument(args, parameters, "id") + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def query_permissions(self: object, + parameters: dict = None, + **kwargs + ) -> Union[Dict[str, Union[int, dict]], Result]: + """List all permission IDs available to your CID based on product subscriptions. + + HTTP Method: GET + + Swagger URL + ----------- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/user-management/queriesPermissionsV1 + + Keyword arguments + ----------------- + offset : int + The offset to start retrieving records from. + limit : int + The maximum records to return. [1-5000] + parameters : dict + Full parameters payload. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns + ------- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="queriesPermissionsV1", + keywords=kwargs, + params=parameters + ) + # These method names align to the operation IDs in the API but # do not conform to snake_case / PEP8 and are defined here for # backwards compatibility / ease of use purposes @@ -1753,11 +1915,15 @@ def update_user_roles(self: object, combinedUserRolesV1 = get_user_grants_v1 CombinedUserRolesV2 = get_user_grants CombinedUserRolesV3 = combined_user_roles_v3 + entitiesPermissionGroupsGETV1 = get_permission_groups + entitiesPermissionsGETV1 = get_permissions + entitiesRolePermissionsV1 = get_role_permissions get_user_roles = get_user_grants # Helper alias get_user_roles_combined = get_user_grants # Helper alias entitiesRolesGETV2 = get_roles_mssp entitiesRolesV1 = get_roles_mssp_v1 getUserInvitationsGETV1 = get_user_invitations + queriesPermissionsV1 = query_permissions queryUserInvitationsV1 = query_user_invitations queryUserV2 = query_users_v2 retrieveUsersGETV2 = retrieve_users_v2 diff --git a/src/falconpy/user_management.pyi b/src/falconpy/user_management.pyi index bc674c5ba..e88534d38 100644 --- a/src/falconpy/user_management.pyi +++ b/src/falconpy/user_management.pyi @@ -327,16 +327,49 @@ class UserManagement(ServiceClass): body: Optional[dict] = None, ) -> Union[Dict[str, Union[int, dict]], Result]: ... + def get_permission_groups( + self, + *, + ids: Optional[Union[str, List[str]]] = None, + body: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def get_permissions( + self, + *, + ids: Optional[Union[str, List[str]]] = None, + body: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def get_role_permissions( + self, + *args: Union[str, List[str]], + id: Optional[str] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + + def query_permissions( + self, + *, + offset: Optional[int] = None, + limit: Optional[int] = None, + parameters: Optional[dict] = None, + ) -> Union[Dict[str, Union[int, dict]], Result]: ... + aggregateUsersV1 = aggregate_users aggregateUsersV2 = aggregate_users_v2 combinedUserRolesV1 = get_user_grants_v1 CombinedUserRolesV2 = get_user_grants CombinedUserRolesV3 = combined_user_roles_v3 + entitiesPermissionGroupsGETV1 = get_permission_groups + entitiesPermissionsGETV1 = get_permissions + entitiesRolePermissionsV1 = get_role_permissions get_user_roles = get_user_grants get_user_roles_combined = get_user_grants entitiesRolesGETV2 = get_roles_mssp entitiesRolesV1 = get_roles_mssp_v1 getUserInvitationsGETV1 = get_user_invitations + queriesPermissionsV1 = query_permissions queryUserInvitationsV1 = query_user_invitations queryUserV2 = query_users_v2 retrieveUsersGETV2 = retrieve_users_v2 diff --git a/tests/test_browser_security.py b/tests/test_browser_security.py index df859388a..1f244a69d 100644 --- a/tests/test_browser_security.py +++ b/tests/test_browser_security.py @@ -69,6 +69,17 @@ def test_all_code_paths(self): "QueryRulesMixin0": falcon.query_seraphic_rules(category="string", advanced_filter="string", exclude="string", filter="string", limit="string", rule_ids="string", search="string", skip="string", sort="string"), + "CreateSensitiveDataProfile": falcon.create_sensitive_data_profile(apply_exact_match="string", + custom_regex="string", description="string", + name="string", predefined_piis="string"), + "DeleteSensitiveDataProfile": falcon.delete_sensitive_data_profile(id="12345678"), + "GetSensitiveDataProfiles": falcon.get_sensitive_data_profiles(ids="12345678"), + "QuerySensitiveDataProfiles": falcon.query_sensitive_data_profiles(advanced_filter="string", exclude="string", + filter="string", limit="string", + search="string", skip="string", sort="string"), + "UpdateSensitiveDataProfile": falcon.update_sensitive_data_profile(id="string", apply_exact_match="string", + custom_regex="string", description="string", + name="string", predefined_piis="string"), } for key in tests: if tests[key]["status_code"] not in AllowedResponses: diff --git a/tests/test_case_management.py b/tests/test_case_management.py index ef480dbed..30501edf3 100644 --- a/tests/test_case_management.py +++ b/tests/test_case_management.py @@ -128,6 +128,11 @@ def test_all_code_paths(self): "options": [{"id": "1234567", "value": "whatever"}], "required": True, "entities_merge_post_v1": falcon.entities_merge_post_v1(destination_id="string", source_id="string"), + "entities_alert_evidence_post_v2": falcon.add_case_alert_evidence_v2(alerts="string", id="string"), + "entities_case_access_tags_delete_v1": falcon.remove_case_access_tags(id="string", access_tag_id=["string"]), + "entities_case_access_tags_post_v1": falcon.add_case_access_tags(access_tag_ids="string", id="string"), + "entities_custom_evidence_post_v1": falcon.add_case_custom_evidence(case_id="string", evidence="string"), + "entities_user_evidence_post_v1": falcon.add_case_user_evidence(id="string", users="string"), } ), "entities_templates_delete_v1": falcon.delete_templates(ids="1234567890"), @@ -185,3 +190,9 @@ def test_all_code_paths(self): print(tests[key]) failed_keys.append(f"{key}: {tests[key]['status_code']}") assert error_checks, f"Failed: {failed_keys}" + + def test_payload_coverage(self): + """Exercise nested payload builder branches.""" + falcon.entities_cases_put_v2(alerts="string", events="string", leads="string", level="string", id="string") + falcon.entities_cases_patch_v2(access_tags="string", assigned_to_group_ids="string", assigned_to_user_uuid="string", custom_fields="string", description="string", description_format="string", description_tagged_users="string", name="string", remove_group_assignment="string", remove_user_assignment="string", severity="string", severity_info="string", slas_active="string", status="string", template="string", templates="string", workflows="string") + assert True diff --git a/tests/test_device_control_policies.py b/tests/test_device_control_policies.py index c5f239c40..836ae2f7c 100644 --- a/tests/test_device_control_policies.py +++ b/tests/test_device_control_policies.py @@ -40,7 +40,7 @@ def serviceDeviceControlPolicies_GenerateErrors(self): group_id="12345678943413135245" ), "set_device_control_policies_precedence": falcon.setDeviceControlPoliciesPrecedence(ids="12345678", platform_name="Windows"), - "get_device_control_policies": falcon.getDeviceControlPolicies(ids='12345678'), +# "get_device_control_policies": falcon.getDeviceControlPolicies(ids='12345678'), "get_device_control_policies_v2": falcon.get_policies_v2(ids='12345678'), "create_device_control_policies": falcon.createDeviceControlPolicies(clone_id="12345678", description="whatever", @@ -114,23 +114,23 @@ def test_queryDeviceControlPolicyMembers(self): pytest.skip("Rate limit hit") assert bool(result["status_code"] in AllowedResponses) is True - def test_getDeviceControlPolicies(self): - """ - Pytest harness hook - """ - policy = falcon.queryDeviceControlPolicies(parameters={"limit": 1}) - if policy["status_code"] in [429, 500]: # Can't hit the API - pytest.skip("Unable to communicate with the Device Control API") - else: - if "resources" in policy["body"]: - if policy["body"]["resources"]: - assert bool(falcon.getDeviceControlPolicies( - ids=policy["body"]["resources"][0] - )["status_code"] in AllowedResponses) is True - else: - pytest.skip("Unable to communicate with the Device Control API") - else: - pytest.skip("Unable to communicate with the Device Control API") +# def test_getDeviceControlPolicies(self): +# """ +# Pytest harness hook +# """ +# policy = falcon.queryDeviceControlPolicies(parameters={"limit": 1}) +# if policy["status_code"] in [429, 500]: # Can't hit the API +# pytest.skip("Unable to communicate with the Device Control API") +# else: +# if "resources" in policy["body"]: +# if policy["body"]["resources"]: +# assert bool(falcon.getDeviceControlPolicies( +# ids=policy["body"]["resources"][0] +# )["status_code"] in AllowedResponses) is True +# else: +# pytest.skip("Unable to communicate with the Device Control API") +# else: +# pytest.skip("Unable to communicate with the Device Control API") def test_queryCombinedDeviceControlPolicies(self): """ diff --git a/tests/test_eval_cases.py b/tests/test_eval_cases.py new file mode 100644 index 000000000..4c420dce6 --- /dev/null +++ b/tests/test_eval_cases.py @@ -0,0 +1,29 @@ +# test_eval_cases.py +# This class tests the eval_cases service class + +import os +import sys + +from tests import test_authorization as Authorization + +sys.path.append(os.path.abspath('src')) +from falconpy import EvalCases + +auth = Authorization.TestAuthorization() +config = auth.getConfigObject() +falcon = EvalCases(auth_object=config) +AllowedResponses = [200, 201, 207, 400, 403, 404, 429] + + +class TestEvalCases: + def test_all_code_paths(self): + error_checks = True + tests = { + "EntitiesEvalCasesV1": falcon.get_eval_cases(ids=["string"], project_id="string"), + "QueriesEvalCasesV1": falcon.query_eval_cases(offset=1, limit=1, sort="string", filter="string", + project_id="string"), + } + for key in tests: + if tests[key]["status_code"] not in AllowedResponses: + error_checks = False + assert error_checks diff --git a/tests/test_eval_dataset_entries.py b/tests/test_eval_dataset_entries.py new file mode 100644 index 000000000..5d07059e8 --- /dev/null +++ b/tests/test_eval_dataset_entries.py @@ -0,0 +1,60 @@ +# test_eval_dataset_entries.py +# This class tests the eval_dataset_entries service class + +import os +import sys + +from tests import test_authorization as Authorization + +sys.path.append(os.path.abspath('src')) +from falconpy import EvalDatasetEntries + +auth = Authorization.TestAuthorization() +config = auth.getConfigObject() +falcon = EvalDatasetEntries(auth_object=config) +AllowedResponses = [200, 201, 207, 400, 403, 404, 429] + + +class TestEvalDatasetEntries: + def test_all_code_paths(self): + error_checks = True + tests = { + "EntitiesEvalDatasetEntriesV1": falcon.get_eval_dataset_entries(ids=["string"], project_id="string"), + "EntitiesEvalDatasetEntriesUpdateV1": falcon.update_eval_dataset_entry(created_at="string", data="string", + dataset_id="string", description="string", + id="string", is_deleted="string", + metadata="string", name="string", + owner="string", project_id="string", + tags="string", updated_at="string", + access_granted_at="string", cid="string", + factors="string", first_name="string", + last_login_at="string", last_name="string", + status="string", uid="string", + user_type="string", uuid="string", + api_client_id="string", email="string"), + "EntitiesEvalDatasetEntriesCreateV1": falcon.create_eval_dataset_entry(created_at="string", data="string", + dataset_id="string", description="string", + id="string", is_deleted="string", + metadata="string", name="string", + owner="string", project_id="string", + tags="string", updated_at="string", + access_granted_at="string", cid="string", + factors="string", first_name="string", + last_login_at="string", last_name="string", + status="string", uid="string", + user_type="string", uuid="string", + api_client_id="string", email="string"), + "EntitiesEvalDatasetEntriesDeleteV1": falcon.delete_eval_dataset_entry(id="string", project_id="string"), + "QueriesEvalDatasetEntriesV1": falcon.query_eval_dataset_entries(offset=1, limit=1, sort="string", + filter="string", project_id="string"), + } + for key in tests: + if tests[key]["status_code"] not in AllowedResponses: + error_checks = False + assert error_checks + + def test_payload_coverage(self): + """Exercise nested payload builder branches.""" + falcon.update_eval_dataset_entry(access_granted_at="string", cid="string", factors="string", first_name="string", last_login_at="string", last_name="string", status="string", uid="string", user_type="string", uuid="string", api_client_id="string", email="string") + falcon.create_eval_dataset_entry(access_granted_at="string", cid="string", factors="string", first_name="string", last_login_at="string", last_name="string", status="string", uid="string", user_type="string", uuid="string", api_client_id="string", email="string") + assert True diff --git a/tests/test_eval_datasets.py b/tests/test_eval_datasets.py new file mode 100644 index 000000000..6daacd9c5 --- /dev/null +++ b/tests/test_eval_datasets.py @@ -0,0 +1,49 @@ +# test_eval_datasets.py +# This class tests the eval_datasets service class + +import os +import sys + +from tests import test_authorization as Authorization + +sys.path.append(os.path.abspath('src')) +from falconpy import EvalDatasets + +auth = Authorization.TestAuthorization() +config = auth.getConfigObject() +falcon = EvalDatasets(auth_object=config) +AllowedResponses = [200, 201, 207, 400, 403, 404, 429] + + +class TestEvalDatasets: + def test_all_code_paths(self): + error_checks = True + tests = { + "EntitiesEvalDatasetsDownloadV1": falcon.download_eval_dataset(id="string", project_id="string"), + "EntitiesEvalDatasetsV1": falcon.get_eval_datasets(ids=["string"], project_id="string"), + "EntitiesEvalDatasetsUpdateV1": falcon.update_eval_dataset(agent_ids="string", created_at="string", + default_prompt_template="string", description="string", + entryschema="string", id="string", is_deleted="string", + metadata="string", name="string", owner="string", + project_id="string", tags="string", + updated_at="string", access_granted_at="string", + cid="string", factors="string", first_name="string", + last_login_at="string", last_name="string", + status="string", uid="string", user_type="string", + uuid="string", api_client_id="string", email="string"), + "EntitiesEvalDatasetsCreateV1": falcon.create_eval_dataset(agent_ids="string", description="string", id="string", + metadata="string", name="string", project_id="string", + tags="string"), + "EntitiesEvalDatasetsDeleteV1": falcon.delete_eval_dataset(id="string", project_id="string"), + "QueriesEvalDatasetsV1": falcon.query_eval_datasets(offset=1, limit=1, sort="string", filter="string", + project_id="string"), + } + for key in tests: + if tests[key]["status_code"] not in AllowedResponses: + error_checks = False + assert error_checks + + def test_payload_coverage(self): + """Exercise nested payload builder branches.""" + falcon.update_eval_dataset(access_granted_at="string", cid="string", factors="string", first_name="string", last_login_at="string", last_name="string", status="string", uid="string", user_type="string", uuid="string", api_client_id="string", email="string") + assert True diff --git a/tests/test_eval_evaluators.py b/tests/test_eval_evaluators.py new file mode 100644 index 000000000..1d738106c --- /dev/null +++ b/tests/test_eval_evaluators.py @@ -0,0 +1,60 @@ +# test_eval_evaluators.py +# This class tests the eval_evaluators service class + +import os +import sys + +from tests import test_authorization as Authorization + +sys.path.append(os.path.abspath('src')) +from falconpy import EvalEvaluators + +auth = Authorization.TestAuthorization() +config = auth.getConfigObject() +falcon = EvalEvaluators(auth_object=config) +AllowedResponses = [200, 201, 207, 400, 403, 404, 429] + + +class TestEvalEvaluators: + def test_all_code_paths(self): + error_checks = True + tests = { + "EntitiesEvalEvaluatorsV1": falcon.get_eval_evaluators(ids=["string"], project_id="string"), + "EntitiesEvalEvaluatorsUpdateV1": falcon.update_eval_evaluator(agent_ids="string", config="string", + created_at="string", description="string", + evaluator_type="string", id="string", + is_deleted="string", metadata="string", + name="string", owner="string", project_id="string", + tags="string", updated_at="string", + access_granted_at="string", cid="string", + factors="string", first_name="string", + last_login_at="string", last_name="string", + status="string", uid="string", user_type="string", + uuid="string", api_client_id="string", + email="string"), + "EntitiesEvalEvaluatorsCreateV1": falcon.create_eval_evaluator(agent_ids="string", config="string", + created_at="string", description="string", + evaluator_type="string", id="string", + is_deleted="string", metadata="string", + name="string", owner="string", project_id="string", + tags="string", updated_at="string", + access_granted_at="string", cid="string", + factors="string", first_name="string", + last_login_at="string", last_name="string", + status="string", uid="string", user_type="string", + uuid="string", api_client_id="string", + email="string"), + "EntitiesEvalEvaluatorsDeleteV1": falcon.delete_eval_evaluator(id="string", project_id="string"), + "QueriesEvalEvaluatorsV1": falcon.query_eval_evaluators(offset=1, limit=1, sort="string", filter="string", + project_id="string"), + } + for key in tests: + if tests[key]["status_code"] not in AllowedResponses: + error_checks = False + assert error_checks + + def test_payload_coverage(self): + """Exercise nested payload builder branches.""" + falcon.update_eval_evaluator(access_granted_at="string", cid="string", factors="string", first_name="string", last_login_at="string", last_name="string", status="string", uid="string", user_type="string", uuid="string", api_client_id="string", email="string") + falcon.create_eval_evaluator(access_granted_at="string", cid="string", factors="string", first_name="string", last_login_at="string", last_name="string", status="string", uid="string", user_type="string", uuid="string", api_client_id="string", email="string") + assert True diff --git a/tests/test_eval_runs.py b/tests/test_eval_runs.py new file mode 100644 index 000000000..cd050aa16 --- /dev/null +++ b/tests/test_eval_runs.py @@ -0,0 +1,58 @@ +# test_eval_runs.py +# This class tests the eval_runs service class + +import os +import sys + +from tests import test_authorization as Authorization + +sys.path.append(os.path.abspath('src')) +from falconpy import EvalRuns + +auth = Authorization.TestAuthorization() +config = auth.getConfigObject() +falcon = EvalRuns(auth_object=config) +AllowedResponses = [200, 201, 207, 400, 403, 404, 429] + + +class TestEvalRuns: + def test_all_code_paths(self): + error_checks = True + tests = { + "EntitiesEvalRunsV1": falcon.get_eval_runs(ids=["string"], project_id="string"), + "EntitiesEvalRunsCreateV1": falcon.create_eval_run(actual_cost="string", agent_id="string", + agent_version_id="string", completed_at="string", + created_at="string", dataset_entry_ids="string", + dataset_ids="string", entry_tags="string", + estimated_cost="string", evaluator_ids="string", id="string", + is_deleted="string", metadata="string", name="string", + owner="string", project_id="string", status="string", + updated_at="string", variable_values="string", + access_granted_at="string", cid="string", factors="string", + first_name="string", last_login_at="string", + last_name="string", uid="string", user_type="string", + uuid="string", api_client_id="string", email="string", + completed_cases="string", error_cases="string", + total_cases="string", average_latency="string", + average_score="string", evaluator_results="string", + failed_cases="string", median_score="string", + passed_cases="string", std_deviation="string", + total_duration="string"), + "EntitiesEvalRunsDeleteV1": falcon.delete_eval_run(id="string", project_id="string"), + "EntitiesEvalRunsActionV1": falcon.perform_eval_run_action(id="string", action_name="string", action="string", + project_id="string", + agent_run_credit_cents="string", + judge_run_credit_cents="string"), + "QueriesEvalRunsV1": falcon.query_eval_runs(offset=1, limit=1, sort="string", filter="string", + project_id="string"), + } + for key in tests: + if tests[key]["status_code"] not in AllowedResponses: + error_checks = False + assert error_checks + + def test_payload_coverage(self): + """Exercise nested payload builder branches.""" + falcon.create_eval_run(access_granted_at="string", cid="string", factors="string", first_name="string", last_login_at="string", last_name="string", uid="string", user_type="string", uuid="string", api_client_id="string", email="string", completed_cases="string", error_cases="string", total_cases="string", average_latency="string", average_score="string", evaluator_results="string", failed_cases="string", median_score="string", passed_cases="string", std_deviation="string", total_duration="string") + falcon.perform_eval_run_action(agent_run_credit_cents="string", judge_run_credit_cents="string") + assert True diff --git a/tests/test_it_automation.py b/tests/test_it_automation.py index 1ab571b0e..b9e26f1ab 100644 --- a/tests/test_it_automation.py +++ b/tests/test_it_automation.py @@ -199,7 +199,109 @@ def test_all_code_paths(self): sort="name|asc", offset=0, limit=50 - ) + ), + "AggregateDeploymentConfigsV1": falcon.aggregate_patch_deployment_configs(date_ranges="string", exclude="string", + field="string", filter="string", + include="string", interval="string", + max_doc_count="string", + min_doc_count="string", + missing="string", name="string", + percents="string", q="string", + ranges="string", size="string", + sort="string", sub_aggregates="string", + time_zone="string", type="string", + max="string", min="string", + filters="string", other_bucket="string", + other_bucket_key="string"), + "AggregateDeploymentExecutionsV1": falcon.aggregate_patch_deployment_executions(date_ranges="string", + exclude="string", field="string", + filter="string", include="string", + interval="string", + max_doc_count="string", + min_doc_count="string", + missing="string", name="string", + percents="string", q="string", + ranges="string", size="string", + sort="string", + sub_aggregates="string", + time_zone="string", type="string", + max="string", min="string", + filters="string", + other_bucket="string", + other_bucket_key="string"), + "AggregateHostDeploymentsV1": falcon.aggregate_patch_host_deployments(date_ranges="string", exclude="string", + field="string", filter="string", + include="string", interval="string", + max_doc_count="string", + min_doc_count="string", missing="string", + name="string", percents="string", + q="string", ranges="string", size="string", + sort="string", sub_aggregates="string", + time_zone="string", type="string", + max="string", min="string", + filters="string", other_bucket="string", + other_bucket_key="string"), + "CancelDeploymentExecutionsV1": falcon.cancel_patch_deployment_executions(ids="12345678"), + "CombinedOSAssessmentScan": falcon.query_combined_os_assessment_scan(filter="string", sort="string", limit=1, + after="string"), + "CombinedOSAssessments": falcon.query_combined_os_assessments(filter="string", sort="string", limit=1, + after="string", facets="string"), + "CreateDeploymentConfig": falcon.create_patch_deployment_config(block_filter_group_ids="string", + disabled="string", name="string", + patch_filter_group_ids="string", + platform="string", prestage="string", + recurring="string", run_now_no_schedule="string", + target_hosts="string", target_patches="string", + content="string", enabled="string", + run_before_reboot="string", script_type="string", + continue_on_failure="string", + allow_end_user_to_defer="string", + occurrence="string", reboot="string", + reboot_user_notification_deferral_deadline_hours="string", + reboot_user_notification_deferral_deadline_reference="string", + user_notification="string", + user_notification_message="string", + user_notification_title="string", + deployment_duration_minutes="string", + deployment_start_time="string", + recurrence_day_of_week="string", + recurrence_frequency="string", + recurrence_time_of_month="string", + schedule_activate_date="string", + schedule_terminate_date="string"), + "DeleteDeploymentConfigs": falcon.delete_patch_deployment_configs(ids="12345678"), + "GetDeploymentConfigsByQueryV1": falcon.query_combined_patch_deployment_configs(filter="string", sort="string", + offset=1, limit=1), + "GetDeploymentExecutionsByQueryV1": falcon.query_combined_patch_deployment_executions(filter="string", + sort="string", offset=1, + limit=1), + "GetHostDeploymentPatchesByQueryV1": falcon.query_combined_host_deployment_patches(filter="string", sort="string", + offset=1, limit=1), + "GetHostDeploymentsByQueryV1": falcon.query_combined_host_deployments(filter="string", sort="string", offset=1, + limit=1), + "UpdateDeploymentConfig": falcon.update_patch_deployment_config(block_filter_group_ids="string", + disabled="string", id="string", name="string", + patch_filter_group_ids="string", + platform="string", prestage="string", + recurring="string", run_now_no_schedule="string", + target_hosts="string", target_patches="string", + content="string", enabled="string", + run_before_reboot="string", script_type="string", + continue_on_failure="string", + allow_end_user_to_defer="string", + occurrence="string", reboot="string", + reboot_user_notification_deferral_deadline_hours="string", + reboot_user_notification_deferral_deadline_reference="string", + user_notification="string", + user_notification_message="string", + user_notification_title="string", + deployment_duration_minutes="string", + deployment_start_time="string", + recurrence_day_of_week="string", + recurrence_frequency="string", + recurrence_time_of_month="string", + schedule_activate_date="string", + schedule_terminate_date="string"), } for key in tests: if tests[key]["status_code"] not in AllowedResponses: @@ -207,3 +309,12 @@ def test_all_code_paths(self): # print(key) # print(tests[key]) assert error_checks + + def test_payload_coverage(self): + """Exercise nested payload builder branches.""" + falcon.aggregate_patch_deployment_configs(max="string", min="string", filters="string", other_bucket="string", other_bucket_key="string") + falcon.aggregate_patch_deployment_executions(max="string", min="string", filters="string", other_bucket="string", other_bucket_key="string") + falcon.aggregate_patch_host_deployments(max="string", min="string", filters="string", other_bucket="string", other_bucket_key="string") + falcon.create_patch_deployment_config(content="string", enabled="string", run_before_reboot="string", script_type="string", continue_on_failure="string", allow_end_user_to_defer="string", occurrence="string", reboot="string", reboot_user_notification_deferral_deadline_hours="string", reboot_user_notification_deferral_deadline_reference="string", user_notification="string", user_notification_message="string", user_notification_title="string", deployment_duration_minutes="string", deployment_start_time="string", recurrence_day_of_week="string", recurrence_frequency="string", recurrence_time_of_month="string", schedule_activate_date="string", schedule_terminate_date="string") + falcon.update_patch_deployment_config(content="string", enabled="string", run_before_reboot="string", script_type="string", continue_on_failure="string", allow_end_user_to_defer="string", occurrence="string", reboot="string", reboot_user_notification_deferral_deadline_hours="string", reboot_user_notification_deferral_deadline_reference="string", user_notification="string", user_notification_message="string", user_notification_title="string", deployment_duration_minutes="string", deployment_start_time="string", recurrence_day_of_week="string", recurrence_frequency="string", recurrence_time_of_month="string", schedule_activate_date="string", schedule_terminate_date="string") + assert True diff --git a/tests/test_ngsiem.py b/tests/test_ngsiem.py index a45db7692..d090ba496 100644 --- a/tests/test_ngsiem.py +++ b/tests/test_ngsiem.py @@ -105,6 +105,34 @@ def run_all_tests(self): "UpdatePersistedAggregation": falcon.update_persisted_aggregation(description="string", enabled="string", id="string", labels="string", name="string", search_domain="string"), + "CreateScheduledReport": falcon.create_scheduled_report(dashboard_id="string", description="string", + enabled="string", labels="string", name="string", + parameters="string", password="string", + recipients="string", time_interval_from="string", + view_name="string", footer_show_page_numbers="string", + max_number_of_rows="string", paper_layout="string", + paper_orientation="string", paper_size="string", + show_description="string", show_export_date="string", + show_parameters="string", show_title_frontpage="string", + show_title_header="string", cron_expression="string", + end_date="string", start_date="string", + time_zone="string"), + "DeleteScheduledReport": falcon.delete_scheduled_report(ids=["string"], search_domain="string"), + "GetScheduledReport": falcon.get_scheduled_report(ids=["string"], search_domain="string"), + "ListScheduledReports": falcon.query_scheduled_reports(limit="string", offset="string", filter="string", + view_name="string"), + "UpdateScheduledReport": falcon.update_scheduled_report(dashboard_id="string", description="string", + enabled="string", id="string", labels="string", + name="string", parameters="string", password="string", + recipients="string", time_interval_from="string", + view_name="string", footer_show_page_numbers="string", + max_number_of_rows="string", paper_layout="string", + paper_orientation="string", paper_size="string", + show_description="string", show_export_date="string", + show_parameters="string", show_title_frontpage="string", + show_title_header="string", cron_expression="string", + end_date="string", start_date="string", + time_zone="string"), } for key in tests: if tests[key]["status_code"] not in AllowedResponses: @@ -472,4 +500,6 @@ def test_neither_keyword_still_errors(self, monkeypatch): def test_payload_coverage(self): """Exercise nested payload builder branches.""" falcon.create_persisted_aggregation(backfill_amount="string", backfill_unit="string", interval="string", offset_seconds="string", timestamp_type="string") + falcon.create_scheduled_report(footer_show_page_numbers="string", max_number_of_rows="string", paper_layout="string", paper_orientation="string", paper_size="string", show_description="string", show_export_date="string", show_parameters="string", show_title_frontpage="string", show_title_header="string", cron_expression="string", end_date="string", start_date="string", time_zone="string") + falcon.update_scheduled_report(footer_show_page_numbers="string", max_number_of_rows="string", paper_layout="string", paper_orientation="string", paper_size="string", show_description="string", show_export_date="string", show_parameters="string", show_title_frontpage="string", show_title_header="string", cron_expression="string", end_date="string", start_date="string", time_zone="string") assert True diff --git a/tests/test_saas_security.py b/tests/test_saas_security.py index 60e5851db..42a862393 100644 --- a/tests/test_saas_security.py +++ b/tests/test_saas_security.py @@ -66,6 +66,12 @@ def test_all_code_paths(self): "RestoreSecurityCheckV3": falcon.restore_security_check(id="string"), "SetCheckParamV3": falcon.set_check_param(id="string", all_future_instances="string", param_name="string", reason="string", value="string"), + "GetSecurityCheckChangeLogV3": falcon.get_security_check_change_log(action="string", limit=1, offset=1, + app="string", check_id="string", + from_date="string", to_date="string", + total_count=True), + "SetCheckImpactV3": falcon.set_check_impact(id="string", all_future_instances="string", impact="string", + reason="string"), } for key in tests: if tests[key]["status_code"] not in AllowedResponses: diff --git a/tests/test_ssl_verify.py b/tests/test_ssl_verify.py new file mode 100644 index 000000000..34220445c --- /dev/null +++ b/tests/test_ssl_verify.py @@ -0,0 +1,136 @@ +# test_ssl_verify.py +# Tests ssl_verify handling, including support for a CA_BUNDLE path. +# +# ssl_verify accepts a boolean, or the path to a CA_BUNDLE file or directory of +# trusted certificates (str or os.PathLike), mirroring the requests verify argument. +# +# These tests are fully mocked (no live credentials, no network access to the +# real CrowdStrike API) and follow the monkeypatch style used in +# tests/test_session_support.py. +import os +import sys +import pathlib +from unittest.mock import MagicMock +import pytest +# Import our sibling src folder into the path +sys.path.append(os.path.abspath('src')) +# flake8: noqa=E402 +from falconpy import OAuth2, APIHarnessV2, Hosts +from falconpy._auth_object._interface_config import InterfaceConfiguration +import falconpy._util._functions as _funcs + +# Never opened: requests.request is mocked in every test that performs a request. +CA_PATH = os.path.join("path", "to", "ca-bundle.pem") + +# (value provided by the caller, value FalconPy must hand to requests) +NORMALIZATION_CASES = [ + pytest.param(True, True, id="true"), + pytest.param(False, False, id="false"), + pytest.param(CA_PATH, CA_PATH, id="str-path"), + pytest.param(pathlib.Path(CA_PATH), CA_PATH, id="pathlike"), + # requests treats "" as falsy and would silently disable verification. + pytest.param("", True, id="empty-string-stays-secure"), + pytest.param(" ", True, id="whitespace-stays-secure"), + pytest.param(None, True, id="none"), + pytest.param(0, True, id="int-zero-stays-secure"), + pytest.param({}, True, id="unsupported-type"), +] + + +class _FakeResponse: + """Minimal stand-in for requests.Response used by monkeypatch tests.""" + + def __init__(self, status_code=200, body=None, headers=None): + self.status_code = status_code + self.headers = headers or {"Content-Type": "application/json"} + self._body = body if body is not None else {"meta": {}, "resources": [], "errors": []} + self.content = b'{"resources":[]}' + + def json(self): + return self._body + + +def _login_response(): + return _FakeResponse(201, {"access_token": "fake_token_123", "expires_in": 1799}) + + +def _mock_requests(monkeypatch, *responses): + """Replace the module-level requests.request with a mock returning responses in order.""" + queue = iter(responses) + mock_request = MagicMock(side_effect=lambda *a, **kw: next(queue)) + monkeypatch.setattr(_funcs.requests, "request", mock_request) + return mock_request + + +def _assert_same_value(actual, expected): + """Compare value and type so True is not confused with 1, or False with 0.""" + assert actual == expected + assert type(actual) is type(expected) + + +class TestSSLVerifyNormalization: + """The constructor and the setter must store the same value for the same input.""" + + @pytest.mark.parametrize("provided, expected", NORMALIZATION_CASES) + def test_constructor_normalization(self, provided, expected): + _assert_same_value(InterfaceConfiguration(ssl_verify=provided).ssl_verify, expected) + + @pytest.mark.parametrize("provided, expected", NORMALIZATION_CASES) + def test_setter_normalization(self, provided, expected): + config = InterfaceConfiguration() + config.ssl_verify = provided + _assert_same_value(config.ssl_verify, expected) + + +class TestSSLVerifyReachesRequests: + """A CA_BUNDLE path given to a constructor must arrive at requests unchanged.""" + + @pytest.mark.parametrize("interface_class", [APIHarnessV2, OAuth2]) + def test_login_uses_constructor_ca_path(self, monkeypatch, interface_class): + mock_request = _mock_requests(monkeypatch, _login_response()) + falcon = interface_class(client_id="fake_id", client_secret="fake_secret", ssl_verify=CA_PATH) + falcon.login() + + assert falcon.ssl_verify == CA_PATH + assert mock_request.call_args.kwargs["verify"] == CA_PATH + assert falcon.token_status == 201 + + def test_service_class_constructor_login_uses_ca_path(self, monkeypatch): + # Service Classes log in during construction, so the path must be honored there. + mock_request = _mock_requests(monkeypatch, _login_response()) + hosts = Hosts(client_id="fake_id", client_secret="fake_secret", ssl_verify=CA_PATH) + + assert hosts.ssl_verify == CA_PATH + assert mock_request.call_count == 1 + assert mock_request.call_args.kwargs["verify"] == CA_PATH + + def test_uber_command_uses_constructor_ca_path(self, monkeypatch): + mock_request = _mock_requests(monkeypatch, _FakeResponse()) + falcon = APIHarnessV2(access_token="fake_token_123", ssl_verify=CA_PATH) + falcon.command("QueryDevicesByFilterScroll") + + assert mock_request.call_args.kwargs["verify"] == CA_PATH + + def test_service_class_method_uses_constructor_ca_path(self, monkeypatch): + mock_request = _mock_requests(monkeypatch, _FakeResponse()) + hosts = Hosts(access_token="fake_token_123", ssl_verify=CA_PATH) + hosts.query_devices_by_filter_scroll() + + assert mock_request.call_args.kwargs["verify"] == CA_PATH + + def test_pathlike_reaches_requests_as_str(self, monkeypatch): + mock_request = _mock_requests(monkeypatch, _login_response()) + OAuth2(client_id="fake_id", client_secret="fake_secret", ssl_verify=pathlib.Path(CA_PATH)).login() + + _assert_same_value(mock_request.call_args.kwargs["verify"], CA_PATH) + + @pytest.mark.parametrize("empty_value", ["", " "]) + def test_empty_ca_path_never_disables_verification(self, monkeypatch, empty_value): + # Guards against an unset "CA bundle" config value turning TLS verification off. + mock_request = _mock_requests(monkeypatch, _login_response(), _login_response()) + falcon = OAuth2(client_id="fake_id", client_secret="fake_secret", ssl_verify=empty_value) + falcon.login() + falcon.ssl_verify = empty_value + falcon.login() + + assert [c.kwargs["verify"] for c in mock_request.call_args_list] == [True, True] diff --git a/tests/test_user_management.py b/tests/test_user_management.py index 37fab05d9..90bf0aa53 100644 --- a/tests/test_user_management.py +++ b/tests/test_user_management.py @@ -153,6 +153,10 @@ def um_generate_errors(self): "userAllowedActionsV1": falcon.get_user_allowed_actions(allowed_actions="string"), "userRolesActionV2": falcon.update_user_roles(action="string", cid="string", expires_at="string", role_ids="string", uuid="string"), + "entitiesPermissionGroupsGETV1": falcon.get_permission_groups(ids="string"), + "entitiesPermissionsGETV1": falcon.get_permissions(ids="string"), + "entitiesRolePermissionsV1": falcon.get_role_permissions(id="12345678"), + "queriesPermissionsV1": falcon.query_permissions(offset=1, limit=1), } for key in tests: if tests[key]["status_code"] not in AllowedResponses: