diff --git a/admyral/actions/__init__.py b/admyral/actions/__init__.py index 22e38286..4f2d397e 100644 --- a/admyral/actions/__init__.py +++ b/admyral/actions/__init__.py @@ -14,6 +14,7 @@ build_lookup_table, filter, join_lists, + select_fields_from_objects_in_list, ) from admyral.actions.integrations.communication import ( send_slack_message, @@ -193,4 +194,5 @@ "list_google_drive_files_with_link_sharing_enabled", "get_jira_project", "get_jira_transitions", + "select_fields_from_objects_in_list", ] diff --git a/admyral/actions/utilities.py b/admyral/actions/utilities.py index 92f8748a..7a210be0 100644 --- a/admyral/actions/utilities.py +++ b/admyral/actions/utilities.py @@ -387,3 +387,27 @@ def calculate_join_key(entry, key_paths): join_result.append(new_entry) return join_result + + +@action( + display_name="Select Fields from Objects in List", + display_namespace="Admyral", + description="Selects fields from a list of JSON objects.", +) +def select_fields_from_objects_in_list( + input_list: Annotated[ + list[dict[str, JsonValue]], + ArgumentMetadata( + display_name="Input List", + description="The list of objects to select fields from.", + ), + ], + fields: Annotated[ + list[str], + ArgumentMetadata( + display_name="Fields", + description="The keys to select from the objects.", + ), + ], +) -> list[dict[str, JsonValue]]: + return [{field: x[field] for field in fields} for x in input_list] diff --git a/docs/pages/pre_defined_actions.mdx b/docs/pages/pre_defined_actions.mdx index 602fb512..b4875ee5 100644 --- a/docs/pages/pre_defined_actions.mdx +++ b/docs/pages/pre_defined_actions.mdx @@ -545,3 +545,42 @@ employee_departments = join_lists( # } # ] ``` + +## Select Fields from Objects in List + +Extract specific fields from each object in a list. For each object in the input list, create a new object containing only the specified fields. If a field doesn't exist in an object, +that entry will raise a KeyError. The field names must exactly match the keys in the objects. + +Example field selections: + +``` +["name", "email"] - extracts just the name and email fields +["id", "created_at", "status"] - extracts multiple top-level fields +``` + +| Parameter | Type | Description | Required/Optional | +| ------------ | ---- | ------------------------------------------------ | ----------------- | +| `input_list` | list | The list of JSON objects to extract fields from. | Required | +| `fields` | list | The field names to select from each object. | Required | + +Usage Examples: + +```python +# Given a list of user objects with multiple fields +users = [ + {"id": 1, "name": "John", "email": "john@example.com", "role": "admin"}, + {"id": 2, "name": "Jane", "email": "jane@example.com", "role": "user"} +] + +# Extract just the name and email fields +simplified_users = select_fields_from_objects_in_list( + input_list=users, + fields=["name", "email"] +) + +# Result: +# [ +# {"name": "John", "email": "john@example.com"}, +# {"name": "Jane", "email": "jane@example.com"} +# ] +``` diff --git a/examples/access_review/workflows/kandji_device_information.py b/examples/access_review/workflows/kandji_device_information.py index c328da49..c57bc885 100644 --- a/examples/access_review/workflows/kandji_device_information.py +++ b/examples/access_review/workflows/kandji_device_information.py @@ -1,7 +1,7 @@ """ admyral action push transform_kandji_devices_information -a workflows/kandji_device_information.py -admyral workflow push kandji_device_information -f workflows/kandji_device_information.py +admyral workflow push kandji_device_information -f workflows/kandji_device_information.py --activate Required Kandji Permissions: - Application Firewall @@ -19,10 +19,10 @@ list_kandji_devices, get_kandji_application_firewall, get_kandji_desktop_and_screensaver, - get_kandji_library_item_statuses, join_lists, format_json_to_list_view_string, send_slack_message, + select_fields_from_objects_in_list, ) from admyral.action import action, ArgumentMetadata @@ -52,7 +52,6 @@ def transform_kandji_devices_information( "Lock Screensaver Interval": device[ "desktop_and_screensaver_screensaver_interval" ], - "Passcode Profile Status": device["passcode_profile_status"], } formatted.append(formatted_device) return formatted @@ -65,10 +64,18 @@ def transform_kandji_devices_information( def kandji_device_information(payload: dict[str, JsonValue]): # get OS version devices = list_kandji_devices(secrets={"KANDJI_SECRET": "kandji_secret"}) + devices = select_fields_from_objects_in_list( + input_list=devices, + fields=["device_id", "device_name", "platform", "os_version"], + ) device_status_application_firewall = get_kandji_application_firewall( secrets={"KANDJI_SECRET": "kandji_secret"}, ) + device_status_application_firewall = select_fields_from_objects_in_list( + input_list=device_status_application_firewall, + fields=["device_id", "status"], + ) result = join_lists( list1=devices, list1_join_key_paths=[["device_id"]], @@ -80,6 +87,10 @@ def kandji_device_information(payload: dict[str, JsonValue]): device_status_desktop_and_screensaver = get_kandji_desktop_and_screensaver( secrets={"KANDJI_SECRET": "kandji_secret"} ) + device_status_desktop_and_screensaver = select_fields_from_objects_in_list( + input_list=device_status_desktop_and_screensaver, + fields=["device_id", "screensaver_interval"], + ) result = join_lists( list1=result, list1_join_key_paths=[["device_id"]], @@ -88,18 +99,6 @@ def kandji_device_information(payload: dict[str, JsonValue]): key_prefix_list2="desktop_and_screensaver_", ) - device_status_passcode_profile = get_kandji_library_item_statuses( - library_item_id="46e31b6e-6d9e-43b8-adf1-9034e94d507e", # TODO: set to your Passcode Profile ID here - secrets={"KANDJI_SECRET": "kandji_secret"}, - ) - result = join_lists( - list1=result, - list1_join_key_paths=[["device_id"]], - list2=device_status_passcode_profile, - list2_join_key_paths=[["computer", "id"]], - key_prefix_list2="passcode_profile_", - ) - formatted_devices = transform_kandji_devices_information(devices=result) message = format_json_to_list_view_string(json_value=formatted_devices) send_slack_message(