post-create.shโข14.7 kB
#!/bin/bash
# NetBox MCP Server DevContainer Post-Create Script
# This script runs after the container is created but before the user connects
set -e
echo "๐ Setting up NetBox MCP Server development environment..."
# Update package lists
echo "๐ฆ Updating package lists..."
apt-get update
# Install additional system dependencies
echo "๐ง Installing system dependencies..."
apt-get install -y \
curl \
wget \
git \
vim \
nano \
htop \
tree \
jq \
unzip \
build-essential \
libssl-dev \
libffi-dev \
python3-dev \
postgresql-client \
redis-tools \
netcat-openbsd \
telnet \
dnsutils \
iputils-ping \
traceroute \
tcpdump \
wireshark-common \
tshark
# Install Docker Compose
echo "๐ณ Installing Docker Compose..."
curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
# Install additional Python tools
echo "๐ Installing Python development tools..."
pip install --upgrade pip setuptools wheel
# Install project dependencies
echo "๐ Installing project dependencies..."
pip install -r requirements.txt
pip install -r requirements-dev.txt
# Install pre-commit hooks
echo "๐ช Setting up pre-commit hooks..."
pre-commit install
# Create development environment file
echo "โ๏ธ Creating development environment configuration..."
cat > .env.dev << 'EOF'
# Development Environment Configuration
# This file is automatically generated by the devcontainer setup
# MCP Server Configuration
MCP_SERVER_LOG_LEVEL=DEBUG
MCP_SERVER_HOST=0.0.0.0
MCP_SERVER_PORT=8080
# NetBox Configuration
NETBOX_URL=http://localhost:8000
NETBOX_TOKEN=dev-token
# Vault Configuration
VAULT_ADDR=http://localhost:8200
VAULT_TOKEN=dev-token
VAULT_PATH=secret/netbox/jit-tokens
# PostgreSQL Configuration
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_DB=mcp_state
POSTGRES_USER=mcp_user
POSTGRES_PASSWORD=mcp_password
POSTGRES_SSLMODE=prefer
# Redis Configuration (if needed)
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_DB=0
# Development flags
DEBUG=true
DEVELOPMENT=true
TESTING=true
EOF
# Create Docker Compose file for local services
echo "๐ณ Creating Docker Compose configuration for local services..."
cat > docker-compose.dev.yml << 'EOF'
version: '3.8'
services:
# PostgreSQL for state confidence
postgres:
image: postgres:15-alpine
container_name: mcp-postgres
environment:
POSTGRES_DB: mcp_state
POSTGRES_USER: mcp_user
POSTGRES_PASSWORD: mcp_password
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
- ./scripts/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U mcp_user -d mcp_state"]
interval: 10s
timeout: 5s
retries: 5
# Redis for caching (optional)
redis:
image: redis:7-alpine
container_name: mcp-redis
ports:
- "6379:6379"
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
# Mock NetBox (for development)
netbox-mock:
image: nginx:alpine
container_name: mcp-netbox-mock
ports:
- "8000:80"
volumes:
- ./scripts/netbox-mock:/usr/share/nginx/html
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/health"]
interval: 10s
timeout: 5s
retries: 5
# Mock Vault (for development)
vault-mock:
image: nginx:alpine
container_name: mcp-vault-mock
ports:
- "8200:80"
volumes:
- ./scripts/vault-mock:/usr/share/nginx/html
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/v1/sys/health"]
interval: 10s
timeout: 5s
retries: 5
volumes:
postgres_data:
EOF
# Create database initialization script
echo "๐๏ธ Creating database initialization script..."
mkdir -p scripts
cat > scripts/init-db.sql << 'EOF'
-- Initialize the state confidence database
-- This script creates the necessary tables for the MCP server
-- Create the state schema
CREATE SCHEMA IF NOT EXISTS state;
-- Create the certainty_scores table
CREATE TABLE IF NOT EXISTS state.certainty_scores (
id SERIAL PRIMARY KEY,
state_id VARCHAR(255) NOT NULL,
state_type VARCHAR(100) NOT NULL,
certainty_score DECIMAL(5,4) NOT NULL CHECK (certainty_score >= 0 AND certainty_score <= 1),
data_age_seconds INTEGER NOT NULL,
last_verified TIMESTAMP WITH TIME ZONE NOT NULL,
verification_method VARCHAR(100),
source_reliability DECIMAL(5,4),
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
-- Create indexes for better performance
CREATE INDEX IF NOT EXISTS idx_certainty_scores_state_id ON state.certainty_scores(state_id);
CREATE INDEX IF NOT EXISTS idx_certainty_scores_state_type ON state.certainty_scores(state_type);
CREATE INDEX IF NOT EXISTS idx_certainty_scores_last_updated ON state.certainty_scores(last_verified);
-- Create a function to update the updated_at timestamp
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$ language 'plpgsql';
-- Create trigger to automatically update updated_at
CREATE TRIGGER update_certainty_scores_updated_at
BEFORE UPDATE ON state.certainty_scores
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();
-- Insert some sample data for development
INSERT INTO state.certainty_scores (state_id, state_type, certainty_score, data_age_seconds, last_verified, verification_method, source_reliability)
VALUES
('web-server-01', 'device', 0.95, 300, CURRENT_TIMESTAMP, 'api_poll', 0.98),
('app-server-01', 'vm', 0.92, 180, CURRENT_TIMESTAMP, 'api_poll', 0.95),
('192.168.1.10', 'ip_address', 0.88, 120, CURRENT_TIMESTAMP, 'ping_test', 0.90),
('100', 'vlan', 0.99, 600, CURRENT_TIMESTAMP, 'config_validation', 0.99)
ON CONFLICT DO NOTHING;
EOF
# Create mock NetBox API responses
echo "๐ญ Creating mock NetBox API responses..."
mkdir -p scripts/netbox-mock
cat > scripts/netbox-mock/index.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
<title>Mock NetBox API</title>
</head>
<body>
<h1>Mock NetBox API Server</h1>
<p>This is a mock NetBox server for development purposes.</p>
<p>Available endpoints:</p>
<ul>
<li><a href="/api/dcim/devices/">/api/dcim/devices/</a></li>
<li><a href="/api/virtualization/virtual-machines/">/api/virtualization/virtual-machines/</a></li>
<li><a href="/api/ipam/ip-addresses/">/api/ipam/ip-addresses/</a></li>
<li><a href="/api/ipam/vlans/">/api/ipam/vlans/</a></li>
</ul>
</body>
</html>
EOF
# Create mock NetBox health endpoint
cat > scripts/netbox-mock/health << 'EOF'
{"status": "healthy", "version": "3.7.0"}
EOF
# Create mock NetBox API endpoints
mkdir -p scripts/netbox-mock/api/dcim/devices
cat > scripts/netbox-mock/api/dcim/devices/index.html << 'EOF'
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"name": "web-server-01",
"display": "web-server-01",
"device_type": {"id": 1, "slug": "server", "display": "Server"},
"device_role": {"id": 1, "slug": "web-server", "display": "Web Server"},
"site": {"id": 1, "slug": "datacenter-1", "display": "Datacenter 1"},
"status": {"value": "active", "label": "Active"},
"primary_ip4": {"id": 1, "address": "192.168.1.10/24", "display": "192.168.1.10/24"},
"created": "2025-01-01T00:00:00Z",
"last_updated": "2025-01-01T12:00:00Z"
},
{
"id": 2,
"name": "db-server-01",
"display": "db-server-01",
"device_type": {"id": 1, "slug": "server", "display": "Server"},
"device_role": {"id": 2, "slug": "database-server", "display": "Database Server"},
"site": {"id": 1, "slug": "datacenter-1", "display": "Datacenter 1"},
"status": {"value": "active", "label": "Active"},
"primary_ip4": {"id": 2, "address": "192.168.1.20/24", "display": "192.168.1.20/24"},
"created": "2025-01-01T00:00:00Z",
"last_updated": "2025-01-01T12:00:00Z"
}
]
}
EOF
# Create mock Vault API responses
echo "๐ Creating mock Vault API responses..."
mkdir -p scripts/vault-mock/v1/sys
cat > scripts/vault-mock/v1/sys/health << 'EOF'
{"initialized": true, "sealed": false, "standby": false, "performance_standby": false, "replication_performance_mode": "disabled", "replication_dr_mode": "disabled", "server_time_utc": 1640995200, "version": "1.12.0", "version_commit": "abc123", "cluster_name": "vault-cluster", "cluster_id": "cluster-123"}
EOF
mkdir -p scripts/vault-mock/v1/secret/data/netbox
cat > scripts/vault-mock/v1/secret/data/netbox/jit-tokens << 'EOF'
{
"data": {
"data": {
"token": "netbox-dev-token-12345"
},
"metadata": {
"created_time": "2025-01-01T00:00:00Z",
"custom_metadata": null,
"deletion_time": "",
"destroyed": false,
"version": 1
}
}
}
EOF
# Create development scripts
echo "๐ Creating development scripts..."
mkdir -p scripts
cat > scripts/start-dev-services.sh << 'EOF'
#!/bin/bash
# Start development services using Docker Compose
echo "๐ Starting development services..."
docker-compose -f docker-compose.dev.yml up -d
echo "โณ Waiting for services to be ready..."
sleep 10
echo "โ
Development services started!"
echo "๐ Service status:"
docker-compose -f docker-compose.dev.yml ps
echo ""
echo "๐ Available services:"
echo " - NetBox Mock: http://localhost:8000"
echo " - Vault Mock: http://localhost:8200"
echo " - PostgreSQL: localhost:5432"
echo " - Redis: localhost:6379"
EOF
chmod +x scripts/start-dev-services.sh
cat > scripts/stop-dev-services.sh << 'EOF'
#!/bin/bash
# Stop development services
echo "๐ Stopping development services..."
docker-compose -f docker-compose.dev.yml down
echo "โ
Development services stopped!"
EOF
chmod +x scripts/stop-dev-services.sh
cat > scripts/test-mcp-server.sh << 'EOF'
#!/bin/bash
# Test the MCP server end-to-end
echo "๐งช Testing MCP server..."
# Start development services
echo "๐ Starting development services..."
docker-compose -f docker-compose.dev.yml up -d
# Wait for services to be ready
echo "โณ Waiting for services to be ready..."
sleep 15
# Run tests
echo "๐ฌ Running tests..."
python -m pytest tests/ -v --tb=short
# Test MCP server functionality
echo "๐ง Testing MCP server functionality..."
python examples/test_mcp_server.py
echo "โ
All tests completed!"
EOF
chmod +x scripts/test-mcp-server.sh
# Create a comprehensive README for the devcontainer
echo "๐ Creating devcontainer README..."
cat > .devcontainer/README.md << 'EOF'
# NetBox MCP Server DevContainer
This devcontainer provides a complete development environment for the NetBox MCP Server project.
## Features
- **Python 3.12** with all necessary development tools
- **Pre-configured VS Code** with Python extensions
- **Docker & Docker Compose** for local services
- **PostgreSQL** for state confidence testing
- **Mock NetBox & Vault** servers for development
- **Pre-commit hooks** for code quality
- **Comprehensive testing** setup
## Quick Start
1. **Open in Codespaces** or **VS Code with Dev Containers**
2. **Wait for setup** to complete (first time takes ~2-3 minutes)
3. **Start development services**:
```bash
./scripts/start-dev-services.sh
```
4. **Run tests**:
```bash
./scripts/test-mcp-server.sh
```
## Available Services
| Service | URL | Description |
|---------|-----|-------------|
| NetBox Mock | http://localhost:8000 | Mock NetBox API server |
| Vault Mock | http://localhost:8200 | Mock HashiCorp Vault server |
| PostgreSQL | localhost:5432 | Database for state confidence |
| Redis | localhost:6379 | Optional caching layer |
## Development Commands
```bash
# Start all development services
./scripts/start-dev-services.sh
# Stop all development services
./scripts/stop-dev-services.sh
# Run all tests
./scripts/test-mcp-server.sh
# Run specific test categories
pytest -m unit
pytest -m integration
pytest -m performance
# Run with coverage
pytest --cov=src --cov-report=html
# Format code
black src/ tests/
isort src/ tests/
# Lint code
flake8 src/ tests/
mypy src/
# Security scan
bandit -r src/
safety check
```
## Environment Variables
The devcontainer automatically sets up these environment variables:
- `NETBOX_URL=http://localhost:8000`
- `VAULT_ADDR=http://localhost:8200`
- `POSTGRES_HOST=localhost`
- `POSTGRES_DB=mcp_state`
- `MCP_SERVER_LOG_LEVEL=DEBUG`
## Troubleshooting
### Services not starting
```bash
# Check service status
docker-compose -f docker-compose.dev.yml ps
# View logs
docker-compose -f docker-compose.dev.yml logs
# Restart services
docker-compose -f docker-compose.dev.yml restart
```
### Database connection issues
```bash
# Check PostgreSQL status
docker-compose -f docker-compose.dev.yml exec postgres pg_isready -U mcp_user -d mcp_state
# Connect to database
docker-compose -f docker-compose.dev.yml exec postgres psql -U mcp_user -d mcp_state
```
### Port conflicts
If you have port conflicts, modify the ports in `docker-compose.dev.yml` and update the environment variables accordingly.
## Learning Resources
- [MCP Documentation](https://modelcontextprotocol.io/)
- [NetBox Documentation](https://docs.netbox.dev/)
- [HashiCorp Vault Documentation](https://www.vaultproject.io/docs)
- [PostgreSQL Documentation](https://www.postgresql.org/docs/)
## Contributing
1. Make your changes
2. Run tests: `./scripts/test-mcp-server.sh`
3. Format code: `black src/ tests/ && isort src/ tests/`
4. Commit your changes
Happy coding! ๐
EOF
# Set up Git configuration
echo "๐ง Setting up Git configuration..."
git config --global --add safe.directory /workspaces/mcp-dc
git config --global user.name "DevContainer User"
git config --global user.email "devcontainer@example.com"
# Create a welcome message
echo "๐ NetBox MCP Server development environment is ready!"
echo ""
echo "๐ Next steps:"
echo " 1. Start development services: ./scripts/start-dev-services.sh"
echo " 2. Run tests: ./scripts/test-mcp-server.sh"
echo " 3. Start coding!"
echo ""
echo "๐ For more information, see .devcontainer/README.md"