Skip to content

Commit b1a3e2a

Browse files
committed
feat: add Knative integration for notifications
- Add CloudEvents sink deployment for eoapi-notifier integration - Configure dynamic secret name for PostgreSQL connection - Add local development configuration with reduced resources - Support both CI and local test environments
1 parent 878a10d commit b1a3e2a

File tree

13 files changed

+454
-80
lines changed

13 files changed

+454
-80
lines changed

.github/workflows/helm-tests.yml

Lines changed: 95 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ jobs:
2525
- name: Run Helm unit tests
2626
run: make tests
2727

28-
integration:
29-
name: Integration Tests (K3s)
28+
k3s-integration-tests:
29+
name: K3s Integration Tests
3030
if: github.event.pull_request.head.repo.full_name == github.repository
3131
permissions:
3232
contents: 'read'
@@ -47,106 +47,128 @@ jobs:
4747
- name: Set release name
4848
run: echo "RELEASE_NAME=eoapi-$(echo "${{ github.sha }}" | cut -c1-8)" >> "$GITHUB_ENV"
4949

50-
- name: Deploy eoAPI
51-
id: deploy
52-
continue-on-error: true
50+
- name: Wait for K3s to be fully ready
5351
run: |
54-
echo "=== Starting eoAPI deployment ==="
55-
export RELEASE_NAME="$RELEASE_NAME"
56-
export PGO_VERSION="${{ env.PGO_VERSION }}"
57-
export GITHUB_SHA="${{ github.sha }}"
58-
./scripts/deploy.sh --ci
52+
echo "=== Waiting for K3s to be fully ready ==="
5953
60-
- name: Check deployment status
61-
id: check
62-
if: steps.deploy.outcome == 'success'
63-
run: |
64-
echo "=== Checking deployment status ==="
65-
export RELEASE_NAME="$RELEASE_NAME"
66-
./scripts/test.sh check-deployment --debug
54+
# Wait for core K3s components to be ready
55+
echo "Waiting for kube-system pods to be ready..."
56+
kubectl wait --for=condition=Ready pod -l k8s-app=kube-dns -n kube-system --timeout=300s
57+
kubectl wait --for=condition=Ready pod -l app.kubernetes.io/name=traefik -n kube-system --timeout=300s
6758
68-
- name: Debug pgstac jobs if deployment failed
69-
if: steps.deploy.outcome == 'failure'
70-
continue-on-error: true
71-
run: |
72-
echo "=== Debugging pgstac job failures ==="
73-
74-
# Check pgstac-migrate job
75-
echo "===== pgstac-migrate Job Status ====="
76-
kubectl get jobs -l app.kubernetes.io/name=pgstac-migrate -o wide || echo "No pgstac-migrate jobs found"
77-
78-
MIGRATE_PODS=$(kubectl get pods -l app.kubernetes.io/name=pgstac-migrate -o jsonpath='{.items[*].metadata.name}' 2>/dev/null)
79-
if [ -n "$MIGRATE_PODS" ]; then
80-
for POD in $MIGRATE_PODS; do
81-
echo "--- Logs from migrate pod $POD ---"
82-
kubectl logs "$POD" --tail=100 || true
83-
echo "--- Description of migrate pod $POD ---"
84-
kubectl describe pod "$POD"
85-
done
86-
fi
87-
88-
# Check pgstac-load-samples job
89-
echo "===== pgstac-load-samples Job Status ====="
90-
kubectl get jobs -l app.kubernetes.io/name=pgstac-load-samples -o wide || echo "No pgstac-load-samples jobs found"
91-
92-
SAMPLES_PODS=$(kubectl get pods -l app.kubernetes.io/name=pgstac-load-samples -o jsonpath='{.items[*].metadata.name}' 2>/dev/null)
93-
if [ -n "$SAMPLES_PODS" ]; then
94-
for POD in $SAMPLES_PODS; do
95-
echo "--- Logs from samples pod $POD ---"
96-
kubectl logs "$POD" --tail=100 || true
97-
echo "--- Description of samples pod $POD ---"
98-
kubectl describe pod "$POD"
99-
done
100-
fi
59+
# Wait for API server to be fully responsive
60+
echo "Checking API server responsiveness..."
61+
kubectl get nodes
62+
kubectl get pods --all-namespaces
10163
102-
# Check database status
103-
echo "===== Database Pod Status ====="
104-
kubectl get pods -l postgres-operator.crunchydata.com/cluster -o wide
105-
kubectl get postgrescluster -o wide
64+
# Give K3s a moment to initialize all CRDs
65+
echo "Waiting for K3s initialization to complete..."
66+
sleep 10
10667
107-
# Check ConfigMaps
108-
echo "===== Relevant ConfigMaps ====="
109-
kubectl get configmaps | grep -E "initdb|pgstac" || echo "No relevant configmaps found"
68+
echo "✅ K3s is ready"
11069
111-
# Check for any related events
112-
echo "===== Related Kubernetes Events ====="
113-
kubectl get events | grep -E "pgstac|initdb" || echo "No relevant events found"
11470
115-
# Check notification system status
116-
echo "===== Notification System Status ====="
117-
kubectl get deployments -l app.kubernetes.io/name=eoapi-notifier -o wide || echo "No eoapi-notifier deployment found"
118-
kubectl get ksvc -l app.kubernetes.io/component=cloudevents-sink -o wide || echo "No Knative CloudEvents sink found"
71+
- name: Wait for Traefik to be ready
72+
run: |
73+
echo "=== Waiting for Traefik to be ready ==="
74+
75+
# Wait for Traefik pods to be ready first
76+
echo "Waiting for Traefik controller to be ready..."
77+
kubectl wait --for=condition=Ready pod -l app.kubernetes.io/name=traefik -n kube-system --timeout=300s
78+
79+
# Wait for essential Traefik CRDs to be available
80+
echo "Checking for Traefik CRDs..."
81+
timeout=300
82+
counter=0
83+
required_crds=("middlewares.traefik.io" "ingressroutes.traefik.io")
84+
85+
for crd in "${required_crds[@]}"; do
86+
echo "Checking for CRD: $crd"
87+
counter=0
88+
while [ $counter -lt $timeout ]; do
89+
if kubectl get crd "$crd" &>/dev/null; then
90+
echo "✅ $crd is available"
91+
break
92+
fi
93+
echo "⏳ Waiting for $crd... ($counter/$timeout)"
94+
sleep 3
95+
counter=$((counter + 3))
96+
done
97+
98+
if [ $counter -ge $timeout ]; then
99+
echo "❌ Timeout waiting for $crd"
100+
echo "Available Traefik CRDs:"
101+
kubectl get crd | grep traefik || echo "No Traefik CRDs found"
102+
echo "All CRDs:"
103+
kubectl get crd
104+
exit 1
105+
fi
106+
done
107+
108+
echo "✅ All required Traefik CRDs are ready"
119109
120-
exit 1
110+
- name: Deploy eoAPI
111+
id: deploy
112+
run: |
113+
echo "=== Starting eoAPI deployment ==="
114+
export RELEASE_NAME="$RELEASE_NAME"
115+
export PGO_VERSION="${{ env.PGO_VERSION }}"
116+
export GITHUB_SHA="${{ github.sha }}"
117+
./scripts/deploy.sh --ci
121118
122119
- name: Run integration tests
123-
if: steps.deploy.outcome == 'success'
124120
run: |
125121
echo "=== Running integration tests ==="
126122
export RELEASE_NAME="$RELEASE_NAME"
127123
./scripts/test.sh integration --debug
128124
129-
- name: Debug deployment status
130-
if: always()
125+
- name: Debug failed deployment
126+
if: failure()
131127
run: |
132-
echo "=== Final Deployment Status ==="
128+
echo "=== Deployment failed - collecting debug information ==="
133129
kubectl get pods -o wide
134130
kubectl get jobs -o wide
135131
kubectl get services -o wide
136-
kubectl get ingress
132+
kubectl get events --sort-by='.lastTimestamp' | tail -20 || true
133+
134+
# Check Knative installation status
135+
echo "=== Knative Installation Status ==="
136+
kubectl get pods -n knative-serving -o wide || echo "Knative Serving not installed"
137+
kubectl get pods -n knative-eventing -o wide || echo "Knative Eventing not installed"
138+
kubectl get pods -n kourier-system -o wide || echo "Kourier not installed"
139+
# Check Knative CRDs
140+
echo "=== Knative CRDs Status ==="
141+
kubectl get crd | grep knative || echo "No Knative CRDs found"
142+
kubectl get crd sinkbindings.sources.knative.dev || echo "SinkBinding CRD not found"
143+
144+
# Check Traefik status
145+
echo "=== Traefik Status ==="
146+
kubectl get pods -n kube-system -l app.kubernetes.io/name=traefik -o wide || echo "No Traefik pods found"
147+
kubectl get crd | grep traefik || echo "No Traefik CRDs found"
148+
kubectl get crd middlewares.traefik.io || echo "Middleware CRD not found"
149+
kubectl get crd ingressroutes.traefik.io || echo "IngressRoute CRD not found"
137150
138151
# Check notification system final status
139152
echo "=== Notification System Final Status ==="
140153
kubectl get deployments -l app.kubernetes.io/name=eoapi-notifier -o wide || echo "No eoapi-notifier deployment"
141154
kubectl get pods -l app.kubernetes.io/name=eoapi-notifier -o wide || echo "No eoapi-notifier pods"
142-
kubectl get ksvc -l app.kubernetes.io/component=cloudevents-sink -o wide || echo "No Knative CloudEvents sink"
143-
kubectl get pods -l serving.knative.dev/service -o wide || echo "No Knative CloudEvents sink pods"
155+
kubectl get ksvc -n eoapi -o wide || echo "No Knative services in eoapi namespace"
156+
kubectl get ksvc eoapi-cloudevents-sink -n eoapi -o wide || echo "No eoapi-cloudevents-sink Knative service"
157+
kubectl get pods -l serving.knative.dev/service=eoapi-cloudevents-sink -n eoapi -o wide || echo "No CloudEvents sink pods"
158+
# Check SinkBinding resources
159+
echo "=== SinkBinding Resources ==="
160+
kubectl get sinkbindings -A -o wide || echo "No SinkBinding resources found"
144161
145162
# Show notification logs if they exist
146163
echo "=== eoapi-notifier Logs ==="
147164
kubectl logs -l app.kubernetes.io/name=eoapi-notifier --tail=20 || echo "No eoapi-notifier logs"
148165
echo "=== Knative CloudEvents Sink Logs ==="
149-
kubectl logs -l serving.knative.dev/service --tail=20 || echo "No Knative CloudEvents sink logs"
166+
kubectl logs -l serving.knative.dev/service=eoapi-cloudevents-sink -n eoapi --tail=20 || echo "No CloudEvents sink logs"
167+
# Show Knative system logs if there are issues
168+
echo "=== Knative Serving Controller Logs ==="
169+
kubectl logs -n knative-serving -l app=controller --tail=20 || echo "No Knative Serving controller logs"
170+
echo "=== Knative Eventing Controller Logs ==="
171+
kubectl logs -n knative-eventing -l app=eventing-controller --tail=20 || echo "No Knative Eventing controller logs"
150172
151173
152174
- name: Cleanup

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ charts/config.yaml
55
charts/eoapi/charts/*.tgz
66
config_ingress.yaml
77
__pycache__
8+
9+
CLAUDE.md

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
- Added knative in CI to test eoapi-notifier.
11+
1012
## [0.7.12] - 2025-10-17
1113

1214
- Bumped eoapi-notifier dependency version to 0.0.7

charts/eoapi/Chart.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ dependencies:
5454
repository: "https://devseed.com/eoapi-k8s/"
5555
condition: postgrescluster.enabled
5656
- name: eoapi-notifier
57-
version: 0.0.7
57+
version: 0.0.8
5858
repository: "oci://ghcr.io/developmentseed/charts"
5959
condition: eoapi-notifier.enabled
60+
- name: knative-operator
61+
version: 1.19.4
62+
repository: https://knative.github.io/operator
63+
condition: knative.enabled
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{{- if and (index .Values "eoapi-notifier").enabled .Values.knative.enabled .Values.knative.cloudEventsSink.enabled }}
2+
{{- range (index .Values "eoapi-notifier").outputs }}
3+
{{- if eq .type "cloudevents" }}
4+
---
5+
apiVersion: serving.knative.dev/v1
6+
kind: Service
7+
metadata:
8+
name: eoapi-cloudevents-sink
9+
namespace: {{ $.Release.Namespace }}
10+
labels:
11+
{{- include "eoapi.labels" $ | nindent 4 }}
12+
app.kubernetes.io/component: cloudevents-sink
13+
annotations:
14+
helm.sh/hook: "post-install,post-upgrade"
15+
helm.sh/hook-weight: "5"
16+
helm.sh/hook-delete-policy: "before-hook-creation"
17+
spec:
18+
template:
19+
metadata:
20+
annotations:
21+
autoscaling.knative.dev/minScale: "1"
22+
autoscaling.knative.dev/maxScale: "1"
23+
labels:
24+
{{- include "eoapi.selectorLabels" $ | nindent 8 }}
25+
app.kubernetes.io/component: cloudevents-sink
26+
spec:
27+
containers:
28+
- name: cloudevents-sink
29+
image: {{ $.Values.knative.cloudEventsSink.image }}
30+
ports:
31+
- containerPort: 8080
32+
env:
33+
- name: TARGET
34+
value: "CloudEvents Sink"
35+
resources:
36+
{{- toYaml $.Values.knative.cloudEventsSink.resources | nindent 10 }}
37+
{{- break }}
38+
{{- end }}
39+
{{- end }}
40+
{{- end }}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
{{- if .Values.knative.enabled }}
2+
apiVersion: batch/v1
3+
kind: Job
4+
metadata:
5+
name: {{ .Release.Name }}-knative-init
6+
namespace: {{ .Release.Namespace }}
7+
labels:
8+
{{- include "eoapi.labels" . | nindent 4 }}
9+
app.kubernetes.io/component: knative-init
10+
annotations:
11+
helm.sh/hook: "post-install,post-upgrade"
12+
helm.sh/hook-weight: "1"
13+
helm.sh/hook-delete-policy: "before-hook-creation,hook-succeeded"
14+
spec:
15+
template:
16+
metadata:
17+
name: {{ .Release.Name }}-knative-init
18+
labels:
19+
{{- include "eoapi.labels" . | nindent 8 }}
20+
app.kubernetes.io/component: knative-init
21+
spec:
22+
restartPolicy: Never
23+
containers:
24+
- name: knative-init
25+
image: bitnami/kubectl:latest
26+
imagePullPolicy: IfNotPresent
27+
command:
28+
- /bin/bash
29+
- -c
30+
- |
31+
set -e
32+
echo "=== Knative Initialization ==="
33+
34+
# Wait for knative-operator to be ready
35+
echo "Waiting for knative-operator..."
36+
kubectl rollout status deployment/knative-operator -n default --timeout=300s
37+
38+
# Create namespaces
39+
kubectl create namespace knative-serving --dry-run=client -o yaml | kubectl apply -f -
40+
kubectl create namespace knative-eventing --dry-run=client -o yaml | kubectl apply -f -
41+
42+
# Create KnativeServing
43+
cat <<EOF | kubectl apply -f -
44+
apiVersion: operator.knative.dev/v1beta1
45+
kind: KnativeServing
46+
metadata:
47+
name: knative-serving
48+
namespace: knative-serving
49+
spec:
50+
version: {{ .Values.knative.version | quote }}
51+
EOF
52+
53+
# Create KnativeEventing
54+
cat <<EOF | kubectl apply -f -
55+
apiVersion: operator.knative.dev/v1beta1
56+
kind: KnativeEventing
57+
metadata:
58+
name: knative-eventing
59+
namespace: knative-eventing
60+
spec:
61+
version: {{ .Values.knative.version | quote }}
62+
EOF
63+
64+
echo "✅ Knative CRs created. Operator will install CRDs."
65+
66+
resources:
67+
requests:
68+
cpu: 50m
69+
memory: 64Mi
70+
limits:
71+
cpu: 100m
72+
memory: 128Mi
73+
backoffLimit: 3
74+
activeDeadlineSeconds: 600
75+
{{- end }}

charts/eoapi/templates/services/rbac.yaml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,38 @@ rules:
1010
resources: ["jobs"]
1111
verbs: ["get", "list", "watch"]
1212
---
13+
{{- if .Values.knative.enabled }}
14+
apiVersion: rbac.authorization.k8s.io/v1
15+
kind: ClusterRole
16+
metadata:
17+
name: eoapi-cluster-role-{{ $.Release.Name }}
18+
labels:
19+
app: eoapi-{{ $.Release.Name }}
20+
rules:
21+
- apiGroups: ["apiextensions.k8s.io"]
22+
resources: ["customresourcedefinitions"]
23+
verbs: ["get", "list"]
24+
- apiGroups: [""]
25+
resources: ["pods"]
26+
verbs: ["get", "list"]
27+
---
28+
apiVersion: rbac.authorization.k8s.io/v1
29+
kind: ClusterRoleBinding
30+
metadata:
31+
name: eoapi-cluster-rolebinding-{{ $.Release.Name }}
32+
labels:
33+
app: eoapi-{{ $.Release.Name }}
34+
subjects:
35+
- kind: ServiceAccount
36+
name: {{ include "eoapi.serviceAccountName" . }}
37+
namespace: {{ $.Release.Namespace }}
38+
roleRef:
39+
kind: ClusterRole
40+
name: eoapi-cluster-role-{{ $.Release.Name }}
41+
apiGroup: rbac.authorization.k8s.io
42+
---
43+
{{- end }}
44+
---
1345
apiVersion: rbac.authorization.k8s.io/v1
1446
kind: RoleBinding
1547
metadata:

0 commit comments

Comments
 (0)