provisioning-core/nulib/domain/diagnostics/next_steps.nu

326 lines
14 KiB
Text

# Next Steps Recommendation Module
# Provides intelligent next-step suggestions based on current system state
use std log
# Selective imports (ADR-025 Phase 3 Layer 2).
# config/accessor star-import was dead — dropped.
use platform/user/config.nu [load-user-config]
# Determine current deployment phase
def get-deployment-phase [] {
let user_config = load-user-config
let active = ($user_config.active_workspace? | default null)
if $active == null {
return "no_workspace"
}
let workspaces = ($user_config.workspaces | where name == $active)
if ($workspaces | length) == 0 {
return "invalid_workspace"
}
let workspace = ($workspaces | first)
let ws_path = ($workspace.path? | default "")
if ($ws_path | is-empty) or not ($ws_path | path exists) {
return "invalid_workspace"
}
# Check for infrastructure definitions
let infra_path = ($ws_path | path join "infra")
let has_infra = if ($infra_path | path exists) {
(ls $infra_path | where type == dir | length) > 0
} else {
false
}
if not $has_infra {
return "no_infrastructure"
}
# Check for server state
let state_path = ($ws_path | path join "runtime" | path join "state")
let has_servers = if ($state_path | path exists) {
(ls $state_path --all | where name =~ r"server.*\.state$" | length) > 0
} else {
false
}
if not $has_servers {
return "no_servers"
}
# Check for taskserv installations
let has_taskservs = if ($state_path | path exists) {
(ls $state_path --all | where name =~ r"taskserv.*\.state$" | length) > 0
} else {
false
}
if not $has_taskservs {
return "no_taskservs"
}
# Check for cluster deployments
let has_clusters = if ($state_path | path exists) {
(ls $state_path --all | where name =~ r"cluster.*\.state$" | length) > 0
} else {
false
}
if not $has_clusters {
return "no_clusters"
}
return "deployed"
}
# Get next steps for no workspace phase
def next-steps-no-workspace [] {
[
$"(ansi cyan_bold)📋 Next Steps: Create Your First Workspace(ansi reset)\n"
$"You haven't created a workspace yet. Let's get started!\n"
$"(ansi yellow_bold)Step 1: Initialize a new workspace(ansi reset)"
$" Command: (ansi green)provisioning workspace init <name>(ansi reset)"
$" Example: (ansi green)provisioning workspace init my-project(ansi reset)\n"
$"(ansi yellow_bold)Alternative: Use the quick setup wizard(ansi reset)"
$" Command: (ansi green)provisioning setup(ansi reset)\n"
$"(ansi blue_bold)📚 Documentation:(ansi reset)"
$" • Workspace Guide: docs/user/WORKSPACE_SWITCHING_GUIDE.md"
$" • Quick Start: docs/guides/quickstart-cheatsheet.md"
$" • From Scratch Guide: docs/guides/from-scratch.md"
] | str join "\n"
}
# Get next steps for no infrastructure phase
def next-steps-no-infrastructure [] {
[
$"(ansi cyan_bold)📋 Next Steps: Define Your Infrastructure(ansi reset)\n"
$"Your workspace is ready! Now let's define infrastructure.\n"
$"(ansi yellow_bold)Step 1: Discover available providers(ansi reset)"
$" Command: (ansi green)provisioning module discover providers(ansi reset)\n"
$"(ansi yellow_bold)Step 2: Load a provider into your workspace(ansi reset)"
$" Command: (ansi green)provisioning module load providers <workspace> <provider>(ansi reset)"
$" Example: (ansi green)provisioning module load providers my-project upcloud(ansi reset)\n"
$"(ansi yellow_bold)Step 3: Create infrastructure definition(ansi reset)"
$" Command: (ansi green)provisioning generate infra --new <name>(ansi reset)"
$" Example: (ansi green)provisioning generate infra --new production(ansi reset)\n"
$"(ansi blue_bold)📚 Documentation:(ansi reset)"
$" • From Scratch Guide: docs/guides/from-scratch.md"
$" • Infrastructure Management: docs/user/SERVICE_MANAGEMENT_GUIDE.md"
$" • Module System: docs/architecture/multi-repo-strategy.md"
] | str join "\n"
}
# Get next steps for no servers phase
def next-steps-no-servers [] {
[
$"(ansi cyan_bold)📋 Next Steps: Deploy Your Servers(ansi reset)\n"
$"Infrastructure is configured! Let's deploy servers.\n"
$"(ansi yellow_bold)Step 1: Review infrastructure configuration(ansi reset)"
$" Command: (ansi green)provisioning infra validate <name>(ansi reset)\n"
$"(ansi yellow_bold)Step 2: Deploy servers (dry-run first)(ansi reset)"
$" Command: (ansi green)provisioning server create --check(ansi reset)"
$" With infra: (ansi green)provisioning server create --infra <name> --check(ansi reset)\n"
$"(ansi yellow_bold)Step 3: Deploy for real(ansi reset)"
$" Command: (ansi green)provisioning server create(ansi reset)"
$" With infra: (ansi green)provisioning server create --infra <name>(ansi reset)\n"
$"(ansi yellow_bold)Step 4: Verify deployment(ansi reset)"
$" Command: (ansi green)provisioning server list(ansi reset)\n"
$"(ansi blue_bold)📚 Documentation:(ansi reset)"
$" • Server Management: docs/user/SERVICE_MANAGEMENT_GUIDE.md"
$" • From Scratch Guide: docs/guides/from-scratch.md"
$" • Troubleshooting: docs/user/troubleshooting-guide.md"
] | str join "\n"
}
# Get next steps for no taskservs phase
def next-steps-no-taskservs [] {
[
$"(ansi cyan_bold)📋 Next Steps: Install Task Services(ansi reset)\n"
$"Servers are running! Let's install infrastructure services.\n"
$"(ansi yellow_bold)Step 1: List available taskservs(ansi reset)"
$" Command: (ansi green)provisioning taskserv list(ansi reset)\n"
$"(ansi yellow_bold)Step 2: Discover taskservs by category(ansi reset)"
$" Command: (ansi green)provisioning module discover taskservs(ansi reset)\n"
$"(ansi yellow_bold)Step 3: Install a taskserv (dry-run first)(ansi reset)"
$" Command: (ansi green)provisioning taskserv create <name> --check(ansi reset)"
$" Example: (ansi green)provisioning taskserv create kubernetes --check(ansi reset)\n"
$"(ansi yellow_bold)Step 4: Install for real(ansi reset)"
$" Command: (ansi green)provisioning taskserv create kubernetes(ansi reset)\n"
$"(ansi yellow_bold)Common taskservs to install:(ansi reset)"
$" • Kubernetes: (ansi green)provisioning taskserv create kubernetes(ansi reset)"
$" • Containerd: (ansi green)provisioning taskserv create containerd(ansi reset)"
$" • etcd: (ansi green)provisioning taskserv create etcd(ansi reset)"
$" • Cilium: (ansi green)provisioning taskserv create cilium(ansi reset)\n"
$"(ansi blue_bold)📚 Documentation:(ansi reset)"
$" • Service Management: docs/user/SERVICE_MANAGEMENT_GUIDE.md"
$" • Taskserv Guide: docs/development/workflow.md"
$" • Dependencies: Check taskserv dependencies.ncl files"
] | str join "\n"
}
# Get next steps for no clusters phase
def next-steps-no-clusters [] {
[
$"(ansi cyan_bold)📋 Next Steps: Deploy Complete Clusters(ansi reset)\n"
$"Task services are installed! Ready for full cluster deployments.\n"
$"(ansi yellow_bold)Step 1: List available cluster configurations(ansi reset)"
$" Command: (ansi green)provisioning module discover clusters(ansi reset)\n"
$"(ansi yellow_bold)Step 2: Create a cluster (dry-run first)(ansi reset)"
$" Command: (ansi green)provisioning cluster create <name> --check(ansi reset)"
$" Example: (ansi green)provisioning cluster create buildkit --check(ansi reset)\n"
$"(ansi yellow_bold)Step 3: Deploy cluster for real(ansi reset)"
$" Command: (ansi green)provisioning cluster create <name>(ansi reset)\n"
$"(ansi yellow_bold)Step 4: Verify cluster health(ansi reset)"
$" Command: (ansi green)provisioning cluster list(ansi reset)\n"
$"(ansi yellow_bold)Alternative: Use batch workflows(ansi reset)"
$" Deploy everything at once with dependencies:"
$" Command: (ansi green)provisioning batch submit workflows/example.ncl(ansi reset)\n"
$"(ansi blue_bold)📚 Documentation:(ansi reset)"
$" • Cluster Management: docs/development/workflow.md"
$" • Batch Workflows: .claude/features/batch-workflow-system.md"
$" • From Scratch Guide: docs/guides/from-scratch.md"
] | str join "\n"
}
# Get next steps for fully deployed phase
def next-steps-deployed [] {
[
$"(ansi green_bold)✅ System Fully Deployed!(ansi reset)\n"
$"Your infrastructure is running. Here are some things you can do:\n"
$"(ansi yellow_bold)Manage Infrastructure:(ansi reset)"
$" • List servers: (ansi green)provisioning server list(ansi reset)"
$" • SSH to server: (ansi green)provisioning server ssh <hostname>(ansi reset)"
$" • Update taskservs: (ansi green)provisioning taskserv check-updates(ansi reset)\n"
$"(ansi yellow_bold)Monitor and Troubleshoot:(ansi reset)"
$" • System status: (ansi green)provisioning status(ansi reset)"
$" • Health check: (ansi green)provisioning health(ansi reset)"
$" • Workflow status: (ansi green)provisioning workflow list(ansi reset)\n"
$"(ansi yellow_bold)Advanced Operations:(ansi reset)"
$" • Test environments: (ansi green)provisioning test quick <taskserv>(ansi reset)"
$" • Batch workflows: (ansi green)provisioning batch submit <workflow.ncl>(ansi reset)"
$" • Update infrastructure: (ansi green)provisioning guide update(ansi reset)\n"
$"(ansi yellow_bold)Platform Services:(ansi reset)"
$" • Start orchestrator: (ansi green)cd provisioning/platform/orchestrator && ./scripts/start-orchestrator.nu(ansi reset)"
$" • Control Center: (ansi green)cd provisioning/platform/control-center && ./serve.nu(ansi reset)\n"
$"(ansi blue_bold)📚 Documentation:(ansi reset)"
$" • Service Management: docs/user/SERVICE_MANAGEMENT_GUIDE.md"
$" • Quick Reference: provisioning sc"
$" • Update Guide: docs/guides/update-infrastructure.md"
$" • Customize Guide: docs/guides/customize-infrastructure.md"
] | str join "\n"
}
# Get next steps for error state
def next-steps-error [] {
[
$"(ansi red_bold)⚠️ Configuration Error Detected(ansi reset)\n"
$"There was an error checking your system state.\n"
$"(ansi yellow_bold)Recommended Actions:(ansi reset)\n"
$"1. Check system status:"
$" Command: (ansi green)provisioning status(ansi reset)\n"
$"2. Run health check:"
$" Command: (ansi green)provisioning health(ansi reset)\n"
$"3. Validate configuration:"
$" Command: (ansi green)provisioning validate config(ansi reset)\n"
$"4. Check logs for errors:"
$" Location: workspace/runtime/logs/\n"
$"(ansi blue_bold)📚 Documentation:(ansi reset)"
$" • Troubleshooting: docs/user/troubleshooting-guide.md"
$" • Configuration Guide: docs/user/WORKSPACE_SWITCHING_GUIDE.md"
$" • Quick Reference: provisioning sc"
] | str join "\n"
}
# Main next steps command
# Intelligent next-step recommendations based on current deployment state
export def "provisioning next" [] {
let phase = (get-deployment-phase)
let message = match $phase {
"no_workspace" => { next-steps-no-workspace }
"invalid_workspace" => { next-steps-no-workspace }
"no_infrastructure" => { next-steps-no-infrastructure }
"no_servers" => { next-steps-no-servers }
"no_taskservs" => { next-steps-no-taskservs }
"no_clusters" => { next-steps-no-clusters }
"deployed" => { next-steps-deployed }
"error" => { next-steps-error }
_ => { next-steps-error }
}
print $message
}
# Get current deployment phase (machine-readable)
export def "provisioning phase" [] {
let phase = (get-deployment-phase)
let phase_info = match $phase {
"no_workspace" => {
phase: "initialization"
step: 1
total_steps: 5
description: "No workspace configured"
ready_for_deployment: false
}
"invalid_workspace" => {
phase: "initialization"
step: 1
total_steps: 5
description: "Workspace path invalid or missing"
ready_for_deployment: false
}
"no_infrastructure" => {
phase: "configuration"
step: 2
total_steps: 5
description: "Workspace created, infrastructure not defined"
ready_for_deployment: false
}
"no_servers" => {
phase: "deployment"
step: 3
total_steps: 5
description: "Infrastructure defined, servers not deployed"
ready_for_deployment: false
}
"no_taskservs" => {
phase: "provisioning"
step: 4
total_steps: 5
description: "Servers deployed, taskservs not installed"
ready_for_deployment: false
}
"no_clusters" => {
phase: "orchestration"
step: 5
total_steps: 5
description: "Taskservs installed, clusters not deployed"
ready_for_deployment: false
}
"deployed" => {
phase: "production"
step: 5
total_steps: 5
description: "Fully deployed and operational"
ready_for_deployment: true
}
_ => {
phase: "error"
step: 0
total_steps: 5
description: "Error determining deployment state"
ready_for_deployment: false
}
}
{
timestamp: (date now | format date "%Y-%m-%dT%H:%M:%SZ")
current_phase: $phase
info: $phase_info
progress_percentage: (($phase_info.step / $phase_info.total_steps) * 100 | math round)
}
}