1414#
1515"""Integrations functionality for Chronicle."""
1616
17- from typing import Any , TYPE_CHECKING
17+ from typing import TYPE_CHECKING , Any
1818
1919from secops .chronicle .models import (
2020 APIVersion ,
2121 DiffType ,
2222 IntegrationParam ,
23- TargetMode ,
24- PythonVersion ,
2523 IntegrationType ,
24+ PythonVersion ,
25+ TargetMode ,
26+ )
27+ from secops .chronicle .utils .format_utils import (
28+ build_patch_body ,
29+ format_resource_id ,
30+ remove_none_values ,
2631)
27-
28- from secops .chronicle .utils .format_utils import build_patch_body
2932from secops .chronicle .utils .request_utils import (
3033 chronicle_paginated_request ,
31- chronicle_request_bytes ,
3234 chronicle_request ,
35+ chronicle_request_bytes ,
3336)
3437
3538if TYPE_CHECKING :
@@ -106,7 +109,7 @@ def get_integration(
106109 return chronicle_request (
107110 client ,
108111 method = "GET" ,
109- endpoint_path = f"integrations/{ integration_name } " ,
112+ endpoint_path = f"integrations/{ format_resource_id ( integration_name ) } " ,
110113 api_version = api_version ,
111114 )
112115
@@ -130,7 +133,7 @@ def delete_integration(
130133 chronicle_request (
131134 client ,
132135 method = "DELETE" ,
133- endpoint_path = f"integrations/{ integration_name } " ,
136+ endpoint_path = f"integrations/{ format_resource_id ( integration_name ) } " ,
134137 api_version = api_version ,
135138 )
136139
@@ -175,27 +178,26 @@ def create_integration(
175178 Raises:
176179 APIError: If the API request fails
177180 """
178- serialised_params : list [dict [str , Any ]] | None = None
181+ serialized_params : list [dict [str , Any ]] | None = None
179182 if parameters is not None :
180- serialised_params = [
183+ serialized_params = [
181184 p .to_dict () if isinstance (p , IntegrationParam ) else p
182185 for p in parameters
183186 ]
184187
185- body_fields = {
186- "displayName" : display_name ,
187- "staging" : staging ,
188- "description" : description ,
189- "imageBase64" : image_base64 ,
190- "svgIcon" : svg_icon ,
191- "pythonVersion" : python_version ,
192- "parameters" : serialised_params ,
193- "categories" : categories ,
194- "type" : integration_type ,
195- }
196-
197- # Remove keys with None values
198- body_fields = {k : v for k , v in body_fields .items () if v is not None }
188+ body_fields = remove_none_values (
189+ {
190+ "displayName" : display_name ,
191+ "staging" : staging ,
192+ "description" : description ,
193+ "imageBase64" : image_base64 ,
194+ "svgIcon" : svg_icon ,
195+ "pythonVersion" : python_version ,
196+ "parameters" : serialized_params ,
197+ "categories" : categories ,
198+ "type" : integration_type ,
199+ }
200+ )
199201
200202 return chronicle_request (
201203 client ,
@@ -271,12 +273,12 @@ def download_integration_dependency(
271273def export_integration_items (
272274 client : "ChronicleClient" ,
273275 integration_name : str ,
274- actions : list [str ] | None = None ,
275- jobs : list [str ] | None = None ,
276- connectors : list [str ] | None = None ,
277- managers : list [str ] | None = None ,
278- transformers : list [str ] | None = None ,
279- logical_operators : list [str ] | None = None ,
276+ actions : list [str ] | str | None = None ,
277+ jobs : list [str ] | str | None = None ,
278+ connectors : list [str ] | str | None = None ,
279+ managers : list [str ] | str | None = None ,
280+ transformers : list [str ] | str | None = None ,
281+ logical_operators : list [str ] | str | None = None ,
280282 api_version : APIVersion | None = APIVersion .V1BETA ,
281283) -> bytes :
282284 """Exports specific items from an integration into a ZIP folder. Use
@@ -286,18 +288,18 @@ def export_integration_items(
286288 Args:
287289 client: ChronicleClient instance
288290 integration_name: name of the integration to export items from
289- actions: Optional. A list the ids of the actions to export. Format:
290- [1,2,3]
291- jobs: Optional. A list the ids of the jobs to export. Format:
292- [1,2,3]
293- connectors: Optional. A list the ids of the connectors to export.
294- Format: [1,2,3]
295- managers: Optional. A list the ids of the managers to export. Format:
296- [1,2,3]
297- transformers: Optional. A list the ids of the transformers to export.
298- Format: [1,2,3]
299- logical_operators: Optional. A list the ids of the logical
300- operators to export. Format: [1,2,3]
291+ actions: Optional. IDs of the actions to export as a list or
292+ comma-separated string. Format: [1,2,3] or "1,2,3"
293+ jobs: Optional. IDs of the jobs to export as a list or
294+ comma-separated string.
295+ connectors: Optional. IDs of the connectors to export as a
296+ list or comma-separated string.
297+ managers: Optional. IDs of the managers to export as a list
298+ or comma-separated string.
299+ transformers: Optional. IDs of the transformers to export as
300+ a list or comma-separated string.
301+ logical_operators: Optional. IDs of the logical operators to
302+ export as a list or comma-separated string.
301303 api_version: API version to use for the request. Default is V1BETA.
302304
303305 Returns:
@@ -306,23 +308,49 @@ def export_integration_items(
306308 Raises:
307309 APIError: If the API request fails
308310 """
309- export_items = {
310- "actions" : "," .join (actions ) if actions else None ,
311- "jobs" : jobs ,
312- "connectors" : connectors ,
313- "managers" : managers ,
314- "transformers" : transformers ,
315- "logicalOperators" : logical_operators ,
316- "alt" : "media" ,
317- }
318-
319- # Remove keys with None values
320- export_items = {k : v for k , v in export_items .items () if v is not None }
311+ export_items = remove_none_values (
312+ {
313+ "actions" : (
314+ "," .join (actions )
315+ if isinstance (actions , list )
316+ else actions if actions else None
317+ ),
318+ "jobs" : (
319+ "," .join (jobs )
320+ if isinstance (jobs , list )
321+ else jobs if jobs else None
322+ ),
323+ "connectors" : (
324+ "," .join (connectors )
325+ if isinstance (connectors , list )
326+ else connectors if connectors else None
327+ ),
328+ "managers" : (
329+ "," .join (managers )
330+ if isinstance (managers , list )
331+ else managers if managers else None
332+ ),
333+ "transformers" : (
334+ "," .join (transformers )
335+ if isinstance (transformers , list )
336+ else transformers if transformers else None
337+ ),
338+ "logicalOperators" : (
339+ "," .join (logical_operators )
340+ if isinstance (logical_operators , list )
341+ else logical_operators if logical_operators else None
342+ ),
343+ "alt" : "media" ,
344+ }
345+ )
321346
322347 return chronicle_request_bytes (
323348 client ,
324349 method = "GET" ,
325- endpoint_path = f"integrations/{ integration_name } :exportItems" ,
350+ endpoint_path = (
351+ f"integrations/{ format_resource_id (integration_name )} :"
352+ "exportItems"
353+ ),
326354 params = export_items ,
327355 api_version = api_version ,
328356 headers = {"Accept" : "application/zip" },
@@ -440,13 +468,12 @@ def get_integration_restricted_agents(
440468 Raises:
441469 APIError: If the API request fails
442470 """
443- params_fields = {
444- "requiredPythonVersion" : required_python_version .value ,
445- "pushRequest" : push_request ,
446- }
447-
448- # Remove keys with None values
449- params_fields = {k : v for k , v in params_fields .items () if v is not None }
471+ params_fields = remove_none_values (
472+ {
473+ "requiredPythonVersion" : required_python_version .value ,
474+ "pushRequest" : push_request ,
475+ }
476+ )
450477
451478 return chronicle_request (
452479 client ,
@@ -487,7 +514,7 @@ def get_integration_diff(
487514 return chronicle_request (
488515 client ,
489516 method = "GET" ,
490- endpoint_path = f"integrations/{ integration_name } "
517+ endpoint_path = f"integrations/{ format_resource_id ( integration_name ) } "
491518 f":fetch{ diff_type .value } Diff" ,
492519 api_version = api_version ,
493520 )
@@ -519,7 +546,7 @@ def transition_integration(
519546 return chronicle_request (
520547 client ,
521548 method = "POST" ,
522- endpoint_path = f"integrations/{ integration_name } "
549+ endpoint_path = f"integrations/{ format_resource_id ( integration_name ) } "
523550 f":pushTo{ target_mode .value } " ,
524551 api_version = api_version ,
525552 )
@@ -592,7 +619,7 @@ def update_integration(
592619 return chronicle_request (
593620 client ,
594621 method = "PATCH" ,
595- endpoint_path = f"integrations/{ integration_name } " ,
622+ endpoint_path = f"integrations/{ format_resource_id ( integration_name ) } " ,
596623 json = body ,
597624 params = params ,
598625 api_version = api_version ,
@@ -650,23 +677,20 @@ def update_custom_integration(
650677 Raises:
651678 APIError: If the API request fails
652679 """
653- integration_fields = {
654- "name" : integration_name ,
655- "displayName" : display_name ,
656- "description" : description ,
657- "imageBase64" : image_base64 ,
658- "svgIcon" : svg_icon ,
659- "pythonVersion" : python_version ,
660- "parameters" : parameters ,
661- "categories" : categories ,
662- "type" : integration_type ,
663- "staging" : staging ,
664- }
665-
666- # Remove keys with None values
667- integration_fields = {
668- k : v for k , v in integration_fields .items () if v is not None
669- }
680+ integration_fields = remove_none_values (
681+ {
682+ "name" : integration_name ,
683+ "displayName" : display_name ,
684+ "description" : description ,
685+ "imageBase64" : image_base64 ,
686+ "svgIcon" : svg_icon ,
687+ "pythonVersion" : python_version ,
688+ "parameters" : parameters ,
689+ "categories" : categories ,
690+ "type" : integration_type ,
691+ "staging" : staging ,
692+ }
693+ )
670694
671695 body = {"integration" : integration_fields }
672696
@@ -679,7 +703,7 @@ def update_custom_integration(
679703 client ,
680704 method = "POST" ,
681705 endpoint_path = f"integrations/"
682- f"{ integration_name } :updateCustomIntegration" ,
706+ f"{ format_resource_id ( integration_name ) } :updateCustomIntegration" ,
683707 json = body ,
684708 params = params ,
685709 api_version = api_version ,
0 commit comments