PrismaCloudAttribution
Recursively extracts specified fields from provided list of assets for Prisma Cloud attribution use case.
python · Prisma Cloud by Palo Alto Networks
Source
import demistomock as demisto from CommonServerPython import * # noqa # pylint: disable=unused-wildcard-import from CommonServerUserPython import * # noqa """PrismaCloudAttribution """ from collections.abc import Iterable from typing import Any IPADDRESS_KEYS = ["publicIpAddress", "natIP", "publicIp", "inboundIpAddress", "ipAddress", "IPAddress"] FQDN_KEYS = [ "publicDnsName", "dnsname", "domainName", "name", "dnsName", "hostName", "properties.hostName", "fqdn", "enabledHostNames", "web", ] """ STANDALONE FUNCTION """ def recursive_find(keys: list[str] | str, value: Iterable[Any]) -> Iterable[Any]: if not isinstance(keys, list): keys = [keys] for k, v in value.items() if isinstance(value, dict) else enumerate(value) if isinstance(value, list) else []: if k in keys: yield v elif isinstance(v, list): for result in recursive_find(keys, v): yield result elif isinstance(v, dict): for result in recursive_find(keys, v): yield result def handle_data(data: dict[str, Any], fields: list[str]) -> dict[str, Any]: out_dict: dict = {} if "ip" in fields: ips = list(set(recursive_find(IPADDRESS_KEYS, data))) out_dict["ip"] = ips if ips else None if "fqdn" in fields: fqdns = list({fq for fq in recursive_find(FQDN_KEYS, data) if fq.count(".") > 0}) out_dict["fqdn"] = fqdns if fqdns else None return out_dict """ COMMAND FUNCTION """ def attribution_command(args: dict[str, Any]) -> CommandResults: assets = argToList(args.get("assets", [])) fields = argToList( args.get("fields", "id,cloudType,resourceName,resourceType,regionId,accountId,accountName,hasAlert,service,ip,fqdn") ) asset_dict: dict[str, dict[str, Any]] = {} for asset in assets: if not isinstance(asset, dict): continue if "rrn" not in asset: continue rrn = asset["rrn"] asset_dict[rrn] = {"rrn": rrn} for k in asset: if k == "name" and "resourceName" in fields: asset_dict[rrn]["resourceName"] = asset["name"] elif k == "data" and isinstance(asset[k], dict): asset_dict[rrn].update(handle_data(asset[k], fields)) elif k in fields: asset_dict[rrn][k] = asset[k] return CommandResults(outputs=list(asset_dict.values()), outputs_prefix="PrismaCloud.Attribution", outputs_key_field="rrn") """ MAIN FUNCTION """ def main(): try: return_results(attribution_command(demisto.args())) except Exception as ex: return_error(f"Failed to execute PrismaCloudAttribution. Error: {ex!s}") """ ENTRY POINT """ if __name__ in ("__main__", "__builtin__", "builtins"): main()
README
Recursively extracts specified fields from provided list of assets for Prisma Cloud attribution use case.
Script Data
| Name | Description |
|---|---|
| Script Type | python3 |
| Tags | |
| Cortex XSOAR Version | 6.0.0 |
Inputs
| Argument Name | Description |
|---|---|
| assets | List of Prisma Cloud assets to return. |
| fields | Fields to be returned (comma separated). |
Outputs
| Path | Description | Type |
|---|---|---|
| PrismaCloud.Attribution.accountId | Cloud Account ID | Unknown |
| PrismaCloud.Attribution.accountName | Cloud Account Name | Unknown |
| PrismaCloud.Attribution.cloudType | Cloud Type | Unknown |
| PrismaCloud.Attribution.fqdn | FQDNs associated to the resource | Unknown |
| PrismaCloud.Attribution.rrn | Resource RRN | Unknown |
| PrismaCloud.Attribution.ip | IPs associated to the resource | Unknown |
| PrismaCloud.Attribution.regionId | Cloud Region ID | Unknown |
| PrismaCloud.Attribution.hasAlert | Resource has Prisma Cloud Alert | Unknown |
| PrismaCloud.Attribution.resourceName | Resource Name | Unknown |
| PrismaCloud.Attribution.resourceType | Resource Type | Unknown |
| PrismaCloud.Attribution.service | Cloud Service | Unknown |
Script Example
!PrismaCloudAttribution assets="${Redlock.Asset}"
Context Example
{
"PrismaCloud": {
"Attribution": [
{
"accountId": "123456",
"accountName": "aws-user-personal",
"cloudType": "aws",
"fqdn": [
"application-lb-123456.us-east-1.elb.amazonaws.com"
],
"hasAlert": false,
"id": "arn:aws:elasticloadbalancing:us-east-1:123456:loadbalancer/app/application-lb/1398164320221c02",
"ip": null,
"regionId": "us-east-1",
"resourceName": "application-lb",
"resourceType": "Managed Load Balancer",
"rrn": "rrn::managedLb:us-east-1:123456:b38d940663c047b02c2116be49695cf353976dff:arn%3Aaws%3Aelasticloadbalancing%3Aus-east-1%3A123456%3Aloadbalancer%2Fapp%2Fapplication-lb%2F1398164320221c02",
"service": "Amazon Elastic Load Balancing"
},
{
"accountId": "123456",
"accountName": "aws-user-personal",
"cloudType": "aws",
"fqdn": [
"ec2.eu.compute-1.amazonaws.com"
],
"hasAlert": false,
"id": "i-654321b",
"ip": [
"35.180.1.1"
],
"regionId": "eu-west-3",
"resourceName": "testvm",
"resourceType": "Instance",
"rrn": "rrn::instance:eu-west-3:123456:9db2db5fdba47606863c8da86d3ae594fb5aee2b:i-654321b",
"service": "Amazon EC2"
}
]
}
}
Human Readable Output
Results
accountId accountName cloudType fqdn hasAlert id ip regionId resourceName resourceType rrn service 12345 aws-user-personal aws application-lb-624166765.us-east-1.elb.amazonaws.com false arn:aws:elasticloadbalancing:us-east-1:12345:loadbalancer/app/application-lb/1398164320221c02 us-east-1 application-lb Managed Load Balancer rrn::managedLb:us-east-1:12345:b38d940663c047b02c2116be49695cf353976dff:arn%3Aaws%3Aelasticloadbalancing%3Aus-east-1%3A12345%3Aloadbalancer%2Fapp%2Fapplication-lb%2F1398164320221c02 Amazon Elastic Load Balancing 12345 aws-user-personal aws ec2.eu.amazonaws.com false i-654321 35.180.1.1 eu-west-3 testvm Instance rrn::instance:eu-west-3:12345:9db2db5fdba47606863c8da86d3ae594fb5aee2b:i-654321 Amazon EC2