Skip to content

Commit 035e405

Browse files
authored
doc: add AGENTS.md (#111)
1 parent 4c0ee9f commit 035e405

File tree

2 files changed

+92
-0
lines changed

2 files changed

+92
-0
lines changed

AGENTS.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# AKS FlexNode Agent
2+
3+
Go agent that extends AKS to non-Azure VMs, transforming Ubuntu machines into semi-managed AKS worker nodes.
4+
5+
## Coding Conventions
6+
7+
- **Language**: Go 1.25+. Standard `gofmt`/`goimports` formatting.
8+
- **Linting**: `golangci-lint` with errcheck (type assertions checked), gosec, govet, ineffassign, staticcheck, unused. Run `make lint`.
9+
- **Quality gate**: `make check` runs formatting, vetting, linting, and tests in sequence.
10+
- **Naming**: packages lowercase; files snake_case; unexported types/vars camelCase; exported PascalCase.
11+
- **Errors**: wrap with context via `fmt.Errorf("context: %w", err)`. Use gRPC status codes in `components/`. Never panic in runtime logic.
12+
- **Logging**: logrus with context propagation (`pkg/logger`). Log at appropriate levels — debug for verbose, info for state changes, error for failures.
13+
- **Comments**: explain *why*, not *what*. Reference upstream docs with URLs where relevant.
14+
- **Protobuf**: edition 2024, opaque API with builder pattern. Run `make generate` to regenerate `.pb.go` files.
15+
- **Sensitive data**: never log or return tokens/secrets. Use `Redact()` in components; avoid committing `.env` or credential files.
16+
17+
## Testing
18+
19+
### Conventions
20+
21+
- **Table-driven tests** with named subtests (`t.Run(name, ...)`).
22+
- **Parallel execution**: call `t.Parallel()` in both top-level and sub-tests.
23+
- **Filesystem isolation**: use `t.TempDir()` for any file I/O.
24+
- **Dependency injection**: accept interfaces on structs; use mock implementations in tests (see `pkg/components/arc/` for example).
25+
- **Idempotency**: explicitly test that operations are safe to re-run.
26+
- **No external test frameworks**: use the standard `testing` package only.
27+
28+
### Makefile Targets
29+
30+
Run `make help` to discover all available build, test, and lint targets.
31+
32+
## Key Design Patterns
33+
34+
1. **Idempotent reconciliation** — compare current state with desired state; only mutate when they differ.
35+
2. **Bootstrapper executor** — sequential step execution with fail-fast (bootstrap) or best-effort (unbootstrap) semantics.
36+
3. **Action hub** — single gRPC endpoint dispatches to versioned component handlers by protobuf type URL.
37+
4. **Interface-driven** — depend on interfaces, not concrete types, to enable testing and extensibility.

components/AGENTS.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Components Module
2+
3+
## Design Overview
4+
5+
Action-based plugin architecture for AKS node provisioning. Each component models a discrete node operation (download binaries, configure services, join cluster) as a **protobuf Action** with `Metadata`, `Spec` (desired state), and `Status` (result).
6+
7+
### Architecture
8+
9+
```
10+
Caller → Hub (gRPC server) → component handler
11+
```
12+
13+
- **Hub** (`services/actions/hub.go`): Central dispatcher mapping protobuf type URLs to `Server` implementations.
14+
- **Registration**: Each versioned package registers via `init()` in `exports.go`; top-level `exports.go` triggers all registrations via blank imports.
15+
- **In-memory gRPC** (`services/inmem/`): Same-process action invocation without network overhead.
16+
17+
### Two-Layer Package Structure
18+
19+
- **Parent package** (e.g. `cni/`): Protobuf definitions, defaulting, validation, redaction — the data model layer.
20+
- **Versioned sub-package** (e.g. `cni/v20260301/`): Concrete implementation of actions.
21+
22+
Components are independent of each other. Shared utilities come from `pkg/`.
23+
24+
## Key Principles
25+
26+
1. **Idempotency** — Every action is safe to re-run. Compare current state with desired state; only write/restart when something changed.
27+
2. **Declarative Spec/Status** — Actions declare desired state in `Spec` and report actual state in `Status`.
28+
3. **Default → Validate pipeline** — Use `api.DefaultAndValidate[M]()` for consistent processing.
29+
4. **Security** — Sensitive fields (tokens, secrets) must be redacted via `Redact()` before leaving the Hub.
30+
5. **Separation of concerns** — Data models (proto + defaulting + redaction) in parent package; logic in versioned sub-package.
31+
32+
## Coding Conventions
33+
34+
- **Go** with `gofmt`/`goimports`. Lint via `golangci-lint` (errcheck, gosec, govet, staticcheck, unused). Use `make fmt`, `make lint`, and `make check` to run these.
35+
- **Protobuf edition 2024**, opaque API with builder pattern. Run `make generate` to regenerate `.pb.go` files from `.proto` definitions.
36+
- **Naming**: packages lowercase (`cni`, `kubelet`); files snake_case (`kubelet_config.go`); unexported action types camelCase (`downloadCNIBinariesAction`); factory functions `new*Action()`.
37+
- **Compile-time interface checks**: `var _ actions.Server = (*myAction)(nil)`.
38+
- **Errors**: Use gRPC status codes (`status.Errorf(codes.Internal, ...)`). Wrap with `fmt.Errorf("context: %w", err)`.
39+
- **Embedded assets**: `//go:embed assets/*` with `text/template` for systemd units and config files.
40+
- **Comments**: Explain *why*, not just *what*. Include upstream reference URLs where relevant.
41+
42+
## Adding a New Component
43+
44+
1. Create `components/<name>/` with `action.proto`, `defaulting.go`, `redact.go`.
45+
2. Create `components/<name>/v<component version>/` with `exports.go` (init registration) and action implementation files.
46+
3. Add blank import in `components/exports.go`.
47+
4. Implement `actions.Server` interface; assert at compile time.
48+
5. Place templates in `assets/` subdirectory; embed with `//go:embed`.
49+
50+
## Testing
51+
52+
- Table-driven tests, parallel execution (`t.Parallel()`), `t.TempDir()` for filesystem isolation.
53+
- Test idempotency explicitly.
54+
- Action structs accept interfaces for dependencies to enable test doubles.
55+
- Run: `make test`, `make test-coverage`, `make test-race`.

0 commit comments

Comments
 (0)