Skip to content

Commit c5e9159

Browse files
committed
Add AGENTS.md for coding agents
1 parent c7e4b40 commit c5e9159

File tree

1 file changed

+203
-0
lines changed

1 file changed

+203
-0
lines changed

AGENTS.md

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
## Purpose
2+
- **Project:** PHP client for Kubernetes clusters with HTTP/WebSocket support, CRD ergonomics, exec/logs/watch, and JSON Patch/Merge Patch.
3+
- **Audience:** Human contributors and code agents working on features, fixes, or docs.
4+
5+
## Quick Repo Map
6+
- `src/KubernetesCluster.php`: Core client; builds URLs, performs operations (get/create/replace/delete, exec, attach, watch, logs, patch).
7+
- `src/Kinds/*`: First‑class resource wrappers (Pod, Deployment, Service, …) extending `K8sResource` with convenience traits.
8+
- `src/Traits/Cluster/*`: HTTP/WebSocket, auth, kubeconfig loaders, version checks.
9+
- `src/Auth/*`: Token providers (ExecCredential, EKS, OpenShift OAuth, ServiceAccount TokenRequest) with automatic refresh.
10+
- `src/Traits/Resource/*`: Reusable capabilities (spec/status/labels/annotations/templates/scale/etc.).
11+
- `src/K8s.php`: Facade/helper for resource construction, YAML parsing, and CRD registration via macros.
12+
- `src/Patches/*`: `JsonPatch` (RFC 6902) and `JsonMergePatch` (RFC 7396).
13+
- `tests/*`: PHPUnit tests (unit + integration) including testing‑only CRDs under `tests/Kinds`.
14+
15+
## Code Style Requirements
16+
17+
This project uses [Laravel Pint](https://laravel.com/docs/pint) with the Laravel preset to enforce PSR-12 coding standards.
18+
19+
**CRITICAL: Always run Pint before committing PHP code changes:**
20+
```bash
21+
./vendor/bin/pint
22+
```
23+
24+
Pint auto-fixes:
25+
- String concatenation spacing (no spaces around `.`)
26+
- Negation operator spacing (space after `!`)
27+
- Trailing commas in multiline arrays
28+
- Doc block formatting
29+
- Use statement ordering
30+
- Class definition formatting
31+
- PSR-12 compliance
32+
33+
**Manual checks after running Pint:**
34+
1. Doc comments must end with periods: `/** Comment. */`
35+
2. No blank lines before `finally` blocks
36+
37+
**If StyleCI reports issues on PR:**
38+
1. Run `./vendor/bin/pint`
39+
2. Fix any remaining manual issues
40+
3. Commit and push fixes
41+
42+
## Stack & Requirements
43+
- **PHP:** `^8.2` (CI also exercises 8.5).
44+
- **Composer deps:** Guzzle 7, Symfony Process 7.3, Illuminate components, Ratchet Pawl, ext‑json; optional `ext-yaml` for YAML helpers, optional `aws/aws-sdk-php` for native EKS authentication.
45+
- **Static analysis:** Psalm (see `psalm.xml`).
46+
- **License:** Apache‑2.0.
47+
- **Authentication:** Supports tokens, certificates, kubeconfig, in-cluster config, exec credential plugins, AWS EKS native, OpenShift OAuth, and ServiceAccount TokenRequest API.
48+
49+
## Local Dev Setup
50+
- **Install deps:** `composer install`.
51+
- **Update deps:** `composer update`.
52+
- **Run all tests:** `vendor/bin/phpunit`.
53+
- **Run tests (unit only):** `vendor/bin/phpunit --filter Test$` (or target specific files) to avoid cluster requirements.
54+
- **Run specific test file:** `vendor/bin/phpunit tests/PriorityClassTest.php`.
55+
- **Run specific test method:** `vendor/bin/phpunit tests/PriorityClassTest.php --filter test_priority_class_build`.
56+
- **Run with CI environment:** `CI=true vendor/bin/phpunit` (requires running Kubernetes cluster).
57+
- **Static analysis:** `vendor/bin/psalm`.
58+
- **Coding style:** Run `./vendor/bin/pint` before all commits (see "Code Style Requirements" above).
59+
60+
## Running Full Integration Tests Locally
61+
These hit a live Kubernetes cluster and mirror CI.
62+
- **Start cluster:** Minikube is the reference. Example: `minikube start --kubernetes-version=v1.33.1`.
63+
- **Enable addons:** `minikube addons enable volumesnapshots && minikube addons enable csi-hostpath-driver && minikube addons enable metrics-server`.
64+
- **Install VPA:** Clone `kubernetes/autoscaler` and run `./vertical-pod-autoscaler/hack/vpa-up.sh`. Alternatively:
65+
```bash
66+
git clone https://github.com/kubernetes/autoscaler.git /tmp/autoscaler
67+
kubectl apply -f /tmp/autoscaler/vertical-pod-autoscaler/deploy/vpa-v1-crd-gen.yaml
68+
kubectl apply -f /tmp/autoscaler/vertical-pod-autoscaler/deploy/recommender-deployment.yaml
69+
kubectl apply -f /tmp/autoscaler/vertical-pod-autoscaler/deploy/updater-deployment.yaml
70+
kubectl apply -f /tmp/autoscaler/vertical-pod-autoscaler/deploy/admission-controller-deployment.yaml
71+
```
72+
- **Install CRDs:**
73+
- Sealed Secrets CRD: `kubectl apply -f https://raw.githubusercontent.com/bitnami-labs/sealed-secrets/main/helm/sealed-secrets/crds/bitnami.com_sealedsecrets.yaml`
74+
- Gateway API: `kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.3.0/standard-install.yaml`
75+
- **Expose API:** `kubectl proxy --port=8080 --reject-paths="^/non-existent-path" &` (tests use `http://127.0.0.1:8080`).
76+
- **Verify connectivity:** `curl -s http://127.0.0.1:8080/version`.
77+
- **Run tests:** `CI=true vendor/bin/phpunit`.
78+
- **Important:** Tests expect the Kubernetes API accessible at `http://127.0.0.1:8080` (see `tests/TestCase.php`).
79+
80+
## Key Concepts
81+
- **Resources:** Each kind extends `Kinds\K8sResource` and composes traits from `Traits\Resource` for spec/status/metadata helpers.
82+
- Resource pattern: `K8sResource` (base) → Uses Traits (HasSpec, HasStatus, etc.) → Implements Contracts (InteractsWithK8sCluster, Watchable, etc.) → Extended by specific classes (K8sPod, K8sDeployment, etc.)
83+
- Namespaced resources: Set `protected static $namespaceable = true` (most resources)
84+
- Cluster-scoped resources: Set `protected static $namespaceable = false` (nodes, PriorityClass, ClusterRole, etc.)
85+
- **Traits:** Provide composable functionality (`src/Traits/Resource/`)
86+
- `HasSpec` - Manage spec section (most resources)
87+
- `HasStatus` - Read-only status information
88+
- `HasSelector` - Label/field selectors
89+
- `HasMetadata` - Labels, annotations, name, namespace
90+
- `HasReplicas` - Replica management (Deployments, StatefulSets, ReplicaSets)
91+
- `HasPodTemplate` - Pod template spec (workload resources)
92+
- `HasStorage` - Storage configuration (PVCs, PVs)
93+
- **Contracts (Interfaces):** Define capabilities (`src/Contracts/`)
94+
- `InteractsWithK8sCluster` - Basic CRUD operations (get, create, update, delete)
95+
- `Watchable` - Watch operations (event streaming)
96+
- `Scalable` - Scale subresource support
97+
- `Loggable` - Log retrieval (pods, jobs)
98+
- `Executable` - Exec operations (pods)
99+
- **Cluster Ops:** `KubernetesCluster` provides typed creators/getters (e.g., `pod()`, `getPodByName()`, `getAllPods()`), plus `exec`, `attach`, `watch`, `logs`, and patch operations.
100+
- **YAML helpers:** `K8s::fromYaml($cluster, $yaml)` and `K8s::fromYamlFile($cluster, $path)` create object(s) from YAML. Templating is supported via `fromTemplatedYamlFile`.
101+
- **CRDs:** Register custom kinds at runtime with `K8s::registerCrd(YourClass::class, 'alias')` or rely on the unique CRD macro computed from kind + apiVersion.
102+
- **Patching:** Use `$resource->jsonPatch($patch)` or `$resource->jsonMergePatch($patch)` with `Patches\JsonPatch`/`JsonMergePatch` or raw arrays.
103+
- **State tracking:** `isSynced()` - resource has been synced with cluster; `exists()` - resource currently exists in cluster.
104+
105+
## Common Tasks
106+
- **Add a new built-in kind:**
107+
1. Create `src/Kinds/K8sYourKind.php` extending `K8sResource`:
108+
```php
109+
<?php
110+
namespace RenokiCo\PhpK8s\Kinds;
111+
use RenokiCo\PhpK8s\Contracts\InteractsWithK8sCluster;
112+
113+
class K8sYourKind extends K8sResource implements InteractsWithK8sCluster
114+
{
115+
protected static $kind = 'YourKind';
116+
protected static $defaultVersion = 'v1'; // or appropriate apiVersion
117+
protected static $namespaceable = true; // or false for cluster-scoped
118+
119+
// Add resource-specific methods
120+
}
121+
```
122+
2. Add factory method in `src/Traits/InitializesResources.php`:
123+
```php
124+
public static function yourKind($cluster = null, array $attributes = [])
125+
{
126+
return new K8sYourKind($cluster, $attributes);
127+
}
128+
```
129+
3. Create test file `tests/YourKindTest.php` with:
130+
- Unit tests: `test_your_kind_build()`, `test_your_kind_from_yaml()`
131+
- Integration test: `test_your_kind_api_interaction()`
132+
- Run methods: `runCreationTests()`, `runGetAllTests()`, `runGetTests()`, `runUpdateTests()`, `runWatchAllTests()`, `runWatchTests()`, `runDeletionTests()`
133+
- Note: Cluster-scoped resources typically omit watch tests
134+
4. Create YAML fixture in `tests/yaml/yourkind.yaml` for YAML parsing tests
135+
136+
- **Test structure:** (`tests/TestCase.php` sets up cluster at `http://127.0.0.1:8080`)
137+
- Build test: Verify resource construction with fluent API
138+
- YAML test: Load and validate from YAML file
139+
- API interaction test: Orchestrate full CRUD lifecycle
140+
- Creation tests: Create resource, verify `isSynced()` and `exists()`
141+
- Deletion tests: Delete resource, wait for deletion, expect `KubernetesAPIException` on get
142+
- **Add support for a CRD (without bundling it):**
143+
- Create a kind class under `tests/Kinds` (for testing) or a separate package.
144+
- Register with `K8s::registerCrd(...)` in tests or userland.
145+
- Provide YAML examples for `K8s::fromYaml*()` parsing.
146+
- **Extend cluster operations:** Add behavior in `Traits/Cluster/*` or `Traits/RunsClusterOperations.php` with matching tests.
147+
148+
## Style & Quality
149+
- **Tests first:** Add/adjust tests for all behavior changes. Use PHPUnit; integration tests may require a live cluster.
150+
- **API stability:** Follow SemVer; avoid breaking public APIs. Prefer additive changes.
151+
- **Consistency:** Mirror naming and patterns used by existing kinds and traits. Keep methods fluent and chainable where appropriate.
152+
- **Docs:** Update `README.md` and/or add focused docs in `docs/` for new features. Keep examples runnable.
153+
- **Static analysis:** Keep Psalm clean (config at `psalm.xml`).
154+
155+
## PR Checklist
156+
- **Code style:** Run `./vendor/bin/pint` and fix any manual style issues before committing.
157+
- `composer install` completes and `vendor/bin/psalm` passes.
158+
- `vendor/bin/phpunit` passes for unit tests; integration suite passes if you ran a local cluster.
159+
- New options/settings covered with tests.
160+
- Changes are scoped; one concern per PR.
161+
162+
## Gotchas
163+
- **Cluster URL:** Tests default to `http://127.0.0.1:8080` via `kubectl proxy` and disable SSL verification for local runs.
164+
- **Namespace handling:** Cluster-scoped resources (`$namespaceable = false`) should not include namespace in specs or API calls.
165+
- **YAML extension:** `ext-yaml` is optional but required for YAML helpers (parsing/serialization). Guard features accordingly. Tests using `fromYamlFile()` will fail without the yaml PHP extension installed.
166+
- **kubectl Proxy:** Integration tests expect proxy on `http://127.0.0.1:8080` - verify with `curl http://127.0.0.1:8080/version`.
167+
- **Watch tests:** Cluster-scoped resources typically don't implement watch tests (pattern varies).
168+
- **Status vs Spec:** Status is read-only from API; modifications go in spec section.
169+
- **WebSockets:** Exec/attach/watch rely on Ratchet Pawl; ensure TLS headers/certs are passed through from `KubernetesCluster` when touching WS paths.
170+
- **Patches:** Use proper content types (`application/json-patch+json` vs `application/merge-patch+json`). The client handles this if you use the provided patch helpers.
171+
172+
## Current Resource Types (33+)
173+
- **Workload:** Pod, Deployment, StatefulSet, DaemonSet, Job, CronJob, ReplicaSet
174+
- **Networking:** Service, Ingress, NetworkPolicy, EndpointSlice
175+
- **Storage:** PersistentVolume, PersistentVolumeClaim, StorageClass
176+
- **Configuration:** ConfigMap, Secret
177+
- **Autoscaling:** HorizontalPodAutoscaler, VerticalPodAutoscaler
178+
- **Policy:** ResourceQuota, LimitRange, PodDisruptionBudget, NetworkPolicy, PriorityClass
179+
- **RBAC:** ServiceAccount, Role, ClusterRole, RoleBinding, ClusterRoleBinding
180+
- **Webhooks:** ValidatingWebhookConfiguration, MutatingWebhookConfiguration
181+
- **Cluster:** Namespace, Node, Event
182+
183+
## Kubernetes API Versions Reference
184+
- Core resources (Pod, Service, etc.): `v1`
185+
- Apps resources (Deployment, StatefulSet, etc.): `apps/v1`
186+
- Networking: `networking.k8s.io/v1`
187+
- Autoscaling: `autoscaling/v2` (HPA), `autoscaling.k8s.io/v1` (VPA)
188+
- Scheduling: `scheduling.k8s.io/v1`
189+
- Policy: `policy/v1`
190+
- RBAC: `rbac.authorization.k8s.io/v1`
191+
192+
## Releasing & CI (Reference)
193+
- CI matrix runs PHP 8.3/8.4/8.5 across Kubernetes v1.32.9, v1.33.5, v1.34.1 and Laravel 11/12 with both `prefer-lowest` and `prefer-stable`.
194+
- Minikube v1.37.0 is provisioned in CI with VolumeSnapshots, CSI hostpath, metrics‑server, VPA, Sealed Secrets CRD, and Gateway API CRDs before running tests.
195+
- Timeout: 25 minutes per job.
196+
197+
## Useful References
198+
- [Documentation](https://php-k8s.renoki.org)
199+
- [Upstream Repository](https://github.com/renoki-co/php-k8s)
200+
- [Kubernetes API Reference](https://kubernetes.io/docs/reference/kubernetes-api/)
201+
202+
If anything is unclear or you need deeper context for a change, open a draft PR with your approach and questions. Keeping changes small and well‑tested speeds up reviews.
203+

0 commit comments

Comments
 (0)