Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ org_id = "your-staging-org-id"
```

**To get these values:**
1. **org_id**: Settings → Organization → Copy the org ID (or from URL: `app.axiom.co/{org_id}/...`)
2. **token**: Settings → Profile → Personal Access Tokens → Create token (use a Personal Access Token, not an API token, for full query access)
- **`org_id`** - The organization ID. Get it from Settings → Organization.
- **`token`** - Use an advanced API token with minimal privileges.

The deployment name (e.g., `prod`, `staging`) is passed to scripts: `scripts/axiom-query prod "..."`

Expand Down
3 changes: 2 additions & 1 deletion skills/building-dashboards/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ token = "xaat-your-api-token"
org_id = "your-org-id"
```

Get your org_id from Settings → Organization. For the token, use a **Personal Access Token** (Settings → Profile → Personal Access Tokens) for full query access.
- **`org_id`** - The organization ID. Get it from Settings → Organization.
- **`token`** - Use an advanced API token with minimal privileges.

**Tip:** Run `scripts/setup` from the `axiom-sre` skill for interactive configuration.

Expand Down
3 changes: 2 additions & 1 deletion skills/controlling-costs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ token = "xaat-your-api-token"
org_id = "your-org-id"
```

Get your org_id from Settings → Organization. For the token, use a **Personal Access Token** (Settings → Profile → Personal Access Tokens) for full query access.
- **`org_id`** - The organization ID. Get it from Settings → Organization.
- **`token`** - Use an advanced API token with minimal privileges.

**Tip:** Run `scripts/setup` from the `axiom-sre` skill for interactive configuration.

Expand Down
2 changes: 1 addition & 1 deletion skills/query-metrics/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ token = "xaat-your-api-token"
org_id = "your-org-id"
```

Get your org_id from Settings → Organization. For the token, use a **Personal Access Token** (Settings → Profile → Personal Access Tokens) for full query access.
Get your org_id from Settings → Organization. For the token, create a scoped **API token** (Settings → API Tokens) with the permissions your workflow needs. Avoid Personal Access Tokens for automated tooling.

**Tip:** Run `scripts/setup` from the `axiom-sre` skill for interactive configuration.

Expand Down
2 changes: 1 addition & 1 deletion skills/query-metrics/scripts/setup
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ org_id = "your-org-id"
EOF
echo ""
echo "Get your org_id from Settings → Organization."
echo "For the token, use a Personal Access Token (Settings → Profile → Personal Access Tokens)."
echo "For the token, create a scoped API token (Settings → API Tokens) with the permissions your workflow needs."
fi

echo ""
Expand Down
2 changes: 1 addition & 1 deletion skills/spl-to-apl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ token = "xaat-your-api-token"
org_id = "your-org-id"
```

Get your org_id from Settings → Organization. For the token, use a **Personal Access Token** (Settings → Profile → Personal Access Tokens) for full query access.
Get your org_id from Settings → Organization. For the token, create a scoped **API token** (Settings → API Tokens) with the permissions your workflow needs. Avoid Personal Access Tokens for automated tooling.

## Related Skills

Expand Down
2 changes: 1 addition & 1 deletion skills/sre/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ token = "xaat-your-api-token"
org_id = "your-org-id"
```

Get your org_id from Settings → Organization. For the token, use a **Personal Access Token** (Settings → Profile → Personal Access Tokens) for full query access.
Get your org_id from Settings → Organization. For the token, create a scoped **API token** (Settings → API Tokens) with the permissions your workflow needs. Avoid Personal Access Tokens for automated tooling.

## Usage

Expand Down
9 changes: 4 additions & 5 deletions skills/sre/reference/api-capabilities.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
# Axiom API Capabilities

Summary of all operations available via Axiom API with a personal access token (PAT).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes in skills/sre need to happen in gilfoyle first, and then they will be synced over automatically.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here it's: axiomhq/gilfoyle#15

Summary of all operations available via Axiom API.

**Base URL:** `https://api.axiom.co` (for all endpoints except ingestion)
**Ingest URL:** Use edge deployment domain (e.g., `https://us-east-1.aws.edge.axiom.co`)
**Base URL:** `https://api.axiom.co` (for management endpoints)
**Query & Ingest URL:** Auto-resolved per dataset via `scripts/resolve-url`

