chore: pre-migration snapshot
Layer0, MCP servers, Terraform consolidation
This commit is contained in:
221
scripts/setup_credentials.py
Normal file
221
scripts/setup_credentials.py
Normal file
@@ -0,0 +1,221 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Cloudflare Credential Setup Wizard
|
||||
Interactive script to guide users through configuring Cloudflare API credentials
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def validate_api_token(token):
|
||||
"""Validate Cloudflare API token format"""
|
||||
# Cloudflare API tokens are typically 40+ characters
|
||||
return len(token.strip()) >= 40
|
||||
|
||||
|
||||
def validate_account_id(account_id):
|
||||
"""Validate Cloudflare Account ID format"""
|
||||
# Account IDs are typically 32-character hex strings
|
||||
return re.match(r"^[a-f0-9]{32}$", account_id.strip(), re.IGNORECASE) is not None
|
||||
|
||||
|
||||
def validate_zone_id(zone_id):
|
||||
"""Validate Cloudflare Zone ID format"""
|
||||
# Zone IDs are also 32-character hex strings
|
||||
return re.match(r"^[a-f0-9]{32}$", zone_id.strip(), re.IGNORECASE) is not None
|
||||
|
||||
|
||||
def get_input(prompt, validation_func=None, secret=False):
|
||||
"""Get validated user input"""
|
||||
while True:
|
||||
try:
|
||||
if secret:
|
||||
import getpass
|
||||
|
||||
value = getpass.getpass(prompt)
|
||||
else:
|
||||
value = input(prompt)
|
||||
|
||||
if validation_func:
|
||||
if validation_func(value):
|
||||
return value
|
||||
else:
|
||||
print("❌ Invalid format. Please try again.")
|
||||
else:
|
||||
return value
|
||||
except KeyboardInterrupt:
|
||||
print("\n\nSetup cancelled.")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def create_env_file(env_vars):
|
||||
"""Create or update .env file with credentials"""
|
||||
env_path = Path(".env")
|
||||
|
||||
# Read existing .env if it exists
|
||||
existing_vars = {}
|
||||
if env_path.exists():
|
||||
with open(env_path, "r") as f:
|
||||
for line in f:
|
||||
if line.strip() and not line.startswith("#") and "=" in line:
|
||||
key, value = line.strip().split("=", 1)
|
||||
existing_vars[key] = value
|
||||
|
||||
# Update with new values
|
||||
existing_vars.update(env_vars)
|
||||
|
||||
# Write back
|
||||
with open(env_path, "w") as f:
|
||||
f.write("# OpenCode Environment Variables\n")
|
||||
f.write("# Generated by setup_credentials.py\n")
|
||||
f.write("# IMPORTANT: Never commit this file to git\n\n")
|
||||
|
||||
# Write Cloudflare section
|
||||
f.write(
|
||||
"# ============================================================================\n"
|
||||
)
|
||||
f.write("# CLOUDFLARE API CONFIGURATION\n")
|
||||
f.write(
|
||||
"# ============================================================================\n"
|
||||
)
|
||||
|
||||
for key, value in env_vars.items():
|
||||
f.write(f'{key}="{value}"\n')
|
||||
|
||||
f.write("\n")
|
||||
|
||||
# Preserve other sections if they exist
|
||||
sections = {
|
||||
"GITHUB": [k for k in existing_vars.keys() if k.startswith("GITHUB")],
|
||||
"GITLAB": [k for k in existing_vars.keys() if k.startswith("GITLAB")],
|
||||
"OTHER": [
|
||||
k
|
||||
for k in existing_vars.keys()
|
||||
if k not in env_vars and not k.startswith(("GITHUB", "GITLAB"))
|
||||
],
|
||||
}
|
||||
|
||||
for section_name, keys in sections.items():
|
||||
if keys:
|
||||
f.write(
|
||||
f"# ============================================================================\n"
|
||||
)
|
||||
f.write(f"# {section_name} CONFIGURATION\n")
|
||||
f.write(
|
||||
f"# ============================================================================\n"
|
||||
)
|
||||
for key in keys:
|
||||
f.write(f'{key}="{existing_vars[key]}"\n')
|
||||
f.write("\n")
|
||||
|
||||
return env_path
|
||||
|
||||
|
||||
def main():
|
||||
print("🚀 Cloudflare Credential Setup Wizard")
|
||||
print("=" * 50)
|
||||
print()
|
||||
|
||||
print("This wizard will help you configure your Cloudflare API credentials.")
|
||||
print("You'll need:")
|
||||
print("1. Cloudflare API Token (with appropriate permissions)")
|
||||
print("2. Cloudflare Account ID")
|
||||
print("3. Optional: Zone ID for specific domain management")
|
||||
print()
|
||||
|
||||
# Check if we're in the right directory
|
||||
current_dir = Path.cwd()
|
||||
if "cloudflare" not in str(current_dir):
|
||||
print("⚠️ Warning: This script should be run from the cloudflare directory")
|
||||
print(f" Current directory: {current_dir}")
|
||||
proceed = get_input("Continue anyway? (y/n): ")
|
||||
if proceed.lower() != "y":
|
||||
print(
|
||||
"Please navigate to the cloudflare directory and run this script again."
|
||||
)
|
||||
return
|
||||
|
||||
# Collect credentials
|
||||
print("\n🔐 Cloudflare API Configuration")
|
||||
print("-" * 30)
|
||||
|
||||
# API Token
|
||||
print("\n📋 Step 1: Cloudflare API Token")
|
||||
print("Get your token from: https://dash.cloudflare.com/profile/api-tokens")
|
||||
print("Required permissions: Zone:DNS:Edit, Zone:Page Rules:Edit, Account:Read")
|
||||
api_token = get_input(
|
||||
"API Token: ", validation_func=validate_api_token, secret=True
|
||||
)
|
||||
|
||||
# Account ID
|
||||
print("\n🏢 Step 2: Cloudflare Account ID")
|
||||
print("Find your Account ID in the Cloudflare dashboard sidebar")
|
||||
print("Format: 32-character hex string (e.g., 1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p)")
|
||||
account_id = get_input("Account ID: ", validation_func=validate_account_id)
|
||||
|
||||
# Zone ID (optional)
|
||||
print("\n🌐 Step 3: Zone ID (Optional)")
|
||||
print("If you want to manage a specific domain, provide its Zone ID")
|
||||
print("Leave blank to skip")
|
||||
zone_id = get_input(
|
||||
"Zone ID (optional): ",
|
||||
validation_func=lambda x: x.strip() == "" or validate_zone_id(x),
|
||||
)
|
||||
|
||||
# Prepare environment variables
|
||||
env_vars = {"CLOUDFLARE_API_TOKEN": api_token, "CLOUDFLARE_ACCOUNT_ID": account_id}
|
||||
|
||||
if zone_id.strip():
|
||||
env_vars["CLOUDFLARE_ZONE_ID"] = zone_id
|
||||
|
||||
# Create .env file
|
||||
print("\n💾 Saving credentials...")
|
||||
env_path = create_env_file(env_vars)
|
||||
|
||||
# Set file permissions
|
||||
env_path.chmod(0o600) # Only user read/write
|
||||
|
||||
print(f"✅ Credentials saved to: {env_path}")
|
||||
print("🔒 File permissions set to 600 (owner read/write only)")
|
||||
|
||||
# Test configuration (basic validation only - no external dependencies)
|
||||
print("\n🧪 Validating credentials...")
|
||||
|
||||
# Basic format validation
|
||||
if validate_api_token(api_token) and validate_account_id(account_id):
|
||||
print("✅ Credential formats are valid")
|
||||
print("⚠️ Note: Full API connectivity test requires 'requests' module")
|
||||
print(" Install with: pip install requests")
|
||||
else:
|
||||
print("❌ Credential validation failed")
|
||||
print(" Please check your inputs and try again")
|
||||
|
||||
# Final instructions
|
||||
print("\n🎉 Setup Complete!")
|
||||
print("=" * 50)
|
||||
print("\nNext steps:")
|
||||
print("1. Source the environment file:")
|
||||
print(" source .env")
|
||||
print("\n2. Test Terraform configuration:")
|
||||
print(" cd terraform && terraform init && terraform plan")
|
||||
print("\n3. Deploy infrastructure:")
|
||||
print(" terraform apply")
|
||||
print("\n4. Start MCP servers:")
|
||||
print(" Check MCP_GUIDE.md for server startup instructions")
|
||||
print("\n📚 Documentation:")
|
||||
print("- USAGE_GUIDE.md - Complete usage instructions")
|
||||
print("- DEPLOYMENT_GUIDE.md - Deployment procedures")
|
||||
print("- MCP_GUIDE.md - MCP server management")
|
||||
|
||||
# Security reminder
|
||||
print("\n🔐 Security Reminder:")
|
||||
print("- Never commit .env to version control")
|
||||
print("- Use .gitignore to exclude .env files")
|
||||
print("- Consider using environment-specific .env files (.env.production, etc.)")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user