container-superposition 0.1.1 → 0.1.3
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.
- package/README.md +206 -1
- package/dist/scripts/init.js +235 -179
- package/dist/scripts/init.js.map +1 -1
- package/dist/tool/commands/doctor.d.ts +15 -0
- package/dist/tool/commands/doctor.d.ts.map +1 -0
- package/dist/tool/commands/doctor.js +862 -0
- package/dist/tool/commands/doctor.js.map +1 -0
- package/dist/tool/commands/explain.d.ts +13 -0
- package/dist/tool/commands/explain.d.ts.map +1 -0
- package/dist/tool/commands/explain.js +211 -0
- package/dist/tool/commands/explain.js.map +1 -0
- package/dist/tool/commands/list.d.ts +16 -0
- package/dist/tool/commands/list.d.ts.map +1 -0
- package/dist/tool/commands/list.js +121 -0
- package/dist/tool/commands/list.js.map +1 -0
- package/dist/tool/commands/plan.d.ts +16 -0
- package/dist/tool/commands/plan.d.ts.map +1 -0
- package/dist/tool/commands/plan.js +329 -0
- package/dist/tool/commands/plan.js.map +1 -0
- package/dist/tool/questionnaire/composer.d.ts +6 -1
- package/dist/tool/questionnaire/composer.d.ts.map +1 -1
- package/dist/tool/questionnaire/composer.js +300 -202
- package/dist/tool/questionnaire/composer.js.map +1 -1
- package/dist/tool/readme/markdown-parser.d.ts.map +1 -1
- package/dist/tool/readme/markdown-parser.js.map +1 -1
- package/dist/tool/readme/readme-generator.d.ts.map +1 -1
- package/dist/tool/readme/readme-generator.js +11 -6
- package/dist/tool/readme/readme-generator.js.map +1 -1
- package/dist/tool/schema/deployment-targets.d.ts +77 -0
- package/dist/tool/schema/deployment-targets.d.ts.map +1 -0
- package/dist/tool/schema/deployment-targets.js +91 -0
- package/dist/tool/schema/deployment-targets.js.map +1 -0
- package/dist/tool/schema/manifest-migrations.d.ts +51 -0
- package/dist/tool/schema/manifest-migrations.d.ts.map +1 -0
- package/dist/tool/schema/manifest-migrations.js +159 -0
- package/dist/tool/schema/manifest-migrations.js.map +1 -0
- package/dist/tool/schema/overlay-loader.d.ts +1 -1
- package/dist/tool/schema/overlay-loader.d.ts.map +1 -1
- package/dist/tool/schema/overlay-loader.js +42 -14
- package/dist/tool/schema/overlay-loader.js.map +1 -1
- package/dist/tool/schema/types.d.ts +44 -2
- package/dist/tool/schema/types.d.ts.map +1 -1
- package/dist/tool/utils/merge.d.ts +134 -0
- package/dist/tool/utils/merge.d.ts.map +1 -0
- package/dist/tool/utils/merge.js +277 -0
- package/dist/tool/utils/merge.js.map +1 -0
- package/dist/tool/utils/port-utils.d.ts +29 -0
- package/dist/tool/utils/port-utils.d.ts.map +1 -0
- package/dist/tool/utils/port-utils.js +128 -0
- package/dist/tool/utils/port-utils.js.map +1 -0
- package/dist/tool/utils/version.d.ts +9 -0
- package/dist/tool/utils/version.d.ts.map +1 -0
- package/dist/tool/utils/version.js +32 -0
- package/dist/tool/utils/version.js.map +1 -0
- package/docs/architecture.md +25 -21
- package/docs/deployment-targets.md +150 -0
- package/docs/discovery-commands.md +442 -0
- package/docs/merge-strategy.md +700 -0
- package/docs/minimal-and-editor.md +265 -0
- package/docs/overlay-imports.md +209 -0
- package/docs/overlay-manifest-refactoring.md +2 -2
- package/docs/overlay-metadata-archive.md +1 -1
- package/docs/overlays.md +91 -23
- package/docs/presets-architecture.md +3 -3
- package/docs/presets.md +1 -1
- package/docs/publishing.md +36 -35
- package/docs/team-workflow.md +540 -0
- package/overlays/.presets/data-engineering.yml +392 -0
- package/overlays/.presets/event-sourced-service.yml +262 -0
- package/overlays/.presets/frontend.yml +287 -0
- package/overlays/.presets/k8s-operator-dev.yml +462 -0
- package/overlays/.registry/README.md +1 -1
- package/overlays/.registry/deployment-targets.yml +54 -0
- package/overlays/.shared/README.md +43 -0
- package/overlays/.shared/compose/common-healthchecks.yml +38 -0
- package/overlays/.shared/otel/instrumentation.env +20 -0
- package/overlays/.shared/otel/otel-base-config.yaml +30 -0
- package/overlays/.shared/vscode/recommended-extensions.json +14 -0
- package/overlays/README.md +1 -1
- package/overlays/codex/overlay.yml +1 -0
- package/overlays/duckdb/README.md +274 -0
- package/overlays/duckdb/devcontainer.patch.json +10 -0
- package/overlays/duckdb/overlay.yml +17 -0
- package/overlays/duckdb/setup.sh +45 -0
- package/overlays/duckdb/verify.sh +32 -0
- package/overlays/git-helpers/overlay.yml +1 -0
- package/overlays/grafana/README.md +5 -5
- package/overlays/grafana/dashboard-provider.yml +1 -1
- package/overlays/grafana/docker-compose.yml +2 -2
- package/overlays/grafana/overlay.yml +6 -1
- package/overlays/jaeger/overlay.yml +16 -3
- package/overlays/jupyter/.env.example +6 -0
- package/overlays/jupyter/README.md +210 -0
- package/overlays/jupyter/devcontainer.patch.json +14 -0
- package/overlays/jupyter/docker-compose.yml +23 -0
- package/overlays/jupyter/overlay.yml +18 -0
- package/overlays/jupyter/verify.sh +35 -0
- package/overlays/kind/README.md +221 -0
- package/overlays/kind/devcontainer.patch.json +10 -0
- package/overlays/kind/overlay.yml +18 -0
- package/overlays/kind/setup.sh +43 -0
- package/overlays/kind/verify.sh +40 -0
- package/overlays/localstack/.env.example +6 -0
- package/overlays/localstack/README.md +188 -0
- package/overlays/localstack/devcontainer.patch.json +21 -0
- package/overlays/localstack/docker-compose.yml +25 -0
- package/overlays/localstack/overlay.yml +18 -0
- package/overlays/localstack/verify.sh +47 -0
- package/overlays/loki/overlay.yml +6 -1
- package/overlays/modern-cli-tools/overlay.yml +1 -0
- package/overlays/mongodb/overlay.yml +12 -2
- package/overlays/mysql/overlay.yml +12 -2
- package/overlays/nats/overlay.yml +12 -2
- package/overlays/openapi-tools/README.md +243 -0
- package/overlays/openapi-tools/devcontainer.patch.json +10 -0
- package/overlays/openapi-tools/overlay.yml +16 -0
- package/overlays/openapi-tools/setup.sh +45 -0
- package/overlays/openapi-tools/verify.sh +51 -0
- package/overlays/otel-collector/overlay.yml.example +26 -0
- package/overlays/postgres/overlay.yml +6 -1
- package/overlays/prometheus/overlay.yml +6 -1
- package/overlays/rabbitmq/overlay.yml +12 -2
- package/overlays/redis/overlay.yml +6 -1
- package/overlays/tilt/README.md +259 -0
- package/overlays/tilt/devcontainer.patch.json +17 -0
- package/overlays/tilt/overlay.yml +19 -0
- package/overlays/tilt/setup.sh +25 -0
- package/overlays/tilt/verify.sh +24 -0
- package/package.json +8 -6
- package/tool/README.md +12 -16
- package/tool/schema/overlay-manifest.schema.json +64 -4
- package/tool/schema/superposition-manifest.schema.json +104 -0
- /package/overlays/{presets → .presets}/docs-site.yml +0 -0
- /package/overlays/{presets → .presets}/fullstack.yml +0 -0
- /package/overlays/{presets → .presets}/microservice.yml +0 -0
- /package/overlays/{presets → .presets}/web-api.yml +0 -0
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
# Kubernetes Operator Development Preset
|
|
2
|
+
# Go-based Kubernetes operator/controller development
|
|
3
|
+
|
|
4
|
+
id: k8s-operator-dev
|
|
5
|
+
name: Kubernetes Operator Development
|
|
6
|
+
description: Go-based operator development with kubectl and Helm
|
|
7
|
+
type: meta
|
|
8
|
+
category: preset
|
|
9
|
+
supports: [] # Works with both plain and compose
|
|
10
|
+
tags: [preset, kubernetes, operator, controller, k8s, crd, go]
|
|
11
|
+
|
|
12
|
+
# Overlays to select
|
|
13
|
+
selects:
|
|
14
|
+
# Always included
|
|
15
|
+
required:
|
|
16
|
+
- go
|
|
17
|
+
- kubectl-helm
|
|
18
|
+
- modern-cli-tools
|
|
19
|
+
|
|
20
|
+
# No user choices - operators are typically Go
|
|
21
|
+
userChoice: {}
|
|
22
|
+
|
|
23
|
+
# Glue configuration - integration helpers
|
|
24
|
+
glueConfig:
|
|
25
|
+
# Pre-configured environment variables
|
|
26
|
+
environment:
|
|
27
|
+
# Go environment
|
|
28
|
+
GOOS: 'linux'
|
|
29
|
+
GOARCH: 'amd64'
|
|
30
|
+
CGO_ENABLED: '0'
|
|
31
|
+
|
|
32
|
+
# Kubernetes configuration
|
|
33
|
+
KUBECONFIG: '/home/vscode/.kube/config'
|
|
34
|
+
|
|
35
|
+
# Operator SDK settings
|
|
36
|
+
OPERATOR_NAME: 'my-operator'
|
|
37
|
+
OPERATOR_NAMESPACE: 'default'
|
|
38
|
+
|
|
39
|
+
# Development cluster settings (for future kind/k3d overlay)
|
|
40
|
+
# KIND_CLUSTER_NAME: 'operator-dev'
|
|
41
|
+
# K3D_CLUSTER_NAME: 'operator-dev'
|
|
42
|
+
|
|
43
|
+
# Suggested port mappings
|
|
44
|
+
portMappings:
|
|
45
|
+
operator-metrics: 8080
|
|
46
|
+
operator-health: 8081
|
|
47
|
+
|
|
48
|
+
# README snippet to add to generated devcontainer
|
|
49
|
+
readme: |
|
|
50
|
+
## Kubernetes Operator Development Stack
|
|
51
|
+
|
|
52
|
+
This devcontainer is configured for Kubernetes operator development:
|
|
53
|
+
|
|
54
|
+
### Tools
|
|
55
|
+
|
|
56
|
+
- **Go**: Operator runtime and tooling
|
|
57
|
+
- **kubectl**: Kubernetes CLI
|
|
58
|
+
- **Helm**: Package manager for Kubernetes
|
|
59
|
+
- **Modern CLI Tools**: jq, yq, bat for manifest inspection
|
|
60
|
+
|
|
61
|
+
### Operator Frameworks
|
|
62
|
+
|
|
63
|
+
This environment supports multiple operator frameworks:
|
|
64
|
+
|
|
65
|
+
#### Kubebuilder (Recommended)
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# Install Kubebuilder
|
|
69
|
+
curl -L -o kubebuilder "https://go.kubebuilder.io/dl/latest/$(go env GOOS)/$(go env GOARCH)"
|
|
70
|
+
chmod +x kubebuilder
|
|
71
|
+
sudo mv kubebuilder /usr/local/bin/
|
|
72
|
+
|
|
73
|
+
# Initialize new operator
|
|
74
|
+
mkdir my-operator && cd my-operator
|
|
75
|
+
kubebuilder init --domain example.com --repo github.com/myorg/my-operator
|
|
76
|
+
|
|
77
|
+
# Create API/Controller
|
|
78
|
+
kubebuilder create api --group apps --version v1alpha1 --kind MyResource
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
#### Operator SDK
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# Install Operator SDK
|
|
85
|
+
export ARCH=$(case "$(uname -m)" in
|
|
86
|
+
x86_64) echo -n amd64 ;;
|
|
87
|
+
aarch64) echo -n arm64 ;;
|
|
88
|
+
*) echo -n "$(uname -m)" ;;
|
|
89
|
+
esac)
|
|
90
|
+
export OS=$(uname | awk '{print tolower($0)}')
|
|
91
|
+
export OPERATOR_SDK_DL_URL=https://github.com/operator-framework/operator-sdk/releases/latest/download
|
|
92
|
+
curl -LO ${OPERATOR_SDK_DL_URL}/operator-sdk_${OS}_${ARCH}
|
|
93
|
+
chmod +x operator-sdk_${OS}_${ARCH}
|
|
94
|
+
sudo mv operator-sdk_${OS}_${ARCH} /usr/local/bin/operator-sdk
|
|
95
|
+
|
|
96
|
+
# Create new operator
|
|
97
|
+
mkdir my-operator && cd my-operator
|
|
98
|
+
operator-sdk init --domain example.com --repo github.com/myorg/my-operator
|
|
99
|
+
|
|
100
|
+
# Create API
|
|
101
|
+
operator-sdk create api --group apps --version v1alpha1 --kind MyResource
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Quick Start (Kubebuilder)
|
|
105
|
+
|
|
106
|
+
#### 1. Scaffold Operator
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
mkdir my-operator && cd my-operator
|
|
110
|
+
kubebuilder init --domain example.com --repo github.com/myorg/my-operator
|
|
111
|
+
kubebuilder create api --group apps --version v1alpha1 --kind MyApp --resource --controller
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
This creates:
|
|
115
|
+
- `api/v1alpha1/myapp_types.go` - CRD definition
|
|
116
|
+
- `internal/controller/myapp_controller.go` - Reconciliation logic
|
|
117
|
+
- `config/` - Kubernetes manifests
|
|
118
|
+
|
|
119
|
+
#### 2. Define CRD
|
|
120
|
+
|
|
121
|
+
```go
|
|
122
|
+
// api/v1alpha1/myapp_types.go
|
|
123
|
+
type MyAppSpec struct {
|
|
124
|
+
// +kubebuilder:validation:Minimum=1
|
|
125
|
+
Replicas int32 `json:"replicas"`
|
|
126
|
+
|
|
127
|
+
// +kubebuilder:validation:Required
|
|
128
|
+
Image string `json:"image"`
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
type MyAppStatus struct {
|
|
132
|
+
// Conditions represent the latest available observations
|
|
133
|
+
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
|
134
|
+
|
|
135
|
+
// Ready replicas
|
|
136
|
+
ReadyReplicas int32 `json:"readyReplicas"`
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
#### 3. Implement Controller
|
|
141
|
+
|
|
142
|
+
```go
|
|
143
|
+
// internal/controller/myapp_controller.go
|
|
144
|
+
func (r *MyAppReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
|
|
145
|
+
log := log.FromContext(ctx)
|
|
146
|
+
|
|
147
|
+
// Fetch the MyApp instance
|
|
148
|
+
myApp := &appsv1alpha1.MyApp{}
|
|
149
|
+
err := r.Get(ctx, req.NamespacedName, myApp)
|
|
150
|
+
if err != nil {
|
|
151
|
+
return ctrl.Result{}, client.IgnoreNotFound(err)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Reconciliation logic
|
|
155
|
+
// 1. Ensure Deployment exists
|
|
156
|
+
// 2. Update Deployment if spec changed
|
|
157
|
+
// 3. Update status
|
|
158
|
+
|
|
159
|
+
log.Info("Reconciled MyApp", "name", myApp.Name)
|
|
160
|
+
return ctrl.Result{}, nil
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
#### 4. Test Locally
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
# Generate manifests
|
|
168
|
+
make manifests
|
|
169
|
+
|
|
170
|
+
# Run tests
|
|
171
|
+
make test
|
|
172
|
+
|
|
173
|
+
# Run controller locally (no cluster needed initially)
|
|
174
|
+
make run
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Connecting to Kubernetes Cluster
|
|
178
|
+
|
|
179
|
+
This preset includes kubectl and Helm. You can connect to:
|
|
180
|
+
|
|
181
|
+
#### Remote Cluster
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
# Set up kubeconfig
|
|
185
|
+
export KUBECONFIG=~/.kube/config
|
|
186
|
+
|
|
187
|
+
# Or copy config from local machine
|
|
188
|
+
cp /path/to/kubeconfig ~/.kube/config
|
|
189
|
+
|
|
190
|
+
# Verify connection
|
|
191
|
+
kubectl cluster-info
|
|
192
|
+
kubectl get nodes
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
#### Future: Local Cluster (kind/k3d overlay)
|
|
196
|
+
|
|
197
|
+
When kind or k3d overlay is available:
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
# kind
|
|
201
|
+
kind create cluster --name operator-dev
|
|
202
|
+
|
|
203
|
+
# k3d
|
|
204
|
+
k3d cluster create operator-dev
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Development Workflow
|
|
208
|
+
|
|
209
|
+
#### 1. Install CRDs
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
make install
|
|
213
|
+
# This creates CustomResourceDefinition in cluster
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
#### 2. Run Operator
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
# Option A: Run locally (outside cluster)
|
|
220
|
+
make run
|
|
221
|
+
|
|
222
|
+
# Option B: Build and deploy to cluster
|
|
223
|
+
make docker-build docker-push IMG=myregistry/my-operator:v0.1.0
|
|
224
|
+
make deploy IMG=myregistry/my-operator:v0.1.0
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
#### 3. Create Custom Resource
|
|
228
|
+
|
|
229
|
+
```yaml
|
|
230
|
+
# config/samples/apps_v1alpha1_myapp.yaml
|
|
231
|
+
apiVersion: apps.example.com/v1alpha1
|
|
232
|
+
kind: MyApp
|
|
233
|
+
metadata:
|
|
234
|
+
name: myapp-sample
|
|
235
|
+
spec:
|
|
236
|
+
replicas: 3
|
|
237
|
+
image: nginx:latest
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
kubectl apply -f config/samples/apps_v1alpha1_myapp.yaml
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
#### 4. Watch Reconciliation
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
# Watch controller logs
|
|
248
|
+
kubectl logs -f -n <namespace> <operator-pod>
|
|
249
|
+
|
|
250
|
+
# Watch custom resource
|
|
251
|
+
kubectl get myapp -w
|
|
252
|
+
|
|
253
|
+
# Describe custom resource
|
|
254
|
+
kubectl describe myapp myapp-sample
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Testing Operators
|
|
258
|
+
|
|
259
|
+
#### Unit Tests
|
|
260
|
+
|
|
261
|
+
```go
|
|
262
|
+
// internal/controller/myapp_controller_test.go
|
|
263
|
+
var _ = Describe("MyApp Controller", func() {
|
|
264
|
+
Context("When reconciling a resource", func() {
|
|
265
|
+
It("Should create a Deployment", func() {
|
|
266
|
+
// Test reconciliation logic
|
|
267
|
+
})
|
|
268
|
+
})
|
|
269
|
+
})
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Run tests:
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
make test
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
#### Integration Tests with envtest
|
|
279
|
+
|
|
280
|
+
```go
|
|
281
|
+
var k8sClient client.Client
|
|
282
|
+
var testEnv *envtest.Environment
|
|
283
|
+
|
|
284
|
+
BeforeSuite(func() {
|
|
285
|
+
testEnv = &envtest.Environment{
|
|
286
|
+
CRDDirectoryPaths: []string{filepath.Join("..", "config", "crd", "bases")},
|
|
287
|
+
}
|
|
288
|
+
cfg, err := testEnv.Start()
|
|
289
|
+
Expect(err).NotTo(HaveOccurred())
|
|
290
|
+
|
|
291
|
+
k8sClient, err = client.New(cfg, client.Options{})
|
|
292
|
+
Expect(err).NotTo(HaveOccurred())
|
|
293
|
+
})
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### Helm Chart for Operator
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
# Create Helm chart
|
|
300
|
+
mkdir -p charts/my-operator
|
|
301
|
+
helm create charts/my-operator
|
|
302
|
+
|
|
303
|
+
# Package chart
|
|
304
|
+
helm package charts/my-operator
|
|
305
|
+
|
|
306
|
+
# Install from chart
|
|
307
|
+
helm install my-operator charts/my-operator
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### RBAC Configuration
|
|
311
|
+
|
|
312
|
+
Operators need appropriate permissions:
|
|
313
|
+
|
|
314
|
+
```yaml
|
|
315
|
+
# config/rbac/role.yaml
|
|
316
|
+
apiVersion: rbac.authorization.k8s.io/v1
|
|
317
|
+
kind: ClusterRole
|
|
318
|
+
metadata:
|
|
319
|
+
name: operator-role
|
|
320
|
+
rules:
|
|
321
|
+
- apiGroups: ["apps.example.com"]
|
|
322
|
+
resources: ["myapps"]
|
|
323
|
+
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
|
324
|
+
- apiGroups: ["apps"]
|
|
325
|
+
resources: ["deployments"]
|
|
326
|
+
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
Kubebuilder generates RBAC with markers:
|
|
330
|
+
|
|
331
|
+
```go
|
|
332
|
+
// +kubebuilder:rbac:groups=apps.example.com,resources=myapps,verbs=get;list;watch;create;update;patch;delete
|
|
333
|
+
// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### Operator Patterns
|
|
337
|
+
|
|
338
|
+
#### Level-Based Reconciliation
|
|
339
|
+
|
|
340
|
+
```go
|
|
341
|
+
func (r *MyAppReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
|
|
342
|
+
// Get desired state
|
|
343
|
+
myApp := &appsv1alpha1.MyApp{}
|
|
344
|
+
if err := r.Get(ctx, req.NamespacedName, myApp); err != nil {
|
|
345
|
+
return ctrl.Result{}, client.IgnoreNotFound(err)
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// Get current state
|
|
349
|
+
deployment := &appsv1.Deployment{}
|
|
350
|
+
err := r.Get(ctx, types.NamespacedName{
|
|
351
|
+
Name: myApp.Name, Namespace: myApp.Namespace,
|
|
352
|
+
}, deployment)
|
|
353
|
+
|
|
354
|
+
if err != nil {
|
|
355
|
+
// Create if not exists
|
|
356
|
+
return r.createDeployment(ctx, myApp)
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// Update if different
|
|
360
|
+
if deployment.Spec.Replicas != &myApp.Spec.Replicas {
|
|
361
|
+
return r.updateDeployment(ctx, myApp, deployment)
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
return ctrl.Result{}, nil
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
#### Finalizers
|
|
369
|
+
|
|
370
|
+
```go
|
|
371
|
+
const myFinalizerName = "myapp.example.com/finalizer"
|
|
372
|
+
|
|
373
|
+
func (r *MyAppReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
|
|
374
|
+
myApp := &appsv1alpha1.MyApp{}
|
|
375
|
+
if err := r.Get(ctx, req.NamespacedName, myApp); err != nil {
|
|
376
|
+
return ctrl.Result{}, client.IgnoreNotFound(err)
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// Handle deletion
|
|
380
|
+
if myApp.DeletionTimestamp != nil {
|
|
381
|
+
if controllerutil.ContainsFinalizer(myApp, myFinalizerName) {
|
|
382
|
+
// Cleanup logic
|
|
383
|
+
if err := r.cleanup(ctx, myApp); err != nil {
|
|
384
|
+
return ctrl.Result{}, err
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
controllerutil.RemoveFinalizer(myApp, myFinalizerName)
|
|
388
|
+
return ctrl.Result{}, r.Update(ctx, myApp)
|
|
389
|
+
}
|
|
390
|
+
return ctrl.Result{}, nil
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// Add finalizer if not present
|
|
394
|
+
if !controllerutil.ContainsFinalizer(myApp, myFinalizerName) {
|
|
395
|
+
controllerutil.AddFinalizer(myApp, myFinalizerName)
|
|
396
|
+
return ctrl.Result{}, r.Update(ctx, myApp)
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// Normal reconciliation
|
|
400
|
+
return ctrl.Result{}, nil
|
|
401
|
+
}
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### Debugging
|
|
405
|
+
|
|
406
|
+
```bash
|
|
407
|
+
# Use kubectl to inspect resources
|
|
408
|
+
kubectl get myapp -o yaml
|
|
409
|
+
kubectl describe myapp myapp-sample
|
|
410
|
+
|
|
411
|
+
# Check events
|
|
412
|
+
kubectl get events --sort-by='.lastTimestamp'
|
|
413
|
+
|
|
414
|
+
# Debug with delve
|
|
415
|
+
dlv debug ./cmd/main.go
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
### Modern CLI Tools for K8s
|
|
419
|
+
|
|
420
|
+
```bash
|
|
421
|
+
# Inspect manifests with yq
|
|
422
|
+
yq eval '.spec.replicas' config/samples/myapp.yaml
|
|
423
|
+
|
|
424
|
+
# Format YAML with bat
|
|
425
|
+
bat config/crd/bases/apps.example.com_myapps.yaml
|
|
426
|
+
|
|
427
|
+
# Search in manifests
|
|
428
|
+
rg 'kind: Deployment' config/
|
|
429
|
+
|
|
430
|
+
# Find manifest files
|
|
431
|
+
fd -e yaml config/
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
### Future Enhancements
|
|
435
|
+
|
|
436
|
+
When kind/k3d and tilt/skaffold overlays are available:
|
|
437
|
+
|
|
438
|
+
#### Local Kubernetes Cluster
|
|
439
|
+
|
|
440
|
+
- Fast inner development loop
|
|
441
|
+
- No external cluster dependencies
|
|
442
|
+
- Test CRD installations locally
|
|
443
|
+
|
|
444
|
+
#### Live Reload with Tilt/Skaffold
|
|
445
|
+
|
|
446
|
+
- Automatic rebuild on code changes
|
|
447
|
+
- Fast feedback cycle
|
|
448
|
+
- Port forwarding management
|
|
449
|
+
- Log aggregation
|
|
450
|
+
|
|
451
|
+
### Next Steps
|
|
452
|
+
|
|
453
|
+
- Choose operator framework (Kubebuilder or Operator SDK)
|
|
454
|
+
- Design your Custom Resource Definition (CRD)
|
|
455
|
+
- Implement reconciliation logic
|
|
456
|
+
- Add unit and integration tests
|
|
457
|
+
- Configure RBAC permissions
|
|
458
|
+
- Create Helm chart for distribution
|
|
459
|
+
- Set up CI/CD for operator builds
|
|
460
|
+
- Document operator usage
|
|
461
|
+
- Implement metrics and monitoring
|
|
462
|
+
- Add webhooks for validation/mutation
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
deployment_targets:
|
|
2
|
+
- id: local
|
|
3
|
+
name: Local Development
|
|
4
|
+
description: Running on local machine with Docker Desktop or Docker daemon
|
|
5
|
+
incompatibleOverlays: []
|
|
6
|
+
recommendations: {}
|
|
7
|
+
portForwarding:
|
|
8
|
+
defaultBehavior: notify
|
|
9
|
+
autoForward: false
|
|
10
|
+
constraints:
|
|
11
|
+
hasHostDocker: true
|
|
12
|
+
supportsPrivileged: true
|
|
13
|
+
|
|
14
|
+
- id: codespaces
|
|
15
|
+
name: GitHub Codespaces
|
|
16
|
+
description: Cloud-based development environment on GitHub
|
|
17
|
+
incompatibleOverlays:
|
|
18
|
+
- docker-sock
|
|
19
|
+
recommendations:
|
|
20
|
+
docker-sock:
|
|
21
|
+
- docker-in-docker
|
|
22
|
+
portForwarding:
|
|
23
|
+
defaultBehavior: notify
|
|
24
|
+
autoForward: true
|
|
25
|
+
constraints:
|
|
26
|
+
hasHostDocker: false
|
|
27
|
+
supportsPrivileged: true
|
|
28
|
+
|
|
29
|
+
- id: gitpod
|
|
30
|
+
name: Gitpod
|
|
31
|
+
description: Cloud development environment on Gitpod
|
|
32
|
+
incompatibleOverlays:
|
|
33
|
+
- docker-sock
|
|
34
|
+
recommendations:
|
|
35
|
+
docker-sock:
|
|
36
|
+
- docker-in-docker
|
|
37
|
+
portForwarding:
|
|
38
|
+
defaultBehavior: openBrowser
|
|
39
|
+
autoForward: true
|
|
40
|
+
constraints:
|
|
41
|
+
hasHostDocker: false
|
|
42
|
+
supportsPrivileged: true
|
|
43
|
+
|
|
44
|
+
- id: devpod
|
|
45
|
+
name: DevPod
|
|
46
|
+
description: Client-only development environments
|
|
47
|
+
incompatibleOverlays: []
|
|
48
|
+
recommendations: {}
|
|
49
|
+
portForwarding:
|
|
50
|
+
defaultBehavior: notify
|
|
51
|
+
autoForward: false
|
|
52
|
+
constraints:
|
|
53
|
+
hasHostDocker: true
|
|
54
|
+
supportsPrivileged: true
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Shared Overlay Configurations
|
|
2
|
+
|
|
3
|
+
This directory contains shared configuration fragments that can be imported by multiple overlays to reduce duplication and ensure consistency.
|
|
4
|
+
|
|
5
|
+
## Structure
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
.shared/
|
|
9
|
+
├── otel/ # OpenTelemetry configurations
|
|
10
|
+
├── compose/ # Docker Compose patterns (healthchecks, etc.)
|
|
11
|
+
└── vscode/ # VS Code extension sets
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
Overlays can import shared files by adding them to the `imports` field in `overlay.yml`:
|
|
17
|
+
|
|
18
|
+
```yaml
|
|
19
|
+
id: prometheus
|
|
20
|
+
imports:
|
|
21
|
+
- .shared/otel/otel-base-config.yaml
|
|
22
|
+
- .shared/compose/common-healthchecks.yml
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Benefits
|
|
26
|
+
|
|
27
|
+
- **DRY (Don't Repeat Yourself)**: Common patterns defined once
|
|
28
|
+
- **Consistency**: All overlays using the same shared config stay in sync
|
|
29
|
+
- **Maintainability**: Update shared config once, all overlays benefit
|
|
30
|
+
- **Best Practices**: Shared configs embody proven patterns
|
|
31
|
+
|
|
32
|
+
## Creating Shared Configs
|
|
33
|
+
|
|
34
|
+
1. Identify common patterns across overlays
|
|
35
|
+
2. Extract to appropriate `.shared/` subdirectory
|
|
36
|
+
3. Update overlays to import the shared file
|
|
37
|
+
4. Test that imports work correctly
|
|
38
|
+
|
|
39
|
+
## Import Resolution
|
|
40
|
+
|
|
41
|
+
- Imports are resolved relative to the `overlays/` directory
|
|
42
|
+
- Shared files are merged into the overlay during composition
|
|
43
|
+
- Files are applied in the order they are listed
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Common Docker Compose Healthcheck Patterns
|
|
2
|
+
# These can be referenced by overlays to ensure consistent healthcheck configuration
|
|
3
|
+
|
|
4
|
+
healthchecks:
|
|
5
|
+
http:
|
|
6
|
+
test: ['CMD-SHELL', 'curl -f http://localhost:${PORT}/health || exit 1']
|
|
7
|
+
interval: 30s
|
|
8
|
+
timeout: 10s
|
|
9
|
+
retries: 3
|
|
10
|
+
start_period: 40s
|
|
11
|
+
|
|
12
|
+
postgres:
|
|
13
|
+
test: ['CMD-SHELL', 'pg_isready -U ${POSTGRES_USER:-postgres}']
|
|
14
|
+
interval: 10s
|
|
15
|
+
timeout: 5s
|
|
16
|
+
retries: 5
|
|
17
|
+
start_period: 10s
|
|
18
|
+
|
|
19
|
+
redis:
|
|
20
|
+
test: ['CMD', 'redis-cli', 'ping']
|
|
21
|
+
interval: 10s
|
|
22
|
+
timeout: 5s
|
|
23
|
+
retries: 5
|
|
24
|
+
start_period: 10s
|
|
25
|
+
|
|
26
|
+
mongodb:
|
|
27
|
+
test: ['CMD', 'mongosh', '--eval', "db.adminCommand('ping')"]
|
|
28
|
+
interval: 10s
|
|
29
|
+
timeout: 5s
|
|
30
|
+
retries: 5
|
|
31
|
+
start_period: 10s
|
|
32
|
+
|
|
33
|
+
mysql:
|
|
34
|
+
test: ['CMD', 'mysqladmin', 'ping', '-h', 'localhost']
|
|
35
|
+
interval: 10s
|
|
36
|
+
timeout: 5s
|
|
37
|
+
retries: 5
|
|
38
|
+
start_period: 10s
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# OpenTelemetry Instrumentation Environment Variables
|
|
2
|
+
# Common variables for language-specific auto-instrumentation
|
|
3
|
+
|
|
4
|
+
# OTEL SDK Configuration
|
|
5
|
+
OTEL_SERVICE_NAME=my-service
|
|
6
|
+
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317
|
|
7
|
+
OTEL_EXPORTER_OTLP_PROTOCOL=grpc
|
|
8
|
+
|
|
9
|
+
# Resource Attributes
|
|
10
|
+
OTEL_RESOURCE_ATTRIBUTES=deployment.environment=development
|
|
11
|
+
|
|
12
|
+
# Trace Configuration
|
|
13
|
+
OTEL_TRACES_SAMPLER=always_on
|
|
14
|
+
OTEL_TRACES_EXPORTER=otlp
|
|
15
|
+
|
|
16
|
+
# Metrics Configuration
|
|
17
|
+
OTEL_METRICS_EXPORTER=otlp
|
|
18
|
+
|
|
19
|
+
# Logs Configuration
|
|
20
|
+
OTEL_LOGS_EXPORTER=otlp
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# OpenTelemetry Base Configuration
|
|
2
|
+
# This file provides common OTEL environment variables for instrumentation
|
|
3
|
+
|
|
4
|
+
receivers:
|
|
5
|
+
otlp:
|
|
6
|
+
protocols:
|
|
7
|
+
grpc:
|
|
8
|
+
endpoint: 0.0.0.0:4317
|
|
9
|
+
http:
|
|
10
|
+
endpoint: 0.0.0.0:4318
|
|
11
|
+
|
|
12
|
+
exporters:
|
|
13
|
+
logging:
|
|
14
|
+
loglevel: debug
|
|
15
|
+
|
|
16
|
+
processors:
|
|
17
|
+
batch:
|
|
18
|
+
timeout: 10s
|
|
19
|
+
send_batch_size: 1024
|
|
20
|
+
|
|
21
|
+
service:
|
|
22
|
+
pipelines:
|
|
23
|
+
traces:
|
|
24
|
+
receivers: [otlp]
|
|
25
|
+
processors: [batch]
|
|
26
|
+
exporters: [logging]
|
|
27
|
+
metrics:
|
|
28
|
+
receivers: [otlp]
|
|
29
|
+
processors: [batch]
|
|
30
|
+
exporters: [logging]
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Commonly recommended VS Code extensions across overlays",
|
|
3
|
+
"extensions": {
|
|
4
|
+
"productivity": [
|
|
5
|
+
"streetsidesoftware.code-spell-checker",
|
|
6
|
+
"usernamehw.errorlens",
|
|
7
|
+
"eamodio.gitlens"
|
|
8
|
+
],
|
|
9
|
+
"formatting": ["editorconfig.editorconfig", "esbenp.prettier-vscode"],
|
|
10
|
+
"docker": ["ms-azuretools.vscode-docker"],
|
|
11
|
+
"yaml": ["redhat.vscode-yaml"],
|
|
12
|
+
"markdown": ["yzhang.markdown-all-in-one", "davidanson.vscode-markdownlint"]
|
|
13
|
+
}
|
|
14
|
+
}
|
package/overlays/README.md
CHANGED
|
@@ -150,6 +150,6 @@ See [Creating Overlays Guide](../docs/creating-overlays.md) for complete documen
|
|
|
150
150
|
|
|
151
151
|
## Presets (Meta-Overlays)
|
|
152
152
|
|
|
153
|
-
Presets are special meta-overlays that select combinations of overlays for common scenarios (web-api, microservice, docs-site, fullstack). They're located in `overlays
|
|
153
|
+
Presets are special meta-overlays that select combinations of overlays for common scenarios (web-api, microservice, docs-site, fullstack). They're located in `overlays/.presets/*.yml`.
|
|
154
154
|
|
|
155
155
|
See [Presets Guide](../docs/presets.md) and [Presets Architecture](../docs/presets-architecture.md) for detailed documentation on creating and using presets.
|