rainbond (Agent Skills)

GitHub

A container platform that needs no Kubernetes learning, Build, deploy, assemble, and manage apps on Kubernetes, no K8s expertise needed, all in a graphical platform.

CLAUDE.md

# Rainbond — Go Core Services

## Overview

Rainbond is a cloud-native application management platform. This repository contains the Go backend services that interface directly with Kubernetes. It is called by `rainbond-console` (Django) via HTTP REST APIs.

- Language: Go 1.23
- Module: `github.com/goodrain/rainbond`
- Router: go-chi/chi
- ORM: jinzhu/gorm (v1)
- Logging: sirupsen/logrus
- Vendor: dependencies vendored in `vendor/`

## Binary Components

Entry points in `cmd/`:

| Binary | Description |
|--------|-------------|
| `cmd/api` | REST API server (the main service called by console) |
| `cmd/builder` | Source code build and image build service |
| `cmd/worker` | Application runtime management, Kubernetes operator |
| `cmd/mq` | Message queue service for async tasks |
| `cmd/grctl` | CLI tool for cluster management |
| `cmd/init-probe` | Init container health probe |

## Key Directories

```
api/
  api_routers/version2/  — chi route registration (v2Routers.go)
  controller/            — HTTP handlers (request parsing, response writing)
  handler/               — Business logic layer
  model/                 — API request/response structs
  middleware/             — Auth, tenant context, CORS
  proxy/                 — Reverse proxy utilities
db/
  model/                 — GORM model definitions (database schema)
  dao/                   — Data access objects (CRUD operations)
  mysql/                 — MySQL-specific DAO implementations
builder/                 — Build system (source code, Docker, slug)
worker/                  — Kubernetes controller/operator logic
pkg/
  apis/rainbond/v1alpha1/ — CRD type definitions
  component/             — Shared components (k8s client, storage)
util/
  http/                  — HTTP response helpers (ReturnSuccess, ReturnError, ReturnBcodeError)
```

## Architecture: Request Flow

```
HTTP Request → chi Router → Middleware → Controller → Handler → DAO → Database
                                                        ↓
                                                   Kubernetes API
```

- Controllers: parse HTTP request, validate input, call handler, write response
- Handlers: business logic, orchestrate DAO calls and K8s operations
- DAOs: database CRUD via GORM

## Adding a New API Endpoint

1. Define request/response structs in `api/model/`
2. Add GORM model in `db/model/` if new table needed
3. Add DAO interface in `db/dao/` and implementation in `db/mysql/`
4. Implement business logic in `api/handler/`
5. Add controller method in `api/controller/`
6. Register route in `api/api_routers/version2/v2Routers.go`

## Code Patterns

### Controller Pattern
```go
func (t *TenantStruct) CreateSomething(w http.ResponseWriter, r *http.Request) {
    var req model.CreateSomethingRequest
    if !httputil.ValidatorRequestStructAndErrorResponse(r, w, &req, nil) {
        return
    }
    // Extract context values
    tenantID := r.Context().Value(ctxutil.ContextKey("tenant_id")).(string)

    result, err := handler.GetSomethingHandler().Create(tenantID, &req)
    if err != nil {
        httputil.ReturnBcodeError(r, w, err)
        return
    }
    httputil.ReturnSuccess(r, w, result)
}
```

### Handler Singleton Pattern
```go
// In handler package, handlers are accessed via GetXxxHandler() functions
handler.GetAppHandler().ExportApp(&tr)
handler.GetApplicationHandler().AddConfigGroup(appID, &configReq)
```

### DAO Access Pattern
```go
db.GetManager().AppDao().AddModel(app)
db.GetManager().TenantServiceDao().GetServiceByID(serviceID)
```

## Cross-Repository Relationship

- This repo is called by `rainbond-console` via `www/apiclient/regionapi.py` (RegionInvokeApi)
- API base path: `/v2/tenants/{tenant_name}/...`
- Console sends requests with region token in Authorization header

## Build & Verify

```bash
go build ./...          # Compile all packages
go vet ./...            # Static analysis
make check              # CI lint check (golint on changed files) + test manifest validation
make test-manifest-check # Validate test-manifest.json against capability_id markers
make build              # Build binaries via localbuild.sh
```

## Test Manifest (CI-enforced)

`test-manifest.json` is a registry of behavior-guarding tests. Any test annotated
with a `capability_id` comment is a "managed" test and MUST have a matching entry
in the manifest, otherwise CI fails.

- Marker: `// capability_id: rainbond.<area>.<behavior>` (Go) or
  `# capability_id: ...` (Python), placed directly above the test function.
- Enforced by `scripts/validate_test_manifest.py`, invoked from `make check` and
  `make test-manifest-check`. Runs in CI as the **Check test manifest** step in
  `.github/workflows/pr-ci-build.yml` and `release-v6.yml`.
- `test-manifest.md` is the human-readable table — **auto-generated, never edit by hand**.

### Registering a managed test

Do NOT hand-edit `test-manifest.json`. Use the manager — it inserts in sorted order
and regenerates `test-manifest.md`:

```bash
python3 scripts/manage_test_manifest.py add rainbond.<area>.<behavior> \
  --title "Short English summary" \
  --interface-type workflow \
  --interface "builder/sources.buildKitTomlContent" \
  --code-path builder/sources/image.go \
  --test builder/sources/buildkit_toml_test.go::TestBuildKitTomlContent \
  --test-type regression
```

- `interface_type`: one of `service_method | view_endpoint | handler_method |
  dao_method | package_function | workflow | other` (internal funcs/methods use `workflow`).
- `test_type`: one of `unit | regression | characterization | integration`.
- Repeat `--code-path` / `--test` for multiple values; `--status` defaults to `active`.
- Other subcommands: `list`, `show <id>`, `render` (rebuild the `.md`), `prune <id>`.

## Coding Conventions

- Use `logrus` for all logging (not `log` or `fmt.Println`)
- Use `httputil.ReturnSuccess/ReturnError/ReturnBcodeError` for HTTP responses
- Use `chi.URLParam(r, "param")` for path parameters
- Use `r.Context().Value(ctxutil.ContextKey("key"))` for middleware-injected values
- Run `goimports` before committing
- Error codes defined in `api/util/bcode/`
- Commit messages in English, Conventional Commits format