@intentius/chant-lexicon-k8s 0.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/dist/integrity.json +32 -0
  2. package/dist/manifest.json +8 -0
  3. package/dist/meta.json +1413 -0
  4. package/dist/rules/hardcoded-namespace.ts +56 -0
  5. package/dist/rules/k8s-helpers.ts +149 -0
  6. package/dist/rules/wk8005.ts +59 -0
  7. package/dist/rules/wk8006.ts +68 -0
  8. package/dist/rules/wk8041.ts +73 -0
  9. package/dist/rules/wk8042.ts +48 -0
  10. package/dist/rules/wk8101.ts +65 -0
  11. package/dist/rules/wk8102.ts +42 -0
  12. package/dist/rules/wk8103.ts +45 -0
  13. package/dist/rules/wk8104.ts +69 -0
  14. package/dist/rules/wk8105.ts +45 -0
  15. package/dist/rules/wk8201.ts +55 -0
  16. package/dist/rules/wk8202.ts +46 -0
  17. package/dist/rules/wk8203.ts +46 -0
  18. package/dist/rules/wk8204.ts +54 -0
  19. package/dist/rules/wk8205.ts +56 -0
  20. package/dist/rules/wk8207.ts +45 -0
  21. package/dist/rules/wk8208.ts +45 -0
  22. package/dist/rules/wk8209.ts +45 -0
  23. package/dist/rules/wk8301.ts +51 -0
  24. package/dist/rules/wk8302.ts +46 -0
  25. package/dist/rules/wk8303.ts +96 -0
  26. package/dist/skills/chant-k8s.md +433 -0
  27. package/dist/types/index.d.ts +2934 -0
  28. package/package.json +30 -0
  29. package/src/actions/actions.test.ts +83 -0
  30. package/src/actions/apps.ts +23 -0
  31. package/src/actions/batch.ts +9 -0
  32. package/src/actions/core.ts +62 -0
  33. package/src/actions/index.ts +50 -0
  34. package/src/actions/networking.ts +15 -0
  35. package/src/actions/rbac.ts +13 -0
  36. package/src/codegen/docs-cli.ts +3 -0
  37. package/src/codegen/docs.ts +1147 -0
  38. package/src/codegen/generate-cli.ts +41 -0
  39. package/src/codegen/generate-lexicon.ts +69 -0
  40. package/src/codegen/generate-typescript.ts +97 -0
  41. package/src/codegen/generate.ts +144 -0
  42. package/src/codegen/naming.test.ts +63 -0
  43. package/src/codegen/naming.ts +187 -0
  44. package/src/codegen/package.ts +56 -0
  45. package/src/codegen/patches.ts +108 -0
  46. package/src/codegen/snapshot.test.ts +95 -0
  47. package/src/codegen/typecheck.test.ts +24 -0
  48. package/src/codegen/typecheck.ts +4 -0
  49. package/src/codegen/versions.ts +43 -0
  50. package/src/composites/autoscaled-service.ts +236 -0
  51. package/src/composites/composites.test.ts +1109 -0
  52. package/src/composites/cron-workload.ts +167 -0
  53. package/src/composites/index.ts +14 -0
  54. package/src/composites/namespace-env.ts +163 -0
  55. package/src/composites/node-agent.ts +224 -0
  56. package/src/composites/stateful-app.ts +134 -0
  57. package/src/composites/web-app.ts +180 -0
  58. package/src/composites/worker-pool.ts +230 -0
  59. package/src/coverage.test.ts +27 -0
  60. package/src/coverage.ts +35 -0
  61. package/src/crd/loader.ts +112 -0
  62. package/src/crd/parser.test.ts +217 -0
  63. package/src/crd/parser.ts +279 -0
  64. package/src/crd/types.ts +54 -0
  65. package/src/default-labels.test.ts +111 -0
  66. package/src/default-labels.ts +122 -0
  67. package/src/generated/index.d.ts +2934 -0
  68. package/src/generated/index.ts +203 -0
  69. package/src/generated/lexicon-k8s.json +1413 -0
  70. package/src/generated/runtime.ts +4 -0
  71. package/src/import/generator.test.ts +121 -0
  72. package/src/import/generator.ts +285 -0
  73. package/src/import/parser.test.ts +156 -0
  74. package/src/import/parser.ts +204 -0
  75. package/src/import/roundtrip.test.ts +86 -0
  76. package/src/index.ts +38 -0
  77. package/src/lint/post-synth/k8s-helpers.test.ts +219 -0
  78. package/src/lint/post-synth/k8s-helpers.ts +149 -0
  79. package/src/lint/post-synth/post-synth.test.ts +969 -0
  80. package/src/lint/post-synth/wk8005.ts +59 -0
  81. package/src/lint/post-synth/wk8006.ts +68 -0
  82. package/src/lint/post-synth/wk8041.ts +73 -0
  83. package/src/lint/post-synth/wk8042.ts +48 -0
  84. package/src/lint/post-synth/wk8101.ts +65 -0
  85. package/src/lint/post-synth/wk8102.ts +42 -0
  86. package/src/lint/post-synth/wk8103.ts +45 -0
  87. package/src/lint/post-synth/wk8104.ts +69 -0
  88. package/src/lint/post-synth/wk8105.ts +45 -0
  89. package/src/lint/post-synth/wk8201.ts +55 -0
  90. package/src/lint/post-synth/wk8202.ts +46 -0
  91. package/src/lint/post-synth/wk8203.ts +46 -0
  92. package/src/lint/post-synth/wk8204.ts +54 -0
  93. package/src/lint/post-synth/wk8205.ts +56 -0
  94. package/src/lint/post-synth/wk8207.ts +45 -0
  95. package/src/lint/post-synth/wk8208.ts +45 -0
  96. package/src/lint/post-synth/wk8209.ts +45 -0
  97. package/src/lint/post-synth/wk8301.ts +51 -0
  98. package/src/lint/post-synth/wk8302.ts +46 -0
  99. package/src/lint/post-synth/wk8303.ts +96 -0
  100. package/src/lint/rules/hardcoded-namespace.ts +56 -0
  101. package/src/lint/rules/rules.test.ts +69 -0
  102. package/src/lsp/completions.test.ts +64 -0
  103. package/src/lsp/completions.ts +20 -0
  104. package/src/lsp/hover.test.ts +69 -0
  105. package/src/lsp/hover.ts +68 -0
  106. package/src/package-cli.ts +28 -0
  107. package/src/plugin.test.ts +209 -0
  108. package/src/plugin.ts +915 -0
  109. package/src/serializer.test.ts +275 -0
  110. package/src/serializer.ts +278 -0
  111. package/src/spec/fetch.test.ts +24 -0
  112. package/src/spec/fetch.ts +68 -0
  113. package/src/spec/parse.test.ts +102 -0
  114. package/src/spec/parse.ts +477 -0
  115. package/src/testdata/manifests/configmap.yaml +7 -0
  116. package/src/testdata/manifests/deployment.yaml +22 -0
  117. package/src/testdata/manifests/full-app.yaml +61 -0
  118. package/src/testdata/manifests/secret.yaml +7 -0
  119. package/src/testdata/manifests/service.yaml +15 -0
  120. package/src/validate-cli.ts +21 -0
  121. package/src/validate.test.ts +29 -0
  122. package/src/validate.ts +46 -0
  123. package/src/variables.ts +36 -0
