Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions cmd/update/moni.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import (
"fmt"

"github.com/CodeMonkeyCybersecurity/eos/pkg/bionicgpt"
"github.com/CodeMonkeyCybersecurity/eos/pkg/bionicgpt/apikeys"
"github.com/CodeMonkeyCybersecurity/eos/pkg/bionicgpt/postinstall"
"github.com/CodeMonkeyCybersecurity/eos/pkg/bionicgpt/refresh"
Expand All @@ -25,6 +26,12 @@
moniRefreshValidateOnly bool
moniRefreshInstallDir string

// Moni API key rotation flags
moniRotateAPIKeysDryRun bool
moniRotateAPIKeysSkipBackup bool
moniRotateAPIKeysSkipVerify bool
moniRotateAPIKeysSkipRestart bool
moniRotateAPIKeysInstallDir string
// Moni post-install and API key rotation flags
moniPostInstall bool
moniRotateAPIKeys bool
Expand Down Expand Up @@ -117,6 +124,61 @@
MoniCmd.Flags().BoolVar(&moniRefreshForce, "refresh", false,
"Refresh Moni configuration and restart services")

// Rotate API keys subcommand
rotateAPIKeysCmd := &cobra.Command{
Use: "rotate-api-keys",
Short: "Rotate LiteLLM virtual API keys for Moni",
Long: `Rotate the virtual API keys used by Moni to access LiteLLM models.

This operation regenerates the virtual key with access to all configured models:
• Moni (GPT-5-mini)
• Moni-4.1 (GPT-4.1-mini)
• Moni-o3 (o3-mini)
• nomic-embed-text (Ollama embeddings)

The rotation process:
1. ASSESS: Check prerequisites (database, LiteLLM health, current keys)
2. INTERVENE: Generate new key, update .env, update database, restart app
3. EVALUATE: Verify new key works and is properly configured

Safety features:
• Automatic backup of .env file before changes
• Transaction-like behavior with automatic rollback on failure
• Comprehensive verification tests after rotation
• Old keys are deleted after successful rotation

Estimated downtime: ~30 seconds (during app restart)

Examples:
# Full API key rotation with confirmation
eos update moni rotate-api-keys

# Dry run (show what would be done)
eos update moni rotate-api-keys --dry-run

# Skip backup (not recommended)
eos update moni rotate-api-keys --skip-backup

# Skip verification tests
eos update moni rotate-api-keys --skip-verify

# Custom installation directory
eos update moni rotate-api-keys --install-dir /opt/moni`,
RunE: eos.Wrap(runMoniRotateAPIKeys),
}

rotateAPIKeysCmd.Flags().BoolVar(&moniRotateAPIKeysDryRun, "dry-run", false,
"Show what would be done without making changes")
rotateAPIKeysCmd.Flags().BoolVar(&moniRotateAPIKeysSkipBackup, "skip-backup", false,
"Skip .env backup (not recommended)")
rotateAPIKeysCmd.Flags().BoolVar(&moniRotateAPIKeysSkipVerify, "skip-verify", false,
"Skip verification tests after rotation")
rotateAPIKeysCmd.Flags().BoolVar(&moniRotateAPIKeysSkipRestart, "skip-restart", false,
"Skip app restart after rotation")
rotateAPIKeysCmd.Flags().StringVar(&moniRotateAPIKeysInstallDir, "install-dir", "/opt/bionicgpt",
"Path to Moni installation directory")

MoniCmd.AddCommand(refreshCmd, rotateAPIKeysCmd)
// Add post-install flag
MoniCmd.Flags().BoolVar(&moniPostInstall, "post-install", false,
"Run post-installation configuration (upsert models, regenerate API keys)")
Expand Down Expand Up @@ -295,9 +357,56 @@
return nil
}

