Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions .clinerules/build-and-deployment.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
globs: "Makefile,main.go,go.mod,go.sum,goreleaser.yml"
description: "Build system and deployment guidelines for the Golang project"
---

# Build and Deployment Guide

## Build System

### Primary Build Tool
**IMPORTANT:** Always use [Makefile](mdc:Makefile) instead of direct `go build` commands. The Makefile handles cross-compilation, version injection, formatting, and tidying.

```bash
# Correct way to build
make # Builds the default binary (onctl)
make clean # Cleans up binary
make test # Runs all tests
make lint # Lints the code
make coverage # Generates and opens coverage report
make release # Creates release using Goreleaser

# Avoid direct go commands
go build ./... # Don't do this - use make instead
go test ./... # Don't do this - use make test
```

The Makefile performs:
- `go mod tidy` to ensure dependencies
- `go fmt ./...` for code formatting
- `go build` with ldflags for version (`git rev-parse HEAD | cut -c1-7`), build time, and Go version
- CGO_ENABLED=0 for static binary

### Dependencies ([go.mod](mdc:go.mod))
Manage dependencies via `go mod tidy` in the Makefile. Key dependencies include:
- Cobra for CLI framework
- Cloud provider SDKs (e.g., aws-sdk-go, hcloud)
- SSH libraries (golang.org/x/crypto/ssh)
- Viper for configuration
- Testify for testing
- Golangci-lint for linting
- Goreleaser for releases

Update dependencies by running `make` or directly `go mod tidy` if needed, but prefer Makefile.

### Release Artifacts
Releases are built using [goreleaser.yml](mdc:goreleaser.yml) via `make release`. Artifacts are generated for multiple platforms:
- macOS (amd64, arm64)
- Linux (amd64, arm64)
- Windows (amd64)

Stored in dist/ directory with versioned folders.

## Development Workflow

### Code Quality
- Run `make lint` before commits (uses golangci-lint)
- Maintain test coverage (target 20%+; current ~18%)
- Follow Go conventions: proper error handling, no unused imports

### Testing
- `make test` for full suite: `go test ./...`
- Coverage: `make coverage` generates HTML report and opens it

### Deployment Considerations
- Binary is statically linked (CGO_ENABLED=0)
- Supports multi-platform builds via Goreleaser
- Versioning: Injected via ldflags from git commit and build time
- Distribution: Use Homebrew formula or direct binary download

Always commit with clean state: run `make` to build and lint before pushing.
42 changes: 42 additions & 0 deletions .clinerules/dependencies.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
globs: "go.mod,go.sum"
description: "Go dependency management guidelines for the Golang project"
---

# Dependencies Guide

## Managing Dependencies

Dependencies are managed using Go modules with [go.mod](mdc:go.mod) as the primary file. Use the Makefile to handle dependency updates to ensure consistency.

### Key Dependencies
The project relies on several key libraries:
- **Cobra**: For the CLI framework and command structure
- **Cloud Provider SDKs**:
- `aws-sdk-go` for AWS
- `azure-sdk-for-go` for Azure
- `google-cloud-go` for GCP
- `hcloud-go` for Hetzner Cloud
- **SSH Libraries**: `golang.org/x/crypto/ssh` for secure connections
- **Viper**: For configuration management
- **Testify**: For testing assertions and mocks
- **Golangci-lint**: For code linting
- **Goreleaser**: For release automation

### Updating Dependencies
- Run `make` to automatically execute `go mod tidy` which adds missing dependencies and removes unused ones.
- For new dependencies: Add with `go get <package>`, then run `make` to tidy and build.
- Avoid manual `go mod tidy` when possible; use the build process.
- Commit both `go.mod` and `go.sum` to ensure reproducible builds.

### Version Policy
- Pin major versions where possible for stability (e.g., `github.com/spf13/cobra v1.8.0`).
- Update dependencies regularly but test thoroughly before merging.
- Use `go list -m all` to see current module versions.

## Development Tips
- If a dependency conflict arises, resolve with `go mod tidy` via Makefile.
- For vendor mode (if needed): `go mod vendor`, but prefer standard modules.
- Check compatibility with Go version in `go.mod` (requires Go 1.21 or later for this project).

Always run `make lint` after dependency changes to ensure no issues.
54 changes: 54 additions & 0 deletions .clinerules/project-structure.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
alwaysApply: true
description: "Project structure and architecture guide for onctl"
---

# OnCtl Project Structure

