Skip to content

feat: add interactive cluster initialization wizard#82

Open
irony wants to merge 2 commits into
mainfrom
feat/cluster-init-wizard
Open

feat: add interactive cluster initialization wizard#82
irony wants to merge 2 commits into
mainfrom
feat/cluster-init-wizard

Conversation

@irony

@irony irony commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

feat: Interactive Cluster Initialization Wizard

Summary

Adds berget clusters init — an interactive wizard for bootstrapping new Kubernetes clusters with FluxCD GitOps and Berget's standard infrastructure components.

What's New

Command:

berget clusters init                          # Interactive wizard
berget clusters init --template-repo          # Use official template
berget clusters init --cluster-name my-cluster --domain example.com
berget clusters init --components cert-manager,external-dns,ingress-nginx

Features:

  • ✅ Interactive prompts via @clack/prompts
  • ✅ Prerequisites checking (kubectl, flux, git)
  • ✅ Component selection from berget-k8s-template:
    • cert-manager (Let's Encrypt TLS)
    • external-dns (RFC2136 DNS automation)
    • ingress-nginx (HTTP/HTTPS routing)
    • cloudnative-pg (PostgreSQL operator)
    • redis-operator (Redis operator)
    • prometheus (metrics collection)
    • grafana (visualization dashboards)
  • ✅ Automatic YAML manifest generation with placeholder replacement
  • ✅ Flux bootstrap integration
  • ✅ Support for official template repo or custom repositories

Architecture

src/commands/clusters/
├── init.ts              # Wizard logic (interactive flow)
├── init-command.ts      # CLI adapter (error handling)
├── yaml-generator.ts    # YAML manifest generation
└── __tests__/
    └── yaml-generator.test.ts

Design Decisions

  1. Local execution: All commands run locally via SpawnCommandRunner (not API calls)
  2. Template-based: Uses berget-k8s-template as the source of truth for manifests
  3. Ports/Adapters pattern: Same testable architecture as berget code init
  4. gcloud/aws inspired: clusters init follows cloud CLI conventions

Testing

# Run YAML generator tests
npx vitest run src/commands/clusters/__tests__/yaml-generator.test.ts

All 6 tests passing ✅

Usage Example

# Interactive setup
$ berget clusters init
? What is your cluster name? my-cluster
? What is your base domain? example.com
? How do you want to set up the GitOps repository? Use berget-k8s-template
? Which components do you want to install? cert-manager, external-dns, ingress-nginx
? Proceed with this configuration? Yes
✓ Cluster directory created
? Run flux bootstrap now? Yes
✓ Flux bootstrap completed

Post-Setup

After initialization, users need to:

  1. Commit and push generated files to their repository
  2. Create required secrets (external-dns TSIG, grafana admin)
  3. Monitor FluxCD reconciliation with flux get kustomizations -A

Copilot AI review requested due to automatic review settings July 6, 2026 12:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new berget clusters init interactive wizard to bootstrap FluxCD GitOps + common infra components, plus supporting YAML manifest generation. The PR also introduces a sizeable new src/commands/code/* OpenCode configuration/installer/merge module that is not currently wired into the CLI and is not mentioned in the PR description.

Changes:

  • Add clusters init subcommand and interactive setup flow (repo selection, component selection, optional Flux bootstrap).
  • Add a YAML manifest generator for selected infrastructure components, with Vitest coverage for generator behavior.
  • Add new OpenCode “code” command helpers (config builder/merger, installer, docs generator, handlers/types), currently exported but not registered with Commander.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/constants/command-structure.ts Adds clusters init subcommand constant + description string.
src/commands/code/types.ts New type definitions for the new code-command module.
src/commands/code/opencode-installer.ts Adds OpenCode install/check helpers (npm global install).
src/commands/code/index.ts Barrel exports for the new code-command module (currently unused by CLI).
src/commands/code/helpers.ts Adds readline-based prompt helpers used by new code handlers.
src/commands/code/handlers/update.ts Adds berget code update handler logic for updating opencode.json.
src/commands/code/handlers/run.ts Adds berget code run handler logic to spawn opencode.
src/commands/code/handlers/init.ts Adds berget code init handler logic to create opencode.json/.env/AGENTS.md.
src/commands/code/handlers/index.ts Exports the new code handlers.
src/commands/code/documentation-generator.ts Generates/writes AGENTS.md and ensures .env is gitignored.
src/commands/code/config-merger.ts Adds AI-assisted config merging with fallback merge logic.
src/commands/code/config-builder.ts Builds the opencode.json “single source of truth” configuration.
src/commands/code/api-key-handler.ts Adds API key selection/creation/rotation logic for the new code flow.
src/commands/clusters/yaml-generator.ts Implements component manifest templates + placeholder replacement + manifest helper APIs.
src/commands/clusters/init.ts Implements the interactive cluster init wizard and Flux bootstrap integration.
src/commands/clusters/init-command.ts CLI adapter for clusters init (parses flags, handles exit codes).
src/commands/clusters/tests/yaml-generator.test.ts Adds unit tests for yaml-generator (components, descriptions, placeholder replacement).
src/commands/clusters.ts Registers the new clusters init command with Commander.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +65 to +85
const trimmed = answer.trim().toLowerCase()

// Handle numeric input (1, 2, etc.)
const numericIndex = parseInt(trimmed) - 1
if (numericIndex >= 0 && numericIndex < options.length) {
resolve(options[numericIndex])
return
}

// Handle text input
const matchingOption = options.find((option) =>
option.toLowerCase().startsWith(trimmed)
)

if (matchingOption) {
resolve(matchingOption)
} else if (defaultChoice) {
resolve(defaultChoice)
} else {
resolve(options[0]) // Default to first option
}
const domain = options.domain || (await promptDomain(prompter));

// Determine repository setup
const repoConfig = await promptRepositorySetup(prompter, options);
Comment on lines +25 to +27
const components = options.components
? options.components.split(',').map((c) => c.trim())
: undefined;
Comment on lines +424 to +426
// Determine namespace from the manifest
const namespaceMatch = content.match(/name: ([a-z-]+)/);
const namespace = namespaceMatch ? namespaceMatch[1] : 'default';
Comment on lines +22 to +30
console.log(chalk.blue('🤖 Using AI to merge configurations...'))

const mergePrompt = `You are a configuration merge specialist. Merge these two OpenCode configurations:

CURRENT CONFIG (user's customizations):
${JSON.stringify(currentConfig, null, 2)}

LATEST CONFIG (new updates):
${JSON.stringify(latestConfig, null, 2)}
Comment on lines +344 to +348
// Clone template repository
const tempDir = `${cwd}/.berget-cluster-init-${Date.now()}`;
s.start('Cloning berget-k8s-template...');
try {
await commands.run('git', [
Comment on lines +13 to +17
export {
handleInitCommand,
handleRunCommand,
handleUpdateCommand,
} from './handlers'
Add berget clusters init command for setting up new Kubernetes clusters
with FluxCD GitOps and infrastructure components.

Features:
- Interactive wizard with clack prompts
- Automatic YAML manifest generation from berget-k8s-template
- Support for official template repo or custom repositories
- Component selection: cert-manager, external-dns, ingress-nginx,
  cloudnative-pg, redis-operator, prometheus, grafana
- Flux bootstrap integration
- Prerequisites checking (kubectl, flux, git)

New files:
- src/commands/clusters/init.ts (wizard logic)
- src/commands/clusters/init-command.ts (command adapter)
- src/commands/clusters/yaml-generator.ts (YAML generation)
- src/commands/clusters/__tests__/yaml-generator.test.ts

Modified:
- src/commands/clusters.ts (added init command)
- src/constants/command-structure.ts (added INIT subcommand)
@irony irony force-pushed the feat/cluster-init-wizard branch from 2a1019c to f4770c1 Compare July 6, 2026 13:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants