Replace Shield Access List (5,000 IP limit) with Bunny Database (libSQL) + Edge Script middleware to support CAPI community blocklists (tens of thousands of IPs). Bouncer now uses CrowdSec streaming API for incremental sync with periodic full resync every 6 hours. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
85 lines
2.6 KiB
Python
85 lines
2.6 KiB
Python
#!/usr/bin/env python3
|
|
"""One-time setup: deploy the Edge Script to Bunny CDN and publish a release."""
|
|
|
|
import os
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import requests
|
|
|
|
BUNNY_API_BASE = "https://api.bunny.net"
|
|
BUNNY_API_KEY = os.environ.get("BUNNY_API_KEY", "")
|
|
BUNNY_SCRIPT_ID = os.environ.get("BUNNY_SCRIPT_ID", "")
|
|
|
|
EDGE_SCRIPT_PATH = Path(__file__).parent / "edge-script" / "index.ts"
|
|
|
|
|
|
def api(method: str, path: str, **kwargs) -> requests.Response:
|
|
url = f"{BUNNY_API_BASE}{path}"
|
|
headers = kwargs.pop("headers", {})
|
|
headers["AccessKey"] = BUNNY_API_KEY
|
|
resp = requests.request(method, url, headers=headers, timeout=30, **kwargs)
|
|
if not resp.ok:
|
|
print(f"ERROR {resp.status_code}: {resp.text}", file=sys.stderr)
|
|
resp.raise_for_status()
|
|
return resp
|
|
|
|
|
|
def upload_code(script_id: str, code: str):
|
|
"""Upload edge script code via POST /compute/script/{id}/code."""
|
|
print(f"Uploading code to script {script_id} …")
|
|
api("POST", f"/compute/script/{script_id}/code", json={"Code": code})
|
|
print("Code uploaded.")
|
|
|
|
|
|
def publish(script_id: str):
|
|
"""Publish the current code as a release via POST /compute/script/{id}/publish."""
|
|
print(f"Publishing script {script_id} …")
|
|
api("POST", f"/compute/script/{script_id}/publish", json={"Note": "CrowdSec bouncer middleware"})
|
|
print("Published.")
|
|
|
|
|
|
def add_variable(script_id: str, name: str, value: str):
|
|
"""Add an environment variable via POST /compute/script/{id}/variables."""
|
|
print(f"Setting variable {name} …")
|
|
api(
|
|
"POST",
|
|
f"/compute/script/{script_id}/variables",
|
|
json={"Name": name, "DefaultValue": value, "Required": True},
|
|
)
|
|
print(f"Variable {name} set.")
|
|
|
|
|
|
def main():
|
|
if not BUNNY_API_KEY:
|
|
print("ERROR: BUNNY_API_KEY is required", file=sys.stderr)
|
|
sys.exit(1)
|
|
if not BUNNY_SCRIPT_ID:
|
|
print("ERROR: BUNNY_SCRIPT_ID is required", file=sys.stderr)
|
|
sys.exit(1)
|
|
if not EDGE_SCRIPT_PATH.exists():
|
|
print(f"ERROR: {EDGE_SCRIPT_PATH} not found", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
code = EDGE_SCRIPT_PATH.read_text()
|
|
|
|
print("=== CrowdSec Bunny Bouncer — Edge Script Deployment ===")
|
|
print(f"Script ID: {BUNNY_SCRIPT_ID}")
|
|
print(f"Code size: {len(code)} bytes")
|
|
print()
|
|
|
|
# Step 1: Upload code
|
|
upload_code(BUNNY_SCRIPT_ID, code)
|
|
|
|
# Step 2: Publish release
|
|
publish(BUNNY_SCRIPT_ID)
|
|
|
|
print()
|
|
print("Done! Make sure you have:")
|
|
print(" 1. Connected your Bunny Database to this Edge Script (DB_URL, DB_TOKEN secrets)")
|
|
print(" 2. Attached the Edge Script to your Pull Zone")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|