-
Notifications
You must be signed in to change notification settings - Fork 3
179 lines (150 loc) · 6.67 KB
/
test-k8s-service-apps-proxy.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
name: 'K8S: Apps Proxy'
on:
# This workflow is also part of the release pipeline,
# in that case, the actual version is deployed twice.
workflow_call:
# In PR the previous version is deployed first and then the actual version.
pull_request:
paths:
- .github/workflows/test-k8s-service-apps-proxy.yml
- provisioning/apps-proxy/**
- provisioning/common/**
# When the config structure is changed it may be necessary to adjust k8s configmap.
- internal/pkg/service/appsproxy/config/**
env:
MINIKUBE_PROFILE: apps-proxy
MINIKUBE_DRIVER: docker
KUBERNETES_NAMESPACE: apps-proxy
KUBERNETES_ROLLOUT_WAIT: 200s
REMOVE_RESOURCES_LIMITS: true
SERVICE_NAME: Apps Proxy
API_RELEASE_NAME: apps-proxy
METRICS_PORT: 9000
defaults:
run:
working-directory: provisioning/apps-proxy
jobs:
test:
name: "K8S test: Data Apps Proxy"
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.ref }}
- name: Create artifacts directory
run: mkdir -p /tmp/artifacts
- name: Copy latest scripts to a temp dir
run: cp -R ${{ github.workspace }}/provisioning/common/scripts /tmp/latest-scripts
- name: Install gron tool
run: |
url="https://github.com/tomnomnom/gron/releases/download/v0.7.1/gron-linux-amd64-0.7.1.tgz"
curl -L "$url" | tar -xz -C /usr/local/bin
- name: Install MiniKube
run: /tmp/latest-scripts/minikube/install.sh
- name: Start MiniKube
run: /tmp/latest-scripts/minikube/start.sh
- name: Set Kubernetes namespace
run: kubectl config set-context --current "--namespace=$KUBERNETES_NAMESPACE"
- name: Checkout BASE branch (or HEAD if it is not a pull request)
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.base.ref }}
- name: Deploy the old version, from the BASE branch
continue-on-error: true
run: ./deploy_local.sh
- name: Dump the old version (for diff)
continue-on-error: true
run: sleep 10 && /tmp/latest-scripts/k8s/dump.sh /tmp/artifacts/test-k8s-state.old.json
- name: Checkout HEAD branch
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.ref }}
- name: Deploy the new version, from the HEAD branch
run: ./deploy_local.sh
- name: Dump the new version (for diff)
if: always()
run: |
set -Eeuo pipefail
# Delete empty old replica sets
emptyReplicaSets=$(kubectl get replicasets --ignore-not-found | tail --lines=+2 | awk '{if ($2 + $3 + $4 == 0) print $1}')
echo -e "Found empty replica sets:"
echo "$emptyReplicaSets"
echo "-------------------------"
echo "$emptyReplicaSets" | xargs --no-run-if-empty -I {} kubectl delete replicaset "{}"
# Wait for pod startup/termination
sleep 10
# Dump objects
/tmp/latest-scripts/k8s/dump.sh /tmp/artifacts/test-k8s-state.new.json
- name: Check deployment of the API nodes
if: always()
run: kubectl rollout status "deployment/$API_RELEASE_NAME" --timeout=10s
- name: Check access to API metrics from the DataDog Agent
if: always()
run: |
set -Eeuo pipefail
kubectl create namespace datadog || true
export POD_IP=`kubectl get pod -l app=apps-proxy -o=jsonpath='{.items[0].status.podIP}'`
echo "Pod IP: $POD_IP"
kubectl run --attach --rm --restart=Never check-api-datadog \
--namespace datadog \
--image docker.io/alpine/curl \
--labels="app=datadog-agent" \
--env="POD_IP=$POD_IP" \
--env="METRICS_PORT=$METRICS_PORT" \
--command -- sh -c "set -eo pipefail; curl -f -L --max-time 5 "$POD_IP:$METRICS_PORT/metrics" | tail"
- name: Check forbidden access to the API metrics from other places
if: always()
run: |
set -Eeuo pipefail
export POD_IP=`kubectl get pod -l app=apps-proxy -o=jsonpath='{.items[0].status.podIP}'`
echo "Pod IP: $POD_IP"
if kubectl run --attach --rm --restart=Never check-api-other \
--image docker.io/alpine/curl \
--env="POD_IP=$POD_IP" \
--env="METRICS_PORT=$METRICS_PORT" \
--command -- sh -c "set -eo pipefail; curl -f -L --max-time 5 "$POD_IP:$METRICS_PORT/metrics" | tail"; then
echo "The command did not fail, but it should have."
exit 1
else
echo "The command failed, OK."
exit 0
fi
- name: Check Proxy response
if: always()
run: curl --fail -L -s --max-time 5 "$(minikube service --url $API_RELEASE_NAME --namespace $KUBERNETES_NAMESPACE)/health-check"
- name: Diff the old and the new Kubernetes state
if: always()
run: |
set -Eeuo pipefail
# Diff JSON states
/tmp/latest-scripts/k8s/diff.sh \
/tmp/artifacts/test-k8s-state.old.json \
/tmp/artifacts/test-k8s-state.new.json \
/tmp/artifacts/test-k8s-state.diff || true
# Remove ANSI sequences
sed -e 's/\x1b\[[0-9;]*m//g' -i /tmp/artifacts/test-k8s-state.diff || true
# Prepare PR comment message
echo -e "### ${{ env.SERVICE_NAME }} Kubernetes Diff [CI]\n\n" >> /tmp/artifacts/test-k8s-state.diff.message
echo -e "Between \`base\` ${{ github.event.pull_request.base.sha }} :arrow_left: \`head\` ${{ github.event.pull_request.head.sha }}.\n\n" >> /tmp/artifacts/test-k8s-state.diff.message
echo -e "<details>\n<summary>Expand</summary>\n\n\`\`\`diff\n" >> /tmp/artifacts/test-k8s-state.diff.message
head -c 50000 /tmp/artifacts/test-k8s-state.diff >> /tmp/artifacts/test-k8s-state.diff.message || true
echo -e "\n\n(see artifacts in the Github Action for more information)\n\`\`\`\n</details>" >> /tmp/artifacts/test-k8s-state.diff.message
- name: Dump logs
if: always()
run: |
/tmp/latest-scripts/minikube/logs.sh /tmp/artifacts &&
/tmp/latest-scripts/k8s/logs.sh /tmp/artifacts
- name: Upload artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: test-k8s-state-apps-proxy
path: /tmp/artifacts
if-no-files-found: error
- name: Send PR comment
uses: marocchino/sticky-pull-request-comment@v2
with:
header: "${{ env.KUBERNETES_NAMESPACE }}-kubernetes-state-diff"
recreate: true
path: /tmp/artifacts/test-k8s-state.diff.message