annator-atom / backend /cli /enable.py
techprotrade's picture
Full stack ATOM backend + AIMONEYFLOW clients (port 7860) (part 2)
ff0e46c verified
Raw
History Blame Contribute Delete
7.84 kB
"""
Atom CLI - Enable command for upgrading Personal to Enterprise.
Enables Enterprise Edition features:
- Sets ATOM_EDITION=enterprise
- Installs enterprise dependencies
- Updates configuration
- Migrates database if needed
"""
import os
import sys
import click
import logging
import subprocess
from pathlib import Path
# Add backend to path for imports
sys.path.insert(0, str(Path(__file__).parent.parent))
logger = logging.getLogger(__name__)
@click.group()
def enable():
"""Enable Enterprise Edition features."""
pass
@enable.command()
@click.option('--workspace-id', help='Workspace ID for enterprise setup')
@click.option('--database-url', help='PostgreSQL database URL')
@click.option('--skip-deps', is_flag=True, help='Skip installing dependencies')
@click.option('--yes', '-y', is_flag=True, help='Skip confirmation')
def enterprise(workspace_id: str, database_url: str, skip_deps: bool, yes: bool):
"""
Enable Enterprise Edition features.
Upgrades Personal Edition to Enterprise:
- Sets ATOM_EDITION=enterprise
- Installs enterprise dependencies
- Prompts for PostgreSQL configuration
- Updates .env with enterprise settings
**Examples:**
atom enable enterprise # Interactive
atom enable enterprise --yes # Skip confirmation
atom enable enterprise --workspace-id acme-corp # With workspace
atom enable enterprise --database-url "postgresql://..." # Custom DB
**Post-Installation:**
- Set up PostgreSQL database
- Configure SSO providers (optional)
- Enable monitoring (optional)
"""
click.echo(click.style("Enterprise Edition Enable", bold=True))
click.echo("=" * 50)
# Check current edition
from core.package_feature_service import get_package_feature_service
service = get_package_feature_service()
if service.is_enterprise:
click.echo(click.style("Enterprise Edition already enabled!", fg="green"))
click.echo(f"Current edition: {service.edition.value}")
return
# Show what will change
click.echo("")
click.echo("This will enable Enterprise Edition features:")
click.echo(" Multi-user support")
click.echo(" Workspace isolation")
click.echo(" SSO (Okta, Auth0, SAML)")
click.echo(" Monitoring (Prometheus, Grafana)")
click.echo(" Advanced analytics")
click.echo(" Audit trail")
click.echo(" Rate limiting")
click.echo("")
# Confirm if not --yes
if not yes:
if not click.confirm("Enable Enterprise Edition?"):
click.echo("Cancelled.")
raise SystemExit(0)
# Install enterprise dependencies
if not skip_deps:
click.echo("")
click.echo("Installing Enterprise dependencies...")
try:
subprocess.run(
[sys.executable, "-m", "pip", "install", "-e", ".[enterprise]"],
check=True,
cwd=Path(__file__).parent.parent
)
click.echo(click.style(" Dependencies installed", fg="green"))
except subprocess.CalledProcessError as e:
click.echo(click.style(f" Failed to install: {e}", fg="red"), err=True)
click.echo("Run manually: pip install atom-os[enterprise]")
raise SystemExit(1)
# Update .env file
env_file = Path(".env")
if env_file.exists():
_update_env_for_enterprise(env_file, database_url, workspace_id)
else:
click.echo(click.style(".env file not found - run 'atom init' first", fg="yellow"))
raise SystemExit(1)
# Success
click.echo("")
click.echo(click.style("Enterprise Edition enabled!", fg="green", bold=True))
# Show next steps
click.echo("")
click.echo("Next steps:")
if not database_url:
click.echo(" 1. Set up PostgreSQL database:")
click.echo(" createdb atom")
click.echo(" # Or update DATABASE_URL in .env")
click.echo(" 2. Restart Atom:")
click.echo(" atom stop # If running")
click.echo(" atom start")
click.echo(" 3. Configure optional features:")
click.echo(" - SSO: Update OKTA_* or AUTH0_* variables")
click.echo(" - Monitoring: Access http://localhost:9090")
click.echo(" - Redis: Set REDIS_URL for multi-user")
def _update_env_for_enterprise(env_file: Path, database_url: str, workspace_id: str) -> None:
"""Update .env file for Enterprise Edition."""
content = env_file.read_text()
# Update edition
if "ATOM_EDITION=" in content:
content = content.replace(
"ATOM_EDITION=personal",
"ATOM_EDITION=enterprise"
)
else:
content = f"\nATOM_EDITION=enterprise\n{content}"
# Update database URL if provided
if database_url:
if "DATABASE_URL=" in content:
lines = content.split("\n")
for i, line in enumerate(lines):
if line.startswith("DATABASE_URL="):
lines[i] = f"DATABASE_URL={database_url}"
break
content = "\n".join(lines)
else:
content = f"\nDATABASE_URL={database_url}\n{content}"
# Enable multi-user
if "ATOM_MULTI_USER_ENABLED=" in content:
content = content.replace(
"ATOM_MULTI_USER_ENABLED=false",
"ATOM_MULTI_USER_ENABLED=true"
)
else:
content = "\nATOM_MULTI_USER_ENABLED=true\n" + content
# Enable monitoring
if "ATOM_MONITORING_ENABLED=" in content:
content = content.replace(
"ATOM_MONITORING_ENABLED=false",
"ATOM_MONITORING_ENABLED=true"
)
else:
content = "\nATOM_MONITORING_ENABLED=true\n" + content
# Add workspace ID if provided
if workspace_id:
if "WORKSPACE_ID=" in content:
lines = content.split("\n")
for i, line in enumerate(lines):
if line.startswith("WORKSPACE_ID="):
lines[i] = f"WORKSPACE_ID={workspace_id}"
break
content = "\n".join(lines)
else:
content = f"\nWORKSPACE_ID={workspace_id}\n{content}"
# Write updated content
env_file.write_text(content)
click.echo(" Updated .env file")
@enable.command()
def features():
"""List available features and their edition requirements."""
from core.package_feature_service import get_package_feature_service
service = get_package_feature_service()
click.echo(click.style("Atom Edition Features", bold=True))
click.echo("=" * 50)
click.echo(f"Current Edition: {service.edition.value.upper()}")
click.echo("")
# List features by edition
click.echo(click.style("Personal Edition Features:", fg="blue"))
for feature in service.get_personal_features():
info = service.get_feature_info(feature)
available = service.is_feature_enabled(feature)
status = click.style("✓", fg="green") if available else click.style("✗", fg="red")
click.echo(f" {status} {info.name}: {info.description}")
click.echo("")
click.echo(click.style("Enterprise Edition Features:", fg="yellow"))
for feature in service.get_enterprise_features():
info = service.get_feature_info(feature)
available = service.is_feature_enabled(feature)
status = click.style("✓", fg="green") if available else click.style("✗", fg="red")
click.echo(f" {status} {info.name}: {info.description}")
if not service.is_enterprise:
click.echo("")
click.echo("Enable Enterprise features:")
click.echo(" atom enable enterprise")
def register_enable_command(cli_group):
"""Register enable command with CLI group."""
cli_group.add_command(enable)