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