**Authentication:**
- PAT: `Authorization: Bearer $PAT` + `x-axiom-org-id: $ORG_ID`
- API Token: `Authorization: Bearer $API_TOKEN`
- `Authorization: Bearer $API_TOKEN` — use an advanced API token with minimal privileges

---

Expand Down
9 changes: 4 additions & 5 deletions skills/sre/reference/axiom.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
# Axiom API Capabilities

Summary of all operations available via Axiom API with a personal access token (PAT).
Summary of all operations available via Axiom API.

**Base URL:** `https://api.axiom.co` (for all endpoints except ingestion)
**Ingest URL:** Use edge deployment domain (e.g., `https://us-east-1.aws.edge.axiom.co`)
**Base URL:** `https://api.axiom.co` (for management endpoints)
**Query & Ingest URL:** Auto-resolved per dataset via `scripts/resolve-url`

**Authentication:**
- PAT: `Authorization: Bearer $PAT` + `x-axiom-org-id: $ORG_ID`
- API Token: `Authorization: Bearer $API_TOKEN`
- `Authorization: Bearer $API_TOKEN` — use an advanced API token with minimal privileges

---

Expand Down
24 changes: 22 additions & 2 deletions skills/sre/scripts/axiom-api
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,28 @@ fi
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
eval "$("$SCRIPT_DIR/config" axiom "$DEPLOYMENT")"