OnCtl is a Go-based CLI tool for managing cloud VMs across multiple providers (AWS, Azure, GCP, Hetzner).

## Main Entry Point
- [main.go](mdc:main.go) - Application entry point
- [Makefile](mdc:Makefile) - Build system (use `make` instead of `go build` directly)

## Core Architecture

### Command Layer (`cmd/`)
- [cmd/root.go](mdc:cmd/root.go) - Root command and provider initialization
- [cmd/common.go](mdc:cmd/common.go) - Shared utilities and helper functions
- [cmd/create.go](mdc:cmd/create.go) - VM creation commands
- [cmd/destroy.go](mdc:cmd/destroy.go) - VM destruction commands
- [cmd/list.go](mdc:cmd/list.go) - VM listing commands
- [cmd/ssh.go](mdc:cmd/ssh.go) - SSH connection commands
- [cmd/network.go](mdc:cmd/network.go) - Network management commands
- [cmd/vm.go](mdc:cmd/vm.go) - VM-specific operations

### Cloud Providers (`internal/cloud/`)
- [internal/cloud/cloud.go](mdc:internal/cloud/cloud.go) - Common cloud interfaces
- [internal/cloud/aws.go](mdc:internal/cloud/aws.go) - AWS implementation
- [internal/cloud/azure.go](mdc:internal/cloud/azure.go) - Azure implementation
- [internal/cloud/gcp.go](mdc:internal/cloud/gcp.go) - GCP implementation
- [internal/cloud/hetzner.go](mdc:internal/cloud/hetzner.go) - Hetzner implementation

### Provider-Specific Helpers
- [internal/provideraws/common.go](mdc:internal/provideraws/common.go) - AWS-specific utilities
- [internal/providerazure/common.go](mdc:internal/providerazure/common.go) - Azure-specific utilities
- [internal/providergcp/common.go](mdc:internal/providergcp/common.go) - GCP-specific utilities
- [internal/providerhtz/common.go](mdc:internal/providerhtz/common.go) - Hetzner-specific utilities

### Tools and Utilities (`internal/tools/`)
- [internal/tools/remote-run.go](mdc:internal/tools/remote-run.go) - Remote command execution
- [internal/tools/scp.go](mdc:internal/tools/scp.go) - File transfer operations
- [internal/tools/ssh.go](mdc:internal/tools/ssh.go) - SSH utilities
- [internal/tools/cloud-init.go](mdc:internal/tools/cloud-init.go) - Cloud-init helpers
- [internal/files/embed.go](mdc:internal/files/embed.go) - Embedded files

### Configuration
- [examples/](mdc:examples/) - Example configuration files
- Configuration is handled through Viper in [cmd/common.go](mdc:cmd/common.go)

## Key Patterns
- All cloud providers implement common interfaces defined in `cloud.go`
- Remote operations use SSH with optional jumphost support
- Configuration merging prioritizes command-line flags over config files
- Error handling follows Go conventions with proper logging
90 changes: 90 additions & 0 deletions .clinerules/testing-guidelines.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
---
globs: "*_test.go"
description: "Testing guidelines and patterns for onctl"
---

# OnCtl Testing Guidelines

## Testing Strategy

### Coverage Goals
- **Target overall coverage:** 20%+ (currently at 18.0%)
- **Priority areas:** Core business logic, data transformations, utilities
- **Avoid testing:** Complex integrations requiring real cloud resources

### Test File Organization
- Test files follow `*_test.go` naming convention
- Place tests in the same package as the code being tested
- Group related tests using descriptive function names with prefixes

### Successful Test Patterns

#### 1. Pure Function Testing (Preferred)
Focus on functions with clear inputs/outputs:
```go
func TestMapHetznerServer(t *testing.T) {
server := hcloud.Server{
ID: 123,
Name: "test-server",
// ... setup data
}

result := mapHetznerServer(server)

assert.Equal(t, "hetzner", result.Provider)
assert.Equal(t, "123", result.ID)
}
```

#### 2. Configuration Parsing Tests
Test configuration loading and validation:
```go
func TestParseDotEnvFile(t *testing.T) {
tempDir := t.TempDir()
envFile := filepath.Join(tempDir, ".env")

envContent := `VAR1=value1\nVAR2=value2`
err := os.WriteFile(envFile, []byte(envContent), 0644)
assert.NoError(t, err)

vars, err := ParseDotEnvFile(envFile)
assert.NoError(t, err)
assert.Equal(t, []string{"VAR1=value1", "VAR2=value2"}, vars)
}
```

