Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ verify: ## Stack status then Splunk MCP client verify
@$(MAKE) status
@$(MAKE) verify-mcp-remote

validate-s4r-dashboard: ## Validate Buttercup dashboard panel SPL via Splunk MCP
@./scripts/validate-s4r-dashboard-queries.sh

s4r-attack-nk-enable: ## Enable NK purchase-attack Eventgen stanza (then: make restart)
@./scripts/toggle-s4r-attack-nk.sh enable

Expand Down
3 changes: 2 additions & 1 deletion SA-S4R/default/data/ui/nav/default.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<!-- Matches Splunk barebones app template ($SPLUNK_HOME/share/splunk/app_templates/barebones/...). -->
<nav search_view="search" color="#1A1C24">
<nav search_view="search" color="#791CF8">
<view name="search" default="true" />
<view name="buttercup_operations_dashboard" />
<view name="analytics_workspace" />
<view name="datasets" />
<view name="reports" />
Expand Down
303 changes: 303 additions & 0 deletions SA-S4R/default/data/ui/views/buttercup_operations_dashboard.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,303 @@
<dashboard version="2" theme="dark">
<label>Buttercup Enterprises — Operations Dashboard</label>
<description>Multi-team Dashboard Studio view for Buttercup Enterprises workshop data (SA-S4R). Global time range defaults to the last hour; searches refresh every minute.</description>
<definition><![CDATA[
{
"title": "Buttercup Enterprises \u2014 Operations Dashboard",
"description": "Multi-team operations dashboard for IT Operations, DevOps, Business Analytics, and Security & Fraud. Panels 4 and 5 contain sensitive revenue and geographic data; restrict dashboard access via Splunk roles.",
"inputs": {
"input_global_trp": {
"type": "input.timerange",
"title": "Global Time Range",
"options": {
"token": "global_time",
"defaultValue": "-1h,now"
}
}
},
"defaults": {
"dataSources": {
"ds.search": {
"options": {
"queryParameters": {
"earliest": "$global_time.earliest$",
"latest": "$global_time.latest$"
},
"refresh": "1m",
"refreshType": "delay"
}
}
},
"visualizations": {
"global": {
"showProgressBar": true,
"showLastUpdated": true
}
}
},
"dataSources": {
"ds_itops_status": {
"type": "ds.search",
"name": "IT Ops status codes",
"options": {
"query": "index=main sourcetype=access_combined\n| timechart count by status limit=10"
}
},
"ds_devops_platform": {
"type": "ds.search",
"name": "DevOps top platforms",
"options": {
"query": "index=main sourcetype=access_combined\n| eval platform=if(isnull(platform),\"Other\",platform)\n| top limit=20 platform showperc=f"
}
},
"ds_devops_browser_failures": {
"type": "ds.search",
"name": "DevOps browser failures",
"options": {
"query": "index=main sourcetype=access_combined status>=400\n| timechart count by useragent limit=5 useother=f"
}
},
"ds_business_lost_revenue": {
"type": "ds.search",
"name": "Business lost revenue",
"options": {
"query": "index=main sourcetype=access_combined action=purchase status>=400\n| lookup product_codes.csv product_id\n| timechart sum(product_price)"
}
},
"ds_security_geo": {
"type": "ds.search",
"name": "Security geographic activity",
"options": {
"query": "index=main sourcetype=access_combined\n| iplocation clientip\n| geostats count by City"
}
}
},
"visualizations": {
"viz_itops_status": {
"type": "splunk.column",
"title": "IT Ops - Web Server Status Codes Over Time",
"description": "Successful vs unsuccessful web server requests over time.",
"dataSources": {
"primary": "ds_itops_status"
},
"options": {
"stackMode": "stacked",
"legendDisplay": "bottom",
"xAxisTitleText": "Time",
"yAxisTitleText": "Request count",
"backgroundColor": "transparent"
},
"containerOptions": {
"title": {
"color": "#FFFFFF"
},
"description": {
"color": "#E0E0E0"
}
}
},
"viz_devops_platform": {
"type": "splunk.bar",
"title": "DevOps - Top 20 Customer Platforms",
"description": "Most common customer operating systems and devices.",
"dataSources": {
"primary": "ds_devops_platform"
},
"options": {
"orientation": "horizontal",
"legendDisplay": "off",
"xAxisTitleText": "Count",
"yAxisTitleText": "Platform",
"backgroundColor": "transparent"
},
"containerOptions": {
"title": {
"color": "#FFFFFF"
},
"description": {
"color": "#E0E0E0"
}
}
},
"viz_devops_browser_failures": {
"type": "splunk.line",
"title": "DevOps - Browser Failures Over Time",
"description": "Web browsers experiencing the most HTTP 4xx/5xx failures.",
"dataSources": {
"primary": "ds_devops_browser_failures"
},
"options": {
"legendDisplay": "bottom",
"xAxisTitleText": "Time",
"yAxisTitleText": "Failure count",
"backgroundColor": "transparent"
},
"containerOptions": {
"title": {
"color": "#FFFFFF"
},
"description": {
"color": "#E0E0E0"
}
}
},
"viz_business_lost_revenue": {
"type": "splunk.area",
"title": "Business Analytics - Lost Revenue from Failed Purchases",
"description": "Financial impact of failed purchases over time (USD). Sensitive panel.",
"dataSources": {
"primary": "ds_business_lost_revenue"
},
"options": {
"legendDisplay": "off",
"xAxisTitleText": "Time",
"yAxisTitleText": "Lost revenue (USD)",
"backgroundColor": "transparent"
},
"containerOptions": {
"title": {
"color": "#FFFFFF"
},
"description": {
"color": "#E0E0E0"
}
}
},
"viz_security_geo": {
"type": "splunk.map",
"title": "Security & Fraud - Geographic Activity Heat Map",
"description": "City-level website activity to identify unusual geographic patterns. Sensitive panel.",
"dataSources": {
"primary": "ds_security_geo"
},
"options": {
"center": [
39.8283,
-98.5795
],
"zoom": 3,
"backgroundColor": "transparent",
"showBaseLayer": true,
"baseLayerTileServer": "https://api.maptiler.com/maps/outdoor/{z}/{x}/{y}.png?key=NmOL38t5MnH6pNq8if7p",
"baseLayerTileServerType": "raster",
"layers": [
{
"type": "bubble",
"bubbleSize": "> primary | frameWithoutSeriesNames('geobin', 'latitude', 'longitude') | frameBySeriesTypes('number')",
"dataValues": "> primary | frameBySeriesTypes('number')"
}
]
},
"context": {
"dataColorsEditorConfig": [
{
"to": 100,
"value": "#61CAFA"
},
{
"from": 100,
"to": 500,
"value": "#FAE75F"
},
{
"from": 500,
"value": "#EC4B43"
}
]
},
"containerOptions": {
"title": {
"color": "#FFFFFF"
},
"description": {
"color": "#E0E0E0"
}
}
}
},
"layout": {
"options": {
"submitButton": false,
"showTitleAndDescription": true
},
"globalInputs": [
"input_global_trp"
],
"tabs": {
"options": {
"showTabBar": false
},
"items": [
{
"label": "Operations",
"layoutId": "layout_main"
}
]
},
"layoutDefinitions": {
"layout_main": {
"type": "absolute",
"options": {
"width": 1440,
"height": 1020,
"display": "auto-scale",
"backgroundColor": "#791CF8"
},
"structure": [
{
"type": "block",
"item": "viz_itops_status",
"position": {
"x": 20,
"y": 90,
"w": 690,
"h": 300
}
},
{
"type": "block",
"item": "viz_devops_platform",
"position": {
"x": 730,
"y": 90,
"w": 690,
"h": 300
}
},
{
"type": "block",
"item": "viz_devops_browser_failures",
"position": {
"x": 20,
"y": 410,
"w": 690,
"h": 280
}
},
{
"type": "block",
"item": "viz_business_lost_revenue",
"position": {
"x": 730,
"y": 410,
"w": 690,
"h": 280
}
},
{
"type": "block",
"item": "viz_security_geo",
"position": {
"x": 20,
"y": 710,
"w": 1400,
"h": 290
}
}
]
}
}
}
}
]]></definition>
</dashboard>
1 change: 1 addition & 0 deletions SA-S4R/default/props.conf
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ EXTRACT-action = action=(?<action>[^&\s"]+)
EXTRACT-product_id = product_id=(?<product_id>[^&\s"]+)
EXTRACT-uid = uid=(?<uid>[^&\s"]+)
EXTRACT-JSESSIONID = JSESSIONID=(?<JSESSIONID>[^&\s"]+)
EXTRACT-platform = \((?<platform>Linux; Android [0-9.]+|Macintosh; Intel Mac OS X [0-9_]+|Windows|iPhone; CPU iPhone OS [0-9_]+)
4 changes: 4 additions & 0 deletions SA-S4R/metadata/default.meta
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@ export = system
[lookup-table-files/product_codes.csv]
access = read : [ * ], write : [ admin, sc_admin ]
export = system

[views/buttercup_operations_dashboard]
access = read : [ admin, sc_admin, power, user ], write : [ admin, sc_admin ]
export = none
1 change: 1 addition & 0 deletions docs/S4R-DASHBOARD.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ Tasks:
- Eventgen in this repo emits workshop-shaped traffic (~67% `/product.screen`, ~33% `/cart.do`) so panel ratios and errors should look plausible after a few minutes of ingestion.
- **Workshop modes:** default data supports **infrastructure failure** (Lab 3–5). Optional **`make s4r-attack-nk-enable`** + **`make restart`** adds NK geo concentration for Lab 6 / “threat vs infrastructure” agent demos — see [SA-S4R-APP.md](SA-S4R-APP.md).
- Prefer shipping dashboard JSON/XML under `SA-S4R/default/data/ui/views/` when automating; keep background reference as a dashboard asset path above.
- Shipped dashboard: **`SA-S4R/default/data/ui/views/buttercup_operations_dashboard.xml`** (Dashboard Studio, indigo `#791CF8` background, last-hour default, 1m refresh). Validate panel SPL: **`make validate-s4r-dashboard`** (requires Splunk MCP).

## References

Expand Down
Loading
Loading