diff --git a/.github/workflows/pr-appinspect.yml b/.github/workflows/pr-appinspect.yml index 2333e8c2..76593d03 100644 --- a/.github/workflows/pr-appinspect.yml +++ b/.github/workflows/pr-appinspect.yml @@ -8,7 +8,7 @@ on: jobs: appinspect-addon: name: AppInspect (Add-on) - runs-on: ubuntu-20.04 + runs-on: ubuntu-20.04 # Remove write permissions permissions: contents: read diff --git a/Splunk_TA_paloalto/bin/input_module_cortex_xdr.py b/Splunk_TA_paloalto/bin/input_module_cortex_xdr.py index 756b81c1..f9ce23ea 100644 --- a/Splunk_TA_paloalto/bin/input_module_cortex_xdr.py +++ b/Splunk_TA_paloalto/bin/input_module_cortex_xdr.py @@ -70,14 +70,19 @@ def fetch_xdr_incidents(helper, client, mod_time): "value": mod_time, } ) + try: + incidents = client.get_incidents( + limit=50, + sort_field="modification_time", + sort_order="asc", + filters=filters, + ) + helper.log_info("Message: XDR API Returned Successfully") + return incidents + except Exception as e: + message = "Message: %s"%e + helper.log_error(message) - incidents = client.get_incidents( - limit=50, - sort_field="modification_time", - sort_order="asc", - filters=filters, - ) - return incidents def fetch_incident_details(helper, client, incident): try: @@ -120,7 +125,7 @@ def handle_incidents(helper, ew, incidents, get_details, base_url): sourcetype='pan:xdr_incident', data=json.dumps(incident)) ew.write_event(event) - helper.log_debug(f"Got {len(incidents)} results") + helper.log_info(f"Got {len(incidents)} results") helper.log_debug( "Got the following incident IDs: " + " ".join([str(y) for y in incidents]) @@ -178,5 +183,5 @@ def collect_events(helper, ew): if incidents: handle_incidents(helper, ew, incidents, get_details, base_url) else: - helper.log_debug("No Incidents") + helper.log_info("No Incidents") diff --git a/Splunk_TA_paloalto/default/data/ui/nav/default.xml b/Splunk_TA_paloalto/default/data/ui/nav/default.xml index 3cbb8959..cc70e344 100644 --- a/Splunk_TA_paloalto/default/data/ui/nav/default.xml +++ b/Splunk_TA_paloalto/default/data/ui/nav/default.xml @@ -1,5 +1,6 @@ \ No newline at end of file diff --git a/Splunk_TA_paloalto/default/data/ui/views/health.xml b/Splunk_TA_paloalto/default/data/ui/views/health.xml new file mode 100644 index 00000000..b8a7c253 --- /dev/null +++ b/Splunk_TA_paloalto/default/data/ui/views/health.xml @@ -0,0 +1,345 @@ +
+ + + + index="_internal" source="/opt/splunk/var/log/splunk/splunk_ta_paloalto_cortex_xdr.log" earliest=-2m + | search _raw="*XDR API Returned Successfully*" OR _raw="*401 Client Error:*" + | head 1 + | rex field=_raw "Message: (?<message>.*)" + | eval severity_level=if(like(message, "401 Client Error%"),"3","0") + | eval Results=case(severity_level=="3", "❗Invalid Cortex XDR API Key or ID", severity_level=="0","✅ This health check item was successful.", false(), "⏹️ ️This health check item is not applicable.") + | eval Check="Cortex XDR API Validation" + | eval "Learn More"="Open Documentation" + | append + [| search sourcetype="pan:*" earliest=-24h + | dedup sourcetype + | fields host sourcetype splunk_server + | stats list(sourcetype) as sourcetypes by splunk_server + | eval invalid_sourcetypes=mvfilter(sourcetypes=="pan:log" OR sourcetypes=="pan:firewall") + | eval severity_level=if(isnull(invalid_sourcetypes), "0", "3") + | eval Check="Valid Palo Alto Networks Sourcetypes" + | eval doc_url="https://pan.dev/splunk/docs/health-checks/#valid-palo-alto-networks-sourcetypes" + | eval "Learn More"="Open Documentation" + | eval Results=case(severity_level=="3", "❗Invalid sourcetypes detected.",severity_level=="0","✅ This health check item was successful.",false(),"⏹️ This health check item is not applicable.") ] + | append + [| search sourcetype=pan:* sourcetype!="pan:iot_*" sourcetype!="pan:xdr_incident" sourcetype!="pan:aperture" sourcetype!="pan:firewall_cloud" + | dedup sourcetype + | rex field=_raw "^(?:[^,]*,){6}(?<time_field>[^,]*)" + | eval valid_time=strptime(time_field, "%Y/%m/%d %H:%M:%S") + | eval severity_level=if(isnull(valid_time), 3, 0) + | eval Check=sourcetype." Timestamp Compatibility" + | eval doc_url="https://pan.dev/splunk/docs/health-checks/#timestamp-compatibility" + | eval "Learn More"="Open Documentation" + | eval Results=case(severity_level=="3", "❗Timestamp format is incorrect. Make sure logs from Firewall or Panorama is sent via syslog BSD with default formatting.",severity_level=="0","✅ This health check item was successful.",false(),"⏹️ This health check item is not applicable.") ] + | append + [| search sourcetype="pan:*" latest=+1mon earliest=now + | stats count + | eval severity_level = case(count > "0", 3, count=="0", 0, false(), 1) + | eval Check="Timestamp Validation" + | eval doc_url="https://pan.dev/splunk/docs/health-checks/#timestamp-validation" + | eval "Learn More"="Open Documentation" + | eval Results=case(severity_level=="3", "❗Log sourcetypes with timestamps detected in the future.",severity_level=="0","✅ This health check item was successful.",false(),"⏹️ This health check item is not applicable.") ] + | append + [| search index="_internal" source="/opt/splunk/var/log/python_upgrade_readiness_app/scan_summary/scan_summary.json" + | head 1 + | spath output=name {}.name + | spath output=scanType {}.scanType + | spath output=details {}.details + | spath output=status {}.status + | eval combined=mvzip(mvzip('name', 'details',"|"), mvzip('scanType', 'status', "|"), "|") + | fields combined, host + | mvexpand combined + | makemv delim="|", combined + | eval name=mvindex(combined, 0) + | eval details=mvindex(combined,1) + | eval scanType=mvindex(combined, 2) + | eval status=mvindex(combined, 3) + | eval severity_level=case(status=="BLOCKER","3",status=="PASSED", "0") + | search scanType="appPythonUpradeReadinessScanDetails" AND (name="Splunk_TA_paloalto" OR name="SplunkforPaloAltoNetworks") + | eval Check=name." Python 2 Artifacts" + | eval doc_url="https://pan.dev/splunk/docs/health-checks/#unsupported-code" + | eval "Learn More"="Open Documentation" + | eval Results=case(severity_level=="3", "❗ ".name." is not compatible with Python 3.",severity_level=="0","✅ This health check item was successful.",false(),"⏹️ This health check item is not applicable.") ] + | append + [| search index="_internal" source="/opt/splunk/var/log/python_upgrade_readiness_app/scan_summary/scan_summary.json" + | head 1 + | spath output=name {}.name + | spath output=scanType {}.scanType + | spath output=details {}.details + | spath output=status {}.status + | eval combined=mvzip(mvzip('name', 'details',"|"), mvzip('scanType', 'status', "|"), "|") + | fields combined, host + | mvexpand combined + | makemv delim="|", combined + | eval name=mvindex(combined, 0) + | eval details=mvindex(combined,1) + | eval scanType=mvindex(combined, 2) + | eval status=mvindex(combined, 3) + | eval severity_level=case(status=="BLOCKER","3",status=="PASSED", "0") + | search scanType="appJqueryUpradeReadinessScanDetails" AND (name="Splunk_TA_paloalto" OR name="SplunkforPaloAltoNetworks") + | eval Check=name." jQuery Artifacts" + | eval doc_url="https://pan.dev/splunk/docs/health-checks/#unsupported-code" + | eval "Learn More"="Open Documentation" + | eval Results=case(severity_level=="3", "❗ ".name." is not compatible with jQuery.",severity_level=="0","✅ This health check item was successful.",false(),"⏹️ This health check item is not applicable.") ] + | append + [| search sourcetype="pan:firewall_cloud" earliest=-15m + | eval isJSON = if(json_valid(_raw), 0, 1) + | stats count by isJSON + | eval severity_level=case(isJSON==0 AND count>0, 0, isJSON==1 and count > 0, 3) + | eval Check="Cortex Log Format" + | eval doc_url="https://pan.dev/splunk/docs/health-checks/#cortex-log-format" + | eval "Learn More"="Open Documentation" + | eval Results = case(severity_level=3, "❗ Invalid JSON detected for Cortex Logs", severity_level=="0","✅ This health check item was successful.",false(),"⏹️ This health check item is not applicable.") ] + | append + [| search rest /servicesNS/nobody/SplunkforPaloAltoNetworks/admin/summarization by_tstats=t splunk_server=local count=0 + | search eai:acl.app=SplunkforPaloAltoNetworks + | eval datamodel=replace('summary.id',"DM_".'eai:acl.app'."_","") + | stats list(datamodel) as datamodels by splunk_server + | eval total_count = mvcount(datamodels) + | eval severity_level=case(total_count="2", 0, total_count="0", 3, total_count="1",2) + | eval Check="Datamodel Acceleration" + | eval doc_url="https://pan.dev/splunk/docs/health-checks/#datamodel-acceleration" + | eval "Learn More"="Open Documentation" + | eval Results=case(severity_level=="3", "❗Datamodels are not enabled. ", severity_level="2", "⚠️ One or more datamodels are not enabled. ", severity_level=="0","✅ This health check item was successful.",false(),"⏹️ This health check item is not applicable.")] + | sort Results desc + + +
+ + + + -24h@h + now + + +
+ + + + + | stats count + + + + + + + + + + + + + + + + + + + + + + + | stats count(eval(severity_level==0)) as count + + + + + + + + + + + + + + + + + + + + + + + | stats count(eval(severity_level==2)) as count + + + + + + + + + + + + + + + + + + + + + + + | stats count(eval(severity_level==3)) as count + + + + + + + + + + + + + + + + + + + + + + + + + Health Checks + + + + + + + + + + + ["Check", "Results", "Learn More"] + + + + $row.doc_url$ + + + + + +
+
+
+ + + + + sourcetype="pan:*" | stats dc(sourcetype) + $time.earliest$ + $time.latest$ + + + + + + + + + + + + + + + + + + + + + + + + + index="_internal" log_level="ERROR" pan | stats dc(event_message) + $time.earliest$ + $time.latest$ + + + + + + + + + + + + + + + + + + + + + + + + + Sourcetypes Detected + + + sourcetype="pan:*" | stats latest(_time) as Time, count by sourcetype | eval Last Seen=strftime(Time,"%Y-%m-%d %H:%M:%S") | table sourcetype, count, "Last Seen" | sort by count desc + $time.earliest$ + $time.latest$ + +
+
+
+ + + Internal Log Error Messages + + + index="_internal" log_level="ERROR" pan | stats count by event_message, source + $time.earliest$ + $time.latest$ + + +
+
+
+ + + + + | rest /services/apps/local/SplunkforPaloAltoNetworks | fields version + -24h@h + now + + + + + + + + + + | rest /services/apps/local/Splunk_TA_paloalto | fields version + -24h@h + now + + + + + + + +
\ No newline at end of file diff --git a/demo/README.md b/demo/README.md index 9f393c88..eba312b4 100644 --- a/demo/README.md +++ b/demo/README.md @@ -57,7 +57,7 @@ After installation, the server is running. ## License -You can run the demo unlicnesed or with a license. +You can run the demo unlicensed or with a license. **Unlicensed**