mirror of
https://github.com/trailofbits/buttercup
synced 2026-06-21 14:11:39 +00:00
Make deployment easier (#158)
* deployment: just use the value in values.template * ci: disable integration tests and private settings * Download trailofbits cscope, not aixcc-finals one * ci: fix docker login to ghcr.io * Changes to allow non aixcc deployment * buttercup-ui: basic skeleton for a CRS interface * file-server implementation * add ui to k8s * other apis * try to fix k8s * remove some labels * fix ui * small fixes to doc * ui: support for cloning private repos * Add setup scripts for easy deployment * update scripts * update make/readme * small adj * address review * we need 0.0.0.0 for k8s
This commit is contained in:
committed by
GitHub
parent
e2e5e45cee
commit
1d385cf89f
@@ -1,19 +1,128 @@
|
||||
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
|
||||
# Makefile for Trail of Bits AIxCC Finals CRS
|
||||
|
||||
HOST_CRS_SCRATCH = $(ROOT_DIR)/crs_scratch
|
||||
OSS_FUZZ_DIR = $(HOST_CRS_SCRATCH)/oss-fuzz
|
||||
.PHONY: help setup-local setup-production validate deploy deploy-local deploy-production test clean
|
||||
|
||||
local-volumes:
|
||||
mkdir -p $(HOST_CRS_SCRATCH)
|
||||
# Default target
|
||||
help:
|
||||
@echo "Trail of Bits AIxCC Finals CRS - Available Commands:"
|
||||
@echo ""
|
||||
@echo "Setup:"
|
||||
@echo " setup-local - Automated local development setup"
|
||||
@echo " setup-production - Automated production AKS setup"
|
||||
@echo " validate - Validate current setup and configuration"
|
||||
@echo ""
|
||||
@echo "Deployment:"
|
||||
@echo " deploy - Deploy to current environment (local or production)"
|
||||
@echo " deploy-local - Deploy to local Minikube environment"
|
||||
@echo " deploy-production - Deploy to production AKS environment"
|
||||
@echo ""
|
||||
@echo "Testing:"
|
||||
@echo " test - Run test task"
|
||||
@echo ""
|
||||
@echo "Development:"
|
||||
@echo " lint - Lint all Python code"
|
||||
@echo " lint-component - Lint specific component (e.g., make lint-component COMPONENT=orchestrator)"
|
||||
@echo ""
|
||||
@echo "Cleanup:"
|
||||
@echo " clean - Clean up deployment"
|
||||
@echo " clean-local - Clean up local environment"
|
||||
|
||||
oss-fuzz:
|
||||
test -d $(OSS_FUZZ_DIR) || git clone https://github.com/google/oss-fuzz.git $(OSS_FUZZ_DIR)
|
||||
# Setup targets
|
||||
setup-local:
|
||||
@echo "Setting up local development environment..."
|
||||
./scripts/setup-local.sh
|
||||
|
||||
up: local-volumes oss-fuzz
|
||||
docker compose up -d $(services)
|
||||
setup-production:
|
||||
@echo "Setting up production AKS environment..."
|
||||
./scripts/setup-production.sh
|
||||
|
||||
demo: local-volumes oss-fuzz
|
||||
TARGET_PACKAGE=nginx docker compose up -d $(services)
|
||||
validate:
|
||||
@echo "Validating setup..."
|
||||
./scripts/validate-setup.sh
|
||||
|
||||
down:
|
||||
docker compose down --remove-orphans
|
||||
# Deployment targets
|
||||
deploy:
|
||||
@echo "Deploying to current environment..."
|
||||
cd deployment && make up
|
||||
|
||||
wait-crs:
|
||||
@echo "Waiting for CRS deployment to be ready..."
|
||||
@if ! kubectl get namespace crs >/dev/null 2>&1; then \
|
||||
echo "Error: CRS namespace not found. Deploy first with 'make deploy'."; \
|
||||
exit 1; \
|
||||
fi
|
||||
@while true; do \
|
||||
PENDING=$$(kubectl get pods -n crs --no-headers 2>/dev/null | grep -v 'Completed' | grep -v 'Running' | wc -l); \
|
||||
if [ "$$PENDING" -eq 0 ]; then \
|
||||
echo "All CRS pods are running."; \
|
||||
break; \
|
||||
else \
|
||||
echo "$$PENDING pods are not yet running. Waiting..."; \
|
||||
sleep 5; \
|
||||
fi \
|
||||
done
|
||||
|
||||
crs-instance-id:
|
||||
@echo "Getting CRS instance ID..."
|
||||
@if ! kubectl get namespace crs >/dev/null 2>&1; then \
|
||||
echo "Error: CRS namespace not found. Deploy first with 'make deploy'."; \
|
||||
exit 1; \
|
||||
fi
|
||||
echo "CRS instance ID: $$(kubectl get configmap -n crs crs-instance-id -o jsonpath='{.data.crs-instance-id}')"
|
||||
|
||||
deploy-local:
|
||||
@echo "Deploying to local Minikube environment..."
|
||||
@if [ ! -f deployment/env ]; then \
|
||||
echo "Error: Configuration file not found. Run 'make setup-local' first."; \
|
||||
exit 1; \
|
||||
fi
|
||||
cd deployment && make up
|
||||
make crs-instance-id
|
||||
make wait-crs
|
||||
|
||||
deploy-production:
|
||||
@echo "Deploying to production AKS environment..."
|
||||
@if [ ! -f deployment/env ]; then \
|
||||
echo "Error: Configuration file not found. Run 'make setup-production' first."; \
|
||||
exit 1; \
|
||||
fi
|
||||
cd deployment && make up
|
||||
crs_instance_id=$$(make crs-instance-id)
|
||||
echo "CRS instance ID: $$crs_instance_id"
|
||||
make wait-crs
|
||||
|
||||
# Testing targets
|
||||
test:
|
||||
@echo "Running test task..."
|
||||
@if ! kubectl get namespace crs >/dev/null 2>&1; then \
|
||||
echo "Error: CRS namespace not found. Deploy first with 'make deploy'."; \
|
||||
exit 1; \
|
||||
fi
|
||||
kubectl port-forward -n crs service/buttercup-ui 31323:1323 &
|
||||
@sleep 3
|
||||
./orchestrator/scripts/task_integration_test.sh
|
||||
@pkill -f "kubectl port-forward" || true
|
||||
|
||||
# Development targets
|
||||
lint:
|
||||
@echo "Linting all Python code..."
|
||||
just lint-python-all
|
||||
|
||||
lint-component:
|
||||
@if [ -z "$(COMPONENT)" ]; then \
|
||||
echo "Error: COMPONENT not specified. Usage: make lint-component COMPONENT=<component>"; \
|
||||
echo "Available components: common, fuzzer, orchestrator, patcher, program-model, seed-gen"; \
|
||||
exit 1; \
|
||||
fi
|
||||
@echo "Linting $(COMPONENT)..."
|
||||
just lint-python $(COMPONENT)
|
||||
|
||||
# Cleanup targets
|
||||
clean:
|
||||
@echo "Cleaning up deployment..."
|
||||
cd deployment && make down
|
||||
|
||||
clean-local:
|
||||
@echo "Cleaning up local environment..."
|
||||
minikube delete || true
|
||||
rm -f deployment/env
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
# Quick Reference Guide
|
||||
|
||||
## Setup Commands
|
||||
|
||||
### Local Development
|
||||
```bash
|
||||
# Automated setup
|
||||
./scripts/setup-local.sh
|
||||
|
||||
# Manual setup
|
||||
cp deployment/env.template deployment/env
|
||||
# Edit deployment/env with your API keys
|
||||
cd deployment && make up
|
||||
```
|
||||
|
||||
### Production AKS
|
||||
```bash
|
||||
# Automated setup
|
||||
./scripts/setup-production.sh
|
||||
|
||||
# Manual setup
|
||||
az login --tenant aixcc.tech
|
||||
# Create service principal and configure deployment/env
|
||||
cd deployment && make up
|
||||
```
|
||||
|
||||
## Common Commands
|
||||
|
||||
### Kubernetes Management
|
||||
```bash
|
||||
# View all resources
|
||||
kubectl get pods -A
|
||||
kubectl get services -A
|
||||
kubectl get ingress -A
|
||||
|
||||
# View specific namespace
|
||||
kubectl get pods -n crs
|
||||
kubectl get services -n crs
|
||||
|
||||
# Port forwarding
|
||||
kubectl port-forward -n crs service/buttercup-competition-api 31323:1323
|
||||
|
||||
# View logs
|
||||
kubectl logs -n crs <pod-name>
|
||||
kubectl logs -n crs -l app=scheduler --tail=-1 --prefix
|
||||
|
||||
# Debug pods
|
||||
kubectl exec -it -n crs <pod-name> -- /bin/bash
|
||||
```
|
||||
|
||||
### Testing
|
||||
```bash
|
||||
# Send test task
|
||||
./orchestrator/scripts/task_crs.sh
|
||||
|
||||
# Send SARIF message
|
||||
./orchestrator/scripts/send_sarif.sh <TASK-ID>
|
||||
|
||||
# Run unscored challenges
|
||||
./orchestrator/scripts/challenge.sh
|
||||
```
|
||||
|
||||
### Development
|
||||
```bash
|
||||
# Lint Python code
|
||||
just lint-python-all
|
||||
just lint-python <component>
|
||||
|
||||
# Docker development
|
||||
docker-compose up -d
|
||||
docker-compose --profile fuzzer-test up
|
||||
```
|
||||
|
||||
### Minikube
|
||||
```bash
|
||||
# Start/stop
|
||||
minikube start --driver=docker
|
||||
minikube stop
|
||||
minikube delete
|
||||
|
||||
# Status
|
||||
minikube status
|
||||
minikube dashboard
|
||||
```
|
||||
|
||||
### Azure AKS
|
||||
```bash
|
||||
# Get credentials
|
||||
az aks get-credentials --name <cluster-name> --resource-group <resource-group>
|
||||
|
||||
# Scale cluster
|
||||
# Update TF_VAR_usr_node_count in deployment/env
|
||||
cd deployment && make up
|
||||
|
||||
# View cluster info
|
||||
az aks show --name <cluster-name> --resource-group <resource-group>
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
#### Minikube Issues
|
||||
```bash
|
||||
# Reset minikube
|
||||
minikube delete
|
||||
minikube start --driver=docker
|
||||
|
||||
# Check status
|
||||
minikube status
|
||||
kubectl cluster-info
|
||||
```
|
||||
|
||||
#### Docker Issues
|
||||
```bash
|
||||
# Permission issues
|
||||
sudo usermod -aG docker $USER
|
||||
# Log out and back in
|
||||
|
||||
# Check Docker daemon
|
||||
sudo systemctl status docker
|
||||
sudo systemctl start docker
|
||||
```
|
||||
|
||||
#### Helm Issues
|
||||
```bash
|
||||
# Update repositories
|
||||
helm repo update
|
||||
helm dependency update deployment/k8s/
|
||||
|
||||
# Check chart
|
||||
helm lint deployment/k8s/
|
||||
```
|
||||
|
||||
#### Azure Issues
|
||||
```bash
|
||||
# Authentication
|
||||
az login --tenant aixcc.tech
|
||||
az account set --subscription <subscription-id>
|
||||
|
||||
# Check service principal
|
||||
az ad sp list --display-name "ButtercupCRS*"
|
||||
```
|
||||
|
||||
#### Kubernetes Issues
|
||||
```bash
|
||||
# Check cluster connectivity
|
||||
kubectl cluster-info
|
||||
kubectl get nodes
|
||||
|
||||
# Check pods
|
||||
kubectl describe pod <pod-name> -n crs
|
||||
kubectl logs <pod-name> -n crs --previous
|
||||
|
||||
# Check events
|
||||
kubectl get events -n crs --sort-by='.lastTimestamp'
|
||||
```
|
||||
|
||||
### Log Analysis
|
||||
|
||||
#### Check Patch Submission
|
||||
```bash
|
||||
kubectl logs -n crs -l app=scheduler --tail=-1 --prefix | grep "WAIT_PATCH_PASS -> SUBMIT_BUNDLE"
|
||||
```
|
||||
|
||||
#### Check Competition API
|
||||
```bash
|
||||
kubectl logs -n crs -l app=competition-api --tail=-1 --prefix
|
||||
```
|
||||
|
||||
#### Check Fuzzer
|
||||
```bash
|
||||
kubectl logs -n crs -l app=fuzzer --tail=-1 --prefix
|
||||
```
|
||||
|
||||
## File Locations
|
||||
|
||||
### Configuration
|
||||
- `deployment/env` - Main configuration file
|
||||
- `deployment/env.template` - Configuration template
|
||||
- `deployment/k8s/values-*.template` - Kubernetes value templates
|
||||
|
||||
### Scripts
|
||||
- `scripts/setup-local.sh` - Local development setup
|
||||
- `scripts/setup-production.sh` - Production AKS setup
|
||||
- `orchestrator/scripts/` - Testing and task scripts
|
||||
|
||||
### Documentation
|
||||
- `README.md` - Main documentation
|
||||
- `deployment/README.md` - Detailed deployment guide
|
||||
|
||||
## Support
|
||||
|
||||
- Check logs: `kubectl logs -n crs <pod-name>`
|
||||
- View events: `kubectl get events -n crs`
|
||||
- Debug pods: `kubectl exec -it -n crs <pod-name> -- /bin/bash`
|
||||
- Monitor resources: `kubectl top pods -A`
|
||||
@@ -1,143 +1,319 @@
|
||||
# Trail of Bits AIxCC Finals CRS
|
||||
# Buttercup Cyber Reasoning System (CRS)
|
||||
|
||||
## Dependencies
|
||||
**Buttercup** is a Cyber Reasoning System (CRS) developed by **Trail of Bits** for the **DARPA AIxCC (AI Cyber Challenge) competition**. It's a comprehensive automated vulnerability detection and patching system designed to compete in AI-driven cybersecurity challenges.
|
||||
|
||||
## Quick Start
|
||||
|
||||
Clone the repo with `--recurse-submodules` as some dependencies are submodules.
|
||||
|
||||
Follow the install instructions for the required dependencies:
|
||||
Choose your deployment method:
|
||||
|
||||
* [Docker install guide](https://docs.docker.com/engine/install/ubuntu/)
|
||||
* [kubectl install guide](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/)
|
||||
* [helm install guide](https://helm.sh/docs/intro/install/):
|
||||
* [minikube install guide](https://minikube.sigs.k8s.io/docs/start/?arch=%2Flinux%2Fx86-64%2Fstable%2Fdebian+package)
|
||||
* Git LFS for some tests
|
||||
- **[Local Development](#local-development)** - Quick setup for development and testing
|
||||
- **[Production AKS Deployment](#production-aks-deployment)** - Full production deployment on Azure Kubernetes Service
|
||||
|
||||
## Configuration
|
||||
## Local Development
|
||||
|
||||
Create a new configuration file, starting from the default template:
|
||||
The fastest way to get started with the **Buttercup CRS** system for development and testing.
|
||||
|
||||
```shell
|
||||
cp \
|
||||
deployment/env.template \
|
||||
deployment/env
|
||||
### Quick Setup (Recommended)
|
||||
|
||||
Use our automated setup script:
|
||||
|
||||
```bash
|
||||
make setup-local
|
||||
```
|
||||
|
||||
Next, configure the following options. Follow the instructions in the comments when setting the `GHCR_AUTH` value.
|
||||
This script will install all dependencies, configure the environment, and guide you through the setup process.
|
||||
|
||||
```shell
|
||||
SCANTRON_GITHUB_PAT
|
||||
GHCR_AUTH
|
||||
OPENAI_API_KEY
|
||||
ANTHROPIC_API_KEY
|
||||
DOCKER_USERNAME
|
||||
DOCKER_PAT
|
||||
### Manual Setup
|
||||
|
||||
If you prefer to set up manually, follow these steps:
|
||||
|
||||
```bash
|
||||
# Docker
|
||||
curl -fsSL https://get.docker.com | sh
|
||||
sudo usermod -aG docker $USER
|
||||
# Log out and back in for group changes to take effect
|
||||
|
||||
# kubectl
|
||||
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
|
||||
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
|
||||
|
||||
# Helm
|
||||
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
|
||||
|
||||
# Minikube
|
||||
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
|
||||
sudo install minikube-linux-amd64 /usr/local/bin/minikube
|
||||
|
||||
# Git LFS (for some tests)
|
||||
sudo apt-get install git-lfs
|
||||
git lfs install
|
||||
```
|
||||
|
||||
### Settings specific to local development and testing
|
||||
#### Manual Configuration
|
||||
|
||||
Use the hardcoded test credentials found in the comments:
|
||||
1. **Create configuration file:**
|
||||
|
||||
```shell
|
||||
AZURE_ENABLED=false
|
||||
TAILSCALE_ENABLED=false
|
||||
COMPETITION_API_KEY_ID: `11111111-1111-1111-1111-111111111111`
|
||||
COMPETITION_API_KEY_TOKEN: `secret`
|
||||
CRS_KEY_ID="515cc8a0-3019-4c9f-8c1c-72d0b54ae561"
|
||||
CRS_KEY_TOKEN="VGuAC8axfOnFXKBB7irpNDOKcDjOlnyB"
|
||||
CRS_API_HOSTNAME="<generated with: openssl rand -hex 16>"
|
||||
BUTTERCUP_K8S_VALUES_TEMPLATE="k8s/values-minikube.template"
|
||||
OTEL_ENDPOINT="<insert endpoint url from aixcc vault, is pseudo secret>"
|
||||
OTEL_PROTOCOL="http"
|
||||
```bash
|
||||
cp deployment/env.template deployment/env
|
||||
```
|
||||
|
||||
Keep empty:
|
||||
2. **Configure the environment file** (`deployment/env`):
|
||||
|
||||
```shell
|
||||
AZURE_API_BASE=""
|
||||
AZURE_API_KEY=""
|
||||
Look at the comments in the `deployment/env.template` for how to set variables.
|
||||
|
||||
### Start Local Development Environment
|
||||
|
||||
1. **Start the services:**
|
||||
|
||||
```bash
|
||||
make deploy-local
|
||||
```
|
||||
|
||||
Commented out:
|
||||
2. **Verify deployment:**
|
||||
|
||||
```shell
|
||||
CRS_URL
|
||||
CRS_API_HOSTNAME
|
||||
LANGFUSE_HOST
|
||||
LANGFUSE_PUBLIC_KEY
|
||||
LANGFUSE_SECRET_KEY
|
||||
OTEL_TOKEN
|
||||
```bash
|
||||
kubectl get pods -n crs
|
||||
kubectl get services -n crs
|
||||
```
|
||||
|
||||
When [re-running unscored rounds](orchestrator/src/buttercup/orchestrator/mock_competition_api/README.md), set this to `true`:
|
||||
3. **Submit the integration-test challenge to the CRS (for 30mins):**
|
||||
|
||||
```shell
|
||||
MOCK_COMPETITION_API_ENABLED
|
||||
```bash
|
||||
make test
|
||||
```
|
||||
|
||||
## Authentication
|
||||
**Alternative manual commands:**
|
||||
|
||||
### Docker
|
||||
```bash
|
||||
# Start services manually
|
||||
cd deployment && make up
|
||||
|
||||
Log into ghcr.io:
|
||||
# Port forward manually
|
||||
kubectl port-forward -n crs service/buttercup-competition-api 31323:1323
|
||||
|
||||
```shell
|
||||
docker login ghcr.io -u <username>
|
||||
# Test manually
|
||||
./orchestrator/scripts/task_integration_test.sh
|
||||
```
|
||||
|
||||
## Running the CRS
|
||||
## Production AKS Deployment
|
||||
|
||||
### Starting the services
|
||||
> **⚠️ Notice:**
|
||||
> The following production deployment instructions have **not been fully tested**.
|
||||
> Please proceed with caution and verify each step in your environment.
|
||||
> If you encounter issues, consult the script comments and configuration files for troubleshooting.
|
||||
|
||||
```shell
|
||||
Full production deployment of the **Buttercup CRS** on Azure Kubernetes Service with proper networking, monitoring, and scaling for the DARPA AIxCC competition.
|
||||
|
||||
### Quick Setup (Recommended)
|
||||
|
||||
Use our automated setup script:
|
||||
|
||||
```bash
|
||||
make setup-production
|
||||
```
|
||||
|
||||
This script will check prerequisites, help create service principals, configure the environment, and validate your setup.
|
||||
|
||||
#### Manual Setup
|
||||
|
||||
If you prefer to set up manually, follow these steps:
|
||||
|
||||
##### Prerequisites
|
||||
|
||||
- Azure CLI installed and configured
|
||||
- Terraform installed
|
||||
- Active Azure subscription
|
||||
- Access to competition Tailscale tailnet
|
||||
|
||||
##### Azure Setup
|
||||
|
||||
1. **Login to Azure:**
|
||||
|
||||
```bash
|
||||
az login --tenant aixcc.tech
|
||||
```
|
||||
|
||||
2. **Create Service Principal:**
|
||||
|
||||
```bash
|
||||
# Get your subscription ID
|
||||
az account show --query "{SubscriptionID:id}" --output table
|
||||
|
||||
# Create service principal (replace with your subscription ID)
|
||||
az ad sp create-for-rbac --name "ButtercupCRS" --role Contributor --scopes /subscriptions/<YOUR-SUBSCRIPTION-ID>
|
||||
```
|
||||
|
||||
##### Production Configuration
|
||||
|
||||
1. **Configure environment file:**
|
||||
|
||||
```bash
|
||||
cp deployment/env.template deployment/env
|
||||
```
|
||||
|
||||
2. **Update `deployment/env` for production:**
|
||||
|
||||
Look at the comments in the `deployment/env.template` for how to set variables.
|
||||
In particular, set `TF_VAR_*` variables, and `TAILSCALE_*` if used.
|
||||
|
||||
### Deploy to AKS
|
||||
|
||||
**Deploy the cluster and services:**
|
||||
|
||||
```bash
|
||||
make deploy-production
|
||||
```
|
||||
|
||||
**Alternative manual command:**
|
||||
|
||||
```bash
|
||||
cd deployment && make up
|
||||
```
|
||||
|
||||
### Stopping the services
|
||||
### Scaling and Management
|
||||
|
||||
```shell
|
||||
- **Scale nodes:** Update `TF_VAR_usr_node_count` in your env file and run `make up`
|
||||
- **View logs:** `kubectl logs -n crs <pod-name>`
|
||||
- **Monitor resources:** `kubectl top pods -A`
|
||||
|
||||
## Cleanup
|
||||
|
||||
```bash
|
||||
make clean
|
||||
```
|
||||
|
||||
**Alternative manual command:**
|
||||
|
||||
```bash
|
||||
cd deployment && make down
|
||||
```
|
||||
|
||||
### Sending the example-libpng task to the system
|
||||
## Development Workflow
|
||||
|
||||
```shell
|
||||
kubectl port-forward -n crs service/buttercup-competition-api 31323:1323
|
||||
### Using Makefile Shortcuts
|
||||
|
||||
The **Buttercup CRS** project includes a Makefile with convenient shortcuts for common tasks:
|
||||
|
||||
```bash
|
||||
# View all available commands
|
||||
make help
|
||||
|
||||
# Setup
|
||||
make setup-local # Automated local setup
|
||||
make setup-production # Automated production setup
|
||||
make validate # Validate current setup
|
||||
|
||||
# Deployment
|
||||
make deploy # Deploy to current environment
|
||||
make deploy-local # Deploy to local Minikube
|
||||
make deploy-production # Deploy to production AKS
|
||||
|
||||
# Testing
|
||||
make test # Run test task
|
||||
|
||||
# Development
|
||||
make lint # Lint all Python code
|
||||
make lint-component COMPONENT=orchestrator # Lint specific component
|
||||
|
||||
# Cleanup
|
||||
make clean # Clean up deployment
|
||||
make clean-local # Clean up local environment
|
||||
```
|
||||
|
||||
```shell
|
||||
./orchestrator/scripts/task_crs.sh
|
||||
### Running Tests
|
||||
|
||||
```bash
|
||||
# Lint all Python code
|
||||
make lint
|
||||
|
||||
# Lint specific component
|
||||
make lint-component COMPONENT=orchestrator
|
||||
|
||||
# Run test task
|
||||
make test
|
||||
```
|
||||
|
||||
Send a SARIF message
|
||||
**Alternative manual commands:**
|
||||
|
||||
```shell
|
||||
./orchestrator/scripts/send_sarif.sh <TASK-ID-FROM-TASK-CRS>
|
||||
```
|
||||
```bash
|
||||
# Lint Python code
|
||||
just lint-python-all
|
||||
|
||||
### Simulating Unscored Round 2
|
||||
# Run specific component tests
|
||||
just lint-python orchestrator
|
||||
|
||||
```shell
|
||||
kubectl port-forward -n crs service/buttercup-competition-api 31323:1323
|
||||
```
|
||||
|
||||
```shell
|
||||
# Test manually
|
||||
./orchestrator/scripts/task_upstream_libpng.sh
|
||||
./orchestrator/scripts/challenge.sh
|
||||
```
|
||||
|
||||
Check that patches get submitted to the bundler.
|
||||
### Docker Development
|
||||
|
||||
```shell
|
||||
kubectl logs -n crs -l app=scheduler --tail=-1 --prefix | grep "WAIT_PATCH_PASS -> SUBMIT_BUNDLE"
|
||||
```bash
|
||||
# Build and run with Docker Compose (only for local development and quick testing)
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
If needing to debug, run the following to log into the pod.
|
||||
### Kubernetes Development
|
||||
|
||||
```shell
|
||||
kubectl get pods -n crs
|
||||
```bash
|
||||
# Port forward for local access
|
||||
kubectl port-forward -n crs service/buttercup-competition-api 31323:1323
|
||||
|
||||
# View logs
|
||||
kubectl logs -n crs -l app=scheduler --tail=-1 --prefix
|
||||
|
||||
# Debug pods
|
||||
kubectl exec -it -n crs <pod-name> -- /bin/bash
|
||||
```
|
||||
|
||||
## Run Unscored Challenges
|
||||
## Troubleshooting
|
||||
|
||||
See [UNSCORED.md](UNSCORED.md)
|
||||
### Common Issues
|
||||
|
||||
1. **Minikube won't start:**
|
||||
|
||||
```bash
|
||||
minikube delete
|
||||
```
|
||||
|
||||
2. **Docker permission issues:**
|
||||
|
||||
```bash
|
||||
sudo usermod -aG docker $USER
|
||||
# Log out and back in
|
||||
```
|
||||
|
||||
3. **Helm chart issues:**
|
||||
|
||||
```bash
|
||||
helm repo update
|
||||
helm dependency update deployment/k8s/
|
||||
```
|
||||
|
||||
4. **Azure authentication:**
|
||||
|
||||
```bash
|
||||
az login --tenant aixcc.tech
|
||||
az account set --subscription <your-subscription-id>
|
||||
```
|
||||
|
||||
### Getting Help
|
||||
|
||||
- **Validate your setup:** `make validate` - Check if your environment is ready
|
||||
- Check the [Quick Reference Guide](QUICK_REFERENCE.md) for common commands and troubleshooting
|
||||
- Check the [deployment README](deployment/README.md) for detailed deployment information
|
||||
- Check logs: `kubectl logs -n crs <pod-name>`
|
||||
|
||||
## Architecture
|
||||
|
||||
The **Buttercup CRS** system consists of several components designed to work together for automated vulnerability detection and patching:
|
||||
|
||||
- **Orchestrator**: Coordinates the overall repair process and manages the workflow
|
||||
- **Fuzzer**: Discovers vulnerabilities through intelligent fuzzing techniques
|
||||
- **Patcher**: Generates and applies security patches to fix vulnerabilities
|
||||
- **Program Model**: Analyzes code structure and semantics for better understanding
|
||||
- **Seed Generator**: Creates targeted test cases for vulnerability discovery
|
||||
- **Competition API**: Interfaces with the DARPA AIxCC competition platform
|
||||
|
||||
+27
-26
@@ -1,7 +1,7 @@
|
||||
# Reference a values file for kubernetes deployment. This should be a template
|
||||
# file, filled by crs-architecture.sh with the correct variables.
|
||||
# See values-upstream-minikube.template, values-minikube.template, values-aks.template, values-prod.template
|
||||
export BUTTERCUP_K8S_VALUES_TEMPLATE="k8s/values-minikube.template"
|
||||
export BUTTERCUP_K8S_VALUES_TEMPLATE="k8s/values-upstream-minikube.template"
|
||||
|
||||
# Namespace used to install the whole CRS in.
|
||||
export BUTTERCUP_NAMESPACE=crs
|
||||
@@ -16,29 +16,29 @@ export CLUSTER_TYPE=minikube # or "aks"
|
||||
|
||||
# These are terraform variables, necessary only for actual deployment in AKS
|
||||
# See README.md for instructions on how to set them up.
|
||||
export TF_VAR_ARM_CLIENT_ID="<your-client-id>"
|
||||
export TF_VAR_ARM_CLIENT_SECRET="<your-client-secret>"
|
||||
export TF_VAR_ARM_TENANT_ID="<your-tenant-id>"
|
||||
export TF_VAR_ARM_SUBSCRIPTION_ID="<your-sub-id>"
|
||||
export TF_VAR_usr_node_count=50
|
||||
export TF_VAR_resource_group_name_prefix="<resource-prefix>"
|
||||
# export TF_VAR_ARM_CLIENT_ID="<your-client-id>"
|
||||
# export TF_VAR_ARM_CLIENT_SECRET="<your-client-secret>"
|
||||
# export TF_VAR_ARM_TENANT_ID="<your-tenant-id>"
|
||||
# export TF_VAR_ARM_SUBSCRIPTION_ID="<your-sub-id>"
|
||||
# export TF_VAR_usr_node_count=50
|
||||
# export TF_VAR_resource_group_name_prefix="<resource-prefix>"
|
||||
|
||||
# TailScale variables, necessary only for production/staging deployments
|
||||
export TAILSCALE_ENABLED=false # or true
|
||||
export TS_CLIENT_ID="<your-tailscale-oauth-client-id>"
|
||||
export TS_CLIENT_SECRET="<your-tailscale-oauth-client-secret>"
|
||||
export TS_OP_TAG="<your-tailscale-operator-tag>"
|
||||
# export TS_CLIENT_ID="<your-tailscale-oauth-client-id>"
|
||||
# export TS_CLIENT_SECRET="<your-tailscale-oauth-client-secret>"
|
||||
# export TS_OP_TAG="<your-tailscale-operator-tag>"
|
||||
|
||||
# Competition API settings, used to properly connect to the right endpoint and
|
||||
# AIxCC - Competition API settings, used to properly connect to the right endpoint and
|
||||
# with the right authentication. If COMPETITION_API_ENABLED is true, a test API
|
||||
# will be deployed and configured according to the variables.
|
||||
# SCANTRON_GITHUB_PAT is a GitHub PAT with at least package:read and repo:write
|
||||
# permissions.
|
||||
export COMPETITION_API_ENABLED=true # or false
|
||||
export COMPETITION_API_KEY_ID="<your-competitionapi-key-id>" # 11111111-1111-1111-1111-111111111111
|
||||
export COMPETITION_API_KEY_TOKEN="<your-competition-api-key-token>" # secret
|
||||
# export COMPETITION_API_ENABLED=false # or true
|
||||
# export COMPETITION_API_KEY_ID="11111111-1111-1111-1111-111111111111"
|
||||
# export COMPETITION_API_KEY_TOKEN="secret"
|
||||
# export COMPETITION_API_URL="<competition-api-url>"
|
||||
export SCANTRON_GITHUB_PAT="<gh-pat-with-repo-read+packages-read>"
|
||||
# export SCANTRON_GITHUB_PAT="<gh-pat-with-repo-read+packages-read>"
|
||||
|
||||
# Start an additional pod for running challenges from blobs and in the same times and using same ids
|
||||
# as in the organized round. See the orchestrator/src/buttercup/orchestrator/mock_competition_api/README.md
|
||||
@@ -46,9 +46,9 @@ export SCANTRON_GITHUB_PAT="<gh-pat-with-repo-read+packages-read>"
|
||||
export MOCK_COMPETITION_API_ENABLED=false # or true
|
||||
|
||||
# CRS settings
|
||||
export CRS_KEY_ID="<your-crs-key-id>" # 515cc8a0-3019-4c9f-8c1c-72d0b54ae561
|
||||
export CRS_KEY_TOKEN="<your-crs-key-token>" # VGuAC8axfOnFXKBB7irpNDOKcDjOlnyB
|
||||
export CRS_KEY_TOKEN_HASH='<argon2-hash-for-crs-key-token>' # $argon2id$v=19$m=65536,t=3,p=4$Dg1v6NPGTyXPoOPF4ozD5A$wa/85ttk17bBsIASSwdR/uGz5UKN/bZuu4wu+JIy1iA
|
||||
export CRS_KEY_ID="515cc8a0-3019-4c9f-8c1c-72d0b54ae561"
|
||||
export CRS_KEY_TOKEN="VGuAC8axfOnFXKBB7irpNDOKcDjOlnyB"
|
||||
export CRS_KEY_TOKEN_HASH='$argon2id$v=19$m=65536,t=3,p=4$Dg1v6NPGTyXPoOPF4ozD5A$wa/85ttk17bBsIASSwdR/uGz5UKN/bZuu4wu+JIy1iA'
|
||||
# export CRS_URL="<your-crs-api-url>"
|
||||
# export CRS_API_HOSTNAME="<your-crs-api-hostname>"
|
||||
|
||||
@@ -58,9 +58,9 @@ export CRS_KEY_TOKEN_HASH='<argon2-hash-for-crs-key-token>' # $argon2id$v=19$m=6
|
||||
export GHCR_AUTH="<your-ghcr-base64-auth>"
|
||||
|
||||
# LiteLLM/LLMs settings
|
||||
export LITELLM_MASTER_KEY="<your-random-litellm-key>" # Generate with: openssl rand -hex 16
|
||||
export AZURE_API_BASE="<your-azure-openai-base-url>"
|
||||
export AZURE_API_KEY="<your-azure-openai-api-key>"
|
||||
export LITELLM_MASTER_KEY="d5179c62ae1c7366e3ee09775d0993d5" # Generate with: openssl rand -hex 16
|
||||
export AZURE_API_BASE="<disabled>"
|
||||
export AZURE_API_KEY="<disabled>"
|
||||
export OPENAI_API_KEY="<your-openai-api-key>"
|
||||
export ANTHROPIC_API_KEY="<your-anthropic-api-key>"
|
||||
|
||||
@@ -73,16 +73,17 @@ export ANTHROPIC_API_KEY="<your-anthropic-api-key>"
|
||||
# OpenTelemetry endpoint settings (e.g. SigNoz)
|
||||
# export OTEL_ENDPOINT="<your-otel-endpoint>"
|
||||
# export OTEL_TOKEN="<your-otel-http-token>"
|
||||
# export OTEL_PROTOCOL=grpc
|
||||
|
||||
# Docker Hub credentials for doing logged requests while getting Container
|
||||
# Images from DockerHub.
|
||||
export DOCKER_USERNAME="<your-docker-username>"
|
||||
export DOCKER_PAT="<your-docker-pat>"
|
||||
# Images from DockerHub. If not set, the system will perform unauthenticated requests.
|
||||
# export DOCKER_USERNAME="<your-docker-username>"
|
||||
# export DOCKER_PAT="<your-docker-pat>"
|
||||
|
||||
# Optionally modify the container image org part used for accessing challenges
|
||||
# containers. Use aixcc-afc by default, but modify this to use upstream oss-fuzz.
|
||||
# export FUZZ_TOOLING_CONTAINER_ORG="gcr.io/oss-fuzz"
|
||||
export FUZZ_TOOLING_CONTAINER_ORG="gcr.io/oss-fuzz"
|
||||
|
||||
# Docker build arguments, useful for local deployment
|
||||
# By default these points to the aixcc-finals images
|
||||
# export FUZZER_BASE_IMAGE="gcr.io/oss-fuzz-base/base-runner"
|
||||
export FUZZER_BASE_IMAGE="gcr.io/oss-fuzz-base/base-runner"
|
||||
|
||||
@@ -13,7 +13,18 @@ RUN uv python install python3.10
|
||||
FROM base-image AS runner-base
|
||||
RUN apt-get update
|
||||
# TODO(Ian): maybe we should have a different base image for the builder
|
||||
RUN curl -fsSL https://get.docker.com | sh
|
||||
RUN apt-get install ca-certificates curl
|
||||
RUN install -m 0755 -d /etc/apt/keyrings
|
||||
RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
|
||||
RUN chmod a+r /etc/apt/keyrings/docker.asc
|
||||
|
||||
# Add the repository to Apt sources:
|
||||
RUN echo \
|
||||
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
|
||||
$(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
|
||||
tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||||
|
||||
FROM base-image AS builder
|
||||
|
||||
|
||||
Executable
+567
@@ -0,0 +1,567 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Common functions and variables for Buttercup CRS setup scripts
|
||||
# This script should be sourced by other setup scripts
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Function to print colored output
|
||||
print_status() {
|
||||
echo -e "${BLUE}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Function to check if command exists
|
||||
command_exists() {
|
||||
command -v "$1" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Function to check if running as root
|
||||
check_not_root() {
|
||||
if [[ $EUID -eq 0 ]]; then
|
||||
print_error "This script should not be run as root"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to install Docker
|
||||
install_docker() {
|
||||
print_status "Installing Docker..."
|
||||
if ! command_exists docker; then
|
||||
curl -fsSL https://get.docker.com | sh
|
||||
print_status "Adding user to Docker group (sudo required)..."
|
||||
sudo usermod -aG docker $USER
|
||||
print_success "Docker installed successfully"
|
||||
print_warning "You need to log out and back in for Docker group changes to take effect"
|
||||
else
|
||||
print_success "Docker is already installed"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to install kubectl
|
||||
install_kubectl() {
|
||||
print_status "Installing kubectl..."
|
||||
if ! command_exists kubectl; then
|
||||
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
|
||||
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
|
||||
rm kubectl
|
||||
print_success "kubectl installed successfully"
|
||||
else
|
||||
print_success "kubectl is already installed"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to install Helm
|
||||
install_helm() {
|
||||
print_status "Installing Helm..."
|
||||
if ! command_exists helm; then
|
||||
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
|
||||
chmod 700 get_helm.sh
|
||||
./get_helm.sh
|
||||
rm get_helm.sh
|
||||
print_success "Helm installed successfully"
|
||||
else
|
||||
print_success "Helm is already installed"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to install Minikube
|
||||
install_minikube() {
|
||||
print_status "Installing Minikube..."
|
||||
if ! command_exists minikube; then
|
||||
curl -LO https://github.com/kubernetes/minikube/releases/latest/download/minikube-linux-amd64
|
||||
sudo install minikube-linux-amd64 /usr/local/bin/minikube
|
||||
rm minikube-linux-amd64
|
||||
print_success "Minikube installed successfully"
|
||||
else
|
||||
print_success "Minikube is already installed"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to install Git LFS
|
||||
install_git_lfs() {
|
||||
print_status "Installing Git LFS..."
|
||||
if ! command_exists git-lfs; then
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y git-lfs
|
||||
git lfs install
|
||||
print_success "Git LFS installed successfully"
|
||||
else
|
||||
print_success "Git LFS is already installed"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to install Just
|
||||
install_just() {
|
||||
print_status "Installing Just..."
|
||||
if ! command_exists just; then
|
||||
if command_exists curl; then
|
||||
# Install using the official installer
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash
|
||||
elif command_exists apt-get; then
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y just
|
||||
elif command_exists yum; then
|
||||
sudo yum install -y just
|
||||
elif command_exists brew; then
|
||||
brew install just
|
||||
else
|
||||
print_error "Could not install Just. Please install it manually."
|
||||
return 1
|
||||
fi
|
||||
print_success "Just installed successfully"
|
||||
else
|
||||
print_success "Just is already installed"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to check Docker
|
||||
check_docker() {
|
||||
print_status "Checking Docker..."
|
||||
if command_exists docker; then
|
||||
if docker info >/dev/null 2>&1; then
|
||||
print_success "Docker is running"
|
||||
else
|
||||
print_error "Docker is installed but not running"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
print_error "Docker is not installed"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to check kubectl
|
||||
check_kubectl() {
|
||||
print_status "Checking kubectl..."
|
||||
if command_exists kubectl; then
|
||||
print_success "kubectl is installed"
|
||||
else
|
||||
print_error "kubectl is not installed"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to check Helm
|
||||
check_helm() {
|
||||
print_status "Checking Helm..."
|
||||
if command_exists helm; then
|
||||
print_success "Helm is installed"
|
||||
else
|
||||
print_error "Helm is not installed"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to check Minikube
|
||||
check_minikube() {
|
||||
print_status "Checking Minikube..."
|
||||
if command_exists minikube; then
|
||||
if minikube status >/dev/null 2>&1; then
|
||||
print_success "Minikube is running"
|
||||
else
|
||||
print_warning "Minikube is installed but not running"
|
||||
fi
|
||||
else
|
||||
print_warning "Minikube is not installed (only needed for local development)"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to check Azure CLI
|
||||
check_azure_cli() {
|
||||
print_status "Checking Azure CLI..."
|
||||
if command_exists az; then
|
||||
if az account show >/dev/null 2>&1; then
|
||||
local subscription=$(az account show --query name -o tsv)
|
||||
print_success "Azure CLI is logged in (subscription: $subscription)"
|
||||
else
|
||||
print_warning "Azure CLI is installed but not logged in"
|
||||
fi
|
||||
else
|
||||
print_warning "Azure CLI is not installed (only needed for AKS deployment)"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to check Terraform
|
||||
check_terraform() {
|
||||
print_status "Checking Terraform..."
|
||||
if command_exists terraform; then
|
||||
print_success "Terraform is installed"
|
||||
else
|
||||
print_warning "Terraform is not installed (only needed for AKS deployment)"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to check Just
|
||||
check_just() {
|
||||
print_status "Checking Just..."
|
||||
if command_exists just; then
|
||||
print_success "Just is installed"
|
||||
else
|
||||
print_error "Just is not installed"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to setup configuration file
|
||||
setup_config_file() {
|
||||
local overwrite_existing=${1:-false}
|
||||
|
||||
print_status "Setting up configuration..."
|
||||
|
||||
if [ ! -f "deployment/env" ]; then
|
||||
cp deployment/env.template deployment/env
|
||||
print_success "Configuration file created from template"
|
||||
else
|
||||
print_warning "Configuration file already exists"
|
||||
if [ "$overwrite_existing" = "true" ]; then
|
||||
read -p "Do you want to overwrite it? (y/n): " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
cp deployment/env.template deployment/env
|
||||
print_success "Configuration file overwritten"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to configure LangFuse
|
||||
configure_langfuse() {
|
||||
print_status "Configuring LangFuse (optional monitoring)..."
|
||||
|
||||
# Source the env file to check current values
|
||||
if [ -f "deployment/env" ]; then
|
||||
source deployment/env
|
||||
fi
|
||||
|
||||
# Check if LangFuse is already enabled
|
||||
if [ "$LANGFUSE_ENABLED" = "true" ] && [ -n "$LANGFUSE_HOST" ] && [ -n "$LANGFUSE_PUBLIC_KEY" ]; then
|
||||
print_status "LangFuse is already configured:"
|
||||
echo " Host: $LANGFUSE_HOST"
|
||||
echo " Public Key: $LANGFUSE_PUBLIC_KEY"
|
||||
read -p "Do you want to reconfigure LangFuse? (y/n): " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
print_status "Keeping existing LangFuse configuration"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
read -p "Do you want to enable LangFuse for LLM monitoring? (y/n): " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
print_status "LangFuse configuration:"
|
||||
read -p "Enter LangFuse host URL: " langfuse_host
|
||||
read -p "Enter LangFuse public key: " langfuse_public_key
|
||||
read -s -p "Enter LangFuse secret key: " langfuse_secret_key
|
||||
echo
|
||||
|
||||
# Update the env file
|
||||
sed -i "s|.*export LANGFUSE_ENABLED=.*|export LANGFUSE_ENABLED=true|" deployment/env
|
||||
sed -i "s|.*export LANGFUSE_HOST=.*|export LANGFUSE_HOST=\"$langfuse_host\"|" deployment/env
|
||||
sed -i "s|.*export LANGFUSE_PUBLIC_KEY=.*|export LANGFUSE_PUBLIC_KEY=\"$langfuse_public_key\"|" deployment/env
|
||||
sed -i "s|.*export LANGFUSE_SECRET_KEY=.*|export LANGFUSE_SECRET_KEY=\"$langfuse_secret_key\"|" deployment/env
|
||||
|
||||
print_success "LangFuse configured successfully"
|
||||
else
|
||||
print_status "LangFuse disabled"
|
||||
sed -i "s|.*export LANGFUSE_ENABLED=.*|export LANGFUSE_ENABLED=false|" deployment/env
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to configure required API keys for local development
|
||||
configure_local_api_keys() {
|
||||
print_status "Configuring required API keys for local development..."
|
||||
|
||||
# Source the env file to check current values
|
||||
if [ -f "deployment/env" ]; then
|
||||
source deployment/env
|
||||
fi
|
||||
|
||||
# OpenAI API Key
|
||||
if [ -n "$OPENAI_API_KEY" ] && [ "$OPENAI_API_KEY" != "<your-openai-api-key>" ]; then
|
||||
print_status "OpenAI API key is already configured"
|
||||
else
|
||||
read -s -p "Enter your OpenAI API key: " openai_key
|
||||
echo
|
||||
sed -i "s|.*export OPENAI_API_KEY=.*|export OPENAI_API_KEY=\"$openai_key\"|" deployment/env
|
||||
fi
|
||||
|
||||
# Anthropic API Key
|
||||
if [ -n "$ANTHROPIC_API_KEY" ] && [ "$ANTHROPIC_API_KEY" != "<your-anthropic-api-key>" ]; then
|
||||
print_status "Anthropic API key is already configured"
|
||||
else
|
||||
read -s -p "Enter your Anthropic API key: " anthropic_key
|
||||
echo
|
||||
sed -i "s|.*export ANTHROPIC_API_KEY=.*|export ANTHROPIC_API_KEY=\"$anthropic_key\"|" deployment/env
|
||||
fi
|
||||
|
||||
# GitHub Container Registry
|
||||
if [ -n "$GHCR_AUTH" ] && [ "$GHCR_AUTH" != "<your-ghcr-base64-auth>" ]; then
|
||||
print_status "GitHub Container Registry authentication is already configured"
|
||||
else
|
||||
read -p "Enter your GitHub username (press Enter to use 'USERNAME'): " ghcr_username
|
||||
if [ -z "$ghcr_username" ]; then
|
||||
ghcr_username="USERNAME"
|
||||
fi
|
||||
read -s -p "Enter your GitHub Personal Access Token (PAT): " ghcr_pat
|
||||
echo
|
||||
|
||||
# Compute GHCR_AUTH
|
||||
ghcr_auth=$(echo -n "$ghcr_username:$ghcr_pat" | base64)
|
||||
sed -i "s|.*export GHCR_AUTH=.*|export GHCR_AUTH=\"$ghcr_auth\"|" deployment/env
|
||||
fi
|
||||
|
||||
# Docker Hub credentials (optional)
|
||||
if [ -n "$DOCKER_USERNAME" ] && [ "$DOCKER_USERNAME" != "<your-docker-username>" ]; then
|
||||
print_status "Docker Hub credentials are already configured (username: $DOCKER_USERNAME)"
|
||||
else
|
||||
read -p "Enter your Docker Hub username (optional, press Enter to skip): " docker_username
|
||||
if [ -n "$docker_username" ]; then
|
||||
read -s -p "Enter your Docker Hub Personal Access Token: " docker_pat
|
||||
echo
|
||||
|
||||
# Set Docker credentials (handles both commented and uncommented lines)
|
||||
sed -i "s|.*export DOCKER_USERNAME=.*|export DOCKER_USERNAME=\"$docker_username\"|" deployment/env
|
||||
sed -i "s|.*export DOCKER_PAT=.*|export DOCKER_PAT=\"$docker_pat\"|" deployment/env
|
||||
fi
|
||||
fi
|
||||
|
||||
print_success "API keys configured successfully"
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Function to configure OTEL telemetry
|
||||
configure_otel() {
|
||||
print_status "Configuring OpenTelemetry telemetry (optional)..."
|
||||
|
||||
# Source the env file to check current values
|
||||
if [ -f "deployment/env" ]; then
|
||||
source deployment/env
|
||||
fi
|
||||
|
||||
# Check if OTEL is already configured
|
||||
if [ -n "$OTEL_ENDPOINT" ] && [ "$OTEL_ENDPOINT" != "" ] && [ "$OTEL_ENDPOINT" != "<your-otel-endpoint>" ]; then
|
||||
print_status "OpenTelemetry is already configured:"
|
||||
echo " Endpoint: $OTEL_ENDPOINT"
|
||||
echo " Protocol: $OTEL_PROTOCOL"
|
||||
read -p "Do you want to reconfigure OpenTelemetry? (y/n): " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
print_status "Keeping existing OpenTelemetry configuration"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
read -p "Do you want to enable OpenTelemetry telemetry? (y/n): " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
print_status "OpenTelemetry configuration:"
|
||||
read -p "Enter OTEL endpoint URL: " otel_endpoint
|
||||
read -p "Enter OTEL protocol (http/grpc): " otel_protocol
|
||||
read -s -p "Enter OTEL token (optional, press Enter to skip): " otel_token
|
||||
echo
|
||||
|
||||
# Update the env file
|
||||
sed -i "s|.*export OTEL_ENDPOINT=.*|export OTEL_ENDPOINT=\"$otel_endpoint\"|" deployment/env
|
||||
sed -i "s|.*export OTEL_PROTOCOL=.*|export OTEL_PROTOCOL=\"$otel_protocol\"|" deployment/env
|
||||
|
||||
if [ -n "$otel_token" ]; then
|
||||
sed -i "s|.*export OTEL_TOKEN=.*|export OTEL_TOKEN=\"$otel_token\"|" deployment/env
|
||||
fi
|
||||
|
||||
print_success "OpenTelemetry configured successfully"
|
||||
else
|
||||
print_status "OpenTelemetry disabled"
|
||||
sed -i "s|.*export OTEL_ENDPOINT=.*|# export OTEL_ENDPOINT=\"\"|" deployment/env
|
||||
sed -i "s|.*export OTEL_PROTOCOL=.*|# export OTEL_PROTOCOL=\"http\"|" deployment/env
|
||||
sed -i "s|.*export OTEL_TOKEN=.*|# export OTEL_TOKEN=\"\"|" deployment/env
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to check configuration file
|
||||
check_config() {
|
||||
print_status "Checking configuration file..."
|
||||
if [ ! -f "deployment/env" ]; then
|
||||
print_error "Configuration file deployment/env does not exist"
|
||||
print_status "Run: cp deployment/env.template deployment/env"
|
||||
return 1
|
||||
fi
|
||||
|
||||
print_success "Configuration file exists"
|
||||
|
||||
# Source the env file to check variables
|
||||
source deployment/env
|
||||
|
||||
# Check cluster type
|
||||
if [ -n "$CLUSTER_TYPE" ]; then
|
||||
print_success "CLUSTER_TYPE is set to: $CLUSTER_TYPE"
|
||||
else
|
||||
print_error "CLUSTER_TYPE is not set"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check template
|
||||
if [ -n "$BUTTERCUP_K8S_VALUES_TEMPLATE" ]; then
|
||||
print_success "BUTTERCUP_K8S_VALUES_TEMPLATE is set to: $BUTTERCUP_K8S_VALUES_TEMPLATE"
|
||||
else
|
||||
print_error "BUTTERCUP_K8S_VALUES_TEMPLATE is not set"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to check Minikube configuration
|
||||
check_minikube_config() {
|
||||
print_status "Checking Minikube configuration..."
|
||||
|
||||
local errors=0
|
||||
|
||||
# Check required API keys
|
||||
local required_vars=(
|
||||
"OPENAI_API_KEY"
|
||||
"ANTHROPIC_API_KEY"
|
||||
"GHCR_AUTH"
|
||||
)
|
||||
|
||||
for var in "${required_vars[@]}"; do
|
||||
if [ -z "${!var}" ] || [ "${!var}" = "<your-*>" ]; then
|
||||
print_error "Required variable $var is not set or has placeholder value"
|
||||
errors=$((errors + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
# Check optional LangFuse configuration
|
||||
if [ "$LANGFUSE_ENABLED" = "true" ]; then
|
||||
local langfuse_vars=(
|
||||
"LANGFUSE_HOST"
|
||||
"LANGFUSE_PUBLIC_KEY"
|
||||
"LANGFUSE_SECRET_KEY"
|
||||
)
|
||||
|
||||
for var in "${langfuse_vars[@]}"; do
|
||||
if [ -z "${!var}" ] || [ "${!var}" = "<your-*>" ]; then
|
||||
print_error "LangFuse variable $var is not set or has placeholder value"
|
||||
errors=$((errors + 1))
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Check optional OTEL configuration
|
||||
if [ -n "$OTEL_ENDPOINT" ] && [ "$OTEL_ENDPOINT" != "" ]; then
|
||||
if [ -z "$OTEL_PROTOCOL" ] || [ "$OTEL_PROTOCOL" = "<your-*>" ]; then
|
||||
print_error "OTEL_PROTOCOL is not set when OTEL_ENDPOINT is configured"
|
||||
errors=$((errors + 1))
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $errors -eq 0 ]; then
|
||||
print_success "Minikube configuration is valid"
|
||||
else
|
||||
print_error "Minikube configuration has $errors error(s)"
|
||||
return $errors
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to check AKS configuration
|
||||
check_aks_config() {
|
||||
print_status "Checking AKS configuration..."
|
||||
|
||||
local errors=0
|
||||
|
||||
# Check Terraform variables
|
||||
local terraform_vars=(
|
||||
"TF_VAR_ARM_CLIENT_ID"
|
||||
"TF_VAR_ARM_CLIENT_SECRET"
|
||||
"TF_VAR_ARM_TENANT_ID"
|
||||
"TF_VAR_ARM_SUBSCRIPTION_ID"
|
||||
)
|
||||
|
||||
for var in "${terraform_vars[@]}"; do
|
||||
if [ -z "${!var}" ] || [ "${!var}" = "<your-*>" ]; then
|
||||
print_error "Required Terraform variable $var is not set or has placeholder value"
|
||||
errors=$((errors + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
# Check API keys
|
||||
local api_vars=(
|
||||
"OPENAI_API_KEY"
|
||||
"ANTHROPIC_API_KEY"
|
||||
"GHCR_AUTH"
|
||||
"CRS_KEY_ID"
|
||||
"CRS_KEY_TOKEN"
|
||||
"COMPETITION_API_KEY_ID"
|
||||
"COMPETITION_API_KEY_TOKEN"
|
||||
)
|
||||
|
||||
for var in "${api_vars[@]}"; do
|
||||
if [ -z "${!var}" ] || [ "${!var}" = "<your-*>" ]; then
|
||||
print_error "Required API variable $var is not set or has placeholder value"
|
||||
errors=$((errors + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
# Check Tailscale (optional but recommended)
|
||||
if [ "$TAILSCALE_ENABLED" = "true" ]; then
|
||||
local tailscale_vars=(
|
||||
"TS_CLIENT_ID"
|
||||
"TS_CLIENT_SECRET"
|
||||
"TS_OP_TAG"
|
||||
)
|
||||
|
||||
for var in "${tailscale_vars[@]}"; do
|
||||
if [ -z "${!var}" ] || [ "${!var}" = "<your-*>" ]; then
|
||||
print_error "Tailscale variable $var is not set or has placeholder value"
|
||||
errors=$((errors + 1))
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Check optional LangFuse configuration
|
||||
if [ "$LANGFUSE_ENABLED" = "true" ]; then
|
||||
local langfuse_vars=(
|
||||
"LANGFUSE_HOST"
|
||||
"LANGFUSE_PUBLIC_KEY"
|
||||
"LANGFUSE_SECRET_KEY"
|
||||
)
|
||||
|
||||
for var in "${langfuse_vars[@]}"; do
|
||||
if [ -z "${!var}" ] || [ "${!var}" = "<your-*>" ]; then
|
||||
print_error "LangFuse variable $var is not set or has placeholder value"
|
||||
errors=$((errors + 1))
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Check optional OTEL configuration
|
||||
if [ -n "$OTEL_ENDPOINT" ] && [ "$OTEL_ENDPOINT" != "" ]; then
|
||||
if [ -z "$OTEL_PROTOCOL" ] || [ "$OTEL_PROTOCOL" = "<your-*>" ]; then
|
||||
print_error "OTEL_PROTOCOL is not set when OTEL_ENDPOINT is configured"
|
||||
errors=$((errors + 1))
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $errors -eq 0 ]; then
|
||||
print_success "AKS configuration is valid"
|
||||
else
|
||||
print_error "AKS configuration has $errors error(s)"
|
||||
return $errors
|
||||
fi
|
||||
}
|
||||
Executable
+65
@@ -0,0 +1,65 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Local Development Setup Script for Buttercup CRS
|
||||
# This script automates the setup process for local development
|
||||
|
||||
set -e
|
||||
|
||||
# Source common functions
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$SCRIPT_DIR/common.sh"
|
||||
|
||||
echo "🚀 Setting up Buttercup CRS for local development..."
|
||||
|
||||
# Check if running as root
|
||||
check_not_root
|
||||
|
||||
# Function to setup configuration
|
||||
setup_config() {
|
||||
setup_config_file
|
||||
|
||||
# Configure required API keys
|
||||
configure_local_api_keys
|
||||
|
||||
# Configure LangFuse (optional)
|
||||
configure_langfuse
|
||||
|
||||
# Configure OTEL telemetry (optional)
|
||||
configure_otel
|
||||
}
|
||||
|
||||
# Function to verify setup
|
||||
verify_setup() {
|
||||
print_status "Verifying setup..."
|
||||
|
||||
# Use the main Makefile validation target
|
||||
if make validate >/dev/null 2>&1; then
|
||||
print_success "Setup verification completed successfully!"
|
||||
print_status "Next steps:"
|
||||
echo " 1. Run: make deploy-local"
|
||||
echo " 2. Test with: make test"
|
||||
else
|
||||
print_error "Setup verification failed. Run 'make validate' for details."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Main execution
|
||||
main() {
|
||||
print_status "Starting local development setup..."
|
||||
|
||||
install_docker
|
||||
install_kubectl
|
||||
install_helm
|
||||
install_minikube
|
||||
install_git_lfs
|
||||
install_just
|
||||
setup_config
|
||||
|
||||
verify_setup
|
||||
|
||||
print_success "Local development setup completed!"
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
Executable
+177
@@ -0,0 +1,177 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Production AKS Deployment Setup Script for Buttercup CRS
|
||||
# This script helps configure and validate production deployment settings
|
||||
|
||||
set -e
|
||||
|
||||
# Source common functions
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$SCRIPT_DIR/common.sh"
|
||||
|
||||
echo "🏭 Setting up Buttercup CRS for production AKS deployment..."
|
||||
|
||||
# Check if running as root
|
||||
check_not_root
|
||||
|
||||
# Function to setup service principal
|
||||
setup_service_principal() {
|
||||
print_status "Setting up Azure Service Principal..."
|
||||
|
||||
# Get current subscription
|
||||
local subscription_id=$(az account show --query id -o tsv)
|
||||
local subscription_name=$(az account show --query name -o tsv)
|
||||
|
||||
print_status "Current subscription: $subscription_name ($subscription_id)"
|
||||
|
||||
read -p "Do you want to create a new service principal? (y/n): " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
local sp_name="ButtercupCRS-$(date +%Y%m%d-%H%M%S)"
|
||||
print_status "Creating service principal: $sp_name"
|
||||
|
||||
local sp_output=$(az ad sp create-for-rbac --name "$sp_name" --role Contributor --scopes "/subscriptions/$subscription_id" --output json)
|
||||
|
||||
local app_id=$(echo "$sp_output" | jq -r '.appId')
|
||||
local password=$(echo "$sp_output" | jq -r '.password')
|
||||
local tenant_id=$(echo "$sp_output" | jq -r '.tenant')
|
||||
|
||||
print_success "Service principal created successfully"
|
||||
echo
|
||||
print_status "Service Principal Details:"
|
||||
echo " Name: $sp_name"
|
||||
echo " App ID: $app_id"
|
||||
echo " Tenant ID: $tenant_id"
|
||||
echo " Password: $password"
|
||||
echo
|
||||
print_warning "Save these credentials securely!"
|
||||
echo
|
||||
|
||||
# Export environment variables
|
||||
export TF_ARM_TENANT_ID="$tenant_id"
|
||||
export TF_ARM_CLIENT_ID="$app_id"
|
||||
export TF_ARM_CLIENT_SECRET="$password"
|
||||
export TF_ARM_SUBSCRIPTION_ID="$subscription_id"
|
||||
|
||||
print_status "Environment variables exported for current session"
|
||||
else
|
||||
print_status "Using existing service principal"
|
||||
print_status "Please set the following environment variables:"
|
||||
echo " export TF_ARM_TENANT_ID=\"<your-tenant-id>\""
|
||||
echo " export TF_ARM_CLIENT_ID=\"<your-client-id>\""
|
||||
echo " export TF_ARM_CLIENT_SECRET=\"<your-client-secret>\""
|
||||
echo " export TF_ARM_SUBSCRIPTION_ID=\"<your-subscription-id>\""
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to setup configuration
|
||||
setup_config() {
|
||||
print_status "Setting up production configuration..."
|
||||
|
||||
setup_config_file "true"
|
||||
|
||||
# Configure required API keys
|
||||
configure_local_api_keys
|
||||
|
||||
# Configure LangFuse (optional)
|
||||
configure_langfuse
|
||||
|
||||
# Configure OTEL telemetry (optional)
|
||||
configure_otel
|
||||
}
|
||||
|
||||
# Function to validate configuration
|
||||
validate_config() {
|
||||
print_status "Validating configuration..."
|
||||
|
||||
# Use the main Makefile validation target
|
||||
if make validate >/dev/null 2>&1; then
|
||||
print_success "Configuration validation passed!"
|
||||
else
|
||||
print_error "Configuration validation failed. Run 'make validate' for details."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to setup remote state (optional)
|
||||
setup_remote_state() {
|
||||
print_status "Setting up Terraform remote state..."
|
||||
|
||||
read -p "Do you want to configure remote state storage? (y/n): " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
print_status "This will create Azure resources for remote state storage"
|
||||
|
||||
# Get resource group name
|
||||
read -p "Enter resource group name for state storage (e.g., buttercup-tfstate-rg): " state_rg
|
||||
read -p "Enter storage account name (e.g., buttercuptfstate): " storage_account
|
||||
|
||||
# Create resource group
|
||||
print_status "Creating resource group: $state_rg"
|
||||
az group create --name "$state_rg" --location eastus
|
||||
|
||||
# Create storage account
|
||||
print_status "Creating storage account: $storage_account"
|
||||
az storage account create --resource-group "$state_rg" --name "$storage_account" --sku Standard_LRS --encryption-services blob
|
||||
|
||||
# Create container
|
||||
print_status "Creating storage container"
|
||||
az storage container create --name tfstate --account-name "$storage_account" --auth-mode login
|
||||
|
||||
# Update backend.tf
|
||||
print_status "Updating backend.tf"
|
||||
cat > deployment/backend.tf << EOF
|
||||
terraform {
|
||||
backend "azurerm" {
|
||||
resource_group_name = "$state_rg"
|
||||
storage_account_name = "$storage_account"
|
||||
container_name = "tfstate"
|
||||
key = "terraform.tfstate"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
print_success "Remote state storage configured"
|
||||
else
|
||||
print_status "Skipping remote state setup (using local state)"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to provide deployment instructions
|
||||
deployment_instructions() {
|
||||
print_success "Production setup completed!"
|
||||
echo
|
||||
print_status "Next steps for deployment:"
|
||||
echo " 1. Run: make deploy-production"
|
||||
echo " 2. Monitor deployment: kubectl get pods -A"
|
||||
echo " 3. Get cluster credentials: az aks get-credentials --name <cluster-name> --resource-group <rg-name>"
|
||||
echo " 4. Access via Tailscale: kubectl get -n crs-webservice ingress"
|
||||
echo
|
||||
print_status "Useful commands:"
|
||||
echo " - View logs: kubectl logs -n crs <pod-name>"
|
||||
echo " - Scale nodes: Update TF_VAR_usr_node_count and run make deploy-production"
|
||||
echo " - Cleanup: make clean"
|
||||
}
|
||||
|
||||
# Main execution
|
||||
main() {
|
||||
print_status "Starting production setup..."
|
||||
|
||||
check_azure_cli
|
||||
check_terraform
|
||||
install_just
|
||||
setup_service_principal
|
||||
setup_config
|
||||
setup_remote_state
|
||||
|
||||
print_status "Configuration validation..."
|
||||
if validate_config; then
|
||||
deployment_instructions
|
||||
else
|
||||
print_error "Please fix configuration issues before proceeding"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
Executable
+48
@@ -0,0 +1,48 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Setup Validation Script for Buttercup CRS
|
||||
# This script validates the current setup and configuration
|
||||
|
||||
set -e
|
||||
|
||||
# Source common functions
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$SCRIPT_DIR/common.sh"
|
||||
|
||||
echo "🔍 Validating Buttercup CRS setup..."
|
||||
|
||||
# Check if running as root
|
||||
check_not_root
|
||||
|
||||
# Main execution
|
||||
main() {
|
||||
local total_errors=0
|
||||
|
||||
print_status "Starting setup validation..."
|
||||
echo
|
||||
|
||||
# Check tools
|
||||
check_docker || total_errors=$((total_errors + 1))
|
||||
check_kubectl || total_errors=$((total_errors + 1))
|
||||
check_helm || total_errors=$((total_errors + 1))
|
||||
check_minikube
|
||||
check_azure_cli
|
||||
check_terraform
|
||||
echo
|
||||
|
||||
# Check configuration
|
||||
check_config || total_errors=$((total_errors + 1))
|
||||
echo
|
||||
|
||||
# Summary
|
||||
if [ $total_errors -eq 0 ]; then
|
||||
print_success "Setup validation completed successfully!"
|
||||
print_status "Your environment is ready for deployment."
|
||||
else
|
||||
print_error "Setup validation completed with $total_errors error(s)"
|
||||
print_status "Please fix the errors above before proceeding."
|
||||
fi
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user