@@ -0,0 +1,433 @@
1
+ ---
2
+ skill: chant-k8s
3
+ description: Build, validate, and deploy Kubernetes manifests from a chant project
4
+ user-invocable: true
5
+ ---
6
+
7
+ # Kubernetes Operational Playbook
8
+
9
+ ## How chant and Kubernetes relate
10
+
11
+ chant is a **synthesis-only** tool — it compiles TypeScript source files into Kubernetes YAML manifests. chant does NOT call the Kubernetes API. Your job as an agent is to bridge the two:
12
+
13
+ - Use **chant** for: build, lint, diff (local YAML comparison)
14
+ - Use **kubectl / k8s API** for: apply, rollback, monitoring, troubleshooting
15
+
16
+ The source of truth for infrastructure is the TypeScript in `src/`. The generated YAML manifests are intermediate artifacts — never edit them by hand.
17
+
18
+ ## Scaffolding a new project
19
+
20
+ ### Initialize with a template
21
+
22
+ ```bash
23
+ chant init --lexicon k8s # default: Deployment + Service
24
+ chant init --lexicon k8s --template microservice # Deployment + Service + HPA + PDB
25
+ chant init --lexicon k8s --template stateful # StatefulSet + PVC + Service
26
+ ```
27
+
28
+ ### Available templates
29
+
30
+ | Template | What it generates | Best for |
31
+ |----------|-------------------|----------|
32
+ | *(default)* | Deployment + Service | Simple stateless apps |
33
+ | `microservice` | Deployment + Service + HPA + PDB | Production microservices |
34
+ | `stateful` | StatefulSet + PVC + headless Service | Databases, caches |
35
+
36
+ ## Build and validate
37
+
38
+ ### Build manifests
39
+
40
+ ```bash
41
+ chant build src/ --output manifests.yaml
42
+ ```
43
+
44
+ Options:
45
+ - `--format yaml` — emit YAML (default for K8s)
46
+ - `--watch` — rebuild on source changes
47
+ - `--output <path>` — write to a specific file
48
+
49
+ ### Lint the source
50
+
51
+ ```bash
52
+ chant lint src/
53
+ ```
54
+
55
+ ### What each step catches
56
+
57
+ | Step | Catches | When to run |
58
+ |------|---------|-------------|
59
+ | `chant lint` | Hardcoded namespaces (WK8001) | Every edit |
60
+ | `chant build` | Post-synth: secrets in env (WK8005), latest tags (WK8006), API keys (WK8041), missing probes (WK8301), no resource limits (WK8201), privileged containers (WK8202), and more | Before apply |
61
+ | `kubectl --dry-run=server` | K8s API validation: schema errors, admission webhooks | Before production apply |
62
+
63
+ ## Deploying to Kubernetes
64
+
65
+ ### Apply manifests
66
+
67
+ ```bash
68
+ # Build
69
+ chant build src/ --output manifests.yaml
70
+
71
+ # Dry run first
72
+ kubectl apply -f manifests.yaml --dry-run=server
73
+
74
+ # Apply
75
+ kubectl apply -f manifests.yaml
76
+ ```
77
+
78
+ ### Check rollout status
79
+
80
+ ```bash
81
+ kubectl rollout status deployment/my-app
82
+ ```
83
+
84
+ ### Rollback
85
+
86
+ ```bash
87
+ kubectl rollout undo deployment/my-app
88
+ kubectl rollout undo deployment/my-app --to-revision=2
89
+ ```
90
+
91
+ ## Debugging strategies
92
+
93
+ ### Check pod status and events
94
+
95
+ ```bash
96
+ # Overview
97
+ kubectl get pods -l app.kubernetes.io/name=my-app
98
+ kubectl get events --sort-by=.lastTimestamp -n <namespace>
99
+
100
+ # Deep dive into a specific pod
101
+ kubectl describe pod <pod-name>
102
+
103
+ # Logs (current and previous crash)
104
+ kubectl logs <pod-name>
105
+ kubectl logs <pod-name> --previous
106
+ kubectl logs <pod-name> -c <container-name> # specific container
107
+ kubectl logs deployment/my-app --all-containers
108
+
109
+ # Debug containers (K8s 1.25+)
110
+ kubectl debug <pod-name> -it --image=busybox --target=<container>
111
+
112
+ # Port-forwarding for local testing
113
+ kubectl port-forward svc/my-app 8080:80
114
+ kubectl port-forward pod/<pod-name> 8080:8080
115
+ ```
116
+
117
+ ### Common error patterns
118
+
119
+ | Status | Meaning | Diagnostic command | Typical fix |
120
+ |--------|---------|-------------------|-------------|
121
+ | Pending | Not scheduled | `kubectl describe pod` → Events | Check resource requests, node selectors, taints, PVC binding |
122
+ | CrashLoopBackOff | App crashing on start | `kubectl logs --previous` | Fix app startup, check probe config, increase initialDelaySeconds |
123
+ | ImagePullBackOff | Image not found | `kubectl describe pod` → Events | Verify image name/tag, check imagePullSecrets, registry auth |
124
+ | OOMKilled | Out of memory | `kubectl describe pod` → Last State | Increase memory limit, profile app memory usage |
125
+ | Evicted | Node disk/memory pressure | `kubectl describe node` | Increase limits, add node capacity, check for log/tmp bloat |
126
+ | CreateContainerError | Container config issue | `kubectl describe pod` → Events | Check volume mounts, configmap/secret refs, security context |
127
+ | Init:CrashLoopBackOff | Init container failing | `kubectl logs -c <init-container>` | Fix init container command, check dependencies |
128
+
129
+ ### Resource inspection
130
+
131
+ ```bash
132
+ # Get all resources in namespace
133
+ kubectl get all -n <namespace>
134
+
135
+ # YAML output for debugging
136
+ kubectl get deployment/my-app -o yaml
137
+
138
+ # Check resource usage
139
+ kubectl top pods -l app.kubernetes.io/name=my-app
140
+ kubectl top nodes
141
+ ```
142
+
143
+ ## Production safety
144
+
145
+ ### Pre-apply validation
146
+
147
+ ```bash
148
+ # Always diff before applying
149
+ kubectl diff -f manifests.yaml
150
+
151
+ # Server-side dry run (validates with admission webhooks)
152
+ kubectl apply -f manifests.yaml --dry-run=server
153
+
154
+ # Client-side dry run (fast, but no webhook validation)
155
+ kubectl apply -f manifests.yaml --dry-run=client
156
+ ```
157
+
158
+ ### Rollback
159
+
160
+ ```bash
161
+ # Check rollout history
162
+ kubectl rollout history deployment/my-app
163
+
164
+ # Undo last rollout
165
+ kubectl rollout undo deployment/my-app
166
+
167
+ # Roll back to a specific revision
168
+ kubectl rollout undo deployment/my-app --to-revision=2
169
+
170
+ # Watch rollout progress
171
+ kubectl rollout status deployment/my-app --timeout=300s
172
+ ```
173
+
174
+ ### Deployment strategies
175
+
176
+ - **RollingUpdate** (default): Gradually replaces pods. Set `maxSurge` and `maxUnavailable`.
177
+ - **Recreate**: All pods terminated before new ones created. Use for stateful apps that cannot run multiple versions.
178
+ - **Canary**: Deploy a second Deployment with 1 replica + same selector labels. Route percentage via Ingress annotations or service mesh.
179
+ - **Blue/Green**: Two full Deployments (blue/green), switch Service selector between them.
180
+
181
+ ## Composites
182
+
183
+ Composites are higher-level functions that produce multiple coordinated K8s resources from a single call. They return plain prop objects — not class instances — that you pass to generated constructors or serialize directly.
184
+
185
+ ### WebApp — Deployment + Service + optional Ingress
186
+
187
+ ```typescript
188
+ import { WebApp } from "@intentius/chant-lexicon-k8s";
189
+
190
+ const { deployment, service, ingress } = WebApp({
191
+ name: "frontend",
192
+ image: "frontend:1.0",
193
+ port: 3000,
194
+ replicas: 3,
195
+ ingressHost: "frontend.example.com",
196
+ ingressTlsSecret: "frontend-tls",
197
+ });
198
+ ```
199
+
200
+ ### StatefulApp — StatefulSet + headless Service + PVC
201
+
202
+ ```typescript
203
+ import { StatefulApp } from "@intentius/chant-lexicon-k8s";
204
+
205
+ const { statefulSet, service } = StatefulApp({
206
+ name: "postgres",
207
+ image: "postgres:16",
208
+ storageSize: "20Gi",
209
+ env: [{ name: "POSTGRES_DB", value: "mydb" }],
210
+ });
211
+ ```
212
+
213
+ ### CronWorkload — CronJob + ServiceAccount + Role + RoleBinding
214
+
215
+ ```typescript
216
+ import { CronWorkload } from "@intentius/chant-lexicon-k8s";
217
+
218
+ const { cronJob, serviceAccount, role, roleBinding } = CronWorkload({
219
+ name: "db-backup",
220
+ image: "postgres:16",
221
+ schedule: "0 2 * * *",
222
+ command: ["pg_dump", "-h", "postgres", "mydb"],
223
+ rbacRules: [{ apiGroups: [""], resources: ["secrets"], verbs: ["get"] }],
224
+ });
225
+ ```
226
+
227
+ ### AutoscaledService — Deployment + Service + HPA + PDB
228
+
229
+ Production HTTP service with autoscaling, health probes, and optional topology spreading.
230
+
231
+ ```typescript
232
+ import { AutoscaledService } from "@intentius/chant-lexicon-k8s";
233
+
234
+ const { deployment, service, hpa, pdb } = AutoscaledService({
235
+ name: "api",
236
+ image: "api:2.0",
237
+ port: 8080,
238
+ maxReplicas: 10,
239
+ minReplicas: 3,
240
+ cpuRequest: "200m",
241
+ memoryRequest: "256Mi",
242
+ cpuLimit: "1",
243
+ memoryLimit: "1Gi",
244
+ // Probe paths — defaults: /healthz and /readyz
245
+ livenessPath: "/healthz",
246
+ readinessPath: "/readyz",
247
+ // Zone-aware topology spreading (default: false)
248
+ topologySpread: true,
249
+ // Custom: topologySpread: { maxSkew: 2, topologyKey: "kubernetes.io/hostname" }
250
+ });
251
+ ```
252
+
253
+ Key features:
254
+ - **Probe paths**: `livenessPath` (default `/healthz`) and `readinessPath` (default `/readyz`) — override for apps that don't serve those routes
255
+ - **Topology spread**: `topologySpread: true` adds zone-aware spreading (maxSkew=1, DoNotSchedule); pass an object for custom key/skew
256
+ - **PDB minAvailable**: accepts number or string percentage (e.g., `"50%"`)
257
+
258
+ ### WorkerPool — Deployment + RBAC + optional ConfigMap + optional HPA
259
+
260
+ Background queue workers with optional RBAC and autoscaling.
261
+
262
+ ```typescript
263
+ import { WorkerPool } from "@intentius/chant-lexicon-k8s";
264
+
265
+ const { deployment, serviceAccount, role, roleBinding, configMap, hpa } = WorkerPool({
266
+ name: "email-worker",
267
+ image: "worker:1.0",
268
+ command: ["bundle", "exec", "sidekiq"],
269
+ config: { REDIS_URL: "redis://redis:6379", QUEUE: "emails" },
270
+ autoscaling: { minReplicas: 2, maxReplicas: 20, targetCPUPercent: 60 },
271
+ });
272
+ ```
273
+
274
+ Key features:
275
+ - **RBAC opt-out**: Pass `rbacRules: []` to skip ServiceAccount/Role/RoleBinding creation entirely. Omitting `rbacRules` (undefined) creates default rules for secrets/configmaps.
276
+ - `serviceAccount`, `role`, `roleBinding` are optional in the result — check before use
277
+
278
+ ### NamespaceEnv — Namespace + ResourceQuota + LimitRange + NetworkPolicy
279
+
280
+ Multi-tenant namespace provisioning with resource guardrails and network isolation.
281
+
282
+ ```typescript
283
+ import { NamespaceEnv } from "@intentius/chant-lexicon-k8s";
284
+
285
+ const { namespace, resourceQuota, limitRange, networkPolicy } = NamespaceEnv({
286
+ name: "team-alpha",
287
+ cpuQuota: "8",
288
+ memoryQuota: "16Gi",
289
+ maxPods: 50,
290
+ defaultCpuRequest: "100m",
291
+ defaultMemoryRequest: "128Mi",
292
+ defaultCpuLimit: "500m",
293
+ defaultMemoryLimit: "512Mi",
294
+ defaultDenyIngress: true,
295
+ defaultDenyEgress: true,
296
+ });
297
+ ```
298
+
299
+ Key features:
300
+ - **Quota-without-limits warning**: Setting ResourceQuota without LimitRange defaults emits a warning — pods without explicit resource requests will fail to schedule
301
+ - **Network policies**: `defaultDenyIngress` (default true), `defaultDenyEgress` (default false) — can be combined or used individually
302
+
303
+ ### NodeAgent — DaemonSet + ServiceAccount + ClusterRole + ClusterRoleBinding + optional ConfigMap
304
+
305
+ Per-node agents (log collectors, security scanners, monitoring exporters).
306
+
307
+ ```typescript
308
+ import { NodeAgent } from "@intentius/chant-lexicon-k8s";
309
+
310
+ const { daemonSet, serviceAccount, clusterRole, clusterRoleBinding, configMap } = NodeAgent({
311
+ name: "log-collector",
312
+ image: "fluentd:v1.16",
313
+ port: 24224,
314
+ hostPaths: [
315
+ { name: "varlog", hostPath: "/var/log", mountPath: "/var/log" },
316
+ ],
317
+ config: { "fluent.conf": "..." },
318
+ rbacRules: [{ apiGroups: [""], resources: ["pods", "namespaces"], verbs: ["get", "list", "watch"] }],
319
+ cpuRequest: "50m", // default: 50m
320
+ memoryRequest: "64Mi", // default: 64Mi
321
+ cpuLimit: "200m", // default: 200m
322
+ memoryLimit: "128Mi", // default: 128Mi
323
+ namespace: "monitoring",
324
+ });
325
+ ```
326
+
327
+ Key features:
328
+ - **Container resources**: Always set with sensible defaults (50m/64Mi requests, 200m/128Mi limits) — override per-agent
329
+ - **Host paths**: Mounted read-only by default; set `readOnly: false` to enable writes
330
+ - **Tolerations**: `tolerateAllTaints: true` (default) ensures agent runs on every node
331
+ - Uses **ClusterRole/ClusterRoleBinding** (cluster-scoped) for node-level access
332
+
333
+ ### Common patterns across all composites
334
+
335
+ - All resources carry `app.kubernetes.io/name`, `app.kubernetes.io/managed-by: chant`, and `app.kubernetes.io/component` labels
336
+ - Pass `labels: { team: "platform" }` to add extra labels to all resources
337
+ - Pass `namespace: "prod"` to set namespace on all namespaced resources
338
+ - Pass `env: [{ name: "KEY", value: "val" }]` for container environment variables
339
+
340
+ ## Namespace management
341
+
342
+ Use the **NamespaceEnv** composite (above) to manage namespaces declaratively. For manual kubectl management:
343
+
344
+ ```bash
345
+ # Create namespace
346
+ kubectl create namespace my-project
347
+
348
+ # Set default resource quotas
349
+ kubectl apply -f - <<EOF
350
+ apiVersion: v1
351
+ kind: ResourceQuota
352
+ metadata:
353
+ name: default-quota
354
+ namespace: my-project
355
+ spec:
356
+ hard:
357
+ requests.cpu: "4"
358
+ requests.memory: 8Gi
359
+ limits.cpu: "8"
360
+ limits.memory: 16Gi
361
+ pods: "20"
362
+ EOF
363
+
364
+ # Set default container limits via LimitRange
365
+ kubectl apply -f - <<EOF
366
+ apiVersion: v1
367
+ kind: LimitRange
368
+ metadata:
369
+ name: default-limits
370
+ namespace: my-project
371
+ spec:
372
+ limits:
373
+ - default:
374
+ cpu: 500m
375
+ memory: 256Mi
376
+ defaultRequest:
377
+ cpu: 100m
378
+ memory: 128Mi
379
+ type: Container
380
+ EOF
381
+ ```
382
+
383
+ ## Troubleshooting reference table
384
+
385
+ | Symptom | Likely cause | Resolution |
386
+ |---------|-------------|------------|
387
+ | Pod stuck in Pending | Insufficient CPU/memory on nodes | Scale up cluster or reduce resource requests |
388
+ | Pod stuck in Pending | PVC not bound | Check StorageClass exists, PV available |
389
+ | Pod stuck in Pending | Node selector/affinity mismatch | Verify node labels match selectors |
390
+ | Pod stuck in ContainerCreating | ConfigMap/Secret not found | Ensure referenced ConfigMaps/Secrets exist |
391
+ | Pod stuck in ContainerCreating | Volume mount failure | Check PVC status, CSI driver health |
392
+ | Service returns 503 | No ready endpoints | Check pod readiness probes, selector match |
393
+ | Service returns 503 | Wrong port configuration | Verify targetPort matches containerPort |
394
+ | Ingress returns 404 | Backend service not found | Check Ingress rules, service name/port |
395
+ | Ingress returns 404 | Wrong path matching | Check pathType (Prefix vs Exact) |
396
+ | HPA not scaling | Metrics server not installed | Install metrics-server |
397
+ | HPA not scaling | Resource requests not set | Add CPU/memory requests to containers |
398
+ | CronJob not running | Invalid cron expression | Validate cron syntax (5-field format) |
399
+ | NetworkPolicy blocking | Default deny applied | Add explicit allow rules for required traffic |
400
+ | RBAC permission denied | Missing Role/RoleBinding | Check ServiceAccount bindings and verb permissions |
401
+
402
+ ## Quick reference
403
+
404
+ ```bash
405
+ # Build
406
+ chant build src/ --output manifests.yaml
407
+
408
+ # Lint
409
+ chant lint src/
410
+
411
+ # Validate
412
+ kubectl apply -f manifests.yaml --dry-run=server
413
+
414
+ # Diff
415
+ kubectl diff -f manifests.yaml
416
+
417
+ # Apply
418
+ kubectl apply -f manifests.yaml
419
+
420
+ # Status
421
+ kubectl get pods,svc,deploy
422
+
423
+ # Logs
424
+ kubectl logs deployment/my-app
425
+
426
+ # Rollback
427
+ kubectl rollout undo deployment/my-app
428
+
429
+ # Debug
430
+ kubectl describe pod <name>
431
+ kubectl logs <name> --previous
432
+ kubectl get events --sort-by=.lastTimestamp
433
+ ```