Skip to content

Commit cdc39c0

Browse files
authored
Merge pull request #8 from metalbear-co/big-change
Big change
2 parents 934dae3 + 8d2b943 commit cdc39c0

74 files changed

Lines changed: 7064 additions & 423 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,3 +239,4 @@ task postgres:clean:gcp # Clean up
239239
task postgres:deploy:gcp
240240
task postgres:run:local:gcp
241241
```
242+

Taskfile.yml

Lines changed: 45 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ includes:
2424
multicluster:
2525
taskfile: ./tasks/Taskfile.multicluster.yml
2626
dir: ./tasks
27+
eks:
28+
taskfile: ./tasks/Taskfile.eks.yml
29+
dir: ./tasks
2730

2831
vars:
2932
ROOT_DIR:
@@ -50,7 +53,7 @@ tasks:
5053
license:create:secret:
5154
desc: Create license secret in cluster
5255
vars:
53-
LICENSE_FILE: "{{.LICENSE_FILE | default .SCRIPTS_DIR}}/company-license.pem"
56+
LICENSE_FILE: "{{.SCRIPTS_DIR}}/company-license.pem"
5457
preconditions:
5558
- sh: test -f {{.LICENSE_FILE}}
5659
msg: "License file not found. Run 'task license:generate' first"
@@ -60,15 +63,15 @@ tasks:
6063
build:operator:
6164
desc: Build operator image
6265
cmds:
63-
- cd {{.OPERATOR_DIR}}/.. && {{.CONTAINER_RUNTIME}} build -f operator/Dockerfile -t {{.OPERATOR_IMAGE}} --build-arg OPERATOR_LICENSE_ISSUER_PUBLIC_KEY="$(cat {{.SCRIPTS_DIR}}/license-issuer.pem)" operator
66+
- cd {{.OPERATOR_DIR}}/.. && {{.CONTAINER_RUNTIME}} build --provenance=false -f operator/Dockerfile -t {{.OPERATOR_IMAGE}} --build-arg OPERATOR_LICENSE_ISSUER_PUBLIC_KEY="$(cat {{.SCRIPTS_DIR}}/license-issuer.pem)" operator
6467
- task: operator:image:load
6568

6669
build:operator:nocache:
6770
desc: Build operator without any cache (clears sccache + Docker layers)
6871
cmds:
6972
- echo "Clearing sccache and target cache mounts..."
7073
- docker builder prune --filter type=exec.cachemount --force || true
71-
- cd {{.OPERATOR_DIR}}/.. && {{.CONTAINER_RUNTIME}} build --no-cache -f operator/Dockerfile -t {{.OPERATOR_IMAGE}} --build-arg OPERATOR_LICENSE_ISSUER_PUBLIC_KEY="$(cat {{.SCRIPTS_DIR}}/license-issuer.pem)" operator
74+
- cd {{.OPERATOR_DIR}}/.. && {{.CONTAINER_RUNTIME}} build --provenance=false --no-cache -f operator/Dockerfile -t {{.OPERATOR_IMAGE}} --build-arg OPERATOR_LICENSE_ISSUER_PUBLIC_KEY="$(cat {{.SCRIPTS_DIR}}/license-issuer.pem)" operator
7275
- task: operator:image:load
7376

7477
build:operator:gcs:
@@ -86,7 +89,7 @@ tasks:
8689
msg: "GCS_BUCKET required"
8790
cmds:
8891
- |
89-
cd {{.OPERATOR_DIR}}/.. && docker build -f operator/Dockerfile -t {{.OPERATOR_IMAGE}} \
92+
cd {{.OPERATOR_DIR}}/.. && docker build --provenance=false -f operator/Dockerfile -t {{.OPERATOR_IMAGE}} \
9093
--secret id=gcp_credentials,src={{.GCS_CREDENTIALS_FILE}} \
9194
--build-arg OPERATOR_LICENSE_ISSUER_PUBLIC_KEY="$(cat {{.SCRIPTS_DIR}}/license-issuer.pem)" \
9295
--build-arg GCS_BUCKET={{.GCS_BUCKET}} \
@@ -113,7 +116,7 @@ tasks:
113116
msg: "Custom issuer file not found"
114117
cmds:
115118
- |
116-
cd {{.OPERATOR_DIR}}/.. && docker build -f operator/Dockerfile -t {{.OPERATOR_IMAGE}} \
119+
cd {{.OPERATOR_DIR}}/.. && docker build --provenance=false -f operator/Dockerfile -t {{.OPERATOR_IMAGE}} \
117120
--secret id=gcp_credentials,src={{.GCS_CREDENTIALS_FILE}} \
118121
--build-arg OPERATOR_LICENSE_ISSUER_PUBLIC_KEY="$(cat {{.CUSTOM_ISSUER_FILE}})" \
119122
--build-arg GCS_BUCKET={{.GCS_BUCKET}} \
@@ -145,41 +148,41 @@ tasks:
145148
--build-arg GCS_PATH_PREFIX={{.MIRRORD_AGENT_GCS_PREFIX}} \
146149
.
147150
- task: mirrord:agent:image:load
148-
vars: {AGENT_IMAGE: '{{.AGENT_IMAGE}}'}
151+
vars: { AGENT_IMAGE: "{{.AGENT_IMAGE}}" }
149152

150153
build:app:sqs:
151154
desc: Build SQS consumer app
152155
dir: "{{.ROOT_DIR}}/apps/sqs-consumer"
153156
cmds:
154-
- '{{.CONTAINER_RUNTIME}} build -t sqs-consumer:local .'
157+
- "{{.CONTAINER_RUNTIME}} build -t sqs-consumer:local ."
155158
- minikube -p {{.CLUSTER_NAME}} image load sqs-consumer:local
156159

157160
build:app:kafka:
158161
desc: Build Kafka consumer app
159162
dir: "{{.ROOT_DIR}}/apps/kafka-consumer"
160163
cmds:
161-
- '{{.CONTAINER_RUNTIME}} build -t kafka-consumer:local .'
164+
- "{{.CONTAINER_RUNTIME}} build -t kafka-consumer:local ."
162165
- minikube -p {{.CLUSTER_NAME}} image load kafka-consumer:local
163166

164167
build:app:mysql:
165168
desc: Build MySQL app
166169
dir: "{{.ROOT_DIR}}/apps/mysql-app"
167170
cmds:
168-
- '{{.CONTAINER_RUNTIME}} build -t mysql-app:local .'
171+
- "{{.CONTAINER_RUNTIME}} build -t mysql-app:local ."
169172
- minikube -p {{.CLUSTER_NAME}} image load mysql-app:local
170173

171174
build:app:postgres:
172175
desc: Build PostgreSQL app
173176
dir: "{{.ROOT_DIR}}/apps/postgres-app"
174177
cmds:
175-
- '{{.CONTAINER_RUNTIME}} build -t postgres-app:local .'
178+
- "{{.CONTAINER_RUNTIME}} build -t postgres-app:local ."
176179
- minikube -p {{.CLUSTER_NAME}} image load postgres-app:local
177180

178181
build:app:mongodb:
179182
desc: Build MongoDB app
180183
dir: "{{.ROOT_DIR}}/apps/mongodb-app"
181184
cmds:
182-
- '{{.CONTAINER_RUNTIME}} build -t mongodb-app:local .'
185+
- "{{.CONTAINER_RUNTIME}} build -t mongodb-app:local ."
183186
- minikube -p {{.CLUSTER_NAME}} image load mongodb-app:local
184187

185188
build:apps:
@@ -348,20 +351,14 @@ tasks:
348351
echo "Press Ctrl+C to stop port-forward"
349352
wait $PF_PID
350353
351-
logs:operator:
352-
desc: Query operator logs from Loki
353-
cmds:
354-
- |
355-
echo "=== Operator Logs ==="
356-
echo "Query: {namespace=\"mirrord\", app=\"mirrord-operator\"}"
357-
kubectl logs -n mirrord -l app=mirrord-operator --tail=100 -f
358-
359354
operator:install:
360355
desc: Install operator with custom image
361356
deps: [infra:all, build:operator]
362357
cmds:
363358
- helm upgrade --install mirrord-operator {{.CHARTS_DIR}} --namespace mirrord --create-namespace -f {{.ROOT_DIR}}/operator-values.yaml
364359
- task: license:create:secret
360+
# Force pod restart to pick up the new image
361+
- kubectl delete pods -n mirrord -l app=mirrord-operator --force --grace-period=0 2>/dev/null || true
365362
- task: _wait:operator
366363

367364
operator:install:nocache:
@@ -370,6 +367,8 @@ tasks:
370367
cmds:
371368
- helm upgrade --install mirrord-operator {{.CHARTS_DIR}} --namespace mirrord --create-namespace -f {{.ROOT_DIR}}/operator-values.yaml
372369
- task: license:create:secret
370+
# Force pod restart to pick up the new image
371+
- kubectl delete pods -n mirrord -l app=mirrord-operator --force --grace-period=0 2>/dev/null || true
373372
- task: _wait:operator
374373

375374
operator:install:nobuild:
@@ -379,6 +378,8 @@ tasks:
379378
- task: operator:image:load
380379
- helm upgrade --install mirrord-operator {{.CHARTS_DIR}} --namespace mirrord --create-namespace -f {{.ROOT_DIR}}/operator-values.yaml
381380
- task: license:create:secret
381+
# Force pod restart to pick up the new image
382+
- kubectl delete pods -n mirrord -l app=mirrord-operator --force --grace-period=0 2>/dev/null || true
382383
- task: _wait:operator
383384

384385
operator:install:new:license:
@@ -404,7 +405,7 @@ tasks:
404405
operator:image:load:
405406
desc: Tag and load operator image into minikube
406407
cmds:
407-
- '{{.CONTAINER_RUNTIME}} tag {{.OPERATOR_IMAGE}} mirrord-operator:{{.CHART_VERSION}}'
408+
- "{{.CONTAINER_RUNTIME}} tag {{.OPERATOR_IMAGE}} mirrord-operator:{{.CHART_VERSION}}"
408409
- minikube -p {{.CLUSTER_NAME}} ssh "{{.CONTAINER_RUNTIME}} rmi mirrord-operator:{{.CHART_VERSION}} --force" || true
409410
- minikube -p {{.CLUSTER_NAME}} image load mirrord-operator:{{.CHART_VERSION}}
410411

@@ -420,6 +421,8 @@ tasks:
420421
desc: Update helm chart only
421422
cmds:
422423
- helm upgrade --install mirrord-operator {{.CHARTS_DIR}} --namespace mirrord -f {{.ROOT_DIR}}/operator-values.yaml
424+
# Force pod restart to pick up any changes
425+
- kubectl delete pods -n mirrord -l app=mirrord-operator --force --grace-period=0 2>/dev/null || true
423426
- task: _wait:operator
424427

425428
test:mysql:
@@ -502,7 +505,6 @@ tasks:
502505
- task: cluster:delete
503506
- task: cluster:create
504507
- task: build:app:postgres
505-
- task: license:create:secret
506508
- task: operator:install:nobuild
507509
- task: postgres:test
508510

@@ -743,7 +745,6 @@ tasks:
743745
sleep 2
744746
done
745747
done
746-
- task: multicluster:kubeconfig:generate
747748
- task: multicluster:test:verify:clusters
748749
- echo "Loading images to minikube clusters..."
749750
- task: multicluster:operator:load:images
@@ -757,8 +758,8 @@ tasks:
757758
- echo "Deploying echo apps..."
758759
- task: multicluster:test:deploy:echo-apps
759760
- echo "Waiting for apps to be ready..."
760-
- 'kubectl --context mirrord-primary wait --for=condition=available deploy/echo-app -n test-multicluster --timeout=120s'
761-
- 'kubectl --context mirrord-remote-1 wait --for=condition=available deploy/echo-app -n test-multicluster --timeout=120s'
761+
- "kubectl --context mirrord-primary wait --for=condition=available deploy/echo-app -n test-multicluster --timeout=120s"
762+
- "kubectl --context mirrord-remote-1 wait --for=condition=available deploy/echo-app -n test-multicluster --timeout=120s"
762763
- echo ""
763764
- echo "============================================"
764765
- echo " SETUP COMPLETE - Ready for testing!"
@@ -816,7 +817,6 @@ tasks:
816817
sleep 2
817818
done
818819
done
819-
- task: multicluster:kubeconfig:generate
820820
- task: multicluster:test:verify:clusters
821821
- echo "Loading images to minikube clusters..."
822822
- task: multicluster:operator:load:images
@@ -829,8 +829,8 @@ tasks:
829829
- echo "Deploying echo apps..."
830830
- task: multicluster:test:deploy:echo-apps
831831
- echo "Waiting for apps to be ready..."
832-
- 'kubectl --context mirrord-primary wait --for=condition=available deploy/echo-app -n test-multicluster --timeout=120s'
833-
- 'kubectl --context mirrord-remote-1 wait --for=condition=available deploy/echo-app -n test-multicluster --timeout=120s'
832+
- "kubectl --context mirrord-primary wait --for=condition=available deploy/echo-app -n test-multicluster --timeout=120s"
833+
- "kubectl --context mirrord-remote-1 wait --for=condition=available deploy/echo-app -n test-multicluster --timeout=120s"
834834
- echo ""
835835
- echo "============================================"
836836
- echo " SETUP COMPLETE - Ready for testing!"
@@ -901,12 +901,12 @@ tasks:
901901
test:tls:certs:
902902
desc: Test TLS certificate configuration
903903
cmds:
904-
- '{{.SCRIPTS_DIR}}/test-tls-certificates.sh'
904+
- "{{.SCRIPTS_DIR}}/test-tls-certificates.sh"
905905

906906
test:tls:quick:
907907
desc: Quick TLS test
908908
cmds:
909-
- '{{.SCRIPTS_DIR}}/quick-tls-test.sh'
909+
- "{{.SCRIPTS_DIR}}/quick-tls-test.sh"
910910

911911
clean:namespaces:
912912
desc: Delete all test namespaces
@@ -992,7 +992,7 @@ tasks:
992992
describe:pod:
993993
desc: Describe a pod (shows events and state history)
994994
vars:
995-
POD: '{{.POD}}'
995+
POD: "{{.POD}}"
996996
NAMESPACE: '{{.NAMESPACE | default "default"}}'
997997
preconditions:
998998
- sh: test -n "{{.POD}}"
@@ -1003,7 +1003,7 @@ tasks:
10031003
logs:previous:
10041004
desc: Show logs from previous container instance (after crash)
10051005
vars:
1006-
POD: '{{.POD}}'
1006+
POD: "{{.POD}}"
10071007
NAMESPACE: '{{.NAMESPACE | default "default"}}'
10081008
preconditions:
10091009
- sh: test -n "{{.POD}}"
@@ -1020,20 +1020,20 @@ tasks:
10201020
- |
10211021
echo "=== Finding last {{.COUNT}} crashed/restarted pods ==="
10221022
echo ""
1023-
1023+
10241024
# Get pods with restarts > 0 or in error state, sorted by restart time
10251025
PODS=$(kubectl get pods --all-namespaces --no-headers 2>/dev/null | \
10261026
awk '($5 > 0) || ($4 ~ /Error|CrashLoop|OOMKilled/) {print $1, $2, $5}' | \
10271027
head -{{.COUNT}})
1028-
1028+
10291029
if [ -z "$PODS" ]; then
10301030
echo "No crashed or restarted pods found."
10311031
echo ""
10321032
echo "Looking for pods with any issues..."
10331033
kubectl get pods --all-namespaces | grep -v "Running\|Completed\|NAMESPACE" | head -{{.COUNT}}
10341034
exit 0
10351035
fi
1036-
1036+
10371037
echo "$PODS" | while read ns pod restarts; do
10381038
echo "=============================================="
10391039
echo "POD: $pod"
@@ -1062,17 +1062,17 @@ tasks:
10621062
- |
10631063
echo "=== Pods with recent warning events ==="
10641064
echo ""
1065-
1065+
10661066
# Get pods from recent warning events
10671067
PODS=$(kubectl get events --all-namespaces --field-selector type!=Normal \
10681068
--sort-by='.lastTimestamp' -o jsonpath='{range .items[*]}{.involvedObject.namespace}{" "}{.involvedObject.name}{"\n"}{end}' 2>/dev/null | \
10691069
grep -v "^$" | tail -{{.COUNT}} | tac)
1070-
1070+
10711071
if [ -z "$PODS" ]; then
10721072
echo "No recent warning events found."
10731073
exit 0
10741074
fi
1075-
1075+
10761076
echo "$PODS" | while read ns pod; do
10771077
if [ -n "$pod" ] && kubectl get pod "$pod" -n "$ns" >/dev/null 2>&1; then
10781078
echo "=============================================="
@@ -1130,6 +1130,14 @@ tasks:
11301130
cmds:
11311131
- redis-cli -p {{.REDIS_PORT}}
11321132

1133+
redis:local:cli:second:
1134+
desc: "Open redis-cli to local Redis"
1135+
vars:
1136+
REDIS_PORT: '{{.REDIS_PORT | default "6380"}}'
1137+
interactive: true
1138+
cmds:
1139+
- redis-cli -p {{.REDIS_PORT}}
1140+
11331141
redis:local:test:
11341142
desc: "Test local Redis connection"
11351143
vars:

apps/echo-app/echo-app

336 Bytes
Binary file not shown.

apps/echo-app/main.go

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -112,25 +112,53 @@ func handleEcho(w http.ResponseWriter, r *http.Request) {
112112
// Echo back the request with cluster info
113113
body, _ := io.ReadAll(r.Body)
114114

115-
// Check for source cluster header (set by traffic generator)
116-
sourceCluster := r.Header.Get("X-Source-Cluster")
117-
if sourceCluster == "" {
118-
sourceCluster = "unknown"
115+
// Check for filter header (for HTTP filter testing)
116+
filterHeader := r.Header.Get("X-My-Header")
117+
118+
// Print formatted multi-line log
119+
log.Printf("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
120+
log.Printf("[%s] ECHO #%d", clusterID, reqNum)
121+
log.Printf(" Method: %s %s", r.Method, r.URL.Path)
122+
if r.URL.RawQuery != "" {
123+
log.Printf(" Query: %s", r.URL.RawQuery)
124+
}
125+
if filterHeader != "" {
126+
log.Printf(" Filter: X-My-Header = %s ", filterHeader)
127+
}
128+
if len(body) > 0 {
129+
if len(body) > 100 {
130+
log.Printf(" Body: (%d bytes) %s...", len(body), string(body[:100]))
131+
} else {
132+
log.Printf(" Body: %s", string(body))
133+
}
134+
}
135+
// Print other interesting headers
136+
for _, h := range []string{"Content-Type", "User-Agent", "X-Request-Id"} {
137+
if v := r.Header.Get(h); v != "" {
138+
log.Printf(" %s: %s", h, v)
139+
}
119140
}
120-
121-
log.Printf("[%s] ECHO #%d: %s %s - From: %s - Body: %s",
122-
clusterID, reqNum, r.Method, r.URL.Path, sourceCluster, string(body))
123141

124142
w.Header().Set("Content-Type", "application/json")
125143
w.Header().Set("X-Cluster-ID", clusterID)
126144

145+
// Collect all headers for response
146+
headers := make(map[string]string)
147+
for key, values := range r.Header {
148+
if len(values) > 0 {
149+
headers[key] = values[0]
150+
}
151+
}
152+
127153
response := map[string]interface{}{
128-
"cluster_id": clusterID,
129-
"request_num": reqNum,
130-
"echo_body": string(body),
131-
"echo_path": r.URL.Path,
132-
"echo_method": r.Method,
133-
"echo_query": r.URL.RawQuery,
154+
"cluster_id": clusterID,
155+
"request_num": reqNum,
156+
"filter_header": filterHeader,
157+
"echo_body": string(body),
158+
"echo_path": r.URL.Path,
159+
"echo_method": r.Method,
160+
"echo_query": r.URL.RawQuery,
161+
"headers": headers,
134162
}
135163

136164
json.NewEncoder(w).Encode(response)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"target": {
3+
"path": "deploy/echo-app",
4+
"namespace": "test-multicluster"
5+
},
6+
"feature": {
7+
"network": {
8+
"incoming": {
9+
"mode": "steal"
10+
}
11+
}
12+
}
13+
}

0 commit comments

Comments
 (0)