Switch to Edge Script + Bunny Database architecture for unlimited IP blocking
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>
This commit is contained in:
84
setup.py
Normal file
84
setup.py
Normal file
@@ -0,0 +1,84 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user