# Auto-resolve edge URL for query and ingest endpoints
REQUEST_URL="$AXIOM_URL"
case "$ENDPOINT" in
/v1/datasets/_apl*|/v1/ingest/*)
DATASET=""
if [[ "$ENDPOINT" == /v1/ingest/* ]]; then
DATASET="${ENDPOINT#/v1/ingest/}"
DATASET="${DATASET%%[?/]*}"
elif [[ -n "$BODY" ]]; then
DATASET=$(echo "$BODY" | jq -r '.apl // empty' 2>/dev/null | grep -oE "^\['[^']+'\]|^\[\"[^\"]+\"\]|^\[[a-zA-Z0-9_-]+\]" | head -1 | tr -d "[]'\"" || true)
fi
if [[ -n "$DATASET" ]]; then
RESOLVED=$("$SCRIPT_DIR/resolve-url" "$DEPLOYMENT" "$DATASET" 2>/dev/null || true)
if [[ -n "$RESOLVED" ]]; then
REQUEST_URL="$RESOLVED"
fi
fi
;;
esac

if [[ -n "$BODY" ]]; then
"$SCRIPT_DIR/curl-auth" axiom "$DEPLOYMENT" -X "$METHOD" -d "$BODY" "${AXIOM_URL}${ENDPOINT}"
"$SCRIPT_DIR/curl-auth" axiom "$DEPLOYMENT" -X "$METHOD" -d "$BODY" "${REQUEST_URL}${ENDPOINT}"
else
"$SCRIPT_DIR/curl-auth" axiom "$DEPLOYMENT" -X "$METHOD" "${AXIOM_URL}${ENDPOINT}"
"$SCRIPT_DIR/curl-auth" axiom "$DEPLOYMENT" -X "$METHOD" "${REQUEST_URL}${ENDPOINT}"
fi
2 changes: 1 addition & 1 deletion skills/sre/scripts/axiom-link
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ fi
# Derive web UI URL from configured API URL
# Replace "api." with "app." in the domain
# Examples:
# https://api.axiom.co → https://app.axiom.co
# https://api.staging.axiom.co → https://app.staging.axiom.co
# https://api.dev.axiom.co → https://app.dev.axiom.co
# https://cloud.axiom.co → https://app.axiom.co
# https://api.axiom.co → https://app.axiom.co
if [[ "$URL" == *"cloud.axiom.co"* ]]; then
BASE_URL="https://app.axiom.co"
elif [[ "$URL" == https://api.* ]]; then
Expand Down
12 changes: 11 additions & 1 deletion skills/sre/scripts/axiom-query
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,19 @@ cleanup() {
}
trap cleanup EXIT

# Auto-resolve edge URL
QUERY_URL="$AXIOM_URL"
DATASET=$(echo "$APL" | grep -oE "^\['[^']+'\]|^\[\"[^\"]+\"\]|^\[[a-zA-Z0-9_-]+\]" | head -1 | tr -d "[]'\"" || true)
if [[ -n "$DATASET" ]]; then
RESOLVED=$("$SCRIPT_DIR/resolve-url" "$DEPLOYMENT" "$DATASET" 2>/dev/null || true)
if [[ -n "$RESOLVED" ]]; then
QUERY_URL="$RESOLVED"
fi
fi

# Execute query and pipe to formatter
HTTP_CODE=$(curl -sS -o "$RESP_BODY" -D "$RESP_HEADERS" -w "%{http_code}" \
-X POST "$AXIOM_URL/v1/datasets/_apl?format=tabular" \
-X POST "$QUERY_URL/v1/datasets/_apl?format=tabular" \
-H "Authorization: Bearer $AXIOM_TOKEN" \
-H "X-Axiom-Org-Id: $AXIOM_ORG_ID" \
-H "Content-Type: application/json" \
Expand Down
89 changes: 89 additions & 0 deletions skills/sre/scripts/resolve-url
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#!/usr/bin/env bash
# resolve-url: Resolve the regional edge URL for a dataset
#
# Usage: resolve-url <deployment> <dataset>
#
# Two-step resolution:
# 1. GET /v1/datasets → find dataset's region (e.g. cloud.us-east-1.aws)
# 2. GET /api/internal/regions/axiom → map region to edge domain
#
# Both steps are cached to avoid repeated API calls.

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

DEPLOYMENT="${1:-}"
DATASET="${2:-}"

if [[ -z "$DEPLOYMENT" || -z "$DATASET" ]]; then
echo "Usage: resolve-url <deployment> <dataset>" >&2
exit 1
fi

CACHE_DIR="${TMPDIR:-/tmp}/axiom-edge-cache"

# Check dataset edge URL cache (valid for 1 hour)
DATASET_CACHE="$CACHE_DIR/edge__${DEPLOYMENT}__${DATASET}"
if [[ -f "$DATASET_CACHE" ]]; then
if [[ "$(uname)" == "Darwin" ]]; then
AGE=$(( $(date +%s) - $(stat -f %m "$DATASET_CACHE") ))
else
AGE=$(( $(date +%s) - $(stat -c %Y "$DATASET_CACHE") ))
fi
if [[ $AGE -lt 3600 ]]; then
cat "$DATASET_CACHE"
exit 0
fi
fi

# Load config to get the base URL as fallback
eval "$("$SCRIPT_DIR/config" axiom "$DEPLOYMENT")"

# Step 1: get dataset region
REGION=$("$SCRIPT_DIR/curl-auth" axiom "$DEPLOYMENT" -X GET "${AXIOM_URL}/v1/datasets" \
| jq -r --arg name "$DATASET" '.[] | select(.name == $name) | .region // empty' 2>/dev/null)

if [[ -z "$REGION" || "$REGION" == "null" ]]; then
echo "$AXIOM_URL"
exit 0
fi

# Step 2: look up edge domain from regions API (cached 24h per deployment)
REGIONS_CACHE="$CACHE_DIR/regions__${DEPLOYMENT}"
REGIONS_JSON=""
if [[ -f "$REGIONS_CACHE" ]]; then
if [[ "$(uname)" == "Darwin" ]]; then
AGE=$(( $(date +%s) - $(stat -f %m "$REGIONS_CACHE") ))
else
AGE=$(( $(date +%s) - $(stat -c %Y "$REGIONS_CACHE") ))
fi
if [[ $AGE -lt 86400 ]]; then
REGIONS_JSON=$(cat "$REGIONS_CACHE")
fi
fi

if [[ -z "$REGIONS_JSON" ]]; then
APP_URL="${AXIOM_URL/api./app.}"
REGIONS_JSON=$("$SCRIPT_DIR/curl-auth" axiom "$DEPLOYMENT" -X GET "${APP_URL}/api/internal/regions/axiom" 2>/dev/null) || true
if [[ -n "$REGIONS_JSON" ]]; then
mkdir -p "$CACHE_DIR"
echo "$REGIONS_JSON" > "$REGIONS_CACHE"
fi
fi

EDGE_DOMAIN=""
if [[ -n "$REGIONS_JSON" ]]; then
EDGE_DOMAIN=$(echo "$REGIONS_JSON" | jq -r --arg region "$REGION" '.axiom[] | select(.id == $region) | .domain // empty' 2>/dev/null)
fi

if [[ -z "$EDGE_DOMAIN" ]]; then
echo "$AXIOM_URL"
exit 0
fi

# Cache the resolved edge URL
mkdir -p "$CACHE_DIR"
echo "$EDGE_DOMAIN" > "$DATASET_CACHE"

echo "$EDGE_DOMAIN"