diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e5be2c28..e59b9886 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,323 +1,358 @@ # Contributing to OpenFrame CLI -We're excited that you're interested in contributing to OpenFrame CLI! This guide will help you get started with contributing to the project. +Thank you for your interest in contributing to OpenFrame CLI! This guide covers how to set up your development environment, the coding standards we follow, and the process for submitting contributions. + +> **Community First:** All development discussions, bug reports, and feature requests are managed in the **[OpenMSP Slack community](https://join.slack.com/t/openmsp/shared_invite/zt-36bl7mx0h-3~U2nFH6nqHqoTPXMaHEHA)** — not GitHub Issues or GitHub Discussions. + +--- + +## Table of Contents + +- [Code of Conduct](#code-of-conduct) +- [Getting Started](#getting-started) +- [Development Environment Setup](#development-environment-setup) +- [Building the Project](#building-the-project) +- [Running Tests](#running-tests) +- [Code Style & Quality](#code-style--quality) +- [Architecture Guidelines](#architecture-guidelines) +- [Submitting a Pull Request](#submitting-a-pull-request) +- [Security Issues](#security-issues) + +--- + +## Code of Conduct + +Be respectful, collaborative, and constructive. The OpenMSP community is a welcoming place for contributors of all experience levels. + +--- ## Getting Started -### Prerequisites +### System Requirements -Before you begin, ensure you have: +| Tier | RAM | CPU Cores | Disk Space | +|------|-----|-----------|------------| +| **Minimum** | 24 GB | 6 cores | 50 GB | +| **Recommended** | 32 GB | 12 cores | 100 GB | -- Go 1.24.6 or higher -- Docker 20.10+ (with daemon running) -- kubectl 1.25+ -- Helm 3.10+ -- K3D 5.0+ -- Git +### Required Tools -### Development Environment Setup +| Tool | Minimum Version | Purpose | +|------|----------------|---------| +| **Go** | 1.21+ | Build the CLI | +| **Docker** | 20.10+ | Run K3D container nodes | +| **k3d** | 5.x | Local Kubernetes clusters | +| **kubectl** | 1.25+ | Kubernetes interaction | +| **Helm** | 3.x | Chart installation | +| **Git** | 2.x | Repository operations | +| **mkcert** | 1.4+ | Local TLS certificates | -1. **Fork and Clone the Repository** -```bash -# Fork the repo on GitHub, then clone your fork -git clone https://github.com/YOUR_USERNAME/openframe-cli.git -cd openframe-cli +### Optional (for `dev` commands) -# Add upstream remote -git remote add upstream https://github.com/flamingo-stack/openframe-cli.git -``` +| Tool | Purpose | +|------|---------| +| **Telepresence** 2.x | Live traffic intercepts | +| **Skaffold** | Hot-reload dev sessions | +| **jq** 1.6+ | JSON processing | -2. **Set Up Your Development Environment** +--- -Follow the [Development Environment Setup](./docs/development/setup/environment.md) guide for detailed IDE configuration, tools, and environment variables. +## Development Environment Setup -3. **Install Go Tools** -```bash -# Install essential Go development tools -go install golang.org/x/tools/cmd/goimports@latest -go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest -go install github.com/rakyll/gotest@latest -``` +### 1. Go Toolchain + +OpenFrame CLI requires **Go 1.21 or newer**. -4. **Build and Test** ```bash -# Build the project -go build -o openframe main.go +# Verify your Go version +go version +# Expected: go version go1.21.x or higher +``` -# Run tests -go test ./... +Configure your Go environment by adding to your shell profile (`~/.bashrc`, `~/.zshrc`, etc.): -# Run linter -golangci-lint run +```bash +export GOPATH=$HOME/go +export GOBIN=$GOPATH/bin +export PATH=$PATH:$GOBIN ``` -## Development Workflow - -### Branch Management +### 2. Clone the Repository -1. **Create a Feature Branch** ```bash -git checkout -b feature/your-feature-name +git clone https://github.com/flamingo-stack/openframe-cli.git +cd openframe-cli ``` -2. **Keep Your Branch Up to Date** +### 3. Install Dependencies + ```bash -git fetch upstream -git rebase upstream/main +go mod download +go mod verify ``` -### Code Standards +### 4. Install Code Quality Tools + +```bash +# goimports — import organizer +go install golang.org/x/tools/cmd/goimports@latest -#### Go Code Style -- Follow standard Go conventions and idioms -- Use `gofmt` and `goimports` for formatting -- Write clear, self-documenting code with meaningful names -- Include comments for exported functions and complex logic +# golangci-lint — multi-linter runner +curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOBIN) latest -#### Project Structure -```text -openframe-cli/ -├── cmd/ # CLI command definitions -├── internal/ -│ ├── cluster/ # Cluster management logic -│ ├── chart/ # Chart and ArgoCD management -│ ├── dev/ # Development tools -│ ├── bootstrap/ # Environment bootstrapping -│ └── shared/ # Common utilities -├── docs/ # Documentation -├── scripts/ # Build and utility scripts -└── main.go # Application entry point +# Verify +goimports --version +golangci-lint --version ``` -#### Testing Guidelines -- Write unit tests for all business logic -- Include integration tests for external tool interactions -- Use table-driven tests where appropriate -- Mock external dependencies using interfaces +### 5. Recommended IDE: VS Code -Example test structure: -```go -func TestClusterCreate(t *testing.T) { - tests := []struct { - name string - input ClusterConfig - expected error - }{ - { - name: "valid cluster creation", - input: ClusterConfig{ - Name: "test-cluster", - Nodes: 3, - }, - expected: nil, - }, - // Add more test cases... - } +Install these extensions: + +```bash +code --install-extension golang.go +code --install-extension eamodio.gitlens +code --install-extension redhat.vscode-yaml +``` - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := CreateCluster(tt.input) - assert.Equal(t, tt.expected, err) - }) +Create `.vscode/settings.json`: + +```json +{ + "go.useLanguageServer": true, + "go.lintTool": "golangci-lint", + "go.lintOnSave": "package", + "go.formatTool": "goimports", + "editor.formatOnSave": true, + "[go]": { + "editor.defaultFormatter": "golang.go", + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.organizeImports": "always" } + } } ``` -### Commit Guidelines +--- -Follow conventional commit format: +## Building the Project -```text -[optional scope]: +```bash +# Build the binary to the project root +go build -o openframe ./main.go -[optional body] +# Verify +./openframe --version -[optional footer(s)] +# Cross-platform builds +GOOS=linux GOARCH=amd64 go build -o openframe-linux-amd64 ./main.go +GOOS=darwin GOARCH=arm64 go build -o openframe-darwin-arm64 ./main.go +GOOS=windows GOARCH=amd64 go build -o openframe-windows-amd64.exe ./main.go ``` -**Types:** -- `feat:` New feature -- `fix:` Bug fix -- `docs:` Documentation changes -- `style:` Code style changes (formatting, etc.) -- `refactor:` Code refactoring -- `test:` Adding or updating tests -- `chore:` Build process or auxiliary tool changes +### Hot Reload with Air -**Examples:** ```bash -git commit -m "feat(cluster): add support for custom node configurations" -git commit -m "fix(bootstrap): resolve ArgoCD installation timeout" -git commit -m "docs: update prerequisites and installation guide" +go install github.com/air-verse/air@latest +air ``` -### Pull Request Process +--- -1. **Prepare Your PR** -```bash -# Ensure your branch is up to date -git fetch upstream -git rebase upstream/main +## Running Tests -# Run all checks -go fmt ./... -goimports -w . -golangci-lint run +```bash +# Run all unit tests go test ./... -``` -2. **Submit Your Pull Request** -- Use a clear, descriptive title -- Include a detailed description of changes -- Reference any related issues -- Add screenshots/logs for UI or behavioral changes -- Ensure all CI checks pass +# Verbose output +go test ./... -v -3. **PR Template** -```markdown -## Description -Brief description of the changes and their purpose. +# Specific package +go test ./internal/cluster/... -## Type of Change -- [ ] Bug fix (non-breaking change which fixes an issue) -- [ ] New feature (non-breaking change which adds functionality) -- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) -- [ ] Documentation update +# With race detection +go test -race ./... -## Testing -- [ ] Unit tests pass -- [ ] Integration tests pass -- [ ] Manual testing completed +# Short tests only (skips integration) +go test ./... -short -## Checklist -- [ ] My code follows the project's style guidelines -- [ ] I have performed a self-review of my code -- [ ] I have commented my code, particularly in hard-to-understand areas -- [ ] I have made corresponding changes to the documentation -- [ ] My changes generate no new warnings +# Integration tests (requires Docker, k3d, kubectl, helm) +go test ./tests/integration/... + +# Coverage report +go test -coverprofile=coverage.out ./... +go tool cover -html=coverage.out -o coverage.html +``` + +### Understanding the Mock Executor + +All external command execution (k3d, helm, kubectl, git) goes through the `CommandExecutor` interface. Unit tests inject a `MockCommandExecutor` that returns pre-configured responses without running real binaries: + +```go +// In test files +testutil.InitializeTestMode() +executor := testutil.NewTestMockExecutor() +flags := testutil.CreateStandardTestFlags() ``` -## Code Review Process +This allows full business logic coverage without a real Kubernetes cluster. -### For Contributors -- Respond promptly to review feedback -- Address all comments and suggestions -- Ask questions if feedback is unclear -- Update documentation if your changes affect user-facing behavior +--- -### For Reviewers -- Provide constructive, actionable feedback -- Focus on code quality, maintainability, and correctness -- Check that tests adequately cover new functionality -- Verify documentation updates are included +## Code Style & Quality -## Testing +### Formatting and Linting -### Running Tests ```bash -# Run all tests -go test ./... +# Format all Go files +goimports -w . -# Run tests with coverage -go test -race -coverprofile=coverage.out ./... -go tool cover -html=coverage.out +# Run the linter +golangci-lint run ./... -# Run specific package tests -go test ./internal/cluster/... +# Check for compilation errors +go vet ./... -# Run integration tests (requires Docker) -go test -tags=integration ./... +# Tidy dependencies +go mod tidy ``` -### Test Categories -- **Unit Tests**: Test individual functions and components -- **Integration Tests**: Test interactions with external tools (Docker, kubectl, etc.) -- **End-to-End Tests**: Test complete workflows from CLI to cluster +### Code Organisation Principles + +OpenFrame CLI follows a **layered clean architecture**: + +1. **`cmd/` layer** — Thin Cobra command definitions only. No business logic. Parse flags, validate combinations, delegate to services. +2. **`internal/*/service*.go`** — Business logic orchestration. Sequence multi-step operations, coordinate providers, manage UI feedback. +3. **`internal/*/providers/`** — Thin wrappers around external tools and APIs. Each provider implements an interface. +4. **`internal/shared/`** — Cross-cutting utilities (executor, UI, errors, config, files). + +**Rules:** +- All external subprocess calls go through `CommandExecutor` — never call `os/exec` directly +- Never interpolate user input into shell strings — always use argument slices +- All providers must have a corresponding interface for mock injection +- No business logic in `cmd/` — it is a wiring layer only -### Writing Good Tests -- Test both happy path and error conditions -- Use descriptive test names that explain what is being tested -- Keep tests focused and atomic -- Use test fixtures and helpers to reduce duplication +### Security Checklist for PRs -## Documentation +Before submitting a pull request, verify: -### Types of Documentation -- **Code Comments**: Explain complex logic and public APIs -- **README Updates**: Keep installation and usage instructions current -- **Developer Docs**: Architecture, design decisions, and development guides -- **User Guides**: Step-by-step tutorials and reference material +- [ ] No credentials or secrets hardcoded in source files +- [ ] All user input validated before use as a command argument +- [ ] External commands use argument slices (not string concatenation) +- [ ] Temporary files are cleaned up in both success and failure paths +- [ ] No new uses of insecure TLS outside K3D-scoped local contexts +- [ ] Error messages do not leak sensitive information (tokens, paths, credentials) +- [ ] `helm-values-tmp.yaml` is gitignored in any new workflows -### Documentation Guidelines -- Write clear, concise instructions -- Include code examples where helpful -- Update docs when making user-facing changes -- Use proper Markdown formatting +--- + +## Architecture Guidelines + +### Interface-Based External I/O -## Release Process +```go +// All subprocess execution goes through this interface +type CommandExecutor interface { + Execute(ctx context.Context, command string, args ...string) (*CommandResult, error) + ExecuteWithOptions(ctx context.Context, opts ExecuteOptions) (*CommandResult, error) +} +``` -### Version Management -We use semantic versioning (SemVer): -- **MAJOR**: Breaking changes -- **MINOR**: New features (backward compatible) -- **PATCH**: Bug fixes (backward compatible) +Any new provider must implement an interface so tests can inject a mock. -### Creating a Release -1. Update version in `main.go` -2. Update `CHANGELOG.md` -3. Create and push version tag -4. GitHub Actions handles the build and release +### Shell Injection Prevention -## Issue Management +```go +// CORRECT: arguments as a slice — user input never interpolated +result, err := executor.Execute(ctx, "k3d", "cluster", "create", clusterName) -### Reporting Issues -When reporting bugs or requesting features: -- Check existing issues first -- Use issue templates when available -- Provide detailed reproduction steps for bugs -- Include system information and versions +// NEVER do this: +// exec.Command("sh", "-c", "k3d cluster create " + clusterName) +``` -### Working on Issues -- Comment on issues before starting work -- Ask for clarification if requirements are unclear -- Link your PR to the issue when ready +### Error Handling -## Community Guidelines +Use the typed errors from `internal/shared/errors/`: -### Communication Channels -- **Primary Support**: [OpenMSP Slack](https://join.slack.com/t/openmsp/shared_invite/zt-36bl7mx0h-3~U2nFH6nqHqoTPXMaHEHA) -- **Development Discussion**: GitHub PR comments and code reviews -- **Feature Requests**: GitHub Issues +```go +return errors.CreateValidationError("cluster-name", name, err.Error()) +return errors.NewBranchNotFoundError(branch, repo) +``` -### Code of Conduct -- Be respectful and inclusive in all interactions -- Focus on constructive feedback and solutions -- Help newcomers get started -- Follow the project's technical standards and conventions +--- -## Getting Help +## Submitting a Pull Request -Need assistance? Here's how to get help: +### Workflow -1. **Development Questions**: Ask in OpenMSP Slack #dev channel -2. **Documentation Issues**: Create a GitHub issue with the "documentation" label -3. **Bug Reports**: File a GitHub issue with reproduction steps -4. **Feature Ideas**: Discuss in Slack first, then create GitHub issue +1. **Discuss first** — Share your idea in the [OpenMSP Slack](https://join.slack.com/t/openmsp/shared_invite/zt-36bl7mx0h-3~U2nFH6nqHqoTPXMaHEHA) before writing code +2. **Fork and branch** — Create a feature branch from `main` +3. **Write tests** — Unit tests for new business logic; integration tests for new commands +4. **Run quality checks** — All linting and tests must pass +5. **Submit PR** — Write a clear description of what and why -## External Dependencies +### PR Description Template -### CLI Tools Integration -This repository contains OpenFrame CLI code. The main OpenFrame application code is maintained separately: +```text +## What +Brief description of the change. -- **OpenFrame Main Repository**: [flamingo-stack/openframe-oss-tenant](https://github.com/flamingo-stack/openframe-oss-tenant) -- **CLI Documentation**: [CLI Documentation](https://github.com/flamingo-stack/openframe-oss-tenant/tree/main/docs) +## Why +The problem this solves or feature this adds. -When contributing CLI-related changes, coordinate with the main repository team through Slack. +## How +Key implementation decisions. + +## Testing +How you tested the change (unit tests, manual testing, integration tests). + +## Checklist +- [ ] Tests pass: go test ./... +- [ ] Linter passes: golangci-lint run ./... +- [ ] No hardcoded credentials +- [ ] Follows layered architecture (no business logic in cmd/) +- [ ] External commands use argument slices (not shell strings) +``` + +### Commit Message Format + +```text +(): + + +``` + +Types: `feat`, `fix`, `docs`, `test`, `refactor`, `chore` + +Examples: + +```text +feat(cluster): add --timeout flag to cluster create command + +fix(chart): handle BranchNotFoundError with retry suggestion + +docs(dev): update intercept command flag descriptions +``` + +--- + +## Security Issues + +For security vulnerabilities, **do not open a public GitHub issue**. Report directly via the [OpenMSP Slack community](https://join.slack.com/t/openmsp/shared_invite/zt-36bl7mx0h-3~U2nFH6nqHqoTPXMaHEHA). + +--- -## Acknowledgments +## Community -Thank you for contributing to OpenFrame CLI! Your efforts help make IT operations more accessible and cost-effective for MSPs worldwide. +- **OpenMSP Slack:** [Join here](https://join.slack.com/t/openmsp/shared_invite/zt-36bl7mx0h-3~U2nFH6nqHqoTPXMaHEHA) — primary support and discussion channel +- **OpenMSP Website:** [https://www.openmsp.ai/](https://www.openmsp.ai/) +- **OpenFrame Platform:** [https://openframe.ai](https://openframe.ai) +- **Flamingo Platform:** [https://flamingo.run](https://flamingo.run) --- -**Questions?** Join our [OpenMSP Slack community](https://join.slack.com/t/openmsp/shared_invite/zt-36bl7mx0h-3~U2nFH6nqHqoTPXMaHEHA) - we're here to help! \ No newline at end of file +
+ Built with 💛 by the Flamingo team +
diff --git a/README.md b/README.md index dc599187..5d4eb5da 100644 --- a/README.md +++ b/README.md @@ -12,197 +12,226 @@ # OpenFrame CLI -OpenFrame CLI is a modern, interactive command-line tool for managing OpenFrame Kubernetes clusters and development workflows. It provides seamless cluster lifecycle management, chart installation with ArgoCD, and developer-friendly tools for service intercepts and scaffolding. +**OpenFrame CLI** is a modern, interactive command-line tool written in Go for bootstrapping and managing [OpenFrame](https://openframe.ai) Kubernetes environments. It is the primary developer-facing entry point to the OpenFrame AI-powered MSP platform — replacing brittle shell scripts with a wizard-style terminal interface that guides you through every step of your environment lifecycle. -[![OpenFrame Preview Webinar](https://img.youtube.com/vi/bINdW0CQbvY/maxresdefault.jpg)](https://www.youtube.com/watch?v=bINdW0CQbvY) +From a single command you can spin up a fully operational local Kubernetes cluster, install ArgoCD, deploy the complete OpenFrame application stack via the App-of-Apps GitOps pattern, and begin intercepting live cluster traffic in your local IDE — all without memorizing dozens of manual steps. -## What is OpenFrame CLI? +> Part of the [Flamingo](https://flamingo.run) ecosystem — an AI-powered MSP platform that replaces expensive proprietary software with open-source alternatives enhanced by intelligent automation (Mingo AI for technicians, Fae for clients). -OpenFrame CLI is part of the broader [OpenFrame](https://openframe.ai) ecosystem - an AI-powered MSP platform that replaces expensive proprietary software with open-source alternatives enhanced by intelligent automation. The CLI serves as the entry point for developers and operators to bootstrap, manage, and develop on OpenFrame environments. +--- + +[![Autonomous AI Agents That Actually Fix Your Infrastructure | OpenFrame v0.5.2](https://img.youtube.com/vi/jEkFcS4AcQ4/maxresdefault.jpg)](https://www.youtube.com/watch?v=jEkFcS4AcQ4) -## Key Features +--- -### 🚀 Complete Environment Bootstrapping -- **One-command setup**: Bootstrap entire OpenFrame environments with `openframe bootstrap` -- **Multi-mode deployment**: Support for OSS tenant, SaaS tenant, and SaaS shared modes -- **Automated cluster creation**: Creates K3D clusters with all necessary components -- **ArgoCD integration**: Automatic chart installation and application management +## Features -### 🔧 Cluster Management -- **Lifecycle operations**: Create, delete, list, and monitor Kubernetes clusters -- **K3D integration**: Lightweight Kubernetes for development and testing -- **Status monitoring**: Real-time cluster health and resource monitoring -- **Easy cleanup**: Remove clusters and associated resources with simple commands +| Feature | Description | +|---------|-------------| +| **One-Command Bootstrap** | `openframe bootstrap` creates a K3D cluster, installs ArgoCD, and deploys the full stack in one shot | +| **Interactive Wizard UI** | Step-by-step guided prompts for cluster names, deployment modes, ingress, and Docker registry settings | +| **Cluster Lifecycle Management** | Create, delete, list, check status, and clean up K3D clusters | +| **Helm & ArgoCD Integration** | Installs ArgoCD via Helm and waits for all Application CRDs to reach Healthy+Synced state | +| **Local Dev Workflows** | Telepresence-based service intercepts route live cluster traffic to your local process | +| **Skaffold Hot Reload** | `openframe dev skaffold` discovers `skaffold.yaml` files and starts live-reload dev sessions | +| **Prerequisite Checking** | Validates Docker, k3d, kubectl, helm, git, and mkcert before any operation | +| **Cross-Platform** | Full Linux, macOS, and Windows (WSL2) support with native path handling | +| **CI/CD Friendly** | `--non-interactive` and `--deployment-mode` flags for fully automated pipelines | -### 📦 Chart & Application Management -- **Helm chart installation**: Streamlined chart deployment with dependency management -- **ArgoCD applications**: GitOps-based application lifecycle management -- **App-of-apps pattern**: Hierarchical application management for complex deployments -- **Synchronization monitoring**: Track deployment progress with detailed logging +--- -### 🛠 Development Tools -- **Service intercepts**: Local development with Telepresence integration -- **Scaffolding**: Generate boilerplate code and configurations -- **Live debugging**: Debug services running in Kubernetes from your local environment -- **Hot reload**: Rapid development cycles with instant feedback +## Architecture -## Architecture Overview +OpenFrame CLI follows a layered clean architecture: thin Cobra command handlers delegate to service layers, which compose providers and infrastructure utilities. All external I/O is abstracted behind interfaces to maximize testability. ```mermaid -graph TB - subgraph "CLI Commands" - Bootstrap[openframe bootstrap] - Cluster[openframe cluster] - Chart[openframe chart] - Dev[openframe dev] +graph TD + subgraph CLI["CLI Entry Layer (cmd/)"] + Root["Root Command"] + Bootstrap["bootstrap"] + Cluster["cluster"] + Chart["chart"] + Dev["dev"] end - - subgraph "Core Services" - ClusterSvc[Cluster Management] - ChartSvc[Chart Installation] - DevSvc[Development Tools] + + subgraph Services["Service Layer (internal/)"] + BootstrapSvc["Bootstrap Service"] + ClusterSvc["Cluster Service"] + ChartSvc["Chart Service"] + DevSvc["Dev Services"] end - - subgraph "External Tools" - K3D[K3D Clusters] - Helm[Helm Charts] - ArgoCD[ArgoCD Apps] - Telepresence[Service Intercepts] + + subgraph Providers["Provider Layer"] + K3D["K3D Manager"] + HelmMgr["Helm Manager"] + ArgoCDMgr["ArgoCD Manager"] + GitRepo["Git Repository"] + TelepresenceProv["Telepresence Provider"] end - - subgraph "Target Environment" - K8s[Kubernetes] - Apps[Applications] - Services[Microservices] + + subgraph External["External Systems"] + K3dBin["k3d binary"] + HelmBin["helm binary"] + ArgoCDAPI["ArgoCD Kubernetes API"] + GitHubRepo["GitHub Repository"] + K8sAPI["Kubernetes API"] + TelepresenceBin["telepresence binary"] end - - Bootstrap --> ClusterSvc - Bootstrap --> ChartSvc + + Root --> Bootstrap + Root --> Cluster + Root --> Chart + Root --> Dev + + Bootstrap --> BootstrapSvc Cluster --> ClusterSvc Chart --> ChartSvc Dev --> DevSvc - + + BootstrapSvc --> ClusterSvc + BootstrapSvc --> ChartSvc + ClusterSvc --> K3D - ChartSvc --> Helm - ChartSvc --> ArgoCD - DevSvc --> Telepresence - - K3D --> K8s - Helm --> Apps - ArgoCD --> Apps - Telepresence --> Services + ChartSvc --> HelmMgr + ChartSvc --> ArgoCDMgr + ChartSvc --> GitRepo + DevSvc --> TelepresenceProv + + K3D --> K3dBin + HelmMgr --> HelmBin + HelmMgr --> ArgoCDAPI + ArgoCDMgr --> K8sAPI + GitRepo --> GitHubRepo + TelepresenceProv --> TelepresenceBin ``` -## Quick Start +--- -Get OpenFrame CLI up and running in 5 minutes! +## Quick Start ### System Requirements -| Resource | Minimum | Recommended | -|----------|---------|-------------| -| **RAM** | 24GB | 32GB | -| **CPU Cores** | 6 cores | 12 cores | -| **Disk Space** | 50GB free | 100GB free | +| Tier | RAM | CPU Cores | Disk Space | +|------|-----|-----------|------------| +| **Minimum** | 24 GB | 6 cores | 50 GB | +| **Recommended** | 32 GB | 12 cores | 100 GB | -### Prerequisites +### Step 1 — Download the CLI -Before installation, ensure you have: -- [Docker](https://docs.docker.com/get-docker/) 20.10+ -- [kubectl](https://kubernetes.io/docs/tasks/tools/) 1.25+ -- [Helm](https://helm.sh/docs/intro/install/) 3.10+ -- [K3D](https://k3d.io/v5.4.6/#installation) 5.0+ +| Platform | Download | +|----------|----------| +| Linux AMD64 | `openframe-cli_linux_amd64.tar.gz` | +| macOS (Apple Silicon) | `openframe-cli_darwin_arm64.tar.gz` | +| macOS (Intel) | `openframe-cli_darwin_amd64.tar.gz` | +| Windows AMD64 | [`openframe-cli_windows_amd64.zip`](https://github.com/flamingo-stack/openframe-cli/releases/latest/download/openframe-cli_windows_amd64.zip) | -### Installation +All releases: [https://github.com/flamingo-stack/openframe-cli/releases](https://github.com/flamingo-stack/openframe-cli/releases) -Choose your platform and install OpenFrame CLI: +### Step 2 — Install the Binary -#### Linux (AMD64) ```bash -curl -fsSL https://github.com/flamingo-stack/openframe-cli/releases/latest/download/openframe-cli_linux_amd64.tar.gz | tar -xz -sudo mv openframe /usr/local/bin/ -chmod +x /usr/local/bin/openframe +# Linux / macOS +curl -LO https://github.com/flamingo-stack/openframe-cli/releases/latest/download/openframe-cli_linux_amd64.tar.gz +tar -xzf openframe-cli_linux_amd64.tar.gz +chmod +x openframe +sudo mv openframe /usr/local/bin/openframe + +# Verify installation +openframe --version ``` -#### macOS (Apple Silicon) +For Windows (AMD64), download the zip from the link above, extract it, and run the installer the same way as other platforms. + +### Step 3 — Bootstrap Your Environment + ```bash -curl -fsSL https://github.com/flamingo-stack/openframe-cli/releases/latest/download/openframe-cli_darwin_arm64.tar.gz | tar -xz -sudo mv openframe /usr/local/bin/ -chmod +x /usr/local/bin/openframe -``` +# Interactive mode — wizard guides you through all setup steps +openframe bootstrap -#### Windows (WSL2) -1. Download: https://github.com/flamingo-stack/openframe-cli/releases/latest/download/openframe-cli_windows_amd64.zip -2. Extract and move `openframe.exe` to a directory in your `PATH` -3. Open WSL2 terminal and verify access +# Non-interactive OSS tenant setup +openframe bootstrap my-cluster --deployment-mode=oss-tenant -### Bootstrap Your Environment +# Verbose output to watch ArgoCD sync progress +openframe bootstrap my-cluster --deployment-mode=oss-tenant -v +``` -Create a complete OpenFrame environment with a single command: +### Step 4 — Verify ```bash -# Verify installation -openframe --version - -# Bootstrap complete environment -openframe bootstrap +# List your cluster +openframe cluster list # Check cluster status -openframe cluster status +openframe cluster status my-cluster + +# Confirm all pods are running +kubectl get pods -A ``` -The bootstrap process creates: -- K3D Kubernetes cluster -- ArgoCD for GitOps deployment -- Traefik ingress controller -- Core monitoring and logging components +### Build from Source -## Core Commands +```bash +git clone https://github.com/flamingo-stack/openframe-cli.git +cd openframe-cli +go build -o openframe ./main.go +./openframe --version +``` -| Command | Description | Example | -|---------|-------------|---------| -| `openframe bootstrap` | Complete environment setup | `openframe bootstrap my-cluster` | -| `openframe cluster create` | Create Kubernetes cluster | `openframe cluster create --nodes 3` | -| `openframe cluster delete` | Remove existing cluster | `openframe cluster delete my-cluster` | -| `openframe cluster status` | Show cluster information | `openframe cluster status` | -| `openframe chart install` | Install charts with ArgoCD | `openframe chart install` | -| `openframe dev intercept` | Start service intercepts | `openframe dev intercept my-service` | +--- -## Technology Stack +## Command Reference -OpenFrame CLI integrates with industry-standard tools: +| Command | Alias | Description | +|---------|-------|-------------| +| `openframe bootstrap` | — | Full one-shot environment setup (cluster + charts) | +| `openframe cluster` | `k` | Manage K3D cluster lifecycle (create/delete/list/status/cleanup) | +| `openframe chart` | `c` | Manage Helm charts and ArgoCD installations | +| `openframe dev intercept` | — | Route live Kubernetes traffic to your local dev process | +| `openframe dev skaffold` | — | Run live hot-reload dev sessions with Skaffold | -- **Kubernetes**: Container orchestration with K3D for development -- **ArgoCD**: GitOps continuous deployment -- **Helm**: Package management for Kubernetes -- **Telepresence**: Local development with remote services -- **Docker**: Container runtime and image management -- **Cobra**: Modern CLI framework with rich help and completion +### Deployment Modes -## Documentation +| Mode | Description | +|------|-------------| +| `oss-tenant` | Open-source self-hosted tenant deployment | +| `saas-tenant` | SaaS tenant deployment with dedicated resources | +| `saas-shared` | SaaS shared infrastructure deployment | + +--- + +## Technology Stack -📚 See the [Documentation](./docs/README.md) for comprehensive guides including: +| Component | Technology | +|-----------|-----------| +| **Language** | Go 1.21+ | +| **CLI Framework** | [Cobra](https://github.com/spf13/cobra) | +| **Terminal UI** | [pterm](https://github.com/pterm/pterm) + [promptui](https://github.com/manifoldco/promptui) | +| **Kubernetes Client** | [client-go](https://github.com/kubernetes/client-go) | +| **ArgoCD Client** | ArgoCD v2 generated clientset | +| **YAML Parsing** | [gopkg.in/yaml.v3](https://pkg.go.dev/gopkg.in/yaml.v3) | +| **Cluster Provider** | K3D (K3s-in-Docker) | +| **GitOps** | ArgoCD with App-of-Apps pattern | +| **Dev Workflows** | Telepresence + Skaffold | -- **Getting Started**: Prerequisites, installation, and first steps -- **Development**: Local setup, architecture, and contribution guidelines -- **Reference**: Technical documentation, API specs, and configuration -- **CLI Tools**: Links to external repositories and tools +--- -## Community and Support +## Documentation -OpenFrame is built by the community for the community: +📚 See the [Documentation](./docs/README.md) for comprehensive guides including Getting Started, Development, and Architecture Reference. -- **OpenMSP Slack**: [Join the community](https://join.slack.com/t/openmsp/shared_invite/zt-36bl7mx0h-3~U2nFH6nqHqoTPXMaHEHA) - Primary support channel -- **Website**: [https://flamingo.run](https://flamingo.run) -- **OpenFrame Platform**: [https://openframe.ai](https://openframe.ai) +--- -> **Note**: We don't use GitHub Issues or Discussions. All support and community interaction happens in the OpenMSP Slack community. +## Community & Support -## License +All issues, discussions, and feature requests are managed in the **OpenMSP Slack community** — not GitHub Issues or GitHub Discussions. -This project is licensed under the Flamingo AI Unified License v1.0 - see the [LICENSE.md](LICENSE.md) file for details. +- **OpenMSP Community Slack:** [Join here](https://join.slack.com/t/openmsp/shared_invite/zt-36bl7mx0h-3~U2nFH6nqHqoTPXMaHEHA) +- **OpenMSP Website:** [https://www.openmsp.ai/](https://www.openmsp.ai/) +- **OpenFrame Platform:** [https://openframe.ai](https://openframe.ai) +- **Flamingo Platform:** [https://flamingo.run](https://flamingo.run) --- +
Built with 💛 by the Flamingo team -
\ No newline at end of file + diff --git a/SECURITY.md b/SECURITY.md index c6999183..49b47610 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -81,7 +81,12 @@ Flamingo AI implements reasonable technical and organizational safeguards, but * Use of Flamingo AI products is entirely at your own risk. Customers are solely responsible for compliance with applicable data protection laws when deploying Flamingo AI software or participating in OpenMSP. -## 11. Contact Information +## 11. Text Messaging Opt-In Data + +Text messaging originator opt-in data and consent will not be shared with any third parties, excluding aggregators and providers of the Text Message services. + + +## 12. Contact Information **Privacy Inquiries:** privacy@flamingo.so **General Information:** info@flamingo.so @@ -89,3 +94,4 @@ Use of Flamingo AI products is entirely at your own risk. Customers are solely r --- *By using Flamingo AI products, you acknowledge and agree to this Privacy Policy.* + diff --git a/docs/README.md b/docs/README.md index 5d0cad47..981c618d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,120 +1,84 @@ -# OpenFrame CLI Documentation +# OpenFrame CLI — Documentation -Welcome to the comprehensive documentation for OpenFrame CLI - a modern, interactive command-line tool for managing OpenFrame Kubernetes clusters and development workflows. +Welcome to the OpenFrame CLI documentation. This is your central hub for guides, references, and architecture documentation. -## 📚 Table of Contents - -### Getting Started - -New to OpenFrame CLI? Start here to get up and running quickly: - -- [Introduction](./getting-started/introduction.md) - Overview of OpenFrame CLI and key concepts -- [Prerequisites](./getting-started/prerequisites.md) - System requirements and dependency installation -- [Quick Start](./getting-started/quick-start.md) - Get OpenFrame running in 5 minutes -- [First Steps](./getting-started/first-steps.md) - Explore key features and workflows - -### Development - -Resources for developers working on or with OpenFrame CLI: - -- [Development Overview](./development/README.md) - Developer documentation index -- [Environment Setup](./development/setup/environment.md) - IDE configuration, tools, and development environment -- [Local Development](./development/setup/local-development.md) - Clone, build, and run OpenFrame CLI locally -- [Architecture Overview](./development/architecture/README.md) - System design and component relationships - -### Reference - -Technical reference documentation generated from source code analysis: - -- [Architecture Documentation](./architecture/overview.md) - Comprehensive system architecture and component design - -### Diagrams - -Visual documentation to understand system architecture and workflows: +> **Community:** All questions, bug reports, and feature discussions happen in the **[OpenMSP Slack community](https://join.slack.com/t/openmsp/shared_invite/zt-36bl7mx0h-3~U2nFH6nqHqoTPXMaHEHA)** — not GitHub Issues or GitHub Discussions. -- [Architecture Diagrams](./diagrams/architecture/README.md) - Mermaid diagrams showing system design, data flows, and component relationships - -### CLI Tools - -The OpenFrame Main code Repository is maintained in a separate repository: -- **Repository**: [flamingo-stack/openframe-oss-tenant](https://github.com/flamingo-stack/openframe-oss-tenant) -- **Documentation**: [CLI Documentation](https://github.com/flamingo-stack/openframe-oss-tenant/tree/main/docs) - -**Note**: CLI tools are NOT located in this repository. Always refer to the external repository for installation and usage. - -## 🚀 Quick Navigation +--- -### For New Users -1. Check [Prerequisites](./getting-started/prerequisites.md) -2. Follow [Quick Start](./getting-started/quick-start.md) -3. Explore [First Steps](./getting-started/first-steps.md) +## 📚 Table of Contents -### For Developers -1. Set up [Development Environment](./development/setup/environment.md) -2. Review [Architecture Documentation](./architecture/overview.md) -3. Check [Contributing Guidelines](../CONTRIBUTING.md) +- [Getting Started](#-getting-started) +- [Development](#-development) +- [Reference Architecture](#-reference-architecture) +- [Architecture Diagrams](#-architecture-diagrams) +- [Quick Links](#-quick-links) -### For System Administrators -1. Review [Prerequisites](./getting-started/prerequisites.md) for system requirements -2. Follow [Bootstrap Guide](./getting-started/quick-start.md#step-3-bootstrap-your-first-environment) -3. Explore cluster management commands in [First Steps](./getting-started/first-steps.md) +--- -## 🎯 Key Features Covered +## 🚀 Getting Started -This documentation covers all major OpenFrame CLI capabilities: +New to OpenFrame CLI? Start here. -- **Complete Environment Bootstrapping**: One-command setup with `openframe bootstrap` -- **Cluster Management**: Create, delete, and monitor K3D Kubernetes clusters -- **Chart & Application Management**: Helm charts and ArgoCD GitOps workflows -- **Development Tools**: Service intercepts, scaffolding, and local development workflows -- **Multi-mode Deployment**: OSS tenant, SaaS tenant, and SaaS shared configurations +| Guide | Description | +|-------|-------------| +| [Introduction](./getting-started/introduction.md) | What is OpenFrame CLI, key features, and target audience | +| [Prerequisites](./getting-started/prerequisites.md) | Required tools, system requirements, and platform-specific setup | +| [Quick Start](./getting-started/quick-start.md) | Download, install, and bootstrap your first environment in minutes | +| [First Steps](./getting-started/first-steps.md) | Explore clusters, charts, intercepts, and Skaffold after your first bootstrap | -## 📖 Quick Links +--- -- [Project README](../README.md) - Main project overview and installation -- [Contributing](../CONTRIBUTING.md) - How to contribute to OpenFrame CLI -- [License](../LICENSE.md) - Project license information +## 🛠 Development -## 🏗️ System Requirements +Guides for contributors and developers building on or extending OpenFrame CLI. -Before using OpenFrame CLI, ensure your system meets these requirements: +| Guide | Description | +|-------|-------------| +| [Development Overview](./development/README.md) | Technology stack, repository structure, and documentation index | +| [Environment Setup](./development/setup/environment.md) | IDE configuration, Go toolchain, linting and formatting tools | +| [Local Development](./development/setup/local-development.md) | Cloning, building, running, debugging, and hot-reload with Air | +| [Architecture Overview](./development/architecture/README.md) | Layered architecture, component responsibilities, and key design decisions | +| [Security Best Practices](./development/security/README.md) | Auth patterns, secrets management, TLS, input validation, and security checklist | -| Resource | Minimum | Recommended | -|----------|---------|-------------| -| **RAM** | 24GB | 32GB | -| **CPU Cores** | 6 cores | 12 cores | -| **Disk Space** | 50GB free | 100GB free | +--- -## 🛠️ Core Dependencies +## 📖 Reference Architecture -Required tools that must be installed: -- [Docker](https://docs.docker.com/get-docker/) 20.10+ -- [kubectl](https://kubernetes.io/docs/tasks/tools/) 1.25+ -- [Helm](https://helm.sh/docs/intro/install/) 3.10+ -- [K3D](https://k3d.io/v5.4.6/#installation) 5.0+ +Comprehensive technical reference generated from source code analysis. -## 🌟 What Makes OpenFrame CLI Different +| Document | Description | +|----------|-------------| +| [Architecture Overview](./reference/architecture/overview.md) | Full component reference, dependency graph, data flow diagrams, CLI commands, and key dependencies | -- **One-Command Bootstrap**: Complete environment setup with single command -- **Developer-Friendly**: Interactive prompts, clear error messages, rich terminal UI -- **GitOps Native**: Built-in ArgoCD integration for modern deployment practices -- **Local Development**: Telepresence service intercepts for debugging -- **Multi-Platform**: Linux, macOS, and Windows (WSL2) support -- **Open Source**: Complete transparency and community-driven development +--- -## 🤝 Community and Support +## 🗺 Architecture Diagrams -Need help or want to contribute? +Visual documentation for the OpenFrame CLI architecture. -- **Primary Support**: [OpenMSP Slack](https://join.slack.com/t/openmsp/shared_invite/zt-36bl7mx0h-3~U2nFH6nqHqoTPXMaHEHA) -- **Website**: [https://flamingo.run](https://flamingo.run) -- **OpenFrame Platform**: [https://openframe.ai](https://openframe.ai) +| Diagram | Description | +|---------|-------------| +| [High-Level Architecture](./diagrams/architecture/high-level-architecture-diagram.mmd) | Top-level view of CLI layers, services, providers, and external systems | +| [Dependency Graph](./diagrams/architecture/dependency-graph.mmd) | Full internal package dependency relationships | +| [Bootstrap Full Environment Setup](./diagrams/architecture/bootstrap-command-full-environment-setup.mmd) | Sequence diagram for the complete bootstrap flow | +| [Interactive Intercept Dev Workflow](./diagrams/architecture/interactive-intercept-dev-workflow.mmd) | Sequence diagram for the `dev intercept` Telepresence workflow | +| [Diagrams README](./diagrams/architecture/README.md) | Diagrams index and rendering instructions | -> **Note**: We don't monitor GitHub Issues for support. All community support and discussion happens in our Slack workspace. +--- -## 📝 Documentation Maintenance +## 🔗 Quick Links -This documentation is automatically generated and maintained by the OpenFrame development team. If you find errors or have suggestions for improvement, please reach out in the OpenMSP Slack community. +| Resource | Link | +|----------|------| +| **Project README** | [../README.md](../README.md) | +| **Contributing Guide** | [../CONTRIBUTING.md](../CONTRIBUTING.md) | +| **License** | [../LICENSE.md](../LICENSE.md) | +| **OpenFrame Platform** | [https://openframe.ai](https://openframe.ai) | +| **Flamingo Platform** | [https://flamingo.run](https://flamingo.run) | +| **OpenMSP Community** | [https://www.openmsp.ai/](https://www.openmsp.ai/) | +| **OpenMSP Slack** | [Join here](https://join.slack.com/t/openmsp/shared_invite/zt-36bl7mx0h-3~U2nFH6nqHqoTPXMaHEHA) | --- -*Documentation generated by [OpenFrame Doc Orchestrator](https://github.com/flamingo-stack/openframe-oss-tenant)* \ No newline at end of file + +*Documentation generated by [OpenFrame Doc Orchestrator](https://github.com/flamingo-stack/openframe-oss-tenant)* diff --git a/docs/architecture/overview.md b/docs/architecture/overview.md deleted file mode 100644 index 87ceae9f..00000000 --- a/docs/architecture/overview.md +++ /dev/null @@ -1,321 +0,0 @@ -# openframe-cli Module Documentation - -# OpenFrame CLI Architecture Documentation - -OpenFrame CLI is a modern, interactive command-line tool for managing OpenFrame Kubernetes clusters and development workflows, providing seamless cluster lifecycle management, chart installation with ArgoCD, and developer-friendly tools for service intercepts and scaffolding. - -## Architecture - -### High-Level System Design - -```mermaid -graph TB - subgraph "CLI Layer" - Root[Root Command] - Bootstrap[Bootstrap Command] - Cluster[Cluster Commands] - Chart[Chart Commands] - Dev[Dev Commands] - end - - subgraph "Service Layer" - ClusterSvc[Cluster Service] - ChartSvc[Chart Service] - InterceptSvc[Intercept Service] - ScaffoldSvc[Scaffold Service] - end - - subgraph "Provider Layer" - K3D[K3D Provider] - Helm[Helm Provider] - ArgoCD[ArgoCD Provider] - Telepresence[Telepresence Provider] - Kubectl[Kubectl Provider] - end - - subgraph "External Systems" - Docker[Docker] - K8s[Kubernetes] - Git[Git Repositories] - Registry[Container Registry] - end - - Root --> Bootstrap - Root --> Cluster - Root --> Chart - Root --> Dev - - Bootstrap --> ClusterSvc - Bootstrap --> ChartSvc - Cluster --> ClusterSvc - Chart --> ChartSvc - Dev --> InterceptSvc - Dev --> ScaffoldSvc - - ClusterSvc --> K3D - ChartSvc --> Helm - ChartSvc --> ArgoCD - InterceptSvc --> Telepresence - InterceptSvc --> Kubectl - ScaffoldSvc --> Kubectl - - K3D --> Docker - Helm --> K8s - ArgoCD --> K8s - ArgoCD --> Git - Telepresence --> K8s - Kubectl --> K8s -``` - -## Core Components - -| Component | Package | Responsibility | -|-----------|---------|---------------| -| **CLI Commands** | `cmd/` | Command definitions and argument parsing using Cobra | -| **Cluster Service** | `internal/cluster/` | Kubernetes cluster lifecycle management (K3D) | -| **Chart Service** | `internal/chart/` | Helm chart and ArgoCD application management | -| **Dev Tools** | `internal/dev/` | Development workflows (Telepresence, Skaffold) | -| **Bootstrap Service** | `internal/bootstrap/` | Complete environment setup orchestration | -| **K3D Provider** | `internal/cluster/providers/k3d/` | K3D cluster operations and configuration | -| **Helm Provider** | `internal/chart/providers/helm/` | Helm chart installation and management | -| **ArgoCD Provider** | `internal/chart/providers/argocd/` | ArgoCD application lifecycle and monitoring | -| **Telepresence Provider** | `internal/dev/providers/telepresence/` | Traffic interception for local development | -| **Shared Utilities** | `internal/shared/` | Common functionality (UI, config, errors, execution) | -| **Prerequisites** | `internal/*/prerequisites/` | Tool installation and validation | - -## Component Relationships - -### Dependency Flow Between Modules - -```mermaid -graph TD - subgraph "Command Layer" - RootCmd[Root Command] - BootstrapCmd[Bootstrap Command] - ClusterCmd[Cluster Commands] - ChartCmd[Chart Commands] - DevCmd[Dev Commands] - end - - subgraph "Service Orchestration" - BootstrapSvc[Bootstrap Service] - end - - subgraph "Domain Services" - ClusterSvc[Cluster Service] - ChartSvc[Chart Service] - InterceptSvc[Intercept Service] - ScaffoldSvc[Scaffold Service] - end - - subgraph "Provider Implementations" - K3DMgr[K3D Manager] - HelmMgr[Helm Manager] - ArgoCDMgr[ArgoCD Manager] - TelepresenceProv[Telepresence Provider] - KubectlProv[Kubectl Provider] - GitRepo[Git Repository] - end - - subgraph "Shared Infrastructure" - Executor[Command Executor] - UI[UI Components] - Config[Configuration] - Prerequisites[Prerequisites] - end - - RootCmd --> BootstrapCmd - RootCmd --> ClusterCmd - RootCmd --> ChartCmd - RootCmd --> DevCmd - - BootstrapCmd --> BootstrapSvc - ClusterCmd --> ClusterSvc - ChartCmd --> ChartSvc - DevCmd --> InterceptSvc - DevCmd --> ScaffoldSvc - - BootstrapSvc --> ClusterSvc - BootstrapSvc --> ChartSvc - - ClusterSvc --> K3DMgr - ChartSvc --> HelmMgr - ChartSvc --> ArgoCDMgr - ChartSvc --> GitRepo - InterceptSvc --> TelepresenceProv - InterceptSvc --> KubectlProv - ScaffoldSvc --> KubectlProv - - K3DMgr --> Executor - HelmMgr --> Executor - ArgoCDMgr --> Executor - TelepresenceProv --> Executor - KubectlProv --> Executor - GitRepo --> Executor - - ClusterSvc --> UI - ChartSvc --> UI - InterceptSvc --> UI - ScaffoldSvc --> UI - - ClusterSvc --> Config - ChartSvc --> Config - - ClusterSvc --> Prerequisites - ChartSvc --> Prerequisites - DevCmd --> Prerequisites -``` - -## Data Flow - -### Complete Bootstrap Workflow - -```mermaid -sequenceDiagram - participant User - participant Bootstrap as Bootstrap Service - participant Cluster as Cluster Service - participant K3D as K3D Provider - participant Chart as Chart Service - participant Helm as Helm Provider - participant ArgoCD as ArgoCD Provider - participant K8s as Kubernetes API - - User->>Bootstrap: openframe bootstrap - Bootstrap->>Bootstrap: Check prerequisites - Bootstrap->>Cluster: Create cluster - Cluster->>K3D: Create K3D cluster - K3D->>K8s: Initialize cluster - K8s-->>K3D: Cluster ready - K3D-->>Cluster: Cluster config - Cluster-->>Bootstrap: rest.Config - - Bootstrap->>Chart: Install charts - Chart->>Helm: Install ArgoCD - Helm->>K8s: Deploy ArgoCD - K8s-->>Helm: ArgoCD running - Helm-->>Chart: Installation complete - - Chart->>ArgoCD: Install app-of-apps - ArgoCD->>K8s: Create Application CRDs - K8s-->>ArgoCD: Applications created - ArgoCD->>ArgoCD: Sync applications - ArgoCD-->>Chart: Applications synced - Chart-->>Bootstrap: Charts installed - Bootstrap-->>User: Environment ready -``` - -### Development Intercept Workflow - -```mermaid -sequenceDiagram - participant Dev as Developer - participant Intercept as Intercept Service - participant Kubectl as Kubectl Provider - participant Telepresence as Telepresence Provider - participant K8s as Kubernetes - participant Local as Local Development - - Dev->>Intercept: openframe dev intercept - Intercept->>Kubectl: Get services - Kubectl->>K8s: List services - K8s-->>Kubectl: Service list - Kubectl-->>Intercept: Available services - Intercept->>Dev: Select service/port - Dev->>Intercept: Service selection - - Intercept->>Telepresence: Setup intercept - Telepresence->>K8s: Create intercept - K8s->>Telepresence: Traffic routing active - Telepresence->>Local: Forward traffic - Local->>Dev: Local debugging - - Note over Dev,Local: Development session active - - Dev->>Intercept: Stop intercept (Ctrl+C) - Intercept->>Telepresence: Cleanup intercept - Telepresence->>K8s: Remove routing - K8s-->>Telepresence: Cleanup complete - Telepresence-->>Intercept: Disconnected - Intercept-->>Dev: Session ended -``` - -## Key Files - -| File | Purpose | -|------|---------| -| `main.go` | Application entry point and version configuration | -| `cmd/root.go` | Root command definition and global flag management | -| `cmd/bootstrap/bootstrap.go` | Complete environment bootstrap command | -| `internal/cluster/service.go` | Core cluster management business logic | -| `internal/cluster/providers/k3d/manager.go` | K3D cluster provider implementation | -| `internal/chart/services/chart_service.go` | Chart installation orchestration | -| `internal/chart/providers/helm/manager.go` | Helm chart deployment logic | -| `internal/chart/providers/argocd/applications.go` | ArgoCD application management | -| `internal/dev/services/intercept/service.go` | Telepresence intercept workflow | -| `internal/shared/executor/executor.go` | Command execution abstraction with WSL support | -| `internal/shared/ui/logo.go` | Terminal UI and branding components | - -## Dependencies - -The project integrates with several external tools and libraries: - -### Core Kubernetes Libraries -- **client-go**: Native Kubernetes API access for cluster operations -- **apiextensions**: CRD management for ArgoCD applications -- **kubectl**: Command-line cluster interaction fallback - -### CLI Framework -- **cobra**: Command structure, argument parsing, and help generation -- **pterm**: Rich terminal UI components, spinners, and progress bars -- **promptui**: Interactive prompts and user input validation - -### External Tool Integration -- **K3D**: Lightweight Kubernetes cluster management -- **Helm**: Chart packaging and deployment via command execution -- **ArgoCD**: GitOps application lifecycle through API and CLI -- **Telepresence**: Service mesh traffic interception -- **Docker**: Container runtime for K3D clusters - -### Configuration and State -- **YAML**: Configuration file parsing for Helm values and cluster specs -- **JSON**: Structured data exchange with Kubernetes APIs -- **Home directory**: User configuration and certificate storage - -## CLI Commands - -### Core Commands - -| Command | Description | Example | -|---------|-------------|---------| -| `openframe bootstrap` | Complete environment setup (cluster + charts) | `openframe bootstrap my-cluster` | -| `openframe cluster create` | Create new Kubernetes cluster | `openframe cluster create --nodes 3` | -| `openframe cluster delete` | Remove existing cluster | `openframe cluster delete my-cluster` | -| `openframe cluster list` | Show all available clusters | `openframe cluster list` | -| `openframe cluster status` | Detailed cluster information | `openframe cluster status my-cluster` | -| `openframe chart install` | Install ArgoCD and applications | `openframe chart install` | -| `openframe dev intercept` | Start Telepresence traffic intercept | `openframe dev intercept my-service --port 8080` | -| `openframe dev skaffold` | Development workflow with hot reload | `openframe dev skaffold my-cluster` | - -### Command Options - -**Global Flags:** -- `--verbose, -v`: Enable detailed logging and progress information -- `--dry-run`: Show planned operations without execution -- `--force, -f`: Skip confirmation prompts for automation - -**Bootstrap Flags:** -- `--deployment-mode`: Pre-select deployment type (oss-tenant, saas-tenant, saas-shared) -- `--non-interactive`: Use existing configuration without prompts - -**Cluster Creation Flags:** -- `--nodes, -n`: Number of worker nodes (default: 3) -- `--type, -t`: Cluster type (k3d, gke) -- `--version`: Kubernetes version -- `--skip-wizard`: Use defaults without interactive configuration - -**Development Flags:** -- `--port`: Local port for traffic forwarding -- `--namespace`: Kubernetes namespace for operations -- `--mount`: Mount remote volumes locally -- `--env-file`: Load environment variables from file diff --git a/docs/development/README.md b/docs/development/README.md index 8ef86fdf..3609c997 100644 --- a/docs/development/README.md +++ b/docs/development/README.md @@ -1,180 +1,86 @@ # Development Documentation -This section contains comprehensive guides for developing with and contributing to OpenFrame CLI. Whether you're setting up a development environment, understanding the architecture, or contributing code, these guides will help you get started. +Welcome to the OpenFrame CLI development documentation. This section covers everything you need to contribute to, extend, or understand the internals of the OpenFrame CLI codebase. -## 🏗️ Architecture & Design - -Understanding how OpenFrame CLI is structured and how its components interact: - -- **[Architecture Overview](architecture/README.md)** - High-level system design, component relationships, and data flows +--- -## 🛠️ Development Setup +## What Is OpenFrame CLI? -Get your development environment ready: +OpenFrame CLI is a Go application built with [Cobra](https://github.com/spf13/cobra) that orchestrates Kubernetes environment management. It follows a layered clean architecture: thin command handlers delegate to service layers, which compose providers and infrastructure utilities. All external I/O is abstracted behind interfaces to maximize testability. -- **[Environment Setup](setup/environment.md)** - IDE configuration, tools, and development dependencies -- **[Local Development](setup/local-development.md)** - Clone, build, run, and debug OpenFrame CLI locally +--- -## 🔒 Security +## Documentation Index -Security best practices and guidelines: +| Document | Description | +|----------|-------------| +| [Environment Setup](setup/environment.md) | IDE setup, editor plugins, Go toolchain configuration | +| [Local Development Guide](setup/local-development.md) | Cloning, building, running, and debugging locally | +| [Architecture Overview](architecture/README.md) | High-level architecture, component diagram, data flow | +| [Security Best Practices](security/README.md) | Auth patterns, secrets management, input validation | +| [Testing Guide](testing/README.md) | Test structure, running tests, writing new tests | +| [Contributing Guidelines](contributing/guidelines.md) | Code style, PR process, commit format, review checklist | -- **[Security Guidelines](security/README.md)** - Authentication patterns, data protection, and vulnerability prevention +--- -## 🧪 Testing +## Technology Stack -Comprehensive testing approaches: +| Component | Technology | +|-----------|-----------| +| **Language** | Go 1.21+ | +| **CLI Framework** | [Cobra](https://github.com/spf13/cobra) | +| **Terminal UI** | [pterm](https://github.com/pterm/pterm) + [promptui](https://github.com/manifoldco/promptui) | +| **Kubernetes Client** | [client-go](https://github.com/kubernetes/client-go) | +| **ArgoCD Client** | [argo-cd/v2](https://github.com/argoproj/argo-cd) generated clientset | +| **YAML Parsing** | [gopkg.in/yaml.v3](https://pkg.go.dev/gopkg.in/yaml.v3) | +| **Cluster Provider** | K3D (K3s-in-Docker) | +| **GitOps** | ArgoCD with App-of-Apps pattern | +| **Dev Workflows** | Telepresence + Skaffold | -- **[Testing Guide](testing/README.md)** - Test structure, running tests, writing new tests, and coverage requirements +--- -## 🤝 Contributing +## Repository Structure -Guidelines for contributing to the project: +```text +openframe-cli/ +├── cmd/ # CLI entry layer (Cobra commands) +│ ├── root.go # Root command, global flags +│ ├── bootstrap/ # bootstrap command +│ ├── cluster/ # cluster subcommands +│ ├── chart/ # chart subcommands +│ └── dev/ # dev subcommands +├── internal/ # Business logic (not importable externally) +│ ├── bootstrap/ # Bootstrap service +│ ├── cluster/ # Cluster service, K3D provider, UI, models +│ ├── chart/ # Chart service, Helm/ArgoCD/Git providers +│ ├── dev/ # Intercept & scaffold services +│ └── shared/ # Cross-cutting: executor, UI, errors, config +├── tests/ +│ ├── integration/ # Integration tests (require real tools) +│ ├── mocks/ # Test doubles +│ └── testutil/ # Test helpers and assertion utilities +└── main.go # Binary entrypoint +``` -- **[Contributing Guidelines](contributing/guidelines.md)** - Code standards, review process, and submission guidelines +--- ## Quick Navigation -### New Contributors -If you're new to OpenFrame CLI development, start here: -1. [Architecture Overview](architecture/README.md) - Understand the system -2. [Environment Setup](setup/environment.md) - Configure your tools -3. [Local Development](setup/local-development.md) - Get the code running -4. [Contributing Guidelines](contributing/guidelines.md) - Learn the process - -### Experienced Developers -Jump to specific areas: -- **Architecture**: Deep dive into design patterns and component interactions -- **Security**: Review security models and best practices -- **Testing**: Understand test patterns and coverage expectations - -### Operations & DevOps -Focus on deployment and operational aspects: -- **Architecture**: Service dependencies and operational considerations -- **Security**: Production security requirements and configurations -- **Testing**: Integration and end-to-end testing strategies - -## Development Workflow Overview - -```mermaid -flowchart TD - A[Fork Repository] --> B[Setup Dev Environment] - B --> C[Create Feature Branch] - C --> D[Write Code & Tests] - D --> E[Run Local Tests] - E --> F{Tests Pass?} - F -->|No| D - F -->|Yes| G[Commit Changes] - G --> H[Push to Fork] - H --> I[Create Pull Request] - I --> J[Code Review] - J --> K{Review Approved?} - K -->|No| D - K -->|Yes| L[Merge to Main] - L --> M[CI/CD Pipeline] - M --> N[Deploy & Test] -``` +**New to the codebase?** Start with the [Architecture Overview](architecture/README.md) to understand how the layers fit together. -## Key Technologies +**Setting up your machine?** Go to [Environment Setup](setup/environment.md). -OpenFrame CLI is built with: +**Ready to code?** Follow the [Local Development Guide](setup/local-development.md). -| Technology | Purpose | Version | -|------------|---------|---------| -| **Go** | Primary language | 1.24.6+ | -| **Cobra** | CLI framework | v1.8.1+ | -| **Kubernetes** | Container orchestration | v1.31.2+ | -| **K3D** | Local Kubernetes clusters | v5.0+ | -| **Helm** | Package management | v3.10+ | -| **ArgoCD** | GitOps deployments | v2.14+ | -| **Telepresence** | Service intercepts | v2.10+ | +**Writing tests?** See the [Testing Guide](testing/README.md). -## Project Structure +**Submitting a PR?** Check the [Contributing Guidelines](contributing/guidelines.md) first. -```text -openframe-cli/ -├── cmd/ # CLI command definitions -│ ├── bootstrap/ # Bootstrap command -│ ├── cluster/ # Cluster management commands -│ ├── chart/ # Chart installation commands -│ ├── dev/ # Development workflow commands -│ └── root.go # Root command setup -├── internal/ # Internal packages -│ ├── bootstrap/ # Bootstrap orchestration -│ ├── cluster/ # Cluster lifecycle management -│ ├── chart/ # Chart and ArgoCD integration -│ ├── dev/ # Development tools -│ └── shared/ # Common utilities -├── tests/ # Test suites -│ ├── integration/ # Integration tests -│ ├── mocks/ # Test mocks -│ └── testutil/ # Test utilities -├── docs/ # Documentation -├── examples/ # Usage examples -├── scripts/ # Build and utility scripts -├── go.mod # Go module definition -├── go.sum # Go dependency checksums -└── main.go # Application entry point -``` +--- -## Development Principles - -### Code Quality -- **Clean Architecture**: Clear separation of concerns with layered design -- **Testability**: All components designed for easy testing and mocking -- **Error Handling**: Comprehensive error handling with user-friendly messages -- **Documentation**: Code is self-documenting with clear comments - -### User Experience -- **Interactive Design**: Wizard-style interfaces for complex operations -- **Clear Feedback**: Progress indicators and status messages -- **Error Recovery**: Helpful error messages with suggested solutions -- **Consistency**: Uniform command patterns and flag usage - -### Operational Excellence -- **Observability**: Comprehensive logging and monitoring capabilities -- **Reliability**: Robust error handling and recovery mechanisms -- **Performance**: Efficient resource usage and fast execution -- **Security**: Secure defaults and best practices - -## Getting Started - -### Prerequisites -Before diving into development, ensure you have: -- Go 1.24.6 or later installed -- Docker and Kubernetes tools (kubectl, helm, k3d) -- Git and a code editor/IDE -- Basic familiarity with Kubernetes concepts - -### Quick Start -1. **Read the [Architecture Overview](architecture/README.md)** to understand the system -2. **Follow the [Environment Setup](setup/environment.md)** guide -3. **Complete the [Local Development](setup/local-development.md)** setup -4. **Review [Contributing Guidelines](contributing/guidelines.md)** before making changes - -## Community & Support - -### Getting Help -- **OpenMSP Slack**: [Join the community](https://join.slack.com/t/openmsp/shared_invite/zt-36bl7mx0h-3~U2nFH6nqHqoTPXMaHEHA) for development questions -- **Documentation**: Browse these guides for detailed information -- **Code Reviews**: Learn from existing pull requests and code reviews - -### Contributing -We welcome contributions! Here's how to get involved: -1. **Start Small**: Begin with bug fixes or documentation improvements -2. **Discuss Large Changes**: Use Slack to discuss major features or architectural changes -3. **Follow Guidelines**: Adhere to coding standards and review processes -4. **Be Patient**: Maintain a collaborative and respectful approach - -### Code of Conduct -- Be respectful and inclusive in all interactions -- Focus on constructive feedback and learning -- Help others learn and grow in the community -- Follow the project's established patterns and conventions +## Community ---- +All development discussions, bug reports, and feature requests are managed in the **OpenMSP Slack community**: -Ready to start developing? Choose your path: -- **New to the project**: Start with [Architecture Overview](architecture/README.md) -- **Ready to code**: Jump to [Local Development](setup/local-development.md) -- **Want to contribute**: Review [Contributing Guidelines](contributing/guidelines.md) \ No newline at end of file +- [Join OpenMSP Slack](https://join.slack.com/t/openmsp/shared_invite/zt-36bl7mx0h-3~U2nFH6nqHqoTPXMaHEHA) +- [OpenMSP Website](https://www.openmsp.ai/) diff --git a/docs/development/architecture/README.md b/docs/development/architecture/README.md index c42f299d..2877b545 100644 --- a/docs/development/architecture/README.md +++ b/docs/development/architecture/README.md @@ -1,574 +1,254 @@ # Architecture Overview -OpenFrame CLI is built with a clean, layered architecture that separates concerns and provides extensibility. This guide provides a comprehensive overview of the system design, component relationships, and key architectural decisions. +OpenFrame CLI follows a **layered clean architecture** pattern: thin Cobra command handlers delegate to service layers, which compose providers and infrastructure utilities. All external I/O (Kubernetes API, shell commands, Git) is abstracted behind interfaces to maximize testability and portability. -## High-Level Architecture - -OpenFrame CLI follows a layered architecture pattern with clear separation between the CLI interface, business logic, and external integrations: - -```mermaid -graph TB - subgraph "User Interface Layer" - CLI[CLI Commands] - UI[Interactive UI] - Wizard[Setup Wizards] - end - - subgraph "Application Layer" - Bootstrap[Bootstrap Orchestrator] - ClusterMgr[Cluster Manager] - ChartMgr[Chart Manager] - DevTools[Development Tools] - end - - subgraph "Provider Layer" - K3DProvider[K3D Provider] - HelmProvider[Helm Provider] - ArgoCDProvider[ArgoCD Provider] - TelepresenceProvider[Telepresence Provider] - KubectlProvider[kubectl Provider] - GitProvider[Git Provider] - end - - subgraph "Infrastructure Layer" - Executor[Command Executor] - Config[Configuration] - Logger[Logging] - ErrorHandler[Error Handling] - FileSystem[File Operations] - end - - subgraph "External Systems" - Docker[Docker Engine] - K8s[Kubernetes API] - Git[Git Repositories] - Registry[Container Registry] - ArgoCD[ArgoCD Server] - end - - CLI --> Bootstrap - CLI --> ClusterMgr - CLI --> ChartMgr - CLI --> DevTools - - Bootstrap --> ClusterMgr - Bootstrap --> ChartMgr - ClusterMgr --> K3DProvider - ChartMgr --> HelmProvider - ChartMgr --> ArgoCDProvider - DevTools --> TelepresenceProvider - DevTools --> KubectlProvider - - K3DProvider --> Executor - HelmProvider --> Executor - ArgoCDProvider --> Executor - TelepresenceProvider --> Executor - KubectlProvider --> Executor - GitProvider --> Executor - - K3DProvider --> Docker - HelmProvider --> K8s - ArgoCDProvider --> ArgoCD - TelepresenceProvider --> K8s - KubectlProvider --> K8s - GitProvider --> Git -``` - -## Core Components +For a deeper technical dive, see the [Reference Architecture Documentation](../../reference/architecture/overview.md). -### Command Layer (`cmd/`) +--- -The command layer implements the CLI interface using the Cobra framework: - -| Component | Purpose | Key Features | -|-----------|---------|--------------| -| **Root Command** | Entry point and version management | Interactive help, global flags, subcommand routing | -| **Bootstrap Command** | Complete environment setup | Orchestrates cluster + chart installation | -| **Cluster Commands** | Kubernetes cluster lifecycle | Create, delete, list, status operations | -| **Chart Commands** | Application deployment | Helm charts, ArgoCD applications | -| **Dev Commands** | Development workflows | Service intercepts, scaffolding | - -### Service Layer (`internal/`) - -The service layer contains the core business logic: - -#### Bootstrap Service (`internal/bootstrap/`) -- **Purpose**: Orchestrates complete environment setup -- **Key Functions**: - - Validates prerequisites - - Creates Kubernetes clusters - - Installs core charts (ArgoCD, Traefik) - - Configures GitOps workflows +## High-Level Architecture ```mermaid -sequenceDiagram - participant User - participant Bootstrap - participant Cluster - participant Chart - participant ArgoCD - - User->>Bootstrap: openframe bootstrap - Bootstrap->>Bootstrap: Check prerequisites - Bootstrap->>Cluster: Create K3D cluster - Cluster-->>Bootstrap: Cluster ready - Bootstrap->>Chart: Install ArgoCD - Chart-->>Bootstrap: ArgoCD installed - Bootstrap->>ArgoCD: Deploy app-of-apps - ArgoCD-->>Bootstrap: Applications synced - Bootstrap-->>User: Environment ready -``` - -#### Cluster Service (`internal/cluster/`) -- **Purpose**: Manages Kubernetes cluster lifecycle -- **Key Functions**: - - K3D cluster creation and deletion - - Cluster status monitoring - - Node management and scaling - - Configuration and context management - -#### Chart Service (`internal/chart/`) -- **Purpose**: Manages application deployments -- **Key Functions**: - - Helm chart installation - - ArgoCD application management - - GitOps workflow configuration - - Application synchronization monitoring - -#### Development Services (`internal/dev/`) -- **Purpose**: Provides development workflow tools -- **Key Functions**: - - Service intercepts with Telepresence - - Code scaffolding and templates - - Local development environment setup - - Debug and testing utilities - -### Provider Layer - -The provider layer abstracts external tool integrations: - -#### K3D Provider (`internal/cluster/providers/k3d/`) -```go -type Manager interface { - CreateCluster(config ClusterConfig) (*rest.Config, error) - DeleteCluster(name string) error - ListClusters() ([]ClusterInfo, error) - GetClusterStatus(name string) (*ClusterStatus, error) -} -``` - -Key responsibilities: -- Docker container management for K3D nodes -- Kubernetes API server configuration -- Network and port forwarding setup -- Cluster lifecycle management - -#### Helm Provider (`internal/chart/providers/helm/`) -```go -type Manager interface { - InstallChart(release string, chart string, values map[string]interface{}) error - UpgradeChart(release string, chart string, values map[string]interface{}) error - UninstallChart(release string) error - ListReleases() ([]Release, error) -} -``` - -Key responsibilities: -- Helm repository management -- Chart installation and upgrades -- Release lifecycle management -- Value overrides and templating - -#### ArgoCD Provider (`internal/chart/providers/argocd/`) -```go -type Manager interface { - CreateApplication(app ApplicationSpec) error - SyncApplication(name string) error - DeleteApplication(name string) error - WaitForSync(name string, timeout time.Duration) error -} -``` - -Key responsibilities: -- ArgoCD application CRD management -- Git repository synchronization -- Application health monitoring -- Sync policy configuration - -### Shared Infrastructure (`internal/shared/`) - -Common utilities and cross-cutting concerns: - -#### Command Executor (`internal/shared/executor/`) -- **Purpose**: Standardized external command execution -- **Features**: - - Command building and execution - - Output capture and streaming - - Error handling and retry logic - - Timeout management - - Mock support for testing - -#### Configuration Management (`internal/shared/config/`) -- **Purpose**: Application configuration and settings -- **Features**: - - YAML/JSON configuration files - - Environment variable overrides - - Default value management - - Validation and type safety - -#### User Interface (`internal/shared/ui/`) -- **Purpose**: Consistent user interaction patterns -- **Features**: - - Interactive prompts and wizards - - Progress indicators and spinners - - Colored output and formatting - - Table rendering and alignment - - Error message presentation - -## Data Flow Architecture - -### Bootstrap Workflow +graph TD + subgraph CLI["CLI Entry Layer (cmd/)"] + Root["Root Command"] + Bootstrap["bootstrap"] + Cluster["cluster"] + Chart["chart"] + Dev["dev"] + end -The bootstrap process follows a carefully orchestrated sequence: + subgraph Services["Service Layer (internal/)"] + BootstrapSvc["Bootstrap Service"] + ClusterSvc["Cluster Service"] + ChartSvc["Chart Service"] + DevSvc["Dev Services"] + end -```mermaid -flowchart TD - A[Start Bootstrap] --> B[Check Prerequisites] - B --> C{Prerequisites OK?} - C -->|No| D[Install Missing Tools] - C -->|Yes| E[Validate Configuration] - D --> E - E --> F[Create K3D Cluster] - F --> G[Wait for Cluster Ready] - G --> H[Install ArgoCD] - H --> I[Configure Git Repositories] - I --> J[Deploy App-of-Apps] - J --> K[Wait for Application Sync] - K --> L{All Apps Healthy?} - L -->|No| M[Troubleshoot & Retry] - L -->|Yes| N[Bootstrap Complete] - M --> K -``` + subgraph Providers["Provider Layer"] + K3D["K3D Manager"] + HelmMgr["Helm Manager"] + ArgoCDMgr["ArgoCD Manager"] + GitRepo["Git Repository"] + KubectlProv["Kubectl Provider"] + TelepresenceProv["Telepresence Provider"] + end -### Service Interaction Patterns + subgraph Shared["Shared Infrastructure"] + Executor["Command Executor"] + UIShared["Shared UI"] + ErrorsShared["Error Handling"] + ConfigShared["Config / Paths"] + FilesShared["File Cleanup"] + end -Services interact through well-defined interfaces: + subgraph External["External Systems"] + K3dBin["k3d binary"] + HelmBin["helm binary"] + ArgoCDAPI["ArgoCD Kubernetes API"] + GitHubRepo["GitHub Repository"] + K8sAPI["Kubernetes API"] + TelepresenceBin["telepresence binary"] + SkaffoldBin["skaffold binary"] + end -```mermaid -classDiagram - class BootstrapService { - +Execute(config BootstrapConfig) error - -validatePrerequisites() error - -createCluster() error - -installCharts() error - } - - class ClusterService { - +Create(name string) error - +Delete(name string) error - +Status(name string) ClusterStatus - +List() []ClusterInfo - } - - class ChartService { - +Install(chart ChartSpec) error - +List() []ChartInfo - +Sync(name string) error - +WaitForReady(name string) error - } - - BootstrapService --> ClusterService - BootstrapService --> ChartService - ChartService --> ArgocdProvider - ClusterService --> K3dProvider + Root --> Bootstrap + Root --> Cluster + Root --> Chart + Root --> Dev + + Bootstrap --> BootstrapSvc + Cluster --> ClusterSvc + Chart --> ChartSvc + Dev --> DevSvc + + BootstrapSvc --> ClusterSvc + BootstrapSvc --> ChartSvc + + ClusterSvc --> K3D + ChartSvc --> HelmMgr + ChartSvc --> ArgoCDMgr + ChartSvc --> GitRepo + DevSvc --> KubectlProv + DevSvc --> TelepresenceProv + + K3D --> Executor + HelmMgr --> Executor + GitRepo --> Executor + KubectlProv --> Executor + TelepresenceProv --> Executor + + Executor --> K3dBin + Executor --> HelmBin + Executor --> TelepresenceBin + Executor --> SkaffoldBin + HelmMgr --> ArgoCDAPI + ArgoCDMgr --> K8sAPI + GitRepo --> GitHubRepo + KubectlProv --> K8sAPI + + ClusterSvc --> UIShared + ChartSvc --> UIShared + DevSvc --> UIShared + ClusterSvc --> ErrorsShared + ChartSvc --> ErrorsShared + ClusterSvc --> ConfigShared + ChartSvc --> ConfigShared + ChartSvc --> FilesShared ``` -## Key Design Decisions - -### 1. Layered Architecture - -**Decision**: Implement strict layering with dependency injection -**Rationale**: -- Clear separation of concerns -- Easier testing through interface mocking -- Flexibility to swap implementations -- Maintainable and extensible codebase - -### 2. Provider Pattern - -**Decision**: Abstract external tools behind provider interfaces -**Rationale**: -- Support multiple Kubernetes distributions (K3D, Kind, etc.) -- Enable testing without external dependencies -- Simplify adding new tool integrations -- Consistent error handling and logging +--- -### 3. Command Executor Abstraction - -**Decision**: Centralize external command execution -**Rationale**: -- Consistent error handling across all external calls -- Unified logging and debugging capabilities -- Simplified testing with command mocking -- Retry logic and timeout management +## Core Components -### 4. Interactive CLI Design +| Package | Path | Responsibility | +|---------|------|----------------| +| **Root Command** | `cmd/root.go` | CLI entrypoint, global flags (`--verbose`, `--silent`), version info, subcommand registration | +| **Bootstrap Command** | `cmd/bootstrap/` | Orchestrates full environment setup: cluster create → chart install in sequence | +| **Cluster Command** | `cmd/cluster/` | Cobra subcommands for create, delete, list, status, cleanup | +| **Chart Command** | `cmd/chart/` | Cobra subcommands for ArgoCD + app-of-apps installation | +| **Dev Command** | `cmd/dev/` | Cobra subcommands for `intercept` (Telepresence) and `skaffold` workflows | +| **Bootstrap Service** | `internal/bootstrap/` | Business logic to sequence cluster creation then chart installation; handles Windows WSL init | +| **Cluster Service** | `internal/cluster/service.go` | High-level cluster lifecycle; delegates to K3D manager | +| **K3D Manager** | `internal/cluster/providers/k3d/` | Low-level K3D cluster operations; config file generation, kubeconfig management, TLS SAN injection | +| **Chart Service** | `internal/chart/services/` | Installation workflow: prerequisites → git clone → helm install ArgoCD → app-of-apps → ArgoCD sync wait | +| **Helm Manager** | `internal/chart/providers/helm/` | Helm CLI wrapper; installs ArgoCD and app-of-apps charts; native K8s client fallback | +| **ArgoCD Manager** | `internal/chart/providers/argocd/` | Watches ArgoCD `Application` CRDs via native Go client; waits for Healthy+Synced state | +| **Git Repository** | `internal/chart/providers/git/` | Clones GitHub repos (`--depth 1`) to temp dirs for chart content | +| **Configuration Wizard** | `internal/chart/ui/configuration/` | Multi-step interactive wizard for deployment mode, SaaS credentials, ingress, Docker registry | +| **Intercept Service** | `internal/dev/services/intercept/` | Manages full Telepresence lifecycle: connect → intercept → wait → cleanup on signal | +| **Scaffold Service** | `internal/dev/services/scaffold/` | Discovers `skaffold.yaml` files, bootstraps cluster, runs `skaffold dev` | +| **Command Executor** | `internal/shared/executor/` | Abstracts `os/exec`; supports dry-run and verbose modes; WSL2 detection and recovery | +| **Shared UI** | `internal/shared/ui/` | Logo rendering, selection prompts, table rendering, confirmation dialogs | +| **Shared Errors** | `internal/shared/errors/` | Typed errors with retry policies and colored terminal output | +| **Shared Config** | `internal/shared/config/` | TLS bypass utilities, credentials prompter, log directory init | -**Decision**: Provide both interactive and non-interactive modes -**Rationale**: -- User-friendly for manual operations -- Scriptable for automation and CI/CD -- Progressive disclosure of complexity -- Clear error messages and guidance +--- -### 5. GitOps-First Approach +## Layer Responsibilities -**Decision**: Default to GitOps workflows with ArgoCD -**Rationale**: -- Industry best practices for Kubernetes deployments -- Declarative infrastructure management -- Audit trails and rollback capabilities -- Team collaboration through Git workflows +### 1. CLI Layer (`cmd/`) -## Error Handling Strategy +Thin Cobra command definitions. Responsibilities: +- Parse CLI flags +- Validate flag combinations +- Delegate all business logic to the service layer +- Handle the `--verbose` / `--silent` global flags -### Error Types and Handling +No business logic lives in `cmd/` — it is purely a wiring layer. -```mermaid -graph TD - A[Error Occurs] --> B{Error Type?} - B -->|Validation Error| C[Show Usage Help] - B -->|External Tool Error| D[Parse Tool Output] - B -->|Network Error| E[Suggest Connectivity Check] - B -->|Resource Error| F[Check Resource Availability] - - C --> G[Exit with Code 1] - D --> H{Recoverable?} - E --> H - F --> H - - H -->|Yes| I[Retry with Backoff] - H -->|No| J[Show Error + Solutions] - - I --> K{Max Retries?} - K -->|No| A - K -->|Yes| J - - J --> G -``` +### 2. Service Layer (`internal/*/service*.go`, `internal/*/services/`) -### Error Categories - -| Category | Examples | Handling Strategy | -|----------|----------|------------------| -| **User Input** | Invalid flags, missing config | Show usage help, suggest corrections | -| **Prerequisites** | Missing tools, permissions | Guide installation, check prerequisites | -| **Network** | Connection timeouts, DNS issues | Retry with backoff, check connectivity | -| **Resource** | Insufficient memory, disk space | Check resources, suggest alternatives | -| **External Tools** | kubectl errors, helm failures | Parse tool output, provide context | - -## Configuration Architecture - -### Configuration Sources (Priority Order) - -1. **Command-line flags** - Highest priority -2. **Environment variables** - Override config files -3. **Configuration files** - User and system configs -4. **Default values** - Built-in sensible defaults - -### Configuration Structure - -```yaml -# ~/.openframe/config.yaml -openframe: - log_level: "info" - config_dir: "~/.openframe" - -cluster: - provider: "k3d" - default_name: "openframe-local" - nodes: 1 - -bootstrap: - mode: "oss-tenant" - timeout: "15m" - interactive: true - -chart: - timeout: "10m" - wait_for_ready: true - -dev: - intercept_timeout: "5m" - scaffold_template_dir: "~/.openframe/templates" -``` +Business logic orchestration. Responsibilities: +- Sequence multi-step operations (e.g., cluster create → chart install) +- Coordinate between providers +- Manage UI feedback (spinners, progress, next-steps output) +- Handle errors with typed error propagation -## Testing Architecture - -### Test Strategy - -```mermaid -graph TB - subgraph "Unit Tests" - A[Service Logic Tests] - B[Provider Tests with Mocks] - C[Utility Function Tests] - end - - subgraph "Integration Tests" - D[End-to-End Command Tests] - E[Provider Integration Tests] - F[External Tool Integration] - end - - subgraph "Acceptance Tests" - G[Complete Bootstrap Workflow] - H[Multi-Cluster Scenarios] - I[Development Workflow Tests] - end - - A --> D - B --> E - C --> F - D --> G - E --> H - F --> I -``` +### 3. Provider Layer (`internal/*/providers/`) -### Mock Strategy +Thin wrappers around external tools and APIs. Responsibilities: +- Invoke external binaries via the `CommandExecutor` +- Make Kubernetes API calls using native Go clients +- Return strongly-typed results -- **External Commands**: Mock command executor for tool interactions -- **Kubernetes API**: Use fake clientsets for API testing -- **File System**: Mock file operations for config testing -- **Network**: Mock HTTP clients for external service calls +Each provider implements an interface so it can be replaced with a mock in tests. -## Security Architecture +### 4. Shared Infrastructure (`internal/shared/`) -### Security Principles +Cross-cutting utilities used by all layers: +- **`executor/`** — subprocess runner with WSL2 support, dry-run mode, verbose mode +- **`ui/`** — all terminal UI primitives (pterm + promptui) +- **`errors/`** — typed errors, retry policies, colored error display +- **`config/`** — TLS configuration, credentials, system service initialization +- **`files/`** — temporary file lifecycle management -1. **Least Privilege**: Request minimal permissions necessary -2. **Secure Defaults**: Safe configurations out of the box -3. **Input Validation**: Sanitize all user inputs -4. **Secret Management**: Secure handling of credentials and keys -5. **Audit Logging**: Track security-relevant operations +--- -### Trust Boundaries +## Data Flow: Bootstrap Command ```mermaid -graph LR - subgraph "Trusted Zone" - A[OpenFrame CLI] - B[Local Kubernetes] - C[Local Docker] - end - - subgraph "Semi-Trusted Zone" - D[Container Images] - E[Helm Charts] - F[Git Repositories] - end - - subgraph "Untrusted Zone" - G[Public Internet] - H[External APIs] - I[User Input] - end - - A --> B - A --> C - B --> D - A --> E - A --> F - - E --> G - F --> G - A --> H - I --> A +sequenceDiagram + participant User + participant BootstrapCmd["bootstrap cmd"] + participant BootstrapSvc["Bootstrap Service"] + participant ClusterSvc["Cluster Service"] + participant K3DMgr["K3D Manager"] + participant ChartSvc["Chart Service"] + participant GitProv["Git Provider"] + participant HelmMgr["Helm Manager"] + participant ArgoCDMgr["ArgoCD Manager"] + + User->>BootstrapCmd: openframe bootstrap my-cluster + BootstrapCmd->>BootstrapSvc: Execute(cmd, args) + BootstrapSvc->>ClusterSvc: CreateClusterWithPrerequisites(name, verbose) + ClusterSvc->>K3DMgr: CreateCluster(ClusterConfig) + K3DMgr-->>ClusterSvc: rest.Config + ClusterSvc-->>BootstrapSvc: rest.Config + + BootstrapSvc->>ChartSvc: InstallChartsWithConfig(InstallationRequest) + ChartSvc->>ChartSvc: Check prerequisites (helm, git, certs) + ChartSvc->>HelmMgr: InstallArgoCDWithProgress(config) + HelmMgr-->>ChartSvc: ArgoCD installed + + ChartSvc->>GitProv: CloneChartRepository(AppOfAppsConfig) + GitProv-->>ChartSvc: CloneResult{TempDir, ChartPath} + + ChartSvc->>HelmMgr: InstallAppOfAppsFromLocal(config) + HelmMgr-->>ChartSvc: App-of-apps installed + + ChartSvc->>ArgoCDMgr: WaitForApplications(config) + ArgoCDMgr-->>ChartSvc: All applications Healthy+Synced + + ChartSvc-->>BootstrapSvc: Success + BootstrapSvc-->>User: Environment ready ``` -## Performance Considerations - -### Optimization Strategies - -1. **Lazy Loading**: Load providers and tools only when needed -2. **Concurrent Operations**: Parallel execution where safe -3. **Caching**: Cache expensive operations (cluster status, etc.) -4. **Resource Monitoring**: Track memory and CPU usage -5. **Efficient Data Structures**: Use appropriate data types - -### Resource Management - -- **Memory**: Stream large outputs, avoid loading everything in memory -- **CPU**: Use worker pools for concurrent operations -- **Disk**: Clean up temporary files, use appropriate buffer sizes -- **Network**: Connection pooling, request batching where possible +--- -## Extensibility Points - -### Adding New Commands - -1. **Create command file** in appropriate `cmd/` subdirectory -2. **Implement service logic** in `internal/` package -3. **Add provider interface** if external tool needed -4. **Write comprehensive tests** for all components -5. **Update documentation** and help text - -### Adding New Providers - -1. **Define provider interface** in appropriate service package -2. **Implement provider** in `internal/*/providers/` directory -3. **Add configuration support** for provider-specific settings -4. **Implement comprehensive testing** including mocks -5. **Update factory functions** to instantiate new provider +## Key Design Decisions -### Plugin Architecture (Future) +### Interface-Based External I/O -Future extensibility through plugins: +All subprocess execution goes through the `CommandExecutor` interface: -```mermaid -graph TB - A[OpenFrame Core] --> B[Plugin Manager] - B --> C[Command Plugins] - B --> D[Provider Plugins] - B --> E[UI Plugins] - - C --> F[Custom Commands] - D --> G[New Tool Integrations] - E --> H[Custom Interfaces] +```go +type CommandExecutor interface { + Execute(ctx context.Context, command string, args ...string) (*CommandResult, error) + ExecuteWithOptions(ctx context.Context, opts ExecuteOptions) (*CommandResult, error) +} ``` -## Migration and Upgrade Strategy +This means any unit test can inject a `MockCommandExecutor` that returns pre-configured responses without ever invoking `k3d`, `helm`, or `kubectl`. -### Backward Compatibility +### Native Kubernetes Clients for ArgoCD -- **Configuration**: Support old config format with migration -- **Commands**: Maintain command compatibility across versions -- **Data**: Migrate user data automatically when needed -- **Dependencies**: Graceful handling of version mismatches +Rather than shelling out to `kubectl` for ArgoCD Application polling, the CLI uses the generated ArgoCD Go clientset (`k8s.io/client-go` + ArgoCD versioned client). This provides: +- Reliable multi-platform behavior (no subprocess path resolution issues on Windows/WSL2) +- Type-safe Application CRD access +- Watch/poll loops with proper context cancellation -### Version Management +### WSL2-Aware Execution -```go -type VersionInfo struct { - Version string // Semantic version - Commit string // Git commit hash - Date string // Build timestamp - Go string // Go version used -} -``` +The `RealCommandExecutor` detects Windows WSL2 environments and: +- Converts Unix paths to WSL-compatible paths where needed +- Wraps commands with `wsl -e` prefix when necessary +- Provides health-check and recovery utilities for the WSL2 Ubuntu distribution -## Next Steps +### Configuration Wizard Pattern -To deepen your understanding of OpenFrame CLI architecture: +The interactive configuration wizard (`internal/chart/ui/configuration/`) uses a strategy pattern — each configuration aspect (branch, Docker registry, ingress, SaaS credentials) is encapsulated in a dedicated configurator struct that implements the same workflow interface. The wizard orchestrates them in sequence. -1. **[Security Guidelines](../security/README.md)** - Learn about security implementations -2. **[Testing Guide](../testing/README.md)** - Understand testing strategies -3. **[Contributing Guidelines](../contributing/guidelines.md)** - Learn development processes +--- -## Additional Resources +## Key Dependencies -- **[Architecture Documentation](./architecture/overview.md)** - Generated architecture docs from code -- **Go Design Patterns**: https://golang.org/doc/effective_go -- **Kubernetes Client Libraries**: https://kubernetes.io/docs/reference/using-api/client-libraries/ -- **Cobra CLI Framework**: https://cobra.dev/ -- **OpenMSP Community**: [Join Slack](https://join.slack.com/t/openmsp/shared_invite/zt-36bl7mx0h-3~U2nFH6nqHqoTPXMaHEHA) \ No newline at end of file +| Library | Usage | +|---------|-------| +| `github.com/spf13/cobra` | CLI framework — all commands, flags, usage templates | +| `github.com/pterm/pterm` | Rich terminal UI — spinners, tables, boxes, progress | +| `github.com/manifoldco/promptui` | Interactive selection menus and text input | +| `k8s.io/client-go` | Native Kubernetes API client | +| `github.com/argoproj/argo-cd/v2` | ArgoCD generated clientset for Application CRD polling | +| `gopkg.in/yaml.v3` | YAML parsing for helm-values.yaml and cluster configs | +| `golang.org/x/term` | Raw terminal mode for single-keystroke prompts | diff --git a/docs/development/security/README.md b/docs/development/security/README.md new file mode 100644 index 00000000..8196993f --- /dev/null +++ b/docs/development/security/README.md @@ -0,0 +1,224 @@ +# Security Best Practices + +This document covers security patterns, secrets management, input validation, and common vulnerabilities relevant to developing and deploying OpenFrame CLI. + +--- + +## Authentication and Authorization + +### Kubeconfig and Cluster Credentials + +OpenFrame CLI interacts with Kubernetes clusters using the standard kubeconfig mechanism. The CLI **never stores or transmits kubeconfig credentials itself** — it reads from the location specified by `$KUBECONFIG` (defaulting to `~/.kube/config`). + +**Best practices:** + +- Use separate kubeconfig contexts per environment (dev, staging, prod) +- Restrict kubeconfig file permissions to the owning user: + +```bash +chmod 600 ~/.kube/config +``` + +- When running in CI, inject kubeconfig via environment variable rather than writing to disk: + +```bash +export KUBECONFIG=/tmp/ci-kubeconfig +echo "$KUBECONFIG_CONTENT" > /tmp/ci-kubeconfig +chmod 600 /tmp/ci-kubeconfig +openframe bootstrap --deployment-mode=oss-tenant --non-interactive +``` + +### SaaS Credentials + +When using `saas-tenant` or `saas-shared` deployment modes, the configuration wizard prompts for SaaS API credentials. These credentials are written into `helm-values-tmp.yaml` — a **temporary file** that the CLI creates, uses, and removes after successful installation. + +**Important:** The CLI creates a backup of `helm-values.yaml` before modification and restores it on failure, ensuring that secrets are not left in intermediate states. + +--- + +## Secrets Management + +### Never Commit Credentials + +OpenFrame CLI generates temporary Helm values files (`helm-values-tmp.yaml`) that may contain credentials. Ensure these are gitignored: + +```bash +# Verify .gitignore includes temporary files +echo "helm-values-tmp.yaml" >> .gitignore +echo "*.tmp.yaml" >> .gitignore +``` + +### Environment Variables Over Flags + +Prefer environment variables over command-line flags for secrets — flags may be visible in process listings: + +```bash +# Avoid: credentials visible in process list +openframe chart install --saas-token=mysecret123 + +# Prefer: pass via environment when the CLI supports it +export OPENFRAME_SAAS_TOKEN=mysecret123 +openframe chart install --deployment-mode=saas-tenant +``` + +### CI/CD Secret Injection + +In CI/CD pipelines, use your platform's secret store and inject at runtime: + +```bash +# GitHub Actions example pattern +# Store KUBECONFIG_BASE64 as a repository secret, then: +echo "$KUBECONFIG_BASE64" | base64 -d > /tmp/kubeconfig +export KUBECONFIG=/tmp/kubeconfig +openframe bootstrap --deployment-mode=oss-tenant --non-interactive +``` + +--- + +## TLS Certificate Security + +### Local Development TLS (mkcert) + +The CLI uses `mkcert` to generate locally-trusted TLS certificates for K3D cluster ingress. These certificates are: + +- Generated fresh per environment +- Stored in the chart installation directory +- Trusted only by your local machine's certificate store + +```bash +# The CLI handles mkcert automatically — but verify your local CA is installed +mkcert -install +``` + +### TLS Bypass for Local K3D + +The CLI applies an **insecure TLS configuration** (`ApplyInsecureTLSConfig()`) specifically for local K3D clusters to avoid TLS verification errors when communicating with the Kubernetes API. This configuration is: + +- Applied **only** to local K3D clusters +- **Not** used for any external API communication +- Appropriate for local development purposes + +> **Warning:** Never use insecure TLS configurations in production or staging environments. The TLS bypass is explicitly scoped to K3D cluster contexts. + +--- + +## Input Validation + +### Cluster Name Validation + +All cluster name inputs are validated before use. The `ValidateClusterName()` function enforces: + +- Lowercase alphanumeric characters and hyphens only +- No leading or trailing hyphens +- Maximum length limits + +Example of validation usage in code: + +```go +if err := models.ValidateClusterName(name); err != nil { + return errors.CreateValidationError("cluster-name", name, err.Error()) +} +``` + +### Flag Validation + +The `ValidateCreateFlags()` and related functions in `internal/cluster/models/flags.go` validate all flag combinations before operations begin, preventing invalid configurations from reaching external tool invocations. + +### Shell Injection Prevention + +The CLI avoids shell injection by using the `os/exec` package directly (never `sh -c "..."`) through the `CommandExecutor` abstraction: + +```go +// Safe: arguments are passed as a slice, never interpolated into a shell string +result, err := executor.Execute(ctx, "k3d", "cluster", "create", clusterName) + +// Never do this: +// exec.Command("sh", "-c", "k3d cluster create " + clusterName) +``` + +All external commands use separate argument slices — user-provided input is never concatenated into shell strings. + +--- + +## Common Security Vulnerabilities and Mitigations + +| Vulnerability | Mitigation | +|---------------|-----------| +| **Shell injection** | All external commands use `os/exec` with argument slices, never string interpolation | +| **Path traversal** | Temp directories are created via `os.MkdirTemp()` and cleaned up after use | +| **Credential leakage in logs** | Verbose mode logs command invocations but strips sensitive flag values | +| **Insecure TLS** | TLS bypass is scoped only to local K3D contexts; production HTTPS is fully verified | +| **Exposed kubeconfig** | CLI reads kubeconfig from standard locations; never stores credentials internally | +| **Temporary file exposure** | `helm-values-tmp.yaml` is deleted on success; restored from backup on failure | + +--- + +## Secure File Handling + +The `internal/shared/files/` package manages the `helm-values-tmp.yaml` lifecycle: + +1. **Backup** — Original `helm-values.yaml` is backed up before modification +2. **Modify** — The temporary file is written with user-provided configuration +3. **Install** — Helm uses the temporary file during chart installation +4. **Cleanup** — On success, the temporary file is deleted and the backup is restored +5. **Recovery** — On failure, the original file is restored from backup + +This ensures that a failed installation never leaves secrets on disk. + +--- + +## Environment Variables and Secrets Checklist + +Before committing code or creating a PR, verify: + +```bash +# Check for accidentally committed secrets +git log --all --full-history -- "*.yaml" "*.env" "*.json" + +# Check that temp files are gitignored +git check-ignore helm-values-tmp.yaml + +# Verify no hardcoded credentials in source +grep -rn "password\|secret\|token\|api_key" --include="*.go" . | grep -v "_test.go" | grep -v "//.*" | grep -v "flag\|env\|config\|model\|type\|field" +``` + +--- + +## Security Testing Guidelines + +### Unit Tests + +Use the `MockCommandExecutor` to test security-sensitive code paths without needing real credentials: + +```go +func TestClusterNameValidation(t *testing.T) { + testutil.InitializeTestMode() + + // Test rejection of invalid names + invalidNames := []string{"My Cluster", "cluster!", "../escape", ""} + for _, name := range invalidNames { + err := models.ValidateClusterName(name) + assert.Error(t, err, "expected validation error for: %s", name) + } +} +``` + +### Code Review Security Checklist + +When reviewing PRs, check for: + +- [ ] No credentials or secrets hardcoded in source files +- [ ] All user input validated before use as a command argument +- [ ] External commands use argument slices (not string concatenation) +- [ ] Temporary files are cleaned up in both success and failure paths +- [ ] No new uses of insecure TLS outside of K3D-scoped contexts +- [ ] Error messages do not leak sensitive information (tokens, paths, credentials) + +--- + +## Reporting Security Issues + +For security vulnerabilities, please report directly via the **OpenMSP Slack community** (do not open a public GitHub issue for security disclosures): + +- [Join OpenMSP Slack](https://join.slack.com/t/openmsp/shared_invite/zt-36bl7mx0h-3~U2nFH6nqHqoTPXMaHEHA) +- [OpenMSP Website](https://www.openmsp.ai/) diff --git a/docs/development/setup/environment.md b/docs/development/setup/environment.md index 9f95aa1e..96b0b4e6 100644 --- a/docs/development/setup/environment.md +++ b/docs/development/setup/environment.md @@ -1,621 +1,198 @@ # Development Environment Setup -This guide walks you through setting up a complete development environment for OpenFrame CLI, including IDEs, tools, extensions, and configuration for maximum productivity. +This guide covers setting up your local machine for OpenFrame CLI development, including IDE configuration, Go toolchain setup, and recommended extensions. -## IDE and Editor Setup +--- -### Visual Studio Code (Recommended) +## Go Toolchain -VS Code provides excellent Go support and Kubernetes tooling: +OpenFrame CLI requires **Go 1.21 or newer**. -#### Installation ```bash -# macOS -brew install --cask visual-studio-code - -# Ubuntu/Debian -wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > packages.microsoft.gpg -sudo install -o root -g root -m 644 packages.microsoft.gpg /etc/apt/trusted.gpg.d/ -sudo sh -c 'echo "deb [arch=amd64,arm64,armhf signed-by=/etc/apt/trusted.gpg.d/packages.microsoft.gpg] https://packages.microsoft.com/repos/code stable main" > /etc/apt/sources.list.d/vscode.list' -sudo apt update -sudo apt install code -``` +# Verify your Go version +go version +# Expected: go version go1.21.x or higher + +# Install Go (Linux) +wget https://go.dev/dl/go1.21.0.linux-amd64.tar.gz +sudo rm -rf /usr/local/go +sudo tar -C /usr/local -xzf go1.21.0.linux-amd64.tar.gz +export PATH=$PATH:/usr/local/go/bin -#### Essential Extensions +# Install Go (macOS) +brew install go + +# Install Go (Windows WSL2) +# Run the Linux instructions above inside your WSL2 terminal +``` -Install these extensions for Go and Kubernetes development: +Ensure your `$GOPATH` and `$GOBIN` are configured: ```bash -# Core Go development -code --install-extension golang.Go -code --install-extension golang.Go-nightly +# Add to your shell profile (~/.bashrc, ~/.zshrc, etc.) +export GOPATH=$HOME/go +export GOBIN=$GOPATH/bin +export PATH=$PATH:$GOBIN +``` -# Kubernetes and YAML -code --install-extension ms-kubernetes-tools.vscode-kubernetes-tools -code --install-extension redhat.vscode-yaml +--- -# Git and GitHub integration -code --install-extension GitHub.vscode-pull-request-github -code --install-extension eamodio.gitlens +## Recommended IDE: VS Code + +[Visual Studio Code](https://code.visualstudio.com/) with the Go extension is the recommended editor for OpenFrame CLI development. -# Code quality and testing -code --install-extension ms-vscode.test-adapter-converter -code --install-extension hbenl.vscode-test-explorer -code --install-extension SonarSource.sonarlint-vscode +### Required Extensions -# Docker and containers -code --install-extension ms-azuretools.vscode-docker +| Extension | ID | Purpose | +|-----------|-----|---------| +| **Go** | `golang.go` | Go language support, IntelliSense, debugging | +| **GitLens** | `eamodio.gitlens` | Enhanced Git integration | +| **YAML** | `redhat.vscode-yaml` | Helm values YAML editing | -# Markdown and documentation -code --install-extension yzhang.markdown-all-in-one -code --install-extension bierner.markdown-mermaid +Install all at once: -# Productivity -code --install-extension vscodevim.vim # Optional: Vim keybindings -code --install-extension ms-vscode.vscode-json +```bash +code --install-extension golang.go +code --install-extension eamodio.gitlens +code --install-extension redhat.vscode-yaml ``` -#### VS Code Configuration +### Recommended VS Code Settings -Create `.vscode/settings.json` in your workspace: +Create or update `.vscode/settings.json` in your project: ```json { - "go.toolsManagement.autoUpdate": true, "go.useLanguageServer": true, - "go.gopath": "", - "go.goroot": "", "go.lintTool": "golangci-lint", - "go.lintFlags": [ - "--fast" - ], - "go.vetOnSave": "package", + "go.lintOnSave": "package", "go.formatTool": "goimports", - "go.buildOnSave": "package", - "go.testFlags": ["-v"], - "go.testTimeout": "30s", - "go.coverOnSave": false, - "go.coverOnSingleTest": true, - "go.coverOnSingleTestFile": true, - "go.coverOnTestPackage": true, + "go.testOnSave": false, "editor.formatOnSave": true, - "editor.codeActionsOnSave": { - "source.organizeImports": true - }, - "files.eol": "\n", - "yaml.schemas": { - "https://json.schemastore.org/kustomization": [ - "kustomization.yaml", - "kustomization.yml" - ], - "https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/crds/application-crd.yaml": [ - "**/argocd-apps/*.yaml", - "**/argocd-apps/*.yml" - ] - }, - "kubernetes.namespace": "default", - "kubernetes.defaultLogLevel": "info" -} -``` - -Create `.vscode/launch.json` for debugging: - -```json -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Launch OpenFrame CLI", - "type": "go", - "request": "launch", - "mode": "auto", - "program": "${workspaceFolder}/main.go", - "args": ["--help"], - "env": { - "GO_ENV": "development" - } - }, - { - "name": "Debug Bootstrap Command", - "type": "go", - "request": "launch", - "mode": "auto", - "program": "${workspaceFolder}/main.go", - "args": ["bootstrap", "--verbose", "--non-interactive"], - "env": { - "GO_ENV": "development" - } - }, - { - "name": "Debug Cluster Status", - "type": "go", - "request": "launch", - "mode": "auto", - "program": "${workspaceFolder}/main.go", - "args": ["cluster", "status"], - "env": { - "GO_ENV": "development" - } + "[go]": { + "editor.defaultFormatter": "golang.go", + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.organizeImports": "always" } - ] + } } ``` -### GoLand/IntelliJ IDEA - -For JetBrains IDEs: +--- -#### Installation -```bash -# macOS -brew install --cask goland - -# Or download from https://www.jetbrains.com/go/ -``` +## Alternative IDE: GoLand -#### Configuration -1. **Go Settings**: File → Settings → Go → GOROOT and GOPATH -2. **Code Style**: File → Settings → Editor → Code Style → Go -3. **Live Templates**: File → Settings → Editor → Live Templates -4. **Kubernetes Plugin**: File → Settings → Plugins → Install "Kubernetes" +[GoLand](https://www.jetbrains.com/go/) by JetBrains is a full-featured Go IDE with built-in debugging, refactoring, and Kubernetes support. -### Vim/Neovim +### Recommended GoLand Plugins -For terminal-based editing: +| Plugin | Purpose | +|--------|---------| +| **Kubernetes** | Kubernetes manifest support | +| **Go** (built-in) | Full Go language tooling | -#### Installation -```bash -# Install vim-go plugin manager -curl -fLo ~/.vim/autoload/plug.vim --create-dirs \ - https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim -``` +--- -Add to `~/.vimrc`: -```vim -call plug#begin('~/.vim/plugged') -Plug 'fatih/vim-go', { 'do': ':GoUpdateBinaries' } -Plug 'neoclide/coc.nvim', {'branch': 'release'} -Plug 'preservim/nerdtree' -Plug 'airblade/vim-gitgutter' -call plug#end() - -" Go-specific settings -let g:go_fmt_command = "goimports" -let g:go_auto_type_info = 1 -let g:go_highlight_types = 1 -let g:go_highlight_fields = 1 -let g:go_highlight_functions = 1 -let g:go_highlight_function_calls = 1 -``` +## Code Quality Tools -## Development Tools - -### Go Tools Installation - -Install essential Go development tools: +Install the following tools for linting and formatting: ```bash -# Core Go tools +# goimports — import organizer (used by the formatter) go install golang.org/x/tools/cmd/goimports@latest -go install golang.org/x/tools/cmd/godoc@latest -go install golang.org/x/tools/cmd/gofmt@latest - -# Linting and code quality -go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest -go install honnef.co/go/tools/cmd/staticcheck@latest -go install github.com/kisielk/errcheck@latest - -# Testing tools -go install github.com/rakyll/gotest@latest -go install github.com/axw/gocov/gocov@latest -go install github.com/AlekSi/gocov-xml@latest - -# Documentation tools -go install golang.org/x/tools/cmd/godoc@latest - -# Binary management -go install github.com/cosmtrek/air@latest # Hot reload -go install github.com/goreleaser/goreleaser@latest # Release management -``` - -### Configure golangci-lint - -Create `.golangci.yml` in the project root: - -```yaml -run: - timeout: 5m - issues-exit-code: 1 - tests: true - -linters-settings: - golint: - min-confidence: 0 - gocyclo: - min-complexity: 15 - goimports: - local-prefixes: github.com/flamingo-stack/openframe-cli - govet: - check-shadowing: true - errcheck: - check-type-assertions: true - check-blank: true - unused: - check-exported: false - -linters: - enable: - - bodyclose - - deadcode - - depguard - - dogsled - - dupl - - errcheck - - exportloopref - - exhaustive - - goconst - - gocritic - - gofmt - - goimports - - golint - - goprintffuncname - - gosec - - gosimple - - govet - - ineffassign - - misspell - - nakedret - - noctx - - nolintlint - - rowserrcheck - - staticcheck - - structcheck - - stylecheck - - typecheck - - unconvert - - unparam - - unused - - varcheck - - whitespace - -issues: - exclude-rules: - - path: _test\.go - linters: - - gosec - - dupl - exclude-use-default: false - exclude: - - "Error return value of .((os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*print.*|os\.(Un)?Setenv). is not checked" -``` -### Shell Configuration +# golangci-lint — multi-linter runner +curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOBIN) latest -Add helpful aliases and functions to your shell profile: - -```bash -# Add to ~/.bashrc, ~/.zshrc, or ~/.fish -# OpenFrame development aliases -alias of="go run main.go" -alias oft="go test ./..." -alias ofb="go build -o openframe main.go" -alias ofl="golangci-lint run" - -# Go development aliases -alias gob="go build" -alias got="go test" -alias gor="go run" -alias gof="go fmt ./..." -alias goi="goimports -w ." -alias gol="golangci-lint run" - -# Kubernetes aliases for development -alias k="kubectl" -alias kgp="kubectl get pods" -alias kgs="kubectl get svc" -alias kgd="kubectl get deployment" -alias kdp="kubectl describe pod" -alias kl="kubectl logs" -alias kex="kubectl exec -it" - -# OpenFrame specific kubectl contexts -alias kof="kubectl config use-context k3d-openframe-local" -alias kctx="kubectl config current-context" -alias kns="kubectl config set-context --current --namespace" - -# Docker aliases -alias d="docker" -alias dc="docker compose" -alias dps="docker ps" -alias di="docker images" -alias dl="docker logs" - -# Git aliases for development workflow -alias gs="git status" -alias ga="git add" -alias gc="git commit" -alias gp="git push" -alias gl="git pull" -alias gb="git branch" -alias gco="git checkout" -alias gd="git diff" +# Verify installations +goimports --version +golangci-lint --version ``` -## Environment Variables - -Set up development environment variables: +--- -```bash -# Add to your shell profile (~/.bashrc, ~/.zshrc, etc.) - -# Go development -export GOPATH="$HOME/go" -export GOROOT="$(go env GOROOT)" -export PATH="$GOPATH/bin:$GOROOT/bin:$PATH" +## Environment Variables for Development -# OpenFrame CLI development -export OPENFRAME_LOG_LEVEL="debug" -export OPENFRAME_CONFIG_DIR="$HOME/.openframe-dev" -export OPENFRAME_DEV_MODE="true" +The following environment variables are commonly used during development: -# Kubernetes development -export KUBECONFIG="$HOME/.kube/config" -export KUBECTL_EXTERNAL_DIFF="diff -u" +| Variable | Description | Example | +|----------|-------------|---------| +| `GOPATH` | Go workspace directory | `$HOME/go` | +| `GOBIN` | Go binaries directory | `$GOPATH/bin` | +| `KUBECONFIG` | Kubeconfig file path | `$HOME/.kube/config` | +| `CI` | Set to any value to enable CI/non-interactive mode | `true` | -# Docker development -export DOCKER_BUILDKIT=1 -export COMPOSE_DOCKER_CLI_BUILD=1 - -# Development tools -export EDITOR="code" # or vim, nano, etc. -export BROWSER="chrome" # or firefox, safari, etc. - -# Testing -export GO_TEST_TIMEOUT="30s" -export COVERAGE_OUTPUT="coverage.out" -``` +--- -## Kubernetes Development Setup +## Shell Completions (Optional) -### Configure kubectl contexts +OpenFrame CLI supports shell completions via Cobra. Add them to speed up development testing: ```bash -# Create separate contexts for development -kubectl config set-context openframe-dev \ - --cluster=k3d-openframe-local \ - --user=admin@k3d-openframe-local +# Bash completions +openframe completion bash > /etc/bash_completion.d/openframe -kubectl config set-context openframe-test \ - --cluster=k3d-openframe-test \ - --user=admin@k3d-openframe-test +# Zsh completions +openframe completion zsh > "${fpath[1]}/_openframe" -# Use development context by default -kubectl config use-context openframe-dev +# Fish completions +openframe completion fish > ~/.config/fish/completions/openframe.fish ``` -### Install Kubernetes development tools +--- -```bash -# Helm -curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash - -# K3D -curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash - -# Stern for log streaming -brew install stern # macOS -# or download from https://github.com/stern/stern/releases - -# kubectx and kubens for context switching -brew install kubectx # macOS -# or download from https://github.com/ahmetb/kubectx/releases - -# K9s for cluster management -brew install k9s # macOS -# or download from https://github.com/derailed/k9s/releases -``` +## Kubernetes Development Tools -## Testing Environment Setup - -### Configure test databases and services - -```bash -# Create test namespace -kubectl create namespace openframe-test - -# Install test dependencies -helm repo add bitnami https://charts.bitnami.com/bitnami -helm install test-redis bitnami/redis \ - --namespace openframe-test \ - --set auth.enabled=false - -# Install test monitoring -kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/kind/deploy.yaml -``` - -### Test configuration - -Create `test.env` for test environment variables: - -```bash -# Test environment configuration -export OPENFRAME_TEST_MODE=true -export OPENFRAME_TEST_CLUSTER="k3d-openframe-test" -export OPENFRAME_TEST_NAMESPACE="openframe-test" -export OPENFRAME_TEST_TIMEOUT="60s" - -# Test database connections -export TEST_REDIS_URL="redis://localhost:6379" -export TEST_DATABASE_URL="postgres://localhost:5432/openframe_test" - -# Integration test settings -export INTEGRATION_TEST_ENABLED=true -export E2E_TEST_ENABLED=false # Disable by default -``` - -## Performance and Debugging Tools - -### Install profiling tools +For working on the `dev` intercept and scaffold features, install these additional tools: ```bash -# Go profiling tools -go install github.com/google/pprof@latest -go install github.com/uber/go-torch@latest - -# Memory and performance analysis -go install github.com/pkg/profile@latest -``` - -### Configure debugging - -Add debug configuration to your project: - -```go -// debug/profile.go -// +build debug - -package debug - -import ( - "github.com/pkg/profile" - "os" -) - -func init() { - if os.Getenv("CPUPROFILE") != "" { - defer profile.Start().Stop() - } - if os.Getenv("MEMPROFILE") != "" { - defer profile.Start(profile.MemProfile).Stop() - } -} -``` - -## Pre-commit Hooks +# Telepresence v2 (traffic intercept) +curl -fL https://app.getambassador.io/download/tel2/linux/amd64/latest/telepresence -o telepresence +chmod +x telepresence && sudo mv telepresence /usr/local/bin/ -Set up git hooks for code quality: +# Skaffold (hot-reload dev sessions) +curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64 +chmod +x skaffold && sudo mv skaffold /usr/local/bin/ -```bash -# Install pre-commit (optional but recommended) -pip install pre-commit - -# Create .pre-commit-config.yaml -cat > .pre-commit-config.yaml << 'EOF' -repos: - - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 - hooks: - - id: trailing-whitespace - - id: end-of-file-fixer - - id: check-yaml - - id: check-added-large-files - - - repo: https://github.com/dnephin/pre-commit-golang - rev: v0.5.1 - hooks: - - id: go-fmt - - id: go-imports - - id: go-vet-mod - - id: go-unit-tests-mod - - id: golangci-lint-mod -EOF - -# Install the hooks -pre-commit install +# jq (JSON processing for intercept scripts) +sudo apt-get install jq # Debian/Ubuntu +brew install jq # macOS ``` -Or create a simple git hook manually: - -```bash -# Create .git/hooks/pre-commit -cat > .git/hooks/pre-commit << 'EOF' -#!/bin/bash -# Pre-commit hook for OpenFrame CLI - -set -e +--- -echo "Running pre-commit checks..." +## Hardware Requirements -# Format code -echo "Running gofmt..." -gofmt -l -w . - -# Organize imports -echo "Running goimports..." -goimports -l -w . - -# Run linter -echo "Running golangci-lint..." -golangci-lint run - -# Run tests -echo "Running tests..." -go test -short ./... - -echo "Pre-commit checks passed!" -EOF - -chmod +x .git/hooks/pre-commit -``` +| Tier | RAM | CPU Cores | Disk | +|------|-----|-----------|------| +| **Minimum** | 24 GB | 6 cores | 50 GB | +| **Recommended** | 32 GB | 12 cores | 100 GB | -## Troubleshooting +Running a full K3D-based stack locally with ArgoCD is resource-intensive. The minimum specs are adequate for unit test development, but the recommended specs are needed for integration testing and full-stack development. -### Common Go Issues +--- -#### GOPATH/GOROOT Problems -```bash -# Check Go environment -go env +## Verifying Your Setup -# Reset Go environment -go env -w GOPATH="" -go env -w GOROOT="" -``` +Run this checklist to confirm your development environment is ready: -#### Module Issues ```bash -# Clean module cache -go clean -modcache - -# Reinstall dependencies -go mod tidy -go mod download -``` - -### Kubernetes Issues +# Go version +go version -#### Context Not Found -```bash -# List available contexts -kubectl config get-contexts +# Module downloads work +go env GOMODCACHE -# Create new context -kubectl config set-context openframe-dev \ - --cluster=k3d-openframe-local \ - --user=admin@k3d-openframe-local -``` +# Linter available +golangci-lint --version -#### Tools Not Found -```bash -# Verify PATH includes Go bin directory -echo $PATH | grep go +# Build the project +cd openframe-cli +go build ./... -# Add Go bin to PATH -export PATH="$GOPATH/bin:$PATH" +# Run unit tests +go test ./... -short ``` -## Next Steps - -Your development environment is now ready! Continue with: - -1. **[Local Development Guide](local-development.md)** - Clone and run OpenFrame CLI locally -2. **[Architecture Overview](../architecture/README.md)** - Understand the system design -3. **[Contributing Guidelines](../contributing/guidelines.md)** - Learn the development workflow - -## Additional Resources - -- **Go Documentation**: https://golang.org/doc/ -- **Kubernetes Documentation**: https://kubernetes.io/docs/ -- **Cobra CLI Documentation**: https://cobra.dev/ -- **VS Code Go Extension**: https://marketplace.visualstudio.com/items?itemName=golang.Go -- **OpenMSP Slack**: [Join the community](https://join.slack.com/t/openmsp/shared_invite/zt-36bl7mx0h-3~U2nFH6nqHqoTPXMaHEHA) \ No newline at end of file +If all commands succeed, your environment is ready for development. Continue to the [Local Development Guide](local-development.md) to clone the repo and start running the CLI. diff --git a/docs/development/setup/local-development.md b/docs/development/setup/local-development.md index 66002a68..1398a6cd 100644 --- a/docs/development/setup/local-development.md +++ b/docs/development/setup/local-development.md @@ -1,590 +1,278 @@ # Local Development Guide -This guide covers cloning, building, running, and debugging OpenFrame CLI in your local development environment. Follow these steps to get the code running and start contributing. +This guide walks you through cloning the repository, running the CLI locally, and setting up your debug configuration for active development on OpenFrame CLI. -## Prerequisites - -Before starting local development, ensure you have completed: -- **[Prerequisites](../../getting-started/prerequisites.md)** - System requirements and dependencies -- **[Environment Setup](environment.md)** - IDE, tools, and development configuration +--- ## Clone the Repository -### Fork and Clone (Recommended for Contributors) - -1. **Fork the repository** on GitHub: - - Go to https://github.com/flamingo-stack/openframe-cli - - Click "Fork" in the top-right corner - - Choose your GitHub account - -2. **Clone your fork**: - ```bash - # Clone your fork - git clone https://github.com/YOUR-USERNAME/openframe-cli.git - cd openframe-cli - - # Add upstream remote for syncing - git remote add upstream https://github.com/flamingo-stack/openframe-cli.git - - # Verify remotes - git remote -v - ``` - -### Direct Clone (Read-only) - -For read-only access or testing: - ```bash git clone https://github.com/flamingo-stack/openframe-cli.git cd openframe-cli ``` -## Project Structure Overview - -Familiarize yourself with the codebase structure: - -```text -openframe-cli/ -├── main.go # Application entry point -├── go.mod # Go module definition -├── go.sum # Go dependency checksums -├── cmd/ # CLI command definitions -│ ├── root.go # Root command and version info -│ ├── bootstrap/ # Complete environment bootstrap -│ ├── cluster/ # Kubernetes cluster management -│ ├── chart/ # Helm chart and ArgoCD operations -│ └── dev/ # Development workflow tools -├── internal/ # Private application code -│ ├── bootstrap/ # Bootstrap orchestration service -│ ├── cluster/ # Cluster lifecycle management -│ ├── chart/ # Chart installation and ArgoCD integration -│ ├── dev/ # Development tools (intercept, scaffold) -│ └── shared/ # Common utilities and adapters -├── tests/ # Test suites and utilities -│ ├── integration/ # Integration tests -│ ├── mocks/ # Test mocks and fixtures -│ └── testutil/ # Test helper functions -├── docs/ # Documentation -├── examples/ # Usage examples and samples -└── scripts/ # Build and utility scripts -``` +--- -## Build and Run +## Install Dependencies -### Build the Binary +Go modules are used for dependency management. Fetch all dependencies: ```bash -# Build for your current platform -go build -o openframe main.go - -# Build with version information -VERSION=$(git describe --tags --always --dirty) -COMMIT=$(git rev-parse --short HEAD) -DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") - -go build -ldflags "-X main.version=$VERSION -X main.commit=$COMMIT -X main.date=$DATE" -o openframe main.go - -# Test the build -./openframe --version +go mod download +go mod verify ``` -### Run During Development +--- -For rapid development cycles, run directly with Go: +## Build the CLI ```bash -# Run with go run (rebuilds automatically) -go run main.go --help +# Build the binary to the project root +go build -o openframe ./main.go -# Run specific commands -go run main.go bootstrap --help -go run main.go cluster status -go run main.go chart list +# Verify it works +./openframe --version ``` -### Hot Reload with Air - -Install and use Air for automatic rebuilds: +For cross-platform builds: ```bash -# Install Air -go install github.com/cosmtrek/air@latest - -# Create .air.toml configuration -cat > .air.toml << 'EOF' -root = "." -testdata_dir = "testdata" -tmp_dir = "tmp" - -[build] -args_bin = [] -bin = "./tmp/main" -cmd = "go build -o ./tmp/main main.go" -delay = 1000 -exclude_dir = ["assets", "tmp", "vendor", "testdata", "docs"] -exclude_file = [] -exclude_regex = ["_test.go"] -exclude_unchanged = false -follow_symlink = false -full_bin = "" -include_dir = [] -include_ext = ["go", "tpl", "tmpl", "html"] -kill_delay = "0s" -log = "build-errors.log" -send_interrupt = false -stop_on_root = false - -[color] -app = "" -build = "yellow" -main = "magenta" -runner = "green" -watcher = "cyan" - -[log] -time = false +# Linux AMD64 +GOOS=linux GOARCH=amd64 go build -o openframe-linux-amd64 ./main.go -[misc] -clean_on_exit = false -EOF +# macOS ARM64 (Apple Silicon) +GOOS=darwin GOARCH=arm64 go build -o openframe-darwin-arm64 ./main.go -# Run with hot reload -air +# Windows AMD64 +GOOS=windows GOARCH=amd64 go build -o openframe-windows-amd64.exe ./main.go ``` -Now changes to Go files will automatically trigger rebuilds. +--- -## Running Tests +## Running the CLI Locally -### Unit Tests +After building, run the local binary directly: ```bash -# Run all tests -go test ./... - -# Run tests with verbose output -go test -v ./... +# Run locally built binary +./openframe --help -# Run tests with coverage -go test -cover ./... +# Run with verbose output +./openframe --verbose cluster list -# Generate detailed coverage report -go test -coverprofile=coverage.out ./... -go tool cover -html=coverage.out -o coverage.html -open coverage.html # macOS -# or xdg-open coverage.html # Linux +# Run in dry-run mode (no actual k3d/helm calls) +./openframe bootstrap --deployment-mode=oss-tenant --dry-run ``` -### Integration Tests - -Integration tests require a running Kubernetes cluster: - -```bash -# Start a test cluster -k3d cluster create openframe-test - -# Run integration tests -go test -tags=integration ./tests/integration/... +--- -# Clean up -k3d cluster delete openframe-test -``` +## Run Without Building (go run) -### Test Specific Packages +For rapid iteration during development: ```bash -# Test specific packages -go test ./internal/cluster/... -go test ./internal/chart/... -go test ./cmd/bootstrap/... +# Run directly without building +go run ./main.go --help -# Test with timeout -go test -timeout=30s ./internal/bootstrap/... +# Run a specific command +go run ./main.go cluster list -# Run specific tests -go test -run TestClusterCreate ./internal/cluster/... -go test -run TestBootstrapService ./internal/bootstrap/... +# Bootstrap with verbose output +go run ./main.go bootstrap --deployment-mode=oss-tenant -v ``` -## Development Workflow - -### Create a Feature Branch - -```bash -# Sync with upstream (if using fork) -git fetch upstream -git checkout main -git merge upstream/main - -# Create feature branch -git checkout -b feature/your-feature-name - -# Or for bug fixes -git checkout -b fix/issue-description -``` +--- -### Make Changes +## Watch Mode / Hot Reload -1. **Write Code**: Implement your feature or fix -2. **Write Tests**: Add or update tests for your changes -3. **Run Tests**: Ensure all tests pass -4. **Format Code**: Use `gofmt` and `goimports` -5. **Lint Code**: Run `golangci-lint` +Go does not have built-in watch mode, but you can use `air` for automatic rebuilds on file changes: ```bash -# Format and organize imports -gofmt -w . -goimports -w . - -# Run linter -golangci-lint run +# Install air +go install github.com/air-verse/air@latest -# Run all tests -go test ./... +# Run in watch mode (rebuilds and restarts on .go file changes) +air ``` -### Commit Changes +Create a minimal `.air.toml` config: -Follow conventional commit format: - -```bash -# Stage changes -git add . - -# Commit with descriptive message -git commit -m "feat(cluster): add support for custom node labels" -git commit -m "fix(bootstrap): handle timeout errors gracefully" -git commit -m "docs(readme): update installation instructions" +```toml +[build] + cmd = "go build -o ./tmp/openframe ./main.go" + bin = "./tmp/openframe" + include_ext = ["go"] + exclude_dir = ["tests", "vendor"] -# Push to your fork -git push origin feature/your-feature-name +[log] + time = true ``` -## Debugging - -### VS Code Debugging - -Use the launch configurations from [Environment Setup](environment.md): +--- -1. **Set breakpoints** in your code -2. **Press F5** or go to Run → Start Debugging -3. **Choose configuration**: - - "Launch OpenFrame CLI" - Debug with `--help` - - "Debug Bootstrap Command" - Debug bootstrap process - - "Debug Cluster Status" - Debug cluster operations - -### Command-line Debugging with Delve +## Running Tests ```bash -# Install Delve -go install github.com/go-delve/delve/cmd/dlv@latest - -# Debug the application -dlv debug main.go -- bootstrap --verbose - -# Debug tests -dlv test ./internal/bootstrap/ +# Run all unit tests +go test ./... -# Debug with arguments -dlv debug main.go -- cluster create --name=test-cluster -``` +# Run with verbose output +go test ./... -v -### Debug Commands in Delve - -```text -(dlv) break main.main # Set breakpoint at main function -(dlv) break bootstrap.go:45 # Set breakpoint at line 45 in bootstrap.go -(dlv) continue # Continue execution -(dlv) next # Execute next line -(dlv) step # Step into function calls -(dlv) print variable_name # Print variable value -(dlv) goroutines # List all goroutines -(dlv) exit # Exit debugger -``` +# Run a specific package +go test ./internal/cluster/... -### Debugging with Print Statements +# Run with race detection +go test -race ./... -For quick debugging, add log statements: +# Run short tests only (skips integration tests) +go test ./... -short -```go -package main - -import ( - "log" - "os" -) - -func debugFunction() { - log.Printf("DEBUG: variable value: %+v", variable) - - // Pretty print structs - log.Printf("DEBUG: struct: %#v", structVariable) - - // Print with file and line info - log.Printf("DEBUG [%s:%d]: message", "filename.go", 123) -} +# Run integration tests (requires Docker, k3d, kubectl, helm) +go test ./tests/integration/... +``` -func init() { - // Enable debug logging during development - if os.Getenv("DEBUG") == "true" { - log.SetFlags(log.LstdFlags | log.Lshortfile) +--- + +## Debug Configuration + +### VS Code Debug Configuration + +Create `.vscode/launch.json`: + +```json +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Debug: bootstrap", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${workspaceFolder}/main.go", + "args": ["bootstrap", "--deployment-mode=oss-tenant", "-v"], + "env": { + "CI": "true" + } + }, + { + "name": "Debug: cluster list", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${workspaceFolder}/main.go", + "args": ["cluster", "list"] + }, + { + "name": "Debug: dev intercept", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${workspaceFolder}/main.go", + "args": ["dev", "intercept", "my-service", "--port", "8080"] } + ] } ``` -Run with debug logging: -```bash -DEBUG=true go run main.go bootstrap -``` - -## Testing Your Changes - -### Manual Testing - -Create test scenarios to verify your changes: - -```bash -# Test bootstrap functionality -go run main.go bootstrap --mode=oss-tenant --non-interactive - -# Test cluster operations -go run main.go cluster create test-cluster -go run main.go cluster status test-cluster -go run main.go cluster delete test-cluster - -# Test chart operations -go run main.go chart install test-app --repo=https://charts.example.com -go run main.go chart list - -# Test development tools -go run main.go dev scaffold my-service --template=microservice -go run main.go dev intercept my-service --port=3000:8080 -``` - -### Integration Testing +### GoLand Debug Configuration -Test with real Kubernetes clusters: +1. Open **Run > Edit Configurations** +2. Add a new **Go Application** configuration +3. Set **Program arguments** to e.g. `bootstrap --deployment-mode=oss-tenant -v` +4. Set **Working directory** to your project root -```bash -# Create test cluster -k3d cluster create openframe-test --agents 2 +--- -# Run your changes against the cluster -KUBECONFIG=$(k3d kubeconfig write openframe-test) go run main.go bootstrap +## Test Mode -# Verify results -kubectl get pods --all-namespaces -kubectl get applications -n argocd +The CLI includes a `TestMode` flag that disables interactive UI elements (logo rendering, spinners) during automated testing: -# Clean up -k3d cluster delete openframe-test -``` - -### Performance Testing - -Monitor resource usage and performance: - -```bash -# Build optimized binary -go build -ldflags="-s -w" -o openframe main.go - -# Monitor memory usage -/usr/bin/time -v ./openframe bootstrap - -# Profile CPU usage -CPUPROFILE=cpu.prof go run main.go bootstrap -go tool pprof cpu.prof - -# Profile memory usage -MEMPROFILE=mem.prof go run main.go bootstrap -go tool pprof mem.prof -``` - -## Code Quality - -### Automated Checks - -Run all quality checks before committing: - -```bash -#!/bin/bash -# quality-check.sh - -echo "Running code quality checks..." - -# Format code -echo "Formatting code..." -gofmt -l -w . -goimports -l -w . - -# Vet code -echo "Vetting code..." -go vet ./... - -# Run linter -echo "Running linter..." -golangci-lint run - -# Run tests -echo "Running tests..." -go test -race -cover ./... - -# Check for security issues -echo "Checking security..." -gosec ./... - -# Check dependencies -echo "Checking dependencies..." -go mod tidy -go mod verify - -echo "All checks passed!" -``` - -Make it executable and run: -```bash -chmod +x quality-check.sh -./quality-check.sh +```go +// In test files +testutil.InitializeTestMode() ``` -### Manual Code Review - -Before submitting changes, review: +This prevents terminal output issues when running tests in CI environments or headless shells. -1. **Code Structure**: Is the code well-organized and follows Go conventions? -2. **Error Handling**: Are errors properly handled and user-friendly? -3. **Documentation**: Are public functions and packages documented? -4. **Tests**: Are there adequate unit and integration tests? -5. **Performance**: Are there any obvious performance issues? +--- -## Advanced Development +## Mock Executor -### Working with Dependencies - -```bash -# Add a new dependency -go get github.com/new/dependency@latest - -# Update dependencies -go get -u ./... - -# Vendor dependencies (if needed) -go mod vendor - -# Remove unused dependencies -go mod tidy -``` - -### Working with Build Tags - -Use build tags for conditional compilation: +All external command execution (k3d, helm, kubectl, git) is abstracted through the `CommandExecutor` interface. During development and testing, you can use the `MockCommandExecutor` to simulate responses without running real binaries: ```go -// +build debug +// Create a mock executor +executor := testutil.NewTestMockExecutor() -package debug - -func init() { - // Debug-only initialization -} +// Inject into service layers for isolated unit testing +flags := testutil.CreateStandardTestFlags() ``` -```bash -# Build with debug tag -go build -tags debug -o openframe-debug main.go - -# Run tests with integration tag -go test -tags integration ./... +The mock executor pattern-matches command strings and returns pre-configured responses, making it safe to run the full business logic without a real Kubernetes cluster. + +--- + +## Typical Development Workflow + +```mermaid +sequenceDiagram + participant Dev["Developer"] + participant Repo["Local Repo"] + participant Tests["go test"] + participant CLI["./openframe binary"] + participant K3D["K3D Cluster"] + + Dev->>Repo: Edit Go source files + Dev->>Tests: go test ./... -short + Tests-->>Dev: Unit tests pass (mocked executor) + Dev->>CLI: go build -o openframe ./main.go + Dev->>CLI: ./openframe cluster list + CLI->>K3D: k3d cluster list + K3D-->>CLI: Cluster info + CLI-->>Dev: Rendered table output + Dev->>Tests: go test ./tests/integration/... (full stack) + Tests->>K3D: Create/delete real cluster + Tests-->>Dev: Integration tests pass ``` -### Cross-platform Development - -Build for multiple platforms: - -```bash -# Build for Linux -GOOS=linux GOARCH=amd64 go build -o openframe-linux main.go - -# Build for Windows -GOOS=windows GOARCH=amd64 go build -o openframe.exe main.go +--- -# Build for macOS (Intel) -GOOS=darwin GOARCH=amd64 go build -o openframe-darwin-amd64 main.go +## Project Configuration Files -# Build for macOS (Apple Silicon) -GOOS=darwin GOARCH=arm64 go build -o openframe-darwin-arm64 main.go -``` +| File | Purpose | +|------|---------| +| `go.mod` | Go module definition and dependencies | +| `go.sum` | Dependency checksums | +| `main.go` | Binary entrypoint — delegates to `cmd.Execute()` | +| `cmd/root.go` | Root Cobra command, global flags, version info | -## Troubleshooting +--- -### Common Development Issues +## Common Development Tasks -#### Module Problems ```bash -# Clear module cache -go clean -modcache - -# Reinitialize modules -rm go.sum +# Tidy up unused dependencies go mod tidy -``` -#### Build Errors -```bash -# Clean build cache -go clean -cache - -# Rebuild everything -go build -a main.go -``` +# Run the linter +golangci-lint run ./... -#### Test Failures -```bash -# Run tests with verbose output -go test -v -race ./... - -# Run specific failing test -go test -v -run TestSpecificFunction ./path/to/package -``` - -#### Kubernetes Context Issues -```bash -# Check current context -kubectl config current-context +# Format all Go files +goimports -w . -# Switch to correct context -kubectl config use-context k3d-openframe-local +# Check for compilation errors without building +go vet ./... -# Verify cluster connectivity -kubectl cluster-info +# Generate test coverage report +go test -coverprofile=coverage.out ./... +go tool cover -html=coverage.out -o coverage.html ``` -### Debug Environment Variables - -Set these for debugging: - -```bash -export GODEBUG="gctrace=1" # GC tracing -export GOTRACEBACK="all" # Full stack traces -export OPENFRAME_LOG_LEVEL="debug" # Detailed logging -export KUBECONFIG="$HOME/.kube/config" -``` +--- ## Next Steps -Now that you have a working development environment: - -1. **[Architecture Overview](../architecture/README.md)** - Understand the system design -2. **[Contributing Guidelines](../contributing/guidelines.md)** - Learn the contribution process -3. **[Testing Guide](../testing/README.md)** - Deep dive into testing strategies - -## Getting Help - -If you encounter issues: - -- **Check existing issues**: Search GitHub issues for similar problems -- **Ask in Slack**: Join the [OpenMSP community](https://join.slack.com/t/openmsp/shared_invite/zt-36bl7mx0h-3~U2nFH6nqHqoTPXMaHEHA) -- **Review documentation**: Check other guides in this repository -- **Debug systematically**: Use logging and debugging tools to isolate issues - -Happy coding! 🚀 \ No newline at end of file +- Review the [Architecture Overview](../architecture/README.md) to understand how the code is organized +- Read the [Testing Guide](../testing/README.md) to learn how to write effective tests +- Check the [Contributing Guidelines](../contributing/guidelines.md) before submitting a PR diff --git a/docs/diagrams/architecture/README.md b/docs/diagrams/architecture/README.md index 7b3e892e..06f0461f 100644 --- a/docs/diagrams/architecture/README.md +++ b/docs/diagrams/architecture/README.md @@ -4,10 +4,10 @@ This directory contains Mermaid diagrams generated from architecture analysis. ## Diagrams -- **[High-Level System Design](./high-level-system-design.mmd)** - `.mmd` file -- **[Dependency Flow Between Modules](./dependency-flow-between-modules.mmd)** - `.mmd` file -- **[Complete Bootstrap Workflow](./complete-bootstrap-workflow.mmd)** - `.mmd` file -- **[Development Intercept Workflow](./development-intercept-workflow.mmd)** - `.mmd` file +- **[High-Level Architecture Diagram](./high-level-architecture-diagram.mmd)** - `.mmd` file +- **[Dependency Graph](./dependency-graph.mmd)** - `.mmd` file +- **[Bootstrap Command: Full Environment Setup](./bootstrap-command-full-environment-setup.mmd)** - `.mmd` file +- **[Interactive Intercept: Dev Workflow](./interactive-intercept-dev-workflow.mmd)** - `.mmd` file ## Viewing Diagrams diff --git a/docs/diagrams/architecture/bootstrap-command-full-environment-setup.mmd b/docs/diagrams/architecture/bootstrap-command-full-environment-setup.mmd new file mode 100644 index 00000000..7bacffe7 --- /dev/null +++ b/docs/diagrams/architecture/bootstrap-command-full-environment-setup.mmd @@ -0,0 +1,48 @@ +sequenceDiagram + participant User + participant BootstrapCmd as "bootstrap cmd" + participant BootstrapSvc as "Bootstrap Service" + participant ClusterSvc as "Cluster Service" + participant K3DMgr as "K3D Manager" + participant ChartSvc as "Chart Service" + participant GitProv as "Git Provider" + participant HelmMgr as "Helm Manager" + participant ArgoCDMgr as "ArgoCD Manager" + participant K8sAPI as "Kubernetes API" + participant GitHub as "GitHub" + + User->>BootstrapCmd: openframe bootstrap [name] [--deployment-mode] + BootstrapCmd->>BootstrapSvc: Execute(cmd, args) + BootstrapSvc->>ClusterSvc: CreateClusterWithPrerequisites(name, verbose) + ClusterSvc->>K3DMgr: CreateCluster(ClusterConfig) + K3DMgr->>K3DMgr: Generate k3d config YAML + K3DMgr->>K3DMgr: k3d cluster create --config ... + K3DMgr-->>ClusterSvc: rest.Config + ClusterSvc-->>BootstrapSvc: rest.Config + + BootstrapSvc->>ChartSvc: InstallChartsWithConfig(InstallationRequest) + ChartSvc->>ChartSvc: Check prerequisites (helm, git, certs) + ChartSvc->>ChartSvc: Interactive wizard OR use --deployment-mode + + ChartSvc->>HelmMgr: InstallArgoCDWithProgress(config) + HelmMgr->>HelmMgr: helm repo add / helm upgrade --install argo-cd + HelmMgr-->>ChartSvc: ArgoCD installed + + ChartSvc->>GitProv: CloneChartRepository(AppOfAppsConfig) + GitProv->>GitHub: git clone --depth 1 --branch [branch] + GitHub-->>GitProv: chart files + GitProv-->>ChartSvc: CloneResult{TempDir, ChartPath} + + ChartSvc->>HelmMgr: InstallAppOfAppsFromLocal(config, certFile, keyFile) + HelmMgr->>K8sAPI: helm upgrade --install app-of-apps + HelmMgr-->>ChartSvc: app-of-apps installed + + ChartSvc->>ArgoCDMgr: WaitForApplications(config) + loop Poll every 2s up to timeout + ArgoCDMgr->>K8sAPI: List Application CRDs + K8sAPI-->>ArgoCDMgr: Application statuses + ArgoCDMgr->>ArgoCDMgr: Check Healthy + Synced + end + ArgoCDMgr-->>ChartSvc: All applications ready + ChartSvc-->>BootstrapSvc: Success + BootstrapSvc-->>User: Environment ready diff --git a/docs/diagrams/architecture/complete-bootstrap-workflow.mmd b/docs/diagrams/architecture/complete-bootstrap-workflow.mmd deleted file mode 100644 index 366b0980..00000000 --- a/docs/diagrams/architecture/complete-bootstrap-workflow.mmd +++ /dev/null @@ -1,32 +0,0 @@ -sequenceDiagram - participant User - participant Bootstrap as Bootstrap Service - participant Cluster as Cluster Service - participant K3D as K3D Provider - participant Chart as Chart Service - participant Helm as Helm Provider - participant ArgoCD as ArgoCD Provider - participant K8s as Kubernetes API - - User->>Bootstrap: openframe bootstrap - Bootstrap->>Bootstrap: Check prerequisites - Bootstrap->>Cluster: Create cluster - Cluster->>K3D: Create K3D cluster - K3D->>K8s: Initialize cluster - K8s-->>K3D: Cluster ready - K3D-->>Cluster: Cluster config - Cluster-->>Bootstrap: rest.Config - - Bootstrap->>Chart: Install charts - Chart->>Helm: Install ArgoCD - Helm->>K8s: Deploy ArgoCD - K8s-->>Helm: ArgoCD running - Helm-->>Chart: Installation complete - - Chart->>ArgoCD: Install app-of-apps - ArgoCD->>K8s: Create Application CRDs - K8s-->>ArgoCD: Applications created - ArgoCD->>ArgoCD: Sync applications - ArgoCD-->>Chart: Applications synced - Chart-->>Bootstrap: Charts installed - Bootstrap-->>User: Environment ready diff --git a/docs/diagrams/architecture/dependency-flow-between-modules.mmd b/docs/diagrams/architecture/dependency-flow-between-modules.mmd deleted file mode 100644 index 4141f827..00000000 --- a/docs/diagrams/architecture/dependency-flow-between-modules.mmd +++ /dev/null @@ -1,76 +0,0 @@ -graph TD - subgraph "Command Layer" - RootCmd[Root Command] - BootstrapCmd[Bootstrap Command] - ClusterCmd[Cluster Commands] - ChartCmd[Chart Commands] - DevCmd[Dev Commands] - end - - subgraph "Service Orchestration" - BootstrapSvc[Bootstrap Service] - end - - subgraph "Domain Services" - ClusterSvc[Cluster Service] - ChartSvc[Chart Service] - InterceptSvc[Intercept Service] - ScaffoldSvc[Scaffold Service] - end - - subgraph "Provider Implementations" - K3DMgr[K3D Manager] - HelmMgr[Helm Manager] - ArgoCDMgr[ArgoCD Manager] - TelepresenceProv[Telepresence Provider] - KubectlProv[Kubectl Provider] - GitRepo[Git Repository] - end - - subgraph "Shared Infrastructure" - Executor[Command Executor] - UI[UI Components] - Config[Configuration] - Prerequisites[Prerequisites] - end - - RootCmd --> BootstrapCmd - RootCmd --> ClusterCmd - RootCmd --> ChartCmd - RootCmd --> DevCmd - - BootstrapCmd --> BootstrapSvc - ClusterCmd --> ClusterSvc - ChartCmd --> ChartSvc - DevCmd --> InterceptSvc - DevCmd --> ScaffoldSvc - - BootstrapSvc --> ClusterSvc - BootstrapSvc --> ChartSvc - - ClusterSvc --> K3DMgr - ChartSvc --> HelmMgr - ChartSvc --> ArgoCDMgr - ChartSvc --> GitRepo - InterceptSvc --> TelepresenceProv - InterceptSvc --> KubectlProv - ScaffoldSvc --> KubectlProv - - K3DMgr --> Executor - HelmMgr --> Executor - ArgoCDMgr --> Executor - TelepresenceProv --> Executor - KubectlProv --> Executor - GitRepo --> Executor - - ClusterSvc --> UI - ChartSvc --> UI - InterceptSvc --> UI - ScaffoldSvc --> UI - - ClusterSvc --> Config - ChartSvc --> Config - - ClusterSvc --> Prerequisites - ChartSvc --> Prerequisites - DevCmd --> Prerequisites diff --git a/docs/diagrams/architecture/dependency-graph.mmd b/docs/diagrams/architecture/dependency-graph.mmd new file mode 100644 index 00000000..97651b9d --- /dev/null +++ b/docs/diagrams/architecture/dependency-graph.mmd @@ -0,0 +1,104 @@ +graph LR + subgraph Commands["cmd/ layer"] + CmdRoot["root"] + CmdBoot["bootstrap"] + CmdCluster["cluster/*"] + CmdChart["chart/*"] + CmdDev["dev/*"] + end + + subgraph InternalBootstrap["internal/bootstrap"] + SvcBoot["Bootstrap Service"] + end + + subgraph InternalCluster["internal/cluster"] + SvcCluster["Cluster Service"] + ModCluster["models"] + ProvK3D["providers/k3d"] + UICluster["ui/*"] + PrereqCluster["prerequisites/*"] + UtilsCluster["utils/"] + end + + subgraph InternalChart["internal/chart"] + SvcChart["services/*"] + ModChart["models"] + ProvHelm["providers/helm"] + ProvArgoCD["providers/argocd"] + ProvGit["providers/git"] + UIChart["ui/*"] + PrereqChart["prerequisites/*"] + UtilsChart["utils/config + errors + types"] + end + + subgraph InternalDev["internal/dev"] + SvcIntercept["services/intercept"] + SvcScaffold["services/scaffold"] + ProvKubectl["providers/kubectl"] + ProvTelepresence["providers/telepresence"] + ProvDevChart["providers/chart"] + UIDevIntercept["ui/intercept + service"] + PrereqDev["prerequisites/*"] + end + + subgraph Shared["internal/shared"] + SharedExec["executor"] + SharedUI["ui/"] + SharedErrors["errors/"] + SharedConfig["config/"] + SharedFiles["files/"] + SharedFlags["flags/"] + end + + CmdRoot --> CmdBoot + CmdRoot --> CmdCluster + CmdRoot --> CmdChart + CmdRoot --> CmdDev + + CmdBoot --> SvcBoot + SvcBoot --> SvcCluster + SvcBoot --> SvcChart + + CmdCluster --> UtilsCluster + UtilsCluster --> SvcCluster + SvcCluster --> ProvK3D + SvcCluster --> UICluster + SvcCluster --> ModCluster + SvcCluster --> PrereqCluster + + CmdChart --> SvcChart + SvcChart --> ProvHelm + SvcChart --> ProvArgoCD + SvcChart --> ProvGit + SvcChart --> UIChart + SvcChart --> UtilsChart + SvcChart --> ModChart + SvcChart --> PrereqChart + + CmdDev --> SvcIntercept + CmdDev --> SvcScaffold + SvcIntercept --> ProvTelepresence + SvcIntercept --> ProvKubectl + SvcScaffold --> ProvDevChart + SvcScaffold --> ProvKubectl + SvcScaffold --> PrereqDev + UIDevIntercept --> ProvKubectl + + ProvK3D --> SharedExec + ProvHelm --> SharedExec + ProvHelm --> SharedConfig + ProvArgoCD --> SharedConfig + ProvGit --> SharedExec + ProvKubectl --> SharedExec + ProvTelepresence --> SharedExec + + SvcCluster --> SharedUI + SvcCluster --> SharedErrors + SvcChart --> SharedErrors + SvcChart --> SharedFiles + SvcChart --> SharedConfig + UICluster --> SharedUI + UIChart --> SharedUI + UIDevIntercept --> SharedUI + + ModCluster --> SharedFlags diff --git a/docs/diagrams/architecture/development-intercept-workflow.mmd b/docs/diagrams/architecture/development-intercept-workflow.mmd deleted file mode 100644 index ec78ee72..00000000 --- a/docs/diagrams/architecture/development-intercept-workflow.mmd +++ /dev/null @@ -1,30 +0,0 @@ -sequenceDiagram - participant Dev as Developer - participant Intercept as Intercept Service - participant Kubectl as Kubectl Provider - participant Telepresence as Telepresence Provider - participant K8s as Kubernetes - participant Local as Local Development - - Dev->>Intercept: openframe dev intercept - Intercept->>Kubectl: Get services - Kubectl->>K8s: List services - K8s-->>Kubectl: Service list - Kubectl-->>Intercept: Available services - Intercept->>Dev: Select service/port - Dev->>Intercept: Service selection - - Intercept->>Telepresence: Setup intercept - Telepresence->>K8s: Create intercept - K8s->>Telepresence: Traffic routing active - Telepresence->>Local: Forward traffic - Local->>Dev: Local debugging - - Note over Dev,Local: Development session active - - Dev->>Intercept: Stop intercept (Ctrl+C) - Intercept->>Telepresence: Cleanup intercept - Telepresence->>K8s: Remove routing - K8s-->>Telepresence: Cleanup complete - Telepresence-->>Intercept: Disconnected - Intercept-->>Dev: Session ended diff --git a/docs/diagrams/architecture/high-level-architecture-diagram.mmd b/docs/diagrams/architecture/high-level-architecture-diagram.mmd new file mode 100644 index 00000000..df0419cb --- /dev/null +++ b/docs/diagrams/architecture/high-level-architecture-diagram.mmd @@ -0,0 +1,87 @@ +graph TD + subgraph CLI["CLI Entry Layer (cmd/)"] + Root["Root Command"] + Bootstrap["bootstrap"] + Cluster["cluster"] + Chart["chart"] + Dev["dev"] + end + + subgraph Services["Service Layer (internal/)"] + BootstrapSvc["Bootstrap Service"] + ClusterSvc["Cluster Service"] + ChartSvc["Chart Service"] + DevSvc["Dev Services"] + end + + subgraph Providers["Provider Layer"] + K3D["K3D Manager"] + HelmMgr["Helm Manager"] + ArgoCDMgr["ArgoCD Manager"] + GitRepo["Git Repository"] + KubectlProv["Kubectl Provider"] + TelepresenceProv["Telepresence Provider"] + end + + subgraph Infra["Shared Infrastructure"] + Executor["Command Executor"] + UIShared["Shared UI"] + ErrorsShared["Error Handling"] + ConfigShared["Config / Paths"] + FilesShared["File Cleanup"] + end + + subgraph External["External Systems"] + K3dBin["k3d binary"] + HelmBin["helm binary"] + ArgoCDAPI["ArgoCD Kubernetes API"] + GitHubRepo["GitHub Repository"] + K8sAPI["Kubernetes API"] + TelepresenceBin["telepresence binary"] + SkaffoldBin["skaffold binary"] + end + + Root --> Bootstrap + Root --> Cluster + Root --> Chart + Root --> Dev + + Bootstrap --> BootstrapSvc + Cluster --> ClusterSvc + Chart --> ChartSvc + Dev --> DevSvc + + BootstrapSvc --> ClusterSvc + BootstrapSvc --> ChartSvc + + ClusterSvc --> K3D + ChartSvc --> HelmMgr + ChartSvc --> ArgoCDMgr + ChartSvc --> GitRepo + DevSvc --> KubectlProv + DevSvc --> TelepresenceProv + + K3D --> Executor + HelmMgr --> Executor + ArgoCDMgr --> K8sAPI + GitRepo --> Executor + KubectlProv --> Executor + TelepresenceProv --> Executor + + Executor --> K3dBin + Executor --> HelmBin + Executor --> TelepresenceBin + Executor --> SkaffoldBin + HelmMgr --> ArgoCDAPI + ArgoCDMgr --> ArgoCDAPI + GitRepo --> GitHubRepo + KubectlProv --> K8sAPI + + ClusterSvc --> UIShared + ChartSvc --> UIShared + DevSvc --> UIShared + ClusterSvc --> ErrorsShared + ChartSvc --> ErrorsShared + ClusterSvc --> ConfigShared + ChartSvc --> ConfigShared + ChartSvc --> FilesShared diff --git a/docs/diagrams/architecture/high-level-system-design.mmd b/docs/diagrams/architecture/high-level-system-design.mmd deleted file mode 100644 index 7f3080f4..00000000 --- a/docs/diagrams/architecture/high-level-system-design.mmd +++ /dev/null @@ -1,56 +0,0 @@ -graph TB - subgraph "CLI Layer" - Root[Root Command] - Bootstrap[Bootstrap Command] - Cluster[Cluster Commands] - Chart[Chart Commands] - Dev[Dev Commands] - end - - subgraph "Service Layer" - ClusterSvc[Cluster Service] - ChartSvc[Chart Service] - InterceptSvc[Intercept Service] - ScaffoldSvc[Scaffold Service] - end - - subgraph "Provider Layer" - K3D[K3D Provider] - Helm[Helm Provider] - ArgoCD[ArgoCD Provider] - Telepresence[Telepresence Provider] - Kubectl[Kubectl Provider] - end - - subgraph "External Systems" - Docker[Docker] - K8s[Kubernetes] - Git[Git Repositories] - Registry[Container Registry] - end - - Root --> Bootstrap - Root --> Cluster - Root --> Chart - Root --> Dev - - Bootstrap --> ClusterSvc - Bootstrap --> ChartSvc - Cluster --> ClusterSvc - Chart --> ChartSvc - Dev --> InterceptSvc - Dev --> ScaffoldSvc - - ClusterSvc --> K3D - ChartSvc --> Helm - ChartSvc --> ArgoCD - InterceptSvc --> Telepresence - InterceptSvc --> Kubectl - ScaffoldSvc --> Kubectl - - K3D --> Docker - Helm --> K8s - ArgoCD --> K8s - ArgoCD --> Git - Telepresence --> K8s - Kubectl --> K8s diff --git a/docs/diagrams/architecture/interactive-intercept-dev-workflow.mmd b/docs/diagrams/architecture/interactive-intercept-dev-workflow.mmd new file mode 100644 index 00000000..1ccedda8 --- /dev/null +++ b/docs/diagrams/architecture/interactive-intercept-dev-workflow.mmd @@ -0,0 +1,45 @@ +sequenceDiagram + participant User + participant DevCmd as "dev intercept cmd" + participant ClusterSvc as "Cluster Service" + participant KubectlProv as "Kubectl Provider" + participant InterceptUI as "Intercept UI" + participant InterceptSvc as "Intercept Service" + participant Telepresence as "Telepresence Binary" + participant K8sAPI as "Kubernetes API" + + User->>DevCmd: openframe dev intercept + DevCmd->>ClusterSvc: ListClusters() + ClusterSvc-->>DevCmd: clusters[] + DevCmd->>User: Select cluster (interactive) + User-->>DevCmd: cluster selected + + DevCmd->>KubectlProv: kubectl config use-context k3d-[name] + DevCmd->>KubectlProv: CheckConnection(ctx) + KubectlProv->>K8sAPI: kubectl cluster-info + K8sAPI-->>KubectlProv: OK + + DevCmd->>InterceptUI: InteractiveInterceptSetup(ctx) + InterceptUI->>KubectlProv: GetNamespaces(ctx) + KubectlProv->>K8sAPI: kubectl get namespaces -o json + K8sAPI-->>KubectlProv: namespace list + InterceptUI->>User: Enter service name + User-->>InterceptUI: service name + + InterceptUI->>KubectlProv: GetService(ctx, namespace, serviceName) + KubectlProv->>K8sAPI: kubectl get service -o json + K8sAPI-->>KubectlProv: ServiceInfo{ports} + InterceptUI->>User: Select Kubernetes port + InterceptUI->>User: Enter local port + User-->>InterceptUI: setup complete + + DevCmd->>InterceptSvc: StartIntercept(serviceName, flags) + InterceptSvc->>Telepresence: telepresence connect + InterceptSvc->>Telepresence: telepresence intercept [svc] --port local:remote + Telepresence-->>InterceptSvc: intercept active + + InterceptSvc->>InterceptSvc: Wait for OS signal (Ctrl+C) + User->>InterceptSvc: Ctrl+C + InterceptSvc->>Telepresence: telepresence leave [svc] + InterceptSvc->>Telepresence: telepresence quit + InterceptSvc-->>User: Intercept stopped diff --git a/docs/getting-started/first-steps.md b/docs/getting-started/first-steps.md index 24c144d6..3242d28a 100644 --- a/docs/getting-started/first-steps.md +++ b/docs/getting-started/first-steps.md @@ -1,467 +1,200 @@ -# First Steps with OpenFrame CLI +# First Steps -Now that you have OpenFrame CLI installed and your first environment bootstrapped, let's explore the key features and workflows. This guide covers the essential first steps to get you productive with OpenFrame. +You've bootstrapped your first OpenFrame environment — here's what to do next to explore its key capabilities. -## Your First 5 Actions +[![OpenFrame Product Walkthrough (Beta Access)](https://img.youtube.com/vi/awc-yAnkhIo/maxresdefault.jpg)](https://www.youtube.com/watch?v=awc-yAnkhIo) -### 1. Explore the CLI Structure +--- + +## Step 1 — Verify Your Cluster -Get familiar with the command hierarchy: +Start by confirming your cluster is healthy and all applications are in sync. ```bash -# See all available commands -openframe --help - -# Explore each command group -openframe cluster --help -openframe chart --help -openframe dev --help -openframe bootstrap --help -``` +# List all managed clusters +openframe cluster list -The CLI is organized into logical groups: -- **bootstrap**: One-time environment setup -- **cluster**: Kubernetes cluster lifecycle -- **chart**: Application and service deployment -- **dev**: Development and debugging tools +# Get detailed status of your cluster +openframe cluster status my-cluster -### 2. Check Your Environment Status +# Confirm all pods are running +kubectl get pods -A +``` -Verify everything is running correctly: +You should see your K3D cluster in `running` state and all ArgoCD-managed pods in the `Running` or `Completed` state. -```bash -# Overall cluster health -openframe cluster status +--- -# List all running clusters -openframe cluster list +## Step 2 — Explore the Cluster Commands -# Check installed charts and applications -openframe chart list -``` +The `cluster` command group (alias `k`) manages your K3D cluster lifecycle: -Expected healthy output: -```text -📊 Cluster Status: openframe-local -✅ Cluster is running -✅ ArgoCD is healthy -✅ All core services operational -``` +```bash +# Create a new cluster interactively +openframe cluster create -### 3. Access the ArgoCD Dashboard +# Create a named cluster with defaults +openframe cluster create my-dev-cluster -ArgoCD provides a web interface for GitOps deployments: +# List all clusters +openframe cluster list -```bash -# Get admin password -kubectl -n argocd get secret argocd-initial-admin-secret \ - -o jsonpath="{.data.password}" | base64 -d; echo +# Get status of a specific cluster +openframe cluster status my-dev-cluster -# Port forward to access UI -kubectl port-forward svc/argocd-server -n argocd 8080:443 +# Clean up unused resources +openframe cluster cleanup -# Open in browser: https://localhost:8080 -# Username: admin -# Password: (from command above) +# Delete a cluster +openframe cluster delete my-dev-cluster ``` -In the ArgoCD UI, you'll see: -- **Applications**: Deployed services and components -- **Repositories**: Connected Git repositories -- **Settings**: Configuration and policies -- **User Info**: Access controls and authentication +> **Tip:** Use the short alias `openframe k` instead of `openframe cluster` to save keystrokes. -### 4. Deploy Your First Application +--- -Let's deploy a simple application to test the workflow: +## Step 3 — Explore the Chart Commands -```bash -# Create a test namespace -kubectl create namespace hello-world - -# Deploy a sample application -kubectl apply -f - <> ~/.bashrc << 'EOF' -# OpenFrame aliases -alias of="openframe" -alias ofcs="openframe cluster status" -alias ofcl="openframe cluster list" -alias k="kubectl" -alias kgp="kubectl get pods" -alias kgs="kubectl get svc" -alias kgn="kubectl get nodes" -EOF - -# Reload shell configuration -source ~/.bashrc -``` +## Step 4 — Set Up a Local Development Intercept -## Key Workflows to Learn - -### Cluster Management Workflow - -```mermaid -flowchart TD - A[Create Cluster] --> B[Check Status] - B --> C[Deploy Applications] - C --> D[Monitor Health] - D --> E{Issues?} - E -->|Yes| F[Debug & Fix] - E -->|No| G[Continue Development] - F --> D - G --> H[Scale or Update] - H --> D -``` +The `dev intercept` command lets you route live Kubernetes traffic for a specific service to your local machine. This is the fastest way to develop and debug a service without rebuilding containers. -#### Common Cluster Commands ```bash -# Create a new cluster -openframe cluster create my-new-cluster +# Interactive intercept setup (recommended for first time) +openframe dev intercept -# List all clusters -openframe cluster list - -# Get detailed status -openframe cluster status my-cluster +# The wizard will guide you through: +# 1. Select which cluster to work with +# 2. Choose a namespace +# 3. Enter the service name to intercept +# 4. Choose the Kubernetes port +# 5. Enter your local port -# Delete a cluster -openframe cluster delete my-cluster - -# Clean up resources -openframe cluster cleanup +# Or use flags directly +openframe dev intercept my-api-service \ + --port 8080 \ + --namespace development ``` -### Application Deployment Workflow - -```mermaid -sequenceDiagram - participant Dev as Developer - participant CLI as OpenFrame CLI - participant ArgoCD as ArgoCD - participant K8s as Kubernetes - - Dev->>CLI: openframe chart install - CLI->>ArgoCD: Create Application - ArgoCD->>K8s: Deploy Resources - K8s-->>ArgoCD: Resource Status - ArgoCD-->>CLI: Sync Status - CLI-->>Dev: Deployment Complete -``` +When the intercept is active, any traffic hitting `my-api-service` in the cluster is forwarded to your local port `8080`. Press `Ctrl+C` to stop and cleanly disconnect. -#### Common Chart Commands -```bash -# Install a chart from repository -openframe chart install my-app \ - --repo=https://github.com/my-org/my-app \ - --path=charts/my-app - -# List installed applications -openframe chart list - -# Check application sync status -kubectl get applications -n argocd - -# Manually sync an application -kubectl patch application my-app -n argocd \ - --type=json \ - -p='[{"op": "replace", "path": "/spec/syncPolicy", "value": {"automated": {"selfHeal": true}}}]' -``` +--- -### Development Workflow +## Step 5 — Run a Skaffold Dev Session -For local development with live Kubernetes integration: +For a full hot-reload development loop, use the `dev skaffold` command: ```bash -# Start a development intercept -openframe dev intercept my-service \ - --namespace=default \ - --port=3000:8080 - -# Generate scaffold for new service -openframe dev scaffold my-new-service \ - --template=microservice \ - --language=go +# Discover skaffold.yaml and start a dev session +openframe dev skaffold + +# Target a specific cluster +openframe dev skaffold my-cluster ``` -## Essential Configuration +This command: +1. Discovers `skaffold.yaml` files in your project +2. Optionally bootstraps a fresh cluster if needed +3. Runs `skaffold dev` with live rebuild-on-change -### Customize OpenFrame Settings +--- -Create a configuration file for personalized settings: +## Quick Reference — All Top-Level Commands ```bash -mkdir -p ~/.openframe -cat > ~/.openframe/config.yaml << 'EOF' -# OpenFrame CLI Configuration -default: - cluster_name: "openframe-local" - namespace: "default" - log_level: "info" - -bootstrap: - mode: "oss-tenant" - interactive: true - timeout: "15m" - -cluster: - provider: "k3d" - nodes: 1 - -chart: - timeout: "10m" - wait: true - -dev: - intercept_timeout: "5m" - scaffold_templates_dir: "~/.openframe/templates" -EOF -``` - -### Configure Git Integration +# Show the help menu and OpenFrame logo +openframe -For ArgoCD to access your repositories: +# Get help for any command +openframe [command] --help -```bash -# Add a Git repository to ArgoCD -kubectl apply -f - < - username: -EOF +# Show version +openframe --version ``` -### Set Up Ingress (Optional) +| Command | Alias | Description | +|---------|-------|-------------| +| `openframe bootstrap` | — | Full one-shot setup (cluster + charts) | +| `openframe cluster` | `k` | Cluster lifecycle management | +| `openframe chart` | `c` | Helm chart and ArgoCD management | +| `openframe dev` | `d` | Local development workflows | -Configure Traefik ingress for external access: +--- -```bash -# Create an ingress for your application -kubectl apply -f - < -n +### Silent Mode -# Check logs -kubectl logs -n +Use `--silent` to suppress all output except errors — useful for scripting: -# Check resource constraints -kubectl get resourcequota -n +```bash +openframe cluster create my-cluster --silent ``` -#### Service Not Accessible -```bash -# Check service endpoints -kubectl get endpoints -n +### Using Global Flags -# Test internal connectivity -kubectl run test-pod --image=busybox -it --rm -- sh -# Inside pod: -wget -q -O- http://..svc.cluster.local -``` +Global flags apply to all commands: -#### ArgoCD Application Not Syncing ```bash -# Check application status -kubectl get application -n argocd -o yaml - -# Force refresh -kubectl patch application -n argocd \ - --type=json \ - -p='[{"op": "replace", "path": "/spec/source/targetRevision", "value": "HEAD"}]' - -# Manual sync -kubectl patch application -n argocd \ - --type=json \ - -p='[{"op": "add", "path": "/metadata/annotations/argocd.argoproj.io~1sync", "value": ""}]' +openframe --verbose cluster create my-cluster +openframe --silent chart install --deployment-mode=oss-tenant ``` -## Best Practices - -### Development Environment -1. **Use namespaces**: Organize applications by environment or team -2. **Resource limits**: Set appropriate CPU/memory limits -3. **Health checks**: Implement liveness and readiness probes -4. **Secrets management**: Use Kubernetes secrets, not hardcoded values - -### GitOps Workflow -1. **Infrastructure as Code**: Store all configurations in Git -2. **Automated sync**: Enable ArgoCD auto-sync for non-production -3. **Manual approval**: Require manual sync for production deployments -4. **Rollback strategy**: Use Git reverts for quick rollbacks - -### Cluster Management -1. **Regular backups**: Backup cluster state and data -2. **Monitor resources**: Set up alerts for resource usage -3. **Update strategy**: Plan regular updates for cluster components -4. **Security scanning**: Regularly scan images and configurations - -## Next Steps - -Now that you're familiar with OpenFrame basics, explore advanced topics: +--- -### Development Workflows -Learn how to set up a complete development environment: -- Configure your IDE and editor -- Set up local development workflows -- Use service intercepts for debugging +## Explore the Configuration Wizard -### Architecture Understanding -Dive deeper into how OpenFrame components work: -- Study the service architecture -- Understand data flows and dependencies -- Learn about security models and best practices +When you run `openframe chart install` or `openframe bootstrap` without `--non-interactive`, the CLI launches a multi-step configuration wizard covering: -### Advanced Deployment Patterns -Master sophisticated deployment strategies: -- Blue/green deployments -- Canary releases -- Multi-environment promotion pipelines +1. **Deployment Mode** — Select `oss-tenant`, `saas-tenant`, or `saas-shared` +2. **Git Branch** — Choose which branch of the OpenFrame chart repo to deploy +3. **Docker Registry** — Configure container image source (GHCR or custom registry) +4. **Ingress** — Set domain and ingress routing configuration +5. **SaaS Credentials** — Provide API tokens if using SaaS mode -## Getting Help +--- -### Community Resources -- **OpenMSP Slack**: [Join the community](https://join.slack.com/t/openmsp/shared_invite/zt-36bl7mx0h-3~U2nFH6nqHqoTPXMaHEHA) for questions and support -- **Documentation**: Explore other guides in this repository -- **Examples**: Check the examples directory for sample configurations +## Where to Get Help -### Useful Commands Reference -```bash -# Quick status check -openframe cluster status +If you run into issues or have questions: -# View all resources -kubectl get all --all-namespaces +- **OpenMSP Community Slack:** The primary support channel — [Join here](https://join.slack.com/t/openmsp/shared_invite/zt-36bl7mx0h-3~U2nFH6nqHqoTPXMaHEHA) +- **OpenMSP Website:** [https://www.openmsp.ai/](https://www.openmsp.ai/) +- **OpenFrame Platform:** [https://openframe.ai](https://openframe.ai) -# Emergency cluster reset -openframe cluster delete -openframe bootstrap +> All bug reports, feature requests, and community discussions happen in the OpenMSP Slack — not GitHub Issues or GitHub Discussions. -# Export current configuration -kubectl get all -o yaml > backup.yaml +--- -# View OpenFrame CLI logs -openframe --verbose -``` +## What's Next? -### Debugging Resources -- ArgoCD UI: https://localhost:8080 (after port forward) -- Traefik Dashboard: https://localhost:9000 (after port forward) -- Kubernetes Dashboard: Install with `kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml` +Now that you're familiar with the basics: -You're now ready to be productive with OpenFrame CLI! Explore the features, experiment with deployments, and join the community for support and sharing experiences. \ No newline at end of file +- Explore the [architecture documentation](../development/architecture/README.md) to understand how the CLI is structured +- Set up your [development environment](../development/setup/environment.md) to contribute to OpenFrame CLI +- Review [security best practices](../development/security/README.md) before deploying to production diff --git a/docs/getting-started/introduction.md b/docs/getting-started/introduction.md index 2c2771af..28a59d6a 100644 --- a/docs/getting-started/introduction.md +++ b/docs/getting-started/introduction.md @@ -1,142 +1,146 @@ # Introduction to OpenFrame CLI -OpenFrame CLI is a modern, interactive command-line tool for managing OpenFrame Kubernetes clusters and development workflows. It provides seamless cluster lifecycle management, chart installation with ArgoCD, and developer-friendly tools for service intercepts and scaffolding. - -[![OpenFrame Product Walkthrough (Beta Access)](https://img.youtube.com/vi/awc-yAnkhIo/maxresdefault.jpg)](https://www.youtube.com/watch?v=awc-yAnkhIo) +[![Getting Started with OpenFrame - Organization Setup Basics](https://img.youtube.com/vi/-_56_qYvMWk/maxresdefault.jpg)](https://www.youtube.com/watch?v=-_56_qYvMWk) ## What is OpenFrame CLI? -OpenFrame CLI is part of the broader OpenFrame ecosystem - an AI-powered MSP platform that replaces expensive proprietary software with open-source alternatives enhanced by intelligent automation. The CLI serves as the entry point for developers and operators to bootstrap, manage, and develop on OpenFrame environments. +**OpenFrame CLI** is a modern, interactive command-line tool written in Go for bootstrapping and managing OpenFrame Kubernetes environments. It is the primary developer-facing entry point to the broader [OpenFrame](https://openframe.ai) AI-powered MSP platform — replacing brittle shell scripts with a wizard-style terminal interface that guides you through every step of your environment lifecycle. + +From a single command you can spin up a fully operational local Kubernetes cluster, install ArgoCD, deploy the complete OpenFrame application stack via the App-of-Apps pattern, and begin intercepting live cluster traffic in your local IDE — all without memorizing dozens of manual steps. + +> **Platform context:** OpenFrame is part of the [Flamingo](https://flamingo.run) ecosystem — an AI-powered MSP platform that replaces expensive proprietary software with open-source alternatives enhanced by intelligent automation (Mingo AI for technicians, Fae for clients). + +--- ## Key Features -### 🚀 Complete Environment Bootstrapping -- **One-command setup**: Bootstrap entire OpenFrame environments with `openframe bootstrap` -- **Multi-mode deployment**: Support for OSS tenant, SaaS tenant, and SaaS shared modes -- **Automated cluster creation**: Creates K3D clusters with all necessary components -- **ArgoCD integration**: Automatic chart installation and application management - -### 🔧 Cluster Management -- **Lifecycle operations**: Create, delete, list, and monitor Kubernetes clusters -- **K3D integration**: Lightweight Kubernetes for development and testing -- **Status monitoring**: Real-time cluster health and resource monitoring -- **Easy cleanup**: Remove clusters and associated resources with simple commands - -### 📦 Chart & Application Management -- **Helm chart installation**: Streamlined chart deployment with dependency management -- **ArgoCD applications**: GitOps-based application lifecycle management -- **App-of-apps pattern**: Hierarchical application management for complex deployments -- **Synchronization monitoring**: Track deployment progress with detailed logging - -### 🛠 Development Tools -- **Service intercepts**: Local development with Telepresence integration -- **Scaffolding**: Generate boilerplate code and configurations -- **Live debugging**: Debug services running in Kubernetes from your local environment -- **Hot reload**: Rapid development cycles with instant feedback +| Feature | Description | +|---------|-------------| +| **One-Command Bootstrap** | `openframe bootstrap` creates a K3D cluster, installs ArgoCD, and deploys the full stack in one shot | +| **Interactive Wizard UI** | Step-by-step guided prompts for cluster names, deployment modes, ingress, and Docker registry settings | +| **Cluster Lifecycle Management** | Create, delete, list, check status, and clean up K3D clusters | +| **Helm & ArgoCD Integration** | Installs ArgoCD via Helm and waits for all Application CRDs to reach Healthy+Synced state | +| **Local Dev Workflows** | Telepresence-based service intercepts route live cluster traffic to your local process | +| **Skaffold Hot Reload** | `openframe dev skaffold` discovers `skaffold.yaml` files and starts live-reload dev sessions | +| **Prerequisite Checking** | Validates Docker, k3d, kubectl, helm, git, and mkcert before any operation | +| **Cross-Platform** | Full Linux, macOS, and Windows (WSL2) support with native path handling | +| **CI/CD Friendly** | `--non-interactive` and `--deployment-mode` flags for fully automated pipelines | + +--- ## Target Audience -### DevOps Engineers -- Simplify Kubernetes cluster management -- Automate deployment pipelines with GitOps -- Monitor and maintain OpenFrame environments - -### Software Developers -- Develop and test microservices locally -- Debug applications running in Kubernetes -- Scaffold new services and components quickly +OpenFrame CLI is designed for: -### System Administrators -- Bootstrap complete OpenFrame environments -- Manage multiple clusters and deployments -- Monitor system health and performance +- **Platform Engineers** setting up OpenFrame environments for their MSP organization +- **Application Developers** who need a local Kubernetes stack with live traffic intercepts for service development +- **DevOps/CI Engineers** automating environment provisioning in pipelines +- **MSP Operators** evaluating the OpenFrame OSS tenant deployment -### MSP Teams -- Deploy OpenFrame for multiple tenants -- Manage client environments efficiently -- Reduce vendor costs with open-source alternatives +--- ## Architecture Overview ```mermaid -graph TB - subgraph "CLI Commands" - Bootstrap[openframe bootstrap] - Cluster[openframe cluster] - Chart[openframe chart] - Dev[openframe dev] +graph TD + subgraph CLI["CLI Entry Layer (cmd/)"] + Root["Root Command (openframe)"] + Bootstrap["bootstrap"] + Cluster["cluster"] + Chart["chart"] + Dev["dev"] end - - subgraph "Core Services" - ClusterSvc[Cluster Management] - ChartSvc[Chart Installation] - DevSvc[Development Tools] + + subgraph Services["Service Layer (internal/)"] + BootstrapSvc["Bootstrap Service"] + ClusterSvc["Cluster Service"] + ChartSvc["Chart Service"] + DevSvc["Dev Services"] end - - subgraph "External Tools" - K3D[K3D Clusters] - Helm[Helm Charts] - ArgoCD[ArgoCD Apps] - Telepresence[Service Intercepts] + + subgraph Providers["Provider Layer"] + K3D["K3D Manager"] + HelmMgr["Helm Manager"] + ArgoCDMgr["ArgoCD Manager"] + GitRepo["Git Repository"] + TelepresenceProv["Telepresence Provider"] end - - subgraph "Target Environment" - K8s[Kubernetes] - Apps[Applications] - Services[Microservices] + + subgraph External["External Systems"] + K3dBin["k3d binary"] + HelmBin["helm binary"] + ArgoCDAPI["ArgoCD Kubernetes API"] + GitHubRepo["GitHub Repository"] + K8sAPI["Kubernetes API"] + TelepresenceBin["telepresence binary"] end - - Bootstrap --> ClusterSvc - Bootstrap --> ChartSvc + + Root --> Bootstrap + Root --> Cluster + Root --> Chart + Root --> Dev + + Bootstrap --> BootstrapSvc Cluster --> ClusterSvc Chart --> ChartSvc Dev --> DevSvc - + + BootstrapSvc --> ClusterSvc + BootstrapSvc --> ChartSvc + ClusterSvc --> K3D - ChartSvc --> Helm - ChartSvc --> ArgoCD - DevSvc --> Telepresence - - K3D --> K8s - Helm --> Apps - ArgoCD --> Apps - Telepresence --> Services + ChartSvc --> HelmMgr + ChartSvc --> ArgoCDMgr + ChartSvc --> GitRepo + DevSvc --> TelepresenceProv + + K3D --> K3dBin + HelmMgr --> HelmBin + HelmMgr --> ArgoCDAPI + ArgoCDMgr --> K8sAPI + GitRepo --> GitHubRepo + TelepresenceProv --> TelepresenceBin ``` -## Key Benefits +--- -| Benefit | Description | -|---------|-------------| -| **Rapid Setup** | Go from zero to running OpenFrame environment in minutes | -| **Developer Friendly** | Interactive prompts, helpful error messages, and clear documentation | -| **Production Ready** | Battle-tested components with enterprise-grade reliability | -| **Open Source** | Complete transparency, community-driven development | -| **Cost Effective** | Replace expensive proprietary tools with open-source alternatives | -| **GitOps Native** | Built-in ArgoCD integration for modern deployment practices | +## Command Summary + +| Command | Alias | What It Does | +|---------|-------|--------------| +| `openframe bootstrap` | — | Full one-shot environment setup (cluster + charts) | +| `openframe cluster` | `k` | Manage K3D cluster lifecycle (create/delete/list/status/cleanup) | +| `openframe chart` | `c` | Manage Helm charts and ArgoCD installations | +| `openframe dev intercept` | — | Route live Kubernetes traffic to your local dev process | +| `openframe dev skaffold` | — | Run live hot-reload dev sessions with Skaffold | + +--- -## How It Works +## Deployment Modes -1. **Bootstrap**: Run `openframe bootstrap` to create a complete environment -2. **Develop**: Use `openframe dev` commands for local development workflows -3. **Deploy**: Manage applications with `openframe chart` commands -4. **Monitor**: Check cluster status with `openframe cluster` commands +OpenFrame CLI supports three deployment modes selectable during bootstrap or chart installation: -The CLI handles all the complexity of Kubernetes cluster management, chart installations, and development tool configuration, allowing you to focus on building and deploying applications. +| Mode | Description | +|------|-------------| +| `oss-tenant` | Open-source self-hosted tenant deployment | +| `saas-tenant` | SaaS tenant deployment with dedicated resources | +| `saas-shared` | SaaS shared infrastructure deployment | -## Next Steps +--- -Ready to get started? Continue with these guides: +## Get Started -- **[Prerequisites](prerequisites.md)** - Check system requirements and install dependencies -- **[Quick Start](quick-start.md)** - Get OpenFrame running in 5 minutes -- **[First Steps](first-steps.md)** - Explore key features and workflows +Ready to jump in? Here are your next steps: -## Community and Support +1. Review the **[Prerequisites Guide](prerequisites.md)** to verify your system is ready +2. Follow the **[Quick Start Guide](quick-start.md)** for a 5-minute environment setup +3. Read **[First Steps](first-steps.md)** to explore key features after installation -OpenFrame is built by the community for the community. Get help and connect with other users: +--- -- **OpenMSP Slack**: [Join the community](https://join.slack.com/t/openmsp/shared_invite/zt-36bl7mx0h-3~U2nFH6nqHqoTPXMaHEHA) -- **Website**: [https://flamingo.run](https://flamingo.run) -- **OpenFrame Platform**: [https://openframe.ai](https://openframe.ai) +## Community & Support -> **Note**: We don't use GitHub Issues or Discussions - all support and community interaction happens in the OpenMSP Slack community. \ No newline at end of file +- **OpenMSP Community Slack:** [Join here](https://join.slack.com/t/openmsp/shared_invite/zt-36bl7mx0h-3~U2nFH6nqHqoTPXMaHEHA) — all issues, discussions, and feature requests are managed here +- **OpenMSP Website:** [https://www.openmsp.ai/](https://www.openmsp.ai/) +- **OpenFrame Platform:** [https://openframe.ai](https://openframe.ai) +- **Flamingo Platform:** [https://flamingo.run](https://flamingo.run) diff --git a/docs/getting-started/prerequisites.md b/docs/getting-started/prerequisites.md index 314e0978..237904e7 100644 --- a/docs/getting-started/prerequisites.md +++ b/docs/getting-started/prerequisites.md @@ -1,315 +1,216 @@ # Prerequisites -Before installing and using OpenFrame CLI, ensure your system meets the following requirements and has the necessary dependencies installed. +Before you can run OpenFrame CLI, you need several tools installed and configured on your system. The CLI validates these prerequisites automatically before any operation — if something is missing it will tell you exactly how to install it. + +--- ## System Requirements -### Hardware Requirements +| Tier | RAM | CPU Cores | Disk Space | +|------|-----|-----------|------------| +| **Minimum** | 24 GB | 6 cores | 50 GB | +| **Recommended** | 32 GB | 12 cores | 100 GB | -| Resource | Minimum | Recommended | -|----------|---------|-------------| -| **RAM** | 24GB | 32GB | -| **CPU Cores** | 6 cores | 12 cores | -| **Disk Space** | 50GB free | 100GB free | -| **Architecture** | x86_64, ARM64 | x86_64, ARM64 | +> **Note:** Running a full K3D-based Kubernetes stack with ArgoCD and the OpenFrame application suite is memory-intensive. The minimum specs will work for single-service development, but the recommended specs are required for stable full-stack operation. -### Operating System Support +--- -| OS | Version | Status | -|---|---------|--------| -| **Linux** | Ubuntu 20.04+, CentOS 8+, RHEL 8+ | ✅ Fully Supported | -| **macOS** | 11+ (Big Sur and later) | ✅ Fully Supported | -| **Windows** | Windows 10/11 with WSL2 | ⚠️ Supported via WSL2 | +## Required Software -> **Windows Users**: OpenFrame CLI requires WSL2 for proper Kubernetes integration. Native Windows support is not currently available. +All of the following tools must be installed before the CLI can run. The prerequisite checker validates each one at startup. -## Required Dependencies +| Tool | Minimum Version | Purpose | Check Command | +|------|----------------|---------|---------------| +| **Go** | 1.21+ | Build the CLI from source (if not using a binary release) | `go version` | +| **Docker** | 20.10+ | Runs the K3D container nodes; daemon must be running | `docker info` | +| **k3d** | 5.x | Creates and manages K3D (K3s-in-Docker) clusters | `k3d version` | +| **kubectl** | 1.25+ | Interacts with Kubernetes clusters | `kubectl version --client` | +| **Helm** | 3.x | Installs ArgoCD and app-of-apps charts | `helm version` | +| **Git** | 2.x | Clones the app-of-apps chart repository from GitHub | `git --version` | +| **mkcert** | 1.4+ | Generates locally-trusted TLS certificates for ingress | `mkcert --version` | -### Core Dependencies +### For Development Workflows (Optional) -These tools must be installed before using OpenFrame CLI: +These are only required when using `openframe dev` commands: -| Tool | Version | Purpose | Installation | -|------|---------|---------|--------------| -| **Docker** | 20.10+ | Container runtime for K3D clusters | [Docker Install Guide](https://docs.docker.com/get-docker/) | -| **kubectl** | 1.25+ | Kubernetes command-line tool | [kubectl Install Guide](https://kubernetes.io/docs/tasks/tools/) | -| **Helm** | 3.10+ | Kubernetes package manager | [Helm Install Guide](https://helm.sh/docs/intro/install/) | -| **K3D** | 5.0+ | Lightweight Kubernetes clusters | [K3D Install Guide](https://k3d.io/v5.4.6/#installation) | +| Tool | Purpose | Check Command | +|------|---------|---------------| +| **Telepresence** | 2.x | Routes live Kubernetes traffic to local processes | `telepresence version` | +| **Skaffold** | Latest | Hot-reload development sessions | `skaffold version` | +| **jq** | 1.6+ | JSON processing used by intercept workflows | `jq --version` | -### Development Dependencies (Optional) +--- -Required only if using development features (`openframe dev` commands): +## Platform-Specific Requirements -| Tool | Version | Purpose | Installation | -|------|---------|---------|--------------| -| **Telepresence** | 2.10+ | Service intercepts for local development | [Telepresence Install](https://www.telepresence.io/docs/latest/install/) | -| **jq** | 1.6+ | JSON processing for dev scripts | [jq Install Guide](https://jqlang.github.io/jq/download/) | +### Linux / macOS -## Installation Verification +No additional requirements. Ensure Docker Desktop (macOS) or Docker Engine (Linux) is running before invoking the CLI. -### Check Docker -```bash -docker --version -docker ps -``` +### Windows (WSL2) -Expected output: -```text -Docker version 20.10.0 or higher -CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -``` +OpenFrame CLI supports Windows via WSL2. The following additional setup is needed: -### Check kubectl -```bash -kubectl version --client -``` +1. **WSL2 enabled** with an Ubuntu distribution installed +2. **Docker Desktop** configured with WSL2 backend enabled +3. All tools above installed **inside WSL2** (not the native Windows environment) -Expected output: -```text -Client Version: version.Info{Major:"1", Minor:"25"+...} -``` +> **Windows users:** The CLI auto-detects WSL2 and wraps commands appropriately. Run `openframe` from within your WSL2 terminal session. -### Check Helm -```bash -helm version -``` +--- -Expected output: -```text -version.BuildInfo{Version:"v3.10.0"+...} -``` +## Environment Variables + +The following environment variables affect CLI behavior. None are required for basic operation, but may be needed in specific setups: + +| Variable | Description | Default | +|----------|-------------|---------| +| `KUBECONFIG` | Path to kubeconfig file | `~/.kube/config` | +| `OPENFRAME_VERBOSE` | Enable verbose output globally | `false` | +| `CI` | Disables interactive prompts in CI mode | unset | + +> When `CI` is set (to any value), the CLI switches to non-interactive mode and skips prompts that require keyboard input. + +--- + +## Account & Access Requirements + +### GitHub Access + +The CLI clones the OpenFrame app-of-apps Helm chart from a GitHub repository during `chart install` and `bootstrap`. You need: + +- Network access to `github.com` +- If using a private repository: a valid GitHub token or SSH key configured + +### Container Registry Access + +For custom deployments using `saas-tenant` or `saas-shared` mode, you may need credentials for: + +- **GitHub Container Registry (GHCR):** `ghcr.io` +- **Custom Docker registry:** configured during the installation wizard + +--- + +## Verification Commands + +Run the following to confirm all prerequisites are installed and working: -### Check K3D ```bash +# Verify Go installation +go version + +# Verify Docker is installed and daemon is running +docker info + +# Verify k3d k3d version -``` -Expected output: -```text -k3d version v5.0.0+ -``` +# Verify kubectl +kubectl version --client -### Check Telepresence (Optional) -```bash -telepresence version -``` +# Verify Helm +helm version -Expected output: -```text -Client: v2.10.0+ -``` +# Verify Git +git --version -### Check jq (Optional) -```bash +# Verify mkcert +mkcert --version + +# Optional: dev workflow tools +telepresence version +skaffold version jq --version ``` -Expected output: -```text -jq-1.6+ -``` +If any command fails or returns an error, install the missing tool using your system package manager or the official installation instructions. -## Network Requirements - -### Outbound Connectivity -OpenFrame CLI requires internet access for: -- Pulling Docker images -- Downloading Helm charts -- Accessing Git repositories -- Installing prerequisites - -### Port Requirements -| Port Range | Protocol | Purpose | -|------------|----------|---------| -| 80, 443 | TCP | HTTPS/HTTP for downloads | -| 6443 | TCP | Kubernetes API server | -| 30000-32767 | TCP | Kubernetes NodePort range | -| 2376, 2377 | TCP | Docker daemon (if remote) | - -### Firewall Considerations -Ensure your firewall allows: -- Docker daemon communication -- Kubernetes cluster communication -- Outbound HTTPS connections +--- -## Environment Variables +## Quick Install References -Set these environment variables for optimal experience: +
+Install k3d -### Required ```bash -# Docker daemon configuration -export DOCKER_HOST="unix:///var/run/docker.sock" +# Using the official install script +curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash -# Kubernetes configuration -export KUBECONFIG="$HOME/.kube/config" +# Or with Homebrew (macOS/Linux) +brew install k3d ``` -### Optional +
+ +
+Install kubectl + ```bash -# OpenFrame CLI configuration -export OPENFRAME_LOG_LEVEL="info" -export OPENFRAME_CONFIG_DIR="$HOME/.openframe" +# Linux (AMD64) +curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" +chmod +x kubectl && sudo mv kubectl /usr/local/bin/ -# Development tools -export TELEPRESENCE_LOGIN_DOMAIN="auth.datawire.io" +# macOS +brew install kubectl ``` -## Account Requirements +
-### Container Registry Access -- **Public registries**: Docker Hub, GHCR.io (no authentication required) -- **Private registries**: Configure Docker credentials if using private images +
+Install Helm -### Git Repository Access -- **Public repositories**: No authentication required -- **Private repositories**: Configure SSH keys or personal access tokens +```bash +# Using the official install script +curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash + +# Or with Homebrew +brew install helm +``` -## Quick Setup Script +
-For convenience, here's a script to verify all prerequisites: +
+Install mkcert ```bash -#!/bin/bash -# prerequisites-check.sh - -echo "🔍 Checking OpenFrame CLI prerequisites..." - -# Function to check if command exists -command_exists() { - command -v "$1" >/dev/null 2>&1 -} - -# Function to check version -check_version() { - local tool="$1" - local min_version="$2" - local current_version="$3" - - echo " $tool: $current_version (required: $min_version+)" -} - -errors=0 - -# Check Docker -if command_exists docker; then - docker_version=$(docker --version | cut -d' ' -f3 | cut -d',' -f1) - check_version "Docker" "20.10.0" "$docker_version" - if ! docker ps >/dev/null 2>&1; then - echo " ❌ Docker daemon is not running or accessible" - ((errors++)) - fi -else - echo " ❌ Docker not found" - ((errors++)) -fi - -# Check kubectl -if command_exists kubectl; then - kubectl_version=$(kubectl version --client -o json 2>/dev/null | jq -r '.clientVersion.gitVersion' 2>/dev/null || echo "unknown") - check_version "kubectl" "1.25.0" "$kubectl_version" -else - echo " ❌ kubectl not found" - ((errors++)) -fi - -# Check Helm -if command_exists helm; then - helm_version=$(helm version --short | cut -d'+' -f1) - check_version "Helm" "3.10.0" "$helm_version" -else - echo " ❌ Helm not found" - ((errors++)) -fi - -# Check K3D -if command_exists k3d; then - k3d_version=$(k3d version | grep k3d | cut -d' ' -f2) - check_version "K3D" "5.0.0" "$k3d_version" -else - echo " ❌ K3D not found" - ((errors++)) -fi - -# Check optional tools -echo "" -echo "📋 Optional development tools:" - -if command_exists telepresence; then - telepresence_version=$(telepresence version --output=json 2>/dev/null | jq -r '.client.version' 2>/dev/null || "unknown") - check_version "Telepresence" "2.10.0" "$telepresence_version" -else - echo " ⚠️ Telepresence not found (optional for dev workflows)" -fi - -if command_exists jq; then - jq_version=$(jq --version | cut -d'-' -f2) - check_version "jq" "1.6" "$jq_version" -else - echo " ⚠️ jq not found (optional for dev scripts)" -fi - -echo "" -if [ $errors -eq 0 ]; then - echo "✅ All required prerequisites are installed!" - echo "🚀 You're ready to install OpenFrame CLI" -else - echo "❌ $errors required dependencies are missing" - echo "📖 Please install missing dependencies before proceeding" - exit 1 -fi +# macOS +brew install mkcert +mkcert -install + +# Linux (using pre-built binary) +curl -LO https://github.com/FiloSottile/mkcert/releases/latest/download/mkcert-v1.4.4-linux-amd64 +chmod +x mkcert-v1.4.4-linux-amd64 && sudo mv mkcert-v1.4.4-linux-amd64 /usr/local/bin/mkcert +mkcert -install ``` -Save this as `prerequisites-check.sh`, make it executable, and run: +
+ +
+Install Telepresence ```bash -chmod +x prerequisites-check.sh -./prerequisites-check.sh +# macOS/Linux +curl -fL https://app.getambassador.io/download/tel2/linux/amd64/latest/telepresence -o telepresence +chmod +x telepresence && sudo mv telepresence /usr/local/bin/ ``` -## Troubleshooting Common Issues +
-### Docker Permission Issues -If you get permission denied errors: +--- -```bash -# Add your user to the docker group -sudo usermod -aG docker $USER +## Automated Prerequisite Check -# Log out and back in, or run: -newgrp docker -``` +The CLI runs its own prerequisite checker before every cluster or chart operation. If you prefer to check manually: -### kubectl Not Finding Config ```bash -# Create kubeconfig directory -mkdir -p ~/.kube - -# Verify KUBECONFIG environment variable -echo `$KUBECONFIG` +# The CLI will check and report missing tools when you run any command +openframe cluster list ``` -### K3D Installation Issues on macOS -```bash -# If using Homebrew -brew install k3d +Missing tools will be reported with platform-specific installation instructions printed directly in the terminal. -# If using curl -curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash -``` - -### WSL2 Setup on Windows -1. Enable WSL2: `wsl --install` -2. Install Ubuntu from Microsoft Store -3. Install Docker Desktop with WSL2 backend -4. Install all prerequisites inside WSL2 environment +--- ## Next Steps -Once all prerequisites are installed and verified: - -1. **[Quick Start Guide](quick-start.md)** - Install OpenFrame CLI and bootstrap your first environment -2. **[First Steps Guide](first-steps.md)** - Explore key features and workflows - -Need help? Join our community: -- **OpenMSP Slack**: [Join here](https://join.slack.com/t/openmsp/shared_invite/zt-36bl7mx0h-3~U2nFH6nqHqoTPXMaHEHA) \ No newline at end of file +Once all prerequisites are verified, follow the [Quick Start Guide](quick-start.md) to bootstrap your first OpenFrame environment. diff --git a/docs/getting-started/quick-start.md b/docs/getting-started/quick-start.md index 72253b3f..31f167c8 100644 --- a/docs/getting-started/quick-start.md +++ b/docs/getting-started/quick-start.md @@ -1,355 +1,176 @@ -# Quick Start Guide +# Quick Start -Get OpenFrame CLI up and running in 5 minutes! This guide will walk you through installing OpenFrame CLI and bootstrapping your first environment. +Get a fully operational OpenFrame Kubernetes environment running in minutes using a single command. -[![OpenFrame: 5-Minute MSP Platform Walkthrough - Cut Vendor Costs & Automate Ops](https://img.youtube.com/vi/er-z6IUnAps/maxresdefault.jpg)](https://www.youtube.com/watch?v=er-z6IUnAps) +[![OpenFrame v0.3.7 - Enhanced Developer Experience](https://img.youtube.com/vi/O8hbBO5Mym8/maxresdefault.jpg)](https://www.youtube.com/watch?v=O8hbBO5Mym8) -## TL;DR - 5-Minute Setup +--- -If you have all prerequisites installed, here's the fastest path: +## TL;DR — 5-Minute Setup ```bash -# 1. Download and install OpenFrame CLI (choose your platform) -# Linux/macOS -curl -fsSL https://github.com/flamingo-stack/openframe-cli/releases/latest/download/openframe-cli_linux_amd64.tar.gz | tar -xz -sudo mv openframe /usr/local/bin/ +# 1. Download the CLI binary for your platform (example: Linux AMD64) +curl -LO https://github.com/flamingo-stack/openframe-cli/releases/latest/download/openframe-cli_linux_amd64.tar.gz +tar -xzf openframe-cli_linux_amd64.tar.gz +chmod +x openframe +sudo mv openframe /usr/local/bin/openframe -# Windows (download manually) -# Download: https://github.com/flamingo-stack/openframe-cli/releases/latest/download/openframe-cli_windows_amd64.zip - -# 2. Verify installation -openframe --version - -# 3. Bootstrap complete environment +# 2. Bootstrap a complete environment (interactive mode) openframe bootstrap -# 4. Check cluster status -openframe cluster status +# 3. That's it — your cluster and full OpenFrame stack are running! ``` -That's it! Continue reading for detailed steps and explanations. +> **Windows (AMD64) users:** Download from [https://github.com/flamingo-stack/openframe-cli/releases/latest/download/openframe-cli_windows_amd64.zip](https://github.com/flamingo-stack/openframe-cli/releases/latest/download/openframe-cli_windows_amd64.zip), extract, and run the installer the same way as other platforms. -## Step 1: Install OpenFrame CLI +--- -### Option A: Download Pre-built Binary (Recommended) +## Step-by-Step Installation -Choose your platform and download the latest release: - -#### Linux (AMD64) -```bash -curl -fsSL https://github.com/flamingo-stack/openframe-cli/releases/latest/download/openframe-cli_linux_amd64.tar.gz | tar -xz -sudo mv openframe /usr/local/bin/ -chmod +x /usr/local/bin/openframe -``` - -#### Linux (ARM64) -```bash -curl -fsSL https://github.com/flamingo-stack/openframe-cli/releases/latest/download/openframe-cli_linux_arm64.tar.gz | tar -xz -sudo mv openframe /usr/local/bin/ -chmod +x /usr/local/bin/openframe -``` - -#### macOS (AMD64) -```bash -curl -fsSL https://github.com/flamingo-stack/openframe-cli/releases/latest/download/openframe-cli_darwin_amd64.tar.gz | tar -xz -sudo mv openframe /usr/local/bin/ -chmod +x /usr/local/bin/openframe -``` +### Step 1 — Download the CLI -#### macOS (Apple Silicon) -```bash -curl -fsSL https://github.com/flamingo-stack/openframe-cli/releases/latest/download/openframe-cli_darwin_arm64.tar.gz | tar -xz -sudo mv openframe /usr/local/bin/ -chmod +x /usr/local/bin/openframe -``` +Choose the binary for your operating system: -#### Windows (AMD64) -1. Download: https://github.com/flamingo-stack/openframe-cli/releases/latest/download/openframe-cli_windows_amd64.zip -2. Extract the ZIP file -3. Move `openframe.exe` to a directory in your `PATH` -4. Open WSL2 terminal and verify access +| Platform | Download | +|----------|----------| +| Linux AMD64 | `openframe-cli_linux_amd64.tar.gz` | +| macOS (Apple Silicon) | `openframe-cli_darwin_arm64.tar.gz` | +| macOS (Intel) | `openframe-cli_darwin_amd64.tar.gz` | +| Windows AMD64 | `openframe-cli_windows_amd64.zip` | -### Option B: Build from Source +All releases are available at: +[https://github.com/flamingo-stack/openframe-cli/releases](https://github.com/flamingo-stack/openframe-cli/releases) -If you have Go 1.24.6+ installed: +### Step 2 — Install the Binary ```bash -# Clone the repository -git clone https://github.com/flamingo-stack/openframe-cli.git -cd openframe-cli - -# Build the binary -go build -o openframe main.go - -# Move to PATH -sudo mv openframe /usr/local/bin/ -``` - -## Step 2: Verify Installation +# Linux / macOS +tar -xzf openframe-cli__.tar.gz +chmod +x openframe +sudo mv openframe /usr/local/bin/openframe -Confirm OpenFrame CLI is installed correctly: - -```bash +# Verify installation openframe --version ``` -Expected output: -```text -openframe version v1.x.x (commit: abc123, built: 2024-01-01) -``` +### Step 3 — Bootstrap Your Environment -Check available commands: -```bash -openframe --help -``` +The `bootstrap` command does everything in one shot: -You should see the main command groups: -- `bootstrap` - Complete environment setup -- `cluster` - Kubernetes cluster management -- `chart` - Helm chart and ArgoCD management -- `dev` - Development tools and workflows - -## Step 3: Bootstrap Your First Environment - -The bootstrap command creates a complete OpenFrame environment with a single command: +1. Checks all prerequisites +2. Creates a K3D local Kubernetes cluster +3. Installs ArgoCD via Helm +4. Clones the OpenFrame Helm chart repository +5. Deploys the app-of-apps stack +6. Waits for all ArgoCD Applications to reach Healthy+Synced state ```bash +# Interactive mode — the wizard asks for cluster name and deployment mode openframe bootstrap -``` - -### Interactive Bootstrap - -The command will guide you through setup with prompts: -```text -🚀 OpenFrame Bootstrap Wizard - -? Select deployment mode: - > oss-tenant (Single tenant, open source) - saas-tenant (Multi-tenant SaaS mode) - saas-shared (Shared SaaS infrastructure) - -? Enable verbose logging? (y/N): y - -🔍 Checking prerequisites... -✅ Docker is running -✅ kubectl is available -✅ Helm is available -✅ K3D is available - -🎯 Creating K3D cluster... -✅ Cluster 'openframe-local' created - -🎭 Installing ArgoCD... -✅ ArgoCD installed and ready +# Non-interactive OSS tenant setup (recommended for first-time) +openframe bootstrap my-cluster --deployment-mode=oss-tenant -📦 Installing application charts... -✅ App-of-apps synchronized -✅ All applications healthy - -🎉 OpenFrame environment is ready! +# Verbose output to see ArgoCD sync progress +openframe bootstrap my-cluster --deployment-mode=oss-tenant -v ``` -### Non-Interactive Bootstrap - -For scripts and CI/CD, use flags to skip prompts: - -```bash -openframe bootstrap \ - --mode=oss-tenant \ - --non-interactive \ - --verbose -``` +--- -## Step 4: Verify Your Environment +## Expected Output -### Check Cluster Status -```bash -openframe cluster status -``` +When bootstrap runs successfully, you'll see output similar to: -Expected output: ```text -📊 Cluster Status: openframe-local - -Cluster Info: - Name: openframe-local - Status: Running ✅ - Nodes: 1 (1 ready) - Kubernetes Version: v1.28.6+k3s1 - -Resource Usage: - CPU: 2 cores (25% used) - Memory: 8Gi (45% used) - Storage: 50Gi (12% used) - -Key Services: - ArgoCD: Healthy ✅ - Traefik: Healthy ✅ - CoreDNS: Healthy ✅ -``` + ___ _____ + / _ \ _ __ ___ _ __ | ___| __ __ _ _ __ ___ ___ +| | | | '_ \ / _ | '_ \| |_ | '__/ _` | '_ ` _ \ / _ \ +| |_| | |_) | __| | | | _|| | | (_| | | | | | | __/ + \___/| .__/ \___|_| |_|_| |_| \__,_|_| |_| |_|\___| + |_| -### Access ArgoCD UI -The bootstrap process installs ArgoCD. Access the web interface: +✓ Prerequisites validated +✓ Cluster "my-cluster" created +✓ ArgoCD installed +✓ App-of-apps deployed +✓ All applications synced and healthy -```bash -# Get ArgoCD URL and credentials -kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo -kubectl port-forward svc/argocd-server -n argocd 8080:443 +Your OpenFrame environment is ready! ``` -Then open: http://localhost:8080 -- Username: `admin` -- Password: (from the command above) +--- -### View Running Applications -```bash -# List all pods across namespaces -kubectl get pods --all-namespaces - -# Check ArgoCD applications -kubectl get applications -n argocd -``` +## Basic "Hello World" — Verify Your Environment -## Step 5: Test Basic Functionality +After bootstrap completes, run these commands to confirm everything is working: -### Create a Test Namespace ```bash -kubectl create namespace test-app -kubectl get namespaces -``` +# List your cluster +openframe cluster list -### Deploy a Simple Application -```bash -# Create a test deployment -kubectl create deployment nginx --image=nginx:latest -n test-app -kubectl expose deployment nginx --port=80 --target-port=80 -n test-app +# Check cluster status +openframe cluster status my-cluster -# Check deployment -kubectl get pods -n test-app -kubectl get svc -n test-app +# Check what's running in Kubernetes +kubectl get pods -A ``` -### Test Service Access -```bash -# Port forward to test connectivity -kubectl port-forward svc/nginx -n test-app 8081:80 & - -# Test the service -curl http://localhost:8081 +Expected cluster list output: -# Clean up -kill %1 # Stop port-forward -kubectl delete namespace test-app +```text +NAME STATE AGENTS SERVER +my-cluster running 1 1 ``` -## What Just Happened? - -The bootstrap process created: - -1. **K3D Cluster**: A lightweight Kubernetes cluster running in Docker -2. **ArgoCD**: GitOps deployment tool for application management -3. **Traefik**: Ingress controller for routing traffic -4. **Core Services**: DNS, metrics, and monitoring components -5. **Application Templates**: Ready-to-use deployment patterns - -## Expected Results - -After successful bootstrap: - -| Component | Status | Access Method | -|-----------|--------|---------------| -| **Kubernetes API** | ✅ Running | `kubectl` commands | -| **ArgoCD UI** | ✅ Running | Port forward to 8080 | -| **Traefik Dashboard** | ✅ Running | Port forward to 9000 | -| **Container Registry** | ✅ Running | Docker daemon | - -## Troubleshooting - -### Bootstrap Fails with Docker Error -```bash -# Check Docker status -docker ps -docker info - -# Restart Docker if needed -sudo systemctl restart docker # Linux -# or restart Docker Desktop on macOS/Windows -``` +--- -### Kubectl Cannot Connect -```bash -# Check kubeconfig -kubectl config current-context -kubectl config get-contexts +## Build from Source (Alternative) -# Switch to openframe context if needed -kubectl config use-context k3d-openframe-local -``` +If you prefer to build from source instead of using a binary release: -### ArgoCD Not Accessible ```bash -# Check ArgoCD pods -kubectl get pods -n argocd - -# Restart ArgoCD if needed -kubectl rollout restart deployment argocd-server -n argocd -``` +# Clone the repository +git clone https://github.com/flamingo-stack/openframe-cli.git +cd openframe-cli -### Port Already in Use -```bash -# Find and kill processes using required ports -lsof -ti:6443,8080,9000 | xargs kill -9 +# Build the binary +go build -o openframe ./main.go -# Or use different ports -kubectl port-forward svc/argocd-server -n argocd 8081:443 +# Run it +./openframe --version ``` -## Next Steps - -🎉 **Congratulations!** You now have a running OpenFrame environment. Here's what to explore next: +--- -- **[First Steps Guide](first-steps.md)** - Learn key workflows and features -- **[Architecture Overview](../development/architecture/README.md)** - Understand how components work together -- **[Development Setup](../development/setup/local-development.md)** - Configure your development environment +## CI/CD Non-Interactive Mode -## Common Next Actions +For automated pipelines, use the `--non-interactive` flag: -### Deploy Your First Application ```bash -# Use ArgoCD to deploy from Git -openframe chart install my-app \ - --repo=https://github.com/your-org/your-app \ - --path=helm-chart +openframe bootstrap my-env \ + --deployment-mode=oss-tenant \ + --non-interactive \ + --verbose ``` -### Start Local Development -```bash -# Intercept a service for local development -openframe dev intercept my-service \ - --namespace=default \ - --port=8080:3000 -``` +The `CI` environment variable also automatically enables non-interactive mode when set. -### Explore the Environment -```bash -# List available commands -openframe --help +--- -# Get cluster information -openframe cluster list -openframe cluster status +## Available Bootstrap Flags -# Check chart installations -openframe chart list -``` +| Flag | Description | Default | +|------|-------------|---------| +| `--deployment-mode` | One of `oss-tenant`, `saas-tenant`, `saas-shared` | Interactive prompt | +| `--non-interactive` | Skip all interactive prompts | `false` | +| `-v`, `--verbose` | Show detailed output including ArgoCD sync | `false` | +| `--silent` | Suppress all output except errors | `false` | -## Getting Help +--- -Need assistance? The OpenFrame community is here to help: +## Next Steps -- **OpenMSP Slack**: [Join the community](https://join.slack.com/t/openmsp/shared_invite/zt-36bl7mx0h-3~U2nFH6nqHqoTPXMaHEHA) -- **Documentation**: Browse other guides in this repository -- **GitHub Issues**: Report bugs or request features (but use Slack for general support) +After completing the quick start: -> **Note**: All community support happens in Slack - we don't monitor GitHub Issues for support requests. \ No newline at end of file +- Follow the **[First Steps Guide](first-steps.md)** to explore key features and run your first development workflow +- Review the **[Prerequisites Guide](prerequisites.md)** if you encountered any tool-missing errors diff --git a/docs/architecture/.gitignore b/docs/reference/architecture/.gitignore similarity index 100% rename from docs/architecture/.gitignore rename to docs/reference/architecture/.gitignore diff --git a/docs/reference/architecture/overview.md b/docs/reference/architecture/overview.md new file mode 100644 index 00000000..2d85462a --- /dev/null +++ b/docs/reference/architecture/overview.md @@ -0,0 +1,536 @@ +# openframe-cli Module Documentation + +# OpenFrame CLI Architecture Documentation + +[![OpenFrame Preview Webinar](https://img.youtube.com/vi/bINdW0CQbvY/hqdefault.jpg)](https://www.youtube.com/watch?v=bINdW0CQbvY) + +## Overview + +OpenFrame CLI is a modern, interactive command-line tool built in Go for bootstrapping and managing OpenFrame Kubernetes environments. It provides a unified interface for full environment lifecycle management — from creating K3D clusters and installing ArgoCD via Helm, to enabling local development workflows through Telepresence service intercepts and Skaffold-based hot reloading. The CLI is the primary developer-facing entry point to the broader [OpenFrame](https://openframe.ai) AI-powered MSP platform. + +--- + +## Architecture + +OpenFrame CLI follows a layered clean architecture pattern: thin Cobra command handlers delegate to service layers, which compose providers and infrastructure utilities. All external I/O (Kubernetes API, shell commands, Git) is abstracted behind interfaces to support testability. + +### High-Level Architecture Diagram + +```mermaid +graph TD + subgraph CLI["CLI Entry Layer (cmd/)"] + Root["Root Command"] + Bootstrap["bootstrap"] + Cluster["cluster"] + Chart["chart"] + Dev["dev"] + end + + subgraph Services["Service Layer (internal/)"] + BootstrapSvc["Bootstrap Service"] + ClusterSvc["Cluster Service"] + ChartSvc["Chart Service"] + DevSvc["Dev Services"] + end + + subgraph Providers["Provider Layer"] + K3D["K3D Manager"] + HelmMgr["Helm Manager"] + ArgoCDMgr["ArgoCD Manager"] + GitRepo["Git Repository"] + KubectlProv["Kubectl Provider"] + TelepresenceProv["Telepresence Provider"] + end + + subgraph Infra["Shared Infrastructure"] + Executor["Command Executor"] + UIShared["Shared UI"] + ErrorsShared["Error Handling"] + ConfigShared["Config / Paths"] + FilesShared["File Cleanup"] + end + + subgraph External["External Systems"] + K3dBin["k3d binary"] + HelmBin["helm binary"] + ArgoCDAPI["ArgoCD Kubernetes API"] + GitHubRepo["GitHub Repository"] + K8sAPI["Kubernetes API"] + TelepresenceBin["telepresence binary"] + SkaffoldBin["skaffold binary"] + end + + Root --> Bootstrap + Root --> Cluster + Root --> Chart + Root --> Dev + + Bootstrap --> BootstrapSvc + Cluster --> ClusterSvc + Chart --> ChartSvc + Dev --> DevSvc + + BootstrapSvc --> ClusterSvc + BootstrapSvc --> ChartSvc + + ClusterSvc --> K3D + ChartSvc --> HelmMgr + ChartSvc --> ArgoCDMgr + ChartSvc --> GitRepo + DevSvc --> KubectlProv + DevSvc --> TelepresenceProv + + K3D --> Executor + HelmMgr --> Executor + ArgoCDMgr --> K8sAPI + GitRepo --> Executor + KubectlProv --> Executor + TelepresenceProv --> Executor + + Executor --> K3dBin + Executor --> HelmBin + Executor --> TelepresenceBin + Executor --> SkaffoldBin + HelmMgr --> ArgoCDAPI + ArgoCDMgr --> ArgoCDAPI + GitRepo --> GitHubRepo + KubectlProv --> K8sAPI + + ClusterSvc --> UIShared + ChartSvc --> UIShared + DevSvc --> UIShared + ClusterSvc --> ErrorsShared + ChartSvc --> ErrorsShared + ClusterSvc --> ConfigShared + ChartSvc --> ConfigShared + ChartSvc --> FilesShared +``` + +--- + +## Core Components + +| Package | Path | Responsibility | +|---------|------|----------------| +| **Root Command** | `cmd/root.go` | CLI entrypoint, global flags (`--verbose`, `--silent`), version info, subcommand registration | +| **Bootstrap Command** | `cmd/bootstrap/` | Orchestrates full environment setup: cluster create → chart install in sequence | +| **Cluster Command** | `cmd/cluster/` | Cobra subcommands for create, delete, list, status, cleanup | +| **Chart Command** | `cmd/chart/` | Cobra subcommands for ArgoCD + app-of-apps installation | +| **Dev Command** | `cmd/dev/` | Cobra subcommands for `intercept` (Telepresence) and `skaffold` workflows | +| **Bootstrap Service** | `internal/bootstrap/` | Business logic to sequence cluster creation then chart installation; handles Windows WSL init | +| **Cluster Service** | `internal/cluster/service.go` | High-level cluster lifecycle: create, delete, list, status, cleanup; delegates to K3D manager | +| **K3D Manager** | `internal/cluster/providers/k3d/` | Low-level K3D cluster operations; config file generation, kubeconfig management, TLS SAN injection | +| **Chart Service** | `internal/chart/services/` | Installation workflow: prerequisites → git clone → helm install ArgoCD → install app-of-apps → wait for sync | +| **Helm Manager** | `internal/chart/providers/helm/` | Helm CLI wrapper; installs ArgoCD and app-of-apps charts via subprocess; native K8s client fallback | +| **ArgoCD Manager** | `internal/chart/providers/argocd/` | Watches ArgoCD `Application` CRDs via native Go client; waits for Healthy+Synced state | +| **Git Repository** | `internal/chart/providers/git/` | Clones GitHub repos (`--depth 1`) to temp dirs for app-of-apps chart content | +| **Configuration Wizard** | `internal/chart/ui/configuration/` | Multi-step interactive wizard for deployment mode, SaaS credentials, ingress, Docker registry | +| **Helm Values Modifier** | `internal/chart/ui/templates/` | Reads, modifies, and writes `helm-values.yaml`; creates `helm-values-tmp.yaml` | +| **Intercept Service** | `internal/dev/services/intercept/` | Manages full Telepresence lifecycle: connect → intercept → wait → cleanup on signal | +| **Scaffold Service** | `internal/dev/services/scaffold/` | Discovers `skaffold.yaml` files, bootstraps cluster, runs `skaffold dev` | +| **Kubectl Provider** | `internal/dev/providers/kubectl/` | kubectl wrapper for namespace/service discovery used by interactive intercept UI | +| **Telepresence Provider** | `internal/dev/providers/telepresence/` | Manages telepresence connect/intercept/quit lifecycle | +| **Command Executor** | `internal/shared/executor/` | Abstracts `os/exec` for all CLI tool invocations; supports dry-run and verbose modes; WSL detection | +| **Prerequisites Checkers** | `internal/cluster/prerequisites/`, `internal/chart/prerequisites/` | Checks/installs Docker, k3d, kubectl, helm, git, mkcert; CI-aware non-interactive mode | +| **Shared UI** | `internal/shared/ui/` | Logo rendering, selection prompts, table rendering, confirmation dialogs; `pterm` + `promptui` | +| **Shared Errors** | `internal/shared/errors/` | `BranchNotFoundError`, `ValidationError`, `AlreadyHandledError`, retry policies, error formatting | +| **Shared Config** | `internal/shared/config/` | TLS bypass utilities for k3d, credentials prompter, system service (log directory init) | +| **File Cleanup** | `internal/shared/files/` | Backup/restore `helm-values-tmp.yaml`; cleanup-on-success semantics | +| **Models** | `internal/cluster/models/`, `internal/chart/models/` | Domain types: `ClusterConfig`, `ClusterInfo`, `AppOfAppsConfig`, `ChartInstallConfig` | + +--- + +## Component Relationships + +### Dependency Graph + +```mermaid +graph LR + subgraph Commands["cmd/ layer"] + CmdRoot["root"] + CmdBoot["bootstrap"] + CmdCluster["cluster/*"] + CmdChart["chart/*"] + CmdDev["dev/*"] + end + + subgraph InternalBootstrap["internal/bootstrap"] + SvcBoot["Bootstrap Service"] + end + + subgraph InternalCluster["internal/cluster"] + SvcCluster["Cluster Service"] + ModCluster["models"] + ProvK3D["providers/k3d"] + UICluster["ui/*"] + PrereqCluster["prerequisites/*"] + UtilsCluster["utils/"] + end + + subgraph InternalChart["internal/chart"] + SvcChart["services/*"] + ModChart["models"] + ProvHelm["providers/helm"] + ProvArgoCD["providers/argocd"] + ProvGit["providers/git"] + UIChart["ui/*"] + PrereqChart["prerequisites/*"] + UtilsChart["utils/config + errors + types"] + end + + subgraph InternalDev["internal/dev"] + SvcIntercept["services/intercept"] + SvcScaffold["services/scaffold"] + ProvKubectl["providers/kubectl"] + ProvTelepresence["providers/telepresence"] + ProvDevChart["providers/chart"] + UIDevIntercept["ui/intercept + service"] + PrereqDev["prerequisites/*"] + end + + subgraph Shared["internal/shared"] + SharedExec["executor"] + SharedUI["ui/"] + SharedErrors["errors/"] + SharedConfig["config/"] + SharedFiles["files/"] + SharedFlags["flags/"] + end + + CmdRoot --> CmdBoot + CmdRoot --> CmdCluster + CmdRoot --> CmdChart + CmdRoot --> CmdDev + + CmdBoot --> SvcBoot + SvcBoot --> SvcCluster + SvcBoot --> SvcChart + + CmdCluster --> UtilsCluster + UtilsCluster --> SvcCluster + SvcCluster --> ProvK3D + SvcCluster --> UICluster + SvcCluster --> ModCluster + SvcCluster --> PrereqCluster + + CmdChart --> SvcChart + SvcChart --> ProvHelm + SvcChart --> ProvArgoCD + SvcChart --> ProvGit + SvcChart --> UIChart + SvcChart --> UtilsChart + SvcChart --> ModChart + SvcChart --> PrereqChart + + CmdDev --> SvcIntercept + CmdDev --> SvcScaffold + SvcIntercept --> ProvTelepresence + SvcIntercept --> ProvKubectl + SvcScaffold --> ProvDevChart + SvcScaffold --> ProvKubectl + SvcScaffold --> PrereqDev + UIDevIntercept --> ProvKubectl + + ProvK3D --> SharedExec + ProvHelm --> SharedExec + ProvHelm --> SharedConfig + ProvArgoCD --> SharedConfig + ProvGit --> SharedExec + ProvKubectl --> SharedExec + ProvTelepresence --> SharedExec + + SvcCluster --> SharedUI + SvcCluster --> SharedErrors + SvcChart --> SharedErrors + SvcChart --> SharedFiles + SvcChart --> SharedConfig + UICluster --> SharedUI + UIChart --> SharedUI + UIDevIntercept --> SharedUI + + ModCluster --> SharedFlags +``` + +--- + +## Data Flow + +### Bootstrap Command: Full Environment Setup + +```mermaid +sequenceDiagram + participant User + participant BootstrapCmd as "bootstrap cmd" + participant BootstrapSvc as "Bootstrap Service" + participant ClusterSvc as "Cluster Service" + participant K3DMgr as "K3D Manager" + participant ChartSvc as "Chart Service" + participant GitProv as "Git Provider" + participant HelmMgr as "Helm Manager" + participant ArgoCDMgr as "ArgoCD Manager" + participant K8sAPI as "Kubernetes API" + participant GitHub as "GitHub" + + User->>BootstrapCmd: openframe bootstrap [name] [--deployment-mode] + BootstrapCmd->>BootstrapSvc: Execute(cmd, args) + BootstrapSvc->>ClusterSvc: CreateClusterWithPrerequisites(name, verbose) + ClusterSvc->>K3DMgr: CreateCluster(ClusterConfig) + K3DMgr->>K3DMgr: Generate k3d config YAML + K3DMgr->>K3DMgr: k3d cluster create --config ... + K3DMgr-->>ClusterSvc: rest.Config + ClusterSvc-->>BootstrapSvc: rest.Config + + BootstrapSvc->>ChartSvc: InstallChartsWithConfig(InstallationRequest) + ChartSvc->>ChartSvc: Check prerequisites (helm, git, certs) + ChartSvc->>ChartSvc: Interactive wizard OR use --deployment-mode + + ChartSvc->>HelmMgr: InstallArgoCDWithProgress(config) + HelmMgr->>HelmMgr: helm repo add / helm upgrade --install argo-cd + HelmMgr-->>ChartSvc: ArgoCD installed + + ChartSvc->>GitProv: CloneChartRepository(AppOfAppsConfig) + GitProv->>GitHub: git clone --depth 1 --branch [branch] + GitHub-->>GitProv: chart files + GitProv-->>ChartSvc: CloneResult{TempDir, ChartPath} + + ChartSvc->>HelmMgr: InstallAppOfAppsFromLocal(config, certFile, keyFile) + HelmMgr->>K8sAPI: helm upgrade --install app-of-apps + HelmMgr-->>ChartSvc: app-of-apps installed + + ChartSvc->>ArgoCDMgr: WaitForApplications(config) + loop Poll every 2s up to timeout + ArgoCDMgr->>K8sAPI: List Application CRDs + K8sAPI-->>ArgoCDMgr: Application statuses + ArgoCDMgr->>ArgoCDMgr: Check Healthy + Synced + end + ArgoCDMgr-->>ChartSvc: All applications ready + ChartSvc-->>BootstrapSvc: Success + BootstrapSvc-->>User: Environment ready +``` + +### Interactive Intercept: Dev Workflow + +```mermaid +sequenceDiagram + participant User + participant DevCmd as "dev intercept cmd" + participant ClusterSvc as "Cluster Service" + participant KubectlProv as "Kubectl Provider" + participant InterceptUI as "Intercept UI" + participant InterceptSvc as "Intercept Service" + participant Telepresence as "Telepresence Binary" + participant K8sAPI as "Kubernetes API" + + User->>DevCmd: openframe dev intercept + DevCmd->>ClusterSvc: ListClusters() + ClusterSvc-->>DevCmd: clusters[] + DevCmd->>User: Select cluster (interactive) + User-->>DevCmd: cluster selected + + DevCmd->>KubectlProv: kubectl config use-context k3d-[name] + DevCmd->>KubectlProv: CheckConnection(ctx) + KubectlProv->>K8sAPI: kubectl cluster-info + K8sAPI-->>KubectlProv: OK + + DevCmd->>InterceptUI: InteractiveInterceptSetup(ctx) + InterceptUI->>KubectlProv: GetNamespaces(ctx) + KubectlProv->>K8sAPI: kubectl get namespaces -o json + K8sAPI-->>KubectlProv: namespace list + InterceptUI->>User: Enter service name + User-->>InterceptUI: service name + + InterceptUI->>KubectlProv: GetService(ctx, namespace, serviceName) + KubectlProv->>K8sAPI: kubectl get service -o json + K8sAPI-->>KubectlProv: ServiceInfo{ports} + InterceptUI->>User: Select Kubernetes port + InterceptUI->>User: Enter local port + User-->>InterceptUI: setup complete + + DevCmd->>InterceptSvc: StartIntercept(serviceName, flags) + InterceptSvc->>Telepresence: telepresence connect + InterceptSvc->>Telepresence: telepresence intercept [svc] --port local:remote + Telepresence-->>InterceptSvc: intercept active + + InterceptSvc->>InterceptSvc: Wait for OS signal (Ctrl+C) + User->>InterceptSvc: Ctrl+C + InterceptSvc->>Telepresence: telepresence leave [svc] + InterceptSvc->>Telepresence: telepresence quit + InterceptSvc-->>User: Intercept stopped +``` + +--- + +## Key Files + +| File | Purpose | +|------|---------| +| `main.go` | Binary entrypoint; delegates to `cmd.Execute()` | +| `cmd/root.go` | Root Cobra command, global flags, version template, subcommand registration | +| `cmd/bootstrap/bootstrap.go` | Bootstrap command definition with `--deployment-mode` and `--non-interactive` flags | +| `cmd/cluster/cluster.go` | Cluster command group with prerequisite check in `PersistentPreRunE` | +| `cmd/cluster/create.go` | Cluster create with wizard/non-wizard branching | +| `cmd/chart/install.go` | Chart install command with full flag extraction and validation | +| `cmd/dev/intercept.go` | Dev intercept command; routes to interactive or flag-based intercept modes | +| `internal/bootstrap/service.go` | Core bootstrap orchestration: cluster create → chart install sequencing | +| `internal/cluster/service.go` | `ClusterService`: wraps K3D manager with UI feedback, spinner, next-steps display | +| `internal/cluster/providers/k3d/manager.go` | K3D cluster CRUD via `k3d` binary; generates config YAML, handles WSL path conversion | +| `internal/chart/services/chart_service.go` | `ChartService` factory and `Install()` entrypoint; wires all chart sub-services | +| `internal/chart/services/installer.go` | `Installer`: orchestrates ArgoCD install → app-of-apps install → wait for sync | +| `internal/chart/providers/helm/manager.go` | `HelmManager`: helm subprocess wrapper with native K8s Go client fallback | +| `internal/chart/providers/argocd/applications.go` | `Manager`: native ArgoCD client using generated clientset; polls Application status | +| `internal/chart/providers/argocd/wait.go` | Long-poll loop with stabilization checks, signal handling, repo-server health recovery | +| `internal/chart/providers/argocd/argocd_values.go` | Embedded ArgoCD Helm values (resource limits, health checks, sync timeouts) | +| `internal/chart/providers/git/repository.go` | `Repository.CloneChartRepository()`: `git clone --depth 1` to temp dir | +| `internal/chart/ui/configuration/wizard.go` | Top-level configuration wizard routing interactive vs. default modes | +| `internal/chart/ui/configuration/modes.go` | Deployment mode selection and per-mode configuration dispatching | +| `internal/chart/ui/templates/helm_modifier.go` | `HelmValuesModifier`: YAML load/apply/write for `helm-values.yaml` | +| `internal/dev/services/intercept/service.go` | `Service.StartIntercept()`: validates, connects Telepresence, creates intercept, blocks | +| `internal/dev/services/scaffold/service.go` | `Service.RunScaffoldWorkflow()`: discovers skaffold.yaml, bootstraps, runs `skaffold dev` | +| `internal/dev/providers/kubectl/services.go` | JSON-based kubectl service discovery across namespaces | +| `internal/shared/executor/executor.go` | `RealCommandExecutor`: subprocess runner; WSL detection and wake-up utilities | +| `internal/shared/executor/mock.go` | `MockCommandExecutor`: test double with pattern-matched responses | +| `internal/shared/config/transport.go` | `ApplyInsecureTLSConfig()`: disables TLS verification for local k3d clusters | +| `internal/shared/errors/errors.go` | Typed errors: `ValidationError`, `BranchNotFoundError`, `AlreadyHandledError` | +| `internal/shared/ui/logo.go` | OpenFrame ASCII logo with terminal detection and `TestMode` suppression | +| `internal/shared/ui/prompts.go` | `SelectFromList`, `ConfirmAction`, `GetInput` — all interactive UI primitives | +| `internal/cluster/utils/cmd_helpers.go` | `WrapCommandWithCommonSetup()`, `GetCommandService()`, global flag container management | +| `internal/cluster/models/flags.go` | All flag structs + `ValidateClusterName()`, `ValidateCreateFlags()` etc. | + +--- + +## Dependencies + +OpenFrame CLI uses the following key libraries: + +| Library | Usage | +|---------|-------| +| `github.com/spf13/cobra` | CLI framework — all commands, flags, `PersistentPreRunE`, usage templates | +| `github.com/pterm/pterm` | Rich terminal UI — spinners, tables, boxes, progress indicators, colored output | +| `github.com/manifoldco/promptui` | Interactive selection menus and text prompts (select, confirm, text input) | +| `k8s.io/client-go` | Native Kubernetes API client — used by ArgoCD manager and Helm manager to interact with cluster | +| `github.com/argoproj/argo-cd/v2` | ArgoCD generated client — used to list and poll `Application` CRDs via the versioned clientset | +| `k8s.io/apiextensions-apiserver` | CRD client — used to verify ArgoCD CRDs are installed before polling applications | +| `k8s.io/apimachinery` | Kubernetes type system — `metav1`, `unstructured`, `schema`, `wait` utilities | +| `sigs.k8s.io/controller-runtime` | Used indirectly via ArgoCD client dependencies | +| `gopkg.in/yaml.v3` | YAML parsing and writing for `helm-values.yaml` and cluster config files | +| `golang.org/x/term` | Raw terminal mode for single-keystroke confirmation prompts | + +The native Go Kubernetes clients (`k8s.io/client-go`, ArgoCD clientset) are the most strategically important dependencies — they allow the CLI to watch ArgoCD Application health status directly via the API server instead of shelling out to `kubectl`, providing reliable multi-platform behavior especially on Windows/WSL2 where subprocess path resolution is fragile. + +--- + +## CLI Commands + +### Top-Level Commands + +| Command | Alias | Description | +|---------|-------|-------------| +| `openframe bootstrap` | — | One-command full environment setup (cluster + charts) | +| `openframe cluster` | `k` | Manage Kubernetes clusters | +| `openframe chart` | `c` | Manage Helm charts and ArgoCD | +| `openframe dev` | `d` | Development workflow tools | + +### `openframe bootstrap` + +```bash +# Interactive mode (prompts for cluster name and deployment mode) +openframe bootstrap + +# Bootstrap with custom cluster name +openframe bootstrap my-cluster + +# Skip deployment mode selection (OSS tenant) +openframe bootstrap --deployment-mode=oss-tenant + +# Fully non-interactive for CI/CD +openframe bootstrap --deployment-mode=saas-shared --non-interactive + +# Verbose output showing ArgoCD sync progress +openframe bootstrap -v --deployment-mode=oss-tenant +``` + +**Flags:** + +| Flag | Description | +|------|-------------| +| `--deployment-mode` | `oss-tenant`, `saas-tenant`, or `saas-shared` (skips interactive selection) | +| `--non-interactive` | Skip all prompts; requires `--deployment-mode` | +| `-v, --verbose` | Show detailed logging including ArgoCD sync progress | + +--- + +### `openframe cluster` + +```bash +openframe cluster create # Interactive wizard +openframe cluster create my-cluster # Custom name, interactive +openframe cluster create --skip-wizard # Defaults only, no wizard +openframe cluster create --nodes 3 --type k3d --skip-wizard + +openframe cluster delete my-cluster # Delete with confirmation +openframe cluster delete my-cluster --force # Skip confirmation + +openframe cluster list # List all clusters +openframe cluster list --quiet # Names only + +openframe cluster status my-cluster # Cluster health overview +openframe cluster status my-cluster --detailed # Include resource usage +openframe cluster status --no-apps # Skip ArgoCD app status + +openframe cluster cleanup my-cluster # Free disk space +openframe cluster cleanup my-cluster --force # Aggressive cleanup +``` + +--- + +### `openframe chart` + +```bash +openframe chart install # Interactive mode +openframe chart install my-cluster # Target specific cluster +openframe chart install --deployment-mode=oss-tenant # Pre-select mode +openframe chart install --deployment-mode=saas-shared --non-interactive +openframe chart install --github-branch develop # Use develop branch +``` + +**Flags:** + +| Flag | Description | +|------|-------------| +| `--deployment-mode` | `oss-tenant`, `saas-tenant`, `saas-shared` | +| `--non-interactive` | Skip interactive prompts | +| `--github-repo` | Override GitHub repository URL | +| `--github-branch` | Override Git branch (default: reads from `helm-values.yaml`) | +| `--cert-dir` | Override certificate directory path | +| `--force` | Force reinstall even if already installed | +| `--dry-run` | Validate configuration without executing | +| `-v, --verbose` | Detailed output including ArgoCD sync logs | + +--- + +### `openframe dev` + +```bash +# Intercept: route cluster service traffic to local port +openframe dev intercept # Interactive: select cluster, service, port +openframe dev intercept my-service --port 8080 +openframe dev intercept my-service --port 8080 --namespace my-ns +openframe dev intercept my-service --global # All traffic, not just header-matched +openframe dev intercept my-service --replace # Replace existing intercept + +# Skaffold: live reload development workflow +openframe dev skaffold # Interactive: discover skaffold.yaml +openframe dev skaffold my-dev-cluster # Target specific cluster +openframe dev skaffold --skip-bootstrap # Skip chart reinstall step +openframe dev skaffold --helm-values ./my-values.yaml +``` + +--- + +### Global Flags (all commands) + +| Flag | Description | +|------|-------------| +| `-v, --verbose` | Enable verbose output | +| `--silent` | Suppress all output except errors | +| `--version` | Show version, commit, and build date | diff --git a/internal/chart/providers/argocd/.applications.md b/internal/chart/providers/argocd/.applications.md index 47096c92..26aa7154 100644 --- a/internal/chart/providers/argocd/.applications.md +++ b/internal/chart/providers/argocd/.applications.md @@ -1,48 +1,30 @@ - -This Go file provides ArgoCD application management functionality with support for both native Kubernetes API clients and kubectl fallback operations, specifically designed for k3d cluster environments. + +Manages ArgoCD application state by providing constructors for the `Manager` type and helpers to discover expected application counts via native Kubernetes clients or `kubectl` fallback. ## Key Components -### Manager Struct -- **Manager**: Primary ArgoCD manager with command executor and multiple Kubernetes client interfaces -- **NewManager()**: Basic constructor with command executor -- **NewManagerWithCluster()**: Constructor with explicit cluster context -- **NewManagerWithConfig()**: Preferred constructor with pre-configured Kubernetes client - -### Application Types -- **Application**: Represents ArgoCD application status with health, sync, and operational details -- **argoApp/argoAppList**: Internal JSON parsing structures for kubectl output - -### Core Methods -- **initKubernetesClients()**: Lazy initialization of native Kubernetes clients with TLS bypass for local clusters -- **getTotalExpectedApplications()**: Determines expected application count using native clients or kubectl fallback -- **parseApplications()**: Retrieves ArgoCD application status (implementation appears truncated) +- **`Manager`** — Central struct holding a `CommandExecutor`, optional cluster name, native Kubernetes/ArgoCD clients (`kubeClient`, `apiextClient`, `argocdClient`), and a `StabilizationChecks` tuning field. +- **`NewManager`** / **`NewManagerWithCluster`** / **`NewManagerWithConfig`** — Three constructors covering progressively richer initialization: bare executor, executor + cluster name, and executor + pre-built `*rest.Config` (preferred when a config already exists). +- **`initKubernetesClients()`** — Lazy initializer that builds a `*rest.Config` from the kubeconfig file, applies insecure TLS for local k3d clusters, normalizes the host on Windows, and wires all three clients. +- **`getTotalExpectedApplications()`** — Determines how many ArgoCD `Application` resources are expected. Uses the native ArgoCD client (inspects `app-of-apps` status resources, then falls back to listing all apps), or delegates to `getTotalExpectedApplicationsViaKubectl` on Windows. +- **`getTotalExpectedApplicationsViaKubectl()`** — `kubectl`-based fallback: first reads `app-of-apps` status via `jsonpath`, then lists all applications as JSON and parses with `argoAppList`. +- **`Application`** / **`argoApp`** / **`argoAppList`** — Data models representing ArgoCD application health, sync, condition, and source metadata. ## Usage Example ```go -import ( - "context" - "github.com/flamingo-stack/openframe-cli/internal/shared/executor" -) - -// Basic usage with command executor -exec := executor.NewCommandExecutor() -manager := argocd.NewManager(exec) - -// Usage with specific cluster context -manager = argocd.NewManagerWithCluster(exec, "openframe") - -// Usage with pre-configured Kubernetes config (preferred) -manager, err := argocd.NewManagerWithConfig(exec, kubeConfig) +// Preferred: pass an existing rest.Config (e.g., after cluster creation) +mgr, err := argocd.NewManagerWithConfig(exec, restConfig) if err != nil { log.Fatal(err) } -// Get total expected applications -ctx := context.Background() -count := manager.getTotalExpectedApplications(ctx, config) -fmt.Printf("Expected applications: %d\n", count) +// Or use a named cluster context +mgr := argocd.NewManagerWithCluster(exec, "openframe") + +// Discover expected application count before waiting +total := mgr.getTotalExpectedApplications(ctx, installConfig) +fmt.Printf("Expecting %d ArgoCD applications\n", total) ``` -The manager includes Windows-specific handling for k3d clusters and provides both native Kubernetes API access and kubectl command fallbacks for reliability across different environments. \ No newline at end of file +> **Note:** On Windows, native client calls are skipped automatically because the k3d API server port is only reachable from inside WSL. All operations fall back to `kubectl` executed through the WSL wrapper. \ No newline at end of file diff --git a/internal/chart/providers/argocd/.argocd_values.md b/internal/chart/providers/argocd/.argocd_values.md index 9c1233df..ef48f622 100644 --- a/internal/chart/providers/argocd/.argocd_values.md +++ b/internal/chart/providers/argocd/.argocd_values.md @@ -1,19 +1,26 @@ - -Provides pre-configured Helm chart values for ArgoCD deployment with optimized resource allocation and monitoring integration. + +Provides the ArgoCD Helm chart values configuration as a Go string literal, used to deploy and configure ArgoCD within the OpenFrame platform. ## Key Components -- **GetArgoCDValues()** - Returns a complete YAML configuration string for ArgoCD Helm chart deployment +- **`GetArgoCDValues() string`** — Returns a YAML string containing the full ArgoCD Helm chart values, including resource limits, pod annotations, and custom health checks. -## Configuration Features +## Configuration Overview -The returned YAML includes: +| Component | CPU Request/Limit | Memory Request/Limit | +|---|---|---| +| `controller` | 200m / 400m | 800Mi / 1Gi | +| `server` | 200m / 300m | 400Mi / 600Mi | +| `repoServer` | 200m / 400m | 400Mi / 800Mi | +| `redis` | 50m / 100m | 64Mi / 128Mi | +| `dex` | 50m / 100m | 64Mi / 128Mi | +| `applicationSet` | 50m / 100m | 64Mi / 128Mi | +| `notifications` | 50m / 100m | 64Mi / 128Mi | -- **Custom Health Checks** - Application health status monitoring via Lua script -- **Resource Limits** - CPU and memory constraints for all ArgoCD components -- **Loki Integration** - Pod annotations for log scraping (`loki.grafana.com/scrape: "true"`) -- **Extended Timeouts** - Controller sync timeout (1800s) and repo server exec timeout (180s) -- **Component Scaling** - Optimized resource requests/limits for controller, server, repo server, Redis, Dex, ApplicationSet, and notifications +Notable settings: +- All pods are annotated for **Loki log scraping** (`loki.grafana.com/scrape: "true"`) +- Custom Lua health check for `argoproj.io/Application` resources +- Sync timeout set to `1800s` and repo server exec timeout to `180s` ## Usage Example @@ -22,25 +29,11 @@ package main import ( "fmt" - "github.com/your-org/your-project/argocd" + "github.com/flamingo-stack/openframe/argocd" ) func main() { - // Get ArgoCD Helm values for deployment values := argocd.GetArgoCDValues() - - // Write to values.yaml file for Helm deployment - err := os.WriteFile("argocd-values.yaml", []byte(values), 0644) - if err != nil { - log.Fatal(err) - } - - // Or use directly with Helm Go SDK - fmt.Println("ArgoCD values configured with:") - fmt.Println("- Resource limits for all components") - fmt.Println("- Loki scraping enabled") - fmt.Println("- Custom health checks") + fmt.Println(values) // Pass to Helm install/upgrade } -``` - -The configuration optimizes ArgoCD for production use with appropriate resource constraints and observability features. \ No newline at end of file +``` \ No newline at end of file diff --git a/internal/chart/providers/argocd/.wait.md b/internal/chart/providers/argocd/.wait.md index 8dd7d7ef..d624deb9 100644 --- a/internal/chart/providers/argocd/.wait.md +++ b/internal/chart/providers/argocd/.wait.md @@ -1,41 +1,34 @@ - -This file provides ArgoCD application monitoring and synchronization logic for OpenFrame CLI deployments. + +Monitors ArgoCD application deployment health by waiting for all applications to reach `Healthy` and `Synced` states, with built-in resilience for cluster connectivity issues, Windows/WSL environments, and repo-server recovery. ## Key Components -- **WaitForApplications()** - Main function that waits for all ArgoCD applications to reach Healthy and Synced status -- **Context Management** - Handles cancellation signals, timeouts, and graceful shutdown via signal handlers -- **Health Monitoring** - Periodic cluster connectivity checks and resource monitoring during bootstrap and main phases -- **Progress Tracking** - Visual spinner with timer and verbose logging for application synchronization progress -- **Recovery Logic** - WSL-specific recovery mechanisms and repo-server issue detection/recovery -- **Timeout Handling** - 60-minute timeout with early exit conditions for dry-run mode and cancelled contexts +- **`WaitForApplications(ctx, config)`** — Main entry point. Orchestrates the full wait lifecycle including dry-run bypass, signal handling, bootstrap phase, and main monitoring loop. +- **Bootstrap phase** — 30-second initial wait with 5-second cluster health checks before beginning application polling. +- **Main monitoring loop** — Polls applications every 2 seconds up to a 60-minute timeout, tracking `everReadyApps` to handle transient sync fluctuations. +- **Connectivity error handling** — Detects `connection refused`, `cluster unreachable`, and `WSL error` patterns; applies exponential backoff (capped at 10s) across up to 5 consecutive failures. +- **WSL recovery** — On `runtime.GOOS == "windows"`, calls `executor.TryRecoverWSL()` before exhausting failure retries. +- **Repo-server health tracking** — Monitors ArgoCD repo-server with per-app failure counters (`appsWithRepoServerIssues`), triggers proactive recovery for OOM/resource issues. +- **Spinner management** — Thread-safe `pterm` spinner with `sync.Mutex`; suppressed in `Silent` mode; stopped immediately on context cancellation or interrupt signal. +- **Stabilization checks** — Requires `consecutiveAllReady` to reach a configurable threshold (default: 15 × 2s = 30s) before declaring success. ## Usage Example ```go -// Initialize ArgoCD manager -manager := &Manager{ - clusterName: "my-cluster", -} +mgr := argocd.NewManager(kubeClient) +mgr.StabilizationChecks = 10 // optional: override default 15 -// Configure installation -config := config.ChartInstallConfig{ - ClusterName: "my-cluster", +cfg := config.ChartInstallConfig{ + ClusterName: "kind-openframe", Verbose: true, DryRun: false, Silent: false, - SkipCRDs: false, } -// Wait for applications with context timeout -ctx, cancel := context.WithTimeout(context.Background(), 60*time.Minute) +ctx, cancel := context.WithTimeout(context.Background(), 45*time.Minute) defer cancel() -// Monitor ArgoCD application synchronization -err := manager.WaitForApplications(ctx, config) -if err != nil { - log.Fatalf("Failed to wait for ArgoCD applications: %v", err) +if err := mgr.WaitForApplications(ctx, cfg); err != nil { + log.Fatalf("ArgoCD apps failed to stabilize: %v", err) } -``` - -The function includes comprehensive error handling for cluster connectivity issues, WSL recovery on Windows systems, and graceful handling of interrupt signals during long-running synchronization operations. \ No newline at end of file +``` \ No newline at end of file diff --git a/internal/chart/providers/helm/.manager.md b/internal/chart/providers/helm/.manager.md index a21dbb18..ada52b0f 100644 --- a/internal/chart/providers/helm/.manager.md +++ b/internal/chart/providers/helm/.manager.md @@ -1,48 +1,48 @@ - -A comprehensive Helm operations manager for OpenFrame that handles chart installations, Kubernetes cluster operations, and ArgoCD deployment with support for both Windows and Linux environments. + +Manages Helm chart installations and Kubernetes resource operations, providing methods to install, verify, and configure Helm releases (primarily ArgoCD) against local k3d clusters with native Go Kubernetes client support and graceful fallbacks. ## Key Components -- **HelmManager**: Main struct containing Kubernetes clients and command executor -- **NewHelmManager()**: Constructor that initializes Kubernetes clients with TLS bypass for local clusters -- **IsHelmInstalled()**: Verifies Helm CLI availability -- **IsChartInstalled()**: Checks if a Helm release exists in a namespace -- **InstallArgoCD()**: Core ArgoCD installation with Helm -- **InstallArgoCDWithProgress()**: ArgoCD installation with progress indicators and cluster connectivity verification -- **getHelmEnv()**: Platform-specific environment configuration for Helm directories +- **`HelmManager`** — Core struct holding a command executor, Kubernetes REST config, dynamic client, typed client, CRD client, and verbosity flag. +- **`NewHelmManager`** — Constructor that initializes all Kubernetes clients from a `rest.Config`, applies insecure TLS for local k3d clusters, and degrades gracefully when individual clients fail to initialize. +- **`getHelmEnv`** — Returns environment variable overrides pointing Helm cache/config/data to `/tmp/helm/*`, with Windows/WSL-aware directory creation. +- **`IsHelmInstalled`** — Validates Helm CLI availability by running `helm version --short`. +- **`IsChartInstalled`** — Checks whether a named Helm release exists in a given namespace using `helm list`. +- **`InstallArgoCD`** — Installs ArgoCD via `helm upgrade --install` with a pinned chart version (`8.2.7`), a temp values file, CRD installation skipped (`crds.install=false`), and optional dry-run support. +- **`InstallArgoCDWithProgress`** — Wraps `InstallArgoCD` logic with `pterm` spinner/progress output, cluster connectivity retries, and an optional pre-flight CRD installation step via the native Go client. ## Usage Example ```go -// Initialize Helm manager with Kubernetes config -config, err := rest.InClusterConfig() +import ( + "context" + "github.com/flamingo-stack/openframe-cli/internal/chart/helm" + "github.com/flamingo-stack/openframe-cli/internal/chart/utils/config" + "github.com/flamingo-stack/openframe-cli/internal/shared/executor" + "k8s.io/client-go/tools/clientcmd" +) + +restCfg, _ := clientcmd.BuildConfigFromFlags("", kubeConfigPath) +exec := executor.NewDefaultExecutor() + +mgr, err := helm.NewHelmManager(exec, restCfg, true) if err != nil { - return err + log.Fatal(err) } -executor := executor.NewCommandExecutor() -helmManager, err := NewHelmManager(executor, config, true) -if err != nil { - return err -} - -// Check if Helm is available ctx := context.Background() -if err := helmManager.IsHelmInstalled(ctx); err != nil { - return fmt.Errorf("helm not available: %w", err) +if err := mgr.IsHelmInstalled(ctx); err != nil { + log.Fatal("Helm not found on PATH") } -// Install ArgoCD with configuration -installConfig := config.ChartInstallConfig{ - ClusterName: "my-cluster", - DryRun: false, - Verbose: true, -} - -err = helmManager.InstallArgoCDWithProgress(ctx, installConfig) -if err != nil { - return fmt.Errorf("argocd installation failed: %w", err) +installed, _ := mgr.IsChartInstalled(ctx, "argo-cd", "argocd") +if !installed { + err = mgr.InstallArgoCDWithProgress(ctx, config.ChartInstallConfig{ + ClusterName: "openframe", + Verbose: true, + SkipCRDs: false, + }) } ``` -The manager provides robust error handling, platform compatibility (Windows/WSL support), and comprehensive logging for Helm operations within the OpenFrame ecosystem. \ No newline at end of file +> **Note:** When `rest.Config` is `nil`, `NewHelmManager` returns a reduced manager that can still run Helm CLI commands but lacks native Kubernetes API access for CRD and deployment verification. \ No newline at end of file