// runMoniRotateAPIKeys handles the API key rotation operation
// Orchestration layer: delegates to pkg/bionicgpt for business logic
func runMoniRotateAPIKeys(rc *eos_io.RuntimeContext, cmd *cobra.Command, args []string) error {
logger := otelzap.Ctx(rc.Ctx)

logger.Info("Starting Moni API key rotation",
zap.String("install_dir", moniRotateAPIKeysInstallDir),
zap.Bool("dry_run", moniRotateAPIKeysDryRun),
zap.Bool("skip_backup", moniRotateAPIKeysSkipBackup),
zap.Bool("skip_verify", moniRotateAPIKeysSkipVerify),
zap.Bool("skip_restart", moniRotateAPIKeysSkipRestart))

// Build rotation configuration
config := &bionicgpt.RotateAPIKeysConfig{
InstallDir: moniRotateAPIKeysInstallDir,
DryRun: moniRotateAPIKeysDryRun,
SkipBackup: moniRotateAPIKeysSkipBackup,
SkipVerify: moniRotateAPIKeysSkipVerify,
SkipRestart: moniRotateAPIKeysSkipRestart,
}

// Execute rotation
if err := bionicgpt.RotateAPIKeys(rc, config); err != nil {
logger.Error("Moni API key rotation failed", zap.Error(err))
return fmt.Errorf("API key rotation failed: %w", err)
}

logger.Info("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
logger.Info("✅ API KEY ROTATION COMPLETE")
logger.Info("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
logger.Info("")
logger.Info("🔑 New virtual key has been generated and configured")
logger.Info("")
logger.Info("🤖 Authorized Models:")
logger.Info(" • Moni (GPT-5-mini)")
logger.Info(" • Moni-4.1 (GPT-4.1-mini)")
logger.Info(" • Moni-o3 (o3-mini)")
logger.Info(" • nomic-embed-text (Ollama)")
logger.Info("")
logger.Info("🧪 Test in Moni UI:")
logger.Info(" http://localhost:8513")
logger.Info(" Try: 'What is your name?'")
logger.Info("")
logger.Info("📝 Monitor logs:")
logger.Info(" docker compose -f /opt/bionicgpt/docker-compose.yml logs -f app litellm-proxy")
logger.Info("")

// runMoniInit handles the Moni initialization worker
// Orchestration layer: delegates to pkg/moni for business logic
func runMoniInit(rc *eos_io.RuntimeContext, cmd *cobra.Command, args []string) error {

Check failure on line 409 in cmd/update/moni.go

View workflow job for this annotation

GitHub Actions / Code Quality Checks

expected '(', found runMoniInit

Check failure on line 409 in cmd/update/moni.go

View workflow job for this annotation

GitHub Actions / Code Quality Checks

expected '(', found runMoniInit

Check failure on line 409 in cmd/update/moni.go

View workflow job for this annotation

GitHub Actions / quality-check

expected '(', found runMoniInit

Check failure on line 409 in cmd/update/moni.go

View workflow job for this annotation

GitHub Actions / quality-check

expected '(', found runMoniInit

Check failure on line 409 in cmd/update/moni.go

View workflow job for this annotation

GitHub Actions / Security Audit

expected ')', found '.'

Check failure on line 409 in cmd/update/moni.go

View workflow job for this annotation

GitHub Actions / Security Audit

missing ',' in parameter list

Check failure on line 409 in cmd/update/moni.go

View workflow job for this annotation

GitHub Actions / Security Audit

expected ')', found '*'

Check failure on line 409 in cmd/update/moni.go

View workflow job for this annotation

GitHub Actions / Security Audit

missing parameter name

Check failure on line 409 in cmd/update/moni.go

View workflow job for this annotation

GitHub Actions / Security Audit

expected '(', found runMoniInit
logger := otelzap.Ctx(rc.Ctx)

// Build worker configuration
Expand Down Expand Up @@ -360,4 +469,4 @@

logger.Info("Moni operation completed successfully")
return nil
}

Check failure on line 472 in cmd/update/moni.go

View workflow job for this annotation

GitHub Actions / Code Quality Checks

expected '}', found 'EOF'

Check failure on line 472 in cmd/update/moni.go

View workflow job for this annotation

GitHub Actions / Code Quality Checks

expected '}', found 'EOF'

Check failure on line 472 in cmd/update/moni.go

View workflow job for this annotation

GitHub Actions / quality-check

expected '}', found 'EOF'

Check failure on line 472 in cmd/update/moni.go

View workflow job for this annotation

GitHub Actions / quality-check

expected '}', found 'EOF'

Check failure on line 472 in cmd/update/moni.go

View workflow job for this annotation

GitHub Actions / Security Audit

expected ';', found 'EOF'
Loading
Loading