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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Contributing to Crane

Thank you for your interest in contributing to Crane! This guide will help you get started.

## Quick Start

1. Fork and clone the repository:
```bash
git clone https://github.com/<your-username>/crane.git
cd crane
```

2. Build the binary:
```bash
go build -o crane main.go
```

3. Run tests:
```bash
go test ./...
```

4. Submit a pull request

## Prerequisites

- **Go** 1.25+ (see `go.mod` for exact version)
- **kubectl** (for deploying output to clusters and for `crane validate` with live cluster mode)
- **Docker** (optional, for container-based testing)
- Access to a Kubernetes cluster (for E2E testing)

## Development Setup

For detailed guides on architecture, testing, and advanced development workflows, see the [Development Documentation](docs/development/README.md).

## Code Standards

### Go Conventions

- Follow standard Go idioms and [Effective Go](https://go.dev/doc/effective_go) practices
- Use `gofmt` for formatting
- Prefer explicit error messages with context — include the actual type received, the API resource being processed, and enough context to debug without re-running

### Error Handling

Error messages must be actionable:

```go
// Good — shows actual object type
fmt.Errorf("expected *unstructured.Unstructured but got %T", object)

// Bad — shows nil pointer
fmt.Errorf("expected *unstructured.Unstructured but got %T", u)
```

### Working with Kubernetes API Objects

- Use `*unstructured.Unstructured` for dynamic resources
- Always check type assertions and provide informative error messages
- Include the actual resource type and API resource name in errors

## Commit and PR Title Conventions

Use verb-first titles that describe what the change does:

- `Fix` for bug fixes (e.g., `Fix transform error on empty namespace`)
- `Add` for new features (e.g., `Add crane validate command`)
- `Update` for enhancements (e.g., `Update crane-lib with resources whiteout`)
- `Refactor` for code restructuring
- `Remove` for removals

Include issue references where applicable: `Fix transform error on empty namespace (#197)`

## Pull Request Guidelines

**Title:** Clear and concise (under 70 characters)

**Body must include:**
- **Summary** — what changed and why
- **Impact** — severity, affected components
- **Test plan** — how to verify

**Before submitting:**

- [ ] Code compiles: `go build ./...`
- [ ] Tests pass: `go test ./...`
- [ ] Error messages are informative
- [ ] No unnecessary refactoring in the same PR
- [ ] Backward compatible (or documented breaking change)

## Testing

- All new features require tests
- Bug fixes should include regression tests when possible
- Use table-driven tests for multiple scenarios
- Test files: `*_test.go` in the same package
- E2E tests: `e2e-tests/`

See [Testing Guide](docs/development/testing.md) for detailed testing documentation.

## Reporting Issues

- Check existing issues before filing a new one
- Include reproduction steps, expected behavior, and actual behavior
- Include Crane version, Go version, and Kubernetes version

## Code of Conduct

Be respectful and constructive. We follow the [Konveyor community guidelines](https://www.konveyor.io/).
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ How does it work? Crane works by:
* `$ cat transform/10_KubernetesPlugin/resources/secret.yaml` - Contains the original exported Secret with all metadata

5. `$ crane apply`
* Runs `kubectl kustomize` on the transform stage to apply patches
* Runs embedded kustomize on the transform stage to apply patches
* Outputs clean, declarative YAML to `output/output.yaml`
* Example:
* `$ cat output/output.yaml`
Expand All @@ -117,6 +117,14 @@ How does it work? Crane works by:
6. The content in `output/output.yaml` is now ready to be deployed to the target cluster or checked into Git for GitOps workflows:
* `$ kubectl apply -f output/output.yaml`

## Documentation

For comprehensive documentation, see the [docs/](docs/README.md) directory:

- [Installation](docs/installation.md)
- [Command Reference](docs/README.md#command-reference) — export, transform, apply, validate, transfer-pvc
- [Contributing](CONTRIBUTING.md) | [Development Guide](docs/development/README.md)

## Further Examples

Please see [konveyor/crane-runner/main/examples](https://github.com/konveyor/crane-runner/tree/main/examples#readme) for further scenarios to explore what can be done with Crane + Tekton for migrating applications.
Expand Down
30 changes: 30 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Crane Documentation

Welcome to the Crane documentation. Crane is a Kubernetes migration tool that helps migrate workloads between clusters using a non-destructive pipeline: **export → transform → apply → validate**.

## Getting Started

- [Installation](./installation.md) — Prerequisites, building, and verifying the Crane binary

## Command Reference

- [`crane export`](./commands/export.md) — Export namespace resources from a source cluster
- [`crane transform`](./commands/transform.md) — Transform exported resources using plugins and Kustomize
- [`crane apply`](./commands/apply.md) — Apply transformations and produce final manifests
- [`crane validate`](./commands/validate.md) — Validate final manifests against a target cluster
- [`crane transfer-pvc`](./commands/transfer-pvc.md) — Transfer PVC data between clusters via rsync

## Concepts

- [Multi-Stage Pipeline](./multistage-pipeline.md) — How Crane's multi-stage Kustomize transform pipeline works
- [Plugins](./plugins.md) — Built-in and custom plugin overview

## Reference

- [Pre-Apply Validation Guide](./pre-apply-validation-guide.md) — Checklist for validating manifests before applying
- [Resource Compatibility](./resource-compatibility.md) — Supported resource types and migration boundaries

## Development

- [Development Guide](./development/README.md) — Architecture, setup, testing, and plugin development
- [Contributing](../CONTRIBUTING.md) — How to contribute to Crane
120 changes: 120 additions & 0 deletions docs/commands/apply.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# crane apply

Apply transformations to exported resources and produce final manifests.

## Synopsis

```bash
crane apply [stage...] [flags]
```

## Description

`crane apply` runs embedded kustomize on each transform stage to apply patches, producing clean, declarative YAML ready for deployment to a target cluster. By default, all stages are applied sequentially to maintain consistency across the pipeline. The output includes both a single multi-document YAML file and individual resource files organized by namespace.

Kustomize is embedded directly in the Crane binary (via the krusty API), so no external `kubectl` dependency is needed.

## Flags

| Flag | Short | Default | Description |
|------|-------|---------|-------------|
| `--export-dir` | `-e` | `export` | The path where exported resources are saved (kept for consistency; not used by apply) |
| `--transform-dir` | `-t` | `transform` | The path where transform stage directories are located |
| `--output-dir` | `-o` | `output` | The path where final manifests are written |
| `--kustomize-args` | | | Additional arguments for kustomize (e.g., `--enable-helm --helm-command=helm3`) |
| `--skip-cluster-scoped` | | `false` | Exclude cluster-scoped resources (ClusterRole, ClusterRoleBinding, CRD, etc.) from output. Useful for non-admin migration scenarios |
| `--overwrite` | | `false` | Overwrite the output directory if it already exists |

Stages are specified as positional arguments (e.g., `crane apply 10_KubernetesPlugin`). Stages can be specified by directory name or plugin name. If no stages are specified, all discovered stages are applied sequentially.

## Output Structure

```text
output/
├── output.yaml # All resources in a single multi-document YAML
└── resources/ # Individual resource files
├── <namespace>/
│ ├── Deployment_apps_v1_<ns>_<name>.yaml
│ ├── Service__v1_<ns>_<name>.yaml
│ └── ConfigMap__v1_<ns>_<name>.yaml
└── _cluster/ # Cluster-scoped resources (when not skipped)
├── ClusterRoleBinding_rbac.authorization.k8s.io_v1_clusterscoped_<name>.yaml
└── ClusterRole_rbac.authorization.k8s.io_v1_clusterscoped_<name>.yaml
```

- **`output.yaml`** — Ready for `kubectl apply -f`
- **`resources/<namespace>/`** — Individual files for selective review or application
- **`resources/_cluster/`** — Cluster-scoped resources (omitted when `--skip-cluster-scoped` is set)

## Examples

### Apply all stages (default)

```bash
crane apply
```

### Apply with custom directories

```bash
crane apply --transform-dir ./migration/transform --output-dir ./migration/output
```

### Apply a specific stage only

```bash
crane apply 10_KubernetesPlugin
```

### Skip cluster-scoped resources (non-admin migration)

When migrating without cluster-admin privileges, use `--skip-cluster-scoped` to exclude ClusterRoles, ClusterRoleBindings, CRDs, and other cluster-scoped resources from the output. These resources typically require admin permissions to create on the target cluster.

```bash
crane apply --skip-cluster-scoped
```

For a complete non-admin migration pipeline:

```bash
crane export -n my-app # Skips inaccessible resources gracefully
crane transform
crane apply --skip-cluster-scoped # Excludes cluster-scoped resources
crane validate --context target-cluster # Or use --api-resources for offline
```

### Pass additional kustomize arguments

```bash
crane apply --kustomize-args "--enable-helm --helm-command=helm3"
```

### Deploy to target cluster

```bash
crane apply
kubectl apply -f output/output.yaml
```

## Common Errors

| Error | Cause | Solution |
|-------|-------|----------|
| `kustomization.yaml validation failed` | Invalid Kustomize syntax or missing resource files | Run `crane apply <stage>` to isolate the failing stage |
| `output directory "X" already exists` | Output directory from a previous run | Use `--overwrite` to replace it |
| `invalid stage name` | Stage name doesn't follow `<number>_<name>` format | Use a valid stage name like `10_KubernetesPlugin` |
| `invalid kustomize-args` | Unsupported or malformed kustomize arguments | Check supported kustomize flags |

## Next Steps

After applying, validate the manifests against your target cluster:

```bash
crane validate --input-dir output --context target-cluster
```

See [crane validate](./validate.md) for details. Or deploy directly:

```bash
kubectl apply -f output/output.yaml
```
Loading
Loading