Skip to content
Merged
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
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@ Versions follow [Semantic Versioning](https://semver.org). The newest entry must
match `metadata.version` in `SKILL.md` and `__version__`/`VERSION` in both
scripts (checked by `tests/test_skill_package.py`).

## [2.2.0] - 2026-10-28

### Added

- `--image REF` takes the Splunk version from a container image tag (`splunk/splunk:9.4.2`, `10.6.1-rhel9`, registry ports and digests handled). `latest`, untagged images and unexpanded variables produce a warning and skip the compatibility check; combining it with `--splunk-version` is a usage error.
- `--cloud` restricts the choice to releases marked Splunk Cloud compatible, and the JSON output gains a `cloud_compatible` field (`true`, `false` or `null`). Both scripts, with contract tests for each.
- Live API check that `cloud_compatible` is still a boolean on releases.

### Fixed

- The skill description claimed Kubernetes support. It only produces `SPLUNK_APPS_URL` values for the `splunk/splunk` image under Docker or Docker Compose; the Splunk Operator installs apps from object storage. The description, routing rules and Docker reference now say so.
- Docker reference verified against docker-splunk, Docker Hub and the Splunk Operator docs: `SPLUNK_GENERAL_TERMS` is required only from 10.x images, `linux/amd64` is the only published architecture, and an unverified claim about `@splunk.com` logins is removed.

## [2.1.1] - 2026-10-28

### Changed
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ The scripts work without Claude. Python 3.9+ (standard library only):
python3 scripts/splunkbase_urls.py 4353 7931 # comma-separated URLs
python3 scripts/splunkbase_urls.py --format env 4353 7931 # SPLUNK_APPS_URL=...
python3 scripts/splunkbase_urls.py --splunk-version 9.4 4353 # newest release supporting Splunk 9.4
python3 scripts/splunkbase_urls.py --image splunk/splunk:9.4.2 4353 # same, version read from the image tag
python3 scripts/splunkbase_urls.py --cloud 4353 # only Splunk Cloud compatible releases
python3 scripts/splunkbase_urls.py --format json 4353 # app, version, compatibility, warnings
python3 scripts/splunkbase_urls.py --search "config explorer" # find IDs by name
```

`scripts/get_splunkbase_urls.sh` (needs `curl` and `jq`, works with macOS bash 3.2) provides the same options except `--search`.
`scripts/get_splunkbase_urls.sh` (needs `curl` and `jq`, works with macOS bash 3.2) provides the same options except `--search` and the `table` format.

Exit status: `0` all resolved, `1` at least one app failed (nothing on stdout unless `--partial`), `2` bad arguments. Warnings go to stderr.

Expand Down
24 changes: 19 additions & 5 deletions SKILL.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
name: splunkbase-skill
description: Resolve Splunkbase apps to their current download URLs, optionally for a specific Splunk version, and find app IDs by name. Use when the user wants the latest release URL of a Splunkbase app or add-on, needs SPLUNK_APPS_URL for splunk/splunk Docker Compose or Kubernetes deployments, asks which Splunkbase release supports their Splunk version, or gives a splunkbase.splunk.com link or app ID. Route app lifecycle, upgrade, or removal advice and general product questions to their owning workflows.
description: Resolve Splunkbase apps to their current download URLs, optionally for a specific Splunk version, and find app IDs by name. Use when the user wants the latest release URL of a Splunkbase app or add-on, needs SPLUNK_APPS_URL for splunk/splunk Docker or Docker Compose deployments, asks which Splunkbase release supports their Splunk version, or gives a splunkbase.splunk.com link or app ID. Route app lifecycle, upgrade, or removal advice and general product questions to their owning workflows.
license: Apache-2.0
metadata:
version: 2.1.1
version: 2.2.0
splunk:
domain: splunkbase-release-resolution
products:
Expand All @@ -22,6 +22,7 @@ metadata:
- splunkbase.splunk.com app link
not-for:
- installing, upgrading, disabling, or removing an app in a deployment
- Splunk Operator for Kubernetes app installs (its App Framework reads packages from object storage)
- app lifecycle, compatibility readiness, or removal-safety assessment
- general Splunk product questions
- downloading app packages or handling Splunkbase credentials
Expand Down Expand Up @@ -63,7 +64,9 @@ Route elsewhere, and say so, when the request is really about:
deployment, AppInspect results, or lifecycle planning: use an app and
add-on lifecycle skill or the product documentation;
- general Splunk product questions;
- performing the installation or download: this skill only resolves URLs.
- performing the installation or download: this skill only resolves URLs;
- Kubernetes with the Splunk Operator: its App Framework installs from S3, Azure
Blob or GCP buckets, not from Splunkbase URLs, so `SPLUNK_APPS_URL` does not apply.

## Workflow

Expand All @@ -81,10 +84,17 @@ Route elsewhere, and say so, when the request is really about:
python3 scripts/splunkbase_urls.py 4353 7931 # comma-separated URLs
python3 scripts/splunkbase_urls.py --format env 4353 7931 # SPLUNK_APPS_URL=...
python3 scripts/splunkbase_urls.py --format json --splunk-version 9.4 4353
python3 scripts/splunkbase_urls.py --image splunk/splunk:9.4.2 4353 7931 # version from the image tag
python3 scripts/splunkbase_urls.py --cloud 4353 # only Splunk Cloud compatible releases
```

Pass `--splunk-version` whenever the Splunk version is known, so the script
picks the newest release that supports it rather than the newest overall.
Pass the Splunk version whenever it is known, so the script picks the newest
release that supports it rather than the newest overall. When a compose file
or `docker run` command names the image, pass it with `--image`; the script
reads the tag (`9.4.2` becomes 9.4). A tag such as `latest`, a digest or an
unexpanded `${VARIABLE}` pins nothing: the script warns and skips the check,
so resolve the variable from the file or `.env`, or ask, and use
`--splunk-version`. `--image` and `--splunk-version` cannot be combined.
Without Python, `scripts/get_splunkbase_urls.sh` gives the same results
(no `--search`).

Expand Down Expand Up @@ -136,6 +146,10 @@ Answer shape for each app: ID and title, resolved version, `compatibility`
later or have the user run the command.
- **URL later returns 401/403 in the container:** credentials or licence
acceptance on the Splunkbase account, see the Docker reference.
- **`warning: image ... does not pin a Splunk version`:** the tag is `latest`,
missing or a variable; compatibility was not checked. Find the real version.
- **`no release is marked Splunk Cloud compatible`:** `--cloud` found no release
flagged `cloud_compatible`; the flag is the app author's, so verify on Splunkbase.
- **Reproducibility:** `latest` moves. Suggest pinning the resolved versions
and re-running on upgrades.

Expand Down
25 changes: 20 additions & 5 deletions references/docker-compose.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
# Installing Splunkbase apps in the `splunk/splunk` image

The container downloads each URL in `SPLUNK_APPS_URL` at start-up, authenticating
with your Splunkbase account.
with your Splunkbase account. This applies to the `splunk/splunk` image run with
Docker or Docker Compose. It does not apply to the Splunk Operator for Kubernetes:
its App Framework installs app packages from S3, Azure Blob or GCP storage, so
download the packages (needs a Splunkbase login) and host them there instead.

Verified 2026-10-28 against the docker-splunk repository (`README.md`,
`docs/advanced/APP_INSTALL.md`, `uf/common-files/entrypoint.sh`), Docker Hub tags
and the Splunk Operator `docs/operate/AppFramework.md`.

## Compose example

Expand All @@ -11,7 +18,7 @@ services:
image: splunk/splunk:${SPLUNK_VERSION:-9.4}
platform: linux/amd64 # the image has no arm64 build; needed on Apple silicon
environment:
SPLUNK_GENERAL_TERMS: --accept-sgt-current-at-splunk-com
SPLUNK_GENERAL_TERMS: --accept-sgt-current-at-splunk-com # required by 10.x images, ignored by 9.x
SPLUNK_START_ARGS: --accept-license
SPLUNK_PASSWORD: ${SPLUNK_PASSWORD}
SPLUNKBASE_USERNAME: ${SPLUNKBASE_USERNAME}
Expand All @@ -24,7 +31,7 @@ services:
Generate the value and keep credentials in an untracked `.env`:

```bash
python3 scripts/splunkbase_urls.py --format env --splunk-version 9.4 4353 7931 >> .env
python3 scripts/splunkbase_urls.py --format env --image splunk/splunk:9.4 4353 7931 >> .env
cat >> .env <<'ENV'
SPLUNK_PASSWORD=change-me-please
SPLUNKBASE_USERNAME=you@example.com
Expand All @@ -36,8 +43,15 @@ echo ".env" >> .gitignore
Notes:

- `SPLUNK_APPS_URL` is comma-separated with no spaces.
- Use your own Splunkbase login name; it is not necessarily an `@splunk.com` address.
- Match `--splunk-version` to the image tag so apps are compatible with the container.
- Use your own Splunkbase account credentials.
- Match the Splunk version to the image tag so apps are compatible with the
container: `--image` reads it from the tag, or pass `--splunk-version`. If the
compose file uses `${SPLUNK_VERSION:-9.4}`, expand the variable first.
- Image tags look like `9.4`, `9.4.2`, `10.6.1.1` and `10.6.1-rhel9`, plus `latest`.
Splunkbase tracks compatibility as major.minor, so `10.6.1.1` is treated as 10.6.
- `SPLUNK_START_ARGS: --accept-license` is required on every container. From 10.x
images `SPLUNK_GENERAL_TERMS: --accept-sgt-current-at-splunk-com` is required
too. Accepting is the user's decision; do not add it silently.
- Re-run the script when upgrading; the URLs pin exact versions.

## Troubleshooting
Expand All @@ -48,3 +62,4 @@ Notes:
| "No such file" or garbled filename | Platform-specific release name (see the warning from the script); pick the intended build |
| App installed but disabled or erroring | App does not support the Splunk version in the image; re-run with `--splunk-version` |
| Slow start on Apple silicon | `linux/amd64` runs under emulation |
| Container exits at once with "License not accepted" | `SPLUNK_START_ARGS` and, on 10.x, `SPLUNK_GENERAL_TERMS` are missing |
3 changes: 3 additions & 0 deletions references/sources.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ itself is unofficial; see [api.md](api.md) for what was verified directly.
| Topic | Source |
|-------|--------|
| `splunk/splunk` image, `SPLUNK_APPS_URL`, `SPLUNKBASE_USERNAME`/`SPLUNKBASE_PASSWORD` | https://splunk.github.io/docker-splunk/ and https://github.com/splunk/docker-splunk |
| `SPLUNK_GENERAL_TERMS` (10.x), license acceptance, comma-separated `SPLUNK_APPS_URL`, credentials | https://github.com/splunk/docker-splunk (`README.md`, `docs/advanced/APP_INSTALL.md`, `uf/common-files/entrypoint.sh`) |
| Image tags and architectures (`linux/amd64` only) | https://hub.docker.com/r/splunk/splunk/tags |
| Kubernetes app installs (object storage, not Splunkbase URLs) | https://github.com/splunk/splunk-operator (`docs/operate/AppFramework.md`) |
| App management and packaging | https://dev.splunk.com/enterprise/docs/developapps/manageapps/ |
| Splunk product documentation | https://help.splunk.com |
| Official Splunk agent skills (lifecycle, product questions) | https://github.com/splunk/splunk-agent-skills |
Expand Down
49 changes: 39 additions & 10 deletions scripts/get_splunkbase_urls.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

set -euo pipefail

VERSION="2.1.1"
VERSION="2.2.0"
BASE_URL="${SPLUNKBASE_BASE_URL:-https://splunkbase.splunk.com}"
BASE_URL="${BASE_URL%/}"
TIMEOUT=10
Expand All @@ -31,6 +31,10 @@ APP is a Splunkbase app ID or app page URL (commas allowed: 4353,7931).
Options:
--splunk-version VER only pick releases supporting this Splunk version
(e.g. 9.4 or 10.2.1)
--image REF take the Splunk version from a container image tag
(e.g. splunk/splunk:9.4.2); latest or untagged
images are not checked
--cloud only pick releases marked Splunk Cloud compatible
--format FMT urls (default): comma-separated
env: SPLUNK_APPS_URL=...
json
Expand Down Expand Up @@ -100,16 +104,19 @@ def tidy: gsub("[\\p{Cc}\\p{Zl}\\p{Zp}]+"; " ") | gsub("\\s+"; " ") | gsub("^ |
def supported: if length > 0 then "\(.[-1]) to \(.[0])" else "unknown" end;
($rel | map(select(type == "object" and (.name | type) == "string"
and ((.name | ascii_downcase | clean) as $n
| ($n == "" or $n == "null" or $n == "none") | not)))) as $usable
| if ($usable | length) == 0 then
| ($n == "" or $n == "null" or $n == "none") | not)))) as $downloadable
| (if $cloud == "1" then $downloadable | map(select(.cloud_compatible == true)) else $downloadable end) as $usable
| if ($downloadable | length) == 0 then
{error: "no downloadable release (the release has no version name, so no download URL can be built)"}
elif ($usable | length) == 0 then
{error: "no release is marked Splunk Cloud compatible"}
else
(if $sv == "" then {r: $usable[0], c: "not-checked", w: []}
else
([ $usable[] | select(((.product_versions // []) | any(. == $sv))
or ((.product_versions // []) | length) == 0) ] | .[0]) as $pick
| if $pick == null then
{error: "no release is compatible with Splunk \($sv) (latest is \($usable[0].name), which supports \(($usable[0].product_versions // []) | supported))"}
{error: "no release is compatible with Splunk \($sv)\(if $cloud == "1" then " among Splunk Cloud compatible releases" else "" end) (latest is \($usable[0].name), which supports \(($usable[0].product_versions // []) | supported))"}
elif ($pick.product_versions // []) | any(. == $sv) then
{r: $pick, c: "compatible", w: []}
else
Expand All @@ -127,17 +134,18 @@ def supported: if length > 0 then "\(.[-1]) to \(.[0])" else "unknown" end;
published: (.r.published_datetime // null),
splunk_versions: (.r.product_versions // []),
compatibility: .c,
cloud_compatible: (if (.r.cloud_compatible | type) == "boolean" then .r.cloud_compatible else null end),
warnings: (.w
+ (if $app.is_archived then ["app is archived on Splunkbase"] else [] end)
+ (if ($v | test("^[0-9][A-Za-z0-9_.+-]*$")) then [] else
["release name \"\($v | tidy)\" has extra text; it may be a platform-specific build, check it is the one you need"] end))}
end
end'

# resolve_app ID SPLUNK_VERSION -> one compact JSON object on stdout.
# resolve_app ID SPLUNK_VERSION CLOUD -> one compact JSON object on stdout.
# On failure prints an "error: ..." line to stderr and returns 1.
resolve_app() {
local id="$1" sv="$2" app rel rc title label out
local id="$1" sv="$2" cloud="$3" app rel rc title label out
rc=0
app="$(fetch_json "${BASE_URL}/api/v1/app/${id}")" || rc=$?
if [ "$rc" = 2 ]; then
Expand All @@ -164,7 +172,7 @@ resolve_app() {
fi

out="$(jq -c --argjson app "$app" --argjson rel "$rel" --arg id "$id" \
--arg sv "$sv" --arg base "$BASE_URL" "$JQ_RESOLVE" <<<null)"
--arg sv "$sv" --arg cloud "$cloud" --arg base "$BASE_URL" "$JQ_RESOLVE" <<<null)"
if jq -e 'has("error")' <<<"$out" >/dev/null; then
echo "error: ${label}: $(jq -r .error <<<"$out")" >&2
return 1
Expand All @@ -174,6 +182,8 @@ resolve_app() {

FORMAT="urls"
SPLUNK_VERSION=""
IMAGE=""
CLOUD=0
PARTIAL=0
QUIET=0
RAW_APPS=()
Expand All @@ -185,6 +195,10 @@ while [ $# -gt 0 ]; do
--splunk-version)
[ $# -ge 2 ] || die_usage "--splunk-version needs a value"
SPLUNK_VERSION="$2"; shift 2 ;;
--image)
[ $# -ge 2 ] || die_usage "--image needs a value"
IMAGE="$2"; shift 2 ;;
--cloud) CLOUD=1; shift ;;
--format)
[ $# -ge 2 ] || die_usage "--format needs a value"
FORMAT="$2"; shift 2 ;;
Expand All @@ -202,8 +216,23 @@ case "$FORMAT" in
esac
[ ${#RAW_APPS[@]} -gt 0 ] || die_usage "give at least one app ID"

if [ -n "$SPLUNK_VERSION" ]; then
sv_re='^([0-9]+)\.([0-9]+)(\.[A-Za-z0-9]+)*$'
sv_re='^([0-9]+)\.([0-9]+)(\.[A-Za-z0-9]+)*$'
if [ -n "$IMAGE" ]; then
[ -z "$SPLUNK_VERSION" ] || die_usage "use either --image or --splunk-version, not both"
image_name="${IMAGE%%@*}"
image_name="${image_name##*/}"
image_tag=""
if [[ "$image_name" == *:* ]]; then
image_tag="${image_name#*:}"
image_tag="${image_tag%%-*}"
fi
if [[ "$image_tag" =~ $sv_re ]]; then
SPLUNK_VERSION="${BASH_REMATCH[1]}.${BASH_REMATCH[2]}"
[ "$QUIET" = 1 ] || echo "note: using Splunk ${SPLUNK_VERSION} from image ${IMAGE}" >&2
else
warn "image ${IMAGE} does not pin a Splunk version; compatibility not checked"
fi
elif [ -n "$SPLUNK_VERSION" ]; then
if [[ "$SPLUNK_VERSION" =~ $sv_re ]]; then
SPLUNK_VERSION="${BASH_REMATCH[1]}.${BASH_REMATCH[2]}"
else
Expand Down Expand Up @@ -238,7 +267,7 @@ RESULTS="$(mktemp)"
trap 'rm -f "$RESULTS"' EXIT
failed=0
for id in "${APP_IDS[@]}"; do
if line="$(resolve_app "$id" "$SPLUNK_VERSION")"; then
if line="$(resolve_app "$id" "$SPLUNK_VERSION" "$CLOUD")"; then
echo "$line" >>"$RESULTS"
else
failed=1
Expand Down
Loading
Loading