#### 3. Error Handling Tests
Always test error conditions:
```go
func TestParseDotEnvFile_NonExistent(t *testing.T) {
_, err := ParseDotEnvFile("/nonexistent/.env")
assert.Error(t, err)
}
```

### What NOT to Test
- SSH connections requiring real servers
- Cloud provider APIs requiring credentials
- File operations that modify system directories
- Interactive terminal input/output

### Test Utilities
- Use `t.TempDir()` for temporary directories
- Use `assert.NoError(t, err)` for error checking
- Use table-driven tests for multiple scenarios
- Clean up resources in defer statements

### Linting Requirements
- Always check error return values: `err := file.Close(); assert.NoError(t, err)`
- Use proper error handling patterns
- Follow golangci-lint rules strictly

### Mock Usage
- Use testify/mock for complex dependencies
- Keep mocks simple and focused
- Prefer testing real implementations when possible

### Running Tests
Use the Makefile for testing:
- `make test` - Runs all tests with `go test ./...`
- `make coverage` - Generates HTML coverage report and opens it
99 changes: 99 additions & 0 deletions .cursor/rules/build-and-deployment.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
---
globs: "Makefile,main.go,go.mod,go.sum,.github/**/*,dist/**/*"
description: "Build system and deployment guidelines"
---

# Build and Deployment Guide

## Build System

### Primary Build Tool
**IMPORTANT:** Always use [Makefile](mdc:Makefile) instead of direct `go build` commands.

```bash
# Correct way to build
make

# Avoid direct go build
go build # Don't do this
```

The Makefile handles:
- Cross-compilation for multiple platforms
- Version injection
- Asset embedding
- Release packaging

### Dependencies ([go.mod](mdc:go.mod))
Key dependencies include:
- Cobra for CLI framework
- Cloud provider SDKs (aws-sdk-go, hcloud-go, etc.)
- SSH libraries (golang.org/x/crypto/ssh)
- Testify for testing

### Release Artifacts ([dist/](mdc:dist/))
Built artifacts are stored in `dist/` directory:
- `onctl_darwin_amd64_v1/` - macOS Intel
- `onctl_darwin_arm64_v8.0/` - macOS Apple Silicon
- `onctl-linux_linux_amd64_v1/` - Linux x64
- `onctl-linux_linux_arm64_v8.0/` - Linux ARM64
- `onctl-windows_windows_amd64_v1/` - Windows x64

### Homebrew Formula
- [dist/homebrew/onctl.rb](mdc:dist/homebrew/onctl.rb) - Homebrew formula for macOS installation

## Configuration Management

### Embedded Files ([internal/files/](mdc:internal/files/))
Static files are embedded using Go's embed functionality:
- Cloud-init templates
- Shell scripts for remote execution
- Default configuration templates

### Environment Variables
The application respects these environment variables:
- `CLOUDFLARE_API_TOKEN` - For domain management
- `CLOUDFLARE_ZONE_ID` - DNS zone configuration
- Provider-specific credentials (AWS_*, AZURE_*, etc.)

### Configuration Files
- [examples/](mdc:examples/) - Example configurations
- Support for YAML configuration files
- Command-line flags override config file values

## Development Workflow

### Code Quality
- Run `golangci-lint run --timeout 5m` before commits
- Maintain test coverage above 18% (current target)
- Follow Go conventions and error handling patterns

### Testing
- Use `go test ./...` for full test suite
- Generate coverage reports: `go test -coverprofile=coverage.out ./...`
- Focus testing on pure functions and business logic

### Documentation
- [docs/](mdc:docs/) - Docusaurus-based documentation
- Auto-completion support in [AUTO-COMPLETION.md](mdc:AUTO-COMPLETION.md)
- Configuration examples in [CONFIG-EXAMPLES.md](mdc:CONFIG-EXAMPLES.md)

## Deployment Considerations

### Multi-Platform Support
The application is designed to run on:
- macOS (Intel and Apple Silicon)
- Linux (x64 and ARM64)
- Windows (x64)

### Cloud Provider Authentication
Each provider has specific authentication requirements:
- AWS: IAM credentials or roles
- Azure: Service principal or managed identity
- GCP: Service account keys
- Hetzner: API tokens

### Network Requirements
- SSH access to target VMs (port 22 or custom)
- Cloud provider API access
- Optional: Jumphost/bastion support for private networks
Loading
Loading