From 3bada0c9ff7638771fb7bcbc21d3103347e5a641 Mon Sep 17 00:00:00 2001 From: alhumaw Date: Thu, 18 Jul 2024 10:50:36 -0700 Subject: [PATCH 1/4] Added 3 new service collections, included testing and updated changelog --- CHANGELOG.md | 31 ++ src/falconpy/__init__.py | 6 +- src/falconpy/_endpoint/__init__.py | 10 + .../_certificate_based_exclusions.py | 171 ++++++ .../_endpoint/_compliance_assessments.py | 299 +++++++++++ src/falconpy/_endpoint/_datascanner.py | 80 +++ src/falconpy/_endpoint/deprecated/__init__.py | 4 + .../_certificate_based_exclusions.py | 171 ++++++ .../_endpoint/deprecated/_datascanner.py | 80 +++ src/falconpy/_payload/__init__.py | 3 +- .../_payload/_certificate_based_exclusions.py | 94 ++++ src/falconpy/certificate_based_exclusions.py | 279 ++++++++++ src/falconpy/compliance_assessments.py | 496 ++++++++++++++++++ src/falconpy/datascanner.py | 154 ++++++ tests/test_certificate_based_exclusions.py | 38 ++ tests/test_compliance_assessments.py | 43 ++ tests/test_datascanner.py | 35 ++ 17 files changed, 1992 insertions(+), 2 deletions(-) create mode 100644 src/falconpy/_endpoint/_certificate_based_exclusions.py create mode 100644 src/falconpy/_endpoint/_compliance_assessments.py create mode 100644 src/falconpy/_endpoint/_datascanner.py create mode 100644 src/falconpy/_endpoint/deprecated/_certificate_based_exclusions.py create mode 100644 src/falconpy/_endpoint/deprecated/_datascanner.py create mode 100644 src/falconpy/_payload/_certificate_based_exclusions.py create mode 100644 src/falconpy/certificate_based_exclusions.py create mode 100644 src/falconpy/compliance_assessments.py create mode 100644 src/falconpy/datascanner.py create mode 100644 tests/test_certificate_based_exclusions.py create mode 100644 tests/test_compliance_assessments.py create mode 100644 tests/test_datascanner.py diff --git a/CHANGELOG.md b/CHANGELOG.md index a8670ad42..54b8f30e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,34 @@ +# Version 1.4.5 +## Added features and functionality ++ Added: Added new __Certificate Based Exclusions__ service collection with six new operations. + - `__init__.py` + - `_endpoint/__init__.py` + - `_endpoint/_certificate_based_exclusions.py` + - `_endpoint/deprecated/_certificate_based_exclusions.py` + - `_payload/__init__.py` + - `_payload/_certificate_based_exclusions.py` + - `certificate_based_exclusions.py` + > Unit testing expanded to complete code coverage. + - `tests/test_certificate_based_exclusions.py` + ++ Added: Added new __Data Scanner__ service collection with 3 new operations. + - `__init__.py` + - `_endpoint/__init__.py` + - `_endpoint/_datascanner.py` + - `_endpoint/deprecated/_datascanner.py` + - `datascanner.py` + > Unit testing expanded to complete code coverage. + - `tests/test_datascanner.py` + + ++ Added: Added new __Compliance Assessments__ service collection with 11 new operations. + - `__init__.py` + - `_endpoint/__init__.py` + - `_endpoint/_compliance_assessments.py` + - `compliance_assessments.py` + > Unit testing expanded to complete code coverage. + - `tests/test_compliance_assessments.py` + # Version 1.4.4 ## Added features and functionality + Added: Added new __API Integrations__ service collection with two new operations, __GetCombinedPluginConfigs__ and __ExecuteCommand__. diff --git a/src/falconpy/__init__.py b/src/falconpy/__init__.py index 066336d0f..0de26b6dc 100644 --- a/src/falconpy/__init__.py +++ b/src/falconpy/__init__.py @@ -90,7 +90,9 @@ from .alerts import Alerts from .api_integrations import APIIntegrations from .api_complete import APIHarness, APIHarnessV2 +from .certificate_based_exclusions import CertificateBasedExclusions from .cloud_snapshots import CloudSnapshots +from .compliance_assessments import ComplianceAssessments from .configuration_assessment_evaluation_logic import ConfigurationAssessmentEvaluationLogic from .configuration_assessment import ConfigurationAssessment from .container_alerts import ContainerAlerts @@ -102,6 +104,7 @@ from .cspm_registration import CSPMRegistration from .custom_ioa import CustomIOA from .custom_storage import CustomStorage +from .datascanner import DataScanner from .d4c_registration import D4CRegistration from .detects import Detects from .device_control_policies import DeviceControlPolicies @@ -198,7 +201,8 @@ "SDKDeprecationWarning", "ConfigurationAssessmentEvaluationLogic", "ConfigurationAssessment", "ContainerAlerts", "ContainerDetections", "ContainerImages", "ContainerPackages", "ContainerVulnerabilities", "DriftIndicators", "UnidentifiedContainers", - "ImageAssessmentPolicies", "APIIntegrations", "ThreatGraph", "ExposureManagement" + "ImageAssessmentPolicies", "APIIntegrations", "ThreatGraph", "ExposureManagement", + "DataScanner", "CertificateBasedExclusions", "ComplianceAssessments" ] """ This is free and unencumbered software released into the public domain. diff --git a/src/falconpy/_endpoint/__init__.py b/src/falconpy/_endpoint/__init__.py index 45dad8fee..85fd3b906 100644 --- a/src/falconpy/_endpoint/__init__.py +++ b/src/falconpy/_endpoint/__init__.py @@ -36,13 +36,17 @@ from .deprecated import _report_executions_deprecated from .deprecated import _scheduled_reports_deprecated from .deprecated import _zero_trust_assessment_deprecated +from .deprecated import _certificate_based_exclusions_deprecated +from .deprecated import _datascanner_deprecated from .deprecated import _deprecated_operation_mapping from .deprecated import _deprecated_class_mapping from ._alerts import _alerts_endpoints from ._api_integrations import _api_integrations_endpoints +from ._certificate_based_exclusions import _certificate_based_exclusions_endpoints from ._cloud_connect_aws import _cloud_connect_aws_endpoints from ._cloud_snapshots import _cloud_snapshots_endpoints +from ._compliance_assessments import _complianceassessments_endpoints from ._configuration_assessment_evaluation_logic import _configuration_assessment_evaluation_logic_endpoints from ._configuration_assessment import _configuration_assessment_endpoints from ._container_alerts import _container_alerts_endpoints @@ -104,6 +108,7 @@ from ._spotlight_vulnerabilities import _spotlight_vulnerabilities_endpoints from ._tailored_intelligence import _tailored_intelligence_endpoints from ._threatgraph import _threatgraph_endpoints +from ._datascanner import _datascanner_endpoints from ._unidentified_containers import _unidentified_containers_endpoints from ._user_management import _user_management_endpoints from ._workflows import _workflows_endpoints @@ -112,8 +117,10 @@ api_endpoints: List[Any] = [] api_endpoints.extend(_alerts_endpoints) api_endpoints.extend(_api_integrations_endpoints) +api_endpoints.extend(_certificate_based_exclusions_endpoints) api_endpoints.extend(_cloud_connect_aws_endpoints) api_endpoints.extend(_cloud_snapshots_endpoints) +api_endpoints.extend(_complianceassessments_endpoints) api_endpoints.extend(_configuration_assessment_evaluation_logic_endpoints) api_endpoints.extend(_configuration_assessment_endpoints) api_endpoints.extend(_container_alerts_endpoints) @@ -124,6 +131,7 @@ api_endpoints.extend(_cspm_registration_endpoints) api_endpoints.extend(_custom_ioa_endpoints) api_endpoints.extend(_custom_storage_endpoints) +api_endpoints.extend(_datascanner_endpoints) api_endpoints.extend(_d4c_registration_endpoints) api_endpoints.extend(_detects_endpoints) api_endpoints.extend(_device_control_policies_endpoints) @@ -182,7 +190,9 @@ # Deprecated endpoints deprecated_endpoints = [] +deprecated_endpoints.extend(_certificate_based_exclusions_deprecated) deprecated_endpoints.extend(_custom_ioa_deprecated) +deprecated_endpoints.extend(_datascanner_deprecated) deprecated_endpoints.extend(_d4c_registration_deprecated) deprecated_endpoints.extend(_discover_deprecated) deprecated_endpoints.extend(_fdr_deprecated) diff --git a/src/falconpy/_endpoint/_certificate_based_exclusions.py b/src/falconpy/_endpoint/_certificate_based_exclusions.py new file mode 100644 index 000000000..81e03459d --- /dev/null +++ b/src/falconpy/_endpoint/_certificate_based_exclusions.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 +""" + +_certificate_based_exclusions_endpoints = [ + [ + "cb_exclusions_get_v1", + "GET", + "/exclusions/entities/cert-based-exclusions/v1", + "Find all exclusion IDs matching the query with filter", + "certificate_based_exclusions", + [ + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "description": "The ids of the exclusions to retrieve", + "name": "ids", + "in": "query", + "required": True + } + ] + ], + [ + "cb_exclusions_create_v1", + "POST", + "/exclusions/entities/cert-based-exclusions/v1", + "Create new Certificate Based Exclusions.", + "certificate_based_exclusions", + [ + { + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "cb_exclusions_update_v1", + "PATCH", + "/exclusions/entities/cert-based-exclusions/v1", + "Updates existing Certificate Based Exclusions", + "certificate_based_exclusions", + [ + { + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "cb_exclusions_delete_v1", + "DELETE", + "/exclusions/entities/cert-based-exclusions/v1", + "Delete the exclusions by id", + "certificate_based_exclusions", + [ + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "description": "The ids of the exclusions to delete", + "name": "ids", + "in": "query", + "required": True + }, + { + "type": "string", + "description": "The comment why these exclusions were deleted", + "name": "comment", + "in": "query" + } + ] + ], + [ + "certificates_get_v1", + "GET", + "/exclusions/entities/certificates/v1", + "Retrieves certificate signing information for a file", + "certificate_based_exclusions", + [ + { + "type": "string", + "description": "The SHA256 Hash of the file to retrieve certificate signing info for", + "name": "ids", + "in": "query", + "required": True + } + ] + ], + [ + "cb_exclusions_query_v1", + "GET", + "/exclusions/queries/cert-based-exclusions/v1", + "Search for cert-based exclusions.", + "certificate_based_exclusions", + [ + { + "type": "string", + "description": "The filter expression that should be used to limit the results.", + "name": "filter", + "in": "query" + }, + { + "type": "integer", + "description": "The offset to start retrieving records from", + "name": "offset", + "in": "query" + }, + { + "maximum": 100, + "type": "integer", + "description": "The maximum records to return. [1-100]", + "name": "limit", + "in": "query" + }, + { + "enum": [ + "created_by", + "created_on", + "modified_by", + "modified_on", + "name" + ], + "type": "string", + "description": "The sort expression that should be used to sort the results.", + "name": "sort", + "in": "query" + } + ] + ] +] diff --git a/src/falconpy/_endpoint/_compliance_assessments.py b/src/falconpy/_endpoint/_compliance_assessments.py new file mode 100644 index 000000000..44a808255 --- /dev/null +++ b/src/falconpy/_endpoint/_compliance_assessments.py @@ -0,0 +1,299 @@ +"""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 +""" + +_complianceassessments_endpoints = [ + [ + "extAggregateClusterAssessments", + "GET", + "/container-compliance/aggregates/compliance-by-clusters/v2", + "get the assessments for each cluster", + "complianceassessments", + [ + { + "type": "string", + "description": "Filter results using a query in Falcon Query Language (FQL). Supported " + "Filters:\ncloud_info.cluster_name: Kubernetes cluster name\ncloud_info.cloud_region: Cloud " + "region\ncompliance_finding.framework: Compliance finding framework (available values: " + "CIS)\ncloud_info.cloud_account_id: Cloud account ID\ncloud_info.namespace: Kubernetes namespace\ncid: Customer " + "ID\ncloud_info.cloud_provider: Cloud provider\n", + "name": "filter", + "in": "query" + } + ] + ], + [ + "extAggregateImageAssessments", + "GET", + "/container-compliance/aggregates/compliance-by-images/v2", + "get the assessments for each image", + "complianceassessments", + [ + { + "type": "string", + "description": "Filter results using a query in Falcon Query Language (FQL). Supported " + "Filters:\ncloud_info.cluster_name: Kubernetes cluster name\ncompliance_finding.id: Compliance finding " + "ID\nimage_digest: Image digest (sha256 digest)\nimage_registry: Image registry\nimage_tag: Image " + "tag\nimage_id: Image ID\ncloud_info.cloud_provider: Cloud provider\nasset_type: asset type (container, " + "image)\ncompliance_finding.severity: Compliance finding severity; available values: 4, 3, 2, 1 (4: critical, " + "3: high, 2: medium, 1:low)\ncompliance_finding.framework: Compliance finding framework (available values: " + "CIS)\nimage_repository: Image repository\ncloud_info.cloud_account_id: Cloud account ID\ncloud_info.namespace: " + " Kubernetes namespace\ncloud_info.cloud_region: Cloud region\ncompliance_finding.name: Compliance finding " + "Name\ncid: Customer ID\n", + "name": "filter", + "in": "query" + }, + { + "type": "string", + "description": "'after' value from the last response. Keep it empty for the first request.", + "name": "after", + "in": "query" + }, + { + "type": "string", + "description": "number of images to return in the response after 'after' key. Keep it empty for the " + "default number of 10000", + "name": "limit", + "in": "query" + } + ] + ], + [ + "extAggregateRulesAssessments", + "GET", + "/container-compliance/aggregates/compliance-by-rules/v2", + "get the assessments for each rule", + "complianceassessments", + [ + { + "type": "string", + "description": "Filter results using a query in Falcon Query Language (FQL). Supported " + "Filters:\nimage_registry: Image registry\nimage_repository: Image repository\ncompliance_finding.framework: " + "Compliance finding framework (available values: CIS)\ncloud_info.cloud_region: Cloud " + "region\ncloud_info.cloud_account_id: Cloud account ID\ncloud_info.cloud_provider: Cloud " + "provider\ncompliance_finding.id: Compliance finding ID\ncompliance_finding.severity: Compliance finding " + "severity; available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low)\ncloud_info.cluster_name: " + "Kubernetes cluster name\nimage_id: Image ID\nimage_tag: Image tag\ncompliance_finding.name: Compliance finding " + "Name\nimage_digest: Image digest (sha256 digest)\ncid: Customer ID\n", + "name": "filter", + "in": "query" + } + ] + ], + [ + "extAggregateFailedContainersByRulesPath", + "GET", + "/container-compliance/aggregates/failed-containers-by-rules/v2", + "get the containers grouped into rules on which they failed", + "complianceassessments", + [ + { + "type": "string", + "description": "Filter results using a query in Falcon Query Language (FQL). Supported " + "Filters:\ncloud_info.cloud_region: Cloud region\nimage_registry: Image registry\ncloud_info.cloud_account_id: " + "Cloud account ID\ncompliance_finding.name: Compliance finding Name\nimage_tag: Image " + "tag\ncloud_info.cluster_name: Kubernetes cluster name\ncompliance_finding.framework: Compliance finding " + "framework (available values: CIS)\ncloud_info.cloud_provider: Cloud provider\ncompliance_finding.id: " + "Compliance finding ID\ncompliance_finding.severity: Compliance finding severity; available values: 4, 3, 2, 1 " + "(4: critical, 3: high, 2: medium, 1:low)\ncid: Customer ID\nimage_id: Image ID\nimage_digest: Image digest " + "(sha256 digest)\ncloud_info.namespace: Kubernetes namespace\nimage_repository: Image repository\n", + "name": "filter", + "in": "query" + } + ] + ], + [ + "extAggregateFailedContainersCountBySeverity", + "GET", + "/container-compliance/aggregates/failed-containers-count-by-severity/v2", + "get the failed containers count grouped into severity levels", + "complianceassessments", + [ + { + "type": "string", + "description": "Filter results using a query in Falcon Query Language (FQL). Supported " + "Filters:\ncloud_info.namespace: Kubernetes namespace\ncloud_info.cloud_provider: Cloud " + "provider\ncompliance_finding.id: Compliance finding ID\nimage_registry: Image " + "registry\ncompliance_finding.name: Compliance finding Name\ncompliance_finding.severity: Compliance finding " + "severity; available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low)\ncloud_info.cluster_name: " + "Kubernetes cluster name\ncloud_info.cloud_account_id: Cloud account ID\nimage_id: Image ID\nimage_digest: " + "Image digest (sha256 digest)\nimage_repository: Image repository\nimage_tag: Image " + "tag\ncompliance_finding.framework: Compliance finding framework (available values: CIS)\ncid: Customer " + "ID\ncloud_info.cloud_region: Cloud region\n", + "name": "filter", + "in": "query" + } + ] + ], + [ + "extAggregateFailedImagesByRulesPath", + "GET", + "/container-compliance/aggregates/failed-images-by-rules/v2", + "get the images grouped into rules on which they failed", + "complianceassessments", + [ + { + "type": "string", + "description": "Filter results using a query in Falcon Query Language (FQL). Supported " + "Filters:\nimage_repository: Image repository\nimage_tag: Image tag\ncloud_info.cluster_name: Kubernetes " + "cluster name\ncloud_info.cloud_region: Cloud region\ncloud_info.cloud_account_id: Cloud account " + "ID\nimage_registry: Image registry\ncompliance_finding.name: Compliance finding " + "Name\ncompliance_finding.framework: Compliance finding framework (available values: " + "CIS)\ncloud_info.namespace: Kubernetes namespace\ncid: Customer ID\ncompliance_finding.severity: Compliance " + "finding severity; available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, " + "1:low)\ncloud_info.cloud_provider: Cloud provider\ncompliance_finding.id: Compliance finding ID\nimage_id: " + "Image ID\nimage_digest: Image digest (sha256 digest)\n", + "name": "filter", + "in": "query" + } + ] + ], + [ + "extAggregateFailedImagesCountBySeverity", + "GET", + "/container-compliance/aggregates/failed-images-count-by-severity/v2", + "get the failed images count grouped into severity levels", + "complianceassessments", + [ + { + "type": "string", + "description": "Filter results using a query in Falcon Query Language (FQL). Supported " + "Filters:\nimage_tag: Image tag\ncompliance_finding.name: Compliance finding Name\ncompliance_finding.severity: " + " Compliance finding severity; available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, " + "1:low)\ncloud_info.cloud_account_id: Cloud account ID\nimage_digest: Image digest (sha256 " + "digest)\nimage_registry: Image registry\nimage_id: Image ID\ncloud_info.namespace: Kubernetes " + "namespace\ncompliance_finding.framework: Compliance finding framework (available values: " + "CIS)\nimage_repository: Image repository\ncloud_info.cloud_provider: Cloud provider\ncid: Customer " + "ID\ncloud_info.cloud_region: Cloud region\ncloud_info.cluster_name: Kubernetes cluster " + "name\ncompliance_finding.id: Compliance finding ID\n", + "name": "filter", + "in": "query" + } + ] + ], + [ + "extAggregateFailedRulesByClusters", + "GET", + "/container-compliance/aggregates/failed-rules-by-clusters/v2", + "get the failed rules for each cluster grouped into severity levels", + "complianceassessments", + [ + { + "type": "string", + "description": "Filter results using a query in Falcon Query Language (FQL). Supported " + "Filters:\ncompliance_finding.name: Compliance finding Name\nimage_digest: Image digest (sha256 " + "digest)\nimage_tag: Image tag\ncloud_info.cloud_account_id: Cloud account ID\nimage_id: Image " + "ID\nimage_registry: Image registry\ncloud_info.cloud_region: Cloud region\nasset_type: asset type (container, " + "image)\ncompliance_finding.severity: Compliance finding severity; available values: 4, 3, 2, 1 (4: critical, " + "3: high, 2: medium, 1:low)\ncid: Customer ID\ncompliance_finding.id: Compliance finding " + "ID\ncompliance_finding.framework: Compliance finding framework (available values: " + "CIS)\ncloud_info.cluster_name: Kubernetes cluster name\nimage_repository: Image " + "repository\ncloud_info.cloud_provider: Cloud provider\n", + "name": "filter", + "in": "query" + } + ] + ], + [ + "extAggregateFailedRulesByImages", + "GET", + "/container-compliance/aggregates/failed-rules-by-images/v2", + "get images with failed rules, rule count grouped by severity for each image", + "complianceassessments", + [ + { + "type": "string", + "description": "Filter results using a query in Falcon Query Language (FQL). Supported " + "Filters:\ncompliance_finding.id: Compliance finding ID\nimage_tag: Image tag\ncloud_info.cluster_name: " + "Kubernetes cluster name\nimage_registry: Image registry\ncloud_info.cloud_provider: Cloud " + "provider\ncompliance_finding.name: Compliance finding Name\ncid: Customer ID\ncloud_info.cloud_region: Cloud " + "region\ncloud_info.cloud_account_id: Cloud account ID\nasset_type: asset type (container, " + "image)\ncompliance_finding.severity: Compliance finding severity; available values: 4, 3, 2, 1 (4: critical, " + "3: high, 2: medium, 1:low)\nimage_id: Image ID\nimage_digest: Image digest (sha256 " + "digest)\ncompliance_finding.framework: Compliance finding framework (available values: CIS)\nimage_repository: " + "Image repository\ncloud_info.namespace: Kubernetes namespace\n", + "name": "filter", + "in": "query" + } + ] + ], + [ + "extAggregateFailedRulesCountBySeverity", + "GET", + "/container-compliance/aggregates/failed-rules-count-by-severity/v2", + "get the failed rules count grouped into severity levels", + "complianceassessments", + [ + { + "type": "string", + "description": "Filter results using a query in Falcon Query Language (FQL). Supported Filters:\ncid: " + "Customer ID\ncloud_info.cloud_region: Cloud region\ncompliance_finding.id: Compliance finding ID\nimage_id: " + "Image ID\nimage_tag: Image tag\nimage_digest: Image digest (sha256 digest)\ncompliance_finding.framework: " + "Compliance finding framework (available values: CIS)\nimage_repository: Image " + "repository\ncloud_info.cloud_account_id: Cloud account ID\ncompliance_finding.severity: Compliance finding " + "severity; available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low)\nasset_type: asset type " + "(container, image)\ncloud_info.cluster_name: Kubernetes cluster name\ncloud_info.cloud_provider: Cloud " + "provider\nimage_registry: Image registry\ncompliance_finding.name: Compliance finding Name\n", + "name": "filter", + "in": "query" + } + ] + ], + [ + "extAggregateRulesByStatus", + "GET", + "/container-compliance/aggregates/rules-by-status/v2", + "get the rules grouped by their statuses", + "complianceassessments", + [ + { + "type": "string", + "description": "Filter results using a query in Falcon Query Language (FQL). Supported " + "Filters:\ncompliance_finding.id: Compliance finding ID\nimage_tag: Image tag\ncompliance_finding.name: " + "Compliance finding Name\nasset_type: asset type (container, image)\ncompliance_finding.severity: Compliance " + "finding severity; available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low)\ncid: Customer " + "ID\ncontainer_name: Container name\ncloud_info.cluster_name: Kubernetes cluster name\nimage_repository: Image " + "repository\ncloud_info.cloud_provider: Cloud provider\nimage_registry: Image " + "registry\ncompliance_finding.framework: Compliance finding framework (available values: " + "CIS)\ncloud_info.cloud_region: Cloud region\ncloud_info.cloud_account_id: Cloud account ID\nimage_id: Image " + "ID\nimage_digest: Image digest (sha256 digest)\ncontainer_id: Container ID\n", + "name": "filter", + "in": "query" + } + ] + ] +] diff --git a/src/falconpy/_endpoint/_datascanner.py b/src/falconpy/_endpoint/_datascanner.py new file mode 100644 index 000000000..fb55c41d4 --- /dev/null +++ b/src/falconpy/_endpoint/_datascanner.py @@ -0,0 +1,80 @@ +"""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 +""" + +_datascanner_endpoints = [ + [ + "get_image_registry_credentials", + "GET", + "/data-security-dspm/entities/image-registry-credentials/v1", + "", + "datascanner", + [] + ], + [ + "get_data_scanner_tasks", + "GET", + "/data-security-dspm/entities/scanner-tasks/v1", + "", + "datascanner", + [ + { + "type": "string", + "description": "ID of the data scanner", + "name": "X-Scanner-Id", + "in": "header", + "required": True + } + ] + ], + [ + "update_data_scanner_tasks", + "PATCH", + "/data-security-dspm/entities/scanner-tasks/v1", + "", + "datascanner", + [ + { + "type": "string", + "description": "ID of the data scanner", + "name": "X-Scanner-Id", + "in": "header", + "required": True + } + ] + ] +] diff --git a/src/falconpy/_endpoint/deprecated/__init__.py b/src/falconpy/_endpoint/deprecated/__init__.py index 82d7c9bf7..7c7ec56a8 100644 --- a/src/falconpy/_endpoint/deprecated/__init__.py +++ b/src/falconpy/_endpoint/deprecated/__init__.py @@ -49,6 +49,8 @@ from ._scheduled_reports import _scheduled_reports_endpoints from ._zero_trust_assessment import _zero_trust_assessment_endpoints from ._mapping import _deprecated_op_mapping, _deprecated_cls_mapping +from ._certificate_based_exclusions import _certificate_based_exclusions_endpoints +from ._datascanner import _datascanner_endpoints _custom_ioa_deprecated = _custom_ioa_endpoints _d4c_registration_deprecated = _d4c_registration_endpoints @@ -67,5 +69,7 @@ _report_executions_deprecated = _report_executions_endpoints _scheduled_reports_deprecated = _scheduled_reports_endpoints _zero_trust_assessment_deprecated = _zero_trust_assessment_endpoints +_certificate_based_exclusions_deprecated = _certificate_based_exclusions_endpoints +_datascanner_deprecated = _datascanner_endpoints _deprecated_operation_mapping = _deprecated_op_mapping _deprecated_class_mapping = _deprecated_cls_mapping diff --git a/src/falconpy/_endpoint/deprecated/_certificate_based_exclusions.py b/src/falconpy/_endpoint/deprecated/_certificate_based_exclusions.py new file mode 100644 index 000000000..b32a10a31 --- /dev/null +++ b/src/falconpy/_endpoint/deprecated/_certificate_based_exclusions.py @@ -0,0 +1,171 @@ +"""Internal API endpoint constant library (deprecated operations). + + _______ __ _______ __ __ __ +| _ .----.-----.--.--.--.--| | _ | |_.----|__| |--.-----. +|. 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 +""" + +_certificate_based_exclusions_endpoints = [ + [ + "cb-exclusions.get.v1", + "GET", + "/exclusions/entities/cert-based-exclusions/v1", + "Find all exclusion IDs matching the query with filter", + "certificate_based_exclusions", + [ + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "description": "The ids of the exclusions to retrieve", + "name": "ids", + "in": "query", + "required": True + } + ] + ], + [ + "cb-exclusions.create.v1", + "POST", + "/exclusions/entities/cert-based-exclusions/v1", + "Create new Certificate Based Exclusions.", + "certificate_based_exclusions", + [ + { + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "cb-exclusions.update.v1", + "PATCH", + "/exclusions/entities/cert-based-exclusions/v1", + "Updates existing Certificate Based Exclusions", + "certificate_based_exclusions", + [ + { + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "cb-exclusions.delete.v1", + "DELETE", + "/exclusions/entities/cert-based-exclusions/v1", + "Delete the exclusions by id", + "certificate_based_exclusions", + [ + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "description": "The ids of the exclusions to delete", + "name": "ids", + "in": "query", + "required": True + }, + { + "type": "string", + "description": "The comment why these exclusions were deleted", + "name": "comment", + "in": "query" + } + ] + ], + [ + "certificates.get.v1", + "GET", + "/exclusions/entities/certificates/v1", + "Retrieves certificate signing information for a file", + "certificate_based_exclusions", + [ + { + "type": "string", + "description": "The SHA256 Hash of the file to retrieve certificate signing info for", + "name": "ids", + "in": "query", + "required": True + } + ] + ], + [ + "cb-exclusions.query.v1", + "GET", + "/exclusions/queries/cert-based-exclusions/v1", + "Search for cert-based exclusions.", + "certificate_based_exclusions", + [ + { + "type": "string", + "description": "The filter expression that should be used to limit the results.", + "name": "filter", + "in": "query" + }, + { + "type": "integer", + "description": "The offset to start retrieving records from", + "name": "offset", + "in": "query" + }, + { + "maximum": 100, + "type": "integer", + "description": "The maximum records to return. [1-100]", + "name": "limit", + "in": "query" + }, + { + "enum": [ + "created_by", + "created_on", + "modified_by", + "modified_on", + "name" + ], + "type": "string", + "description": "The sort expression that should be used to sort the results.", + "name": "sort", + "in": "query" + } + ] + ] +] diff --git a/src/falconpy/_endpoint/deprecated/_datascanner.py b/src/falconpy/_endpoint/deprecated/_datascanner.py new file mode 100644 index 000000000..e6a1c4786 --- /dev/null +++ b/src/falconpy/_endpoint/deprecated/_datascanner.py @@ -0,0 +1,80 @@ +"""Internal API endpoint constant library (deprecated operations). + + _______ __ _______ __ __ __ +| _ .----.-----.--.--.--.--| | _ | |_.----|__| |--.-----. +|. 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 +""" + +_datascanner_endpoints = [ + [ + "get-image-registry-credentials", + "GET", + "/data-security-dspm/entities/image-registry-credentials/v1", + "", + "datascanner", + [] + ], + [ + "get-data-scanner-tasks", + "GET", + "/data-security-dspm/entities/scanner-tasks/v1", + "", + "datascanner", + [ + { + "type": "string", + "description": "ID of the data scanner", + "name": "X-Scanner-Id", + "in": "header", + "required": True + } + ] + ], + [ + "update-data-scanner-tasks", + "PATCH", + "/data-security-dspm/entities/scanner-tasks/v1", + "", + "datascanner", + [ + { + "type": "string", + "description": "ID of the data scanner", + "name": "X-Scanner-Id", + "in": "header", + "required": True + } + ] + ] +] diff --git a/src/falconpy/_payload/__init__.py b/src/falconpy/_payload/__init__.py index 6ec88e10f..bd0b67b4f 100644 --- a/src/falconpy/_payload/__init__.py +++ b/src/falconpy/_payload/__init__.py @@ -53,6 +53,7 @@ from ._sensor_update_policy import sensor_policy_payload from ._response_policy import response_policy_payload from ._real_time_response import command_payload, data_payload +from ._certificate_based_exclusions import certificate_based_exclusions_payload from ._cloud_connect_aws import aws_registration_payload from ._ioc import indicator_payload, indicator_update_payload, indicator_report_payload from ._d4c_registration import ( @@ -130,5 +131,5 @@ "image_policy_payload", "image_exclusions_payload", "image_group_payload", "workflow_definition_payload", "workflow_human_input", "workflow_mock_payload", "cspm_service_account_validate_payload", "api_plugin_command_payload", "mobile_enrollment_payload", - "filevantage_start_payload", "fem_asset_payload" + "filevantage_start_payload", "fem_asset_payload", "certificate_based_exclusions_payload" ] diff --git a/src/falconpy/_payload/_certificate_based_exclusions.py b/src/falconpy/_payload/_certificate_based_exclusions.py new file mode 100644 index 000000000..393c1582a --- /dev/null +++ b/src/falconpy/_payload/_certificate_based_exclusions.py @@ -0,0 +1,94 @@ +"""Internal payload handling library - Certificate Based Exclusions. + + _______ __ _______ __ __ __ +| _ .----.-----.--.--.--.--| | _ | |_.----|__| |--.-----. +|. 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, List, Union + + +def certificate_based_exclusions_payload(passed_keywords: dict) -> Dict[str, List[Dict[str, Union[str, int]]]]: + """Create a properly formatted payload for exclusion creatio + { + "resources": [ + { + "applied_globally": true, + "certificate": { + "issuer": "string", + "serial": "string", + "subject": "string", + "thumbprint": "string", + "valid_from": "2024-07-17T16:55:01.502Z", + "valid_to": "2024-07-17T16:55:01.502Z" + }, + "children_cids": [ + "string" + ], + "comment": "string", + "created_by": "string", + "created_on": "2024-07-17T16:55:01.502Z", + "description": "string", + "host_groups": [ + "string" + ], + "modified_by": "string", + "modified_on": "2024-07-17T16:55:01.502Z", + "name": "string", + "status": "string" + } + ] + } + """ + returned = { + "resources": [] + } + item = {} + keys = [ + "applied_globally", "certificate", "children_cids", "comment", "created_by", "created_on", + "description", "host_groups", "modified_by", "modified_on", "name", "status", + ] + certificate_keys = [ + "issuer", "serial", "subject", "thumbprint", "valid_from", "valid_to" + ] + for key in keys: + if passed_keywords.get(key, None): + if key in certificate_keys: + if "certificate" not in item: + item["certificate"] = {} + item["certificate"][key] = passed_keywords.get(key, None) + else: + item[key] = passed_keywords.get(key, None) + returned["resources"].append(item) + + return returned diff --git a/src/falconpy/certificate_based_exclusions.py b/src/falconpy/certificate_based_exclusions.py new file mode 100644 index 000000000..63d480f45 --- /dev/null +++ b/src/falconpy/certificate_based_exclusions.py @@ -0,0 +1,279 @@ +"""CrowdStrike Falcon Certificate Based Exclusions 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, handle_single_argument +from ._service_class import ServiceClass +from ._payload import certificate_based_exclusions_payload +from ._endpoint._certificate_based_exclusions import _certificate_based_exclusions_endpoints as Endpoints + + +class CertificateBasedExclusions(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_exclusions(self: object, *args, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: + """Find all exclusion IDs matching the query with filter + + Keyword arguments: + ids -- One or more exclusion IDs . String or list of strings. + parameters - full parameters payload, not required if ids is provided as a keyword. + + Arguments: When not specified, the first argument to this method is assumed to be 'ids'. + All others are ignored. + + Returns: dict object containing API response. + + HTTP Method: GET + + Swagger URL + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/certificate-based-exclusions/cb-exclusions.get.v1 + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="cb_exclusions_get_v1", + keywords=kwargs, + params=handle_single_argument(args, parameters, "ids") + ) + + @force_default(defaults=["body"], default_types=["dict"]) + def create_exclusions(self: object, body: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: + """Create new Certificate Based Exclusions. + + Keyword arguments: + body -- full body payload, not required if using other keywords. + { + "resources": [ + { + "applied_globally": true, + "certificate": { + "issuer": "string", + "serial": "string", + "subject": "string", + "thumbprint": "string", + "valid_from": "2024-07-17T16:55:01.502Z", + "valid_to": "2024-07-17T16:55:01.502Z" + }, + "children_cids": [ + "string" + ], + "comment": "string", + "created_by": "string", + "created_on": "2024-07-17T16:55:01.502Z", + "description": "string", + "host_groups": [ + "string" + ], + "modified_by": "string", + "modified_on": "2024-07-17T16:55:01.502Z", + "name": "string", + "status": "string" + } + ] + } + + Returns: dict object containing API response. + + HTTP Method: POST + + Swagger URL + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/certificate-based-exclusions/cb-exclusions.create.v1 + """ + if not body: + body = certificate_based_exclusions_payload(passed_keywords=kwargs) + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="cb_exclusions_create_v1", + body=body + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def delete_exclusions(self: object, *args, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: + """Delete a set of exclusions by specifying their IDs. + + Keyword arguments: + ids -- List of exclusion IDs to delete. String or list of strings. + parameters -- full parameters payload, not required if ids is provided as a keyword. + comment - The comment why these exclusions were deleted. String. + + Arguments: When not specified, the first argument to this method is assumed to be 'ids'. + All others are ignored. + + Returns: dict object containing API response. + + HTTP Method: DELETE + + Swagger URL + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/certificate-based-exclusions/cb-exclusions.delete.v1 + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="cb_exclusions_delete_v1", + keywords=kwargs, + params=handle_single_argument(args, parameters, "ids") + ) + + @force_default(defaults=["body"], default_types=["dict"]) + def update_exclusions(self: object, body: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: + """Update Certificate Based Exclusions. + + Keyword arguments: + body -- full body payload, not required if using other keywords. + { + "resources": [ + { + "applied_globally": true, + "certificate": { + "issuer": "string", + "serial": "string", + "subject": "string", + "thumbprint": "string", + "valid_from": "2024-07-17T16:55:01.502Z", + "valid_to": "2024-07-17T16:55:01.502Z" + }, + "children_cids": [ + "string" + ], + "comment": "string", + "created_by": "string", + "created_on": "2024-07-17T16:55:01.502Z", + "description": "string", + "host_groups": [ + "string" + ], + "modified_by": "string", + "modified_on": "2024-07-17T16:55:01.502Z", + "name": "string", + "status": "string" + } + ] + } + + Returns: dict object containing API response. + + HTTP Method: PATCH + + Swagger URL + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/certificate-based-exclusions/cb-exclusions.update.v1 + """ + if not body: + body = certificate_based_exclusions_payload(passed_keywords=kwargs) + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="cb_exclusions_update_v1", + body=body + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def get_certificates(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: + """Retrieve vulnerability and package related info for this customer. + + Keyword arguments: + ids - The SHA256 Hash of the file to retrieve certificate signing info for. String. + parameters -- Full parameters payload dictionary. Not required if using other keywords. + + This method only supports keywords for providing arguments. + + Returns: dict object containing API response. + + HTTP Method: GET + + Swagger URL + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/certificate-based-exclusions/certificates.get.v1 + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="certificates_get_v1", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def query_certificates(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: + """Search for cert-based exclusions. + + Keyword arguments: + filter -- The filter expression that should be used to limit the results. FQL syntax. + limit -- The maximum records to return. [1-500]. Defaults to 100. + Use with the offset parameter to manage pagination of results. + offset -- The offset to start retrieving records from. Integer. + Use with the limit parameter to manage pagination of results. + parameters - full parameters payload, not required if using other keywords. + sort -- The property to sort by (e.g. alias.desc or state.asc). FQL syntax. + + This method only supports keywords for providing arguments. + + Returns: dict object containing API response. + + HTTP Method: GET + + Swagger URL + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/certificate-based-exclusions/cb-exclusions.query.v1 + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="cb_exclusions_query_v1", + 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 + cb_exclusions_get_v1 = get_exclusions + cb_exclusions_create_v1 = create_exclusions + cb_exclusions_delete_v1 = delete_exclusions + cb_exclusions_update_v1 = update_exclusions + certificates_get_v1 = get_certificates + cb_exclusions_query_v1 = query_certificates diff --git a/src/falconpy/compliance_assessments.py b/src/falconpy/compliance_assessments.py new file mode 100644 index 000000000..a1aae1a32 --- /dev/null +++ b/src/falconpy/compliance_assessments.py @@ -0,0 +1,496 @@ +"""CrowdStrike Falcon Certificate Based Exclusions 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 ._service_class import ServiceClass +from ._endpoint._compliance_assessments import _complianceassessments_endpoints as Endpoints + + +class ComplianceAssessments(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 aggregate_cluster_assessments(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: + """Get the assessments for each cluster. + + Keyword arguments: + filter -- Filter results using a query in Falcon Query Language (FQL). String. + Supported filters: + cloud_info.cluster_name: Kubernetes cluster name, + cloud_info.cloud_region: Cloud region, + compliance_finding.framework: Compliance finding framework (available values: CIS), + cloud_info.cloud_account_id: Cloud account ID, + cloud_info.namespace: Kubernetes namespace, + cid: Customer ID cloud_info.cloud_provider: Cloud provider + + This method only supports keywords for providing arguments. + + Returns: dict object containing API response. + + HTTP Method: GET + + Swagger URL + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/complianceAssessments/extAggregateClusterAssessments + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="extAggregateClusterAssessments", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def aggregate_image_assessments(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: + """Get the assessments for each cluster. + + Keyword arguments: + filter -- Filter results using a query in Falcon Query Language (FQL). String. + Supported filters: + cloud_info.cluster_name: Kubernetes cluster name + compliance_finding.id: Compliance finding ID + image_digest: Image digest (sha256 digest) + image_registry: Image registry + image_tag: Image tag + image_id: Image ID + cloud_info.cloud_provider: Cloud provider + asset_type: asset type (container image) + compliance_finding.severity: Compliance finding severity; available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) + compliance_finding.framework: Compliance finding framework (available values: CIS) + image_repository: Image repository + cloud_info.cloud_account_id: Cloud account ID + cloud_info.namespace: Kubernetes namespace + cloud_info.cloud_region: Cloud region + compliance_finding.name: Compliance finding Name + cid: Customer ID + after -- 'after' value from the last response. Keep it empty for the first request. String. + limit -- number of images to return in the response after 'after' key. + Keep it empty for the default number of 10000. String. + + This method only supports keywords for providing arguments. + + Returns: dict object containing API response. + + HTTP Method: GET + + Swagger URL + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/complianceAssessments/extAggregateImageAssessments + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="extAggregateImageAssessments", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def aggregate_rules_assessments(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: + """Get the assessments for each rule. + + Keyword arguments: + filter -- "Filter results using a query in Falcon Query Language (FQL). Supported Filters: + image_registry: Image registry + image_repository: Image repository + compliance_finding.framework: Compliance finding framework (available values: CIS) + cloud_info.cloud_region: Cloud region + cloud_info.cloud_account_id: Cloud account ID + cloud_info.cloud_provider: Cloud provider + compliance_finding.id: Compliance finding ID + compliance_finding.severity: Compliance finding severity; available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) + cloud_info.cluster_name: Kubernetes cluster name + image_id: Image ID + image_tag: Image tag + compliance_finding.name: Compliance finding Name + image_digest: Image digest (sha256 digest) + cid: Customer ID + + This method only supports keywords for providing arguments. + + Returns: dict object containing API response. + + HTTP Method: GET + + Swagger URL + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/complianceAssessments/extAggregateRulesAssessments + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="extAggregateRulesAssessments", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def aggregate_failed_containers_by_rules(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: + """get the containers grouped into rules on which they failed + + Keyword arguments: + filter -- "Filter results using a query in Falcon Query Language (FQL). Supported Filters: + cloud_info.cloud_region: Cloud region + image_registry: Image registry + cloud_info.cloud_account_id: Cloud account ID + compliance_finding.name: Compliance finding Name + image_tag: Image tag + cloud_info.cluster_name: Kubernetes cluster name + compliance_finding.framework: Compliance finding framework (available values: CIS) + cloud_info.cloud_provider: Cloud provider + compliance_finding.id: Compliance finding ID + compliance_finding.severity: Compliance finding severity; available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) + cid: Customer ID + image_id: Image ID + image_digest: Image digest (sha256 digest) + cloud_info.namespace: Kubernetes namespace + image_repository: Image repository + + This method only supports keywords for providing arguments. + + Returns: dict object containing API response. + + HTTP Method: GET + + Swagger URL + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/complianceAssessments/extAggregateFailedContainersByRulesPath + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="extAggregateFailedContainersByRulesPath", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def aggregate_failed_containers_count_by_severity(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: + """Get the failed containers count grouped into severity levels + + Keyword arguments: + filter -- "Filter results using a query in Falcon Query Language (FQL). Supported Filters: + cloud_info.namespace: Kubernetes namespace + cloud_info.cloud_provider: Cloud provider + compliance_finding.id: Compliance finding ID + image_registry: Image registry + compliance_finding.name: Compliance finding Name + compliance_finding.severity: Compliance finding severity; available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) + cloud_info.cluster_name: Kubernetes cluster name + cloud_info.cloud_account_id: Cloud account ID + image_id: Image ID + image_digest: Image digest (sha256 digest) + image_repository: Image repository + image_tag: Image tag + compliance_finding.framework: Compliance finding framework (available values: CIS) + cid: Customer ID + cloud_info.cloud_region: Cloud region + + This method only supports keywords for providing arguments. + + Returns: dict object containing API response. + + HTTP Method: GET + + Swagger URL + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/complianceAssessments/extAggregateFailedContainersCountBySeverity + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="extAggregateFailedContainersCountBySeverity", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def aggregate_failed_images_by_rules(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: + """get the images grouped into rules on which they failed + + Keyword arguments: + filter -- "Filter results using a query in Falcon Query Language (FQL). Supported Filters: + image_repository: Image repository + image_tag: Image tag + cloud_info.cluster_name: Kubernetes cluster name + cloud_info.cloud_region: Cloud region + cloud_info.cloud_account_id: Cloud account ID + image_registry: Image registry + compliance_finding.name: Compliance finding Name + compliance_finding.framework: Compliance finding framework (available values: CIS) + cloud_info.namespace: Kubernetes namespace + cid: Customer ID + compliance_finding.severity: Compliance finding severity; available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) + cloud_info.cloud_provider: Cloud provider + compliance_finding.id: Compliance finding ID + image_id: Image ID + image_digest: Image digest (sha256 digest) + + This method only supports keywords for providing arguments. + + Returns: dict object containing API response. + + HTTP Method: GET + + Swagger URL + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/complianceAssessments/extAggregateFailedImagesByRulesPath + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="extAggregateFailedImagesByRulesPath", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def aggregate_failed_images_count_by_severity(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: + """Get the failed images count grouped into severity levels + + Keyword arguments: + filter -- "Filter results using a query in Falcon Query Language (FQL). Supported Filters: + image_tag: Image tag + compliance_finding.name: Compliance finding Name + compliance_finding.severity: Compliance finding severity; available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) + cloud_info.cloud_account_id: Cloud account ID + image_digest: Image digest (sha256 digest) + image_registry: Image registry + image_id: Image ID + cloud_info.namespace: Kubernetes namespace + compliance_finding.framework: Compliance finding framework (available values: CIS) + image_repository: Image repository + cloud_info.cloud_provider: Cloud provider + cid: Customer ID + cloud_info.cloud_region: Cloud region + cloud_info.cluster_name: Kubernetes cluster name + compliance_finding.id: Compliance finding ID + + This method only supports keywords for providing arguments. + + Returns: dict object containing API response. + + HTTP Method: GET + + Swagger URL + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/complianceAssessments/extAggregateFailedImagesCountBySeverity + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="extAggregateFailedImagesCountBySeverity", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def aggregate_failed_rules_by_clusters(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: + """Get the failed rules for each cluster grouped into severity levels. + + Keyword arguments: + filter -- "Filter results using a query in Falcon Query Language (FQL). Supported Filters: + compliance_finding.name: Compliance finding Name + image_digest: Image digest (sha256 digest) + image_tag: Image tag + cloud_info.cloud_account_id: Cloud account ID + image_id: Image ID + image_registry: Image registry + cloud_info.cloud_region: Cloud region + asset_type: asset type (container, image) + compliance_finding.severity: Compliance finding severity; available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) + cid: Customer ID + compliance_finding.id: Compliance finding ID + compliance_finding.framework: Compliance finding framework (available values: CIS) + cloud_info.cluster_name: Kubernetes cluster name + image_repository: Image repository + cloud_info.cloud_provider: Cloud provider + + This method only supports keywords for providing arguments. + + Returns: dict object containing API response. + + HTTP Method: GET + + Swagger URL + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/complianceAssessments/extAggregateFailedRulesByClusters + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="extAggregateFailedRulesByClusters", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def aggregate_failed_rules_by_image(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: + """Get images with failed rules, rule count grouped by severity for each image. + + Keyword arguments: + filter -- "Filter results using a query in Falcon Query Language (FQL). Supported Filters: + compliance_finding.id: Compliance finding ID + image_tag: Image tag + cloud_info.cluster_name: Kubernetes cluster name + image_registry: Image registry + cloud_info.cloud_provider: Cloud provider + compliance_finding.name: Compliance finding Name + cid: Customer ID + cloud_info.cloud_region: Cloud region + cloud_info.cloud_account_id: Cloud account ID + asset_type: asset type (container, image) + compliance_finding.severity: Compliance finding severity; available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) + image_id: Image ID + image_digest: Image digest (sha256 digest) + compliance_finding.framework: Compliance finding framework (available values: CIS) + image_repository: Image repository + cloud_info.namespace: Kubernetes namespace + + This method only supports keywords for providing arguments. + + Returns: dict object containing API response. + + HTTP Method: GET + + Swagger URL + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/complianceAssessments/extAggregateFailedRulesByImages + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="extAggregateFailedRulesByImages", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def aggregate_failed_rules_count_by_severity(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: + """Get the failed rules count grouped into severity levels. + + Keyword arguments: + filter -- "Filter results using a query in Falcon Query Language (FQL). Supported Filters: + cid: Customer ID + cloud_info.cloud_region: Cloud region + compliance_finding.id: Compliance finding ID + image_id: Image ID + image_tag: Image tag + image_digest: Image digest (sha256 digest) + compliance_finding.framework: Compliance finding framework (available values: CIS) + image_repository: Image repository + cloud_info.cloud_account_id: Cloud account ID + compliance_finding.severity: Compliance finding severity; available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) + asset_type: asset type (container, image) + cloud_info.cluster_name: Kubernetes cluster name + cloud_info.cloud_provider: Cloud provider + image_registry: Image registry + compliance_finding.name: Compliance finding Name + + This method only supports keywords for providing arguments. + + Returns: dict object containing API response. + + HTTP Method: GET + + Swagger URL + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/complianceAssessments/extAggregateFailedRulesCountBySeverity + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="extAggregateFailedRulesCountBySeverity", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def aggregate_rules_by_status(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: + """Get the rules grouped by their statuses. + + Keyword arguments: + filter -- "Filter results using a query in Falcon Query Language (FQL). Supported Filters: + compliance_finding.id: Compliance finding ID + image_tag: Image tag + compliance_finding.name: Compliance finding Name + asset_type: asset type (container, image) + compliance_finding.severity: Compliance finding severity; available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) + cid: Customer ID + container_name: Container name + cloud_info.cluster_name: Kubernetes cluster name + image_repository: Image repository + cloud_info.cloud_provider: Cloud provider + image_registry: Image registry + compliance_finding.framework: Compliance finding framework (available values: CIS) + cloud_info.cloud_region: Cloud region + cloud_info.cloud_account_id: Cloud account ID + image_id: Image ID + image_digest: Image digest (sha256 digest) + container_id: Container ID + + This method only supports keywords for providing arguments. + + Returns: dict object containing API response. + + HTTP Method: GET + + Swagger URL + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/complianceAssessments/extAggregateRulesByStatus + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="extAggregateRulesByStatus", + 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 + extAggregateClusterAssessments = aggregate_cluster_assessments + extAggregateImageAssessments = aggregate_image_assessments + extAggregateRulesAssessments = aggregate_rules_assessments + extAggregateFailedContainersByRulesPath = aggregate_failed_containers_by_rules + extAggregateFailedContainersCountBySeverity = aggregate_failed_containers_count_by_severity + extAggregateFailedImagesByRulesPath = aggregate_failed_images_by_rules + extAggregateFailedImagesCountBySeverity = aggregate_failed_images_count_by_severity + extAggregateFailedRulesByClusters = aggregate_failed_rules_by_clusters + extAggregateFailedRulesByImages = aggregate_failed_rules_by_image + extAggregateFailedRulesCountBySeverity = aggregate_failed_rules_count_by_severity + extAggregateRulesByStatus = aggregate_rules_by_status diff --git a/src/falconpy/datascanner.py b/src/falconpy/datascanner.py new file mode 100644 index 000000000..d3905f83c --- /dev/null +++ b/src/falconpy/datascanner.py @@ -0,0 +1,154 @@ +"""CrowdStrike Falcon Datascanner 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 ._service_class import ServiceClass +from ._endpoint._datascanner import _datascanner_endpoints as Endpoints + + +class DataScanner(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_image_registry_credentials(self: object) -> Dict[str, Union[int, dict]]: + """Retrieve the registry credentials. + + HTTP Method: GET + + Swagger URL + ---- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/datascanner/get-image-registry-credentials + + Keyword arguments + ---- + This method does not accept keyword arguments. + + Arguments + ---- + This method does not accept arguments. + + Returns + ---- + dict + Dictionary object containing API response. + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="get_image_registry_credentials", + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def get_data_scanner_tasks(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: + """Retrieve data scanner tasks identified by the id. + + HTTP Method: GET + + Swagger URL + ---- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/datascanner/get-data-scanner-tasks + + Keyword arguments + ---- + X-Scanner-Id : str (required) + id of the data scanner. + + 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="get_data_scanner_tasks", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def update_data_scanner_tasks(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: + """Update data scanner tasks, as identified by the X-Scanner-Id. + + HTTP Method: PATCH + + Swagger URL + ---- + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/datascanner/update-data-scanner-tasks + + Keyword arguments + ---- + X-Scanner-Id : str + ID of the data scanner + X-Machine-Id : str + Provider ID of the machine + + 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="update_data_scanner_tasks", + 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 + get_image_registry_credentials = get_image_registry_credentials + get_data_scanner_tasks = get_data_scanner_tasks + update_data_scanner_tasks = update_data_scanner_tasks diff --git a/tests/test_certificate_based_exclusions.py b/tests/test_certificate_based_exclusions.py new file mode 100644 index 000000000..184c80d3e --- /dev/null +++ b/tests/test_certificate_based_exclusions.py @@ -0,0 +1,38 @@ +# test_certificate_based_exclusions.py +# This class tests the CertificateBasedExclusions service class + +# import json +import os +import sys + +# Authentication via the test_authorization.py +from tests import test_authorization as Authorization + +# Classes to test - manually imported from sibling folder +from falconpy import CertificateBasedExclusions +# Import our sibling src folder into the path +sys.path.append(os.path.abspath('src')) + +auth = Authorization.TestAuthorization() +config = auth.getConfigObject() +falcon = CertificateBasedExclusions(auth_object=config) +AllowedResponses = [200, 201, 207, 400, 404, 429, 500] + + +class TestCertificateBasedExclusions: + def test_all_code_paths(self): + error_checks = True + tests = { + "get_exclusions": falcon.get_exclusions(ids="1234567"), + "create_exclusions": falcon.create_exclusions("12345678"), + "delete_exclusions": falcon.delete_exclusions(ids="1234567"), + "update_exclusions": falcon.update_exclusions("exclusion_here"), + "get_certificates": falcon.get_certificates(ids="1234567"), + "query_certificates": falcon.query_certificates() + } + for key in tests: + if tests[key]["status_code"] not in AllowedResponses: + error_checks = False + # print(key) + # print(tests[key]) + assert error_checks diff --git a/tests/test_compliance_assessments.py b/tests/test_compliance_assessments.py new file mode 100644 index 000000000..22b5687b5 --- /dev/null +++ b/tests/test_compliance_assessments.py @@ -0,0 +1,43 @@ +# test_certificate_based_exclusions.py +# This class tests the CertificateBasedExclusions service class + +# import json +import os +import sys + +# Authentication via the test_authorization.py +from tests import test_authorization as Authorization + +# Classes to test - manually imported from sibling folder +from falconpy import ComplianceAssessments +# Import our sibling src folder into the path +sys.path.append(os.path.abspath('src')) + +auth = Authorization.TestAuthorization() +config = auth.getConfigObject() +falcon = ComplianceAssessments(auth_object=config) +AllowedResponses = [200, 201, 207, 400, 404, 429, 500] + + +class TestCertificateBasedExclusions: + def test_all_code_paths(self): + error_checks = True + tests = { + "aggregate_cluster_assessments": falcon.aggregate_cluster_assessments(), + "aggregate_image_assessments": falcon.aggregate_image_assessments(), + "aggregate_rules_assessments": falcon.aggregate_rules_assessments(filter="compliance_finding.severity: '4'"), + "aggregate_failed_containers_by_rules": falcon.aggregate_failed_containers_by_rules(), + "aggregate_failed_containers_count_by_severity": falcon.aggregate_failed_containers_count_by_severity(), + "aggregate_failed_images_by_rules": falcon.aggregate_failed_images_by_rules(), + "aggregate_failed_images_count_by_severity": falcon.aggregate_failed_images_count_by_severity(), + "aggregate_failed_rules_by_clusters": falcon.aggregate_failed_rules_by_clusters(), + "aggregate_failed_rules_by_image": falcon.aggregate_failed_rules_by_image(), + "aggregate_failed_rules_count_by_severity": falcon.aggregate_failed_rules_count_by_severity(), + "aggregate_rules_by_status": falcon.aggregate_rules_by_status() + } + for key in tests: + if tests[key]["status_code"] not in AllowedResponses: + error_checks = False + # print(key) + # print(tests[key]) + assert error_checks diff --git a/tests/test_datascanner.py b/tests/test_datascanner.py new file mode 100644 index 000000000..39d0e2292 --- /dev/null +++ b/tests/test_datascanner.py @@ -0,0 +1,35 @@ +# test_certificate_based_exclusions.py +# This class tests the CertificateBasedExclusions service class + +# import json +import os +import sys + +# Authentication via the test_authorization.py +from tests import test_authorization as Authorization + +# Classes to test - manually imported from sibling folder +from falconpy import DataScanner +# Import our sibling src folder into the path +sys.path.append(os.path.abspath('src')) + +auth = Authorization.TestAuthorization() +config = auth.getConfigObject() +falcon = DataScanner(auth_object=config) +AllowedResponses = [200, 201, 207, 400, 404, 429, 500] + + +class TestDataScanner: + def test_all_code_paths(self): + error_checks = True + tests = { + "get_image_registry_credentials": falcon.get_image_registry_credentials(), + "get_data_scanner_tasks": falcon.get_data_scanner_tasks(), + "update_data_scanner_tasks": falcon.update_data_scanner_tasks() + } + for key in tests: + if tests[key]["status_code"] not in AllowedResponses: + error_checks = False + # print(key) + # print(tests[key]) + assert error_checks From aed6d584e3f32c04991108137be4ba09416286fe Mon Sep 17 00:00:00 2001 From: alhumaw Date: Fri, 19 Jul 2024 16:36:29 -0700 Subject: [PATCH 2/4] integrated host_migration service collection, updated changelog, fixed certificate_based _exclusions --- CHANGELOG.md | 8 + src/falconpy/__init__.py | 3 +- src/falconpy/_endpoint/__init__.py | 2 + src/falconpy/_endpoint/_host_migration.py | 327 +++++++++ src/falconpy/_payload/__init__.py | 2 +- .../_payload/_certificate_based_exclusions.py | 22 +- src/falconpy/host_migration.py | 655 ++++++++++++++++++ tests/test_host_migration.py | 59 ++ 8 files changed, 1069 insertions(+), 9 deletions(-) create mode 100644 src/falconpy/_endpoint/_host_migration.py create mode 100644 src/falconpy/host_migration.py create mode 100644 tests/test_host_migration.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 54b8f30e3..e5e1ae865 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Version 1.4.5 ## Added features and functionality ++ Added: Added new __Host Migration__ service collection with 10 new operations. + - `__init__.py` + - `_endpoint/__init__.py` + - `_endpoint/_host_migration.py` + - `host_migration.py` + > Unit testing expanded to complete code coverage. + - `tests/test_host_migration.py` + + Added: Added new __Certificate Based Exclusions__ service collection with six new operations. - `__init__.py` - `_endpoint/__init__.py` diff --git a/src/falconpy/__init__.py b/src/falconpy/__init__.py index 0de26b6dc..9934d34da 100644 --- a/src/falconpy/__init__.py +++ b/src/falconpy/__init__.py @@ -122,6 +122,7 @@ from .foundry_logscale import FoundryLogScale from .host_group import HostGroup from .hosts import Hosts +from .host_migration import HostMigration from .identity_protection import IdentityProtection from .image_assessment_policies import ImageAssessmentPolicies from .incidents import Incidents @@ -202,7 +203,7 @@ "ContainerAlerts", "ContainerDetections", "ContainerImages", "ContainerPackages", "ContainerVulnerabilities", "DriftIndicators", "UnidentifiedContainers", "ImageAssessmentPolicies", "APIIntegrations", "ThreatGraph", "ExposureManagement", - "DataScanner", "CertificateBasedExclusions", "ComplianceAssessments" + "DataScanner", "CertificateBasedExclusions", "ComplianceAssessments", "HostMigration" ] """ This is free and unencumbered software released into the public domain. diff --git a/src/falconpy/_endpoint/__init__.py b/src/falconpy/_endpoint/__init__.py index 85fd3b906..d8fb97ee5 100644 --- a/src/falconpy/_endpoint/__init__.py +++ b/src/falconpy/_endpoint/__init__.py @@ -73,6 +73,7 @@ from ._foundry_logscale import _foundry_logscale_endpoints from ._host_group import _host_group_endpoints from ._hosts import _hosts_endpoints +from ._host_migration import _host_migration_endpoints from ._identity_protection import _identity_protection_endpoints from ._image_assessment_policies import _image_assessment_policies_endpoints from ._incidents import _incidents_endpoints @@ -148,6 +149,7 @@ api_endpoints.extend(_foundry_logscale_endpoints) api_endpoints.extend(_host_group_endpoints) api_endpoints.extend(_hosts_endpoints) +api_endpoints.extend(_host_migration_endpoints) api_endpoints.extend(_identity_protection_endpoints) api_endpoints.extend(_image_assessment_policies_endpoints) api_endpoints.extend(_incidents_endpoints) diff --git a/src/falconpy/_endpoint/_host_migration.py b/src/falconpy/_endpoint/_host_migration.py new file mode 100644 index 000000000..7e9de151e --- /dev/null +++ b/src/falconpy/_endpoint/_host_migration.py @@ -0,0 +1,327 @@ +"""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 +""" + +_host_migration_endpoints = [ + [ + "HostMigrationAggregatesV1", + "POST", + "/host-migration/aggregates/host-migrations/v1", + "Get host migration aggregates as specified via json in request body.", + "host_migration", + [ + { + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "MigrationAggregatesV1", + "POST", + "/host-migration/aggregates/migrations/v1", + "Get migration aggregates as specified via json in request body.", + "host_migration", + [ + { + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "HostMigrationsActionsV1", + "POST", + "/host-migration/entities/host-migrations-actions/v1", + "Perform an action on host migrations.", + "host_migration", + [ + { + "type": "string", + "description": "The migration job to perform actions on", + "name": "id", + "in": "query", + "required": True + }, + { + "enum": [ + "remove_hosts", + "remove_host_groups", + "add_host_groups" + ], + "type": "string", + "description": "The action to perform", + "name": "action_name", + "in": "query", + "required": True + }, + { + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "GetHostMigrationsV1", + "POST", + "/host-migration/entities/host-migrations/GET/v1", + "Get host migration details.", + "host_migration", + [ + { + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "GetMigrationDestinationsV1", + "POST", + "/host-migration/entities/migration-destinations/GET/v1", + "Get destinations for a migration.", + "host_migration", + [ + { + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "MigrationsActionsV1", + "POST", + "/host-migration/entities/migrations-actions/v1", + "Perform an action on a migration job.", + "host_migration", + [ + { + "enum": [ + "delete_migration", + "rename_migration", + "start_migration", + "cancel_migration" + ], + "type": "string", + "description": "The action to perform", + "name": "action_name", + "in": "query", + "required": True + }, + { + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "GetMigrationsV1", + "GET", + "/host-migration/entities/migrations/v1", + "Get migration job details.", + "host_migration", + [ + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "description": "The migration jobs of interest.", + "name": "ids", + "in": "query", + "required": True + } + ] + ], + [ + "CreateMigrationV1", + "POST", + "/host-migration/entities/migrations/v1", + "Create a device migration job.", + "host_migration", + [ + { + "name": "body", + "in": "body", + "required": True + } + ] + ], + [ + "GetHostMigrationIDsV1", + "GET", + "/host-migration/queries/host-migrations/v1", + "Query host migration IDs.", + "host_migration", + [ + { + "type": "string", + "description": "The migration job to query", + "name": "id", + "in": "query", + "required": True + }, + { + "type": "integer", + "description": "The offset to start retrieving records from", + "name": "offset", + "in": "query" + }, + { + "type": "integer", + "description": "The maximum records to return. [1-10000]", + "name": "limit", + "in": "query" + }, + { + "enum": [ + "hostname|asc", + "hostname|desc", + "hostname", + "status|asc", + "status|desc", + "status", + "migration_id|asc", + "migration_id|desc", + "migration_id", + "created_time|asc", + "created_time|desc", + "created_time", + "host_migration_id|asc", + "host_migration_id|desc", + "host_migration_id", + "groups|asc", + "groups|desc", + "groups", + "hostgroups|asc", + "hostgroups|desc", + "hostgroups", + "source_cid|asc", + "source_cid|desc", + "source_cid", + "id|asc", + "id|desc", + "id", + "static_host_groups|asc", + "static_host_groups|desc", + "static_host_groups", + "target_cid|asc", + "target_cid|desc", + "target_cid" + ], + "type": "string", + "description": "The property to sort by.", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "description": "The filter expression that should be used to limit the results. Valid fields: " + "host_migration_id, groups, hostgroups, hostname, status, migration_id, created_time, static_host_groups, " + "target_cid, source_cid, id", + "name": "filter", + "in": "query" + } + ] + ], + [ + "GetMigrationIDsV1", + "GET", + "/host-migration/queries/migrations/v1", + "Query migration jobs.", + "host_migration", + [ + { + "type": "integer", + "description": "The offset to start retrieving records from", + "name": "offset", + "in": "query" + }, + { + "type": "integer", + "description": "The maximum records to return. [1-10000]", + "name": "limit", + "in": "query" + }, + { + "enum": [ + "target_cid|asc", + "target_cid|desc", + "target_cid", + "status|asc", + "status|desc", + "status", + "migration_status|asc", + "migration_status|desc", + "migration_status", + "created_by|asc", + "created_by|desc", + "created_by", + "created_time|asc", + "created_time|desc", + "created_time", + "name|asc", + "name|desc", + "name", + "id|asc", + "id|desc", + "id", + "migration_id|asc", + "migration_id|desc", + "migration_id" + ], + "type": "string", + "description": "The property to sort by.", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "description": "The filter expression that should be used to limit the results. Valid fields: " + "target_cid, status, migration_status, created_by, created_time, name, id, migration_id", + "name": "filter", + "in": "query" + } + ] + ] +] diff --git a/src/falconpy/_payload/__init__.py b/src/falconpy/_payload/__init__.py index bd0b67b4f..0f7510c03 100644 --- a/src/falconpy/_payload/__init__.py +++ b/src/falconpy/_payload/__init__.py @@ -131,5 +131,5 @@ "image_policy_payload", "image_exclusions_payload", "image_group_payload", "workflow_definition_payload", "workflow_human_input", "workflow_mock_payload", "cspm_service_account_validate_payload", "api_plugin_command_payload", "mobile_enrollment_payload", - "filevantage_start_payload", "fem_asset_payload", "certificate_based_exclusions_payload" + "filevantage_start_payload", "fem_asset_payload", "certificate_based_exclusions_payload", ] diff --git a/src/falconpy/_payload/_certificate_based_exclusions.py b/src/falconpy/_payload/_certificate_based_exclusions.py index 393c1582a..b9933b0f5 100644 --- a/src/falconpy/_payload/_certificate_based_exclusions.py +++ b/src/falconpy/_payload/_certificate_based_exclusions.py @@ -75,20 +75,28 @@ def certificate_based_exclusions_payload(passed_keywords: dict) -> Dict[str, Lis } item = {} keys = [ - "applied_globally", "certificate", "children_cids", "comment", "created_by", "created_on", - "description", "host_groups", "modified_by", "modified_on", "name", "status", + "applied_globally", "certificate", "comment", "created_by", "created_on", + "description", "modified_by", "modified_on", "name", "status", ] certificate_keys = [ "issuer", "serial", "subject", "thumbprint", "valid_from", "valid_to" ] + list_keys = ["children_cids", "host_groups"] for key in keys: if passed_keywords.get(key, None): - if key in certificate_keys: - if "certificate" not in item: - item["certificate"] = {} - item["certificate"][key] = passed_keywords.get(key, None) + if key == "certificate": + item["certificate"] = {} + for cert_key in certificate_keys: + item["certificate"][cert_key] = passed_keywords.get(cert_key, None) else: item[key] = passed_keywords.get(key, None) - returned["resources"].append(item) + for key in list_keys: + if passed_keywords.get(key, None): + provided = passed_keywords.get(key, None) + if isinstance(provided, str): + provided = provided.split(",") + item[key] = provided + + returned["resources"].append(item) return returned diff --git a/src/falconpy/host_migration.py b/src/falconpy/host_migration.py new file mode 100644 index 000000000..ea7c2d3b3 --- /dev/null +++ b/src/falconpy/host_migration.py @@ -0,0 +1,655 @@ +"""CrowdStrike Falcon Certificate Based Exclusions 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, generate_error_result, handle_single_argument +from ._service_class import ServiceClass +from ._endpoint._host_migration import _host_migration_endpoints as Endpoints +from ._payload import generic_payload_list, aggregate_payload + + +class HostMigration(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=["body"], default_types=["list"]) + def aggregate_host_migration(self: object, body: list = None, **kwargs) -> Dict[str, Union[int, dict]]: + """Get host migration aggregates as specified via json in request body. + + Keyword arguments: + body -- full body payload, not required if using other keywords. + { + "resources": [ + { + "date_ranges": [ + { + "from": "string", + "to": "string" + } + ], + "exclude": "string", + "extended_bounds": { + "max": "string", + "min": "string" + }, + "field": "string", + "filter": "string", + "from": 0, + "include": "string", + "interval": "string", + "max_doc_count": 0, + "min_doc_count": 0, + "missing": "string", + "name": "string", + "q": "string", + "ranges": [ + { + "From": 0, + "To": 0 + } + ], + "size": 0, + "sort": "string", + "sub_aggregates": [ + null + ], + "time_zone": "string", + "type": "string" + } + ] + } + + Supported Types: + Both types support the following FQL filter properties: + groups, hostgroups, static_host_groups, hostname, status, + target_cid, source_cid, migration_id, id, host_migration_id, created_time. + The values groups and hostgroups are aliases for static_host_groups. + The value host_migration_id is an alias for id + + Type 1 - Terms + "type": "terms" + Supported field values: + groups, hostgroups, static_host_groups, hostname, + status, target_cid, source_cid, migration_id, id, host_migration_id. + sort must be done on the same value as field and include a direction (asc or desc). + Supports all FQL fields except for groups, hostgroups, or static_host_groups. + Examples sort value: status|asc or created_by|desc + + Type 2 - Date Range + "type": "date_range" + Supported field fields: created_time. + Does not support sort, size, or from. + + Returns: dict object containing API response. + + HTTP Method: POST + + Swagger URL + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/host-migration/HostMigrationAggregatesV1 + """ + + if not body: + body = [aggregate_payload(submitted_keywords=kwargs)] + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="HostMigrationAggregatesV1", + body=body + ) + + @force_default(defaults=["body"], default_types=["list"]) + def aggregate_migration(self: object, body: list = None, **kwargs) -> Dict[str, Union[int, dict]]: + """Get migration aggregates as specified via json in request body. + + Keyword arguments: + body -- full body payload, not required if using other keywords. + { + "resources": [ + { + "date_ranges": [ + { + "from": "string", + "to": "string" + } + ], + "exclude": "string", + "extended_bounds": { + "max": "string", + "min": "string" + }, + "field": "string", + "filter": "string", + "from": 0, + "include": "string", + "interval": "string", + "max_doc_count": 0, + "min_doc_count": 0, + "missing": "string", + "name": "string", + "q": "string", + "ranges": [ + { + "From": 0, + "To": 0 + } + ], + "size": 0, + "sort": "string", + "sub_aggregates": [ + null + ], + "time_zone": "string", + "type": "string" + } + ] + } + + Supported Types: + Both types support the following FQL filter props: + name, id, migration_id, target_cid, status, migration_status, created_by, created_time. + The value migration_status is an alias for status. + The value migration_id is an alias for id. + + + Type 1 - Terms + "type": "terms" + Supported field values: name, id, migration_id, target_cid, status, migration_status, created_by. + sort on terms type must be done on the same value as field and include a direction (asc or desc). + Supports all supported FQL fields. + Examples sort value: status|asc or created_by|desc. + + Type 2 - Date Range + "type": "date_range" + Supported field fields: created_time. + Does not support sort, size, or from. + + Returns: dict object containing API response. + + HTTP Method: POST + + Swagger URL + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/host-migration/MigrationAggregatesV1 + """ + + if not body: + body = [aggregate_payload(submitted_keywords=kwargs)] + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="MigrationAggregatesV1", + body=body + ) + + @force_default(defaults=["body", "parameters"], default_types=["dict"]) + def perform_host_migration_action(self: object, + body: dict = None, + parameters: dict = None, + **kwargs) -> Dict[str, Union[int, dict]]: + """Perform an action on host migrations + + Keyword arguments: + + id -- The migration job to perform actions on. String. + + action_name -- The action to perform + Available values: remove_hosts, remove_host_groups, add_host_groups + + body -- full body payload, not required if using other keywords. + { + "resources": [ + { + "action_parameters": [ + { + "name": "string", + "value": "string" + } + ], + "filter": "string", + "ids": [ + "string" + ] + } + ] + } + + Available Actions: + These actions only works if the migration has not started. + + add_host_groups adds static host groups to the selected hosts in a migration. + This action accepts the following action parameter: { "name": "host_group": "value": "$host_group_id" }. + Action parameters can be repeated to add multiple static host groups in a single request. + + remove_host_groups removes static host groups from the selected hosts in a migration. + This action accepts the following action parameter: { "name": "host_group": "value": "$host_group_id" }. + Action parameters can be repeated to remove multiple static host groups in a single request. + + remove_hosts removes the selected hosts from a migration. + This action does not accept any action parameters. + + FQL Filter supports the following fields: + groups, hostgroups, static_host_groups, + hostname, status, target_cid, source_cid, + migration_id, id, host_migration_id, created_time. + + Returns: dict object containing API response. + + HTTP Method: POST + + Swagger URL + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/host-migration/HostMigrationsActionsV1 + """ + if not body: + body = generic_payload_list(submitted_keywords=kwargs, + payload_value="ids" + ) + if kwargs.get("filter", None): + body["filter"] = kwargs.get("filter") + # Passing an action_parameters list will override the filter keyword + if kwargs.get("action_parameters", None): + body["action_parameters"] = kwargs.get("action_parameters", None) + + _allowed_actions = ['remove_hosts', 'remove_host_groups', 'add_host_groups'] + operation_id = "HostMigrationsActionsV1" + if kwargs.get("action_name").lower() in _allowed_actions: + returned = process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id=operation_id, + body=body, + keywords=kwargs, + params=parameters + ) + else: + returned = generate_error_result("Invalid value specified for action_name parameter.") + + return returned + + @force_default(defaults=["body"], default_types=["dict"]) + def get_host_migration_details(self: object, body: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: + """Get migration aggregates as specified via json in request body. + + Keyword arguments: + body -- full body payload, not required if using other keywords. + { + "resources":[ + { + "ids":[ + "string" + ] + } + ] + } + + Returns: dict object containing API response. + + Events + The events field describes actions that have occurred to the host migration entity. + Each object is defined by the action field. + When user is present, it is the user who performed the action. time is when the action occurred. + + Status Details + The status_details field is an optional field that + provides some more details about the status of a failed host migration. + It may be omitted or empty from a response. + + + + HTTP Method: POST + + Swagger URL + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/host-migration/GetHostMigrationsV1 + """ + + if not body: + body = generic_payload_list(submitted_keywords=kwargs, + payload_value="ids" + ) + + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="GetHostMigrationsV1", + body=body + ) + + @force_default(defaults=["body"], default_types=["dict"]) + def get_migration_destination(self: object, body: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: + """Gets destinations for a migration + + Keyword arguments: + body -- full body payload, not required if using other keywords. + { + "resources": [ + { + "device_ids": [ + "string" + ], + "filter": "string" + } + ] + } + + Returns: dict object containing API response. + + HTTP Method: POST + + Swagger URL + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/host-migration/GetMigrationDestinationsV1 + """ + + if not body: + if kwargs.get("device_ids", None): + body = generic_payload_list(submitted_keywords=kwargs, + payload_value="device_ids" + ) + else: + body["filter"] = kwargs.get("filter", None) + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="GetMigrationDestinationsV1", + body=body + ) + + @force_default(defaults=["body", "parameters"], default_types=["dict"]) + def perform_migration_job_action(self: object, + body: dict = None, + parameters: dict = None, + **kwargs) -> Dict[str, Union[int, dict]]: + """Perform an action on host migrations + + Keyword arguments: + action_name -- The action to perform + Available values: remove_hosts, remove_host_groups, add_host_groups + body -- full body payload, not required if using other keywords. + { + "resources": [ + { + "action_parameters": [ + { + "name": "string", + "value": "string" + } + ], + "filter": "string", + "ids": [ + "string" + ] + } + ] + } + + Available Actions: + These actions only works if the migration has not started. + + add_host_groups adds static host groups to the selected hosts in a migration. + This action accepts the following action parameter: { "name": "host_group": "value": "$host_group_id" }. + Action parameters can be repeated to add multiple static host groups in a single request. + + remove_host_groups removes static host groups from the selected hosts in a migration. + This action accepts the following action parameter: { "name": "host_group": "value": "$host_group_id" }. + Action parameters can be repeated to remove multiple static host groups in a single request. + + remove_hosts removes the selected hosts from a migration. + This action does not accept any action parameters. + + FQL Filter supports the following fields: + groups, hostgroups, static_host_groups, + hostname, status, target_cid, source_cid, + migration_id, id, host_migration_id, created_time. + + Returns: dict object containing API response. + + HTTP Method: POST + + Swagger URL + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/host-migration/MigrationsActionsV1 + """ + if not body: + body = generic_payload_list(submitted_keywords=kwargs, + payload_value="ids" + ) + if kwargs.get("filter", None): + body["filter"] = kwargs.get("filter") + # Passing an action_parameters list will override the filter keyword + if kwargs.get("action_parameters", None): + body["action_parameters"] = kwargs.get("action_parameters", None) + + _allowed_actions = ['start_migration', 'cancel_migration', 'rename_migration', 'delete_migration'] + operation_id = "MigrationsActionsV1" + if kwargs.get("action_name", "Not Specified").lower() in _allowed_actions: + returned = process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id=operation_id, + body=body, + keywords=kwargs, + params=parameters + ) + else: + returned = generate_error_result("Invalid value specified for action_name parameter.") + + return returned + + @force_default(defaults=["parameters"], default_types=["dict"]) + def get_migration_job_details(self: object, *args, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: + """Get migration job details + + Keyword arguments: + ids -- The migration jobs of interest. + parameters -- full parameters payload, not required if ids is provided as a keyword. + + Arguments: When not specified, the first argument to this method is assumed to be 'ids'. + All others are ignored. + + Returns: dict object containing API response. + + HTTP Method: GET + + Swagger URL + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/host-migration/GetMigrationsV1 + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="GetMigrationsV1", + keywords=kwargs, + params=handle_single_argument(args, parameters, "ids") + ) + + @force_default(defaults=["body"], default_types=["dict"]) + def create_migration(self: object, body: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: + """Create a device migration job. + + Keyword arguments: + body -- full body payload, not required if using other keywords. + { + "resources": [ + { + "device_ids": [ + "string" + ], + "filter": "string", + "name": "string", + "target_cid": "string + } + ] + } + + Returns: dict object containing API response. + + HTTP Method: POST + + Swagger URL + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/host-migration/CreateMigrationV1 + """ + if not body: + body = generic_payload_list(submitted_keywords=kwargs, + payload_value="device_ids" + ) + if kwargs.get("filter", None): + body["filter"] = kwargs.get("filter", None) + if kwargs.get("name", None): + body["name"] = kwargs.get("name", None) + if kwargs.get("target_cid", None): + body["target_cid"] = kwargs.get("target_cid", None) + + operation_id = "CreateMigrationV1" + + returned = process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id=operation_id, + body=body + ) + + return returned + + @force_default(defaults=["parameters"], default_types=["dict"]) + def query_host_migration_ids(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: + """Query host migration IDs + + Provide a FQL filter and paging details. + + Returns a set of Agent IDs which match the filter criteria. + + Keyword arguments: + filter -- The filter expression that should be used to limit the results. + Valid fields: host_migration_id, groups, hostgroups, hostname, + status, migration_id, created_time, static_host_groups, target_cid, source_cid, id + id -- The migration job to query. String. + limit -- The maximum records to return. [1-10000] + offset -- The offset to start retrieving records from + parameters - full parameters payload, not required if using other keywords. + sort -- The property to sort by. FQL syntax (e.g. name|asc). + Available values : + hostname|asc, hostname|desc, hostname, + status|asc, status|desc, status, migration_id|asc, + migration_id|desc, migration_id, created_time|asc, + created_time|desc, created_time, host_migration_id|asc, + host_migration_id|desc, host_migration_id, groups|asc, + groups|desc, groups, hostgroups|asc, hostgroups|desc, + hostgroups, source_cid|asc, source_cid|desc, source_cid, + id|asc, id|desc, id, static_host_groups|asc, static_host_groups|desc, + static_host_groups, target_cid|asc, target_cid|desc, target_cid + + This method only supports keywords for providing arguments. + + Returns: dict object containing API response. + + HTTP Method: GET + + Swagger URL + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/host-migration/GetHostMigrationIDsV1 + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="GetHostMigrationIDsV1", + keywords=kwargs, + params=parameters + ) + + @force_default(defaults=["parameters"], default_types=["dict"]) + def query_migration_jobs(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: + """Query host migration jobs. + + Provide a FQL filter and paging details. + + Returns a set of Agent IDs which match the filter criteria. + + Keyword arguments: + filter -- The filter expression that should be used to limit the results. + Valid fields: target_cid, status, migration_status, created_by, + created_time, name, id, migration_id + limit -- The maximum records to return. [1-10000] + offset -- The offset to start retrieving records from + parameters - full parameters payload, not required if using other keywords. + sort -- The property to sort by. FQL syntax (e.g. name|asc). + Available values : + target_cid|asc, target_cid|desc, target_cid, + status|asc, status|desc, status, + migration_status|asc, migration_status|desc, migration_status, + created_by|asc, created_by|desc, created_by, + created_time|asc, created_time|desc, created_time, + name|asc, name|desc, name, + id|asc, id|desc, id, migration_id|asc, + migration_id|desc, migration_id + + + + This method only supports keywords for providing arguments. + + Returns: dict object containing API response. + + HTTP Method: GET + + Swagger URL + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/host-migration/GetMigrationIDsV1 + """ + return process_service_request( + calling_object=self, + endpoints=Endpoints, + operation_id="GetMigrationIDsV1", + 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 + HostMigrationAggregatesV1 = aggregate_host_migration + MigrationAggregatesV1 = aggregate_migration + HostMigrationsActionsV1 = perform_host_migration_action + GetHostMigrationsV1 = get_host_migration_details + GetMigrationDestinationsV1 = get_migration_destination + MigrationsActionsV1 = perform_migration_job_action + GetMigrationsV1 = get_migration_job_details + CreateMigrationV1 = create_migration + GetHostMigrationIDsV1 = query_host_migration_ids + GetMigrationIDsV1 = query_migration_jobs diff --git a/tests/test_host_migration.py b/tests/test_host_migration.py new file mode 100644 index 000000000..3536f15c5 --- /dev/null +++ b/tests/test_host_migration.py @@ -0,0 +1,59 @@ +# test_certificate_based_exclusions.py +# This class tests the CertificateBasedExclusions service class + +# import json +import os +import sys + +# Authentication via the test_authorization.py +from tests import test_authorization as Authorization + +# Classes to test - manually imported from sibling folder +from falconpy import HostMigration +# Import our sibling src folder into the path +sys.path.append(os.path.abspath('src')) + +auth = Authorization.TestAuthorization() +config = auth.getConfigObject() +falcon = HostMigration(auth_object=config) +AllowedResponses = [600] + + +class TestHostMigration: + def test_all_code_paths(self): + error_checks = True + tests = { + "aggregate_host_migration": falcon.aggregate_host_migration(body={}), + "aggregate_migration": falcon.aggregate_migration(body={}), + "perform_host_migration_action": falcon.perform_host_migration_action(id="1234567", + action_name="remove_hosts", + ids="1234567", + action_parameters=[{ + "name": "group_id", + "value": "1234567"}]), + "get_host_migration_details": falcon.get_host_migration_details(ids="12345678"), + "get_migration_destination": falcon.get_migration_destination(filter="filter"), + "perform_migration_job_action": falcon.perform_migration_job_action(action_name="rename_migration", + filter="filter", + ids="12345677", + action_parameters=[{ + "name": "my_migration", + "value": "new_migration"}]), + "get_migration_job_details": falcon.get_migration_job_details(ids=12345678), + "create_migration": falcon.create_migration(filter="test: 'test'", + name="name", + target_cid="cid", + device_ids=["12345678"]), + "query_host_migration_ids": falcon.query_host_migration_ids(id="12345678", + offset=2, + limit=1, + sort="hostname|asc", + ilter="test:'test'"), + "query_migration_jobs": falcon.query_migration_jobs() + } + for key in tests: + if tests[key]["status_code"] not in AllowedResponses: + error_checks = False + print(key) + print(tests[key]) + assert error_checks From a5040a4824caeafed54c2dd5d9bafd1fdcb73994 Mon Sep 17 00:00:00 2001 From: alhumaw Date: Fri, 19 Jul 2024 16:37:35 -0700 Subject: [PATCH 3/4] unit test error code adjustment --- tests/test_host_migration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_host_migration.py b/tests/test_host_migration.py index 3536f15c5..a95802001 100644 --- a/tests/test_host_migration.py +++ b/tests/test_host_migration.py @@ -16,7 +16,7 @@ auth = Authorization.TestAuthorization() config = auth.getConfigObject() falcon = HostMigration(auth_object=config) -AllowedResponses = [600] +AllowedResponses = [200, 201, 207, 400, 404, 429, 500] class TestHostMigration: From b0ffee0d6da27c297badc115185e135201437ea5 Mon Sep 17 00:00:00 2001 From: alhumaw Date: Fri, 19 Jul 2024 16:42:45 -0700 Subject: [PATCH 4/4] linting and cleanup --- src/falconpy/__init__.py | 3 +- src/falconpy/_endpoint/__init__.py | 4 - src/falconpy/_endpoint/_datascanner.py | 80 --------- src/falconpy/_endpoint/deprecated/__init__.py | 2 - .../_endpoint/deprecated/_datascanner.py | 80 --------- .../_payload/_certificate_based_exclusions.py | 62 +++---- src/falconpy/certificate_based_exclusions.py | 11 +- src/falconpy/compliance_assessments.py | 49 ++++-- src/falconpy/datascanner.py | 154 ------------------ src/falconpy/host_migration.py | 20 +-- tests/test_certificate_based_exclusions.py | 8 +- tests/test_compliance_assessments.py | 4 +- tests/test_datascanner.py | 35 ---- tests/test_host_migration.py | 4 +- 14 files changed, 88 insertions(+), 428 deletions(-) delete mode 100644 src/falconpy/_endpoint/_datascanner.py delete mode 100644 src/falconpy/_endpoint/deprecated/_datascanner.py delete mode 100644 src/falconpy/datascanner.py delete mode 100644 tests/test_datascanner.py diff --git a/src/falconpy/__init__.py b/src/falconpy/__init__.py index 9934d34da..e0fe8febf 100644 --- a/src/falconpy/__init__.py +++ b/src/falconpy/__init__.py @@ -104,7 +104,6 @@ from .cspm_registration import CSPMRegistration from .custom_ioa import CustomIOA from .custom_storage import CustomStorage -from .datascanner import DataScanner from .d4c_registration import D4CRegistration from .detects import Detects from .device_control_policies import DeviceControlPolicies @@ -203,7 +202,7 @@ "ContainerAlerts", "ContainerDetections", "ContainerImages", "ContainerPackages", "ContainerVulnerabilities", "DriftIndicators", "UnidentifiedContainers", "ImageAssessmentPolicies", "APIIntegrations", "ThreatGraph", "ExposureManagement", - "DataScanner", "CertificateBasedExclusions", "ComplianceAssessments", "HostMigration" + "CertificateBasedExclusions", "ComplianceAssessments", "HostMigration" ] """ This is free and unencumbered software released into the public domain. diff --git a/src/falconpy/_endpoint/__init__.py b/src/falconpy/_endpoint/__init__.py index d8fb97ee5..765ef0fa8 100644 --- a/src/falconpy/_endpoint/__init__.py +++ b/src/falconpy/_endpoint/__init__.py @@ -37,7 +37,6 @@ from .deprecated import _scheduled_reports_deprecated from .deprecated import _zero_trust_assessment_deprecated from .deprecated import _certificate_based_exclusions_deprecated -from .deprecated import _datascanner_deprecated from .deprecated import _deprecated_operation_mapping from .deprecated import _deprecated_class_mapping @@ -109,7 +108,6 @@ from ._spotlight_vulnerabilities import _spotlight_vulnerabilities_endpoints from ._tailored_intelligence import _tailored_intelligence_endpoints from ._threatgraph import _threatgraph_endpoints -from ._datascanner import _datascanner_endpoints from ._unidentified_containers import _unidentified_containers_endpoints from ._user_management import _user_management_endpoints from ._workflows import _workflows_endpoints @@ -132,7 +130,6 @@ api_endpoints.extend(_cspm_registration_endpoints) api_endpoints.extend(_custom_ioa_endpoints) api_endpoints.extend(_custom_storage_endpoints) -api_endpoints.extend(_datascanner_endpoints) api_endpoints.extend(_d4c_registration_endpoints) api_endpoints.extend(_detects_endpoints) api_endpoints.extend(_device_control_policies_endpoints) @@ -194,7 +191,6 @@ deprecated_endpoints = [] deprecated_endpoints.extend(_certificate_based_exclusions_deprecated) deprecated_endpoints.extend(_custom_ioa_deprecated) -deprecated_endpoints.extend(_datascanner_deprecated) deprecated_endpoints.extend(_d4c_registration_deprecated) deprecated_endpoints.extend(_discover_deprecated) deprecated_endpoints.extend(_fdr_deprecated) diff --git a/src/falconpy/_endpoint/_datascanner.py b/src/falconpy/_endpoint/_datascanner.py deleted file mode 100644 index fb55c41d4..000000000 --- a/src/falconpy/_endpoint/_datascanner.py +++ /dev/null @@ -1,80 +0,0 @@ -"""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 -""" - -_datascanner_endpoints = [ - [ - "get_image_registry_credentials", - "GET", - "/data-security-dspm/entities/image-registry-credentials/v1", - "", - "datascanner", - [] - ], - [ - "get_data_scanner_tasks", - "GET", - "/data-security-dspm/entities/scanner-tasks/v1", - "", - "datascanner", - [ - { - "type": "string", - "description": "ID of the data scanner", - "name": "X-Scanner-Id", - "in": "header", - "required": True - } - ] - ], - [ - "update_data_scanner_tasks", - "PATCH", - "/data-security-dspm/entities/scanner-tasks/v1", - "", - "datascanner", - [ - { - "type": "string", - "description": "ID of the data scanner", - "name": "X-Scanner-Id", - "in": "header", - "required": True - } - ] - ] -] diff --git a/src/falconpy/_endpoint/deprecated/__init__.py b/src/falconpy/_endpoint/deprecated/__init__.py index 7c7ec56a8..5bd72ac17 100644 --- a/src/falconpy/_endpoint/deprecated/__init__.py +++ b/src/falconpy/_endpoint/deprecated/__init__.py @@ -50,7 +50,6 @@ from ._zero_trust_assessment import _zero_trust_assessment_endpoints from ._mapping import _deprecated_op_mapping, _deprecated_cls_mapping from ._certificate_based_exclusions import _certificate_based_exclusions_endpoints -from ._datascanner import _datascanner_endpoints _custom_ioa_deprecated = _custom_ioa_endpoints _d4c_registration_deprecated = _d4c_registration_endpoints @@ -70,6 +69,5 @@ _scheduled_reports_deprecated = _scheduled_reports_endpoints _zero_trust_assessment_deprecated = _zero_trust_assessment_endpoints _certificate_based_exclusions_deprecated = _certificate_based_exclusions_endpoints -_datascanner_deprecated = _datascanner_endpoints _deprecated_operation_mapping = _deprecated_op_mapping _deprecated_class_mapping = _deprecated_cls_mapping diff --git a/src/falconpy/_endpoint/deprecated/_datascanner.py b/src/falconpy/_endpoint/deprecated/_datascanner.py deleted file mode 100644 index e6a1c4786..000000000 --- a/src/falconpy/_endpoint/deprecated/_datascanner.py +++ /dev/null @@ -1,80 +0,0 @@ -"""Internal API endpoint constant library (deprecated operations). - - _______ __ _______ __ __ __ -| _ .----.-----.--.--.--.--| | _ | |_.----|__| |--.-----. -|. 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 -""" - -_datascanner_endpoints = [ - [ - "get-image-registry-credentials", - "GET", - "/data-security-dspm/entities/image-registry-credentials/v1", - "", - "datascanner", - [] - ], - [ - "get-data-scanner-tasks", - "GET", - "/data-security-dspm/entities/scanner-tasks/v1", - "", - "datascanner", - [ - { - "type": "string", - "description": "ID of the data scanner", - "name": "X-Scanner-Id", - "in": "header", - "required": True - } - ] - ], - [ - "update-data-scanner-tasks", - "PATCH", - "/data-security-dspm/entities/scanner-tasks/v1", - "", - "datascanner", - [ - { - "type": "string", - "description": "ID of the data scanner", - "name": "X-Scanner-Id", - "in": "header", - "required": True - } - ] - ] -] diff --git a/src/falconpy/_payload/_certificate_based_exclusions.py b/src/falconpy/_payload/_certificate_based_exclusions.py index b9933b0f5..29a1c0689 100644 --- a/src/falconpy/_payload/_certificate_based_exclusions.py +++ b/src/falconpy/_payload/_certificate_based_exclusions.py @@ -35,40 +35,42 @@ For more information, please refer to """ + from typing import Dict, List, Union def certificate_based_exclusions_payload(passed_keywords: dict) -> Dict[str, List[Dict[str, Union[str, int]]]]: - """Create a properly formatted payload for exclusion creatio - { - "resources": [ - { - "applied_globally": true, - "certificate": { - "issuer": "string", - "serial": "string", - "subject": "string", - "thumbprint": "string", - "valid_from": "2024-07-17T16:55:01.502Z", - "valid_to": "2024-07-17T16:55:01.502Z" - }, - "children_cids": [ - "string" - ], - "comment": "string", - "created_by": "string", - "created_on": "2024-07-17T16:55:01.502Z", - "description": "string", - "host_groups": [ - "string" - ], - "modified_by": "string", - "modified_on": "2024-07-17T16:55:01.502Z", - "name": "string", - "status": "string" - } - ] - } + """Create a properly formatted payload for exclusion creation. + + { + "resources": [ + { + "applied_globally": true, + "certificate": { + "issuer": "string", + "serial": "string", + "subject": "string", + "thumbprint": "string", + "valid_from": "2024-07-17T16:55:01.502Z", + "valid_to": "2024-07-17T16:55:01.502Z" + }, + "children_cids": [ + "string" + ], + "comment": "string", + "created_by": "string", + "created_on": "2024-07-17T16:55:01.502Z", + "description": "string", + "host_groups": [ + "string" + ], + "modified_by": "string", + "modified_on": "2024-07-17T16:55:01.502Z", + "name": "string", + "status": "string" + } + ] + } """ returned = { "resources": [] diff --git a/src/falconpy/certificate_based_exclusions.py b/src/falconpy/certificate_based_exclusions.py index 63d480f45..baa0f9324 100644 --- a/src/falconpy/certificate_based_exclusions.py +++ b/src/falconpy/certificate_based_exclusions.py @@ -35,6 +35,7 @@ For more information, please refer to """ + from typing import Dict, Union from ._util import force_default, process_service_request, handle_single_argument from ._service_class import ServiceClass @@ -54,9 +55,10 @@ class CertificateBasedExclusions(ServiceClass): - 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_exclusions(self: object, *args, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: - """Find all exclusion IDs matching the query with filter + """Find all exclusion IDs matching the query with filter. Keyword arguments: ids -- One or more exclusion IDs . String or list of strings. @@ -130,7 +132,8 @@ def create_exclusions(self: object, body: dict = None, **kwargs) -> Dict[str, Un calling_object=self, endpoints=Endpoints, operation_id="cb_exclusions_create_v1", - body=body + body=body, + keywords=kwargs ) @force_default(defaults=["parameters"], default_types=["dict"]) @@ -159,7 +162,7 @@ def delete_exclusions(self: object, *args, parameters: dict = None, **kwargs) -> keywords=kwargs, params=handle_single_argument(args, parameters, "ids") ) - + @force_default(defaults=["body"], default_types=["dict"]) def update_exclusions(self: object, body: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: """Update Certificate Based Exclusions. @@ -267,7 +270,7 @@ def query_certificates(self: object, parameters: dict = None, **kwargs) -> Dict[ 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 diff --git a/src/falconpy/compliance_assessments.py b/src/falconpy/compliance_assessments.py index a1aae1a32..2cf00d3c7 100644 --- a/src/falconpy/compliance_assessments.py +++ b/src/falconpy/compliance_assessments.py @@ -35,6 +35,7 @@ For more information, please refer to """ + from typing import Dict, Union from ._util import force_default, process_service_request from ._service_class import ServiceClass @@ -53,6 +54,7 @@ class ComplianceAssessments(ServiceClass): - 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 aggregate_cluster_assessments(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: """Get the assessments for each cluster. @@ -99,7 +101,8 @@ def aggregate_image_assessments(self: object, parameters: dict = None, **kwargs) image_id: Image ID cloud_info.cloud_provider: Cloud provider asset_type: asset type (container image) - compliance_finding.severity: Compliance finding severity; available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) + compliance_finding.severity: Compliance finding severity; + available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) compliance_finding.framework: Compliance finding framework (available values: CIS) image_repository: Image repository cloud_info.cloud_account_id: Cloud account ID @@ -141,7 +144,8 @@ def aggregate_rules_assessments(self: object, parameters: dict = None, **kwargs) cloud_info.cloud_account_id: Cloud account ID cloud_info.cloud_provider: Cloud provider compliance_finding.id: Compliance finding ID - compliance_finding.severity: Compliance finding severity; available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) + compliance_finding.severity: Compliance finding severity; + available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) cloud_info.cluster_name: Kubernetes cluster name image_id: Image ID image_tag: Image tag @@ -168,7 +172,7 @@ def aggregate_rules_assessments(self: object, parameters: dict = None, **kwargs) @force_default(defaults=["parameters"], default_types=["dict"]) def aggregate_failed_containers_by_rules(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: - """get the containers grouped into rules on which they failed + """Get the containers grouped into rules on which they failed. Keyword arguments: filter -- "Filter results using a query in Falcon Query Language (FQL). Supported Filters: @@ -181,7 +185,8 @@ def aggregate_failed_containers_by_rules(self: object, parameters: dict = None, compliance_finding.framework: Compliance finding framework (available values: CIS) cloud_info.cloud_provider: Cloud provider compliance_finding.id: Compliance finding ID - compliance_finding.severity: Compliance finding severity; available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) + compliance_finding.severity: Compliance finding severity; + available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) cid: Customer ID image_id: Image ID image_digest: Image digest (sha256 digest) @@ -206,8 +211,9 @@ def aggregate_failed_containers_by_rules(self: object, parameters: dict = None, ) @force_default(defaults=["parameters"], default_types=["dict"]) - def aggregate_failed_containers_count_by_severity(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: - """Get the failed containers count grouped into severity levels + def aggregate_failed_containers_count_by_severity(self: object, + parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: + """Get the failed containers count grouped into severity levels. Keyword arguments: filter -- "Filter results using a query in Falcon Query Language (FQL). Supported Filters: @@ -216,7 +222,8 @@ def aggregate_failed_containers_count_by_severity(self: object, parameters: dict compliance_finding.id: Compliance finding ID image_registry: Image registry compliance_finding.name: Compliance finding Name - compliance_finding.severity: Compliance finding severity; available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) + compliance_finding.severity: Compliance finding severity; + available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) cloud_info.cluster_name: Kubernetes cluster name cloud_info.cloud_account_id: Cloud account ID image_id: Image ID @@ -246,7 +253,7 @@ def aggregate_failed_containers_count_by_severity(self: object, parameters: dict @force_default(defaults=["parameters"], default_types=["dict"]) def aggregate_failed_images_by_rules(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: - """get the images grouped into rules on which they failed + """Get the images grouped into rules on which they failed. Keyword arguments: filter -- "Filter results using a query in Falcon Query Language (FQL). Supported Filters: @@ -260,7 +267,8 @@ def aggregate_failed_images_by_rules(self: object, parameters: dict = None, **kw compliance_finding.framework: Compliance finding framework (available values: CIS) cloud_info.namespace: Kubernetes namespace cid: Customer ID - compliance_finding.severity: Compliance finding severity; available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) + compliance_finding.severity: Compliance finding severity; + available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) cloud_info.cloud_provider: Cloud provider compliance_finding.id: Compliance finding ID image_id: Image ID @@ -284,14 +292,16 @@ def aggregate_failed_images_by_rules(self: object, parameters: dict = None, **kw ) @force_default(defaults=["parameters"], default_types=["dict"]) - def aggregate_failed_images_count_by_severity(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: - """Get the failed images count grouped into severity levels + def aggregate_failed_images_count_by_severity(self: object, + parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: + """Get the failed images count grouped into severity levels. Keyword arguments: filter -- "Filter results using a query in Falcon Query Language (FQL). Supported Filters: image_tag: Image tag compliance_finding.name: Compliance finding Name - compliance_finding.severity: Compliance finding severity; available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) + compliance_finding.severity: Compliance finding severity; + available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) cloud_info.cloud_account_id: Cloud account ID image_digest: Image digest (sha256 digest) image_registry: Image registry @@ -336,7 +346,8 @@ def aggregate_failed_rules_by_clusters(self: object, parameters: dict = None, ** image_registry: Image registry cloud_info.cloud_region: Cloud region asset_type: asset type (container, image) - compliance_finding.severity: Compliance finding severity; available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) + compliance_finding.severity: Compliance finding severity; + available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) cid: Customer ID compliance_finding.id: Compliance finding ID compliance_finding.framework: Compliance finding framework (available values: CIS) @@ -377,7 +388,8 @@ def aggregate_failed_rules_by_image(self: object, parameters: dict = None, **kwa cloud_info.cloud_region: Cloud region cloud_info.cloud_account_id: Cloud account ID asset_type: asset type (container, image) - compliance_finding.severity: Compliance finding severity; available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) + compliance_finding.severity: Compliance finding severity; + available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) image_id: Image ID image_digest: Image digest (sha256 digest) compliance_finding.framework: Compliance finding framework (available values: CIS) @@ -402,7 +414,8 @@ def aggregate_failed_rules_by_image(self: object, parameters: dict = None, **kwa ) @force_default(defaults=["parameters"], default_types=["dict"]) - def aggregate_failed_rules_count_by_severity(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: + def aggregate_failed_rules_count_by_severity(self: object, + parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: """Get the failed rules count grouped into severity levels. Keyword arguments: @@ -416,7 +429,8 @@ def aggregate_failed_rules_count_by_severity(self: object, parameters: dict = No compliance_finding.framework: Compliance finding framework (available values: CIS) image_repository: Image repository cloud_info.cloud_account_id: Cloud account ID - compliance_finding.severity: Compliance finding severity; available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) + compliance_finding.severity: Compliance finding severity; + available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) asset_type: asset type (container, image) cloud_info.cluster_name: Kubernetes cluster name cloud_info.cloud_provider: Cloud provider @@ -450,7 +464,8 @@ def aggregate_rules_by_status(self: object, parameters: dict = None, **kwargs) - image_tag: Image tag compliance_finding.name: Compliance finding Name asset_type: asset type (container, image) - compliance_finding.severity: Compliance finding severity; available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) + compliance_finding.severity: Compliance finding severity; + available values: 4, 3, 2, 1 (4: critical, 3: high, 2: medium, 1:low) cid: Customer ID container_name: Container name cloud_info.cluster_name: Kubernetes cluster name diff --git a/src/falconpy/datascanner.py b/src/falconpy/datascanner.py deleted file mode 100644 index d3905f83c..000000000 --- a/src/falconpy/datascanner.py +++ /dev/null @@ -1,154 +0,0 @@ -"""CrowdStrike Falcon Datascanner 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 ._service_class import ServiceClass -from ._endpoint._datascanner import _datascanner_endpoints as Endpoints - - -class DataScanner(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_image_registry_credentials(self: object) -> Dict[str, Union[int, dict]]: - """Retrieve the registry credentials. - - HTTP Method: GET - - Swagger URL - ---- - https://assets.falcon.crowdstrike.com/support/api/swagger.html#/datascanner/get-image-registry-credentials - - Keyword arguments - ---- - This method does not accept keyword arguments. - - Arguments - ---- - This method does not accept arguments. - - Returns - ---- - dict - Dictionary object containing API response. - """ - return process_service_request( - calling_object=self, - endpoints=Endpoints, - operation_id="get_image_registry_credentials", - ) - - @force_default(defaults=["parameters"], default_types=["dict"]) - def get_data_scanner_tasks(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: - """Retrieve data scanner tasks identified by the id. - - HTTP Method: GET - - Swagger URL - ---- - https://assets.falcon.crowdstrike.com/support/api/swagger.html#/datascanner/get-data-scanner-tasks - - Keyword arguments - ---- - X-Scanner-Id : str (required) - id of the data scanner. - - 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="get_data_scanner_tasks", - keywords=kwargs, - params=parameters - ) - - @force_default(defaults=["parameters"], default_types=["dict"]) - def update_data_scanner_tasks(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: - """Update data scanner tasks, as identified by the X-Scanner-Id. - - HTTP Method: PATCH - - Swagger URL - ---- - https://assets.falcon.crowdstrike.com/support/api/swagger.html#/datascanner/update-data-scanner-tasks - - Keyword arguments - ---- - X-Scanner-Id : str - ID of the data scanner - X-Machine-Id : str - Provider ID of the machine - - 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="update_data_scanner_tasks", - 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 - get_image_registry_credentials = get_image_registry_credentials - get_data_scanner_tasks = get_data_scanner_tasks - update_data_scanner_tasks = update_data_scanner_tasks diff --git a/src/falconpy/host_migration.py b/src/falconpy/host_migration.py index ea7c2d3b3..4bfd388a8 100644 --- a/src/falconpy/host_migration.py +++ b/src/falconpy/host_migration.py @@ -35,6 +35,7 @@ For more information, please refer to """ + from typing import Dict, Union from ._util import force_default, process_service_request, generate_error_result, handle_single_argument from ._service_class import ServiceClass @@ -128,9 +129,8 @@ def aggregate_host_migration(self: object, body: list = None, **kwargs) -> Dict[ HTTP Method: POST Swagger URL - https://assets.falcon.crowdstrike.com/support/api/swagger.html#/host-migration/HostMigrationAggregatesV1 + https://assets.falcon.crowdstrike.com/support/api/swagger.html#/host-migration/HostMigrationAggregatesV1 """ - if not body: body = [aggregate_payload(submitted_keywords=kwargs)] @@ -198,7 +198,7 @@ def aggregate_migration(self: object, body: list = None, **kwargs) -> Dict[str, Type 1 - Terms "type": "terms" Supported field values: name, id, migration_id, target_cid, status, migration_status, created_by. - sort on terms type must be done on the same value as field and include a direction (asc or desc). + sort on terms type must be done on the same value as field and include a direction (asc or desc). Supports all supported FQL fields. Examples sort value: status|asc or created_by|desc. @@ -214,7 +214,6 @@ def aggregate_migration(self: object, body: list = None, **kwargs) -> Dict[str, Swagger URL https://assets.falcon.crowdstrike.com/support/api/swagger.html#/host-migration/MigrationAggregatesV1 """ - if not body: body = [aggregate_payload(submitted_keywords=kwargs)] @@ -230,10 +229,9 @@ def perform_host_migration_action(self: object, body: dict = None, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: - """Perform an action on host migrations + """Perform an action on host migrations. Keyword arguments: - id -- The migration job to perform actions on. String. action_name -- The action to perform @@ -344,7 +342,6 @@ def get_host_migration_details(self: object, body: dict = None, **kwargs) -> Dic Swagger URL https://assets.falcon.crowdstrike.com/support/api/swagger.html#/host-migration/GetHostMigrationsV1 """ - if not body: body = generic_payload_list(submitted_keywords=kwargs, payload_value="ids" @@ -359,7 +356,7 @@ def get_host_migration_details(self: object, body: dict = None, **kwargs) -> Dic @force_default(defaults=["body"], default_types=["dict"]) def get_migration_destination(self: object, body: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: - """Gets destinations for a migration + """Get destinations for a migration. Keyword arguments: body -- full body payload, not required if using other keywords. @@ -381,7 +378,6 @@ def get_migration_destination(self: object, body: dict = None, **kwargs) -> Dict Swagger URL https://assets.falcon.crowdstrike.com/support/api/swagger.html#/host-migration/GetMigrationDestinationsV1 """ - if not body: if kwargs.get("device_ids", None): body = generic_payload_list(submitted_keywords=kwargs, @@ -401,7 +397,7 @@ def perform_migration_job_action(self: object, body: dict = None, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: - """Perform an action on host migrations + """Perform an action on host migrations. Keyword arguments: action_name -- The action to perform @@ -478,7 +474,7 @@ def perform_migration_job_action(self: object, @force_default(defaults=["parameters"], default_types=["dict"]) def get_migration_job_details(self: object, *args, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: - """Get migration job details + """Get migration job details. Keyword arguments: ids -- The migration jobs of interest. @@ -552,7 +548,7 @@ def create_migration(self: object, body: dict = None, **kwargs) -> Dict[str, Uni @force_default(defaults=["parameters"], default_types=["dict"]) def query_host_migration_ids(self: object, parameters: dict = None, **kwargs) -> Dict[str, Union[int, dict]]: - """Query host migration IDs + """Query host migration IDs. Provide a FQL filter and paging details. diff --git a/tests/test_certificate_based_exclusions.py b/tests/test_certificate_based_exclusions.py index 184c80d3e..8c0436c31 100644 --- a/tests/test_certificate_based_exclusions.py +++ b/tests/test_certificate_based_exclusions.py @@ -24,15 +24,15 @@ def test_all_code_paths(self): error_checks = True tests = { "get_exclusions": falcon.get_exclusions(ids="1234567"), - "create_exclusions": falcon.create_exclusions("12345678"), + "create_exclusions": falcon.create_exclusions(body={}), "delete_exclusions": falcon.delete_exclusions(ids="1234567"), - "update_exclusions": falcon.update_exclusions("exclusion_here"), + "update_exclusions": falcon.update_exclusions(body={}), "get_certificates": falcon.get_certificates(ids="1234567"), "query_certificates": falcon.query_certificates() } for key in tests: if tests[key]["status_code"] not in AllowedResponses: error_checks = False - # print(key) - # print(tests[key]) + # print(key) + # print(tests[key]) assert error_checks diff --git a/tests/test_compliance_assessments.py b/tests/test_compliance_assessments.py index 22b5687b5..a69930d83 100644 --- a/tests/test_compliance_assessments.py +++ b/tests/test_compliance_assessments.py @@ -38,6 +38,6 @@ def test_all_code_paths(self): for key in tests: if tests[key]["status_code"] not in AllowedResponses: error_checks = False - # print(key) - # print(tests[key]) + # print(key) + # print(tests[key]) assert error_checks diff --git a/tests/test_datascanner.py b/tests/test_datascanner.py deleted file mode 100644 index 39d0e2292..000000000 --- a/tests/test_datascanner.py +++ /dev/null @@ -1,35 +0,0 @@ -# test_certificate_based_exclusions.py -# This class tests the CertificateBasedExclusions service class - -# import json -import os -import sys - -# Authentication via the test_authorization.py -from tests import test_authorization as Authorization - -# Classes to test - manually imported from sibling folder -from falconpy import DataScanner -# Import our sibling src folder into the path -sys.path.append(os.path.abspath('src')) - -auth = Authorization.TestAuthorization() -config = auth.getConfigObject() -falcon = DataScanner(auth_object=config) -AllowedResponses = [200, 201, 207, 400, 404, 429, 500] - - -class TestDataScanner: - def test_all_code_paths(self): - error_checks = True - tests = { - "get_image_registry_credentials": falcon.get_image_registry_credentials(), - "get_data_scanner_tasks": falcon.get_data_scanner_tasks(), - "update_data_scanner_tasks": falcon.update_data_scanner_tasks() - } - for key in tests: - if tests[key]["status_code"] not in AllowedResponses: - error_checks = False - # print(key) - # print(tests[key]) - assert error_checks diff --git a/tests/test_host_migration.py b/tests/test_host_migration.py index a95802001..3a261db27 100644 --- a/tests/test_host_migration.py +++ b/tests/test_host_migration.py @@ -54,6 +54,6 @@ def test_all_code_paths(self): for key in tests: if tests[key]["status_code"] not in AllowedResponses: error_checks = False - print(key) - print(tests[key]) + # print(key) + # print(tests[key]) assert error_checks